15 Commits

Author SHA1 Message Date
Konsta
ff8c9e0aec sepolicy: escape dots 2023-09-27 19:43:36 +03:00
Konsta
af52e8b4e1 sepolicy: define cec hal domain 2023-08-22 19:16:39 +03:00
Konsta
9c62ce999b add hdmi cec hal
* Based on AOSP yukawa HDMI-CEC HAL
  https://android.googlesource.com/device/amlogic/yukawa/+/refs/heads/main/hal/hdmicec/
2023-07-25 15:26:48 +03:00
Konsta
acc4b35086 add generic keylayout
* Copy from frameworks/base/data/keyboards/Generic.kl
2023-07-25 15:26:30 +03:00
Konsta
4e10f632e1 overlay: mark device as not mobile data capable
* d1e1b35604
  291415806f
2023-07-24 13:50:58 +03:00
Konsta
1adc59b4db ueventd: adjust media/video node permissions for ffmpeg
* ffmpeg_codec2 now runs as user media
2023-04-27 17:09:39 +03:00
Konsta
c5c3e50da2 sepolicy: remove alsa_loop 2023-04-11 10:55:06 +03:00
Konsta
556e2c3278 hdmi audio: remove local VC4 HDMI configuration
* This was updated in alsa-lib v1.2.7 so use the upstream config.
2023-03-12 17:41:25 +02:00
nename0
95838474b1 hdmi audio: add default values to vendor.prop 2023-03-06 11:05:02 +02:00
nename0
ba68930423 hdmi audio: remove alsa_loop service 2023-03-06 11:04:54 +02:00
nename0
2960d80f8d hdmi audio: add new audio HAL module with alsa instead of tinyalsa 2023-03-06 11:04:45 +02:00
Konsta
f724b0f13a sepolicy: add ffmpeg service
* Fixes https://github.com/raspberry-vanilla/android_local_manifest/issues/7
* ABC OCD
2023-02-22 20:34:15 +02:00
Konsta
71e3493aa7 ffmpeg: integrate into build and enable h.265 hw decoder by default
* Use codec ranks to switch between decoders.
2023-01-30 14:36:00 +02:00
Konsta
6cd5b54d6e v4l2: enable h.264 hw decoder & encoder by default
* Use codec ranks to switch between decoders/encoders.
2023-01-30 14:34:46 +02:00
Konsta
842583bff1 v4l2: enable h264 hardware encoder 2023-01-09 17:47:19 +02:00
20 changed files with 1959 additions and 173 deletions

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2015 The Android Open Source Project
// Copyright (C) 2021-2022 KonstaKANG
// Copyright (C) 2021-2023 KonstaKANG
//
// SPDX-License-Identifier: Apache-2.0
@@ -22,3 +22,22 @@ cc_library_shared {
],
cflags: ["-Wno-unused-parameter"],
}
cc_library_shared {
name: "audio.primary.rpi_hdmi",
relative_install_path: "hw",
proprietary: true,
srcs: ["audio_hw_hdmi.c"],
include_dirs: [
"external/expat/lib",
"system/media/audio_effects/include",
"system/media/audio_utils/include",
],
header_libs: ["libhardware_headers"],
shared_libs: [
"libcutils",
"liblog",
"libasound",
],
cflags: ["-Wno-unused-parameter"],
}

770
audio/audio_hw_hdmi.c Normal file
View File

