| 328 | } |
| 329 | |
| 330 | bool VideoBackendAndroid::Player_Create(const VideoBackendPlayerInfo& info, VideoBackendPlayer& player) |
| 331 | { |
| 332 | PROFILE_CPU(); |
| 333 | player = VideoBackendPlayer(); |
| 334 | auto& playerAndroid = player.GetBackendState<VideoPlayerAndroid>(); |
| 335 | media_status_t status; |
| 336 | |
| 337 | // Load media |
| 338 | playerAndroid.Extractor = AMediaExtractor_new(); |
| 339 | if (!playerAndroid.Extractor) |
| 340 | { |
| 341 | VIDEO_API_ANDROID_ERROR(AMediaExtractor_new, 0); |
| 342 | return true; |
| 343 | } |
| 344 | FileReadStream* fileStream = nullptr; |
| 345 | if (!info.Url.StartsWith(TEXT("http"), StringSearchCase::IgnoreCase)) |
| 346 | { |
| 347 | if (info.Url.StartsWith(TEXT("Content/"), StringSearchCase::CaseSensitive)) |
| 348 | fileStream = FileReadStream::Open(Globals::ProjectFolder / info.Url); |
| 349 | else |
| 350 | fileStream = FileReadStream::Open(info.Url); |
| 351 | } |
| 352 | if (fileStream) |
| 353 | { |
| 354 | // File (AAsset* or Unix handle) |
| 355 | #if VIDEO_API_ANDROID_DEBUG |
| 356 | LOG(Info, "[VideoBackendAndroid] Loading local file '{}'", info.Url); |
| 357 | #endif |
| 358 | auto* mediaSource = AMediaDataSource_new(); |
| 359 | AMediaDataSource_setUserdata(mediaSource, fileStream); |
| 360 | AMediaDataSource_setReadAt(mediaSource, Android::AMediaDataSourceReadAt); |
| 361 | AMediaDataSource_setGetSize(mediaSource, Android::AMediaDataSourceGetSize); |
| 362 | AMediaDataSource_setClose(mediaSource, Android::AMediaDataSourceClose); |
| 363 | status = AMediaExtractor_setDataSourceCustom(playerAndroid.Extractor, mediaSource); |
| 364 | } |
| 365 | else |
| 366 | { |
| 367 | // Url |
| 368 | #if VIDEO_API_ANDROID_DEBUG |
| 369 | LOG(Info, "[VideoBackendAndroid] Loading url '{}'", info.Url); |
| 370 | #endif |
| 371 | const StringAsANSI<> url(info.Url.Get(), info.Url.Length()); |
| 372 | status = AMediaExtractor_setDataSource(playerAndroid.Extractor, url.Get()); |
| 373 | } |
| 374 | if (status != AMEDIA_OK) |
| 375 | { |
| 376 | VIDEO_API_ANDROID_ERROR(AMediaExtractor_setDataSource, status); |
| 377 | AMediaExtractor_delete(playerAndroid.Extractor); |
| 378 | return true; |
| 379 | } |
| 380 | |
| 381 | // Load tracks |
| 382 | playerAndroid.VideoTrackIndex = playerAndroid.AudioTrackIndex = MAX_uint16; |
| 383 | player.FrameRate = 24; |
| 384 | size_t tracks = AMediaExtractor_getTrackCount(playerAndroid.Extractor); |
| 385 | for (size_t trackIndex = 0; trackIndex < tracks; trackIndex++) |
| 386 | { |
| 387 | AMediaFormat* trackFormat = AMediaExtractor_getTrackFormat(playerAndroid.Extractor, trackIndex); |
nothing calls this directly
no test coverage detected