summaryrefslogtreecommitdiff
path: root/chromium/media
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-09-03 13:32:17 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-01 14:31:55 +0200
commit21ba0c5d4bf8fba15dddd97cd693bad2358b77fd (patch)
tree91be119f694044dfc1ff9fdc054459e925de9df0 /chromium/media
parent03c549e0392f92c02536d3f86d5e1d8dfa3435ac (diff)
downloadqtwebengine-chromium-21ba0c5d4bf8fba15dddd97cd693bad2358b77fd.tar.gz
BASELINE: Update Chromium to 92.0.4515.166
Change-Id: I42a050486714e9e54fc271f2a8939223a02ae364
Diffstat (limited to 'chromium/media')
-rw-r--r--chromium/media/BUILD.gn9
-rw-r--r--chromium/media/DIR_METADATA4
-rw-r--r--chromium/media/audio/BUILD.gn4
-rw-r--r--chromium/media/audio/DIR_METADATA4
-rw-r--r--chromium/media/audio/alsa/alsa_input.cc9
-rw-r--r--chromium/media/audio/alsa/alsa_input.h2
-rw-r--r--chromium/media/audio/alsa/alsa_output.cc7
-rw-r--r--chromium/media/audio/alsa/alsa_output_unittest.cc4
-rw-r--r--chromium/media/audio/android/aaudio_output.cc83
-rw-r--r--chromium/media/audio/android/aaudio_output.h7
-rw-r--r--chromium/media/audio/android/audio_android_unittest.cc10
-rw-r--r--chromium/media/audio/android/audio_manager_android.h2
-rw-r--r--chromium/media/audio/android/muteable_audio_output_stream.h6
-rw-r--r--chromium/media/audio/android/opensles_input.cc9
-rw-r--r--chromium/media/audio/android/opensles_input.h2
-rw-r--r--chromium/media/audio/audio_encoders_unittest.cc2
-rw-r--r--chromium/media/audio/audio_features.cc11
-rw-r--r--chromium/media/audio/audio_features.h4
-rw-r--r--chromium/media/audio/audio_input_device.cc20
-rw-r--r--chromium/media/audio/audio_input_device.h7
-rw-r--r--chromium/media/audio/audio_input_device_unittest.cc10
-rw-r--r--chromium/media/audio/audio_input_ipc.h3
-rw-r--r--chromium/media/audio/audio_input_stream_data_interceptor.cc4
-rw-r--r--chromium/media/audio/audio_input_stream_data_interceptor.h2
-rw-r--r--chromium/media/audio/audio_input_stream_data_interceptor_unittest.cc2
-rw-r--r--chromium/media/audio/audio_input_unittest.cc9
-rw-r--r--chromium/media/audio/audio_io.h12
-rw-r--r--chromium/media/audio/audio_low_latency_input_output_unittest.cc8
-rw-r--r--chromium/media/audio/audio_manager.cc5
-rw-r--r--chromium/media/audio/audio_manager_base.cc4
-rw-r--r--chromium/media/audio/audio_manager_unittest.cc24
-rw-r--r--chromium/media/audio/audio_opus_encoder.cc2
-rw-r--r--chromium/media/audio/audio_opus_encoder.h2
-rw-r--r--chromium/media/audio/audio_output_device.h2
-rw-r--r--chromium/media/audio/audio_output_device_thread_callback.h2
-rw-r--r--chromium/media/audio/audio_output_device_unittest.cc2
-rw-r--r--chromium/media/audio/audio_output_dispatcher_impl.cc2
-rw-r--r--chromium/media/audio/audio_output_ipc.h2
-rw-r--r--chromium/media/audio/audio_output_stream_sink.h2
-rw-r--r--chromium/media/audio/audio_sink_parameters.h4
-rw-r--r--chromium/media/audio/audio_source_parameters.h6
-rw-r--r--chromium/media/audio/audio_system.h10
-rw-r--r--chromium/media/audio/audio_system_helper.cc18
-rw-r--r--chromium/media/audio/audio_system_helper.h4
-rw-r--r--chromium/media/audio/audio_system_test_util.cc24
-rw-r--r--chromium/media/audio/audio_system_test_util.h34
-rw-r--r--chromium/media/audio/audio_thread_hang_monitor.cc4
-rw-r--r--chromium/media/audio/audio_thread_hang_monitor.h6
-rw-r--r--chromium/media/audio/audio_thread_hang_monitor_unittest.cc10
-rw-r--r--chromium/media/audio/audio_thread_impl.cc6
-rw-r--r--chromium/media/audio/audio_thread_impl.h2
-rw-r--r--chromium/media/audio/cras/audio_manager_chromeos.cc204
-rw-r--r--chromium/media/audio/cras/audio_manager_chromeos.h31
-rw-r--r--chromium/media/audio/cras/audio_manager_chromeos_unittest.cc217
-rw-r--r--chromium/media/audio/cras/cras_input.cc34
-rw-r--r--chromium/media/audio/cras/cras_input.h8
-rw-r--r--chromium/media/audio/cras/cras_input_unittest.cc12
-rw-r--r--chromium/media/audio/cras/cras_unified.h1
-rw-r--r--chromium/media/audio/fake_audio_input_stream.cc6
-rw-r--r--chromium/media/audio/fake_audio_input_stream.h9
-rw-r--r--chromium/media/audio/fuchsia/DIR_METADATA4
-rw-r--r--chromium/media/audio/fuchsia/OWNERS2
-rw-r--r--chromium/media/audio/fuchsia/audio_output_stream_fuchsia.h4
-rw-r--r--chromium/media/audio/mac/audio_device_listener_mac.cc2
-rw-r--r--chromium/media/audio/mac/audio_input_mac.cc9
-rw-r--r--chromium/media/audio/mac/audio_input_mac.h2
-rw-r--r--chromium/media/audio/mac/audio_low_latency_input_mac.cc8
-rw-r--r--chromium/media/audio/mac/audio_low_latency_input_mac.h2
-rw-r--r--chromium/media/audio/mac/audio_low_latency_input_mac_unittest.cc12
-rw-r--r--chromium/media/audio/mac/audio_manager_mac.cc8
-rw-r--r--chromium/media/audio/mac/core_audio_util_mac.cc36
-rw-r--r--chromium/media/audio/mac/core_audio_util_mac.h10
-rw-r--r--chromium/media/audio/pulse/pulse_input.cc8
-rw-r--r--chromium/media/audio/pulse/pulse_input.h2
-rw-r--r--chromium/media/audio/win/audio_low_latency_input_win.cc258
-rw-r--r--chromium/media/audio/win/audio_low_latency_input_win.h22
-rw-r--r--chromium/media/audio/win/audio_low_latency_input_win_unittest.cc48
-rw-r--r--chromium/media/audio/win/audio_low_latency_output_win.cc34
-rw-r--r--chromium/media/audio/win/volume_range_util.cc64
-rw-r--r--chromium/media/audio/win/volume_range_util.h45
-rw-r--r--chromium/media/audio/win/volume_range_util_unittest.cc103
-rw-r--r--chromium/media/base/BUILD.gn5
-rw-r--r--chromium/media/base/DEPS3
-rw-r--r--chromium/media/base/android/media_codec_bridge.h4
-rw-r--r--chromium/media/base/android/media_codec_bridge_impl.cc2
-rw-r--r--chromium/media/base/android/media_codec_bridge_impl.h4
-rw-r--r--chromium/media/base/android/media_codec_loop.h2
-rw-r--r--chromium/media/base/android/media_codec_loop_unittest.cc10
-rw-r--r--chromium/media/base/android/media_crypto_context_impl.h2
-rw-r--r--chromium/media/base/android/media_drm_bridge.cc23
-rw-r--r--chromium/media/base/android/media_drm_bridge_unittest.cc11
-rw-r--r--chromium/media/base/android/mock_media_codec_bridge.h2
-rw-r--r--chromium/media/base/android/mock_media_crypto_context.h2
-rw-r--r--chromium/media/base/android/test_destruction_observable.h4
-rw-r--r--chromium/media/base/android_overlay_mojo_factory.h6
-rw-r--r--chromium/media/base/audio_buffer.cc59
-rw-r--r--chromium/media/base/audio_buffer.h16
-rw-r--r--chromium/media/base/audio_buffer_converter.h1
-rw-r--r--chromium/media/base/audio_buffer_unittest.cc70
-rw-r--r--chromium/media/base/audio_bus.cc29
-rw-r--r--chromium/media/base/audio_bus.h17
-rw-r--r--chromium/media/base/audio_bus_unittest.cc9
-rw-r--r--chromium/media/base/audio_capturer_source.h7
-rw-r--r--chromium/media/base/audio_converter.h1
-rw-r--r--chromium/media/base/audio_decoder.h2
-rw-r--r--chromium/media/base/audio_encoder.h4
-rw-r--r--chromium/media/base/audio_parameters.h6
-rw-r--r--chromium/media/base/audio_processing.h1
-rw-r--r--chromium/media/base/audio_renderer.h4
-rw-r--r--chromium/media/base/audio_renderer_mixer_input.h2
-rw-r--r--chromium/media/base/cdm_context.cc4
-rw-r--r--chromium/media/base/cdm_context.h18
-rw-r--r--chromium/media/base/data_source.h1
-rw-r--r--chromium/media/base/decoder_buffer.h1
-rw-r--r--chromium/media/base/decrypt_config.cc6
-rw-r--r--chromium/media/base/decrypt_config.h10
-rw-r--r--chromium/media/base/decrypt_config_unittest.cc6
-rw-r--r--chromium/media/base/demuxer.h4
-rw-r--r--chromium/media/base/demuxer_memory_limit_cast_unittest.cc2
-rw-r--r--chromium/media/base/demuxer_stream.h1
-rw-r--r--chromium/media/base/eme_constants.h9
-rw-r--r--chromium/media/base/encryption_pattern.h2
-rw-r--r--chromium/media/base/fake_audio_renderer_sink.h2
-rw-r--r--chromium/media/base/fake_text_track_stream.cc4
-rw-r--r--chromium/media/base/format_utils.cc8
-rw-r--r--chromium/media/base/format_utils.h6
-rw-r--r--chromium/media/base/frame_rate_estimator.cc2
-rw-r--r--chromium/media/base/frame_rate_estimator.h6
-rw-r--r--chromium/media/base/ipc/media_param_traits.cc2
-rw-r--r--chromium/media/base/key_system_names.cc5
-rw-r--r--chromium/media/base/key_system_names.h4
-rw-r--r--chromium/media/base/key_system_properties.h10
-rw-r--r--chromium/media/base/key_systems.cc15
-rw-r--r--chromium/media/base/key_systems.h10
-rw-r--r--chromium/media/base/key_systems_unittest.cc14
-rw-r--r--chromium/media/base/limits.h3
-rw-r--r--chromium/media/base/localized_strings.h6
-rw-r--r--chromium/media/base/mac/videotoolbox_helpers.cc11
-rw-r--r--chromium/media/base/media_client.h4
-rw-r--r--chromium/media/base/media_drm_storage.h4
-rw-r--r--chromium/media/base/media_log.h5
-rw-r--r--chromium/media/base/media_serializers.h4
-rw-r--r--chromium/media/base/media_serializers_unittest.cc2
-rw-r--r--chromium/media/base/media_switches.cc73
-rw-r--r--chromium/media/base/media_switches.h5
-rw-r--r--chromium/media/base/media_url_demuxer.cc4
-rw-r--r--chromium/media/base/media_url_demuxer.h2
-rw-r--r--chromium/media/base/memory_dump_provider_proxy.h4
-rw-r--r--chromium/media/base/mock_filters.cc4
-rw-r--r--chromium/media/base/mock_filters.h22
-rw-r--r--chromium/media/base/offloading_audio_encoder_unittest.cc2
-rw-r--r--chromium/media/base/offloading_video_encoder_unittest.cc4
-rw-r--r--chromium/media/base/overlay_info.h4
-rw-r--r--chromium/media/base/pipeline.h8
-rw-r--r--chromium/media/base/pipeline_impl.cc38
-rw-r--r--chromium/media/base/pipeline_impl.h16
-rw-r--r--chromium/media/base/pipeline_impl_unittest.cc2
-rw-r--r--chromium/media/base/pipeline_status.cc4
-rw-r--r--chromium/media/base/pipeline_status.h4
-rw-r--r--chromium/media/base/renderer.h4
-rw-r--r--chromium/media/base/renderer_client.h3
-rw-r--r--chromium/media/base/renderer_factory_selector.cc30
-rw-r--r--chromium/media/base/renderer_factory_selector.h38
-rw-r--r--chromium/media/base/renderer_factory_selector_unittest.cc82
-rw-r--r--chromium/media/base/routing_token_callback.h2
-rw-r--r--chromium/media/base/sample_rates.h2
-rw-r--r--chromium/media/base/sinc_resampler.cc1
-rw-r--r--chromium/media/base/sinc_resampler_perftest.cc1
-rw-r--r--chromium/media/base/status.cc3
-rw-r--r--chromium/media/base/status.h6
-rw-r--r--chromium/media/base/status_codes.h1
-rw-r--r--chromium/media/base/tuneable.h1
-rw-r--r--chromium/media/base/user_input_monitor_win.cc1
-rw-r--r--chromium/media/base/video_color_space.h2
-rw-r--r--chromium/media/base/video_decoder.h8
-rw-r--r--chromium/media/base/video_decoder_config.h6
-rw-r--r--chromium/media/base/video_encoder.h16
-rw-r--r--chromium/media/base/video_frame.cc141
-rw-r--r--chromium/media/base/video_frame.h56
-rw-r--r--chromium/media/base/video_frame_layout.cc16
-rw-r--r--chromium/media/base/video_frame_layout.h12
-rw-r--r--chromium/media/base/video_frame_metadata.h47
-rw-r--r--chromium/media/base/video_frame_pool.cc5
-rw-r--r--chromium/media/base/video_frame_pool.h5
-rw-r--r--chromium/media/base/video_frame_unittest.cc5
-rw-r--r--chromium/media/base/video_renderer.h10
-rw-r--r--chromium/media/base/video_thumbnail_decoder.h5
-rw-r--r--chromium/media/base/video_thumbnail_decoder_unittest.cc9
-rw-r--r--chromium/media/base/video_util_unittest.cc13
-rw-r--r--chromium/media/base/win/BUILD.gn2
-rw-r--r--chromium/media/base/win/dxgi_device_manager.h4
-rw-r--r--chromium/media/base/win/media_foundation_cdm_proxy.h (renamed from chromium/media/base/win/mf_cdm_proxy.h)58
-rw-r--r--chromium/media/blink/BUILD.gn4
-rw-r--r--chromium/media/blink/blink_platform_with_task_environment.h1
-rw-r--r--chromium/media/blink/cache_util.h2
-rw-r--r--chromium/media/blink/cdm_result_promise_helper.h1
-rw-r--r--chromium/media/blink/cdm_session_adapter.cc12
-rw-r--r--chromium/media/blink/key_system_config_selector.cc34
-rw-r--r--chromium/media/blink/key_system_config_selector_unittest.cc103
-rw-r--r--chromium/media/blink/learning_experiment_helper_unittest.cc6
-rw-r--r--chromium/media/blink/multibuffer_data_source.cc1
-rw-r--r--chromium/media/blink/multibuffer_data_source.h3
-rw-r--r--chromium/media/blink/multibuffer_data_source_unittest.cc6
-rw-r--r--chromium/media/blink/multibuffer_reader.h4
-rw-r--r--chromium/media/blink/new_session_cdm_result_promise.cc2
-rw-r--r--chromium/media/blink/power_status_helper.cc310
-rw-r--r--chromium/media/blink/power_status_helper.h133
-rw-r--r--chromium/media/blink/power_status_helper_unittest.cc445
-rw-r--r--chromium/media/blink/resource_fetch_context.h1
-rw-r--r--chromium/media/blink/resource_multibuffer_data_provider.cc3
-rw-r--r--chromium/media/blink/resource_multibuffer_data_provider_unittest.cc10
-rw-r--r--chromium/media/blink/smoothness_helper.cc6
-rw-r--r--chromium/media/blink/smoothness_helper_unittest.cc14
-rw-r--r--chromium/media/blink/url_index.cc34
-rw-r--r--chromium/media/blink/url_index.h5
-rw-r--r--chromium/media/blink/url_index_unittest.cc1
-rw-r--r--chromium/media/blink/video_decode_stats_reporter.cc2
-rw-r--r--chromium/media/blink/video_decode_stats_reporter.h5
-rw-r--r--chromium/media/blink/video_decode_stats_reporter_unittest.cc6
-rw-r--r--chromium/media/blink/video_frame_compositor.cc1
-rw-r--r--chromium/media/blink/video_frame_compositor.h3
-rw-r--r--chromium/media/blink/video_frame_compositor_unittest.cc2
-rw-r--r--chromium/media/blink/webcontentdecryptionmodulesession_impl.cc22
-rw-r--r--chromium/media/blink/webcontentdecryptionmodulesession_impl.h3
-rw-r--r--chromium/media/blink/webencryptedmediaclient_impl.cc3
-rw-r--r--chromium/media/blink/webmediaplayer_impl.cc42
-rw-r--r--chromium/media/blink/webmediaplayer_impl.h55
-rw-r--r--chromium/media/blink/webmediaplayer_impl_unittest.cc17
-rw-r--r--chromium/media/blink/webmediaplayer_params.h1
-rw-r--r--chromium/media/blink/websourcebuffer_impl.cc10
-rw-r--r--chromium/media/blink/websourcebuffer_impl.h2
-rw-r--r--chromium/media/capabilities/bucket_utility.h6
-rw-r--r--chromium/media/capabilities/in_memory_video_decode_stats_db_impl.cc1
-rw-r--r--chromium/media/capabilities/in_memory_video_decode_stats_db_impl.h1
-rw-r--r--chromium/media/capture/BUILD.gn18
-rw-r--r--chromium/media/capture/content/DIR_METADATA4
-rw-r--r--chromium/media/capture/content/android/screen_capture_machine_android.h1
-rw-r--r--chromium/media/capture/content/video_capture_oracle_unittest.cc8
-rw-r--r--chromium/media/capture/mojom/video_capture_buffer.mojom5
-rw-r--r--chromium/media/capture/mojom/video_capture_types_mojom_traits.h2
-rw-r--r--chromium/media/capture/video/DIR_METADATA4
-rw-r--r--chromium/media/capture/video/android/video_capture_device_factory_android.cc1
-rw-r--r--chromium/media/capture/video/chromeos/DEPS1
-rw-r--r--chromium/media/capture/video/chromeos/camera_app_device_impl.cc13
-rw-r--r--chromium/media/capture/video/chromeos/camera_app_device_impl.h5
-rw-r--r--chromium/media/capture/video/chromeos/camera_app_device_provider_impl.cc4
-rw-r--r--chromium/media/capture/video/chromeos/camera_app_device_provider_impl.h6
-rw-r--r--chromium/media/capture/video/chromeos/camera_buffer_factory.cc4
-rw-r--r--chromium/media/capture/video/chromeos/camera_device_context.h2
-rw-r--r--chromium/media/capture/video/chromeos/camera_device_delegate.cc65
-rw-r--r--chromium/media/capture/video/chromeos/camera_device_delegate.h43
-rw-r--r--chromium/media/capture/video/chromeos/camera_device_delegate_unittest.cc10
-rw-r--r--chromium/media/capture/video/chromeos/camera_hal_delegate.cc2
-rw-r--r--chromium/media/capture/video/chromeos/camera_hal_delegate_unittest.cc4
-rw-r--r--chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc63
-rw-r--r--chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl.h21
-rw-r--r--chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl_unittest.cc3
-rw-r--r--chromium/media/capture/video/chromeos/camera_metadata_utils.h2
-rw-r--r--chromium/media/capture/video/chromeos/gpu_memory_buffer_tracker.cc4
-rw-r--r--chromium/media/capture/video/chromeos/mock_vendor_tag_ops.h4
-rw-r--r--chromium/media/capture/video/chromeos/mojom/BUILD.gn2
-rw-r--r--chromium/media/capture/video/chromeos/mojom/camera3.mojom18
-rw-r--r--chromium/media/capture/video/chromeos/mojom/camera_common.mojom7
-rw-r--r--chromium/media/capture/video/chromeos/mojom/cros_camera_client.mojom23
-rw-r--r--chromium/media/capture/video/chromeos/mojom/cros_camera_service.mojom27
-rw-r--r--chromium/media/capture/video/chromeos/pixel_format_utils.cc4
-rw-r--r--chromium/media/capture/video/chromeos/pixel_format_utils.h4
-rw-r--r--chromium/media/capture/video/chromeos/request_builder.cc4
-rw-r--r--chromium/media/capture/video/chromeos/request_builder.h6
-rw-r--r--chromium/media/capture/video/chromeos/request_manager.cc17
-rw-r--r--chromium/media/capture/video/chromeos/request_manager.h12
-rw-r--r--chromium/media/capture/video/chromeos/request_manager_unittest.cc8
-rw-r--r--chromium/media/capture/video/chromeos/stream_buffer_manager.cc20
-rw-r--r--chromium/media/capture/video/chromeos/stream_buffer_manager.h12
-rw-r--r--chromium/media/capture/video/chromeos/token_manager.cc28
-rw-r--r--chromium/media/capture/video/chromeos/token_manager.h10
-rw-r--r--chromium/media/capture/video/chromeos/vendor_tag_ops_delegate.cc4
-rw-r--r--chromium/media/capture/video/chromeos/vendor_tag_ops_delegate.h4
-rw-r--r--chromium/media/capture/video/chromeos/video_capture_device_chromeos_delegate.cc2
-rw-r--r--chromium/media/capture/video/chromeos/video_capture_features_chromeos.cc4
-rw-r--r--chromium/media/capture/video/chromeos/video_capture_features_chromeos.h1
-rw-r--r--chromium/media/capture/video/chromeos/video_capture_jpeg_decoder.h1
-rw-r--r--chromium/media/capture/video/create_video_capture_device_factory.cc24
-rw-r--r--chromium/media/capture/video/fake_video_capture_device_factory.cc6
-rw-r--r--chromium/media/capture/video/file_video_capture_device.cc216
-rw-r--r--chromium/media/capture/video/file_video_capture_device.h23
-rw-r--r--chromium/media/capture/video/file_video_capture_device_factory.cc1
-rw-r--r--chromium/media/capture/video/file_video_capture_device_unittest.cc77
-rw-r--r--chromium/media/capture/video/fuchsia/video_capture_device_factory_fuchsia.cc6
-rw-r--r--chromium/media/capture/video/fuchsia/video_capture_device_factory_fuchsia.h4
-rw-r--r--chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.cc95
-rw-r--r--chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.h25
-rw-r--r--chromium/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc2
-rw-r--r--chromium/media/capture/video/linux/camera_config_chromeos.cc221
-rw-r--r--chromium/media/capture/video/linux/camera_config_chromeos.h86
-rw-r--r--chromium/media/capture/video/linux/camera_config_chromeos_unittest.cc43
-rw-r--r--chromium/media/capture/video/linux/fake_device_provider.cc11
-rw-r--r--chromium/media/capture/video/linux/fake_device_provider.h4
-rw-r--r--chromium/media/capture/video/linux/fake_v4l2_impl.cc11
-rw-r--r--chromium/media/capture/video/linux/fake_v4l2_impl.h11
-rw-r--r--chromium/media/capture/video/linux/v4l2_capture_delegate_unittest.cc5
-rw-r--r--chromium/media/capture/video/linux/video_capture_device_chromeos.cc87
-rw-r--r--chromium/media/capture/video/linux/video_capture_device_chromeos.h65
-rw-r--r--chromium/media/capture/video/linux/video_capture_device_factory_linux.cc51
-rw-r--r--chromium/media/capture/video/linux/video_capture_device_factory_linux.h14
-rw-r--r--chromium/media/capture/video/mac/pixel_buffer_pool_mac.cc4
-rw-r--r--chromium/media/capture/video/mac/pixel_buffer_pool_mac.h10
-rw-r--r--chromium/media/capture/video/mac/pixel_buffer_pool_mac_unittest.mm4
-rw-r--r--chromium/media/capture/video/mac/sample_buffer_transformer_mac.cc5
-rw-r--r--chromium/media/capture/video/mac/sample_buffer_transformer_mac.h7
-rw-r--r--chromium/media/capture/video/mac/video_capture_device_avfoundation_mac.h2
-rw-r--r--chromium/media/capture/video/mac/video_capture_device_avfoundation_mac.mm26
-rw-r--r--chromium/media/capture/video/mac/video_capture_device_avfoundation_mac_unittest.mm18
-rw-r--r--chromium/media/capture/video/mac/video_capture_device_avfoundation_utils_mac.mm2
-rw-r--r--chromium/media/capture/video/mac/video_capture_device_mac.h3
-rw-r--r--chromium/media/capture/video/mac/video_capture_device_mac.mm18
-rw-r--r--chromium/media/capture/video/mac/video_capture_device_mac_unittest.mm24
-rw-r--r--chromium/media/capture/video/mock_gpu_memory_buffer_manager.cc3
-rw-r--r--chromium/media/capture/video/mock_gpu_memory_buffer_manager.h16
-rw-r--r--chromium/media/capture/video/video_capture_device.h6
-rw-r--r--chromium/media/capture/video/video_capture_device_client.cc2
-rw-r--r--chromium/media/capture/video/video_capture_device_client.h1
-rw-r--r--chromium/media/capture/video/video_capture_device_client_unittest.cc7
-rw-r--r--chromium/media/capture/video/video_capture_device_descriptor.h2
-rw-r--r--chromium/media/capture/video/video_capture_device_unittest.cc46
-rw-r--r--chromium/media/capture/video/win/capability_list_win.cc76
-rw-r--r--chromium/media/capture/video/win/capability_list_win.h16
-rw-r--r--chromium/media/capture/video/win/gpu_memory_buffer_tracker.cc13
-rw-r--r--chromium/media/capture/video/win/video_capture_device_factory_win.cc6
-rw-r--r--chromium/media/capture/video/win/video_capture_device_factory_win_unittest.cc25
-rw-r--r--chromium/media/capture/video/win/video_capture_device_mf_win.cc133
-rw-r--r--chromium/media/capture/video/win/video_capture_device_mf_win.h7
-rw-r--r--chromium/media/capture/video/win/video_capture_device_win.h4
-rw-r--r--chromium/media/capture/video_capture_types.h2
-rw-r--r--chromium/media/cast/BUILD.gn60
-rw-r--r--chromium/media/cast/DIR_METADATA4
-rw-r--r--chromium/media/cast/OWNERS1
-rw-r--r--chromium/media/cast/README.md6
-rw-r--r--chromium/media/cast/cast_config.h5
-rw-r--r--chromium/media/cast/cast_environment.h2
-rw-r--r--chromium/media/cast/cast_receiver.h73
-rw-r--r--chromium/media/cast/cast_sender.h5
-rw-r--r--chromium/media/cast/cast_sender_impl.cc5
-rw-r--r--chromium/media/cast/cast_sender_impl.h3
-rw-r--r--chromium/media/cast/common/mod_util.h1
-rw-r--r--chromium/media/cast/logging/logging_defines.h4
-rw-r--r--chromium/media/cast/logging/stats_event_subscriber.h3
-rw-r--r--chromium/media/cast/net/cast_transport_defines.h1
-rw-r--r--chromium/media/cast/net/rtcp/receiver_rtcp_session.h1
-rw-r--r--chromium/media/cast/net/rtcp/rtcp_builder.h3
-rw-r--r--chromium/media/cast/net/rtcp/rtcp_defines.h1
-rw-r--r--chromium/media/cast/net/rtp/cast_message_builder.cc202
-rw-r--r--chromium/media/cast/net/rtp/cast_message_builder.h69
-rw-r--r--chromium/media/cast/net/rtp/cast_message_builder_unittest.cc411
-rw-r--r--chromium/media/cast/net/rtp/frame_buffer.cc113
-rw-r--r--chromium/media/cast/net/rtp/frame_buffer.h63
-rw-r--r--chromium/media/cast/net/rtp/frame_buffer_unittest.cc96
-rw-r--r--chromium/media/cast/net/rtp/framer.cc200
-rw-r--r--chromium/media/cast/net/rtp/framer.h98
-rw-r--r--chromium/media/cast/net/rtp/framer_unittest.cc457
-rw-r--r--chromium/media/cast/net/rtp/receiver_stats.cc133
-rw-r--r--chromium/media/cast/net/rtp/receiver_stats.h50
-rw-r--r--chromium/media/cast/net/rtp/receiver_stats_unittest.cc158
-rw-r--r--chromium/media/cast/net/rtp/rtp_packetizer.h3
-rw-r--r--chromium/media/cast/receiver/audio_decoder.cc258
-rw-r--r--chromium/media/cast/receiver/audio_decoder.h66
-rw-r--r--chromium/media/cast/receiver/audio_decoder_unittest.cc251
-rw-r--r--chromium/media/cast/receiver/cast_receiver_impl.cc214
-rw-r--r--chromium/media/cast/receiver/cast_receiver_impl.h115
-rw-r--r--chromium/media/cast/receiver/frame_receiver.cc403
-rw-r--r--chromium/media/cast/receiver/frame_receiver.h221
-rw-r--r--chromium/media/cast/receiver/frame_receiver_unittest.cc457
-rw-r--r--chromium/media/cast/receiver/video_decoder.cc270
-rw-r--r--chromium/media/cast/receiver/video_decoder.h66
-rw-r--r--chromium/media/cast/receiver/video_decoder_unittest.cc244
-rw-r--r--chromium/media/cast/sender/external_video_encoder.cc216
-rw-r--r--chromium/media/cast/sender/external_video_encoder.h20
-rw-r--r--chromium/media/cast/sender/fake_video_encode_accelerator_factory.cc26
-rw-r--r--chromium/media/cast/sender/fake_video_encode_accelerator_factory.h21
-rw-r--r--chromium/media/cast/sender/h264_vt_encoder_unittest.cc2
-rw-r--r--chromium/media/cast/sender/video_encoder.cc5
-rw-r--r--chromium/media/cast/sender/video_encoder.h5
-rw-r--r--chromium/media/cast/sender/video_encoder_unittest.cc14
-rw-r--r--chromium/media/cast/sender/video_frame_factory.h2
-rw-r--r--chromium/media/cast/sender/video_sender.cc9
-rw-r--r--chromium/media/cast/sender/video_sender.h1
-rw-r--r--chromium/media/cast/sender/video_sender_unittest.cc11
-rw-r--r--chromium/media/cast/sender/vp8_encoder.h2
-rw-r--r--chromium/media/cast/sender/vp8_quantizer_parser_unittest.cc2
-rw-r--r--chromium/media/cdm/BUILD.gn35
-rw-r--r--chromium/media/cdm/aes_cbc_crypto.h2
-rw-r--r--chromium/media/cdm/aes_cbc_crypto_unittest.cc2
-rw-r--r--chromium/media/cdm/aes_decryptor_unittest.cc2
-rw-r--r--chromium/media/cdm/cbcs_decryptor_unittest.cc4
-rw-r--r--chromium/media/cdm/cdm_adapter.cc4
-rw-r--r--chromium/media/cdm/cdm_adapter.h3
-rw-r--r--chromium/media/cdm/cdm_auxiliary_helper.cc4
-rw-r--r--chromium/media/cdm/cdm_auxiliary_helper.h7
-rw-r--r--chromium/media/cdm/cdm_capability.cc27
-rw-r--r--chromium/media/cdm/cdm_capability.h51
-rw-r--r--chromium/media/cdm/cdm_context_ref_impl.h2
-rw-r--r--chromium/media/cdm/cdm_paths.cc14
-rw-r--r--chromium/media/cdm/cdm_paths.h13
-rw-r--r--chromium/media/cdm/cdm_wrapper.h2
-rw-r--r--chromium/media/cdm/json_web_key.cc45
-rw-r--r--chromium/media/cdm/json_web_key.h1
-rw-r--r--chromium/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc6
-rw-r--r--chromium/media/cdm/mock_helpers.cc6
-rw-r--r--chromium/media/cdm/mock_helpers.h3
-rw-r--r--chromium/media/cdm/supported_audio_codecs.cc20
-rw-r--r--chromium/media/cdm/supported_audio_codecs.h25
-rw-r--r--chromium/media/cdm/supported_cdm_versions.cc8
-rw-r--r--chromium/media/cdm/win/media_foundation_cdm.cc38
-rw-r--r--chromium/media/cdm/win/media_foundation_cdm.h7
-rw-r--r--chromium/media/cdm/win/media_foundation_cdm_factory.cc85
-rw-r--r--chromium/media/cdm/win/media_foundation_cdm_factory.h17
-rw-r--r--chromium/media/cdm/win/media_foundation_cdm_factory_unittest.cc47
-rw-r--r--chromium/media/cdm/win/media_foundation_cdm_module.cc131
-rw-r--r--chromium/media/cdm/win/media_foundation_cdm_module.h58
-rw-r--r--chromium/media/device_monitors/device_monitor_mac.mm6
-rw-r--r--chromium/media/device_monitors/system_message_window_win.cc4
-rw-r--r--chromium/media/filters/BUILD.gn1
-rw-r--r--chromium/media/filters/android/media_codec_audio_decoder.cc13
-rw-r--r--chromium/media/filters/android/media_codec_audio_decoder.h1
-rw-r--r--chromium/media/filters/android/video_frame_extractor.h1
-rw-r--r--chromium/media/filters/audio_decoder_unittest.cc4
-rw-r--r--chromium/media/filters/audio_renderer_algorithm.cc2
-rw-r--r--chromium/media/filters/audio_renderer_algorithm.h4
-rw-r--r--chromium/media/filters/audio_renderer_algorithm_unittest.cc4
-rw-r--r--chromium/media/filters/audio_video_metadata_extractor.h6
-rw-r--r--chromium/media/filters/chunk_demuxer.cc4
-rw-r--r--chromium/media/filters/chunk_demuxer.h2
-rw-r--r--chromium/media/filters/decrypting_audio_decoder.h1
-rw-r--r--chromium/media/filters/ffmpeg_audio_decoder.h1
-rw-r--r--chromium/media/filters/ffmpeg_demuxer.cc16
-rw-r--r--chromium/media/filters/ffmpeg_demuxer.h2
-rw-r--r--chromium/media/filters/ffmpeg_demuxer_unittest.cc1
-rw-r--r--chromium/media/filters/ffmpeg_video_decoder.cc5
-rw-r--r--chromium/media/filters/ffmpeg_video_decoder.h10
-rw-r--r--chromium/media/filters/ffmpeg_video_decoder_unittest.cc8
-rw-r--r--chromium/media/filters/file_data_source.h2
-rw-r--r--chromium/media/filters/frame_buffer_pool.cc25
-rw-r--r--chromium/media/filters/frame_buffer_pool.h5
-rw-r--r--chromium/media/filters/frame_buffer_pool_unittest.cc12
-rw-r--r--chromium/media/filters/fuchsia/DIR_METADATA4
-rw-r--r--chromium/media/filters/fuchsia/OWNERS2
-rw-r--r--chromium/media/filters/fuchsia/fuchsia_video_decoder.cc725
-rw-r--r--chromium/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc3
-rw-r--r--chromium/media/filters/media_file_checker.h6
-rw-r--r--chromium/media/filters/pipeline_controller.cc4
-rw-r--r--chromium/media/filters/pipeline_controller.h8
-rw-r--r--chromium/media/filters/pipeline_controller_unittest.cc2
-rw-r--r--chromium/media/filters/source_buffer_stream.cc2
-rw-r--r--chromium/media/filters/stream_parser_factory.cc12
-rw-r--r--chromium/media/filters/video_cadence_estimator.h4
-rw-r--r--chromium/media/filters/vp9_parser_unittest.cc20
-rw-r--r--chromium/media/filters/vpx_video_decoder.cc4
-rw-r--r--chromium/media/filters/vpx_video_decoder.h5
-rw-r--r--chromium/media/filters/vpx_video_decoder_unittest.cc8
-rw-r--r--chromium/media/formats/mp2t/descriptors.h2
-rw-r--r--chromium/media/formats/mp2t/es_parser_adts.cc2
-rw-r--r--chromium/media/formats/mp2t/es_parser_adts.h1
-rw-r--r--chromium/media/formats/mp2t/es_parser_h264.cc6
-rw-r--r--chromium/media/formats/mp2t/es_parser_h264.h1
-rw-r--r--chromium/media/formats/mp2t/mp2t_stream_parser.cc4
-rw-r--r--chromium/media/formats/mp2t/ts_section_cat.h2
-rw-r--r--chromium/media/formats/mp2t/ts_section_cets_ecm.h2
-rw-r--r--chromium/media/formats/mp2t/ts_section_cets_pssh.h2
-rw-r--r--chromium/media/formats/mp4/avc_unittest.cc22
-rw-r--r--chromium/media/formats/mp4/bitstream_converter.h8
-rw-r--r--chromium/media/formats/mp4/box_definitions.cc6
-rw-r--r--chromium/media/formats/mp4/box_definitions.h6
-rw-r--r--chromium/media/formats/mp4/dolby_vision.h2
-rw-r--r--chromium/media/formats/mp4/hevc_unittest.cc14
-rw-r--r--chromium/media/formats/webcodecs/webcodecs_encoded_chunk_stream_parser.h1
-rw-r--r--chromium/media/formats/webm/webm_colour_parser.cc1
-rw-r--r--chromium/media/formats/webm/webm_colour_parser.h4
-rw-r--r--chromium/media/formats/webm/webm_stream_parser.h1
-rw-r--r--chromium/media/formats/webm/webm_stream_parser_unittest.cc2
-rw-r--r--chromium/media/fuchsia/audio/BUILD.gn9
-rw-r--r--chromium/media/fuchsia/audio/fake_audio_consumer.h1
-rw-r--r--chromium/media/fuchsia/audio/fuchsia_audio_capturer_source.cc3
-rw-r--r--chromium/media/fuchsia/audio/fuchsia_audio_capturer_source.h3
-rw-r--r--chromium/media/fuchsia/audio/fuchsia_audio_capturer_source_test.cc5
-rw-r--r--chromium/media/fuchsia/audio/fuchsia_audio_output_device.cc42
-rw-r--r--chromium/media/fuchsia/audio/fuchsia_audio_output_device.h5
-rw-r--r--chromium/media/fuchsia/audio/fuchsia_audio_output_device_test.cc8
-rw-r--r--chromium/media/fuchsia/audio/fuchsia_audio_renderer.cc350
-rw-r--r--chromium/media/fuchsia/audio/fuchsia_audio_renderer.h74
-rw-r--r--chromium/media/fuchsia/audio/fuchsia_audio_renderer_test.cc1010
-rw-r--r--chromium/media/fuchsia/camera/fake_fuchsia_camera.cc91
-rw-r--r--chromium/media/fuchsia/camera/fake_fuchsia_camera.h24
-rw-r--r--chromium/media/fuchsia/cdm/fuchsia_cdm.cc64
-rw-r--r--chromium/media/fuchsia/cdm/fuchsia_cdm.h19
-rw-r--r--chromium/media/fuchsia/cdm/fuchsia_cdm_context.h10
-rw-r--r--chromium/media/fuchsia/cdm/fuchsia_decryptor.cc20
-rw-r--r--chromium/media/fuchsia/cdm/fuchsia_decryptor.h5
-rw-r--r--chromium/media/fuchsia/cdm/fuchsia_stream_decryptor.cc425
-rw-r--r--chromium/media/fuchsia/cdm/fuchsia_stream_decryptor.h192
-rw-r--r--chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager.cc14
-rw-r--r--chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager.h8
-rw-r--r--chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager_unittest.cc2
-rw-r--r--chromium/media/fuchsia/common/BUILD.gn21
-rw-r--r--chromium/media/fuchsia/common/decrypting_sysmem_buffer_stream.cc123
-rw-r--r--chromium/media/fuchsia/common/decrypting_sysmem_buffer_stream.h66
-rw-r--r--chromium/media/fuchsia/common/passthrough_sysmem_buffer_stream.cc71
-rw-r--r--chromium/media/fuchsia/common/passthrough_sysmem_buffer_stream.h52
-rw-r--r--chromium/media/fuchsia/common/stream_processor_helper.cc99
-rw-r--r--chromium/media/fuchsia/common/stream_processor_helper.h60
-rw-r--r--chromium/media/fuchsia/common/sysmem_buffer_pool.cc196
-rw-r--r--chromium/media/fuchsia/common/sysmem_buffer_pool.h128
-rw-r--r--chromium/media/fuchsia/common/sysmem_buffer_reader.cc112
-rw-r--r--chromium/media/fuchsia/common/sysmem_buffer_reader.h71
-rw-r--r--chromium/media/fuchsia/common/sysmem_buffer_stream.h72
-rw-r--r--chromium/media/fuchsia/common/sysmem_buffer_writer.cc202
-rw-r--r--chromium/media/fuchsia/common/sysmem_buffer_writer.h70
-rw-r--r--chromium/media/fuchsia/common/sysmem_client.cc172
-rw-r--r--chromium/media/fuchsia/common/sysmem_client.h114
-rw-r--r--chromium/media/fuchsia/common/vmo_buffer.cc171
-rw-r--r--chromium/media/fuchsia/common/vmo_buffer.h99
-rw-r--r--chromium/media/fuchsia/common/vmo_buffer_writer_queue.cc (renamed from chromium/media/fuchsia/common/sysmem_buffer_writer_queue.cc)87
-rw-r--r--chromium/media/fuchsia/common/vmo_buffer_writer_queue.h (renamed from chromium/media/fuchsia/common/sysmem_buffer_writer_queue.h)45
-rw-r--r--chromium/media/gpu/BUILD.gn1
-rw-r--r--chromium/media/gpu/android/android_video_encode_accelerator.cc2
-rw-r--r--chromium/media/gpu/android/android_video_surface_chooser.h4
-rw-r--r--chromium/media/gpu/android/android_video_surface_chooser_impl.cc2
-rw-r--r--chromium/media/gpu/android/android_video_surface_chooser_impl.h2
-rw-r--r--chromium/media/gpu/android/android_video_surface_chooser_impl_unittest.cc6
-rw-r--r--chromium/media/gpu/android/codec_image.cc47
-rw-r--r--chromium/media/gpu/android/codec_image.h10
-rw-r--r--chromium/media/gpu/android/codec_image_group.h2
-rw-r--r--chromium/media/gpu/android/codec_image_unittest.cc17
-rw-r--r--chromium/media/gpu/android/codec_output_buffer_renderer.cc70
-rw-r--r--chromium/media/gpu/android/codec_output_buffer_renderer.h14
-rw-r--r--chromium/media/gpu/android/codec_wrapper.cc4
-rw-r--r--chromium/media/gpu/android/direct_shared_image_video_provider.cc46
-rw-r--r--chromium/media/gpu/android/direct_shared_image_video_provider.h16
-rw-r--r--chromium/media/gpu/android/frame_info_helper.cc17
-rw-r--r--chromium/media/gpu/android/frame_info_helper.h4
-rw-r--r--chromium/media/gpu/android/maybe_render_early_manager.h4
-rw-r--r--chromium/media/gpu/android/media_codec_video_decoder.cc4
-rw-r--r--chromium/media/gpu/android/media_codec_video_decoder.h4
-rw-r--r--chromium/media/gpu/android/mock_android_video_surface_chooser.cc2
-rw-r--r--chromium/media/gpu/android/mock_android_video_surface_chooser.h2
-rw-r--r--chromium/media/gpu/android/mock_shared_image_video_provider.cc7
-rw-r--r--chromium/media/gpu/android/mock_shared_image_video_provider.h11
-rw-r--r--chromium/media/gpu/android/pooled_shared_image_video_provider.cc8
-rw-r--r--chromium/media/gpu/android/pooled_shared_image_video_provider.h4
-rw-r--r--chromium/media/gpu/android/pooled_shared_image_video_provider_unittest.cc11
-rw-r--r--chromium/media/gpu/android/promotion_hint_aggregator_impl.h2
-rw-r--r--chromium/media/gpu/android/shared_image_video_provider.h4
-rw-r--r--chromium/media/gpu/android/surface_chooser_helper.cc4
-rw-r--r--chromium/media/gpu/android/surface_chooser_helper.h2
-rw-r--r--chromium/media/gpu/android/surface_chooser_helper_unittest.cc2
-rw-r--r--chromium/media/gpu/android/video_frame_factory.h6
-rw-r--r--chromium/media/gpu/android/video_frame_factory_impl.cc22
-rw-r--r--chromium/media/gpu/android/video_frame_factory_impl.h13
-rw-r--r--chromium/media/gpu/av1_decoder.h6
-rw-r--r--chromium/media/gpu/av1_picture.h2
-rw-r--r--chromium/media/gpu/chromeos/chromeos_video_decoder_factory.cc30
-rw-r--r--chromium/media/gpu/chromeos/dmabuf_video_frame_pool.h4
-rw-r--r--chromium/media/gpu/chromeos/fourcc.cc25
-rw-r--r--chromium/media/gpu/chromeos/fourcc.h14
-rw-r--r--chromium/media/gpu/chromeos/fourcc_unittests.cc16
-rw-r--r--chromium/media/gpu/chromeos/gpu_buffer_layout.cc4
-rw-r--r--chromium/media/gpu/chromeos/gpu_buffer_layout.h4
-rw-r--r--chromium/media/gpu/chromeos/image_processor.cc4
-rw-r--r--chromium/media/gpu/chromeos/image_processor.h4
-rw-r--r--chromium/media/gpu/chromeos/image_processor_factory.h2
-rw-r--r--chromium/media/gpu/chromeos/image_processor_with_pool.cc2
-rw-r--r--chromium/media/gpu/chromeos/libyuv_image_processor_backend.cc1
-rw-r--r--chromium/media/gpu/chromeos/mailbox_video_frame_converter.cc7
-rw-r--r--chromium/media/gpu/chromeos/platform_video_frame_pool.cc12
-rw-r--r--chromium/media/gpu/chromeos/platform_video_frame_pool.h10
-rw-r--r--chromium/media/gpu/chromeos/platform_video_frame_pool_unittest.cc4
-rw-r--r--chromium/media/gpu/chromeos/platform_video_frame_utils.cc7
-rw-r--r--chromium/media/gpu/chromeos/platform_video_frame_utils.h2
-rw-r--r--chromium/media/gpu/chromeos/platform_video_frame_utils_unittest.cc8
-rw-r--r--chromium/media/gpu/chromeos/vd_video_decode_accelerator.cc16
-rw-r--r--chromium/media/gpu/chromeos/vd_video_decode_accelerator.h13
-rw-r--r--chromium/media/gpu/chromeos/vda_video_frame_pool.cc10
-rw-r--r--chromium/media/gpu/chromeos/vda_video_frame_pool.h18
-rw-r--r--chromium/media/gpu/chromeos/video_decoder_pipeline.cc16
-rw-r--r--chromium/media/gpu/chromeos/video_decoder_pipeline.h8
-rw-r--r--chromium/media/gpu/chromeos/video_decoder_pipeline_unittest.cc2
-rw-r--r--chromium/media/gpu/command_buffer_helper.cc62
-rw-r--r--chromium/media/gpu/gles2_decoder_helper.h2
-rw-r--r--chromium/media/gpu/gpu_video_accelerator_util.h2
-rw-r--r--chromium/media/gpu/gpu_video_decode_accelerator_factory.cc2
-rw-r--r--chromium/media/gpu/gpu_video_encode_accelerator_factory.cc5
-rw-r--r--chromium/media/gpu/h264_decoder.cc4
-rw-r--r--chromium/media/gpu/h264_decoder.h6
-rw-r--r--chromium/media/gpu/h265_decoder.cc2
-rw-r--r--chromium/media/gpu/ipc/common/BUILD.gn2
-rw-r--r--chromium/media/gpu/ipc/common/create_video_encoder_params.cc19
-rw-r--r--chromium/media/gpu/ipc/common/create_video_encoder_params.h26
-rw-r--r--chromium/media/gpu/ipc/common/media_messages.h1
-rw-r--r--chromium/media/gpu/ipc/common/media_param_traits_macros.h9
-rw-r--r--chromium/media/gpu/ipc/service/media_gpu_channel.h9
-rw-r--r--chromium/media/gpu/mac/vt_config_util.h4
-rw-r--r--chromium/media/gpu/mac/vt_config_util.mm2
-rw-r--r--chromium/media/gpu/mac/vt_config_util_unittest.cc6
-rw-r--r--chromium/media/gpu/mac/vt_video_decode_accelerator_mac.cc6
-rw-r--r--chromium/media/gpu/mac/vt_video_encode_accelerator_mac.cc14
-rw-r--r--chromium/media/gpu/mac/vt_video_encode_accelerator_mac.h7
-rw-r--r--chromium/media/gpu/v4l2/BUILD.gn4
-rw-r--r--chromium/media/gpu/v4l2/buffer_affinity_tracker.cc4
-rw-r--r--chromium/media/gpu/v4l2/buffer_affinity_tracker.h10
-rw-r--r--chromium/media/gpu/v4l2/v4l2_decode_surface.h2
-rw-r--r--chromium/media/gpu/v4l2/v4l2_device.cc98
-rw-r--r--chromium/media/gpu/v4l2/v4l2_device.h42
-rw-r--r--chromium/media/gpu/v4l2/v4l2_framerate_control.cc129
-rw-r--r--chromium/media/gpu/v4l2/v4l2_framerate_control.h61
-rw-r--r--chromium/media/gpu/v4l2/v4l2_h264_accelerator.cc53
-rw-r--r--chromium/media/gpu/v4l2/v4l2_h264_accelerator.h10
-rw-r--r--chromium/media/gpu/v4l2/v4l2_h264_accelerator_chromium.cc491
-rw-r--r--chromium/media/gpu/v4l2/v4l2_h264_accelerator_chromium.h78
-rw-r--r--chromium/media/gpu/v4l2/v4l2_image_processor_backend.cc10
-rw-r--r--chromium/media/gpu/v4l2/v4l2_image_processor_backend.h4
-rw-r--r--chromium/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h3
-rw-r--r--chromium/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.cc4
-rw-r--r--chromium/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc35
-rw-r--r--chromium/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h6
-rw-r--r--chromium/media/gpu/v4l2/v4l2_vda_helpers.cc8
-rw-r--r--chromium/media/gpu/v4l2/v4l2_vda_helpers.h6
-rw-r--r--chromium/media/gpu/v4l2/v4l2_video_decode_accelerator.cc6
-rw-r--r--chromium/media/gpu/v4l2/v4l2_video_decode_accelerator.h8
-rw-r--r--chromium/media/gpu/v4l2/v4l2_video_decoder.cc12
-rw-r--r--chromium/media/gpu/v4l2/v4l2_video_decoder.h2
-rw-r--r--chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc13
-rw-r--r--chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h15
-rw-r--r--chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.cc21
-rw-r--r--chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h4
-rw-r--r--chromium/media/gpu/v4l2/v4l2_video_encode_accelerator.cc88
-rw-r--r--chromium/media/gpu/v4l2/v4l2_video_encode_accelerator.h12
-rw-r--r--chromium/media/gpu/v4l2/v4l2_vp8_accelerator.h2
-rw-r--r--chromium/media/gpu/v4l2/v4l2_vp8_accelerator_legacy.h2
-rw-r--r--chromium/media/gpu/v4l2/v4l2_vp9_accelerator_legacy.h2
-rw-r--r--chromium/media/gpu/vaapi/OWNERS2
-rw-r--r--chromium/media/gpu/vaapi/h264_encoder.cc2
-rw-r--r--chromium/media/gpu/vaapi/h264_encoder_unittest.cc4
-rw-r--r--chromium/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.cc6
-rw-r--r--chromium/media/gpu/vaapi/vaapi_picture_factory.cc1
-rw-r--r--chromium/media/gpu/vaapi/vaapi_unittest.cc28
-rw-r--r--chromium/media/gpu/vaapi/vaapi_video_decode_accelerator.cc12
-rw-r--r--chromium/media/gpu/vaapi/vaapi_video_decode_accelerator.h7
-rw-r--r--chromium/media/gpu/vaapi/vaapi_video_decoder.cc26
-rw-r--r--chromium/media/gpu/vaapi/vaapi_video_decoder.h18
-rw-r--r--chromium/media/gpu/vaapi/vaapi_video_encode_accelerator.cc4
-rw-r--r--chromium/media/gpu/vaapi/vaapi_wrapper.cc37
-rw-r--r--chromium/media/gpu/vaapi/vaapi_wrapper.h17
-rw-r--r--chromium/media/gpu/vaapi/vp9_encoder_unittest.cc22
-rw-r--r--chromium/media/gpu/vaapi/vp9_rate_control.h2
-rw-r--r--chromium/media/gpu/vaapi/vp9_temporal_layers_unittest.cc3
-rw-r--r--chromium/media/gpu/video_decode_accelerator_perf_tests.cc1
-rw-r--r--chromium/media/gpu/video_encode_accelerator_perf_tests.cc5
-rw-r--r--chromium/media/gpu/video_encode_accelerator_tests.cc20
-rw-r--r--chromium/media/gpu/vp9_picture.h4
-rw-r--r--chromium/media/gpu/windows/d3d11_copying_texture_wrapper.cc2
-rw-r--r--chromium/media/gpu/windows/d3d11_copying_texture_wrapper.h8
-rw-r--r--chromium/media/gpu/windows/d3d11_copying_texture_wrapper_unittest.cc10
-rw-r--r--chromium/media/gpu/windows/d3d11_h264_accelerator.h2
-rw-r--r--chromium/media/gpu/windows/d3d11_texture_selector.cc25
-rw-r--r--chromium/media/gpu/windows/d3d11_texture_selector.h4
-rw-r--r--chromium/media/gpu/windows/d3d11_texture_selector_unittest.cc2
-rw-r--r--chromium/media/gpu/windows/d3d11_texture_wrapper.cc334
-rw-r--r--chromium/media/gpu/windows/d3d11_texture_wrapper.h42
-rw-r--r--chromium/media/gpu/windows/d3d11_texture_wrapper_unittest.cc22
-rw-r--r--chromium/media/gpu/windows/d3d11_video_decoder.cc2
-rw-r--r--chromium/media/gpu/windows/d3d11_video_decoder.h6
-rw-r--r--chromium/media/gpu/windows/d3d11_video_decoder_impl.h6
-rw-r--r--chromium/media/gpu/windows/d3d11_video_decoder_unittest.cc12
-rw-r--r--chromium/media/gpu/windows/d3d11_video_device_format_support.h3
-rw-r--r--chromium/media/gpu/windows/dxva_video_decode_accelerator_win.cc56
-rw-r--r--chromium/media/gpu/windows/dxva_video_decode_accelerator_win.h5
-rw-r--r--chromium/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc200
-rw-r--r--chromium/media/gpu/windows/media_foundation_video_encode_accelerator_win.h17
-rw-r--r--chromium/media/gpu/windows/output_with_release_mailbox_cb.h6
-rw-r--r--chromium/media/learning/common/learning_task.h4
-rw-r--r--chromium/media/learning/common/learning_task_controller.h12
-rw-r--r--chromium/media/learning/impl/distribution_reporter.h6
-rw-r--r--chromium/media/learning/impl/feature_provider.h3
-rw-r--r--chromium/media/learning/impl/fisher_iris_dataset.h2
-rw-r--r--chromium/media/learning/impl/learning_fuzzertest.cc4
-rw-r--r--chromium/media/learning/impl/learning_session_impl.cc12
-rw-r--r--chromium/media/learning/impl/learning_session_impl_unittest.cc20
-rw-r--r--chromium/media/learning/impl/learning_task_controller_helper.cc2
-rw-r--r--chromium/media/learning/impl/learning_task_controller_helper.h2
-rw-r--r--chromium/media/learning/impl/learning_task_controller_helper_unittest.cc12
-rw-r--r--chromium/media/learning/impl/learning_task_controller_impl.cc8
-rw-r--r--chromium/media/learning/impl/learning_task_controller_impl.h6
-rw-r--r--chromium/media/learning/impl/learning_task_controller_impl_unittest.cc18
-rw-r--r--chromium/media/learning/impl/lookup_table_trainer.h3
-rw-r--r--chromium/media/learning/impl/model.h1
-rw-r--r--chromium/media/learning/impl/one_hot.h4
-rw-r--r--chromium/media/learning/impl/random_number_generator.h1
-rw-r--r--chromium/media/learning/impl/random_tree_trainer.cc6
-rw-r--r--chromium/media/learning/mojo/mojo_learning_task_controller_service.cc4
-rw-r--r--chromium/media/learning/mojo/mojo_learning_task_controller_service.h4
-rw-r--r--chromium/media/learning/mojo/mojo_learning_task_controller_service_unittest.cc28
-rw-r--r--chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller.cc6
-rw-r--r--chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller.h8
-rw-r--r--chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller_unittest.cc26
-rw-r--r--chromium/media/learning/mojo/public/mojom/learning_task_controller.mojom2
-rw-r--r--chromium/media/media_options.gni3
-rw-r--r--chromium/media/midi/DIR_METADATA4
-rw-r--r--chromium/media/midi/midi_manager_alsa_unittest.cc151
-rw-r--r--chromium/media/midi/midi_manager_win.cc9
-rw-r--r--chromium/media/midi/midi_manager_winrt.cc5
-rw-r--r--chromium/media/midi/midi_output_port_android.h1
-rw-r--r--chromium/media/midi/task_service.cc2
-rw-r--r--chromium/media/midi/usb_midi_device_factory_android.h1
-rw-r--r--chromium/media/mojo/clients/mojo_android_overlay.h6
-rw-r--r--chromium/media/mojo/clients/mojo_android_overlay_unittest.cc6
-rw-r--r--chromium/media/mojo/clients/mojo_audio_decoder.cc2
-rw-r--r--chromium/media/mojo/clients/mojo_cdm.cc2
-rw-r--r--chromium/media/mojo/clients/mojo_cdm.h4
-rw-r--r--chromium/media/mojo/clients/mojo_demuxer_stream_impl.cc8
-rw-r--r--chromium/media/mojo/clients/mojo_renderer.cc8
-rw-r--r--chromium/media/mojo/clients/mojo_renderer.h6
-rw-r--r--chromium/media/mojo/clients/mojo_renderer_wrapper.cc2
-rw-r--r--chromium/media/mojo/clients/mojo_renderer_wrapper.h2
-rw-r--r--chromium/media/mojo/clients/mojo_video_decoder.cc6
-rw-r--r--chromium/media/mojo/clients/mojo_video_decoder.h2
-rw-r--r--chromium/media/mojo/clients/mojo_video_encode_accelerator_unittest.cc12
-rw-r--r--chromium/media/mojo/clients/win/media_foundation_renderer_client.cc4
-rw-r--r--chromium/media/mojo/clients/win/media_foundation_renderer_client.h4
-rw-r--r--chromium/media/mojo/common/BUILD.gn4
-rw-r--r--chromium/media/mojo/common/input_error_code_converter.cc18
-rw-r--r--chromium/media/mojo/common/input_error_code_converter.h16
-rw-r--r--chromium/media/mojo/common/mojo_data_pipe_read_write.h2
-rw-r--r--chromium/media/mojo/common/mojo_decoder_buffer_converter.h6
-rw-r--r--chromium/media/mojo/mojom/BUILD.gn15
-rw-r--r--chromium/media/mojo/mojom/audio_input_stream.mojom3
-rw-r--r--chromium/media/mojo/mojom/capture_handle.mojom13
-rw-r--r--chromium/media/mojo/mojom/cdm_capability_mojom_traits.cc39
-rw-r--r--chromium/media/mojo/mojom/cdm_capability_mojom_traits.h50
-rw-r--r--chromium/media/mojo/mojom/display_media_information.mojom3
-rw-r--r--chromium/media/mojo/mojom/key_system_support.mojom17
-rw-r--r--chromium/media/mojo/mojom/media_types.mojom7
-rw-r--r--chromium/media/mojo/mojom/output_protection.mojom6
-rw-r--r--chromium/media/mojo/mojom/pipeline_status_mojom_traits.h2
-rw-r--r--chromium/media/mojo/mojom/platform_verification.mojom2
-rw-r--r--chromium/media/mojo/mojom/speech_recognition_service.mojom47
-rw-r--r--chromium/media/mojo/mojom/status_mojom_traits.cc4
-rw-r--r--chromium/media/mojo/mojom/status_mojom_traits.h10
-rw-r--r--chromium/media/mojo/mojom/video_decoder_config_mojom_traits.cc2
-rw-r--r--chromium/media/mojo/mojom/video_decoder_config_mojom_traits.h2
-rw-r--r--chromium/media/mojo/mojom/video_encode_accelerator.mojom1
-rw-r--r--chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits.cc12
-rw-r--r--chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits.h5
-rw-r--r--chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits_unittest.cc2
-rw-r--r--chromium/media/mojo/mojom/video_frame_metadata_mojom_traits.cc4
-rw-r--r--chromium/media/mojo/mojom/video_frame_metadata_mojom_traits.h28
-rw-r--r--chromium/media/mojo/mojom/video_frame_mojom_traits.cc6
-rw-r--r--chromium/media/mojo/mojom/video_frame_mojom_traits.h7
-rw-r--r--chromium/media/mojo/services/BUILD.gn22
-rw-r--r--chromium/media/mojo/services/gpu_mojo_media_client.cc6
-rw-r--r--chromium/media/mojo/services/gpu_mojo_media_client.h6
-rw-r--r--chromium/media/mojo/services/media_foundation_mojo_media_client.cc8
-rw-r--r--chromium/media/mojo/services/media_foundation_mojo_media_client.h4
-rw-r--r--chromium/media/mojo/services/media_foundation_renderer_wrapper.cc7
-rw-r--r--chromium/media/mojo/services/media_foundation_renderer_wrapper.h2
-rw-r--r--chromium/media/mojo/services/media_foundation_service.cc23
-rw-r--r--chromium/media/mojo/services/media_foundation_service.h15
-rw-r--r--chromium/media/mojo/services/media_metrics_provider.h2
-rw-r--r--chromium/media/mojo/services/media_mojo_export.h6
-rw-r--r--chromium/media/mojo/services/mojo_audio_decoder_service.cc2
-rw-r--r--chromium/media/mojo/services/mojo_audio_decoder_service.h4
-rw-r--r--chromium/media/mojo/services/mojo_audio_input_stream.cc2
-rw-r--r--chromium/media/mojo/services/mojo_audio_input_stream_unittest.cc12
-rw-r--r--chromium/media/mojo/services/mojo_audio_output_stream_provider.h2
-rw-r--r--chromium/media/mojo/services/mojo_cdm_promise.cc1
-rw-r--r--chromium/media/mojo/services/mojo_cdm_promise.h1
-rw-r--r--chromium/media/mojo/services/mojo_cdm_service.h2
-rw-r--r--chromium/media/mojo/services/mojo_demuxer_stream_adapter.cc12
-rw-r--r--chromium/media/mojo/services/mojo_demuxer_stream_adapter.h14
-rw-r--r--chromium/media/mojo/services/mojo_media_client.h1
-rw-r--r--chromium/media/mojo/services/mojo_media_drm_storage.cc4
-rw-r--r--chromium/media/mojo/services/mojo_renderer_service.cc8
-rw-r--r--chromium/media/mojo/services/mojo_renderer_service.h6
-rw-r--r--chromium/media/mojo/services/mojo_video_decoder_service.cc6
-rw-r--r--chromium/media/mojo/services/mojo_video_decoder_service.h6
-rw-r--r--chromium/media/mojo/services/playback_events_recorder.h2
-rw-r--r--chromium/media/mojo/services/video_decode_perf_history_unittest.cc1
-rw-r--r--chromium/media/mojo/services/video_decode_stats_recorder.h2
-rw-r--r--chromium/media/mojo/services/watch_time_recorder.cc8
-rw-r--r--chromium/media/mojo/services/watch_time_recorder.h2
-rw-r--r--chromium/media/mojo/services/watch_time_recorder_unittest.cc22
-rw-r--r--chromium/media/muxers/DIR_METADATA4
-rw-r--r--chromium/media/muxers/webm_muxer.cc14
-rw-r--r--chromium/media/muxers/webm_muxer.h7
-rw-r--r--chromium/media/remoting/DIR_METADATA4
-rw-r--r--chromium/media/remoting/courier_renderer.cc8
-rw-r--r--chromium/media/remoting/courier_renderer.h2
-rw-r--r--chromium/media/remoting/courier_renderer_unittest.cc4
-rw-r--r--chromium/media/remoting/demuxer_stream_adapter.cc4
-rw-r--r--chromium/media/remoting/demuxer_stream_adapter.h6
-rw-r--r--chromium/media/remoting/end2end_test_renderer.cc2
-rw-r--r--chromium/media/remoting/end2end_test_renderer.h8
-rw-r--r--chromium/media/remoting/integration_test.cc4
-rw-r--r--chromium/media/remoting/metrics.cc6
-rw-r--r--chromium/media/remoting/metrics.h8
-rw-r--r--chromium/media/remoting/metrics_unittest.cc10
-rw-r--r--chromium/media/remoting/proto_enum_utils.cc62
-rw-r--r--chromium/media/remoting/proto_enum_utils.h34
-rw-r--r--chromium/media/remoting/receiver.cc4
-rw-r--r--chromium/media/remoting/receiver.h4
-rw-r--r--chromium/media/remoting/receiver_unittest.cc4
-rw-r--r--chromium/media/remoting/renderer_controller.h2
-rw-r--r--chromium/media/remoting/stream_provider.cc4
-rw-r--r--chromium/media/remoting/stream_provider.h2
-rw-r--r--chromium/media/renderers/BUILD.gn4
-rw-r--r--chromium/media/renderers/audio_renderer_impl.cc4
-rw-r--r--chromium/media/renderers/audio_renderer_impl.h6
-rw-r--r--chromium/media/renderers/audio_renderer_impl_unittest.cc2
-rw-r--r--chromium/media/renderers/decrypting_renderer.cc2
-rw-r--r--chromium/media/renderers/decrypting_renderer.h2
-rw-r--r--chromium/media/renderers/default_decoder_factory.cc15
-rw-r--r--chromium/media/renderers/paint_canvas_video_renderer.cc27
-rw-r--r--chromium/media/renderers/paint_canvas_video_renderer.h5
-rw-r--r--chromium/media/renderers/paint_canvas_video_renderer_unittest.cc5
-rw-r--r--chromium/media/renderers/renderer_impl.cc6
-rw-r--r--chromium/media/renderers/renderer_impl.h4
-rw-r--r--chromium/media/renderers/renderer_impl_unittest.cc2
-rw-r--r--chromium/media/renderers/video_frame_yuv_converter.cc352
-rw-r--r--chromium/media/renderers/video_frame_yuv_converter.h4
-rw-r--r--chromium/media/renderers/video_frame_yuv_mailboxes_holder.cc346
-rw-r--r--chromium/media/renderers/video_frame_yuv_mailboxes_holder.h99
-rw-r--r--chromium/media/renderers/video_renderer_impl.cc4
-rw-r--r--chromium/media/renderers/video_renderer_impl.h6
-rw-r--r--chromium/media/renderers/video_renderer_impl_unittest.cc24
-rw-r--r--chromium/media/renderers/video_resource_updater.cc15
-rw-r--r--chromium/media/renderers/video_resource_updater.h4
-rw-r--r--chromium/media/renderers/video_resource_updater_unittest.cc45
-rw-r--r--chromium/media/renderers/win/media_engine_notify_impl.h1
-rw-r--r--chromium/media/renderers/win/media_foundation_protection_manager.cc14
-rw-r--r--chromium/media/renderers/win/media_foundation_protection_manager.h8
-rw-r--r--chromium/media/renderers/win/media_foundation_renderer.cc8
-rw-r--r--chromium/media/renderers/win/media_foundation_renderer.h4
-rw-r--r--chromium/media/renderers/win/media_foundation_renderer_factory.cc34
-rw-r--r--chromium/media/renderers/win/media_foundation_renderer_factory.h37
-rw-r--r--chromium/media/renderers/win/media_foundation_renderer_integration_test.cc2
-rw-r--r--chromium/media/renderers/win/media_foundation_renderer_unittest.cc81
-rw-r--r--chromium/media/renderers/win/media_foundation_source_wrapper.cc7
-rw-r--r--chromium/media/renderers/win/media_foundation_source_wrapper.h8
-rw-r--r--chromium/media/video/fake_gpu_memory_buffer.cc2
-rw-r--r--chromium/media/video/gpu_memory_buffer_video_frame_pool.cc36
-rw-r--r--chromium/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc7
-rw-r--r--chromium/media/video/gpu_video_accelerator_factories.h12
-rw-r--r--chromium/media/video/h264_level_limits.cc4
-rw-r--r--chromium/media/video/h264_level_limits.h6
-rw-r--r--chromium/media/video/h264_parser.cc14
-rw-r--r--chromium/media/video/h264_parser.h8
-rw-r--r--chromium/media/video/h264_parser_fuzzertest.cc6
-rw-r--r--chromium/media/video/h264_parser_unittest.cc8
-rw-r--r--chromium/media/video/h264_poc.cc8
-rw-r--r--chromium/media/video/h264_poc.h2
-rw-r--r--chromium/media/video/h264_poc_unittest.cc2
-rw-r--r--chromium/media/video/h265_parser.cc8
-rw-r--r--chromium/media/video/h265_parser.h5
-rw-r--r--chromium/media/video/mock_gpu_video_accelerator_factories.h2
-rw-r--r--chromium/media/video/openh264_video_encoder.cc5
-rw-r--r--chromium/media/video/openh264_video_encoder.h1
-rw-r--r--chromium/media/video/software_video_encoder_test.cc54
-rw-r--r--chromium/media/video/video_decode_accelerator.h6
-rw-r--r--chromium/media/video/video_encode_accelerator.cc8
-rw-r--r--chromium/media/video/video_encode_accelerator.h30
-rw-r--r--chromium/media/video/video_encode_accelerator_adapter.cc15
-rw-r--r--chromium/media/video/video_encode_accelerator_adapter.h6
-rw-r--r--chromium/media/video/video_encode_accelerator_adapter_test.cc17
-rw-r--r--chromium/media/video/video_encoder_info.h2
-rw-r--r--chromium/media/video/vpx_video_encoder.h3
-rw-r--r--chromium/media/webrtc/DIR_METADATA4
-rw-r--r--chromium/media/webrtc/helpers.h2
-rw-r--r--chromium/media/webrtc/webrtc_switches.cc9
-rw-r--r--chromium/media/webrtc/webrtc_switches.h6
877 files changed, 10840 insertions, 12505 deletions
diff --git a/chromium/media/BUILD.gn b/chromium/media/BUILD.gn
index 7e7271097d2..740789d1dcc 100644
--- a/chromium/media/BUILD.gn
+++ b/chromium/media/BUILD.gn
@@ -196,10 +196,17 @@ test("media_unittests") {
}
if (is_fuchsia) {
+ deps += [
+ "//media/fuchsia/audio:unittests",
+ "//media/fuchsia/cdm/service:unittests",
+ ]
+
additional_manifest_fragments = [
"//build/config/fuchsia/test/audio_capabilities.test-cmx",
- # TODO(crbug.com/1185811): Figure out why jit_capabilities is needed.
+ # TODO(crbug.com/1185811): Figure out why
+ # PaintCanvasVideoRendererWithGLTest.CopyVideoFrameYUVDataToGLTexture
+ # crashes without "deprecated-ambient-replace-as-executable".
"//build/config/fuchsia/test/jit_capabilities.test-cmx",
"//build/config/fuchsia/test/vulkan_capabilities.test-cmx",
diff --git a/chromium/media/DIR_METADATA b/chromium/media/DIR_METADATA
index 9f769ce7f98..2dc14a41ec9 100644
--- a/chromium/media/DIR_METADATA
+++ b/chromium/media/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Internals>Media"
diff --git a/chromium/media/audio/BUILD.gn b/chromium/media/audio/BUILD.gn
index c68099d5baa..d7a46d050eb 100644
--- a/chromium/media/audio/BUILD.gn
+++ b/chromium/media/audio/BUILD.gn
@@ -201,6 +201,8 @@ source_set("audio") {
"win/core_audio_util_win.h",
"win/device_enumeration_win.cc",
"win/device_enumeration_win.h",
+ "win/volume_range_util.cc",
+ "win/volume_range_util.h",
"win/waveout_output_win.cc",
"win/waveout_output_win.h",
]
@@ -445,6 +447,7 @@ source_set("unit_tests") {
if (use_cras) {
sources += [
+ "cras/audio_manager_chromeos_unittest.cc",
"cras/cras_input_unittest.cc",
"cras/cras_unified_unittest.cc",
]
@@ -460,6 +463,7 @@ source_set("unit_tests") {
"win/audio_session_event_listener_win_unittest.cc",
"win/core_audio_util_win_unittest.cc",
"win/device_enumeration_win_unittest.cc",
+ "win/volume_range_util_unittest.cc",
]
}
diff --git a/chromium/media/audio/DIR_METADATA b/chromium/media/audio/DIR_METADATA
index 99031e09f7e..e80d793156b 100644
--- a/chromium/media/audio/DIR_METADATA
+++ b/chromium/media/audio/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Internals>Media>Audio"
diff --git a/chromium/media/audio/alsa/alsa_input.cc b/chromium/media/audio/alsa/alsa_input.cc
index ee7c5d0305d..404516dcdcb 100644
--- a/chromium/media/audio/alsa/alsa_input.cc
+++ b/chromium/media/audio/alsa/alsa_input.cc
@@ -52,9 +52,9 @@ AlsaPcmInputStream::AlsaPcmInputStream(AudioManagerBase* audio_manager,
AlsaPcmInputStream::~AlsaPcmInputStream() = default;
-bool AlsaPcmInputStream::Open() {
+AudioInputStream::OpenOutcome AlsaPcmInputStream::Open() {
if (device_handle_)
- return false; // Already open.
+ return OpenOutcome::kAlreadyOpen;
uint32_t packet_us = buffer_duration_.InMicroseconds();
uint32_t buffer_us = packet_us * kNumPacketsInRingBuffer;
@@ -91,7 +91,8 @@ bool AlsaPcmInputStream::Open() {
}
}
- return device_handle_ != nullptr;
+ return device_handle_ != nullptr ? OpenOutcome::kSuccess
+ : OpenOutcome::kFailed;
}
void AlsaPcmInputStream::Start(AudioInputCallback* callback) {
@@ -112,7 +113,7 @@ void AlsaPcmInputStream::Start(AudioInputCallback* callback) {
} else {
base::Thread::Options options;
options.priority = base::ThreadPriority::REALTIME_AUDIO;
- CHECK(capture_thread_.StartWithOptions(options));
+ CHECK(capture_thread_.StartWithOptions(std::move(options)));
// We start reading data half |buffer_duration_| later than when the
// buffer might have got filled, to accommodate some delays in the audio
diff --git a/chromium/media/audio/alsa/alsa_input.h b/chromium/media/audio/alsa/alsa_input.h
index 09e525f826f..6301fba9afc 100644
--- a/chromium/media/audio/alsa/alsa_input.h
+++ b/chromium/media/audio/alsa/alsa_input.h
@@ -46,7 +46,7 @@ class MEDIA_EXPORT AlsaPcmInputStream
~AlsaPcmInputStream() override;
// Implementation of AudioInputStream.
- bool Open() override;
+ OpenOutcome Open() override;
void Start(AudioInputCallback* callback) override;
void Stop() override;
void Close() override;
diff --git a/chromium/media/audio/alsa/alsa_output.cc b/chromium/media/audio/alsa/alsa_output.cc
index c2cc61d1d8c..c148f26b5ac 100644
--- a/chromium/media/audio/alsa/alsa_output.cc
+++ b/chromium/media/audio/alsa/alsa_output.cc
@@ -37,6 +37,7 @@
#include <stddef.h>
#include <algorithm>
+#include <memory>
#include <utility>
#include "base/bind.h"
@@ -230,7 +231,7 @@ bool AlsaPcmOutputStream::Open() {
channel_mixer_ ? mixed_audio_bus_->channels() * bytes_per_sample_
: bytes_per_frame_;
uint32_t output_packet_size = frames_per_packet_ * bytes_per_output_frame_;
- buffer_.reset(new SeekableBuffer(0, output_packet_size));
+ buffer_ = std::make_unique<SeekableBuffer>(0, output_packet_size);
// Get alsa buffer size.
snd_pcm_uframes_t buffer_size;
@@ -710,8 +711,8 @@ snd_pcm_t* AlsaPcmOutputStream::AutoSelectDevice(unsigned int latency) {
// downmixing.
uint32_t default_channels = channels_;
if (default_channels > 2) {
- channel_mixer_.reset(
- new ChannelMixer(channel_layout_, kDefaultOutputChannelLayout));
+ channel_mixer_ = std::make_unique<ChannelMixer>(
+ channel_layout_, kDefaultOutputChannelLayout);
default_channels = 2;
mixed_audio_bus_ = AudioBus::Create(
default_channels, audio_bus_->frames());
diff --git a/chromium/media/audio/alsa/alsa_output_unittest.cc b/chromium/media/audio/alsa/alsa_output_unittest.cc
index 9183721af1b..33fd1c5d0c8 100644
--- a/chromium/media/audio/alsa/alsa_output_unittest.cc
+++ b/chromium/media/audio/alsa/alsa_output_unittest.cc
@@ -80,7 +80,7 @@ class MockAudioManagerAlsa : public AudioManagerAlsa {
class AlsaPcmOutputStreamTest : public testing::Test {
protected:
AlsaPcmOutputStreamTest() {
- mock_manager_.reset(new StrictMock<MockAudioManagerAlsa>());
+ mock_manager_ = std::make_unique<StrictMock<MockAudioManagerAlsa>>();
}
~AlsaPcmOutputStreamTest() override { mock_manager_->Shutdown(); }
@@ -115,7 +115,7 @@ class AlsaPcmOutputStreamTest : public testing::Test {
DCHECK(test_stream);
packet_ = new DataBuffer(kTestPacketSize);
packet_->set_data_size(kTestPacketSize);
- test_stream->buffer_.reset(new SeekableBuffer(0, kTestPacketSize));
+ test_stream->buffer_ = std::make_unique<SeekableBuffer>(0, kTestPacketSize);
test_stream->buffer_->Append(packet_.get());
}
diff --git a/chromium/media/audio/android/aaudio_output.cc b/chromium/media/audio/android/aaudio_output.cc
index 9e9b53ab89b..c054f3910a2 100644
--- a/chromium/media/audio/android/aaudio_output.cc
+++ b/chromium/media/audio/android/aaudio_output.cc
@@ -4,7 +4,10 @@
#include "media/audio/android/aaudio_output.h"
+#include "base/callback_helpers.h"
#include "base/logging.h"
+#include "base/thread_annotations.h"
+#include "base/threading/sequenced_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "media/audio/android/aaudio_stubs.h"
#include "media/audio/android/audio_manager_android.h"
@@ -12,14 +15,58 @@
namespace media {
+// Used to circumvent issues where the AAudio thread callbacks continue
+// after AAudioStream_requestStop() completes. See crbug.com/1183255.
+class LOCKABLE AAudioDestructionHelper {
+ public:
+ explicit AAudioDestructionHelper(AAudioOutputStream* stream)
+ : output_stream_(stream) {}
+
+ ~AAudioDestructionHelper() {
+ DCHECK(is_closing_);
+ if (aaudio_stream_)
+ AAudioStream_close(aaudio_stream_);
+ }
+
+ AAudioOutputStream* GetAndLockStream() EXCLUSIVE_LOCK_FUNCTION() {
+ lock_.Acquire();
+ return is_closing_ ? nullptr : output_stream_;
+ }
+
+ void UnlockStream() UNLOCK_FUNCTION() { lock_.Release(); }
+
+ void DeferStreamClosure(AAudioStream* stream) {
+ base::AutoLock al(lock_);
+ DCHECK(!is_closing_);
+
+ is_closing_ = true;
+ aaudio_stream_ = stream;
+ }
+
+ private:
+ base::Lock lock_;
+ AAudioOutputStream* output_stream_ GUARDED_BY(lock_) = nullptr;
+ AAudioStream* aaudio_stream_ GUARDED_BY(lock_) = nullptr;
+ bool is_closing_ GUARDED_BY(lock_) = false;
+};
+
static aaudio_data_callback_result_t OnAudioDataRequestedCallback(
AAudioStream* stream,
void* user_data,
void* audio_data,
int32_t num_frames) {
- AAudioOutputStream* output_stream =
- reinterpret_cast<AAudioOutputStream*>(user_data);
- return output_stream->OnAudioDataRequested(audio_data, num_frames);
+ AAudioDestructionHelper* destruction_helper =
+ reinterpret_cast<AAudioDestructionHelper*>(user_data);
+
+ AAudioOutputStream* output_stream = destruction_helper->GetAndLockStream();
+
+ aaudio_data_callback_result_t result = AAUDIO_CALLBACK_RESULT_STOP;
+ if (output_stream)
+ result = output_stream->OnAudioDataRequested(audio_data, num_frames);
+
+ destruction_helper->UnlockStream();
+
+ return result;
}
static void OnStreamErrorCallback(AAudioStream* stream,
@@ -38,7 +85,8 @@ AAudioOutputStream::AAudioOutputStream(AudioManagerAndroid* manager,
usage_(usage),
performance_mode_(AAUDIO_PERFORMANCE_MODE_NONE),
ns_per_frame_(base::Time::kNanosecondsPerSecond /
- static_cast<double>(params.sample_rate())) {
+ static_cast<double>(params.sample_rate())),
+ destruction_helper_(std::make_unique<AAudioDestructionHelper>(this)) {
DCHECK(manager);
DCHECK(params.IsValid());
@@ -66,6 +114,18 @@ AAudioOutputStream::AAudioOutputStream(AudioManagerAndroid* manager,
AAudioOutputStream::~AAudioOutputStream() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // In R and earlier, it is possible for callbacks to still be running even
+ // after calling AAudioStream_close(). The code below is a mitigation to work
+ // around this issue. See crbug.com/1183255.
+
+ // Keep |destruction_helper_| alive longer than |this|, so the |user_data|
+ // bound to the callback stays valid until the callbacks stop.
+ base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(
+ base::DoNothing::Once<std::unique_ptr<AAudioDestructionHelper>>(),
+ std::move(destruction_helper_)),
+ base::TimeDelta::FromMilliseconds(250));
}
void AAudioOutputStream::Flush() {}
@@ -90,7 +150,7 @@ bool AAudioOutputStream::Open() {
// Callbacks
AAudioStreamBuilder_setDataCallback(builder, OnAudioDataRequestedCallback,
- this);
+ destruction_helper_.get());
AAudioStreamBuilder_setErrorCallback(builder, OnStreamErrorCallback, this);
result = AAudioStreamBuilder_openStream(builder, &aaudio_stream_);
@@ -120,13 +180,12 @@ void AAudioOutputStream::Close() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
Stop();
- if (aaudio_stream_) {
- const auto result = AAudioStream_close(aaudio_stream_);
- if (result != AAUDIO_OK) {
- DLOG(ERROR) << "Failed to close audio stream, result: "
- << AAudio_convertResultToText(result);
- }
- }
+
+ // |destruction_helper_->GetStreamAndLock()| will return nullptr after this.
+ destruction_helper_->DeferStreamClosure(aaudio_stream_);
+
+ // We shouldn't be acessing |aaudio_stream_| after it's stopped.
+ aaudio_stream_ = nullptr;
// Note: This must be last, it will delete |this|.
audio_manager_->ReleaseOutputStream(this);
diff --git a/chromium/media/audio/android/aaudio_output.h b/chromium/media/audio/android/aaudio_output.h
index 5c6b7b21de9..35343369e05 100644
--- a/chromium/media/audio/android/aaudio_output.h
+++ b/chromium/media/audio/android/aaudio_output.h
@@ -15,6 +15,7 @@
namespace media {
+class AAudioDestructionHelper;
class AudioManagerAndroid;
class AAudioOutputStream : public MuteableAudioOutputStream {
@@ -60,6 +61,10 @@ class AAudioOutputStream : public MuteableAudioOutputStream {
AAudioStream* aaudio_stream_ = nullptr;
+ // Bound to the audio data callback. Outlives |this| in case the callbacks
+ // continue after |this| is destroyed. See crbug.com/1183255.
+ std::unique_ptr<AAudioDestructionHelper> destruction_helper_;
+
// Lock protects all members below which may be read concurrently from the
// audio manager thread and the OS provided audio thread.
base::Lock lock_;
@@ -74,4 +79,4 @@ class AAudioOutputStream : public MuteableAudioOutputStream {
} // namespace media
-#endif // MEDIA_AUDIO_ANDROID_AAUDIO_OUTPUT_H_ \ No newline at end of file
+#endif // MEDIA_AUDIO_ANDROID_AAUDIO_OUTPUT_H_
diff --git a/chromium/media/audio/android/audio_android_unittest.cc b/chromium/media/audio/android/audio_android_unittest.cc
index 8dfff9017f1..20e696fc555 100644
--- a/chromium/media/audio/android/audio_android_unittest.cc
+++ b/chromium/media/audio/android/audio_android_unittest.cc
@@ -241,7 +241,7 @@ class FileAudioSink : public AudioInputStream::AudioInputCallback {
// Allocate space for ~10 seconds of data.
const int kMaxBufferSize =
10 * params.sample_rate() * params.GetBytesPerFrame(kSampleFormat);
- buffer_.reset(new media::SeekableBuffer(0, kMaxBufferSize));
+ buffer_ = std::make_unique<media::SeekableBuffer>(0, kMaxBufferSize);
// Open up the binary file which will be written to in the destructor.
base::FilePath file_path;
@@ -314,7 +314,7 @@ class FullDuplexAudioSinkSource
// Start with a reasonably small FIFO size. It will be increased
// dynamically during the test if required.
size_t buffer_size = params.GetBytesPerBuffer(kSampleFormat);
- fifo_.reset(new media::SeekableBuffer(0, 2 * buffer_size));
+ fifo_ = std::make_unique<media::SeekableBuffer>(0, 2 * buffer_size);
buffer_.reset(new uint8_t[buffer_size]);
}
@@ -691,14 +691,16 @@ class AudioAndroidInputTest : public AudioAndroidOutputTest,
void OpenAndClose() {
DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
- EXPECT_TRUE(audio_input_stream_->Open());
+ EXPECT_EQ(audio_input_stream_->Open(),
+ AudioInputStream::OpenOutcome::kSuccess);
audio_input_stream_->Close();
audio_input_stream_ = nullptr;
}
void OpenAndStart(AudioInputStream::AudioInputCallback* sink) {
DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
- EXPECT_TRUE(audio_input_stream_->Open());
+ EXPECT_EQ(audio_input_stream_->Open(),
+ AudioInputStream::OpenOutcome::kSuccess);
audio_input_stream_->Start(sink);
}
diff --git a/chromium/media/audio/android/audio_manager_android.h b/chromium/media/audio/android/audio_manager_android.h
index 742c4bbf54c..a58a4e1ddf5 100644
--- a/chromium/media/audio/android/audio_manager_android.h
+++ b/chromium/media/audio/android/audio_manager_android.h
@@ -122,7 +122,7 @@ class MEDIA_EXPORT AudioManagerAndroid : public AudioManagerBase {
// input stream is destroyed. Also affects the stream type of output streams.
bool communication_mode_is_on_;
- base::Optional<bool> is_aaudio_available_;
+ absl::optional<bool> is_aaudio_available_;
// If set, overrides volume level on output streams
bool output_volume_override_set_;
diff --git a/chromium/media/audio/android/muteable_audio_output_stream.h b/chromium/media/audio/android/muteable_audio_output_stream.h
index 8ef13a640dd..db4f6b19cb5 100644
--- a/chromium/media/audio/android/muteable_audio_output_stream.h
+++ b/chromium/media/audio/android/muteable_audio_output_stream.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_MUTEABLE_AUDIO_OUTPUT_STREAM_H_
-#define MEDIA_MUTEABLE_AUDIO_OUTPUT_STREAM_H_
+#ifndef MEDIA_AUDIO_ANDROID_MUTEABLE_AUDIO_OUTPUT_STREAM_H_
+#define MEDIA_AUDIO_ANDROID_MUTEABLE_AUDIO_OUTPUT_STREAM_H_
#include "media/audio/audio_io.h"
@@ -20,4 +20,4 @@ class MEDIA_EXPORT MuteableAudioOutputStream : public AudioOutputStream {
} // namespace media
-#endif // MEDIA_MUTEABLE_AUDIO_OUTPUT_STREAM_H_
+#endif // MEDIA_AUDIO_ANDROID_MUTEABLE_AUDIO_OUTPUT_STREAM_H_
diff --git a/chromium/media/audio/android/opensles_input.cc b/chromium/media/audio/android/opensles_input.cc
index 5949e7dee00..695277ed7f9 100644
--- a/chromium/media/audio/android/opensles_input.cc
+++ b/chromium/media/audio/android/opensles_input.cc
@@ -63,18 +63,17 @@ OpenSLESInputStream::~OpenSLESInputStream() {
DCHECK(!audio_data_[0]);
}
-bool OpenSLESInputStream::Open() {
+AudioInputStream::OpenOutcome OpenSLESInputStream::Open() {
DVLOG(2) << __PRETTY_FUNCTION__;
DCHECK(thread_checker_.CalledOnValidThread());
if (engine_object_.Get())
- return false;
+ return AudioInputStream::OpenOutcome::kFailed;
if (!CreateRecorder())
- return false;
+ return AudioInputStream::OpenOutcome::kFailed;
SetupAudioBuffer();
-
- return true;
+ return AudioInputStream::OpenOutcome::kSuccess;
}
void OpenSLESInputStream::Start(AudioInputCallback* callback) {
diff --git a/chromium/media/audio/android/opensles_input.h b/chromium/media/audio/android/opensles_input.h
index a3afed0ed77..ee354f214ae 100644
--- a/chromium/media/audio/android/opensles_input.h
+++ b/chromium/media/audio/android/opensles_input.h
@@ -38,7 +38,7 @@ class OpenSLESInputStream : public AudioInputStream {
~OpenSLESInputStream() override;
// Implementation of AudioInputStream.
- bool Open() override;
+ OpenOutcome Open() override;
void Start(AudioInputCallback* callback) override;
void Stop() override;
void Close() override;
diff --git a/chromium/media/audio/audio_encoders_unittest.cc b/chromium/media/audio/audio_encoders_unittest.cc
index c5fd70ceca1..d81a6729c5e 100644
--- a/chromium/media/audio/audio_encoders_unittest.cc
+++ b/chromium/media/audio/audio_encoders_unittest.cc
@@ -69,7 +69,7 @@ class AudioEncodersTest : public ::testing::TestWithParam<TestAudioParams> {
AudioEncodersTest& operator=(const AudioEncodersTest&) = delete;
~AudioEncodersTest() override = default;
- using MaybeDesc = base::Optional<AudioEncoder::CodecDescription>;
+ using MaybeDesc = absl::optional<AudioEncoder::CodecDescription>;
AudioEncoder* encoder() const { return encoder_.get(); }
diff --git a/chromium/media/audio/audio_features.cc b/chromium/media/audio/audio_features.cc
index d231e8f0f29..dd1c1f30fac 100644
--- a/chromium/media/audio/audio_features.cc
+++ b/chromium/media/audio/audio_features.cc
@@ -33,10 +33,19 @@ const base::Feature kUseAAudioDriver{"UseAAudioDriver",
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
-const base::Feature kCrOSSystemAEC{"CrOSSystemAEC",
+const base::Feature kCrOSSystemAEC{"CrOSSystemAECWithBoardTuningsAllowed",
base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kCrOSSystemAECDeactivatedGroups{
"CrOSSystemAECDeactivatedGroups", base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kCrOSEnforceSystemAecNsAgc{
+ "CrOSEnforceSystemAecNsAgc", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kCrOSEnforceSystemAecNs{"CrOSEnforceSystemAecNs",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kCrOSEnforceSystemAecAgc{"CrOSEnforceSystemAecAgc",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kCrOSEnforceSystemAec{"CrOSEnforceSystemAec",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
#endif
#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chromium/media/audio/audio_features.h b/chromium/media/audio/audio_features.h
index 0f3dcde21b0..38bcf40e464 100644
--- a/chromium/media/audio/audio_features.h
+++ b/chromium/media/audio/audio_features.h
@@ -22,6 +22,10 @@ MEDIA_EXPORT extern const base::Feature kUseAAudioDriver;
#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
MEDIA_EXPORT extern const base::Feature kCrOSSystemAEC;
MEDIA_EXPORT extern const base::Feature kCrOSSystemAECDeactivatedGroups;
+MEDIA_EXPORT extern const base::Feature kCrOSEnforceSystemAecNsAgc;
+MEDIA_EXPORT extern const base::Feature kCrOSEnforceSystemAecNs;
+MEDIA_EXPORT extern const base::Feature kCrOSEnforceSystemAecAgc;
+MEDIA_EXPORT extern const base::Feature kCrOSEnforceSystemAec;
#endif
#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chromium/media/audio/audio_input_device.cc b/chromium/media/audio/audio_input_device.cc
index 9e09e005df0..803c1430101 100644
--- a/chromium/media/audio/audio_input_device.cc
+++ b/chromium/media/audio/audio_input_device.cc
@@ -9,7 +9,6 @@
#include <vector>
#include "base/bind.h"
-#include "base/callback_forward.h"
#include "base/callback_helpers.h"
#include "base/format_macros.h"
#include "base/logging.h"
@@ -291,7 +290,7 @@ void AudioInputDevice::OnStreamCreated(
alive_checker_->Start();
}
-void AudioInputDevice::OnError() {
+void AudioInputDevice::OnError(AudioCapturerSource::ErrorCode code) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
TRACE_EVENT0("audio", "AudioInputDevice::OnError");
@@ -299,7 +298,6 @@ void AudioInputDevice::OnError() {
if (state_ < CREATING_STREAM)
return;
-
if (state_ == CREATING_STREAM) {
// At this point, we haven't attempted to start the audio thread.
// Accessing the hardware might have failed or we may have reached
@@ -309,7 +307,10 @@ void AudioInputDevice::OnError() {
// a local audio source).
had_error_ = kErrorDuringCreation;
callback_->OnCaptureError(
- "Maximum allowed input device limit reached or OS failure.");
+ code, code == AudioCapturerSource::ErrorCode::kSystemPermissions
+ ? "Unable to open due to failing an OS Permissions check."
+ : "Maximum allowed input device limit reached or an OS "
+ "failure occured.");
} else {
// Don't dereference the callback object if the audio thread
// is stopped or stopping. That could mean that the callback
@@ -319,7 +320,7 @@ void AudioInputDevice::OnError() {
// a callback object via Start() and clear it in Stop().
had_error_ = kErrorDuringCapture;
if (audio_thread_)
- callback_->OnCaptureError("IPC delegate state error.");
+ callback_->OnCaptureError(code, "IPC delegate state error.");
}
}
@@ -352,7 +353,8 @@ AudioInputDevice::~AudioInputDevice() {
}
void AudioInputDevice::DetectedDeadInputStream() {
- callback_->OnCaptureError("No audio received from audio capture device.");
+ callback_->OnCaptureError(media::AudioCapturerSource::ErrorCode::kUnknown,
+ "No audio received from audio capture device.");
}
// AudioInputDevice::AudioThreadCallback
@@ -432,14 +434,16 @@ void AudioInputDevice::AudioThreadCallback::Process(uint32_t pending_data) {
"Incorrect buffer sequence. Expected = %u. Actual = %u.",
last_buffer_id_ + 1, buffer->params.id);
LOG(ERROR) << message;
- capture_callback_->OnCaptureError(message);
+ capture_callback_->OnCaptureError(
+ media::AudioCapturerSource::ErrorCode::kUnknown, message);
}
if (current_segment_id_ != pending_data) {
std::string message = base::StringPrintf(
"Segment id not matching. Remote = %u. Local = %" PRIuS ".",
pending_data, current_segment_id_);
LOG(ERROR) << message;
- capture_callback_->OnCaptureError(message);
+ capture_callback_->OnCaptureError(
+ media::AudioCapturerSource::ErrorCode::kUnknown, message);
}
last_buffer_id_ = buffer->params.id;
diff --git a/chromium/media/audio/audio_input_device.h b/chromium/media/audio/audio_input_device.h
index 219b79301d8..ab9d0991cf6 100644
--- a/chromium/media/audio/audio_input_device.h
+++ b/chromium/media/audio/audio_input_device.h
@@ -51,16 +51,15 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/read_only_shared_memory_region.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/threading/platform_thread.h"
-#include "base/time/time.h"
#include "media/audio/alive_checker.h"
#include "media/audio/audio_device_thread.h"
#include "media/audio/audio_input_ipc.h"
#include "media/base/audio_capturer_source.h"
#include "media/base/audio_parameters.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -117,7 +116,7 @@ class MEDIA_EXPORT AudioInputDevice : public AudioCapturerSource,
void OnStreamCreated(base::ReadOnlySharedMemoryRegion shared_memory_region,
base::SyncSocket::ScopedHandle socket_handle,
bool initially_muted) override;
- void OnError() override;
+ void OnError(AudioCapturerSource::ErrorCode code) override;
void OnMuted(bool is_muted) override;
void OnIPCClosed() override;
@@ -161,7 +160,7 @@ class MEDIA_EXPORT AudioInputDevice : public AudioCapturerSource,
// Cache the output device used for AEC in case it's called before the stream
// is created.
- base::Optional<std::string> output_device_id_for_aec_;
+ absl::optional<std::string> output_device_id_for_aec_;
DISALLOW_IMPLICIT_CONSTRUCTORS(AudioInputDevice);
};
diff --git a/chromium/media/audio/audio_input_device_unittest.cc b/chromium/media/audio/audio_input_device_unittest.cc
index d951d344522..b0c1eba928a 100644
--- a/chromium/media/audio/audio_input_device_unittest.cc
+++ b/chromium/media/audio/audio_input_device_unittest.cc
@@ -57,7 +57,9 @@ class MockCaptureCallback : public AudioCapturerSource::CaptureCallback {
double volume,
bool key_pressed));
- MOCK_METHOD1(OnCaptureError, void(const std::string& message));
+ MOCK_METHOD2(OnCaptureError,
+ void(AudioCapturerSource::ErrorCode code,
+ const std::string& message));
MOCK_METHOD1(OnCaptureMuted, void(bool is_muted));
};
@@ -77,7 +79,8 @@ TEST_P(AudioInputDeviceTest, Noop) {
}
ACTION_P(ReportStateChange, device) {
- static_cast<AudioInputIPCDelegate*>(device)->OnError();
+ static_cast<AudioInputIPCDelegate*>(device)->OnError(
+ media::AudioCapturerSource::ErrorCode::kUnknown);
}
// Verify that we get an OnCaptureError() callback if CreateStream fails.
@@ -93,7 +96,8 @@ TEST_P(AudioInputDeviceTest, FailToCreateStream) {
device->Initialize(params, &callback);
EXPECT_CALL(*input_ipc, CreateStream(_, _, _, _))
.WillOnce(ReportStateChange(device.get()));
- EXPECT_CALL(callback, OnCaptureError(_));
+ EXPECT_CALL(callback,
+ OnCaptureError(AudioCapturerSource::ErrorCode::kUnknown, _));
EXPECT_CALL(*input_ipc, CloseStream());
device->Start();
device->Stop();
diff --git a/chromium/media/audio/audio_input_ipc.h b/chromium/media/audio/audio_input_ipc.h
index 1f2192a3a6a..28663a98ab5 100644
--- a/chromium/media/audio/audio_input_ipc.h
+++ b/chromium/media/audio/audio_input_ipc.h
@@ -9,6 +9,7 @@
#include "base/memory/read_only_shared_memory_region.h"
#include "base/sync_socket.h"
+#include "media/base/audio_capturer_source.h"
#include "media/base/audio_parameters.h"
#include "media/base/media_export.h"
@@ -30,7 +31,7 @@ class MEDIA_EXPORT AudioInputIPCDelegate {
bool initially_muted) = 0;
// Called when state of an audio stream has changed.
- virtual void OnError() = 0;
+ virtual void OnError(AudioCapturerSource::ErrorCode code) = 0;
// Called when an audio stream is muted or unmuted.
virtual void OnMuted(bool is_muted) = 0;
diff --git a/chromium/media/audio/audio_input_stream_data_interceptor.cc b/chromium/media/audio/audio_input_stream_data_interceptor.cc
index b50303851f5..332b3aeaf79 100644
--- a/chromium/media/audio/audio_input_stream_data_interceptor.cc
+++ b/chromium/media/audio/audio_input_stream_data_interceptor.cc
@@ -24,13 +24,13 @@ AudioInputStreamDataInterceptor::~AudioInputStreamDataInterceptor() {
}
// Implementation of AudioInputStream.
-bool AudioInputStreamDataInterceptor::Open() {
+AudioInputStream::OpenOutcome AudioInputStreamDataInterceptor::Open() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return stream_->Open();
}
void AudioInputStreamDataInterceptor::Start(
- media::AudioInputStream::AudioInputCallback* callback) {
+ AudioInputStream::AudioInputCallback* callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
callback_ = callback;
debug_recorder_ = create_debug_recorder_cb_.Run();
diff --git a/chromium/media/audio/audio_input_stream_data_interceptor.h b/chromium/media/audio/audio_input_stream_data_interceptor.h
index 383a28b329e..6794267c840 100644
--- a/chromium/media/audio/audio_input_stream_data_interceptor.h
+++ b/chromium/media/audio/audio_input_stream_data_interceptor.h
@@ -36,7 +36,7 @@ class MEDIA_EXPORT AudioInputStreamDataInterceptor
~AudioInputStreamDataInterceptor() override;
// Implementation of AudioInputStream.
- bool Open() override;
+ OpenOutcome Open() override;
void Start(AudioInputStream::AudioInputCallback* callback) override;
void Stop() override;
void Close() override;
diff --git a/chromium/media/audio/audio_input_stream_data_interceptor_unittest.cc b/chromium/media/audio/audio_input_stream_data_interceptor_unittest.cc
index 6e560003b04..3a2ec62f218 100644
--- a/chromium/media/audio/audio_input_stream_data_interceptor_unittest.cc
+++ b/chromium/media/audio/audio_input_stream_data_interceptor_unittest.cc
@@ -30,7 +30,7 @@ class MockStream : public AudioInputStream {
public:
MockStream() = default;
~MockStream() override = default;
- MOCK_METHOD0(Open, bool());
+ MOCK_METHOD0(Open, AudioInputStream::OpenOutcome());
MOCK_METHOD1(Start, void(AudioInputStream::AudioInputCallback*));
MOCK_METHOD0(Stop, void());
MOCK_METHOD0(Close, void());
diff --git a/chromium/media/audio/audio_input_unittest.cc b/chromium/media/audio/audio_input_unittest.cc
index ddaba1dd45c..cd9195987c6 100644
--- a/chromium/media/audio/audio_input_unittest.cc
+++ b/chromium/media/audio/audio_input_unittest.cc
@@ -145,7 +145,8 @@ class AudioInputTest : public testing::Test {
void OpenAndClose() {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
ASSERT_TRUE(audio_input_stream_);
- EXPECT_TRUE(audio_input_stream_->Open());
+ EXPECT_EQ(audio_input_stream_->Open(),
+ AudioInputStream::OpenOutcome::kSuccess);
audio_input_stream_->Close();
audio_input_stream_ = nullptr;
}
@@ -153,14 +154,16 @@ class AudioInputTest : public testing::Test {
void OpenAndStart(AudioInputStream::AudioInputCallback* sink) {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
ASSERT_TRUE(audio_input_stream_);
- EXPECT_TRUE(audio_input_stream_->Open());
+ EXPECT_EQ(audio_input_stream_->Open(),
+ AudioInputStream::OpenOutcome::kSuccess);
audio_input_stream_->Start(sink);
}
void OpenStopAndClose() {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
ASSERT_TRUE(audio_input_stream_);
- EXPECT_TRUE(audio_input_stream_->Open());
+ EXPECT_EQ(audio_input_stream_->Open(),
+ AudioInputStream::OpenOutcome::kSuccess);
audio_input_stream_->Stop();
audio_input_stream_->Close();
audio_input_stream_ = nullptr;
diff --git a/chromium/media/audio/audio_io.h b/chromium/media/audio/audio_io.h
index ae9111ab575..e574390d52e 100644
--- a/chromium/media/audio/audio_io.h
+++ b/chromium/media/audio/audio_io.h
@@ -39,7 +39,6 @@
// Specifically for this case we avoid supporting complex formats such as MP3
// or WMA. Complex format decoding should be done by the renderers.
-
// Models an audio stream that gets rendered to the audio hardware output.
// Because we support more audio streams than physically available channels
// a given AudioOutputStream might or might not talk directly to hardware.
@@ -155,9 +154,18 @@ class MEDIA_EXPORT AudioInputStream {
virtual ~AudioInputStream() {}
+ enum class OpenOutcome {
+ kSuccess,
+ kAlreadyOpen,
+ // Failed due to an unknown or unspecified reason.
+ kFailed,
+ // Failed to open due to OS-level System permissions.
+ kFailedSystemPermissions,
+ };
+
// Open the stream and prepares it for recording. Call Start() to actually
// begin recording.
- virtual bool Open() = 0;
+ virtual OpenOutcome Open() = 0;
// Starts recording audio and generating AudioInputCallback::OnData().
// The input stream does not take ownership of this callback.
diff --git a/chromium/media/audio/audio_low_latency_input_output_unittest.cc b/chromium/media/audio/audio_low_latency_input_output_unittest.cc
index 859181d3e33..eca3b36754d 100644
--- a/chromium/media/audio/audio_low_latency_input_output_unittest.cc
+++ b/chromium/media/audio/audio_low_latency_input_output_unittest.cc
@@ -119,11 +119,11 @@ class FullDuplexAudioSinkSource
// Start with the smallest possible buffer size. It will be increased
// dynamically during the test if required.
- buffer_.reset(
- new media::SeekableBuffer(0, samples_per_packet_ * frame_size_));
+ buffer_ = std::make_unique<media::SeekableBuffer>(
+ 0, samples_per_packet_ * frame_size_);
frames_to_ms_ = static_cast<double>(1000.0 / sample_rate_);
- delay_states_.reset(new AudioDelayState[kMaxDelayMeasurements]);
+ delay_states_ = std::make_unique<AudioDelayState[]>(kMaxDelayMeasurements);
}
~FullDuplexAudioSinkSource() override {
@@ -378,7 +378,7 @@ TEST_F(AudioLowLatencyInputOutputTest, DISABLED_FullDuplexDelayMeasurement) {
return;
}
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
EXPECT_TRUE(aos->Open());
FullDuplexAudioSinkSource full_duplex(
diff --git a/chromium/media/audio/audio_manager.cc b/chromium/media/audio/audio_manager.cc
index ff94c386043..f04c67116c0 100644
--- a/chromium/media/audio/audio_manager.cc
+++ b/chromium/media/audio/audio_manager.cc
@@ -6,6 +6,7 @@
#include <stdint.h>
+#include <memory>
#include <utility>
#include "base/bind.h"
@@ -16,7 +17,6 @@
#include "base/metrics/histogram_macros.h"
#include "base/power_monitor/power_monitor.h"
#include "base/single_thread_task_runner.h"
-#include "base/strings/stringprintf.h"
#include "base/thread_annotations.h"
#include "build/build_config.h"
#include "media/audio/fake_audio_log_factory.h"
@@ -44,7 +44,8 @@ class AudioManagerHelper {
// This should be called before creating an AudioManager in tests to ensure
// that the creating thread is COM initialized.
void InitializeCOMForTesting() {
- com_initializer_for_testing_.reset(new base::win::ScopedCOMInitializer());
+ com_initializer_for_testing_ =
+ std::make_unique<base::win::ScopedCOMInitializer>();
}
#endif
diff --git a/chromium/media/audio/audio_manager_base.cc b/chromium/media/audio/audio_manager_base.cc
index 2f97c51cbd4..f7d31c9c3ae 100644
--- a/chromium/media/audio/audio_manager_base.cc
+++ b/chromium/media/audio/audio_manager_base.cc
@@ -11,7 +11,6 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
@@ -25,6 +24,7 @@
#include "media/audio/fake_audio_input_stream.h"
#include "media/audio/fake_audio_output_stream.h"
#include "media/base/media_switches.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "base/logging.h"
#include "build/chromeos_buildflags.h"
@@ -332,7 +332,7 @@ AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy(
const std::string& device_id) {
CHECK(GetTaskRunner()->BelongsToCurrentThread());
DCHECK(params.IsValid());
- base::Optional<StreamFormat> uma_stream_format;
+ absl::optional<StreamFormat> uma_stream_format;
// If the caller supplied an empty device id to select the default device,
// we fetch the actual device id of the default device so that the lookup
diff --git a/chromium/media/audio/audio_manager_unittest.cc b/chromium/media/audio/audio_manager_unittest.cc
index 85aba43cd33..c4ced09ce28 100644
--- a/chromium/media/audio/audio_manager_unittest.cc
+++ b/chromium/media/audio/audio_manager_unittest.cc
@@ -137,7 +137,8 @@ const AudioNode kInternalSpeaker(false,
"Speaker",
false,
0,
- 2);
+ 2,
+ 0);
const AudioNode kInternalMic(true,
kInternalMicId,
@@ -149,7 +150,8 @@ const AudioNode kInternalMic(true,
"Internal Mic",
false,
0,
- 1);
+ 1,
+ 1); // EFFECT_TYPE_NOISE_CANCELLATION
const AudioNode kJabraSpeaker1(false,
kJabraSpeaker1Id,
@@ -161,7 +163,8 @@ const AudioNode kJabraSpeaker1(false,
"Jabra Speaker 1",
false,
0,
- 2); // expects CHANNEL_LAYOUT_STEREO
+ 2, // expects CHANNEL_LAYOUT_STEREO
+ 0);
const AudioNode kJabraSpeaker2(false,
kJabraSpeaker2Id,
@@ -173,7 +176,8 @@ const AudioNode kJabraSpeaker2(false,
"Jabra Speaker 2",
false,
0,
- 6); // expects CHANNEL_LAYOUT_5_1
+ 6, // expects CHANNEL_LAYOUT_5_1
+ 0);
const AudioNode kHDMIOutput(false,
kHDMIOutputId,
@@ -185,7 +189,8 @@ const AudioNode kHDMIOutput(false,
"HDA Intel MID",
false,
0,
- 8); // expects CHANNEL_LAYOUT_7_1
+ 8, // expects CHANNEL_LAYOUT_7_1
+ 0);
const AudioNode kJabraMic1(true,
kJabraMic1Id,
@@ -197,7 +202,8 @@ const AudioNode kJabraMic1(true,
"Jabra Mic 1",
false,
0,
- 1);
+ 1,
+ 0);
const AudioNode kJabraMic2(true,
kJabraMic2Id,
@@ -209,7 +215,8 @@ const AudioNode kJabraMic2(true,
"Jabra Mic 2",
false,
0,
- 1);
+ 1,
+ 0);
const AudioNode kUSBCameraMic(true,
kWebcamMicId,
@@ -221,7 +228,8 @@ const AudioNode kUSBCameraMic(true,
"Logitech Webcam",
false,
0,
- 1);
+ 1,
+ 0);
#endif // defined(USE_CRAS)
const char kRealDefaultInputDeviceID[] = "input2";
diff --git a/chromium/media/audio/audio_opus_encoder.cc b/chromium/media/audio/audio_opus_encoder.cc
index 03bcef1993a..7a3a45100d3 100644
--- a/chromium/media/audio/audio_opus_encoder.cc
+++ b/chromium/media/audio/audio_opus_encoder.cc
@@ -275,7 +275,7 @@ void AudioOpusEncoder::OnFifoOutput(const AudioBus& output_bus,
// If |result| in {0,1}, do nothing; the documentation says that a return
// value of zero or one means the packet does not need to be transmitted.
if (encoded_data_size > 1) {
- base::Optional<CodecDescription> desc;
+ absl::optional<CodecDescription> desc;
if (need_to_emit_extra_data_) {
desc = PrepareExtraData();
need_to_emit_extra_data_ = false;
diff --git a/chromium/media/audio/audio_opus_encoder.h b/chromium/media/audio/audio_opus_encoder.h
index 0c1f45a413e..fcef6b60835 100644
--- a/chromium/media/audio/audio_opus_encoder.h
+++ b/chromium/media/audio/audio_opus_encoder.h
@@ -8,12 +8,12 @@
#include <memory>
#include <vector>
-#include "base/optional.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_converter.h"
#include "media/base/audio_encoder.h"
#include "media/base/audio_push_fifo.h"
#include "media/base/audio_timestamp_helper.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/opus/src/include/opus.h"
namespace media {
diff --git a/chromium/media/audio/audio_output_device.h b/chromium/media/audio/audio_output_device.h
index c7686e01768..97704136e85 100644
--- a/chromium/media/audio/audio_output_device.h
+++ b/chromium/media/audio/audio_output_device.h
@@ -208,7 +208,7 @@ class MEDIA_EXPORT AudioOutputDevice : public AudioRendererSink,
// received in OnDeviceAuthorized().
std::string matched_device_id_;
- base::Optional<base::UnguessableToken> processing_id_;
+ absl::optional<base::UnguessableToken> processing_id_;
// In order to avoid a race between OnStreamCreated and Stop(), we use this
// guard to control stopping and starting the audio thread.
diff --git a/chromium/media/audio/audio_output_device_thread_callback.h b/chromium/media/audio/audio_output_device_thread_callback.h
index 84b80d9af78..ba3fac80fbc 100644
--- a/chromium/media/audio/audio_output_device_thread_callback.h
+++ b/chromium/media/audio/audio_output_device_thread_callback.h
@@ -8,9 +8,9 @@
#include <memory>
#include "base/memory/unsafe_shared_memory_region.h"
-#include "base/optional.h"
#include "media/audio/audio_device_thread.h"
#include "media/base/audio_renderer_sink.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
diff --git a/chromium/media/audio/audio_output_device_unittest.cc b/chromium/media/audio/audio_output_device_unittest.cc
index ed5547fe088..768156d41ce 100644
--- a/chromium/media/audio/audio_output_device_unittest.cc
+++ b/chromium/media/audio/audio_output_device_unittest.cc
@@ -75,7 +75,7 @@ class MockAudioOutputIPC : public AudioOutputIPC {
CreateStream,
void(AudioOutputIPCDelegate* delegate,
const AudioParameters& params,
- const base::Optional<base::UnguessableToken>& processing_id));
+ const absl::optional<base::UnguessableToken>& processing_id));
MOCK_METHOD0(PlayStream, void());
MOCK_METHOD0(PauseStream, void());
MOCK_METHOD0(FlushStream, void());
diff --git a/chromium/media/audio/audio_output_dispatcher_impl.cc b/chromium/media/audio/audio_output_dispatcher_impl.cc
index 439331d5edd..a8c428caf51 100644
--- a/chromium/media/audio/audio_output_dispatcher_impl.cc
+++ b/chromium/media/audio/audio_output_dispatcher_impl.cc
@@ -9,8 +9,8 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/containers/contains.h"
#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
#include "base/time/time.h"
#include "media/audio/audio_logging.h"
#include "media/audio/audio_manager.h"
diff --git a/chromium/media/audio/audio_output_ipc.h b/chromium/media/audio/audio_output_ipc.h
index 0b83581d93b..77198786b63 100644
--- a/chromium/media/audio/audio_output_ipc.h
+++ b/chromium/media/audio/audio_output_ipc.h
@@ -86,7 +86,7 @@ class MEDIA_EXPORT AudioOutputIPC {
virtual void CreateStream(
AudioOutputIPCDelegate* delegate,
const AudioParameters& params,
- const base::Optional<base::UnguessableToken>& processing_id) = 0;
+ const absl::optional<base::UnguessableToken>& processing_id) = 0;
// Starts playing the stream. This should generate a call to
// AudioOutputController::Play().
diff --git a/chromium/media/audio/audio_output_stream_sink.h b/chromium/media/audio/audio_output_stream_sink.h
index 1c3eefe6741..fcc8bc14b3d 100644
--- a/chromium/media/audio/audio_output_stream_sink.h
+++ b/chromium/media/audio/audio_output_stream_sink.h
@@ -7,8 +7,6 @@
#include <stdint.h>
-#include <string>
-
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/media/audio/audio_sink_parameters.h b/chromium/media/audio/audio_sink_parameters.h
index a51f1b82bc7..45b89b3127f 100644
--- a/chromium/media/audio/audio_sink_parameters.h
+++ b/chromium/media/audio/audio_sink_parameters.h
@@ -7,9 +7,9 @@
#include <string>
-#include "base/optional.h"
#include "base/unguessable_token.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -31,7 +31,7 @@ struct MEDIA_EXPORT AudioSinkParameters final {
base::UnguessableToken session_id;
std::string device_id;
- base::Optional<base::UnguessableToken> processing_id;
+ absl::optional<base::UnguessableToken> processing_id;
};
} // namespace media
diff --git a/chromium/media/audio/audio_source_parameters.h b/chromium/media/audio/audio_source_parameters.h
index 96e1c1960ab..efd2da31abd 100644
--- a/chromium/media/audio/audio_source_parameters.h
+++ b/chromium/media/audio/audio_source_parameters.h
@@ -5,12 +5,10 @@
#ifndef MEDIA_AUDIO_AUDIO_SOURCE_PARAMETERS_H_
#define MEDIA_AUDIO_AUDIO_SOURCE_PARAMETERS_H_
-#include <string>
-
-#include "base/optional.h"
#include "base/unguessable_token.h"
#include "media/base/audio_processing.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -33,7 +31,7 @@ struct MEDIA_EXPORT AudioSourceParameters final {
AudioProcessingSettings settings;
};
- base::Optional<ProcessingConfig> processing;
+ absl::optional<ProcessingConfig> processing;
};
} // namespace media
diff --git a/chromium/media/audio/audio_system.h b/chromium/media/audio/audio_system.h
index c01f8d75e84..9701570bb73 100644
--- a/chromium/media/audio/audio_system.h
+++ b/chromium/media/audio/audio_system.h
@@ -8,10 +8,10 @@
#include <string>
#include "base/callback.h"
-#include "base/optional.h"
#include "media/audio/audio_device_description.h"
#include "media/base/audio_parameters.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -33,12 +33,12 @@ class MEDIA_EXPORT AudioSystem {
// std::string. If optional matched output device id is empty, it means there
// is no associated output device.
using OnAudioParamsCallback =
- base::OnceCallback<void(const base::Optional<AudioParameters>&)>;
+ base::OnceCallback<void(const absl::optional<AudioParameters>&)>;
using OnDeviceIdCallback =
- base::OnceCallback<void(const base::Optional<std::string>&)>;
+ base::OnceCallback<void(const absl::optional<std::string>&)>;
using OnInputDeviceInfoCallback =
- base::OnceCallback<void(const base::Optional<AudioParameters>&,
- const base::Optional<std::string>&)>;
+ base::OnceCallback<void(const absl::optional<AudioParameters>&,
+ const absl::optional<std::string>&)>;
using OnBoolCallback = base::OnceCallback<void(bool)>;
using OnDeviceDescriptionsCallback =
diff --git a/chromium/media/audio/audio_system_helper.cc b/chromium/media/audio/audio_system_helper.cc
index e1a741726a5..ad026bc699c 100644
--- a/chromium/media/audio/audio_system_helper.cc
+++ b/chromium/media/audio/audio_system_helper.cc
@@ -12,7 +12,7 @@ namespace media {
namespace {
-base::Optional<AudioParameters> TryToFixChannels(
+absl::optional<AudioParameters> TryToFixChannels(
const AudioParameters& params) {
DCHECK(!params.IsValid());
AudioParameters params_copy(params);
@@ -26,7 +26,7 @@ base::Optional<AudioParameters> TryToFixChannels(
}
return params_copy.IsValid() ? params_copy
- : base::Optional<AudioParameters>();
+ : absl::optional<AudioParameters>();
}
} // namespace
@@ -83,7 +83,7 @@ void AudioSystemHelper::GetAssociatedOutputDeviceID(
const std::string associated_output_device_id =
audio_manager_->GetAssociatedOutputDeviceID(input_device_id);
std::move(on_device_id_cb)
- .Run(associated_output_device_id.empty() ? base::Optional<std::string>()
+ .Run(associated_output_device_id.empty() ? absl::optional<std::string>()
: associated_output_device_id);
}
@@ -95,11 +95,11 @@ void AudioSystemHelper::GetInputDeviceInfo(
audio_manager_->GetAssociatedOutputDeviceID(input_device_id);
std::move(on_input_device_info_cb)
.Run(ComputeInputParameters(input_device_id),
- associated_output_device_id.empty() ? base::Optional<std::string>()
+ associated_output_device_id.empty() ? absl::optional<std::string>()
: associated_output_device_id);
}
-base::Optional<AudioParameters> AudioSystemHelper::ComputeInputParameters(
+absl::optional<AudioParameters> AudioSystemHelper::ComputeInputParameters(
const std::string& device_id) {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
@@ -111,17 +111,17 @@ base::Optional<AudioParameters> AudioSystemHelper::ComputeInputParameters(
// AudioManager::GetInputStreamParameters will check |device_id| and
// query the correct device for audio parameters by itself.
if (!audio_manager_->HasAudioOutputDevices())
- return base::Optional<AudioParameters>();
+ return absl::optional<AudioParameters>();
} else {
if (!audio_manager_->HasAudioInputDevices())
- return base::Optional<AudioParameters>();
+ return absl::optional<AudioParameters>();
}
AudioParameters params = audio_manager_->GetInputStreamParameters(device_id);
return params.IsValid() ? params : TryToFixChannels(params);
}
-base::Optional<AudioParameters> AudioSystemHelper::ComputeOutputParameters(
+absl::optional<AudioParameters> AudioSystemHelper::ComputeOutputParameters(
const std::string& device_id) {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
@@ -129,7 +129,7 @@ base::Optional<AudioParameters> AudioSystemHelper::ComputeOutputParameters(
// AudioManager::Get[Default]OutputStreamParameters() returns invalid
// parameters if the device is not found.
if (!audio_manager_->HasAudioOutputDevices())
- return base::Optional<AudioParameters>();
+ return absl::optional<AudioParameters>();
AudioParameters params =
AudioDeviceDescription::IsDefaultDevice(device_id)
diff --git a/chromium/media/audio/audio_system_helper.h b/chromium/media/audio/audio_system_helper.h
index e3e16428254..e630555651a 100644
--- a/chromium/media/audio/audio_system_helper.h
+++ b/chromium/media/audio/audio_system_helper.h
@@ -44,9 +44,9 @@ class MEDIA_EXPORT AudioSystemHelper {
AudioSystem::OnInputDeviceInfoCallback on_input_device_info_cb);
private:
- base::Optional<AudioParameters> ComputeInputParameters(
+ absl::optional<AudioParameters> ComputeInputParameters(
const std::string& device_id);
- base::Optional<AudioParameters> ComputeOutputParameters(
+ absl::optional<AudioParameters> ComputeOutputParameters(
const std::string& device_id);
AudioManager* const audio_manager_;
diff --git a/chromium/media/audio/audio_system_test_util.cc b/chromium/media/audio/audio_system_test_util.cc
index dae244c0253..7e31a7fff0b 100644
--- a/chromium/media/audio/audio_system_test_util.cc
+++ b/chromium/media/audio/audio_system_test_util.cc
@@ -19,7 +19,7 @@ AudioSystem::OnAudioParamsCallback
AudioSystemCallbackExpectations::GetAudioParamsCallback(
const base::Location& location,
base::OnceClosure on_cb_received,
- const base::Optional<AudioParameters>& expected_params) {
+ const absl::optional<AudioParameters>& expected_params) {
return base::BindOnce(&AudioSystemCallbackExpectations::OnAudioParams,
base::Unretained(this), location.ToString(),
std::move(on_cb_received), expected_params);
@@ -48,8 +48,8 @@ AudioSystem::OnInputDeviceInfoCallback
AudioSystemCallbackExpectations::GetInputDeviceInfoCallback(
const base::Location& location,
base::OnceClosure on_cb_received,
- const base::Optional<AudioParameters>& expected_input,
- const base::Optional<std::string>& expected_associated_device_id) {
+ const absl::optional<AudioParameters>& expected_input,
+ const absl::optional<std::string>& expected_associated_device_id) {
return base::BindOnce(&AudioSystemCallbackExpectations::OnInputDeviceInfo,
base::Unretained(this), location.ToString(),
std::move(on_cb_received), expected_input,
@@ -60,7 +60,7 @@ AudioSystem::OnDeviceIdCallback
AudioSystemCallbackExpectations::GetDeviceIdCallback(
const base::Location& location,
base::OnceClosure on_cb_received,
- const base::Optional<std::string>& expected_id) {
+ const absl::optional<std::string>& expected_id) {
return base::BindOnce(&AudioSystemCallbackExpectations::OnDeviceId,
base::Unretained(this), location.ToString(),
std::move(on_cb_received), expected_id);
@@ -69,8 +69,8 @@ AudioSystemCallbackExpectations::GetDeviceIdCallback(
void AudioSystemCallbackExpectations::OnAudioParams(
const std::string& from_here,
base::OnceClosure on_cb_received,
- const base::Optional<AudioParameters>& expected,
- const base::Optional<AudioParameters>& received) {
+ const absl::optional<AudioParameters>& expected,
+ const absl::optional<AudioParameters>& received) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_, from_here);
if (expected) {
EXPECT_TRUE(received) << from_here;
@@ -105,10 +105,10 @@ void AudioSystemCallbackExpectations::OnDeviceDescriptions(
void AudioSystemCallbackExpectations::OnInputDeviceInfo(
const std::string& from_here,
base::OnceClosure on_cb_received,
- const base::Optional<AudioParameters>& expected_input,
- const base::Optional<std::string>& expected_associated_device_id,
- const base::Optional<AudioParameters>& input,
- const base::Optional<std::string>& associated_device_id) {
+ const absl::optional<AudioParameters>& expected_input,
+ const absl::optional<std::string>& expected_associated_device_id,
+ const absl::optional<AudioParameters>& input,
+ const absl::optional<std::string>& associated_device_id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_, from_here);
EXPECT_TRUE(!input || input->IsValid());
if (expected_input) {
@@ -132,8 +132,8 @@ void AudioSystemCallbackExpectations::OnInputDeviceInfo(
void AudioSystemCallbackExpectations::OnDeviceId(
const std::string& from_here,
base::OnceClosure on_cb_received,
- const base::Optional<std::string>& expected_id,
- const base::Optional<std::string>& result_id) {
+ const absl::optional<std::string>& expected_id,
+ const absl::optional<std::string>& result_id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_, from_here);
EXPECT_TRUE(!result_id || !result_id->empty());
if (expected_id) {
diff --git a/chromium/media/audio/audio_system_test_util.h b/chromium/media/audio/audio_system_test_util.h
index fa7133e1c92..20edd161fd4 100644
--- a/chromium/media/audio/audio_system_test_util.h
+++ b/chromium/media/audio/audio_system_test_util.h
@@ -8,7 +8,6 @@
#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "base/run_loop.h"
#include "base/threading/thread_checker.h"
#include "media/audio/audio_device_description.h"
@@ -16,6 +15,7 @@
#include "media/audio/mock_audio_manager.h"
#include "media/base/audio_parameters.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -31,7 +31,7 @@ class AudioSystemCallbackExpectations {
AudioSystem::OnAudioParamsCallback GetAudioParamsCallback(
const base::Location& location,
base::OnceClosure on_cb_received,
- const base::Optional<AudioParameters>& expected_params);
+ const absl::optional<AudioParameters>& expected_params);
AudioSystem::OnBoolCallback GetBoolCallback(const base::Location& location,
base::OnceClosure on_cb_received,
@@ -45,20 +45,20 @@ class AudioSystemCallbackExpectations {
AudioSystem::OnInputDeviceInfoCallback GetInputDeviceInfoCallback(
const base::Location& location,
base::OnceClosure on_cb_received,
- const base::Optional<AudioParameters>& expected_input,
- const base::Optional<std::string>& expected_associated_device_id);
+ const absl::optional<AudioParameters>& expected_input,
+ const absl::optional<std::string>& expected_associated_device_id);
AudioSystem::OnDeviceIdCallback GetDeviceIdCallback(
const base::Location& location,
base::OnceClosure on_cb_received,
- const base::Optional<std::string>& expected_id);
+ const absl::optional<std::string>& expected_id);
private:
// Methods to verify correctness of received data.
void OnAudioParams(const std::string& from_here,
base::OnceClosure on_cb_received,
- const base::Optional<AudioParameters>& expected,
- const base::Optional<AudioParameters>& received);
+ const absl::optional<AudioParameters>& expected,
+ const absl::optional<AudioParameters>& received);
void OnBool(const std::string& from_here,
base::OnceClosure on_cb_received,
@@ -74,15 +74,15 @@ class AudioSystemCallbackExpectations {
void OnInputDeviceInfo(
const std::string& from_here,
base::OnceClosure on_cb_received,
- const base::Optional<AudioParameters>& expected_input,
- const base::Optional<std::string>& expected_associated_device_id,
- const base::Optional<AudioParameters>& input,
- const base::Optional<std::string>& associated_device_id);
+ const absl::optional<AudioParameters>& expected_input,
+ const absl::optional<std::string>& expected_associated_device_id,
+ const absl::optional<AudioParameters>& input,
+ const absl::optional<std::string>& associated_device_id);
void OnDeviceId(const std::string& from_here,
base::OnceClosure on_cb_received,
- const base::Optional<std::string>& expected_id,
- const base::Optional<std::string>& result_id);
+ const absl::optional<std::string>& expected_id,
+ const absl::optional<std::string>& result_id);
THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(AudioSystemCallbackExpectations);
@@ -160,7 +160,7 @@ TYPED_TEST_P(AudioSystemTestTemplate, GetInputStreamParametersNoDevice) {
AudioDeviceDescription::kDefaultDeviceId,
this->expectations_.GetAudioParamsCallback(
FROM_HERE, wait_loop.QuitClosure(),
- base::Optional<AudioParameters>()));
+ absl::optional<AudioParameters>()));
wait_loop.Run();
}
@@ -190,7 +190,7 @@ TYPED_TEST_P(AudioSystemTestTemplate,
AudioDeviceDescription::kDefaultDeviceId,
this->expectations_.GetAudioParamsCallback(
FROM_HERE, wait_loop.QuitClosure(),
- base::Optional<AudioParameters>()));
+ absl::optional<AudioParameters>()));
wait_loop.Run();
}
@@ -201,7 +201,7 @@ TYPED_TEST_P(AudioSystemTestTemplate,
this->audio_system()->GetOutputStreamParameters(
"non-default-device-id", this->expectations_.GetAudioParamsCallback(
FROM_HERE, wait_loop.QuitClosure(),
- base::Optional<AudioParameters>()));
+ absl::optional<AudioParameters>()));
wait_loop.Run();
}
@@ -321,7 +321,7 @@ TYPED_TEST_P(AudioSystemTestTemplate, GetInputDeviceInfoNoAssociation) {
"non-default-device-id",
this->expectations_.GetInputDeviceInfoCallback(
FROM_HERE, wait_loop.QuitClosure(), this->input_params_,
- base::Optional<std::string>()));
+ absl::optional<std::string>()));
wait_loop.Run();
}
diff --git a/chromium/media/audio/audio_thread_hang_monitor.cc b/chromium/media/audio/audio_thread_hang_monitor.cc
index c26d3f59590..6131b53cb65 100644
--- a/chromium/media/audio/audio_thread_hang_monitor.cc
+++ b/chromium/media/audio/audio_thread_hang_monitor.cc
@@ -44,7 +44,7 @@ AudioThreadHangMonitor::SharedAtomicFlag::~SharedAtomicFlag() {}
// static
AudioThreadHangMonitor::Ptr AudioThreadHangMonitor::Create(
HangAction hang_action,
- base::Optional<base::TimeDelta> hang_deadline,
+ absl::optional<base::TimeDelta> hang_deadline,
const base::TickClock* clock,
scoped_refptr<base::SingleThreadTaskRunner> audio_thread_task_runner,
scoped_refptr<base::SequencedTaskRunner> monitor_task_runner) {
@@ -73,7 +73,7 @@ bool AudioThreadHangMonitor::IsAudioThreadHung() const {
AudioThreadHangMonitor::AudioThreadHangMonitor(
HangAction hang_action,
- base::Optional<base::TimeDelta> hang_deadline,
+ absl::optional<base::TimeDelta> hang_deadline,
const base::TickClock* clock,
scoped_refptr<base::SingleThreadTaskRunner> audio_thread_task_runner)
: clock_(clock),
diff --git a/chromium/media/audio/audio_thread_hang_monitor.h b/chromium/media/audio/audio_thread_hang_monitor.h
index 89a3758f718..014ac272b66 100644
--- a/chromium/media/audio/audio_thread_hang_monitor.h
+++ b/chromium/media/audio/audio_thread_hang_monitor.h
@@ -15,12 +15,12 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace base {
class TickClock;
@@ -68,7 +68,7 @@ class MEDIA_EXPORT AudioThreadHangMonitor final {
// zero, a default value is used.
static Ptr Create(
HangAction hang_action,
- base::Optional<base::TimeDelta> hang_deadline,
+ absl::optional<base::TimeDelta> hang_deadline,
const base::TickClock* clock,
scoped_refptr<base::SingleThreadTaskRunner> audio_thread_task_runner,
scoped_refptr<base::SequencedTaskRunner> monitor_task_runner = nullptr);
@@ -95,7 +95,7 @@ class MEDIA_EXPORT AudioThreadHangMonitor final {
AudioThreadHangMonitor(
HangAction hang_action,
- base::Optional<base::TimeDelta> hang_deadline,
+ absl::optional<base::TimeDelta> hang_deadline,
const base::TickClock* clock,
scoped_refptr<base::SingleThreadTaskRunner> audio_thread_task_runner);
diff --git a/chromium/media/audio/audio_thread_hang_monitor_unittest.cc b/chromium/media/audio/audio_thread_hang_monitor_unittest.cc
index a173c726d5a..5ed9585f2e9 100644
--- a/chromium/media/audio/audio_thread_hang_monitor_unittest.cc
+++ b/chromium/media/audio/audio_thread_hang_monitor_unittest.cc
@@ -6,7 +6,6 @@
#include "base/bind.h"
#include "base/location.h"
-#include "base/optional.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
@@ -14,6 +13,7 @@
#include "base/threading/thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
using testing::ElementsAre;
using testing::Test;
@@ -47,7 +47,7 @@ class AudioThreadHangMonitorTest : public Test {
// runner since TaskEnvironment::FastForwardBy only works for the main
// thread.
hang_monitor_ = AudioThreadHangMonitor::Create(
- HangAction::kDoNothing, base::nullopt, task_env_.GetMockTickClock(),
+ HangAction::kDoNothing, absl::nullopt, task_env_.GetMockTickClock(),
audio_thread_.task_runner(), task_env_.GetMainThreadTaskRunner());
}
@@ -251,7 +251,7 @@ TEST_F(AudioThreadHangMonitorTest, NoHangActionWhenOk) {
TEST_F(AudioThreadHangMonitorTest, DumpsWhenAudioThreadIsBlocked) {
hang_monitor_ = AudioThreadHangMonitor::Create(
- HangAction::kDump, base::nullopt, task_env_.GetMockTickClock(),
+ HangAction::kDump, absl::nullopt, task_env_.GetMockTickClock(),
audio_thread_.task_runner(), task_env_.GetMainThreadTaskRunner());
SetHangActionCallbacksForTesting();
RunUntilIdle();
@@ -268,7 +268,7 @@ TEST_F(AudioThreadHangMonitorTest, DumpsWhenAudioThreadIsBlocked) {
TEST_F(AudioThreadHangMonitorTest, TerminatesProcessWhenAudioThreadIsBlocked) {
hang_monitor_ = AudioThreadHangMonitor::Create(
- HangAction::kTerminateCurrentProcess, base::nullopt,
+ HangAction::kTerminateCurrentProcess, absl::nullopt,
task_env_.GetMockTickClock(), audio_thread_.task_runner(),
task_env_.GetMainThreadTaskRunner());
SetHangActionCallbacksForTesting();
@@ -287,7 +287,7 @@ TEST_F(AudioThreadHangMonitorTest, TerminatesProcessWhenAudioThreadIsBlocked) {
TEST_F(AudioThreadHangMonitorTest,
DumpsAndTerminatesProcessWhenAudioThreadIsBlocked) {
hang_monitor_ = AudioThreadHangMonitor::Create(
- HangAction::kDumpAndTerminateCurrentProcess, base::nullopt,
+ HangAction::kDumpAndTerminateCurrentProcess, absl::nullopt,
task_env_.GetMockTickClock(), audio_thread_.task_runner(),
task_env_.GetMainThreadTaskRunner());
SetHangActionCallbacksForTesting();
diff --git a/chromium/media/audio/audio_thread_impl.cc b/chromium/media/audio/audio_thread_impl.cc
index db3d4e84b7b..f52e7aae934 100644
--- a/chromium/media/audio/audio_thread_impl.cc
+++ b/chromium/media/audio/audio_thread_impl.cc
@@ -5,11 +5,11 @@
#include "media/audio/audio_thread_impl.h"
#include "base/message_loop/message_pump_type.h"
-#include "base/optional.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/default_tick_clock.h"
#include "build/build_config.h"
#include "media/audio/audio_thread_hang_monitor.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -23,7 +23,7 @@ AudioThreadImpl::AudioThreadImpl()
// FIDL-based APIs require async_t, which is initialized on IO thread.
thread_options.message_pump_type = base::MessagePumpType::IO;
#endif
- CHECK(thread_.StartWithOptions(thread_options));
+ CHECK(thread_.StartWithOptions(std::move(thread_options)));
#if defined(OS_MAC)
// On Mac, the audio task runner must belong to the main thread.
@@ -39,7 +39,7 @@ AudioThreadImpl::AudioThreadImpl()
// https://crbug.com/946968: The hang monitor possibly causes crashes on
// Android
hang_monitor_ = AudioThreadHangMonitor::Create(
- AudioThreadHangMonitor::HangAction::kDoNothing, base::nullopt,
+ AudioThreadHangMonitor::HangAction::kDoNothing, absl::nullopt,
base::DefaultTickClock::GetInstance(), task_runner_);
#endif
}
diff --git a/chromium/media/audio/audio_thread_impl.h b/chromium/media/audio/audio_thread_impl.h
index 77b0fcdd47b..70100352440 100644
--- a/chromium/media/audio/audio_thread_impl.h
+++ b/chromium/media/audio/audio_thread_impl.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_AUDIO_AUDIO_THREAD_IMPL_H_
#define MEDIA_AUDIO_AUDIO_THREAD_IMPL_H_
-#include <memory>
-
#include "base/sequenced_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
diff --git a/chromium/media/audio/cras/audio_manager_chromeos.cc b/chromium/media/audio/cras/audio_manager_chromeos.cc
index 15d36844128..9d1badafe52 100644
--- a/chromium/media/audio/cras/audio_manager_chromeos.cc
+++ b/chromium/media/audio/cras/audio_manager_chromeos.cc
@@ -100,6 +100,42 @@ void ProcessVirtualDeviceName(AudioDeviceNames* device_names,
}
}
+// Collects flags values for whether, and in what way, the AEC, NS or AGC
+// effects should be enforced in spite of them not being flagged as supported by
+// the board.
+void RetrieveSystemEffectFeatures(bool& enforce_system_aec,
+ bool& enforce_system_ns,
+ bool& enforce_system_agc,
+ bool& tuned_system_aec_allowed) {
+ const bool enforce_system_aec_ns_agc_feature =
+ base::FeatureList::IsEnabled(features::kCrOSEnforceSystemAecNsAgc);
+ const bool enforce_system_aec_ns_feature =
+ base::FeatureList::IsEnabled(features::kCrOSEnforceSystemAecNs);
+ const bool enforce_system_aec_agc_feature =
+ base::FeatureList::IsEnabled(features::kCrOSEnforceSystemAecAgc);
+ const bool enforce_system_aec_feature =
+ base::FeatureList::IsEnabled(features::kCrOSEnforceSystemAec);
+
+ enforce_system_aec =
+ enforce_system_aec_feature || enforce_system_aec_ns_agc_feature ||
+ enforce_system_aec_ns_feature || enforce_system_aec_agc_feature;
+ enforce_system_ns =
+ enforce_system_aec_ns_agc_feature || enforce_system_aec_ns_feature;
+ enforce_system_agc =
+ enforce_system_aec_ns_agc_feature || enforce_system_aec_agc_feature;
+
+ tuned_system_aec_allowed =
+ base::FeatureList::IsEnabled(features::kCrOSSystemAEC);
+}
+
+// Checks if a system AEC with a specific group ID is flagged to be deactivated
+// by the field trial.
+bool IsSystemAecDeactivated(int aec_group_id) {
+ return base::GetFieldTrialParamByFeatureAsBool(
+ features::kCrOSSystemAECDeactivatedGroups, std::to_string(aec_group_id),
+ false);
+}
+
} // namespace
bool AudioManagerChromeOS::HasAudioOutputDevices() {
@@ -175,44 +211,24 @@ AudioParameters AudioManagerChromeOS::GetInputStreamParameters(
const std::string& device_id) {
DCHECK(GetTaskRunner()->BelongsToCurrentThread());
- int user_buffer_size = GetUserBufferSize();
- int buffer_size =
- user_buffer_size ? user_buffer_size : kDefaultInputBufferSize;
-
- // TODO(hshi): Fine-tune audio parameters based on |device_id|. The optimal
- // parameters for the loopback stream may differ from the default.
- AudioParameters params(
- AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
- kDefaultSampleRate, buffer_size,
- AudioParameters::HardwareCapabilities(limits::kMinAudioBufferSize,
- limits::kMaxAudioBufferSize));
+ // Check if the device has keyboard.
AudioDeviceList devices;
GetAudioDevices(&devices);
- if (HasKeyboardMic(devices))
- params.set_effects(AudioParameters::KEYBOARD_MIC);
+ const bool has_keyboard = HasKeyboardMic(devices);
- // Allow experimentation with system echo cancellation with all devices,
- // but enable it by default on devices that actually support it.
- params.set_effects(params.effects() |
- AudioParameters::EXPERIMENTAL_ECHO_CANCELLER);
- if (base::FeatureList::IsEnabled(features::kCrOSSystemAEC)) {
- if (GetSystemAecSupportedPerBoard()) {
- const int32_t aec_group_id = GetSystemAecGroupIdPerBoard();
-
- // Check if the system AEC has a group ID which is flagged to be
- // deactivated by the field trial.
- const bool system_aec_deactivated =
- base::GetFieldTrialParamByFeatureAsBool(
- features::kCrOSSystemAECDeactivatedGroups,
- std::to_string(aec_group_id), false);
-
- if (!system_aec_deactivated) {
- params.set_effects(params.effects() | AudioParameters::ECHO_CANCELLER);
- }
- }
- }
+ // Retrieve buffer size.
+ int user_buffer_size = GetUserBufferSize();
+ user_buffer_size =
+ user_buffer_size != 0 ? user_buffer_size : kDefaultInputBufferSize;
- return params;
+ // Retrieve the board support in terms of APM effects and properties.
+ const SystemAudioProcessingInfo system_apm_info =
+ GetSystemApmEffectsSupportedPerBoard();
+
+ // TODO(hshi): Fine-tune audio parameters based on |device_id|. The optimal
+ // parameters for the loopback stream may differ from the default.
+ return GetStreamParametersForSystem(user_buffer_size, has_keyboard,
+ system_apm_info);
}
std::string AudioManagerChromeOS::GetAssociatedOutputDeviceID(
@@ -295,46 +311,28 @@ int AudioManagerChromeOS::GetDefaultOutputBufferSizePerBoard() {
return static_cast<int>(buffer_size);
}
-bool AudioManagerChromeOS::GetSystemAecSupportedPerBoard() {
+AudioManagerChromeOS::SystemAudioProcessingInfo
+AudioManagerChromeOS::GetSystemApmEffectsSupportedPerBoard() {
DCHECK(GetTaskRunner()->BelongsToCurrentThread());
- bool system_aec_supported = false;
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
- if (main_task_runner_->BelongsToCurrentThread()) {
- // Unittest may use the same thread for audio thread.
- GetSystemAecSupportedOnMainThread(&system_aec_supported, &event);
- } else {
- // Using base::Unretained is safe here because we wait for callback be
- // executed in main thread before local variables are destructed.
- main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&AudioManagerChromeOS::GetSystemAecSupportedOnMainThread,
- weak_this_, base::Unretained(&system_aec_supported),
- base::Unretained(&event)));
- }
- WaitEventOrShutdown(&event);
- return system_aec_supported;
-}
-int32_t AudioManagerChromeOS::GetSystemAecGroupIdPerBoard() {
- DCHECK(GetTaskRunner()->BelongsToCurrentThread());
- int32_t group_id = CrasAudioHandler::kSystemAecGroupIdNotAvailable;
- base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
+ SystemAudioProcessingInfo system_apm_info;
if (main_task_runner_->BelongsToCurrentThread()) {
// Unittest may use the same thread for audio thread.
- GetSystemAecGroupIdOnMainThread(&group_id, &event);
+ GetSystemApmEffectsSupportedOnMainThread(&system_apm_info, &event);
} else {
// Using base::Unretained is safe here because we wait for callback be
// executed in main thread before local variables are destructed.
main_task_runner_->PostTask(
FROM_HERE,
- base::BindOnce(&AudioManagerChromeOS::GetSystemAecGroupIdOnMainThread,
- weak_this_, base::Unretained(&group_id),
- base::Unretained(&event)));
+ base::BindOnce(
+ &AudioManagerChromeOS::GetSystemApmEffectsSupportedOnMainThread,
+ weak_this_, base::Unretained(&system_apm_info),
+ base::Unretained(&event)));
}
WaitEventOrShutdown(&event);
- return group_id;
+ return system_apm_info;
}
AudioParameters AudioManagerChromeOS::GetPreferredOutputStreamParameters(
@@ -516,25 +514,23 @@ void AudioManagerChromeOS::GetDefaultOutputBufferSizeOnMainThread(
event->Signal();
}
-void AudioManagerChromeOS::GetSystemAecSupportedOnMainThread(
- bool* system_aec_supported,
+void AudioManagerChromeOS::GetSystemApmEffectsSupportedOnMainThread(
+ SystemAudioProcessingInfo* system_apm_info,
base::WaitableEvent* event) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
if (CrasAudioHandler::Get()) {
- *system_aec_supported = CrasAudioHandler::Get()->system_aec_supported();
+ system_apm_info->aec_supported =
+ CrasAudioHandler::Get()->system_aec_supported();
+ system_apm_info->aec_group_id =
+ CrasAudioHandler::Get()->system_aec_group_id();
+ system_apm_info->ns_supported =
+ CrasAudioHandler::Get()->system_ns_supported();
+ system_apm_info->agc_supported =
+ CrasAudioHandler::Get()->system_agc_supported();
}
event->Signal();
}
-void AudioManagerChromeOS::GetSystemAecGroupIdOnMainThread(
- int32_t* group_id,
- base::WaitableEvent* event) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
- if (CrasAudioHandler::Get())
- *group_id = CrasAudioHandler::Get()->system_aec_group_id();
- event->Signal();
-}
-
void AudioManagerChromeOS::WaitEventOrShutdown(base::WaitableEvent* event) {
base::WaitableEvent* waitables[] = {event, &on_shutdown_};
base::WaitableEvent::WaitMany(waitables, base::size(waitables));
@@ -544,4 +540,66 @@ enum CRAS_CLIENT_TYPE AudioManagerChromeOS::GetClientType() {
return CRAS_CLIENT_TYPE_CHROME;
}
+AudioParameters AudioManagerChromeOS::GetStreamParametersForSystem(
+ int user_buffer_size,
+ bool has_keyboard,
+ const AudioManagerChromeOS::SystemAudioProcessingInfo& system_apm_info) {
+ AudioParameters params(
+ AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
+ kDefaultSampleRate, user_buffer_size,
+ AudioParameters::HardwareCapabilities(limits::kMinAudioBufferSize,
+ limits::kMaxAudioBufferSize));
+ if (has_keyboard)
+ params.set_effects(AudioParameters::KEYBOARD_MIC);
+
+ bool enforce_system_aec;
+ bool enforce_system_ns;
+ bool enforce_system_agc;
+ bool tuned_system_aec_allowed;
+ RetrieveSystemEffectFeatures(enforce_system_aec, enforce_system_ns,
+ enforce_system_agc, tuned_system_aec_allowed);
+
+ // Activation of the system AEC. Allow experimentation with system AEC with
+ // all devices, but enable it by default on devices that actually support it.
+ params.set_effects(params.effects() |
+ AudioParameters::EXPERIMENTAL_ECHO_CANCELLER);
+
+ // Rephrase the field aec_supported to properly reflect its meaning in this
+ // context (since it currently signals whether an CrAS APM with tuned settings
+ // is available).
+ const bool tuned_system_apm_available = system_apm_info.aec_supported;
+
+ // Don't use the system AEC if it is deactivated for this group ID. Also never
+ // activate NS nor AGC for this board if the AEC is not activated, since this
+ // will cause issues for the Browser AEC.
+ bool use_system_aec =
+ (tuned_system_apm_available && tuned_system_aec_allowed) ||
+ enforce_system_aec;
+
+ if (!use_system_aec || IsSystemAecDeactivated(system_apm_info.aec_group_id)) {
+ return params;
+ }
+
+ // Activation of the system AEC.
+ params.set_effects(params.effects() | AudioParameters::ECHO_CANCELLER);
+
+ // Don't use system NS or AGC if the AEC has board-specific tunings.
+ if (tuned_system_apm_available) {
+ return params;
+ }
+
+ // Activation of the system NS.
+ if (system_apm_info.ns_supported || enforce_system_ns) {
+ params.set_effects(params.effects() | AudioParameters::NOISE_SUPPRESSION);
+ }
+
+ // Activation of the system AGC.
+ if (system_apm_info.agc_supported || enforce_system_agc) {
+ params.set_effects(params.effects() |
+ AudioParameters::AUTOMATIC_GAIN_CONTROL);
+ }
+
+ return params;
+}
+
} // namespace media
diff --git a/chromium/media/audio/cras/audio_manager_chromeos.h b/chromium/media/audio/cras/audio_manager_chromeos.h
index 40da0ad6f82..3d38a3eb89f 100644
--- a/chromium/media/audio/cras/audio_manager_chromeos.h
+++ b/chromium/media/audio/cras/audio_manager_chromeos.h
@@ -12,6 +12,7 @@
#include <vector>
#include "ash/components/audio/audio_device.h"
+#include "ash/components/audio/cras_audio_handler.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -45,6 +46,22 @@ class MEDIA_EXPORT AudioManagerChromeOS : public AudioManagerCrasBase {
bool IsDefault(const std::string& device_id, bool is_input) override;
enum CRAS_CLIENT_TYPE GetClientType() override;
+ // Stores information about the system audio processing effects and
+ // properties that are provided by the system audio processing module (APM).
+ struct SystemAudioProcessingInfo {
+ bool aec_supported = false;
+ int32_t aec_group_id = ash::CrasAudioHandler::kSystemAecGroupIdNotAvailable;
+ bool ns_supported = false;
+ bool agc_supported = false;
+ };
+
+ // Produces AudioParameters for the system, including audio processing
+ // capabilities tailored for the system,
+ static AudioParameters GetStreamParametersForSystem(
+ int user_buffer_size,
+ bool has_keyboard,
+ const AudioManagerChromeOS::SystemAudioProcessingInfo& system_apm_info);
+
protected:
AudioParameters GetPreferredOutputStreamParameters(
const std::string& output_device_id,
@@ -54,11 +71,8 @@ class MEDIA_EXPORT AudioManagerChromeOS : public AudioManagerCrasBase {
// Get default output buffer size for this board.
int GetDefaultOutputBufferSizePerBoard();
- // Get if system AEC is supported or not for this board.
- bool GetSystemAecSupportedPerBoard();
-
- // Get what the system AEC group ID is for this board.
- int32_t GetSystemAecGroupIdPerBoard();
+ // Get any system APM effects that are supported for this board.
+ SystemAudioProcessingInfo GetSystemApmEffectsSupportedPerBoard();
void GetAudioDeviceNamesImpl(bool is_input, AudioDeviceNames* device_names);
@@ -77,10 +91,9 @@ class MEDIA_EXPORT AudioManagerChromeOS : public AudioManagerCrasBase {
base::WaitableEvent* event);
void GetDefaultOutputBufferSizeOnMainThread(int32_t* buffer_size,
base::WaitableEvent* event);
- void GetSystemAecSupportedOnMainThread(bool* system_aec_supported,
- base::WaitableEvent* event);
- void GetSystemAecGroupIdOnMainThread(int32_t* group_id,
- base::WaitableEvent* event);
+ void GetSystemApmEffectsSupportedOnMainThread(
+ SystemAudioProcessingInfo* system_apm_info,
+ base::WaitableEvent* event);
void WaitEventOrShutdown(base::WaitableEvent* event);
diff --git a/chromium/media/audio/cras/audio_manager_chromeos_unittest.cc b/chromium/media/audio/cras/audio_manager_chromeos_unittest.cc
new file mode 100644
index 00000000000..db4517a4b3b
--- /dev/null
+++ b/chromium/media/audio/cras/audio_manager_chromeos_unittest.cc
@@ -0,0 +1,217 @@
+// Copyright (c) 2021 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 "media/audio/cras/audio_manager_chromeos.h"
+
+#include "base/test/scoped_feature_list.h"
+#include "media/audio/audio_features.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+namespace {
+constexpr int kAecTestGroupId = 9;
+constexpr int kNoAecFlaggedGroupId = 0;
+
+// Chosen to be the same as in `audio_manager_chromeos.cc`, but any size should
+// work since this should not affect the testing done herein.
+constexpr int kDefaultInputBufferSize = 1024;
+
+bool ExperimentalAecActive(const AudioParameters& params) {
+ return params.effects() & AudioParameters::EXPERIMENTAL_ECHO_CANCELLER;
+}
+
+bool AecActive(const AudioParameters& params) {
+ return params.effects() & AudioParameters::ECHO_CANCELLER;
+}
+
+bool NsActive(const AudioParameters& params) {
+ return params.effects() & AudioParameters::NOISE_SUPPRESSION;
+}
+
+bool AgcActive(const AudioParameters& params) {
+ return params.effects() & AudioParameters::AUTOMATIC_GAIN_CONTROL;
+}
+
+} // namespace
+
+class GetStreamParametersForSystem
+ : public ::testing::Test,
+ public ::testing::WithParamInterface<
+ std::tuple<bool, int, bool, int32_t, bool, bool>> {
+ protected:
+ // Retrieve test parameter values.
+ void GetTestParameters() {
+ has_keyboard_ = std::get<0>(GetParam());
+ user_buffer_size_ = std::get<1>(GetParam());
+ system_apm_info_.aec_supported = std::get<2>(GetParam());
+ system_apm_info_.aec_group_id = std::get<3>(GetParam());
+ system_apm_info_.ns_supported = std::get<4>(GetParam());
+ system_apm_info_.agc_supported = std::get<5>(GetParam());
+ }
+
+ AudioManagerChromeOS::SystemAudioProcessingInfo system_apm_info_;
+ size_t has_keyboard_;
+ size_t user_buffer_size_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ AllInputParameters,
+ GetStreamParametersForSystem,
+ ::testing::Combine(::testing::Values(false, true),
+ ::testing::Values(512, kDefaultInputBufferSize),
+ ::testing::Values(false, true),
+ ::testing::Values(kNoAecFlaggedGroupId, kAecTestGroupId),
+ ::testing::Values(false, true),
+ ::testing::Values(false, true)));
+
+TEST_P(GetStreamParametersForSystem, DefaultBehavior) {
+ GetTestParameters();
+ AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
+ user_buffer_size_, has_keyboard_, system_apm_info_);
+
+ EXPECT_TRUE(ExperimentalAecActive(params));
+ EXPECT_EQ(AecActive(params), system_apm_info_.aec_supported);
+ if (system_apm_info_.aec_supported) {
+ EXPECT_FALSE(NsActive(params));
+ EXPECT_FALSE(AgcActive(params));
+ } else {
+ EXPECT_FALSE(NsActive(params));
+ EXPECT_FALSE(AgcActive(params));
+ }
+}
+
+TEST_P(GetStreamParametersForSystem,
+ BehaviorWithCrOSEnforceSystemAecDisallowed) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndDisableFeature(features::kCrOSSystemAEC);
+
+ GetTestParameters();
+ AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
+ user_buffer_size_, has_keyboard_, system_apm_info_);
+
+ EXPECT_TRUE(ExperimentalAecActive(params));
+ EXPECT_FALSE(AecActive(params));
+ EXPECT_FALSE(NsActive(params));
+ EXPECT_FALSE(AgcActive(params));
+}
+
+TEST_P(GetStreamParametersForSystem, BehaviorWithCrOSEnforceSystemAecNsAgc) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecNsAgc);
+
+ GetTestParameters();
+ AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
+ user_buffer_size_, has_keyboard_, system_apm_info_);
+
+ EXPECT_TRUE(ExperimentalAecActive(params));
+ EXPECT_TRUE(AecActive(params));
+ if (system_apm_info_.aec_supported) {
+ EXPECT_FALSE(NsActive(params));
+ EXPECT_FALSE(AgcActive(params));
+ } else {
+ EXPECT_TRUE(NsActive(params));
+ EXPECT_TRUE(AgcActive(params));
+ }
+}
+
+TEST_P(GetStreamParametersForSystem,
+ BehaviorWithCrOSEnforceSystemAecNsAndAecAgc) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecNs);
+ feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecAgc);
+
+ GetTestParameters();
+ AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
+ user_buffer_size_, has_keyboard_, system_apm_info_);
+
+ EXPECT_TRUE(ExperimentalAecActive(params));
+ EXPECT_TRUE(AecActive(params));
+ if (system_apm_info_.aec_supported) {
+ EXPECT_FALSE(NsActive(params));
+ EXPECT_FALSE(AgcActive(params));
+ } else {
+ EXPECT_TRUE(NsActive(params));
+ EXPECT_TRUE(AgcActive(params));
+ }
+}
+
+TEST_P(GetStreamParametersForSystem,
+ BehaviorWithCrOSEnforceSystemAecNsAgcAndDisallowedSystemAec) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecNsAgc);
+ feature_list.InitAndDisableFeature(features::kCrOSSystemAEC);
+
+ GetTestParameters();
+ AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
+ user_buffer_size_, has_keyboard_, system_apm_info_);
+
+ EXPECT_TRUE(ExperimentalAecActive(params));
+ EXPECT_TRUE(AecActive(params));
+ if (system_apm_info_.aec_supported) {
+ EXPECT_FALSE(NsActive(params));
+ EXPECT_FALSE(AgcActive(params));
+ } else {
+ EXPECT_TRUE(NsActive(params));
+ EXPECT_TRUE(AgcActive(params));
+ }
+}
+
+TEST_P(GetStreamParametersForSystem, BehaviorWithCrOSEnforceSystemAecNs) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecNs);
+
+ GetTestParameters();
+ AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
+ user_buffer_size_, has_keyboard_, system_apm_info_);
+
+ EXPECT_TRUE(ExperimentalAecActive(params));
+ EXPECT_TRUE(AecActive(params));
+ if (system_apm_info_.aec_supported) {
+ EXPECT_FALSE(NsActive(params));
+ EXPECT_FALSE(AgcActive(params));
+ } else {
+ EXPECT_TRUE(NsActive(params));
+ EXPECT_EQ(AgcActive(params), system_apm_info_.agc_supported);
+ }
+}
+
+TEST_P(GetStreamParametersForSystem, BehaviorWithCrOSEnforceSystemAecAgc) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecAgc);
+
+ GetTestParameters();
+ AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
+ user_buffer_size_, has_keyboard_, system_apm_info_);
+
+ EXPECT_TRUE(ExperimentalAecActive(params));
+ EXPECT_TRUE(AecActive(params));
+ if (system_apm_info_.aec_supported) {
+ EXPECT_FALSE(NsActive(params));
+ EXPECT_FALSE(AgcActive(params));
+ } else {
+ EXPECT_EQ(NsActive(params), system_apm_info_.ns_supported);
+ EXPECT_TRUE(AgcActive(params));
+ }
+}
+
+TEST_P(GetStreamParametersForSystem, BehaviorWithCrOSEnforceSystemAec) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAec);
+
+ GetTestParameters();
+ AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
+ user_buffer_size_, has_keyboard_, system_apm_info_);
+
+ EXPECT_TRUE(ExperimentalAecActive(params));
+ EXPECT_TRUE(AecActive(params));
+ if (system_apm_info_.aec_supported) {
+ EXPECT_FALSE(NsActive(params));
+ EXPECT_FALSE(AgcActive(params));
+ } else {
+ EXPECT_EQ(NsActive(params), system_apm_info_.ns_supported);
+ EXPECT_EQ(AgcActive(params), system_apm_info_.agc_supported);
+ }
+}
+
+} // namespace media
diff --git a/chromium/media/audio/cras/cras_input.cc b/chromium/media/audio/cras/cras_input.cc
index dc91a84737f..ad4caaf5a17 100644
--- a/chromium/media/audio/cras/cras_input.cc
+++ b/chromium/media/audio/cras/cras_input.cc
@@ -45,22 +45,22 @@ CrasInputStream::~CrasInputStream() {
DCHECK(!client_);
}
-bool CrasInputStream::Open() {
+AudioInputStream::OpenOutcome CrasInputStream::Open() {
if (client_) {
NOTREACHED() << "CrasInputStream already open";
- return false; // Already open.
+ return OpenOutcome::kAlreadyOpen;
}
// Sanity check input values.
if (params_.sample_rate() <= 0) {
DLOG(WARNING) << "Unsupported audio frequency.";
- return false;
+ return OpenOutcome::kFailed;
}
if (AudioParameters::AUDIO_PCM_LINEAR != params_.format() &&
AudioParameters::AUDIO_PCM_LOW_LATENCY != params_.format()) {
DLOG(WARNING) << "Unsupported audio format.";
- return false;
+ return OpenOutcome::kFailed;
}
// Create the client and connect to the CRAS server.
@@ -68,14 +68,14 @@ bool CrasInputStream::Open() {
if (!client_) {
DLOG(WARNING) << "Couldn't create CRAS client.\n";
client_ = NULL;
- return false;
+ return OpenOutcome::kFailed;
}
if (libcras_client_connect(client_)) {
DLOG(WARNING) << "Couldn't connect CRAS client.\n";
libcras_client_destroy(client_);
client_ = NULL;
- return false;
+ return OpenOutcome::kFailed;
}
// Then start running the client.
@@ -83,7 +83,7 @@ bool CrasInputStream::Open() {
DLOG(WARNING) << "Couldn't run CRAS client.\n";
libcras_client_destroy(client_);
client_ = NULL;
- return false;
+ return OpenOutcome::kFailed;
}
if (is_loopback_) {
@@ -93,7 +93,7 @@ bool CrasInputStream::Open() {
// cleanup code.
libcras_client_destroy(client_);
client_ = NULL;
- return false;
+ return OpenOutcome::kFailed;
}
int rc = libcras_client_get_loopback_dev_idx(client_, &pin_device_);
@@ -101,11 +101,11 @@ bool CrasInputStream::Open() {
DLOG(WARNING) << "Couldn't find CRAS loopback device.";
libcras_client_destroy(client_);
client_ = NULL;
- return false;
+ return OpenOutcome::kFailed;
}
}
- return true;
+ return OpenOutcome::kSuccess;
}
void CrasInputStream::Close() {
@@ -126,6 +126,14 @@ inline bool CrasInputStream::UseCrasAec() const {
return params_.effects() & AudioParameters::ECHO_CANCELLER;
}
+inline bool CrasInputStream::UseCrasNs() const {
+ return params_.effects() & AudioParameters::NOISE_SUPPRESSION;
+}
+
+inline bool CrasInputStream::UseCrasAgc() const {
+ return params_.effects() & AudioParameters::AUTOMATIC_GAIN_CONTROL;
+}
+
void CrasInputStream::Start(AudioInputCallback* callback) {
DCHECK(client_);
DCHECK(callback);
@@ -212,6 +220,12 @@ void CrasInputStream::Start(AudioInputCallback* callback) {
if (UseCrasAec())
libcras_stream_params_enable_aec(stream_params);
+ if (UseCrasNs())
+ libcras_stream_params_enable_ns(stream_params);
+
+ if (UseCrasAgc())
+ libcras_stream_params_enable_agc(stream_params);
+
// Adding the stream will start the audio callbacks.
if (libcras_client_add_pinned_stream(client_, pin_device_, &stream_id_,
stream_params)) {
diff --git a/chromium/media/audio/cras/cras_input.h b/chromium/media/audio/cras/cras_input.h
index 17fa790e5ff..8efe59a35c8 100644
--- a/chromium/media/audio/cras/cras_input.h
+++ b/chromium/media/audio/cras/cras_input.h
@@ -39,7 +39,7 @@ class MEDIA_EXPORT CrasInputStream : public AgcAudioStream<AudioInputStream> {
~CrasInputStream() override;
// Implementation of AudioInputStream.
- bool Open() override;
+ AudioInputStream::OpenOutcome Open() override;
void Start(AudioInputCallback* callback) override;
void Stop() override;
void Close() override;
@@ -76,6 +76,12 @@ class MEDIA_EXPORT CrasInputStream : public AgcAudioStream<AudioInputStream> {
// Return true to use AEC in CRAS for this input stream.
inline bool UseCrasAec() const;
+ // Return true to use NS in CRAS for this input stream.
+ inline bool UseCrasNs() const;
+
+ // Return true to use AGC in CRAS for this input stream.
+ inline bool UseCrasAgc() const;
+
// Non-refcounted pointer back to the audio manager.
// The AudioManager indirectly holds on to stream objects, so we don't
// want circular references. Additionally, stream objects live on the audio
diff --git a/chromium/media/audio/cras/cras_input_unittest.cc b/chromium/media/audio/cras/cras_input_unittest.cc
index 04d4deafe09..5bda316b07f 100644
--- a/chromium/media/audio/cras/cras_input_unittest.cc
+++ b/chromium/media/audio/cras/cras_input_unittest.cc
@@ -102,7 +102,7 @@ class CrasInputStreamTest : public testing::Test {
CrasInputStream* test_stream = new CrasInputStream(
params, mock_manager_.get(), AudioDeviceDescription::kDefaultDeviceId);
- ASSERT_TRUE(test_stream->Open());
+ EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
// Allow 8 frames variance for SRC in the callback. Different numbers of
// samples can be provided when doing non-integer SRC. For example
@@ -146,13 +146,13 @@ const int CrasInputStreamTest::kTestSampleRate = 44100;
TEST_F(CrasInputStreamTest, OpenMono) {
CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
- EXPECT_TRUE(test_stream->Open());
+ EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
test_stream->Close();
}
TEST_F(CrasInputStreamTest, OpenStereo) {
CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_STEREO);
- EXPECT_TRUE(test_stream->Open());
+ EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
test_stream->Close();
}
@@ -164,13 +164,13 @@ TEST_F(CrasInputStreamTest, BadSampleRate) {
CrasInputStream* test_stream =
new CrasInputStream(bad_rate_params, mock_manager_.get(),
AudioDeviceDescription::kDefaultDeviceId);
- EXPECT_FALSE(test_stream->Open());
+ EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kFailed);
test_stream->Close();
}
TEST_F(CrasInputStreamTest, SetGetVolume) {
CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
- EXPECT_TRUE(test_stream->Open());
+ EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
double max_volume = test_stream->GetMaxVolume();
EXPECT_GE(max_volume, 1.0);
@@ -212,7 +212,7 @@ TEST_F(CrasInputStreamTest, CaptureLoopback) {
CrasInputStream* test_stream =
CreateStream(CHANNEL_LAYOUT_STEREO, kTestFramesPerPacket,
AudioDeviceDescription::kLoopbackInputDeviceId);
- EXPECT_TRUE(test_stream->Open());
+ EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
test_stream->Close();
}
diff --git a/chromium/media/audio/cras/cras_unified.h b/chromium/media/audio/cras/cras_unified.h
index eb57e01c402..26055a726b2 100644
--- a/chromium/media/audio/cras/cras_unified.h
+++ b/chromium/media/audio/cras/cras_unified.h
@@ -18,7 +18,6 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/time/time.h"
#include "media/audio/audio_io.h"
#include "media/base/audio_parameters.h"
diff --git a/chromium/media/audio/fake_audio_input_stream.cc b/chromium/media/audio/fake_audio_input_stream.cc
index ca0ec900067..7d500303fc0 100644
--- a/chromium/media/audio/fake_audio_input_stream.cc
+++ b/chromium/media/audio/fake_audio_input_stream.cc
@@ -61,11 +61,11 @@ FakeAudioInputStream::~FakeAudioInputStream() {
DCHECK(!fake_audio_worker_);
}
-bool FakeAudioInputStream::Open() {
+AudioInputStream::OpenOutcome FakeAudioInputStream::Open() {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
audio_bus_->Zero();
- return true;
+ return OpenOutcome::kSuccess;
}
void FakeAudioInputStream::Start(AudioInputCallback* callback) {
@@ -79,7 +79,7 @@ void FakeAudioInputStream::Start(AudioInputCallback* callback) {
// REALTIME_AUDIO priority is needed to avoid audio playout delays.
// See crbug.com/971265
options.priority = base::ThreadPriority::REALTIME_AUDIO;
- CHECK(capture_thread_->StartWithOptions(options));
+ CHECK(capture_thread_->StartWithOptions(std::move(options)));
{
base::AutoLock lock(callback_lock_);
diff --git a/chromium/media/audio/fake_audio_input_stream.h b/chromium/media/audio/fake_audio_input_stream.h
index b76f12fdde5..809edfb7b2f 100644
--- a/chromium/media/audio/fake_audio_input_stream.h
+++ b/chromium/media/audio/fake_audio_input_stream.h
@@ -28,13 +28,12 @@ class AudioManagerBase;
// beeping sound unless --use-file-for-fake-audio-capture=<file> is specified,
// in which case the indicated .wav file will be read and played into the
// stream.
-class MEDIA_EXPORT FakeAudioInputStream
- : public AudioInputStream {
+class MEDIA_EXPORT FakeAudioInputStream : public AudioInputStream {
public:
- static AudioInputStream* MakeFakeStream(
- AudioManagerBase* manager, const AudioParameters& params);
+ static AudioInputStream* MakeFakeStream(AudioManagerBase* manager,
+ const AudioParameters& params);
- bool Open() override;
+ OpenOutcome Open() override;
void Start(AudioInputCallback* callback) override;
void Stop() override;
void Close() override;
diff --git a/chromium/media/audio/fuchsia/DIR_METADATA b/chromium/media/audio/fuchsia/DIR_METADATA
index e88f62328ca..abc57ac0fd5 100644
--- a/chromium/media/audio/fuchsia/DIR_METADATA
+++ b/chromium/media/audio/fuchsia/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
team_email: "cr-fuchsia@chromium.org"
os: FUCHSIA \ No newline at end of file
diff --git a/chromium/media/audio/fuchsia/OWNERS b/chromium/media/audio/fuchsia/OWNERS
index 3ebcc4268bd..e7034eabb1e 100644
--- a/chromium/media/audio/fuchsia/OWNERS
+++ b/chromium/media/audio/fuchsia/OWNERS
@@ -1 +1 @@
-file://build/fuchsia/OWNERS \ No newline at end of file
+file://build/fuchsia/OWNERS
diff --git a/chromium/media/audio/fuchsia/audio_output_stream_fuchsia.h b/chromium/media/audio/fuchsia/audio_output_stream_fuchsia.h
index ff8fe2d62a0..5f5bfa89501 100644
--- a/chromium/media/audio/fuchsia/audio_output_stream_fuchsia.h
+++ b/chromium/media/audio/fuchsia/audio_output_stream_fuchsia.h
@@ -8,10 +8,10 @@
#include <fuchsia/media/cpp/fidl.h>
#include "base/memory/shared_memory_mapping.h"
-#include "base/optional.h"
#include "base/timer/timer.h"
#include "media/audio/audio_io.h"
#include "media/base/audio_parameters.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -92,7 +92,7 @@ class AudioOutputStreamFuchsia : public AudioOutputStream {
// Current min lead time for the stream. This value is not set until the first
// AudioRenderer::OnMinLeadTimeChanged event.
- base::Optional<base::TimeDelta> min_lead_time_;
+ absl::optional<base::TimeDelta> min_lead_time_;
// Timer that's scheduled to call PumpSamples().
base::OneShotTimer timer_;
diff --git a/chromium/media/audio/mac/audio_device_listener_mac.cc b/chromium/media/audio/mac/audio_device_listener_mac.cc
index bccd5e64fb0..347608260fb 100644
--- a/chromium/media/audio/mac/audio_device_listener_mac.cc
+++ b/chromium/media/audio/mac/audio_device_listener_mac.cc
@@ -10,11 +10,11 @@
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "media/audio/audio_manager.h"
#include "media/audio/mac/core_audio_util_mac.h"
#include "media/base/bind_to_current_loop.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
diff --git a/chromium/media/audio/mac/audio_input_mac.cc b/chromium/media/audio/mac/audio_input_mac.cc
index 7cac52acea6..3151f4e687a 100644
--- a/chromium/media/audio/mac/audio_input_mac.cc
+++ b/chromium/media/audio/mac/audio_input_mac.cc
@@ -27,7 +27,7 @@ namespace {
// should ideally be set to about the same value as in
// audio_low_latency_input_mac.cc, to make comparing them reasonable.
const int kInputCallbackStartTimeoutInSeconds = 8;
-}
+} // namespace
PCMQueueInAudioInputStream::PCMQueueInAudioInputStream(
AudioManagerMac* manager,
@@ -66,7 +66,7 @@ PCMQueueInAudioInputStream::~PCMQueueInAudioInputStream() {
DCHECK(!audio_queue_);
}
-bool PCMQueueInAudioInputStream::Open() {
+AudioInputStream::OpenOutcome PCMQueueInAudioInputStream::Open() {
OSStatus err = AudioQueueNewInput(&format_,
&HandleInputBufferStatic,
this,
@@ -76,9 +76,10 @@ bool PCMQueueInAudioInputStream::Open() {
&audio_queue_);
if (err != noErr) {
HandleError(err);
- return false;
+ return AudioInputStream::OpenOutcome::kFailed;
}
- return SetupBuffers();
+ return SetupBuffers() ? AudioInputStream::OpenOutcome::kSuccess
+ : AudioInputStream::OpenOutcome::kFailed;
}
void PCMQueueInAudioInputStream::Start(AudioInputCallback* callback) {
diff --git a/chromium/media/audio/mac/audio_input_mac.h b/chromium/media/audio/mac/audio_input_mac.h
index b96aadfa8eb..15da618e448 100644
--- a/chromium/media/audio/mac/audio_input_mac.h
+++ b/chromium/media/audio/mac/audio_input_mac.h
@@ -35,7 +35,7 @@ class PCMQueueInAudioInputStream : public AudioInputStream {
~PCMQueueInAudioInputStream() override;
// Implementation of AudioInputStream.
- bool Open() override;
+ AudioInputStream::OpenOutcome Open() override;
void Start(AudioInputCallback* callback) override;
void Stop() override;
void Close() override;
diff --git a/chromium/media/audio/mac/audio_low_latency_input_mac.cc b/chromium/media/audio/mac/audio_low_latency_input_mac.cc
index e5fd2b351b4..eb39b38c308 100644
--- a/chromium/media/audio/mac/audio_low_latency_input_mac.cc
+++ b/chromium/media/audio/mac/audio_low_latency_input_mac.cc
@@ -286,7 +286,7 @@ AUAudioInputStream::~AUAudioInputStream() {
}
// Obtain and open the AUHAL AudioOutputUnit for recording.
-bool AUAudioInputStream::Open() {
+AudioInputStream::OpenOutcome AUAudioInputStream::Open() {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "Open";
DCHECK(!audio_unit_);
@@ -296,7 +296,7 @@ bool AUAudioInputStream::Open() {
if (input_device_id_ == kAudioObjectUnknown) {
NOTREACHED() << "Device ID is unknown";
HandleError(kAudioUnitErr_InvalidElement);
- return false;
+ return OpenOutcome::kFailed;
}
// The requested sample-rate must match the hardware sample-rate.
@@ -311,7 +311,7 @@ bool AUAudioInputStream::Open() {
use_voice_processing_ ? OpenVoiceProcessingAU() : OpenAUHAL();
if (!success)
- return false;
+ return OpenOutcome::kFailed;
// The hardware latency is fixed and will not change during the call.
hardware_latency_ = AudioManagerMac::GetHardwareLatency(
@@ -322,7 +322,7 @@ bool AUAudioInputStream::Open() {
// And the master channel is not counted in |number_of_channels_in_frame_|.
number_of_channels_in_frame_ = GetNumberOfChannelsFromStream();
- return true;
+ return OpenOutcome::kSuccess;
}
bool AUAudioInputStream::OpenAUHAL() {
diff --git a/chromium/media/audio/mac/audio_low_latency_input_mac.h b/chromium/media/audio/mac/audio_low_latency_input_mac.h
index da716271eab..1344ba83e3e 100644
--- a/chromium/media/audio/mac/audio_low_latency_input_mac.h
+++ b/chromium/media/audio/mac/audio_low_latency_input_mac.h
@@ -72,7 +72,7 @@ class MEDIA_EXPORT AUAudioInputStream
~AUAudioInputStream() override;
// Implementation of AudioInputStream.
- bool Open() override;
+ AudioInputStream::OpenOutcome Open() override;
void Start(AudioInputCallback* callback) override;
void Stop() override;
void Close() override;
diff --git a/chromium/media/audio/mac/audio_low_latency_input_mac_unittest.cc b/chromium/media/audio/mac/audio_low_latency_input_mac_unittest.cc
index 341111d2e6b..96287c9515e 100644
--- a/chromium/media/audio/mac/audio_low_latency_input_mac_unittest.cc
+++ b/chromium/media/audio/mac/audio_low_latency_input_mac_unittest.cc
@@ -184,7 +184,7 @@ TEST_F(MacAudioInputTest, AUAudioInputStreamCreateAndClose) {
TEST_F(MacAudioInputTest, AUAudioInputStreamOpenAndClose) {
ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
AudioInputStream* ais = CreateDefaultAudioInputStream();
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
ais->Close();
}
@@ -192,7 +192,7 @@ TEST_F(MacAudioInputTest, AUAudioInputStreamOpenAndClose) {
TEST_F(MacAudioInputTest, AUAudioInputStreamOpenStartAndClose) {
ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
AudioInputStream* ais = CreateDefaultAudioInputStream();
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
MockAudioInputCallback sink;
ais->Start(&sink);
ais->Close();
@@ -202,7 +202,7 @@ TEST_F(MacAudioInputTest, AUAudioInputStreamOpenStartAndClose) {
TEST_F(MacAudioInputTest, AUAudioInputStreamOpenStartStopAndClose) {
ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
AudioInputStream* ais = CreateDefaultAudioInputStream();
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
MockAudioInputCallback sink;
ais->Start(&sink);
ais->Stop();
@@ -217,7 +217,7 @@ TEST_F(MacAudioInputTest, AUAudioInputStreamVerifyMonoRecording) {
// Create an audio input stream which records in mono.
AudioInputStream* ais = CreateAudioInputStream(CHANNEL_LAYOUT_MONO);
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
MockAudioInputCallback sink;
@@ -246,7 +246,7 @@ TEST_F(MacAudioInputTest, AUAudioInputStreamVerifyStereoRecording) {
// Create an audio input stream which records in stereo.
AudioInputStream* ais = CreateAudioInputStream(CHANNEL_LAYOUT_STEREO);
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
MockAudioInputCallback sink;
@@ -286,7 +286,7 @@ TEST_F(MacAudioInputTest, DISABLED_AUAudioInputStreamRecordToFile) {
int fs = static_cast<int>(AUAudioInputStream::HardwareSampleRate());
AudioInputStream* ais = CreateDefaultAudioInputStream();
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
fprintf(stderr, " File name : %s\n", file_name);
fprintf(stderr, " Sample rate: %d\n", fs);
diff --git a/chromium/media/audio/mac/audio_manager_mac.cc b/chromium/media/audio/mac/audio_manager_mac.cc
index 29f12e9928e..261596b9b74 100644
--- a/chromium/media/audio/mac/audio_manager_mac.cc
+++ b/chromium/media/audio/mac/audio_manager_mac.cc
@@ -17,7 +17,6 @@
#include "base/mac/scoped_cftyperef.h"
#include "base/macros.h"
#include "base/memory/free_deleter.h"
-#include "base/optional.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_observer.h"
#include "base/strings/sys_string_conversions.h"
@@ -36,6 +35,7 @@
#include "media/base/limits.h"
#include "media/base/mac/audio_latency_mac.h"
#include "media/base/media_switches.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -139,12 +139,12 @@ static void GetAudioDeviceInfo(bool is_input,
if (!is_valid_for_direction)
continue;
- base::Optional<std::string> unique_id =
+ absl::optional<std::string> unique_id =
core_audio_mac::GetDeviceUniqueID(device_id);
if (!unique_id)
continue;
- base::Optional<std::string> label =
+ absl::optional<std::string> label =
core_audio_mac::GetDeviceLabel(device_id, is_input);
if (!label)
continue;
@@ -680,7 +680,7 @@ std::string AudioManagerMac::GetAssociatedOutputDeviceID(
// to detect if a device (e.g. a digital output device) is actually connected
// to an endpoint, so we cannot randomly pick a device.
if (related_output_device_ids.size() == 1) {
- base::Optional<std::string> related_unique_id =
+ absl::optional<std::string> related_unique_id =
core_audio_mac::GetDeviceUniqueID(related_output_device_ids[0]);
if (related_unique_id)
return std::move(*related_unique_id);
diff --git a/chromium/media/audio/mac/core_audio_util_mac.cc b/chromium/media/audio/mac/core_audio_util_mac.cc
index fa6dcf24539..8283c1abba6 100644
--- a/chromium/media/audio/mac/core_audio_util_mac.cc
+++ b/chromium/media/audio/mac/core_audio_util_mac.cc
@@ -23,7 +23,7 @@ AudioObjectPropertyScope InputOutputScope(bool is_input) {
: kAudioObjectPropertyScopeOutput;
}
-base::Optional<std::string> GetDeviceStringProperty(
+absl::optional<std::string> GetDeviceStringProperty(
AudioObjectID device_id,
AudioObjectPropertySelector property_selector) {
CFStringRef property_value = nullptr;
@@ -39,11 +39,11 @@ base::Optional<std::string> GetDeviceStringProperty(
OSSTATUS_DLOG(WARNING, result)
<< "Failed to read string property " << property_selector
<< " for device " << device_id;
- return base::nullopt;
+ return absl::nullopt;
}
if (!property_value)
- return base::nullopt;
+ return absl::nullopt;
std::string device_property = base::SysCFStringRefToUTF8(property_value);
CFRelease(property_value);
@@ -51,7 +51,7 @@ base::Optional<std::string> GetDeviceStringProperty(
return device_property;
}
-base::Optional<uint32_t> GetDeviceUint32Property(
+absl::optional<uint32_t> GetDeviceUint32Property(
AudioObjectID device_id,
AudioObjectPropertySelector property_selector,
AudioObjectPropertyScope property_scope) {
@@ -63,7 +63,7 @@ base::Optional<uint32_t> GetDeviceUint32Property(
device_id, &property_address, 0 /* inQualifierDataSize */,
nullptr /* inQualifierData */, &size, &property_value);
if (result != noErr)
- return base::nullopt;
+ return absl::nullopt;
return property_value;
}
@@ -123,11 +123,11 @@ std::vector<AudioObjectID> GetAudioObjectIDs(
return device_ids;
}
-base::Optional<std::string> GetDeviceName(AudioObjectID device_id) {
+absl::optional<std::string> GetDeviceName(AudioObjectID device_id) {
return GetDeviceStringProperty(device_id, kAudioObjectPropertyName);
}
-base::Optional<std::string> GetDeviceModel(AudioObjectID device_id) {
+absl::optional<std::string> GetDeviceModel(AudioObjectID device_id) {
return GetDeviceStringProperty(device_id, kAudioDevicePropertyModelUID);
}
@@ -178,7 +178,7 @@ std::string TransportTypeToString(uint32_t transport_type) {
}
}
-base::Optional<std::string> TranslateDeviceSource(AudioObjectID device_id,
+absl::optional<std::string> TranslateDeviceSource(AudioObjectID device_id,
UInt32 source_id,
bool is_input) {
CFStringRef source_name = nullptr;
@@ -197,7 +197,7 @@ base::Optional<std::string> TranslateDeviceSource(AudioObjectID device_id,
device_id, &property_address, 0 /* inQualifierDataSize */,
nullptr /* inQualifierData */, &translation_size, &translation);
if (result)
- return base::nullopt;
+ return absl::nullopt;
std::string ret = base::SysCFStringRefToUTF8(source_name);
CFRelease(source_name);
@@ -216,14 +216,14 @@ std::vector<AudioObjectID> GetRelatedDeviceIDs(AudioObjectID device_id) {
return GetAudioObjectIDs(device_id, kAudioDevicePropertyRelatedDevices);
}
-base::Optional<std::string> GetDeviceUniqueID(AudioObjectID device_id) {
+absl::optional<std::string> GetDeviceUniqueID(AudioObjectID device_id) {
return GetDeviceStringProperty(device_id, kAudioDevicePropertyDeviceUID);
}
-base::Optional<std::string> GetDeviceLabel(AudioObjectID device_id,
+absl::optional<std::string> GetDeviceLabel(AudioObjectID device_id,
bool is_input) {
- base::Optional<std::string> device_label;
- base::Optional<uint32_t> source = GetDeviceSource(device_id, is_input);
+ absl::optional<std::string> device_label;
+ absl::optional<uint32_t> source = GetDeviceSource(device_id, is_input);
if (source) {
device_label = TranslateDeviceSource(device_id, *source, is_input);
}
@@ -231,14 +231,14 @@ base::Optional<std::string> GetDeviceLabel(AudioObjectID device_id,
if (!device_label) {
device_label = GetDeviceName(device_id);
if (!device_label)
- return base::nullopt;
+ return absl::nullopt;
}
std::string suffix;
- base::Optional<uint32_t> transport_type = GetDeviceTransportType(device_id);
+ absl::optional<uint32_t> transport_type = GetDeviceTransportType(device_id);
if (transport_type) {
if (*transport_type == kAudioDeviceTransportTypeUSB) {
- base::Optional<std::string> model = GetDeviceModel(device_id);
+ absl::optional<std::string> model = GetDeviceModel(device_id);
if (model) {
suffix = UsbVidPidFromModel(*model);
}
@@ -259,13 +259,13 @@ uint32_t GetNumStreams(AudioObjectID device_id, bool is_input) {
InputOutputScope(is_input));
}
-base::Optional<uint32_t> GetDeviceSource(AudioObjectID device_id,
+absl::optional<uint32_t> GetDeviceSource(AudioObjectID device_id,
bool is_input) {
return GetDeviceUint32Property(device_id, kAudioDevicePropertyDataSource,
InputOutputScope(is_input));
}
-base::Optional<uint32_t> GetDeviceTransportType(AudioObjectID device_id) {
+absl::optional<uint32_t> GetDeviceTransportType(AudioObjectID device_id) {
return GetDeviceUint32Property(device_id, kAudioDevicePropertyTransportType,
kAudioObjectPropertyScopeGlobal);
}
diff --git a/chromium/media/audio/mac/core_audio_util_mac.h b/chromium/media/audio/mac/core_audio_util_mac.h
index b8301be3ecc..b46243a5167 100644
--- a/chromium/media/audio/mac/core_audio_util_mac.h
+++ b/chromium/media/audio/mac/core_audio_util_mac.h
@@ -10,7 +10,7 @@
#include <string>
#include <vector>
-#include "base/optional.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace core_audio_mac {
@@ -26,12 +26,12 @@ std::vector<AudioObjectID> GetRelatedDeviceIDs(AudioObjectID device_id);
// Returns a string with a unique device ID for the given |device_id|, or no
// value if there is an error.
-base::Optional<std::string> GetDeviceUniqueID(AudioObjectID device_id);
+absl::optional<std::string> GetDeviceUniqueID(AudioObjectID device_id);
// Returns a string with a descriptive label for the given |device_id|, or no
// value if there is an error. The returned label is based on several
// characteristics of the device.
-base::Optional<std::string> GetDeviceLabel(AudioObjectID device_id,
+absl::optional<std::string> GetDeviceLabel(AudioObjectID device_id,
bool is_input);
// Returns the number of input or output streams associated with the given
@@ -40,12 +40,12 @@ uint32_t GetNumStreams(AudioObjectID device_id, bool is_input);
// Returns the source associated with the given |device_id|, or no value if
// |device_id| has no source or if there is an error.
-base::Optional<uint32_t> GetDeviceSource(AudioObjectID device_id,
+absl::optional<uint32_t> GetDeviceSource(AudioObjectID device_id,
bool is_input);
// Returns the transport type of the given |device_id|, or no value if
// |device_id| has no source or if there is an error.
-base::Optional<uint32_t> GetDeviceTransportType(AudioObjectID device_id);
+absl::optional<uint32_t> GetDeviceTransportType(AudioObjectID device_id);
// Returns whether or not the |device_id| corresponds to a private, aggregate
// device. Such a device gets created by instantiating a VoiceProcessingIO
diff --git a/chromium/media/audio/pulse/pulse_input.cc b/chromium/media/audio/pulse/pulse_input.cc
index 10bbd2d2af6..59b288eda69 100644
--- a/chromium/media/audio/pulse/pulse_input.cc
+++ b/chromium/media/audio/pulse/pulse_input.cc
@@ -56,25 +56,25 @@ PulseAudioInputStream::~PulseAudioInputStream() {
DCHECK(!handle_);
}
-bool PulseAudioInputStream::Open() {
+AudioInputStream::OpenOutcome PulseAudioInputStream::Open() {
DCHECK(thread_checker_.CalledOnValidThread());
SendLogMessage("%s()", __func__);
if (device_name_ == AudioDeviceDescription::kDefaultDeviceId &&
audio_manager_->DefaultSourceIsMonitor()) {
SendLogMessage("%s => (ERROR: can't open monitor device)", __func__);
- return false;
+ return OpenOutcome::kFailed;
}
AutoPulseLock auto_lock(pa_mainloop_);
if (!pulse::CreateInputStream(pa_mainloop_, pa_context_, &handle_, params_,
device_name_, &StreamNotifyCallback, this)) {
SendLogMessage("%s => (ERROR: failed to open PA stream)", __func__);
- return false;
+ return OpenOutcome::kFailed;
}
DCHECK(handle_);
- return true;
+ return OpenOutcome::kSuccess;
}
void PulseAudioInputStream::Start(AudioInputCallback* callback) {
diff --git a/chromium/media/audio/pulse/pulse_input.h b/chromium/media/audio/pulse/pulse_input.h
index 2fe4b773fb2..b340bda07e9 100644
--- a/chromium/media/audio/pulse/pulse_input.h
+++ b/chromium/media/audio/pulse/pulse_input.h
@@ -34,7 +34,7 @@ class PulseAudioInputStream : public AgcAudioStream<AudioInputStream> {
~PulseAudioInputStream() override;
// Implementation of AudioInputStream.
- bool Open() override;
+ AudioInputStream::OpenOutcome Open() override;
void Start(AudioInputCallback* callback) override;
void Stop() override;
void Close() override;
diff --git a/chromium/media/audio/win/audio_low_latency_input_win.cc b/chromium/media/audio/win/audio_low_latency_input_win.cc
index a5e5daf3ce7..f97f1e6eabe 100644
--- a/chromium/media/audio/win/audio_low_latency_input_win.cc
+++ b/chromium/media/audio/win/audio_low_latency_input_win.cc
@@ -30,12 +30,14 @@
#include "media/audio/audio_features.h"
#include "media/audio/win/avrt_wrapper_win.h"
#include "media/audio/win/core_audio_util_win.h"
+#include "media/audio/win/volume_range_util.h"
#include "media/base/audio_block_fifo.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_timestamp_helper.h"
#include "media/base/channel_layout.h"
#include "media/base/limits.h"
#include "media/base/media_switches.h"
+#include "media/base/timestamp_constants.h"
using ABI::Windows::Foundation::Collections::IVectorView;
using ABI::Windows::Media::Devices::IMediaDeviceStatics;
@@ -339,11 +341,11 @@ WASAPIAudioInputStream::~WASAPIAudioInputStream() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
-bool WASAPIAudioInputStream::Open() {
+AudioInputStream::OpenOutcome WASAPIAudioInputStream::Open() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
SendLogMessage("%s([opened=%s])", __func__, opened_ ? "true" : "false");
if (opened_) {
- return false;
+ return OpenOutcome::kAlreadyOpen;
}
// Obtain a reference to the IMMDevice interface of the capturing device with
@@ -351,7 +353,7 @@ bool WASAPIAudioInputStream::Open() {
HRESULT hr = SetCaptureDevice();
if (FAILED(hr)) {
ReportOpenResult(hr);
- return false;
+ return OpenOutcome::kFailed;
}
// Check if raw audio processing is supported for the selected capture device.
@@ -382,7 +384,7 @@ bool WASAPIAudioInputStream::Open() {
if (FAILED(hr)) {
open_result_ = OPEN_RESULT_ACTIVATION_FAILED;
ReportOpenResult(hr);
- return false;
+ return OpenOutcome::kFailed;
}
#ifndef NDEBUG
@@ -407,7 +409,7 @@ bool WASAPIAudioInputStream::Open() {
if (!DesiredFormatIsSupported(&hr)) {
open_result_ = OPEN_RESULT_FORMAT_NOT_SUPPORTED;
ReportOpenResult(hr);
- return false;
+ return OpenOutcome::kFailed;
}
// Initialize the audio stream between the client and the device using
@@ -418,7 +420,12 @@ bool WASAPIAudioInputStream::Open() {
ReportOpenResult(hr); // Report before we assign a value to |opened_|.
opened_ = SUCCEEDED(hr);
- return opened_;
+ if (opened_) {
+ return OpenOutcome::kSuccess;
+ }
+
+ return (hr == E_ACCESSDENIED) ? OpenOutcome::kFailedSystemPermissions
+ : OpenOutcome::kFailed;
}
void WASAPIAudioInputStream::Start(AudioInputCallback* callback) {
@@ -466,9 +473,9 @@ void WASAPIAudioInputStream::Start(AudioInputCallback* callback) {
// Create and start the thread that will drive the capturing by waiting for
// capture events.
DCHECK(!capture_thread_.get());
- capture_thread_.reset(new base::DelegateSimpleThread(
+ capture_thread_ = std::make_unique<base::DelegateSimpleThread>(
this, "wasapi_capture_thread",
- base::SimpleThread::Options(base::ThreadPriority::REALTIME_AUDIO)));
+ base::SimpleThread::Options(base::ThreadPriority::REALTIME_AUDIO));
capture_thread_->Start();
// Start streaming data between the endpoint buffer and the audio engine.
@@ -509,6 +516,23 @@ void WASAPIAudioInputStream::Stop() {
}
}
+ absl::optional<VolumeRange> volume_range;
+ if (add_uma_histogram && system_audio_volume_ &&
+ !AudioDeviceDescription::IsLoopbackDevice(device_id_)) {
+ VolumeRange range;
+ HRESULT hr = system_audio_volume_->GetVolumeRange(
+ &range.min_volume_db, &range.max_volume_db, &range.volume_step_db);
+ if (FAILED(hr)) {
+ SendLogMessage("%s => (ERROR: IAudioEndpointVolume::GetVolumeRange=[%s])",
+ __func__, ErrorToString(hr).c_str());
+ } else {
+ SendLogMessage("%s => (IAudioEndpointVolume::GetVolumeRange) %f %f %f",
+ __func__, range.min_volume_db, range.max_volume_db,
+ range.volume_step_db);
+ volume_range = range;
+ }
+ }
+
// Stops periodic AGC microphone measurements.
StopAgc();
@@ -537,8 +561,21 @@ void WASAPIAudioInputStream::Stop() {
base::UmaHistogramBoolean("Media.Audio.InputVolumeStartsAtZeroWin",
audio_session_starts_at_zero_volume_);
audio_session_starts_at_zero_volume_ = false;
+ LogVolumeRangeUmaHistograms(volume_range);
}
+ SendLogMessage(
+ "%s => (timestamp(n)-timestamp(n-1)=[min: %.3f msec, max: %.3f msec])",
+ __func__, min_timestamp_diff_.InMillisecondsF(),
+ max_timestamp_diff_.InMillisecondsF());
+
+ const bool monotonic_timestamps =
+ min_timestamp_diff_ >= base::TimeDelta::FromMicroseconds(1);
+ base::UmaHistogramBoolean("Media.Audio.Capture.Win.MonotonicTimestamps",
+ monotonic_timestamps);
+ SendLogMessage("%s => (Media.Audio.Capture.Win.MonotonicTimestamps=%s)",
+ __func__, monotonic_timestamps ? "true" : "false");
+
started_ = false;
sink_ = nullptr;
}
@@ -706,8 +743,8 @@ void WASAPIAudioInputStream::Run() {
++buffers_required;
DCHECK(!fifo_);
- fifo_.reset(new AudioBlockFifo(input_format_.Format.nChannels,
- packet_size_frames_, buffers_required));
+ fifo_ = std::make_unique<AudioBlockFifo>(
+ input_format_.Format.nChannels, packet_size_frames_, buffers_required);
DVLOG(1) << "AudioBlockFifo buffer count: " << buffers_required;
bool recording = true;
@@ -715,6 +752,11 @@ void WASAPIAudioInputStream::Run() {
HANDLE wait_array[2] = {stop_capture_event_.Get(),
audio_samples_ready_event_.Get()};
+ record_start_time_ = base::TimeTicks::Now();
+ last_capture_time_ = base::TimeTicks();
+ max_timestamp_diff_ = base::TimeDelta::Min();
+ min_timestamp_diff_ = base::TimeDelta::Max();
+
while (recording && !error) {
// Wait for a close-down event or a new capture event.
DWORD wait_result = WaitForMultipleObjects(2, wait_array, FALSE, INFINITE);
@@ -754,39 +796,81 @@ void WASAPIAudioInputStream::PullCaptureDataAndPushToSink() {
"sample rate", input_format_.Format.nSamplesPerSec);
UINT64 last_device_position = 0;
+ UINT32 num_frames_in_next_packet = 0;
+
+ // Get the number of frames in the next data packet in the capture endpoint
+ // buffer. The count reported by GetNextPacketSize matches the count retrieved
+ // in the GetBuffer call that follows this call.
+ HRESULT hr =
+ audio_capture_client_->GetNextPacketSize(&num_frames_in_next_packet);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "WAIS::" << __func__
+ << " => (ERROR: 1-IAudioCaptureClient::GetNextPacketSize=["
+ << ErrorToString(hr).c_str() << "])";
+ return;
+ }
// Pull data from the capture endpoint buffer until it's empty or an error
- // occurs.
- while (true) {
+ // occurs. Drains the WASAPI capture buffer fully.
+ while (num_frames_in_next_packet > 0) {
BYTE* data_ptr = nullptr;
UINT32 num_frames_to_read = 0;
DWORD flags = 0;
UINT64 device_position = 0;
-
- // Note: The units on this are 100ns intervals. Both GetBuffer() and
- // GetPosition() will handle the translation from the QPC value, so we just
- // need to convert from 100ns units into us. Which is just dividing by 10.0
- // since 10x100ns = 1us.
UINT64 capture_time_100ns = 0;
// Retrieve the amount of data in the capture endpoint buffer, replace it
// with silence if required, create callbacks for each packet and store
// non-delivered data for the next event.
- HRESULT hr =
+ hr =
audio_capture_client_->GetBuffer(&data_ptr, &num_frames_to_read, &flags,
&device_position, &capture_time_100ns);
- if (hr == AUDCLNT_S_BUFFER_EMPTY)
- break;
-
- // TODO(grunell): Should we handle different errors explicitly? Perhaps exit
- // by setting |error = true|. What are the assumptions here that makes us
- // rely on the next WaitForMultipleObjects? Do we expect the next wait to be
- // successful sometimes?
+ if (hr == AUDCLNT_S_BUFFER_EMPTY) {
+ DCHECK_EQ(num_frames_to_read, 0u);
+ return;
+ }
+ if (hr == AUDCLNT_E_OUT_OF_ORDER) {
+ // A previous IAudioCaptureClient::GetBuffer() call is still in effect.
+ // Release any acquired buffer to be able to try reading a buffer again.
+ audio_capture_client_->ReleaseBuffer(num_frames_to_read);
+ }
if (FAILED(hr)) {
LOG(ERROR) << "WAIS::" << __func__
<< " => (ERROR: IAudioCaptureClient::GetBuffer=["
<< ErrorToString(hr).c_str() << "])";
- break;
+ return;
+ }
+
+ // The data in the packet is not correlated with the previous packet's
+ // device position; this is possibly due to a stream state transition or
+ // timing glitch. Note that, usage of this flag was added after the existing
+ // glitch detection in UpdateGlitchCount() and it will be used as a
+ // supplementary scheme initially.
+ // The behavior of the AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY flag is
+ // undefined on the application's first call to GetBuffer after Start and
+ // Windows 7 or later is required for support.
+ if (device_position > 0 && flags & AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY) {
+ LOG(WARNING) << "WAIS::" << __func__
+ << " => (WARNING: AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY)";
+ ++num_data_discontinuity_warnings_;
+ }
+
+ // The time at which the device's stream position was recorded is uncertain.
+ // Thus, the client might be unable to accurately set a time stamp for the
+ // current data packet.
+ bool timestamp_error_was_detected = false;
+ if (flags & AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR) {
+ // TODO(https://crbug.com/825744): it might be possible to improve error
+ // handling here and avoid using the counter in |capture_time_100ns|.
+ LOG(WARNING) << "WAIS::" << __func__
+ << " => (WARNING: AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR)";
+ if (num_timestamp_errors_ == 0) {
+ // Measure the time it took until the first timestamp error was found.
+ time_until_first_timestamp_error_ =
+ base::TimeTicks::Now() - record_start_time_;
+ }
+ ++num_timestamp_errors_;
+ timestamp_error_was_detected = true;
}
// If the device position has changed, we assume this data belongs to a new
@@ -802,41 +886,46 @@ void WASAPIAudioInputStream::PullCaptureDataAndPushToSink() {
expected_next_device_position_ += num_frames_to_read;
}
- // TODO(dalecurtis, olka, grunell): Is this ever false? If it is, should we
- // handle |flags & AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR|?
- if (audio_clock_) {
- // The reported timestamp from GetBuffer is not as reliable as the clock
- // from the client. We've seen timestamps reported for USB audio devices,
- // be off by several days. Furthermore we've seen them jump back in time
- // every 2 seconds or so.
- // TODO(grunell): Using the audio clock as capture time for the currently
- // processed buffer seems incorrect. http://crbug.com/825744.
- audio_clock_->GetPosition(&device_position, &capture_time_100ns);
- }
-
base::TimeTicks capture_time;
- if (capture_time_100ns) {
- // See conversion notes on |capture_time_100ns|.
+ if (!timestamp_error_was_detected) {
+ // Use the latest |capture_time_100ns| since it is marked as valid.
capture_time +=
base::TimeDelta::FromMicroseconds(capture_time_100ns / 10.0);
- } else {
- // We may not have an IAudioClock or GetPosition() may return zero.
- capture_time = base::TimeTicks::Now();
+ }
+ if (capture_time <= last_capture_time_) {
+ // Latest |capture_time_100ns| can't be trusted. Ensure a monotonic time-
+ // stamp sequence by adding one microsecond to the latest timestamp.
+ capture_time = last_capture_time_ + base::TimeDelta::FromMicroseconds(1);
+ }
+
+ // Keep track of max and min time difference between two successive time-
+ // stamps. Results are used in Stop() to verify that the time-stamp sequence
+ // was monotonic.
+ if (!last_capture_time_.is_null()) {
+ const auto delta_ts = capture_time - last_capture_time_;
+ DCHECK_GT(device_position, 0u);
+ DCHECK_GT(delta_ts, base::TimeDelta::Min());
+ if (delta_ts > max_timestamp_diff_) {
+ max_timestamp_diff_ = delta_ts;
+ } else if (delta_ts < min_timestamp_diff_) {
+ min_timestamp_diff_ = delta_ts;
+ }
}
+ // Store the capture timestamp. Might be used as reference next time if
+ // a new valid timestamp can't be retrieved to always guarantee a monotonic
+ // sequence.
+ last_capture_time_ = capture_time;
+
// Adjust |capture_time| for the FIFO before pushing.
capture_time -= AudioTimestampHelper::FramesToTime(
fifo_->GetAvailableFrames(), input_format_.Format.nSamplesPerSec);
- // TODO(grunell): Since we check |hr == AUDCLNT_S_BUFFER_EMPTY| above,
- // should we instead assert that |num_frames_to_read != 0|?
- if (num_frames_to_read != 0) {
- if (flags & AUDCLNT_BUFFERFLAGS_SILENT) {
- fifo_->PushSilence(num_frames_to_read);
- } else {
- fifo_->Push(data_ptr, num_frames_to_read,
- input_format_.Format.wBitsPerSample / 8);
- }
+ if (flags & AUDCLNT_BUFFERFLAGS_SILENT) {
+ fifo_->PushSilence(num_frames_to_read);
+ } else {
+ fifo_->Push(data_ptr, num_frames_to_read,
+ input_format_.Format.wBitsPerSample / 8);
}
hr = audio_capture_client_->ReleaseBuffer(num_frames_to_read);
@@ -844,7 +933,7 @@ void WASAPIAudioInputStream::PullCaptureDataAndPushToSink() {
LOG(ERROR) << "WAIS::" << __func__
<< " => (ERROR: IAudioCaptureClient::ReleaseBuffer=["
<< ErrorToString(hr).c_str() << "])";
- break;
+ return;
}
// Get a cached AGC volume level which is updated once every second on the
@@ -862,7 +951,7 @@ void WASAPIAudioInputStream::PullCaptureDataAndPushToSink() {
// Special case. We need to buffer up more audio before we can convert
// or else we'll suffer an underrun.
// TODO(grunell): Verify this is really true.
- break;
+ return;
}
converter_->Convert(convert_bus_.get());
sink_->OnData(convert_bus_.get(), capture_time, volume);
@@ -878,7 +967,17 @@ void WASAPIAudioInputStream::PullCaptureDataAndPushToSink() {
packet_size_frames_, input_format_.Format.nSamplesPerSec);
}
}
- } // while (true)
+
+ // Get the number of frames in the next data packet in the capture endpoint
+ // buffer. Keep reading if more samples exist.
+ hr = audio_capture_client_->GetNextPacketSize(&num_frames_in_next_packet);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "WAIS::" << __func__
+ << " => (ERROR: 2-IAudioCaptureClient::GetNextPacketSize=["
+ << ErrorToString(hr).c_str() << "])";
+ return;
+ }
+ } // while (num_frames_in_next_packet > 0)
}
void WASAPIAudioInputStream::HandleError(HRESULT err) {
@@ -926,15 +1025,15 @@ HRESULT WASAPIAudioInputStream::SetCaptureDevice() {
return hr;
}
- // If loopback device with muted system audio is requested, get the volume
- // interface for the endpoint.
- if (device_id_ == AudioDeviceDescription::kLoopbackWithMuteDeviceId) {
- hr = endpoint_device_->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL,
- nullptr, &system_audio_volume_);
- if (FAILED(hr)) {
- open_result_ = OPEN_RESULT_ACTIVATION_FAILED;
- return hr;
- }
+ // Get the volume interface for the endpoint. Used in `Stop()` to query the
+ // volume range of the selected input device or to get/set mute state in
+ // `Start()` and `Stop()` if a loopback device with muted system audio is
+ // requested.
+ hr = endpoint_device_->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL,
+ nullptr, &system_audio_volume_);
+ if (FAILED(hr)) {
+ open_result_ = OPEN_RESULT_ACTIVATION_FAILED;
+ return hr;
}
// Verify that the audio endpoint device is active, i.e., the audio
@@ -1301,7 +1400,7 @@ void WASAPIAudioInputStream::SetupConverterAndStoreFormatInfo() {
output_layout, output_format_.nSamplesPerSec,
packet_size_frames_);
- converter_.reset(new AudioConverter(input, output, false));
+ converter_ = std::make_unique<AudioConverter>(input, output, false);
converter_->AddInput(this);
converter_->PrimeWithSilence();
convert_bus_ = AudioBus::Create(output);
@@ -1463,14 +1562,6 @@ HRESULT WASAPIAudioInputStream::InitializeAudioEngine() {
if (FAILED(hr))
open_result_ = OPEN_RESULT_NO_AUDIO_VOLUME;
- audio_client_->GetService(IID_PPV_ARGS(&audio_clock_));
- if (!audio_clock_) {
- SendLogMessage(
- "%s => (WARNING: IAudioClock unavailable, capture times will be "
- "inaccurate)",
- __func__);
- }
-
return hr;
}
@@ -1542,10 +1633,31 @@ void WASAPIAudioInputStream::ReportAndResetGlitchStats() {
50);
}
+ // TODO(https://crbug.com/825744): It can be possible to replace
+ // "Media.Audio.Capture.Glitches" with this new (simplified) metric instead.
+ base::UmaHistogramCounts1M("Media.Audio.Capture.Win.Glitches",
+ num_data_discontinuity_warnings_);
+ SendLogMessage("%s => (discontinuity warnings=[%" PRIu64 "])", __func__,
+ num_data_discontinuity_warnings_);
+ base::UmaHistogramCounts1M("Media.Audio.Capture.Win.TimestampErrors",
+ num_timestamp_errors_);
+ SendLogMessage("%s => (timstamp errors=[%" PRIu64 "])", __func__,
+ num_timestamp_errors_);
+ if (num_timestamp_errors_ > 0) {
+ base::UmaHistogramLongTimes(
+ "Media.Audio.Capture.Win.TimeUntilFirstTimestampError",
+ time_until_first_timestamp_error_);
+ SendLogMessage("%s => (time until first timestamp error=[%" PRId64 " ms])",
+ __func__,
+ time_until_first_timestamp_error_.InMilliseconds());
+ }
+
expected_next_device_position_ = 0;
total_glitches_ = 0;
total_lost_frames_ = 0;
largest_glitch_frames_ = 0;
+ num_data_discontinuity_warnings_ = 0;
+ num_timestamp_errors_ = 0;
}
} // namespace media
diff --git a/chromium/media/audio/win/audio_low_latency_input_win.h b/chromium/media/audio/win/audio_low_latency_input_win.h
index f3e45d6343a..91b8fb19d3a 100644
--- a/chromium/media/audio/win/audio_low_latency_input_win.h
+++ b/chromium/media/audio/win/audio_low_latency_input_win.h
@@ -130,7 +130,7 @@ class MEDIA_EXPORT WASAPIAudioInputStream
~WASAPIAudioInputStream() override;
// Implementation of AudioInputStream.
- bool Open() override;
+ AudioInputStream::OpenOutcome Open() override;
void Start(AudioInputCallback* callback) override;
void Stop() override;
void Close() override;
@@ -266,11 +266,6 @@ class MEDIA_EXPORT WASAPIAudioInputStream
// from a capture endpoint buffer.
Microsoft::WRL::ComPtr<IAudioCaptureClient> audio_capture_client_;
- // The IAudioClock interface is used to get the current timestamp, as the
- // timestamp from IAudioCaptureClient::GetBuffer can be unreliable with some
- // devices.
- Microsoft::WRL::ComPtr<IAudioClock> audio_clock_;
-
// The ISimpleAudioVolume interface enables a client to control the
// master volume level of an audio session.
// The volume-level is a value in the range 0.0 to 1.0.
@@ -312,6 +307,21 @@ class MEDIA_EXPORT WASAPIAudioInputStream
UINT64 total_lost_frames_ = 0;
UINT64 largest_glitch_frames_ = 0;
+ // Tracks error messages from IAudioCaptureClient::GetBuffer.
+ UINT64 num_data_discontinuity_warnings_ = 0;
+ UINT64 num_timestamp_errors_ = 0;
+ base::TimeTicks record_start_time_;
+ base::TimeDelta time_until_first_timestamp_error_;
+
+ // Contains the last capture timestamp from IAudioCaptureClient::GetBuffer.
+ base::TimeTicks last_capture_time_;
+
+ // Max and min of difference in time between two successive timestamps.
+ // |min_timestamp_diff_| should always be larger than or equal to one micro-
+ // second.
+ base::TimeDelta max_timestamp_diff_;
+ base::TimeDelta min_timestamp_diff_;
+
// Enabled if the volume level of the audio session is set to zero when the
// session starts. Utilized in UMA histogram.
bool audio_session_starts_at_zero_volume_ = false;
diff --git a/chromium/media/audio/win/audio_low_latency_input_win_unittest.cc b/chromium/media/audio/win/audio_low_latency_input_win_unittest.cc
index 2eed0cc87ea..a2cdbc2f2a1 100644
--- a/chromium/media/audio/win/audio_low_latency_input_win_unittest.cc
+++ b/chromium/media/audio/win/audio_low_latency_input_win_unittest.cc
@@ -19,6 +19,7 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/test/test_timeouts.h"
@@ -347,7 +348,7 @@ TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) {
ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
ScopedAudioInputStream ais(
CreateDefaultAudioInputStream(audio_manager_.get()));
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
ais.Close();
}
@@ -366,7 +367,7 @@ TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenAndCloseForAllDevices) {
AudioInputStreamWrapper aisw(audio_manager_.get(), device.unique_id);
{
ScopedAudioInputStream ais(aisw.Create());
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
}
}
}
@@ -376,7 +377,7 @@ TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) {
ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
ScopedAudioInputStream ais(
CreateDefaultAudioInputStream(audio_manager_.get()));
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
MockAudioInputCallback sink;
ais->Start(&sink);
ais.Close();
@@ -393,13 +394,34 @@ TEST_P(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) {
ScopedAudioInputStream ais(
CreateDefaultAudioInputStream(audio_manager_.get()));
EXPECT_TRUE(ais->SetAutomaticGainControl(true));
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
MockAudioInputCallback sink;
ais->Start(&sink);
ais->Stop();
ais.Close();
}
+// Verify that histograms are created as expected. Only covers the latest
+// histograms.
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamHistograms) {
+ ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
+ base::HistogramTester histogram_tester;
+ ScopedAudioInputStream ais(
+ CreateDefaultAudioInputStream(audio_manager_.get()));
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
+ FakeAudioInputCallback sink;
+ ais->Start(&sink);
+ sink.WaitForData();
+ sink.WaitForData();
+ ais->Stop();
+ ais.Close();
+ histogram_tester.ExpectTotalCount("Media.Audio.Capture.Win.Glitches", 1);
+ histogram_tester.ExpectTotalCount("Media.Audio.Capture.Win.TimestampErrors",
+ 1);
+ histogram_tester.ExpectTotalCount(
+ "Media.Audio.Capture.Win.TimeUntilFirstTimestampError", 0);
+}
+
// Test some additional calling sequences.
TEST_F(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) {
ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
@@ -407,8 +429,8 @@ TEST_F(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) {
CreateDefaultAudioInputStream(audio_manager_.get()));
// Open(), Open() should fail the second time.
- EXPECT_TRUE(ais->Open());
- EXPECT_FALSE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kAlreadyOpen);
FakeAudioInputCallback sink;
@@ -437,7 +459,7 @@ TEST_F(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) {
// the shared mixing rate. The default buffer size is 10ms.
AudioInputStreamWrapper aisw(audio_manager_.get());
ScopedAudioInputStream ais(aisw.Create());
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
MockAudioInputCallback sink;
@@ -469,7 +491,7 @@ TEST_F(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) {
count = 0;
ais.Reset(aisw.Create(2 * frames_per_buffer_10ms));
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() *
SampleFormatToBytesPerChannel(kSampleFormat);
@@ -490,7 +512,7 @@ TEST_F(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) {
count = 0;
ais.Reset(aisw.Create(frames_per_buffer_10ms / 2));
- EXPECT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() *
SampleFormatToBytesPerChannel(kSampleFormat);
@@ -525,7 +547,7 @@ TEST_F(WinAudioInputTest, WASAPIAudioInputStreamLoopback) {
ScopedAudioInputStream stream(audio_manager_->MakeAudioInputStream(
params, AudioDeviceDescription::kLoopbackInputDeviceId,
base::BindRepeating(&LogCallbackDummy)));
- ASSERT_TRUE(stream->Open());
+ EXPECT_EQ(stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
FakeAudioInputCallback sink;
stream->Start(&sink);
ASSERT_FALSE(sink.error());
@@ -553,7 +575,7 @@ TEST_F(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) {
AudioInputStreamWrapper aisw(audio_manager_.get());
ScopedAudioInputStream ais(aisw.Create());
- ASSERT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
VLOG(0) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]";
WriteToFileAudioSink file_sink(file_name);
@@ -580,7 +602,7 @@ TEST_F(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFileRAW) {
AudioInputStreamWrapper aisw(audio_manager_.get());
ScopedAudioInputStream ais(aisw.Create());
- ASSERT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
VLOG(0) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]";
WriteToFileAudioSink file_sink(file_name);
@@ -634,7 +656,7 @@ TEST_F(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamResampleToFile) {
AudioInputStreamWrapper aisw(audio_manager_.get(), params);
ScopedAudioInputStream ais(aisw.Create());
- ASSERT_TRUE(ais->Open());
+ EXPECT_EQ(ais->Open(), AudioInputStream::OpenOutcome::kSuccess);
VLOG(0) << ">> Resampled rate will be: " << aisw.sample_rate() << " [Hz]";
VLOG(0) << ">> New layout will be: "
diff --git a/chromium/media/audio/win/audio_low_latency_output_win.cc b/chromium/media/audio/win/audio_low_latency_output_win.cc
index 5282739bb6c..1f7e1ec9461 100644
--- a/chromium/media/audio/win/audio_low_latency_output_win.cc
+++ b/chromium/media/audio/win/audio_low_latency_output_win.cc
@@ -10,11 +10,13 @@
#include <objbase.h>
#include <climits>
+#include <memory>
#include "base/callback.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
@@ -32,13 +34,23 @@
#include "media/base/limits.h"
#include "media/base/media_switches.h"
-using base::win::ScopedCOMInitializer;
using base::win::ScopedCoMem;
+using base::win::ScopedCOMInitializer;
namespace media {
namespace {
+constexpr char kOpenFailureHistogram[] = "Media.Audio.Output.Win.OpenError";
+constexpr char kStartFailureHistogram[] = "Media.Audio.Output.Win.StartError";
+constexpr char kStopFailureHistogram[] = "Media.Audio.Output.Win.StopError";
+constexpr char kRunFailureHistogram[] = "Media.Audio.Output.Win.RunError";
+constexpr char kRenderFailureHistogram[] = "Media.Audio.Output.Win.RenderError";
+
+void RecordAudioFailure(const char* histogram, HRESULT hr) {
+ base::UmaHistogramSparse(histogram, hr);
+}
+
// Converts a COM error into a human-readable string.
std::string ErrorToString(HRESULT hresult) {
return CoreAudioUtil::ErrorToString(hresult);
@@ -180,6 +192,7 @@ bool WASAPIAudioOutputStream::Open() {
Microsoft::WRL::ComPtr<IAudioClient> audio_client(
CoreAudioUtil::CreateClient(device_id_, eRender, device_role_));
if (!audio_client.Get()) {
+ RecordAudioFailure(kOpenFailureHistogram, GetLastError());
SendLogMessage("%s => (ERROR: CAU::CreateClient failed)", __func__);
return false;
}
@@ -187,6 +200,7 @@ bool WASAPIAudioOutputStream::Open() {
// Extra sanity to ensure that the provided device format is still valid.
if (!CoreAudioUtil::IsFormatSupported(audio_client.Get(), share_mode_,
&format_)) {
+ RecordAudioFailure(kOpenFailureHistogram, GetLastError());
SendLogMessage("%s => (ERROR: CAU::IsFormatSupported failed)", __func__);
return false;
}
@@ -200,6 +214,7 @@ bool WASAPIAudioOutputStream::Open() {
requested_iaudioclient3_buffer_size_, &endpoint_buffer_size_frames_,
communications_device ? &kCommunicationsSessionId : nullptr);
if (FAILED(hr)) {
+ RecordAudioFailure(kOpenFailureHistogram, hr);
SendLogMessage("%s => (ERROR: IAudioClient::SharedModeInitialize=[%s])",
__func__, ErrorToString(hr).c_str());
return false;
@@ -208,6 +223,7 @@ bool WASAPIAudioOutputStream::Open() {
REFERENCE_TIME device_period = 0;
if (FAILED(CoreAudioUtil::GetDevicePeriod(
audio_client.Get(), AUDCLNT_SHAREMODE_SHARED, &device_period))) {
+ RecordAudioFailure(kOpenFailureHistogram, GetLastError());
return false;
}
@@ -270,6 +286,7 @@ bool WASAPIAudioOutputStream::Open() {
Microsoft::WRL::ComPtr<IAudioRenderClient> audio_render_client =
CoreAudioUtil::CreateRenderClient(audio_client.Get());
if (!audio_render_client.Get()) {
+ RecordAudioFailure(kOpenFailureHistogram, GetLastError());
SendLogMessage("%s => (ERROR: CAU::CreateRenderClient failed)", __func__);
return false;
}
@@ -280,6 +297,7 @@ bool WASAPIAudioOutputStream::Open() {
hr = audio_client_->GetService(IID_PPV_ARGS(&audio_clock_));
if (FAILED(hr)) {
+ RecordAudioFailure(kOpenFailureHistogram, hr);
SendLogMessage("%s => (ERROR: IAudioClient::GetService(IAudioClock)=[%s])",
__func__, ErrorToString(hr).c_str());
return false;
@@ -336,6 +354,7 @@ void WASAPIAudioOutputStream::Start(AudioSourceCallback* callback) {
audio_render_client_.Reset();
if (!Open() || !CoreAudioUtil::FillRenderEndpointBufferWithSilence(
audio_client_.Get(), audio_render_client_.Get())) {
+ RecordAudioFailure(kStartFailureHistogram, GetLastError());
SendLogMessage("%s => (ERROR: Recovery attempt failed)", __func__);
callback->OnError(AudioSourceCallback::ErrorType::kUnknown);
return;
@@ -350,11 +369,12 @@ void WASAPIAudioOutputStream::Start(AudioSourceCallback* callback) {
// Create and start the thread that will drive the rendering by waiting for
// render events.
- render_thread_.reset(new base::DelegateSimpleThread(
+ render_thread_ = std::make_unique<base::DelegateSimpleThread>(
this, "wasapi_render_thread",
- base::SimpleThread::Options(base::ThreadPriority::REALTIME_AUDIO)));
+ base::SimpleThread::Options(base::ThreadPriority::REALTIME_AUDIO));
render_thread_->Start();
if (!render_thread_->HasBeenStarted()) {
+ RecordAudioFailure(kStartFailureHistogram, GetLastError());
SendLogMessage("%s => (ERROR: Failed to start \"wasapi_render_thread\")",
__func__);
StopThread();
@@ -365,6 +385,7 @@ void WASAPIAudioOutputStream::Start(AudioSourceCallback* callback) {
// Start streaming data between the endpoint buffer and the audio engine.
HRESULT hr = audio_client_->Start();
if (FAILED(hr)) {
+ RecordAudioFailure(kStartFailureHistogram, hr);
SendLogMessage("%s => (ERROR: IAudioClient::Start=[%s])", __func__,
ErrorToString(hr).c_str());
StopThread();
@@ -384,6 +405,7 @@ void WASAPIAudioOutputStream::Stop() {
// Stop output audio streaming.
HRESULT hr = audio_client_->Stop();
if (FAILED(hr)) {
+ RecordAudioFailure(kStopFailureHistogram, hr);
SendLogMessage("%s => (ERROR: IAudioClient::Stop=[%s])", __func__,
ErrorToString(hr).c_str());
source_->OnError(AudioSourceCallback::ErrorType::kUnknown);
@@ -396,6 +418,7 @@ void WASAPIAudioOutputStream::Stop() {
// Flush all pending data and reset the audio clock stream position to 0.
hr = audio_client_->Reset();
if (FAILED(hr)) {
+ RecordAudioFailure(kStopFailureHistogram, hr);
SendLogMessage("%s => (ERROR: IAudioClient::Reset=[%s])", __func__,
ErrorToString(hr).c_str());
callback->OnError(AudioSourceCallback::ErrorType::kUnknown);
@@ -494,6 +517,7 @@ void WASAPIAudioOutputStream::Run() {
hr = audio_clock_->GetFrequency(&device_frequency);
error = FAILED(hr);
if (error) {
+ RecordAudioFailure(kRunFailureHistogram, hr);
LOG(ERROR) << "WAOS::" << __func__
<< " => (ERROR: IAudioClock::GetFrequency=["
<< ErrorToString(hr).c_str() << "])";
@@ -522,6 +546,7 @@ void WASAPIAudioOutputStream::Run() {
}
if (playing && error) {
+ RecordAudioFailure(kRunFailureHistogram, GetLastError());
LOG(ERROR) << "WAOS::" << __func__
<< " => (ERROR: WASAPI rendering failed)";
@@ -561,6 +586,7 @@ bool WASAPIAudioOutputStream::RenderAudioFromSource(UINT64 device_frequency) {
num_available_frames =
endpoint_buffer_size_frames_ - num_queued_frames;
if (FAILED(hr)) {
+ RecordAudioFailure(kRenderFailureHistogram, hr);
LOG(ERROR) << "WAOS::" << __func__
<< " => (ERROR: IAudioClient::GetCurrentPadding=["
<< ErrorToString(hr).c_str() << "])";
@@ -606,6 +632,7 @@ bool WASAPIAudioOutputStream::RenderAudioFromSource(UINT64 device_frequency) {
hr = audio_render_client_->GetBuffer(packet_size_frames_,
&audio_data);
if (FAILED(hr)) {
+ RecordAudioFailure(kRenderFailureHistogram, hr);
LOG(ERROR) << "WAOS::" << __func__
<< " => (ERROR: IAudioRenderClient::GetBuffer=["
<< ErrorToString(hr).c_str() << "])";
@@ -677,6 +704,7 @@ bool WASAPIAudioOutputStream::RenderAudioFromSource(UINT64 device_frequency) {
// by 10.0 since 10x100ns = 1us.
delay_timestamp += base::TimeDelta::FromMicroseconds(qpc_position * 0.1);
} else {
+ RecordAudioFailure(kRenderFailureHistogram, hr);
LOG(ERROR) << "WAOS::" << __func__
<< " => (ERROR: IAudioClock::GetPosition=["
<< ErrorToString(hr).c_str() << "])";
diff --git a/chromium/media/audio/win/volume_range_util.cc b/chromium/media/audio/win/volume_range_util.cc
new file mode 100644
index 00000000000..086660309c9
--- /dev/null
+++ b/chromium/media/audio/win/volume_range_util.cc
@@ -0,0 +1,64 @@
+// Copyright (c) 2021 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 "media/audio/win/volume_range_util.h"
+
+#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
+
+namespace media {
+namespace {
+
+constexpr int CountVolumeRangeIntervals(VolumeRange range) {
+ DCHECK_LT(range.min_volume_db, range.max_volume_db);
+ DCHECK_GT(range.volume_step_db, 0.0f);
+ return (range.max_volume_db - range.min_volume_db) / range.volume_step_db;
+}
+
+} // namespace
+
+void LogVolumeRangeUmaHistograms(absl::optional<VolumeRange> range) {
+ base::UmaHistogramBoolean("Media.Audio.Capture.Win.VolumeRangeAvailable",
+ range.has_value());
+ if (!range.has_value()) {
+ return;
+ }
+ // Count the number of steps before the range is modified.
+ constexpr int kMaxVolumeSteps = 2000;
+ const int num_steps =
+ std::min(CountVolumeRangeIntervals(*range), kMaxVolumeSteps);
+ // Approximate `range` to an integer interval since UMA histograms do not log
+ // floating point values.
+ range->min_volume_db = std::floor(range->min_volume_db);
+ range->max_volume_db = std::ceil(range->max_volume_db);
+ // `range` is expected to be fully included in [`kMinDb`, `kMaxDb`].
+ constexpr int kMinDb = -60;
+ constexpr int kMaxDb = 60;
+ static_assert(kMinDb < kMaxDb, "");
+ // UMA histograms only accept non-negative values; however, a volume range is
+ // expected to include negative values (if `kMinDb` is negative). Therefore,
+ // `max(0, -kMinDb)` is added as offset.
+ constexpr int kVolumeOffsetDb = kMinDb < 0 ? -kMinDb : 0;
+ range->min_volume_db += kVolumeOffsetDb;
+ range->max_volume_db += kVolumeOffsetDb;
+ // Log the modified volume range.
+ constexpr int kExclusiveMaxVolumeDb = kMaxDb + kVolumeOffsetDb + 1;
+ DCHECK_LE(range->min_volume_db, range->max_volume_db);
+ base::UmaHistogramExactLinear("Media.Audio.Capture.Win.VolumeRangeMin2",
+ static_cast<int>(range->min_volume_db),
+ kExclusiveMaxVolumeDb);
+ DCHECK_GE(range->max_volume_db, 0);
+ base::UmaHistogramExactLinear("Media.Audio.Capture.Win.VolumeRangeMax2",
+ static_cast<int>(range->max_volume_db),
+ kExclusiveMaxVolumeDb);
+ // Log the number of volume range steps.
+ DCHECK_GT(num_steps, 0);
+ constexpr int kStepsNumBuckets = 100;
+ base::UmaHistogramCustomCounts("Media.Audio.Capture.Win.VolumeRangeNumSteps",
+ /*sample=*/num_steps,
+ /*min=*/1, /*max=*/kMaxVolumeSteps,
+ kStepsNumBuckets);
+}
+
+} // namespace media
diff --git a/chromium/media/audio/win/volume_range_util.h b/chromium/media/audio/win/volume_range_util.h
new file mode 100644
index 00000000000..29d0d62c1fa
--- /dev/null
+++ b/chromium/media/audio/win/volume_range_util.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2021 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.
+//
+// Volume range definition and UMA logging utilities for
+// `IAudioEndpointVolume::GetVolumeRange()`.
+//
+// Implementation notes:
+// - The minimum supported client is Windows Vista.
+
+#ifndef MEDIA_AUDIO_WIN_VOLUME_RANGE_UTIL_H_
+#define MEDIA_AUDIO_WIN_VOLUME_RANGE_UTIL_H_
+
+#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace media {
+
+// Microphone volume range in decibels.
+struct VolumeRange {
+ float min_volume_db; // Range minimum.
+ float max_volume_db; // Range maximum.
+ // The range above is divided into N uniform intervals of size
+ // `volume_step_db`.
+ float volume_step_db;
+};
+
+// Logs `Media.Audio.Capture.Win.VolumeRange*` UMA histograms.
+// `Media.Audio.Capture.Win.VolumeRangeAvailable` is always logged; the logged
+// value reflects whether `range` is specified. When specified, the volume range
+// and the number of steps are also logged as follows. `range.min_volume_db` and
+// `range.max_volume_db` are logged as `Media.Audio.Capture.Win.VolumeRangeMin2`
+// and `Media.Audio.Capture.Win.VolumeRangeMax2` respectively by casting the
+// original values to an integer, by clamping in the [-60, 60] range, and by
+// adding a 60 dB offset in order to log positive values - required by the UMA
+// histograms framework. The value for
+// `Media.Audio.Capture.Win.VolumeRangeNumSteps` is computed as
+// (`range.max_volume_db` - `range.min_volume_db` / `volume_step_db`) and it is
+// clamped to 2000.
+MEDIA_EXPORT void LogVolumeRangeUmaHistograms(
+ absl::optional<VolumeRange> range);
+
+} // namespace media
+
+#endif // MEDIA_AUDIO_WIN_VOLUME_RANGE_UTIL_H_
diff --git a/chromium/media/audio/win/volume_range_util_unittest.cc b/chromium/media/audio/win/volume_range_util_unittest.cc
new file mode 100644
index 00000000000..cc3098eb69f
--- /dev/null
+++ b/chromium/media/audio/win/volume_range_util_unittest.cc
@@ -0,0 +1,103 @@
+// Copyright (c) 2021 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 "media/audio/win/volume_range_util.h"
+
+#include "base/test/metrics/histogram_tester.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace media {
+namespace {
+
+using base::Bucket;
+using testing::ElementsAre;
+
+constexpr int kClampedMaxVolumeDb = 60;
+constexpr int kVolumeOffsetDb = 60;
+constexpr int kMaxNumSteps = 2000;
+
+constexpr VolumeRange kValidVolumeRange{.min_volume_db = -17.0f,
+ .max_volume_db = 20.0f,
+ .volume_step_db = 0.03125f};
+
+constexpr int ComputeNumSteps(VolumeRange range) {
+ return (range.max_volume_db - range.min_volume_db) / range.volume_step_db;
+}
+
+TEST(VolumeRangeUtilWin, LogUnavailableVolumeRange) {
+ base::HistogramTester tester;
+ LogVolumeRangeUmaHistograms(/*range=*/absl::nullopt);
+ EXPECT_THAT(
+ tester.GetAllSamples("Media.Audio.Capture.Win.VolumeRangeAvailable"),
+ ElementsAre(Bucket(false, 1)));
+}
+
+TEST(VolumeRangeUtilWin, LogAvailableVolumeRange) {
+ base::HistogramTester tester;
+ LogVolumeRangeUmaHistograms(kValidVolumeRange);
+ EXPECT_THAT(
+ tester.GetAllSamples("Media.Audio.Capture.Win.VolumeRangeAvailable"),
+ ElementsAre(Bucket(true, 1)));
+}
+
+TEST(VolumeRangeUtilWin, VolumeRangeMinMaxOffsetAdded) {
+ base::HistogramTester tester;
+ LogVolumeRangeUmaHistograms(kValidVolumeRange);
+ tester.ExpectUniqueSample(
+ "Media.Audio.Capture.Win.VolumeRangeMin2",
+ static_cast<int>(kValidVolumeRange.min_volume_db + kVolumeOffsetDb), 1);
+ tester.ExpectUniqueSample(
+ "Media.Audio.Capture.Win.VolumeRangeMax2",
+ static_cast<int>(kValidVolumeRange.max_volume_db + kVolumeOffsetDb), 1);
+}
+
+TEST(VolumeRangeUtilWin, VolumeRangeMinMaxRoundedOff) {
+ base::HistogramTester tester;
+ constexpr VolumeRange kVolumeRange{.min_volume_db = -1.123f,
+ .max_volume_db = 1.123f,
+ .volume_step_db = 2.246};
+ LogVolumeRangeUmaHistograms(kVolumeRange);
+ tester.ExpectUniqueSample("Media.Audio.Capture.Win.VolumeRangeMin2",
+ -2 + kVolumeOffsetDb, 1);
+ tester.ExpectUniqueSample("Media.Audio.Capture.Win.VolumeRangeMax2",
+ 2 + kVolumeOffsetDb, 1);
+}
+
+// Checks that volume values outside of the expected range fall into the first
+// and the last (a.k.a., overflow) buckets respectively.
+TEST(VolumeRangeUtilWin, VolumeRangeMinMaxClamped) {
+ base::HistogramTester tester;
+ constexpr VolumeRange kVolumeRange{.min_volume_db = -10000.0f,
+ .max_volume_db = 10000.0f,
+ .volume_step_db = 1.0f};
+ LogVolumeRangeUmaHistograms(kVolumeRange);
+ tester.ExpectUniqueSample("Media.Audio.Capture.Win.VolumeRangeMin2", 0, 1);
+ constexpr int kOverflowBucket = kClampedMaxVolumeDb + kVolumeOffsetDb + 1;
+ tester.ExpectUniqueSample("Media.Audio.Capture.Win.VolumeRangeMax2",
+ kOverflowBucket, 1);
+}
+
+TEST(VolumeRangeUtilWin, VolumeRangeNumSteps) {
+ base::HistogramTester tester;
+ LogVolumeRangeUmaHistograms(kValidVolumeRange);
+ tester.ExpectUniqueSample("Media.Audio.Capture.Win.VolumeRangeNumSteps",
+ ComputeNumSteps(kValidVolumeRange), 1);
+}
+
+TEST(VolumeRangeUtilWin, VolumeRangeNumStepsClamped) {
+ base::HistogramTester tester;
+ constexpr VolumeRange kVolumeRange{.min_volume_db = -17.0f,
+ .max_volume_db = 20.0f,
+ .volume_step_db = 0.00925f};
+ LogVolumeRangeUmaHistograms(kVolumeRange);
+ constexpr int kNumSteps = ComputeNumSteps(kVolumeRange);
+ static_assert(kNumSteps > kMaxNumSteps, "");
+ tester.ExpectUniqueSample("Media.Audio.Capture.Win.VolumeRangeNumSteps",
+ kMaxNumSteps, 1);
+}
+
+} // namespace
+} // namespace media
diff --git a/chromium/media/base/BUILD.gn b/chromium/media/base/BUILD.gn
index 54e6842abd4..eb2295b777f 100644
--- a/chromium/media/base/BUILD.gn
+++ b/chromium/media/base/BUILD.gn
@@ -374,6 +374,7 @@ source_set("base") {
"//ui/display:display",
"//ui/events:events",
"//ui/events:events_base",
+ "//ui/events:keyboard_hook",
"//url:url",
]
@@ -394,6 +395,10 @@ source_set("base") {
]
}
+ if (is_chromeos_ash) {
+ deps += [ "//ash/constants" ]
+ }
+
if (media_use_libvpx) {
deps += [ "//third_party/libvpx" ]
}
diff --git a/chromium/media/base/DEPS b/chromium/media/base/DEPS
new file mode 100644
index 00000000000..f51400454f2
--- /dev/null
+++ b/chromium/media/base/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+ash/constants",
+]
diff --git a/chromium/media/base/android/media_codec_bridge.h b/chromium/media/base/android/media_codec_bridge.h
index f9cb49f9cfe..4858127716e 100644
--- a/chromium/media/base/android/media_codec_bridge.h
+++ b/chromium/media/base/android/media_codec_bridge.h
@@ -14,11 +14,11 @@
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "base/time/time.h"
#include "media/base/encryption_pattern.h"
#include "media/base/encryption_scheme.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
@@ -95,7 +95,7 @@ class MEDIA_EXPORT MediaCodecBridge {
const std::string& iv,
const std::vector<SubsampleEntry>& subsamples,
EncryptionScheme encryption_scheme,
- base::Optional<EncryptionPattern> encryption_pattern,
+ absl::optional<EncryptionPattern> encryption_pattern,
base::TimeDelta presentation_time) = 0;
// Submits an empty buffer with the END_OF_STREAM flag set.
diff --git a/chromium/media/base/android/media_codec_bridge_impl.cc b/chromium/media/base/android/media_codec_bridge_impl.cc
index 8bd73acadf1..68d6a8b0969 100644
--- a/chromium/media/base/android/media_codec_bridge_impl.cc
+++ b/chromium/media/base/android/media_codec_bridge_impl.cc
@@ -383,7 +383,7 @@ MediaCodecStatus MediaCodecBridgeImpl::QueueSecureInputBuffer(
const std::string& iv,
const std::vector<SubsampleEntry>& subsamples,
EncryptionScheme encryption_scheme,
- base::Optional<EncryptionPattern> encryption_pattern,
+ absl::optional<EncryptionPattern> encryption_pattern,
base::TimeDelta presentation_time) {
DVLOG(3) << __func__ << " " << index << ": " << data_size;
if (data_size >
diff --git a/chromium/media/base/android/media_codec_bridge_impl.h b/chromium/media/base/android/media_codec_bridge_impl.h
index 1d4ce6da9d8..a1375a8ae10 100644
--- a/chromium/media/base/android/media_codec_bridge_impl.h
+++ b/chromium/media/base/android/media_codec_bridge_impl.h
@@ -54,7 +54,7 @@ class MEDIA_EXPORT VideoCodecConfig {
// VP9 HDR metadata is only embedded in the container. HDR10 metadata is
// embedded in the video stream.
- base::Optional<gfx::HDRMetadata> hdr_metadata;
+ absl::optional<gfx::HDRMetadata> hdr_metadata;
// Enables the async MediaCodec.Callback API. |on_buffers_available_cb|
// will be called when input or output buffers are available. This will be
@@ -122,7 +122,7 @@ class MEDIA_EXPORT MediaCodecBridgeImpl : public MediaCodecBridge {
const std::string& iv,
const std::vector<SubsampleEntry>& subsamples,
EncryptionScheme encryption_scheme,
- base::Optional<EncryptionPattern> encryption_pattern,
+ absl::optional<EncryptionPattern> encryption_pattern,
base::TimeDelta presentation_time) override;
void QueueEOS(int input_buffer_index) override;
MediaCodecStatus DequeueInputBuffer(base::TimeDelta timeout,
diff --git a/chromium/media/base/android/media_codec_loop.h b/chromium/media/base/android/media_codec_loop.h
index 81651149a3c..a66c38cb265 100644
--- a/chromium/media/base/android/media_codec_loop.h
+++ b/chromium/media/base/android/media_codec_loop.h
@@ -124,7 +124,7 @@ class MEDIA_EXPORT MediaCodecLoop {
bool is_eos = false;
EncryptionScheme encryption_scheme = EncryptionScheme::kUnencrypted;
- base::Optional<EncryptionPattern> encryption_pattern;
+ absl::optional<EncryptionPattern> encryption_pattern;
};
// Handy enum for "no buffer".
diff --git a/chromium/media/base/android/media_codec_loop_unittest.cc b/chromium/media/base/android/media_codec_loop_unittest.cc
index b52a888f33e..f3ac9638026 100644
--- a/chromium/media/base/android/media_codec_loop_unittest.cc
+++ b/chromium/media/base/android/media_codec_loop_unittest.cc
@@ -92,8 +92,8 @@ class MediaCodecLoopTest : public testing::Test {
std::unique_ptr<MediaCodecBridge> codec(new MockMediaCodecBridge());
// Since we're providing a codec, we do not expect an error.
EXPECT_CALL(*client_, OnCodecLoopError()).Times(0);
- codec_loop_.reset(new MediaCodecLoop(sdk_int, client_.get(),
- std::move(codec), mock_task_runner_));
+ codec_loop_ = std::make_unique<MediaCodecLoop>(
+ sdk_int, client_.get(), std::move(codec), mock_task_runner_);
codec_loop_->SetTestTickClock(mock_task_runner_->GetMockTickClock());
Mock::VerifyAndClearExpectations(client_.get());
}
@@ -199,9 +199,9 @@ TEST_F(MediaCodecLoopTest, TestConstructionWithNullCodec) {
std::unique_ptr<MediaCodecBridge> codec;
EXPECT_CALL(*client_, OnCodecLoopError()).Times(1);
const int sdk_int = base::android::SDK_VERSION_LOLLIPOP;
- codec_loop_.reset(
- new MediaCodecLoop(sdk_int, client_.get(), std::move(codec),
- scoped_refptr<base::SingleThreadTaskRunner>()));
+ codec_loop_ = std::make_unique<MediaCodecLoop>(
+ sdk_int, client_.get(), std::move(codec),
+ scoped_refptr<base::SingleThreadTaskRunner>());
// Do not WaitUntilIdle() here, since that assumes that we have a codec.
ASSERT_FALSE(codec_loop_->GetCodec());
diff --git a/chromium/media/base/android/media_crypto_context_impl.h b/chromium/media/base/android/media_crypto_context_impl.h
index 435c96d953a..27e9eda77d6 100644
--- a/chromium/media/base/android/media_crypto_context_impl.h
+++ b/chromium/media/base/android/media_crypto_context_impl.h
@@ -7,8 +7,6 @@
#include <jni.h>
-#include <memory>
-
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
#include "media/base/android/media_crypto_context.h"
diff --git a/chromium/media/base/android/media_drm_bridge.cc b/chromium/media/base/android/media_drm_bridge.cc
index 182dc13ad28..69356037f75 100644
--- a/chromium/media/base/android/media_drm_bridge.cc
+++ b/chromium/media/base/android/media_drm_bridge.cc
@@ -265,22 +265,6 @@ std::string GetSecurityLevelString(
return "";
}
-bool AreMediaDrmApisAvailable() {
- if (base::android::BuildInfo::GetInstance()->sdk_int() <
- base::android::SDK_VERSION_KITKAT)
- return false;
-
- int32_t os_major_version = 0;
- int32_t os_minor_version = 0;
- int32_t os_bugfix_version = 0;
- base::SysInfo::OperatingSystemVersionNumbers(
- &os_major_version, &os_minor_version, &os_bugfix_version);
- if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0)
- return false;
-
- return true;
-}
-
int GetFirstApiLevel() {
JNIEnv* env = AttachCurrentThread();
int first_api_level = Java_MediaDrmBridge_getFirstApiLevel(env);
@@ -293,7 +277,7 @@ int GetFirstApiLevel() {
// APIs and MediaCodec APIs must be enabled and not blocked.
// static
bool MediaDrmBridge::IsAvailable() {
- return AreMediaDrmApisAvailable() && MediaCodecUtil::IsMediaCodecAvailable();
+ return MediaCodecUtil::IsMediaCodecAvailable();
}
// static
@@ -375,7 +359,6 @@ scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateInternal(
const SessionKeysChangeCB& session_keys_change_cb,
const SessionExpirationUpdateCB& session_expiration_update_cb) {
// All paths requires the MediaDrmApis.
- DCHECK(AreMediaDrmApisAvailable());
DCHECK(!scheme_uuid.empty());
// TODO(crbug.com/917527): Check that |origin_id| is specified on devices
@@ -400,10 +383,6 @@ scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport(
CreateFetcherCB create_fetcher_cb) {
DVLOG(1) << __func__;
- // Sessions won't be used so decoding capability is not required.
- if (!AreMediaDrmApisAvailable())
- return nullptr;
-
UUID scheme_uuid = GetKeySystemManager()->GetUUID(key_system);
if (scheme_uuid.empty())
return nullptr;
diff --git a/chromium/media/base/android/media_drm_bridge_unittest.cc b/chromium/media/base/android/media_drm_bridge_unittest.cc
index 40c31575c49..06260327382 100644
--- a/chromium/media/base/android/media_drm_bridge_unittest.cc
+++ b/chromium/media/base/android/media_drm_bridge_unittest.cc
@@ -127,16 +127,11 @@ TEST_F(MediaDrmBridgeTest, IsKeySystemSupported_Widevine) {
EXPECT_TRUE_IF_WIDEVINE_AVAILABLE(
IsKeySystemSupportedWithType(kWidevineKeySystem, kVideoMp4));
- if (base::android::BuildInfo::GetInstance()->sdk_int() <=
- base::android::SDK_VERSION_KITKAT) {
- EXPECT_FALSE(IsKeySystemSupportedWithType(kWidevineKeySystem, kAudioWebM));
- EXPECT_FALSE(IsKeySystemSupportedWithType(kWidevineKeySystem, kVideoWebM));
- } else {
- EXPECT_TRUE_IF_WIDEVINE_AVAILABLE(
+
+ EXPECT_TRUE_IF_WIDEVINE_AVAILABLE(
IsKeySystemSupportedWithType(kWidevineKeySystem, kAudioWebM));
- EXPECT_TRUE_IF_WIDEVINE_AVAILABLE(
+ EXPECT_TRUE_IF_WIDEVINE_AVAILABLE(
IsKeySystemSupportedWithType(kWidevineKeySystem, kVideoWebM));
- }
EXPECT_FALSE(IsKeySystemSupportedWithType(kWidevineKeySystem, "unknown"));
EXPECT_FALSE(IsKeySystemSupportedWithType(kWidevineKeySystem, "video/avi"));
diff --git a/chromium/media/base/android/mock_media_codec_bridge.h b/chromium/media/base/android/mock_media_codec_bridge.h
index 85325f56cff..babe78a3064 100644
--- a/chromium/media/base/android/mock_media_codec_bridge.h
+++ b/chromium/media/base/android/mock_media_codec_bridge.h
@@ -44,7 +44,7 @@ class MockMediaCodecBridge : public MediaCodecBridge,
const std::string& iv,
const std::vector<SubsampleEntry>& subsamples,
EncryptionScheme encryption_scheme,
- base::Optional<EncryptionPattern> encryption_pattern,
+ absl::optional<EncryptionPattern> encryption_pattern,
base::TimeDelta presentation_time));
MOCK_METHOD1(QueueEOS, void(int input_buffer_index));
MOCK_METHOD2(DequeueInputBuffer,
diff --git a/chromium/media/base/android/mock_media_crypto_context.h b/chromium/media/base/android/mock_media_crypto_context.h
index a113613545b..1cd64809cfd 100644
--- a/chromium/media/base/android/mock_media_crypto_context.h
+++ b/chromium/media/base/android/mock_media_crypto_context.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_BASE_ANDROID_MOCK_MEDIA_CRYPTO_CONTEXT_H_
#define MEDIA_BASE_ANDROID_MOCK_MEDIA_CRYPTO_CONTEXT_H_
-#include <memory>
-
#include "base/macros.h"
#include "media/base/android/media_crypto_context.h"
#include "media/base/cdm_context.h"
diff --git a/chromium/media/base/android/test_destruction_observable.h b/chromium/media/base/android/test_destruction_observable.h
index 90dddfeec9e..d11b7ab9dda 100644
--- a/chromium/media/base/android/test_destruction_observable.h
+++ b/chromium/media/base/android/test_destruction_observable.h
@@ -7,7 +7,7 @@
#include "base/callback_helpers.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -55,7 +55,7 @@ class DestructionObserver {
bool destructed_;
// Whether to expect destruction. Unset if there is no expectation.
- base::Optional<bool> expect_destruction_;
+ absl::optional<bool> expect_destruction_;
base::WeakPtrFactory<DestructionObserver> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(DestructionObserver);
diff --git a/chromium/media/base/android_overlay_mojo_factory.h b/chromium/media/base/android_overlay_mojo_factory.h
index a7c0d06ed20..4a94579f27b 100644
--- a/chromium/media/base/android_overlay_mojo_factory.h
+++ b/chromium/media/base/android_overlay_mojo_factory.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_BASE_ANDROID_OVERLAY_MOJO_FACTORY_CB_H_
-#define MEDIA_BASE_ANDROID_OVERLAY_MOJO_FACTORY_CB_H_
+#ifndef MEDIA_BASE_ANDROID_OVERLAY_MOJO_FACTORY_H_
+#define MEDIA_BASE_ANDROID_OVERLAY_MOJO_FACTORY_H_
#include "base/callback.h"
#include "base/macros.h"
@@ -20,4 +20,4 @@ using AndroidOverlayMojoFactoryCB =
} // namespace media
-#endif // MEDIA_BASE_ANDROID_OVERLAY_MOJO_FACTORY_CB_H_
+#endif // MEDIA_BASE_ANDROID_OVERLAY_MOJO_FACTORY_H_
diff --git a/chromium/media/base/audio_buffer.cc b/chromium/media/base/audio_buffer.cc
index 99cbfb6af4c..56761fbe610 100644
--- a/chromium/media/base/audio_buffer.cc
+++ b/chromium/media/base/audio_buffer.cc
@@ -6,6 +6,7 @@
#include <cmath>
+#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "media/base/audio_bus.h"
@@ -187,6 +188,26 @@ scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom(
}
// static
+scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom(
+ int sample_rate,
+ const base::TimeDelta timestamp,
+ const AudioBus* audio_bus,
+ scoped_refptr<AudioBufferMemoryPool> pool) {
+ DCHECK(audio_bus->frames());
+
+ const int channel_count = audio_bus->channels();
+ DCHECK(channel_count);
+
+ std::vector<const uint8_t*> data(channel_count);
+ for (int ch = 0; ch < channel_count; ch++)
+ data[ch] = reinterpret_cast<const uint8_t*>(audio_bus->channel(ch));
+
+ return CopyFrom(kSampleFormatPlanarF32, GuessChannelLayout(channel_count),
+ channel_count, sample_rate, audio_bus->frames(), data.data(),
+ timestamp, std::move(pool));
+}
+
+// static
scoped_refptr<AudioBuffer> AudioBuffer::CopyBitstreamFrom(
SampleFormat sample_format,
ChannelLayout channel_layout,
@@ -255,6 +276,44 @@ scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() {
nullptr, 0, kNoTimestamp, nullptr));
}
+// static
+std::unique_ptr<AudioBus> AudioBuffer::WrapOrCopyToAudioBus(
+ scoped_refptr<AudioBuffer> buffer) {
+ DCHECK(buffer);
+
+ const int channels = buffer->channel_count();
+ const int frames = buffer->frame_count();
+
+ DCHECK(channels);
+ DCHECK(frames);
+
+ // |buffer| might already have the right memory layout. Prevent a data copy
+ // by wrapping it instead.
+ if (buffer->sample_format() == SampleFormat::kSampleFormatPlanarF32) {
+ auto audio_bus = AudioBus::CreateWrapper(channels);
+
+ for (int ch = 0; ch < channels; ++ch) {
+ audio_bus->SetChannelData(
+ ch, reinterpret_cast<float*>(buffer->channel_data()[ch]));
+ }
+
+ audio_bus->set_frames(frames);
+
+ // Keep |buffer| alive as long as |audio_bus|.
+ audio_bus->SetWrappedDataDeleter(
+ base::BindOnce(base::DoNothing::Once<scoped_refptr<AudioBuffer>>(),
+ std::move(buffer)));
+
+ return audio_bus;
+ }
+
+ // |buffer|'s memory can't be wrapped directly. Convert and copy it instead.
+ auto audio_bus = AudioBus::Create(channels, frames);
+ buffer->ReadFrames(frames, 0, 0, audio_bus.get());
+
+ return audio_bus;
+}
+
void AudioBuffer::AdjustSampleRate(int sample_rate) {
DCHECK(!end_of_stream_);
sample_rate_ = sample_rate;
diff --git a/chromium/media/base/audio_buffer.h b/chromium/media/base/audio_buffer.h
index 9a90ef1d88d..7042fab41b0 100644
--- a/chromium/media/base/audio_buffer.h
+++ b/chromium/media/base/audio_buffer.h
@@ -65,6 +65,15 @@ class MEDIA_EXPORT AudioBuffer
const base::TimeDelta timestamp,
scoped_refptr<AudioBufferMemoryPool> pool = nullptr);
+ // Create an AudioBuffer from a copy of the data in |audio_bus|.
+ // For optimal efficiency when many buffers are being created, a
+ // AudioBufferMemoryPool can be provided to avoid thrashing memory.
+ static scoped_refptr<AudioBuffer> CopyFrom(
+ int sample_rate,
+ const base::TimeDelta timestamp,
+ const AudioBus* audio_bus,
+ scoped_refptr<AudioBufferMemoryPool> pool = nullptr);
+
// Create an AudioBuffer for compressed bitstream. Its channel data is copied
// from |data|, and the size is |data_size|. |data| must not be null and
// |frame_count| must be >= 0.
@@ -110,6 +119,13 @@ class MEDIA_EXPORT AudioBuffer
int frame_count,
const base::TimeDelta timestamp);
+ // Helper function that creates a new AudioBus which wraps |audio_buffer| and
+ // takes a reference on it, if the memory layout (e.g. |sample_format_|) is
+ // compatible with wrapping. Otherwise, this copies |audio_buffer| to a new
+ // AudioBus, using ReadFrames().
+ static std::unique_ptr<AudioBus> WrapOrCopyToAudioBus(
+ scoped_refptr<AudioBuffer> audio_buffer);
+
// Create a AudioBuffer indicating we've reached end of stream.
// Calling any method other than end_of_stream() on the resulting buffer
// is disallowed.
diff --git a/chromium/media/base/audio_buffer_converter.h b/chromium/media/base/audio_buffer_converter.h
index 3a0320be67d..f59e8f23354 100644
--- a/chromium/media/base/audio_buffer_converter.h
+++ b/chromium/media/base/audio_buffer_converter.h
@@ -9,7 +9,6 @@
#include "base/containers/circular_deque.h"
#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
#include "media/base/audio_buffer.h"
#include "media/base/audio_converter.h"
#include "media/base/audio_parameters.h"
diff --git a/chromium/media/base/audio_buffer_unittest.cc b/chromium/media/base/audio_buffer_unittest.cc
index 3a30db21d2d..88ea630fc2a 100644
--- a/chromium/media/base/audio_buffer_unittest.cc
+++ b/chromium/media/base/audio_buffer_unittest.cc
@@ -174,6 +174,44 @@ TEST(AudioBufferTest, CopyFrom) {
EXPECT_FALSE(original_buffer->end_of_stream());
}
+TEST(AudioBufferTest, CopyFromAudioBus) {
+ const int kChannelCount = 2;
+ const int kFrameCount = kSampleRate / 100;
+
+ // For convenience's sake, create an arbitrary |temp_buffer| and copy it to
+ // |audio_bus|, instead of generating data in |audio_bus| ourselves.
+ scoped_refptr<AudioBuffer> temp_buffer = MakeAudioBuffer<uint8_t>(
+ kSampleFormatU8, CHANNEL_LAYOUT_STEREO, kChannelCount, kSampleRate, 1, 1,
+ kFrameCount, base::TimeDelta());
+
+ auto audio_bus = media::AudioBus::Create(kChannelCount, kFrameCount);
+ temp_buffer->ReadFrames(kFrameCount, 0, 0, audio_bus.get());
+
+ const base::TimeDelta kTimestamp = base::TimeDelta::FromMilliseconds(123);
+
+ auto audio_buffer_from_bus =
+ media::AudioBuffer::CopyFrom(kSampleRate, kTimestamp, audio_bus.get());
+
+ EXPECT_EQ(audio_buffer_from_bus->channel_count(), audio_bus->channels());
+ EXPECT_EQ(audio_buffer_from_bus->channel_layout(),
+ GuessChannelLayout(kChannelCount));
+ EXPECT_EQ(audio_buffer_from_bus->frame_count(), audio_bus->frames());
+ EXPECT_EQ(audio_buffer_from_bus->timestamp(), kTimestamp);
+ EXPECT_EQ(audio_buffer_from_bus->sample_rate(), kSampleRate);
+ EXPECT_EQ(audio_buffer_from_bus->sample_format(),
+ SampleFormat::kSampleFormatPlanarF32);
+ EXPECT_FALSE(audio_buffer_from_bus->end_of_stream());
+
+ for (int ch = 0; ch < kChannelCount; ++ch) {
+ const float* bus_data = audio_bus->channel(ch);
+ const float* buffer_data = reinterpret_cast<const float*>(
+ audio_buffer_from_bus->channel_data()[ch]);
+
+ for (int i = 0; i < kFrameCount; ++i)
+ EXPECT_EQ(buffer_data[i], bus_data[i]);
+ }
+}
+
TEST(AudioBufferTest, CopyBitstreamFrom) {
const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
const int kChannelCount = ChannelLayoutToChannelCount(kChannelLayout);
@@ -456,6 +494,38 @@ TEST(AudioBufferTest, ReadF32Planar) {
VerifyBus(bus.get(), frames, 1, 1, ValueType::kFloat);
}
+TEST(AudioBufferTest, WrapOrCopyToAudioBus) {
+ const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
+ const int channels = ChannelLayoutToChannelCount(channel_layout);
+ const int frames = 100;
+ const base::TimeDelta start_time;
+ scoped_refptr<AudioBuffer> buffer =
+ MakeAudioBuffer<float>(kSampleFormatPlanarF32, channel_layout, channels,
+ kSampleRate, 1.0f, 1.0f, frames, start_time);
+
+ // With kSampleFormatPlanarF32, the memory layout should allow |bus| to
+ // directly wrap |buffer|'s data.
+ std::unique_ptr<AudioBus> bus = AudioBuffer::WrapOrCopyToAudioBus(buffer);
+ for (int ch = 0; ch < channels; ++ch) {
+ EXPECT_EQ(bus->channel(ch),
+ reinterpret_cast<float*>(buffer->channel_data()[ch]));
+ }
+
+ // |bus| should have its own reference on |buffer|, so clearing it here should
+ // not free the underlying data.
+ buffer.reset();
+ VerifyBus(bus.get(), frames, 1, 1, ValueType::kFloat);
+
+ // Interleaved samples cannot be wrapped, and samples will be copied out.
+ buffer = MakeAudioBuffer<float>(kSampleFormatF32, channel_layout, channels,
+ kSampleRate, 1.0f, 1.0f, frames, start_time);
+
+ bus = AudioBuffer::WrapOrCopyToAudioBus(buffer);
+ buffer.reset();
+
+ VerifyBus(bus.get(), frames, 1, 1, ValueType::kFloat);
+}
+
TEST(AudioBufferTest, EmptyBuffer) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
const int channels = ChannelLayoutToChannelCount(channel_layout);
diff --git a/chromium/media/base/audio_bus.cc b/chromium/media/base/audio_bus.cc
index 76ee5c24218..3115558f367 100644
--- a/chromium/media/base/audio_bus.cc
+++ b/chromium/media/base/audio_bus.cc
@@ -64,8 +64,7 @@ void AudioBus::CheckOverflow(int start_frame, int frames, int total_frames) {
}
AudioBus::AudioBus(int channels, int frames)
- : frames_(frames),
- can_set_channel_data_(false) {
+ : frames_(frames), is_wrapper_(false) {
ValidateConfig(channels, frames_);
int aligned_frames = 0;
@@ -78,8 +77,7 @@ AudioBus::AudioBus(int channels, int frames)
}
AudioBus::AudioBus(int channels, int frames, float* data)
- : frames_(frames),
- can_set_channel_data_(false) {
+ : frames_(frames), is_wrapper_(false) {
// Since |data| may have come from an external source, ensure it's valid.
CHECK(data);
ValidateConfig(channels, frames_);
@@ -91,9 +89,7 @@ AudioBus::AudioBus(int channels, int frames, float* data)
}
AudioBus::AudioBus(int frames, const std::vector<float*>& channel_data)
- : channel_data_(channel_data),
- frames_(frames),
- can_set_channel_data_(false) {
+ : channel_data_(channel_data), frames_(frames), is_wrapper_(false) {
ValidateConfig(
base::checked_cast<int>(channel_data_.size()), frames_);
@@ -103,15 +99,16 @@ AudioBus::AudioBus(int frames, const std::vector<float*>& channel_data)
}
AudioBus::AudioBus(int channels)
- : channel_data_(channels),
- frames_(0),
- can_set_channel_data_(true) {
+ : channel_data_(channels), frames_(0), is_wrapper_(true) {
CHECK_GT(channels, 0);
for (size_t i = 0; i < channel_data_.size(); ++i)
channel_data_[i] = NULL;
}
-AudioBus::~AudioBus() = default;
+AudioBus::~AudioBus() {
+ if (wrapped_data_deleter_cb_)
+ std::move(wrapped_data_deleter_cb_).Run();
+}
std::unique_ptr<AudioBus> AudioBus::Create(int channels, int frames) {
return base::WrapUnique(new AudioBus(channels, frames));
@@ -171,7 +168,7 @@ std::unique_ptr<const AudioBus> AudioBus::WrapReadOnlyMemory(
}
void AudioBus::SetChannelData(int channel, float* data) {
- CHECK(can_set_channel_data_);
+ CHECK(is_wrapper_);
CHECK(data);
CHECK_GE(channel, 0);
CHECK_LT(static_cast<size_t>(channel), channel_data_.size());
@@ -180,11 +177,17 @@ void AudioBus::SetChannelData(int channel, float* data) {
}
void AudioBus::set_frames(int frames) {
- CHECK(can_set_channel_data_);
+ CHECK(is_wrapper_);
ValidateConfig(static_cast<int>(channel_data_.size()), frames);
frames_ = frames;
}
+void AudioBus::SetWrappedDataDeleter(base::OnceClosure deleter) {
+ CHECK(is_wrapper_);
+ DCHECK(!wrapped_data_deleter_cb_);
+ wrapped_data_deleter_cb_ = std::move(deleter);
+}
+
size_t AudioBus::GetBitstreamDataSize() const {
DCHECK(is_bitstream_format_);
return bitstream_data_size_;
diff --git a/chromium/media/base/audio_bus.h b/chromium/media/base/audio_bus.h
index 1c520279146..75792baa9b8 100644
--- a/chromium/media/base/audio_bus.h
+++ b/chromium/media/base/audio_bus.h
@@ -10,6 +10,7 @@
#include <memory>
#include <vector>
+#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/aligned_memory.h"
#include "media/base/audio_sample_types.h"
@@ -76,6 +77,13 @@ class MEDIA_SHMEM_EXPORT AudioBus {
void SetChannelData(int channel, float* data);
void set_frames(int frames);
+ // Method optionally called after AudioBus::CreateWrapper().
+ // Runs |deleter| when on |this|' destruction, freeing external data
+ // referenced by SetChannelData().
+ // Note: It is illegal to call this method when using a factory method other
+ // than CreateWrapper().
+ void SetWrappedDataDeleter(base::OnceClosure deleter);
+
// Methods for compressed bitstream formats. The data size may not be equal to
// the capacity of the AudioBus. Also, the frame count may not be equal to the
// capacity of the AudioBus. Thus, we need extra methods to access the real
@@ -220,8 +228,13 @@ class MEDIA_SHMEM_EXPORT AudioBus {
std::vector<float*> channel_data_;
int frames_;
- // Protect SetChannelData() and set_frames() for use by CreateWrapper().
- bool can_set_channel_data_;
+ // Protect SetChannelData(), set_frames() and SetWrappedDataDeleter() for use
+ // by CreateWrapper().
+ bool is_wrapper_;
+
+ // Run on destruction. Frees memory to the data set via SetChannelData().
+ // Only used with CreateWrapper().
+ base::OnceClosure wrapped_data_deleter_cb_;
DISALLOW_COPY_AND_ASSIGN(AudioBus);
};
diff --git a/chromium/media/base/audio_bus_unittest.cc b/chromium/media/base/audio_bus_unittest.cc
index 38d5cbd09da..e2cac3c8e29 100644
--- a/chromium/media/base/audio_bus_unittest.cc
+++ b/chromium/media/base/audio_bus_unittest.cc
@@ -11,6 +11,7 @@
#include "base/memory/aligned_memory.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
+#include "base/test/bind.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/audio_bus.h"
@@ -157,8 +158,16 @@ TEST_F(AudioBusTest, CreateWrapper) {
for (int i = 0; i < bus->channels(); ++i)
bus->SetChannelData(i, data_[i]);
+ bool deleted = false;
+ bus->SetWrappedDataDeleter(
+ base::BindLambdaForTesting([&]() { deleted = true; }));
+
VerifyChannelAndFrameCount(bus.get());
VerifyReadWriteAndAlignment(bus.get());
+
+ EXPECT_FALSE(deleted);
+ bus.reset();
+ EXPECT_TRUE(deleted);
}
// Verify an AudioBus created via wrapping a vector works as advertised.
diff --git a/chromium/media/base/audio_capturer_source.h b/chromium/media/base/audio_capturer_source.h
index ca91a598c22..7ec2136eb5f 100644
--- a/chromium/media/base/audio_capturer_source.h
+++ b/chromium/media/base/audio_capturer_source.h
@@ -23,6 +23,11 @@ class AudioProcessorControls;
class AudioCapturerSource
: public base::RefCountedThreadSafe<media::AudioCapturerSource> {
public:
+ enum class ErrorCode {
+ kUnknown = 0,
+ kSystemPermissions = 1,
+ };
+
class CaptureCallback {
public:
// Signals that audio recording has been started. Called asynchronously
@@ -40,7 +45,7 @@ class AudioCapturerSource
bool key_pressed) = 0;
// Signals an error has occurred.
- virtual void OnCaptureError(const std::string& message) = 0;
+ virtual void OnCaptureError(ErrorCode code, const std::string& message) = 0;
// Signals the muted state has changed. May be called before
// OnCaptureStarted.
diff --git a/chromium/media/base/audio_converter.h b/chromium/media/base/audio_converter.h
index 5e1b609fabf..45b667b1fe8 100644
--- a/chromium/media/base/audio_converter.h
+++ b/chromium/media/base/audio_converter.h
@@ -23,7 +23,6 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "base/time/time.h"
#include "media/base/audio_parameters.h"
#include "media/base/media_export.h"
diff --git a/chromium/media/base/audio_decoder.h b/chromium/media/base/audio_decoder.h
index 245ac2979a0..961d570e561 100644
--- a/chromium/media/base/audio_decoder.h
+++ b/chromium/media/base/audio_decoder.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_BASE_AUDIO_DECODER_H_
#define MEDIA_BASE_AUDIO_DECODER_H_
-#include <string>
-
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
diff --git a/chromium/media/base/audio_encoder.h b/chromium/media/base/audio_encoder.h
index 2d3362bebca..d7979cca1e9 100644
--- a/chromium/media/base/audio_encoder.h
+++ b/chromium/media/base/audio_encoder.h
@@ -55,7 +55,7 @@ class MEDIA_EXPORT AudioEncoder {
Options(const Options&);
~Options();
- base::Optional<int> bitrate;
+ absl::optional<int> bitrate;
int channels;
@@ -69,7 +69,7 @@ class MEDIA_EXPORT AudioEncoder {
// invoked on the same sequence on which EncodeAudio() is called.
using OutputCB =
base::RepeatingCallback<void(EncodedAudioBuffer output,
- base::Optional<CodecDescription>)>;
+ absl::optional<CodecDescription>)>;
// Signature of the callback to report errors.
using StatusCB = base::OnceCallback<void(Status error)>;
diff --git a/chromium/media/base/audio_parameters.h b/chromium/media/base/audio_parameters.h
index 9d571a3c6e2..fbebe23cf45 100644
--- a/chromium/media/base/audio_parameters.h
+++ b/chromium/media/base/audio_parameters.h
@@ -11,7 +11,6 @@
#include "base/compiler_specific.h"
#include "base/numerics/checked_math.h"
-#include "base/optional.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/audio_bus.h"
@@ -20,6 +19,7 @@
#include "media/base/channel_layout.h"
#include "media/base/media_shmem_export.h"
#include "media/base/sample_format.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -254,7 +254,7 @@ class MEDIA_SHMEM_EXPORT AudioParameters {
}
int frames_per_buffer() const { return frames_per_buffer_; }
- base::Optional<HardwareCapabilities> hardware_capabilities() const {
+ absl::optional<HardwareCapabilities> hardware_capabilities() const {
return hardware_capabilities_;
}
@@ -305,7 +305,7 @@ class MEDIA_SHMEM_EXPORT AudioParameters {
// Audio hardware specific parameters, these are treated as read-only and
// changing them has no effect.
- base::Optional<HardwareCapabilities> hardware_capabilities_;
+ absl::optional<HardwareCapabilities> hardware_capabilities_;
};
// Comparison is useful when AudioParameters is used with std structures.
diff --git a/chromium/media/base/audio_processing.h b/chromium/media/base/audio_processing.h
index 46428114847..52f32fbc6ef 100644
--- a/chromium/media/base/audio_processing.h
+++ b/chromium/media/base/audio_processing.h
@@ -8,7 +8,6 @@
#include <string>
#include "base/files/file.h"
-#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "media/base/media_export.h"
diff --git a/chromium/media/base/audio_renderer.h b/chromium/media/base/audio_renderer.h
index 15701b34294..907d0fc7f82 100644
--- a/chromium/media/base/audio_renderer.h
+++ b/chromium/media/base/audio_renderer.h
@@ -7,11 +7,11 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "base/time/time.h"
#include "media/base/buffering_state.h"
#include "media/base/media_export.h"
#include "media/base/pipeline_status.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -63,7 +63,7 @@ class MEDIA_EXPORT AudioRenderer {
// Set a hint indicating target latency. See comment in renderer.h.
// |latency_hint| may be nullopt to indicate the hint has been cleared
// (restore UA default).
- virtual void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) = 0;
+ virtual void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) = 0;
// Sets a flag indicating that the AudioRenderer should use or avoid pitch
// preservation when playing back at speeds other than 1.0.
diff --git a/chromium/media/base/audio_renderer_mixer_input.h b/chromium/media/base/audio_renderer_mixer_input.h
index c56e1f209c8..724cba483d5 100644
--- a/chromium/media/base/audio_renderer_mixer_input.h
+++ b/chromium/media/base/audio_renderer_mixer_input.h
@@ -83,7 +83,7 @@ class MEDIA_EXPORT AudioRendererMixerInput
double volume_ GUARDED_BY(volume_lock_) = 1.0;
scoped_refptr<AudioRendererSink> sink_;
- base::Optional<OutputDeviceInfo> device_info_;
+ absl::optional<OutputDeviceInfo> device_info_;
// AudioConverter::InputCallback implementation.
double ProvideInput(AudioBus* audio_bus, uint32_t frames_delayed) override;
diff --git a/chromium/media/base/cdm_context.cc b/chromium/media/base/cdm_context.cc
index 9b30303dd4b..fc2901585bb 100644
--- a/chromium/media/base/cdm_context.cc
+++ b/chromium/media/base/cdm_context.cc
@@ -22,8 +22,8 @@ Decryptor* CdmContext::GetDecryptor() {
return nullptr;
}
-base::Optional<base::UnguessableToken> CdmContext::GetCdmId() const {
- return base::nullopt;
+absl::optional<base::UnguessableToken> CdmContext::GetCdmId() const {
+ return absl::nullopt;
}
std::string CdmContext::CdmIdToString(const base::UnguessableToken* cdm_id) {
diff --git a/chromium/media/base/cdm_context.h b/chromium/media/base/cdm_context.h
index 9bb677217cc..f426dd3fd13 100644
--- a/chromium/media/base/cdm_context.h
+++ b/chromium/media/base/cdm_context.h
@@ -7,17 +7,13 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "base/optional.h"
+#include "base/memory/scoped_refptr.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "media/base/media_export.h"
#include "media/media_buildflags.h"
-
-#if defined(OS_WIN)
-#include <wrl/client.h>
-struct IMFCdmProxy;
-#endif
+#include "third_party/abseil-cpp/absl/types/optional.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
namespace chromeos {
@@ -35,6 +31,10 @@ class MediaCryptoContext;
class FuchsiaCdmContext;
#endif
+#if defined(OS_WIN)
+class MediaFoundationCdmProxy;
+#endif
+
// An interface representing the context that a media player needs from a
// content decryption module (CDM) to decrypt (and decode) encrypted buffers.
// Typically this will be passed to the media player (e.g. using SetCdm()).
@@ -88,9 +88,9 @@ class MEDIA_EXPORT CdmContext {
virtual Decryptor* GetDecryptor();
// Returns an ID that can be used to find a remote CDM, in which case this CDM
- // serves as a proxy to the remote one. Returns base::nullopt when remote CDM
+ // serves as a proxy to the remote one. Returns absl::nullopt when remote CDM
// is not supported (e.g. this CDM is a local CDM).
- virtual base::Optional<base::UnguessableToken> GetCdmId() const;
+ virtual absl::optional<base::UnguessableToken> GetCdmId() const;
static std::string CdmIdToString(const base::UnguessableToken* cdm_id);
@@ -101,7 +101,7 @@ class MEDIA_EXPORT CdmContext {
virtual bool RequiresMediaFoundationRenderer();
using GetMediaFoundationCdmProxyCB =
- base::OnceCallback<void(Microsoft::WRL::ComPtr<IMFCdmProxy>)>;
+ base::OnceCallback<void(scoped_refptr<MediaFoundationCdmProxy>)>;
// This allows a CdmContext to expose an IMFTrustedInput instance for use in
// a Media Foundation rendering pipeline. This method is asynchronous because
// the underlying MF-based CDM might not have a native session created yet.
diff --git a/chromium/media/base/data_source.h b/chromium/media/base/data_source.h
index 82dd76485fa..08c740c0fa0 100644
--- a/chromium/media/base/data_source.h
+++ b/chromium/media/base/data_source.h
@@ -9,7 +9,6 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "base/time/time.h"
#include "media/base/media_export.h"
namespace media {
diff --git a/chromium/media/base/decoder_buffer.h b/chromium/media/base/decoder_buffer.h
index ea64fa50d0b..9a305f3e77a 100644
--- a/chromium/media/base/decoder_buffer.h
+++ b/chromium/media/base/decoder_buffer.h
@@ -14,7 +14,6 @@
#include "base/check.h"
#include "base/macros.h"
-#include "base/memory/aligned_memory.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
diff --git a/chromium/media/base/decrypt_config.cc b/chromium/media/base/decrypt_config.cc
index 5b7c02c8f5e..ff3ed63f7a4 100644
--- a/chromium/media/base/decrypt_config.cc
+++ b/chromium/media/base/decrypt_config.cc
@@ -19,7 +19,7 @@ std::unique_ptr<DecryptConfig> DecryptConfig::CreateCencConfig(
const std::string& iv,
const std::vector<SubsampleEntry>& subsamples) {
return std::make_unique<DecryptConfig>(EncryptionScheme::kCenc, key_id, iv,
- subsamples, base::nullopt);
+ subsamples, absl::nullopt);
}
// static
@@ -27,7 +27,7 @@ std::unique_ptr<DecryptConfig> DecryptConfig::CreateCbcsConfig(
const std::string& key_id,
const std::string& iv,
const std::vector<SubsampleEntry>& subsamples,
- base::Optional<EncryptionPattern> encryption_pattern) {
+ absl::optional<EncryptionPattern> encryption_pattern) {
return std::make_unique<DecryptConfig>(EncryptionScheme::kCbcs, key_id, iv,
subsamples,
std::move(encryption_pattern));
@@ -38,7 +38,7 @@ DecryptConfig::DecryptConfig(
const std::string& key_id,
const std::string& iv,
const std::vector<SubsampleEntry>& subsamples,
- base::Optional<EncryptionPattern> encryption_pattern)
+ absl::optional<EncryptionPattern> encryption_pattern)
: encryption_scheme_(encryption_scheme),
key_id_(key_id),
iv_(iv),
diff --git a/chromium/media/base/decrypt_config.h b/chromium/media/base/decrypt_config.h
index 79905419bdd..a9c55064566 100644
--- a/chromium/media/base/decrypt_config.h
+++ b/chromium/media/base/decrypt_config.h
@@ -13,11 +13,11 @@
#include <vector>
#include "base/macros.h"
-#include "base/optional.h"
#include "media/base/encryption_pattern.h"
#include "media/base/encryption_scheme.h"
#include "media/base/media_export.h"
#include "media/base/subsample_entry.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -47,20 +47,20 @@ class MEDIA_EXPORT DecryptConfig {
const std::string& key_id,
const std::string& iv,
const std::vector<SubsampleEntry>& subsamples,
- base::Optional<EncryptionPattern> encryption_pattern);
+ absl::optional<EncryptionPattern> encryption_pattern);
DecryptConfig(EncryptionScheme encryption_scheme,
const std::string& key_id,
const std::string& iv,
const std::vector<SubsampleEntry>& subsamples,
- base::Optional<EncryptionPattern> encryption_pattern);
+ absl::optional<EncryptionPattern> encryption_pattern);
~DecryptConfig();
const std::string& key_id() const { return key_id_; }
const std::string& iv() const { return iv_; }
const std::vector<SubsampleEntry>& subsamples() const { return subsamples_; }
EncryptionScheme encryption_scheme() const { return encryption_scheme_; }
- const base::Optional<EncryptionPattern>& encryption_pattern() const {
+ const absl::optional<EncryptionPattern>& encryption_pattern() const {
return encryption_pattern_;
}
@@ -95,7 +95,7 @@ class MEDIA_EXPORT DecryptConfig {
const std::vector<SubsampleEntry> subsamples_;
// Only specified if |encryption_mode_| requires a pattern.
- base::Optional<EncryptionPattern> encryption_pattern_;
+ absl::optional<EncryptionPattern> encryption_pattern_;
DISALLOW_ASSIGN(DecryptConfig);
};
diff --git a/chromium/media/base/decrypt_config_unittest.cc b/chromium/media/base/decrypt_config_unittest.cc
index e39d7a79461..014ee6a4d23 100644
--- a/chromium/media/base/decrypt_config_unittest.cc
+++ b/chromium/media/base/decrypt_config_unittest.cc
@@ -78,7 +78,7 @@ TEST(DecryptConfigTest, CbcsConstruction) {
// Now without pattern.
config = DecryptConfig::CreateCbcsConfig(kAlternateKeyId, kDefaultIV,
- {{1, 2}}, base::nullopt);
+ {{1, 2}}, absl::nullopt);
EXPECT_EQ(config->key_id(), kAlternateKeyId);
EXPECT_EQ(config->iv(), kDefaultIV);
EXPECT_EQ(config->subsamples().size(), 1u);
@@ -173,7 +173,7 @@ TEST(DecryptConfigTest, CbcsMatches) {
// Without pattern.
auto config6 = DecryptConfig::CreateCbcsConfig(kDefaultKeyId, kDefaultIV, {},
- base::nullopt);
+ absl::nullopt);
EXPECT_FALSE(config1->Matches(*config6));
EXPECT_FALSE(config5->Matches(*config6));
EXPECT_FALSE(config6->Matches(*config1));
@@ -192,7 +192,7 @@ TEST(DecryptConfigTest, Output) {
// Simple 'cbcs' config.
stream << *DecryptConfig::CreateCbcsConfig(kDefaultKeyId, kDefaultIV, {},
- base::nullopt);
+ absl::nullopt);
// 'cbcs' config with subsamples and pattern.
stream << *DecryptConfig::CreateCbcsConfig(kAlternateKeyId, kAlternateIV,
diff --git a/chromium/media/base/demuxer.h b/chromium/media/base/demuxer.h
index c9a4ebbd6b8..e048fca2d9c 100644
--- a/chromium/media/base/demuxer.h
+++ b/chromium/media/base/demuxer.h
@@ -11,7 +11,6 @@
#include <vector>
#include "base/macros.h"
-#include "base/optional.h"
#include "base/time/time.h"
#include "media/base/container_names.h"
#include "media/base/data_source.h"
@@ -22,6 +21,7 @@
#include "media/base/media_track.h"
#include "media/base/pipeline_status.h"
#include "media/base/ranges.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -149,7 +149,7 @@ class MEDIA_EXPORT Demuxer : public MediaResource {
// Implementations where this is not meaningful will return an empty value.
// Implementations that do provide values should always provide a value,
// returning CONTAINER_UNKNOWN in cases where the container is not known.
- virtual base::Optional<container_names::MediaContainerName>
+ virtual absl::optional<container_names::MediaContainerName>
GetContainerForMetrics() const = 0;
// The |track_ids| vector has either 1 track, or is empty, indicating that
diff --git a/chromium/media/base/demuxer_memory_limit_cast_unittest.cc b/chromium/media/base/demuxer_memory_limit_cast_unittest.cc
index 41b68a20aed..4dbe6d4308b 100644
--- a/chromium/media/base/demuxer_memory_limit_cast_unittest.cc
+++ b/chromium/media/base/demuxer_memory_limit_cast_unittest.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/optional.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/demuxer.h"
#include "media/base/demuxer_memory_limit.h"
#include "media/base/media_util.h"
#include "media/base/video_decoder_config.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
diff --git a/chromium/media/base/demuxer_stream.h b/chromium/media/base/demuxer_stream.h
index 30236894215..3b10523f7fb 100644
--- a/chromium/media/base/demuxer_stream.h
+++ b/chromium/media/base/demuxer_stream.h
@@ -7,7 +7,6 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
#include "media/base/media_export.h"
#include "media/base/video_transformation.h"
diff --git a/chromium/media/base/eme_constants.h b/chromium/media/base/eme_constants.h
index 11e7c1ed3ff..6e47c0ed18a 100644
--- a/chromium/media/base/eme_constants.h
+++ b/chromium/media/base/eme_constants.h
@@ -187,19 +187,20 @@ enum class EmeConfigRule {
IDENTIFIER_AND_PERSISTENCE_REQUIRED,
// The configuration option prevents use of hardware-secure codecs.
- // This rule only has meaning on platforms that distinguish hardware-secure
- // codecs (i.e. Android, Windows and ChromeOS).
HW_SECURE_CODECS_NOT_ALLOWED,
// The configuration option is supported if hardware-secure codecs are used.
- // This rule only has meaning on platforms that distinguish hardware-secure
- // codecs (i.e. Android, Windows and ChromeOS).
HW_SECURE_CODECS_REQUIRED,
// The configuration option is supported on platforms where hardware-secure
// codecs are used and an identifier is also required (i.e. ChromeOS).
IDENTIFIER_AND_HW_SECURE_CODECS_REQUIRED,
+ // The configuration option is supported on platforms where hardware-secure
+ // codecs are used and both identifier and persistent state are required (i.e.
+ // Windows).
+ IDENTIFIER_PERSISTENCE_AND_HW_SECURE_CODECS_REQUIRED,
+
// The configuration option is supported without conditions.
SUPPORTED,
};
diff --git a/chromium/media/base/encryption_pattern.h b/chromium/media/base/encryption_pattern.h
index 928c1dbadb9..89c3e28b115 100644
--- a/chromium/media/base/encryption_pattern.h
+++ b/chromium/media/base/encryption_pattern.h
@@ -20,7 +20,7 @@ namespace media {
// encrypted, and the next nine are skipped. This pattern is applied
// repeatedly until the end of the last 16-byte block in the subsample.
// Any remaining bytes are left clear.
-// TODO(jrummell): Use base::Optional<EncryptionPattern> everywhere.
+// TODO(jrummell): Use absl::optional<EncryptionPattern> everywhere.
class MEDIA_EXPORT EncryptionPattern {
public:
EncryptionPattern();
diff --git a/chromium/media/base/fake_audio_renderer_sink.h b/chromium/media/base/fake_audio_renderer_sink.h
index 9918eabad63..63af4b5b987 100644
--- a/chromium/media/base/fake_audio_renderer_sink.h
+++ b/chromium/media/base/fake_audio_renderer_sink.h
@@ -7,8 +7,6 @@
#include <stdint.h>
-#include <string>
-
#include "base/macros.h"
#include "media/base/audio_parameters.h"
#include "media/base/audio_renderer_sink.h"
diff --git a/chromium/media/base/fake_text_track_stream.cc b/chromium/media/base/fake_text_track_stream.cc
index 72a1655cfa8..5a9bd62f5ce 100644
--- a/chromium/media/base/fake_text_track_stream.cc
+++ b/chromium/media/base/fake_text_track_stream.cc
@@ -63,8 +63,8 @@ void FakeTextTrackStream::SatisfyPendingRead(
const uint8_t* const sd_buf = &side_data[0];
const int sd_len = static_cast<int>(side_data.size());
- scoped_refptr<DecoderBuffer> buffer;
- buffer = DecoderBuffer::CopyFrom(data_buf, data_len, sd_buf, sd_len);
+ scoped_refptr<DecoderBuffer> buffer =
+ DecoderBuffer::CopyFrom(data_buf, data_len, sd_buf, sd_len);
buffer->set_timestamp(start);
buffer->set_duration(duration);
diff --git a/chromium/media/base/format_utils.cc b/chromium/media/base/format_utils.cc
index be5a8b9c411..b9fc8143bd6 100644
--- a/chromium/media/base/format_utils.cc
+++ b/chromium/media/base/format_utils.cc
@@ -8,7 +8,7 @@
namespace media {
-base::Optional<VideoPixelFormat> GfxBufferFormatToVideoPixelFormat(
+absl::optional<VideoPixelFormat> GfxBufferFormatToVideoPixelFormat(
gfx::BufferFormat format) {
switch (format) {
case gfx::BufferFormat::BGRX_8888:
@@ -40,11 +40,11 @@ base::Optional<VideoPixelFormat> GfxBufferFormatToVideoPixelFormat(
default:
DLOG(WARNING) << "Unsupported BufferFormat: "
<< gfx::BufferFormatToString(format);
- return base::nullopt;
+ return absl::nullopt;
}
}
-base::Optional<gfx::BufferFormat> VideoPixelFormatToGfxBufferFormat(
+absl::optional<gfx::BufferFormat> VideoPixelFormatToGfxBufferFormat(
VideoPixelFormat pixel_format) {
switch (pixel_format) {
case PIXEL_FORMAT_ARGB:
@@ -70,7 +70,7 @@ base::Optional<gfx::BufferFormat> VideoPixelFormatToGfxBufferFormat(
default:
DLOG(WARNING) << "Unsupported VideoPixelFormat: " << pixel_format;
- return base::nullopt;
+ return absl::nullopt;
}
}
diff --git a/chromium/media/base/format_utils.h b/chromium/media/base/format_utils.h
index de7980c7034..eed468b553f 100644
--- a/chromium/media/base/format_utils.h
+++ b/chromium/media/base/format_utils.h
@@ -5,17 +5,17 @@
#ifndef MEDIA_BASE_FORMAT_UTILS_H_
#define MEDIA_BASE_FORMAT_UTILS_H_
-#include "base/optional.h"
#include "media/base/media_export.h"
#include "media/base/video_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/buffer_types.h"
namespace media {
-MEDIA_EXPORT base::Optional<VideoPixelFormat> GfxBufferFormatToVideoPixelFormat(
+MEDIA_EXPORT absl::optional<VideoPixelFormat> GfxBufferFormatToVideoPixelFormat(
gfx::BufferFormat format);
-MEDIA_EXPORT base::Optional<gfx::BufferFormat>
+MEDIA_EXPORT absl::optional<gfx::BufferFormat>
VideoPixelFormatToGfxBufferFormat(VideoPixelFormat pixel_format);
} // namespace media
diff --git a/chromium/media/base/frame_rate_estimator.cc b/chromium/media/base/frame_rate_estimator.cc
index 96a39b90707..48cf9f9a56d 100644
--- a/chromium/media/base/frame_rate_estimator.cc
+++ b/chromium/media/base/frame_rate_estimator.cc
@@ -62,7 +62,7 @@ void FrameRateEstimator::AddSample(base::TimeDelta frame_duration) {
most_recent_bucket_ = bucketed_fps_min;
}
-base::Optional<int> FrameRateEstimator::ComputeFPS() {
+absl::optional<int> FrameRateEstimator::ComputeFPS() {
return most_recent_bucket_;
}
diff --git a/chromium/media/base/frame_rate_estimator.h b/chromium/media/base/frame_rate_estimator.h
index 3a00f7bcd5e..38262abe4fc 100644
--- a/chromium/media/base/frame_rate_estimator.h
+++ b/chromium/media/base/frame_rate_estimator.h
@@ -6,9 +6,9 @@
#define MEDIA_BASE_FRAME_RATE_ESTIMATOR_H_
#include "base/macros.h"
-#include "base/optional.h"
#include "media/base/media_export.h"
#include "media/base/moving_average.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -25,7 +25,7 @@ class MEDIA_EXPORT FrameRateEstimator {
// Return the current (bucketed) frame rate (not duration), or nullopt if one
// isn't available with suitable certainty.
- base::Optional<int> ComputeFPS();
+ absl::optional<int> ComputeFPS();
// Reset everything.
void Reset();
@@ -43,7 +43,7 @@ class MEDIA_EXPORT FrameRateEstimator {
uint64_t required_samples_;
// Most recently computed bucketed FPS (not duration), if any.
- base::Optional<int> most_recent_bucket_;
+ absl::optional<int> most_recent_bucket_;
};
} // namespace media
diff --git a/chromium/media/base/ipc/media_param_traits.cc b/chromium/media/base/ipc/media_param_traits.cc
index 271754aff43..884ac079019 100644
--- a/chromium/media/base/ipc/media_param_traits.cc
+++ b/chromium/media/base/ipc/media_param_traits.cc
@@ -41,7 +41,7 @@ bool ParamTraits<AudioParameters>::Read(const base::Pickle* m,
int sample_rate, frames_per_buffer, channels, effects;
std::vector<media::Point> mic_positions;
AudioLatency::LatencyType latency_tag;
- base::Optional<media::AudioParameters::HardwareCapabilities>
+ absl::optional<media::AudioParameters::HardwareCapabilities>
hardware_capabilities;
if (!ReadParam(m, iter, &format) || !ReadParam(m, iter, &channel_layout) ||
diff --git a/chromium/media/base/key_system_names.cc b/chromium/media/base/key_system_names.cc
index 6fdf44cac9e..6a8bc0a9f42 100644
--- a/chromium/media/base/key_system_names.cc
+++ b/chromium/media/base/key_system_names.cc
@@ -13,15 +13,14 @@ bool IsClearKey(const std::string& key_system) {
return key_system == kClearKey;
}
-bool IsChildKeySystemOf(const std::string& key_system,
- const std::string& base) {
+bool IsSubKeySystemOf(const std::string& key_system, const std::string& base) {
std::string prefix = base + '.';
return key_system.substr(0, prefix.size()) == prefix;
}
bool IsExternalClearKey(const std::string& key_system) {
return key_system == kExternalClearKey ||
- IsChildKeySystemOf(key_system, kExternalClearKey);
+ IsSubKeySystemOf(key_system, kExternalClearKey);
}
} // namespace media
diff --git a/chromium/media/base/key_system_names.h b/chromium/media/base/key_system_names.h
index 0ba1934a275..e7ed8840b1e 100644
--- a/chromium/media/base/key_system_names.h
+++ b/chromium/media/base/key_system_names.h
@@ -18,8 +18,8 @@ namespace media {
MEDIA_EXPORT bool IsClearKey(const std::string& key_system);
// Returns true if |key_system| is (reverse) sub-domain of |base|.
-MEDIA_EXPORT bool IsChildKeySystemOf(const std::string& key_system,
- const std::string& base);
+MEDIA_EXPORT bool IsSubKeySystemOf(const std::string& key_system,
+ const std::string& base);
// Returns true if |key_system| is External Clear Key, false otherwise.
MEDIA_EXPORT bool IsExternalClearKey(const std::string& key_system);
diff --git a/chromium/media/base/key_system_properties.h b/chromium/media/base/key_system_properties.h
index 032f745fd42..0cd832ff69a 100644
--- a/chromium/media/base/key_system_properties.h
+++ b/chromium/media/base/key_system_properties.h
@@ -40,9 +40,17 @@ class MEDIA_EXPORT KeySystemProperties {
virtual SupportedCodecs GetSupportedHwSecureCodecs() const;
// Returns the configuration rule for supporting a robustness requirement.
+ // If `hw_secure_requirement` is true, then the key system already has a HW
+ // secure requirement, if false then it already has a requirement to disallow
+ // HW secure; if null then there is no HW secure requirement to apply. This
+ // does not imply that `requested_robustness` should be ignored, both rules
+ // must be applied.
+ // TODO(crbug.com/1204284): Refactor this and remove the
+ // `hw_secure_requirement` argument.
virtual EmeConfigRule GetRobustnessConfigRule(
EmeMediaType media_type,
- const std::string& requested_robustness) const = 0;
+ const std::string& requested_robustness,
+ const bool* hw_secure_requirement) const = 0;
// Returns the support this key system provides for persistent-license
// sessions.
diff --git a/chromium/media/base/key_systems.cc b/chromium/media/base/key_systems.cc
index c05c68495e6..03c1007bcd2 100644
--- a/chromium/media/base/key_systems.cc
+++ b/chromium/media/base/key_systems.cc
@@ -162,7 +162,8 @@ class ClearKeyProperties : public KeySystemProperties {
EmeConfigRule GetRobustnessConfigRule(
EmeMediaType media_type,
- const std::string& requested_robustness) const override {
+ const std::string& requested_robustness,
+ const bool* /*hw_secure_requirement*/) const override {
return requested_robustness.empty() ? EmeConfigRule::SUPPORTED
: EmeConfigRule::NOT_SUPPORTED;
}
@@ -219,7 +220,7 @@ static bool IsPotentiallySupportedKeySystem(const std::string& key_system) {
// Chromecast defines behaviors for Cast clients within its reverse domain.
const char kChromecastRoot[] = "com.chromecast";
- if (IsChildKeySystemOf(key_system, kChromecastRoot))
+ if (IsSubKeySystemOf(key_system, kChromecastRoot))
return true;
// Implementations that do not have a specification or appropriate glue code
@@ -264,7 +265,8 @@ class KeySystemsImpl : public KeySystems {
EmeConfigRule GetRobustnessConfigRule(
const std::string& key_system,
EmeMediaType media_type,
- const std::string& requested_robustness) const override;
+ const std::string& requested_robustness,
+ const bool* hw_secure_requirement) const override;
EmeSessionTypeSupport GetPersistentLicenseSessionSupport(
const std::string& key_system) const override;
@@ -711,7 +713,8 @@ EmeConfigRule KeySystemsImpl::GetContentTypeConfigRule(
EmeConfigRule KeySystemsImpl::GetRobustnessConfigRule(
const std::string& key_system,
EmeMediaType media_type,
- const std::string& requested_robustness) const {
+ const std::string& requested_robustness,
+ const bool* hw_secure_requirement) const {
DCHECK(thread_checker_.CalledOnValidThread());
auto key_system_iter = key_system_properties_map_.find(key_system);
@@ -719,8 +722,8 @@ EmeConfigRule KeySystemsImpl::GetRobustnessConfigRule(
NOTREACHED();
return EmeConfigRule::NOT_SUPPORTED;
}
- return key_system_iter->second->GetRobustnessConfigRule(media_type,
- requested_robustness);
+ return key_system_iter->second->GetRobustnessConfigRule(
+ media_type, requested_robustness, hw_secure_requirement);
}
EmeSessionTypeSupport KeySystemsImpl::GetPersistentLicenseSessionSupport(
diff --git a/chromium/media/base/key_systems.h b/chromium/media/base/key_systems.h
index 34fd6a46602..9d2e2b7fc26 100644
--- a/chromium/media/base/key_systems.h
+++ b/chromium/media/base/key_systems.h
@@ -56,10 +56,18 @@ class MEDIA_EXPORT KeySystems {
const std::vector<std::string>& codecs) const = 0;
// Returns the configuration rule for supporting a robustness requirement.
+ // If `hw_secure_requirement` is true, then the key system already has a HW
+ // secure requirement, if false then it already has a requirement to disallow
+ // HW secure; if null then there is no HW secure requirement to apply. This
+ // does not imply that `requested_robustness` should be ignored, both rules
+ // must be applied.
+ // TODO(crbug.com/1204284): Refactor this and remove the
+ // `hw_secure_requirement` argument.
virtual EmeConfigRule GetRobustnessConfigRule(
const std::string& key_system,
EmeMediaType media_type,
- const std::string& requested_robustness) const = 0;
+ const std::string& requested_robustness,
+ const bool* hw_secure_requirement) const = 0;
// Returns the support |key_system| provides for persistent-license sessions.
virtual EmeSessionTypeSupport GetPersistentLicenseSessionSupport(
diff --git a/chromium/media/base/key_systems_unittest.cc b/chromium/media/base/key_systems_unittest.cc
index e38e2b33c2b..4a21bb67c4b 100644
--- a/chromium/media/base/key_systems_unittest.cc
+++ b/chromium/media/base/key_systems_unittest.cc
@@ -76,7 +76,8 @@ class TestKeySystemPropertiesBase : public KeySystemProperties {
EmeConfigRule GetRobustnessConfigRule(
EmeMediaType media_type,
- const std::string& requested_robustness) const override {
+ const std::string& requested_robustness,
+ const bool* /*hw_secure_requirement*/) const override {
return requested_robustness.empty() ? EmeConfigRule::SUPPORTED
: EmeConfigRule::NOT_SUPPORTED;
}
@@ -140,7 +141,8 @@ class ExternalKeySystemProperties : public TestKeySystemPropertiesBase {
EmeConfigRule GetRobustnessConfigRule(
EmeMediaType media_type,
- const std::string& requested_robustness) const override {
+ const std::string& requested_robustness,
+ const bool* /*hw_secure_requirement*/) const override {
if (requested_robustness == kRobustnessSupported)
return EmeConfigRule::SUPPORTED;
else if (requested_robustness == kRobustnessSecureCodecsRequired)
@@ -206,7 +208,7 @@ bool IsSupportedKeySystem(const std::string& key_system) {
EmeConfigRule GetRobustnessConfigRule(const std::string& requested_robustness) {
return KeySystems::GetInstance()->GetRobustnessConfigRule(
- kExternal, EmeMediaType::VIDEO, requested_robustness);
+ kExternal, EmeMediaType::VIDEO, requested_robustness, nullptr);
}
// Adds test container and codec masks.
@@ -268,7 +270,7 @@ class TestMediaClient : public MediaClient {
// test the key system update case.
void DisableExternalKeySystemSupport();
- base::Optional<::media::AudioRendererAlgorithmParameters>
+ absl::optional<::media::AudioRendererAlgorithmParameters>
GetAudioRendererAlgorithmParameters(AudioParameters audio_parameters) final;
private:
@@ -317,10 +319,10 @@ void TestMediaClient::DisableExternalKeySystemSupport() {
supports_external_key_system_ = false;
}
-base::Optional<::media::AudioRendererAlgorithmParameters>
+absl::optional<::media::AudioRendererAlgorithmParameters>
TestMediaClient::GetAudioRendererAlgorithmParameters(
AudioParameters audio_parameters) {
- return base::nullopt;
+ return absl::nullopt;
}
} // namespace
diff --git a/chromium/media/base/limits.h b/chromium/media/base/limits.h
index edc8fc6a39e..5430e09c1cb 100644
--- a/chromium/media/base/limits.h
+++ b/chromium/media/base/limits.h
@@ -32,6 +32,9 @@ enum {
// restriction.
// - Most PC audio hardware is limited to 192 kHz, some specialized DAC
// devices will use 768 kHz though.
+ //
+ // kMaxSampleRate should be updated with
+ // blink::audio_utilities::MaxAudioBufferSampleRate()
kMaxSampleRate = 768000,
kMinSampleRate = 3000,
kMaxChannels = 32,
diff --git a/chromium/media/base/localized_strings.h b/chromium/media/base/localized_strings.h
index 9ee50b18bb7..48779b0af56 100644
--- a/chromium/media/base/localized_strings.h
+++ b/chromium/media/base/localized_strings.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_BASE_MEDIA_LOCALIZED_STRINGS_H_
-#define MEDIA_BASE_MEDIA_LOCALIZED_STRINGS_H_
+#ifndef MEDIA_BASE_LOCALIZED_STRINGS_H_
+#define MEDIA_BASE_LOCALIZED_STRINGS_H_
#include <string>
@@ -46,4 +46,4 @@ std::u16string GetLocalizedStringUTF16(MessageId message_id);
} // namespace media
-#endif // MEDIA_BASE_MEDIA_LOCALIZED_STRINGS_H_
+#endif // MEDIA_BASE_LOCALIZED_STRINGS_H_
diff --git a/chromium/media/base/mac/videotoolbox_helpers.cc b/chromium/media/base/mac/videotoolbox_helpers.cc
index 014cd2a05dd..25c7b864933 100644
--- a/chromium/media/base/mac/videotoolbox_helpers.cc
+++ b/chromium/media/base/mac/videotoolbox_helpers.cc
@@ -74,6 +74,10 @@ class RawAnnexBBuffer : public AnnexBBuffer {
: annexb_buffer_(annexb_buffer),
annexb_buffer_size_(annexb_buffer_size),
annexb_buffer_offset_(0) {}
+ RawAnnexBBuffer() = delete;
+ RawAnnexBBuffer(const RawAnnexBBuffer&) = delete;
+ RawAnnexBBuffer& operator=(const RawAnnexBBuffer&) = delete;
+
bool Reserve(size_t size) override {
reserved_size_ = size;
return size <= annexb_buffer_size_;
@@ -90,14 +94,16 @@ class RawAnnexBBuffer : public AnnexBBuffer {
size_t annexb_buffer_size_;
size_t annexb_buffer_offset_;
size_t reserved_size_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(RawAnnexBBuffer);
};
class StringAnnexBBuffer : public AnnexBBuffer {
public:
explicit StringAnnexBBuffer(std::string* str_annexb_buffer)
: str_annexb_buffer_(str_annexb_buffer) {}
+ StringAnnexBBuffer() = delete;
+ StringAnnexBBuffer(const StringAnnexBBuffer&) = delete;
+ StringAnnexBBuffer& operator=(const StringAnnexBBuffer&) = delete;
+
bool Reserve(size_t size) override {
str_annexb_buffer_->reserve(size);
return true;
@@ -109,7 +115,6 @@ class StringAnnexBBuffer : public AnnexBBuffer {
private:
std::string* str_annexb_buffer_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(StringAnnexBBuffer);
};
template <typename NalSizeType>
diff --git a/chromium/media/base/media_client.h b/chromium/media/base/media_client.h
index 5c7d6c06c68..db1d3091990 100644
--- a/chromium/media/base/media_client.h
+++ b/chromium/media/base/media_client.h
@@ -9,7 +9,6 @@
#include <string>
#include <vector>
-#include "base/optional.h"
#include "media/base/audio_codecs.h"
#include "media/base/audio_parameters.h"
#include "media/base/key_system_properties.h"
@@ -17,6 +16,7 @@
#include "media/base/media_types.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/color_space.h"
#include "url/gurl.h"
@@ -61,7 +61,7 @@ class MEDIA_EXPORT MediaClient {
virtual bool IsSupportedBitstreamAudioCodec(AudioCodec codec) = 0;
// Optionally returns audio renderer algorithm parameters.
- virtual base::Optional<::media::AudioRendererAlgorithmParameters>
+ virtual absl::optional<::media::AudioRendererAlgorithmParameters>
GetAudioRendererAlgorithmParameters(AudioParameters audio_parameters) = 0;
};
diff --git a/chromium/media/base/media_drm_storage.h b/chromium/media/base/media_drm_storage.h
index ac17314bc3e..d691f232b60 100644
--- a/chromium/media/base/media_drm_storage.h
+++ b/chromium/media/base/media_drm_storage.h
@@ -14,9 +14,9 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "media/base/media_drm_key_type.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/origin.h"
namespace base {
@@ -32,7 +32,7 @@ class MEDIA_EXPORT MediaDrmStorage
public:
// When using per-origin provisioning, this is the ID for the origin.
// If not specified, the device specific origin ID is to be used.
- using MediaDrmOriginId = base::Optional<base::UnguessableToken>;
+ using MediaDrmOriginId = absl::optional<base::UnguessableToken>;
struct MEDIA_EXPORT SessionData {
SessionData(std::vector<uint8_t> key_set_id,
diff --git a/chromium/media/base/media_log.h b/chromium/media/base/media_log.h
index dc3ea25be66..46b52ae5587 100644
--- a/chromium/media/base/media_log.h
+++ b/chromium/media/base/media_log.h
@@ -214,8 +214,9 @@ class MEDIA_EXPORT LogHelper {
// Provides a stringstream to collect a log entry to pass to the provided
// MediaLog at the requested level.
-#define MEDIA_LOG(level, media_log) \
- LogHelper((MediaLogMessageLevel::k##level), (media_log)).stream()
+#define MEDIA_LOG(level, media_log) \
+ media::LogHelper((media::MediaLogMessageLevel::k##level), (media_log)) \
+ .stream()
// Logs only while |count| < |max|, increments |count| for each log, and warns
// in the log if |count| has just reached |max|.
diff --git a/chromium/media/base/media_serializers.h b/chromium/media/base/media_serializers.h
index 5dbff1ba7fb..a91f8bc2413 100644
--- a/chromium/media/base/media_serializers.h
+++ b/chromium/media/base/media_serializers.h
@@ -61,8 +61,8 @@ struct MediaSerializer<std::vector<VecType>> {
// serialize optional types
template <typename OptType>
-struct MediaSerializer<base::Optional<OptType>> {
- static base::Value Serialize(const base::Optional<OptType>& opt) {
+struct MediaSerializer<absl::optional<OptType>> {
+ static base::Value Serialize(const absl::optional<OptType>& opt) {
return opt ? MediaSerializer<OptType>::Serialize(opt.value())
: base::Value("unset"); // TODO(tmathmeyer) maybe empty string?
}
diff --git a/chromium/media/base/media_serializers_unittest.cc b/chromium/media/base/media_serializers_unittest.cc
index e3f3a7bfc5c..466155569b8 100644
--- a/chromium/media/base/media_serializers_unittest.cc
+++ b/chromium/media/base/media_serializers_unittest.cc
@@ -41,7 +41,7 @@ TEST(MediaSerializersTest, BaseTypes) {
}
TEST(MediaSerializersTest, Optional) {
- base::Optional<int> foo;
+ absl::optional<int> foo;
ASSERT_EQ(ToString(MediaSerialize(foo)), "unset");
foo = 1;
diff --git a/chromium/media/base/media_switches.cc b/chromium/media/base/media_switches.cc
index 065ff8a0bd6..7c6ca90d52a 100644
--- a/chromium/media/base/media_switches.cc
+++ b/chromium/media/base/media_switches.cc
@@ -9,6 +9,14 @@
#include "build/chromeos_buildflags.h"
#include "components/system_media_controls/linux/buildflags/buildflags.h"
+#if defined(OS_LINUX)
+#include "base/cpu.h"
+#endif
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "ash/constants/ash_features.h"
+#endif
+
namespace switches {
// Allow users to specify a custom buffer size for debugging purpose.
@@ -91,8 +99,8 @@ const char kUseCras[] = "use-cras";
#endif // defined(USE_CRAS)
// For automated testing of protected content, this switch allows specific
-// domains (e.g. example.com) to skip asking the user for permission to share
-// the protected media identifier. In this context, domain does not include the
+// domains (e.g. example.com) to always allow the permission to share the
+// protected media identifier. In this context, domain does not include the
// port number. User's content settings will not be affected by enabling this
// switch.
// Reference: http://crbug.com/718608
@@ -178,7 +186,8 @@ const char kOverrideEnabledCdmInterfaceVersion[] =
// Overrides hardware secure codecs support for testing. If specified, real
// platform hardware secure codecs check will be skipped. Codecs are separated
-// by comma. Valid codecs are "vp8", "vp9" and "avc1". For example:
+// by comma. Valid video codecs are "vp8", "vp9" and "avc1", and the only valid
+// audio codec is "vorbis". For example:
// --override-hardware-secure-codecs-for-testing=vp8,vp9
// --override-hardware-secure-codecs-for-testing=avc1
// CENC encryption scheme is assumed to be supported for the specified codecs.
@@ -331,7 +340,7 @@ const base::Feature kD3D11PrintCodecOnCrash{"D3D11PrintCodecOnCrash",
// Enable The D3D11 Video decoder.
const base::Feature kD3D11VideoDecoder{"D3D11VideoDecoder",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
// Tell D3D11VideoDecoder to ignore workarounds for zero copy. Requires that
// kD3D11VideoDecoder is enabled.
@@ -452,7 +461,7 @@ const base::Feature kSuspendMutedAudio{"SuspendMutedAudio",
// Enables using the media history store to store media engagement metrics.
const base::Feature kUseMediaHistoryStore{"UseMediaHistoryStore",
- base::FEATURE_ENABLED_BY_DEFAULT};
+ base::FEATURE_DISABLED_BY_DEFAULT};
// Use R16 texture for 9-16 bit channel instead of half-float conversion by CPU.
const base::Feature kUseR16Texture{"use-r16-texture",
@@ -517,17 +526,9 @@ const base::Feature kVideoBlitColorAccuracy{"video-blit-color-accuracy",
const base::Feature kExternalClearKeyForTesting{
"ExternalClearKeyForTesting", base::FEATURE_DISABLED_BY_DEFAULT};
-// Enables the Live Caption feature.
-const base::Feature kLiveCaption {
- "LiveCaption",
-#if defined(OS_CHROMEOS)
- // TODO(crbug.com/1209058): Remove this special case after it's merged
- // into M91.
- base::FEATURE_DISABLED_BY_DEFAULT
-#else
- base::FEATURE_ENABLED_BY_DEFAULT
-#endif
-};
+// Enables the Live Caption feature on supported devices.
+const base::Feature kLiveCaption{"LiveCaption",
+ base::FEATURE_ENABLED_BY_DEFAULT};
// Use the Speech On-Device API (SODA) to power the Live Caption feature instead
// of the Cloud-based Open Speech API.
@@ -631,11 +632,6 @@ const base::Feature kMediaDrmPreprovisioning{"MediaDrmPreprovisioning",
const base::Feature kMediaDrmPreprovisioningAtStartup{
"MediaDrmPreprovisioningAtStartup", base::FEATURE_ENABLED_BY_DEFAULT};
-// Prevents using SurfaceLayer for videos. This is meant to be used by embedders
-// that cannot support SurfaceLayer at the moment.
-const base::Feature kDisableSurfaceLayerForVideo{
- "DisableSurfaceLayerForVideo", base::FEATURE_DISABLED_BY_DEFAULT};
-
// Enable picture in picture web api for android.
const base::Feature kPictureInPictureAPI{"PictureInPictureAPI",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -859,6 +855,10 @@ const base::Feature kUseFakeDeviceForMediaStream{
const base::Feature kBresenhamCadence{"BresenhamCadence",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Display the playback speed button on the media controls.
+const base::Feature kPlaybackSpeedButton{"PlaybackSpeedButton",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
bool IsVideoCaptureAcceleratedJpegDecodingEnabled() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableAcceleratedMjpegDecode)) {
@@ -874,4 +874,35 @@ bool IsVideoCaptureAcceleratedJpegDecodingEnabled() {
return false;
}
+bool IsLiveCaptionFeatureEnabled() {
+ if (!base::FeatureList::IsEnabled(media::kLiveCaption))
+ return false;
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+ // Some Chrome OS devices do not support on-device speech.
+ if (!base::FeatureList::IsEnabled(ash::features::kOnDeviceSpeechRecognition))
+ return false;
+#endif
+
+#if defined(OS_LINUX)
+ if (base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption)) {
+ // Check if the CPU has the required instruction set to run the Speech
+ // On-Device API (SODA) library.
+ static bool has_sse41 = base::CPU().has_sse41();
+ if (!has_sse41)
+ return false;
+ }
+#endif
+
+#if defined(OS_WIN) && defined(ARCH_CPU_ARM64)
+ if (base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption)) {
+ // The Speech On-Device API (SODA) component does not support Windows on
+ // arm64.
+ return false;
+ }
+#endif
+
+ return true;
+}
+
} // namespace media
diff --git a/chromium/media/base/media_switches.h b/chromium/media/base/media_switches.h
index 57ae439f02b..69b9cfcc7b8 100644
--- a/chromium/media/base/media_switches.h
+++ b/chromium/media/base/media_switches.h
@@ -10,6 +10,7 @@
#include <string>
#include "base/feature_list.h"
+#include "base/metrics/field_trial_params.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "media/base/media_export.h"
@@ -162,6 +163,7 @@ MEDIA_EXPORT extern const base::Feature kMediaSessionWebRTC;
MEDIA_EXPORT extern const base::Feature kMemoryPressureBasedSourceBufferGC;
MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo;
MEDIA_EXPORT extern const base::Feature kPictureInPicture;
+MEDIA_EXPORT extern const base::Feature kPlaybackSpeedButton;
MEDIA_EXPORT extern const base::Feature kPreloadMediaEngagementData;
MEDIA_EXPORT extern const base::Feature kPreloadMetadataLazyLoad;
MEDIA_EXPORT extern const base::Feature kPreloadMetadataSuspend;
@@ -205,7 +207,6 @@ MEDIA_EXPORT extern const base::Feature kMediaControlsExpandGesture;
MEDIA_EXPORT extern const base::Feature kMediaDrmPersistentLicense;
MEDIA_EXPORT extern const base::Feature kMediaDrmPreprovisioning;
MEDIA_EXPORT extern const base::Feature kMediaDrmPreprovisioningAtStartup;
-MEDIA_EXPORT extern const base::Feature kDisableSurfaceLayerForVideo;
MEDIA_EXPORT extern const base::Feature kCanPlayHls;
MEDIA_EXPORT extern const base::Feature kPictureInPictureAPI;
MEDIA_EXPORT extern const base::Feature kHlsPlayer;
@@ -246,6 +247,8 @@ MEDIA_EXPORT std::string GetEffectiveAutoplayPolicy(
MEDIA_EXPORT bool IsVideoCaptureAcceleratedJpegDecodingEnabled();
+MEDIA_EXPORT bool IsLiveCaptionFeatureEnabled();
+
enum class kCrosGlobalMediaControlsPinOptions {
kPin,
kNotPin,
diff --git a/chromium/media/base/media_url_demuxer.cc b/chromium/media/base/media_url_demuxer.cc
index cff132e69e2..734604a4a7f 100644
--- a/chromium/media/base/media_url_demuxer.cc
+++ b/chromium/media/base/media_url_demuxer.cc
@@ -83,9 +83,9 @@ int64_t MediaUrlDemuxer::GetMemoryUsage() const {
return 0;
}
-base::Optional<container_names::MediaContainerName>
+absl::optional<container_names::MediaContainerName>
MediaUrlDemuxer::GetContainerForMetrics() const {
- return base::nullopt;
+ return absl::nullopt;
}
void MediaUrlDemuxer::OnEnabledAudioTracksChanged(
diff --git a/chromium/media/base/media_url_demuxer.h b/chromium/media/base/media_url_demuxer.h
index 638cc9b14a7..4d497ebacec 100644
--- a/chromium/media/base/media_url_demuxer.h
+++ b/chromium/media/base/media_url_demuxer.h
@@ -58,7 +58,7 @@ class MEDIA_EXPORT MediaUrlDemuxer : public Demuxer {
base::TimeDelta GetStartTime() const override;
base::Time GetTimelineOffset() const override;
int64_t GetMemoryUsage() const override;
- base::Optional<container_names::MediaContainerName> GetContainerForMetrics()
+ absl::optional<container_names::MediaContainerName> GetContainerForMetrics()
const override;
void OnEnabledAudioTracksChanged(const std::vector<MediaTrack::Id>& track_ids,
base::TimeDelta curr_time,
diff --git a/chromium/media/base/memory_dump_provider_proxy.h b/chromium/media/base/memory_dump_provider_proxy.h
index 0473c79403d..0bdda75b7c5 100644
--- a/chromium/media/base/memory_dump_provider_proxy.h
+++ b/chromium/media/base/memory_dump_provider_proxy.h
@@ -8,10 +8,6 @@
#include <stddef.h>
#include <stdint.h>
-#include <memory>
-#include <string>
-#include <utility>
-
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/media/base/mock_filters.cc b/chromium/media/base/mock_filters.cc
index 4bf36edf546..981c4363d84 100644
--- a/chromium/media/base/mock_filters.cc
+++ b/chromium/media/base/mock_filters.cc
@@ -169,12 +169,12 @@ MockCdmContext::MockCdmContext() = default;
MockCdmContext::~MockCdmContext() = default;
-base::Optional<base::UnguessableToken> MockCdmContext::GetCdmId() const {
+absl::optional<base::UnguessableToken> MockCdmContext::GetCdmId() const {
return cdm_id_;
}
void MockCdmContext::set_cdm_id(const base::UnguessableToken& cdm_id) {
- cdm_id_ = base::make_optional(cdm_id);
+ cdm_id_ = absl::make_optional(cdm_id);
}
MockCdmPromise::MockCdmPromise(bool expect_success) {
diff --git a/chromium/media/base/mock_filters.h b/chromium/media/base/mock_filters.h
index 281afd56335..e70cb8c6d9f 100644
--- a/chromium/media/base/mock_filters.h
+++ b/chromium/media/base/mock_filters.h
@@ -69,7 +69,7 @@ class MockPipelineClient : public Pipeline::Client {
MOCK_METHOD1(OnVideoConfigChange, void(const VideoDecoderConfig&));
MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&));
MOCK_METHOD1(OnVideoOpacityChange, void(bool));
- MOCK_METHOD1(OnVideoFrameRateChange, void(base::Optional<int>));
+ MOCK_METHOD1(OnVideoFrameRateChange, void(absl::optional<int>));
MOCK_METHOD0(OnVideoAverageKeyframeDistanceUpdate, void());
MOCK_METHOD1(OnAudioDecoderChange, void(const AudioDecoderInfo&));
MOCK_METHOD1(OnVideoDecoderChange, void(const VideoDecoderInfo&));
@@ -103,7 +103,7 @@ class MockPipeline : public Pipeline {
MOCK_METHOD2(OnEnabledAudioTracksChanged,
void(const std::vector<MediaTrack::Id>&, base::OnceClosure));
MOCK_METHOD2(OnSelectedVideoTrackChanged,
- void(base::Optional<MediaTrack::Id>, base::OnceClosure));
+ void(absl::optional<MediaTrack::Id>, base::OnceClosure));
// TODO(sandersd): This should automatically return true between Start() and
// Stop(). (Or better, remove it from the interface entirely.)
@@ -116,7 +116,7 @@ class MockPipeline : public Pipeline {
MOCK_METHOD1(SetPlaybackRate, void(double));
MOCK_CONST_METHOD0(GetVolume, float());
MOCK_METHOD1(SetVolume, void(float));
- MOCK_METHOD1(SetLatencyHint, void(base::Optional<base::TimeDelta>));
+ MOCK_METHOD1(SetLatencyHint, void(absl::optional<base::TimeDelta>));
MOCK_METHOD1(SetPreservesPitch, void(bool));
MOCK_METHOD1(SetAutoplayInitiated, void(bool));
@@ -175,7 +175,7 @@ class MockDemuxer : public Demuxer {
MOCK_CONST_METHOD0(GetTimelineOffset, base::Time());
MOCK_CONST_METHOD0(GetMemoryUsage, int64_t());
MOCK_CONST_METHOD0(GetContainerForMetrics,
- base::Optional<container_names::MediaContainerName>());
+ absl::optional<container_names::MediaContainerName>());
MOCK_METHOD3(OnEnabledAudioTracksChanged,
void(const std::vector<MediaTrack::Id>&,
base::TimeDelta,
@@ -401,7 +401,7 @@ class MockRendererClient : public RendererClient {
MOCK_METHOD1(OnVideoConfigChange, void(const VideoDecoderConfig&));
MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&));
MOCK_METHOD1(OnVideoOpacityChange, void(bool));
- MOCK_METHOD1(OnVideoFrameRateChange, void(base::Optional<int>));
+ MOCK_METHOD1(OnVideoFrameRateChange, void(absl::optional<int>));
MOCK_METHOD1(OnDurationChange, void(base::TimeDelta));
MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
MOCK_METHOD0(IsVideoStreamAvailable, bool());
@@ -431,7 +431,7 @@ class MockVideoRenderer : public VideoRenderer {
MOCK_METHOD0(OnTimeProgressing, void());
MOCK_METHOD0(OnTimeStopped, void());
MOCK_METHOD1(SetLatencyHint,
- void(base::Optional<base::TimeDelta> latency_hint));
+ void(absl::optional<base::TimeDelta> latency_hint));
private:
DISALLOW_COPY_AND_ASSIGN(MockVideoRenderer);
@@ -459,7 +459,7 @@ class MockAudioRenderer : public AudioRenderer {
MOCK_METHOD0(StartPlaying, void());
MOCK_METHOD1(SetVolume, void(float volume));
MOCK_METHOD1(SetLatencyHint,
- void(base::Optional<base::TimeDelta> latency_hint));
+ void(absl::optional<base::TimeDelta> latency_hint));
MOCK_METHOD1(SetPreservesPitch, void(bool));
MOCK_METHOD1(SetAutoplayInitiated, void(bool));
@@ -482,7 +482,7 @@ class MockRenderer : public Renderer {
void(MediaResource* media_resource,
RendererClient* client,
PipelineStatusCallback& init_cb));
- MOCK_METHOD1(SetLatencyHint, void(base::Optional<base::TimeDelta>));
+ MOCK_METHOD1(SetLatencyHint, void(absl::optional<base::TimeDelta>));
MOCK_METHOD1(SetPreservesPitch, void(bool));
MOCK_METHOD1(SetAutoplayInitiated, void(bool));
void Flush(base::OnceClosure flush_cb) override { OnFlush(flush_cb); }
@@ -638,12 +638,12 @@ class MockCdmContext : public CdmContext {
bool(GetMediaFoundationCdmProxyCB get_mf_cdm_proxy_cb));
#endif
- base::Optional<base::UnguessableToken> GetCdmId() const override;
+ absl::optional<base::UnguessableToken> GetCdmId() const override;
void set_cdm_id(const base::UnguessableToken& cdm_id);
private:
- base::Optional<base::UnguessableToken> cdm_id_;
+ absl::optional<base::UnguessableToken> cdm_id_;
DISALLOW_COPY_AND_ASSIGN(MockCdmContext);
};
@@ -830,7 +830,7 @@ class MockMediaClient : public media::MediaClient {
MOCK_METHOD1(IsSupportedVideoType, bool(const media::VideoType& type));
MOCK_METHOD1(IsSupportedBitstreamAudioCodec, bool(media::AudioCodec codec));
MOCK_METHOD1(GetAudioRendererAlgorithmParameters,
- base::Optional<::media::AudioRendererAlgorithmParameters>(
+ absl::optional<::media::AudioRendererAlgorithmParameters>(
media::AudioParameters audio_parameters));
private:
diff --git a/chromium/media/base/offloading_audio_encoder_unittest.cc b/chromium/media/base/offloading_audio_encoder_unittest.cc
index b1377ae44c8..a3bbe6482f4 100644
--- a/chromium/media/base/offloading_audio_encoder_unittest.cc
+++ b/chromium/media/base/offloading_audio_encoder_unittest.cc
@@ -55,7 +55,7 @@ TEST_F(OffloadingAudioEncoderTest, Initialize) {
bool called_output = false;
AudioEncoder::Options options;
AudioEncoder::OutputCB output_cb = base::BindLambdaForTesting(
- [&](EncodedAudioBuffer, base::Optional<AudioEncoder::CodecDescription>) {
+ [&](EncodedAudioBuffer, absl::optional<AudioEncoder::CodecDescription>) {
EXPECT_TRUE(callback_runner_->RunsTasksInCurrentSequence());
called_output = true;
});
diff --git a/chromium/media/base/offloading_video_encoder_unittest.cc b/chromium/media/base/offloading_video_encoder_unittest.cc
index 8b2bc0a28b5..570c7dd98b6 100644
--- a/chromium/media/base/offloading_video_encoder_unittest.cc
+++ b/chromium/media/base/offloading_video_encoder_unittest.cc
@@ -57,7 +57,7 @@ TEST_F(OffloadingVideoEncoderTest, Initialize) {
VideoEncoder::Options options;
VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
- [&](VideoEncoderOutput, base::Optional<VideoEncoder::CodecDescription>) {
+ [&](VideoEncoderOutput, absl::optional<VideoEncoder::CodecDescription>) {
EXPECT_TRUE(callback_runner_->RunsTasksInCurrentSequence());
called_output = true;
});
@@ -111,7 +111,7 @@ TEST_F(OffloadingVideoEncoderTest, ChangeOptions) {
});
VideoEncoder::OutputCB output_cb = base::BindRepeating(
- [](VideoEncoderOutput, base::Optional<VideoEncoder::CodecDescription>) {
+ [](VideoEncoderOutput, absl::optional<VideoEncoder::CodecDescription>) {
});
EXPECT_CALL(*mock_video_encoder_, ChangeOptions(_, _, _))
diff --git a/chromium/media/base/overlay_info.h b/chromium/media/base/overlay_info.h
index 603a2208f86..f0f1e6448ed 100644
--- a/chromium/media/base/overlay_info.h
+++ b/chromium/media/base/overlay_info.h
@@ -7,16 +7,16 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "base/unguessable_token.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
struct MEDIA_EXPORT OverlayInfo {
// An unset routing token indicates "do not use any routing token". A null
// routing token isn't serializable, else we'd probably use that instead.
- using RoutingToken = base::Optional<base::UnguessableToken>;
+ using RoutingToken = absl::optional<base::UnguessableToken>;
OverlayInfo();
OverlayInfo(const OverlayInfo&);
diff --git a/chromium/media/base/pipeline.h b/chromium/media/base/pipeline.h
index 3e1180fb019..ffa8ad8a029 100644
--- a/chromium/media/base/pipeline.h
+++ b/chromium/media/base/pipeline.h
@@ -8,7 +8,6 @@
#include <memory>
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "base/time/time.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/buffering_state.h"
@@ -22,6 +21,7 @@
#include "media/base/video_decoder_config.h"
#include "media/base/video_transformation.h"
#include "media/base/waiting.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
@@ -85,7 +85,7 @@ class MEDIA_EXPORT Pipeline {
// Executed whenever the video frame rate changes. |fps| will be unset if
// the frame rate is unstable. The duration used for the frame rate is
// based on wall clock time, not media time.
- virtual void OnVideoFrameRateChange(base::Optional<int> fps) = 0;
+ virtual void OnVideoFrameRateChange(absl::optional<int> fps) = 0;
};
virtual ~Pipeline() {}
@@ -148,7 +148,7 @@ class MEDIA_EXPORT Pipeline {
// |selected_track_id| is either empty, which means no video track is
// selected, or contains the selected video track id.
virtual void OnSelectedVideoTrackChanged(
- base::Optional<MediaTrack::Id> selected_track_id,
+ absl::optional<MediaTrack::Id> selected_track_id,
base::OnceClosure change_completed_cb) = 0;
// Stops the pipeline. This is a blocking function.
@@ -223,7 +223,7 @@ class MEDIA_EXPORT Pipeline {
// post-decode buffering required to start playback or resume from
// seek/underflow. A null option indicates the hint is unset and the pipeline
// can choose its own default.
- virtual void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) = 0;
+ virtual void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) = 0;
// Sets whether pitch adjustment should be applied when the playback rate is
// different than 1.0.
diff --git a/chromium/media/base/pipeline_impl.cc b/chromium/media/base/pipeline_impl.cc
index 9eeeb52b324..f29e529019c 100644
--- a/chromium/media/base/pipeline_impl.cc
+++ b/chromium/media/base/pipeline_impl.cc
@@ -71,7 +71,7 @@ class PipelineImpl::RendererWrapper final : public DemuxerHost,
void Resume(std::unique_ptr<Renderer> default_renderer, base::TimeDelta time);
void SetPlaybackRate(double playback_rate);
void SetVolume(float volume);
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint);
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint);
void SetPreservesPitch(bool preserves_pitch);
void SetAutoplayInitiated(bool autoplay_initiated);
base::TimeDelta GetMediaTime() const;
@@ -88,7 +88,7 @@ class PipelineImpl::RendererWrapper final : public DemuxerHost,
// |selected_track_id| is either empty, which means no video track is
// selected, or contains the selected video track id.
void OnSelectedVideoTrackChanged(
- base::Optional<MediaTrack::Id> selected_track_id,
+ absl::optional<MediaTrack::Id> selected_track_id,
base::OnceClosure change_completed_cb);
private:
@@ -150,7 +150,7 @@ class PipelineImpl::RendererWrapper final : public DemuxerHost,
void OnVideoConfigChange(const VideoDecoderConfig& config) final;
void OnVideoNaturalSizeChange(const gfx::Size& size) final;
void OnVideoOpacityChange(bool opaque) final;
- void OnVideoFrameRateChange(base::Optional<int> fps) final;
+ void OnVideoFrameRateChange(absl::optional<int> fps) final;
// Common handlers for notifications from renderers and demuxer.
void OnPipelineError(PipelineStatus error);
@@ -194,7 +194,7 @@ class PipelineImpl::RendererWrapper final : public DemuxerHost,
double playback_rate_;
float volume_;
- base::Optional<base::TimeDelta> latency_hint_;
+ absl::optional<base::TimeDelta> latency_hint_;
CdmContext* cdm_context_;
// By default, apply pitch adjustments.
@@ -480,7 +480,7 @@ void PipelineImpl::RendererWrapper::SetVolume(float volume) {
}
void PipelineImpl::RendererWrapper::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
DCHECK(media_task_runner_->BelongsToCurrentThread());
if (latency_hint_ == latency_hint)
@@ -580,16 +580,16 @@ void PipelineImpl::RendererWrapper::CreateRendererInternal(
DCHECK(cdm_context_ || !HasEncryptedStream())
<< "CDM should be available now if has encrypted stream";
- base::Optional<RendererFactoryType> factory_type;
+ absl::optional<RendererType> renderer_type;
#if defined(OS_WIN)
if (cdm_context_ && cdm_context_->RequiresMediaFoundationRenderer())
- factory_type = RendererFactoryType::kMediaFoundation;
+ renderer_type = RendererType::kMediaFoundation;
#endif // defined(OS_WIN)
// TODO(xhwang): During Resume(), the |default_renderer_| might already match
- // the |factory_type|, in which case we shouldn't need to create a new one.
- if (!default_renderer_ || factory_type) {
+ // the |renderer_type|, in which case we shouldn't need to create a new one.
+ if (!default_renderer_ || renderer_type) {
// Create the Renderer asynchronously on the main task runner. Use
// BindToCurrentLoop to call OnRendererCreated() on the media task runner.
auto renderer_created_cb = BindToCurrentLoop(
@@ -598,7 +598,7 @@ void PipelineImpl::RendererWrapper::CreateRendererInternal(
main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&PipelineImpl::AsyncCreateRenderer, weak_pipeline_,
- factory_type, std::move(renderer_created_cb)));
+ renderer_type, std::move(renderer_created_cb)));
return;
}
@@ -701,7 +701,7 @@ void PipelineImpl::RendererWrapper::OnEnabledAudioTracksChanged(
}
void PipelineImpl::OnSelectedVideoTrackChanged(
- base::Optional<MediaTrack::Id> selected_track_id,
+ absl::optional<MediaTrack::Id> selected_track_id,
base::OnceClosure change_completed_cb) {
DCHECK(thread_checker_.CalledOnValidThread());
media_task_runner_->PostTask(
@@ -713,7 +713,7 @@ void PipelineImpl::OnSelectedVideoTrackChanged(
}
void PipelineImpl::RendererWrapper::OnSelectedVideoTrackChanged(
- base::Optional<MediaTrack::Id> selected_track_id,
+ absl::optional<MediaTrack::Id> selected_track_id,
base::OnceClosure change_completed_cb) {
DCHECK(media_task_runner_->BelongsToCurrentThread());
@@ -856,7 +856,7 @@ void PipelineImpl::RendererWrapper::OnVideoOpacityChange(bool opaque) {
}
void PipelineImpl::RendererWrapper::OnVideoFrameRateChange(
- base::Optional<int> fps) {
+ absl::optional<int> fps) {
DCHECK(media_task_runner_->BelongsToCurrentThread());
main_task_runner_->PostTask(
@@ -1229,7 +1229,7 @@ void PipelineImpl::Start(StartType start_type,
// play. In this case, not creating a default renderer to reduce memory usage.
std::unique_ptr<Renderer> default_renderer;
if (start_type != StartType::kSuspendAfterMetadata)
- default_renderer = create_renderer_cb_.Run(base::nullopt);
+ default_renderer = create_renderer_cb_.Run(absl::nullopt);
media_task_runner_->PostTask(
FROM_HERE,
@@ -1317,7 +1317,7 @@ void PipelineImpl::Resume(base::TimeDelta time,
last_media_time_ = base::TimeDelta();
// Always create a default renderer for Resume().
- auto default_renderer = create_renderer_cb_.Run(base::nullopt);
+ auto default_renderer = create_renderer_cb_.Run(absl::nullopt);
media_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&RendererWrapper::Resume,
@@ -1383,7 +1383,7 @@ void PipelineImpl::SetVolume(float volume) {
}
void PipelineImpl::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
DVLOG(1) << __func__ << "("
<< (latency_hint
? base::NumberToString(latency_hint->InMilliseconds()) + "ms"
@@ -1507,12 +1507,12 @@ const char* PipelineImpl::GetStateString(State state) {
#undef RETURN_STRING
void PipelineImpl::AsyncCreateRenderer(
- base::Optional<RendererFactoryType> factory_type,
+ absl::optional<RendererType> renderer_type,
RendererCreatedCB renderer_created_cb) {
DVLOG(2) << __func__;
DCHECK(thread_checker_.CalledOnValidThread());
- std::move(renderer_created_cb).Run(create_renderer_cb_.Run(factory_type));
+ std::move(renderer_created_cb).Run(create_renderer_cb_.Run(renderer_type));
}
void PipelineImpl::OnError(PipelineStatus error) {
@@ -1603,7 +1603,7 @@ void PipelineImpl::OnVideoOpacityChange(bool opaque) {
client_->OnVideoOpacityChange(opaque);
}
-void PipelineImpl::OnVideoFrameRateChange(base::Optional<int> fps) {
+void PipelineImpl::OnVideoFrameRateChange(absl::optional<int> fps) {
DVLOG(2) << __func__;
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(IsRunning());
diff --git a/chromium/media/base/pipeline_impl.h b/chromium/media/base/pipeline_impl.h
index beb88adb2b6..3edada0a981 100644
--- a/chromium/media/base/pipeline_impl.h
+++ b/chromium/media/base/pipeline_impl.h
@@ -10,12 +10,12 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "media/base/media_export.h"
#include "media/base/pipeline.h"
#include "media/base/renderer.h"
#include "media/base/renderer_factory_selector.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace base {
class SingleThreadTaskRunner;
@@ -25,13 +25,13 @@ namespace media {
class MediaLog;
-// Callbacks used for Renderer creation. When the FactoryType is nullopt, the
+// Callbacks used for Renderer creation. When the RendererType is nullopt, the
// current base one will be created.
using CreateRendererCB = base::RepeatingCallback<std::unique_ptr<Renderer>(
- base::Optional<RendererFactoryType>)>;
+ absl::optional<RendererType>)>;
using RendererCreatedCB = base::OnceCallback<void(std::unique_ptr<Renderer>)>;
using AsyncCreateRendererCB =
- base::RepeatingCallback<void(base::Optional<RendererFactoryType>,
+ base::RepeatingCallback<void(absl::optional<RendererType>,
RendererCreatedCB)>;
// Pipeline runs the media pipeline. Filters are created and called on the
@@ -103,7 +103,7 @@ class MEDIA_EXPORT PipelineImpl : public Pipeline {
void SetPlaybackRate(double playback_rate) override;
float GetVolume() const override;
void SetVolume(float volume) override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void SetPreservesPitch(bool preserves_pitch) override;
void SetAutoplayInitiated(bool autoplay_initiated) override;
base::TimeDelta GetMediaTime() const override;
@@ -121,7 +121,7 @@ class MEDIA_EXPORT PipelineImpl : public Pipeline {
// |selected_track_id| is either empty, which means no video track is
// selected, or contains the selected video track id.
void OnSelectedVideoTrackChanged(
- base::Optional<MediaTrack::Id> selected_track_id,
+ absl::optional<MediaTrack::Id> selected_track_id,
base::OnceClosure change_completed_cb) override;
private:
@@ -146,7 +146,7 @@ class MEDIA_EXPORT PipelineImpl : public Pipeline {
// Create a Renderer asynchronously. Must be called on the main task runner
// and the callback will be called on the main task runner as well.
- void AsyncCreateRenderer(base::Optional<RendererFactoryType> factory_type,
+ void AsyncCreateRenderer(absl::optional<RendererType> renderer_type,
RendererCreatedCB renderer_created_cb);
// Notifications from RendererWrapper.
@@ -165,7 +165,7 @@ class MEDIA_EXPORT PipelineImpl : public Pipeline {
void OnAudioDecoderChange(const AudioDecoderInfo& info);
void OnVideoDecoderChange(const VideoDecoderInfo& info);
void OnRemotePlayStateChange(MediaStatus::State state);
- void OnVideoFrameRateChange(base::Optional<int> fps);
+ void OnVideoFrameRateChange(absl::optional<int> fps);
// Task completion callbacks from RendererWrapper.
void OnSeekDone(bool is_suspended);
diff --git a/chromium/media/base/pipeline_impl_unittest.cc b/chromium/media/base/pipeline_impl_unittest.cc
index 8ff37cf90bc..69a0bed8c75 100644
--- a/chromium/media/base/pipeline_impl_unittest.cc
+++ b/chromium/media/base/pipeline_impl_unittest.cc
@@ -295,7 +295,7 @@ class PipelineImplTest : public ::testing::Test {
}
std::unique_ptr<Renderer> CreateRenderer(
- base::Optional<RendererFactoryType> /* factory_type */) {
+ absl::optional<RendererType> /* renderer_type */) {
return std::move(scoped_renderer_);
}
diff --git a/chromium/media/base/pipeline_status.cc b/chromium/media/base/pipeline_status.cc
index ab7dfbee853..32c24f13563 100644
--- a/chromium/media/base/pipeline_status.cc
+++ b/chromium/media/base/pipeline_status.cc
@@ -8,7 +8,7 @@
namespace media {
-base::Optional<PipelineStatus> StatusCodeToPipelineStatus(StatusCode status) {
+absl::optional<PipelineStatus> StatusCodeToPipelineStatus(StatusCode status) {
switch (status) {
case StatusCode::kOk:
return PIPELINE_OK;
@@ -48,7 +48,7 @@ base::Optional<PipelineStatus> StatusCodeToPipelineStatus(StatusCode status) {
return DEMUXER_ERROR_DETECTED_HLS;
default:
NOTREACHED();
- return base::nullopt;
+ return absl::nullopt;
}
}
diff --git a/chromium/media/base/pipeline_status.h b/chromium/media/base/pipeline_status.h
index a9e448040de..cab7506d68d 100644
--- a/chromium/media/base/pipeline_status.h
+++ b/chromium/media/base/pipeline_status.h
@@ -10,12 +10,12 @@
#include <string>
#include "base/callback.h"
-#include "base/optional.h"
#include "base/time/time.h"
#include "media/base/decoder.h"
#include "media/base/media_export.h"
#include "media/base/status.h"
#include "media/base/timestamp_constants.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -62,7 +62,7 @@ enum PipelineStatus {
PIPELINE_STATUS_MAX = DEMUXER_ERROR_DETECTED_HLS,
};
-MEDIA_EXPORT base::Optional<PipelineStatus> StatusCodeToPipelineStatus(
+MEDIA_EXPORT absl::optional<PipelineStatus> StatusCodeToPipelineStatus(
StatusCode status);
MEDIA_EXPORT StatusCode PipelineStatusToStatusCode(PipelineStatus status);
diff --git a/chromium/media/base/renderer.h b/chromium/media/base/renderer.h
index 9244948c287..09d775f0c99 100644
--- a/chromium/media/base/renderer.h
+++ b/chromium/media/base/renderer.h
@@ -8,12 +8,12 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "base/time/time.h"
#include "media/base/buffering_state.h"
#include "media/base/demuxer_stream.h"
#include "media/base/media_export.h"
#include "media/base/pipeline_status.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -49,7 +49,7 @@ class MEDIA_EXPORT Renderer {
// of decoded data is buffered. A nullopt hint indicates the user is clearing
// their preference and the renderer should restore its default buffering
// thresholds.
- virtual void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) = 0;
+ virtual void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) = 0;
// Sets whether pitch adjustment should be applied when the playback rate is
// different than 1.0.
diff --git a/chromium/media/base/renderer_client.h b/chromium/media/base/renderer_client.h
index f11f2132430..cb4c7131101 100644
--- a/chromium/media/base/renderer_client.h
+++ b/chromium/media/base/renderer_client.h
@@ -5,7 +5,6 @@
#ifndef MEDIA_BASE_RENDERER_CLIENT_H_
#define MEDIA_BASE_RENDERER_CLIENT_H_
-#include "base/time/time.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/buffering_state.h"
#include "media/base/media_status.h"
@@ -58,7 +57,7 @@ class MEDIA_EXPORT RendererClient {
// Called when the bucketed frames per second has changed. |fps| will be
// unset if the frame rate is unstable. The duration used for the frame rate
// is based on the wall clock time, not the media time.
- virtual void OnVideoFrameRateChange(base::Optional<int> fps) = 0;
+ virtual void OnVideoFrameRateChange(absl::optional<int> fps) = 0;
};
} // namespace media
diff --git a/chromium/media/base/renderer_factory_selector.cc b/chromium/media/base/renderer_factory_selector.cc
index 0e912d86a9b..c3d8fa5d371 100644
--- a/chromium/media/base/renderer_factory_selector.cc
+++ b/chromium/media/base/renderer_factory_selector.cc
@@ -13,30 +13,30 @@ RendererFactorySelector::RendererFactorySelector() = default;
RendererFactorySelector::~RendererFactorySelector() = default;
void RendererFactorySelector::AddBaseFactory(
- RendererFactoryType type,
+ RendererType type,
std::unique_ptr<RendererFactory> factory) {
DVLOG(1) << __func__ << ": type=" << static_cast<int>(type);
- DCHECK(!base_factory_type_) << "At most one base factory!";
+ DCHECK(!base_renderer_type_) << "At most one base factory!";
AddFactory(type, std::move(factory));
- SetBaseFactoryType(type);
+ SetBaseRendererType(type);
}
void RendererFactorySelector::AddConditionalFactory(
- RendererFactoryType type,
+ RendererType type,
std::unique_ptr<RendererFactory> factory,
ConditionalFactoryCB callback) {
DCHECK(factory);
DCHECK(callback);
- DCHECK(!conditional_factory_types_.count(type))
+ DCHECK(!conditional_factories_.count(type))
<< "At most one conditional factory for a given type!";
- conditional_factory_types_.emplace(type, callback);
+ conditional_factories_.emplace(type, callback);
AddFactory(type, std::move(factory));
}
void RendererFactorySelector::AddFactory(
- RendererFactoryType type,
+ RendererType type,
std::unique_ptr<RendererFactory> factory) {
DCHECK(factory);
DCHECK(!factories_.count(type));
@@ -44,26 +44,26 @@ void RendererFactorySelector::AddFactory(
factories_[type] = std::move(factory);
}
-void RendererFactorySelector::SetBaseFactoryType(RendererFactoryType type) {
+void RendererFactorySelector::SetBaseRendererType(RendererType type) {
DCHECK(factories_.count(type));
- base_factory_type_ = type;
+ base_renderer_type_ = type;
}
-RendererFactoryType RendererFactorySelector::GetCurrentFactoryType() {
- for (const auto& entry : conditional_factory_types_) {
+RendererType RendererFactorySelector::GetCurrentRendererType() {
+ for (const auto& entry : conditional_factories_) {
if (entry.second.Run())
return entry.first;
}
- return base_factory_type_.value();
+ return base_renderer_type_.value();
}
RendererFactory* RendererFactorySelector::GetCurrentFactory() {
- RendererFactoryType current_factory_type = GetCurrentFactoryType();
+ RendererType current_renderer_type = GetCurrentRendererType();
DVLOG(1) << __func__ << " Selecting factory type: "
- << static_cast<int>(current_factory_type);
- auto* current_factory = factories_[current_factory_type].get();
+ << static_cast<int>(current_renderer_type);
+ auto* current_factory = factories_[current_renderer_type].get();
DCHECK(current_factory);
return current_factory;
diff --git a/chromium/media/base/renderer_factory_selector.h b/chromium/media/base/renderer_factory_selector.h
index c291fb35d20..a9599314b85 100644
--- a/chromium/media/base/renderer_factory_selector.h
+++ b/chromium/media/base/renderer_factory_selector.h
@@ -8,10 +8,10 @@
#include <map>
#include "base/callback.h"
-#include "base/optional.h"
#include "build/build_config.h"
#include "media/base/media_status.h"
#include "media/base/renderer_factory.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -30,14 +30,14 @@ namespace media {
//
// Notes:
// - One and at most one base factory must be set.
-// - The base factory can be changed by calling SetBaseFactoryType().
+// - The base factory can be changed by calling SetBaseRendererType().
// - Multiple conditional factories are supported but there should be at most
// one conditional factory for any factory type. If multiple conditions are
// met, it's up to the implementation detail which factory will be returned.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
-enum class RendererFactoryType {
+enum class RendererType {
kDefault = 0, // DefaultRendererFactory
kMojo = 1, // MojoRendererFactory
kMediaPlayer = 2, // MediaPlayerRendererClientFactory
@@ -46,7 +46,7 @@ enum class RendererFactoryType {
kCast = 5, // CastRendererClientFactory
kMediaFoundation = 6, // MediaFoundationRendererClientFactory
kFuchsia = 7, // FuchsiaRendererFactory
- kRemoting = 8, // RemotingRendererFactory
+ kRemoting = 8, // RemotingRendererFactory for remoting::Receiver
kMaxValue = kRemoting,
};
@@ -58,27 +58,26 @@ class MEDIA_EXPORT RendererFactorySelector {
~RendererFactorySelector();
// See file level comments above.
- void AddBaseFactory(RendererFactoryType type,
+ void AddBaseFactory(RendererType type,
std::unique_ptr<RendererFactory> factory);
- void AddConditionalFactory(RendererFactoryType type,
+ void AddConditionalFactory(RendererType type,
std::unique_ptr<RendererFactory> factory,
ConditionalFactoryCB callback);
- void AddFactory(RendererFactoryType type,
- std::unique_ptr<RendererFactory> factory);
+ void AddFactory(RendererType type, std::unique_ptr<RendererFactory> factory);
// Sets the base factory to be returned, when there are no signals telling us
// to select any specific factory.
- // NOTE: |type| can be different than FactoryType::kDefault. kDefault is used
+ // NOTE: |type| can be different than RendererType::kDefault. kDefault is used
// to identify the DefaultRendererFactory, not to indicate that a factory
// should be used by default.
- void SetBaseFactoryType(RendererFactoryType type);
+ void SetBaseRendererType(RendererType type);
- // Returns the type of the factory that GetCurrentFactory() would return.
- // NOTE: SetBaseFactoryType() must be called before calling this method.
- RendererFactoryType GetCurrentFactoryType();
+ // Returns the type of the Renderer for what GetCurrentFactory() would return.
+ // NOTE: SetBaseRendererType() must be called before calling this method.
+ RendererType GetCurrentRendererType();
// Updates |current_factory_| if necessary, and returns its value.
- // NOTE: SetBaseFactoryType() must be called before calling this method.
+ // NOTE: SetBaseRendererType() must be called before calling this method.
RendererFactory* GetCurrentFactory();
#if defined(OS_ANDROID)
@@ -94,19 +93,18 @@ class MEDIA_EXPORT RendererFactorySelector {
#endif
private:
- base::Optional<RendererFactoryType> base_factory_type_;
+ absl::optional<RendererType> base_renderer_type_;
- // Use a map to avoid duplicate entires for the same FactoryType.
- std::map<RendererFactoryType, ConditionalFactoryCB>
- conditional_factory_types_;
+ // Use a map to avoid duplicate entries for the same RendererType.
+ std::map<RendererType, ConditionalFactoryCB> conditional_factories_;
RequestRemotePlayStateChangeCB remote_play_state_change_cb_request_;
- std::map<RendererFactoryType, std::unique_ptr<RendererFactory>> factories_;
+ std::map<RendererType, std::unique_ptr<RendererFactory>> factories_;
DISALLOW_COPY_AND_ASSIGN(RendererFactorySelector);
};
} // namespace media
-#endif // MEDIA_BASE_RENDERER_FACTORY_H_
+#endif // MEDIA_BASE_RENDERER_FACTORY_SELECTOR_H_
diff --git a/chromium/media/base/renderer_factory_selector_unittest.cc b/chromium/media/base/renderer_factory_selector_unittest.cc
index c4900ab51e8..468d49cf685 100644
--- a/chromium/media/base/renderer_factory_selector_unittest.cc
+++ b/chromium/media/base/renderer_factory_selector_unittest.cc
@@ -14,11 +14,9 @@ namespace media {
class RendererFactorySelectorTest : public testing::Test {
public:
- using FactoryType = RendererFactoryType;
-
class FakeFactory : public RendererFactory {
public:
- explicit FakeFactory(FactoryType type) : type_(type) {}
+ explicit FakeFactory(RendererType type) : type_(type) {}
std::unique_ptr<Renderer> CreateRenderer(
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
@@ -30,23 +28,23 @@ class RendererFactorySelectorTest : public testing::Test {
return nullptr;
}
- FactoryType factory_type() { return type_; }
+ RendererType factory_type() { return type_; }
private:
- FactoryType type_;
+ RendererType type_;
};
RendererFactorySelectorTest() = default;
- void AddBaseFactory(FactoryType type) {
+ void AddBaseFactory(RendererType type) {
selector_.AddBaseFactory(type, std::make_unique<FakeFactory>(type));
}
- void AddFactory(FactoryType type) {
+ void AddFactory(RendererType type) {
selector_.AddFactory(type, std::make_unique<FakeFactory>(type));
}
- void AddConditionalFactory(FactoryType type) {
+ void AddConditionalFactory(RendererType type) {
condition_met_map_[type] = false;
selector_.AddConditionalFactory(
type, std::make_unique<FakeFactory>(type),
@@ -54,75 +52,75 @@ class RendererFactorySelectorTest : public testing::Test {
base::Unretained(this), type));
}
- FactoryType GetCurrentlySelectedFactoryType() {
+ RendererType GetCurrentlySelectedRendererType() {
return reinterpret_cast<FakeFactory*>(selector_.GetCurrentFactory())
->factory_type();
}
- bool IsConditionMet(FactoryType type) {
+ bool IsConditionMet(RendererType type) {
DCHECK(condition_met_map_.count(type));
return condition_met_map_[type];
}
protected:
RendererFactorySelector selector_;
- std::map<FactoryType, bool> condition_met_map_;
+ std::map<RendererType, bool> condition_met_map_;
DISALLOW_COPY_AND_ASSIGN(RendererFactorySelectorTest);
};
TEST_F(RendererFactorySelectorTest, SingleFactory) {
- AddBaseFactory(FactoryType::kDefault);
- EXPECT_EQ(FactoryType::kDefault, GetCurrentlySelectedFactoryType());
+ AddBaseFactory(RendererType::kDefault);
+ EXPECT_EQ(RendererType::kDefault, GetCurrentlySelectedRendererType());
}
TEST_F(RendererFactorySelectorTest, MultipleFactory) {
- AddBaseFactory(FactoryType::kDefault);
- AddFactory(FactoryType::kMojo);
+ AddBaseFactory(RendererType::kDefault);
+ AddFactory(RendererType::kMojo);
- EXPECT_EQ(FactoryType::kDefault, GetCurrentlySelectedFactoryType());
+ EXPECT_EQ(RendererType::kDefault, GetCurrentlySelectedRendererType());
- selector_.SetBaseFactoryType(FactoryType::kMojo);
- EXPECT_EQ(FactoryType::kMojo, GetCurrentlySelectedFactoryType());
+ selector_.SetBaseRendererType(RendererType::kMojo);
+ EXPECT_EQ(RendererType::kMojo, GetCurrentlySelectedRendererType());
}
TEST_F(RendererFactorySelectorTest, ConditionalFactory) {
- AddBaseFactory(FactoryType::kDefault);
- AddFactory(FactoryType::kMojo);
- AddConditionalFactory(FactoryType::kCourier);
+ AddBaseFactory(RendererType::kDefault);
+ AddFactory(RendererType::kMojo);
+ AddConditionalFactory(RendererType::kCourier);
- EXPECT_EQ(FactoryType::kDefault, GetCurrentlySelectedFactoryType());
+ EXPECT_EQ(RendererType::kDefault, GetCurrentlySelectedRendererType());
- condition_met_map_[FactoryType::kCourier] = true;
- EXPECT_EQ(FactoryType::kCourier, GetCurrentlySelectedFactoryType());
+ condition_met_map_[RendererType::kCourier] = true;
+ EXPECT_EQ(RendererType::kCourier, GetCurrentlySelectedRendererType());
- selector_.SetBaseFactoryType(FactoryType::kMojo);
- EXPECT_EQ(FactoryType::kCourier, GetCurrentlySelectedFactoryType());
+ selector_.SetBaseRendererType(RendererType::kMojo);
+ EXPECT_EQ(RendererType::kCourier, GetCurrentlySelectedRendererType());
- condition_met_map_[FactoryType::kCourier] = false;
- EXPECT_EQ(FactoryType::kMojo, GetCurrentlySelectedFactoryType());
+ condition_met_map_[RendererType::kCourier] = false;
+ EXPECT_EQ(RendererType::kMojo, GetCurrentlySelectedRendererType());
}
TEST_F(RendererFactorySelectorTest, MultipleConditionalFactories) {
- AddBaseFactory(FactoryType::kDefault);
- AddConditionalFactory(FactoryType::kFlinging);
- AddConditionalFactory(FactoryType::kCourier);
+ AddBaseFactory(RendererType::kDefault);
+ AddConditionalFactory(RendererType::kFlinging);
+ AddConditionalFactory(RendererType::kCourier);
- EXPECT_EQ(FactoryType::kDefault, GetCurrentlySelectedFactoryType());
+ EXPECT_EQ(RendererType::kDefault, GetCurrentlySelectedRendererType());
- condition_met_map_[FactoryType::kFlinging] = false;
- condition_met_map_[FactoryType::kCourier] = true;
- EXPECT_EQ(FactoryType::kCourier, GetCurrentlySelectedFactoryType());
+ condition_met_map_[RendererType::kFlinging] = false;
+ condition_met_map_[RendererType::kCourier] = true;
+ EXPECT_EQ(RendererType::kCourier, GetCurrentlySelectedRendererType());
- condition_met_map_[FactoryType::kFlinging] = true;
- condition_met_map_[FactoryType::kCourier] = false;
- EXPECT_EQ(FactoryType::kFlinging, GetCurrentlySelectedFactoryType());
+ condition_met_map_[RendererType::kFlinging] = true;
+ condition_met_map_[RendererType::kCourier] = false;
+ EXPECT_EQ(RendererType::kFlinging, GetCurrentlySelectedRendererType());
// It's up to the implementation detail to decide which one to use.
- condition_met_map_[FactoryType::kFlinging] = true;
- condition_met_map_[FactoryType::kCourier] = true;
- EXPECT_TRUE(GetCurrentlySelectedFactoryType() == FactoryType::kFlinging ||
- GetCurrentlySelectedFactoryType() == FactoryType::kCourier);
+ condition_met_map_[RendererType::kFlinging] = true;
+ condition_met_map_[RendererType::kCourier] = true;
+ EXPECT_TRUE(GetCurrentlySelectedRendererType() == RendererType::kFlinging ||
+ GetCurrentlySelectedRendererType() == RendererType::kCourier);
}
} // namespace media
diff --git a/chromium/media/base/routing_token_callback.h b/chromium/media/base/routing_token_callback.h
index 9663c17f3f0..cecff0f6219 100644
--- a/chromium/media/base/routing_token_callback.h
+++ b/chromium/media/base/routing_token_callback.h
@@ -22,4 +22,4 @@ using RequestRoutingTokenCallback =
} // namespace media
-#endif // MEDIA_BASE_ANDROID_ROUTING_TOKEN_CALLBACK_H_
+#endif // MEDIA_BASE_ROUTING_TOKEN_CALLBACK_H_
diff --git a/chromium/media/base/sample_rates.h b/chromium/media/base/sample_rates.h
index edba90ed2a6..80aa2ff5ca9 100644
--- a/chromium/media/base/sample_rates.h
+++ b/chromium/media/base/sample_rates.h
@@ -27,7 +27,7 @@ enum AudioSampleRate {
k384000Hz = 12,
k768000Hz = 13,
// Must always equal the largest value ever reported:
- kAudioSampleRateMax = k384000Hz,
+ kAudioSampleRateMax = k768000Hz,
};
// Helper method to convert integral values to their respective enum values,
diff --git a/chromium/media/base/sinc_resampler.cc b/chromium/media/base/sinc_resampler.cc
index 06c85f9349b..118667ff83d 100644
--- a/chromium/media/base/sinc_resampler.cc
+++ b/chromium/media/base/sinc_resampler.cc
@@ -78,6 +78,7 @@
#include <limits>
#include "base/check_op.h"
+#include "base/cpu.h"
#include "base/numerics/math_constants.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
diff --git a/chromium/media/base/sinc_resampler_perftest.cc b/chromium/media/base/sinc_resampler_perftest.cc
index 9570e792bd7..4ac8c8a2941 100644
--- a/chromium/media/base/sinc_resampler_perftest.cc
+++ b/chromium/media/base/sinc_resampler_perftest.cc
@@ -4,6 +4,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/cpu.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/sinc_resampler.h"
diff --git a/chromium/media/base/status.cc b/chromium/media/base/status.cc
index 1e30c223c4b..8bfa2f999b2 100644
--- a/chromium/media/base/status.cc
+++ b/chromium/media/base/status.cc
@@ -5,6 +5,7 @@
#include "media/base/status.h"
#include <memory>
+#include "base/strings/string_piece.h"
#include "media/base/media_serializers.h"
namespace media {
@@ -19,7 +20,7 @@ Status::Status(StatusCode code,
DCHECK(message.empty());
return;
}
- data_ = std::make_unique<StatusInternal>(code, message.as_string());
+ data_ = std::make_unique<StatusInternal>(code, std::string(message));
AddFrame(location);
}
diff --git a/chromium/media/base/status.h b/chromium/media/base/status.h
index 8a7b4e0b9c7..d8e74805bb9 100644
--- a/chromium/media/base/status.h
+++ b/chromium/media/base/status.h
@@ -257,10 +257,10 @@ class StatusOr {
private:
// Optional error.
- base::Optional<Status> error_;
+ absl::optional<Status> error_;
// We wrap |T| in a container so that windows COM wrappers work. They
- // override operator& and similar, and won't compile in a base::Optional.
- base::Optional<std::tuple<T>> value_;
+ // override operator& and similar, and won't compile in a absl::optional.
+ absl::optional<std::tuple<T>> value_;
};
} // namespace media
diff --git a/chromium/media/base/status_codes.h b/chromium/media/base/status_codes.h
index 45eee6460fa..70078b05dcb 100644
--- a/chromium/media/base/status_codes.h
+++ b/chromium/media/base/status_codes.h
@@ -94,6 +94,7 @@ enum class StatusCode : StatusCodeType {
kGetQuantBufferFailed = 0x00000328,
kReleaseQuantBufferFailed = 0x00000329,
kBitstreamBufferSliceTooBig = 0x00000330,
+ kCreateSharedImageFailed = 0x00000331,
// MojoDecoder Errors: 0x04
kMojoDecoderNoWrappedDecoder = 0x00000401,
diff --git a/chromium/media/base/tuneable.h b/chromium/media/base/tuneable.h
index e1efc37458d..913fd3533c2 100644
--- a/chromium/media/base/tuneable.h
+++ b/chromium/media/base/tuneable.h
@@ -6,7 +6,6 @@
#define MEDIA_BASE_TUNEABLE_H_
#include "base/macros.h"
-#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "media/base/media_export.h"
diff --git a/chromium/media/base/user_input_monitor_win.cc b/chromium/media/base/user_input_monitor_win.cc
index 6082070ace0..327b28bb711 100644
--- a/chromium/media/base/user_input_monitor_win.cc
+++ b/chromium/media/base/user_input_monitor_win.cc
@@ -13,7 +13,6 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
-#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/task/current_thread.h"
#include "base/win/message_window.h"
diff --git a/chromium/media/base/video_color_space.h b/chromium/media/base/video_color_space.h
index ee639452198..72a7d73fcb5 100644
--- a/chromium/media/base/video_color_space.h
+++ b/chromium/media/base/video_color_space.h
@@ -107,4 +107,4 @@ class MEDIA_EXPORT VideoColorSpace {
} // namespace media
-#endif
+#endif // MEDIA_BASE_VIDEO_COLOR_SPACE_H_
diff --git a/chromium/media/base/video_decoder.h b/chromium/media/base/video_decoder.h
index 8c6cb290dc2..77772ab6b82 100644
--- a/chromium/media/base/video_decoder.h
+++ b/chromium/media/base/video_decoder.h
@@ -5,9 +5,6 @@
#ifndef MEDIA_BASE_VIDEO_DECODER_H_
#define MEDIA_BASE_VIDEO_DECODER_H_
-#include <string>
-
-#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "media/base/decode_status.h"
#include "media/base/decoder.h"
@@ -41,6 +38,8 @@ class MEDIA_EXPORT VideoDecoder : public Decoder {
using DecodeCB = base::OnceCallback<void(Status)>;
VideoDecoder();
+ VideoDecoder(const VideoDecoder&) = delete;
+ VideoDecoder& operator=(const VideoDecoder&) = delete;
~VideoDecoder() override;
// Initializes a VideoDecoder with the given |config|, executing the
@@ -131,9 +130,6 @@ class MEDIA_EXPORT VideoDecoder : public Decoder {
// this should return the underlying type, if it is known, otherwise return
// its own type.
virtual VideoDecoderType GetDecoderType() const = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(VideoDecoder);
};
} // namespace media
diff --git a/chromium/media/base/video_decoder_config.h b/chromium/media/base/video_decoder_config.h
index 144f7d61a15..af04252500c 100644
--- a/chromium/media/base/video_decoder_config.h
+++ b/chromium/media/base/video_decoder_config.h
@@ -11,13 +11,13 @@
#include <vector>
#include "base/macros.h"
-#include "base/optional.h"
#include "media/base/encryption_scheme.h"
#include "media/base/media_export.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
#include "media/base/video_transformation.h"
#include "media/base/video_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/hdr_metadata.h"
@@ -155,7 +155,7 @@ class MEDIA_EXPORT VideoDecoderConfig {
void set_hdr_metadata(const gfx::HDRMetadata& hdr_metadata) {
hdr_metadata_ = hdr_metadata;
}
- const base::Optional<gfx::HDRMetadata>& hdr_metadata() const {
+ const absl::optional<gfx::HDRMetadata>& hdr_metadata() const {
return hdr_metadata_;
}
@@ -194,7 +194,7 @@ class MEDIA_EXPORT VideoDecoderConfig {
EncryptionScheme encryption_scheme_ = EncryptionScheme::kUnencrypted;
VideoColorSpace color_space_info_;
- base::Optional<gfx::HDRMetadata> hdr_metadata_;
+ absl::optional<gfx::HDRMetadata> hdr_metadata_;
bool is_rtc_ = false;
// Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
diff --git a/chromium/media/base/video_encoder.h b/chromium/media/base/video_encoder.h
index 4a5eb6bda79..2d80329c4f4 100644
--- a/chromium/media/base/video_encoder.h
+++ b/chromium/media/base/video_encoder.h
@@ -6,11 +6,10 @@
#define MEDIA_BASE_VIDEO_ENCODER_H_
#include "base/callback.h"
-#include "base/macros.h"
-#include "base/optional.h"
#include "media/base/media_export.h"
#include "media/base/status.h"
#include "media/base/video_codecs.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
@@ -44,12 +43,12 @@ class MEDIA_EXPORT VideoEncoder {
Options();
Options(const Options&);
~Options();
- base::Optional<uint64_t> bitrate;
- base::Optional<double> framerate;
+ absl::optional<uint64_t> bitrate;
+ absl::optional<double> framerate;
gfx::Size frame_size;
- base::Optional<int> keyframe_interval = 10000;
+ absl::optional<int> keyframe_interval = 10000;
// Requested number of SVC temporal layers.
int temporal_layers = 1;
@@ -67,12 +66,14 @@ class MEDIA_EXPORT VideoEncoder {
// becomes available.
using OutputCB =
base::RepeatingCallback<void(VideoEncoderOutput output,
- base::Optional<CodecDescription>)>;
+ absl::optional<CodecDescription>)>;
// Callback to report success and errors in encoder calls.
using StatusCB = base::OnceCallback<void(Status error)>;
VideoEncoder();
+ VideoEncoder(const VideoEncoder&) = delete;
+ VideoEncoder& operator=(const VideoEncoder&) = delete;
virtual ~VideoEncoder();
// Initializes a VideoEncoder with the given |options|, executing the
@@ -117,9 +118,6 @@ class MEDIA_EXPORT VideoEncoder {
// Requests all outputs for already encoded frames to be
// produced via |output_cb| and calls |dene_cb| after that.
virtual void Flush(StatusCB done_cb) = 0;
-
- protected:
- DISALLOW_COPY_AND_ASSIGN(VideoEncoder);
};
} // namespace media
diff --git a/chromium/media/base/video_frame.cc b/chromium/media/base/video_frame.cc
index 452b1782164..d895ebf38a4 100644
--- a/chromium/media/base/video_frame.cc
+++ b/chromium/media/base/video_frame.cc
@@ -14,7 +14,7 @@
#include "base/bits.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
-#include "base/memory/aligned_memory.h"
+#include "base/process/memory.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
@@ -210,7 +210,7 @@ static bool RequiresEvenSizeAllocation(VideoPixelFormat format) {
}
// Creates VideoFrameLayout for tightly packed frame.
-static base::Optional<VideoFrameLayout> GetDefaultLayout(
+static absl::optional<VideoFrameLayout> GetDefaultLayout(
VideoPixelFormat format,
const gfx::Size& coded_size) {
std::vector<ColorPlaneLayout> planes;
@@ -259,7 +259,7 @@ static base::Optional<VideoFrameLayout> GetDefaultLayout(
// http://crbug.com/555909 .
DLOG(ERROR) << "Unsupported pixel format"
<< VideoPixelFormatToString(format);
- return base::nullopt;
+ return absl::nullopt;
}
return VideoFrameLayout::CreateWithPlanes(format, coded_size, planes);
@@ -291,33 +291,8 @@ bool VideoFrame::IsValidConfig(VideoPixelFormat format,
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size) {
- // Check maximum limits for all formats.
- int coded_size_area = coded_size.GetCheckedArea().ValueOrDefault(INT_MAX);
- int natural_size_area = natural_size.GetCheckedArea().ValueOrDefault(INT_MAX);
- static_assert(limits::kMaxCanvas < INT_MAX, "");
- if (coded_size_area > limits::kMaxCanvas ||
- coded_size.width() > limits::kMaxDimension ||
- coded_size.height() > limits::kMaxDimension || visible_rect.x() < 0 ||
- visible_rect.y() < 0 || visible_rect.right() > coded_size.width() ||
- visible_rect.bottom() > coded_size.height() ||
- natural_size_area > limits::kMaxCanvas ||
- natural_size.width() > limits::kMaxDimension ||
- natural_size.height() > limits::kMaxDimension) {
- return false;
- }
-
- // Make sure new formats are properly accounted for in the method.
- static_assert(PIXEL_FORMAT_MAX == 33,
- "Added pixel format, please review IsValidConfig()");
-
- if (format == PIXEL_FORMAT_UNKNOWN) {
- return coded_size.IsEmpty() && visible_rect.IsEmpty() &&
- natural_size.IsEmpty();
- }
-
- // Check that software-allocated buffer formats are not empty.
- return !coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
- !natural_size.IsEmpty();
+ return IsValidConfigInternal(format, FrameControlType::kNone, coded_size,
+ visible_rect, natural_size);
}
// static
@@ -336,9 +311,9 @@ scoped_refptr<VideoFrame> VideoFrame::CreateVideoHoleFrame(
const gfx::Size& natural_size,
base::TimeDelta timestamp) {
auto layout = VideoFrameLayout::Create(PIXEL_FORMAT_UNKNOWN, natural_size);
- scoped_refptr<VideoFrame> frame =
- new VideoFrame(*layout, StorageType::STORAGE_OPAQUE,
- gfx::Rect(natural_size), natural_size, timestamp);
+ scoped_refptr<VideoFrame> frame = new VideoFrame(
+ *layout, StorageType::STORAGE_OPAQUE, gfx::Rect(natural_size),
+ natural_size, timestamp, FrameControlType::kVideoHole);
frame->metadata().overlay_plane_id = overlay_plane_id;
return frame;
}
@@ -603,7 +578,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalGpuMemoryBuffer(
const gpu::MailboxHolder (&mailbox_holders)[kMaxPlanes],
ReleaseMailboxCB mailbox_holder_release_cb,
base::TimeDelta timestamp) {
- const base::Optional<VideoPixelFormat> format =
+ const absl::optional<VideoPixelFormat> format =
GfxBufferFormatToVideoPixelFormat(gpu_memory_buffer->GetFormat());
if (!format)
return nullptr;
@@ -740,7 +715,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapUnacceleratedIOSurface(
std::vector<int32_t> strides;
for (size_t i = 0; i < num_planes; ++i)
strides.push_back(IOSurfaceGetBytesPerRowOfPlane(io_surface, i));
- base::Optional<VideoFrameLayout> layout =
+ absl::optional<VideoFrameLayout> layout =
media::VideoFrameLayout::CreateWithStrides(pixel_format, size, strides);
if (!layout) {
DLOG(ERROR) << "Invalid layout.";
@@ -857,7 +832,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame(
}
size_t new_plane_count = NumPlanes(format);
- base::Optional<VideoFrameLayout> new_layout;
+ absl::optional<VideoFrameLayout> new_layout;
if (format == frame->format()) {
new_layout = frame->layout();
} else {
@@ -913,8 +888,9 @@ scoped_refptr<VideoFrame> VideoFrame::CreateEOSFrame() {
DLOG(ERROR) << "Invalid layout.";
return nullptr;
}
- scoped_refptr<VideoFrame> frame = new VideoFrame(
- *layout, STORAGE_UNKNOWN, gfx::Rect(), gfx::Size(), kNoTimestamp);
+ scoped_refptr<VideoFrame> frame =
+ new VideoFrame(*layout, STORAGE_UNKNOWN, gfx::Rect(), gfx::Size(),
+ kNoTimestamp, FrameControlType::kEos);
frame->metadata().end_of_stream = true;
return frame;
}
@@ -1322,7 +1298,8 @@ VideoFrame::VideoFrame(const VideoFrameLayout& layout,
StorageType storage_type,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
- base::TimeDelta timestamp)
+ base::TimeDelta timestamp,
+ FrameControlType frame_control_type)
: layout_(layout),
storage_type_(storage_type),
visible_rect_(Intersection(visible_rect, gfx::Rect(layout.coded_size()))),
@@ -1332,8 +1309,8 @@ VideoFrame::VideoFrame(const VideoFrameLayout& layout,
#endif
timestamp_(timestamp),
unique_id_(g_unique_id_generator.GetNext()) {
- DCHECK(IsValidConfig(format(), storage_type, coded_size(), visible_rect_,
- natural_size_));
+ DCHECK(IsValidConfigInternal(format(), frame_control_type, coded_size(),
+ visible_rect_, natural_size_));
DCHECK(visible_rect_ == visible_rect)
<< "visible_rect " << visible_rect.ToString() << " exceeds coded_size "
<< coded_size().ToString();
@@ -1383,6 +1360,46 @@ gfx::Size VideoFrame::DetermineAlignedSize(VideoPixelFormat format,
}
// static
+bool VideoFrame::IsValidConfigInternal(VideoPixelFormat format,
+ FrameControlType frame_control_type,
+ const gfx::Size& coded_size,
+ const gfx::Rect& visible_rect,
+ const gfx::Size& natural_size) {
+ // Check maximum limits for all formats.
+ int coded_size_area = coded_size.GetCheckedArea().ValueOrDefault(INT_MAX);
+ int natural_size_area = natural_size.GetCheckedArea().ValueOrDefault(INT_MAX);
+ static_assert(limits::kMaxCanvas < INT_MAX, "");
+ if (coded_size_area > limits::kMaxCanvas ||
+ coded_size.width() > limits::kMaxDimension ||
+ coded_size.height() > limits::kMaxDimension || visible_rect.x() < 0 ||
+ visible_rect.y() < 0 || visible_rect.right() > coded_size.width() ||
+ visible_rect.bottom() > coded_size.height() ||
+ natural_size_area > limits::kMaxCanvas ||
+ natural_size.width() > limits::kMaxDimension ||
+ natural_size.height() > limits::kMaxDimension) {
+ return false;
+ }
+
+ // Make sure new formats are properly accounted for in the method.
+ static_assert(PIXEL_FORMAT_MAX == 33,
+ "Added pixel format, please review AreSizesValid()");
+ switch (frame_control_type) {
+ case FrameControlType::kNone:
+ // Check that software-allocated buffer formats are not empty.
+ return !coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
+ !natural_size.IsEmpty();
+ case FrameControlType::kEos:
+ DCHECK_EQ(format, PIXEL_FORMAT_UNKNOWN);
+ return coded_size.IsEmpty() && visible_rect.IsEmpty() &&
+ natural_size.IsEmpty();
+ case FrameControlType::kVideoHole:
+ DCHECK_EQ(format, PIXEL_FORMAT_UNKNOWN);
+ return !coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
+ !natural_size.IsEmpty();
+ }
+}
+
+// static
scoped_refptr<VideoFrame> VideoFrame::CreateFrameInternal(
VideoPixelFormat format,
const gfx::Size& coded_size,
@@ -1390,9 +1407,10 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrameInternal(
const gfx::Size& natural_size,
base::TimeDelta timestamp,
bool zero_initialize_memory) {
- // Since we're creating a new frame (and allocating memory for it ourselves),
- // we can pad the requested |coded_size| if necessary if the request does not
- // line up on sample boundaries. See discussion at http://crrev.com/1240833003
+ // Since we're creating a new frame (and allocating memory for it
+ // ourselves), we can pad the requested |coded_size| if necessary if the
+ // request does not line up on sample boundaries. See discussion at
+ // http://crrev.com/1240833003
const gfx::Size new_coded_size = DetermineAlignedSize(format, coded_size);
auto layout = VideoFrameLayout::CreateWithStrides(
format, new_coded_size, ComputeStrides(format, new_coded_size));
@@ -1422,8 +1440,7 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrameWithLayout(
scoped_refptr<VideoFrame> frame(new VideoFrame(
std::move(layout), storage, visible_rect, natural_size, timestamp));
- frame->AllocateMemory(zero_initialize_memory);
- return frame;
+ return frame->AllocateMemory(zero_initialize_memory) ? frame : nullptr;
}
// static
@@ -1438,27 +1455,43 @@ gfx::Size VideoFrame::CommonAlignment(VideoPixelFormat format) {
return gfx::Size(max_sample_width, max_sample_height);
}
-void VideoFrame::AllocateMemory(bool zero_initialize_memory) {
+bool VideoFrame::AllocateMemory(bool zero_initialize_memory) {
DCHECK_EQ(storage_type_, STORAGE_OWNED_MEMORY);
static_assert(0 == kYPlane, "y plane data must be index 0");
std::vector<size_t> plane_size = CalculatePlaneSize();
- const size_t total_buffer_size =
+ const size_t buffer_size =
std::accumulate(plane_size.begin(), plane_size.end(), 0u);
+ const size_t allocation_size =
+ buffer_size + (layout_.buffer_addr_align() - 1);
- uint8_t* data = reinterpret_cast<uint8_t*>(
- base::AlignedAlloc(total_buffer_size, layout_.buffer_addr_align()));
+ uint8_t* data = nullptr;
if (zero_initialize_memory) {
- memset(data, 0, total_buffer_size);
+ if (!base::UncheckedCalloc(1, allocation_size,
+ reinterpret_cast<void**>(&data)) ||
+ !data) {
+ return false;
+ }
+ } else {
+ if (!base::UncheckedMalloc(allocation_size,
+ reinterpret_cast<void**>(&data)) ||
+ !data) {
+ return false;
+ }
}
- AddDestructionObserver(base::BindOnce(&base::AlignedFree, data));
+ private_data_.reset(data);
+
+ data = base::bits::Align(data, layout_.buffer_addr_align());
+ DCHECK_LE(data + buffer_size, private_data_.get() + allocation_size);
- // Note that if layout.buffer_sizes is specified, color planes' layout is the
- // same as buffers'. See CalculatePlaneSize() for detail.
+ // Note that if layout.buffer_sizes is specified, color planes' layout is
+ // the same as buffers'. See CalculatePlaneSize() for detail.
for (size_t plane = 0, offset = 0; plane < NumPlanes(format()); ++plane) {
data_[plane] = data + offset;
offset += plane_size[plane];
}
+
+ return true;
}
bool VideoFrame::IsValidSharedMemoryFrame() const {
diff --git a/chromium/media/base/video_frame.h b/chromium/media/base/video_frame.h
index cf10ff045c1..373d0268b67 100644
--- a/chromium/media/base/video_frame.h
+++ b/chromium/media/base/video_frame.h
@@ -16,11 +16,9 @@
#include "base/callback.h"
#include "base/check_op.h"
#include "base/hash/md5.h"
-#include "base/macros.h"
-#include "base/memory/aligned_memory.h"
+#include "base/memory/free_deleter.h"
#include "base/memory/ref_counted.h"
#include "base/memory/unsafe_shared_memory_region.h"
-#include "base/optional.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/unguessable_token.h"
@@ -30,6 +28,7 @@
#include "media/base/video_frame_layout.h"
#include "media/base/video_frame_metadata.h"
#include "media/base/video_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -104,16 +103,21 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
// the GPU Command Buffer and wait for it.
class SyncTokenClient {
public:
- SyncTokenClient() {}
+ SyncTokenClient() = default;
+ SyncTokenClient(const SyncTokenClient&) = delete;
+ SyncTokenClient& operator=(const SyncTokenClient&) = delete;
+
virtual void GenerateSyncToken(gpu::SyncToken* sync_token) = 0;
virtual void WaitSyncToken(const gpu::SyncToken& sync_token) = 0;
protected:
- virtual ~SyncTokenClient() {}
-
- DISALLOW_COPY_AND_ASSIGN(SyncTokenClient);
+ virtual ~SyncTokenClient() = default;
};
+ VideoFrame() = delete;
+ VideoFrame(const VideoFrame&) = delete;
+ VideoFrame& operator=(const VideoFrame&) = delete;
+
// Returns true if frame configuration is valid.
static bool IsValidConfig(VideoPixelFormat format,
StorageType storage_type,
@@ -448,11 +452,11 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
color_space_ = color_space;
}
- const base::Optional<gfx::HDRMetadata>& hdr_metadata() const {
+ const absl::optional<gfx::HDRMetadata>& hdr_metadata() const {
return hdr_metadata_;
}
- void set_hdr_metadata(const base::Optional<gfx::HDRMetadata>& hdr_metadata) {
+ void set_hdr_metadata(const absl::optional<gfx::HDRMetadata>& hdr_metadata) {
hdr_metadata_ = hdr_metadata;
}
@@ -499,7 +503,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
return data_[plane];
}
- const base::Optional<gpu::VulkanYCbCrInfo>& ycbcr_info() const {
+ const absl::optional<gpu::VulkanYCbCrInfo>& ycbcr_info() const {
return wrapped_frame_ ? wrapped_frame_->ycbcr_info() : ycbcr_info_;
}
@@ -597,13 +601,19 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
size_t BitDepth() const;
// Provide the sampler conversion information for the frame.
- void set_ycbcr_info(const base::Optional<gpu::VulkanYCbCrInfo>& ycbcr_info) {
+ void set_ycbcr_info(const absl::optional<gpu::VulkanYCbCrInfo>& ycbcr_info) {
ycbcr_info_ = ycbcr_info;
}
protected:
friend class base::RefCountedThreadSafe<VideoFrame>;
+ enum class FrameControlType {
+ kNone,
+ kEos,
+ kVideoHole,
+ };
+
// Clients must use the static factory/wrapping methods to create a new frame.
// Derived classes should create their own factory/wrapping methods, and use
// this constructor to do basic initialization.
@@ -611,8 +621,8 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
StorageType storage_type,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
- base::TimeDelta timestamp);
-
+ base::TimeDelta timestamp,
+ FrameControlType frame_control_type = FrameControlType::kNone);
virtual ~VideoFrame();
// Creates a summary of the configuration settings provided as parameters.
@@ -629,6 +639,15 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
}
private:
+ // The constructor of VideoFrame should use IsValidConfigInternal()
+ // instead of the public IsValidConfig() to check the config, because we can
+ // create special video frames that won't pass the check by IsValidConfig().
+ static bool IsValidConfigInternal(VideoPixelFormat format,
+ FrameControlType frame_control_type,
+ const gfx::Size& coded_size,
+ const gfx::Rect& visible_rect,
+ const gfx::Size& natural_size);
+
static scoped_refptr<VideoFrame> CreateFrameInternal(
VideoPixelFormat format,
const gfx::Size& coded_size,
@@ -641,7 +660,9 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
// alignment for each individual plane.
static gfx::Size CommonAlignment(VideoPixelFormat format);
- void AllocateMemory(bool zero_initialize_memory);
+ // Tries to allocate the requisite amount of memory for this frame. Returns
+ // false if this would cause an out of memory error.
+ WARN_UNUSED_RESULT bool AllocateMemory(bool zero_initialize_memory);
// Calculates plane size.
// It first considers buffer size layout_ object provides. If layout's
@@ -729,12 +750,13 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
const int unique_id_;
gfx::ColorSpace color_space_;
- base::Optional<gfx::HDRMetadata> hdr_metadata_;
+ absl::optional<gfx::HDRMetadata> hdr_metadata_;
// Sampler conversion information which is used in vulkan context for android.
- base::Optional<gpu::VulkanYCbCrInfo> ycbcr_info_;
+ absl::optional<gpu::VulkanYCbCrInfo> ycbcr_info_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(VideoFrame);
+ // Allocation which makes up |data_| planes for self-allocated frames.
+ std::unique_ptr<uint8_t, base::FreeDeleter> private_data_;
};
} // namespace media
diff --git a/chromium/media/base/video_frame_layout.cc b/chromium/media/base/video_frame_layout.cc
index dcf0dd23cc5..3eef408656d 100644
--- a/chromium/media/base/video_frame_layout.cc
+++ b/chromium/media/base/video_frame_layout.cc
@@ -87,7 +87,7 @@ size_t VideoFrameLayout::NumPlanes(VideoPixelFormat format) {
}
// static
-base::Optional<VideoFrameLayout> VideoFrameLayout::Create(
+absl::optional<VideoFrameLayout> VideoFrameLayout::Create(
VideoPixelFormat format,
const gfx::Size& coded_size) {
return CreateWithStrides(format, coded_size,
@@ -95,7 +95,7 @@ base::Optional<VideoFrameLayout> VideoFrameLayout::Create(
}
// static
-base::Optional<VideoFrameLayout> VideoFrameLayout::CreateWithStrides(
+absl::optional<VideoFrameLayout> VideoFrameLayout::CreateWithStrides(
VideoPixelFormat format,
const gfx::Size& coded_size,
std::vector<int32_t> strides,
@@ -106,32 +106,32 @@ base::Optional<VideoFrameLayout> VideoFrameLayout::CreateWithStrides(
}
// static
-base::Optional<VideoFrameLayout> VideoFrameLayout::CreateWithPlanes(
+absl::optional<VideoFrameLayout> VideoFrameLayout::CreateWithPlanes(
VideoPixelFormat format,
const gfx::Size& coded_size,
std::vector<ColorPlaneLayout> planes,
size_t buffer_addr_align,
uint64_t modifier) {
// NOTE: Even if format is UNKNOWN, it is valid if coded_sizes is not Empty().
- // TODO(crbug.com/896135): Return base::nullopt,
+ // TODO(crbug.com/896135): Return absl::nullopt,
// if (format != PIXEL_FORMAT_UNKNOWN || !coded_sizes.IsEmpty())
- // TODO(crbug.com/896135): Return base::nullopt,
+ // TODO(crbug.com/896135): Return absl::nullopt,
// if (planes.size() != NumPlanes(format))
return VideoFrameLayout(format, coded_size, std::move(planes),
false /*is_multi_planar */, buffer_addr_align,
modifier);
}
-base::Optional<VideoFrameLayout> VideoFrameLayout::CreateMultiPlanar(
+absl::optional<VideoFrameLayout> VideoFrameLayout::CreateMultiPlanar(
VideoPixelFormat format,
const gfx::Size& coded_size,
std::vector<ColorPlaneLayout> planes,
size_t buffer_addr_align,
uint64_t modifier) {
// NOTE: Even if format is UNKNOWN, it is valid if coded_sizes is not Empty().
- // TODO(crbug.com/896135): Return base::nullopt,
+ // TODO(crbug.com/896135): Return absl::nullopt,
// if (format != PIXEL_FORMAT_UNKNOWN || !coded_sizes.IsEmpty())
- // TODO(crbug.com/896135): Return base::nullopt,
+ // TODO(crbug.com/896135): Return absl::nullopt,
// if (planes.size() != NumPlanes(format))
return VideoFrameLayout(format, coded_size, std::move(planes),
true /*is_multi_planar */, buffer_addr_align,
diff --git a/chromium/media/base/video_frame_layout.h b/chromium/media/base/video_frame_layout.h
index 9d1f7c17437..73b106e0d4a 100644
--- a/chromium/media/base/video_frame_layout.h
+++ b/chromium/media/base/video_frame_layout.h
@@ -13,10 +13,10 @@
#include <utility>
#include <vector>
-#include "base/optional.h"
#include "media/base/color_plane_layout.h"
#include "media/base/media_export.h"
#include "media/base/video_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/native_pixmap_handle.h"
@@ -47,19 +47,19 @@ class MEDIA_EXPORT VideoFrameLayout {
// |modifier| is the additional information of |format|. It will become some
// value else than gfx::NativePixmapHandle::kNoModifier when the underlying
// buffer format is different from a standard |format| due to tiling.
- // The returned base::Optional will be base::nullopt if the configured values
+ // The returned absl::optional will be absl::nullopt if the configured values
// are invalid.
// Create a layout suitable for |format| at |coded_size|. The stride, offsets
// and size of all planes are set to 0, since that information cannot reliably
// be infered from the arguments.
- static base::Optional<VideoFrameLayout> Create(VideoPixelFormat format,
+ static absl::optional<VideoFrameLayout> Create(VideoPixelFormat format,
const gfx::Size& coded_size);
// Create a layout suitable for |format| at |coded_size|, with the |strides|
// for each plane specified. The offsets and size of all planes are set to 0.
// The size of |strides| must be equal to NumPlanes(|format|).
- static base::Optional<VideoFrameLayout> CreateWithStrides(
+ static absl::optional<VideoFrameLayout> CreateWithStrides(
VideoPixelFormat format,
const gfx::Size& coded_size,
std::vector<int32_t> strides,
@@ -69,7 +69,7 @@ class MEDIA_EXPORT VideoFrameLayout {
// Create a layout suitable for |format| at |coded_size|, with the |planes|
// fully provided.
// The size of |planes| must be equal to NumPlanes(|format|).
- static base::Optional<VideoFrameLayout> CreateWithPlanes(
+ static absl::optional<VideoFrameLayout> CreateWithPlanes(
VideoPixelFormat format,
const gfx::Size& coded_size,
std::vector<ColorPlaneLayout> planes,
@@ -79,7 +79,7 @@ class MEDIA_EXPORT VideoFrameLayout {
// This constructor should be called for situations where the frames using
// this format are backed by multiple physical buffers, instead of having each
// plane at different offsets of the same buffer. Currently only used by V4L2.
- static base::Optional<VideoFrameLayout> CreateMultiPlanar(
+ static absl::optional<VideoFrameLayout> CreateMultiPlanar(
VideoPixelFormat format,
const gfx::Size& coded_size,
std::vector<ColorPlaneLayout> planes,
diff --git a/chromium/media/base/video_frame_metadata.h b/chromium/media/base/video_frame_metadata.h
index 3456e0703bd..844fde80b4d 100644
--- a/chromium/media/base/video_frame_metadata.h
+++ b/chromium/media/base/video_frame_metadata.h
@@ -5,9 +5,6 @@
#ifndef MEDIA_BASE_VIDEO_FRAME_METADATA_H_
#define MEDIA_BASE_VIDEO_FRAME_METADATA_H_
-#include <memory>
-#include <string>
-
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/time/time.h"
@@ -55,8 +52,8 @@ struct MEDIA_EXPORT VideoFrameMetadata {
// Video capture begin/end timestamps. Consumers can use these values for
// dynamic optimizations, logging stats, etc.
- base::Optional<base::TimeTicks> capture_begin_time;
- base::Optional<base::TimeTicks> capture_end_time;
+ absl::optional<base::TimeTicks> capture_begin_time;
+ absl::optional<base::TimeTicks> capture_end_time;
// A counter that is increased by the producer of video frames each time
// it pushes out a new frame. By looking for gaps in this counter, clients
@@ -64,7 +61,7 @@ struct MEDIA_EXPORT VideoFrameMetadata {
// the producer between two consecutively received frames. Note that the
// counter may start at arbitrary values, so the absolute value of it has no
// meaning.
- base::Optional<int> capture_counter;
+ absl::optional<int> capture_counter;
// The rectangular region of the frame that has changed since the frame
// with the directly preceding CAPTURE_COUNTER. If that frame was not
@@ -73,11 +70,11 @@ struct MEDIA_EXPORT VideoFrameMetadata {
// The rectangle is relative to the full frame data, i.e. [0, 0,
// coded_size().width(), coded_size().height()]. It does not have to be
// fully contained within visible_rect().
- base::Optional<gfx::Rect> capture_update_rect;
+ absl::optional<gfx::Rect> capture_update_rect;
// If not null, it indicates how video frame mailbox should be copied to a
// new mailbox.
- base::Optional<CopyMode> copy_mode;
+ absl::optional<CopyMode> copy_mode;
// Indicates if the current frame is the End of its current Stream.
bool end_of_stream = false;
@@ -88,12 +85,12 @@ struct MEDIA_EXPORT VideoFrameMetadata {
// vary unpredictably for every frame. Consumers can use this to optimize
// playback scheduling, make encoding quality decisions, and/or compute
// frame-level resource utilization stats.
- base::Optional<base::TimeDelta> frame_duration;
+ absl::optional<base::TimeDelta> frame_duration;
// Represents either the fixed frame rate, or the maximum frame rate to
// expect from a variable-rate source. This value generally remains the
// same for all frames in the same session.
- base::Optional<double> frame_rate;
+ absl::optional<double> frame_rate;
// This is a boolean that signals that the video capture engine detects
// interactive content. One possible optimization that this signal can help
@@ -107,7 +104,7 @@ struct MEDIA_EXPORT VideoFrameMetadata {
// a high-resolution timestamp, and so it should not be used as a
// presentation time; but, instead, it should be used for buffering playback
// and for A/V synchronization purposes.
- base::Optional<base::TimeTicks> reference_time;
+ absl::optional<base::TimeTicks> reference_time;
// Sources of VideoFrames use this marker to indicate that an instance of
// VideoFrameExternalResources produced from the associated video frame
@@ -115,7 +112,7 @@ struct MEDIA_EXPORT VideoFrameMetadata {
bool read_lock_fences_enabled = false;
// Indicates that the frame has a rotation and/or flip.
- base::Optional<VideoTransformation> transformation;
+ absl::optional<VideoTransformation> transformation;
// Android only: if set, then this frame is not suitable for overlay, even
// if ALLOW_OVERLAY is set. However, it allows us to process the overlay
@@ -140,7 +137,7 @@ struct MEDIA_EXPORT VideoFrameMetadata {
// An UnguessableToken that identifies VideoOverlayFactory that created
// this VideoFrame. It's used by Cast to help with video hole punch.
- base::Optional<base::UnguessableToken> overlay_plane_id;
+ absl::optional<base::UnguessableToken> overlay_plane_id;
// Whether this frame was decoded in a power efficient way.
bool power_efficient = false;
@@ -149,46 +146,46 @@ struct MEDIA_EXPORT VideoFrameMetadata {
// remote debugging.
// TODO(crbug.com/832220): Use a customized dictionary value instead of
// using these keys directly.
- base::Optional<double> device_scale_factor;
- base::Optional<double> page_scale_factor;
- base::Optional<double> root_scroll_offset_x;
- base::Optional<double> root_scroll_offset_y;
- base::Optional<double> top_controls_visible_height;
+ absl::optional<double> device_scale_factor;
+ absl::optional<double> page_scale_factor;
+ absl::optional<double> root_scroll_offset_x;
+ absl::optional<double> root_scroll_offset_y;
+ absl::optional<double> top_controls_visible_height;
// If present, this field represents the local time at which the VideoFrame
// was decoded from whichever format it was encoded in. Sometimes only
// DECODE_END_TIME will be present.
- base::Optional<base::TimeTicks> decode_begin_time;
- base::Optional<base::TimeTicks> decode_end_time;
+ absl::optional<base::TimeTicks> decode_begin_time;
+ absl::optional<base::TimeTicks> decode_end_time;
// If present, this field represents the elapsed time from the submission of
// the encoded packet with the same PTS as this frame to the decoder until
// the decoded frame was ready for presentation.
- base::Optional<base::TimeDelta> processing_time;
+ absl::optional<base::TimeDelta> processing_time;
// The RTP timestamp associated with this video frame. Stored as a double
// since base::DictionaryValue doesn't have a uint32_t type.
//
// https://w3c.github.io/webrtc-pc/#dom-rtcrtpcontributingsource-rtptimestamp
- base::Optional<double> rtp_timestamp;
+ absl::optional<double> rtp_timestamp;
// For video frames coming from a remote source, this is the time the
// encoded frame was received by the platform, i.e., the time at
// which the last packet belonging to this frame was received over the
// network.
- base::Optional<base::TimeTicks> receive_time;
+ absl::optional<base::TimeTicks> receive_time;
// If present, this field represents the duration this frame is ideally
// expected to spend on the screen during playback. Unlike FRAME_DURATION
// this field takes into account current playback rate.
- base::Optional<base::TimeDelta> wallclock_frame_duration;
+ absl::optional<base::TimeDelta> wallclock_frame_duration;
// WebRTC streams only: if present, this field represents the maximum
// composition delay that is allowed for this frame. This is respected
// in a best effort manner.
// This is an experimental feature, see crbug.com/1138888 for more
// information.
- base::Optional<int> maximum_composition_delay_in_frames;
+ absl::optional<int> maximum_composition_delay_in_frames;
};
} // namespace media
diff --git a/chromium/media/base/video_frame_pool.cc b/chromium/media/base/video_frame_pool.cc
index 4541324af7b..b5db2c3fbab 100644
--- a/chromium/media/base/video_frame_pool.cc
+++ b/chromium/media/base/video_frame_pool.cc
@@ -7,7 +7,6 @@
#include "base/bind.h"
#include "base/containers/circular_deque.h"
#include "base/logging.h"
-#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
@@ -19,6 +18,8 @@ class VideoFramePool::PoolImpl
: public base::RefCountedThreadSafe<VideoFramePool::PoolImpl> {
public:
PoolImpl();
+ PoolImpl(const PoolImpl&) = delete;
+ PoolImpl& operator=(const PoolImpl&) = delete;
// See VideoFramePool::CreateFrame() for usage. Attempts to keep |frames_| in
// LRU order by always pulling from the back of |frames_|.
@@ -65,8 +66,6 @@ class VideoFramePool::PoolImpl
// |tick_clock_| is always a DefaultTickClock outside of testing.
const base::TickClock* tick_clock_;
-
- DISALLOW_COPY_AND_ASSIGN(PoolImpl);
};
VideoFramePool::PoolImpl::PoolImpl()
diff --git a/chromium/media/base/video_frame_pool.h b/chromium/media/base/video_frame_pool.h
index e6532b4bf41..88cac326086 100644
--- a/chromium/media/base/video_frame_pool.h
+++ b/chromium/media/base/video_frame_pool.h
@@ -7,7 +7,6 @@
#include <stddef.h>
-#include "base/macros.h"
#include "media/base/media_export.h"
#include "media/base/video_frame.h"
@@ -28,6 +27,8 @@ namespace media {
class MEDIA_EXPORT VideoFramePool {
public:
VideoFramePool();
+ VideoFramePool(const VideoFramePool&) = delete;
+ VideoFramePool& operator=(const VideoFramePool&) = delete;
~VideoFramePool();
// Returns a frame from the pool that matches the specified
@@ -53,8 +54,6 @@ class MEDIA_EXPORT VideoFramePool {
private:
class PoolImpl;
scoped_refptr<PoolImpl> pool_;
-
- DISALLOW_COPY_AND_ASSIGN(VideoFramePool);
};
} // namespace media
diff --git a/chromium/media/base/video_frame_unittest.cc b/chromium/media/base/video_frame_unittest.cc
index 50836987e0d..a16ecbcd3cf 100644
--- a/chromium/media/base/video_frame_unittest.cc
+++ b/chromium/media/base/video_frame_unittest.cc
@@ -291,6 +291,11 @@ TEST(VideoFrame, CreateFrame) {
// Test an empty frame.
frame = VideoFrame::CreateEOSFrame();
EXPECT_TRUE(frame->metadata().end_of_stream);
+
+ // Test an video hole frame.
+ frame = VideoFrame::CreateVideoHoleFrame(base::UnguessableToken::Create(),
+ size, kTimestamp);
+ ASSERT_TRUE(frame);
}
TEST(VideoFrame, CreateZeroInitializedFrame) {
diff --git a/chromium/media/base/video_renderer.h b/chromium/media/base/video_renderer.h
index bfbc676c856..6e5611886f2 100644
--- a/chromium/media/base/video_renderer.h
+++ b/chromium/media/base/video_renderer.h
@@ -6,11 +6,10 @@
#define MEDIA_BASE_VIDEO_RENDERER_H_
#include "base/callback_forward.h"
-#include "base/macros.h"
-#include "base/optional.h"
#include "media/base/media_export.h"
#include "media/base/pipeline_status.h"
#include "media/base/time_source.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -21,6 +20,8 @@ class RendererClient;
class MEDIA_EXPORT VideoRenderer {
public:
VideoRenderer();
+ VideoRenderer(const VideoRenderer&) = delete;
+ VideoRenderer& operator=(const VideoRenderer&) = delete;
// Stops all operations and fires all pending callbacks.
virtual ~VideoRenderer();
@@ -68,10 +69,7 @@ class MEDIA_EXPORT VideoRenderer {
// media::Renderer::SetLatencyHint().
// |latency_hint| may be nullopt to indicate the hint has been cleared
// (restore UA default).
- virtual void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(VideoRenderer);
+ virtual void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) = 0;
};
} // namespace media
diff --git a/chromium/media/base/video_thumbnail_decoder.h b/chromium/media/base/video_thumbnail_decoder.h
index 409ec23ab6a..af70aaf20dd 100644
--- a/chromium/media/base/video_thumbnail_decoder.h
+++ b/chromium/media/base/video_thumbnail_decoder.h
@@ -9,7 +9,6 @@
#include <vector>
#include "base/callback.h"
-#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "media/base/media_export.h"
@@ -32,6 +31,8 @@ class MEDIA_EXPORT VideoThumbnailDecoder {
VideoThumbnailDecoder(std::unique_ptr<VideoDecoder> decoder,
const VideoDecoderConfig& config,
std::vector<uint8_t> encoded_data);
+ VideoThumbnailDecoder(const VideoThumbnailDecoder&) = delete;
+ VideoThumbnailDecoder& operator=(const VideoThumbnailDecoder&) = delete;
~VideoThumbnailDecoder();
// Starts to decode the video frame.
@@ -56,8 +57,6 @@ class MEDIA_EXPORT VideoThumbnailDecoder {
VideoFrameCallback video_frame_callback_;
base::WeakPtrFactory<VideoThumbnailDecoder> weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(VideoThumbnailDecoder);
};
} // namespace media
diff --git a/chromium/media/base/video_thumbnail_decoder_unittest.cc b/chromium/media/base/video_thumbnail_decoder_unittest.cc
index 10aa6e34f6b..f070c07cce9 100644
--- a/chromium/media/base/video_thumbnail_decoder_unittest.cc
+++ b/chromium/media/base/video_thumbnail_decoder_unittest.cc
@@ -28,8 +28,11 @@ namespace {
class VideoThumbnailDecoderTest : public testing::Test {
public:
- VideoThumbnailDecoderTest() {}
- ~VideoThumbnailDecoderTest() override {}
+ VideoThumbnailDecoderTest() = default;
+ VideoThumbnailDecoderTest(const VideoThumbnailDecoderTest&) = delete;
+ VideoThumbnailDecoderTest& operator=(const VideoThumbnailDecoderTest&) =
+ delete;
+ ~VideoThumbnailDecoderTest() override = default;
protected:
void SetUp() override {
@@ -76,8 +79,6 @@ class VideoThumbnailDecoderTest : public testing::Test {
// The video frame returned from the thumbnail decoder.
scoped_refptr<VideoFrame> frame_;
-
- DISALLOW_COPY_AND_ASSIGN(VideoThumbnailDecoderTest);
};
// Verifies a video frame can be delivered when decoder successfully created
diff --git a/chromium/media/base/video_util_unittest.cc b/chromium/media/base/video_util_unittest.cc
index c6ae0616ddc..abaa9e25696 100644
--- a/chromium/media/base/video_util_unittest.cc
+++ b/chromium/media/base/video_util_unittest.cc
@@ -9,7 +9,6 @@
#include <cmath>
#include <memory>
-#include "base/macros.h"
#include "media/base/video_frame.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -151,7 +150,8 @@ class VideoUtilTest : public testing::Test {
u_stride_(0),
v_stride_(0) {
}
-
+ VideoUtilTest(const VideoUtilTest&) = delete;
+ VideoUtilTest& operator=(const VideoUtilTest&) = delete;
~VideoUtilTest() override = default;
void CreateSourceFrame(int width, int height,
@@ -187,8 +187,6 @@ class VideoUtilTest : public testing::Test {
int v_stride_;
scoped_refptr<VideoFrame> destination_frame_;
-
- DISALLOW_COPY_AND_ASSIGN(VideoUtilTest);
};
TEST_F(VideoUtilTest, GetPixelAspectRatio) {
@@ -408,15 +406,14 @@ class VideoUtilRotationTest
VideoUtilRotationTest() {
dest_.reset(new uint8_t[GetParam().width * GetParam().height]);
}
-
- virtual ~VideoUtilRotationTest() = default;
+ VideoUtilRotationTest(const VideoUtilRotationTest&) = delete;
+ VideoUtilRotationTest& operator=(const VideoUtilRotationTest&) = delete;
+ ~VideoUtilRotationTest() override = default;
uint8_t* dest_plane() { return dest_.get(); }
private:
std::unique_ptr<uint8_t[]> dest_;
-
- DISALLOW_COPY_AND_ASSIGN(VideoUtilRotationTest);
};
TEST_P(VideoUtilRotationTest, Rotate) {
diff --git a/chromium/media/base/win/BUILD.gn b/chromium/media/base/win/BUILD.gn
index b78090ac9c1..97dfcd06aa6 100644
--- a/chromium/media/base/win/BUILD.gn
+++ b/chromium/media/base/win/BUILD.gn
@@ -54,7 +54,7 @@ source_set("hresult_status_helper") {
}
source_set("mf_cdm_proxy") {
- sources = [ "mf_cdm_proxy.h" ]
+ sources = [ "media_foundation_cdm_proxy.h" ]
deps = [ "//base" ]
}
diff --git a/chromium/media/base/win/dxgi_device_manager.h b/chromium/media/base/win/dxgi_device_manager.h
index d489b3160c2..98e830154f2 100644
--- a/chromium/media/base/win/dxgi_device_manager.h
+++ b/chromium/media/base/win/dxgi_device_manager.h
@@ -33,7 +33,7 @@ class MF_INITIALIZER_EXPORT DXGIDeviceScopedHandle {
};
class MF_INITIALIZER_EXPORT DXGIDeviceManager
- : public base::RefCounted<DXGIDeviceManager> {
+ : public base::RefCountedThreadSafe<DXGIDeviceManager> {
public:
DXGIDeviceManager(const DXGIDeviceManager&) = delete;
DXGIDeviceManager& operator=(const DXGIDeviceManager&) = delete;
@@ -61,7 +61,7 @@ class MF_INITIALIZER_EXPORT DXGIDeviceManager
Microsoft::WRL::ComPtr<IMFDXGIDeviceManager> GetMFDXGIDeviceManager();
protected:
- friend class base::RefCounted<DXGIDeviceManager>;
+ friend class base::RefCountedThreadSafe<DXGIDeviceManager>;
DXGIDeviceManager(
Microsoft::WRL::ComPtr<IMFDXGIDeviceManager> mf_dxgi_device_manager,
UINT d3d_device_reset_token);
diff --git a/chromium/media/base/win/mf_cdm_proxy.h b/chromium/media/base/win/media_foundation_cdm_proxy.h
index fcbeff51a85..e7e7c51d9d2 100644
--- a/chromium/media/base/win/mf_cdm_proxy.h
+++ b/chromium/media/base/win/media_foundation_cdm_proxy.h
@@ -2,27 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_BASE_WIN_MF_CDM_PROXY_H_
-#define MEDIA_BASE_WIN_MF_CDM_PROXY_H_
+#ifndef MEDIA_BASE_WIN_MEDIA_FOUNDATION_CDM_PROXY_H_
+#define MEDIA_BASE_WIN_MEDIA_FOUNDATION_CDM_PROXY_H_
+#include <mfobjects.h>
#include <stdint.h>
#include <unknwn.h>
+#include <windef.h>
-// Interface for clients to get information from MediaFoundationCdm to
-// implements COM interfaces.
-// COM interface is used because we are working with Media Foundation which uses
-// COM extensively for object lifetime management.
-MIDL_INTERFACE("565ab5c2-9923-44e0-997a-f93ccba5dcbf")
-IMFCdmProxy : public IUnknown {
+#include "base/memory/ref_counted.h"
+
+namespace media {
+
+// Interface for the media pipeline to get information from MediaFoundationCdm.
+// TODO(xhwang): Investigate whether this class needs to be ref-counted.
+class MediaFoundationCdmProxy
+ : public base::RefCountedThreadSafe<MediaFoundationCdmProxy> {
public:
// Used by MediaFoundationProtectionManager to get
// ABI::Windows::Media::Protection::IMediaProtectionPMPServer to implement
- // ABI::Windows::Media::Protection::IMediaProtectionManager::get_Properties as
- // in
+ // ABI::Windows::Media::Protection::IMediaProtectionManager::get_Properties
// https://docs.microsoft.com/en-us/uwp/api/windows.media.protection.mediaprotectionmanager
- virtual HRESULT STDMETHODCALLTYPE GetPMPServer(
- /* [in] */ __RPC__in REFIID riid,
- /* [iid_is][out] */ __RPC__deref_out_opt LPVOID * object_result) = 0;
+ virtual HRESULT GetPMPServer(REFIID riid, LPVOID* object_result) = 0;
// Used by MediaFoundationSourceWrapper to implement
// IMFTrustedInput::GetInputTrustAuthority as in
@@ -30,30 +31,35 @@ IMFCdmProxy : public IUnknown {
//
// |content_init_data| is optional initialization data as in
// https://www.w3.org/TR/encrypted-media/#initialization-data
- virtual HRESULT STDMETHODCALLTYPE GetInputTrustAuthority(
- _In_ uint32_t stream_id, _In_ uint32_t stream_count,
- _In_reads_bytes_opt_(content_init_data_size)
- const uint8_t* content_init_data,
- _In_ uint32_t content_init_data_size, _In_ REFIID riid,
- _COM_Outptr_ IUnknown** object_out) = 0;
+ virtual HRESULT GetInputTrustAuthority(uint32_t stream_id,
+ uint32_t stream_count,
+ const uint8_t* content_init_data,
+ uint32_t content_init_data_size,
+ REFIID riid,
+ IUnknown** object_out) = 0;
// When the media Renderer is suspended, `MediaFoundationSourceWrapper`
// provides its last set of key IDs using `SetLastKeyId()` when it is
// destructed. Then during resume, the new `MediaFoundationSourceWrapper`
// calls `RefreshTrustedInput()` to let the CDM use the key IDs information to
// perform some optimization.
- virtual HRESULT STDMETHODCALLTYPE SetLastKeyId(_In_ uint32_t stream_id,
- _In_ REFGUID key_id) = 0;
- virtual HRESULT STDMETHODCALLTYPE RefreshTrustedInput() = 0;
+ virtual HRESULT SetLastKeyId(uint32_t stream_id, REFGUID key_id) = 0;
+ virtual HRESULT RefreshTrustedInput() = 0;
// Used by MediaFoundationProtectionManager to implement
// IMFContentProtectionManager::BeginEnableContent as in
// https://msdn.microsoft.com/en-us/windows/ms694217(v=vs.71)
//
- // |result| is used to obtain the result of an asynchronous operation as in
+ // `result` is used to obtain the result of an asynchronous operation as in
// https://docs.microsoft.com/en-us/windows/win32/api/mfobjects/nn-mfobjects-imfasyncresult
- virtual HRESULT STDMETHODCALLTYPE ProcessContentEnabler(
- _In_ IUnknown * request, _In_ IMFAsyncResult * result) = 0;
+ virtual HRESULT ProcessContentEnabler(IUnknown* request,
+ IMFAsyncResult* result) = 0;
+
+ protected:
+ friend base::RefCountedThreadSafe<MediaFoundationCdmProxy>;
+ virtual ~MediaFoundationCdmProxy() = default;
};
-#endif // MEDIA_BASE_WIN_MF_CDM_PROXY_H_
+} // namespace media
+
+#endif // MEDIA_BASE_WIN_MEDIA_FOUNDATION_CDM_PROXY_H_
diff --git a/chromium/media/blink/BUILD.gn b/chromium/media/blink/BUILD.gn
index 3537092d52b..f96c86f9430 100644
--- a/chromium/media/blink/BUILD.gn
+++ b/chromium/media/blink/BUILD.gn
@@ -35,6 +35,7 @@ component("blink") {
"multibuffer_reader.h",
"new_session_cdm_result_promise.cc",
"new_session_cdm_result_promise.h",
+ "power_status_helper.cc",
"power_status_helper.h",
"remote_playback_client_wrapper_impl.cc",
"remote_playback_client_wrapper_impl.h",
@@ -82,6 +83,7 @@ component("blink") {
"//media/learning/mojo/public/cpp:cpp",
"//media/mojo/mojom",
"//net",
+ "//services/device/public/mojom",
"//services/network/public/cpp:cpp",
"//services/service_manager/public/cpp:cpp",
"//third_party/blink/public:blink",
@@ -116,6 +118,7 @@ test("media_blink_unittests") {
"//mojo/core/embedder",
"//net",
"//services/device:test_support",
+ "//services/device/public/mojom",
"//testing/gmock",
"//testing/gtest",
"//third_party/blink/public:blink",
@@ -149,6 +152,7 @@ test("media_blink_unittests") {
"mock_webassociatedurlloader.h",
"multibuffer_data_source_unittest.cc",
"multibuffer_unittest.cc",
+ "power_status_helper_unittest.cc",
"resource_multibuffer_data_provider_unittest.cc",
"run_all_unittests.cc",
"smoothness_helper_unittest.cc",
diff --git a/chromium/media/blink/blink_platform_with_task_environment.h b/chromium/media/blink/blink_platform_with_task_environment.h
index a279b2bc31c..4ebfff99e76 100644
--- a/chromium/media/blink/blink_platform_with_task_environment.h
+++ b/chromium/media/blink/blink_platform_with_task_environment.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/test/task_environment.h"
+#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/web/blink.h"
diff --git a/chromium/media/blink/cache_util.h b/chromium/media/blink/cache_util.h
index 16e5c317c90..f354b9dc41e 100644
--- a/chromium/media/blink/cache_util.h
+++ b/chromium/media/blink/cache_util.h
@@ -7,8 +7,6 @@
#include <stdint.h>
-#include <vector>
-
#include "base/time/time.h"
#include "media/blink/media_blink_export.h"
diff --git a/chromium/media/blink/cdm_result_promise_helper.h b/chromium/media/blink/cdm_result_promise_helper.h
index a2a0fd7904a..80d9bf97859 100644
--- a/chromium/media/blink/cdm_result_promise_helper.h
+++ b/chromium/media/blink/cdm_result_promise_helper.h
@@ -7,7 +7,6 @@
#include <string>
-#include "base/time/time.h"
#include "media/base/cdm_key_information.h"
#include "media/base/cdm_promise.h"
#include "media/blink/media_blink_export.h"
diff --git a/chromium/media/blink/cdm_session_adapter.cc b/chromium/media/blink/cdm_session_adapter.cc
index ca046934c99..e378e62d575 100644
--- a/chromium/media/blink/cdm_session_adapter.cc
+++ b/chromium/media/blink/cdm_session_adapter.cc
@@ -8,10 +8,10 @@
#include <utility>
#include "base/bind.h"
+#include "base/containers/contains.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_functions.h"
-#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "media/base/cdm_factory.h"
@@ -38,8 +38,8 @@ void CdmSessionAdapter::CreateCdm(CdmFactory* cdm_factory,
const std::string& key_system,
const CdmConfig& cdm_config,
WebCdmCreatedCB web_cdm_created_cb) {
- TRACE_EVENT_ASYNC_BEGIN0("media", "CdmSessionAdapter::CreateCdm",
- ++trace_id_);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "CdmSessionAdapter::CreateCdm",
+ ++trace_id_);
base::TimeTicks start_time = base::TimeTicks::Now();
@@ -171,9 +171,9 @@ void CdmSessionAdapter::OnCdmCreated(
<< (cdm ? "success" : "failure (" + error_message + ")");
DCHECK(!cdm_);
- TRACE_EVENT_ASYNC_END2("media", "CdmSessionAdapter::CreateCdm", trace_id_,
- "success", (cdm ? "true" : "false"), "error_message",
- error_message);
+ TRACE_EVENT_NESTABLE_ASYNC_END2(
+ "media", "CdmSessionAdapter::CreateCdm", trace_id_, "success",
+ (cdm ? "true" : "false"), "error_message", error_message);
auto key_system_uma_prefix =
kMediaEME + GetKeySystemNameForUMA(key_system) + kDot;
diff --git a/chromium/media/blink/key_system_config_selector.cc b/chromium/media/blink/key_system_config_selector.cc
index 0fb75ba185f..68c833ec965 100644
--- a/chromium/media/blink/key_system_config_selector.cc
+++ b/chromium/media/blink/key_system_config_selector.cc
@@ -20,15 +20,12 @@
#include "media/base/media_permission.h"
#include "media/base/mime_util.h"
#include "media/media_buildflags.h"
-#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/public/platform/web_media_key_system_configuration.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/modules/media/webmediaplayer_util.h"
#include "third_party/blink/public/web/web_local_frame.h"
-#include "url/gurl.h"
-#include "url/origin.h"
namespace media {
@@ -247,6 +244,10 @@ class KeySystemConfigSelector::ConfigState {
return are_hw_secure_codecs_required_;
}
+ bool AreHwSecureCodesNotAllowed() const {
+ return are_hw_secure_codecs_not_allowed_;
+ }
+
// Checks whether a rule is compatible with all previously added rules.
bool IsRuleSupported(EmeConfigRule rule) const {
switch (rule) {
@@ -265,8 +266,8 @@ class KeySystemConfigSelector::ConfigState {
case EmeConfigRule::PERSISTENCE_REQUIRED:
return !is_persistence_not_allowed_;
case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED:
- return (!is_identifier_not_allowed_ && IsPermissionPossible() &&
- !is_persistence_not_allowed_);
+ return !is_identifier_not_allowed_ && IsPermissionPossible() &&
+ !is_persistence_not_allowed_;
case EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED:
return !are_hw_secure_codecs_required_;
case EmeConfigRule::HW_SECURE_CODECS_REQUIRED:
@@ -274,6 +275,10 @@ class KeySystemConfigSelector::ConfigState {
case EmeConfigRule::IDENTIFIER_AND_HW_SECURE_CODECS_REQUIRED:
return !is_identifier_not_allowed_ && IsPermissionPossible() &&
!are_hw_secure_codecs_not_allowed_;
+ case EmeConfigRule::IDENTIFIER_PERSISTENCE_AND_HW_SECURE_CODECS_REQUIRED:
+ return !is_identifier_not_allowed_ && IsPermissionPossible() &&
+ !is_persistence_not_allowed_ &&
+ !are_hw_secure_codecs_not_allowed_;
case EmeConfigRule::SUPPORTED:
return true;
}
@@ -317,6 +322,11 @@ class KeySystemConfigSelector::ConfigState {
is_identifier_required_ = true;
are_hw_secure_codecs_required_ = true;
return;
+ case EmeConfigRule::IDENTIFIER_PERSISTENCE_AND_HW_SECURE_CODECS_REQUIRED:
+ is_identifier_required_ = true;
+ is_persistence_required_ = true;
+ are_hw_secure_codecs_required_ = true;
+ return;
case EmeConfigRule::SUPPORTED:
return;
}
@@ -506,8 +516,20 @@ bool KeySystemConfigSelector::GetSupportedCapabilities(
continue;
requested_robustness_ascii = capability.robustness.Ascii();
}
+ // Both of these should not be true.
+ DCHECK(!(proposed_config_state.AreHwSecureCodecsRequired() &&
+ proposed_config_state.AreHwSecureCodesNotAllowed()));
+ bool hw_secure_requirement;
+ bool* hw_secure_requirement_ptr = &hw_secure_requirement;
+ if (proposed_config_state.AreHwSecureCodecsRequired())
+ hw_secure_requirement = true;
+ else if (proposed_config_state.AreHwSecureCodesNotAllowed())
+ hw_secure_requirement = false;
+ else
+ hw_secure_requirement_ptr = nullptr;
EmeConfigRule robustness_rule = key_systems_->GetRobustnessConfigRule(
- key_system, media_type, requested_robustness_ascii);
+ key_system, media_type, requested_robustness_ascii,
+ hw_secure_requirement_ptr);
// 3.13. If the user agent and implementation definitely support playback of
// encrypted media data for the combination of container, media types,
diff --git a/chromium/media/blink/key_system_config_selector_unittest.cc b/chromium/media/blink/key_system_config_selector_unittest.cc
index a05a8f5bc13..3b6d68b8f44 100644
--- a/chromium/media/blink/key_system_config_selector_unittest.cc
+++ b/chromium/media/blink/key_system_config_selector_unittest.cc
@@ -45,8 +45,10 @@ const char kRecommendIdentifierRobustness[] = "recommend_identifier";
const char kRequireIdentifierRobustness[] = "require_identifier";
const char kDisallowHwSecureCodecRobustness[] = "disallow_hw_secure_codec";
const char kRequireHwSecureCodecRobustness[] = "require_hw_secure_codec";
-const char kRequireHwSecureCodecAndIdentifierRobustness[] =
- "require_hw_secure_codec_and_identifier";
+const char kRequireIdentifierAndHwSecureCodecRobustness[] =
+ "require_identifier_and_hw_secure_codec";
+const char kRequireIdentifierPersistenceAndHwSecureCodecRobustness[] =
+ "require_identifier_persistence_and_hw_secure_codec";
const char kUnsupportedRobustness[] = "unsupported";
// Test container mime types. Supported types are prefixed with audio/video so
@@ -284,7 +286,15 @@ class FakeKeySystems : public KeySystems {
EmeConfigRule GetRobustnessConfigRule(
const std::string& key_system,
EmeMediaType media_type,
- const std::string& requested_robustness) const override {
+ const std::string& requested_robustness,
+ const bool* hw_secure_requirement) const override {
+ // TODO(crbug.com/1204284): Remove the `hw_secure_requirement` parameter.
+ // This only exists as a temporary solution until a larger refactoring is
+ // done. We are only testing the explicit thing it is fixing here.
+ if (hw_secure_requirement && *hw_secure_requirement &&
+ distinctive_identifier == EmeFeatureSupport::NOT_SUPPORTED) {
+ return EmeConfigRule::NOT_SUPPORTED;
+ }
if (requested_robustness.empty())
return EmeConfigRule::SUPPORTED;
if (requested_robustness == kSupportedRobustness)
@@ -297,8 +307,13 @@ class FakeKeySystems : public KeySystems {
return EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED;
if (requested_robustness == kRequireHwSecureCodecRobustness)
return EmeConfigRule::HW_SECURE_CODECS_REQUIRED;
- if (requested_robustness == kRequireHwSecureCodecAndIdentifierRobustness)
+ if (requested_robustness == kRequireIdentifierAndHwSecureCodecRobustness)
return EmeConfigRule::IDENTIFIER_AND_HW_SECURE_CODECS_REQUIRED;
+ if (requested_robustness ==
+ kRequireIdentifierPersistenceAndHwSecureCodecRobustness) {
+ return EmeConfigRule::
+ IDENTIFIER_PERSISTENCE_AND_HW_SECURE_CODECS_REQUIRED;
+ }
if (requested_robustness == kUnsupportedRobustness)
return EmeConfigRule::NOT_SUPPORTED;
@@ -1503,10 +1518,10 @@ TEST_F(KeySystemConfigSelectorTest,
SelectConfigReturnsError();
}
-// --- HW Secure and Identifier Robustness ---
+// --- Identifier and HW Secure Robustness ---
TEST_F(KeySystemConfigSelectorTest,
- HwSecureCodecAndIdentifier_IncompatibleCodecAndRobustness) {
+ IdentifierAndHwSecureCodec_IncompatibleCodecAndRobustness) {
media_permission_->is_granted = true;
key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
@@ -1515,7 +1530,7 @@ TEST_F(KeySystemConfigSelectorTest,
video_capabilities[0].mime_type = kSupportedVideoContainer;
video_capabilities[0].codecs = kDisallowHwSecureCodec;
video_capabilities[0].robustness =
- kRequireHwSecureCodecAndIdentifierRobustness;
+ kRequireIdentifierAndHwSecureCodecRobustness;
auto config = EmptyConfiguration();
config.video_capabilities = video_capabilities;
@@ -1525,7 +1540,7 @@ TEST_F(KeySystemConfigSelectorTest,
}
TEST_F(KeySystemConfigSelectorTest,
- HwSecureCodecAndIdentifier_IncompatibleCapabilities) {
+ IdentifierAndHwSecureCodec_IncompatibleCapabilities) {
media_permission_->is_granted = true;
key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
@@ -1534,7 +1549,7 @@ TEST_F(KeySystemConfigSelectorTest,
video_capabilities[0].mime_type = kSupportedVideoContainer;
video_capabilities[0].codecs = kSupportedVideoCodec;
video_capabilities[0].robustness =
- kRequireHwSecureCodecAndIdentifierRobustness;
+ kRequireIdentifierAndHwSecureCodecRobustness;
video_capabilities[1].content_type = "disallow_hw_secure_codec";
video_capabilities[1].mime_type = kSupportedVideoContainer;
video_capabilities[1].codecs = kDisallowHwSecureCodec;
@@ -1553,7 +1568,7 @@ TEST_F(KeySystemConfigSelectorTest,
}
TEST_F(KeySystemConfigSelectorTest,
- HwSecureCodecAndIdentifier_UnsupportedCapabilityNotAffectingRules) {
+ IdentifierAndHwSecureCodec_UnsupportedCapabilityNotAffectingRules) {
media_permission_->is_granted = true;
key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
@@ -1566,7 +1581,7 @@ TEST_F(KeySystemConfigSelectorTest,
video_capabilities[1].mime_type = kSupportedVideoContainer;
video_capabilities[1].codecs = kRequireHwSecureCodec;
video_capabilities[1].robustness =
- kRequireHwSecureCodecAndIdentifierRobustness;
+ kRequireIdentifierAndHwSecureCodecRobustness;
auto config = EmptyConfiguration();
config.video_capabilities = video_capabilities;
@@ -1580,6 +1595,72 @@ TEST_F(KeySystemConfigSelectorTest,
EXPECT_TRUE(cdm_config_.use_hw_secure_codecs);
}
+TEST_F(KeySystemConfigSelectorTest,
+ HwSecureCodecAndIdentifier_IdentifierAndHwSecureCodecsDisjoint) {
+ media_permission_->is_granted = false;
+ key_systems_->distinctive_identifier = EmeFeatureSupport::NOT_SUPPORTED;
+
+ std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2);
+ video_capabilities[0].content_type = "require_hw_secure_codec";
+ video_capabilities[0].mime_type = kSupportedVideoContainer;
+ video_capabilities[0].codecs = kRequireHwSecureCodec;
+ video_capabilities[0].robustness = "";
+
+ auto config = EmptyConfiguration();
+ config.video_capabilities = video_capabilities;
+ configs_.push_back(config);
+
+ SelectConfigReturnsError();
+}
+
+// --- Identifier, Persistence and HW Secure Robustness ---
+
+TEST_F(KeySystemConfigSelectorTest,
+ IdentifierPersistenceAndHwSecureCodec_Supported) {
+ media_permission_->is_granted = true;
+ key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE;
+ key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
+
+ std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1);
+ video_capabilities[0].content_type = "require_hw_secure_codec";
+ video_capabilities[0].mime_type = kSupportedVideoContainer;
+ video_capabilities[0].codecs = kSupportedVideoCodec;
+ video_capabilities[0].robustness =
+ kRequireIdentifierPersistenceAndHwSecureCodecRobustness;
+
+ auto config = EmptyConfiguration();
+ config.video_capabilities = video_capabilities;
+ configs_.push_back(config);
+
+ SelectConfigRequestsPermissionAndReturnsConfig();
+ EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier);
+ EXPECT_EQ(MediaKeysRequirement::kRequired, config_.persistent_state);
+ ASSERT_EQ(1u, config_.video_capabilities.size());
+ EXPECT_EQ("require_hw_secure_codec",
+ config_.video_capabilities[0].content_type);
+ EXPECT_TRUE(cdm_config_.use_hw_secure_codecs);
+}
+
+TEST_F(KeySystemConfigSelectorTest,
+ IdentifierPersistenceAndHwSecureCodec_NotSupported) {
+ media_permission_->is_granted = true;
+ key_systems_->persistent_state = EmeFeatureSupport::NOT_SUPPORTED;
+ key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
+
+ std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1);
+ video_capabilities[0].content_type = "require_hw_secure_codec";
+ video_capabilities[0].mime_type = kSupportedVideoContainer;
+ video_capabilities[0].codecs = kSupportedVideoCodec;
+ video_capabilities[0].robustness =
+ kRequireIdentifierPersistenceAndHwSecureCodecRobustness;
+
+ auto config = EmptyConfiguration();
+ config.video_capabilities = video_capabilities;
+ configs_.push_back(config);
+
+ SelectConfigReturnsError();
+}
+
// --- audioCapabilities ---
// These are handled by the same code as |videoCapabilities|, so only minimal
// additional testing is done.
diff --git a/chromium/media/blink/learning_experiment_helper_unittest.cc b/chromium/media/blink/learning_experiment_helper_unittest.cc
index 63926025760..36e3e0bec98 100644
--- a/chromium/media/blink/learning_experiment_helper_unittest.cc
+++ b/chromium/media/blink/learning_experiment_helper_unittest.cc
@@ -29,15 +29,15 @@ class MockLearningTaskController : public LearningTaskController {
MOCK_METHOD4(BeginObservation,
void(base::UnguessableToken id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_value,
- const base::Optional<ukm::SourceId>& source_id));
+ const absl::optional<TargetValue>& default_value,
+ const absl::optional<ukm::SourceId>& source_id));
MOCK_METHOD2(CompleteObservation,
void(base::UnguessableToken id,
const ObservationCompletion& completion));
MOCK_METHOD1(CancelObservation, void(base::UnguessableToken id));
MOCK_METHOD2(UpdateDefaultTarget,
void(base::UnguessableToken id,
- const base::Optional<TargetValue>& default_target));
+ const absl::optional<TargetValue>& default_target));
MOCK_METHOD2(PredictDistribution,
void(const FeatureVector& features, PredictionCB callback));
diff --git a/chromium/media/blink/multibuffer_data_source.cc b/chromium/media/blink/multibuffer_data_source.cc
index 1e5c85595c7..c157471b08e 100644
--- a/chromium/media/blink/multibuffer_data_source.cc
+++ b/chromium/media/blink/multibuffer_data_source.cc
@@ -17,6 +17,7 @@
#include "media/blink/buffered_data_source_host_impl.h"
#include "media/blink/multibuffer_reader.h"
#include "net/base/net_errors.h"
+#include "url/gurl.h"
namespace {
diff --git a/chromium/media/blink/multibuffer_data_source.h b/chromium/media/blink/multibuffer_data_source.h
index 8441d15ece8..2f35c43811e 100644
--- a/chromium/media/blink/multibuffer_data_source.h
+++ b/chromium/media/blink/multibuffer_data_source.h
@@ -20,7 +20,8 @@
#include "media/base/tuneable.h"
#include "media/blink/media_blink_export.h"
#include "media/blink/url_index.h"
-#include "url/gurl.h"
+
+class GURL;
namespace base {
class SingleThreadTaskRunner;
diff --git a/chromium/media/blink/multibuffer_data_source_unittest.cc b/chromium/media/blink/multibuffer_data_source_unittest.cc
index 3bdce8224f9..bf7e74c1b90 100644
--- a/chromium/media/blink/multibuffer_data_source_unittest.cc
+++ b/chromium/media/blink/multibuffer_data_source_unittest.cc
@@ -22,6 +22,7 @@
#include "media/blink/multibuffer_reader.h"
#include "media/blink/resource_multibuffer_data_provider.h"
#include "media/blink/test_response_generator.h"
+#include "services/network/public/mojom/fetch_api.mojom.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_response.h"
@@ -1405,7 +1406,6 @@ TEST_F(MultibufferDataSourceTest, Http_RetryThenRedirect) {
// Issue a pending read but trigger an error to force a retry.
EXPECT_CALL(*this, ReadCallback(kDataSize - 10));
- EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize * 2));
ReadAt(kDataSize + 10, kDataSize - 10);
base::RunLoop run_loop;
data_provider()->DidFail(response_generator_->GenerateError());
@@ -1417,9 +1417,11 @@ TEST_F(MultibufferDataSourceTest, Http_RetryThenRedirect) {
blink::WebURLResponse response((GURL(kHttpUrl)));
response.SetHttpStatusCode(307);
data_provider()->WillFollowRedirect(url, response);
+
+ EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize * 2));
Respond(response_generator_->Generate206(kDataSize));
ReceiveData(kDataSize);
- EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize * 3));
+
FinishLoading();
EXPECT_FALSE(loading());
Stop();
diff --git a/chromium/media/blink/multibuffer_reader.h b/chromium/media/blink/multibuffer_reader.h
index 137f3888be2..ae67ccae4ba 100644
--- a/chromium/media/blink/multibuffer_reader.h
+++ b/chromium/media/blink/multibuffer_reader.h
@@ -7,10 +7,6 @@
#include <stdint.h>
-#include <limits>
-#include <map>
-#include <set>
-
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "media/blink/media_blink_export.h"
diff --git a/chromium/media/blink/new_session_cdm_result_promise.cc b/chromium/media/blink/new_session_cdm_result_promise.cc
index 4e718cac8f1..0f19f3a939a 100644
--- a/chromium/media/blink/new_session_cdm_result_promise.cc
+++ b/chromium/media/blink/new_session_cdm_result_promise.cc
@@ -4,9 +4,9 @@
#include "media/blink/new_session_cdm_result_promise.h"
+#include "base/containers/contains.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
-#include "base/stl_util.h"
#include "media/blink/cdm_result_promise_helper.h"
#include "third_party/blink/public/platform/web_string.h"
diff --git a/chromium/media/blink/power_status_helper.cc b/chromium/media/blink/power_status_helper.cc
new file mode 100644
index 00000000000..aaed8fd3824
--- /dev/null
+++ b/chromium/media/blink/power_status_helper.cc
@@ -0,0 +1,310 @@
+// 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 "media/blink/power_status_helper.h"
+
+#include <utility>
+
+#include "base/check.h"
+#include "base/check_op.h"
+#include "base/metrics/histogram_macros.h"
+#include "media/base/pipeline_metadata.h"
+#include "services/device/public/mojom/battery_status.mojom.h"
+
+namespace media {
+namespace {
+
+using ::device::mojom::BatteryStatusPtr;
+
+static constexpr const char* kBatteryDeltaHistogram =
+ "Media.PlaybackPower.BatteryDelta";
+static constexpr const char* kElapsedTimeHistogram =
+ "Media.PlaybackPower.ElapsedTime";
+
+// Minimum enum value that we'll generate, inclusive.
+static constexpr int kMinEnumValue = 0;
+
+// Maximum enum value that we'll generate, inclusive.
+static constexpr int kMaxEnumValue =
+ PowerStatusHelper::Bits::kCodecBitsH264 |
+ PowerStatusHelper::Bits::kCodecBitsVP9Profile0 |
+ PowerStatusHelper::Bits::kCodecBitsVP9Profile2 |
+
+ PowerStatusHelper::Bits::kResolution360p |
+ PowerStatusHelper::Bits::kResolution720p |
+ PowerStatusHelper::Bits::kResolution1080p |
+
+ PowerStatusHelper::Bits::kFrameRate30 |
+ PowerStatusHelper::Bits::kFrameRate60 |
+
+ PowerStatusHelper::Bits::kFullScreenNo |
+ PowerStatusHelper::Bits::kFullScreenYes;
+
+// UMA buckets are always [uma_min, uma_max). The first bucket is an implicit
+// underflow bucket [0, uma_min), and the last is the overflow bucket
+// [uma_max, infinity). The underflow bucket isn't counted, but the overflow
+// bucket is.
+
+// Minimum bucket number. Since we always get an underflow bucket, we choose
+// the minimum bucket to be one higher than the minimum enum value. That way.
+// the minimum enum goes to the underflow bucket.
+// //tools/metrics/histograms/README.md#count-histograms_choosing-min-and-max
+// for details.
+static constexpr int kMinUmaValue = kMinEnumValue + 1;
+
+// We want to avoid using the overflow bucket. See
+// //tools/metrics/histograms/README.md#count-histograms_choosing-min-and-max
+// and UMA_HISTOGRAM_EXACT_LINEAR for details.
+
+// Max value as reported to UMA, which is the lower bound of the overflow
+// bucket. Add one, since we want the overflow bucket to be unused.
+static constexpr int kMaxUmaValue = kMaxEnumValue + 1;
+
+// Number of buckets we want, which includes the overflow bucket but not the
+// implicit underflow bucket.
+// NOTE: We add two here, else we don't quite get enough buckets. This was
+// emperically determined by checking Histogram::bucket_ranges(). It might
+// be the case that we should subtract one here and from |kMaxUmaValue|, but
+// either way, i think it works out. We just have one unused bucket at worst,
+// which won't be renumbered even if we start using it later.
+static constexpr int kNumUmaBuckets = kMaxUmaValue - kMinUmaValue + 2;
+
+// For example, if kMinEnum == 0 and kMaxEnum == 5 (inclusive), then:
+// kMinUma = 1 (0 is implicit), kMaxUma = 6, and we'll want the implicit
+// underflow bucket plus kNumUmaBuckets = 6 more.
+// [0, 1) << implicit underflow bucket, kMinEnum goes here
+// [1, 2)
+// [2, 3)
+// [3, 4)
+// [4, 5)
+// [5, 6) << kMaxEnum goes here
+// [6, infinity) << unused overflow bucket.
+
+// We can have more, but shouldn't without talking to metrics folks.
+static_assert(kNumUmaBuckets < 100, "Too many buckets");
+
+} // namespace
+
+PowerStatusHelper::PowerStatusHelper(
+ CreateBatteryMonitorCB create_battery_monitor_cb)
+ : create_battery_monitor_cb_(std::move(create_battery_monitor_cb)) {}
+
+PowerStatusHelper::~PowerStatusHelper() = default;
+
+// static
+absl::optional<int> PowerStatusHelper::BucketFor(
+ bool is_playing,
+ bool has_video,
+ media::VideoCodec codec,
+ media::VideoCodecProfile profile,
+ gfx::Size natural_size,
+ bool is_fullscreen,
+ absl::optional<int> average_fps) {
+ if (!is_playing)
+ return {};
+
+ if (!has_video)
+ return {};
+
+ int bucket = 0;
+
+ if (codec == media::VideoCodec::kCodecH264)
+ bucket |= Bits::kCodecBitsH264;
+ else if (profile == media::VP9PROFILE_PROFILE0)
+ bucket |= Bits::kCodecBitsVP9Profile0;
+ else if (profile == media::VP9PROFILE_PROFILE2)
+ bucket |= Bits::kCodecBitsVP9Profile2;
+ else
+ return {};
+
+ // We could take into account rotation, but ignore it for now.
+ if (natural_size == gfx::Size(640, 360))
+ bucket |= kResolution360p;
+ else if (natural_size == gfx::Size(1280, 720))
+ bucket |= kResolution720p;
+ else if (natural_size == gfx::Size(1920, 1080))
+ bucket |= kResolution1080p;
+ else
+ return {};
+
+ // Estimate the frame rate. Since 24 is popular, allow a wide range around
+ // 30fps, since it's likely the same for power.
+ if (!average_fps)
+ return {};
+ else if (*average_fps == 60)
+ bucket |= kFrameRate60;
+ else if (*average_fps >= 24 && *average_fps <= 30)
+ bucket |= kFrameRate30;
+ else
+ return {};
+
+ bucket |= is_fullscreen ? kFullScreenYes : kFullScreenNo;
+
+ return bucket;
+}
+
+// static
+const char* PowerStatusHelper::BatteryDeltaHistogram() {
+ return kBatteryDeltaHistogram;
+}
+
+// static
+const char* PowerStatusHelper::ElapsedTimeHistogram() {
+ return kElapsedTimeHistogram;
+}
+
+void PowerStatusHelper::SetIsPlaying(bool is_playing) {
+ is_playing_ = is_playing;
+ OnAnyStateChange();
+}
+
+void PowerStatusHelper::SetMetadata(const media::PipelineMetadata& metadata) {
+ has_video_ = metadata.has_video;
+ codec_ = metadata.video_decoder_config.codec();
+ profile_ = metadata.video_decoder_config.profile();
+ natural_size_ = metadata.video_decoder_config.natural_size();
+ OnAnyStateChange();
+}
+
+void PowerStatusHelper::SetIsFullscreen(bool is_fullscreen) {
+ is_fullscreen_ = is_fullscreen;
+ OnAnyStateChange();
+}
+
+void PowerStatusHelper::SetAverageFrameRate(absl::optional<int> average_fps) {
+ average_fps_ = average_fps;
+ OnAnyStateChange();
+}
+
+void PowerStatusHelper::UpdatePowerExperimentState(bool state) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ experiment_state_ = state;
+ OnAnyStateChange();
+}
+
+void PowerStatusHelper::OnAnyStateChange() {
+ absl::optional<int> old_bucket = current_bucket_;
+ current_bucket_.reset();
+
+ // If we're the power experiment, then we might have a bucket. Else, we
+ // definitely don't.
+ if (experiment_state_) {
+ current_bucket_ = BucketFor(is_playing_, has_video_, codec_, profile_,
+ natural_size_, is_fullscreen_, average_fps_);
+ }
+
+ // If we're changing buckets, then request power updates with a new generation
+ // id. This lets us separate readings from the old bucket.
+ if (current_bucket_ && (!old_bucket || *current_bucket_ != *old_bucket)) {
+ // Also reset the baseline, in case we're changing buckets. We don't want
+ // to include any battery drain that should have been in the first bucket.
+ StartMonitoring();
+ } else if (old_bucket && !current_bucket_) {
+ // We don't need power updates, but we had them before.
+ StopMonitoring();
+ }
+}
+
+void PowerStatusHelper::OnBatteryStatus(
+ device::mojom::BatteryStatusPtr battery_status) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ QueryNextStatus();
+
+ if (battery_status->charging) {
+ // If we're charging, then wait until we stop. Take a new baseline then.
+ battery_level_baseline_.reset();
+ return;
+ }
+
+ // Compute the amount of time since our last update. Note that, if this is
+ // the first status update since we (re)started monitoring, then the baseline
+ // should be unset, so |elapsed| will be ignored. That's good, since it could
+ // be quite far in the past since we've had an update.
+ const base::TimeTicks now = base::TimeTicks::Now();
+
+ // Convert to floating point 0-100 from 0-1.
+ const float current_level = battery_status->level * 100;
+
+ // If we don't have a baseline, then use |current_level| and |now|. In the
+ // future, we might want to wait until the battery drain is reported twice,
+ // since we don't know how much of a fractional percent remains in this
+ // initial baseline. For now, just ignore that.
+ if (!battery_level_baseline_) {
+ battery_level_baseline_ = current_level;
+ last_update_ = now;
+ return;
+ }
+
+ // Second or later update since we started monitoring / stopped charging.
+ // Compute the battery used. Note that positive numbers indicate that the
+ // battery has gone down.
+ const float delta = *battery_level_baseline_ - current_level;
+
+ DCHECK(current_bucket_);
+ DCHECK_GE(delta, 0.);
+
+ // See if we can record some nonzero battery drain and elapsed time, when
+ // converted to int. We can only record ints in UMA.
+ const int delta_int = static_cast<int>(delta);
+ const base::TimeDelta elapsed = now - last_update_;
+ const int elapsed_msec = elapsed.InMilliseconds();
+ if (delta_int > 0 && elapsed_msec > 0) {
+ // Record that we consumed |delta_int| battery percent in |elapsed_msec|.
+ base::LinearHistogram::FactoryGet(
+ BatteryDeltaHistogram(), kMinUmaValue, kMaxUmaValue, kNumUmaBuckets,
+ base::HistogramBase::kUmaTargetedHistogramFlag)
+ ->AddCount(*current_bucket_, delta_int);
+
+ base::LinearHistogram::FactoryGet(
+ ElapsedTimeHistogram(), kMinUmaValue, kMaxUmaValue, kNumUmaBuckets,
+ base::HistogramBase::kUmaTargetedHistogramFlag)
+ ->AddCount(*current_bucket_, elapsed_msec);
+
+ // Update the baseline to |current_level|, but include any fractional
+ // unrecorded amount so that we can record it later.
+ battery_level_baseline_ = current_level + (delta - delta_int);
+ // Don't bother remembering any fractional msec.
+ last_update_ = now;
+ }
+}
+
+void PowerStatusHelper::StartMonitoring() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (!battery_monitor_.is_bound()) {
+ auto pending = create_battery_monitor_cb_.Run();
+ if (!pending.is_valid())
+ return;
+ battery_monitor_.Bind(std::move(pending));
+
+ // In case it's not available for some reason, do nothing.
+ if (!battery_monitor_.is_bound())
+ return;
+
+ // Start querying for status as long as we're connected.
+ QueryNextStatus();
+ }
+
+ // Any baseline that we had should be reset, since we're called to start or
+ // restart monitoring when our bucket changes.
+ battery_level_baseline_.reset();
+}
+
+void PowerStatusHelper::StopMonitoring() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ battery_monitor_.reset();
+}
+
+void PowerStatusHelper::QueryNextStatus() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(battery_monitor_.is_bound());
+
+ // Remember that overlapping calls are not allowed by BatteryMonitor, and are
+ // treated as a connection error. Unretained since we own |battery_monitor_|.
+ battery_monitor_->QueryNextStatus(base::BindOnce(
+ &PowerStatusHelper::OnBatteryStatus, base::Unretained(this)));
+}
+
+} // namespace media
diff --git a/chromium/media/blink/power_status_helper.h b/chromium/media/blink/power_status_helper.h
index 828055afa21..d8381dd1d59 100644
--- a/chromium/media/blink/power_status_helper.h
+++ b/chromium/media/blink/power_status_helper.h
@@ -5,35 +5,142 @@
#ifndef MEDIA_BLINK_POWER_STATUS_HELPER_H_
#define MEDIA_BLINK_POWER_STATUS_HELPER_H_
-#include "base/macros.h"
-#include "base/optional.h"
+#include "base/callback.h"
+#include "base/sequence_checker.h"
#include "base/time/time.h"
-#include "media/base/pipeline_metadata.h"
#include "media/base/video_codecs.h"
#include "media/blink/media_blink_export.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/device/public/mojom/battery_monitor.mojom.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/gfx/geometry/size.h"
namespace media {
+struct PipelineMetadata;
-// Base class to monitor for power events during playback and record them to
-// UMA / UKM.
+// Class to monitor for power events during playback and record them to UMA/UKM.
class MEDIA_BLINK_EXPORT PowerStatusHelper {
public:
- PowerStatusHelper() = default;
- virtual ~PowerStatusHelper() = default;
+ using CreateBatteryMonitorCB = base::RepeatingCallback<
+ mojo::PendingRemote<device::mojom::BatteryMonitor>()>;
+
+ // Bits used to construct UMA buckets.
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum /* not class */ Bits {
+ // Bit layout is: [msb] xx f F RR CC [lsb]
+ // R == resolution
+ // C == codec
+ // F == frame rate
+ // f == full screen
+ // x == unused
+ // Remember that we can't use more than 6 bits, since we shouldn't go over
+ // 100 UMA buckets.
+
+ // Codec bits, values 0x00 to 0x03
+ // Named "CodecBits" to prevent a name collision with media::VideoCodec.
+ kCodecBitsH264 = (0x00) << 0,
+ kCodecBitsVP9Profile0 = (0x01) << 0,
+ // Ignore Profile1
+ kCodecBitsVP9Profile2 = (0x02) << 0,
+ // TODO(liberato): add AV1
+
+ // Resolution bits, values 0x00 to 0x03
+ kResolution360p = (0x00) << 2,
+ kResolution720p = (0x01) << 2,
+ kResolution1080p = (0x02) << 2,
+
+ // Frame rate bits, values 0x00 to 0x01
+ kFrameRate30 = (0x00) << 4,
+ kFrameRate60 = (0x01) << 4,
+
+ // Fullscreen bits, values 0x00 to 0x01
+ kFullScreenNo = (0x00) << 5,
+ kFullScreenYes = (0x01) << 5,
+
+ // This is not a valid bit for, you know, testing.
+ kNotAValidBitForTesting = (0x01) << 10,
+ };
+
+ // If |stats_cb| is not provided, then we'll record to UMA. It's just for
+ // the tests.
+ explicit PowerStatusHelper(CreateBatteryMonitorCB create_battery_monitor_cb);
+ PowerStatusHelper(const PowerStatusHelper&) = delete;
+ PowerStatusHelper& operator=(const PowerStatusHelper&) = delete;
+ ~PowerStatusHelper();
// Notify us about changes to the player.
- virtual void SetIsPlaying(bool is_playing) = 0;
- virtual void SetMetadata(const PipelineMetadata& metadata) = 0;
- virtual void SetIsFullscreen(bool is_fullscreen) = 0;
- virtual void SetAverageFrameRate(base::Optional<int> average_fps) = 0;
+ void SetIsPlaying(bool is_playing);
+ void SetMetadata(const media::PipelineMetadata& metadata);
+ void SetIsFullscreen(bool is_fullscreen);
+ void SetAverageFrameRate(absl::optional<int> average_fps);
// Handle notifications about the experiment state from the power experiment.
// manager. |state| indicates whether our player is eligible to record power
// experiments readings.
- virtual void UpdatePowerExperimentState(bool state) = 0;
+ void UpdatePowerExperimentState(bool state);
private:
- DISALLOW_COPY_AND_ASSIGN(PowerStatusHelper);
+ friend class PowerStatusHelperTest;
+ friend class PowerStatusHelperBucketTest;
+
+ // Return the UMA bucket for the given video configuration, or nullopt if we
+ // don't want to record it.
+ static absl::optional<int> BucketFor(bool is_playing,
+ bool has_video,
+ media::VideoCodec codec,
+ media::VideoCodecProfile profile,
+ gfx::Size natural_size,
+ bool is_fullscreen,
+ absl::optional<int> average_fps);
+
+ // Return the histogram names. Here so that tests can find them too.
+ static const char* BatteryDeltaHistogram();
+ static const char* ElapsedTimeHistogram();
+
+ // Recompute everything when playback state or power experiment state changes.
+ void OnAnyStateChange();
+
+ // Handle updates about the current battery status.
+ void OnBatteryStatus(device::mojom::BatteryStatusPtr battery_status);
+
+ // Start monitoring if we haven't already. Any outstanding callbacks will be
+ // cancelled if monitoring was already in progress.
+ void StartMonitoring();
+ void StopMonitoring();
+
+ // Register to receive a power update the next time it changes.
+ void QueryNextStatus();
+
+ CreateBatteryMonitorCB create_battery_monitor_cb_;
+
+ // Most recent parameters we were given.
+ bool is_playing_ = false;
+ bool has_video_ = false;
+ media::VideoCodec codec_ = media::VideoCodec::kUnknownVideoCodec;
+ media::VideoCodecProfile profile_ =
+ media::VideoCodecProfile::VIDEO_CODEC_PROFILE_UNKNOWN;
+ gfx::Size natural_size_;
+ bool is_fullscreen_ = false;
+ // For estimating fps. Can be unset if we don't know.
+ absl::optional<int> average_fps_;
+
+ // Current UMA bucket, if any.
+ absl::optional<int> current_bucket_;
+
+ // If set, our previous battery level, from 0-100.
+ absl::optional<float> battery_level_baseline_;
+ // The time at which we last got an update from |battery_monitor_|.
+ base::TimeTicks last_update_;
+
+ // Are we currently the player that should be recording power for the power
+ // experiment, according to the MediaPowerExperimentManager?
+ bool experiment_state_ = false;
+
+ mojo::Remote<device::mojom::BatteryMonitor> battery_monitor_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace media
diff --git a/chromium/media/blink/power_status_helper_unittest.cc b/chromium/media/blink/power_status_helper_unittest.cc
new file mode 100644
index 00000000000..cdacbd7873a
--- /dev/null
+++ b/chromium/media/blink/power_status_helper_unittest.cc
@@ -0,0 +1,445 @@
+// 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 "media/blink/power_status_helper.h"
+
+#include <memory>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "base/run_loop.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/mock_callback.h"
+#include "base/test/task_environment.h"
+#include "media/base/pipeline_metadata.h"
+#include "media/blink/blink_platform_with_task_environment.h"
+#include "services/device/public/mojom/battery_status.mojom.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::Bool;
+using ::testing::Combine;
+using ::testing::Eq;
+using ::testing::Gt;
+using ::testing::Lt;
+using ::testing::ResultOf;
+using ::testing::Return;
+using ::testing::Values;
+
+class PowerStatusHelperTest : public testing::Test {
+ public:
+ class MockBatteryMonitor : public device::mojom::BatteryMonitor {
+ public:
+ MOCK_METHOD0(DidGetBatteryMonitor, void());
+ MOCK_METHOD0(DidQueryNextStatus, void());
+ MOCK_METHOD0(DidDisconnect, void());
+
+ ~MockBatteryMonitor() {
+ // Mojo gets mad if we don't finish up outstanding callbacks.
+ if (callback_)
+ ProvidePowerUpdate(0, 0);
+ }
+
+ // device::mojom::BatteryMonitor
+ void QueryNextStatus(QueryNextStatusCallback callback) override {
+ DidQueryNextStatus();
+ callback_ = std::move(callback);
+ }
+
+ // Would be nice to use a MockCallback for this, but a move-only return type
+ // doesn't seem to work.
+ mojo::PendingRemote<device::mojom::BatteryMonitor> GetBatteryMonitor() {
+ DidGetBatteryMonitor();
+ switch (remote_type_) {
+ case RemoteType::kConnected:
+ case RemoteType::kDisconnected: {
+ auto pending = receiver_.BindNewPipeAndPassRemote();
+ receiver_.set_disconnect_handler(base::BindOnce(
+ &MockBatteryMonitor::DidDisconnect, base::Unretained(this)));
+ if (remote_type_ == RemoteType::kDisconnected)
+ receiver_.reset();
+ base::RunLoop().RunUntilIdle();
+ return pending;
+ }
+ case RemoteType::kEmpty:
+ return mojo::PendingRemote<device::mojom::BatteryMonitor>();
+ }
+ }
+
+ // Would be nice if this were base::MockCallback, but move-only types don't
+ // seem to work.
+ PowerStatusHelper::CreateBatteryMonitorCB cb() {
+ return base::BindRepeating(&MockBatteryMonitor::GetBatteryMonitor,
+ base::Unretained(this));
+ }
+
+ // Provide a battery update via |callback_|.
+ void ProvidePowerUpdate(bool is_charging, float current_level) {
+ EXPECT_TRUE(callback_);
+ device::mojom::BatteryStatusPtr status =
+ device::mojom::BatteryStatus::New(is_charging, 0, /* charging time */
+ 0, /* discharging time */
+ current_level);
+ std::move(callback_).Run(std::move(status));
+ base::RunLoop().RunUntilIdle();
+ }
+
+ mojo::Receiver<device::mojom::BatteryMonitor> receiver_{this};
+
+ // If false, then GetBatteryMonitor will not return a monitor.
+ enum class RemoteType {
+ // Provide a connected remote.
+ kConnected,
+ // Provide an empty PendingRemote
+ kEmpty,
+ // Provide a PendingRemote to a disconnected remote.
+ kDisconnected
+ };
+ RemoteType remote_type_ = RemoteType::kConnected;
+
+ // Most recently provided callback.
+ QueryNextStatusCallback callback_;
+ };
+
+ void SetUp() override {
+ helper_ = std::make_unique<PowerStatusHelper>(monitor_.cb());
+ }
+
+ // Set up |helper_| to be in a state that should record. Returns the bucket.
+ // |alternate| just causes us to create a different recordable bucket.
+ int MakeRecordable(bool alternate = false) {
+ helper_->SetIsPlaying(true);
+ media::PipelineMetadata metadata;
+ metadata.has_video = true;
+ metadata.video_decoder_config = media::VideoDecoderConfig(
+ media::kCodecH264, media::H264PROFILE_MAIN,
+ media::VideoDecoderConfig::AlphaMode::kIsOpaque,
+ media::VideoColorSpace(), media::VideoTransformation(),
+ gfx::Size(0, 0), /* coded_size */
+ gfx::Rect(0, 0), /* visible rect */
+ gfx::Size(640, 360), /* natural size */
+ std::vector<uint8_t>(), /* extra_data */
+ media::EncryptionScheme::kUnencrypted);
+ helper_->SetMetadata(metadata);
+ helper_->SetAverageFrameRate(60);
+ // Use |alternate| to set fullscreen state, since that should still be
+ // recordable but in a different bucket.
+ helper_->SetIsFullscreen(alternate);
+ base::RunLoop().RunUntilIdle();
+ helper_->UpdatePowerExperimentState(true);
+ base::RunLoop().RunUntilIdle();
+
+ return PowerStatusHelper::kCodecBitsH264 |
+ PowerStatusHelper::kResolution360p |
+ PowerStatusHelper::kFrameRate60 |
+ (alternate ? PowerStatusHelper::kFullScreenYes
+ : PowerStatusHelper::kFullScreenNo);
+ }
+
+ void FastForward(base::TimeDelta delta) {
+ BlinkPlatformWithTaskEnvironment::GetTaskEnvironment()->FastForwardBy(
+ delta);
+ }
+
+ // Verify that we've added |battery_delta| and |time_delta| to |bucket| in
+ // both histograms.
+ void VerifyHistogramDelta(int bucket,
+ int battery_delta,
+ base::TimeDelta time_delta) {
+ // Since histograms are cumulative, include the new counts.
+ total_battery_delta += battery_delta;
+ total_time_delta += time_delta.InMilliseconds();
+ histogram_tester_.ExpectBucketCount(helper_->BatteryDeltaHistogram(),
+ bucket, total_battery_delta);
+ histogram_tester_.ExpectBucketCount(helper_->ElapsedTimeHistogram(), bucket,
+ total_time_delta);
+ }
+
+ // Previous total histogram counts. Note that we record the total in msec,
+ // rather than as a TimeDelta, so that we round the same way as the helper.
+ int total_battery_delta = 0;
+ int total_time_delta = 0; // msec
+
+ MockBatteryMonitor monitor_;
+
+ // Helper under test
+ std::unique_ptr<PowerStatusHelper> helper_;
+
+ base::HistogramTester histogram_tester_;
+};
+
+TEST_F(PowerStatusHelperTest, EmptyPendingRemoteIsOkay) {
+ // Enable power monitoring, but have the callback fail to provide a remote.
+ // This should be handled gracefully.
+
+ // Ask |monitor_| not to provide a remote, and expect that |helper_| asks.
+ monitor_.remote_type_ = MockBatteryMonitor::RemoteType::kEmpty;
+ EXPECT_CALL(monitor_, DidGetBatteryMonitor()).Times(1);
+ MakeRecordable();
+}
+
+TEST_F(PowerStatusHelperTest, UnboundPendingRemoteIsOkay) {
+ // TODO: this doesn't run the "is bound" part. maybe we should just delete
+ // the "is bound" part, or switch to a disconnection handler, etc.
+ monitor_.remote_type_ = MockBatteryMonitor::RemoteType::kDisconnected;
+ EXPECT_CALL(monitor_, DidGetBatteryMonitor()).Times(1);
+ MakeRecordable();
+}
+
+TEST_F(PowerStatusHelperTest, BasicReportingWithFractionalAmounts) {
+ // Send three power updates, and verify that an update is called for the
+ // last two. The update should be fractional, so that some of it is rolled
+ // over to the next call.
+ EXPECT_CALL(monitor_, DidGetBatteryMonitor()).Times(1);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ const int bucket = MakeRecordable();
+
+ const float baseline_level = 0.9;
+ // Will round to 10%.
+ const float second_level = baseline_level - 0.106;
+ // Will round to 11% (plus a little).
+ const float third_level = second_level - 0.106;
+
+ // This should be the baseline.
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ monitor_.ProvidePowerUpdate(false, baseline_level);
+
+ // This should trigger recording.
+ base::TimeDelta time_delta = base::TimeDelta::FromSeconds(1);
+ FastForward(time_delta);
+
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ monitor_.ProvidePowerUpdate(false, second_level);
+ VerifyHistogramDelta(bucket, 10, time_delta);
+
+ // This should also record, and pick up the fractional percentage drop that
+ // wasn't included in the previous one.
+ FastForward(time_delta);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ monitor_.ProvidePowerUpdate(false, third_level);
+ VerifyHistogramDelta(bucket, 11, time_delta);
+}
+
+TEST_F(PowerStatusHelperTest, ChargingResetsBaseline) {
+ // Send some power updates, then send an update that's marked as 'charging'.
+ // Make sure that the baseline resets.
+ EXPECT_CALL(monitor_, DidGetBatteryMonitor()).Times(1);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ const int bucket = MakeRecordable();
+
+ const float fake_baseline_level = 0.95;
+ const float baseline_level = 0.9;
+ const float second_level = baseline_level - 0.10;
+
+ // Send the fake baseline.
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ monitor_.ProvidePowerUpdate(false, fake_baseline_level);
+
+ // Send an update that's marked as charging.
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ monitor_.ProvidePowerUpdate(true, second_level);
+
+ // This should be the correct baseline.
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ monitor_.ProvidePowerUpdate(false, baseline_level);
+
+ // This should trigger recording.
+ base::TimeDelta time_delta = base::TimeDelta::FromSeconds(1);
+ FastForward(time_delta);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ monitor_.ProvidePowerUpdate(false, second_level);
+ VerifyHistogramDelta(bucket, 10, time_delta);
+}
+
+TEST_F(PowerStatusHelperTest, ExperimentStateStopsRecording) {
+ // Verify that stopping the power experiment stops recording.
+ EXPECT_CALL(monitor_, DidGetBatteryMonitor()).Times(1);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ MakeRecordable();
+
+ EXPECT_CALL(monitor_, DidDisconnect()).Times(1);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(0);
+ helper_->UpdatePowerExperimentState(false);
+ base::RunLoop().RunUntilIdle();
+
+ // Call the callback to make sure nothing bad happens. It should be ignored,
+ // since it shouldn't use battery updates after the experiment stops.
+ monitor_.ProvidePowerUpdate(false, 1.0);
+}
+
+TEST_F(PowerStatusHelperTest, ChangingBucketsWorks) {
+ // Switch buckets mid-recording, and make sure that we get a new bucket and
+ // use a new baseline.
+ EXPECT_CALL(monitor_, DidGetBatteryMonitor()).Times(1);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ auto first_bucket = MakeRecordable(false);
+
+ const float fake_baseline_level = 0.95;
+ const float baseline_level = 0.9;
+ const float second_level = baseline_level - 0.10;
+
+ // Send the fake baseline.
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ monitor_.ProvidePowerUpdate(false, fake_baseline_level);
+
+ // Switch buckets.
+ auto second_bucket = MakeRecordable(true);
+ ASSERT_NE(first_bucket, second_bucket);
+
+ // This should be the correct baseline.
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ monitor_.ProvidePowerUpdate(false, baseline_level);
+
+ // This should trigger recording.
+ base::TimeDelta time_delta = base::TimeDelta::FromSeconds(1);
+ FastForward(time_delta);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ monitor_.ProvidePowerUpdate(false, second_level);
+ VerifyHistogramDelta(second_bucket, 10, time_delta);
+}
+
+TEST_F(PowerStatusHelperTest, UnbucketedVideoStopsRecording) {
+ // If we switch to video that doesn't have a bucket, then recording should
+ // stop too.
+ EXPECT_CALL(monitor_, DidGetBatteryMonitor()).Times(1);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ MakeRecordable();
+
+ // Should disconnect when we send bad params.
+ EXPECT_CALL(monitor_, DidDisconnect()).Times(1);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(0);
+ helper_->SetIsPlaying(false);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(PowerStatusHelperTest, UnbucketedFrameRateStopsRecording) {
+ // If we switch to an unbucketed frame rate, then it should stop recording.
+ EXPECT_CALL(monitor_, DidGetBatteryMonitor()).Times(1);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(1);
+ MakeRecordable();
+
+ // Should disconnect when we send bad params.
+ EXPECT_CALL(monitor_, DidDisconnect()).Times(1);
+ EXPECT_CALL(monitor_, DidQueryNextStatus()).Times(0);
+ helper_->SetAverageFrameRate({});
+ base::RunLoop().RunUntilIdle();
+}
+
+using PlaybackParamsTuple = std::tuple<bool, /* is_playing */
+ bool, /* has_video */
+ PowerStatusHelper::Bits, /* codec */
+ PowerStatusHelper::Bits, /* resolution */
+ PowerStatusHelper::Bits, /* frame rate */
+ PowerStatusHelper::Bits /* full screen */
+ >;
+
+class PowerStatusHelperBucketTest
+ : public testing::TestWithParam<PlaybackParamsTuple> {
+ public:
+ absl::optional<int> BucketFor(bool is_playing,
+ bool has_video,
+ media::VideoCodec codec,
+ media::VideoCodecProfile profile,
+ gfx::Size coded_size,
+ bool is_fullscreen,
+ absl::optional<int> average_fps) {
+ return PowerStatusHelper::BucketFor(is_playing, has_video, codec, profile,
+ coded_size, is_fullscreen, average_fps);
+ }
+};
+
+TEST_P(PowerStatusHelperBucketTest, TestBucket) {
+ // Construct a params that should end up in the bucket specified by the test
+ // parameter, if one exists.
+ bool expect_bucket = true;
+
+ bool is_playing = std::get<0>(GetParam());
+ bool has_video = std::get<1>(GetParam());
+
+ // We must be playing video to get a bucket.
+ if (!is_playing || !has_video)
+ expect_bucket = false;
+
+ auto codec_bits = std::get<2>(GetParam());
+ media::VideoCodec codec;
+ media::VideoCodecProfile profile;
+ if (codec_bits == PowerStatusHelper::Bits::kCodecBitsH264) {
+ codec = media::kCodecH264;
+ profile = media::H264PROFILE_MAIN;
+ } else if (codec_bits == PowerStatusHelper::Bits::kCodecBitsVP9Profile0) {
+ codec = media::kCodecVP9;
+ profile = media::VP9PROFILE_PROFILE0;
+ } else if (codec_bits == PowerStatusHelper::Bits::kCodecBitsVP9Profile2) {
+ codec = media::kCodecVP9;
+ profile = media::VP9PROFILE_PROFILE2;
+ } else {
+ // Some unsupported codec.
+ codec = media::kCodecVP8;
+ profile = media::VIDEO_CODEC_PROFILE_UNKNOWN;
+ expect_bucket = false;
+ }
+
+ auto res = std::get<3>(GetParam());
+ gfx::Size coded_size;
+ if (res == PowerStatusHelper::Bits::kResolution360p) {
+ coded_size = gfx::Size(640, 360);
+ } else if (res == PowerStatusHelper::Bits::kResolution720p) {
+ coded_size = gfx::Size(1280, 720);
+ } else if (res == PowerStatusHelper::Bits::kResolution1080p) {
+ coded_size = gfx::Size(1920, 1080);
+ } else {
+ coded_size = gfx::Size(1234, 5678);
+ expect_bucket = false;
+ }
+
+ auto fps = std::get<4>(GetParam());
+ absl::optional<int> average_fps;
+ if (fps == PowerStatusHelper::Bits::kFrameRate30) {
+ average_fps = 30;
+ } else if (fps == PowerStatusHelper::Bits::kFrameRate60) {
+ average_fps = 60;
+ } else {
+ average_fps = 90;
+ expect_bucket = false;
+ }
+
+ bool is_fullscreen =
+ (std::get<5>(GetParam()) == PowerStatusHelper::Bits::kFullScreenYes);
+
+ auto bucket = BucketFor(is_playing, has_video, codec, profile, coded_size,
+ is_fullscreen, average_fps);
+ if (!expect_bucket) {
+ EXPECT_FALSE(bucket);
+ } else {
+ EXPECT_EQ(*bucket, std::get<2>(GetParam()) | std::get<3>(GetParam()) |
+ std::get<4>(GetParam()) | std::get<5>(GetParam()));
+ }
+}
+
+// Instantiate all valid combinations, plus some that aren't.
+INSTANTIATE_TEST_SUITE_P(
+ All,
+ PowerStatusHelperBucketTest,
+ Combine(Bool(),
+ Bool(),
+ Values(PowerStatusHelper::Bits::kCodecBitsH264,
+ PowerStatusHelper::Bits::kCodecBitsVP9Profile0,
+ PowerStatusHelper::Bits::kCodecBitsVP9Profile2,
+ PowerStatusHelper::Bits::kNotAValidBitForTesting),
+ Values(PowerStatusHelper::Bits::kResolution360p,
+ PowerStatusHelper::Bits::kResolution720p,
+ PowerStatusHelper::Bits::kResolution1080p,
+ PowerStatusHelper::Bits::kNotAValidBitForTesting),
+ Values(PowerStatusHelper::Bits::kFrameRate30,
+ PowerStatusHelper::Bits::kFrameRate60,
+ PowerStatusHelper::Bits::kNotAValidBitForTesting),
+ Values(PowerStatusHelper::Bits::kFullScreenNo,
+ PowerStatusHelper::Bits::kFullScreenYes)));
+
+} // namespace media
diff --git a/chromium/media/blink/resource_fetch_context.h b/chromium/media/blink/resource_fetch_context.h
index e517811384d..588347c7760 100644
--- a/chromium/media/blink/resource_fetch_context.h
+++ b/chromium/media/blink/resource_fetch_context.h
@@ -8,7 +8,6 @@
#include <memory>
#include "media/blink/media_blink_export.h"
-#include "services/network/public/mojom/referrer_policy.mojom.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_associated_url_loader.h"
#include "third_party/blink/public/web/web_associated_url_loader_options.h"
diff --git a/chromium/media/blink/resource_multibuffer_data_provider.cc b/chromium/media/blink/resource_multibuffer_data_provider.cc
index 3b9795f8d1a..3b369c0d924 100644
--- a/chromium/media/blink/resource_multibuffer_data_provider.cc
+++ b/chromium/media/blink/resource_multibuffer_data_provider.cc
@@ -17,7 +17,6 @@
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "media/blink/cache_util.h"
-#include "media/blink/media_blink_export.h"
#include "media/blink/resource_fetch_context.h"
#include "media/blink/url_index.h"
#include "net/http/http_byte_range.h"
@@ -564,7 +563,7 @@ bool ResourceMultiBufferDataProvider::VerifyPartialResponse(
return false;
}
- if (url_data_->length() == kPositionNotSpecified) {
+ if (url_data->length() == kPositionNotSpecified) {
url_data->set_length(instance_size);
}
diff --git a/chromium/media/blink/resource_multibuffer_data_provider_unittest.cc b/chromium/media/blink/resource_multibuffer_data_provider_unittest.cc
index 2a2958d0231..56df066b396 100644
--- a/chromium/media/blink/resource_multibuffer_data_provider_unittest.cc
+++ b/chromium/media/blink/resource_multibuffer_data_provider_unittest.cc
@@ -325,6 +325,16 @@ TEST_F(ResourceMultiBufferDataProviderTest, TestRedirects) {
StopWhenLoad();
}
+// Tests partial response after a redirect.
+TEST_F(ResourceMultiBufferDataProviderTest, TestRedirectedPartialResponse) {
+ Initialize(kHttpUrl, 0);
+ Start();
+ PartialResponse(0, 2048, 32000);
+ Redirect(kHttpRedirect);
+ PartialResponse(2048, 4096, 32000);
+ StopWhenLoad();
+}
+
TEST_F(ResourceMultiBufferDataProviderTest, TestSaveDataFRFRPreviewsState) {
struct TestCase {
std::string label;
diff --git a/chromium/media/blink/smoothness_helper.cc b/chromium/media/blink/smoothness_helper.cc
index 267697d4e5c..5c8e7b8e378 100644
--- a/chromium/media/blink/smoothness_helper.cc
+++ b/chromium/media/blink/smoothness_helper.cc
@@ -5,10 +5,10 @@
#include "media/blink/smoothness_helper.h"
#include "base/bind.h"
-#include "base/optional.h"
#include "base/timer/timer.h"
#include "base/unguessable_token.h"
#include "media/learning/common/learning_task_controller.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace {
static constexpr base::TimeDelta kSegmentSize =
@@ -191,7 +191,7 @@ class SmoothnessHelperImpl : public SmoothnessHelper {
private:
// If an observation is in progress, then this is the id.
- base::Optional<base::UnguessableToken> id_;
+ absl::optional<base::UnguessableToken> id_;
std::unique_ptr<LearningTaskController> controller_;
TargetValue target_value_;
@@ -207,7 +207,7 @@ class SmoothnessHelperImpl : public SmoothnessHelper {
struct Task consecutive_nnr_;
// Time of the most recent nnr.
- base::Optional<base::TimeTicks> most_recent_nnr_;
+ absl::optional<base::TimeTicks> most_recent_nnr_;
// Number of NNRs that have occurred within |kMaxNNRDistance|.
int num_consecutive_nnrs_ = 0;
diff --git a/chromium/media/blink/smoothness_helper_unittest.cc b/chromium/media/blink/smoothness_helper_unittest.cc
index 2162f5952f6..d706573e41c 100644
--- a/chromium/media/blink/smoothness_helper_unittest.cc
+++ b/chromium/media/blink/smoothness_helper_unittest.cc
@@ -30,11 +30,11 @@ using testing::Return;
// Helper for EXPECT_CALL argument matching on Optional<TargetValue>. Applies
// matcher |m| to the TargetValue as a double. For example:
-// void Foo(base::Optional<TargetValue>);
+// void Foo(absl::optional<TargetValue>);
// EXPECT_CALL(..., Foo(OPT_TARGET(Gt(0.9)))) will expect that the value of the
// Optional<TargetValue> passed to Foo() to be greather than 0.9 .
#define OPT_TARGET(m) \
- ResultOf([](const base::Optional<TargetValue>& v) { return (*v).value(); }, m)
+ ResultOf([](const absl::optional<TargetValue>& v) { return (*v).value(); }, m)
// Same as above, but expects an ObservationCompletion.
#define COMPLETION_TARGET(m) \
@@ -48,8 +48,8 @@ class SmoothnessHelperTest : public testing::Test {
MOCK_METHOD4(BeginObservation,
void(base::UnguessableToken id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target,
- const base::Optional<ukm::SourceId>& source_id));
+ const absl::optional<TargetValue>& default_target,
+ const absl::optional<ukm::SourceId>& source_id));
MOCK_METHOD2(CompleteObservation,
void(base::UnguessableToken id,
@@ -59,7 +59,7 @@ class SmoothnessHelperTest : public testing::Test {
MOCK_METHOD2(UpdateDefaultTarget,
void(base::UnguessableToken id,
- const base::Optional<TargetValue>& default_target));
+ const absl::optional<TargetValue>& default_target));
MOCK_METHOD0(GetLearningTask, const LearningTask&());
MOCK_METHOD2(PredictDistribution,
@@ -87,8 +87,8 @@ class SmoothnessHelperTest : public testing::Test {
}
// Helper for EXPECT_CALL.
- base::Optional<TargetValue> Opt(double x) {
- return base::Optional<TargetValue>(TargetValue(x));
+ absl::optional<TargetValue> Opt(double x) {
+ return absl::optional<TargetValue>(TargetValue(x));
}
void FastForwardBy(base::TimeDelta amount) {
diff --git a/chromium/media/blink/url_index.cc b/chromium/media/blink/url_index.cc
index 701a0977457..af704d17757 100644
--- a/chromium/media/blink/url_index.cc
+++ b/chromium/media/blink/url_index.cc
@@ -59,12 +59,12 @@ UrlData::UrlData(const GURL& url, CorsMode cors_mode, UrlIndex* url_index)
UrlData::~UrlData() = default;
std::pair<GURL, UrlData::CorsMode> UrlData::key() const {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return std::make_pair(url(), cors_mode());
}
void UrlData::set_valid_until(base::Time valid_until) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
valid_until_ = valid_until;
}
@@ -73,7 +73,7 @@ void UrlData::MergeFrom(const scoped_refptr<UrlData>& other) {
// resource, so when we merge the metadata, we can use the most
// optimistic values.
if (ValidateDataOrigin(other->data_origin_)) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
valid_until_ = std::max(valid_until_, other->valid_until_);
// set_length() will not override the length if already known.
set_length(other->length_);
@@ -91,12 +91,12 @@ void UrlData::MergeFrom(const scoped_refptr<UrlData>& other) {
}
void UrlData::set_cacheable(bool cacheable) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
cacheable_ = cacheable;
}
void UrlData::set_length(int64_t length) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (length != kPositionNotSpecified) {
length_ = length;
}
@@ -113,7 +113,7 @@ void UrlData::set_has_access_control() {
}
void UrlData::RedirectTo(const scoped_refptr<UrlData>& url_data) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Copy any cached data over to the new location.
url_data->multibuffer()->MergeFrom(multibuffer());
@@ -125,7 +125,7 @@ void UrlData::RedirectTo(const scoped_refptr<UrlData>& url_data) {
}
void UrlData::Fail() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Handled similar to a redirect.
std::vector<RedirectCB> redirect_callbacks;
redirect_callbacks.swap(redirect_callbacks_);
@@ -135,12 +135,12 @@ void UrlData::Fail() {
}
void UrlData::OnRedirect(RedirectCB cb) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
redirect_callbacks_.push_back(std::move(cb));
}
void UrlData::Use() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
last_used_ = base::Time::Now();
}
@@ -158,12 +158,12 @@ bool UrlData::ValidateDataOrigin(const GURL& origin) {
}
void UrlData::OnEmpty() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
url_index_->RemoveUrlData(this);
}
bool UrlData::FullyCached() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (length_ == kPositionNotSpecified)
return false;
// Check that the first unavailable block in the cache is after the
@@ -172,7 +172,7 @@ bool UrlData::FullyCached() {
}
bool UrlData::Valid() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
base::Time now = base::Time::Now();
if (!range_supported_ && !FullyCached())
return false;
@@ -186,27 +186,27 @@ bool UrlData::Valid() {
}
void UrlData::set_last_modified(base::Time last_modified) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
last_modified_ = last_modified;
}
void UrlData::set_etag(const std::string& etag) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
etag_ = etag;
}
void UrlData::set_range_supported() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
range_supported_ = true;
}
ResourceMultiBuffer* UrlData::multibuffer() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return &multibuffer_;
}
size_t UrlData::CachedSize() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return multibuffer()->map().size();
}
diff --git a/chromium/media/blink/url_index.h b/chromium/media/blink/url_index.h
index 80eef9a7e8a..88c595fc93d 100644
--- a/chromium/media/blink/url_index.h
+++ b/chromium/media/blink/url_index.h
@@ -16,10 +16,8 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
-#include "media/blink/lru.h"
#include "media/blink/media_blink_export.h"
#include "media/blink/multibuffer.h"
-#include "services/network/public/mojom/fetch_api.mojom.h"
#include "url/gurl.h"
namespace media {
@@ -216,7 +214,8 @@ class MEDIA_BLINK_EXPORT UrlData : public base::RefCounted<UrlData> {
ResourceMultiBuffer multibuffer_;
std::vector<RedirectCB> redirect_callbacks_;
- base::ThreadChecker thread_checker_;
+ THREAD_CHECKER(thread_checker_);
+
DISALLOW_COPY_AND_ASSIGN(UrlData);
};
diff --git a/chromium/media/blink/url_index_unittest.cc b/chromium/media/blink/url_index_unittest.cc
index 0f3bcfa16fd..3933710f132 100644
--- a/chromium/media/blink/url_index_unittest.cc
+++ b/chromium/media/blink/url_index_unittest.cc
@@ -9,7 +9,6 @@
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
#include "media/base/media_switches.h"
#include "media/blink/url_index.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/media/blink/video_decode_stats_reporter.cc b/chromium/media/blink/video_decode_stats_reporter.cc
index e78848d28c7..ba9d1f853f5 100644
--- a/chromium/media/blink/video_decode_stats_reporter.cc
+++ b/chromium/media/blink/video_decode_stats_reporter.cc
@@ -21,7 +21,7 @@ VideoDecodeStatsReporter::VideoDecodeStatsReporter(
VideoCodecProfile codec_profile,
const gfx::Size& natural_size,
std::string key_system,
- base::Optional<CdmConfig> cdm_config,
+ absl::optional<CdmConfig> cdm_config,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const base::TickClock* tick_clock)
: kRecordingInterval(
diff --git a/chromium/media/blink/video_decode_stats_reporter.h b/chromium/media/blink/video_decode_stats_reporter.h
index e430e7dda4b..cd641deb074 100644
--- a/chromium/media/blink/video_decode_stats_reporter.h
+++ b/chromium/media/blink/video_decode_stats_reporter.h
@@ -10,7 +10,6 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
@@ -23,6 +22,8 @@
#include "media/mojo/mojom/video_decode_stats_recorder.mojom.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/gfx/geometry/size.h"
namespace media {
@@ -40,7 +41,7 @@ class MEDIA_BLINK_EXPORT VideoDecodeStatsReporter {
VideoCodecProfile codec_profile,
const gfx::Size& natural_size,
std::string key_system,
- base::Optional<CdmConfig> cdm_config,
+ absl::optional<CdmConfig> cdm_config,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const base::TickClock* tick_clock =
base::DefaultTickClock::GetInstance());
diff --git a/chromium/media/blink/video_decode_stats_reporter_unittest.cc b/chromium/media/blink/video_decode_stats_reporter_unittest.cc
index 96a8f1e6a2d..4661354b5b0 100644
--- a/chromium/media/blink/video_decode_stats_reporter_unittest.cc
+++ b/chromium/media/blink/video_decode_stats_reporter_unittest.cc
@@ -7,7 +7,6 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/task/current_thread.h"
#include "base/test/test_mock_time_task_runner.h"
@@ -25,6 +24,7 @@
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/rect.h"
using ::testing::Invoke;
@@ -186,7 +186,7 @@ class VideoDecodeStatsReporterTest : public ::testing::Test {
VideoCodecProfile profile = kDefaultProfile,
const gfx::Size& natural_size = gfx::Size(kDefaultWidth, kDefaultHeight),
const std::string key_system = kDefaultKeySystem,
- const base::Optional<CdmConfig> cdm_config = kDefaultCdmConfig) {
+ const absl::optional<CdmConfig> cdm_config = kDefaultCdmConfig) {
reporter_ = std::make_unique<VideoDecodeStatsReporter>(
SetupRecordInterceptor(&interceptor_),
base::BindRepeating(&VideoDecodeStatsReporterTest::GetPipelineStatsCB,
@@ -875,7 +875,7 @@ TEST_F(VideoDecodeStatsReporterTest, VaryEmeProperties) {
const char kFooKeySystem[] = "fookeysytem";
// Make reporter with no EME properties.
- MakeReporter(kDefaultProfile, kDefaultSize, kEmptyKeySystem, base::nullopt);
+ MakeReporter(kDefaultProfile, kDefaultSize, kEmptyKeySystem, absl::nullopt);
// Verify the empty key system and non-default hw_secure_codecs.
StartPlayingAndStabilizeFramerate(kDefaultProfile, kDefaultSize, kDefaultFps,
kEmptyKeySystem, kNonDefaultHwSecureCodecs);
diff --git a/chromium/media/blink/video_frame_compositor.cc b/chromium/media/blink/video_frame_compositor.cc
index 344d3c4a483..16e48bf22b0 100644
--- a/chromium/media/blink/video_frame_compositor.cc
+++ b/chromium/media/blink/video_frame_compositor.cc
@@ -15,7 +15,6 @@
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "media/base/media_switches.h"
#include "media/base/video_frame.h"
-#include "media/blink/webmediaplayer_params.h"
#include "third_party/blink/public/platform/web_video_frame_submitter.h"
namespace media {
diff --git a/chromium/media/blink/video_frame_compositor.h b/chromium/media/blink/video_frame_compositor.h
index 8ee417924fe..2c7c535d558 100644
--- a/chromium/media/blink/video_frame_compositor.h
+++ b/chromium/media/blink/video_frame_compositor.h
@@ -21,9 +21,8 @@
#include "cc/layers/video_frame_provider.h"
#include "media/base/video_renderer_sink.h"
#include "media/blink/media_blink_export.h"
-#include "media/blink/webmediaplayer_params.h"
+#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/public/platform/web_video_frame_submitter.h"
-#include "ui/gfx/geometry/size.h"
namespace base {
class WaitableEvent;
diff --git a/chromium/media/blink/video_frame_compositor_unittest.cc b/chromium/media/blink/video_frame_compositor_unittest.cc
index cd8ef477441..e1491b2d8ab 100644
--- a/chromium/media/blink/video_frame_compositor_unittest.cc
+++ b/chromium/media/blink/video_frame_compositor_unittest.cc
@@ -6,8 +6,10 @@
#include "base/bind.h"
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/synchronization/waitable_event.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/simple_test_tick_clock.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "media/base/video_frame.h"
diff --git a/chromium/media/blink/webcontentdecryptionmodulesession_impl.cc b/chromium/media/blink/webcontentdecryptionmodulesession_impl.cc
index 64e17e577eb..0be92465c3e 100644
--- a/chromium/media/blink/webcontentdecryptionmodulesession_impl.cc
+++ b/chromium/media/blink/webcontentdecryptionmodulesession_impl.cc
@@ -233,7 +233,7 @@ WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl(
WebContentDecryptionModuleSessionImpl::
~WebContentDecryptionModuleSessionImpl() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!session_id_.empty()) {
adapter_->UnregisterSession(session_id_);
@@ -271,7 +271,7 @@ void WebContentDecryptionModuleSessionImpl::InitializeNewSession(
blink::WebContentDecryptionModuleResult result) {
DCHECK(init_data);
DCHECK(session_id_.empty());
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// From https://w3c.github.io/encrypted-media/#generateRequest.
// 6. If the Key System implementation represented by this object's cdm
@@ -347,7 +347,7 @@ void WebContentDecryptionModuleSessionImpl::Load(
blink::WebContentDecryptionModuleResult result) {
DCHECK(!session_id.IsEmpty());
DCHECK(session_id_.empty());
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(session_type_ == CdmSessionType::kPersistentLicense);
// From https://w3c.github.io/encrypted-media/#load.
@@ -382,7 +382,7 @@ void WebContentDecryptionModuleSessionImpl::Update(
blink::WebContentDecryptionModuleResult result) {
DCHECK(response);
DCHECK(!session_id_.empty());
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// From https://w3c.github.io/encrypted-media/#update.
// 6.1 Let sanitized response be a validated and/or sanitized version of
@@ -412,7 +412,7 @@ void WebContentDecryptionModuleSessionImpl::Update(
void WebContentDecryptionModuleSessionImpl::Close(
blink::WebContentDecryptionModuleResult result) {
DCHECK(!session_id_.empty());
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// close() shouldn't be called if the session is already closed. Since the
// operation is asynchronous, there is a window where close() was called
@@ -434,7 +434,7 @@ void WebContentDecryptionModuleSessionImpl::Close(
void WebContentDecryptionModuleSessionImpl::Remove(
blink::WebContentDecryptionModuleResult result) {
DCHECK(!session_id_.empty());
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
adapter_->RemoveSession(
session_id_,
@@ -446,7 +446,7 @@ void WebContentDecryptionModuleSessionImpl::OnSessionMessage(
CdmMessageType message_type,
const std::vector<uint8_t>& message) {
DCHECK(client_) << "Client not set before message event";
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
client_->OnSessionMessage(convertMessageType(message_type), message.data(),
message.size());
}
@@ -454,7 +454,7 @@ void WebContentDecryptionModuleSessionImpl::OnSessionMessage(
void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange(
bool has_additional_usable_key,
CdmKeysInfo keys_info) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
blink::WebVector<blink::WebEncryptedMediaKeyInformation> keys(
keys_info.size());
for (size_t i = 0; i < keys_info.size(); ++i) {
@@ -475,7 +475,7 @@ void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange(
void WebContentDecryptionModuleSessionImpl::OnSessionExpirationUpdate(
base::Time new_expiry_time) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// The check works around an issue in base::Time that converts null base::Time
// to |1601-01-01 00:00:00 UTC| in ToJsTime(). See http://crbug.com/679079
client_->OnSessionExpirationUpdate(
@@ -484,7 +484,7 @@ void WebContentDecryptionModuleSessionImpl::OnSessionExpirationUpdate(
}
void WebContentDecryptionModuleSessionImpl::OnSessionClosed() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Only send one closed event to blink.
if (is_closed_)
@@ -497,7 +497,7 @@ void WebContentDecryptionModuleSessionImpl::OnSessionClosed() {
void WebContentDecryptionModuleSessionImpl::OnSessionInitialized(
const std::string& session_id,
SessionInitStatus* status) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// CDM will return NULL if the session to be loaded can't be found.
if (session_id.empty()) {
*status = SessionInitStatus::SESSION_NOT_FOUND;
diff --git a/chromium/media/blink/webcontentdecryptionmodulesession_impl.h b/chromium/media/blink/webcontentdecryptionmodulesession_impl.h
index b6c4572e96f..2bdb47aca03 100644
--- a/chromium/media/blink/webcontentdecryptionmodulesession_impl.h
+++ b/chromium/media/blink/webcontentdecryptionmodulesession_impl.h
@@ -88,7 +88,8 @@ class WebContentDecryptionModuleSessionImpl
bool has_close_been_called_;
bool is_closed_;
- base::ThreadChecker thread_checker_;
+ THREAD_CHECKER(thread_checker_);
+
// Since promises will live until they are fired, use a weak reference when
// creating a promise in case this class disappears before the promise
// actually fires.
diff --git a/chromium/media/blink/webencryptedmediaclient_impl.cc b/chromium/media/blink/webencryptedmediaclient_impl.cc
index 9460a70ff04..125f22d3c48 100644
--- a/chromium/media/blink/webencryptedmediaclient_impl.cc
+++ b/chromium/media/blink/webencryptedmediaclient_impl.cc
@@ -15,14 +15,11 @@
#include "media/base/media_permission.h"
#include "media/blink/webcontentdecryptionmodule_impl.h"
#include "media/blink/webcontentdecryptionmoduleaccess_impl.h"
-#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_content_decryption_module_result.h"
#include "third_party/blink/public/platform/web_encrypted_media_request.h"
#include "third_party/blink/public/platform/web_media_key_system_configuration.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_string.h"
-#include "url/gurl.h"
-#include "url/origin.h"
namespace media {
diff --git a/chromium/media/blink/webmediaplayer_impl.cc b/chromium/media/blink/webmediaplayer_impl.cc
index 8fe58a83c76..ce5762369f3 100644
--- a/chromium/media/blink/webmediaplayer_impl.cc
+++ b/chromium/media/blink/webmediaplayer_impl.cc
@@ -23,6 +23,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/task_runner_util.h"
@@ -31,6 +32,7 @@
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/layers/video_layer.h"
+#include "components/viz/common/gpu/raster_context_provider.h"
#include "media/audio/null_audio_sink.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/cdm_context.h"
@@ -44,6 +46,7 @@
#include "media/base/text_renderer.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_frame.h"
+#include "media/blink/power_status_helper.h"
#include "media/blink/texttrack_impl.h"
#include "media/blink/url_index.h"
#include "media/blink/video_decode_stats_reporter.h"
@@ -53,11 +56,15 @@
#include "media/filters/chunk_demuxer.h"
#include "media/filters/ffmpeg_demuxer.h"
#include "media/filters/memory_data_source.h"
+#include "media/filters/pipeline_controller.h"
+#include "media/learning/common/learning_task_controller.h"
+#include "media/learning/common/media_learning_tasks.h"
#include "media/learning/mojo/public/cpp/mojo_learning_task_controller.h"
#include "media/media_buildflags.h"
#include "media/remoting/remoting_constants.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/data_url.h"
+#include "third_party/blink/public/common/media/display_type.h"
#include "third_party/blink/public/common/media/watch_time_reporter.h"
#include "third_party/blink/public/platform/web_encrypted_media_types.h"
#include "third_party/blink/public/platform/web_fullscreen_video_status.h"
@@ -78,6 +85,7 @@
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_view.h"
+#include "ui/gfx/geometry/size.h"
#if defined(OS_ANDROID)
#include "media/base/android/media_codec_util.h"
@@ -97,7 +105,7 @@ namespace {
const char kWatchTimeHistogram[] = "Media.WebMediaPlayerImpl.WatchTime";
-void RecordSimpleWatchTimeUMA(RendererFactoryType type) {
+void RecordSimpleWatchTimeUMA(RendererType type) {
UMA_HISTOGRAM_ENUMERATION(kWatchTimeHistogram, type);
}
@@ -1037,7 +1045,7 @@ void WebMediaPlayerImpl::SetVolume(double volume) {
void WebMediaPlayerImpl::SetLatencyHint(double seconds) {
DVLOG(1) << __func__ << "(" << seconds << ")";
DCHECK(main_task_runner_->BelongsToCurrentThread());
- base::Optional<base::TimeDelta> latency_hint;
+ absl::optional<base::TimeDelta> latency_hint;
if (std::isfinite(seconds)) {
DCHECK_GE(seconds, 0);
latency_hint = base::TimeDelta::FromSecondsD(seconds);
@@ -1124,7 +1132,7 @@ void WebMediaPlayerImpl::SelectedVideoTrackChanged(
blink::WebMediaPlayer::TrackId* selectedTrackId) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- base::Optional<MediaTrack::Id> selected_video_track_id;
+ absl::optional<MediaTrack::Id> selected_video_track_id;
if (selectedTrackId && !video_track_disabled_)
selected_video_track_id = MediaTrack::Id(selectedTrackId->Utf8().data());
MEDIA_LOG(INFO, media_log_.get())
@@ -1791,8 +1799,7 @@ void WebMediaPlayerImpl::OnError(PipelineStatus status) {
"Media.WebMediaPlayerImpl.HLS.IsMixedContent",
frame_url_is_cryptographic && !manifest_url_is_cryptographic);
- renderer_factory_selector_->SetBaseFactoryType(
- RendererFactoryType::kMediaPlayer);
+ renderer_factory_selector_->SetBaseRendererType(RendererType::kMediaPlayer);
loaded_url_ = mb_data_source_->GetUrlAfterRedirects();
DCHECK(data_source_);
@@ -2342,7 +2349,7 @@ void WebMediaPlayerImpl::OnVideoOpacityChange(bool opaque) {
bridge_->SetContentsOpaque(opaque_);
}
-void WebMediaPlayerImpl::OnVideoFrameRateChange(base::Optional<int> fps) {
+void WebMediaPlayerImpl::OnVideoFrameRateChange(absl::optional<int> fps) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
if (power_status_helper_)
power_status_helper_->SetAverageFrameRate(fps);
@@ -2717,7 +2724,7 @@ void WebMediaPlayerImpl::MaybeSendOverlayInfoToDecoder() {
}
std::unique_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer(
- base::Optional<RendererFactoryType> factory_type) {
+ absl::optional<RendererType> renderer_type) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
// Make sure that overlays are enabled if they're always allowed.
@@ -2730,13 +2737,14 @@ std::unique_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer(
&WebMediaPlayerImpl::OnOverlayInfoRequested, weak_this_));
#endif
- if (factory_type) {
+ if (renderer_type) {
DVLOG(1) << __func__
- << ": factory_type=" << static_cast<int>(factory_type.value());
- renderer_factory_selector_->SetBaseFactoryType(factory_type.value());
+ << ": renderer_type=" << static_cast<int>(renderer_type.value());
+ renderer_factory_selector_->SetBaseRendererType(renderer_type.value());
}
- reported_renderer_type_ = renderer_factory_selector_->GetCurrentFactoryType();
+ reported_renderer_type_ =
+ renderer_factory_selector_->GetCurrentRendererType();
return renderer_factory_selector_->GetCurrentFactory()->CreateRenderer(
media_task_runner_, worker_task_runner_, audio_source_provider_.get(),
@@ -3077,7 +3085,7 @@ WebMediaPlayerImpl::UpdatePlayState_ComputePlayState(bool is_flinging,
// TODO(sandersd): Make the delegate suspend idle players immediately when
// hidden.
bool idle_suspended = can_auto_suspend && is_stale && paused_ && !seeking_ &&
- !overlay_enabled_ && !needs_first_frame_;
+ !overlay_info_.is_fullscreen && !needs_first_frame_;
// If we're already suspended, see if we can wait for user interaction. Prior
// to kReadyStateHaveMetadata, we require |is_stale| to remain suspended.
@@ -3299,7 +3307,7 @@ void WebMediaPlayerImpl::ScheduleIdlePauseTimer() {
// Idle timeout chosen arbitrarily.
background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5),
client_,
- &blink::WebMediaPlayerClient::ResumePlayback);
+ &blink::WebMediaPlayerClient::PausePlayback);
}
void WebMediaPlayerImpl::CreateWatchTimeReporter() {
@@ -3423,9 +3431,9 @@ int WebMediaPlayerImpl::GetDelegateId() {
return delegate_id_;
}
-base::Optional<viz::SurfaceId> WebMediaPlayerImpl::GetSurfaceId() {
+absl::optional<viz::SurfaceId> WebMediaPlayerImpl::GetSurfaceId() {
if (!surface_layer_for_video_enabled_)
- return base::nullopt;
+ return absl::nullopt;
return bridge_->GetSurfaceId();
}
@@ -3615,7 +3623,7 @@ void WebMediaPlayerImpl::DisableVideoTrackIfNeeded() {
void WebMediaPlayerImpl::SetPipelineStatisticsForTest(
const PipelineStatistics& stats) {
- pipeline_statistics_for_test_ = base::make_optional(stats);
+ pipeline_statistics_for_test_ = absl::make_optional(stats);
}
PipelineStatistics WebMediaPlayerImpl::GetPipelineStatistics() const {
@@ -3627,7 +3635,7 @@ PipelineStatistics WebMediaPlayerImpl::GetPipelineStatistics() const {
void WebMediaPlayerImpl::SetPipelineMediaDurationForTest(
base::TimeDelta duration) {
- pipeline_media_duration_for_test_ = base::make_optional(duration);
+ pipeline_media_duration_for_test_ = absl::make_optional(duration);
}
base::TimeDelta WebMediaPlayerImpl::GetPipelineMediaDuration() const {
diff --git a/chromium/media/blink/webmediaplayer_impl.h b/chromium/media/blink/webmediaplayer_impl.h
index 7eb775c291c..3c1069fd557 100644
--- a/chromium/media/blink/webmediaplayer_impl.h
+++ b/chromium/media/blink/webmediaplayer_impl.h
@@ -17,15 +17,12 @@
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/threading/thread.h"
#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
-#include "cc/layers/surface_layer.h"
-#include "components/viz/common/gpu/raster_context_provider.h"
#include "media/base/cdm_config.h"
#include "media/base/encryption_scheme.h"
#include "media/base/media_observer.h"
@@ -39,17 +36,14 @@
#include "media/blink/learning_experiment_helper.h"
#include "media/blink/media_blink_export.h"
#include "media/blink/multibuffer_data_source.h"
-#include "media/blink/power_status_helper.h"
#include "media/blink/smoothness_helper.h"
#include "media/blink/video_frame_compositor.h"
#include "media/blink/webmediaplayer_params.h"
-#include "media/filters/pipeline_controller.h"
-#include "media/learning/common/media_learning_tasks.h"
#include "media/mojo/mojom/playback_events_recorder.mojom.h"
#include "media/renderers/paint_canvas_video_renderer.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/media_session/public/cpp/media_position.h"
-#include "third_party/blink/public/common/media/display_type.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/platform/media/webmediaplayer_delegate.h"
#include "third_party/blink/public/platform/web_audio_source_provider.h"
#include "third_party/blink/public/platform/web_content_decryption_module_result.h"
@@ -75,12 +69,26 @@ namespace cc {
class VideoLayer;
}
+namespace gfx {
+class Size;
+}
+
+namespace learning {
+class LearningTaskController;
+}
+
+namespace viz {
+class RasterContextProvider;
+}
+
namespace media {
class CdmContextRef;
class ChunkDemuxer;
class VideoDecodeStatsReporter;
class MediaLog;
class MemoryDumpProviderProxy;
+class PipelineController;
+class PowerStatusHelper;
class UrlIndex;
class VideoFrameCompositor;
@@ -256,7 +264,7 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
void OnBecameVisible() override;
bool IsOpaque() const override;
int GetDelegateId() override;
- base::Optional<viz::SurfaceId> GetSurfaceId() override;
+ absl::optional<viz::SurfaceId> GetSurfaceId() override;
GURL GetSrcAfterRedirects() override;
void RequestVideoFrameCallback() override;
std::unique_ptr<blink::WebMediaPlayer::VideoFramePresentationMetadata>
@@ -327,7 +335,7 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
void OnVideoConfigChange(const VideoDecoderConfig& config) override;
void OnVideoNaturalSizeChange(const gfx::Size& size) override;
void OnVideoOpacityChange(bool opaque) override;
- void OnVideoFrameRateChange(base::Optional<int> fps) override;
+ void OnVideoFrameRateChange(absl::optional<int> fps) override;
void OnVideoAverageKeyframeDistanceUpdate() override;
void OnAudioDecoderChange(const AudioDecoderInfo& info) override;
void OnVideoDecoderChange(const VideoDecoderInfo& info) override;
@@ -364,10 +372,10 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
ProvideOverlayInfoCB provide_overlay_info_cb);
// Creates a Renderer via the |renderer_factory_selector_|. If the
- // |factory_type| is base::nullopt, create the base Renderer. Otherwise, set
- // the base type to be |factory_type| and create a Renderer of that type.
+ // |renderer_type| is absl::nullopt, create the base Renderer. Otherwise, set
+ // the base type to be |renderer_type| and create a Renderer of that type.
std::unique_ptr<Renderer> CreateRenderer(
- base::Optional<RendererFactoryType> factory_type);
+ absl::optional<RendererType> renderer_type);
// Finishes starting the pipeline due to a call to load().
void StartPipeline();
@@ -708,11 +716,12 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
// WebMediaPlayer may also receive directives (play, pause) from the delegate
// via the WebMediaPlayerDelegate::Observer interface after registration.
//
- // NOTE: HTMLMediaElement is a Blink::PausableObject, and will receive a
- // call to contextDestroyed() when Blink::Document::shutdown() is called.
- // Document::shutdown() is called before the frame detaches (and before the
- // frame is destroyed). RenderFrameImpl owns |delegate_| and is guaranteed
- // to outlive |this|; thus it is safe to store |delegate_| as a raw pointer.
+ // NOTE: HTMLMediaElement is a blink::ExecutionContextLifecycleObserver, and
+ // will receive a call to contextDestroyed() when blink::Document::shutdown()
+ // is called. Document::shutdown() is called before the frame detaches (and
+ // before the frame is destroyed). RenderFrameImpl owns |delegate_| and is
+ // guaranteed to outlive |this|; thus it is safe to store |delegate_| as a raw
+ // pointer.
blink::WebMediaPlayerDelegate* delegate_;
int delegate_id_ = 0;
@@ -783,7 +792,7 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
// Captured once the cdm is provided to SetCdmInternal(). Used in creation of
// |video_decode_stats_reporter_|.
- base::Optional<CdmConfig> cdm_config_;
+ absl::optional<CdmConfig> cdm_config_;
// String identifying the KeySystem described by |cdm_config_|. Empty until a
// CDM has been attached. Used in creation |video_decode_stats_reporter_|.
@@ -917,10 +926,10 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
bool disable_pipeline_auto_suspend_ = false;
// Pipeline statistics overridden by tests.
- base::Optional<PipelineStatistics> pipeline_statistics_for_test_;
+ absl::optional<PipelineStatistics> pipeline_statistics_for_test_;
// Pipeline media duration overridden by tests.
- base::Optional<base::TimeDelta> pipeline_media_duration_for_test_;
+ absl::optional<base::TimeDelta> pipeline_media_duration_for_test_;
// Whether the video requires a user gesture to resume after it was paused in
// the background. Affects the value of ShouldPausePlaybackWhenHidden().
@@ -974,7 +983,7 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
mojo::Remote<mojom::MediaMetricsProvider> media_metrics_provider_;
mojo::Remote<mojom::PlaybackEventsRecorder> playback_events_recorder_;
- base::Optional<ReadyState> stale_state_override_for_testing_;
+ absl::optional<ReadyState> stale_state_override_for_testing_;
// True if we attempt to start the media pipeline in a suspended state for
// preload=metadata. Cleared upon pipeline startup.
@@ -1006,7 +1015,7 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
base::CancelableOnceClosure have_enough_after_lazy_load_cb_;
// State for simplified watch time reporting.
- RendererFactoryType reported_renderer_type_ = RendererFactoryType::kDefault;
+ RendererType reported_renderer_type_ = RendererType::kDefault;
SimpleWatchTimer simple_watch_timer_;
LearningExperimentHelper will_play_helper_;
@@ -1018,7 +1027,7 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
// Created while playing, deleted otherwise.
std::unique_ptr<SmoothnessHelper> smoothness_helper_;
- base::Optional<int> last_reported_fps_;
+ absl::optional<int> last_reported_fps_;
base::WeakPtr<WebMediaPlayerImpl> weak_this_;
base::WeakPtrFactory<WebMediaPlayerImpl> weak_factory_{this};
diff --git a/chromium/media/blink/webmediaplayer_impl_unittest.cc b/chromium/media/blink/webmediaplayer_impl_unittest.cc
index d9280ccdfb5..9cb9f9d0c22 100644
--- a/chromium/media/blink/webmediaplayer_impl_unittest.cc
+++ b/chromium/media/blink/webmediaplayer_impl_unittest.cc
@@ -15,6 +15,7 @@
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
#include "base/test/bind.h"
@@ -44,6 +45,7 @@
#include "media/blink/video_decode_stats_reporter.h"
#include "media/blink/webcontentdecryptionmodule_impl.h"
#include "media/blink/webmediaplayer_params.h"
+#include "media/filters/pipeline_controller.h"
#include "media/mojo/services/media_metrics_provider.h"
#include "media/mojo/services/video_decode_stats_recorder.h"
#include "media/mojo/services/watch_time_recorder.h"
@@ -318,6 +320,7 @@ class WebMediaPlayerImplTest
/*is_hidden=*/false,
/*is_inside_portal=*/false,
/*compositing_enabled=*/false,
+ /*widgets_never_composited=*/false,
/*opener=*/nullptr,
mojo::NullAssociatedReceiver(),
*agent_group_scheduler,
@@ -387,14 +390,14 @@ class WebMediaPlayerImplTest
decoder_factory_ = std::make_unique<media::DefaultDecoderFactory>(nullptr);
#if defined(OS_ANDROID)
factory_selector->AddBaseFactory(
- RendererFactoryType::kDefault,
+ RendererType::kDefault,
std::make_unique<DefaultRendererFactory>(
media_log.get(), decoder_factory_.get(),
DefaultRendererFactory::GetGpuFactoriesCB()));
factory_selector->StartRequestRemotePlayStateCB(base::DoNothing());
#else
factory_selector->AddBaseFactory(
- RendererFactoryType::kDefault,
+ RendererType::kDefault,
std::make_unique<DefaultRendererFactory>(
media_log.get(), decoder_factory_.get(),
DefaultRendererFactory::GetGpuFactoriesCB(), nullptr));
@@ -497,6 +500,7 @@ class WebMediaPlayerImplTest
void SetFullscreen(bool is_fullscreen) {
wmpi_->overlay_enabled_ = is_fullscreen;
+ wmpi_->overlay_info_.is_fullscreen = is_fullscreen;
}
void SetMetadata(bool has_audio, bool has_video) {
@@ -617,6 +621,7 @@ class WebMediaPlayerImplTest
void Pause() { wmpi_->Pause(); }
void ScheduleIdlePauseTimer() { wmpi_->ScheduleIdlePauseTimer(); }
+ void FireIdlePauseTimer() { wmpi_->background_pause_timer_.FireNow(); }
bool IsIdlePauseTimerRunning() {
return wmpi_->background_pause_timer_.IsRunning();
@@ -787,7 +792,7 @@ class WebMediaPlayerImplTest
void CreateCdm() {
// Must use a supported key system on a secure context.
- auto key_system = base::ASCIIToUTF16("org.w3.clearkey");
+ std::u16string key_system = u"org.w3.clearkey";
auto test_origin = blink::WebSecurityOrigin::CreateFromString(
blink::WebString::FromUTF8("https://test.origin"));
@@ -1753,7 +1758,7 @@ TEST_F(WebMediaPlayerImplTest, FallbackToMediaFoundationRenderer) {
return mock_renderer;
})));
- renderer_factory_selector_->AddFactory(RendererFactoryType::kMediaFoundation,
+ renderer_factory_selector_->AddFactory(RendererType::kMediaFoundation,
std::move(mock_renderer_factory));
// Create and set CDM. The CDM doesn't support a Decryptor and requires Media
@@ -1935,6 +1940,10 @@ TEST_F(WebMediaPlayerImplTest, BackgroundIdlePauseTimerDependsOnAudio) {
SetMetadata(true, true);
ScheduleIdlePauseTimer();
EXPECT_TRUE(IsIdlePauseTimerRunning());
+
+ EXPECT_CALL(client_, PausePlayback());
+ FireIdlePauseTimer();
+ base::RunLoop().RunUntilIdle();
}
// Verifies that an infinite duration doesn't muck up GetCurrentTimeInternal.
diff --git a/chromium/media/blink/webmediaplayer_params.h b/chromium/media/blink/webmediaplayer_params.h
index 70db6159b12..d7a2e42375f 100644
--- a/chromium/media/blink/webmediaplayer_params.h
+++ b/chromium/media/blink/webmediaplayer_params.h
@@ -12,7 +12,6 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
#include "cc/layers/surface_layer.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "media/base/media_log.h"
diff --git a/chromium/media/blink/websourcebuffer_impl.cc b/chromium/media/blink/websourcebuffer_impl.cc
index 1ea1357f6b5..ff928eb5fc5 100644
--- a/chromium/media/blink/websourcebuffer_impl.cc
+++ b/chromium/media/blink/websourcebuffer_impl.cc
@@ -16,6 +16,7 @@
#include "media/base/media_tracks.h"
#include "media/base/timestamp_constants.h"
#include "media/filters/chunk_demuxer.h"
+#include "media/filters/source_buffer_parse_warnings.h"
#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/public/platform/web_source_buffer_client.h"
@@ -49,14 +50,11 @@ static base::TimeDelta DoubleToTimeDelta(double time) {
if (time == std::numeric_limits<double>::infinity())
return kInfiniteDuration;
- // Don't use base::TimeDelta::Max() here, as we want the largest finite time
- // delta.
- base::TimeDelta max_time = base::TimeDelta::FromInternalValue(
- std::numeric_limits<int64_t>::max() - 1);
- double max_time_in_seconds = max_time.InSecondsF();
+ constexpr double max_time_in_seconds =
+ base::TimeDelta::FiniteMax().InSecondsF();
if (time >= max_time_in_seconds)
- return max_time;
+ return base::TimeDelta::FiniteMax();
return base::TimeDelta::FromMicroseconds(
time * base::Time::kMicrosecondsPerSecond);
diff --git a/chromium/media/blink/websourcebuffer_impl.h b/chromium/media/blink/websourcebuffer_impl.h
index 0d79492d45b..284c792d130 100644
--- a/chromium/media/blink/websourcebuffer_impl.h
+++ b/chromium/media/blink/websourcebuffer_impl.h
@@ -13,12 +13,12 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/time/time.h"
-#include "media/filters/source_buffer_parse_warnings.h"
#include "third_party/blink/public/platform/web_source_buffer.h"
namespace media {
class ChunkDemuxer;
class MediaTracks;
+enum class SourceBufferParseWarning;
class WebSourceBufferImpl : public blink::WebSourceBuffer {
public:
diff --git a/chromium/media/capabilities/bucket_utility.h b/chromium/media/capabilities/bucket_utility.h
index 4bf05dbde7c..9d89b3d9da3 100644
--- a/chromium/media/capabilities/bucket_utility.h
+++ b/chromium/media/capabilities/bucket_utility.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_CAPABILITIES_BUCKET_UTILITY
-#define MEDIA_CAPABILITIES_BUCKET_UTILITY
+#ifndef MEDIA_CAPABILITIES_BUCKET_UTILITY_H_
+#define MEDIA_CAPABILITIES_BUCKET_UTILITY_H_
#include "media/base/media_export.h"
#include "ui/gfx/geometry/size.h"
@@ -25,4 +25,4 @@ MEDIA_EXPORT int GetFpsBucket(double raw_fps);
} // namespace media
-#endif // MEDIA_CAPABILITIES_BUCKET_UTILITY \ No newline at end of file
+#endif // MEDIA_CAPABILITIES_BUCKET_UTILITY_H_
diff --git a/chromium/media/capabilities/in_memory_video_decode_stats_db_impl.cc b/chromium/media/capabilities/in_memory_video_decode_stats_db_impl.cc
index c6901cd122d..dcee0b3a6b2 100644
--- a/chromium/media/capabilities/in_memory_video_decode_stats_db_impl.cc
+++ b/chromium/media/capabilities/in_memory_video_decode_stats_db_impl.cc
@@ -13,7 +13,6 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequence_checker.h"
-#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "media/base/bind_to_current_loop.h"
#include "media/capabilities/video_decode_stats_db_provider.h"
diff --git a/chromium/media/capabilities/in_memory_video_decode_stats_db_impl.h b/chromium/media/capabilities/in_memory_video_decode_stats_db_impl.h
index c896534b987..7e3190878af 100644
--- a/chromium/media/capabilities/in_memory_video_decode_stats_db_impl.h
+++ b/chromium/media/capabilities/in_memory_video_decode_stats_db_impl.h
@@ -8,7 +8,6 @@
#include <map>
#include <memory>
-#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "components/leveldb_proto/public/proto_database.h"
#include "media/base/media_export.h"
diff --git a/chromium/media/capture/BUILD.gn b/chromium/media/capture/BUILD.gn
index bd8a26a1dcc..e96ba09d212 100644
--- a/chromium/media/capture/BUILD.gn
+++ b/chromium/media/capture/BUILD.gn
@@ -256,10 +256,7 @@ component("capture_lib") {
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
}
- # This includes the case of ChromeOS
- # TODO: As we move to separately version Chrome from ChromeOS, we may need to split
- # these sources into linux, chromeos, and common.
- if (is_linux || is_chromeos) {
+ if (is_linux || is_chromeos_lacros) {
sources += [
"video/linux/scoped_v4l2_device_fd.cc",
"video/linux/scoped_v4l2_device_fd.h",
@@ -327,15 +324,12 @@ component("capture_lib") {
"video/chromeos/video_capture_jpeg_decoder.h",
"video/chromeos/video_capture_jpeg_decoder_impl.cc",
"video/chromeos/video_capture_jpeg_decoder_impl.h",
- "video/linux/camera_config_chromeos.cc",
- "video/linux/camera_config_chromeos.h",
- "video/linux/video_capture_device_chromeos.cc",
- "video/linux/video_capture_device_chromeos.h",
]
public_deps += [ "//media/capture/video/chromeos/public" ]
deps += [
"//ash/constants",
"//build/config/linux/libdrm",
+ "//chromeos/components/sensors:sensors",
"//chromeos/dbus/power",
"//components/chromeos_camera:mojo_mjpeg_decode_accelerator",
"//components/chromeos_camera/common",
@@ -391,7 +385,7 @@ source_set("test_support") {
"//ui/gfx:test_support",
]
- if (is_linux || is_chromeos) {
+ if (is_linux || is_chromeos_lacros) {
sources += [
"video/linux/fake_device_provider.cc",
"video/linux/fake_device_provider.h",
@@ -453,17 +447,13 @@ test("capture_unittests") {
"//ui/gfx:test_support",
]
- if (is_linux || is_chromeos) {
+ if (is_linux || is_chromeos_lacros) {
sources += [
"video/linux/v4l2_capture_delegate_unittest.cc",
"video/linux/video_capture_device_factory_linux_unittest.cc",
]
}
- if (is_chromeos_ash) {
- sources += [ "video/linux/camera_config_chromeos_unittest.cc" ]
- }
-
if (is_android) {
deps += [
"//media/capture/video/android",
diff --git a/chromium/media/capture/content/DIR_METADATA b/chromium/media/capture/content/DIR_METADATA
index c46eabd56bc..f689e004f05 100644
--- a/chromium/media/capture/content/DIR_METADATA
+++ b/chromium/media/capture/content/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Internals>Media>SurfaceCapture"
diff --git a/chromium/media/capture/content/android/screen_capture_machine_android.h b/chromium/media/capture/content/android/screen_capture_machine_android.h
index 4b118341f62..c1246e5a8f7 100644
--- a/chromium/media/capture/content/android/screen_capture_machine_android.h
+++ b/chromium/media/capture/content/android/screen_capture_machine_android.h
@@ -6,7 +6,6 @@
#define MEDIA_CAPTURE_CONTENT_ANDROID_SCREEN_CAPTURE_MACHINE_ANDROID_H_
#include <jni.h>
-#include <memory>
#include "base/android/scoped_java_ref.h"
#include "base/memory/scoped_refptr.h"
diff --git a/chromium/media/capture/content/video_capture_oracle_unittest.cc b/chromium/media/capture/content/video_capture_oracle_unittest.cc
index 8f0c1d123da..aea1256f456 100644
--- a/chromium/media/capture/content/video_capture_oracle_unittest.cc
+++ b/chromium/media/capture/content/video_capture_oracle_unittest.cc
@@ -4,8 +4,8 @@
#include "media/capture/content/video_capture_oracle.h"
-#include "base/strings/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -880,7 +880,7 @@ TEST(VideoCaptureOracleTest, RespectsMaxFrameRateFeedback) {
int frame_number;
// As if previous frame was captured at 30 fps.
- base::Optional<base::TimeTicks> last_capture_time;
+ absl::optional<base::TimeTicks> last_capture_time;
for (int i = 0; i < 100; ++i) {
t += vsync_interval;
if (oracle.ObserveEventAndDecideCapture(
@@ -904,7 +904,7 @@ TEST(VideoCaptureOracleTest, RespectsMaxFrameRateFeedback) {
frame_number, media::VideoCaptureFeedback(kNoResourceUtilization, k5Fps));
// Don't measure frame-rate across different target frame-rates.
- last_capture_time = base::nullopt;
+ last_capture_time = absl::nullopt;
// Continue capturing frames, observe that frame-rate limit is respected.
for (int i = 0; i < 100; ++i) {
t += vsync_interval;
@@ -930,7 +930,7 @@ TEST(VideoCaptureOracleTest, RespectsMaxFrameRateFeedback) {
media::VideoCaptureFeedback(kNoResourceUtilization, kNoFpsLimit));
// Don't measure frame-rate across different target frame-rates.
- last_capture_time = base::nullopt;
+ last_capture_time = absl::nullopt;
// Continue capturing frames, observe that original min capture period is
// respected.
for (int i = 0; i < 100; ++i) {
diff --git a/chromium/media/capture/mojom/video_capture_buffer.mojom b/chromium/media/capture/mojom/video_capture_buffer.mojom
index e8a70ee00a9..fa28c2eac09 100644
--- a/chromium/media/capture/mojom/video_capture_buffer.mojom
+++ b/chromium/media/capture/mojom/video_capture_buffer.mojom
@@ -19,6 +19,11 @@ struct VideoFrameInfo{
VideoCapturePixelFormat pixel_format;
gfx.mojom.Size coded_size;
gfx.mojom.Rect visible_rect;
+ // Some buffer types may be preemtively mapped in the capturer.
+ // In that case a shared memory region is passed to the consumer together
+ // with a GMB handle, and this flag here is passed to notify the consumer
+ // that the region has valid data.
+ bool is_premapped;
// This field is only optional to work around the issue of native enums
// not being usable for non-Chromium Mojo clients.
// TODO(chfremer): Make this non-optional once gfx.mojom.ColorSpace has been
diff --git a/chromium/media/capture/mojom/video_capture_types_mojom_traits.h b/chromium/media/capture/mojom/video_capture_types_mojom_traits.h
index d47081e700f..aaaad37daa2 100644
--- a/chromium/media/capture/mojom/video_capture_types_mojom_traits.h
+++ b/chromium/media/capture/mojom/video_capture_types_mojom_traits.h
@@ -5,13 +5,13 @@
#ifndef MEDIA_CAPTURE_MOJOM_VIDEO_CAPTURE_TYPES_MOJOM_TRAITS_H_
#define MEDIA_CAPTURE_MOJOM_VIDEO_CAPTURE_TYPES_MOJOM_TRAITS_H_
-#include "base/optional.h"
#include "media/base/video_facing.h"
#include "media/capture/mojom/video_capture_types.mojom-shared.h"
#include "media/capture/video/video_capture_device_descriptor.h"
#include "media/capture/video/video_capture_device_info.h"
#include "media/capture/video/video_capture_feedback.h"
#include "media/capture/video_capture_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace mojo {
diff --git a/chromium/media/capture/video/DIR_METADATA b/chromium/media/capture/video/DIR_METADATA
index dc21b380384..ca45fdeb142 100644
--- a/chromium/media/capture/video/DIR_METADATA
+++ b/chromium/media/capture/video/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Internals>Media>CameraCapture"
diff --git a/chromium/media/capture/video/android/video_capture_device_factory_android.cc b/chromium/media/capture/video/android/video_capture_device_factory_android.cc
index 157e2676c27..33e1b744ff1 100644
--- a/chromium/media/capture/video/android/video_capture_device_factory_android.cc
+++ b/chromium/media/capture/video/android/video_capture_device_factory_android.cc
@@ -10,7 +10,6 @@
#include "base/android/scoped_java_ref.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
#include "media/capture/video/android/capture_jni_headers/VideoCaptureFactory_jni.h"
#include "media/capture/video/android/video_capture_device_android.h"
diff --git a/chromium/media/capture/video/chromeos/DEPS b/chromium/media/capture/video/chromeos/DEPS
index db76c2a1b65..170ac6c6b6f 100644
--- a/chromium/media/capture/video/chromeos/DEPS
+++ b/chromium/media/capture/video/chromeos/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+ash/constants/ash_features.h",
+ "+chromeos/components/sensors",
"+chromeos/dbus",
"+components/chromeos_camera",
"+third_party/libsync",
diff --git a/chromium/media/capture/video/chromeos/camera_app_device_impl.cc b/chromium/media/capture/video/chromeos/camera_app_device_impl.cc
index cf23b2aa7cb..8d0595ed820 100644
--- a/chromium/media/capture/video/chromeos/camera_app_device_impl.cc
+++ b/chromium/media/capture/video/chromeos/camera_app_device_impl.cc
@@ -125,7 +125,7 @@ void CameraAppDeviceImpl::ConsumeReprocessOptions(
std::move(consumption_callback).Run(std::move(result_task_queue));
}
-base::Optional<gfx::Range> CameraAppDeviceImpl::GetFpsRange() {
+absl::optional<gfx::Range> CameraAppDeviceImpl::GetFpsRange() {
base::AutoLock lock(fps_ranges_lock_);
return specified_fps_range_;
@@ -247,8 +247,15 @@ void CameraAppDeviceImpl::SetCaptureIntent(
SetCaptureIntentCallback callback) {
DCHECK(mojo_task_runner_->BelongsToCurrentThread());
- base::AutoLock lock(capture_intent_lock_);
- capture_intent_ = capture_intent;
+ {
+ base::AutoLock lock(capture_intent_lock_);
+ capture_intent_ = capture_intent;
+ }
+ // Reset fps range for VCD to determine it if not explicitly set by app.
+ {
+ base::AutoLock lock(fps_ranges_lock_);
+ specified_fps_range_ = {};
+ }
std::move(callback).Run();
}
diff --git a/chromium/media/capture/video/chromeos/camera_app_device_impl.h b/chromium/media/capture/video/chromeos/camera_app_device_impl.h
index 9bb497ddd0b..42ca9fcd51c 100644
--- a/chromium/media/capture/video/chromeos/camera_app_device_impl.h
+++ b/chromium/media/capture/video/chromeos/camera_app_device_impl.h
@@ -11,6 +11,7 @@
#include <vector>
#include "base/containers/flat_set.h"
+#include "base/containers/queue.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
@@ -87,7 +88,7 @@ class CAPTURE_EXPORT CameraAppDeviceImpl : public cros::mojom::CameraAppDevice {
base::OnceCallback<void(ReprocessTaskQueue)> consumption_callback);
// Retrieves the fps range if it is specified by the app.
- base::Optional<gfx::Range> GetFpsRange();
+ absl::optional<gfx::Range> GetFpsRange();
// Retrieves the corresponding capture resolution which is specified by the
// app.
@@ -168,7 +169,7 @@ class CAPTURE_EXPORT CameraAppDeviceImpl : public cros::mojom::CameraAppDevice {
// It will be inserted and read from different threads.
base::Lock fps_ranges_lock_;
- base::Optional<gfx::Range> specified_fps_range_ GUARDED_BY(fps_ranges_lock_);
+ absl::optional<gfx::Range> specified_fps_range_ GUARDED_BY(fps_ranges_lock_);
// It will be inserted and read from different threads.
base::Lock still_capture_resolution_lock_;
diff --git a/chromium/media/capture/video/chromeos/camera_app_device_provider_impl.cc b/chromium/media/capture/video/chromeos/camera_app_device_provider_impl.cc
index 53defd23bee..66eb6cc1f39 100644
--- a/chromium/media/capture/video/chromeos/camera_app_device_provider_impl.cc
+++ b/chromium/media/capture/video/chromeos/camera_app_device_provider_impl.cc
@@ -39,7 +39,7 @@ void CameraAppDeviceProviderImpl::GetCameraAppDevice(
void CameraAppDeviceProviderImpl::GetCameraAppDeviceWithDeviceId(
GetCameraAppDeviceCallback callback,
- const base::Optional<std::string>& device_id) {
+ const absl::optional<std::string>& device_id) {
if (!device_id.has_value()) {
std::move(callback).Run(
cros::mojom::GetCameraAppDeviceStatus::ERROR_INVALID_ID,
@@ -68,7 +68,7 @@ void CameraAppDeviceProviderImpl::SetMultipleStreamsEnabled(
void CameraAppDeviceProviderImpl::SetMultipleStreamsEnabledWithDeviceId(
bool enabled,
SetMultipleStreamsEnabledCallback callback,
- const base::Optional<std::string>& device_id) {
+ const absl::optional<std::string>& device_id) {
if (!device_id.has_value()) {
std::move(callback).Run(false);
return;
diff --git a/chromium/media/capture/video/chromeos/camera_app_device_provider_impl.h b/chromium/media/capture/video/chromeos/camera_app_device_provider_impl.h
index 6bf036ef614..3fbb56257b6 100644
--- a/chromium/media/capture/video/chromeos/camera_app_device_provider_impl.h
+++ b/chromium/media/capture/video/chromeos/camera_app_device_provider_impl.h
@@ -17,7 +17,7 @@ class CAPTURE_EXPORT CameraAppDeviceProviderImpl
: public cros::mojom::CameraAppDeviceProvider {
public:
using WithRealIdCallback =
- base::OnceCallback<void(const base::Optional<std::string>&)>;
+ base::OnceCallback<void(const absl::optional<std::string>&)>;
using DeviceIdMappingCallback =
base::RepeatingCallback<void(const std::string&, WithRealIdCallback)>;
@@ -40,12 +40,12 @@ class CAPTURE_EXPORT CameraAppDeviceProviderImpl
private:
void GetCameraAppDeviceWithDeviceId(
GetCameraAppDeviceCallback callback,
- const base::Optional<std::string>& device_id);
+ const absl::optional<std::string>& device_id);
void SetMultipleStreamsEnabledWithDeviceId(
bool enable,
SetMultipleStreamsEnabledCallback callback,
- const base::Optional<std::string>& device_id);
+ const absl::optional<std::string>& device_id);
mojo::Remote<cros::mojom::CameraAppDeviceBridge> bridge_;
diff --git a/chromium/media/capture/video/chromeos/camera_buffer_factory.cc b/chromium/media/capture/video/chromeos/camera_buffer_factory.cc
index 345c9dcf27d..a4e3b5eb88f 100644
--- a/chromium/media/capture/video/chromeos/camera_buffer_factory.cc
+++ b/chromium/media/capture/video/chromeos/camera_buffer_factory.cc
@@ -4,7 +4,7 @@
#include "media/capture/video/chromeos/camera_buffer_factory.h"
-#include "base/stl_util.h"
+#include "base/containers/contains.h"
#include "media/capture/video/chromeos/video_capture_device_factory_chromeos.h"
namespace media {
@@ -24,7 +24,7 @@ CameraBufferFactory::CreateGpuMemoryBuffer(const gfx::Size& size,
return nullptr;
}
return buf_manager->CreateGpuMemoryBuffer(size, format, usage,
- gpu::kNullSurfaceHandle);
+ gpu::kNullSurfaceHandle, nullptr);
}
// There's no good way to resolve the HAL pixel format to the platform-specific
diff --git a/chromium/media/capture/video/chromeos/camera_device_context.h b/chromium/media/capture/video/chromeos/camera_device_context.h
index 1d40dcc5cd1..a85d7f58243 100644
--- a/chromium/media/capture/video/chromeos/camera_device_context.h
+++ b/chromium/media/capture/video/chromeos/camera_device_context.h
@@ -203,4 +203,4 @@ class CAPTURE_EXPORT CameraDeviceContext {
} // namespace media
-#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_DEVICE_CONTEXT_CHROMEOS_H_
+#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_DEVICE_CONTEXT_H_
diff --git a/chromium/media/capture/video/chromeos/camera_device_delegate.cc b/chromium/media/capture/video/chromeos/camera_device_delegate.cc
index b7d497c7a4d..490e828bab5 100644
--- a/chromium/media/capture/video/chromeos/camera_device_delegate.cc
+++ b/chromium/media/capture/video/chromeos/camera_device_delegate.cc
@@ -14,6 +14,7 @@
#include "ash/constants/ash_features.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/containers/contains.h"
#include "base/no_destructor.h"
#include "base/numerics/ranges.h"
#include "base/posix/safe_strerror.h"
@@ -307,8 +308,11 @@ void CameraDeviceDelegate::AllocateAndStart(
device_context_ = device_context;
device_context_->SetState(CameraDeviceContext::State::kStarting);
- if (camera_app_device_) {
- camera_app_device_->SetCameraDeviceContext(device_context_);
+ auto camera_app_device =
+ CameraAppDeviceBridgeImpl::GetInstance()->GetWeakCameraAppDevice(
+ device_descriptor_.device_id);
+ if (camera_app_device) {
+ camera_app_device->SetCameraDeviceContext(device_context_);
}
auto camera_info = camera_hal_delegate_->GetCameraInfoFromDeviceId(
@@ -320,6 +324,7 @@ void CameraDeviceDelegate::AllocateAndStart(
return;
}
+ device_api_version_ = camera_info->device_version;
SortCameraMetadata(&camera_info->static_camera_characteristics);
static_metadata_ = std::move(camera_info->static_camera_characteristics);
@@ -369,8 +374,11 @@ void CameraDeviceDelegate::StopAndDeAllocate(
// CameraDeviceContext::State::kStopping.
DCHECK_NE(device_context_->GetState(), CameraDeviceContext::State::kStopping);
- if (camera_app_device_) {
- camera_app_device_->SetCameraDeviceContext(nullptr);
+ auto camera_app_device =
+ CameraAppDeviceBridgeImpl::GetInstance()->GetWeakCameraAppDevice(
+ device_descriptor_.device_id);
+ if (camera_app_device) {
+ camera_app_device->SetCameraDeviceContext(nullptr);
}
device_close_callback_ = std::move(device_close_callback);
@@ -610,7 +618,7 @@ void CameraDeviceDelegate::ReconfigureStreams(
// ReconfigureStreams is used for video recording. It does not require
// photo.
request_manager_->StopPreview(base::BindOnce(
- &CameraDeviceDelegate::OnFlushed, GetWeakPtr(), false, base::nullopt));
+ &CameraDeviceDelegate::OnFlushed, GetWeakPtr(), false, absl::nullopt));
}
}
@@ -645,7 +653,7 @@ bool CameraDeviceDelegate::MaybeReconfigureForPhotoStream(
std::move(new_blob_resolution)));
} else {
request_manager_->StopPreview(base::BindOnce(
- &CameraDeviceDelegate::OnFlushed, GetWeakPtr(), true, base::nullopt));
+ &CameraDeviceDelegate::OnFlushed, GetWeakPtr(), true, absl::nullopt));
}
return true;
}
@@ -666,7 +674,7 @@ void CameraDeviceDelegate::TakePhotoImpl() {
// Trigger the reconfigure process if it not yet triggered.
if (on_reconfigured_callbacks_.empty()) {
request_manager_->StopPreview(base::BindOnce(
- &CameraDeviceDelegate::OnFlushed, GetWeakPtr(), true, base::nullopt));
+ &CameraDeviceDelegate::OnFlushed, GetWeakPtr(), true, absl::nullopt));
}
auto on_reconfigured_callback = base::BindOnce(
[](base::WeakPtr<Camera3AController> controller,
@@ -703,7 +711,7 @@ void CameraDeviceDelegate::OnMojoConnectionError() {
void CameraDeviceDelegate::OnFlushed(
bool require_photo,
- base::Optional<gfx::Size> new_blob_resolution,
+ absl::optional<gfx::Size> new_blob_resolution,
int32_t result) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
if (result) {
@@ -790,7 +798,8 @@ void CameraDeviceDelegate::Initialize() {
device_context_,
chrome_capture_params_[ClientType::kPreviewClient].buffer_type,
std::make_unique<CameraBufferFactory>(),
- base::BindRepeating(&RotateAndBlobify), ipc_task_runner_);
+ base::BindRepeating(&RotateAndBlobify), ipc_task_runner_,
+ device_api_version_);
camera_3a_controller_ = std::make_unique<Camera3AController>(
static_metadata_, request_manager_.get(), ipc_task_runner_);
device_ops_->Initialize(
@@ -837,12 +846,12 @@ void CameraDeviceDelegate::OnInitialized(int32_t result) {
return false;
}
}();
- ConfigureStreams(require_photo, base::nullopt);
+ ConfigureStreams(require_photo, absl::nullopt);
}
void CameraDeviceDelegate::ConfigureStreams(
bool require_photo,
- base::Optional<gfx::Size> new_blob_resolution) {
+ absl::optional<gfx::Size> new_blob_resolution) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
DCHECK_EQ(device_context_->GetState(),
CameraDeviceContext::State::kInitialized);
@@ -871,6 +880,9 @@ void CameraDeviceDelegate::ConfigureStreams(
stream->data_space = 0;
stream->rotation =
cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
+ if (device_api_version_ >= cros::mojom::CAMERA_DEVICE_API_VERSION_3_5) {
+ stream->physical_camera_id = "";
+ }
stream_config->streams.push_back(std::move(stream));
}
@@ -903,6 +915,9 @@ void CameraDeviceDelegate::ConfigureStreams(
still_capture_stream->data_space = 0;
still_capture_stream->rotation =
cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
+ if (device_api_version_ >= cros::mojom::CAMERA_DEVICE_API_VERSION_3_5) {
+ still_capture_stream->physical_camera_id = "";
+ }
stream_config->streams.push_back(std::move(still_capture_stream));
int32_t max_yuv_width = 0, max_yuv_height = 0;
@@ -919,6 +934,9 @@ void CameraDeviceDelegate::ConfigureStreams(
reprocessing_stream_input->data_space = 0;
reprocessing_stream_input->rotation =
cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
+ if (device_api_version_ >= cros::mojom::CAMERA_DEVICE_API_VERSION_3_5) {
+ reprocessing_stream_input->physical_camera_id = "";
+ }
auto reprocessing_stream_output = cros::mojom::Camera3Stream::New();
reprocessing_stream_output->id =
@@ -935,6 +953,9 @@ void CameraDeviceDelegate::ConfigureStreams(
reprocessing_stream_output->data_space = 0;
reprocessing_stream_output->rotation =
cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
+ if (device_api_version_ >= cros::mojom::CAMERA_DEVICE_API_VERSION_3_5) {
+ reprocessing_stream_output->physical_camera_id = "";
+ }
stream_config->streams.push_back(std::move(reprocessing_stream_input));
stream_config->streams.push_back(std::move(reprocessing_stream_output));
@@ -943,6 +964,9 @@ void CameraDeviceDelegate::ConfigureStreams(
stream_config->operation_mode = cros::mojom::Camera3StreamConfigurationMode::
CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE;
+ if (device_api_version_ >= cros::mojom::CAMERA_DEVICE_API_VERSION_3_5) {
+ stream_config->session_parameters = cros::mojom::CameraMetadata::New();
+ }
device_ops_->ConfigureStreams(
std::move(stream_config),
base::BindOnce(&CameraDeviceDelegate::OnConfiguredStreams, GetWeakPtr(),
@@ -1125,7 +1149,7 @@ void CameraDeviceDelegate::OnConstructedDefaultPreviewRequestSettings(
CameraAppDeviceBridgeImpl::GetInstance()->GetWeakCameraAppDevice(
device_descriptor_.device_id);
auto specified_fps_range =
- camera_app_device ? camera_app_device->GetFpsRange() : base::nullopt;
+ camera_app_device ? camera_app_device->GetFpsRange() : absl::nullopt;
if (specified_fps_range) {
SetFpsRangeInMetadata(&settings, specified_fps_range->GetMin(),
specified_fps_range->GetMax());
@@ -1152,16 +1176,15 @@ void CameraDeviceDelegate::OnConstructedDefaultPreviewRequestSettings(
SetFpsRangeInMetadata(&settings, target_min, target_max);
}
- request_manager_->StartPreview(std::move(settings));
-
- if (!take_photo_callbacks_.empty()) {
- TakePhotoImpl();
- }
-
while (!on_reconfigured_callbacks_.empty()) {
std::move(on_reconfigured_callbacks_.front()).Run();
on_reconfigured_callbacks_.pop();
}
+
+ request_manager_->StartPreview(std::move(settings));
+ if (!take_photo_callbacks_.empty()) {
+ TakePhotoImpl();
+ }
}
void CameraDeviceDelegate::OnConstructedDefaultStillCaptureRequestSettings(
@@ -1193,7 +1216,7 @@ void CameraDeviceDelegate::OnConstructedDefaultStillCaptureRequestSettings(
}
gfx::Size CameraDeviceDelegate::GetBlobResolution(
- base::Optional<gfx::Size> new_blob_resolution) {
+ absl::optional<gfx::Size> new_blob_resolution) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
std::vector<gfx::Size> blob_resolutions;
@@ -1304,7 +1327,7 @@ bool CameraDeviceDelegate::SetPointsOfInterest(
mojom::RangePtr CameraDeviceDelegate::GetControlRangeByVendorTagName(
const std::string& range_name,
- const base::Optional<int32_t>& current) {
+ const absl::optional<int32_t>& current) {
const VendorTagInfo* info =
camera_hal_delegate_->GetVendorTagInfoByName(range_name);
if (info == nullptr) {
@@ -1338,7 +1361,7 @@ void CameraDeviceDelegate::OnResultMetadataAvailable(
auto get_vendor_int =
[&](const std::string& name,
const cros::mojom::CameraMetadataPtr& result_metadata,
- base::Optional<int32_t>* returned_value) {
+ absl::optional<int32_t>* returned_value) {
returned_value->reset();
const VendorTagInfo* info =
camera_hal_delegate_->GetVendorTagInfoByName(name);
diff --git a/chromium/media/capture/video/chromeos/camera_device_delegate.h b/chromium/media/capture/video/chromeos/camera_device_delegate.h
index 3f821f96b54..3f8c72cfb5e 100644
--- a/chromium/media/capture/video/chromeos/camera_device_delegate.h
+++ b/chromium/media/capture/video/chromeos/camera_device_delegate.h
@@ -11,7 +11,6 @@
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "media/capture/video/chromeos/camera_device_context.h"
#include "media/capture/video/chromeos/capture_metadata_dispatcher.h"
@@ -20,13 +19,13 @@
#include "media/capture/video/video_capture_device.h"
#include "media/capture/video_capture_types.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/range/range.h"
namespace media {
class Camera3AController;
-class CameraAppDeviceImpl;
class CameraHalDelegate;
class RequestManager;
@@ -56,21 +55,21 @@ struct ResultMetadata {
ResultMetadata();
~ResultMetadata();
- base::Optional<uint8_t> ae_mode;
- base::Optional<int32_t> ae_compensation;
- base::Optional<uint8_t> af_mode;
- base::Optional<uint8_t> awb_mode;
- base::Optional<int32_t> brightness;
- base::Optional<int32_t> contrast;
- base::Optional<int64_t> exposure_time;
- base::Optional<float> focus_distance;
- base::Optional<int32_t> pan;
- base::Optional<int32_t> saturation;
- base::Optional<int32_t> sensitivity;
- base::Optional<int32_t> sharpness;
- base::Optional<int32_t> tilt;
- base::Optional<int32_t> zoom;
- base::Optional<gfx::Rect> scaler_crop_region;
+ absl::optional<uint8_t> ae_mode;
+ absl::optional<int32_t> ae_compensation;
+ absl::optional<uint8_t> af_mode;
+ absl::optional<uint8_t> awb_mode;
+ absl::optional<int32_t> brightness;
+ absl::optional<int32_t> contrast;
+ absl::optional<int64_t> exposure_time;
+ absl::optional<float> focus_distance;
+ absl::optional<int32_t> pan;
+ absl::optional<int32_t> saturation;
+ absl::optional<int32_t> sensitivity;
+ absl::optional<int32_t> sharpness;
+ absl::optional<int32_t> tilt;
+ absl::optional<int32_t> zoom;
+ absl::optional<gfx::Rect> scaler_crop_region;
};
// Returns true if the given stream type is an input stream.
@@ -160,7 +159,7 @@ class CAPTURE_EXPORT CameraDeviceDelegate final
// Reconfigure streams for picture taking and recording.
void OnFlushed(bool require_photo,
- base::Optional<gfx::Size> new_blob_resolution,
+ absl::optional<gfx::Size> new_blob_resolution,
int32_t result);
// Callback method for the Close Mojo IPC call. This method resets the Mojo
@@ -186,7 +185,7 @@ class CAPTURE_EXPORT CameraDeviceDelegate final
// |client_| the capture has started by calling OnStarted, and proceeds to
// ConstructDefaultRequestSettings.
void ConfigureStreams(bool require_photo,
- base::Optional<gfx::Size> new_blob_resolution);
+ absl::optional<gfx::Size> new_blob_resolution);
void OnConfiguredStreams(
gfx::Size blob_resolution,
int32_t result,
@@ -214,7 +213,7 @@ class CAPTURE_EXPORT CameraDeviceDelegate final
void OnConstructedDefaultStillCaptureRequestSettings(
cros::mojom::CameraMetadataPtr settings);
- gfx::Size GetBlobResolution(base::Optional<gfx::Size> new_blob_resolution);
+ gfx::Size GetBlobResolution(absl::optional<gfx::Size> new_blob_resolution);
// StreamCaptureInterface implementations. These methods are called by
// |stream_buffer_manager_| on |ipc_task_runner_|.
@@ -229,7 +228,7 @@ class CAPTURE_EXPORT CameraDeviceDelegate final
// metadata by |range_name| and current value of |current|.
mojom::RangePtr GetControlRangeByVendorTagName(
const std::string& range_name,
- const base::Optional<int32_t>& current);
+ const absl::optional<int32_t>& current);
// CaptureMetadataDispatcher::ResultMetadataObserver implementation.
void OnResultMetadataAvailable(
@@ -270,7 +269,7 @@ class CAPTURE_EXPORT CameraDeviceDelegate final
std::queue<base::OnceClosure> on_reconfigured_callbacks_;
- base::WeakPtr<CameraAppDeviceImpl> camera_app_device_;
+ uint32_t device_api_version_;
// States of SetPhotoOptions
bool is_set_awb_mode_;
diff --git a/chromium/media/capture/video/chromeos/camera_device_delegate_unittest.cc b/chromium/media/capture/video/chromeos/camera_device_delegate_unittest.cc
index 1c1bb4ad006..9d47ddc1b62 100644
--- a/chromium/media/capture/video/chromeos/camera_device_delegate_unittest.cc
+++ b/chromium/media/capture/video/chromeos/camera_device_delegate_unittest.cc
@@ -396,7 +396,7 @@ class CameraDeviceDelegateTest : public ::testing::Test {
CreateGpuMemoryBuffer(
_, gfx::BufferFormat::YUV_420_BIPLANAR,
gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE,
- gpu::kNullSurfaceHandle))
+ gpu::kNullSurfaceHandle, nullptr))
.Times(1)
.WillOnce(Invoke(&unittest_internal::MockGpuMemoryBufferManager::
CreateFakeGpuMemoryBuffer));
@@ -404,7 +404,7 @@ class CameraDeviceDelegateTest : public ::testing::Test {
mock_gpu_memory_buffer_manager_,
CreateGpuMemoryBuffer(_, gfx::BufferFormat::R_8,
gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE,
- gpu::kNullSurfaceHandle))
+ gpu::kNullSurfaceHandle, nullptr))
.Times(AtMost(1))
.WillOnce(Invoke(&unittest_internal::MockGpuMemoryBufferManager::
CreateFakeGpuMemoryBuffer));
@@ -413,7 +413,7 @@ class CameraDeviceDelegateTest : public ::testing::Test {
gfx::Size(kDefaultWidth, kDefaultHeight),
gfx::BufferFormat::YUV_420_BIPLANAR,
gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE,
- gpu::kNullSurfaceHandle))
+ gpu::kNullSurfaceHandle, nullptr))
.Times(1)
.WillOnce(Invoke(&unittest_internal::MockGpuMemoryBufferManager::
CreateFakeGpuMemoryBuffer));
@@ -421,7 +421,7 @@ class CameraDeviceDelegateTest : public ::testing::Test {
CreateGpuMemoryBuffer(
gfx::Size(kJpegMaxBufferSize, 1), gfx::BufferFormat::R_8,
gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE,
- gpu::kNullSurfaceHandle))
+ gpu::kNullSurfaceHandle, nullptr))
.Times(AtMost(1))
.WillOnce(Invoke(&unittest_internal::MockGpuMemoryBufferManager::
CreateFakeGpuMemoryBuffer));
@@ -490,7 +490,7 @@ class CameraDeviceDelegateTest : public ::testing::Test {
}
void DoLoop() {
- run_loop_.reset(new base::RunLoop());
+ run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
diff --git a/chromium/media/capture/video/chromeos/camera_hal_delegate.cc b/chromium/media/capture/video/chromeos/camera_hal_delegate.cc
index fcc92b23aed..9b83d4c0f9a 100644
--- a/chromium/media/capture/video/chromeos/camera_hal_delegate.cc
+++ b/chromium/media/capture/video/chromeos/camera_hal_delegate.cc
@@ -264,7 +264,7 @@ void CameraHalDelegate::GetSupportedFormats(
continue;
}
- CAMERA_LOG(EVENT) << "Supported format: " << width << "x" << height
+ CAMERA_LOG(DEBUG) << "Supported format: " << width << "x" << height
<< " fps=" << fps
<< " format=" << cr_format.video_format;
supported_formats->emplace_back(gfx::Size(width, height), fps,
diff --git a/chromium/media/capture/video/chromeos/camera_hal_delegate_unittest.cc b/chromium/media/capture/video/chromeos/camera_hal_delegate_unittest.cc
index 3e1bf9b0d6e..a3cd9a46a27 100644
--- a/chromium/media/capture/video/chromeos/camera_hal_delegate_unittest.cc
+++ b/chromium/media/capture/video/chromeos/camera_hal_delegate_unittest.cc
@@ -56,7 +56,7 @@ class CameraHalDelegateTest : public ::testing::Test {
}
void Wait() {
- run_loop_.reset(new base::RunLoop());
+ run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
@@ -232,7 +232,7 @@ TEST_F(CameraHalDelegateTest, GetBuiltinCameraInfo) {
CreateGpuMemoryBuffer(
_, gfx::BufferFormat::YUV_420_BIPLANAR,
gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE,
- gpu::kNullSurfaceHandle))
+ gpu::kNullSurfaceHandle, nullptr))
.Times(1)
.WillOnce(Invoke(&unittest_internal::MockGpuMemoryBufferManager::
CreateFakeGpuMemoryBuffer));
diff --git a/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc b/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc
index 18e810897d3..bdba7369c6f 100644
--- a/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc
+++ b/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"
+
#include <fcntl.h>
#include <grp.h>
#include <poll.h>
@@ -22,10 +23,14 @@
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/threading/sequenced_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
+#include "chromeos/components/sensors/sensor_util.h"
#include "components/device_event_log/device_event_log.h"
#include "media/base/bind_to_current_loop.h"
#include "media/capture/video/chromeos/mojom/camera_common.mojom.h"
+#include "media/capture/video/chromeos/mojom/cros_camera_client.mojom.h"
+#include "media/capture/video/chromeos/video_capture_features_chromeos.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/platform/platform_channel.h"
@@ -37,8 +42,10 @@ namespace media {
namespace {
const base::FilePath::CharType kArcCamera3SocketPath[] =
- "/var/run/camera/camera3.sock";
+ "/run/camera/camera3.sock";
const char kArcCameraGroup[] = "arc-camera";
+const base::FilePath::CharType kForceEnableAePath[] =
+ "/run/camera/force_enable_ae";
std::string GenerateRandomToken() {
char random_bytes[16];
@@ -164,6 +171,18 @@ bool CameraHalDispatcherImpl::Start(
TRACE_EVENT0("camera", "CameraHalDispatcherImpl");
base::trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this);
+ base::FilePath file_path(kForceEnableAePath);
+ if (base::FeatureList::IsEnabled(media::features::kForceEnableFaceAe)) {
+ if (!base::PathExists(file_path)) {
+ base::File file(file_path, base::File::FLAG_CREATE_ALWAYS);
+ file.Close();
+ }
+ } else {
+ if (base::PathExists(file_path)) {
+ base::DeleteFile(file_path);
+ }
+ }
+
jda_factory_ = std::move(jda_factory);
jea_factory_ = std::move(jea_factory);
base::WaitableEvent started(base::WaitableEvent::ResetPolicy::MANUAL,
@@ -179,6 +198,11 @@ bool CameraHalDispatcherImpl::Start(
LOG(ERROR) << "Failed to generate token for test client";
return false;
}
+ if (!token_manager_.GenerateServerSensorClientToken()) {
+ LOG(ERROR) << "Failed to generate authentication token for server as a "
+ "sensor client";
+ }
+
blocking_io_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&CameraHalDispatcherImpl::CreateSocket,
@@ -250,6 +274,7 @@ void CameraHalDispatcherImpl::UnregisterPluginVmToken(
CameraHalDispatcherImpl::CameraHalDispatcherImpl()
: proxy_thread_("CameraProxyThread"),
blocking_io_thread_("CameraBlockingIOThread"),
+ main_task_runner_(base::SequencedTaskRunnerHandle::Get()),
camera_hal_server_callbacks_(this),
active_client_observers_(
new base::ObserverListThreadSafe<CameraActiveClientObserver>()),
@@ -344,6 +369,20 @@ void CameraHalDispatcherImpl::GetJpegEncodeAccelerator(
jea_factory_.Run(std::move(jea_receiver));
}
+void CameraHalDispatcherImpl::RegisterSensorClientWithToken(
+ mojo::PendingRemote<chromeos::sensors::mojom::SensorHalClient> client,
+ const base::UnguessableToken& auth_token,
+ RegisterSensorClientWithTokenCallback callback) {
+ DCHECK(proxy_task_runner_->BelongsToCurrentThread());
+
+ main_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &CameraHalDispatcherImpl::RegisterSensorClientWithTokenOnUIThread,
+ weak_factory_.GetWeakPtr(), std::move(client), auth_token,
+ BindToCurrentLoop(std::move(callback))));
+}
+
void CameraHalDispatcherImpl::CameraDeviceActivityChange(
int32_t camera_id,
bool opened,
@@ -395,6 +434,8 @@ void CameraHalDispatcherImpl::CameraPrivacySwitchStateChange(
FROM_HERE,
&CameraPrivacySwitchObserver::OnCameraPrivacySwitchStatusChanged,
current_privacy_switch_state_);
+ CAMERA_LOG(EVENT) << "Camera privacy switch state changed: "
+ << current_privacy_switch_state_;
}
base::UnguessableToken CameraHalDispatcherImpl::GetTokenForTrustedClient(
@@ -640,6 +681,26 @@ void CameraHalDispatcherImpl::OnCameraHalClientConnectionError(
}
}
+void CameraHalDispatcherImpl::RegisterSensorClientWithTokenOnUIThread(
+ mojo::PendingRemote<chromeos::sensors::mojom::SensorHalClient> client,
+ const base::UnguessableToken& auth_token,
+ RegisterSensorClientWithTokenCallback callback) {
+ DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
+
+ if (!token_manager_.AuthenticateServerSensorClient(auth_token)) {
+ std::move(callback).Run(-EPERM);
+ return;
+ }
+
+ if (!chromeos::sensors::BindSensorHalClient(std::move(client))) {
+ LOG(ERROR) << "Failed to bind SensorHalClient to SensorHalDispatcher";
+ std::move(callback).Run(-ENOSYS);
+ return;
+ }
+
+ std::move(callback).Run(0);
+}
+
void CameraHalDispatcherImpl::StopOnProxyThread() {
DCHECK(proxy_task_runner_->BelongsToCurrentThread());
base::trace_event::TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
diff --git a/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl.h b/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl.h
index 57ecc7118a8..e3422a83a84 100644
--- a/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl.h
+++ b/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl.h
@@ -14,6 +14,7 @@
#include "base/files/scoped_file.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/singleton.h"
+#include "base/memory/weak_ptr.h"
#include "base/observer_list_threadsafe.h"
#include "base/observer_list_types.h"
#include "base/synchronization/lock.h"
@@ -113,12 +114,18 @@ class CAPTURE_EXPORT CameraPrivacySwitchObserver
// /var/run/camera3.sock. CameraHalServer and CameraHalClients connect to the
// unix domain socket to create the initial Mojo connections with the
// CameraHalDisptcherImpl, and CameraHalDispatcherImpl then creates and
-// dispaches the Mojo channels between CameraHalServer and CameraHalClients to
+// dispatches the Mojo channels between CameraHalServer and CameraHalClients to
// establish direct Mojo connections between the CameraHalServer and the
// CameraHalClients.
//
// For general documentation about the CameraHalDispater Mojo interface see the
// comments in mojo/cros_camera_service.mojom.
+//
+// On ChromeOS the video capture service must run in the browser process,
+// because parts of the code depend on global objects that are only available in
+// the Browser process. Therefore, CameraHalDispatcherImpl must run in the
+// browser process as well.
+// See https://crbug.com/891961.
class CAPTURE_EXPORT CameraHalDispatcherImpl final
: public cros::mojom::CameraHalDispatcher,
public cros::mojom::CameraHalServerCallbacks,
@@ -177,6 +184,10 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
void GetJpegEncodeAccelerator(
mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator>
jea_receiver) final;
+ void RegisterSensorClientWithToken(
+ mojo::PendingRemote<chromeos::sensors::mojom::SensorHalClient> client,
+ const base::UnguessableToken& auth_token,
+ RegisterSensorClientWithTokenCallback callback) final;
// CameraHalServerCallbacks implementations.
void CameraDeviceActivityChange(int32_t camera_id,
@@ -229,6 +240,11 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
void OnCameraHalServerConnectionError();
void OnCameraHalClientConnectionError(CameraClientObserver* client);
+ void RegisterSensorClientWithTokenOnUIThread(
+ mojo::PendingRemote<chromeos::sensors::mojom::SensorHalClient> client,
+ const base::UnguessableToken& auth_token,
+ RegisterSensorClientWithTokenCallback callback);
+
void StopOnProxyThread();
void OnTraceLogEnabledOnProxyThread();
@@ -241,6 +257,7 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
base::Thread proxy_thread_;
base::Thread blocking_io_thread_;
+ scoped_refptr<base::SequencedTaskRunner> main_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> blocking_io_task_runner_;
@@ -275,6 +292,8 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
scoped_refptr<base::ObserverListThreadSafe<CameraPrivacySwitchObserver>>
privacy_switch_observers_;
+ base::WeakPtrFactory<CameraHalDispatcherImpl> weak_factory_{this};
+
DISALLOW_COPY_AND_ASSIGN(CameraHalDispatcherImpl);
};
diff --git a/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl_unittest.cc b/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl_unittest.cc
index d5c6452a44a..f7b0265c2de 100644
--- a/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl_unittest.cc
+++ b/chromium/media/capture/video/chromeos/camera_hal_dispatcher_impl_unittest.cc
@@ -14,6 +14,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/test/task_environment.h"
#include "media/capture/video/chromeos/mojom/camera_common.mojom.h"
+#include "media/capture/video/chromeos/mojom/cros_camera_client.mojom.h"
#include "media/capture/video/chromeos/mojom/cros_camera_service.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@@ -108,7 +109,7 @@ class CameraHalDispatcherImplTest : public ::testing::Test {
}
void DoLoop() {
- run_loop_.reset(new base::RunLoop());
+ run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
diff --git a/chromium/media/capture/video/chromeos/camera_metadata_utils.h b/chromium/media/capture/video/chromeos/camera_metadata_utils.h
index 851b1fda550..d6b4a30b9f8 100644
--- a/chromium/media/capture/video/chromeos/camera_metadata_utils.h
+++ b/chromium/media/capture/video/chromeos/camera_metadata_utils.h
@@ -5,7 +5,7 @@
#ifndef MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_METADATA_UTILS_H_
#define MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_METADATA_UTILS_H_
-#include "base/stl_util.h"
+#include "base/containers/contains.h"
#include "media/capture/capture_export.h"
#include "media/capture/video/chromeos/mojom/camera_metadata.mojom.h"
diff --git a/chromium/media/capture/video/chromeos/gpu_memory_buffer_tracker.cc b/chromium/media/capture/video/chromeos/gpu_memory_buffer_tracker.cc
index 3a3f9a02a60..5b8c92838ea 100644
--- a/chromium/media/capture/video/chromeos/gpu_memory_buffer_tracker.cc
+++ b/chromium/media/capture/video/chromeos/gpu_memory_buffer_tracker.cc
@@ -19,7 +19,7 @@ GpuMemoryBufferTracker::~GpuMemoryBufferTracker() = default;
bool GpuMemoryBufferTracker::Init(const gfx::Size& dimensions,
VideoPixelFormat format,
const mojom::PlaneStridesPtr& strides) {
- base::Optional<gfx::BufferFormat> gfx_format = PixFormatVideoToGfx(format);
+ absl::optional<gfx::BufferFormat> gfx_format = PixFormatVideoToGfx(format);
if (!gfx_format) {
NOTREACHED() << "Unsupported VideoPixelFormat "
<< VideoPixelFormatToString(format);
@@ -46,7 +46,7 @@ bool GpuMemoryBufferTracker::IsReusableForFormat(
const gfx::Size& dimensions,
VideoPixelFormat format,
const mojom::PlaneStridesPtr& strides) {
- base::Optional<gfx::BufferFormat> gfx_format = PixFormatVideoToGfx(format);
+ absl::optional<gfx::BufferFormat> gfx_format = PixFormatVideoToGfx(format);
if (!gfx_format) {
return false;
}
diff --git a/chromium/media/capture/video/chromeos/mock_vendor_tag_ops.h b/chromium/media/capture/video/chromeos/mock_vendor_tag_ops.h
index d9bd4711941..8798e1c0c78 100644
--- a/chromium/media/capture/video/chromeos/mock_vendor_tag_ops.h
+++ b/chromium/media/capture/video/chromeos/mock_vendor_tag_ops.h
@@ -31,10 +31,10 @@ class MockVendorTagOps : public cros::mojom::VendorTagOps {
MOCK_METHOD0(DoGetAllTags, std::vector<uint32_t>());
void GetAllTags(GetAllTagsCallback callback);
- MOCK_METHOD1(DoGetSectionName, base::Optional<std::string>(uint32_t tag));
+ MOCK_METHOD1(DoGetSectionName, absl::optional<std::string>(uint32_t tag));
void GetSectionName(uint32_t tag, GetSectionNameCallback callback);
- MOCK_METHOD1(DoGetTagName, base::Optional<std::string>(uint32_t tag));
+ MOCK_METHOD1(DoGetTagName, absl::optional<std::string>(uint32_t tag));
void GetTagName(uint32_t tag, GetTagNameCallback callback);
MOCK_METHOD1(DoGetTagType, int32_t(uint32_t tag));
diff --git a/chromium/media/capture/video/chromeos/mojom/BUILD.gn b/chromium/media/capture/video/chromeos/mojom/BUILD.gn
index cb72cea2f1b..4dfea8a0522 100644
--- a/chromium/media/capture/video/chromeos/mojom/BUILD.gn
+++ b/chromium/media/capture/video/chromeos/mojom/BUILD.gn
@@ -11,10 +11,12 @@ mojom("cros_camera") {
"camera_common.mojom",
"camera_metadata.mojom",
"camera_metadata_tags.mojom",
+ "cros_camera_client.mojom",
"cros_camera_service.mojom",
]
deps = [
+ "//chromeos/components/sensors/mojom",
"//components/chromeos_camera/common",
"//media/capture/mojom:image_capture",
"//ui/gfx/geometry/mojom",
diff --git a/chromium/media/capture/video/chromeos/mojom/camera3.mojom b/chromium/media/capture/video/chromeos/mojom/camera3.mojom
index ce3e6506bc5..e0976bac90f 100644
--- a/chromium/media/capture/video/chromeos/mojom/camera3.mojom
+++ b/chromium/media/capture/video/chromeos/mojom/camera3.mojom
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Next min version: 4
+// Next min version: 5
module cros.mojom;
@@ -86,11 +86,15 @@ struct Camera3Stream {
uint32 data_space;
Camera3StreamRotation rotation;
[MinVersion=1] CropRotateScaleInfo? crop_rotate_scale_info;
+ // Required for camera HAL device API versions >= 3.5.
+ [MinVersion=4] string? physical_camera_id;
};
struct Camera3StreamConfiguration {
array<Camera3Stream> streams;
Camera3StreamConfigurationMode operation_mode;
+ // Required for camera HAL device API versions >= 3.5.
+ [MinVersion=4] CameraMetadata? session_parameters;
};
enum Camera3BufferStatus {
@@ -167,11 +171,21 @@ enum Camera3RequestTemplate {
CAMERA3_TEMPLATE_COUNT,
};
+struct Camera3PhyscamMetadata {
+ // |id| is the camera ID of the physical camera, and comes from
+ // CameraCharacteristics.getPhysicalCameraIds(). All values are guaranteed to
+ // be integers.
+ int32 id;
+ CameraMetadata metadata;
+};
+
struct Camera3CaptureRequest {
uint32 frame_number;
CameraMetadata settings;
Camera3StreamBuffer? input_buffer;
array<Camera3StreamBuffer> output_buffers;
+ // Required for camera HAL device API versions >= 3.5.
+ [MinVersion=4] array<Camera3PhyscamMetadata>? physcam_settings;
};
struct Camera3CaptureResult {
@@ -180,6 +194,8 @@ struct Camera3CaptureResult {
array<Camera3StreamBuffer>? output_buffers;
Camera3StreamBuffer? input_buffer;
uint32 partial_result;
+ // Required for camera HAL device API versions >= 3.5.
+ [MinVersion=4] array<Camera3PhyscamMetadata>? physcam_metadata;
};
// Camera3CallbackOps is a translation of the camera3_callback_ops_t API
diff --git a/chromium/media/capture/video/chromeos/mojom/camera_common.mojom b/chromium/media/capture/video/chromeos/mojom/camera_common.mojom
index 15e2ab0e381..74263e98341 100644
--- a/chromium/media/capture/video/chromeos/mojom/camera_common.mojom
+++ b/chromium/media/capture/video/chromeos/mojom/camera_common.mojom
@@ -22,6 +22,13 @@ struct CameraResourceCost {
uint32 resource_cost;
};
+const uint32 CAMERA_DEVICE_API_VERSION_3_0 = 0x300;
+const uint32 CAMERA_DEVICE_API_VERSION_3_1 = 0x301;
+const uint32 CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
+const uint32 CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
+const uint32 CAMERA_DEVICE_API_VERSION_3_4 = 0x304;
+const uint32 CAMERA_DEVICE_API_VERSION_3_5 = 0x305;
+
struct CameraInfo {
CameraFacing facing;
int32 orientation;
diff --git a/chromium/media/capture/video/chromeos/mojom/cros_camera_client.mojom b/chromium/media/capture/video/chromeos/mojom/cros_camera_client.mojom
new file mode 100644
index 00000000000..674b9bff613
--- /dev/null
+++ b/chromium/media/capture/video/chromeos/mojom/cros_camera_client.mojom
@@ -0,0 +1,23 @@
+// Copyright 2021 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.
+
+// Next min version: 1
+
+module cros.mojom;
+
+import "media/capture/video/chromeos/mojom/camera_common.mojom";
+
+// The CrOS camera HAL v3 Mojo client.
+//
+// Next method ID: 1
+interface CameraHalClient {
+ // A caller calls SetUpChannel to dispatch the established Mojo channel
+ // |camera_module| to the client. The CameraHalClient can create a Mojo
+ // channel to the camera HAL v3 adapter process with |camera_module|.
+ // SetUpChannel may be called multiple times. In cases such as the
+ // CameraHalServer which holds the original Mojo channel crashes,
+ // CameraHalDispatcher will call SetUpChannel again once a new CameraHalServer
+ // reconnects.
+ SetUpChannel@0(pending_remote<CameraModule> camera_module);
+};
diff --git a/chromium/media/capture/video/chromeos/mojom/cros_camera_service.mojom b/chromium/media/capture/video/chromeos/mojom/cros_camera_service.mojom
index b1a20076375..45c00de1e8e 100644
--- a/chromium/media/capture/video/chromeos/mojom/cros_camera_service.mojom
+++ b/chromium/media/capture/video/chromeos/mojom/cros_camera_service.mojom
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Next min version: 6
+// Next min version: 7
module cros.mojom;
+import "chromeos/components/sensors/mojom/cros_sensor_service.mojom";
import "components/chromeos_camera/common/jpeg_encode_accelerator.mojom";
import "components/chromeos_camera/common/mjpeg_decode_accelerator.mojom";
import "media/capture/video/chromeos/mojom/camera_common.mojom";
+import "media/capture/video/chromeos/mojom/cros_camera_client.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
// CameraClientType indicates the type of a CameraHalClient.
@@ -48,7 +50,7 @@ enum CameraPrivacySwitchState{
// channel to the server and pass the established Mojo channel to the client in
// order to set up a Mojo channel between the client and the server.
//
-// Next method ID: 6
+// Next method ID: 7
interface CameraHalDispatcher {
// [Deprecated in version 4]
// A CameraHalServer calls RegisterServer to register itself with the
@@ -88,6 +90,13 @@ interface CameraHalDispatcher {
CameraClientType type,
mojo_base.mojom.UnguessableToken auth_token) => (int32 result);
+ // A SensorHalClient calls RegisterSensorClient to register itself with
+ // SensorHalDispatcher through CameraHalDispatcher. |auth_token| is used to
+ // prove the caller has been granted permission to access SensorHalClient.
+ // CameraHalDispatcher will send back |result| as the errno.
+ [MinVersion=6] RegisterSensorClientWithToken@6(
+ pending_remote<chromeos.sensors.mojom.SensorHalClient> client,
+ mojo_base.mojom.UnguessableToken auth_token) => (int32 result);
};
// The CrOS camera HAL v3 Mojo server.
@@ -125,17 +134,3 @@ interface CameraHalServerCallbacks {
[MinVersion=5]
CameraPrivacySwitchStateChange@1(CameraPrivacySwitchState state);
};
-
-// The CrOS camera HAL v3 Mojo client.
-//
-// Next method ID: 1
-interface CameraHalClient {
- // A caller calls SetUpChannel to dispatch the established Mojo channel
- // |camera_module| to the client. The CameraHalClient can create a Mojo
- // channel to the camera HAL v3 adapter process with |camera_module|.
- // SetUpChannel may be called multiple times. In cases such as the
- // CameraHalServer which holds the original Mojo channel crashes,
- // CameraHalDispatcher will call SetUpChannel again once a new CameraHalServer
- // reconnects.
- SetUpChannel@0(pending_remote<CameraModule> camera_module);
-};
diff --git a/chromium/media/capture/video/chromeos/pixel_format_utils.cc b/chromium/media/capture/video/chromeos/pixel_format_utils.cc
index af5ded603ee..73237bc7569 100644
--- a/chromium/media/capture/video/chromeos/pixel_format_utils.cc
+++ b/chromium/media/capture/video/chromeos/pixel_format_utils.cc
@@ -62,7 +62,7 @@ uint32_t PixFormatVideoToDrm(VideoPixelFormat from) {
}
}
-base::Optional<gfx::BufferFormat> PixFormatVideoToGfx(
+absl::optional<gfx::BufferFormat> PixFormatVideoToGfx(
VideoPixelFormat pixel_format) {
switch (pixel_format) {
case PIXEL_FORMAT_MJPEG:
@@ -70,7 +70,7 @@ base::Optional<gfx::BufferFormat> PixFormatVideoToGfx(
case PIXEL_FORMAT_NV12:
return gfx::BufferFormat::YUV_420_BIPLANAR;
default:
- return base::nullopt;
+ return absl::nullopt;
}
}
diff --git a/chromium/media/capture/video/chromeos/pixel_format_utils.h b/chromium/media/capture/video/chromeos/pixel_format_utils.h
index be43491a9b4..f2ba1af221f 100644
--- a/chromium/media/capture/video/chromeos/pixel_format_utils.h
+++ b/chromium/media/capture/video/chromeos/pixel_format_utils.h
@@ -7,9 +7,9 @@
#include <vector>
-#include "base/optional.h"
#include "media/capture/video/chromeos/mojom/camera3.mojom.h"
#include "media/capture/video_capture_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/buffer_types.h"
namespace media {
@@ -32,7 +32,7 @@ std::vector<ChromiumPixelFormat> PixFormatHalToChromium(
uint32_t PixFormatVideoToDrm(VideoPixelFormat from);
// Converts the video pixel format |pixel_format| to gfx::BufferFormat.
-base::Optional<gfx::BufferFormat> PixFormatVideoToGfx(
+absl::optional<gfx::BufferFormat> PixFormatVideoToGfx(
VideoPixelFormat pixel_format);
} // namespace media
diff --git a/chromium/media/capture/video/chromeos/request_builder.cc b/chromium/media/capture/video/chromeos/request_builder.cc
index c4fbbdf5310..b82fa2b60bd 100644
--- a/chromium/media/capture/video/chromeos/request_builder.cc
+++ b/chromium/media/capture/video/chromeos/request_builder.cc
@@ -23,10 +23,10 @@ RequestBuilder::~RequestBuilder() = default;
cros::mojom::Camera3CaptureRequestPtr RequestBuilder::BuildRequest(
std::set<StreamType> stream_types,
cros::mojom::CameraMetadataPtr settings,
- base::Optional<uint64_t> input_buffer_id) {
+ absl::optional<uint64_t> input_buffer_id) {
auto capture_request = cros::mojom::Camera3CaptureRequest::New();
for (StreamType stream_type : stream_types) {
- base::Optional<BufferInfo> buffer_info;
+ absl::optional<BufferInfo> buffer_info;
if (IsInputStream(stream_type)) {
DCHECK(input_buffer_id.has_value());
buffer_info = request_buffer_callback_.Run(stream_type, input_buffer_id);
diff --git a/chromium/media/capture/video/chromeos/request_builder.h b/chromium/media/capture/video/chromeos/request_builder.h
index 95f4d8e5b32..90d4207d526 100644
--- a/chromium/media/capture/video/chromeos/request_builder.h
+++ b/chromium/media/capture/video/chromeos/request_builder.h
@@ -9,10 +9,10 @@
#include <set>
#include <vector>
-#include "base/optional.h"
#include "media/capture/video/chromeos/camera_device_delegate.h"
#include "media/capture/video/chromeos/mojom/camera3.mojom.h"
#include "media/capture/video_capture_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -33,7 +33,7 @@ struct BufferInfo {
class CAPTURE_EXPORT RequestBuilder {
public:
using RequestBufferCallback = base::RepeatingCallback<
- base::Optional<BufferInfo>(StreamType, base::Optional<uint64_t>)>;
+ absl::optional<BufferInfo>(StreamType, absl::optional<uint64_t>)>;
RequestBuilder(CameraDeviceContext* device_context,
// Callback to request buffer from StreamBufferManager. Having
@@ -47,7 +47,7 @@ class CAPTURE_EXPORT RequestBuilder {
cros::mojom::Camera3CaptureRequestPtr BuildRequest(
std::set<StreamType> stream_types,
cros::mojom::CameraMetadataPtr settings,
- base::Optional<uint64_t> input_buffer_id);
+ absl::optional<uint64_t> input_buffer_id);
private:
cros::mojom::CameraBufferHandlePtr CreateCameraBufferHandle(
diff --git a/chromium/media/capture/video/chromeos/request_manager.cc b/chromium/media/capture/video/chromeos/request_manager.cc
index 14cfdaba413..2eab9764a32 100644
--- a/chromium/media/capture/video/chromeos/request_manager.cc
+++ b/chromium/media/capture/video/chromeos/request_manager.cc
@@ -14,6 +14,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/containers/contains.h"
#include "base/posix/safe_strerror.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
@@ -43,7 +44,8 @@ RequestManager::RequestManager(
VideoCaptureBufferType buffer_type,
std::unique_ptr<CameraBufferFactory> camera_buffer_factory,
BlobifyCallback blobify_callback,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner)
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner,
+ uint32_t device_api_version)
: device_id_(device_id),
callback_ops_(this, std::move(callback_ops_receiver)),
capture_interface_(std::move(capture_interface)),
@@ -58,7 +60,8 @@ RequestManager::RequestManager(
ipc_task_runner_(std::move(ipc_task_runner)),
capturing_(false),
partial_result_count_(1),
- first_frame_shutter_time_(base::TimeTicks()) {
+ first_frame_shutter_time_(base::TimeTicks()),
+ device_api_version_(device_api_version) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
DCHECK(callback_ops_.is_bound());
DCHECK(device_context_);
@@ -287,7 +290,7 @@ void RequestManager::PrepareCaptureRequest() {
std::set<StreamType> stream_types;
cros::mojom::CameraMetadataPtr settings;
TakePhotoCallback callback = base::NullCallback();
- base::Optional<uint64_t> input_buffer_id;
+ absl::optional<uint64_t> input_buffer_id;
cros::mojom::Effect reprocess_effect = cros::mojom::Effect::NO_EFFECT;
bool is_reprocess_request = false;
@@ -369,6 +372,10 @@ void RequestManager::PrepareCaptureRequest() {
if (!is_reprocess_request) {
UpdateCaptureSettings(&capture_request->settings);
}
+ if (device_api_version_ >= cros::mojom::CAMERA_DEVICE_API_VERSION_3_5) {
+ capture_request->physcam_settings =
+ std::vector<cros::mojom::Camera3PhyscamMetadataPtr>();
+ }
capture_interface_->ProcessCaptureRequest(
std::move(capture_request),
base::BindOnce(&RequestManager::OnProcessedCaptureRequest, GetWeakPtr()));
@@ -378,7 +385,7 @@ bool RequestManager::TryPrepareReprocessRequest(
std::set<StreamType>* stream_types,
cros::mojom::CameraMetadataPtr* settings,
TakePhotoCallback* callback,
- base::Optional<uint64_t>* input_buffer_id,
+ absl::optional<uint64_t>* input_buffer_id,
cros::mojom::Effect* reprocess_effect) {
if (buffer_id_reprocess_job_info_map_.empty() ||
!stream_buffer_manager_->HasFreeBuffers(kYUVReprocessStreams)) {
@@ -882,7 +889,7 @@ void RequestManager::SubmitCapturedPreviewRecordingBuffer(
auto client_type = kStreamClientTypeMap[static_cast<int>(stream_type)];
if (video_capture_use_gmb_) {
VideoCaptureFormat format;
- base::Optional<VideoCaptureDevice::Client::Buffer> buffer =
+ absl::optional<VideoCaptureDevice::Client::Buffer> buffer =
stream_buffer_manager_->AcquireBufferForClientById(
stream_type, buffer_ipc_id, &format);
CHECK(buffer);
diff --git a/chromium/media/capture/video/chromeos/request_manager.h b/chromium/media/capture/video/chromeos/request_manager.h
index 8739ceab41c..8b9fc55ad22 100644
--- a/chromium/media/capture/video/chromeos/request_manager.h
+++ b/chromium/media/capture/video/chromeos/request_manager.h
@@ -14,7 +14,6 @@
#include "base/containers/flat_map.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "media/capture/mojom/image_capture.mojom.h"
#include "media/capture/video/chromeos/camera_app_device_impl.h"
#include "media/capture/video/chromeos/camera_device_context.h"
@@ -27,6 +26,7 @@
#include "media/capture/video_capture_types.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -93,7 +93,7 @@ class CAPTURE_EXPORT RequestManager final
// NO_EFFECT if it is not a reprocess request.
cros::mojom::Effect reprocess_effect;
// The input buffer id for this capture request.
- base::Optional<uint64_t> input_buffer_id;
+ absl::optional<uint64_t> input_buffer_id;
// The orientation which is stored at the time the request is prepared. It
// can be used to construct the reprocess job info when the result is back.
int32_t orientation;
@@ -107,7 +107,8 @@ class CAPTURE_EXPORT RequestManager final
VideoCaptureBufferType buffer_type,
std::unique_ptr<CameraBufferFactory> camera_buffer_factory,
BlobifyCallback blobify_callback,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner);
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner,
+ uint32_t device_api_version);
~RequestManager() override;
// Sets up the stream context and allocate buffers according to the
@@ -216,7 +217,7 @@ class CAPTURE_EXPORT RequestManager final
bool TryPrepareReprocessRequest(std::set<StreamType>* stream_types,
cros::mojom::CameraMetadataPtr* settings,
TakePhotoCallback* callback,
- base::Optional<uint64_t>* input_buffer_id,
+ absl::optional<uint64_t>* input_buffer_id,
cros::mojom::Effect* reprocess_effect);
bool TryPreparePreviewRequest(std::set<StreamType>* stream_types,
@@ -371,6 +372,9 @@ class CAPTURE_EXPORT RequestManager final
base::WeakPtr<CameraAppDeviceImpl> camera_app_device_;
+ // The API version of the camera device.
+ uint32_t device_api_version_;
+
base::WeakPtrFactory<RequestManager> weak_ptr_factory_{this};
DISALLOW_IMPLICIT_CONSTRUCTORS(RequestManager);
diff --git a/chromium/media/capture/video/chromeos/request_manager_unittest.cc b/chromium/media/capture/video/chromeos/request_manager_unittest.cc
index 90b9e83aafe..eb62aafc0f7 100644
--- a/chromium/media/capture/video/chromeos/request_manager_unittest.cc
+++ b/chromium/media/capture/video/chromeos/request_manager_unittest.cc
@@ -65,7 +65,8 @@ class FakeCameraBufferFactory : public CameraBufferFactory {
gfx::BufferFormat format,
gfx::BufferUsage usage) override {
return unittest_internal::MockGpuMemoryBufferManager::
- CreateFakeGpuMemoryBuffer(size, format, usage, gpu::kNullSurfaceHandle);
+ CreateFakeGpuMemoryBuffer(size, format, usage, gpu::kNullSurfaceHandle,
+ nullptr);
}
ChromiumPixelFormat ResolveStreamBufferFormat(
@@ -104,7 +105,8 @@ class RequestManagerTest : public ::testing::Test {
[](const uint8_t* buffer, const uint32_t bytesused,
const VideoCaptureFormat& capture_format,
const int rotation) { return mojom::Blob::New(); }),
- base::ThreadTaskRunnerHandle::Get());
+ base::ThreadTaskRunnerHandle::Get(),
+ cros::mojom::CAMERA_DEVICE_API_VERSION_3_5);
}
}
@@ -114,7 +116,7 @@ class RequestManagerTest : public ::testing::Test {
}
void DoLoop() {
- run_loop_.reset(new base::RunLoop());
+ run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
diff --git a/chromium/media/capture/video/chromeos/stream_buffer_manager.cc b/chromium/media/capture/video/chromeos/stream_buffer_manager.cc
index 21bf391e673..2c107163365 100644
--- a/chromium/media/capture/video/chromeos/stream_buffer_manager.cc
+++ b/chromium/media/capture/video/chromeos/stream_buffer_manager.cc
@@ -63,7 +63,7 @@ gfx::GpuMemoryBuffer* StreamBufferManager::GetGpuMemoryBufferById(
return it->second.gmb.get();
}
-base::Optional<StreamBufferManager::Buffer>
+absl::optional<StreamBufferManager::Buffer>
StreamBufferManager::AcquireBufferForClientById(StreamType stream_type,
uint64_t buffer_ipc_id,
VideoCaptureFormat* format) {
@@ -73,7 +73,7 @@ StreamBufferManager::AcquireBufferForClientById(StreamType stream_type,
if (it == stream_context->buffers.end()) {
LOG(ERROR) << "Invalid buffer: " << buffer_ipc_id
<< " for stream: " << stream_type;
- return base::nullopt;
+ return absl::nullopt;
}
auto buffer_pair = std::move(it->second);
stream_context->buffers.erase(it);
@@ -92,7 +92,7 @@ StreamBufferManager::AcquireBufferForClientById(StreamType stream_type,
gfx::Size(format->frame_size.height(), format->frame_size.width());
}
- base::Optional<gfx::BufferFormat> gfx_format =
+ absl::optional<gfx::BufferFormat> gfx_format =
PixFormatVideoToGfx(format->pixel_format);
DCHECK(gfx_format);
const auto& original_gmb = buffer_pair.gmb;
@@ -154,7 +154,7 @@ StreamBufferManager::AcquireBufferForClientById(StreamType stream_type,
return std::move(buffer_pair.vcd_buffer);
}
- base::Optional<gfx::BufferFormat> gfx_format =
+ absl::optional<gfx::BufferFormat> gfx_format =
PixFormatVideoToGfx(format->pixel_format);
DCHECK(gfx_format);
auto rotated_gmb = gmb_support_->CreateGpuMemoryBufferImplFromHandle(
@@ -320,9 +320,9 @@ cros::mojom::Camera3StreamPtr StreamBufferManager::GetStreamConfiguration(
return stream_context_[stream_type]->stream.Clone();
}
-base::Optional<BufferInfo> StreamBufferManager::RequestBufferForCaptureRequest(
+absl::optional<BufferInfo> StreamBufferManager::RequestBufferForCaptureRequest(
StreamType stream_type,
- base::Optional<uint64_t> buffer_ipc_id) {
+ absl::optional<uint64_t> buffer_ipc_id) {
VideoPixelFormat buffer_format =
stream_context_[stream_type]->capture_format.pixel_format;
uint32_t drm_format = PixFormatVideoToDrm(buffer_format);
@@ -405,7 +405,7 @@ int StreamBufferManager::GetBufferKey(uint64_t buffer_ipc_id) {
void StreamBufferManager::ReserveBufferFromFactory(StreamType stream_type) {
auto& stream_context = stream_context_[stream_type];
- base::Optional<gfx::BufferFormat> gfx_format =
+ absl::optional<gfx::BufferFormat> gfx_format =
PixFormatVideoToGfx(stream_context->capture_format.pixel_format);
if (!gfx_format) {
device_context_->SetErrorState(
@@ -437,12 +437,12 @@ void StreamBufferManager::ReserveBufferFromFactory(StreamType stream_type) {
int key = stream_context->buffers.size() + 1;
stream_context->free_buffers.push(key);
stream_context->buffers.insert(
- std::make_pair(key, BufferPair(std::move(gmb), base::nullopt)));
+ std::make_pair(key, BufferPair(std::move(gmb), absl::nullopt)));
}
void StreamBufferManager::ReserveBufferFromPool(StreamType stream_type) {
auto& stream_context = stream_context_[stream_type];
- base::Optional<gfx::BufferFormat> gfx_format =
+ absl::optional<gfx::BufferFormat> gfx_format =
PixFormatVideoToGfx(stream_context->capture_format.pixel_format);
if (!gfx_format) {
device_context_->SetErrorState(
@@ -489,7 +489,7 @@ void StreamBufferManager::DestroyCurrentStreamsAndBuffers() {
StreamBufferManager::BufferPair::BufferPair(
std::unique_ptr<gfx::GpuMemoryBuffer> input_gmb,
- base::Optional<Buffer> input_vcd_buffer)
+ absl::optional<Buffer> input_vcd_buffer)
: gmb(std::move(input_gmb)), vcd_buffer(std::move(input_vcd_buffer)) {}
StreamBufferManager::BufferPair::BufferPair(
diff --git a/chromium/media/capture/video/chromeos/stream_buffer_manager.h b/chromium/media/capture/video/chromeos/stream_buffer_manager.h
index ba62fbe89f4..86ea140aa93 100644
--- a/chromium/media/capture/video/chromeos/stream_buffer_manager.h
+++ b/chromium/media/capture/video/chromeos/stream_buffer_manager.h
@@ -17,12 +17,12 @@
#include "base/containers/flat_map.h"
#include "base/containers/queue.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "media/capture/video/chromeos/camera_device_context.h"
#include "media/capture/video/chromeos/camera_device_delegate.h"
#include "media/capture/video/chromeos/mojom/camera3.mojom.h"
#include "media/capture/video_capture_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace gfx {
@@ -68,7 +68,7 @@ class CAPTURE_EXPORT StreamBufferManager final {
//
// TODO(crbug.com/990682): Remove the |rotation| arg when we disable the
// camera frame rotation for good.
- base::Optional<Buffer> AcquireBufferForClientById(StreamType stream_type,
+ absl::optional<Buffer> AcquireBufferForClientById(StreamType stream_type,
uint64_t buffer_ipc_id,
VideoCaptureFormat* format);
@@ -93,9 +93,9 @@ class CAPTURE_EXPORT StreamBufferManager final {
// Requests buffer for specific stream type. If the |buffer_id| is provided,
// it will use |buffer_id| as buffer id rather than using id from free
// buffers.
- base::Optional<BufferInfo> RequestBufferForCaptureRequest(
+ absl::optional<BufferInfo> RequestBufferForCaptureRequest(
StreamType stream_type,
- base::Optional<uint64_t> buffer_ipc_id);
+ absl::optional<uint64_t> buffer_ipc_id);
// Releases buffer by marking it as free buffer.
void ReleaseBufferFromCaptureResult(StreamType stream_type,
@@ -113,7 +113,7 @@ class CAPTURE_EXPORT StreamBufferManager final {
// BufferPair holding up to two types of handles of a stream buffer.
struct BufferPair {
BufferPair(std::unique_ptr<gfx::GpuMemoryBuffer> gmb,
- base::Optional<Buffer> vcd_buffer);
+ absl::optional<Buffer> vcd_buffer);
BufferPair(BufferPair&& other);
~BufferPair();
// The GpuMemoryBuffer interface of the stream buffer.
@@ -124,7 +124,7 @@ class CAPTURE_EXPORT StreamBufferManager final {
std::unique_ptr<gfx::GpuMemoryBuffer> gmb;
// The VCD buffer reserved from the VCD buffer pool. This is only set when
// the VCD runs GpuMemoryBuffer-based VideoCapture buffer.
- base::Optional<Buffer> vcd_buffer;
+ absl::optional<Buffer> vcd_buffer;
};
struct StreamContext {
diff --git a/chromium/media/capture/video/chromeos/token_manager.cc b/chromium/media/capture/video/chromeos/token_manager.cc
index 4e128d9348c..90e8f169d7a 100644
--- a/chromium/media/capture/video/chromeos/token_manager.cc
+++ b/chromium/media/capture/video/chromeos/token_manager.cc
@@ -13,6 +13,7 @@
#include "base/files/file_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
+#include "chromeos/components/sensors/ash/sensor_hal_dispatcher.h"
namespace {
@@ -66,6 +67,7 @@ bool WriteTokenToFile(const base::FilePath& token_path,
namespace media {
constexpr char TokenManager::kServerTokenPath[];
+constexpr char TokenManager::kServerSensorClientTokenPath[];
constexpr char TokenManager::kTestClientTokenPath[];
constexpr std::array<cros::mojom::CameraClientType, 3>
TokenManager::kTrustedClientTypes;
@@ -78,6 +80,16 @@ bool TokenManager::GenerateServerToken() {
return WriteTokenToFile(base::FilePath(kServerTokenPath), server_token_);
}
+bool TokenManager::GenerateServerSensorClientToken() {
+ auto* sensor_hal_dispatcher =
+ chromeos::sensors::SensorHalDispatcher::GetInstance();
+ if (!sensor_hal_dispatcher)
+ return false;
+
+ return WriteTokenToFile(base::FilePath(kServerSensorClientTokenPath),
+ sensor_hal_dispatcher->GetTokenForTrustedClient());
+}
+
bool TokenManager::GenerateTestClientToken() {
return WriteTokenToFile(
base::FilePath(kTestClientTokenPath),
@@ -122,7 +134,17 @@ bool TokenManager::AuthenticateServer(const base::UnguessableToken& token) {
return server_token_ == token;
}
-base::Optional<cros::mojom::CameraClientType> TokenManager::AuthenticateClient(
+bool TokenManager::AuthenticateServerSensorClient(
+ const base::UnguessableToken& token) {
+ auto* sensor_hal_dispatcher =
+ chromeos::sensors::SensorHalDispatcher::GetInstance();
+ if (!sensor_hal_dispatcher)
+ return false;
+
+ return sensor_hal_dispatcher->AuthenticateClient(token);
+}
+
+absl::optional<cros::mojom::CameraClientType> TokenManager::AuthenticateClient(
cros::mojom::CameraClientType type,
const base::UnguessableToken& token) {
base::AutoLock l(client_token_map_lock_);
@@ -133,11 +155,11 @@ base::Optional<cros::mojom::CameraClientType> TokenManager::AuthenticateClient(
return client_token_map_pair.first;
}
}
- return base::nullopt;
+ return absl::nullopt;
}
auto& token_set = client_token_map_[type];
if (token_set.find(token) == token_set.end()) {
- return base::nullopt;
+ return absl::nullopt;
}
return type;
}
diff --git a/chromium/media/capture/video/chromeos/token_manager.h b/chromium/media/capture/video/chromeos/token_manager.h
index c4a75ad5f9f..0508aae905c 100644
--- a/chromium/media/capture/video/chromeos/token_manager.h
+++ b/chromium/media/capture/video/chromeos/token_manager.h
@@ -9,17 +9,19 @@
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
-#include "base/optional.h"
#include "base/thread_annotations.h"
#include "base/unguessable_token.h"
#include "media/capture/capture_export.h"
#include "media/capture/video/chromeos/mojom/cros_camera_service.mojom.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
class CAPTURE_EXPORT TokenManager {
public:
static constexpr char kServerTokenPath[] = "/run/camera_tokens/server/token";
+ static constexpr char kServerSensorClientTokenPath[] =
+ "/run/camera_tokens/server/sensor_client_token";
static constexpr char kTestClientTokenPath[] =
"/run/camera_tokens/testing/token";
static constexpr std::array<cros::mojom::CameraClientType, 3>
@@ -31,6 +33,7 @@ class CAPTURE_EXPORT TokenManager {
~TokenManager();
bool GenerateServerToken();
+ bool GenerateServerSensorClientToken();
bool GenerateTestClientToken();
@@ -41,13 +44,14 @@ class CAPTURE_EXPORT TokenManager {
void UnregisterPluginVmToken(const base::UnguessableToken& token);
bool AuthenticateServer(const base::UnguessableToken& token);
+ bool AuthenticateServerSensorClient(const base::UnguessableToken& token);
// Authenticates client with the given |type| and |token|. When |type| is
// cros::mojom::CameraClientType::UNKNOWN, it tries to figure out the actual
// client type by the supplied |token|. If authentication succeeds, it returns
// the authenticated type of the client. If authentication fails,
- // base::nullopt is returned.
- base::Optional<cros::mojom::CameraClientType> AuthenticateClient(
+ // absl::nullopt is returned.
+ absl::optional<cros::mojom::CameraClientType> AuthenticateClient(
cros::mojom::CameraClientType type,
const base::UnguessableToken& token);
diff --git a/chromium/media/capture/video/chromeos/vendor_tag_ops_delegate.cc b/chromium/media/capture/video/chromeos/vendor_tag_ops_delegate.cc
index 013b267fa77..0f36b69eb6c 100644
--- a/chromium/media/capture/video/chromeos/vendor_tag_ops_delegate.cc
+++ b/chromium/media/capture/video/chromeos/vendor_tag_ops_delegate.cc
@@ -96,7 +96,7 @@ void VendorTagOpsDelegate::OnGotAllTags(size_t tag_count,
void VendorTagOpsDelegate::OnGotSectionName(
uint32_t tag,
- const base::Optional<std::string>& section_name) {
+ const absl::optional<std::string>& section_name) {
DCHECK(ipc_task_runner_->RunsTasksInCurrentSequence());
if (!section_name.has_value()) {
LOG(ERROR) << "Failed to get section name of tag " << std::hex
@@ -113,7 +113,7 @@ void VendorTagOpsDelegate::OnGotSectionName(
void VendorTagOpsDelegate::OnGotTagName(
uint32_t tag,
- const base::Optional<std::string>& tag_name) {
+ const absl::optional<std::string>& tag_name) {
DCHECK(ipc_task_runner_->RunsTasksInCurrentSequence());
if (!tag_name.has_value()) {
LOG(ERROR) << "Failed to get tag name of tag " << std::hex << std::showbase
diff --git a/chromium/media/capture/video/chromeos/vendor_tag_ops_delegate.h b/chromium/media/capture/video/chromeos/vendor_tag_ops_delegate.h
index cd963e0cdd8..a5e3aa8e2dc 100644
--- a/chromium/media/capture/video/chromeos/vendor_tag_ops_delegate.h
+++ b/chromium/media/capture/video/chromeos/vendor_tag_ops_delegate.h
@@ -48,8 +48,8 @@ class VendorTagOpsDelegate {
void OnGotTagCount(int32_t tag_count);
void OnGotAllTags(size_t tag_count, const std::vector<uint32_t>& tags);
void OnGotSectionName(uint32_t tag,
- const base::Optional<std::string>& section_name);
- void OnGotTagName(uint32_t tag, const base::Optional<std::string>& tag_name);
+ const absl::optional<std::string>& section_name);
+ void OnGotTagName(uint32_t tag, const absl::optional<std::string>& tag_name);
void OnGotTagType(uint32_t tag, int32_t type);
scoped_refptr<base::SequencedTaskRunner> ipc_task_runner_;
diff --git a/chromium/media/capture/video/chromeos/video_capture_device_chromeos_delegate.cc b/chromium/media/capture/video/chromeos/video_capture_device_chromeos_delegate.cc
index ebb424ceb25..a1e7cdf555b 100644
--- a/chromium/media/capture/video/chromeos/video_capture_device_chromeos_delegate.cc
+++ b/chromium/media/capture/video/chromeos/video_capture_device_chromeos_delegate.cc
@@ -265,6 +265,8 @@ void VideoCaptureDeviceChromeOSDelegate::CloseDevice(
DCHECK(capture_task_runner_->BelongsToCurrentThread());
if (!camera_device_delegate_) {
+ if (!unblock_suspend_token.is_empty())
+ power_manager_client_proxy_->UnblockSuspend(unblock_suspend_token);
return;
}
// We do our best to allow the camera HAL cleanly shut down the device. In
diff --git a/chromium/media/capture/video/chromeos/video_capture_features_chromeos.cc b/chromium/media/capture/video/chromeos/video_capture_features_chromeos.cc
index 6e07d3913ad..81919624dac 100644
--- a/chromium/media/capture/video/chromeos/video_capture_features_chromeos.cc
+++ b/chromium/media/capture/video/chromeos/video_capture_features_chromeos.cc
@@ -12,5 +12,9 @@ namespace features {
const base::Feature kDisableCameraFrameRotationAtSource{
"DisableCameraFrameRotationAtSource", base::FEATURE_DISABLED_BY_DEFAULT};
+// If enabled, will force enable face AE if the camera supports.
+const base::Feature kForceEnableFaceAe{"ForceEnableFaceAe",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
} // namespace features
} // namespace media
diff --git a/chromium/media/capture/video/chromeos/video_capture_features_chromeos.h b/chromium/media/capture/video/chromeos/video_capture_features_chromeos.h
index f9d1705f366..04633a854b3 100644
--- a/chromium/media/capture/video/chromeos/video_capture_features_chromeos.h
+++ b/chromium/media/capture/video/chromeos/video_capture_features_chromeos.h
@@ -12,6 +12,7 @@ namespace media {
namespace features {
CAPTURE_EXPORT extern const base::Feature kDisableCameraFrameRotationAtSource;
+CAPTURE_EXPORT extern const base::Feature kForceEnableFaceAe;
} // namespace features
} // namespace media
diff --git a/chromium/media/capture/video/chromeos/video_capture_jpeg_decoder.h b/chromium/media/capture/video/chromeos/video_capture_jpeg_decoder.h
index 59850884926..21a51d09df2 100644
--- a/chromium/media/capture/video/chromeos/video_capture_jpeg_decoder.h
+++ b/chromium/media/capture/video/chromeos/video_capture_jpeg_decoder.h
@@ -7,7 +7,6 @@
#include "base/callback.h"
#include "media/capture/capture_export.h"
-#include "media/capture/mojom/video_capture_types.mojom.h"
#include "media/capture/video/video_capture_device.h"
#include "media/capture/video/video_frame_receiver.h"
diff --git a/chromium/media/capture/video/create_video_capture_device_factory.cc b/chromium/media/capture/video/create_video_capture_device_factory.cc
index 435ede8bd3b..f234d6822f3 100644
--- a/chromium/media/capture/video/create_video_capture_device_factory.cc
+++ b/chromium/media/capture/video/create_video_capture_device_factory.cc
@@ -16,7 +16,6 @@
#elif BUILDFLAG(IS_CHROMEOS_ASH)
#include "media/capture/video/chromeos/public/cros_features.h"
#include "media/capture/video/chromeos/video_capture_device_factory_chromeos.h"
-#include "media/capture/video/linux/video_capture_device_factory_linux.h"
#elif defined(OS_WIN)
#include "media/capture/video/win/video_capture_device_factory_win.h"
#elif defined(OS_MAC)
@@ -56,34 +55,13 @@ CreateFakeVideoCaptureDeviceFactory() {
}
}
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-std::unique_ptr<VideoCaptureDeviceFactory>
-CreateChromeOSVideoCaptureDeviceFactory(
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
- // On Chrome OS we have to support two use cases:
- //
- // 1. For devices that have the camera HAL v3 service running on Chrome OS,
- // we use the HAL v3 capture device which VideoCaptureDeviceFactoryChromeOS
- // provides.
- // 2. Existing devices that use UVC cameras need to use the V4L2 capture
- // device which VideoCaptureDeviceFacotoryLinux provides; there are also
- // some special devices that may never be able to implement a camera HAL
- // v3.
- if (ShouldUseCrosCameraService()) {
- return std::make_unique<VideoCaptureDeviceFactoryChromeOS>(ui_task_runner);
- } else {
- return std::make_unique<VideoCaptureDeviceFactoryLinux>(ui_task_runner);
- }
-}
-#endif // BUILDFLAG(IS_CHROMEOS_ASH)
-
std::unique_ptr<VideoCaptureDeviceFactory>
CreatePlatformSpecificVideoCaptureDeviceFactory(
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
return std::make_unique<VideoCaptureDeviceFactoryLinux>(ui_task_runner);
#elif BUILDFLAG(IS_CHROMEOS_ASH)
- return CreateChromeOSVideoCaptureDeviceFactory(ui_task_runner);
+ return std::make_unique<VideoCaptureDeviceFactoryChromeOS>(ui_task_runner);
#elif defined(OS_WIN)
return std::make_unique<VideoCaptureDeviceFactoryWin>();
#elif defined(OS_MAC)
diff --git a/chromium/media/capture/video/fake_video_capture_device_factory.cc b/chromium/media/capture/video/fake_video_capture_device_factory.cc
index b96840f0a63..222e0ab1582 100644
--- a/chromium/media/capture/video/fake_video_capture_device_factory.cc
+++ b/chromium/media/capture/video/fake_video_capture_device_factory.cc
@@ -267,9 +267,9 @@ void FakeVideoCaptureDeviceFactory::ParseFakeDevicesConfigFromOptionsString(
FakeVideoCaptureDevice::DisplayMediaType::ANY;
while (option_tokenizer.GetNext()) {
- std::vector<std::string> param =
- base::SplitString(option_tokenizer.token(), "=", base::TRIM_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY);
+ std::vector<base::StringPiece> param = base::SplitStringPiece(
+ option_tokenizer.token_piece(), "=", base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY);
if (param.size() != 2u) {
LOG(WARNING) << "Forget a value '" << options_string
diff --git a/chromium/media/capture/video/file_video_capture_device.cc b/chromium/media/capture/video/file_video_capture_device.cc
index f70ee57eed8..295db70a9eb 100644
--- a/chromium/media/capture/video/file_video_capture_device.cc
+++ b/chromium/media/capture/video/file_video_capture_device.cc
@@ -13,6 +13,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/numerics/ranges.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
@@ -28,6 +29,23 @@
namespace media {
+namespace {
+
+int gcd(int a, int b) {
+ int c;
+
+ c = a % b;
+ while (c != 0) {
+ a = b;
+ b = c;
+ c = a % b;
+ }
+
+ return (b);
+}
+
+} // namespace
+
static const int kY4MHeaderMaxSize = 200;
static const char kY4MSimpleFrameDelimiter[] = "FRAME";
static const int kY4MSimpleFrameDelimiterSize = 6;
@@ -307,6 +325,124 @@ std::unique_ptr<VideoFileParser> FileVideoCaptureDevice::GetVideoFileParser(
return file_parser;
}
+std::unique_ptr<uint8_t[]> FileVideoCaptureDevice::CropPTZRegion(
+ const uint8_t* frame,
+ size_t frame_buffer_size) {
+ CHECK(frame);
+
+ const gfx::Size& frame_size = capture_format_.frame_size;
+ uint32_t fourcc;
+ std::unique_ptr<uint8_t[]> jpeg_to_i420_buffer_;
+ switch (capture_format_.pixel_format) {
+ case PIXEL_FORMAT_MJPEG:
+ // |libyuv::ConvertToI420| don't support cropping MJPG into different
+ // width and thus require transform to i420 first.
+ if ([&frame, &frame_buffer_size, &frame_size, &jpeg_to_i420_buffer_]() {
+ const size_t i420_buffer_size =
+ VideoFrame::AllocationSize(PIXEL_FORMAT_I420, frame_size);
+ jpeg_to_i420_buffer_.reset(new uint8_t[i420_buffer_size]);
+
+ uint8_t* dst_yp = jpeg_to_i420_buffer_.get();
+ uint8_t* dst_up =
+ dst_yp + VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 0, frame_size)
+ .GetArea();
+ uint8_t* dst_vp =
+ dst_up + VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 1, frame_size)
+ .GetArea();
+ int dst_yp_stride = frame_size.width();
+ int dst_up_stride = dst_yp_stride / 2;
+ int dst_vp_stride = dst_yp_stride / 2;
+
+ return libyuv::ConvertToI420(
+ frame, frame_buffer_size, dst_yp, dst_yp_stride, dst_up,
+ dst_up_stride, dst_vp, dst_vp_stride, /* crop_x */ 0,
+ /* crop_y */ 0,
+ /* src_width */ frame_size.width(),
+ /* src_height */ frame_size.height(),
+ /* crop_width */ frame_size.width(),
+ /* crop_height */ frame_size.height(),
+ libyuv::RotationMode::kRotate0, libyuv::FOURCC_MJPG);
+ }()) {
+ LOG(ERROR) << "Failed to convert MJPEG to i420 for ptz transform";
+ }
+ frame = jpeg_to_i420_buffer_.get();
+ frame_buffer_size =
+ VideoFrame::AllocationSize(PIXEL_FORMAT_I420, frame_size);
+ ABSL_FALLTHROUGH_INTENDED;
+ case PIXEL_FORMAT_I420:
+ fourcc = libyuv::FOURCC_I420;
+ break;
+ default:
+ LOG(ERROR) << "Unsupported file format for ptz transform.";
+ return {};
+ }
+
+ // Crop zoomed region.
+ const int crop_width = (zoom_max_levels_ - zoom_) * aspect_ratio_numerator_;
+ const int crop_height =
+ (zoom_max_levels_ - zoom_) * aspect_ratio_denominator_;
+ const gfx::Size crop_size(crop_width, crop_height);
+ const int crop_x =
+ std::min(pan_ * aspect_ratio_numerator_, frame_size.width() - crop_width);
+ const int crop_y =
+ std::min((zoom_max_levels_ - 1 - tilt_) * aspect_ratio_denominator_,
+ frame_size.height() - crop_height);
+ const size_t crop_buffer_size =
+ VideoFrame::AllocationSize(PIXEL_FORMAT_I420, crop_size);
+ std::unique_ptr<uint8_t[]> crop_frame(new uint8_t[crop_buffer_size]);
+
+ uint8_t* crop_yp = crop_frame.get();
+ uint8_t* crop_up =
+ crop_yp +
+ VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 0, crop_size).GetArea();
+ uint8_t* crop_vp =
+ crop_up +
+ VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 1, crop_size).GetArea();
+ int crop_yp_stride = crop_width;
+ int crop_up_stride = crop_yp_stride / 2;
+ int crop_vp_stride = crop_yp_stride / 2;
+
+ if (libyuv::ConvertToI420(frame, frame_buffer_size, crop_yp, crop_yp_stride,
+ crop_up, crop_up_stride, crop_vp, crop_vp_stride,
+ crop_x, crop_y, frame_size.width(),
+ frame_size.height(), crop_width, crop_height,
+ libyuv::RotationMode::kRotate0, fourcc)) {
+ LOG(ERROR) << "Failed to crop image for ptz transform.";
+ return {};
+ }
+
+ if (crop_size == frame_size)
+ return crop_frame;
+
+ // Scale cropped region to original size.
+ const auto& scale_size = frame_size;
+ const size_t scale_buffer_size =
+ VideoFrame::AllocationSize(PIXEL_FORMAT_I420, scale_size);
+ std::unique_ptr<uint8_t[]> scale_frame(new uint8_t[scale_buffer_size]);
+
+ uint8_t* scale_yp = scale_frame.get();
+ uint8_t* scale_up =
+ scale_yp +
+ VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 0, scale_size).GetArea();
+ uint8_t* scale_vp =
+ scale_up +
+ VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 1, scale_size).GetArea();
+ int scale_yp_stride = scale_size.width();
+ int scale_up_stride = scale_yp_stride / 2;
+ int scale_vp_stride = scale_yp_stride / 2;
+
+ if (libyuv::I420Scale(crop_yp, crop_yp_stride, crop_up, crop_up_stride,
+ crop_vp, crop_vp_stride, crop_width, crop_height,
+ scale_yp, scale_yp_stride, scale_up, scale_up_stride,
+ scale_vp, scale_vp_stride, scale_size.width(),
+ scale_size.height(),
+ libyuv::FilterMode::kFilterBilinear)) {
+ LOG(ERROR) << "Failed to scale image for ptz transform.";
+ return {};
+ }
+ return scale_frame;
+}
+
FileVideoCaptureDevice::FileVideoCaptureDevice(
const base::FilePath& file_path,
std::unique_ptr<gpu::GpuMemoryBufferSupport> gmb_support)
@@ -348,6 +484,15 @@ void FileVideoCaptureDevice::StopAndDeAllocate() {
void FileVideoCaptureDevice::GetPhotoState(GetPhotoStateCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
+ CHECK(capture_thread_.IsRunning());
+
+ capture_thread_.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&FileVideoCaptureDevice::OnGetPhotoState,
+ base::Unretained(this), std::move(callback)));
+}
+
+void FileVideoCaptureDevice::OnGetPhotoState(GetPhotoStateCallback callback) {
+ DCHECK(capture_thread_.task_runner()->BelongsToCurrentThread());
auto photo_capabilities = mojo::CreateEmptyPhotoState();
@@ -356,12 +501,44 @@ void FileVideoCaptureDevice::GetPhotoState(GetPhotoStateCallback callback) {
int width = capture_format_.frame_size.width();
photo_capabilities->width = mojom::Range::New(width, width, width, 0);
+ if (zoom_max_levels_ > 0) {
+ photo_capabilities->pan = mojom::Range::New();
+ photo_capabilities->pan->current = pan_;
+ photo_capabilities->pan->max = zoom_max_levels_ - 1;
+ photo_capabilities->pan->min = 0;
+ photo_capabilities->pan->step = 1;
+
+ photo_capabilities->tilt = mojom::Range::New();
+ photo_capabilities->tilt->current = tilt_;
+ photo_capabilities->tilt->max = zoom_max_levels_ - 1;
+ photo_capabilities->tilt->min = 0;
+ photo_capabilities->tilt->step = 1;
+
+ photo_capabilities->zoom = mojom::Range::New();
+ photo_capabilities->zoom->current = zoom_;
+ photo_capabilities->zoom->max = zoom_max_levels_ - 1;
+ photo_capabilities->zoom->min = 0;
+ photo_capabilities->zoom->step = 1;
+ }
+
std::move(callback).Run(std::move(photo_capabilities));
}
void FileVideoCaptureDevice::SetPhotoOptions(mojom::PhotoSettingsPtr settings,
SetPhotoOptionsCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
+ CHECK(capture_thread_.IsRunning());
+
+ capture_thread_.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&FileVideoCaptureDevice::OnSetPhotoOptions,
+ base::Unretained(this), std::move(settings),
+ std::move(callback)));
+}
+
+void FileVideoCaptureDevice::OnSetPhotoOptions(
+ mojom::PhotoSettingsPtr settings,
+ SetPhotoOptionsCallback callback) {
+ DCHECK(capture_thread_.task_runner()->BelongsToCurrentThread());
if (settings->has_height &&
settings->height != capture_format_.frame_size.height()) {
@@ -383,11 +560,21 @@ void FileVideoCaptureDevice::SetPhotoOptions(mojom::PhotoSettingsPtr settings,
settings->has_color_temperature || settings->has_iso ||
settings->has_brightness || settings->has_contrast ||
settings->has_saturation || settings->has_sharpness ||
- settings->has_focus_distance || settings->has_pan || settings->has_tilt ||
- settings->has_zoom || settings->has_fill_light_mode) {
+ settings->has_focus_distance || settings->has_fill_light_mode) {
return;
}
+ if (settings->has_pan) {
+ pan_ = base::ClampToRange(int(settings->pan), 0, zoom_max_levels_);
+ }
+
+ if (settings->has_tilt) {
+ tilt_ = base::ClampToRange(int(settings->tilt), 0, zoom_max_levels_);
+ }
+ if (settings->has_zoom) {
+ zoom_ = base::ClampToRange(int(settings->zoom), 0, zoom_max_levels_);
+ }
+
std::move(callback).Run(true);
}
@@ -417,6 +604,16 @@ void FileVideoCaptureDevice::OnAllocateAndStart(
return;
}
+ zoom_max_levels_ = gcd(capture_format_.frame_size.width(),
+ capture_format_.frame_size.height());
+ aspect_ratio_numerator_ =
+ capture_format_.frame_size.width() / zoom_max_levels_;
+ aspect_ratio_denominator_ =
+ capture_format_.frame_size.height() / zoom_max_levels_;
+ zoom_ = 0;
+ pan_ = 0;
+ tilt_ = zoom_max_levels_ - 1;
+
DVLOG(1) << "Opened video file " << capture_format_.frame_size.ToString()
<< ", fps: " << capture_format_.frame_rate;
client_->OnStarted();
@@ -442,8 +639,11 @@ void FileVideoCaptureDevice::OnCaptureTask() {
// Give the captured frame to the client.
int frame_size = 0;
const uint8_t* frame_ptr = file_parser_->GetNextFrame(&frame_size);
- DCHECK(frame_size);
CHECK(frame_ptr);
+
+ auto ptz_frame = CropPTZRegion(frame_ptr, frame_size);
+ CHECK(ptz_frame);
+
const base::TimeTicks current_time = base::TimeTicks::Now();
if (first_ref_time_.is_null())
first_ref_time_ = current_time;
@@ -462,12 +662,12 @@ void FileVideoCaptureDevice::OnCaptureTask() {
return;
}
ScopedNV12GpuMemoryBufferMapping scoped_mapping(std::move(gmb));
- const uint8_t* src_y_plane = frame_ptr;
+ const uint8_t* src_y_plane = ptz_frame.get();
const uint8_t* src_u_plane =
- frame_ptr +
+ ptz_frame.get() +
VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 0, buffer_size).GetArea();
const uint8_t* src_v_plane =
- frame_ptr +
+ ptz_frame.get() +
VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 0, buffer_size).GetArea() +
VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 1, buffer_size).GetArea();
libyuv::I420ToNV12(
@@ -487,7 +687,7 @@ void FileVideoCaptureDevice::OnCaptureTask() {
// Leave the color space unset for compatibility purposes but this
// information should be retrieved from the container when possible.
client_->OnIncomingCapturedData(
- frame_ptr, frame_size, capture_format_, gfx::ColorSpace(),
+ ptz_frame.get(), frame_size, capture_format_, gfx::ColorSpace(),
0 /* clockwise_rotation */, false /* flip_y */, current_time,
current_time - first_ref_time_);
}
@@ -498,7 +698,7 @@ void FileVideoCaptureDevice::OnCaptureTask() {
take_photo_callbacks_.pop();
mojom::BlobPtr blob =
- RotateAndBlobify(frame_ptr, frame_size, capture_format_, 0);
+ RotateAndBlobify(ptz_frame.get(), frame_size, capture_format_, 0);
if (!blob)
continue;
diff --git a/chromium/media/capture/video/file_video_capture_device.h b/chromium/media/capture/video/file_video_capture_device.h
index 796202cc778..a08187a58d0 100644
--- a/chromium/media/capture/video/file_video_capture_device.h
+++ b/chromium/media/capture/video/file_video_capture_device.h
@@ -10,6 +10,7 @@
#include <memory>
#include <string>
+#include "base/containers/queue.h"
#include "base/files/file.h"
#include "base/files/memory_mapped_file.h"
#include "base/macros.h"
@@ -67,9 +68,16 @@ class CAPTURE_EXPORT FileVideoCaptureDevice : public VideoCaptureDevice {
const base::FilePath& file_path,
VideoCaptureFormat* video_format);
+ // Crops frame with respect to PTZ settings.
+ std::unique_ptr<uint8_t[]> CropPTZRegion(const uint8_t* frame,
+ size_t frame_buffer_size);
+
// Called on the |capture_thread_|.
void OnAllocateAndStart(const VideoCaptureParams& params,
std::unique_ptr<Client> client);
+ void OnGetPhotoState(GetPhotoStateCallback callback);
+ void OnSetPhotoOptions(mojom::PhotoSettingsPtr settings,
+ SetPhotoOptionsCallback callback);
void OnStopAndDeAllocate();
const uint8_t* GetNextFrame();
void OnCaptureTask();
@@ -86,6 +94,21 @@ class CAPTURE_EXPORT FileVideoCaptureDevice : public VideoCaptureDevice {
const base::FilePath file_path_;
std::unique_ptr<VideoFileParser> file_parser_;
VideoCaptureFormat capture_format_;
+
+ // The max zoom-able integer level that can be zoomed-in with respect to
+ // aspect ratio of original file.
+ int zoom_max_levels_;
+ // Numerator of file aspect ratio.
+ int aspect_ratio_numerator_;
+ // Denominator of file aspect ratio.
+ int aspect_ratio_denominator_;
+ // Current zoom values.
+ int zoom_;
+ // Current pan values.
+ int pan_;
+ // Current tilt values.
+ int tilt_;
+
// Target time for the next frame.
base::TimeTicks next_frame_time_;
// The system time when we receive the first frame.
diff --git a/chromium/media/capture/video/file_video_capture_device_factory.cc b/chromium/media/capture/video/file_video_capture_device_factory.cc
index 29fd7c77a0e..e318860c5cb 100644
--- a/chromium/media/capture/video/file_video_capture_device_factory.cc
+++ b/chromium/media/capture/video/file_video_capture_device_factory.cc
@@ -23,7 +23,6 @@ base::FilePath GetFilePathFromCommandLine() {
base::FilePath command_line_file_path =
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
switches::kUseFileForFakeVideoCapture);
- CHECK(!command_line_file_path.empty());
return command_line_file_path;
}
diff --git a/chromium/media/capture/video/file_video_capture_device_unittest.cc b/chromium/media/capture/video/file_video_capture_device_unittest.cc
index 5f15cb60a95..a92f5729fb1 100644
--- a/chromium/media/capture/video/file_video_capture_device_unittest.cc
+++ b/chromium/media/capture/video/file_video_capture_device_unittest.cc
@@ -9,6 +9,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/synchronization/waitable_event.h"
#include "base/test/task_environment.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/test_data_util.h"
@@ -25,16 +26,33 @@ namespace media {
namespace {
+const base::TimeDelta kWaitTimeoutSecs = base::TimeDelta::FromSeconds(3);
+
class MockImageCaptureClient {
public:
+ MockImageCaptureClient()
+ : wait_get_photo_state_(base::WaitableEvent::ResetPolicy::AUTOMATIC),
+ wait_set_photo_state_(base::WaitableEvent::ResetPolicy::AUTOMATIC) {}
+
// GMock doesn't support move-only arguments, so we use this forward method.
void DoOnGetPhotoState(mojom::PhotoStatePtr state) {
state_ = std::move(state);
+ wait_get_photo_state_.Signal();
+ }
+
+ const mojom::PhotoState* State() {
+ EXPECT_TRUE(wait_get_photo_state_.TimedWait(kWaitTimeoutSecs));
+ return state_.get();
}
- const mojom::PhotoState* state() { return state_.get(); }
+ void DoOnSetPhotoOptions(bool success) {
+ EXPECT_TRUE(success);
+ wait_set_photo_state_.Signal();
+ }
- MOCK_METHOD1(OnCorrectSetPhotoOptions, void(bool));
+ void WaitSetPhotoOptions() {
+ EXPECT_TRUE(wait_set_photo_state_.TimedWait(kWaitTimeoutSecs));
+ }
// GMock doesn't support move-only arguments, so we use this forward method.
void DoOnPhotoTaken(mojom::BlobPtr blob) {
@@ -44,7 +62,10 @@ class MockImageCaptureClient {
MOCK_METHOD0(OnCorrectPhotoTaken, void(void));
private:
+ base::WaitableEvent wait_get_photo_state_;
mojom::PhotoStatePtr state_;
+
+ base::WaitableEvent wait_set_photo_state_;
};
} // namespace
@@ -82,6 +103,22 @@ class FileVideoCaptureDeviceTest : public ::testing::Test {
run_loop_->Run();
}
+ void SetPhotoOptions(double pan, double tilt, double zoom) {
+ mojom::PhotoSettingsPtr photo_settings = mojom::PhotoSettings::New();
+ photo_settings->has_pan = photo_settings->has_tilt =
+ photo_settings->has_zoom = true;
+ photo_settings->pan = pan;
+ photo_settings->tilt = tilt;
+ photo_settings->zoom = zoom;
+
+ VideoCaptureDevice::SetPhotoOptionsCallback scoped_set_callback =
+ base::BindOnce(&MockImageCaptureClient::DoOnSetPhotoOptions,
+ base::Unretained(&image_capture_client_));
+ device_->SetPhotoOptions(std::move(photo_settings),
+ std::move(scoped_set_callback));
+ image_capture_client_.WaitSetPhotoOptions();
+ }
+
std::unique_ptr<NiceMockVideoCaptureDeviceClient> client_;
MockImageCaptureClient image_capture_client_;
std::unique_ptr<VideoCaptureDevice> device_;
@@ -97,21 +134,41 @@ TEST_F(FileVideoCaptureDeviceTest, GetPhotoState) {
device_->GetPhotoState(std::move(scoped_get_callback));
- const mojom::PhotoState* state = image_capture_client_.state();
+ const mojom::PhotoState* state = image_capture_client_.State();
EXPECT_TRUE(state);
+
+ // From gcd of "bear.mjpeg" width=320, height=192.
+ const int kZoomMaxLevels = 64;
+
+ const mojom::RangePtr& pan = state->pan;
+ EXPECT_TRUE(pan);
+ EXPECT_EQ(pan->current, 0);
+ EXPECT_EQ(pan->max, kZoomMaxLevels - 1);
+ EXPECT_EQ(pan->min, 0);
+ EXPECT_EQ(pan->step, 1);
+
+ const mojom::RangePtr& tilt = state->tilt;
+ EXPECT_TRUE(tilt);
+ EXPECT_EQ(tilt->current, kZoomMaxLevels - 1);
+ EXPECT_EQ(tilt->max, kZoomMaxLevels - 1);
+ EXPECT_EQ(tilt->min, 0);
+ EXPECT_EQ(tilt->step, 1);
+
+ const mojom::RangePtr& zoom = state->zoom;
+ EXPECT_TRUE(zoom);
+ EXPECT_EQ(zoom->current, 0);
+ EXPECT_EQ(zoom->max, kZoomMaxLevels - 1);
+ EXPECT_EQ(zoom->min, 0);
+ EXPECT_EQ(zoom->step, 1);
}
TEST_F(FileVideoCaptureDeviceTest, SetPhotoOptions) {
- mojom::PhotoSettingsPtr photo_settings = mojom::PhotoSettings::New();
- VideoCaptureDevice::SetPhotoOptionsCallback scoped_set_callback =
- base::BindOnce(&MockImageCaptureClient::OnCorrectSetPhotoOptions,
- base::Unretained(&image_capture_client_));
- EXPECT_CALL(image_capture_client_, OnCorrectSetPhotoOptions(true)).Times(1);
- device_->SetPhotoOptions(std::move(photo_settings),
- std::move(scoped_set_callback));
+ SetPhotoOptions(1.0, 1.0, 1.0);
}
TEST_F(FileVideoCaptureDeviceTest, TakePhoto) {
+ SetPhotoOptions(1.0, 1.0, 1.0);
+
VideoCaptureDevice::TakePhotoCallback scoped_callback =
base::BindOnce(&MockImageCaptureClient::DoOnPhotoTaken,
base::Unretained(&image_capture_client_));
diff --git a/chromium/media/capture/video/fuchsia/video_capture_device_factory_fuchsia.cc b/chromium/media/capture/video/fuchsia/video_capture_device_factory_fuchsia.cc
index 1c42b270512..e87c3c8dbb3 100644
--- a/chromium/media/capture/video/fuchsia/video_capture_device_factory_fuchsia.cc
+++ b/chromium/media/capture/video/fuchsia/video_capture_device_factory_fuchsia.cc
@@ -99,8 +99,8 @@ class VideoCaptureDeviceFactoryFuchsia::DeviceConfigFetcher {
uint64_t device_id_;
fuchsia::camera3::DevicePtr device_;
- base::Optional<std::string> description_;
- base::Optional<VideoCaptureFormats> formats_;
+ absl::optional<std::string> description_;
+ absl::optional<VideoCaptureFormats> formats_;
base::OnceClosure on_fetched_callback_;
};
@@ -178,7 +178,7 @@ void VideoCaptureDeviceFactoryFuchsia::OnDeviceWatcherDisconnected(
// Clear the list of devices, so we don't report any camera devices while
// DeviceWatcher is disconnected. We will try connecting DeviceWatcher again
// when GetDevicesInfo() is called.
- devices_ = base::nullopt;
+ devices_ = absl::nullopt;
num_pending_device_info_requests_ = 0;
MaybeResolvePendingDeviceInfoCallbacks();
diff --git a/chromium/media/capture/video/fuchsia/video_capture_device_factory_fuchsia.h b/chromium/media/capture/video/fuchsia/video_capture_device_factory_fuchsia.h
index 4afb3228c65..eeafa468882 100644
--- a/chromium/media/capture/video/fuchsia/video_capture_device_factory_fuchsia.h
+++ b/chromium/media/capture/video/fuchsia/video_capture_device_factory_fuchsia.h
@@ -10,8 +10,8 @@
#include <map>
#include "base/containers/small_map.h"
-#include "base/optional.h"
#include "media/capture/video/video_capture_device_factory.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -52,7 +52,7 @@ class CAPTURE_EXPORT VideoCaptureDeviceFactoryFuchsia
// Current list of devices. Set to nullopt if the list hasn't been received
// yet.
- base::Optional<
+ absl::optional<
base::small_map<std::map<uint64_t, std::unique_ptr<DeviceConfigFetcher>>>>
devices_;
diff --git a/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.cc b/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.cc
index 2692ac2a3ca..33159564011 100644
--- a/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.cc
+++ b/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.cc
@@ -179,9 +179,8 @@ void VideoCaptureDeviceFuchsia::OnStreamError(zx_status_t status) {
void VideoCaptureDeviceFuchsia::DisconnectStream() {
stream_.Unbind();
- buffer_collection_creator_.reset();
buffer_collection_.reset();
- buffer_reader_.reset();
+ buffers_.clear();
frame_size_.reset();
}
@@ -246,70 +245,55 @@ void VideoCaptureDeviceFuchsia::InitializeBufferCollection(
// Drop old buffers.
buffer_collection_.reset();
- buffer_reader_.reset();
+ buffers_.clear();
// Initialize the new collection.
fuchsia::sysmem::BufferCollectionTokenPtr token;
token.Bind(std::move(token_handle));
- buffer_collection_creator_ =
- sysmem_allocator_.MakeBufferPoolCreatorFromToken(std::move(token));
// Request just one buffer in collection constraints: each frame is copied as
// soon as it's received.
const size_t kMaxUsedOutputFrames = 1;
- // Sysmem calculates buffer size based on image constraints, so it doesn't
- // need to specified explicitly.
- fuchsia::sysmem::BufferCollectionConstraints constraints =
- SysmemBufferReader::GetRecommendedConstraints(
- kMaxUsedOutputFrames,
- /*min_buffer_size=*/base::nullopt);
// This is not an actual device driver, so the priority should be > 1. It's
// also not a high-level system, so the name should be < 100.
constexpr uint32_t kNamePriority = 10;
- buffer_collection_creator_->SetName(kNamePriority,
- "CrVideoCaptureDeviceFuchsia");
- buffer_collection_creator_->Create(
- std::move(constraints),
- base::BindOnce(&VideoCaptureDeviceFuchsia::OnBufferCollectionCreated,
- base::Unretained(this)));
-}
-
-void VideoCaptureDeviceFuchsia::OnBufferCollectionCreated(
- std::unique_ptr<SysmemBufferPool> collection) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- // Buffer collection allocation has failed. This case is not treated as an
- // error because the camera may create a new collection.
- if (!collection)
- return;
- buffer_collection_ = std::move(collection);
- buffer_collection_->CreateReader(
- base::BindOnce(&VideoCaptureDeviceFuchsia::OnBufferReaderCreated,
- base::Unretained(this)));
+ // Sysmem calculates buffer size based on image constraints, so it doesn't
+ // need to be specified explicitly.
+ fuchsia::sysmem::BufferCollectionConstraints constraints =
+ VmoBuffer::GetRecommendedConstraints(kMaxUsedOutputFrames,
+ /*min_buffer_size=*/absl::nullopt,
+ /*writable=*/false);
+ buffer_collection_ = sysmem_allocator_.BindSharedCollection(std::move(token));
+ buffer_collection_->Initialize(std::move(constraints), "CrVideoCaptureDevice",
+ kNamePriority);
+ buffer_collection_->AcquireBuffers(base::BindOnce(
+ &VideoCaptureDeviceFuchsia::OnBuffersAcquired, base::Unretained(this)));
}
-void VideoCaptureDeviceFuchsia::OnBufferReaderCreated(
- std::unique_ptr<SysmemBufferReader> reader) {
+void VideoCaptureDeviceFuchsia::OnBuffersAcquired(
+ std::vector<VmoBuffer> buffers,
+ const fuchsia::sysmem::SingleBufferSettings& buffer_settings) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Buffer collection allocation has failed. This case is not treated as an
// error because the camera may create a new collection.
- if (!reader) {
+ if (buffers.empty()) {
buffer_collection_.reset();
return;
}
- buffer_reader_ = std::move(reader);
- if (!buffer_reader_->buffer_settings().has_image_format_constraints) {
+ buffers_ = std::move(buffers);
+
+ if (!buffer_settings.has_image_format_constraints) {
OnError(FROM_HERE, VideoCaptureError::kFuchsiaSysmemDidNotSetImageFormat,
"Sysmem created buffer without image format constraints");
return;
}
- auto pixel_format = buffer_reader_->buffer_settings()
- .image_format_constraints.pixel_format.type;
+ auto pixel_format =
+ buffer_settings.image_format_constraints.pixel_format.type;
if (!IsSupportedPixelFormat(pixel_format)) {
OnError(FROM_HERE, VideoCaptureError::kFuchsiaUnsupportedPixelFormat,
base::StringPrintf("Unsupported video frame format: %d",
@@ -317,6 +301,8 @@ void VideoCaptureDeviceFuchsia::OnBufferReaderCreated(
return;
}
+ buffers_format_ = buffer_settings.image_format_constraints;
+
if (!started_) {
started_ = true;
client_->OnStarted();
@@ -336,38 +322,35 @@ void VideoCaptureDeviceFuchsia::ProcessNewFrame(
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(client_);
- if (!buffer_reader_) {
+ if (buffers_.empty()) {
DLOG(WARNING) << "Dropping frame received before sysmem collection has "
"been initialized.";
return;
}
size_t index = frame_info.buffer_index;
- if (index >= buffer_reader_->num_buffers()) {
+ if (index >= buffers_.size()) {
OnError(FROM_HERE, VideoCaptureError::kFuchsiaSysmemInvalidBufferIndex,
base::StringPrintf("Received frame with invalid buffer_index=%zu",
index));
return;
}
- const fuchsia::sysmem::ImageFormatConstraints& sysmem_buffer_format =
- buffer_reader_->buffer_settings().image_format_constraints;
-
// Calculate coded frame dimensions for the buffer collection based on the
// sysmem collection constraints. This logic should match
// LogicalBufferCollection::Allocate() in sysmem.
size_t src_coded_width =
- RoundUp(std::max(sysmem_buffer_format.min_coded_width,
- sysmem_buffer_format.required_max_coded_width),
- sysmem_buffer_format.coded_width_divisor);
+ RoundUp(std::max(buffers_format_.min_coded_width,
+ buffers_format_.required_max_coded_width),
+ buffers_format_.coded_width_divisor);
size_t src_coded_height =
- RoundUp(std::max(sysmem_buffer_format.min_coded_height,
- sysmem_buffer_format.required_max_coded_height),
- sysmem_buffer_format.coded_height_divisor);
- size_t src_stride = RoundUp(
- std::max(static_cast<size_t>(sysmem_buffer_format.min_bytes_per_row),
- src_coded_width),
- sysmem_buffer_format.bytes_per_row_divisor);
+ RoundUp(std::max(buffers_format_.min_coded_height,
+ buffers_format_.required_max_coded_height),
+ buffers_format_.coded_height_divisor);
+ size_t src_stride =
+ RoundUp(std::max(static_cast<size_t>(buffers_format_.min_bytes_per_row),
+ src_coded_width),
+ buffers_format_.bytes_per_row_divisor);
gfx::Size visible_size =
frame_size_.value_or(gfx::Size(src_coded_width, src_coded_height));
gfx::Size nonrotated_output_size((visible_size.width() + 1) & ~1,
@@ -401,7 +384,7 @@ void VideoCaptureDeviceFuchsia::ProcessNewFrame(
return;
}
- auto src_span = buffer_reader_->GetMappingForBuffer(index);
+ auto src_span = buffers_[index].GetMemory();
if (src_span.empty()) {
OnError(FROM_HERE, VideoCaptureError::kFuchsiaFailedToMapSysmemBuffer,
"Failed to map buffers allocated by sysmem");
@@ -440,9 +423,7 @@ void VideoCaptureDeviceFuchsia::ProcessNewFrame(
if (flip_y)
flipped_src_height = -flipped_src_height;
- auto four_cc =
- GetFourccForPixelFormat(buffer_reader_->buffer_settings()
- .image_format_constraints.pixel_format.type);
+ auto four_cc = GetFourccForPixelFormat(buffers_format_.pixel_format.type);
libyuv::ConvertToI420(src_span.data(), src_span.size(), dst_y, dst_stride_y,
dst_u, dst_stride_u, dst_v, dst_stride_v,
diff --git a/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.h b/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.h
index 1d2e40ce55a..2df3beefda2 100644
--- a/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.h
+++ b/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.h
@@ -9,12 +9,12 @@
#include <memory>
-#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "media/capture/video/video_capture_device.h"
-#include "media/fuchsia/common/sysmem_buffer_pool.h"
-#include "media/fuchsia/common/sysmem_buffer_reader.h"
+#include "media/fuchsia/common/sysmem_client.h"
+#include "media/fuchsia/common/vmo_buffer.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -77,11 +77,10 @@ class CAPTURE_EXPORT VideoCaptureDeviceFuchsia : public VideoCaptureDevice {
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
token_handle);
- // Callback for SysmemBufferPool::Creator.
- void OnBufferCollectionCreated(std::unique_ptr<SysmemBufferPool> collection);
-
- // Callback for SysmemBufferPool::CreateReader().
- void OnBufferReaderCreated(std::unique_ptr<SysmemBufferReader> reader);
+ // Callback for SysmemCollectionClient::AcquireBuffers().
+ void OnBuffersAcquired(
+ std::vector<VmoBuffer> buffers,
+ const fuchsia::sysmem::SingleBufferSettings& buffer_settings);
// Calls Stream::GetNextFrame() in a loop to receive incoming frames.
void ReceiveNextFrame();
@@ -95,12 +94,12 @@ class CAPTURE_EXPORT VideoCaptureDeviceFuchsia : public VideoCaptureDevice {
std::unique_ptr<Client> client_;
- media::BufferAllocator sysmem_allocator_;
- std::unique_ptr<SysmemBufferPool::Creator> buffer_collection_creator_;
- std::unique_ptr<SysmemBufferPool> buffer_collection_;
- std::unique_ptr<SysmemBufferReader> buffer_reader_;
+ SysmemAllocatorClient sysmem_allocator_;
+ std::unique_ptr<SysmemCollectionClient> buffer_collection_;
+ std::vector<VmoBuffer> buffers_;
+ fuchsia::sysmem::ImageFormatConstraints buffers_format_;
- base::Optional<gfx::Size> frame_size_;
+ absl::optional<gfx::Size> frame_size_;
fuchsia::camera3::Orientation orientation_ =
fuchsia::camera3::Orientation::UP;
diff --git a/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc b/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc
index 321f11fe695..f6c8312867b 100644
--- a/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc
+++ b/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc
@@ -191,7 +191,7 @@ class TestVideoCaptureClient : public VideoCaptureDevice::Client {
bool started_ = false;
std::vector<ReceivedFrame> received_frames_;
- base::Optional<base::RunLoop> wait_frame_run_loop_;
+ absl::optional<base::RunLoop> wait_frame_run_loop_;
};
} // namespace
diff --git a/chromium/media/capture/video/linux/camera_config_chromeos.cc b/chromium/media/capture/video/linux/camera_config_chromeos.cc
deleted file mode 100644
index c2dbdd383ec..00000000000
--- a/chromium/media/capture/video/linux/camera_config_chromeos.cc
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright 2016 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 "media/capture/video/linux/camera_config_chromeos.h"
-
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-
-namespace media {
-
-namespace {
-
-// The value for each field in the enum matches the value in
-// /etc/camera/camera_characteristics.conf.
-enum LensFacing { FRONT = 0, BACK = 1 };
-
-bool ParseCameraId(const base::StringPiece& sub_key, int* camera_id) {
- const base::StringPiece camera_id_prefix = "camera";
- if (!base::StartsWith(sub_key, camera_id_prefix))
- return false;
- return base::StringToInt(sub_key.substr(camera_id_prefix.size()), camera_id);
-}
-}
-
-// /etc/camera/camera_characteristics.conf contains camera information which
-// driver cannot provide.
-static const char kCameraCharacteristicsConfigFile[] =
- "/etc/camera/camera_characteristics.conf";
-static const char kLensFacing[] = "lens_facing";
-static const char kSensorOrientation[] = "sensor_orientation";
-static const char kUsbVidPid[] = "usb_vid_pid";
-static const char kUsbPath[] = "usb_path";
-static const int kOrientationDefault = 0;
-static const int kCameraIdNotFound = -1;
-
-CameraConfigChromeOS::CameraConfigChromeOS() {
- InitializeDeviceInfo(std::string(kCameraCharacteristicsConfigFile));
-}
-
-CameraConfigChromeOS::CameraConfigChromeOS(
- const std::string& config_file_path) {
- InitializeDeviceInfo(config_file_path);
-}
-
-CameraConfigChromeOS::~CameraConfigChromeOS() = default;
-
-VideoFacingMode CameraConfigChromeOS::GetCameraFacing(
- const std::string& device_id,
- const std::string& model_id) const {
- int camera_id = GetCameraId(device_id, model_id);
- const auto& camera_id_to_facing_const = camera_id_to_facing_;
- const auto facing_found = camera_id_to_facing_const.find(camera_id);
- if (facing_found == camera_id_to_facing_const.end()) {
- DLOG(ERROR) << "Can't find lens_facing of camera ID " << camera_id
- << " in config file";
- return kLensFacingDefault;
- }
- return facing_found->second;
-}
-
-int CameraConfigChromeOS::GetOrientation(const std::string& device_id,
- const std::string& model_id) const {
- int camera_id = GetCameraId(device_id, model_id);
- const auto& camera_id_to_orientation = camera_id_to_orientation_;
- const auto orientation_found = camera_id_to_orientation.find(camera_id);
- if (orientation_found == camera_id_to_orientation.end()) {
- DLOG(ERROR) << "Can't find sensor_orientation of camera ID " << camera_id
- << " in config file";
- return kOrientationDefault;
- }
- return orientation_found->second;
-}
-
-int CameraConfigChromeOS::GetCameraId(const std::string& device_id,
- const std::string& model_id) const {
- std::string usb_id = GetUsbId(device_id);
- const auto& usb_id_to_camera_id = usb_id_to_camera_id_;
- const auto& model_id_to_camera_id = model_id_to_camera_id_;
-
- const auto usb_id_found = usb_id_to_camera_id.find(usb_id);
- if (usb_id_found != usb_id_to_camera_id.end())
- return usb_id_found->second;
-
- // Can't find Usb ID. Fall back to use |model_id|.
- const auto model_id_found = model_id_to_camera_id.find(model_id);
- if (model_id_found != model_id_to_camera_id.end())
- return model_id_found->second;
-
- DLOG(ERROR) << "Can't find model ID in config file: " << model_id;
- return kCameraIdNotFound;
-}
-
-std::string CameraConfigChromeOS::GetUsbId(const std::string& device_id) const {
- // |device_id| is of the form "/dev/video2". We want to retrieve "video2"
- // into |file_name|.
- const std::string device_dir = "/dev/";
- if (!base::StartsWith(device_id, device_dir)) {
- DLOG(ERROR) << "device_id is invalid: " << device_id;
- return std::string();
- }
- const std::string file_name = device_id.substr(device_dir.length());
-
- // Usb ID can be obtained by "readlink /sys/class/video4linux/video2/device".
- const std::string symlink =
- base::StringPrintf("/sys/class/video4linux/%s/device", file_name.c_str());
- base::FilePath symlinkTarget;
- if (!base::ReadSymbolicLink(base::FilePath(symlink), &symlinkTarget)) {
- DPLOG(ERROR) << "Failed to readlink: " << symlink;
- return std::string();
- }
-
- // |symlinkTarget| is of the format "../../../A-B:C.D". Remove the path
- // prefix.
- base::StringPiece usb_part = symlinkTarget.BaseName().value();
-
- // |usb_part| is of the format "A-B:C.D" or "A-B.C:D". We want everything
- // before ":".
- std::vector<base::StringPiece> usb_id_pieces = base::SplitStringPiece(
- usb_part, ":", base::WhitespaceHandling::TRIM_WHITESPACE,
- base::SplitResult::SPLIT_WANT_ALL);
-
- if (usb_id_pieces.empty()) {
- DLOG(ERROR) << "Error after split: " << usb_part;
- return std::string();
- }
- return usb_id_pieces[0].as_string();
-}
-
-void CameraConfigChromeOS::InitializeDeviceInfo(
- const std::string& config_file_path) {
- const base::FilePath path(config_file_path);
- std::string content;
- if (!base::ReadFileToString(path, &content)) {
- DPLOG(ERROR) << "ReadFileToString fails";
- return;
- }
- const std::vector<base::StringPiece> lines = base::SplitStringPiece(
- content, "\n", base::WhitespaceHandling::TRIM_WHITESPACE,
- base::SplitResult::SPLIT_WANT_NONEMPTY);
-
- for (const base::StringPiece& line : lines) {
- // Ignore the comments that starts with "#".
- if (base::StartsWith(line, "#"))
- continue;
- const std::vector<base::StringPiece> key_value = base::SplitStringPiece(
- line, "=", base::WhitespaceHandling::TRIM_WHITESPACE,
- base::SplitResult::SPLIT_WANT_ALL);
- if (key_value.size() != 2) {
- DLOG(ERROR) << "Invalid line in config file: " << line;
- continue;
- }
- const auto& key = key_value[0];
- const auto& value = key_value[1];
- const std::vector<base::StringPiece> sub_keys = base::SplitStringPiece(
- key, ".", base::WhitespaceHandling::TRIM_WHITESPACE,
- base::SplitResult::SPLIT_WANT_ALL);
-
- if (sub_keys.size() < 1) {
- DLOG(ERROR) << "No valid sub key exists. Line format is invalid: "
- << line;
- continue;
- }
- int camera_id = 0;
- if (!ParseCameraId(sub_keys[0], &camera_id)) {
- DLOG(ERROR) << "Invalid sub key for camera id: " << sub_keys[0];
- continue;
- }
-
- if (sub_keys.size() == 2 && sub_keys[1] == kLensFacing) {
- int lens_facing = -1;
- if (!base::StringToInt(value, &lens_facing)) {
- DLOG(ERROR) << "Invalid value for lens_facing: " << value;
- continue;
- }
- switch (lens_facing) {
- case LensFacing::FRONT:
- camera_id_to_facing_[camera_id] =
- VideoFacingMode::MEDIA_VIDEO_FACING_USER;
- break;
- case LensFacing::BACK:
- camera_id_to_facing_[camera_id] =
- VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT;
- break;
- default:
- DLOG(ERROR) << "Invalid value for lens_facing: " << lens_facing;
- continue;
- }
- } else if (sub_keys.size() == 2 && sub_keys[1] == kSensorOrientation) {
- int orientation = 0;
- if (!base::StringToInt(value, &orientation)) {
- DLOG(ERROR) << "Invalid value for sensor_orientation: " << value;
- continue;
- }
- camera_id_to_orientation_[camera_id] = orientation;
- } else if (sub_keys.size() == 3 && sub_keys[2] == kUsbVidPid) {
- if (value.empty()) {
- DLOG(ERROR) << "model_id is empty";
- continue;
- }
- std::string model_id = value.as_string();
- std::transform(model_id.begin(), model_id.end(), model_id.begin(),
- ::tolower);
- model_id_to_camera_id_[model_id] = camera_id;
- } else if (sub_keys.size() == 3 && sub_keys[2] == kUsbPath) {
- if (value.empty()) {
- DLOG(ERROR) << "usb_path is empty";
- continue;
- }
- usb_id_to_camera_id_[value.as_string()] = camera_id;
- }
- // Ignore unknown or unutilized attributes.
- }
-}
-
-} // namespace media
diff --git a/chromium/media/capture/video/linux/camera_config_chromeos.h b/chromium/media/capture/video/linux/camera_config_chromeos.h
deleted file mode 100644
index 3191eb0f22d..00000000000
--- a/chromium/media/capture/video/linux/camera_config_chromeos.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2016 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 MEDIA_CAPTURE_VIDEO_LINUX_CAMERA_CONFIG_CHROMEOS_H_
-#define MEDIA_CAPTURE_VIDEO_LINUX_CAMERA_CONFIG_CHROMEOS_H_
-
-#include <stddef.h>
-
-#include <string>
-#include <unordered_map>
-
-#include "base/strings/string_piece.h"
-#include "media/base/video_facing.h"
-#include "media/capture/capture_export.h"
-
-namespace media {
-
-// CameraConfigChromeOS reads the file /etc/camera/camera_characteristics.conf
-// and populates |camera_id_to_facing_|, |usb_id_to_camera_id_| and
-// |model_id_to_camera_id_|.
-//
-// Each line in the config file can be:
-// 1. Empty line
-// 2. Line starts with '#': comments
-// 3. Line follows the format:
-// camera[camera_id].[root_level_attribute]=[value] OR
-// camera[camera_id].module[module_id].[module_level_attribute]=[value]
-//
-// There are several assumptions of the config file:
-// 1. One camera ID has exactly one lens_facing attribute, at root level.
-// 2. usb_path is specified at module level. usb_path may not present at all,
-// but if it presents, the same usb_path does not appear accross different
-// camera IDs.
-// 3. usb_vid_pid is specified at module level. If usb_path does not present,
-// each module needs to have one unique usb_vid_pid.
-//
-// Example of the config file:
-// camera0.lens_facing=0
-// camera0.sensor_orientation=0
-// camera0.module0.usb_vid_pid=0123:4567
-// camera0.module0.horizontal_view_angle=68.4
-// camera0.module0.lens_info_available_focal_lengths=1.64
-// camera0.module0.lens_info_minimum_focus_distance=0.22
-// camera0.module0.lens_info_optimal_focus_distance=0.5
-// camera0.module0.vertical_view_angle=41.6
-// camera0.module1.usb_vid_pid=89ab:cdef
-// camera0.module1.lens_info_available_focal_lengths=1.69,2
-// camera1.lens_facing=1
-// camera1.sensor_orientation=180
-class CAPTURE_EXPORT CameraConfigChromeOS {
- public:
- CameraConfigChromeOS();
- CAPTURE_EXPORT CameraConfigChromeOS(const std::string& config_file_path);
- CAPTURE_EXPORT ~CameraConfigChromeOS();
-
- // Get camera facing by specifying USB vid and pid and device path. |model_id|
- // should be formatted as "vid:pid". |device_id| is something like
- // "/dev/video2". It first tries to match usb path, obtained from |device_id|.
- // If fails, |model_id| is then used.
- CAPTURE_EXPORT VideoFacingMode
- GetCameraFacing(const std::string& device_id,
- const std::string& model_id) const;
- int GetOrientation(const std::string& device_id,
- const std::string& model_id) const;
-
- static const VideoFacingMode kLensFacingDefault =
- VideoFacingMode::MEDIA_VIDEO_FACING_NONE;
-
- private:
- std::string GetUsbId(const std::string& device_id) const;
- int GetCameraId(const std::string& device_id,
- const std::string& model_id) const;
- // Read file content and populate |camera_id_to_facing_|,
- // |usb_id_to_camera_id_| and |model_id_to_camera_id_|.
- void InitializeDeviceInfo(const std::string& config_file_path);
-
- std::unordered_map<int, VideoFacingMode> camera_id_to_facing_;
- std::unordered_map<int, int> camera_id_to_orientation_;
- std::unordered_map<std::string, int> usb_id_to_camera_id_;
- std::unordered_map<std::string, int> model_id_to_camera_id_;
-};
-
-} // namespace media
-
-#endif // MEDIA_CAPTURE_VIDEO_LINUX_CAMERA_CONFIG_CHROMEOS_H_
diff --git a/chromium/media/capture/video/linux/camera_config_chromeos_unittest.cc b/chromium/media/capture/video/linux/camera_config_chromeos_unittest.cc
deleted file mode 100644
index 9fa1d01141f..00000000000
--- a/chromium/media/capture/video/linux/camera_config_chromeos_unittest.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2016 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 <string>
-
-#include "base/files/file.h"
-#include "base/files/file_util.h"
-#include "media/capture/video/linux/camera_config_chromeos.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace media {
-
-namespace {
-
-const char kConfigFileContent[] =
- "camera0.lens_facing=1\ncamera0.sensor_orientation=90\ncamera0.module0.usb_"
- "vid_pid=04f2:b53a\n";
-}
-
-TEST(CameraConfigChromeOSTest, ParseSuccessfully) {
- base::FilePath conf_path;
- ASSERT_TRUE(base::CreateTemporaryFile(&conf_path));
- base::WriteFile(conf_path, kConfigFileContent, sizeof(kConfigFileContent));
-
- CameraConfigChromeOS camera_config(conf_path.value());
- EXPECT_EQ(VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT,
- camera_config.GetCameraFacing(std::string("/dev/video2"),
- std::string("04f2:b53a")));
- EXPECT_EQ(90, camera_config.GetOrientation(std::string("/dev/video2"),
- std::string("04f2:b53a")));
-}
-
-TEST(CameraConfigChromeOSTest, ConfigFileNotExist) {
- CameraConfigChromeOS camera_config(std::string("file_not_exist"));
- EXPECT_EQ(VideoFacingMode::MEDIA_VIDEO_FACING_NONE,
- camera_config.GetCameraFacing(std::string("/dev/video2"),
- std::string("04f2:b53a")));
- EXPECT_EQ(0, camera_config.GetOrientation(std::string("/dev/video2"),
- std::string("04f2:b53a")));
-}
-
-} // namespace media
diff --git a/chromium/media/capture/video/linux/fake_device_provider.cc b/chromium/media/capture/video/linux/fake_device_provider.cc
index a8c79723c49..581c260a399 100644
--- a/chromium/media/capture/video/linux/fake_device_provider.cc
+++ b/chromium/media/capture/video/linux/fake_device_provider.cc
@@ -52,15 +52,4 @@ std::string FakeDeviceProvider::GetDeviceDisplayName(
return iter->display_name();
}
-VideoFacingMode FakeDeviceProvider::GetCameraFacing(
- const std::string& device_id,
- const std::string& model_id) {
- return MEDIA_VIDEO_FACING_NONE;
-}
-
-int FakeDeviceProvider::GetOrientation(const std::string& device_id,
- const std::string& model_id) {
- return 0;
-}
-
} // namespace media
diff --git a/chromium/media/capture/video/linux/fake_device_provider.h b/chromium/media/capture/video/linux/fake_device_provider.h
index 15b95f59042..a98648eb356 100644
--- a/chromium/media/capture/video/linux/fake_device_provider.h
+++ b/chromium/media/capture/video/linux/fake_device_provider.h
@@ -25,10 +25,6 @@ class FakeDeviceProvider
void GetDeviceIds(std::vector<std::string>* target_container) override;
std::string GetDeviceModelId(const std::string& device_id) override;
std::string GetDeviceDisplayName(const std::string& device_id) override;
- VideoFacingMode GetCameraFacing(const std::string& device_id,
- const std::string& model_id) override;
- int GetOrientation(const std::string& device_id,
- const std::string& model_id) override;
private:
std::vector<VideoCaptureDeviceDescriptor> descriptors_;
diff --git a/chromium/media/capture/video/linux/fake_v4l2_impl.cc b/chromium/media/capture/video/linux/fake_v4l2_impl.cc
index 4a976815d00..09647474bed 100644
--- a/chromium/media/capture/video/linux/fake_v4l2_impl.cc
+++ b/chromium/media/capture/video/linux/fake_v4l2_impl.cc
@@ -380,10 +380,16 @@ FakeV4L2Impl::~FakeV4L2Impl() = default;
void FakeV4L2Impl::AddDevice(const std::string& device_name,
const FakeV4L2DeviceConfig& config) {
+ base::AutoLock lock(lock_);
device_configs_.emplace(device_name, config);
}
int FakeV4L2Impl::open(const char* device_name, int flags) {
+ if (!device_name)
+ return kInvalidId;
+
+ base::AutoLock lock(lock_);
+
std::string device_name_as_string(device_name);
auto device_configs_iter = device_configs_.find(device_name_as_string);
if (device_configs_iter == device_configs_.end())
@@ -403,6 +409,7 @@ int FakeV4L2Impl::open(const char* device_name, int flags) {
}
int FakeV4L2Impl::close(int fd) {
+ base::AutoLock lock(lock_);
auto device_iter = opened_devices_.find(fd);
if (device_iter == opened_devices_.end())
return kErrorReturnValue;
@@ -412,6 +419,7 @@ int FakeV4L2Impl::close(int fd) {
}
int FakeV4L2Impl::ioctl(int fd, int request, void* argp) {
+ base::AutoLock lock(lock_);
auto device_iter = opened_devices_.find(fd);
if (device_iter == opened_devices_.end())
return EBADF;
@@ -518,6 +526,7 @@ void* FakeV4L2Impl::mmap(void* /*start*/,
int flags,
int fd,
off_t offset) {
+ base::AutoLock lock(lock_);
if (flags & MAP_FIXED) {
errno = EINVAL;
return MAP_FAILED;
@@ -543,10 +552,12 @@ void* FakeV4L2Impl::mmap(void* /*start*/,
}
int FakeV4L2Impl::munmap(void* start, size_t length) {
+ base::AutoLock lock(lock_);
return kSuccessReturnValue;
}
int FakeV4L2Impl::poll(struct pollfd* ufds, unsigned int nfds, int timeout) {
+ base::AutoLock lock(lock_);
if (nfds != 1) {
// We only support polling of a single device.
errno = EINVAL;
diff --git a/chromium/media/capture/video/linux/fake_v4l2_impl.h b/chromium/media/capture/video/linux/fake_v4l2_impl.h
index 0a035a97dd8..ae7167f9516 100644
--- a/chromium/media/capture/video/linux/fake_v4l2_impl.h
+++ b/chromium/media/capture/video/linux/fake_v4l2_impl.h
@@ -10,6 +10,7 @@
#include <linux/videodev2.h>
+#include "base/synchronization/lock.h"
#include "media/capture/capture_export.h"
#include "media/capture/video/linux/v4l2_capture_device.h"
#include "media/capture/video/video_capture_device_descriptor.h"
@@ -52,11 +53,13 @@ class CAPTURE_EXPORT FakeV4L2Impl : public V4L2CaptureDevice {
private:
class OpenedDevice;
- int next_id_to_return_from_open_;
- std::map<std::string, FakeV4L2DeviceConfig> device_configs_;
- std::map<std::string, int> device_name_to_open_id_map_;
+ base::Lock lock_;
+
+ int next_id_to_return_from_open_ GUARDED_BY(lock_);
+ std::map<std::string, FakeV4L2DeviceConfig> device_configs_ GUARDED_BY(lock_);
+ std::map<std::string, int> device_name_to_open_id_map_ GUARDED_BY(lock_);
std::map<int /*value returned by open()*/, std::unique_ptr<OpenedDevice>>
- opened_devices_;
+ opened_devices_ GUARDED_BY(lock_);
};
} // namespace media
diff --git a/chromium/media/capture/video/linux/v4l2_capture_delegate_unittest.cc b/chromium/media/capture/video/linux/v4l2_capture_delegate_unittest.cc
index 88564367bee..710f5adf4ab 100644
--- a/chromium/media/capture/video/linux/v4l2_capture_delegate_unittest.cc
+++ b/chromium/media/capture/video/linux/v4l2_capture_delegate_unittest.cc
@@ -194,11 +194,12 @@ class V4L2CaptureDelegateTest : public ::testing::Test {
} // anonymous namespace
// Fails on Linux, see crbug/732355
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if defined(OS_LINUX)
#define MAYBE_CreateAndDestroyAndVerifyControls \
DISABLED_CreateAndDestroyAndVerifyControls
#else
-#define MAYBE_CrashingTest CreateAndDestroyAndVerifyControls
+#define MAYBE_CreateAndDestroyAndVerifyControls \
+ CreateAndDestroyAndVerifyControls
#endif
TEST_F(V4L2CaptureDelegateTest, MAYBE_CreateAndDestroyAndVerifyControls) {
// Check that there is at least a video device, otherwise bail.
diff --git a/chromium/media/capture/video/linux/video_capture_device_chromeos.cc b/chromium/media/capture/video/linux/video_capture_device_chromeos.cc
deleted file mode 100644
index 8fd1829805a..00000000000
--- a/chromium/media/capture/video/linux/video_capture_device_chromeos.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2014 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 "media/capture/video/linux/video_capture_device_chromeos.h"
-
-#include <stdint.h>
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "ui/display/display.h"
-#include "ui/display/display_observer.h"
-#include "ui/display/screen.h"
-
-namespace media {
-
-VideoCaptureDeviceChromeOS::VideoCaptureDeviceChromeOS(
- const ChromeOSDeviceCameraConfig& camera_config,
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
- scoped_refptr<V4L2CaptureDevice> v4l2,
- const VideoCaptureDeviceDescriptor& device_descriptor)
- : VideoCaptureDeviceLinux(std::move(v4l2), device_descriptor),
- camera_config_(camera_config),
- screen_observer_delegate_(
- ScreenObserverDelegate::Create(this, ui_task_runner)) {}
-
-VideoCaptureDeviceChromeOS::~VideoCaptureDeviceChromeOS() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- screen_observer_delegate_->RemoveObserver();
-}
-
-void VideoCaptureDeviceChromeOS::SetRotation(int rotation) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (!camera_config_.rotates_with_device) {
- rotation = 0;
- } else if (camera_config_.lens_facing ==
- VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT) {
- // Original frame when |rotation| = 0
- // -----------------------
- // | * |
- // | * * |
- // | * * |
- // | ******* |
- // | * * |
- // | * * |
- // -----------------------
- //
- // |rotation| = 90, this is what back camera sees
- // -----------------------
- // | ******** |
- // | * **** |
- // | * *** |
- // | * *** |
- // | * **** |
- // | ******** |
- // -----------------------
- //
- // |rotation| = 90, this is what front camera sees
- // -----------------------
- // | ******** |
- // | **** * |
- // | *** * |
- // | *** * |
- // | **** * |
- // | ******** |
- // -----------------------
- //
- // Therefore, for back camera, we need to rotate (360 - |rotation|).
- rotation = (360 - rotation) % 360;
- }
- // Take into account camera orientation w.r.t. the display. External cameras
- // would have camera_orientation_ as 0.
- rotation = (rotation + camera_config_.camera_orientation) % 360;
- VideoCaptureDeviceLinux::SetRotation(rotation);
-}
-
-void VideoCaptureDeviceChromeOS::SetDisplayRotation(
- const display::Display& display) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (display.IsInternal())
- SetRotation(display.rotation() * 90);
-}
-
-} // namespace media
diff --git a/chromium/media/capture/video/linux/video_capture_device_chromeos.h b/chromium/media/capture/video/linux/video_capture_device_chromeos.h
deleted file mode 100644
index 13471667d53..00000000000
--- a/chromium/media/capture/video/linux/video_capture_device_chromeos.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2014 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 MEDIA_CAPTURE_VIDEO_LINUX_VIDEO_CAPTURE_DEVICE_CHROMEOS_H_
-#define MEDIA_CAPTURE_VIDEO_LINUX_VIDEO_CAPTURE_DEVICE_CHROMEOS_H_
-
-#include "base/macros.h"
-#include "base/single_thread_task_runner.h"
-#include "media/capture/video/chromeos/display_rotation_observer.h"
-#include "media/capture/video/linux/video_capture_device_linux.h"
-
-namespace display {
-class Display;
-} // namespace display
-
-namespace media {
-
-struct ChromeOSDeviceCameraConfig {
- ChromeOSDeviceCameraConfig(VideoFacingMode lens_facing,
- int camera_orientation)
- : lens_facing(lens_facing),
- camera_orientation(camera_orientation),
- // External cameras have lens_facing as MEDIA_VIDEO_FACING_NONE.
- // We don't want to rotate the frame even if the device rotates.
- rotates_with_device(lens_facing !=
- VideoFacingMode::MEDIA_VIDEO_FACING_NONE) {}
-
- const VideoFacingMode lens_facing;
- const int camera_orientation;
- // Whether the incoming frames should rotate when the device rotates.
- const bool rotates_with_device;
-};
-
-// This class is functionally the same as VideoCaptureDeviceLinux, with the
-// exception that it is aware of the orientation of the internal Display. When
-// the internal Display is rotated, the frames captured are rotated to match.
-class VideoCaptureDeviceChromeOS : public VideoCaptureDeviceLinux,
- public DisplayRotationObserver {
- public:
- VideoCaptureDeviceChromeOS(
- const ChromeOSDeviceCameraConfig& camera_config,
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
- scoped_refptr<V4L2CaptureDevice> v4l2,
- const VideoCaptureDeviceDescriptor& device_descriptor);
- ~VideoCaptureDeviceChromeOS() override;
-
- protected:
- void SetRotation(int rotation) override;
-
- private:
- // DisplayRotationObserver implementation.
- void SetDisplayRotation(const display::Display& display) override;
-
- const ChromeOSDeviceCameraConfig camera_config_;
- scoped_refptr<ScreenObserverDelegate> screen_observer_delegate_;
-
- SEQUENCE_CHECKER(sequence_checker_);
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceChromeOS);
-};
-
-} // namespace media
-
-#endif // MEDIA_CAPTURE_VIDEO_LINUX_VIDEO_CAPTURE_DEVICE_CHROMEOS_H_
diff --git a/chromium/media/capture/video/linux/video_capture_device_factory_linux.cc b/chromium/media/capture/video/linux/video_capture_device_factory_linux.cc
index 677d733460e..6724957d80a 100644
--- a/chromium/media/capture/video/linux/video_capture_device_factory_linux.cc
+++ b/chromium/media/capture/video/linux/video_capture_device_factory_linux.cc
@@ -12,13 +12,13 @@
#include <algorithm>
#include <utility>
+#include "base/containers/contains.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
#include "media/capture/video/linux/scoped_v4l2_device_fd.h"
#include "media/capture/video/linux/video_capture_device_linux.h"
@@ -28,11 +28,6 @@
#include <linux/videodev2.h>
#endif
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "media/capture/video/linux/camera_config_chromeos.h"
-#include "media/capture/video/linux/video_capture_device_chromeos.h"
-#endif
-
namespace media {
namespace {
@@ -53,13 +48,6 @@ const char kPidPathTemplate[] = "/sys/class/video4linux/%s/device/../idProduct";
const char kInterfacePathTemplate[] =
"/sys/class/video4linux/%s/device/interface";
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-static CameraConfigChromeOS* GetCameraConfig() {
- static CameraConfigChromeOS* config = new CameraConfigChromeOS();
- return config;
-}
-#endif
-
bool ReadIdFile(const std::string& path, std::string* id) {
char id_buf[kVidPidSize];
FILE* file = fopen(path.c_str(), "rb");
@@ -122,26 +110,6 @@ class DevVideoFilePathsDeviceProvider
}
return display_name;
}
-
- VideoFacingMode GetCameraFacing(const std::string& device_id,
- const std::string& model_id) override {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
- return GetCameraConfig()->GetCameraFacing(device_id, model_id);
-#else
- NOTREACHED();
- return MEDIA_VIDEO_FACING_NONE;
-#endif
- }
-
- int GetOrientation(const std::string& device_id,
- const std::string& model_id) override {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
- return GetCameraConfig()->GetOrientation(device_id, model_id);
-#else
- NOTREACHED();
- return 0;
-#endif
- }
};
} // namespace
@@ -166,18 +134,8 @@ std::unique_ptr<VideoCaptureDevice>
VideoCaptureDeviceFactoryLinux::CreateDevice(
const VideoCaptureDeviceDescriptor& device_descriptor) {
DCHECK(thread_checker_.CalledOnValidThread());
-#if BUILDFLAG(IS_CHROMEOS_ASH)
- ChromeOSDeviceCameraConfig camera_config(
- device_provider_->GetCameraFacing(device_descriptor.device_id,
- device_descriptor.model_id),
- device_provider_->GetOrientation(device_descriptor.device_id,
- device_descriptor.model_id));
- auto self = std::make_unique<VideoCaptureDeviceChromeOS>(
- camera_config, ui_task_runner_, v4l2_.get(), device_descriptor);
-#else
auto self =
std::make_unique<VideoCaptureDeviceLinux>(v4l2_.get(), device_descriptor);
-#endif
// Test opening the device driver. This is to make sure it is available.
// We will reopen it again in our worker thread when someone
@@ -230,12 +188,7 @@ void VideoCaptureDeviceFactoryLinux::GetDevicesInfo(
if (display_name.empty())
display_name = reinterpret_cast<char*>(cap.card);
- VideoFacingMode facing_mode =
-#if BUILDFLAG(IS_CHROMEOS_ASH)
- device_provider_->GetCameraFacing(unique_id, model_id);
-#else
- VideoFacingMode::MEDIA_VIDEO_FACING_NONE;
-#endif
+ VideoFacingMode facing_mode = VideoFacingMode::MEDIA_VIDEO_FACING_NONE;
VideoCaptureFormats supported_formats;
GetSupportedFormatsForV4L2BufferType(fd.get(), &supported_formats);
diff --git a/chromium/media/capture/video/linux/video_capture_device_factory_linux.h b/chromium/media/capture/video/linux/video_capture_device_factory_linux.h
index 9895d2129f9..63ffeef9e96 100644
--- a/chromium/media/capture/video/linux/video_capture_device_factory_linux.h
+++ b/chromium/media/capture/video/linux/video_capture_device_factory_linux.h
@@ -31,20 +31,6 @@ class CAPTURE_EXPORT VideoCaptureDeviceFactoryLinux
virtual void GetDeviceIds(std::vector<std::string>* target_container) = 0;
virtual std::string GetDeviceModelId(const std::string& device_id) = 0;
virtual std::string GetDeviceDisplayName(const std::string& device_id) = 0;
- virtual VideoFacingMode GetCameraFacing(const std::string& device_id,
- const std::string& model_id) = 0;
- // Get the orientation of the camera. The value is the angle that the camera
- // image needs to be rotated clockwise so it shows correctly on the display
- // in its natural orientation. It should be 0, 90, 180, or 270.
- //
- // For example, suppose a device has a naturally tall screen. The
- // back-facing camera sensor is mounted in landscape. You are looking at the
- // screen. If the top side of the camera sensor is aligned with the right
- // edge of the screen in natural orientation, the value should be 90. If the
- // top side of a front-facing camera sensor is aligned with the right of the
- // screen, the value should be 270.
- virtual int GetOrientation(const std::string& device_id,
- const std::string& model_id) = 0;
};
explicit VideoCaptureDeviceFactoryLinux(
diff --git a/chromium/media/capture/video/mac/pixel_buffer_pool_mac.cc b/chromium/media/capture/video/mac/pixel_buffer_pool_mac.cc
index 4eae3d8f696..b25bb385da7 100644
--- a/chromium/media/capture/video/mac/pixel_buffer_pool_mac.cc
+++ b/chromium/media/capture/video/mac/pixel_buffer_pool_mac.cc
@@ -42,7 +42,7 @@ std::unique_ptr<PixelBufferPool> PixelBufferPool::Create(
OSType format,
int width,
int height,
- base::Optional<size_t> max_buffers) {
+ absl::optional<size_t> max_buffers) {
// Pixel buffer attributes: The attributes of buffers created by the pool.
CFStringRef pixel_buffer_attribute_keys[] = {
kCVPixelBufferIOSurfacePropertiesKey, // We want IOSurfaces.
@@ -91,7 +91,7 @@ std::unique_ptr<PixelBufferPool> PixelBufferPool::Create(
PixelBufferPool::PixelBufferPool(
base::ScopedCFTypeRef<CVPixelBufferPoolRef> buffer_pool,
- base::Optional<size_t> max_buffers)
+ absl::optional<size_t> max_buffers)
: buffer_pool_(std::move(buffer_pool)),
max_buffers_(std::move(max_buffers)),
num_consecutive_errors_(0) {
diff --git a/chromium/media/capture/video/mac/pixel_buffer_pool_mac.h b/chromium/media/capture/video/mac/pixel_buffer_pool_mac.h
index ed431d4699c..06c31a4f240 100644
--- a/chromium/media/capture/video/mac/pixel_buffer_pool_mac.h
+++ b/chromium/media/capture/video/mac/pixel_buffer_pool_mac.h
@@ -9,8 +9,8 @@
#include <memory>
#include "base/mac/scoped_cftyperef.h"
-#include "base/optional.h"
#include "media/capture/capture_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -26,7 +26,7 @@ class CAPTURE_EXPORT PixelBufferPool {
OSType format,
int width,
int height,
- base::Optional<size_t> max_buffers);
+ absl::optional<size_t> max_buffers);
~PixelBufferPool();
// Creates a new buffer from the pool, if possible. The underlying buffers are
@@ -55,13 +55,13 @@ class CAPTURE_EXPORT PixelBufferPool {
private:
friend std::unique_ptr<PixelBufferPool> std::make_unique<PixelBufferPool>(
base::ScopedCFTypeRef<CVPixelBufferPoolRef>&& buffer_pool,
- base::Optional<size_t>&& max_buffers);
+ absl::optional<size_t>&& max_buffers);
PixelBufferPool(base::ScopedCFTypeRef<CVPixelBufferPoolRef> buffer_pool,
- base::Optional<size_t> max_buffers);
+ absl::optional<size_t> max_buffers);
base::ScopedCFTypeRef<CVPixelBufferPoolRef> buffer_pool_;
- const base::Optional<size_t> max_buffers_;
+ const absl::optional<size_t> max_buffers_;
size_t num_consecutive_errors_;
};
diff --git a/chromium/media/capture/video/mac/pixel_buffer_pool_mac_unittest.mm b/chromium/media/capture/video/mac/pixel_buffer_pool_mac_unittest.mm
index bf0b561b96c..9cad540d016 100644
--- a/chromium/media/capture/video/mac/pixel_buffer_pool_mac_unittest.mm
+++ b/chromium/media/capture/video/mac/pixel_buffer_pool_mac_unittest.mm
@@ -76,7 +76,7 @@ TEST(PixelBufferPoolTest, CannotExceedMaxBuffersWhenIOSurfaceIsInUse) {
TEST(PixelBufferPoolTest, CanCreateBuffersIfMaxIsNull) {
std::unique_ptr<PixelBufferPool> pool = PixelBufferPool::Create(
- kPixelFormatNv12, kVgaWidth, kVgaHeight, base::nullopt);
+ kPixelFormatNv12, kVgaWidth, kVgaHeight, absl::nullopt);
base::ScopedCFTypeRef<CVPixelBufferRef> first_buffer = pool->CreateBuffer();
EXPECT_TRUE(first_buffer);
base::ScopedCFTypeRef<CVPixelBufferRef> second_buffer = pool->CreateBuffer();
@@ -180,7 +180,7 @@ TEST(PixelBufferPoolTest, BuffersCanOutliveThePool) {
TEST(PixelBufferPoolTest, CanFlushWhileBufferIsInUse) {
std::unique_ptr<PixelBufferPool> pool = PixelBufferPool::Create(
- kPixelFormatNv12, kVgaWidth, kVgaHeight, base::nullopt);
+ kPixelFormatNv12, kVgaWidth, kVgaHeight, absl::nullopt);
base::ScopedCFTypeRef<CVPixelBufferRef> retained_buffer =
pool->CreateBuffer();
base::ScopedCFTypeRef<CVPixelBufferRef> released_buffer =
diff --git a/chromium/media/capture/video/mac/sample_buffer_transformer_mac.cc b/chromium/media/capture/video/mac/sample_buffer_transformer_mac.cc
index ed8a5293527..0d98d68189d 100644
--- a/chromium/media/capture/video/mac/sample_buffer_transformer_mac.cc
+++ b/chromium/media/capture/video/mac/sample_buffer_transformer_mac.cc
@@ -15,9 +15,6 @@
namespace media {
-const base::Feature kInCaptureConvertToNv12{"InCaptureConvertToNv12",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
namespace {
// NV12 a.k.a. 420v
@@ -479,7 +476,7 @@ void SampleBufferTransformer::Reconfigure(
Transformer transformer,
OSType destination_pixel_format,
const gfx::Size& destination_size,
- base::Optional<size_t> buffer_pool_size) {
+ absl::optional<size_t> buffer_pool_size) {
DCHECK(transformer != Transformer::kLibyuv ||
destination_pixel_format == kPixelFormatI420 ||
destination_pixel_format == kPixelFormatNv12)
diff --git a/chromium/media/capture/video/mac/sample_buffer_transformer_mac.h b/chromium/media/capture/video/mac/sample_buffer_transformer_mac.h
index 24d42cff78d..d8b66605dcf 100644
--- a/chromium/media/capture/video/mac/sample_buffer_transformer_mac.h
+++ b/chromium/media/capture/video/mac/sample_buffer_transformer_mac.h
@@ -18,11 +18,6 @@
namespace media {
-// This flag is used to decide whether or not to use the SampleBufferTransformer
-// to convert captured images to NV12, see
-// video_capture_device_avfoundation_mac.mm.
-CAPTURE_EXPORT extern const base::Feature kInCaptureConvertToNv12;
-
// Capable of converting from any supported capture format (NV12, YUY2, UYVY and
// MJPEG) to NV12 or I420 and doing rescaling. This class can be configured to
// use VTPixelTransferSession (sometimes HW-accelerated) or third_party/libyuv
@@ -60,7 +55,7 @@ class CAPTURE_EXPORT SampleBufferTransformer {
void Reconfigure(Transformer transformer,
OSType destination_pixel_format,
const gfx::Size& destination_size,
- base::Optional<size_t> buffer_pool_size = base::nullopt);
+ absl::optional<size_t> buffer_pool_size = absl::nullopt);
// Converts the input buffer to an IOSurface-backed pixel buffer according to
// current configurations. If no transformation is needed (input format is the
diff --git a/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac.h b/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac.h
index 2e2b3f65bac..68ee39aec62 100644
--- a/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac.h
+++ b/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac.h
@@ -142,7 +142,7 @@ CAPTURE_EXPORT
// initialise an object of this class and register a |frameReceiver_|. This
// initializes the instance and the underlying capture session and registers the
// frame receiver.
-- (id)initWithFrameReceiver:
+- (instancetype)initWithFrameReceiver:
(media::VideoCaptureDeviceAVFoundationFrameReceiver*)frameReceiver;
// Frame receiver registration or removal can also happen via explicit call
diff --git a/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac.mm b/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
index 1cc1bdbcec2..e062332d85f 100644
--- a/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
+++ b/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
@@ -162,7 +162,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
#pragma mark Public methods
-- (id)initWithFrameReceiver:
+- (instancetype)initWithFrameReceiver:
(media::VideoCaptureDeviceAVFoundationFrameReceiver*)frameReceiver {
if ((self = [super init])) {
_mainThreadTaskRunner = base::ThreadTaskRunnerHandle::Get();
@@ -178,10 +178,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
self);
[self setFrameReceiver:frameReceiver];
_captureSession.reset([[AVCaptureSession alloc] init]);
- if (base::FeatureList::IsEnabled(media::kInCaptureConvertToNv12)) {
- _sampleBufferTransformer = media::SampleBufferTransformer::Create();
- VLOG(1) << "Capturing with SampleBufferTransformer enabled";
- }
+ _sampleBufferTransformer = media::SampleBufferTransformer::Create();
}
return self;
}
@@ -227,8 +224,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
_captureDevice.reset([AVCaptureDevice deviceWithUniqueID:deviceId],
base::scoped_policy::RETAIN);
if (!_captureDevice) {
- *outMessage =
- [NSString stringWithUTF8String:"Could not open video capture device."];
+ *outMessage = @"Could not open video capture device.";
return NO;
}
@@ -252,8 +248,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
_captureVideoDataOutput.reset([[AVCaptureVideoDataOutput alloc] init]);
if (!_captureVideoDataOutput) {
[_captureSession removeInput:_captureDeviceInput];
- *outMessage =
- [NSString stringWithUTF8String:"Could not create video data output."];
+ *outMessage = @"Could not create video data output.";
return NO;
}
[_captureVideoDataOutput setAlwaysDiscardsLateVideoFrames:true];
@@ -816,7 +811,10 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
// https://crbug.com/959962 (ignoring color space)
gfx::ColorSpace overriddenColorSpace = colorSpace;
if (colorSpace == kColorSpaceRec709Apple) {
- overriddenColorSpace = gfx::ColorSpace::CreateSRGB();
+ overriddenColorSpace = gfx::ColorSpace(
+ gfx::ColorSpace::PrimaryID::BT709,
+ gfx::ColorSpace::TransferID::IEC61966_2_1,
+ gfx::ColorSpace::MatrixID::BT709, gfx::ColorSpace::RangeID::LIMITED);
IOSurfaceSetValue(ioSurface, CFSTR("IOSurfaceColorSpace"),
kCGColorSpaceSRGB);
}
@@ -906,7 +904,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
// back on the M87 code path if this is the case.
// TODO(https://crbug.com/1160315): When the SampleBufferTransformer is
// patched to support non-MJPEG-and-non-pixel-buffer sample buffers, remove
- // this workaround.
+ // this workaround and the fallback other code path.
bool sampleHasPixelBufferOrIsMjpeg =
CMSampleBufferGetImageBuffer(sampleBuffer) ||
CMFormatDescriptionGetMediaSubType(CMSampleBufferGetFormatDescription(
@@ -916,9 +914,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
// formats to an IOSurface-backed NV12 pixel buffer.
// TODO(https://crbug.com/1175142): Refactor to not hijack the code paths
// below the transformer code.
- // TODO(hbos): When |_sampleBufferTransformer| gets shipped 100%, delete the
- // other code paths.
- if (_sampleBufferTransformer && sampleHasPixelBufferOrIsMjpeg) {
+ if (sampleHasPixelBufferOrIsMjpeg) {
_sampleBufferTransformer->Reconfigure(
media::SampleBufferTransformer::GetBestTransformerForNv12Output(
sampleBuffer),
@@ -1009,7 +1005,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
- (void)onVideoError:(NSNotification*)errorNotification {
NSError* error = base::mac::ObjCCast<NSError>(
- [[errorNotification userInfo] objectForKey:AVCaptureSessionErrorKey]);
+ [errorNotification userInfo][AVCaptureSessionErrorKey]);
[self sendErrorString:[NSString
stringWithFormat:@"%@: %@",
[error localizedDescription],
diff --git a/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac_unittest.mm b/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac_unittest.mm
index b51edef31da..2c6a3d55e72 100644
--- a/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac_unittest.mm
+++ b/chromium/media/capture/video/mac/video_capture_device_avfoundation_mac_unittest.mm
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/mac/scoped_nsobject.h"
#include "base/run_loop.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/scoped_feature_list.h"
@@ -29,8 +30,7 @@ namespace media {
TEST(VideoCaptureDeviceAVFoundationMacTest,
OutputsNv12WithoutScalingByDefault) {
base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- {kInCaptureConvertToNv12, kInCapturerScaling}, {});
+ scoped_feature_list.InitAndEnableFeature(kInCapturerScaling);
RunTestCase(base::BindOnce([] {
NSString* deviceId = GetFirstDeviceId();
@@ -76,7 +76,6 @@ TEST(VideoCaptureDeviceAVFoundationMacTest,
TEST(VideoCaptureDeviceAVFoundationMacTest,
SpecifiedScalingIsIgnoredWhenInCapturerScalingIsNotEnabled) {
base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(kInCaptureConvertToNv12);
// By default, kInCapturerScaling is false.
EXPECT_FALSE(base::FeatureList::IsEnabled(kInCapturerScaling));
@@ -127,8 +126,7 @@ TEST(VideoCaptureDeviceAVFoundationMacTest,
TEST(VideoCaptureDeviceAVFoundationMacTest, SpecifiedScalingOutputsNv12) {
base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- {kInCaptureConvertToNv12, kInCapturerScaling}, {});
+ scoped_feature_list.InitAndEnableFeature(kInCapturerScaling);
RunTestCase(base::BindOnce([] {
NSString* deviceId = GetFirstDeviceId();
@@ -183,8 +181,7 @@ TEST(VideoCaptureDeviceAVFoundationMacTest, SpecifiedScalingOutputsNv12) {
TEST(VideoCaptureDeviceAVFoundationMacTest,
SpecifiedScalingCanChangeDuringCapture) {
base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- {kInCaptureConvertToNv12, kInCapturerScaling}, {});
+ scoped_feature_list.InitAndEnableFeature(kInCapturerScaling);
RunTestCase(base::BindOnce([] {
NSString* deviceId = GetFirstDeviceId();
@@ -254,8 +251,7 @@ TEST(VideoCaptureDeviceAVFoundationMacTest,
TEST(VideoCaptureDeviceAVFoundationMacTest,
SpecifiedScalingUsesGoodSizesButNotBadSizes) {
base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- {kInCaptureConvertToNv12, kInCapturerScaling}, {});
+ scoped_feature_list.InitAndEnableFeature(kInCapturerScaling);
RunTestCase(base::BindOnce([] {
VideoCaptureDeviceFactoryMac video_capture_device_factory;
@@ -266,8 +262,8 @@ TEST(VideoCaptureDeviceAVFoundationMacTest,
return;
}
const auto& device_info = device_infos.front();
- NSString* deviceId = [NSString
- stringWithUTF8String:device_info.descriptor.device_id.c_str()];
+ NSString* deviceId =
+ base::SysUTF8ToNSString(device_info.descriptor.device_id);
VideoCaptureFormat camera_format = device_info.supported_formats.front();
testing::NiceMock<MockVideoCaptureDeviceAVFoundationFrameReceiver>
diff --git a/chromium/media/capture/video/mac/video_capture_device_avfoundation_utils_mac.mm b/chromium/media/capture/video/mac/video_capture_device_avfoundation_utils_mac.mm
index f37ca493c1f..5268b2c1b2f 100644
--- a/chromium/media/capture/video/mac/video_capture_device_avfoundation_utils_mac.mm
+++ b/chromium/media/capture/video/mac/video_capture_device_avfoundation_utils_mac.mm
@@ -153,7 +153,7 @@ base::scoped_nsobject<NSDictionary> GetDeviceNames() {
[[[DeviceNameAndTransportType alloc]
initWithName:[device localizedName]
transportType:[device transportType]] autorelease];
- [deviceNames setObject:nameAndTransportType forKey:[device uniqueID]];
+ deviceNames[[device uniqueID]] = nameAndTransportType;
}
}
MaybeWriteUma([deviceNames count], number_of_suspended_devices);
diff --git a/chromium/media/capture/video/mac/video_capture_device_mac.h b/chromium/media/capture/video/mac/video_capture_device_mac.h
index a4fde58694a..e1538917169 100644
--- a/chromium/media/capture/video/mac/video_capture_device_mac.h
+++ b/chromium/media/capture/video/mac/video_capture_device_mac.h
@@ -41,7 +41,8 @@ CAPTURE_EXPORT
int32_t _transportType;
}
-- (id)initWithName:(NSString*)name transportType:(int32_t)transportType;
+- (instancetype)initWithName:(NSString*)name
+ transportType:(int32_t)transportType;
- (NSString*)deviceName;
- (int32_t)transportType;
diff --git a/chromium/media/capture/video/mac/video_capture_device_mac.mm b/chromium/media/capture/video/mac/video_capture_device_mac.mm
index ed70ba8f991..83d4d0a18d1 100644
--- a/chromium/media/capture/video/mac/video_capture_device_mac.mm
+++ b/chromium/media/capture/video/mac/video_capture_device_mac.mm
@@ -37,7 +37,8 @@ using ScopedIOUSBInterfaceInterface =
@implementation DeviceNameAndTransportType
-- (id)initWithName:(NSString*)deviceName transportType:(int32_t)transportType {
+- (instancetype)initWithName:(NSString*)deviceName
+ transportType:(int32_t)transportType {
if (self = [super init]) {
_deviceName.reset([deviceName copy]);
_transportType = transportType;
@@ -450,8 +451,8 @@ static void GetZoomControlRangeAndCurrent(
static void SetPanTiltInUsbDevice(
IOUSBInterfaceInterface220** control_interface,
int unit_id,
- base::Optional<int> pan,
- base::Optional<int> tilt) {
+ absl::optional<int> pan,
+ absl::optional<int> tilt) {
if (!pan.has_value() && !tilt.has_value())
return;
@@ -620,8 +621,7 @@ void VideoCaptureDeviceMac::AllocateAndStart(
LogMessage("Using AVFoundation for device: " +
device_descriptor_.display_name());
- NSString* deviceId =
- [NSString stringWithUTF8String:device_descriptor_.device_id.c_str()];
+ NSString* deviceId = base::SysUTF8ToNSString(device_descriptor_.device_id);
[capture_device_ setFrameReceiver:this];
@@ -750,10 +750,10 @@ void VideoCaptureDeviceMac::SetPhotoOptions(mojom::PhotoSettingsPtr settings,
if (settings->has_pan || settings->has_tilt) {
SetPanTiltInUsbDevice(
control_interface, unit_id,
- settings->has_pan ? base::make_optional(settings->pan)
- : base::nullopt,
- settings->has_tilt ? base::make_optional(settings->tilt)
- : base::nullopt);
+ settings->has_pan ? absl::make_optional(settings->pan)
+ : absl::nullopt,
+ settings->has_tilt ? absl::make_optional(settings->tilt)
+ : absl::nullopt);
}
if (settings->has_zoom) {
SetZoomInUsbDevice(control_interface, unit_id, settings->zoom);
diff --git a/chromium/media/capture/video/mac/video_capture_device_mac_unittest.mm b/chromium/media/capture/video/mac/video_capture_device_mac_unittest.mm
index f690264dbf7..d5ed43a2bbf 100644
--- a/chromium/media/capture/video/mac/video_capture_device_mac_unittest.mm
+++ b/chromium/media/capture/video/mac/video_capture_device_mac_unittest.mm
@@ -15,15 +15,15 @@
Float64 _minFrameRate;
Float64 _maxFrameRate;
}
-- (id)initWithMinFrameRate:(Float64)minFrameRate
- maxFrameRate:(Float64)maxFrameRate;
+- (instancetype)initWithMinFrameRate:(Float64)minFrameRate
+ maxFrameRate:(Float64)maxFrameRate;
@end
@implementation FakeAVFrameRateRange
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
-- (id)initWithMinFrameRate:(Float64)minFrameRate
- maxFrameRate:(Float64)maxFrameRate {
+- (instancetype)initWithMinFrameRate:(Float64)minFrameRate
+ maxFrameRate:(Float64)maxFrameRate {
_minFrameRate = minFrameRate;
_maxFrameRate = maxFrameRate;
return self;
@@ -46,20 +46,20 @@
base::scoped_nsobject<FakeAVFrameRateRange> _frameRateRange1;
base::scoped_nsobject<FakeAVFrameRateRange> _frameRateRange2;
};
-- (id)initWithWidth:(int)width
- height:(int)height
- fourCC:(FourCharCode)fourCC
- frameRate:(Float64)frameRate;
+- (instancetype)initWithWidth:(int)width
+ height:(int)height
+ fourCC:(FourCharCode)fourCC
+ frameRate:(Float64)frameRate;
- (void)setSecondFrameRate:(Float64)frameRate;
@end
@implementation FakeAVCaptureDeviceFormat
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
-- (id)initWithWidth:(int)width
- height:(int)height
- fourCC:(FourCharCode)fourCC
- frameRate:(Float64)frameRate {
+- (instancetype)initWithWidth:(int)width
+ height:(int)height
+ fourCC:(FourCharCode)fourCC
+ frameRate:(Float64)frameRate {
CMVideoFormatDescriptionCreate(nullptr, fourCC, width, height, nullptr,
_formatDescription.InitializeInto());
_frameRateRange1.reset([[FakeAVFrameRateRange alloc]
diff --git a/chromium/media/capture/video/mock_gpu_memory_buffer_manager.cc b/chromium/media/capture/video/mock_gpu_memory_buffer_manager.cc
index 0246f6cbe99..8d1e5f9d4c8 100644
--- a/chromium/media/capture/video/mock_gpu_memory_buffer_manager.cc
+++ b/chromium/media/capture/video/mock_gpu_memory_buffer_manager.cc
@@ -24,7 +24,8 @@ MockGpuMemoryBufferManager::CreateFakeGpuMemoryBuffer(
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
- gpu::SurfaceHandle surface_handle) {
+ gpu::SurfaceHandle surface_handle,
+ base::WaitableEvent* shutdown_event) {
auto gmb = std::make_unique<FakeGpuMemoryBuffer>(size, format);
#if BUILDFLAG(IS_CHROMEOS_ASH)
// For faking a valid JPEG blob buffer.
diff --git a/chromium/media/capture/video/mock_gpu_memory_buffer_manager.h b/chromium/media/capture/video/mock_gpu_memory_buffer_manager.h
index 614cf8b8ac6..d617825ef3f 100644
--- a/chromium/media/capture/video/mock_gpu_memory_buffer_manager.h
+++ b/chromium/media/capture/video/mock_gpu_memory_buffer_manager.h
@@ -19,12 +19,13 @@ class MockGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager {
~MockGpuMemoryBufferManager() override;
- MOCK_METHOD4(
- CreateGpuMemoryBuffer,
- std::unique_ptr<gfx::GpuMemoryBuffer>(const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- gpu::SurfaceHandle surface_handle));
+ MOCK_METHOD5(CreateGpuMemoryBuffer,
+ std::unique_ptr<gfx::GpuMemoryBuffer>(
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ gpu::SurfaceHandle surface_handle,
+ base::WaitableEvent* shutdown_event));
MOCK_METHOD2(SetDestructionSyncToken,
void(gfx::GpuMemoryBuffer* buffer,
@@ -43,7 +44,8 @@ class MockGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager {
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
- gpu::SurfaceHandle surface_handle);
+ gpu::SurfaceHandle surface_handle,
+ base::WaitableEvent* shutdown_event);
private:
DISALLOW_COPY_AND_ASSIGN(MockGpuMemoryBufferManager);
diff --git a/chromium/media/capture/video/video_capture_device.h b/chromium/media/capture/video/video_capture_device.h
index fdc1197c3a8..0ee1782bb83 100644
--- a/chromium/media/capture/video/video_capture_device.h
+++ b/chromium/media/capture/video/video_capture_device.h
@@ -137,6 +137,12 @@ class CAPTURE_EXPORT VideoCaptureDevice
int frame_feedback_id;
std::unique_ptr<HandleProvider> handle_provider;
std::unique_ptr<ScopedAccessPermission> access_permission;
+
+ // Some buffer types may be preemptively mapped in the capturer if
+ // requested by the consumer.
+ // This is used to notify the client that a shared memory region
+ // associated with the buffer is valid.
+ bool is_premapped = false;
};
// Result code for calls to ReserveOutputBuffer()
diff --git a/chromium/media/capture/video/video_capture_device_client.cc b/chromium/media/capture/video/video_capture_device_client.cc
index 47ea404600e..a6771881497 100644
--- a/chromium/media/capture/video/video_capture_device_client.cc
+++ b/chromium/media/capture/video/video_capture_device_client.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/containers/contains.h"
#include "base/location.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
@@ -628,6 +629,7 @@ void VideoCaptureDeviceClient::OnIncomingCapturedBufferExt(
info->coded_size = format.frame_size;
info->visible_rect = visible_rect;
info->metadata = metadata;
+ info->is_premapped = buffer.is_premapped;
buffer_pool_->HoldForConsumers(buffer.id, 1);
receiver_->OnFrameReadyInBuffer(
diff --git a/chromium/media/capture/video/video_capture_device_client.h b/chromium/media/capture/video/video_capture_device_client.h
index 07d39c57cb5..3205586b357 100644
--- a/chromium/media/capture/video/video_capture_device_client.h
+++ b/chromium/media/capture/video/video_capture_device_client.h
@@ -16,7 +16,6 @@
#include "base/threading/thread_collision_warner.h"
#include "build/chromeos_buildflags.h"
#include "media/capture/capture_export.h"
-#include "media/capture/mojom/video_capture_types.mojom.h"
#include "media/capture/video/video_capture_device.h"
#include "media/capture/video/video_frame_receiver.h"
diff --git a/chromium/media/capture/video/video_capture_device_client_unittest.cc b/chromium/media/capture/video/video_capture_device_client_unittest.cc
index 0d5f18b5ddc..c4a218f423e 100644
--- a/chromium/media/capture/video/video_capture_device_client_unittest.cc
+++ b/chromium/media/capture/video/video_capture_device_client_unittest.cc
@@ -112,7 +112,7 @@ TEST_F(VideoCaptureDeviceClientTest, Minimal) {
gpu_memory_buffer_manager_->CreateFakeGpuMemoryBuffer(
kBufferDimensions, gfx::BufferFormat::YUV_420_BIPLANAR,
gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE,
- gpu::kNullSurfaceHandle);
+ gpu::kNullSurfaceHandle, nullptr);
{
InSequence s;
const int expected_buffer_id = 0;
@@ -152,7 +152,8 @@ TEST_F(VideoCaptureDeviceClientTest, FailsSilentlyGivenInvalidFrameFormat) {
std::unique_ptr<gfx::GpuMemoryBuffer> buffer =
gpu_memory_buffer_manager_->CreateFakeGpuMemoryBuffer(
kBufferDimensions, gfx::BufferFormat::YUV_420_BIPLANAR,
- gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, gpu::kNullSurfaceHandle);
+ gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, gpu::kNullSurfaceHandle,
+ nullptr);
EXPECT_CALL(*receiver_, MockOnFrameReadyInBuffer(_, _, _)).Times(0);
device_client_->OnIncomingCapturedGfxBuffer(
buffer.get(), kFrameFormat, 0 /*clockwise rotation*/, base::TimeTicks(),
@@ -311,7 +312,7 @@ TEST_F(VideoCaptureDeviceClientTest, CheckRotationsAndCrops) {
size_and_rotation.input_resolution,
gfx::BufferFormat::YUV_420_BIPLANAR,
gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE,
- gpu::kNullSurfaceHandle);
+ gpu::kNullSurfaceHandle, nullptr);
gfx::Size coded_size;
EXPECT_CALL(*receiver_, MockOnFrameReadyInBuffer(_, _, _))
diff --git a/chromium/media/capture/video/video_capture_device_descriptor.h b/chromium/media/capture/video/video_capture_device_descriptor.h
index f73d893e970..6318097be1d 100644
--- a/chromium/media/capture/video/video_capture_device_descriptor.h
+++ b/chromium/media/capture/video/video_capture_device_descriptor.h
@@ -8,9 +8,9 @@
#include <string>
#include <vector>
-#include "base/optional.h"
#include "media/base/video_facing.h"
#include "media/capture/capture_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
diff --git a/chromium/media/capture/video/video_capture_device_unittest.cc b/chromium/media/capture/video/video_capture_device_unittest.cc
index 8ce31e46f7b..dcdb16d4c0b 100644
--- a/chromium/media/capture/video/video_capture_device_unittest.cc
+++ b/chromium/media/capture/video/video_capture_device_unittest.cc
@@ -109,13 +109,9 @@
#define MAYBE_UsingRealWebcam_AllocateBadSize \
DISABLED_UsingRealWebcam_AllocateBadSize
#define MAYBE_UsingRealWebcam_CaptureMjpeg UsingRealWebcam_CaptureMjpeg
-// Flaky: https://crbug.com/1096082
-#define MAYBE_UsingRealWebcam_TakePhoto DISABLED_UsingRealWebcam_TakePhoto
-#define MAYBE_UsingRealWebcam_GetPhotoState \
- DISABLED_UsingRealWebcam_GetPhotoState
-// Flaky crash: https://crbug.com/1069608
-#define MAYBE_UsingRealWebcam_CaptureWithSize \
- DISABLED_UsingRealWebcam_CaptureWithSize
+#define MAYBE_UsingRealWebcam_TakePhoto UsingRealWebcam_TakePhoto
+#define MAYBE_UsingRealWebcam_GetPhotoState UsingRealWebcam_GetPhotoState
+#define MAYBE_UsingRealWebcam_CaptureWithSize UsingRealWebcam_CaptureWithSize
#define MAYBE_UsingRealWebcam_CheckPhotoCallbackRelease \
UsingRealWebcam_CheckPhotoCallbackRelease
#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -374,7 +370,7 @@ class VideoCaptureDeviceTest
run_loop_->Run();
}
- base::Optional<VideoCaptureDeviceInfo> FindUsableDevice() {
+ absl::optional<VideoCaptureDeviceInfo> FindUsableDevice() {
base::RunLoop run_loop;
video_capture_device_factory_->GetDevicesInfo(base::BindLambdaForTesting(
[this, &run_loop](std::vector<VideoCaptureDeviceInfo> devices_info) {
@@ -385,7 +381,7 @@ class VideoCaptureDeviceTest
if (devices_info_.empty()) {
DLOG(WARNING) << "No camera found";
- return base::nullopt;
+ return absl::nullopt;
}
#if defined(OS_ANDROID)
for (const auto& device : devices_info_) {
@@ -400,7 +396,7 @@ class VideoCaptureDeviceTest
}
}
DLOG(WARNING) << "No usable camera found";
- return base::nullopt;
+ return absl::nullopt;
#else
auto device = devices_info_.front();
DLOG(INFO) << "Using camera " << device.descriptor.GetNameAndModel();
@@ -410,10 +406,10 @@ class VideoCaptureDeviceTest
const VideoCaptureFormat& last_format() const { return last_format_; }
- base::Optional<VideoCaptureDeviceInfo> GetFirstDeviceSupportingPixelFormat(
+ absl::optional<VideoCaptureDeviceInfo> GetFirstDeviceSupportingPixelFormat(
const VideoPixelFormat& pixel_format) {
if (!FindUsableDevice())
- return base::nullopt;
+ return absl::nullopt;
for (const auto& device : devices_info_) {
for (const auto& format : device.supported_formats) {
@@ -424,7 +420,7 @@ class VideoCaptureDeviceTest
}
DVLOG_IF(1, pixel_format != PIXEL_FORMAT_MAX)
<< VideoPixelFormatToString(pixel_format);
- return base::nullopt;
+ return absl::nullopt;
}
bool IsCaptureSizeSupported(const VideoCaptureDeviceInfo& device_info,
@@ -477,15 +473,17 @@ class VideoCaptureDeviceTest
std::unique_ptr<VideoCaptureDeviceFactory> video_capture_device_factory_;
};
-// Causes a flaky crash on Chrome OS. https://crbug.com/1069608
// Cause hangs on Windows Debug. http://crbug.com/417824
-#if BUILDFLAG(IS_CHROMEOS_ASH) || (defined(OS_WIN) && !defined(NDEBUG))
-#define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice
+#if (defined(OS_WIN) && !defined(NDEBUG))
+#define MAYBE_UsingRealWebcam_OpenInvalidDevice \
+ DISABLED_UsingRealWebcam_OpenInvalidDevice
#else
-#define MAYBE_OpenInvalidDevice OpenInvalidDevice
+#define MAYBE_UsingRealWebcam_OpenInvalidDevice \
+ UsingRealWebcam_OpenInvalidDevice
#endif
// Tries to allocate an invalid device and verifies it doesn't work.
-WRAPPED_TEST_P(VideoCaptureDeviceTest, MAYBE_OpenInvalidDevice) {
+WRAPPED_TEST_P(VideoCaptureDeviceTest,
+ MAYBE_UsingRealWebcam_OpenInvalidDevice) {
RunTestCase(
base::BindOnce(&VideoCaptureDeviceTest::RunOpenInvalidDeviceTestCase,
base::Unretained(this)));
@@ -707,14 +705,10 @@ void VideoCaptureDeviceTest::RunCaptureMjpegTestCase() {
device->StopAndDeAllocate();
}
-// Flaky on ChromeOS. See https://crbug.com/1096082
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-#define MAYBE_NoCameraSupportsPixelFormatMax \
- DISABLED_NoCameraSupportsPixelFormatMax
-#else
-#define MAYBE_NoCameraSupportsPixelFormatMax NoCameraSupportsPixelFormatMax
-#endif
-WRAPPED_TEST_P(VideoCaptureDeviceTest, MAYBE_NoCameraSupportsPixelFormatMax) {
+#define MAYBE_UsingRealWebcam_NoCameraSupportsPixelFormatMax \
+ UsingRealWebcam_NoCameraSupportsPixelFormatMax
+WRAPPED_TEST_P(VideoCaptureDeviceTest,
+ MAYBE_UsingRealWebcam_NoCameraSupportsPixelFormatMax) {
RunTestCase(base::BindOnce(
&VideoCaptureDeviceTest::RunNoCameraSupportsPixelFormatMaxTestCase,
base::Unretained(this)));
diff --git a/chromium/media/capture/video/win/capability_list_win.cc b/chromium/media/capture/video/win/capability_list_win.cc
index 4ea9c690490..5ce95b17037 100644
--- a/chromium/media/capture/video/win/capability_list_win.cc
+++ b/chromium/media/capture/video/win/capability_list_win.cc
@@ -10,6 +10,7 @@
#include "base/check.h"
#include "media/capture/video_capture_types.h"
+#include "base/logging.h"
namespace media {
namespace {
@@ -17,41 +18,79 @@ namespace {
// Compares the priority of the capture formats. Returns true if |lhs| is the
// preferred capture format in comparison with |rhs|. Returns false otherwise.
bool CompareCapability(const VideoCaptureFormat& requested,
- const VideoCaptureFormat& lhs,
- const VideoCaptureFormat& rhs) {
+ const CapabilityWin& lhs,
+ const CapabilityWin& rhs) {
// When 16-bit format or NV12 is requested and available, avoid other formats.
// If both lhs and rhs are 16-bit, we still need to compare them based on
// height, width and frame rate.
const bool use_requested =
(requested.pixel_format == media::PIXEL_FORMAT_Y16) ||
(requested.pixel_format == media::PIXEL_FORMAT_NV12);
- if (use_requested && lhs.pixel_format != rhs.pixel_format) {
- if (lhs.pixel_format == requested.pixel_format)
+ if (use_requested &&
+ lhs.supported_format.pixel_format != rhs.supported_format.pixel_format) {
+ if (lhs.supported_format.pixel_format == requested.pixel_format)
return true;
- if (rhs.pixel_format == requested.pixel_format)
+ if (rhs.supported_format.pixel_format == requested.pixel_format)
return false;
}
- const int diff_height_lhs =
- std::abs(lhs.frame_size.height() - requested.frame_size.height());
- const int diff_height_rhs =
- std::abs(rhs.frame_size.height() - requested.frame_size.height());
+ const int diff_height_lhs = std::abs(
+ lhs.supported_format.frame_size.height() - requested.frame_size.height());
+ const int diff_height_rhs = std::abs(
+ rhs.supported_format.frame_size.height() - requested.frame_size.height());
if (diff_height_lhs != diff_height_rhs)
return diff_height_lhs < diff_height_rhs;
- const int diff_width_lhs =
- std::abs(lhs.frame_size.width() - requested.frame_size.width());
- const int diff_width_rhs =
- std::abs(rhs.frame_size.width() - requested.frame_size.width());
+ const int diff_width_lhs = std::abs(lhs.supported_format.frame_size.width() -
+ requested.frame_size.width());
+ const int diff_width_rhs = std::abs(rhs.supported_format.frame_size.width() -
+ requested.frame_size.width());
if (diff_width_lhs != diff_width_rhs)
return diff_width_lhs < diff_width_rhs;
- const float diff_fps_lhs = std::fabs(lhs.frame_rate - requested.frame_rate);
- const float diff_fps_rhs = std::fabs(rhs.frame_rate - requested.frame_rate);
+ const float diff_fps_lhs =
+ std::fabs(lhs.supported_format.frame_rate - requested.frame_rate);
+ const float diff_fps_rhs =
+ std::fabs(rhs.supported_format.frame_rate - requested.frame_rate);
if (diff_fps_lhs != diff_fps_rhs)
return diff_fps_lhs < diff_fps_rhs;
- return VideoCaptureFormat::ComparePixelFormatPreference(lhs.pixel_format,
- rhs.pixel_format);
+ // Compare by internal pixel format to avoid conversions when possible.
+ if (lhs.source_pixel_format != rhs.source_pixel_format) {
+ // Choose the format with no conversion if possible.
+ if (lhs.source_pixel_format == requested.pixel_format)
+ return true;
+ if (rhs.source_pixel_format == requested.pixel_format)
+ return false;
+ // Prefer I420<->NV12 conversion over all.
+ if ((lhs.source_pixel_format == PIXEL_FORMAT_NV12 &&
+ requested.pixel_format == PIXEL_FORMAT_I420) ||
+ (lhs.source_pixel_format == PIXEL_FORMAT_I420 &&
+ requested.pixel_format == PIXEL_FORMAT_NV12)) {
+ return true;
+ }
+ if ((rhs.source_pixel_format == PIXEL_FORMAT_NV12 &&
+ requested.pixel_format == PIXEL_FORMAT_I420) ||
+ (rhs.source_pixel_format == PIXEL_FORMAT_I420 &&
+ requested.pixel_format == PIXEL_FORMAT_NV12)) {
+ return false;
+ }
+ // YUY2<->NV12 is the next best.
+ if ((lhs.source_pixel_format == PIXEL_FORMAT_NV12 &&
+ requested.pixel_format == PIXEL_FORMAT_YUY2) ||
+ (lhs.source_pixel_format == PIXEL_FORMAT_YUY2 &&
+ requested.pixel_format == PIXEL_FORMAT_NV12)) {
+ return true;
+ }
+ if ((rhs.source_pixel_format == PIXEL_FORMAT_NV12 &&
+ requested.pixel_format == PIXEL_FORMAT_YUY2) ||
+ (rhs.source_pixel_format == PIXEL_FORMAT_YUY2 &&
+ requested.pixel_format == PIXEL_FORMAT_NV12)) {
+ return false;
+ }
+ }
+
+ return VideoCaptureFormat::ComparePixelFormatPreference(
+ lhs.supported_format.pixel_format, rhs.supported_format.pixel_format);
}
} // namespace
@@ -62,8 +101,7 @@ const CapabilityWin& GetBestMatchedCapability(
DCHECK(!capabilities.empty());
const CapabilityWin* best_match = &(*capabilities.begin());
for (const CapabilityWin& capability : capabilities) {
- if (CompareCapability(requested, capability.supported_format,
- best_match->supported_format)) {
+ if (CompareCapability(requested, capability, *best_match)) {
best_match = &capability;
}
}
diff --git a/chromium/media/capture/video/win/capability_list_win.h b/chromium/media/capture/video/win/capability_list_win.h
index f873251d6a6..2b77fbe98aa 100644
--- a/chromium/media/capture/video/win/capability_list_win.h
+++ b/chromium/media/capture/video/win/capability_list_win.h
@@ -21,7 +21,8 @@ struct CapabilityWin {
: media_type_index(media_type_index),
supported_format(format),
info_header(),
- stream_index(0) {}
+ stream_index(0),
+ source_pixel_format(format.pixel_format) {}
// Used by VideoCaptureDeviceWin.
CapabilityWin(int media_type_index,
@@ -30,16 +31,19 @@ struct CapabilityWin {
: media_type_index(media_type_index),
supported_format(format),
info_header(info_header),
- stream_index(0) {}
+ stream_index(0),
+ source_pixel_format(format.pixel_format) {}
// Used by VideoCaptureDeviceMFWin.
CapabilityWin(int media_type_index,
const VideoCaptureFormat& format,
- int stream_index)
+ int stream_index,
+ VideoPixelFormat source_format)
: media_type_index(media_type_index),
supported_format(format),
info_header(),
- stream_index(stream_index) {}
+ stream_index(stream_index),
+ source_pixel_format(source_format) {}
const int media_type_index;
const VideoCaptureFormat supported_format;
@@ -49,6 +53,10 @@ struct CapabilityWin {
// |stream_index| is only valid if MediaFoundation is used.
const int stream_index;
+
+ // |source_pixel_format| may differ from |supported_format|
+ // if MediaFoundation is used.
+ VideoPixelFormat source_pixel_format;
};
typedef std::list<CapabilityWin> CapabilityList;
diff --git a/chromium/media/capture/video/win/gpu_memory_buffer_tracker.cc b/chromium/media/capture/video/win/gpu_memory_buffer_tracker.cc
index e39f2db5f4f..8579ebcc295 100644
--- a/chromium/media/capture/video/win/gpu_memory_buffer_tracker.cc
+++ b/chromium/media/capture/video/win/gpu_memory_buffer_tracker.cc
@@ -101,6 +101,9 @@ bool GpuMemoryBufferTracker::CreateBufferInternal() {
NOTREACHED() << "Failed to create GPU memory buffer";
return false;
}
+
+ region_ = base::UnsafeSharedMemoryRegion::Create(GetMemorySizeInBytes());
+
return true;
}
@@ -137,10 +140,8 @@ GpuMemoryBufferTracker::DuplicateAsUnsafeRegion() {
if (!buffer_) {
return base::UnsafeSharedMemoryRegion();
}
- const auto data_size = GetMemorySizeInBytes();
- if (!region_.IsValid() || region_.GetSize() < data_size) {
- region_ = base::UnsafeSharedMemoryRegion::Create(data_size);
- }
+
+ CHECK(region_.IsValid());
if (!gpu::CopyDXGIBufferToShMem(buffer_->GetHandle(), region_.Duplicate(),
d3d_device_.Get(), &staging_texture_)) {
@@ -160,7 +161,9 @@ gfx::GpuMemoryBufferHandle GpuMemoryBufferTracker::GetGpuMemoryBufferHandle() {
if (!EnsureD3DDevice()) {
return gfx::GpuMemoryBufferHandle();
}
- return buffer_->CloneHandle();
+ auto handle = buffer_->CloneHandle();
+ handle.region = region_.Duplicate();
+ return handle;
}
uint32_t GpuMemoryBufferTracker::GetMemorySizeInBytes() {
diff --git a/chromium/media/capture/video/win/video_capture_device_factory_win.cc b/chromium/media/capture/video/win/video_capture_device_factory_win.cc
index 43e01991837..d7b56a063ac 100644
--- a/chromium/media/capture/video/win/video_capture_device_factory_win.cc
+++ b/chromium/media/capture/video/win/video_capture_device_factory_win.cc
@@ -17,6 +17,7 @@
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
@@ -975,11 +976,6 @@ VideoCaptureDeviceFactoryWin::GetSupportedFormatsMediaFoundation(
++stream_index;
if (capture_format.pixel_format == PIXEL_FORMAT_UNKNOWN)
continue;
- // If we're using the hardware capture path, ignore non-NV12 pixel formats
- // to prevent copies
- if (dxgi_device_manager_available &&
- capture_format.pixel_format != PIXEL_FORMAT_NV12)
- continue;
formats.push_back(capture_format);
DVLOG(1) << display_name << " "
diff --git a/chromium/media/capture/video/win/video_capture_device_factory_win_unittest.cc b/chromium/media/capture/video/win/video_capture_device_factory_win_unittest.cc
index 274bab4fdac..15bda062bd3 100644
--- a/chromium/media/capture/video/win/video_capture_device_factory_win_unittest.cc
+++ b/chromium/media/capture/video/win/video_capture_device_factory_win_unittest.cc
@@ -8,6 +8,7 @@
#include <ksmedia.h>
#include <mfapi.h>
#include <mferror.h>
+#include <mfobjects.h>
#include <stddef.h>
#include <vidcap.h>
#include <wrl.h>
@@ -64,6 +65,11 @@ const wchar_t* kDirectShowDeviceName5 = L"Dazzle";
const wchar_t* kDirectShowDeviceId6 = L"\\\\?\\usb#vid_eb1a&pid_2860&mi_00";
const wchar_t* kDirectShowDeviceName6 = L"Empia Device";
+constexpr int kWidth = 1280;
+constexpr int kHeight = 720;
+
+constexpr int kFps = 30;
+
using iterator = std::vector<VideoCaptureDeviceInfo>::const_iterator;
iterator FindDeviceInRange(iterator begin,
iterator end,
@@ -385,6 +391,11 @@ class StubMFMediaSource final : public StubDeviceInterface<IMFMediaSourceEx> {
*object = AddReference(static_cast<IMFMediaSource*>(this));
return S_OK;
}
+ if (riid == _uuidof(IMFMediaEventGenerator)) {
+ *object = AddReference(static_cast<IMFMediaEventGenerator*>(this));
+ return S_OK;
+ }
+
return StubDeviceInterface::QueryInterface(riid, object);
}
// IMFMediaEventGenerator
@@ -436,6 +447,15 @@ class StubMFMediaSource final : public StubDeviceInterface<IMFMediaSourceEx> {
if (FAILED(hr)) {
return hr;
}
+ hr = MFSetAttributeSize(media_type.Get(), MF_MT_FRAME_SIZE, kWidth,
+ kHeight);
+ if (FAILED(hr)) {
+ return hr;
+ }
+ hr = MFSetAttributeRatio(media_type.Get(), MF_MT_FRAME_RATE, kFps, 1);
+ if (FAILED(hr)) {
+ return hr;
+ }
media_types.push_back(media_type);
media_type_list.push_back(media_type.Get());
}
@@ -1579,6 +1599,7 @@ TEST_P(VideoCaptureDeviceFactoryMFWinTest,
base::SysWideToUTF8(kMFDeviceId0));
ASSERT_NE(it, devices_info.end());
EXPECT_EQ(it->descriptor.display_name(), base::SysWideToUTF8(kMFDeviceName0));
+ EXPECT_FALSE(it->supported_formats.empty());
for (size_t i = 0; i < it->supported_formats.size(); i++) {
SCOPED_TRACE(i);
EXPECT_EQ(it->supported_formats[i].pixel_format,
@@ -1589,9 +1610,11 @@ TEST_P(VideoCaptureDeviceFactoryMFWinTest,
base::SysWideToUTF8(kMFDeviceId1));
ASSERT_NE(it, devices_info.end());
EXPECT_EQ(it->descriptor.display_name(), base::SysWideToUTF8(kMFDeviceName1));
+ EXPECT_FALSE(it->supported_formats.empty());
for (size_t i = 0; i < it->supported_formats.size(); i++) {
SCOPED_TRACE(i);
- EXPECT_EQ(it->supported_formats[i].pixel_format, PIXEL_FORMAT_I420);
+ EXPECT_EQ(it->supported_formats[i].pixel_format,
+ expected_pixel_format_for_nv12);
}
}
diff --git a/chromium/media/capture/video/win/video_capture_device_mf_win.cc b/chromium/media/capture/video/win/video_capture_device_mf_win.cc
index 2f2b72f1e44..750a04d1dc4 100644
--- a/chromium/media/capture/video/win/video_capture_device_mf_win.cc
+++ b/chromium/media/capture/video/win/video_capture_device_mf_win.cc
@@ -10,6 +10,7 @@
#include <stddef.h>
#include <wincodec.h>
+#include <memory>
#include <thread>
#include <utility>
@@ -226,10 +227,39 @@ bool GetFrameRateFromMediaType(IMFMediaType* type, float* frame_rate) {
return true;
}
+struct PixelFormatMap {
+ GUID mf_source_media_subtype;
+ VideoPixelFormat pixel_format;
+};
+
+VideoPixelFormat MfSubTypeToSourcePixelFormat(
+ const GUID& mf_source_media_subtype) {
+ static const PixelFormatMap kPixelFormatMap[] = {
+
+ {MFVideoFormat_I420, PIXEL_FORMAT_I420},
+ {MFVideoFormat_YUY2, PIXEL_FORMAT_YUY2},
+ {MFVideoFormat_UYVY, PIXEL_FORMAT_UYVY},
+ {MFVideoFormat_RGB24, PIXEL_FORMAT_RGB24},
+ {MFVideoFormat_RGB32, PIXEL_FORMAT_XRGB},
+ {MFVideoFormat_ARGB32, PIXEL_FORMAT_ARGB},
+ {MFVideoFormat_MJPG, PIXEL_FORMAT_MJPEG},
+ {MFVideoFormat_NV12, PIXEL_FORMAT_NV12},
+ {MFVideoFormat_YV12, PIXEL_FORMAT_YV12},
+ {GUID_ContainerFormatJpeg, PIXEL_FORMAT_MJPEG}};
+
+ for (const auto& kEntry : kPixelFormatMap) {
+ if (kEntry.mf_source_media_subtype == mf_source_media_subtype) {
+ return kEntry.pixel_format;
+ }
+ }
+ return PIXEL_FORMAT_UNKNOWN;
+}
+
bool GetFormatFromSourceMediaType(IMFMediaType* source_media_type,
bool photo,
bool use_hardware_format,
- VideoCaptureFormat* format) {
+ VideoCaptureFormat* format,
+ VideoPixelFormat* source_pixel_format) {
GUID major_type_guid;
if (FAILED(source_media_type->GetGUID(MF_MT_MAJOR_TYPE, &major_type_guid)) ||
(major_type_guid != MFMediaType_Image &&
@@ -246,6 +276,7 @@ bool GetFormatFromSourceMediaType(IMFMediaType* source_media_type,
return false;
}
+ *source_pixel_format = MfSubTypeToSourcePixelFormat(sub_type_guid);
return true;
}
@@ -264,6 +295,7 @@ HRESULT CopyAttribute(IMFAttributes* source_attributes,
}
struct MediaFormatConfiguration {
+ bool is_hardware_format;
GUID mf_source_media_subtype;
GUID mf_sink_media_subtype;
VideoPixelFormat pixel_format;
@@ -273,13 +305,6 @@ bool GetMediaFormatConfigurationFromMFSourceMediaSubtype(
const GUID& mf_source_media_subtype,
bool use_hardware_format,
MediaFormatConfiguration* media_format_configuration) {
- // Special case handling of the NV12 format when using hardware capture
- // to ensure that captured buffers are passed through without copies
- if (use_hardware_format && mf_source_media_subtype == MFVideoFormat_NV12) {
- *media_format_configuration = {MFVideoFormat_NV12, MFVideoFormat_NV12,
- PIXEL_FORMAT_NV12};
- return true;
- }
static const MediaFormatConfiguration kMediaFormatConfigurationMap[] = {
// IMFCaptureEngine inevitably performs the video frame decoding itself.
// This means that the sink must always be set to an uncompressed video
@@ -287,30 +312,56 @@ bool GetMediaFormatConfigurationFromMFSourceMediaSubtype(
// Since chromium uses I420 at the other end of the pipe, MF known video
// output formats are always set to I420.
- {MFVideoFormat_I420, MFVideoFormat_I420, PIXEL_FORMAT_I420},
- {MFVideoFormat_YUY2, MFVideoFormat_I420, PIXEL_FORMAT_I420},
- {MFVideoFormat_UYVY, MFVideoFormat_I420, PIXEL_FORMAT_I420},
- {MFVideoFormat_RGB24, MFVideoFormat_I420, PIXEL_FORMAT_I420},
- {MFVideoFormat_RGB32, MFVideoFormat_I420, PIXEL_FORMAT_I420},
- {MFVideoFormat_ARGB32, MFVideoFormat_I420, PIXEL_FORMAT_I420},
- {MFVideoFormat_MJPG, MFVideoFormat_I420, PIXEL_FORMAT_I420},
- {MFVideoFormat_NV12, MFVideoFormat_I420, PIXEL_FORMAT_I420},
- {MFVideoFormat_YV12, MFVideoFormat_I420, PIXEL_FORMAT_I420},
+ {false, MFVideoFormat_I420, MFVideoFormat_I420, PIXEL_FORMAT_I420},
+ {false, MFVideoFormat_YUY2, MFVideoFormat_I420, PIXEL_FORMAT_I420},
+ {false, MFVideoFormat_UYVY, MFVideoFormat_I420, PIXEL_FORMAT_I420},
+ {false, MFVideoFormat_RGB24, MFVideoFormat_I420, PIXEL_FORMAT_I420},
+ {false, MFVideoFormat_RGB32, MFVideoFormat_I420, PIXEL_FORMAT_I420},
+ {false, MFVideoFormat_ARGB32, MFVideoFormat_I420, PIXEL_FORMAT_I420},
+ {false, MFVideoFormat_MJPG, MFVideoFormat_I420, PIXEL_FORMAT_I420},
+ {false, MFVideoFormat_NV12, MFVideoFormat_I420, PIXEL_FORMAT_I420},
+ {false, MFVideoFormat_YV12, MFVideoFormat_I420, PIXEL_FORMAT_I420},
// Depth cameras use 16-bit uncompressed video formats.
// We ask IMFCaptureEngine to let the frame pass through, without
// transcoding, since transcoding would lead to precision loss.
- {kMediaSubTypeY16, kMediaSubTypeY16, PIXEL_FORMAT_Y16},
- {kMediaSubTypeZ16, kMediaSubTypeZ16, PIXEL_FORMAT_Y16},
- {kMediaSubTypeINVZ, kMediaSubTypeINVZ, PIXEL_FORMAT_Y16},
- {MFVideoFormat_D16, MFVideoFormat_D16, PIXEL_FORMAT_Y16},
+ {false, kMediaSubTypeY16, kMediaSubTypeY16, PIXEL_FORMAT_Y16},
+ {false, kMediaSubTypeZ16, kMediaSubTypeZ16, PIXEL_FORMAT_Y16},
+ {false, kMediaSubTypeINVZ, kMediaSubTypeINVZ, PIXEL_FORMAT_Y16},
+ {false, MFVideoFormat_D16, MFVideoFormat_D16, PIXEL_FORMAT_Y16},
// Photo type
- {GUID_ContainerFormatJpeg, GUID_ContainerFormatJpeg, PIXEL_FORMAT_MJPEG}};
+ {false, GUID_ContainerFormatJpeg, GUID_ContainerFormatJpeg,
+ PIXEL_FORMAT_MJPEG},
+
+ // For hardware path we always convert to NV12, since it's the only
+ // supported by GMBs format.
+ {true, MFVideoFormat_I420, MFVideoFormat_NV12, PIXEL_FORMAT_NV12},
+ {true, MFVideoFormat_YUY2, MFVideoFormat_NV12, PIXEL_FORMAT_NV12},
+ {true, MFVideoFormat_UYVY, MFVideoFormat_NV12, PIXEL_FORMAT_NV12},
+ {true, MFVideoFormat_RGB24, MFVideoFormat_NV12, PIXEL_FORMAT_NV12},
+ {true, MFVideoFormat_RGB32, MFVideoFormat_NV12, PIXEL_FORMAT_NV12},
+ {true, MFVideoFormat_ARGB32, MFVideoFormat_NV12, PIXEL_FORMAT_NV12},
+ {true, MFVideoFormat_MJPG, MFVideoFormat_NV12, PIXEL_FORMAT_NV12},
+ {true, MFVideoFormat_NV12, MFVideoFormat_NV12, PIXEL_FORMAT_NV12},
+ {true, MFVideoFormat_YV12, MFVideoFormat_NV12, PIXEL_FORMAT_NV12},
+
+ // 16-bit formats can't be converted without loss of precision,
+ // so if leave an option to get Y16 pixel format even though the
+ // HW path won't be used for it.
+ {true, kMediaSubTypeY16, kMediaSubTypeY16, PIXEL_FORMAT_Y16},
+ {true, kMediaSubTypeZ16, kMediaSubTypeZ16, PIXEL_FORMAT_Y16},
+ {true, kMediaSubTypeINVZ, kMediaSubTypeINVZ, PIXEL_FORMAT_Y16},
+ {true, MFVideoFormat_D16, MFVideoFormat_D16, PIXEL_FORMAT_Y16},
+
+ // Photo type
+ {true, GUID_ContainerFormatJpeg, GUID_ContainerFormatJpeg,
+ PIXEL_FORMAT_MJPEG}};
for (const auto& kMediaFormatConfiguration : kMediaFormatConfigurationMap) {
- if (kMediaFormatConfiguration.mf_source_media_subtype ==
- mf_source_media_subtype) {
+ if (kMediaFormatConfiguration.is_hardware_format == use_hardware_format &&
+ kMediaFormatConfiguration.mf_source_media_subtype ==
+ mf_source_media_subtype) {
*media_format_configuration = kMediaFormatConfiguration;
return true;
}
@@ -789,12 +840,14 @@ HRESULT VideoCaptureDeviceMFWin::FillCapabilities(
while (SUCCEEDED(hr = GetAvailableDeviceMediaType(
source, stream_index, media_type_index, &type))) {
VideoCaptureFormat format;
+ VideoPixelFormat source_pixel_format;
if (GetFormatFromSourceMediaType(
type.Get(), photo,
/*use_hardware_format=*/!photo &&
static_cast<bool>(dxgi_device_manager_),
- &format))
- capabilities->emplace_back(media_type_index, format, stream_index);
+ &format, &source_pixel_format))
+ capabilities->emplace_back(media_type_index, format, stream_index,
+ source_pixel_format);
type.Reset();
++media_type_index;
}
@@ -947,8 +1000,8 @@ void VideoCaptureDeviceMFWin::AllocateAndStart(
}
if (!photo_capabilities_.empty()) {
- selected_photo_capability_.reset(
- new CapabilityWin(photo_capabilities_.front()));
+ selected_photo_capability_ =
+ std::make_unique<CapabilityWin>(photo_capabilities_.front());
}
CapabilityList video_capabilities;
@@ -1065,8 +1118,8 @@ void VideoCaptureDeviceMFWin::AllocateAndStart(
return;
}
- selected_video_capability_.reset(
- new CapabilityWin(best_match_video_capability));
+ selected_video_capability_ =
+ std::make_unique<CapabilityWin>(best_match_video_capability);
is_started_ = true;
}
@@ -1132,8 +1185,10 @@ void VideoCaptureDeviceMFWin::TakePhoto(TakePhotoCallback callback) {
}
VideoCaptureFormat format;
+ VideoPixelFormat source_format;
hr = GetFormatFromSourceMediaType(sink_media_type.Get(), true,
- /*use_hardware_format=*/false, &format)
+ /*use_hardware_format=*/false, &format,
+ &source_format)
? S_OK
: E_FAIL;
if (FAILED(hr)) {
@@ -1309,7 +1364,7 @@ void VideoCaptureDeviceMFWin::SetPhotoOptions(
const CapabilityWin best_match = GetBestMatchedPhotoCapability(
current_source_media_type, requested_size, photo_capabilities_);
- selected_photo_capability_.reset(new CapabilityWin(best_match));
+ selected_photo_capability_ = std::make_unique<CapabilityWin>(best_match);
}
if (camera_control_ && video_control_) {
@@ -1496,9 +1551,15 @@ HRESULT VideoCaptureDeviceMFWin::DeliverTextureToClient(
auto gmb_handle = capture_buffer.handle_provider->GetGpuMemoryBufferHandle();
hr = CopyTextureToGpuMemoryBuffer(texture, gmb_handle.dxgi_handle.Get());
+ capture_buffer.is_premapped = false;
if (last_feedback_.require_mapped_frame) {
- gmb_handle.region =
- capture_buffer.handle_provider->DuplicateAsUnsafeRegion();
+ // Only a flag on the Buffer is set here; the region itself isn't passed
+ // anywhere because it was passed when the buffer was created.
+ // Now the flag would tell the consumer that the region contains actual
+ // frame data.
+ if (capture_buffer.handle_provider->DuplicateAsUnsafeRegion().IsValid()) {
+ capture_buffer.is_premapped = true;
+ }
}
if (FAILED(hr)) {
@@ -1563,7 +1624,11 @@ void VideoCaptureDeviceMFWin::OnIncomingCapturedDataInternal(
camera_rotation_ = GetCameraRotation(facing_mode_);
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
+ // Use the hardware path only if it is enabled and the selected pixel format
+ // is NV12 (which is the only supported one).
if (dxgi_device_manager_ &&
+ selected_video_capability_->supported_format.pixel_format ==
+ PIXEL_FORMAT_NV12 &&
SUCCEEDED(GetTextureFromMFBuffer(buffer, &texture))) {
HRESULT hr =
DeliverTextureToClient(texture.Get(), reference_time, timestamp);
diff --git a/chromium/media/capture/video/win/video_capture_device_mf_win.h b/chromium/media/capture/video/win/video_capture_device_mf_win.h
index beefdb9bec8..196ab92d0e2 100644
--- a/chromium/media/capture/video/win/video_capture_device_mf_win.h
+++ b/chromium/media/capture/video/win/video_capture_device_mf_win.h
@@ -19,14 +19,15 @@
#include <vector>
#include "base/callback_forward.h"
+#include "base/containers/queue.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "media/base/win/dxgi_device_manager.h"
#include "media/capture/capture_export.h"
#include "media/capture/video/video_capture_device.h"
#include "media/capture/video/win/capability_list_win.h"
#include "media/capture/video/win/metrics.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
interface IMFSourceReader;
@@ -106,7 +107,7 @@ class CAPTURE_EXPORT VideoCaptureDeviceMFWin : public VideoCaptureDevice {
dxgi_device_manager_ = std::move(dxgi_device_manager);
}
- base::Optional<int> camera_rotation() const { return camera_rotation_; }
+ absl::optional<int> camera_rotation() const { return camera_rotation_; }
private:
HRESULT ExecuteHresultCallbackWithRetries(
@@ -173,7 +174,7 @@ class CAPTURE_EXPORT VideoCaptureDeviceMFWin : public VideoCaptureDevice {
base::WaitableEvent capture_initialize_;
base::WaitableEvent capture_error_;
scoped_refptr<DXGIDeviceManager> dxgi_device_manager_;
- base::Optional<int> camera_rotation_;
+ absl::optional<int> camera_rotation_;
media::VideoCaptureFeedback last_feedback_;
diff --git a/chromium/media/capture/video/win/video_capture_device_win.h b/chromium/media/capture/video/win/video_capture_device_win.h
index 00775a5f60e..54bf57ed64a 100644
--- a/chromium/media/capture/video/win/video_capture_device_win.h
+++ b/chromium/media/capture/video/win/video_capture_device_win.h
@@ -20,13 +20,13 @@
#include "base/containers/queue.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "media/capture/video/video_capture_device.h"
#include "media/capture/video/win/capability_list_win.h"
#include "media/capture/video/win/sink_filter_win.h"
#include "media/capture/video/win/sink_input_pin_win.h"
#include "media/capture/video_capture_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace base {
class Location;
@@ -156,7 +156,7 @@ class VideoCaptureDeviceWin : public VideoCaptureDevice,
bool enable_get_photo_state_;
- base::Optional<int> camera_rotation_;
+ absl::optional<int> camera_rotation_;
DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceWin);
};
diff --git a/chromium/media/capture/video_capture_types.h b/chromium/media/capture/video_capture_types.h
index 051b9765f16..f3c2dfd0303 100644
--- a/chromium/media/capture/video_capture_types.h
+++ b/chromium/media/capture/video_capture_types.h
@@ -9,11 +9,11 @@
#include <vector>
-#include "base/optional.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "media/base/video_types.h"
#include "media/capture/capture_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
diff --git a/chromium/media/cast/BUILD.gn b/chromium/media/cast/BUILD.gn
index 242ea4039d9..9a69682a21c 100644
--- a/chromium/media/cast/BUILD.gn
+++ b/chromium/media/cast/BUILD.gn
@@ -182,25 +182,25 @@ source_set("sender") {
}
}
-source_set("receiver") {
+source_set("test_receiver") {
sources = [
- "cast_receiver.h",
- "net/rtp/cast_message_builder.cc",
- "net/rtp/cast_message_builder.h",
- "net/rtp/frame_buffer.cc",
- "net/rtp/frame_buffer.h",
- "net/rtp/framer.cc",
- "net/rtp/framer.h",
- "net/rtp/receiver_stats.cc",
- "net/rtp/receiver_stats.h",
- "receiver/audio_decoder.cc",
- "receiver/audio_decoder.h",
- "receiver/cast_receiver_impl.cc",
- "receiver/cast_receiver_impl.h",
- "receiver/frame_receiver.cc",
- "receiver/frame_receiver.h",
- "receiver/video_decoder.cc",
- "receiver/video_decoder.h",
+ "test/receiver/audio_decoder.cc",
+ "test/receiver/audio_decoder.h",
+ "test/receiver/cast_message_builder.cc",
+ "test/receiver/cast_message_builder.h",
+ "test/receiver/cast_receiver.h",
+ "test/receiver/cast_receiver_impl.cc",
+ "test/receiver/cast_receiver_impl.h",
+ "test/receiver/frame_buffer.cc",
+ "test/receiver/frame_buffer.h",
+ "test/receiver/frame_receiver.cc",
+ "test/receiver/frame_receiver.h",
+ "test/receiver/framer.cc",
+ "test/receiver/framer.h",
+ "test/receiver/receiver_stats.cc",
+ "test/receiver/receiver_stats.h",
+ "test/receiver/video_decoder.cc",
+ "test/receiver/video_decoder.h",
]
deps = [
@@ -252,8 +252,8 @@ static_library("test_support") {
deps = [
":net",
- ":receiver",
":sender",
+ ":test_receiver",
"//base/test:test_support",
"//media",
"//net",
@@ -301,22 +301,15 @@ test("cast_unittests") {
# files.
"net/rtcp/test_rtcp_packet_builder.cc",
"net/rtcp/test_rtcp_packet_builder.h",
- "net/rtp/cast_message_builder_unittest.cc",
- "net/rtp/frame_buffer_unittest.cc",
- "net/rtp/framer_unittest.cc",
"net/rtp/mock_rtp_payload_feedback.cc",
"net/rtp/mock_rtp_payload_feedback.h",
"net/rtp/packet_storage_unittest.cc",
- "net/rtp/receiver_stats_unittest.cc",
"net/rtp/rtp_packet_builder.cc",
"net/rtp/rtp_packet_builder.h",
"net/rtp/rtp_packetizer_unittest.cc",
"net/rtp/rtp_parser_unittest.cc",
"net/udp_packet_pipe_unittest.cc",
"net/udp_transport_unittest.cc",
- "receiver/audio_decoder_unittest.cc",
- "receiver/frame_receiver_unittest.cc",
- "receiver/video_decoder_unittest.cc",
"sender/audio_encoder_unittest.cc",
"sender/audio_sender_unittest.cc",
"sender/congestion_control_unittest.cc",
@@ -327,6 +320,13 @@ test("cast_unittests") {
"sender/video_sender_unittest.cc",
"sender/vp8_quantizer_parser_unittest.cc",
"test/end2end_unittest.cc",
+ "test/receiver/audio_decoder_unittest.cc",
+ "test/receiver/cast_message_builder_unittest.cc",
+ "test/receiver/frame_buffer_unittest.cc",
+ "test/receiver/frame_receiver_unittest.cc",
+ "test/receiver/framer_unittest.cc",
+ "test/receiver/receiver_stats_unittest.cc",
+ "test/receiver/video_decoder_unittest.cc",
"test/utility/audio_utility_unittest.cc",
"test/utility/barcode_unittest.cc",
]
@@ -334,8 +334,8 @@ test("cast_unittests") {
deps = [
":common",
":net",
- ":receiver",
":sender",
+ ":test_receiver",
":test_support",
"//base",
"//base:cfi_buildflags",
@@ -386,8 +386,8 @@ if (is_win || is_mac || is_linux || is_chromeos_lacros) {
deps = [
":common",
":net",
- ":receiver",
":sender",
+ ":test_receiver",
":test_support",
"//base",
"//base/test:test_support",
@@ -424,8 +424,8 @@ if (is_win || is_mac || is_linux || is_chromeos_lacros) {
":common",
":net",
":network_simulation_model_proto",
- ":receiver",
":sender",
+ ":test_receiver",
":test_support",
"//base",
"//base/test:test_support",
@@ -499,5 +499,5 @@ static_library("cast_sender") {
static_library("cast_receiver") {
complete_static_lib = true
configs -= [ "//build/config/compiler:thin_archive" ]
- deps = [ ":receiver" ]
+ deps = [ ":test_receiver" ]
}
diff --git a/chromium/media/cast/DIR_METADATA b/chromium/media/cast/DIR_METADATA
index 9e255559a4f..7c577c4a958 100644
--- a/chromium/media/cast/DIR_METADATA
+++ b/chromium/media/cast/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Internals>Cast>Streaming"
diff --git a/chromium/media/cast/OWNERS b/chromium/media/cast/OWNERS
index 866a0313dc6..736f33990db 100644
--- a/chromium/media/cast/OWNERS
+++ b/chromium/media/cast/OWNERS
@@ -1,2 +1,3 @@
jophba@chromium.org
mfoltz@chromium.org
+rwkeane@google.com
diff --git a/chromium/media/cast/README.md b/chromium/media/cast/README.md
index 5d28612985f..679e0a2efdb 100644
--- a/chromium/media/cast/README.md
+++ b/chromium/media/cast/README.md
@@ -18,11 +18,11 @@ jophba@chromium.org for details.
* net/ - Wire-level packetization and pacing.
-* receiver/ - A minimal receiver implementation, used only for end-to-end
- testing.
-
* sender/ - Encoder front-ends and frame-level sender implementation for
audio/video.
* test/ - A collection of end-to-end tests, experiments, benchmarks, and related
utility code.
+
+* test/receiver/ - A minimal receiver implementation, used only for end-to-end
+ testing.
diff --git a/chromium/media/cast/cast_config.h b/chromium/media/cast/cast_config.h
index 67d156c604a..9a9f84c1f1c 100644
--- a/chromium/media/cast/cast_config.h
+++ b/chromium/media/cast/cast_config.h
@@ -245,7 +245,6 @@ struct FrameReceiverConfig {
std::string aes_iv_mask;
};
-// TODO(miu): Remove the CreateVEA callbacks. http://crbug.com/454029
typedef base::OnceCallback<void(scoped_refptr<base::SingleThreadTaskRunner>,
std::unique_ptr<media::VideoEncodeAccelerator>)>
ReceiveVideoEncodeAcceleratorCallback;
@@ -253,10 +252,6 @@ typedef base::RepeatingCallback<void(ReceiveVideoEncodeAcceleratorCallback)>
CreateVideoEncodeAcceleratorCallback;
typedef base::OnceCallback<void(base::UnsafeSharedMemoryRegion)>
ReceiveVideoEncodeMemoryCallback;
-typedef base::RepeatingCallback<void(size_t size,
- ReceiveVideoEncodeMemoryCallback)>
- CreateVideoEncodeMemoryCallback;
-
} // namespace cast
} // namespace media
diff --git a/chromium/media/cast/cast_environment.h b/chromium/media/cast/cast_environment.h
index bff6604efe7..7af484e17c0 100644
--- a/chromium/media/cast/cast_environment.h
+++ b/chromium/media/cast/cast_environment.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_CAST_CAST_ENVIRONMENT_H_
#define MEDIA_CAST_CAST_ENVIRONMENT_H_
-#include <memory>
-
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/media/cast/cast_receiver.h b/chromium/media/cast/cast_receiver.h
deleted file mode 100644
index 659531b132c..00000000000
--- a/chromium/media/cast/cast_receiver.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2013 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.
-//
-// This is the main interface for the cast receiver. All configuration are done
-// at creation.
-
-#ifndef MEDIA_CAST_CAST_RECEIVER_H_
-#define MEDIA_CAST_CAST_RECEIVER_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
-#include "media/base/audio_bus.h"
-#include "media/cast/cast_config.h"
-#include "media/cast/cast_environment.h"
-#include "media/cast/net/cast_transport.h"
-
-namespace media {
-class VideoFrame;
-
-namespace cast {
-
-// The following callbacks are used to deliver decoded audio/video frame data,
-// the frame's corresponding play-out time, and a continuity flag.
-// |is_continuous| will be false to indicate the loss of data due to a loss of
-// frames (or decoding errors). This allows the client to take steps to smooth
-// discontinuities for playback. Note: A NULL pointer can be returned when data
-// is not available (e.g., bad/missing packet).
-using AudioFrameDecodedCallback =
- base::RepeatingCallback<void(std::unique_ptr<AudioBus> audio_bus,
- base::TimeTicks playout_time,
- bool is_continuous)>;
-// TODO(miu): |video_frame| includes a timestamp, so use that instead.
-using VideoFrameDecodedCallback =
- base::RepeatingCallback<void(scoped_refptr<media::VideoFrame> video_frame,
- base::TimeTicks playout_time,
- bool is_continuous)>;
-
-class CastReceiver {
- public:
- static std::unique_ptr<CastReceiver> Create(
- scoped_refptr<CastEnvironment> cast_environment,
- const FrameReceiverConfig& audio_config,
- const FrameReceiverConfig& video_config,
- CastTransport* const transport);
-
- // All received RTP and RTCP packets for the call should be sent to this
- // PacketReceiver. Can be called from any thread.
- virtual void ReceivePacket(std::unique_ptr<Packet> packet) = 0;
-
- // Polling interface to get audio and video frames from the CastReceiver. The
- // the RequestDecodedXXXXXFrame() methods utilize internal software-based
- // decoding.
- //
- // In all cases, the given |callback| is guaranteed to be run at some point in
- // the future, except for those requests still enqueued at destruction time.
- //
- // These methods should all be called on the CastEnvironment's MAIN thread.
- virtual void RequestDecodedAudioFrame(
- const AudioFrameDecodedCallback& callback) = 0;
- virtual void RequestDecodedVideoFrame(
- const VideoFrameDecodedCallback& callback) = 0;
-
- virtual ~CastReceiver() {}
-};
-
-} // namespace cast
-} // namespace media
-
-#endif // MEDIA_CAST_CAST_RECEIVER_H_
diff --git a/chromium/media/cast/cast_sender.h b/chromium/media/cast/cast_sender.h
index 48b2d3d33d6..7784d60f42a 100644
--- a/chromium/media/cast/cast_sender.h
+++ b/chromium/media/cast/cast_sender.h
@@ -108,13 +108,10 @@ class CastSender {
// Initialize the video stack. Must be called in order to send video frames.
// |status_change_cb| will be run as operational status changes.
- //
- // TODO(miu): Remove the VEA-specific callbacks. http://crbug.com/454029
virtual void InitializeVideo(
const FrameSenderConfig& video_config,
const StatusChangeCallback& status_change_cb,
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) = 0;
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb) = 0;
// Change the target delay. This is only valid if the receiver
// supports the "adaptive_target_delay" rtp extension.
diff --git a/chromium/media/cast/cast_sender_impl.cc b/chromium/media/cast/cast_sender_impl.cc
index 5882ea199c7..37a89f7e064 100644
--- a/chromium/media/cast/cast_sender_impl.cc
+++ b/chromium/media/cast/cast_sender_impl.cc
@@ -126,8 +126,7 @@ void CastSenderImpl::InitializeAudio(
void CastSenderImpl::InitializeVideo(
const FrameSenderConfig& video_config,
const StatusChangeCallback& status_change_cb,
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) {
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb) {
DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
VLOG(1) << "CastSenderImpl@" << this << "::InitializeVideo()";
@@ -137,7 +136,7 @@ void CastSenderImpl::InitializeVideo(
cast_environment_, video_config,
base::BindRepeating(&CastSenderImpl::OnVideoStatusChange,
weak_factory_.GetWeakPtr(), status_change_cb),
- create_vea_cb, create_video_encode_mem_cb, transport_sender_,
+ create_vea_cb, transport_sender_,
base::BindRepeating(&CastSenderImpl::SetTargetPlayoutDelay,
weak_factory_.GetWeakPtr()),
media::VideoCaptureFeedbackCB());
diff --git a/chromium/media/cast/cast_sender_impl.h b/chromium/media/cast/cast_sender_impl.h
index cb8cbe98fa2..df50674851b 100644
--- a/chromium/media/cast/cast_sender_impl.h
+++ b/chromium/media/cast/cast_sender_impl.h
@@ -31,8 +31,7 @@ class CastSenderImpl final : public CastSender {
void InitializeVideo(
const FrameSenderConfig& video_config,
const StatusChangeCallback& status_change_cb,
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) final;
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb) final;
void SetTargetPlayoutDelay(base::TimeDelta new_target_playout_delay) final;
diff --git a/chromium/media/cast/common/mod_util.h b/chromium/media/cast/common/mod_util.h
index fc68c63f26f..2761df66d0b 100644
--- a/chromium/media/cast/common/mod_util.h
+++ b/chromium/media/cast/common/mod_util.h
@@ -5,7 +5,6 @@
#ifndef MEDIA_CAST_COMMON_MOD_UTIL_H_
#define MEDIA_CAST_COMMON_MOD_UTIL_H_
-#include <map>
#include "base/check.h"
namespace media {
diff --git a/chromium/media/cast/logging/logging_defines.h b/chromium/media/cast/logging/logging_defines.h
index 0199c45ae5a..c3a668cfa67 100644
--- a/chromium/media/cast/logging/logging_defines.h
+++ b/chromium/media/cast/logging/logging_defines.h
@@ -8,10 +8,6 @@
#include <stddef.h>
#include <stdint.h>
-#include <map>
-#include <string>
-#include <vector>
-
#include "base/time/time.h"
#include "media/cast/common/frame_id.h"
#include "media/cast/common/rtp_time.h"
diff --git a/chromium/media/cast/logging/stats_event_subscriber.h b/chromium/media/cast/logging/stats_event_subscriber.h
index 8c88c920f84..b2e2b410c54 100644
--- a/chromium/media/cast/logging/stats_event_subscriber.h
+++ b/chromium/media/cast/logging/stats_event_subscriber.h
@@ -8,7 +8,10 @@
#include <stddef.h>
#include <stdint.h>
+#include <map>
#include <memory>
+#include <utility>
+#include <vector>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
diff --git a/chromium/media/cast/net/cast_transport_defines.h b/chromium/media/cast/net/cast_transport_defines.h
index a9e0a407a25..7c11de2da03 100644
--- a/chromium/media/cast/net/cast_transport_defines.h
+++ b/chromium/media/cast/net/cast_transport_defines.h
@@ -15,7 +15,6 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
#include "media/cast/common/frame_id.h"
namespace media {
diff --git a/chromium/media/cast/net/rtcp/receiver_rtcp_session.h b/chromium/media/cast/net/rtcp/receiver_rtcp_session.h
index 5b95a87973f..166f91b6304 100644
--- a/chromium/media/cast/net/rtcp/receiver_rtcp_session.h
+++ b/chromium/media/cast/net/rtcp/receiver_rtcp_session.h
@@ -9,7 +9,6 @@
#include "media/cast/common/clock_drift_smoother.h"
#include "media/cast/net/pacing/paced_sender.h"
#include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h"
-#include "media/cast/net/rtcp/receiver_rtcp_session.h"
#include "media/cast/net/rtcp/rtcp_defines.h"
#include "media/cast/net/rtcp/rtcp_session.h"
#include "media/cast/net/rtcp/rtcp_utility.h"
diff --git a/chromium/media/cast/net/rtcp/rtcp_builder.h b/chromium/media/cast/net/rtcp/rtcp_builder.h
index 7ff7050d0aa..10bd90475ff 100644
--- a/chromium/media/cast/net/rtcp/rtcp_builder.h
+++ b/chromium/media/cast/net/rtcp/rtcp_builder.h
@@ -8,9 +8,6 @@
#include <stddef.h>
#include <stdint.h>
-#include <list>
-#include <string>
-
#include "base/big_endian.h"
#include "base/macros.h"
#include "media/cast/net/cast_transport_config.h"
diff --git a/chromium/media/cast/net/rtcp/rtcp_defines.h b/chromium/media/cast/net/rtcp/rtcp_defines.h
index 51f39259aae..d309149c05b 100644
--- a/chromium/media/cast/net/rtcp/rtcp_defines.h
+++ b/chromium/media/cast/net/rtcp/rtcp_defines.h
@@ -13,7 +13,6 @@
#include <utility>
#include <vector>
-#include "base/callback_forward.h"
#include "base/macros.h"
#include "media/cast/logging/logging_defines.h"
#include "media/cast/net/cast_transport_defines.h"
diff --git a/chromium/media/cast/net/rtp/cast_message_builder.cc b/chromium/media/cast/net/rtp/cast_message_builder.cc
deleted file mode 100644
index 61a152b53a1..00000000000
--- a/chromium/media/cast/net/rtp/cast_message_builder.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2014 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 "media/cast/net/rtp/cast_message_builder.h"
-
-#include "base/logging.h"
-#include "media/cast/constants.h"
-#include "media/cast/net/rtp/framer.h"
-
-namespace media {
-namespace cast {
-
-namespace {
-
-// TODO(miu): These should probably be dynamic and computed base on configured
-// end-to-end latency and packet loss rates. http://crbug.com/563784
-enum {
- // Number of milliseconds between sending of ACK/NACK Cast Message RTCP
- // packets back to the sender.
- kCastMessageUpdateIntervalMs = 33,
-
- // Number of milliseconds between repeating a NACK for packets in the same
- // frame.
- kNackRepeatIntervalMs = 30,
-};
-
-} // namespace
-
-CastMessageBuilder::CastMessageBuilder(
- const base::TickClock* clock,
- RtpPayloadFeedback* incoming_payload_feedback,
- const Framer* framer,
- uint32_t media_ssrc,
- bool decoder_faster_than_max_frame_rate,
- int max_unacked_frames)
- : clock_(clock),
- cast_feedback_(incoming_payload_feedback),
- framer_(framer),
- media_ssrc_(media_ssrc),
- decoder_faster_than_max_frame_rate_(decoder_faster_than_max_frame_rate),
- max_unacked_frames_(max_unacked_frames),
- cast_msg_(media_ssrc),
- slowing_down_ack_(false),
- acked_last_frame_(true) {
- cast_msg_.ack_frame_id = FrameId::first() - 1;
-}
-
-CastMessageBuilder::~CastMessageBuilder() = default;
-
-void CastMessageBuilder::CompleteFrameReceived(FrameId frame_id) {
- DCHECK_GE(frame_id, last_acked_frame_id());
- VLOG(2) << "CompleteFrameReceived: " << frame_id;
- if (last_update_time_.is_null()) {
- // Our first update.
- last_update_time_ = clock_->NowTicks();
- }
-
- if (!UpdateAckMessage(frame_id)) {
- return;
- }
- BuildPacketList();
-
- // Send cast message.
- VLOG(2) << "Send cast message Ack:" << frame_id;
- cast_feedback_->CastFeedback(cast_msg_);
-}
-
-bool CastMessageBuilder::UpdateAckMessage(FrameId frame_id) {
- if (!decoder_faster_than_max_frame_rate_) {
- int complete_frame_count = framer_->NumberOfCompleteFrames();
- if (complete_frame_count > max_unacked_frames_) {
- // We have too many frames pending in our framer; slow down ACK.
- if (!slowing_down_ack_) {
- slowing_down_ack_ = true;
- ack_queue_.push_back(last_acked_frame_id());
- }
- } else if (complete_frame_count <= 1) {
- // We are down to one or less frames in our framer; ACK normally.
- slowing_down_ack_ = false;
- ack_queue_.clear();
- }
- }
-
- if (slowing_down_ack_) {
- // We are slowing down acknowledgment by acknowledging every other frame.
- // Note: frame skipping and slowdown ACK is not supported at the same
- // time; and it's not needed since we can skip frames to catch up.
- if (!ack_queue_.empty() && ack_queue_.back() == frame_id) {
- return false;
- }
- ack_queue_.push_back(frame_id);
- if (!acked_last_frame_) {
- ack_queue_.pop_front();
- }
- frame_id = ack_queue_.front();
- }
-
- // Is it a new frame?
- if (last_acked_frame_id() == frame_id) {
- acked_last_frame_ = false;
- return false;
- }
- acked_last_frame_ = true;
- cast_msg_.ack_frame_id = frame_id;
- cast_msg_.missing_frames_and_packets.clear();
- last_update_time_ = clock_->NowTicks();
- time_last_nacked_map_.erase(
- time_last_nacked_map_.begin(),
- time_last_nacked_map_.upper_bound(last_acked_frame_id()));
- return true;
-}
-
-bool CastMessageBuilder::TimeToSendNextCastMessage(
- base::TimeTicks* time_to_send) {
- // We haven't received any packets.
- if (last_update_time_.is_null() && framer_->Empty())
- return false;
-
- *time_to_send = last_update_time_ + base::TimeDelta::FromMilliseconds(
- kCastMessageUpdateIntervalMs);
- return true;
-}
-
-void CastMessageBuilder::UpdateCastMessage() {
- RtcpCastMessage message(media_ssrc_);
- if (!UpdateCastMessageInternal(&message))
- return;
-
- // Send cast message.
- cast_feedback_->CastFeedback(message);
-}
-
-bool CastMessageBuilder::UpdateCastMessageInternal(RtcpCastMessage* message) {
- if (last_update_time_.is_null()) {
- if (!framer_->Empty()) {
- // We have received packets.
- last_update_time_ = clock_->NowTicks();
- }
- return false;
- }
-
- // Is it time to update the cast message?
- base::TimeTicks now = clock_->NowTicks();
- if (now - last_update_time_ <
- base::TimeDelta::FromMilliseconds(kCastMessageUpdateIntervalMs)) {
- return false;
- }
- last_update_time_ = now;
-
- // Needed to cover when a frame is skipped.
- UpdateAckMessage(last_acked_frame_id());
- BuildPacketList();
- *message = cast_msg_;
- return true;
-}
-
-void CastMessageBuilder::BuildPacketList() {
- base::TimeTicks now = clock_->NowTicks();
-
- // Clear message NACK list.
- cast_msg_.missing_frames_and_packets.clear();
-
- // Are we missing packets?
- if (framer_->Empty())
- return;
-
- const FrameId newest_frame_id = framer_->newest_frame_id();
- FrameId next_expected_frame_id = last_acked_frame_id() + 1;
-
- // Iterate over all frames.
- for (; next_expected_frame_id <= newest_frame_id; ++next_expected_frame_id) {
- const auto it = time_last_nacked_map_.find(next_expected_frame_id);
- if (it != time_last_nacked_map_.end()) {
- // We have sent a NACK in this frame before, make sure enough time have
- // passed.
- if (now - it->second <
- base::TimeDelta::FromMilliseconds(kNackRepeatIntervalMs)) {
- continue;
- }
- }
-
- PacketIdSet missing;
- if (framer_->FrameExists(next_expected_frame_id)) {
- bool last_frame = (newest_frame_id == next_expected_frame_id);
- framer_->GetMissingPackets(
- next_expected_frame_id, last_frame, &missing);
- if (!missing.empty()) {
- time_last_nacked_map_[next_expected_frame_id] = now;
- cast_msg_.missing_frames_and_packets.insert(
- std::make_pair(next_expected_frame_id, missing));
- }
- } else {
- time_last_nacked_map_[next_expected_frame_id] = now;
- missing.insert(kRtcpCastAllPacketsLost);
- cast_msg_.missing_frames_and_packets[next_expected_frame_id] = missing;
- }
- }
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/net/rtp/cast_message_builder.h b/chromium/media/cast/net/rtp/cast_message_builder.h
deleted file mode 100644
index 9afd8c19752..00000000000
--- a/chromium/media/cast/net/rtp/cast_message_builder.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2014 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.
-
-// Handles NACK list and manages ACK.
-
-#ifndef MEDIA_CAST_NET_RTP_CAST_MESSAGE_BUILDER_H_
-#define MEDIA_CAST_NET_RTP_CAST_MESSAGE_BUILDER_H_
-
-#include <stdint.h>
-
-#include <map>
-
-#include "base/containers/circular_deque.h"
-#include "base/time/tick_clock.h"
-#include "media/cast/net/rtp/rtp_defines.h"
-
-namespace media {
-namespace cast {
-
-class Framer;
-class RtpPayloadFeedback;
-
-class CastMessageBuilder {
- public:
- CastMessageBuilder(const base::TickClock* clock,
- RtpPayloadFeedback* incoming_payload_feedback,
- const Framer* framer,
- uint32_t media_ssrc,
- bool decoder_faster_than_max_frame_rate,
- int max_unacked_frames);
- ~CastMessageBuilder();
-
- void CompleteFrameReceived(FrameId frame_id);
- bool TimeToSendNextCastMessage(base::TimeTicks* time_to_send);
- void UpdateCastMessage();
-
- private:
- bool UpdateAckMessage(FrameId frame_id);
- void BuildPacketList();
- bool UpdateCastMessageInternal(RtcpCastMessage* message);
-
- FrameId last_acked_frame_id() const { return cast_msg_.ack_frame_id; }
-
- const base::TickClock* const clock_; // Not owned by this class.
- RtpPayloadFeedback* const cast_feedback_;
-
- // CastMessageBuilder has only const access to the framer.
- const Framer* const framer_;
- const uint32_t media_ssrc_;
- const bool decoder_faster_than_max_frame_rate_;
- const int max_unacked_frames_;
-
- RtcpCastMessage cast_msg_;
- base::TimeTicks last_update_time_;
-
- std::map<FrameId, base::TimeTicks> time_last_nacked_map_;
-
- bool slowing_down_ack_;
- bool acked_last_frame_;
- base::circular_deque<FrameId> ack_queue_;
-
- DISALLOW_COPY_AND_ASSIGN(CastMessageBuilder);
-};
-
-} // namespace cast
-} // namespace media
-
-#endif // MEDIA_CAST_NET_RTP_CAST_MESSAGE_BUILDER_H_
diff --git a/chromium/media/cast/net/rtp/cast_message_builder_unittest.cc b/chromium/media/cast/net/rtp/cast_message_builder_unittest.cc
deleted file mode 100644
index 370a5751cf4..00000000000
--- a/chromium/media/cast/net/rtp/cast_message_builder_unittest.cc
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright 2014 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 "media/cast/net/rtp/cast_message_builder.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "media/cast/net/rtcp/rtcp_defines.h"
-#include "media/cast/net/rtp/framer.h"
-#include "media/cast/net/rtp/rtp_defines.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace media {
-namespace cast {
-
-namespace {
-static const uint32_t kSsrc = 0x1234;
-static const uint32_t kShortTimeIncrementMs = 10;
-static const uint32_t kLongTimeIncrementMs = 40;
-static const int64_t kStartMillisecond = INT64_C(12345678900000);
-
-typedef std::map<FrameId, size_t> MissingPacketsMap;
-
-class NackFeedbackVerification : public RtpPayloadFeedback {
- public:
- NackFeedbackVerification() : triggered_(false) {}
-
- void CastFeedback(const RtcpCastMessage& cast_feedback) final {
- EXPECT_EQ(kSsrc, cast_feedback.remote_ssrc);
-
- last_frame_acked_ = cast_feedback.ack_frame_id;
-
- auto frame_it = cast_feedback.missing_frames_and_packets.begin();
-
- // Keep track of the number of missing packets per frame.
- missing_packets_.clear();
- while (frame_it != cast_feedback.missing_frames_and_packets.end()) {
- // Check for complete frame lost.
- if ((frame_it->second.size() == 1) &&
- (*frame_it->second.begin() == kRtcpCastAllPacketsLost)) {
- missing_packets_.insert(
- std::make_pair(frame_it->first, kRtcpCastAllPacketsLost));
- } else {
- missing_packets_.insert(
- std::make_pair(frame_it->first, frame_it->second.size()));
- }
- ++frame_it;
- }
- triggered_ = true;
- }
-
- size_t num_missing_packets(FrameId frame_id) {
- MissingPacketsMap::iterator it;
- it = missing_packets_.find(frame_id);
- if (it == missing_packets_.end())
- return 0;
-
- return it->second;
- }
-
- // Holds value for one call.
- bool triggered() {
- bool ret_val = triggered_;
- triggered_ = false;
- return ret_val;
- }
-
- FrameId last_frame_acked() { return last_frame_acked_; }
-
- private:
- bool triggered_;
- MissingPacketsMap missing_packets_; // Missing packets per frame.
- FrameId last_frame_acked_;
-
- DISALLOW_COPY_AND_ASSIGN(NackFeedbackVerification);
-};
-} // namespace
-
-class CastMessageBuilderTest : public ::testing::Test {
- protected:
- CastMessageBuilderTest()
- : framer_(&testing_clock_,
- &feedback_,
- kSsrc,
- true,
- 10),
- cast_msg_builder_(new CastMessageBuilder(&testing_clock_,
- &feedback_,
- &framer_,
- kSsrc,
- true,
- 0)) {
- rtp_header_.sender_ssrc = kSsrc;
- rtp_header_.is_key_frame = false;
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kStartMillisecond));
- }
-
- ~CastMessageBuilderTest() override = default;
-
- void SetFrameIds(FrameId frame_id, FrameId reference_frame_id) {
- rtp_header_.frame_id = frame_id;
- rtp_header_.reference_frame_id = reference_frame_id;
- }
-
- void SetPacketId(uint16_t packet_id) { rtp_header_.packet_id = packet_id; }
-
- void SetMaxPacketId(uint16_t max_packet_id) {
- rtp_header_.max_packet_id = max_packet_id;
- }
-
- void SetKeyFrame(bool is_key) { rtp_header_.is_key_frame = is_key; }
-
- void InsertPacket() {
- bool duplicate;
- uint8_t payload = 0;
- if (framer_.InsertPacket(&payload, 1, rtp_header_, &duplicate)) {
- cast_msg_builder_->CompleteFrameReceived(rtp_header_.frame_id);
- }
- cast_msg_builder_->UpdateCastMessage();
- }
-
- void SetDecoderSlowerThanMaxFrameRate(int max_unacked_frames) {
- cast_msg_builder_ = std::make_unique<CastMessageBuilder>(
- &testing_clock_, &feedback_, &framer_, kSsrc, false,
- max_unacked_frames);
- }
-
- NackFeedbackVerification feedback_;
- Framer framer_;
- std::unique_ptr<CastMessageBuilder> cast_msg_builder_;
- RtpCastHeader rtp_header_;
- base::SimpleTestTickClock testing_clock_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CastMessageBuilderTest);
-};
-
-TEST_F(CastMessageBuilderTest, OneFrameNackList) {
- SetFrameIds(FrameId::first(), FrameId::first());
- SetPacketId(4);
- SetMaxPacketId(10);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- EXPECT_FALSE(feedback_.triggered());
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetPacketId(5);
- InsertPacket();
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(4u, feedback_.num_missing_packets(FrameId::first()));
-}
-
-TEST_F(CastMessageBuilderTest, CompleteFrameMissing) {
- SetFrameIds(FrameId::first(), FrameId::first());
- SetPacketId(2);
- SetMaxPacketId(5);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameIds(FrameId::first() + 2, FrameId::first() + 1);
- SetPacketId(2);
- SetMaxPacketId(5);
- InsertPacket();
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(kRtcpCastAllPacketsLost,
- feedback_.num_missing_packets(FrameId::first() + 1));
-}
-
-TEST_F(CastMessageBuilderTest, ReleaseFrames) {
- SetFrameIds(FrameId::first() + 1, FrameId::first());
- SetPacketId(0);
- SetMaxPacketId(1);
- InsertPacket();
- EXPECT_FALSE(feedback_.triggered());
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameIds(FrameId::first() + 2, FrameId::first() + 1);
- SetPacketId(0);
- SetMaxPacketId(0);
- InsertPacket();
- EXPECT_TRUE(feedback_.triggered());
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameIds(FrameId::first() + 3, FrameId::first() + 2);
- SetPacketId(0);
- SetMaxPacketId(5);
- InsertPacket();
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(FrameId::first() + 2, feedback_.last_frame_acked());
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameIds(FrameId::first() + 5, FrameId::first() + 5);
- SetPacketId(0);
- SetMaxPacketId(0);
- SetKeyFrame(true);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- // Simulate 5 being pulled for rendering.
- framer_.ReleaseFrame(FrameId::first() + 5);
- cast_msg_builder_->UpdateCastMessage();
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(FrameId::first() + 5, feedback_.last_frame_acked());
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- SetFrameIds(FrameId::first() + 1, FrameId::first());
- SetPacketId(1);
- SetMaxPacketId(1);
- InsertPacket();
- EXPECT_FALSE(feedback_.triggered());
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- InsertPacket();
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(FrameId::first() + 5, feedback_.last_frame_acked());
-}
-
-TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacket) {
- SetFrameIds(FrameId::first(), FrameId::first());
- SetPacketId(0);
- SetMaxPacketId(20);
- SetKeyFrame(true);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetPacketId(5);
- InsertPacket();
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(4u, feedback_.num_missing_packets(FrameId::first()));
-}
-
-TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextFrame) {
- SetFrameIds(FrameId::first(), FrameId::first());
- SetPacketId(0);
- SetMaxPacketId(20);
- SetKeyFrame(true);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetPacketId(5);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(4u, feedback_.num_missing_packets(FrameId::first()));
- SetFrameIds(FrameId::first() + 1, FrameId::first());
- SetMaxPacketId(2);
- SetPacketId(0);
- SetKeyFrame(false);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(19u, feedback_.num_missing_packets(FrameId::first()));
-}
-
-TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextKey) {
- SetFrameIds(FrameId::first(), FrameId::first());
- SetPacketId(0);
- SetMaxPacketId(20);
- SetKeyFrame(true);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetPacketId(5);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(4u, feedback_.num_missing_packets(FrameId::first()));
- SetFrameIds(FrameId::first() + 1, FrameId::first() + 1);
- SetMaxPacketId(0);
- SetPacketId(0);
- SetKeyFrame(true);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(0u, feedback_.num_missing_packets(FrameId::first()));
-}
-
-TEST_F(CastMessageBuilderTest, BasicRps) {
- SetFrameIds(FrameId::first(), FrameId::first());
- SetPacketId(0);
- SetMaxPacketId(0);
- SetKeyFrame(true);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(FrameId::first(), feedback_.last_frame_acked());
- SetFrameIds(FrameId::first() + 3, FrameId::first());
- SetKeyFrame(false);
- InsertPacket();
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(FrameId::first() + 3, feedback_.last_frame_acked());
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- // Simulate 3 being pulled for rendering.
- framer_.ReleaseFrame(FrameId::first() + 3);
- cast_msg_builder_->UpdateCastMessage();
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(FrameId::first() + 3, feedback_.last_frame_acked());
-}
-
-TEST_F(CastMessageBuilderTest, InOrderRps) {
- // Create a pattern - skip to rps, and don't look back.
- SetFrameIds(FrameId::first(), FrameId::first());
- SetPacketId(0);
- SetMaxPacketId(0);
- SetKeyFrame(true);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(FrameId::first(), feedback_.last_frame_acked());
- SetFrameIds(FrameId::first() + 1, FrameId::first());
- SetPacketId(0);
- SetMaxPacketId(1);
- SetKeyFrame(false);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- EXPECT_FALSE(feedback_.triggered());
- SetFrameIds(FrameId::first() + 3, FrameId::first());
- SetPacketId(0);
- SetMaxPacketId(0);
- SetKeyFrame(false);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- // Simulate 3 being pulled for rendering.
- framer_.ReleaseFrame(FrameId::first() + 3);
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- cast_msg_builder_->UpdateCastMessage();
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(FrameId::first() + 3, feedback_.last_frame_acked());
- // Make an old frame complete - should not trigger an ack.
- SetFrameIds(FrameId::first() + 1, FrameId::first());
- SetPacketId(1);
- SetMaxPacketId(1);
- SetKeyFrame(false);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- EXPECT_FALSE(feedback_.triggered());
- EXPECT_EQ(FrameId::first() + 3, feedback_.last_frame_acked());
-}
-
-TEST_F(CastMessageBuilderTest, SlowDownAck) {
- SetDecoderSlowerThanMaxFrameRate(3);
- SetFrameIds(FrameId::first(), FrameId::first());
- SetPacketId(0);
- SetMaxPacketId(0);
- SetKeyFrame(true);
- InsertPacket();
-
- FrameId frame_id;
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- SetKeyFrame(false);
- for (frame_id = FrameId::first() + 1; frame_id < FrameId::first() + 3;
- ++frame_id) {
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(frame_id - 1, feedback_.last_frame_acked());
- SetFrameIds(frame_id, frame_id - 1);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- }
- // We should now have entered the slowdown ACK state.
- FrameId expected_frame_id = FrameId::first() + 1;
- for (; frame_id < FrameId::first() + 10; ++frame_id) {
- if ((frame_id - FrameId::first()) % 2) {
- ++expected_frame_id;
- EXPECT_TRUE(feedback_.triggered());
- } else {
- EXPECT_FALSE(feedback_.triggered());
- }
- EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
- SetFrameIds(frame_id, frame_id - 1);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- }
- EXPECT_FALSE(feedback_.triggered());
- EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
-
- // Simulate frame_id being pulled for rendering.
- framer_.ReleaseFrame(frame_id);
- // We should now leave the slowdown ACK state.
- ++frame_id;
- SetFrameIds(frame_id, frame_id - 1);
- InsertPacket();
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- EXPECT_TRUE(feedback_.triggered());
- EXPECT_EQ(frame_id, feedback_.last_frame_acked());
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/net/rtp/frame_buffer.cc b/chromium/media/cast/net/rtp/frame_buffer.cc
deleted file mode 100644
index 255b5067157..00000000000
--- a/chromium/media/cast/net/rtp/frame_buffer.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2014 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 "media/cast/net/rtp/frame_buffer.h"
-
-#include "base/check_op.h"
-
-namespace media {
-namespace cast {
-
-FrameBuffer::FrameBuffer()
- : max_packet_id_(0),
- num_packets_received_(0),
- max_seen_packet_id_(0),
- new_playout_delay_ms_(0),
- is_key_frame_(false),
- total_data_size_(0),
- packets_() {}
-
-FrameBuffer::~FrameBuffer() = default;
-
-bool FrameBuffer::InsertPacket(const uint8_t* payload_data,
- size_t payload_size,
- const RtpCastHeader& rtp_header) {
- // Is this the first packet in the frame?
- if (packets_.empty()) {
- frame_id_ = rtp_header.frame_id;
- max_packet_id_ = rtp_header.max_packet_id;
- is_key_frame_ = rtp_header.is_key_frame;
- new_playout_delay_ms_ = rtp_header.new_playout_delay_ms;
- if (is_key_frame_)
- DCHECK_EQ(rtp_header.frame_id, rtp_header.reference_frame_id);
- last_referenced_frame_id_ = rtp_header.reference_frame_id;
- rtp_timestamp_ = rtp_header.rtp_timestamp;
- }
- // Is this the correct frame?
- if (rtp_header.frame_id != frame_id_)
- return false;
-
- // Insert every packet only once.
- if (packets_.find(rtp_header.packet_id) != packets_.end()) {
- return false;
- }
-
- std::vector<uint8_t> data;
- std::pair<PacketMap::iterator, bool> retval =
- packets_.insert(make_pair(rtp_header.packet_id, data));
-
- // Insert the packet.
- retval.first->second.resize(payload_size);
- std::copy(
- payload_data, payload_data + payload_size, retval.first->second.begin());
-
- ++num_packets_received_;
- max_seen_packet_id_ = std::max(max_seen_packet_id_, rtp_header.packet_id);
- total_data_size_ += payload_size;
- return true;
-}
-
-bool FrameBuffer::Complete() const {
- return num_packets_received_ - 1 == max_packet_id_;
-}
-
-bool FrameBuffer::AssembleEncodedFrame(EncodedFrame* frame) const {
- if (!Complete())
- return false;
-
- // Frame is complete -> construct.
- if (is_key_frame_)
- frame->dependency = EncodedFrame::KEY;
- else if (frame_id_ == last_referenced_frame_id_)
- frame->dependency = EncodedFrame::INDEPENDENT;
- else
- frame->dependency = EncodedFrame::DEPENDENT;
- frame->frame_id = frame_id_;
- frame->referenced_frame_id = last_referenced_frame_id_;
- frame->rtp_timestamp = rtp_timestamp_;
- frame->new_playout_delay_ms = new_playout_delay_ms_;
-
- // Build the data vector.
- frame->data.clear();
- frame->data.reserve(total_data_size_);
- PacketMap::const_iterator it;
- for (it = packets_.begin(); it != packets_.end(); ++it)
- frame->data.insert(frame->data.end(), it->second.begin(), it->second.end());
- return true;
-}
-
-void FrameBuffer::GetMissingPackets(bool newest_frame,
- PacketIdSet* missing_packets) const {
- // Missing packets capped by max_seen_packet_id_.
- // (Iff it's the latest frame)
- int maximum = newest_frame ? max_seen_packet_id_ : max_packet_id_;
- int packet = 0;
- for (auto i = packets_.begin(); i != packets_.end() && packet <= maximum;
- ++i) {
- int end = std::min<int>(i->first, maximum + 1);
- while (packet < end) {
- missing_packets->insert(packet);
- packet++;
- }
- packet++;
- }
- while (packet <= maximum) {
- missing_packets->insert(packet);
- packet++;
- }
-}
-
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/net/rtp/frame_buffer.h b/chromium/media/cast/net/rtp/frame_buffer.h
deleted file mode 100644
index 7f9b9859679..00000000000
--- a/chromium/media/cast/net/rtp/frame_buffer.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 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 MEDIA_CAST_NET_RTP_FRAME_BUFFER_H_
-#define MEDIA_CAST_NET_RTP_FRAME_BUFFER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <vector>
-
-#include "base/macros.h"
-#include "media/cast/common/rtp_time.h"
-#include "media/cast/net/cast_transport_config.h"
-#include "media/cast/net/rtp/rtp_defines.h"
-
-namespace media {
-namespace cast {
-
-typedef std::map<uint16_t, std::vector<uint8_t>> PacketMap;
-
-class FrameBuffer {
- public:
- FrameBuffer();
- ~FrameBuffer();
- bool InsertPacket(const uint8_t* payload_data,
- size_t payload_size,
- const RtpCastHeader& rtp_header);
- bool Complete() const;
-
- void GetMissingPackets(bool newest_frame, PacketIdSet* missing_packets) const;
-
- // If a frame is complete, sets the frame IDs and RTP timestamp in |frame|,
- // and also copies the data from all packets into the data field in |frame|.
- // Returns true if the frame was complete; false if incomplete and |frame|
- // remains unchanged.
- bool AssembleEncodedFrame(EncodedFrame* frame) const;
-
- bool is_key_frame() const { return is_key_frame_; }
- FrameId last_referenced_frame_id() const { return last_referenced_frame_id_; }
- FrameId frame_id() const { return frame_id_; }
-
- private:
- FrameId frame_id_;
- uint16_t max_packet_id_;
- uint16_t num_packets_received_;
- uint16_t max_seen_packet_id_;
- uint16_t new_playout_delay_ms_;
- bool is_key_frame_;
- size_t total_data_size_;
- FrameId last_referenced_frame_id_;
- RtpTimeTicks rtp_timestamp_;
- PacketMap packets_;
-
- DISALLOW_COPY_AND_ASSIGN(FrameBuffer);
-};
-
-} // namespace cast
-} // namespace media
-
-#endif // MEDIA_CAST_NET_RTP_FRAME_BUFFER_H_
diff --git a/chromium/media/cast/net/rtp/frame_buffer_unittest.cc b/chromium/media/cast/net/rtp/frame_buffer_unittest.cc
deleted file mode 100644
index 60f35378988..00000000000
--- a/chromium/media/cast/net/rtp/frame_buffer_unittest.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2014 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 <stdint.h>
-
-#include "base/macros.h"
-#include "media/cast/net/cast_transport_defines.h"
-#include "media/cast/net/rtp/frame_buffer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace media {
-namespace cast {
-
-class FrameBufferTest : public ::testing::Test {
- protected:
- FrameBufferTest() {
- payload_.assign(kMaxIpPacketSize, 0);
- rtp_header_.frame_id = FrameId::first();
- rtp_header_.reference_frame_id = FrameId::first();
- }
-
- ~FrameBufferTest() override = default;
-
- FrameBuffer buffer_;
- std::vector<uint8_t> payload_;
- RtpCastHeader rtp_header_;
-
- DISALLOW_COPY_AND_ASSIGN(FrameBufferTest);
-};
-
-TEST_F(FrameBufferTest, OnePacketInsertSanity) {
- rtp_header_.rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(3000));
- rtp_header_.is_key_frame = true;
- rtp_header_.frame_id = FrameId::first() + 5;
- rtp_header_.reference_frame_id = FrameId::first() + 5;
- buffer_.InsertPacket(&payload_[0], payload_.size(), rtp_header_);
- EncodedFrame frame;
- EXPECT_TRUE(buffer_.AssembleEncodedFrame(&frame));
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first() + 5, frame.frame_id);
- EXPECT_EQ(FrameId::first() + 5, frame.referenced_frame_id);
- EXPECT_EQ(3000u, frame.rtp_timestamp.lower_32_bits());
-}
-
-TEST_F(FrameBufferTest, EmptyBuffer) {
- EXPECT_FALSE(buffer_.Complete());
- EncodedFrame frame;
- EXPECT_FALSE(buffer_.AssembleEncodedFrame(&frame));
-}
-
-TEST_F(FrameBufferTest, DefaultOnePacketFrame) {
- buffer_.InsertPacket(&payload_[0], payload_.size(), rtp_header_);
- EXPECT_TRUE(buffer_.Complete());
- EXPECT_FALSE(buffer_.is_key_frame());
- EncodedFrame frame;
- EXPECT_TRUE(buffer_.AssembleEncodedFrame(&frame));
- EXPECT_EQ(payload_.size(), frame.data.size());
-}
-
-TEST_F(FrameBufferTest, MultiplePacketFrame) {
- rtp_header_.is_key_frame = true;
- rtp_header_.max_packet_id = 2;
- buffer_.InsertPacket(&payload_[0], payload_.size(), rtp_header_);
- ++rtp_header_.packet_id;
- buffer_.InsertPacket(&payload_[0], payload_.size(), rtp_header_);
- ++rtp_header_.packet_id;
- buffer_.InsertPacket(&payload_[0], payload_.size(), rtp_header_);
- ++rtp_header_.packet_id;
- EXPECT_TRUE(buffer_.Complete());
- EXPECT_TRUE(buffer_.is_key_frame());
- EncodedFrame frame;
- EXPECT_TRUE(buffer_.AssembleEncodedFrame(&frame));
- EXPECT_EQ(3 * payload_.size(), frame.data.size());
-}
-
-TEST_F(FrameBufferTest, IncompleteFrame) {
- rtp_header_.max_packet_id = 4;
- buffer_.InsertPacket(&payload_[0], payload_.size(), rtp_header_);
- ++rtp_header_.packet_id;
- buffer_.InsertPacket(&payload_[0], payload_.size(), rtp_header_);
- ++rtp_header_.packet_id;
- // Increment again - skip packet #2.
- ++rtp_header_.packet_id;
- buffer_.InsertPacket(&payload_[0], payload_.size(), rtp_header_);
- ++rtp_header_.packet_id;
- buffer_.InsertPacket(&payload_[0], payload_.size(), rtp_header_);
- EXPECT_FALSE(buffer_.Complete());
- // Insert missing packet.
- rtp_header_.packet_id = 2;
- buffer_.InsertPacket(&payload_[0], payload_.size(), rtp_header_);
- EXPECT_TRUE(buffer_.Complete());
-}
-
-} // namespace media
-} // namespace cast
diff --git a/chromium/media/cast/net/rtp/framer.cc b/chromium/media/cast/net/rtp/framer.cc
deleted file mode 100644
index 369c9db7a35..00000000000
--- a/chromium/media/cast/net/rtp/framer.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2014 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 "media/cast/net/rtp/framer.h"
-
-#include "base/logging.h"
-#include "media/cast/constants.h"
-
-namespace media {
-namespace cast {
-
-Framer::Framer(const base::TickClock* clock,
- RtpPayloadFeedback* incoming_payload_feedback,
- uint32_t ssrc,
- bool decoder_faster_than_max_frame_rate,
- int max_unacked_frames)
- : decoder_faster_than_max_frame_rate_(decoder_faster_than_max_frame_rate),
- cast_msg_builder_(clock,
- incoming_payload_feedback,
- this,
- ssrc,
- decoder_faster_than_max_frame_rate,
- max_unacked_frames),
- waiting_for_key_(true),
- last_released_frame_(FrameId::first() - 1),
- newest_frame_id_(FrameId::first() - 1) {
- DCHECK(incoming_payload_feedback) << "Invalid argument";
-}
-
-Framer::~Framer() = default;
-
-bool Framer::InsertPacket(const uint8_t* payload_data,
- size_t payload_size,
- const RtpCastHeader& rtp_header,
- bool* duplicate) {
- *duplicate = false;
-
- if (rtp_header.is_key_frame && waiting_for_key_) {
- last_released_frame_ = rtp_header.frame_id - 1;
- waiting_for_key_ = false;
- }
-
- VLOG(1) << "InsertPacket frame:" << rtp_header.frame_id
- << " packet:" << static_cast<int>(rtp_header.packet_id)
- << " max packet:" << static_cast<int>(rtp_header.max_packet_id);
-
- if ((rtp_header.frame_id <= last_released_frame_) && !waiting_for_key_) {
- // Packet is too old.
- return false;
- }
-
- // Update the last received frame id.
- if (rtp_header.frame_id > newest_frame_id_) {
- newest_frame_id_ = rtp_header.frame_id;
- }
-
- // Insert packet.
- const auto it = frames_.find(rtp_header.frame_id);
- FrameBuffer* buffer;
- if (it == frames_.end()) {
- buffer = new FrameBuffer();
- frames_.insert(std::make_pair(rtp_header.frame_id,
- std::unique_ptr<FrameBuffer>(buffer)));
- } else {
- buffer = it->second.get();
- }
- if (!buffer->InsertPacket(payload_data, payload_size, rtp_header)) {
- VLOG(3) << "Packet already received, ignored: frame " << rtp_header.frame_id
- << ", packet " << rtp_header.packet_id;
- *duplicate = true;
- return false;
- }
-
- return buffer->Complete();
-}
-
-// This does not release the frame.
-bool Framer::GetEncodedFrame(EncodedFrame* frame,
- bool* next_frame,
- bool* have_multiple_decodable_frames) {
- *have_multiple_decodable_frames = HaveMultipleDecodableFrames();
-
- // Find frame id.
- FrameBuffer* buffer = FindNextFrameForRelease();
- if (buffer) {
- // We have our next frame.
- *next_frame = true;
- } else {
- // Check if we can skip frames when our decoder is too slow.
- if (!decoder_faster_than_max_frame_rate_)
- return false;
-
- buffer = FindOldestDecodableFrame();
- if (!buffer)
- return false;
- *next_frame = false;
- }
-
- return buffer->AssembleEncodedFrame(frame);
-}
-
-void Framer::AckFrame(FrameId frame_id) {
- VLOG(2) << "ACK frame " << frame_id;
- cast_msg_builder_.CompleteFrameReceived(frame_id);
-}
-
-void Framer::ReleaseFrame(FrameId frame_id) {
- const auto it = frames_.begin();
- const bool skipped_old_frame = it->first < frame_id;
- frames_.erase(it, frames_.upper_bound(frame_id));
- last_released_frame_ = frame_id;
- if (skipped_old_frame)
- cast_msg_builder_.UpdateCastMessage();
-}
-
-bool Framer::TimeToSendNextCastMessage(base::TimeTicks* time_to_send) {
- return cast_msg_builder_.TimeToSendNextCastMessage(time_to_send);
-}
-
-void Framer::SendCastMessage() {
- cast_msg_builder_.UpdateCastMessage();
-}
-
-FrameBuffer* Framer::FindNextFrameForRelease() {
- for (const auto& entry : frames_) {
- if (entry.second->Complete() && IsNextFrameForRelease(*entry.second))
- return entry.second.get();
- }
- return nullptr;
-}
-
-FrameBuffer* Framer::FindOldestDecodableFrame() {
- for (const auto& entry : frames_) {
- if (entry.second->Complete() && IsDecodableFrame(*entry.second))
- return entry.second.get();
- }
- return nullptr;
-}
-
-bool Framer::HaveMultipleDecodableFrames() const {
- bool found_one = false;
- for (const auto& entry : frames_) {
- if (entry.second->Complete() && IsDecodableFrame(*entry.second)) {
- if (found_one)
- return true; // Found another.
- else
- found_one = true; // Found first one. Continue search for another.
- }
- }
- return false;
-}
-
-bool Framer::Empty() const { return frames_.empty(); }
-
-int Framer::NumberOfCompleteFrames() const {
- int count = 0;
- for (const auto& entry : frames_) {
- if (entry.second->Complete())
- ++count;
- }
- return count;
-}
-
-bool Framer::FrameExists(FrameId frame_id) const {
- return frames_.end() != frames_.find(frame_id);
-}
-
-void Framer::GetMissingPackets(FrameId frame_id,
- bool last_frame,
- PacketIdSet* missing_packets) const {
- const auto it = frames_.find(frame_id);
- if (it == frames_.end())
- return;
-
- it->second->GetMissingPackets(last_frame, missing_packets);
-}
-
-bool Framer::IsNextFrameForRelease(const FrameBuffer& buffer) const {
- if (waiting_for_key_ && !buffer.is_key_frame())
- return false;
- return (last_released_frame_ + 1) == buffer.frame_id();
-}
-
-bool Framer::IsDecodableFrame(const FrameBuffer& buffer) const {
- if (buffer.is_key_frame())
- return true;
- if (waiting_for_key_)
- return false;
- // Self-reference?
- if (buffer.last_referenced_frame_id() == buffer.frame_id())
- return true;
-
- // Current frame is not necessarily referencing the last frame.
- // Has the reference frame been released already?
- return buffer.last_referenced_frame_id() <= last_released_frame_;
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/net/rtp/framer.h b/chromium/media/cast/net/rtp/framer.h
deleted file mode 100644
index 1d0160a500b..00000000000
--- a/chromium/media/cast/net/rtp/framer.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2014 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 MEDIA_CAST_NET_RTP_FRAMER_H_
-#define MEDIA_CAST_NET_RTP_FRAMER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-
-#include "base/macros.h"
-#include "base/time/tick_clock.h"
-#include "base/time/time.h"
-#include "media/cast/net/rtp/cast_message_builder.h"
-#include "media/cast/net/rtp/frame_buffer.h"
-#include "media/cast/net/rtp/rtp_defines.h"
-
-namespace media {
-namespace cast {
-
-class Framer {
- public:
- Framer(const base::TickClock* clock,
- RtpPayloadFeedback* incoming_payload_feedback,
- uint32_t ssrc,
- bool decoder_faster_than_max_frame_rate,
- int max_unacked_frames);
- ~Framer();
-
- // Return true when receiving the last packet in a frame, creating a
- // complete frame. If a duplicate packet for an already complete frame is
- // received, the function returns false but sets |duplicate| to true.
- bool InsertPacket(const uint8_t* payload_data,
- size_t payload_size,
- const RtpCastHeader& rtp_header,
- bool* duplicate);
-
- // Extracts a complete encoded frame - will only return a complete and
- // decodable frame. Returns false if no such frames exist.
- // |next_frame| will be set to true if the returned frame is the very
- // next frame. |have_multiple_complete_frames| will be set to true
- // if there are more decodadble frames available.
- bool GetEncodedFrame(EncodedFrame* video_frame,
- bool* next_frame,
- bool* have_multiple_complete_frames);
-
- // TODO(hubbe): Move this elsewhere.
- void AckFrame(FrameId frame_id);
-
- void ReleaseFrame(FrameId frame_id);
-
- bool TimeToSendNextCastMessage(base::TimeTicks* time_to_send);
- void SendCastMessage();
-
- // TODO(miu): These methods are called from CastMessageBuilder. We need to
- // resolve these circular dependencies with some refactoring.
- // http://crbug.com/530845
- FrameId newest_frame_id() const { return newest_frame_id_; }
- bool Empty() const;
- bool FrameExists(FrameId frame_id) const;
- int NumberOfCompleteFrames() const;
- void GetMissingPackets(FrameId frame_id,
- bool last_frame,
- PacketIdSet* missing_packets) const;
-
- private:
- // Identifies the next frame to be released (rendered) and returns its
- // associated buffer, or returns nullptr there is none.
- FrameBuffer* FindNextFrameForRelease();
-
- // Returns the buffer associated with the oldest decodable frame (i.e., where
- // all dependencies are met), or nullptr if there is none.
- FrameBuffer* FindOldestDecodableFrame();
- bool HaveMultipleDecodableFrames() const;
-
- // Helper for FindNextFrameForRelease().
- bool IsNextFrameForRelease(const FrameBuffer& frame) const;
-
- // Helper for FindOldestDecodableFrame() and HaveMultipleDecodableFrames().
- bool IsDecodableFrame(const FrameBuffer& frame) const;
-
- const bool decoder_faster_than_max_frame_rate_;
- std::map<FrameId, std::unique_ptr<FrameBuffer>> frames_;
- CastMessageBuilder cast_msg_builder_;
- bool waiting_for_key_;
- FrameId last_released_frame_;
- FrameId newest_frame_id_;
-
- DISALLOW_COPY_AND_ASSIGN(Framer);
-};
-
-} // namespace cast
-} // namespace media
-
-#endif // MEDIA_CAST_NET_RTP_FRAMER_H_
diff --git a/chromium/media/cast/net/rtp/framer_unittest.cc b/chromium/media/cast/net/rtp/framer_unittest.cc
deleted file mode 100644
index cc6a05d7a84..00000000000
--- a/chromium/media/cast/net/rtp/framer_unittest.cc
+++ /dev/null
@@ -1,457 +0,0 @@
-// Copyright 2014 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 <stdint.h>
-
-#include "base/macros.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "media/cast/net/cast_transport_defines.h"
-#include "media/cast/net/rtp/framer.h"
-#include "media/cast/net/rtp/mock_rtp_payload_feedback.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace media {
-namespace cast {
-
-class FramerTest : public ::testing::Test {
- protected:
- FramerTest()
- : mock_rtp_payload_feedback_(),
- framer_(&testing_clock_, &mock_rtp_payload_feedback_, 0, true, 0) {
- payload_.assign(kMaxIpPacketSize, 0);
-
- EXPECT_CALL(mock_rtp_payload_feedback_, CastFeedback(testing::_))
- .WillRepeatedly(testing::Return());
- }
-
- ~FramerTest() override = default;
-
- std::vector<uint8_t> payload_;
- RtpCastHeader rtp_header_;
- MockRtpPayloadFeedback mock_rtp_payload_feedback_;
- Framer framer_;
- base::SimpleTestTickClock testing_clock_;
-
- DISALLOW_COPY_AND_ASSIGN(FramerTest);
-};
-
-TEST_F(FramerTest, EmptyState) {
- EncodedFrame frame;
- bool next_frame = false;
- bool multiple = false;
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
-}
-
-TEST_F(FramerTest, AlwaysStartWithKey) {
- EncodedFrame frame;
- bool next_frame = false;
- bool complete = false;
- bool multiple = false;
- bool duplicate = false;
-
- // Insert non key first frame.
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(complete);
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- rtp_header_.frame_id = FrameId::first() + 1;
- rtp_header_.reference_frame_id = FrameId::first() + 1;
- rtp_header_.is_key_frame = true;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(complete);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_TRUE(multiple);
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first() + 1, frame.frame_id);
- EXPECT_EQ(FrameId::first() + 1, frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
-}
-
-TEST_F(FramerTest, CompleteFrame) {
- EncodedFrame frame;
- bool next_frame = false;
- bool complete = false;
- bool multiple = false;
- bool duplicate = false;
-
- // Start with a complete key frame.
- rtp_header_.is_key_frame = true;
- rtp_header_.frame_id = FrameId::first();
- rtp_header_.reference_frame_id = FrameId::first();
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(complete);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_FALSE(multiple);
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first(), frame.frame_id);
- EXPECT_EQ(FrameId::first(), frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
-
- // Incomplete delta.
- ++rtp_header_.frame_id;
- rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
- rtp_header_.is_key_frame = false;
- rtp_header_.max_packet_id = 2;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_FALSE(complete);
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
-
- // Complete delta - can't skip, as incomplete sequence.
- ++rtp_header_.frame_id;
- rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
- rtp_header_.max_packet_id = 0;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(complete);
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
-}
-
-TEST_F(FramerTest, DuplicatePackets) {
- EncodedFrame frame;
- bool next_frame = false;
- bool complete = false;
- bool multiple = false;
- bool duplicate = false;
-
- // Start with an incomplete key frame.
- rtp_header_.is_key_frame = true;
- rtp_header_.frame_id = FrameId::first();
- rtp_header_.reference_frame_id = FrameId::first();
- rtp_header_.max_packet_id = 1;
- duplicate = true;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_FALSE(complete);
- EXPECT_FALSE(duplicate);
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
-
- // Add same packet again in incomplete key frame.
- duplicate = false;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_FALSE(complete);
- EXPECT_TRUE(duplicate);
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
-
- // Complete key frame.
- rtp_header_.packet_id = 1;
- duplicate = true;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(complete);
- EXPECT_FALSE(duplicate);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_FALSE(multiple);
- EXPECT_EQ(FrameId::first(), frame.referenced_frame_id);
-
- // Add same packet again in complete key frame.
- duplicate = false;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_FALSE(complete);
- EXPECT_TRUE(duplicate);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first(), frame.frame_id);
- EXPECT_FALSE(multiple);
- EXPECT_EQ(FrameId::first(), frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
-
- // Incomplete delta frame.
- ++rtp_header_.frame_id;
- rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
- rtp_header_.packet_id = 0;
- rtp_header_.is_key_frame = false;
- duplicate = true;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_FALSE(complete);
- EXPECT_FALSE(duplicate);
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
-
- // Add same packet again in incomplete delta frame.
- duplicate = false;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_FALSE(complete);
- EXPECT_TRUE(duplicate);
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
-
- // Complete delta frame.
- rtp_header_.packet_id = 1;
- duplicate = true;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(complete);
- EXPECT_FALSE(duplicate);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_EQ(EncodedFrame::DEPENDENT, frame.dependency);
- EXPECT_EQ(FrameId::first() + 1, frame.frame_id);
- EXPECT_EQ(FrameId::first(), frame.referenced_frame_id);
- EXPECT_FALSE(multiple);
-
- // Add same packet again in complete delta frame.
- duplicate = false;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_FALSE(complete);
- EXPECT_TRUE(duplicate);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_EQ(EncodedFrame::DEPENDENT, frame.dependency);
- EXPECT_EQ(FrameId::first() + 1, frame.frame_id);
- EXPECT_EQ(FrameId::first(), frame.referenced_frame_id);
- EXPECT_FALSE(multiple);
-}
-
-TEST_F(FramerTest, ContinuousSequence) {
- EncodedFrame frame;
- bool next_frame = false;
- bool complete = false;
- bool multiple = false;
- bool duplicate = false;
-
- // Start with a complete key frame.
- rtp_header_.is_key_frame = true;
- rtp_header_.frame_id = FrameId::first();
- rtp_header_.reference_frame_id = FrameId::first();
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(complete);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_FALSE(multiple);
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first(), frame.frame_id);
- EXPECT_EQ(FrameId::first(), frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
-
- // Complete - not continuous.
- rtp_header_.frame_id = FrameId::first() + 2;
- rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
- rtp_header_.is_key_frame = false;
- complete = framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(complete);
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
-}
-
-TEST_F(FramerTest, RequireKeyFrameForFirstFrame) {
- EncodedFrame frame;
- bool next_frame = false;
- bool multiple = false;
- bool duplicate = false;
-
- // Start with a complete key frame.
- rtp_header_.is_key_frame = false;
- rtp_header_.frame_id = FrameId::first();
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- rtp_header_.frame_id = FrameId::first() + 1;
- rtp_header_.reference_frame_id = FrameId::first() + 1;
- rtp_header_.is_key_frame = true;
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_TRUE(multiple);
-}
-
-TEST_F(FramerTest, BasicNonLastReferenceId) {
- EncodedFrame frame;
- bool next_frame = false;
- bool multiple = false;
- bool duplicate = false;
-
- rtp_header_.is_key_frame = true;
- rtp_header_.frame_id = FrameId::first();
- rtp_header_.reference_frame_id = FrameId::first();
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
-
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_FALSE(multiple);
- framer_.ReleaseFrame(frame.frame_id);
-
- rtp_header_.is_key_frame = false;
- rtp_header_.frame_id = FrameId::first() + 5;
- rtp_header_.reference_frame_id = FrameId::first();
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
-
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_FALSE(next_frame);
- EXPECT_FALSE(multiple);
-}
-
-TEST_F(FramerTest, InOrderReferenceFrameSelection) {
- // Create pattern: 0, 1, 4, 5.
- EncodedFrame frame;
- bool next_frame = false;
- bool multiple = false;
- bool duplicate = false;
-
- rtp_header_.is_key_frame = true;
- rtp_header_.frame_id = FrameId::first();
- rtp_header_.reference_frame_id = FrameId::first();
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- rtp_header_.is_key_frame = false;
- rtp_header_.frame_id = FrameId::first() + 1;
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
-
- // Insert frame #2 partially.
- rtp_header_.frame_id = FrameId::first() + 2;
- rtp_header_.max_packet_id = 1;
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- rtp_header_.frame_id = FrameId::first() + 4;
- rtp_header_.max_packet_id = 0;
- rtp_header_.reference_frame_id = FrameId::first();
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first(), frame.frame_id);
- EXPECT_EQ(FrameId::first(), frame.referenced_frame_id);
- EXPECT_FALSE(multiple);
- framer_.ReleaseFrame(frame.frame_id);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_TRUE(multiple);
- EXPECT_EQ(EncodedFrame::DEPENDENT, frame.dependency);
- EXPECT_EQ(FrameId::first() + 1, frame.frame_id);
- EXPECT_EQ(FrameId::first(), frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_FALSE(next_frame);
- EXPECT_FALSE(multiple);
- EXPECT_EQ(EncodedFrame::DEPENDENT, frame.dependency);
- EXPECT_EQ(FrameId::first() + 4, frame.frame_id);
- EXPECT_EQ(FrameId::first(), frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
- // Insert remaining packet of frame #2 - should no be continuous.
- rtp_header_.frame_id = FrameId::first() + 2;
- rtp_header_.packet_id = 1;
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- rtp_header_.frame_id = FrameId::first() + 5;
- rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
- rtp_header_.packet_id = 0;
- rtp_header_.max_packet_id = 0;
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_FALSE(multiple);
- EXPECT_EQ(EncodedFrame::DEPENDENT, frame.dependency);
- EXPECT_EQ(FrameId::first() + 5, frame.frame_id);
- EXPECT_EQ(FrameId::first() + 4, frame.referenced_frame_id);
-}
-
-TEST_F(FramerTest, ReleasesAllReceivedKeyFramesInContinuousSequence) {
- EncodedFrame frame;
- bool next_frame = false;
- bool multiple = false;
- bool duplicate = false;
-
- rtp_header_.is_key_frame = true;
- rtp_header_.frame_id = FrameId::first() + 254;
- rtp_header_.reference_frame_id = FrameId::first() + 254;
-
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_FALSE(multiple);
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first() + 254, frame.frame_id);
- EXPECT_EQ(FrameId::first() + 254, frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
-
- rtp_header_.frame_id = FrameId::first() + 255;
- rtp_header_.reference_frame_id = FrameId::first() + 255;
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
-
- // Insert wrapped frame - should be continuous.
- rtp_header_.frame_id = FrameId::first() + 256;
- rtp_header_.reference_frame_id = FrameId::first() + 256;
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
-
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_TRUE(multiple);
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first() + 255, frame.frame_id);
- EXPECT_EQ(FrameId::first() + 255, frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
-
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_FALSE(multiple);
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first() + 256, frame.frame_id);
- EXPECT_EQ(FrameId::first() + 256, frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
-}
-
-TEST_F(FramerTest, SkipsMissingFramesWhenLaterKeyFramesAreAvailable) {
- EncodedFrame frame;
- bool next_frame = false;
- bool multiple = true;
- bool duplicate = false;
-
- // Insert and get first frame's packet.
- rtp_header_.is_key_frame = true;
- rtp_header_.frame_id = FrameId::first() + 253;
- rtp_header_.reference_frame_id = FrameId::first() + 253;
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_FALSE(multiple);
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first() + 253, frame.frame_id);
- EXPECT_EQ(FrameId::first() + 253, frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
-
- // Insert third and fourth frames' packet.
- rtp_header_.frame_id = FrameId::first() + 255;
- rtp_header_.reference_frame_id = FrameId::first() + 255;
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
- rtp_header_.frame_id = FrameId::first() + 256;
- rtp_header_.reference_frame_id = FrameId::first() + 256;
- framer_.InsertPacket(
- &payload_[0], payload_.size(), rtp_header_, &duplicate);
-
- // Get third and fourth frame.
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_FALSE(next_frame);
- EXPECT_TRUE(multiple);
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first() + 255, frame.frame_id);
- EXPECT_EQ(FrameId::first() + 255, frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
- EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
- EXPECT_TRUE(next_frame);
- EXPECT_FALSE(multiple);
- EXPECT_EQ(EncodedFrame::KEY, frame.dependency);
- EXPECT_EQ(FrameId::first() + 256, frame.frame_id);
- EXPECT_EQ(FrameId::first() + 256, frame.referenced_frame_id);
- framer_.ReleaseFrame(frame.frame_id);
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/net/rtp/receiver_stats.cc b/chromium/media/cast/net/rtp/receiver_stats.cc
deleted file mode 100644
index c9d3f68c203..00000000000
--- a/chromium/media/cast/net/rtp/receiver_stats.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2014 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 "media/cast/net/rtp/receiver_stats.h"
-
-#include "media/cast/net/rtp/rtp_defines.h"
-
-namespace media {
-namespace cast {
-
-namespace {
-
-constexpr uint32_t kMaxSequenceNumber = 65536;
-
-// TODO(miu): Get rid of all the special 16-bit rounding detection and special
-// handling throughout this file, and just use good 'ol int64_t.
-// http://crbug.com/530839
-bool IsNewerSequenceNumber(uint16_t sequence_number,
- uint16_t prev_sequence_number) {
- return (sequence_number != prev_sequence_number) &&
- static_cast<uint16_t>(sequence_number - prev_sequence_number) < 0x8000;
-}
-
-} // namespace
-
-ReceiverStats::ReceiverStats(const base::TickClock* clock)
- : clock_(clock),
- min_sequence_number_(0),
- max_sequence_number_(0),
- total_number_packets_(0),
- sequence_number_cycles_(0),
- interval_min_sequence_number_(0),
- interval_number_packets_(0),
- interval_wrap_count_(0) {}
-
-RtpReceiverStatistics ReceiverStats::GetStatistics() {
- RtpReceiverStatistics ret;
- // Compute losses.
- if (interval_number_packets_ == 0) {
- ret.fraction_lost = 0;
- } else {
- int diff = 0;
- if (interval_wrap_count_ == 0) {
- diff = max_sequence_number_ - interval_min_sequence_number_ + 1;
- } else {
- diff = kMaxSequenceNumber * (interval_wrap_count_ - 1) +
- (max_sequence_number_ - interval_min_sequence_number_ +
- kMaxSequenceNumber + 1);
- }
-
- if (diff < 1) {
- ret.fraction_lost = 0;
- } else {
- float tmp_ratio =
- (1 - static_cast<float>(interval_number_packets_) / abs(diff));
- ret.fraction_lost = static_cast<uint8_t>(256 * tmp_ratio);
- }
- }
-
- int expected_packets_num = max_sequence_number_ - min_sequence_number_ + 1;
- if (total_number_packets_ == 0) {
- ret.cumulative_lost = 0;
- } else if (sequence_number_cycles_ == 0) {
- ret.cumulative_lost = expected_packets_num - total_number_packets_;
- } else {
- ret.cumulative_lost =
- kMaxSequenceNumber * (sequence_number_cycles_ - 1) +
- (expected_packets_num - total_number_packets_ + kMaxSequenceNumber);
- }
-
- // Extended high sequence number consists of the highest seq number and the
- // number of cycles (wrap).
- ret.extended_high_sequence_number =
- (sequence_number_cycles_ << 16) + max_sequence_number_;
-
- ret.jitter =
- static_cast<uint32_t>(std::abs(jitter_.InMillisecondsRoundedUp()));
-
- // Reset interval values.
- interval_min_sequence_number_ = 0;
- interval_number_packets_ = 0;
- interval_wrap_count_ = 0;
-
- return ret;
-}
-
-void ReceiverStats::UpdateStatistics(const RtpCastHeader& header,
- int rtp_timebase) {
- const uint16_t new_seq_num = header.sequence_number;
-
- if (interval_number_packets_ == 0) {
- // First packet in the interval.
- interval_min_sequence_number_ = new_seq_num;
- }
- if (total_number_packets_ == 0) {
- // First incoming packet.
- min_sequence_number_ = new_seq_num;
- max_sequence_number_ = new_seq_num;
- }
-
- if (IsNewerSequenceNumber(new_seq_num, max_sequence_number_)) {
- // Check wrap.
- if (new_seq_num < max_sequence_number_) {
- ++sequence_number_cycles_;
- ++interval_wrap_count_;
- }
- max_sequence_number_ = new_seq_num;
- }
-
- // Compute Jitter.
- const base::TimeTicks now = clock_->NowTicks();
- if (total_number_packets_ > 0) {
- const base::TimeDelta packet_time_difference =
- now - last_received_packet_time_;
- const base::TimeDelta media_time_differerence =
- (header.rtp_timestamp - last_received_rtp_timestamp_)
- .ToTimeDelta(rtp_timebase);
- const base::TimeDelta delta =
- packet_time_difference - media_time_differerence;
- // Update jitter.
- jitter_ += (delta - jitter_) / 16;
- }
- last_received_rtp_timestamp_ = header.rtp_timestamp;
- last_received_packet_time_ = now;
-
- // Increment counters.
- ++total_number_packets_;
- ++interval_number_packets_;
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/net/rtp/receiver_stats.h b/chromium/media/cast/net/rtp/receiver_stats.h
deleted file mode 100644
index a1cd9039714..00000000000
--- a/chromium/media/cast/net/rtp/receiver_stats.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 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 MEDIA_CAST_NET_RTP_RECEIVER_STATS_H_
-#define MEDIA_CAST_NET_RTP_RECEIVER_STATS_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/time/tick_clock.h"
-#include "base/time/time.h"
-#include "media/cast/common/rtp_time.h"
-#include "media/cast/net/rtp/rtp_defines.h"
-
-namespace media {
-namespace cast {
-
-// TODO(miu): Document this class.
-class ReceiverStats {
- public:
- explicit ReceiverStats(const base::TickClock* clock);
-
- RtpReceiverStatistics GetStatistics();
- void UpdateStatistics(const RtpCastHeader& header, int rtp_timebase);
-
- private:
- const base::TickClock* const clock_; // Not owned by this class.
-
- // Global metrics.
- uint16_t min_sequence_number_;
- uint16_t max_sequence_number_;
- uint32_t total_number_packets_;
- uint16_t sequence_number_cycles_;
- RtpTimeTicks last_received_rtp_timestamp_;
- base::TimeTicks last_received_packet_time_;
- base::TimeDelta jitter_;
-
- // Intermediate metrics - between RTCP reports.
- int interval_min_sequence_number_;
- int interval_number_packets_;
- int interval_wrap_count_;
-
- DISALLOW_COPY_AND_ASSIGN(ReceiverStats);
-};
-
-} // namespace cast
-} // namespace media
-
-#endif // MEDIA_CAST_NET_RTP_RECEIVER_STATS_H_
diff --git a/chromium/media/cast/net/rtp/receiver_stats_unittest.cc b/chromium/media/cast/net/rtp/receiver_stats_unittest.cc
deleted file mode 100644
index ec132e4a7a2..00000000000
--- a/chromium/media/cast/net/rtp/receiver_stats_unittest.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2014 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 <gtest/gtest.h>
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/time/time.h"
-#include "media/cast/constants.h"
-#include "media/cast/net/rtp/receiver_stats.h"
-#include "media/cast/net/rtp/rtp_defines.h"
-
-namespace media {
-namespace cast {
-
-static const int64_t kStartMillisecond = INT64_C(12345678900000);
-static const uint32_t kStdTimeIncrementMs = 33;
-
-class ReceiverStatsTest : public ::testing::Test {
- protected:
- ReceiverStatsTest()
- : stats_(&testing_clock_) {
- testing_clock_.Advance(
- base::TimeDelta::FromMilliseconds(kStartMillisecond));
- start_time_ = testing_clock_.NowTicks();
- delta_increments_ = base::TimeDelta::FromMilliseconds(kStdTimeIncrementMs);
- }
- ~ReceiverStatsTest() override = default;
-
- uint32_t ExpectedJitter(uint32_t const_interval, int num_packets) {
- float jitter = 0;
- // Assume timestamps have a constant kStdTimeIncrementMs interval.
- float float_interval =
- static_cast<float>(const_interval - kStdTimeIncrementMs);
- for (int i = 0; i < num_packets; ++i) {
- jitter += (float_interval - jitter) / 16;
- }
- return static_cast<uint32_t>(jitter + 0.5f);
- }
-
- ReceiverStats stats_;
- RtpCastHeader rtp_header_;
- base::SimpleTestTickClock testing_clock_;
- base::TimeTicks start_time_;
- base::TimeDelta delta_increments_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ReceiverStatsTest);
-};
-
-TEST_F(ReceiverStatsTest, ResetState) {
- RtpReceiverStatistics s = stats_.GetStatistics();
- EXPECT_EQ(0u, s.fraction_lost);
- EXPECT_EQ(0u, s.cumulative_lost);
- EXPECT_EQ(0u, s.extended_high_sequence_number);
- EXPECT_EQ(0u, s.jitter);
-}
-
-TEST_F(ReceiverStatsTest, LossCount) {
- for (int i = 0; i < 300; ++i) {
- if (i % 4)
- stats_.UpdateStatistics(rtp_header_, kVideoFrequency);
- if (i % 3) {
- rtp_header_.rtp_timestamp += RtpTimeDelta::FromTimeDelta(
- base::TimeDelta::FromMilliseconds(33), kVideoFrequency);
- }
- ++rtp_header_.sequence_number;
- testing_clock_.Advance(delta_increments_);
- }
- RtpReceiverStatistics s = stats_.GetStatistics();
- EXPECT_EQ(63u, s.fraction_lost);
- EXPECT_EQ(74u, s.cumulative_lost);
- // Build extended sequence number.
- const uint32_t extended_seq_num = rtp_header_.sequence_number - 1;
- EXPECT_EQ(extended_seq_num, s.extended_high_sequence_number);
-}
-
-TEST_F(ReceiverStatsTest, NoLossWrap) {
- rtp_header_.sequence_number = 65500;
- for (int i = 0; i < 300; ++i) {
- stats_.UpdateStatistics(rtp_header_, kVideoFrequency);
- if (i % 3) {
- rtp_header_.rtp_timestamp += RtpTimeDelta::FromTimeDelta(
- base::TimeDelta::FromMilliseconds(33), kVideoFrequency);
- }
- ++rtp_header_.sequence_number;
- testing_clock_.Advance(delta_increments_);
- }
- RtpReceiverStatistics s = stats_.GetStatistics();
- EXPECT_EQ(0u, s.fraction_lost);
- EXPECT_EQ(0u, s.cumulative_lost);
- // Build extended sequence number (one wrap cycle).
- const uint32_t extended_seq_num = (1 << 16) + rtp_header_.sequence_number - 1;
- EXPECT_EQ(extended_seq_num, s.extended_high_sequence_number);
-}
-
-TEST_F(ReceiverStatsTest, LossCountWrap) {
- const uint32_t kStartSequenceNumber = 65500;
- rtp_header_.sequence_number = kStartSequenceNumber;
- for (int i = 0; i < 300; ++i) {
- if (i % 4)
- stats_.UpdateStatistics(rtp_header_, kVideoFrequency);
- if (i % 3)
- rtp_header_.rtp_timestamp += RtpTimeDelta::FromTicks(1);
- ++rtp_header_.sequence_number;
- testing_clock_.Advance(delta_increments_);
- }
- RtpReceiverStatistics s = stats_.GetStatistics();
- EXPECT_EQ(63u, s.fraction_lost);
- EXPECT_EQ(74u, s.cumulative_lost);
- // Build extended sequence number (one wrap cycle).
- const uint32_t extended_seq_num = (1 << 16) + rtp_header_.sequence_number - 1;
- EXPECT_EQ(extended_seq_num, s.extended_high_sequence_number);
-}
-
-TEST_F(ReceiverStatsTest, BasicJitter) {
- for (int i = 0; i < 300; ++i) {
- stats_.UpdateStatistics(rtp_header_, kVideoFrequency);
- ++rtp_header_.sequence_number;
- rtp_header_.rtp_timestamp += RtpTimeDelta::FromTimeDelta(
- base::TimeDelta::FromMilliseconds(33), kVideoFrequency);
- testing_clock_.Advance(delta_increments_);
- }
- RtpReceiverStatistics s = stats_.GetStatistics();
- EXPECT_FALSE(s.fraction_lost);
- EXPECT_FALSE(s.cumulative_lost);
- // Build extended sequence number (one wrap cycle).
- const uint32_t extended_seq_num = rtp_header_.sequence_number - 1;
- EXPECT_EQ(extended_seq_num, s.extended_high_sequence_number);
- EXPECT_EQ(ExpectedJitter(kStdTimeIncrementMs, 300), s.jitter);
-}
-
-TEST_F(ReceiverStatsTest, NonTrivialJitter) {
- const int kAdditionalIncrement = 5;
- for (int i = 0; i < 300; ++i) {
- stats_.UpdateStatistics(rtp_header_, kVideoFrequency);
- ++rtp_header_.sequence_number;
- rtp_header_.rtp_timestamp += RtpTimeDelta::FromTimeDelta(
- base::TimeDelta::FromMilliseconds(33), kVideoFrequency);
- base::TimeDelta additional_delta =
- base::TimeDelta::FromMilliseconds(kAdditionalIncrement);
- testing_clock_.Advance(delta_increments_ + additional_delta);
- }
- RtpReceiverStatistics s = stats_.GetStatistics();
- EXPECT_FALSE(s.fraction_lost);
- EXPECT_FALSE(s.cumulative_lost);
- // Build extended sequence number (one wrap cycle).
- const uint32_t extended_seq_num = rtp_header_.sequence_number - 1;
- EXPECT_EQ(extended_seq_num, s.extended_high_sequence_number);
- EXPECT_EQ(ExpectedJitter(kStdTimeIncrementMs + kAdditionalIncrement, 300),
- s.jitter);
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/net/rtp/rtp_packetizer.h b/chromium/media/cast/net/rtp/rtp_packetizer.h
index bb689541886..9bb6d61021a 100644
--- a/chromium/media/cast/net/rtp/rtp_packetizer.h
+++ b/chromium/media/cast/net/rtp/rtp_packetizer.h
@@ -9,10 +9,7 @@
#include <stdint.h>
#include <cmath>
-#include <list>
-#include <map>
-#include "base/time/time.h"
#include "media/cast/common/rtp_time.h"
#include "media/cast/net/rtp/packet_storage.h"
diff --git a/chromium/media/cast/receiver/audio_decoder.cc b/chromium/media/cast/receiver/audio_decoder.cc
deleted file mode 100644
index d3b760b81f2..00000000000
--- a/chromium/media/cast/receiver/audio_decoder.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright 2014 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 "media/cast/receiver/audio_decoder.h"
-
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/sys_byteorder.h"
-#include "build/build_config.h"
-#include "third_party/opus/src/include/opus.h"
-
-namespace media {
-namespace cast {
-
-// Base class that handles the common problem of detecting dropped frames, and
-// then invoking the Decode() method implemented by the subclasses to convert
-// the encoded payload data into usable audio data.
-class AudioDecoder::ImplBase
- : public base::RefCountedThreadSafe<AudioDecoder::ImplBase> {
- public:
- ImplBase(const scoped_refptr<CastEnvironment>& cast_environment,
- Codec codec,
- int num_channels,
- int sampling_rate)
- : cast_environment_(cast_environment),
- codec_(codec),
- num_channels_(num_channels),
- operational_status_(STATUS_UNINITIALIZED) {
- if (num_channels_ <= 0 || sampling_rate <= 0 || sampling_rate % 100 != 0) {
- operational_status_ = STATUS_INVALID_CONFIGURATION;
- }
- }
-
- OperationalStatus InitializationResult() const {
- return operational_status_;
- }
-
- void DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,
- DecodeFrameCallback callback) {
- DCHECK_EQ(operational_status_, STATUS_INITIALIZED);
-
- bool is_continuous = true;
- DCHECK(!encoded_frame->frame_id.is_null());
- if (!last_frame_id_.is_null()) {
- if (encoded_frame->frame_id > (last_frame_id_ + 1)) {
- RecoverBecauseFramesWereDropped();
- is_continuous = false;
- }
- }
- last_frame_id_ = encoded_frame->frame_id;
-
- std::unique_ptr<AudioBus> decoded_audio =
- Decode(encoded_frame->mutable_bytes(),
- static_cast<int>(encoded_frame->data.size()));
- if (!decoded_audio) {
- VLOG(2) << "Decoding of frame " << encoded_frame->frame_id << " failed.";
- cast_environment_->PostTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(std::move(callback), std::move(decoded_audio), false));
- return;
- }
-
- std::unique_ptr<FrameEvent> event(new FrameEvent());
- event->timestamp = cast_environment_->Clock()->NowTicks();
- event->type = FRAME_DECODED;
- event->media_type = AUDIO_EVENT;
- event->rtp_timestamp = encoded_frame->rtp_timestamp;
- event->frame_id = encoded_frame->frame_id;
- cast_environment_->logger()->DispatchFrameEvent(std::move(event));
-
- cast_environment_->PostTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(std::move(callback), std::move(decoded_audio),
- is_continuous));
- }
-
- protected:
- friend class base::RefCountedThreadSafe<ImplBase>;
- virtual ~ImplBase() = default;
-
- virtual void RecoverBecauseFramesWereDropped() {}
-
- // Note: Implementation of Decode() is allowed to mutate |data|.
- virtual std::unique_ptr<AudioBus> Decode(uint8_t* data, int len) = 0;
-
- const scoped_refptr<CastEnvironment> cast_environment_;
- const Codec codec_;
- const int num_channels_;
-
- // Subclass' ctor is expected to set this to STATUS_INITIALIZED.
- OperationalStatus operational_status_;
-
- private:
- FrameId last_frame_id_;
-
- DISALLOW_COPY_AND_ASSIGN(ImplBase);
-};
-
-class AudioDecoder::OpusImpl final : public AudioDecoder::ImplBase {
- public:
- OpusImpl(const scoped_refptr<CastEnvironment>& cast_environment,
- int num_channels,
- int sampling_rate)
- : ImplBase(cast_environment,
- CODEC_AUDIO_OPUS,
- num_channels,
- sampling_rate),
- decoder_memory_(new uint8_t[opus_decoder_get_size(num_channels)]),
- opus_decoder_(reinterpret_cast<OpusDecoder*>(decoder_memory_.get())),
- max_samples_per_frame_(kOpusMaxFrameDurationMillis * sampling_rate /
- 1000),
- buffer_(new float[max_samples_per_frame_ * num_channels]) {
- if (ImplBase::operational_status_ != STATUS_UNINITIALIZED) {
- return;
- }
- if (opus_decoder_init(opus_decoder_, sampling_rate, num_channels) !=
- OPUS_OK) {
- ImplBase::operational_status_ = STATUS_INVALID_CONFIGURATION;
- return;
- }
- ImplBase::operational_status_ = STATUS_INITIALIZED;
- }
-
- private:
- ~OpusImpl() final = default;
-
- void RecoverBecauseFramesWereDropped() final {
- // Passing nullptr for the input data notifies the decoder of frame loss.
- const opus_int32 result = opus_decode_float(
- opus_decoder_, nullptr, 0, buffer_.get(), max_samples_per_frame_, 0);
- DCHECK_GE(result, 0);
- }
-
- std::unique_ptr<AudioBus> Decode(uint8_t* data, int len) final {
- std::unique_ptr<AudioBus> audio_bus;
- const opus_int32 num_samples_decoded = opus_decode_float(
- opus_decoder_, data, len, buffer_.get(), max_samples_per_frame_, 0);
- if (num_samples_decoded <= 0)
- return audio_bus; // Decode error.
-
- // Copy interleaved samples from |buffer_| into a new AudioBus (where
- // samples are stored in planar format, for each channel).
- audio_bus = AudioBus::Create(num_channels_, num_samples_decoded);
- // TODO(miu): This should be moved into AudioBus::FromInterleaved().
- for (int ch = 0; ch < num_channels_; ++ch) {
- const float* src = buffer_.get() + ch;
- const float* const src_end = src + num_samples_decoded * num_channels_;
- float* dest = audio_bus->channel(ch);
- for (; src < src_end; src += num_channels_, ++dest)
- *dest = *src;
- }
- return audio_bus;
- }
-
- const std::unique_ptr<uint8_t[]> decoder_memory_;
- OpusDecoder* const opus_decoder_;
- const int max_samples_per_frame_;
- const std::unique_ptr<float[]> buffer_;
-
- // According to documentation in third_party/opus/src/include/opus.h, we must
- // provide enough space in |buffer_| to contain 120ms of samples. At 48 kHz,
- // then, that means 5760 samples times the number of channels.
- static const int kOpusMaxFrameDurationMillis = 120;
-
- DISALLOW_COPY_AND_ASSIGN(OpusImpl);
-};
-
-class AudioDecoder::Pcm16Impl final : public AudioDecoder::ImplBase {
- public:
- Pcm16Impl(const scoped_refptr<CastEnvironment>& cast_environment,
- int num_channels,
- int sampling_rate)
- : ImplBase(cast_environment,
- CODEC_AUDIO_PCM16,
- num_channels,
- sampling_rate) {
- if (ImplBase::operational_status_ != STATUS_UNINITIALIZED)
- return;
- ImplBase::operational_status_ = STATUS_INITIALIZED;
- }
-
- private:
- ~Pcm16Impl() final = default;
-
- std::unique_ptr<AudioBus> Decode(uint8_t* data, int len) final {
- std::unique_ptr<AudioBus> audio_bus;
- const int num_samples = len / sizeof(int16_t) / num_channels_;
- if (num_samples <= 0)
- return audio_bus;
-
- int16_t* const pcm_data = reinterpret_cast<int16_t*>(data);
-#if defined(ARCH_CPU_LITTLE_ENDIAN)
- // Convert endianness.
- const int num_elements = num_samples * num_channels_;
- for (int i = 0; i < num_elements; ++i)
- pcm_data[i] = static_cast<int16_t>(base::NetToHost16(pcm_data[i]));
-#endif
- audio_bus = AudioBus::Create(num_channels_, num_samples);
- audio_bus->FromInterleaved<SignedInt16SampleTypeTraits>(pcm_data,
- num_samples);
- return audio_bus;
- }
-
- DISALLOW_COPY_AND_ASSIGN(Pcm16Impl);
-};
-
-AudioDecoder::AudioDecoder(
- const scoped_refptr<CastEnvironment>& cast_environment,
- int channels,
- int sampling_rate,
- Codec codec)
- : cast_environment_(cast_environment) {
- switch (codec) {
- case CODEC_AUDIO_OPUS:
- impl_ = new OpusImpl(cast_environment, channels, sampling_rate);
- break;
- case CODEC_AUDIO_PCM16:
- impl_ = new Pcm16Impl(cast_environment, channels, sampling_rate);
- break;
- default:
- NOTREACHED() << "Unknown or unspecified codec.";
- break;
- }
-}
-
-AudioDecoder::~AudioDecoder() = default;
-
-OperationalStatus AudioDecoder::InitializationResult() const {
- if (impl_.get())
- return impl_->InitializationResult();
- return STATUS_UNSUPPORTED_CODEC;
-}
-
-void AudioDecoder::DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,
- DecodeFrameCallback callback) {
- DCHECK(encoded_frame.get());
- DCHECK(!callback.is_null());
- if (!impl_.get() || impl_->InitializationResult() != STATUS_INITIALIZED) {
- std::move(callback).Run(base::WrapUnique<AudioBus>(nullptr), false);
- return;
- }
- cast_environment_->PostTask(
- CastEnvironment::AUDIO, FROM_HERE,
- base::BindOnce(&AudioDecoder::ImplBase::DecodeFrame, impl_,
- std::move(encoded_frame), std::move(callback)));
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/receiver/audio_decoder.h b/chromium/media/cast/receiver/audio_decoder.h
deleted file mode 100644
index 608ff016e4e..00000000000
--- a/chromium/media/cast/receiver/audio_decoder.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2014 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 MEDIA_CAST_RECEIVER_AUDIO_DECODER_H_
-#define MEDIA_CAST_RECEIVER_AUDIO_DECODER_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "media/base/audio_bus.h"
-#include "media/cast/cast_environment.h"
-#include "media/cast/constants.h"
-#include "media/cast/net/cast_transport_config.h"
-
-namespace media {
-namespace cast {
-
-class AudioDecoder {
- public:
- // Callback passed to DecodeFrame, to deliver decoded audio data from the
- // decoder. The number of samples in |audio_bus| may vary, and |audio_bus|
- // can be NULL when errors occur. |is_continuous| is normally true, but will
- // be false if the decoder has detected a frame skip since the last decode
- // operation; and the client should take steps to smooth audio discontinuities
- // in this case.
- using DecodeFrameCallback =
- base::OnceCallback<void(std::unique_ptr<AudioBus> audio_bus,
- bool is_continuous)>;
-
- AudioDecoder(const scoped_refptr<CastEnvironment>& cast_environment,
- int channels,
- int sampling_rate,
- Codec codec);
- virtual ~AudioDecoder();
-
- // Returns STATUS_INITIALIZED if the decoder was successfully constructed. If
- // this method returns any other value, calls to DecodeFrame() will not
- // succeed.
- OperationalStatus InitializationResult() const;
-
- // Decode the payload in |encoded_frame| asynchronously. |callback| will be
- // invoked on the CastEnvironment::MAIN thread with the result.
- //
- // In the normal case, |encoded_frame->frame_id| will be
- // monotonically-increasing by 1 for each successive call to this method.
- // When it is not, the decoder will assume one or more frames have been
- // dropped (e.g., due to packet loss), and will perform recovery actions.
- void DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,
- DecodeFrameCallback callback);
-
- private:
- class ImplBase;
- class OpusImpl;
- class Pcm16Impl;
-
- const scoped_refptr<CastEnvironment> cast_environment_;
- scoped_refptr<ImplBase> impl_;
-
- DISALLOW_COPY_AND_ASSIGN(AudioDecoder);
-};
-
-} // namespace cast
-} // namespace media
-
-#endif // MEDIA_CAST_RECEIVER_AUDIO_DECODER_H_
diff --git a/chromium/media/cast/receiver/audio_decoder_unittest.cc b/chromium/media/cast/receiver/audio_decoder_unittest.cc
deleted file mode 100644
index 39268d66e5e..00000000000
--- a/chromium/media/cast/receiver/audio_decoder_unittest.cc
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2014 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 <stddef.h>
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/stl_util.h"
-#include "base/synchronization/condition_variable.h"
-#include "base/synchronization/lock.h"
-#include "base/sys_byteorder.h"
-#include "base/time/time.h"
-#include "build/build_config.h"
-#include "media/cast/cast_config.h"
-#include "media/cast/receiver/audio_decoder.h"
-#include "media/cast/test/utility/audio_utility.h"
-#include "media/cast/test/utility/standalone_cast_environment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/opus/src/include/opus.h"
-
-namespace media {
-namespace cast {
-
-namespace {
-struct TestScenario {
- Codec codec;
- int num_channels;
- int sampling_rate;
-
- TestScenario(Codec c, int n, int s)
- : codec(c), num_channels(n), sampling_rate(s) {}
-};
-} // namespace
-
-class AudioDecoderTest : public ::testing::TestWithParam<TestScenario> {
- public:
- AudioDecoderTest()
- : cast_environment_(new StandaloneCastEnvironment()),
- cond_(&lock_) {}
-
- virtual ~AudioDecoderTest() {
- // Make sure all threads have stopped before the environment goes away.
- cast_environment_->Shutdown();
- }
-
- protected:
- void SetUp() final {
- audio_decoder_.reset(new AudioDecoder(cast_environment_,
- GetParam().num_channels,
- GetParam().sampling_rate,
- GetParam().codec));
- CHECK_EQ(STATUS_INITIALIZED, audio_decoder_->InitializationResult());
-
- audio_bus_factory_.reset(
- new TestAudioBusFactory(GetParam().num_channels,
- GetParam().sampling_rate,
- TestAudioBusFactory::kMiddleANoteFreq,
- 0.5f));
- last_frame_id_ = FrameId::first();
- decoded_frames_seen_ = 0;
-
- if (GetParam().codec == CODEC_AUDIO_OPUS) {
- opus_encoder_memory_.reset(
- new uint8_t[opus_encoder_get_size(GetParam().num_channels)]);
- OpusEncoder* const opus_encoder =
- reinterpret_cast<OpusEncoder*>(opus_encoder_memory_.get());
- CHECK_EQ(OPUS_OK, opus_encoder_init(opus_encoder,
- GetParam().sampling_rate,
- GetParam().num_channels,
- OPUS_APPLICATION_AUDIO));
- CHECK_EQ(OPUS_OK,
- opus_encoder_ctl(opus_encoder, OPUS_SET_BITRATE(OPUS_AUTO)));
- }
-
- total_audio_feed_in_ = base::TimeDelta();
- total_audio_decoded_ = base::TimeDelta();
- }
-
- // Called from the unit test thread to create another EncodedFrame and push it
- // into the decoding pipeline.
- void FeedMoreAudio(const base::TimeDelta& duration,
- int num_dropped_frames) {
- // Prepare a simulated EncodedFrame to feed into the AudioDecoder.
- std::unique_ptr<EncodedFrame> encoded_frame(new EncodedFrame());
- encoded_frame->dependency = EncodedFrame::KEY;
- encoded_frame->frame_id = last_frame_id_ + 1 + num_dropped_frames;
- encoded_frame->referenced_frame_id = encoded_frame->frame_id;
- last_frame_id_ = encoded_frame->frame_id;
-
- const std::unique_ptr<AudioBus> audio_bus(
- audio_bus_factory_->NextAudioBus(duration));
-
- // Encode |audio_bus| into |encoded_frame->data|.
- const int num_elements = audio_bus->channels() * audio_bus->frames();
- std::vector<int16_t> interleaved(num_elements);
- audio_bus->ToInterleaved<SignedInt16SampleTypeTraits>(audio_bus->frames(),
- &interleaved.front());
- if (GetParam().codec == CODEC_AUDIO_PCM16) {
- encoded_frame->data.resize(num_elements * sizeof(int16_t));
- int16_t* const pcm_data =
- reinterpret_cast<int16_t*>(encoded_frame->mutable_bytes());
- for (size_t i = 0; i < interleaved.size(); ++i)
- pcm_data[i] = static_cast<int16_t>(base::HostToNet16(interleaved[i]));
- } else if (GetParam().codec == CODEC_AUDIO_OPUS) {
- OpusEncoder* const opus_encoder =
- reinterpret_cast<OpusEncoder*>(opus_encoder_memory_.get());
- const int kOpusEncodeBufferSize = 4000;
- encoded_frame->data.resize(kOpusEncodeBufferSize);
- const int payload_size =
- opus_encode(opus_encoder,
- &interleaved.front(),
- audio_bus->frames(),
- encoded_frame->mutable_bytes(),
- encoded_frame->data.size());
- CHECK_GT(payload_size, 1);
- encoded_frame->data.resize(payload_size);
- } else {
- ASSERT_TRUE(false); // Not reached.
- }
-
- {
- base::AutoLock auto_lock(lock_);
- total_audio_feed_in_ += duration;
- }
-
- cast_environment_->PostTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(&AudioDecoder::DecodeFrame,
- base::Unretained(audio_decoder_.get()),
- std::move(encoded_frame),
- base::BindRepeating(&AudioDecoderTest::OnDecodedFrame,
- base::Unretained(this),
- num_dropped_frames == 0)));
- }
-
- // Blocks the caller until all audio that has been feed in has been decoded.
- void WaitForAllAudioToBeDecoded() {
- DCHECK(!cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- base::AutoLock auto_lock(lock_);
- while (total_audio_decoded_ < total_audio_feed_in_)
- cond_.Wait();
- EXPECT_EQ(total_audio_feed_in_.InMicroseconds(),
- total_audio_decoded_.InMicroseconds());
- }
-
- private:
- // Called by |audio_decoder_| to deliver each frame of decoded audio.
- void OnDecodedFrame(bool should_be_continuous,
- std::unique_ptr<AudioBus> audio_bus,
- bool is_continuous) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-
- // A NULL |audio_bus| indicates a decode error, which we don't expect.
- ASSERT_TRUE(audio_bus);
-
- // Did the decoder detect whether frames were dropped?
- EXPECT_EQ(should_be_continuous, is_continuous);
-
- // Does the audio data seem to be intact? For Opus, we have to ignore the
- // first two frames seen at the start (and immediately after dropped packet
- // recovery) because it introduces a tiny, significant delay.
- bool examine_signal = true;
- if (GetParam().codec == CODEC_AUDIO_OPUS) {
- decoded_frames_seen_ = should_be_continuous ? decoded_frames_seen_ + 1 : 1;
- examine_signal = (decoded_frames_seen_ > 2) && should_be_continuous;
- }
- if (examine_signal) {
- for (int ch = 0; ch < audio_bus->channels(); ++ch) {
- EXPECT_NEAR(
- TestAudioBusFactory::kMiddleANoteFreq * 2 * audio_bus->frames() /
- GetParam().sampling_rate,
- CountZeroCrossings(audio_bus->channel(ch), audio_bus->frames()),
- 1);
- }
- }
-
- // Signal the main test thread that more audio was decoded.
- base::AutoLock auto_lock(lock_);
- total_audio_decoded_ += base::TimeDelta::FromSeconds(1) *
- audio_bus->frames() / GetParam().sampling_rate;
- cond_.Signal();
- }
-
- const scoped_refptr<StandaloneCastEnvironment> cast_environment_;
- std::unique_ptr<AudioDecoder> audio_decoder_;
- std::unique_ptr<TestAudioBusFactory> audio_bus_factory_;
- FrameId last_frame_id_;
- int decoded_frames_seen_;
- std::unique_ptr<uint8_t[]> opus_encoder_memory_;
-
- base::Lock lock_;
- base::ConditionVariable cond_;
- base::TimeDelta total_audio_feed_in_;
- base::TimeDelta total_audio_decoded_;
-
- DISALLOW_COPY_AND_ASSIGN(AudioDecoderTest);
-};
-
-TEST_P(AudioDecoderTest, DecodesFramesWithSameDuration) {
- const base::TimeDelta kTenMilliseconds =
- base::TimeDelta::FromMilliseconds(10);
- const int kNumFrames = 10;
- for (int i = 0; i < kNumFrames; ++i)
- FeedMoreAudio(kTenMilliseconds, 0);
- WaitForAllAudioToBeDecoded();
-}
-
-TEST_P(AudioDecoderTest, DecodesFramesWithVaryingDuration) {
- // These are the set of frame durations supported by the Opus encoder.
- const int kFrameDurationMs[] = { 5, 10, 20, 40, 60 };
-
- const int kNumFrames = 10;
- for (size_t i = 0; i < base::size(kFrameDurationMs); ++i)
- for (int j = 0; j < kNumFrames; ++j)
- FeedMoreAudio(base::TimeDelta::FromMilliseconds(kFrameDurationMs[i]), 0);
- WaitForAllAudioToBeDecoded();
-}
-
-TEST_P(AudioDecoderTest, RecoversFromDroppedFrames) {
- const base::TimeDelta kTenMilliseconds =
- base::TimeDelta::FromMilliseconds(10);
- const int kNumFrames = 100;
- int next_drop_at = 3;
- int next_num_dropped = 1;
- for (int i = 0; i < kNumFrames; ++i) {
- if (i == next_drop_at) {
- const int num_dropped = next_num_dropped++;
- next_drop_at *= 2;
- i += num_dropped;
- FeedMoreAudio(kTenMilliseconds, num_dropped);
- } else {
- FeedMoreAudio(kTenMilliseconds, 0);
- }
- }
- WaitForAllAudioToBeDecoded();
-}
-
-INSTANTIATE_TEST_SUITE_P(
- AudioDecoderTestScenarios,
- AudioDecoderTest,
- ::testing::Values(TestScenario(CODEC_AUDIO_PCM16, 1, 8000),
- TestScenario(CODEC_AUDIO_PCM16, 2, 48000),
- TestScenario(CODEC_AUDIO_OPUS, 1, 8000),
- TestScenario(CODEC_AUDIO_OPUS, 2, 48000)));
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/receiver/cast_receiver_impl.cc b/chromium/media/cast/receiver/cast_receiver_impl.cc
deleted file mode 100644
index 9e279fb4c6e..00000000000
--- a/chromium/media/cast/receiver/cast_receiver_impl.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2014 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 "media/cast/receiver/cast_receiver_impl.h"
-
-#include <stddef.h>
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/trace_event/trace_event.h"
-#include "media/cast/net/rtcp/rtcp_utility.h"
-#include "media/cast/receiver/audio_decoder.h"
-#include "media/cast/receiver/video_decoder.h"
-
-namespace media {
-namespace cast {
-
-std::unique_ptr<CastReceiver> CastReceiver::Create(
- scoped_refptr<CastEnvironment> cast_environment,
- const FrameReceiverConfig& audio_config,
- const FrameReceiverConfig& video_config,
- CastTransport* const transport) {
- return std::unique_ptr<CastReceiver>(new CastReceiverImpl(
- cast_environment, audio_config, video_config, transport));
-}
-
-CastReceiverImpl::CastReceiverImpl(
- scoped_refptr<CastEnvironment> cast_environment,
- const FrameReceiverConfig& audio_config,
- const FrameReceiverConfig& video_config,
- CastTransport* const transport)
- : cast_environment_(cast_environment),
- audio_receiver_(cast_environment, audio_config, AUDIO_EVENT, transport),
- video_receiver_(cast_environment, video_config, VIDEO_EVENT, transport),
- ssrc_of_audio_sender_(audio_config.sender_ssrc),
- ssrc_of_video_sender_(video_config.sender_ssrc),
- num_audio_channels_(audio_config.channels),
- audio_sampling_rate_(audio_config.rtp_timebase),
- audio_codec_(audio_config.codec),
- video_codec_(video_config.codec) {}
-
-CastReceiverImpl::~CastReceiverImpl() = default;
-
-void CastReceiverImpl::ReceivePacket(std::unique_ptr<Packet> packet) {
- const uint8_t* const data = &packet->front();
- const size_t length = packet->size();
-
- uint32_t ssrc_of_sender;
- if (IsRtcpPacket(data, length)) {
- ssrc_of_sender = GetSsrcOfSender(data, length);
- } else if (!RtpParser::ParseSsrc(data, length, &ssrc_of_sender)) {
- VLOG(1) << "Invalid RTP packet.";
- return;
- }
-
- base::WeakPtr<FrameReceiver> target;
- if (ssrc_of_sender == ssrc_of_video_sender_) {
- target = video_receiver_.AsWeakPtr();
- } else if (ssrc_of_sender == ssrc_of_audio_sender_) {
- target = audio_receiver_.AsWeakPtr();
- } else {
- VLOG(1) << "Dropping packet with a non matching sender SSRC: "
- << ssrc_of_sender;
- return;
- }
- cast_environment_->PostTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(base::IgnoreResult(&FrameReceiver::ProcessPacket), target,
- std::move(packet)));
-}
-
-void CastReceiverImpl::RequestDecodedAudioFrame(
- const AudioFrameDecodedCallback& callback) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- DCHECK(!callback.is_null());
- audio_receiver_.RequestEncodedFrame(base::BindOnce(
- &CastReceiverImpl::DecodeEncodedAudioFrame,
- // Note: Use of Unretained is safe since this Closure is guaranteed to be
- // invoked or discarded by |audio_receiver_| before destruction of |this|.
- base::Unretained(this), callback));
-}
-
-void CastReceiverImpl::RequestDecodedVideoFrame(
- const VideoFrameDecodedCallback& callback) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- DCHECK(!callback.is_null());
- video_receiver_.RequestEncodedFrame(base::BindOnce(
- &CastReceiverImpl::DecodeEncodedVideoFrame,
- // Note: Use of Unretained is safe since this Closure is guaranteed to be
- // invoked or discarded by |video_receiver_| before destruction of |this|.
- base::Unretained(this), callback));
-}
-
-void CastReceiverImpl::DecodeEncodedAudioFrame(
- const AudioFrameDecodedCallback& callback,
- std::unique_ptr<EncodedFrame> encoded_frame) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- if (!encoded_frame) {
- callback.Run(base::WrapUnique<AudioBus>(nullptr), base::TimeTicks(), false);
- return;
- }
-
- if (!audio_decoder_) {
- audio_decoder_ =
- std::make_unique<AudioDecoder>(cast_environment_, num_audio_channels_,
- audio_sampling_rate_, audio_codec_);
- }
- const FrameId frame_id = encoded_frame->frame_id;
- const RtpTimeTicks rtp_timestamp = encoded_frame->rtp_timestamp;
- const base::TimeTicks playout_time = encoded_frame->reference_time;
- audio_decoder_->DecodeFrame(
- std::move(encoded_frame),
- base::BindOnce(&CastReceiverImpl::EmitDecodedAudioFrame,
- cast_environment_, callback, frame_id, rtp_timestamp,
- playout_time));
-}
-
-void CastReceiverImpl::DecodeEncodedVideoFrame(
- const VideoFrameDecodedCallback& callback,
- std::unique_ptr<EncodedFrame> encoded_frame) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- if (!encoded_frame) {
- callback.Run(base::WrapRefCounted<VideoFrame>(nullptr), base::TimeTicks(),
- false);
- return;
- }
-
- // Used by chrome/browser/media/cast_mirroring_performance_browsertest.cc
- TRACE_EVENT_INSTANT1("cast_perf_test", "PullEncodedVideoFrame",
- TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp",
- encoded_frame->rtp_timestamp.lower_32_bits());
-
- if (!video_decoder_) {
- video_decoder_ =
- std::make_unique<VideoDecoder>(cast_environment_, video_codec_);
- }
- const FrameId frame_id = encoded_frame->frame_id;
- const RtpTimeTicks rtp_timestamp = encoded_frame->rtp_timestamp;
- const base::TimeTicks playout_time = encoded_frame->reference_time;
- video_decoder_->DecodeFrame(
- std::move(encoded_frame),
- base::BindRepeating(&CastReceiverImpl::EmitDecodedVideoFrame,
- cast_environment_, callback, frame_id, rtp_timestamp,
- playout_time));
-}
-
-// static
-void CastReceiverImpl::EmitDecodedAudioFrame(
- const scoped_refptr<CastEnvironment>& cast_environment,
- const AudioFrameDecodedCallback& callback,
- FrameId frame_id,
- RtpTimeTicks rtp_timestamp,
- const base::TimeTicks& playout_time,
- std::unique_ptr<AudioBus> audio_bus,
- bool is_continuous) {
- DCHECK(cast_environment->CurrentlyOn(CastEnvironment::MAIN));
-
- if (audio_bus.get()) {
- // TODO(miu): This is reporting incorrect timestamp and delay.
- // http://crbug.com/547251
- std::unique_ptr<FrameEvent> playout_event(new FrameEvent());
- playout_event->timestamp = cast_environment->Clock()->NowTicks();
- playout_event->type = FRAME_PLAYOUT;
- playout_event->media_type = AUDIO_EVENT;
- playout_event->rtp_timestamp = rtp_timestamp;
- playout_event->frame_id = frame_id;
- playout_event->delay_delta = playout_time - playout_event->timestamp;
- cast_environment->logger()->DispatchFrameEvent(std::move(playout_event));
- }
-
- callback.Run(std::move(audio_bus), playout_time, is_continuous);
-}
-
-// static
-void CastReceiverImpl::EmitDecodedVideoFrame(
- const scoped_refptr<CastEnvironment>& cast_environment,
- const VideoFrameDecodedCallback& callback,
- FrameId frame_id,
- RtpTimeTicks rtp_timestamp,
- const base::TimeTicks& playout_time,
- scoped_refptr<VideoFrame> video_frame,
- bool is_continuous) {
- DCHECK(cast_environment->CurrentlyOn(CastEnvironment::MAIN));
-
- if (video_frame) {
- // TODO(miu): This is reporting incorrect timestamp and delay.
- // http://crbug.com/547251
- std::unique_ptr<FrameEvent> playout_event(new FrameEvent());
- playout_event->timestamp = cast_environment->Clock()->NowTicks();
- playout_event->type = FRAME_PLAYOUT;
- playout_event->media_type = VIDEO_EVENT;
- playout_event->rtp_timestamp = rtp_timestamp;
- playout_event->frame_id = frame_id;
- playout_event->delay_delta = playout_time - playout_event->timestamp;
- cast_environment->logger()->DispatchFrameEvent(std::move(playout_event));
-
- // Used by chrome/browser/media/cast_mirroring_performance_browsertest.cc
- TRACE_EVENT_INSTANT2("cast_perf_test", "VideoFrameDecoded",
- TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp",
- rtp_timestamp.lower_32_bits(), "playout_time",
- (playout_time - base::TimeTicks()).InMicroseconds());
- }
-
- callback.Run(std::move(video_frame), playout_time, is_continuous);
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/receiver/cast_receiver_impl.h b/chromium/media/cast/receiver/cast_receiver_impl.h
deleted file mode 100644
index 81b8304a802..00000000000
--- a/chromium/media/cast/receiver/cast_receiver_impl.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2014 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 MEDIA_CAST_RECEIVER_CAST_RECEIVER_IMPL_H_
-#define MEDIA_CAST_RECEIVER_CAST_RECEIVER_IMPL_H_
-
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "media/cast/cast_environment.h"
-#include "media/cast/cast_receiver.h"
-#include "media/cast/common/rtp_time.h"
-#include "media/cast/net/pacing/paced_sender.h"
-#include "media/cast/receiver/frame_receiver.h"
-
-namespace media {
-namespace cast {
-
-class AudioDecoder;
-class VideoDecoder;
-
-// This is a pure owner class that groups all required receiver-related objects
-// together, such as the paced packet sender, audio/video RTP frame receivers,
-// and software decoders (created on-demand).
-class CastReceiverImpl final : public CastReceiver {
- public:
- CastReceiverImpl(scoped_refptr<CastEnvironment> cast_environment,
- const FrameReceiverConfig& audio_config,
- const FrameReceiverConfig& video_config,
- CastTransport* const transport);
-
- ~CastReceiverImpl() final;
-
- // CastReceiver implementation.
- void ReceivePacket(std::unique_ptr<Packet> packet) final;
- void RequestDecodedAudioFrame(
- const AudioFrameDecodedCallback& callback) final;
- void RequestDecodedVideoFrame(
- const VideoFrameDecodedCallback& callback) final;
-
- private:
- // Feeds an EncodedFrame into |audio_decoder_|. RequestDecodedAudioFrame()
- // uses this as a callback for RequestEncodedAudioFrame().
- void DecodeEncodedAudioFrame(const AudioFrameDecodedCallback& callback,
- std::unique_ptr<EncodedFrame> encoded_frame);
-
- // Feeds an EncodedFrame into |video_decoder_|. RequestDecodedVideoFrame()
- // uses this as a callback for RequestEncodedVideoFrame().
- void DecodeEncodedVideoFrame(const VideoFrameDecodedCallback& callback,
- std::unique_ptr<EncodedFrame> encoded_frame);
-
- // Receives an AudioBus from |audio_decoder_|, logs the event, and passes the
- // data on by running the given |callback|. This method is static to ensure
- // it can be called after a CastReceiverImpl instance is destroyed.
- // DecodeEncodedAudioFrame() uses this as a callback for
- // AudioDecoder::DecodeFrame().
- static void EmitDecodedAudioFrame(
- const scoped_refptr<CastEnvironment>& cast_environment,
- const AudioFrameDecodedCallback& callback,
- FrameId frame_id,
- RtpTimeTicks rtp_timestamp,
- const base::TimeTicks& playout_time,
- std::unique_ptr<AudioBus> audio_bus,
- bool is_continuous);
-
- // Receives a VideoFrame from |video_decoder_|, logs the event, and passes the
- // data on by running the given |callback|. This method is static to ensure
- // it can be called after a CastReceiverImpl instance is destroyed.
- // DecodeEncodedVideoFrame() uses this as a callback for
- // VideoDecoder::DecodeFrame().
- static void EmitDecodedVideoFrame(
- const scoped_refptr<CastEnvironment>& cast_environment,
- const VideoFrameDecodedCallback& callback,
- FrameId frame_id,
- RtpTimeTicks rtp_timestamp,
- const base::TimeTicks& playout_time,
- scoped_refptr<VideoFrame> video_frame,
- bool is_continuous);
-
- const scoped_refptr<CastEnvironment> cast_environment_;
- FrameReceiver audio_receiver_;
- FrameReceiver video_receiver_;
-
- // Used by DispatchReceivedPacket() to direct packets to the appropriate frame
- // receiver.
- const uint32_t ssrc_of_audio_sender_;
- const uint32_t ssrc_of_video_sender_;
-
- // Parameters for the decoders that are created on-demand. The values here
- // might be nonsense if the client of CastReceiverImpl never intends to use
- // the internal software-based decoders.
- const int num_audio_channels_;
- const int audio_sampling_rate_;
- const Codec audio_codec_;
- const Codec video_codec_;
-
- // Created on-demand to decode frames from |audio_receiver_| into AudioBuses
- // for playback.
- std::unique_ptr<AudioDecoder> audio_decoder_;
-
- // Created on-demand to decode frames from |video_receiver_| into VideoFrame
- // images for playback.
- std::unique_ptr<VideoDecoder> video_decoder_;
-
- DISALLOW_COPY_AND_ASSIGN(CastReceiverImpl);
-};
-
-} // namespace cast
-} // namespace media
-
-#endif // MEDIA_CAST_RECEIVER_CAST_RECEIVER_IMPL_H_
diff --git a/chromium/media/cast/receiver/frame_receiver.cc b/chromium/media/cast/receiver/frame_receiver.cc
deleted file mode 100644
index 33a35833524..00000000000
--- a/chromium/media/cast/receiver/frame_receiver.cc
+++ /dev/null
@@ -1,403 +0,0 @@
-// Copyright 2014 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 "media/cast/receiver/frame_receiver.h"
-
-#include <algorithm>
-#include <string>
-#include <utility>
-
-#include "base/big_endian.h"
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/numerics/safe_conversions.h"
-#include "media/cast/cast_config.h"
-#include "media/cast/cast_environment.h"
-#include "media/cast/constants.h"
-#include "media/cast/net/rtcp/rtcp_utility.h"
-
-namespace {
-
-const int kMinSchedulingDelayMs = 1;
-
-media::cast::RtcpTimeData CreateRtcpTimeData(base::TimeTicks now) {
- media::cast::RtcpTimeData ret;
- ret.timestamp = now;
- media::cast::ConvertTimeTicksToNtp(now, &ret.ntp_seconds, &ret.ntp_fraction);
- return ret;
-}
-
-} // namespace
-
-namespace media {
-namespace cast {
-
-FrameReceiver::FrameReceiver(
- const scoped_refptr<CastEnvironment>& cast_environment,
- const FrameReceiverConfig& config,
- EventMediaType event_media_type,
- CastTransport* const transport)
- : cast_environment_(cast_environment),
- transport_(transport),
- packet_parser_(
- config.sender_ssrc,
- config.rtp_payload_type <= RtpPayloadType::AUDIO_LAST ? 127 : 96),
- stats_(cast_environment->Clock()),
- event_media_type_(event_media_type),
- event_subscriber_(kReceiverRtcpEventHistorySize, event_media_type),
- rtp_timebase_(config.rtp_timebase),
- target_playout_delay_(
- base::TimeDelta::FromMilliseconds(config.rtp_max_delay_ms)),
- expected_frame_duration_(
- base::TimeDelta::FromSecondsD(1.0 / config.target_frame_rate)),
- reports_are_scheduled_(false),
- framer_(cast_environment->Clock(),
- this,
- config.sender_ssrc,
- true,
- static_cast<int>(config.rtp_max_delay_ms *
- config.target_frame_rate / 1000)),
- rtcp_(cast_environment_->Clock(),
- config.receiver_ssrc,
- config.sender_ssrc),
- is_waiting_for_consecutive_frame_(false),
- lip_sync_drift_(ClockDriftSmoother::GetDefaultTimeConstant()) {
- transport_->AddValidRtpReceiver(config.sender_ssrc, config.receiver_ssrc);
- DCHECK_GT(config.rtp_max_delay_ms, 0);
- DCHECK_GT(config.target_frame_rate, 0);
- decryptor_.Initialize(config.aes_key, config.aes_iv_mask);
- cast_environment_->logger()->Subscribe(&event_subscriber_);
-}
-
-FrameReceiver::~FrameReceiver() {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- cast_environment_->logger()->Unsubscribe(&event_subscriber_);
-}
-
-void FrameReceiver::RequestEncodedFrame(ReceiveEncodedFrameCallback callback) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- frame_request_queue_.push_back(std::move(callback));
- EmitAvailableEncodedFrames();
-}
-
-bool FrameReceiver::ProcessPacket(std::unique_ptr<Packet> packet) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-
- if (IsRtcpPacket(&packet->front(), packet->size())) {
- rtcp_.IncomingRtcpPacket(&packet->front(), packet->size());
- } else {
- RtpCastHeader rtp_header;
- const uint8_t* payload_data;
- size_t payload_size;
- if (!packet_parser_.ParsePacket(&packet->front(),
- packet->size(),
- &rtp_header,
- &payload_data,
- &payload_size)) {
- return false;
- }
-
- ProcessParsedPacket(rtp_header, payload_data, payload_size);
- stats_.UpdateStatistics(rtp_header, rtp_timebase_);
- }
-
- if (!reports_are_scheduled_) {
- ScheduleNextRtcpReport();
- ScheduleNextCastMessage();
- reports_are_scheduled_ = true;
- }
-
- return true;
-}
-
-base::WeakPtr<FrameReceiver> FrameReceiver::AsWeakPtr() {
- return weak_factory_.GetWeakPtr();
-}
-
-void FrameReceiver::ProcessParsedPacket(const RtpCastHeader& rtp_header,
- const uint8_t* payload_data,
- size_t payload_size) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-
- const base::TimeTicks now = cast_environment_->Clock()->NowTicks();
-
- frame_id_to_rtp_timestamp_[rtp_header.frame_id.lower_8_bits()] =
- rtp_header.rtp_timestamp;
-
- std::unique_ptr<PacketEvent> receive_event(new PacketEvent());
- receive_event->timestamp = now;
- receive_event->type = PACKET_RECEIVED;
- receive_event->media_type = event_media_type_;
- receive_event->rtp_timestamp = rtp_header.rtp_timestamp;
- receive_event->frame_id = rtp_header.frame_id;
- receive_event->packet_id = rtp_header.packet_id;
- receive_event->max_packet_id = rtp_header.max_packet_id;
- receive_event->size = base::checked_cast<uint32_t>(payload_size);
- cast_environment_->logger()->DispatchPacketEvent(std::move(receive_event));
-
- bool duplicate = false;
- const bool complete =
- framer_.InsertPacket(payload_data, payload_size, rtp_header, &duplicate);
-
- // Duplicate packets are ignored.
- if (duplicate)
- return;
-
- // Update lip-sync values upon receiving the first packet of each frame, or if
- // they have never been set yet.
- if (rtp_header.packet_id == 0 || lip_sync_reference_time_.is_null()) {
- RtpTimeTicks fresh_sync_rtp;
- base::TimeTicks fresh_sync_reference;
- if (!rtcp_.GetLatestLipSyncTimes(&fresh_sync_rtp, &fresh_sync_reference)) {
- // HACK: The sender should have provided Sender Reports before the first
- // frame was sent. However, the spec does not currently require this.
- // Therefore, when the data is missing, the local clock is used to
- // generate reference timestamps.
- VLOG(2) << "Lip sync info missing. Falling-back to local clock.";
- fresh_sync_rtp = rtp_header.rtp_timestamp;
- fresh_sync_reference = now;
- }
- // |lip_sync_reference_time_| is always incremented according to the time
- // delta computed from the difference in RTP timestamps. Then,
- // |lip_sync_drift_| accounts for clock drift and also smoothes-out any
- // sudden/discontinuous shifts in the series of reference time values.
- if (lip_sync_reference_time_.is_null()) {
- lip_sync_reference_time_ = fresh_sync_reference;
- } else {
- // Note: It's okay for the conversion ToTimeDelta() to be approximate
- // because |lip_sync_drift_| will account for accumulated errors.
- lip_sync_reference_time_ +=
- (fresh_sync_rtp - lip_sync_rtp_timestamp_).ToTimeDelta(rtp_timebase_);
- }
- lip_sync_rtp_timestamp_ = fresh_sync_rtp;
- lip_sync_drift_.Update(
- now, fresh_sync_reference - lip_sync_reference_time_);
- }
-
- // Another frame is complete from a non-duplicate packet. Attempt to emit
- // more frames to satisfy enqueued requests.
- if (complete)
- EmitAvailableEncodedFrames();
-}
-
-void FrameReceiver::CastFeedback(const RtcpCastMessage& cast_message) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-
- base::TimeTicks now = cast_environment_->Clock()->NowTicks();
- RtpTimeTicks rtp_timestamp =
- frame_id_to_rtp_timestamp_[cast_message.ack_frame_id.lower_8_bits()];
-
- std::unique_ptr<FrameEvent> ack_sent_event(new FrameEvent());
- ack_sent_event->timestamp = now;
- ack_sent_event->type = FRAME_ACK_SENT;
- ack_sent_event->media_type = event_media_type_;
- ack_sent_event->rtp_timestamp = rtp_timestamp;
- ack_sent_event->frame_id = cast_message.ack_frame_id;
- cast_environment_->logger()->DispatchFrameEvent(std::move(ack_sent_event));
-
- ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events;
- event_subscriber_.GetRtcpEventsWithRedundancy(&rtcp_events);
- SendRtcpReport(rtcp_.local_ssrc(), rtcp_.remote_ssrc(),
- CreateRtcpTimeData(now), &cast_message, nullptr,
- target_playout_delay_, &rtcp_events, nullptr);
-}
-
-void FrameReceiver::EmitAvailableEncodedFrames() {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-
- while (!frame_request_queue_.empty()) {
- // Attempt to peek at the next completed frame from the |framer_|.
- // TODO(miu): We should only be peeking at the metadata, and not copying the
- // payload yet! Or, at least, peek using a StringPiece instead of a copy.
- std::unique_ptr<EncodedFrame> encoded_frame(new EncodedFrame());
- bool is_consecutively_next_frame = false;
- bool have_multiple_complete_frames = false;
- if (!framer_.GetEncodedFrame(encoded_frame.get(),
- &is_consecutively_next_frame,
- &have_multiple_complete_frames)) {
- VLOG(1) << "Wait for more packets to produce a completed frame.";
- return; // ProcessParsedPacket() will invoke this method in the future.
- }
-
- const base::TimeTicks now = cast_environment_->Clock()->NowTicks();
- const base::TimeTicks playout_time = GetPlayoutTime(*encoded_frame);
-
- // If we have multiple decodable frames, and the current frame is
- // too old, then skip it and decode the next frame instead.
- if (have_multiple_complete_frames && now > playout_time) {
- framer_.ReleaseFrame(encoded_frame->frame_id);
- continue;
- }
-
- // If |framer_| has a frame ready that is out of sequence, examine the
- // playout time to determine whether it's acceptable to continue, thereby
- // skipping one or more frames. Skip if the missing frame wouldn't complete
- // playing before the start of playback of the available frame.
- if (!is_consecutively_next_frame) {
- // This assumes that decoding takes as long as playing, which might
- // not be true.
- const base::TimeTicks earliest_possible_end_time_of_missing_frame =
- now + expected_frame_duration_ * 2;
- if (earliest_possible_end_time_of_missing_frame < playout_time) {
- VLOG(1) << "Wait for next consecutive frame instead of skipping.";
- if (!is_waiting_for_consecutive_frame_) {
- is_waiting_for_consecutive_frame_ = true;
- cast_environment_->PostDelayedTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(
- &FrameReceiver::EmitAvailableEncodedFramesAfterWaiting,
- AsWeakPtr()),
- playout_time - now);
- }
- return;
- }
- }
-
- // At this point, we have the complete next frame, or a decodable
- // frame from somewhere later in the stream, AND we have given up
- // on waiting for any frames in between, so now we can ACK the frame.
- framer_.AckFrame(encoded_frame->frame_id);
-
- // Decrypt the payload data in the frame, if crypto is being used.
- if (decryptor_.is_activated()) {
- std::string decrypted_data;
- if (!decryptor_.Decrypt(encoded_frame->frame_id,
- encoded_frame->data,
- &decrypted_data)) {
- // Decryption failed. Give up on this frame.
- framer_.ReleaseFrame(encoded_frame->frame_id);
- continue;
- }
- encoded_frame->data.swap(decrypted_data);
- }
-
- // At this point, we have a decrypted EncodedFrame ready to be emitted.
- encoded_frame->reference_time = playout_time;
- framer_.ReleaseFrame(encoded_frame->frame_id);
- if (encoded_frame->new_playout_delay_ms) {
- target_playout_delay_ = base::TimeDelta::FromMilliseconds(
- encoded_frame->new_playout_delay_ms);
- }
- cast_environment_->PostTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(&FrameReceiver::EmitOneFrame, AsWeakPtr(),
- std::move(*frame_request_queue_.begin()),
- std::move(encoded_frame)));
- frame_request_queue_.pop_front();
- }
-}
-
-void FrameReceiver::EmitAvailableEncodedFramesAfterWaiting() {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- DCHECK(is_waiting_for_consecutive_frame_);
- is_waiting_for_consecutive_frame_ = false;
- EmitAvailableEncodedFrames();
-}
-
-void FrameReceiver::EmitOneFrame(
- ReceiveEncodedFrameCallback callback,
- std::unique_ptr<EncodedFrame> encoded_frame) const {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- if (!callback.is_null())
- std::move(callback).Run(std::move(encoded_frame));
-}
-
-base::TimeTicks FrameReceiver::GetPlayoutTime(const EncodedFrame& frame) const {
- base::TimeDelta target_playout_delay = target_playout_delay_;
- if (frame.new_playout_delay_ms) {
- target_playout_delay = base::TimeDelta::FromMilliseconds(
- frame.new_playout_delay_ms);
- }
- return lip_sync_reference_time_ + lip_sync_drift_.Current() +
- (frame.rtp_timestamp - lip_sync_rtp_timestamp_)
- .ToTimeDelta(rtp_timebase_) +
- target_playout_delay;
-}
-
-void FrameReceiver::ScheduleNextCastMessage() {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- base::TimeTicks send_time;
- framer_.TimeToSendNextCastMessage(&send_time);
- base::TimeDelta time_to_send =
- send_time - cast_environment_->Clock()->NowTicks();
- time_to_send = std::max(
- time_to_send, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
- cast_environment_->PostDelayedTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(&FrameReceiver::SendNextCastMessage, AsWeakPtr()),
- time_to_send);
-}
-
-void FrameReceiver::SendNextCastMessage() {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- framer_.SendCastMessage(); // Will only send a message if it is time.
- ScheduleNextCastMessage();
-}
-
-void FrameReceiver::ScheduleNextRtcpReport() {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-
- cast_environment_->PostDelayedTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(&FrameReceiver::SendNextRtcpReport, AsWeakPtr()),
- base::TimeDelta::FromMilliseconds(kRtcpReportIntervalMs));
-}
-
-void FrameReceiver::SendNextRtcpReport() {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- const base::TimeTicks now = cast_environment_->Clock()->NowTicks();
- RtpReceiverStatistics stats = stats_.GetStatistics();
- SendRtcpReport(rtcp_.local_ssrc(), rtcp_.remote_ssrc(),
- CreateRtcpTimeData(now), nullptr, nullptr, base::TimeDelta(),
- nullptr, &stats);
- ScheduleNextRtcpReport();
-}
-
-void FrameReceiver::SendRtcpReport(
- uint32_t rtp_receiver_ssrc,
- uint32_t rtp_sender_ssrc,
- const RtcpTimeData& time_data,
- const RtcpCastMessage* cast_message,
- const RtcpPliMessage* pli_message,
- base::TimeDelta target_delay,
- const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events,
- const RtpReceiverStatistics* rtp_receiver_statistics) {
- transport_->InitializeRtpReceiverRtcpBuilder(rtp_receiver_ssrc, time_data);
- RtcpReportBlock report_block;
- if (rtp_receiver_statistics) {
- report_block.remote_ssrc = 0; // Not needed to set send side.
- report_block.media_ssrc =
- rtp_sender_ssrc; // SSRC of the RTP packet sender.
- report_block.fraction_lost = rtp_receiver_statistics->fraction_lost;
- report_block.cumulative_lost = rtp_receiver_statistics->cumulative_lost;
- report_block.extended_high_sequence_number =
- rtp_receiver_statistics->extended_high_sequence_number;
- report_block.jitter = rtp_receiver_statistics->jitter;
- report_block.last_sr = rtcp_.last_report_truncated_ntp();
- base::TimeTicks last_report_received_time =
- rtcp_.time_last_report_received();
- if (!last_report_received_time.is_null()) {
- uint32_t delay_seconds = 0;
- uint32_t delay_fraction = 0;
- base::TimeDelta delta = time_data.timestamp - last_report_received_time;
- ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds,
- &delay_fraction);
- report_block.delay_since_last_sr =
- ConvertToNtpDiff(delay_seconds, delay_fraction);
- } else {
- report_block.delay_since_last_sr = 0;
- }
- transport_->AddRtpReceiverReport(report_block);
- }
- if (cast_message)
- transport_->AddCastFeedback(*cast_message, target_delay);
- if (pli_message)
- transport_->AddPli(*pli_message);
- if (rtcp_events)
- transport_->AddRtcpEvents(*rtcp_events);
- transport_->SendRtcpFromRtpReceiver();
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/receiver/frame_receiver.h b/chromium/media/cast/receiver/frame_receiver.h
deleted file mode 100644
index c5d2cb4f27e..00000000000
--- a/chromium/media/cast/receiver/frame_receiver.h
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright 2014 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 MEDIA_CAST_RECEIVER_FRAME_RECEIVER_H_
-#define MEDIA_CAST_RECEIVER_FRAME_RECEIVER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <list>
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
-#include "media/cast/cast_receiver.h"
-#include "media/cast/common/clock_drift_smoother.h"
-#include "media/cast/common/rtp_time.h"
-#include "media/cast/common/transport_encryption_handler.h"
-#include "media/cast/logging/logging_defines.h"
-#include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h"
-#include "media/cast/net/rtcp/receiver_rtcp_session.h"
-#include "media/cast/net/rtp/framer.h"
-#include "media/cast/net/rtp/receiver_stats.h"
-#include "media/cast/net/rtp/rtp_defines.h"
-#include "media/cast/net/rtp/rtp_parser.h"
-
-namespace media {
-namespace cast {
-
-class CastEnvironment;
-
-// The following callback delivers encoded frame data and metadata. The client
-// should examine the |frame_id| field to determine whether any frames have been
-// dropped (i.e., frame_id should be incrementing by one each time). Note: A
-// nullptr can be returned on error.
-using ReceiveEncodedFrameCallback =
- base::OnceCallback<void(std::unique_ptr<EncodedFrame>)>;
-
-// FrameReceiver receives packets out-of-order while clients make requests for
-// complete frames in-order. (A frame consists of one or more packets.)
-//
-// FrameReceiver also includes logic for computing the playout time for each
-// frame, accounting for a constant targeted playout delay. The purpose of the
-// playout delay is to provide a fixed window of time between the capture event
-// on the sender and the playout on the receiver. This is important because
-// each step of the pipeline (i.e., encode frame, then transmit/retransmit from
-// the sender, then receive and re-order packets on the receiver, then decode
-// frame) can vary in duration and is typically very hard to predict.
-//
-// Each request for a frame includes a callback which FrameReceiver guarantees
-// will be called at some point in the future unless the FrameReceiver is
-// destroyed. Clients should generally limit the number of outstanding requests
-// (perhaps to just one or two).
-//
-// This class is not thread safe. Should only be called from the Main cast
-// thread.
-class FrameReceiver final : public RtpPayloadFeedback {
- public:
- FrameReceiver(const scoped_refptr<CastEnvironment>& cast_environment,
- const FrameReceiverConfig& config,
- EventMediaType event_media_type,
- CastTransport* const transport);
-
- ~FrameReceiver() final;
-
- // Request an encoded frame.
- //
- // The given |callback| is guaranteed to be run at some point in the future,
- // except for those requests still enqueued at destruction time.
- void RequestEncodedFrame(ReceiveEncodedFrameCallback callback);
-
- // Called to deliver another packet, possibly a duplicate, and possibly
- // out-of-order. Returns true if the parsing of the packet succeeded.
- bool ProcessPacket(std::unique_ptr<Packet> packet);
-
- base::WeakPtr<FrameReceiver> AsWeakPtr();
-
- protected:
- friend class FrameReceiverTest; // Invokes ProcessParsedPacket().
-
- void ProcessParsedPacket(const RtpCastHeader& rtp_header,
- const uint8_t* payload_data,
- size_t payload_size);
-
- // RtpPayloadFeedback implementation.
- void CastFeedback(const RtcpCastMessage& cast_message) final;
-
- private:
- // Processes ready-to-consume packets from |framer_|, decrypting each packet's
- // payload data, and then running the enqueued callbacks in order (one for
- // each packet). This method may post a delayed task to re-invoke itself in
- // the future to wait for missing/incomplete frames.
- void EmitAvailableEncodedFrames();
-
- // Clears the |is_waiting_for_consecutive_frame_| flag and invokes
- // EmitAvailableEncodedFrames().
- void EmitAvailableEncodedFramesAfterWaiting();
-
- // Helper that runs |callback|, passing ownership of |encoded_frame| to it.
- // This method is used by EmitAvailableEncodedFrames() to return to the event
- // loop, but make sure that FrameReceiver is still alive before the callback
- // is run.
- void EmitOneFrame(ReceiveEncodedFrameCallback callback,
- std::unique_ptr<EncodedFrame> encoded_frame) const;
-
- // Computes the playout time for a frame with the given |rtp_timestamp|.
- // Because lip-sync info is refreshed regularly, calling this method with the
- // same argument may return different results.
- base::TimeTicks GetPlayoutTime(const EncodedFrame& frame) const;
-
- // Schedule timing for the next cast message.
- void ScheduleNextCastMessage();
-
- // Schedule timing for the next RTCP report.
- void ScheduleNextRtcpReport();
-
- // Actually send the next cast message.
- void SendNextCastMessage();
-
- // Actually send the next RTCP report.
- void SendNextRtcpReport();
-
- // Interface to send RTCP reports.
- // |cast_message|, |rtcp_events| and |rtp_receiver_statistics| are optional;
- // if |cast_message| is provided the RTCP receiver report will contain a Cast
- // ACK/NACK feedback message; |target_delay| is sent together with
- // |cast_message|. If |rtcp_events| is provided the RTCP receiver report will
- // include event log messages
- void SendRtcpReport(
- uint32_t rtp_receiver_ssrc,
- uint32_t rtp_sender_ssrc,
- const RtcpTimeData& time_data,
- const RtcpCastMessage* cast_message,
- const RtcpPliMessage* pli_message,
- base::TimeDelta target_delay,
- const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events,
- const RtpReceiverStatistics* rtp_receiver_statistics);
-
- const scoped_refptr<CastEnvironment> cast_environment_;
-
- // Transport used to send data back.
- CastTransport* const transport_;
-
- // Deserializes a packet into a RtpHeader + payload bytes.
- RtpParser packet_parser_;
-
- // Accumulates packet statistics, including packet loss, counts, and jitter.
- ReceiverStats stats_;
-
- // Partitions logged events by the type of media passing through.
- EventMediaType event_media_type_;
-
- // Subscribes to raw events.
- // Processes raw events to be sent over to the cast sender via RTCP.
- ReceiverRtcpEventSubscriber event_subscriber_;
-
- // RTP timebase: The number of RTP units advanced per one second.
- const int rtp_timebase_;
-
- // The total amount of time between a frame's capture/recording on the sender
- // and its playback on the receiver (i.e., shown to a user). This is fixed as
- // a value large enough to give the system sufficient time to encode,
- // transmit/retransmit, receive, decode, and render; given its run-time
- // environment (sender/receiver hardware performance, network conditions,
- // etc.).
- base::TimeDelta target_playout_delay_;
-
- // Hack: This is used in logic that determines whether to skip frames.
- // TODO(miu): Revisit this. Logic needs to also account for expected decode
- // time.
- const base::TimeDelta expected_frame_duration_;
-
- // Set to false initially, then set to true after scheduling the periodic
- // sending of reports back to the sender. Reports are first scheduled just
- // after receiving a first packet (since the first packet identifies the
- // sender for the remainder of the session).
- bool reports_are_scheduled_;
-
- // Assembles packets into frames, providing this receiver with complete,
- // decodable EncodedFrames.
- Framer framer_;
-
- // Manages sending/receiving of RTCP packets, including sender/receiver
- // reports.
- ReceiverRtcpSession rtcp_;
-
- // Decrypts encrypted frames.
- TransportEncryptionHandler decryptor_;
-
- // Outstanding callbacks to run to deliver on client requests for frames.
- std::list<ReceiveEncodedFrameCallback> frame_request_queue_;
-
- // True while there's an outstanding task to re-invoke
- // EmitAvailableEncodedFrames().
- bool is_waiting_for_consecutive_frame_;
-
- // This mapping allows us to log FRAME_ACK_SENT as a frame event. In addition
- // it allows the event to be transmitted via RTCP. The index into this ring
- // buffer is the lower 8 bits of the FrameId.
- RtpTimeTicks frame_id_to_rtp_timestamp_[256];
-
- // Lip-sync values used to compute the playout time of each frame from its RTP
- // timestamp. These are updated each time the first packet of a frame is
- // received.
- RtpTimeTicks lip_sync_rtp_timestamp_;
- base::TimeTicks lip_sync_reference_time_;
- ClockDriftSmoother lip_sync_drift_;
-
- // NOTE: Weak pointers must be invalidated before all other member variables.
- base::WeakPtrFactory<FrameReceiver> weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(FrameReceiver);
-};
-
-} // namespace cast
-} // namespace media
-
-#endif // MEDIA_CAST_RECEIVER_FRAME_RECEIVER_H_
diff --git a/chromium/media/cast/receiver/frame_receiver_unittest.cc b/chromium/media/cast/receiver/frame_receiver_unittest.cc
deleted file mode 100644
index 9e8bdbed4d7..00000000000
--- a/chromium/media/cast/receiver/frame_receiver_unittest.cc
+++ /dev/null
@@ -1,457 +0,0 @@
-// Copyright 2014 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 "media/cast/receiver/frame_receiver.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/containers/circular_deque.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "media/base/fake_single_thread_task_runner.h"
-#include "media/cast/cast_environment.h"
-#include "media/cast/logging/simple_event_subscriber.h"
-#include "media/cast/net/cast_transport_impl.h"
-#include "media/cast/net/rtcp/rtcp_utility.h"
-#include "media/cast/net/rtcp/test_rtcp_packet_builder.h"
-#include "media/cast/test/mock_cast_transport.h"
-#include "media/cast/test/utility/default_config.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-using ::testing::_;
-
-namespace media {
-namespace cast {
-
-namespace {
-
-const int kPacketSize = 1500;
-const int kPlayoutDelayMillis = 100;
-
-FrameId GetFirstTestFrameId() {
- return FrameId::first() + 1234;
-}
-
-class FakeFrameClient {
- public:
- FakeFrameClient() : num_called_(0) {}
- virtual ~FakeFrameClient() = default;
-
- void AddExpectedResult(FrameId expected_frame_id,
- const base::TimeTicks& expected_playout_time) {
- expected_results_.push_back(
- std::make_pair(expected_frame_id, expected_playout_time));
- }
-
- void DeliverEncodedFrame(std::unique_ptr<EncodedFrame> frame) {
- SCOPED_TRACE(::testing::Message() << "num_called_ is " << num_called_);
- ASSERT_TRUE(frame)
- << "If at shutdown: There were unsatisfied requests enqueued.";
- ASSERT_FALSE(expected_results_.empty());
- EXPECT_EQ(expected_results_.front().first, frame->frame_id);
- EXPECT_EQ(expected_results_.front().second, frame->reference_time);
- expected_results_.pop_front();
- ++num_called_;
- }
-
- int number_times_called() const { return num_called_; }
-
- private:
- base::circular_deque<std::pair<FrameId, base::TimeTicks>> expected_results_;
- int num_called_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeFrameClient);
-};
-} // namespace
-
-class FrameReceiverTest : public ::testing::Test {
- protected:
- FrameReceiverTest() {
- testing_clock_.Advance(base::TimeTicks::Now() - base::TimeTicks());
- start_time_ = testing_clock_.NowTicks();
- task_runner_ = new FakeSingleThreadTaskRunner(&testing_clock_);
-
- cast_environment_ = new CastEnvironment(&testing_clock_, task_runner_,
- task_runner_, task_runner_);
- }
-
- ~FrameReceiverTest() override = default;
-
- void SetUp() final {
- payload_.assign(kPacketSize, 0);
-
- // Always start with a key frame.
- rtp_header_.is_key_frame = true;
- rtp_header_.frame_id = GetFirstTestFrameId();
- rtp_header_.packet_id = 0;
- rtp_header_.max_packet_id = 0;
- rtp_header_.reference_frame_id = rtp_header_.frame_id;
- rtp_header_.rtp_timestamp = RtpTimeTicks();
- }
-
- void CreateFrameReceiverOfAudio() {
- config_ = GetDefaultAudioReceiverConfig();
- config_.rtp_max_delay_ms = kPlayoutDelayMillis;
-
- receiver_ = std::make_unique<FrameReceiver>(cast_environment_, config_,
- AUDIO_EVENT, &mock_transport_);
- }
-
- void CreateFrameReceiverOfVideo() {
- config_ = GetDefaultVideoReceiverConfig();
- config_.rtp_max_delay_ms = kPlayoutDelayMillis;
- // Note: Frame rate must divide 1000 without remainder so the test code
- // doesn't have to account for rounding errors.
- config_.target_frame_rate = 25;
-
- receiver_ = std::make_unique<FrameReceiver>(cast_environment_, config_,
- VIDEO_EVENT, &mock_transport_);
- }
-
- void FeedOneFrameIntoReceiver() {
- // Note: For testing purposes, a frame consists of only a single packet.
- receiver_->ProcessParsedPacket(
- rtp_header_, &payload_[0], payload_.size());
- }
-
- void FeedLipSyncInfoIntoReceiver() {
- const base::TimeTicks now = testing_clock_.NowTicks();
- const RtpTimeTicks rtp_timestamp =
- RtpTimeTicks::FromTimeDelta(now - start_time_, config_.rtp_timebase);
- CHECK_LE(RtpTimeTicks(), rtp_timestamp);
- uint32_t ntp_seconds;
- uint32_t ntp_fraction;
- ConvertTimeTicksToNtp(now, &ntp_seconds, &ntp_fraction);
- TestRtcpPacketBuilder rtcp_packet;
- rtcp_packet.AddSrWithNtp(config_.sender_ssrc, ntp_seconds, ntp_fraction,
- rtp_timestamp.lower_32_bits());
- ASSERT_TRUE(receiver_->ProcessPacket(rtcp_packet.GetPacket()));
- }
-
- FrameReceiverConfig config_;
- std::vector<uint8_t> payload_;
- RtpCastHeader rtp_header_;
- base::SimpleTestTickClock testing_clock_;
- base::TimeTicks start_time_;
- MockCastTransport mock_transport_;
- scoped_refptr<FakeSingleThreadTaskRunner> task_runner_;
- scoped_refptr<CastEnvironment> cast_environment_;
- FakeFrameClient frame_client_;
-
- // Important for the FrameReceiver to be declared last, since its dependencies
- // must remain alive until after its destruction.
- std::unique_ptr<FrameReceiver> receiver_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FrameReceiverTest);
-};
-
-TEST_F(FrameReceiverTest, RejectsUnparsablePackets) {
- EXPECT_CALL(mock_transport_, AddValidRtpReceiver(_, _))
- .WillRepeatedly(testing::Return());
-
- CreateFrameReceiverOfVideo();
-
- SimpleEventSubscriber event_subscriber;
- cast_environment_->logger()->Subscribe(&event_subscriber);
-
- const bool success =
- receiver_->ProcessPacket(std::make_unique<Packet>(kPacketSize, 0xff));
- EXPECT_FALSE(success);
-
- // Confirm no log events.
- std::vector<FrameEvent> frame_events;
- event_subscriber.GetFrameEventsAndReset(&frame_events);
- EXPECT_TRUE(frame_events.empty());
- cast_environment_->logger()->Unsubscribe(&event_subscriber);
-}
-
-TEST_F(FrameReceiverTest, ReceivesOneFrame) {
- EXPECT_CALL(mock_transport_, AddValidRtpReceiver(_, _))
- .WillRepeatedly(testing::Return());
-
- CreateFrameReceiverOfAudio();
-
- SimpleEventSubscriber event_subscriber;
- cast_environment_->logger()->Subscribe(&event_subscriber);
-
- EXPECT_CALL(mock_transport_, InitializeRtpReceiverRtcpBuilder(_, _))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, AddCastFeedback(_, _))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, AddPli(_)).WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, AddRtcpEvents(_))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, SendRtcpFromRtpReceiver())
- .WillRepeatedly(testing::Return());
-
- FeedLipSyncInfoIntoReceiver();
- task_runner_->RunTasks();
-
- // Enqueue a request for a frame.
- receiver_->RequestEncodedFrame(base::BindOnce(
- &FakeFrameClient::DeliverEncodedFrame, base::Unretained(&frame_client_)));
-
- // The request should not be satisfied since no packets have been received.
- task_runner_->RunTasks();
- EXPECT_EQ(0, frame_client_.number_times_called());
-
- // Deliver one frame to the receiver and expect to get one frame back.
- const base::TimeDelta target_playout_delay =
- base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis);
- frame_client_.AddExpectedResult(
- GetFirstTestFrameId(), testing_clock_.NowTicks() + target_playout_delay);
- FeedOneFrameIntoReceiver();
- task_runner_->RunTasks();
- EXPECT_EQ(1, frame_client_.number_times_called());
-
- // Was the frame logged?
- std::vector<FrameEvent> frame_events;
- event_subscriber.GetFrameEventsAndReset(&frame_events);
- ASSERT_TRUE(!frame_events.empty());
- EXPECT_EQ(FRAME_ACK_SENT, frame_events.begin()->type);
- EXPECT_EQ(AUDIO_EVENT, frame_events.begin()->media_type);
- EXPECT_EQ(rtp_header_.frame_id, frame_events.begin()->frame_id);
- EXPECT_EQ(rtp_header_.rtp_timestamp, frame_events.begin()->rtp_timestamp);
- cast_environment_->logger()->Unsubscribe(&event_subscriber);
-}
-
-TEST_F(FrameReceiverTest, ReceivesFramesSkippingWhenAppropriate) {
- EXPECT_CALL(mock_transport_, AddValidRtpReceiver(_, _))
- .WillRepeatedly(testing::Return());
-
- CreateFrameReceiverOfAudio();
-
- SimpleEventSubscriber event_subscriber;
- cast_environment_->logger()->Subscribe(&event_subscriber);
-
- EXPECT_CALL(mock_transport_, InitializeRtpReceiverRtcpBuilder(_, _))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, AddCastFeedback(_, _))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, AddPli(_)).WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, AddRtcpEvents(_))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, SendRtcpFromRtpReceiver())
- .WillRepeatedly(testing::Return());
-
- const base::TimeDelta time_advance_per_frame =
- base::TimeDelta::FromSeconds(1) / config_.target_frame_rate;
- const RtpTimeDelta rtp_advance_per_frame =
- RtpTimeDelta::FromTimeDelta(time_advance_per_frame, config_.rtp_timebase);
-
- // Feed and process lip sync in receiver.
- FeedLipSyncInfoIntoReceiver();
- task_runner_->RunTasks();
- const base::TimeTicks first_frame_capture_time = testing_clock_.NowTicks();
-
- // Enqueue a request for a frame.
- receiver_->RequestEncodedFrame(base::BindOnce(
- &FakeFrameClient::DeliverEncodedFrame, base::Unretained(&frame_client_)));
- task_runner_->RunTasks();
- EXPECT_EQ(0, frame_client_.number_times_called());
-
- // Receive one frame and expect to see the first request satisfied.
- const base::TimeDelta target_playout_delay =
- base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis);
- frame_client_.AddExpectedResult(
- GetFirstTestFrameId(), first_frame_capture_time + target_playout_delay);
- rtp_header_.rtp_timestamp = RtpTimeTicks();
- FeedOneFrameIntoReceiver(); // Frame 1
- task_runner_->RunTasks();
- EXPECT_EQ(1, frame_client_.number_times_called());
-
- // Enqueue a second request for a frame, but it should not be fulfilled yet.
- receiver_->RequestEncodedFrame(base::BindOnce(
- &FakeFrameClient::DeliverEncodedFrame, base::Unretained(&frame_client_)));
- task_runner_->RunTasks();
- EXPECT_EQ(1, frame_client_.number_times_called());
-
- // Receive one frame out-of-order: Make sure that we are not continuous and
- // that the RTP timestamp represents a time in the future.
- rtp_header_.frame_id = GetFirstTestFrameId() + 2; // "Frame 3"
- rtp_header_.reference_frame_id = rtp_header_.frame_id;
- rtp_header_.rtp_timestamp += rtp_advance_per_frame * 2;
- frame_client_.AddExpectedResult(rtp_header_.frame_id,
- first_frame_capture_time +
- 2 * time_advance_per_frame +
- target_playout_delay);
- FeedOneFrameIntoReceiver(); // Frame 3
-
- // Frame 2 should not come out at this point in time.
- task_runner_->RunTasks();
- EXPECT_EQ(1, frame_client_.number_times_called());
-
- // Enqueue a third request for a frame.
- receiver_->RequestEncodedFrame(base::BindOnce(
- &FakeFrameClient::DeliverEncodedFrame, base::Unretained(&frame_client_)));
- task_runner_->RunTasks();
- EXPECT_EQ(1, frame_client_.number_times_called());
-
- // Now, advance time forward such that the receiver is convinced it should
- // skip Frame 2. Frame 3 is emitted (to satisfy the second request) because a
- // decision was made to skip over the no-show Frame 2.
- testing_clock_.Advance(2 * time_advance_per_frame + target_playout_delay);
- task_runner_->RunTasks();
- EXPECT_EQ(2, frame_client_.number_times_called());
-
- // Receive Frame 4 and expect it to fulfill the third request immediately.
- rtp_header_.frame_id = GetFirstTestFrameId() + 3; // "Frame 4"
- rtp_header_.reference_frame_id = rtp_header_.frame_id;
- rtp_header_.rtp_timestamp += rtp_advance_per_frame;
- frame_client_.AddExpectedResult(rtp_header_.frame_id,
- first_frame_capture_time +
- 3 * time_advance_per_frame +
- target_playout_delay);
- FeedOneFrameIntoReceiver(); // Frame 4
- task_runner_->RunTasks();
- EXPECT_EQ(3, frame_client_.number_times_called());
-
- // Move forward to the playout time of an unreceived Frame 5. Expect no
- // additional frames were emitted.
- testing_clock_.Advance(3 * time_advance_per_frame);
- task_runner_->RunTasks();
- EXPECT_EQ(3, frame_client_.number_times_called());
-
- // Were only non-skipped frames logged?
- std::vector<FrameEvent> frame_events;
- event_subscriber.GetFrameEventsAndReset(&frame_events);
- ASSERT_TRUE(!frame_events.empty());
- for (size_t i = 0; i < frame_events.size(); ++i) {
- EXPECT_EQ(FRAME_ACK_SENT, frame_events[i].type);
- EXPECT_EQ(AUDIO_EVENT, frame_events[i].media_type);
- EXPECT_LE(GetFirstTestFrameId(), frame_events[i].frame_id);
- EXPECT_GE(GetFirstTestFrameId() + 4, frame_events[i].frame_id);
- const int frame_offset = frame_events[i].frame_id - GetFirstTestFrameId();
- EXPECT_NE(frame_offset, 1); // Frame 2 never received.
- EXPECT_EQ(RtpTimeTicks() + (rtp_advance_per_frame * frame_offset),
- frame_events[i].rtp_timestamp);
- }
- cast_environment_->logger()->Unsubscribe(&event_subscriber);
-}
-
-TEST_F(FrameReceiverTest, ReceivesFramesRefusingToSkipAny) {
- EXPECT_CALL(mock_transport_, AddValidRtpReceiver(_, _))
- .WillRepeatedly(testing::Return());
-
- CreateFrameReceiverOfVideo();
-
- SimpleEventSubscriber event_subscriber;
- cast_environment_->logger()->Subscribe(&event_subscriber);
-
- EXPECT_CALL(mock_transport_, InitializeRtpReceiverRtcpBuilder(_, _))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, AddCastFeedback(_, _))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, AddPli(_)).WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, AddRtcpEvents(_))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(mock_transport_, SendRtcpFromRtpReceiver())
- .WillRepeatedly(testing::Return());
-
- const base::TimeDelta time_advance_per_frame =
- base::TimeDelta::FromSeconds(1) / config_.target_frame_rate;
- const RtpTimeDelta rtp_advance_per_frame =
- RtpTimeDelta::FromTimeDelta(time_advance_per_frame, config_.rtp_timebase);
-
- // Feed and process lip sync in receiver.
- FeedLipSyncInfoIntoReceiver();
- task_runner_->RunTasks();
- const base::TimeTicks first_frame_capture_time = testing_clock_.NowTicks();
-
- // Enqueue a request for a frame.
- receiver_->RequestEncodedFrame(base::BindOnce(
- &FakeFrameClient::DeliverEncodedFrame, base::Unretained(&frame_client_)));
- task_runner_->RunTasks();
- EXPECT_EQ(0, frame_client_.number_times_called());
-
- // Receive one frame and expect to see the first request satisfied.
- const base::TimeDelta target_playout_delay =
- base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis);
- frame_client_.AddExpectedResult(
- GetFirstTestFrameId(), first_frame_capture_time + target_playout_delay);
- rtp_header_.rtp_timestamp = RtpTimeTicks();
- FeedOneFrameIntoReceiver(); // Frame 1
- task_runner_->RunTasks();
- EXPECT_EQ(1, frame_client_.number_times_called());
-
- // Enqueue a second request for a frame, but it should not be fulfilled yet.
- receiver_->RequestEncodedFrame(base::BindOnce(
- &FakeFrameClient::DeliverEncodedFrame, base::Unretained(&frame_client_)));
- task_runner_->RunTasks();
- EXPECT_EQ(1, frame_client_.number_times_called());
-
- // Receive one frame out-of-order: Make sure that we are not continuous and
- // that the RTP timestamp represents a time in the future.
- rtp_header_.is_key_frame = false;
- rtp_header_.frame_id = GetFirstTestFrameId() + 2; // "Frame 3"
- rtp_header_.reference_frame_id = GetFirstTestFrameId() + 1; // "Frame 2"
- rtp_header_.rtp_timestamp += rtp_advance_per_frame * 2;
- FeedOneFrameIntoReceiver(); // Frame 3
-
- // Frame 2 should not come out at this point in time.
- task_runner_->RunTasks();
- EXPECT_EQ(1, frame_client_.number_times_called());
-
- // Enqueue a third request for a frame.
- receiver_->RequestEncodedFrame(base::BindOnce(
- &FakeFrameClient::DeliverEncodedFrame, base::Unretained(&frame_client_)));
- task_runner_->RunTasks();
- EXPECT_EQ(1, frame_client_.number_times_called());
-
- // Now, advance time forward such that Frame 2 is now too late for playback.
- // Regardless, the receiver must NOT emit Frame 3 yet because it is not
- // allowed to skip frames when dependencies are not satisfied. In other
- // words, Frame 3 is not decodable without Frame 2.
- testing_clock_.Advance(2 * time_advance_per_frame + target_playout_delay);
- task_runner_->RunTasks();
- EXPECT_EQ(1, frame_client_.number_times_called());
-
- // Now receive Frame 2 and expect both the second and third requests to be
- // fulfilled immediately.
- frame_client_.AddExpectedResult(GetFirstTestFrameId() + 1, // "Frame 2"
- first_frame_capture_time +
- 1 * time_advance_per_frame +
- target_playout_delay);
- frame_client_.AddExpectedResult(GetFirstTestFrameId() + 2, // "Frame 3"
- first_frame_capture_time +
- 2 * time_advance_per_frame +
- target_playout_delay);
- --rtp_header_.frame_id; // "Frame 2"
- --rtp_header_.reference_frame_id; // "Frame 1"
- rtp_header_.rtp_timestamp -= rtp_advance_per_frame;
- FeedOneFrameIntoReceiver(); // Frame 2
- task_runner_->RunTasks();
- EXPECT_EQ(3, frame_client_.number_times_called());
-
- // Move forward to the playout time of an unreceived Frame 5. Expect no
- // additional frames were emitted.
- testing_clock_.Advance(3 * time_advance_per_frame);
- task_runner_->RunTasks();
- EXPECT_EQ(3, frame_client_.number_times_called());
-
- // Sanity-check logging results.
- std::vector<FrameEvent> frame_events;
- event_subscriber.GetFrameEventsAndReset(&frame_events);
- ASSERT_TRUE(!frame_events.empty());
- for (size_t i = 0; i < frame_events.size(); ++i) {
- EXPECT_EQ(FRAME_ACK_SENT, frame_events[i].type);
- EXPECT_EQ(VIDEO_EVENT, frame_events[i].media_type);
- EXPECT_LE(GetFirstTestFrameId(), frame_events[i].frame_id);
- EXPECT_GE(GetFirstTestFrameId() + 3, frame_events[i].frame_id);
- const int frame_offset = frame_events[i].frame_id - GetFirstTestFrameId();
- EXPECT_EQ(RtpTimeTicks() + (rtp_advance_per_frame * frame_offset),
- frame_events[i].rtp_timestamp);
- }
- cast_environment_->logger()->Unsubscribe(&event_subscriber);
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/receiver/video_decoder.cc b/chromium/media/cast/receiver/video_decoder.cc
deleted file mode 100644
index ecf20f40a04..00000000000
--- a/chromium/media/cast/receiver/video_decoder.cc
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2014 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 "media/cast/receiver/video_decoder.h"
-
-#include <stdint.h>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/json/json_reader.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/values.h"
-#include "media/base/video_frame_pool.h"
-#include "media/base/video_util.h"
-#include "media/cast/cast_environment.h"
-#include "third_party/libvpx/source/libvpx/vpx/vp8dx.h"
-#include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h"
-#include "third_party/libyuv/include/libyuv/convert.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace media {
-namespace cast {
-
-// Base class that handles the common problem of detecting dropped frames, and
-// then invoking the Decode() method implemented by the subclasses to convert
-// the encoded payload data into a usable video frame.
-class VideoDecoder::ImplBase
- : public base::RefCountedThreadSafe<VideoDecoder::ImplBase> {
- public:
- ImplBase(const scoped_refptr<CastEnvironment>& cast_environment, Codec codec)
- : cast_environment_(cast_environment),
- codec_(codec),
- operational_status_(STATUS_UNINITIALIZED) {}
-
- OperationalStatus InitializationResult() const {
- return operational_status_;
- }
-
- void DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,
- const DecodeFrameCallback& callback) {
- DCHECK_EQ(operational_status_, STATUS_INITIALIZED);
-
- bool is_continuous = true;
- DCHECK(!encoded_frame->frame_id.is_null());
- if (!last_frame_id_.is_null()) {
- if (encoded_frame->frame_id > (last_frame_id_ + 1)) {
- RecoverBecauseFramesWereDropped();
- is_continuous = false;
- }
- }
- last_frame_id_ = encoded_frame->frame_id;
-
- const scoped_refptr<VideoFrame> decoded_frame = Decode(
- encoded_frame->mutable_bytes(),
- static_cast<int>(encoded_frame->data.size()));
- if (!decoded_frame) {
- VLOG(2) << "Decoding of frame " << encoded_frame->frame_id << " failed.";
- cast_environment_->PostTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(callback, decoded_frame, false));
- return;
- }
- decoded_frame->set_timestamp(
- encoded_frame->rtp_timestamp.ToTimeDelta(kVideoFrequency));
-
- std::unique_ptr<FrameEvent> decode_event(new FrameEvent());
- decode_event->timestamp = cast_environment_->Clock()->NowTicks();
- decode_event->type = FRAME_DECODED;
- decode_event->media_type = VIDEO_EVENT;
- decode_event->rtp_timestamp = encoded_frame->rtp_timestamp;
- decode_event->frame_id = encoded_frame->frame_id;
- cast_environment_->logger()->DispatchFrameEvent(std::move(decode_event));
-
- cast_environment_->PostTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(callback, decoded_frame, is_continuous));
- }
-
- protected:
- friend class base::RefCountedThreadSafe<ImplBase>;
- virtual ~ImplBase() = default;
-
- virtual void RecoverBecauseFramesWereDropped() {}
-
- // Note: Implementation of Decode() is allowed to mutate |data|.
- virtual scoped_refptr<VideoFrame> Decode(uint8_t* data, int len) = 0;
-
- const scoped_refptr<CastEnvironment> cast_environment_;
- const Codec codec_;
-
- // Subclass' ctor is expected to set this to STATUS_INITIALIZED.
- OperationalStatus operational_status_;
-
- // Pool of VideoFrames to decode incoming frames into.
- media::VideoFramePool video_frame_pool_;
-
- private:
- FrameId last_frame_id_;
-
- DISALLOW_COPY_AND_ASSIGN(ImplBase);
-};
-
-class VideoDecoder::Vp8Impl final : public VideoDecoder::ImplBase {
- public:
- explicit Vp8Impl(const scoped_refptr<CastEnvironment>& cast_environment)
- : ImplBase(cast_environment, CODEC_VIDEO_VP8) {
- if (ImplBase::operational_status_ != STATUS_UNINITIALIZED)
- return;
-
- vpx_codec_dec_cfg_t cfg = {0};
- // TODO(miu): Revisit this for typical multi-core desktop use case. This
- // feels like it should be 4 or 8.
- cfg.threads = 1;
-
- DCHECK(vpx_codec_get_caps(vpx_codec_vp8_dx()) & VPX_CODEC_CAP_POSTPROC);
- if (vpx_codec_dec_init(&context_,
- vpx_codec_vp8_dx(),
- &cfg,
- VPX_CODEC_USE_POSTPROC) != VPX_CODEC_OK) {
- ImplBase::operational_status_ = STATUS_INVALID_CONFIGURATION;
- return;
- }
- ImplBase::operational_status_ = STATUS_INITIALIZED;
- }
-
- private:
- ~Vp8Impl() final {
- if (ImplBase::operational_status_ == STATUS_INITIALIZED)
- CHECK_EQ(VPX_CODEC_OK, vpx_codec_destroy(&context_));
- }
-
- scoped_refptr<VideoFrame> Decode(uint8_t* data, int len) final {
- if (len <= 0 ||
- vpx_codec_decode(&context_, data, static_cast<unsigned int>(len),
- nullptr, 0) != VPX_CODEC_OK) {
- return nullptr;
- }
-
- vpx_codec_iter_t iter = nullptr;
- vpx_image_t* const image = vpx_codec_get_frame(&context_, &iter);
- if (!image)
- return nullptr;
- if (image->fmt != VPX_IMG_FMT_I420) {
- NOTREACHED() << "Only pixel format supported is I420, got " << image->fmt;
- return nullptr;
- }
- DCHECK(vpx_codec_get_frame(&context_, &iter) == nullptr)
- << "Should have only decoded exactly one frame.";
-
- const gfx::Size frame_size(image->d_w, image->d_h);
- // Note: Timestamp for the VideoFrame will be set in VideoReceiver.
- // |decoded_frame| will be returned to |video_frame_pool_| on destruction to
- // be reused.
- const scoped_refptr<VideoFrame> decoded_frame =
- video_frame_pool_.CreateFrame(PIXEL_FORMAT_I420, frame_size,
- gfx::Rect(frame_size), frame_size,
- base::TimeDelta());
- libyuv::I420Copy(image->planes[VPX_PLANE_Y], image->stride[VPX_PLANE_Y],
- image->planes[VPX_PLANE_U], image->stride[VPX_PLANE_U],
- image->planes[VPX_PLANE_V], image->stride[VPX_PLANE_V],
- decoded_frame->visible_data(media::VideoFrame::kYPlane),
- decoded_frame->stride(media::VideoFrame::kYPlane),
- decoded_frame->visible_data(media::VideoFrame::kUPlane),
- decoded_frame->stride(media::VideoFrame::kUPlane),
- decoded_frame->visible_data(media::VideoFrame::kVPlane),
- decoded_frame->stride(media::VideoFrame::kVPlane),
- frame_size.width(), frame_size.height());
- return decoded_frame;
- }
-
- // VPX decoder context (i.e., an instantiation).
- vpx_codec_ctx_t context_;
-
- DISALLOW_COPY_AND_ASSIGN(Vp8Impl);
-};
-
-#ifndef OFFICIAL_BUILD
-// A fake video decoder that always output 2x2 black frames.
-class VideoDecoder::FakeImpl final : public VideoDecoder::ImplBase {
- public:
- explicit FakeImpl(const scoped_refptr<CastEnvironment>& cast_environment)
- : ImplBase(cast_environment, CODEC_VIDEO_FAKE),
- last_decoded_id_(-1) {
- if (ImplBase::operational_status_ != STATUS_UNINITIALIZED)
- return;
- ImplBase::operational_status_ = STATUS_INITIALIZED;
- }
-
- private:
- ~FakeImpl() final = default;
-
- scoped_refptr<VideoFrame> Decode(uint8_t* data, int len) final {
- // Make sure this is a JSON string.
- if (!len || data[0] != '{')
- return nullptr;
- std::unique_ptr<base::Value> values(base::JSONReader::ReadDeprecated(
- base::StringPiece(reinterpret_cast<char*>(data), len)));
- if (!values)
- return nullptr;
- base::DictionaryValue* dict = nullptr;
- values->GetAsDictionary(&dict);
-
- bool key = false;
- int id = 0;
- int ref = 0;
- dict->GetBoolean("key", &key);
- dict->GetInteger("id", &id);
- dict->GetInteger("ref", &ref);
- DCHECK(id == last_decoded_id_ + 1);
- last_decoded_id_ = id;
- return media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2));
- }
-
- int last_decoded_id_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeImpl);
-};
-#endif
-
-VideoDecoder::VideoDecoder(
- const scoped_refptr<CastEnvironment>& cast_environment,
- Codec codec)
- : cast_environment_(cast_environment) {
- switch (codec) {
-#ifndef OFFICIAL_BUILD
- case CODEC_VIDEO_FAKE:
- impl_ = new FakeImpl(cast_environment);
- break;
-#endif
- case CODEC_VIDEO_VP8:
- impl_ = new Vp8Impl(cast_environment);
- break;
- case CODEC_VIDEO_H264:
- // TODO(miu): Need implementation.
- NOTIMPLEMENTED();
- break;
- default:
- NOTREACHED() << "Unknown or unspecified codec.";
- break;
- }
-}
-
-VideoDecoder::~VideoDecoder() = default;
-
-OperationalStatus VideoDecoder::InitializationResult() const {
- if (impl_.get())
- return impl_->InitializationResult();
- return STATUS_UNSUPPORTED_CODEC;
-}
-
-void VideoDecoder::DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,
- const DecodeFrameCallback& callback) {
- DCHECK(encoded_frame.get());
- DCHECK(!callback.is_null());
- if (!impl_.get() || impl_->InitializationResult() != STATUS_INITIALIZED) {
- callback.Run(base::WrapRefCounted<VideoFrame>(nullptr), false);
- return;
- }
- cast_environment_->PostTask(
- CastEnvironment::VIDEO, FROM_HERE,
- base::BindOnce(&VideoDecoder::ImplBase::DecodeFrame, impl_,
- std::move(encoded_frame), callback));
-}
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/receiver/video_decoder.h b/chromium/media/cast/receiver/video_decoder.h
deleted file mode 100644
index 2116217cd53..00000000000
--- a/chromium/media/cast/receiver/video_decoder.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2014 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 MEDIA_CAST_RECEIVER_VIDEO_DECODER_H_
-#define MEDIA_CAST_RECEIVER_VIDEO_DECODER_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "media/base/video_frame.h"
-#include "media/cast/constants.h"
-#include "media/cast/net/cast_transport_config.h"
-
-namespace media {
-namespace cast {
-
-class CastEnvironment;
-
-class VideoDecoder {
- public:
- // Callback passed to DecodeFrame, to deliver a decoded video frame from the
- // decoder. |frame| can be NULL when errors occur. |is_continuous| is
- // normally true, but will be false if the decoder has detected a frame skip
- // since the last decode operation; and the client might choose to take steps
- // to smooth/interpolate video discontinuities in this case.
- typedef base::RepeatingCallback<void(scoped_refptr<VideoFrame> frame,
- bool is_continuous)>
- DecodeFrameCallback;
-
- VideoDecoder(const scoped_refptr<CastEnvironment>& cast_environment,
- Codec codec);
- virtual ~VideoDecoder();
-
- // Returns STATUS_INITIALIZED if the decoder was successfully constructed. If
- // this method returns any other value, calls to DecodeFrame() will not
- // succeed.
- OperationalStatus InitializationResult() const;
-
- // Decode the payload in |encoded_frame| asynchronously. |callback| will be
- // invoked on the CastEnvironment::MAIN thread with the result.
- //
- // In the normal case, |encoded_frame->frame_id| will be
- // monotonically-increasing by 1 for each successive call to this method.
- // When it is not, the decoder will assume one or more frames have been
- // dropped (e.g., due to packet loss), and will perform recovery actions.
- void DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,
- const DecodeFrameCallback& callback);
-
- private:
- class FakeImpl;
- class ImplBase;
- class Vp8Impl;
-
- const scoped_refptr<CastEnvironment> cast_environment_;
- scoped_refptr<ImplBase> impl_;
-
- DISALLOW_COPY_AND_ASSIGN(VideoDecoder);
-};
-
-} // namespace cast
-} // namespace media
-
-#endif // MEDIA_CAST_RECEIVER_VIDEO_DECODER_H_
diff --git a/chromium/media/cast/receiver/video_decoder_unittest.cc b/chromium/media/cast/receiver/video_decoder_unittest.cc
deleted file mode 100644
index 496195648d3..00000000000
--- a/chromium/media/cast/receiver/video_decoder_unittest.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2014 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 <stdint.h>
-
-#include <cstdlib>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/macros.h"
-#include "base/synchronization/condition_variable.h"
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
-#include "media/cast/cast_config.h"
-#include "media/cast/receiver/video_decoder.h"
-#include "media/cast/sender/sender_encoded_frame.h"
-#include "media/cast/sender/vp8_encoder.h"
-#include "media/cast/test/utility/default_config.h"
-#include "media/cast/test/utility/standalone_cast_environment.h"
-#include "media/cast/test/utility/video_utility.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace media {
-namespace cast {
-
-namespace {
-
-const int kStartingWidth = 360;
-const int kStartingHeight = 240;
-const int kFrameRate = 10;
-
-FrameSenderConfig GetVideoSenderConfigForTest() {
- FrameSenderConfig config = GetDefaultVideoSenderConfig();
- config.max_frame_rate = kFrameRate;
- return config;
-}
-
-} // namespace
-
-class VideoDecoderTest : public ::testing::TestWithParam<Codec> {
- public:
- VideoDecoderTest()
- : cast_environment_(new StandaloneCastEnvironment()),
- vp8_encoder_(GetVideoSenderConfigForTest()),
- cond_(&lock_) {
- vp8_encoder_.Initialize();
- }
-
- virtual ~VideoDecoderTest() {
- // Make sure all threads have stopped before the environment goes away.
- cast_environment_->Shutdown();
- }
-
- protected:
- void SetUp() final {
- video_decoder_ =
- std::make_unique<VideoDecoder>(cast_environment_, GetParam());
- CHECK_EQ(STATUS_INITIALIZED, video_decoder_->InitializationResult());
-
- next_frame_size_ = gfx::Size(kStartingWidth, kStartingHeight);
- next_frame_timestamp_ = base::TimeDelta();
- last_frame_id_ = FrameId::first();
- seen_a_decoded_frame_ = false;
-
- total_video_frames_feed_in_ = 0;
- total_video_frames_decoded_ = 0;
- }
-
- void SetNextFrameSize(const gfx::Size& size) {
- next_frame_size_ = size;
- }
-
- // Called from the unit test thread to create another EncodedFrame and push it
- // into the decoding pipeline.
- void FeedMoreVideo(int num_dropped_frames) {
- DCHECK(!cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-
- // Prepare a simulated VideoFrame to feed into the VideoEncoder.
- const scoped_refptr<VideoFrame> video_frame = VideoFrame::CreateFrame(
- PIXEL_FORMAT_I420, next_frame_size_, gfx::Rect(next_frame_size_),
- next_frame_size_, next_frame_timestamp_);
- const base::TimeTicks reference_time =
- base::TimeTicks::UnixEpoch() + next_frame_timestamp_;
- next_frame_timestamp_ += base::TimeDelta::FromSeconds(1) / kFrameRate;
- PopulateVideoFrame(video_frame.get(), 0);
-
- // Encode |frame| into |encoded_frame->data|.
- std::unique_ptr<SenderEncodedFrame> encoded_frame(new SenderEncodedFrame());
- // Test only supports VP8, currently.
- CHECK_EQ(CODEC_VIDEO_VP8, GetParam());
- vp8_encoder_.Encode(video_frame, reference_time, encoded_frame.get());
- // Rewrite frame IDs for testing purposes.
- encoded_frame->frame_id = last_frame_id_ + 1 + num_dropped_frames;
- if (encoded_frame->dependency == EncodedFrame::KEY)
- encoded_frame->referenced_frame_id = encoded_frame->frame_id;
- else
- encoded_frame->referenced_frame_id = encoded_frame->frame_id - 1;
- last_frame_id_ = encoded_frame->frame_id;
- ASSERT_EQ(reference_time, encoded_frame->reference_time);
-
- ++total_video_frames_feed_in_;
-
- // Post a task to decode the encoded frame.
- cast_environment_->PostTask(
- CastEnvironment::MAIN, FROM_HERE,
- base::BindOnce(&VideoDecoder::DecodeFrame,
- base::Unretained(video_decoder_.get()),
- std::move(encoded_frame),
- base::BindRepeating(&VideoDecoderTest::OnDecodedFrame,
- base::Unretained(this), video_frame,
- num_dropped_frames == 0)));
- }
-
- // Blocks the caller until all video that has been feed in has been decoded.
- void WaitForAllVideoToBeDecoded() {
- DCHECK(!cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- base::AutoLock auto_lock(lock_);
- while (total_video_frames_decoded_ < total_video_frames_feed_in_)
- cond_.Wait();
- EXPECT_EQ(total_video_frames_feed_in_, total_video_frames_decoded_);
- }
-
- private:
- // Called by |vp8_decoder_| to deliver each frame of decoded video.
- void OnDecodedFrame(scoped_refptr<VideoFrame> expected_video_frame,
- bool should_be_continuous,
- scoped_refptr<VideoFrame> video_frame,
- bool is_continuous) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-
- // A NULL |video_frame| indicates a decode error, which we don't expect.
- ASSERT_TRUE(video_frame);
-
- // Did the decoder detect whether frames were dropped?
- EXPECT_EQ(should_be_continuous, is_continuous);
-
- // Does the video data seem to be intact?
- EXPECT_EQ(expected_video_frame->coded_size().width(),
- video_frame->coded_size().width());
- EXPECT_EQ(expected_video_frame->coded_size().height(),
- video_frame->coded_size().height());
- EXPECT_LT(40.0, I420PSNR(*expected_video_frame, *video_frame));
- // TODO(miu): Once we start using VideoFrame::timestamp_, check that here.
-
- // Signal the main test thread that more video was decoded.
- base::AutoLock auto_lock(lock_);
- ++total_video_frames_decoded_;
- cond_.Signal();
- }
-
- const scoped_refptr<StandaloneCastEnvironment> cast_environment_;
- std::unique_ptr<VideoDecoder> video_decoder_;
- gfx::Size next_frame_size_;
- base::TimeDelta next_frame_timestamp_;
- FrameId last_frame_id_;
- bool seen_a_decoded_frame_;
-
- Vp8Encoder vp8_encoder_;
-
- // Unlike |total_video_frames_decoded_|, this is only read/written on a single
- // thread.
- int total_video_frames_feed_in_;
-
- base::Lock lock_;
- base::ConditionVariable cond_;
- int total_video_frames_decoded_; // Protected by |lock_|.
-
- DISALLOW_COPY_AND_ASSIGN(VideoDecoderTest);
-};
-
-TEST_P(VideoDecoderTest, DecodesFrames) {
- const int kNumFrames = 3;
- for (int i = 0; i < kNumFrames; ++i)
- FeedMoreVideo(0);
- WaitForAllVideoToBeDecoded();
-}
-
-TEST_P(VideoDecoderTest, RecoversFromDroppedFrames) {
- // Feed 20 frames and expect 20 to be decoded. At random points, drop one or
- // more frames.
- FeedMoreVideo(0);
- FeedMoreVideo(2); // Two frames dropped.
- FeedMoreVideo(0);
- FeedMoreVideo(0);
- FeedMoreVideo(1); // One frame dropped.
- FeedMoreVideo(0);
- FeedMoreVideo(0);
- FeedMoreVideo(0);
- FeedMoreVideo(1); // One frame dropped.
- FeedMoreVideo(0);
- FeedMoreVideo(0);
- FeedMoreVideo(0);
- FeedMoreVideo(0);
- FeedMoreVideo(3); // Three frames dropped.
- FeedMoreVideo(0);
- FeedMoreVideo(0);
- FeedMoreVideo(10); // Ten frames dropped.
- FeedMoreVideo(0);
- FeedMoreVideo(1); // One frame dropped.
- FeedMoreVideo(0);
- WaitForAllVideoToBeDecoded();
-}
-
-TEST_P(VideoDecoderTest, DecodesFramesOfVaryingSizes) {
- std::vector<gfx::Size> frame_sizes;
- frame_sizes.push_back(gfx::Size(128, 72));
- frame_sizes.push_back(gfx::Size(64, 36)); // Shrink both dimensions.
- frame_sizes.push_back(gfx::Size(30, 20)); // Shrink both dimensions again.
- frame_sizes.push_back(gfx::Size(20, 30)); // Same area.
- frame_sizes.push_back(gfx::Size(60, 40)); // Grow both dimensions.
- frame_sizes.push_back(gfx::Size(58, 40)); // Shrink only one dimension.
- frame_sizes.push_back(gfx::Size(58, 38)); // Shrink the other dimension.
- frame_sizes.push_back(gfx::Size(32, 18)); // Shrink both dimensions again.
- frame_sizes.push_back(gfx::Size(34, 18)); // Grow only one dimension.
- frame_sizes.push_back(gfx::Size(34, 20)); // Grow the other dimension.
- frame_sizes.push_back(gfx::Size(192, 108)); // Grow both dimensions again.
-
- // Encode one frame at each size.
- for (const auto& frame_size : frame_sizes) {
- SetNextFrameSize(frame_size);
- FeedMoreVideo(0);
- }
-
- // Encode 3 frames at each size.
- for (const auto& frame_size : frame_sizes) {
- SetNextFrameSize(frame_size);
- const int kNumFrames = 3;
- for (int i = 0; i < kNumFrames; ++i)
- FeedMoreVideo(0);
- }
-
- WaitForAllVideoToBeDecoded();
-}
-
-INSTANTIATE_TEST_SUITE_P(All,
- VideoDecoderTest,
- ::testing::Values(CODEC_VIDEO_VP8));
-
-} // namespace cast
-} // namespace media
diff --git a/chromium/media/cast/sender/external_video_encoder.cc b/chromium/media/cast/sender/external_video_encoder.cc
index f9688c6ea85..3f5cc4631c9 100644
--- a/chromium/media/cast/sender/external_video_encoder.cc
+++ b/chromium/media/cast/sender/external_video_encoder.cc
@@ -4,7 +4,9 @@
#include "media/cast/sender/external_video_encoder.h"
+#include <array>
#include <cmath>
+#include <sstream>
#include <utility>
#include "base/bind.h"
@@ -31,7 +33,13 @@
namespace {
-enum { MAX_H264_QUANTIZER = 51 };
+// The percentage of each frame to sample. This value is based on an
+// analysis that showed sampling 10% of the rows of a frame generated
+// reasonably accurate results.
+constexpr int kFrameSamplingPercentage = 10;
+
+// QP for H.264 encoders ranges from [0, 51] (inclusive).
+constexpr int kMaxH264Quantizer = 51;
// Number of buffers for encoded bit stream.
constexpr size_t kOutputBufferCount = 3;
@@ -44,6 +52,10 @@ constexpr size_t kExtraInputBufferCount = 2;
// assumed to be in full usage when the number of frames in progress reaches it.
constexpr int kBacklogRedlineThreshold = 4;
+// The number of histogram buckets for quantization estimation. These
+// histograms must encompass the range [-255, 255] (inclusive).
+constexpr int kQuantizationHistogramSize = 511;
+
} // namespace
namespace media {
@@ -93,13 +105,11 @@ class ExternalVideoEncoder::VEAClientImpl final
const scoped_refptr<base::SingleThreadTaskRunner>& encoder_task_runner,
std::unique_ptr<media::VideoEncodeAccelerator> vea,
double max_frame_rate,
- StatusChangeCallback status_change_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb)
+ StatusChangeCallback status_change_cb)
: cast_environment_(cast_environment),
task_runner_(encoder_task_runner),
max_frame_rate_(max_frame_rate),
status_change_cb_(std::move(status_change_cb)),
- create_video_encode_memory_cb_(create_video_encode_memory_cb),
video_encode_accelerator_(std::move(vea)),
encoder_active_(false),
next_frame_id_(FrameId::first()),
@@ -107,7 +117,6 @@ class ExternalVideoEncoder::VEAClientImpl final
codec_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN),
key_frame_quantizer_parsable_(false),
requested_bit_rate_(-1),
- max_allowed_input_buffers_(0),
allocate_input_buffer_in_progress_(false) {}
base::SingleThreadTaskRunner* task_runner() const {
@@ -179,10 +188,11 @@ class ExternalVideoEncoder::VEAClientImpl final
if (!allocate_input_buffer_in_progress_ &&
input_buffers_.size() < max_allowed_input_buffers_) {
allocate_input_buffer_in_progress_ = true;
- create_video_encode_memory_cb_.Run(
- media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420,
- frame_coded_size_),
- base::BindOnce(&VEAClientImpl::OnCreateInputSharedMemory, this));
+ const size_t buffer_size = media::VideoFrame::AllocationSize(
+ media::PIXEL_FORMAT_I420, frame_coded_size_);
+ task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&VEAClientImpl::AllocateInputBuffer, this,
+ buffer_size));
}
AbortLatestEncodeAttemptDueToErrors();
return;
@@ -241,25 +251,54 @@ class ExternalVideoEncoder::VEAClientImpl final
CastEnvironment::MAIN, FROM_HERE,
base::BindOnce(status_change_cb_, STATUS_CODEC_RUNTIME_ERROR));
- // TODO(miu): Force-flush all |in_progress_frame_encodes_| immediately so
- // pending frames do not become stuck, freezing VideoSender.
+ // TODO(crbug.com/1199930): Force-flush all |in_progress_frame_encodes_|
+ // immediately so pending frames do not become stuck, freezing VideoSender.
+ }
+
+ void AllocateInputBuffer(size_t size) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
+ auto memory = base::UnsafeSharedMemoryRegion::Create(size);
+ if (memory.IsValid()) {
+ base::WritableSharedMemoryMapping mapping = memory.Map();
+ DCHECK(mapping.IsValid());
+ input_buffers_.push_back(
+ std::make_unique<std::pair<base::UnsafeSharedMemoryRegion,
+ base::WritableSharedMemoryMapping>>(
+ std::move(memory), std::move(mapping)));
+ free_input_buffer_index_.push_back(input_buffers_.size() - 1);
+ }
+ allocate_input_buffer_in_progress_ = false;
+ }
+
+ void AllocateOutputBuffers(size_t size) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
+ for (size_t i = 0; i < kOutputBufferCount; ++i) {
+ auto memory = base::UnsafeSharedMemoryRegion::Create(size);
+ base::WritableSharedMemoryMapping mapping = memory.Map();
+ DCHECK(mapping.IsValid());
+ output_buffers_.push_back(
+ std::make_pair(std::move(memory), std::move(mapping)));
+
+ video_encode_accelerator_->UseOutputBitstreamBuffer(
+ media::BitstreamBuffer(static_cast<int32_t>(i),
+ output_buffers_[i].first.Duplicate(),
+ output_buffers_[i].first.GetSize()));
+ }
}
- // Called to allocate the input and output buffers.
+ // Called by the VEA to indicate its buffer requirements.
void RequireBitstreamBuffers(unsigned int input_count,
const gfx::Size& input_coded_size,
size_t output_buffer_size) final {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
frame_coded_size_ = input_coded_size;
-
max_allowed_input_buffers_ = input_count + kExtraInputBufferCount;
-
- for (size_t j = 0; j < kOutputBufferCount; ++j) {
- create_video_encode_memory_cb_.Run(
- output_buffer_size,
- base::BindOnce(&VEAClientImpl::OnCreateSharedMemory, this));
- }
+ task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&VEAClientImpl::AllocateOutputBuffers, this,
+ output_buffer_size));
}
// Encoder has encoded a frame and it's available in one of the output
@@ -294,10 +333,7 @@ class ExternalVideoEncoder::VEAClientImpl final
// Do not send video until we have encountered the first key frame.
// Save the bitstream buffer in |stream_header_| to be sent later along
// with the first key frame.
- //
- // TODO(miu): Should |stream_header_| be an std::ostringstream for
- // performance reasons?
- stream_header_.append(output_buffer_memory, metadata.payload_size_bytes);
+ stream_header_.write(output_buffer_memory, metadata.payload_size_bytes);
} else if (!in_progress_frame_encodes_.empty()) {
InProgressExternalVideoFrameEncode& request =
in_progress_frame_encodes_.front();
@@ -315,9 +351,11 @@ class ExternalVideoEncoder::VEAClientImpl final
encoded_frame->rtp_timestamp = RtpTimeTicks::FromTimeDelta(
request.video_frame->timestamp(), kVideoFrequency);
encoded_frame->reference_time = request.reference_time;
- if (!stream_header_.empty()) {
- encoded_frame->data = stream_header_;
- stream_header_.clear();
+
+ std::string header = stream_header_.str();
+ if (!header.empty()) {
+ encoded_frame->data = std::move(header);
+ std::ostringstream().swap(stream_header_);
}
encoded_frame->data.append(output_buffer_memory,
metadata.payload_size_bytes);
@@ -389,7 +427,7 @@ class ExternalVideoEncoder::VEAClientImpl final
const double max_quantizer =
codec_profile_ == media::VP8PROFILE_ANY
? static_cast<int>(QuantizerEstimator::MAX_VP8_QUANTIZER)
- : static_cast<int>(MAX_H264_QUANTIZER);
+ : static_cast<int>(kMaxH264Quantizer);
encoded_frame->lossy_utilization =
bitrate_utilization * (quantizer / max_quantizer);
}
@@ -436,55 +474,6 @@ class ExternalVideoEncoder::VEAClientImpl final
}
}
- // Note: This method can be called on any thread.
- void OnCreateSharedMemory(base::UnsafeSharedMemoryRegion memory) {
- task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&VEAClientImpl::OnReceivedSharedMemory, this,
- std::move(memory)));
- }
-
- void OnCreateInputSharedMemory(base::UnsafeSharedMemoryRegion memory) {
- task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&VEAClientImpl::OnReceivedInputSharedMemory,
- this, std::move(memory)));
- }
-
- void OnReceivedSharedMemory(base::UnsafeSharedMemoryRegion memory) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
-
- base::WritableSharedMemoryMapping mapping = memory.Map();
- DCHECK(mapping.IsValid());
- output_buffers_.push_back(
- std::make_pair(std::move(memory), std::move(mapping)));
-
- // Wait until all requested buffers are received.
- if (output_buffers_.size() < kOutputBufferCount)
- return;
-
- // Immediately provide all output buffers to the VEA.
- for (size_t i = 0; i < output_buffers_.size(); ++i) {
- video_encode_accelerator_->UseOutputBitstreamBuffer(
- media::BitstreamBuffer(static_cast<int32_t>(i),
- output_buffers_[i].first.Duplicate(),
- output_buffers_[i].first.GetSize()));
- }
- }
-
- void OnReceivedInputSharedMemory(base::UnsafeSharedMemoryRegion region) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
-
- if (region.IsValid()) {
- base::WritableSharedMemoryMapping mapping = region.Map();
- DCHECK(mapping.IsValid());
- input_buffers_.push_back(
- std::make_unique<std::pair<base::UnsafeSharedMemoryRegion,
- base::WritableSharedMemoryMapping>>(
- std::move(region), std::move(mapping)));
- free_input_buffer_index_.push_back(input_buffers_.size() - 1);
- }
- allocate_input_buffer_in_progress_ = false;
- }
-
// This is called when an error occurs while preparing a VideoFrame for
// encode, or to abort a frame encode when shutting down.
void AbortLatestEncodeAttemptDueToErrors() {
@@ -540,7 +529,7 @@ class ExternalVideoEncoder::VEAClientImpl final
? pps->pic_init_qs_minus26 + slice_header.slice_qs_delta
: pps->pic_init_qp_minus26 + slice_header.slice_qp_delta);
DCHECK_GE(slice_quantizer, 0);
- DCHECK_LE(slice_quantizer, MAX_H264_QUANTIZER);
+ DCHECK_LE(slice_quantizer, kMaxH264Quantizer);
total_quantizer += slice_quantizer;
break;
}
@@ -570,12 +559,11 @@ class ExternalVideoEncoder::VEAClientImpl final
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
const double max_frame_rate_;
const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread.
- const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_;
std::unique_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_;
bool encoder_active_;
FrameId next_frame_id_;
bool key_frame_encountered_;
- std::string stream_header_;
+ std::ostringstream stream_header_;
VideoCodecProfile codec_profile_;
bool key_frame_quantizer_parsable_;
H264Parser h264_parser_;
@@ -628,10 +616,7 @@ bool ExternalVideoEncoder::IsSupported(const FrameSenderConfig& video_config) {
video_config.codec != CODEC_VIDEO_H264)
return false;
- // TODO(miu): "Layering hooks" are needed to be able to query outside of
- // libmedia, to determine whether the system provides a hardware encoder. For
- // now, assume that this was already checked by this point.
- // http://crbug.com/454029
+ // We assume that the system provides a hardware encoder at this point.
return video_config.use_external_encoder;
}
@@ -641,19 +626,15 @@ ExternalVideoEncoder::ExternalVideoEncoder(
const gfx::Size& frame_size,
FrameId first_frame_id,
StatusChangeCallback status_change_cb,
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb)
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb)
: cast_environment_(cast_environment),
- create_video_encode_memory_cb_(create_video_encode_memory_cb),
frame_size_(frame_size),
- bit_rate_(video_config.start_bitrate),
- key_frame_requested_(false) {
+ bit_rate_(video_config.start_bitrate) {
DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
DCHECK_GT(video_config.max_frame_rate, 0);
DCHECK(!frame_size_.IsEmpty());
DCHECK(status_change_cb);
DCHECK(create_vea_cb);
- DCHECK(create_video_encode_memory_cb_);
DCHECK_GT(bit_rate_, 0);
create_vea_cb.Run(
@@ -783,8 +764,7 @@ void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator(
DCHECK(!client_);
client_ = new VEAClientImpl(cast_environment_, encoder_task_runner,
std::move(vea), video_config.max_frame_rate,
- std::move(wrapped_status_change_cb),
- create_video_encode_memory_cb_);
+ std::move(wrapped_status_change_cb));
client_->task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&VEAClientImpl::Initialize, client_, frame_size_,
@@ -795,13 +775,11 @@ SizeAdaptableExternalVideoEncoder::SizeAdaptableExternalVideoEncoder(
const scoped_refptr<CastEnvironment>& cast_environment,
const FrameSenderConfig& video_config,
StatusChangeCallback status_change_cb,
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb)
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb)
: SizeAdaptableVideoEncoderBase(cast_environment,
video_config,
std::move(status_change_cb)),
- create_vea_cb_(create_vea_cb),
- create_video_encode_memory_cb_(create_video_encode_memory_cb) {}
+ create_vea_cb_(create_vea_cb) {}
SizeAdaptableExternalVideoEncoder::~SizeAdaptableExternalVideoEncoder() =
default;
@@ -810,8 +788,7 @@ std::unique_ptr<VideoEncoder>
SizeAdaptableExternalVideoEncoder::CreateEncoder() {
return std::make_unique<ExternalVideoEncoder>(
cast_environment(), video_config(), frame_size(), next_frame_id(),
- CreateEncoderStatusChangeCallback(), create_vea_cb_,
- create_video_encode_memory_cb_);
+ CreateEncoderStatusChangeCallback(), create_vea_cb_);
}
QuantizerEstimator::QuantizerEstimator() = default;
@@ -832,17 +809,15 @@ double QuantizerEstimator::EstimateForKeyFrame(const VideoFrame& frame) {
// frame, since the entropy analysis only examines a subset of each frame.
const gfx::Size size = frame.visible_rect().size();
const int rows_in_subset =
- std::max(1, size.height() * FRAME_SAMPLING_PERCENT / 100);
+ std::max(1, size.height() * kFrameSamplingPercentage / 100);
if (last_frame_size_ != size || !last_frame_pixel_buffer_) {
last_frame_pixel_buffer_.reset(new uint8_t[size.width() * rows_in_subset]);
last_frame_size_ = size;
}
// Compute a histogram where each bucket represents the number of times two
- // neighboring pixels were different by a specific amount. 511 buckets are
- // needed, one for each integer in the range [-255,255].
- int histogram[511];
- memset(histogram, 0, sizeof(histogram));
+ // neighboring pixels were different by a specific amount.
+ std::array<int, kQuantizationHistogramSize> histogram{};
const int row_skip = size.height() / rows_in_subset;
int y = 0;
for (int i = 0; i < rows_in_subset; ++i, y += row_skip) {
@@ -869,7 +844,7 @@ double QuantizerEstimator::EstimateForKeyFrame(const VideoFrame& frame) {
// histogram and return it.
const int num_samples = (size.width() - 1) * rows_in_subset;
return ToQuantizerEstimate(ComputeEntropyFromHistogram(
- histogram, base::size(histogram), num_samples));
+ histogram.data(), histogram.size(), num_samples));
}
double QuantizerEstimator::EstimateForDeltaFrame(const VideoFrame& frame) {
@@ -879,19 +854,17 @@ double QuantizerEstimator::EstimateForDeltaFrame(const VideoFrame& frame) {
// If the size of the |frame| has changed, no difference can be examined.
// In this case, process this frame as if it were a key frame.
- const gfx::Size size = frame.visible_rect().size();
+ const gfx::Size& size = frame.visible_rect().size();
if (last_frame_size_ != size || !last_frame_pixel_buffer_) {
return EstimateForKeyFrame(frame);
}
const int rows_in_subset =
- std::max(1, size.height() * FRAME_SAMPLING_PERCENT / 100);
+ std::max(1, size.height() * (kFrameSamplingPercentage / 100));
// Compute a histogram where each bucket represents the number of times the
// same pixel in this frame versus the last frame was different by a specific
- // amount. 511 buckets are needed, one for each integer in the range
- // [-255,255].
- int histogram[511];
- memset(histogram, 0, sizeof(histogram));
+ // amount.
+ std::array<int, kQuantizationHistogramSize> histogram{};
const int row_skip = size.height() / rows_in_subset;
int y = 0;
for (int i = 0; i < rows_in_subset; ++i, y += row_skip) {
@@ -916,7 +889,7 @@ double QuantizerEstimator::EstimateForDeltaFrame(const VideoFrame& frame) {
// histogram and return it.
const int num_samples = size.width() * rows_in_subset;
return ToQuantizerEstimate(ComputeEntropyFromHistogram(
- histogram, base::size(histogram), num_samples));
+ histogram.data(), histogram.size(), num_samples));
}
// static
@@ -929,22 +902,14 @@ bool QuantizerEstimator::CanExamineFrame(const VideoFrame& frame) {
// static
double QuantizerEstimator::ComputeEntropyFromHistogram(const int* histogram,
- size_t num_buckets,
+ size_t histogram_size,
int num_samples) {
-#if defined(OS_ANDROID)
- // Android does not currently provide a log2() function in their C++ standard
- // library. This is a substitute.
- const auto log2 = [](double num) -> double {
- return log(num) / 0.69314718055994528622676398299518041312694549560546875;
- };
-#endif
-
DCHECK_LT(0, num_samples);
double entropy = 0.0;
- for (size_t i = 0; i < num_buckets; ++i) {
+ for (size_t i = 0; i < histogram_size; ++i) {
const double probability = static_cast<double>(histogram[i]) / num_samples;
if (probability > 0.0) {
- entropy = entropy - probability * log2(probability);
+ entropy = entropy - probability * std::log2(probability);
}
}
return entropy;
@@ -961,14 +926,11 @@ double QuantizerEstimator::ToQuantizerEstimate(double shannon_entropy) {
// running alongside. Based on an analysis of the data, the following linear
// mapping seems to produce reasonable VP8 quantizer values from the
// |shannon_entropy| values.
- //
- // TODO(miu): Confirm whether this model and value work well on other
- // platforms.
- const double kEntropyAtMaxQuantizer = 7.5;
- const double slope =
+ constexpr double kEntropyAtMaxQuantizer = 7.5;
+ constexpr double kSlope =
(MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer;
const double quantizer = std::min<double>(
- MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy);
+ MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + kSlope * shannon_entropy);
return quantizer;
}
diff --git a/chromium/media/cast/sender/external_video_encoder.h b/chromium/media/cast/sender/external_video_encoder.h
index fbbfdb3c7d5..be6878aec8d 100644
--- a/chromium/media/cast/sender/external_video_encoder.h
+++ b/chromium/media/cast/sender/external_video_encoder.h
@@ -36,8 +36,7 @@ class ExternalVideoEncoder final : public VideoEncoder {
const gfx::Size& frame_size,
FrameId first_frame_id,
StatusChangeCallback status_change_cb,
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb);
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb);
~ExternalVideoEncoder() final;
@@ -66,13 +65,12 @@ class ExternalVideoEncoder final : public VideoEncoder {
std::unique_ptr<media::VideoEncodeAccelerator> vea);
const scoped_refptr<CastEnvironment> cast_environment_;
- const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_;
// The size of the visible region of the video frames to be encoded.
const gfx::Size frame_size_;
int bit_rate_;
- bool key_frame_requested_;
+ bool key_frame_requested_ = false;
scoped_refptr<VEAClientImpl> client_;
@@ -92,8 +90,7 @@ class SizeAdaptableExternalVideoEncoder final
const scoped_refptr<CastEnvironment>& cast_environment,
const FrameSenderConfig& video_config,
StatusChangeCallback status_change_cb,
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb);
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb);
~SizeAdaptableExternalVideoEncoder() final;
@@ -102,9 +99,7 @@ class SizeAdaptableExternalVideoEncoder final
private:
// Special callbacks needed by media::cast::ExternalVideoEncoder.
- // TODO(miu): Remove these. http://crbug.com/454029
const CreateVideoEncodeAcceleratorCallback create_vea_cb_;
- const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_;
DISALLOW_COPY_AND_ASSIGN(SizeAdaptableExternalVideoEncoder);
};
@@ -135,13 +130,6 @@ class QuantizerEstimator {
double EstimateForDeltaFrame(const VideoFrame& frame);
private:
- enum {
- // The percentage of each frame to sample. This value is based on an
- // analysis that showed sampling 10% of the rows of a frame generated
- // reasonably accurate results.
- FRAME_SAMPLING_PERCENT = 10,
- };
-
// Returns true if the frame is in planar YUV format.
static bool CanExamineFrame(const VideoFrame& frame);
@@ -149,7 +137,7 @@ class QuantizerEstimator {
// based on the probabilities of values falling within each of the buckets of
// the given |histogram|.
static double ComputeEntropyFromHistogram(const int* histogram,
- size_t num_buckets,
+ size_t histogram_size,
int num_samples);
// Map the |shannon_entropy| to its corresponding software VP8 quantizer.
diff --git a/chromium/media/cast/sender/fake_video_encode_accelerator_factory.cc b/chromium/media/cast/sender/fake_video_encode_accelerator_factory.cc
index b9c7ea280be..51d61d9d288 100644
--- a/chromium/media/cast/sender/fake_video_encode_accelerator_factory.cc
+++ b/chromium/media/cast/sender/fake_video_encode_accelerator_factory.cc
@@ -13,11 +13,7 @@ namespace cast {
FakeVideoEncodeAcceleratorFactory::FakeVideoEncodeAcceleratorFactory(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
- : task_runner_(task_runner),
- will_init_succeed_(true),
- auto_respond_(false),
- vea_response_count_(0),
- shm_response_count_(0) {}
+ : task_runner_(task_runner) {}
FakeVideoEncodeAcceleratorFactory::~FakeVideoEncodeAcceleratorFactory() =
default;
@@ -32,8 +28,6 @@ void FakeVideoEncodeAcceleratorFactory::SetAutoRespond(bool auto_respond) {
if (auto_respond_) {
if (!vea_response_callback_.is_null())
RespondWithVideoEncodeAccelerator();
- if (!shm_response_callback_.is_null())
- RespondWithSharedMemory();
}
}
@@ -51,18 +45,6 @@ void FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator(
RespondWithVideoEncodeAccelerator();
}
-void FakeVideoEncodeAcceleratorFactory::CreateSharedMemory(
- size_t size,
- ReceiveVideoEncodeMemoryCallback callback) {
- DCHECK(!callback.is_null());
- DCHECK(!next_response_shm_.IsValid());
-
- next_response_shm_ = base::UnsafeSharedMemoryRegion::Create(size);
- shm_response_callback_ = std::move(callback);
- if (auto_respond_)
- RespondWithSharedMemory();
-}
-
void FakeVideoEncodeAcceleratorFactory::RespondWithVideoEncodeAccelerator() {
DCHECK(next_response_vea_.get());
++vea_response_count_;
@@ -70,11 +52,5 @@ void FakeVideoEncodeAcceleratorFactory::RespondWithVideoEncodeAccelerator() {
.Run(task_runner_, std::move(next_response_vea_));
}
-void FakeVideoEncodeAcceleratorFactory::RespondWithSharedMemory() {
- DCHECK(next_response_shm_.IsValid());
- ++shm_response_count_;
- std::move(shm_response_callback_).Run(std::move(next_response_shm_));
-}
-
} // namespace cast
} // namespace media
diff --git a/chromium/media/cast/sender/fake_video_encode_accelerator_factory.h b/chromium/media/cast/sender/fake_video_encode_accelerator_factory.h
index 81984145719..648ee27ed91 100644
--- a/chromium/media/cast/sender/fake_video_encode_accelerator_factory.h
+++ b/chromium/media/cast/sender/fake_video_encode_accelerator_factory.h
@@ -31,9 +31,6 @@ class FakeVideoEncodeAcceleratorFactory {
int vea_response_count() const {
return vea_response_count_;
}
- int shm_response_count() const {
- return shm_response_count_;
- }
// Set whether the next created media::FakeVideoEncodeAccelerator will
// initialize successfully.
@@ -47,30 +44,18 @@ class FakeVideoEncodeAcceleratorFactory {
void CreateVideoEncodeAccelerator(
ReceiveVideoEncodeAcceleratorCallback callback);
- // Creates shared memory of the requested |size|. If in auto-respond mode,
- // |callback| is run synchronously (i.e., before this method returns).
- void CreateSharedMemory(size_t size,
- ReceiveVideoEncodeMemoryCallback callback);
-
// Runs the |callback| provided to the last call to
// CreateVideoEncodeAccelerator() with the new VideoEncodeAccelerator
// instance.
void RespondWithVideoEncodeAccelerator();
- // Runs the |callback| provided to the last call to
- // CreateSharedMemory() with the new base::UnsafeSharedMemoryRegion instance.
- void RespondWithSharedMemory();
-
private:
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- bool will_init_succeed_;
- bool auto_respond_;
+ bool will_init_succeed_ = true;
+ bool auto_respond_ = false;
std::unique_ptr<media::VideoEncodeAccelerator> next_response_vea_;
ReceiveVideoEncodeAcceleratorCallback vea_response_callback_;
- base::UnsafeSharedMemoryRegion next_response_shm_;
- ReceiveVideoEncodeMemoryCallback shm_response_callback_;
- int vea_response_count_;
- int shm_response_count_;
+ int vea_response_count_ = 0;
DISALLOW_COPY_AND_ASSIGN(FakeVideoEncodeAcceleratorFactory);
};
diff --git a/chromium/media/cast/sender/h264_vt_encoder_unittest.cc b/chromium/media/cast/sender/h264_vt_encoder_unittest.cc
index c43b40b4538..5f38a9980ba 100644
--- a/chromium/media/cast/sender/h264_vt_encoder_unittest.cc
+++ b/chromium/media/cast/sender/h264_vt_encoder_unittest.cc
@@ -12,7 +12,7 @@
#include "base/power_monitor/power_monitor.h"
#include "base/run_loop.h"
#include "base/test/launcher/unit_test_launcher.h"
-#include "base/test/power_monitor_test_base.h"
+#include "base/test/power_monitor_test.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/task_environment.h"
#include "base/test/test_suite.h"
diff --git a/chromium/media/cast/sender/video_encoder.cc b/chromium/media/cast/sender/video_encoder.cc
index 6e338fbabcd..bcd26be784c 100644
--- a/chromium/media/cast/sender/video_encoder.cc
+++ b/chromium/media/cast/sender/video_encoder.cc
@@ -20,8 +20,7 @@ std::unique_ptr<VideoEncoder> VideoEncoder::Create(
const scoped_refptr<CastEnvironment>& cast_environment,
const FrameSenderConfig& video_config,
StatusChangeCallback status_change_cb,
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) {
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb) {
// On MacOS or IOS, attempt to use the system VideoToolbox library to
// perform optimized H.264 encoding.
#if defined(OS_MAC)
@@ -36,7 +35,7 @@ std::unique_ptr<VideoEncoder> VideoEncoder::Create(
if (ExternalVideoEncoder::IsSupported(video_config)) {
return std::unique_ptr<VideoEncoder>(new SizeAdaptableExternalVideoEncoder(
cast_environment, video_config, std::move(status_change_cb),
- create_vea_cb, create_video_encode_memory_cb));
+ create_vea_cb));
}
// Attempt to use the software encoder implementation.
diff --git a/chromium/media/cast/sender/video_encoder.h b/chromium/media/cast/sender/video_encoder.h
index b9ef180eee7..1bcb401f5e6 100644
--- a/chromium/media/cast/sender/video_encoder.h
+++ b/chromium/media/cast/sender/video_encoder.h
@@ -34,14 +34,11 @@ class VideoEncoder {
//
// All VideoEncoder instances returned by this function support encoding
// sequences of differently-size VideoFrames.
- //
- // TODO(miu): Remove the CreateVEA callbacks. http://crbug.com/454029
static std::unique_ptr<VideoEncoder> Create(
const scoped_refptr<CastEnvironment>& cast_environment,
const FrameSenderConfig& video_config,
StatusChangeCallback status_change_cb,
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb);
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb);
virtual ~VideoEncoder() {}
diff --git a/chromium/media/cast/sender/video_encoder_unittest.cc b/chromium/media/cast/sender/video_encoder_unittest.cc
index eeaf2321014..a8c54b7dbbc 100644
--- a/chromium/media/cast/sender/video_encoder_unittest.cc
+++ b/chromium/media/cast/sender/video_encoder_unittest.cc
@@ -77,9 +77,6 @@ class VideoEncoderTest
base::Unretained(this)),
base::BindRepeating(
&FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator,
- base::Unretained(vea_factory_.get())),
- base::BindRepeating(
- &FakeVideoEncodeAcceleratorFactory::CreateSharedMemory,
base::Unretained(vea_factory_.get())));
RunTasksAndAdvanceClock();
if (is_encoder_present())
@@ -164,13 +161,10 @@ class VideoEncoderTest
// If the implementation of |video_encoder_| is ExternalVideoEncoder, check
// that the VEA factory has responded (by running the callbacks) a specific
// number of times. Otherwise, check that the VEA factory is inactive.
- void ExpectVEAResponsesForExternalVideoEncoder(
- int vea_response_count,
- int shm_response_count) const {
+ void ExpectVEAResponseForExternalVideoEncoder(int vea_response_count) const {
if (!vea_factory_)
return;
EXPECT_EQ(vea_response_count, vea_factory_->vea_response_count());
- EXPECT_EQ(shm_response_count, vea_factory_->shm_response_count());
}
void SetVEAFactoryAutoRespond(bool auto_respond) {
@@ -220,7 +214,7 @@ TEST_P(VideoEncoderTest, MAYBE_EncodesVariedFrameSizes) {
CreateEncoder();
SetVEAFactoryAutoRespond(true);
- ExpectVEAResponsesForExternalVideoEncoder(0, 0);
+ ExpectVEAResponseForExternalVideoEncoder(0);
std::vector<gfx::Size> frame_sizes;
frame_sizes.push_back(gfx::Size(128, 72));
@@ -350,14 +344,14 @@ TEST_P(VideoEncoderTest, MAYBE_CanBeDestroyedBeforeVEAIsCreated) {
// Destroy the encoder, and confirm the VEA Factory did not respond yet.
DestroyEncoder();
- ExpectVEAResponsesForExternalVideoEncoder(0, 0);
+ ExpectVEAResponseForExternalVideoEncoder(0);
// Allow the VEA Factory to respond by running the creation callback. When
// the task runs, it will be a no-op since the weak pointers to the
// ExternalVideoEncoder were invalidated.
SetVEAFactoryAutoRespond(true);
RunTasksAndAdvanceClock();
- ExpectVEAResponsesForExternalVideoEncoder(1, 0);
+ ExpectVEAResponseForExternalVideoEncoder(1);
}
namespace {
diff --git a/chromium/media/cast/sender/video_frame_factory.h b/chromium/media/cast/sender/video_frame_factory.h
index 367f2265058..1db6ebecf2f 100644
--- a/chromium/media/cast/sender/video_frame_factory.h
+++ b/chromium/media/cast/sender/video_frame_factory.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_CAST_SENDER_VIDEO_FRAME_FACTORY_H_
#define MEDIA_CAST_SENDER_VIDEO_FRAME_FACTORY_H_
-#include <memory>
-
#include "base/time/time.h"
namespace gfx {
diff --git a/chromium/media/cast/sender/video_sender.cc b/chromium/media/cast/sender/video_sender.cc
index 5962cd92731..6e3949ee2bc 100644
--- a/chromium/media/cast/sender/video_sender.cc
+++ b/chromium/media/cast/sender/video_sender.cc
@@ -90,7 +90,6 @@ VideoSender::VideoSender(
const FrameSenderConfig& video_config,
StatusChangeCallback status_change_cb,
const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
CastTransport* const transport_sender,
PlayoutDelayChangeCB playout_delay_change_cb,
media::VideoCaptureFeedbackCB feedback_callback)
@@ -112,12 +111,8 @@ VideoSender::VideoSender(
low_latency_mode_(false),
last_reported_encoder_utilization_(-1.0),
last_reported_lossy_utilization_(-1.0) {
- video_encoder_ = VideoEncoder::Create(
- cast_environment_,
- video_config,
- status_change_cb,
- create_vea_cb,
- create_video_encode_mem_cb);
+ video_encoder_ = VideoEncoder::Create(cast_environment_, video_config,
+ status_change_cb, create_vea_cb);
if (!video_encoder_) {
cast_environment_->PostTask(
CastEnvironment::MAIN, FROM_HERE,
diff --git a/chromium/media/cast/sender/video_sender.h b/chromium/media/cast/sender/video_sender.h
index 33d38e7a4a0..053d0dda9d2 100644
--- a/chromium/media/cast/sender/video_sender.h
+++ b/chromium/media/cast/sender/video_sender.h
@@ -44,7 +44,6 @@ class VideoSender : public FrameSender {
const FrameSenderConfig& video_config,
StatusChangeCallback status_change_cb,
const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
CastTransport* const transport_sender,
PlayoutDelayChangeCB playout_delay_change_cb,
media::VideoCaptureFeedbackCB feedback_callback);
diff --git a/chromium/media/cast/sender/video_sender_unittest.cc b/chromium/media/cast/sender/video_sender_unittest.cc
index 580f5482fce..05584fe0dac 100644
--- a/chromium/media/cast/sender/video_sender_unittest.cc
+++ b/chromium/media/cast/sender/video_sender_unittest.cc
@@ -112,13 +112,11 @@ class PeerVideoSender : public VideoSender {
const FrameSenderConfig& video_config,
const StatusChangeCallback& status_change_cb,
const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
CastTransport* const transport_sender)
: VideoSender(cast_environment,
video_config,
status_change_cb,
create_vea_cb,
- create_video_encode_mem_cb,
transport_sender,
base::BindRepeating(&IgnorePlayoutDelayChanges),
base::BindRepeating(&PeerVideoSender::ProcessFeedback,
@@ -196,16 +194,12 @@ class VideoSenderTest : public ::testing::Test {
base::BindRepeating(
&FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator,
base::Unretained(&vea_factory_)),
- base::BindRepeating(
- &FakeVideoEncodeAcceleratorFactory::CreateSharedMemory,
- base::Unretained(&vea_factory_)),
transport_sender_.get());
} else {
video_sender_ = std::make_unique<PeerVideoSender>(
cast_environment_, video_config,
base::BindRepeating(&SaveOperationalStatus, &operational_status_),
- CreateDefaultVideoEncodeAcceleratorCallback(),
- CreateDefaultVideoEncodeMemoryCallback(), transport_sender_.get());
+ base::DoNothing(), transport_sender_.get());
}
task_runner_->RunTasks();
}
@@ -286,7 +280,6 @@ TEST_F(VideoSenderTest, ExternalEncoder) {
// VideoSender created an encoder for 1280x720 frames, in order to provide the
// INITIALIZED status.
EXPECT_EQ(1, vea_factory_.vea_response_count());
- EXPECT_LT(0, vea_factory_.shm_response_count());
scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
@@ -297,13 +290,11 @@ TEST_F(VideoSenderTest, ExternalEncoder) {
// VideoSender re-created the encoder for the 320x240 frames we're
// providing.
EXPECT_EQ(1, vea_factory_.vea_response_count());
- EXPECT_LT(0, vea_factory_.shm_response_count());
}
video_sender_.reset(NULL);
task_runner_->RunTasks();
EXPECT_EQ(1, vea_factory_.vea_response_count());
- EXPECT_LT(0, vea_factory_.shm_response_count());
}
TEST_F(VideoSenderTest, ExternalEncoderInitFails) {
diff --git a/chromium/media/cast/sender/vp8_encoder.h b/chromium/media/cast/sender/vp8_encoder.h
index a6080c41eec..00afbfdcb32 100644
--- a/chromium/media/cast/sender/vp8_encoder.h
+++ b/chromium/media/cast/sender/vp8_encoder.h
@@ -7,8 +7,6 @@
#include <stdint.h>
-#include <memory>
-
#include "base/macros.h"
#include "base/threading/thread_checker.h"
#include "media/base/feedback_signal_accumulator.h"
diff --git a/chromium/media/cast/sender/vp8_quantizer_parser_unittest.cc b/chromium/media/cast/sender/vp8_quantizer_parser_unittest.cc
index d001777691c..3f42076715b 100644
--- a/chromium/media/cast/sender/vp8_quantizer_parser_unittest.cc
+++ b/chromium/media/cast/sender/vp8_quantizer_parser_unittest.cc
@@ -10,10 +10,10 @@
#include "base/macros.h"
#include "base/time/time.h"
#include "media/cast/cast_config.h"
-#include "media/cast/receiver/video_decoder.h"
#include "media/cast/sender/sender_encoded_frame.h"
#include "media/cast/sender/vp8_encoder.h"
#include "media/cast/sender/vp8_quantizer_parser.h"
+#include "media/cast/test/receiver/video_decoder.h"
#include "media/cast/test/utility/default_config.h"
#include "media/cast/test/utility/video_utility.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/media/cdm/BUILD.gn b/chromium/media/cdm/BUILD.gn
index 49304dc271a..b166b77e8b0 100644
--- a/chromium/media/cdm/BUILD.gn
+++ b/chromium/media/cdm/BUILD.gn
@@ -9,7 +9,7 @@ source_set("cdm_api") {
}
source_set("cdm_type_conversion") {
- if (enable_library_cdms) {
+ if (enable_library_cdms || is_win) {
# This target is a subcomponent.
visibility = [
"//media",
@@ -51,6 +51,8 @@ source_set("cdm") {
"aes_decryptor.h",
"cbcs_decryptor.cc",
"cbcs_decryptor.h",
+ "cdm_capability.cc",
+ "cdm_capability.h",
"cdm_context_ref_impl.cc",
"cdm_context_ref_impl.h",
"cenc_decryptor.cc",
@@ -61,6 +63,8 @@ source_set("cdm") {
"default_cdm_factory.h",
"json_web_key.cc",
"json_web_key.h",
+ "supported_audio_codecs.cc",
+ "supported_audio_codecs.h",
]
# TODO(crbug.com/167187): Fix size_t to int truncations.
@@ -81,7 +85,6 @@ source_set("cdm") {
deps += [
":cdm_api",
":cdm_paths",
- ":cdm_type_conversion",
"//components/crash/core/common:crash_key",
]
sources += [
@@ -89,12 +92,6 @@ source_set("cdm") {
"cdm_adapter.h",
"cdm_adapter_factory.cc",
"cdm_adapter_factory.h",
- "cdm_allocator.cc",
- "cdm_allocator.h",
- "cdm_auxiliary_helper.cc",
- "cdm_auxiliary_helper.h",
- "cdm_helpers.cc",
- "cdm_helpers.h",
"cdm_module.cc",
"cdm_module.h",
"cdm_wrapper.h",
@@ -114,19 +111,39 @@ source_set("cdm") {
}
}
+ if (is_win || enable_library_cdms) {
+ sources += [
+ "cdm_allocator.cc",
+ "cdm_allocator.h",
+ "cdm_auxiliary_helper.cc",
+ "cdm_auxiliary_helper.h",
+ "cdm_helpers.cc",
+ "cdm_helpers.h",
+ ]
+ deps += [
+ ":cdm_api",
+ ":cdm_type_conversion",
+ ]
+ }
+
if (is_win) {
sources += [
"win/media_foundation_cdm.cc",
"win/media_foundation_cdm.h",
"win/media_foundation_cdm_factory.cc",
"win/media_foundation_cdm_factory.h",
+ "win/media_foundation_cdm_module.cc",
+ "win/media_foundation_cdm_module.h",
"win/media_foundation_cdm_session.cc",
"win/media_foundation_cdm_session.h",
]
libs = [ "Propsys.lib" ]
- deps += [ "//media/base/win:media_foundation_util" ]
+ deps += [
+ ":cdm_paths",
+ "//media/base/win:media_foundation_util",
+ ]
}
}
diff --git a/chromium/media/cdm/aes_cbc_crypto.h b/chromium/media/cdm/aes_cbc_crypto.h
index b6e0ee5965f..a01ebc02d95 100644
--- a/chromium/media/cdm/aes_cbc_crypto.h
+++ b/chromium/media/cdm/aes_cbc_crypto.h
@@ -7,8 +7,6 @@
#include <stdint.h>
-#include <string>
-
#include "base/containers/span.h"
#include "base/macros.h"
#include "media/base/media_export.h"
diff --git a/chromium/media/cdm/aes_cbc_crypto_unittest.cc b/chromium/media/cdm/aes_cbc_crypto_unittest.cc
index 4b996017215..a79c7598d63 100644
--- a/chromium/media/cdm/aes_cbc_crypto_unittest.cc
+++ b/chromium/media/cdm/aes_cbc_crypto_unittest.cc
@@ -7,13 +7,13 @@
#include <memory>
#include "base/containers/span.h"
-#include "base/optional.h"
#include "base/stl_util.h"
#include "crypto/encryptor.h"
#include "crypto/symmetric_key.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/boringssl/src/include/openssl/aes.h"
#include "third_party/boringssl/src/include/openssl/crypto.h"
#include "third_party/boringssl/src/include/openssl/err.h"
diff --git a/chromium/media/cdm/aes_decryptor_unittest.cc b/chromium/media/cdm/aes_decryptor_unittest.cc
index 36fd40537d5..caf7ec589b0 100644
--- a/chromium/media/cdm/aes_decryptor_unittest.cc
+++ b/chromium/media/cdm/aes_decryptor_unittest.cc
@@ -60,7 +60,7 @@ MATCHER(NotEmpty, "") {
}
MATCHER(IsJSONDictionary, "") {
std::string result(arg.begin(), arg.end());
- base::Optional<base::Value> root = base::JSONReader::Read(result);
+ absl::optional<base::Value> root = base::JSONReader::Read(result);
return (root && root->type() == base::Value::Type::DICTIONARY);
}
MATCHER(IsNullTime, "") {
diff --git a/chromium/media/cdm/cbcs_decryptor_unittest.cc b/chromium/media/cdm/cbcs_decryptor_unittest.cc
index 1d4192028bd..ac73c1844d9 100644
--- a/chromium/media/cdm/cbcs_decryptor_unittest.cc
+++ b/chromium/media/cdm/cbcs_decryptor_unittest.cc
@@ -9,7 +9,6 @@
#include <memory>
#include "base/containers/span.h"
-#include "base/optional.h"
#include "base/stl_util.h"
#include "base/time/time.h"
#include "crypto/encryptor.h"
@@ -17,6 +16,7 @@
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -108,7 +108,7 @@ class CbcsDecryptorTest : public testing::Test {
const std::vector<uint8_t>& data,
const std::string& iv,
const std::vector<SubsampleEntry>& subsample_entries,
- base::Optional<EncryptionPattern> encryption_pattern) {
+ absl::optional<EncryptionPattern> encryption_pattern) {
EXPECT_FALSE(data.empty());
EXPECT_FALSE(iv.empty());
diff --git a/chromium/media/cdm/cdm_adapter.cc b/chromium/media/cdm/cdm_adapter.cc
index ae40d1a7709..c0a849ae689 100644
--- a/chromium/media/cdm/cdm_adapter.cc
+++ b/chromium/media/cdm/cdm_adapter.cc
@@ -413,9 +413,9 @@ Decryptor* CdmAdapter::GetDecryptor() {
return this;
}
-base::Optional<base::UnguessableToken> CdmAdapter::GetCdmId() const {
+absl::optional<base::UnguessableToken> CdmAdapter::GetCdmId() const {
DCHECK(task_runner_->BelongsToCurrentThread());
- return base::nullopt;
+ return absl::nullopt;
}
void CdmAdapter::Decrypt(StreamType stream_type,
diff --git a/chromium/media/cdm/cdm_adapter.h b/chromium/media/cdm/cdm_adapter.h
index 57f2c4aeb0f..19976efc13d 100644
--- a/chromium/media/cdm/cdm_adapter.h
+++ b/chromium/media/cdm/cdm_adapter.h
@@ -13,7 +13,6 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
-#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -95,7 +94,7 @@ class MEDIA_EXPORT CdmAdapter final : public ContentDecryptionModule,
// CdmContext implementation.
std::unique_ptr<CallbackRegistration> RegisterEventCB(EventCB event_cb) final;
Decryptor* GetDecryptor() final;
- base::Optional<base::UnguessableToken> GetCdmId() const final;
+ absl::optional<base::UnguessableToken> GetCdmId() const final;
// Decryptor implementation.
void Decrypt(StreamType stream_type,
diff --git a/chromium/media/cdm/cdm_auxiliary_helper.cc b/chromium/media/cdm/cdm_auxiliary_helper.cc
index 6183e10da98..642c7834c7a 100644
--- a/chromium/media/cdm/cdm_auxiliary_helper.cc
+++ b/chromium/media/cdm/cdm_auxiliary_helper.cc
@@ -22,6 +22,10 @@ url::Origin CdmAuxiliaryHelper::GetCdmOrigin() {
return url::Origin();
}
+base::UnguessableToken CdmAuxiliaryHelper::GetCdmOriginId() {
+ return base::UnguessableToken::Null();
+}
+
cdm::Buffer* CdmAuxiliaryHelper::CreateCdmBuffer(size_t capacity) {
return nullptr;
}
diff --git a/chromium/media/cdm/cdm_auxiliary_helper.h b/chromium/media/cdm/cdm_auxiliary_helper.h
index 9bbf1301d12..5b9650e97bc 100644
--- a/chromium/media/cdm/cdm_auxiliary_helper.h
+++ b/chromium/media/cdm/cdm_auxiliary_helper.h
@@ -12,6 +12,7 @@
#include "base/callback.h"
#include "base/macros.h"
+#include "base/unguessable_token.h"
#include "media/base/media_export.h"
#include "media/cdm/cdm_allocator.h"
#include "media/cdm/output_protection.h"
@@ -51,6 +52,12 @@ class MEDIA_EXPORT CdmAuxiliaryHelper : public CdmAllocator,
// if the origin is unavailable or if error happened.
virtual url::Origin GetCdmOrigin();
+ // Gets the origin ID of the frame associated with the CDM. The origin ID does
+ // not reveal the origin directly and is resettable by the user by clearing
+ // browsing data. The origin ID can be empty if an error happened and should
+ // be handled by the caller.
+ virtual base::UnguessableToken GetCdmOriginId();
+
// CdmAllocator implementation.
cdm::Buffer* CreateCdmBuffer(size_t capacity) override;
std::unique_ptr<VideoFrameImpl> CreateCdmVideoFrame() override;
diff --git a/chromium/media/cdm/cdm_capability.cc b/chromium/media/cdm/cdm_capability.cc
new file mode 100644
index 00000000000..80ad67062c0
--- /dev/null
+++ b/chromium/media/cdm/cdm_capability.cc
@@ -0,0 +1,27 @@
+// Copyright 2021 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 "media/cdm/cdm_capability.h"
+
+#include <utility>
+
+namespace media {
+
+CdmCapability::CdmCapability() = default;
+
+CdmCapability::CdmCapability(
+ std::vector<AudioCodec> audio_codecs,
+ std::vector<VideoCodec> video_codecs,
+ base::flat_set<EncryptionScheme> encryption_schemes,
+ base::flat_set<CdmSessionType> session_types)
+ : audio_codecs(std::move(audio_codecs)),
+ video_codecs(std::move(video_codecs)),
+ encryption_schemes(std::move(encryption_schemes)),
+ session_types(std::move(session_types)) {}
+
+CdmCapability::CdmCapability(const CdmCapability& other) = default;
+
+CdmCapability::~CdmCapability() = default;
+
+} // namespace media
diff --git a/chromium/media/cdm/cdm_capability.h b/chromium/media/cdm/cdm_capability.h
new file mode 100644
index 00000000000..0548a3e1d7e
--- /dev/null
+++ b/chromium/media/cdm/cdm_capability.h
@@ -0,0 +1,51 @@
+// Copyright 2021 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 MEDIA_CDM_CDM_CAPABILITY_H_
+#define MEDIA_CDM_CDM_CAPABILITY_H_
+
+#include <vector>
+
+#include "base/containers/flat_set.h"
+#include "media/base/audio_codecs.h"
+#include "media/base/content_decryption_module.h"
+#include "media/base/encryption_scheme.h"
+#include "media/base/media_export.h"
+#include "media/base/video_codecs.h"
+
+namespace media {
+
+// Capabilities supported by a Content Decryption Module.
+struct MEDIA_EXPORT CdmCapability {
+ CdmCapability();
+ CdmCapability(std::vector<AudioCodec> audio_codecs,
+ std::vector<VideoCodec> video_codecs,
+ base::flat_set<EncryptionScheme> encryption_schemes,
+ base::flat_set<CdmSessionType> session_types);
+ CdmCapability(const CdmCapability& other);
+ ~CdmCapability();
+
+ // List of audio codecs supported by the CDM (e.g. opus). This is the set of
+ // codecs supported by the media pipeline using the CDM, where CDM does the
+ // decryption, and the media pipeline does decoding. As this is generic, not
+ // all profiles or levels of the specified codecs may actually be supported.
+ std::vector<AudioCodec> audio_codecs;
+
+ // List of video codecs supported by the CDM (e.g. vp8). This is the set of
+ // codecs supported by the media pipeline using the CDM, where CDM does the
+ // decryption, and the media pipeline does decoding. As this is generic, not
+ // all profiles or levels of the specified codecs may actually be supported.
+ // TODO(crbug.com/796725) Find a way to include profiles and levels.
+ std::vector<VideoCodec> video_codecs;
+
+ // List of encryption schemes supported by the CDM (e.g. cenc).
+ base::flat_set<EncryptionScheme> encryption_schemes;
+
+ // List of session types supported by the CDM.
+ base::flat_set<CdmSessionType> session_types;
+};
+
+} // namespace media
+
+#endif // MEDIA_CDM_CDM_CAPABILITY_H_
diff --git a/chromium/media/cdm/cdm_context_ref_impl.h b/chromium/media/cdm/cdm_context_ref_impl.h
index 299690cd3ba..7ea73f99eb9 100644
--- a/chromium/media/cdm/cdm_context_ref_impl.h
+++ b/chromium/media/cdm/cdm_context_ref_impl.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_CDM_CDM_CONTEXT_REF_IMPL_H_
#define MEDIA_CDM_CDM_CONTEXT_REF_IMPL_H_
-#include <memory>
-
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
diff --git a/chromium/media/cdm/cdm_paths.cc b/chromium/media/cdm/cdm_paths.cc
index 211169c7e5d..84c4a471819 100644
--- a/chromium/media/cdm/cdm_paths.cc
+++ b/chromium/media/cdm/cdm_paths.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "base/system/sys_info.h"
#include "media/media_buildflags.h"
namespace media {
@@ -39,4 +40,17 @@ base::FilePath GetPlatformSpecificDirectory(const std::string& cdm_base_path) {
base::FilePath::FromUTF8Unsafe(cdm_base_path));
}
+#if defined(OS_WIN)
+const char kCdmStore[] = "CdmStore";
+
+base::FilePath GetCdmStorePath(const base::FilePath& user_data_dir,
+ const base::UnguessableToken& cdm_origin_id,
+ const std::string& key_system) {
+ return user_data_dir.AppendASCII(kCdmStore)
+ .AppendASCII(base::SysInfo::ProcessCPUArchitecture())
+ .AppendASCII(cdm_origin_id.ToString())
+ .AppendASCII(key_system);
+}
+#endif // defined(OS_WIN)
+
} // namespace media
diff --git a/chromium/media/cdm/cdm_paths.h b/chromium/media/cdm/cdm_paths.h
index 7c67d1f0db5..d761a2bbddc 100644
--- a/chromium/media/cdm/cdm_paths.h
+++ b/chromium/media/cdm/cdm_paths.h
@@ -9,6 +9,8 @@
#include "base/files/file_path.h"
#include "base/token.h"
+#include "base/unguessable_token.h"
+#include "build/build_config.h"
namespace media {
@@ -41,6 +43,17 @@ base::FilePath GetPlatformSpecificDirectory(
const base::FilePath& cdm_base_path);
base::FilePath GetPlatformSpecificDirectory(const std::string& cdm_base_path);
+#if defined(OS_WIN)
+// Returns the "CDM store path" to be passed to `MediaFoundationCdm`. The
+// `user_data_dir` is typically the LPAC specific path, e.g.
+// C:\Users\<user>\AppData\Local\Packages\
+// cr.sb.cdm4b414ceb52402c4e188a185dd531c100416d8daf\AC\Google\Chrome\User Data
+// TODO(xhwang): Separate by Chromium user profile as well.
+base::FilePath GetCdmStorePath(const base::FilePath& user_data_dir,
+ const base::UnguessableToken& cdm_origin_id,
+ const std::string& key_system);
+#endif // defined(OS_WIN)
+
} // namespace media
#endif // MEDIA_CDM_CDM_PATHS_H_
diff --git a/chromium/media/cdm/cdm_wrapper.h b/chromium/media/cdm/cdm_wrapper.h
index ef0eab69bf2..d911516c6b9 100644
--- a/chromium/media/cdm/cdm_wrapper.h
+++ b/chromium/media/cdm/cdm_wrapper.h
@@ -7,8 +7,6 @@
#include <stdint.h>
-#include <string>
-
#include "base/check.h"
#include "base/compiler_specific.h"
#include "base/feature_list.h"
diff --git a/chromium/media/cdm/json_web_key.cc b/chromium/media/cdm/json_web_key.cc
index d3d696229b0..0fdc9dbb89f 100644
--- a/chromium/media/cdm/json_web_key.cc
+++ b/chromium/media/cdm/json_web_key.cc
@@ -168,7 +168,7 @@ bool ExtractKeysFromJWKSet(const std::string& jwk_set,
return false;
}
- base::Optional<base::Value> root = base::JSONReader::Read(jwk_set);
+ absl::optional<base::Value> root = base::JSONReader::Read(jwk_set);
if (!root || root->type() != base::Value::Type::DICTIONARY) {
DVLOG(1) << "Not valid JSON: " << jwk_set;
return false;
@@ -235,7 +235,7 @@ bool ExtractKeyIdsFromKeyIdsInitData(const std::string& input,
return false;
}
- base::Optional<base::Value> root = base::JSONReader::Read(input);
+ absl::optional<base::Value> root = base::JSONReader::Read(input);
if (!root || root->type() != base::Value::Type::DICTIONARY) {
error_message->assign("Not valid JSON: ");
error_message->append(ShortenTo64Characters(input));
@@ -297,8 +297,8 @@ void CreateLicenseRequest(const KeyIdList& key_ids,
CdmSessionType session_type,
std::vector<uint8_t>* license) {
// Create the license request.
- auto request = std::make_unique<base::DictionaryValue>();
- auto list = std::make_unique<base::ListValue>();
+ base::Value request(base::Value::Type::DICTIONARY);
+ base::Value list(base::Value::Type::LIST);
for (const auto& key_id : key_ids) {
std::string key_id_string;
base::Base64UrlEncode(
@@ -306,32 +306,32 @@ void CreateLicenseRequest(const KeyIdList& key_ids,
key_id.size()),
base::Base64UrlEncodePolicy::OMIT_PADDING, &key_id_string);
- list->AppendString(key_id_string);
+ list.Append(key_id_string);
}
- request->Set(kKeyIdsTag, std::move(list));
+ request.SetKey(kKeyIdsTag, std::move(list));
switch (session_type) {
case CdmSessionType::kTemporary:
- request->SetString(kTypeTag, kTemporarySession);
+ request.SetStringKey(kTypeTag, kTemporarySession);
break;
case CdmSessionType::kPersistentLicense:
- request->SetString(kTypeTag, kPersistentLicenseSession);
+ request.SetStringKey(kTypeTag, kPersistentLicenseSession);
break;
}
// Serialize the license request as a string.
std::string json;
JSONStringValueSerializer serializer(&json);
- serializer.Serialize(*request);
+ serializer.Serialize(request);
// Convert the serialized license request into std::vector and return it.
std::vector<uint8_t> result(json.begin(), json.end());
license->swap(result);
}
-void AddKeyIdsToDictionary(const KeyIdList& key_ids,
- base::DictionaryValue* dictionary) {
- auto list = std::make_unique<base::ListValue>();
+base::Value MakeKeyIdsDictionary(const KeyIdList& key_ids) {
+ base::Value dictionary(base::Value::Type::DICTIONARY);
+ base::Value list(base::Value::Type::LIST);
for (const auto& key_id : key_ids) {
std::string key_id_string;
base::Base64UrlEncode(
@@ -339,17 +339,18 @@ void AddKeyIdsToDictionary(const KeyIdList& key_ids,
key_id.size()),
base::Base64UrlEncodePolicy::OMIT_PADDING, &key_id_string);
- list->AppendString(key_id_string);
+ list.Append(key_id_string);
}
- dictionary->Set(kKeyIdsTag, std::move(list));
+ dictionary.SetKey(kKeyIdsTag, std::move(list));
+ return dictionary;
}
std::vector<uint8_t> SerializeDictionaryToVector(
- const base::DictionaryValue* dictionary) {
+ const base::Value& dictionary) {
// Serialize the dictionary as a string.
std::string json;
JSONStringValueSerializer serializer(&json);
- serializer.Serialize(*dictionary);
+ serializer.Serialize(dictionary);
// Convert the serialized data into std::vector and return it.
return std::vector<uint8_t>(json.begin(), json.end());
@@ -358,10 +359,9 @@ std::vector<uint8_t> SerializeDictionaryToVector(
void CreateKeyIdsInitData(const KeyIdList& key_ids,
std::vector<uint8_t>* init_data) {
// Create the init_data.
- auto dictionary = std::make_unique<base::DictionaryValue>();
- AddKeyIdsToDictionary(key_ids, dictionary.get());
+ auto dictionary = MakeKeyIdsDictionary(key_ids);
- auto data = SerializeDictionaryToVector(dictionary.get());
+ auto data = SerializeDictionaryToVector(dictionary);
init_data->swap(data);
}
@@ -372,9 +372,8 @@ void CreateKeyIdsInitData(const KeyIdList& key_ids,
// of the octet sequence containing the key ID value.
std::vector<uint8_t> CreateLicenseReleaseMessage(const KeyIdList& key_ids) {
// Create the init_data.
- auto dictionary = std::make_unique<base::DictionaryValue>();
- AddKeyIdsToDictionary(key_ids, dictionary.get());
- return SerializeDictionaryToVector(dictionary.get());
+ auto dictionary = MakeKeyIdsDictionary(key_ids);
+ return SerializeDictionaryToVector(dictionary);
}
bool ExtractFirstKeyIdFromLicenseRequest(const std::vector<uint8_t>& license,
@@ -387,7 +386,7 @@ bool ExtractFirstKeyIdFromLicenseRequest(const std::vector<uint8_t>& license,
return false;
}
- base::Optional<base::Value> root = base::JSONReader::Read(license_as_str);
+ absl::optional<base::Value> root = base::JSONReader::Read(license_as_str);
if (!root || root->type() != base::Value::Type::DICTIONARY) {
DVLOG(1) << "Not valid JSON: " << license_as_str;
return false;
diff --git a/chromium/media/cdm/json_web_key.h b/chromium/media/cdm/json_web_key.h
index d2add7bb3ee..c490a16a513 100644
--- a/chromium/media/cdm/json_web_key.h
+++ b/chromium/media/cdm/json_web_key.h
@@ -11,7 +11,6 @@
#include <utility>
#include <vector>
-#include "base/time/time.h"
#include "media/base/media_export.h"
namespace media {
diff --git a/chromium/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc b/chromium/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc
index 4a398807d72..9fd2daf5cb6 100644
--- a/chromium/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc
+++ b/chromium/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc
@@ -15,7 +15,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/no_destructor.h"
-#include "base/optional.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
// Necessary to convert async media::VideoDecoder to sync CdmVideoDecoder.
// Typically not recommended for production code, but is ok here since
// ClearKeyCdm is only for testing.
@@ -280,8 +280,8 @@ class VideoDecoderAdapter final : public CdmVideoDecoder {
// Results of |video_decoder_| operations. Set iff the callback of the
// operation has been called.
- base::Optional<Status> last_init_result_;
- base::Optional<Status> last_decode_status_;
+ absl::optional<Status> last_init_result_;
+ absl::optional<Status> last_decode_status_;
// Queue of decoded video frames.
using VideoFrameQueue = base::queue<scoped_refptr<VideoFrame>>;
diff --git a/chromium/media/cdm/mock_helpers.cc b/chromium/media/cdm/mock_helpers.cc
index 0e8b68e6287..4934a98dfc3 100644
--- a/chromium/media/cdm/mock_helpers.cc
+++ b/chromium/media/cdm/mock_helpers.cc
@@ -15,10 +15,16 @@ MockCdmAuxiliaryHelper::~MockCdmAuxiliaryHelper() = default;
void MockCdmAuxiliaryHelper::SetFileReadCB(FileReadCB file_read_cb) {}
cdm::Buffer* MockCdmAuxiliaryHelper::CreateCdmBuffer(size_t capacity) {
+ if (!allocator_)
+ return nullptr;
+
return allocator_->CreateCdmBuffer(capacity);
}
std::unique_ptr<VideoFrameImpl> MockCdmAuxiliaryHelper::CreateCdmVideoFrame() {
+ if (!allocator_)
+ return nullptr;
+
return allocator_->CreateCdmVideoFrame();
}
diff --git a/chromium/media/cdm/mock_helpers.h b/chromium/media/cdm/mock_helpers.h
index 5c812113220..678bd11e8a0 100644
--- a/chromium/media/cdm/mock_helpers.h
+++ b/chromium/media/cdm/mock_helpers.h
@@ -21,6 +21,7 @@ namespace media {
class MockCdmAuxiliaryHelper : public CdmAuxiliaryHelper {
public:
+ // `allocator` is optional; can be null if no need to create buffers/frames.
explicit MockCdmAuxiliaryHelper(std::unique_ptr<CdmAllocator> allocator);
~MockCdmAuxiliaryHelper() override;
@@ -50,6 +51,8 @@ class MockCdmAuxiliaryHelper : public CdmAuxiliaryHelper {
MOCK_METHOD1(GetStorageIdCalled, std::vector<uint8_t>(uint32_t version));
void GetStorageId(uint32_t version, StorageIdCB callback) override;
+ MOCK_METHOD0(GetCdmOriginId, base::UnguessableToken());
+
private:
std::unique_ptr<CdmAllocator> allocator_;
diff --git a/chromium/media/cdm/supported_audio_codecs.cc b/chromium/media/cdm/supported_audio_codecs.cc
new file mode 100644
index 00000000000..1f416ac1f6e
--- /dev/null
+++ b/chromium/media/cdm/supported_audio_codecs.cc
@@ -0,0 +1,20 @@
+// Copyright 2021 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 "media/cdm/supported_audio_codecs.h"
+
+#include "media/media_buildflags.h"
+
+namespace media {
+
+const std::vector<AudioCodec> GetCdmSupportedAudioCodecs() {
+ return {
+ AudioCodec::kCodecOpus, AudioCodec::kCodecVorbis, AudioCodec::kCodecFLAC,
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+ AudioCodec::kCodecAAC,
+#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
+ };
+}
+
+} // namespace media
diff --git a/chromium/media/cdm/supported_audio_codecs.h b/chromium/media/cdm/supported_audio_codecs.h
new file mode 100644
index 00000000000..c4e0d4bedfb
--- /dev/null
+++ b/chromium/media/cdm/supported_audio_codecs.h
@@ -0,0 +1,25 @@
+// Copyright 2021 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 MEDIA_CDM_SUPPORTED_AUDIO_CODECS_H_
+#define MEDIA_CDM_SUPPORTED_AUDIO_CODECS_H_
+
+#include <vector>
+
+#include "media/base/audio_codecs.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+// Returns a set of audio codecs that are supported for decoding by the
+// browser after a CDM has decrypted the stream. This will be used by
+// CDMs that only support decryption of audio content.
+// Note that this should only be used on desktop CDMs. On other platforms
+// (e.g. Android) we should query the system for (encrypted) audio codec
+// support.
+MEDIA_EXPORT const std::vector<AudioCodec> GetCdmSupportedAudioCodecs();
+
+} // namespace media
+
+#endif // MEDIA_CDM_SUPPORTED_AUDIO_CODECS_H_
diff --git a/chromium/media/cdm/supported_cdm_versions.cc b/chromium/media/cdm/supported_cdm_versions.cc
index 971895257f6..eca81444316 100644
--- a/chromium/media/cdm/supported_cdm_versions.cc
+++ b/chromium/media/cdm/supported_cdm_versions.cc
@@ -5,9 +5,9 @@
#include "media/cdm/supported_cdm_versions.h"
#include "base/command_line.h"
-#include "base/optional.h"
#include "base/strings/string_number_conversions.h"
#include "media/base/media_switches.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -15,17 +15,17 @@ namespace {
// Returns the overridden supported CDM interface version specified on command
// line, which can be null if not specified.
-base::Optional<int> GetSupportedCdmInterfaceVersionOverrideFromCommandLine() {
+absl::optional<int> GetSupportedCdmInterfaceVersionOverrideFromCommandLine() {
auto* command_line = base::CommandLine::ForCurrentProcess();
if (!command_line)
- return base::nullopt;
+ return absl::nullopt;
auto version_string = command_line->GetSwitchValueASCII(
switches::kOverrideEnabledCdmInterfaceVersion);
int version = 0;
if (!base::StringToInt(version_string, &version))
- return base::nullopt;
+ return absl::nullopt;
else
return version;
}
diff --git a/chromium/media/cdm/win/media_foundation_cdm.cc b/chromium/media/cdm/win/media_foundation_cdm.cc
index 548db42982e..b1f2ae2d08a 100644
--- a/chromium/media/cdm/win/media_foundation_cdm.cc
+++ b/chromium/media/cdm/win/media_foundation_cdm.cc
@@ -12,9 +12,10 @@
#include "base/win/scoped_co_mem.h"
#include "base/win/scoped_propvariant.h"
#include "base/win/win_util.h"
+#include "base/win/windows_version.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/cdm_promise.h"
-#include "media/base/win/mf_cdm_proxy.h"
+#include "media/base/win/media_foundation_cdm_proxy.h"
#include "media/base/win/mf_helpers.h"
#include "media/cdm/win/media_foundation_cdm_session.h"
@@ -95,16 +96,14 @@ HRESULT RefreshDecryptor(IMFTransform* decryptor,
return S_OK;
}
-class CdmProxyImpl
- : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IMFCdmProxy> {
+class CdmProxyImpl : public MediaFoundationCdmProxy {
public:
explicit CdmProxyImpl(ComPtr<IMFContentDecryptionModule> mf_cdm)
: mf_cdm_(mf_cdm) {}
- ~CdmProxyImpl() override = default;
- // IMFCdmProxy implementation
+ // MediaFoundationCdmProxy implementation
- STDMETHODIMP GetPMPServer(REFIID riid, LPVOID* object_result) override {
+ HRESULT GetPMPServer(REFIID riid, LPVOID* object_result) override {
DVLOG_FUNC(1);
ComPtr<IMFGetService> cdm_services;
RETURN_IF_FAILED(mf_cdm_.As(&cdm_services));
@@ -113,12 +112,12 @@ class CdmProxyImpl
return S_OK;
}
- STDMETHODIMP GetInputTrustAuthority(uint32_t stream_id,
- uint32_t /*stream_count*/,
- const uint8_t* content_init_data,
- uint32_t content_init_data_size,
- REFIID riid,
- IUnknown** object_out) override {
+ HRESULT GetInputTrustAuthority(uint32_t stream_id,
+ uint32_t /*stream_count*/,
+ const uint8_t* content_init_data,
+ uint32_t content_init_data_size,
+ REFIID riid,
+ IUnknown** object_out) override {
DVLOG_FUNC(1);
if (input_trust_authorities_.count(stream_id)) {
@@ -147,13 +146,13 @@ class CdmProxyImpl
return S_OK;
}
- STDMETHODIMP SetLastKeyId(uint32_t stream_id, REFGUID key_id) override {
+ HRESULT SetLastKeyId(uint32_t stream_id, REFGUID key_id) override {
DVLOG_FUNC(1);
last_key_ids_[stream_id] = key_id;
return S_OK;
}
- STDMETHODIMP RefreshTrustedInput() override {
+ HRESULT RefreshTrustedInput() override {
DVLOG_FUNC(1);
// Refresh all decryptors of the last key IDs.
@@ -179,7 +178,7 @@ class CdmProxyImpl
return S_OK;
}
- STDMETHODIMP
+ HRESULT
ProcessContentEnabler(IUnknown* request, IMFAsyncResult* result) override {
DVLOG_FUNC(1);
ComPtr<IMFContentEnabler> content_enabler;
@@ -188,6 +187,8 @@ class CdmProxyImpl
}
private:
+ ~CdmProxyImpl() override = default;
+
HRESULT GetProtectionSystemId(GUID* protection_system_id) {
// Typically the CDM should only return one protection system ID. So just
// use the first one if available.
@@ -222,6 +223,11 @@ class CdmProxyImpl
} // namespace
+// static
+bool MediaFoundationCdm::IsAvailable() {
+ return base::win::GetVersion() >= base::win::Version::WIN10_20H1;
+}
+
MediaFoundationCdm::MediaFoundationCdm(
Microsoft::WRL::ComPtr<IMFContentDecryptionModule> mf_cdm,
const SessionMessageCB& session_message_cb,
@@ -397,7 +403,7 @@ bool MediaFoundationCdm::GetMediaFoundationCdmProxy(
DVLOG_FUNC(1);
if (!cdm_proxy_)
- cdm_proxy_ = Make<CdmProxyImpl>(mf_cdm_);
+ cdm_proxy_ = base::MakeRefCounted<CdmProxyImpl>(mf_cdm_);
BindToCurrentLoop(std::move(get_mf_cdm_proxy_cb)).Run(cdm_proxy_);
return true;
diff --git a/chromium/media/cdm/win/media_foundation_cdm.h b/chromium/media/cdm/win/media_foundation_cdm.h
index 1020b732d0d..b5e80dfbf67 100644
--- a/chromium/media/cdm/win/media_foundation_cdm.h
+++ b/chromium/media/cdm/win/media_foundation_cdm.h
@@ -12,6 +12,7 @@
#include <memory>
#include <string>
+#include "base/memory/scoped_refptr.h"
#include "media/base/cdm_context.h"
#include "media/base/content_decryption_module.h"
#include "media/base/media_export.h"
@@ -25,6 +26,10 @@ class MediaFoundationCdmSession;
class MEDIA_EXPORT MediaFoundationCdm : public ContentDecryptionModule,
public CdmContext {
public:
+ // Checks whether MediaFoundationCdm is available based on OS version. Further
+ // checks need to be made to determine the usability and the capabilities.
+ static bool IsAvailable();
+
MediaFoundationCdm(
Microsoft::WRL::ComPtr<IMFContentDecryptionModule> mf_cdm,
const SessionMessageCB& session_message_cb,
@@ -89,7 +94,7 @@ class MEDIA_EXPORT MediaFoundationCdm : public ContentDecryptionModule,
// Session ID to session map.
std::map<std::string, std::unique_ptr<MediaFoundationCdmSession>> sessions_;
- Microsoft::WRL::ComPtr<IMFCdmProxy> cdm_proxy_;
+ scoped_refptr<MediaFoundationCdmProxy> cdm_proxy_;
};
} // namespace media
diff --git a/chromium/media/cdm/win/media_foundation_cdm_factory.cc b/chromium/media/cdm/win/media_foundation_cdm_factory.cc
index bb94d7ca9ff..9fa61d821a4 100644
--- a/chromium/media/cdm/win/media_foundation_cdm_factory.cc
+++ b/chromium/media/cdm/win/media_foundation_cdm_factory.cc
@@ -5,8 +5,10 @@
#include "media/cdm/win/media_foundation_cdm_factory.h"
#include <combaseapi.h>
+#include <initguid.h> // Needed for DEFINE_PROPERTYKEY to work properly.
#include <mferror.h>
#include <mfmediaengine.h>
+#include <propkeydef.h> // Needed for DEFINE_PROPERTYKEY.
#include <propvarutil.h>
#include "base/bind.h"
@@ -17,7 +19,9 @@
#include "media/base/bind_to_current_loop.h"
#include "media/base/cdm_config.h"
#include "media/base/win/mf_helpers.h"
+#include "media/cdm/cdm_paths.h"
#include "media/cdm/win/media_foundation_cdm.h"
+#include "media/cdm/win/media_foundation_cdm_module.h"
namespace media {
@@ -25,6 +29,22 @@ namespace {
using Microsoft::WRL::ComPtr;
+// Key to the CDM Origin ID to be passed to the CDM for privacy purposes. The
+// same value is also used in MediaFoundation CDMs. Do NOT change this value!
+DEFINE_PROPERTYKEY(EME_CONTENTDECRYPTIONMODULE_ORIGIN_ID,
+ 0x1218a3e2,
+ 0xcfb0,
+ 0x4c98,
+ 0x90,
+ 0xe5,
+ 0x5f,
+ 0x58,
+ 0x18,
+ 0xd4,
+ 0xb6,
+ 0x7e,
+ PID_FIRST_USABLE);
+
void SetBSTR(const wchar_t* str, PROPVARIANT* propvariant) {
propvariant->vt = VT_BSTR;
propvariant->bstrVal = SysAllocString(str);
@@ -105,20 +125,25 @@ HRESULT BuildCdmAccessConfigurations(const CdmConfig& cdm_config,
return S_OK;
}
-HRESULT BuildCdmProperties(ComPtr<IPropertyStore>& properties) {
+HRESULT BuildCdmProperties(const base::UnguessableToken& origin_id,
+ const base::FilePath& store_path,
+ ComPtr<IPropertyStore>& properties) {
+ DCHECK(!origin_id.is_empty());
+
ComPtr<IPropertyStore> temp_properties;
RETURN_IF_FAILED(PSCreateMemoryPropertyStore(IID_PPV_ARGS(&temp_properties)));
- // TODO(xhwang): Provide per-user, per-profile and per-key-system path here.
- base::FilePath temp_dir;
- CHECK(base::GetTempDir(&temp_dir));
- CHECK(base::DirectoryExists(temp_dir));
+ base::win::ScopedPropVariant origin_id_var;
+ RETURN_IF_FAILED(InitPropVariantFromString(
+ base::UTF8ToWide(origin_id.ToString()).c_str(), origin_id_var.Receive()));
+ RETURN_IF_FAILED(temp_properties->SetValue(
+ EME_CONTENTDECRYPTIONMODULE_ORIGIN_ID, origin_id_var.get()));
- base::win::ScopedPropVariant propvar;
- RETURN_IF_FAILED(
- InitPropVariantFromString(temp_dir.value().c_str(), propvar.Receive()));
+ base::win::ScopedPropVariant store_path_var;
+ RETURN_IF_FAILED(InitPropVariantFromString(store_path.value().c_str(),
+ store_path_var.Receive()));
RETURN_IF_FAILED(temp_properties->SetValue(
- MF_CONTENTDECRYPTIONMODULE_STOREPATH, propvar.get()));
+ MF_CONTENTDECRYPTIONMODULE_STOREPATH, store_path_var.get()));
properties = temp_properties;
return S_OK;
@@ -126,11 +151,14 @@ HRESULT BuildCdmProperties(ComPtr<IPropertyStore>& properties) {
} // namespace
-MediaFoundationCdmFactory::MediaFoundationCdmFactory() = default;
+MediaFoundationCdmFactory::MediaFoundationCdmFactory(
+ std::unique_ptr<CdmAuxiliaryHelper> helper,
+ const base::FilePath& user_data_dir)
+ : helper_(std::move(helper)), user_data_dir_(user_data_dir) {}
MediaFoundationCdmFactory::~MediaFoundationCdmFactory() = default;
-void MediaFoundationCdmFactory::SetCreateCdmFactoryCallback(
+void MediaFoundationCdmFactory::SetCreateCdmFactoryCallbackForTesting(
const std::string& key_system,
CreateCdmFactoryCB create_cdm_factory_cb) {
DCHECK(!create_cdm_factory_cbs_.count(key_system));
@@ -166,7 +194,7 @@ void MediaFoundationCdmFactory::Create(
BindToCurrentLoop(std::move(cdm_created_cb)).Run(cdm, "");
}
-HRESULT MediaFoundationCdmFactory::CreateMFCdmFactory(
+HRESULT MediaFoundationCdmFactory::GetCdmFactory(
const std::string& key_system,
Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory>& cdm_factory) {
// Use key system specific `create_cdm_factory_cb` if there's one registered.
@@ -180,14 +208,9 @@ HRESULT MediaFoundationCdmFactory::CreateMFCdmFactory(
return S_OK;
}
- // Otherwise, use the default creation.
- ComPtr<IMFMediaEngineClassFactory4> class_factory;
- RETURN_IF_FAILED(CoCreateInstance(CLSID_MFMediaEngineClassFactory, nullptr,
- CLSCTX_INPROC_SERVER,
- IID_PPV_ARGS(&class_factory)));
- auto key_system_str = base::UTF8ToWide(key_system);
- RETURN_IF_FAILED(class_factory->CreateContentDecryptionModuleFactory(
- key_system_str.c_str(), IID_PPV_ARGS(&cdm_factory)));
+ // Otherwise, use the one in MediaFoundationCdmModule.
+ RETURN_IF_FAILED(MediaFoundationCdmModule::GetInstance()->GetCdmFactory(
+ key_system, cdm_factory));
return S_OK;
}
@@ -196,7 +219,7 @@ HRESULT MediaFoundationCdmFactory::CreateCdmInternal(
const CdmConfig& cdm_config,
ComPtr<IMFContentDecryptionModule>& mf_cdm) {
ComPtr<IMFContentDecryptionModuleFactory> cdm_factory;
- RETURN_IF_FAILED(CreateMFCdmFactory(key_system, cdm_factory));
+ RETURN_IF_FAILED(GetCdmFactory(key_system, cdm_factory));
auto key_system_str = base::UTF8ToWide(key_system);
if (!cdm_factory->IsTypeSupported(key_system_str.c_str(), nullptr)) {
@@ -213,9 +236,27 @@ HRESULT MediaFoundationCdmFactory::CreateCdmInternal(
key_system_str.c_str(), configurations, ARRAYSIZE(configurations),
&cdm_access));
+ // Don't cache `origin_id` in this class since user can clear it any time.
+ base::UnguessableToken origin_id = helper_->GetCdmOriginId();
+ if (origin_id.is_empty()) {
+ DLOG(ERROR) << "Failed to get CDM origin ID";
+ return E_FAIL;
+ }
+
+ // Provide a per-user, per-arch, per-origin and per-key-system path.
+ auto store_path = GetCdmStorePath(user_data_dir_, origin_id, key_system);
+ DVLOG(1) << "store_path=" << store_path;
+
+ // Ensure the path exists. If it already exists, this call will do nothing.
+ base::File::Error file_error;
+ if (!base::CreateDirectoryAndGetError(store_path, &file_error)) {
+ DLOG(ERROR) << "Create CDM store path failed with " << file_error;
+ return E_FAIL;
+ }
+
ComPtr<IPropertyStore> cdm_properties;
ComPtr<IMFContentDecryptionModule> cdm;
- RETURN_IF_FAILED(BuildCdmProperties(cdm_properties));
+ RETURN_IF_FAILED(BuildCdmProperties(origin_id, store_path, cdm_properties));
RETURN_IF_FAILED(
cdm_access->CreateContentDecryptionModule(cdm_properties.Get(), &cdm));
diff --git a/chromium/media/cdm/win/media_foundation_cdm_factory.h b/chromium/media/cdm/win/media_foundation_cdm_factory.h
index 98b6d08ca44..4cb2b8d794c 100644
--- a/chromium/media/cdm/win/media_foundation_cdm_factory.h
+++ b/chromium/media/cdm/win/media_foundation_cdm_factory.h
@@ -9,18 +9,23 @@
#include <wrl.h>
#include <map>
+#include <memory>
#include <string>
#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/unguessable_token.h"
#include "base/win/scoped_com_initializer.h"
#include "media/base/cdm_factory.h"
#include "media/base/media_export.h"
+#include "media/cdm/cdm_auxiliary_helper.h"
namespace media {
class MEDIA_EXPORT MediaFoundationCdmFactory : public CdmFactory {
public:
- MediaFoundationCdmFactory();
+ MediaFoundationCdmFactory(std::unique_ptr<CdmAuxiliaryHelper> helper,
+ const base::FilePath& user_data_dir);
MediaFoundationCdmFactory(const MediaFoundationCdmFactory&) = delete;
MediaFoundationCdmFactory& operator=(const MediaFoundationCdmFactory&) =
delete;
@@ -30,8 +35,9 @@ class MEDIA_EXPORT MediaFoundationCdmFactory : public CdmFactory {
// support different key systems and for testing.
using CreateCdmFactoryCB = base::RepeatingCallback<HRESULT(
Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory>& factory)>;
- void SetCreateCdmFactoryCallback(const std::string& key_system,
- CreateCdmFactoryCB create_cdm_factory_cb);
+ void SetCreateCdmFactoryCallbackForTesting(
+ const std::string& key_system,
+ CreateCdmFactoryCB create_cdm_factory_cb);
// CdmFactory implementation.
void Create(const std::string& key_system,
@@ -43,7 +49,7 @@ class MEDIA_EXPORT MediaFoundationCdmFactory : public CdmFactory {
CdmCreatedCB cdm_created_cb) final;
private:
- HRESULT CreateMFCdmFactory(
+ HRESULT GetCdmFactory(
const std::string& key_system,
Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory>& cdm_factory);
HRESULT CreateCdmInternal(
@@ -51,6 +57,9 @@ class MEDIA_EXPORT MediaFoundationCdmFactory : public CdmFactory {
const CdmConfig& cdm_config,
Microsoft::WRL::ComPtr<IMFContentDecryptionModule>& mf_cdm);
+ std::unique_ptr<CdmAuxiliaryHelper> helper_;
+ base::FilePath user_data_dir_;
+
// IMFContentDecryptionModule implementations typically require MTA to run.
base::win::ScopedCOMInitializer com_initializer_{
base::win::ScopedCOMInitializer::kMTA};
diff --git a/chromium/media/cdm/win/media_foundation_cdm_factory_unittest.cc b/chromium/media/cdm/win/media_foundation_cdm_factory_unittest.cc
index 1ee8da42bf7..c5ac0650a47 100644
--- a/chromium/media/cdm/win/media_foundation_cdm_factory_unittest.cc
+++ b/chromium/media/cdm/win/media_foundation_cdm_factory_unittest.cc
@@ -11,6 +11,7 @@
#include "media/base/test_helpers.h"
#include "media/base/win/mf_helpers.h"
#include "media/base/win/mf_mocks.h"
+#include "media/cdm/mock_helpers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -34,7 +35,13 @@ class MediaFoundationCdmFactoryTest : public testing::Test {
MediaFoundationCdmFactoryTest()
: mf_cdm_factory_(MakeComPtr<MockMFCdmFactory>()),
mf_cdm_access_(MakeComPtr<MockMFCdmAccess>()),
- mf_cdm_(MakeComPtr<MockMFCdm>()) {}
+ mf_cdm_(MakeComPtr<MockMFCdm>()) {
+ auto cdm_helper =
+ std::make_unique<StrictMock<MockCdmAuxiliaryHelper>>(nullptr);
+ cdm_helper_ = cdm_helper.get();
+ cdm_factory_ = std::make_unique<MediaFoundationCdmFactory>(
+ std::move(cdm_helper), base::FilePath());
+ }
~MediaFoundationCdmFactoryTest() override = default;
@@ -48,8 +55,8 @@ class MediaFoundationCdmFactoryTest : public testing::Test {
return S_OK;
}
- void SetCreateCdmFactoryCallback(bool expect_success) {
- cdm_factory_.SetCreateCdmFactoryCallback(
+ void SetCreateCdmFactoryCallbackForTesting(bool expect_success) {
+ cdm_factory_->SetCreateCdmFactoryCallbackForTesting(
kClearKeyKeySystem,
base::BindRepeating(&MediaFoundationCdmFactoryTest::GetMockCdmFactory,
base::Unretained(this), expect_success));
@@ -57,7 +64,7 @@ class MediaFoundationCdmFactoryTest : public testing::Test {
protected:
void Create() {
- cdm_factory_.Create(
+ cdm_factory_->Create(
kClearKeyKeySystem, kHardwareSecureCdmConfig,
base::BindRepeating(&MockCdmClient::OnSessionMessage,
base::Unretained(&cdm_client_)),
@@ -77,18 +84,21 @@ class MediaFoundationCdmFactoryTest : public testing::Test {
ComPtr<MockMFCdmFactory> mf_cdm_factory_;
ComPtr<MockMFCdmAccess> mf_cdm_access_;
ComPtr<MockMFCdm> mf_cdm_;
- MediaFoundationCdmFactory cdm_factory_;
+ StrictMock<MockCdmAuxiliaryHelper>* cdm_helper_ = nullptr;
+ std::unique_ptr<MediaFoundationCdmFactory> cdm_factory_;
base::MockCallback<CdmCreatedCB> cdm_created_cb_;
};
TEST_F(MediaFoundationCdmFactoryTest, Create) {
- SetCreateCdmFactoryCallback(/*expect_success=*/true);
+ SetCreateCdmFactoryCallbackForTesting(/*expect_success=*/true);
COM_EXPECT_CALL(mf_cdm_factory_, IsTypeSupported(NotNull(), IsNull()))
.WillOnce(Return(TRUE));
COM_EXPECT_CALL(mf_cdm_factory_, CreateContentDecryptionModuleAccess(
NotNull(), NotNull(), _, _))
.WillOnce(DoAll(SetComPointee<3>(mf_cdm_access_.Get()), Return(S_OK)));
+ EXPECT_CALL(*cdm_helper_, GetCdmOriginId())
+ .WillOnce(Return(base::UnguessableToken::Create()));
COM_EXPECT_CALL(mf_cdm_access_, CreateContentDecryptionModule(NotNull(), _))
.WillOnce(DoAll(SetComPointee<1>(mf_cdm_.Get()), Return(S_OK)));
@@ -97,14 +107,14 @@ TEST_F(MediaFoundationCdmFactoryTest, Create) {
}
TEST_F(MediaFoundationCdmFactoryTest, CreateCdmFactoryFail) {
- SetCreateCdmFactoryCallback(/*expect_success=*/false);
+ SetCreateCdmFactoryCallbackForTesting(/*expect_success=*/false);
EXPECT_CALL(cdm_created_cb_, Run(IsNull(), _));
Create();
}
TEST_F(MediaFoundationCdmFactoryTest, IsTypeSupportedFail) {
- SetCreateCdmFactoryCallback(/*expect_success=*/true);
+ SetCreateCdmFactoryCallbackForTesting(/*expect_success=*/true);
COM_EXPECT_CALL(mf_cdm_factory_, IsTypeSupported(NotNull(), IsNull()))
.WillOnce(Return(FALSE));
@@ -114,7 +124,7 @@ TEST_F(MediaFoundationCdmFactoryTest, IsTypeSupportedFail) {
}
TEST_F(MediaFoundationCdmFactoryTest, CreateCdmAccessFail) {
- SetCreateCdmFactoryCallback(/*expect_success=*/true);
+ SetCreateCdmFactoryCallbackForTesting(/*expect_success=*/true);
COM_EXPECT_CALL(mf_cdm_factory_, IsTypeSupported(NotNull(), IsNull()))
.WillOnce(Return(TRUE));
@@ -126,14 +136,31 @@ TEST_F(MediaFoundationCdmFactoryTest, CreateCdmAccessFail) {
Create();
}
+TEST_F(MediaFoundationCdmFactoryTest, NullCdmOriginIdFail) {
+ SetCreateCdmFactoryCallbackForTesting(/*expect_success=*/true);
+
+ COM_EXPECT_CALL(mf_cdm_factory_, IsTypeSupported(NotNull(), IsNull()))
+ .WillOnce(Return(TRUE));
+ COM_EXPECT_CALL(mf_cdm_factory_, CreateContentDecryptionModuleAccess(
+ NotNull(), NotNull(), _, _))
+ .WillOnce(DoAll(SetComPointee<3>(mf_cdm_access_.Get()), Return(S_OK)));
+ EXPECT_CALL(*cdm_helper_, GetCdmOriginId())
+ .WillOnce(Return(base::UnguessableToken::Null()));
+
+ EXPECT_CALL(cdm_created_cb_, Run(IsNull(), _));
+ Create();
+}
+
TEST_F(MediaFoundationCdmFactoryTest, CreateCdmFail) {
- SetCreateCdmFactoryCallback(/*expect_success=*/true);
+ SetCreateCdmFactoryCallbackForTesting(/*expect_success=*/true);
COM_EXPECT_CALL(mf_cdm_factory_, IsTypeSupported(NotNull(), IsNull()))
.WillOnce(Return(TRUE));
COM_EXPECT_CALL(mf_cdm_factory_, CreateContentDecryptionModuleAccess(
NotNull(), NotNull(), _, _))
.WillOnce(DoAll(SetComPointee<3>(mf_cdm_access_.Get()), Return(S_OK)));
+ EXPECT_CALL(*cdm_helper_, GetCdmOriginId())
+ .WillOnce(Return(base::UnguessableToken::Create()));
COM_EXPECT_CALL(mf_cdm_access_, CreateContentDecryptionModule(NotNull(), _))
.WillOnce(DoAll(SetComPointee<1>(mf_cdm_.Get()), Return(E_FAIL)));
diff --git a/chromium/media/cdm/win/media_foundation_cdm_module.cc b/chromium/media/cdm/win/media_foundation_cdm_module.cc
new file mode 100644
index 00000000000..d0595cf5bd1
--- /dev/null
+++ b/chromium/media/cdm/win/media_foundation_cdm_module.cc
@@ -0,0 +1,131 @@
+// Copyright 2021 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 "media/cdm/win/media_foundation_cdm_module.h"
+
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/win/scoped_hstring.h"
+#include "media/base/win/mf_helpers.h"
+
+namespace media {
+
+namespace {
+
+using Microsoft::WRL::ComPtr;
+
+static MediaFoundationCdmModule* g_cdm_module = nullptr;
+
+} // namespace
+
+// static
+MediaFoundationCdmModule* MediaFoundationCdmModule::GetInstance() {
+ if (!g_cdm_module)
+ g_cdm_module = new MediaFoundationCdmModule();
+
+ return g_cdm_module;
+}
+
+MediaFoundationCdmModule::MediaFoundationCdmModule() = default;
+MediaFoundationCdmModule::~MediaFoundationCdmModule() = default;
+
+void MediaFoundationCdmModule::Initialize(const base::FilePath& cdm_path) {
+ DVLOG(1) << __func__ << ": cdm_path=" << cdm_path.value();
+
+ DCHECK(!initialized_);
+ initialized_ = true;
+
+ cdm_path_ = cdm_path;
+
+ // If `cdm_path_` is not empty, load the CDM before the sandbox is sealed.
+ if (!cdm_path_.empty()) {
+ library_ = base::ScopedNativeLibrary(cdm_path_);
+ LOG_IF(ERROR, !library_.is_valid())
+ << __func__ << ": Failed to load CDM at " << cdm_path_.value()
+ << " (Error: " << library_.GetError()->ToString() << ")";
+ }
+}
+
+HRESULT MediaFoundationCdmModule::GetCdmFactory(
+ const std::string& key_system,
+ Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory>& cdm_factory) {
+ if (!initialized_) {
+ DLOG(ERROR) << __func__ << " failed: Not initialized";
+ return E_NOT_VALID_STATE;
+ }
+
+ if (key_system.empty()) {
+ DLOG(ERROR) << __func__ << " failed: Empty key system";
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if (key_system_.empty())
+ key_system_ = key_system;
+
+ if (key_system != key_system_) {
+ DLOG(ERROR) << __func__ << " failed: key system mismatch";
+ return E_NOT_VALID_STATE;
+ }
+
+ if (!cdm_factory_)
+ RETURN_IF_FAILED(ActivateCdmFactory());
+
+ cdm_factory = cdm_factory_;
+ return S_OK;
+}
+
+HRESULT MediaFoundationCdmModule::ActivateCdmFactory() {
+ DCHECK(initialized_);
+
+ // For OS or store CDM, the `cdm_path_` is empty. Just use default creation.
+ if (cdm_path_.empty()) {
+ DCHECK(!library_.is_valid());
+ ComPtr<IMFMediaEngineClassFactory4> class_factory;
+ RETURN_IF_FAILED(CoCreateInstance(CLSID_MFMediaEngineClassFactory, nullptr,
+ CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(&class_factory)));
+ auto key_system_str = base::UTF8ToWide(key_system_);
+ RETURN_IF_FAILED(class_factory->CreateContentDecryptionModuleFactory(
+ key_system_str.c_str(), IID_PPV_ARGS(&cdm_factory_)));
+ return S_OK;
+ }
+
+ if (!library_.is_valid()) {
+ LOG(ERROR) << "CDM failed to load previously";
+ return E_FAIL;
+ }
+
+ // Initialization required to call base::win::ScopedHString::Create();
+ if (!base::win::ScopedHString::ResolveCoreWinRTStringDelayload())
+ return E_FAIL;
+
+ // Get function pointer to the activation factory.
+ using GetActivationFactoryFunc =
+ HRESULT(WINAPI*)(_In_ HSTRING activatible_class_id,
+ _COM_Outptr_ IActivationFactory * *factory);
+ const char kDllGetActivationFactory[] = "DllGetActivationFactory";
+ auto get_activation_factory_func = reinterpret_cast<GetActivationFactoryFunc>(
+ library_.GetFunctionPointer(kDllGetActivationFactory));
+ if (!get_activation_factory_func) {
+ LOG(ERROR) << "Cannot get function " << kDllGetActivationFactory;
+ return E_FAIL;
+ }
+
+ // Activate CdmFactory. Assuming the class ID is always in the format
+ // "<key_system>.ContentDecryptionModuleFactory".
+ auto class_name = base::win::ScopedHString::Create(
+ base::StringPiece(key_system_ + ".ContentDecryptionModuleFactory"));
+ ComPtr<IActivationFactory> activation_factory;
+ RETURN_IF_FAILED(
+ get_activation_factory_func(class_name.get(), &activation_factory));
+
+ ComPtr<IInspectable> inspectable_factory;
+ RETURN_IF_FAILED(activation_factory->ActivateInstance(&inspectable_factory));
+ RETURN_IF_FAILED(inspectable_factory.As(&cdm_factory_));
+
+ return S_OK;
+}
+
+} // namespace media
diff --git a/chromium/media/cdm/win/media_foundation_cdm_module.h b/chromium/media/cdm/win/media_foundation_cdm_module.h
new file mode 100644
index 00000000000..7f438127024
--- /dev/null
+++ b/chromium/media/cdm/win/media_foundation_cdm_module.h
@@ -0,0 +1,58 @@
+// Copyright 2021 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 MEDIA_CDM_WIN_MEDIA_FOUNDATION_CDM_MODULE_H_
+#define MEDIA_CDM_WIN_MEDIA_FOUNDATION_CDM_MODULE_H_
+
+#include <string>
+
+#include <mfcontentdecryptionmodule.h>
+#include <wrl.h>
+
+#include "base/files/file_path.h"
+#include "base/scoped_native_library.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+// A singleton in the MediaFoundationService process in charge of CDM loading
+// and IMFContentDecryptionModuleFactory activation.
+class MEDIA_EXPORT MediaFoundationCdmModule {
+ public:
+ static MediaFoundationCdmModule* GetInstance();
+
+ // Loads the CDM at `cdm_path` if not empty. So `ActivateCdmFactory()` can
+ // activate the IMFContentDecryptionModuleFactory from the CDM later. If the
+ // CDM is an OS or store CDM, `cdm_path` could be empty. See implementation
+ // details in ActivateCdmFactory() for how OS or store CDMs are handled.
+ // The caller should check `initialized()` and only call this function once.
+ void Initialize(const base::FilePath& cdm_path);
+
+ HRESULT GetCdmFactory(
+ const std::string& key_system,
+ Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory>& cdm_factory);
+
+ bool initialized() const { return initialized_; }
+ const base::FilePath& cdm_path() const { return cdm_path_; }
+
+ private:
+ MediaFoundationCdmModule();
+ MediaFoundationCdmModule(const MediaFoundationCdmModule&) = delete;
+ MediaFoundationCdmModule& operator=(const MediaFoundationCdmModule&) = delete;
+ ~MediaFoundationCdmModule();
+
+ HRESULT ActivateCdmFactory();
+
+ // Declared first so it's destructed after `cdm_factory_`.
+ base::ScopedNativeLibrary library_;
+
+ bool initialized_ = false;
+ base::FilePath cdm_path_;
+ std::string key_system_;
+ Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory> cdm_factory_;
+};
+
+} // namespace media
+
+#endif // MEDIA_CDM_WIN_MEDIA_FOUNDATION_CDM_MODULE_H_
diff --git a/chromium/media/device_monitors/device_monitor_mac.mm b/chromium/media/device_monitors/device_monitor_mac.mm
index 26bab09017d..91df5c668ec 100644
--- a/chromium/media/device_monitors/device_monitor_mac.mm
+++ b/chromium/media/device_monitors/device_monitor_mac.mm
@@ -134,7 +134,8 @@ class SuspendObserverDelegate;
base::ThreadChecker _mainThreadChecker;
}
-- (id)initWithOnChangedCallback:(const base::RepeatingClosure&)callback;
+- (instancetype)initWithOnChangedCallback:
+ (const base::RepeatingClosure&)callback;
- (void)startObserving:(base::scoped_nsobject<AVCaptureDevice>)device;
- (void)stopObserving:(AVCaptureDevice*)device;
- (void)clearOnDeviceChangedCallback;
@@ -348,7 +349,8 @@ void AVFoundationMonitorImpl::OnDeviceChanged() {
@implementation CrAVFoundationDeviceObserver
-- (id)initWithOnChangedCallback:(const base::RepeatingClosure&)callback {
+- (instancetype)initWithOnChangedCallback:
+ (const base::RepeatingClosure&)callback {
DCHECK(_mainThreadChecker.CalledOnValidThread());
if ((self = [super init])) {
DCHECK(!callback.is_null());
diff --git a/chromium/media/device_monitors/system_message_window_win.cc b/chromium/media/device_monitors/system_message_window_win.cc
index d20145cdfa9..30a7294070a 100644
--- a/chromium/media/device_monitors/system_message_window_win.cc
+++ b/chromium/media/device_monitors/system_message_window_win.cc
@@ -7,6 +7,8 @@
#include <dbt.h>
#include <stddef.h>
+#include <memory>
+
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/stl_util.h"
@@ -98,7 +100,7 @@ SystemMessageWindowWin::SystemMessageWindowWin() {
window_ =
CreateWindow(kWindowClassName, 0, 0, 0, 0, 0, 0, 0, 0, instance_, 0);
SetWindowLongPtr(window_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
- device_notifications_.reset(new DeviceNotifications(window_));
+ device_notifications_ = std::make_unique<DeviceNotifications>(window_);
}
SystemMessageWindowWin::~SystemMessageWindowWin() {
diff --git a/chromium/media/filters/BUILD.gn b/chromium/media/filters/BUILD.gn
index 3cc37a4379f..9f7dc8c0036 100644
--- a/chromium/media/filters/BUILD.gn
+++ b/chromium/media/filters/BUILD.gn
@@ -11,6 +11,7 @@ source_set("filters") {
# should be using //media and not directly DEP this roll-up target.
visibility = [
"//media",
+ "//media/fuchsia/audio",
"//media/renderers",
]
diff --git a/chromium/media/filters/android/media_codec_audio_decoder.cc b/chromium/media/filters/android/media_codec_audio_decoder.cc
index 1486e1adb2b..a2840b746dd 100644
--- a/chromium/media/filters/android/media_codec_audio_decoder.cc
+++ b/chromium/media/filters/android/media_codec_audio_decoder.cc
@@ -5,6 +5,7 @@
#include "media/filters/android/media_codec_audio_decoder.h"
#include <cmath>
+#include <memory>
#include "base/android/build_info.h"
#include "base/bind.h"
@@ -153,10 +154,10 @@ bool MediaCodecAudioDecoder::CreateMediaCodecLoop() {
return false;
}
- codec_loop_.reset(
- new MediaCodecLoop(base::android::BuildInfo::GetInstance()->sdk_int(),
- this, std::move(audio_codec_bridge),
- scoped_refptr<base::SingleThreadTaskRunner>()));
+ codec_loop_ = std::make_unique<MediaCodecLoop>(
+ base::android::BuildInfo::GetInstance()->sdk_int(), this,
+ std::move(audio_codec_bridge),
+ scoped_refptr<base::SingleThreadTaskRunner>());
return true;
}
@@ -491,7 +492,7 @@ bool MediaCodecAudioDecoder::OnOutputFormatChanged() {
timestamp_helper_->base_timestamp() == kNoTimestamp
? kNoTimestamp
: timestamp_helper_->GetTimestamp();
- timestamp_helper_.reset(new AudioTimestampHelper(sample_rate_));
+ timestamp_helper_ = std::make_unique<AudioTimestampHelper>(sample_rate_);
if (base_timestamp != kNoTimestamp)
timestamp_helper_->SetBaseTimestamp(base_timestamp);
}
@@ -523,7 +524,7 @@ void MediaCodecAudioDecoder::SetInitialConfiguration() {
channel_count_ = ChannelLayoutToChannelCount(channel_layout_);
sample_rate_ = config_.samples_per_second();
- timestamp_helper_.reset(new AudioTimestampHelper(sample_rate_));
+ timestamp_helper_ = std::make_unique<AudioTimestampHelper>(sample_rate_);
}
void MediaCodecAudioDecoder::PumpMediaCodecLoop() {
diff --git a/chromium/media/filters/android/media_codec_audio_decoder.h b/chromium/media/filters/android/media_codec_audio_decoder.h
index ef8433c07a3..acf37982cb2 100644
--- a/chromium/media/filters/android/media_codec_audio_decoder.h
+++ b/chromium/media/filters/android/media_codec_audio_decoder.h
@@ -12,7 +12,6 @@
#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
#include "base/timer/timer.h"
#include "media/base/android/media_codec_loop.h"
#include "media/base/android/media_crypto_context.h"
diff --git a/chromium/media/filters/android/video_frame_extractor.h b/chromium/media/filters/android/video_frame_extractor.h
index 53257da31af..11755107976 100644
--- a/chromium/media/filters/android/video_frame_extractor.h
+++ b/chromium/media/filters/android/video_frame_extractor.h
@@ -11,7 +11,6 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
#include "media/base/media_export.h"
#include "media/filters/ffmpeg_demuxer.h"
diff --git a/chromium/media/filters/audio_decoder_unittest.cc b/chromium/media/filters/audio_decoder_unittest.cc
index 7b3899f6007..6abf4283f02 100644
--- a/chromium/media/filters/audio_decoder_unittest.cc
+++ b/chromium/media/filters/audio_decoder_unittest.cc
@@ -139,8 +139,8 @@ class AudioDecoderTest
break;
#if defined(OS_ANDROID)
case MEDIA_CODEC:
- decoder_.reset(new MediaCodecAudioDecoder(
- task_environment_.GetMainThreadTaskRunner()));
+ decoder_ = std::make_unique<MediaCodecAudioDecoder>(
+ task_environment_.GetMainThreadTaskRunner());
break;
#endif
}
diff --git a/chromium/media/filters/audio_renderer_algorithm.cc b/chromium/media/filters/audio_renderer_algorithm.cc
index ef1196f1f34..d3e1e1fc834 100644
--- a/chromium/media/filters/audio_renderer_algorithm.cc
+++ b/chromium/media/filters/audio_renderer_algorithm.cc
@@ -357,7 +357,7 @@ void AudioRendererAlgorithm::EnqueueBuffer(
}
void AudioRendererAlgorithm::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
DCHECK_GE(playback_threshold_, min_playback_threshold_);
DCHECK_LE(playback_threshold_, capacity_);
DCHECK_LE(capacity_, max_capacity_);
diff --git a/chromium/media/filters/audio_renderer_algorithm.h b/chromium/media/filters/audio_renderer_algorithm.h
index 9c07d2ecee0..f2a1f779e5e 100644
--- a/chromium/media/filters/audio_renderer_algorithm.h
+++ b/chromium/media/filters/audio_renderer_algorithm.h
@@ -83,7 +83,7 @@ class MEDIA_EXPORT AudioRendererAlgorithm {
// Sets a target queue latency. This target will be clamped and stored in
// |playback_threshold_|. It may also cause an increase in |capacity_|. A
// value of nullopt indicates the algorithm should restore the default value.
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint);
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint);
// Sets a flag indicating whether apply pitch adjustments when playing back
// at rates other than 1.0. Concretely, we use WSOLA when this is true, and
@@ -217,7 +217,7 @@ class MEDIA_EXPORT AudioRendererAlgorithm {
// Hint to adjust |playback_threshold_| as a means of controlling playback
// start latency. See SetLatencyHint();
- base::Optional<base::TimeDelta> latency_hint_;
+ absl::optional<base::TimeDelta> latency_hint_;
// Whether to apply pitch adjusments or not when playing back at rates other
// than 1.0. In other words, we use WSOLA to preserve pitch when this is on,
diff --git a/chromium/media/filters/audio_renderer_algorithm_unittest.cc b/chromium/media/filters/audio_renderer_algorithm_unittest.cc
index b5a0eeb9569..b6ea7271944 100644
--- a/chromium/media/filters/audio_renderer_algorithm_unittest.cc
+++ b/chromium/media/filters/audio_renderer_algorithm_unittest.cc
@@ -976,7 +976,7 @@ TEST_F(AudioRendererAlgorithmTest, LowLatencyHint) {
// Clearing the hint should restore the higher default playback threshold,
// such that we no longer have enough buffer to be "adequate for playback".
- algorithm_.SetLatencyHint(base::nullopt);
+ algorithm_.SetLatencyHint(absl::nullopt);
EXPECT_FALSE(algorithm_.IsQueueAdequateForPlayback());
// Fill until "full". Verify that "adequate" now matches "full".
@@ -1027,7 +1027,7 @@ TEST_F(AudioRendererAlgorithmTest, HighLatencyHint) {
// Clearing the hint should restore the lower default playback threshold and
// capacity.
- algorithm_.SetLatencyHint(base::nullopt);
+ algorithm_.SetLatencyHint(absl::nullopt);
EXPECT_EQ(algorithm_.QueueCapacity(), default_capacity);
// The queue is over-full from our last fill when the hint was set. Flush and
diff --git a/chromium/media/filters/audio_video_metadata_extractor.h b/chromium/media/filters/audio_video_metadata_extractor.h
index 425793317af..b875caeaf04 100644
--- a/chromium/media/filters/audio_video_metadata_extractor.h
+++ b/chromium/media/filters/audio_video_metadata_extractor.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_BASE_AUDIO_VIDEO_METADATA_EXTRACTOR_H_
-#define MEDIA_BASE_AUDIO_VIDEO_METADATA_EXTRACTOR_H_
+#ifndef MEDIA_FILTERS_AUDIO_VIDEO_METADATA_EXTRACTOR_H_
+#define MEDIA_FILTERS_AUDIO_VIDEO_METADATA_EXTRACTOR_H_
#include <map>
#include <string>
@@ -110,4 +110,4 @@ class MEDIA_EXPORT AudioVideoMetadataExtractor {
} // namespace media
-#endif // MEDIA_BASE_AUDIO_VIDEO_METADATA_EXTRACTOR_H_
+#endif // MEDIA_FILTERS_AUDIO_VIDEO_METADATA_EXTRACTOR_H_
diff --git a/chromium/media/filters/chunk_demuxer.cc b/chromium/media/filters/chunk_demuxer.cc
index 5f650f37ec4..9965a49d5dd 100644
--- a/chromium/media/filters/chunk_demuxer.cc
+++ b/chromium/media/filters/chunk_demuxer.cc
@@ -570,9 +570,9 @@ int64_t ChunkDemuxer::GetMemoryUsage() const {
return mem;
}
-base::Optional<container_names::MediaContainerName>
+absl::optional<container_names::MediaContainerName>
ChunkDemuxer::GetContainerForMetrics() const {
- return base::nullopt;
+ return absl::nullopt;
}
void ChunkDemuxer::AbortPendingReads() {
diff --git a/chromium/media/filters/chunk_demuxer.h b/chromium/media/filters/chunk_demuxer.h
index 68a2488a13a..6f40e9c3656 100644
--- a/chromium/media/filters/chunk_demuxer.h
+++ b/chromium/media/filters/chunk_demuxer.h
@@ -225,7 +225,7 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer {
std::vector<DemuxerStream*> GetAllStreams() override;
base::TimeDelta GetStartTime() const override;
int64_t GetMemoryUsage() const override;
- base::Optional<container_names::MediaContainerName> GetContainerForMetrics()
+ absl::optional<container_names::MediaContainerName> GetContainerForMetrics()
const override;
void AbortPendingReads() override;
diff --git a/chromium/media/filters/decrypting_audio_decoder.h b/chromium/media/filters/decrypting_audio_decoder.h
index ce507173ea2..9ca951e2950 100644
--- a/chromium/media/filters/decrypting_audio_decoder.h
+++ b/chromium/media/filters/decrypting_audio_decoder.h
@@ -11,7 +11,6 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
#include "media/base/audio_decoder.h"
#include "media/base/callback_registry.h"
#include "media/base/cdm_context.h"
diff --git a/chromium/media/filters/ffmpeg_audio_decoder.h b/chromium/media/filters/ffmpeg_audio_decoder.h
index 58b132a7445..bd8f074e23b 100644
--- a/chromium/media/filters/ffmpeg_audio_decoder.h
+++ b/chromium/media/filters/ffmpeg_audio_decoder.h
@@ -11,7 +11,6 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/sequence_checker.h"
-#include "base/time/time.h"
#include "media/base/audio_buffer.h"
#include "media/base/audio_decoder.h"
#include "media/base/demuxer_stream.h"
diff --git a/chromium/media/filters/ffmpeg_demuxer.cc b/chromium/media/filters/ffmpeg_demuxer.cc
index 828b043c051..9dfa1ddee89 100644
--- a/chromium/media/filters/ffmpeg_demuxer.cc
+++ b/chromium/media/filters/ffmpeg_demuxer.cc
@@ -585,6 +585,20 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
base::TimeDelta::FromMicroseconds(1));
}
+ // Fixup negative timestamps where the before-zero portion is completely
+ // discarded after decoding.
+ if (buffer->timestamp() < base::TimeDelta()) {
+ // Discard padding may also remove samples after zero.
+ auto fixed_ts = buffer->discard_padding().first + buffer->timestamp();
+
+ // Allow for rounding error in the discard padding calculations.
+ if (fixed_ts == base::TimeDelta::FromMicroseconds(-1))
+ fixed_ts = base::TimeDelta();
+
+ if (fixed_ts >= base::TimeDelta())
+ buffer->set_timestamp(fixed_ts);
+ }
+
// Only allow negative timestamps past if we know they'll be fixed up by the
// code paths below; otherwise they should be treated as a parse error.
if ((!fixup_chained_ogg_ || last_packet_timestamp_ == kNoTimestamp) &&
@@ -1173,7 +1187,7 @@ int64_t FFmpegDemuxer::GetMemoryUsage() const {
return allocation_size;
}
-base::Optional<container_names::MediaContainerName>
+absl::optional<container_names::MediaContainerName>
FFmpegDemuxer::GetContainerForMetrics() const {
return container();
}
diff --git a/chromium/media/filters/ffmpeg_demuxer.h b/chromium/media/filters/ffmpeg_demuxer.h
index c2fc118b3ca..b137a2b5685 100644
--- a/chromium/media/filters/ffmpeg_demuxer.h
+++ b/chromium/media/filters/ffmpeg_demuxer.h
@@ -229,7 +229,7 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer {
std::vector<DemuxerStream*> GetAllStreams() override;
base::TimeDelta GetStartTime() const override;
int64_t GetMemoryUsage() const override;
- base::Optional<container_names::MediaContainerName> GetContainerForMetrics()
+ absl::optional<container_names::MediaContainerName> GetContainerForMetrics()
const override;
// Calls |encrypted_media_init_data_cb_| with the initialization data
diff --git a/chromium/media/filters/ffmpeg_demuxer_unittest.cc b/chromium/media/filters/ffmpeg_demuxer_unittest.cc
index 63f7c08feed..8391036bda1 100644
--- a/chromium/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/chromium/media/filters/ffmpeg_demuxer_unittest.cc
@@ -11,7 +11,6 @@
#include <utility>
#include "base/bind.h"
-#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/logging.h"
diff --git a/chromium/media/filters/ffmpeg_video_decoder.cc b/chromium/media/filters/ffmpeg_video_decoder.cc
index c9ca3a8b6fa..6ee981a2942 100644
--- a/chromium/media/filters/ffmpeg_video_decoder.cc
+++ b/chromium/media/filters/ffmpeg_video_decoder.cc
@@ -109,7 +109,7 @@ SupportedVideoDecoderConfigs FFmpegVideoDecoder::SupportedConfigsForWebRTC() {
}
FFmpegVideoDecoder::FFmpegVideoDecoder(MediaLog* media_log)
- : media_log_(media_log), state_(kUninitialized), decode_nalus_(false) {
+ : media_log_(media_log) {
DVLOG(1) << __func__;
DETACH_FROM_SEQUENCE(sequence_checker_);
}
@@ -159,6 +159,9 @@ int FFmpegVideoDecoder::GetVideoBuffer(struct AVCodecContext* codec_context,
gfx::Size coded_size(std::max(size.width(), codec_context->coded_width),
std::max(size.height(), codec_context->coded_height));
+ if (force_allocation_error_)
+ return AVERROR(EINVAL);
+
// FFmpeg expects the initial allocation to be zero-initialized. Failure to
// do so can lead to uninitialized value usage. See http://crbug.com/390941
scoped_refptr<VideoFrame> video_frame = frame_pool_.CreateFrame(
diff --git a/chromium/media/filters/ffmpeg_video_decoder.h b/chromium/media/filters/ffmpeg_video_decoder.h
index 4436e2bf906..08b59748605 100644
--- a/chromium/media/filters/ffmpeg_video_decoder.h
+++ b/chromium/media/filters/ffmpeg_video_decoder.h
@@ -57,6 +57,8 @@ class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder {
AVFrame* frame,
int flags);
+ void force_allocation_error_for_testing() { force_allocation_error_ = true; }
+
private:
enum DecoderState {
kUninitialized,
@@ -79,9 +81,9 @@ class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder {
SEQUENCE_CHECKER(sequence_checker_);
- MediaLog* media_log_;
+ MediaLog* const media_log_;
- DecoderState state_;
+ DecoderState state_ = kUninitialized;
OutputCB output_cb_;
@@ -92,7 +94,9 @@ class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder {
VideoFramePool frame_pool_;
- bool decode_nalus_;
+ bool decode_nalus_ = false;
+
+ bool force_allocation_error_ = false;
std::unique_ptr<FFmpegDecodingLoop> decoding_loop_;
diff --git a/chromium/media/filters/ffmpeg_video_decoder_unittest.cc b/chromium/media/filters/ffmpeg_video_decoder_unittest.cc
index 3a07a387ad1..dead41951b0 100644
--- a/chromium/media/filters/ffmpeg_video_decoder_unittest.cc
+++ b/chromium/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -260,6 +260,14 @@ TEST_F(FFmpegVideoDecoderTest, DecodeFrame_Normal) {
ASSERT_EQ(1U, output_frames_.size());
}
+TEST_F(FFmpegVideoDecoderTest, DecodeFrame_OOM) {
+ Initialize();
+ decoder_->force_allocation_error_for_testing();
+ EXPECT_MEDIA_LOG(_);
+ EXPECT_FALSE(DecodeSingleFrame(i_frame_buffer_).is_ok());
+ EXPECT_TRUE(output_frames_.empty());
+}
+
TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeError) {
Initialize();
diff --git a/chromium/media/filters/file_data_source.h b/chromium/media/filters/file_data_source.h
index 60fdcbe6be7..7b5fd6d340d 100644
--- a/chromium/media/filters/file_data_source.h
+++ b/chromium/media/filters/file_data_source.h
@@ -7,8 +7,6 @@
#include <stdint.h>
-#include <string>
-
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/memory_mapped_file.h"
diff --git a/chromium/media/filters/frame_buffer_pool.cc b/chromium/media/filters/frame_buffer_pool.cc
index c6aa7d03b4a..e3978b47284 100644
--- a/chromium/media/filters/frame_buffer_pool.cc
+++ b/chromium/media/filters/frame_buffer_pool.cc
@@ -9,6 +9,8 @@
#include "base/check_op.h"
#include "base/location.h"
#include "base/macros.h"
+#include "base/memory/free_deleter.h"
+#include "base/process/memory.h"
#include "base/sequenced_task_runner.h"
#include "base/stl_util.h"
#include "base/threading/sequenced_task_runner_handle.h"
@@ -21,9 +23,9 @@ namespace media {
struct FrameBufferPool::FrameBuffer {
// Not using std::vector<uint8_t> as resize() calls take a really long time
// for large buffers.
- std::unique_ptr<uint8_t[]> data;
+ std::unique_ptr<uint8_t, base::FreeDeleter> data;
size_t data_size = 0u;
- std::unique_ptr<uint8_t[]> alpha_data;
+ std::unique_ptr<uint8_t, base::FreeDeleter> alpha_data;
size_t alpha_data_size = 0u;
bool held_by_library = false;
// Needs to be a counter since a frame buffer might be used multiple times.
@@ -71,7 +73,16 @@ uint8_t* FrameBufferPool::GetFrameBuffer(size_t min_size, void** fb_priv) {
// Free the existing |data| first so that the memory can be reused,
// if possible. Note that the new array is purposely not initialized.
frame_buffer->data.reset();
- frame_buffer->data.reset(new uint8_t[min_size]);
+
+ uint8_t* data = nullptr;
+ if (force_allocation_error_ ||
+ !base::UncheckedMalloc(min_size, reinterpret_cast<void**>(&data)) ||
+ !data) {
+ frame_buffers_.erase(it);
+ return nullptr;
+ }
+
+ frame_buffer->data.reset(data);
frame_buffer->data_size = min_size;
}
@@ -102,7 +113,13 @@ uint8_t* FrameBufferPool::AllocateAlphaPlaneForFrameBuffer(size_t min_size,
// Free the existing |alpha_data| first so that the memory can be reused,
// if possible. Note that the new array is purposely not initialized.
frame_buffer->alpha_data.reset();
- frame_buffer->alpha_data.reset(new uint8_t[min_size]);
+ uint8_t* data = nullptr;
+ if (force_allocation_error_ ||
+ !base::UncheckedMalloc(min_size, reinterpret_cast<void**>(&data)) ||
+ !data) {
+ return nullptr;
+ }
+ frame_buffer->alpha_data.reset(data);
frame_buffer->alpha_data_size = min_size;
}
return frame_buffer->alpha_data.get();
diff --git a/chromium/media/filters/frame_buffer_pool.h b/chromium/media/filters/frame_buffer_pool.h
index 9dddec6fb5d..d96132ed6c3 100644
--- a/chromium/media/filters/frame_buffer_pool.h
+++ b/chromium/media/filters/frame_buffer_pool.h
@@ -14,7 +14,6 @@
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
#include "base/time/default_tick_clock.h"
-#include "base/time/time.h"
#include "base/trace_event/memory_dump_provider.h"
#include "media/base/media_export.h"
@@ -55,6 +54,8 @@ class MEDIA_EXPORT FrameBufferPool
tick_clock_ = tick_clock;
}
+ void force_allocation_error_for_testing() { force_allocation_error_ = true; }
+
// Called when no more GetFrameBuffer() calls are expected. All unused memory
// is released at this time. As frames are returned their memory is released.
// This should not be called until anything that might call GetFrameBuffer()
@@ -92,6 +93,8 @@ class MEDIA_EXPORT FrameBufferPool
bool registered_dump_provider_ = false;
+ bool force_allocation_error_ = false;
+
// |tick_clock_| is always a DefaultTickClock outside of testing.
const base::TickClock* tick_clock_;
diff --git a/chromium/media/filters/frame_buffer_pool_unittest.cc b/chromium/media/filters/frame_buffer_pool_unittest.cc
index 8644ce37092..0cdf4d040b0 100644
--- a/chromium/media/filters/frame_buffer_pool_unittest.cc
+++ b/chromium/media/filters/frame_buffer_pool_unittest.cc
@@ -57,6 +57,18 @@ TEST(FrameBufferPool, BasicFunctionality) {
EXPECT_EQ(0u, pool->get_pool_size_for_testing());
}
+TEST(FrameBufferPool, ForceAllocationError) {
+ base::TestMessageLoop message_loop;
+ scoped_refptr<FrameBufferPool> pool = new FrameBufferPool();
+ pool->force_allocation_error_for_testing();
+
+ void* priv1 = nullptr;
+ uint8_t* buf1 = pool->GetFrameBuffer(kBufferSize, &priv1);
+ ASSERT_FALSE(priv1);
+ ASSERT_FALSE(buf1);
+ pool->Shutdown();
+}
+
TEST(FrameBufferPool, DeferredDestruction) {
base::TestMessageLoop message_loop;
scoped_refptr<FrameBufferPool> pool = new FrameBufferPool();
diff --git a/chromium/media/filters/fuchsia/DIR_METADATA b/chromium/media/filters/fuchsia/DIR_METADATA
index e88f62328ca..abc57ac0fd5 100644
--- a/chromium/media/filters/fuchsia/DIR_METADATA
+++ b/chromium/media/filters/fuchsia/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
team_email: "cr-fuchsia@chromium.org"
os: FUCHSIA \ No newline at end of file
diff --git a/chromium/media/filters/fuchsia/OWNERS b/chromium/media/filters/fuchsia/OWNERS
index 3ebcc4268bd..e7034eabb1e 100644
--- a/chromium/media/filters/fuchsia/OWNERS
+++ b/chromium/media/filters/fuchsia/OWNERS
@@ -1 +1 @@
-file://build/fuchsia/OWNERS \ No newline at end of file
+file://build/fuchsia/OWNERS
diff --git a/chromium/media/filters/fuchsia/fuchsia_video_decoder.cc b/chromium/media/filters/fuchsia/fuchsia_video_decoder.cc
index fe5075e3d8e..d84c36aa7e9 100644
--- a/chromium/media/filters/fuchsia/fuchsia_video_decoder.cc
+++ b/chromium/media/filters/fuchsia/fuchsia_video_decoder.cc
@@ -6,10 +6,8 @@
#include <fuchsia/media/cpp/fidl.h>
#include <fuchsia/mediacodec/cpp/fidl.h>
-#include <fuchsia/sysmem/cpp/fidl.h>
#include <lib/sys/cpp/component_context.h>
#include <vulkan/vulkan.h>
-#include <zircon/rights.h>
#include "base/bind.h"
#include "base/bits.h"
@@ -31,7 +29,6 @@
#include "gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/cdm_context.h"
-#include "media/base/decryptor.h"
#include "media/base/media_switches.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
@@ -40,9 +37,10 @@
#include "media/fuchsia/cdm/fuchsia_cdm_context.h"
#include "media/fuchsia/cdm/fuchsia_decryptor.h"
#include "media/fuchsia/cdm/fuchsia_stream_decryptor.h"
+#include "media/fuchsia/common/decrypting_sysmem_buffer_stream.h"
+#include "media/fuchsia/common/passthrough_sysmem_buffer_stream.h"
#include "media/fuchsia/common/stream_processor_helper.h"
-#include "media/fuchsia/common/sysmem_buffer_pool.h"
-#include "media/fuchsia/common/sysmem_buffer_writer_queue.h"
+#include "media/fuchsia/common/sysmem_client.h"
#include "third_party/libyuv/include/libyuv/video_common.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/client_native_pixmap_factory.h"
@@ -55,24 +53,26 @@ namespace {
// Number of output buffers allocated "for camping". This value is passed to
// sysmem to ensure that we get one output buffer for the frame currently
// displayed on the screen.
-const uint32_t kOutputBuffersForCamping = 1;
+constexpr uint32_t kOutputBuffersForCamping = 1;
// Maximum number of frames we expect to have queued up while playing video.
// Higher values require more memory for output buffers. Lower values make it
// more likely that renderer will stall because decoded frames are not available
// on time.
-const uint32_t kMaxUsedOutputBuffers = 5;
+constexpr uint32_t kMaxUsedOutputBuffers = 5;
-// Use 2 buffers for decoder input. Limiting total number of buffers to 2 allows
-// to minimize required memory without significant effect on performance.
-const size_t kNumInputBuffers = 2;
+// Use 2 buffers for decoder input. Allocating more than one buffers ensures
+// that when the decoder is done working on one packet it will have another one
+// waiting in the queue. Limiting number of buffers to 2 allows to minimize
+// required memory, without significant effect on performance.
+constexpr size_t kNumInputBuffers = 2;
// Some codecs do not support splitting video frames across multiple input
// buffers, so the buffers need to be large enough to fit all video frames. The
-// buffer size is calculated to fit 1080p frame with MinCR=2 (per H264 spec),
-// plus 128KiB for SEI/SPS/PPS. (note that the same size is used for all codecs,
-// not just H264).
-const size_t kInputBufferSize = 1920 * 1080 * 3 / 2 / 2 + 128 * 1024;
+// buffer size is calculated to fit 1080p I420 frame with MinCR=2 (per H264
+// spec), plus 128KiB for SEI/SPS/PPS. (note that the same size is used for all
+// codecs, not just H264).
+constexpr size_t kInputBufferSize = 1920 * 1080 * 3 / 2 / 2 + 128 * 1024;
// Helper used to hold mailboxes for the output textures. OutputMailbox may
// outlive FuchsiaVideoDecoder if is referenced by a VideoFrame.
@@ -82,10 +82,9 @@ class OutputMailbox {
scoped_refptr<viz::RasterContextProvider> raster_context_provider,
std::unique_ptr<gfx::GpuMemoryBuffer> gmb)
: raster_context_provider_(raster_context_provider), weak_factory_(this) {
- uint32_t usage = gpu::SHARED_IMAGE_USAGE_RASTER |
- gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION |
- gpu::SHARED_IMAGE_USAGE_DISPLAY |
- gpu::SHARED_IMAGE_USAGE_SCANOUT;
+ uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY |
+ gpu::SHARED_IMAGE_USAGE_SCANOUT |
+ gpu::SHARED_IMAGE_USAGE_VIDEO_DECODE;
mailbox_ =
raster_context_provider_->SharedImageInterface()->CreateSharedImage(
gmb.get(), nullptr, gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin,
@@ -186,13 +185,17 @@ struct InputDecoderPacket {
} // namespace
class FuchsiaVideoDecoder : public VideoDecoder,
- public FuchsiaSecureStreamDecryptor::Client {
+ public SysmemBufferStream::Sink,
+ public StreamProcessorHelper::Client {
public:
FuchsiaVideoDecoder(
scoped_refptr<viz::RasterContextProvider> raster_context_provider,
bool enable_sw_decoding);
~FuchsiaVideoDecoder() override;
+ FuchsiaVideoDecoder(const FuchsiaVideoDecoder&) = delete;
+ FuchsiaVideoDecoder& operator=(const FuchsiaVideoDecoder&) = delete;
+
// Decoder implementation.
bool IsPlatformDecoder() const override;
bool SupportsDecryption() const override;
@@ -212,29 +215,33 @@ class FuchsiaVideoDecoder : public VideoDecoder,
int GetMaxDecodeRequests() const override;
private:
- bool InitializeDecryptor(CdmContext* cdm_context);
-
- // FuchsiaSecureStreamDecryptor::Client implementation.
- size_t GetInputBufferSize() override;
- void OnDecryptorOutputPacket(StreamProcessorHelper::IoPacket packet) override;
- void OnDecryptorEndOfStreamPacket() override;
- void OnDecryptorError() override;
- void OnDecryptorNoKey() override;
-
- // Event handlers for |decoder_|.
- void OnStreamFailed(uint64_t stream_lifetime_ordinal,
- fuchsia::media::StreamError error);
- void OnInputConstraints(
- fuchsia::media::StreamBufferConstraints input_constraints);
- void OnFreeInputPacket(fuchsia::media::PacketHeader free_input_packet);
- void OnOutputConstraints(
- fuchsia::media::StreamOutputConstraints output_constraints);
- void OnOutputFormat(fuchsia::media::StreamOutputFormat output_format);
- void OnOutputPacket(fuchsia::media::Packet output_packet,
- bool error_detected_before,
- bool error_detected_during);
- void OnOutputEndOfStream(uint64_t stream_lifetime_ordinal,
- bool error_detected_before);
+ StatusCode InitializeSysmemBufferStream(bool is_encrypted,
+ CdmContext* cdm_context,
+ bool* secure_mode);
+
+ // SysmemBufferStream::Sink implementation.
+ void OnSysmemBufferStreamBufferCollectionToken(
+ fuchsia::sysmem::BufferCollectionTokenPtr token) override;
+ void OnSysmemBufferStreamOutputPacket(
+ StreamProcessorHelper::IoPacket packet) override;
+ void OnSysmemBufferStreamEndOfStream() override;
+ void OnSysmemBufferStreamError() override;
+ void OnSysmemBufferStreamNoKey() override;
+
+ // StreamProcessorHelper::Client implementation.
+ void OnStreamProcessorAllocateOutputBuffers(
+ const fuchsia::media::StreamBufferConstraints& stream_constraints)
+ override;
+ void OnStreamProcessorEndOfStream() override;
+ void OnStreamProcessorOutputFormat(
+ fuchsia::media::StreamOutputFormat format) override;
+ void OnStreamProcessorOutputPacket(
+ StreamProcessorHelper::IoPacket packet) override;
+ void OnStreamProcessorNoKey() override;
+ void OnStreamProcessorError() override;
+
+ // Calls next callback in the |decode_callbacks_| queue.
+ void CallNextDecodeCallback();
// Drops all pending input buffers and then calls all pending DecodeCB with
// |status|. Returns true if the decoder still exists.
@@ -243,29 +250,15 @@ class FuchsiaVideoDecoder : public VideoDecoder,
// Called on errors to shutdown the decoder and notify the client.
void OnError();
- // Callback for |input_buffer_collection_creator_->Create()|.
- void OnInputBufferPoolCreated(std::unique_ptr<SysmemBufferPool> pool);
-
- // Callback for |input_buffer_collection_->CreateWriter()|.
- void OnWriterCreated(std::unique_ptr<SysmemBufferWriter> writer);
-
- // Callbacks for |input_writer_|.
- void SendInputPacket(const DecoderBuffer* buffer,
- StreamProcessorHelper::IoPacket packet);
- void ProcessEndOfStream();
+ // Callback for SysmemBufferCollection::CreateSharedToken(), used to send the
+ // sysmem buffer collection token to the GPU process.
+ void SetBufferCollectionTokenForGpu(
+ fuchsia::sysmem::BufferCollectionTokenPtr token);
- // Called by OnOutputConstraints() to initialize input buffers.
- void InitializeOutputBufferCollection(
- fuchsia::media::StreamBufferConstraints constraints,
- fuchsia::sysmem::BufferCollectionTokenPtr collection_token_for_codec,
- fuchsia::sysmem::BufferCollectionTokenPtr collection_token_for_gpu);
+ // Called by OutputMailbox to signal that the output buffer can be reused.
+ void ReleaseOutputPacket(StreamProcessorHelper::IoPacket packet);
- // Called by OutputMailbox to signal that the mailbox and buffer can be
- // reused.
- void OnReuseMailbox(uint32_t buffer_index, uint32_t packet_index);
-
- // Releases BufferCollections used for input or output buffers if any.
- void ReleaseInputBuffers();
+ // Releases BufferCollection used for output buffers if any.
void ReleaseOutputBuffers();
const scoped_refptr<viz::RasterContextProvider> raster_context_provider_;
@@ -279,52 +272,39 @@ class FuchsiaVideoDecoder : public VideoDecoder,
// value is used only if the aspect ratio is not specified in the bitstream.
float container_pixel_aspect_ratio_ = 1.0;
- // Decryptor is allocated only for encrypted streams.
- std::unique_ptr<FuchsiaSecureStreamDecryptor> decryptor_;
+ std::unique_ptr<SysmemBufferStream> sysmem_buffer_stream_;
- VideoCodec current_codec_ = kUnknownVideoCodec;
+ size_t max_decoder_requests_ = kNumInputBuffers + 1;
- // TODO(crbug.com/1131175): Use StreamProcessorHelper.
- fuchsia::media::StreamProcessorPtr decoder_;
+ VideoDecoderConfig current_config_;
- base::Optional<fuchsia::media::StreamBufferConstraints>
- decoder_input_constraints_;
+ std::unique_ptr<StreamProcessorHelper> decoder_;
- BufferAllocator sysmem_allocator_;
+ SysmemAllocatorClient sysmem_allocator_;
std::unique_ptr<gfx::ClientNativePixmapFactory> client_native_pixmap_factory_;
- uint64_t stream_lifetime_ordinal_ = 1;
-
- // Set to true if we've sent an input packet with the current
- // stream_lifetime_ordinal_.
- bool active_stream_ = false;
-
// Callbacks for pending Decode() request.
std::deque<DecodeCB> decode_callbacks_;
- // Buffer queue for |decoder_|. Used only for clear streams, i.e. when there
- // is no |decryptor_|.
- SysmemBufferWriterQueue input_writer_queue_;
-
// Input buffers for |decoder_|.
- uint64_t input_buffer_lifetime_ordinal_ = 1;
- std::unique_ptr<SysmemBufferPool::Creator> input_buffer_collection_creator_;
- std::unique_ptr<SysmemBufferPool> input_buffer_collection_;
- base::flat_map<size_t, InputDecoderPacket> in_flight_input_packets_;
+ std::unique_ptr<SysmemCollectionClient> input_buffer_collection_;
// Output buffers for |decoder_|.
fuchsia::media::VideoUncompressedFormat output_format_;
- uint64_t output_buffer_lifetime_ordinal_ = 1;
- fuchsia::sysmem::BufferCollectionPtr output_buffer_collection_;
+ std::unique_ptr<SysmemCollectionClient> output_buffer_collection_;
gfx::SysmemBufferCollectionId output_buffer_collection_id_;
std::vector<OutputMailbox*> output_mailboxes_;
size_t num_used_output_buffers_ = 0;
base::WeakPtr<FuchsiaVideoDecoder> weak_this_;
- base::WeakPtrFactory<FuchsiaVideoDecoder> weak_factory_;
+ base::WeakPtrFactory<FuchsiaVideoDecoder> weak_factory_{this};
- DISALLOW_COPY_AND_ASSIGN(FuchsiaVideoDecoder);
+ // WeakPtrFactory used to schedule CallNextDecodeCallbacks(). These pointers
+ // are discarded in DropInputQueue() in order to avoid calling
+ // Decode() callback when the decoder queue is discarded.
+ base::WeakPtrFactory<FuchsiaVideoDecoder> decode_callbacks_weak_factory_{
+ this};
};
FuchsiaVideoDecoder::FuchsiaVideoDecoder(
@@ -335,16 +315,17 @@ FuchsiaVideoDecoder::FuchsiaVideoDecoder(
use_overlays_for_video_(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseOverlaysForVideo)),
sysmem_allocator_("CrFuchsiaVideoDecoder"),
- client_native_pixmap_factory_(ui::CreateClientNativePixmapFactoryOzone()),
- weak_factory_(this) {
+ client_native_pixmap_factory_(
+ ui::CreateClientNativePixmapFactoryOzone()) {
DCHECK(raster_context_provider_);
weak_this_ = weak_factory_.GetWeakPtr();
}
FuchsiaVideoDecoder::~FuchsiaVideoDecoder() {
- // Call ReleaseInputBuffers() to make sure the corresponding fields are
- // destroyed in the right order.
- ReleaseInputBuffers();
+ // Reset SysmemBufferStream to ensure it doesn't try to send new packets when
+ // the |decoder_| is destroyed.
+ sysmem_buffer_stream_.reset();
+ decoder_.reset();
// Release mailboxes used for output frames.
ReleaseOutputBuffers();
@@ -384,25 +365,25 @@ void FuchsiaVideoDecoder::Initialize(const VideoDecoderConfig& config,
container_pixel_aspect_ratio_ = config.GetPixelAspectRatio();
// Keep decoder and decryptor if the configuration hasn't changed.
- bool have_decryptor = decryptor_ != nullptr;
- if (decoder_ && current_codec_ == config.codec() &&
- have_decryptor == config.is_encrypted()) {
+ if (decoder_ && current_config_.is_encrypted() == config.codec() &&
+ current_config_.is_encrypted() == config.is_encrypted()) {
std::move(done_callback).Run(OkStatus());
return;
}
- decryptor_.reset();
- decoder_.Unbind();
+ sysmem_buffer_stream_.reset();
+ decoder_.reset();
- // Initialize decryptor for encrypted streams.
- if (config.is_encrypted() && !InitializeDecryptor(cdm_context)) {
- std::move(done_callback)
- .Run(StatusCode::kDecoderMissingCdmForEncryptedContent);
+ // Initialize the stream.
+ bool secure_mode = false;
+ StatusCode status = InitializeSysmemBufferStream(config.is_encrypted(),
+ cdm_context, &secure_mode);
+ if (status != StatusCode::kOk) {
+ std::move(done_callback).Run(StatusCode::kOk);
return;
}
- // Reset IO buffers since we won't be able to re-use them.
- ReleaseInputBuffers();
+ // Reset output buffers since we won't be able to re-use them.
ReleaseOutputBuffers();
fuchsia::mediacodec::CreateDecoder_Params decoder_params;
@@ -430,18 +411,15 @@ void FuchsiaVideoDecoder::Initialize(const VideoDecoderConfig& config,
return;
}
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableProtectedVideoBuffers)) {
- if (decryptor_) {
- decoder_params.set_secure_input_mode(
- fuchsia::mediacodec::SecureMemoryMode::ON);
- }
+ if (secure_mode) {
+ decoder_params.set_secure_input_mode(
+ fuchsia::mediacodec::SecureMemoryMode::ON);
+ }
- if (decryptor_ || base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kForceProtectedVideoOutputBuffers)) {
- decoder_params.set_secure_output_mode(
- fuchsia::mediacodec::SecureMemoryMode::ON);
- }
+ if (secure_mode || base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kForceProtectedVideoOutputBuffers)) {
+ decoder_params.set_secure_output_mode(
+ fuchsia::mediacodec::SecureMemoryMode::ON);
}
decoder_params.set_promise_separate_access_units_on_input(true);
@@ -450,32 +428,12 @@ void FuchsiaVideoDecoder::Initialize(const VideoDecoderConfig& config,
auto decoder_factory = base::ComponentContextForProcess()
->svc()
->Connect<fuchsia::mediacodec::CodecFactory>();
+ fuchsia::media::StreamProcessorPtr decoder;
decoder_factory->CreateDecoder(std::move(decoder_params),
- decoder_.NewRequest());
+ decoder.NewRequest());
+ decoder_ = std::make_unique<StreamProcessorHelper>(std::move(decoder), this);
- decoder_.set_error_handler([this](zx_status_t status) {
- ZX_LOG(ERROR, status) << "fuchsia.media.StreamProcessor disconnected.";
- OnError();
- });
-
- decoder_.events().OnStreamFailed =
- fit::bind_member(this, &FuchsiaVideoDecoder::OnStreamFailed);
- decoder_.events().OnInputConstraints =
- fit::bind_member(this, &FuchsiaVideoDecoder::OnInputConstraints);
- decoder_.events().OnFreeInputPacket =
- fit::bind_member(this, &FuchsiaVideoDecoder::OnFreeInputPacket);
- decoder_.events().OnOutputConstraints =
- fit::bind_member(this, &FuchsiaVideoDecoder::OnOutputConstraints);
- decoder_.events().OnOutputFormat =
- fit::bind_member(this, &FuchsiaVideoDecoder::OnOutputFormat);
- decoder_.events().OnOutputPacket =
- fit::bind_member(this, &FuchsiaVideoDecoder::OnOutputPacket);
- decoder_.events().OnOutputEndOfStream =
- fit::bind_member(this, &FuchsiaVideoDecoder::OnOutputEndOfStream);
-
- decoder_->EnableOnStreamFailed();
-
- current_codec_ = config.codec();
+ current_config_ = config;
std::move(done_callback).Run(OkStatus());
}
@@ -493,11 +451,7 @@ void FuchsiaVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
decode_callbacks_.push_back(std::move(decode_cb));
- if (decryptor_) {
- decryptor_->Decrypt(std::move(buffer));
- } else {
- input_writer_queue_.EnqueueBuffer(buffer);
- }
+ sysmem_buffer_stream_->EnqueueBuffer(std::move(buffer));
}
void FuchsiaVideoDecoder::Reset(base::OnceClosure closure) {
@@ -515,305 +469,113 @@ bool FuchsiaVideoDecoder::CanReadWithoutStalling() const {
}
int FuchsiaVideoDecoder::GetMaxDecodeRequests() const {
- if (!decryptor_) {
- // Add one extra request to be able to send a new InputBuffer immediately
- // after OnFreeInputPacket().
- return input_writer_queue_.num_buffers() + 1;
- }
-
- // For encrypted streams we need enough decode requests to fill the
- // decryptor's queue and all decoder buffers. Add one extra same as above.
- return decryptor_->GetMaxDecryptRequests() + kNumInputBuffers + 1;
+ return max_decoder_requests_;
}
-bool FuchsiaVideoDecoder::InitializeDecryptor(CdmContext* cdm_context) {
- DCHECK(!decryptor_);
+StatusCode FuchsiaVideoDecoder::InitializeSysmemBufferStream(
+ bool is_encrypted,
+ CdmContext* cdm_context,
+ bool* out_secure_mode) {
+ DCHECK(!sysmem_buffer_stream_);
- // Caller makes sure |cdm_context| is available if the stream is encrypted.
- if (!cdm_context) {
- DLOG(ERROR) << "No cdm context for encrypted stream.";
- return false;
- }
+ *out_secure_mode = false;
+
+ // By default queue as many decode requests as the input buffers available
+ // with one extra request to be able to send a new InputBuffer immediately.
+ max_decoder_requests_ = kNumInputBuffers + 1;
- // If Cdm is not FuchsiaCdm then fail initialization to allow decoder
- // selector to choose DecryptingDemuxerStream, which will handle the
- // decryption and pass the clear stream to this decoder.
- FuchsiaCdmContext* fuchsia_cdm = cdm_context->GetFuchsiaCdmContext();
- if (!fuchsia_cdm) {
- DLOG(ERROR) << "FuchsiaVideoDecoder is compatible only with Fuchsia CDM.";
- return false;
+ if (is_encrypted) {
+ // Caller makes sure |cdm_context| is available if the stream is encrypted.
+ if (!cdm_context) {
+ DLOG(ERROR) << "No cdm context for encrypted stream.";
+ return StatusCode::kDecoderMissingCdmForEncryptedContent;
+ }
+
+ // Use FuchsiaStreamDecryptor with FuchsiaCdm (it doesn't support
+ // media::Decryptor interface). Otherwise (e.g. for ClearKey CDM) use
+ // DecryptingSysmemBufferStream.
+ FuchsiaCdmContext* fuchsia_cdm = cdm_context->GetFuchsiaCdmContext();
+ if (fuchsia_cdm) {
+ *out_secure_mode = base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableProtectedVideoBuffers);
+ sysmem_buffer_stream_ =
+ fuchsia_cdm->CreateStreamDecryptor(*out_secure_mode);
+
+ // For optimal performance allow more requests to fill the decryptor
+ // queue.
+ max_decoder_requests_ += FuchsiaStreamDecryptor::kInputBufferCount;
+ } else {
+ sysmem_buffer_stream_ = std::make_unique<DecryptingSysmemBufferStream>(
+ &sysmem_allocator_, cdm_context, Decryptor::kVideo);
+ }
+ } else {
+ sysmem_buffer_stream_ =
+ std::make_unique<PassthroughSysmemBufferStream>(&sysmem_allocator_);
}
- decryptor_ = fuchsia_cdm->CreateVideoDecryptor(this);
+ sysmem_buffer_stream_->Initialize(this, kInputBufferSize, kNumInputBuffers);
- return true;
+ return StatusCode::kOk;
}
-size_t FuchsiaVideoDecoder::GetInputBufferSize() {
- return kInputBufferSize;
+void FuchsiaVideoDecoder::OnSysmemBufferStreamBufferCollectionToken(
+ fuchsia::sysmem::BufferCollectionTokenPtr token) {
+ DCHECK(decoder_);
+ decoder_->SetInputBufferCollectionToken(std::move(token));
}
-void FuchsiaVideoDecoder::OnDecryptorOutputPacket(
+void FuchsiaVideoDecoder::OnSysmemBufferStreamOutputPacket(
StreamProcessorHelper::IoPacket packet) {
- SendInputPacket(nullptr, std::move(packet));
+ packet.AddOnDestroyClosure(
+ base::BindOnce(&FuchsiaVideoDecoder::CallNextDecodeCallback,
+ decode_callbacks_weak_factory_.GetWeakPtr()));
+ decoder_->Process(std::move(packet));
}
-void FuchsiaVideoDecoder::OnDecryptorEndOfStreamPacket() {
- ProcessEndOfStream();
+void FuchsiaVideoDecoder::OnSysmemBufferStreamEndOfStream() {
+ decoder_->ProcessEos();
}
-void FuchsiaVideoDecoder::OnDecryptorError() {
+void FuchsiaVideoDecoder::OnSysmemBufferStreamError() {
OnError();
}
-void FuchsiaVideoDecoder::OnDecryptorNoKey() {
+void FuchsiaVideoDecoder::OnSysmemBufferStreamNoKey() {
waiting_cb_.Run(WaitingReason::kNoDecryptionKey);
}
-void FuchsiaVideoDecoder::OnStreamFailed(uint64_t stream_lifetime_ordinal,
- fuchsia::media::StreamError error) {
- if (stream_lifetime_ordinal_ != stream_lifetime_ordinal) {
- return;
- }
-
- OnError();
-}
+void FuchsiaVideoDecoder::OnStreamProcessorAllocateOutputBuffers(
+ const fuchsia::media::StreamBufferConstraints& output_constraints) {
+ ReleaseOutputBuffers();
-void FuchsiaVideoDecoder::OnInputConstraints(
- fuchsia::media::StreamBufferConstraints stream_constraints) {
- // Buffer lifetime ordinal is an odd number incremented by 2 for each buffer
- // generation as required by StreamProcessor.
- input_buffer_lifetime_ordinal_ += 2;
- decoder_input_constraints_ = std::move(stream_constraints);
+ output_buffer_collection_ = sysmem_allocator_.AllocateNewCollection();
- ReleaseInputBuffers();
+ output_buffer_collection_->CreateSharedToken(
+ base::BindOnce(&StreamProcessorHelper::CompleteOutputBuffersAllocation,
+ base::Unretained(decoder_.get())),
+ "codec");
+ output_buffer_collection_->CreateSharedToken(
+ base::BindOnce(&FuchsiaVideoDecoder::SetBufferCollectionTokenForGpu,
+ base::Unretained(this)),
+ "gpu");
- // Create buffer constrains for the input buffer collection.
- size_t num_tokens;
fuchsia::sysmem::BufferCollectionConstraints buffer_constraints;
-
- if (decryptor_) {
- // For encrypted streams the sysmem buffer collection is used for decryptor
- // output and decoder input. It is not used directly.
- num_tokens = 2;
- buffer_constraints.usage.none = fuchsia::sysmem::noneUsage;
- buffer_constraints.min_buffer_count = kNumInputBuffers;
- buffer_constraints.has_buffer_memory_constraints = true;
- buffer_constraints.buffer_memory_constraints.min_size_bytes =
- kInputBufferSize;
- buffer_constraints.buffer_memory_constraints.ram_domain_supported = true;
- buffer_constraints.buffer_memory_constraints.cpu_domain_supported = true;
- buffer_constraints.buffer_memory_constraints.inaccessible_domain_supported =
- true;
- } else {
- num_tokens = 1;
- auto writer_constraints = SysmemBufferWriter::GetRecommendedConstraints(
- kNumInputBuffers, kInputBufferSize);
- if (!writer_constraints.has_value()) {
- OnError();
- return;
- }
- buffer_constraints = std::move(writer_constraints).value();
- }
-
- input_buffer_collection_creator_ =
- sysmem_allocator_.MakeBufferPoolCreator(num_tokens);
- input_buffer_collection_creator_->Create(
- std::move(buffer_constraints),
- base::BindOnce(&FuchsiaVideoDecoder::OnInputBufferPoolCreated,
- base::Unretained(this)));
-}
-
-void FuchsiaVideoDecoder::OnInputBufferPoolCreated(
- std::unique_ptr<SysmemBufferPool> pool) {
- if (!pool) {
- DLOG(ERROR) << "Fail to allocate input buffers for the codec.";
- OnError();
- return;
- }
-
- input_buffer_collection_ = std::move(pool);
-
- fuchsia::media::StreamBufferPartialSettings settings;
- settings.set_buffer_lifetime_ordinal(input_buffer_lifetime_ordinal_);
- settings.set_buffer_constraints_version_ordinal(
- decoder_input_constraints_->buffer_constraints_version_ordinal());
- settings.set_sysmem_token(input_buffer_collection_->TakeToken());
- decoder_->SetInputBufferPartialSettings(std::move(settings));
-
- if (decryptor_) {
- decryptor_->SetOutputBufferCollectionToken(
- input_buffer_collection_->TakeToken());
- } else {
- input_buffer_collection_->CreateWriter(base::BindOnce(
- &FuchsiaVideoDecoder::OnWriterCreated, base::Unretained(this)));
- }
-}
-
-void FuchsiaVideoDecoder::OnWriterCreated(
- std::unique_ptr<SysmemBufferWriter> writer) {
- if (!writer) {
- OnError();
- return;
- }
-
- input_writer_queue_.Start(
- std::move(writer),
- base::BindRepeating(&FuchsiaVideoDecoder::SendInputPacket,
- base::Unretained(this)),
- base::BindRepeating(&FuchsiaVideoDecoder::ProcessEndOfStream,
- base::Unretained(this)));
-}
-
-void FuchsiaVideoDecoder::SendInputPacket(
- const DecoderBuffer* buffer,
- StreamProcessorHelper::IoPacket packet) {
- fuchsia::media::Packet media_packet;
- media_packet.mutable_header()->set_buffer_lifetime_ordinal(
- input_buffer_lifetime_ordinal_);
- media_packet.mutable_header()->set_packet_index(packet.buffer_index());
- media_packet.set_buffer_index(packet.buffer_index());
- media_packet.set_timestamp_ish(packet.timestamp().InNanoseconds());
- media_packet.set_stream_lifetime_ordinal(stream_lifetime_ordinal_);
- media_packet.set_start_offset(packet.offset());
- media_packet.set_valid_length_bytes(packet.size());
- media_packet.set_known_end_access_unit(packet.unit_end());
- decoder_->QueueInputPacket(std::move(media_packet));
-
- active_stream_ = true;
-
- DCHECK(in_flight_input_packets_.find(packet.buffer_index()) ==
- in_flight_input_packets_.end());
- const size_t buffer_index = packet.buffer_index();
- in_flight_input_packets_.insert_or_assign(
- buffer_index, InputDecoderPacket{std::move(packet)});
-}
-
-void FuchsiaVideoDecoder::ProcessEndOfStream() {
- active_stream_ = true;
- decoder_->QueueInputEndOfStream(stream_lifetime_ordinal_);
- decoder_->FlushEndOfStreamAndCloseStream(stream_lifetime_ordinal_);
-}
-
-void FuchsiaVideoDecoder::OnFreeInputPacket(
- fuchsia::media::PacketHeader free_input_packet) {
- if (!free_input_packet.has_buffer_lifetime_ordinal() ||
- !free_input_packet.has_packet_index()) {
- DLOG(ERROR) << "Received OnFreeInputPacket() with missing required fields.";
- OnError();
- return;
- }
-
- if (free_input_packet.buffer_lifetime_ordinal() !=
- input_buffer_lifetime_ordinal_) {
- return;
- }
-
- auto it = in_flight_input_packets_.find(free_input_packet.packet_index());
- if (it == in_flight_input_packets_.end()) {
- DLOG(ERROR) << "Received OnFreeInputPacket() with invalid packet index.";
- OnError();
- return;
- }
-
- // Call DecodeCB if this was a last packet for a Decode() request. Ignore
- // packets from a previous stream.
- bool call_decode_callback =
- it->second.packet.unit_end() && it->second.used_for_current_stream;
-
- {
- // The packet should be destroyed only after it's removed from
- // |in_flight_input_packets_|. Otherwise SysmemBufferWriter may call
- // SendInputPacket() while the packet is still in
- // |in_flight_input_packets_|.
- auto packet = std::move(it->second.packet);
- in_flight_input_packets_.erase(it);
- }
-
- if (call_decode_callback) {
- DCHECK(!decode_callbacks_.empty());
- std::move(decode_callbacks_.front()).Run(DecodeStatus::OK);
- decode_callbacks_.pop_front();
- }
+ buffer_constraints.usage.none = fuchsia::sysmem::noneUsage;
+ buffer_constraints.min_buffer_count_for_camping = kOutputBuffersForCamping;
+ buffer_constraints.min_buffer_count_for_shared_slack =
+ kMaxUsedOutputBuffers - kOutputBuffersForCamping;
+ output_buffer_collection_->Initialize(std::move(buffer_constraints),
+ "ChromiumVideoDecoderOutput");
}
-void FuchsiaVideoDecoder::OnOutputConstraints(
- fuchsia::media::StreamOutputConstraints output_constraints) {
- if (!output_constraints.has_stream_lifetime_ordinal()) {
- DLOG(ERROR)
- << "Received OnOutputConstraints() with missing required fields.";
- OnError();
- return;
- }
-
- if (output_constraints.stream_lifetime_ordinal() !=
- stream_lifetime_ordinal_) {
- return;
- }
-
- if (!output_constraints.has_buffer_constraints_action_required() ||
- !output_constraints.buffer_constraints_action_required()) {
- return;
- }
-
- ReleaseOutputBuffers();
-
- // mediacodec API expects odd buffer lifetime ordinal, which is incremented by
- // 2 for each buffer generation.
- output_buffer_lifetime_ordinal_ += 2;
-
- // Create a new sysmem buffer collection token for the output buffers.
- fuchsia::sysmem::BufferCollectionTokenPtr collection_token;
- sysmem_allocator_.raw()->AllocateSharedCollection(
- collection_token.NewRequest());
- collection_token->SetName(100u, "ChromiumVideoDecoderOutput");
- collection_token->SetDebugClientInfo("chromium_video_decoder", 0u);
-
- // Create sysmem tokens for the gpu process and the codec.
- fuchsia::sysmem::BufferCollectionTokenPtr collection_token_for_codec;
- collection_token->Duplicate(ZX_RIGHT_SAME_RIGHTS,
- collection_token_for_codec.NewRequest());
- collection_token_for_codec->SetDebugClientInfo("codec", 0u);
- fuchsia::sysmem::BufferCollectionTokenPtr collection_token_for_gpu;
- collection_token->Duplicate(ZX_RIGHT_SAME_RIGHTS,
- collection_token_for_gpu.NewRequest());
- collection_token_for_gpu->SetDebugClientInfo("chromium_gpu", 0u);
-
- // Convert the token to a BufferCollection connection.
- sysmem_allocator_.raw()->BindSharedCollection(
- std::move(collection_token), output_buffer_collection_.NewRequest());
- output_buffer_collection_.set_error_handler([this](zx_status_t status) {
- ZX_LOG(ERROR, status) << "fuchsia.sysmem.BufferCollection disconnected.";
- OnError();
- });
-
- // BufferCollection needs to be synchronized before we can use it.
- output_buffer_collection_->Sync(
- [this,
- buffer_constraints = std::move(
- std::move(*output_constraints.mutable_buffer_constraints())),
- collection_token_for_codec = std::move(collection_token_for_codec),
- collection_token_for_gpu =
- std::move(collection_token_for_gpu)]() mutable {
- InitializeOutputBufferCollection(std::move(buffer_constraints),
- std::move(collection_token_for_codec),
- std::move(collection_token_for_gpu));
- });
+void FuchsiaVideoDecoder::OnStreamProcessorEndOfStream() {
+ // Decode() is not supposed to be called again after EOF.
+ DCHECK_EQ(decode_callbacks_.size(), 1U);
+ CallNextDecodeCallback();
}
-void FuchsiaVideoDecoder::OnOutputFormat(
+void FuchsiaVideoDecoder::OnStreamProcessorOutputFormat(
fuchsia::media::StreamOutputFormat output_format) {
- if (!output_format.has_stream_lifetime_ordinal() ||
- !output_format.has_format_details()) {
- DLOG(ERROR) << "Received OnOutputFormat() with missing required fields.";
- OnError();
- return;
- }
-
- if (output_format.stream_lifetime_ordinal() != stream_lifetime_ordinal_) {
- return;
- }
-
auto* format = output_format.mutable_format_details();
if (!format->has_domain() || !format->domain().is_video() ||
!format->domain().video().is_uncompressed()) {
@@ -825,27 +587,8 @@ void FuchsiaVideoDecoder::OnOutputFormat(
output_format_ = std::move(format->mutable_domain()->video().uncompressed());
}
-void FuchsiaVideoDecoder::OnOutputPacket(fuchsia::media::Packet output_packet,
- bool error_detected_before,
- bool error_detected_during) {
- if (!output_packet.has_header() ||
- !output_packet.header().has_buffer_lifetime_ordinal() ||
- !output_packet.header().has_packet_index() ||
- !output_packet.has_buffer_index()) {
- DLOG(ERROR) << "Received OnOutputPacket() with missing required fields.";
- OnError();
- return;
- }
-
- if (output_packet.stream_lifetime_ordinal() != stream_lifetime_ordinal_) {
- return;
- }
-
- if (output_packet.header().buffer_lifetime_ordinal() !=
- output_buffer_lifetime_ordinal_) {
- return;
- }
-
+void FuchsiaVideoDecoder::OnStreamProcessorOutputPacket(
+ StreamProcessorHelper::IoPacket output_packet) {
fuchsia::sysmem::PixelFormatType sysmem_pixel_format =
output_format_.image_format.pixel_format.type;
@@ -912,26 +655,24 @@ void FuchsiaVideoDecoder::OnOutputPacket(fuchsia::media::Packet output_packet,
pixel_aspect_ratio = container_pixel_aspect_ratio_;
}
+ auto timestamp = output_packet.timestamp();
+
// SendInputPacket() sets timestamp for all packets sent to the decoder, so we
// expect to receive timestamp for all decoded frames. Missing timestamp
// indicates a bug in the decoder implementation.
- if (!output_packet.has_timestamp_ish()) {
+ if (timestamp == kNoTimestamp) {
LOG(ERROR) << "Received frame without timestamp.";
OnError();
return;
}
- base::TimeDelta timestamp =
- base::TimeDelta::FromNanoseconds(output_packet.timestamp_ish());
-
num_used_output_buffers_++;
auto frame = output_mailboxes_[buffer_index]->CreateFrame(
pixel_format, coded_size, display_rect,
GetNaturalSize(display_rect, pixel_aspect_ratio), timestamp,
- base::BindOnce(&FuchsiaVideoDecoder::OnReuseMailbox,
- base::Unretained(this), buffer_index,
- output_packet.header().packet_index()));
+ base::BindOnce(&FuchsiaVideoDecoder::ReleaseOutputPacket,
+ base::Unretained(this), std::move(output_packet)));
// Currently sysmem doesn't specify location of chroma samples relative to
// luma (see fxb/13677). Assume they are cosited with luma. YCbCr info here
@@ -958,41 +699,36 @@ void FuchsiaVideoDecoder::OnOutputPacket(fuchsia::media::Packet output_packet,
output_cb_.Run(std::move(frame));
}
-void FuchsiaVideoDecoder::OnOutputEndOfStream(uint64_t stream_lifetime_ordinal,
- bool error_detected_before) {
- if (stream_lifetime_ordinal != stream_lifetime_ordinal_) {
- return;
- }
+void FuchsiaVideoDecoder::OnStreamProcessorNoKey() {
+ // Decoder is not expected to produce NoKey() error.
+ DLOG(ERROR) << "Video decoder failed with DECRYPTOR_NO_KEY expectedly";
+ OnError();
+}
- stream_lifetime_ordinal_ += 2;
- active_stream_ = false;
+void FuchsiaVideoDecoder::OnStreamProcessorError() {
+ OnError();
+}
- // Decode() is not supposed to be called after EOF.
- DCHECK_EQ(decode_callbacks_.size(), 1U);
- auto flush_cb = std::move(decode_callbacks_.front());
+void FuchsiaVideoDecoder::CallNextDecodeCallback() {
+ DCHECK(!decode_callbacks_.empty());
+ auto cb = std::move(decode_callbacks_.front());
decode_callbacks_.pop_front();
- std::move(flush_cb).Run(DecodeStatus::OK);
+ std::move(cb).Run(DecodeStatus::OK);
}
bool FuchsiaVideoDecoder::DropInputQueue(DecodeStatus status) {
- input_writer_queue_.ResetQueue();
+ // Invalidate callbacks for CallNextDecodeCallback(), so the callbacks are not
+ // called when the |decoder_| is dropped below. The callbacks are called
+ // explicitly later.
+ decode_callbacks_weak_factory_.InvalidateWeakPtrs();
- if (active_stream_) {
- if (decoder_) {
- decoder_->CloseCurrentStream(stream_lifetime_ordinal_,
- /*release_input_buffers=*/false,
- /*release_output_buffers=*/false);
- }
- stream_lifetime_ordinal_ += 2;
- active_stream_ = false;
+ if (decoder_) {
+ decoder_->Reset();
}
- if (decryptor_)
- decryptor_->Reset();
-
- for (auto& packet : in_flight_input_packets_) {
- packet.second.used_for_current_stream = false;
+ if (sysmem_buffer_stream_) {
+ sysmem_buffer_stream_->Reset();
}
auto weak_this = weak_this_;
@@ -1010,69 +746,35 @@ bool FuchsiaVideoDecoder::DropInputQueue(DecodeStatus status) {
}
void FuchsiaVideoDecoder::OnError() {
- decoder_.Unbind();
- decryptor_.reset();
+ sysmem_buffer_stream_.reset();
+ decoder_.reset();
- ReleaseInputBuffers();
ReleaseOutputBuffers();
DropInputQueue(DecodeStatus::DECODE_ERROR);
}
-void FuchsiaVideoDecoder::InitializeOutputBufferCollection(
- fuchsia::media::StreamBufferConstraints constraints,
- fuchsia::sysmem::BufferCollectionTokenPtr collection_token_for_codec,
- fuchsia::sysmem::BufferCollectionTokenPtr collection_token_for_gpu) {
- fuchsia::sysmem::BufferCollectionConstraints buffer_constraints;
- buffer_constraints.usage.none = fuchsia::sysmem::noneUsage;
- buffer_constraints.min_buffer_count_for_camping = kOutputBuffersForCamping;
- buffer_constraints.min_buffer_count_for_shared_slack =
- kMaxUsedOutputBuffers - kOutputBuffersForCamping;
- output_buffer_collection_->SetConstraints(
- /*has_constraints=*/true, std::move(buffer_constraints));
-
+void FuchsiaVideoDecoder::SetBufferCollectionTokenForGpu(
+ fuchsia::sysmem::BufferCollectionTokenPtr token) {
// Register the new collection with the GPU process.
DCHECK(!output_buffer_collection_id_);
output_buffer_collection_id_ = gfx::SysmemBufferCollectionId::Create();
raster_context_provider_->SharedImageInterface()
->RegisterSysmemBufferCollection(
- output_buffer_collection_id_,
- collection_token_for_gpu.Unbind().TakeChannel(),
+ output_buffer_collection_id_, token.Unbind().TakeChannel(),
gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::GPU_READ,
use_overlays_for_video_ /*register_with_image_pipe*/);
- // Pass new output buffer settings to the codec.
- fuchsia::media::StreamBufferPartialSettings settings;
- settings.set_buffer_lifetime_ordinal(output_buffer_lifetime_ordinal_);
- settings.set_buffer_constraints_version_ordinal(
- constraints.buffer_constraints_version_ordinal());
- settings.set_sysmem_token(std::move(collection_token_for_codec));
- decoder_->SetOutputBufferPartialSettings(std::move(settings));
- decoder_->CompleteOutputBufferPartialSettings(
- output_buffer_lifetime_ordinal_);
-
// Exact number of buffers sysmem will allocate is unknown here.
// |output_mailboxes_| is resized when we start receiving output frames.
DCHECK(output_mailboxes_.empty());
}
-void FuchsiaVideoDecoder::ReleaseInputBuffers() {
- input_writer_queue_.ResetBuffers();
- input_buffer_collection_creator_.reset();
- input_buffer_collection_.reset();
-
- // |in_flight_input_packets_| must be destroyed after
- // |input_writer_queue_.ResetBuffers()|. Otherwise |input_writer_queue_| may
- // call SendInputPacket() in response to the packet destruction callbacks.
- in_flight_input_packets_.clear();
-}
-
void FuchsiaVideoDecoder::ReleaseOutputBuffers() {
// Release the buffer collection.
num_used_output_buffers_ = 0;
if (output_buffer_collection_) {
- output_buffer_collection_->Close();
- output_buffer_collection_.Unbind();
+ output_buffer_collection_.reset();
}
// Release all output mailboxes.
@@ -1090,17 +792,10 @@ void FuchsiaVideoDecoder::ReleaseOutputBuffers() {
}
}
-void FuchsiaVideoDecoder::OnReuseMailbox(uint32_t buffer_index,
- uint32_t packet_index) {
- DCHECK(decoder_);
-
+void FuchsiaVideoDecoder::ReleaseOutputPacket(
+ StreamProcessorHelper::IoPacket output_packet) {
DCHECK_GT(num_used_output_buffers_, 0U);
num_used_output_buffers_--;
-
- fuchsia::media::PacketHeader header;
- header.set_buffer_lifetime_ordinal(output_buffer_lifetime_ordinal_);
- header.set_packet_index(packet_index);
- decoder_->RecycleOutputPacket(std::move(header));
}
std::unique_ptr<VideoDecoder> CreateFuchsiaVideoDecoder(
diff --git a/chromium/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc b/chromium/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc
index 2b319eae494..24bebcc5a58 100644
--- a/chromium/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc
+++ b/chromium/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc
@@ -78,7 +78,7 @@ class TestBufferCollection {
fuchsia::sysmem::AllocatorPtr sysmem_allocator_;
fuchsia::sysmem::BufferCollectionSyncPtr buffers_collection_;
- base::Optional<fuchsia::sysmem::BufferCollectionInfo_2>
+ absl::optional<fuchsia::sysmem::BufferCollectionInfo_2>
buffer_collection_info_;
DISALLOW_COPY_AND_ASSIGN(TestBufferCollection);
@@ -115,6 +115,7 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
gpu::Mailbox CreateSharedImage(
gfx::GpuMemoryBuffer* gpu_memory_buffer,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+ gfx::BufferPlane plane,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
diff --git a/chromium/media/filters/media_file_checker.h b/chromium/media/filters/media_file_checker.h
index 86db498b03d..113f8434b02 100644
--- a/chromium/media/filters/media_file_checker.h
+++ b/chromium/media/filters/media_file_checker.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_BASE_MEDIA_FILE_CHECKER_H_
-#define MEDIA_BASE_MEDIA_FILE_CHECKER_H_
+#ifndef MEDIA_FILTERS_MEDIA_FILE_CHECKER_H_
+#define MEDIA_FILTERS_MEDIA_FILE_CHECKER_H_
#include "base/files/file.h"
#include "base/macros.h"
@@ -36,4 +36,4 @@ class MEDIA_EXPORT MediaFileChecker {
} // namespace media
-#endif // MEDIA_BASE_MEDIA_FILE_CHECKER_H_
+#endif // MEDIA_FILTERS_MEDIA_FILE_CHECKER_H_
diff --git a/chromium/media/filters/pipeline_controller.cc b/chromium/media/filters/pipeline_controller.cc
index 68b39ebe31a..b304bc826dc 100644
--- a/chromium/media/filters/pipeline_controller.cc
+++ b/chromium/media/filters/pipeline_controller.cc
@@ -384,7 +384,7 @@ void PipelineController::SetVolume(float volume) {
}
void PipelineController::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
DCHECK(!latency_hint || (*latency_hint >= base::TimeDelta()));
pipeline_->SetLatencyHint(latency_hint);
}
@@ -433,7 +433,7 @@ void PipelineController::OnEnabledAudioTracksChanged(
}
void PipelineController::OnSelectedVideoTrackChanged(
- base::Optional<MediaTrack::Id> selected_track_id) {
+ absl::optional<MediaTrack::Id> selected_track_id) {
DCHECK(thread_checker_.CalledOnValidThread());
pending_video_track_change_ = true;
diff --git a/chromium/media/filters/pipeline_controller.h b/chromium/media/filters/pipeline_controller.h
index a77ab00085b..ea0370332dc 100644
--- a/chromium/media/filters/pipeline_controller.h
+++ b/chromium/media/filters/pipeline_controller.h
@@ -8,11 +8,11 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "media/base/media_export.h"
#include "media/base/pipeline.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -131,7 +131,7 @@ class MEDIA_EXPORT PipelineController {
void SetPlaybackRate(double playback_rate);
float GetVolume() const;
void SetVolume(float volume);
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint);
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint);
void SetPreservesPitch(bool preserves_pitch);
void SetAutoplayInitiated(bool autoplay_initiated);
base::TimeDelta GetMediaTime() const;
@@ -143,7 +143,7 @@ class MEDIA_EXPORT PipelineController {
void OnEnabledAudioTracksChanged(
const std::vector<MediaTrack::Id>& enabled_track_ids);
void OnSelectedVideoTrackChanged(
- base::Optional<MediaTrack::Id> selected_track_id);
+ absl::optional<MediaTrack::Id> selected_track_id);
// Used to fire the OnTrackChangeComplete function which is captured in a
// OnceCallback, and doesn't play nicely with gmock.
@@ -226,7 +226,7 @@ class MEDIA_EXPORT PipelineController {
// |pending_video_track_change_|.
base::TimeDelta pending_seek_time_;
std::vector<MediaTrack::Id> pending_audio_track_change_ids_;
- base::Optional<MediaTrack::Id> pending_video_track_change_id_;
+ absl::optional<MediaTrack::Id> pending_video_track_change_id_;
// Set to true during Start(). Indicates that |seeked_cb_| must be fired once
// we've completed startup.
diff --git a/chromium/media/filters/pipeline_controller_unittest.cc b/chromium/media/filters/pipeline_controller_unittest.cc
index 390dbc69409..5ca4b2a8be0 100644
--- a/chromium/media/filters/pipeline_controller_unittest.cc
+++ b/chromium/media/filters/pipeline_controller_unittest.cc
@@ -150,7 +150,7 @@ class PipelineControllerTest : public ::testing::Test, public Pipeline::Client {
void OnAudioConfigChange(const AudioDecoderConfig& config) override {}
void OnVideoConfigChange(const VideoDecoderConfig& config) override {}
void OnVideoOpacityChange(bool opaque) override {}
- void OnVideoFrameRateChange(base::Optional<int>) override {}
+ void OnVideoFrameRateChange(absl::optional<int>) override {}
void OnVideoAverageKeyframeDistanceUpdate() override {}
void OnAudioDecoderChange(const AudioDecoderInfo& info) override {}
void OnVideoDecoderChange(const VideoDecoderInfo& info) override {}
diff --git a/chromium/media/filters/source_buffer_stream.cc b/chromium/media/filters/source_buffer_stream.cc
index 488f9e2a62b..3c877e35d0b 100644
--- a/chromium/media/filters/source_buffer_stream.cc
+++ b/chromium/media/filters/source_buffer_stream.cc
@@ -673,7 +673,6 @@ bool SourceBufferStream::IsDtsMonotonicallyIncreasing(
const BufferQueue& buffers) {
DCHECK(!buffers.empty());
DecodeTimestamp prev_dts = last_appended_buffer_decode_timestamp_;
- bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
for (BufferQueue::const_iterator itr = buffers.begin();
itr != buffers.end(); ++itr) {
DecodeTimestamp current_dts = (*itr)->GetDecodeTimestamp();
@@ -706,7 +705,6 @@ bool SourceBufferStream::IsDtsMonotonicallyIncreasing(
}
prev_dts = current_dts;
- prev_is_keyframe = current_is_keyframe;
}
return true;
}
diff --git a/chromium/media/filters/stream_parser_factory.cc b/chromium/media/filters/stream_parser_factory.cc
index 58a60adaa63..098ebd4e717 100644
--- a/chromium/media/filters/stream_parser_factory.cc
+++ b/chromium/media/filters/stream_parser_factory.cc
@@ -488,6 +488,18 @@ static SupportsType CheckTypeAndCodecs(
bool found_codec = false;
std::string codec_id = codecs[j];
for (int k = 0; type_info.codecs[k]; ++k) {
+ // Only check a codec pattern if there is one to check. Some types,
+ // like audio/mpeg and audio/aac require there be no codecs parameter,
+ // and instead have implicit codec. If a codec is provided for such a
+ // type then it is not supported by MSE. We don't check any other
+ // potential matches because none should be configured.
+ if (!type_info.codecs[k]->pattern) {
+ DCHECK(k == 0 && !type_info.codecs[1])
+ << "For a type with implicit codec, then only one codec must "
+ "be configured";
+ break;
+ }
+
if (base::MatchPattern(codec_id, type_info.codecs[k]->pattern) &&
(!type_info.codecs[k]->validator ||
type_info.codecs[k]->validator(codec_id, media_log))) {
diff --git a/chromium/media/filters/video_cadence_estimator.h b/chromium/media/filters/video_cadence_estimator.h
index 71cfeed693d..bed98a919ed 100644
--- a/chromium/media/filters/video_cadence_estimator.h
+++ b/chromium/media/filters/video_cadence_estimator.h
@@ -11,9 +11,9 @@
#include <vector>
#include "base/macros.h"
-#include "base/optional.h"
#include "base/time/time.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -179,7 +179,7 @@ class MEDIA_EXPORT VideoCadenceEstimator {
// In an ideal world, each video frame would be shown for this many display
// intervals. It equals (display frequency) divided by (video frame rate).
// Absent when a video has variable frame rate.
- base::Optional<double> perfect_cadence_;
+ absl::optional<double> perfect_cadence_;
} bm_;
DISALLOW_COPY_AND_ASSIGN(VideoCadenceEstimator);
diff --git a/chromium/media/filters/vp9_parser_unittest.cc b/chromium/media/filters/vp9_parser_unittest.cc
index 639e0c1e767..0bca30b41b1 100644
--- a/chromium/media/filters/vp9_parser_unittest.cc
+++ b/chromium/media/filters/vp9_parser_unittest.cc
@@ -212,10 +212,10 @@ TEST_F(Vp9ParserTest, AlignedFrameSubsampleParsing) {
std::vector<std::unique_ptr<DecryptConfig>> expected;
expected.push_back(DecryptConfig::CreateCbcsConfig(
- kKeyID, kInitialIV, {SubsampleEntry(16, 16)}, base::nullopt));
+ kKeyID, kInitialIV, {SubsampleEntry(16, 16)}, absl::nullopt));
expected.push_back(DecryptConfig::CreateCbcsConfig(
- kKeyID, kIVIncrementOne, {SubsampleEntry(16, 16)}, base::nullopt));
+ kKeyID, kIVIncrementOne, {SubsampleEntry(16, 16)}, absl::nullopt));
CheckSubsampleValues(
kSuperframe, sizeof(kSuperframe),
@@ -253,10 +253,10 @@ TEST_F(Vp9ParserTest, UnalignedFrameSubsampleParsing) {
std::vector<std::unique_ptr<DecryptConfig>> expected;
expected.push_back(DecryptConfig::CreateCbcsConfig(
- kKeyID, kInitialIV, {SubsampleEntry(32, 0)}, base::nullopt));
+ kKeyID, kInitialIV, {SubsampleEntry(32, 0)}, absl::nullopt));
expected.push_back(DecryptConfig::CreateCbcsConfig(
- kKeyID, kInitialIV, {SubsampleEntry(16, 16)}, base::nullopt));
+ kKeyID, kInitialIV, {SubsampleEntry(16, 16)}, absl::nullopt));
CheckSubsampleValues(kSuperframe, sizeof(kSuperframe),
DecryptConfig::CreateCencConfig(
@@ -295,10 +295,10 @@ TEST_F(Vp9ParserTest, ClearSectionRollsOverSubsampleParsing) {
std::vector<std::unique_ptr<DecryptConfig>> expected;
expected.push_back(DecryptConfig::CreateCbcsConfig(
kKeyID, kInitialIV, {SubsampleEntry(16, 16), SubsampleEntry(16, 0)},
- base::nullopt));
+ absl::nullopt));
expected.push_back(DecryptConfig::CreateCbcsConfig(
- kKeyID, kIVIncrementOne, {SubsampleEntry(16, 16)}, base::nullopt));
+ kKeyID, kIVIncrementOne, {SubsampleEntry(16, 16)}, absl::nullopt));
CheckSubsampleValues(
kSuperframe, sizeof(kSuperframe),
@@ -340,10 +340,10 @@ TEST_F(Vp9ParserTest, FirstFrame2xSubsampleParsing) {
std::vector<std::unique_ptr<DecryptConfig>> expected;
expected.push_back(DecryptConfig::CreateCbcsConfig(
kKeyID, kInitialIV, {SubsampleEntry(16, 16), SubsampleEntry(16, 16)},
- base::nullopt));
+ absl::nullopt));
expected.push_back(DecryptConfig::CreateCbcsConfig(
- kKeyID, kIVIncrementTwo, {SubsampleEntry(16, 16)}, base::nullopt));
+ kKeyID, kIVIncrementTwo, {SubsampleEntry(16, 16)}, absl::nullopt));
CheckSubsampleValues(kSuperframe, sizeof(kSuperframe),
DecryptConfig::CreateCencConfig(
@@ -387,10 +387,10 @@ TEST_F(Vp9ParserTest, UnalignedBigFrameSubsampleParsing) {
expected.push_back(DecryptConfig::CreateCbcsConfig(
kKeyID, kInitialIV,
{SubsampleEntry(16, 16), SubsampleEntry(16, 16), SubsampleEntry(8, 0)},
- base::nullopt));
+ absl::nullopt));
expected.push_back(DecryptConfig::CreateCbcsConfig(
- kKeyID, kIVIncrementTwo, {SubsampleEntry(16, 16)}, base::nullopt));
+ kKeyID, kIVIncrementTwo, {SubsampleEntry(16, 16)}, absl::nullopt));
CheckSubsampleValues(
kSuperframe, sizeof(kSuperframe),
diff --git a/chromium/media/filters/vpx_video_decoder.cc b/chromium/media/filters/vpx_video_decoder.cc
index 3204b5f7734..bfc29036943 100644
--- a/chromium/media/filters/vpx_video_decoder.cc
+++ b/chromium/media/filters/vpx_video_decoder.cc
@@ -83,7 +83,7 @@ static int32_t GetVP9FrameBuffer(void* user_priv,
FrameBufferPool* pool = static_cast<FrameBufferPool*>(user_priv);
fb->data = pool->GetFrameBuffer(min_size, &fb->priv);
fb->size = min_size;
- return 0;
+ return fb->data ? 0 : VPX_CODEC_MEM_ERROR;
}
static int32_t ReleaseVP9FrameBuffer(void* user_priv,
@@ -556,6 +556,8 @@ bool VpxVideoDecoder::CopyVpxImageToVideoFrame(
vpx_image_alpha->stride[VPX_PLANE_Y] * vpx_image_alpha->d_h;
uint8_t* alpha_plane = memory_pool_->AllocateAlphaPlaneForFrameBuffer(
alpha_plane_size, vpx_image->fb_priv);
+ if (!alpha_plane) // In case of OOM, abort copy.
+ return false;
libyuv::CopyPlane(vpx_image_alpha->planes[VPX_PLANE_Y],
vpx_image_alpha->stride[VPX_PLANE_Y], alpha_plane,
vpx_image_alpha->stride[VPX_PLANE_Y],
diff --git a/chromium/media/filters/vpx_video_decoder.h b/chromium/media/filters/vpx_video_decoder.h
index 37445263d39..34a8433258c 100644
--- a/chromium/media/filters/vpx_video_decoder.h
+++ b/chromium/media/filters/vpx_video_decoder.h
@@ -13,6 +13,7 @@
#include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h"
#include "media/base/video_frame_pool.h"
+#include "media/filters/frame_buffer_pool.h"
#include "media/filters/offloading_video_decoder.h"
struct vpx_codec_ctx;
@@ -49,6 +50,10 @@ class MEDIA_EXPORT VpxVideoDecoder : public OffloadableVideoDecoder {
// OffloadableVideoDecoder implementation.
void Detach() override;
+ void force_allocation_error_for_testing() {
+ memory_pool_->force_allocation_error_for_testing();
+ }
+
private:
enum DecoderState {
kUninitialized,
diff --git a/chromium/media/filters/vpx_video_decoder_unittest.cc b/chromium/media/filters/vpx_video_decoder_unittest.cc
index 6e428b72e53..6f37edb3067 100644
--- a/chromium/media/filters/vpx_video_decoder_unittest.cc
+++ b/chromium/media/filters/vpx_video_decoder_unittest.cc
@@ -196,6 +196,14 @@ TEST_F(VpxVideoDecoderTest, DecodeFrame_Normal) {
ASSERT_EQ(1U, output_frames_.size());
}
+TEST_F(VpxVideoDecoderTest, DecodeFrame_OOM) {
+ Initialize();
+ static_cast<VpxVideoDecoder*>(decoder_.get())
+ ->force_allocation_error_for_testing();
+ EXPECT_FALSE(DecodeSingleFrame(i_frame_buffer_).is_ok());
+ EXPECT_TRUE(output_frames_.empty());
+}
+
// Decode |i_frame_buffer_| and then a frame with a larger width and verify
// the output size was adjusted.
TEST_F(VpxVideoDecoderTest, DecodeFrame_LargerWidth) {
diff --git a/chromium/media/formats/mp2t/descriptors.h b/chromium/media/formats/mp2t/descriptors.h
index ad55322fc2e..817da22c93c 100644
--- a/chromium/media/formats/mp2t/descriptors.h
+++ b/chromium/media/formats/mp2t/descriptors.h
@@ -68,4 +68,4 @@ class Descriptors {
} // namespace mp2t
} // namespace media
-#endif // MEDIA_FORMATS_MP2T_DESCRIPTOR_LIST_H_
+#endif // MEDIA_FORMATS_MP2T_DESCRIPTORS_H_
diff --git a/chromium/media/formats/mp2t/es_parser_adts.cc b/chromium/media/formats/mp2t/es_parser_adts.cc
index c612e6e4b87..91470b75d25 100644
--- a/chromium/media/formats/mp2t/es_parser_adts.cc
+++ b/chromium/media/formats/mp2t/es_parser_adts.cc
@@ -9,7 +9,6 @@
#include <vector>
#include "base/logging.h"
-#include "base/optional.h"
#include "base/strings/string_number_conversions.h"
#include "media/base/audio_timestamp_helper.h"
#include "media/base/bit_reader.h"
@@ -21,6 +20,7 @@
#include "media/formats/common/offset_byte_queue.h"
#include "media/formats/mp2t/mp2t_common.h"
#include "media/formats/mpeg/adts_constants.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
diff --git a/chromium/media/formats/mp2t/es_parser_adts.h b/chromium/media/formats/mp2t/es_parser_adts.h
index 7a9950e516c..665ec3f7794 100644
--- a/chromium/media/formats/mp2t/es_parser_adts.h
+++ b/chromium/media/formats/mp2t/es_parser_adts.h
@@ -14,7 +14,6 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/time/time.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/decrypt_config.h"
#include "media/base/media_export.h"
diff --git a/chromium/media/formats/mp2t/es_parser_h264.cc b/chromium/media/formats/mp2t/es_parser_h264.cc
index 2093e21dabc..a00a90cad5f 100644
--- a/chromium/media/formats/mp2t/es_parser_h264.cc
+++ b/chromium/media/formats/mp2t/es_parser_h264.cc
@@ -8,7 +8,6 @@
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
-#include "base/optional.h"
#include "media/base/decrypt_config.h"
#include "media/base/encryption_pattern.h"
#include "media/base/media_util.h"
@@ -18,6 +17,7 @@
#include "media/formats/common/offset_byte_queue.h"
#include "media/formats/mp2t/mp2t_common.h"
#include "media/video/h264_parser.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -490,11 +490,11 @@ bool EsParserH264::UpdateVideoDecoderConfig(const H264SPS* sps,
int sar_width = (sps->sar_width == 0) ? 1 : sps->sar_width;
int sar_height = (sps->sar_height == 0) ? 1 : sps->sar_height;
- base::Optional<gfx::Size> coded_size = sps->GetCodedSize();
+ absl::optional<gfx::Size> coded_size = sps->GetCodedSize();
if (!coded_size)
return false;
- base::Optional<gfx::Rect> visible_rect = sps->GetVisibleRect();
+ absl::optional<gfx::Rect> visible_rect = sps->GetVisibleRect();
if (!visible_rect)
return false;
diff --git a/chromium/media/formats/mp2t/es_parser_h264.h b/chromium/media/formats/mp2t/es_parser_h264.h
index 74c5a08e438..4a771af3bd2 100644
--- a/chromium/media/formats/mp2t/es_parser_h264.h
+++ b/chromium/media/formats/mp2t/es_parser_h264.h
@@ -13,7 +13,6 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/time/time.h"
#include "media/base/media_export.h"
#include "media/base/ranges.h"
#include "media/base/video_decoder_config.h"
diff --git a/chromium/media/formats/mp2t/mp2t_stream_parser.cc b/chromium/media/formats/mp2t/mp2t_stream_parser.cc
index b118f05ae6a..1e42091969b 100644
--- a/chromium/media/formats/mp2t/mp2t_stream_parser.cc
+++ b/chromium/media/formats/mp2t/mp2t_stream_parser.cc
@@ -9,7 +9,6 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
-#include "base/optional.h"
#include "media/base/media_tracks.h"
#include "media/base/stream_parser_buffer.h"
#include "media/base/text_track_config.h"
@@ -25,6 +24,7 @@
#include "media/formats/mp2t/ts_section_pat.h"
#include "media/formats/mp2t/ts_section_pes.h"
#include "media/formats/mp2t/ts_section_pmt.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
#include "media/formats/mp2t/ts_section_cat.h"
@@ -968,7 +968,7 @@ void Mp2tStreamParser::RegisterNewKeyIdAndIv(const std::string& key_id,
break;
case EncryptionScheme::kCbcs:
decrypt_config_ =
- DecryptConfig::CreateCbcsConfig(key_id, iv, {}, base::nullopt);
+ DecryptConfig::CreateCbcsConfig(key_id, iv, {}, absl::nullopt);
break;
}
}
diff --git a/chromium/media/formats/mp2t/ts_section_cat.h b/chromium/media/formats/mp2t/ts_section_cat.h
index 1dcd9672fb4..69ef68714e9 100644
--- a/chromium/media/formats/mp2t/ts_section_cat.h
+++ b/chromium/media/formats/mp2t/ts_section_cat.h
@@ -41,4 +41,4 @@ class TsSectionCat : public TsSectionPsi {
} // namespace mp2t
} // namespace media
-#endif
+#endif // MEDIA_FORMATS_MP2T_TS_SECTION_CAT_H_
diff --git a/chromium/media/formats/mp2t/ts_section_cets_ecm.h b/chromium/media/formats/mp2t/ts_section_cets_ecm.h
index 6d17b8bff37..d2fb53414cf 100644
--- a/chromium/media/formats/mp2t/ts_section_cets_ecm.h
+++ b/chromium/media/formats/mp2t/ts_section_cets_ecm.h
@@ -47,4 +47,4 @@ class TsSectionCetsEcm : public TsSection {
} // namespace mp2t
} // namespace media
-#endif
+#endif // MEDIA_FORMATS_MP2T_TS_SECTION_CETS_ECM_H_
diff --git a/chromium/media/formats/mp2t/ts_section_cets_pssh.h b/chromium/media/formats/mp2t/ts_section_cets_pssh.h
index b599bc3e04d..b4803068891 100644
--- a/chromium/media/formats/mp2t/ts_section_cets_pssh.h
+++ b/chromium/media/formats/mp2t/ts_section_cets_pssh.h
@@ -40,4 +40,4 @@ class TsSectionCetsPssh : public TsSection {
} // namespace mp2t
} // namespace media
-#endif
+#endif // MEDIA_FORMATS_MP2T_TS_SECTION_CETS_PSSH_H_
diff --git a/chromium/media/formats/mp4/avc_unittest.cc b/chromium/media/formats/mp4/avc_unittest.cc
index e21c126f7fd..cc190e02631 100644
--- a/chromium/media/formats/mp4/avc_unittest.cc
+++ b/chromium/media/formats/mp4/avc_unittest.cc
@@ -8,7 +8,6 @@
#include <ostream>
-#include "base/optional.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@@ -20,6 +19,7 @@
#include "media/formats/mp4/nalu_test_helper.h"
#include "media/video/h264_parser.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace mp4 {
@@ -337,19 +337,19 @@ TEST_F(AVCConversionTest, ValidAnnexBConstructs) {
TEST_F(AVCConversionTest, InvalidAnnexBConstructs) {
struct {
const char* case_string;
- const base::Optional<bool> is_keyframe;
+ const absl::optional<bool> is_keyframe;
} test_cases[] = {
// For these cases, lack of conformance is determined before detecting any
// IDR or non-IDR slices, so the non-conformant frames' keyframe analysis
- // reports base::nullopt (which means undetermined analysis result).
- {"AUD", base::nullopt}, // No VCL present.
- {"AUD,SEI", base::nullopt}, // No VCL present.
- {"SPS PPS", base::nullopt}, // No VCL present.
- {"SPS PPS AUD I", base::nullopt}, // Parameter sets must come after AUD.
- {"SPSExt SPS P", base::nullopt}, // SPS must come before SPSExt.
- {"SPS PPS SPSExt P", base::nullopt}, // SPSExt must follow an SPS.
- {"EOSeq", base::nullopt}, // EOSeq must come after a VCL.
- {"EOStr", base::nullopt}, // EOStr must come after a VCL.
+ // reports absl::nullopt (which means undetermined analysis result).
+ {"AUD", absl::nullopt}, // No VCL present.
+ {"AUD,SEI", absl::nullopt}, // No VCL present.
+ {"SPS PPS", absl::nullopt}, // No VCL present.
+ {"SPS PPS AUD I", absl::nullopt}, // Parameter sets must come after AUD.
+ {"SPSExt SPS P", absl::nullopt}, // SPS must come before SPSExt.
+ {"SPS PPS SPSExt P", absl::nullopt}, // SPSExt must follow an SPS.
+ {"EOSeq", absl::nullopt}, // EOSeq must come after a VCL.
+ {"EOStr", absl::nullopt}, // EOStr must come after a VCL.
// For these cases, IDR slice is first VCL and is detected before
// conformance failure, so the non-conformant frame is reported as a
diff --git a/chromium/media/formats/mp4/bitstream_converter.h b/chromium/media/formats/mp4/bitstream_converter.h
index b6ad4a47cbf..4b9677131cc 100644
--- a/chromium/media/formats/mp4/bitstream_converter.h
+++ b/chromium/media/formats/mp4/bitstream_converter.h
@@ -10,8 +10,8 @@
#include <vector>
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -27,14 +27,14 @@ class MEDIA_EXPORT BitstreamConverter
public:
// Describes the result of Analyze(). Not all analyses are implemented or
// enabled across mp4::BitstreamConverter implementations, hence the use of
- // base::Optional<>.
+ // absl::optional<>.
struct MEDIA_EXPORT AnalysisResult {
AnalysisResult();
AnalysisResult(const AnalysisResult&);
~AnalysisResult();
- base::Optional<bool> is_conformant;
- base::Optional<bool> is_keyframe;
+ absl::optional<bool> is_conformant;
+ absl::optional<bool> is_keyframe;
};
// Converts a single frame/buffer |frame_buf| into the output format.
diff --git a/chromium/media/formats/mp4/box_definitions.cc b/chromium/media/formats/mp4/box_definitions.cc
index 6bc50c65f7a..f53b9347c8d 100644
--- a/chromium/media/formats/mp4/box_definitions.cc
+++ b/chromium/media/formats/mp4/box_definitions.cc
@@ -31,8 +31,8 @@
#include "media/video/h264_parser.h" // nogncheck
#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
-#include "base/optional.h"
#include "media/formats/mp4/dolby_vision.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#endif // BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
@@ -50,7 +50,7 @@ const size_t kFlacMetadataBlockStreaminfoSize = 34;
#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
// Parse dvcC or dvvC box.
-base::Optional<DOVIDecoderConfigurationRecord> ParseDOVIConfig(
+absl::optional<DOVIDecoderConfigurationRecord> ParseDOVIConfig(
BoxReader* reader) {
{
DolbyVisionConfiguration dvcc;
@@ -68,7 +68,7 @@ base::Optional<DOVIDecoderConfigurationRecord> ParseDOVIConfig(
}
}
- return base::nullopt;
+ return absl::nullopt;
}
#endif // BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
diff --git a/chromium/media/formats/mp4/box_definitions.h b/chromium/media/formats/mp4/box_definitions.h
index 8cc2c8379c7..450f3fc43c1 100644
--- a/chromium/media/formats/mp4/box_definitions.h
+++ b/chromium/media/formats/mp4/box_definitions.h
@@ -12,7 +12,6 @@
#include <vector>
#include "base/compiler_specific.h"
-#include "base/optional.h"
#include "media/base/decrypt_config.h"
#include "media/base/media_export.h"
#include "media/base/media_log.h"
@@ -22,6 +21,7 @@
#include "media/formats/mp4/box_reader.h"
#include "media/formats/mp4/fourccs.h"
#include "media/media_buildflags.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace mp4 {
@@ -330,8 +330,8 @@ struct MEDIA_EXPORT VideoSampleEntry : Box {
VideoCodecLevel video_codec_level;
VideoColorSpace video_color_space;
- base::Optional<MasteringDisplayColorVolume> mastering_display_color_volume;
- base::Optional<ContentLightLevelInformation> content_light_level_information;
+ absl::optional<MasteringDisplayColorVolume> mastering_display_color_volume;
+ absl::optional<ContentLightLevelInformation> content_light_level_information;
bool IsFormatValid() const;
diff --git a/chromium/media/formats/mp4/dolby_vision.h b/chromium/media/formats/mp4/dolby_vision.h
index c1bc9bd00d9..4ce6c1c2fc5 100644
--- a/chromium/media/formats/mp4/dolby_vision.h
+++ b/chromium/media/formats/mp4/dolby_vision.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_FORMATS_MP4_DOLBY_VISION_H_
#define MEDIA_FORMATS_MP4_DOLBY_VISION_H_
-#include <vector>
-
#include "base/memory/ref_counted.h"
#include "media/base/media_export.h"
#include "media/formats/mp4/box_definitions.h"
diff --git a/chromium/media/formats/mp4/hevc_unittest.cc b/chromium/media/formats/mp4/hevc_unittest.cc
index 7bc641d996e..ce2b918ba9d 100644
--- a/chromium/media/formats/mp4/hevc_unittest.cc
+++ b/chromium/media/formats/mp4/hevc_unittest.cc
@@ -39,16 +39,16 @@ TEST(HEVCAnalyzeAnnexBTest, ValidAnnexBConstructs) {
TEST(HEVCAnalyzeAnnexBTest, InvalidAnnexBConstructs) {
struct {
const char* case_string;
- const base::Optional<bool> is_keyframe;
+ const absl::optional<bool> is_keyframe;
} test_cases[] = {
// For these cases, lack of conformance is determined before detecting any
// IDR or non-IDR slices, so the non-conformant frames' keyframe analysis
- // reports base::nullopt (which means undetermined analysis result).
- {"AUD", base::nullopt}, // No VCL present.
- {"AUD,SPS", base::nullopt}, // No VCL present.
- {"SPS AUD I", base::nullopt}, // Parameter sets must come after AUD.
- {"EOS", base::nullopt}, // EOS must come after a VCL.
- {"EOB", base::nullopt}, // EOB must come after a VCL.
+ // reports absl::nullopt (which means undetermined analysis result).
+ {"AUD", absl::nullopt}, // No VCL present.
+ {"AUD,SPS", absl::nullopt}, // No VCL present.
+ {"SPS AUD I", absl::nullopt}, // Parameter sets must come after AUD.
+ {"EOS", absl::nullopt}, // EOS must come after a VCL.
+ {"EOB", absl::nullopt}, // EOB must come after a VCL.
// For these cases, IDR slice is first VCL and is detected before
// conformance failure, so the non-conformant frame is reported as a
diff --git a/chromium/media/formats/webcodecs/webcodecs_encoded_chunk_stream_parser.h b/chromium/media/formats/webcodecs/webcodecs_encoded_chunk_stream_parser.h
index c5dafee217a..85480ab1793 100644
--- a/chromium/media/formats/webcodecs/webcodecs_encoded_chunk_stream_parser.h
+++ b/chromium/media/formats/webcodecs/webcodecs_encoded_chunk_stream_parser.h
@@ -9,7 +9,6 @@
#include <memory>
-#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "media/base/audio_decoder_config.h"
diff --git a/chromium/media/formats/webm/webm_colour_parser.cc b/chromium/media/formats/webm/webm_colour_parser.cc
index 134f4f7583a..7deee8eaa10 100644
--- a/chromium/media/formats/webm/webm_colour_parser.cc
+++ b/chromium/media/formats/webm/webm_colour_parser.cc
@@ -4,6 +4,7 @@
#include "media/formats/webm/webm_colour_parser.h"
+#include "base/check.h"
#include "base/logging.h"
#include "media/formats/webm/webm_constants.h"
#include "third_party/libwebm/source/mkvmuxer/mkvmuxer.h"
diff --git a/chromium/media/formats/webm/webm_colour_parser.h b/chromium/media/formats/webm/webm_colour_parser.h
index dedd824f43b..2a97bc73168 100644
--- a/chromium/media/formats/webm/webm_colour_parser.h
+++ b/chromium/media/formats/webm/webm_colour_parser.h
@@ -6,9 +6,9 @@
#define MEDIA_FORMATS_WEBM_WEBM_COLOUR_PARSER_H_
#include "base/macros.h"
-#include "base/optional.h"
#include "media/base/video_color_space.h"
#include "media/formats/webm/webm_parser.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/hdr_metadata.h"
namespace media {
@@ -26,7 +26,7 @@ struct MEDIA_EXPORT WebMColorMetadata {
VideoColorSpace color_space;
- base::Optional<gfx::HDRMetadata> hdr_metadata;
+ absl::optional<gfx::HDRMetadata> hdr_metadata;
WebMColorMetadata();
WebMColorMetadata(const WebMColorMetadata& rhs);
diff --git a/chromium/media/formats/webm/webm_stream_parser.h b/chromium/media/formats/webm/webm_stream_parser.h
index dc0b9167a74..bab74de0a80 100644
--- a/chromium/media/formats/webm/webm_stream_parser.h
+++ b/chromium/media/formats/webm/webm_stream_parser.h
@@ -9,7 +9,6 @@
#include <memory>
-#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "media/base/audio_decoder_config.h"
diff --git a/chromium/media/formats/webm/webm_stream_parser_unittest.cc b/chromium/media/formats/webm/webm_stream_parser_unittest.cc
index 7c01c85a0ef..fdb19030b31 100644
--- a/chromium/media/formats/webm/webm_stream_parser_unittest.cc
+++ b/chromium/media/formats/webm/webm_stream_parser_unittest.cc
@@ -176,7 +176,7 @@ TEST_F(WebMStreamParserTest, ColourElement) {
gfx::ColorSpace::RangeID::FULL);
EXPECT_EQ(video_config.color_space_info(), expected_color_space);
- base::Optional<gfx::HDRMetadata> hdr_metadata = video_config.hdr_metadata();
+ absl::optional<gfx::HDRMetadata> hdr_metadata = video_config.hdr_metadata();
EXPECT_TRUE(hdr_metadata.has_value());
EXPECT_EQ(hdr_metadata->max_content_light_level, 11u);
EXPECT_EQ(hdr_metadata->max_frame_average_light_level, 12u);
diff --git a/chromium/media/fuchsia/audio/BUILD.gn b/chromium/media/fuchsia/audio/BUILD.gn
index eb547274da2..618fdd7fa0f 100644
--- a/chromium/media/fuchsia/audio/BUILD.gn
+++ b/chromium/media/fuchsia/audio/BUILD.gn
@@ -7,11 +7,16 @@ source_set("audio") {
deps = [
"//base",
- "//media",
+ "//media/base",
+ "//media/filters",
+ "//media/fuchsia/cdm",
+ "//media/fuchsia/common",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media.audio",
"//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
]
+ configs += [ "//media:subcomponent_config" ]
+
sources = [
"fuchsia_audio_capturer_source.cc",
"fuchsia_audio_capturer_source.h",
@@ -40,7 +45,6 @@ source_set("unittests") {
testonly = true
deps = [
- ":audio",
":test_support",
"//base",
"//base/test:test_support",
@@ -52,5 +56,6 @@ source_set("unittests") {
sources = [
"fuchsia_audio_capturer_source_test.cc",
"fuchsia_audio_output_device_test.cc",
+ "fuchsia_audio_renderer_test.cc",
]
}
diff --git a/chromium/media/fuchsia/audio/fake_audio_consumer.h b/chromium/media/fuchsia/audio/fake_audio_consumer.h
index da1fcefb88c..e56bbfcbc75 100644
--- a/chromium/media/fuchsia/audio/fake_audio_consumer.h
+++ b/chromium/media/fuchsia/audio/fake_audio_consumer.h
@@ -11,6 +11,7 @@
#include <fuchsia/media/cpp/fidl_test_base.h>
#include <lib/fidl/cpp/binding.h>
+#include <list>
#include <vector>
#include "base/fuchsia/scoped_service_binding.h"
diff --git a/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source.cc b/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source.cc
index 80c28b2a6e3..721365dff9d 100644
--- a/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source.cc
+++ b/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source.cc
@@ -11,6 +11,7 @@
#include "base/bits.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/location.h"
+#include "base/stl_util.h"
#include "base/task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "media/base/audio_parameters.h"
@@ -170,7 +171,7 @@ void FuchsiaAudioCapturerSource::SetOutputDeviceForAec(
void FuchsiaAudioCapturerSource::NotifyCaptureError(
const std::string& message) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- callback_->OnCaptureError(message);
+ callback_->OnCaptureError(AudioCapturerSource::ErrorCode::kUnknown, message);
}
void FuchsiaAudioCapturerSource::NotifyCaptureStarted() {
diff --git a/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source.h b/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source.h
index 58fb18f8b55..43563e9231d 100644
--- a/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source.h
+++ b/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source.h
@@ -10,10 +10,11 @@
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "media/base/audio_capturer_source.h"
+#include "media/base/media_export.h"
namespace media {
-class FuchsiaAudioCapturerSource : public AudioCapturerSource {
+class MEDIA_EXPORT FuchsiaAudioCapturerSource : public AudioCapturerSource {
public:
explicit FuchsiaAudioCapturerSource(
fidl::InterfaceHandle<fuchsia::media::AudioCapturer> capturer_handle);
diff --git a/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source_test.cc b/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source_test.cc
index c045c52c39f..3d9a04c82a6 100644
--- a/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source_test.cc
+++ b/chromium/media/fuchsia/audio/fuchsia_audio_capturer_source_test.cc
@@ -121,7 +121,7 @@ class TestAudioCapturer
zx::vmo buffer_vmo_;
uint64_t buffer_size_ = 0;
- base::Optional<fuchsia::media::AudioStreamType> stream_type_;
+ absl::optional<fuchsia::media::AudioStreamType> stream_type_;
bool is_active_ = false;
size_t frames_per_packet_ = 0;
std::vector<bool> packets_usage_;
@@ -156,7 +156,8 @@ class TestCaptureCallback : public AudioCapturerSource::CaptureCallback {
packets_.push_back(std::move(bus));
}
- void OnCaptureError(const std::string& message) final {
+ void OnCaptureError(AudioCapturerSource::ErrorCode code,
+ const std::string& message) final {
EXPECT_FALSE(have_error_);
have_error_ = true;
}
diff --git a/chromium/media/fuchsia/audio/fuchsia_audio_output_device.cc b/chromium/media/fuchsia/audio/fuchsia_audio_output_device.cc
index 50429b46f06..3ebab0a45e6 100644
--- a/chromium/media/fuchsia/audio/fuchsia_audio_output_device.cc
+++ b/chromium/media/fuchsia/audio/fuchsia_audio_output_device.cc
@@ -9,7 +9,6 @@
#include "base/memory/shared_memory_mapping.h"
#include "base/memory/writable_shared_memory_region.h"
#include "base/no_destructor.h"
-#include "base/strings/stringprintf.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "media/base/audio_timestamp_helper.h"
@@ -386,46 +385,33 @@ void FuchsiaAudioOutputDevice::SchedulePumpSamples() {
base::TimeTicks now = base::TimeTicks::Now();
- int skipped_frames = 0;
-
// Target time for when PumpSamples() should run.
base::TimeTicks target_time = playback_time - min_lead_time_ - kLeadTimeExtra;
- // Check if it's too late to send the next packet. If it is, then advance
- // current stream position, adding kLeadTimeExtra to ensure the next packet
- // doesn't miss the deadline.
- auto lead_time = playback_time - now;
- if (lead_time < min_lead_time_) {
- auto new_playback_time = now + min_lead_time_ + kLeadTimeExtra;
- auto skipped_time = new_playback_time - playback_time;
- skipped_frames =
- AudioTimestampHelper::TimeToFrames(skipped_time, params_.sample_rate());
- media_pos_frames_ += skipped_frames;
- target_time = now;
- playback_time += skipped_time;
- }
-
base::TimeDelta delay = target_time - now;
pump_samples_timer_.Start(
FROM_HERE, delay,
base::BindOnce(&FuchsiaAudioOutputDevice::PumpSamples, this,
- playback_time, skipped_frames));
+ playback_time));
}
-void FuchsiaAudioOutputDevice::PumpSamples(base::TimeTicks playback_time,
- int frames_skipped) {
+void FuchsiaAudioOutputDevice::PumpSamples(base::TimeTicks playback_time) {
DCHECK(CurrentThreadIsRenderingThread());
auto now = base::TimeTicks::Now();
- // Check if the timer has missed the deadline. It doesn't make sense to try
- // sending the packet in that case (it's likely to arrive too late).
- // Reschedule the timer. In this case SchedulePumpSamples() is expected to
- // schedule PumpSamples() to run immediately with frames_skipped > 0.
+ int skipped_frames = 0;
+
+ // Check if it's too late to send the next packet. If it is, then advance
+ // current stream position.
auto lead_time = playback_time - now;
if (lead_time < min_lead_time_) {
- SchedulePumpSamples();
- return;
+ auto new_playback_time = now + min_lead_time_;
+ auto skipped_time = new_playback_time - playback_time;
+ skipped_frames =
+ AudioTimestampHelper::TimeToFrames(skipped_time, params_.sample_rate());
+ media_pos_frames_ += skipped_frames;
+ playback_time += skipped_time;
}
int frames_filled;
@@ -437,7 +423,7 @@ void FuchsiaAudioOutputDevice::PumpSamples(base::TimeTicks playback_time,
if (!callback_)
return;
- frames_filled = callback_->Render(playback_time - now, now, frames_skipped,
+ frames_filled = callback_->Render(playback_time - now, now, skipped_frames,
audio_bus_.get());
}
@@ -489,4 +475,4 @@ void FuchsiaAudioOutputDevice::ReportError() {
}
}
-} // namespace media \ No newline at end of file
+} // namespace media
diff --git a/chromium/media/fuchsia/audio/fuchsia_audio_output_device.h b/chromium/media/fuchsia/audio/fuchsia_audio_output_device.h
index a08617ade56..985aac96c0f 100644
--- a/chromium/media/fuchsia/audio/fuchsia_audio_output_device.h
+++ b/chromium/media/fuchsia/audio/fuchsia_audio_output_device.h
@@ -16,6 +16,7 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "media/base/audio_renderer_sink.h"
+#include "media/base/media_export.h"
namespace base {
class SingleThreadTaskRunner;
@@ -31,7 +32,7 @@ namespace media {
// All work is performed on the TaskRunner passed to Create(). It must be an IO
// thread to allow FIDL usage. AudioRendererSink can be used on a different
// thread.
-class FuchsiaAudioOutputDevice : public AudioRendererSink {
+class MEDIA_EXPORT FuchsiaAudioOutputDevice : public AudioRendererSink {
public:
static scoped_refptr<FuchsiaAudioOutputDevice> Create(
fidl::InterfaceHandle<fuchsia::media::AudioConsumer>
@@ -95,7 +96,7 @@ class FuchsiaAudioOutputDevice : public AudioRendererSink {
// Pumps a single packet to AudioConsumer and calls SchedulePumpSamples() to
// pump the next packet.
- void PumpSamples(base::TimeTicks playback_time, int frames_skipped);
+ void PumpSamples(base::TimeTicks playback_time);
// Callback for StreamSink::SendPacket().
void OnStreamSendDone(size_t buffer_index);
diff --git a/chromium/media/fuchsia/audio/fuchsia_audio_output_device_test.cc b/chromium/media/fuchsia/audio/fuchsia_audio_output_device_test.cc
index d058dc76f68..1b8c6eb51af 100644
--- a/chromium/media/fuchsia/audio/fuchsia_audio_output_device_test.cc
+++ b/chromium/media/fuchsia/audio/fuchsia_audio_output_device_test.cc
@@ -98,8 +98,8 @@ class FuchsiaAudioOutputDeviceTest : public testing::Test {
}
void CallPumpSamples() {
- output_device_->PumpSamples(
- base::TimeTicks::Now() + base::TimeDelta::FromMilliseconds(200), 0);
+ output_device_->PumpSamples(base::TimeTicks::Now() +
+ base::TimeDelta::FromMilliseconds(200));
}
void ValidatePresentationTime() {
@@ -194,8 +194,8 @@ TEST_F(FuchsiaAudioOutputDeviceTest, Underflow) {
// Advance time by 100ms, causing some frames to be skipped.
task_environment_.AdvanceClock(kPeriod * 10);
task_environment_.RunUntilIdle();
- EXPECT_EQ(renderer_.frames_rendered(), kFramesPerPeriod);
- EXPECT_EQ(renderer_.frames_skipped(), kFramesPerPeriod * 9);
+ EXPECT_EQ(renderer_.frames_rendered(), kFramesPerPeriod * 3);
+ EXPECT_EQ(renderer_.frames_skipped(), kFramesPerPeriod * 7);
renderer_.reset_frames_rendered();
ValidatePresentationTime();
diff --git a/chromium/media/fuchsia/audio/fuchsia_audio_renderer.cc b/chromium/media/fuchsia/audio/fuchsia_audio_renderer.cc
index 871c566c89f..20d98f09c31 100644
--- a/chromium/media/fuchsia/audio/fuchsia_audio_renderer.cc
+++ b/chromium/media/fuchsia/audio/fuchsia_audio_renderer.cc
@@ -12,9 +12,12 @@
#include "base/sequenced_task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "media/base/cdm_context.h"
#include "media/base/decoder_buffer.h"
#include "media/base/renderer_client.h"
-#include "media/filters/decrypting_demuxer_stream.h"
+#include "media/fuchsia/cdm/fuchsia_cdm_context.h"
+#include "media/fuchsia/common/decrypting_sysmem_buffer_stream.h"
+#include "media/fuchsia/common/passthrough_sysmem_buffer_stream.h"
namespace media {
@@ -22,7 +25,7 @@ namespace {
// nullopt is returned in case the codec is not supported. nullptr is returned
// for uncompressed PCM streams.
-base::Optional<std::unique_ptr<fuchsia::media::Compression>>
+absl::optional<std::unique_ptr<fuchsia::media::Compression>>
GetFuchsiaCompressionFromDecoderConfig(AudioDecoderConfig config) {
auto compression = std::make_unique<fuchsia::media::Compression>();
switch (config.codec()) {
@@ -46,7 +49,7 @@ GetFuchsiaCompressionFromDecoderConfig(AudioDecoderConfig config) {
break;
default:
- return base::nullopt;
+ return absl::nullopt;
}
if (!config.extra_data().empty()) {
@@ -56,7 +59,7 @@ GetFuchsiaCompressionFromDecoderConfig(AudioDecoderConfig config) {
return std::move(compression);
}
-base::Optional<fuchsia::media::AudioSampleFormat>
+absl::optional<fuchsia::media::AudioSampleFormat>
GetFuchsiaSampleFormatFromSampleFormat(SampleFormat sample_format) {
switch (sample_format) {
case kSampleFormatU8:
@@ -69,7 +72,7 @@ GetFuchsiaSampleFormatFromSampleFormat(SampleFormat sample_format) {
return fuchsia::media::AudioSampleFormat::FLOAT;
default:
- return base::nullopt;
+ return absl::nullopt;
}
}
@@ -85,12 +88,10 @@ constexpr size_t kNumBuffers = 16;
FuchsiaAudioRenderer::FuchsiaAudioRenderer(
MediaLog* media_log,
fidl::InterfaceHandle<fuchsia::media::AudioConsumer> audio_consumer_handle)
- : media_log_(media_log),
- audio_consumer_handle_(std::move(audio_consumer_handle)) {
+ : audio_consumer_handle_(std::move(audio_consumer_handle)) {
DETACH_FROM_THREAD(thread_checker_);
}
-
FuchsiaAudioRenderer::~FuchsiaAudioRenderer() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
@@ -105,6 +106,7 @@ void FuchsiaAudioRenderer::Initialize(DemuxerStream* stream,
DCHECK(!init_cb_);
init_cb_ = std::move(init_cb);
+ demuxer_stream_ = stream;
client_ = client;
audio_consumer_.Bind(std::move(audio_consumer_handle_));
@@ -118,8 +120,6 @@ void FuchsiaAudioRenderer::Initialize(DemuxerStream* stream,
audio_consumer_.events().OnEndOfStream = [this]() { OnEndOfStream(); };
RequestAudioConsumerStatus();
- InitializeStreamSink(stream->audio_decoder_config());
-
// AAC streams require bitstream conversion. Without it the demuxer may
// produce decoded stream without ADTS headers which are required for AAC
// streams in AudioConsumer.
@@ -128,21 +128,27 @@ void FuchsiaAudioRenderer::Initialize(DemuxerStream* stream,
stream->EnableBitstreamConverter();
}
- // DecryptingDemuxerStream handles both encrypted and clear streams, so
- // initialize it long as we have cdm_context.
- if (cdm_context) {
- WaitingCB waiting_cb = base::BindRepeating(&RendererClient::OnWaiting,
- base::Unretained(client_));
- decrypting_demuxer_stream_ = std::make_unique<DecryptingDemuxerStream>(
- base::ThreadTaskRunnerHandle::Get(), media_log_, waiting_cb);
- decrypting_demuxer_stream_->Initialize(
- stream, cdm_context,
- base::BindRepeating(&FuchsiaAudioRenderer::OnDecryptorInitialized,
- base::Unretained(this)));
- return;
+ if (stream->audio_decoder_config().is_encrypted()) {
+ if (!cdm_context) {
+ DLOG(ERROR) << "No cdm context for encrypted stream.";
+ OnError(AUDIO_RENDERER_ERROR);
+ return;
+ }
+
+ FuchsiaCdmContext* fuchsia_cdm = cdm_context->GetFuchsiaCdmContext();
+ if (fuchsia_cdm) {
+ sysmem_buffer_stream_ = fuchsia_cdm->CreateStreamDecryptor(false);
+ } else {
+ sysmem_buffer_stream_ = std::make_unique<DecryptingSysmemBufferStream>(
+ &sysmem_allocator_, cdm_context, Decryptor::kAudio);
+ }
+
+ } else {
+ sysmem_buffer_stream_ =
+ std::make_unique<PassthroughSysmemBufferStream>(&sysmem_allocator_);
}
- demuxer_stream_ = stream;
+ sysmem_buffer_stream_->Initialize(this, kBufferSize, kNumBuffers);
std::move(init_cb_).Run(PIPELINE_OK);
}
@@ -159,41 +165,41 @@ void FuchsiaAudioRenderer::UpdateVolume() {
volume_control_->SetVolume(volume_);
}
-void FuchsiaAudioRenderer::InitializeStreamSink(
- const AudioDecoderConfig& config) {
+void FuchsiaAudioRenderer::OnBuffersAcquired(
+ std::vector<VmoBuffer> buffers,
+ const fuchsia::sysmem::SingleBufferSettings&) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!stream_sink_);
- DCHECK(stream_sink_buffers_.empty());
- DCHECK_EQ(num_pending_packets_, 0U);
- // Allocate input buffers for the StreamSink.
- stream_sink_buffers_.resize(kNumBuffers);
- std::vector<zx::vmo> vmos_for_stream_sink;
- vmos_for_stream_sink.reserve(kNumBuffers);
- for (StreamSinkBuffer& buffer : stream_sink_buffers_) {
- zx_status_t status = zx::vmo::create(kBufferSize, 0, &buffer.vmo);
- ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create";
+ input_buffers_ = std::move(buffers);
+ InitializeStreamSink();
- constexpr char kName[] = "cr-audio-renderer";
- status =
- buffer.vmo.set_property(ZX_PROP_NAME, kName, base::size(kName) - 1);
- ZX_DCHECK(status == ZX_OK, status);
+ while (!delayed_packets_.empty()) {
+ auto packet = std::move(delayed_packets_.front());
+ delayed_packets_.pop_front();
+ SendInputPacket(std::move(packet));
+ }
- // Duplicate VMO handle to pass to AudioConsumer.
- zx::vmo readonly_vmo;
- status = buffer.vmo.duplicate(ZX_RIGHT_DUPLICATE | ZX_RIGHT_TRANSFER |
- ZX_RIGHT_READ | ZX_RIGHT_MAP |
- ZX_RIGHT_GET_PROPERTY,
- &readonly_vmo);
- ZX_CHECK(status == ZX_OK, status) << "zx_handle_duplicate";
+ if (is_at_end_of_stream_) {
+ OnSysmemBufferStreamEndOfStream();
+ }
+}
+
+void FuchsiaAudioRenderer::InitializeStreamSink() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!stream_sink_);
- vmos_for_stream_sink.push_back(std::move(readonly_vmo));
+ // Clone |buffers| to pass to StreamSink.
+ std::vector<zx::vmo> vmos_for_stream_sink;
+ vmos_for_stream_sink.reserve(input_buffers_.size());
+ for (VmoBuffer& buffer : input_buffers_) {
+ vmos_for_stream_sink.push_back(buffer.Duplicate(/*writable=*/false));
}
+ auto config = demuxer_stream_->audio_decoder_config();
auto compression = GetFuchsiaCompressionFromDecoderConfig(config);
if (!compression) {
LOG(ERROR) << "Unsupported audio codec: " << GetCodecName(config.codec());
- std::move(init_cb_).Run(AUDIO_RENDERER_ERROR);
+ OnError(AUDIO_RENDERER_ERROR);
return;
}
@@ -203,12 +209,12 @@ void FuchsiaAudioRenderer::InitializeStreamSink(
// Set sample_format for uncompressed streams.
if (!compression) {
- base::Optional<fuchsia::media::AudioSampleFormat> sample_format =
+ absl::optional<fuchsia::media::AudioSampleFormat> sample_format =
GetFuchsiaSampleFormatFromSampleFormat(config.sample_format());
if (!sample_format) {
LOG(ERROR) << "Unsupported sample format: "
<< SampleFormatToString(config.sample_format());
- std::move(init_cb_).Run(AUDIO_RENDERER_ERROR);
+ OnError(AUDIO_RENDERER_ERROR);
return;
}
stream_type.sample_format = sample_format.value();
@@ -221,6 +227,11 @@ void FuchsiaAudioRenderer::InitializeStreamSink(
audio_consumer_->CreateStreamSink(
std::move(vmos_for_stream_sink), std::move(stream_type),
std::move(compression).value(), stream_sink_.NewRequest());
+
+ if (GetPlaybackState() == PlaybackState::kStartPending)
+ StartAudioConsumer();
+
+ ScheduleReadDemuxerStream();
}
TimeSource* FuchsiaAudioRenderer::GetTimeSource() {
@@ -231,12 +242,15 @@ void FuchsiaAudioRenderer::Flush(base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
FlushInternal();
+ renderer_started_ = false;
+
std::move(callback).Run();
}
void FuchsiaAudioRenderer::StartPlaying() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ renderer_started_ = true;
ScheduleReadDemuxerStream();
}
@@ -248,7 +262,7 @@ void FuchsiaAudioRenderer::SetVolume(float volume) {
}
void FuchsiaAudioRenderer::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
// TODO(crbug.com/1131116): Implement at some later date after we've vetted
// the API shape and usefulness outside of fuchsia.
}
@@ -260,13 +274,35 @@ void FuchsiaAudioRenderer::SetAutoplayInitiated(bool autoplay_initiated) {}
void FuchsiaAudioRenderer::StartTicking() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // If StreamSink hasn't been created yet, then delay starting AudioConsumer
+ // until StreamSink is created.
+ if (!stream_sink_) {
+ base::AutoLock lock(timeline_lock_);
+ SetPlaybackState(PlaybackState::kStartPending);
+ return;
+ }
+
+ StartAudioConsumer();
+}
+
+void FuchsiaAudioRenderer::StartAudioConsumer() {
+ DCHECK(stream_sink_);
+
fuchsia::media::AudioConsumerStartFlags flags{};
if (demuxer_stream_->liveness() == DemuxerStream::LIVENESS_LIVE) {
flags = fuchsia::media::AudioConsumerStartFlags::LOW_LATENCY;
}
- if (GetPlaybackState() != PlaybackState::kStopped) {
- audio_consumer_->Stop();
+ // Stop the AudioConsumer if it's been started.
+ switch (GetPlaybackState()) {
+ case PlaybackState::kStopped:
+ case PlaybackState::kStartPending:
+ break;
+
+ case PlaybackState::kStarting:
+ case PlaybackState::kPlaying:
+ audio_consumer_->Stop();
+ break;
}
base::TimeDelta media_pos;
@@ -384,6 +420,8 @@ void FuchsiaAudioRenderer::OnError(PipelineStatus status) {
audio_consumer_.Unbind();
stream_sink_.Unbind();
+ sysmem_buffer_stream_.reset();
+
if (init_cb_) {
std::move(init_cb_).Run(status);
} else if (client_) {
@@ -391,22 +429,6 @@ void FuchsiaAudioRenderer::OnError(PipelineStatus status) {
}
}
-void FuchsiaAudioRenderer::OnDecryptorInitialized(PipelineStatus status) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- // |init_cb_| may be cleared in OnError(), e.g. if AudioConsumer was
- // disconnected.
- if (!init_cb_) {
- return;
- }
-
- if (status == PIPELINE_OK) {
- demuxer_stream_ = decrypting_demuxer_stream_.get();
- }
-
- std::move(init_cb_).Run(status);
-}
-
void FuchsiaAudioRenderer::RequestAudioConsumerStatus() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
audio_consumer_->WatchStatus(fit::bind_member(
@@ -423,6 +445,8 @@ void FuchsiaAudioRenderer::OnAudioConsumerStatusChanged(
return;
}
+ bool reschedule_read_timer = false;
+
if (status.has_presentation_timeline()) {
if (GetPlaybackState() != PlaybackState::kStopped) {
base::AutoLock lock(timeline_lock_);
@@ -435,10 +459,11 @@ void FuchsiaAudioRenderer::OnAudioConsumerStatusChanged(
status.presentation_timeline().subject_time);
reference_delta_ = status.presentation_timeline().reference_delta;
media_delta_ = status.presentation_timeline().subject_delta;
+
+ reschedule_read_timer = true;
}
}
- bool reschedule_read_timer = false;
if (status.has_min_lead_time()) {
auto new_min_lead_time =
base::TimeDelta::FromZxDuration(status.min_lead_time());
@@ -469,21 +494,27 @@ void FuchsiaAudioRenderer::OnAudioConsumerStatusChanged(
void FuchsiaAudioRenderer::ScheduleReadDemuxerStream() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!demuxer_stream_ || read_timer_.IsRunning() || is_demuxer_read_pending_ ||
- is_at_end_of_stream_ ||
- num_pending_packets_ >= stream_sink_buffers_.size()) {
+ if (!renderer_started_ || !demuxer_stream_ || read_timer_.IsRunning() ||
+ is_demuxer_read_pending_ || is_at_end_of_stream_) {
return;
}
base::TimeDelta next_read_delay;
if (!last_packet_timestamp_.is_min()) {
- auto relative_buffer_pos = last_packet_timestamp_ - CurrentMediaTime();
-
- if (!min_lead_time_.is_zero() && relative_buffer_pos > min_lead_time_) {
- SetBufferState(BUFFERING_HAVE_ENOUGH);
- }
-
- if (!max_lead_time_.is_zero() && relative_buffer_pos > max_lead_time_) {
+ std::vector<base::TimeTicks> wall_clock_times;
+ bool is_time_moving =
+ GetWallClockTimes({last_packet_timestamp_}, &wall_clock_times);
+ base::TimeDelta relative_buffer_pos =
+ wall_clock_times[0] - base::TimeTicks::Now();
+
+ // Check if we have buffered more than |max_lead_time_|.
+ if (relative_buffer_pos >= max_lead_time_) {
+ // If playback is not active then there is no need to buffer more.
+ if (!is_time_moving)
+ return;
+
+ // If the buffer is larger than |max_lead_time_|, then the next read
+ // should be delayed.
next_read_delay = relative_buffer_pos - max_lead_time_;
}
}
@@ -523,11 +554,10 @@ void FuchsiaAudioRenderer::OnDemuxerStreamReadDone(
OnError(PIPELINE_ERROR_READ);
} else if (read_status == DemuxerStream::kConfigChanged) {
stream_sink_.Unbind();
- stream_sink_buffers_.clear();
- num_pending_packets_ = 0;
+ sysmem_buffer_stream_->Reset();
- InitializeStreamSink(demuxer_stream_->audio_decoder_config());
- ScheduleReadDemuxerStream();
+ InitializeStreamSink();
+ client_->OnAudioConfigChange(demuxer_stream_->audio_decoder_config());
} else {
DCHECK_EQ(read_status, DemuxerStream::kAborted);
}
@@ -536,71 +566,61 @@ void FuchsiaAudioRenderer::OnDemuxerStreamReadDone(
if (buffer->end_of_stream()) {
is_at_end_of_stream_ = true;
- stream_sink_->EndOfStream();
-
- // No more data is going to be buffered. Update buffering state to ensure
- // RendererImpl starts playback in case it was waiting for buffering to
- // finish.
- SetBufferState(BUFFERING_HAVE_ENOUGH);
-
- return;
- }
+ } else {
+ if (buffer->data_size() > kBufferSize) {
+ DLOG(ERROR) << "Demuxer returned buffer that is too big: "
+ << buffer->data_size();
+ OnError(AUDIO_RENDERER_ERROR);
+ return;
+ }
- if (buffer->data_size() > kBufferSize) {
- DLOG(ERROR) << "Demuxer returned buffer that is too big: "
- << buffer->data_size();
- OnError(AUDIO_RENDERER_ERROR);
- return;
+ last_packet_timestamp_ = buffer->timestamp();
+ if (buffer->duration() != kNoTimestamp)
+ last_packet_timestamp_ += buffer->duration();
}
- // Find unused buffer.
- auto it = std::find_if(
- stream_sink_buffers_.begin(), stream_sink_buffers_.end(),
- [](const StreamSinkBuffer& b) -> bool { return !b.is_used; });
-
- // ReadDemuxerStream() is not supposed to be called unless there are unused
- // buffers.
- CHECK(it != stream_sink_buffers_.end());
+ sysmem_buffer_stream_->EnqueueBuffer(std::move(buffer));
- ++num_pending_packets_;
- DCHECK_LE(num_pending_packets_, stream_sink_buffers_.size());
-
- it->is_used = true;
- zx_status_t status = it->vmo.write(buffer->data(), 0, buffer->data_size());
- ZX_CHECK(status == ZX_OK, status) << "zx_vmo_write";
+ ScheduleReadDemuxerStream();
+}
- size_t buffer_index = it - stream_sink_buffers_.begin();
+void FuchsiaAudioRenderer::SendInputPacket(
+ StreamProcessorHelper::IoPacket packet) {
+ fuchsia::media::StreamPacket stream_packet;
+ stream_packet.payload_buffer_id = packet.buffer_index();
+ stream_packet.pts = packet.timestamp().ToZxDuration();
+ stream_packet.payload_offset = packet.offset();
+ stream_packet.payload_size = packet.size();
- fuchsia::media::StreamPacket packet;
- packet.payload_buffer_id = buffer_index;
- packet.pts = buffer->timestamp().ToZxDuration();
- packet.payload_offset = 0;
- packet.payload_size = buffer->data_size();
-
- stream_sink_->SendPacket(std::move(packet), [this, buffer_index]() {
- OnStreamSendDone(buffer_index);
- });
+ stream_sink_->SendPacket(
+ std::move(stream_packet),
+ [this, packet = std::make_unique<StreamProcessorHelper::IoPacket>(
+ std::move(packet))]() mutable {
+ OnStreamSendDone(std::move(packet));
+ });
// AudioConsumer doesn't report exact time when the data is decoded, but it's
// safe to report it as decoded right away since the packet is expected to be
// decoded soon after AudioConsumer receives it.
PipelineStatistics stats;
- stats.audio_bytes_decoded = buffer->data_size();
+ stats.audio_bytes_decoded = packet.size();
client_->OnStatisticsUpdate(stats);
-
- last_packet_timestamp_ = buffer->timestamp();
-
- ScheduleReadDemuxerStream();
}
-void FuchsiaAudioRenderer::OnStreamSendDone(size_t buffer_index) {
+void FuchsiaAudioRenderer::OnStreamSendDone(
+ std::unique_ptr<StreamProcessorHelper::IoPacket> packet) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_LT(buffer_index, stream_sink_buffers_.size());
- DCHECK(stream_sink_buffers_[buffer_index].is_used);
- stream_sink_buffers_[buffer_index].is_used = false;
- DCHECK_GT(num_pending_packets_, 0U);
- --num_pending_packets_;
+ // Check if we need to update buffering state after sending more than
+ // |min_lead_time_| to the AudioConsumer.
+ if (buffer_state_ == BUFFERING_HAVE_NOTHING) {
+ std::vector<base::TimeTicks> wall_clock_times;
+ GetWallClockTimes({packet->timestamp()}, &wall_clock_times);
+ base::TimeDelta relative_buffer_pos =
+ wall_clock_times[0] - base::TimeTicks::Now();
+ if (relative_buffer_pos >= min_lead_time_)
+ SetBufferState(BUFFERING_HAVE_ENOUGH);
+ }
ScheduleReadDemuxerStream();
}
@@ -617,7 +637,9 @@ void FuchsiaAudioRenderer::FlushInternal() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(GetPlaybackState() == PlaybackState::kStopped || is_at_end_of_stream_);
- stream_sink_->DiscardAllPacketsNoReply();
+ if (stream_sink_)
+ stream_sink_->DiscardAllPacketsNoReply();
+
SetBufferState(BUFFERING_HAVE_NOTHING);
last_packet_timestamp_ = base::TimeDelta::Min();
read_timer_.Stop();
@@ -655,4 +677,64 @@ base::TimeDelta FuchsiaAudioRenderer::CurrentMediaTimeLocked() {
media_delta_ / reference_delta_;
}
+void FuchsiaAudioRenderer::OnSysmemBufferStreamBufferCollectionToken(
+ fuchsia::sysmem::BufferCollectionTokenPtr token) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ // Drop old buffers.
+ input_buffers_.clear();
+ stream_sink_.Unbind();
+
+ // Acquire buffers for the new buffer collection.
+ input_buffer_collection_ =
+ sysmem_allocator_.BindSharedCollection(std::move(token));
+ fuchsia::sysmem::BufferCollectionConstraints buffer_constraints =
+ VmoBuffer::GetRecommendedConstraints(kNumBuffers, kBufferSize,
+ /*writable=*/false);
+ input_buffer_collection_->Initialize(std::move(buffer_constraints),
+ "CrAudioRenderer");
+ input_buffer_collection_->AcquireBuffers(base::BindOnce(
+ &FuchsiaAudioRenderer::OnBuffersAcquired, base::Unretained(this)));
+}
+
+void FuchsiaAudioRenderer::OnSysmemBufferStreamOutputPacket(
+ StreamProcessorHelper::IoPacket packet) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (stream_sink_) {
+ SendInputPacket(std::move(packet));
+ } else {
+ // The packet will be sent after StreamSink is connected.
+ delayed_packets_.push_back(std::move(packet));
+ }
+
+ ScheduleReadDemuxerStream();
+}
+
+void FuchsiaAudioRenderer::OnSysmemBufferStreamEndOfStream() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(is_at_end_of_stream_);
+
+ // Stream sink is not bound yet, don't send EOS.
+ if (!stream_sink_)
+ return;
+
+ stream_sink_->EndOfStream();
+
+ // No more data is going to be buffered. Update buffering state to ensure
+ // RendererImpl starts playback in case it was waiting for buffering to
+ // finish.
+ SetBufferState(BUFFERING_HAVE_ENOUGH);
+}
+
+void FuchsiaAudioRenderer::OnSysmemBufferStreamError() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ OnError(AUDIO_RENDERER_ERROR);
+}
+
+void FuchsiaAudioRenderer::OnSysmemBufferStreamNoKey() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ client_->OnWaiting(WaitingReason::kNoDecryptionKey);
+}
+
} // namespace media
diff --git a/chromium/media/fuchsia/audio/fuchsia_audio_renderer.h b/chromium/media/fuchsia/audio/fuchsia_audio_renderer.h
index 65dd995cd9e..78a8a356a74 100644
--- a/chromium/media/fuchsia/audio/fuchsia_audio_renderer.h
+++ b/chromium/media/fuchsia/audio/fuchsia_audio_renderer.h
@@ -13,17 +13,22 @@
#include "media/base/audio_renderer.h"
#include "media/base/buffering_state.h"
#include "media/base/demuxer_stream.h"
+#include "media/base/media_export.h"
#include "media/base/time_source.h"
+#include "media/fuchsia/common/sysmem_buffer_stream.h"
+#include "media/fuchsia/common/sysmem_client.h"
+#include "media/fuchsia/common/vmo_buffer.h"
namespace media {
-class DecryptingDemuxerStream;
class MediaLog;
// AudioRenderer implementation that output audio to AudioConsumer interface on
// Fuchsia. Unlike the default AudioRendererImpl it doesn't decode audio and
// sends encoded stream directly to AudioConsumer provided by the platform.
-class FuchsiaAudioRenderer : public AudioRenderer, public TimeSource {
+class MEDIA_EXPORT FuchsiaAudioRenderer : public AudioRenderer,
+ public TimeSource,
+ public SysmemBufferStream::Sink {
public:
FuchsiaAudioRenderer(MediaLog* media_log,
fidl::InterfaceHandle<fuchsia::media::AudioConsumer>
@@ -39,7 +44,7 @@ class FuchsiaAudioRenderer : public AudioRenderer, public TimeSource {
void Flush(base::OnceClosure callback) final;
void StartPlaying() final;
void SetVolume(float volume) final;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) final;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) final;
void SetPreservesPitch(bool preserves_pitch) final;
void SetAutoplayInitiated(bool autoplay_initiated) final;
@@ -56,6 +61,11 @@ class FuchsiaAudioRenderer : public AudioRenderer, public TimeSource {
enum class PlaybackState {
kStopped,
+ // StartTicking() was called, but sysmem buffers haven't been allocated yet.
+ // AudioConsumer::Start() will be called after CreateStreamSink() once the
+ // sysmem buffers are allocated.
+ kStartPending,
+
// We've called Start(), but haven't received updated state. |start_time_|
// should not be used yet.
kStarting,
@@ -65,12 +75,7 @@ class FuchsiaAudioRenderer : public AudioRenderer, public TimeSource {
kPlaying,
};
- // Struct used to store state of an input buffer shared with the
- // |stream_sink_|.
- struct StreamSinkBuffer {
- zx::vmo vmo;
- bool is_used = false;
- };
+ void StartAudioConsumer();
// Returns current PlaybackState. Should be used only on the main thread.
PlaybackState GetPlaybackState() NO_THREAD_SAFETY_ANALYSIS;
@@ -88,12 +93,14 @@ class FuchsiaAudioRenderer : public AudioRenderer, public TimeSource {
// |volume_|.
void UpdateVolume();
+ // Callback for input_buffer_collection_.AcquireBuffers().
+ void OnBuffersAcquired(
+ std::vector<VmoBuffer> buffers,
+ const fuchsia::sysmem::SingleBufferSettings& buffer_settings);
+
// Initializes |stream_sink_|. Called during initialization and every time
// configuration changes.
- void InitializeStreamSink(const AudioDecoderConfig& config);
-
- // Callback for DecryptingDemuxerStream::Initialize().
- void OnDecryptorInitialized(PipelineStatus status);
+ void InitializeStreamSink();
// Helpers to receive AudioConsumerStatus from the |audio_consumer_|.
void RequestAudioConsumerStatus();
@@ -105,8 +112,12 @@ class FuchsiaAudioRenderer : public AudioRenderer, public TimeSource {
void OnDemuxerStreamReadDone(DemuxerStream::Status status,
scoped_refptr<DecoderBuffer> buffer);
+ // Sends the specified packet to |stream_sink_|.
+ void SendInputPacket(StreamProcessorHelper::IoPacket packet);
+
// Result handler for StreamSink::SendPacket().
- void OnStreamSendDone(size_t buffer_index);
+ void OnStreamSendDone(
+ std::unique_ptr<StreamProcessorHelper::IoPacket> packet);
// Updates buffer state and notifies the |client_| if necessary.
void SetBufferState(BufferingState buffer_state);
@@ -132,7 +143,14 @@ class FuchsiaAudioRenderer : public AudioRenderer, public TimeSource {
base::TimeDelta CurrentMediaTimeLocked()
EXCLUSIVE_LOCKS_REQUIRED(timeline_lock_);
- MediaLog* const media_log_;
+ // SysmemBufferStream::Sink implementation.
+ void OnSysmemBufferStreamBufferCollectionToken(
+ fuchsia::sysmem::BufferCollectionTokenPtr token) override;
+ void OnSysmemBufferStreamOutputPacket(
+ StreamProcessorHelper::IoPacket packet) override;
+ void OnSysmemBufferStreamEndOfStream() override;
+ void OnSysmemBufferStreamError() override;
+ void OnSysmemBufferStreamNoKey() override;
// Handle for |audio_consumer_|. It's stored here until Initialize() is
// called.
@@ -153,20 +171,32 @@ class FuchsiaAudioRenderer : public AudioRenderer, public TimeSource {
// Initialize() completion callback.
PipelineStatusCallback init_cb_;
- std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream_;
+ // Indicates that StartPlaying() has been called. Note that playback doesn't
+ // start until TimeSource::StartTicking() is called.
+ bool renderer_started_ = false;
BufferingState buffer_state_ = BUFFERING_HAVE_NOTHING;
base::TimeDelta last_packet_timestamp_ = base::TimeDelta::Min();
base::OneShotTimer read_timer_;
- std::vector<StreamSinkBuffer> stream_sink_buffers_;
- size_t num_pending_packets_ = 0u;
+ SysmemAllocatorClient sysmem_allocator_{"CrFuchsiaAudioRenderer"};
+ std::unique_ptr<SysmemCollectionClient> input_buffer_collection_;
+
+ std::unique_ptr<SysmemBufferStream> sysmem_buffer_stream_;
+
+ // VmoBuffers for the buffers |input_buffer_collection_|.
+ std::vector<VmoBuffer> input_buffers_;
+
+ // Packets produced before the |stream_sink_| is connected. They are sent as
+ // soon as input buffers are acquired and |stream_sink_| is connected in
+ // OnBuffersAcquired().
+ std::list<StreamProcessorHelper::IoPacket> delayed_packets_;
- // Lead time range requested by the |audio_consumer_|. Initialized to 0 until
- // the initial AudioConsumerStatus is received.
- base::TimeDelta min_lead_time_;
- base::TimeDelta max_lead_time_;
+ // Lead time range requested by the |audio_consumer_|. Initialized to the
+ // [100ms, 500ms] until the initial AudioConsumerStatus is received.
+ base::TimeDelta min_lead_time_ = base::TimeDelta::FromMilliseconds(100);
+ base::TimeDelta max_lead_time_ = base::TimeDelta::FromMilliseconds(500);
// Set to true after we've received end-of-stream from the |demuxer_stream_|.
// The renderer may be restarted after Flush().
diff --git a/chromium/media/fuchsia/audio/fuchsia_audio_renderer_test.cc b/chromium/media/fuchsia/audio/fuchsia_audio_renderer_test.cc
new file mode 100644
index 00000000000..986856ce78a
--- /dev/null
+++ b/chromium/media/fuchsia/audio/fuchsia_audio_renderer_test.cc
@@ -0,0 +1,1010 @@
+// Copyright 2021 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 "media/fuchsia/audio/fuchsia_audio_renderer.h"
+
+#include <fuchsia/media/audio/cpp/fidl_test_base.h>
+#include <fuchsia/media/cpp/fidl_test_base.h>
+#include <lib/fidl/cpp/binding.h>
+
+#include "base/containers/queue.h"
+#include "base/logging.h"
+#include "base/test/bind.h"
+#include "base/test/task_environment.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "media/base/cdm_context.h"
+#include "media/base/decoder_buffer.h"
+#include "media/base/renderer_client.h"
+#include "media/fuchsia/cdm/fuchsia_cdm_context.h"
+#include "media/fuchsia/common/passthrough_sysmem_buffer_stream.h"
+#include "media/fuchsia/common/sysmem_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace media {
+
+namespace {
+
+constexpr int kDefaultSampleRate = 48000;
+constexpr base::TimeDelta kPacketDuration =
+ base::TimeDelta::FromMilliseconds(20);
+constexpr base::TimeDelta kMinLeadTime = base::TimeDelta::FromMilliseconds(100);
+constexpr base::TimeDelta kMaxLeadTime = base::TimeDelta::FromMilliseconds(500);
+const base::TimeDelta kTimeStep = base::TimeDelta::FromMilliseconds(2);
+
+class TestDemuxerStream : public DemuxerStream {
+ public:
+ struct ReadResult {
+ explicit ReadResult(scoped_refptr<DecoderBuffer> buffer) : buffer(buffer) {}
+ explicit ReadResult(const AudioDecoderConfig& config) : config(config) {}
+
+ Status status;
+ absl::optional<AudioDecoderConfig> config;
+ scoped_refptr<DecoderBuffer> buffer;
+ };
+
+ explicit TestDemuxerStream(const AudioDecoderConfig& config)
+ : config_(config) {}
+
+ ~TestDemuxerStream() override {}
+
+ void QueueReadResult(ReadResult read_result) {
+ CHECK(read_result.config.has_value() == !read_result.buffer);
+ read_queue_.push(std::move(read_result));
+ SatisfyRead();
+ }
+
+ void DiscardQueueAndAbortRead() {
+ while (!read_queue_.empty())
+ read_queue_.pop();
+ if (read_cb_)
+ std::move(read_cb_).Run(kAborted, nullptr);
+ }
+
+ bool is_read_pending() const { return !!read_cb_; }
+
+ // DemuxerStream implementation.
+ void Read(ReadCB read_cb) override {
+ read_cb_ = std::move(read_cb);
+ SatisfyRead();
+ }
+ AudioDecoderConfig audio_decoder_config() override { return config_; }
+ VideoDecoderConfig video_decoder_config() override {
+ NOTREACHED();
+ return VideoDecoderConfig();
+ }
+ Type type() const override { return AUDIO; }
+ Liveness liveness() const override { return LIVENESS_RECORDED; }
+ bool SupportsConfigChanges() override { return true; }
+
+ private:
+ void SatisfyRead() {
+ if (read_queue_.empty() || !read_cb_)
+ return;
+
+ auto result = std::move(read_queue_.front());
+ read_queue_.pop();
+
+ Status status;
+ if (result.config) {
+ config_ = result.config.value();
+ status = kConfigChanged;
+ } else {
+ status = kOk;
+ }
+
+ std::move(read_cb_).Run(status, result.buffer);
+ }
+
+ AudioDecoderConfig config_;
+ ReadCB read_cb_;
+
+ base::queue<ReadResult> read_queue_;
+};
+
+class TestStreamSink : public fuchsia::media::testing::StreamSink_TestBase {
+ public:
+ TestStreamSink(
+ std::vector<zx::vmo> buffers,
+ fuchsia::media::AudioStreamType stream_type,
+ std::unique_ptr<fuchsia::media::Compression> compression,
+ fidl::InterfaceRequest<fuchsia::media::StreamSink> stream_sink_request)
+ : binding_(this, std::move(stream_sink_request)),
+ buffers_(std::move(buffers)),
+ stream_type_(std::move(stream_type)),
+ compression_(std::move(compression)) {}
+
+ const std::vector<zx::vmo>& buffers() const { return buffers_; }
+ const fuchsia::media::AudioStreamType& stream_type() const {
+ return stream_type_;
+ }
+ const fuchsia::media::Compression* compression() const {
+ return compression_.get();
+ }
+
+ std::vector<fuchsia::media::StreamPacket>* received_packets() {
+ return &received_packets_;
+ }
+
+ std::vector<fuchsia::media::StreamPacket>* discarded_packets() {
+ return &discarded_packets_;
+ }
+
+ bool received_end_of_stream() const { return received_end_of_stream_; }
+
+ // fuchsia::media::StreamSink overrides.
+ void SendPacket(fuchsia::media::StreamPacket packet,
+ SendPacketCallback callback) override {
+ EXPECT_FALSE(received_end_of_stream_);
+ received_packets_.push_back(std::move(packet));
+ callback();
+ }
+ void EndOfStream() override { received_end_of_stream_ = true; }
+ void DiscardAllPackets(DiscardAllPacketsCallback callback) override {
+ DiscardAllPacketsNoReply();
+ callback();
+ }
+ void DiscardAllPacketsNoReply() override {
+ std::move(std::begin(received_packets_), std::end(received_packets_),
+ std::back_inserter(discarded_packets_));
+ received_packets_.clear();
+ }
+
+ // Other methods are not expected to be called.
+ void NotImplemented_(const std::string& name) final {
+ FAIL() << ": " << name;
+ }
+
+ private:
+ fidl::Binding<fuchsia::media::StreamSink> binding_;
+
+ std::vector<zx::vmo> buffers_;
+ fuchsia::media::AudioStreamType stream_type_;
+ std::unique_ptr<fuchsia::media::Compression> compression_;
+
+ std::vector<fuchsia::media::StreamPacket> received_packets_;
+ std::vector<fuchsia::media::StreamPacket> discarded_packets_;
+
+ bool received_end_of_stream_ = false;
+};
+
+class TestAudioConsumer
+ : public fuchsia::media::testing::AudioConsumer_TestBase,
+ public fuchsia::media::audio::testing::VolumeControl_TestBase {
+ public:
+ explicit TestAudioConsumer(
+ fidl::InterfaceRequest<fuchsia::media::AudioConsumer> request)
+ : binding_(this, std::move(request)), volume_control_binding_(this) {}
+
+ std::unique_ptr<TestStreamSink> TakeStreamSink() {
+ return std::move(stream_sink_);
+ }
+
+ std::unique_ptr<TestStreamSink> WaitStreamSinkConnected() {
+ if (!stream_sink_) {
+ base::RunLoop run_loop;
+ wait_stream_sink_created_loop_ = &run_loop;
+ run_loop.Run();
+ wait_stream_sink_created_loop_ = nullptr;
+ }
+ EXPECT_TRUE(stream_sink_);
+ return TakeStreamSink();
+ }
+
+ void WaitStarted() {
+ if (started_)
+ return;
+
+ base::RunLoop run_loop;
+ wait_started_loop_ = &run_loop;
+ run_loop.Run();
+ wait_started_loop_ = nullptr;
+ EXPECT_TRUE(started_);
+ }
+
+ void UpdateStatus(absl::optional<base::TimeTicks> reference_time,
+ absl::optional<base::TimeDelta> media_time) {
+ fuchsia::media::AudioConsumerStatus status;
+ if (reference_time) {
+ CHECK(media_time);
+
+ fuchsia::media::TimelineFunction timeline;
+ timeline.reference_time = reference_time->ToZxTime();
+ timeline.subject_time = media_time->ToZxDuration();
+ timeline.reference_delta = 1000;
+ timeline.subject_delta = static_cast<int>(playback_rate_ * 1000.0);
+ status.set_presentation_timeline(std::move(timeline));
+ }
+
+ status.set_min_lead_time(kMinLeadTime.ToZxDuration());
+ status.set_max_lead_time(kMaxLeadTime.ToZxDuration());
+ status_update_ = std::move(status);
+
+ if (status_callback_)
+ CallStatusCallback();
+ }
+
+ void SignalEndOfStream() { binding_.events().OnEndOfStream(); }
+
+ bool started() const { return started_; }
+ base::TimeDelta start_media_time() const { return start_media_time_; }
+ float playback_rate() const { return playback_rate_; }
+ float volume() const { return volume_; }
+
+ // fuchsia::media::AudioConsumer overrides.
+ void CreateStreamSink(
+ std::vector<zx::vmo> buffers,
+ fuchsia::media::AudioStreamType stream_type,
+ std::unique_ptr<fuchsia::media::Compression> compression,
+ fidl::InterfaceRequest<fuchsia::media::StreamSink> stream_sink_request)
+ override {
+ create_stream_sink_called_ = true;
+ stream_sink_ = std::make_unique<TestStreamSink>(
+ std::move(buffers), std::move(stream_type), std::move(compression),
+ std::move(stream_sink_request));
+ if (wait_stream_sink_created_loop_)
+ wait_stream_sink_created_loop_->Quit();
+ }
+
+ void Start(fuchsia::media::AudioConsumerStartFlags flags,
+ int64_t reference_time,
+ int64_t media_time) override {
+ EXPECT_TRUE(create_stream_sink_called_);
+ EXPECT_FALSE(started_);
+ EXPECT_EQ(reference_time, fuchsia::media::NO_TIMESTAMP);
+ started_ = true;
+ start_media_time_ = base::TimeDelta::FromZxDuration(media_time);
+ if (wait_started_loop_)
+ wait_started_loop_->Quit();
+ }
+
+ void Stop() override {
+ EXPECT_TRUE(started_);
+ started_ = false;
+ }
+
+ void SetRate(float rate) override { playback_rate_ = rate; }
+
+ void BindVolumeControl(
+ fidl::InterfaceRequest<fuchsia::media::audio::VolumeControl>
+ volume_control_request) override {
+ volume_control_binding_.Bind(std::move(volume_control_request));
+ }
+
+ void WatchStatus(WatchStatusCallback callback) override {
+ EXPECT_FALSE(!!status_callback_);
+
+ status_callback_ = std::move(callback);
+
+ if (status_update_) {
+ CallStatusCallback();
+ }
+ }
+
+ // fuchsia::media::audio::VolumeControl overrides.
+ void SetVolume(float volume) override { volume_ = volume; }
+
+ // Other methods are not expected to be called.
+ void NotImplemented_(const std::string& name) final {
+ FAIL() << ": " << name;
+ }
+
+ private:
+ void CallStatusCallback() {
+ EXPECT_TRUE(status_callback_);
+ EXPECT_TRUE(status_update_);
+
+ std::move(status_callback_)(std::move(status_update_.value()));
+ status_callback_ = {};
+ status_update_ = absl::nullopt;
+ }
+
+ fidl::Binding<fuchsia::media::AudioConsumer> binding_;
+ fidl::Binding<fuchsia::media::audio::VolumeControl> volume_control_binding_;
+ std::unique_ptr<TestStreamSink> stream_sink_;
+
+ base::RunLoop* wait_stream_sink_created_loop_ = nullptr;
+ base::RunLoop* wait_started_loop_ = nullptr;
+
+ bool create_stream_sink_called_ = false;
+
+ WatchStatusCallback status_callback_;
+ absl::optional<fuchsia::media::AudioConsumerStatus> status_update_;
+
+ bool started_ = false;
+ base::TimeDelta start_media_time_;
+
+ float playback_rate_ = 1.0;
+
+ float volume_ = 1.0;
+};
+
+class TestRendererClient : public RendererClient {
+ public:
+ TestRendererClient() = default;
+ ~TestRendererClient() {
+ EXPECT_EQ(expected_error_, PIPELINE_OK);
+ EXPECT_FALSE(expect_eos_);
+ }
+
+ void ExpectError(PipelineStatus expected_error) {
+ EXPECT_EQ(expected_error_, PIPELINE_OK);
+ expected_error_ = expected_error;
+ }
+
+ void ExpectEos() {
+ EXPECT_FALSE(expect_eos_);
+ expect_eos_ = true;
+ }
+
+ BufferingState buffering_state() const { return buffering_state_; }
+
+ absl::optional<AudioDecoderConfig> last_config_change() const {
+ return last_config_change_;
+ }
+
+ // RendererClient implementation.
+ void OnError(PipelineStatus status) override {
+ EXPECT_EQ(status, expected_error_);
+ EXPECT_FALSE(have_error_);
+ have_error_ = true;
+ expected_error_ = PIPELINE_OK;
+ }
+
+ void OnEnded() override {
+ EXPECT_TRUE(expect_eos_);
+ expect_eos_ = false;
+ }
+
+ void OnStatisticsUpdate(const PipelineStatistics& stats) override {
+ bytes_decoded_ += stats.audio_bytes_decoded;
+ }
+
+ void OnBufferingStateChange(BufferingState state,
+ BufferingStateChangeReason reason) override {
+ buffering_state_ = state;
+ }
+
+ void OnWaiting(WaitingReason reason) override {}
+ void OnAudioConfigChange(const AudioDecoderConfig& config) override {
+ last_config_change_ = config;
+ }
+ void OnVideoConfigChange(const VideoDecoderConfig& config) override {
+ FAIL();
+ }
+ void OnVideoNaturalSizeChange(const gfx::Size& size) override { FAIL(); }
+ void OnVideoOpacityChange(bool opaque) override { FAIL(); }
+ void OnVideoFrameRateChange(absl::optional<int> fps) override { FAIL(); }
+
+ private:
+ PipelineStatus expected_error_ = PIPELINE_OK;
+ bool have_error_ = false;
+ bool expect_eos_ = false;
+ BufferingState buffering_state_ = BUFFERING_HAVE_NOTHING;
+ size_t bytes_decoded_ = 0;
+ absl::optional<AudioDecoderConfig> last_config_change_;
+};
+
+// SysmemBufferStream that asynchronously decouples buffer production from
+// buffer consumption. Used to simulate stream decryptor.
+class AsyncSysmemBufferStream : public SysmemBufferStream {
+ public:
+ AsyncSysmemBufferStream();
+ ~AsyncSysmemBufferStream() override;
+
+ AsyncSysmemBufferStream(const AsyncSysmemBufferStream&) = delete;
+ AsyncSysmemBufferStream& operator=(const AsyncSysmemBufferStream&) = delete;
+
+ // SysmemBufferStream implementation:
+ void Initialize(Sink* sink,
+ size_t min_buffer_size,
+ size_t min_buffer_count) override;
+ void EnqueueBuffer(scoped_refptr<DecoderBuffer> buffer) override;
+ void Reset() override;
+
+ private:
+ void DoEnqueueBuffer(scoped_refptr<DecoderBuffer> buffer);
+
+ SysmemAllocatorClient sysmem_allocator_;
+ PassthroughSysmemBufferStream passthrough_stream_;
+
+ bool is_at_end_of_stream_ = false;
+
+ base::WeakPtrFactory<AsyncSysmemBufferStream> weak_factory_{this};
+};
+
+AsyncSysmemBufferStream::AsyncSysmemBufferStream()
+ : sysmem_allocator_("AsyncSysmemBufferStream"),
+ passthrough_stream_(&sysmem_allocator_) {}
+
+AsyncSysmemBufferStream::~AsyncSysmemBufferStream() = default;
+
+void AsyncSysmemBufferStream::Initialize(Sink* sink,
+ size_t min_buffer_size,
+ size_t min_buffer_count) {
+ passthrough_stream_.Initialize(sink, min_buffer_size, min_buffer_count);
+}
+
+void AsyncSysmemBufferStream::EnqueueBuffer(
+ scoped_refptr<DecoderBuffer> buffer) {
+ if (buffer->end_of_stream()) {
+ EXPECT_FALSE(is_at_end_of_stream_);
+ is_at_end_of_stream_ = true;
+ }
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(&AsyncSysmemBufferStream::DoEnqueueBuffer,
+ weak_factory_.GetWeakPtr(), std::move(buffer)));
+}
+
+void AsyncSysmemBufferStream::Reset() {
+ passthrough_stream_.Reset();
+
+ // Drop pending DoEnqueueBuffer tasks.
+ weak_factory_.InvalidateWeakPtrs();
+
+ is_at_end_of_stream_ = false;
+}
+
+void AsyncSysmemBufferStream::DoEnqueueBuffer(
+ scoped_refptr<DecoderBuffer> buffer) {
+ passthrough_stream_.EnqueueBuffer(std::move(buffer));
+}
+
+class TestFuchsiaCdmContext : public CdmContext, public FuchsiaCdmContext {
+ public:
+ // CdmContext overrides.
+ FuchsiaCdmContext* GetFuchsiaCdmContext() override { return this; }
+
+ // FuchsiaCdmContext implementation.
+ std::unique_ptr<SysmemBufferStream> CreateStreamDecryptor(
+ bool secure_mode) override {
+ return std::make_unique<AsyncSysmemBufferStream>();
+ }
+};
+
+} // namespace
+
+struct RendererTestConfig {
+ bool simulate_fuchsia_cdm;
+};
+
+class FuchsiaAudioRendererTest
+ : public testing::Test,
+ public testing::WithParamInterface<RendererTestConfig> {
+ public:
+ FuchsiaAudioRendererTest() = default;
+ ~FuchsiaAudioRendererTest() override = default;
+
+ void CreateUninitializedRenderer();
+ void CreateTestDemuxerStream();
+ void InitializeRenderer();
+ void CreateAndInitializeRenderer();
+ void ProduceDemuxerPacket(base::TimeDelta duration);
+ void FillDemuxerStream(base::TimeDelta end_pos);
+ void FillBuffer();
+ void StartPlayback(base::TimeDelta start_time = base::TimeDelta());
+ void CheckGetWallClockTimes(absl::optional<base::TimeDelta> media_timestamp,
+ base::TimeTicks expected_wall_clock,
+ bool is_time_moving);
+
+ // Starts playback from |start_time| at the specified |playback_rate| and
+ // verifies that the clock works correctly.
+ void StartPlaybackAndVerifyClock(base::TimeDelta start_time,
+ float playback_rate);
+
+ protected:
+ base::test::SingleThreadTaskEnvironment task_environment_{
+ base::test::SingleThreadTaskEnvironment::MainThreadType::IO,
+ base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+
+ std::unique_ptr<CdmContext> cdm_context_;
+ std::unique_ptr<TestAudioConsumer> audio_consumer_;
+ std::unique_ptr<TestStreamSink> stream_sink_;
+ std::unique_ptr<TestDemuxerStream> demuxer_stream_;
+ TestRendererClient client_;
+
+ std::unique_ptr<AudioRenderer> audio_renderer_;
+ TimeSource* time_source_;
+ base::TimeDelta demuxer_stream_pos_;
+};
+
+void FuchsiaAudioRendererTest::CreateUninitializedRenderer() {
+ fidl::InterfaceHandle<fuchsia::media::AudioConsumer> audio_consumer_handle;
+ audio_consumer_ =
+ std::make_unique<TestAudioConsumer>(audio_consumer_handle.NewRequest());
+ audio_renderer_ = std::make_unique<FuchsiaAudioRenderer>(
+ /*media_log=*/nullptr, std::move(audio_consumer_handle));
+ time_source_ = audio_renderer_->GetTimeSource();
+}
+
+void FuchsiaAudioRendererTest::CreateTestDemuxerStream() {
+ AudioDecoderConfig config(kCodecPCM, kSampleFormatF32, CHANNEL_LAYOUT_MONO,
+ kDefaultSampleRate, {},
+ EncryptionScheme::kUnencrypted);
+
+ if (GetParam().simulate_fuchsia_cdm) {
+ config.SetIsEncrypted(true);
+ cdm_context_ = std::make_unique<TestFuchsiaCdmContext>();
+ }
+
+ demuxer_stream_ = std::make_unique<TestDemuxerStream>(config);
+}
+
+void FuchsiaAudioRendererTest::InitializeRenderer() {
+ if (!demuxer_stream_)
+ CreateTestDemuxerStream();
+
+ base::RunLoop run_loop;
+ PipelineStatus pipeline_status;
+ audio_renderer_->Initialize(
+ demuxer_stream_.get(), cdm_context_.get(), &client_,
+ base::BindLambdaForTesting(
+ [&run_loop, &pipeline_status](PipelineStatus s) {
+ pipeline_status = s;
+ run_loop.Quit();
+ }));
+ run_loop.Run();
+
+ ASSERT_EQ(pipeline_status, PIPELINE_OK);
+
+ audio_consumer_->UpdateStatus(absl::nullopt, absl::nullopt);
+
+ task_environment_.RunUntilIdle();
+}
+
+void FuchsiaAudioRendererTest::CreateAndInitializeRenderer() {
+ CreateUninitializedRenderer();
+ InitializeRenderer();
+}
+
+void FuchsiaAudioRendererTest::ProduceDemuxerPacket(base::TimeDelta duration) {
+ // Create a dummy packet that contains just 1 byte.
+ const size_t kBufferSize = 1;
+ scoped_refptr<DecoderBuffer> buffer = new DecoderBuffer(kBufferSize);
+ buffer->set_timestamp(demuxer_stream_pos_);
+ buffer->set_duration(duration);
+ demuxer_stream_pos_ += duration;
+ demuxer_stream_->QueueReadResult(TestDemuxerStream::ReadResult(buffer));
+}
+
+void FuchsiaAudioRendererTest::FillDemuxerStream(base::TimeDelta end_pos) {
+ EXPECT_LT(demuxer_stream_pos_, end_pos);
+ while (demuxer_stream_pos_ < end_pos) {
+ ProduceDemuxerPacket(kPacketDuration);
+ }
+}
+
+void FuchsiaAudioRendererTest::FillBuffer() {
+ if (!stream_sink_) {
+ stream_sink_ = audio_consumer_->WaitStreamSinkConnected();
+ }
+
+ // The renderer expects one extra packet after reaching kMinLeadTime to get
+ // to the BUFFERING_HAVE_ENOUGH state.
+ const size_t kNumPackets = kMinLeadTime / kPacketDuration + 1;
+ for (size_t i = 0; i < kNumPackets; ++i) {
+ ProduceDemuxerPacket(kPacketDuration);
+ }
+ task_environment_.RunUntilIdle();
+
+ // Renderer should not start reading demuxer untile StartPlaying() is
+ // called.
+ EXPECT_EQ(client_.buffering_state(), BUFFERING_HAVE_NOTHING);
+ EXPECT_EQ(stream_sink_->received_packets()->size(), 0U);
+
+ // Start playback. The renderer should push queued packets to the
+ // AudioConsumer and updated buffering state.
+ audio_renderer_->StartPlaying();
+ task_environment_.RunUntilIdle();
+
+ EXPECT_EQ(stream_sink_->received_packets()->size(), kNumPackets);
+ EXPECT_EQ(client_.buffering_state(), BUFFERING_HAVE_ENOUGH);
+}
+
+void FuchsiaAudioRendererTest::StartPlayback(base::TimeDelta start_time) {
+ EXPECT_FALSE(audio_consumer_->started());
+ time_source_->SetMediaTime(start_time);
+
+ ASSERT_NO_FATAL_FAILURE(FillBuffer());
+ time_source_->StartTicking();
+ task_environment_.RunUntilIdle();
+ EXPECT_TRUE(audio_consumer_->started());
+ EXPECT_EQ(audio_consumer_->start_media_time(), start_time);
+
+ audio_consumer_->UpdateStatus(base::TimeTicks::Now(), start_time);
+ task_environment_.RunUntilIdle();
+}
+
+void FuchsiaAudioRendererTest::CheckGetWallClockTimes(
+ absl::optional<base::TimeDelta> media_timestamp,
+ base::TimeTicks expected_wall_clock,
+ bool is_time_moving) {
+ std::vector<base::TimeDelta> media_timestamps;
+ if (media_timestamp)
+ media_timestamps.push_back(media_timestamp.value());
+ std::vector<base::TimeTicks> wall_clock;
+ bool result = time_source_->GetWallClockTimes(media_timestamps, &wall_clock);
+ EXPECT_EQ(wall_clock[0], expected_wall_clock);
+ EXPECT_EQ(result, is_time_moving);
+}
+
+void FuchsiaAudioRendererTest::StartPlaybackAndVerifyClock(
+ base::TimeDelta start_time,
+ float playback_rate) {
+ time_source_->SetMediaTime(start_time);
+ time_source_->SetPlaybackRate(playback_rate);
+
+ demuxer_stream_pos_ = start_time;
+ ASSERT_NO_FATAL_FAILURE(FillBuffer());
+
+ EXPECT_FALSE(audio_consumer_->started());
+ time_source_->StartTicking();
+ task_environment_.RunUntilIdle();
+ EXPECT_TRUE(audio_consumer_->started());
+
+ // Start position should be reported before updated status is received.
+ EXPECT_EQ(time_source_->CurrentMediaTime(), start_time);
+ task_environment_.FastForwardBy(kTimeStep);
+ EXPECT_EQ(time_source_->CurrentMediaTime(), start_time);
+
+ CheckGetWallClockTimes(absl::nullopt, base::TimeTicks(), false);
+ CheckGetWallClockTimes(start_time + kTimeStep,
+ base::TimeTicks::Now() + kTimeStep, false);
+
+ // MediaTime will start moving once AudioConsumer updates timeline.
+ const base::TimeDelta kStartDelay = base::TimeDelta::FromMilliseconds(3);
+ base::TimeTicks start_wall_clock = base::TimeTicks::Now() + kStartDelay;
+ audio_consumer_->UpdateStatus(start_wall_clock, start_time);
+ task_environment_.RunUntilIdle();
+
+ EXPECT_EQ(time_source_->CurrentMediaTime(),
+ start_time - kStartDelay * playback_rate);
+ task_environment_.FastForwardBy(kTimeStep);
+ EXPECT_EQ(time_source_->CurrentMediaTime(),
+ start_time + (-kStartDelay + kTimeStep) * playback_rate);
+
+ CheckGetWallClockTimes(absl::nullopt, base::TimeTicks::Now(), true);
+ CheckGetWallClockTimes(start_time + kTimeStep,
+ start_wall_clock + kTimeStep / playback_rate, true);
+ CheckGetWallClockTimes(start_time + 2 * kTimeStep,
+ start_wall_clock + 2.0 * kTimeStep / playback_rate,
+ true);
+}
+
+// Run all FuchsiaAudioRendererTests with CDM enabled and disabled.
+INSTANTIATE_TEST_SUITE_P(Unencrypted,
+ FuchsiaAudioRendererTest,
+ testing::Values(RendererTestConfig{false}));
+INSTANTIATE_TEST_SUITE_P(Encrypted,
+ FuchsiaAudioRendererTest,
+ testing::Values(RendererTestConfig{true}));
+
+TEST_P(FuchsiaAudioRendererTest, Initialize) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+}
+
+TEST_P(FuchsiaAudioRendererTest, InitializeAndBuffer) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ ASSERT_NO_FATAL_FAILURE(FillBuffer());
+
+ // Extra packets should be sent to AudioConsumer immediately.
+ stream_sink_->received_packets()->clear();
+ ProduceDemuxerPacket(base::TimeDelta::FromMilliseconds(10));
+ task_environment_.RunUntilIdle();
+ EXPECT_EQ(stream_sink_->received_packets()->size(), 1U);
+}
+
+TEST_P(FuchsiaAudioRendererTest, StartPlaybackBeforeStreamSinkConnected) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+
+ // Start playing immediately after initialization. The renderer should wait
+ // for buffers to be allocated before it starts reading from the demuxer.
+ audio_renderer_->StartPlaying();
+ ProduceDemuxerPacket(base::TimeDelta::FromMilliseconds(10));
+ task_environment_.RunUntilIdle();
+
+ stream_sink_ = audio_consumer_->WaitStreamSinkConnected();
+ task_environment_.RunUntilIdle();
+ EXPECT_EQ(stream_sink_->received_packets()->size(), 1U);
+}
+
+TEST_P(FuchsiaAudioRendererTest, StartTicking) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ ASSERT_NO_FATAL_FAILURE(StartPlaybackAndVerifyClock(
+ /*start_pos=*/base::TimeDelta::FromMilliseconds(123),
+ /*playback_rate=*/1.0));
+}
+
+TEST_P(FuchsiaAudioRendererTest, StartTickingRate1_5) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ ASSERT_NO_FATAL_FAILURE(StartPlaybackAndVerifyClock(
+ /*start_pos=*/base::TimeDelta::FromMilliseconds(123),
+ /*playback_rate=*/1.5));
+}
+
+TEST_P(FuchsiaAudioRendererTest, StartTickingRate0_5) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ ASSERT_NO_FATAL_FAILURE(StartPlaybackAndVerifyClock(
+ /*start_pos=*/base::TimeDelta::FromMilliseconds(123),
+ /*playback_rate=*/0.5));
+}
+
+// Verify that the renderer doesn't send packets more than kMaxLeadTime ahead of
+// time.
+TEST_P(FuchsiaAudioRendererTest, MaxLeadTime) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ ASSERT_NO_FATAL_FAILURE(FillBuffer());
+
+ // Queue packets up to kMaxLeadTime with 10 extra packets. The Renderer
+ // shouldn't read these extra packets at the end.
+ FillDemuxerStream(kMaxLeadTime + kPacketDuration * 10);
+
+ task_environment_.RunUntilIdle();
+
+ // Verify that the renderer has filled the buffer to kMaxLeadTime.
+ size_t expected_packets = kMaxLeadTime / kPacketDuration;
+ EXPECT_EQ(expected_packets, stream_sink_->received_packets()->size());
+}
+
+TEST_P(FuchsiaAudioRendererTest, Seek) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+
+ constexpr base::TimeDelta kStartPos = base::TimeDelta();
+ ASSERT_NO_FATAL_FAILURE(StartPlayback(kStartPos));
+ task_environment_.FastForwardBy(kTimeStep);
+ time_source_->StopTicking();
+ demuxer_stream_->DiscardQueueAndAbortRead();
+
+ // Media time should be stopped after StopTicking().
+ EXPECT_EQ(time_source_->CurrentMediaTime(), kStartPos + kTimeStep);
+ task_environment_.FastForwardBy(kTimeStep);
+ EXPECT_EQ(time_source_->CurrentMediaTime(), kStartPos + kTimeStep);
+
+ // Flush the renderer.
+ base::RunLoop run_loop;
+ audio_renderer_->Flush(run_loop.QuitClosure());
+ run_loop.Run();
+
+ // Restart playback from a new position.
+ const base::TimeDelta kSeekPos = base::TimeDelta::FromMilliseconds(123);
+ ASSERT_NO_FATAL_FAILURE(StartPlaybackAndVerifyClock(kSeekPos,
+ /*playback_rate=*/1.0));
+
+ ProduceDemuxerPacket(kPacketDuration);
+
+ // Verify that old packets were discarded and StreamSink started received
+ // packets at the correct position.
+ EXPECT_GT(stream_sink_->discarded_packets()->size(), 0u);
+ EXPECT_EQ(stream_sink_->received_packets()->at(0).pts,
+ kSeekPos.ToZxDuration());
+}
+
+TEST_P(FuchsiaAudioRendererTest, ChangeConfig) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ ASSERT_NO_FATAL_FAILURE(StartPlayback());
+
+ const auto kConfigChangePos = base::TimeDelta::FromSeconds(1);
+
+ // Queue packets up to kConfigChangePos.
+ FillDemuxerStream(kConfigChangePos);
+
+ const size_t kNewSampleRate = 44100;
+ const std::vector<uint8_t> kArbitraryExtraData = {1, 2, 3};
+ AudioDecoderConfig updated_config(
+ kCodecOpus, kSampleFormatF32, CHANNEL_LAYOUT_STEREO, kNewSampleRate,
+ kArbitraryExtraData, EncryptionScheme::kUnencrypted);
+ demuxer_stream_->QueueReadResult(
+ TestDemuxerStream::ReadResult(updated_config));
+
+ // Queue one more packet with the new config.
+ ProduceDemuxerPacket(kPacketDuration);
+
+ task_environment_.FastForwardBy(kConfigChangePos);
+
+ // The renderer should have created new StreamSink when config was changed.
+ auto new_stream_sink = audio_consumer_->TakeStreamSink();
+ ASSERT_TRUE(new_stream_sink);
+
+ ASSERT_TRUE(client_.last_config_change().has_value());
+ EXPECT_TRUE(client_.last_config_change()->Matches(updated_config));
+
+ EXPECT_EQ(stream_sink_->stream_type().channels, 1U);
+ EXPECT_EQ(stream_sink_->stream_type().frames_per_second,
+ static_cast<uint32_t>(kDefaultSampleRate));
+ EXPECT_EQ(stream_sink_->received_packets()->size(),
+ kConfigChangePos / kPacketDuration);
+
+ EXPECT_EQ(new_stream_sink->stream_type().channels,
+ static_cast<uint32_t>(updated_config.channels()));
+ EXPECT_EQ(new_stream_sink->stream_type().frames_per_second, kNewSampleRate);
+ EXPECT_TRUE(new_stream_sink->compression());
+ EXPECT_EQ(new_stream_sink->compression()->type,
+ fuchsia::media::AUDIO_ENCODING_OPUS);
+ EXPECT_EQ(new_stream_sink->compression()->parameters, kArbitraryExtraData);
+ EXPECT_EQ(new_stream_sink->received_packets()->size(), 1U);
+ EXPECT_EQ(new_stream_sink->received_packets()->at(0).pts,
+ kConfigChangePos.ToZxDuration());
+}
+
+TEST_P(FuchsiaAudioRendererTest, UpdateTimeline) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ ASSERT_NO_FATAL_FAILURE(StartPlayback());
+
+ FillDemuxerStream(base::TimeDelta::FromSeconds(2));
+
+ const auto kTimelineChangePos = base::TimeDelta::FromSeconds(1);
+ task_environment_.FastForwardBy(kTimelineChangePos);
+
+ // Shift the timeline by 2ms.
+ const auto kMediaDelta = base::TimeDelta::FromMilliseconds(2);
+ audio_consumer_->UpdateStatus(base::TimeTicks::Now(),
+ kTimelineChangePos + kMediaDelta);
+ task_environment_.RunUntilIdle();
+
+ EXPECT_EQ(time_source_->CurrentMediaTime(), kTimelineChangePos + kMediaDelta);
+ task_environment_.FastForwardBy(kTimeStep);
+ EXPECT_EQ(time_source_->CurrentMediaTime(),
+ kTimelineChangePos + kMediaDelta + kTimeStep);
+}
+
+TEST_P(FuchsiaAudioRendererTest, PauseAndResume) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ ASSERT_NO_FATAL_FAILURE(StartPlayback());
+
+ const auto kPauseTimestamp = base::TimeDelta::FromSeconds(1);
+ const auto kStreamLength = base::TimeDelta::FromSeconds(2);
+
+ FillDemuxerStream(kStreamLength);
+
+ task_environment_.FastForwardBy(kPauseTimestamp);
+
+ // Pause playback by setting playback rate to 0.0.
+ time_source_->SetPlaybackRate(0.0);
+ task_environment_.RunUntilIdle();
+ EXPECT_EQ(audio_consumer_->playback_rate(), 0.0);
+
+ task_environment_.FastForwardBy(kTimeStep);
+ audio_consumer_->UpdateStatus(base::TimeTicks::Now(), kPauseTimestamp);
+ task_environment_.RunUntilIdle();
+
+ const size_t kExpectedQueuedPackets =
+ (kPauseTimestamp + kMaxLeadTime) / kPacketDuration + 1;
+ EXPECT_EQ(stream_sink_->received_packets()->size(), kExpectedQueuedPackets);
+ EXPECT_EQ(time_source_->CurrentMediaTime(), kPauseTimestamp);
+
+ // Keep the stream paused for 10 seconds. The Renderer should not be sending
+ // new packets
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(10));
+ EXPECT_EQ(stream_sink_->received_packets()->size(), kExpectedQueuedPackets);
+ EXPECT_EQ(time_source_->CurrentMediaTime(), kPauseTimestamp);
+
+ // Resume playback.
+ time_source_->SetPlaybackRate(1.0);
+ task_environment_.RunUntilIdle();
+ EXPECT_EQ(audio_consumer_->playback_rate(), 1.0);
+ audio_consumer_->UpdateStatus(base::TimeTicks::Now(), kPauseTimestamp);
+ task_environment_.RunUntilIdle();
+
+ EXPECT_EQ(time_source_->CurrentMediaTime(), kPauseTimestamp);
+
+ // The renderer should start sending packets again.
+ task_environment_.FastForwardBy(kPacketDuration);
+ EXPECT_EQ(stream_sink_->received_packets()->size(),
+ kExpectedQueuedPackets + 1);
+
+ EXPECT_EQ(time_source_->CurrentMediaTime(),
+ kPauseTimestamp + kPacketDuration);
+}
+
+// Verify that end-of-stream is handled correctly when the renderer is buffered.
+TEST_P(FuchsiaAudioRendererTest, EndOfStreamBuffered) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ ASSERT_NO_FATAL_FAILURE(StartPlayback());
+
+ const auto kStreamLength = base::TimeDelta::FromSeconds(1);
+ FillDemuxerStream(kStreamLength);
+ demuxer_stream_->QueueReadResult(
+ TestDemuxerStream::ReadResult(DecoderBuffer::CreateEOSBuffer()));
+
+ // Queue second EOS buffer. The renderer should not read it.
+ demuxer_stream_->QueueReadResult(
+ TestDemuxerStream::ReadResult(DecoderBuffer::CreateEOSBuffer()));
+
+ task_environment_.FastForwardBy(kStreamLength);
+
+ EXPECT_EQ(stream_sink_->received_packets()->size(),
+ kStreamLength / kPacketDuration);
+ EXPECT_TRUE(stream_sink_->received_end_of_stream());
+
+ client_.ExpectEos();
+ audio_consumer_->SignalEndOfStream();
+ task_environment_.RunUntilIdle();
+}
+
+// Verifies that buffering state is updated after reaching EOS. See
+// https://crbug.com/1162503 .
+TEST_P(FuchsiaAudioRendererTest, EndOfStreamWhenBuffering) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ stream_sink_ = audio_consumer_->WaitStreamSinkConnected();
+
+ // Produce stream shorter than kMinLeadTime.
+ const auto kStreamLength = kMinLeadTime / 2;
+ FillDemuxerStream(kStreamLength);
+ demuxer_stream_->QueueReadResult(
+ TestDemuxerStream::ReadResult(DecoderBuffer::CreateEOSBuffer()));
+ task_environment_.RunUntilIdle();
+
+ // Start playback. The renderer should push queued packets to the
+ // AudioConsumer and updated buffering state when it reaches EOS.
+ audio_renderer_->StartPlaying();
+ task_environment_.RunUntilIdle();
+
+ EXPECT_EQ(client_.buffering_state(), BUFFERING_HAVE_ENOUGH);
+ EXPECT_TRUE(stream_sink_->received_end_of_stream());
+}
+
+TEST_P(FuchsiaAudioRendererTest, EndOfStreamStart) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+ stream_sink_ = audio_consumer_->WaitStreamSinkConnected();
+
+ // Queue EOS without any preceding packets.
+ demuxer_stream_->QueueReadResult(
+ TestDemuxerStream::ReadResult(DecoderBuffer::CreateEOSBuffer()));
+ task_environment_.RunUntilIdle();
+
+ // Start playback. The renderer should push queued packets to the
+ // AudioConsumer and updated buffering state when it reaches EOS.
+ audio_renderer_->StartPlaying();
+ task_environment_.RunUntilIdle();
+
+ EXPECT_EQ(client_.buffering_state(), BUFFERING_HAVE_ENOUGH);
+ EXPECT_TRUE(stream_sink_->received_end_of_stream());
+}
+
+TEST_P(FuchsiaAudioRendererTest, SetVolume) {
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+
+ audio_renderer_->SetVolume(0.5);
+ task_environment_.RunUntilIdle();
+ EXPECT_EQ(audio_consumer_->volume(), 0.5);
+}
+
+TEST_P(FuchsiaAudioRendererTest, SetVolumeBeforeInitialize) {
+ ASSERT_NO_FATAL_FAILURE(CreateUninitializedRenderer());
+
+ // SetVolume() may be called before AudioRenderer is initialized. It should
+ // still be handled.
+ audio_renderer_->SetVolume(0.5);
+
+ ASSERT_NO_FATAL_FAILURE(InitializeRenderer());
+ EXPECT_EQ(audio_consumer_->volume(), 0.5);
+}
+
+// Verify that the case when StartTicking() is called shortly after
+// StartPlaying() is handled correctly. AudioConsumer::Start() should be sent
+// only after CreateStreamSink(). See crbug.com/1219147 .
+TEST_P(FuchsiaAudioRendererTest, PlaybackBeforeSinkCreation) {
+ CreateTestDemuxerStream();
+ const auto kStreamLength = base::TimeDelta::FromMilliseconds(100);
+ FillDemuxerStream(kStreamLength);
+ demuxer_stream_->QueueReadResult(
+ TestDemuxerStream::ReadResult(DecoderBuffer::CreateEOSBuffer()));
+
+ ASSERT_NO_FATAL_FAILURE(CreateAndInitializeRenderer());
+
+ // Call StartTicking() shortly after StartPlayback(). At this point sysmem
+ // buffer allocation hasn't been complete, so AudioConsumer::Start() should be
+ // delayed until the buffer are allocated.
+ audio_renderer_->StartPlaying();
+ time_source_->StartTicking();
+
+ // Wait until the stream is started. Start() should be called only after
+ // StreamSink() is connected and the packets are buffered.
+ audio_consumer_->WaitStarted();
+ stream_sink_ = audio_consumer_->TakeStreamSink();
+ EXPECT_GT(stream_sink_->received_packets()->size(), 0U);
+}
+
+} // namespace media
diff --git a/chromium/media/fuchsia/camera/fake_fuchsia_camera.cc b/chromium/media/fuchsia/camera/fake_fuchsia_camera.cc
index 718999edb22..3c1311bf5d0 100644
--- a/chromium/media/fuchsia/camera/fake_fuchsia_camera.cc
+++ b/chromium/media/fuchsia/camera/fake_fuchsia_camera.cc
@@ -285,37 +285,63 @@ void FakeCameraStream::SetBufferCollection(
buffer_collection_.Unbind();
}
- // Use a SyncPtr to be able to wait for Sync() synchronously.
- fuchsia::sysmem::BufferCollectionTokenSyncPtr token;
- token.Bind(std::move(token_handle));
+ new_buffer_collection_token_.Bind(std::move(token_handle));
+ new_buffer_collection_token_.set_error_handler(
+ fit::bind_member(this, &FakeCameraStream::OnBufferCollectionError));
// Duplicate the token to access from the stream.
- fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> local_token;
- zx_status_t status =
- token->Duplicate(/*rights_attenuation_mask=*/0, local_token.NewRequest());
- EXPECT_EQ(status, ZX_OK);
+ fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
+ token_for_client;
+ new_buffer_collection_token_->Duplicate(ZX_RIGHT_SAME_RIGHTS,
+ token_for_client.NewRequest());
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> failed_token;
if (first_buffer_collection_fail_mode_ == SysmemFailMode::kFailSync) {
- // Create an additional token that's dropped before this method returns.
- // This will cause sysmem to fail the collection, so the future attempt to
- // Sync() the collection from the production code will fail as well.
- zx_status_t status = token->Duplicate(/*rights_attenuation_mask=*/0,
- failed_token.NewRequest());
- EXPECT_EQ(status, ZX_OK);
+ // Create an additional token that's dropped in OnBufferCollectionSyncDone()
+ // before buffers are allocated. This will cause sysmem to fail the
+ // collection, so the future attempt to Sync() the collection from the
+ // production code will fail as well.
+ new_buffer_collection_token_->Duplicate(
+ /*rights_attenuation_mask=*/0, failed_token.NewRequest());
}
- status = token->Sync();
- EXPECT_EQ(status, ZX_OK);
+ new_buffer_collection_token_->Sync(
+ [this, token_for_client = std::move(token_for_client),
+ failed_token = std::move(failed_token)]() mutable {
+ OnBufferCollectionSyncDone(std::move(token_for_client),
+ std::move(failed_token));
+ });
+}
+
+void FakeCameraStream::WatchBufferCollection(
+ WatchBufferCollectionCallback callback) {
+ EXPECT_FALSE(watch_buffer_collection_callback_);
+ watch_buffer_collection_callback_ = std::move(callback);
+ SendBufferCollection();
+}
+
+void FakeCameraStream::GetNextFrame(GetNextFrameCallback callback) {
+ EXPECT_FALSE(get_next_frame_callback_);
+ get_next_frame_callback_ = std::move(callback);
+ SendNextFrame();
+}
+
+void FakeCameraStream::NotImplemented_(const std::string& name) {
+ ADD_FAILURE() << "NotImplemented_: " << name;
+}
+void FakeCameraStream::OnBufferCollectionSyncDone(
+ fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
+ token_for_client,
+ fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
+ failed_token) {
// Return the token back to the client.
- new_buffer_collection_token_ = token.Unbind();
+ new_buffer_collection_token_for_client_ = std::move(token_for_client);
SendBufferCollection();
// Initialize the new collection using |local_token|.
- sysmem_allocator_->BindSharedCollection(std::move(local_token),
- buffer_collection_.NewRequest());
- EXPECT_EQ(status, ZX_OK);
+ sysmem_allocator_->BindSharedCollection(
+ std::move(new_buffer_collection_token_), buffer_collection_.NewRequest());
buffer_collection_.set_error_handler(
fit::bind_member(this, &FakeCameraStream::OnBufferCollectionError));
@@ -353,23 +379,6 @@ void FakeCameraStream::SetBufferCollection(
fit::bind_member(this, &FakeCameraStream::OnBufferCollectionAllocated));
}
-void FakeCameraStream::WatchBufferCollection(
- WatchBufferCollectionCallback callback) {
- EXPECT_FALSE(watch_buffer_collection_callback_);
- watch_buffer_collection_callback_ = std::move(callback);
- SendBufferCollection();
-}
-
-void FakeCameraStream::GetNextFrame(GetNextFrameCallback callback) {
- EXPECT_FALSE(get_next_frame_callback_);
- get_next_frame_callback_ = std::move(callback);
- SendNextFrame();
-}
-
-void FakeCameraStream::NotImplemented_(const std::string& name) {
- ADD_FAILURE() << "NotImplemented_: " << name;
-}
-
void FakeCameraStream::OnBufferCollectionError(zx_status_t status) {
if (first_buffer_collection_fail_mode_ != SysmemFailMode::kNone) {
first_buffer_collection_fail_mode_ = SysmemFailMode::kNone;
@@ -438,12 +447,14 @@ void FakeCameraStream::SendOrientation() {
}
void FakeCameraStream::SendBufferCollection() {
- if (!watch_buffer_collection_callback_ || !new_buffer_collection_token_)
+ if (!watch_buffer_collection_callback_ ||
+ !new_buffer_collection_token_for_client_) {
return;
+ }
watch_buffer_collection_callback_(
- std::move(new_buffer_collection_token_.value()));
+ std::move(new_buffer_collection_token_for_client_.value()));
watch_buffer_collection_callback_ = {};
- new_buffer_collection_token_.reset();
+ new_buffer_collection_token_for_client_.reset();
}
void FakeCameraStream::SendNextFrame() {
@@ -610,4 +621,4 @@ void FakeCameraDeviceWatcher::Client::NotImplemented_(const std::string& name) {
ADD_FAILURE() << "NotImplemented_: " << name;
}
-} // namespace media \ No newline at end of file
+} // namespace media
diff --git a/chromium/media/fuchsia/camera/fake_fuchsia_camera.h b/chromium/media/fuchsia/camera/fake_fuchsia_camera.h
index 0fba3b2a1fe..6b9afa3cac3 100644
--- a/chromium/media/fuchsia/camera/fake_fuchsia_camera.h
+++ b/chromium/media/fuchsia/camera/fake_fuchsia_camera.h
@@ -14,8 +14,8 @@
#include <vector>
#include "base/message_loop/message_pump_for_io.h"
-#include "base/optional.h"
#include "base/run_loop.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
@@ -86,6 +86,12 @@ class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase,
// fuchsia::camera3::testing::Stream_TestBase override.
void NotImplemented_(const std::string& name) override;
+ void OnBufferCollectionSyncDone(
+ fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
+ token_for_client,
+ fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
+ failed_token);
+
void OnBufferCollectionError(zx_status_t status);
void OnBufferCollectionAllocated(
@@ -118,26 +124,28 @@ class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase,
fuchsia::camera3::Orientation orientation_ =
fuchsia::camera3::Orientation::UP;
- base::Optional<fuchsia::math::Size> resolution_update_ = fuchsia::math::Size{
+ absl::optional<fuchsia::math::Size> resolution_update_ = fuchsia::math::Size{
kDefaultFrameSize.width(), kDefaultFrameSize.height()};
WatchResolutionCallback watch_resolution_callback_;
- base::Optional<fuchsia::camera3::Orientation> orientation_update_ =
+ absl::optional<fuchsia::camera3::Orientation> orientation_update_ =
fuchsia::camera3::Orientation::UP;
WatchOrientationCallback watch_orientation_callback_;
- base::Optional<fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>>
- new_buffer_collection_token_;
+ fuchsia::sysmem::BufferCollectionTokenPtr new_buffer_collection_token_;
+
+ absl::optional<fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>>
+ new_buffer_collection_token_for_client_;
WatchBufferCollectionCallback watch_buffer_collection_callback_;
- base::Optional<fuchsia::camera3::FrameInfo> next_frame_;
+ absl::optional<fuchsia::camera3::FrameInfo> next_frame_;
GetNextFrameCallback get_next_frame_callback_;
fuchsia::sysmem::AllocatorPtr sysmem_allocator_;
fuchsia::sysmem::BufferCollectionPtr buffer_collection_;
- base::Optional<base::RunLoop> wait_buffers_allocated_run_loop_;
- base::Optional<base::RunLoop> wait_free_buffer_run_loop_;
+ absl::optional<base::RunLoop> wait_buffers_allocated_run_loop_;
+ absl::optional<base::RunLoop> wait_free_buffer_run_loop_;
std::vector<std::unique_ptr<Buffer>> buffers_;
size_t num_used_buffers_ = 0;
diff --git a/chromium/media/fuchsia/cdm/fuchsia_cdm.cc b/chromium/media/fuchsia/cdm/fuchsia_cdm.cc
index 23dba99d9e3..07bd76fa26a 100644
--- a/chromium/media/fuchsia/cdm/fuchsia_cdm.cc
+++ b/chromium/media/fuchsia/cdm/fuchsia_cdm.cc
@@ -4,14 +4,12 @@
#include "media/fuchsia/cdm/fuchsia_cdm.h"
-#include "base/command_line.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/logging.h"
-#include "base/optional.h"
#include "fuchsia/base/mem_buffer_util.h"
#include "media/base/callback_registry.h"
#include "media/base/cdm_promise.h"
-#include "media/base/media_switches.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#define REJECT_PROMISE_AND_RETURN_IF_BAD_CDM(promise, cdm) \
if (!cdm) { \
@@ -24,10 +22,6 @@ namespace media {
namespace {
-// Audio packets are normally smaller than 128kB (more than enough for 2 seconds
-// at 320kb/s).
-const size_t kAudioStreamBufferSize = 128 * 1024;
-
std::string GetInitDataTypeName(EmeInitDataType type) {
switch (type) {
case EmeInitDataType::WEBM:
@@ -128,7 +122,7 @@ CdmPromise::Exception ToCdmPromiseException(fuchsia::media::drm::Error error) {
class FuchsiaCdm::CdmSession {
public:
using ResultCB =
- base::OnceCallback<void(base::Optional<CdmPromise::Exception>)>;
+ base::OnceCallback<void(absl::optional<CdmPromise::Exception>)>;
using SessionReadyCB = base::OnceCallback<void(bool success)>;
CdmSession(const FuchsiaCdm::SessionCallbacks* callbacks,
@@ -258,8 +252,8 @@ class FuchsiaCdm::CdmSession {
DCHECK(result_cb_);
std::move(result_cb_)
.Run(result.is_err()
- ? base::make_optional(ToCdmPromiseException(result.err()))
- : base::nullopt);
+ ? absl::make_optional(ToCdmPromiseException(result.err()))
+ : absl::nullopt);
}
const SessionCallbacks* const session_callbacks_;
@@ -315,43 +309,28 @@ FuchsiaCdm::FuchsiaCdm(fuchsia::media::drm::ContentDecryptionModulePtr cdm,
FuchsiaCdm::~FuchsiaCdm() = default;
-std::unique_ptr<FuchsiaSecureStreamDecryptor> FuchsiaCdm::CreateVideoDecryptor(
- FuchsiaSecureStreamDecryptor::Client* client) {
+std::unique_ptr<SysmemBufferStream> FuchsiaCdm::CreateStreamDecryptor(
+ bool secure_mode) {
fuchsia::media::drm::DecryptorParams params;
-
- bool secure_mode = base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableProtectedVideoBuffers);
params.set_require_secure_mode(secure_mode);
-
params.mutable_input_details()->set_format_details_version_ordinal(0);
+
fuchsia::media::StreamProcessorPtr stream_processor;
cdm_->CreateDecryptor(std::move(params), stream_processor.NewRequest());
- auto decryptor = std::make_unique<FuchsiaSecureStreamDecryptor>(
- std::move(stream_processor), client);
+ auto decryptor =
+ std::make_unique<FuchsiaStreamDecryptor>(std::move(stream_processor));
// Save callback to use to notify the decryptor about a new key.
auto new_key_cb = decryptor->GetOnNewKeyClosure();
{
- base::AutoLock auto_lock(new_key_cb_for_video_lock_);
- new_key_cb_for_video_ = new_key_cb;
+ base::AutoLock auto_lock(new_key_callbacks_lock_);
+ new_key_callbacks_.push_back(std::move(new_key_cb));
}
return decryptor;
}
-std::unique_ptr<FuchsiaClearStreamDecryptor>
-FuchsiaCdm::CreateAudioDecryptor() {
- fuchsia::media::drm::DecryptorParams params;
- params.set_require_secure_mode(false);
- params.mutable_input_details()->set_format_details_version_ordinal(0);
- fuchsia::media::StreamProcessorPtr stream_processor;
- cdm_->CreateDecryptor(std::move(params), stream_processor.NewRequest());
-
- return std::make_unique<FuchsiaClearStreamDecryptor>(
- std::move(stream_processor), kAudioStreamBufferSize);
-}
-
void FuchsiaCdm::SetServerCertificate(
const std::vector<uint8_t>& certificate,
std::unique_ptr<SimpleCdmPromise> promise) {
@@ -434,7 +413,7 @@ void FuchsiaCdm::OnCreateSession(std::unique_ptr<CdmSession> session,
void FuchsiaCdm::OnGenerateLicenseRequestStatus(
CdmSession* session,
uint32_t promise_id,
- base::Optional<CdmPromise::Exception> exception) {
+ absl::optional<CdmPromise::Exception> exception) {
DCHECK(session);
std::string session_id = session->session_id();
@@ -522,7 +501,7 @@ void FuchsiaCdm::UpdateSession(const std::string& session_id,
void FuchsiaCdm::OnProcessLicenseServerMessageStatus(
const std::string& session_id,
uint32_t promise_id,
- base::Optional<CdmPromise::Exception> exception) {
+ absl::optional<CdmPromise::Exception> exception) {
if (exception.has_value()) {
promises_.RejectPromise(promise_id, exception.value(), 0,
"fail to process license.");
@@ -584,7 +563,7 @@ void FuchsiaCdm::RemoveSession(const std::string& session_id,
void FuchsiaCdm::OnGenerateLicenseReleaseStatus(
const std::string& session_id,
uint32_t promise_id,
- base::Optional<CdmPromise::Exception> exception) {
+ absl::optional<CdmPromise::Exception> exception) {
if (exception.has_value()) {
promises_.RejectPromise(promise_id, exception.value(), 0,
"Failed to release license.");
@@ -616,9 +595,18 @@ FuchsiaCdmContext* FuchsiaCdm::GetFuchsiaCdmContext() {
void FuchsiaCdm::OnNewKey() {
event_callbacks_.Notify(Event::kHasAdditionalUsableKey);
{
- base::AutoLock auto_lock(new_key_cb_for_video_lock_);
- if (new_key_cb_for_video_)
- new_key_cb_for_video_.Run();
+ base::AutoLock auto_lock(new_key_callbacks_lock_);
+
+ // Remove cancelled callbacks.
+ new_key_callbacks_.erase(
+ std::remove_if(
+ new_key_callbacks_.begin(), new_key_callbacks_.end(),
+ [](const base::RepeatingClosure& cb) { return cb.IsCancelled(); }),
+ new_key_callbacks_.end());
+
+ for (auto& cb : new_key_callbacks_) {
+ cb.Run();
+ }
}
}
diff --git a/chromium/media/fuchsia/cdm/fuchsia_cdm.h b/chromium/media/fuchsia/cdm/fuchsia_cdm.h
index 6f3c2a10805..f1f058ba580 100644
--- a/chromium/media/fuchsia/cdm/fuchsia_cdm.h
+++ b/chromium/media/fuchsia/cdm/fuchsia_cdm.h
@@ -10,13 +10,13 @@
#include "base/callback_forward.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "media/base/callback_registry.h"
#include "media/base/cdm_context.h"
#include "media/base/cdm_promise_adapter.h"
#include "media/base/content_decryption_module.h"
#include "media/fuchsia/cdm/fuchsia_cdm_context.h"
#include "media/fuchsia/cdm/fuchsia_decryptor.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -71,9 +71,8 @@ class FuchsiaCdm : public ContentDecryptionModule,
FuchsiaCdmContext* GetFuchsiaCdmContext() override;
// FuchsiaCdmContext implementation:
- std::unique_ptr<FuchsiaSecureStreamDecryptor> CreateVideoDecryptor(
- FuchsiaSecureStreamDecryptor::Client* client) override;
- std::unique_ptr<FuchsiaClearStreamDecryptor> CreateAudioDecryptor() override;
+ std::unique_ptr<SysmemBufferStream> CreateStreamDecryptor(
+ bool secure_mode) override;
private:
class CdmSession;
@@ -87,11 +86,11 @@ class FuchsiaCdm : public ContentDecryptionModule,
void OnGenerateLicenseRequestStatus(
CdmSession* session,
uint32_t promise_id,
- base::Optional<CdmPromise::Exception> exception);
+ absl::optional<CdmPromise::Exception> exception);
void OnProcessLicenseServerMessageStatus(
const std::string& session_id,
uint32_t promise_id,
- base::Optional<CdmPromise::Exception> exception);
+ absl::optional<CdmPromise::Exception> exception);
void OnSessionLoaded(std::unique_ptr<CdmSession> session,
uint32_t promise_id,
bool loaded);
@@ -99,7 +98,7 @@ class FuchsiaCdm : public ContentDecryptionModule,
void OnGenerateLicenseReleaseStatus(
const std::string& session_id,
uint32_t promise_id,
- base::Optional<CdmPromise::Exception> exception);
+ absl::optional<CdmPromise::Exception> exception);
void OnNewKey();
@@ -112,9 +111,9 @@ class FuchsiaCdm : public ContentDecryptionModule,
FuchsiaDecryptor decryptor_;
- base::Lock new_key_cb_for_video_lock_;
- base::RepeatingClosure new_key_cb_for_video_
- GUARDED_BY(new_key_cb_for_video_lock_);
+ base::Lock new_key_callbacks_lock_;
+ std::vector<base::RepeatingClosure> new_key_callbacks_
+ GUARDED_BY(new_key_callbacks_lock_);
CallbackRegistry<EventCB::RunType> event_callbacks_;
diff --git a/chromium/media/fuchsia/cdm/fuchsia_cdm_context.h b/chromium/media/fuchsia/cdm/fuchsia_cdm_context.h
index 667b78d71a4..a382acb2468 100644
--- a/chromium/media/fuchsia/cdm/fuchsia_cdm_context.h
+++ b/chromium/media/fuchsia/cdm/fuchsia_cdm_context.h
@@ -5,20 +5,20 @@
#ifndef MEDIA_FUCHSIA_CDM_FUCHSIA_CDM_CONTEXT_H_
#define MEDIA_FUCHSIA_CDM_FUCHSIA_CDM_CONTEXT_H_
-#include "media/fuchsia/cdm/fuchsia_stream_decryptor.h"
+#include <memory>
namespace media {
+class SysmemBufferStream;
+
// Interface for Fuchsia-specific extensions to the CdmContext interface.
class FuchsiaCdmContext {
public:
FuchsiaCdmContext() = default;
// Creates FuchsiaSecureStreamDecryptor instance for the CDM context.
- virtual std::unique_ptr<FuchsiaSecureStreamDecryptor> CreateVideoDecryptor(
- FuchsiaSecureStreamDecryptor::Client* client) = 0;
- virtual std::unique_ptr<FuchsiaClearStreamDecryptor>
- CreateAudioDecryptor() = 0;
+ virtual std::unique_ptr<SysmemBufferStream> CreateStreamDecryptor(
+ bool secure_mode) = 0;
protected:
virtual ~FuchsiaCdmContext() = default;
diff --git a/chromium/media/fuchsia/cdm/fuchsia_decryptor.cc b/chromium/media/fuchsia/cdm/fuchsia_decryptor.cc
index c046957b792..82ee7cad742 100644
--- a/chromium/media/fuchsia/cdm/fuchsia_decryptor.cc
+++ b/chromium/media/fuchsia/cdm/fuchsia_decryptor.cc
@@ -22,32 +22,16 @@ FuchsiaDecryptor::FuchsiaDecryptor(FuchsiaCdmContext* cdm_context)
}
FuchsiaDecryptor::~FuchsiaDecryptor() {
- if (audio_decryptor_) {
- audio_decryptor_task_runner_->DeleteSoon(FROM_HERE,
- std::move(audio_decryptor_));
- }
}
void FuchsiaDecryptor::Decrypt(StreamType stream_type,
scoped_refptr<DecoderBuffer> encrypted,
DecryptCB decrypt_cb) {
- if (stream_type != StreamType::kAudio) {
- std::move(decrypt_cb).Run(Status::kError, nullptr);
- return;
- }
-
- if (!audio_decryptor_) {
- audio_decryptor_task_runner_ = base::ThreadTaskRunnerHandle::Get();
- audio_decryptor_ = cdm_context_->CreateAudioDecryptor();
- }
-
- audio_decryptor_->Decrypt(std::move(encrypted), std::move(decrypt_cb));
+ std::move(decrypt_cb).Run(Status::kError, nullptr);
}
void FuchsiaDecryptor::CancelDecrypt(StreamType stream_type) {
- if (stream_type == StreamType::kAudio && audio_decryptor_) {
- audio_decryptor_->CancelDecrypt();
- }
+ NOTREACHED();
}
void FuchsiaDecryptor::InitializeAudioDecoder(const AudioDecoderConfig& config,
diff --git a/chromium/media/fuchsia/cdm/fuchsia_decryptor.h b/chromium/media/fuchsia/cdm/fuchsia_decryptor.h
index ae502e70454..006b079e094 100644
--- a/chromium/media/fuchsia/cdm/fuchsia_decryptor.h
+++ b/chromium/media/fuchsia/cdm/fuchsia_decryptor.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_FUCHSIA_CDM_FUCHSIA_DECRYPTOR_H_
#define MEDIA_FUCHSIA_CDM_FUCHSIA_DECRYPTOR_H_
-#include <memory>
-
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
@@ -17,7 +15,6 @@
namespace media {
class FuchsiaCdmContext;
-class FuchsiaClearStreamDecryptor;
class FuchsiaDecryptor : public Decryptor {
public:
@@ -45,8 +42,6 @@ class FuchsiaDecryptor : public Decryptor {
private:
FuchsiaCdmContext* const cdm_context_;
- std::unique_ptr<FuchsiaClearStreamDecryptor> audio_decryptor_;
-
// TaskRunner for the thread on which |audio_decryptor_| was created.
scoped_refptr<base::SingleThreadTaskRunner> audio_decryptor_task_runner_;
diff --git a/chromium/media/fuchsia/cdm/fuchsia_stream_decryptor.cc b/chromium/media/fuchsia/cdm/fuchsia_stream_decryptor.cc
index 5a3d1b205ef..9b2e4214546 100644
--- a/chromium/media/fuchsia/cdm/fuchsia_stream_decryptor.cc
+++ b/chromium/media/fuchsia/cdm/fuchsia_stream_decryptor.cc
@@ -15,17 +15,10 @@
#include "media/base/decrypt_config.h"
#include "media/base/encryption_pattern.h"
#include "media/base/subsample_entry.h"
-#include "media/fuchsia/common/sysmem_buffer_reader.h"
-#include "media/fuchsia/common/sysmem_buffer_writer.h"
namespace media {
namespace {
-// Minimum number of buffers in the input and output buffer collection.
-// Decryptors provided by fuchsia.media.drm API normally decrypt a single
-// buffer at a time. Second buffer is useful to allow reading/writing a
-// packet while the decryptor is working on another one.
-const size_t kMinBufferCount = 2;
std::string GetEncryptionScheme(EncryptionScheme mode) {
switch (mode) {
@@ -97,103 +90,159 @@ fuchsia::media::FormatDetails GetEncryptedFormatDetails(
} // namespace
-FuchsiaStreamDecryptorBase::FuchsiaStreamDecryptorBase(
- fuchsia::media::StreamProcessorPtr processor,
- size_t min_buffer_size)
+FuchsiaStreamDecryptor::FuchsiaStreamDecryptor(
+ fuchsia::media::StreamProcessorPtr processor)
: processor_(std::move(processor), this),
- min_buffer_size_(min_buffer_size),
- allocator_("CrFuchsiaStreamDecryptorBase") {}
+ allocator_("CrFuchsiaStreamDecryptor") {}
-FuchsiaStreamDecryptorBase::~FuchsiaStreamDecryptorBase() {
+FuchsiaStreamDecryptor::~FuchsiaStreamDecryptor() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
-int FuchsiaStreamDecryptorBase::GetMaxDecryptRequests() const {
- return input_writer_queue_.num_buffers() + 1;
+base::RepeatingClosure FuchsiaStreamDecryptor::GetOnNewKeyClosure() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ return BindToCurrentLoop(base::BindRepeating(
+ &FuchsiaStreamDecryptor::OnNewKey, weak_factory_.GetWeakPtr()));
+}
+
+void FuchsiaStreamDecryptor::Initialize(Sink* sink,
+ size_t min_buffer_size,
+ size_t min_buffer_count) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ sink_ = sink;
+
+ min_buffer_size_ = min_buffer_size;
+ min_buffer_count_ = min_buffer_count;
+
+ input_buffer_collection_ = allocator_.AllocateNewCollection();
+ input_buffer_collection_->CreateSharedToken(
+ base::BindOnce(&StreamProcessorHelper::SetInputBufferCollectionToken,
+ base::Unretained(&processor_)));
+ auto buffer_constraints = VmoBuffer::GetRecommendedConstraints(
+ kInputBufferCount, min_buffer_size_, /*writable=*/true);
+ input_buffer_collection_->Initialize(std::move(buffer_constraints),
+ "CrFuchsiaStreamDecryptor");
+ input_buffer_collection_->AcquireBuffers(base::BindOnce(
+ &FuchsiaStreamDecryptor::OnInputBuffersAcquired, base::Unretained(this)));
}
-void FuchsiaStreamDecryptorBase::DecryptInternal(
- scoped_refptr<DecoderBuffer> encrypted) {
+void FuchsiaStreamDecryptor::EnqueueBuffer(
+ scoped_refptr<DecoderBuffer> buffer) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- input_writer_queue_.EnqueueBuffer(std::move(encrypted));
+ input_writer_queue_.EnqueueBuffer(std::move(buffer));
}
-void FuchsiaStreamDecryptorBase::ResetStream() {
+void FuchsiaStreamDecryptor::Reset() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Close current stream and drop all the cached decoder buffers.
// Keep input and output buffers to avoid buffer re-allocation.
processor_.Reset();
input_writer_queue_.ResetQueue();
+ waiting_for_key_ = false;
}
-// StreamProcessorHelper::Client implementation:
-void FuchsiaStreamDecryptorBase::AllocateInputBuffers(
+void FuchsiaStreamDecryptor::OnStreamProcessorAllocateOutputBuffers(
const fuchsia::media::StreamBufferConstraints& stream_constraints) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- base::Optional<fuchsia::sysmem::BufferCollectionConstraints>
- buffer_constraints = SysmemBufferWriter::GetRecommendedConstraints(
- kMinBufferCount, min_buffer_size_);
-
- if (!buffer_constraints.has_value()) {
- OnError();
- return;
- }
-
- input_pool_creator_ =
- allocator_.MakeBufferPoolCreator(1 /* num_shared_token */);
+ output_buffer_collection_ = allocator_.AllocateNewCollection();
+ output_buffer_collection_->CreateSharedToken(
+ base::BindOnce(&StreamProcessorHelper::CompleteOutputBuffersAllocation,
+ base::Unretained(&processor_)));
+ output_buffer_collection_->CreateSharedToken(
+ base::BindOnce(&Sink::OnSysmemBufferStreamBufferCollectionToken,
+ base::Unretained(sink_)));
+
+ fuchsia::sysmem::BufferCollectionConstraints buffer_constraints;
+ buffer_constraints.usage.none = fuchsia::sysmem::noneUsage;
+ buffer_constraints.min_buffer_count = min_buffer_count_;
+ buffer_constraints.has_buffer_memory_constraints = true;
+ buffer_constraints.buffer_memory_constraints.min_size_bytes =
+ min_buffer_size_;
+ buffer_constraints.buffer_memory_constraints.ram_domain_supported = true;
+ buffer_constraints.buffer_memory_constraints.cpu_domain_supported = true;
+ buffer_constraints.buffer_memory_constraints.inaccessible_domain_supported =
+ true;
+
+ output_buffer_collection_->Initialize(std::move(buffer_constraints),
+ "CrFuchsiaStreamDecryptorOutput");
+}
+
+void FuchsiaStreamDecryptor::OnStreamProcessorEndOfStream() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- input_pool_creator_->Create(
- std::move(buffer_constraints).value(),
- base::BindOnce(&FuchsiaStreamDecryptorBase::OnInputBufferPoolCreated,
- base::Unretained(this)));
+ sink_->OnSysmemBufferStreamEndOfStream();
}
-void FuchsiaStreamDecryptorBase::OnOutputFormat(
+void FuchsiaStreamDecryptor::OnStreamProcessorOutputFormat(
fuchsia::media::StreamOutputFormat format) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
-void FuchsiaStreamDecryptorBase::OnInputBufferPoolCreated(
- std::unique_ptr<SysmemBufferPool> pool) {
+void FuchsiaStreamDecryptor::OnStreamProcessorOutputPacket(
+ StreamProcessorHelper::IoPacket packet) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (!pool) {
- DLOG(ERROR) << "Fail to allocate input buffer.";
- OnError();
+ sink_->OnSysmemBufferStreamOutputPacket(std::move(packet));
+}
+
+void FuchsiaStreamDecryptor::OnStreamProcessorNoKey() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(!waiting_for_key_);
+
+ // Reset stream position, but keep all pending buffers. They will be
+ // resubmitted later, when we have a new key.
+ input_writer_queue_.ResetPositionAndPause();
+
+ if (retry_on_no_key_event_) {
+ retry_on_no_key_event_ = false;
+ input_writer_queue_.Unpause();
return;
}
- input_pool_ = std::move(pool);
+ waiting_for_key_ = true;
+ sink_->OnSysmemBufferStreamNoKey();
+}
+
+void FuchsiaStreamDecryptor::OnStreamProcessorError() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ OnError();
+}
+
+void FuchsiaStreamDecryptor::OnError() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // Provide token before enabling writer. Tokens must be provided to
- // StreamProcessor before getting the allocated buffers.
- processor_.CompleteInputBuffersAllocation(input_pool_->TakeToken());
+ Reset();
- input_pool_->CreateWriter(base::BindOnce(
- &FuchsiaStreamDecryptorBase::OnWriterCreated, base::Unretained(this)));
+ // No need to reset other fields since OnError() is called for non-recoverable
+ // errors.
+
+ sink_->OnSysmemBufferStreamError();
}
-void FuchsiaStreamDecryptorBase::OnWriterCreated(
- std::unique_ptr<SysmemBufferWriter> writer) {
+void FuchsiaStreamDecryptor::OnInputBuffersAcquired(
+ std::vector<VmoBuffer> buffers,
+ const fuchsia::sysmem::SingleBufferSettings&) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (!writer) {
+ if (buffers.empty()) {
OnError();
return;
}
input_writer_queue_.Start(
- std::move(writer),
- base::BindRepeating(&FuchsiaStreamDecryptorBase::SendInputPacket,
+ std::move(buffers),
+ base::BindRepeating(&FuchsiaStreamDecryptor::SendInputPacket,
base::Unretained(this)),
- base::BindRepeating(&FuchsiaStreamDecryptorBase::ProcessEndOfStream,
+ base::BindRepeating(&FuchsiaStreamDecryptor::ProcessEndOfStream,
base::Unretained(this)));
}
-void FuchsiaStreamDecryptorBase::SendInputPacket(
+void FuchsiaStreamDecryptor::SendInputPacket(
const DecoderBuffer* buffer,
StreamProcessorHelper::IoPacket packet) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -217,279 +266,21 @@ void FuchsiaStreamDecryptorBase::SendInputPacket(
processor_.Process(std::move(packet));
}
-void FuchsiaStreamDecryptorBase::ProcessEndOfStream() {
+void FuchsiaStreamDecryptor::ProcessEndOfStream() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
processor_.ProcessEos();
}
-FuchsiaClearStreamDecryptor::FuchsiaClearStreamDecryptor(
- fuchsia::media::StreamProcessorPtr processor,
- size_t min_buffer_size)
- : FuchsiaStreamDecryptorBase(std::move(processor), min_buffer_size) {}
-
-FuchsiaClearStreamDecryptor::~FuchsiaClearStreamDecryptor() = default;
-
-void FuchsiaClearStreamDecryptor::Decrypt(
- scoped_refptr<DecoderBuffer> encrypted,
- Decryptor::DecryptCB decrypt_cb) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(!decrypt_cb_);
-
- decrypt_cb_ = std::move(decrypt_cb);
- current_status_ = Decryptor::kSuccess;
- DecryptInternal(std::move(encrypted));
-}
-
-void FuchsiaClearStreamDecryptor::CancelDecrypt() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- ResetStream();
-
- // Fire |decrypt_cb_| immediately as required by Decryptor::CancelDecrypt.
- if (decrypt_cb_)
- std::move(decrypt_cb_).Run(Decryptor::kSuccess, nullptr);
-}
-
-void FuchsiaClearStreamDecryptor::AllocateOutputBuffers(
- const fuchsia::media::StreamBufferConstraints& stream_constraints) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- output_pool_creator_ =
- allocator_.MakeBufferPoolCreator(1 /* num_shared_token */);
- output_pool_creator_->Create(
- SysmemBufferReader::GetRecommendedConstraints(kMinBufferCount,
- min_buffer_size_),
- base::BindOnce(&FuchsiaClearStreamDecryptor::OnOutputBufferPoolCreated,
- base::Unretained(this)));
-}
-
-void FuchsiaClearStreamDecryptor::OnProcessEos() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- // Decryptor never pushes EOS frame.
- NOTREACHED();
-}
-
-void FuchsiaClearStreamDecryptor::OnOutputPacket(
- StreamProcessorHelper::IoPacket packet) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(decrypt_cb_);
-
- DCHECK(output_reader_);
- if (!output_pool_->is_live()) {
- DLOG(ERROR) << "Output buffer pool is dead.";
- return;
- }
-
- // If that's not the last packet for the current Decrypt() request then just
- // store the output and wait for the next packet.
- if (!packet.unit_end()) {
- size_t pos = output_data_.size();
- output_data_.resize(pos + packet.size());
-
- bool read_success = output_reader_->Read(
- packet.buffer_index(), packet.offset(),
- base::make_span(output_data_.data() + pos, packet.size()));
-
- if (!read_success) {
- // If we've failed to read a partial packet then delay reporting the error
- // until we've received the last packet to make sure we consume all output
- // packets generated by the last Decrypt() call.
- DLOG(ERROR) << "Fail to get decrypted result.";
- current_status_ = Decryptor::kError;
- output_data_.clear();
- }
-
- return;
- }
-
- // We've received the last packet. Assemble DecoderBuffer and pass it to the
- // DecryptCB.
- auto clear_buffer =
- base::MakeRefCounted<DecoderBuffer>(output_data_.size() + packet.size());
- clear_buffer->set_timestamp(packet.timestamp());
-
- // Copy data received in the previous packets.
- memcpy(clear_buffer->writable_data(), output_data_.data(),
- output_data_.size());
- output_data_.clear();
-
- // Copy data received in the last packet
- bool read_success = output_reader_->Read(
- packet.buffer_index(), packet.offset(),
- base::make_span(clear_buffer->writable_data() + output_data_.size(),
- packet.size()));
-
- if (!read_success) {
- DLOG(ERROR) << "Fail to get decrypted result.";
- current_status_ = Decryptor::kError;
- }
-
- std::move(decrypt_cb_)
- .Run(current_status_, current_status_ == Decryptor::kSuccess
- ? std::move(clear_buffer)
- : nullptr);
-}
-
-void FuchsiaClearStreamDecryptor::OnNoKey() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- // Reset the queue. The client is expected to call Decrypt() with the same
- // buffer again when it gets kNoKey.
- input_writer_queue_.ResetQueue();
-
- if (decrypt_cb_)
- std::move(decrypt_cb_).Run(Decryptor::kNoKey, nullptr);
-}
-
-void FuchsiaClearStreamDecryptor::OnError() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- ResetStream();
- if (decrypt_cb_)
- std::move(decrypt_cb_).Run(Decryptor::kError, nullptr);
-}
-
-void FuchsiaClearStreamDecryptor::OnOutputBufferPoolCreated(
- std::unique_ptr<SysmemBufferPool> pool) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- if (!pool) {
- LOG(ERROR) << "Fail to allocate output buffer.";
- OnError();
- return;
- }
-
- output_pool_ = std::move(pool);
-
- // Provide token before enabling reader. Tokens must be provided to
- // StreamProcessor before getting the allocated buffers.
- processor_.CompleteOutputBuffersAllocation(output_pool_->TakeToken());
-
- output_pool_->CreateReader(base::BindOnce(
- &FuchsiaClearStreamDecryptor::OnOutputBufferPoolReaderCreated,
- base::Unretained(this)));
-}
-
-void FuchsiaClearStreamDecryptor::OnOutputBufferPoolReaderCreated(
- std::unique_ptr<SysmemBufferReader> reader) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- if (!reader) {
- LOG(ERROR) << "Fail to enable output buffer reader.";
- OnError();
- return;
- }
-
- DCHECK(!output_reader_);
- output_reader_ = std::move(reader);
-}
-
-FuchsiaSecureStreamDecryptor::FuchsiaSecureStreamDecryptor(
- fuchsia::media::StreamProcessorPtr processor,
- Client* client)
- : FuchsiaStreamDecryptorBase(std::move(processor),
- client->GetInputBufferSize()),
- client_(client) {}
-
-FuchsiaSecureStreamDecryptor::~FuchsiaSecureStreamDecryptor() = default;
-
-void FuchsiaSecureStreamDecryptor::SetOutputBufferCollectionToken(
- fuchsia::sysmem::BufferCollectionTokenPtr token) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(!complete_buffer_allocation_callback_);
- complete_buffer_allocation_callback_ =
- base::BindOnce(&StreamProcessorHelper::CompleteOutputBuffersAllocation,
- base::Unretained(&processor_), std::move(token));
- if (waiting_output_buffers_) {
- std::move(complete_buffer_allocation_callback_).Run();
- waiting_output_buffers_ = false;
- }
-}
-
-void FuchsiaSecureStreamDecryptor::Decrypt(
- scoped_refptr<DecoderBuffer> encrypted) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- DecryptInternal(std::move(encrypted));
-}
-
-void FuchsiaSecureStreamDecryptor::Reset() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- ResetStream();
- waiting_for_key_ = false;
-}
-
-void FuchsiaSecureStreamDecryptor::AllocateOutputBuffers(
- const fuchsia::media::StreamBufferConstraints& stream_constraints) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- if (complete_buffer_allocation_callback_) {
- std::move(complete_buffer_allocation_callback_).Run();
- } else {
- waiting_output_buffers_ = true;
- }
-}
-
-void FuchsiaSecureStreamDecryptor::OnProcessEos() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- client_->OnDecryptorEndOfStreamPacket();
-}
-
-void FuchsiaSecureStreamDecryptor::OnOutputPacket(
- StreamProcessorHelper::IoPacket packet) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- client_->OnDecryptorOutputPacket(std::move(packet));
-}
-
-base::RepeatingClosure FuchsiaSecureStreamDecryptor::GetOnNewKeyClosure() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- return BindToCurrentLoop(base::BindRepeating(
- &FuchsiaSecureStreamDecryptor::OnNewKey, weak_factory_.GetWeakPtr()));
-}
-
-void FuchsiaSecureStreamDecryptor::OnError() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- ResetStream();
-
- // No need to reset other fields since OnError() is called for non-recoverable
- // errors.
-
- client_->OnDecryptorError();
-}
-
-void FuchsiaSecureStreamDecryptor::OnNoKey() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(!waiting_for_key_);
-
- // Reset stream position, but keep all pending buffers. They will be
- // resubmitted later, when we have a new key.
- input_writer_queue_.ResetPositionAndPause();
-
- if (retry_on_no_key_) {
- retry_on_no_key_ = false;
- input_writer_queue_.Unpause();
- return;
- }
-
- waiting_for_key_ = true;
- client_->OnDecryptorNoKey();
-}
-
-void FuchsiaSecureStreamDecryptor::OnNewKey() {
+void FuchsiaStreamDecryptor::OnNewKey() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!waiting_for_key_) {
- retry_on_no_key_ = true;
+ retry_on_no_key_event_ = true;
return;
}
- DCHECK(!retry_on_no_key_);
+ DCHECK(!retry_on_no_key_event_);
waiting_for_key_ = false;
input_writer_queue_.Unpause();
}
diff --git a/chromium/media/fuchsia/cdm/fuchsia_stream_decryptor.h b/chromium/media/fuchsia/cdm/fuchsia_stream_decryptor.h
index e26fa6897a0..bba2d0cbe46 100644
--- a/chromium/media/fuchsia/cdm/fuchsia_stream_decryptor.h
+++ b/chromium/media/fuchsia/cdm/fuchsia_stream_decryptor.h
@@ -11,129 +11,31 @@
#include "base/sequence_checker.h"
#include "media/base/decryptor.h"
+#include "media/base/media_export.h"
#include "media/fuchsia/common/stream_processor_helper.h"
-#include "media/fuchsia/common/sysmem_buffer_pool.h"
-#include "media/fuchsia/common/sysmem_buffer_writer_queue.h"
+#include "media/fuchsia/common/sysmem_buffer_stream.h"
+#include "media/fuchsia/common/sysmem_client.h"
+#include "media/fuchsia/common/vmo_buffer_writer_queue.h"
namespace media {
-class SysmemBufferReader;
-// Base class for media stream decryptor implementations.
-class FuchsiaStreamDecryptorBase : public StreamProcessorHelper::Client {
+// Stream decryptor used to decrypt protected media streams on Fuchsia. Must be
+// created an used on the same thread.
+class MEDIA_EXPORT FuchsiaStreamDecryptor
+ : public SysmemBufferStream,
+ public StreamProcessorHelper::Client {
public:
- FuchsiaStreamDecryptorBase(fuchsia::media::StreamProcessorPtr processor,
- size_t min_buffer_size);
- ~FuchsiaStreamDecryptorBase() override;
+ // Number of buffers that the decryptor allocates for input buffer
+ // collection. Decryptors provided by fuchsia.media.drm API normally decrypt a
+ // single buffer at a time. Second buffer is useful to allow reading/writing a
+ // packet while the decryptor is working on another one.
+ static constexpr size_t kInputBufferCount = 2;
- int GetMaxDecryptRequests() const;
+ explicit FuchsiaStreamDecryptor(fuchsia::media::StreamProcessorPtr processor);
+ ~FuchsiaStreamDecryptor() override;
- protected:
- // StreamProcessorHelper::Client overrides.
- void AllocateInputBuffers(
- const fuchsia::media::StreamBufferConstraints& stream_constraints) final;
- void OnOutputFormat(fuchsia::media::StreamOutputFormat format) final;
-
- void DecryptInternal(scoped_refptr<DecoderBuffer> encrypted);
- void ResetStream();
-
- StreamProcessorHelper processor_;
-
- const size_t min_buffer_size_;
-
- BufferAllocator allocator_;
-
- SysmemBufferWriterQueue input_writer_queue_;
-
- // Key ID for which we received the last OnNewKey() event.
- std::string last_new_key_id_;
-
- SEQUENCE_CHECKER(sequence_checker_);
-
- private:
- void OnInputBufferPoolCreated(std::unique_ptr<SysmemBufferPool> pool);
- void OnWriterCreated(std::unique_ptr<SysmemBufferWriter> writer);
- void SendInputPacket(const DecoderBuffer* buffer,
- StreamProcessorHelper::IoPacket packet);
- void ProcessEndOfStream();
-
- std::unique_ptr<SysmemBufferPool::Creator> input_pool_creator_;
- std::unique_ptr<SysmemBufferPool> input_pool_;
-
- DISALLOW_COPY_AND_ASSIGN(FuchsiaStreamDecryptorBase);
-};
-
-// Stream decryptor that copies output to clear DecodeBuffer's. Used for audio
-// streams.
-class FuchsiaClearStreamDecryptor : public FuchsiaStreamDecryptorBase {
- public:
- static std::unique_ptr<FuchsiaClearStreamDecryptor> Create(
- fuchsia::media::drm::ContentDecryptionModule* cdm,
- size_t min_buffer_size);
-
- FuchsiaClearStreamDecryptor(fuchsia::media::StreamProcessorPtr processor,
- size_t min_buffer_size);
- ~FuchsiaClearStreamDecryptor() override;
-
- // Decrypt() behavior should match media::Decryptor interface.
- void Decrypt(scoped_refptr<DecoderBuffer> encrypted,
- Decryptor::DecryptCB decrypt_cb);
- void CancelDecrypt();
-
- private:
- // StreamProcessorHelper::Client overrides.
- void AllocateOutputBuffers(
- const fuchsia::media::StreamBufferConstraints& stream_constraints) final;
- void OnProcessEos() final;
- void OnOutputPacket(StreamProcessorHelper::IoPacket packet) final;
- void OnNoKey() final;
- void OnError() final;
-
- void OnOutputBufferPoolCreated(std::unique_ptr<SysmemBufferPool> pool);
- void OnOutputBufferPoolReaderCreated(
- std::unique_ptr<SysmemBufferReader> reader);
-
- Decryptor::DecryptCB decrypt_cb_;
-
- std::unique_ptr<SysmemBufferPool::Creator> output_pool_creator_;
- std::unique_ptr<SysmemBufferPool> output_pool_;
- std::unique_ptr<SysmemBufferReader> output_reader_;
-
- // Used to re-assemble decrypted output that was split between multiple sysmem
- // buffers.
- Decryptor::Status current_status_ = Decryptor::kSuccess;
- std::vector<uint8_t> output_data_;
-
- DISALLOW_COPY_AND_ASSIGN(FuchsiaClearStreamDecryptor);
-};
-
-// Stream decryptor that decrypts data to protected sysmem buffers. Used for
-// video stream.
-class FuchsiaSecureStreamDecryptor : public FuchsiaStreamDecryptorBase {
- public:
- class Client {
- public:
- virtual size_t GetInputBufferSize() = 0;
- virtual void OnDecryptorOutputPacket(
- StreamProcessorHelper::IoPacket packet) = 0;
- virtual void OnDecryptorEndOfStreamPacket() = 0;
- virtual void OnDecryptorError() = 0;
- virtual void OnDecryptorNoKey() = 0;
-
- protected:
- virtual ~Client() = default;
- };
-
- FuchsiaSecureStreamDecryptor(fuchsia::media::StreamProcessorPtr processor,
- Client* client);
- ~FuchsiaSecureStreamDecryptor() override;
-
- void SetOutputBufferCollectionToken(
- fuchsia::sysmem::BufferCollectionTokenPtr token);
-
- // Enqueues the specified buffer to the input queue. Caller is allowed to
- // queue as many buffers as it needs without waiting for results from the
- // previous Decrypt() calls.
- void Decrypt(scoped_refptr<DecoderBuffer> encrypted);
+ FuchsiaStreamDecryptor(const FuchsiaStreamDecryptor&) = delete;
+ FuchsiaStreamDecryptor& operator=(const FuchsiaStreamDecryptor&) = delete;
// Returns closure that should be called when the key changes. This class
// uses this notification to handle NO_KEY errors. Note that this class can
@@ -144,42 +46,70 @@ class FuchsiaSecureStreamDecryptor : public FuchsiaStreamDecryptorBase {
// the key is updated.
base::RepeatingClosure GetOnNewKeyClosure();
- // Drops all pending decryption requests.
- void Reset();
+ // SysmemBufferStream implementation.
+ void Initialize(Sink* sink,
+ size_t min_buffer_size,
+ size_t min_buffer_count) override;
+ void EnqueueBuffer(scoped_refptr<DecoderBuffer> buffer) override;
+ void Reset() override;
private:
// StreamProcessorHelper::Client overrides.
- void AllocateOutputBuffers(
+ void OnStreamProcessorAllocateOutputBuffers(
const fuchsia::media::StreamBufferConstraints& stream_constraints) final;
- void OnProcessEos() final;
- void OnOutputPacket(StreamProcessorHelper::IoPacket packet) final;
- void OnNoKey() final;
- void OnError() final;
+ void OnStreamProcessorEndOfStream() final;
+ void OnStreamProcessorOutputFormat(
+ fuchsia::media::StreamOutputFormat format) final;
+ void OnStreamProcessorOutputPacket(
+ StreamProcessorHelper::IoPacket packet) final;
+ void OnStreamProcessorNoKey() final;
+ void OnStreamProcessorError() final;
+
+ void OnError();
+
+ void OnInputBuffersAcquired(
+ std::vector<VmoBuffer> buffers,
+ const fuchsia::sysmem::SingleBufferSettings& buffer_settings);
+ void SendInputPacket(const DecoderBuffer* buffer,
+ StreamProcessorHelper::IoPacket packet);
+ void ProcessEndOfStream();
// Callback returned by GetOnNewKeyClosure(). When waiting for a key this
// method unpauses the stream to decrypt any pending buffers.
void OnNewKey();
- Client* const client_;
+ StreamProcessorHelper processor_;
+
+ SysmemAllocatorClient allocator_;
+
+ Sink* sink_ = nullptr;
- bool waiting_output_buffers_ = false;
- base::OnceClosure complete_buffer_allocation_callback_;
+ size_t min_buffer_size_ = 0;
+ size_t min_buffer_count_ = 0;
+
+ std::unique_ptr<SysmemCollectionClient> input_buffer_collection_;
+ VmoBufferWriterQueue input_writer_queue_;
+
+ std::unique_ptr<SysmemCollectionClient> output_buffer_collection_;
+
+ // Key ID for which we received the last OnNewKey() event.
+ std::string last_new_key_id_;
// Set to true if some keys have been updated recently. New key notifications
// are received from a LicenseSession, while DECRYPTOR_NO_KEY error is
// received from StreamProcessor. These are separate FIDL connections that are
// handled on different threads, so they are not synchronized. As result
// OnNewKey() may be called before we get OnNoKey(). To handle this case
- // correctly OnNewKey() sets |retry_on_no_key_| and then OnNoKey() tries to
- // restart the stream immediately if this flag is set.
- bool retry_on_no_key_ = false;
+ // correctly OnNewKey() sets |retry_on_no_key_event_| and then OnNoKey() tries
+ // to restart the stream immediately if this flag is set.
+ bool retry_on_no_key_event_ = false;
// Set to true if the stream is paused while we are waiting for new keys.
bool waiting_for_key_ = false;
- base::WeakPtrFactory<FuchsiaSecureStreamDecryptor> weak_factory_{this};
+ SEQUENCE_CHECKER(sequence_checker_);
- DISALLOW_COPY_AND_ASSIGN(FuchsiaSecureStreamDecryptor);
+ base::WeakPtrFactory<FuchsiaStreamDecryptor> weak_factory_{this};
};
} // namespace media
diff --git a/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager.cc b/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager.cc
index 7edfa056a86..5fbf4223b89 100644
--- a/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager.cc
+++ b/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager.cc
@@ -18,11 +18,11 @@
#include "base/fuchsia/fuchsia_logging.h"
#include "base/hash/hash.h"
#include "base/logging.h"
-#include "base/optional.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "media/fuchsia/cdm/service/provisioning_fetcher_impl.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/origin.h"
namespace media {
@@ -126,7 +126,7 @@ std::string HexEncodeHash(const std::string& name) {
}
// Returns a nullopt if storage was created successfully.
-base::Optional<base::File::Error> CreateStorageDirectory(base::FilePath path) {
+absl::optional<base::File::Error> CreateStorageDirectory(base::FilePath path) {
base::File::Error error;
bool success = base::CreateDirectoryAndGetError(path, &error);
if (!success) {
@@ -168,7 +168,7 @@ class FuchsiaCdmManager::KeySystemClient {
CreateFetcherCB create_fetcher_callback,
fidl::InterfaceRequest<fuchsia::media::drm::ContentDecryptionModule>
request) {
- base::Optional<DataStoreId> data_store_id = GetDataStoreIdForPath(
+ absl::optional<DataStoreId> data_store_id = GetDataStoreIdForPath(
std::move(storage_path), std::move(create_fetcher_callback));
if (!data_store_id) {
request.Close(ZX_ERR_NO_RESOURCES);
@@ -186,7 +186,7 @@ class FuchsiaCdmManager::KeySystemClient {
private:
using DataStoreId = uint32_t;
- base::Optional<DataStoreId> GetDataStoreIdForPath(
+ absl::optional<DataStoreId> GetDataStoreIdForPath(
base::FilePath storage_path,
CreateFetcherCB create_fetcher_callback) {
// If we have already added a data store id for that path, just use that
@@ -200,7 +200,7 @@ class FuchsiaCdmManager::KeySystemClient {
base::OpenDirectoryHandle(storage_path);
if (!data_directory.is_valid()) {
DLOG(ERROR) << "Unable to OpenDirectory " << storage_path;
- return base::nullopt;
+ return absl::nullopt;
}
auto provisioning_fetcher = std::make_unique<ProvisioningFetcherImpl>(
@@ -264,7 +264,7 @@ class FuchsiaCdmManager::KeySystemClient {
FuchsiaCdmManager::FuchsiaCdmManager(
CreateKeySystemCallbackMap create_key_system_callbacks_by_name,
base::FilePath cdm_data_path,
- base::Optional<uint64_t> cdm_data_quota_bytes)
+ absl::optional<uint64_t> cdm_data_quota_bytes)
: create_key_system_callbacks_by_name_(
std::move(create_key_system_callbacks_by_name)),
cdm_data_path_(std::move(cdm_data_path)),
@@ -352,7 +352,7 @@ void FuchsiaCdmManager::CreateCdm(
fidl::InterfaceRequest<fuchsia::media::drm::ContentDecryptionModule>
request,
base::FilePath storage_path,
- base::Optional<base::File::Error> storage_creation_error) {
+ absl::optional<base::File::Error> storage_creation_error) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (storage_creation_error) {
diff --git a/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager.h b/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager.h
index 40f91be48fa..718b3adcc17 100644
--- a/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager.h
+++ b/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager.h
@@ -14,10 +14,10 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/thread_checker.h"
#include "media/base/provision_fetcher.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace url {
class Origin;
@@ -41,7 +41,7 @@ class FuchsiaCdmManager {
FuchsiaCdmManager(
CreateKeySystemCallbackMap create_key_system_callbacks_by_name,
base::FilePath cdm_data_path,
- base::Optional<uint64_t> cdm_data_quota_bytes);
+ absl::optional<uint64_t> cdm_data_quota_bytes);
~FuchsiaCdmManager();
@@ -76,13 +76,13 @@ class FuchsiaCdmManager {
fidl::InterfaceRequest<fuchsia::media::drm::ContentDecryptionModule>
request,
base::FilePath storage_path,
- base::Optional<base::File::Error> storage_creation_error);
+ absl::optional<base::File::Error> storage_creation_error);
void OnKeySystemClientError(const std::string& key_system_name);
// A map of callbacks to create KeySystem channels indexed by their EME name.
const CreateKeySystemCallbackMap create_key_system_callbacks_by_name_;
const base::FilePath cdm_data_path_;
- const base::Optional<uint64_t> cdm_data_quota_bytes_;
+ const absl::optional<uint64_t> cdm_data_quota_bytes_;
// Used for operations on the CDM data directory.
const scoped_refptr<base::SequencedTaskRunner> storage_task_runner_;
diff --git a/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager_unittest.cc b/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager_unittest.cc
index 64a011a535e..4e6ef5a9c4e 100644
--- a/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager_unittest.cc
+++ b/chromium/media/fuchsia/cdm/service/fuchsia_cdm_manager_unittest.cc
@@ -78,7 +78,7 @@ class FuchsiaCdmManagerTest : public ::testing::Test {
std::unique_ptr<FuchsiaCdmManager> CreateFuchsiaCdmManager(
std::vector<base::StringPiece> key_systems,
- base::Optional<uint64_t> cdm_data_quota_bytes = base::nullopt) {
+ absl::optional<uint64_t> cdm_data_quota_bytes = absl::nullopt) {
FuchsiaCdmManager::CreateKeySystemCallbackMap create_key_system_callbacks;
for (const base::StringPiece& name : key_systems) {
diff --git a/chromium/media/fuchsia/common/BUILD.gn b/chromium/media/fuchsia/common/BUILD.gn
index a7190bf4cde..381db174a5f 100644
--- a/chromium/media/fuchsia/common/BUILD.gn
+++ b/chromium/media/fuchsia/common/BUILD.gn
@@ -6,18 +6,23 @@ assert(is_fuchsia)
source_set("common") {
sources = [
+ "decrypting_sysmem_buffer_stream.cc",
+ "decrypting_sysmem_buffer_stream.h",
+ "passthrough_sysmem_buffer_stream.cc",
+ "passthrough_sysmem_buffer_stream.h",
"stream_processor_helper.cc",
"stream_processor_helper.h",
- "sysmem_buffer_pool.cc",
- "sysmem_buffer_pool.h",
- "sysmem_buffer_reader.cc",
- "sysmem_buffer_reader.h",
- "sysmem_buffer_writer.cc",
- "sysmem_buffer_writer.h",
- "sysmem_buffer_writer_queue.cc",
- "sysmem_buffer_writer_queue.h",
+ "sysmem_buffer_stream.h",
+ "sysmem_client.cc",
+ "sysmem_client.h",
+ "vmo_buffer.cc",
+ "vmo_buffer.h",
+ "vmo_buffer_writer_queue.cc",
+ "vmo_buffer_writer_queue.h",
]
+ configs += [ "//media:subcomponent_config" ]
+
deps = [
"//base",
"//media/base",
diff --git a/chromium/media/fuchsia/common/decrypting_sysmem_buffer_stream.cc b/chromium/media/fuchsia/common/decrypting_sysmem_buffer_stream.cc
new file mode 100644
index 00000000000..51a74989c83
--- /dev/null
+++ b/chromium/media/fuchsia/common/decrypting_sysmem_buffer_stream.cc
@@ -0,0 +1,123 @@
+// Copyright 2021 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 "media/fuchsia/common/decrypting_sysmem_buffer_stream.h"
+
+#include "media/base/callback_registry.h"
+#include "media/base/decoder_buffer.h"
+
+namespace media {
+
+DecryptingSysmemBufferStream::DecryptingSysmemBufferStream(
+ SysmemAllocatorClient* sysmem_allocator,
+ CdmContext* cdm_context,
+ Decryptor::StreamType stream_type)
+ : passthrough_stream_(sysmem_allocator),
+ decryptor_(cdm_context->GetDecryptor()),
+ stream_type_(stream_type) {
+ DCHECK(decryptor_);
+
+ event_cb_registration_ = cdm_context->RegisterEventCB(
+ base::BindRepeating(&DecryptingSysmemBufferStream::OnCdmContextEvent,
+ weak_factory_.GetWeakPtr()));
+}
+
+DecryptingSysmemBufferStream::~DecryptingSysmemBufferStream() = default;
+
+void DecryptingSysmemBufferStream::Initialize(Sink* sink,
+ size_t min_buffer_size,
+ size_t min_buffer_count) {
+ sink_ = sink;
+ passthrough_stream_.Initialize(sink, min_buffer_size, min_buffer_count);
+}
+
+void DecryptingSysmemBufferStream::EnqueueBuffer(
+ scoped_refptr<DecoderBuffer> buffer) {
+ buffer_queue_.push_back(std::move(buffer));
+ DecryptNextBuffer();
+}
+
+void DecryptingSysmemBufferStream::Reset() {
+ buffer_queue_.clear();
+
+ if (state_ == State::kDecryptPending) {
+ decryptor_->CancelDecrypt(stream_type_);
+ }
+
+ state_ = State::kIdle;
+ retry_on_no_key_ = false;
+}
+
+void DecryptingSysmemBufferStream::OnCdmContextEvent(CdmContext::Event event) {
+ if (event != CdmContext::Event::kHasAdditionalUsableKey)
+ return;
+
+ switch (state_) {
+ case State::kIdle:
+ break;
+
+ case State::kDecryptPending:
+ retry_on_no_key_ = true;
+ break;
+
+ case State::kWaitingKey:
+ state_ = State::kIdle;
+ DecryptNextBuffer();
+ break;
+ }
+}
+
+void DecryptingSysmemBufferStream::DecryptNextBuffer() {
+ if (buffer_queue_.empty() || state_ != State::kIdle)
+ return;
+
+ if (buffer_queue_.front()->end_of_stream()) {
+ scoped_refptr<DecoderBuffer> buffer = std::move(buffer_queue_.front());
+ buffer_queue_.pop_front();
+ DCHECK(buffer_queue_.empty());
+ passthrough_stream_.EnqueueBuffer(std::move(buffer));
+ return;
+ }
+
+ state_ = State::kDecryptPending;
+ decryptor_->Decrypt(
+ stream_type_, buffer_queue_.front(),
+ base::BindOnce(&DecryptingSysmemBufferStream::OnBufferDecrypted,
+ weak_factory_.GetWeakPtr()));
+}
+
+void DecryptingSysmemBufferStream::OnBufferDecrypted(
+ Decryptor::Status status,
+ scoped_refptr<DecoderBuffer> decrypted_buffer) {
+ DCHECK(state_ == State::kDecryptPending);
+ state_ = State::kIdle;
+
+ switch (status) {
+ case Decryptor::kError:
+ sink_->OnSysmemBufferStreamError();
+ return;
+
+ case Decryptor::kNoKey:
+ if (retry_on_no_key_) {
+ retry_on_no_key_ = false;
+ DecryptNextBuffer();
+ } else {
+ state_ = State::kWaitingKey;
+ sink_->OnSysmemBufferStreamNoKey();
+ }
+ return;
+
+ case Decryptor::kNeedMoreData:
+ break;
+
+ case Decryptor::kSuccess:
+ passthrough_stream_.EnqueueBuffer(std::move(decrypted_buffer));
+ }
+
+ buffer_queue_.pop_front();
+
+ DecryptNextBuffer();
+}
+
+} // namespace media
diff --git a/chromium/media/fuchsia/common/decrypting_sysmem_buffer_stream.h b/chromium/media/fuchsia/common/decrypting_sysmem_buffer_stream.h
new file mode 100644
index 00000000000..8fb00306abf
--- /dev/null
+++ b/chromium/media/fuchsia/common/decrypting_sysmem_buffer_stream.h
@@ -0,0 +1,66 @@
+// Copyright 2021 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 MEDIA_FUCHSIA_COMMON_DECRYPTING_SYSMEM_BUFFER_STREAM_H_
+#define MEDIA_FUCHSIA_COMMON_DECRYPTING_SYSMEM_BUFFER_STREAM_H_
+
+#include "media/fuchsia/common/passthrough_sysmem_buffer_stream.h"
+
+#include <deque>
+
+#include "media/base/cdm_context.h"
+#include "media/base/decryptor.h"
+
+namespace media {
+
+// A SysmemBufferStream that decrypts the stream before copying the data to
+// sysmem buffers.
+class MEDIA_EXPORT DecryptingSysmemBufferStream : public SysmemBufferStream {
+ public:
+ DecryptingSysmemBufferStream(SysmemAllocatorClient* sysmem_allocator,
+ CdmContext* cdm_context,
+ Decryptor::StreamType stream_type);
+ ~DecryptingSysmemBufferStream() override;
+
+ DecryptingSysmemBufferStream(const DecryptingSysmemBufferStream&) = delete;
+ DecryptingSysmemBufferStream& operator=(const DecryptingSysmemBufferStream&) =
+ delete;
+
+ // SysmemBufferStream implementation:
+ void Initialize(Sink* sink,
+ size_t min_buffer_size,
+ size_t min_buffer_count) override;
+ void EnqueueBuffer(scoped_refptr<DecoderBuffer> buffer) override;
+ void Reset() override;
+
+ private:
+ enum class State {
+ kIdle,
+ kDecryptPending,
+ kWaitingKey,
+ };
+
+ void OnCdmContextEvent(CdmContext::Event event);
+ void DecryptNextBuffer();
+ void OnBufferDecrypted(Decryptor::Status status,
+ scoped_refptr<DecoderBuffer> decrypted_buffer);
+
+ PassthroughSysmemBufferStream passthrough_stream_;
+ Decryptor* const decryptor_;
+ const Decryptor::StreamType stream_type_;
+
+ std::unique_ptr<CallbackRegistration> event_cb_registration_;
+
+ Sink* sink_ = nullptr;
+ std::deque<scoped_refptr<DecoderBuffer>> buffer_queue_;
+ State state_ = State::kIdle;
+
+ bool retry_on_no_key_ = false;
+
+ base::WeakPtrFactory<DecryptingSysmemBufferStream> weak_factory_{this};
+};
+
+} // namespace media
+
+#endif // MEDIA_FUCHSIA_COMMON_DECRYPTING_SYSMEM_BUFFER_STREAM_H_ \ No newline at end of file
diff --git a/chromium/media/fuchsia/common/passthrough_sysmem_buffer_stream.cc b/chromium/media/fuchsia/common/passthrough_sysmem_buffer_stream.cc
new file mode 100644
index 00000000000..bb04295fbe0
--- /dev/null
+++ b/chromium/media/fuchsia/common/passthrough_sysmem_buffer_stream.cc
@@ -0,0 +1,71 @@
+// Copyright 2021 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 "media/fuchsia/common/passthrough_sysmem_buffer_stream.h"
+
+#include "media/base/decoder_buffer.h"
+
+namespace media {
+
+PassthroughSysmemBufferStream::PassthroughSysmemBufferStream(
+ SysmemAllocatorClient* sysmem_allocator)
+ : sysmem_allocator_(sysmem_allocator) {
+ DCHECK(sysmem_allocator_);
+}
+
+PassthroughSysmemBufferStream::~PassthroughSysmemBufferStream() = default;
+
+void PassthroughSysmemBufferStream::Initialize(Sink* sink,
+ size_t min_buffer_size,
+ size_t min_buffer_count) {
+ DCHECK(sink);
+ sink_ = sink;
+
+ fuchsia::sysmem::BufferCollectionConstraints buffer_constraints =
+ VmoBuffer::GetRecommendedConstraints(min_buffer_count, min_buffer_size,
+ /*writable=*/true);
+
+ // Create buffer collection.
+ output_buffer_collection_ = sysmem_allocator_->AllocateNewCollection();
+ output_buffer_collection_->CreateSharedToken(
+ base::BindOnce(&Sink::OnSysmemBufferStreamBufferCollectionToken,
+ base::Unretained(sink_)));
+ output_buffer_collection_->Initialize(std::move(buffer_constraints),
+ "CrPassthroughSysmemBufferStream");
+ output_buffer_collection_->AcquireBuffers(
+ base::BindOnce(&PassthroughSysmemBufferStream::OnBuffersAcquired,
+ base::Unretained(this)));
+}
+
+void PassthroughSysmemBufferStream::EnqueueBuffer(
+ scoped_refptr<DecoderBuffer> buffer) {
+ queue_.EnqueueBuffer(std::move(buffer));
+}
+
+void PassthroughSysmemBufferStream::Reset() {
+ queue_.ResetQueue();
+}
+
+void PassthroughSysmemBufferStream::OnBuffersAcquired(
+ std::vector<VmoBuffer> buffers,
+ const fuchsia::sysmem::SingleBufferSettings& buffer_settings) {
+ queue_.Start(
+ std::move(buffers),
+ base::BindRepeating(&PassthroughSysmemBufferStream::ProcessOutputPacket,
+ base::Unretained(this)),
+ base::BindRepeating(&PassthroughSysmemBufferStream::ProcessEndOfStream,
+ base::Unretained(this)));
+}
+
+void PassthroughSysmemBufferStream::ProcessOutputPacket(
+ const DecoderBuffer* buffer,
+ StreamProcessorHelper::IoPacket packet) {
+ sink_->OnSysmemBufferStreamOutputPacket(std::move(packet));
+}
+
+void PassthroughSysmemBufferStream::ProcessEndOfStream() {
+ sink_->OnSysmemBufferStreamEndOfStream();
+}
+
+} // namespace media
diff --git a/chromium/media/fuchsia/common/passthrough_sysmem_buffer_stream.h b/chromium/media/fuchsia/common/passthrough_sysmem_buffer_stream.h
new file mode 100644
index 00000000000..4cd9373e781
--- /dev/null
+++ b/chromium/media/fuchsia/common/passthrough_sysmem_buffer_stream.h
@@ -0,0 +1,52 @@
+// Copyright 2021 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 MEDIA_FUCHSIA_COMMON_PASSTHROUGH_SYSMEM_BUFFER_STREAM_H_
+#define MEDIA_FUCHSIA_COMMON_PASSTHROUGH_SYSMEM_BUFFER_STREAM_H_
+
+#include "media/fuchsia/common/sysmem_buffer_stream.h"
+#include "media/fuchsia/common/sysmem_client.h"
+#include "media/fuchsia/common/vmo_buffer_writer_queue.h"
+
+namespace media {
+
+// A SysmemBufferStream that simply writes the stream to sysmem buffers.
+class MEDIA_EXPORT PassthroughSysmemBufferStream : public SysmemBufferStream {
+ public:
+ explicit PassthroughSysmemBufferStream(
+ SysmemAllocatorClient* sysmem_allocator);
+ ~PassthroughSysmemBufferStream() override;
+
+ PassthroughSysmemBufferStream(const PassthroughSysmemBufferStream&) = delete;
+ PassthroughSysmemBufferStream& operator=(
+ const PassthroughSysmemBufferStream&) = delete;
+
+ // SysmemBufferStream implementation:
+ void Initialize(Sink* sink,
+ size_t min_buffer_size,
+ size_t min_buffer_count) override;
+ void EnqueueBuffer(scoped_refptr<DecoderBuffer> buffer) override;
+ void Reset() override;
+
+ private:
+ void OnBuffersAcquired(
+ std::vector<VmoBuffer> buffers,
+ const fuchsia::sysmem::SingleBufferSettings& buffer_settings);
+
+ // Callbacks for VmoBufferWriterQueue.
+ void ProcessOutputPacket(const DecoderBuffer* buffer,
+ StreamProcessorHelper::IoPacket packet);
+ void ProcessEndOfStream();
+
+ Sink* sink_ = nullptr;
+
+ SysmemAllocatorClient* const sysmem_allocator_;
+ std::unique_ptr<SysmemCollectionClient> output_buffer_collection_;
+
+ VmoBufferWriterQueue queue_;
+};
+
+} // namespace media
+
+#endif // MEDIA_FUCHSIA_COMMON_PASSTHROUGH_SYSMEM_BUFFER_STREAM_H_ \ No newline at end of file
diff --git a/chromium/media/fuchsia/common/stream_processor_helper.cc b/chromium/media/fuchsia/common/stream_processor_helper.cc
index 17b95bef191..0ca556a7ac3 100644
--- a/chromium/media/fuchsia/common/stream_processor_helper.cc
+++ b/chromium/media/fuchsia/common/stream_processor_helper.cc
@@ -6,9 +6,18 @@
#include "base/bind.h"
#include "base/fuchsia/fuchsia_logging.h"
+#include "media/base/timestamp_constants.h"
namespace media {
+namespace {
+
+// Input buffers are allocate once per decoder, the |buffer_lifetime_ordinal| is
+// always the same.
+constexpr uint64_t kInputBufferLifetimeOrdinal = 1;
+
+} // namespace
+
StreamProcessorHelper::IoPacket::IoPacket(size_t index,
size_t offset,
size_t size,
@@ -19,36 +28,23 @@ StreamProcessorHelper::IoPacket::IoPacket(size_t index,
offset_(offset),
size_(size),
timestamp_(timestamp),
- unit_end_(unit_end),
- destroy_cb_(std::move(destroy_cb)) {}
+ unit_end_(unit_end) {
+ destroy_callbacks_.push_front(std::move(destroy_cb));
+}
-StreamProcessorHelper::IoPacket::~IoPacket() = default;
+StreamProcessorHelper::IoPacket::~IoPacket() {
+ for (auto& cb : destroy_callbacks_) {
+ std::move(cb).Run();
+ }
+}
StreamProcessorHelper::IoPacket::IoPacket(IoPacket&&) = default;
StreamProcessorHelper::IoPacket& StreamProcessorHelper::IoPacket::operator=(
IoPacket&&) = default;
-// static
-StreamProcessorHelper::IoPacket StreamProcessorHelper::IoPacket::CreateInput(
- size_t index,
- size_t size,
- base::TimeDelta timestamp,
- bool unit_end,
- base::OnceClosure destroy_cb) {
- return IoPacket(index, 0 /* offset */, size, timestamp, unit_end,
- std::move(destroy_cb));
-}
-
-// static
-StreamProcessorHelper::IoPacket StreamProcessorHelper::IoPacket::CreateOutput(
- size_t index,
- size_t offset,
- size_t size,
- base::TimeDelta timestamp,
- bool unit_end,
- base::OnceClosure destroy_cb) {
- return IoPacket(index, offset, size, timestamp, unit_end,
- std::move(destroy_cb));
+void StreamProcessorHelper::IoPacket::AddOnDestroyClosure(
+ base::OnceClosure closure) {
+ destroy_callbacks_.push_front(std::move(closure));
}
StreamProcessorHelper::StreamProcessorHelper(
@@ -68,8 +64,6 @@ StreamProcessorHelper::StreamProcessorHelper(
processor_.events().OnStreamFailed =
fit::bind_member(this, &StreamProcessorHelper::OnStreamFailed);
- processor_.events().OnInputConstraints =
- fit::bind_member(this, &StreamProcessorHelper::OnInputConstraints);
processor_.events().OnFreeInputPacket =
fit::bind_member(this, &StreamProcessorHelper::OnFreeInputPacket);
processor_.events().OnOutputConstraints =
@@ -94,7 +88,7 @@ void StreamProcessorHelper::Process(IoPacket input) {
fuchsia::media::Packet packet;
packet.mutable_header()->set_buffer_lifetime_ordinal(
- input_buffer_lifetime_ordinal_);
+ kInputBufferLifetimeOrdinal);
packet.mutable_header()->set_packet_index(input.buffer_index());
packet.set_buffer_index(packet.header().packet_index());
packet.set_timestamp_ish(input.timestamp().InNanoseconds());
@@ -154,43 +148,23 @@ void StreamProcessorHelper::OnStreamFailed(uint64_t stream_lifetime_ordinal,
// Always reset the stream since the current one has failed.
Reset();
- client_->OnNoKey();
+ client_->OnStreamProcessorNoKey();
return;
}
OnError();
}
-void StreamProcessorHelper::OnInputConstraints(
- fuchsia::media::StreamBufferConstraints constraints) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- // Buffer lifetime ordinal is an odd number incremented by 2 for each buffer
- // generation as required by StreamProcessor.
- input_buffer_lifetime_ordinal_ += 2;
-
- DCHECK(input_packets_.empty());
- input_buffer_constraints_ = std::move(constraints);
-
- client_->AllocateInputBuffers(input_buffer_constraints_);
-}
-
void StreamProcessorHelper::OnFreeInputPacket(
fuchsia::media::PacketHeader free_input_packet) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!free_input_packet.has_buffer_lifetime_ordinal() ||
- !free_input_packet.has_packet_index()) {
+ if (!free_input_packet.has_packet_index()) {
DLOG(ERROR) << "Received OnFreeInputPacket() with missing required fields.";
OnError();
return;
}
- if (free_input_packet.buffer_lifetime_ordinal() !=
- input_buffer_lifetime_ordinal_) {
- return;
- }
-
auto it = input_packets_.find(free_input_packet.packet_index());
if (it == input_packets_.end()) {
DLOG(ERROR) << "Received OnFreeInputPacket() with invalid packet index.";
@@ -240,7 +214,7 @@ void StreamProcessorHelper::OnOutputConstraints(
output_buffer_constraints_ =
std::move(*output_constraints.mutable_buffer_constraints());
- client_->AllocateOutputBuffers(output_buffer_constraints_);
+ client_->OnStreamProcessorAllocateOutputBuffers(output_buffer_constraints_);
}
void StreamProcessorHelper::OnOutputFormat(
@@ -258,7 +232,7 @@ void StreamProcessorHelper::OnOutputFormat(
return;
}
- client_->OnOutputFormat(std::move(output_format));
+ client_->OnStreamProcessorOutputFormat(std::move(output_format));
}
void StreamProcessorHelper::OnOutputPacket(fuchsia::media::Packet output_packet,
@@ -290,12 +264,12 @@ void StreamProcessorHelper::OnOutputPacket(fuchsia::media::Packet output_packet,
auto buffer_index = output_packet.buffer_index();
auto packet_index = output_packet.header().packet_index();
- base::TimeDelta timestamp;
- if (output_packet.has_timestamp_ish()) {
- timestamp = base::TimeDelta::FromNanoseconds(output_packet.timestamp_ish());
- }
+ base::TimeDelta timestamp =
+ output_packet.has_timestamp_ish()
+ ? base::TimeDelta::FromNanoseconds(output_packet.timestamp_ish())
+ : kNoTimestamp;
- client_->OnOutputPacket(IoPacket::CreateOutput(
+ client_->OnStreamProcessorOutputPacket(IoPacket(
buffer_index, output_packet.start_offset(),
output_packet.valid_length_bytes(), timestamp,
output_packet.known_end_access_unit(),
@@ -315,22 +289,21 @@ void StreamProcessorHelper::OnOutputEndOfStream(
stream_lifetime_ordinal_ += 2;
active_stream_ = false;
- client_->OnProcessEos();
+ client_->OnStreamProcessorEndOfStream();
}
void StreamProcessorHelper::OnError() {
processor_.Unbind();
- client_->OnError();
+ client_->OnStreamProcessorError();
}
-void StreamProcessorHelper::CompleteInputBuffersAllocation(
+void StreamProcessorHelper::SetInputBufferCollectionToken(
fuchsia::sysmem::BufferCollectionTokenPtr sysmem_token) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!input_buffer_constraints_.IsEmpty());
+
fuchsia::media::StreamBufferPartialSettings settings;
- settings.set_buffer_lifetime_ordinal(input_buffer_lifetime_ordinal_);
- settings.set_buffer_constraints_version_ordinal(
- input_buffer_constraints_.buffer_constraints_version_ordinal());
+ settings.set_buffer_lifetime_ordinal(kInputBufferLifetimeOrdinal);
+ settings.set_buffer_constraints_version_ordinal(0);
settings.set_sysmem_token(std::move(sysmem_token));
processor_->SetInputBufferPartialSettings(std::move(settings));
}
diff --git a/chromium/media/fuchsia/common/stream_processor_helper.h b/chromium/media/fuchsia/common/stream_processor_helper.h
index 3b333d15daa..c2e32de77a4 100644
--- a/chromium/media/fuchsia/common/stream_processor_helper.h
+++ b/chromium/media/fuchsia/common/stream_processor_helper.h
@@ -8,14 +8,16 @@
#include <fuchsia/media/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
+#include <forward_list>
+
#include "base/callback.h"
-#include "base/callback_helpers.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
+#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -23,23 +25,10 @@ namespace media {
// 1. Data validation check.
// 2. Stream/Buffer life time management.
// 3. Configure StreamProcessor and input/output buffer settings.
-class StreamProcessorHelper {
+class MEDIA_EXPORT StreamProcessorHelper {
public:
- class IoPacket {
+ class MEDIA_EXPORT IoPacket {
public:
- static IoPacket CreateInput(size_t index,
- size_t size,
- base::TimeDelta timestamp,
- bool unit_end,
- base::OnceClosure destroy_cb);
-
- static IoPacket CreateOutput(size_t index,
- size_t offset,
- size_t size,
- base::TimeDelta timestamp,
- bool unit_end,
- base::OnceClosure destroy_cb);
-
IoPacket(size_t index,
size_t offset,
size_t size,
@@ -61,6 +50,9 @@ class StreamProcessorHelper {
}
const fuchsia::media::FormatDetails& format() const { return format_; }
+ // Adds a |closure| that will be called when the packet is destroyed.
+ void AddOnDestroyClosure(base::OnceClosure closure);
+
private:
size_t index_;
size_t offset_;
@@ -68,38 +60,36 @@ class StreamProcessorHelper {
base::TimeDelta timestamp_;
bool unit_end_;
fuchsia::media::FormatDetails format_;
- base::ScopedClosureRunner destroy_cb_;
+ std::forward_list<base::OnceClosure> destroy_callbacks_;
DISALLOW_COPY_AND_ASSIGN(IoPacket);
};
class Client {
public:
- // Allocate input/output buffers with the given constraints. Client should
- // call ProvideInput/OutputBufferCollectionToken to finish the buffer
- // allocation flow.
- virtual void AllocateInputBuffers(
- const fuchsia::media::StreamBufferConstraints& stream_constraints) = 0;
- virtual void AllocateOutputBuffers(
+ // Allocate output buffers with the given constraints. Client should call
+ // ProvideIOutputBufferCollectionToken to finish the buffer allocation flow.
+ virtual void OnStreamProcessorAllocateOutputBuffers(
const fuchsia::media::StreamBufferConstraints& stream_constraints) = 0;
// Called when all the pushed packets are processed.
- virtual void OnProcessEos() = 0;
+ virtual void OnStreamProcessorEndOfStream() = 0;
// Called when output format is available.
- virtual void OnOutputFormat(fuchsia::media::StreamOutputFormat format) = 0;
+ virtual void OnStreamProcessorOutputFormat(
+ fuchsia::media::StreamOutputFormat format) = 0;
// Called when output packet is available. Deleting |packet| will notify
// StreamProcessor the output buffer is available to be re-used. Client
// should delete |packet| on the same thread as this function.
- virtual void OnOutputPacket(IoPacket packet) = 0;
+ virtual void OnStreamProcessorOutputPacket(IoPacket packet) = 0;
// Only available for decryption, which indicates currently the
// StreamProcessor doesn't have the content key to process.
- virtual void OnNoKey() = 0;
+ virtual void OnStreamProcessorNoKey() = 0;
// Called when any fatal errors happens.
- virtual void OnError() = 0;
+ virtual void OnStreamProcessorError() = 0;
protected:
virtual ~Client() = default;
@@ -117,10 +107,12 @@ class StreamProcessorHelper {
// StreamProcessor without calling Reset.
void ProcessEos();
- // Provide input/output BufferCollectionToken to finish StreamProcessor buffer
- // setup flow.
- void CompleteInputBuffersAllocation(
+ // Sets buffer collection tocken to use for input buffers.
+ void SetInputBufferCollectionToken(
fuchsia::sysmem::BufferCollectionTokenPtr token);
+
+ // Provide output BufferCollectionToken to finish StreamProcessor buffer
+ // setup flow. Should be called only after AllocateOutputBuffers.
void CompleteOutputBuffersAllocation(
fuchsia::sysmem::BufferCollectionTokenPtr token);
@@ -156,10 +148,6 @@ class StreamProcessorHelper {
// stream_lifetime_ordinal_.
bool active_stream_ = false;
- // Input buffers.
- uint64_t input_buffer_lifetime_ordinal_ = 1;
- fuchsia::media::StreamBufferConstraints input_buffer_constraints_;
-
// Map from packet index to corresponding input IoPacket. IoPacket should be
// owned by this class until StreamProcessor released the buffer.
base::flat_map<size_t, IoPacket> input_packets_;
diff --git a/chromium/media/fuchsia/common/sysmem_buffer_pool.cc b/chromium/media/fuchsia/common/sysmem_buffer_pool.cc
deleted file mode 100644
index de5e197c1c3..00000000000
--- a/chromium/media/fuchsia/common/sysmem_buffer_pool.cc
+++ /dev/null
@@ -1,196 +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 "media/fuchsia/common/sysmem_buffer_pool.h"
-
-#include <zircon/rights.h>
-#include <algorithm>
-
-#include "base/bind.h"
-#include "base/fuchsia/fuchsia_logging.h"
-#include "base/fuchsia/process_context.h"
-#include "base/process/process_handle.h"
-#include "media/fuchsia/common/sysmem_buffer_reader.h"
-#include "media/fuchsia/common/sysmem_buffer_writer.h"
-
-namespace media {
-
-SysmemBufferPool::Creator::Creator(
- fuchsia::sysmem::BufferCollectionPtr collection,
- std::vector<fuchsia::sysmem::BufferCollectionTokenPtr> shared_tokens)
- : collection_(std::move(collection)),
- shared_tokens_(std::move(shared_tokens)) {
- collection_.set_error_handler(
- [this](zx_status_t status) {
- ZX_DLOG(ERROR, status)
- << "Connection to BufferCollection was disconnected.";
- collection_.Unbind();
-
- if (create_cb_)
- std::move(create_cb_).Run(nullptr);
- });
-}
-
-SysmemBufferPool::Creator::~Creator() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-}
-
-void SysmemBufferPool::Creator::SetName(uint32_t priority,
- base::StringPiece name) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!create_cb_);
- collection_->SetName(priority, std::string(name));
-}
-
-void SysmemBufferPool::Creator::Create(
- fuchsia::sysmem::BufferCollectionConstraints constraints,
- CreateCB create_cb) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!create_cb_);
- create_cb_ = std::move(create_cb);
- // BufferCollection needs to be synchronized to ensure that all token
- // duplicate requests have been processed and sysmem knows about all clients
- // that will be using this buffer collection.
- collection_->Sync([this, constraints = std::move(constraints)]() mutable {
- collection_->SetConstraints(true /* has constraints */,
- std::move(constraints));
-
- DCHECK(create_cb_);
- std::move(create_cb_)
- .Run(std::make_unique<SysmemBufferPool>(std::move(collection_),
- std::move(shared_tokens_)));
- });
-}
-
-SysmemBufferPool::SysmemBufferPool(
- fuchsia::sysmem::BufferCollectionPtr collection,
- std::vector<fuchsia::sysmem::BufferCollectionTokenPtr> shared_tokens)
- : collection_(std::move(collection)),
- shared_tokens_(std::move(shared_tokens)) {
- collection_.set_error_handler([this](zx_status_t status) {
- ZX_LOG(ERROR, status) << "fuchsia.sysmem.BufferCollection disconnected.";
- OnError();
- });
-}
-
-SysmemBufferPool::~SysmemBufferPool() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (collection_)
- collection_->Close();
-}
-
-fuchsia::sysmem::BufferCollectionTokenPtr SysmemBufferPool::TakeToken() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!shared_tokens_.empty());
- auto token = std::move(shared_tokens_.back());
- shared_tokens_.pop_back();
- return token;
-}
-
-void SysmemBufferPool::CreateReader(CreateReaderCB create_cb) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!create_reader_cb_);
- create_reader_cb_ = std::move(create_cb);
- collection_->WaitForBuffersAllocated(
- fit::bind_member(this, &SysmemBufferPool::OnBuffersAllocated));
-}
-
-void SysmemBufferPool::CreateWriter(CreateWriterCB create_cb) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!create_writer_cb_);
- create_writer_cb_ = std::move(create_cb);
- collection_->WaitForBuffersAllocated(
- fit::bind_member(this, &SysmemBufferPool::OnBuffersAllocated));
-}
-
-void SysmemBufferPool::OnBuffersAllocated(
- zx_status_t status,
- fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- if (status != ZX_OK) {
- ZX_LOG(ERROR, status) << "Fail to allocate sysmem buffers.";
- OnError();
- return;
- }
-
- if (create_reader_cb_) {
- std::move(create_reader_cb_)
- .Run(SysmemBufferReader::Create(std::move(buffer_collection_info)));
- } else if (create_writer_cb_) {
- std::move(create_writer_cb_)
- .Run(SysmemBufferWriter::Create(std::move(buffer_collection_info)));
- }
-}
-
-void SysmemBufferPool::OnError() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- collection_.Unbind();
- if (create_reader_cb_)
- std::move(create_reader_cb_).Run(nullptr);
- if (create_writer_cb_)
- std::move(create_writer_cb_).Run(nullptr);
-}
-
-BufferAllocator::BufferAllocator(base::StringPiece client_name) {
- allocator_ = base::ComponentContextForProcess()
- ->svc()
- ->Connect<fuchsia::sysmem::Allocator>();
-
- allocator_->SetDebugClientInfo(std::string(client_name),
- base::GetCurrentProcId());
-
- allocator_.set_error_handler([](zx_status_t status) {
- // Just log a warning. We will handle BufferCollection the failure when
- // trying to create a new BufferCollection.
- ZX_DLOG(WARNING, status)
- << "The fuchsia.sysmem.Allocator channel was disconnected.";
- });
-}
-
-BufferAllocator::~BufferAllocator() = default;
-
-fuchsia::sysmem::BufferCollectionTokenPtr BufferAllocator::CreateNewToken() {
- fuchsia::sysmem::BufferCollectionTokenPtr collection_token;
- allocator_->AllocateSharedCollection(collection_token.NewRequest());
- return collection_token;
-}
-
-std::unique_ptr<SysmemBufferPool::Creator>
-BufferAllocator::MakeBufferPoolCreator(size_t num_of_tokens) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- // Create a new sysmem buffer collection token for the allocated buffers.
- fuchsia::sysmem::BufferCollectionTokenPtr collection_token = CreateNewToken();
-
- // Create collection token for sharing with other components.
- std::vector<fuchsia::sysmem::BufferCollectionTokenPtr> shared_tokens;
- for (size_t i = 0; i < num_of_tokens; i++) {
- fuchsia::sysmem::BufferCollectionTokenPtr token;
- collection_token->Duplicate(ZX_RIGHT_SAME_RIGHTS, token.NewRequest());
- shared_tokens.push_back(std::move(token));
- }
-
- fuchsia::sysmem::BufferCollectionPtr buffer_collection;
-
- // Convert the token to a BufferCollection connection.
- allocator_->BindSharedCollection(std::move(collection_token),
- buffer_collection.NewRequest());
-
- return std::make_unique<SysmemBufferPool::Creator>(
- std::move(buffer_collection), std::move(shared_tokens));
-}
-
-std::unique_ptr<SysmemBufferPool::Creator>
-BufferAllocator::MakeBufferPoolCreatorFromToken(
- fuchsia::sysmem::BufferCollectionTokenPtr token) {
- fuchsia::sysmem::BufferCollectionPtr buffer_collection;
- allocator_->BindSharedCollection(std::move(token),
- buffer_collection.NewRequest());
- return std::make_unique<SysmemBufferPool::Creator>(
- std::move(buffer_collection),
- std::vector<fuchsia::sysmem::BufferCollectionTokenPtr>{});
-}
-
-} // namespace media
diff --git a/chromium/media/fuchsia/common/sysmem_buffer_pool.h b/chromium/media/fuchsia/common/sysmem_buffer_pool.h
deleted file mode 100644
index 84407ccc59c..00000000000
--- a/chromium/media/fuchsia/common/sysmem_buffer_pool.h
+++ /dev/null
@@ -1,128 +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 MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_POOL_H_
-#define MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_POOL_H_
-
-#include <fuchsia/media/cpp/fidl.h>
-#include <fuchsia/sysmem/cpp/fidl.h>
-#include <lib/sys/cpp/component_context.h>
-
-#include <list>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/containers/span.h"
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-
-namespace media {
-
-class SysmemBufferReader;
-class SysmemBufferWriter;
-
-// Pool of buffers allocated by sysmem. It owns BufferCollection. It doesn't
-// provide any function read/write the buffers. Call should use
-// ReadableBufferPool/WritableBufferPool for read/write.
-class SysmemBufferPool {
- public:
- using CreateReaderCB =
- base::OnceCallback<void(std::unique_ptr<SysmemBufferReader>)>;
- using CreateWriterCB =
- base::OnceCallback<void(std::unique_ptr<SysmemBufferWriter>)>;
-
- // Creates SysmemBufferPool asynchronously. It also owns the channel to
- // fuchsia services.
- class Creator {
- public:
- using CreateCB =
- base::OnceCallback<void(std::unique_ptr<SysmemBufferPool>)>;
- Creator(
- fuchsia::sysmem::BufferCollectionPtr collection,
- std::vector<fuchsia::sysmem::BufferCollectionTokenPtr> shared_tokens);
- ~Creator();
-
- // Sets the name of the created buffers. Priority is a number used to choose
- // which name to use when multiple clients set names. Must be called before
- // Create. See fuchsia.sysmem/BufferCollection.SetName for a description of
- // the arguments.
- void SetName(uint32_t priority, base::StringPiece name);
- void Create(fuchsia::sysmem::BufferCollectionConstraints constraints,
- CreateCB build_cb);
-
- private:
- fuchsia::sysmem::BufferCollectionPtr collection_;
- std::vector<fuchsia::sysmem::BufferCollectionTokenPtr> shared_tokens_;
- CreateCB create_cb_;
-
- THREAD_CHECKER(thread_checker_);
-
- DISALLOW_COPY_AND_ASSIGN(Creator);
- };
-
- SysmemBufferPool(
- fuchsia::sysmem::BufferCollectionPtr collection,
- std::vector<fuchsia::sysmem::BufferCollectionTokenPtr> shared_tokens);
- ~SysmemBufferPool();
-
- fuchsia::sysmem::BufferCollectionTokenPtr TakeToken();
-
- // Create Reader/Writer to access raw memory. The returned Reader/Writer is
- // owned by SysmemBufferPool and lives as long as SysmemBufferPool.
- void CreateReader(CreateReaderCB create_cb);
- void CreateWriter(CreateWriterCB create_cb);
-
- // Returns if this object is still usable. Caller must check this before
- // calling SysmemBufferReader/Writer APIs.
- bool is_live() const { return collection_.is_bound(); }
-
- private:
- friend class BufferAllocator;
-
- void OnBuffersAllocated(
- zx_status_t status,
- fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info);
- void OnError();
-
- fuchsia::sysmem::BufferCollectionPtr collection_;
- std::vector<fuchsia::sysmem::BufferCollectionTokenPtr> shared_tokens_;
-
- CreateReaderCB create_reader_cb_;
- CreateWriterCB create_writer_cb_;
-
- // FIDL interfaces are thread-affine (see crbug.com/1012875).
- THREAD_CHECKER(thread_checker_);
-
- DISALLOW_COPY_AND_ASSIGN(SysmemBufferPool);
-};
-
-// Wrapper of sysmem Allocator.
-class BufferAllocator {
- public:
- explicit BufferAllocator(base::StringPiece client_name);
- ~BufferAllocator();
-
- fuchsia::sysmem::BufferCollectionTokenPtr CreateNewToken();
-
- std::unique_ptr<SysmemBufferPool::Creator> MakeBufferPoolCreator(
- size_t num_shared_token);
-
- std::unique_ptr<SysmemBufferPool::Creator> MakeBufferPoolCreatorFromToken(
- fuchsia::sysmem::BufferCollectionTokenPtr token);
-
- // TODO(crbug.com/1131183): Update FuchsiaVideoDecoder to use SysmemBufferPool
- // and remove this function.
- fuchsia::sysmem::Allocator* raw() { return allocator_.get(); }
-
- private:
- fuchsia::sysmem::AllocatorPtr allocator_;
-
- THREAD_CHECKER(thread_checker_);
-
- DISALLOW_COPY_AND_ASSIGN(BufferAllocator);
-};
-
-} // namespace media
-
-#endif // MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_POOL_H_
diff --git a/chromium/media/fuchsia/common/sysmem_buffer_reader.cc b/chromium/media/fuchsia/common/sysmem_buffer_reader.cc
deleted file mode 100644
index 3bc7cf268ac..00000000000
--- a/chromium/media/fuchsia/common/sysmem_buffer_reader.cc
+++ /dev/null
@@ -1,112 +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 "media/fuchsia/common/sysmem_buffer_reader.h"
-
-#include "base/fuchsia/fuchsia_logging.h"
-
-namespace media {
-
-SysmemBufferReader::SysmemBufferReader(
- fuchsia::sysmem::BufferCollectionInfo_2 info)
- : collection_info_(std::move(info)) {}
-
-SysmemBufferReader::~SysmemBufferReader() = default;
-
-bool SysmemBufferReader::Read(size_t index,
- size_t offset,
- base::span<uint8_t> data) {
- DCHECK_LT(index, num_buffers());
- DCHECK_LE(offset + data.size(),
- collection_info_.settings.buffer_settings.size_bytes);
-
- const fuchsia::sysmem::VmoBuffer& buffer = collection_info_.buffers[index];
- size_t vmo_offset = buffer.vmo_usable_start + offset;
-
- InvalidateCacheIfNecessary(buffer.vmo, vmo_offset, data.size());
-
- zx_status_t status = buffer.vmo.read(data.data(), vmo_offset, data.size());
-
- ZX_LOG_IF(ERROR, status != ZX_OK, status) << "Fail to read";
- return status == ZX_OK;
-}
-
-base::span<const uint8_t> SysmemBufferReader::GetMappingForBuffer(
- size_t index) {
- if (mappings_.empty())
- mappings_.resize(num_buffers());
-
- DCHECK_LT(index, mappings_.size());
-
- const fuchsia::sysmem::BufferMemorySettings& settings =
- collection_info_.settings.buffer_settings;
- fuchsia::sysmem::VmoBuffer& buffer = collection_info_.buffers[index];
-
- auto& mapping = mappings_[index];
- size_t buffer_start = buffer.vmo_usable_start;
-
- if (!mapping.IsValid()) {
- size_t mapping_size = buffer_start + settings.size_bytes;
- auto region = base::ReadOnlySharedMemoryRegion::Deserialize(
- base::subtle::PlatformSharedMemoryRegion::Take(
- std::move(buffer.vmo),
- base::subtle::PlatformSharedMemoryRegion::Mode::kReadOnly,
- mapping_size, base::UnguessableToken::Create()));
-
- mapping = region.Map();
-
- // Return the VMO handle back to buffer_.
- buffer.vmo = base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
- std::move(region))
- .PassPlatformHandle();
- }
-
- if (!mapping.IsValid()) {
- DLOG(WARNING) << "Failed to map VMO returned by sysmem";
- return {};
- }
-
- InvalidateCacheIfNecessary(buffer.vmo, buffer_start, settings.size_bytes);
-
- return base::make_span(
- reinterpret_cast<const uint8_t*>(mapping.memory()) + buffer_start,
- settings.size_bytes);
-}
-
-void SysmemBufferReader::InvalidateCacheIfNecessary(const zx::vmo& vmo,
- size_t offset,
- size_t size) {
- if (collection_info_.settings.buffer_settings.coherency_domain ==
- fuchsia::sysmem::CoherencyDomain::RAM) {
- zx_status_t status = vmo.op_range(ZX_VMO_OP_CACHE_CLEAN_INVALIDATE, offset,
- size, nullptr, 0);
- ZX_LOG_IF(ERROR, status != ZX_OK, status) << "Fail to invalidate cache";
- }
-}
-
-// static
-std::unique_ptr<SysmemBufferReader> SysmemBufferReader::Create(
- fuchsia::sysmem::BufferCollectionInfo_2 info) {
- return std::make_unique<SysmemBufferReader>(std::move(info));
-}
-
-// static
-fuchsia::sysmem::BufferCollectionConstraints
-SysmemBufferReader::GetRecommendedConstraints(
- size_t min_buffer_count,
- base::Optional<size_t> min_buffer_size) {
- fuchsia::sysmem::BufferCollectionConstraints buffer_constraints;
- buffer_constraints.usage.cpu = fuchsia::sysmem::cpuUsageRead;
- buffer_constraints.min_buffer_count = min_buffer_count;
- if (min_buffer_size) {
- buffer_constraints.has_buffer_memory_constraints = true;
- buffer_constraints.buffer_memory_constraints.min_size_bytes =
- min_buffer_size.value();
- buffer_constraints.buffer_memory_constraints.ram_domain_supported = true;
- buffer_constraints.buffer_memory_constraints.cpu_domain_supported = true;
- }
- return buffer_constraints;
-}
-
-} // namespace media
diff --git a/chromium/media/fuchsia/common/sysmem_buffer_reader.h b/chromium/media/fuchsia/common/sysmem_buffer_reader.h
deleted file mode 100644
index c4c4e0b10a4..00000000000
--- a/chromium/media/fuchsia/common/sysmem_buffer_reader.h
+++ /dev/null
@@ -1,71 +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 MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_READER_H_
-#define MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_READER_H_
-
-#include <fuchsia/media/cpp/fidl.h>
-#include <fuchsia/sysmem/cpp/fidl.h>
-
-#include <memory>
-
-#include "base/containers/span.h"
-#include "base/memory/read_only_shared_memory_region.h"
-#include "base/optional.h"
-
-namespace media {
-
-// Helper class to read content from fuchsia::sysmem::BufferCollection.
-class SysmemBufferReader {
- public:
- // Returns sysmem buffer constraints with the specified |min_buffer_count|.
- // Currently it doesn't request buffers for camping or any shared slack, so
- // the clients are expected to read incoming buffers (using Read() or
- // GetMappingForBuffer()) and then release them back to the source.
- static fuchsia::sysmem::BufferCollectionConstraints GetRecommendedConstraints(
- size_t min_buffer_count,
- base::Optional<size_t> min_buffer_size);
-
- static std::unique_ptr<SysmemBufferReader> Create(
- fuchsia::sysmem::BufferCollectionInfo_2 info);
-
- explicit SysmemBufferReader(fuchsia::sysmem::BufferCollectionInfo_2 info);
- ~SysmemBufferReader();
-
- size_t num_buffers() const { return collection_info_.buffer_count; }
-
- const fuchsia::sysmem::SingleBufferSettings& buffer_settings() {
- return collection_info_.settings;
- }
-
- // Read the buffer content at |index| into |data|, starting from |offset|.
- bool Read(size_t index, size_t offset, base::span<uint8_t> data);
-
- // Returns a span for the memory-mapping of the buffer with the specified
- // |index|, invalidating the CPU cache for the specified buffer in the sysmem
- // collection if necessary. Buffers are mapped lazily and remain mapped for
- // the lifetime of SysmemBufferReader. Should be called every time before
- // accessing the mapping to ensure that the CPU cache is invalidated for
- // buffers with RAM coherency.
- base::span<const uint8_t> GetMappingForBuffer(size_t index);
-
- private:
- // Invalidates CPU cache for the specified range of the specified vmo in
- // case the collection was allocated with RAM coherency. No-op for collections
- // with CPU coherency. Called from Read() and GetMapping() to ensure clients
- // get up-to-date buffer content in case the buffer was updated by other
- // participants directly in RAM (bypassing CPU cache).
- void InvalidateCacheIfNecessary(const zx::vmo& buffer,
- size_t offset,
- size_t size);
-
- fuchsia::sysmem::BufferCollectionInfo_2 collection_info_;
- std::vector<base::ReadOnlySharedMemoryMapping> mappings_;
-
- DISALLOW_COPY_AND_ASSIGN(SysmemBufferReader);
-};
-
-} // namespace media
-
-#endif // MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_READER_H_
diff --git a/chromium/media/fuchsia/common/sysmem_buffer_stream.h b/chromium/media/fuchsia/common/sysmem_buffer_stream.h
new file mode 100644
index 00000000000..f02ebe9d175
--- /dev/null
+++ b/chromium/media/fuchsia/common/sysmem_buffer_stream.h
@@ -0,0 +1,72 @@
+// Copyright 2021 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 MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_STREAM_H_
+#define MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_STREAM_H_
+
+#include <fuchsia/sysmem/cpp/fidl.h>
+
+#include "base/memory/scoped_refptr.h"
+#include "media/fuchsia/common/stream_processor_helper.h"
+
+namespace media {
+
+class DecoderBuffer;
+
+// Abstract interface for media stream processors. SysmemBufferStream takes a
+// stream of buffers in DecoderBuffer, processes them and then writes the output
+// to sysmem buffers.
+class MEDIA_EXPORT SysmemBufferStream {
+ public:
+ class Sink {
+ public:
+ // Called to set BufferCollectionToken for the output buffer collection.
+ virtual void OnSysmemBufferStreamBufferCollectionToken(
+ fuchsia::sysmem::BufferCollectionTokenPtr token) = 0;
+
+ // Called when a packet has been processed. The client should drop the
+ // |packet| only after it's finished using it.
+ virtual void OnSysmemBufferStreamOutputPacket(
+ StreamProcessorHelper::IoPacket packet) = 0;
+
+ // Called when the end of stream has been reached.
+ virtual void OnSysmemBufferStreamEndOfStream() = 0;
+
+ // Called on error.
+ virtual void OnSysmemBufferStreamError() = 0;
+
+ // Called to notify the sink that the SysmemBufferStream has stopped
+ // because it doesn't have a key. It will resume automatically once a new
+ // key is received.
+ virtual void OnSysmemBufferStreamNoKey() = 0;
+
+ protected:
+ virtual ~Sink() = default;
+ };
+
+ SysmemBufferStream() {}
+ virtual ~SysmemBufferStream() {}
+
+ // Allocates a buffer collection for the output and starts processing the
+ // stream, passing the output to the specified |sink|. |min_buffer_size| and
+ // |min_buffer_count| specify the minimum number of packets in the output
+ // buffer collection.
+ virtual void Initialize(Sink* sink,
+ size_t min_buffer_size,
+ size_t min_buffer_count) = 0;
+
+ // Enqueues the specified buffer to the input queue. Caller is allowed to
+ // queue as many buffers as it needs without waiting for results from the
+ // previous Process() calls. May be called before Initialize(). Queued buffers
+ // will be processed only after Initialize().
+ virtual void EnqueueBuffer(scoped_refptr<DecoderBuffer> buffer) = 0;
+
+ // Stops processing queued buffers and drops them. Keeps the |sink| passed to
+ // Start() and the output buffer collections.
+ virtual void Reset() = 0;
+};
+
+} // namespace media
+
+#endif // MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_STREAM_H_
diff --git a/chromium/media/fuchsia/common/sysmem_buffer_writer.cc b/chromium/media/fuchsia/common/sysmem_buffer_writer.cc
deleted file mode 100644
index d2a1a28e4f0..00000000000
--- a/chromium/media/fuchsia/common/sysmem_buffer_writer.cc
+++ /dev/null
@@ -1,202 +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 "media/fuchsia/common/sysmem_buffer_writer.h"
-
-#include <zircon/rights.h>
-#include <algorithm>
-
-#include "base/bits.h"
-#include "base/fuchsia/fuchsia_logging.h"
-#include "base/process/process_metrics.h"
-
-namespace media {
-
-class SysmemBufferWriter::Buffer {
- public:
- Buffer() = default;
-
- ~Buffer() {
- if (!base_address_) {
- return;
- }
-
- size_t mapped_bytes =
- base::bits::Align(offset_ + size_, base::GetPageSize());
- zx_status_t status = zx::vmar::root_self()->unmap(
- reinterpret_cast<uintptr_t>(base_address_), mapped_bytes);
- ZX_DCHECK(status == ZX_OK, status) << "zx_vmar_unmap";
- }
-
- Buffer(Buffer&&) = default;
- Buffer& operator=(Buffer&&) = default;
-
- bool Initialize(zx::vmo vmo,
- size_t offset,
- size_t size,
- fuchsia::sysmem::CoherencyDomain coherency_domain) {
- DCHECK(!base_address_);
- DCHECK(vmo);
-
- // zx_vmo_write() doesn't work for sysmem-allocated VMOs (see ZX-4854), so
- // the VMOs have to be mapped.
- size_t bytes_to_map = base::bits::Align(offset + size, base::GetPageSize());
- uintptr_t addr;
- zx_status_t status = zx::vmar::root_self()->map(
- ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, /*vmar_offset=*/0, vmo,
- /*vmo_offset=*/0, bytes_to_map, &addr);
- if (status != ZX_OK) {
- ZX_DLOG(ERROR, status) << "zx_vmar_map";
- return false;
- }
-
- base_address_ = reinterpret_cast<uint8_t*>(addr);
- offset_ = offset;
- size_ = size;
- coherency_domain_ = coherency_domain;
-
- return true;
- }
-
- bool is_used() const { return is_used_; }
- size_t size() const { return size_; }
-
- // Copies as much data as possible from |data| to this input buffer.
- size_t Write(base::span<const uint8_t> data) {
- DCHECK(!is_used_);
- is_used_ = true;
-
- size_t bytes_to_fill = std::min(size_, data.size());
- memcpy(base_address_ + offset_, data.data(), bytes_to_fill);
-
- FlushBuffer(0, bytes_to_fill);
-
- return bytes_to_fill;
- }
-
- base::span<uint8_t> ReserveAndMapBuffer() {
- DCHECK(!is_used_);
- is_used_ = true;
- return base::make_span(base_address_ + offset_, size_);
- }
-
- void FlushBuffer(size_t flush_offset, size_t flush_size) {
- DCHECK(is_used_);
- DCHECK_LE(flush_size, size_ - flush_offset);
-
- if (coherency_domain_ != fuchsia::sysmem::CoherencyDomain::RAM)
- return;
-
- uint8_t* address = base_address_ + offset_ + flush_offset;
- zx_status_t status =
- zx_cache_flush(address, flush_size, ZX_CACHE_FLUSH_DATA);
- ZX_DCHECK(status == ZX_OK, status) << "zx_cache_flush";
- }
-
- void Release() { is_used_ = false; }
-
- private:
- uint8_t* base_address_ = nullptr;
-
- // Buffer settings provided by sysmem.
- size_t offset_ = 0;
- size_t size_ = 0;
- fuchsia::sysmem::CoherencyDomain coherency_domain_;
-
- // Set to true when this buffer is being used by the codec.
- bool is_used_ = false;
-};
-
-SysmemBufferWriter::SysmemBufferWriter(std::vector<Buffer> buffers)
- : buffers_(std::move(buffers)) {}
-
-SysmemBufferWriter::~SysmemBufferWriter() = default;
-
-size_t SysmemBufferWriter::Write(size_t index, base::span<const uint8_t> data) {
- DCHECK_LT(index, buffers_.size());
- DCHECK(!buffers_[index].is_used());
-
- return buffers_[index].Write(data);
-}
-
-base::Optional<size_t> SysmemBufferWriter::Acquire() {
- auto it = std::find_if(
- buffers_.begin(), buffers_.end(),
- [](const SysmemBufferWriter::Buffer& buf) { return !buf.is_used(); });
-
- if (it == buffers_.end())
- return base::nullopt;
-
- return it - buffers_.begin();
-}
-
-void SysmemBufferWriter::Release(size_t index) {
- DCHECK_LT(index, buffers_.size());
- buffers_[index].Release();
-}
-
-void SysmemBufferWriter::ReleaseAll() {
- for (auto& buf : buffers_) {
- buf.Release();
- }
-}
-
-size_t SysmemBufferWriter::num_buffers() const {
- return buffers_.size();
-}
-
-// static
-std::unique_ptr<SysmemBufferWriter> SysmemBufferWriter::Create(
- fuchsia::sysmem::BufferCollectionInfo_2 info) {
- std::vector<SysmemBufferWriter::Buffer> buffers;
- buffers.resize(info.buffer_count);
-
- fuchsia::sysmem::BufferMemorySettings& settings =
- info.settings.buffer_settings;
- for (size_t i = 0; i < info.buffer_count; ++i) {
- fuchsia::sysmem::VmoBuffer& buffer = info.buffers[i];
- if (!buffers[i].Initialize(std::move(buffer.vmo), buffer.vmo_usable_start,
- settings.size_bytes,
- settings.coherency_domain)) {
- return nullptr;
- }
- }
-
- return std::make_unique<SysmemBufferWriter>(std::move(buffers));
-}
-
-// static
-base::Optional<fuchsia::sysmem::BufferCollectionConstraints>
-SysmemBufferWriter::GetRecommendedConstraints(size_t min_buffer_count,
- size_t min_buffer_size) {
- fuchsia::sysmem::BufferCollectionConstraints buffer_constraints;
-
- // Currently we have to map buffers VMOs to write to them (see ZX-4854) and
- // memory cannot be mapped as write-only (see ZX-4872), so request RW access
- // even though we will never need to read from these buffers.
- buffer_constraints.usage.cpu =
- fuchsia::sysmem::cpuUsageRead | fuchsia::sysmem::cpuUsageWrite;
-
- buffer_constraints.min_buffer_count = min_buffer_count;
- buffer_constraints.has_buffer_memory_constraints = true;
- buffer_constraints.buffer_memory_constraints.min_size_bytes = min_buffer_size;
- buffer_constraints.buffer_memory_constraints.ram_domain_supported = true;
- buffer_constraints.buffer_memory_constraints.cpu_domain_supported = true;
-
- return buffer_constraints;
-}
-
-base::span<uint8_t> SysmemBufferWriter::ReserveAndMapBuffer(size_t index) {
- DCHECK_LT(index, buffers_.size());
- return buffers_[index].ReserveAndMapBuffer();
-}
-
-void SysmemBufferWriter::FlushBuffer(size_t index,
- size_t flush_offset,
- size_t flush_size) {
- DCHECK_LT(index, buffers_.size());
- return buffers_[index].FlushBuffer(flush_offset, flush_size);
-}
-
-} // namespace media
diff --git a/chromium/media/fuchsia/common/sysmem_buffer_writer.h b/chromium/media/fuchsia/common/sysmem_buffer_writer.h
deleted file mode 100644
index 376468d1b75..00000000000
--- a/chromium/media/fuchsia/common/sysmem_buffer_writer.h
+++ /dev/null
@@ -1,70 +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 MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_WRITER_H_
-#define MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_WRITER_H_
-
-#include <fuchsia/media/cpp/fidl.h>
-#include <fuchsia/sysmem/cpp/fidl.h>
-
-#include <memory>
-
-#include "base/containers/span.h"
-#include "base/memory/shared_memory_mapping.h"
-#include "base/optional.h"
-
-namespace media {
-
-// Helper class to write content into fuchsia::sysmem::BufferCollection.
-class SysmemBufferWriter {
- public:
- class Buffer;
-
- static base::Optional<fuchsia::sysmem::BufferCollectionConstraints>
- GetRecommendedConstraints(size_t min_buffer_count, size_t min_buffer_size);
-
- static std::unique_ptr<SysmemBufferWriter> Create(
- fuchsia::sysmem::BufferCollectionInfo_2 info);
-
- explicit SysmemBufferWriter(std::vector<Buffer> buffers);
- ~SysmemBufferWriter();
-
- SysmemBufferWriter(const SysmemBufferWriter&) = delete;
- SysmemBufferWriter& operator=(const SysmemBufferWriter&) = delete;
-
- // Write the content of |data| into the buffer at |index|. Return num of bytes
- // written into the buffer. Can be called only for an unused buffer. Marks
- // the buffer as used.
- size_t Write(size_t index, base::span<const uint8_t> data);
-
- // Returns a span for the memory-mapping of the buffer with the specified
- // |index|. Can be called only for an unused buffer. Marks the buffer as used.
- // Callers must call FlushCache() after they are finished updating the buffer.
- base::span<uint8_t> ReserveAndMapBuffer(size_t index);
-
- // Flushes CPU cache for specified range in the buffer with the specified
- // |index| in case the buffer collection uses RAM coherency. No-op for
- // collections with RAM coherency.
- void FlushBuffer(size_t index, size_t flush_offset, size_t flush_size);
-
- // Acquire unused buffer for write. If |min_size| is provided, the returned
- // buffer will have available size larger than |min_size|. This will NOT
- // mark the buffer as "used".
- base::Optional<size_t> Acquire();
-
- // Notify the pool buffer at |index| is free to write new data.
- void Release(size_t index);
-
- // Mark all buffers as unused.
- void ReleaseAll();
-
- size_t num_buffers() const;
-
- private:
- std::vector<Buffer> buffers_;
-};
-
-} // namespace media
-
-#endif // MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_WRITER_H_
diff --git a/chromium/media/fuchsia/common/sysmem_client.cc b/chromium/media/fuchsia/common/sysmem_client.cc
new file mode 100644
index 00000000000..4c5d86dbeb1
--- /dev/null
+++ b/chromium/media/fuchsia/common/sysmem_client.cc
@@ -0,0 +1,172 @@
+// Copyright 2021 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 "media/fuchsia/common/sysmem_client.h"
+
+#include <lib/sys/cpp/component_context.h>
+#include <zircon/rights.h>
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/fuchsia/fuchsia_logging.h"
+#include "base/fuchsia/process_context.h"
+#include "base/process/process_handle.h"
+#include "media/fuchsia/common/vmo_buffer.h"
+
+namespace media {
+
+SysmemCollectionClient::SysmemCollectionClient(
+ fuchsia::sysmem::Allocator* allocator,
+ fuchsia::sysmem::BufferCollectionTokenPtr collection_token)
+ : allocator_(allocator), collection_token_(std::move(collection_token)) {
+ DCHECK(allocator_);
+ DCHECK(collection_token_);
+}
+
+SysmemCollectionClient::~SysmemCollectionClient() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (collection_)
+ collection_->Close();
+}
+
+void SysmemCollectionClient::Initialize(
+ fuchsia::sysmem::BufferCollectionConstraints constraints,
+ base::StringPiece name,
+ uint32_t name_priority) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ writable_ = (constraints.usage.cpu & fuchsia::sysmem::cpuUsageWrite) ==
+ fuchsia::sysmem::cpuUsageWrite;
+
+ allocator_->BindSharedCollection(std::move(collection_token_),
+ collection_.NewRequest());
+
+ collection_.set_error_handler(
+ fit::bind_member(this, &SysmemCollectionClient::OnError));
+ collection_->SetName(name_priority, std::string(name));
+
+ // If Sync() is not required then constraints can be set immediately.
+ if (sync_completion_closures_.empty()) {
+ collection_->SetConstraints(/*have_constraints=*/true,
+ std::move(constraints));
+ return;
+ }
+
+ sync_completion_closures_.push_back(
+ base::BindOnce(&fuchsia::sysmem::BufferCollection::SetConstraints,
+ base::Unretained(collection_.get()),
+ /*have_constraints=*/true, std::move(constraints)));
+ collection_->Sync(
+ fit::bind_member(this, &SysmemCollectionClient::OnSyncComplete));
+}
+
+void SysmemCollectionClient::CreateSharedToken(
+ GetSharedTokenCB cb,
+ base::StringPiece debug_client_name,
+ uint64_t debug_client_id) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(collection_token_);
+
+ fuchsia::sysmem::BufferCollectionTokenPtr token;
+ collection_token_->Duplicate(ZX_RIGHT_SAME_RIGHTS, token.NewRequest());
+
+ if (!debug_client_name.empty()) {
+ token->SetDebugClientInfo(std::string(debug_client_name), debug_client_id);
+ }
+
+ sync_completion_closures_.push_back(
+ base::BindOnce(std::move(cb), std::move(token)));
+}
+
+void SysmemCollectionClient::AcquireBuffers(AcquireBuffersCB cb) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!collection_token_);
+
+ if (!collection_) {
+ std::move(cb).Run({}, {});
+ return;
+ }
+
+ acquire_buffers_cb_ = std::move(cb);
+ collection_->WaitForBuffersAllocated(
+ fit::bind_member(this, &SysmemCollectionClient::OnBuffersAllocated));
+}
+
+void SysmemCollectionClient::OnSyncComplete() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ std::vector<base::OnceClosure> sync_closures =
+ std::move(sync_completion_closures_);
+ for (auto& cb : sync_closures) {
+ std::move(cb).Run();
+ }
+}
+
+void SysmemCollectionClient::OnBuffersAllocated(
+ zx_status_t status,
+ fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (status != ZX_OK) {
+ ZX_LOG(ERROR, status) << "Failed to allocate sysmem buffers.";
+ OnError(status);
+ return;
+ }
+
+ if (acquire_buffers_cb_) {
+ auto buffers = VmoBuffer::CreateBuffersFromSysmemCollection(
+ &buffer_collection_info, writable_);
+ std::move(acquire_buffers_cb_)
+ .Run(std::move(buffers), buffer_collection_info.settings);
+ }
+}
+
+void SysmemCollectionClient::OnError(zx_status_t status) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ ZX_DLOG(ERROR, status) << "Connection to BufferCollection was disconnected.";
+ collection_.Unbind();
+ if (acquire_buffers_cb_)
+ std::move(acquire_buffers_cb_).Run({}, {});
+}
+
+SysmemAllocatorClient::SysmemAllocatorClient(base::StringPiece client_name) {
+ allocator_ = base::ComponentContextForProcess()
+ ->svc()
+ ->Connect<fuchsia::sysmem::Allocator>();
+
+ allocator_->SetDebugClientInfo(std::string(client_name),
+ base::GetCurrentProcId());
+
+ allocator_.set_error_handler([](zx_status_t status) {
+ // Just log a warning. We will handle BufferCollection the failure when
+ // trying to create a new BufferCollection.
+ ZX_DLOG(WARNING, status)
+ << "The fuchsia.sysmem.Allocator channel was disconnected.";
+ });
+}
+
+SysmemAllocatorClient::~SysmemAllocatorClient() = default;
+
+fuchsia::sysmem::BufferCollectionTokenPtr
+SysmemAllocatorClient::CreateNewToken() {
+ fuchsia::sysmem::BufferCollectionTokenPtr collection_token;
+ allocator_->AllocateSharedCollection(collection_token.NewRequest());
+ return collection_token;
+}
+
+std::unique_ptr<SysmemCollectionClient>
+SysmemAllocatorClient::AllocateNewCollection() {
+ return std::make_unique<SysmemCollectionClient>(allocator_.get(),
+ CreateNewToken());
+}
+
+std::unique_ptr<SysmemCollectionClient>
+SysmemAllocatorClient::BindSharedCollection(
+ fuchsia::sysmem::BufferCollectionTokenPtr token) {
+ return std::make_unique<SysmemCollectionClient>(allocator_.get(),
+ std::move(token));
+}
+
+} // namespace media
diff --git a/chromium/media/fuchsia/common/sysmem_client.h b/chromium/media/fuchsia/common/sysmem_client.h
new file mode 100644
index 00000000000..1b0b1b16e1d
--- /dev/null
+++ b/chromium/media/fuchsia/common/sysmem_client.h
@@ -0,0 +1,114 @@
+// Copyright 2021 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 MEDIA_FUCHSIA_COMMON_SYSMEM_CLIENT_H_
+#define MEDIA_FUCHSIA_COMMON_SYSMEM_CLIENT_H_
+
+#include <fuchsia/media/cpp/fidl.h>
+#include <fuchsia/sysmem/cpp/fidl.h>
+
+#include <vector>
+
+#include "base/callback.h"
+#include "base/threading/thread_checker.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+class VmoBuffer;
+
+// Wrapper for fuchsia.sysmem.BufferCollection . It provides the following two
+// features:
+// 1. Calls Sync() and ensures that it completes before buffer constrains are
+// set and shared tokens are passed to other participants.
+// 2. Provides AcquireBuffers() that allows to acquire buffers and handle
+// possible errors.
+class MEDIA_EXPORT SysmemCollectionClient {
+ public:
+ static constexpr uint32_t kDefaultNamePriority = 100;
+
+ // Callback for GetSharedToken().
+ using GetSharedTokenCB =
+ base::OnceCallback<void(fuchsia::sysmem::BufferCollectionTokenPtr token)>;
+
+ // Callback for AcquireBuffers(). Called with an empty |buffers| if buffers
+ // allocation failed.
+ using AcquireBuffersCB = base::OnceCallback<void(
+ std::vector<VmoBuffer> buffers,
+ const fuchsia::sysmem::SingleBufferSettings& settings)>;
+
+ SysmemCollectionClient(
+ fuchsia::sysmem::Allocator* allocator,
+ fuchsia::sysmem::BufferCollectionTokenPtr collection_token);
+ ~SysmemCollectionClient();
+
+ SysmemCollectionClient(const SysmemCollectionClient&) = delete;
+ SysmemCollectionClient& operator=(const SysmemCollectionClient&) = delete;
+
+ // Creates one shared token to be shared with other participants and returns
+ // it asynchronously, when it's safe to pass it (i.e. after Sync()). Must be
+ // called before Initialize().
+ void CreateSharedToken(
+ GetSharedTokenCB cb,
+ base::StringPiece debug_client_name = base::StringPiece(),
+ uint64_t debug_client_id = 0);
+
+ // Initializes the collection with the given name and constraints.
+ void Initialize(fuchsia::sysmem::BufferCollectionConstraints constraints,
+ base::StringPiece name,
+ uint32_t name_priority = kDefaultNamePriority);
+
+ // Create VmoBuffers to access raw memory. Should be called only after
+ // GetSharedToken() has been called for all shared tokens.
+ void AcquireBuffers(AcquireBuffersCB cb);
+
+ private:
+ void OnSyncComplete();
+ void OnBuffersAllocated(
+ zx_status_t status,
+ fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info);
+ void OnError(zx_status_t status);
+
+ fuchsia::sysmem::Allocator* const allocator_;
+ fuchsia::sysmem::BufferCollectionTokenPtr collection_token_;
+ fuchsia::sysmem::BufferCollectionPtr collection_;
+
+ bool writable_ = false;
+ std::vector<base::OnceClosure> sync_completion_closures_;
+ AcquireBuffersCB acquire_buffers_cb_;
+
+ THREAD_CHECKER(thread_checker_);
+};
+
+// Helper fuchsia.sysmem.Allocator .
+class MEDIA_EXPORT SysmemAllocatorClient {
+ public:
+ explicit SysmemAllocatorClient(base::StringPiece client_name);
+ ~SysmemAllocatorClient();
+
+ SysmemAllocatorClient(const SysmemAllocatorClient&) = delete;
+ SysmemAllocatorClient& operator=(const SysmemAllocatorClient&) = delete;
+
+ fuchsia::sysmem::BufferCollectionTokenPtr CreateNewToken();
+
+ // Creates new buffer collection.
+ std::unique_ptr<SysmemCollectionClient> AllocateNewCollection();
+
+ // Binds the specified token to a SysmemCollectionClient.
+ std::unique_ptr<SysmemCollectionClient> BindSharedCollection(
+ fuchsia::sysmem::BufferCollectionTokenPtr token);
+
+ // TODO(crbug.com/1131183): Update FuchsiaVideoDecoder to use
+ // SysmemCollectionClient and remove this function.
+ fuchsia::sysmem::Allocator* raw() { return allocator_.get(); }
+
+ private:
+ friend SysmemCollectionClient;
+
+ fuchsia::sysmem::AllocatorPtr allocator_;
+};
+
+} // namespace media
+
+#endif // MEDIA_FUCHSIA_COMMON_SYSMEM_CLIENT_H_
diff --git a/chromium/media/fuchsia/common/vmo_buffer.cc b/chromium/media/fuchsia/common/vmo_buffer.cc
new file mode 100644
index 00000000000..6fb77333223
--- /dev/null
+++ b/chromium/media/fuchsia/common/vmo_buffer.cc
@@ -0,0 +1,171 @@
+// Copyright 2021 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 "media/fuchsia/common/vmo_buffer.h"
+
+#include <zircon/rights.h>
+#include <algorithm>
+
+#include "base/bits.h"
+#include "base/fuchsia/fuchsia_logging.h"
+#include "base/memory/page_size.h"
+
+namespace media {
+
+// static
+fuchsia::sysmem::BufferCollectionConstraints
+VmoBuffer::GetRecommendedConstraints(size_t min_buffer_count,
+ absl::optional<size_t> min_buffer_size,
+ bool writable) {
+ fuchsia::sysmem::BufferCollectionConstraints buffer_constraints;
+
+ buffer_constraints.usage.cpu = fuchsia::sysmem::cpuUsageRead;
+ if (writable)
+ buffer_constraints.usage.cpu |= fuchsia::sysmem::cpuUsageWrite;
+
+ buffer_constraints.min_buffer_count = min_buffer_count;
+
+ if (min_buffer_size) {
+ buffer_constraints.has_buffer_memory_constraints = true;
+ buffer_constraints.buffer_memory_constraints.min_size_bytes =
+ min_buffer_size.value();
+ buffer_constraints.buffer_memory_constraints.ram_domain_supported = true;
+ buffer_constraints.buffer_memory_constraints.cpu_domain_supported = true;
+ }
+
+ return buffer_constraints;
+}
+
+// static
+std::vector<VmoBuffer> VmoBuffer::CreateBuffersFromSysmemCollection(
+ fuchsia::sysmem::BufferCollectionInfo_2* info,
+ bool writable) {
+ std::vector<VmoBuffer> buffers;
+ buffers.resize(info->buffer_count);
+
+ fuchsia::sysmem::BufferMemorySettings& settings =
+ info->settings.buffer_settings;
+ for (size_t i = 0; i < info->buffer_count; ++i) {
+ fuchsia::sysmem::VmoBuffer& buffer = info->buffers[i];
+ if (!buffers[i].Initialize(std::move(buffer.vmo), writable,
+ buffer.vmo_usable_start, settings.size_bytes,
+ settings.coherency_domain)) {
+ return {};
+ }
+ }
+
+ return buffers;
+}
+
+VmoBuffer::VmoBuffer() = default;
+
+VmoBuffer::~VmoBuffer() {
+ if (!base_address_) {
+ return;
+ }
+
+ zx_status_t status = zx::vmar::root_self()->unmap(
+ reinterpret_cast<uintptr_t>(base_address_), mapped_size());
+ ZX_DCHECK(status == ZX_OK, status) << "zx_vmar_unmap";
+}
+
+VmoBuffer::VmoBuffer(VmoBuffer&&) = default;
+VmoBuffer& VmoBuffer::operator=(VmoBuffer&&) = default;
+
+bool VmoBuffer::Initialize(zx::vmo vmo,
+ bool writable,
+ size_t offset,
+ size_t size,
+ fuchsia::sysmem::CoherencyDomain coherency_domain) {
+ DCHECK(!base_address_);
+ DCHECK(vmo);
+
+ writable_ = writable;
+ offset_ = offset;
+ size_ = size;
+ coherency_domain_ = coherency_domain;
+
+ zx_vm_option_t options = ZX_VM_PERM_READ;
+ if (writable)
+ options |= ZX_VM_PERM_WRITE;
+
+ uintptr_t addr;
+ zx_status_t status =
+ zx::vmar::root_self()->map(options, /*vmar_offset=*/0, vmo,
+ /*vmo_offset=*/0, mapped_size(), &addr);
+ if (status != ZX_OK) {
+ ZX_DLOG(ERROR, status) << "zx_vmar_map";
+ return false;
+ }
+
+ vmo_ = std::move(vmo);
+ base_address_ = reinterpret_cast<uint8_t*>(addr);
+
+ return true;
+}
+
+size_t VmoBuffer::Read(size_t offset, base::span<uint8_t> data) {
+ if (offset >= size_)
+ return 0U;
+ size_t bytes_to_fill = std::min(size_ - offset, data.size());
+ FlushCache(offset, bytes_to_fill, /*invalidate=*/true);
+ memcpy(data.data(), base_address_ + offset_ + offset, bytes_to_fill);
+ return bytes_to_fill;
+}
+
+size_t VmoBuffer::Write(base::span<const uint8_t> data) {
+ DCHECK(writable_);
+
+ size_t bytes_to_fill = std::min(size_, data.size());
+ memcpy(base_address_ + offset_, data.data(), bytes_to_fill);
+
+ FlushCache(0, bytes_to_fill, /*invalidate=*/false);
+
+ return bytes_to_fill;
+}
+
+base::span<const uint8_t> VmoBuffer::GetMemory() {
+ FlushCache(0, size_, /*invalidate=*/true);
+ return base::make_span(base_address_ + offset_, size_);
+}
+
+base::span<uint8_t> VmoBuffer::GetWritableMemory() {
+ DCHECK(writable_);
+ return base::make_span(base_address_ + offset_, size_);
+}
+
+void VmoBuffer::FlushCache(size_t flush_offset,
+ size_t flush_size,
+ bool invalidate) {
+ DCHECK_LE(flush_size, size_ - flush_offset);
+
+ if (coherency_domain_ != fuchsia::sysmem::CoherencyDomain::RAM)
+ return;
+
+ uint8_t* address = base_address_ + offset_ + flush_offset;
+ uint32_t options = ZX_CACHE_FLUSH_DATA;
+ if (invalidate)
+ options |= ZX_CACHE_FLUSH_INVALIDATE;
+ zx_status_t status = zx_cache_flush(address, flush_size, options);
+ ZX_DCHECK(status == ZX_OK, status) << "zx_cache_flush";
+}
+
+size_t VmoBuffer::mapped_size() {
+ return base::bits::Align(offset_ + size_, base::GetPageSize());
+}
+
+zx::vmo VmoBuffer::Duplicate(bool writable) {
+ zx_rights_t rights = ZX_RIGHT_DUPLICATE | ZX_RIGHT_TRANSFER | ZX_RIGHT_READ |
+ ZX_RIGHT_MAP | ZX_RIGHT_GET_PROPERTY;
+ if (writable)
+ rights |= ZX_RIGHT_WRITE;
+
+ zx::vmo vmo;
+ zx_status_t status = vmo_.duplicate(rights, &vmo);
+ ZX_CHECK(status == ZX_OK, status) << "zx_handle_duplicate";
+
+ return vmo;
+}
+
+} // namespace media
diff --git a/chromium/media/fuchsia/common/vmo_buffer.h b/chromium/media/fuchsia/common/vmo_buffer.h
new file mode 100644
index 00000000000..8a6ab02de51
--- /dev/null
+++ b/chromium/media/fuchsia/common/vmo_buffer.h
@@ -0,0 +1,99 @@
+// Copyright 2021 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 MEDIA_FUCHSIA_COMMON_VMO_BUFFER_H_
+#define MEDIA_FUCHSIA_COMMON_VMO_BUFFER_H_
+
+#include <fuchsia/media/cpp/fidl.h>
+#include <fuchsia/sysmem/cpp/fidl.h>
+
+#include <memory>
+
+#include "base/compiler_specific.h"
+#include "base/containers/span.h"
+#include "base/memory/shared_memory_mapping.h"
+#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace media {
+
+class MEDIA_EXPORT VmoBuffer {
+ public:
+ // Returns sysmem buffer constraints to use to ensure that sysmem buffer
+ // collection is compatible with this class.
+ static fuchsia::sysmem::BufferCollectionConstraints GetRecommendedConstraints(
+ size_t min_buffer_count,
+ absl::optional<size_t> min_buffer_size,
+ bool writable);
+
+ // Creates a set of buffers from a sysmem collection. An empty vector is
+ // returned in case of a failure.
+ static std::vector<VmoBuffer> CreateBuffersFromSysmemCollection(
+ fuchsia::sysmem::BufferCollectionInfo_2* info,
+ bool writable);
+
+ VmoBuffer();
+ ~VmoBuffer();
+
+ VmoBuffer(VmoBuffer&&);
+ VmoBuffer& operator=(VmoBuffer&&);
+
+ // Initializes the buffer from the specified |vmo|. |writable| should be true
+ // for writable buffers. |offset| and |size| are used to specify the portion
+ // of the |vmo| that should be used for this buffer. Returns false if it fails
+ // to map the buffer.
+ bool Initialize(zx::vmo vmo,
+ bool writable,
+ size_t offset,
+ size_t size,
+ fuchsia::sysmem::CoherencyDomain coherency_domain)
+ WARN_UNUSED_RESULT;
+
+ size_t size() const { return size_; }
+
+ // Read the buffer content into |data|, starting from |offset|. For buffers
+ // with RAM coherency the cache is invalidated prior to read to ensure the
+ // data is read from RAM instead of the CPU cache. Returns number of bytes
+ // that have been copied.
+ size_t Read(size_t offset, base::span<uint8_t> data);
+
+ // Writes |data| to this input buffer. If the |data| is larger than the buffer
+ // then writes only size() bytes from the head of the |data|. Returns number
+ // of bytes that have been copied.
+ size_t Write(base::span<const uint8_t> data);
+
+ // Returns read-only memory corresponding to the buffer. Also invalidates CPU
+ // cache for buffers with RAM coherency.
+ base::span<const uint8_t> GetMemory();
+
+ // Returns writable memory span. The caller should call Flush() after writing
+ // to the buffer in order to ensure that the buffer is flushed in case it uses
+ // RAM coherency.
+ base::span<uint8_t> GetWritableMemory();
+
+ // Flushes the CPU cache if the buffers uses RAM coherency. No-op for buffers
+ // with CPU coherency. If |invalidate| flag is set then the cache is also
+ // invalidated.
+ void FlushCache(size_t flush_offset, size_t flush_size, bool invalidate);
+
+ // Duplicates VMO.
+ zx::vmo Duplicate(bool writable);
+
+ private:
+ // Returns size of the mapped region.
+ size_t mapped_size();
+
+ zx::vmo vmo_;
+
+ uint8_t* base_address_ = nullptr;
+
+ bool writable_ = false;
+ size_t offset_ = 0;
+ size_t size_ = 0;
+ fuchsia::sysmem::CoherencyDomain coherency_domain_;
+};
+
+} // namespace media
+
+#endif // MEDIA_FUCHSIA_COMMON_VMO_BUFFER_H_
diff --git a/chromium/media/fuchsia/common/sysmem_buffer_writer_queue.cc b/chromium/media/fuchsia/common/vmo_buffer_writer_queue.cc
index defb54d059d..2367a8d3f91 100644
--- a/chromium/media/fuchsia/common/sysmem_buffer_writer_queue.cc
+++ b/chromium/media/fuchsia/common/vmo_buffer_writer_queue.cc
@@ -1,8 +1,8 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2021 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 "media/fuchsia/common/sysmem_buffer_writer_queue.h"
+#include "media/fuchsia/common/vmo_buffer_writer_queue.h"
#include <zircon/rights.h>
#include <algorithm>
@@ -14,7 +14,7 @@
namespace media {
-struct SysmemBufferWriterQueue::PendingBuffer {
+struct VmoBufferWriterQueue::PendingBuffer {
PendingBuffer(scoped_refptr<DecoderBuffer> buffer) : buffer(buffer) {
DCHECK(buffer);
}
@@ -39,37 +39,50 @@ struct SysmemBufferWriterQueue::PendingBuffer {
// Index of the last buffer in the sysmem buffer collection that was used to
// send this input buffer. Should be set only when |bytes_left()==0|.
- base::Optional<size_t> tail_sysmem_buffer_index;
+ absl::optional<size_t> tail_sysmem_buffer_index;
};
-SysmemBufferWriterQueue::SysmemBufferWriterQueue() = default;
-SysmemBufferWriterQueue::~SysmemBufferWriterQueue() = default;
+VmoBufferWriterQueue::VmoBufferWriterQueue() {
+ DETACH_FROM_THREAD(thread_checker_);
+}
+
+VmoBufferWriterQueue::~VmoBufferWriterQueue() = default;
-void SysmemBufferWriterQueue::EnqueueBuffer(
- scoped_refptr<DecoderBuffer> buffer) {
+void VmoBufferWriterQueue::EnqueueBuffer(scoped_refptr<DecoderBuffer> buffer) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
pending_buffers_.push_back(PendingBuffer(buffer));
PumpPackets();
}
-void SysmemBufferWriterQueue::Start(std::unique_ptr<SysmemBufferWriter> writer,
- SendPacketCB send_packet_cb,
- EndOfStreamCB end_of_stream_cb) {
+void VmoBufferWriterQueue::Start(std::vector<VmoBuffer> buffers,
+ SendPacketCB send_packet_cb,
+ EndOfStreamCB end_of_stream_cb) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!writer_);
+ DCHECK(buffers_.empty());
+ DCHECK(!buffers.empty());
- writer_ = std::move(writer);
+ buffers_ = std::move(buffers);
send_packet_cb_ = std::move(send_packet_cb);
end_of_stream_cb_ = std::move(end_of_stream_cb);
+ // Initialize |unused_buffers_|.
+ unused_buffers_.reserve(buffers_.size());
+ for (size_t i = 0; i < buffers_.size(); ++i) {
+ unused_buffers_.push_back(i);
+ }
+
PumpPackets();
}
-void SysmemBufferWriterQueue::PumpPackets() {
+bool VmoBufferWriterQueue::IsBlocked() const {
+ return unused_buffers_.empty();
+}
+
+void VmoBufferWriterQueue::PumpPackets() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto weak_this = weak_factory_.GetWeakPtr();
- while (writer_ && !is_paused_ &&
+ while (!buffers_.empty() && !is_paused_ &&
input_queue_position_ < pending_buffers_.size()) {
PendingBuffer* current_buffer = &pending_buffers_[input_queue_position_];
@@ -81,30 +94,28 @@ void SysmemBufferWriterQueue::PumpPackets() {
continue;
}
- base::Optional<size_t> index_opt = writer_->Acquire();
-
- if (!index_opt.has_value()) {
+ if (unused_buffers_.empty()) {
// No input buffer available.
return;
}
- size_t sysmem_buffer_index = index_opt.value();
+ size_t buffer_index = unused_buffers_.back();
+ unused_buffers_.pop_back();
- size_t bytes_filled = writer_->Write(
- sysmem_buffer_index,
+ size_t bytes_filled = buffers_[buffer_index].Write(
base::make_span(current_buffer->data(), current_buffer->bytes_left()));
current_buffer->AdvanceCurrentPos(bytes_filled);
bool buffer_end = current_buffer->bytes_left() == 0;
- auto packet = StreamProcessorHelper::IoPacket::CreateInput(
- sysmem_buffer_index, bytes_filled, current_buffer->buffer->timestamp(),
- buffer_end,
- base::BindOnce(&SysmemBufferWriterQueue::ReleaseBuffer,
- weak_factory_.GetWeakPtr(), sysmem_buffer_index));
+ auto packet = StreamProcessorHelper::IoPacket(
+ buffer_index, /*offset=*/0, bytes_filled,
+ current_buffer->buffer->timestamp(), buffer_end,
+ base::BindOnce(&VmoBufferWriterQueue::ReleaseBuffer,
+ weak_factory_.GetWeakPtr(), buffer_index));
if (buffer_end) {
- current_buffer->tail_sysmem_buffer_index = sysmem_buffer_index;
+ current_buffer->tail_sysmem_buffer_index = buffer_index;
input_queue_position_ += 1;
}
@@ -114,16 +125,16 @@ void SysmemBufferWriterQueue::PumpPackets() {
}
}
-void SysmemBufferWriterQueue::ResetQueue() {
+void VmoBufferWriterQueue::ResetQueue() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
pending_buffers_.clear();
input_queue_position_ = 0;
is_paused_ = false;
}
-void SysmemBufferWriterQueue::ResetBuffers() {
+void VmoBufferWriterQueue::ResetBuffers() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- writer_.reset();
+ buffers_.clear();
send_packet_cb_ = SendPacketCB();
end_of_stream_cb_ = EndOfStreamCB();
@@ -132,7 +143,7 @@ void SysmemBufferWriterQueue::ResetBuffers() {
weak_factory_.InvalidateWeakPtrs();
}
-void SysmemBufferWriterQueue::ResetPositionAndPause() {
+void VmoBufferWriterQueue::ResetPositionAndPause() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
for (auto& buffer : pending_buffers_) {
buffer.buffer_pos = 0;
@@ -141,22 +152,22 @@ void SysmemBufferWriterQueue::ResetPositionAndPause() {
// All packets that were pending will need to be resent. Reset
// |tail_sysmem_buffer_index| to ensure that these packets are not removed
// from the queue in ReleaseBuffer().
- buffer.tail_sysmem_buffer_index = base::nullopt;
+ buffer.tail_sysmem_buffer_index = absl::nullopt;
}
input_queue_position_ = 0;
is_paused_ = true;
}
-void SysmemBufferWriterQueue::Unpause() {
+void VmoBufferWriterQueue::Unpause() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(is_paused_);
is_paused_ = false;
PumpPackets();
}
-void SysmemBufferWriterQueue::ReleaseBuffer(size_t buffer_index) {
+void VmoBufferWriterQueue::ReleaseBuffer(size_t buffer_index) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(writer_);
+ DCHECK(!buffers_.empty());
// Mark the input buffer as complete.
for (size_t i = 0; i < input_queue_position_; ++i) {
@@ -176,13 +187,13 @@ void SysmemBufferWriterQueue::ReleaseBuffer(size_t buffer_index) {
input_queue_position_--;
}
- writer_->Release(buffer_index);
+ unused_buffers_.push_back(buffer_index);
PumpPackets();
}
-size_t SysmemBufferWriterQueue::num_buffers() const {
+size_t VmoBufferWriterQueue::num_buffers() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return writer_ ? writer_->num_buffers() : 0;
+ return buffers_.size();
}
} // namespace media
diff --git a/chromium/media/fuchsia/common/sysmem_buffer_writer_queue.h b/chromium/media/fuchsia/common/vmo_buffer_writer_queue.h
index 761d2b5aae1..543373077dd 100644
--- a/chromium/media/fuchsia/common/sysmem_buffer_writer_queue.h
+++ b/chromium/media/fuchsia/common/vmo_buffer_writer_queue.h
@@ -1,9 +1,9 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2021 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 MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_WRITER_QUEUE_H_
-#define MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_WRITER_QUEUE_H_
+#ifndef MEDIA_FUCHSIA_COMMON_VMO_BUFFER_WRITER_QUEUE_H_
+#define MEDIA_FUCHSIA_COMMON_VMO_BUFFER_WRITER_QUEUE_H_
#include <fuchsia/media/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
@@ -12,18 +12,19 @@
#include "base/containers/span.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/threading/thread_checker.h"
+#include "media/base/media_export.h"
#include "media/fuchsia/common/stream_processor_helper.h"
-#include "media/fuchsia/common/sysmem_buffer_writer.h"
+#include "media/fuchsia/common/vmo_buffer.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
class DecoderBuffer;
-// A SysmemBufferWriter wrapper that keeps a queue of pending DecodeBuffers,
-// writes them to sysmem buffers and generates StreamProcessor packets.
-class SysmemBufferWriterQueue {
+// A helper that keeps a queue of pending DecodeBuffers, writes them to a set of
+// VmoBuffers and generates StreamProcessor packets.
+class MEDIA_EXPORT VmoBufferWriterQueue {
public:
// Callback passed to StartSender(). |buffer| corresponds to the original
// buffer from which the |packet| was generated.
@@ -34,16 +35,19 @@ class SysmemBufferWriterQueue {
// Called when processing DecoderBuffer that's marked as end-of-stream.
using EndOfStreamCB = base::RepeatingClosure;
- SysmemBufferWriterQueue();
- ~SysmemBufferWriterQueue();
+ VmoBufferWriterQueue();
+ ~VmoBufferWriterQueue();
+
+ VmoBufferWriterQueue(VmoBufferWriterQueue&) = delete;
+ VmoBufferWriterQueue& operator=(VmoBufferWriterQueue&) = delete;
// Enqueues buffer to the queue.
void EnqueueBuffer(scoped_refptr<DecoderBuffer> buffer);
- // Sets the buffer writer to use and starts sending outgoing packets using
+ // Sets the buffers to use and starts sending outgoing packets using
// |send_packet_cb|. |end_of_stream_cb| will be called when processing each
// end-of-stream buffer.
- void Start(std::unique_ptr<SysmemBufferWriter> writer,
+ void Start(std::vector<VmoBuffer> buffers,
SendPacketCB send_packet_cb,
EndOfStreamCB end_of_stream_cb);
@@ -73,6 +77,10 @@ class SysmemBufferWriterQueue {
// been allocated (i.e. before Start()).
size_t num_buffers() const;
+ // Returns true of the queue is currently blocked, i.e. buffers passed
+ // to EnqueueBuffer() will not be sent immediately.
+ bool IsBlocked() const;
+
private:
struct PendingBuffer;
class SysmemBuffer;
@@ -95,8 +103,11 @@ class SysmemBufferWriterQueue {
// Unpause() is called.
bool is_paused_ = false;
- // Buffers for sysmem buffer collection. Not set until Start() is called.
- std::unique_ptr<SysmemBufferWriter> writer_;
+ // Buffers for sysmem buffer collection. Empty until Start() is called.
+ std::vector<VmoBuffer> buffers_;
+
+ // Usd to store indices of the buffers that are not being used currently.
+ std::vector<size_t> unused_buffers_;
SendPacketCB send_packet_cb_;
EndOfStreamCB end_of_stream_cb_;
@@ -104,11 +115,9 @@ class SysmemBufferWriterQueue {
// FIDL interfaces are thread-affine (see crbug.com/1012875).
THREAD_CHECKER(thread_checker_);
- base::WeakPtrFactory<SysmemBufferWriterQueue> weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(SysmemBufferWriterQueue);
+ base::WeakPtrFactory<VmoBufferWriterQueue> weak_factory_{this};
};
} // namespace media
-#endif // MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_WRITER_QUEUE_H_
+#endif // MEDIA_FUCHSIA_COMMON_VMO_BUFFER_WRITER_QUEUE_H_
diff --git a/chromium/media/gpu/BUILD.gn b/chromium/media/gpu/BUILD.gn
index 9e5be7d3d5f..4fba7f3731e 100644
--- a/chromium/media/gpu/BUILD.gn
+++ b/chromium/media/gpu/BUILD.gn
@@ -222,6 +222,7 @@ component("gpu") {
]
public_deps += [ "//media/base/win:media_foundation_util" ]
deps += [
+ "//gpu/ipc/common:common",
"//media/base/win:hresult_status_helper",
"//media/parsers",
"//third_party/angle:includes",
diff --git a/chromium/media/gpu/android/android_video_encode_accelerator.cc b/chromium/media/gpu/android/android_video_encode_accelerator.cc
index a2e21c0273d..f5b1408bd2b 100644
--- a/chromium/media/gpu/android/android_video_encode_accelerator.cc
+++ b/chromium/media/gpu/android/android_video_encode_accelerator.cc
@@ -145,7 +145,7 @@ bool AndroidVideoEncodeAccelerator::Initialize(const Config& config,
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(client);
- client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
+ client_ptr_factory_ = std::make_unique<base::WeakPtrFactory<Client>>(client);
if (config.input_format != PIXEL_FORMAT_I420) {
DLOG(ERROR) << "Unexpected combo: " << config.input_format << ", "
diff --git a/chromium/media/gpu/android/android_video_surface_chooser.h b/chromium/media/gpu/android/android_video_surface_chooser.h
index 3b88a20655e..77ef846d4f2 100644
--- a/chromium/media/gpu/android/android_video_surface_chooser.h
+++ b/chromium/media/gpu/android/android_video_surface_chooser.h
@@ -8,10 +8,10 @@
#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "media/base/android/android_overlay.h"
#include "media/base/video_transformation.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/rect.h"
namespace media {
@@ -83,7 +83,7 @@ class MEDIA_GPU_EXPORT AndroidVideoSurfaceChooser {
// Updates the current state and makes a new surface choice with the new
// state. If |new_factory| is empty, the factory is left as-is. Otherwise,
// the factory is updated to |*new_factory|.
- virtual void UpdateState(base::Optional<AndroidOverlayFactoryCB> new_factory,
+ virtual void UpdateState(absl::optional<AndroidOverlayFactoryCB> new_factory,
const State& new_state) = 0;
private:
diff --git a/chromium/media/gpu/android/android_video_surface_chooser_impl.cc b/chromium/media/gpu/android/android_video_surface_chooser_impl.cc
index fb0f8010f23..dc562f083f4 100644
--- a/chromium/media/gpu/android/android_video_surface_chooser_impl.cc
+++ b/chromium/media/gpu/android/android_video_surface_chooser_impl.cc
@@ -35,7 +35,7 @@ void AndroidVideoSurfaceChooserImpl::SetClientCallbacks(
}
void AndroidVideoSurfaceChooserImpl::UpdateState(
- base::Optional<AndroidOverlayFactoryCB> new_factory,
+ absl::optional<AndroidOverlayFactoryCB> new_factory,
const State& new_state) {
DCHECK(use_overlay_cb_);
bool entered_fullscreen =
diff --git a/chromium/media/gpu/android/android_video_surface_chooser_impl.h b/chromium/media/gpu/android/android_video_surface_chooser_impl.h
index 84f5f486f1c..a23aad8cd51 100644
--- a/chromium/media/gpu/android/android_video_surface_chooser_impl.h
+++ b/chromium/media/gpu/android/android_video_surface_chooser_impl.h
@@ -31,7 +31,7 @@ class MEDIA_GPU_EXPORT AndroidVideoSurfaceChooserImpl
// AndroidVideoSurfaceChooser
void SetClientCallbacks(UseOverlayCB use_overlay_cb,
UseTextureOwnerCB use_texture_owner_cb) override;
- void UpdateState(base::Optional<AndroidOverlayFactoryCB> new_factory,
+ void UpdateState(absl::optional<AndroidOverlayFactoryCB> new_factory,
const State& new_state) override;
private:
diff --git a/chromium/media/gpu/android/android_video_surface_chooser_impl_unittest.cc b/chromium/media/gpu/android/android_video_surface_chooser_impl_unittest.cc
index d3de47e086c..9bd5f3a60b9 100644
--- a/chromium/media/gpu/android/android_video_surface_chooser_impl_unittest.cc
+++ b/chromium/media/gpu/android/android_video_surface_chooser_impl_unittest.cc
@@ -141,7 +141,7 @@ class AndroidVideoSurfaceChooserImplTest
base::BindRepeating(&MockClient::UseTextureOwner,
base::Unretained(&client_)));
chooser_->UpdateState(
- factory ? base::make_optional(std::move(factory)) : base::nullopt,
+ factory ? absl::make_optional(std::move(factory)) : absl::nullopt,
chooser_state_);
}
@@ -359,7 +359,7 @@ TEST_F(AndroidVideoSurfaceChooserImplTest,
// Note that if it enforces a delay here before retrying, that might be okay
// too. For now, we assume that it doesn't.
EXPECT_CALL(*this, MockOnOverlayCreated());
- chooser_->UpdateState(base::Optional<AndroidOverlayFactoryCB>(),
+ chooser_->UpdateState(absl::optional<AndroidOverlayFactoryCB>(),
chooser_state_);
}
@@ -391,7 +391,7 @@ TEST_F(AndroidVideoSurfaceChooserImplTest, AlwaysUseTextureOwner) {
// instead.
chooser_state_.always_use_texture_owner = true;
EXPECT_CALL(client_, UseTextureOwner());
- chooser_->UpdateState(base::nullopt, chooser_state_);
+ chooser_->UpdateState(absl::nullopt, chooser_state_);
}
TEST_P(AndroidVideoSurfaceChooserImplTest, OverlayIsUsedOrNotBasedOnState) {
diff --git a/chromium/media/gpu/android/codec_image.cc b/chromium/media/gpu/android/codec_image.cc
index 3721ceb5f8e..f176cad8c3d 100644
--- a/chromium/media/gpu/android/codec_image.cc
+++ b/chromium/media/gpu/android/codec_image.cc
@@ -84,17 +84,24 @@ bool CodecImage::CopyTexImage(unsigned target) {
if (!output_buffer_renderer_)
return true;
- GLint bound_service_id = 0;
- glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
- // The currently bound texture should be the texture owner's texture.
- if (bound_service_id !=
- static_cast<GLint>(
- output_buffer_renderer_->texture_owner()->GetTextureId()))
+ GLint texture_id = 0;
+ glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id);
+
+ // CopyTexImage will only be called for TextureOwner's SurfaceTexture
+ // implementation which binds texture to TextureOwner's texture_id on update.
+ DCHECK(output_buffer_renderer_->texture_owner()->binds_texture_on_update());
+ if (texture_id > 0 &&
+ static_cast<unsigned>(texture_id) !=
+ output_buffer_renderer_->texture_owner()->GetTextureId()) {
return false;
+ }
-
+ // On some devices GL_TEXTURE_BINDING_EXTERNAL_OES is not supported as
+ // glGetIntegerv() parameter. In this case the value of |texture_id| will be
+ // zero and we assume that it is properly bound to TextureOwner's texture id.
output_buffer_renderer_->RenderToTextureOwnerFrontBuffer(
- BindingsMode::kEnsureTexImageBound);
+ BindingsMode::kEnsureTexImageBound,
+ output_buffer_renderer_->texture_owner()->GetTextureId());
return true;
}
@@ -168,8 +175,9 @@ bool CodecImage::IsUsingGpuMemory() const {
return output_buffer_renderer_->was_tex_image_bound();
}
-void CodecImage::UpdateAndBindTexImage() {
- RenderToTextureOwnerFrontBuffer(BindingsMode::kEnsureTexImageBound);
+void CodecImage::UpdateAndBindTexImage(GLuint service_id) {
+ RenderToTextureOwnerFrontBuffer(BindingsMode::kEnsureTexImageBound,
+ service_id);
}
bool CodecImage::HasTextureOwner() const {
@@ -193,11 +201,12 @@ bool CodecImage::RenderToTextureOwnerBackBuffer() {
return output_buffer_renderer_->RenderToTextureOwnerBackBuffer();
}
-bool CodecImage::RenderToTextureOwnerFrontBuffer(BindingsMode bindings_mode) {
+bool CodecImage::RenderToTextureOwnerFrontBuffer(BindingsMode bindings_mode,
+ GLuint service_id) {
if (!output_buffer_renderer_)
return false;
- return output_buffer_renderer_->RenderToTextureOwnerFrontBuffer(
- bindings_mode);
+ return output_buffer_renderer_->RenderToTextureOwnerFrontBuffer(bindings_mode,
+ service_id);
}
bool CodecImage::RenderToOverlay() {
@@ -206,6 +215,12 @@ bool CodecImage::RenderToOverlay() {
return output_buffer_renderer_->RenderToOverlay();
}
+bool CodecImage::TextureOwnerBindsTextureOnUpdate() {
+ if (!output_buffer_renderer_)
+ return false;
+ return output_buffer_renderer_->texture_owner()->binds_texture_on_update();
+}
+
void CodecImage::ReleaseCodecBuffer() {
output_buffer_renderer_.reset();
}
@@ -219,7 +234,11 @@ CodecImage::GetAHardwareBuffer() {
if (!output_buffer_renderer_)
return nullptr;
- RenderToTextureOwnerFrontBuffer(BindingsMode::kDontRestoreIfBound);
+ // Using BindingsMode::kDontRestoreIfBound here since we do not want to bind
+ // the image. We just want to get the AHardwareBuffer from the latest image.
+ // Hence pass service_id as 0.
+ RenderToTextureOwnerFrontBuffer(BindingsMode::kDontRestoreIfBound,
+ 0 /* service_id */);
return output_buffer_renderer_->texture_owner()->GetAHardwareBuffer();
}
diff --git a/chromium/media/gpu/android/codec_image.h b/chromium/media/gpu/android/codec_image.h
index d71cda8f3a4..531f0d664ba 100644
--- a/chromium/media/gpu/android/codec_image.h
+++ b/chromium/media/gpu/android/codec_image.h
@@ -99,13 +99,14 @@ class MEDIA_GPU_EXPORT CodecImage
// gpu::StreamTextureSharedImageInterface implementation.
void ReleaseResources() override;
bool IsUsingGpuMemory() const override;
- void UpdateAndBindTexImage() override;
+ void UpdateAndBindTexImage(GLuint service_id) override;
bool HasTextureOwner() const override;
gpu::TextureBase* GetTextureBase() const override;
void NotifyOverlayPromotion(bool promotion, const gfx::Rect& bounds) override;
// Renders this image to the overlay. Returns true if the buffer is in the
// overlay front buffer. Returns false if the buffer was invalidated.
bool RenderToOverlay() override;
+ bool TextureOwnerBindsTextureOnUpdate() override;
// Whether the codec buffer has been rendered to the front buffer.
bool was_rendered_to_front_buffer() const {
@@ -156,7 +157,12 @@ class MEDIA_GPU_EXPORT CodecImage
// Renders this image to the texture owner front buffer by first rendering
// it to the back buffer if it's not already there, and then waiting for the
// frame available event before calling UpdateTexImage().
- bool RenderToTextureOwnerFrontBuffer(BindingsMode bindings_mode);
+ // Also bind the latest image
+ // to the provided |service_id| if TextureOwner does not binds texture on
+ // update. If |bindings_mode| is other than kEnsureTexImageBound, then
+ // |service_id| is not required.
+ bool RenderToTextureOwnerFrontBuffer(BindingsMode bindings_mode,
+ GLuint service_id);
// Whether this image is texture_owner or overlay backed.
bool is_texture_owner_backed_ = false;
diff --git a/chromium/media/gpu/android/codec_image_group.h b/chromium/media/gpu/android/codec_image_group.h
index 9eda7b27e99..0b27493e908 100644
--- a/chromium/media/gpu/android/codec_image_group.h
+++ b/chromium/media/gpu/android/codec_image_group.h
@@ -74,4 +74,4 @@ class MEDIA_GPU_EXPORT CodecImageGroup
} // namespace media
-#endif // MEDIA_GPU_ANDROID_CODEC_IMAGE_H_
+#endif // MEDIA_GPU_ANDROID_CODEC_IMAGE_GROUP_H_
diff --git a/chromium/media/gpu/android/codec_image_unittest.cc b/chromium/media/gpu/android/codec_image_unittest.cc
index 29a09b3989d..bdc1676a7ff 100644
--- a/chromium/media/gpu/android/codec_image_unittest.cc
+++ b/chromium/media/gpu/android/codec_image_unittest.cc
@@ -207,20 +207,6 @@ TEST_F(CodecImageTest, CopyTexImageTriggersFrontBufferRendering) {
ASSERT_TRUE(i->was_rendered_to_front_buffer());
}
-TEST_F(CodecImageTestExplicitBind, CopyTexImageTriggersFrontBufferRendering) {
- auto i = NewImage(kTextureOwner);
- // Verify that the release comes before the wait.
- InSequence s;
- EXPECT_CALL(*codec_, ReleaseOutputBuffer(_, true));
- EXPECT_CALL(*codec_buffer_wait_coordinator_, WaitForFrameAvailable());
- EXPECT_CALL(*codec_buffer_wait_coordinator_->texture_owner(),
- UpdateTexImage());
- EXPECT_CALL(*codec_buffer_wait_coordinator_->texture_owner(),
- EnsureTexImageBound());
- i->CopyTexImage(GL_TEXTURE_EXTERNAL_OES);
- ASSERT_TRUE(i->was_rendered_to_front_buffer());
-}
-
TEST_F(CodecImageTest, ScheduleOverlayPlaneTriggersFrontBufferRendering) {
auto i = NewImage(kOverlay);
EXPECT_CALL(*codec_, ReleaseOutputBuffer(_, true));
@@ -380,7 +366,8 @@ TEST_F(CodecImageTest, RenderAfterUnusedDoesntCrash) {
i->NotifyUnused();
EXPECT_FALSE(i->RenderToTextureOwnerBackBuffer());
EXPECT_FALSE(i->RenderToTextureOwnerFrontBuffer(
- CodecImage::BindingsMode::kEnsureTexImageBound));
+ CodecImage::BindingsMode::kEnsureTexImageBound,
+ codec_buffer_wait_coordinator_->texture_owner()->GetTextureId()));
}
TEST_F(CodecImageTest, CodedSizeVsVisibleSize) {
diff --git a/chromium/media/gpu/android/codec_output_buffer_renderer.cc b/chromium/media/gpu/android/codec_output_buffer_renderer.cc
index b327de7c161..00cba42ab2a 100644
--- a/chromium/media/gpu/android/codec_output_buffer_renderer.cc
+++ b/chromium/media/gpu/android/codec_output_buffer_renderer.cc
@@ -7,13 +7,14 @@
#include "base/android/scoped_hardware_buffer_fence_sync.h"
#include "base/callback_helpers.h"
-#include "base/optional.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/texture_manager.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/scoped_make_current.h"
namespace media {
+
namespace {
// Makes |texture_owner|'s context current if it isn't already.
@@ -38,19 +39,6 @@ std::unique_ptr<ui::ScopedMakeCurrent> MakeCurrentIfNeeded(
return scoped_current;
}
-class ScopedRestoreTextureBinding {
- public:
- ScopedRestoreTextureBinding() {
- glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id_);
- }
- ~ScopedRestoreTextureBinding() {
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id_);
- }
-
- private:
- GLint bound_service_id_;
-};
-
} // namespace
CodecOutputBufferRenderer::CodecOutputBufferRenderer(
@@ -93,7 +81,8 @@ bool CodecOutputBufferRenderer::RenderToTextureOwnerBackBuffer() {
}
bool CodecOutputBufferRenderer::RenderToTextureOwnerFrontBuffer(
- BindingsMode bindings_mode) {
+ BindingsMode bindings_mode,
+ GLuint service_id) {
// Normally, we should have a wait coordinator if we're called. However, if
// the renderer is torn down (either VideoFrameSubmitter or the whole process)
// before we get returns back from viz, then we can be notified that we're
@@ -103,33 +92,33 @@ bool CodecOutputBufferRenderer::RenderToTextureOwnerFrontBuffer(
return false;
if (phase_ == Phase::kInFrontBuffer) {
- EnsureBoundIfNeeded(bindings_mode);
+ EnsureBoundIfNeeded(bindings_mode, service_id);
return true;
}
if (phase_ == Phase::kInvalidated)
return false;
std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current;
+ absl::optional<gpu::ScopedRestoreTextureBinding> scoped_restore_texture;
- // If the texture_owner() binds the texture while doing the texture update
- // (UpdateTexImage), like in SurfaceTexture case, then only make the context
- // current. For AImageReader, since we only acquire the latest image from it
- // during the texture update process, there is no need to make it's context
- // current.
if (codec_buffer_wait_coordinator_->texture_owner()
->binds_texture_on_update()) {
+ // If the texture_owner() binds the texture while doing the texture update
+ // (UpdateTexImage), like in SurfaceTexture case, then make sure that the
+ // texture owner's context is made current. This is because the texture
+ // which will be bound was generated on TextureOwner's context.
+ // For AImageReader case, the texture which will be bound will not
+ // necessarily be TextureOwner's texture and hence caller is responsible to
+ // handle making correct context current before binding the texture.
scoped_make_current = MakeCurrentIfNeeded(
codec_buffer_wait_coordinator_->texture_owner().get());
- }
- // If updating the image will implicitly update the texture bindings then
- // restore if requested or the update needed a context switch.
- base::Optional<ScopedRestoreTextureBinding> scoped_restore_texture;
- if (codec_buffer_wait_coordinator_->texture_owner()
- ->binds_texture_on_update() &&
- (bindings_mode == BindingsMode::kRestoreIfBound ||
- !!scoped_make_current)) {
- scoped_restore_texture.emplace();
+ // If updating the image will implicitly update the texture bindings then
+ // restore if requested or the update needed a context switch.
+ if (bindings_mode == BindingsMode::kRestoreIfBound ||
+ !!scoped_make_current) {
+ scoped_restore_texture.emplace();
+ }
}
// Render it to the back buffer if it's not already there.
@@ -157,21 +146,30 @@ bool CodecOutputBufferRenderer::RenderToTextureOwnerFrontBuffer(
codec_buffer_wait_coordinator_->WaitForFrameAvailable();
codec_buffer_wait_coordinator_->texture_owner()->UpdateTexImage();
- EnsureBoundIfNeeded(bindings_mode);
+ EnsureBoundIfNeeded(bindings_mode, service_id);
return true;
}
-void CodecOutputBufferRenderer::EnsureBoundIfNeeded(BindingsMode mode) {
+void CodecOutputBufferRenderer::EnsureBoundIfNeeded(BindingsMode mode,
+ GLuint service_id) {
DCHECK(codec_buffer_wait_coordinator_);
if (codec_buffer_wait_coordinator_->texture_owner()
->binds_texture_on_update()) {
+ if (mode == BindingsMode::kEnsureTexImageBound) {
+ DCHECK_EQ(
+ service_id,
+ codec_buffer_wait_coordinator_->texture_owner()->GetTextureId());
+ }
was_tex_image_bound_ = true;
return;
}
if (mode != BindingsMode::kEnsureTexImageBound)
return;
- codec_buffer_wait_coordinator_->texture_owner()->EnsureTexImageBound();
+
+ DCHECK_GT(service_id, 0u);
+ codec_buffer_wait_coordinator_->texture_owner()->EnsureTexImageBound(
+ service_id);
was_tex_image_bound_ = true;
}
@@ -191,9 +189,11 @@ bool CodecOutputBufferRenderer::RenderToOverlay() {
bool CodecOutputBufferRenderer::RenderToFrontBuffer() {
// This code is used to trigger early rendering of the image before it is used
- // for compositing, there is no need to bind the image.
+ // for compositing, there is no need to bind the image. Hence pass texture
+ // service_id as 0.
return codec_buffer_wait_coordinator_
- ? RenderToTextureOwnerFrontBuffer(BindingsMode::kRestoreIfBound)
+ ? RenderToTextureOwnerFrontBuffer(BindingsMode::kRestoreIfBound,
+ 0 /* service_id */)
: RenderToOverlay();
}
diff --git a/chromium/media/gpu/android/codec_output_buffer_renderer.h b/chromium/media/gpu/android/codec_output_buffer_renderer.h
index d809960aae0..e8c23774edc 100644
--- a/chromium/media/gpu/android/codec_output_buffer_renderer.h
+++ b/chromium/media/gpu/android/codec_output_buffer_renderer.h
@@ -39,7 +39,11 @@ class MEDIA_GPU_EXPORT CodecOutputBufferRenderer {
// Renders this image to the texture owner front buffer by first rendering
// it to the back buffer if it's not already there, and then waiting for the
// frame available event before calling UpdateTexImage().
- bool RenderToTextureOwnerFrontBuffer(BindingsMode bindings_mode);
+ // Also bind the latest imagecto the provided |service_id| if TextureOwner
+ // does not binds texture on update. If |bindings_mode| is other than
+ // kEnsureTexImageBound, then |service_id| is not required.
+ bool RenderToTextureOwnerFrontBuffer(BindingsMode bindings_mode,
+ GLuint service_id);
// Renders this image to the front buffer of its backing surface.
// Returns true if the buffer is in the front buffer. Returns false if the
@@ -80,7 +84,11 @@ class MEDIA_GPU_EXPORT CodecOutputBufferRenderer {
// kInFrontBuffer and kInvalidated are terminal.
enum class Phase { kInCodec, kInBackBuffer, kInFrontBuffer, kInvalidated };
- void EnsureBoundIfNeeded(BindingsMode mode);
+ // Ensure that the latest image is bound to the texture |service_id| if
+ // TextureOwner does not binds texture on update. If TextureOwner binds
+ // texture on update, then it will always be bound to the TextureOwners
+ // texture and |service_id| will be ignored.
+ void EnsureBoundIfNeeded(BindingsMode mode, GLuint service_id);
void set_phase_for_testing(Phase phase) { phase_ = phase; }
@@ -98,4 +106,4 @@ class MEDIA_GPU_EXPORT CodecOutputBufferRenderer {
};
} // namespace media
-#endif // MEDIA_GPU_ANDROID_CODEC_OUTPUT_BUFFER_RENDERER_H
+#endif // MEDIA_GPU_ANDROID_CODEC_OUTPUT_BUFFER_RENDERER_H_
diff --git a/chromium/media/gpu/android/codec_wrapper.cc b/chromium/media/gpu/android/codec_wrapper.cc
index be7a5ddd7a4..8083f4c5381 100644
--- a/chromium/media/gpu/android/codec_wrapper.cc
+++ b/chromium/media/gpu/android/codec_wrapper.cc
@@ -12,10 +12,10 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
-#include "base/optional.h"
#include "base/stl_util.h"
#include "media/base/android/media_codec_util.h"
#include "media/base/bind_to_current_loop.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -82,7 +82,7 @@ class CodecWrapperImpl : public base::RefCountedThreadSafe<CodecWrapperImpl> {
// An input buffer that was dequeued but subsequently rejected from
// QueueInputBuffer() because the codec didn't have the crypto key. We
// maintain ownership of it and reuse it next time.
- base::Optional<int> owned_input_buffer_;
+ absl::optional<int> owned_input_buffer_;
// The current output size. Updated when DequeueOutputBuffer() reports
// OUTPUT_FORMAT_CHANGED.
diff --git a/chromium/media/gpu/android/direct_shared_image_video_provider.cc b/chromium/media/gpu/android/direct_shared_image_video_provider.cc
index 11efbbe4db0..8fcc9ca3bc2 100644
--- a/chromium/media/gpu/android/direct_shared_image_video_provider.cc
+++ b/chromium/media/gpu/android/direct_shared_image_video_provider.cc
@@ -71,10 +71,8 @@ void DirectSharedImageVideoProvider::Initialize(GpuInitCB gpu_init_cb) {
.WithArgs(std::move(gpu_init_cb));
}
-void DirectSharedImageVideoProvider::RequestImage(
- ImageReadyCB cb,
- const ImageSpec& spec,
- scoped_refptr<gpu::TextureOwner> texture_owner) {
+void DirectSharedImageVideoProvider::RequestImage(ImageReadyCB cb,
+ const ImageSpec& spec) {
// It's unclear that we should handle the image group, but since CodecImages
// have to be registered on it, we do. If the CodecImage is ever re-used,
// then part of that re-use would be to call the (then mis-named)
@@ -87,8 +85,7 @@ void DirectSharedImageVideoProvider::RequestImage(
// Note: `cb` is only run on successful creation, so this does not use
// `AsyncCall()` + `Then()` to chain the callbacks.
gpu_factory_.AsyncCall(&GpuSharedImageVideoFactory::CreateImage)
- .WithArgs(BindToCurrentLoop(std::move(cb)), spec,
- std::move(texture_owner));
+ .WithArgs(BindToCurrentLoop(std::move(cb)), spec);
}
GpuSharedImageVideoFactory::GpuSharedImageVideoFactory(
@@ -113,8 +110,6 @@ void GpuSharedImageVideoFactory::Initialize(
return;
}
- decoder_helper_ = GLES2DecoderHelper::Create(stub_->decoder_context());
-
gpu::ContextResult result;
auto shared_context = GetSharedContext(stub_, &result);
if (!shared_context) {
@@ -145,8 +140,7 @@ void GpuSharedImageVideoFactory::Initialize(
void GpuSharedImageVideoFactory::CreateImage(
FactoryImageReadyCB image_ready_cb,
- const SharedImageVideoProvider::ImageSpec& spec,
- scoped_refptr<gpu::TextureOwner> texture_owner) {
+ const SharedImageVideoProvider::ImageSpec& spec) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Generate a shared image mailbox.
@@ -155,8 +149,7 @@ void GpuSharedImageVideoFactory::CreateImage(
TRACE_EVENT0("media", "GpuSharedImageVideoFactory::CreateVideoFrame");
- if (!CreateImageInternal(spec, std::move(texture_owner), mailbox,
- codec_image)) {
+ if (!CreateImageInternal(spec, mailbox, codec_image)) {
return;
}
@@ -192,7 +185,6 @@ void GpuSharedImageVideoFactory::CreateImage(
bool GpuSharedImageVideoFactory::CreateImageInternal(
const SharedImageVideoProvider::ImageSpec& spec,
- scoped_refptr<gpu::TextureOwner> texture_owner,
gpu::Mailbox mailbox,
scoped_refptr<CodecImage> image) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -205,28 +197,6 @@ bool GpuSharedImageVideoFactory::CreateImageInternal(
const auto& coded_size = spec.coded_size;
- // Create a Texture and a CodecImage to back it.
- // TODO(liberato): Once legacy mailbox support is removed, we don't need to
- // create this texture. So, we won't need |texture_owner| either.
- std::unique_ptr<AbstractTexture> texture = decoder_helper_->CreateTexture(
- GL_TEXTURE_EXTERNAL_OES, GL_RGBA, coded_size.width(), coded_size.height(),
- GL_RGBA, GL_UNSIGNED_BYTE);
-
- // Attach the image to the texture.
- // Either way, we expect this to be UNBOUND (i.e., decoder-managed). For
- // overlays, BindTexImage will return true, causing it to transition to the
- // BOUND state, and thus receive ScheduleOverlayPlane calls. For TextureOwner
- // backed images, BindTexImage will return false, and CopyTexImage will be
- // tried next.
- // TODO(liberato): consider not binding this as a StreamTextureImage if we're
- // using an overlay. There's no advantage. We'd likely want to create (and
- // initialize to a 1x1 texture) a 2D texture above in that case, in case
- // somebody tries to sample from it. Be sure that promotion hints still
- // work properly, though -- they might require a stream texture image.
- GLuint texture_owner_service_id =
- texture_owner ? texture_owner->GetTextureId() : 0;
- texture->BindStreamTextureImage(image.get(), texture_owner_service_id);
-
gpu::ContextResult result;
auto shared_context = GetSharedContext(stub_, &result);
if (!shared_context) {
@@ -244,8 +214,7 @@ bool GpuSharedImageVideoFactory::CreateImageInternal(
auto shared_image = std::make_unique<gpu::SharedImageVideo>(
mailbox, coded_size, gfx::ColorSpace::CreateSRGB(),
kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, std::move(image),
- std::move(texture), std::move(shared_context),
- false /* is_thread_safe */);
+ std::move(shared_context), false /* is_thread_safe */);
// Register it with shared image mailbox as well as legacy mailbox. This
// keeps |shared_image| around until its destruction cb is called.
@@ -253,7 +222,7 @@ bool GpuSharedImageVideoFactory::CreateImageInternal(
// mailbox.
DCHECK(stub_->channel()->gpu_channel_manager()->shared_image_manager());
stub_->channel()->shared_image_stub()->factory()->RegisterBacking(
- std::move(shared_image), /* legacy_mailbox */ true);
+ std::move(shared_image), /*allow_legacy_mailbox=*/false);
return true;
}
@@ -262,7 +231,6 @@ void GpuSharedImageVideoFactory::OnWillDestroyStub(bool have_context) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(stub_);
stub_ = nullptr;
- decoder_helper_ = nullptr;
}
} // namespace media
diff --git a/chromium/media/gpu/android/direct_shared_image_video_provider.h b/chromium/media/gpu/android/direct_shared_image_video_provider.h
index e140b6cad02..2499058a255 100644
--- a/chromium/media/gpu/android/direct_shared_image_video_provider.h
+++ b/chromium/media/gpu/android/direct_shared_image_video_provider.h
@@ -5,10 +5,7 @@
#ifndef MEDIA_GPU_ANDROID_DIRECT_SHARED_IMAGE_VIDEO_PROVIDER_H_
#define MEDIA_GPU_ANDROID_DIRECT_SHARED_IMAGE_VIDEO_PROVIDER_H_
-#include <memory>
-
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/sequence_bound.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
@@ -24,6 +21,7 @@
#include "media/gpu/android/video_frame_factory.h"
#include "media/gpu/gles2_decoder_helper.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gl/gl_bindings.h"
namespace media {
@@ -41,9 +39,7 @@ class MEDIA_GPU_EXPORT DirectSharedImageVideoProvider
// SharedImageVideoProvider
void Initialize(GpuInitCB get_stub_cb) override;
- void RequestImage(ImageReadyCB cb,
- const ImageSpec& spec,
- scoped_refptr<gpu::TextureOwner> texture_owner) override;
+ void RequestImage(ImageReadyCB cb, const ImageSpec& spec) override;
private:
base::SequenceBound<GpuSharedImageVideoFactory> gpu_factory_;
@@ -79,23 +75,17 @@ class GpuSharedImageVideoFactory
// create the per-frame texture. All of that is only needed for legacy
// mailbox support, where we have to have one texture per CodecImage.
void CreateImage(FactoryImageReadyCB cb,
- const SharedImageVideoProvider::ImageSpec& spec,
- scoped_refptr<gpu::TextureOwner> texture_owner);
+ const SharedImageVideoProvider::ImageSpec& spec);
private:
// Creates a SharedImage for |mailbox|, and returns success or failure.
bool CreateImageInternal(const SharedImageVideoProvider::ImageSpec& spec,
- scoped_refptr<gpu::TextureOwner> texture_owner,
gpu::Mailbox mailbox,
scoped_refptr<CodecImage> image);
void OnWillDestroyStub(bool have_context) override;
gpu::CommandBufferStub* stub_ = nullptr;
-
- // A helper for creating textures. Only valid while |stub_| is valid.
- std::unique_ptr<GLES2DecoderHelper> decoder_helper_;
-
bool is_vulkan_ = false;
THREAD_CHECKER(thread_checker_);
diff --git a/chromium/media/gpu/android/frame_info_helper.cc b/chromium/media/gpu/android/frame_info_helper.cc
index 6d4b20935e0..22950e69376 100644
--- a/chromium/media/gpu/android/frame_info_helper.cc
+++ b/chromium/media/gpu/android/frame_info_helper.cc
@@ -71,16 +71,17 @@ class FrameInfoHelperImpl : public FrameInfoHelper {
void GetFrameInfoImpl(
std::unique_ptr<CodecOutputBufferRenderer> buffer_renderer,
base::OnceCallback<void(std::unique_ptr<CodecOutputBufferRenderer>,
- base::Optional<FrameInfo>)> cb) {
+ absl::optional<FrameInfo>)> cb) {
DCHECK(buffer_renderer);
auto texture_owner = buffer_renderer->texture_owner();
DCHECK(texture_owner);
- base::Optional<FrameInfo> info;
+ absl::optional<FrameInfo> info;
if (buffer_renderer->RenderToTextureOwnerFrontBuffer(
- CodecOutputBufferRenderer::BindingsMode::kDontRestoreIfBound)) {
+ CodecOutputBufferRenderer::BindingsMode::kDontRestoreIfBound,
+ 0)) {
gfx::Size coded_size;
gfx::Rect visible_rect;
if (texture_owner->GetCodedSizeAndVisibleRect(
@@ -98,7 +99,7 @@ class FrameInfoHelperImpl : public FrameInfoHelper {
void GetFrameInfo(
std::unique_ptr<CodecOutputBufferRenderer> buffer_renderer,
base::OnceCallback<void(std::unique_ptr<CodecOutputBufferRenderer>,
- base::Optional<FrameInfo>)> cb) {
+ absl::optional<FrameInfo>)> cb) {
DCHECK(buffer_renderer);
auto texture_owner = buffer_renderer->texture_owner();
@@ -112,12 +113,12 @@ class FrameInfoHelperImpl : public FrameInfoHelper {
private:
// Gets YCbCrInfo from last rendered frame.
- base::Optional<gpu::VulkanYCbCrInfo> GetYCbCrInfo(
+ absl::optional<gpu::VulkanYCbCrInfo> GetYCbCrInfo(
gpu::TextureOwner* texture_owner) {
gpu::ContextResult result;
if (!stub_)
- return base::nullopt;
+ return absl::nullopt;
auto shared_context =
stub_->channel()->gpu_channel_manager()->GetSharedContextState(
@@ -125,7 +126,7 @@ class FrameInfoHelperImpl : public FrameInfoHelper {
auto context_provider =
(result == gpu::ContextResult::kSuccess) ? shared_context : nullptr;
if (!context_provider)
- return base::nullopt;
+ return absl::nullopt;
return gpu::SharedImageVideo::GetYcbcrInfo(texture_owner,
context_provider);
@@ -144,7 +145,7 @@ class FrameInfoHelperImpl : public FrameInfoHelper {
void OnFrameInfoReady(
std::unique_ptr<CodecOutputBufferRenderer> buffer_renderer,
- base::Optional<FrameInfo> frame_info) {
+ absl::optional<FrameInfo> frame_info) {
DCHECK(buffer_renderer);
DCHECK(!requests_.empty());
diff --git a/chromium/media/gpu/android/frame_info_helper.h b/chromium/media/gpu/android/frame_info_helper.h
index 1f60bceb094..f4be1c76efd 100644
--- a/chromium/media/gpu/android/frame_info_helper.h
+++ b/chromium/media/gpu/android/frame_info_helper.h
@@ -5,9 +5,9 @@
#ifndef MEDIA_GPU_ANDROID_FRAME_INFO_HELPER_H_
#define MEDIA_GPU_ANDROID_FRAME_INFO_HELPER_H_
-#include "base/optional.h"
#include "media/gpu/android/shared_image_video_provider.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
class CodecOutputBufferRenderer;
@@ -25,7 +25,7 @@ class MEDIA_GPU_EXPORT FrameInfoHelper {
gfx::Size coded_size;
gfx::Rect visible_rect;
- base::Optional<gpu::VulkanYCbCrInfo> ycbcr_info;
+ absl::optional<gpu::VulkanYCbCrInfo> ycbcr_info;
};
using FrameInfoReadyCB =
diff --git a/chromium/media/gpu/android/maybe_render_early_manager.h b/chromium/media/gpu/android/maybe_render_early_manager.h
index de26f8e23df..5a4c2a7ceb9 100644
--- a/chromium/media/gpu/android/maybe_render_early_manager.h
+++ b/chromium/media/gpu/android/maybe_render_early_manager.h
@@ -9,10 +9,10 @@
#include <vector>
#include "base/memory/scoped_refptr.h"
-#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "media/gpu/android/codec_image.h" // For CodecImage::BlockingMode
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
class CodecImageHolder;
@@ -61,7 +61,7 @@ void MEDIA_GPU_EXPORT MaybeRenderEarly(std::vector<Image*>* image_vector_ptr) {
return;
// Find the latest image rendered to the front buffer (if any).
- base::Optional<size_t> front_buffer_index;
+ absl::optional<size_t> front_buffer_index;
for (int i = images.size() - 1; i >= 0; --i) {
if (images[i]->was_rendered_to_front_buffer()) {
front_buffer_index = i;
diff --git a/chromium/media/gpu/android/media_codec_video_decoder.cc b/chromium/media/gpu/android/media_codec_video_decoder.cc
index be37e450fbd..10c7deb0e10 100644
--- a/chromium/media/gpu/android/media_codec_video_decoder.cc
+++ b/chromium/media/gpu/android/media_codec_video_decoder.cc
@@ -564,8 +564,8 @@ void MediaCodecVideoDecoder::OnOverlayInfoChanged(
surface_chooser_helper_.SetIsPersistentVideo(
overlay_info_.is_persistent_video);
surface_chooser_helper_.UpdateChooserState(
- overlay_changed ? base::make_optional(CreateOverlayFactoryCb())
- : base::nullopt);
+ overlay_changed ? absl::make_optional(CreateOverlayFactoryCb())
+ : absl::nullopt);
}
void MediaCodecVideoDecoder::OnSurfaceChosen(
diff --git a/chromium/media/gpu/android/media_codec_video_decoder.h b/chromium/media/gpu/android/media_codec_video_decoder.h
index 4b9d81a7821..6e7997ac53e 100644
--- a/chromium/media/gpu/android/media_codec_video_decoder.h
+++ b/chromium/media/gpu/android/media_codec_video_decoder.h
@@ -8,7 +8,6 @@
#include <vector>
#include "base/containers/circular_deque.h"
-#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "base/timer/elapsed_timer.h"
#include "base/timer/timer.h"
@@ -28,6 +27,7 @@
#include "media/gpu/android/surface_chooser_helper.h"
#include "media/gpu/android/video_frame_factory.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -242,7 +242,7 @@ class MEDIA_GPU_EXPORT MediaCodecVideoDecoder final : public VideoDecoder {
bool waiting_for_key_ = false;
// The reason for the current drain operation if any.
- base::Optional<DrainType> drain_type_;
+ absl::optional<DrainType> drain_type_;
// The current reset cb if a Reset() is in progress.
base::OnceClosure reset_cb_;
diff --git a/chromium/media/gpu/android/mock_android_video_surface_chooser.cc b/chromium/media/gpu/android/mock_android_video_surface_chooser.cc
index 35f701f1ab7..f490acf8834 100644
--- a/chromium/media/gpu/android/mock_android_video_surface_chooser.cc
+++ b/chromium/media/gpu/android/mock_android_video_surface_chooser.cc
@@ -18,7 +18,7 @@ void MockAndroidVideoSurfaceChooser::SetClientCallbacks(
}
void MockAndroidVideoSurfaceChooser::UpdateState(
- base::Optional<AndroidOverlayFactoryCB> factory,
+ absl::optional<AndroidOverlayFactoryCB> factory,
const State& new_state) {
MockUpdateState();
if (factory) {
diff --git a/chromium/media/gpu/android/mock_android_video_surface_chooser.h b/chromium/media/gpu/android/mock_android_video_surface_chooser.h
index 24a2322f734..2f0fe248b00 100644
--- a/chromium/media/gpu/android/mock_android_video_surface_chooser.h
+++ b/chromium/media/gpu/android/mock_android_video_surface_chooser.h
@@ -28,7 +28,7 @@ class MockAndroidVideoSurfaceChooser : public AndroidVideoSurfaceChooser {
void SetClientCallbacks(UseOverlayCB use_overlay_cb,
UseTextureOwnerCB use_texture_owner_cb) override;
- void UpdateState(base::Optional<AndroidOverlayFactoryCB> factory,
+ void UpdateState(absl::optional<AndroidOverlayFactoryCB> factory,
const State& new_state) override;
// Calls the corresponding callback to choose the surface.
diff --git a/chromium/media/gpu/android/mock_shared_image_video_provider.cc b/chromium/media/gpu/android/mock_shared_image_video_provider.cc
index c131f4ac8e5..ecde0e54d2a 100644
--- a/chromium/media/gpu/android/mock_shared_image_video_provider.cc
+++ b/chromium/media/gpu/android/mock_shared_image_video_provider.cc
@@ -8,11 +8,8 @@ namespace media {
MockSharedImageVideoProvider::RequestImageArgs::RequestImageArgs(
ImageReadyCB cb,
- ImageSpec spec,
- scoped_refptr<gpu::TextureOwner> texture_owner)
- : cb_(std::move(cb)),
- spec_(std::move(spec)),
- texture_owner_(std::move(texture_owner)) {}
+ ImageSpec spec)
+ : cb_(std::move(cb)), spec_(std::move(spec)) {}
MockSharedImageVideoProvider::RequestImageArgs::~RequestImageArgs() = default;
diff --git a/chromium/media/gpu/android/mock_shared_image_video_provider.h b/chromium/media/gpu/android/mock_shared_image_video_provider.h
index cd554aa2b46..4412dc95185 100644
--- a/chromium/media/gpu/android/mock_shared_image_video_provider.h
+++ b/chromium/media/gpu/android/mock_shared_image_video_provider.h
@@ -25,10 +25,8 @@ class MockSharedImageVideoProvider : public SharedImageVideoProvider {
MOCK_METHOD1(Initialize_, void(GpuInitCB& gpu_init_cb));
- void RequestImage(ImageReadyCB cb,
- const ImageSpec& spec,
- scoped_refptr<gpu::TextureOwner> texture_owner) override {
- requests_.emplace_back(std::move(cb), spec, std::move(texture_owner));
+ void RequestImage(ImageReadyCB cb, const ImageSpec& spec) override {
+ requests_.emplace_back(std::move(cb), spec);
MockRequestImage();
}
@@ -59,13 +57,10 @@ class MockSharedImageVideoProvider : public SharedImageVideoProvider {
// Most recent arguments to RequestImage.
struct RequestImageArgs {
- RequestImageArgs(ImageReadyCB cb,
- ImageSpec spec,
- scoped_refptr<gpu::TextureOwner> texture_owner);
+ RequestImageArgs(ImageReadyCB cb, ImageSpec spec);
~RequestImageArgs();
ImageReadyCB cb_;
ImageSpec spec_;
- scoped_refptr<gpu::TextureOwner> texture_owner_;
};
std::list<RequestImageArgs> requests_;
diff --git a/chromium/media/gpu/android/pooled_shared_image_video_provider.cc b/chromium/media/gpu/android/pooled_shared_image_video_provider.cc
index a4b10ff30a7..b4e3d0a3171 100644
--- a/chromium/media/gpu/android/pooled_shared_image_video_provider.cc
+++ b/chromium/media/gpu/android/pooled_shared_image_video_provider.cc
@@ -52,10 +52,8 @@ void PooledSharedImageVideoProvider::Initialize(GpuInitCB gpu_init_cb) {
provider_->Initialize(std::move(gpu_init_cb));
}
-void PooledSharedImageVideoProvider::RequestImage(
- ImageReadyCB cb,
- const ImageSpec& spec,
- scoped_refptr<gpu::TextureOwner> texture_owner) {
+void PooledSharedImageVideoProvider::RequestImage(ImageReadyCB cb,
+ const ImageSpec& spec) {
// See if the pool matches the requested spec.
if (pool_spec_ != spec) {
// Nope -- mark any outstanding images for destruction and start a new pool.
@@ -106,7 +104,7 @@ void PooledSharedImageVideoProvider::RequestImage(
auto ready_cb =
base::BindOnce(&PooledSharedImageVideoProvider::OnImageCreated,
weak_factory_.GetWeakPtr(), spec);
- provider_->RequestImage(std::move(ready_cb), spec, std::move(texture_owner));
+ provider_->RequestImage(std::move(ready_cb), spec);
}
void PooledSharedImageVideoProvider::OnImageCreated(ImageSpec spec,
diff --git a/chromium/media/gpu/android/pooled_shared_image_video_provider.h b/chromium/media/gpu/android/pooled_shared_image_video_provider.h
index a4d02393d3f..8f13b656d92 100644
--- a/chromium/media/gpu/android/pooled_shared_image_video_provider.h
+++ b/chromium/media/gpu/android/pooled_shared_image_video_provider.h
@@ -46,9 +46,7 @@ class MEDIA_GPU_EXPORT PooledSharedImageVideoProvider
// SharedImageVideoProvider
void Initialize(GpuInitCB gpu_init_cb) override;
- void RequestImage(ImageReadyCB cb,
- const ImageSpec& spec,
- scoped_refptr<gpu::TextureOwner> texture_owner) override;
+ void RequestImage(ImageReadyCB cb, const ImageSpec& spec) override;
private:
friend class PooledSharedImageVideoProviderTest;
diff --git a/chromium/media/gpu/android/pooled_shared_image_video_provider_unittest.cc b/chromium/media/gpu/android/pooled_shared_image_video_provider_unittest.cc
index 174c8bb8c8b..0776d2b616a 100644
--- a/chromium/media/gpu/android/pooled_shared_image_video_provider_unittest.cc
+++ b/chromium/media/gpu/android/pooled_shared_image_video_provider_unittest.cc
@@ -10,7 +10,6 @@
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "base/threading/sequenced_task_runner_handle.h"
-#include "gpu/command_buffer/service/abstract_texture_impl_shared_context_state.h"
#include "gpu/ipc/common/command_buffer_id.h"
#include "media/gpu/android/mock_shared_image_video_provider.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -70,7 +69,7 @@ class PooledSharedImageVideoProviderTest : public testing::Test {
// |mock_provider_raw_|. Have |mock_provider_raw_| return an image, too.
void RequestAndProvideImage(const SharedImageVideoProvider::ImageSpec& spec) {
EXPECT_CALL(*mock_provider_raw_, MockRequestImage()).Times(1);
- provider_->RequestImage(SaveImageRecordCB(), spec, texture_owner_);
+ provider_->RequestImage(SaveImageRecordCB(), spec);
base::RunLoop().RunUntilIdle();
Mock::VerifyAndClearExpectations(mock_provider_raw_);
mock_provider_raw_->ProvideOneRequestedImage();
@@ -155,7 +154,7 @@ TEST_F(PooledSharedImageVideoProviderTest, RequestImageReusesReturnedImages) {
// Shouldn't call MockRequestImage a third time.
EXPECT_CALL(*mock_provider_raw_, MockRequestImage()).Times(0);
- provider_->RequestImage(SaveImageRecordCB(), spec, texture_owner_);
+ provider_->RequestImage(SaveImageRecordCB(), spec);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(image_records_.size(), 2u);
}
@@ -164,7 +163,7 @@ TEST_F(PooledSharedImageVideoProviderTest,
DeletingProviderWithOutstandingImagesDoesntCrash) {
// Destroying |provider_| with outstanding images shouldn't break anything.
SharedImageVideoProvider::ImageSpec spec(gfx::Size(1, 1), 0u);
- provider_->RequestImage(SaveImageRecordCB(), spec, texture_owner_);
+ provider_->RequestImage(SaveImageRecordCB(), spec);
base::RunLoop().RunUntilIdle();
provider_.reset();
base::RunLoop().RunUntilIdle();
@@ -229,8 +228,8 @@ TEST_F(PooledSharedImageVideoProviderTest, InFlightSpecChangeProvidesImage) {
// Request both images before providing either.
EXPECT_CALL(*mock_provider_raw_, MockRequestImage()).Times(2);
- provider_->RequestImage(SaveImageRecordCB(), spec_1, texture_owner_);
- provider_->RequestImage(SaveImageRecordCB(), spec_2, texture_owner_);
+ provider_->RequestImage(SaveImageRecordCB(), spec_1);
+ provider_->RequestImage(SaveImageRecordCB(), spec_2);
base::RunLoop().RunUntilIdle();
// Provide the |spec_1| image. Nothing should be released since it should
diff --git a/chromium/media/gpu/android/promotion_hint_aggregator_impl.h b/chromium/media/gpu/android/promotion_hint_aggregator_impl.h
index 9130800b34d..1d33c4cfa65 100644
--- a/chromium/media/gpu/android/promotion_hint_aggregator_impl.h
+++ b/chromium/media/gpu/android/promotion_hint_aggregator_impl.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_GPU_ANDROID_PROMOTION_HINT_AGGREGATOR_IMPL_H_
#define MEDIA_GPU_ANDROID_PROMOTION_HINT_AGGREGATOR_IMPL_H_
-#include <memory>
-
#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/media/gpu/android/shared_image_video_provider.h b/chromium/media/gpu/android/shared_image_video_provider.h
index ffbac1331a5..87fa7ec8d2c 100644
--- a/chromium/media/gpu/android/shared_image_video_provider.h
+++ b/chromium/media/gpu/android/shared_image_video_provider.h
@@ -94,9 +94,7 @@ class MEDIA_GPU_EXPORT SharedImageVideoProvider {
// Call |cb| when we have a shared image that matches |spec|. We may call
// |cb| back before returning, or we might post it for later.
- virtual void RequestImage(ImageReadyCB cb,
- const ImageSpec& spec,
- scoped_refptr<gpu::TextureOwner> texture_owner) = 0;
+ virtual void RequestImage(ImageReadyCB cb, const ImageSpec& spec) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(SharedImageVideoProvider);
diff --git a/chromium/media/gpu/android/surface_chooser_helper.cc b/chromium/media/gpu/android/surface_chooser_helper.cc
index 2c858d090fb..36613fd5f51 100644
--- a/chromium/media/gpu/android/surface_chooser_helper.cc
+++ b/chromium/media/gpu/android/surface_chooser_helper.cc
@@ -100,7 +100,7 @@ void SurfaceChooserHelper::SetIsPersistentVideo(bool is_persistent_video) {
}
void SurfaceChooserHelper::UpdateChooserState(
- base::Optional<AndroidOverlayFactoryCB> new_factory) {
+ absl::optional<AndroidOverlayFactoryCB> new_factory) {
surface_chooser_->UpdateState(std::move(new_factory), surface_chooser_state_);
}
@@ -144,7 +144,7 @@ void SurfaceChooserHelper::NotifyPromotionHintAndUpdateChooser(
if (update_state) {
most_recent_chooser_retry_ = now;
- UpdateChooserState(base::Optional<AndroidOverlayFactoryCB>());
+ UpdateChooserState(absl::optional<AndroidOverlayFactoryCB>());
}
}
diff --git a/chromium/media/gpu/android/surface_chooser_helper.h b/chromium/media/gpu/android/surface_chooser_helper.h
index a019d031e15..8f1f0ed407f 100644
--- a/chromium/media/gpu/android/surface_chooser_helper.h
+++ b/chromium/media/gpu/android/surface_chooser_helper.h
@@ -85,7 +85,7 @@ class MEDIA_GPU_EXPORT SurfaceChooserHelper {
void SetIsPersistentVideo(bool is_persistent_video);
// Update the chooser state using the given factory.
- void UpdateChooserState(base::Optional<AndroidOverlayFactoryCB> new_factory);
+ void UpdateChooserState(absl::optional<AndroidOverlayFactoryCB> new_factory);
// Notify us about a promotion hint. This will update the chooser state
// if needed.
diff --git a/chromium/media/gpu/android/surface_chooser_helper_unittest.cc b/chromium/media/gpu/android/surface_chooser_helper_unittest.cc
index 353e9b0bfde..adb33255466 100644
--- a/chromium/media/gpu/android/surface_chooser_helper_unittest.cc
+++ b/chromium/media/gpu/android/surface_chooser_helper_unittest.cc
@@ -52,7 +52,7 @@ class SurfaceChooserHelperTest : public testing::Test {
// Convenience function.
void UpdateChooserState() {
EXPECT_CALL(*chooser_, MockUpdateState());
- helper_->UpdateChooserState(base::Optional<AndroidOverlayFactoryCB>());
+ helper_->UpdateChooserState(absl::optional<AndroidOverlayFactoryCB>());
}
base::SimpleTestTickClock tick_clock_;
diff --git a/chromium/media/gpu/android/video_frame_factory.h b/chromium/media/gpu/android/video_frame_factory.h
index afc58cfe651..81c83bc2637 100644
--- a/chromium/media/gpu/android/video_frame_factory.h
+++ b/chromium/media/gpu/android/video_frame_factory.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_
-#define MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_
+#ifndef MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_H_
+#define MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_H_
#include <memory>
@@ -73,4 +73,4 @@ class MEDIA_GPU_EXPORT VideoFrameFactory {
} // namespace media
-#endif // MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_
+#endif // MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_H_
diff --git a/chromium/media/gpu/android/video_frame_factory_impl.cc b/chromium/media/gpu/android/video_frame_factory_impl.cc
index 8be7a01fcb7..aae48f924ab 100644
--- a/chromium/media/gpu/android/video_frame_factory_impl.cc
+++ b/chromium/media/gpu/android/video_frame_factory_impl.cc
@@ -38,10 +38,10 @@ namespace {
// (http://crbug.com/582170). This texture copy can be avoided if
// AImageReader/AHardwareBuffer is supported and AImageReader
// max size is not limited to 1 (crbug.com/1091945).
-base::Optional<VideoFrameMetadata::CopyMode> GetVideoFrameCopyMode(
+absl::optional<VideoFrameMetadata::CopyMode> GetVideoFrameCopyMode(
bool enable_threaded_texture_mailboxes) {
if (!enable_threaded_texture_mailboxes)
- return base::nullopt;
+ return absl::nullopt;
return features::IsWebViewZeroCopyVideoEnabled()
? VideoFrameMetadata::CopyMode::kCopyMailboxesOnly
@@ -50,7 +50,7 @@ base::Optional<VideoFrameMetadata::CopyMode> GetVideoFrameCopyMode(
gpu::TextureOwner::Mode GetTextureOwnerMode(
VideoFrameFactory::OverlayMode overlay_mode,
- const base::Optional<VideoFrameMetadata::CopyMode>& copy_mode) {
+ const absl::optional<VideoFrameMetadata::CopyMode>& copy_mode) {
if (copy_mode == VideoFrameMetadata::kCopyMailboxesOnly) {
DCHECK(features::IsWebViewZeroCopyVideoEnabled());
return gpu::TextureOwner::Mode::kAImageReaderInsecureMultithreaded;
@@ -79,7 +79,7 @@ gpu::TextureOwner::Mode GetTextureOwnerMode(
static void AllocateTextureOwnerOnGpuThread(
VideoFrameFactory::InitCB init_cb,
VideoFrameFactory::OverlayMode overlay_mode,
- const base::Optional<VideoFrameMetadata::CopyMode>& copy_mode,
+ const absl::optional<VideoFrameMetadata::CopyMode>& copy_mode,
scoped_refptr<gpu::SharedContextState> shared_context_state) {
if (!shared_context_state) {
std::move(init_cb).Run(nullptr);
@@ -88,7 +88,7 @@ static void AllocateTextureOwnerOnGpuThread(
std::move(init_cb).Run(gpu::TextureOwner::Create(
gpu::TextureOwner::CreateTexture(shared_context_state),
- GetTextureOwnerMode(overlay_mode, copy_mode)));
+ GetTextureOwnerMode(overlay_mode, copy_mode), shared_context_state));
}
} // namespace
@@ -202,8 +202,7 @@ void VideoFrameFactoryImpl::RequestImage(
ImageWithInfoReadyCB image_ready_cb) {
auto info_cb =
base::BindOnce(&VideoFrameFactoryImpl::CreateVideoFrame_OnFrameInfoReady,
- weak_factory_.GetWeakPtr(), std::move(image_ready_cb),
- codec_buffer_wait_coordinator_);
+ weak_factory_.GetWeakPtr(), std::move(image_ready_cb));
frame_info_helper_->GetFrameInfo(std::move(buffer_renderer),
std::move(info_cb));
@@ -211,7 +210,6 @@ void VideoFrameFactoryImpl::RequestImage(
void VideoFrameFactoryImpl::CreateVideoFrame_OnFrameInfoReady(
ImageWithInfoReadyCB image_ready_cb,
- scoped_refptr<CodecBufferWaitCoordinator> codec_buffer_wait_coordinator,
std::unique_ptr<CodecOutputBufferRenderer> output_buffer_renderer,
FrameInfoHelper::FrameInfo frame_info) {
// If we don't have output buffer here we can't rely on reply from
@@ -237,11 +235,7 @@ void VideoFrameFactoryImpl::CreateVideoFrame_OnFrameInfoReady(
auto cb = base::BindOnce(std::move(image_ready_cb),
std::move(output_buffer_renderer), frame_info);
-
- auto texture_owner = codec_buffer_wait_coordinator
- ? codec_buffer_wait_coordinator->texture_owner()
- : nullptr;
- image_provider_->RequestImage(std::move(cb), image_spec_, texture_owner);
+ image_provider_->RequestImage(std::move(cb), image_spec_);
}
// static
@@ -254,7 +248,7 @@ void VideoFrameFactoryImpl::CreateVideoFrame_OnImageReady(
PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb,
VideoPixelFormat pixel_format,
OverlayMode overlay_mode,
- const base::Optional<VideoFrameMetadata::CopyMode>& copy_mode,
+ const absl::optional<VideoFrameMetadata::CopyMode>& copy_mode,
scoped_refptr<base::SequencedTaskRunner> gpu_task_runner,
std::unique_ptr<CodecOutputBufferRenderer> output_buffer_renderer,
FrameInfoHelper::FrameInfo frame_info,
diff --git a/chromium/media/gpu/android/video_frame_factory_impl.h b/chromium/media/gpu/android/video_frame_factory_impl.h
index 6bf6ca6a5fc..ad0a0c722a5 100644
--- a/chromium/media/gpu/android/video_frame_factory_impl.h
+++ b/chromium/media/gpu/android/video_frame_factory_impl.h
@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_IMPL_
-#define MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_IMPL_
+#ifndef MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_IMPL_H_
+#define MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_IMPL_H_
#include <memory>
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "gpu/config/gpu_preferences.h"
#include "media/base/video_frame.h"
@@ -20,6 +19,7 @@
#include "media/gpu/android/shared_image_video_provider.h"
#include "media/gpu/android/video_frame_factory.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gl/gl_bindings.h"
namespace media {
@@ -94,7 +94,7 @@ class MEDIA_GPU_EXPORT VideoFrameFactoryImpl : public VideoFrameFactory {
PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb,
VideoPixelFormat pixel_format,
OverlayMode overlay_mode,
- const base::Optional<VideoFrameMetadata::CopyMode>& copy_mode,
+ const absl::optional<VideoFrameMetadata::CopyMode>& copy_mode,
scoped_refptr<base::SequencedTaskRunner> gpu_task_runner,
std::unique_ptr<CodecOutputBufferRenderer> output_buffer_renderer,
FrameInfoHelper::FrameInfo frame_info,
@@ -102,7 +102,6 @@ class MEDIA_GPU_EXPORT VideoFrameFactoryImpl : public VideoFrameFactory {
void CreateVideoFrame_OnFrameInfoReady(
ImageWithInfoReadyCB image_ready_cb,
- scoped_refptr<CodecBufferWaitCoordinator> codec_buffer_wait_coordinator,
std::unique_ptr<CodecOutputBufferRenderer> output_buffer_renderer,
FrameInfoHelper::FrameInfo frame_info);
@@ -117,7 +116,7 @@ class MEDIA_GPU_EXPORT VideoFrameFactoryImpl : public VideoFrameFactory {
OverlayMode overlay_mode_ = OverlayMode::kDontRequestPromotionHints;
// Indicates how video frame needs to be copied when required.
- base::Optional<VideoFrameMetadata::CopyMode> copy_mode_;
+ absl::optional<VideoFrameMetadata::CopyMode> copy_mode_;
// Current group that new CodecImages should belong to. Do not use this on
// our thread; everything must be posted to the gpu main thread, including
@@ -141,4 +140,4 @@ class MEDIA_GPU_EXPORT VideoFrameFactoryImpl : public VideoFrameFactory {
} // namespace media
-#endif // MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_IMPL_
+#endif // MEDIA_GPU_ANDROID_VIDEO_FRAME_FACTORY_IMPL_H_
diff --git a/chromium/media/gpu/av1_decoder.h b/chromium/media/gpu/av1_decoder.h
index 02bee3a1ec2..5c0391e1e81 100644
--- a/chromium/media/gpu/av1_decoder.h
+++ b/chromium/media/gpu/av1_decoder.h
@@ -19,7 +19,7 @@
// For libgav1::RefCountedBufferPtr.
#include "third_party/libgav1/src/src/buffer_pool.h"
-// For libgav1::ObuSequenceHeader. base::Optional demands ObuSequenceHeader to
+// For libgav1::ObuSequenceHeader. absl::optional demands ObuSequenceHeader to
// fulfill std::is_trivially_constructible if it is forward-declared. But
// ObuSequenceHeader doesn't.
#include "third_party/libgav1/src/src/obu_parser.h"
@@ -138,8 +138,8 @@ class MEDIA_GPU_EXPORT AV1Decoder : public AcceleratedVideoDecoder {
const std::unique_ptr<AV1Accelerator> accelerator_;
AV1ReferenceFrameVector ref_frames_;
- base::Optional<libgav1::ObuSequenceHeader> current_sequence_header_;
- base::Optional<libgav1::ObuFrameHeader> current_frame_header_;
+ absl::optional<libgav1::ObuSequenceHeader> current_sequence_header_;
+ absl::optional<libgav1::ObuFrameHeader> current_frame_header_;
libgav1::RefCountedBufferPtr current_frame_;
gfx::Rect visible_rect_;
diff --git a/chromium/media/gpu/av1_picture.h b/chromium/media/gpu/av1_picture.h
index 505c9cd4670..d770f9f3f37 100644
--- a/chromium/media/gpu/av1_picture.h
+++ b/chromium/media/gpu/av1_picture.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_GPU_AV1_PICTURE_H_
#define MEDIA_GPU_AV1_PICTURE_H_
-#include <memory>
-
#include "media/gpu/codec_picture.h"
#include "media/gpu/media_gpu_export.h"
#include "third_party/libgav1/src/src/utils/types.h"
diff --git a/chromium/media/gpu/chromeos/chromeos_video_decoder_factory.cc b/chromium/media/gpu/chromeos/chromeos_video_decoder_factory.cc
index 262c36fbbfe..9721219921a 100644
--- a/chromium/media/gpu/chromeos/chromeos_video_decoder_factory.cc
+++ b/chromium/media/gpu/chromeos/chromeos_video_decoder_factory.cc
@@ -7,6 +7,8 @@
#include <utility>
#include "base/sequenced_task_runner.h"
+#include "gpu/config/gpu_driver_bug_workarounds.h"
+#include "gpu/config/gpu_preferences.h"
#include "media/base/video_decoder.h"
#include "media/gpu/buildflags.h"
#include "media/gpu/chromeos/mailbox_video_frame_converter.h"
@@ -27,12 +29,34 @@ namespace media {
SupportedVideoDecoderConfigs ChromeosVideoDecoderFactory::GetSupportedConfigs(
const gpu::GpuDriverBugWorkarounds& workarounds) {
#if BUILDFLAG(USE_VAAPI)
- return VaapiVideoDecoder::GetSupportedConfigs(workarounds);
+ auto configs = VaapiVideoDecoder::GetSupportedConfigs();
#elif BUILDFLAG(USE_V4L2_CODEC)
- return V4L2VideoDecoder::GetSupportedConfigs();
+ auto configs = V4L2VideoDecoder::GetSupportedConfigs();
#endif
-}
+ if (workarounds.disable_accelerated_vp8_decode) {
+ base::EraseIf(configs, [](const auto& config) {
+ return config.profile_min >= VP8PROFILE_MIN &&
+ config.profile_max <= VP8PROFILE_MAX;
+ });
+ }
+
+ if (workarounds.disable_accelerated_vp9_decode) {
+ base::EraseIf(configs, [](const auto& config) {
+ return config.profile_min >= VP9PROFILE_PROFILE0 &&
+ config.profile_max <= VP9PROFILE_PROFILE0;
+ });
+ }
+
+ if (workarounds.disable_accelerated_vp9_profile2_decode) {
+ base::EraseIf(configs, [](const auto& config) {
+ return config.profile_min >= VP9PROFILE_PROFILE2 &&
+ config.profile_max <= VP9PROFILE_PROFILE2;
+ });
+ }
+
+ return configs;
+}
// static
std::unique_ptr<VideoDecoder> ChromeosVideoDecoderFactory::Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
diff --git a/chromium/media/gpu/chromeos/dmabuf_video_frame_pool.h b/chromium/media/gpu/chromeos/dmabuf_video_frame_pool.h
index b874b62005f..aff3c945182 100644
--- a/chromium/media/gpu/chromeos/dmabuf_video_frame_pool.h
+++ b/chromium/media/gpu/chromeos/dmabuf_video_frame_pool.h
@@ -6,12 +6,12 @@
#define MEDIA_GPU_CHROMEOS_DMABUF_VIDEO_FRAME_POOL_H_
#include "base/memory/scoped_refptr.h"
-#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "media/base/video_frame.h"
#include "media/gpu/chromeos/fourcc.h"
#include "media/gpu/chromeos/gpu_buffer_layout.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -42,7 +42,7 @@ class MEDIA_GPU_EXPORT DmabufVideoFramePool {
// Sets the parameters of allocating frames and the maximum number of frames
// which can be allocated. Returns a valid GpuBufferLayout if VideoFrame
// will be created by GetFrame().
- virtual base::Optional<GpuBufferLayout> Initialize(
+ virtual absl::optional<GpuBufferLayout> Initialize(
const Fourcc& fourcc,
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
diff --git a/chromium/media/gpu/chromeos/fourcc.cc b/chromium/media/gpu/chromeos/fourcc.cc
index af87c3fd762..bc68962308d 100644
--- a/chromium/media/gpu/chromeos/fourcc.cc
+++ b/chromium/media/gpu/chromeos/fourcc.cc
@@ -6,7 +6,6 @@
#include "base/logging.h"
#include "base/notreached.h"
-#include "base/strings/stringprintf.h"
#include "media/gpu/macros.h"
#if BUILDFLAG(USE_V4L2_CODEC)
@@ -24,7 +23,7 @@ Fourcc::~Fourcc() = default;
Fourcc& Fourcc::operator=(const Fourcc& other) = default;
// static
-base::Optional<Fourcc> Fourcc::FromUint32(uint32_t fourcc) {
+absl::optional<Fourcc> Fourcc::FromUint32(uint32_t fourcc) {
switch (fourcc) {
case AR24:
case AB24:
@@ -47,11 +46,11 @@ base::Optional<Fourcc> Fourcc::FromUint32(uint32_t fourcc) {
return Fourcc(static_cast<Value>(fourcc));
}
DVLOGF(3) << "Unmapped fourcc: " << FourccToString(fourcc);
- return base::nullopt;
+ return absl::nullopt;
}
// static
-base::Optional<Fourcc> Fourcc::FromVideoPixelFormat(
+absl::optional<Fourcc> Fourcc::FromVideoPixelFormat(
VideoPixelFormat pixel_format,
bool single_planar) {
if (single_planar) {
@@ -147,7 +146,7 @@ base::Optional<Fourcc> Fourcc::FromVideoPixelFormat(
}
DVLOGF(3) << "Unmapped " << VideoPixelFormatToString(pixel_format) << " for "
<< (single_planar ? "single-planar" : "multi-planar");
- return base::nullopt;
+ return absl::nullopt;
}
VideoPixelFormat Fourcc::ToVideoPixelFormat() const {
@@ -200,7 +199,7 @@ VideoPixelFormat Fourcc::ToVideoPixelFormat() const {
#if BUILDFLAG(USE_V4L2_CODEC)
// static
-base::Optional<Fourcc> Fourcc::FromV4L2PixFmt(uint32_t v4l2_pix_fmt) {
+absl::optional<Fourcc> Fourcc::FromV4L2PixFmt(uint32_t v4l2_pix_fmt) {
// We can do that because we adopt the same internal definition of Fourcc as
// V4L2.
return FromUint32(v4l2_pix_fmt);
@@ -215,7 +214,7 @@ uint32_t Fourcc::ToV4L2PixFmt() const {
#if BUILDFLAG(USE_VAAPI)
// static
-base::Optional<Fourcc> Fourcc::FromVAFourCC(uint32_t va_fourcc) {
+absl::optional<Fourcc> Fourcc::FromVAFourCC(uint32_t va_fourcc) {
switch (va_fourcc) {
case VA_FOURCC_I420:
return Fourcc(YU12);
@@ -241,10 +240,10 @@ base::Optional<Fourcc> Fourcc::FromVAFourCC(uint32_t va_fourcc) {
return Fourcc(P010);
}
DVLOGF(3) << "Unmapped VAFourCC: " << FourccToString(va_fourcc);
- return base::nullopt;
+ return absl::nullopt;
}
-base::Optional<uint32_t> Fourcc::ToVAFourCC() const {
+absl::optional<uint32_t> Fourcc::ToVAFourCC() const {
switch (value_) {
case YU12:
return VA_FOURCC_I420;
@@ -278,15 +277,15 @@ base::Optional<uint32_t> Fourcc::ToVAFourCC() const {
// VAAPI does not know about these formats, so signal this by returning
// nullopt.
DVLOGF(3) << "Fourcc not convertible to VaFourCC: " << ToString();
- return base::nullopt;
+ return absl::nullopt;
}
NOTREACHED() << "Unmapped Fourcc: " << ToString();
- return base::nullopt;
+ return absl::nullopt;
}
#endif // BUILDFLAG(USE_VAAPI)
-base::Optional<Fourcc> Fourcc::ToSinglePlanar() const {
+absl::optional<Fourcc> Fourcc::ToSinglePlanar() const {
switch (value_) {
case AR24:
case AB24:
@@ -311,7 +310,7 @@ base::Optional<Fourcc> Fourcc::ToSinglePlanar() const {
case YM16:
case MT21:
case MM21:
- return base::nullopt;
+ return absl::nullopt;
}
}
diff --git a/chromium/media/gpu/chromeos/fourcc.h b/chromium/media/gpu/chromeos/fourcc.h
index f9e5d691174..560305c70ef 100644
--- a/chromium/media/gpu/chromeos/fourcc.h
+++ b/chromium/media/gpu/chromeos/fourcc.h
@@ -8,10 +8,10 @@
#include <stdint.h>
#include <string>
-#include "base/optional.h"
#include "media/base/video_types.h"
#include "media/gpu/buildflags.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -124,24 +124,24 @@ class MEDIA_GPU_EXPORT Fourcc {
// Builds a Fourcc from a given fourcc code. This will return a valid
// Fourcc if the argument is part of the |Value| enum, or nullopt otherwise.
- static base::Optional<Fourcc> FromUint32(uint32_t fourcc);
+ static absl::optional<Fourcc> FromUint32(uint32_t fourcc);
// Converts a VideoPixelFormat to Fourcc.
// Returns nullopt for invalid input.
// Note that a VideoPixelFormat may have two Fourcc counterparts. Caller has
// to specify if it is for single-planar or multi-planar format.
- static base::Optional<Fourcc> FromVideoPixelFormat(
+ static absl::optional<Fourcc> FromVideoPixelFormat(
VideoPixelFormat pixel_format,
bool single_planar = true);
#if BUILDFLAG(USE_V4L2_CODEC)
// Converts a V4L2PixFmt to Fourcc.
// Returns nullopt for invalid input.
- static base::Optional<Fourcc> FromV4L2PixFmt(uint32_t v4l2_pix_fmt);
+ static absl::optional<Fourcc> FromV4L2PixFmt(uint32_t v4l2_pix_fmt);
#endif // BUILDFLAG(USE_V4L2_CODEC)
#if BUILDFLAG(USE_VAAPI)
// Converts a VAFourCC to Fourcc.
// Returns nullopt for invalid input.
- static base::Optional<Fourcc> FromVAFourCC(uint32_t va_fourcc);
+ static absl::optional<Fourcc> FromVAFourCC(uint32_t va_fourcc);
#endif // BUILDFLAG(USE_VAAPI)
// Value getters:
@@ -156,12 +156,12 @@ class MEDIA_GPU_EXPORT Fourcc {
#if BUILDFLAG(USE_VAAPI)
// Returns the VAFourCC counterpart of the value.
// Returns nullopt if no mapping is found.
- base::Optional<uint32_t> ToVAFourCC() const;
+ absl::optional<uint32_t> ToVAFourCC() const;
#endif // BUILDFLAG(USE_VAAPI)
// Returns the single-planar Fourcc of the value. If value is a single-planar,
// returns the same Fourcc. Returns nullopt if no mapping is found.
- base::Optional<Fourcc> ToSinglePlanar() const;
+ absl::optional<Fourcc> ToSinglePlanar() const;
// Returns whether |value_| is multi planar format.
bool IsMultiPlanar() const;
diff --git a/chromium/media/gpu/chromeos/fourcc_unittests.cc b/chromium/media/gpu/chromeos/fourcc_unittests.cc
index d59b317ee0b..4ee99544c68 100644
--- a/chromium/media/gpu/chromeos/fourcc_unittests.cc
+++ b/chromium/media/gpu/chromeos/fourcc_unittests.cc
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/optional.h"
#include "media/gpu/chromeos/fourcc.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "media/gpu/buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -21,8 +21,8 @@ namespace media {
// Checks that converting a V4L2 pixel format to Fourcc and back to V4L2
// yields the same format as the original one.
static void CheckFromV4L2PixFmtAndBack(uint32_t fmt) {
- base::Optional<Fourcc> fourcc = Fourcc::FromV4L2PixFmt(fmt);
- EXPECT_NE(fourcc, base::nullopt);
+ absl::optional<Fourcc> fourcc = Fourcc::FromV4L2PixFmt(fmt);
+ EXPECT_NE(fourcc, absl::nullopt);
EXPECT_EQ(fourcc->ToV4L2PixFmt(), fmt);
}
@@ -84,7 +84,7 @@ TEST(FourccTest, V4L2PixFmtToVideoPixelFormat) {
Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_RGB32)->ToVideoPixelFormat());
// Randomly pick an unmapped v4l2 fourcc.
- EXPECT_EQ(base::nullopt, Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_Z16));
+ EXPECT_EQ(absl::nullopt, Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_Z16));
}
TEST(FourccTest, VideoPixelFormatToV4L2PixFmt) {
@@ -115,10 +115,10 @@ TEST(FourccTest, VideoPixelFormatToV4L2PixFmt) {
// Checks that converting a VaFourCC to Fourcc and back to VaFourCC
// yields the same format as the original one.
static void CheckFromVAFourCCAndBack(uint32_t va_fourcc) {
- base::Optional<Fourcc> fourcc = Fourcc::FromVAFourCC(va_fourcc);
- EXPECT_NE(fourcc, base::nullopt);
- base::Optional<uint32_t> to_va_fourcc = fourcc->ToVAFourCC();
- EXPECT_NE(to_va_fourcc, base::nullopt);
+ absl::optional<Fourcc> fourcc = Fourcc::FromVAFourCC(va_fourcc);
+ EXPECT_NE(fourcc, absl::nullopt);
+ absl::optional<uint32_t> to_va_fourcc = fourcc->ToVAFourCC();
+ EXPECT_NE(to_va_fourcc, absl::nullopt);
EXPECT_EQ(*to_va_fourcc, va_fourcc);
}
diff --git a/chromium/media/gpu/chromeos/gpu_buffer_layout.cc b/chromium/media/gpu/chromeos/gpu_buffer_layout.cc
index d2adee82885..578884f536b 100644
--- a/chromium/media/gpu/chromeos/gpu_buffer_layout.cc
+++ b/chromium/media/gpu/chromeos/gpu_buffer_layout.cc
@@ -29,7 +29,7 @@ std::string VectorToString(const std::vector<T>& vec) {
} // namespace
// static
-base::Optional<GpuBufferLayout> GpuBufferLayout::Create(
+absl::optional<GpuBufferLayout> GpuBufferLayout::Create(
const Fourcc& fourcc,
const gfx::Size& size,
const std::vector<ColorPlaneLayout>& planes,
@@ -41,7 +41,7 @@ base::Optional<GpuBufferLayout> GpuBufferLayout::Create(
<< ", size: " << size.ToString()
<< ", planes: " << VectorToString(planes)
<< ", modifier: " << std::hex << modifier;
- return base::nullopt;
+ return absl::nullopt;
}
return GpuBufferLayout(fourcc, size, planes, modifier);
diff --git a/chromium/media/gpu/chromeos/gpu_buffer_layout.h b/chromium/media/gpu/chromeos/gpu_buffer_layout.h
index 06f52be9f31..833c1824b6f 100644
--- a/chromium/media/gpu/chromeos/gpu_buffer_layout.h
+++ b/chromium/media/gpu/chromeos/gpu_buffer_layout.h
@@ -9,17 +9,17 @@
#include <string>
#include <vector>
-#include "base/optional.h"
#include "media/base/color_plane_layout.h"
#include "media/gpu/chromeos/fourcc.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
class MEDIA_GPU_EXPORT GpuBufferLayout {
public:
- static base::Optional<GpuBufferLayout> Create(
+ static absl::optional<GpuBufferLayout> Create(
const Fourcc& fourcc,
const gfx::Size& size,
const std::vector<ColorPlaneLayout>& planes,
diff --git a/chromium/media/gpu/chromeos/image_processor.cc b/chromium/media/gpu/chromeos/image_processor.cc
index 6b3dccc35e6..b3408b243ed 100644
--- a/chromium/media/gpu/chromeos/image_processor.cc
+++ b/chromium/media/gpu/chromeos/image_processor.cc
@@ -131,7 +131,7 @@ bool ImageProcessor::Process(scoped_refptr<VideoFrame> input_frame,
// static
void ImageProcessor::OnProcessDoneThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<ImageProcessor>> weak_this,
+ absl::optional<base::WeakPtr<ImageProcessor>> weak_this,
int cb_index,
scoped_refptr<VideoFrame> frame) {
DVLOGF(4);
@@ -178,7 +178,7 @@ bool ImageProcessor::Process(scoped_refptr<VideoFrame> frame,
// static
void ImageProcessor::OnProcessLegacyDoneThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<ImageProcessor>> weak_this,
+ absl::optional<base::WeakPtr<ImageProcessor>> weak_this,
int cb_index,
size_t buffer_id,
scoped_refptr<VideoFrame> frame) {
diff --git a/chromium/media/gpu/chromeos/image_processor.h b/chromium/media/gpu/chromeos/image_processor.h
index ac62dbaf8cd..c64aebe384d 100644
--- a/chromium/media/gpu/chromeos/image_processor.h
+++ b/chromium/media/gpu/chromeos/image_processor.h
@@ -108,12 +108,12 @@ class MEDIA_GPU_EXPORT ImageProcessor {
// Callbacks of processing frames.
static void OnProcessDoneThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<ImageProcessor>> weak_this,
+ absl::optional<base::WeakPtr<ImageProcessor>> weak_this,
int cb_index,
scoped_refptr<VideoFrame> frame);
static void OnProcessLegacyDoneThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<ImageProcessor>> weak_this,
+ absl::optional<base::WeakPtr<ImageProcessor>> weak_this,
int cb_index,
size_t buffer_id,
scoped_refptr<VideoFrame> frame);
diff --git a/chromium/media/gpu/chromeos/image_processor_factory.h b/chromium/media/gpu/chromeos/image_processor_factory.h
index a81eddde318..0d29d87e80c 100644
--- a/chromium/media/gpu/chromeos/image_processor_factory.h
+++ b/chromium/media/gpu/chromeos/image_processor_factory.h
@@ -22,7 +22,7 @@ namespace media {
class MEDIA_GPU_EXPORT ImageProcessorFactory {
public:
// Callback to pick a valid format from given |candidates| formats.
- using PickFormatCB = base::RepeatingCallback<base::Optional<Fourcc>(
+ using PickFormatCB = base::RepeatingCallback<absl::optional<Fourcc>(
const std::vector<Fourcc>& /* candidates */)>;
// Factory method to create ImageProcessor.
diff --git a/chromium/media/gpu/chromeos/image_processor_with_pool.cc b/chromium/media/gpu/chromeos/image_processor_with_pool.cc
index 2c03db29ef3..bbd9c64b168 100644
--- a/chromium/media/gpu/chromeos/image_processor_with_pool.cc
+++ b/chromium/media/gpu/chromeos/image_processor_with_pool.cc
@@ -18,7 +18,7 @@ std::unique_ptr<ImageProcessorWithPool> ImageProcessorWithPool::Create(
size_t num_frames,
const scoped_refptr<base::SequencedTaskRunner> task_runner) {
const ImageProcessor::PortConfig& config = image_processor->output_config();
- base::Optional<GpuBufferLayout> layout = frame_pool->Initialize(
+ absl::optional<GpuBufferLayout> layout = frame_pool->Initialize(
config.fourcc, config.size, config.visible_rect, config.size, num_frames,
/*use_protected=*/false);
if (!layout || layout->size() != config.size) {
diff --git a/chromium/media/gpu/chromeos/libyuv_image_processor_backend.cc b/chromium/media/gpu/chromeos/libyuv_image_processor_backend.cc
index 1c7566c7dcf..4990c87b982 100644
--- a/chromium/media/gpu/chromeos/libyuv_image_processor_backend.cc
+++ b/chromium/media/gpu/chromeos/libyuv_image_processor_backend.cc
@@ -4,6 +4,7 @@
#include "media/gpu/chromeos/libyuv_image_processor_backend.h"
+#include "base/containers/contains.h"
#include "base/memory/ptr_util.h"
#include "media/gpu/chromeos/fourcc.h"
#include "media/gpu/macros.h"
diff --git a/chromium/media/gpu/chromeos/mailbox_video_frame_converter.cc b/chromium/media/gpu/chromeos/mailbox_video_frame_converter.cc
index c7ce5363d4b..afa3bf56b76 100644
--- a/chromium/media/gpu/chromeos/mailbox_video_frame_converter.cc
+++ b/chromium/media/gpu/chromeos/mailbox_video_frame_converter.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/containers/contains.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
@@ -237,6 +238,7 @@ void MailboxVideoFrameConverter::WrapMailboxAndVideoFrameAndOutput(
GetRectSizeFromOrigin(frame->visible_rect()), frame->visible_rect(),
frame->natural_size(), frame->timestamp());
mailbox_frame->set_color_space(frame->ColorSpace());
+ mailbox_frame->set_hdr_metadata(frame->hdr_metadata());
mailbox_frame->set_metadata(frame->metadata());
mailbox_frame->metadata().read_lock_fences_enabled = true;
@@ -355,8 +357,9 @@ bool MailboxVideoFrameConverter::GenerateSharedImageOnGPUThread(
const bool success = shared_image_stub->CreateSharedImage(
mailbox, gpu::kPlatformVideoFramePoolClientId,
std::move(gpu_memory_buffer_handle), *buffer_format,
- gpu::kNullSurfaceHandle, shared_image_size, video_frame->ColorSpace(),
- kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, shared_image_usage);
+ gfx::BufferPlane::DEFAULT, gpu::kNullSurfaceHandle, shared_image_size,
+ video_frame->ColorSpace(), kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType,
+ shared_image_usage);
if (!success) {
OnError(FROM_HERE, "Failed to create shared image.");
return false;
diff --git a/chromium/media/gpu/chromeos/platform_video_frame_pool.cc b/chromium/media/gpu/chromeos/platform_video_frame_pool.cc
index 401aa08aa93..db9a3086fe2 100644
--- a/chromium/media/gpu/chromeos/platform_video_frame_pool.cc
+++ b/chromium/media/gpu/chromeos/platform_video_frame_pool.cc
@@ -7,13 +7,13 @@
#include <utility>
#include "base/logging.h"
-#include "base/optional.h"
#include "base/task/post_task.h"
#include "media/base/video_util.h"
#include "media/gpu/chromeos/gpu_buffer_layout.h"
#include "media/gpu/chromeos/platform_video_frame_utils.h"
#include "media/gpu/macros.h"
#include "media/media_buildflags.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -138,7 +138,7 @@ scoped_refptr<VideoFrame> PlatformVideoFramePool::GetFrame() {
return wrapped_frame;
}
-base::Optional<GpuBufferLayout> PlatformVideoFramePool::Initialize(
+absl::optional<GpuBufferLayout> PlatformVideoFramePool::Initialize(
const Fourcc& fourcc,
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
@@ -152,13 +152,13 @@ base::Optional<GpuBufferLayout> PlatformVideoFramePool::Initialize(
VideoPixelFormat format = fourcc.ToVideoPixelFormat();
if (format == PIXEL_FORMAT_UNKNOWN) {
VLOGF(1) << "Unsupported fourcc: " << fourcc.ToString();
- return base::nullopt;
+ return absl::nullopt;
}
#if !BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
if (use_protected) {
VLOGF(1) << "Protected buffers unsupported";
- return base::nullopt;
+ return absl::nullopt;
}
#endif
@@ -186,7 +186,7 @@ base::Optional<GpuBufferLayout> PlatformVideoFramePool::Initialize(
if (!frame) {
VLOGF(1) << "Failed to create video frame " << format << " (fourcc "
<< fourcc.ToString() << ")";
- return base::nullopt;
+ return absl::nullopt;
}
frame_layout_ = GpuBufferLayout::Create(fourcc, frame->coded_size(),
frame->layout().planes(),
@@ -243,7 +243,7 @@ void PlatformVideoFramePool::NotifyWhenFrameAvailable(base::OnceClosure cb) {
// static
void PlatformVideoFramePool::OnFrameReleasedThunk(
- base::Optional<base::WeakPtr<PlatformVideoFramePool>> pool,
+ absl::optional<base::WeakPtr<PlatformVideoFramePool>> pool,
scoped_refptr<base::SequencedTaskRunner> task_runner,
scoped_refptr<VideoFrame> origin_frame) {
DCHECK(pool);
diff --git a/chromium/media/gpu/chromeos/platform_video_frame_pool.h b/chromium/media/gpu/chromeos/platform_video_frame_pool.h
index ed8c875baa5..5e1391aa1a1 100644
--- a/chromium/media/gpu/chromeos/platform_video_frame_pool.h
+++ b/chromium/media/gpu/chromeos/platform_video_frame_pool.h
@@ -13,7 +13,6 @@
#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
@@ -21,6 +20,7 @@
#include "media/base/video_types.h"
#include "media/gpu/chromeos/dmabuf_video_frame_pool.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/gpu_memory_buffer.h"
namespace gpu {
@@ -48,7 +48,7 @@ class MEDIA_GPU_EXPORT PlatformVideoFramePool : public DmabufVideoFramePool {
static gfx::GpuMemoryBufferId GetGpuMemoryBufferId(const VideoFrame& frame);
// DmabufVideoFramePool implementation.
- base::Optional<GpuBufferLayout> Initialize(const Fourcc& fourcc,
+ absl::optional<GpuBufferLayout> Initialize(const Fourcc& fourcc,
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
@@ -71,10 +71,10 @@ class MEDIA_GPU_EXPORT PlatformVideoFramePool : public DmabufVideoFramePool {
// Thunk to post OnFrameReleased() to |task_runner|.
// Because this thunk may be called in any thread, We don't want to
- // dereference WeakPtr. Therefore we wrap the WeakPtr by base::Optional to
+ // dereference WeakPtr. Therefore we wrap the WeakPtr by absl::optional to
// avoid the task runner defererencing the WeakPtr.
static void OnFrameReleasedThunk(
- base::Optional<base::WeakPtr<PlatformVideoFramePool>> pool,
+ absl::optional<base::WeakPtr<PlatformVideoFramePool>> pool,
scoped_refptr<base::SequencedTaskRunner> task_runner,
scoped_refptr<VideoFrame> origin_frame);
// Called when a wrapped frame gets destroyed.
@@ -116,7 +116,7 @@ class MEDIA_GPU_EXPORT PlatformVideoFramePool : public DmabufVideoFramePool {
// The arguments of current frame. We allocate new frames only if a pixel
// format or size in |frame_layout_| is changed. When GetFrame() is
// called, we update |visible_rect_| and |natural_size_| of wrapped frames.
- base::Optional<GpuBufferLayout> frame_layout_ GUARDED_BY(lock_);
+ absl::optional<GpuBufferLayout> frame_layout_ GUARDED_BY(lock_);
gfx::Rect visible_rect_ GUARDED_BY(lock_);
gfx::Size natural_size_ GUARDED_BY(lock_);
diff --git a/chromium/media/gpu/chromeos/platform_video_frame_pool_unittest.cc b/chromium/media/gpu/chromeos/platform_video_frame_pool_unittest.cc
index fbb9f6589ac..d6d5dc24854 100644
--- a/chromium/media/gpu/chromeos/platform_video_frame_pool_unittest.cc
+++ b/chromium/media/gpu/chromeos/platform_video_frame_pool_unittest.cc
@@ -32,7 +32,7 @@ scoped_refptr<VideoFrame> CreateGpuMemoryBufferVideoFrame(
const gfx::Size& natural_size,
bool use_protected,
base::TimeDelta timestamp) {
- base::Optional<gfx::BufferFormat> gfx_format =
+ absl::optional<gfx::BufferFormat> gfx_format =
VideoPixelFormatToGfxBufferFormat(format);
DCHECK(gfx_format);
const gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes] = {};
@@ -96,7 +96,7 @@ class PlatformVideoFramePoolTest
base::test::TaskEnvironment task_environment_;
std::unique_ptr<PlatformVideoFramePool> pool_;
- base::Optional<GpuBufferLayout> layout_;
+ absl::optional<GpuBufferLayout> layout_;
gfx::Rect visible_rect_;
gfx::Size natural_size_;
};
diff --git a/chromium/media/gpu/chromeos/platform_video_frame_utils.cc b/chromium/media/gpu/chromeos/platform_video_frame_utils.cc
index 24dd4216171..7d79759066c 100644
--- a/chromium/media/gpu/chromeos/platform_video_frame_utils.cc
+++ b/chromium/media/gpu/chromeos/platform_video_frame_utils.cc
@@ -16,6 +16,7 @@
#include "base/files/scoped_file.h"
#include "base/no_destructor.h"
#include "base/posix/eintr_wrapper.h"
+#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "gpu/ipc/common/gpu_client_ids.h"
@@ -253,7 +254,7 @@ scoped_refptr<VideoFrame> CreatePlatformVideoFrame(
return frame;
}
-base::Optional<VideoFrameLayout> GetPlatformVideoFrameLayout(
+absl::optional<VideoFrameLayout> GetPlatformVideoFrameLayout(
gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory,
VideoPixelFormat pixel_format,
const gfx::Size& coded_size,
@@ -263,8 +264,8 @@ base::Optional<VideoFrameLayout> GetPlatformVideoFrameLayout(
auto frame = CreatePlatformVideoFrame(
gpu_memory_buffer_factory, pixel_format, coded_size,
gfx::Rect(coded_size), coded_size, base::TimeDelta(), buffer_usage);
- return frame ? base::make_optional<VideoFrameLayout>(frame->layout())
- : base::nullopt;
+ return frame ? absl::make_optional<VideoFrameLayout>(frame->layout())
+ : absl::nullopt;
}
gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferHandle(
diff --git a/chromium/media/gpu/chromeos/platform_video_frame_utils.h b/chromium/media/gpu/chromeos/platform_video_frame_utils.h
index f1bd0d85aef..b3320540245 100644
--- a/chromium/media/gpu/chromeos/platform_video_frame_utils.h
+++ b/chromium/media/gpu/chromeos/platform_video_frame_utils.h
@@ -66,7 +66,7 @@ MEDIA_GPU_EXPORT scoped_refptr<VideoFrame> CreatePlatformVideoFrame(
// encoding when the usage is VEA_READ_CAMERA_AND_CPU_READ_WRITE). It's
// safe to call this function concurrently from multiple threads (as long as
// either |gpu_memory_buffer_factory| is thread-safe or nullptr).
-MEDIA_GPU_EXPORT base::Optional<VideoFrameLayout> GetPlatformVideoFrameLayout(
+MEDIA_GPU_EXPORT absl::optional<VideoFrameLayout> GetPlatformVideoFrameLayout(
gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory,
VideoPixelFormat pixel_format,
const gfx::Size& coded_size,
diff --git a/chromium/media/gpu/chromeos/platform_video_frame_utils_unittest.cc b/chromium/media/gpu/chromeos/platform_video_frame_utils_unittest.cc
index ba698cb838d..32aae281a41 100644
--- a/chromium/media/gpu/chromeos/platform_video_frame_utils_unittest.cc
+++ b/chromium/media/gpu/chromeos/platform_video_frame_utils_unittest.cc
@@ -10,13 +10,12 @@
#include <utility>
#include <vector>
+#include "base/containers/contains.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
-#include "base/optional.h"
-#include "base/stl_util.h"
#include "base/time/time.h"
#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
#include "media/base/color_plane_layout.h"
@@ -26,6 +25,7 @@
#include "media/base/video_types.h"
#include "media/video/fake_gpu_memory_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -42,7 +42,7 @@ scoped_refptr<VideoFrame> CreateMockDmaBufVideoFrame(
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size) {
- const base::Optional<VideoFrameLayout> layout =
+ const absl::optional<VideoFrameLayout> layout =
VideoFrameLayout::Create(pixel_format, coded_size);
if (!layout) {
LOG(ERROR) << "Failed to create video frame layout";
@@ -129,7 +129,7 @@ TEST(PlatformVideoFrameUtilsTest, CreateNativePixmapDmaBuf) {
constexpr VideoPixelFormat kPixelFormat = PIXEL_FORMAT_NV12;
constexpr gfx::Size kCodedSize(320, 240);
- const base::Optional<gfx::BufferFormat> gfx_format =
+ const absl::optional<gfx::BufferFormat> gfx_format =
VideoPixelFormatToGfxBufferFormat(kPixelFormat);
ASSERT_TRUE(gfx_format) << "Invalid pixel format: " << kPixelFormat;
diff --git a/chromium/media/gpu/chromeos/vd_video_decode_accelerator.cc b/chromium/media/gpu/chromeos/vd_video_decode_accelerator.cc
index e582898f58c..32311997c2c 100644
--- a/chromium/media/gpu/chromeos/vd_video_decode_accelerator.cc
+++ b/chromium/media/gpu/chromeos/vd_video_decode_accelerator.cc
@@ -103,7 +103,7 @@ void VdVideoDecodeAccelerator::Destroy() {
// Because VdaVideoFramePool is blocked for this callback, we must call the
// callback before destroying.
if (notify_layout_changed_cb_)
- std::move(notify_layout_changed_cb_).Run(base::nullopt);
+ std::move(notify_layout_changed_cb_).Run(absl::nullopt);
client_ = nullptr;
vd_.reset();
@@ -209,7 +209,7 @@ void VdVideoDecodeAccelerator::OnFrameReady(scoped_refptr<VideoFrame> frame) {
DCHECK(frame);
DCHECK(client_);
- base::Optional<Picture> picture = GetPicture(*frame);
+ absl::optional<Picture> picture = GetPicture(*frame);
if (!picture) {
VLOGF(1) << "Failed to get picture.";
OnError(FROM_HERE, PLATFORM_FAILURE);
@@ -331,7 +331,7 @@ void VdVideoDecodeAccelerator::ImportBufferForPicture(
auto fourcc = Fourcc::FromVideoPixelFormat(pixel_format);
if (!fourcc) {
VLOGF(1) << "Failed to convert to Fourcc.";
- std::move(notify_layout_changed_cb_).Run(base::nullopt);
+ std::move(notify_layout_changed_cb_).Run(absl::nullopt);
return;
}
@@ -349,7 +349,7 @@ void VdVideoDecodeAccelerator::ImportBufferForPicture(
<< ", coded_size: " << coded_size_.ToString()
<< ", planes: " << VectorToString(planes)
<< ", modifier: " << std::hex << modifier;
- std::move(notify_layout_changed_cb_).Run(base::nullopt);
+ std::move(notify_layout_changed_cb_).Run(absl::nullopt);
return;
}
@@ -395,7 +395,7 @@ void VdVideoDecodeAccelerator::ImportBufferForPicture(
import_frame_cb_.Run(std::move(wrapped_frame));
}
-base::Optional<Picture> VdVideoDecodeAccelerator::GetPicture(
+absl::optional<Picture> VdVideoDecodeAccelerator::GetPicture(
const VideoFrame& frame) {
DVLOGF(4);
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
@@ -404,18 +404,18 @@ base::Optional<Picture> VdVideoDecodeAccelerator::GetPicture(
frame_id_to_picture_id_.find(DmabufVideoFramePool::GetDmabufId(frame));
if (it == frame_id_to_picture_id_.end()) {
VLOGF(1) << "Failed to find the picture buffer id.";
- return base::nullopt;
+ return absl::nullopt;
}
int32_t picture_buffer_id = it->second;
int32_t bitstream_id = FakeTimestampToBitstreamId(frame.timestamp());
- return base::make_optional(Picture(picture_buffer_id, bitstream_id,
+ return absl::make_optional(Picture(picture_buffer_id, bitstream_id,
frame.visible_rect(), frame.ColorSpace(),
frame.metadata().allow_overlay));
}
// static
void VdVideoDecodeAccelerator::OnFrameReleasedThunk(
- base::Optional<base::WeakPtr<VdVideoDecodeAccelerator>> weak_this,
+ absl::optional<base::WeakPtr<VdVideoDecodeAccelerator>> weak_this,
scoped_refptr<base::SequencedTaskRunner> task_runner,
scoped_refptr<VideoFrame> origin_frame) {
DVLOGF(4);
diff --git a/chromium/media/gpu/chromeos/vd_video_decode_accelerator.h b/chromium/media/gpu/chromeos/vd_video_decode_accelerator.h
index f4ea148df36..be844f68b99 100644
--- a/chromium/media/gpu/chromeos/vd_video_decode_accelerator.h
+++ b/chromium/media/gpu/chromeos/vd_video_decode_accelerator.h
@@ -11,10 +11,8 @@
#include "base/callback_forward.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
-#include "base/time/time.h"
#include "media/base/status.h"
#include "media/base/video_decoder.h"
#include "media/gpu/chromeos/dmabuf_video_frame_pool.h"
@@ -23,6 +21,7 @@
#include "media/gpu/chromeos/video_frame_converter.h"
#include "media/gpu/media_gpu_export.h"
#include "media/video/video_decode_accelerator.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -100,15 +99,15 @@ class MEDIA_GPU_EXPORT VdVideoDecodeAccelerator
void OnResetDone();
// Get Picture instance that represents the same buffer as |frame|. Return
- // base::nullopt if the buffer is already dismissed.
- base::Optional<Picture> GetPicture(const VideoFrame& frame);
+ // absl::nullopt if the buffer is already dismissed.
+ absl::optional<Picture> GetPicture(const VideoFrame& frame);
// Thunk to post OnFrameReleased() to |task_runner|.
// Because this thunk may be called in any thread, We don't want to
- // dereference WeakPtr. Therefore we wrap the WeakPtr by base::Optional to
+ // dereference WeakPtr. Therefore we wrap the WeakPtr by absl::optional to
// avoid the task runner defererencing the WeakPtr.
static void OnFrameReleasedThunk(
- base::Optional<base::WeakPtr<VdVideoDecodeAccelerator>> weak_this,
+ absl::optional<base::WeakPtr<VdVideoDecodeAccelerator>> weak_this,
scoped_refptr<base::SequencedTaskRunner> task_runner,
scoped_refptr<VideoFrame> origin_frame);
// Called when a frame gets destroyed.
@@ -133,7 +132,7 @@ class MEDIA_GPU_EXPORT VdVideoDecodeAccelerator
gfx::Size pending_coded_size_;
// The formats of the current buffers.
gfx::Size coded_size_;
- base::Optional<VideoFrameLayout> layout_;
+ absl::optional<VideoFrameLayout> layout_;
// Mapping from VideoFrame's DmabufId to picture buffer id.
std::map<DmabufId, int32_t /* picture_buffer_id */> frame_id_to_picture_id_;
diff --git a/chromium/media/gpu/chromeos/vda_video_frame_pool.cc b/chromium/media/gpu/chromeos/vda_video_frame_pool.cc
index f7ba7977be4..305b7a2a411 100644
--- a/chromium/media/gpu/chromeos/vda_video_frame_pool.cc
+++ b/chromium/media/gpu/chromeos/vda_video_frame_pool.cc
@@ -29,7 +29,7 @@ VdaVideoFramePool::~VdaVideoFramePool() {
weak_this_factory_.InvalidateWeakPtrs();
}
-base::Optional<GpuBufferLayout> VdaVideoFramePool::Initialize(
+absl::optional<GpuBufferLayout> VdaVideoFramePool::Initialize(
const Fourcc& fourcc,
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
@@ -41,7 +41,7 @@ base::Optional<GpuBufferLayout> VdaVideoFramePool::Initialize(
if (use_protected) {
LOG(ERROR) << "Cannot allocated protected buffers for VDA";
- return base::nullopt;
+ return absl::nullopt;
}
visible_rect_ = visible_rect;
@@ -65,7 +65,7 @@ base::Optional<GpuBufferLayout> VdaVideoFramePool::Initialize(
// Clear the pool and reset the layout to prevent previous frames are recycled
// back to the pool.
frame_pool_ = {};
- layout_ = base::nullopt;
+ layout_ = absl::nullopt;
// Receive the layout from the callback. |layout_| is accessed on
// |parent_task_runner_| except OnRequestFramesDone(). However, we block
@@ -89,7 +89,7 @@ base::Optional<GpuBufferLayout> VdaVideoFramePool::Initialize(
void VdaVideoFramePool::OnRequestFramesDone(
base::WaitableEvent* done,
- base::Optional<GpuBufferLayout> value) {
+ absl::optional<GpuBufferLayout> value) {
DVLOGF(3);
// RequestFrames() is blocked on |parent_task_runner_| to wait for this method
// finishes, so this method must not be run on the same sequence.
@@ -107,7 +107,7 @@ void VdaVideoFramePool::OnRequestFramesDone(
// static
void VdaVideoFramePool::ImportFrameThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<VdaVideoFramePool>> weak_this,
+ absl::optional<base::WeakPtr<VdaVideoFramePool>> weak_this,
scoped_refptr<VideoFrame> frame) {
DVLOGF(3);
DCHECK(weak_this);
diff --git a/chromium/media/gpu/chromeos/vda_video_frame_pool.h b/chromium/media/gpu/chromeos/vda_video_frame_pool.h
index fd2995a9af7..0955a9f2886 100644
--- a/chromium/media/gpu/chromeos/vda_video_frame_pool.h
+++ b/chromium/media/gpu/chromeos/vda_video_frame_pool.h
@@ -5,16 +5,14 @@
#ifndef MEDIA_GPU_CHROMEOS_VDA_VIDEO_FRAME_POOL_H_
#define MEDIA_GPU_CHROMEOS_VDA_VIDEO_FRAME_POOL_H_
-#include <vector>
-
#include "base/containers/queue.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "media/base/video_frame.h"
#include "media/gpu/chromeos/dmabuf_video_frame_pool.h"
#include "media/gpu/chromeos/fourcc.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace base {
class WaitableEvent;
@@ -38,7 +36,7 @@ class VdaVideoFramePool : public DmabufVideoFramePool {
public:
// Callback for returning the layout of requested buffer.
using NotifyLayoutChangedCb =
- base::OnceCallback<void(base::Optional<GpuBufferLayout>)>;
+ base::OnceCallback<void(absl::optional<GpuBufferLayout>)>;
// Callback for importing available frames to this pool.
using ImportFrameCb =
base::RepeatingCallback<void(scoped_refptr<VideoFrame>)>;
@@ -62,7 +60,7 @@ class VdaVideoFramePool : public DmabufVideoFramePool {
~VdaVideoFramePool() override;
// DmabufVideoFramePool implementation.
- base::Optional<GpuBufferLayout> Initialize(const Fourcc& fourcc,
+ absl::optional<GpuBufferLayout> Initialize(const Fourcc& fourcc,
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
@@ -76,15 +74,15 @@ class VdaVideoFramePool : public DmabufVideoFramePool {
// Update the layout of the buffers. |vda_| calls this as
// NotifyLayoutChangedCb.
void OnRequestFramesDone(base::WaitableEvent* done,
- base::Optional<GpuBufferLayout> value);
+ absl::optional<GpuBufferLayout> value);
// Thunk to post ImportFrame() to |task_runner|.
// Because this thunk may be called in any thread, We don't want to
- // dereference WeakPtr. Therefore we wrap the WeakPtr by base::Optional to
+ // dereference WeakPtr. Therefore we wrap the WeakPtr by absl::optional to
// avoid the task runner defererencing the WeakPtr.
static void ImportFrameThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<VdaVideoFramePool>> weak_this,
+ absl::optional<base::WeakPtr<VdaVideoFramePool>> weak_this,
scoped_refptr<VideoFrame> frame);
// Import an available frame.
void ImportFrame(scoped_refptr<VideoFrame> frame);
@@ -104,11 +102,11 @@ class VdaVideoFramePool : public DmabufVideoFramePool {
base::OnceClosure frame_available_cb_;
// The layout of the frames in |frame_pool_|.
- base::Optional<GpuBufferLayout> layout_;
+ absl::optional<GpuBufferLayout> layout_;
// Data passed from Initialize().
size_t max_num_frames_ = 0;
- base::Optional<Fourcc> fourcc_;
+ absl::optional<Fourcc> fourcc_;
gfx::Size coded_size_;
gfx::Rect visible_rect_;
gfx::Size natural_size_;
diff --git a/chromium/media/gpu/chromeos/video_decoder_pipeline.cc b/chromium/media/gpu/chromeos/video_decoder_pipeline.cc
index 2c59b384add..80f1f59324e 100644
--- a/chromium/media/gpu/chromeos/video_decoder_pipeline.cc
+++ b/chromium/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -8,7 +8,6 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
-#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
@@ -23,6 +22,7 @@
#include "media/gpu/chromeos/platform_video_frame_pool.h"
#include "media/gpu/macros.h"
#include "media/media_buildflags.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace {
@@ -33,7 +33,7 @@ constexpr size_t kNumFramesForImageProcessor = limits::kMaxVideoFrames + 1;
// Pick a compositor renderable format from |candidates|.
// Return zero if not found.
-base::Optional<Fourcc> PickRenderableFourcc(
+absl::optional<Fourcc> PickRenderableFourcc(
const std::vector<Fourcc>& candidates) {
// Hardcode compositor renderable format now.
// TODO: figure out a way to pick the best one dynamically.
@@ -54,7 +54,7 @@ base::Optional<Fourcc> PickRenderableFourcc(
return Fourcc(value);
}
}
- return base::nullopt;
+ return absl::nullopt;
}
} // namespace
@@ -455,7 +455,7 @@ DmabufVideoFramePool* VideoDecoderPipeline::GetVideoFramePool() const {
return main_frame_pool_.get();
}
-base::Optional<std::pair<Fourcc, gfx::Size>>
+absl::optional<std::pair<Fourcc, gfx::Size>>
VideoDecoderPipeline::PickDecoderOutputFormat(
const std::vector<std::pair<Fourcc, gfx::Size>>& candidates,
const gfx::Rect& visible_rect) {
@@ -463,7 +463,7 @@ VideoDecoderPipeline::PickDecoderOutputFormat(
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
if (candidates.empty())
- return base::nullopt;
+ return absl::nullopt;
image_processor_.reset();
@@ -478,7 +478,7 @@ VideoDecoderPipeline::PickDecoderOutputFormat(
if (candidate.first == renderable_fourcc)
return candidate;
DVLOGF(2) << "Renderable Fourcc not in candidates list. This is a bug.";
- return base::nullopt;
+ return absl::nullopt;
}
std::unique_ptr<ImageProcessor> image_processor =
@@ -489,7 +489,7 @@ VideoDecoderPipeline::PickDecoderOutputFormat(
decoder_weak_this_));
if (!image_processor) {
DVLOGF(2) << "Unable to find ImageProcessor to convert format";
- return base::nullopt;
+ return absl::nullopt;
}
// Note that fourcc is specified in ImageProcessor's factory method.
@@ -502,7 +502,7 @@ VideoDecoderPipeline::PickDecoderOutputFormat(
kNumFramesForImageProcessor, decoder_task_runner_);
if (!image_processor_) {
DVLOGF(2) << "Unable to create ImageProcessorWithPool.";
- return base::nullopt;
+ return absl::nullopt;
}
return std::make_pair(fourcc, size);
diff --git a/chromium/media/gpu/chromeos/video_decoder_pipeline.h b/chromium/media/gpu/chromeos/video_decoder_pipeline.h
index ea17d274fd1..1c4530a59e2 100644
--- a/chromium/media/gpu/chromeos/video_decoder_pipeline.h
+++ b/chromium/media/gpu/chromeos/video_decoder_pipeline.h
@@ -9,7 +9,6 @@
#include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
@@ -17,6 +16,7 @@
#include "media/gpu/chromeos/image_processor_with_pool.h"
#include "media/gpu/chromeos/video_frame_converter.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace base {
@@ -62,8 +62,8 @@ class MEDIA_GPU_EXPORT DecoderInterface {
// Return a valid format and size for |decoder_| output from given
// |candidates| and the visible rect. The size might be modified from the
// ones provided originally to accommodate the needs of the pipeline.
- // Return base::nullopt if no valid format is found.
- virtual base::Optional<std::pair<Fourcc, gfx::Size>>
+ // Return absl::nullopt if no valid format is found.
+ virtual absl::optional<std::pair<Fourcc, gfx::Size>>
PickDecoderOutputFormat(
const std::vector<std::pair<Fourcc, gfx::Size>>& candidates,
const gfx::Rect& visible_rect) = 0;
@@ -166,7 +166,7 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder,
// After picking a format, it instantiates an |image_processor_| if none of
// format in |candidates| is renderable and an ImageProcessor can convert a
// candidate to renderable format.
- base::Optional<std::pair<Fourcc, gfx::Size>> PickDecoderOutputFormat(
+ absl::optional<std::pair<Fourcc, gfx::Size>> PickDecoderOutputFormat(
const std::vector<std::pair<Fourcc, gfx::Size>>& candidates,
const gfx::Rect& visible_rect) override;
diff --git a/chromium/media/gpu/chromeos/video_decoder_pipeline_unittest.cc b/chromium/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
index 9582d9493b8..6823dfc83df 100644
--- a/chromium/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
+++ b/chromium/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
@@ -36,7 +36,7 @@ class MockVideoFramePool : public DmabufVideoFramePool {
// DmabufVideoFramePool implementation.
MOCK_METHOD6(Initialize,
- base::Optional<GpuBufferLayout>(const Fourcc&,
+ absl::optional<GpuBufferLayout>(const Fourcc&,
const gfx::Size&,
const gfx::Rect&,
const gfx::Size&,
diff --git a/chromium/media/gpu/command_buffer_helper.cc b/chromium/media/gpu/command_buffer_helper.cc
index a15549c0a6e..36c9aab569a 100644
--- a/chromium/media/gpu/command_buffer_helper.cc
+++ b/chromium/media/gpu/command_buffer_helper.cc
@@ -32,7 +32,10 @@ class CommandBufferHelperImpl
public gpu::CommandBufferStub::DestructionObserver {
public:
explicit CommandBufferHelperImpl(gpu::CommandBufferStub* stub)
- : CommandBufferHelper(stub->channel()->task_runner()), stub_(stub) {
+ : CommandBufferHelper(stub->channel()->task_runner()),
+ stub_(stub),
+ memory_tracker_(this),
+ memory_type_tracker_(&memory_tracker_) {
DVLOG(1) << __func__;
DCHECK(stub_->channel()->task_runner()->BelongsToCurrentThread());
@@ -48,8 +51,6 @@ class CommandBufferHelperImpl
#endif // defined(OS_MAC)
);
decoder_helper_ = GLES2DecoderHelper::Create(stub_->decoder_context());
- tracker_ =
- std::make_unique<gpu::MemoryTypeTracker>(stub_->GetMemoryTracker());
}
gl::GLContext* GetGLContext() override {
@@ -63,6 +64,11 @@ class CommandBufferHelperImpl
}
gpu::SharedImageStub* GetSharedImageStub() override {
+ return shared_image_stub();
+ }
+
+ // Const variant of above method for internal callers.
+ gpu::SharedImageStub* shared_image_stub() const {
if (!stub_)
return nullptr;
return stub_->channel()->shared_image_stub();
@@ -89,7 +95,7 @@ class CommandBufferHelperImpl
return stub_->channel()
->gpu_channel_manager()
->shared_image_manager()
- ->Register(std::move(backing), tracker_.get());
+ ->Register(std::move(backing), &memory_type_tracker_);
}
gpu::TextureBase* GetTexture(GLuint service_id) const override {
@@ -209,6 +215,51 @@ class CommandBufferHelperImpl
}
private:
+ // Helper class to forward memory tracking calls to shared image stub.
+ // Necessary because the underlying stub and channel can get destroyed before
+ // the CommandBufferHelper and its clients.
+ class MemoryTrackerImpl : public gpu::MemoryTracker {
+ public:
+ explicit MemoryTrackerImpl(CommandBufferHelperImpl* helper)
+ : helper_(helper) {
+ if (auto* stub = helper_->shared_image_stub()) {
+ // We assume these don't change after initialization.
+ client_id_ = stub->ClientId();
+ client_tracing_id_ = stub->ClientTracingId();
+ context_group_tracing_id_ = stub->ContextGroupTracingId();
+ }
+ }
+ ~MemoryTrackerImpl() override = default;
+
+ MemoryTrackerImpl(const MemoryTrackerImpl&) = delete;
+ MemoryTrackerImpl& operator=(const MemoryTrackerImpl&) = delete;
+
+ void TrackMemoryAllocatedChange(int64_t delta) override {
+ if (auto* stub = helper_->shared_image_stub())
+ stub->TrackMemoryAllocatedChange(delta);
+ }
+
+ uint64_t GetSize() const override {
+ if (auto* stub = helper_->shared_image_stub())
+ return stub->GetSize();
+ return 0;
+ }
+
+ int ClientId() const override { return client_id_; }
+
+ uint64_t ClientTracingId() const override { return client_tracing_id_; }
+
+ uint64_t ContextGroupTracingId() const override {
+ return context_group_tracing_id_;
+ }
+
+ private:
+ CommandBufferHelperImpl* const helper_;
+ int client_id_ = 0;
+ uint64_t client_tracing_id_ = 0;
+ uint64_t context_group_tracing_id_ = 0;
+ };
+
~CommandBufferHelperImpl() override {
DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -257,7 +308,8 @@ class CommandBufferHelperImpl
WillDestroyStubCB will_destroy_stub_cb_;
- std::unique_ptr<gpu::MemoryTypeTracker> tracker_;
+ MemoryTrackerImpl memory_tracker_;
+ gpu::MemoryTypeTracker memory_type_tracker_;
THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(CommandBufferHelperImpl);
diff --git a/chromium/media/gpu/gles2_decoder_helper.h b/chromium/media/gpu/gles2_decoder_helper.h
index f97e5f4152e..1645c5b607d 100644
--- a/chromium/media/gpu/gles2_decoder_helper.h
+++ b/chromium/media/gpu/gles2_decoder_helper.h
@@ -10,8 +10,8 @@
#include <memory>
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gl/gl_bindings.h"
namespace gpu {
diff --git a/chromium/media/gpu/gpu_video_accelerator_util.h b/chromium/media/gpu/gpu_video_accelerator_util.h
index 8cf8c12b7bb..c8fe4910064 100644
--- a/chromium/media/gpu/gpu_video_accelerator_util.h
+++ b/chromium/media/gpu/gpu_video_accelerator_util.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_GPU_GPU_VIDEO_ACCELERATOR_UTIL_H_
#define MEDIA_GPU_GPU_VIDEO_ACCELERATOR_UTIL_H_
-#include <vector>
-
#include "gpu/config/gpu_info.h"
#include "media/gpu/media_gpu_export.h"
#include "media/video/video_decode_accelerator.h"
diff --git a/chromium/media/gpu/gpu_video_decode_accelerator_factory.cc b/chromium/media/gpu/gpu_video_decode_accelerator_factory.cc
index 360f54ec0d7..0e55ef47ec6 100644
--- a/chromium/media/gpu/gpu_video_decode_accelerator_factory.cc
+++ b/chromium/media/gpu/gpu_video_decode_accelerator_factory.cc
@@ -59,7 +59,7 @@ gpu::VideoDecodeAcceleratorCapabilities GetDecoderCapabilitiesInternal(
#elif BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
#if BUILDFLAG(USE_VAAPI)
capabilities.supported_profiles =
- VaapiVideoDecodeAccelerator::GetSupportedProfiles(workarounds);
+ VaapiVideoDecodeAccelerator::GetSupportedProfiles();
#elif BUILDFLAG(USE_V4L2_CODEC)
GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
V4L2VideoDecodeAccelerator::GetSupportedProfiles(),
diff --git a/chromium/media/gpu/gpu_video_encode_accelerator_factory.cc b/chromium/media/gpu/gpu_video_encode_accelerator_factory.cc
index 3ddcd3cf273..9469934be87 100644
--- a/chromium/media/gpu/gpu_video_encode_accelerator_factory.cc
+++ b/chromium/media/gpu/gpu_video_encode_accelerator_factory.cc
@@ -197,6 +197,11 @@ GpuVideoEncodeAcceleratorFactory::GetSupportedProfiles(
});
}
+ base::EraseIf(profiles, [](const auto& vea_profile) {
+ return vea_profile.profile >= HEVCPROFILE_MIN &&
+ vea_profile.profile <= HEVCPROFILE_MAX;
+ });
+
return profiles;
}
diff --git a/chromium/media/gpu/h264_decoder.cc b/chromium/media/gpu/h264_decoder.cc
index 20538297e8b..771eedc557a 100644
--- a/chromium/media/gpu/h264_decoder.cc
+++ b/chromium/media/gpu/h264_decoder.cc
@@ -11,11 +11,11 @@
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
-#include "base/optional.h"
#include "base/stl_util.h"
#include "media/base/media_switches.h"
#include "media/gpu/h264_decoder.h"
#include "media/video/h264_level_limits.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace {
@@ -1050,7 +1050,7 @@ bool H264Decoder::FinishPicture(scoped_refptr<H264Picture> pic) {
// outputting all pictures before it, to avoid outputting corrupted
// frames.
(*output_candidate)->frame_num == *recovery_frame_num_) {
- recovery_frame_num_ = base::nullopt;
+ recovery_frame_num_ = absl::nullopt;
if (!OutputPic(*output_candidate))
return false;
}
diff --git a/chromium/media/gpu/h264_decoder.h b/chromium/media/gpu/h264_decoder.h
index d01ab1544ea..9b4f0830ce1 100644
--- a/chromium/media/gpu/h264_decoder.h
+++ b/chromium/media/gpu/h264_decoder.h
@@ -384,12 +384,12 @@ class MEDIA_GPU_EXPORT H264Decoder : public AcceleratedVideoDecoder {
std::vector<base::span<const uint8_t>> encrypted_sei_nalus_;
std::vector<SubsampleEntry> sei_subsamples_;
- // These are base::nullopt unless get recovery point SEI message after Reset.
+ // These are absl::nullopt unless get recovery point SEI message after Reset.
// A frame_num of the frame at output order that is correct in content.
- base::Optional<int> recovery_frame_num_;
+ absl::optional<int> recovery_frame_num_;
// A value in the recovery point SEI message to compute |recovery_frame_num_|
// later.
- base::Optional<int> recovery_frame_cnt_;
+ absl::optional<int> recovery_frame_cnt_;
// Output picture size.
gfx::Size pic_size_;
diff --git a/chromium/media/gpu/h265_decoder.cc b/chromium/media/gpu/h265_decoder.cc
index 64d5106de33..547154689a8 100644
--- a/chromium/media/gpu/h265_decoder.cc
+++ b/chromium/media/gpu/h265_decoder.cc
@@ -40,7 +40,7 @@ bool IsValidBitDepth(uint8_t bit_depth, VideoCodecProfile profile) {
case HEVCPROFILE_MAIN_STILL_PICTURE:
return bit_depth == 8u;
default:
- NOTREACHED();
+ DVLOG(1) << "Invalid profile specified for H265";
return false;
}
}
diff --git a/chromium/media/gpu/ipc/common/BUILD.gn b/chromium/media/gpu/ipc/common/BUILD.gn
index 194f6e5e7d3..1d8f8bca6a2 100644
--- a/chromium/media/gpu/ipc/common/BUILD.gn
+++ b/chromium/media/gpu/ipc/common/BUILD.gn
@@ -4,8 +4,6 @@
source_set("common") {
sources = [
- "create_video_encoder_params.cc",
- "create_video_encoder_params.h",
"media_message_generator.cc",
"media_message_generator.h",
"media_messages.h",
diff --git a/chromium/media/gpu/ipc/common/create_video_encoder_params.cc b/chromium/media/gpu/ipc/common/create_video_encoder_params.cc
deleted file mode 100644
index 4de82bf0bfd..00000000000
--- a/chromium/media/gpu/ipc/common/create_video_encoder_params.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2016 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 "media/gpu/ipc/common/create_video_encoder_params.h"
-
-#include "ipc/ipc_message.h"
-
-namespace media {
-
-CreateVideoEncoderParams::CreateVideoEncoderParams()
- : input_format(PIXEL_FORMAT_UNKNOWN),
- output_profile(VIDEO_CODEC_PROFILE_UNKNOWN),
- initial_bitrate(0),
- encoder_route_id(MSG_ROUTING_NONE) {}
-
-CreateVideoEncoderParams::~CreateVideoEncoderParams() = default;
-
-} // namespace media
diff --git a/chromium/media/gpu/ipc/common/create_video_encoder_params.h b/chromium/media/gpu/ipc/common/create_video_encoder_params.h
deleted file mode 100644
index 995a6d9aa36..00000000000
--- a/chromium/media/gpu/ipc/common/create_video_encoder_params.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2016 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 MEDIA_GPU_IPC_COMMON_CREATE_VIDEO_ENCODER_PARAMS_H_
-#define MEDIA_GPU_IPC_COMMON_CREATE_VIDEO_ENCODER_PARAMS_H_
-
-#include "media/base/video_codecs.h"
-#include "media/base/video_types.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace media {
-
-struct CreateVideoEncoderParams {
- CreateVideoEncoderParams();
- ~CreateVideoEncoderParams();
- VideoPixelFormat input_format;
- gfx::Size input_visible_size;
- VideoCodecProfile output_profile;
- uint32_t initial_bitrate;
- int32_t encoder_route_id;
-};
-
-} // namespace media
-
-#endif // MEDIA_GPU_IPC_COMMON_CREATE_VIDEO_ENCODER_PARAMS_H_
diff --git a/chromium/media/gpu/ipc/common/media_messages.h b/chromium/media/gpu/ipc/common/media_messages.h
index 3f47f08cdf6..8d0e1f87b81 100644
--- a/chromium/media/gpu/ipc/common/media_messages.h
+++ b/chromium/media/gpu/ipc/common/media_messages.h
@@ -11,6 +11,7 @@
#include "gpu/config/gpu_info.h"
#include "gpu/ipc/common/gpu_param_traits_macros.h"
#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_message_start.h"
#include "ipc/param_traits_macros.h"
#include "media/base/overlay_info.h"
#include "media/gpu/ipc/common/media_param_traits.h"
diff --git a/chromium/media/gpu/ipc/common/media_param_traits_macros.h b/chromium/media/gpu/ipc/common/media_param_traits_macros.h
index 22d0b7eb247..a15d8d03cd6 100644
--- a/chromium/media/gpu/ipc/common/media_param_traits_macros.h
+++ b/chromium/media/gpu/ipc/common/media_param_traits_macros.h
@@ -8,7 +8,6 @@
#include "gpu/config/gpu_info.h"
#include "ipc/ipc_message_macros.h"
#include "media/base/ipc/media_param_traits.h"
-#include "media/gpu/ipc/common/create_video_encoder_params.h"
#include "media/video/video_decode_accelerator.h"
#include "media/video/video_encode_accelerator.h"
#include "ui/gfx/ipc/color/gfx_param_traits.h"
@@ -32,12 +31,4 @@ IPC_STRUCT_TRAITS_BEGIN(media::VideoDecodeAccelerator::Config)
IPC_STRUCT_TRAITS_MEMBER(hdr_metadata)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(media::CreateVideoEncoderParams)
- IPC_STRUCT_TRAITS_MEMBER(input_format)
- IPC_STRUCT_TRAITS_MEMBER(input_visible_size)
- IPC_STRUCT_TRAITS_MEMBER(output_profile)
- IPC_STRUCT_TRAITS_MEMBER(initial_bitrate)
- IPC_STRUCT_TRAITS_MEMBER(encoder_route_id)
-IPC_STRUCT_TRAITS_END()
-
#endif // MEDIA_GPU_IPC_COMMON_MEDIA_PARAM_TRAITS_MACROS_H_
diff --git a/chromium/media/gpu/ipc/service/media_gpu_channel.h b/chromium/media/gpu/ipc/service/media_gpu_channel.h
index 04db47080be..8d21c2a8026 100644
--- a/chromium/media/gpu/ipc/service/media_gpu_channel.h
+++ b/chromium/media/gpu/ipc/service/media_gpu_channel.h
@@ -5,18 +5,12 @@
#ifndef MEDIA_GPU_IPC_SERVICE_MEDIA_GPU_CHANNEL_H_
#define MEDIA_GPU_IPC_SERVICE_MEDIA_GPU_CHANNEL_H_
-#include <memory>
-
#include "base/unguessable_token.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
#include "media/base/android_overlay_mojo_factory.h"
#include "media/video/video_decode_accelerator.h"
-namespace media {
-struct CreateVideoEncoderParams;
-}
-
namespace gpu {
class GpuChannel;
}
@@ -47,9 +41,6 @@ class MediaGpuChannel : public IPC::Listener, public IPC::Sender {
const VideoDecodeAccelerator::Config& config,
int32_t route_id,
IPC::Message* reply_message);
- void OnCreateVideoEncoder(int32_t command_buffer_route_id,
- const CreateVideoEncoderParams& params,
- IPC::Message* reply_message);
gpu::GpuChannel* const channel_;
scoped_refptr<MediaGpuChannelFilter> filter_;
diff --git a/chromium/media/gpu/mac/vt_config_util.h b/chromium/media/gpu/mac/vt_config_util.h
index d3b4a5e3e31..ea86e465f56 100644
--- a/chromium/media/gpu/mac/vt_config_util.h
+++ b/chromium/media/gpu/mac/vt_config_util.h
@@ -8,10 +8,10 @@
#include <CoreFoundation/CoreFoundation.h>
#include <CoreMedia/CoreMedia.h>
-#include "base/optional.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
#include "media/gpu/media_gpu_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/hdr_metadata.h"
namespace media {
@@ -20,7 +20,7 @@ MEDIA_GPU_EXPORT CFMutableDictionaryRef
CreateFormatExtensions(CMVideoCodecType codec_type,
VideoCodecProfile profile,
const VideoColorSpace& color_space,
- base::Optional<gfx::HDRMetadata> hdr_metadata);
+ absl::optional<gfx::HDRMetadata> hdr_metadata);
} // namespace media
diff --git a/chromium/media/gpu/mac/vt_config_util.mm b/chromium/media/gpu/mac/vt_config_util.mm
index 09d03a517ee..8e659e63ec6 100644
--- a/chromium/media/gpu/mac/vt_config_util.mm
+++ b/chromium/media/gpu/mac/vt_config_util.mm
@@ -228,7 +228,7 @@ CFMutableDictionaryRef CreateFormatExtensions(
CMVideoCodecType codec_type,
VideoCodecProfile profile,
const VideoColorSpace& color_space,
- base::Optional<gfx::HDRMetadata> hdr_metadata) {
+ absl::optional<gfx::HDRMetadata> hdr_metadata) {
auto* extensions = [[NSMutableDictionary alloc] init];
SetDictionaryValue(extensions, kCMFormatDescriptionExtension_FormatName,
CMVideoCodecTypeToString(codec_type));
diff --git a/chromium/media/gpu/mac/vt_config_util_unittest.cc b/chromium/media/gpu/mac/vt_config_util_unittest.cc
index 3c264e1aec8..6fbb4144e1f 100644
--- a/chromium/media/gpu/mac/vt_config_util_unittest.cc
+++ b/chromium/media/gpu/mac/vt_config_util_unittest.cc
@@ -136,7 +136,7 @@ namespace media {
TEST(VTConfigUtil, CreateFormatExtensions_H264_BT709) {
base::ScopedCFTypeRef<CFDictionaryRef> fmt(
CreateFormatExtensions(kCMVideoCodecType_H264, H264PROFILE_MAIN,
- VideoColorSpace::REC709(), base::nullopt));
+ VideoColorSpace::REC709(), absl::nullopt));
EXPECT_EQ("avc1", GetStrValue(fmt, kCMFormatDescriptionExtension_FormatName));
EXPECT_EQ(24, GetIntValue(fmt, kCMFormatDescriptionExtension_Depth));
EXPECT_EQ(kCMFormatDescriptionColorPrimaries_ITU_R_709_2,
@@ -271,7 +271,7 @@ TEST(VTConfigUtil, CreateFormatExtensions_VP9Profile0) {
constexpr VideoCodecProfile kTestProfile = VP9PROFILE_PROFILE0;
const auto kTestColorSpace = VideoColorSpace::REC709();
base::ScopedCFTypeRef<CFDictionaryRef> fmt(CreateFormatExtensions(
- kCMVideoCodecType_VP9, kTestProfile, kTestColorSpace, base::nullopt));
+ kCMVideoCodecType_VP9, kTestProfile, kTestColorSpace, absl::nullopt));
EXPECT_EQ(8, GetIntValue(fmt, base::SysUTF8ToCFStringRef(kBitDepthKey)));
auto vpcc = GetNestedDataValue(
@@ -293,7 +293,7 @@ TEST(VTConfigUtil, CreateFormatExtensions_VP9Profile2) {
VideoColorSpace::TransferID::SMPTEST2084,
VideoColorSpace::MatrixID::BT2020_NCL, gfx::ColorSpace::RangeID::LIMITED);
base::ScopedCFTypeRef<CFDictionaryRef> fmt(CreateFormatExtensions(
- kCMVideoCodecType_VP9, kTestProfile, kTestColorSpace, base::nullopt));
+ kCMVideoCodecType_VP9, kTestProfile, kTestColorSpace, absl::nullopt));
EXPECT_EQ(10, GetIntValue(fmt, base::SysUTF8ToCFStringRef(kBitDepthKey)));
auto vpcc = GetNestedDataValue(
diff --git a/chromium/media/gpu/mac/vt_video_decode_accelerator_mac.cc b/chromium/media/gpu/mac/vt_video_decode_accelerator_mac.cc
index f00df04b313..af3230f4b54 100644
--- a/chromium/media/gpu/mac/vt_video_decode_accelerator_mac.cc
+++ b/chromium/media/gpu/mac/vt_video_decode_accelerator_mac.cc
@@ -196,7 +196,7 @@ base::ScopedCFTypeRef<CMFormatDescriptionRef> CreateVideoFormatH264(
base::ScopedCFTypeRef<CMFormatDescriptionRef> CreateVideoFormatVP9(
media::VideoColorSpace color_space,
media::VideoCodecProfile profile,
- base::Optional<gfx::HDRMetadata> hdr_metadata,
+ absl::optional<gfx::HDRMetadata> hdr_metadata,
const gfx::Size& coded_size) {
base::ScopedCFTypeRef<CFMutableDictionaryRef> format_config(
CreateFormatExtensions(kCMVideoCodecType_VP9, profile, color_space,
@@ -325,7 +325,7 @@ bool InitializeVideoToolboxInternal() {
// Create a VP9 decoding session.
if (!CreateVideoToolboxSession(
CreateVideoFormatVP9(VideoColorSpace::REC709(), VP9PROFILE_PROFILE0,
- base::nullopt, gfx::Size(720, 480)),
+ absl::nullopt, gfx::Size(720, 480)),
/*require_hardware=*/true, /*is_hbd=*/false, &callback, &session,
&configured_size)) {
DVLOG(1) << "Hardware VP9 decoding with VideoToolbox is not supported";
@@ -933,7 +933,7 @@ void VTVideoDecodeAccelerator::DecodeTask(scoped_refptr<DecoderBuffer> buffer,
// Compute and store frame properties. |image_size| gets filled in
// later, since it comes from the decoder configuration.
- base::Optional<int32_t> pic_order_cnt =
+ absl::optional<int32_t> pic_order_cnt =
poc_.ComputePicOrderCnt(sps, slice_hdr);
if (!pic_order_cnt.has_value()) {
WriteToMediaLog(MediaLogMessageLevel::kERROR,
diff --git a/chromium/media/gpu/mac/vt_video_encode_accelerator_mac.cc b/chromium/media/gpu/mac/vt_video_encode_accelerator_mac.cc
index a879e765372..a7e1c74d7f4 100644
--- a/chromium/media/gpu/mac/vt_video_encode_accelerator_mac.cc
+++ b/chromium/media/gpu/mac/vt_video_encode_accelerator_mac.cc
@@ -166,6 +166,7 @@ bool VTVideoEncodeAccelerator::Initialize(const Config& config,
frame_rate_ = kMaxFrameRateNumerator / kMaxFrameRateDenominator;
initial_bitrate_ = config.initial_bitrate;
bitstream_buffer_size_ = config.input_visible_size.GetArea();
+ require_low_delay_ = config.require_low_delay;
if (!encoder_thread_.Start()) {
DLOG(ERROR) << "Failed spawning encoder thread.";
@@ -560,10 +561,19 @@ bool VTVideoEncodeAccelerator::ConfigureCompressionSession() {
kVTCompressionPropertyKey_MaxKeyFrameInterval, 7200);
rv &= session_property_setter.Set(
kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, 240);
- rv &=
+ DLOG_IF(ERROR, !rv) << " Setting session property failed.";
+
+ // Setting MaxFrameDelayCount fails on low resolutions and arm64 macs,
+ // but we can use accelerated encoder anyway. See: crbug.com/1195177
+ bool delay_count_rv =
session_property_setter.Set(kVTCompressionPropertyKey_MaxFrameDelayCount,
static_cast<int>(kNumInputBuffers));
- DLOG_IF(ERROR, !rv) << " Setting session property failed.";
+ if (!delay_count_rv) {
+ DLOG(ERROR) << " Setting frame delay count failed.";
+ if (require_low_delay_)
+ return false;
+ }
+
return rv;
}
diff --git a/chromium/media/gpu/mac/vt_video_encode_accelerator_mac.h b/chromium/media/gpu/mac/vt_video_encode_accelerator_mac.h
index 70d1f764e54..43b2942a693 100644
--- a/chromium/media/gpu/mac/vt_video_encode_accelerator_mac.h
+++ b/chromium/media/gpu/mac/vt_video_encode_accelerator_mac.h
@@ -110,6 +110,13 @@ class MEDIA_GPU_EXPORT VTVideoEncodeAccelerator
int32_t encoder_set_bitrate_;
VideoCodecProfile h264_profile_;
+ // If True, the encoder fails initialization if setting of session's property
+ // kVTCompressionPropertyKey_MaxFrameDelayCount returns an error.
+ // Encoder can work even after if MaxFrameDelayCount fails, but it'll
+ // have larger latency on low resolutions, and it's bad for RTC.
+ // Context: https://crbug.com/1195177 https://crbug.com/webrtc/7304
+ bool require_low_delay_ = true;
+
// Bitrate adjuster used to fix VideoToolbox's inconsistent bitrate issues.
webrtc::BitrateAdjuster bitrate_adjuster_;
diff --git a/chromium/media/gpu/v4l2/BUILD.gn b/chromium/media/gpu/v4l2/BUILD.gn
index 32cc30eb84e..755f8bc4cae 100644
--- a/chromium/media/gpu/v4l2/BUILD.gn
+++ b/chromium/media/gpu/v4l2/BUILD.gn
@@ -35,10 +35,10 @@ source_set("v4l2") {
"v4l2_device.h",
"v4l2_device_poller.cc",
"v4l2_device_poller.h",
+ "v4l2_framerate_control.cc",
+ "v4l2_framerate_control.h",
"v4l2_h264_accelerator.cc",
"v4l2_h264_accelerator.h",
- "v4l2_h264_accelerator_chromium.cc",
- "v4l2_h264_accelerator_chromium.h",
"v4l2_h264_accelerator_legacy.cc",
"v4l2_h264_accelerator_legacy.h",
"v4l2_image_processor_backend.cc",
diff --git a/chromium/media/gpu/v4l2/buffer_affinity_tracker.cc b/chromium/media/gpu/v4l2/buffer_affinity_tracker.cc
index fdb62c9252a..7ada30e1960 100644
--- a/chromium/media/gpu/v4l2/buffer_affinity_tracker.cc
+++ b/chromium/media/gpu/v4l2/buffer_affinity_tracker.cc
@@ -23,7 +23,7 @@ void BufferAffinityTracker::resize(size_t nb_buffers) {
DVLOGF(4) << this << " resize: " << nb_buffers;
}
-base::Optional<size_t> BufferAffinityTracker::get_buffer_for_id(
+absl::optional<size_t> BufferAffinityTracker::get_buffer_for_id(
gfx::GenericSharedMemoryId id) {
base::AutoLock lock(lock_);
@@ -39,7 +39,7 @@ base::Optional<size_t> BufferAffinityTracker::get_buffer_for_id(
// No buffer available? No luck then.
if (id_to_buffer_map_.size() == nb_buffers()) {
DVLOGF(4) << this << " tracker is full!";
- return base::nullopt;
+ return absl::nullopt;
}
const size_t v4l2_id = id_to_buffer_map_.size();
diff --git a/chromium/media/gpu/v4l2/buffer_affinity_tracker.h b/chromium/media/gpu/v4l2/buffer_affinity_tracker.h
index 0516efaf778..5019518967e 100644
--- a/chromium/media/gpu/v4l2/buffer_affinity_tracker.h
+++ b/chromium/media/gpu/v4l2/buffer_affinity_tracker.h
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_GPU_V4L2_V4L2_BUFFER_AFFINITY_TRACKER_H_
-#define MEDIA_GPU_V4L2_V4L2_BUFFER_AFFINITY_TRACKER_H_
+#ifndef MEDIA_GPU_V4L2_BUFFER_AFFINITY_TRACKER_H_
+#define MEDIA_GPU_V4L2_BUFFER_AFFINITY_TRACKER_H_
#include <cstddef>
#include <map>
-#include "base/optional.h"
#include "base/synchronization/lock.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/generic_shared_memory_id.h"
namespace media {
@@ -42,7 +42,7 @@ class BufferAffinityTracker {
* On subsequent calls with the same id, that same V4L2 buffer will be
* returned.
*/
- base::Optional<size_t> get_buffer_for_id(gfx::GenericSharedMemoryId id);
+ absl::optional<size_t> get_buffer_for_id(gfx::GenericSharedMemoryId id);
private:
base::Lock lock_;
@@ -53,4 +53,4 @@ class BufferAffinityTracker {
} // namespace media
-#endif // MEDIA_GPU_V4L2_V4L2_BUFFER_AFFINITY_TRACKER_H_
+#endif // MEDIA_GPU_V4L2_BUFFER_AFFINITY_TRACKER_H_
diff --git a/chromium/media/gpu/v4l2/v4l2_decode_surface.h b/chromium/media/gpu/v4l2/v4l2_decode_surface.h
index 865883b5df8..424752c0549 100644
--- a/chromium/media/gpu/v4l2/v4l2_decode_surface.h
+++ b/chromium/media/gpu/v4l2/v4l2_decode_surface.h
@@ -10,9 +10,9 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "media/gpu/v4l2/v4l2_device.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/rect.h"
struct v4l2_ext_controls;
diff --git a/chromium/media/gpu/v4l2/v4l2_device.cc b/chromium/media/gpu/v4l2/v4l2_device.cc
index 1cff2201faf..ba587e59247 100644
--- a/chromium/media/gpu/v4l2/v4l2_device.cc
+++ b/chromium/media/gpu/v4l2/v4l2_device.cc
@@ -300,9 +300,9 @@ class V4L2BuffersList : public base::RefCountedThreadSafe<V4L2BuffersList> {
// Note that it is illegal to return the same buffer twice.
void ReturnBuffer(size_t buffer_id);
// Get any of the buffers in the list. There is no order guarantee whatsoever.
- base::Optional<size_t> GetFreeBuffer();
+ absl::optional<size_t> GetFreeBuffer();
// Get the buffer with specified index.
- base::Optional<size_t> GetFreeBuffer(size_t requested_buffer_id);
+ absl::optional<size_t> GetFreeBuffer(size_t requested_buffer_id);
// Number of buffers currently in this list.
size_t size() const;
@@ -322,13 +322,13 @@ void V4L2BuffersList::ReturnBuffer(size_t buffer_id) {
DCHECK(inserted.second);
}
-base::Optional<size_t> V4L2BuffersList::GetFreeBuffer() {
+absl::optional<size_t> V4L2BuffersList::GetFreeBuffer() {
base::AutoLock auto_lock(lock_);
auto iter = free_buffers_.begin();
if (iter == free_buffers_.end()) {
DVLOGF(4) << "No free buffer available!";
- return base::nullopt;
+ return absl::nullopt;
}
size_t buffer_id = *iter;
@@ -337,13 +337,13 @@ base::Optional<size_t> V4L2BuffersList::GetFreeBuffer() {
return buffer_id;
}
-base::Optional<size_t> V4L2BuffersList::GetFreeBuffer(
+absl::optional<size_t> V4L2BuffersList::GetFreeBuffer(
size_t requested_buffer_id) {
base::AutoLock auto_lock(lock_);
return (free_buffers_.erase(requested_buffer_id) > 0)
- ? base::make_optional(requested_buffer_id)
- : base::nullopt;
+ ? absl::make_optional(requested_buffer_id)
+ : absl::nullopt;
}
size_t V4L2BuffersList::size() const {
@@ -966,46 +966,46 @@ V4L2Queue::~V4L2Queue() {
std::move(destroy_cb_).Run();
}
-base::Optional<struct v4l2_format> V4L2Queue::SetFormat(uint32_t fourcc,
+absl::optional<struct v4l2_format> V4L2Queue::SetFormat(uint32_t fourcc,
const gfx::Size& size,
size_t buffer_size) {
struct v4l2_format format = BuildV4L2Format(type_, fourcc, size, buffer_size);
if (device_->Ioctl(VIDIOC_S_FMT, &format) != 0 ||
format.fmt.pix_mp.pixelformat != fourcc) {
VPQLOGF(2) << "Failed to set format fourcc: " << FourccToString(fourcc);
- return base::nullopt;
+ return absl::nullopt;
}
current_format_ = format;
return current_format_;
}
-base::Optional<struct v4l2_format> V4L2Queue::TryFormat(uint32_t fourcc,
+absl::optional<struct v4l2_format> V4L2Queue::TryFormat(uint32_t fourcc,
const gfx::Size& size,
size_t buffer_size) {
struct v4l2_format format = BuildV4L2Format(type_, fourcc, size, buffer_size);
if (device_->Ioctl(VIDIOC_TRY_FMT, &format) != 0 ||
format.fmt.pix_mp.pixelformat != fourcc) {
VPQLOGF(2) << "Failed to try format fourcc: " << FourccToString(fourcc);
- return base::nullopt;
+ return absl::nullopt;
}
return format;
}
-std::pair<base::Optional<struct v4l2_format>, int> V4L2Queue::GetFormat() {
+std::pair<absl::optional<struct v4l2_format>, int> V4L2Queue::GetFormat() {
struct v4l2_format format;
memset(&format, 0, sizeof(format));
format.type = type_;
if (device_->Ioctl(VIDIOC_G_FMT, &format) != 0) {
VPQLOGF(2) << "Failed to get format";
- return std::make_pair(base::nullopt, errno);
+ return std::make_pair(absl::nullopt, errno);
}
return std::make_pair(format, 0);
}
-base::Optional<gfx::Rect> V4L2Queue::GetVisibleRect() {
+absl::optional<gfx::Rect> V4L2Queue::GetVisibleRect() {
// Some drivers prior to 4.13 only accept the non-MPLANE variant when using
// VIDIOC_G_SELECTION. This block can be removed once we stop supporting
// kernels < 4.13.
@@ -1044,7 +1044,7 @@ base::Optional<gfx::Rect> V4L2Queue::GetVisibleRect() {
}
VQLOGF(1) << "Failed to get visible rect";
- return base::nullopt;
+ return absl::nullopt;
}
size_t V4L2Queue::AllocateBuffers(size_t count, enum v4l2_memory memory) {
@@ -1069,7 +1069,7 @@ size_t V4L2Queue::AllocateBuffers(size_t count, enum v4l2_memory memory) {
}
// First query the number of planes in the buffers we are about to request.
- base::Optional<v4l2_format> format = GetFormat().first;
+ absl::optional<v4l2_format> format = GetFormat().first;
if (!format) {
VQLOGF(1) << "Cannot get format.";
return 0;
@@ -1166,50 +1166,50 @@ v4l2_memory V4L2Queue::GetMemoryType() const {
return memory_;
}
-base::Optional<V4L2WritableBufferRef> V4L2Queue::GetFreeBuffer() {
+absl::optional<V4L2WritableBufferRef> V4L2Queue::GetFreeBuffer() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// No buffers allocated at the moment?
if (!free_buffers_)
- return base::nullopt;
+ return absl::nullopt;
auto buffer_id = free_buffers_->GetFreeBuffer();
if (!buffer_id.has_value())
- return base::nullopt;
+ return absl::nullopt;
return V4L2BufferRefFactory::CreateWritableRef(
buffers_[buffer_id.value()]->v4l2_buffer(),
weak_this_factory_.GetWeakPtr());
}
-base::Optional<V4L2WritableBufferRef> V4L2Queue::GetFreeBuffer(
+absl::optional<V4L2WritableBufferRef> V4L2Queue::GetFreeBuffer(
size_t requested_buffer_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// No buffers allocated at the moment?
if (!free_buffers_)
- return base::nullopt;
+ return absl::nullopt;
auto buffer_id = free_buffers_->GetFreeBuffer(requested_buffer_id);
if (!buffer_id.has_value())
- return base::nullopt;
+ return absl::nullopt;
return V4L2BufferRefFactory::CreateWritableRef(
buffers_[buffer_id.value()]->v4l2_buffer(),
weak_this_factory_.GetWeakPtr());
}
-base::Optional<V4L2WritableBufferRef> V4L2Queue::GetFreeBufferForFrame(
+absl::optional<V4L2WritableBufferRef> V4L2Queue::GetFreeBufferForFrame(
const VideoFrame& frame) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// No buffers allocated at the moment?
if (!free_buffers_)
- return base::nullopt;
+ return absl::nullopt;
if (memory_ != V4L2_MEMORY_DMABUF) {
DVLOGF(1) << "Queue is not DMABUF";
- return base::nullopt;
+ return absl::nullopt;
}
gfx::GenericSharedMemoryId id;
@@ -1219,12 +1219,12 @@ base::Optional<V4L2WritableBufferRef> V4L2Queue::GetFreeBufferForFrame(
id = gfx::GenericSharedMemoryId(frame.DmabufFds()[0].get());
} else {
DVLOGF(1) << "Unsupported frame provided";
- return base::nullopt;
+ return absl::nullopt;
}
const auto v4l2_id = affinity_tracker_.get_buffer_for_id(id);
if (!v4l2_id) {
- return base::nullopt;
+ return absl::nullopt;
}
return GetFreeBuffer(*v4l2_id);
@@ -1381,7 +1381,7 @@ bool V4L2Queue::SupportsRequests() {
return supports_requests_;
}
-base::Optional<struct v4l2_format> V4L2Queue::SetModifierFormat(
+absl::optional<struct v4l2_format> V4L2Queue::SetModifierFormat(
uint64_t modifier,
const gfx::Size& size) {
if (DRM_FORMAT_MOD_QCOM_COMPRESSED == modifier) {
@@ -1391,7 +1391,7 @@ base::Optional<struct v4l2_format> V4L2Queue::SetModifierFormat(
VPLOGF(1) << "Failed to set magic modifier format.";
return format;
}
- return base::nullopt;
+ return absl::nullopt;
}
// This class is used to expose V4L2Queue's constructor to this module. This is
@@ -1777,12 +1777,12 @@ gfx::Size V4L2Device::AllocatedSizeFromV4L2Format(
}
// static
-base::Optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
+absl::optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
const struct v4l2_format& format) {
if (!V4L2_TYPE_IS_MULTIPLANAR(format.type)) {
VLOGF(1) << "v4l2_buf_type is not multiplanar: " << std::hex << "0x"
<< format.type;
- return base::nullopt;
+ return absl::nullopt;
}
const v4l2_pix_format_mplane& pix_mp = format.fmt.pix_mp;
const uint32_t& pix_fmt = pix_mp.pixelformat;
@@ -1790,7 +1790,7 @@ base::Optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
if (!video_fourcc) {
VLOGF(1) << "Failed to convert pixel format to VideoPixelFormat: "
<< FourccToString(pix_fmt);
- return base::nullopt;
+ return absl::nullopt;
}
const VideoPixelFormat video_format = video_fourcc->ToVideoPixelFormat();
const size_t num_buffers = pix_mp.num_planes;
@@ -1798,14 +1798,14 @@ base::Optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
if (num_color_planes == 0) {
VLOGF(1) << "Unsupported video format for NumPlanes(): "
<< VideoPixelFormatToString(video_format);
- return base::nullopt;
+ return absl::nullopt;
}
if (num_buffers > num_color_planes) {
VLOGF(1) << "pix_mp.num_planes: " << num_buffers
<< " should not be larger than NumPlanes("
<< VideoPixelFormatToString(video_format)
<< "): " << num_color_planes;
- return base::nullopt;
+ return absl::nullopt;
}
// Reserve capacity in advance to prevent unnecessary vector reallocation.
std::vector<ColorPlaneLayout> planes;
@@ -1839,7 +1839,7 @@ base::Optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
if (y_stride % 2 != 0 || pix_mp.height % 2 != 0) {
VLOGF(1) << "Plane-Y stride and height should be even; stride: "
<< y_stride << ", height: " << pix_mp.height;
- return base::nullopt;
+ return absl::nullopt;
}
const int32_t half_stride = y_stride / 2;
const size_t plane_0_area = y_stride_abs * pix_mp.height;
@@ -1853,7 +1853,7 @@ base::Optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
default:
VLOGF(1) << "Cannot derive stride for each plane for pixel format "
<< FourccToString(pix_fmt);
- return base::nullopt;
+ return absl::nullopt;
}
}
@@ -1873,7 +1873,7 @@ base::Optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
// static
size_t V4L2Device::GetNumPlanesOfV4L2PixFmt(uint32_t pix_fmt) {
- base::Optional<Fourcc> fourcc = Fourcc::FromV4L2PixFmt(pix_fmt);
+ absl::optional<Fourcc> fourcc = Fourcc::FromV4L2PixFmt(pix_fmt);
if (fourcc && fourcc->IsMultiPlanar()) {
return VideoFrame::NumPlanes(fourcc->ToVideoPixelFormat());
}
@@ -2041,7 +2041,7 @@ void V4L2Device::SchedulePoll() {
device_poller_->SchedulePoll();
}
-base::Optional<struct v4l2_event> V4L2Device::DequeueEvent() {
+absl::optional<struct v4l2_event> V4L2Device::DequeueEvent() {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
struct v4l2_event event;
memset(&event, 0, sizeof(event));
@@ -2050,7 +2050,7 @@ base::Optional<struct v4l2_event> V4L2Device::DequeueEvent() {
// The ioctl will fail if there are no pending events. This is part of the
// normal flow, so keep this log level low.
VPLOGF(4) << "Failed to dequeue event";
- return base::nullopt;
+ return absl::nullopt;
}
return event;
@@ -2119,7 +2119,7 @@ bool V4L2Device::SetExtCtrls(uint32_t ctrl_class,
return result == 0;
}
-base::Optional<struct v4l2_ext_control> V4L2Device::GetCtrl(uint32_t ctrl_id) {
+absl::optional<struct v4l2_ext_control> V4L2Device::GetCtrl(uint32_t ctrl_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
struct v4l2_ext_control ctrl;
memset(&ctrl, 0, sizeof(ctrl));
@@ -2132,7 +2132,7 @@ base::Optional<struct v4l2_ext_control> V4L2Device::GetCtrl(uint32_t ctrl_id) {
if (Ioctl(VIDIOC_G_EXT_CTRLS, &ext_ctrls) != 0) {
VPLOGF(3) << "Failed to get control";
- return base::nullopt;
+ return absl::nullopt;
}
return ctrl;
@@ -2343,14 +2343,14 @@ bool V4L2RequestRef::ApplyQueueBuffer(struct v4l2_buffer* buffer) const {
return request_->ApplyQueueBuffer(buffer);
}
-base::Optional<V4L2SubmittedRequestRef> V4L2RequestRef::Submit() && {
+absl::optional<V4L2SubmittedRequestRef> V4L2RequestRef::Submit() && {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_NE(request_, nullptr);
V4L2RequestRef self(std::move(*this));
if (!self.request_->Submit())
- return base::nullopt;
+ return absl::nullopt;
return V4L2SubmittedRequestRef(self.request_);
}
@@ -2375,7 +2375,7 @@ V4L2RequestsQueue::~V4L2RequestsQueue() {
media_fd_.reset();
}
-base::Optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() {
+absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
int request_fd;
@@ -2383,13 +2383,13 @@ base::Optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() {
ioctl(media_fd_.get(), MEDIA_IOC_REQUEST_ALLOC, &request_fd));
if (ret < 0) {
VPLOGF(1) << "Failed to create request";
- return base::nullopt;
+ return absl::nullopt;
}
return base::ScopedFD(request_fd);
}
-base::Optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() {
+absl::optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
V4L2Request* request_ptr =
@@ -2402,7 +2402,7 @@ base::Optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() {
auto request_fd = CreateRequestFD();
if (!request_fd.has_value()) {
VLOGF(1) << "Error while creating a new request FD!";
- return base::nullopt;
+ return absl::nullopt;
}
// Not using std::make_unique because constructor is private.
std::unique_ptr<V4L2Request> request(
@@ -2417,7 +2417,7 @@ base::Optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() {
<< "request is blocking.";
if (!request_ptr->WaitForCompletion()) {
VLOG(1) << "Timeout while waiting for request to complete.";
- return base::nullopt;
+ return absl::nullopt;
}
free_requests_.pop();
}
@@ -2425,7 +2425,7 @@ base::Optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() {
DCHECK(request_ptr);
if (!request_ptr->Reset()) {
VPLOGF(1) << "Failed to reset request";
- return base::nullopt;
+ return absl::nullopt;
}
return V4L2RequestRef(request_ptr);
diff --git a/chromium/media/gpu/v4l2/v4l2_device.h b/chromium/media/gpu/v4l2/v4l2_device.h
index 62262043721..50ddba9fa07 100644
--- a/chromium/media/gpu/v4l2/v4l2_device.h
+++ b/chromium/media/gpu/v4l2/v4l2_device.h
@@ -20,7 +20,6 @@
#include "base/containers/flat_map.h"
#include "base/files/scoped_file.h"
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "media/base/video_codecs.h"
#include "media/base/video_decoder_config.h"
@@ -32,6 +31,7 @@
#include "media/gpu/v4l2/v4l2_device_poller.h"
#include "media/video/video_decode_accelerator.h"
#include "media/video/video_encode_accelerator.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/native_pixmap_handle.h"
#include "ui/gl/gl_bindings.h"
@@ -304,7 +304,7 @@ class MEDIA_GPU_EXPORT V4L2Queue
// format is returned. It is guaranteed to feature the specified |fourcc|,
// but any other parameter (including |size| and |buffer_size| may have been
// adjusted by the driver, so the caller must check their values.
- base::Optional<struct v4l2_format> SetFormat(uint32_t fourcc,
+ absl::optional<struct v4l2_format> SetFormat(uint32_t fourcc,
const gfx::Size& size,
size_t buffer_size)
WARN_UNUSED_RESULT;
@@ -313,16 +313,16 @@ class MEDIA_GPU_EXPORT V4L2Queue
// be called anytime.
// Returns an adjusted V4L2 format if |fourcc| is supported by the queue, or
// |nullopt| if |fourcc| is not supported or an ioctl error happened.
- base::Optional<struct v4l2_format> TryFormat(uint32_t fourcc,
+ absl::optional<struct v4l2_format> TryFormat(uint32_t fourcc,
const gfx::Size& size,
size_t buffer_size)
WARN_UNUSED_RESULT;
// Returns the currently set format on the queue. The result is returned as
- // a std::pair where the first member is the format, or base::nullopt if the
+ // a std::pair where the first member is the format, or absl::nullopt if the
// format could not be obtained due to an ioctl error. The second member is
// only used in case of an error and contains the |errno| set by the failing
- // ioctl. If the first member is not base::nullopt, the second member will
+ // ioctl. If the first member is not absl::nullopt, the second member will
// always be zero.
//
// If the second member is 0, then the first member is guaranteed to have
@@ -332,11 +332,11 @@ class MEDIA_GPU_EXPORT V4L2Queue
// This pair is used because not all failures to get the format are
// necessarily errors, so we need to way to let the use decide whether it
// is one or not.
- std::pair<base::Optional<struct v4l2_format>, int> GetFormat();
+ std::pair<absl::optional<struct v4l2_format>, int> GetFormat();
// Codec-specific method to get the visible rectangle of the queue, using the
// VIDIOC_G_SELECTION ioctl if available, or VIDIOC_G_CROP as a fallback.
- base::Optional<gfx::Rect> GetVisibleRect();
+ absl::optional<gfx::Rect> GetVisibleRect();
// Allocate |count| buffers for the current format of this queue, with a
// specific |memory| allocation, and returns the number of buffers allocated
@@ -367,13 +367,13 @@ class MEDIA_GPU_EXPORT V4L2Queue
//
// If the caller discards the returned reference, the underlying buffer is
// made available to clients again.
- base::Optional<V4L2WritableBufferRef> GetFreeBuffer();
+ absl::optional<V4L2WritableBufferRef> GetFreeBuffer();
// Return the buffer at index |requested_buffer_id|, if it is available at
// this time.
//
// If the buffer is currently in use or the provided index is invalid,
- // return |base::nullopt|.
- base::Optional<V4L2WritableBufferRef> GetFreeBuffer(
+ // return |absl::nullopt|.
+ absl::optional<V4L2WritableBufferRef> GetFreeBuffer(
size_t requested_buffer_id);
// Return a V4L2 buffer suitable for the passed VideoFrame.
//
@@ -390,7 +390,7 @@ class MEDIA_GPU_EXPORT V4L2Queue
// since it will maximize performance in that case provided the number of
// different VideoFrames passed to this method does not exceed the number of
// V4L2 buffers allocated on the queue.
- base::Optional<V4L2WritableBufferRef> GetFreeBufferForFrame(
+ absl::optional<V4L2WritableBufferRef> GetFreeBufferForFrame(
const VideoFrame& frame);
// Attempt to dequeue a buffer, and return a reference to it if one was
@@ -433,7 +433,7 @@ class MEDIA_GPU_EXPORT V4L2Queue
// TODO (b/166275274) : Remove this once V4L2 properly supports modifiers.
// Out of band method to configure V4L2 for modifier use.
- base::Optional<struct v4l2_format> SetModifierFormat(uint64_t modifier,
+ absl::optional<struct v4l2_format> SetModifierFormat(uint64_t modifier,
const gfx::Size& size);
private:
@@ -450,7 +450,7 @@ class MEDIA_GPU_EXPORT V4L2Queue
bool supports_requests_ = false;
size_t planes_count_ = 0;
// Current format as set by SetFormat.
- base::Optional<struct v4l2_format> current_format_;
+ absl::optional<struct v4l2_format> current_format_;
std::vector<std::unique_ptr<V4L2Buffer>> buffers_;
@@ -520,7 +520,7 @@ class MEDIA_GPU_EXPORT V4L2RequestRef : public V4L2RequestRefBase {
// Apply buffer to the request.
bool ApplyQueueBuffer(struct v4l2_buffer* buffer) const;
// Submits the request to the driver.
- base::Optional<V4L2SubmittedRequestRef> Submit() &&;
+ absl::optional<V4L2SubmittedRequestRef> Submit() &&;
private:
friend class V4L2RequestsQueue;
@@ -565,7 +565,7 @@ class MEDIA_GPU_EXPORT V4L2RequestsQueue {
public:
// Gets a free request. If no request is available, a non-valid request
// reference will be returned.
- base::Optional<V4L2RequestRef> GetFreeRequest();
+ absl::optional<V4L2RequestRef> GetFreeRequest();
private:
// File descriptor of the media device (/dev/mediaX) from which requests
@@ -577,7 +577,7 @@ class MEDIA_GPU_EXPORT V4L2RequestsQueue {
std::queue<V4L2Request*> free_requests_;
// Returns a new request file descriptor.
- base::Optional<base::ScopedFD> CreateRequestFD();
+ absl::optional<base::ScopedFD> CreateRequestFD();
friend class V4L2Request;
// Returns a request to the queue after being used.
@@ -610,8 +610,8 @@ class MEDIA_GPU_EXPORT V4L2Device
static int32_t H264LevelIdcToV4L2H264Level(uint8_t level_idc);
// Composes VideoFrameLayout based on v4l2_format.
- // If error occurs, it returns base::nullopt.
- static base::Optional<VideoFrameLayout> V4L2FormatToVideoFrameLayout(
+ // If error occurs, it returns absl::nullopt.
+ static absl::optional<VideoFrameLayout> V4L2FormatToVideoFrameLayout(
const struct v4l2_format& format);
// Returns number of planes of |pix_fmt|.
@@ -758,7 +758,7 @@ class MEDIA_GPU_EXPORT V4L2Device
void SchedulePoll();
// Attempt to dequeue a V4L2 event and return it.
- base::Optional<struct v4l2_event> DequeueEvent();
+ absl::optional<struct v4l2_event> DequeueEvent();
// Returns requests queue to get free requests. A null pointer is returned if
// the queue creation failed or if requests are not supported.
@@ -773,9 +773,9 @@ class MEDIA_GPU_EXPORT V4L2Device
std::vector<V4L2ExtCtrl> ctrls,
V4L2RequestRef* request_ref = nullptr);
- // Get the value of a single control, or base::nullopt of the control is not
+ // Get the value of a single control, or absl::nullopt of the control is not
// exposed by the device.
- base::Optional<struct v4l2_ext_control> GetCtrl(uint32_t ctrl_id);
+ absl::optional<struct v4l2_ext_control> GetCtrl(uint32_t ctrl_id);
// Set periodic keyframe placement (group of pictures length)
bool SetGOPLength(uint32_t gop_length);
diff --git a/chromium/media/gpu/v4l2/v4l2_framerate_control.cc b/chromium/media/gpu/v4l2/v4l2_framerate_control.cc
new file mode 100644
index 00000000000..6ba06543d51
--- /dev/null
+++ b/chromium/media/gpu/v4l2/v4l2_framerate_control.cc
@@ -0,0 +1,129 @@
+// Copyright 2021 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 "media/gpu/v4l2/v4l2_framerate_control.h"
+
+#include "base/sequence_checker.h"
+
+namespace media {
+
+static constexpr int kMovingAverageWindowSize = 32;
+static constexpr base::TimeDelta kFrameIntervalFor120fps =
+ base::TimeDelta::FromMilliseconds(8);
+static constexpr base::TimeDelta kFrameIntervalFor24fps =
+ base::TimeDelta::FromMilliseconds(41);
+
+V4L2FrameRateControl::V4L2FrameRateControl(
+ scoped_refptr<V4L2Device> device,
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : device_(device),
+ framerate_control_present_(FrameRateControlPresent()),
+ current_frame_duration_avg_ms_(0),
+ last_frame_display_time_(base::TimeTicks::Now()),
+ frame_duration_moving_average_(kMovingAverageWindowSize),
+ task_runner_(task_runner),
+ weak_this_factory_(this) {}
+
+V4L2FrameRateControl::~V4L2FrameRateControl() = default;
+
+void V4L2FrameRateControl::UpdateFrameRate() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if ((frame_duration_moving_average_.count() <
+ frame_duration_moving_average_.depth())) {
+ return;
+ }
+
+ const base::TimeDelta frame_duration_avg =
+ frame_duration_moving_average_.Average();
+
+ if (frame_duration_avg > kFrameIntervalFor120fps &&
+ frame_duration_avg < kFrameIntervalFor24fps &&
+ frame_duration_avg.InMilliseconds() != current_frame_duration_avg_ms_) {
+ current_frame_duration_avg_ms_ = frame_duration_avg.InMilliseconds();
+
+ struct v4l2_streamparm parms;
+ memset(&parms, 0, sizeof(parms));
+ parms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ parms.parm.output.timeperframe.numerator = current_frame_duration_avg_ms_;
+ parms.parm.output.timeperframe.denominator = 1000L;
+
+ const auto result = device_->Ioctl(VIDIOC_S_PARM, &parms);
+ LOG_IF(ERROR, result != 0) << "Failed to issue VIDIOC_S_PARM command";
+
+ VLOG(1) << "Average framerate: " << frame_duration_avg.ToHz();
+ }
+}
+
+// static
+void V4L2FrameRateControl::RecordFrameDurationThunk(
+ base::WeakPtr<V4L2FrameRateControl> weak_this,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ if (task_runner->RunsTasksInCurrentSequence()) {
+ if (weak_this) {
+ weak_this->RecordFrameDuration();
+ }
+ } else {
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&V4L2FrameRateControl::RecordFrameDuration, weak_this));
+ }
+}
+
+void V4L2FrameRateControl::RecordFrameDuration() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ constexpr base::TimeDelta kMaxFrameInterval =
+ base::TimeDelta::FromMilliseconds(500);
+ const base::TimeTicks frame_display_time = base::TimeTicks::Now();
+ const base::TimeDelta duration =
+ frame_display_time - last_frame_display_time_;
+
+ // Frames are expected to be returned at a consistent cadence because the
+ // durations are recorded after the frame is displayed, but this isn't always
+ // the case. If the video is not visible, then the frames will be returned
+ // as soon as they are decoded. The window needs to be large enough to
+ // handle this scenario. The video may also be paused, in which case there
+ // could be a large duration. In this case, reset the filter.
+ if (duration > kMaxFrameInterval)
+ frame_duration_moving_average_.Reset();
+ else
+ frame_duration_moving_average_.AddSample(duration);
+
+ last_frame_display_time_ = frame_display_time;
+
+ UpdateFrameRate();
+}
+
+void V4L2FrameRateControl::AttachToVideoFrame(
+ scoped_refptr<VideoFrame>& video_frame) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!framerate_control_present_)
+ return;
+
+ video_frame->AddDestructionObserver(
+ base::BindOnce(&V4L2FrameRateControl::RecordFrameDurationThunk,
+ weak_this_factory_.GetWeakPtr(), task_runner_));
+}
+
+bool V4L2FrameRateControl::FrameRateControlPresent() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(device_);
+
+ struct v4l2_streamparm parms;
+ memset(&parms, 0, sizeof(parms));
+ parms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ // Try to set the framerate to 30fps to see if the control is available.
+ // VIDIOC_G_PARM can not be used as it does not return the current framerate.
+ parms.parm.output.timeperframe.numerator = 30;
+ parms.parm.output.timeperframe.denominator = 1000L;
+
+ if (device_->Ioctl(VIDIOC_S_PARM, &parms) != 0) {
+ VLOG(1) << "Failed to issue VIDIOC_S_PARM command";
+ return false;
+ }
+
+ return parms.parm.output.capability & V4L2_CAP_TIMEPERFRAME;
+}
+
+} // namespace media
diff --git a/chromium/media/gpu/v4l2/v4l2_framerate_control.h b/chromium/media/gpu/v4l2/v4l2_framerate_control.h
new file mode 100644
index 00000000000..c82d5c9949b
--- /dev/null
+++ b/chromium/media/gpu/v4l2/v4l2_framerate_control.h
@@ -0,0 +1,61 @@
+// Copyright 2021 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 MEDIA_GPU_V4L2_V4L2_FRAMERATE_CONTROL_H_
+#define MEDIA_GPU_V4L2_V4L2_FRAMERATE_CONTROL_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner.h"
+#include "base/time/time.h"
+#include "media/base/moving_average.h"
+#include "media/base/video_frame.h"
+#include "media/gpu/v4l2/v4l2_device.h"
+
+namespace media {
+
+// Some hardware decoder implementations (Qualcomm) need to know the framerate
+// of the content being decoded. On these platforms the hardware uses the
+// framerate to allocate resources correctly. The number of simultaneous
+// contexts supported is dependent on hardware usage, i.e. only 1 4KP60 decode
+// may be supported but if the framerate is reduce to 30 fps, 2 4KP30 clips
+// can be decoded simultaneously.
+class V4L2FrameRateControl {
+ public:
+ V4L2FrameRateControl(scoped_refptr<V4L2Device> device,
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
+ ~V4L2FrameRateControl();
+
+ // Trampoline method for VideoFrame destructor callbacks to be directed
+ // to this class' task runner.
+ static void RecordFrameDurationThunk(
+ base::WeakPtr<V4L2FrameRateControl> weak_this,
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
+
+ // Called from the VideoFrame destructor. Stores the duration between
+ // subsequent video frames into the moving average.
+ void RecordFrameDuration();
+
+ // Register this class as a VideoFrame destructor observer.
+ void AttachToVideoFrame(scoped_refptr<VideoFrame>& video_frame);
+
+ private:
+ void UpdateFrameRate();
+ bool FrameRateControlPresent();
+
+ scoped_refptr<V4L2Device> device_;
+ const bool framerate_control_present_;
+ int64_t current_frame_duration_avg_ms_;
+ base::TimeTicks last_frame_display_time_;
+ MovingAverage frame_duration_moving_average_;
+
+ const scoped_refptr<base::SequencedTaskRunner> task_runner_;
+ base::WeakPtrFactory<V4L2FrameRateControl> weak_this_factory_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+};
+
+} // namespace media
+
+#endif // MEDIA_GPU_V4L2_V4L2_FRAMERATE_CONTROL_H_
diff --git a/chromium/media/gpu/v4l2/v4l2_h264_accelerator.cc b/chromium/media/gpu/v4l2/v4l2_h264_accelerator.cc
index 5afa0cd7012..26616559494 100644
--- a/chromium/media/gpu/v4l2/v4l2_h264_accelerator.cc
+++ b/chromium/media/gpu/v4l2/v4l2_h264_accelerator.cc
@@ -44,32 +44,6 @@ class V4L2H264Picture : public H264Picture {
DISALLOW_COPY_AND_ASSIGN(V4L2H264Picture);
};
-// static
-bool V4L2H264Accelerator::SupportsUpstreamABI(V4L2Device* device) {
- struct v4l2_querymenu qmenu;
-
- // This accelerator currently supports frame-based decoding only. Print an
- // error at runtime if we try to use it with a slice-based decoder.
- memset(&qmenu, 0, sizeof(qmenu));
- qmenu.id = V4L2_CID_STATELESS_H264_DECODE_MODE;
- qmenu.index = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED;
-
- if (device->Ioctl(VIDIOC_QUERYMENU, &qmenu) < 0) {
- switch (errno) {
- case EINVAL:
- VLOGF(1)
- << "This decoder does not support the frame-based stateless API";
- return false;
- default:
- VPLOGF(1) << "Error while checking for H264_DECODE_MODE control";
- return false;
- }
- }
-
- VLOGF(1) << "This decoder supports the frame-based stateless API";
- return true;
-}
-
V4L2H264Accelerator::V4L2H264Accelerator(
V4L2DecodeSurfaceHandler* surface_handler,
V4L2Device* device)
@@ -322,14 +296,6 @@ H264Decoder::H264Accelerator::Status V4L2H264Accelerator::SubmitSlice(
SHDR_TO_V4L2DPARM(pic_order_cnt_bit_size);
#undef SHDR_TO_V4L2DPARM
-#define SET_V4L2_DPARM_FLAG_IF(cond, flag) \
- priv_->v4l2_decode_param.flags |= ((slice_hdr->cond) ? (flag) : 0)
- SET_V4L2_DPARM_FLAG_IF(idr_pic_flag, V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC);
- SET_V4L2_DPARM_FLAG_IF(field_pic_flag, V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC);
- SET_V4L2_DPARM_FLAG_IF(bottom_field_flag,
- V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD);
-#undef SET_V4L2_DPARM_FLAG_IF
-
scoped_refptr<V4L2DecodeSurface> dec_surface =
H264PictureToV4L2DecodeSurface(pic.get());
@@ -353,9 +319,24 @@ H264Decoder::H264Accelerator::Status V4L2H264Accelerator::SubmitDecode(
scoped_refptr<V4L2DecodeSurface> dec_surface =
H264PictureToV4L2DecodeSurface(pic.get());
- if (pic->idr) {
- priv_->v4l2_decode_param.flags |= 1;
+
+ switch (pic->field) {
+ case H264Picture::FIELD_NONE:
+ priv_->v4l2_decode_param.flags = 0;
+ break;
+ case H264Picture::FIELD_TOP:
+ priv_->v4l2_decode_param.flags = V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC;
+ break;
+ case H264Picture::FIELD_BOTTOM:
+ priv_->v4l2_decode_param.flags =
+ (V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC |
+ V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD);
+ break;
}
+
+ if (pic->idr)
+ priv_->v4l2_decode_param.flags |= V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC;
+
priv_->v4l2_decode_param.top_field_order_cnt = pic->top_field_order_cnt;
priv_->v4l2_decode_param.bottom_field_order_cnt = pic->bottom_field_order_cnt;
diff --git a/chromium/media/gpu/v4l2/v4l2_h264_accelerator.h b/chromium/media/gpu/v4l2/v4l2_h264_accelerator.h
index 7d1f2893451..38b90b1494f 100644
--- a/chromium/media/gpu/v4l2/v4l2_h264_accelerator.h
+++ b/chromium/media/gpu/v4l2/v4l2_h264_accelerator.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_GPU_V4L2_V4L2_H264_ACCELERATOR_UPSTREAM_H_
-#define MEDIA_GPU_V4L2_V4L2_H264_ACCELERATOR_UPSTREAM_H_
+#ifndef MEDIA_GPU_V4L2_V4L2_H264_ACCELERATOR_H_
+#define MEDIA_GPU_V4L2_V4L2_H264_ACCELERATOR_H_
#include <memory>
#include <vector>
@@ -24,10 +24,6 @@ class V4L2H264Accelerator : public H264Decoder::H264Accelerator {
public:
using Status = H264Decoder::H264Accelerator::Status;
- // Checks whether drivers support the upstream ABI or whether we should
- // fallback to the V4L2ChromeH264Accelerator.
- static bool SupportsUpstreamABI(V4L2Device* device);
-
explicit V4L2H264Accelerator(V4L2DecodeSurfaceHandler* surface_handler,
V4L2Device* device);
~V4L2H264Accelerator() override;
@@ -71,4 +67,4 @@ class V4L2H264Accelerator : public H264Decoder::H264Accelerator {
} // namespace media
-#endif // MEDIA_GPU_V4L2_V4L2_H264_ACCELERATOR_UPSTREAM_H_
+#endif // MEDIA_GPU_V4L2_V4L2_H264_ACCELERATOR_H_
diff --git a/chromium/media/gpu/v4l2/v4l2_h264_accelerator_chromium.cc b/chromium/media/gpu/v4l2/v4l2_h264_accelerator_chromium.cc
deleted file mode 100644
index 672cc7fb32a..00000000000
--- a/chromium/media/gpu/v4l2/v4l2_h264_accelerator_chromium.cc
+++ /dev/null
@@ -1,491 +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 "media/gpu/v4l2/v4l2_h264_accelerator_chromium.h"
-
-// TODO(987856): prevent legacy headers being included from videodev2.h until
-// v4.14
-// support is deprecated.
-#define _H264_CTRLS_LEGACY_H_
-
-#include <linux/media/h264-ctrls.h>
-#include <linux/videodev2.h>
-#include <type_traits>
-
-#include "base/logging.h"
-#include "base/stl_util.h"
-#include "media/gpu/macros.h"
-#include "media/gpu/v4l2/v4l2_decode_surface.h"
-#include "media/gpu/v4l2/v4l2_decode_surface_handler.h"
-#include "media/gpu/v4l2/v4l2_device.h"
-
-namespace media {
-
-// This struct contains the kernel-specific parts of the H264 acceleration,
-// that we don't want to expose in the .h file since they may differ from
-// upstream.
-struct V4L2H264AcceleratorPrivate {
- // TODO(posciak): This should be queried from hardware once supported.
- static constexpr size_t kMaxSlices = 16;
-
- struct v4l2_ctrl_h264_slice_params v4l2_slice_params[kMaxSlices];
- struct v4l2_ctrl_h264_decode_params v4l2_decode_param;
-};
-
-class V4L2H264Picture : public H264Picture {
- public:
- explicit V4L2H264Picture(scoped_refptr<V4L2DecodeSurface> dec_surface)
- : dec_surface_(std::move(dec_surface)) {}
-
- V4L2H264Picture* AsV4L2H264Picture() override { return this; }
- scoped_refptr<V4L2DecodeSurface> dec_surface() { return dec_surface_; }
-
- private:
- ~V4L2H264Picture() override {}
-
- scoped_refptr<V4L2DecodeSurface> dec_surface_;
-
- DISALLOW_COPY_AND_ASSIGN(V4L2H264Picture);
-};
-
-V4L2ChromiumH264Accelerator::V4L2ChromiumH264Accelerator(
- V4L2DecodeSurfaceHandler* surface_handler,
- V4L2Device* device)
- : num_slices_(0),
- surface_handler_(surface_handler),
- device_(device),
- priv_(std::make_unique<V4L2H264AcceleratorPrivate>()) {
- DCHECK(surface_handler_);
-}
-
-V4L2ChromiumH264Accelerator::~V4L2ChromiumH264Accelerator() {}
-
-scoped_refptr<H264Picture> V4L2ChromiumH264Accelerator::CreateH264Picture() {
- scoped_refptr<V4L2DecodeSurface> dec_surface =
- surface_handler_->CreateSurface();
- if (!dec_surface)
- return nullptr;
-
- return new V4L2H264Picture(dec_surface);
-}
-
-void V4L2ChromiumH264Accelerator::H264PictureListToDPBIndicesList(
- const H264Picture::Vector& src_pic_list,
- uint8_t dst_list[kDPBIndicesListSize]) {
- size_t i;
- for (i = 0; i < src_pic_list.size() && i < kDPBIndicesListSize; ++i) {
- const H264Picture* pic = (src_pic_list[i]).get();
- dst_list[i] = pic ? pic->dpb_position : VIDEO_MAX_FRAME;
- }
-
- while (i < kDPBIndicesListSize)
- dst_list[i++] = VIDEO_MAX_FRAME;
-}
-
-void V4L2ChromiumH264Accelerator::H264DPBToV4L2DPB(
- const H264DPB& dpb,
- std::vector<scoped_refptr<V4L2DecodeSurface>>* ref_surfaces) {
- memset(priv_->v4l2_decode_param.dpb, 0, sizeof(priv_->v4l2_decode_param.dpb));
- size_t i = 0;
- for (const auto& pic : dpb) {
- if (i >= base::size(priv_->v4l2_decode_param.dpb)) {
- VLOGF(1) << "Invalid DPB size";
- break;
- }
-
- int index = VIDEO_MAX_FRAME;
- if (!pic->nonexisting) {
- scoped_refptr<V4L2DecodeSurface> dec_surface =
- H264PictureToV4L2DecodeSurface(pic.get());
- index = dec_surface->GetReferenceID();
- ref_surfaces->push_back(dec_surface);
- }
-
- struct v4l2_h264_dpb_entry& entry = priv_->v4l2_decode_param.dpb[i++];
- entry.reference_ts = index;
- entry.frame_num = pic->frame_num;
- entry.pic_num = pic->pic_num;
- entry.top_field_order_cnt = pic->top_field_order_cnt;
- entry.bottom_field_order_cnt = pic->bottom_field_order_cnt;
- entry.flags = (pic->ref ? V4L2_H264_DPB_ENTRY_FLAG_ACTIVE : 0) |
- (pic->long_term ? V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM : 0);
- }
-}
-
-H264Decoder::H264Accelerator::Status V4L2ChromiumH264Accelerator::SubmitFrameMetadata(
- const H264SPS* sps,
- const H264PPS* pps,
- const H264DPB& dpb,
- const H264Picture::Vector& ref_pic_listp0,
- const H264Picture::Vector& ref_pic_listb0,
- const H264Picture::Vector& ref_pic_listb1,
- scoped_refptr<H264Picture> pic) {
- struct v4l2_ext_control ctrl;
- std::vector<struct v4l2_ext_control> ctrls;
-
- struct v4l2_ctrl_h264_sps v4l2_sps;
- memset(&v4l2_sps, 0, sizeof(v4l2_sps));
- v4l2_sps.constraint_set_flags =
- (sps->constraint_set0_flag ? V4L2_H264_SPS_CONSTRAINT_SET0_FLAG : 0) |
- (sps->constraint_set1_flag ? V4L2_H264_SPS_CONSTRAINT_SET1_FLAG : 0) |
- (sps->constraint_set2_flag ? V4L2_H264_SPS_CONSTRAINT_SET2_FLAG : 0) |
- (sps->constraint_set3_flag ? V4L2_H264_SPS_CONSTRAINT_SET3_FLAG : 0) |
- (sps->constraint_set4_flag ? V4L2_H264_SPS_CONSTRAINT_SET4_FLAG : 0) |
- (sps->constraint_set5_flag ? V4L2_H264_SPS_CONSTRAINT_SET5_FLAG : 0);
-#define SPS_TO_V4L2SPS(a) v4l2_sps.a = sps->a
- SPS_TO_V4L2SPS(profile_idc);
- SPS_TO_V4L2SPS(level_idc);
- SPS_TO_V4L2SPS(seq_parameter_set_id);
- SPS_TO_V4L2SPS(chroma_format_idc);
- SPS_TO_V4L2SPS(bit_depth_luma_minus8);
- SPS_TO_V4L2SPS(bit_depth_chroma_minus8);
- SPS_TO_V4L2SPS(log2_max_frame_num_minus4);
- SPS_TO_V4L2SPS(pic_order_cnt_type);
- SPS_TO_V4L2SPS(log2_max_pic_order_cnt_lsb_minus4);
- SPS_TO_V4L2SPS(offset_for_non_ref_pic);
- SPS_TO_V4L2SPS(offset_for_top_to_bottom_field);
- SPS_TO_V4L2SPS(num_ref_frames_in_pic_order_cnt_cycle);
-
- static_assert(std::extent<decltype(v4l2_sps.offset_for_ref_frame)>() ==
- std::extent<decltype(sps->offset_for_ref_frame)>(),
- "offset_for_ref_frame arrays must be same size");
- for (size_t i = 0; i < base::size(v4l2_sps.offset_for_ref_frame); ++i)
- v4l2_sps.offset_for_ref_frame[i] = sps->offset_for_ref_frame[i];
- SPS_TO_V4L2SPS(max_num_ref_frames);
- SPS_TO_V4L2SPS(pic_width_in_mbs_minus1);
- SPS_TO_V4L2SPS(pic_height_in_map_units_minus1);
-#undef SPS_TO_V4L2SPS
-
-#define SET_V4L2_SPS_FLAG_IF(cond, flag) \
- v4l2_sps.flags |= ((sps->cond) ? (flag) : 0)
- SET_V4L2_SPS_FLAG_IF(separate_colour_plane_flag,
- V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
- SET_V4L2_SPS_FLAG_IF(qpprime_y_zero_transform_bypass_flag,
- V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
- SET_V4L2_SPS_FLAG_IF(delta_pic_order_always_zero_flag,
- V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
- SET_V4L2_SPS_FLAG_IF(gaps_in_frame_num_value_allowed_flag,
- V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED);
- SET_V4L2_SPS_FLAG_IF(frame_mbs_only_flag, V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
- SET_V4L2_SPS_FLAG_IF(mb_adaptive_frame_field_flag,
- V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
- SET_V4L2_SPS_FLAG_IF(direct_8x8_inference_flag,
- V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
-#undef SET_V4L2_SPS_FLAG_IF
- memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_VIDEO_H264_SPS;
- ctrl.size = sizeof(v4l2_sps);
- ctrl.ptr = &v4l2_sps;
- ctrls.push_back(ctrl);
-
- struct v4l2_ctrl_h264_pps v4l2_pps;
- memset(&v4l2_pps, 0, sizeof(v4l2_pps));
-#define PPS_TO_V4L2PPS(a) v4l2_pps.a = pps->a
- PPS_TO_V4L2PPS(pic_parameter_set_id);
- PPS_TO_V4L2PPS(seq_parameter_set_id);
- PPS_TO_V4L2PPS(num_slice_groups_minus1);
- PPS_TO_V4L2PPS(num_ref_idx_l0_default_active_minus1);
- PPS_TO_V4L2PPS(num_ref_idx_l1_default_active_minus1);
- PPS_TO_V4L2PPS(weighted_bipred_idc);
- PPS_TO_V4L2PPS(pic_init_qp_minus26);
- PPS_TO_V4L2PPS(pic_init_qs_minus26);
- PPS_TO_V4L2PPS(chroma_qp_index_offset);
- PPS_TO_V4L2PPS(second_chroma_qp_index_offset);
-#undef PPS_TO_V4L2PPS
-
-#define SET_V4L2_PPS_FLAG_IF(cond, flag) \
- v4l2_pps.flags |= ((pps->cond) ? (flag) : 0)
- SET_V4L2_PPS_FLAG_IF(entropy_coding_mode_flag,
- V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
- SET_V4L2_PPS_FLAG_IF(
- bottom_field_pic_order_in_frame_present_flag,
- V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
- SET_V4L2_PPS_FLAG_IF(weighted_pred_flag, V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
- SET_V4L2_PPS_FLAG_IF(deblocking_filter_control_present_flag,
- V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
- SET_V4L2_PPS_FLAG_IF(constrained_intra_pred_flag,
- V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
- SET_V4L2_PPS_FLAG_IF(redundant_pic_cnt_present_flag,
- V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
- SET_V4L2_PPS_FLAG_IF(transform_8x8_mode_flag,
- V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
- SET_V4L2_PPS_FLAG_IF(pic_scaling_matrix_present_flag,
- V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT);
-#undef SET_V4L2_PPS_FLAG_IF
- memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_VIDEO_H264_PPS;
- ctrl.size = sizeof(v4l2_pps);
- ctrl.ptr = &v4l2_pps;
- ctrls.push_back(ctrl);
-
- struct v4l2_ctrl_h264_scaling_matrix v4l2_scaling_matrix;
- memset(&v4l2_scaling_matrix, 0, sizeof(v4l2_scaling_matrix));
-
- static_assert(
- std::extent<decltype(v4l2_scaling_matrix.scaling_list_4x4)>() <=
- std::extent<decltype(pps->scaling_list4x4)>() &&
- std::extent<decltype(v4l2_scaling_matrix.scaling_list_4x4[0])>() <=
- std::extent<decltype(pps->scaling_list4x4[0])>() &&
- std::extent<decltype(v4l2_scaling_matrix.scaling_list_8x8)>() <=
- std::extent<decltype(pps->scaling_list8x8)>() &&
- std::extent<decltype(v4l2_scaling_matrix.scaling_list_8x8[0])>() <=
- std::extent<decltype(pps->scaling_list8x8[0])>(),
- "scaling_lists must be of correct size");
- static_assert(
- std::extent<decltype(v4l2_scaling_matrix.scaling_list_4x4)>() <=
- std::extent<decltype(sps->scaling_list4x4)>() &&
- std::extent<decltype(v4l2_scaling_matrix.scaling_list_4x4[0])>() <=
- std::extent<decltype(sps->scaling_list4x4[0])>() &&
- std::extent<decltype(v4l2_scaling_matrix.scaling_list_8x8)>() <=
- std::extent<decltype(sps->scaling_list8x8)>() &&
- std::extent<decltype(v4l2_scaling_matrix.scaling_list_8x8[0])>() <=
- std::extent<decltype(sps->scaling_list8x8[0])>(),
- "scaling_lists must be of correct size");
-
- const auto* scaling_list4x4 = &sps->scaling_list4x4[0];
- const auto* scaling_list8x8 = &sps->scaling_list8x8[0];
- if (pps->pic_scaling_matrix_present_flag) {
- scaling_list4x4 = &pps->scaling_list4x4[0];
- scaling_list8x8 = &pps->scaling_list8x8[0];
- }
-
- for (size_t i = 0; i < base::size(v4l2_scaling_matrix.scaling_list_4x4);
- ++i) {
- for (size_t j = 0; j < base::size(v4l2_scaling_matrix.scaling_list_4x4[i]);
- ++j) {
- v4l2_scaling_matrix.scaling_list_4x4[i][j] = scaling_list4x4[i][j];
- }
- }
- for (size_t i = 0; i < base::size(v4l2_scaling_matrix.scaling_list_8x8);
- ++i) {
- for (size_t j = 0; j < base::size(v4l2_scaling_matrix.scaling_list_8x8[i]);
- ++j) {
- v4l2_scaling_matrix.scaling_list_8x8[i][j] = scaling_list8x8[i][j];
- }
- }
-
- memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX;
- ctrl.size = sizeof(v4l2_scaling_matrix);
- ctrl.ptr = &v4l2_scaling_matrix;
- ctrls.push_back(ctrl);
-
- scoped_refptr<V4L2DecodeSurface> dec_surface =
- H264PictureToV4L2DecodeSurface(pic.get());
-
- struct v4l2_ext_controls ext_ctrls;
- memset(&ext_ctrls, 0, sizeof(ext_ctrls));
- ext_ctrls.count = ctrls.size();
- ext_ctrls.controls = &ctrls[0];
- dec_surface->PrepareSetCtrls(&ext_ctrls);
- if (device_->Ioctl(VIDIOC_S_EXT_CTRLS, &ext_ctrls) != 0) {
- VPLOGF(1) << "ioctl() failed: VIDIOC_S_EXT_CTRLS";
- return Status::kFail;
- }
-
- H264PictureListToDPBIndicesList(ref_pic_listp0,
- priv_->v4l2_decode_param.ref_pic_list_p0);
- H264PictureListToDPBIndicesList(ref_pic_listb0,
- priv_->v4l2_decode_param.ref_pic_list_b0);
- H264PictureListToDPBIndicesList(ref_pic_listb1,
- priv_->v4l2_decode_param.ref_pic_list_b1);
-
- std::vector<scoped_refptr<V4L2DecodeSurface>> ref_surfaces;
- H264DPBToV4L2DPB(dpb, &ref_surfaces);
- dec_surface->SetReferenceSurfaces(ref_surfaces);
-
- return Status::kOk;
-}
-
-H264Decoder::H264Accelerator::Status V4L2ChromiumH264Accelerator::SubmitSlice(
- const H264PPS* pps,
- const H264SliceHeader* slice_hdr,
- const H264Picture::Vector& ref_pic_list0,
- const H264Picture::Vector& ref_pic_list1,
- scoped_refptr<H264Picture> pic,
- const uint8_t* data,
- size_t size,
- const std::vector<SubsampleEntry>& subsamples) {
- if (num_slices_ == priv_->kMaxSlices) {
- VLOGF(1) << "Over limit of supported slices per frame";
- return Status::kFail;
- }
-
- struct v4l2_ctrl_h264_slice_params& v4l2_slice_param =
- priv_->v4l2_slice_params[num_slices_++];
- memset(&v4l2_slice_param, 0, sizeof(v4l2_slice_param));
-
- v4l2_slice_param.size = size;
-#define SHDR_TO_V4L2SPARM(a) v4l2_slice_param.a = slice_hdr->a
- SHDR_TO_V4L2SPARM(header_bit_size);
- SHDR_TO_V4L2SPARM(first_mb_in_slice);
- SHDR_TO_V4L2SPARM(slice_type);
- SHDR_TO_V4L2SPARM(pic_parameter_set_id);
- SHDR_TO_V4L2SPARM(colour_plane_id);
- SHDR_TO_V4L2SPARM(frame_num);
- SHDR_TO_V4L2SPARM(idr_pic_id);
- SHDR_TO_V4L2SPARM(pic_order_cnt_lsb);
- SHDR_TO_V4L2SPARM(delta_pic_order_cnt_bottom);
- SHDR_TO_V4L2SPARM(delta_pic_order_cnt0);
- SHDR_TO_V4L2SPARM(delta_pic_order_cnt1);
- SHDR_TO_V4L2SPARM(redundant_pic_cnt);
- SHDR_TO_V4L2SPARM(dec_ref_pic_marking_bit_size);
- SHDR_TO_V4L2SPARM(cabac_init_idc);
- SHDR_TO_V4L2SPARM(slice_qp_delta);
- SHDR_TO_V4L2SPARM(slice_qs_delta);
- SHDR_TO_V4L2SPARM(disable_deblocking_filter_idc);
- SHDR_TO_V4L2SPARM(slice_alpha_c0_offset_div2);
- SHDR_TO_V4L2SPARM(slice_beta_offset_div2);
- SHDR_TO_V4L2SPARM(num_ref_idx_l0_active_minus1);
- SHDR_TO_V4L2SPARM(num_ref_idx_l1_active_minus1);
- SHDR_TO_V4L2SPARM(pic_order_cnt_bit_size);
-#undef SHDR_TO_V4L2SPARM
-
-#define SET_V4L2_SPARM_FLAG_IF(cond, flag) \
- v4l2_slice_param.flags |= ((slice_hdr->cond) ? (flag) : 0)
- SET_V4L2_SPARM_FLAG_IF(field_pic_flag, V4L2_H264_SLICE_FLAG_FIELD_PIC);
- SET_V4L2_SPARM_FLAG_IF(bottom_field_flag, V4L2_H264_SLICE_FLAG_BOTTOM_FIELD);
- SET_V4L2_SPARM_FLAG_IF(direct_spatial_mv_pred_flag,
- V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED);
- SET_V4L2_SPARM_FLAG_IF(sp_for_switch_flag,
- V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH);
-#undef SET_V4L2_SPARM_FLAG_IF
-
- struct v4l2_h264_pred_weight_table* pred_weight_table =
- &v4l2_slice_param.pred_weight_table;
-
- if (((slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) &&
- pps->weighted_pred_flag) ||
- (slice_hdr->IsBSlice() && pps->weighted_bipred_idc == 1)) {
- pred_weight_table->luma_log2_weight_denom =
- slice_hdr->luma_log2_weight_denom;
- pred_weight_table->chroma_log2_weight_denom =
- slice_hdr->chroma_log2_weight_denom;
-
- struct v4l2_h264_weight_factors* factorsl0 =
- &pred_weight_table->weight_factors[0];
-
- for (int i = 0; i < 32; ++i) {
- factorsl0->luma_weight[i] =
- slice_hdr->pred_weight_table_l0.luma_weight[i];
- factorsl0->luma_offset[i] =
- slice_hdr->pred_weight_table_l0.luma_offset[i];
-
- for (int j = 0; j < 2; ++j) {
- factorsl0->chroma_weight[i][j] =
- slice_hdr->pred_weight_table_l0.chroma_weight[i][j];
- factorsl0->chroma_offset[i][j] =
- slice_hdr->pred_weight_table_l0.chroma_offset[i][j];
- }
- }
-
- if (slice_hdr->IsBSlice()) {
- struct v4l2_h264_weight_factors* factorsl1 =
- &pred_weight_table->weight_factors[1];
-
- for (int i = 0; i < 32; ++i) {
- factorsl1->luma_weight[i] =
- slice_hdr->pred_weight_table_l1.luma_weight[i];
- factorsl1->luma_offset[i] =
- slice_hdr->pred_weight_table_l1.luma_offset[i];
-
- for (int j = 0; j < 2; ++j) {
- factorsl1->chroma_weight[i][j] =
- slice_hdr->pred_weight_table_l1.chroma_weight[i][j];
- factorsl1->chroma_offset[i][j] =
- slice_hdr->pred_weight_table_l1.chroma_offset[i][j];
- }
- }
- }
- }
-
- H264PictureListToDPBIndicesList(ref_pic_list0,
- v4l2_slice_param.ref_pic_list0);
- H264PictureListToDPBIndicesList(ref_pic_list1,
- v4l2_slice_param.ref_pic_list1);
-
- scoped_refptr<V4L2DecodeSurface> dec_surface =
- H264PictureToV4L2DecodeSurface(pic.get());
-
- priv_->v4l2_decode_param.nal_ref_idc = slice_hdr->nal_ref_idc;
-
- // TODO(posciak): Don't add start code back here, but have it passed from
- // the parser.
- size_t data_copy_size = size + 3;
- std::unique_ptr<uint8_t[]> data_copy(new uint8_t[data_copy_size]);
- memset(data_copy.get(), 0, data_copy_size);
- data_copy[2] = 0x01;
- memcpy(data_copy.get() + 3, data, size);
- return surface_handler_->SubmitSlice(dec_surface.get(), data_copy.get(),
- data_copy_size)
- ? Status::kOk
- : Status::kFail;
-}
-
-H264Decoder::H264Accelerator::Status V4L2ChromiumH264Accelerator::SubmitDecode(
- scoped_refptr<H264Picture> pic) {
- scoped_refptr<V4L2DecodeSurface> dec_surface =
- H264PictureToV4L2DecodeSurface(pic.get());
-
- priv_->v4l2_decode_param.num_slices = num_slices_;
- if (pic->idr) {
- priv_->v4l2_decode_param.flags |= 1;
- }
- priv_->v4l2_decode_param.top_field_order_cnt = pic->top_field_order_cnt;
- priv_->v4l2_decode_param.bottom_field_order_cnt = pic->bottom_field_order_cnt;
-
- struct v4l2_ext_control ctrl;
- std::vector<struct v4l2_ext_control> ctrls;
-
- memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS;
- ctrl.size = sizeof(priv_->v4l2_slice_params);
- ctrl.ptr = priv_->v4l2_slice_params;
- ctrls.push_back(ctrl);
-
- memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS;
- ctrl.size = sizeof(priv_->v4l2_decode_param);
- ctrl.ptr = &priv_->v4l2_decode_param;
- ctrls.push_back(ctrl);
-
- struct v4l2_ext_controls ext_ctrls;
- memset(&ext_ctrls, 0, sizeof(ext_ctrls));
- ext_ctrls.count = ctrls.size();
- ext_ctrls.controls = &ctrls[0];
- dec_surface->PrepareSetCtrls(&ext_ctrls);
- if (device_->Ioctl(VIDIOC_S_EXT_CTRLS, &ext_ctrls) != 0) {
- VPLOGF(1) << "ioctl() failed: VIDIOC_S_EXT_CTRLS";
- return Status::kFail;
- }
-
- Reset();
-
- DVLOGF(4) << "Submitting decode for surface: " << dec_surface->ToString();
- surface_handler_->DecodeSurface(dec_surface);
- return Status::kOk;
-}
-
-bool V4L2ChromiumH264Accelerator::OutputPicture(scoped_refptr<H264Picture> pic) {
- // TODO(crbug.com/647725): Insert correct color space.
- surface_handler_->SurfaceReady(H264PictureToV4L2DecodeSurface(pic.get()),
- pic->bitstream_id(), pic->visible_rect(),
- VideoColorSpace());
- return true;
-}
-
-void V4L2ChromiumH264Accelerator::Reset() {
- num_slices_ = 0;
- memset(&priv_->v4l2_decode_param, 0, sizeof(priv_->v4l2_decode_param));
- memset(&priv_->v4l2_slice_params, 0, sizeof(priv_->v4l2_slice_params));
-}
-
-scoped_refptr<V4L2DecodeSurface>
-V4L2ChromiumH264Accelerator::H264PictureToV4L2DecodeSurface(H264Picture* pic) {
- V4L2H264Picture* v4l2_pic = pic->AsV4L2H264Picture();
- CHECK(v4l2_pic);
- return v4l2_pic->dec_surface();
-}
-
-} // namespace media
diff --git a/chromium/media/gpu/v4l2/v4l2_h264_accelerator_chromium.h b/chromium/media/gpu/v4l2/v4l2_h264_accelerator_chromium.h
deleted file mode 100644
index 0e0171f9766..00000000000
--- a/chromium/media/gpu/v4l2/v4l2_h264_accelerator_chromium.h
+++ /dev/null
@@ -1,78 +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 MEDIA_GPU_V4L2_V4L2_H264_ACCELERATOR_CHROMIUM_H_
-#define MEDIA_GPU_V4L2_V4L2_H264_ACCELERATOR_CHROMIUM_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "media/gpu/h264_decoder.h"
-#include "media/gpu/h264_dpb.h"
-
-namespace media {
-
-class V4L2Device;
-class V4L2DecodeSurface;
-class V4L2DecodeSurfaceHandler;
-struct V4L2H264AcceleratorPrivate;
-
-// H.264 accelerator supported the old Chromium-only ABI with the kernel.
-class V4L2ChromiumH264Accelerator : public H264Decoder::H264Accelerator {
- public:
- using Status = H264Decoder::H264Accelerator::Status;
-
- explicit V4L2ChromiumH264Accelerator(V4L2DecodeSurfaceHandler* surface_handler,
- V4L2Device* device);
- ~V4L2ChromiumH264Accelerator() override;
-
- // H264Decoder::H264Accelerator implementation.
- scoped_refptr<H264Picture> CreateH264Picture() override;
- Status SubmitFrameMetadata(const H264SPS* sps,
- const H264PPS* pps,
- const H264DPB& dpb,
- const H264Picture::Vector& ref_pic_listp0,
- const H264Picture::Vector& ref_pic_listb0,
- const H264Picture::Vector& ref_pic_listb1,
- scoped_refptr<H264Picture> pic) override;
- Status SubmitSlice(const H264PPS* pps,
- const H264SliceHeader* slice_hdr,
- const H264Picture::Vector& ref_pic_list0,
- const H264Picture::Vector& ref_pic_list1,
- scoped_refptr<H264Picture> pic,
- const uint8_t* data,
- size_t size,
- const std::vector<SubsampleEntry>& subsamples) override;
- Status SubmitDecode(scoped_refptr<H264Picture> pic) override;
- bool OutputPicture(scoped_refptr<H264Picture> pic) override;
- void Reset() override;
-
- private:
- // Max size of reference list.
- static constexpr size_t kDPBIndicesListSize = 32;
-
- void H264PictureListToDPBIndicesList(const H264Picture::Vector& src_pic_list,
- uint8_t dst_list[kDPBIndicesListSize]);
- void H264DPBToV4L2DPB(
- const H264DPB& dpb,
- std::vector<scoped_refptr<V4L2DecodeSurface>>* ref_surfaces);
- scoped_refptr<V4L2DecodeSurface> H264PictureToV4L2DecodeSurface(
- H264Picture* pic);
-
- size_t num_slices_;
- V4L2DecodeSurfaceHandler* const surface_handler_;
- V4L2Device* const device_;
-
- // Contains the kernel-specific structures that we don't want to expose
- // outside of the compilation unit.
- const std::unique_ptr<V4L2H264AcceleratorPrivate> priv_;
-
- DISALLOW_COPY_AND_ASSIGN(V4L2ChromiumH264Accelerator);
-};
-
-} // namespace media
-
-#endif // MEDIA_GPU_V4L2_V4L2_H264_ACCELERATOR_CHROMIUM_H_
diff --git a/chromium/media/gpu/v4l2/v4l2_image_processor_backend.cc b/chromium/media/gpu/v4l2/v4l2_image_processor_backend.cc
index a6d2ebae6c2..30097973821 100644
--- a/chromium/media/gpu/v4l2/v4l2_image_processor_backend.cc
+++ b/chromium/media/gpu/v4l2/v4l2_image_processor_backend.cc
@@ -56,12 +56,12 @@ enum v4l2_buf_type ToSingleV4L2Planar(enum v4l2_buf_type type) {
}
}
-base::Optional<gfx::GpuMemoryBufferHandle> CreateHandle(
+absl::optional<gfx::GpuMemoryBufferHandle> CreateHandle(
const VideoFrame* frame) {
gfx::GpuMemoryBufferHandle handle = CreateGpuMemoryBufferHandle(frame);
if (handle.is_null() || handle.type != gfx::NATIVE_PIXMAP)
- return base::nullopt;
+ return absl::nullopt;
return handle;
}
@@ -624,7 +624,7 @@ void V4L2ImageProcessorBackend::ProcessJobsTask() {
}
// We need one input and one output buffer to schedule the job
- base::Optional<V4L2WritableBufferRef> input_buffer;
+ absl::optional<V4L2WritableBufferRef> input_buffer;
// If we are using DMABUF frames, try to always obtain the same V4L2 buffer.
if (input_memory_type_ == V4L2_MEMORY_DMABUF) {
const VideoFrame& input_frame =
@@ -634,7 +634,7 @@ void V4L2ImageProcessorBackend::ProcessJobsTask() {
if (!input_buffer)
input_buffer = input_queue_->GetFreeBuffer();
- base::Optional<V4L2WritableBufferRef> output_buffer;
+ absl::optional<V4L2WritableBufferRef> output_buffer;
// If we are using DMABUF frames, try to always obtain the same V4L2 buffer.
if (output_memory_type_ == V4L2_MEMORY_DMABUF) {
const VideoFrame& output_frame =
@@ -906,7 +906,7 @@ void V4L2ImageProcessorBackend::EnqueueOutput(JobRecord* job_record,
// static
void V4L2ImageProcessorBackend::V4L2VFRecycleThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<V4L2ImageProcessorBackend>> image_processor,
+ absl::optional<base::WeakPtr<V4L2ImageProcessorBackend>> image_processor,
V4L2ReadableBufferRef buf) {
DVLOGF(4);
DCHECK(image_processor);
diff --git a/chromium/media/gpu/v4l2/v4l2_image_processor_backend.h b/chromium/media/gpu/v4l2/v4l2_image_processor_backend.h
index 4652bda62b7..e8a9629d584 100644
--- a/chromium/media/gpu/v4l2/v4l2_image_processor_backend.h
+++ b/chromium/media/gpu/v4l2/v4l2_image_processor_backend.h
@@ -17,13 +17,13 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "media/gpu/chromeos/image_processor_backend.h"
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/v4l2/v4l2_device.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
@@ -148,7 +148,7 @@ class MEDIA_GPU_EXPORT V4L2ImageProcessorBackend
// task to |device_task_runner_|.
static void V4L2VFRecycleThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<V4L2ImageProcessorBackend>> image_processor,
+ absl::optional<base::WeakPtr<V4L2ImageProcessorBackend>> image_processor,
V4L2ReadableBufferRef buf);
void V4L2VFRecycleTask(V4L2ReadableBufferRef buf);
diff --git a/chromium/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h b/chromium/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h
index f025ca06636..181b6b10019 100644
--- a/chromium/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h
+++ b/chromium/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h
@@ -24,7 +24,6 @@
#include "media/base/video_frame.h"
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/v4l2/v4l2_device.h"
-#include "media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h"
#include "media/parsers/jpeg_parser.h"
namespace {
@@ -330,7 +329,7 @@ class MEDIA_GPU_EXPORT V4L2JpegEncodeAccelerator
V4L2JpegEncodeAccelerator* parent_;
// Layout that represents the input data.
- base::Optional<VideoFrameLayout> device_input_layout_;
+ absl::optional<VideoFrameLayout> device_input_layout_;
// The V4L2Device this class is operating upon.
scoped_refptr<V4L2Device> device_;
diff --git a/chromium/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.cc b/chromium/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.cc
index e9d961454d6..f2ed447f5aa 100644
--- a/chromium/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.cc
+++ b/chromium/media/gpu/v4l2/v4l2_mjpeg_decode_accelerator.cc
@@ -17,8 +17,8 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/files/scoped_file.h"
+#include "base/memory/page_size.h"
#include "base/numerics/safe_conversions.h"
-#include "base/process/process_metrics.h"
#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "media/base/bitstream_buffer.h"
@@ -755,7 +755,7 @@ void V4L2MjpegDecodeAccelerator::DevicePollTask() {
bool V4L2MjpegDecodeAccelerator::DequeueSourceChangeEvent() {
DCHECK(decoder_task_runner_->BelongsToCurrentThread());
- if (base::Optional<struct v4l2_event> event = device_->DequeueEvent()) {
+ if (absl::optional<struct v4l2_event> event = device_->DequeueEvent()) {
if (event->type == V4L2_EVENT_SOURCE_CHANGE) {
VLOGF(2) << ": got source change event: " << event->u.src_change.changes;
if (event->u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION) {
diff --git a/chromium/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc b/chromium/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
index 771e3281a86..c09ed75e000 100644
--- a/chromium/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
+++ b/chromium/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
@@ -41,7 +41,6 @@
#include "media/gpu/macros.h"
#include "media/gpu/v4l2/v4l2_decode_surface.h"
#include "media/gpu/v4l2/v4l2_h264_accelerator.h"
-#include "media/gpu/v4l2/v4l2_h264_accelerator_chromium.h"
#include "media/gpu/v4l2/v4l2_h264_accelerator_legacy.h"
#include "media/gpu/v4l2/v4l2_image_processor_backend.h"
#include "media/gpu/v4l2/v4l2_utils.h"
@@ -297,14 +296,9 @@ bool V4L2SliceVideoDecodeAccelerator::Initialize(const Config& config,
if (video_profile_ >= H264PROFILE_MIN && video_profile_ <= H264PROFILE_MAX) {
if (supports_requests_) {
- if (V4L2H264Accelerator::SupportsUpstreamABI(device_.get()))
- decoder_ = std::make_unique<H264Decoder>(
- std::make_unique<V4L2H264Accelerator>(this, device_.get()),
- video_profile_);
- else
- decoder_ = std::make_unique<H264Decoder>(
- std::make_unique<V4L2ChromiumH264Accelerator>(this, device_.get()),
- video_profile_);
+ decoder_ = std::make_unique<H264Decoder>(
+ std::make_unique<V4L2H264Accelerator>(this, device_.get()),
+ video_profile_);
} else {
decoder_ = std::make_unique<H264Decoder>(
std::make_unique<V4L2LegacyH264Accelerator>(this, device_.get()),
@@ -519,7 +513,7 @@ bool V4L2SliceVideoDecodeAccelerator::SetupFormats() {
// output format or not may depend on the input format.
memset(&fmtdesc, 0, sizeof(fmtdesc));
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- output_format_fourcc_ = base::nullopt;
+ output_format_fourcc_ = absl::nullopt;
output_planes_count_ = 0;
while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
auto fourcc = Fourcc::FromV4L2PixFmt(fmtdesc.pixelformat);
@@ -1478,9 +1472,18 @@ void V4L2SliceVideoDecodeAccelerator::CreateGLImageFor(
gl::ScopedTextureBinder bind_restore(gl_device->GetTextureTarget(),
texture_id);
bool ret = gl_image->BindTexImage(gl_device->GetTextureTarget());
- DCHECK(ret);
- bind_image_cb_.Run(client_texture_id, gl_device->GetTextureTarget(), gl_image,
- true);
+ if (!ret) {
+ LOG(ERROR) << "Error while binding tex image";
+ NOTIFY_ERROR(PLATFORM_FAILURE);
+ return;
+ }
+ ret = bind_image_cb_.Run(client_texture_id, gl_device->GetTextureTarget(),
+ gl_image, true);
+ if (!ret) {
+ LOG(ERROR) << "Error while running bind image callback";
+ NOTIFY_ERROR(PLATFORM_FAILURE);
+ return;
+ }
}
void V4L2SliceVideoDecodeAccelerator::ImportBufferForPicture(
@@ -1512,7 +1515,9 @@ void V4L2SliceVideoDecodeAccelerator::ImportBufferForPictureForImportTask(
if (pixel_format != gl_image_format_fourcc_->ToVideoPixelFormat()) {
LOG(ERROR) << "Unsupported import format: "
- << VideoPixelFormatToString(pixel_format);
+ << VideoPixelFormatToString(pixel_format) << ", expected "
+ << VideoPixelFormatToString(
+ gl_image_format_fourcc_->ToVideoPixelFormat());
NOTIFY_ERROR(INVALID_ARGUMENT);
return;
}
@@ -2093,7 +2098,7 @@ V4L2SliceVideoDecodeAccelerator::CreateSurface() {
if (supports_requests_) {
// Get a free request from the queue for a new surface.
- base::Optional<V4L2RequestRef> request_ref =
+ absl::optional<V4L2RequestRef> request_ref =
requests_queue_->GetFreeRequest();
if (!request_ref) {
LOG(ERROR) << "Failed getting a request";
diff --git a/chromium/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h b/chromium/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h
index 6c9fac3ec46..864a50b38b1 100644
--- a/chromium/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h
+++ b/chromium/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h
@@ -18,7 +18,6 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/trace_event/memory_dump_provider.h"
@@ -31,6 +30,7 @@
#include "media/gpu/vp8_decoder.h"
#include "media/gpu/vp9_decoder.h"
#include "media/video/video_decode_accelerator.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/native_pixmap_handle.h"
#include "ui/gl/gl_fence_egl.h"
@@ -418,7 +418,7 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator
VideoCodecProfile video_profile_;
uint32_t input_format_fourcc_;
- base::Optional<Fourcc> output_format_fourcc_;
+ absl::optional<Fourcc> output_format_fourcc_;
gfx::Size coded_size_;
struct BitstreamBufferRef;
@@ -501,7 +501,7 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator
std::unique_ptr<ImageProcessor> image_processor_;
// The format of GLImage.
- base::Optional<Fourcc> gl_image_format_fourcc_;
+ absl::optional<Fourcc> gl_image_format_fourcc_;
// The logical dimensions of GLImage buffer in pixels.
gfx::Size gl_image_size_;
// Number of planes for GLImage.
diff --git a/chromium/media/gpu/v4l2/v4l2_vda_helpers.cc b/chromium/media/gpu/v4l2/v4l2_vda_helpers.cc
index ca557f5b5b6..adec5b8c064 100644
--- a/chromium/media/gpu/v4l2/v4l2_vda_helpers.cc
+++ b/chromium/media/gpu/v4l2/v4l2_vda_helpers.cc
@@ -16,7 +16,7 @@
namespace media {
namespace v4l2_vda_helpers {
-base::Optional<Fourcc> FindImageProcessorInputFormat(V4L2Device* vda_device) {
+absl::optional<Fourcc> FindImageProcessorInputFormat(V4L2Device* vda_device) {
std::vector<uint32_t> processor_input_formats =
V4L2ImageProcessorBackend::GetSupportedInputFormats();
@@ -32,10 +32,10 @@ base::Optional<Fourcc> FindImageProcessorInputFormat(V4L2Device* vda_device) {
}
++fmtdesc.index;
}
- return base::nullopt;
+ return absl::nullopt;
}
-base::Optional<Fourcc> FindImageProcessorOutputFormat(V4L2Device* ip_device) {
+absl::optional<Fourcc> FindImageProcessorOutputFormat(V4L2Device* ip_device) {
// Prefer YVU420 and NV12 because ArcGpuVideoDecodeAccelerator only supports
// single physical plane.
static constexpr uint32_t kPreferredFormats[] = {V4L2_PIX_FMT_NV12,
@@ -63,7 +63,7 @@ base::Optional<Fourcc> FindImageProcessorOutputFormat(V4L2Device* ip_device) {
}
}
- return base::nullopt;
+ return absl::nullopt;
}
std::unique_ptr<ImageProcessor> CreateImageProcessor(
diff --git a/chromium/media/gpu/v4l2/v4l2_vda_helpers.h b/chromium/media/gpu/v4l2/v4l2_vda_helpers.h
index 05b74a3205d..0fc4dfcf614 100644
--- a/chromium/media/gpu/v4l2/v4l2_vda_helpers.h
+++ b/chromium/media/gpu/v4l2/v4l2_vda_helpers.h
@@ -8,10 +8,10 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
-#include "base/optional.h"
#include "media/base/video_codecs.h"
#include "media/gpu/chromeos/fourcc.h"
#include "media/gpu/chromeos/image_processor.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
@@ -26,9 +26,9 @@ class H264Parser;
namespace v4l2_vda_helpers {
// Returns a usable input format of image processor, or nullopt if not found.
-base::Optional<Fourcc> FindImageProcessorInputFormat(V4L2Device* vda_device);
+absl::optional<Fourcc> FindImageProcessorInputFormat(V4L2Device* vda_device);
// Return a usable output format of image processor, or nullopt if not found.
-base::Optional<Fourcc> FindImageProcessorOutputFormat(V4L2Device* ip_device);
+absl::optional<Fourcc> FindImageProcessorOutputFormat(V4L2Device* ip_device);
// Create and return an image processor for the given parameters, or nullptr
// if it cannot be created.
diff --git a/chromium/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/chromium/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
index f0822769361..6ebf5f38b85 100644
--- a/chromium/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
+++ b/chromium/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -590,7 +590,9 @@ void V4L2VideoDecodeAccelerator::ImportBufferForPictureForImportTask(
// the final output format from the image processor (if exists).
// Use |egl_image_format_fourcc_|, it will be the final output format.
if (pixel_format != egl_image_format_fourcc_->ToVideoPixelFormat()) {
- LOG(ERROR) << "Unsupported import format: " << pixel_format;
+ LOG(ERROR) << "Unsupported import format: " << pixel_format << ", expected "
+ << VideoPixelFormatToString(
+ egl_image_format_fourcc_->ToVideoPixelFormat());
NOTIFY_ERROR(INVALID_ARGUMENT);
return;
}
@@ -1401,7 +1403,7 @@ bool V4L2VideoDecodeAccelerator::DequeueResolutionChangeEvent() {
DCHECK_NE(decoder_state_, kUninitialized);
DVLOGF(3);
- while (base::Optional<struct v4l2_event> event = device_->DequeueEvent()) {
+ while (absl::optional<struct v4l2_event> event = device_->DequeueEvent()) {
if (event->type == V4L2_EVENT_SOURCE_CHANGE) {
if (event->u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION) {
VLOGF(2) << "got resolution change event.";
diff --git a/chromium/media/gpu/v4l2/v4l2_video_decode_accelerator.h b/chromium/media/gpu/v4l2/v4l2_video_decode_accelerator.h
index 1460737b26e..6dacbdc5bdc 100644
--- a/chromium/media/gpu/v4l2/v4l2_video_decode_accelerator.h
+++ b/chromium/media/gpu/v4l2/v4l2_video_decode_accelerator.h
@@ -24,7 +24,6 @@
#include "base/containers/queue.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/trace_event/memory_dump_provider.h"
@@ -37,6 +36,7 @@
#include "media/gpu/v4l2/v4l2_device.h"
#include "media/video/picture.h"
#include "media/video/video_decode_accelerator.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_fence_egl.h"
@@ -539,7 +539,7 @@ class MEDIA_GPU_EXPORT V4L2VideoDecodeAccelerator
// thread manipulates them.
//
- base::Optional<V4L2WritableBufferRef> current_input_buffer_;
+ absl::optional<V4L2WritableBufferRef> current_input_buffer_;
scoped_refptr<V4L2Queue> input_queue_;
scoped_refptr<V4L2Queue> output_queue_;
@@ -601,7 +601,7 @@ class MEDIA_GPU_EXPORT V4L2VideoDecodeAccelerator
// Chosen input format for the video profile we are decoding from.
uint32_t input_format_fourcc_;
// Chosen output format.
- base::Optional<Fourcc> output_format_fourcc_;
+ absl::optional<Fourcc> output_format_fourcc_;
// Image processor device, if one is in use.
scoped_refptr<V4L2Device> image_processor_device_;
@@ -609,7 +609,7 @@ class MEDIA_GPU_EXPORT V4L2VideoDecodeAccelerator
std::unique_ptr<ImageProcessor> image_processor_;
// The format of EGLImage.
- base::Optional<Fourcc> egl_image_format_fourcc_;
+ absl::optional<Fourcc> egl_image_format_fourcc_;
// The logical dimensions of EGLImage buffer in pixels.
gfx::Size egl_image_size_;
diff --git a/chromium/media/gpu/v4l2/v4l2_video_decoder.cc b/chromium/media/gpu/v4l2/v4l2_video_decoder.cc
index 34c2fc68463..b9a93a02a22 100644
--- a/chromium/media/gpu/v4l2/v4l2_video_decoder.cc
+++ b/chromium/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -202,7 +202,7 @@ StatusCode V4L2VideoDecoder::InitializeBackend() {
constexpr bool kStateful = false;
constexpr bool kStateless = true;
- base::Optional<std::pair<bool, uint32_t>> api_and_format;
+ absl::optional<std::pair<bool, uint32_t>> api_and_format;
// Try both kStateful and kStateless APIs via |fourcc| and select the first
// combination where Open()ing the |device_| works.
for (const auto api : {kStateful, kStateless}) {
@@ -333,7 +333,7 @@ bool V4L2VideoDecoder::SetupOutputFormat(const gfx::Size& size,
continue;
}
- base::Optional<struct v4l2_format> format =
+ absl::optional<struct v4l2_format> format =
output_queue_->TryFormat(pixfmt, size, 0);
if (!format)
continue;
@@ -344,7 +344,7 @@ bool V4L2VideoDecoder::SetupOutputFormat(const gfx::Size& size,
}
// Ask the pipeline to pick the output format.
- const base::Optional<std::pair<Fourcc, gfx::Size>> output_format =
+ const absl::optional<std::pair<Fourcc, gfx::Size>> output_format =
client_->PickDecoderOutputFormat(candidates, visible_rect);
if (!output_format) {
VLOGF(1) << "Failed to pick an output format.";
@@ -354,7 +354,7 @@ bool V4L2VideoDecoder::SetupOutputFormat(const gfx::Size& size,
gfx::Size picked_size = std::move(output_format->second);
// We successfully picked the output format. Now setup output format again.
- base::Optional<struct v4l2_format> format =
+ absl::optional<struct v4l2_format> format =
output_queue_->SetFormat(fourcc.ToV4L2PixFmt(), picked_size, 0);
DCHECK(format);
gfx::Size adjusted_size(format->fmt.pix_mp.width, format->fmt.pix_mp.height);
@@ -374,7 +374,7 @@ bool V4L2VideoDecoder::SetupOutputFormat(const gfx::Size& size,
// created by VideoFramePool.
DmabufVideoFramePool* pool = client_->GetVideoFramePool();
if (pool) {
- base::Optional<GpuBufferLayout> layout = pool->Initialize(
+ absl::optional<GpuBufferLayout> layout = pool->Initialize(
fourcc, adjusted_size, visible_rect,
GetNaturalSize(visible_rect, pixel_aspect_ratio_), num_output_frames_,
/*use_protected=*/false);
@@ -393,7 +393,7 @@ bool V4L2VideoDecoder::SetupOutputFormat(const gfx::Size& size,
VLOGF(1) << "buffer modifier: " << std::hex << layout->modifier();
if (layout->modifier() &&
layout->modifier() != gfx::NativePixmapHandle::kNoModifier) {
- base::Optional<struct v4l2_format> modifier_format =
+ absl::optional<struct v4l2_format> modifier_format =
output_queue_->SetModifierFormat(layout->modifier(), picked_size);
if (!modifier_format)
return false;
diff --git a/chromium/media/gpu/v4l2/v4l2_video_decoder.h b/chromium/media/gpu/v4l2/v4l2_video_decoder.h
index 094465cd094..9d96b5b442a 100644
--- a/chromium/media/gpu/v4l2/v4l2_video_decoder.h
+++ b/chromium/media/gpu/v4l2/v4l2_video_decoder.h
@@ -18,7 +18,6 @@
#include "base/containers/queue.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/thread.h"
@@ -31,6 +30,7 @@
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/v4l2/v4l2_device.h"
#include "media/gpu/v4l2/v4l2_video_decoder_backend.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
diff --git a/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc b/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc
index bc23ecda02a..5953f4118ef 100644
--- a/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc
+++ b/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc
@@ -10,9 +10,7 @@
#include <utility>
#include "base/bind.h"
-#include "base/callback_forward.h"
#include "base/logging.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "media/base/video_codecs.h"
@@ -21,6 +19,7 @@
#include "media/gpu/v4l2/v4l2_device.h"
#include "media/gpu/v4l2/v4l2_vda_helpers.h"
#include "media/gpu/v4l2/v4l2_video_decoder_backend.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -96,6 +95,9 @@ bool V4L2StatefulVideoDecoderBackend::Initialize() {
return false;
}
+ framerate_control_ =
+ std::make_unique<V4L2FrameRateControl>(device_, task_runner_);
+
return true;
}
@@ -238,7 +240,7 @@ void V4L2StatefulVideoDecoderBackend::ScheduleDecodeWork() {
}
void V4L2StatefulVideoDecoderBackend::ProcessEventQueue() {
- while (base::Optional<struct v4l2_event> ev = device_->DequeueEvent()) {
+ while (absl::optional<struct v4l2_event> ev = device_->DequeueEvent()) {
if (ev->type == V4L2_EVENT_SOURCE_CHANGE &&
(ev->u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION)) {
ChangeResolution();
@@ -269,7 +271,7 @@ void V4L2StatefulVideoDecoderBackend::EnqueueOutputBuffers() {
bool ret = false;
bool no_buffer = false;
- base::Optional<V4L2WritableBufferRef> buffer;
+ absl::optional<V4L2WritableBufferRef> buffer;
switch (mem_type) {
case V4L2_MEMORY_MMAP:
buffer = output_queue_->GetFreeBuffer();
@@ -292,6 +294,7 @@ void V4L2StatefulVideoDecoderBackend::EnqueueOutputBuffers() {
break;
}
+ framerate_control_->AttachToVideoFrame(video_frame);
ret = std::move(*buffer).QueueDMABuf(std::move(video_frame));
break;
}
@@ -341,7 +344,7 @@ scoped_refptr<VideoFrame> V4L2StatefulVideoDecoderBackend::GetPoolVideoFrame() {
// static
void V4L2StatefulVideoDecoderBackend::ReuseOutputBufferThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<V4L2StatefulVideoDecoderBackend>> weak_this,
+ absl::optional<base::WeakPtr<V4L2StatefulVideoDecoderBackend>> weak_this,
V4L2ReadableBufferRef buffer) {
DVLOGF(3);
DCHECK(weak_this);
diff --git a/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h b/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h
index b91230cec80..3d133864913 100644
--- a/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h
+++ b/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h
@@ -10,11 +10,12 @@
#include "base/containers/queue.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "media/base/video_codecs.h"
#include "media/gpu/v4l2/v4l2_device.h"
+#include "media/gpu/v4l2/v4l2_framerate_control.h"
#include "media/gpu/v4l2/v4l2_video_decoder_backend.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -87,7 +88,7 @@ class V4L2StatefulVideoDecoderBackend : public V4L2VideoDecoderBackend {
static void ReuseOutputBufferThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<V4L2StatefulVideoDecoderBackend>> weak_this,
+ absl::optional<base::WeakPtr<V4L2StatefulVideoDecoderBackend>> weak_this,
V4L2ReadableBufferRef buffer);
void ReuseOutputBuffer(V4L2ReadableBufferRef buffer);
@@ -129,14 +130,14 @@ class V4L2StatefulVideoDecoderBackend : public V4L2VideoDecoderBackend {
base::queue<DecodeRequest> decode_request_queue_;
// The decode request which is currently processed.
- base::Optional<DecodeRequest> current_decode_request_;
+ absl::optional<DecodeRequest> current_decode_request_;
// V4L2 input buffer currently being prepared.
- base::Optional<V4L2WritableBufferRef> current_input_buffer_;
+ absl::optional<V4L2WritableBufferRef> current_input_buffer_;
std::unique_ptr<v4l2_vda_helpers::InputBufferFragmentSplitter>
frame_splitter_;
- base::Optional<gfx::Rect> visible_rect_;
+ absl::optional<gfx::Rect> visible_rect_;
// Callback of the buffer that triggered a flush, to be called when the
// flush completes.
@@ -151,6 +152,10 @@ class V4L2StatefulVideoDecoderBackend : public V4L2VideoDecoderBackend {
// flush or reset.
bool has_pending_requests_ = false;
+ // The venus driver is the only implementation that requires the client
+ // to inform the driver of the framerate.
+ std::unique_ptr<V4L2FrameRateControl> framerate_control_;
+
base::WeakPtr<V4L2StatefulVideoDecoderBackend> weak_this_;
base::WeakPtrFactory<V4L2StatefulVideoDecoderBackend> weak_this_factory_{
this};
diff --git a/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.cc b/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.cc
index 60bac877b75..82b4eebadf5 100644
--- a/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.cc
+++ b/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.cc
@@ -23,7 +23,6 @@
#include "media/gpu/macros.h"
#include "media/gpu/v4l2/v4l2_device.h"
#include "media/gpu/v4l2/v4l2_h264_accelerator.h"
-#include "media/gpu/v4l2/v4l2_h264_accelerator_chromium.h"
#include "media/gpu/v4l2/v4l2_h264_accelerator_legacy.h"
#include "media/gpu/v4l2/v4l2_vp8_accelerator.h"
#include "media/gpu/v4l2/v4l2_vp8_accelerator_legacy.h"
@@ -147,7 +146,7 @@ bool V4L2StatelessVideoDecoderBackend::Initialize() {
// static
void V4L2StatelessVideoDecoderBackend::ReuseOutputBufferThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<V4L2StatelessVideoDecoderBackend>> weak_this,
+ absl::optional<base::WeakPtr<V4L2StatelessVideoDecoderBackend>> weak_this,
V4L2ReadableBufferRef buffer) {
DVLOGF(3);
DCHECK(weak_this);
@@ -266,7 +265,7 @@ V4L2StatelessVideoDecoderBackend::CreateSurface() {
scoped_refptr<V4L2DecodeSurface> dec_surface;
if (input_queue_->SupportsRequests()) {
- base::Optional<V4L2RequestRef> request_ref =
+ absl::optional<V4L2RequestRef> request_ref =
requests_queue_->GetFreeRequest();
if (!request_ref) {
DVLOGF(1) << "Could not get free request.";
@@ -418,7 +417,7 @@ bool V4L2StatelessVideoDecoderBackend::PumpDecodeTask() {
if (current_decode_request_) {
DCHECK(current_decode_request_->decode_cb);
std::move(current_decode_request_->decode_cb).Run(DecodeStatus::OK);
- current_decode_request_ = base::nullopt;
+ current_decode_request_ = absl::nullopt;
}
// Process next decode request.
@@ -441,7 +440,7 @@ bool V4L2StatelessVideoDecoderBackend::PumpDecodeTask() {
output_request_queue_.push(OutputRequest::FlushFence());
PumpOutputSurfaces();
- current_decode_request_ = base::nullopt;
+ current_decode_request_ = absl::nullopt;
return true;
}
@@ -608,7 +607,7 @@ void V4L2StatelessVideoDecoderBackend::ClearPendingRequests(
// Clear current_decode_request_ and decode_request_queue_.
if (current_decode_request_) {
std::move(current_decode_request_->decode_cb).Run(status);
- current_decode_request_ = base::nullopt;
+ current_decode_request_ = absl::nullopt;
}
while (!decode_request_queue_.empty()) {
@@ -651,14 +650,8 @@ bool V4L2StatelessVideoDecoderBackend::CreateAvd() {
if (profile_ >= H264PROFILE_MIN && profile_ <= H264PROFILE_MAX) {
if (input_queue_->SupportsRequests()) {
- std::unique_ptr<H264Decoder::H264Accelerator> accelerator;
- if (V4L2H264Accelerator::SupportsUpstreamABI(device_.get()))
- accelerator =
- std::make_unique<V4L2H264Accelerator>(this, device_.get());
- else
- accelerator =
- std::make_unique<V4L2ChromiumH264Accelerator>(this, device_.get());
- avd_ = std::make_unique<H264Decoder>(std::move(accelerator), profile_);
+ avd_ = std::make_unique<H264Decoder>(
+ std::make_unique<V4L2H264Accelerator>(this, device_.get()), profile_);
} else {
avd_ = std::make_unique<H264Decoder>(
std::make_unique<V4L2LegacyH264Accelerator>(this, device_.get()),
diff --git a/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h b/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h
index 704d6171f7f..b475bb1aa00 100644
--- a/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h
+++ b/chromium/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h
@@ -104,7 +104,7 @@ class V4L2StatelessVideoDecoderBackend : public V4L2VideoDecoderBackend,
// Callback which is called when the output buffer is not used anymore.
static void ReuseOutputBufferThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Optional<base::WeakPtr<V4L2StatelessVideoDecoderBackend>> weak_this,
+ absl::optional<base::WeakPtr<V4L2StatelessVideoDecoderBackend>> weak_this,
V4L2ReadableBufferRef buffer);
void ReuseOutputBuffer(V4L2ReadableBufferRef buffer);
@@ -140,7 +140,7 @@ class V4L2StatelessVideoDecoderBackend : public V4L2VideoDecoderBackend,
std::unique_ptr<AcceleratedVideoDecoder> avd_;
// The decode request which is currently processed.
- base::Optional<DecodeRequest> current_decode_request_;
+ absl::optional<DecodeRequest> current_decode_request_;
// Surfaces enqueued to V4L2 device. Since we are stateless, they are
// guaranteed to be proceeded in FIFO order.
base::queue<scoped_refptr<V4L2DecodeSurface>> surfaces_at_device_;
diff --git a/chromium/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/chromium/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
index eb1810645a6..addf790f003 100644
--- a/chromium/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
+++ b/chromium/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -22,7 +22,6 @@
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/numerics/safe_conversions.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/task/post_task.h"
@@ -43,6 +42,7 @@
#include "media/gpu/macros.h"
#include "media/video/h264_level_limits.h"
#include "media/video/h264_parser.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#define NOTIFY_ERROR(x) \
do { \
@@ -102,7 +102,7 @@ namespace media {
namespace {
// Convert VideoFrameLayout to ImageProcessor::PortConfig.
-base::Optional<ImageProcessor::PortConfig> VideoFrameLayoutToPortConfig(
+absl::optional<ImageProcessor::PortConfig> VideoFrameLayoutToPortConfig(
const VideoFrameLayout& layout,
const gfx::Rect& visible_rect,
const std::vector<VideoFrame::StorageType>& preferred_storage_types) {
@@ -111,7 +111,7 @@ base::Optional<ImageProcessor::PortConfig> VideoFrameLayoutToPortConfig(
if (!fourcc) {
DVLOGF(1) << "Failed to create Fourcc from video pixel format "
<< VideoPixelFormatToString(layout.format());
- return base::nullopt;
+ return absl::nullopt;
}
return ImageProcessor::PortConfig(*fourcc, layout.coded_size(),
layout.planes(), visible_rect,
@@ -119,10 +119,10 @@ base::Optional<ImageProcessor::PortConfig> VideoFrameLayoutToPortConfig(
}
// Create Layout from |layout| with is_multi_planar = true.
-base::Optional<VideoFrameLayout> AsMultiPlanarLayout(
+absl::optional<VideoFrameLayout> AsMultiPlanarLayout(
const VideoFrameLayout& layout) {
if (layout.is_multi_planar())
- return base::make_optional<VideoFrameLayout>(layout);
+ return absl::make_optional<VideoFrameLayout>(layout);
return VideoFrameLayout::CreateMultiPlanar(
layout.format(), layout.coded_size(), layout.planes());
}
@@ -1046,7 +1046,7 @@ void V4L2VideoEncodeAccelerator::Enqueue() {
break;
}
- base::Optional<V4L2WritableBufferRef> input_buffer;
+ absl::optional<V4L2WritableBufferRef> input_buffer;
switch (input_memory_type_) {
case V4L2_MEMORY_DMABUF:
input_buffer = input_queue_->GetFreeBufferForFrame(
@@ -1060,7 +1060,7 @@ void V4L2VideoEncodeAccelerator::Enqueue() {
input_buffer = input_queue_->GetFreeBuffer();
break;
}
- // input_buffer cannot be base::nullopt since we checked for
+ // input_buffer cannot be absl::nullopt since we checked for
// input_queue_->FreeBuffersCount() > 0 before entering the loop.
DCHECK(input_buffer);
if (!EnqueueInputRecord(std::move(*input_buffer)))
@@ -1516,7 +1516,7 @@ bool V4L2VideoEncodeAccelerator::SetOutputFormat(
// Sets 0 to width and height in CAPTURE queue, which should be ignored by the
// driver.
- base::Optional<struct v4l2_format> format = output_queue_->SetFormat(
+ absl::optional<struct v4l2_format> format = output_queue_->SetFormat(
output_format_fourcc_, gfx::Size(), output_buffer_byte_size_);
if (!format) {
return false;
@@ -1530,7 +1530,7 @@ bool V4L2VideoEncodeAccelerator::SetOutputFormat(
return true;
}
-base::Optional<struct v4l2_format>
+absl::optional<struct v4l2_format>
V4L2VideoEncodeAccelerator::NegotiateInputFormat(VideoPixelFormat input_format,
const gfx::Size& size) {
VLOGF(2);
@@ -1544,7 +1544,7 @@ V4L2VideoEncodeAccelerator::NegotiateInputFormat(VideoPixelFormat input_format,
if (!input_fourcc) {
DVLOGF(2) << "Invalid input format "
<< VideoPixelFormatToString(input_format);
- return base::nullopt;
+ return absl::nullopt;
}
pix_fmt_candidates.push_back(input_fourcc->ToV4L2PixFmt());
// Second try preferred input formats for both single-planar and
@@ -1557,7 +1557,7 @@ V4L2VideoEncodeAccelerator::NegotiateInputFormat(VideoPixelFormat input_format,
for (const auto pix_fmt : pix_fmt_candidates) {
DVLOGF(3) << "Trying S_FMT with " << FourccToString(pix_fmt);
- base::Optional<struct v4l2_format> format =
+ absl::optional<struct v4l2_format> format =
input_queue_->SetFormat(pix_fmt, size, 0);
if (!format)
continue;
@@ -1566,7 +1566,7 @@ V4L2VideoEncodeAccelerator::NegotiateInputFormat(VideoPixelFormat input_format,
device_input_layout_ = V4L2Device::V4L2FormatToVideoFrameLayout(*format);
if (!device_input_layout_) {
VLOGF(1) << "Invalid device_input_layout_";
- return base::nullopt;
+ return absl::nullopt;
}
DVLOG(3) << "Negotiated device_input_layout_: " << *device_input_layout_;
if (!gfx::Rect(device_input_layout_->coded_size())
@@ -1574,17 +1574,17 @@ V4L2VideoEncodeAccelerator::NegotiateInputFormat(VideoPixelFormat input_format,
VLOGF(1) << "Input size " << size.ToString()
<< " exceeds encoder capability. Size encoder can handle: "
<< device_input_layout_->coded_size().ToString();
- return base::nullopt;
+ return absl::nullopt;
}
// Make sure that the crop is preserved as we have changed the input
// resolution.
if (!ApplyCrop()) {
- return base::nullopt;
+ return absl::nullopt;
}
return format;
}
- return base::nullopt;
+ return absl::nullopt;
}
bool V4L2VideoEncodeAccelerator::ApplyCrop() {
@@ -1730,11 +1730,9 @@ bool V4L2VideoEncodeAccelerator::InitControlsH264(const Config& config) {
DVLOGF(2) << "Will inject SPS+PPS before each IDR, unsupported by device";
}
- // Optional H264 controls.
- std::vector<V4L2ExtCtrl> h264_ctrls;
-
// No B-frames, for lowest decoding latency.
- h264_ctrls.emplace_back(V4L2_CID_MPEG_VIDEO_B_FRAMES, 0);
+ device_->SetExtCtrls(V4L2_CTRL_CLASS_MPEG,
+ {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_B_FRAMES, 0)});
// Set H.264 profile.
int32_t profile_value =
@@ -1743,7 +1741,14 @@ bool V4L2VideoEncodeAccelerator::InitControlsH264(const Config& config) {
NOTIFY_ERROR(kInvalidArgumentError);
return false;
}
- h264_ctrls.emplace_back(V4L2_CID_MPEG_VIDEO_H264_PROFILE, profile_value);
+ if (!device_->SetExtCtrls(
+ V4L2_CTRL_CLASS_MPEG,
+ {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_H264_PROFILE, profile_value)})) {
+ VLOGF(1) << "Unsupported profile: "
+ << GetProfileName(config.output_profile);
+ NOTIFY_ERROR(kInvalidArgumentError);
+ return false;
+ }
// Set H.264 output level from config. Use Level 4.0 as fallback default.
uint8_t h264_level = config.h264_output_level.value_or(H264SPS::kLevelIDC4p0);
@@ -1763,7 +1768,7 @@ bool V4L2VideoEncodeAccelerator::InitControlsH264(const Config& config) {
if (!CheckH264LevelLimits(config.output_profile, h264_level,
config.initial_bitrate, framerate,
framesize_in_mbs)) {
- base::Optional<uint8_t> valid_level =
+ absl::optional<uint8_t> valid_level =
FindValidH264Level(config.output_profile, config.initial_bitrate,
framerate, framesize_in_mbs);
if (!valid_level) {
@@ -1780,14 +1785,41 @@ bool V4L2VideoEncodeAccelerator::InitControlsH264(const Config& config) {
}
int32_t level_value = V4L2Device::H264LevelIdcToV4L2H264Level(h264_level);
- h264_ctrls.emplace_back(V4L2_CID_MPEG_VIDEO_H264_LEVEL, level_value);
+ device_->SetExtCtrls(
+ V4L2_CTRL_CLASS_MPEG,
+ {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_H264_LEVEL, level_value)});
// Ask not to put SPS and PPS into separate bitstream buffers.
- h264_ctrls.emplace_back(V4L2_CID_MPEG_VIDEO_HEADER_MODE,
- V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
-
- // Ignore return value as these controls are optional.
- device_->SetExtCtrls(V4L2_CTRL_CLASS_MPEG, std::move(h264_ctrls));
+ device_->SetExtCtrls(
+ V4L2_CTRL_CLASS_MPEG,
+ {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+ V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME)});
+
+ // H264 coding tools parameter. Since a driver may not support some of them,
+ // EXT_S_CTRLS is called to each of them to enable as many coding tools as
+ // possible.
+ // Don't produce Intra-only frame.
+ device_->SetExtCtrls(V4L2_CTRL_CLASS_MPEG,
+ {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, 0)});
+ // Enable deblocking filter.
+ device_->SetExtCtrls(
+ V4L2_CTRL_CLASS_MPEG,
+ {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
+ V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED)});
+ // Use CABAC in Main and High profiles.
+ if (config.output_profile == H264PROFILE_MAIN ||
+ config.output_profile == H264PROFILE_HIGH) {
+ device_->SetExtCtrls(
+ V4L2_CTRL_CLASS_MPEG,
+ {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
+ V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)});
+ }
+ // Use 8x8 transform in High profile.
+ if (config.output_profile == H264PROFILE_HIGH) {
+ device_->SetExtCtrls(
+ V4L2_CTRL_CLASS_MPEG,
+ {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM, true)});
+ }
// Quantization parameter. The h264 qp range is 0-51.
// Note: Webrtc default values are 24 and 37 respectively, see
@@ -1795,7 +1827,7 @@ bool V4L2VideoEncodeAccelerator::InitControlsH264(const Config& config) {
// These values were copied from the VA-API encoder.
// Ignore return values as these controls are optional.
device_->SetExtCtrls(V4L2_CTRL_CLASS_MPEG,
- {V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 42});
+ {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 42)});
// Don't set MIN_QP with other controls since it is not supported by
// some devices and may prevent other controls from being set.
device_->SetExtCtrls(V4L2_CTRL_CLASS_MPEG,
diff --git a/chromium/media/gpu/v4l2/v4l2_video_encode_accelerator.h b/chromium/media/gpu/v4l2/v4l2_video_encode_accelerator.h
index 792bc4e57f1..86881939599 100644
--- a/chromium/media/gpu/v4l2/v4l2_video_encode_accelerator.h
+++ b/chromium/media/gpu/v4l2/v4l2_video_encode_accelerator.h
@@ -18,7 +18,6 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
@@ -27,6 +26,7 @@
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/v4l2/v4l2_device.h"
#include "media/video/video_encode_accelerator.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
@@ -70,7 +70,7 @@ class MEDIA_GPU_EXPORT V4L2VideoEncodeAccelerator
// This is valid only if image processor is used. The buffer associated with
// this index can be reused in Dequeue().
- base::Optional<size_t> ip_output_buffer_index;
+ absl::optional<size_t> ip_output_buffer_index;
};
// Store all the information of input frame passed to Encode().
@@ -87,7 +87,7 @@ class MEDIA_GPU_EXPORT V4L2VideoEncodeAccelerator
// This is valid only if image processor is used. This info needs to be
// propagated to InputRecord.
- base::Optional<size_t> ip_output_buffer_index;
+ absl::optional<size_t> ip_output_buffer_index;
};
enum {
@@ -209,9 +209,9 @@ class MEDIA_GPU_EXPORT V4L2VideoEncodeAccelerator
// Try to set up the device to the input format we were Initialized() with,
// or if the device doesn't support it, use one it can support, so that we
// can later instantiate an ImageProcessor to convert to it. Return
- // base::nullopt if no format is supported, otherwise return v4l2_format
+ // absl::nullopt if no format is supported, otherwise return v4l2_format
// adjusted by the driver.
- base::Optional<struct v4l2_format> NegotiateInputFormat(
+ absl::optional<struct v4l2_format> NegotiateInputFormat(
VideoPixelFormat input_format,
const gfx::Size& frame_size);
@@ -274,7 +274,7 @@ class MEDIA_GPU_EXPORT V4L2VideoEncodeAccelerator
gfx::Rect encoder_input_visible_rect_;
// Layout of device accepted input VideoFrame.
- base::Optional<VideoFrameLayout> device_input_layout_;
+ absl::optional<VideoFrameLayout> device_input_layout_;
// Stands for whether an input buffer is native graphic buffer.
bool native_input_mode_;
diff --git a/chromium/media/gpu/v4l2/v4l2_vp8_accelerator.h b/chromium/media/gpu/v4l2/v4l2_vp8_accelerator.h
index 8ea3b196e12..ef0087b98b7 100644
--- a/chromium/media/gpu/v4l2/v4l2_vp8_accelerator.h
+++ b/chromium/media/gpu/v4l2/v4l2_vp8_accelerator.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_GPU_V4L2_V4L2_VP8_ACCELERATOR_H_
#define MEDIA_GPU_V4L2_V4L2_VP8_ACCELERATOR_H_
-#include <vector>
-
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "media/gpu/vp8_decoder.h"
diff --git a/chromium/media/gpu/v4l2/v4l2_vp8_accelerator_legacy.h b/chromium/media/gpu/v4l2/v4l2_vp8_accelerator_legacy.h
index 95fb4ad52a0..5920d41fa7f 100644
--- a/chromium/media/gpu/v4l2/v4l2_vp8_accelerator_legacy.h
+++ b/chromium/media/gpu/v4l2/v4l2_vp8_accelerator_legacy.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_GPU_V4L2_V4L2_VP8_ACCELERATOR_LEGACY_H_
#define MEDIA_GPU_V4L2_V4L2_VP8_ACCELERATOR_LEGACY_H_
-#include <vector>
-
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "media/gpu/vp8_decoder.h"
diff --git a/chromium/media/gpu/v4l2/v4l2_vp9_accelerator_legacy.h b/chromium/media/gpu/v4l2/v4l2_vp9_accelerator_legacy.h
index 9e01a272f86..d93d44f6bba 100644
--- a/chromium/media/gpu/v4l2/v4l2_vp9_accelerator_legacy.h
+++ b/chromium/media/gpu/v4l2/v4l2_vp9_accelerator_legacy.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_GPU_V4L2_V4L2_VP9_ACCELERATOR_LEGACY_H_
#define MEDIA_GPU_V4L2_V4L2_VP9_ACCELERATOR_LEGACY_H_
-#include <vector>
-
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
diff --git a/chromium/media/gpu/vaapi/OWNERS b/chromium/media/gpu/vaapi/OWNERS
index 93cfc79bb9a..54ca4a0e14f 100644
--- a/chromium/media/gpu/vaapi/OWNERS
+++ b/chromium/media/gpu/vaapi/OWNERS
@@ -7,4 +7,4 @@ jkardatzke@google.com
# Legacy owners.
dstaessens@chromium.org
kcwu@chromium.org
-posciak@chromium.org \ No newline at end of file
+posciak@chromium.org
diff --git a/chromium/media/gpu/vaapi/h264_encoder.cc b/chromium/media/gpu/vaapi/h264_encoder.cc
index b17d1d23494..dcdcc298d30 100644
--- a/chromium/media/gpu/vaapi/h264_encoder.cc
+++ b/chromium/media/gpu/vaapi/h264_encoder.cc
@@ -110,7 +110,7 @@ bool H264Encoder::Initialize(
// framerate and dimension.
if (!CheckH264LevelLimits(profile_, level_, config.initial_bitrate,
initial_framerate, mb_width_ * mb_height_)) {
- base::Optional<uint8_t> valid_level =
+ absl::optional<uint8_t> valid_level =
FindValidH264Level(profile_, config.initial_bitrate, initial_framerate,
mb_width_ * mb_height_);
if (!valid_level) {
diff --git a/chromium/media/gpu/vaapi/h264_encoder_unittest.cc b/chromium/media/gpu/vaapi/h264_encoder_unittest.cc
index 423cdafdb78..0280fedc1bd 100644
--- a/chromium/media/gpu/vaapi/h264_encoder_unittest.cc
+++ b/chromium/media/gpu/vaapi/h264_encoder_unittest.cc
@@ -24,8 +24,8 @@ VideoEncodeAccelerator::Config kDefaultVEAConfig(
H264PROFILE_BASELINE,
14000000 /* = maximum bitrate in bits per second for level 3.1 */,
VideoEncodeAccelerator::kDefaultFramerate,
- base::nullopt /* gop_length */,
- base::nullopt /* h264 output level*/,
+ absl::nullopt /* gop_length */,
+ absl::nullopt /* h264 output level*/,
false /* is_constrained_h264 */,
VideoEncodeAccelerator::Config::StorageType::kShmem,
VideoEncodeAccelerator::Config::ContentType::kCamera);
diff --git a/chromium/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.cc b/chromium/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.cc
index 40ec7291eb1..3b0d6580cae 100644
--- a/chromium/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.cc
+++ b/chromium/media/gpu/vaapi/vaapi_mjpeg_decode_accelerator.cc
@@ -16,11 +16,10 @@
#include "base/files/scoped_file.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/memory/page_size.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
-#include "base/optional.h"
-#include "base/process/process_metrics.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
@@ -38,6 +37,7 @@
#include "media/gpu/vaapi/vaapi_image_decoder.h"
#include "media/gpu/vaapi/vaapi_utils.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/libyuv/include/libyuv.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -220,7 +220,7 @@ bool VaapiMjpegDecodeAccelerator::OutputPictureLibYuvOnTaskRunner(
if (video_frame->HasDmaBufs()) {
// Dmabuf-backed frame needs to be mapped for SW access.
DCHECK(gpu_memory_buffer_support_);
- base::Optional<gfx::BufferFormat> gfx_format =
+ absl::optional<gfx::BufferFormat> gfx_format =
VideoPixelFormatToGfxBufferFormat(video_frame->format());
if (!gfx_format) {
VLOGF(1) << "Unsupported format: " << video_frame->format();
diff --git a/chromium/media/gpu/vaapi/vaapi_picture_factory.cc b/chromium/media/gpu/vaapi/vaapi_picture_factory.cc
index 50d5f245f83..719035b87c8 100644
--- a/chromium/media/gpu/vaapi/vaapi_picture_factory.cc
+++ b/chromium/media/gpu/vaapi/vaapi_picture_factory.cc
@@ -4,6 +4,7 @@
#include "media/gpu/vaapi/vaapi_picture_factory.h"
+#include "base/containers/contains.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include "media/video/picture.h"
#include "ui/base/ui_base_features.h"
diff --git a/chromium/media/gpu/vaapi/vaapi_unittest.cc b/chromium/media/gpu/vaapi/vaapi_unittest.cc
index d6adb5b876b..79f4eeca0ff 100644
--- a/chromium/media/gpu/vaapi/vaapi_unittest.cc
+++ b/chromium/media/gpu/vaapi/vaapi_unittest.cc
@@ -14,27 +14,28 @@
#include <va/va_str.h>
#include "base/callback_helpers.h"
+#include "base/containers/contains.h"
+#include "base/cpu.h"
#include "base/files/file.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
-#include "base/optional.h"
#include "base/process/launch.h"
-#include "base/stl_util.h"
#include "base/strings/pattern.h"
#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
#include "base/test/launcher/unit_test_launcher.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_suite.h"
#include "build/chromeos_buildflags.h"
-#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "media/base/media_switches.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include "media/media_buildflags.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace {
-base::Optional<VAProfile> ConvertToVAProfile(VideoCodecProfile profile) {
+absl::optional<VAProfile> ConvertToVAProfile(VideoCodecProfile profile) {
// A map between VideoCodecProfile and VAProfile.
const std::map<VideoCodecProfile, VAProfile> kProfileMap = {
// VAProfileH264Baseline is deprecated in <va/va.h> from libva 2.0.0.
@@ -51,12 +52,12 @@ base::Optional<VAProfile> ConvertToVAProfile(VideoCodecProfile profile) {
#endif
};
auto it = kProfileMap.find(profile);
- return it != kProfileMap.end() ? base::make_optional<VAProfile>(it->second)
- : base::nullopt;
+ return it != kProfileMap.end() ? absl::make_optional<VAProfile>(it->second)
+ : absl::nullopt;
}
// Converts the given string to VAProfile
-base::Optional<VAProfile> StringToVAProfile(const std::string& va_profile) {
+absl::optional<VAProfile> StringToVAProfile(const std::string& va_profile) {
const std::map<std::string, VAProfile> kStringToVAProfile = {
{"VAProfileNone", VAProfileNone},
{"VAProfileH264ConstrainedBaseline", VAProfileH264ConstrainedBaseline},
@@ -81,12 +82,12 @@ base::Optional<VAProfile> StringToVAProfile(const std::string& va_profile) {
auto it = kStringToVAProfile.find(va_profile);
return it != kStringToVAProfile.end()
- ? base::make_optional<VAProfile>(it->second)
- : base::nullopt;
+ ? absl::make_optional<VAProfile>(it->second)
+ : absl::nullopt;
}
// Converts the given string to VAEntrypoint
-base::Optional<VAEntrypoint> StringToVAEntrypoint(
+absl::optional<VAEntrypoint> StringToVAEntrypoint(
const std::string& va_entrypoint) {
const std::map<std::string, VAEntrypoint> kStringToVAEntrypoint = {
{"VAEntrypointVLD", VAEntrypointVLD},
@@ -101,8 +102,8 @@ base::Optional<VAEntrypoint> StringToVAEntrypoint(
auto it = kStringToVAEntrypoint.find(va_entrypoint);
return it != kStringToVAEntrypoint.end()
- ? base::make_optional<VAEntrypoint>(it->second)
- : base::nullopt;
+ ? absl::make_optional<VAEntrypoint>(it->second)
+ : absl::nullopt;
}
std::unique_ptr<base::test::ScopedFeatureList> CreateScopedFeatureList() {
@@ -196,8 +197,7 @@ TEST_F(VaapiTest, VerifyNoVAProfileH264Baseline) {
TEST_F(VaapiTest, GetSupportedDecodeProfiles) {
const auto va_info = RetrieveVAInfoOutput();
- for (const auto& profile : VaapiWrapper::GetSupportedDecodeProfiles(
- gpu::GpuDriverBugWorkarounds())) {
+ for (const auto& profile : VaapiWrapper::GetSupportedDecodeProfiles()) {
const auto va_profile = ConvertToVAProfile(profile.profile);
ASSERT_TRUE(va_profile.has_value());
diff --git a/chromium/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/chromium/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
index 9d9cb7a1713..35c4b45ead4 100644
--- a/chromium/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
+++ b/chromium/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -11,6 +11,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/containers/contains.h"
#include "base/cpu.h"
#include "base/files/scoped_file.h"
#include "base/json/json_writer.h"
@@ -21,6 +22,7 @@
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_dump_manager.h"
@@ -151,7 +153,6 @@ VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(
const BindGLImageCallback& bind_image_cb)
: state_(kUninitialized),
input_ready_(&lock_),
- vaapi_picture_factory_(new VaapiPictureFactory()),
buffer_allocation_mode_(BufferAllocationMode::kNormal),
surfaces_available_(&lock_),
va_surface_format_(VA_INVALID_ID),
@@ -190,6 +191,8 @@ bool VaapiVideoDecodeAccelerator::Initialize(const Config& config,
return false;
#endif
+ vaapi_picture_factory_ = std::make_unique<VaapiPictureFactory>();
+
if (config.is_encrypted()) {
NOTREACHED() << "Encrypted streams are not supported for this VDA";
return false;
@@ -646,7 +649,7 @@ void VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange() {
<< " pictures of size: " << requested_pic_size_.ToString()
<< " and visible rectangle = " << requested_visible_rect_.ToString();
- const base::Optional<VideoPixelFormat> format =
+ const absl::optional<VideoPixelFormat> format =
GfxBufferFormatToVideoPixelFormat(
vaapi_picture_factory_->GetBufferFormat());
CHECK(format);
@@ -1196,10 +1199,9 @@ void VaapiVideoDecodeAccelerator::RecycleVASurface(
// static
VideoDecodeAccelerator::SupportedProfiles
-VaapiVideoDecodeAccelerator::GetSupportedProfiles(
- const gpu::GpuDriverBugWorkarounds& workarounds) {
+VaapiVideoDecodeAccelerator::GetSupportedProfiles() {
VideoDecodeAccelerator::SupportedProfiles profiles =
- VaapiWrapper::GetSupportedDecodeProfiles(workarounds);
+ VaapiWrapper::GetSupportedDecodeProfiles();
// VaVDA never supported VP9 Profile 2, AV1 and HEVC, but VaapiWrapper does.
// Filter them out.
base::EraseIf(profiles, [](const auto& profile) {
diff --git a/chromium/media/gpu/vaapi/vaapi_video_decode_accelerator.h b/chromium/media/gpu/vaapi/vaapi_video_decode_accelerator.h
index 07ae2d85c52..d347fb95f62 100644
--- a/chromium/media/gpu/vaapi/vaapi_video_decode_accelerator.h
+++ b/chromium/media/gpu/vaapi/vaapi_video_decode_accelerator.h
@@ -40,10 +40,6 @@ namespace gl {
class GLImage;
}
-namespace gpu {
-class GpuDriverBugWorkarounds;
-}
-
namespace media {
class AcceleratedVideoDecoder;
@@ -92,8 +88,7 @@ class MEDIA_GPU_EXPORT VaapiVideoDecodeAccelerator
const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
override;
- static VideoDecodeAccelerator::SupportedProfiles GetSupportedProfiles(
- const gpu::GpuDriverBugWorkarounds& workarounds);
+ static VideoDecodeAccelerator::SupportedProfiles GetSupportedProfiles();
// DecodeSurfaceHandler implementation.
scoped_refptr<VASurface> CreateSurface() override;
diff --git a/chromium/media/gpu/vaapi/vaapi_video_decoder.cc b/chromium/media/gpu/vaapi/vaapi_video_decoder.cc
index e04ae1a0328..66c1b732e0e 100644
--- a/chromium/media/gpu/vaapi/vaapi_video_decoder.cc
+++ b/chromium/media/gpu/vaapi/vaapi_video_decoder.cc
@@ -10,10 +10,10 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
+#include "base/containers/contains.h"
#include "base/containers/fixed_flat_map.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
-#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
#include "build/chromeos_buildflags.h"
#include "media/base/bind_to_current_loop.h"
@@ -50,7 +50,7 @@ namespace {
// Size of the timestamp cache, needs to be large enough for frame-reordering.
constexpr size_t kTimestampCacheSize = 128;
-base::Optional<VideoPixelFormat> GetPixelFormatForBitDepth(uint8_t bit_depth) {
+absl::optional<VideoPixelFormat> GetPixelFormatForBitDepth(uint8_t bit_depth) {
constexpr auto kSupportedBitDepthAndGfxFormats = base::MakeFixedFlatMap<
uint8_t, gfx::BufferFormat>({
#if defined(USE_OZONE)
@@ -61,7 +61,7 @@ base::Optional<VideoPixelFormat> GetPixelFormatForBitDepth(uint8_t bit_depth) {
});
if (!base::Contains(kSupportedBitDepthAndGfxFormats, bit_depth)) {
VLOGF(1) << "Unsupported bit depth: " << base::strict_cast<int>(bit_depth);
- return base::nullopt;
+ return absl::nullopt;
}
return GfxBufferFormatToVideoPixelFormat(
kSupportedBitDepthAndGfxFormats.at(bit_depth));
@@ -100,10 +100,9 @@ std::unique_ptr<DecoderInterface> VaapiVideoDecoder::Create(
}
// static
-SupportedVideoDecoderConfigs VaapiVideoDecoder::GetSupportedConfigs(
- const gpu::GpuDriverBugWorkarounds& workarounds) {
+SupportedVideoDecoderConfigs VaapiVideoDecoder::GetSupportedConfigs() {
return ConvertFromSupportedProfiles(
- VaapiWrapper::GetSupportedDecodeProfiles(workarounds),
+ VaapiWrapper::GetSupportedDecodeProfiles(),
#if BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
true /* allow_encrypted */);
#else
@@ -275,6 +274,7 @@ void VaapiVideoDecoder::Initialize(const VideoDecoderConfig& config,
profile_ = profile;
color_space_ = config.color_space_info();
+ hdr_metadata_ = config.hdr_metadata();
encryption_scheme_ = config.encryption_scheme();
auto accel_status = CreateAcceleratedVideoDecoder();
if (!accel_status.is_ok()) {
@@ -380,7 +380,7 @@ void VaapiVideoDecoder::HandleDecodeTask() {
// Decoding was successful, notify client and try to schedule the next
// task. Switch to the idle state if we ran out of buffers to decode.
std::move(current_decode_task_->decode_done_cb_).Run(DecodeStatus::OK);
- current_decode_task_ = base::nullopt;
+ current_decode_task_ = absl::nullopt;
if (!decode_task_queue_.empty()) {
ScheduleNextDecodeTask();
} else {
@@ -428,7 +428,7 @@ void VaapiVideoDecoder::ClearDecodeTaskQueue(DecodeStatus status) {
if (current_decode_task_) {
std::move(current_decode_task_->decode_done_cb_).Run(status);
- current_decode_task_ = base::nullopt;
+ current_decode_task_ = absl::nullopt;
}
while (!decode_task_queue_.empty()) {
@@ -607,7 +607,7 @@ void VaapiVideoDecoder::SurfaceReady(scoped_refptr<VASurface> va_surface,
const auto gfx_color_space = color_space.ToGfxColorSpace();
if (gfx_color_space.IsValid())
video_frame->set_color_space(gfx_color_space);
-
+ video_frame->set_hdr_metadata(hdr_metadata_);
output_cb_.Run(std::move(video_frame));
}
@@ -651,7 +651,7 @@ void VaapiVideoDecoder::ApplyResolutionChangeWithScreenSizes(
return;
const uint8_t bit_depth = decoder_->GetBitDepth();
- const base::Optional<VideoPixelFormat> format =
+ const absl::optional<VideoPixelFormat> format =
GetPixelFormatForBitDepth(bit_depth);
if (!format) {
SetState(State::kError);
@@ -740,7 +740,7 @@ void VaapiVideoDecoder::ApplyResolutionChangeWithScreenSizes(
// Create the surface pool for decoding, the normal pool will be used for
// output.
const size_t decode_pool_size = decoder_->GetRequiredNumOfPictures();
- const base::Optional<gfx::BufferFormat> buffer_format =
+ const absl::optional<gfx::BufferFormat> buffer_format =
VideoPixelFormatToGfxBufferFormat(*format);
if (!buffer_format) {
decode_to_output_scale_factor_.reset();
@@ -761,7 +761,7 @@ void VaapiVideoDecoder::ApplyResolutionChangeWithScreenSizes(
std::unique_ptr<ScopedVASurface> surface =
vaapi_wrapper_->CreateScopedVASurface(
base::strict_cast<unsigned int>(va_rt_format), decoder_pic_size,
- /*visible_size=*/base::nullopt, va_fourcc);
+ /*visible_size=*/absl::nullopt, va_fourcc);
if (!surface) {
while (!decode_surface_pool_for_scaling_.empty())
decode_surface_pool_for_scaling_.pop();
@@ -893,7 +893,7 @@ void VaapiVideoDecoder::Flush() {
// Notify the client flushing is done.
std::move(current_decode_task_->decode_done_cb_).Run(DecodeStatus::OK);
- current_decode_task_ = base::nullopt;
+ current_decode_task_ = absl::nullopt;
// Wait for new decodes, no decode tasks should be queued while flushing.
SetState(State::kWaitingForInput);
diff --git a/chromium/media/gpu/vaapi/vaapi_video_decoder.h b/chromium/media/gpu/vaapi/vaapi_video_decoder.h
index 06cdb0004df..8aabb95f147 100644
--- a/chromium/media/gpu/vaapi/vaapi_video_decoder.h
+++ b/chromium/media/gpu/vaapi/vaapi_video_decoder.h
@@ -19,7 +19,6 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "build/chromeos_buildflags.h"
@@ -32,13 +31,11 @@
#include "media/gpu/chromeos/video_decoder_pipeline.h"
#include "media/gpu/decode_surface_handler.h"
#include "media/gpu/vaapi/vaapi_utils.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"
-
-namespace gpu {
-class GpuDriverBugWorkarounds;
-}
+#include "ui/gfx/hdr_metadata.h"
namespace media {
@@ -56,8 +53,7 @@ class VaapiVideoDecoder : public DecoderInterface,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
base::WeakPtr<DecoderInterface::Client> client);
- static SupportedVideoDecoderConfigs GetSupportedConfigs(
- const gpu::GpuDriverBugWorkarounds& workarounds);
+ static SupportedVideoDecoderConfigs GetSupportedConfigs();
// DecoderInterface implementation.
void Initialize(const VideoDecoderConfig& config,
@@ -172,10 +168,10 @@ class VaapiVideoDecoder : public DecoderInterface,
// request a reset. (Used in protected decoding).
WaitingCB waiting_cb_;
- // The video stream's profile.
+ // Bitstream information, written during Initialize().
VideoCodecProfile profile_ = VIDEO_CODEC_PROFILE_UNKNOWN;
- // Color space of the video frame.
VideoColorSpace color_space_;
+ absl::optional<gfx::HDRMetadata> hdr_metadata_;
// Ratio of natural size to |visible_rect_| of the output frames.
double pixel_aspect_ratio_ = 0.0;
@@ -192,7 +188,7 @@ class VaapiVideoDecoder : public DecoderInterface,
// Queue containing all requested decode tasks.
base::queue<DecodeTask> decode_task_queue_;
// The decode task we're currently trying to execute.
- base::Optional<DecodeTask> current_decode_task_;
+ absl::optional<DecodeTask> current_decode_task_;
// The next input buffer id.
int32_t next_buffer_id_ = 0;
@@ -240,7 +236,7 @@ class VaapiVideoDecoder : public DecoderInterface,
// When we are doing scaled decoding, this is the scale factor we are using,
// and applies the same in both dimensions.
- base::Optional<float> decode_to_output_scale_factor_;
+ absl::optional<float> decode_to_output_scale_factor_;
SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chromium/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/chromium/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
index 035361dea27..059f3f68b65 100644
--- a/chromium/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
+++ b/chromium/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -92,7 +92,7 @@ gfx::Size GetInputFrameSize(VideoPixelFormat format,
const gfx::Size& visible_size) {
// Get a VideoFrameLayout of a graphic buffer with the same gfx::BufferUsage
// as camera stack.
- base::Optional<VideoFrameLayout> layout = GetPlatformVideoFrameLayout(
+ absl::optional<VideoFrameLayout> layout = GetPlatformVideoFrameLayout(
/*gpu_memory_buffer_factory=*/nullptr, format, visible_size,
gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE);
if (!layout || layout->planes().empty()) {
@@ -1092,7 +1092,7 @@ bool VaapiVideoEncodeAccelerator::H264Accelerator::SubmitFrameParameters(
seq_param.bits_per_second = encode_params.bitrate_bps;
SPS_TO_SP(max_num_ref_frames);
- base::Optional<gfx::Size> coded_size = sps.GetCodedSize();
+ absl::optional<gfx::Size> coded_size = sps.GetCodedSize();
if (!coded_size) {
DVLOGF(1) << "Invalid coded size";
return false;
diff --git a/chromium/media/gpu/vaapi/vaapi_wrapper.cc b/chromium/media/gpu/vaapi/vaapi_wrapper.cc
index df500d8bdeb..4333c6adc0d 100644
--- a/chromium/media/gpu/vaapi/vaapi_wrapper.cc
+++ b/chromium/media/gpu/vaapi/vaapi_wrapper.cc
@@ -23,6 +23,7 @@
#include "base/bind.h"
#include "base/bits.h"
#include "base/callback_helpers.h"
+#include "base/containers/contains.h"
#include "base/cpu.h"
#include "base/environment.h"
#include "base/files/scoped_file.h"
@@ -51,7 +52,6 @@
// Auto-generated for dlopen libva libraries
#include "media/gpu/vaapi/va_stubs.h"
-#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "third_party/libva_protected_content/va_protected_content.h"
#include "third_party/libyuv/include/libyuv.h"
#include "third_party/minigbm/src/external/i915_drm.h"
@@ -1433,8 +1433,7 @@ VaapiWrapper::GetSupportedEncodeProfiles() {
// static
VideoDecodeAccelerator::SupportedProfiles
-VaapiWrapper::GetSupportedDecodeProfiles(
- const gpu::GpuDriverBugWorkarounds& workarounds) {
+VaapiWrapper::GetSupportedDecodeProfiles() {
VideoDecodeAccelerator::SupportedProfiles profiles;
for (const auto& media_to_va_profile_map_entry : GetProfileCodecMap()) {
@@ -1442,15 +1441,6 @@ VaapiWrapper::GetSupportedDecodeProfiles(
const VAProfile va_profile = media_to_va_profile_map_entry.second;
DCHECK(va_profile != VAProfileNone);
- if (media_profile == VP8PROFILE_ANY &&
- workarounds.disable_accelerated_vp8_decode) {
- continue;
- }
- if (media_profile == VP9PROFILE_PROFILE2 &&
- workarounds.disable_accelerated_vp9_profile2_decode) {
- continue;
- }
-
const VASupportedProfiles::ProfileInfo* profile_info =
VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile);
if (!profile_info)
@@ -1601,11 +1591,11 @@ bool VaapiWrapper::IsVppResolutionAllowed(const gfx::Size& size) {
VAProfileNone);
if (!profile_info)
return false;
- return gfx::Rect(profile_info->min_resolution.width(),
- profile_info->min_resolution.height(),
- profile_info->max_resolution.width(),
- profile_info->max_resolution.height())
- .Contains(size.width(), size.height());
+
+ return size.width() >= profile_info->min_resolution.width() &&
+ size.width() <= profile_info->max_resolution.width() &&
+ size.height() >= profile_info->min_resolution.height() &&
+ size.height() <= profile_info->max_resolution.height();
}
// static
@@ -1765,7 +1755,7 @@ bool VaapiWrapper::CreateContextAndSurfaces(
std::unique_ptr<ScopedVASurface> VaapiWrapper::CreateContextAndScopedVASurface(
unsigned int va_format,
const gfx::Size& size,
- const base::Optional<gfx::Size>& visible_size) {
+ const absl::optional<gfx::Size>& visible_size) {
if (va_context_id_ != VA_INVALID_ID) {
LOG(ERROR) << "The current context should be destroyed before creating a "
"new one";
@@ -2549,7 +2539,10 @@ bool VaapiWrapper::DownloadFromVABuffer(VABufferID buffer_id,
base::AutoLock auto_lock(*va_lock_);
TRACE_EVENT0("media,gpu", "VaapiWrapper::DownloadFromVABufferLocked");
- {
+ // vaSyncSurface() is not necessary on Intel platforms as long as there is a
+ // vaMapBuffer() like in ScopedVABufferMapping below, see b/184312032.
+ if (GetImplementationType() != VAImplementation::kIntelI965 &&
+ GetImplementationType() != VAImplementation::kIntelIHD) {
TRACE_EVENT0("media,gpu", "VaapiWrapper::DownloadFromVABuffer_SyncSurface");
const VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id);
VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, false);
@@ -2622,8 +2615,8 @@ bool VaapiWrapper::IsRotationSupported() {
bool VaapiWrapper::BlitSurface(const VASurface& va_surface_src,
const VASurface& va_surface_dest,
- base::Optional<gfx::Rect> src_rect,
- base::Optional<gfx::Rect> dest_rect,
+ absl::optional<gfx::Rect> src_rect,
+ absl::optional<gfx::Rect> dest_rect,
VideoRotation rotation) {
DCHECK_EQ(mode_, kVideoProcess);
base::AutoLock auto_lock(*va_lock_);
@@ -2919,7 +2912,7 @@ bool VaapiWrapper::CreateSurfaces(unsigned int va_format,
std::unique_ptr<ScopedVASurface> VaapiWrapper::CreateScopedVASurface(
unsigned int va_rt_format,
const gfx::Size& size,
- const base::Optional<gfx::Size>& visible_size,
+ const absl::optional<gfx::Size>& visible_size,
uint32_t va_fourcc) {
if (kInvalidVaRtFormat == va_rt_format) {
LOG(ERROR) << "Invalid VA RT format to CreateScopedVASurface";
diff --git a/chromium/media/gpu/vaapi/vaapi_wrapper.h b/chromium/media/gpu/vaapi/vaapi_wrapper.h
index 29b68649982..da1e5477233 100644
--- a/chromium/media/gpu/vaapi/vaapi_wrapper.h
+++ b/chromium/media/gpu/vaapi/vaapi_wrapper.h
@@ -24,7 +24,6 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
-#include "base/optional.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "build/chromeos_buildflags.h"
@@ -33,6 +32,7 @@
#include "media/gpu/vaapi/vaapi_utils.h"
#include "media/video/video_decode_accelerator.h"
#include "media/video/video_encode_accelerator.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
#if defined(USE_X11)
@@ -46,10 +46,6 @@ class NativePixmapDmaBuf;
class Rect;
}
-namespace gpu {
-class GpuDriverBugWorkarounds;
-}
-
namespace media {
constexpr unsigned int kInvalidVaRtFormat = 0u;
@@ -169,8 +165,7 @@ class MEDIA_GPU_EXPORT VaapiWrapper
static VideoEncodeAccelerator::SupportedProfiles GetSupportedEncodeProfiles();
// Return the supported video decode profiles.
- static VideoDecodeAccelerator::SupportedProfiles GetSupportedDecodeProfiles(
- const gpu::GpuDriverBugWorkarounds& workarounds);
+ static VideoDecodeAccelerator::SupportedProfiles GetSupportedDecodeProfiles();
// Return true when decoding using |va_profile| is supported.
static bool IsDecodeSupported(VAProfile va_profile);
@@ -269,7 +264,7 @@ class MEDIA_GPU_EXPORT VaapiWrapper
std::unique_ptr<ScopedVASurface> CreateContextAndScopedVASurface(
unsigned int va_format,
const gfx::Size& size,
- const base::Optional<gfx::Size>& visible_size = base::nullopt);
+ const absl::optional<gfx::Size>& visible_size = absl::nullopt);
// Attempts to create a protected session that will be attached to the
// decoding context to enable encrypted video decoding. If it cannot be
@@ -315,7 +310,7 @@ class MEDIA_GPU_EXPORT VaapiWrapper
std::unique_ptr<ScopedVASurface> CreateScopedVASurface(
unsigned int va_rt_format,
const gfx::Size& size,
- const base::Optional<gfx::Size>& visible_size = base::nullopt,
+ const absl::optional<gfx::Size>& visible_size = absl::nullopt,
uint32_t va_fourcc = 0);
// Creates a self-releasing VASurface from |pixmap|. The created VASurface
@@ -469,8 +464,8 @@ class MEDIA_GPU_EXPORT VaapiWrapper
// be used to specify the area used in the blit.
bool BlitSurface(const VASurface& va_surface_src,
const VASurface& va_surface_dest,
- base::Optional<gfx::Rect> src_rect = base::nullopt,
- base::Optional<gfx::Rect> dest_rect = base::nullopt,
+ absl::optional<gfx::Rect> src_rect = absl::nullopt,
+ absl::optional<gfx::Rect> dest_rect = absl::nullopt,
VideoRotation rotation = VIDEO_ROTATION_0)
WARN_UNUSED_RESULT;
diff --git a/chromium/media/gpu/vaapi/vp9_encoder_unittest.cc b/chromium/media/gpu/vaapi/vp9_encoder_unittest.cc
index 689506089bf..bed699b56bb 100644
--- a/chromium/media/gpu/vaapi/vp9_encoder_unittest.cc
+++ b/chromium/media/gpu/vaapi/vp9_encoder_unittest.cc
@@ -12,13 +12,13 @@
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
-#include "base/optional.h"
#include "base/stl_util.h"
#include "media/filters/vp9_parser.h"
#include "media/gpu/vaapi/vp9_rate_control.h"
#include "media/gpu/vaapi/vp9_temporal_layers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/libvpx/source/libvpx/vp9/common/vp9_blockd.h"
#include "third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h"
@@ -42,8 +42,8 @@ VideoEncodeAccelerator::Config kDefaultVideoEncodeAcceleratorConfig(
VP9PROFILE_PROFILE0,
14000000 /* = maximum bitrate in bits per second for level 3.1 */,
VideoEncodeAccelerator::kDefaultFramerate,
- base::nullopt /* gop_length */,
- base::nullopt /* h264 output level*/,
+ absl::nullopt /* gop_length */,
+ absl::nullopt /* h264 output level*/,
false /* is_constrained_h264 */,
VideoEncodeAccelerator::Config::StorageType::kShmem);
@@ -56,7 +56,7 @@ void GetTemporalLayer(bool keyframe,
int index,
size_t num_temporal_layers,
std::array<bool, kVp9NumRefsPerFrame>* ref_frames_used,
- base::Optional<uint8_t>* temporal_layer_id) {
+ absl::optional<uint8_t>* temporal_layer_id) {
switch (num_temporal_layers) {
case 1:
*ref_frames_used =
@@ -211,9 +211,9 @@ class VP9EncoderTest : public ::testing::TestWithParam<VP9EncoderTestParam> {
void EncodeSequence(bool is_keyframe);
void EncodeConstantQuantizationParameterSequence(
bool is_keyframe,
- base::Optional<std::array<bool, kVp9NumRefsPerFrame>>
+ absl::optional<std::array<bool, kVp9NumRefsPerFrame>>
expected_ref_frames_used,
- base::Optional<uint8_t> expected_temporal_layer_id = base::nullopt);
+ absl::optional<uint8_t> expected_temporal_layer_id = absl::nullopt);
void UpdateRatesTest(BitrateControl bitrate_control,
size_t num_temporal_layers);
@@ -312,9 +312,9 @@ void VP9EncoderTest::EncodeSequence(bool is_keyframe) {
void VP9EncoderTest::EncodeConstantQuantizationParameterSequence(
bool is_keyframe,
- base::Optional<std::array<bool, kVp9NumRefsPerFrame>>
+ absl::optional<std::array<bool, kVp9NumRefsPerFrame>>
expected_ref_frames_used,
- base::Optional<uint8_t> expected_temporal_layer_id) {
+ absl::optional<uint8_t> expected_temporal_layer_id) {
InSequence seq;
auto encode_job = CreateEncodeJob(is_keyframe);
scoped_refptr<VP9Picture> picture(new VP9Picture);
@@ -390,7 +390,7 @@ void VP9EncoderTest::UpdateRatesTest(BitrateControl bitrate_control,
num_temporal_layers);
if (bitrate_control == BitrateControl::kConstantQuantizationParameter) {
EncodeConstantQuantizationParameterSequence(is_keyframe, {},
- base::nullopt);
+ absl::nullopt);
} else {
EncodeSequence(is_keyframe);
}
@@ -460,7 +460,7 @@ TEST_P(VP9EncoderTest, EncodeWithSoftwareBitrateControl) {
for (size_t i = 0; i < kEncodeFrames; i++) {
const bool is_keyframe = i == 0;
std::array<bool, kVp9NumRefsPerFrame> ref_frames_used;
- base::Optional<uint8_t> temporal_layer_id;
+ absl::optional<uint8_t> temporal_layer_id;
GetTemporalLayer(is_keyframe, i, num_temporal_layers, &ref_frames_used,
&temporal_layer_id);
EncodeConstantQuantizationParameterSequence(is_keyframe, ref_frames_used,
@@ -495,7 +495,7 @@ TEST_P(VP9EncoderTest, ForceKeyFrameWithSoftwareBitrateControl) {
for (size_t i = 0; i < kKeyFrameInterval; i++) {
const bool is_keyframe = i == 0;
std::array<bool, kVp9NumRefsPerFrame> ref_frames_used;
- base::Optional<uint8_t> temporal_layer_id;
+ absl::optional<uint8_t> temporal_layer_id;
GetTemporalLayer(is_keyframe, i, num_temporal_layers, &ref_frames_used,
&temporal_layer_id);
EncodeConstantQuantizationParameterSequence(is_keyframe, ref_frames_used,
diff --git a/chromium/media/gpu/vaapi/vp9_rate_control.h b/chromium/media/gpu/vaapi/vp9_rate_control.h
index 116f47f5895..5c03eb3db09 100644
--- a/chromium/media/gpu/vaapi/vp9_rate_control.h
+++ b/chromium/media/gpu/vaapi/vp9_rate_control.h
@@ -7,7 +7,7 @@
#include <memory>
#include "base/callback.h"
-#include "base/optional.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace libvpx {
struct VP9FrameParamsQpRTC;
diff --git a/chromium/media/gpu/vaapi/vp9_temporal_layers_unittest.cc b/chromium/media/gpu/vaapi/vp9_temporal_layers_unittest.cc
index 7b4f3cb3795..354138ab62d 100644
--- a/chromium/media/gpu/vaapi/vp9_temporal_layers_unittest.cc
+++ b/chromium/media/gpu/vaapi/vp9_temporal_layers_unittest.cc
@@ -9,12 +9,13 @@
#include <map>
#include <vector>
-#include "base/optional.h"
+#include "base/containers/contains.h"
#include "media/filters/vp9_parser.h"
#include "media/gpu/vp9_picture.h"
#include "media/gpu/vp9_reference_frame_vector.h"
#include "media/video/video_encode_accelerator.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
class VP9TemporalLayersTest : public ::testing::TestWithParam<size_t> {
diff --git a/chromium/media/gpu/video_decode_accelerator_perf_tests.cc b/chromium/media/gpu/video_decode_accelerator_perf_tests.cc
index 8037133f95f..d6fd4d309bb 100644
--- a/chromium/media/gpu/video_decode_accelerator_perf_tests.cc
+++ b/chromium/media/gpu/video_decode_accelerator_perf_tests.cc
@@ -9,7 +9,6 @@
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
-#include "base/strings/stringprintf.h"
#include "media/base/test_data_util.h"
#include "media/gpu/test/video.h"
#include "media/gpu/test/video_player/frame_renderer_dummy.h"
diff --git a/chromium/media/gpu/video_encode_accelerator_perf_tests.cc b/chromium/media/gpu/video_encode_accelerator_perf_tests.cc
index 6e54c3d784f..d38d78f9c36 100644
--- a/chromium/media/gpu/video_encode_accelerator_perf_tests.cc
+++ b/chromium/media/gpu/video_encode_accelerator_perf_tests.cc
@@ -10,8 +10,6 @@
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
-#include "base/optional.h"
-#include "base/strings/stringprintf.h"
#include "media/base/bitstream_buffer.h"
#include "media/base/media_util.h"
#include "media/base/test_data_util.h"
@@ -24,6 +22,7 @@
#include "media/gpu/test/video_frame_validator.h"
#include "media/gpu/test/video_test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace test {
@@ -584,7 +583,7 @@ int main(int argc, char** argv) {
base::FilePath video_metadata_path =
(args.size() >= 2) ? base::FilePath(args[1]) : base::FilePath();
std::string codec = "h264";
- base::Optional<uint32_t> encode_bitrate;
+ absl::optional<uint32_t> encode_bitrate;
// Parse command line arguments.
base::FilePath::StringType output_folder = media::test::kDefaultOutputFolder;
diff --git a/chromium/media/gpu/video_encode_accelerator_tests.cc b/chromium/media/gpu/video_encode_accelerator_tests.cc
index 99c1d1db010..1948f123838 100644
--- a/chromium/media/gpu/video_encode_accelerator_tests.cc
+++ b/chromium/media/gpu/video_encode_accelerator_tests.cc
@@ -8,7 +8,6 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
-#include "base/optional.h"
#include "base/strings/string_number_conversions.h"
#include "media/base/media_util.h"
#include "media/base/test_data_util.h"
@@ -29,6 +28,7 @@
#include "media/gpu/test/video_test_environment.h"
#include "media/gpu/test/video_test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace test {
@@ -128,7 +128,7 @@ class VideoEncoderTest : public ::testing::Test {
const VideoDecoderConfig& decoder_config,
const size_t last_frame_index,
VideoFrameValidator::GetModelFrameCB get_model_frame_cb,
- base::Optional<size_t> num_vp9_temporal_layers_to_decode) {
+ absl::optional<size_t> num_vp9_temporal_layers_to_decode) {
std::vector<std::unique_ptr<VideoFrameProcessor>> video_frame_processors;
// Attach a video frame writer to store individual frames to disk if
@@ -255,7 +255,7 @@ class VideoEncoderTest : public ::testing::Test {
} else {
bitstream_processors.emplace_back(CreateBitstreamValidator(
video, decoder_config, config.num_frames_to_encode - 1,
- get_model_frame_cb, base::nullopt));
+ get_model_frame_cb, absl::nullopt));
LOG_ASSERT(bitstream_processors.back());
}
return bitstream_processors;
@@ -276,19 +276,19 @@ class VideoEncoderTest : public ::testing::Test {
std::unique_ptr<RawDataHelper> raw_data_helper_;
};
-base::Optional<std::string> SupportsDynamicFramerate() {
+absl::optional<std::string> SupportsDynamicFramerate() {
return g_env->IsKeplerUsed()
- ? base::make_optional<std::string>(
+ ? absl::make_optional<std::string>(
"The rate controller in the kepler firmware doesn't handle "
"frame rate changes correctly.")
- : base::nullopt;
+ : absl::nullopt;
}
-base::Optional<std::string> SupportsNV12DmaBufInput() {
- return g_env->IsKeplerUsed() ? base::make_optional<std::string>(
+absl::optional<std::string> SupportsNV12DmaBufInput() {
+ return g_env->IsKeplerUsed() ? absl::make_optional<std::string>(
"Encoding with dmabuf input frames is not "
"supported in kepler.")
- : base::nullopt;
+ : absl::nullopt;
}
} // namespace
@@ -722,7 +722,7 @@ int main(int argc, char** argv) {
media::test::VideoEncoderTestEnvironment::Create(
video_path, video_metadata_path, enable_bitstream_validator,
output_folder, codec, num_temporal_layers, output_bitstream,
- /*output_bitrate=*/base::nullopt, frame_output_config);
+ /*output_bitrate=*/absl::nullopt, frame_output_config);
if (!test_environment)
return EXIT_FAILURE;
diff --git a/chromium/media/gpu/vp9_picture.h b/chromium/media/gpu/vp9_picture.h
index a200bbd2bb7..75490d1c309 100644
--- a/chromium/media/gpu/vp9_picture.h
+++ b/chromium/media/gpu/vp9_picture.h
@@ -8,10 +8,10 @@
#include <memory>
#include "base/macros.h"
-#include "base/optional.h"
#include "media/filters/vp9_parser.h"
#include "media/gpu/codec_picture.h"
#include "media/video/video_encode_accelerator.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -33,7 +33,7 @@ class VP9Picture : public CodecPicture {
std::unique_ptr<Vp9FrameHeader> frame_hdr;
- base::Optional<Vp9Metadata> metadata_for_encoding;
+ absl::optional<Vp9Metadata> metadata_for_encoding;
protected:
~VP9Picture() override;
diff --git a/chromium/media/gpu/windows/d3d11_copying_texture_wrapper.cc b/chromium/media/gpu/windows/d3d11_copying_texture_wrapper.cc
index 96e72747877..8d0a4c2cc15 100644
--- a/chromium/media/gpu/windows/d3d11_copying_texture_wrapper.cc
+++ b/chromium/media/gpu/windows/d3d11_copying_texture_wrapper.cc
@@ -20,7 +20,7 @@ CopyingTexture2DWrapper::CopyingTexture2DWrapper(
std::unique_ptr<Texture2DWrapper> output_wrapper,
scoped_refptr<VideoProcessorProxy> processor,
ComD3D11Texture2D output_texture,
- base::Optional<gfx::ColorSpace> output_color_space)
+ absl::optional<gfx::ColorSpace> output_color_space)
: size_(size),
video_processor_(std::move(processor)),
output_texture_wrapper_(std::move(output_wrapper)),
diff --git a/chromium/media/gpu/windows/d3d11_copying_texture_wrapper.h b/chromium/media/gpu/windows/d3d11_copying_texture_wrapper.h
index 5fb2fffef9b..31c6a40570b 100644
--- a/chromium/media/gpu/windows/d3d11_copying_texture_wrapper.h
+++ b/chromium/media/gpu/windows/d3d11_copying_texture_wrapper.h
@@ -8,10 +8,10 @@
#include <memory>
#include <vector>
-#include "base/optional.h"
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/windows/d3d11_picture_buffer.h"
#include "media/gpu/windows/d3d11_video_processor_proxy.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -28,7 +28,7 @@ class MEDIA_GPU_EXPORT CopyingTexture2DWrapper : public Texture2DWrapper {
std::unique_ptr<Texture2DWrapper> output_wrapper,
scoped_refptr<VideoProcessorProxy> processor,
ComD3D11Texture2D output_texture,
- base::Optional<gfx::ColorSpace> output_color_space);
+ absl::optional<gfx::ColorSpace> output_color_space);
~CopyingTexture2DWrapper() override;
Status ProcessTexture(const gfx::ColorSpace& input_color_space,
@@ -50,10 +50,10 @@ class MEDIA_GPU_EXPORT CopyingTexture2DWrapper : public Texture2DWrapper {
std::unique_ptr<Texture2DWrapper> output_texture_wrapper_;
ComD3D11Texture2D output_texture_;
// If set, then this is the desired output color space for the copy.
- base::Optional<gfx::ColorSpace> output_color_space_;
+ absl::optional<gfx::ColorSpace> output_color_space_;
// If set, this is the color space that we last saw in ProcessTexture.
- base::Optional<gfx::ColorSpace> previous_input_color_space_;
+ absl::optional<gfx::ColorSpace> previous_input_color_space_;
ComD3D11Texture2D texture_;
size_t array_slice_ = 0;
diff --git a/chromium/media/gpu/windows/d3d11_copying_texture_wrapper_unittest.cc b/chromium/media/gpu/windows/d3d11_copying_texture_wrapper_unittest.cc
index a999fe50fe3..4119647c6ae 100644
--- a/chromium/media/gpu/windows/d3d11_copying_texture_wrapper_unittest.cc
+++ b/chromium/media/gpu/windows/d3d11_copying_texture_wrapper_unittest.cc
@@ -76,10 +76,10 @@ class MockVideoProcessorProxy : public VideoProcessorProxy {
MOCK_METHOD0(MockVideoProcessorBlt, HRESULT());
// Most recent arguments to SetStream/OutputColorSpace()/etc.
- base::Optional<gfx::ColorSpace> last_stream_color_space_;
- base::Optional<gfx::ColorSpace> last_output_color_space_;
- base::Optional<DXGI_HDR_METADATA_HDR10> last_stream_metadata_;
- base::Optional<DXGI_HDR_METADATA_HDR10> last_display_metadata_;
+ absl::optional<gfx::ColorSpace> last_stream_color_space_;
+ absl::optional<gfx::ColorSpace> last_output_color_space_;
+ absl::optional<DXGI_HDR_METADATA_HDR10> last_stream_metadata_;
+ absl::optional<DXGI_HDR_METADATA_HDR10> last_display_metadata_;
private:
~MockVideoProcessorProxy() override = default;
@@ -212,7 +212,7 @@ TEST_P(D3D11CopyingTexture2DWrapperTest,
MockVideoProcessorProxy* processor_raw = processor.get();
// Provide an unlikely color space, to see if it gets to the video processor,
// if we're not just doing a pass-through of the input.
- base::Optional<gfx::ColorSpace> copy_color_space;
+ absl::optional<gfx::ColorSpace> copy_color_space;
if (!GetPassthroughColorSpace())
copy_color_space = gfx::ColorSpace::CreateDisplayP3D65();
auto texture_wrapper = ExpectTextureWrapper();
diff --git a/chromium/media/gpu/windows/d3d11_h264_accelerator.h b/chromium/media/gpu/windows/d3d11_h264_accelerator.h
index 08ca39f8bd8..59198167366 100644
--- a/chromium/media/gpu/windows/d3d11_h264_accelerator.h
+++ b/chromium/media/gpu/windows/d3d11_h264_accelerator.h
@@ -123,4 +123,4 @@ class D3D11H264Accelerator : public H264Decoder::H264Accelerator {
} // namespace media
-#endif // MEDIA_GPU_D3D11_WINDOWS_H264_ACCELERATOR_H_
+#endif // MEDIA_GPU_WINDOWS_D3D11_H264_ACCELERATOR_H_
diff --git a/chromium/media/gpu/windows/d3d11_texture_selector.cc b/chromium/media/gpu/windows/d3d11_texture_selector.cc
index 7a92a8f5280..34f5db5bdbb 100644
--- a/chromium/media/gpu/windows/d3d11_texture_selector.cc
+++ b/chromium/media/gpu/windows/d3d11_texture_selector.cc
@@ -50,7 +50,7 @@ std::unique_ptr<TextureSelector> TextureSelector::Create(
MediaLog* media_log) {
VideoPixelFormat output_pixel_format;
DXGI_FORMAT output_dxgi_format;
- base::Optional<gfx::ColorSpace> output_color_space;
+ absl::optional<gfx::ColorSpace> output_color_space;
// TODO(liberato): add other options here, like "copy to rgb" for NV12.
switch (decoder_output_format) {
@@ -66,7 +66,6 @@ std::unique_ptr<TextureSelector> TextureSelector::Create(
}
case DXGI_FORMAT_P010: {
MEDIA_LOG(INFO, media_log) << "D3D11VideoDecoder producing P010";
- output_pixel_format = PIXEL_FORMAT_ARGB;
// TODO(liberato): handle case where we bind P010 directly (see dxva).
@@ -94,6 +93,7 @@ std::unique_ptr<TextureSelector> TextureSelector::Create(
// TODO(liberato): use the format checker, else bind P010.
MEDIA_LOG(INFO, media_log) << "D3D11VideoDecoder: 8 bit sRGB";
output_dxgi_format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ output_pixel_format = PIXEL_FORMAT_ARGB;
output_color_space = gfx::ColorSpace::CreateSRGB();
} else {
// Bind P010 directly, since we can't copy.
@@ -116,9 +116,10 @@ std::unique_ptr<TextureSelector> TextureSelector::Create(
output_color_space = gfx::ColorSpace::CreateSCRGBLinear();
} else if (format_checker->CheckOutputFormatSupport(
DXGI_FORMAT_R10G10B10A2_UNORM)) {
- MEDIA_LOG(INFO, media_log) << "D3D11VideoDecoder: BGRA10 scRGBLinear";
+ MEDIA_LOG(INFO, media_log) << "D3D11VideoDecoder: RGB10A2 HDR10/PQ";
output_dxgi_format = DXGI_FORMAT_R10G10B10A2_UNORM;
- output_color_space = gfx::ColorSpace::CreateSCRGBLinear();
+ output_pixel_format = PIXEL_FORMAT_XB30;
+ output_color_space = gfx::ColorSpace::CreateHDR10();
} else {
// No support at all. Just bind P010, and hope for the best.
MEDIA_LOG(INFO, media_log)
@@ -149,9 +150,10 @@ std::unique_ptr<TextureSelector> TextureSelector::Create(
// If we're trying to produce an output texture that's different from what
// the decoder is providing, then we need to copy it. If sharing decoder
// textures is not allowed, then copy either way.
- bool needs_texture_copy = !SupportsZeroCopy(gpu_preferences, workarounds) ||
- (decoder_output_format != output_dxgi_format) ||
- base::FeatureList::IsEnabled(kD3D11VideoDecoderAlwaysCopy);
+ bool needs_texture_copy =
+ !SupportsZeroCopy(gpu_preferences, workarounds) ||
+ (decoder_output_format != output_dxgi_format) ||
+ base::FeatureList::IsEnabled(kD3D11VideoDecoderAlwaysCopy);
MEDIA_LOG(INFO, media_log)
<< "D3D11VideoDecoder output color space: "
@@ -178,8 +180,7 @@ std::unique_ptr<Texture2DWrapper> TextureSelector::CreateTextureWrapper(
ComD3D11Device device,
gfx::Size size) {
// TODO(liberato): If the output format is rgb, then create a pbuffer wrapper.
- return std::make_unique<DefaultTexture2DWrapper>(size, OutputDXGIFormat(),
- PixelFormat());
+ return std::make_unique<DefaultTexture2DWrapper>(size, OutputDXGIFormat());
}
bool TextureSelector::WillCopyForTesting() const {
@@ -190,7 +191,7 @@ CopyTextureSelector::CopyTextureSelector(
VideoPixelFormat pixfmt,
DXGI_FORMAT input_dxgifmt,
DXGI_FORMAT output_dxgifmt,
- base::Optional<gfx::ColorSpace> output_color_space,
+ absl::optional<gfx::ColorSpace> output_color_space,
ComD3D11VideoDevice video_device,
ComD3D11DeviceContext device_context)
: TextureSelector(pixfmt,
@@ -228,9 +229,7 @@ std::unique_ptr<Texture2DWrapper> CopyTextureSelector::CreateTextureWrapper(
return nullptr;
return std::make_unique<CopyingTexture2DWrapper>(
- size,
- std::make_unique<DefaultTexture2DWrapper>(size, OutputDXGIFormat(),
- PixelFormat()),
+ size, std::make_unique<DefaultTexture2DWrapper>(size, OutputDXGIFormat()),
video_processor_proxy_, out_texture, output_color_space_);
}
diff --git a/chromium/media/gpu/windows/d3d11_texture_selector.h b/chromium/media/gpu/windows/d3d11_texture_selector.h
index 7de0a4d891f..f27444bcb0d 100644
--- a/chromium/media/gpu/windows/d3d11_texture_selector.h
+++ b/chromium/media/gpu/windows/d3d11_texture_selector.h
@@ -78,7 +78,7 @@ class MEDIA_GPU_EXPORT CopyTextureSelector : public TextureSelector {
CopyTextureSelector(VideoPixelFormat pixfmt,
DXGI_FORMAT input_dxgifmt,
DXGI_FORMAT output_dxgifmt,
- base::Optional<gfx::ColorSpace> output_color_space,
+ absl::optional<gfx::ColorSpace> output_color_space,
ComD3D11VideoDevice video_device,
ComD3D11DeviceContext d3d11_device_context);
~CopyTextureSelector() override;
@@ -90,7 +90,7 @@ class MEDIA_GPU_EXPORT CopyTextureSelector : public TextureSelector {
bool WillCopyForTesting() const override;
private:
- base::Optional<gfx::ColorSpace> output_color_space_;
+ absl::optional<gfx::ColorSpace> output_color_space_;
scoped_refptr<VideoProcessorProxy> video_processor_proxy_;
};
diff --git a/chromium/media/gpu/windows/d3d11_texture_selector_unittest.cc b/chromium/media/gpu/windows/d3d11_texture_selector_unittest.cc
index 12bd030c458..9ebb9c34ca6 100644
--- a/chromium/media/gpu/windows/d3d11_texture_selector_unittest.cc
+++ b/chromium/media/gpu/windows/d3d11_texture_selector_unittest.cc
@@ -129,7 +129,7 @@ TEST_F(D3D11TextureSelectorUnittest, P010CopiesTo10BitRGBInHDR) {
CreateWithDefaultGPUInfo(DXGI_FORMAT_P010, ZeroCopyEnabled::kTrue,
TextureSelector::HDRMode::kSDROrHDR);
- EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_ARGB);
+ EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_XB30);
EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_R10G10B10A2_UNORM);
EXPECT_TRUE(tex_sel->WillCopyForTesting());
}
diff --git a/chromium/media/gpu/windows/d3d11_texture_wrapper.cc b/chromium/media/gpu/windows/d3d11_texture_wrapper.cc
index ed2ede8d1eb..0d1da963177 100644
--- a/chromium/media/gpu/windows/d3d11_texture_wrapper.cc
+++ b/chromium/media/gpu/windows/d3d11_texture_wrapper.cc
@@ -22,90 +22,43 @@ namespace media {
namespace {
-// Populates Viz |texture_formats| that map to the corresponding DXGI format and
-// VideoPixelFormat. Returns true if they can be successfully mapped.
-bool DXGIFormatToVizFormat(
- DXGI_FORMAT dxgi_format,
- VideoPixelFormat pixel_format,
- size_t textures_per_picture,
- std::array<viz::ResourceFormat, VideoFrame::kMaxPlanes>& texture_formats) {
+bool SupportsFormat(DXGI_FORMAT dxgi_format) {
switch (dxgi_format) {
case DXGI_FORMAT_NV12:
- DCHECK_EQ(textures_per_picture, 2u);
- texture_formats[0] = viz::RED_8; // Y
- texture_formats[1] = viz::RG_88; // UV
- return true;
case DXGI_FORMAT_P010:
- // TODO(crbug.com/1011555): P010 formats are not fully supported.
- // Treat them to be the same as NV12 for the time being.
- DCHECK_EQ(textures_per_picture, 2u);
- texture_formats[0] = viz::RED_8;
- texture_formats[1] = viz::RG_88;
- return true;
case DXGI_FORMAT_B8G8R8A8_UNORM:
- DCHECK_EQ(textures_per_picture, 1u);
- if (pixel_format != PIXEL_FORMAT_ARGB) {
- return false;
- }
- texture_formats[0] = viz::BGRA_8888;
- return true;
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
case DXGI_FORMAT_R16G16B16A16_FLOAT:
- DCHECK_EQ(textures_per_picture, 1u);
- if (pixel_format != PIXEL_FORMAT_RGBAF16)
- return false;
- texture_formats[0] = viz::RGBA_F16;
return true;
- default: // Unsupported
+ default:
return false;
}
}
-} // anonymous namespace
-
-// Handy structure so that we can activate / bind one or two textures.
-struct ScopedTextureEverything {
- ScopedTextureEverything(GLenum unit, GLuint service_id)
- : active_(unit), binder_(GL_TEXTURE_EXTERNAL_OES, service_id) {}
- ~ScopedTextureEverything() = default;
-
- // Order is important; we need |active_| to be constructed first
- // and destructed last.
- gl::ScopedActiveTexture active_;
- gl::ScopedTextureBinder binder_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedTextureEverything);
-};
-
-// Another handy helper class to guarantee that ScopedTextureEverythings
-// are deleted in reverse order. This is required so that the scoped
-// active texture unit doesn't change. Surprisingly, none of the stl
-// containers, or the chromium ones, seem to guarantee anything about
-// the order of destruction.
-struct OrderedDestructionList {
- OrderedDestructionList() = default;
- ~OrderedDestructionList() {
- // Erase last-to-first.
- while (!list_.empty())
- list_.pop_back();
- }
-
- template <typename... Args>
- void emplace_back(Args&&... args) {
- list_.emplace_back(std::forward<Args>(args)...);
+size_t NumPlanes(DXGI_FORMAT dxgi_format) {
+ switch (dxgi_format) {
+ case DXGI_FORMAT_NV12:
+ case DXGI_FORMAT_P010:
+ return 2;
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ return 1;
+ default:
+ NOTREACHED();
+ return 0;
}
+}
- std::list<ScopedTextureEverything> list_;
- DISALLOW_COPY_AND_ASSIGN(OrderedDestructionList);
-};
+} // anonymous namespace
Texture2DWrapper::Texture2DWrapper() = default;
Texture2DWrapper::~Texture2DWrapper() = default;
DefaultTexture2DWrapper::DefaultTexture2DWrapper(const gfx::Size& size,
- DXGI_FORMAT dxgi_format,
- VideoPixelFormat pixel_format)
- : size_(size), dxgi_format_(dxgi_format), pixel_format_(pixel_format) {}
+ DXGI_FORMAT dxgi_format)
+ : size_(size), dxgi_format_(dxgi_format) {}
DefaultTexture2DWrapper::~DefaultTexture2DWrapper() = default;
@@ -135,28 +88,17 @@ Status DefaultTexture2DWrapper::Init(
GetCommandBufferHelperCB get_helper_cb,
ComD3D11Texture2D texture,
size_t array_slice) {
- gpu_resources_ = base::SequenceBound<GpuResources>(
- std::move(gpu_task_runner),
- BindToCurrentLoop(base::BindOnce(&DefaultTexture2DWrapper::OnError,
- weak_factory_.GetWeakPtr())));
-
- const size_t textures_per_picture = VideoFrame::NumPlanes(pixel_format_);
-
- std::array<viz::ResourceFormat, VideoFrame::kMaxPlanes> texture_formats;
- if (!DXGIFormatToVizFormat(dxgi_format_, pixel_format_, textures_per_picture,
- texture_formats)) {
+ if (!SupportsFormat(dxgi_format_))
return Status(StatusCode::kUnsupportedTextureFormatForBind);
- }
// Generate mailboxes and holders.
// TODO(liberato): Verify that this is really okay off the GPU main thread.
// The current implementation is.
std::vector<gpu::Mailbox> mailboxes;
- for (size_t texture_idx = 0; texture_idx < textures_per_picture;
- texture_idx++) {
+ for (size_t plane = 0; plane < NumPlanes(dxgi_format_); plane++) {
mailboxes.push_back(gpu::Mailbox::GenerateForSharedImage());
- mailbox_holders_[texture_idx] = gpu::MailboxHolder(
- mailboxes[texture_idx], gpu::SyncToken(), GL_TEXTURE_EXTERNAL_OES);
+ mailbox_holders_[plane] = gpu::MailboxHolder(
+ mailboxes[plane], gpu::SyncToken(), GL_TEXTURE_EXTERNAL_OES);
}
// Start construction of the GpuResources.
@@ -164,10 +106,12 @@ Status DefaultTexture2DWrapper::Init(
// device for decoding. Sharing seems not to work very well. Otherwise, we
// would create the texture with KEYED_MUTEX and NTHANDLE, then send along
// a handle that we get from |texture| as an IDXGIResource1.
- gpu_resources_.AsyncCall(&GpuResources::Init)
- .WithArgs(std::move(get_helper_cb), std::move(mailboxes),
- GL_TEXTURE_EXTERNAL_OES, size_, textures_per_picture,
- texture_formats, pixel_format_, texture, array_slice);
+ auto on_error_cb = BindToCurrentLoop(base::BindOnce(
+ &DefaultTexture2DWrapper::OnError, weak_factory_.GetWeakPtr()));
+ gpu_resources_ = base::SequenceBound<GpuResources>(
+ std::move(gpu_task_runner), std::move(on_error_cb),
+ std::move(get_helper_cb), std::move(mailboxes), size_, dxgi_format_,
+ texture, array_slice);
return OkStatus();
}
@@ -182,217 +126,47 @@ void DefaultTexture2DWrapper::SetStreamHDRMetadata(
void DefaultTexture2DWrapper::SetDisplayHDRMetadata(
const DXGI_HDR_METADATA_HDR10& dxgi_display_metadata) {}
-DefaultTexture2DWrapper::GpuResources::GpuResources(OnErrorCB on_error_cb)
- : on_error_cb_(std::move(on_error_cb)) {}
-
-DefaultTexture2DWrapper::GpuResources::~GpuResources() {
- if (helper_ && helper_->MakeContextCurrent()) {
- for (uint32_t service_id : service_ids_)
- helper_->DestroyTexture(service_id);
- }
-}
-
-void DefaultTexture2DWrapper::GpuResources::Init(
+DefaultTexture2DWrapper::GpuResources::GpuResources(
+ OnErrorCB on_error_cb,
GetCommandBufferHelperCB get_helper_cb,
- const std::vector<gpu::Mailbox> mailboxes,
- GLenum target,
- gfx::Size size,
- size_t textures_per_picture,
- std::array<viz::ResourceFormat, VideoFrame::kMaxPlanes> texture_formats,
- VideoPixelFormat pixel_format,
+ const std::vector<gpu::Mailbox>& mailboxes,
+ const gfx::Size& size,
+ DXGI_FORMAT dxgi_format,
ComD3D11Texture2D texture,
size_t array_slice) {
helper_ = get_helper_cb.Run();
if (!helper_ || !helper_->MakeContextCurrent()) {
- NotifyError(StatusCode::kMakeContextCurrentFailed);
- return;
- }
-
- // Create the stream for zero-copy use by gl.
- EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
- const EGLint stream_attributes[] = {
- // clang-format off
- EGL_CONSUMER_LATENCY_USEC_KHR, 0,
- EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0,
- EGL_NONE,
- // clang-format on
- };
- EGLStreamKHR stream = eglCreateStreamKHR(egl_display, stream_attributes);
- if (!stream) {
- NotifyError(StatusCode::kCreateEglStreamFailed);
+ std::move(on_error_cb)
+ .Run(std::move(StatusCode::kMakeContextCurrentFailed));
return;
}
- // |stream| will be destroyed when the GLImage is.
- // TODO(liberato): for tests, it will be destroyed pretty much at the end of
- // this function unless |helper_| retains it. Also, this won't work if we
- // have a FakeCommandBufferHelper since the service IDs aren't meaningful.
- gl_image_ = base::MakeRefCounted<gl::GLImageDXGI>(size, stream);
-
- // Create the textures and attach them to the mailboxes.
- // TODO(liberato): Should we use GL_FLOAT for an fp16 texture? It doesn't
- // really seem to matter so far as I can tell.
- for (size_t texture_idx = 0; texture_idx < textures_per_picture;
- texture_idx++) {
- const viz::ResourceFormat format = texture_formats[texture_idx];
- const GLenum internal_format = viz::GLInternalFormat(format);
- const GLenum data_type = viz::GLDataType(format);
- const GLenum data_format = viz::GLDataFormat(format);
-
- // Adjust the size by the subsampling factor.
- const size_t width =
- VideoFrame::Columns(texture_idx, pixel_format, size.width());
- const size_t height =
- VideoFrame::Rows(texture_idx, pixel_format, size.height());
- const gfx::Size plane_size(width, height);
-
- // TODO(crbug.com/1011555): CreateTexture allocates a GL texture, figure out
- // if this can be removed.
- const uint32_t service_id =
- helper_->CreateTexture(target, internal_format, plane_size.width(),
- plane_size.height(), data_format, data_type);
+ // Usage flags to allow the display compositor to draw from it, video to
+ // decode, and allow webgl/canvas access.
+ constexpr uint32_t usage =
+ gpu::SHARED_IMAGE_USAGE_VIDEO_DECODE | gpu::SHARED_IMAGE_USAGE_GLES2 |
+ gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_DISPLAY |
+ gpu::SHARED_IMAGE_USAGE_SCANOUT;
- const auto& mailbox = mailboxes[texture_idx];
-
- // Shared image does not need to store the colorspace since it is already
- // stored on the VideoFrame which is provided upon presenting the overlay.
- // To prevent the developer from mistakenly using it, provide the invalid
- // value from default-construction.
- const gfx::ColorSpace kInvalidColorSpace;
-
- // Usage flags to allow the display compositor to draw from it, video to
- // decode, and allow webgl/canvas access.
- const uint32_t shared_image_usage =
- gpu::SHARED_IMAGE_USAGE_VIDEO_DECODE | gpu::SHARED_IMAGE_USAGE_GLES2 |
- gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_DISPLAY |
- gpu::SHARED_IMAGE_USAGE_SCANOUT;
-
- // Create a shared image
- // TODO(crbug.com/1011555): Need key shared mutex if shared image is ever
- // used by another device.
- scoped_refptr<gpu::gles2::TexturePassthrough> gl_texture =
- gpu::gles2::TexturePassthrough::CheckedCast(
- helper_->GetTexture(service_id));
-
- auto shared_image = std::make_unique<gpu::SharedImageBackingD3D>(
- mailbox, format, plane_size, kInvalidColorSpace,
- kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, shared_image_usage,
- /*swap_chain=*/nullptr, std::move(gl_texture), gl_image_,
- /*buffer_index=*/0, texture, base::win::ScopedHandle(),
- /*dxgi_key_mutex=*/nullptr);
-
- // Caller is assumed to provide cleared d3d textures.
- shared_image->SetCleared();
-
- // Shared images will be destroyed when this wrapper goes away.
- // Only GpuResource can be used to safely destroy the shared images on the
- // gpu main thread.
- shared_images_.push_back(helper_->Register(std::move(shared_image)));
-
- service_ids_.push_back(service_id);
- }
-
- // Bind all the textures so that the stream can find them.
- OrderedDestructionList texture_everythings;
- for (size_t i = 0; i < textures_per_picture; i++)
- texture_everythings.emplace_back(GL_TEXTURE0 + i, service_ids_[i]);
-
- std::vector<EGLAttrib> consumer_attributes;
- if (textures_per_picture == 2) {
- // Assume NV12.
- consumer_attributes = {
- // clang-format off
- EGL_COLOR_BUFFER_TYPE, EGL_YUV_BUFFER_EXT,
- EGL_YUV_NUMBER_OF_PLANES_EXT, 2,
- EGL_YUV_PLANE0_TEXTURE_UNIT_NV, 0,
- EGL_YUV_PLANE1_TEXTURE_UNIT_NV, 1,
- EGL_NONE,
- // clang-format on
- };
- } else {
- // Assume some rgb format.
- consumer_attributes = {
- // clang-format off
- EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
- EGL_NONE,
- // clang-format on
- };
- }
- EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV(
- egl_display, stream, consumer_attributes.data());
- if (!result) {
- NotifyError(StatusCode::kCreateEglStreamConsumerFailed);
- return;
- }
-
- EGLAttrib producer_attributes[] = {
- EGL_NONE,
- };
-
- result = eglCreateStreamProducerD3DTextureANGLE(egl_display, stream,
- producer_attributes);
- if (!result) {
- NotifyError(StatusCode::kCreateEglStreamProducerFailed);
+ auto shared_image_backings =
+ gpu::SharedImageBackingD3D::CreateFromVideoTexture(
+ mailboxes, dxgi_format, size, usage, texture, array_slice);
+ if (shared_image_backings.empty()) {
+ std::move(on_error_cb).Run(std::move(StatusCode::kCreateSharedImageFailed));
return;
}
+ DCHECK_EQ(shared_image_backings.size(), NumPlanes(dxgi_format));
- // Note that this is valid as long as |gl_image_| is valid; it is
- // what deletes the stream.
- stream_ = stream;
-
- // Bind the image to each texture.
- for (size_t texture_idx = 0; texture_idx < service_ids_.size();
- texture_idx++) {
- helper_->BindImage(service_ids_[texture_idx], gl_image_.get(),
- false /* client_managed */);
- }
-
- // Specify the texture so ProcessTexture knows how to process it using a GL
- // image.
- gl_image_->SetTexture(texture, array_slice);
-
- PushNewTexture();
+ for (auto& backing : shared_image_backings)
+ shared_images_.push_back(helper_->Register(std::move(backing)));
}
-void DefaultTexture2DWrapper::GpuResources::PushNewTexture() {
- // If init didn't complete, then signal (another) error that will probably be
- // ignored in favor of whatever we signalled earlier.
- if (!gl_image_ || !stream_) {
- NotifyError(StatusCode::kDecoderInitializeNeverCompleted);
- return;
- }
-
- if (!helper_ || !helper_->MakeContextCurrent()) {
- NotifyError(StatusCode::kMakeContextCurrentFailed);
- return;
- }
-
- // Notify angle that it has a new texture.
- EGLAttrib frame_attributes[] = {
- EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE,
- gl_image_->level(),
- EGL_NONE,
- };
-
- EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
- if (!eglStreamPostD3DTextureANGLE(
- egl_display, stream_, static_cast<void*>(gl_image_->texture().Get()),
- frame_attributes)) {
- NotifyError(StatusCode::kPostTextureFailed);
- return;
- }
-
- if (!eglStreamConsumerAcquireKHR(egl_display, stream_)) {
- NotifyError(StatusCode::kPostAcquireStreamFailed);
+DefaultTexture2DWrapper::GpuResources::~GpuResources() {
+ // Destroy shared images with a current context.
+ if (!helper_ || !helper_->MakeContextCurrent())
return;
- }
-}
-
-void DefaultTexture2DWrapper::GpuResources::NotifyError(Status status) {
- if (on_error_cb_)
- std::move(on_error_cb_).Run(std::move(status));
- // else this isn't the first error, so skip it.
+ shared_images_.clear();
}
} // namespace media
diff --git a/chromium/media/gpu/windows/d3d11_texture_wrapper.h b/chromium/media/gpu/windows/d3d11_texture_wrapper.h
index 5c097ec9cac..88171c16a82 100644
--- a/chromium/media/gpu/windows/d3d11_texture_wrapper.h
+++ b/chromium/media/gpu/windows/d3d11_texture_wrapper.h
@@ -11,7 +11,6 @@
#include <vector>
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/threading/sequence_bound.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/texture_manager.h"
@@ -20,6 +19,7 @@
#include "media/gpu/command_buffer_helper.h"
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/windows/d3d11_com_defs.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/hdr_metadata.h"
#include "ui/gl/gl_bindings.h"
@@ -74,9 +74,7 @@ class MEDIA_GPU_EXPORT DefaultTexture2DWrapper : public Texture2DWrapper {
// While the specific texture instance can change on every call to
// ProcessTexture, the dxgi format must be the same for all of them.
- DefaultTexture2DWrapper(const gfx::Size& size,
- DXGI_FORMAT dxgi_format,
- VideoPixelFormat pixel_format);
+ DefaultTexture2DWrapper(const gfx::Size& size, DXGI_FORMAT dxgi_format);
~DefaultTexture2DWrapper() override;
Status Init(scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
@@ -99,36 +97,17 @@ class MEDIA_GPU_EXPORT DefaultTexture2DWrapper : public Texture2DWrapper {
// can use the mailbox.
class GpuResources {
public:
- GpuResources(OnErrorCB on_error_cb);
+ GpuResources(OnErrorCB on_error_cb,
+ GetCommandBufferHelperCB get_helper_cb,
+ const std::vector<gpu::Mailbox>& mailboxes,
+ const gfx::Size& size,
+ DXGI_FORMAT dxgi_format,
+ ComD3D11Texture2D texture,
+ size_t array_slice);
~GpuResources();
- void Init(
- GetCommandBufferHelperCB get_helper_cb,
- const std::vector<gpu::Mailbox> mailboxes,
- GLenum target,
- gfx::Size size,
- size_t textures_per_picture,
- std::array<viz::ResourceFormat, VideoFrame::kMaxPlanes> texture_formats,
- VideoPixelFormat pixel_format,
- ComD3D11Texture2D texture,
- size_t array_slice);
-
- std::vector<uint32_t> service_ids_;
-
private:
- // Push a new |texture|, |array_slice| to |gl_image_|.
- // Both |texture| and |array_slice| were set by Init.
- void PushNewTexture();
-
- // Notify our wrapper about |status|, if we haven't before.
- void NotifyError(Status status);
-
- // May be empty if we've already sent an error.
- OnErrorCB on_error_cb_;
-
scoped_refptr<CommandBufferHelper> helper_;
- scoped_refptr<gl::GLImageDXGI> gl_image_;
- EGLStreamKHR stream_;
std::vector<std::unique_ptr<gpu::SharedImageRepresentationFactoryRef>>
shared_images_;
@@ -140,13 +119,12 @@ class MEDIA_GPU_EXPORT DefaultTexture2DWrapper : public Texture2DWrapper {
void OnError(Status status);
// The first error status that we've received from |gpu_resources_|, if any.
- base::Optional<Status> received_error_;
+ absl::optional<Status> received_error_;
gfx::Size size_;
base::SequenceBound<GpuResources> gpu_resources_;
MailboxHolderArray mailbox_holders_;
DXGI_FORMAT dxgi_format_;
- VideoPixelFormat pixel_format_;
base::WeakPtrFactory<DefaultTexture2DWrapper> weak_factory_{this};
};
diff --git a/chromium/media/gpu/windows/d3d11_texture_wrapper_unittest.cc b/chromium/media/gpu/windows/d3d11_texture_wrapper_unittest.cc
index 3142782db7f..cfcd5fafc91 100644
--- a/chromium/media/gpu/windows/d3d11_texture_wrapper_unittest.cc
+++ b/chromium/media/gpu/windows/d3d11_texture_wrapper_unittest.cc
@@ -88,10 +88,8 @@ class D3D11TextureWrapperUnittest : public ::testing::Test {
TEST_F(D3D11TextureWrapperUnittest, NV12InitSucceeds) {
STOP_IF_WIN7();
const DXGI_FORMAT dxgi_format = DXGI_FORMAT_NV12;
- const VideoPixelFormat pixel_format = PIXEL_FORMAT_NV12;
- auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format,
- pixel_format);
+ auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format);
const Status init_result = wrapper->Init(
task_runner_, get_helper_cb_, /*texture_d3d=*/nullptr, /*array_slice=*/0);
EXPECT_TRUE(init_result.is_ok());
@@ -102,10 +100,8 @@ TEST_F(D3D11TextureWrapperUnittest, NV12InitSucceeds) {
TEST_F(D3D11TextureWrapperUnittest, BGRA8InitSucceeds) {
STOP_IF_WIN7();
const DXGI_FORMAT dxgi_format = DXGI_FORMAT_B8G8R8A8_UNORM;
- const VideoPixelFormat pixel_format = PIXEL_FORMAT_ARGB;
- auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format,
- pixel_format);
+ auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format);
const Status init_result = wrapper->Init(
task_runner_, get_helper_cb_, /*texture_d3d=*/nullptr, /*array_slice=*/0);
EXPECT_TRUE(init_result.is_ok());
@@ -114,10 +110,8 @@ TEST_F(D3D11TextureWrapperUnittest, BGRA8InitSucceeds) {
TEST_F(D3D11TextureWrapperUnittest, FP16InitSucceeds) {
STOP_IF_WIN7();
const DXGI_FORMAT dxgi_format = DXGI_FORMAT_R16G16B16A16_FLOAT;
- const VideoPixelFormat pixel_format = PIXEL_FORMAT_RGBAF16;
- auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format,
- pixel_format);
+ auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format);
const Status init_result = wrapper->Init(
task_runner_, get_helper_cb_, /*texture_d3d=*/nullptr, /*array_slice=*/0);
EXPECT_TRUE(init_result.is_ok());
@@ -126,10 +120,8 @@ TEST_F(D3D11TextureWrapperUnittest, FP16InitSucceeds) {
TEST_F(D3D11TextureWrapperUnittest, P010InitSucceeds) {
STOP_IF_WIN7();
const DXGI_FORMAT dxgi_format = DXGI_FORMAT_P010;
- const VideoPixelFormat pixel_format = PIXEL_FORMAT_NV12;
- auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format,
- pixel_format);
+ auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format);
const Status init_result = wrapper->Init(
task_runner_, get_helper_cb_, /*texture_d3d=*/nullptr, /*array_slice=*/0);
EXPECT_TRUE(init_result.is_ok());
@@ -138,13 +130,11 @@ TEST_F(D3D11TextureWrapperUnittest, P010InitSucceeds) {
TEST_F(D3D11TextureWrapperUnittest, UnknownInitFails) {
STOP_IF_WIN7();
const DXGI_FORMAT dxgi_format = DXGI_FORMAT_UNKNOWN;
- const VideoPixelFormat pixel_format = PIXEL_FORMAT_UNKNOWN;
- auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format,
- pixel_format);
+ auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format);
const Status init_result = wrapper->Init(
task_runner_, get_helper_cb_, /*texture_d3d=*/nullptr, /*array_slice=*/0);
EXPECT_FALSE(init_result.is_ok());
}
-} // namespace media \ No newline at end of file
+} // namespace media
diff --git a/chromium/media/gpu/windows/d3d11_video_decoder.cc b/chromium/media/gpu/windows/d3d11_video_decoder.cc
index 04e0d58eb65..6d5da96ac7f 100644
--- a/chromium/media/gpu/windows/d3d11_video_decoder.cc
+++ b/chromium/media/gpu/windows/d3d11_video_decoder.cc
@@ -718,7 +718,7 @@ void D3D11VideoDecoder::CreatePictureBuffers() {
stream_metadata = *config_.hdr_metadata();
// else leave |stream_metadata| default-initialized. We might use it anyway.
- base::Optional<DXGI_HDR_METADATA_HDR10> display_metadata;
+ absl::optional<DXGI_HDR_METADATA_HDR10> display_metadata;
if (decoder_configurator_->TextureFormat() == DXGI_FORMAT_P010) {
// For HDR formats, try to get the display metadata. This may fail, which
// is okay. We'll just skip sending the metadata.
diff --git a/chromium/media/gpu/windows/d3d11_video_decoder.h b/chromium/media/gpu/windows/d3d11_video_decoder.h
index e41d8c38add..a539820a129 100644
--- a/chromium/media/gpu/windows/d3d11_video_decoder.h
+++ b/chromium/media/gpu/windows/d3d11_video_decoder.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_GPU_D3D11_VIDEO_DECODER_H_
-#define MEDIA_GPU_D3D11_VIDEO_DECODER_H_
+#ifndef MEDIA_GPU_WINDOWS_D3D11_VIDEO_DECODER_H_
+#define MEDIA_GPU_WINDOWS_D3D11_VIDEO_DECODER_H_
#include <d3d11.h>
#include <string>
@@ -308,4 +308,4 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder,
} // namespace media
-#endif // MEDIA_GPU_D3D11_VIDEO_DECODER_H_
+#endif // MEDIA_GPU_WINDOWS_D3D11_VIDEO_DECODER_H_
diff --git a/chromium/media/gpu/windows/d3d11_video_decoder_impl.h b/chromium/media/gpu/windows/d3d11_video_decoder_impl.h
index 770d81cf88f..4a7f1449e71 100644
--- a/chromium/media/gpu/windows/d3d11_video_decoder_impl.h
+++ b/chromium/media/gpu/windows/d3d11_video_decoder_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_GPU_D3D11_VIDEO_DECODER_IMPL_H_
-#define MEDIA_GPU_D3D11_VIDEO_DECODER_IMPL_H_
+#ifndef MEDIA_GPU_WINDOWS_D3D11_VIDEO_DECODER_IMPL_H_
+#define MEDIA_GPU_WINDOWS_D3D11_VIDEO_DECODER_IMPL_H_
#include <d3d11_1.h>
#include <wrl/client.h>
@@ -86,4 +86,4 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoderImpl {
} // namespace media
-#endif // MEDIA_GPU_D3D11_VIDEO_DECODER_IMPL_H_
+#endif // MEDIA_GPU_WINDOWS_D3D11_VIDEO_DECODER_IMPL_H_
diff --git a/chromium/media/gpu/windows/d3d11_video_decoder_unittest.cc b/chromium/media/gpu/windows/d3d11_video_decoder_unittest.cc
index 91b53e6d129..a3c5e9ca7df 100644
--- a/chromium/media/gpu/windows/d3d11_video_decoder_unittest.cc
+++ b/chromium/media/gpu/windows/d3d11_video_decoder_unittest.cc
@@ -11,7 +11,6 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/memory/ptr_util.h"
-#include "base/optional.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/scoped_feature_list.h"
@@ -27,6 +26,7 @@
#include "media/base/win/d3d11_mocks.h"
#include "media/gpu/windows/d3d11_video_decoder_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
using ::testing::_;
using ::testing::DoAll;
@@ -153,7 +153,7 @@ class D3D11VideoDecoderTest : public ::testing::Test {
}
// Most recently provided video decoder desc.
- base::Optional<D3D11_VIDEO_DECODER_DESC> last_video_decoder_desc_;
+ absl::optional<D3D11_VIDEO_DECODER_DESC> last_video_decoder_desc_;
D3D11_VIDEO_DECODER_CONFIG video_decoder_config_;
void TearDown() override {
@@ -177,8 +177,8 @@ class D3D11VideoDecoderTest : public ::testing::Test {
// use it. Otherwise, we'll use the list that's autodetected by the
// decoder based on the current device mock.
void CreateDecoder(
- base::Optional<D3D11VideoDecoder::SupportedConfigs> supported_configs =
- base::Optional<D3D11VideoDecoder::SupportedConfigs>()) {
+ absl::optional<D3D11VideoDecoder::SupportedConfigs> supported_configs =
+ absl::optional<D3D11VideoDecoder::SupportedConfigs>()) {
auto get_device_cb = base::BindRepeating(
[](Microsoft::WRL::ComPtr<ID3D11Device> device) { return device; },
mock_d3d11_device_);
@@ -249,7 +249,7 @@ class D3D11VideoDecoderTest : public ::testing::Test {
DXGI_ADAPTER_DESC mock_adapter_desc_;
- base::Optional<base::test::ScopedFeatureList> scoped_feature_list_;
+ absl::optional<base::test::ScopedFeatureList> scoped_feature_list_;
base::win::ScopedCOMInitializer com_initializer_;
};
@@ -323,7 +323,7 @@ TEST_F(D3D11VideoDecoderTest, DoesNotSupportH264IfNoSupportedConfig) {
// config check kinda works.
// For whatever reason, Optional<SupportedConfigs>({}) results in one that
// doesn't have a value, rather than one that has an empty vector.
- base::Optional<D3D11VideoDecoder::SupportedConfigs> empty_configs;
+ absl::optional<D3D11VideoDecoder::SupportedConfigs> empty_configs;
empty_configs.emplace(std::vector<SupportedVideoDecoderConfig>());
CreateDecoder(empty_configs);
diff --git a/chromium/media/gpu/windows/d3d11_video_device_format_support.h b/chromium/media/gpu/windows/d3d11_video_device_format_support.h
index 0e07a4ecddf..bf75e839b17 100644
--- a/chromium/media/gpu/windows/d3d11_video_device_format_support.h
+++ b/chromium/media/gpu/windows/d3d11_video_device_format_support.h
@@ -6,12 +6,11 @@
#define MEDIA_GPU_WINDOWS_D3D11_VIDEO_DEVICE_FORMAT_SUPPORT_H_
#include <d3d11_1.h>
-#include <vector>
-#include "base/optional.h"
#include "media/base/media_log.h"
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/windows/d3d11_com_defs.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
diff --git a/chromium/media/gpu/windows/dxva_video_decode_accelerator_win.cc b/chromium/media/gpu/windows/dxva_video_decode_accelerator_win.cc
index 55c4d9329ee..02a7a850394 100644
--- a/chromium/media/gpu/windows/dxva_video_decode_accelerator_win.cc
+++ b/chromium/media/gpu/windows/dxva_video_decode_accelerator_win.cc
@@ -24,6 +24,7 @@
#include "base/bind_post_task.h"
#include "base/callback.h"
#include "base/command_line.h"
+#include "base/containers/contains.h"
#include "base/file_version_info.h"
#include "base/files/file_path.h"
#include "base/location.h"
@@ -321,6 +322,10 @@ bool ConfigChangeDetector::IsYUV420() const {
return false;
}
+bool ConfigChangeDetector::is_vp9_resilient_mode() const {
+ return false;
+}
+
// Provides functionality to detect H.264 stream configuration changes.
// TODO(ananta)
// Move this to a common place so that all VDA's can use this.
@@ -364,7 +369,7 @@ bool H264ConfigChangeDetector::DetectConfig(const uint8_t* stream,
bool idr_seen = false;
if (!parser_.get())
- parser_.reset(new H264Parser);
+ parser_ = std::make_unique<H264Parser>();
parser_->SetStream(stream, size);
config_changed_ = false;
@@ -508,6 +513,9 @@ class VP9ConfigChangeDetector : public ConfigChangeDetector {
color_space_ = fhdr.GetColorSpace();
gfx::Size new_size(fhdr.frame_width, fhdr.frame_height);
+ if (!gfx::Rect(new_size).Contains(visible_rect_)) {
+ visible_rect_ = gfx::Rect(new_size);
+ }
if (!size_.IsEmpty() && !pending_config_changed_ && !config_changed_ &&
size_ != new_size) {
pending_config_changed_ = true;
@@ -516,6 +524,8 @@ class VP9ConfigChangeDetector : public ConfigChangeDetector {
}
size_ = new_size;
+ is_resilient_mode_ |= fhdr.error_resilient_mode;
+
// Resolution changes can happen on any frame technically, so wait for a
// keyframe before signaling the config change.
if (fhdr.IsKeyframe() && pending_config_changed_) {
@@ -539,11 +549,14 @@ class VP9ConfigChangeDetector : public ConfigChangeDetector {
: color_space_;
}
+ bool is_vp9_resilient_mode() const override { return is_resilient_mode_; }
+
private:
gfx::Size size_;
bool pending_config_changed_ = false;
gfx::Rect visible_rect_;
VideoColorSpace color_space_;
+ bool is_resilient_mode_ = false;
Vp9Parser parser_;
};
@@ -661,6 +674,8 @@ DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
!workarounds.disable_accelerated_vp8_decode),
enable_accelerated_vp9_decode_(
!workarounds.disable_accelerated_vp9_decode),
+ disallow_vp9_resilient_dxva_decoding_(
+ workarounds.disallow_vp9_resilient_dxva_decoding),
processing_config_changed_(false),
use_empty_video_hdr_metadata_(workarounds.use_empty_video_hdr_metadata) {
weak_ptr_ = weak_this_factory_.GetWeakPtr();
@@ -807,11 +822,11 @@ bool DXVAVideoDecodeAccelerator::Initialize(const Config& config,
"Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed", false);
if (codec_ == kCodecH264)
- config_change_detector_.reset(new H264ConfigChangeDetector());
+ config_change_detector_ = std::make_unique<H264ConfigChangeDetector>();
if (codec_ == kCodecVP8)
- config_change_detector_.reset(new VP8ConfigChangeDetector());
+ config_change_detector_ = std::make_unique<VP8ConfigChangeDetector>();
if (codec_ == kCodecVP9)
- config_change_detector_.reset(new VP9ConfigChangeDetector());
+ config_change_detector_ = std::make_unique<VP9ConfigChangeDetector>();
processing_config_changed_ = false;
SetState(kNormal);
@@ -2328,6 +2343,12 @@ void DXVAVideoDecodeAccelerator::DecodeInternal(
RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to check video stream config",
PLATFORM_FAILURE, );
+ if (disallow_vp9_resilient_dxva_decoding_ &&
+ config_change_detector_->is_vp9_resilient_mode()) {
+ RETURN_AND_NOTIFY_ON_HR_FAILURE(
+ E_FAIL, "Incompatible GPU for VP9 resilient mode", PLATFORM_FAILURE, );
+ }
+
// https://crbug.com/1160623 -- non 4:2:0 content hangs the decoder.
RETURN_AND_NOTIFY_ON_FAILURE(
codec_ != kCodecH264 || config_change_detector_->IsYUV420(),
@@ -2377,7 +2398,11 @@ void DXVAVideoDecodeAccelerator::DecodeInternal(
PLATFORM_FAILURE, );
hr = decoder_->ProcessInput(0, sample.Get(), 0);
}
- // If we continue to get the MF_E_NOTACCEPTING error we do the following:-
+ // If we continue to get the MF_E_NOTACCEPTING error we do the following:
+ // 1. Check if MF appears to be stuck in a not-accepting loop. When this
+ // occurs we want to break out of the loop early to allow recovery
+ // without prolonged ux hangs or running into potential OOM issues.
+ // If not in a loop then:
// 1. Add the input sample to the pending queue.
// 2. If we don't have any output samples we post the
// DecodePendingInputBuffers task to process the pending input samples.
@@ -2387,6 +2412,17 @@ void DXVAVideoDecodeAccelerator::DecodeInternal(
// given time due to the limitation with the Microsoft media foundation
// decoder where it recycles the output Decoder surfaces.
if (hr == MF_E_NOTACCEPTING) {
+ // Check if we appear to be stuck in a loop
+ if (inputs_before_decode_ >= 1000) {
+ // The value of 1000 is an arbitrary upper bound here since processing
+ // is not gated on any media timings. In practice we typically see
+ // maximum values in the 5 to 10 range for normal execution, so 1000
+ // affords two orders of magnitude outside of the expected range.
+ RETURN_AND_NOTIFY_ON_HR_FAILURE(
+ hr, "Input processing appears stuck in MF_E_NOTACCEPTING loop.",
+ PLATFORM_FAILURE, );
+ }
+
pending_input_buffers_.push_back(sample);
decoder_thread_task_runner_->PostTask(
FROM_HERE,
@@ -2732,16 +2768,12 @@ void DXVAVideoDecodeAccelerator::BindPictureBufferToSample(
// this |picture_buffer| will be updated when the video frame is created.
const auto& mailbox = gpu::Mailbox::GenerateForSharedImage();
- auto shared_image = std::make_unique<gpu::SharedImageBackingD3D>(
+ auto shared_image = gpu::SharedImageBackingD3D::CreateFromGLTexture(
mailbox, viz_formats[texture_idx],
picture_buffer->texture_size(texture_idx),
picture_buffer->color_space(), kTopLeft_GrSurfaceOrigin,
- kPremul_SkAlphaType, shared_image_usage,
- /*swap_chain=*/nullptr, std::move(gl_texture),
- picture_buffer->gl_image(),
- /*buffer_index=*/0, gl_image_dxgi->texture(),
- base::win::ScopedHandle(),
- /*dxgi_keyed_mutex=*/nullptr);
+ kPremul_SkAlphaType, shared_image_usage, gl_image_dxgi->texture(),
+ std::move(gl_texture));
// Caller is assumed to provide cleared d3d textures.
shared_image->SetCleared();
diff --git a/chromium/media/gpu/windows/dxva_video_decode_accelerator_win.h b/chromium/media/gpu/windows/dxva_video_decode_accelerator_win.h
index b7fc1b95e4c..c4c5463f9ed 100644
--- a/chromium/media/gpu/windows/dxva_video_decode_accelerator_win.h
+++ b/chromium/media/gpu/windows/dxva_video_decode_accelerator_win.h
@@ -65,6 +65,7 @@ class ConfigChangeDetector {
virtual VideoColorSpace current_color_space(
const VideoColorSpace& container_color_space) const = 0;
virtual bool IsYUV420() const;
+ virtual bool is_vp9_resilient_mode() const;
bool config_changed() const { return config_changed_; }
protected:
@@ -612,6 +613,8 @@ class MEDIA_GPU_EXPORT DXVAVideoDecodeAccelerator
const bool enable_accelerated_vp8_decode_;
const bool enable_accelerated_vp9_decode_;
+ const bool disallow_vp9_resilient_dxva_decoding_;
+
// The media foundation H.264 decoder has problems handling changes like
// resolution change, bitrate change etc. If we reinitialize the decoder
// when these changes occur then, the decoder works fine. The
@@ -630,7 +633,7 @@ class MEDIA_GPU_EXPORT DXVAVideoDecodeAccelerator
gfx::Rect current_visible_rect_;
VideoColorSpace current_color_space_;
- base::Optional<gl::HDRMetadataHelperWin> hdr_metadata_helper_;
+ absl::optional<gl::HDRMetadataHelperWin> hdr_metadata_helper_;
bool use_empty_video_hdr_metadata_ = false;
// Have we delivered any decoded frames since the last call to Initialize()?
diff --git a/chromium/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc b/chromium/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
index e61b7fd921b..31394a96f9d 100644
--- a/chromium/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
+++ b/chromium/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -14,6 +14,7 @@
#include <objbase.h>
#include <iterator>
+#include <memory>
#include <utility>
#include <vector>
@@ -24,10 +25,12 @@
#include "base/win/scoped_co_mem.h"
#include "base/win/scoped_variant.h"
#include "base/win/windows_version.h"
+#include "gpu/ipc/common/dxgi_helpers.h"
#include "media/base/media_switches.h"
#include "media/base/win/mf_helpers.h"
#include "media/base/win/mf_initializer.h"
#include "third_party/libyuv/include/libyuv.h"
+#include "ui/gfx/color_space_win.h"
#include "ui/gfx/gpu_memory_buffer.h"
using media::MediaBufferScopedPointer;
@@ -245,7 +248,8 @@ bool MediaFoundationVideoEncodeAccelerator::Initialize(const Config& config,
}
}
- main_client_weak_factory_.reset(new base::WeakPtrFactory<Client>(client));
+ main_client_weak_factory_ =
+ std::make_unique<base::WeakPtrFactory<Client>>(client);
main_client_ = main_client_weak_factory_->GetWeakPtr();
input_visible_size_ = config.input_visible_size;
if (config.initial_framerate.has_value())
@@ -404,6 +408,10 @@ void MediaFoundationVideoEncodeAccelerator::Destroy() {
delete this;
}
+bool MediaFoundationVideoEncodeAccelerator::IsGpuFrameResizeSupported() {
+ return true;
+}
+
// static
bool MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization() {
bool result = true;
@@ -851,18 +859,41 @@ HRESULT MediaFoundationVideoEncodeAccelerator::PopulateInputSampleBuffer(
HRESULT hr = d3d_device.As(&device1);
RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D11Device1", hr);
- Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
+ Microsoft::WRL::ComPtr<ID3D11Texture2D> input_texture;
hr = device1->OpenSharedResource1(buffer_handle.dxgi_handle.Get(),
- IID_PPV_ARGS(&texture));
+ IID_PPV_ARGS(&input_texture));
RETURN_ON_HR_FAILURE(hr, "Failed to open shared GMB D3D texture", hr);
+ // Check if we need to scale the input texture
+ D3D11_TEXTURE2D_DESC input_desc = {};
+ input_texture->GetDesc(&input_desc);
+
+ Microsoft::WRL::ComPtr<ID3D11Texture2D> sample_texture;
+ if (input_desc.Width != uint32_t{input_visible_size_.width()} ||
+ input_desc.Height != uint32_t{input_visible_size_.height()}) {
+ hr = PerformD3DScaling(input_texture.Get());
+ RETURN_ON_HR_FAILURE(hr, "Failed to perform D3D video processing", hr);
+ sample_texture = scaled_d3d11_texture_;
+ } else {
+ sample_texture = input_texture;
+ }
+
Microsoft::WRL::ComPtr<IMFMediaBuffer> input_buffer;
- hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), texture.Get(), 0,
- FALSE, &input_buffer);
+ hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D),
+ sample_texture.Get(), 0, FALSE,
+ &input_buffer);
RETURN_ON_HR_FAILURE(hr, "Failed to create MF DXGI surface buffer", hr);
+ // Some encoder MFTs (e.g. Qualcomm) depend on the sample buffer having a
+ // valid current length. Call GetMaxLength() to compute the plane size.
+ DWORD buffer_length = 0;
+ hr = input_buffer->GetMaxLength(&buffer_length);
+ RETURN_ON_HR_FAILURE(hr, "Failed to get max buffer length", hr);
+ hr = input_buffer->SetCurrentLength(buffer_length);
+ RETURN_ON_HR_FAILURE(hr, "Failed to set current buffer length", hr);
+
hr = input_sample_->RemoveAllBuffers();
- RETURN_ON_HR_FAILURE(hr, "Failed remove buffers from sample", hr);
+ RETURN_ON_HR_FAILURE(hr, "Failed to remove buffers from sample", hr);
hr = input_sample_->AddBuffer(input_buffer.Get());
RETURN_ON_HR_FAILURE(hr, "Failed to add buffer to sample", hr);
return S_OK;
@@ -1255,4 +1286,161 @@ void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() {
output_sample_.Reset();
}
+HRESULT MediaFoundationVideoEncodeAccelerator::InitializeD3DVideoProcessing(
+ ID3D11Texture2D* input_texture) {
+ D3D11_TEXTURE2D_DESC input_desc = {};
+ input_texture->GetDesc(&input_desc);
+ if (vp_desc_.InputWidth == input_desc.Width &&
+ vp_desc_.InputHeight == input_desc.Height) {
+ return S_OK;
+ }
+
+ // Input/output framerates are dummy values for passthrough.
+ D3D11_VIDEO_PROCESSOR_CONTENT_DESC vp_desc = {
+ .InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE,
+ .InputFrameRate = {60, 1},
+ .InputWidth = input_desc.Width,
+ .InputHeight = input_desc.Height,
+ .OutputFrameRate = {60, 1},
+ .OutputWidth = input_visible_size_.width(),
+ .OutputHeight = input_visible_size_.height(),
+ .Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL};
+
+ Microsoft::WRL::ComPtr<ID3D11Device> texture_device;
+ input_texture->GetDevice(&texture_device);
+ Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device;
+ HRESULT hr = texture_device.As(&video_device);
+ RETURN_ON_HR_FAILURE(hr, "Failed to query for ID3D11VideoDevice", hr);
+
+ Microsoft::WRL::ComPtr<ID3D11VideoProcessorEnumerator>
+ video_processor_enumerator;
+ hr = video_device->CreateVideoProcessorEnumerator(
+ &vp_desc, &video_processor_enumerator);
+ RETURN_ON_HR_FAILURE(hr, "CreateVideoProcessorEnumerator failed", hr);
+
+ Microsoft::WRL::ComPtr<ID3D11VideoProcessor> video_processor;
+ hr = video_device->CreateVideoProcessor(video_processor_enumerator.Get(), 0,
+ &video_processor);
+ RETURN_ON_HR_FAILURE(hr, "CreateVideoProcessor failed", hr);
+
+ Microsoft::WRL::ComPtr<ID3D11DeviceContext> device_context;
+ texture_device->GetImmediateContext(&device_context);
+ Microsoft::WRL::ComPtr<ID3D11VideoContext> video_context;
+ hr = device_context.As(&video_context);
+ RETURN_ON_HR_FAILURE(hr, "Failed to query for ID3D11VideoContext", hr);
+
+ // Auto stream processing (the default) can hurt power consumption.
+ video_context->VideoProcessorSetStreamAutoProcessingMode(
+ video_processor.Get(), 0, FALSE);
+
+ D3D11_TEXTURE2D_DESC scaled_desc = {
+ .Width = input_visible_size_.width(),
+ .Height = input_visible_size_.height(),
+ .MipLevels = 1,
+ .ArraySize = 1,
+ .Format = DXGI_FORMAT_NV12,
+ .SampleDesc = {1, 0},
+ .Usage = D3D11_USAGE_DEFAULT,
+ .BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
+ .CPUAccessFlags = 0,
+ .MiscFlags = 0};
+ Microsoft::WRL::ComPtr<ID3D11Texture2D> scaled_d3d11_texture;
+ hr = texture_device->CreateTexture2D(&scaled_desc, nullptr,
+ &scaled_d3d11_texture);
+ RETURN_ON_HR_FAILURE(hr, "Failed to create texture", hr);
+
+ D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC output_desc = {};
+ output_desc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;
+ output_desc.Texture2D.MipSlice = 0;
+ Microsoft::WRL::ComPtr<ID3D11VideoProcessorOutputView> vp_output_view;
+ hr = video_device->CreateVideoProcessorOutputView(
+ scaled_d3d11_texture.Get(), video_processor_enumerator.Get(),
+ &output_desc, &vp_output_view);
+ RETURN_ON_HR_FAILURE(hr, "CreateVideoProcessorOutputView failed", hr);
+
+ video_device_ = std::move(video_device);
+ video_processor_enumerator_ = std::move(video_processor_enumerator);
+ video_processor_ = std::move(video_processor);
+ video_context_ = std::move(video_context);
+ vp_desc_ = std::move(vp_desc);
+ scaled_d3d11_texture_ = std::move(scaled_d3d11_texture);
+ vp_output_view_ = std::move(vp_output_view);
+ return S_OK;
+}
+
+HRESULT MediaFoundationVideoEncodeAccelerator::PerformD3DScaling(
+ ID3D11Texture2D* input_texture) {
+ HRESULT hr = InitializeD3DVideoProcessing(input_texture);
+ RETURN_ON_HR_FAILURE(hr, "Couldn't initialize D3D video processing", hr);
+
+ // Set the color space for passthrough.
+ auto src_color_space = gfx::ColorSpace::CreateSRGB();
+ auto output_color_space = gfx::ColorSpace::CreateSRGB();
+
+ D3D11_VIDEO_PROCESSOR_COLOR_SPACE src_d3d11_color_space =
+ gfx::ColorSpaceWin::GetD3D11ColorSpace(src_color_space);
+ video_context_->VideoProcessorSetStreamColorSpace(video_processor_.Get(), 0,
+ &src_d3d11_color_space);
+ D3D11_VIDEO_PROCESSOR_COLOR_SPACE output_d3d11_color_space =
+ gfx::ColorSpaceWin::GetD3D11ColorSpace(output_color_space);
+ video_context_->VideoProcessorSetOutputColorSpace(video_processor_.Get(),
+ &output_d3d11_color_space);
+
+ {
+ absl::optional<gpu::DXGIScopedReleaseKeyedMutex> release_keyed_mutex;
+ Microsoft::WRL::ComPtr<IDXGIKeyedMutex> keyed_mutex;
+ hr = input_texture->QueryInterface(IID_PPV_ARGS(&keyed_mutex));
+ if (SUCCEEDED(hr)) {
+ // The producer may still be using this texture for a short period of
+ // time, so wait long enough to hopefully avoid glitches. For example,
+ // all levels of the texture share the same keyed mutex, so if the
+ // hardware decoder acquired the mutex to decode into a different array
+ // level then it still may block here temporarily.
+ constexpr int kMaxSyncTimeMs = 100;
+ hr = keyed_mutex->AcquireSync(0, kMaxSyncTimeMs);
+ RETURN_ON_HR_FAILURE(hr, "Failed to acquire keyed mutex", hr);
+ release_keyed_mutex.emplace(std::move(keyed_mutex), 0);
+ }
+
+ // Setup |video_context_| for VPBlt operation.
+ D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC input_desc = {};
+ input_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
+ input_desc.Texture2D.ArraySlice = 0;
+ Microsoft::WRL::ComPtr<ID3D11VideoProcessorInputView> input_view;
+ hr = video_device_->CreateVideoProcessorInputView(
+ input_texture, video_processor_enumerator_.Get(), &input_desc,
+ &input_view);
+ RETURN_ON_HR_FAILURE(hr, "CreateVideoProcessorInputView failed", hr);
+
+ D3D11_VIDEO_PROCESSOR_STREAM stream = {.Enable = true,
+ .OutputIndex = 0,
+ .InputFrameOrField = 0,
+ .PastFrames = 0,
+ .FutureFrames = 0,
+ .pInputSurface = input_view.Get()};
+
+ D3D11_TEXTURE2D_DESC input_texture_desc = {};
+ input_texture->GetDesc(&input_texture_desc);
+ RECT source_rect = {0, 0, input_texture_desc.Width,
+ input_texture_desc.Height};
+ video_context_->VideoProcessorSetStreamSourceRect(video_processor_.Get(), 0,
+ TRUE, &source_rect);
+
+ D3D11_TEXTURE2D_DESC output_texture_desc = {};
+ scaled_d3d11_texture_->GetDesc(&output_texture_desc);
+ RECT dest_rect = {0, 0, output_texture_desc.Width,
+ output_texture_desc.Height};
+ video_context_->VideoProcessorSetOutputTargetRect(video_processor_.Get(),
+ TRUE, &dest_rect);
+ video_context_->VideoProcessorSetStreamDestRect(video_processor_.Get(), 0,
+ TRUE, &dest_rect);
+
+ hr = video_context_->VideoProcessorBlt(
+ video_processor_.Get(), vp_output_view_.Get(), 0, 1, &stream);
+ RETURN_ON_HR_FAILURE(hr, "VideoProcessorBlt failed", hr);
+ }
+
+ return hr;
+}
+
} // namespace media
diff --git a/chromium/media/gpu/windows/media_foundation_video_encode_accelerator_win.h b/chromium/media/gpu/windows/media_foundation_video_encode_accelerator_win.h
index 3ce96cc475e..6be82c57351 100644
--- a/chromium/media/gpu/windows/media_foundation_video_encode_accelerator_win.h
+++ b/chromium/media/gpu/windows/media_foundation_video_encode_accelerator_win.h
@@ -48,6 +48,7 @@ class MEDIA_GPU_EXPORT MediaFoundationVideoEncodeAccelerator
void RequestEncodingParametersChange(uint32_t bitrate,
uint32_t framerate) override;
void Destroy() override;
+ bool IsGpuFrameResizeSupported() override;
// Preloads dlls required for encoding. Returns true if all required dlls are
// correctly loaded.
@@ -117,6 +118,12 @@ class MEDIA_GPU_EXPORT MediaFoundationVideoEncodeAccelerator
// Releases resources encoder holds.
void ReleaseEncoderResources();
+ // Initialize video processing (for scaling)
+ HRESULT InitializeD3DVideoProcessing(ID3D11Texture2D* input_texture);
+
+ // Perform D3D11 scaling operation
+ HRESULT PerformD3DScaling(ID3D11Texture2D* input_texture);
+
const bool compatible_with_win7_;
// Flag to enable the usage of MFTEnumEx.
@@ -139,7 +146,7 @@ class MEDIA_GPU_EXPORT MediaFoundationVideoEncodeAccelerator
// Group of picture length for encoded output stream, indicates the
// distance between two key frames.
- base::Optional<uint32_t> gop_length_;
+ absl::optional<uint32_t> gop_length_;
Microsoft::WRL::ComPtr<IMFActivate> activate_;
Microsoft::WRL::ComPtr<IMFTransform> encoder_;
@@ -155,6 +162,14 @@ class MEDIA_GPU_EXPORT MediaFoundationVideoEncodeAccelerator
bool input_required_;
Microsoft::WRL::ComPtr<IMFSample> input_sample_;
Microsoft::WRL::ComPtr<IMFSample> output_sample_;
+ Microsoft::WRL::ComPtr<ID3D11VideoProcessor> video_processor_;
+ Microsoft::WRL::ComPtr<ID3D11VideoProcessorEnumerator>
+ video_processor_enumerator_;
+ Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device_;
+ Microsoft::WRL::ComPtr<ID3D11VideoContext> video_context_;
+ D3D11_VIDEO_PROCESSOR_CONTENT_DESC vp_desc_ = {};
+ Microsoft::WRL::ComPtr<ID3D11Texture2D> scaled_d3d11_texture_;
+ Microsoft::WRL::ComPtr<ID3D11VideoProcessorOutputView> vp_output_view_;
// To expose client callbacks from VideoEncodeAccelerator.
// NOTE: all calls to this object *MUST* be executed on
diff --git a/chromium/media/gpu/windows/output_with_release_mailbox_cb.h b/chromium/media/gpu/windows/output_with_release_mailbox_cb.h
index d653c3a1d32..9fcfcb509e2 100644
--- a/chromium/media/gpu/windows/output_with_release_mailbox_cb.h
+++ b/chromium/media/gpu/windows/output_with_release_mailbox_cb.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_BASE_OUTPUT_WITH_RELEASE_MAILBOX_CB_H_
-#define MEDIA_BASE_OUTPUT_WITH_RELEASE_MAILBOX_CB_H_
+#ifndef MEDIA_GPU_WINDOWS_OUTPUT_WITH_RELEASE_MAILBOX_CB_H_
+#define MEDIA_GPU_WINDOWS_OUTPUT_WITH_RELEASE_MAILBOX_CB_H_
#include "base/callback.h"
#include "base/memory/ref_counted.h"
@@ -23,4 +23,4 @@ using OutputWithReleaseMailboxCB =
} // namespace media
-#endif // MEDIA_BASE_OUTPUT_WITH_RELEASE_MAILBOX_CB_H_
+#endif // MEDIA_GPU_WINDOWS_OUTPUT_WITH_RELEASE_MAILBOX_CB_H_
diff --git a/chromium/media/learning/common/learning_task.h b/chromium/media/learning/common/learning_task.h
index 9d70b93e1e1..90a19a131c9 100644
--- a/chromium/media/learning/common/learning_task.h
+++ b/chromium/media/learning/common/learning_task.h
@@ -10,8 +10,8 @@
#include <vector>
#include "base/component_export.h"
-#include "base/optional.h"
#include "media/learning/common/value.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace learning {
@@ -121,7 +121,7 @@ struct COMPONENT_EXPORT(LEARNING_COMMON) LearningTask {
// of feature to train the model with, to allow for feature importance
// measurement. Note that UMA reporting only supports subsets of size one, or
// the whole set.
- base::Optional<int> feature_subset_size;
+ absl::optional<int> feature_subset_size;
// RandomForest parameters
diff --git a/chromium/media/learning/common/learning_task_controller.h b/chromium/media/learning/common/learning_task_controller.h
index 64ba5a2cbc7..0644e2d85f8 100644
--- a/chromium/media/learning/common/learning_task_controller.h
+++ b/chromium/media/learning/common/learning_task_controller.h
@@ -8,12 +8,12 @@
#include "base/callback.h"
#include "base/component_export.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "base/unguessable_token.h"
#include "media/learning/common/labelled_example.h"
#include "media/learning/common/learning_task.h"
#include "media/learning/common/target_histogram.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace learning {
@@ -46,7 +46,7 @@ struct ObservationCompletion {
class COMPONENT_EXPORT(LEARNING_COMMON) LearningTaskController {
public:
using PredictionCB = base::OnceCallback<void(
- const base::Optional<TargetHistogram>& predicted)>;
+ const absl::optional<TargetHistogram>& predicted)>;
LearningTaskController() = default;
virtual ~LearningTaskController() = default;
@@ -68,8 +68,8 @@ class COMPONENT_EXPORT(LEARNING_COMMON) LearningTaskController {
virtual void BeginObservation(
base::UnguessableToken id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target = base::nullopt,
- const base::Optional<ukm::SourceId>& source_id = base::nullopt) = 0;
+ const absl::optional<TargetValue>& default_target = absl::nullopt,
+ const absl::optional<ukm::SourceId>& source_id = absl::nullopt) = 0;
// Complete an observation by sending a completion.
virtual void CompleteObservation(base::UnguessableToken id,
@@ -85,13 +85,13 @@ class COMPONENT_EXPORT(LEARNING_COMMON) LearningTaskController {
// default value was given.
virtual void UpdateDefaultTarget(
base::UnguessableToken id,
- const base::Optional<TargetValue>& default_target) = 0;
+ const absl::optional<TargetValue>& default_target) = 0;
// Returns the LearningTask associated with |this|.
virtual const LearningTask& GetLearningTask() = 0;
// Asynchronously predicts distribution for given |features|. |callback| will
- // receive a base::nullopt prediction when model is not available. |callback|
+ // receive a absl::nullopt prediction when model is not available. |callback|
// may be called immediately without posting.
virtual void PredictDistribution(const FeatureVector& features,
PredictionCB callback) = 0;
diff --git a/chromium/media/learning/impl/distribution_reporter.h b/chromium/media/learning/impl/distribution_reporter.h
index 5ec60e9205b..6a96cf7aac4 100644
--- a/chromium/media/learning/impl/distribution_reporter.h
+++ b/chromium/media/learning/impl/distribution_reporter.h
@@ -11,11 +11,11 @@
#include "base/component_export.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "media/learning/common/learning_task.h"
#include "media/learning/common/target_histogram.h"
#include "media/learning/impl/model.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace learning {
@@ -81,7 +81,7 @@ class COMPONENT_EXPORT(LEARNING_IMPL) DistributionReporter {
virtual void OnPrediction(const PredictionInfo& prediction_info,
TargetHistogram predicted) = 0;
- const base::Optional<std::set<int>>& feature_indices() const {
+ const absl::optional<std::set<int>>& feature_indices() const {
return feature_indices_;
}
@@ -90,7 +90,7 @@ class COMPONENT_EXPORT(LEARNING_IMPL) DistributionReporter {
// If provided, then these are the features that are used to train the model.
// Otherwise, we assume that all features are used.
- base::Optional<std::set<int>> feature_indices_;
+ absl::optional<std::set<int>> feature_indices_;
base::WeakPtrFactory<DistributionReporter> weak_factory_{this};
diff --git a/chromium/media/learning/impl/feature_provider.h b/chromium/media/learning/impl/feature_provider.h
index 3932905885a..c53fb81374a 100644
--- a/chromium/media/learning/impl/feature_provider.h
+++ b/chromium/media/learning/impl/feature_provider.h
@@ -5,9 +5,6 @@
#ifndef MEDIA_LEARNING_IMPL_FEATURE_PROVIDER_H_
#define MEDIA_LEARNING_IMPL_FEATURE_PROVIDER_H_
-#include <map>
-#include <string>
-
#include "base/callback.h"
#include "base/component_export.h"
#include "base/macros.h"
diff --git a/chromium/media/learning/impl/fisher_iris_dataset.h b/chromium/media/learning/impl/fisher_iris_dataset.h
index 09d7c8132d7..6117ddf54b6 100644
--- a/chromium/media/learning/impl/fisher_iris_dataset.h
+++ b/chromium/media/learning/impl/fisher_iris_dataset.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_LEARNING_IMPL_FISHER_IRIS_DATASET_H_
#define MEDIA_LEARNING_IMPL_FISHER_IRIS_DATASET_H_
-#include <vector>
-
#include "base/memory/ref_counted.h"
#include "media/learning/common/labelled_example.h"
diff --git a/chromium/media/learning/impl/learning_fuzzertest.cc b/chromium/media/learning/impl/learning_fuzzertest.cc
index 8dc05543ed7..d6d00b9efcc 100644
--- a/chromium/media/learning/impl/learning_fuzzertest.cc
+++ b/chromium/media/learning/impl/learning_fuzzertest.cc
@@ -64,11 +64,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Build random examples.
while (provider.remaining_bytes() > 0) {
base::UnguessableToken id = base::UnguessableToken::Create();
- base::Optional<TargetValue> default_target;
+ absl::optional<TargetValue> default_target;
if (provider.ConsumeBool())
default_target = TargetValue(ConsumeDouble(&provider));
controller.BeginObservation(id, ConsumeFeatureVector(&provider),
- default_target, base::nullopt);
+ default_target, absl::nullopt);
controller.CompleteObservation(
id, ObservationCompletion(TargetValue(ConsumeDouble(&provider)),
ConsumeDouble(&provider)));
diff --git a/chromium/media/learning/impl/learning_session_impl.cc b/chromium/media/learning/impl/learning_session_impl.cc
index cfe5ababfe7..620bd91b874 100644
--- a/chromium/media/learning/impl/learning_session_impl.cc
+++ b/chromium/media/learning/impl/learning_session_impl.cc
@@ -35,7 +35,7 @@ class WeakLearningTaskController : public LearningTaskController {
// Cancel any outstanding observation, unless they have a default value. In
// that case, complete them.
for (auto& id : outstanding_observations_) {
- const base::Optional<TargetValue>& default_value = id.second;
+ const absl::optional<TargetValue>& default_value = id.second;
if (default_value) {
controller_->AsyncCall(&LearningTaskController::CompleteObservation)
.WithArgs(id.first, *default_value);
@@ -49,8 +49,8 @@ class WeakLearningTaskController : public LearningTaskController {
void BeginObservation(
base::UnguessableToken id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target,
- const base::Optional<ukm::SourceId>& source_id) override {
+ const absl::optional<TargetValue>& default_target,
+ const absl::optional<ukm::SourceId>& source_id) override {
if (!weak_session_)
return;
@@ -59,7 +59,7 @@ class WeakLearningTaskController : public LearningTaskController {
// doesn't support it. Since all client calls eventually come through us
// anyway, it seems okay to handle it here.
controller_->AsyncCall(&LearningTaskController::BeginObservation)
- .WithArgs(id, features, base::nullopt, source_id);
+ .WithArgs(id, features, absl::nullopt, source_id);
}
void CompleteObservation(base::UnguessableToken id,
@@ -81,7 +81,7 @@ class WeakLearningTaskController : public LearningTaskController {
void UpdateDefaultTarget(
base::UnguessableToken id,
- const base::Optional<TargetValue>& default_target) override {
+ const absl::optional<TargetValue>& default_target) override {
if (!weak_session_)
return;
@@ -104,7 +104,7 @@ class WeakLearningTaskController : public LearningTaskController {
// Set of ids that have been started but not completed / cancelled yet, and
// any default target value.
- std::map<base::UnguessableToken, base::Optional<TargetValue>>
+ std::map<base::UnguessableToken, absl::optional<TargetValue>>
outstanding_observations_;
};
diff --git a/chromium/media/learning/impl/learning_session_impl_unittest.cc b/chromium/media/learning/impl/learning_session_impl_unittest.cc
index 86df5620ca7..bb3b17155b4 100644
--- a/chromium/media/learning/impl/learning_session_impl_unittest.cc
+++ b/chromium/media/learning/impl/learning_session_impl_unittest.cc
@@ -42,8 +42,8 @@ class LearningSessionImplTest : public testing::Test {
void BeginObservation(
base::UnguessableToken id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target,
- const base::Optional<ukm::SourceId>& source_id) override {
+ const absl::optional<TargetValue>& default_target,
+ const absl::optional<ukm::SourceId>& source_id) override {
id_ = id;
observation_features_ = features;
default_target_ = default_target;
@@ -64,7 +64,7 @@ class LearningSessionImplTest : public testing::Test {
void UpdateDefaultTarget(
base::UnguessableToken id,
- const base::Optional<TargetValue>& default_target) override {
+ const absl::optional<TargetValue>& default_target) override {
// Should not be called, since LearningTaskControllerImpl doesn't support
// default values.
updated_id_ = id;
@@ -86,15 +86,15 @@ class LearningSessionImplTest : public testing::Test {
FeatureVector observation_features_;
FeatureVector predict_features_;
PredictionCB predict_cb_;
- base::Optional<TargetValue> default_target_;
- base::Optional<ukm::SourceId> source_id_;
+ absl::optional<TargetValue> default_target_;
+ absl::optional<ukm::SourceId> source_id_;
LabelledExample example_;
// Most recently cancelled id.
base::UnguessableToken cancelled_id_;
// Id of most recently changed default target value.
- base::Optional<base::UnguessableToken> updated_id_;
+ absl::optional<base::UnguessableToken> updated_id_;
};
class FakeFeatureProvider : public FeatureProvider {
@@ -191,7 +191,7 @@ TEST_F(LearningSessionImplTest, ExamplesAreForwardedToCorrectTask) {
std::unique_ptr<LearningTaskController> ltc_0 =
session_->GetController(task_0_.name);
ukm::SourceId source_id(123);
- ltc_0->BeginObservation(id, example_0.features, base::nullopt, source_id);
+ ltc_0->BeginObservation(id, example_0.features, absl::nullopt, source_id);
ltc_0->CompleteObservation(
id, ObservationCompletion(example_0.target_value, example_0.weight));
@@ -290,7 +290,7 @@ TEST_F(LearningSessionImplTest, ChangeDefaultTargetToValue) {
// Start an observation without a default, then add one.
base::UnguessableToken id = base::UnguessableToken::Create();
- controller->BeginObservation(id, FeatureVector(), base::nullopt);
+ controller->BeginObservation(id, FeatureVector(), absl::nullopt);
TargetValue default_target(123);
controller->UpdateDefaultTarget(id, default_target);
task_environment_.RunUntilIdle();
@@ -316,7 +316,7 @@ TEST_F(LearningSessionImplTest, ChangeDefaultTargetToNoValue) {
base::UnguessableToken id = base::UnguessableToken::Create();
TargetValue default_target(123);
controller->BeginObservation(id, FeatureVector(), default_target);
- controller->UpdateDefaultTarget(id, base::nullopt);
+ controller->UpdateDefaultTarget(id, absl::nullopt);
task_environment_.RunUntilIdle();
EXPECT_EQ(task_controllers_[0]->id_, id);
@@ -341,7 +341,7 @@ TEST_F(LearningSessionImplTest, PredictDistribution) {
controller->PredictDistribution(
features, base::BindOnce(
[](TargetHistogram* test_storage,
- const base::Optional<TargetHistogram>& predicted) {
+ const absl::optional<TargetHistogram>& predicted) {
*test_storage = *predicted;
},
&observed_prediction));
diff --git a/chromium/media/learning/impl/learning_task_controller_helper.cc b/chromium/media/learning/impl/learning_task_controller_helper.cc
index 59dee3cbbe5..37a823fd943 100644
--- a/chromium/media/learning/impl/learning_task_controller_helper.cc
+++ b/chromium/media/learning/impl/learning_task_controller_helper.cc
@@ -27,7 +27,7 @@ LearningTaskControllerHelper::~LearningTaskControllerHelper() = default;
void LearningTaskControllerHelper::BeginObservation(
base::UnguessableToken id,
FeatureVector features,
- base::Optional<ukm::SourceId> source_id) {
+ absl::optional<ukm::SourceId> source_id) {
auto& pending_example = pending_examples_[id];
if (source_id)
diff --git a/chromium/media/learning/impl/learning_task_controller_helper.h b/chromium/media/learning/impl/learning_task_controller_helper.h
index 69e59a1de21..1f45a9c4aae 100644
--- a/chromium/media/learning/impl/learning_task_controller_helper.h
+++ b/chromium/media/learning/impl/learning_task_controller_helper.h
@@ -49,7 +49,7 @@ class COMPONENT_EXPORT(LEARNING_IMPL) LearningTaskControllerHelper
// See LearningTaskController::BeginObservation.
void BeginObservation(base::UnguessableToken id,
FeatureVector features,
- base::Optional<ukm::SourceId> source_id);
+ absl::optional<ukm::SourceId> source_id);
void CompleteObservation(base::UnguessableToken id,
const ObservationCompletion& completion);
void CancelObservation(base::UnguessableToken id);
diff --git a/chromium/media/learning/impl/learning_task_controller_helper_unittest.cc b/chromium/media/learning/impl/learning_task_controller_helper_unittest.cc
index 1d0774246fd..427f68d0a8e 100644
--- a/chromium/media/learning/impl/learning_task_controller_helper_unittest.cc
+++ b/chromium/media/learning/impl/learning_task_controller_helper_unittest.cc
@@ -93,7 +93,7 @@ class LearningTaskControllerHelperTest : public testing::Test {
FeatureProvider::FeatureVectorCB fp_cb_;
// Most recently added example via OnLabelledExample, if any.
- base::Optional<LabelledExample> most_recent_example_;
+ absl::optional<LabelledExample> most_recent_example_;
ukm::SourceId most_recent_source_id_;
LearningTask task_;
@@ -122,7 +122,7 @@ TEST_F(LearningTaskControllerHelperTest, AddingAnExampleWithoutFPWorks) {
TEST_F(LearningTaskControllerHelperTest, DropTargetValueWithoutFPWorks) {
// Verify that we can drop an example without labelling it.
CreateClient(false);
- helper_->BeginObservation(id_, example_.features, base::nullopt);
+ helper_->BeginObservation(id_, example_.features, absl::nullopt);
EXPECT_EQ(pending_example_count(), 1u);
helper_->CancelObservation(id_);
task_environment_.RunUntilIdle();
@@ -133,7 +133,7 @@ TEST_F(LearningTaskControllerHelperTest, DropTargetValueWithoutFPWorks) {
TEST_F(LearningTaskControllerHelperTest, AddTargetValueBeforeFP) {
// Verify that an example is added if the target value arrives first.
CreateClient(true);
- helper_->BeginObservation(id_, example_.features, base::nullopt);
+ helper_->BeginObservation(id_, example_.features, absl::nullopt);
EXPECT_EQ(pending_example_count(), 1u);
task_environment_.RunUntilIdle();
// The feature provider should know about the example.
@@ -158,7 +158,7 @@ TEST_F(LearningTaskControllerHelperTest, AddTargetValueBeforeFP) {
TEST_F(LearningTaskControllerHelperTest, DropTargetValueBeforeFP) {
// Verify that an example is correctly dropped before the FP adds features.
CreateClient(true);
- helper_->BeginObservation(id_, example_.features, base::nullopt);
+ helper_->BeginObservation(id_, example_.features, absl::nullopt);
EXPECT_EQ(pending_example_count(), 1u);
task_environment_.RunUntilIdle();
// The feature provider should know about the example.
@@ -181,7 +181,7 @@ TEST_F(LearningTaskControllerHelperTest, DropTargetValueBeforeFP) {
TEST_F(LearningTaskControllerHelperTest, AddTargetValueAfterFP) {
// Verify that an example is added if the target value arrives second.
CreateClient(true);
- helper_->BeginObservation(id_, example_.features, base::nullopt);
+ helper_->BeginObservation(id_, example_.features, absl::nullopt);
EXPECT_EQ(pending_example_count(), 1u);
task_environment_.RunUntilIdle();
// The feature provider should know about the example.
@@ -207,7 +207,7 @@ TEST_F(LearningTaskControllerHelperTest, AddTargetValueAfterFP) {
TEST_F(LearningTaskControllerHelperTest, DropTargetValueAfterFP) {
// Verify that we can cancel the observationc after sending features.
CreateClient(true);
- helper_->BeginObservation(id_, example_.features, base::nullopt);
+ helper_->BeginObservation(id_, example_.features, absl::nullopt);
EXPECT_EQ(pending_example_count(), 1u);
task_environment_.RunUntilIdle();
// The feature provider should know about the example.
diff --git a/chromium/media/learning/impl/learning_task_controller_impl.cc b/chromium/media/learning/impl/learning_task_controller_impl.cc
index 45c812d2489..895f94f8681 100644
--- a/chromium/media/learning/impl/learning_task_controller_impl.cc
+++ b/chromium/media/learning/impl/learning_task_controller_impl.cc
@@ -52,8 +52,8 @@ LearningTaskControllerImpl::~LearningTaskControllerImpl() = default;
void LearningTaskControllerImpl::BeginObservation(
base::UnguessableToken id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target,
- const base::Optional<ukm::SourceId>& source_id) {
+ const absl::optional<TargetValue>& default_target,
+ const absl::optional<ukm::SourceId>& source_id) {
// TODO(liberato): Should we enforce that the right number of features are
// present here? Right now, we allow it to be shorter, so that features from
// a FeatureProvider may be omitted. Of course, they have to be at the end in
@@ -87,7 +87,7 @@ void LearningTaskControllerImpl::CancelObservation(base::UnguessableToken id) {
void LearningTaskControllerImpl::UpdateDefaultTarget(
base::UnguessableToken id,
- const base::Optional<TargetValue>& default_target) {
+ const absl::optional<TargetValue>& default_target) {
NOTREACHED();
}
@@ -101,7 +101,7 @@ void LearningTaskControllerImpl::PredictDistribution(
if (model_)
std::move(callback).Run(model_->PredictDistribution(features));
else
- std::move(callback).Run(base::nullopt);
+ std::move(callback).Run(absl::nullopt);
}
void LearningTaskControllerImpl::AddFinishedExample(LabelledExample example,
diff --git a/chromium/media/learning/impl/learning_task_controller_impl.h b/chromium/media/learning/impl/learning_task_controller_impl.h
index 1453f1b779c..bc32ddf86eb 100644
--- a/chromium/media/learning/impl/learning_task_controller_impl.h
+++ b/chromium/media/learning/impl/learning_task_controller_impl.h
@@ -54,14 +54,14 @@ class COMPONENT_EXPORT(LEARNING_IMPL) LearningTaskControllerImpl
void BeginObservation(
base::UnguessableToken id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target,
- const base::Optional<ukm::SourceId>& source_id) override;
+ const absl::optional<TargetValue>& default_target,
+ const absl::optional<ukm::SourceId>& source_id) override;
void CompleteObservation(base::UnguessableToken id,
const ObservationCompletion& completion) override;
void CancelObservation(base::UnguessableToken id) override;
void UpdateDefaultTarget(
base::UnguessableToken id,
- const base::Optional<TargetValue>& default_target) override;
+ const absl::optional<TargetValue>& default_target) override;
const LearningTask& GetLearningTask() override;
void PredictDistribution(const FeatureVector& features,
PredictionCB callback) override;
diff --git a/chromium/media/learning/impl/learning_task_controller_impl_unittest.cc b/chromium/media/learning/impl/learning_task_controller_impl_unittest.cc
index 38945699bc7..ad8b059645f 100644
--- a/chromium/media/learning/impl/learning_task_controller_impl_unittest.cc
+++ b/chromium/media/learning/impl/learning_task_controller_impl_unittest.cc
@@ -23,7 +23,7 @@ class LearningTaskControllerImplTest : public testing::Test {
: DistributionReporter(task) {}
// protected => public
- const base::Optional<std::set<int>>& feature_indices() const {
+ const absl::optional<std::set<int>>& feature_indices() const {
return DistributionReporter::feature_indices();
}
@@ -133,21 +133,21 @@ class LearningTaskControllerImplTest : public testing::Test {
}
void AddExample(const LabelledExample& example,
- base::Optional<ukm::SourceId> source_id = base::nullopt) {
+ absl::optional<ukm::SourceId> source_id = absl::nullopt) {
base::UnguessableToken id = base::UnguessableToken::Create();
- controller_->BeginObservation(id, example.features, base::nullopt,
+ controller_->BeginObservation(id, example.features, absl::nullopt,
source_id);
controller_->CompleteObservation(
id, ObservationCompletion(example.target_value, example.weight));
}
void VerifyPrediction(const FeatureVector& features,
- base::Optional<TargetHistogram> expectation) {
- base::Optional<TargetHistogram> observed_prediction;
+ absl::optional<TargetHistogram> expectation) {
+ absl::optional<TargetHistogram> observed_prediction;
controller_->PredictDistribution(
features, base::BindOnce(
- [](base::Optional<TargetHistogram>* test_storage,
- const base::Optional<TargetHistogram>& predicted) {
+ [](absl::optional<TargetHistogram>* test_storage,
+ const absl::optional<TargetHistogram>& predicted) {
*test_storage = predicted;
},
&observed_prediction));
@@ -279,9 +279,9 @@ TEST_F(LearningTaskControllerImplTest, FeatureSubsetsWork) {
TEST_F(LearningTaskControllerImplTest, PredictDistribution) {
CreateController();
- // Predictions should be base::nullopt until we have a model.
+ // Predictions should be absl::nullopt until we have a model.
LabelledExample example;
- VerifyPrediction(example.features, base::nullopt);
+ VerifyPrediction(example.features, absl::nullopt);
AddExample(example);
TargetHistogram expected_histogram;
diff --git a/chromium/media/learning/impl/lookup_table_trainer.h b/chromium/media/learning/impl/lookup_table_trainer.h
index 5417c84823d..f17e6173b2a 100644
--- a/chromium/media/learning/impl/lookup_table_trainer.h
+++ b/chromium/media/learning/impl/lookup_table_trainer.h
@@ -5,9 +5,6 @@
#ifndef MEDIA_LEARNING_IMPL_LOOKUP_TABLE_TRAINER_H_
#define MEDIA_LEARNING_IMPL_LOOKUP_TABLE_TRAINER_H_
-#include <memory>
-#include <vector>
-
#include "base/component_export.h"
#include "base/macros.h"
#include "media/learning/common/learning_task.h"
diff --git a/chromium/media/learning/impl/model.h b/chromium/media/learning/impl/model.h
index 673b61e4c43..793455c8505 100644
--- a/chromium/media/learning/impl/model.h
+++ b/chromium/media/learning/impl/model.h
@@ -9,7 +9,6 @@
#include "base/component_export.h"
#include "media/learning/common/labelled_example.h"
#include "media/learning/common/target_histogram.h"
-#include "media/learning/impl/model.h"
namespace media {
namespace learning {
diff --git a/chromium/media/learning/impl/one_hot.h b/chromium/media/learning/impl/one_hot.h
index b48b66ec924..23e69845c38 100644
--- a/chromium/media/learning/impl/one_hot.h
+++ b/chromium/media/learning/impl/one_hot.h
@@ -11,11 +11,11 @@
#include "base/component_export.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "media/learning/common/labelled_example.h"
#include "media/learning/common/learning_task.h"
#include "media/learning/common/value.h"
#include "media/learning/impl/model.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace learning {
@@ -53,7 +53,7 @@ class COMPONENT_EXPORT(LEARNING_IMPL) OneHotConverter {
// [original task feature index] = optional converter for it. If the feature
// was kNumeric to begin with, then there will be no converter.
- std::vector<base::Optional<ValueVectorIndexMap>> converters_;
+ std::vector<absl::optional<ValueVectorIndexMap>> converters_;
DISALLOW_COPY_AND_ASSIGN(OneHotConverter);
};
diff --git a/chromium/media/learning/impl/random_number_generator.h b/chromium/media/learning/impl/random_number_generator.h
index e4ee413dad9..aeb4514b18e 100644
--- a/chromium/media/learning/impl/random_number_generator.h
+++ b/chromium/media/learning/impl/random_number_generator.h
@@ -6,7 +6,6 @@
#define MEDIA_LEARNING_IMPL_RANDOM_NUMBER_GENERATOR_H_
#include <cstdint>
-#include <memory>
#include "base/component_export.h"
#include "base/macros.h"
diff --git a/chromium/media/learning/impl/random_tree_trainer.cc b/chromium/media/learning/impl/random_tree_trainer.cc
index b75deafec04..041cd884e24 100644
--- a/chromium/media/learning/impl/random_tree_trainer.cc
+++ b/chromium/media/learning/impl/random_tree_trainer.cc
@@ -8,8 +8,8 @@
#include "base/bind.h"
#include "base/check_op.h"
-#include "base/optional.h"
#include "base/threading/sequenced_task_runner_handle.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
namespace learning {
@@ -177,9 +177,9 @@ std::unique_ptr<Model> RandomTreeTrainer::Build(
// and the target value, if the Optional has a value then it's the singular
// value that we've found so far. If we find a second one, then we'll clear
// the Optional.
- base::Optional<TargetValue> target_value(
+ absl::optional<TargetValue> target_value(
training_data[training_idx[0]].target_value);
- std::vector<base::Optional<FeatureValue>> feature_values;
+ std::vector<absl::optional<FeatureValue>> feature_values;
feature_values.resize(training_data[0].features.size());
for (size_t feature_idx : unused_set) {
feature_values[feature_idx] =
diff --git a/chromium/media/learning/mojo/mojo_learning_task_controller_service.cc b/chromium/media/learning/mojo/mojo_learning_task_controller_service.cc
index 92dc1e179c9..af2b814525d 100644
--- a/chromium/media/learning/mojo/mojo_learning_task_controller_service.cc
+++ b/chromium/media/learning/mojo/mojo_learning_task_controller_service.cc
@@ -28,7 +28,7 @@ MojoLearningTaskControllerService::~MojoLearningTaskControllerService() =
void MojoLearningTaskControllerService::BeginObservation(
const base::UnguessableToken& id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target) {
+ const absl::optional<TargetValue>& default_target) {
// Drop the observation if it doesn't match the feature description size.
if (features.size() != task_.feature_descriptions.size())
return;
@@ -66,7 +66,7 @@ void MojoLearningTaskControllerService::CancelObservation(
void MojoLearningTaskControllerService::UpdateDefaultTarget(
const base::UnguessableToken& id,
- const base::Optional<TargetValue>& default_target) {
+ const absl::optional<TargetValue>& default_target) {
auto iter = in_flight_observations_.find(id);
if (iter == in_flight_observations_.end())
return;
diff --git a/chromium/media/learning/mojo/mojo_learning_task_controller_service.h b/chromium/media/learning/mojo/mojo_learning_task_controller_service.h
index eff098fe99c..9cdb8eae8ea 100644
--- a/chromium/media/learning/mojo/mojo_learning_task_controller_service.h
+++ b/chromium/media/learning/mojo/mojo_learning_task_controller_service.h
@@ -34,13 +34,13 @@ class COMPONENT_EXPORT(MEDIA_LEARNING_MOJO) MojoLearningTaskControllerService
void BeginObservation(
const base::UnguessableToken& id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target) override;
+ const absl::optional<TargetValue>& default_target) override;
void CompleteObservation(const base::UnguessableToken& id,
const ObservationCompletion& completion) override;
void CancelObservation(const base::UnguessableToken& id) override;
void UpdateDefaultTarget(
const base::UnguessableToken& id,
- const base::Optional<TargetValue>& default_target) override;
+ const absl::optional<TargetValue>& default_target) override;
void PredictDistribution(const FeatureVector& features,
PredictDistributionCallback callback) override;
diff --git a/chromium/media/learning/mojo/mojo_learning_task_controller_service_unittest.cc b/chromium/media/learning/mojo/mojo_learning_task_controller_service_unittest.cc
index 971e6dcbe3d..59675cab5d5 100644
--- a/chromium/media/learning/mojo/mojo_learning_task_controller_service_unittest.cc
+++ b/chromium/media/learning/mojo/mojo_learning_task_controller_service_unittest.cc
@@ -28,8 +28,8 @@ class MojoLearningTaskControllerServiceTest : public ::testing::Test {
void BeginObservation(
base::UnguessableToken id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target,
- const base::Optional<ukm::SourceId>& source_id) override {
+ const absl::optional<TargetValue>& default_target,
+ const absl::optional<ukm::SourceId>& source_id) override {
begin_args_.id_ = id;
begin_args_.features_ = features;
begin_args_.default_target_ = default_target;
@@ -48,7 +48,7 @@ class MojoLearningTaskControllerServiceTest : public ::testing::Test {
void UpdateDefaultTarget(
base::UnguessableToken id,
- const base::Optional<TargetValue>& default_target) override {
+ const absl::optional<TargetValue>& default_target) override {
update_default_args_.id_ = id;
update_default_args_.default_target_ = default_target;
}
@@ -66,8 +66,8 @@ class MojoLearningTaskControllerServiceTest : public ::testing::Test {
struct {
base::UnguessableToken id_;
FeatureVector features_;
- base::Optional<TargetValue> default_target_;
- base::Optional<ukm::SourceId> source_id_;
+ absl::optional<TargetValue> default_target_;
+ absl::optional<ukm::SourceId> source_id_;
} begin_args_;
struct {
@@ -81,7 +81,7 @@ class MojoLearningTaskControllerServiceTest : public ::testing::Test {
struct {
base::UnguessableToken id_;
- base::Optional<TargetValue> default_target_;
+ absl::optional<TargetValue> default_target_;
} update_default_args_;
struct {
@@ -122,7 +122,7 @@ class MojoLearningTaskControllerServiceTest : public ::testing::Test {
TEST_F(MojoLearningTaskControllerServiceTest, BeginComplete) {
base::UnguessableToken id = base::UnguessableToken::Create();
FeatureVector features = {FeatureValue(123), FeatureValue(456)};
- service_->BeginObservation(id, features, base::nullopt);
+ service_->BeginObservation(id, features, absl::nullopt);
EXPECT_EQ(id, controller_raw_->begin_args_.id_);
EXPECT_EQ(features, controller_raw_->begin_args_.features_);
EXPECT_FALSE(controller_raw_->begin_args_.default_target_);
@@ -140,7 +140,7 @@ TEST_F(MojoLearningTaskControllerServiceTest, BeginComplete) {
TEST_F(MojoLearningTaskControllerServiceTest, BeginCancel) {
base::UnguessableToken id = base::UnguessableToken::Create();
FeatureVector features = {FeatureValue(123), FeatureValue(456)};
- service_->BeginObservation(id, features, base::nullopt);
+ service_->BeginObservation(id, features, absl::nullopt);
EXPECT_EQ(id, controller_raw_->begin_args_.id_);
EXPECT_EQ(features, controller_raw_->begin_args_.features_);
EXPECT_FALSE(controller_raw_->begin_args_.default_target_);
@@ -166,7 +166,7 @@ TEST_F(MojoLearningTaskControllerServiceTest, TooFewFeaturesIsIgnored) {
// A FeatureVector with too few elements should be ignored.
base::UnguessableToken id = base::UnguessableToken::Create();
FeatureVector short_features = {FeatureValue(123)};
- service_->BeginObservation(id, short_features, base::nullopt);
+ service_->BeginObservation(id, short_features, absl::nullopt);
EXPECT_NE(id, controller_raw_->begin_args_.id_);
EXPECT_EQ(controller_raw_->begin_args_.features_.size(), 0u);
}
@@ -176,7 +176,7 @@ TEST_F(MojoLearningTaskControllerServiceTest, TooManyFeaturesIsIgnored) {
base::UnguessableToken id = base::UnguessableToken::Create();
FeatureVector long_features = {FeatureValue(123), FeatureValue(456),
FeatureValue(789)};
- service_->BeginObservation(id, long_features, base::nullopt);
+ service_->BeginObservation(id, long_features, absl::nullopt);
EXPECT_NE(id, controller_raw_->begin_args_.id_);
EXPECT_EQ(controller_raw_->begin_args_.features_.size(), 0u);
}
@@ -197,7 +197,7 @@ TEST_F(MojoLearningTaskControllerServiceTest, CancelWithoutBeginFails) {
TEST_F(MojoLearningTaskControllerServiceTest, UpdateDefaultTargetToValue) {
base::UnguessableToken id = base::UnguessableToken::Create();
FeatureVector features = {FeatureValue(123), FeatureValue(456)};
- service_->BeginObservation(id, features, base::nullopt);
+ service_->BeginObservation(id, features, absl::nullopt);
TargetValue default_target(987);
service_->UpdateDefaultTarget(id, default_target);
EXPECT_EQ(id, controller_raw_->update_default_args_.id_);
@@ -210,9 +210,9 @@ TEST_F(MojoLearningTaskControllerServiceTest, UpdateDefaultTargetToNoValue) {
FeatureVector features = {FeatureValue(123), FeatureValue(456)};
TargetValue default_target(987);
service_->BeginObservation(id, features, default_target);
- service_->UpdateDefaultTarget(id, base::nullopt);
+ service_->UpdateDefaultTarget(id, absl::nullopt);
EXPECT_EQ(id, controller_raw_->update_default_args_.id_);
- EXPECT_EQ(base::nullopt,
+ EXPECT_EQ(absl::nullopt,
controller_raw_->update_default_args_.default_target_);
}
@@ -222,7 +222,7 @@ TEST_F(MojoLearningTaskControllerServiceTest, PredictDistribution) {
service_->PredictDistribution(
features, base::BindOnce(
[](TargetHistogram* test_storage,
- const base::Optional<TargetHistogram>& predicted) {
+ const absl::optional<TargetHistogram>& predicted) {
*test_storage = *predicted;
},
&observed_prediction));
diff --git a/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller.cc b/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller.cc
index 3d7b16cb6f5..aaca1ad3896 100644
--- a/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller.cc
+++ b/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller.cc
@@ -19,8 +19,8 @@ MojoLearningTaskController::~MojoLearningTaskController() = default;
void MojoLearningTaskController::BeginObservation(
base::UnguessableToken id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target,
- const base::Optional<ukm::SourceId>& source_id) {
+ const absl::optional<TargetValue>& default_target,
+ const absl::optional<ukm::SourceId>& source_id) {
// We don't need to keep track of in-flight observations, since the service
// side handles it for us. Also note that |source_id| is ignored; the service
// has no reason to trust it. It will fill it in for us. DCHECK in case
@@ -41,7 +41,7 @@ void MojoLearningTaskController::CancelObservation(base::UnguessableToken id) {
void MojoLearningTaskController::UpdateDefaultTarget(
base::UnguessableToken id,
- const base::Optional<TargetValue>& default_target) {
+ const absl::optional<TargetValue>& default_target) {
controller_->UpdateDefaultTarget(id, default_target);
}
diff --git a/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller.h b/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller.h
index efe5067778e..f58305908a5 100644
--- a/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller.h
+++ b/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_LEARNING_MOJO_PUBLIC_CPP_MOJO_LEARNING_TASK_CONTROLLER_H_
#define MEDIA_LEARNING_MOJO_PUBLIC_CPP_MOJO_LEARNING_TASK_CONTROLLER_H_
-#include <utility>
-
#include "base/component_export.h"
#include "base/macros.h"
#include "media/learning/common/learning_task_controller.h"
@@ -31,14 +29,14 @@ class COMPONENT_EXPORT(MEDIA_LEARNING_MOJO) MojoLearningTaskController
void BeginObservation(
base::UnguessableToken id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target,
- const base::Optional<ukm::SourceId>& source_id) override;
+ const absl::optional<TargetValue>& default_target,
+ const absl::optional<ukm::SourceId>& source_id) override;
void CompleteObservation(base::UnguessableToken id,
const ObservationCompletion& completion) override;
void CancelObservation(base::UnguessableToken id) override;
void UpdateDefaultTarget(
base::UnguessableToken id,
- const base::Optional<TargetValue>& default_target) override;
+ const absl::optional<TargetValue>& default_target) override;
const LearningTask& GetLearningTask() override;
void PredictDistribution(const FeatureVector& features,
PredictionCB callback) override;
diff --git a/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller_unittest.cc b/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller_unittest.cc
index 37232a6b313..9d7beecef00 100644
--- a/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller_unittest.cc
+++ b/chromium/media/learning/mojo/public/cpp/mojo_learning_task_controller_unittest.cc
@@ -26,7 +26,7 @@ class MojoLearningTaskControllerTest : public ::testing::Test {
void BeginObservation(
const base::UnguessableToken& id,
const FeatureVector& features,
- const base::Optional<TargetValue>& default_target) override {
+ const absl::optional<TargetValue>& default_target) override {
begin_args_.id_ = id;
begin_args_.features_ = features;
begin_args_.default_target_ = default_target;
@@ -44,7 +44,7 @@ class MojoLearningTaskControllerTest : public ::testing::Test {
void UpdateDefaultTarget(
const base::UnguessableToken& id,
- const base::Optional<TargetValue>& default_target) override {
+ const absl::optional<TargetValue>& default_target) override {
update_default_args_.id_ = id;
update_default_args_.default_target_ = default_target;
}
@@ -58,7 +58,7 @@ class MojoLearningTaskControllerTest : public ::testing::Test {
struct {
base::UnguessableToken id_;
FeatureVector features_;
- base::Optional<TargetValue> default_target_;
+ absl::optional<TargetValue> default_target_;
} begin_args_;
struct {
@@ -72,7 +72,7 @@ class MojoLearningTaskControllerTest : public ::testing::Test {
struct {
base::UnguessableToken id_;
- base::Optional<TargetValue> default_target_;
+ absl::optional<TargetValue> default_target_;
} update_default_args_;
struct {
@@ -115,8 +115,8 @@ TEST_F(MojoLearningTaskControllerTest, GetLearningTask) {
TEST_F(MojoLearningTaskControllerTest, BeginWithoutDefaultTarget) {
base::UnguessableToken id = base::UnguessableToken::Create();
FeatureVector features = {FeatureValue(123), FeatureValue(456)};
- learning_controller_->BeginObservation(id, features, base::nullopt,
- base::nullopt);
+ learning_controller_->BeginObservation(id, features, absl::nullopt,
+ absl::nullopt);
task_environment_.RunUntilIdle();
EXPECT_EQ(id, fake_learning_controller_.begin_args_.id_);
EXPECT_EQ(features, fake_learning_controller_.begin_args_.features_);
@@ -128,7 +128,7 @@ TEST_F(MojoLearningTaskControllerTest, BeginWithDefaultTarget) {
TargetValue default_target(987);
FeatureVector features = {FeatureValue(123), FeatureValue(456)};
learning_controller_->BeginObservation(id, features, default_target,
- base::nullopt);
+ absl::nullopt);
task_environment_.RunUntilIdle();
EXPECT_EQ(id, fake_learning_controller_.begin_args_.id_);
EXPECT_EQ(features, fake_learning_controller_.begin_args_.features_);
@@ -140,8 +140,8 @@ TEST_F(MojoLearningTaskControllerTest, UpdateDefaultTargetToValue) {
// Test if we can update the default target to a non-nullopt.
base::UnguessableToken id = base::UnguessableToken::Create();
FeatureVector features = {FeatureValue(123), FeatureValue(456)};
- learning_controller_->BeginObservation(id, features, base::nullopt,
- base::nullopt);
+ learning_controller_->BeginObservation(id, features, absl::nullopt,
+ absl::nullopt);
TargetValue default_target(987);
learning_controller_->UpdateDefaultTarget(id, default_target);
task_environment_.RunUntilIdle();
@@ -157,12 +157,12 @@ TEST_F(MojoLearningTaskControllerTest, UpdateDefaultTargetToNoValue) {
FeatureVector features = {FeatureValue(123), FeatureValue(456)};
TargetValue default_target(987);
learning_controller_->BeginObservation(id, features, default_target,
- base::nullopt);
- learning_controller_->UpdateDefaultTarget(id, base::nullopt);
+ absl::nullopt);
+ learning_controller_->UpdateDefaultTarget(id, absl::nullopt);
task_environment_.RunUntilIdle();
EXPECT_EQ(id, fake_learning_controller_.update_default_args_.id_);
EXPECT_EQ(features, fake_learning_controller_.begin_args_.features_);
- EXPECT_EQ(base::nullopt,
+ EXPECT_EQ(absl::nullopt,
fake_learning_controller_.update_default_args_.default_target_);
}
@@ -190,7 +190,7 @@ TEST_F(MojoLearningTaskControllerTest, PredictDistribution) {
learning_controller_->PredictDistribution(
features, base::BindOnce(
[](TargetHistogram* test_storage,
- const base::Optional<TargetHistogram>& predicted) {
+ const absl::optional<TargetHistogram>& predicted) {
*test_storage = *predicted;
},
&observed_prediction));
diff --git a/chromium/media/learning/mojo/public/mojom/learning_task_controller.mojom b/chromium/media/learning/mojo/public/mojom/learning_task_controller.mojom
index 782c8608ca7..4c4d9bf0e7e 100644
--- a/chromium/media/learning/mojo/public/mojom/learning_task_controller.mojom
+++ b/chromium/media/learning/mojo/public/mojom/learning_task_controller.mojom
@@ -43,7 +43,7 @@ interface LearningTaskController {
TargetValue? default_target);
// Asynchronously predicts distribution for given |features|. |callback| will
- // receive a base::nullopt prediction when model is not available.
+ // receive a absl::nullopt prediction when model is not available.
PredictDistribution(array<FeatureValue> features)
=> (TargetHistogram? predicted);
};
diff --git a/chromium/media/media_options.gni b/chromium/media/media_options.gni
index 61c804e9624..303b2e323d5 100644
--- a/chromium/media/media_options.gni
+++ b/chromium/media/media_options.gni
@@ -249,6 +249,7 @@ media_subcomponent_deps = [
if (is_fuchsia) {
media_subcomponent_deps += [
+ "//media/fuchsia/audio",
"//media/fuchsia/cdm",
"//media/fuchsia/common",
]
@@ -258,6 +259,6 @@ if (media_use_ffmpeg) {
media_subcomponent_deps += [ "//media/ffmpeg" ]
}
-if (enable_library_cdms) {
+if (enable_library_cdms || is_win) {
media_subcomponent_deps += [ "//media/cdm:cdm_type_conversion" ]
}
diff --git a/chromium/media/midi/DIR_METADATA b/chromium/media/midi/DIR_METADATA
index d6aec82bd66..b44dd56948b 100644
--- a/chromium/media/midi/DIR_METADATA
+++ b/chromium/media/midi/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Blink>WebMIDI"
diff --git a/chromium/media/midi/midi_manager_alsa_unittest.cc b/chromium/media/midi/midi_manager_alsa_unittest.cc
index 88baa7580f6..995ccc350bd 100644
--- a/chromium/media/midi/midi_manager_alsa_unittest.cc
+++ b/chromium/media/midi/midi_manager_alsa_unittest.cc
@@ -18,101 +18,116 @@ class MidiManagerAlsaTest : public ::testing::Test {
// following tests.
// Inputs. port_input_0_ == port_input_1_.
- port_input_0_.reset(new MidiManagerAlsa::MidiPort(
- "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial"),
+ port_input_0_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial"),
1, 2, 5, "client_name", "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_1_.reset(new MidiManagerAlsa::MidiPort(
- "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial"),
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_1_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial"),
1, 2, 5, "client_name", "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_minimal_.reset(new MidiManagerAlsa::MidiPort(
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_minimal_ = std::make_unique<MidiManagerAlsa::MidiPort>(
"", MidiManagerAlsa::MidiPort::Id(), 0, 0, 0, "", "", "", "",
- MidiManagerAlsa::MidiPort::Type::kInput));
+ MidiManagerAlsa::MidiPort::Type::kInput);
// Outputs. port_output_0_ == port_output_1_.
- port_output_0_.reset(new MidiManagerAlsa::MidiPort(
- "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial"),
+ port_output_0_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial"),
1, 2, 5, "client_name", "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kOutput));
- port_output_1_.reset(new MidiManagerAlsa::MidiPort(
- "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial"),
+ MidiManagerAlsa::MidiPort::Type::kOutput);
+ port_output_1_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial"),
1, 2, 5, "client_name", "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kOutput));
+ MidiManagerAlsa::MidiPort::Type::kOutput);
// MidiPort fields that differ from port_input_0_ in a single way each time.
// Used for testing the Match* and Find* methods.
- port_input_0_alt_path_.reset(new MidiManagerAlsa::MidiPort(
- "path2", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial"),
+ port_input_0_alt_path_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path2",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial"),
1, 2, 5, "client_name", "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_0_alt_id_.reset(new MidiManagerAlsa::MidiPort(
- "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial2"),
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_0_alt_id_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial2"),
1, 2, 5, "client_name", "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_0_alt_client_name_.reset(new MidiManagerAlsa::MidiPort(
- "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial"),
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_0_alt_client_name_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial"),
1, 2, 5, "client_name2", "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_0_alt_port_name_.reset(new MidiManagerAlsa::MidiPort(
- "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial"),
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_0_alt_port_name_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial"),
1, 2, 5, "client_name", "port_name2", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_0_alt_client_id_.reset(new MidiManagerAlsa::MidiPort(
- "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial"),
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_0_alt_client_id_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial"),
2, 2, 5, "client_name", "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_0_alt_port_id_.reset(new MidiManagerAlsa::MidiPort(
- "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial"),
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_0_alt_port_id_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial"),
1, 3, 5, "client_name", "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_0_alt_midi_device_.reset(new MidiManagerAlsa::MidiPort(
- "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
- "interface", "serial"),
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_0_alt_midi_device_ = std::make_unique<MidiManagerAlsa::MidiPort>(
+ "path",
+ MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model", "interface",
+ "serial"),
1, 2, 6, "client_name", "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
+ MidiManagerAlsa::MidiPort::Type::kInput);
// "No card" variants of above. For testing FindDisconnected.
- port_input_0_no_card_.reset(new MidiManagerAlsa::MidiPort(
+ port_input_0_no_card_ = std::make_unique<MidiManagerAlsa::MidiPort>(
"", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name",
"port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_1_no_card_.reset(new MidiManagerAlsa::MidiPort(
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_1_no_card_ = std::make_unique<MidiManagerAlsa::MidiPort>(
"", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name",
"port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_output_0_no_card_.reset(new MidiManagerAlsa::MidiPort(
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_output_0_no_card_ = std::make_unique<MidiManagerAlsa::MidiPort>(
"", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name",
"port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kOutput));
+ MidiManagerAlsa::MidiPort::Type::kOutput);
// No card variants of the alt variants from above. For more testing
// of Match* and Find*.
- port_input_0_no_card_alt_client_name_.reset(new MidiManagerAlsa::MidiPort(
- "", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name2",
- "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_0_no_card_alt_port_name_.reset(new MidiManagerAlsa::MidiPort(
- "", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name",
- "port_name2", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_0_no_card_alt_client_id_.reset(new MidiManagerAlsa::MidiPort(
- "", MidiManagerAlsa::MidiPort::Id(), 2, 2, -1, "client_name",
- "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
- port_input_0_no_card_alt_port_id_.reset(new MidiManagerAlsa::MidiPort(
- "", MidiManagerAlsa::MidiPort::Id(), 1, 3, -1, "client_name",
- "port_name", "manufacturer", "version",
- MidiManagerAlsa::MidiPort::Type::kInput));
+ port_input_0_no_card_alt_client_name_ =
+ std::make_unique<MidiManagerAlsa::MidiPort>(
+ "", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name2",
+ "port_name", "manufacturer", "version",
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_0_no_card_alt_port_name_ =
+ std::make_unique<MidiManagerAlsa::MidiPort>(
+ "", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name",
+ "port_name2", "manufacturer", "version",
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_0_no_card_alt_client_id_ =
+ std::make_unique<MidiManagerAlsa::MidiPort>(
+ "", MidiManagerAlsa::MidiPort::Id(), 2, 2, -1, "client_name",
+ "port_name", "manufacturer", "version",
+ MidiManagerAlsa::MidiPort::Type::kInput);
+ port_input_0_no_card_alt_port_id_ =
+ std::make_unique<MidiManagerAlsa::MidiPort>(
+ "", MidiManagerAlsa::MidiPort::Id(), 1, 3, -1, "client_name",
+ "port_name", "manufacturer", "version",
+ MidiManagerAlsa::MidiPort::Type::kInput);
}
// Counts ports for help with testing ToMidiPortState().
diff --git a/chromium/media/midi/midi_manager_win.cc b/chromium/media/midi/midi_manager_win.cc
index 4f1f67d5168..5ddf29b44dc 100644
--- a/chromium/media/midi/midi_manager_win.cc
+++ b/chromium/media/midi/midi_manager_win.cc
@@ -14,6 +14,7 @@
#include <algorithm>
#include <limits>
#include <map>
+#include <memory>
#include <string>
#include <utility>
@@ -21,7 +22,6 @@
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
@@ -34,6 +34,7 @@
#include "media/midi/midi_service.mojom.h"
#include "media/midi/midi_switches.h"
#include "services/device/public/cpp/usb/usb_ids.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace midi {
@@ -118,7 +119,7 @@ base::Lock* GetInstanceIdLock() {
}
// Issues unique MidiManager instance ID.
-int64_t IssueNextInstanceId(base::Optional<int64_t> override_id) {
+int64_t IssueNextInstanceId(absl::optional<int64_t> override_id) {
static int64_t id = kInvalidInstanceId;
if (override_id) {
int64_t result = ++id;
@@ -633,7 +634,7 @@ MidiManagerWin::PortManager::HandleMidiInCallback(HMIDIIN hmi,
if (IsRunningInsideMidiInGetNumDevs())
GetTaskLock()->AssertAcquired();
else
- task_lock.reset(new base::AutoLock(*GetTaskLock()));
+ task_lock = std::make_unique<base::AutoLock>(*GetTaskLock());
{
base::AutoLock lock(*GetInstanceIdLock());
if (instance_id != g_active_instance_id)
@@ -702,7 +703,7 @@ void MidiManagerWin::OverflowInstanceIdForTesting() {
MidiManagerWin::MidiManagerWin(MidiService* service)
: MidiManager(service),
- instance_id_(IssueNextInstanceId(base::nullopt)),
+ instance_id_(IssueNextInstanceId(absl::nullopt)),
port_manager_(std::make_unique<PortManager>()) {
base::AutoLock lock(*GetInstanceIdLock());
CHECK_EQ(kInvalidInstanceId, g_active_instance_id);
diff --git a/chromium/media/midi/midi_manager_winrt.cc b/chromium/media/midi/midi_manager_winrt.cc
index 9ec6bad7047..eb1de49d6d4 100644
--- a/chromium/media/midi/midi_manager_winrt.cc
+++ b/chromium/media/midi/midi_manager_winrt.cc
@@ -22,6 +22,7 @@
#include <wrl/event.h>
#include <iomanip>
+#include <memory>
#include <unordered_map>
#include <unordered_set>
@@ -828,8 +829,8 @@ void MidiManagerWinrt::InitializeOnComRunner() {
return;
}
- port_manager_in_.reset(new MidiInPortManager(this));
- port_manager_out_.reset(new MidiOutPortManager(this));
+ port_manager_in_ = std::make_unique<MidiInPortManager>(this);
+ port_manager_out_ = std::make_unique<MidiOutPortManager>(this);
if (!(port_manager_in_->StartWatcher() &&
port_manager_out_->StartWatcher())) {
diff --git a/chromium/media/midi/midi_output_port_android.h b/chromium/media/midi/midi_output_port_android.h
index 0574c276145..f2da111b426 100644
--- a/chromium/media/midi/midi_output_port_android.h
+++ b/chromium/media/midi/midi_output_port_android.h
@@ -10,7 +10,6 @@
#include <vector>
#include "base/android/scoped_java_ref.h"
-#include "base/time/time.h"
namespace midi {
diff --git a/chromium/media/midi/task_service.cc b/chromium/media/midi/task_service.cc
index fb190688880..21bb8dc0a9b 100644
--- a/chromium/media/midi/task_service.cc
+++ b/chromium/media/midi/task_service.cc
@@ -151,7 +151,7 @@ scoped_refptr<base::SingleThreadTaskRunner> TaskService::GetTaskRunner(
#elif defined(OS_MAC)
options.message_pump_type = base::MessagePumpType::UI;
#endif
- threads_[thread]->StartWithOptions(options);
+ threads_[thread]->StartWithOptions(std::move(options));
}
return threads_[thread]->task_runner();
}
diff --git a/chromium/media/midi/usb_midi_device_factory_android.h b/chromium/media/midi/usb_midi_device_factory_android.h
index d0dae559ac7..feb6fafdbda 100644
--- a/chromium/media/midi/usb_midi_device_factory_android.h
+++ b/chromium/media/midi/usb_midi_device_factory_android.h
@@ -6,7 +6,6 @@
#define MEDIA_MIDI_USB_MIDI_DEVICE_FACTORY_ANDROID_H_
#include <jni.h>
-#include <vector>
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
diff --git a/chromium/media/mojo/clients/mojo_android_overlay.h b/chromium/media/mojo/clients/mojo_android_overlay.h
index 333a537e8b1..0e2e8a8cafb 100644
--- a/chromium/media/mojo/clients/mojo_android_overlay.h
+++ b/chromium/media/mojo/clients/mojo_android_overlay.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_BASE_MOJO_ANDROID_OVERLAY_H_
-#define MEDIA_BASE_MOJO_ANDROID_OVERLAY_H_
+#ifndef MEDIA_MOJO_CLIENTS_MOJO_ANDROID_OVERLAY_H_
+#define MEDIA_MOJO_CLIENTS_MOJO_ANDROID_OVERLAY_H_
#include "base/macros.h"
#include "base/unguessable_token.h"
@@ -51,4 +51,4 @@ class MojoAndroidOverlay : public AndroidOverlay,
} // namespace media
-#endif // MEDIA_BASE_MOJO_ANDROID_OVERLAY_H_
+#endif // MEDIA_MOJO_CLIENTS_MOJO_ANDROID_OVERLAY_H_
diff --git a/chromium/media/mojo/clients/mojo_android_overlay_unittest.cc b/chromium/media/mojo/clients/mojo_android_overlay_unittest.cc
index ca09bfd567b..cbe08142895 100644
--- a/chromium/media/mojo/clients/mojo_android_overlay_unittest.cc
+++ b/chromium/media/mojo/clients/mojo_android_overlay_unittest.cc
@@ -112,9 +112,9 @@ class MojoAndroidOverlayTest : public ::testing::Test {
base::UnguessableToken routing_token = base::UnguessableToken::Create();
- overlay_client_.reset(
- new MojoAndroidOverlay(provider_receiver_.BindNewPipeAndPassRemote(),
- std::move(config_), routing_token));
+ overlay_client_ = std::make_unique<MojoAndroidOverlay>(
+ provider_receiver_.BindNewPipeAndPassRemote(), std::move(config_),
+ routing_token);
overlay_client_->AddSurfaceDestroyedCallback(base::BindOnce(
&MockClientCallbacks::OnDestroyed, base::Unretained(&callbacks_)));
base::RunLoop().RunUntilIdle();
diff --git a/chromium/media/mojo/clients/mojo_audio_decoder.cc b/chromium/media/mojo/clients/mojo_audio_decoder.cc
index 76259add30c..105647f5f36 100644
--- a/chromium/media/mojo/clients/mojo_audio_decoder.cc
+++ b/chromium/media/mojo/clients/mojo_audio_decoder.cc
@@ -75,7 +75,7 @@ void MojoAudioDecoder::Initialize(const AudioDecoderConfig& config,
}
// Fail immediately if the stream is encrypted but |cdm_context| is invalid.
- base::Optional<base::UnguessableToken> cdm_id;
+ absl::optional<base::UnguessableToken> cdm_id;
if (config.is_encrypted() && cdm_context)
cdm_id = cdm_context->GetCdmId();
diff --git a/chromium/media/mojo/clients/mojo_cdm.cc b/chromium/media/mojo/clients/mojo_cdm.cc
index f0098346345..3a7e883efef 100644
--- a/chromium/media/mojo/clients/mojo_cdm.cc
+++ b/chromium/media/mojo/clients/mojo_cdm.cc
@@ -267,7 +267,7 @@ Decryptor* MojoCdm::GetDecryptor() {
return decryptor_.get();
}
-base::Optional<base::UnguessableToken> MojoCdm::GetCdmId() const {
+absl::optional<base::UnguessableToken> MojoCdm::GetCdmId() const {
// Can be called on a different thread.
base::AutoLock auto_lock(lock_);
DVLOG(2) << __func__ << ": cdm_id="
diff --git a/chromium/media/mojo/clients/mojo_cdm.h b/chromium/media/mojo/clients/mojo_cdm.h
index ca886cc99cf..b4e04d4ef37 100644
--- a/chromium/media/mojo/clients/mojo_cdm.h
+++ b/chromium/media/mojo/clients/mojo_cdm.h
@@ -78,7 +78,7 @@ class MojoCdm final : public ContentDecryptionModule,
// All GetDecryptor() calls must be made on the same thread.
std::unique_ptr<CallbackRegistration> RegisterEventCB(EventCB event_cb) final;
Decryptor* GetDecryptor() final;
- base::Optional<base::UnguessableToken> GetCdmId() const final;
+ absl::optional<base::UnguessableToken> GetCdmId() const final;
#if defined(OS_WIN)
bool RequiresMediaFoundationRenderer() final;
#endif // defined(OS_WIN)
@@ -124,7 +124,7 @@ class MojoCdm final : public ContentDecryptionModule,
// CDM ID of the remote CDM. Set after initialization is completed. Must not
// be invalid if initialization succeeded.
- base::Optional<base::UnguessableToken> cdm_id_ GUARDED_BY(lock_);
+ absl::optional<base::UnguessableToken> cdm_id_ GUARDED_BY(lock_);
// The mojo::PendingRemote<mojom::Decryptor> exposed by the remote CDM. Set
// after initialization is completed and cleared after |decryptor_| is
diff --git a/chromium/media/mojo/clients/mojo_demuxer_stream_impl.cc b/chromium/media/mojo/clients/mojo_demuxer_stream_impl.cc
index e2bae040316..2149c8aaef3 100644
--- a/chromium/media/mojo/clients/mojo_demuxer_stream_impl.cc
+++ b/chromium/media/mojo/clients/mojo_demuxer_stream_impl.cc
@@ -31,8 +31,8 @@ void MojoDemuxerStreamImpl::Initialize(InitializeCallback callback) {
DVLOG(2) << __func__;
// Prepare the initial config.
- base::Optional<AudioDecoderConfig> audio_config;
- base::Optional<VideoDecoderConfig> video_config;
+ absl::optional<AudioDecoderConfig> audio_config;
+ absl::optional<VideoDecoderConfig> video_config;
if (stream_->type() == Type::AUDIO) {
audio_config = stream_->audio_decoder_config();
} else if (stream_->type() == Type::VIDEO) {
@@ -64,8 +64,8 @@ void MojoDemuxerStreamImpl::EnableBitstreamConverter() {
void MojoDemuxerStreamImpl::OnBufferReady(ReadCallback callback,
Status status,
scoped_refptr<DecoderBuffer> buffer) {
- base::Optional<AudioDecoderConfig> audio_config;
- base::Optional<VideoDecoderConfig> video_config;
+ absl::optional<AudioDecoderConfig> audio_config;
+ absl::optional<VideoDecoderConfig> video_config;
if (status == Status::kConfigChanged) {
DVLOG(2) << __func__ << ": ConfigChange!";
diff --git a/chromium/media/mojo/clients/mojo_renderer.cc b/chromium/media/mojo/clients/mojo_renderer.cc
index 3e3a752134b..52fada6caed 100644
--- a/chromium/media/mojo/clients/mojo_renderer.cc
+++ b/chromium/media/mojo/clients/mojo_renderer.cc
@@ -120,7 +120,7 @@ void MojoRenderer::InitializeRendererFromUrl(media::RendererClient* client) {
url_params.top_frame_origin, url_params.allow_credentials,
url_params.is_hls);
remote_renderer_->Initialize(client_receiver_.BindNewEndpointAndPassRemote(),
- base::nullopt, std::move(media_url_params),
+ absl::nullopt, std::move(media_url_params),
base::BindOnce(&MojoRenderer::OnInitialized,
base::Unretained(this), client));
}
@@ -139,7 +139,7 @@ void MojoRenderer::SetCdm(CdmContext* cdm_context,
return;
}
- base::Optional<base::UnguessableToken> cdm_id = cdm_context->GetCdmId();
+ absl::optional<base::UnguessableToken> cdm_id = cdm_context->GetCdmId();
if (!cdm_id) {
DVLOG(2) << "MojoRenderer only works with remote CDMs but the CDM ID "
"is invalid.";
@@ -156,7 +156,7 @@ void MojoRenderer::SetCdm(CdmContext* cdm_context,
}
void MojoRenderer::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
// TODO(chcunningham): Proxy to remote renderer if needed.
}
@@ -254,7 +254,7 @@ void MojoRenderer::OnError(const Status& status) {
DCHECK(!init_cb_);
encountered_error_ = true;
- base::Optional<PipelineStatus> pipeline_status =
+ absl::optional<PipelineStatus> pipeline_status =
StatusCodeToPipelineStatus(status.code());
// If an unexpected status code is encountered default
diff --git a/chromium/media/mojo/clients/mojo_renderer.h b/chromium/media/mojo/clients/mojo_renderer.h
index 50354d88b73..096f6e24e66 100644
--- a/chromium/media/mojo/clients/mojo_renderer.h
+++ b/chromium/media/mojo/clients/mojo_renderer.h
@@ -11,7 +11,6 @@
#include <vector>
#include "base/macros.h"
-#include "base/optional.h"
#include "base/time/default_tick_clock.h"
#include "base/unguessable_token.h"
#include "media/base/demuxer_stream.h"
@@ -21,6 +20,7 @@
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace base {
class SingleThreadTaskRunner;
@@ -56,7 +56,7 @@ class MojoRenderer : public Renderer, public mojom::RendererClient {
media::RendererClient* client,
PipelineStatusCallback init_cb) override;
void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void Flush(base::OnceClosure flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
void SetPlaybackRate(double playback_rate) override;
@@ -158,7 +158,7 @@ class MojoRenderer : public Renderer, public mojom::RendererClient {
mutable base::Lock lock_;
media::TimeDeltaInterpolator media_time_interpolator_;
- base::Optional<PipelineStatistics> pending_stats_;
+ absl::optional<PipelineStatistics> pending_stats_;
DISALLOW_COPY_AND_ASSIGN(MojoRenderer);
};
diff --git a/chromium/media/mojo/clients/mojo_renderer_wrapper.cc b/chromium/media/mojo/clients/mojo_renderer_wrapper.cc
index 2971244b9fa..0bf3197a414 100644
--- a/chromium/media/mojo/clients/mojo_renderer_wrapper.cc
+++ b/chromium/media/mojo/clients/mojo_renderer_wrapper.cc
@@ -42,7 +42,7 @@ void MojoRendererWrapper::SetCdm(CdmContext* cdm_context,
}
void MojoRendererWrapper::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
mojo_renderer_->SetLatencyHint(latency_hint);
}
diff --git a/chromium/media/mojo/clients/mojo_renderer_wrapper.h b/chromium/media/mojo/clients/mojo_renderer_wrapper.h
index 891b4ff0de7..23fbb053d08 100644
--- a/chromium/media/mojo/clients/mojo_renderer_wrapper.h
+++ b/chromium/media/mojo/clients/mojo_renderer_wrapper.h
@@ -27,7 +27,7 @@ class MojoRendererWrapper : public Renderer {
RendererClient* client,
PipelineStatusCallback init_cb) override;
void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void Flush(base::OnceClosure flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
void SetPlaybackRate(double playback_rate) override;
diff --git a/chromium/media/mojo/clients/mojo_video_decoder.cc b/chromium/media/mojo/clients/mojo_video_decoder.cc
index 23c3bc5d7c1..d516b23b432 100644
--- a/chromium/media/mojo/clients/mojo_video_decoder.cc
+++ b/chromium/media/mojo/clients/mojo_video_decoder.cc
@@ -169,8 +169,8 @@ void MojoVideoDecoder::Initialize(const VideoDecoderConfig& config,
return;
}
- base::Optional<base::UnguessableToken> cdm_id =
- cdm_context ? cdm_context->GetCdmId() : base::nullopt;
+ absl::optional<base::UnguessableToken> cdm_id =
+ cdm_context ? cdm_context->GetCdmId() : absl::nullopt;
// Fail immediately if the stream is encrypted but |cdm_id| is invalid.
// This check is needed to avoid unnecessary IPC to the remote process.
@@ -255,7 +255,7 @@ void MojoVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
void MojoVideoDecoder::OnVideoFrameDecoded(
const scoped_refptr<VideoFrame>& frame,
bool can_read_without_stalling,
- const base::Optional<base::UnguessableToken>& release_token) {
+ const absl::optional<base::UnguessableToken>& release_token) {
DVLOG(3) << __func__;
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/chromium/media/mojo/clients/mojo_video_decoder.h b/chromium/media/mojo/clients/mojo_video_decoder.h
index 1d85f48837d..cd486c3dd1d 100644
--- a/chromium/media/mojo/clients/mojo_video_decoder.h
+++ b/chromium/media/mojo/clients/mojo_video_decoder.h
@@ -80,7 +80,7 @@ class MojoVideoDecoder final : public VideoDecoder,
void OnVideoFrameDecoded(
const scoped_refptr<VideoFrame>& frame,
bool can_read_without_stalling,
- const base::Optional<base::UnguessableToken>& release_token) final;
+ const absl::optional<base::UnguessableToken>& release_token) final;
void OnWaiting(WaitingReason reason) final;
void RequestOverlayInfo(bool restart_for_transitions) final;
diff --git a/chromium/media/mojo/clients/mojo_video_encode_accelerator_unittest.cc b/chromium/media/mojo/clients/mojo_video_encode_accelerator_unittest.cc
index e2fbe73d745..9eda59e756f 100644
--- a/chromium/media/mojo/clients/mojo_video_encode_accelerator_unittest.cc
+++ b/chromium/media/mojo/clients/mojo_video_encode_accelerator_unittest.cc
@@ -4,6 +4,9 @@
#include <stddef.h>
+#include <memory>
+
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "gpu/config/gpu_info.h"
@@ -146,9 +149,10 @@ class MojoVideoEncodeAcceleratorTest : public ::testing::Test {
std::make_unique<MockMojoVideoEncodeAccelerator>(),
mojo_vea.InitWithNewPipeAndPassReceiver());
- mojo_vea_.reset(new MojoVideoEncodeAccelerator(
- std::move(mojo_vea),
- media::VideoEncodeAccelerator::SupportedProfiles()));
+ mojo_vea_ =
+ base::WrapUnique<VideoEncodeAccelerator>(new MojoVideoEncodeAccelerator(
+ std::move(mojo_vea),
+ media::VideoEncodeAccelerator::SupportedProfiles()));
}
void TearDown() override {
@@ -184,7 +188,7 @@ class MojoVideoEncodeAcceleratorTest : public ::testing::Test {
const VideoEncodeAccelerator::Config config(
PIXEL_FORMAT_I420, kInputVisibleSize, kOutputProfile, kInitialBitrate,
- base::nullopt, base::nullopt, base::nullopt, false, base::nullopt,
+ absl::nullopt, absl::nullopt, absl::nullopt, false, absl::nullopt,
kContentType);
EXPECT_TRUE(mojo_vea()->Initialize(config, mock_vea_client));
base::RunLoop().RunUntilIdle();
diff --git a/chromium/media/mojo/clients/win/media_foundation_renderer_client.cc b/chromium/media/mojo/clients/win/media_foundation_renderer_client.cc
index 66ef3880041..e2f85301a60 100644
--- a/chromium/media/mojo/clients/win/media_foundation_renderer_client.cc
+++ b/chromium/media/mojo/clients/win/media_foundation_renderer_client.cc
@@ -282,7 +282,7 @@ void MediaFoundationRendererClient::SetCdm(CdmContext* cdm_context,
}
void MediaFoundationRendererClient::SetLatencyHint(
- base::Optional<base::TimeDelta> /*latency_hint*/) {
+ absl::optional<base::TimeDelta> /*latency_hint*/) {
// We do not use the latency hint today
}
@@ -377,7 +377,7 @@ void MediaFoundationRendererClient::OnVideoOpacityChange(bool opaque) {
}
void MediaFoundationRendererClient::OnVideoFrameRateChange(
- base::Optional<int> fps) {
+ absl::optional<int> fps) {
DVLOG_FUNC(1) << "fps=" << (fps ? *fps : -1);
DCHECK(has_video_);
client_->OnVideoFrameRateChange(fps);
diff --git a/chromium/media/mojo/clients/win/media_foundation_renderer_client.h b/chromium/media/mojo/clients/win/media_foundation_renderer_client.h
index f9afedaa4f7..c4b655b30b3 100644
--- a/chromium/media/mojo/clients/win/media_foundation_renderer_client.h
+++ b/chromium/media/mojo/clients/win/media_foundation_renderer_client.h
@@ -56,7 +56,7 @@ class MediaFoundationRendererClient
RendererClient* client,
PipelineStatusCallback init_cb) override;
void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void Flush(base::OnceClosure flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
void SetPlaybackRate(double playback_rate) override;
@@ -77,7 +77,7 @@ class MediaFoundationRendererClient
void OnVideoConfigChange(const media::VideoDecoderConfig& config) override;
void OnVideoNaturalSizeChange(const gfx::Size& size) override;
void OnVideoOpacityChange(bool opaque) override;
- void OnVideoFrameRateChange(base::Optional<int>) override;
+ void OnVideoFrameRateChange(absl::optional<int>) override;
// media::VideoRendererSink::RenderCallback implementation.
scoped_refptr<media::VideoFrame> Render(
diff --git a/chromium/media/mojo/common/BUILD.gn b/chromium/media/mojo/common/BUILD.gn
index 8d33e8dc97c..a570c550931 100644
--- a/chromium/media/mojo/common/BUILD.gn
+++ b/chromium/media/mojo/common/BUILD.gn
@@ -6,6 +6,8 @@ source_set("common") {
sources = [
"audio_data_s16_converter.cc",
"audio_data_s16_converter.h",
+ "input_error_code_converter.cc",
+ "input_error_code_converter.h",
"media_type_converters.cc",
"media_type_converters.h",
"mojo_data_pipe_read_write.cc",
@@ -19,7 +21,7 @@ source_set("common") {
deps = [
":mojo_shared_buffer_video_frame",
"//base",
- "//gpu/ipc/common:mojom_traits",
+ "//gpu/ipc/common",
"//media",
"//media/mojo/mojom",
"//mojo/public/cpp/bindings",
diff --git a/chromium/media/mojo/common/input_error_code_converter.cc b/chromium/media/mojo/common/input_error_code_converter.cc
new file mode 100644
index 00000000000..3829bb7cbc3
--- /dev/null
+++ b/chromium/media/mojo/common/input_error_code_converter.cc
@@ -0,0 +1,18 @@
+// Copyright 2021 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 "media/mojo/common/input_error_code_converter.h"
+
+namespace media {
+AudioCapturerSource::ErrorCode ConvertToCaptureCallbackCode(
+ mojom::InputStreamErrorCode code) {
+ switch (code) {
+ case mojom::InputStreamErrorCode::kSystemPermissions:
+ return AudioCapturerSource::ErrorCode::kSystemPermissions;
+ case mojom::InputStreamErrorCode::kUnknown:
+ break;
+ }
+ return AudioCapturerSource::ErrorCode::kUnknown;
+}
+} // namespace media
diff --git a/chromium/media/mojo/common/input_error_code_converter.h b/chromium/media/mojo/common/input_error_code_converter.h
new file mode 100644
index 00000000000..99a1f0b1059
--- /dev/null
+++ b/chromium/media/mojo/common/input_error_code_converter.h
@@ -0,0 +1,16 @@
+// Copyright 2021 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 MEDIA_MOJO_COMMON_INPUT_ERROR_CODE_CONVERTER_H_
+#define MEDIA_MOJO_COMMON_INPUT_ERROR_CODE_CONVERTER_H_
+
+#include "media/base/audio_capturer_source.h"
+#include "media/mojo/mojom/media_types.mojom.h"
+
+namespace media {
+AudioCapturerSource::ErrorCode ConvertToCaptureCallbackCode(
+ mojom::InputStreamErrorCode code);
+}
+
+#endif
diff --git a/chromium/media/mojo/common/mojo_data_pipe_read_write.h b/chromium/media/mojo/common/mojo_data_pipe_read_write.h
index 85b767c08a7..553d356b461 100644
--- a/chromium/media/mojo/common/mojo_data_pipe_read_write.h
+++ b/chromium/media/mojo/common/mojo_data_pipe_read_write.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_MOJO_COMMON_MOJO_DATA_PIPE_READ_WRITE_H_
#define MEDIA_MOJO_COMMON_MOJO_DATA_PIPE_READ_WRITE_H_
-#include <memory>
-
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "mojo/public/cpp/system/data_pipe.h"
diff --git a/chromium/media/mojo/common/mojo_decoder_buffer_converter.h b/chromium/media/mojo/common/mojo_decoder_buffer_converter.h
index 7c8ca3d99e7..c1ea6eeb892 100644
--- a/chromium/media/mojo/common/mojo_decoder_buffer_converter.h
+++ b/chromium/media/mojo/common/mojo_decoder_buffer_converter.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_MOJO_COMMON_MOJO_DECODER_BUFFER_CONVERTER_
-#define MEDIA_MOJO_COMMON_MOJO_DECODER_BUFFER_CONVERTER_
+#ifndef MEDIA_MOJO_COMMON_MOJO_DECODER_BUFFER_CONVERTER_H_
+#define MEDIA_MOJO_COMMON_MOJO_DECODER_BUFFER_CONVERTER_H_
#include <memory>
@@ -156,4 +156,4 @@ class MojoDecoderBufferWriter {
} // namespace media
-#endif // MEDIA_MOJO_COMMON_MOJO_DECODER_BUFFER_CONVERTER_
+#endif // MEDIA_MOJO_COMMON_MOJO_DECODER_BUFFER_CONVERTER_H_
diff --git a/chromium/media/mojo/mojom/BUILD.gn b/chromium/media/mojo/mojom/BUILD.gn
index 341e26de457..2caa8635a66 100644
--- a/chromium/media/mojo/mojom/BUILD.gn
+++ b/chromium/media/mojo/mojom/BUILD.gn
@@ -18,6 +18,7 @@ mojom("mojom") {
"audio_output_stream.mojom",
"audio_parameters.mojom",
"audio_stream_factory.mojom",
+ "capture_handle.mojom",
"cdm_service.mojom",
"cdm_storage.mojom",
"content_decryption_module.mojom",
@@ -536,6 +537,17 @@ mojom("mojom") {
"//ui/gfx/geometry/mojom",
]
},
+ {
+ types = [
+ {
+ mojom = "media.mojom.CdmCapability"
+ cpp = "::media::CdmCapability"
+ },
+ ]
+ traits_headers = [ "cdm_capability_mojom_traits.h" ]
+ traits_sources = [ "cdm_capability_mojom_traits.cc" ]
+ traits_public_deps = [ "//media" ]
+ },
]
cpp_typemaps += shared_typemaps
@@ -554,8 +566,7 @@ source_set("shared_mojom_traits") {
public_deps = [
":mojom_shared",
- "//gpu/ipc/common:common",
- "//gpu/ipc/common:mojom_traits",
+ "//gpu/ipc/common",
"//media",
"//media/base/ipc:ipc",
"//mojo/public/mojom/base",
diff --git a/chromium/media/mojo/mojom/audio_input_stream.mojom b/chromium/media/mojo/mojom/audio_input_stream.mojom
index f77ac9dde6f..9f48a3aab08 100644
--- a/chromium/media/mojo/mojom/audio_input_stream.mojom
+++ b/chromium/media/mojo/mojom/audio_input_stream.mojom
@@ -21,7 +21,7 @@ interface AudioInputStream {
// An interface for receiving notifications of state changes of an
// AudioInputStream.
interface AudioInputStreamClient {
- OnError();
+ OnError(InputStreamErrorCode code);
OnMutedStateChanged(bool is_muted);
};
@@ -42,6 +42,7 @@ interface AudioInputStreamObserver {
kTerminatedByClient = 2,
kStreamCreationFailed = 3,
kDocumentDestroyed = 4,
+ kSystemPermissions = 5,
};
// It will be called only once when input stream starts recording.
diff --git a/chromium/media/mojo/mojom/capture_handle.mojom b/chromium/media/mojo/mojom/capture_handle.mojom
new file mode 100644
index 00000000000..7dc157bd82d
--- /dev/null
+++ b/chromium/media/mojo/mojom/capture_handle.mojom
@@ -0,0 +1,13 @@
+// Copyright 2021 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.
+
+module media.mojom;
+
+import "mojo/public/mojom/base/string16.mojom";
+import "url/mojom/origin.mojom";
+
+struct CaptureHandle {
+ url.mojom.Origin origin;
+ mojo_base.mojom.String16 capture_handle;
+};
diff --git a/chromium/media/mojo/mojom/cdm_capability_mojom_traits.cc b/chromium/media/mojo/mojom/cdm_capability_mojom_traits.cc
new file mode 100644
index 00000000000..f72a0d32b7e
--- /dev/null
+++ b/chromium/media/mojo/mojom/cdm_capability_mojom_traits.cc
@@ -0,0 +1,39 @@
+// Copyright 2021 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 "media/mojo/mojom/cdm_capability_mojom_traits.h"
+
+#include <utility>
+
+namespace mojo {
+
+// static
+bool StructTraits<media::mojom::CdmCapabilityDataView, media::CdmCapability>::
+ Read(media::mojom::CdmCapabilityDataView input,
+ media::CdmCapability* output) {
+ std::vector<media::AudioCodec> audio_codecs;
+ if (!input.ReadAudioCodecs(&audio_codecs))
+ return false;
+
+ std::vector<media::VideoCodec> video_codecs;
+ if (!input.ReadVideoCodecs(&video_codecs))
+ return false;
+
+ std::vector<media::EncryptionScheme> encryption_schemes;
+ if (!input.ReadEncryptionSchemes(&encryption_schemes))
+ return false;
+
+ std::vector<media::CdmSessionType> session_types;
+ if (!input.ReadSessionTypes(&session_types))
+ return false;
+
+ // |encryption_schemes| and |session_types| are convert to a base::flat_map
+ // implicitly.
+ *output = media::CdmCapability(
+ std::move(audio_codecs), std::move(video_codecs),
+ std::move(encryption_schemes), std::move(session_types));
+ return true;
+}
+
+} // namespace mojo
diff --git a/chromium/media/mojo/mojom/cdm_capability_mojom_traits.h b/chromium/media/mojo/mojom/cdm_capability_mojom_traits.h
new file mode 100644
index 00000000000..178b17a7863
--- /dev/null
+++ b/chromium/media/mojo/mojom/cdm_capability_mojom_traits.h
@@ -0,0 +1,50 @@
+// Copyright 2021 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 MEDIA_MOJO_MOJOM_CDM_CAPABILITY_MOJOM_TRAITS_H_
+#define MEDIA_MOJO_MOJOM_CDM_CAPABILITY_MOJOM_TRAITS_H_
+
+#include <vector>
+
+#include "base/containers/flat_set.h"
+#include "media/base/audio_codecs.h"
+#include "media/base/content_decryption_module.h"
+#include "media/base/encryption_scheme.h"
+#include "media/base/video_codecs.h"
+#include "media/cdm/cdm_capability.h"
+#include "media/mojo/mojom/key_system_support.mojom.h"
+
+namespace mojo {
+
+template <>
+struct StructTraits<media::mojom::CdmCapabilityDataView, media::CdmCapability> {
+ static const std::vector<media::AudioCodec>& audio_codecs(
+ const media::CdmCapability& input) {
+ return input.audio_codecs;
+ }
+
+ static const std::vector<media::VideoCodec>& video_codecs(
+ const media::CdmCapability& input) {
+ return input.video_codecs;
+ }
+
+ // List of encryption schemes supported by the CDM (e.g. cenc).
+ static const base::flat_set<media::EncryptionScheme>& encryption_schemes(
+ const media::CdmCapability& input) {
+ return input.encryption_schemes;
+ }
+
+ // List of session types supported by the CDM.
+ static const base::flat_set<media::CdmSessionType>& session_types(
+ const media::CdmCapability& input) {
+ return input.session_types;
+ }
+
+ static bool Read(media::mojom::CdmCapabilityDataView input,
+ media::CdmCapability* output);
+};
+
+} // namespace mojo
+
+#endif // MEDIA_MOJO_MOJOM_CDM_CAPABILITY_MOJOM_TRAITS_H_
diff --git a/chromium/media/mojo/mojom/display_media_information.mojom b/chromium/media/mojo/mojom/display_media_information.mojom
index ad441305339..387d8cb8a96 100644
--- a/chromium/media/mojo/mojom/display_media_information.mojom
+++ b/chromium/media/mojo/mojom/display_media_information.mojom
@@ -4,6 +4,8 @@
module media.mojom;
+import "media/mojo/mojom/capture_handle.mojom";
+
// Mojo equivalent to media::DisplayMediaInformation. See also
// media/base/display_media_information.h
@@ -24,4 +26,5 @@ struct DisplayMediaInformation {
DisplayCaptureSurfaceType display_surface;
bool logical_surface;
CursorCaptureType cursor;
+ CaptureHandle? capture_handle;
};
diff --git a/chromium/media/mojo/mojom/key_system_support.mojom b/chromium/media/mojo/mojom/key_system_support.mojom
index ce6267224bd..371c259a7f4 100644
--- a/chromium/media/mojo/mojom/key_system_support.mojom
+++ b/chromium/media/mojo/mojom/key_system_support.mojom
@@ -10,20 +10,19 @@ import "media/mojo/mojom/media_types.mojom";
// TODO(xhwang): Use "set" instead of "array" if supported by mojom.
// TODO(crbug.com/796725) Find a way to include profiles and levels for
// supported codecs.
-struct KeySystemCapability {
- // Software secure codecs and encryption schemes supported by the CDM.
+struct CdmCapability {
+ array<AudioCodec> audio_codecs;
array<VideoCodec> video_codecs;
array<EncryptionScheme> encryption_schemes;
-
- // Hardware secure codecs and encryption schemes supported by the CDM.
- array<VideoCodec> hw_secure_video_codecs;
- array<EncryptionScheme> hw_secure_encryption_schemes;
-
- // Session types supported in software secure mode if no
- // |hw_secure_video_codecs| is supported, or in both modes otherwise.
array<CdmSessionType> session_types;
};
+struct KeySystemCapability {
+ CdmCapability? sw_secure_capability;
+ CdmCapability? hw_secure_capability;
+};
+
+// Used to query the browser to see if a specific key system is supported.
interface KeySystemSupport {
// Query to determine if the browser supports the |key_system|. If supported,
// |key_system_capability| is non-null indicating supported capability.
diff --git a/chromium/media/mojo/mojom/media_types.mojom b/chromium/media/mojo/mojom/media_types.mojom
index 1db4788ed02..f9d24e84613 100644
--- a/chromium/media/mojo/mojom/media_types.mojom
+++ b/chromium/media/mojo/mojom/media_types.mojom
@@ -471,3 +471,10 @@ enum MediaStreamType {
kRemote = 5, // The source is a remote peer connection.
kNone = 6, // Not a media stream.
};
+
+// Error codes propagated by Input media streams OnError methods to indicate the
+// reason for an error.
+enum InputStreamErrorCode {
+ kUnknown = 0,
+ kSystemPermissions = 1,
+};
diff --git a/chromium/media/mojo/mojom/output_protection.mojom b/chromium/media/mojo/mojom/output_protection.mojom
index 87dc10d37bf..0d09055e9c7 100644
--- a/chromium/media/mojo/mojom/output_protection.mojom
+++ b/chromium/media/mojo/mojom/output_protection.mojom
@@ -8,14 +8,16 @@ module media.mojom;
// on links that support it.
interface OutputProtection {
+ [Stable, Extensible]
enum ProtectionType {
- NONE = 0,
+ [Default] NONE = 0,
HDCP = 1,
};
// Video output link types.
+ [Stable, Extensible]
enum LinkType {
- NONE = 0,
+ [Default] NONE = 0,
UNKNOWN = 1,
INTERNAL = 2,
VGA = 4,
diff --git a/chromium/media/mojo/mojom/pipeline_status_mojom_traits.h b/chromium/media/mojo/mojom/pipeline_status_mojom_traits.h
index d2893e209d9..220323d75ce 100644
--- a/chromium/media/mojo/mojom/pipeline_status_mojom_traits.h
+++ b/chromium/media/mojo/mojom/pipeline_status_mojom_traits.h
@@ -5,8 +5,6 @@
#ifndef MEDIA_MOJO_MOJOM_PIPELINE_STATUS_MOJOM_TRAITS_H_
#define MEDIA_MOJO_MOJOM_PIPELINE_STATUS_MOJOM_TRAITS_H_
-#include <string>
-
#include "media/base/pipeline_status.h"
#include "media/mojo/mojom/media_types.mojom.h"
diff --git a/chromium/media/mojo/mojom/platform_verification.mojom b/chromium/media/mojo/mojom/platform_verification.mojom
index c96c33bb887..c3cf5b7ab5f 100644
--- a/chromium/media/mojo/mojom/platform_verification.mojom
+++ b/chromium/media/mojo/mojom/platform_verification.mojom
@@ -33,6 +33,6 @@ interface PlatformVerification {
GetStorageId(uint32 version) => (uint32 version, array<uint8> storage_id);
// Returns true if Verified Access is enabled in settings, false otherwise.
- [EnableIf=is_chromeos]
+ [EnableIf=is_chromeos_ash]
IsVerifiedAccessEnabled() => (bool enabled);
};
diff --git a/chromium/media/mojo/mojom/speech_recognition_service.mojom b/chromium/media/mojo/mojom/speech_recognition_service.mojom
index ab4d55221b5..55cf313f7c7 100644
--- a/chromium/media/mojo/mojom/speech_recognition_service.mojom
+++ b/chromium/media/mojo/mojom/speech_recognition_service.mojom
@@ -30,7 +30,8 @@ interface SpeechRecognitionContext {
// indicating whether multichannel audio is supported by the speech
// recognition service.
BindRecognizer(pending_receiver<SpeechRecognitionRecognizer> receiver,
- pending_remote<SpeechRecognitionRecognizerClient> client)
+ pending_remote<SpeechRecognitionRecognizerClient> client,
+ SpeechRecognitionOptions options)
=> (bool is_multichannel_supported);
// Prepares microphone audio to be captured from within the
@@ -38,7 +39,8 @@ interface SpeechRecognitionContext {
// SpeechRecognitionRecognizerClient.
BindAudioSourceFetcher(
pending_receiver<AudioSourceFetcher> fetcher_receiver,
- pending_remote<SpeechRecognitionRecognizerClient> client)
+ pending_remote<SpeechRecognitionRecognizerClient> client,
+ SpeechRecognitionOptions options)
=> (bool is_multichannel_supported);
};
@@ -94,26 +96,21 @@ interface SpeechRecognitionRecognizer {
// to the originating media.
SendAudioToSpeechRecognitionService(AudioDataS16 buffer);
- // Notify the speech recognition recognizer that the caption bubble was
- // closed. Used to determine whether the caption bubble was visible when
- // recording watch time.
- OnCaptionBubbleClosed();
-
- // Notify the speech recognition recognizer that audio was received by the
- // renderer after the caption bubble was closed.
- AudioReceivedAfterBubbleClosed(mojo_base.mojom.TimeDelta duration);
-
// Notify the speech recognition recognizer that the language changed. Takes
// in the locale string (e.g. "en-US").
OnLanguageChanged(string language);
};
// The interface used to return speech recognition events from the speech
-// recognition service back to the originating media. The remote lives in the
-// speech recognition process and the receiver lives in the renderer process.
+// recognition service to the client that will display the results to the user.
+// The remote lives in the speech recognition process and the receiver lives in
+// the browser process.
interface SpeechRecognitionRecognizerClient {
// Triggered by speech recognition process on a speech recognition event.
- OnSpeechRecognitionRecognitionEvent(SpeechRecognitionResult result);
+ // Returns whether the result was received successfully. Speech recognition
+ // will halt if this returns false.
+ OnSpeechRecognitionRecognitionEvent(SpeechRecognitionResult result)
+ => (bool success);
// Triggered by an error within the speech recognition service.
OnSpeechRecognitionError();
@@ -123,7 +120,7 @@ interface SpeechRecognitionRecognizerClient {
};
// A speech recognition result created by the speech service and passed to the
-// renderer.
+// browser.
struct SpeechRecognitionResult {
string transcription;
@@ -164,3 +161,23 @@ interface SpeechRecognitionClientBrowserInterface {
BindSpeechRecognitionBrowserObserver(
pending_remote<SpeechRecognitionBrowserObserver> observer);
};
+
+// Corresponds to ExtendedSodaConfigMsg in
+// chrome/services/speech/soda/proto/soda_api.proto.
+enum SpeechRecognitionMode {
+ kUnknown,
+ // Intended for voice input for keyboard usage.
+ kIme,
+ // Intended to caption a stream of audio.
+ kCaption,
+};
+
+// Options for speech recognition.
+// TODO(crbug.com/1195916): Add language identifier.
+// TODO(crbug.com/1165437): Add option to include timing metrics in the result.
+struct SpeechRecognitionOptions {
+ // What kind of recognition to use.
+ // In the case of web fallback (not for launch, used for development only),
+ // this option will be ignored.
+ SpeechRecognitionMode recognition_mode;
+};
diff --git a/chromium/media/mojo/mojom/status_mojom_traits.cc b/chromium/media/mojo/mojom/status_mojom_traits.cc
index 9efb4af6e57..639e8462643 100644
--- a/chromium/media/mojo/mojom/status_mojom_traits.cc
+++ b/chromium/media/mojo/mojom/status_mojom_traits.cc
@@ -24,7 +24,7 @@ bool StructTraits<media::mojom::StatusDataView, media::Status>::Read(
if (media::StatusCode::kOk == code)
return true;
- base::Optional<std::string> optional_message;
+ absl::optional<std::string> optional_message;
if (!data.ReadMessage(&optional_message))
return false;
message = std::move(optional_message).value_or(std::string());
@@ -38,7 +38,7 @@ bool StructTraits<media::mojom::StatusDataView, media::Status>::Read(
if (!data.ReadCauses(&output->data_->causes))
return false;
- base::Optional<base::Value> optional_data;
+ absl::optional<base::Value> optional_data;
if (!data.ReadData(&optional_data))
return false;
output->data_->data = std::move(optional_data).value_or(base::Value());
diff --git a/chromium/media/mojo/mojom/status_mojom_traits.h b/chromium/media/mojo/mojom/status_mojom_traits.h
index 03eb5ab36ed..8896ea76130 100644
--- a/chromium/media/mojo/mojom/status_mojom_traits.h
+++ b/chromium/media/mojo/mojom/status_mojom_traits.h
@@ -6,11 +6,11 @@
#define MEDIA_MOJO_MOJOM_STATUS_MOJOM_TRAITS_H_
#include "base/containers/span.h"
-#include "base/optional.h"
#include "base/values.h"
#include "media/base/ipc/media_param_traits.h"
#include "media/base/status.h"
#include "media/mojo/mojom/media_types.mojom.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace mojo {
@@ -20,9 +20,9 @@ struct StructTraits<media::mojom::StatusDataView, media::Status> {
return input.code();
}
- static base::Optional<std::string> message(const media::Status& input) {
+ static absl::optional<std::string> message(const media::Status& input) {
if (input.is_ok())
- return base::nullopt;
+ return absl::nullopt;
DCHECK(input.data_);
return input.message();
}
@@ -41,12 +41,12 @@ struct StructTraits<media::mojom::StatusDataView, media::Status> {
return input.data_->causes;
}
- static base::Optional<base::Value> data(const media::Status& input) {
+ static absl::optional<base::Value> data(const media::Status& input) {
if (!input.is_ok()) {
DCHECK(input.data_);
return input.data_->data.Clone();
}
- return base::nullopt;
+ return absl::nullopt;
}
static bool Read(media::mojom::StatusDataView data, media::Status* output);
diff --git a/chromium/media/mojo/mojom/video_decoder_config_mojom_traits.cc b/chromium/media/mojo/mojom/video_decoder_config_mojom_traits.cc
index 4699902207f..f968638da35 100644
--- a/chromium/media/mojo/mojom/video_decoder_config_mojom_traits.cc
+++ b/chromium/media/mojo/mojom/video_decoder_config_mojom_traits.cc
@@ -47,7 +47,7 @@ bool StructTraits<media::mojom::VideoDecoderConfigDataView,
if (!input.ReadColorSpaceInfo(&color_space))
return false;
- base::Optional<gfx::HDRMetadata> hdr_metadata;
+ absl::optional<gfx::HDRMetadata> hdr_metadata;
if (!input.ReadHdrMetadata(&hdr_metadata))
return false;
diff --git a/chromium/media/mojo/mojom/video_decoder_config_mojom_traits.h b/chromium/media/mojo/mojom/video_decoder_config_mojom_traits.h
index f89cfcc2f87..19a0d2f61a1 100644
--- a/chromium/media/mojo/mojom/video_decoder_config_mojom_traits.h
+++ b/chromium/media/mojo/mojom/video_decoder_config_mojom_traits.h
@@ -64,7 +64,7 @@ struct StructTraits<media::mojom::VideoDecoderConfigDataView,
return input.video_transformation();
}
- static const base::Optional<gfx::HDRMetadata>& hdr_metadata(
+ static const absl::optional<gfx::HDRMetadata>& hdr_metadata(
const media::VideoDecoderConfig& input) {
return input.hdr_metadata();
}
diff --git a/chromium/media/mojo/mojom/video_encode_accelerator.mojom b/chromium/media/mojo/mojom/video_encode_accelerator.mojom
index 3516920dd39..82cf95f9a6a 100644
--- a/chromium/media/mojo/mojom/video_encode_accelerator.mojom
+++ b/chromium/media/mojo/mojom/video_encode_accelerator.mojom
@@ -101,6 +101,7 @@ struct VideoEncodeAcceleratorConfig {
bool has_storage_type; // Whether or not config has storage type config
ContentType content_type;
array<SpatialLayer> spatial_layers;
+ bool require_low_delay;
};
interface VideoEncodeAccelerator {
diff --git a/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits.cc b/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits.cc
index df744f70048..506a38e71f7 100644
--- a/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits.cc
+++ b/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits.cc
@@ -5,10 +5,10 @@
#include "media/mojo/mojom/video_encode_accelerator_mojom_traits.h"
#include "base/notreached.h"
-#include "base/optional.h"
#include "media/base/video_bitrate_allocation.h"
#include "media/mojo/mojom/video_encode_accelerator.mojom.h"
#include "mojo/public/cpp/base/time_mojom_traits.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace mojo {
@@ -258,21 +258,21 @@ bool StructTraits<media::mojom::VideoEncodeAcceleratorConfigDataView,
if (!input.ReadOutputProfile(&output_profile))
return false;
- base::Optional<uint32_t> initial_framerate;
+ absl::optional<uint32_t> initial_framerate;
if (input.has_initial_framerate())
initial_framerate = input.initial_framerate();
- base::Optional<uint32_t> gop_length;
+ absl::optional<uint32_t> gop_length;
if (input.has_gop_length())
gop_length = input.gop_length();
- base::Optional<uint8_t> h264_output_level;
+ absl::optional<uint8_t> h264_output_level;
if (input.has_h264_output_level())
h264_output_level = input.h264_output_level();
bool is_constrained_h264 = input.is_constrained_h264();
- base::Optional<media::VideoEncodeAccelerator::Config::StorageType>
+ absl::optional<media::VideoEncodeAccelerator::Config::StorageType>
storage_type;
if (input.has_storage_type()) {
if (!input.ReadStorageType(&storage_type))
@@ -292,6 +292,8 @@ bool StructTraits<media::mojom::VideoEncodeAcceleratorConfigDataView,
input_format, input_visible_size, output_profile, input.initial_bitrate(),
initial_framerate, gop_length, h264_output_level, is_constrained_h264,
storage_type, content_type, spatial_layers);
+
+ output->require_low_delay = input.require_low_delay();
return true;
}
diff --git a/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits.h b/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits.h
index 569b7f912a3..7cc9dc720d0 100644
--- a/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits.h
+++ b/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits.h
@@ -304,6 +304,11 @@ struct StructTraits<media::mojom::VideoEncodeAcceleratorConfigDataView,
return input.spatial_layers;
}
+ static bool require_low_delay(
+ const media::VideoEncodeAccelerator::Config& input) {
+ return input.require_low_delay;
+ }
+
static bool Read(media::mojom::VideoEncodeAcceleratorConfigDataView input,
media::VideoEncodeAccelerator::Config* output);
};
diff --git a/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits_unittest.cc b/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits_unittest.cc
index 15d59d1d76a..57dc0256efb 100644
--- a/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits_unittest.cc
+++ b/chromium/media/mojo/mojom/video_encode_accelerator_mojom_traits_unittest.cc
@@ -67,7 +67,7 @@ TEST(VideoEncodeAcceleratorConfigStructTraitTest, RoundTrip) {
}
::media::VideoEncodeAccelerator::Config input_config(
::media::PIXEL_FORMAT_NV12, kBaseSize, ::media::VP9PROFILE_PROFILE0,
- kBaseBitrateBps, kBaseFramerate, base::nullopt, base::nullopt, false,
+ kBaseBitrateBps, kBaseFramerate, absl::nullopt, absl::nullopt, false,
::media::VideoEncodeAccelerator::Config::StorageType::kGpuMemoryBuffer,
::media::VideoEncodeAccelerator::Config::ContentType::kCamera,
input_spatial_layers);
diff --git a/chromium/media/mojo/mojom/video_frame_metadata_mojom_traits.cc b/chromium/media/mojo/mojom/video_frame_metadata_mojom_traits.cc
index 0e77001b970..95666aaf226 100644
--- a/chromium/media/mojo/mojom/video_frame_metadata_mojom_traits.cc
+++ b/chromium/media/mojo/mojom/video_frame_metadata_mojom_traits.cc
@@ -14,13 +14,13 @@
namespace mojo {
-// Deserializes has_field and field into a base::Optional.
+// Deserializes has_field and field into a absl::optional.
#define DESERIALIZE_INTO_OPT(field) \
if (input.has_##field()) \
output->field = input.field()
#define READ_AND_ASSIGN_OPT(type, field, FieldInCamelCase) \
- base::Optional<type> field; \
+ absl::optional<type> field; \
if (!input.Read##FieldInCamelCase(&field)) \
return false; \
\
diff --git a/chromium/media/mojo/mojom/video_frame_metadata_mojom_traits.h b/chromium/media/mojo/mojom/video_frame_metadata_mojom_traits.h
index 06b7cf3ebc8..c545248edb1 100644
--- a/chromium/media/mojo/mojom/video_frame_metadata_mojom_traits.h
+++ b/chromium/media/mojo/mojom/video_frame_metadata_mojom_traits.h
@@ -6,7 +6,6 @@
#define MEDIA_MOJO_MOJOM_VIDEO_FRAME_METADATA_MOJOM_TRAITS_H_
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "media/base/ipc/media_param_traits_macros.h"
#include "media/base/video_frame_metadata.h"
#include "media/base/video_transformation.h"
@@ -14,11 +13,12 @@
#include "media/mojo/mojom/media_types_enum_mojom_traits.h"
#include "media/mojo/mojom/video_transformation_mojom_traits.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
namespace mojo {
-// Creates a has_foo() and a foo() to serialize a foo base::Optional<>.
+// Creates a has_foo() and a foo() to serialize a foo absl::optional<>.
#define GENERATE_OPT_SERIALIZATION(type, field, default_value) \
static bool has_##field(const media::VideoFrameMetadata& input) { \
return input.field.has_value(); \
@@ -79,7 +79,7 @@ struct StructTraits<media::mojom::VideoFrameMetadataDataView,
copy_mode,
media::VideoFrameMetadata::CopyMode::kCopyToNewTexture)
- static base::Optional<media::VideoTransformation> transformation(
+ static absl::optional<media::VideoTransformation> transformation(
const media::VideoFrameMetadata& input) {
return input.transformation;
}
@@ -92,57 +92,57 @@ struct StructTraits<media::mojom::VideoFrameMetadataDataView,
GENERATE_OPT_SERIALIZATION(double, frame_rate, 0.0)
GENERATE_OPT_SERIALIZATION(double, rtp_timestamp, 0.0)
- static base::Optional<gfx::Rect> capture_update_rect(
+ static absl::optional<gfx::Rect> capture_update_rect(
const media::VideoFrameMetadata& input) {
return input.capture_update_rect;
}
- static base::Optional<base::UnguessableToken> overlay_plane_id(
+ static absl::optional<base::UnguessableToken> overlay_plane_id(
const media::VideoFrameMetadata& input) {
return input.overlay_plane_id;
}
- static base::Optional<base::TimeTicks> receive_time(
+ static absl::optional<base::TimeTicks> receive_time(
const media::VideoFrameMetadata& input) {
return input.receive_time;
}
- static base::Optional<base::TimeTicks> capture_begin_time(
+ static absl::optional<base::TimeTicks> capture_begin_time(
const media::VideoFrameMetadata& input) {
return input.capture_begin_time;
}
- static base::Optional<base::TimeTicks> capture_end_time(
+ static absl::optional<base::TimeTicks> capture_end_time(
const media::VideoFrameMetadata& input) {
return input.capture_end_time;
}
- static base::Optional<base::TimeTicks> decode_begin_time(
+ static absl::optional<base::TimeTicks> decode_begin_time(
const media::VideoFrameMetadata& input) {
return input.decode_begin_time;
}
- static base::Optional<base::TimeTicks> decode_end_time(
+ static absl::optional<base::TimeTicks> decode_end_time(
const media::VideoFrameMetadata& input) {
return input.decode_end_time;
}
- static base::Optional<base::TimeTicks> reference_time(
+ static absl::optional<base::TimeTicks> reference_time(
const media::VideoFrameMetadata& input) {
return input.reference_time;
}
- static base::Optional<base::TimeDelta> processing_time(
+ static absl::optional<base::TimeDelta> processing_time(
const media::VideoFrameMetadata& input) {
return input.processing_time;
}
- static base::Optional<base::TimeDelta> frame_duration(
+ static absl::optional<base::TimeDelta> frame_duration(
const media::VideoFrameMetadata& input) {
return input.frame_duration;
}
- static base::Optional<base::TimeDelta> wallclock_frame_duration(
+ static absl::optional<base::TimeDelta> wallclock_frame_duration(
const media::VideoFrameMetadata& input) {
return input.wallclock_frame_duration;
}
diff --git a/chromium/media/mojo/mojom/video_frame_mojom_traits.cc b/chromium/media/mojo/mojom/video_frame_mojom_traits.cc
index 08ad8fc66ef..268def5e1c8 100644
--- a/chromium/media/mojo/mojom/video_frame_mojom_traits.cc
+++ b/chromium/media/mojo/mojom/video_frame_mojom_traits.cc
@@ -174,7 +174,7 @@ bool StructTraits<media::mojom::VideoFrameDataView,
for (size_t i = 0; i < mailbox_holder.size(); i++)
mailbox_holder_array[i] = mailbox_holder[i];
- base::Optional<gfx::BufferFormat> buffer_format =
+ absl::optional<gfx::BufferFormat> buffer_format =
VideoPixelFormatToGfxBufferFormat(format);
if (!buffer_format)
return false;
@@ -203,7 +203,7 @@ bool StructTraits<media::mojom::VideoFrameDataView,
for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; i++)
mailbox_holder_array[i] = mailbox_holder[i];
- base::Optional<gpu::VulkanYCbCrInfo> ycbcr_info;
+ absl::optional<gpu::VulkanYCbCrInfo> ycbcr_info;
if (!mailbox_data.ReadYcbcrData(&ycbcr_info))
return false;
@@ -231,7 +231,7 @@ bool StructTraits<media::mojom::VideoFrameDataView,
return false;
frame->set_color_space(color_space);
- base::Optional<gfx::HDRMetadata> hdr_metadata;
+ absl::optional<gfx::HDRMetadata> hdr_metadata;
if (!input.ReadHdrMetadata(&hdr_metadata))
return false;
frame->set_hdr_metadata(std::move(hdr_metadata));
diff --git a/chromium/media/mojo/mojom/video_frame_mojom_traits.h b/chromium/media/mojo/mojom/video_frame_mojom_traits.h
index 9071089bd2e..93c515276e5 100644
--- a/chromium/media/mojo/mojom/video_frame_mojom_traits.h
+++ b/chromium/media/mojo/mojom/video_frame_mojom_traits.h
@@ -6,14 +6,13 @@
#define MEDIA_MOJO_MOJOM_VIDEO_FRAME_MOJOM_TRAITS_H_
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
-#include "base/values.h"
#include "gpu/ipc/common/mailbox_holder_mojom_traits.h"
#include "gpu/ipc/common/vulkan_ycbcr_info_mojom_traits.h"
#include "media/base/ipc/media_param_traits_macros.h"
#include "media/base/video_frame.h"
#include "media/mojo/mojom/media_types.mojom.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
#include "ui/gfx/ipc/color/gfx_param_traits.h"
@@ -62,12 +61,12 @@ struct StructTraits<media::mojom::VideoFrameDataView,
return input->ColorSpace();
}
- static const base::Optional<gfx::HDRMetadata>& hdr_metadata(
+ static const absl::optional<gfx::HDRMetadata>& hdr_metadata(
const scoped_refptr<media::VideoFrame>& input) {
return input->hdr_metadata();
}
- static const base::Optional<gpu::VulkanYCbCrInfo>& ycbcr_info(
+ static const absl::optional<gpu::VulkanYCbCrInfo>& ycbcr_info(
const scoped_refptr<media::VideoFrame>& input) {
return input->ycbcr_info();
}
diff --git a/chromium/media/mojo/services/BUILD.gn b/chromium/media/mojo/services/BUILD.gn
index 3a87515b49c..2e80cb73ae4 100644
--- a/chromium/media/mojo/services/BUILD.gn
+++ b/chromium/media/mojo/services/BUILD.gn
@@ -123,16 +123,6 @@ component("services") {
sources += [
"cdm_service.cc",
"cdm_service.h",
- "mojo_cdm_allocator.cc",
- "mojo_cdm_allocator.h",
- "mojo_cdm_file_io.cc",
- "mojo_cdm_file_io.h",
- "mojo_cdm_helper.cc",
- "mojo_cdm_helper.h",
- ]
- deps += [
- "//media/cdm:cdm_api",
- "//media/cdm:cdm_paths",
]
# TODO(xhwang): Ideally media should not worry about sandbox. Find a way to
@@ -142,6 +132,18 @@ component("services") {
}
}
+ if (is_win || enable_library_cdms) {
+ sources += [
+ "mojo_cdm_allocator.cc",
+ "mojo_cdm_allocator.h",
+ "mojo_cdm_file_io.cc",
+ "mojo_cdm_file_io.h",
+ "mojo_cdm_helper.cc",
+ "mojo_cdm_helper.h",
+ ]
+ deps += [ "//media/cdm:cdm_api" ]
+ }
+
if (is_chromeos_ash) {
deps +=
[ "//chromeos/components/cdm_factory_daemon:cdm_factory_daemon_gpu" ]
diff --git a/chromium/media/mojo/services/gpu_mojo_media_client.cc b/chromium/media/mojo/services/gpu_mojo_media_client.cc
index 49eb8786b5f..1a2f25bda04 100644
--- a/chromium/media/mojo/services/gpu_mojo_media_client.cc
+++ b/chromium/media/mojo/services/gpu_mojo_media_client.cc
@@ -238,9 +238,9 @@ std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder(
auto get_stub_cb = base::BindRepeating(
&GetCommandBufferStub, gpu_task_runner_, media_gpu_channel_manager_,
command_buffer_id->channel_token, command_buffer_id->route_id);
- std::unique_ptr<SharedImageVideoProvider> image_provider;
- image_provider = std::make_unique<DirectSharedImageVideoProvider>(
- gpu_task_runner_, get_stub_cb);
+ std::unique_ptr<SharedImageVideoProvider> image_provider =
+ std::make_unique<DirectSharedImageVideoProvider>(gpu_task_runner_,
+ get_stub_cb);
if (base::FeatureList::IsEnabled(kUsePooledSharedImageVideoProvider)) {
// Wrap |image_provider| in a pool.
image_provider = PooledSharedImageVideoProvider::Create(
diff --git a/chromium/media/mojo/services/gpu_mojo_media_client.h b/chromium/media/mojo/services/gpu_mojo_media_client.h
index 667b43a0115..7e70788ba3d 100644
--- a/chromium/media/mojo/services/gpu_mojo_media_client.h
+++ b/chromium/media/mojo/services/gpu_mojo_media_client.h
@@ -10,7 +10,6 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "build/build_config.h"
#include "gpu/config/gpu_driver_bug_workarounds.h"
@@ -20,6 +19,7 @@
#include "media/base/supported_video_decoder_config.h"
#include "media/media_buildflags.h"
#include "media/mojo/services/mojo_media_client.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace gpu {
class GpuMemoryBufferFactory;
@@ -67,10 +67,10 @@ class GpuMojoMediaClient final : public MojoMediaClient {
#if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
// Indirectly owned by GpuChildThread.
gpu::GpuMemoryBufferFactory* const gpu_memory_buffer_factory_;
- base::Optional<SupportedVideoDecoderConfigs> cros_supported_configs_;
+ absl::optional<SupportedVideoDecoderConfigs> cros_supported_configs_;
#endif // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
#if defined(OS_WIN)
- base::Optional<SupportedVideoDecoderConfigs> d3d11_supported_configs_;
+ absl::optional<SupportedVideoDecoderConfigs> d3d11_supported_configs_;
#endif // defined(OS_WIN)
DISALLOW_COPY_AND_ASSIGN(GpuMojoMediaClient);
diff --git a/chromium/media/mojo/services/media_foundation_mojo_media_client.cc b/chromium/media/mojo/services/media_foundation_mojo_media_client.cc
index 27de9b14c14..98162339f0e 100644
--- a/chromium/media/mojo/services/media_foundation_mojo_media_client.cc
+++ b/chromium/media/mojo/services/media_foundation_mojo_media_client.cc
@@ -7,10 +7,13 @@
#include "media/base/win/mf_helpers.h"
#include "media/cdm/win/media_foundation_cdm_factory.h"
#include "media/mojo/services/media_foundation_renderer_wrapper.h"
+#include "media/mojo/services/mojo_cdm_helper.h"
namespace media {
-MediaFoundationMojoMediaClient::MediaFoundationMojoMediaClient() {
+MediaFoundationMojoMediaClient::MediaFoundationMojoMediaClient(
+ const base::FilePath& user_data_dir)
+ : user_data_dir_(user_data_dir) {
DVLOG_FUNC(1);
}
@@ -32,7 +35,8 @@ MediaFoundationMojoMediaClient::CreateMediaFoundationRenderer(
std::unique_ptr<CdmFactory> MediaFoundationMojoMediaClient::CreateCdmFactory(
mojom::FrameInterfaceFactory* frame_interfaces) {
DVLOG_FUNC(1);
- return std::make_unique<MediaFoundationCdmFactory>();
+ return std::make_unique<MediaFoundationCdmFactory>(
+ std::make_unique<MojoCdmHelper>(frame_interfaces), user_data_dir_);
}
} // namespace media
diff --git a/chromium/media/mojo/services/media_foundation_mojo_media_client.h b/chromium/media/mojo/services/media_foundation_mojo_media_client.h
index 45286fb39b1..a4b4b4dba83 100644
--- a/chromium/media/mojo/services/media_foundation_mojo_media_client.h
+++ b/chromium/media/mojo/services/media_foundation_mojo_media_client.h
@@ -5,6 +5,7 @@
#ifndef MEDIA_MOJO_SERVICES_MEDIA_FOUNDATION_MOJO_MEDIA_CLIENT_H_
#define MEDIA_MOJO_SERVICES_MEDIA_FOUNDATION_MOJO_MEDIA_CLIENT_H_
+#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "media/mojo/services/mojo_media_client.h"
@@ -16,7 +17,7 @@ namespace media {
// process hosting MediaFoundationRenderer and MediaFoundationCdm.
class MediaFoundationMojoMediaClient : public MojoMediaClient {
public:
- MediaFoundationMojoMediaClient();
+ explicit MediaFoundationMojoMediaClient(const base::FilePath& user_data_dir);
~MediaFoundationMojoMediaClient() final;
// MojoMediaClient implementation.
@@ -28,6 +29,7 @@ class MediaFoundationMojoMediaClient : public MojoMediaClient {
mojom::FrameInterfaceFactory* frame_interfaces) final;
private:
+ base::FilePath user_data_dir_;
DISALLOW_COPY_AND_ASSIGN(MediaFoundationMojoMediaClient);
};
diff --git a/chromium/media/mojo/services/media_foundation_renderer_wrapper.cc b/chromium/media/mojo/services/media_foundation_renderer_wrapper.cc
index 21953a23dfe..58ec1770da4 100644
--- a/chromium/media/mojo/services/media_foundation_renderer_wrapper.cc
+++ b/chromium/media/mojo/services/media_foundation_renderer_wrapper.cc
@@ -11,13 +11,16 @@
namespace media {
+// TODO(xhwang): Remove `force_dcomp_mode_for_testing=true` after composition is
+// working by default.
MediaFoundationRendererWrapper::MediaFoundationRendererWrapper(
bool web_contents_muted,
scoped_refptr<base::SequencedTaskRunner> task_runner,
mojo::PendingReceiver<RendererExtension> renderer_extension_receiver)
: renderer_(std::make_unique<media::MediaFoundationRenderer>(
web_contents_muted,
- std::move(task_runner))),
+ std::move(task_runner),
+ /*force_dcomp_mode_for_testing=*/true)),
renderer_extension_receiver_(this,
std::move(renderer_extension_receiver)) {
DVLOG_FUNC(1);
@@ -40,7 +43,7 @@ void MediaFoundationRendererWrapper::SetCdm(CdmContext* cdm_context,
}
void MediaFoundationRendererWrapper::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
renderer_->SetLatencyHint(latency_hint);
}
diff --git a/chromium/media/mojo/services/media_foundation_renderer_wrapper.h b/chromium/media/mojo/services/media_foundation_renderer_wrapper.h
index 01f8fa0ea06..88aaefee6e7 100644
--- a/chromium/media/mojo/services/media_foundation_renderer_wrapper.h
+++ b/chromium/media/mojo/services/media_foundation_renderer_wrapper.h
@@ -40,7 +40,7 @@ class MediaFoundationRendererWrapper
media::RendererClient* client,
media::PipelineStatusCallback init_cb) override;
void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void Flush(base::OnceClosure flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
void SetPlaybackRate(double playback_rate) override;
diff --git a/chromium/media/mojo/services/media_foundation_service.cc b/chromium/media/mojo/services/media_foundation_service.cc
index 892cbd96381..4410d231dc9 100644
--- a/chromium/media/mojo/services/media_foundation_service.cc
+++ b/chromium/media/mojo/services/media_foundation_service.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/check.h"
+#include "media/cdm/win/media_foundation_cdm_module.h"
#include "media/media_buildflags.h"
#include "media/mojo/mojom/interface_factory.mojom.h"
#include "media/mojo/services/interface_factory_impl.h"
@@ -15,17 +16,28 @@
namespace media {
MediaFoundationService::MediaFoundationService(
- mojo::PendingReceiver<mojom::MediaFoundationService> receiver)
- : receiver_(this, std::move(receiver)) {
+ mojo::PendingReceiver<mojom::MediaFoundationService> receiver,
+ const base::FilePath& user_data_dir,
+ base::OnceClosure ensure_sandboxed_cb)
+ : receiver_(this, std::move(receiver)),
+ ensure_sandboxed_cb_(std::move(ensure_sandboxed_cb)),
+ mojo_media_client_(user_data_dir) {
mojo_media_client_.Initialize();
}
MediaFoundationService::~MediaFoundationService() = default;
void MediaFoundationService::Initialize(const base::FilePath& cdm_path) {
- // TODO(xhwang): Support loading MediaFoundation CDM and activating
- // IMFContentDecryptionModuleFactory.
- NOTIMPLEMENTED();
+ DVLOG(1) << __func__ << ": cdm_path=" << cdm_path;
+
+ auto* instance = MediaFoundationCdmModule::GetInstance();
+ if (instance->initialized()) {
+ DCHECK_EQ(cdm_path, instance->cdm_path());
+ return;
+ }
+
+ instance->Initialize(cdm_path);
+ std::move(ensure_sandboxed_cb_).Run();
}
void MediaFoundationService::IsKeySystemSupported(
@@ -34,6 +46,7 @@ void MediaFoundationService::IsKeySystemSupported(
// TODO(crbug.com/1115687): Implement MediaFoundation-based key system support
// query.
NOTIMPLEMENTED();
+ std::move(callback).Run(false, nullptr);
}
void MediaFoundationService::CreateInterfaceFactory(
diff --git a/chromium/media/mojo/services/media_foundation_service.h b/chromium/media/mojo/services/media_foundation_service.h
index ad25361a377..0e3745f477b 100644
--- a/chromium/media/mojo/services/media_foundation_service.h
+++ b/chromium/media/mojo/services/media_foundation_service.h
@@ -5,7 +5,8 @@
#ifndef MEDIA_MOJO_SERVICES_MEDIA_FOUNDATION_SERVICE_H_
#define MEDIA_MOJO_SERVICES_MEDIA_FOUNDATION_SERVICE_H_
-#include "build/build_config.h"
+#include "base/callback.h"
+#include "base/files/file_path.h"
#include "media/mojo/mojom/frame_interface_factory.mojom.h"
#include "media/mojo/mojom/interface_factory.mojom.h"
#include "media/mojo/mojom/media_foundation_service.mojom.h"
@@ -23,13 +24,17 @@ namespace media {
class MEDIA_MOJO_EXPORT MediaFoundationService final
: public mojom::MediaFoundationService {
public:
- explicit MediaFoundationService(
- mojo::PendingReceiver<mojom::MediaFoundationService> receiver);
+ // The MediaFoundationService process is NOT sandboxed after startup. The
+ // `ensure_sandboxed_cb` must be called after necessary initialization to
+ // ensure the process is sandboxed.
+ MediaFoundationService(
+ mojo::PendingReceiver<mojom::MediaFoundationService> receiver,
+ const base::FilePath& user_data_dir,
+ base::OnceClosure ensure_sandboxed_cb);
MediaFoundationService(const MediaFoundationService&) = delete;
MediaFoundationService operator=(const MediaFoundationService&) = delete;
~MediaFoundationService() final;
- private:
// mojom::MediaFoundationService implementation:
void Initialize(const base::FilePath& cdm_path) final;
void IsKeySystemSupported(const std::string& key_system,
@@ -38,7 +43,9 @@ class MEDIA_MOJO_EXPORT MediaFoundationService final
mojo::PendingReceiver<mojom::InterfaceFactory> receiver,
mojo::PendingRemote<mojom::FrameInterfaceFactory> frame_interfaces) final;
+ private:
mojo::Receiver<mojom::MediaFoundationService> receiver_;
+ base::OnceClosure ensure_sandboxed_cb_;
MediaFoundationMojoMediaClient mojo_media_client_;
mojo::UniqueReceiverSet<mojom::InterfaceFactory> interface_factory_receivers_;
};
diff --git a/chromium/media/mojo/services/media_metrics_provider.h b/chromium/media/mojo/services/media_metrics_provider.h
index e10715732bd..8c7d8d4583a 100644
--- a/chromium/media/mojo/services/media_metrics_provider.h
+++ b/chromium/media/mojo/services/media_metrics_provider.h
@@ -160,7 +160,7 @@ class MEDIA_MOJO_EXPORT MediaMetricsProvider
base::TimeDelta time_to_first_frame_ = kNoTimestamp;
base::TimeDelta time_to_play_ready_ = kNoTimestamp;
- base::Optional<container_names::MediaContainerName> container_name_;
+ absl::optional<container_names::MediaContainerName> container_name_;
DISALLOW_COPY_AND_ASSIGN(MediaMetricsProvider);
};
diff --git a/chromium/media/mojo/services/media_mojo_export.h b/chromium/media/mojo/services/media_mojo_export.h
index 1eba90a358c..a0ddd1d9127 100644
--- a/chromium/media/mojo/services/media_mojo_export.h
+++ b/chromium/media/mojo/services/media_mojo_export.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_MOJO_COMMON_MEDIA_MOJO_EXPORT_H_
-#define MEDIA_MOJO_COMMON_MEDIA_MOJO_EXPORT_H_
+#ifndef MEDIA_MOJO_SERVICES_MEDIA_MOJO_EXPORT_H_
+#define MEDIA_MOJO_SERVICES_MEDIA_MOJO_EXPORT_H_
// Define MEDIA_MOJO_EXPORT so that functionality implemented by the
// media/mojo module can be exported to consumers.
@@ -29,4 +29,4 @@
#define MEDIA_MOJO_EXPORT
#endif
-#endif // MEDIA_MOJO_COMMON_MEDIA_MOJO_EXPORT_H_
+#endif // MEDIA_MOJO_SERVICES_MEDIA_MOJO_EXPORT_H_
diff --git a/chromium/media/mojo/services/mojo_audio_decoder_service.cc b/chromium/media/mojo/services/mojo_audio_decoder_service.cc
index 90f071bb723..c4c25b4c908 100644
--- a/chromium/media/mojo/services/mojo_audio_decoder_service.cc
+++ b/chromium/media/mojo/services/mojo_audio_decoder_service.cc
@@ -36,7 +36,7 @@ void MojoAudioDecoderService::Construct(
void MojoAudioDecoderService::Initialize(
const AudioDecoderConfig& config,
- const base::Optional<base::UnguessableToken>& cdm_id,
+ const absl::optional<base::UnguessableToken>& cdm_id,
InitializeCallback callback) {
DVLOG(1) << __func__ << " " << config.AsHumanReadableString();
diff --git a/chromium/media/mojo/services/mojo_audio_decoder_service.h b/chromium/media/mojo/services/mojo_audio_decoder_service.h
index 3b0b340196a..8fd5a0583df 100644
--- a/chromium/media/mojo/services/mojo_audio_decoder_service.h
+++ b/chromium/media/mojo/services/mojo_audio_decoder_service.h
@@ -36,7 +36,7 @@ class MEDIA_MOJO_EXPORT MojoAudioDecoderService final
void Construct(
mojo::PendingAssociatedRemote<mojom::AudioDecoderClient> client) final;
void Initialize(const AudioDecoderConfig& config,
- const base::Optional<base::UnguessableToken>& cdm_id,
+ const absl::optional<base::UnguessableToken>& cdm_id,
InitializeCallback callback) final;
void SetDataSource(mojo::ScopedDataPipeConsumerHandle receive_pipe) final;
@@ -78,7 +78,7 @@ class MEDIA_MOJO_EXPORT MojoAudioDecoderService final
// The CDM ID and the corresponding CdmContextRef, which must be held to keep
// the CdmContext alive for the lifetime of the |decoder_|.
- base::Optional<base::UnguessableToken> cdm_id_;
+ absl::optional<base::UnguessableToken> cdm_id_;
std::unique_ptr<CdmContextRef> cdm_context_ref_;
// The AudioDecoder that does actual decoding work.
diff --git a/chromium/media/mojo/services/mojo_audio_input_stream.cc b/chromium/media/mojo/services/mojo_audio_input_stream.cc
index 246d3b2e639..d0a43d63ad6 100644
--- a/chromium/media/mojo/services/mojo_audio_input_stream.cc
+++ b/chromium/media/mojo/services/mojo_audio_input_stream.cc
@@ -101,7 +101,7 @@ void MojoAudioInputStream::OnMuted(int stream_id, bool is_muted) {
void MojoAudioInputStream::OnStreamError(int stream_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- client_->OnError();
+ client_->OnError(mojom::InputStreamErrorCode::kUnknown);
OnError();
}
diff --git a/chromium/media/mojo/services/mojo_audio_input_stream_unittest.cc b/chromium/media/mojo/services/mojo_audio_input_stream_unittest.cc
index 45f13d98dd4..dda1bd435cd 100644
--- a/chromium/media/mojo/services/mojo_audio_input_stream_unittest.cc
+++ b/chromium/media/mojo/services/mojo_audio_input_stream_unittest.cc
@@ -118,7 +118,7 @@ class MockClient : public mojom::AudioInputStreamClient {
MOCK_METHOD1(OnMutedStateChanged, void(bool));
- MOCK_METHOD0(OnError, void());
+ MOCK_METHOD1(OnError, void(mojom::InputStreamErrorCode));
private:
base::ReadOnlySharedMemoryRegion region_;
@@ -190,7 +190,7 @@ class MojoAudioInputStreamTest : public Test {
TEST_F(MojoAudioInputStreamTest, NoDelegate_SignalsError) {
bool deleter_called = false;
- EXPECT_CALL(client_, OnError());
+ EXPECT_CALL(client_, OnError(mojom::InputStreamErrorCode::kUnknown));
mojo::Remote<mojom::AudioInputStream> stream_remote;
MojoAudioInputStream stream(
stream_remote.BindNewPipeAndPassReceiver(),
@@ -252,7 +252,7 @@ TEST_F(MojoAudioInputStreamTest, Created_NotifiesClient) {
TEST_F(MojoAudioInputStreamTest, SetVolumeTooLarge_Error) {
auto audio_input = CreateAudioInput();
EXPECT_CALL(deleter_, Finished());
- EXPECT_CALL(client_, OnError());
+ EXPECT_CALL(client_, OnError(mojom::InputStreamErrorCode::kUnknown));
audio_input->SetVolume(15);
base::RunLoop().RunUntilIdle();
@@ -262,7 +262,7 @@ TEST_F(MojoAudioInputStreamTest, SetVolumeTooLarge_Error) {
TEST_F(MojoAudioInputStreamTest, SetVolumeNegative_Error) {
auto audio_input = CreateAudioInput();
EXPECT_CALL(deleter_, Finished());
- EXPECT_CALL(client_, OnError());
+ EXPECT_CALL(client_, OnError(mojom::InputStreamErrorCode::kUnknown));
audio_input->SetVolume(-0.5);
base::RunLoop().RunUntilIdle();
@@ -272,7 +272,7 @@ TEST_F(MojoAudioInputStreamTest, SetVolumeNegative_Error) {
TEST_F(MojoAudioInputStreamTest, DelegateErrorBeforeCreated_PropagatesError) {
auto audio_input = CreateAudioInput();
EXPECT_CALL(deleter_, Finished());
- EXPECT_CALL(client_, OnError());
+ EXPECT_CALL(client_, OnError(mojom::InputStreamErrorCode::kUnknown));
ASSERT_NE(nullptr, delegate_event_handler_);
delegate_event_handler_->OnStreamError(kStreamId);
@@ -285,7 +285,7 @@ TEST_F(MojoAudioInputStreamTest, DelegateErrorAfterCreated_PropagatesError) {
auto audio_input = CreateAudioInput();
EXPECT_CALL(client_, GotNotification(kInitiallyNotMuted));
EXPECT_CALL(deleter_, Finished());
- EXPECT_CALL(client_, OnError());
+ EXPECT_CALL(client_, OnError(mojom::InputStreamErrorCode::kUnknown));
base::RunLoop().RunUntilIdle();
ASSERT_NE(nullptr, delegate_event_handler_);
diff --git a/chromium/media/mojo/services/mojo_audio_output_stream_provider.h b/chromium/media/mojo/services/mojo_audio_output_stream_provider.h
index 52c23ee60ee..8d632351d55 100644
--- a/chromium/media/mojo/services/mojo_audio_output_stream_provider.h
+++ b/chromium/media/mojo/services/mojo_audio_output_stream_provider.h
@@ -62,7 +62,7 @@ class MEDIA_MOJO_EXPORT MojoAudioOutputStreamProvider
DeleterCallback deleter_callback_;
std::unique_ptr<mojom::AudioOutputStreamObserver> observer_;
mojo::Receiver<mojom::AudioOutputStreamObserver> observer_receiver_;
- base::Optional<MojoAudioOutputStream> audio_output_;
+ absl::optional<MojoAudioOutputStream> audio_output_;
mojo::Remote<mojom::AudioOutputStreamProviderClient> provider_client_;
DISALLOW_COPY_AND_ASSIGN(MojoAudioOutputStreamProvider);
diff --git a/chromium/media/mojo/services/mojo_cdm_promise.cc b/chromium/media/mojo/services/mojo_cdm_promise.cc
index 5bd1295a42f..3641388b5ce 100644
--- a/chromium/media/mojo/services/mojo_cdm_promise.cc
+++ b/chromium/media/mojo/services/mojo_cdm_promise.cc
@@ -12,6 +12,7 @@
#include "base/check.h"
#include "media/base/content_decryption_module.h"
#include "media/base/decryptor.h"
+#include "media/mojo/mojom/content_decryption_module.mojom.h"
namespace media {
diff --git a/chromium/media/mojo/services/mojo_cdm_promise.h b/chromium/media/mojo/services/mojo_cdm_promise.h
index b6c0988eb97..d5db3d8a604 100644
--- a/chromium/media/mojo/services/mojo_cdm_promise.h
+++ b/chromium/media/mojo/services/mojo_cdm_promise.h
@@ -10,7 +10,6 @@
#include "base/callback.h"
#include "base/macros.h"
#include "media/base/cdm_promise.h"
-#include "media/mojo/mojom/content_decryption_module.mojom.h"
namespace media {
diff --git a/chromium/media/mojo/services/mojo_cdm_service.h b/chromium/media/mojo/services/mojo_cdm_service.h
index 18195fb1c73..53d736d9999 100644
--- a/chromium/media/mojo/services/mojo_cdm_service.h
+++ b/chromium/media/mojo/services/mojo_cdm_service.h
@@ -112,7 +112,7 @@ class MEDIA_MOJO_EXPORT MojoCdmService final
std::unique_ptr<mojo::Receiver<mojom::Decryptor>> decryptor_receiver_;
// Set to a valid CDM ID if the |cdm_| is successfully created.
- base::Optional<base::UnguessableToken> cdm_id_;
+ absl::optional<base::UnguessableToken> cdm_id_;
mojo::AssociatedRemote<mojom::ContentDecryptionModuleClient> client_;
diff --git a/chromium/media/mojo/services/mojo_demuxer_stream_adapter.cc b/chromium/media/mojo/services/mojo_demuxer_stream_adapter.cc
index d9f40c7eefc..c248002d029 100644
--- a/chromium/media/mojo/services/mojo_demuxer_stream_adapter.cc
+++ b/chromium/media/mojo/services/mojo_demuxer_stream_adapter.cc
@@ -70,8 +70,8 @@ bool MojoDemuxerStreamAdapter::SupportsConfigChanges() {
void MojoDemuxerStreamAdapter::OnStreamReady(
Type type,
mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const base::Optional<AudioDecoderConfig>& audio_config,
- const base::Optional<VideoDecoderConfig>& video_config) {
+ const absl::optional<AudioDecoderConfig>& audio_config,
+ const absl::optional<VideoDecoderConfig>& video_config) {
DVLOG(1) << __func__;
DCHECK_EQ(UNKNOWN, type_);
DCHECK(consumer_handle.is_valid());
@@ -89,8 +89,8 @@ void MojoDemuxerStreamAdapter::OnStreamReady(
void MojoDemuxerStreamAdapter::OnBufferReady(
Status status,
mojom::DecoderBufferPtr buffer,
- const base::Optional<AudioDecoderConfig>& audio_config,
- const base::Optional<VideoDecoderConfig>& video_config) {
+ const absl::optional<AudioDecoderConfig>& audio_config,
+ const absl::optional<VideoDecoderConfig>& video_config) {
DVLOG(3) << __func__;
DCHECK(read_cb_);
DCHECK_NE(type_, UNKNOWN);
@@ -123,8 +123,8 @@ void MojoDemuxerStreamAdapter::OnBufferRead(
}
void MojoDemuxerStreamAdapter::UpdateConfig(
- const base::Optional<AudioDecoderConfig>& audio_config,
- const base::Optional<VideoDecoderConfig>& video_config) {
+ const absl::optional<AudioDecoderConfig>& audio_config,
+ const absl::optional<VideoDecoderConfig>& video_config) {
DCHECK_NE(type_, UNKNOWN);
switch(type_) {
diff --git a/chromium/media/mojo/services/mojo_demuxer_stream_adapter.h b/chromium/media/mojo/services/mojo_demuxer_stream_adapter.h
index 1cb22c8ea3f..4d5b55fc3d4 100644
--- a/chromium/media/mojo/services/mojo_demuxer_stream_adapter.h
+++ b/chromium/media/mojo/services/mojo_demuxer_stream_adapter.h
@@ -9,13 +9,13 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/demuxer_stream.h"
#include "media/base/video_decoder_config.h"
#include "media/mojo/mojom/demuxer_stream.mojom.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -49,20 +49,20 @@ class MojoDemuxerStreamAdapter : public DemuxerStream {
private:
void OnStreamReady(Type type,
mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const base::Optional<AudioDecoderConfig>& audio_config,
- const base::Optional<VideoDecoderConfig>& video_config);
+ const absl::optional<AudioDecoderConfig>& audio_config,
+ const absl::optional<VideoDecoderConfig>& video_config);
// The callback from |demuxer_stream_| that a read operation has completed.
// |read_cb| is a callback from the client who invoked Read() on |this|.
void OnBufferReady(Status status,
mojom::DecoderBufferPtr buffer,
- const base::Optional<AudioDecoderConfig>& audio_config,
- const base::Optional<VideoDecoderConfig>& video_config);
+ const absl::optional<AudioDecoderConfig>& audio_config,
+ const absl::optional<VideoDecoderConfig>& video_config);
void OnBufferRead(scoped_refptr<DecoderBuffer> buffer);
- void UpdateConfig(const base::Optional<AudioDecoderConfig>& audio_config,
- const base::Optional<VideoDecoderConfig>& video_config);
+ void UpdateConfig(const absl::optional<AudioDecoderConfig>& audio_config,
+ const absl::optional<VideoDecoderConfig>& video_config);
// See constructor for descriptions.
mojo::Remote<mojom::DemuxerStream> demuxer_stream_;
diff --git a/chromium/media/mojo/services/mojo_media_client.h b/chromium/media/mojo/services/mojo_media_client.h
index cba23037f32..1f63e9f357f 100644
--- a/chromium/media/mojo/services/mojo_media_client.h
+++ b/chromium/media/mojo/services/mojo_media_client.h
@@ -9,7 +9,6 @@
#include <string>
#include <vector>
-#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/unguessable_token.h"
#include "media/base/overlay_info.h"
diff --git a/chromium/media/mojo/services/mojo_media_drm_storage.cc b/chromium/media/mojo/services/mojo_media_drm_storage.cc
index 113535f14ff..49f0405e08a 100644
--- a/chromium/media/mojo/services/mojo_media_drm_storage.cc
+++ b/chromium/media/mojo/services/mojo_media_drm_storage.cc
@@ -9,10 +9,10 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
-#include "base/optional.h"
#include "base/unguessable_token.h"
#include "media/mojo/mojom/media_drm_storage.mojom.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -30,7 +30,7 @@ MojoMediaDrmStorage::~MojoMediaDrmStorage() {}
void MojoMediaDrmStorage::Initialize(InitCB init_cb) {
DVLOG(1) << __func__;
media_drm_storage_->Initialize(mojo::WrapCallbackWithDefaultInvokeIfNotRun(
- std::move(init_cb), false, base::nullopt));
+ std::move(init_cb), false, absl::nullopt));
}
void MojoMediaDrmStorage::OnProvisioned(ResultCB result_cb) {
diff --git a/chromium/media/mojo/services/mojo_renderer_service.cc b/chromium/media/mojo/services/mojo_renderer_service.cc
index 5fbf6cf0e4c..31967288a8b 100644
--- a/chromium/media/mojo/services/mojo_renderer_service.cc
+++ b/chromium/media/mojo/services/mojo_renderer_service.cc
@@ -9,13 +9,13 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
-#include "base/optional.h"
#include "media/base/cdm_context.h"
#include "media/base/media_url_demuxer.h"
#include "media/base/renderer.h"
#include "media/mojo/common/media_type_converters.h"
#include "media/mojo/services/media_resource_shim.h"
#include "media/mojo/services/mojo_cdm_service_context.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -54,7 +54,7 @@ MojoRendererService::~MojoRendererService() = default;
void MojoRendererService::Initialize(
mojo::PendingAssociatedRemote<mojom::RendererClient> client,
- base::Optional<std::vector<mojo::PendingRemote<mojom::DemuxerStream>>>
+ absl::optional<std::vector<mojo::PendingRemote<mojom::DemuxerStream>>>
streams,
mojom::MediaUrlParamsPtr media_url_params,
InitializeCallback callback) {
@@ -112,7 +112,7 @@ void MojoRendererService::SetVolume(float volume) {
}
void MojoRendererService::SetCdm(
- const base::Optional<base::UnguessableToken>& cdm_id,
+ const absl::optional<base::UnguessableToken>& cdm_id,
SetCdmCallback callback) {
if (cdm_context_ref_) {
DVLOG(1) << "Switching CDM not supported";
@@ -204,7 +204,7 @@ void MojoRendererService::OnVideoOpacityChange(bool opaque) {
client_->OnVideoOpacityChange(opaque);
}
-void MojoRendererService::OnVideoFrameRateChange(base::Optional<int> fps) {
+void MojoRendererService::OnVideoFrameRateChange(absl::optional<int> fps) {
DVLOG(2) << __func__ << "(" << (fps ? *fps : -1) << ")";
// TODO(liberato): plumb to |client_|.
}
diff --git a/chromium/media/mojo/services/mojo_renderer_service.h b/chromium/media/mojo/services/mojo_renderer_service.h
index 08953954f11..0c7c7d6b8c0 100644
--- a/chromium/media/mojo/services/mojo_renderer_service.h
+++ b/chromium/media/mojo/services/mojo_renderer_service.h
@@ -56,7 +56,7 @@ class MEDIA_MOJO_EXPORT MojoRendererService final : public mojom::Renderer,
// mojom::Renderer implementation.
void Initialize(
mojo::PendingAssociatedRemote<mojom::RendererClient> client,
- base::Optional<std::vector<mojo::PendingRemote<mojom::DemuxerStream>>>
+ absl::optional<std::vector<mojo::PendingRemote<mojom::DemuxerStream>>>
streams,
mojom::MediaUrlParamsPtr media_url_params,
InitializeCallback callback) final;
@@ -64,7 +64,7 @@ class MEDIA_MOJO_EXPORT MojoRendererService final : public mojom::Renderer,
void StartPlayingFrom(base::TimeDelta time_delta) final;
void SetPlaybackRate(double playback_rate) final;
void SetVolume(float volume) final;
- void SetCdm(const base::Optional<base::UnguessableToken>& cdm_id,
+ void SetCdm(const absl::optional<base::UnguessableToken>& cdm_id,
SetCdmCallback callback) final;
private:
@@ -87,7 +87,7 @@ class MEDIA_MOJO_EXPORT MojoRendererService final : public mojom::Renderer,
void OnVideoConfigChange(const VideoDecoderConfig& config) final;
void OnVideoNaturalSizeChange(const gfx::Size& size) final;
void OnVideoOpacityChange(bool opaque) final;
- void OnVideoFrameRateChange(base::Optional<int> fps) final;
+ void OnVideoFrameRateChange(absl::optional<int> fps) final;
// Called when the MediaResourceShim is ready to go (has a config,
// pipe handle, etc) and can be handed off to a renderer for use.
diff --git a/chromium/media/mojo/services/mojo_video_decoder_service.cc b/chromium/media/mojo/services/mojo_video_decoder_service.cc
index 19e7d34f60a..80bc77c3e47 100644
--- a/chromium/media/mojo/services/mojo_video_decoder_service.cc
+++ b/chromium/media/mojo/services/mojo_video_decoder_service.cc
@@ -13,7 +13,6 @@
#include "base/macros.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/optional.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/elapsed_timer.h"
@@ -31,6 +30,7 @@
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/system/buffer.h"
#include "mojo/public/cpp/system/handle.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -195,7 +195,7 @@ void MojoVideoDecoderService::Construct(
void MojoVideoDecoderService::Initialize(
const VideoDecoderConfig& config,
bool low_delay,
- const base::Optional<base::UnguessableToken>& cdm_id,
+ const absl::optional<base::UnguessableToken>& cdm_id,
InitializeCallback callback) {
DVLOG(1) << __func__ << " config = " << config.AsHumanReadableString()
<< ", cdm_id = "
@@ -382,7 +382,7 @@ void MojoVideoDecoderService::OnDecoderOutput(scoped_refptr<VideoFrame> frame) {
// you can remove this DCHECK.
DCHECK(frame->metadata().power_efficient);
- base::Optional<base::UnguessableToken> release_token;
+ absl::optional<base::UnguessableToken> release_token;
if (frame->HasReleaseMailboxCB() && video_frame_handle_releaser_) {
// |video_frame_handle_releaser_| is explicitly constructed with a
// VideoFrameHandleReleaserImpl in Construct().
diff --git a/chromium/media/mojo/services/mojo_video_decoder_service.h b/chromium/media/mojo/services/mojo_video_decoder_service.h
index d04d177d3bf..06ec7e5a6e3 100644
--- a/chromium/media/mojo/services/mojo_video_decoder_service.h
+++ b/chromium/media/mojo/services/mojo_video_decoder_service.h
@@ -55,7 +55,7 @@ class MEDIA_MOJO_EXPORT MojoVideoDecoderService final
const gfx::ColorSpace& target_color_space) final;
void Initialize(const VideoDecoderConfig& config,
bool low_delay,
- const base::Optional<base::UnguessableToken>& cdm_id,
+ const absl::optional<base::UnguessableToken>& cdm_id,
InitializeCallback callback) final;
void Decode(mojom::DecoderBufferPtr buffer, DecodeCallback callback) final;
void Reset(ResetCallback callback) final;
@@ -87,7 +87,7 @@ class MEDIA_MOJO_EXPORT MojoVideoDecoderService final
ProvideOverlayInfoCB provide_overlay_info_cb);
// Implementation value provided at the time of Construct().
- base::Optional<VideoDecoderImplementation> implementation_;
+ absl::optional<VideoDecoderImplementation> implementation_;
// Whether this instance is active (Decode() was called at least once).
bool is_active_instance_ = false;
@@ -114,7 +114,7 @@ class MEDIA_MOJO_EXPORT MojoVideoDecoderService final
// The CDM ID and the corresponding CdmContextRef, which must be held to keep
// the CdmContext alive for the lifetime of the |decoder_|.
- base::Optional<base::UnguessableToken> cdm_id_;
+ absl::optional<base::UnguessableToken> cdm_id_;
std::unique_ptr<CdmContextRef> cdm_context_ref_;
std::unique_ptr<media::VideoDecoder> decoder_;
diff --git a/chromium/media/mojo/services/playback_events_recorder.h b/chromium/media/mojo/services/playback_events_recorder.h
index 39f248e03f7..df7de722016 100644
--- a/chromium/media/mojo/services/playback_events_recorder.h
+++ b/chromium/media/mojo/services/playback_events_recorder.h
@@ -50,7 +50,7 @@ class MEDIA_MOJO_EXPORT PlaybackEventsRecorder final
size_t audio_bytes_ = 0;
size_t video_bytes_ = 0;
- base::Optional<PipelineStatistics> last_stats_;
+ absl::optional<PipelineStatistics> last_stats_;
base::TimeTicks last_stats_time_;
};
diff --git a/chromium/media/mojo/services/video_decode_perf_history_unittest.cc b/chromium/media/mojo/services/video_decode_perf_history_unittest.cc
index e6eeddb2364..7d2bfc29ee6 100644
--- a/chromium/media/mojo/services/video_decode_perf_history_unittest.cc
+++ b/chromium/media/mojo/services/video_decode_perf_history_unittest.cc
@@ -10,7 +10,6 @@
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
diff --git a/chromium/media/mojo/services/video_decode_stats_recorder.h b/chromium/media/mojo/services/video_decode_stats_recorder.h
index 72bbd0a7b5c..f4901789b84 100644
--- a/chromium/media/mojo/services/video_decode_stats_recorder.h
+++ b/chromium/media/mojo/services/video_decode_stats_recorder.h
@@ -6,9 +6,7 @@
#define MEDIA_MOJO_SERVICES_VIDEO_DECODE_STATS_RECORDER_H_
#include <stdint.h>
-#include <string>
-#include "base/time/time.h"
#include "media/base/video_codecs.h"
#include "media/learning/common/value.h"
#include "media/mojo/mojom/media_types.mojom.h"
diff --git a/chromium/media/mojo/services/watch_time_recorder.cc b/chromium/media/mojo/services/watch_time_recorder.cc
index 6cb630ed5d0..414751e8aa3 100644
--- a/chromium/media/mojo/services/watch_time_recorder.cc
+++ b/chromium/media/mojo/services/watch_time_recorder.cc
@@ -31,7 +31,7 @@ static void RecordWatchTimeInternal(
base::TimeDelta value,
base::TimeDelta minimum = kMinimumElapsedWatchTime) {
DCHECK(!key.empty());
- base::UmaHistogramCustomTimes(key.as_string(), value, minimum,
+ base::UmaHistogramCustomTimes(std::string(key), value, minimum,
base::TimeDelta::FromHours(10), 50);
}
@@ -47,13 +47,13 @@ static void RecordMeanTimeBetweenRebuffers(base::StringPiece key,
static void RecordDiscardedWatchTime(base::StringPiece key,
base::TimeDelta value) {
DCHECK(!key.empty());
- base::UmaHistogramCustomTimes(key.as_string(), value, base::TimeDelta(),
+ base::UmaHistogramCustomTimes(std::string(key), value, base::TimeDelta(),
kMinimumElapsedWatchTime, 50);
}
static void RecordRebuffersCount(base::StringPiece key, int underflow_count) {
DCHECK(!key.empty());
- base::UmaHistogramCounts100(key.as_string(), underflow_count);
+ base::UmaHistogramCounts100(std::string(key), underflow_count);
}
WatchTimeRecorder::WatchTimeUkmRecord::WatchTimeUkmRecord(
@@ -328,7 +328,7 @@ void WatchTimeRecorder::RecordUkmPlaybackData() {
return;
// Round duration to the most significant digit in milliseconds for privacy.
- base::Optional<uint64_t> clamped_duration_ms;
+ absl::optional<uint64_t> clamped_duration_ms;
if (duration_ != kNoTimestamp && duration_ != kInfiniteDuration) {
clamped_duration_ms = duration_.InMilliseconds();
if (duration_ > base::TimeDelta::FromSeconds(1)) {
diff --git a/chromium/media/mojo/services/watch_time_recorder.h b/chromium/media/mojo/services/watch_time_recorder.h
index 3b373f3b19a..77e768fe570 100644
--- a/chromium/media/mojo/services/watch_time_recorder.h
+++ b/chromium/media/mojo/services/watch_time_recorder.h
@@ -126,7 +126,7 @@ class MEDIA_MOJO_EXPORT WatchTimeRecorder : public mojom::WatchTimeRecorder {
PipelineStatus pipeline_status_ = PIPELINE_OK;
base::TimeDelta duration_ = kNoTimestamp;
base::TimeDelta last_timestamp_ = kNoTimestamp;
- base::Optional<bool> autoplay_initiated_;
+ absl::optional<bool> autoplay_initiated_;
RecordAggregateWatchTimeCallback record_playback_cb_;
DISALLOW_COPY_AND_ASSIGN(WatchTimeRecorder);
diff --git a/chromium/media/mojo/services/watch_time_recorder_unittest.cc b/chromium/media/mojo/services/watch_time_recorder_unittest.cc
index 08467f09fef..126f57436f1 100644
--- a/chromium/media/mojo/services/watch_time_recorder_unittest.cc
+++ b/chromium/media/mojo/services/watch_time_recorder_unittest.cc
@@ -14,6 +14,7 @@
#include "base/hash/hash.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "base/test/test_message_loop.h"
@@ -110,10 +111,10 @@ class WatchTimeRecorderTest : public testing::Test {
continue;
auto it = std::find(keys.begin(), keys.end(), test_key);
if (it == keys.end()) {
- histogram_tester_->ExpectTotalCount(test_key.as_string(), 0);
+ histogram_tester_->ExpectTotalCount(test_key, 0);
} else {
- histogram_tester_->ExpectUniqueSample(test_key.as_string(),
- value.InMilliseconds(), 1);
+ histogram_tester_->ExpectUniqueSample(test_key, value.InMilliseconds(),
+ 1);
}
}
}
@@ -124,9 +125,9 @@ class WatchTimeRecorderTest : public testing::Test {
for (auto key : full_key_list) {
auto it = std::find(keys.begin(), keys.end(), key);
if (it == keys.end())
- histogram_tester_->ExpectTotalCount(key.as_string(), 0);
+ histogram_tester_->ExpectTotalCount(key, 0);
else
- histogram_tester_->ExpectUniqueSample(key.as_string(), value, 1);
+ histogram_tester_->ExpectUniqueSample(key, value, 1);
}
}
@@ -225,7 +226,7 @@ TEST_F(WatchTimeRecorderTest, TestBasicReporting) {
auto key_str = ConvertWatchTimeKeyToStringForUma(key);
SCOPED_TRACE(key_str.empty() ? base::NumberToString(i)
- : key_str.as_string());
+ : std::string(key_str));
// Values for |is_background| and |is_muted| don't matter in this test since
// they don't prevent the muted or background keys from being recorded.
@@ -376,7 +377,7 @@ TEST_F(WatchTimeRecorderTest, TestBasicReportingMediaStream) {
auto key_str = ConvertWatchTimeKeyToStringForUma(key);
SCOPED_TRACE(key_str.empty() ? base::NumberToString(i)
- : key_str.as_string());
+ : std::string(key_str));
// Values for |is_background| and |is_muted| don't matter in this test since
// they don't prevent the muted or background keys from being recorded.
@@ -558,7 +559,7 @@ TEST_F(WatchTimeRecorderTest, TestRebufferingMetrics) {
// Nothing should be logged since this doesn't meet requirements.
ExpectMtbrTime({}, base::TimeDelta());
for (auto key : smooth_keys_)
- histogram_tester_->ExpectTotalCount(key.as_string(), 0);
+ histogram_tester_->ExpectTotalCount(key, 0);
}
TEST_F(WatchTimeRecorderTest, TestRebufferingMetricsMediaStream) {
@@ -607,8 +608,7 @@ TEST_F(WatchTimeRecorderTest, TestDiscardMetrics) {
// Verify the time was instead logged to the discard keys.
for (auto key : discard_keys_) {
- histogram_tester_->ExpectUniqueSample(key.as_string(),
- kWatchTime.InMilliseconds(), 1);
+ histogram_tester_->ExpectUniqueSample(key, kWatchTime.InMilliseconds(), 1);
}
// UKM watch time won't be logged because we aren't sending "All" keys.
@@ -631,7 +631,7 @@ TEST_F(WatchTimeRecorderTest, TestDiscardMetricsMediaStream) {
// No watch time and no discard metrics should be logged.
ExpectWatchTime({}, base::TimeDelta());
for (auto key : discard_keys_) {
- histogram_tester_->ExpectTotalCount(key.as_string(), 0);
+ histogram_tester_->ExpectTotalCount(key, 0);
}
// UKM watch time won't be logged because we aren't sending "All" keys.
diff --git a/chromium/media/muxers/DIR_METADATA b/chromium/media/muxers/DIR_METADATA
index af1480ef95e..25b8514c4b7 100644
--- a/chromium/media/muxers/DIR_METADATA
+++ b/chromium/media/muxers/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Blink>MediaRecording"
diff --git a/chromium/media/muxers/webm_muxer.cc b/chromium/media/muxers/webm_muxer.cc
index 7c9091b6449..bca545a5de9 100644
--- a/chromium/media/muxers/webm_muxer.cc
+++ b/chromium/media/muxers/webm_muxer.cc
@@ -110,7 +110,7 @@ static const char* MkvCodeIcForMediaVideoCodecId(VideoCodec video_codec) {
}
}
-base::Optional<mkvmuxer::Colour> ColorFromColorSpace(
+absl::optional<mkvmuxer::Colour> ColorFromColorSpace(
const gfx::ColorSpace& color) {
using mkvmuxer::Colour;
using MatrixID = gfx::ColorSpace::MatrixID;
@@ -127,7 +127,7 @@ base::Optional<mkvmuxer::Colour> ColorFromColorSpace(
matrix_coefficients = Colour::kBt2020NonConstantLuminance;
break;
default:
- return base::nullopt;
+ return absl::nullopt;
}
colour.set_matrix_coefficients(matrix_coefficients);
int range;
@@ -139,7 +139,7 @@ base::Optional<mkvmuxer::Colour> ColorFromColorSpace(
range = Colour::kFullRange;
break;
default:
- return base::nullopt;
+ return absl::nullopt;
}
colour.set_range(range);
int transfer_characteristics;
@@ -154,7 +154,7 @@ base::Optional<mkvmuxer::Colour> ColorFromColorSpace(
transfer_characteristics = Colour::kSmpteSt2084;
break;
default:
- return base::nullopt;
+ return absl::nullopt;
}
colour.set_transfer_characteristics(transfer_characteristics);
int primaries;
@@ -166,7 +166,7 @@ base::Optional<mkvmuxer::Colour> ColorFromColorSpace(
primaries = Colour::kIturBt2020;
break;
default:
- return base::nullopt;
+ return absl::nullopt;
}
colour.set_primaries(primaries);
return colour;
@@ -185,7 +185,7 @@ WebmMuxer::VideoParameters::VideoParameters(
gfx::Size visible_rect_size,
double frame_rate,
VideoCodec codec,
- base::Optional<gfx::ColorSpace> color_space)
+ absl::optional<gfx::ColorSpace> color_space)
: visible_rect_size(visible_rect_size),
frame_rate(frame_rate),
codec(codec),
@@ -349,7 +349,7 @@ bool WebmMuxer::Flush() {
void WebmMuxer::AddVideoTrack(
const gfx::Size& frame_size,
double frame_rate,
- const base::Optional<gfx::ColorSpace>& color_space) {
+ const absl::optional<gfx::ColorSpace>& color_space) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(0u, video_track_index_)
<< "WebmMuxer can only be initialized once.";
diff --git a/chromium/media/muxers/webm_muxer.h b/chromium/media/muxers/webm_muxer.h
index 63b6dc87194..7121c83d753 100644
--- a/chromium/media/muxers/webm_muxer.h
+++ b/chromium/media/muxers/webm_muxer.h
@@ -21,6 +21,7 @@
#include "media/base/media_export.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/libwebm/source/mkvmuxer.hpp"
#include "ui/gfx/geometry/size.h"
@@ -57,13 +58,13 @@ class MEDIA_EXPORT WebmMuxer : public mkvmuxer::IMkvWriter {
VideoParameters(gfx::Size visible_rect_size,
double frame_rate,
VideoCodec codec,
- base::Optional<gfx::ColorSpace> color_space);
+ absl::optional<gfx::ColorSpace> color_space);
VideoParameters(const VideoParameters&);
~VideoParameters();
gfx::Size visible_rect_size;
double frame_rate;
VideoCodec codec;
- base::Optional<gfx::ColorSpace> color_space;
+ absl::optional<gfx::ColorSpace> color_space;
};
// |audio_codec| should coincide with whatever is sent in OnEncodedAudio(),
@@ -121,7 +122,7 @@ class MEDIA_EXPORT WebmMuxer : public mkvmuxer::IMkvWriter {
// frame size.
void AddVideoTrack(const gfx::Size& frame_size,
double frame_rate,
- const base::Optional<gfx::ColorSpace>& color_space);
+ const absl::optional<gfx::ColorSpace>& color_space);
void AddAudioTrack(const media::AudioParameters& params);
// IMkvWriter interface.
diff --git a/chromium/media/remoting/DIR_METADATA b/chromium/media/remoting/DIR_METADATA
index 9e255559a4f..7c577c4a958 100644
--- a/chromium/media/remoting/DIR_METADATA
+++ b/chromium/media/remoting/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Internals>Cast>Streaming"
diff --git a/chromium/media/remoting/courier_renderer.cc b/chromium/media/remoting/courier_renderer.cc
index ea0a946088d..773f87e8ab5 100644
--- a/chromium/media/remoting/courier_renderer.cc
+++ b/chromium/media/remoting/courier_renderer.cc
@@ -138,7 +138,7 @@ void CourierRenderer::Initialize(MediaResource* media_resource,
}
void CourierRenderer::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {}
+ absl::optional<base::TimeDelta> latency_hint) {}
void CourierRenderer::Flush(base::OnceClosure flush_cb) {
DCHECK(media_task_runner_->BelongsToCurrentThread());
@@ -154,10 +154,10 @@ void CourierRenderer::Flush(base::OnceClosure flush_cb) {
}
state_ = STATE_FLUSHING;
- base::Optional<uint32_t> flush_audio_count;
+ absl::optional<uint32_t> flush_audio_count;
if (audio_demuxer_stream_adapter_)
flush_audio_count = audio_demuxer_stream_adapter_->SignalFlush(true);
- base::Optional<uint32_t> flush_video_count;
+ absl::optional<uint32_t> flush_video_count;
if (video_demuxer_stream_adapter_)
flush_video_count = video_demuxer_stream_adapter_->SignalFlush(true);
// Makes sure flush count is valid if stream is available or both audio and
@@ -520,7 +520,7 @@ void CourierRenderer::OnBufferingStateChange(
OnFatalError(RPC_INVALID);
return;
}
- base::Optional<BufferingState> state = ToMediaBufferingState(
+ absl::optional<BufferingState> state = ToMediaBufferingState(
message->rendererclient_onbufferingstatechange_rpc().state());
BufferingStateChangeReason reason = BUFFERING_CHANGE_REASON_UNKNOWN;
if (!state.has_value())
diff --git a/chromium/media/remoting/courier_renderer.h b/chromium/media/remoting/courier_renderer.h
index ea0cef06a58..8e3e985b45a 100644
--- a/chromium/media/remoting/courier_renderer.h
+++ b/chromium/media/remoting/courier_renderer.h
@@ -75,7 +75,7 @@ class CourierRenderer final : public Renderer {
void Initialize(MediaResource* media_resource,
RendererClient* client,
PipelineStatusCallback init_cb) final;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) final;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) final;
void Flush(base::OnceClosure flush_cb) final;
void StartPlayingFrom(base::TimeDelta time) final;
void SetPlaybackRate(double playback_rate) final;
diff --git a/chromium/media/remoting/courier_renderer_unittest.cc b/chromium/media/remoting/courier_renderer_unittest.cc
index cec0ff3b658..1fdafa56f8b 100644
--- a/chromium/media/remoting/courier_renderer_unittest.cc
+++ b/chromium/media/remoting/courier_renderer_unittest.cc
@@ -96,7 +96,7 @@ class RendererClientImpl final : public RendererClient {
void OnWaiting(WaitingReason reason) override {}
MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size& size));
MOCK_METHOD1(OnVideoOpacityChange, void(bool opaque));
- MOCK_METHOD1(OnVideoFrameRateChange, void(base::Optional<int>));
+ MOCK_METHOD1(OnVideoFrameRateChange, void(absl::optional<int>));
MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
void DelegateOnStatisticsUpdate(const PipelineStatistics& stats) {
@@ -439,7 +439,7 @@ class CourierRendererTest : public testing::Test {
// Issue RPC_RC_ONBUFFERINGSTATECHANGE RPC message.
void IssuesBufferingStateRpc(BufferingState state) {
- base::Optional<
+ absl::optional<
openscreen::cast::RendererClientOnBufferingStateChange::State>
pb_state = ToProtoMediaBufferingState(state);
if (!pb_state.has_value())
diff --git a/chromium/media/remoting/demuxer_stream_adapter.cc b/chromium/media/remoting/demuxer_stream_adapter.cc
index cccf161e42e..9039908e07c 100644
--- a/chromium/media/remoting/demuxer_stream_adapter.cc
+++ b/chromium/media/remoting/demuxer_stream_adapter.cc
@@ -81,13 +81,13 @@ int64_t DemuxerStreamAdapter::GetBytesWrittenAndReset() {
return current_count;
}
-base::Optional<uint32_t> DemuxerStreamAdapter::SignalFlush(bool flushing) {
+absl::optional<uint32_t> DemuxerStreamAdapter::SignalFlush(bool flushing) {
DCHECK(media_task_runner_->BelongsToCurrentThread());
DEMUXER_VLOG(2) << "flushing=" << flushing;
// Ignores if |pending_flush_| states is same.
if (pending_flush_ == flushing)
- return base::nullopt;
+ return absl::nullopt;
// Cleans up pending frame data.
pending_frame_is_eos_ = false;
diff --git a/chromium/media/remoting/demuxer_stream_adapter.h b/chromium/media/remoting/demuxer_stream_adapter.h
index 3e55c6cebdf..a30444c8c48 100644
--- a/chromium/media/remoting/demuxer_stream_adapter.h
+++ b/chromium/media/remoting/demuxer_stream_adapter.h
@@ -13,7 +13,6 @@
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/demuxer_stream.h"
#include "media/base/video_decoder_config.h"
@@ -25,6 +24,7 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/simple_watcher.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace base {
class SingleThreadTaskRunner;
@@ -84,8 +84,8 @@ class DemuxerStreamAdapter {
// signal when flush starts and when is done. During flush operation, all
// fetching data actions will be discarded. The return value indicates frame
// count in order to signal receiver what frames are in flight before flush,
- // or base::nullopt if the flushing state was unchanged.
- base::Optional<uint32_t> SignalFlush(bool flushing);
+ // or absl::nullopt if the flushing state was unchanged.
+ absl::optional<uint32_t> SignalFlush(bool flushing);
bool is_processing_read_request() const {
// |read_until_callback_handle_| is set when RPC_DS_READUNTIL message is
diff --git a/chromium/media/remoting/end2end_test_renderer.cc b/chromium/media/remoting/end2end_test_renderer.cc
index 4f71628b829..b431f565fdd 100644
--- a/chromium/media/remoting/end2end_test_renderer.cc
+++ b/chromium/media/remoting/end2end_test_renderer.cc
@@ -362,7 +362,7 @@ void End2EndTestRenderer::OnAcquireRendererDone(int receiver_renderer_handle) {
}
void End2EndTestRenderer::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
courier_renderer_->SetLatencyHint(latency_hint);
}
diff --git a/chromium/media/remoting/end2end_test_renderer.h b/chromium/media/remoting/end2end_test_renderer.h
index 61749c758a1..deab7964849 100644
--- a/chromium/media/remoting/end2end_test_renderer.h
+++ b/chromium/media/remoting/end2end_test_renderer.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_REMOTING_END2END_RENDERER_H_
-#define MEDIA_REMOTING_END2END_RENDERER_H_
+#ifndef MEDIA_REMOTING_END2END_TEST_RENDERER_H_
+#define MEDIA_REMOTING_END2END_TEST_RENDERER_H_
#include <memory>
#include <vector>
@@ -32,7 +32,7 @@ class End2EndTestRenderer final : public Renderer {
void Initialize(MediaResource* media_resource,
RendererClient* client,
PipelineStatusCallback init_cb) override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void SetPreservesPitch(bool preserves_pitch) override;
void Flush(base::OnceClosure flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
@@ -102,4 +102,4 @@ class End2EndTestRenderer final : public Renderer {
} // namespace remoting
} // namespace media
-#endif // MEDIA_REMOTING_END2END_RENDERER_H_
+#endif // MEDIA_REMOTING_END2END_TEST_RENDERER_H_
diff --git a/chromium/media/remoting/integration_test.cc b/chromium/media/remoting/integration_test.cc
index bbac6f6a8a8..805a425e1d0 100644
--- a/chromium/media/remoting/integration_test.cc
+++ b/chromium/media/remoting/integration_test.cc
@@ -25,9 +25,9 @@ class MediaRemotingIntegrationTest : public testing::Test,
private:
std::unique_ptr<Renderer> CreateEnd2EndTestRenderer(
- base::Optional<RendererFactoryType> factory_type) {
+ absl::optional<RendererType> renderer_type) {
return std::make_unique<End2EndTestRenderer>(
- this->CreateDefaultRenderer(factory_type));
+ this->CreateDefaultRenderer(renderer_type));
}
DISALLOW_COPY_AND_ASSIGN(MediaRemotingIntegrationTest);
diff --git a/chromium/media/remoting/metrics.cc b/chromium/media/remoting/metrics.cc
index fd3252c558a..c2f9f03a271 100644
--- a/chromium/media/remoting/metrics.cc
+++ b/chromium/media/remoting/metrics.cc
@@ -116,7 +116,7 @@ void SessionMetricsRecorder::WillStopSession(StopTrigger trigger) {
// Reset |start_trigger_| since metrics recording of the current remoting
// session has now completed.
- start_trigger_ = base::nullopt;
+ start_trigger_ = absl::nullopt;
}
void SessionMetricsRecorder::OnPipelineMetadataChanged(
@@ -182,6 +182,10 @@ void SessionMetricsRecorder::RecordVideoPixelRateSupport(
void SessionMetricsRecorder::RecordCompatibility(
RemotingCompatibility compatibility) {
+ if (did_record_compatibility_) {
+ return;
+ }
+ did_record_compatibility_ = true;
base::UmaHistogramEnumeration("Media.Remoting.Compatibility", compatibility);
}
diff --git a/chromium/media/remoting/metrics.h b/chromium/media/remoting/metrics.h
index 017ad9de60f..c08e8779b77 100644
--- a/chromium/media/remoting/metrics.h
+++ b/chromium/media/remoting/metrics.h
@@ -6,10 +6,10 @@
#define MEDIA_REMOTING_METRICS_H_
#include "base/macros.h"
-#include "base/optional.h"
#include "base/time/time.h"
#include "media/base/pipeline_metadata.h"
#include "media/remoting/triggers.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
@@ -70,7 +70,8 @@ class SessionMetricsRecorder {
// for the recorder instance.
void RecordVideoPixelRateSupport(PixelRateSupport support);
- // Records the compatibility of a media content with remoting.
+ // Records the compatibility of a media content with remoting. Records only on
+ // the first call for the recorder instance.
void RecordCompatibility(RemotingCompatibility compatibility);
private:
@@ -95,7 +96,7 @@ class SessionMetricsRecorder {
void RecordTrackConfiguration();
// |start_trigger_| is set while a remoting session is active.
- base::Optional<StartTrigger> start_trigger_;
+ absl::optional<StartTrigger> start_trigger_;
// When the current (or last) remoting session started.
base::TimeTicks start_time_;
@@ -114,6 +115,7 @@ class SessionMetricsRecorder {
bool remote_playback_is_disabled_ = false;
bool did_record_pixel_rate_support_ = false;
+ bool did_record_compatibility_ = false;
DISALLOW_COPY_AND_ASSIGN(SessionMetricsRecorder);
};
diff --git a/chromium/media/remoting/metrics_unittest.cc b/chromium/media/remoting/metrics_unittest.cc
index 8ac9b0b6b76..cd6f8b6f020 100644
--- a/chromium/media/remoting/metrics_unittest.cc
+++ b/chromium/media/remoting/metrics_unittest.cc
@@ -51,13 +51,13 @@ TEST_F(MediaRemotingMetricsTest, RecordCompatibility) {
recorder_.RecordCompatibility(RemotingCompatibility::kCompatible);
recorder_.RecordCompatibility(RemotingCompatibility::kIncompatibleVideoCodec);
+ // We record only for the first RecordCompatibility() call for the
+ // given SessionMetricsRecorder instance.
EXPECT_THAT(
tester.GetAllSamples(kCompatibilityHistogramName),
- ElementsAre(
- Bucket(static_cast<int>(RemotingCompatibility::kCompatible), 1),
- Bucket(
- static_cast<int>(RemotingCompatibility::kIncompatibleVideoCodec),
- 2)));
+ ElementsAre(Bucket(
+ static_cast<int>(RemotingCompatibility::kIncompatibleVideoCodec),
+ 1)));
}
} // namespace remoting
diff --git a/chromium/media/remoting/proto_enum_utils.cc b/chromium/media/remoting/proto_enum_utils.cc
index 6d1c9d59be1..e080e050580 100644
--- a/chromium/media/remoting/proto_enum_utils.cc
+++ b/chromium/media/remoting/proto_enum_utils.cc
@@ -11,7 +11,7 @@ namespace remoting {
case OriginType::x: \
return OtherType::x
-base::Optional<AudioCodec> ToMediaAudioCodec(
+absl::optional<AudioCodec> ToMediaAudioCodec(
openscreen::cast::AudioDecoderConfig::Codec value) {
using OriginType = openscreen::cast::AudioDecoderConfig;
using OtherType = AudioCodec;
@@ -35,10 +35,10 @@ base::Optional<AudioCodec> ToMediaAudioCodec(
CASE_RETURN_OTHER(kCodecAC3);
CASE_RETURN_OTHER(kCodecMpegHAudio);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<openscreen::cast::AudioDecoderConfig::Codec>
+absl::optional<openscreen::cast::AudioDecoderConfig::Codec>
ToProtoAudioDecoderConfigCodec(AudioCodec value) {
using OriginType = AudioCodec;
using OtherType = openscreen::cast::AudioDecoderConfig;
@@ -62,10 +62,10 @@ ToProtoAudioDecoderConfigCodec(AudioCodec value) {
CASE_RETURN_OTHER(kCodecAC3);
CASE_RETURN_OTHER(kCodecMpegHAudio);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<SampleFormat> ToMediaSampleFormat(
+absl::optional<SampleFormat> ToMediaSampleFormat(
openscreen::cast::AudioDecoderConfig::SampleFormat value) {
using OriginType = openscreen::cast::AudioDecoderConfig;
using OtherType = SampleFormat;
@@ -83,10 +83,10 @@ base::Optional<SampleFormat> ToMediaSampleFormat(
CASE_RETURN_OTHER(kSampleFormatEac3);
CASE_RETURN_OTHER(kSampleFormatMpegHAudio);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<openscreen::cast::AudioDecoderConfig::SampleFormat>
+absl::optional<openscreen::cast::AudioDecoderConfig::SampleFormat>
ToProtoAudioDecoderConfigSampleFormat(SampleFormat value) {
using OriginType = SampleFormat;
using OtherType = openscreen::cast::AudioDecoderConfig;
@@ -104,10 +104,10 @@ ToProtoAudioDecoderConfigSampleFormat(SampleFormat value) {
CASE_RETURN_OTHER(kSampleFormatEac3);
CASE_RETURN_OTHER(kSampleFormatMpegHAudio);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<ChannelLayout> ToMediaChannelLayout(
+absl::optional<ChannelLayout> ToMediaChannelLayout(
openscreen::cast::AudioDecoderConfig::ChannelLayout value) {
using OriginType = openscreen::cast::AudioDecoderConfig;
using OtherType = ChannelLayout;
@@ -146,10 +146,10 @@ base::Optional<ChannelLayout> ToMediaChannelLayout(
CASE_RETURN_OTHER(CHANNEL_LAYOUT_4_1_QUAD_SIDE);
CASE_RETURN_OTHER(CHANNEL_LAYOUT_BITSTREAM);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<openscreen::cast::AudioDecoderConfig::ChannelLayout>
+absl::optional<openscreen::cast::AudioDecoderConfig::ChannelLayout>
ToProtoAudioDecoderConfigChannelLayout(ChannelLayout value) {
using OriginType = ChannelLayout;
using OtherType = openscreen::cast::AudioDecoderConfig;
@@ -188,10 +188,10 @@ ToProtoAudioDecoderConfigChannelLayout(ChannelLayout value) {
CASE_RETURN_OTHER(CHANNEL_LAYOUT_4_1_QUAD_SIDE);
CASE_RETURN_OTHER(CHANNEL_LAYOUT_BITSTREAM);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<VideoCodec> ToMediaVideoCodec(
+absl::optional<VideoCodec> ToMediaVideoCodec(
openscreen::cast::VideoDecoderConfig::Codec value) {
using OriginType = openscreen::cast::VideoDecoderConfig;
using OtherType = VideoCodec;
@@ -208,10 +208,10 @@ base::Optional<VideoCodec> ToMediaVideoCodec(
CASE_RETURN_OTHER(kCodecDolbyVision);
CASE_RETURN_OTHER(kCodecAV1);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<openscreen::cast::VideoDecoderConfig::Codec>
+absl::optional<openscreen::cast::VideoDecoderConfig::Codec>
ToProtoVideoDecoderConfigCodec(VideoCodec value) {
using OriginType = VideoCodec;
using OtherType = openscreen::cast::VideoDecoderConfig;
@@ -228,10 +228,10 @@ ToProtoVideoDecoderConfigCodec(VideoCodec value) {
CASE_RETURN_OTHER(kCodecDolbyVision);
CASE_RETURN_OTHER(kCodecAV1);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<VideoCodecProfile> ToMediaVideoCodecProfile(
+absl::optional<VideoCodecProfile> ToMediaVideoCodecProfile(
openscreen::cast::VideoDecoderConfig::Profile value) {
using OriginType = openscreen::cast::VideoDecoderConfig;
using OtherType = VideoCodecProfile;
@@ -267,10 +267,10 @@ base::Optional<VideoCodecProfile> ToMediaVideoCodecProfile(
CASE_RETURN_OTHER(AV1PROFILE_PROFILE_HIGH);
CASE_RETURN_OTHER(AV1PROFILE_PROFILE_PRO);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<openscreen::cast::VideoDecoderConfig::Profile>
+absl::optional<openscreen::cast::VideoDecoderConfig::Profile>
ToProtoVideoDecoderConfigProfile(VideoCodecProfile value) {
using OriginType = VideoCodecProfile;
using OtherType = openscreen::cast::VideoDecoderConfig;
@@ -306,10 +306,10 @@ ToProtoVideoDecoderConfigProfile(VideoCodecProfile value) {
CASE_RETURN_OTHER(AV1PROFILE_PROFILE_HIGH);
CASE_RETURN_OTHER(AV1PROFILE_PROFILE_PRO);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<VideoPixelFormat> ToMediaVideoPixelFormat(
+absl::optional<VideoPixelFormat> ToMediaVideoPixelFormat(
openscreen::cast::VideoDecoderConfig::Format value) {
using OriginType = openscreen::cast::VideoDecoderConfig;
using OtherType = VideoPixelFormat;
@@ -344,12 +344,12 @@ base::Optional<VideoPixelFormat> ToMediaVideoPixelFormat(
CASE_RETURN_OTHER(PIXEL_FORMAT_XB30);
// PIXEL_FORMAT_UYVY, PIXEL_FORMAT_RGB32 and PIXEL_FORMAT_Y8 are deprecated.
case openscreen::cast::VideoDecoderConfig_Format_PIXEL_FORMAT_RGB32:
- return base::nullopt;
+ return absl::nullopt;
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<BufferingState> ToMediaBufferingState(
+absl::optional<BufferingState> ToMediaBufferingState(
openscreen::cast::RendererClientOnBufferingStateChange::State value) {
using OriginType = openscreen::cast::RendererClientOnBufferingStateChange;
using OtherType = BufferingState;
@@ -357,10 +357,10 @@ base::Optional<BufferingState> ToMediaBufferingState(
CASE_RETURN_OTHER(BUFFERING_HAVE_NOTHING);
CASE_RETURN_OTHER(BUFFERING_HAVE_ENOUGH);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<openscreen::cast::RendererClientOnBufferingStateChange::State>
+absl::optional<openscreen::cast::RendererClientOnBufferingStateChange::State>
ToProtoMediaBufferingState(BufferingState value) {
using OriginType = BufferingState;
using OtherType = openscreen::cast::RendererClientOnBufferingStateChange;
@@ -368,10 +368,10 @@ ToProtoMediaBufferingState(BufferingState value) {
CASE_RETURN_OTHER(BUFFERING_HAVE_NOTHING);
CASE_RETURN_OTHER(BUFFERING_HAVE_ENOUGH);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<DemuxerStream::Status> ToDemuxerStreamStatus(
+absl::optional<DemuxerStream::Status> ToDemuxerStreamStatus(
openscreen::cast::DemuxerStreamReadUntilCallback::Status value) {
using OriginType = openscreen::cast::DemuxerStreamReadUntilCallback;
using OtherType = DemuxerStream;
@@ -381,10 +381,10 @@ base::Optional<DemuxerStream::Status> ToDemuxerStreamStatus(
CASE_RETURN_OTHER(kConfigChanged);
CASE_RETURN_OTHER(kError);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
-base::Optional<openscreen::cast::DemuxerStreamReadUntilCallback::Status>
+absl::optional<openscreen::cast::DemuxerStreamReadUntilCallback::Status>
ToProtoDemuxerStreamStatus(DemuxerStream::Status value) {
using OriginType = DemuxerStream;
using OtherType = openscreen::cast::DemuxerStreamReadUntilCallback;
@@ -394,7 +394,7 @@ ToProtoDemuxerStreamStatus(DemuxerStream::Status value) {
CASE_RETURN_OTHER(kConfigChanged);
CASE_RETURN_OTHER(kError);
}
- return base::nullopt; // Not a 'default' to ensure compile-time checks.
+ return absl::nullopt; // Not a 'default' to ensure compile-time checks.
}
} // namespace remoting
diff --git a/chromium/media/remoting/proto_enum_utils.h b/chromium/media/remoting/proto_enum_utils.h
index d4dd1362024..1748d4f5d16 100644
--- a/chromium/media/remoting/proto_enum_utils.h
+++ b/chromium/media/remoting/proto_enum_utils.h
@@ -5,7 +5,6 @@
#ifndef MEDIA_REMOTING_PROTO_ENUM_UTILS_H_
#define MEDIA_REMOTING_PROTO_ENUM_UTILS_H_
-#include "base/optional.h"
#include "media/base/audio_codecs.h"
#include "media/base/buffering_state.h"
#include "media/base/channel_layout.h"
@@ -13,6 +12,7 @@
#include "media/base/sample_format.h"
#include "media/base/video_codecs.h"
#include "media/base/video_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/openscreen/src/cast/streaming/remoting.pb.h"
namespace media {
@@ -24,45 +24,45 @@ namespace remoting {
// modules while maintaining compile-time checks to ensure that there are always
// valid, backwards-compatible mappings between the two.
//
-// Each returns a base::Optional value. If it is not set, that indicates the
+// Each returns a absl::optional value. If it is not set, that indicates the
// conversion failed.
-base::Optional<AudioCodec> ToMediaAudioCodec(
+absl::optional<AudioCodec> ToMediaAudioCodec(
openscreen::cast::AudioDecoderConfig::Codec value);
-base::Optional<openscreen::cast::AudioDecoderConfig::Codec>
+absl::optional<openscreen::cast::AudioDecoderConfig::Codec>
ToProtoAudioDecoderConfigCodec(AudioCodec value);
-base::Optional<SampleFormat> ToMediaSampleFormat(
+absl::optional<SampleFormat> ToMediaSampleFormat(
openscreen::cast::AudioDecoderConfig::SampleFormat value);
-base::Optional<openscreen::cast::AudioDecoderConfig::SampleFormat>
+absl::optional<openscreen::cast::AudioDecoderConfig::SampleFormat>
ToProtoAudioDecoderConfigSampleFormat(SampleFormat value);
-base::Optional<ChannelLayout> ToMediaChannelLayout(
+absl::optional<ChannelLayout> ToMediaChannelLayout(
openscreen::cast::AudioDecoderConfig::ChannelLayout value);
-base::Optional<openscreen::cast::AudioDecoderConfig::ChannelLayout>
+absl::optional<openscreen::cast::AudioDecoderConfig::ChannelLayout>
ToProtoAudioDecoderConfigChannelLayout(ChannelLayout value);
-base::Optional<VideoCodec> ToMediaVideoCodec(
+absl::optional<VideoCodec> ToMediaVideoCodec(
openscreen::cast::VideoDecoderConfig::Codec value);
-base::Optional<openscreen::cast::VideoDecoderConfig::Codec>
+absl::optional<openscreen::cast::VideoDecoderConfig::Codec>
ToProtoVideoDecoderConfigCodec(VideoCodec value);
-base::Optional<VideoCodecProfile> ToMediaVideoCodecProfile(
+absl::optional<VideoCodecProfile> ToMediaVideoCodecProfile(
openscreen::cast::VideoDecoderConfig::Profile value);
-base::Optional<openscreen::cast::VideoDecoderConfig::Profile>
+absl::optional<openscreen::cast::VideoDecoderConfig::Profile>
ToProtoVideoDecoderConfigProfile(VideoCodecProfile value);
-base::Optional<VideoPixelFormat> ToMediaVideoPixelFormat(
+absl::optional<VideoPixelFormat> ToMediaVideoPixelFormat(
openscreen::cast::VideoDecoderConfig::Format value);
-base::Optional<BufferingState> ToMediaBufferingState(
+absl::optional<BufferingState> ToMediaBufferingState(
openscreen::cast::RendererClientOnBufferingStateChange::State value);
-base::Optional<openscreen::cast::RendererClientOnBufferingStateChange::State>
+absl::optional<openscreen::cast::RendererClientOnBufferingStateChange::State>
ToProtoMediaBufferingState(BufferingState value);
-base::Optional<DemuxerStream::Status> ToDemuxerStreamStatus(
+absl::optional<DemuxerStream::Status> ToDemuxerStreamStatus(
openscreen::cast::DemuxerStreamReadUntilCallback::Status value);
-base::Optional<openscreen::cast::DemuxerStreamReadUntilCallback::Status>
+absl::optional<openscreen::cast::DemuxerStreamReadUntilCallback::Status>
ToProtoDemuxerStreamStatus(DemuxerStream::Status value);
} // namespace remoting
diff --git a/chromium/media/remoting/receiver.cc b/chromium/media/remoting/receiver.cc
index 80772aaf894..fa5fda9ed55 100644
--- a/chromium/media/remoting/receiver.cc
+++ b/chromium/media/remoting/receiver.cc
@@ -85,7 +85,7 @@ void Receiver::SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) {
}
// No-op. Controlled by sender via RPC calls instead.
-void Receiver::SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) {}
+void Receiver::SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) {}
// No-op. Controlled by sender via RPC calls instead.
void Receiver::Flush(base::OnceClosure flush_cb) {}
@@ -358,7 +358,7 @@ void Receiver::OnVideoOpacityChange(bool opaque) {
SendRpcMessageOnMainThread(std::move(rpc));
}
-void Receiver::OnVideoFrameRateChange(base::Optional<int>) {}
+void Receiver::OnVideoFrameRateChange(absl::optional<int>) {}
} // namespace remoting
} // namespace media
diff --git a/chromium/media/remoting/receiver.h b/chromium/media/remoting/receiver.h
index 868329dca49..885dc2e1b74 100644
--- a/chromium/media/remoting/receiver.h
+++ b/chromium/media/remoting/receiver.h
@@ -54,7 +54,7 @@ class Receiver final : public Renderer, public RendererClient {
RendererClient* client,
PipelineStatusCallback init_cb) override;
void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void Flush(base::OnceClosure flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
void SetPlaybackRate(double playback_rate) override;
@@ -72,7 +72,7 @@ class Receiver final : public Renderer, public RendererClient {
void OnVideoConfigChange(const VideoDecoderConfig& config) override;
void OnVideoNaturalSizeChange(const gfx::Size& size) override;
void OnVideoOpacityChange(bool opaque) override;
- void OnVideoFrameRateChange(base::Optional<int>) override;
+ void OnVideoFrameRateChange(absl::optional<int>) override;
// Used to set |remote_handle_| after Receiver is created, because the remote
// handle might be received after Receiver is created.
diff --git a/chromium/media/remoting/receiver_unittest.cc b/chromium/media/remoting/receiver_unittest.cc
index 60e74939eb1..e5c46712d62 100644
--- a/chromium/media/remoting/receiver_unittest.cc
+++ b/chromium/media/remoting/receiver_unittest.cc
@@ -7,7 +7,6 @@
#include <utility>
#include "base/check.h"
-#include "base/optional.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/task_environment.h"
#include "media/base/audio_decoder_config.h"
@@ -21,6 +20,7 @@
#include "media/remoting/proto_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
using base::test::RunOnceCallback;
using testing::_;
@@ -78,7 +78,7 @@ class MockSender {
break;
}
case openscreen::cast::RpcMessage::RPC_RC_ONBUFFERINGSTATECHANGE: {
- base::Optional<BufferingState> state = ToMediaBufferingState(
+ absl::optional<BufferingState> state = ToMediaBufferingState(
message->rendererclient_onbufferingstatechange_rpc().state());
if (state.has_value())
OnBufferingStateChange(state.value());
diff --git a/chromium/media/remoting/renderer_controller.h b/chromium/media/remoting/renderer_controller.h
index 4bcc0e1c1b0..72e966dcdab 100644
--- a/chromium/media/remoting/renderer_controller.h
+++ b/chromium/media/remoting/renderer_controller.h
@@ -9,7 +9,6 @@
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
@@ -23,6 +22,7 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#if BUILDFLAG(ENABLE_MEDIA_REMOTING_RPC)
#include "media/remoting/rpc_broker.h" // nogncheck
diff --git a/chromium/media/remoting/stream_provider.cc b/chromium/media/remoting/stream_provider.cc
index 1966bc51bf0..15c1d134e7b 100644
--- a/chromium/media/remoting/stream_provider.cc
+++ b/chromium/media/remoting/stream_provider.cc
@@ -477,9 +477,9 @@ int64_t StreamProvider::GetMemoryUsage() const {
return 0;
}
-base::Optional<container_names::MediaContainerName>
+absl::optional<container_names::MediaContainerName>
StreamProvider::GetContainerForMetrics() const {
- return base::Optional<container_names::MediaContainerName>();
+ return absl::optional<container_names::MediaContainerName>();
}
void StreamProvider::OnEnabledAudioTracksChanged(
diff --git a/chromium/media/remoting/stream_provider.h b/chromium/media/remoting/stream_provider.h
index 5073bc42852..d7352ab854b 100644
--- a/chromium/media/remoting/stream_provider.h
+++ b/chromium/media/remoting/stream_provider.h
@@ -52,7 +52,7 @@ class StreamProvider final : public Demuxer {
base::TimeDelta GetStartTime() const override;
base::Time GetTimelineOffset() const override;
int64_t GetMemoryUsage() const override;
- base::Optional<container_names::MediaContainerName> GetContainerForMetrics()
+ absl::optional<container_names::MediaContainerName> GetContainerForMetrics()
const override;
void OnEnabledAudioTracksChanged(const std::vector<MediaTrack::Id>& track_ids,
base::TimeDelta curr_time,
diff --git a/chromium/media/renderers/BUILD.gn b/chromium/media/renderers/BUILD.gn
index 42981ccb8b3..154f6be4c05 100644
--- a/chromium/media/renderers/BUILD.gn
+++ b/chromium/media/renderers/BUILD.gn
@@ -26,6 +26,8 @@ source_set("renderers") {
"renderer_impl.h",
"video_frame_yuv_converter.cc",
"video_frame_yuv_converter.h",
+ "video_frame_yuv_mailboxes_holder.cc",
+ "video_frame_yuv_mailboxes_holder.h",
"video_overlay_factory.cc",
"video_overlay_factory.h",
"video_renderer_impl.cc",
@@ -72,8 +74,6 @@ source_set("renderers") {
"win/media_foundation_renderer.cc",
"win/media_foundation_renderer.h",
"win/media_foundation_renderer_extension.h",
- "win/media_foundation_renderer_factory.cc",
- "win/media_foundation_renderer_factory.h",
"win/media_foundation_source_wrapper.cc",
"win/media_foundation_source_wrapper.h",
"win/media_foundation_stream_wrapper.cc",
diff --git a/chromium/media/renderers/audio_renderer_impl.cc b/chromium/media/renderers/audio_renderer_impl.cc
index 587534a9073..cdcae8e2639 100644
--- a/chromium/media/renderers/audio_renderer_impl.cc
+++ b/chromium/media/renderers/audio_renderer_impl.cc
@@ -641,7 +641,7 @@ void AudioRendererImpl::OnAudioDecoderStreamInitialized(bool success) {
auto params =
(media_client ? media_client->GetAudioRendererAlgorithmParameters(
audio_parameters_)
- : base::nullopt);
+ : absl::nullopt);
if (params && !client_->IsVideoStreamAvailable()) {
algorithm_ =
std::make_unique<AudioRendererAlgorithm>(media_log_, params.value());
@@ -777,7 +777,7 @@ void AudioRendererImpl::SetVolume(float volume) {
}
void AudioRendererImpl::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
base::AutoLock auto_lock(lock_);
latency_hint_ = latency_hint;
diff --git a/chromium/media/renderers/audio_renderer_impl.h b/chromium/media/renderers/audio_renderer_impl.h
index 90d5a18a089..d9ea713331c 100644
--- a/chromium/media/renderers/audio_renderer_impl.h
+++ b/chromium/media/renderers/audio_renderer_impl.h
@@ -25,7 +25,6 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/power_monitor/power_observer.h"
#include "base/synchronization/lock.h"
#include "media/base/audio_decoder.h"
@@ -38,6 +37,7 @@
#include "media/filters/audio_renderer_algorithm.h"
#include "media/filters/decoder_stream.h"
#include "media/renderers/default_renderer_factory.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace base {
class SingleThreadTaskRunner;
@@ -99,7 +99,7 @@ class MEDIA_EXPORT AudioRendererImpl
void Flush(base::OnceClosure callback) override;
void StartPlaying() override;
void SetVolume(float volume) override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void SetPreservesPitch(bool preserves_pitch) override;
void SetAutoplayInitiated(bool autoplay_initiated) override;
@@ -310,7 +310,7 @@ class MEDIA_EXPORT AudioRendererImpl
// Stored value from last call to SetLatencyHint(). Passed to |algorithm_|
// during Initialize().
- base::Optional<base::TimeDelta> latency_hint_;
+ absl::optional<base::TimeDelta> latency_hint_;
// Passed to |algorithm_|. Indicates whether |algorithm_| should or should not
// make pitch adjustments at playbacks other than 1.0.
diff --git a/chromium/media/renderers/audio_renderer_impl_unittest.cc b/chromium/media/renderers/audio_renderer_impl_unittest.cc
index 7f25d00afee..101fd5f218c 100644
--- a/chromium/media/renderers/audio_renderer_impl_unittest.cc
+++ b/chromium/media/renderers/audio_renderer_impl_unittest.cc
@@ -222,7 +222,7 @@ class AudioRendererImplTest : public ::testing::Test, public RendererClient {
MOCK_METHOD1(OnVideoConfigChange, void(const VideoDecoderConfig&));
MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&));
MOCK_METHOD1(OnVideoOpacityChange, void(bool));
- MOCK_METHOD1(OnVideoFrameRateChange, void(base::Optional<int>));
+ MOCK_METHOD1(OnVideoFrameRateChange, void(absl::optional<int>));
MOCK_METHOD1(OnDurationChange, void(base::TimeDelta));
MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
MOCK_METHOD1(TranscribeAudioCallback, void(scoped_refptr<AudioBuffer>));
diff --git a/chromium/media/renderers/decrypting_renderer.cc b/chromium/media/renderers/decrypting_renderer.cc
index 346a774f33e..d1d21d9e5c8 100644
--- a/chromium/media/renderers/decrypting_renderer.cc
+++ b/chromium/media/renderers/decrypting_renderer.cc
@@ -107,7 +107,7 @@ void DecryptingRenderer::SetCdm(CdmContext* cdm_context,
}
void DecryptingRenderer::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
renderer_->SetLatencyHint(latency_hint);
}
diff --git a/chromium/media/renderers/decrypting_renderer.h b/chromium/media/renderers/decrypting_renderer.h
index a51d2482bf3..d803b7504ff 100644
--- a/chromium/media/renderers/decrypting_renderer.h
+++ b/chromium/media/renderers/decrypting_renderer.h
@@ -45,7 +45,7 @@ class MEDIA_EXPORT DecryptingRenderer : public Renderer {
RendererClient* client,
PipelineStatusCallback init_cb) override;
void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void SetPreservesPitch(bool preserves_pitch) override;
void SetAutoplayInitiated(bool autoplay_initiated) override;
diff --git a/chromium/media/renderers/default_decoder_factory.cc b/chromium/media/renderers/default_decoder_factory.cc
index eafe4947f40..5e242d3623a 100644
--- a/chromium/media/renderers/default_decoder_factory.cc
+++ b/chromium/media/renderers/default_decoder_factory.cc
@@ -100,15 +100,6 @@ DefaultDecoderFactory::GetSupportedVideoDecoderConfigsForWebRTC() {
}
}
-#if defined(OS_FUCHSIA)
- // TODO(crbug.com/1173503): Implement capabilities for fuchsia.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableSoftwareVideoDecoders)) {
- // Bypass software codec registration.
- return supported_configs;
- }
-#endif
-
if (!base::FeatureList::IsEnabled(media::kExposeSwDecodersToWebRTC))
return supported_configs;
@@ -191,12 +182,6 @@ void DefaultDecoderFactory::CreateVideoDecoders(
<< "Can't create FuchsiaVideoDecoder due to GPU context loss.";
}
}
-
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableSoftwareVideoDecoders)) {
- // Bypass software codec registration.
- return;
- }
#endif
#if BUILDFLAG(ENABLE_LIBVPX)
diff --git a/chromium/media/renderers/paint_canvas_video_renderer.cc b/chromium/media/renderers/paint_canvas_video_renderer.cc
index fd23d7d3740..cb27f53305f 100644
--- a/chromium/media/renderers/paint_canvas_video_renderer.cc
+++ b/chromium/media/renderers/paint_canvas_video_renderer.cc
@@ -812,7 +812,7 @@ void PaintCanvasVideoRenderer::Paint(
cc::PaintImage image = cache_->paint_image;
DCHECK(image);
- base::Optional<ScopedSharedImageAccess> source_access;
+ absl::optional<ScopedSharedImageAccess> source_access;
if (video_frame->HasTextures() && cache_->source_texture) {
DCHECK(cache_->texture_backing);
source_access.emplace(raster_context_provider->RasterInterface(),
@@ -896,21 +896,19 @@ void PaintCanvasVideoRenderer::Paint(
} else if (video_frame->HasTextures()) {
DCHECK_EQ(video_frame->coded_size(),
gfx::Size(image.width(), image.height()));
- canvas->drawImageRect(
- image, gfx::RectToSkRect(video_frame->visible_rect()),
- SkRect::MakeWH(video_frame->visible_rect().width(),
- video_frame->visible_rect().height()),
- SkSamplingOptions(flags.getFilterQuality(),
- SkSamplingOptions::kMedium_asMipmapLinear),
- &video_flags, SkCanvas::kStrict_SrcRectConstraint);
+ canvas->drawImageRect(image, gfx::RectToSkRect(video_frame->visible_rect()),
+ SkRect::MakeWH(video_frame->visible_rect().width(),
+ video_frame->visible_rect().height()),
+ cc::PaintFlags::FilterQualityToSkSamplingOptions(
+ flags.getFilterQuality()),
+ &video_flags, SkCanvas::kStrict_SrcRectConstraint);
} else {
DCHECK_EQ(video_frame->visible_rect().size(),
gfx::Size(image.width(), image.height()));
- canvas->drawImage(
- image, 0, 0,
- SkSamplingOptions(flags.getFilterQuality(),
- SkSamplingOptions::kMedium_asMipmapLinear),
- &video_flags);
+ canvas->drawImage(image, 0, 0,
+ cc::PaintFlags::FilterQualityToSkSamplingOptions(
+ flags.getFilterQuality()),
+ &video_flags);
}
if (need_transform)
@@ -1477,7 +1475,8 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameYUVDataToGLTexture(
int level,
bool premultiply_alpha,
bool flip_y) {
- DCHECK(raster_context_provider);
+ if (!raster_context_provider)
+ return false;
#if defined(OS_ANDROID)
// TODO(crbug.com/1181993): These formats don't work with the passthrough
// command decoder on Android for some reason.
diff --git a/chromium/media/renderers/paint_canvas_video_renderer.h b/chromium/media/renderers/paint_canvas_video_renderer.h
index c7c6bec8e10..b8ad267ab88 100644
--- a/chromium/media/renderers/paint_canvas_video_renderer.h
+++ b/chromium/media/renderers/paint_canvas_video_renderer.h
@@ -10,9 +10,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "base/threading/thread_checker.h"
-#include "base/time/time.h"
#include "base/timer/timer.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
@@ -23,6 +21,7 @@
#include "media/base/video_frame.h"
#include "media/base/video_transformation.h"
#include "media/renderers/video_frame_yuv_converter.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace gfx {
class RectF;
@@ -258,7 +257,7 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer {
bool CacheBackingWrapsTexture() const;
- base::Optional<Cache> cache_;
+ absl::optional<Cache> cache_;
// If |cache_| is not used for a while, it's deleted to save memory.
base::DelayTimer cache_deleting_timer_;
diff --git a/chromium/media/renderers/paint_canvas_video_renderer_unittest.cc b/chromium/media/renderers/paint_canvas_video_renderer_unittest.cc
index b85126b2bbe..acfa87f7662 100644
--- a/chromium/media/renderers/paint_canvas_video_renderer_unittest.cc
+++ b/chromium/media/renderers/paint_canvas_video_renderer_unittest.cc
@@ -162,8 +162,7 @@ static SkBitmap AllocBitmap(int width, int height) {
}
static scoped_refptr<VideoFrame> CreateCroppedFrame() {
- scoped_refptr<VideoFrame> cropped_frame;
- cropped_frame = VideoFrame::CreateFrame(
+ scoped_refptr<VideoFrame> cropped_frame = VideoFrame::CreateFrame(
PIXEL_FORMAT_I420, gfx::Size(16, 16), gfx::Rect(6, 6, 8, 6),
gfx::Size(8, 6), base::TimeDelta::FromMilliseconds(4));
// Make sure the cropped video frame's aspect ratio matches the output device.
@@ -1078,7 +1077,7 @@ class PaintCanvasVideoRendererWithGLTest : public testing::TestWithParam<bool> {
scoped_refptr<VideoFrame> cropped_frame() { return cropped_frame_; }
protected:
- base::Optional<gl::DisableNullDrawGLBindings> enable_pixels_;
+ absl::optional<gl::DisableNullDrawGLBindings> enable_pixels_;
scoped_refptr<viz::TestInProcessContextProvider> media_context_;
scoped_refptr<viz::TestInProcessContextProvider> gles2_context_;
scoped_refptr<viz::TestInProcessContextProvider> destination_context_;
diff --git a/chromium/media/renderers/renderer_impl.cc b/chromium/media/renderers/renderer_impl.cc
index 049ffcf0883..7357ba495f2 100644
--- a/chromium/media/renderers/renderer_impl.cc
+++ b/chromium/media/renderers/renderer_impl.cc
@@ -65,7 +65,7 @@ class RendererImpl::RendererClientInternal final : public RendererClient {
DCHECK(type_ == DemuxerStream::VIDEO);
renderer_->OnVideoOpacityChange(opaque);
}
- void OnVideoFrameRateChange(base::Optional<int> fps) override {
+ void OnVideoFrameRateChange(absl::optional<int> fps) override {
DCHECK(type_ == DemuxerStream::VIDEO);
renderer_->OnVideoFrameRateChange(fps);
}
@@ -178,7 +178,7 @@ void RendererImpl::SetCdm(CdmContext* cdm_context,
}
void RendererImpl::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
DVLOG(1) << __func__;
DCHECK(!latency_hint || (*latency_hint >= base::TimeDelta()));
DCHECK(task_runner_->BelongsToCurrentThread());
@@ -950,7 +950,7 @@ void RendererImpl::OnVideoOpacityChange(bool opaque) {
client_->OnVideoOpacityChange(opaque);
}
-void RendererImpl::OnVideoFrameRateChange(base::Optional<int> fps) {
+void RendererImpl::OnVideoFrameRateChange(absl::optional<int> fps) {
DCHECK(task_runner_->BelongsToCurrentThread());
client_->OnVideoFrameRateChange(fps);
}
diff --git a/chromium/media/renderers/renderer_impl.h b/chromium/media/renderers/renderer_impl.h
index 5c0d688aa6e..69abeb247da 100644
--- a/chromium/media/renderers/renderer_impl.h
+++ b/chromium/media/renderers/renderer_impl.h
@@ -58,7 +58,7 @@ class MEDIA_EXPORT RendererImpl final : public Renderer {
RendererClient* client,
PipelineStatusCallback init_cb) final;
void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) final;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) final;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) final;
void SetPreservesPitch(bool preserves_pitch) final;
void SetAutoplayInitiated(bool autoplay_initiated) final;
void Flush(base::OnceClosure flush_cb) final;
@@ -199,7 +199,7 @@ class MEDIA_EXPORT RendererImpl final : public Renderer {
void OnAudioConfigChange(const AudioDecoderConfig& config);
void OnVideoConfigChange(const VideoDecoderConfig& config);
void OnVideoOpacityChange(bool opaque);
- void OnVideoFrameRateChange(base::Optional<int> fps);
+ void OnVideoFrameRateChange(absl::optional<int> fps);
void OnStreamRestartCompleted();
diff --git a/chromium/media/renderers/renderer_impl_unittest.cc b/chromium/media/renderers/renderer_impl_unittest.cc
index 4ac4867400a..a7e80c0ca91 100644
--- a/chromium/media/renderers/renderer_impl_unittest.cc
+++ b/chromium/media/renderers/renderer_impl_unittest.cc
@@ -10,7 +10,6 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "base/run_loop.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/gmock_move_support.h"
@@ -21,6 +20,7 @@
#include "media/base/test_helpers.h"
#include "media/renderers/renderer_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
using ::base::test::RunCallback;
using ::base::test::RunClosure;
diff --git a/chromium/media/renderers/video_frame_yuv_converter.cc b/chromium/media/renderers/video_frame_yuv_converter.cc
index 6eded70dac3..e2f04012210 100644
--- a/chromium/media/renderers/video_frame_yuv_converter.cc
+++ b/chromium/media/renderers/video_frame_yuv_converter.cc
@@ -12,6 +12,7 @@
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "media/base/video_frame.h"
+#include "media/renderers/video_frame_yuv_mailboxes_holder.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkRefCnt.h"
@@ -26,50 +27,6 @@ namespace media {
namespace {
-SkYUVColorSpace ColorSpaceToSkYUVColorSpace(
- const gfx::ColorSpace& color_space) {
- // TODO(crbug.com/828599): This should really default to rec709.
- SkYUVColorSpace sk_color_space = kRec601_SkYUVColorSpace;
- color_space.ToSkYUVColorSpace(&sk_color_space);
- return sk_color_space;
-}
-
-viz::ResourceFormat PlaneResourceFormat(int num_channels) {
- switch (num_channels) {
- case 1:
- return viz::LUMINANCE_8;
- case 2:
- return viz::RG_88;
- case 3:
- return viz::RGBX_8888;
- case 4:
- return viz::RGBA_8888;
- }
- NOTREACHED();
- return viz::RGBA_8888;
-}
-
-GLenum PlaneGLFormat(int num_channels) {
- return viz::TextureStorageFormat(PlaneResourceFormat(num_channels));
-}
-
-std::tuple<SkYUVAInfo::PlaneConfig, SkYUVAInfo::Subsampling>
-VideoPixelFormatToSkiaValues(VideoPixelFormat video_format) {
- // To expand support for additional VideoFormats expand this switch. Note that
- // we do assume 8 bit formats. With that exception, anything else should work.
- switch (video_format) {
- case PIXEL_FORMAT_NV12:
- return {SkYUVAInfo::PlaneConfig::kY_UV, SkYUVAInfo::Subsampling::k420};
- case PIXEL_FORMAT_I420:
- return {SkYUVAInfo::PlaneConfig::kY_U_V, SkYUVAInfo::Subsampling::k420};
- case PIXEL_FORMAT_I420A:
- return {SkYUVAInfo::PlaneConfig::kY_U_V_A, SkYUVAInfo::Subsampling::k420};
- default:
- return {SkYUVAInfo::PlaneConfig::kUnknown,
- SkYUVAInfo::Subsampling::kUnknown};
- }
-}
-
SkColorType GetCompatibleSurfaceColorType(GrGLenum format) {
switch (format) {
case GL_RGBA8:
@@ -132,22 +89,6 @@ bool DrawYUVImageToSkSurface(const VideoFrame* video_frame,
return true;
}
-bool YUVGrBackendTexturesToSkSurface(
- GrDirectContext* gr_context,
- const VideoFrame* video_frame,
- const GrYUVABackendTextures& yuva_backend_textures,
- sk_sp<SkSurface> surface,
- bool use_visible_rect) {
- auto image = SkImage::MakeFromYUVATextures(gr_context, yuva_backend_textures,
- SkColorSpace::MakeSRGB());
-
- if (!image) {
- return false;
- }
-
- return DrawYUVImageToSkSurface(video_frame, image, surface, use_visible_rect);
-}
-
bool YUVPixmapsToSkSurface(GrDirectContext* gr_context,
const VideoFrame* video_frame,
const SkYUVAPixmaps yuva_pixmaps,
@@ -166,281 +107,13 @@ bool YUVPixmapsToSkSurface(GrDirectContext* gr_context,
} // namespace
-class VideoFrameYUVConverter::VideoFrameYUVMailboxesHolder {
- public:
- VideoFrameYUVMailboxesHolder() = default;
- ~VideoFrameYUVMailboxesHolder() { ReleaseCachedData(); }
-
- void ReleaseCachedData();
- void ReleaseTextures();
-
- // Extracts shared image information if |video_frame| is texture backed or
- // creates new shared images and uploads YUV data to GPU if |video_frame| is
- // mappable. This function can be called repeatedly to re-use shared images in
- // the case of CPU backed VideoFrames. The planes are returned in |mailboxes|.
- void VideoFrameToMailboxes(
- const VideoFrame* video_frame,
- viz::RasterContextProvider* raster_context_provider,
- gpu::Mailbox mailboxes[]);
-
- // Like VideoFrameToMailboxes but imports the textures from the mailboxes and
- // returns the planes as a set of YUVA GrBackendTextures.
- GrYUVABackendTextures VideoFrameToSkiaTextures(
- const VideoFrame* video_frame,
- viz::RasterContextProvider* raster_context_provider);
-
- SkYUVAPixmaps VideoFrameToSkiaPixmaps(const VideoFrame* video_frame);
-
- SkYUVAInfo::PlaneConfig plane_config() const { return plane_config_; }
-
- SkYUVAInfo::Subsampling subsampling() const { return subsampling_; }
-
- private:
- static constexpr size_t kMaxPlanes =
- static_cast<size_t>(SkYUVAInfo::kMaxPlanes);
-
- void ImportTextures();
- size_t NumPlanes() {
- return static_cast<size_t>(SkYUVAInfo::NumPlanes(plane_config_));
- }
-
- scoped_refptr<viz::RasterContextProvider> provider_;
- bool imported_textures_ = false;
- SkYUVAInfo::PlaneConfig plane_config_ = SkYUVAInfo::PlaneConfig::kUnknown;
- SkYUVAInfo::Subsampling subsampling_ = SkYUVAInfo::Subsampling::kUnknown;
- bool created_shared_images_ = false;
- gfx::Size cached_video_size_;
- gfx::ColorSpace cached_video_color_space_;
- std::array<gpu::MailboxHolder, kMaxPlanes> holders_;
-
- struct YUVPlaneTextureInfo {
- GrGLTextureInfo texture = {0, 0};
- bool is_shared_image = false;
- };
- std::array<YUVPlaneTextureInfo, kMaxPlanes> textures_;
-};
-
-void VideoFrameYUVConverter::VideoFrameYUVMailboxesHolder::ReleaseCachedData() {
- if (holders_[0].mailbox.IsZero())
- return;
-
- ReleaseTextures();
-
- // Don't destroy shared images we don't own.
- if (!created_shared_images_)
- return;
-
- auto* ri = provider_->RasterInterface();
- DCHECK(ri);
- gpu::SyncToken token;
- ri->GenUnverifiedSyncTokenCHROMIUM(token.GetData());
-
- auto* sii = provider_->SharedImageInterface();
- DCHECK(sii);
- for (auto& mailbox_holder : holders_) {
- if (!mailbox_holder.mailbox.IsZero())
- sii->DestroySharedImage(token, mailbox_holder.mailbox);
- mailbox_holder.mailbox.SetZero();
- }
-
- created_shared_images_ = false;
-}
-
-void VideoFrameYUVConverter::VideoFrameYUVMailboxesHolder::
- VideoFrameToMailboxes(const VideoFrame* video_frame,
- viz::RasterContextProvider* raster_context_provider,
- gpu::Mailbox mailboxes[]) {
- std::tie(plane_config_, subsampling_) =
- VideoPixelFormatToSkiaValues(video_frame->format());
- DCHECK_NE(plane_config_, SkYUVAInfo::PlaneConfig::kUnknown);
-
- // If we have cached shared images but the provider or video has changed we
- // need to release shared images created on the old context and recreate them.
- if (created_shared_images_ &&
- (provider_.get() != raster_context_provider ||
- video_frame->coded_size() != cached_video_size_ ||
- video_frame->ColorSpace() != cached_video_color_space_))
- ReleaseCachedData();
- provider_ = raster_context_provider;
- DCHECK(provider_);
- auto* ri = provider_->RasterInterface();
- DCHECK(ri);
-
- gfx::Size video_size = video_frame->coded_size();
- SkISize plane_sizes[SkYUVAInfo::kMaxPlanes];
- size_t num_planes = SkYUVAInfo::PlaneDimensions(
- {video_size.width(), video_size.height()}, plane_config_, subsampling_,
- kTopLeft_SkEncodedOrigin, plane_sizes);
-
- if (video_frame->HasTextures()) {
- DCHECK_EQ(num_planes, video_frame->NumTextures());
- for (size_t plane = 0; plane < video_frame->NumTextures(); ++plane) {
- holders_[plane] = video_frame->mailbox_holder(plane);
- DCHECK(holders_[plane].texture_target == GL_TEXTURE_2D ||
- holders_[plane].texture_target == GL_TEXTURE_EXTERNAL_OES ||
- holders_[plane].texture_target == GL_TEXTURE_RECTANGLE_ARB)
- << "Unsupported texture target " << std::hex << std::showbase
- << holders_[plane].texture_target;
- ri->WaitSyncTokenCHROMIUM(holders_[plane].sync_token.GetConstData());
- mailboxes[plane] = holders_[plane].mailbox;
- }
- } else {
- if (!created_shared_images_) {
- auto* sii = provider_->SharedImageInterface();
- DCHECK(sii);
- uint32_t mailbox_usage;
- if (provider_->ContextCapabilities().supports_oop_raster) {
- mailbox_usage = gpu::SHARED_IMAGE_USAGE_RASTER |
- gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
- } else {
- mailbox_usage = gpu::SHARED_IMAGE_USAGE_GLES2;
- }
- for (size_t plane = 0; plane < num_planes; ++plane) {
- gfx::Size tex_size = {plane_sizes[plane].width(),
- plane_sizes[plane].height()};
- int num_channels = SkYUVAInfo::NumChannelsInPlane(plane_config_, plane);
- viz::ResourceFormat format = PlaneResourceFormat(num_channels);
- holders_[plane].mailbox = sii->CreateSharedImage(
- format, tex_size, video_frame->ColorSpace(),
- kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, mailbox_usage,
- gpu::kNullSurfaceHandle);
- holders_[plane].texture_target = GL_TEXTURE_2D;
- }
-
- // Split up shared image creation from upload so we only have to wait on
- // one sync token.
- ri->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());
-
- cached_video_size_ = video_frame->coded_size();
- cached_video_color_space_ = video_frame->ColorSpace();
- created_shared_images_ = true;
- }
-
- // If we have cached shared images that have been imported release them to
- // prevent writing to a shared image for which we're holding read access.
- ReleaseTextures();
-
- for (size_t plane = 0; plane < num_planes; ++plane) {
- int num_channels = SkYUVAInfo::NumChannelsInPlane(plane_config_, plane);
- SkColorType color_type = SkYUVAPixmapInfo::DefaultColorTypeForDataType(
- SkYUVAPixmaps::DataType::kUnorm8, num_channels);
- SkImageInfo info = SkImageInfo::Make(plane_sizes[plane], color_type,
- kUnknown_SkAlphaType);
- ri->WritePixels(holders_[plane].mailbox, 0, 0, GL_TEXTURE_2D,
- video_frame->stride(plane), info,
- video_frame->data(plane));
- mailboxes[plane] = holders_[plane].mailbox;
- }
- }
-}
-
-GrYUVABackendTextures
-VideoFrameYUVConverter::VideoFrameYUVMailboxesHolder::VideoFrameToSkiaTextures(
- const VideoFrame* video_frame,
- viz::RasterContextProvider* raster_context_provider) {
- gpu::Mailbox mailboxes[kMaxPlanes];
- VideoFrameToMailboxes(video_frame, raster_context_provider, mailboxes);
- ImportTextures();
- SkISize video_size{video_frame->coded_size().width(),
- video_frame->coded_size().height()};
- SkYUVAInfo yuva_info(video_size, plane_config_, subsampling_,
- ColorSpaceToSkYUVColorSpace(video_frame->ColorSpace()));
- GrBackendTexture backend_textures[SkYUVAInfo::kMaxPlanes];
- SkISize plane_sizes[SkYUVAInfo::kMaxPlanes];
- int num_planes = yuva_info.planeDimensions(plane_sizes);
- for (int i = 0; i < num_planes; ++i) {
- backend_textures[i] = {plane_sizes[i].width(), plane_sizes[i].height(),
- GrMipmapped::kNo, textures_[i].texture};
- }
- return GrYUVABackendTextures(yuva_info, backend_textures,
- kTopLeft_GrSurfaceOrigin);
-}
-
-SkYUVAPixmaps
-VideoFrameYUVConverter::VideoFrameYUVMailboxesHolder::VideoFrameToSkiaPixmaps(
- const VideoFrame* video_frame) {
- std::tie(plane_config_, subsampling_) =
- VideoPixelFormatToSkiaValues(video_frame->format());
- DCHECK_NE(plane_config_, SkYUVAInfo::PlaneConfig::kUnknown);
-
- SkISize video_size{video_frame->coded_size().width(),
- video_frame->coded_size().height()};
- SkYUVAInfo yuva_info(video_size, plane_config_, subsampling_,
- ColorSpaceToSkYUVColorSpace(video_frame->ColorSpace()));
- SkPixmap pixmaps[SkYUVAInfo::kMaxPlanes];
- SkISize plane_sizes[SkYUVAInfo::kMaxPlanes];
- int num_planes = yuva_info.planeDimensions(plane_sizes);
-
- // Create SkImageInfos with the appropriate color types for 8 bit unorm data
- // based on plane config.
- size_t row_bytes[kMaxPlanes];
- for (int i = 0; i < num_planes; ++i) {
- row_bytes[i] =
- VideoFrame::RowBytes(i, video_frame->format(), plane_sizes[i].width());
- }
-
- SkYUVAPixmapInfo pixmaps_infos(yuva_info, SkYUVAPixmaps::DataType::kUnorm8,
- row_bytes);
-
- for (int i = 0; i < num_planes; ++i) {
- pixmaps[i].reset(pixmaps_infos.planeInfo(i), video_frame->data(i),
- pixmaps_infos.rowBytes(i));
- }
-
- return SkYUVAPixmaps::FromExternalPixmaps(yuva_info, pixmaps);
-}
-
-void VideoFrameYUVConverter::VideoFrameYUVMailboxesHolder::ImportTextures() {
- DCHECK(!imported_textures_)
- << "Textures should always be released after converting video frame. "
- "Call ReleaseTextures() for each call to VideoFrameToSkiaTextures()";
-
- auto* ri = provider_->RasterInterface();
- for (size_t plane = 0; plane < NumPlanes(); ++plane) {
- textures_[plane].texture.fID =
- ri->CreateAndConsumeForGpuRaster(holders_[plane].mailbox);
- if (holders_[plane].mailbox.IsSharedImage()) {
- textures_[plane].is_shared_image = true;
- ri->BeginSharedImageAccessDirectCHROMIUM(
- textures_[plane].texture.fID,
- GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
- }
-
- int num_channels = SkYUVAInfo::NumChannelsInPlane(plane_config_, plane);
- textures_[plane].texture.fTarget = holders_[plane].texture_target;
- textures_[plane].texture.fFormat = PlaneGLFormat(num_channels);
- }
-
- imported_textures_ = true;
-}
-
-void VideoFrameYUVConverter::VideoFrameYUVMailboxesHolder::ReleaseTextures() {
- if (!imported_textures_)
- return;
-
- auto* ri = provider_->RasterInterface();
- DCHECK(ri);
- for (auto& tex_info : textures_) {
- if (!tex_info.texture.fID)
- continue;
-
- if (tex_info.is_shared_image)
- ri->EndSharedImageAccessDirectCHROMIUM(tex_info.texture.fID);
- ri->DeleteGpuRasterTexture(tex_info.texture.fID);
-
- tex_info.texture.fID = 0;
- }
-
- imported_textures_ = false;
-}
-
VideoFrameYUVConverter::VideoFrameYUVConverter() = default;
VideoFrameYUVConverter::~VideoFrameYUVConverter() = default;
bool VideoFrameYUVConverter::IsVideoFrameFormatSupported(
const VideoFrame& video_frame) {
- return std::get<0>(VideoPixelFormatToSkiaValues(video_frame.format())) !=
- SkYUVAInfo::PlaneConfig::kUnknown;
+ return std::get<0>(VideoFrameYUVMailboxesHolder::VideoPixelFormatToSkiaValues(
+ video_frame.format())) != SkYUVAInfo::PlaneConfig::kUnknown;
}
bool VideoFrameYUVConverter::ConvertYUVVideoFrameNoCaching(
@@ -481,15 +154,14 @@ bool VideoFrameYUVConverter::ConvertYUVVideoFrame(
auto* ri = raster_context_provider->RasterInterface();
DCHECK(ri);
ri->WaitSyncTokenCHROMIUM(dest_mailbox_holder.sync_token.GetConstData());
- SkYUVColorSpace color_space =
- ColorSpaceToSkYUVColorSpace(video_frame->ColorSpace());
gpu::Mailbox mailboxes[SkYUVAInfo::kMaxPlanes]{};
holder_->VideoFrameToMailboxes(video_frame, raster_context_provider,
mailboxes);
- ri->ConvertYUVAMailboxesToRGB(dest_mailbox_holder.mailbox, color_space,
- holder_->plane_config(), holder_->subsampling(),
- mailboxes);
+ ri->ConvertYUVAMailboxesToRGB(dest_mailbox_holder.mailbox,
+ holder_->yuva_info().yuvColorSpace(),
+ holder_->yuva_info().planeConfig(),
+ holder_->yuva_info().subsampling(), mailboxes);
return true;
}
@@ -594,13 +266,11 @@ bool VideoFrameYUVConverter::ConvertFromVideoFrameYUVSkia(
result = YUVPixmapsToSkSurface(gr_context, video_frame, yuva_pixmaps,
surface, use_visible_rect);
} else {
- GrYUVABackendTextures yuva_backend_textures =
- holder_->VideoFrameToSkiaTextures(video_frame, raster_context_provider);
- DCHECK(yuva_backend_textures.isValid());
+ auto image =
+ holder_->VideoFrameToSkImage(video_frame, raster_context_provider);
+ result =
+ DrawYUVImageToSkSurface(video_frame, image, surface, use_visible_rect);
- result = YUVGrBackendTexturesToSkSurface(gr_context, video_frame,
- yuva_backend_textures, surface,
- use_visible_rect);
// Release textures to guarantee |holder_| doesn't hold read access on
// textures it doesn't own.
holder_->ReleaseTextures();
diff --git a/chromium/media/renderers/video_frame_yuv_converter.h b/chromium/media/renderers/video_frame_yuv_converter.h
index c8e761fece9..c7f4759e212 100644
--- a/chromium/media/renderers/video_frame_yuv_converter.h
+++ b/chromium/media/renderers/video_frame_yuv_converter.h
@@ -20,6 +20,7 @@ class RasterContextProvider;
namespace media {
class VideoFrame;
+class VideoFrameYUVMailboxesHolder;
// Converts YUV video frames to RGB format and stores the results in the
// provided mailbox. The caller of functions in this class maintains ownership
@@ -87,9 +88,8 @@ class MEDIA_EXPORT VideoFrameYUVConverter {
bool use_visible_rect,
bool use_sk_pixmap);
- class VideoFrameYUVMailboxesHolder;
std::unique_ptr<VideoFrameYUVMailboxesHolder> holder_;
};
} // namespace media
-#endif // MEDIA_RENDERERS_VIDEO_FRAME_YUV_CONVERTER_H_ \ No newline at end of file
+#endif // MEDIA_RENDERERS_VIDEO_FRAME_YUV_CONVERTER_H_
diff --git a/chromium/media/renderers/video_frame_yuv_mailboxes_holder.cc b/chromium/media/renderers/video_frame_yuv_mailboxes_holder.cc
new file mode 100644
index 00000000000..495a96081be
--- /dev/null
+++ b/chromium/media/renderers/video_frame_yuv_mailboxes_holder.cc
@@ -0,0 +1,346 @@
+// Copyright 2021 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 "media/renderers/video_frame_yuv_mailboxes_holder.h"
+
+#include <GLES3/gl3.h>
+
+#include "base/logging.h"
+#include "components/viz/common/gpu/raster_context_provider.h"
+#include "components/viz/common/resources/resource_format_utils.h"
+#include "gpu/GLES2/gl2extchromium.h"
+#include "gpu/command_buffer/client/raster_interface.h"
+#include "gpu/command_buffer/client/shared_image_interface.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
+#include "third_party/skia/include/core/SkImage.h"
+#include "third_party/skia/include/core/SkSurface.h"
+#include "third_party/skia/include/core/SkYUVAPixmaps.h"
+#include "third_party/skia/include/gpu/GrDirectContext.h"
+#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
+
+namespace media {
+
+namespace {
+
+viz::ResourceFormat PlaneResourceFormat(int num_channels, bool for_surface) {
+ switch (num_channels) {
+ case 1:
+ return for_surface ? viz::RED_8 : viz::LUMINANCE_8;
+ case 2:
+ return viz::RG_88;
+ case 3:
+ return viz::RGBX_8888;
+ case 4:
+ return viz::RGBA_8888;
+ }
+ NOTREACHED();
+ return viz::RGBA_8888;
+}
+
+GLenum PlaneGLFormat(int num_channels, bool for_surface) {
+ return viz::TextureStorageFormat(
+ PlaneResourceFormat(num_channels, for_surface));
+}
+
+} // namespace
+
+VideoFrameYUVMailboxesHolder::VideoFrameYUVMailboxesHolder() = default;
+
+VideoFrameYUVMailboxesHolder::~VideoFrameYUVMailboxesHolder() {
+ ReleaseCachedData();
+}
+
+void VideoFrameYUVMailboxesHolder::ReleaseCachedData() {
+ if (holders_[0].mailbox.IsZero())
+ return;
+
+ ReleaseTextures();
+
+ // Don't destroy shared images we don't own.
+ if (!created_shared_images_)
+ return;
+
+ auto* ri = provider_->RasterInterface();
+ DCHECK(ri);
+ gpu::SyncToken token;
+ ri->GenUnverifiedSyncTokenCHROMIUM(token.GetData());
+
+ auto* sii = provider_->SharedImageInterface();
+ DCHECK(sii);
+ for (auto& mailbox_holder : holders_) {
+ if (!mailbox_holder.mailbox.IsZero())
+ sii->DestroySharedImage(token, mailbox_holder.mailbox);
+ mailbox_holder.mailbox.SetZero();
+ }
+
+ created_shared_images_ = false;
+}
+
+void VideoFrameYUVMailboxesHolder::VideoFrameToMailboxes(
+ const VideoFrame* video_frame,
+ viz::RasterContextProvider* raster_context_provider,
+ gpu::Mailbox mailboxes[SkYUVAInfo::kMaxPlanes]) {
+ yuva_info_ = VideoFrameGetSkYUVAInfo(video_frame);
+ num_planes_ = yuva_info_.planeDimensions(plane_sizes_);
+
+ // If we have cached shared images but the provider or video has changed we
+ // need to release shared images created on the old context and recreate them.
+ if (created_shared_images_ &&
+ (provider_.get() != raster_context_provider ||
+ video_frame->coded_size() != cached_video_size_ ||
+ video_frame->ColorSpace() != cached_video_color_space_)) {
+ ReleaseCachedData();
+ }
+ provider_ = raster_context_provider;
+ DCHECK(provider_);
+ auto* ri = provider_->RasterInterface();
+ DCHECK(ri);
+
+ if (video_frame->HasTextures()) {
+ DCHECK_EQ(num_planes_, video_frame->NumTextures());
+ for (size_t plane = 0; plane < video_frame->NumTextures(); ++plane) {
+ holders_[plane] = video_frame->mailbox_holder(plane);
+ DCHECK(holders_[plane].texture_target == GL_TEXTURE_2D ||
+ holders_[plane].texture_target == GL_TEXTURE_EXTERNAL_OES ||
+ holders_[plane].texture_target == GL_TEXTURE_RECTANGLE_ARB)
+ << "Unsupported texture target " << std::hex << std::showbase
+ << holders_[plane].texture_target;
+ ri->WaitSyncTokenCHROMIUM(holders_[plane].sync_token.GetConstData());
+ mailboxes[plane] = holders_[plane].mailbox;
+ }
+ return;
+ }
+
+ // Create a shared image to upload the data to, if one doesn't exist already.
+ if (!created_shared_images_) {
+ auto* sii = provider_->SharedImageInterface();
+ DCHECK(sii);
+ uint32_t mailbox_usage;
+ if (provider_->ContextCapabilities().supports_oop_raster) {
+ mailbox_usage = gpu::SHARED_IMAGE_USAGE_RASTER |
+ gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
+ } else {
+ mailbox_usage = gpu::SHARED_IMAGE_USAGE_GLES2;
+ }
+ for (size_t plane = 0; plane < num_planes_; ++plane) {
+ gfx::Size tex_size = {plane_sizes_[plane].width(),
+ plane_sizes_[plane].height()};
+ int num_channels = yuva_info_.numChannelsInPlane(plane);
+ viz::ResourceFormat format = PlaneResourceFormat(num_channels, false);
+ holders_[plane].mailbox = sii->CreateSharedImage(
+ format, tex_size, video_frame->ColorSpace(), kTopLeft_GrSurfaceOrigin,
+ kPremul_SkAlphaType, mailbox_usage, gpu::kNullSurfaceHandle);
+ holders_[plane].texture_target = GL_TEXTURE_2D;
+ }
+
+ // Split up shared image creation from upload so we only have to wait on
+ // one sync token.
+ ri->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());
+
+ cached_video_size_ = video_frame->coded_size();
+ cached_video_color_space_ = video_frame->ColorSpace();
+ created_shared_images_ = true;
+ }
+
+ // If we have cached shared images that have been imported release them to
+ // prevent writing to a shared image for which we're holding read access.
+ ReleaseTextures();
+
+ for (size_t plane = 0; plane < num_planes_; ++plane) {
+ int num_channels = yuva_info_.numChannelsInPlane(plane);
+ SkColorType color_type = SkYUVAPixmapInfo::DefaultColorTypeForDataType(
+ SkYUVAPixmaps::DataType::kUnorm8, num_channels);
+ SkImageInfo info = SkImageInfo::Make(plane_sizes_[plane], color_type,
+ kUnknown_SkAlphaType);
+ ri->WritePixels(holders_[plane].mailbox, 0, 0, GL_TEXTURE_2D,
+ video_frame->stride(plane), info, video_frame->data(plane));
+ mailboxes[plane] = holders_[plane].mailbox;
+ }
+}
+
+GrYUVABackendTextures VideoFrameYUVMailboxesHolder::VideoFrameToSkiaTextures(
+ const VideoFrame* video_frame,
+ viz::RasterContextProvider* raster_context_provider,
+ bool for_surface) {
+ gpu::Mailbox mailboxes[kMaxPlanes];
+ VideoFrameToMailboxes(video_frame, raster_context_provider, mailboxes);
+ ImportTextures(for_surface);
+ GrBackendTexture backend_textures[SkYUVAInfo::kMaxPlanes];
+ for (size_t plane = 0; plane < num_planes_; ++plane) {
+ backend_textures[plane] = {plane_sizes_[plane].width(),
+ plane_sizes_[plane].height(), GrMipmapped::kNo,
+ textures_[plane].texture};
+ }
+ return GrYUVABackendTextures(yuva_info_, backend_textures,
+ kTopLeft_GrSurfaceOrigin);
+}
+
+sk_sp<SkImage> VideoFrameYUVMailboxesHolder::VideoFrameToSkImage(
+ const VideoFrame* video_frame,
+ viz::RasterContextProvider* raster_context_provider) {
+ GrDirectContext* gr_context = raster_context_provider->GrContext();
+ DCHECK(gr_context);
+
+ GrYUVABackendTextures yuva_backend_textures = VideoFrameToSkiaTextures(
+ video_frame, raster_context_provider, /*for_surface=*/false);
+
+ DCHECK(yuva_backend_textures.isValid());
+ auto result = SkImage::MakeFromYUVATextures(gr_context, yuva_backend_textures,
+ SkColorSpace::MakeSRGB());
+ DCHECK(result);
+ return result;
+}
+
+bool VideoFrameYUVMailboxesHolder::VideoFrameToPlaneSkSurfaces(
+ const VideoFrame* video_frame,
+ viz::RasterContextProvider* raster_context_provider,
+ sk_sp<SkSurface> surfaces[SkYUVAInfo::kMaxPlanes]) {
+ for (size_t plane = 0; plane < SkYUVAInfo::kMaxPlanes; ++plane)
+ surfaces[plane] = nullptr;
+
+ if (!video_frame->HasTextures()) {
+ // The below call to VideoFrameToSkiaTextures would blit |video_frame| into
+ // a temporary SharedImage, which would be exposed as a SkSurface. That is
+ // probably undesirable (it has no current use cases), so just return an
+ // error.
+ DLOG(ERROR) << "VideoFrameToPlaneSkSurfaces requires texture backing.";
+ return false;
+ }
+
+ GrDirectContext* gr_context = raster_context_provider->GrContext();
+ DCHECK(gr_context);
+ GrYUVABackendTextures yuva_backend_textures = VideoFrameToSkiaTextures(
+ video_frame, raster_context_provider, /*for_surface=*/true);
+
+ bool result = true;
+ for (size_t plane = 0; plane < num_planes_; ++plane) {
+ const int num_channels = yuva_info_.numChannelsInPlane(plane);
+ SkColorType color_type = SkYUVAPixmapInfo::DefaultColorTypeForDataType(
+ SkYUVAPixmaps::DataType::kUnorm8, num_channels);
+ // Gray is not renderable.
+ if (color_type == kGray_8_SkColorType)
+ color_type = kAlpha_8_SkColorType;
+
+ auto surface = SkSurface::MakeFromBackendTexture(
+ gr_context, yuva_backend_textures.texture(plane),
+ kTopLeft_GrSurfaceOrigin, /*sampleCnt=*/1, color_type,
+ SkColorSpace::MakeSRGB(), nullptr);
+ if (!surface) {
+ DLOG(ERROR)
+ << "VideoFrameToPlaneSkSurfaces failed to make surface for plane "
+ << plane << " of " << num_planes_ << ".";
+ result = false;
+ }
+ surfaces[plane] = surface;
+ }
+ return result;
+}
+
+SkYUVAPixmaps VideoFrameYUVMailboxesHolder::VideoFrameToSkiaPixmaps(
+ const VideoFrame* video_frame) {
+ yuva_info_ = VideoFrameGetSkYUVAInfo(video_frame);
+ num_planes_ = yuva_info_.planeDimensions(plane_sizes_);
+
+ // Create SkImageInfos with the appropriate color types for 8 bit unorm data
+ // based on plane config.
+ size_t row_bytes[kMaxPlanes];
+ for (size_t plane = 0; plane < num_planes_; ++plane) {
+ row_bytes[plane] = VideoFrame::RowBytes(plane, video_frame->format(),
+ plane_sizes_[plane].width());
+ }
+
+ SkYUVAPixmapInfo pixmaps_infos(yuva_info_, SkYUVAPixmaps::DataType::kUnorm8,
+ row_bytes);
+ SkPixmap pixmaps[SkYUVAInfo::kMaxPlanes];
+ for (size_t plane = 0; plane < num_planes_; ++plane) {
+ pixmaps[plane].reset(pixmaps_infos.planeInfo(plane),
+ video_frame->data(plane),
+ pixmaps_infos.rowBytes(plane));
+ }
+ return SkYUVAPixmaps::FromExternalPixmaps(yuva_info_, pixmaps);
+}
+
+void VideoFrameYUVMailboxesHolder::ImportTextures(bool for_surface) {
+ DCHECK(!imported_textures_)
+ << "Textures should always be released after converting video frame. "
+ "Call ReleaseTextures() for each call to VideoFrameToSkiaTextures()";
+
+ auto* ri = provider_->RasterInterface();
+ for (size_t plane = 0; plane < num_planes_; ++plane) {
+ textures_[plane].texture.fID =
+ ri->CreateAndConsumeForGpuRaster(holders_[plane].mailbox);
+ if (holders_[plane].mailbox.IsSharedImage()) {
+ textures_[plane].is_shared_image = true;
+ ri->BeginSharedImageAccessDirectCHROMIUM(
+ textures_[plane].texture.fID,
+ for_surface ? GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM
+ : GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
+ } else {
+ textures_[plane].is_shared_image = false;
+ }
+
+ int num_channels = yuva_info_.numChannelsInPlane(plane);
+ textures_[plane].texture.fTarget = holders_[plane].texture_target;
+ textures_[plane].texture.fFormat = PlaneGLFormat(num_channels, for_surface);
+ }
+
+ imported_textures_ = true;
+}
+
+void VideoFrameYUVMailboxesHolder::ReleaseTextures() {
+ if (!imported_textures_)
+ return;
+
+ auto* ri = provider_->RasterInterface();
+ DCHECK(ri);
+ for (auto& tex_info : textures_) {
+ if (!tex_info.texture.fID)
+ continue;
+
+ if (tex_info.is_shared_image)
+ ri->EndSharedImageAccessDirectCHROMIUM(tex_info.texture.fID);
+ ri->DeleteGpuRasterTexture(tex_info.texture.fID);
+
+ tex_info.texture.fID = 0;
+ }
+
+ imported_textures_ = false;
+}
+
+// static
+std::tuple<SkYUVAInfo::PlaneConfig, SkYUVAInfo::Subsampling>
+VideoFrameYUVMailboxesHolder::VideoPixelFormatToSkiaValues(
+ VideoPixelFormat video_format) {
+ // To expand support for additional VideoFormats expand this switch. Note that
+ // we do assume 8 bit formats. With that exception, anything else should work.
+ switch (video_format) {
+ case PIXEL_FORMAT_NV12:
+ return {SkYUVAInfo::PlaneConfig::kY_UV, SkYUVAInfo::Subsampling::k420};
+ case PIXEL_FORMAT_I420:
+ return {SkYUVAInfo::PlaneConfig::kY_U_V, SkYUVAInfo::Subsampling::k420};
+ case PIXEL_FORMAT_I420A:
+ return {SkYUVAInfo::PlaneConfig::kY_U_V_A, SkYUVAInfo::Subsampling::k420};
+ default:
+ return {SkYUVAInfo::PlaneConfig::kUnknown,
+ SkYUVAInfo::Subsampling::kUnknown};
+ }
+}
+
+// static
+SkYUVAInfo VideoFrameYUVMailboxesHolder::VideoFrameGetSkYUVAInfo(
+ const VideoFrame* video_frame) {
+ SkISize video_size{video_frame->coded_size().width(),
+ video_frame->coded_size().height()};
+ auto plane_config = SkYUVAInfo::PlaneConfig::kUnknown;
+ auto subsampling = SkYUVAInfo::Subsampling::kUnknown;
+ std::tie(plane_config, subsampling) =
+ VideoPixelFormatToSkiaValues(video_frame->format());
+
+ // TODO(crbug.com/828599): This should really default to rec709.
+ SkYUVColorSpace color_space = kRec601_SkYUVColorSpace;
+ video_frame->ColorSpace().ToSkYUVColorSpace(&color_space);
+ return SkYUVAInfo(video_size, plane_config, subsampling, color_space);
+}
+
+} // namespace media
diff --git a/chromium/media/renderers/video_frame_yuv_mailboxes_holder.h b/chromium/media/renderers/video_frame_yuv_mailboxes_holder.h
new file mode 100644
index 00000000000..5a1e51ba226
--- /dev/null
+++ b/chromium/media/renderers/video_frame_yuv_mailboxes_holder.h
@@ -0,0 +1,99 @@
+// Copyright 2021 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 MEDIA_RENDERERS_VIDEO_FRAME_YUV_MAILBOXES_HOLDER_H_
+#define MEDIA_RENDERERS_VIDEO_FRAME_YUV_MAILBOXES_HOLDER_H_
+
+#include "media/base/media_export.h"
+#include "media/base/video_frame.h"
+#include "third_party/skia/include/core/SkYUVAInfo.h"
+#include "third_party/skia/include/gpu/GrYUVABackendTextures.h"
+#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
+
+namespace viz {
+class RasterContextProvider;
+} // namespace viz
+
+namespace media {
+
+class MEDIA_EXPORT VideoFrameYUVMailboxesHolder {
+ public:
+ VideoFrameYUVMailboxesHolder();
+ ~VideoFrameYUVMailboxesHolder();
+
+ void ReleaseCachedData();
+ void ReleaseTextures();
+
+ // Extracts shared image information if |video_frame| is texture backed or
+ // creates new shared images and uploads YUV data to GPU if |video_frame| is
+ // mappable. This function can be called repeatedly to re-use shared images in
+ // the case of CPU backed VideoFrames. The planes are returned in |mailboxes|.
+ void VideoFrameToMailboxes(
+ const VideoFrame* video_frame,
+ viz::RasterContextProvider* raster_context_provider,
+ gpu::Mailbox mailboxes[SkYUVAInfo::kMaxPlanes]);
+
+ // Returns a YUV SkImage for the specified video frame.
+ sk_sp<SkImage> VideoFrameToSkImage(
+ const VideoFrame* video_frame,
+ viz::RasterContextProvider* raster_context_provider);
+
+ // Creates SkSurfaces for each plane for the specified video frame. Returns
+ // true only if surfaces for all planes were created.
+ bool VideoFrameToPlaneSkSurfaces(
+ const VideoFrame* video_frame,
+ viz::RasterContextProvider* raster_context_provider,
+ sk_sp<SkSurface> surfaces[SkYUVAInfo::kMaxPlanes]);
+
+ SkYUVAPixmaps VideoFrameToSkiaPixmaps(const VideoFrame* video_frame);
+
+ const SkYUVAInfo& yuva_info() const { return yuva_info_; }
+
+ // Utility to convert a media pixel format to SkYUVAInfo.
+ static std::tuple<SkYUVAInfo::PlaneConfig, SkYUVAInfo::Subsampling>
+ VideoPixelFormatToSkiaValues(VideoPixelFormat video_format);
+
+ // Utility to populate a SkYUVAInfo from a video frame.
+ static SkYUVAInfo VideoFrameGetSkYUVAInfo(const VideoFrame* video_frame);
+
+ private:
+ static constexpr size_t kMaxPlanes =
+ static_cast<size_t>(SkYUVAInfo::kMaxPlanes);
+
+ // Like VideoFrameToMailboxes but imports the textures from the mailboxes and
+ // returns the planes as a set of YUVA GrBackendTextures. If |for_surface| is
+ // true, then select color types and pixel formats that are renderable as
+ // SkSurfaces.
+ GrYUVABackendTextures VideoFrameToSkiaTextures(
+ const VideoFrame* video_frame,
+ viz::RasterContextProvider* raster_context_provider,
+ bool for_surface);
+
+ void ImportTextures(bool for_surface);
+
+ scoped_refptr<viz::RasterContextProvider> provider_;
+ bool imported_textures_ = false;
+ bool created_shared_images_ = false;
+ gfx::Size cached_video_size_;
+ gfx::ColorSpace cached_video_color_space_;
+
+ // The properties of the most recently received video frame.
+ size_t num_planes_ = 0;
+ SkYUVAInfo yuva_info_;
+ SkISize plane_sizes_[SkYUVAInfo::kMaxPlanes];
+
+ // Populated by VideoFrameToMailboxes.
+ std::array<gpu::MailboxHolder, kMaxPlanes> holders_;
+
+ // Populated by ImportTextures.
+ struct YUVPlaneTextureInfo {
+ GrGLTextureInfo texture = {0, 0};
+ bool is_shared_image = false;
+ };
+ std::array<YUVPlaneTextureInfo, kMaxPlanes> textures_;
+};
+
+} // namespace media
+
+#endif // MEDIA_RENDERERS_VIDEO_FRAME_YUV_MAILBOXES_HOLDER_H_
diff --git a/chromium/media/renderers/video_renderer_impl.cc b/chromium/media/renderers/video_renderer_impl.cc
index c67759babb7..83497d5bdd2 100644
--- a/chromium/media/renderers/video_renderer_impl.cc
+++ b/chromium/media/renderers/video_renderer_impl.cc
@@ -466,7 +466,7 @@ void VideoRendererImpl::OnTimeStopped() {
}
void VideoRendererImpl::SetLatencyHint(
- base::Optional<base::TimeDelta> latency_hint) {
+ absl::optional<base::TimeDelta> latency_hint) {
base::AutoLock auto_lock(lock_);
latency_hint_ = latency_hint;
@@ -829,7 +829,7 @@ void VideoRendererImpl::ReportFrameRateIfNeeded_Locked() {
DCHECK(task_runner_->BelongsToCurrentThread());
lock_.AssertAcquired();
- base::Optional<int> current_fps = fps_estimator_.ComputeFPS();
+ absl::optional<int> current_fps = fps_estimator_.ComputeFPS();
if (last_reported_fps_ && current_fps &&
*last_reported_fps_ == *current_fps) {
// Reported an FPS before, and it hasn't changed.
diff --git a/chromium/media/renderers/video_renderer_impl.h b/chromium/media/renderers/video_renderer_impl.h
index 524fa1f748e..00c4d08743f 100644
--- a/chromium/media/renderers/video_renderer_impl.h
+++ b/chromium/media/renderers/video_renderer_impl.h
@@ -73,7 +73,7 @@ class MEDIA_EXPORT VideoRendererImpl
void StartPlayingFrom(base::TimeDelta timestamp) override;
void OnTimeProgressing() override;
void OnTimeStopped() override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void SetTickClockForTesting(const base::TickClock* tick_clock);
size_t frames_queued_for_testing() const {
@@ -338,11 +338,11 @@ class MEDIA_EXPORT VideoRendererImpl
FrameRateEstimator fps_estimator_;
// Last FPS, if any, reported to the client.
- base::Optional<int> last_reported_fps_;
+ absl::optional<int> last_reported_fps_;
// Value saved from last call to SetLatencyHint(). Used to recompute buffering
// limits as framerate fluctuates.
- base::Optional<base::TimeDelta> latency_hint_;
+ absl::optional<base::TimeDelta> latency_hint_;
// When latency_hint_ > 0, we make regular adjustments to buffering caps as
// |algorithm_->average_frame_duration()| fluctuates, but we only want to emit
diff --git a/chromium/media/renderers/video_renderer_impl_unittest.cc b/chromium/media/renderers/video_renderer_impl_unittest.cc
index 7fd1b5f80a5..d5f94b32cfd 100644
--- a/chromium/media/renderers/video_renderer_impl_unittest.cc
+++ b/chromium/media/renderers/video_renderer_impl_unittest.cc
@@ -635,7 +635,7 @@ TEST_F(VideoRendererImplTest, StartPlayingFrom_RightBefore) {
EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
- EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(base::Optional<int>(100)));
+ EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(100)));
StartPlayingFrom(59);
Destroy();
}
@@ -649,7 +649,7 @@ TEST_F(VideoRendererImplTest, StartPlayingFrom_RightAfter) {
EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
- EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(base::Optional<int>(100)));
+ EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(100)));
StartPlayingFrom(61);
Destroy();
}
@@ -1150,12 +1150,12 @@ TEST_F(VideoRendererImplTest, VideoFrameRateChange) {
EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
// Send 50fps frames first.
- EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(base::Optional<int>(50)));
+ EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(50)));
QueueFrames("0 20 40 60 80 100 120 140 160 180 200");
QueueFrames("220 240 260 280 300 320 340 360 380 400");
// Also queue some frames that aren't at 50fps, so that we get an unknown fps.
- EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(base::Optional<int>()));
+ EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>()));
QueueFrames("500 600");
// Drain everything.
@@ -1376,7 +1376,7 @@ TEST_P(UnderflowTest, UnderflowAndRecoverTest) {
// the have enough state.
case UnderflowTestType::NORMAL:
QueueFrames("80 100 120 140 160");
- EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(base::Optional<int>(50)));
+ EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(50)));
break;
// In either of these modes the HAVE_ENOUGH transition should still
// occur with a single frame.
@@ -1483,7 +1483,7 @@ TEST_F(VideoRendererLatencyHintTest, HaveEnough_LowLatencyHint) {
EXPECT_EQ(renderer_->frames_queued_for_testing(), 4u);
// Unset latencyHint, to verify default behavior.
- renderer_->SetLatencyHint(base::nullopt);
+ renderer_->SetLatencyHint(absl::nullopt);
// Flush to return to clean slate.
EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _));
@@ -1518,7 +1518,7 @@ TEST_F(VideoRendererLatencyHintTest, HaveEnough_HighLatencyHint) {
// Queue 12 frames, each 30 ms apart. At this framerate, 400ms rounds to 13
// frames, so 12 frames should be 1 shy of the HaveEnough threshold.
- EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(base::Optional<int>(33)));
+ EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(33)));
EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
.Times(0);
QueueFrames("0 30 60 90 120 150 180 210 240 270 300 330");
@@ -1538,7 +1538,7 @@ TEST_F(VideoRendererLatencyHintTest, HaveEnough_HighLatencyHint) {
Mock::VerifyAndClearExpectations(&mock_cb_);
// Unset latencyHint, to verify default behavior.
- renderer_->SetLatencyHint(base::nullopt);
+ renderer_->SetLatencyHint(absl::nullopt);
// Flush to return to clean slate.
EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _));
@@ -1574,7 +1574,7 @@ TEST_F(VideoRendererLatencyHintTest,
EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
- EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(base::Optional<int>(33)));
+ EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(33)));
EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
QueueFrames("0 30 60 90 120 150 180");
StartPlayingFrom(0);
@@ -1634,7 +1634,7 @@ TEST_F(VideoRendererLatencyHintTest, LatencyHintOverridesLowDelay) {
// 7 frames, so 6 frames should be 1 shy of the HaveEnough threshold. Verify
// that HAVE_ENOUGH is not triggered in spite of being initialized with low
// delay mode.
- EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(base::Optional<int>(33)));
+ EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(33)));
EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
.Times(0);
QueueFrames("0 30 60 90 120 150");
@@ -1654,7 +1654,7 @@ TEST_F(VideoRendererLatencyHintTest, LatencyHintOverridesLowDelay) {
// Unset latencyHint, to verify default behavior. NOTE: low delay mode is not
// restored when latency hint unset.
- renderer_->SetLatencyHint(base::nullopt);
+ renderer_->SetLatencyHint(absl::nullopt);
// Flush to return to clean slate.
EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _));
@@ -1711,7 +1711,7 @@ TEST_F(VideoRendererLatencyHintTest,
Mock::VerifyAndClearExpectations(&mock_cb_);
// Unset latency hint to verify 1-frame HAVE_ENOUGH threshold is maintained.
- renderer_->SetLatencyHint(base::nullopt);
+ renderer_->SetLatencyHint(absl::nullopt);
// Flush to return to clean slate.
EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _));
diff --git a/chromium/media/renderers/video_resource_updater.cc b/chromium/media/renderers/video_resource_updater.cc
index 6169cc98e13..f8af767fb27 100644
--- a/chromium/media/renderers/video_resource_updater.cc
+++ b/chromium/media/renderers/video_resource_updater.cc
@@ -13,6 +13,7 @@
#include "base/atomic_sequence_num.h"
#include "base/bind.h"
#include "base/bit_cast.h"
+#include "base/containers/contains.h"
#include "base/logging.h"
#include "base/memory/shared_memory_mapping.h"
#include "base/memory/unsafe_shared_memory_region.h"
@@ -522,8 +523,7 @@ void VideoResourceUpdater::ObtainFrameResources(
for (size_t i = 0; i < external_resources.resources.size(); ++i) {
viz::ResourceId resource_id = resource_provider_->ImportResource(
external_resources.resources[i],
- viz::SingleReleaseCallback::Create(
- std::move(external_resources.release_callbacks[i])));
+ std::move(external_resources.release_callbacks[i]));
frame_resources_.emplace_back(resource_id,
external_resources.resources[i].size);
}
@@ -545,8 +545,7 @@ void VideoResourceUpdater::AppendQuads(
gfx::Rect quad_rect,
gfx::Rect visible_quad_rect,
const gfx::MaskFilterInfo& mask_filter_info,
- gfx::Rect clip_rect,
- bool is_clipped,
+ absl::optional<gfx::Rect> clip_rect,
bool contents_opaque,
float draw_opacity,
int sorting_context_id) {
@@ -554,10 +553,9 @@ void VideoResourceUpdater::AppendQuads(
viz::SharedQuadState* shared_quad_state =
render_pass->CreateAndAppendSharedQuadState();
- shared_quad_state->SetAll(transform, quad_rect, visible_quad_rect,
- mask_filter_info, clip_rect, is_clipped,
- contents_opaque, draw_opacity,
- SkBlendMode::kSrcOver, sorting_context_id);
+ shared_quad_state->SetAll(
+ transform, quad_rect, visible_quad_rect, mask_filter_info, clip_rect,
+ contents_opaque, draw_opacity, SkBlendMode::kSrcOver, sorting_context_id);
bool needs_blending = !contents_opaque;
@@ -912,6 +910,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
mailbox, GL_LINEAR, mailbox_holder.texture_target, sync_token,
plane_size, video_frame->metadata().allow_overlay);
transfer_resource.color_space = resource_color_space;
+ transfer_resource.hdr_metadata = video_frame->hdr_metadata();
transfer_resource.read_lock_fences_enabled =
video_frame->metadata().read_lock_fences_enabled;
transfer_resource.format = viz::GetResourceFormat(buffer_formats[i]);
diff --git a/chromium/media/renderers/video_resource_updater.h b/chromium/media/renderers/video_resource_updater.h
index e23887c3fe2..d2ad861f59a 100644
--- a/chromium/media/renderers/video_resource_updater.h
+++ b/chromium/media/renderers/video_resource_updater.h
@@ -15,7 +15,6 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
#include "base/trace_event/memory_dump_provider.h"
#include "base/unguessable_token.h"
#include "components/viz/common/resources/release_callback.h"
@@ -124,8 +123,7 @@ class MEDIA_EXPORT VideoResourceUpdater
gfx::Rect quad_rect,
gfx::Rect visible_quad_rect,
const gfx::MaskFilterInfo& mask_filter_info,
- gfx::Rect clip_rect,
- bool is_clipped,
+ absl::optional<gfx::Rect> clip_rect,
bool context_opaque,
float draw_opacity,
int sorting_context_id);
diff --git a/chromium/media/renderers/video_resource_updater_unittest.cc b/chromium/media/renderers/video_resource_updater_unittest.cc
index 65814ed93cf..286a083aa4f 100644
--- a/chromium/media/renderers/video_resource_updater_unittest.cc
+++ b/chromium/media/renderers/video_resource_updater_unittest.cc
@@ -213,7 +213,7 @@ class VideoResourceUpdaterTest : public testing::Test {
}
scoped_refptr<VideoFrame> CreateTestStreamTextureHardwareVideoFrame(
- base::Optional<VideoFrameMetadata::CopyMode> copy_mode) {
+ absl::optional<VideoFrameMetadata::CopyMode> copy_mode) {
scoped_refptr<VideoFrame> video_frame = CreateTestHardwareVideoFrame(
PIXEL_FORMAT_ARGB, GL_TEXTURE_EXTERNAL_OES);
video_frame->metadata().copy_mode = std::move(copy_mode);
@@ -577,7 +577,7 @@ TEST_F(VideoResourceUpdaterTest,
CreateUpdaterForHardware(true);
EXPECT_EQ(0u, GetSharedImageCount());
scoped_refptr<VideoFrame> video_frame =
- CreateTestStreamTextureHardwareVideoFrame(base::nullopt);
+ CreateTestStreamTextureHardwareVideoFrame(absl::nullopt);
VideoFrameExternalResources resources =
updater->CreateExternalResourcesFromVideoFrame(video_frame);
@@ -608,7 +608,7 @@ TEST_F(VideoResourceUpdaterTest,
CreateUpdaterForHardware(true);
EXPECT_EQ(0u, GetSharedImageCount());
scoped_refptr<VideoFrame> video_frame =
- CreateTestStreamTextureHardwareVideoFrame(base::nullopt);
+ CreateTestStreamTextureHardwareVideoFrame(absl::nullopt);
VideoFrameExternalResources resources =
updater->CreateExternalResourcesFromVideoFrame(video_frame);
EXPECT_EQ(VideoFrameResourceType::STREAM_TEXTURE, resources.type);
@@ -637,7 +637,7 @@ TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_TextureQuad) {
std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
EXPECT_EQ(0u, GetSharedImageCount());
scoped_refptr<VideoFrame> video_frame =
- CreateTestStreamTextureHardwareVideoFrame(base::nullopt);
+ CreateTestStreamTextureHardwareVideoFrame(absl::nullopt);
VideoFrameExternalResources resources =
updater->CreateExternalResourcesFromVideoFrame(video_frame);
@@ -793,5 +793,42 @@ TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_DualNV12) {
EXPECT_EQ(0u, GetSharedImageCount());
}
+TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_SingleP016HDR) {
+ constexpr auto kHDR10ColorSpace = gfx::ColorSpace::CreateHDR10();
+ gfx::HDRMetadata hdr_metadata{};
+ hdr_metadata.mastering_metadata.luminance_max = 1000;
+ std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
+ EXPECT_EQ(0u, GetSharedImageCount());
+ scoped_refptr<VideoFrame> video_frame = CreateTestHardwareVideoFrame(
+ PIXEL_FORMAT_P016LE, GL_TEXTURE_EXTERNAL_OES);
+ video_frame->set_color_space(kHDR10ColorSpace);
+ video_frame->set_hdr_metadata(hdr_metadata);
+
+ VideoFrameExternalResources resources =
+ updater->CreateExternalResourcesFromVideoFrame(video_frame);
+ EXPECT_EQ(VideoFrameResourceType::RGB, resources.type);
+ EXPECT_EQ(1u, resources.resources.size());
+ EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES),
+ resources.resources[0].mailbox_holder.texture_target);
+ EXPECT_EQ(viz::P010, resources.resources[0].format);
+ EXPECT_EQ(kHDR10ColorSpace, resources.resources[0].color_space);
+ EXPECT_EQ(hdr_metadata, resources.resources[0].hdr_metadata);
+
+ video_frame = CreateTestYuvHardwareVideoFrame(PIXEL_FORMAT_P016LE, 1,
+ GL_TEXTURE_RECTANGLE_ARB);
+ video_frame->set_color_space(kHDR10ColorSpace);
+ video_frame->set_hdr_metadata(hdr_metadata);
+ resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
+ EXPECT_EQ(VideoFrameResourceType::RGB, resources.type);
+ EXPECT_EQ(1u, resources.resources.size());
+ EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
+ resources.resources[0].mailbox_holder.texture_target);
+ EXPECT_EQ(viz::P010, resources.resources[0].format);
+ EXPECT_EQ(kHDR10ColorSpace, resources.resources[0].color_space);
+ EXPECT_EQ(hdr_metadata, resources.resources[0].hdr_metadata);
+
+ EXPECT_EQ(0u, GetSharedImageCount());
+}
+
} // namespace
} // namespace media
diff --git a/chromium/media/renderers/win/media_engine_notify_impl.h b/chromium/media/renderers/win/media_engine_notify_impl.h
index b0dcf6a4001..cf3cafc6045 100644
--- a/chromium/media/renderers/win/media_engine_notify_impl.h
+++ b/chromium/media/renderers/win/media_engine_notify_impl.h
@@ -10,7 +10,6 @@
#include "base/callback.h"
#include "base/synchronization/lock.h"
-#include "base/time/time.h"
#include "media/base/buffering_state.h"
#include "media/base/pipeline_status.h"
diff --git a/chromium/media/renderers/win/media_foundation_protection_manager.cc b/chromium/media/renderers/win/media_foundation_protection_manager.cc
index d7ef8edf861..01827989857 100644
--- a/chromium/media/renderers/win/media_foundation_protection_manager.cc
+++ b/chromium/media/renderers/win/media_foundation_protection_manager.cc
@@ -18,8 +18,13 @@ namespace media {
using Microsoft::WRL::ComPtr;
-MediaFoundationProtectionManager::MediaFoundationProtectionManager() = default;
-MediaFoundationProtectionManager::~MediaFoundationProtectionManager() = default;
+MediaFoundationProtectionManager::MediaFoundationProtectionManager() {
+ DVLOG_FUNC(1);
+}
+
+MediaFoundationProtectionManager::~MediaFoundationProtectionManager() {
+ DVLOG_FUNC(1);
+}
HRESULT MediaFoundationProtectionManager::RuntimeClassInitialize() {
DVLOG_FUNC(1);
@@ -36,11 +41,12 @@ HRESULT MediaFoundationProtectionManager::RuntimeClassInitialize() {
return S_OK;
}
-HRESULT MediaFoundationProtectionManager::SetCdmProxy(IMFCdmProxy* cdm_proxy) {
+HRESULT MediaFoundationProtectionManager::SetCdmProxy(
+ scoped_refptr<MediaFoundationCdmProxy> cdm_proxy) {
DVLOG_FUNC(1);
DCHECK(cdm_proxy);
- cdm_proxy_ = cdm_proxy;
+ cdm_proxy_ = std::move(cdm_proxy);
ComPtr<ABI::Windows::Media::Protection::IMediaProtectionPMPServer> pmp_server;
RETURN_IF_FAILED(cdm_proxy_->GetPMPServer(IID_PPV_ARGS(&pmp_server)));
RETURN_IF_FAILED(SetPMPServer(pmp_server.Get()));
diff --git a/chromium/media/renderers/win/media_foundation_protection_manager.h b/chromium/media/renderers/win/media_foundation_protection_manager.h
index 3ccb8b39ae9..201ac76f787 100644
--- a/chromium/media/renderers/win/media_foundation_protection_manager.h
+++ b/chromium/media/renderers/win/media_foundation_protection_manager.h
@@ -10,7 +10,8 @@
#include <windows.media.protection.h>
#include <wrl.h>
-#include "media/base/win/mf_cdm_proxy.h"
+#include "base/memory/scoped_refptr.h"
+#include "media/base/win/media_foundation_cdm_proxy.h"
namespace media {
@@ -33,7 +34,7 @@ class MediaFoundationProtectionManager
~MediaFoundationProtectionManager() override;
HRESULT RuntimeClassInitialize();
- HRESULT SetCdmProxy(IMFCdmProxy* cdm_proxy);
+ HRESULT SetCdmProxy(scoped_refptr<MediaFoundationCdmProxy> cdm_proxy);
// IMFContentProtectionManager.
IFACEMETHODIMP BeginEnableContent(IMFActivate* enabler_activate,
@@ -65,7 +66,8 @@ class MediaFoundationProtectionManager
protected:
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IPropertySet>
property_set_;
- Microsoft::WRL::ComPtr<IMFCdmProxy> cdm_proxy_;
+
+ scoped_refptr<MediaFoundationCdmProxy> cdm_proxy_;
HRESULT SetPMPServer(
ABI::Windows::Media::Protection::IMediaProtectionPMPServer* pmp_server);
diff --git a/chromium/media/renderers/win/media_foundation_renderer.cc b/chromium/media/renderers/win/media_foundation_renderer.cc
index b69263da83a..4e97cec3b74 100644
--- a/chromium/media/renderers/win/media_foundation_renderer.cc
+++ b/chromium/media/renderers/win/media_foundation_renderer.cc
@@ -320,13 +320,13 @@ void MediaFoundationRenderer::SetCdm(CdmContext* cdm_context,
}
void MediaFoundationRenderer::SetLatencyHint(
- base::Optional<base::TimeDelta> /*latency_hint*/) {
+ absl::optional<base::TimeDelta> /*latency_hint*/) {
// TODO(frankli): Ensure MFMediaEngine rendering pipeine is in real time mode.
NOTIMPLEMENTED() << "We do not use the latency hint today";
}
void MediaFoundationRenderer::OnCdmProxyReceived(
- ComPtr<IMFCdmProxy> cdm_proxy) {
+ scoped_refptr<MediaFoundationCdmProxy> cdm_proxy) {
DVLOG_FUNC(1);
if (!waiting_for_mf_cdm_ || !content_protection_manager_) {
@@ -337,8 +337,8 @@ void MediaFoundationRenderer::OnCdmProxyReceived(
waiting_for_mf_cdm_ = false;
- content_protection_manager_->SetCdmProxy(cdm_proxy.Get());
- mf_source_->SetCdmProxy(cdm_proxy.Get());
+ content_protection_manager_->SetCdmProxy(cdm_proxy);
+ mf_source_->SetCdmProxy(cdm_proxy);
HRESULT hr = SetSourceOnMediaEngine();
if (FAILED(hr)) {
DLOG(ERROR) << "Failed to set source on media engine: " << PrintHr(hr);
diff --git a/chromium/media/renderers/win/media_foundation_renderer.h b/chromium/media/renderers/win/media_foundation_renderer.h
index 70a209f94aa..21b7d383f73 100644
--- a/chromium/media/renderers/win/media_foundation_renderer.h
+++ b/chromium/media/renderers/win/media_foundation_renderer.h
@@ -54,7 +54,7 @@ class MEDIA_EXPORT MediaFoundationRenderer
RendererClient* client,
PipelineStatusCallback init_cb) override;
void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) override;
- void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
+ void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void Flush(base::OnceClosure flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
void SetPlaybackRate(double playback_rate) override;
@@ -86,7 +86,7 @@ class MEDIA_EXPORT MediaFoundationRenderer
void OnVideoNaturalSizeChange();
void OnTimeUpdate();
- void OnCdmProxyReceived(Microsoft::WRL::ComPtr<IMFCdmProxy> cdm_proxy);
+ void OnCdmProxyReceived(scoped_refptr<MediaFoundationCdmProxy> cdm_proxy);
HRESULT SetDCompModeInternal(bool enabled);
HRESULT GetDCompSurfaceInternal(HANDLE* surface_handle);
diff --git a/chromium/media/renderers/win/media_foundation_renderer_factory.cc b/chromium/media/renderers/win/media_foundation_renderer_factory.cc
deleted file mode 100644
index f44de378857..00000000000
--- a/chromium/media/renderers/win/media_foundation_renderer_factory.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2020 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 "media/renderers/win/media_foundation_renderer_factory.h"
-
-#include "base/single_thread_task_runner.h"
-#include "media/renderers/win/media_foundation_renderer.h"
-
-namespace media {
-
-MediaFoundationRendererFactory::MediaFoundationRendererFactory() = default;
-
-MediaFoundationRendererFactory::~MediaFoundationRendererFactory() = default;
-
-// MediaFoundationRenderer does most audio/video rendering by itself and doesn't
-// use most of the parameters passed in.
-std::unique_ptr<Renderer> MediaFoundationRendererFactory::CreateRenderer(
- const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
- const scoped_refptr<base::TaskRunner>& /*worker_task_runner*/,
- AudioRendererSink* /*audio_renderer_sink*/,
- VideoRendererSink* /*video_renderer_sink*/,
- RequestOverlayInfoCB /*request_overlay_info_cb*/,
- const gfx::ColorSpace& /*target_color_space*/) {
- // TODO(xhwang): Investigate how to set |muted| and update after composition
- // is connected.
- auto renderer = std::make_unique<MediaFoundationRenderer>(
- /*muted=*/false, media_task_runner,
- /*force_dcomp_mode_for_testing=*/true);
-
- return renderer;
-}
-
-} // namespace media \ No newline at end of file
diff --git a/chromium/media/renderers/win/media_foundation_renderer_factory.h b/chromium/media/renderers/win/media_foundation_renderer_factory.h
deleted file mode 100644
index 50a9b9d1d8b..00000000000
--- a/chromium/media/renderers/win/media_foundation_renderer_factory.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2020 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 MEDIA_RENDERERS_WIN_MEDIA_FOUNDATION_RENDERER_FACTORY_H_
-#define MEDIA_RENDERERS_WIN_MEDIA_FOUNDATION_RENDERER_FACTORY_H_
-
-#include <stdint.h>
-
-#include "media/base/media_export.h"
-#include "media/base/renderer_factory.h"
-
-namespace media {
-
-// RendererFactory to create MediaFoundationRendererFactory.
-class MEDIA_EXPORT MediaFoundationRendererFactory : public RendererFactory {
- public:
- MediaFoundationRendererFactory();
- MediaFoundationRendererFactory(const MediaFoundationRendererFactory&) =
- delete;
- MediaFoundationRendererFactory& operator=(
- const MediaFoundationRendererFactory&) = delete;
- ~MediaFoundationRendererFactory() final;
-
- // RendererFactory implementation.
- std::unique_ptr<Renderer> CreateRenderer(
- const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
- const scoped_refptr<base::TaskRunner>& worker_task_runner,
- AudioRendererSink* audio_renderer_sink,
- VideoRendererSink* video_renderer_sink,
- RequestOverlayInfoCB request_overlay_info_cb,
- const gfx::ColorSpace& target_color_space) final;
-};
-
-} // namespace media
-
-#endif // MEDIA_RENDERERS_WIN_MEDIA_FOUNDATION_RENDERER_FACTORY_H_
diff --git a/chromium/media/renderers/win/media_foundation_renderer_integration_test.cc b/chromium/media/renderers/win/media_foundation_renderer_integration_test.cc
index 163708f6905..b9b4b462239 100644
--- a/chromium/media/renderers/win/media_foundation_renderer_integration_test.cc
+++ b/chromium/media/renderers/win/media_foundation_renderer_integration_test.cc
@@ -61,7 +61,7 @@ class MediaFoundationRendererIntegrationTest
private:
std::unique_ptr<Renderer> CreateMediaFoundationRenderer(
- base::Optional<RendererFactoryType> factory_type) {
+ absl::optional<RendererType> /*renderer_type*/) {
auto renderer = std::make_unique<MediaFoundationRenderer>(
/*muted=*/false, task_environment_.GetMainThreadTaskRunner(),
/*force_dcomp_mode_for_testing=*/true);
diff --git a/chromium/media/renderers/win/media_foundation_renderer_unittest.cc b/chromium/media/renderers/win/media_foundation_renderer_unittest.cc
index 9f74d065f30..b5ebb75391d 100644
--- a/chromium/media/renderers/win/media_foundation_renderer_unittest.cc
+++ b/chromium/media/renderers/win/media_foundation_renderer_unittest.cc
@@ -8,10 +8,12 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/memory/scoped_refptr.h"
#include "base/single_thread_task_runner.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "base/win/scoped_com_initializer.h"
+#include "media/base/bind_to_current_loop.h"
#include "media/base/demuxer_stream.h"
#include "media/base/mock_filters.h"
#include "media/base/test_helpers.h"
@@ -29,33 +31,30 @@ namespace media {
using ABI::Windows::Media::Protection::IMediaProtectionPMPServer;
using Microsoft::WRL::ComPtr;
-class MockMFCdmProxy
- : public Microsoft::WRL::RuntimeClass<
- Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
- IMFCdmProxy> {
+class MockMediaFoundationCdmProxy : public MediaFoundationCdmProxy {
public:
- MockMFCdmProxy();
- ~MockMFCdmProxy() override;
-
- // IMFCdmProxy.
- MOCK_STDCALL_METHOD2(GetPMPServer,
- HRESULT(REFIID riid, void** object_result));
- MOCK_STDCALL_METHOD6(GetInputTrustAuthority,
- HRESULT(uint32_t stream_id,
- uint32_t stream_count,
- const uint8_t* content_init_data,
- uint32_t content_init_data_size,
- REFIID riid,
- IUnknown** object_result));
- MOCK_STDCALL_METHOD2(SetLastKeyId,
- HRESULT(uint32_t stream_id, REFGUID key_id));
- MOCK_STDCALL_METHOD0(RefreshTrustedInput, HRESULT());
- MOCK_STDCALL_METHOD2(ProcessContentEnabler,
- HRESULT(IUnknown* request, IMFAsyncResult* result));
+ MockMediaFoundationCdmProxy();
+
+ // MediaFoundationCdmProxy.
+ MOCK_METHOD2(GetPMPServer, HRESULT(REFIID riid, void** object_result));
+ MOCK_METHOD6(GetInputTrustAuthority,
+ HRESULT(uint32_t stream_id,
+ uint32_t stream_count,
+ const uint8_t* content_init_data,
+ uint32_t content_init_data_size,
+ REFIID riid,
+ IUnknown** object_result));
+ MOCK_METHOD2(SetLastKeyId, HRESULT(uint32_t stream_id, REFGUID key_id));
+ MOCK_METHOD0(RefreshTrustedInput, HRESULT());
+ MOCK_METHOD2(ProcessContentEnabler,
+ HRESULT(IUnknown* request, IMFAsyncResult* result));
+
+ protected:
+ ~MockMediaFoundationCdmProxy() override;
};
-MockMFCdmProxy::MockMFCdmProxy() = default;
-MockMFCdmProxy::~MockMFCdmProxy() = default;
+MockMediaFoundationCdmProxy::MockMediaFoundationCdmProxy() = default;
+MockMediaFoundationCdmProxy::~MockMediaFoundationCdmProxy() = default;
class MockMediaProtectionPMPServer
: public Microsoft::WRL::RuntimeClass<
@@ -92,6 +91,13 @@ class MediaFoundationRendererTest : public testing::Test {
if (!MediaFoundationRenderer::IsSupported())
return;
+ mf_cdm_proxy_ =
+ base::MakeRefCounted<NiceMock<MockMediaFoundationCdmProxy>>();
+
+ // MF MediaEngine holds IMFMediaSource (MediaFoundationSourceWrapper) even
+ // after the test finishes, which holds a reference to the `mf_cdm_proxy_`.
+ testing::Mock::AllowLeak(mf_cdm_proxy_.get());
+
MockMediaProtectionPMPServer::MakeMockMediaProtectionPMPServer(
&pmp_server_);
@@ -100,11 +106,11 @@ class MediaFoundationRendererTest : public testing::Test {
// Some default actions.
ON_CALL(cdm_context_, GetMediaFoundationCdmProxy(_))
+ .WillByDefault(Invoke(
+ this, &MediaFoundationRendererTest::GetMediaFoundationCdmProxy));
+ ON_CALL(*mf_cdm_proxy_, GetPMPServer(_, _))
.WillByDefault(
- Invoke(this, &MediaFoundationRendererTest::MockGetMFCdm));
- ON_CALL(mf_cdm_proxy_, GetPMPServer(_, _))
- .WillByDefault(
- Invoke(this, &MediaFoundationRendererTest::MockGetPMPServer));
+ Invoke(this, &MediaFoundationRendererTest::GetPMPServer));
// Some expected calls with return values.
EXPECT_CALL(media_resource_, GetAllStreams())
@@ -130,23 +136,14 @@ class MediaFoundationRendererTest : public testing::Test {
return streams;
}
- void OnSendCdmProxy(
- CdmContext::GetMediaFoundationCdmProxyCB get_mf_cdm_proxy_cb) {
- std::move(get_mf_cdm_proxy_cb).Run(&mf_cdm_proxy_);
- }
-
- bool MockGetMFCdm(
+ bool GetMediaFoundationCdmProxy(
CdmContext::GetMediaFoundationCdmProxyCB get_mf_cdm_proxy_cb) {
- // The callback should be invoked asynchronously per API contract. Post
- // to make callback from OnSendCdmProxy().
- task_environment_.GetMainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&MediaFoundationRendererTest::OnSendCdmProxy,
- base::Unretained(this), std::move(get_mf_cdm_proxy_cb)));
+ // Call the callback asynchronously per API contract.
+ BindToCurrentLoop(std::move(get_mf_cdm_proxy_cb)).Run(mf_cdm_proxy_);
return true;
}
- HRESULT MockGetPMPServer(REFIID riid, LPVOID* object_result) {
+ HRESULT GetPMPServer(REFIID riid, LPVOID* object_result) {
ComPtr<IMediaProtectionPMPServer> pmp_server;
if (riid != __uuidof(**(&pmp_server)) || !object_result) {
return E_INVALIDARG;
@@ -164,7 +161,7 @@ class MediaFoundationRendererTest : public testing::Test {
NiceMock<MockCdmContext> cdm_context_;
NiceMock<MockMediaResource> media_resource_;
NiceMock<MockRendererClient> renderer_client_;
- NiceMock<MockMFCdmProxy> mf_cdm_proxy_;
+ scoped_refptr<NiceMock<MockMediaFoundationCdmProxy>> mf_cdm_proxy_;
ComPtr<IMediaProtectionPMPServer> pmp_server_;
std::unique_ptr<MediaFoundationRenderer> mf_renderer_;
std::vector<std::unique_ptr<StrictMock<MockDemuxerStream>>> streams_;
diff --git a/chromium/media/renderers/win/media_foundation_source_wrapper.cc b/chromium/media/renderers/win/media_foundation_source_wrapper.cc
index ee8dd306197..3a41567f5c4 100644
--- a/chromium/media/renderers/win/media_foundation_source_wrapper.cc
+++ b/chromium/media/renderers/win/media_foundation_source_wrapper.cc
@@ -18,6 +18,8 @@ using Microsoft::WRL::ComPtr;
MediaFoundationSourceWrapper::MediaFoundationSourceWrapper() = default;
MediaFoundationSourceWrapper::~MediaFoundationSourceWrapper() {
+ DVLOG_FUNC(1);
+
if (!cdm_proxy_)
return;
@@ -506,13 +508,14 @@ bool MediaFoundationSourceWrapper::HasEncryptedStream() const {
return false;
}
-void MediaFoundationSourceWrapper::SetCdmProxy(IMFCdmProxy* cdm_proxy) {
+void MediaFoundationSourceWrapper::SetCdmProxy(
+ scoped_refptr<MediaFoundationCdmProxy> cdm_proxy) {
DVLOG_FUNC(2);
DCHECK(task_runner_->RunsTasksInCurrentSequence());
// cdm_proxy_ should never change.
DCHECK(!cdm_proxy_);
- cdm_proxy_ = cdm_proxy;
+ cdm_proxy_ = std::move(cdm_proxy);
HRESULT hr = cdm_proxy_->RefreshTrustedInput();
DLOG_IF(ERROR, FAILED(hr))
diff --git a/chromium/media/renderers/win/media_foundation_source_wrapper.h b/chromium/media/renderers/win/media_foundation_source_wrapper.h
index 2c8a8c00f32..88ca8f96b44 100644
--- a/chromium/media/renderers/win/media_foundation_source_wrapper.h
+++ b/chromium/media/renderers/win/media_foundation_source_wrapper.h
@@ -12,9 +12,10 @@
#include <map>
#include <vector>
+#include "base/memory/scoped_refptr.h"
#include "base/sequenced_task_runner.h"
#include "media/base/media_resource.h"
-#include "media/base/win/mf_cdm_proxy.h"
+#include "media/base/win/media_foundation_cdm_proxy.h"
#include "media/renderers/win/media_foundation_stream_wrapper.h"
namespace media {
@@ -40,6 +41,7 @@ class MediaFoundationSourceWrapper
public:
MediaFoundationSourceWrapper();
~MediaFoundationSourceWrapper() override;
+
// This is only called on |task_runner|.
void DetachResource();
@@ -109,7 +111,7 @@ class MediaFoundationSourceWrapper
// |media_streams_| has encrypted stream or not.
bool HasEncryptedStream() const;
// Set the internal |cdm_proxy_|.
- void SetCdmProxy(IMFCdmProxy* cdm_proxy);
+ void SetCdmProxy(scoped_refptr<MediaFoundationCdmProxy> cdm_proxy);
// Set the internal |video_stream_enabled_|. Returns true if we are
// re-enabling a video stream which has previously reached EOS.
bool SetVideoStreamEnabled(bool enabled);
@@ -130,7 +132,7 @@ class MediaFoundationSourceWrapper
Microsoft::WRL::ComPtr<IMFMediaEventQueue> mf_media_event_queue_;
// The proxy interface to communicate with MFCdm.
- Microsoft::WRL::ComPtr<IMFCdmProxy> cdm_proxy_;
+ scoped_refptr<MediaFoundationCdmProxy> cdm_proxy_;
bool video_stream_enabled_ = true;
float current_rate_ = 0.0f;
diff --git a/chromium/media/video/fake_gpu_memory_buffer.cc b/chromium/media/video/fake_gpu_memory_buffer.cc
index b7d570c2fa6..87223970100 100644
--- a/chromium/media/video/fake_gpu_memory_buffer.cc
+++ b/chromium/media/video/fake_gpu_memory_buffer.cc
@@ -64,7 +64,7 @@ FakeGpuMemoryBuffer::FakeGpuMemoryBuffer(const gfx::Size& size,
gfx::BufferFormat format,
uint64_t modifier)
: size_(size), format_(format) {
- base::Optional<VideoPixelFormat> video_pixel_format =
+ absl::optional<VideoPixelFormat> video_pixel_format =
GfxBufferFormatToVideoPixelFormat(format);
CHECK(video_pixel_format);
video_pixel_format_ = *video_pixel_format;
diff --git a/chromium/media/video/gpu_memory_buffer_video_frame_pool.cc b/chromium/media/video/gpu_memory_buffer_video_frame_pool.cc
index 89f65952080..a5327db33ce 100644
--- a/chromium/media/video/gpu_memory_buffer_video_frame_pool.cc
+++ b/chromium/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -595,16 +595,21 @@ gfx::Size CodedSize(const VideoFrame* video_frame,
GpuVideoAcceleratorFactories::OutputFormat output_format) {
DCHECK(gfx::Rect(video_frame->coded_size())
.Contains(video_frame->visible_rect()));
- DCHECK((video_frame->visible_rect().x() & 1) == 0);
+ DCHECK_EQ(video_frame->visible_rect().x() % 2, 0);
gfx::Size output;
switch (output_format) {
case GpuVideoAcceleratorFactories::OutputFormat::I420:
case GpuVideoAcceleratorFactories::OutputFormat::P010:
case GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB:
case GpuVideoAcceleratorFactories::OutputFormat::NV12_DUAL_GMB:
- DCHECK((video_frame->visible_rect().y() & 1) == 0);
- output = gfx::Size((video_frame->visible_rect().width() + 1) & ~1,
- (video_frame->visible_rect().height() + 1) & ~1);
+ if (gfx::AllowOddHeightMultiPlanarBuffers()) {
+ output = gfx::Size((video_frame->visible_rect().width() + 1) & ~1,
+ video_frame->visible_rect().height());
+ } else {
+ DCHECK((video_frame->visible_rect().y() & 1) == 0);
+ output = gfx::Size((video_frame->visible_rect().width() + 1) & ~1,
+ (video_frame->visible_rect().height() + 1) & ~1);
+ }
break;
case GpuVideoAcceleratorFactories::OutputFormat::XR30:
case GpuVideoAcceleratorFactories::OutputFormat::XB30:
@@ -702,14 +707,21 @@ void GpuMemoryBufferVideoFramePool::PoolImpl::CreateHardwareFrame(
}
passthrough = true;
}
- // TODO(dcastagna): Handle odd positioned video frame input, see
- // https://crbug.com/638906.
- // TODO(emircan): Eliminate odd size video frame input cases as they are not
- // valid, see https://crbug.com/webrtc/9033.
- if ((video_frame->visible_rect().x() & 1) ||
- (video_frame->visible_rect().y() & 1) ||
- (video_frame->coded_size().width() & 1) ||
- (video_frame->coded_size().height() & 1)) {
+
+ // TODO(https://crbug.com/638906): Handle odd positioned video frame input.
+ if (video_frame->visible_rect().x() % 2)
+ passthrough = true;
+ if (video_frame->visible_rect().y() % 2 &&
+ !gfx::AllowOddHeightMultiPlanarBuffers()) {
+ passthrough = true;
+ }
+
+ // TODO(https://crbug.com/webrtc/9033): Eliminate odd size video frame input
+ // cases as they are not valid.
+ if (video_frame->coded_size().width() % 2)
+ passthrough = true;
+ if (video_frame->coded_size().height() % 2 &&
+ !gfx::AllowOddHeightMultiPlanarBuffers()) {
passthrough = true;
}
diff --git a/chromium/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc b/chromium/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
index 90123897655..3dd9536affd 100644
--- a/chromium/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
+++ b/chromium/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
@@ -15,6 +15,7 @@
#include "media/video/gpu_memory_buffer_video_frame_pool.h"
#include "media/video/mock_gpu_video_accelerator_factories.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "ui/gfx/buffer_format_util.h"
using ::testing::_;
using ::testing::AtLeast;
@@ -612,13 +613,13 @@ TEST_F(GpuMemoryBufferVideoFramePoolTest, PreservesOrder) {
std::vector<scoped_refptr<VideoFrame>> frame_outputs;
scoped_refptr<VideoFrame> software_frame_1 = CreateTestYUVVideoFrame(10);
- scoped_refptr<VideoFrame> frame_1 = nullptr;
+ scoped_refptr<VideoFrame> frame_1;
gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
software_frame_1,
base::BindOnce(MaybeCreateHardwareFrameCallback, &frame_1));
scoped_refptr<VideoFrame> software_frame_2 = CreateTestYUVVideoFrame(10);
- scoped_refptr<VideoFrame> frame_2 = nullptr;
+ scoped_refptr<VideoFrame> frame_2;
base::TimeTicks time_2;
gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
software_frame_2,
@@ -626,7 +627,7 @@ TEST_F(GpuMemoryBufferVideoFramePoolTest, PreservesOrder) {
&time_2));
scoped_refptr<VideoFrame> software_frame_3 = VideoFrame::CreateEOSFrame();
- scoped_refptr<VideoFrame> frame_3 = nullptr;
+ scoped_refptr<VideoFrame> frame_3;
base::TimeTicks time_3;
gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
software_frame_3,
diff --git a/chromium/media/video/gpu_video_accelerator_factories.h b/chromium/media/video/gpu_video_accelerator_factories.h
index 331233b05df..40137ef5740 100644
--- a/chromium/media/video/gpu_video_accelerator_factories.h
+++ b/chromium/media/video/gpu_video_accelerator_factories.h
@@ -14,7 +14,6 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/unsafe_shared_memory_region.h"
-#include "base/optional.h"
#include "base/unguessable_token.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/mailbox.h"
@@ -24,6 +23,7 @@
#include "media/base/video_decoder.h"
#include "media/base/video_types.h"
#include "media/video/video_encode_accelerator.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/gpu_memory_buffer.h"
namespace base {
@@ -52,10 +52,10 @@ class MediaLog;
// video accelerator.
// Threading model:
// * The GpuVideoAcceleratorFactories may be constructed on any thread.
-// * The GpuVideoAcceleratorFactories has an associated message loop, which may
-// be retrieved as |GetMessageLoop()|.
-// * All calls to the Factories after construction must be made on its message
-// loop, unless otherwise documented below.
+// * The GpuVideoAcceleratorFactories has an associated task runner, which may
+// be retrieved as |GetTaskRunner()|.
+// * All calls to the Factories after construction must be made on its task
+// runnner, unless otherwise documented below.
class MEDIA_EXPORT GpuVideoAcceleratorFactories {
public:
enum class OutputFormat {
@@ -137,7 +137,7 @@ class MEDIA_EXPORT GpuVideoAcceleratorFactories {
//
// TODO(sandersd): Remove Optional if/when all clients check
// IsEncoderSupportKnown().
- virtual base::Optional<VideoEncodeAccelerator::SupportedProfiles>
+ virtual absl::optional<VideoEncodeAccelerator::SupportedProfiles>
GetVideoEncodeAcceleratorSupportedProfiles() = 0;
// Returns true if GetVideoEncodeAcceleratorSupportedProfiles() is populated.
diff --git a/chromium/media/video/h264_level_limits.cc b/chromium/media/video/h264_level_limits.cc
index a51d34a1472..2c6427c2013 100644
--- a/chromium/media/video/h264_level_limits.cc
+++ b/chromium/media/video/h264_level_limits.cc
@@ -142,7 +142,7 @@ bool CheckH264LevelLimits(VideoCodecProfile profile,
return true;
}
-base::Optional<uint8_t> FindValidH264Level(VideoCodecProfile profile,
+absl::optional<uint8_t> FindValidH264Level(VideoCodecProfile profile,
uint32_t bitrate,
uint32_t framerate,
uint32_t framesize_in_mbs) {
@@ -162,7 +162,7 @@ base::Optional<uint8_t> FindValidH264Level(VideoCodecProfile profile,
return level;
}
}
- return base::nullopt;
+ return absl::nullopt;
}
} // namespace media
diff --git a/chromium/media/video/h264_level_limits.h b/chromium/media/video/h264_level_limits.h
index fcc8eb8c8b1..2c46d7d1fbf 100644
--- a/chromium/media/video/h264_level_limits.h
+++ b/chromium/media/video/h264_level_limits.h
@@ -7,9 +7,9 @@
#include <stddef.h>
-#include "base/optional.h"
#include "media/base/media_export.h"
#include "media/base/video_codecs.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -40,8 +40,8 @@ bool MEDIA_EXPORT CheckH264LevelLimits(VideoCodecProfile profile,
// Return a minimum level that comforts Table A-1 in spec with |profile|,
// |bitrate|, |framerate| and |framesize_in_mbs|. If there is no proper level,
-// returns base::nullopt.
-base::Optional<uint8_t> MEDIA_EXPORT
+// returns absl::nullopt.
+absl::optional<uint8_t> MEDIA_EXPORT
FindValidH264Level(VideoCodecProfile profile,
uint32_t bitrate,
uint32_t framerate,
diff --git a/chromium/media/video/h264_parser.cc b/chromium/media/video/h264_parser.cc
index f4a10a12899..12332ca0678 100644
--- a/chromium/media/video/h264_parser.cc
+++ b/chromium/media/video/h264_parser.cc
@@ -107,7 +107,7 @@ H264SPS::H264SPS() {
// Based on T-REC-H.264 7.4.2.1.1, "Sequence parameter set data semantics",
// available from http://www.itu.int/rec/T-REC-H.264.
-base::Optional<gfx::Size> H264SPS::GetCodedSize() const {
+absl::optional<gfx::Size> H264SPS::GetCodedSize() const {
// Interlaced frames are twice the height of each field.
const int mb_unit = 16;
int map_unit = frame_mbs_only_flag ? 16 : 32;
@@ -121,7 +121,7 @@ base::Optional<gfx::Size> H264SPS::GetCodedSize() const {
if (pic_width_in_mbs_minus1 > max_mb_minus1 ||
pic_height_in_map_units_minus1 > max_map_units_minus1) {
DVLOG(1) << "Coded size is too large.";
- return base::nullopt;
+ return absl::nullopt;
}
return gfx::Size(mb_unit * (pic_width_in_mbs_minus1 + 1),
@@ -129,10 +129,10 @@ base::Optional<gfx::Size> H264SPS::GetCodedSize() const {
}
// Also based on section 7.4.2.1.1.
-base::Optional<gfx::Rect> H264SPS::GetVisibleRect() const {
- base::Optional<gfx::Size> coded_size = GetCodedSize();
+absl::optional<gfx::Rect> H264SPS::GetVisibleRect() const {
+ absl::optional<gfx::Size> coded_size = GetCodedSize();
if (!coded_size)
- return base::nullopt;
+ return absl::nullopt;
if (!frame_cropping_flag)
return gfx::Rect(coded_size.value());
@@ -161,7 +161,7 @@ base::Optional<gfx::Rect> H264SPS::GetVisibleRect() const {
coded_size->height() / crop_unit_y < frame_crop_top_offset ||
coded_size->height() / crop_unit_y < frame_crop_bottom_offset) {
DVLOG(1) << "Frame cropping exceeds coded size.";
- return base::nullopt;
+ return absl::nullopt;
}
int crop_left = crop_unit_x * frame_crop_left_offset;
int crop_right = crop_unit_x * frame_crop_right_offset;
@@ -174,7 +174,7 @@ base::Optional<gfx::Rect> H264SPS::GetVisibleRect() const {
if (coded_size->width() - crop_left <= crop_right ||
coded_size->height() - crop_top <= crop_bottom) {
DVLOG(1) << "Frame cropping excludes entire frame.";
- return base::nullopt;
+ return absl::nullopt;
}
return gfx::Rect(crop_left, crop_top,
diff --git a/chromium/media/video/h264_parser.h b/chromium/media/video/h264_parser.h
index 652cbe9f70f..af8cdc8d75e 100644
--- a/chromium/media/video/h264_parser.h
+++ b/chromium/media/video/h264_parser.h
@@ -16,12 +16,12 @@
#include <vector>
#include "base/macros.h"
-#include "base/optional.h"
#include "media/base/media_export.h"
#include "media/base/ranges.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
#include "media/video/h264_bit_reader.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace gfx {
class Rect;
@@ -214,10 +214,10 @@ struct MEDIA_EXPORT H264SPS {
bool* constraint_set3_flag);
// Helpers to compute frequently-used values. These methods return
- // base::nullopt if they encounter integer overflow. They do not verify that
+ // absl::nullopt if they encounter integer overflow. They do not verify that
// the results are in-spec for the given profile or level.
- base::Optional<gfx::Size> GetCodedSize() const;
- base::Optional<gfx::Rect> GetVisibleRect() const;
+ absl::optional<gfx::Size> GetCodedSize() const;
+ absl::optional<gfx::Rect> GetVisibleRect() const;
VideoColorSpace GetColorSpace() const;
// Helper to compute indicated level from parsed SPS data. The value of
diff --git a/chromium/media/video/h264_parser_fuzzertest.cc b/chromium/media/video/h264_parser_fuzzertest.cc
index e8355193371..6ded4dcc95c 100644
--- a/chromium/media/video/h264_parser_fuzzertest.cc
+++ b/chromium/media/video/h264_parser_fuzzertest.cc
@@ -5,8 +5,8 @@
#include <stddef.h>
#include "base/numerics/safe_conversions.h"
-#include "base/optional.h"
#include "media/video/h264_parser.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -46,9 +46,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
break;
// Also test the SPS helper methods. We make sure that the results are
// used so that the calls are not optimized away.
- base::Optional<gfx::Size> coded_size = sps->GetCodedSize();
+ absl::optional<gfx::Size> coded_size = sps->GetCodedSize();
volatile_sink = coded_size.value_or(gfx::Size()).ToString().length();
- base::Optional<gfx::Rect> visible_rect = sps->GetVisibleRect();
+ absl::optional<gfx::Rect> visible_rect = sps->GetVisibleRect();
volatile_sink = visible_rect.value_or(gfx::Rect()).ToString().length();
break;
}
diff --git a/chromium/media/video/h264_parser_unittest.cc b/chromium/media/video/h264_parser_unittest.cc
index 7a67fe81e4d..96d997dcde8 100644
--- a/chromium/media/video/h264_parser_unittest.cc
+++ b/chromium/media/video/h264_parser_unittest.cc
@@ -9,13 +9,13 @@
#include "base/command_line.h"
#include "base/files/memory_mapped_file.h"
#include "base/logging.h"
-#include "base/optional.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "media/base/subsample_entry.h"
#include "media/base/test_data_util.h"
#include "media/video/h264_parser.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -62,7 +62,7 @@ TEST_F(H264SPSTest, GetCodedSize) {
// Overflow.
sps->pic_width_in_mbs_minus1 = std::numeric_limits<int>::max();
- EXPECT_EQ(base::nullopt, sps->GetCodedSize());
+ EXPECT_EQ(absl::nullopt, sps->GetCodedSize());
}
TEST_F(H264SPSTest, GetVisibleRect) {
@@ -89,14 +89,14 @@ TEST_F(H264SPSTest, GetVisibleRect) {
sps->frame_crop_right_offset = 1;
sps->frame_crop_top_offset = 0;
sps->frame_crop_bottom_offset = 0;
- EXPECT_EQ(base::nullopt, sps->GetVisibleRect());
+ EXPECT_EQ(absl::nullopt, sps->GetVisibleRect());
// Overflow.
sps->frame_crop_left_offset = std::numeric_limits<int>::max() / 2 + 1;
sps->frame_crop_right_offset = 0;
sps->frame_crop_top_offset = 0;
sps->frame_crop_bottom_offset = 0;
- EXPECT_EQ(base::nullopt, sps->GetVisibleRect());
+ EXPECT_EQ(absl::nullopt, sps->GetVisibleRect());
}
TEST(H264ParserTest, StreamFileParsing) {
diff --git a/chromium/media/video/h264_poc.cc b/chromium/media/video/h264_poc.cc
index 59c0ae7b651..d06729240a1 100644
--- a/chromium/media/video/h264_poc.cc
+++ b/chromium/media/video/h264_poc.cc
@@ -57,12 +57,12 @@ void H264POC::Reset() {
pending_mmco5_ = false;
}
-base::Optional<int32_t> H264POC::ComputePicOrderCnt(
+absl::optional<int32_t> H264POC::ComputePicOrderCnt(
const H264SPS* sps,
const H264SliceHeader& slice_hdr) {
if (slice_hdr.field_pic_flag) {
DLOG(ERROR) << "Interlaced frames are not supported";
- return base::nullopt;
+ return absl::nullopt;
}
int32_t pic_order_cnt = 0;
@@ -166,7 +166,7 @@ base::Optional<int32_t> H264POC::ComputePicOrderCnt(
// Moved inside 8-9 to avoid division when this check is not done.
if (sps->num_ref_frames_in_pic_order_cnt_cycle == 0) {
DLOG(ERROR) << "Invalid num_ref_frames_in_pic_order_cnt_cycle";
- return base::nullopt;
+ return absl::nullopt;
}
// H264Parser checks that num_ref_frames_in_pic_order_cnt_cycle < 255.
@@ -246,7 +246,7 @@ base::Optional<int32_t> H264POC::ComputePicOrderCnt(
default:
DLOG(ERROR) << "Invalid pic_order_cnt_type: " << sps->pic_order_cnt_type;
- return base::nullopt;
+ return absl::nullopt;
}
return pic_order_cnt;
diff --git a/chromium/media/video/h264_poc.h b/chromium/media/video/h264_poc.h
index 06a0dfd3411..0f0b242cfe4 100644
--- a/chromium/media/video/h264_poc.h
+++ b/chromium/media/video/h264_poc.h
@@ -20,7 +20,7 @@ class MEDIA_EXPORT H264POC {
~H264POC();
// Returns the picture order count for a slice.
- base::Optional<int32_t> ComputePicOrderCnt(const H264SPS* sps,
+ absl::optional<int32_t> ComputePicOrderCnt(const H264SPS* sps,
const H264SliceHeader& slice_hdr);
// As specified, the POC of a frame with MMCO5 changes (to zero) after
diff --git a/chromium/media/video/h264_poc_unittest.cc b/chromium/media/video/h264_poc_unittest.cc
index cc667ea0216..60a485cb40a 100644
--- a/chromium/media/video/h264_poc_unittest.cc
+++ b/chromium/media/video/h264_poc_unittest.cc
@@ -43,7 +43,7 @@ class H264POCTest : public testing::Test {
slice_hdr_.ref_pic_marking[2].memory_mgmnt_control_operation = 0;
}
- base::Optional<int32_t> poc_;
+ absl::optional<int32_t> poc_;
H264SPS sps_;
H264SliceHeader slice_hdr_;
diff --git a/chromium/media/video/h265_parser.cc b/chromium/media/video/h265_parser.cc
index 61fcbbc3f8c..aababea9d8a 100644
--- a/chromium/media/video/h265_parser.cc
+++ b/chromium/media/video/h265_parser.cc
@@ -988,6 +988,14 @@ H265Parser::Result H265Parser::ParseSliceHeader(const H265NALU& nalu,
memcpy(reinterpret_cast<uint8_t*>(shdr) + skip_amount,
reinterpret_cast<uint8_t*>(prior_shdr) + skip_amount,
sizeof(H265SliceHeader) - skip_amount);
+
+ // We also need to validate the fields that have conditions that depend on
+ // anything unique in this slice (i.e. anything already parsed).
+ if ((shdr->irap_pic ||
+ sps->sps_max_dec_pic_buffering_minus1[pps->temporal_id] == 0) &&
+ nalu.nuh_layer_id == 0) {
+ TRUE_OR_RETURN(shdr->slice_type == 2);
+ }
} else {
// Set these defaults if they are not present here.
shdr->pic_output_flag = 1;
diff --git a/chromium/media/video/h265_parser.h b/chromium/media/video/h265_parser.h
index e322aa81358..b3d4198e0f7 100644
--- a/chromium/media/video/h265_parser.h
+++ b/chromium/media/video/h265_parser.h
@@ -360,6 +360,10 @@ struct MEDIA_EXPORT H265SliceHeader {
size_t header_size; // calculated, not including emulation prevention bytes
size_t header_emulation_prevention_bytes;
+ // Calculated, but needs to be preserved when we copy slice dependent data
+ // so put it at the front.
+ bool irap_pic;
+
// Syntax elements.
bool first_slice_segment_in_pic_flag;
bool no_output_of_prior_pics_flag;
@@ -403,7 +407,6 @@ struct MEDIA_EXPORT H265SliceHeader {
// Calculated.
int curr_rps_idx;
int num_pic_total_curr;
- bool irap_pic;
// Number of bits st_ref_pic_set takes after removing emulation prevention
// bytes.
int st_rps_bits;
diff --git a/chromium/media/video/mock_gpu_video_accelerator_factories.h b/chromium/media/video/mock_gpu_video_accelerator_factories.h
index a1aadde4566..98363d62d71 100644
--- a/chromium/media/video/mock_gpu_video_accelerator_factories.h
+++ b/chromium/media/video/mock_gpu_video_accelerator_factories.h
@@ -84,7 +84,7 @@ class MockGpuVideoAcceleratorFactories : public GpuVideoAcceleratorFactories {
std::unique_ptr<VideoEncodeAccelerator> CreateVideoEncodeAccelerator()
override;
- base::Optional<VideoEncodeAccelerator::SupportedProfiles>
+ absl::optional<VideoEncodeAccelerator::SupportedProfiles>
GetVideoEncodeAcceleratorSupportedProfiles() override {
return VideoEncodeAccelerator::SupportedProfiles();
}
diff --git a/chromium/media/video/openh264_video_encoder.cc b/chromium/media/video/openh264_video_encoder.cc
index 8aab81210f5..fd01eea3fa5 100644
--- a/chromium/media/video/openh264_video_encoder.cc
+++ b/chromium/media/video/openh264_video_encoder.cc
@@ -8,7 +8,6 @@
#include <limits>
#include "base/logging.h"
-#include "base/strings/stringprintf.h"
#include "base/system/sys_info.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
@@ -191,7 +190,7 @@ Status OpenH264VideoEncoder::DrainOutputs(const SFrameBSInfo& frame_info,
if (!h264_converter_) {
result.size = total_chunk_size;
- output_cb_.Run(std::move(result), base::Optional<CodecDescription>());
+ output_cb_.Run(std::move(result), absl::optional<CodecDescription>());
return OkStatus();
}
@@ -207,7 +206,7 @@ Status OpenH264VideoEncoder::DrainOutputs(const SFrameBSInfo& frame_info,
result.size = converted_output_size;
- base::Optional<CodecDescription> desc;
+ absl::optional<CodecDescription> desc;
if (config_changed) {
const auto& config = h264_converter_->GetCurrentConfig();
desc = CodecDescription();
diff --git a/chromium/media/video/openh264_video_encoder.h b/chromium/media/video/openh264_video_encoder.h
index 3a4a57b2c33..47e0bdd8230 100644
--- a/chromium/media/video/openh264_video_encoder.h
+++ b/chromium/media/video/openh264_video_encoder.h
@@ -8,7 +8,6 @@
#include <memory>
#include <vector>
-#include "base/callback_forward.h"
#include "media/base/media_export.h"
#include "media/base/video_encoder.h"
#include "media/base/video_frame_pool.h"
diff --git a/chromium/media/video/software_video_encoder_test.cc b/chromium/media/video/software_video_encoder_test.cc
index e8ba147bb85..83e23d9ff1d 100644
--- a/chromium/media/video/software_video_encoder_test.cc
+++ b/chromium/media/video/software_video_encoder_test.cc
@@ -12,7 +12,6 @@
#include "base/memory/scoped_refptr.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/task_environment.h"
@@ -189,6 +188,20 @@ class SoftwareVideoEncoderTest
});
}
+ void DecodeAndWaitForStatus(
+ scoped_refptr<DecoderBuffer> buffer,
+ const base::Location& location = base::Location::Current()) {
+ base::RunLoop run_loop;
+ decoder_->Decode(
+ std::move(buffer), base::BindLambdaForTesting([&](Status status) {
+ EXPECT_TRUE(status.is_ok())
+ << " Callback created: " << location.ToString()
+ << " Code: " << status.code() << " Error: " << status.message();
+ run_loop.Quit();
+ }));
+ run_loop.Run(location);
+ }
+
int CountDifferentPixels(VideoFrame& frame1, VideoFrame& frame2) {
int diff_cnt = 0;
uint8_t tolerance = 10;
@@ -241,7 +254,7 @@ TEST_P(SoftwareVideoEncoderTest, InitializeAndFlush) {
options.frame_size = gfx::Size(640, 480);
bool output_called = false;
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
- [&](VideoEncoderOutput, base::Optional<VideoEncoder::CodecDescription>) {
+ [&](VideoEncoderOutput, absl::optional<VideoEncoder::CodecDescription>) {
output_called = true;
});
@@ -262,7 +275,7 @@ TEST_P(SoftwareVideoEncoderTest, ForceAllKeyFrames) {
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
[&](VideoEncoderOutput output,
- base::Optional<VideoEncoder::CodecDescription> desc) {
+ absl::optional<VideoEncoder::CodecDescription> desc) {
EXPECT_TRUE(output.key_frame);
outputs_count++;
});
@@ -290,7 +303,7 @@ TEST_P(SoftwareVideoEncoderTest, ResizeFrames) {
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
[&](VideoEncoderOutput output,
- base::Optional<VideoEncoder::CodecDescription> desc) {
+ absl::optional<VideoEncoder::CodecDescription> desc) {
outputs_count++;
});
@@ -325,7 +338,7 @@ TEST_P(SoftwareVideoEncoderTest, OutputCountEqualsFrameCount) {
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
[&](VideoEncoderOutput output,
- base::Optional<VideoEncoder::CodecDescription> desc) {
+ absl::optional<VideoEncoder::CodecDescription> desc) {
EXPECT_NE(output.data, nullptr);
EXPECT_EQ(output.timestamp, frame_duration * outputs_count);
outputs_count++;
@@ -369,7 +382,7 @@ TEST_P(SoftwareVideoEncoderTest, EncodeAndDecode) {
VideoEncoder::OutputCB encoder_output_cb = base::BindLambdaForTesting(
[&, this](VideoEncoderOutput output,
- base::Optional<VideoEncoder::CodecDescription> desc) {
+ absl::optional<VideoEncoder::CodecDescription> desc) {
auto buffer =
DecoderBuffer::FromArray(std::move(output.data), output.size);
buffer->set_timestamp(output.timestamp);
@@ -400,8 +413,7 @@ TEST_P(SoftwareVideoEncoderTest, EncodeAndDecode) {
}
encoder_->Flush(ValidatingStatusCB());
- decoder_->Decode(DecoderBuffer::CreateEOSBuffer(), ValidatingStatusCB());
- RunUntilIdle();
+ DecodeAndWaitForStatus(DecoderBuffer::CreateEOSBuffer());
EXPECT_EQ(decoded_frames.size(), frames_to_encode.size());
for (auto i = 0u; i < decoded_frames.size(); i++) {
auto original_frame = frames_to_encode[i];
@@ -435,7 +447,7 @@ TEST_P(SVCVideoEncoderTest, EncodeClipTemporalSvc) {
VideoEncoder::OutputCB encoder_output_cb = base::BindLambdaForTesting(
[&](VideoEncoderOutput output,
- base::Optional<VideoEncoder::CodecDescription> desc) {
+ absl::optional<VideoEncoder::CodecDescription> desc) {
chunks.push_back(std::move(output));
});
@@ -476,12 +488,10 @@ TEST_P(SVCVideoEncoderTest, EncodeClipTemporalSvc) {
auto buffer = DecoderBuffer::CopyFrom(chunk.data.get(), chunk.size);
buffer->set_timestamp(chunk.timestamp);
buffer->set_is_key_frame(chunk.key_frame);
- decoder_->Decode(std::move(buffer), ValidatingStatusCB());
- RunUntilIdle();
+ DecodeAndWaitForStatus(std::move(buffer));
}
}
- decoder_->Decode(DecoderBuffer::CreateEOSBuffer(), ValidatingStatusCB());
- RunUntilIdle();
+ DecodeAndWaitForStatus(DecoderBuffer::CreateEOSBuffer());
int rate_decimator =
(1 << (options.temporal_layers - 1)) / (1 << max_layer);
@@ -504,7 +514,7 @@ TEST_P(H264VideoEncoderTest, AvcExtraData) {
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
[&](VideoEncoderOutput output,
- base::Optional<VideoEncoder::CodecDescription> desc) {
+ absl::optional<VideoEncoder::CodecDescription> desc) {
switch (outputs_count) {
case 0:
// First frame should have extra_data
@@ -549,7 +559,7 @@ TEST_P(H264VideoEncoderTest, AnnexB) {
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
[&](VideoEncoderOutput output,
- base::Optional<VideoEncoder::CodecDescription> desc) {
+ absl::optional<VideoEncoder::CodecDescription> desc) {
EXPECT_FALSE(desc.has_value());
EXPECT_NE(output.data, nullptr);
@@ -591,7 +601,7 @@ TEST_P(H264VideoEncoderTest, EncodeAndDecodeWithConfig) {
options.avc.produce_annexb = false;
struct ChunkWithConfig {
VideoEncoderOutput output;
- base::Optional<VideoEncoder::CodecDescription> desc;
+ absl::optional<VideoEncoder::CodecDescription> desc;
};
std::vector<scoped_refptr<VideoFrame>> frames_to_encode;
std::vector<scoped_refptr<VideoFrame>> decoded_frames;
@@ -602,7 +612,7 @@ TEST_P(H264VideoEncoderTest, EncodeAndDecodeWithConfig) {
VideoEncoder::OutputCB encoder_output_cb = base::BindLambdaForTesting(
[&](VideoEncoderOutput output,
- base::Optional<VideoEncoder::CodecDescription> desc) {
+ absl::optional<VideoEncoder::CodecDescription> desc) {
chunks.push_back({std::move(output), std::move(desc)});
});
@@ -632,9 +642,7 @@ TEST_P(H264VideoEncoderTest, EncodeAndDecodeWithConfig) {
if (chunk.desc.has_value()) {
if (decoder_)
- decoder_->Decode(DecoderBuffer::CreateEOSBuffer(),
- ValidatingStatusCB());
- RunUntilIdle();
+ DecodeAndWaitForStatus(DecoderBuffer::CreateEOSBuffer());
PrepareDecoder(options.frame_size, std::move(decoder_output_cb),
chunk.desc.value());
}
@@ -642,11 +650,9 @@ TEST_P(H264VideoEncoderTest, EncodeAndDecodeWithConfig) {
auto buffer = DecoderBuffer::FromArray(std::move(output.data), output.size);
buffer->set_timestamp(output.timestamp);
buffer->set_is_key_frame(output.key_frame);
- decoder_->Decode(std::move(buffer), ValidatingStatusCB());
- RunUntilIdle();
+ DecodeAndWaitForStatus(std::move(buffer));
}
- decoder_->Decode(DecoderBuffer::CreateEOSBuffer(), ValidatingStatusCB());
- RunUntilIdle();
+ DecodeAndWaitForStatus(DecoderBuffer::CreateEOSBuffer());
EXPECT_EQ(decoded_frames.size(), total_frames_count);
}
diff --git a/chromium/media/video/video_decode_accelerator.h b/chromium/media/video/video_decode_accelerator.h
index 5821cc9ece5..12a0c37b559 100644
--- a/chromium/media/video/video_decode_accelerator.h
+++ b/chromium/media/video/video_decode_accelerator.h
@@ -12,7 +12,6 @@
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/unguessable_token.h"
#include "media/base/bitstream_buffer.h"
#include "media/base/cdm_context.h"
@@ -22,6 +21,7 @@
#include "media/base/status.h"
#include "media/base/video_decoder_config.h"
#include "media/video/picture.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -156,7 +156,7 @@ class MEDIA_EXPORT VideoDecodeAccelerator {
// The CDM that the VDA should use to decode encrypted streams. Must be
// set to a valid ID if |is_encrypted|.
- base::Optional<base::UnguessableToken> cdm_id;
+ absl::optional<base::UnguessableToken> cdm_id;
// Whether the client supports deferred initialization.
bool is_deferred_initialization_allowed = false;
@@ -189,7 +189,7 @@ class MEDIA_EXPORT VideoDecodeAccelerator {
gfx::ColorSpace target_color_space;
// HDR metadata specified by the container.
- base::Optional<gfx::HDRMetadata> hdr_metadata;
+ absl::optional<gfx::HDRMetadata> hdr_metadata;
};
// Interface for collaborating with picture interface to provide memory for
diff --git a/chromium/media/video/video_encode_accelerator.cc b/chromium/media/video/video_encode_accelerator.cc
index e0e0fe45b9a..361e53ade2d 100644
--- a/chromium/media/video/video_encode_accelerator.cc
+++ b/chromium/media/video/video_encode_accelerator.cc
@@ -49,11 +49,11 @@ VideoEncodeAccelerator::Config::Config(
const gfx::Size& input_visible_size,
VideoCodecProfile output_profile,
uint32_t initial_bitrate,
- base::Optional<uint32_t> initial_framerate,
- base::Optional<uint32_t> gop_length,
- base::Optional<uint8_t> h264_output_level,
+ absl::optional<uint32_t> initial_framerate,
+ absl::optional<uint32_t> gop_length,
+ absl::optional<uint8_t> h264_output_level,
bool is_constrained_h264,
- base::Optional<StorageType> storage_type,
+ absl::optional<StorageType> storage_type,
ContentType content_type,
const std::vector<SpatialLayer>& spatial_layers)
: input_format(input_format),
diff --git a/chromium/media/video/video_encode_accelerator.h b/chromium/media/video/video_encode_accelerator.h
index 0bea721e347..3e0584a9d57 100644
--- a/chromium/media/video/video_encode_accelerator.h
+++ b/chromium/media/video/video_encode_accelerator.h
@@ -14,7 +14,6 @@
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "media/base/bitstream_buffer.h"
#include "media/base/media_export.h"
@@ -23,6 +22,7 @@
#include "media/base/video_frame.h"
#include "media/video/h264_parser.h"
#include "media/video/video_encoder_info.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
@@ -86,8 +86,8 @@ struct MEDIA_EXPORT BitstreamBufferMetadata final {
// Either |vp8| or |vp9| may be set, but not both of them. Presumably, it's
// also possible for none of them to be set.
- base::Optional<Vp8Metadata> vp8;
- base::Optional<Vp9Metadata> vp9;
+ absl::optional<Vp8Metadata> vp8;
+ absl::optional<Vp9Metadata> vp9;
};
// Video encoder interface.
@@ -100,6 +100,8 @@ class MEDIA_EXPORT VideoEncodeAccelerator {
const gfx::Size& max_resolution,
uint32_t max_framerate_numerator = 0u,
uint32_t max_framerate_denominator = 1u);
+ SupportedProfile(const SupportedProfile& other) = default;
+ SupportedProfile& operator=(const SupportedProfile& other) = default;
~SupportedProfile();
VideoCodecProfile profile;
gfx::Size min_resolution;
@@ -160,11 +162,11 @@ class MEDIA_EXPORT VideoEncodeAccelerator {
const gfx::Size& input_visible_size,
VideoCodecProfile output_profile,
uint32_t initial_bitrate,
- base::Optional<uint32_t> initial_framerate = base::nullopt,
- base::Optional<uint32_t> gop_length = base::nullopt,
- base::Optional<uint8_t> h264_output_level = base::nullopt,
+ absl::optional<uint32_t> initial_framerate = absl::nullopt,
+ absl::optional<uint32_t> gop_length = absl::nullopt,
+ absl::optional<uint8_t> h264_output_level = absl::nullopt,
bool is_constrained_h264 = false,
- base::Optional<StorageType> storage_type = base::nullopt,
+ absl::optional<StorageType> storage_type = absl::nullopt,
ContentType content_type = ContentType::kCamera,
const std::vector<SpatialLayer>& spatial_layers = {});
@@ -191,17 +193,17 @@ class MEDIA_EXPORT VideoEncodeAccelerator {
// Initial encoding framerate in frames per second. This is optional and
// VideoEncodeAccelerator should use |kDefaultFramerate| if not given.
- base::Optional<uint32_t> initial_framerate;
+ absl::optional<uint32_t> initial_framerate;
// Group of picture length for encoded output stream, indicates the
// distance between two key frames, i.e. IPPPIPPP would be represent as 4.
- base::Optional<uint32_t> gop_length;
+ absl::optional<uint32_t> gop_length;
// Codec level of encoded output stream for H264 only. This value should
// be aligned to the H264 standard definition of SPS.level_idc.
// If this is not given, VideoEncodeAccelerator selects one of proper H.264
// levels for |input_visible_size| and |initial_framerate|.
- base::Optional<uint8_t> h264_output_level;
+ absl::optional<uint8_t> h264_output_level;
// Indicates baseline profile or constrained baseline profile for H264 only.
bool is_constrained_h264;
@@ -211,7 +213,7 @@ class MEDIA_EXPORT VideoEncodeAccelerator {
// Encode().
// This is kShmem iff a video frame is mapped in user space.
// This is kDmabuf iff a video frame has dmabuf.
- base::Optional<StorageType> storage_type;
+ absl::optional<StorageType> storage_type;
// Indicates captured video (from a camera) or generated (screen grabber).
// Screen content has a number of special properties such as lack of noise,
@@ -225,6 +227,12 @@ class MEDIA_EXPORT VideoEncodeAccelerator {
// empty, VideoEncodeAccelerator should refer the width, height, bitrate and
// etc. of |spatial_layers|.
std::vector<SpatialLayer> spatial_layers;
+
+ // Currently it's Mac only! This flag forces Mac encoder to enforce low
+ // latency mode. Initialize() will fail if the system can't do it for some
+ // reason. See VTVideoEncodeAccelerator::require_low_delay_ for more
+ // details.
+ bool require_low_delay = true;
};
// Interface for clients that use VideoEncodeAccelerator. These callbacks will
diff --git a/chromium/media/video/video_encode_accelerator_adapter.cc b/chromium/media/video/video_encode_accelerator_adapter.cc
index 15c2888b9d5..8e47cf2406e 100644
--- a/chromium/media/video/video_encode_accelerator_adapter.cc
+++ b/chromium/media/video/video_encode_accelerator_adapter.cc
@@ -12,7 +12,6 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
-#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -37,7 +36,7 @@ VideoEncodeAccelerator::Config SetUpVeaConfig(
const VideoEncoder::Options& opts,
VideoPixelFormat format,
VideoFrame::StorageType storage_type) {
- base::Optional<uint32_t> initial_framerate;
+ absl::optional<uint32_t> initial_framerate;
if (opts.framerate.has_value())
initial_framerate = static_cast<uint32_t>(opts.framerate.value());
@@ -58,6 +57,9 @@ VideoEncodeAccelerator::Config SetUpVeaConfig(
config.spatial_layers.push_back(layer);
}
+ // We don't mind if Mac encoding will have higher latency on low resolutions.
+ config.require_low_delay = false;
+
const bool is_rgb =
format == PIXEL_FORMAT_XBGR || format == PIXEL_FORMAT_XRGB ||
format == PIXEL_FORMAT_ABGR || format == PIXEL_FORMAT_ARGB;
@@ -289,9 +291,9 @@ void VideoEncodeAcceleratorAdapter::EncodeOnAcceleratorThread(
StatusOr<scoped_refptr<VideoFrame>> result(nullptr);
if (use_gpu_buffer)
- result = PrepareGpuFrame(options_.frame_size, frame);
+ result = PrepareGpuFrame(input_coded_size_, frame);
else
- result = PrepareCpuFrame(options_.frame_size, frame);
+ result = PrepareCpuFrame(input_coded_size_, frame);
if (result.has_error()) {
auto status = std::move(result).error();
@@ -417,6 +419,7 @@ void VideoEncodeAcceleratorAdapter::RequireBitstreamBuffers(
size_t output_buffer_size) {
DCHECK_CALLED_ON_VALID_SEQUENCE(accelerator_sequence_checker_);
+ input_coded_size_ = input_coded_size;
input_buffer_size_ =
VideoFrame::AllocationSize(PIXEL_FORMAT_I420, input_coded_size);
@@ -438,7 +441,7 @@ void VideoEncodeAcceleratorAdapter::RequireBitstreamBuffers(
void VideoEncodeAcceleratorAdapter::BitstreamBufferReady(
int32_t buffer_id,
const BitstreamBufferMetadata& metadata) {
- base::Optional<CodecDescription> desc;
+ absl::optional<CodecDescription> desc;
VideoEncoderOutput result;
result.key_frame = metadata.key_frame;
result.timestamp = metadata.timestamp;
@@ -627,7 +630,7 @@ VideoEncodeAcceleratorAdapter::PrepareCpuFrame(
? ConvertToMemoryMappedFrame(src_frame)
: src_frame;
auto shared_frame = VideoFrame::WrapExternalData(
- PIXEL_FORMAT_I420, options_.frame_size, gfx::Rect(size), size,
+ PIXEL_FORMAT_I420, size, gfx::Rect(size), size,
mapping.GetMemoryAsSpan<uint8_t>().data(), mapping.size(),
src_frame->timestamp());
diff --git a/chromium/media/video/video_encode_accelerator_adapter.h b/chromium/media/video/video_encode_accelerator_adapter.h
index f190477a04d..b0248a3cc89 100644
--- a/chromium/media/video/video_encode_accelerator_adapter.h
+++ b/chromium/media/video/video_encode_accelerator_adapter.h
@@ -13,11 +13,11 @@
#include "base/containers/queue.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/unsafe_shared_memory_pool.h"
-#include "base/optional.h"
#include "base/synchronization/lock.h"
#include "media/base/media_export.h"
#include "media/base/video_encoder.h"
#include "media/video/video_encode_accelerator.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace base {
@@ -142,7 +142,7 @@ class MEDIA_EXPORT VideoEncodeAcceleratorAdapter
scoped_refptr<base::SequencedTaskRunner> callback_task_runner_;
State state_ = State::kNotInitialized;
- base::Optional<bool> flush_support_;
+ absl::optional<bool> flush_support_;
// True if underlying instance of VEA can handle GPU backed frames with a
// size different from what VEA was configured for.
@@ -166,6 +166,8 @@ class MEDIA_EXPORT VideoEncodeAcceleratorAdapter
VideoCodecProfile profile_ = VIDEO_CODEC_PROFILE_UNKNOWN;
Options options_;
OutputCB output_cb_;
+
+ gfx::Size input_coded_size_;
};
} // namespace media
diff --git a/chromium/media/video/video_encode_accelerator_adapter_test.cc b/chromium/media/video/video_encode_accelerator_adapter_test.cc
index f7cab8ab448..baa9c4fa0d3 100644
--- a/chromium/media/video/video_encode_accelerator_adapter_test.cc
+++ b/chromium/media/video/video_encode_accelerator_adapter_test.cc
@@ -11,7 +11,6 @@
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequenced_task_runner.h"
-#include "base/strings/stringprintf.h"
#include "base/task/thread_pool.h"
#include "base/test/bind.h"
#include "base/test/gmock_callback_support.h"
@@ -180,7 +179,7 @@ TEST_F(VideoEncodeAcceleratorAdapterTest, PreInitialize) {
VideoEncoder::Options options;
options.frame_size = gfx::Size(640, 480);
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
- [&](VideoEncoderOutput, base::Optional<VideoEncoder::CodecDescription>) {
+ [&](VideoEncoderOutput, absl::optional<VideoEncoder::CodecDescription>) {
});
adapter()->Initialize(profile_, options, std::move(output_cb),
@@ -194,7 +193,7 @@ TEST_F(VideoEncodeAcceleratorAdapterTest, InitializeAfterFirstFrame) {
int outputs_count = 0;
auto pixel_format = PIXEL_FORMAT_I420;
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
- [&](VideoEncoderOutput, base::Optional<VideoEncoder::CodecDescription>) {
+ [&](VideoEncoderOutput, absl::optional<VideoEncoder::CodecDescription>) {
outputs_count++;
});
@@ -223,7 +222,7 @@ TEST_F(VideoEncodeAcceleratorAdapterTest, TemporalSvc) {
auto pixel_format = PIXEL_FORMAT_I420;
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
[&](VideoEncoderOutput output,
- base::Optional<VideoEncoder::CodecDescription>) {
+ absl::optional<VideoEncoder::CodecDescription>) {
if (output.timestamp == base::TimeDelta::FromMilliseconds(1))
EXPECT_EQ(output.temporal_id, 1);
else
@@ -263,7 +262,7 @@ TEST_F(VideoEncodeAcceleratorAdapterTest, FlushDuringInitialize) {
int outputs_count = 0;
auto pixel_format = PIXEL_FORMAT_I420;
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
- [&](VideoEncoderOutput, base::Optional<VideoEncoder::CodecDescription>) {
+ [&](VideoEncoderOutput, absl::optional<VideoEncoder::CodecDescription>) {
outputs_count++;
});
@@ -293,7 +292,7 @@ TEST_F(VideoEncodeAcceleratorAdapterTest, InitializationError) {
int outputs_count = 0;
auto pixel_format = PIXEL_FORMAT_I420;
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
- [&](VideoEncoderOutput, base::Optional<VideoEncoder::CodecDescription>) {
+ [&](VideoEncoderOutput, absl::optional<VideoEncoder::CodecDescription>) {
outputs_count++;
});
@@ -323,7 +322,7 @@ TEST_P(VideoEncodeAcceleratorAdapterTest, TwoFramesResize) {
gfx::Size large_size(800, 600);
auto pixel_format = GetParam();
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
- [&](VideoEncoderOutput, base::Optional<VideoEncoder::CodecDescription>) {
+ [&](VideoEncoderOutput, absl::optional<VideoEncoder::CodecDescription>) {
outputs_count++;
});
@@ -359,7 +358,7 @@ TEST_F(VideoEncodeAcceleratorAdapterTest, AutomaticResizeSupport) {
gfx::Size small_size(480, 320);
auto pixel_format = PIXEL_FORMAT_NV12;
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
- [&](VideoEncoderOutput, base::Optional<VideoEncoder::CodecDescription>) {
+ [&](VideoEncoderOutput, absl::optional<VideoEncoder::CodecDescription>) {
outputs_count++;
});
@@ -398,7 +397,7 @@ TEST_P(VideoEncodeAcceleratorAdapterTest, RunWithAllPossibleInputConversions) {
adapter()->SetInputBufferPreferenceForTesting(input_kind);
VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
- [&](VideoEncoderOutput, base::Optional<VideoEncoder::CodecDescription>) {
+ [&](VideoEncoderOutput, absl::optional<VideoEncoder::CodecDescription>) {
outputs_count++;
});
diff --git a/chromium/media/video/video_encoder_info.h b/chromium/media/video/video_encoder_info.h
index f6d7fbb0ea1..892017e0d18 100644
--- a/chromium/media/video/video_encoder_info.h
+++ b/chromium/media/video/video_encoder_info.h
@@ -9,8 +9,8 @@
#include <string>
#include <vector>
-#include "base/optional.h"
#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace media {
diff --git a/chromium/media/video/vpx_video_encoder.h b/chromium/media/video/vpx_video_encoder.h
index 4fffc12237f..f3775caa838 100644
--- a/chromium/media/video/vpx_video_encoder.h
+++ b/chromium/media/video/vpx_video_encoder.h
@@ -8,7 +8,6 @@
#include <memory>
#include <vector>
-#include "base/callback_forward.h"
#include "media/base/media_export.h"
#include "media/base/video_encoder.h"
#include "media/base/video_frame_pool.h"
@@ -56,4 +55,4 @@ class MEDIA_EXPORT VpxVideoEncoder : public VideoEncoder {
};
} // namespace media
-#endif // MEDIA_VIDEO_VPX_VIDEO_ENCODER_H_ \ No newline at end of file
+#endif // MEDIA_VIDEO_VPX_VIDEO_ENCODER_H_
diff --git a/chromium/media/webrtc/DIR_METADATA b/chromium/media/webrtc/DIR_METADATA
index 7ae006c85b7..e28b9ae8a63 100644
--- a/chromium/media/webrtc/DIR_METADATA
+++ b/chromium/media/webrtc/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Blink>WebRTC>Audio"
diff --git a/chromium/media/webrtc/helpers.h b/chromium/media/webrtc/helpers.h
index 4e27fefcdf3..c748f86f58a 100644
--- a/chromium/media/webrtc/helpers.h
+++ b/chromium/media/webrtc/helpers.h
@@ -23,4 +23,4 @@ bool LeftAndRightChannelsAreSymmetric(const AudioBus& audio);
} // namespace media
-#endif // MEDIA_WEBRTC_WEBRTC_HELPERS_H_
+#endif // MEDIA_WEBRTC_HELPERS_H_
diff --git a/chromium/media/webrtc/webrtc_switches.cc b/chromium/media/webrtc/webrtc_switches.cc
index 3c16994bca6..051228d7519 100644
--- a/chromium/media/webrtc/webrtc_switches.cc
+++ b/chromium/media/webrtc/webrtc_switches.cc
@@ -20,6 +20,11 @@ const char kAgcStartupMinVolume[] = "agc-startup-min-volume";
namespace features {
+// When enabled we will tell WebRTC that we want to use the
+// Windows.Graphics.Capture API based DesktopCapturer, if it is available.
+const base::Feature kWebRtcAllowWgcDesktopCapturer{
+ "AllowWgcDesktopCapturer", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Enables multichannel capture audio to be processed without downmixing in the
// WebRTC audio processing module.
const base::Feature kWebRtcEnableCaptureMultiChannelApm{
@@ -36,4 +41,8 @@ const base::Feature kWebRtcAllow48kHzProcessingOnArm{
const base::Feature kWebRtcHybridAgc{"WebRtcHybridAgc",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Enables and configures the clipping control in the WebRTC analog AGC.
+const base::Feature kWebRtcAnalogAgcClippingControl{
+ "WebRtcAnalogAgcClippingControl", base::FEATURE_DISABLED_BY_DEFAULT};
+
} // namespace features
diff --git a/chromium/media/webrtc/webrtc_switches.h b/chromium/media/webrtc/webrtc_switches.h
index 1c223d9066c..c7675917c10 100644
--- a/chromium/media/webrtc/webrtc_switches.h
+++ b/chromium/media/webrtc/webrtc_switches.h
@@ -19,6 +19,9 @@ COMPONENT_EXPORT(MEDIA_WEBRTC) extern const char kAgcStartupMinVolume[];
namespace features {
COMPONENT_EXPORT(MEDIA_WEBRTC)
+extern const base::Feature kWebRtcAllowWgcDesktopCapturer;
+
+COMPONENT_EXPORT(MEDIA_WEBRTC)
extern const base::Feature kWebRtcEnableCaptureMultiChannelApm;
COMPONENT_EXPORT(MEDIA_WEBRTC)
@@ -27,6 +30,9 @@ extern const base::Feature kWebRtcAllow48kHzProcessingOnArm;
COMPONENT_EXPORT(MEDIA_WEBRTC)
extern const base::Feature kWebRtcHybridAgc;
+COMPONENT_EXPORT(MEDIA_WEBRTC)
+extern const base::Feature kWebRtcAnalogAgcClippingControl;
+
} // namespace features
#endif // MEDIA_WEBRTC_WEBRTC_SWITCHES_H_