@@ -0,0 +1,770 @@
/*
* Copyright (C) 2016 The Android Open Source Project
* Copyright (C) 2021-2023 KonstaKANG
*
* 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.
*/
#define LOG_TAG "audio_hw_rpi_hdmi"
//#define LOG_NDEBUG 0
#include <errno.h>
#include <malloc.h>
#include <pthread.h>
#include <stdint.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <log/log.h>
#include <cutils/str_parms.h>
#include <cutils/properties.h>
#include <hardware/hardware.h>
#include <system/audio.h>
#include <hardware/audio.h>
#include <alsa/asoundlib.h>
#include <audio_utils/resampler.h>
#include <audio_utils/echo_reference.h>
#include <hardware/audio_effect.h>
#include <audio_effects/effect_aec.h>
/* Minimum granularity - Arbitrary but small value */
#define CODEC_BASE_FRAME_COUNT 32
/* number of base blocks in a short period (low latency) */
#define PERIOD_MULTIPLIER 32 /* 21 ms */
/* number of frames per short period (low latency) */
#define PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * PERIOD_MULTIPLIER)
/* number of pseudo periods for low latency playback */
#define PLAYBACK_PERIOD_COUNT 4
#define PLAYBACK_PERIOD_START_THRESHOLD 2
#define CODEC_SAMPLING_RATE 48000
#define CHANNEL_STEREO 2
#define MIN_WRITE_SLEEP_US 5000
struct stub_stream_in {
struct audio_stream_in stream;
};
struct alsa_audio_device {
struct audio_hw_device hw_device;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
int devices;
struct alsa_stream_in *active_input;
struct alsa_stream_out *active_output;
bool mic_mute;
};
struct alsa_stream_out {
struct audio_stream_out stream;
struct alsa_audio_device *dev;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
snd_pcm_t *pcm;
snd_pcm_uframes_t period_size;
unsigned int periods;
snd_pcm_uframes_t buffer_size;
bool unavailable;
int standby;
snd_pcm_uframes_t written;
};
static void get_alsa_device_name(char *name) {
char hdmiDevice[PROPERTY_VALUE_MAX];
property_get("persist.audio.hdmi.device", hdmiDevice, "vc4hdmi0");
// use card configured in vc4-hdmi.conf to get IEC958 subframe conversion
sprintf(name, "default:CARD=%s", hdmiDevice);
}
/* must be called with hw device and output stream mutexes locked */
static int start_output_stream(struct alsa_stream_out *out)
{
struct alsa_audio_device *adev = out->dev;
if (out->unavailable)
return -ENODEV;
char device_name[PROPERTY_VALUE_MAX];
get_alsa_device_name(device_name);
ALOGI("start_output_stream: %s", device_name);
int r;
snd_pcm_t *pcm;
if ((r = snd_pcm_open(&pcm, device_name, SND_PCM_STREAM_PLAYBACK, 0) < 0)) {
ALOGE("cannot open pcm_out driver: %s", snd_strerror(r));
adev->active_output = NULL;
out->unavailable = true;
return -ENODEV;
}
out->pcm = pcm;
snd_pcm_hw_params_t *hwp;
snd_pcm_hw_params_alloca(&hwp);
snd_pcm_hw_params_any(pcm, hwp);
snd_pcm_hw_params_set_access(pcm, hwp, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(pcm, hwp, SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_rate(pcm, hwp, CODEC_SAMPLING_RATE, 0);
snd_pcm_hw_params_set_channels(pcm, hwp, CHANNEL_STEREO);
// Configurue period_size, periods and buffer_size
int dir = 0;
out->period_size = PERIOD_SIZE;
if ((r = snd_pcm_hw_params_set_period_size_near(pcm, hwp, &out->period_size, &dir)) < 0) {
ALOGE("cannot snd_pcm_hw_params_set_period_size_near: %s", snd_strerror(r));
adev->active_output = NULL;
out->unavailable = true;
return -ENODEV;
}
dir = 0;
out->periods = PLAYBACK_PERIOD_COUNT;
if ((r = snd_pcm_hw_params_set_periods_near(pcm, hwp, &out->periods, &dir)) < 0) {
ALOGE("cannot snd_pcm_hw_params_set_periods_near: %s", snd_strerror(r));
adev->active_output = NULL;
out->unavailable = true;
return -ENODEV;
}
out->buffer_size = out->period_size * out->periods;
if ((r = snd_pcm_hw_params_set_buffer_size_near(pcm, hwp, &out->buffer_size)) < 0) {
ALOGE("cannot snd_pcm_hw_params_set_buffer_size_near: %s", snd_strerror(r));
adev->active_output = NULL;
out->unavailable = true;
return -ENODEV;
}
//write the hw params
if ((r = snd_pcm_hw_params(pcm, hwp)) < 0) {
ALOGE("cannot snd_pcm_hw_params: %s", snd_strerror(r));
adev->active_output = NULL;
out->unavailable = true;
return -ENODEV;
}
//Software parameters
snd_pcm_sw_params_t *swp;
snd_pcm_sw_params_alloca(&swp);
snd_pcm_sw_params_current(pcm, swp);
// set avail_min to period_size
if ((r = snd_pcm_sw_params_set_avail_min(pcm, swp, out->period_size)) < 0) {
ALOGE("cannot snd_pcm_sw_params_set_avail_min: %s", snd_strerror(r));
adev->active_output = NULL;
out->unavailable = true;
return -ENODEV;
}
// set start_threshold to period_size * PLAYBACK_PERIOD_START_THRESHOLD
if ((r = snd_pcm_sw_params_set_start_threshold(pcm, swp, out->period_size * PLAYBACK_PERIOD_START_THRESHOLD)) < 0) {
ALOGE("cannot snd_pcm_sw_params_set_start_threshold: %s", snd_strerror(r));
adev->active_output = NULL;
out->unavailable = true;
return -ENODEV;
}
//write the sw params
if ((r = snd_pcm_sw_params(pcm, swp)) < 0) {
ALOGE("cannot snd_pcm_sw_params: %s", snd_strerror(r));
adev->active_output = NULL;
out->unavailable = true;
return -ENODEV;
}
// prepare
if ((r = snd_pcm_prepare(pcm)) < 0) {
ALOGE("cannot snd_pcm_prepare: %s", snd_strerror(r));
adev->active_output = NULL;
out->unavailable = true;
return -ENODEV;
}
adev->active_output = out;
return 0;
}
static uint32_t out_get_sample_rate(const struct audio_stream *stream)
{
ALOGV("out_get_sample_rate: %d", CODEC_SAMPLING_RATE);
return CODEC_SAMPLING_RATE;
}
static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
{
ALOGV("out_set_sample_rate: %d", 0);
return -ENOSYS;
}
static size_t out_get_buffer_size(const struct audio_stream *stream)
{
struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
/* return the closest majoring multiple of 16 frames, as
* audioflinger expects audio buffers to be a multiple of 16 frames */
size_t size = out->period_size;
size = ((size + 15) / 16) * 16;
ALOGV("out_get_buffer_size: %ld", (long int)size);
return size * audio_stream_out_frame_size((struct audio_stream_out *)stream);
}
static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
{
ALOGV("out_get_channels: %d", CHANNEL_STEREO);
return audio_channel_out_mask_from_count(CHANNEL_STEREO);
}
static audio_format_t out_get_format(const struct audio_stream *stream)
{
ALOGV("out_get_format: %d", AUDIO_FORMAT_PCM_16_BIT);
return AUDIO_FORMAT_PCM_16_BIT;
}
static int out_set_format(struct audio_stream *stream, audio_format_t format)
{
ALOGV("out_set_format: %d",format);
return -ENOSYS;
}
static int do_output_standby(struct alsa_stream_out *out)
{
struct alsa_audio_device *adev = out->dev;
if (!out->standby) {
snd_pcm_close(out->pcm);
out->pcm = NULL;
adev->active_output = NULL;
out->standby = 1;
}
return 0;
}
static int out_standby(struct audio_stream *stream)
{
ALOGV("out_standby");
struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
int status;
pthread_mutex_lock(&out->dev->lock);
pthread_mutex_lock(&out->lock);
status = do_output_standby(out);
pthread_mutex_unlock(&out->lock);
pthread_mutex_unlock(&out->dev->lock);
return status;
}
static int out_dump(const struct audio_stream *stream, int fd)
{
ALOGV("out_dump");
return 0;
}
static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
{
ALOGV("out_set_parameters");
struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
struct alsa_audio_device *adev = out->dev;
struct str_parms *parms;
char value[32];
int val = 0;
int ret = -EINVAL;
if (kvpairs == NULL || kvpairs[0] == 0) {
return 0;
}
parms = str_parms_create_str(kvpairs);
if (str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)) >= 0) {
val = atoi(value);
pthread_mutex_lock(&adev->lock);
pthread_mutex_lock(&out->lock);
if (((adev->devices & AUDIO_DEVICE_OUT_ALL) != val) && (val != 0)) {
adev->devices &= ~AUDIO_DEVICE_OUT_ALL;
adev->devices |= val;
}
pthread_mutex_unlock(&out->lock);
pthread_mutex_unlock(&adev->lock);
ret = 0;
}
str_parms_destroy(parms);
return ret;
}
static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
{
ALOGV("out_get_parameters");
return strdup("");
}
static uint32_t out_get_latency(const struct audio_stream_out *stream)
{
ALOGV("out_get_latency");
struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
// latency = buffer_size / rate
return (out->buffer_size * 1000) / CODEC_SAMPLING_RATE;
}
static int out_set_volume(struct audio_stream_out *stream, float left,
float right)
{
ALOGV("out_set_volume: Left:%f Right:%f", left, right);
return 0;
}
static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
size_t bytes)
{
int ret;
struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
struct alsa_audio_device *adev = out->dev;
size_t frame_size = audio_stream_out_frame_size(stream);
snd_pcm_uframes_t out_frames = bytes / frame_size;
/* acquiring hw device mutex systematically is useful if a low priority thread is waiting
* on the output stream mutex - e.g. executing select_mode() while holding the hw device
* mutex
*/
pthread_mutex_lock(&adev->lock);
pthread_mutex_lock(&out->lock);
if (out->standby) {
ret = start_output_stream(out);
if (ret != 0) {
pthread_mutex_unlock(&adev->lock);
goto exit;
}
out->standby = 0;
}
pthread_mutex_unlock(&adev->lock);
ALOGV("out_write: out_frames:%ld", (long int)out_frames);
ret = snd_pcm_writei(out->pcm, buffer, out_frames);
if (ret == out_frames) {
out->written += out_frames;
}
exit:
pthread_mutex_unlock(&out->lock);
if (ret != out_frames) {
if (ret == -EPIPE) {
ALOGE("underrun deteced -> redo snd_pcm_prepare");
snd_pcm_prepare(out->pcm);
} else {
ALOGE("out_write err: %s", snd_strerror(ret));
usleep((int64_t)bytes * 1000000 / audio_stream_out_frame_size(stream) /
out_get_sample_rate(&stream->common));
}
}
return bytes;
}
static int out_get_render_position(const struct audio_stream_out *stream,
uint32_t *dsp_frames)
{
*dsp_frames = 0;
ALOGV("out_get_render_position: dsp_frames: %p", dsp_frames);
return -EINVAL;
}
static int out_get_presentation_position(const struct audio_stream_out *stream,
uint64_t *frames, struct timespec *timestamp)
{
struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
int ret = -1;
if (out->pcm) {
snd_pcm_uframes_t avail;
int r;
if ((r = snd_pcm_htimestamp(out->pcm, &avail, timestamp)) == 0) {
int64_t signed_frames = (int64_t)(out->written) - out->buffer_size + avail;
if (signed_frames >= 0) {
*frames = signed_frames;
ret = 0;
}
ALOGV("out_get_presentation_position: %ld", (long int)(*frames));
} else {
ALOGE("out_get_presentation_position: err: %s", snd_strerror(r));
}
} else {
ALOGV("out_get_presentation_position: stream in standby");
}
return ret;
}
static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
{
ALOGV("out_add_audio_effect: %p", effect);
return 0;
}
static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
{
ALOGV("out_remove_audio_effect: %p", effect);
return 0;
}
static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
int64_t *timestamp)
{
*timestamp = 0;
ALOGV("out_get_next_write_timestamp: %ld", (long int)(*timestamp));
return -EINVAL;
}
/** audio_stream_in implementation **/
static uint32_t in_get_sample_rate(const struct audio_stream *stream)
{
ALOGV("in_get_sample_rate");
return 8000;
}
static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
{
ALOGV("in_set_sample_rate: %d", rate);
return -ENOSYS;
}
static size_t in_get_buffer_size(const struct audio_stream *stream)
{
ALOGV("in_get_buffer_size: %d", 320);
return 320;
}
static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
{
ALOGV("in_get_channels: %d", AUDIO_CHANNEL_IN_MONO);
return AUDIO_CHANNEL_IN_MONO;
}
static audio_format_t in_get_format(const struct audio_stream *stream)
{
return AUDIO_FORMAT_PCM_16_BIT;
}
static int in_set_format(struct audio_stream *stream, audio_format_t format)
{
return -ENOSYS;
}
static int in_standby(struct audio_stream *stream)
{
return 0;
}
static int in_dump(const struct audio_stream *stream, int fd)
{
return 0;
}
static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
{
return 0;
}
static char * in_get_parameters(const struct audio_stream *stream,
const char *keys)
{
return strdup("");
}
static int in_set_gain(struct audio_stream_in *stream, float gain)
{
return 0;
}
static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
size_t bytes)
{
ALOGV("in_read: bytes %zu", bytes);
/* XXX: fake timing for audio input */
usleep((int64_t)bytes * 1000000 / audio_stream_in_frame_size(stream) /
in_get_sample_rate(&stream->common));
memset(buffer, 0, bytes);
return bytes;
}
static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
{
return 0;
}
static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
{
return 0;
}
static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
{
return 0;
}
static int adev_open_output_stream(struct audio_hw_device *dev,
audio_io_handle_t handle,
audio_devices_t devices,
audio_output_flags_t flags,
struct audio_config *config,
struct audio_stream_out **stream_out,
const char *address __unused)
{
ALOGV("adev_open_output_stream...");
struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev;
struct alsa_stream_out *out;
int ret = 0;
out = (struct alsa_stream_out *)calloc(1, sizeof(struct alsa_stream_out));
if (!out)
return -ENOMEM;
out->stream.common.get_sample_rate = out_get_sample_rate;
out->stream.common.set_sample_rate = out_set_sample_rate;
out->stream.common.get_buffer_size = out_get_buffer_size;
out->stream.common.get_channels = out_get_channels;
out->stream.common.get_format = out_get_format;
out->stream.common.set_format = out_set_format;
out->stream.common.standby = out_standby;
out->stream.common.dump = out_dump;
out->stream.common.set_parameters = out_set_parameters;
out->stream.common.get_parameters = out_get_parameters;
out->stream.common.add_audio_effect = out_add_audio_effect;
out->stream.common.remove_audio_effect = out_remove_audio_effect;
out->stream.get_latency = out_get_latency;
out->stream.set_volume = out_set_volume;
out->stream.write = out_write;
out->stream.get_render_position = out_get_render_position;
out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
out->stream.get_presentation_position = out_get_presentation_position;
out->period_size = PERIOD_SIZE;
out->periods = PLAYBACK_PERIOD_COUNT;
out->buffer_size = out->period_size * out->periods;
out->dev = ladev;
out->standby = 1;
out->unavailable = false;
config->format = out_get_format(&out->stream.common);
config->channel_mask = out_get_channels(&out->stream.common);
config->sample_rate = out_get_sample_rate(&out->stream.common);
*stream_out = &out->stream;
/* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger. */
ret = 0;
return ret;
}
static void adev_close_output_stream(struct audio_hw_device *dev,
struct audio_stream_out *stream)
{
ALOGV("adev_close_output_stream...");
free(stream);
}
static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
{
ALOGV("adev_set_parameters");
return -ENOSYS;
}
static char * adev_get_parameters(const struct audio_hw_device *dev,
const char *keys)
{
ALOGV("adev_get_parameters");
return strdup("");
}
static int adev_init_check(const struct audio_hw_device *dev)
{
ALOGV("adev_init_check");
return 0;
}
static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
{
ALOGV("adev_set_voice_volume: %f", volume);
return -ENOSYS;
}
static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
{
ALOGV("adev_set_master_volume: %f", volume);
return -ENOSYS;
}
static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
{
ALOGV("adev_get_master_volume: %f", *volume);
return -ENOSYS;
}
static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
{
ALOGV("adev_set_master_mute: %d", muted);
return -ENOSYS;
}
static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
{
ALOGV("adev_get_master_mute: %d", *muted);
return -ENOSYS;
}
static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
{
ALOGV("adev_set_mode: %d", mode);
return 0;
}
static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
{
ALOGV("adev_set_mic_mute: %d",state);
return -ENOSYS;
}
static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
{
ALOGV("adev_get_mic_mute");
return -ENOSYS;
}
static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
const struct audio_config *config)
{
ALOGV("adev_get_input_buffer_size: %d", 320);
return 320;
}
static int adev_open_input_stream(struct audio_hw_device __unused *dev,
audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
struct audio_stream_in **stream_in,
audio_input_flags_t flags __unused,
const char *address __unused,
audio_source_t source __unused)
{
struct stub_stream_in *in;
ALOGV("adev_open_input_stream...");
in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
if (!in)
return -ENOMEM;
in->stream.common.get_sample_rate = in_get_sample_rate;
in->stream.common.set_sample_rate = in_set_sample_rate;
in->stream.common.get_buffer_size = in_get_buffer_size;
in->stream.common.get_channels = in_get_channels;
in->stream.common.get_format = in_get_format;
in->stream.common.set_format = in_set_format;
in->stream.common.standby = in_standby;
in->stream.common.dump = in_dump;
in->stream.common.set_parameters = in_set_parameters;
in->stream.common.get_parameters = in_get_parameters;
in->stream.common.add_audio_effect = in_add_audio_effect;
in->stream.common.remove_audio_effect = in_remove_audio_effect;
in->stream.set_gain = in_set_gain;
in->stream.read = in_read;
in->stream.get_input_frames_lost = in_get_input_frames_lost;
*stream_in = &in->stream;
return 0;
}
static void adev_close_input_stream(struct audio_hw_device *dev,
struct audio_stream_in *in)
{
ALOGV("adev_close_input_stream...");
return;
}
static int adev_dump(const audio_hw_device_t *device, int fd)
{
ALOGV("adev_dump");
return 0;
}
static int adev_close(hw_device_t *device)
{
ALOGV("adev_close");
free(device);
return 0;
}
static int adev_open(const hw_module_t* module, const char* name,
hw_device_t** device)
{
struct alsa_audio_device *adev;
ALOGV("adev_open: %s", name);
if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
return -EINVAL;
adev = calloc(1, sizeof(struct alsa_audio_device));
if (!adev)
return -ENOMEM;
adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
adev->hw_device.common.module = (struct hw_module_t *) module;
adev->hw_device.common.close = adev_close;
adev->hw_device.init_check = adev_init_check;
adev->hw_device.set_voice_volume = adev_set_voice_volume;
adev->hw_device.set_master_volume = adev_set_master_volume;
adev->hw_device.get_master_volume = adev_get_master_volume;
adev->hw_device.set_master_mute = adev_set_master_mute;
adev->hw_device.get_master_mute = adev_get_master_mute;
adev->hw_device.set_mode = adev_set_mode;
adev->hw_device.set_mic_mute = adev_set_mic_mute;
adev->hw_device.get_mic_mute = adev_get_mic_mute;
adev->hw_device.set_parameters = adev_set_parameters;
adev->hw_device.get_parameters = adev_get_parameters;
adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
adev->hw_device.open_output_stream = adev_open_output_stream;
adev->hw_device.close_output_stream = adev_close_output_stream;
adev->hw_device.open_input_stream = adev_open_input_stream;
adev->hw_device.close_input_stream = adev_close_input_stream;
adev->hw_device.dump = adev_dump;
adev->devices = AUDIO_DEVICE_NONE;
*device = &adev->hw_device.common;
return 0;
}
static struct hw_module_methods_t hal_module_methods = {
.open = adev_open,
};
struct audio_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = AUDIO_MODULE_API_VERSION_0_1,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = AUDIO_HARDWARE_MODULE_ID,
.name = "Raspberry Pi audio hdmi HW HAL",
.author = "The Android Open Source Project",
.methods = &hal_module_methods,
},
};

View File

@@ -1,68 +0,0 @@
# Configuration for the VC4-HDMI sound card using software IEC958
# subframe conversion
<confdir:pcm/hdmi.conf>
vc4-hdmi.pcm.hdmi.0 {
@args [ CARD AES0 AES1 AES2 AES3 ]
@args.CARD {
type string
}
@args.AES0 {
type integer
}
@args.AES1 {
type integer
}
@args.AES2 {
type integer
}
@args.AES3 {
type integer
}
type iec958
slave {
format IEC958_SUBFRAME_LE
pcm {
type hooks
slave.pcm {
type hw
card $CARD
device 0
}
hooks.0 {
type ctl_elems
hook_args [
{
name "IEC958 Playback Default"
interface PCM
optional true
lock true
preserve true
value [ $AES0 $AES1 $AES2 $AES3 ]
}
]
}
}
}
status [ $AES0 $AES1 $AES2 $AES3 ]
}
# default with plug
vc4-hdmi.pcm.default {
@args [ CARD ]
@args.CARD {
type string
}
type plug
slave.pcm {
type softvol
slave.pcm {
@func concat
strings [ "hdmi:" $CARD ]
}
control {
name "PCM Playback Volume"
card $CARD
}
}
}

View File

@@ -21,7 +21,7 @@ disable_overscan=1
# Graphics acceleration
dtoverlay=vc4-kms-v3d
dtoverlay=cma,cma-384
dtoverlay=cma,cma-512
# I2C
#dtparam=i2c_arm=on
@@ -42,4 +42,4 @@ dtoverlay=dwc2,dr_mode=otg
[all]
# V4L2
#dtoverlay=rpivid-v4l2
dtoverlay=rpivid-v4l2

17
cec/Android.bp Normal file
View File

@@ -0,0 +1,17 @@
// Copyright (C) 2019 The Android Open-Source Project
// Copyright (C) 2021-2022 KonstaKANG
//
// SPDX-License-Identifier: Apache-2.0
cc_library_shared {
name: "hdmi_cec.rpi",
relative_install_path: "hw",
proprietary: true,
srcs: ["hdmi_cec.c"],
cflags: ["-Werror"],
shared_libs: [
"liblog",
"libcutils",
"libhardware",
],
}

616
cec/hdmi_cec.c Normal file
View File

@@ -0,0 +1,616 @@
/*
* Copyright (C) 2019 BayLibre, SAS.
* Copyright (C) 2021-2022 KonstaKANG
*
* 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.
*/
#define LOG_TAG "hdmi_cec"
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <poll.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/cec.h>
#include <sys/eventfd.h>
#include <log/log.h>
#include <cutils/properties.h>
#include <hardware/hdmi_cec.h>
typedef struct hdmicec_context
{
hdmi_cec_device_t device; /* must be first */
int cec_fd;
unsigned int vendor_id;
unsigned int type;
unsigned int version;
struct hdmi_port_info port_info;
event_callback_t p_event_cb;
void *cb_arg;
pthread_t thread;
int exit_fd;
pthread_mutex_t options_lock;
bool cec_enabled;
bool cec_control_enabled;
} hdmicec_context_t;
static int hdmicec_add_logical_address(const struct hdmi_cec_device *dev, cec_logical_address_t addr)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)dev;
unsigned int la_type = CEC_LOG_ADDR_TYPE_UNREGISTERED;
unsigned int all_dev_types = 0;
unsigned int prim_type = 0xff;
struct cec_log_addrs laddrs;
int ret;
ALOGD("%s: addr:%x\n", __func__, addr);
if (addr >= CEC_ADDR_BROADCAST)
return -1;
ret = ioctl(ctx->cec_fd, CEC_ADAP_G_LOG_ADDRS, &laddrs);
if (ret)
return ret;
memset(&laddrs, 0, sizeof(laddrs));
laddrs.cec_version = ctx->version;
laddrs.vendor_id = ctx->vendor_id;
switch (addr) {
case CEC_LOG_ADDR_TV:
prim_type = CEC_OP_PRIM_DEVTYPE_TV;
la_type = CEC_LOG_ADDR_TYPE_TV;
all_dev_types = CEC_OP_ALL_DEVTYPE_TV;
break;
case CEC_LOG_ADDR_RECORD_1:
case CEC_LOG_ADDR_RECORD_2:
case CEC_LOG_ADDR_RECORD_3:
prim_type = CEC_OP_PRIM_DEVTYPE_RECORD;
la_type = CEC_LOG_ADDR_TYPE_RECORD;
all_dev_types = CEC_OP_ALL_DEVTYPE_RECORD;
break;
case CEC_LOG_ADDR_TUNER_1:
case CEC_LOG_ADDR_TUNER_2:
case CEC_LOG_ADDR_TUNER_3:
case CEC_LOG_ADDR_TUNER_4:
prim_type = CEC_OP_PRIM_DEVTYPE_TUNER;
la_type = CEC_LOG_ADDR_TYPE_TUNER;
all_dev_types = CEC_OP_ALL_DEVTYPE_TUNER;
break;
case CEC_LOG_ADDR_PLAYBACK_1:
case CEC_LOG_ADDR_PLAYBACK_2:
case CEC_LOG_ADDR_PLAYBACK_3:
prim_type = CEC_OP_PRIM_DEVTYPE_PLAYBACK;
la_type = CEC_LOG_ADDR_TYPE_PLAYBACK;
all_dev_types = CEC_OP_ALL_DEVTYPE_PLAYBACK;
laddrs.flags = CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU;
break;
case CEC_LOG_ADDR_AUDIOSYSTEM:
prim_type = CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM;
la_type = CEC_LOG_ADDR_TYPE_AUDIOSYSTEM;
all_dev_types = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM;
break;
case CEC_LOG_ADDR_SPECIFIC:
prim_type = CEC_OP_PRIM_DEVTYPE_PROCESSOR;
la_type = CEC_LOG_ADDR_TYPE_SPECIFIC;
all_dev_types = CEC_OP_ALL_DEVTYPE_SWITCH;
break;
case CEC_ADDR_RESERVED_1:
case CEC_ADDR_RESERVED_2:
case CEC_ADDR_UNREGISTERED:
laddrs.flags = CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK;
break;
}
laddrs.num_log_addrs = 1;
laddrs.log_addr[0] = addr;
laddrs.log_addr_type[0] = la_type;
laddrs.primary_device_type[0] = prim_type;
laddrs.all_device_types[0] = all_dev_types;
laddrs.features[0][0] = 0;
laddrs.features[0][1] = 0;
ret = ioctl(ctx->cec_fd, CEC_ADAP_S_LOG_ADDRS, &laddrs);
if (ret) {
ALOGD("%s: %m\n", __func__);
return ret;
}
ALOGD("%s: log_addr_mask=%x\n", __func__, laddrs.log_addr_mask);
return 0;
}
static void hdmicec_clear_logical_address(const struct hdmi_cec_device *dev)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)dev;
struct cec_log_addrs laddrs;
int ret;
memset(&laddrs, 0, sizeof(laddrs));
ret = ioctl(ctx->cec_fd, CEC_ADAP_S_LOG_ADDRS, &laddrs);
if (ret)
ALOGD("%s: %m\n", __func__);
}
static int hdmicec_get_physical_address(const struct hdmi_cec_device *dev, uint16_t *addr)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)dev;
int ret = ioctl(ctx->cec_fd, CEC_ADAP_G_PHYS_ADDR, addr);
if (ret)
ALOGD("%s: %m\n", __func__);
return ret;
}
static int hdmicec_send_message(const struct hdmi_cec_device *dev, const cec_message_t *msg)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)dev;
struct cec_msg cec_msg;
int ret;
pthread_mutex_lock(&ctx->options_lock);
bool cec_enabled = ctx->cec_enabled;
pthread_mutex_unlock(&ctx->options_lock);
if (!cec_enabled) {
return HDMI_RESULT_FAIL;
}
ALOGD("%s: len=%u\n", __func__, (unsigned int)msg->length);
memset(&cec_msg, 0, sizeof(cec_msg));
cec_msg.msg[0] = (msg->initiator << 4) | msg->destination;
memcpy(&cec_msg.msg[1], msg->body, msg->length);
cec_msg.len = msg->length + 1;
ret = ioctl(ctx->cec_fd, CEC_TRANSMIT, &cec_msg);
if (ret) {
ALOGD("%s: %m\n", __func__);
return HDMI_RESULT_FAIL;
}
if (cec_msg.tx_status != CEC_TX_STATUS_OK)
ALOGD("%s: tx_status=%d\n", __func__, cec_msg.tx_status);
switch (cec_msg.tx_status) {
case CEC_TX_STATUS_OK:
return HDMI_RESULT_SUCCESS;
case CEC_TX_STATUS_ARB_LOST:
return HDMI_RESULT_BUSY;
case CEC_TX_STATUS_NACK:
return HDMI_RESULT_NACK;
default:
if (cec_msg.tx_status & CEC_TX_STATUS_NACK)
return HDMI_RESULT_NACK;
return HDMI_RESULT_FAIL;
}
}
static void hdmicec_register_event_callback(const struct hdmi_cec_device *dev,
event_callback_t callback, void *arg)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)dev;
ctx->p_event_cb = callback;
ctx->cb_arg = arg;
}
static void hdmicec_get_version(const struct hdmi_cec_device *dev, int *version)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)dev;
*version = ctx->version;
}
static void hdmicec_get_vendor_id(const struct hdmi_cec_device *dev, uint32_t *vendor_id)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)dev;
*vendor_id = ctx->vendor_id;
}
static void hdmicec_get_port_info(const struct hdmi_cec_device *dev,
struct hdmi_port_info *list[], int *total)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)dev;
int ret;
ret = ioctl(ctx->cec_fd, CEC_ADAP_G_PHYS_ADDR, &ctx->port_info.physical_address);
if (ret)
ALOGD("%s: %m\n", __func__);
ALOGD("type:%s, id:%d, cec support:%d, arc support:%d, physical address:%x",
ctx->port_info.type ? "output" : "input",
ctx->port_info.port_id,
ctx->port_info.cec_supported,
ctx->port_info.arc_supported,
ctx->port_info.physical_address);
*list = &ctx->port_info;
*total = 1;
}
static void hdmicec_set_option(const struct hdmi_cec_device *dev, int flag, int value)
{
struct hdmicec_context* ctx = (struct hdmicec_context*)dev;
ALOGD("%s: flag=%d, value=%d", __func__, flag, value);
switch (flag) {
case HDMI_OPTION_ENABLE_CEC:
pthread_mutex_lock(&ctx->options_lock);
ctx->cec_enabled = (value == 1 ? true : false);
pthread_mutex_unlock(&ctx->options_lock);
break;
case HDMI_OPTION_WAKEUP:
// Not valid for playback devices
break;
case HDMI_OPTION_SYSTEM_CEC_CONTROL:
pthread_mutex_lock(&ctx->options_lock);
ctx->cec_control_enabled = (value == 1 ? true : false);
pthread_mutex_unlock(&ctx->options_lock);
break;
}
}
static int hdmicec_is_connected(const struct hdmi_cec_device *dev, int port_id)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)dev;
int ret;
(void)port_id;
ret = ioctl(ctx->cec_fd, CEC_ADAP_G_PHYS_ADDR,
&ctx->port_info.physical_address);
if (ret) {
ALOGD("%s: %m\n", __func__);
return ret;
}
if (ctx->port_info.physical_address == CEC_PHYS_ADDR_INVALID)
return false;
return true;
}
static int get_opcode(struct cec_msg* message) {
return (((uint8_t)message->msg[1]) & 0xff);
}
static int get_first_param(struct cec_msg* message) {
return (((uint8_t)message->msg[2]) & 0xff);
}
static bool is_power_ui_command(struct cec_msg* message) {
int ui_command = get_first_param(message);
switch (ui_command) {
case CEC_OP_UI_CMD_POWER:
case CEC_OP_UI_CMD_DEVICE_ROOT_MENU:
case CEC_OP_UI_CMD_POWER_ON_FUNCTION:
return true;
default:
return false;
}
}
static bool is_transferable_in_sleep(struct cec_msg* message) {
int opcode = get_opcode(message);
switch (opcode) {
case CEC_MESSAGE_ABORT:
case CEC_MESSAGE_DEVICE_VENDOR_ID:
case CEC_MESSAGE_GET_CEC_VERSION:
case CEC_MESSAGE_GET_MENU_LANGUAGE:
case CEC_MESSAGE_GIVE_DEVICE_POWER_STATUS:
case CEC_MESSAGE_GIVE_DEVICE_VENDOR_ID:
case CEC_MESSAGE_GIVE_OSD_NAME:
case CEC_MESSAGE_GIVE_PHYSICAL_ADDRESS:
case CEC_MESSAGE_REPORT_PHYSICAL_ADDRESS:
case CEC_MESSAGE_REPORT_POWER_STATUS:
case CEC_MESSAGE_SET_OSD_NAME:
case CEC_MESSAGE_DECK_CONTROL:
case CEC_MESSAGE_PLAY:
return true;
case CEC_MESSAGE_USER_CONTROL_PRESSED:
return is_power_ui_command(message);
default:
return false;
}
}
static void *event_thread(void *arg)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)arg;
int ret;
struct pollfd ufds[3] = {
{ ctx->cec_fd, POLLIN, 0 },
{ ctx->cec_fd, POLLERR, 0 },
{ ctx->exit_fd, POLLIN, 0 },
};
ALOGI("%s start!", __func__);
while (1) {
ufds[0].revents = 0;
ufds[1].revents = 0;
ufds[2].revents = 0;
ret = poll(ufds, 3, -1);
if (ret <= 0)
continue;
if (ufds[2].revents == POLLIN) /* Exit */
break;
if (ufds[1].revents == POLLERR) { /* CEC Event */
hdmi_event_t event = { };
struct cec_event ev;
ret = ioctl(ctx->cec_fd, CEC_DQEVENT, &ev);
if (ret)
continue;
pthread_mutex_lock(&ctx->options_lock);
bool cec_enabled = ctx->cec_enabled;
pthread_mutex_unlock(&ctx->options_lock);
if (!cec_enabled) {
continue;
}
if (ev.event == CEC_EVENT_STATE_CHANGE) {
event.type = HDMI_EVENT_HOT_PLUG;
event.dev = &ctx->device;
event.hotplug.port_id = 1;
if (ev.state_change.phys_addr == CEC_PHYS_ADDR_INVALID)
event.hotplug.connected = false;
else
event.hotplug.connected = true;
if (ctx->p_event_cb != NULL) {
ctx->p_event_cb(&event, ctx->cb_arg);
} else {
ALOGE("no event callback for hotplug\n");
}
}
}
if (ufds[0].revents == POLLIN) { /* CEC Driver */
struct cec_msg msg = { };
hdmi_event_t event = { };
ret = ioctl(ctx->cec_fd, CEC_RECEIVE, &msg);
if (ret) {
ALOGE("%s: CEC_RECEIVE error (%m)\n", __func__);
continue;
}
if (msg.rx_status != CEC_RX_STATUS_OK) {
ALOGD("%s: rx_status=%d\n", __func__, msg.rx_status);
continue;
}
pthread_mutex_lock(&ctx->options_lock);
bool cec_enabled = ctx->cec_enabled;
pthread_mutex_unlock(&ctx->options_lock);
if (!cec_enabled) {
continue;
}
pthread_mutex_lock(&ctx->options_lock);
bool cec_control_enabled = ctx->cec_control_enabled;
pthread_mutex_unlock(&ctx->options_lock);
if (!cec_control_enabled && !is_transferable_in_sleep(&msg)) {
ALOGD("%s: filter message in standby mode\n", __func__);
continue;
}
if (ctx->p_event_cb != NULL) {
event.type = HDMI_EVENT_CEC_MESSAGE;
event.dev = &ctx->device;
event.cec.initiator = msg.msg[0] >> 4;
event.cec.destination = msg.msg[0] & 0xf;
event.cec.length = msg.len - 1;
memcpy(event.cec.body, &msg.msg[1], msg.len - 1);
ctx->p_event_cb(&event, ctx->cb_arg);
} else {
ALOGE("no event callback for msg\n");
}
}
}
ALOGI("%s exit!", __func__);
return NULL;
}
static void hdmicec_set_arc(const struct hdmi_cec_device *dev, int port_id, int flag)
{
(void)dev;
(void)port_id;
(void)flag;
/* Not supported */
}
static int hdmicec_close(struct hdmi_cec_device *dev)
{
struct hdmicec_context *ctx = (struct hdmicec_context *)dev;
uint64_t tmp = 1;
ALOGD("%s\n", __func__);
if (ctx->exit_fd > 0) {
write(ctx->exit_fd, &tmp, sizeof(tmp));
pthread_join(ctx->thread, NULL);
}
if (ctx->cec_fd > 0)
close(ctx->cec_fd);
if (ctx->exit_fd > 0)
close(ctx->exit_fd);
free(ctx);
ctx->cec_enabled = false;
ctx->cec_control_enabled = false;
return 0;
}
static int cec_init(struct hdmicec_context *ctx)
{
struct cec_log_addrs laddrs = {};
struct cec_caps caps = {};
uint32_t mode;
int ret;
// Ensure the CEC device supports required capabilities
ret = ioctl(ctx->cec_fd, CEC_ADAP_G_CAPS, &caps);
if (ret)
return ret;
if (!(caps.capabilities & (CEC_CAP_LOG_ADDRS |
CEC_CAP_TRANSMIT |
CEC_CAP_PASSTHROUGH))) {
ALOGE("%s: wrong cec adapter capabilities %x\n",
__func__, caps.capabilities);
return -1;
}
// This is an exclusive follower, in addition put the CEC device into passthrough mode
mode = CEC_MODE_INITIATOR | CEC_MODE_EXCL_FOLLOWER_PASSTHRU;
ret = ioctl(ctx->cec_fd, CEC_S_MODE, &mode);
if (ret)
return ret;
ctx->type = property_get_int32("ro.hdmi.device_type", CEC_DEVICE_PLAYBACK);
ctx->vendor_id = property_get_int32("ro.hdmi.vendor_id",
0x000c03 /* HDMI LLC vendor ID */);
ctx->version = property_get_bool("ro.hdmi.cec_version",
CEC_OP_CEC_VERSION_1_4);
ctx->port_info.type = ctx->type == CEC_DEVICE_TV ? HDMI_INPUT : HDMI_OUTPUT;
ctx->port_info.port_id = 1;
ctx->port_info.cec_supported = 1;
ctx->port_info.arc_supported = 0;
ALOGD("%s: type=%d\n", __func__, ctx->type);
ALOGD("%s: vendor_id=%04x\n", __func__, ctx->vendor_id);
ALOGD("%s: version=%d\n", __func__, ctx->version);
memset(&laddrs, 0, sizeof(laddrs));
ret = ioctl(ctx->cec_fd, CEC_ADAP_S_LOG_ADDRS, &laddrs);
if (ret)
return ret;
pthread_mutex_init(&ctx->options_lock, NULL);
ALOGD("%s: initialized CEC controller\n", __func__);
return ret;
}
static int open_hdmi_cec(const struct hw_module_t *module, const char *id,
struct hw_device_t **device)
{
char path[32];
char prop[PROPERTY_VALUE_MAX];
hdmicec_context_t *ctx;
int ret;
ALOGD("%s: id=%s\n", __func__, id);
ctx = malloc(sizeof(struct hdmicec_context));
if (!ctx)
return -ENOMEM;
memset(ctx, 0, sizeof(*ctx));
property_get("ro.hdmi.cec_device", prop, "cec0");
snprintf(path, sizeof(path), "/dev/%s", prop);
ctx->cec_fd = open(path, O_RDWR);
if (ctx->cec_fd < 0) {
ALOGE("faild to open %s, ret=%s\n", path, strerror(errno));
goto fail;
}
ctx->exit_fd = eventfd(0, EFD_NONBLOCK);
if (ctx->exit_fd < 0) {
ALOGE("faild to open eventfd, ret = %d\n", errno);
goto fail;
}
ctx->device.common.tag = HARDWARE_DEVICE_TAG;
ctx->device.common.version = HDMI_CEC_DEVICE_API_VERSION_1_0;
ctx->device.common.module = (struct hw_module_t *)module;
ctx->device.common.close = (int (*)(struct hw_device_t* device))hdmicec_close;
ctx->device.add_logical_address = hdmicec_add_logical_address;
ctx->device.clear_logical_address = hdmicec_clear_logical_address;
ctx->device.get_physical_address = hdmicec_get_physical_address;
ctx->device.send_message = hdmicec_send_message;
ctx->device.register_event_callback = hdmicec_register_event_callback;
ctx->device.get_version = hdmicec_get_version;
ctx->device.get_vendor_id = hdmicec_get_vendor_id;
ctx->device.get_port_info = hdmicec_get_port_info;
ctx->device.set_option = hdmicec_set_option;
ctx->device.set_audio_return_channel = hdmicec_set_arc;
ctx->device.is_connected = hdmicec_is_connected;
/* init status */
ret = cec_init(ctx);
if (ret)
goto fail;
*device = &ctx->device.common;
/* thread loop for receiving cec msg */
if (pthread_create(&ctx->thread, NULL, event_thread, ctx)) {
ALOGE("Can't create event thread: %s\n", strerror(errno));
goto fail;
}
ctx->cec_enabled = true;
ctx->cec_control_enabled = true;
return 0;
fail:
hdmicec_close((struct hdmi_cec_device *)ctx);
return -errno;
}
/* module method */
static struct hw_module_methods_t hdmi_cec_module_methods = {
.open = open_hdmi_cec,
};
/* hdmi_cec module */
struct hw_module_t HAL_MODULE_INFO_SYM = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = HDMI_CEC_HARDWARE_MODULE_ID,
.name = "Raspberry Pi HDMI CEC HAL",
.author = "The Android Open Source Project",
.methods = &hdmi_cec_module_methods,
};

View File

@@ -25,6 +25,7 @@ PRODUCT_PACKAGES += \
android.hardware.audio@7.0-impl \
android.hardware.audio.effect@7.0-impl \
audio.primary.rpi \
audio.primary.rpi_hdmi \
audio.r_submix.default \
audio.usb.default
@@ -50,9 +51,9 @@ PRODUCT_PACKAGES += \
alsa_loop
PRODUCT_COPY_FILES += \
$(DEVICE_PATH)/audio/vc4-hdmi.conf:$(TARGET_COPY_OUT_VENDOR)/etc/alsa/cards/vc4-hdmi.conf \
external/alsa-lib/src/conf/alsa.conf:$(TARGET_COPY_OUT_VENDOR)/etc/alsa/alsa.conf \
external/alsa-lib/src/conf/cards/aliases.conf:$(TARGET_COPY_OUT_VENDOR)/etc/alsa/cards/aliases.conf \
external/alsa-lib/src/conf/cards/vc4-hdmi.conf:$(TARGET_COPY_OUT_VENDOR)/etc/alsa/cards/vc4-hdmi.conf \
external/alsa-lib/src/conf/ctl/default.conf:$(TARGET_COPY_OUT_VENDOR)/etc/alsa/ctl/default.conf \
external/alsa-lib/src/conf/pcm/center_lfe.conf:$(TARGET_COPY_OUT_VENDOR)/etc/alsa/pcm/center_lfe.conf \
external/alsa-lib/src/conf/pcm/default.conf:$(TARGET_COPY_OUT_VENDOR)/etc/alsa/pcm/default.conf \
@@ -122,6 +123,15 @@ PRODUCT_COPY_FILES += \
PRODUCT_COPY_FILES += \
$(DEVICE_PATH)/camera/media_profiles_V1_0.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_profiles_V1_0.xml
# CEC
PRODUCT_PACKAGES += \
android.hardware.tv.cec@1.0-impl \
android.hardware.tv.cec@1.0-service \
hdmi_cec.rpi
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.hdmi.cec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.hdmi.cec.xml
# Debugfs
PRODUCT_SET_DEBUGFS_RESTRICTIONS := false
@@ -135,6 +145,10 @@ PRODUCT_PACKAGES += \
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.ethernet.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.ethernet.xml
# FFmpeg
PRODUCT_PACKAGES += \
android.hardware.media.c2@1.2-service-ffmpeg
# Gatekeeper
PRODUCT_PACKAGES += \
android.hardware.gatekeeper@1.0-service.software
@@ -174,6 +188,10 @@ PRODUCT_PACKAGES += \
PRODUCT_COPY_FILES += \
$(DEVICE_PATH)-kernel/Image:$(PRODUCT_OUT)/kernel
# Keylayout
PRODUCT_COPY_FILES += \
$(DEVICE_PATH)/keylayout/Generic.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/Generic.kl
# Keymaster
PRODUCT_PACKAGES += \
android.hardware.keymaster@3.0-impl \
@@ -186,7 +204,6 @@ PRODUCT_PACKAGES += \
# Media
PRODUCT_COPY_FILES += \
$(DEVICE_PATH)/media/media_codecs.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs.xml \
$(DEVICE_PATH)/media/media_codecs_v4l2_c2_video.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_v4l2_c2_video.xml \
frameworks/av/media/libstagefright/data/media_codecs_google_c2_audio.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_c2_audio.xml \
frameworks/av/media/libstagefright/data/media_codecs_google_c2_tv.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_c2_tv.xml \
frameworks/av/media/libstagefright/data/media_codecs_google_c2_video.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_c2_video.xml
@@ -248,6 +265,9 @@ PRODUCT_PACKAGES += \
android.hardware.media.c2@1.0-service-v4l2 \
libc2plugin_store
PRODUCT_COPY_FILES += \
$(DEVICE_PATH)/media/media_codecs_v4l2_c2_video.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_v4l2_c2_video.xml
# Wifi
PRODUCT_PACKAGES += \
android.hardware.wifi@1.0-service \

461
keylayout/Generic.kl Normal file
View File

@@ -0,0 +1,461 @@
# Copyright (C) 2010 The Android Open Source Project
#
# 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.
#
# Generic key layout file for full alphabetic US English PC style external keyboards.
#
# This file is intentionally very generic and is intended to support a broad range of keyboards.
# Do not edit the generic key layout to support a specific keyboard; instead, create
# a new key layout file with the required keyboard configuration.
#
key 1 ESCAPE
key 2 1
key 3 2
key 4 3
key 5 4
key 6 5
key 7 6
key 8 7
key 9 8
key 10 9
key 11 0
key 12 MINUS
key 13 EQUALS
key 14 DEL
key 15 TAB
key 16 Q
key 17 W
key 18 E
key 19 R
key 20 T
key 21 Y
key 22 U
key 23 I
key 24 O
key 25 P
key 26 LEFT_BRACKET
key 27 RIGHT_BRACKET
key 28 ENTER
key 29 CTRL_LEFT
key 30 A
key 31 S
key 32 D
key 33 F
key 34 G
key 35 H
key 36 J
key 37 K
key 38 L
key 39 SEMICOLON
key 40 APOSTROPHE
key 41 GRAVE
key 42 SHIFT_LEFT
key 43 BACKSLASH
key 44 Z
key 45 X
key 46 C
key 47 V
key 48 B
key 49 N
key 50 M
key 51 COMMA
key 52 PERIOD
key 53 SLASH
key 54 SHIFT_RIGHT
key 55 NUMPAD_MULTIPLY
key 56 ALT_LEFT
key 57 SPACE
key 58 CAPS_LOCK
key 59 F1
key 60 F2
key 61 F3
key 62 F4
key 63 F5
key 64 F6
key 65 F7
key 66 F8
key 67 F9
key 68 F10
key 69 NUM_LOCK
key 70 SCROLL_LOCK
key 71 NUMPAD_7
key 72 NUMPAD_8
key 73 NUMPAD_9
key 74 NUMPAD_SUBTRACT
key 75 NUMPAD_4
key 76 NUMPAD_5
key 77 NUMPAD_6
key 78 NUMPAD_ADD
key 79 NUMPAD_1
key 80 NUMPAD_2
key 81 NUMPAD_3
key 82 NUMPAD_0
key 83 NUMPAD_DOT
# key 84 (undefined)
key 85 ZENKAKU_HANKAKU
key 86 BACKSLASH
key 87 F11
key 88 F12
key 89 RO
# key 90 "KEY_KATAKANA"
# key 91 "KEY_HIRAGANA"
key 92 HENKAN
key 93 KATAKANA_HIRAGANA
key 94 MUHENKAN
key 95 NUMPAD_COMMA
key 96 NUMPAD_ENTER
key 97 CTRL_RIGHT
key 98 NUMPAD_DIVIDE
key 99 SYSRQ
key 100 ALT_RIGHT
# key 101 "KEY_LINEFEED"
key 102 MOVE_HOME
key 103 DPAD_UP
key 104 PAGE_UP
key 105 DPAD_LEFT
key 106 DPAD_RIGHT
key 107 MOVE_END
key 108 DPAD_DOWN
key 109 PAGE_DOWN
key 110 INSERT
key 111 FORWARD_DEL
# key 112 "KEY_MACRO"
key 113 VOLUME_MUTE
key 114 VOLUME_DOWN
key 115 VOLUME_UP
key 116 POWER
key 117 NUMPAD_EQUALS
# key 118 "KEY_KPPLUSMINUS"
key 119 BREAK
# key 120 (undefined)
key 121 NUMPAD_COMMA
key 122 KANA
key 123 EISU
key 124 YEN
key 125 META_LEFT
key 126 META_RIGHT
key 127 MENU
key 128 MEDIA_STOP
# key 129 "KEY_AGAIN"
# key 130 "KEY_PROPS"
# key 131 "KEY_UNDO"
# key 132 "KEY_FRONT"
key 133 COPY
# key 134 "KEY_OPEN"
key 135 PASTE
# key 136 "KEY_FIND"
key 137 CUT
# key 138 "KEY_HELP"
key 139 MENU
key 140 CALCULATOR
# key 141 "KEY_SETUP"
key 142 SLEEP
key 143 WAKEUP
# key 144 "KEY_FILE"
# key 145 "KEY_SENDFILE"
# key 146 "KEY_DELETEFILE"
# key 147 "KEY_XFER"
# key 148 "KEY_PROG1"
# key 149 "KEY_PROG2"
key 150 EXPLORER
# key 151 "KEY_MSDOS"
key 152 POWER
# key 153 "KEY_DIRECTION"
# key 154 "KEY_CYCLEWINDOWS"
key 155 ENVELOPE
key 156 BOOKMARK
# key 157 "KEY_COMPUTER"
key 158 BACK
key 159 FORWARD
key 160 MEDIA_CLOSE
key 161 MEDIA_EJECT
key 162 MEDIA_EJECT
key 163 MEDIA_NEXT
key 164 MEDIA_PLAY_PAUSE
key 165 MEDIA_PREVIOUS
key 166 MEDIA_STOP
key 167 MEDIA_RECORD
key 168 MEDIA_REWIND
key 169 CALL
# key 170 "KEY_ISO"
key 171 MUSIC
key 172 HOME
key 173 REFRESH
# key 174 "KEY_EXIT"
# key 175 "KEY_MOVE"
# key 176 "KEY_EDIT"
key 177 PAGE_UP
key 178 PAGE_DOWN
key 179 NUMPAD_LEFT_PAREN
key 180 NUMPAD_RIGHT_PAREN
# key 181 "KEY_NEW"
# key 182 "KEY_REDO"
# key 183 F13
# key 184 F14
# key 185 F15
# key 186 F16
# key 187 F17
# key 188 F18
# key 189 F19
# key 190 F20
# key 191 F21
# key 192 F22
# key 193 F23
# key 194 F24
# key 195 (undefined)
# key 196 (undefined)
# key 197 (undefined)
# key 198 (undefined)
# key 199 (undefined)
key 200 MEDIA_PLAY
key 201 MEDIA_PAUSE
# key 202 "KEY_PROG3"
# key 203 "KEY_PROG4"
key 204 NOTIFICATION
# key 205 "KEY_SUSPEND"
# key 206 "KEY_CLOSE"
key 207 MEDIA_PLAY
key 208 MEDIA_FAST_FORWARD
# key 209 "KEY_BASSBOOST"
# key 210 "KEY_PRINT"
# key 211 "KEY_HP"
key 212 CAMERA
key 213 MUSIC
# key 214 "KEY_QUESTION"
key 215 ENVELOPE
# key 216 "KEY_CHAT"
key 217 SEARCH
# key 218 "KEY_CONNECT"
# key 219 "KEY_FINANCE"
# key 220 "KEY_SPORT"
# key 221 "KEY_SHOP"
# key 222 "KEY_ALTERASE"
# key 223 "KEY_CANCEL"
key 224 BRIGHTNESS_DOWN
key 225 BRIGHTNESS_UP
key 226 HEADSETHOOK
key 256 BUTTON_1
key 257 BUTTON_2
key 258 BUTTON_3
key 259 BUTTON_4
key 260 BUTTON_5
key 261 BUTTON_6
key 262 BUTTON_7
key 263 BUTTON_8
key 264 BUTTON_9
key 265 BUTTON_10
key 266 BUTTON_11
key 267 BUTTON_12
key 268 BUTTON_13
key 269 BUTTON_14
key 270 BUTTON_15
key 271 BUTTON_16
key 288 BUTTON_1
key 289 BUTTON_2
key 290 BUTTON_3
key 291 BUTTON_4
key 292 BUTTON_5
key 293 BUTTON_6
key 294 BUTTON_7
key 295 BUTTON_8
key 296 BUTTON_9
key 297 BUTTON_10
key 298 BUTTON_11
key 299 BUTTON_12
key 300 BUTTON_13
key 301 BUTTON_14
key 302 BUTTON_15
key 303 BUTTON_16
key 304 BUTTON_A
key 305 BUTTON_B
key 306 BUTTON_C
key 307 BUTTON_X
key 308 BUTTON_Y
key 309 BUTTON_Z
key 310 BUTTON_L1
key 311 BUTTON_R1
key 312 BUTTON_L2
key 313 BUTTON_R2
key 314 BUTTON_SELECT
key 315 BUTTON_START
key 316 BUTTON_MODE
key 317 BUTTON_THUMBL
key 318 BUTTON_THUMBR
# key 352 "KEY_OK"
key 353 DPAD_CENTER
# key 354 "KEY_GOTO"
# key 355 "KEY_CLEAR"
# key 356 "KEY_POWER2"
# key 357 "KEY_OPTION"
# key 358 "KEY_INFO"
# key 359 "KEY_TIME"
# key 360 "KEY_VENDOR"
# key 361 "KEY_ARCHIVE"
key 362 GUIDE
# key 363 "KEY_CHANNEL"
# key 364 "KEY_FAVORITES"
# key 365 "KEY_EPG"
key 366 DVR
# key 367 "KEY_MHP"
# key 368 "KEY_LANGUAGE"
# key 369 "KEY_TITLE"
key 370 CAPTIONS
# key 371 "KEY_ANGLE"
# key 372 "KEY_ZOOM"
# key 373 "KEY_MODE"
# key 374 "KEY_KEYBOARD"
# key 375 "KEY_SCREEN"
# key 376 "KEY_PC"
key 377 TV
# key 378 "KEY_TV2"
# key 379 "KEY_VCR"
# key 380 "KEY_VCR2"
# key 381 "KEY_SAT"
# key 382 "KEY_SAT2"
# key 383 "KEY_CD"
# key 384 "KEY_TAPE"
# key 385 "KEY_RADIO"
# key 386 "KEY_TUNER"
# key 387 "KEY_PLAYER"
# key 388 "KEY_TEXT"
# key 389 "KEY_DVD"
# key 390 "KEY_AUX"
# key 391 "KEY_MP3"
# key 392 "KEY_AUDIO"
# key 393 "KEY_VIDEO"
# key 394 "KEY_DIRECTORY"
# key 395 "KEY_LIST"
# key 396 "KEY_MEMO"
key 397 CALENDAR
key 398 PROG_RED
key 399 PROG_GREEN
key 400 PROG_YELLOW
key 401 PROG_BLUE
key 402 CHANNEL_UP
key 403 CHANNEL_DOWN
# key 404 "KEY_FIRST"
key 405 LAST_CHANNEL
# key 406 "KEY_AB"
# key 407 "KEY_NEXT"
# key 408 "KEY_RESTART"
# key 409 "KEY_SLOW"
# key 410 "KEY_SHUFFLE"
# key 411 "KEY_BREAK"
# key 412 "KEY_PREVIOUS"
# key 413 "KEY_DIGITS"
# key 414 "KEY_TEEN"
# key 415 "KEY_TWEN"
key 429 CONTACTS
# key 448 "KEY_DEL_EOL"
# key 449 "KEY_DEL_EOS"
# key 450 "KEY_INS_LINE"
# key 451 "KEY_DEL_LINE"
key 464 FUNCTION
key 465 ESCAPE FUNCTION
key 466 F1 FUNCTION
key 467 F2 FUNCTION
key 468 F3 FUNCTION
key 469 F4 FUNCTION
key 470 F5 FUNCTION
key 471 F6 FUNCTION
key 472 F7 FUNCTION
key 473 F8 FUNCTION
key 474 F9 FUNCTION
key 475 F10 FUNCTION
key 476 F11 FUNCTION
key 477 F12 FUNCTION
key 478 1 FUNCTION
key 479 2 FUNCTION
key 480 D FUNCTION
key 481 E FUNCTION
key 482 F FUNCTION
key 483 S FUNCTION
key 484 B FUNCTION
# key 497 KEY_BRL_DOT1
# key 498 KEY_BRL_DOT2
# key 499 KEY_BRL_DOT3
# key 500 KEY_BRL_DOT4
# key 501 KEY_BRL_DOT5
# key 502 KEY_BRL_DOT6
# key 503 KEY_BRL_DOT7
# key 504 KEY_BRL_DOT8
key 522 STAR
key 523 POUND
key 580 APP_SWITCH
key 582 VOICE_ASSIST
# Linux KEY_ASSISTANT
key 583 ASSIST
# CEC
key 352 ENTER
key 618 HOME
key 141 POWER
key 174 BACK
# Keys defined by HID usages
key usage 0x0c0067 WINDOW
key usage 0x0c006F BRIGHTNESS_UP
key usage 0x0c0070 BRIGHTNESS_DOWN
key usage 0x0c0173 MEDIA_AUDIO_TRACK
# Joystick and game controller axes.
# Axes that are not mapped will be assigned generic axis numbers by the input subsystem.
axis 0x00 X
axis 0x01 Y
axis 0x02 Z
axis 0x03 RX
axis 0x04 RY
axis 0x05 RZ
axis 0x06 THROTTLE
axis 0x07 RUDDER
axis 0x08 WHEEL
axis 0x09 GAS
axis 0x0a BRAKE
axis 0x10 HAT_X
axis 0x11 HAT_Y
# LEDs
led 0x00 NUM_LOCK
led 0x01 CAPS_LOCK
led 0x02 SCROLL_LOCK
led 0x03 COMPOSE
led 0x04 KANA
led 0x05 SLEEP
led 0x06 SUSPEND
led 0x07 MUTE
led 0x08 MISC
led 0x09 MAIL
led 0x0a CHARGING
# SENSORs
sensor 0x00 ACCELEROMETER X
sensor 0x01 ACCELEROMETER Y
sensor 0x02 ACCELEROMETER Z
sensor 0x03 GYROSCOPE X
sensor 0x04 GYROSCOPE Y
sensor 0x05 GYROSCOPE Z

View File

@@ -76,15 +76,6 @@
<instance>default</instance>
</interface>
</hal>
<hal format="hidl">
<name>android.hardware.media.c2</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>IComponentStore</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl">
<name>android.hardware.media.omx</name>
<transport>hwbinder</transport>
@@ -98,4 +89,13 @@
<instance>default</instance>
</interface>
</hal>
<hal format="hidl">
<name>android.hardware.tv.cec</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>IHdmiCec</name>
<instance>default</instance>
</interface>
</hal>
</manifest>

View File

@@ -17,7 +17,8 @@
-->
<MediaCodecs>
<!-- <Include href="media_codecs_v4l2_c2_video.xml" /> -->
<Include href="media_codecs_ffmpeg_c2.xml" />
<Include href="media_codecs_v4l2_c2_video.xml" />
<Include href="media_codecs_google_c2_audio.xml" />
<Include href="media_codecs_google_c2_tv.xml" />
<Include href="media_codecs_google_c2_video.xml" />

View File

@@ -17,7 +17,6 @@
-->
<Included>
<!--
<Encoders>
<MediaCodec name="c2.v4l2.avc.encoder" type="video/avc">
<Limit name="size" min="32x32" max="4096x4096" />
@@ -29,10 +28,9 @@
<Limit name="performance-point-1280x720" range="30-30" />
</MediaCodec>
</Encoders>
-->
<Decoders>
<MediaCodec name="c2.v4l2.avc.decoder" type="video/avc" >
<MediaCodec name="c2.v4l2.avc.decoder" type="video/avc">
<Limit name="size" min="16x16" max="4096x4096" />
<Limit name="alignment" value="2x2" />
<Limit name="block-size" value="16x16" />
@@ -42,65 +40,5 @@
<Limit name="performance-point-3840x2160" range="30-30" />
<Feature name="adaptive-playback" />
</MediaCodec>
<!--
<MediaCodec name="c2.v4l2.vp8.decoder" type="video/x-vnd.on2.vp8" >
<Limit name="size" min="16x16" max="4096x4096" />
<Limit name="alignment" value="2x2" />
<Limit name="block-size" value="16x16" />
<Limit name="blocks-per-second" min="1" max="1984500" />
<Limit name="bitrate" range="1-62500000" />
<Limit name="concurrent-instances" max="8" />
<Limit name="performance-point-3840x2160" range="30-30" />
<Feature name="adaptive-playback" />
</MediaCodec>
<MediaCodec name="c2.v4l2.vp9.decoder" type="video/x-vnd.on2.vp9" >
<Limit name="size" min="16x16" max="4096x4096" />
<Limit name="alignment" value="2x2" />
<Limit name="block-size" value="16x16" />
<Limit name="blocks-per-second" min="1" max="2073600" />
<Limit name="bitrate" range="1-62500000" />
<Limit name="concurrent-instances" max="8" />
<Limit name="performance-point-3840x2160" range="30-30" />
<Feature name="adaptive-playback" />
</MediaCodec>
<MediaCodec name="c2.v4l2.avc.decoder.secure" type="video/avc" >
<Limit name="size" min="16x16" max="4096x4096" />
<Limit name="alignment" value="2x2" />
<Limit name="block-size" value="16x16" />
<Limit name="blocks-per-second" min="1" max="1879200" />
<Limit name="bitrate" range="1-62500000" />
<Limit name="concurrent-instances" max="8" />
<Limit name="performance-point-3840x2160" range="30-30" />
<Feature name="adaptive-playback" />
<Feature name="secure-playback" required="true" />
</MediaCodec>
<MediaCodec name="c2.v4l2.vp8.decoder.secure" type="video/x-vnd.on2.vp8" >
<Limit name="size" min="16x16" max="4096x4096" />
<Limit name="alignment" value="2x2" />
<Limit name="block-size" value="16x16" />
<Limit name="blocks-per-second" min="1" max="1984500" />
<Limit name="bitrate" range="1-62500000" />
<Limit name="concurrent-instances" max="8" />
<Limit name="performance-point-3840x2160" range="30-30" />
<Feature name="adaptive-playback" />
<Feature name="secure-playback" required="true" />
</MediaCodec>
<MediaCodec name="c2.v4l2.vp9.decoder.secure" type="video/x-vnd.on2.vp9" >
<Limit name="size" min="16x16" max="4096x4096" />
<Limit name="alignment" value="2x2" />
<Limit name="block-size" value="16x16" />
<Limit name="blocks-per-second" min="1" max="2073600" />
<Limit name="bitrate" range="1-62500000" />
<Limit name="concurrent-instances" max="8" />
<Limit name="performance-point-3840x2160" range="30-30" />
<Feature name="adaptive-playback" />
<Feature name="secure-playback" required="true" />
</MediaCodec>
-->
</Decoders>
</Included>

