Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(WIP, DNS) [android] Support snapshot of media implementation #4584

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
4 changes: 4 additions & 0 deletions starboard/android/shared/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ static_library("starboard_platform") {
if (sb_evergreen_compatible_use_libunwind) {
deps += [ "//third_party/llvm-project/libunwind:unwind_starboard" ]
}

snapshotted_media_files = []

sources -= snapshotted_media_files
}

static_library("starboard_base_symbolize") {
Expand Down
2 changes: 1 addition & 1 deletion starboard/android/shared/drm_system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ SbDrmSessionRequestType SbDrmSessionRequestTypeFromMediaDrmKeyRequestType(

// This has to be defined outside the above anonymous namespace to be picked up
// by the comparison of std::vector<SbDrmKeyId>.
bool operator==(const SbDrmKeyId& left, const SbDrmKeyId& right) {
inline bool operator==(const SbDrmKeyId& left, const SbDrmKeyId& right) {
if (left.identifier_size != right.identifier_size) {
return false;
}
Expand Down
27 changes: 27 additions & 0 deletions starboard/shared/media_snapshot/media_snapshot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2024 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef STARBOARD_SHARED_MEDIA_SNAPSHOT_MEDIA_SNAPSHOT_H_
#define STARBOARD_SHARED_MEDIA_SNAPSHOT_MEDIA_SNAPSHOT_H_

inline int GetMediaSnapshotVersion() {
#if SB_API_VERSION >= 15
return 2500;
#else // SB_API_VERSION >= 15
// Media snapshot is only support for C25 or after.
return 0;
#endif // SB_API_VERSION >= 15
}

#endif // STARBOARD_SHARED_MEDIA_SNAPSHOT_MEDIA_SNAPSHOT_H_
65 changes: 65 additions & 0 deletions starboard/tools/media/find_dependency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python3
# Copyright 2024 The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
'''Create a snapshot of an Starboard Android TV implementation under
'starboard/android/shared/media_<version>/'. This helps with running
multiple Starboard media implementations side by side.'''

import gn_utils
import os
import source_utils
import utils

_GN_TARGETS = [
'//starboard/common:common',
'//starboard/android/shared:starboard_platform',
'//starboard/shared/starboard/media:media_util',
'//starboard/shared/starboard/player/filter:filter_based_player_sources',
]


def find_inbound_dependencies(project_root_dir, ninja_output_pathname):
project_root_dir = os.path.abspath(os.path.expanduser(project_root_dir))
assert os.path.isdir(project_root_dir)
assert os.path.isdir(os.path.join(project_root_dir, ninja_output_pathname))

source_files = []

for target in _GN_TARGETS:
source_files += gn_utils.get_source_pathnames(project_root_dir,
ninja_output_pathname, target)

source_files.sort()

non_media_files = [f for f in source_files if not utils.is_media_file(f)]

inbound_dependencies = {}

for file in non_media_files:
with open(file, encoding='utf-8') as f:
content = f.read()

headers = source_utils.extract_project_includes(content)
for header in headers:
if utils.is_media_file(header):
if header in inbound_dependencies:
inbound_dependencies[header].append(file)
else:
inbound_dependencies[header] = [file]

for header, sources in inbound_dependencies.items():
print(header)
for source in sources:
print(' ', source)
print()
179 changes: 179 additions & 0 deletions starboard/tools/media/gn_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#!/usr/bin/env python3
# Copyright 2024 The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
'''Utility to work with gn.'''

from datetime import datetime
from textwrap import dedent

import os
import subprocess

_COPYRIGHT_HEADER = '''\
# Copyright {0} The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
'''

_GN_CONTENT = '''\
static_library("{0}") {{
check_includes = false

sources = [
{1}
]

configs += [ "//starboard/build/config:starboard_implementation" ]

public_deps = [
"//starboard/common",
]
deps = [
"//base", # TODO: Remove once the upstream is refined.
"//third_party/opus",
]
}}
'''

_CANONICAL_GN_CONTENT = '''
static_library("media_snapshot") {{
check_includes = false

sources = [
{0}
]

configs += [ "//starboard/build/config:starboard_implementation" ]

public_deps = [
"//starboard/common",
]
}}
'''


def _get_copyright_header():
return dedent(_COPYRIGHT_HEADER).format(datetime.now().year)


def convert_source_list_to_gn_format(project_root_dir, gn_pathname,
file_pathnames):
abs_project_root_dir = os.path.abspath(project_root_dir)
abs_gn_pathname = os.path.abspath(gn_pathname)

# The gn file should reside in the project dir.
assert abs_gn_pathname.find(abs_project_root_dir) == 0

source_list = []

for file_pathname in file_pathnames:
abs_file_pathname = os.path.abspath(file_pathname)
if os.path.dirname(file_pathname) == os.path.dirname(abs_gn_pathname):
rel_file_pathname = os.path.basename(file_pathname)
else:
rel_file_pathname = '//' + os.path.relpath(abs_file_pathname,
abs_project_root_dir)
source_list.append('\"' + rel_file_pathname + '",')

source_list.sort()

return source_list


def create_gn_file(project_root_dir, gn_pathname, library_name, file_pathnames):
abs_project_root_dir = os.path.abspath(project_root_dir)
abs_gn_pathname = os.path.abspath(gn_pathname)

# The gn file should reside in the project dir.
assert abs_gn_pathname.find(abs_project_root_dir) == 0

source_list = convert_source_list_to_gn_format(project_root_dir, gn_pathname,
file_pathnames)

with open(abs_gn_pathname, 'w+', encoding='utf-8') as f:
f.write(_get_copyright_header() + '\n' +
_GN_CONTENT.format(library_name, '\n '.join(source_list)))


def _get_full_pathname(project_root_dir, pathname_in_gn_format):
''' Transform a pathname in gn format to unix format

project_root_dir: The project root directory in unix format, e.g.
'/home/.../cobalt'
pathname_in_gn_format: A pathname in gn format, e.g. '//starboard/media.h'
return: the full path name as '/home/.../cobalt/starboard/media.h'
'''
assert pathname_in_gn_format.find('//') == 0
pathname_in_gn_format = pathname_in_gn_format[2:]
pathname = os.path.join(project_root_dir, pathname_in_gn_format)
if pathname.find('game-activity') < 0:
assert os.path.isfile(pathname), pathname
return pathname


def get_source_pathnames(project_root_dir, ninja_root_dir,
target_name_or_names):
''' Return a list of source files built for a particular ninja target or a
series of target names.

project_root_dir: The project root directory, e.g. '/home/.../cobalt'
ninja_root_dir: The output directory, e.g. 'out/android-arm'
target_name_or_names: The name of the ninja target, e.g.
'//cobalt/base:base', or a series pf target names, e.g.
('//cobalt/base:base', '//cobalt/media:media').
'''
if isinstance(target_name_or_names, str):
target_name = target_name_or_names
else:
# Assume `target_name_or_names` is a container
source_files = []
for target_name in target_name_or_names:
source_files += get_source_pathnames(project_root_dir, ninja_root_dir,
target_name)
return source_files

saved_python_path = os.environ['PYTHONPATH']
os.environ['PYTHONPATH'] = os.path.abspath(
project_root_dir) + ':' + os.environ['PYTHONPATH']
gn_desc = subprocess.check_output(['gn', 'desc', ninja_root_dir, target_name],
cwd=project_root_dir).decode('utf-8')
os.environ['PYTHONPATH'] = saved_python_path

# gn_desc is in format:
# ...
# sources
# //path/name1
# //path/name2
# <empty line>
# ...
lines = gn_desc.split('\n')
sources_index = lines.index('sources')
assert sources_index >= 0
sources_index += 1
sources = []
while sources_index < len(lines) and lines[sources_index]:
sources.append(
_get_full_pathname(project_root_dir, lines[sources_index].strip()))
sources_index += 1
return sources
Loading
Loading