diff --git a/lib/src/impl/agora_video_view_impl.dart b/lib/src/impl/agora_video_view_impl.dart index 96433d656..6047cddd4 100644 --- a/lib/src/impl/agora_video_view_impl.dart +++ b/lib/src/impl/agora_video_view_impl.dart @@ -181,11 +181,6 @@ class _AgoraRtcRenderTextureState extends State @override void maybeCreateChannel(int viewId, String viewType) { - if (!(defaultTargetPlatform == TargetPlatform.macOS || - defaultTargetPlatform == TargetPlatform.iOS)) { - return; - } - // Only handle render mode on macos at this time final textureId = widget.controller.getTextureId(); methodChannel = MethodChannel('agora_rtc_engine/texture_render_$textureId'); @@ -257,11 +252,6 @@ class _AgoraRtcRenderTextureState extends State @override Widget build(BuildContext context) { if (widget.controller.getTextureId() != kTextureNotInit) { - if (!(defaultTargetPlatform == TargetPlatform.macOS || - defaultTargetPlatform == TargetPlatform.iOS)) { - return buildTexure(widget.controller.getTextureId()); - } - // Only handle render mode on macos at this time if (_height != 0 && _width != 0) { Widget result = buildTexure(widget.controller.getTextureId()); diff --git a/test_shard/rendering_test/integration_test/agora_video_view_render_test.dart b/test_shard/rendering_test/integration_test/agora_video_view_render_test.dart index f2d19902b..89a2d2dce 100644 --- a/test_shard/rendering_test/integration_test/agora_video_view_render_test.dart +++ b/test_shard/rendering_test/integration_test/agora_video_view_render_test.dart @@ -1001,66 +1001,399 @@ void main() { ); group( - 'AgoraVideoView Windows', + 'AgoraVideoView Windows screenshot test', () { - testWidgets( - 'local rendering screenshot test', - (WidgetTester tester) async { - final onFrameCompleter = Completer(); - late RtcEngineEx rtcEngine; + group('local rendering', () { + testWidgets( + 'do not handle render mode', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; - await tester.pumpWidget(LocalVideoView( - useFlutterTexture: true, - onRendered: (RtcEngineEx engine) async { - if (onFrameCompleter.isCompleted) { - return; - } + await tester.pumpWidget(LocalVideoView( + useFlutterTexture: true, + isRenderModeTest: false, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } - rtcEngine = engine; - onFrameCompleter.complete(); - }, - )); + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); - await tester.pumpAndSettle(const Duration(seconds: 10)); + await tester.pumpAndSettle(const Duration(seconds: 10)); - await onFrameCompleter.future; - await tester.pumpAndSettle(const Duration(seconds: 10)); + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); - await matchScreenShotDesktop( - rtcEngine, 'windows.agora_video_view_render.texture.local'); + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.local.donot_handle_rendermode'); - await waitDisposed(tester, binding); - }, - ); + await waitDisposed(tester, binding); + }, + ); - testWidgets( - 'remote rendering screenshot test', - (WidgetTester tester) async { - final onFrameCompleter = Completer(); - late RtcEngineEx rtcEngine; + testWidgets( + 'render mode default', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; - await tester.pumpWidget(RemoteVideoView( - useFlutterTexture: true, - onRendered: (RtcEngineEx engine) async { - if (onFrameCompleter.isCompleted) { - return; - } - rtcEngine = engine; - onFrameCompleter.complete(); - }, - )); + await tester.pumpWidget(LocalVideoView( + useFlutterTexture: true, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } - await tester.pumpAndSettle(const Duration(seconds: 10)); + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); - await onFrameCompleter.future; - await tester.pumpAndSettle(const Duration(seconds: 10)); + await tester.pumpAndSettle(const Duration(seconds: 10)); - await matchScreenShotDesktop( - rtcEngine, 'windows.agora_video_view_render.texture.remote'); + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); - await waitDisposed(tester, binding); - }, - ); + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.local.with_default_rendermode'); + + await waitDisposed(tester, binding); + }, + ); + + testWidgets( + 'render mode renderModeHidden', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; + + await tester.pumpWidget(LocalVideoView( + useFlutterTexture: true, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + renderModeType: RenderModeType.renderModeHidden, + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } + + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); + + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.local.with_rendermodehidden'); + + await waitDisposed(tester, binding); + }, + ); + + testWidgets( + 'render mode renderModeFit', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; + + await tester.pumpWidget(LocalVideoView( + useFlutterTexture: true, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + renderModeType: RenderModeType.renderModeFit, + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } + + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); + + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.local.with_rendermodefit'); + + await waitDisposed(tester, binding); + }, + ); + + testWidgets( + 'render mode renderModeAdaptive', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; + + await tester.pumpWidget(LocalVideoView( + useFlutterTexture: true, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + renderModeType: RenderModeType.renderModeAdaptive, + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } + + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); + + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.local.with_rendermodeadaptive'); + + await waitDisposed(tester, binding); + }, + ); + + testWidgets( + 'render mode default and videoMirrorModeDisabled', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; + + await tester.pumpWidget(LocalVideoView( + useFlutterTexture: true, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + mirrorModeType: VideoMirrorModeType.videoMirrorModeDisabled, + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } + + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); + + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.local.with_default_rendermode.with_videomirrormodedisabled'); + + await waitDisposed(tester, binding); + }, + ); + }); + + group('remote rendering', () { + testWidgets( + 'do not handle render mode', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; + + await tester.pumpWidget(RemoteVideoView( + useFlutterTexture: true, + isRenderModeTest: false, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); + + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.remote.donot_handle_rendermode'); + + await waitDisposed(tester, binding); + }, + ); + + testWidgets( + 'render mode default', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; + + await tester.pumpWidget(RemoteVideoView( + useFlutterTexture: true, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); + + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.remote.with_default_rendermode'); + + await waitDisposed(tester, binding); + }, + ); + + testWidgets( + 'render mode renderModeHidden', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; + + await tester.pumpWidget(RemoteVideoView( + useFlutterTexture: true, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + renderModeType: RenderModeType.renderModeHidden, + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); + + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.remote.with_rendermodehidden'); + + await waitDisposed(tester, binding); + }, + ); + + testWidgets( + 'render mode renderModeFit', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; + + await tester.pumpWidget(RemoteVideoView( + useFlutterTexture: true, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + renderModeType: RenderModeType.renderModeFit, + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); + + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.remote.with_rendermodefit'); + + await waitDisposed(tester, binding); + }, + ); + + testWidgets( + 'render mode renderModeAdaptive', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; + + await tester.pumpWidget(RemoteVideoView( + useFlutterTexture: true, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + renderModeType: RenderModeType.renderModeAdaptive, + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); + + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.remote.with_rendermodeadaptive'); + + await waitDisposed(tester, binding); + }, + ); + + testWidgets( + 'render mode default and videoMirrorModeDisabled', + (WidgetTester tester) async { + final onFrameCompleter = Completer(); + late RtcEngineEx rtcEngine; + + await tester.pumpWidget(RemoteVideoView( + useFlutterTexture: true, + url: + 'https://download.agora.io/demo/test/agoravideoview_rendering_test_solid_spilt_asymmetrical.mp4', + mirrorModeType: VideoMirrorModeType.videoMirrorModeEnabled, + onRendered: (RtcEngineEx engine) async { + if (onFrameCompleter.isCompleted) { + return; + } + rtcEngine = engine; + onFrameCompleter.complete(); + }, + )); + + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await onFrameCompleter.future; + await tester.pumpAndSettle(const Duration(seconds: 10)); + + await matchScreenShotDesktop(rtcEngine, + 'windows.agora_video_view_render.texture.remote.with_default_rendermodede.with_videoMirrorModeEnabled'); + + await waitDisposed(tester, binding); + }, + ); + }); }, skip: !Platform.isWindows, ); diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.donot_handle_rendermode.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.donot_handle_rendermode.png new file mode 100644 index 000000000..7e26121ba Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.donot_handle_rendermode.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_default_rendermode.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_default_rendermode.png new file mode 100644 index 000000000..f4f8940d7 Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_default_rendermode.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_default_rendermode.with_videomirrormodedisabled.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_default_rendermode.with_videomirrormodedisabled.png new file mode 100644 index 000000000..816cdc2fb Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_default_rendermode.with_videomirrormodedisabled.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_rendermodeadaptive.png similarity index 60% rename from test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.png rename to test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_rendermodeadaptive.png index b3f91c178..9084de1a6 100644 Binary files a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.png and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_rendermodeadaptive.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_rendermodefit.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_rendermodefit.png new file mode 100644 index 000000000..7388f8906 Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_rendermodefit.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_rendermodehidden.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_rendermodehidden.png new file mode 100644 index 000000000..f4f8940d7 Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.local.with_rendermodehidden.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.donot_handle_rendermode.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.donot_handle_rendermode.png new file mode 100644 index 000000000..1f715c201 Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.donot_handle_rendermode.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.png deleted file mode 100644 index dc0c5675b..000000000 Binary files a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.png and /dev/null differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_default_rendermode.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_default_rendermode.png new file mode 100644 index 000000000..1f715c201 Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_default_rendermode.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_default_rendermodede.with_videoMirrorModeEnabled.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_default_rendermodede.with_videoMirrorModeEnabled.png new file mode 100644 index 000000000..bc2b51a94 Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_default_rendermodede.with_videoMirrorModeEnabled.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_rendermodeadaptive.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_rendermodeadaptive.png new file mode 100644 index 000000000..f1daa31d9 Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_rendermodeadaptive.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_rendermodefit.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_rendermodefit.png new file mode 100644 index 000000000..b47d155ae Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_rendermodefit.png differ diff --git a/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_rendermodehidden.png b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_rendermodehidden.png new file mode 100644 index 000000000..599f0b9ac Binary files /dev/null and b/test_shard/rendering_test/screenshot/windows.agora_video_view_render.texture.remote.with_rendermodehidden.png differ diff --git a/windows/include/agora_rtc_engine/texture_render.h b/windows/include/agora_rtc_engine/texture_render.h index d2d590482..6f2836c2f 100644 --- a/windows/include/agora_rtc_engine/texture_render.h +++ b/windows/include/agora_rtc_engine/texture_render.h @@ -40,6 +40,7 @@ class TextureRender : public agora::iris::IrisVideoFrameBufferDelegate flutter::TextureRegistrar *registrar_; agora::iris::IrisVideoFrameBufferManager *videoFrameBufferManager_; flutter::TextureVariant texture_; + std::unique_ptr> method_channel_; int64_t texture_id_ = -1; // std::unique_ptr> channel_; // unsigned int uid_; diff --git a/windows/texture_render.cc b/windows/texture_render.cc index 44e0d2522..a8c4bca5a 100644 --- a/windows/texture_render.cc +++ b/windows/texture_render.cc @@ -21,6 +21,11 @@ TextureRender::TextureRender(flutter::BinaryMessenger *messenger, pixel_buffer_(new FlutterDesktopPixelBuffer{nullptr, 0, 0}) { texture_id_ = registrar_->RegisterTexture(&texture_); + + method_channel_ = std::make_unique>( + messenger, + "agora_rtc_engine/texture_render_" + std::to_string(texture_id_), + &flutter::StandardMethodCodec::GetInstance()); } TextureRender::~TextureRender() @@ -43,6 +48,11 @@ void TextureRender::OnVideoFrameReceived(const IrisVideoFrame &video_frame, delete[] pixel_buffer_->buffer; } pixel_buffer_->buffer = new uint8_t[video_frame.y_buffer_length]; + + flutter::EncodableMap args = { + {EncodableValue("width"), EncodableValue(video_frame.width)}, + {EncodableValue("height"), EncodableValue(video_frame.height)}}; + method_channel_->InvokeMethod("onSizeChanged", std::make_unique(EncodableValue(args))); } memcpy((void *)pixel_buffer_->buffer, video_frame.y_buffer, video_frame.y_buffer_length);