View File

@@ -46,6 +46,12 @@
cell broadcasting sms, and MMS. -->
<bool name="config_sms_capable">false</bool>
<!-- Flag indicating whether the current device allows data.
If true, this means that the device supports data connectivity through
the telephony network.
This can be overridden to false for devices that support voice and/or sms . -->
<bool name="config_mobile_data_capable">false</bool>
<!-- Whether a software navigation bar should be shown. NOTE: in the future this may be
autodetected from the Configuration. -->
<bool name="config_showNavigationBar">true</bool>

View File

@@ -33,6 +33,9 @@
<!-- Keep screen on at all times by default -->
<bool name="def_stay_on_while_plugged_in">true</bool>
<!-- Disable HDMI-CEC power off -->
<bool name="def_hdmiControlAutoDeviceOff">false</bool>
<!-- No setup wizard -->
<bool name="def_device_provisioned">true</bool>
<bool name="def_user_setup_complete">true</bool>

View File

@@ -19,20 +19,6 @@ on property:sys.boot_completed=1
# Reinit lmkd to reconfigure lmkd properties
setprop lmkd.reinit 1
on property:sys.boot_completed=1 && property:persist.audio.hdmi.device=*
stop alsa_loop
start alsa_loop
on property:persist.audio.hdmi.device=
stop alsa_loop
service alsa_loop /vendor/bin/alsa_loop --cdevice=hw:${persist.audio.pcm.card},1 --pdevice=default:CARD=${persist.audio.hdmi.device}
user root
group system
priority 10
ioprio rt 4
disabled
service suspend_blocker_rpi /vendor/bin/suspend_blocker_rpi
class early_hal # Start together with system_suspend HAL
group system

View File

@@ -8,6 +8,10 @@
/dev/v4l-subdev* 0660 system camera
/dev/video* 0660 system camera
# CEC
/dev/cec0 0660 system graphics
/dev/cec1 0660 system graphics
# DMA
/dev/dma_heap/linux,cma 0666 system graphics

View File

@@ -1,7 +0,0 @@
type alsa_loop, domain;
type alsa_loop_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(alsa_loop)
allow alsa_loop audio_device:dir r_dir_perms;
allow alsa_loop audio_device:chr_file rw_file_perms;

View File

@@ -1 +1,2 @@
type cec_device, dev_type;
type vcio_device, dev_type, mlstrustedobject;

View File

@@ -1,17 +1,21 @@
# Audio
/vendor/bin/alsa_loop u:object_r:alsa_loop_exec:s0
# Bluetooth
/dev/ttyAMA0 u:object_r:hci_attach_dev:s0
/dev/vcio u:object_r:vcio_device:s0
/sys/class/rfkill/rfkill[0-9]/state u:object_r:sysfs_bluetooth_writable:s0
# CEC
/dev/cec0 u:object_r:cec_device:s0
/dev/cec1 u:object_r:cec_device:s0
# DRM
/vendor/bin/hw/android\.hardware\.drm@1\.4-service\.clearkey u:object_r:hal_drm_clearkey_exec:s0
/vendor/bin/hw/android\.hardware\.drm@1\.4-service\.widevine u:object_r:hal_drm_widevine_exec:s0
# FFmpeg
/vendor/bin/hw/android\.hardware\.media\.c2@1\.2-service-ffmpeg(.*)? u:object_r:mediacodec_exec:s0
# Gatekeeper
/vendor/bin/hw/android\.hardware\.gatekeeper@1\.0-service.software u:object_r:hal_gatekeeper_default_exec:s0
/vendor/bin/hw/android\.hardware\.gatekeeper@1\.0-service\.software u:object_r:hal_gatekeeper_default_exec:s0
# Graphics
/dev/dri u:object_r:gpu_device:s0
@@ -29,12 +33,12 @@
/vendor/lib(64)?/libminigbm_gralloc_gbm_mesa\.so u:object_r:same_process_hal_file:s0
# Health
/vendor/bin/hw/android\.hardware\.health@2\.0-service.rpi u:object_r:hal_health_default_exec:s0
/vendor/bin/hw/android\.hardware\.health@2\.0-service\.rpi u:object_r:hal_health_default_exec:s0
# Lights
/sys/class/backlight/rpi_backlight/brightness u:object_r:sysfs_leds:s0
/sys/devices/platform/rpi_backlight/backlight/rpi_backlight/brightness u:object_r:sysfs_leds:s0
/vendor/bin/hw/android\.hardware\.light@2\.0-service.rpi u:object_r:hal_light_default_exec:s0
/vendor/bin/hw/android\.hardware\.light@2\.0-service\.rpi u:object_r:hal_light_default_exec:s0
# Partitions
/dev/block/mmcblk0p1 u:object_r:boot_block_device:s0

View File

@@ -0,0 +1 @@
allow hal_tv_cec_default cec_device:chr_file rw_file_perms;

View File

@@ -1,9 +1,11 @@
# Audio
persist.audio.hdmi.device=vc4hdmi0
persist.audio.pcm.card=0
persist.audio.pcm.device=0
ro.config.media_vol_default=20
ro.config.media_vol_steps=25
ro.hardware.audio.primary=rpi
# Bluetooth
ro.rfkilldisabled=1
@@ -12,9 +14,19 @@ ro.rfkilldisabled=1
media.settings.xml=/vendor/etc/media_profiles_V1_0.xml
ro.hardware.camera=libcamera
# CEC
ro.hdmi.cec_device=cec0
ro.hdmi.device_type=4
# Display
debug.drm.mode.force=1920x1080
# FFmpeg
persist.ffmpeg_codec2.rank.audio=16
persist.ffmpeg_codec2.rank.video=256
persist.ffmpeg_codec2.v4l2.h264=false
persist.ffmpeg_codec2.v4l2.h265=true
# Graphics
ro.hardware.hwcomposer=drm
ro.hardware.vulkan=broadcom
@@ -34,6 +46,8 @@ ro.lmk.use_minfree_levels=true
# V4L2
debug.stagefright.c2-poolmask=0xf50000
persist.v4l2_codec2.rank.decoder=128
persist.v4l2_codec2.rank.encoder=128
ro.vendor.v4l2_codec2.decode_concurrent_instances=8
ro.vendor.v4l2_codec2.encode_concurrent_instances=8