Skip to content

[video_player_videohole] Migrating from Platform Channels to Dart FFI - #1073

Merged
xiaowei-guan merged 47 commits into
flutter-tizen:mainfrom
gin7773:videohole/ffi_migration
Sep 16, 2026
Merged

xiaowei-guan merged 47 commits into
flutter-tizen:mainfrom
gin7773:videohole/ffi_migration

Conversation

@gin7773

@gin7773 gin7773 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Main changes:

  • Migrated from Platform Channels to Dart FFI.
  • Replaced EventChannel with FFI port for event callbacks.
  • Added JSON serialization for complex parameters.

Threading note

After migrating from Platform Channels to Dart FFI, some native calls are invoked synchronously from the Flutter UI thread rather than through the previous platform-channel handler path. The ecore_wl2 display path is marked with a TODO because those APIs are not thread-safe and will be revisited during the planned ecore-to-GLib migration.

Performance Comparison: FFI vs Platform Channel

Test Item / Iterations Method FFI avg (μs) Platform Channel avg (μs)
Simple Calls / 1000 each play 8,057 11,018
pause 1,611 3,332
setVolume 386 1,073
setLooping 265 674
setPlaybackSpeed 350 847
High Frequency Query / 1000 each getPosition 306 950
getDuration 895 1,407
getPosition+getDuration 1,026 2,464
String Transfer / 100 each getTrackInfo (video) 1,109 2,309
getTrackInfo (audio) 1,691 2,197
getTrackInfo (text) 470 973
SeekTo Call / 100 seekTo 51,414 148,544
Create+Dispose Cycle / 20 create+dispose 2,225,290 2,238,198
StartToPlay(create->play position > 0) / 20 / 346,540 365,580
Memory (RSS) /proc/self/status VmRSS 1,232 KB 5,088 KB
Conclusion
  • FFI is 2.5-3x faster than Platform Channel for lightweight calls, because it eliminates message serialization and thread-hopping overhead.
  • FFI is 1.5-3x faster for high-frequency queries, making it well-suited for polling scenarios such as progress-bar updates.
  • FFI's advantage narrows to ~1.4-2x for play/pause, because the dominant cost is the native player_start()/player_pause() pipeline restart, not communication.
  • FFI shows no difference for create→playing (347ms vs 366ms) and create+dispose (2225ms vs 2238ms), because over 99% of these durations come from the native media pipeline (media open, decoder init, first-frame decode), which is identical in both implementations.
  • FFI's memory footprint is 4x smaller (1232KB vs 5088KB RSS delta), making it more efficient for long-running sessions.

@gin7773
gin7773 marked this pull request as draft July 28, 2026 10:38
gin7773 added 6 commits July 29, 2026 18:01
- Add nlohmann/json single-header library to tizen/third_party/
- Replace handwritten JSON parser with nlohmann/json in ParseJsonMap()
- Simplify ParseCreateMessage() to use json library directly
- Add EncodableValueFromJson() helper for JSON to EncodableValue conversion

This change improves JSON parsing reliability by supporting:
- Escape characters in strings
- Nested objects and arrays
- Unicode characters
- Proper error handling with parse_error exceptions

Co-Authored-By: Cline SR
- Add UnregisterAllPlayerEventPorts() function in video_player.cc
- Add ffi_unregister_all_player_event_ports() FFI wrapper
- Add Dart bindings in ffi_messages.g.dart
- Call unregisterAllPlayerEventPorts() in init() to clean up ports on hot restart

This fix prevents Dart port leaks when the Dart VM is restarted
(e.g., hot restart during development) while the native process continues.

Co-Authored-By: Cline SR
- Fix FFI event port symbol name mismatch (ffi_register_dart_port)
- Call Prepare() after RestorePlayer for two-phase initialization
- Return true from Play() when already playing (idempotent)
- Remove duplicate play() call in restored event handler

Co-Authored-By: Cline SR
@xiaowei-guan
xiaowei-guan self-requested a review July 30, 2026 09:24
@gin7773
gin7773 marked this pull request as ready for review August 5, 2026 08:19
@gin7773
gin7773 requested a review from JSUYA August 5, 2026 08:19
@gin7773

gin7773 commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

You need to check the LICENSE in json.hpp. Please verify whether a separate license document needs to be included. For example, for WebRTC, if additional publication is required, the LICENSE is included like this: flutter_webrtc/tizen/third_party/svpng/LICENSE.

Please resolve the conflict and write a new PR targeting the main branch for the next PR update.

Add tizen/third_party/nlohmann_json directory with LICENSE information~

Comment thread packages/video_player_videohole/tizen/src/media_player.cc Outdated
Comment thread packages/video_player_videohole/CHANGELOG.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants