Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build/build_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@
#define BUILDFLAG_INTERNAL_USE_STARBOARD_MEDIA() (0)
#endif

#if defined(ENABLE_BUILDFLAG_USE_STARBOARD_URL_PLAYER)
#define BUILDFLAG_INTERNAL_USE_STARBOARD_URL_PLAYER() (1)
#else
#define BUILDFLAG_INTERNAL_USE_STARBOARD_URL_PLAYER() (0)
#endif

#if defined(ENABLE_BUILDFLAG_USE_EVERGREEN)
#define BUILDFLAG_INTERNAL_USE_EVERGREEN() (1)
#else
Expand Down
8 changes: 8 additions & 0 deletions cobalt/build/configs/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ config("buildflag_defines") {
defines += [ "ENABLE_BUILDFLAG_USE_STARBOARD_MEDIA" ]
}

# use_starboard_url_player and BUILDFLAG(USE_STARBOARD_URL_PLAYER) should be
# used to wrap URL-based player functionality (e.g., HLS via AVPlayer on
# tvOS). This is a derived capability that is true only for tvOS builds with
# Starboard media enabled.
if (use_starboard_url_player) {
defines += [ "ENABLE_BUILDFLAG_USE_STARBOARD_URL_PLAYER" ]
}

# use_evergreen and BUILDFLAG(USE_EVERGREEN) should be used for
# Evergreen-specific functionality, i.e. the Evergreen loader_app. Do not use
# this flag for hermetic build functionality, instead use
Expand Down
8 changes: 7 additions & 1 deletion media/base/renderer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
// found in the LICENSE file.

#include "media/base/renderer.h"

#include "base/logging.h"
#include "build/build_config.h"

namespace media {

Expand Down Expand Up @@ -34,7 +36,11 @@ std::string GetRendererName(RendererType renderer_type) {
#if BUILDFLAG(USE_STARBOARD_MEDIA)
case RendererType::kStarboard:
return "StarboardRenderer";
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
#if BUILDFLAG(USE_STARBOARD_URL_PLAYER)
case RendererType::kUrlPlayer:
return "UrlPlayerRenderer";
#endif // BUILDFLAG(USE_STARBOARD_URL_PLAYER)
}
}

Expand Down
10 changes: 8 additions & 2 deletions media/base/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "base/functional/callback.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/buffering_state.h"
#include "media/base/demuxer_stream.h"
#include "media/base/media_export.h"
Expand Down Expand Up @@ -39,10 +40,15 @@ enum class RendererType {
kTest = 11, // Renderer implementations used in tests
#if BUILDFLAG(USE_STARBOARD_MEDIA)
kStarboard = 12, // StarboardRendererFactory
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
#if BUILDFLAG(USE_STARBOARD_URL_PLAYER)
kUrlPlayer = 13, // UrlPlayerRendererClientFactory
kMaxValue = kUrlPlayer,
#elif BUILDFLAG(USE_STARBOARD_MEDIA)
kMaxValue = kStarboard,
#else // BUILDFLAG(USE_STARBOARD_MEDIA)
#else
kMaxValue = kTest,
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
#endif // BUILDFLAG(USE_STARBOARD_URL_PLAYER)
};

// Get the name of the Renderer for `renderer_type`. The returned name could be
Expand Down
4 changes: 4 additions & 0 deletions media/mojo/mojom/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ mojom("mojom") {
enabled_features += [ "use_starboard_media" ]
}

if (is_cobalt && use_starboard_url_player) {
enabled_features += [ "use_starboard_url_player" ]
}

shared_typemaps = [
{
types = [
Expand Down
2 changes: 2 additions & 0 deletions media/mojo/mojom/media_types.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,8 @@ enum RendererType {
kTest= 11, // Renderer implementations used in tests
[EnableIf=use_starboard_media]
kStarboard = 12, // StarboardRendererFactory
[EnableIf=use_starboard_url_player]
kUrlPlayer = 13, // UrlPlayerRendererClientFactory
};

// See media/base/demuxer.h for description.
Expand Down
13 changes: 11 additions & 2 deletions media/mojo/mojom/media_types_enum_mojom_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,11 @@ struct EnumTraits<media::mojom::RendererType, ::media::RendererType> {
#if BUILDFLAG(USE_STARBOARD_MEDIA)
case ::media::RendererType::kStarboard:
return media::mojom::RendererType::kStarboard;
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
#if BUILDFLAG(USE_STARBOARD_URL_PLAYER)
case ::media::RendererType::kUrlPlayer:
return media::mojom::RendererType::kUrlPlayer;
#endif // BUILDFLAG(USE_STARBOARD_URL_PLAYER)
}

NOTREACHED();
Expand Down Expand Up @@ -436,7 +440,12 @@ struct EnumTraits<media::mojom::RendererType, ::media::RendererType> {
case media::mojom::RendererType::kStarboard:
*output = ::media::RendererType::kStarboard;
return true;
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
#if BUILDFLAG(USE_STARBOARD_URL_PLAYER)
case media::mojom::RendererType::kUrlPlayer:
*output = ::media::RendererType::kUrlPlayer;
return true;
#endif // BUILDFLAG(USE_STARBOARD_URL_PLAYER)
}

NOTREACHED();
Expand Down
7 changes: 7 additions & 0 deletions starboard/build/buildflags.gni
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,10 @@ declare_args() {
is_cobalt && current_toolchain != host_toolchain &&
(!is_starboard || current_toolchain != v8_snapshot_toolchain)
}

if (is_ios) {
import("//build/config/apple/mobile_config.gni")
use_starboard_url_player = use_starboard_media && target_platform == "tvos"
} else {
use_starboard_url_player = false
}
Comment on lines +27 to +32

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think just use_starboard_url_player = use_starboard_media && is_ios is fine. A comment describing the variable would be good too.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If use_starboard_url_player = use_starboard_media && (is_ios || is_tvos), why not just use is_ios or is_tvos behind the code gated by use_starboard_media?

As both use_starboard_url_player and use_starboard_media are for Starboard Player, I think it's not ideal to introduce one more global build flag for a single Starboard platform.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback. Let me walk through the reasoning.

use_starboard_url_player is not a platform-specific flag, it is a capability flag. Today this capability is limited to tvOS, but conceptually it represents "this build can delegate playback to a platform URL player."

At the Starboard API layer, we already have SB_HAS(PLAYER_WITH_URL), the Starboard layer already treats URL player as a distinct capability with its own flag. However, that flag is defined in platform headers (starboard/tvos/shared/configuration_public.h) and is not available in GN, Mojom IDL, or upstream Chromium C++ files that do not include Starboard headers. So above Starboard, we need another way to express the same capability.

There is no is_tvos flag in the build system:

Unlike is_ios, is_mac, or is_linux, there is no general GN is_tvos variable.

Why a single GN variable is required:

Mojom [EnableIf=...] accepts only a single feature name from GN. It cannot express compound conditions like use_starboard_media && is_ios && target_platform == "tvos". So we need a dedicated GN variable for the Mojom gate. Leaving the Mojom methods ungated ("always present") is not viable either as it forces every platform to implement URL player methods.

We need these Mojom methods because in the URL player architecture the complete player lives in the GPU process, and we need IPC to share player status (duration, buffering info, etc.) back to the renderer/JS side.

Consistency across layers(like GN/Starboard/mojom/non-starboard):

Since we need a GN variable for the Mojom gate anyway, reusing the same derived flag in C++ keeps the URL player condition tied to one named capability. This is not trying to replace every tvOS platform guard in the tree. The platform-specific code can still use the appropriate platform guard for its layer. The point is narrower: URL player is a specific media capability, and the code that depends on that capability should not have to reconstruct it differently in each layer.

Using [EnableIf=is_ios] would work mechanically for the current tvOS build, but it would make the Mojom method availability depend on the iOS platform bucket rather than on URL-player support. That is the wrong boundary for this IPC. The URL-player methods are needed because this build uses the URL-player architecture, where playback state has to cross process boundaries, not simply because the build is in the iOS family.

With a named capability flag, the same concept is available consistently above the Starboard layer:

  • Starboard: SB_HAS(PLAYER_WITH_URL)
  • Mojom: [EnableIf=use_starboard_url_player]
  • Non-Starboard C++: BUILDFLAG(USE_STARBOARD_URL_PLAYER)

The same reasoning applies on the C++ side. We could continue using the compound check (BUILDFLAG(USE_STARBOARD_MEDIA) && BUILDFLAG(IS_IOS_TVOS)), but that condition is broader than URL player because it is also true for the regular Starboard media path. As URL player diverges further from the HTML5 player path, keeping that distinction explicit becomes more important.

The flag is derived, not independent:

This is not a new user-facing configuration. It is derived in one place:

use_starboard_url_player = use_starboard_media && is_ios

It is a named alias for the compound condition.

Naming:

We agree the current name is confusing. The use_starboard_ prefix makes this look like a sibling of use_starboard_media, while the intent is to describe URL player capability. We are happy to rename it to something clearer, for example enable_url_player, enable_platform_url_player, or has_player_with_url.

If we settle on a clearer name, for example enable_url_player, the Starboard-side define(SB_HAS_PLAYER_WITH_URL) could also be aligned in a follow-up. That is not required for these CLs stack, but it would make the capability naming more consistent across layers.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the place that tvOS need to delegate playbacks to SbPlayer using URL player? I haven't checked tvOS code yet, but I think there should be a way for tvOS to build it without additional GLOBAL build flags.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tvOS-specific delegation happens when HLS playback is initialized with a URL instead of demuxed media buffers.

Regular Starboard playback uses Chromium's media pipeline: Chromium fetches/demuxes the media and sends encoded buffers to Starboard through SbPlayerWriteSamples(). In that path Chromium owns most of the pipeline state.

The tvOS URL-player path is different. For HLS, tvOS needs to delegate playback to Apple's
AVPlayer. This native player accepts only URL of media file to play. In our Starboard layer that is exposed through the URL-player APIs in starboard/tvos/shared/media/url_player.h: SbUrlPlayerCreate, SbUrlPlayerSetDrmSystem, and SbUrlPlayerGetExtraInfo. Our main responsibility is to send player url from chromium world to starboard world where this player lives but using chromium media pipeline.

In the Chromium/Cobalt side, UrlPlayerRendererWrapper::InitializeWithUrl() carries the URL
into the GPU-side renderer. That reaches SbPlayerBridge::CreateUrlPlayer(), which calls
sbplayer_interface_->CreateUrlPlayer(...); the default implementation delegates to
SbUrlPlayerCreate().

Because AVPlayer owns manifest fetching, demuxing, buffering, decoding, and rendering in this
path, Chromium's normal demuxer/buffer pipeline is bypassed. But JS still needs media state such
as duration, buffered ranges, current time, ended/error, and encrypted init data. That is why
the URL-player path adds IPC/Mojom surface such as InitializeWithUrl() to send URL from renderer to GPU and player status updates( like duration, buffered ranges) from GPU to renderer for status plumbing.

I do not intend this to be an independent global knob. The flag is derived from the same tvOS/Starboard condition you mentioned. The reason it exists as a named build feature is that the affected code is above the Starboard layer: shared media/Mojo/Blink files do not include Starboard platform headers, so they cannot
use SB_HAS(PLAYER_WITH_URL). Mojom also cannot directly reference compound condition.; it needs
GN to expose a named feature for [EnableIf=...].

Once that named feature exists for Mojom, using the same flag consistently in GN and C++ means the URL-player capability is identified the same way at every layer above Starboard, rather than each layer reconstructing it from a different combination of platform and media flags.So this is effectively the "URL player capability" equivalent of SB_HAS(PLAYER_WITH_URL) for the layers above Starboard.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments are splits to many PRs, but refer to https://github.com/youtube/cobalt/pull/11066/changes#r3501515960.

2 changes: 2 additions & 0 deletions tools/metrics/histograms/enums.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19946,6 +19946,8 @@ from previous Chrome versions.
<int value="11" label="kTest"/>
<!-- Cobalt: Renderer for Starboard (SbPlayer) -->
<int value="12" label="kStarboard"/>
<!-- Cobalt: URL-based renderer for native HLS on tvOS -->
<int value="13" label="kUrlPlayer"/>
</enum>

<enum name="MediaSessionAction">
Expand Down
Loading