8 Commits
vic ... udc

Author SHA1 Message Date
Tim Zimmermann
877c1a0564 aidl: Update light to V2
Change-Id: I126448662234741a158f41ebdc1577e9c3a44816
2024-08-04 10:57:32 +02:00
Tim Zimmermann
201fd3cc32 aidl: Remove thermal HAL
* Pixel thermal HAL can now be used directly

Change-Id: Ied8350355b819453e84026585f47e097d3f502f5
2024-08-04 10:51:55 +02:00
Tim Zimmermann
56626e0201 aidl: sensors: Use multihal sources directly from hardware/interfaces
* Possible after 5a856698db

Change-Id: I7b4beaf08327431740ab24dd651bc133bdf65cf1
2024-08-04 10:24:53 +02:00
matthuang
edb30cd0c5 Add group 'uhid' to AIDL sensors multi-HAL
Allow sensor hal to send SW_LID event through HID transport
drivers when hall_effect event is detected.

Bug: 262056923
Test: Build pass.
Change-Id: I9b583df6090a5e415abac7bef4bc3b7d28c31b8f
2024-08-03 21:55:10 +02:00
Roy Luo
a65af94562 Usb compliance warning extension
Add new warnings to enum ComplianceWarning

Test: atest VtsAidlUsbTargetTest
Bug: 296119135
Bug: 300340959
Change-Id: I5dcfe50285589d35dd2a2ab87020de8e2b92c181
2024-08-03 21:53:25 +02:00
RD Babiera
dd3baf47d3 Usb DisplayPort alt mode aidl interfaces
Adds enums for DisplayPortAltModeStatus and DisplayPortAltModePinAssignment.
Adds AltModeData and DisplayPortAltModeData.
Updates PortStatus to reflect these new enums and parcelables.

Test: atest VtsAidlUsbTargetTest
Bug: 253534975
Change-Id: I0fc62601dfc162b909e796586110686beed137ea
2024-08-03 21:51:21 +02:00
RD Babiera
4d5a25b7c1 Usb non-compliant port partner aidl extension
Adds aidl api definitions for notifying if the plugged Type-C
port partner (power source/accessory/cable) is non-compliant
with type-c power delivery specification. PortStatus is extended to have
a boolean that states whether or not this feature is supported as well
as an array for a new enum ComplianceWarning.

Test: atest VtsAidlUsbTargetTest
new test nonCompliantChargerStatus expects expects array to be empty
when the feature is not supported. new test nonCompliantChargerValues
expects any values in array to be in range of ComplianceWarning enums
if feature is supported.

Bug: 236322506
Change-Id: Ie3c2365e7c713327b44421c4d132b321d0e03d5f
2024-08-03 21:48:06 +02:00
Tim Zimmermann
bf39dfb28b aidl: Add missing vintf version entries
* This is required for devices using a target-level that actually
  has these HALs in their compatibility matrix

Change-Id: I29cba455ab92e7708ece405bb29ea1c46e46cf41
2024-08-03 21:44:08 +02:00
560 changed files with 155501 additions and 2160 deletions

View File

@@ -8,7 +8,7 @@ android_app {
name: "AdvancedDisplay",
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
certificate: "platform",
platform_apis: true,

0
AdvancedDisplay/res/layout/framelayout.xml Normal file → Executable file
View File

View File

@@ -21,8 +21,8 @@
<string name="screen_colors_title">Rənglər</string>
<string name="mdnie_scenario_title_head">Ekran rejimi</string>
<string name="mdnie_scenario_summary_head">mDNle ssenarisini ayarla</string>
<string name="mdnie_accessibility_title_head">Erişiləbilənlik rejimi</string>
<string name="mdnie_accessibility_summary_head">mDNIe erişiləbilənlik rejimini ayarla</string>
<string name="mdnie_accessibility_title_head">Əlçatımlılıq rejimi</string>
<string name="mdnie_accessibility_summary_head">mDNIe əlçatımlılıq rejimini ayarla</string>
<string name="mdnie_scenario_ui">LineageOS (ilkin)</string>
<string name="mdnie_scenario_video">Video</string>
<string name="mdnie_scenario_video_warm">Video - isti</string>

View File

@@ -16,6 +16,7 @@
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Налады экрана</string>
<string name="category_screen_title">Экран</string>
<string name="screen_colors_title">Колеры</string>
<string name="mdnie_scenario_video_warm">Відэа (цёплыя тоны)</string>
@@ -25,7 +26,6 @@
<string name="mdnie_scenario_vt">Відэавыклік</string>
<string name="mdnie_scenario_browser">Браўзер</string>
<string name="mdnie_scenario_tdmb">Лічбавае тэлебачанне</string>
<string name="mdnie_accessibility_normal">Звычайны</string>
<string name="mdnie_accessibility_inverse">Інвертаваны</string>
<string name="mdnie_accessibility_color_blind">Дальтанізм</string>
<string name="mdnie_accessibility_grayscale">Шэры</string>

View File

@@ -33,12 +33,5 @@
<string name="mdnie_scenario_vt">Videollamada</string>
<string name="mdnie_scenario_browser">Navegador</string>
<string name="mdnie_scenario_ebook">Libro electrónico</string>
<string name="mdnie_scenario_email">Correo electrónico</string>
<string name="mdnie_scenario_tdmb">Televisión digital</string>
<string name="mdnie_accessibility_normal">Normal</string>
<string name="mdnie_accessibility_inverse">Invertido</string>
<string name="mdnie_accessibility_color_blind">Daltonismo</string>
<string name="mdnie_accessibility_screen_curtain">Cortina de pantalla</string>
<string name="mdnie_accessibility_grayscale">Gris</string>
<string name="mdnie_accessibility_gray_negative">Gris invertido</string>
</resources>

View File

@@ -21,24 +21,4 @@
<string name="screen_colors_title">رنگ‌ها</string>
<string name="mdnie_scenario_title_head">خط مشی</string>
<string name="mdnie_scenario_summary_head">تنظیم خط مشی mDNIe</string>
<string name="mdnie_accessibility_title_head">حالت دسترسی</string>
<string name="mdnie_accessibility_summary_head">تنظیم حالت دسترسی mDNIe</string>
<string name="mdnie_scenario_ui">LineageOS (پیش فرض)</string>
<string name="mdnie_scenario_video">ویدئو</string>
<string name="mdnie_scenario_video_warm">ویدئو گرم</string>
<string name="mdnie_scenario_video_cold">ویدئو سرد</string>
<string name="mdnie_scenario_camera">دوربین</string>
<string name="mdnie_scenario_navigation">پیمایش</string>
<string name="mdnie_scenario_gallery">گالری</string>
<string name="mdnie_scenario_vt">تماس تصویری</string>
<string name="mdnie_scenario_browser">مرورگر</string>
<string name="mdnie_scenario_ebook">کتاب</string>
<string name="mdnie_scenario_email">ایمیل</string>
<string name="mdnie_scenario_tdmb">تلویزیون دیجیتال</string>
<string name="mdnie_accessibility_normal">عادی</string>
<string name="mdnie_accessibility_inverse">معکوس</string>
<string name="mdnie_accessibility_color_blind">کور رنگی</string>
<string name="mdnie_accessibility_screen_curtain">پرده صفحه نمایش</string>
<string name="mdnie_accessibility_grayscale">خاکستری</string>
<string name="mdnie_accessibility_gray_negative">خاکستری معکوس</string>
</resources>

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012-2014 The CyanogenMod Project
Copyright (C) 2018 The LineageOS 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.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Taispeáint chun cinn</string>
<string name="category_screen_title">Scáileán</string>
<string name="screen_colors_title">Dathanna</string>
<string name="mdnie_scenario_title_head">Cás</string>
<string name="mdnie_scenario_summary_head">Socraigh an cás mDNIe</string>
<string name="mdnie_accessibility_title_head">Mód inrochtaineachta</string>
<string name="mdnie_accessibility_summary_head">Socraigh modh inrochtaineachta mDNIe</string>
<string name="mdnie_scenario_ui">LineageOS (réamhshocraithe)</string>
<string name="mdnie_scenario_video">Físeán</string>
<string name="mdnie_scenario_video_warm">Físeán te</string>
<string name="mdnie_scenario_video_cold">Físeán fuar</string>
<string name="mdnie_scenario_camera">Ceamara</string>
<string name="mdnie_scenario_navigation">Loingseoireacht</string>
<string name="mdnie_scenario_gallery">Gailearaí</string>
<string name="mdnie_scenario_vt">Glao físe</string>
<string name="mdnie_scenario_browser">Brabhsálaí</string>
<string name="mdnie_scenario_ebook">r-leabhar</string>
<string name="mdnie_scenario_email">R-phost</string>
<string name="mdnie_scenario_tdmb">Teilifís dhigiteach</string>
<string name="mdnie_accessibility_normal">Gnáth</string>
<string name="mdnie_accessibility_inverse">Inbhéartaithe</string>
<string name="mdnie_accessibility_color_blind">Dath dall</string>
<string name="mdnie_accessibility_screen_curtain">Cuirtín scáileáin</string>
<string name="mdnie_accessibility_grayscale">Liath</string>
<string name="mdnie_accessibility_gray_negative">Liath inbhéartaithe</string>
</resources>

View File

@@ -32,9 +32,9 @@
<string name="mdnie_scenario_gallery">Galeria</string>
<string name="mdnie_scenario_vt">Chamada de vídeo</string>
<string name="mdnie_scenario_browser">Navegador</string>
<string name="mdnie_scenario_ebook">eBook</string>
<string name="mdnie_scenario_ebook">e-book</string>
<string name="mdnie_scenario_email">E-mail</string>
<string name="mdnie_scenario_tdmb">TV digital</string>
<string name="mdnie_scenario_tdmb">Televisão digital</string>
<string name="mdnie_accessibility_normal">Normal</string>
<string name="mdnie_accessibility_inverse">Invertido</string>
<string name="mdnie_accessibility_color_blind">Daltônico</string>

View File

@@ -21,17 +21,4 @@
<string name="screen_colors_title">நிறங்கள்</string>
<string name="mdnie_scenario_title_head">சூழ்நிலை</string>
<string name="mdnie_scenario_summary_head">mDNIe சூழ்நிலையை அமை</string>
<string name="mdnie_scenario_ui">LineageOS (இயல்புநிலை)</string>
<string name="mdnie_scenario_video">காணொளி</string>
<string name="mdnie_scenario_camera">படமி</string>
<string name="mdnie_scenario_gallery">தொகுப்பு</string>
<string name="mdnie_scenario_vt">ஒளி அழைப்பு</string>
<string name="mdnie_scenario_browser">உலாவி</string>
<string name="mdnie_scenario_ebook">மின்னூல்</string>
<string name="mdnie_scenario_email">மின்னஞ்சல்</string>
<string name="mdnie_scenario_tdmb"> எண்முறை தொலைக்காட்சி</string>
<string name="mdnie_accessibility_normal">இயல்பு</string>
<string name="mdnie_accessibility_color_blind">நிறக்குருடு</string>
<string name="mdnie_accessibility_screen_curtain">திரை மறைப்பு</string>
<string name="mdnie_accessibility_grayscale">சாம்பல்நிறம்</string>
</resources>

View File

@@ -21,24 +21,4 @@
<string name="screen_colors_title">رەڭلەر</string>
<string name="mdnie_scenario_title_head">كۆرۈنۈش</string>
<string name="mdnie_scenario_summary_head">mDNIe لايىھە تەڭشىكى</string>
<string name="mdnie_accessibility_title_head">ئاجىزلار ھالىتى</string>
<string name="mdnie_accessibility_summary_head">mDNIe نى ئاجىزلار ھالىتىگە تەڭشەيدۇ</string>
<string name="mdnie_scenario_ui">LineageOS (كۆڭۈلدىكى)</string>
<string name="mdnie_scenario_video">سىن</string>
<string name="mdnie_scenario_video_warm">سىن ئىسسىق</string>
<string name="mdnie_scenario_video_cold">سىن سوغۇق</string>
<string name="mdnie_scenario_camera">كامېرا</string>
<string name="mdnie_scenario_navigation">يولباشچى</string>
<string name="mdnie_scenario_gallery">سۈرەتدان</string>
<string name="mdnie_scenario_vt">سىن چاقىرىش</string>
<string name="mdnie_scenario_browser">تور كۆرگۈچ</string>
<string name="mdnie_scenario_ebook">ئې-كىتاب</string>
<string name="mdnie_scenario_email">ئېلخەت</string>
<string name="mdnie_scenario_tdmb">رەقەملىك تېلېۋىزور</string>
<string name="mdnie_accessibility_normal">ئادەتتىكى</string>
<string name="mdnie_accessibility_inverse">تەتۈر</string>
<string name="mdnie_accessibility_color_blind">رەڭ قارىغۇسى</string>
<string name="mdnie_accessibility_screen_curtain">ئېكران توسۇش</string>
<string name="mdnie_accessibility_grayscale">كۈلرەڭ</string>
<string name="mdnie_accessibility_gray_negative">ئەكسى كۈلرەڭ</string>
</resources>

43
Android.mk Normal file
View File

@@ -0,0 +1,43 @@
# Copyright (C) 2012 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.
SAM_ROOT := $(call my-dir)
# Exynos 4
ifeq ($(TARGET_BOARD_PLATFORM),exynos4)
ifeq ($(TARGET_SOC),exynos4210)
include $(SAM_ROOT)/exynos4210.mk
endif
ifeq ($(TARGET_SOC),exynos4x12)
include $(SAM_ROOT)/exynos4x12.mk
endif
endif
# Exynos 3
ifeq ($(TARGET_BOARD_PLATFORM),s5pc110)
include $(SAM_ROOT)/s5pc110.mk
endif
# Wifi
ifeq ($(BOARD_HAVE_SAMSUNG_WIFI),true)
include $(SAM_ROOT)/macloader/Android.mk
include $(SAM_ROOT)/wifiloader/Android.mk
endif
ifeq ($(BOARD_VENDOR),samsung)
include $(SAM_ROOT)/audio/Android.mk
include $(SAM_ROOT)/hidl/Android.mk
include $(SAM_ROOT)/modemloader/Android.mk
include $(SAM_ROOT)/ril/Android.mk
endif

View File

@@ -1,10 +1,10 @@
cc_library_static {
name: "android.hardware.camera.common-helper.samsung",
vendor_available: true,
defaults: [
"hidl_defaults",
"samsung_camera3_defaults",
],
vendor_available: true,
srcs: [
"CameraModule.cpp",
"CameraMetadata.cpp",
@@ -30,10 +30,7 @@ cc_library_static {
],
include_dirs: ["system/media/private/camera/include"],
header_libs: ["libhardware_headers.camera3_samsung"],
export_include_dirs: [
"include",
"include_samsung",
],
export_include_dirs: ["include", "include_samsung"],
export_shared_lib_headers: ["libui"],
}

View File

@@ -36,11 +36,6 @@ __BEGIN_DECLS
*/
#define CAMERA_HARDWARE_MODULE_ID "camera"
/**
* The id of Samsung UniHAL module
*/
#define SEC_CAMERA_HARDWARE_MODULE_ID "camera.unihal"
/**
* Module versioning information for the Camera hardware module, based on
* camera_module_t.common.module_api_version. The two most significant hex

View File

@@ -25,7 +25,7 @@ cc_defaults {
name: "camera_service_aidl_defaults.samsung",
defaults: [
"extra_id_defaults",
"samsung_camera3_defaults",
"samsung_camera3_defaults"
],
vintf_fragments: ["android.hardware.camera.provider-service.samsung.xml"],
vendor: true,

View File

@@ -183,13 +183,10 @@ bool CameraProvider::initCamera(int id) {
bool CameraProvider::initialize() {
camera_module_t* rawModule;
int err = hw_get_module(SEC_CAMERA_HARDWARE_MODULE_ID, (const hw_module_t**)&rawModule);
int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t**)&rawModule);
if (err < 0) {
err = hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t**)&rawModule);
if (err < 0) {
ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
return true;
}
ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
return true;
}
mModule = new SamsungCameraModule(rawModule);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2022 The Android Open Source Project
* Copyright (C) 2024-2025 The LineageOS Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,6 @@ int main() {
ALOGI("CameraProvider: samsung service is starting.");
ABinderProcess_setThreadPoolMaxThreadCount(HWBINDER_THREAD_COUNT);
ABinderProcess_startThreadPool();
std::shared_ptr<CameraProvider> defaultProvider = ndk::SharedRefBase::make<CameraProvider>();
const std::string serviceName = std::string(CameraProvider::descriptor) + "/internal/0";

View File

@@ -1,5 +1,5 @@
service vendor.fingerprint-default /vendor/bin/hw/android.hardware.biometrics.fingerprint-service.samsung
class late_start
class hal
user system
group system input uhid
shutdown critical

View File

@@ -9,7 +9,6 @@
#include <aidl/android/hardware/light/BnLights.h>
#include <samsung_lights.h>
#include <functional>
#include <unordered_map>
using ::aidl::android::hardware::light::HwLightState;

View File

@@ -1,24 +0,0 @@
//
// SPDX-FileCopyrightText: 2025 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
cc_binary {
name: "vendor.lineage.powershare-service.samsung",
defaults: ["samsung_header_path_defaults"],
vintf_fragments: ["vendor.lineage.powershare-service.samsung.xml"],
init_rc: ["vendor.lineage.powershare-service.samsung.rc"],
vendor: true,
relative_install_path: "hw",
srcs: [
"PowerShare.cpp",
"service.cpp",
],
shared_libs: [
"libbase",
"liblog",
"libbinder_ndk",
"libutils",
"vendor.lineage.powershare-V1-ndk",
],
}

View File

@@ -1,69 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "vendor.lineage.powershare-service.samsung"
#include "PowerShare.h"
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <samsung_powershare.h>
using ::android::base::ReadFileToString;
using ::android::base::Trim;
using ::android::base::WriteStringToFile;
namespace aidl {
namespace vendor {
namespace lineage {
namespace powershare {
ndk::ScopedAStatus PowerShare::getMinBattery(int32_t* _aidl_return) {
std::string value;
if (!ReadFileToString(POWERSHARE_STOP_CAPACITY_PATH, &value)) {
LOG(ERROR) << "Failed to get PowerShare minimum battery level";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
*_aidl_return = std::stoi(value);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus PowerShare::isEnabled(bool* _aidl_return) {
std::string value;
if (!ReadFileToString(POWERSHARE_PATH, &value)) {
LOG(ERROR) << "Failed to read current PowerShare state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
*_aidl_return = Trim(value) == POWERSHARE_ENABLED;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus PowerShare::setEnabled(bool enable) {
std::string value = enable ? POWERSHARE_ENABLED : POWERSHARE_DISABLED;
if (!WriteStringToFile(value, POWERSHARE_PATH)) {
LOG(ERROR) << "Failed to write PowerShare state";
return ndk::ScopedAStatus::fromExceptionCode(EX_SERVICE_SPECIFIC);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus PowerShare::setMinBattery(int32_t minBattery) {
if (!WriteStringToFile(std::to_string(minBattery), POWERSHARE_STOP_CAPACITY_PATH)) {
LOG(ERROR) << "Failed to set PowerShare minimum battery level";
return ndk::ScopedAStatus::fromExceptionCode(EX_SERVICE_SPECIFIC);
}
return ndk::ScopedAStatus::ok();
}
} // namespace powershare
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,26 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/powershare/BnPowerShare.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace powershare {
class PowerShare : public BnPowerShare {
public:
ndk::ScopedAStatus getMinBattery(int32_t* _aidl_return) override;
ndk::ScopedAStatus isEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool enable) override;
ndk::ScopedAStatus setMinBattery(int32_t minBattery) override;
};
} // namespace powershare
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,12 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#define POWERSHARE_DISABLED "0"
#define POWERSHARE_ENABLED "1"
#define POWERSHARE_PATH "/sys/class/power_supply/battery/wc_tx_en"
#define POWERSHARE_STOP_CAPACITY_PATH "/sys/class/power_supply/battery/wc_tx_stop_capacity"

View File

@@ -1,25 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#include "PowerShare.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using aidl::vendor::lineage::powershare::PowerShare;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<PowerShare> powershare = ndk::SharedRefBase::make<PowerShare>();
const std::string instance = std::string(PowerShare::descriptor) + "/default";
binder_status_t status =
AServiceManager_addService(powershare->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,10 +0,0 @@
on init
chown system system /sys/class/power_supply/battery/wc_tx_en
chown system system /sys/class/power_supply/battery/wc_tx_stop_capacity
chmod 0664 /sys/class/power_supply/battery/wc_tx_en
chmod 0664 /sys/class/power_supply/battery/wc_tx_stop_capacity
service vendor.powershare-hal /vendor/bin/hw/vendor.lineage.powershare-service.samsung
class hal
user system
group system

View File

@@ -1,7 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>vendor.lineage.powershare</name>
<version>1</version>
<fqname>IPowerShare/default</fqname>
</hal>
</manifest>

View File

@@ -32,7 +32,7 @@ cc_binary {
"android.hardware.sensors@2.0",
"android.hardware.sensors@2.0-ScopedWakelock",
"android.hardware.sensors@2.1",
"android.hardware.sensors-V3-ndk",
"android.hardware.sensors-V2-ndk",
"libbase",
"libbinder_ndk",
"libcutils",
@@ -49,9 +49,3 @@ cc_binary {
"libaidlcommonsupport",
],
}
cc_library_shared {
name: "sensors.sensorhub_wait_for_mcu",
srcs: ["SensorHubWaitForMCUInit.cpp"],
vendor: true,
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS 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.
*/
#include <dlfcn.h>
#include <chrono>
#include <fstream>
#include <thread>
extern "C" void* sensorsHalGetSubHal(uint32_t* version) {
static auto sensorsHalGetSubHalOrig = reinterpret_cast<typeof(sensorsHalGetSubHal)*>(
dlsym(dlopen("sensors.sensorhub.so", RTLD_NOW), "sensorsHalGetSubHal"));
while (true) {
std::ifstream mcu_test("/sys/devices/virtual/sensors/ssp_sensor/mcu_test");
if (mcu_test) {
std::string value;
mcu_test >> value;
if (value.ends_with(",OK")) {
break;
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
return sensorsHalGetSubHalOrig(version);
}

View File

@@ -17,7 +17,7 @@
<manifest version="1.0" type="device">
<hal format="aidl" override="true">
<name>android.hardware.sensors</name>
<version>3</version>
<version>2</version>
<fqname>ISensors/default</fqname>
</hal>
</manifest>

View File

@@ -1,26 +0,0 @@
//
// SPDX-FileCopyrightText: 2025 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
cc_binary {
name: "vendor.lineage.touch-service.samsung",
defaults: ["samsung_header_path_defaults"],
init_rc: ["vendor.lineage.touch-service.samsung.rc"],
relative_install_path: "hw",
proprietary: true,
srcs: [
"GloveMode.cpp",
"KeyDisabler.cpp",
"StylusMode.cpp",
"TouchscreenGesture.cpp",
"service.cpp",
],
shared_libs: [
"libbase",
"liblog",
"libbinder_ndk",
"libutils",
"vendor.lineage.touch-V1-ndk",
],
}

View File

@@ -1,49 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#include <fstream>
#include "GloveMode.h"
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
bool GloveMode::isSupported() {
std::ifstream file(TSP_CMD_LIST_NODE);
if (file.is_open()) {
std::string line;
while (getline(file, line)) {
if (!line.compare("glove_mode")) return true;
}
file.close();
}
return false;
}
ndk::ScopedAStatus GloveMode::getEnabled(bool* _aidl_return) {
std::ifstream file(TSP_CMD_RESULT_NODE);
if (file.is_open()) {
std::string line;
getline(file, line);
*_aidl_return = !line.compare("glove_mode,1:OK");
file.close();
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus GloveMode::setEnabled(bool enabled) {
std::ofstream file(TSP_CMD_NODE);
file << "glove_mode," << (enabled ? "1" : "0");
return ndk::ScopedAStatus::ok();
}
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,27 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/touch/BnGloveMode.h>
#include <samsung_touch.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
class GloveMode : public BnGloveMode {
public:
bool isSupported();
ndk::ScopedAStatus getEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool enabled) override;
};
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,42 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#include <fstream>
#include "KeyDisabler.h"
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
bool KeyDisabler::isSupported() {
std::ofstream file(KEY_DISABLER_NODE);
return file.good();
}
ndk::ScopedAStatus KeyDisabler::getEnabled(bool* _aidl_return) {
std::ifstream file(KEY_DISABLER_NODE);
int status = -1;
if (file.is_open()) {
file >> status;
}
*_aidl_return = status == 0;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus KeyDisabler::setEnabled(bool enabled) {
std::ofstream file(KEY_DISABLER_NODE);
file << (enabled ? "0" : "1");
return ndk::ScopedAStatus::ok();
}
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,27 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/touch/BnKeyDisabler.h>
#include <samsung_touch.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
class KeyDisabler : public BnKeyDisabler {
public:
bool isSupported();
ndk::ScopedAStatus getEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool enabled) override;
};
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,49 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#include <fstream>
#include "StylusMode.h"
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
bool StylusMode::isSupported() {
std::ifstream file(TSP_CMD_LIST_NODE);
if (file.is_open()) {
std::string line;
while (getline(file, line)) {
if (!line.compare("hover_enable")) return true;
}
file.close();
}
return false;
}
ndk::ScopedAStatus StylusMode::getEnabled(bool* _aidl_return) {
std::ifstream file(TSP_CMD_RESULT_NODE);
if (file.is_open()) {
std::string line;
getline(file, line);
*_aidl_return = !line.compare("hover_enable,1:OK");
file.close();
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus StylusMode::setEnabled(bool enabled) {
std::ofstream file(TSP_CMD_NODE);
file << "hover_enable," << (enabled ? "1" : "0");
return ndk::ScopedAStatus::ok();
}
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,27 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/touch/BnStylusMode.h>
#include <samsung_touch.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
class StylusMode : public BnStylusMode {
public:
bool isSupported();
ndk::ScopedAStatus getEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool enabled) override;
};
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,61 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#include <fstream>
#include "TouchscreenGesture.h"
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
const std::map<int32_t, TouchscreenGesture::GestureInfo> TouchscreenGesture::kGestureInfoMap = {
// clang-format off
{0, {0x2f1, "Swipe up stylus"}},
{1, {0x2f2, "Swipe down stylus"}},
{2, {0x2f3, "Swipe left stylus"}},
{3, {0x2f4, "Swipe right stylus"}},
{4, {0x2f5, "Long press stylus"}},
// clang-format on
};
bool TouchscreenGesture::isSupported() {
std::ifstream file(TOUCHSCREEN_GESTURE_NODE);
return file.good();
}
ndk::ScopedAStatus TouchscreenGesture::getSupportedGestures(std::vector<Gesture>* _aidl_return) {
std::vector<Gesture> gestures;
for (const auto& entry : kGestureInfoMap) {
gestures.push_back({entry.first, entry.second.name, entry.second.keycode});
}
*_aidl_return = gestures;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus TouchscreenGesture::setGestureEnabled(const Gesture& gesture, bool enabled) {
std::fstream file(TOUCHSCREEN_GESTURE_NODE);
int gestureMode;
int mask = 1 << gesture.id;
file >> gestureMode;
if (enabled)
gestureMode |= mask;
else
gestureMode &= ~mask;
file << gestureMode;
return ndk::ScopedAStatus::ok();
}
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,35 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/touch/BnTouchscreenGesture.h>
#include <map>
#include <samsung_touch.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
class TouchscreenGesture : public BnTouchscreenGesture {
public:
bool isSupported();
ndk::ScopedAStatus getSupportedGestures(std::vector<Gesture>* _aidl_return) override;
ndk::ScopedAStatus setGestureEnabled(const Gesture& gesture, bool enabled) override;
private:
typedef struct {
int32_t keycode;
const char* name;
} GestureInfo;
static const std::map<int32_t, GestureInfo> kGestureInfoMap; // id -> info
};
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,25 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/*
* Board specific nodes
*
* If your kernel exposes these controls in another place, you can either
* symlink to the locations given here, or override this header in your
* device tree.
*/
// For GloveMode and StylusMode
#define TSP_CMD_LIST_NODE "/sys/class/sec/tsp/cmd_list"
#define TSP_CMD_RESULT_NODE "/sys/class/sec/tsp/cmd_result"
#define TSP_CMD_NODE "/sys/class/sec/tsp/cmd"
// For KeyDisabler
#define KEY_DISABLER_NODE "/sys/class/sec/sec_touchkey/input/enabled"
//For TouchscreenGesture
#define TOUCHSCREEN_GESTURE_NODE "/sys/class/sec/sec_epen/epen_gestures"

View File

@@ -1,57 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "vendor.lineage.touch-service.samsung"
#include "GloveMode.h"
#include "KeyDisabler.h"
#include "StylusMode.h"
#include "TouchscreenGesture.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using aidl::vendor::lineage::touch::GloveMode;
using aidl::vendor::lineage::touch::KeyDisabler;
using aidl::vendor::lineage::touch::StylusMode;
using aidl::vendor::lineage::touch::TouchscreenGesture;
int main() {
binder_status_t status = STATUS_OK;
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<GloveMode> gm = ndk::SharedRefBase::make<GloveMode>();
if (gm->isSupported()) {
const std::string gm_instance = std::string(GloveMode::descriptor) + "/default";
status = AServiceManager_addService(gm->asBinder().get(), gm_instance.c_str());
CHECK_EQ(status, STATUS_OK) << "Failed to add service " << gm_instance << " " << status;
}
std::shared_ptr<KeyDisabler> kd = ndk::SharedRefBase::make<KeyDisabler>();
if (kd->isSupported()) {
const std::string kd_instance = std::string(KeyDisabler::descriptor) + "/default";
status = AServiceManager_addService(kd->asBinder().get(), kd_instance.c_str());
CHECK_EQ(status, STATUS_OK) << "Failed to add service " << kd_instance << " " << status;
}
std::shared_ptr<StylusMode> sm = ndk::SharedRefBase::make<StylusMode>();
if (sm->isSupported()) {
const std::string sm_instance = std::string(StylusMode::descriptor) + "/default";
status = AServiceManager_addService(sm->asBinder().get(), sm_instance.c_str());
CHECK_EQ(status, STATUS_OK) << "Failed to add service " << sm_instance << " " << status;
}
std::shared_ptr<TouchscreenGesture> tg = ndk::SharedRefBase::make<TouchscreenGesture>();
if (tg->isSupported()) {
const std::string tg_instance = std::string(TouchscreenGesture::descriptor) + "/default";
status = AServiceManager_addService(tg->asBinder().get(), tg_instance.c_str());
CHECK_EQ(status, STATUS_OK) << "Failed to add service " << tg_instance << " " << status;
}
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,4 +0,0 @@
service vendor.touch-hal /vendor/bin/hw/vendor.lineage.touch-service.samsung
class hal
user system
group system

View File

@@ -40,14 +40,8 @@ cc_binary {
"android.hardware.usb.gadget-service.samsung.xml",
],
vendor: true,
srcs: [
"service_gadget.cpp",
"UsbGadget.cpp",
],
cflags: [
"-Wall",
"-Werror",
],
srcs: ["service_gadget.cpp", "UsbGadget.cpp"],
cflags: ["-Wall", "-Werror"],
shared_libs: [
"libbase",
"liblog",

View File

@@ -10,14 +10,11 @@
#include <android-base/properties.h>
#include <cmath>
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <map>
#include <thread>
#include <linux/input.h>
namespace aidl {
namespace android {
namespace hardware {
@@ -34,14 +31,6 @@ static std::map<Effect, int> CP_TRIGGER_EFFECTS {
{ Effect::TICK, 50 }
};
static std::map<Effect, short> FF_EFFECT_IDS {
{ Effect::CLICK, 1 },
{ Effect::DOUBLE_CLICK, 5 },
{ Effect::TICK, 41 },
{ Effect::HEAVY_CLICK, 14 },
{ Effect::TEXTURE_TICK, 41 }
};
#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
static std::map<EffectStrength, float> DURATION_AMPLITUDE = {
{ EffectStrength::LIGHT, DURATION_AMPLITUDE_LIGHT },
@@ -83,21 +72,6 @@ static int getIntProperty(const std::string& key, int def) {
Vibrator::Vibrator() {
mIsTimedOutVibrator = nodeExists(VIBRATOR_TIMEOUT_PATH);
if (!mIsTimedOutVibrator) {
for (const auto &file : std::filesystem::directory_iterator("/dev/input")) {
auto fd = open(file.path().c_str(), O_RDWR);
if (fd != -1) {
char name[32];
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
if (strcmp("sec_vibrator_inputff", name) == 0) {
mVibratorFd = fd;
mIsForceFeedbackVibrator = true;
break;
}
close(fd);
}
}
}
mHasTimedOutIntensity = nodeExists(VIBRATOR_INTENSITY_PATH);
mHasTimedOutEffect = nodeExists(VIBRATOR_CP_TRIGGER_PATH);
}
@@ -114,9 +88,6 @@ ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
*_aidl_return |= IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
#endif
if (mIsForceFeedbackVibrator)
*_aidl_return |= IVibrator::CAP_AMPLITUDE_CONTROL;
return ndk::ScopedAStatus::ok();
}
@@ -130,9 +101,6 @@ ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs, const std::shared_ptr<IVibrat
if (mHasTimedOutEffect)
writeNode(VIBRATOR_CP_TRIGGER_PATH, 0); // Clear all effects
if (mIsForceFeedbackVibrator)
uploadFFEffect(0, timeoutMs);
#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
timeoutMs *= mDurationAmplitude;
#endif
@@ -161,17 +129,11 @@ ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength, con
if (!status.isOk())
return status;
if (mIsTimedOutVibrator)
activate(0);
activate(0);
setAmplitude(amplitude);
if (mHasTimedOutEffect && CP_TRIGGER_EFFECTS.find(effect) != CP_TRIGGER_EFFECTS.end()) {
writeNode(VIBRATOR_CP_TRIGGER_PATH, CP_TRIGGER_EFFECTS[effect]);
} else if (mIsForceFeedbackVibrator) {
if (FF_EFFECT_IDS.find(effect) == FF_EFFECT_IDS.end())
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
uploadFFEffect(FF_EFFECT_IDS[effect], 0);
} else {
if (mHasTimedOutEffect)
writeNode(VIBRATOR_CP_TRIGGER_PATH, 0); // Clear previous effect
@@ -233,17 +195,6 @@ ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
if (mHasTimedOutIntensity) {
return writeNode(VIBRATOR_INTENSITY_PATH, intensity);
}
if (mIsForceFeedbackVibrator) {
struct input_event event {
.type = EV_FF,
.code = FF_GAIN,
.value = static_cast<__s32>(intensity),
};
if (write(mVibratorFd, &event, sizeof(event)) == -1)
return ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
return ndk::ScopedAStatus::ok();
}
#endif
return ndk::ScopedAStatus::ok();
@@ -331,68 +282,11 @@ ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle>& /*com
ndk::ScopedAStatus Vibrator::activate(uint32_t timeoutMs) {
std::lock_guard<std::mutex> lock{mMutex};
if (mIsTimedOutVibrator) {
return writeNode(VIBRATOR_TIMEOUT_PATH, timeoutMs);
}
if (mIsForceFeedbackVibrator) {
struct input_event event {
.type = EV_FF,
.code = 0,
.value = timeoutMs != 0,
};
writeNode("/sys/class/sec_vib_inputff/control/use_sep_index", 1);
if (write(mVibratorFd, &event, sizeof(event)) == -1)
return ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
return ndk::ScopedAStatus::ok();
}
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
ndk::ScopedAStatus Vibrator::uploadFFEffect(short effectId, int timeoutMs) {
int16_t data[2] = {0, effectId};
int ret;
// Remove previously uploaded effect in case it exists
ret = ioctl(mVibratorFd, EVIOCRMFF, 0);
if (ret == -1) {
LOG(WARNING) << "Failed to remove effect";
if (!mIsTimedOutVibrator) {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
struct ff_effect effect = {
.type = FF_PERIODIC,
.id = -1,
.direction = 0,
.trigger = {
.button = 0,
.interval = 0,
},
.replay = {
.length = static_cast<uint16_t>(timeoutMs),
.delay = 0,
},
.u.periodic = {
.waveform = FF_CUSTOM,
.period = 0,
.magnitude = 0,
.offset = 0,
.phase = 0,
.envelope = {
.attack_length = 0,
.attack_level = 0,
.fade_length = 0,
.fade_level = 0,
},
.custom_len = 2,
.custom_data = data,
},
};
ret = ioctl(mVibratorFd, EVIOCSFF, &effect);
if (ret == -1) {
LOG(ERROR) << "Effect upload failed: " << errno;
return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
}
return ndk::ScopedAStatus::ok();
return writeNode(VIBRATOR_TIMEOUT_PATH, timeoutMs);
}
float Vibrator::strengthToAmplitude(EffectStrength strength, ndk::ScopedAStatus* status) {

View File

@@ -69,7 +69,6 @@ public:
private:
ndk::ScopedAStatus activate(uint32_t ms);
ndk::ScopedAStatus uploadFFEffect(short effectId, int timeoutMs);
uint32_t effectToMs(Effect effect, ndk::ScopedAStatus* status);
static float strengthToAmplitude(EffectStrength strength, ndk::ScopedAStatus* status);
@@ -83,11 +82,8 @@ private:
std::mutex mMutex;
bool mIsTimedOutVibrator;
bool mIsForceFeedbackVibrator{false};
bool mHasTimedOutIntensity;
bool mHasTimedOutEffect;
int mVibratorFd{-1};
};
} // namespace vibrator

67
audio/Android.mk Normal file
View File

@@ -0,0 +1,67 @@
# Copyright (C) 2017 The LineageOS 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.
ifeq ($(TARGET_AUDIOHAL_VARIANT),samsung)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES := \
audience.c \
audio_hw.c \
compress_offload.c \
ril_interface.c \
voice.c
# TODO: remove resampler if possible when AudioFlinger supports downsampling from 48 to 8
LOCAL_SHARED_LIBRARIES := \
liblog \
libcutils \
libaudioutils \
libhardware \
libprocessgroup \
libtinyalsa \
libtinycompress \
libaudioroute \
libdl \
libsecril-client
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/include \
external/tinyalsa/include \
external/tinycompress/include \
hardware/libhardware/include \
hardware/samsung/ril/libsecril-client \
$(call include-path-for, audio-utils) \
$(call include-path-for, audio-route) \
$(call include-path-for, audio-effects)
LOCAL_CFLAGS := -Werror -Wall
LOCAL_CFLAGS += -DPREPROCESSING_ENABLED
LOCAL_MODULE := audio.primary.$(TARGET_BOOTLOADER_BOARD_NAME)
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE_TAGS := optional
LOCAL_VENDOR_MODULE := true
include $(BUILD_SHARED_LIBRARY)
endif

195
audio/audience.c Normal file
View File

@@ -0,0 +1,195 @@
/*
* Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
*
* 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_audience"
#define LOG_NDEBUG 0
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cutils/log.h>
#include <audience-routes.h>
#include "audience.h"
/*
* Writes an Integer to a file.
*
* @param path The absolute path string.
* @param value The Integer value to be written.
* @return 0 on success, errno on error.
*/
static int write_int(char const *path, const int value)
{
int fd, len, num_bytes;
int ret = 0;
char buffer[20];
fd = open(path, O_WRONLY);
if (fd < 0) {
ret = errno;
ALOGE("%s: failed to open %s (%s)", __func__, path, strerror(errno));
goto exit;
}
num_bytes = sprintf(buffer, "%d", value);
len = write(fd, buffer, num_bytes);
if (len < 0) {
ret = errno;
ALOGE("%s: failed to write to %s (%s)", __func__, path, strerror(errno));
goto exit;
}
exit:
close(fd);
return ret;
}
/*
* Writes the route value to sysfs.
*
* @param value The long Integer value to be written.
* @return 0 on success, -1 or errno on error.
*/
static int es_route_value_set(int value)
{
return write_int(SYSFS_PATH_PRESET, value);
}
/*
* Writes the veq control to sysfs.
*
* @param value The Integer value to be written.
* @return 0 on success, -1 or errno on error.
*/
static int es_veq_control_set(int value)
{
return write_int(SYSFS_PATH_VEQ, value);
}
/*
* Writes the extra volume to sysfs.
*
* @param value The Integer value to be written.
* @return 0 on success, -1 or errno on error.
*/
static int es_extra_volume_set(int value)
{
return write_int(SYSFS_PATH_EXTRAVOLUME, value);
}
/*
* Convertes an out_device from the session to an earSmart compatible route.
*
* @param out_device The output device to be converted.
* @return Audience earSmart route, coded as long Integer.
*/
static long es_device_to_route(struct voice_session *session)
{
long ret;
long nb_route;
long wb_route;
switch(session->out_device) {
case AUDIO_DEVICE_OUT_EARPIECE:
nb_route = Call_CT_NB;
wb_route = Call_CT_WB;
break;
case AUDIO_DEVICE_OUT_SPEAKER:
nb_route = Call_FT_NB;
wb_route = Call_FT_WB;
break;
case AUDIO_DEVICE_OUT_WIRED_HEADSET:
case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
nb_route = Call_HS_NB;
wb_route = Call_HS_WB;
break;
case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
nb_route = Call_BT_NB;
wb_route = Call_BT_WB;
break;
default:
/* if output device isn't supported, use earpiece by default */
ALOGE("%s: unknown output device: %d, defaulting to earpiece", __func__,
session->out_device);
nb_route = Call_CT_NB;
wb_route = Call_CT_WB;
break;
}
/* TODO: Handle wb_amr=2 */
if (session->wb_amr_type >= 1) {
ret = wb_route;
} else {
ret = nb_route;
}
ALOGV("%s: converting out_device=%d to %s route: %ld", __func__, session->out_device,
ret == wb_route ? "Wide Band" : "Narrow Band", ret);
return ret;
}
/*
* Configures and enables the Audience earSmart IC.
*
* @param session Reference to the active voice call session.
* @return @return 0 on success, -1 or errno on error.
*/
int es_start_voice_session(struct voice_session *session)
{
int ret;
long es_route = es_device_to_route(session);
/* TODO: Calculate these */
int extra_volume = 0;
int veq_control = 4;
/*
* The control flow for audience earSmart chip is as follows:
*
* route_value >> power_control(internal) >> extra_volume >> veq_control
*/
ret = es_route_value_set(es_route);
if (ret != 0) {
ALOGE("%s: es_route_value_set(%ld) failed with code: %d", __func__, es_route, ret);
goto exit;
}
ret = es_extra_volume_set(extra_volume);
if (ret != 0) {
ALOGE("%s: es_extra_volume_set(%d) failed with code: %d", __func__, extra_volume, ret);
goto exit;
}
ret = es_veq_control_set(veq_control);
if (ret != 0) {
ALOGE("%s: es_veq_control_set(%d) failed with code: %d", __func__, veq_control, ret);
goto exit;
}
exit:
return ret;
}
/*
* Disables the Audience earSmart IC.
*/
void es_stop_voice_session()
{
/* This will cancel any pending workers, stop the stream and send the IC to sleep */
es_route_value_set(AUDIENCE_SLEEP);
}

29
audio/audience.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
*
* 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.
*/
#include "audio_hw.h"
#include "voice.h"
enum es_power_state {
ES_POWER_FW_LOAD,
ES_POWER_SLEEP,
ES_POWER_SLEEP_PENDING,
ES_POWER_AWAKE,
ES_MAX = ES_POWER_AWAKE
};
int es_start_voice_session(struct voice_session *session);
void es_stop_voice_session();

4346
audio/audio_hw.c Normal file

File diff suppressed because it is too large Load Diff

421
audio/audio_hw.h Normal file
View File

@@ -0,0 +1,421 @@
/*
* Copyright (C) 2013 The Android Open Source Project
* Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
* Copyright (C) 2018 The LineageOS 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.
*/
#ifndef SAMSUNG_AUDIO_HW_H
#define SAMSUNG_AUDIO_HW_H
#include <cutils/list.h>
#include <hardware/audio.h>
#include <hardware/audio_amplifier.h>
#include <tinyalsa/asoundlib.h>
#include <tinycompress/tinycompress.h>
/* TODO: remove resampler if possible when AudioFlinger supports downsampling from 48 to 8 */
#include <audio_utils/resampler.h>
#include <audio_route/audio_route.h>
/* Retry for delay in FW loading*/
#define RETRY_NUMBER 10
#define RETRY_US 500000
#ifdef __LP64__
#define OFFLOAD_FX_LIBRARY_PATH "/system/lib64/soundfx/libnvvisualizer.so"
#else
#define OFFLOAD_FX_LIBRARY_PATH "/system/lib/soundfx/libnvvisualizer.so"
#endif
#ifdef PREPROCESSING_ENABLED
#include <audio_utils/echo_reference.h>
#define MAX_PREPROCESSORS 3
struct effect_info_s {
effect_handle_t effect_itfe;
size_t num_channel_configs;
channel_config_t *channel_configs;
};
#endif
/* Sound devices specific to the platform
* The DEVICE_OUT_* and DEVICE_IN_* should be mapped to these sound
* devices to enable corresponding mixer paths
*/
enum {
SND_DEVICE_NONE = 0,
/* Playback devices */
SND_DEVICE_MIN,
SND_DEVICE_OUT_BEGIN = SND_DEVICE_MIN,
SND_DEVICE_OUT_EARPIECE = SND_DEVICE_OUT_BEGIN,
SND_DEVICE_OUT_SPEAKER,
SND_DEVICE_OUT_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
SND_DEVICE_OUT_VOICE_EARPIECE,
SND_DEVICE_OUT_VOICE_EARPIECE_WB,
SND_DEVICE_OUT_VOICE_SPEAKER,
SND_DEVICE_OUT_VOICE_SPEAKER_WB,
SND_DEVICE_OUT_VOICE_HEADPHONES,
SND_DEVICE_OUT_VOICE_HEADPHONES_WB,
SND_DEVICE_OUT_VOICE_BT_SCO,
SND_DEVICE_OUT_VOICE_BT_SCO_WB,
SND_DEVICE_OUT_HDMI,
SND_DEVICE_OUT_SPEAKER_AND_HDMI,
SND_DEVICE_OUT_BT_SCO,
SND_DEVICE_OUT_END,
/*
* Note: IN_BEGIN should be same as OUT_END because total number of devices
* SND_DEVICES_MAX should not exceed MAX_RX + MAX_TX devices.
*/
/* Capture devices */
SND_DEVICE_IN_BEGIN = SND_DEVICE_OUT_END,
SND_DEVICE_IN_EARPIECE_MIC = SND_DEVICE_IN_BEGIN,
SND_DEVICE_IN_SPEAKER_MIC,
SND_DEVICE_IN_HEADSET_MIC,
SND_DEVICE_IN_EARPIECE_MIC_AEC,
SND_DEVICE_IN_SPEAKER_MIC_AEC,
SND_DEVICE_IN_HEADSET_MIC_AEC,
SND_DEVICE_IN_VOICE_MIC,
SND_DEVICE_IN_VOICE_EARPIECE_MIC,
SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB,
SND_DEVICE_IN_VOICE_SPEAKER_MIC,
SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB,
SND_DEVICE_IN_VOICE_HEADSET_MIC,
SND_DEVICE_IN_VOICE_HEADSET_MIC_WB,
SND_DEVICE_IN_VOICE_BT_SCO_MIC,
SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB,
SND_DEVICE_IN_HDMI_MIC,
SND_DEVICE_IN_BT_SCO_MIC,
SND_DEVICE_IN_CAMCORDER_MIC,
SND_DEVICE_IN_VOICE_REC_HEADSET_MIC,
SND_DEVICE_IN_VOICE_REC_MIC,
SND_DEVICE_IN_END,
SND_DEVICE_MAX = SND_DEVICE_IN_END,
};
/*
* tinyAlsa library interprets period size as number of frames
* one frame = channel_count * sizeof (pcm sample)
* so if format = 16-bit PCM and channels = Stereo, frame size = 2 ch * 2 = 4 bytes
* DEEP_BUFFER_OUTPUT_PERIOD_SIZE = 1024 means 1024 * 4 = 4096 bytes
* We should take care of returning proper size when AudioFlinger queries for
* the buffer size of an input/output stream
*/
#define PLAYBACK_PERIOD_SIZE 256
#define PLAYBACK_PERIOD_COUNT 2
#define PLAYBACK_DEFAULT_CHANNEL_COUNT 2
#define PLAYBACK_DEFAULT_SAMPLING_RATE 48000
#define PLAYBACK_START_THRESHOLD(size, count) (((size) * (count)) - 1)
#define PLAYBACK_STOP_THRESHOLD(size, count) ((size) * ((count) + 2))
#define PLAYBACK_AVAILABLE_MIN 1
#define SCO_PERIOD_SIZE 168
#define SCO_PERIOD_COUNT 2
#define SCO_DEFAULT_CHANNEL_COUNT 2
#define SCO_DEFAULT_SAMPLING_RATE 8000
#define SCO_WB_SAMPLING_RATE 16000
#define SCO_START_THRESHOLD 335
#define SCO_STOP_THRESHOLD 336
#define SCO_AVAILABLE_MIN 1
#define PLAYBACK_HDMI_MULTI_PERIOD_SIZE 1024
#define PLAYBACK_HDMI_MULTI_PERIOD_COUNT 4
#define PLAYBACK_HDMI_MULTI_DEFAULT_CHANNEL_COUNT 6
#define PLAYBACK_HDMI_MULTI_PERIOD_BYTES \
(PLAYBACK_HDMI_MULTI_PERIOD_SIZE * PLAYBACK_HDMI_MULTI_DEFAULT_CHANNEL_COUNT * 2)
#define PLAYBACK_HDMI_MULTI_START_THRESHOLD 4095
#define PLAYBACK_HDMI_MULTI_STOP_THRESHOLD 4096
#define PLAYBACK_HDMI_MULTI_AVAILABLE_MIN 1
#define PLAYBACK_HDMI_DEFAULT_CHANNEL_COUNT 2
#define CAPTURE_PERIOD_SIZE 1024
#define CAPTURE_PERIOD_SIZE_LOW_LATENCY 256
#define CAPTURE_PERIOD_COUNT 2
#define CAPTURE_PERIOD_COUNT_LOW_LATENCY 2
#define CAPTURE_DEFAULT_CHANNEL_COUNT 2
#define CAPTURE_DEFAULT_SAMPLING_RATE 48000
#define CAPTURE_START_THRESHOLD 1
#define COMPRESS_CARD 0
#define COMPRESS_DEVICE 5
#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
#define COMPRESS_OFFLOAD_NUM_FRAGMENTS 4
/* ToDo: Check and update a proper value in msec */
#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96
#define COMPRESS_PLAYBACK_VOLUME_MAX 0x10000 //NV suggested value
#define DEEP_BUFFER_OUTPUT_SAMPLING_RATE 48000
#define DEEP_BUFFER_OUTPUT_PERIOD_SIZE 480
#define DEEP_BUFFER_OUTPUT_PERIOD_COUNT 8
#define MAX_SUPPORTED_CHANNEL_MASKS 2
typedef int snd_device_t;
/* These are the supported use cases by the hardware.
* Each usecase is mapped to a specific PCM device.
* Refer to pcm_device_table[].
*/
typedef enum {
USECASE_INVALID = -1,
/* Playback usecases */
USECASE_AUDIO_PLAYBACK = 0,
USECASE_AUDIO_PLAYBACK_MULTI_CH,
USECASE_AUDIO_PLAYBACK_OFFLOAD,
USECASE_AUDIO_PLAYBACK_DEEP_BUFFER,
/* Capture usecases */
USECASE_AUDIO_CAPTURE,
USECASE_VOICE_CALL,
AUDIO_USECASE_MAX
} audio_usecase_t;
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
/*
* tinyAlsa library interprets period size as number of frames
* one frame = channel_count * sizeof (pcm sample)
* so if format = 16-bit PCM and channels = Stereo, frame size = 2 ch * 2 = 4 bytes
* DEEP_BUFFER_OUTPUT_PERIOD_SIZE = 1024 means 1024 * 4 = 4096 bytes
* We should take care of returning proper size when AudioFlinger queries for
* the buffer size of an input/output stream
*/
enum {
OFFLOAD_CMD_EXIT, /* exit compress offload thread loop*/
OFFLOAD_CMD_DRAIN, /* send a full drain request to DSP */
OFFLOAD_CMD_PARTIAL_DRAIN, /* send a partial drain request to DSP */
OFFLOAD_CMD_WAIT_FOR_BUFFER, /* wait for buffer released by DSP */
};
enum {
OFFLOAD_STATE_IDLE,
OFFLOAD_STATE_PLAYING,
OFFLOAD_STATE_PAUSED,
OFFLOAD_STATE_PAUSED_FLUSHED,
};
typedef enum {
PCM_PLAYBACK = 0x1,
PCM_CAPTURE = 0x2,
VOICE_CALL = 0x4,
PCM_CAPTURE_LOW_LATENCY = 0x10,
} usecase_type_t;
struct offload_cmd {
struct listnode node;
int cmd;
int data[];
};
struct pcm_device_profile {
struct pcm_config config;
int card;
int id;
usecase_type_t type;
audio_devices_t devices;
};
struct pcm_device {
struct listnode stream_list_node;
struct pcm_device_profile* pcm_profile;
struct pcm* pcm;
int status;
};
struct stream_out {
struct audio_stream_out stream;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
pthread_cond_t cond;
struct pcm_config config;
struct listnode pcm_dev_list;
struct compr_config compr_config;
struct compress* compr;
int standby;
unsigned int sample_rate;
audio_channel_mask_t channel_mask;
audio_format_t format;
audio_devices_t devices;
audio_output_flags_t flags;
audio_usecase_t usecase;
/* Array of supported channel mask configurations. +1 so that the last entry is always 0 */
audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
bool muted;
/* total frames written, not cleared when entering standby */
uint64_t written;
audio_io_handle_t handle;
int non_blocking;
int offload_state;
pthread_cond_t offload_cond;
pthread_t offload_thread;
struct listnode offload_cmd_list;
bool offload_thread_blocked;
stream_callback_t offload_callback;
void* offload_cookie;
struct compr_gapless_mdata gapless_mdata;
int send_new_metadata;
struct audio_device* dev;
#ifdef PREPROCESSING_ENABLED
struct echo_reference_itfe *echo_reference;
// echo_reference_generation indicates if the echo reference used by the output stream is
// in sync with the one known by the audio_device. When different from the generation stored
// in the audio_device the output stream must release the echo reference.
// always modified with audio device and stream mutex locked.
int32_t echo_reference_generation;
#endif
bool is_fastmixer_affinity_set;
int64_t last_write_time_us;
};
struct stream_in {
struct audio_stream_in stream;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by
capture thread */
struct pcm_config config;
struct listnode pcm_dev_list;
int standby;
audio_source_t source;
audio_devices_t devices;
uint32_t main_channels;
audio_usecase_t usecase;
usecase_type_t usecase_type;
bool enable_aec;
audio_input_flags_t input_flags;
/* TODO: remove resampler if possible when AudioFlinger supports downsampling from 48 to 8 */
unsigned int requested_rate;
struct resampler_itfe* resampler;
struct resampler_buffer_provider buf_provider;
int read_status;
int16_t* read_buf;
size_t read_buf_size;
size_t read_buf_frames;
int16_t *proc_buf_in;
int16_t *proc_buf_out;
size_t proc_buf_size;
size_t proc_buf_frames;
#ifdef PREPROCESSING_ENABLED
struct echo_reference_itfe *echo_reference;
int16_t *ref_buf;
size_t ref_buf_size;
size_t ref_buf_frames;
int num_preprocessors;
struct effect_info_s preprocessors[MAX_PREPROCESSORS];
bool aux_channels_changed;
uint32_t aux_channels;
#endif
struct audio_device* dev;
bool is_fastcapture_affinity_set;
int64_t last_read_time_us;
int64_t frames_read; /* total frames read, not cleared when
entering standby */
};
struct mixer_card {
struct listnode adev_list_node;
struct listnode uc_list_node[AUDIO_USECASE_MAX];
int card;
struct mixer* mixer;
struct audio_route* audio_route;
struct timespec dsp_poweroff_time;
};
struct audio_usecase {
struct listnode adev_list_node;
audio_usecase_t id;
usecase_type_t type;
audio_devices_t devices;
snd_device_t out_snd_device;
snd_device_t in_snd_device;
struct audio_stream* stream;
struct listnode mixer_list;
};
struct voice_data {
bool in_call;
float volume;
bool bluetooth_nrec;
bool bluetooth_wb;
struct voice_session *session;
};
struct audio_device {
struct audio_hw_device device;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
struct listnode mixer_list;
audio_mode_t mode;
struct stream_in* active_input;
struct stream_out* primary_output;
bool mic_mute;
bool screen_off;
bool bt_sco_active;
struct pcm *pcm_sco_rx;
struct pcm *pcm_sco_tx;
struct voice_data voice;
int* snd_dev_ref_cnt;
struct listnode usecase_list;
bool speaker_lr_swap;
unsigned int cur_hdmi_channels;
bool ns_in_voice_rec;
void* offload_fx_lib;
int (*offload_fx_start_output)(audio_io_handle_t);
int (*offload_fx_stop_output)(audio_io_handle_t);
#ifdef PREPROCESSING_ENABLED
struct echo_reference_itfe* echo_reference;
// echo_reference_generation indicates if the echo reference used by the output stream is
// in sync with the one known by the audio_device.
// incremented atomically with a memory barrier and audio device mutex locked but WITHOUT
// stream mutex locked: the stream will load it atomically with a barrier and re-read it
// with audio device mutex if needed
volatile int32_t echo_reference_generation;
#endif
pthread_mutex_t lock_inputs; /* see note below on mutex acquisition order */
amplifier_device_t *amp;
};
/*
* NOTE: when multiple mutexes have to be acquired, always take the
* lock_inputs, stream_in, stream_out, then audio_device mutex.
* stream_in mutex must always be before stream_out mutex
* lock_inputs must be held in order to either close the input stream, or prevent closure.
*/
#endif // SAMSUNG_AUDIO_HW_H

428
audio/compress_offload.c Normal file
View File

@@ -0,0 +1,428 @@
/*
* Copyright (C) 2013 The Android Open Source Project
* Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
*
* 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_primary"
/*#define LOG_NDEBUG 0*/
/*#define VERY_VERY_VERBOSE_LOGGING*/
#ifdef VERY_VERY_VERBOSE_LOGGING
#define ALOGVV ALOGV
#else
#define ALOGVV(a...) do { } while(0)
#endif
#define _GNU_SOURCE
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <cutils/log.h>
#include <cutils/str_parms.h>
#include <cutils/sched_policy.h>
#include <system/thread_defs.h>
#include <samsung_audio.h>
#include "audio_hw.h"
#include "sound/compress_params.h"
#define MIXER_CTL_COMPRESS_PLAYBACK_VOLUME "Compress Playback Volume"
/* Prototypes */
void lock_input_stream(struct stream_in *in);
void lock_output_stream(struct stream_out *out);
int disable_snd_device(struct audio_device *adev,
struct audio_usecase *uc_info,
snd_device_t snd_device,
bool update_mixer);
int enable_output_path_l(struct stream_out *out);
int disable_output_path_l(struct stream_out *out);
/* must be called with out->lock locked */
static int send_offload_cmd_l(struct stream_out* out, int command)
{
struct offload_cmd *cmd = (struct offload_cmd *)calloc(1, sizeof(struct offload_cmd));
ALOGVV("%s %d", __func__, command);
cmd->cmd = command;
list_add_tail(&out->offload_cmd_list, &cmd->node);
pthread_cond_signal(&out->offload_cond);
return 0;
}
/* must be called iwth out->lock locked */
void stop_compressed_output_l(struct stream_out *out)
{
out->send_new_metadata = 1;
if (out->compr != NULL) {
compress_stop(out->compr);
while (out->offload_thread_blocked) {
pthread_cond_wait(&out->cond, &out->lock);
}
}
}
static void *offload_thread_loop(void *context)
{
struct stream_out *out = (struct stream_out *) context;
struct listnode *item;
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
set_sched_policy(0, SP_FOREGROUND);
prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0);
ALOGV("%s", __func__);
lock_output_stream(out);
for (;;) {
struct offload_cmd *cmd = NULL;
stream_callback_event_t event;
bool send_callback = false;
ALOGVV("%s offload_cmd_list %d out->offload_state %d",
__func__, list_empty(&out->offload_cmd_list),
out->offload_state);
if (list_empty(&out->offload_cmd_list)) {
ALOGV("%s SLEEPING", __func__);
pthread_cond_wait(&out->offload_cond, &out->lock);
ALOGV("%s RUNNING", __func__);
continue;
}
item = list_head(&out->offload_cmd_list);
cmd = node_to_item(item, struct offload_cmd, node);
list_remove(item);
ALOGVV("%s STATE %d CMD %d out->compr %p",
__func__, out->offload_state, cmd->cmd, out->compr);
if (cmd->cmd == OFFLOAD_CMD_EXIT) {
free(cmd);
break;
}
if (out->compr == NULL) {
ALOGE("%s: Compress handle is NULL", __func__);
pthread_cond_signal(&out->cond);
continue;
}
out->offload_thread_blocked = true;
pthread_mutex_unlock(&out->lock);
send_callback = false;
switch(cmd->cmd) {
case OFFLOAD_CMD_WAIT_FOR_BUFFER:
compress_wait(out->compr, -1);
send_callback = true;
event = STREAM_CBK_EVENT_WRITE_READY;
break;
case OFFLOAD_CMD_PARTIAL_DRAIN:
compress_next_track(out->compr);
compress_partial_drain(out->compr);
send_callback = true;
event = STREAM_CBK_EVENT_DRAIN_READY;
break;
case OFFLOAD_CMD_DRAIN:
compress_drain(out->compr);
send_callback = true;
event = STREAM_CBK_EVENT_DRAIN_READY;
break;
default:
ALOGE("%s unknown command received: %d", __func__, cmd->cmd);
break;
}
lock_output_stream(out);
out->offload_thread_blocked = false;
pthread_cond_signal(&out->cond);
if (send_callback) {
out->offload_callback(event, NULL, out->offload_cookie);
}
free(cmd);
}
pthread_cond_signal(&out->cond);
while (!list_empty(&out->offload_cmd_list)) {
item = list_head(&out->offload_cmd_list);
list_remove(item);
free(node_to_item(item, struct offload_cmd, node));
}
pthread_mutex_unlock(&out->lock);
return NULL;
}
int create_offload_callback_thread(struct stream_out *out)
{
pthread_cond_init(&out->offload_cond, (const pthread_condattr_t *) NULL);
list_init(&out->offload_cmd_list);
pthread_create(&out->offload_thread, (const pthread_attr_t *) NULL,
offload_thread_loop, out);
return 0;
}
int destroy_offload_callback_thread(struct stream_out *out)
{
lock_output_stream(out);
send_offload_cmd_l(out, OFFLOAD_CMD_EXIT);
pthread_mutex_unlock(&out->lock);
pthread_join(out->offload_thread, (void **) NULL);
pthread_cond_destroy(&out->offload_cond);
return 0;
}
int parse_compress_metadata(struct stream_out *out, struct str_parms *parms)
{
int ret = 0;
char value[32];
struct compr_gapless_mdata tmp_mdata;
if (!out || !parms) {
return -EINVAL;
}
ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, value, sizeof(value));
if (ret >= 0) {
tmp_mdata.encoder_delay = atoi(value); /* what is a good limit check? */
} else {
return -EINVAL;
}
ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES, value, sizeof(value));
if (ret >= 0) {
tmp_mdata.encoder_padding = atoi(value);
} else {
return -EINVAL;
}
out->gapless_mdata = tmp_mdata;
out->send_new_metadata = 1;
ALOGV("%s new encoder delay %u and padding %u", __func__,
out->gapless_mdata.encoder_delay, out->gapless_mdata.encoder_padding);
return 0;
}
int stop_output_offload_stream(struct stream_out *out, bool *disable)
{
int ret = 0;
struct audio_device *adev = out->dev;
if (adev->offload_fx_stop_output != NULL) {
adev->offload_fx_stop_output(out->handle);
if (out->offload_state == OFFLOAD_STATE_PAUSED ||
out->offload_state == OFFLOAD_STATE_PAUSED_FLUSHED)
*disable = false;
out->offload_state = OFFLOAD_STATE_IDLE;
}
return ret;
}
int out_set_offload_parameters(struct audio_device *adev, struct audio_usecase *uc_info)
{
int ret = 0;
if (uc_info == NULL) {
ALOGE("%s: Could not find the usecase (%d) in the list",
__func__, USECASE_AUDIO_PLAYBACK);
ret = -1;
}
if (uc_info != NULL && uc_info->out_snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
ALOGV("Out_set_param: spk+headset enabled\n");
uc_info->out_snd_device = SND_DEVICE_OUT_HEADPHONES;
disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER, true);
}
return ret;
}
ssize_t out_write_offload(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
struct stream_out *out = (struct stream_out *)stream;
struct audio_device *adev = out->dev;
ssize_t ret = 0;
ALOGVV("%s: writing buffer (%d bytes) to compress device", __func__, bytes);
if (out->offload_state == OFFLOAD_STATE_PAUSED_FLUSHED) {
ALOGV("start offload write from pause state");
pthread_mutex_lock(&adev->lock);
ret = enable_output_path_l(out);
pthread_mutex_unlock(&adev->lock);
if (ret != 0) {
return ret;
}
}
if (out->send_new_metadata) {
ALOGVV("send new gapless metadata");
compress_set_gapless_metadata(out->compr, &out->gapless_mdata);
out->send_new_metadata = 0;
}
ret = compress_write(out->compr, buffer, bytes);
ALOGVV("%s: writing buffer (%d bytes) to compress device returned %d", __func__, bytes, ret);
if (ret >= 0 && ret < (ssize_t)bytes) {
send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
}
if (out->offload_state != OFFLOAD_STATE_PLAYING) {
compress_start(out->compr);
out->offload_state = OFFLOAD_STATE_PLAYING;
}
pthread_mutex_unlock(&out->lock);
return ret;
}
int out_get_render_offload_position(struct stream_out *out,
uint32_t *dsp_frames)
{
*dsp_frames = 0;
if (dsp_frames != NULL) {
lock_output_stream(out);
if (out->compr != NULL) {
compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
&out->sample_rate);
ALOGVV("%s rendered frames %d sample_rate %d",
__func__, *dsp_frames, out->sample_rate);
}
pthread_mutex_unlock(&out->lock);
return 0;
} else
return -EINVAL;
}
int out_get_presentation_offload_position(struct stream_out *out, uint64_t *frames,
struct timespec *timestamp)
{
int ret = -1;
unsigned long dsp_frames;
if (out->compr != NULL) {
compress_get_tstamp(out->compr, &dsp_frames,
&out->sample_rate);
ALOGVV("%s rendered frames %ld sample_rate %d",
__func__, dsp_frames, out->sample_rate);
*frames = dsp_frames;
ret = 0;
/* this is the best we can do */
clock_gettime(CLOCK_MONOTONIC, timestamp);
}
return ret;
}
int out_pause_offload(struct stream_out *out)
{
int status = -ENOSYS;
lock_output_stream(out);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PLAYING) {
status = compress_pause(out->compr);
out->offload_state = OFFLOAD_STATE_PAUSED;
pthread_mutex_lock(&out->dev->lock);
status = disable_output_path_l(out);
pthread_mutex_unlock(&out->dev->lock);
}
pthread_mutex_unlock(&out->lock);
return status;
}
int out_resume_offload(struct stream_out *out)
{
int status = -ENOSYS;
status = 0;
lock_output_stream(out);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PAUSED) {
pthread_mutex_lock(&out->dev->lock);
enable_output_path_l(out);
pthread_mutex_unlock(&out->dev->lock);
status = compress_resume(out->compr);
out->offload_state = OFFLOAD_STATE_PLAYING;
}
pthread_mutex_unlock(&out->lock);
return status;
}
int out_drain_offload(struct stream_out *out, audio_drain_type_t type)
{
int status = -ENOSYS;
lock_output_stream(out);
if (type == AUDIO_DRAIN_EARLY_NOTIFY)
status = send_offload_cmd_l(out, OFFLOAD_CMD_PARTIAL_DRAIN);
else
status = send_offload_cmd_l(out, OFFLOAD_CMD_DRAIN);
pthread_mutex_unlock(&out->lock);
return status;
}
int out_flush_offload(struct stream_out *out)
{
lock_output_stream(out);
if (out->offload_state == OFFLOAD_STATE_PLAYING) {
ALOGE("out_flush() called in wrong state %d", out->offload_state);
pthread_mutex_unlock(&out->lock);
return -ENOSYS;
}
if (out->offload_state == OFFLOAD_STATE_PAUSED) {
stop_compressed_output_l(out);
out->offload_state = OFFLOAD_STATE_PAUSED_FLUSHED;
}
pthread_mutex_unlock(&out->lock);
return 0;
}
int out_set_offload_volume(float left, float right)
{
int offload_volume[2];//For stereo
struct mixer_ctl *ctl;
struct mixer *mixer = NULL;
offload_volume[0] = (int)(left * COMPRESS_PLAYBACK_VOLUME_MAX);
offload_volume[1] = (int)(right * COMPRESS_PLAYBACK_VOLUME_MAX);
mixer = mixer_open(MIXER_CARD);
if (!mixer) {
ALOGE("%s unable to open the mixer for card %d, aborting.",
__func__, MIXER_CARD);
return -EINVAL;
}
ctl = mixer_get_ctl_by_name(mixer, MIXER_CTL_COMPRESS_PLAYBACK_VOLUME);
if (!ctl) {
ALOGE("%s: Could not get ctl for mixer cmd - %s",
__func__, MIXER_CTL_COMPRESS_PLAYBACK_VOLUME);
mixer_close(mixer);
return -EINVAL;
}
ALOGV("out_set_volume set offload volume (%f, %f)", left, right);
mixer_ctl_set_array(ctl, offload_volume,
sizeof(offload_volume)/sizeof(offload_volume[0]));
mixer_close(mixer);
return 0;
}

52
audio/compress_offload.h Normal file
View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2013 The Android Open Source Project
* Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
*
* 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 COMPRESS_OFFLOAD_H
#define COMPRESS_OFFLOAD_H
void stop_compressed_output_l(struct stream_out *out);
int create_offload_callback_thread(struct stream_out *out);
int destroy_offload_callback_thread(struct stream_out *out);
int parse_compress_metadata(struct stream_out *out, struct str_parms *parms);
int stop_output_offload_stream(struct stream_out *out, bool *disable);
int out_set_offload_parameters(struct audio_device *adev, struct audio_usecase *uc_info);
ssize_t out_write_offload(struct audio_stream_out *stream, const void *buffer,
size_t bytes);
int out_get_render_offload_position(struct stream_out *out,
uint32_t *dsp_frames);
int out_get_presentation_offload_position(struct stream_out *out, uint64_t *frames,
struct timespec *timestamp);
int out_pause_offload(struct stream_out *out);
int out_resume_offload(struct stream_out *out);
int out_drain_offload(struct stream_out *out, audio_drain_type_t type);
int out_flush_offload(struct stream_out *out);
int out_set_offload_volume(float left, float right);
#endif // COMPRESS_OFFLOAD_H

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
*
* 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.
*/
/*
* NOTICE
*
* This must be kept in sync with the kernel API, for exmaple
* "es705-routes.h" for the Galaxy Note 5 (N920T) with its ES804 IC.
*/
#define SYSFS_PATH_POWERCTRL "/sys/class/earsmart/control/power_control_set"
#define SYSFS_PATH_PRESET "/sys/class/earsmart/control/route_value"
#define SYSFS_PATH_VEQ "/sys/class/earsmart/control/veq_control_set"
#define SYSFS_PATH_EXTRAVOLUME "/sys/class/earsmart/control/extra_volume"
#define Call_HS_NB 0 /* Call, Headset, Narrow Band */
#define Call_FT_NB 1 /* Call, Far Talk, Narrow Band */
#define Call_CT_NB 2 /* Call, Close Talk, Narrow Band */
#define Call_FT_NB_NR_OFF 3 /* Call, Far Talk, NB, NR off */
#define Call_CT_NB_NR_OFF 4 /* Call, Close Talk, NB, NR off */
#define Call_BT_NB 10 /* Call, BT, NB */
#define Call_TTY_VCO 11 /* Call, TTY HCO NB */
#define Call_TTY_HCO 12 /* Call, TTY VCO NB */
#define Call_TTY_FULL 13 /* Call, TTY FULL NB */
#define Call_FT_EVS 14 /* Call, Far Talk, EVS */
#define Call_CT_EVS 15 /* Call, Close Talk, EVS */
#define LOOPBACK_CT 17 /* Loopback, Close Talk */
#define LOOPBACK_FT 18 /* Loopback, Far Talk */
#define LOOPBACK_HS 19 /* Loopback, Headset */
#define Call_BT_WB 20 /* Call, BT, WB */
#define Call_HS_WB 21 /* Call, Headset, Wide Band */
#define Call_FT_WB 22 /* Call, Far Talk, Wide Band */
#define Call_CT_WB 23 /* Call, Close Talk, Wide Band */
#define Call_FT_WB_NR_OFF 24 /* Call, Far Talk, WB, NR off */
#define Call_CT_WB_NR_OFF 25 /* Call, Close Talk, WB, NR off */
#define AUDIENCE_SLEEP 40 /* Route none, Audience Sleep State */

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2017 The LineageOS 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.
*/
#include <telephony/ril.h>
#ifndef SAMSUNG_AUDIO_H
#define SAMSUNG_AUDIO_H
/*
* Sound card specific defines.
*
* This is an example configuration for a WolfsonMicro WM1814 sound card.
* Codec: Vegas
*
* If you driver does not support one of the devices, the id should not be
* defined.
*/
#define MIXER_CARD 0
#define SOUND_CARD 0
/* Playback */
#define SOUND_DEEP_BUFFER_DEVICE 3
#define SOUND_PLAYBACK_DEVICE 4
#define SOUND_PLAYBACK_SCO_DEVICE 2
/* Capture */
#define SOUND_CAPTURE_DEVICE 0
#define SOUND_CAPTURE_SCO_DEVICE 2
/* Voice calls */
#define SOUND_PLAYBACK_VOICE_DEVICE 1
#define SOUND_CAPTURE_VOICE_DEVICE 1
/* Wideband AMR callback */
#ifndef RIL_UNSOL_SNDMGR_WB_AMR_REPORT
#ifdef RIL_UNSOL_WB_AMR_STATE
#define RIL_UNSOL_SNDMGR_WB_AMR_REPORT RIL_UNSOL_WB_AMR_STATE
#else
#define RIL_UNSOL_SNDMGR_WB_AMR_REPORT 0
#endif
#endif
/* Unusupported
#define SOUND_CAPTURE_LOOPBACK_AEC_DEVICE 1
#define SOUND_CAPTURE_HOTWORD_DEVICE 0
*/
/*
* If the device has stereo speakers and the speakers are arranged on
* different sides of the device you can activate this feature by
* setting it to 1.
*/
#define SWAP_SPEAKER_ON_SCREEN_ROTATION 0
/*
* You can that this to 1 if your kernel supports irq affinity for
* fast mode. See /proc/asound/irq_affinity
*/
#define SUPPORTS_IRQ_AFFINITY 0
/*
* The Wolfson/Cirruslogic chips need to shutdown the DAPM route completely
* to be able to load a new firmware. Some of these chips need a delay after
* shutodown to full poweroff the DSPs.
*
* A good value to start with is 10ms:
*
* #define DSP_POWEROFF_DELAY 10 * 1000
*/
/* #define DSP_POWEROFF_DELAY 0 */
/*
* Some device variants (often T-Mobile) have a separate voice processing IC
* (Audience EarSmart xxx).
* This hooks into the voice call session and enables, configures and disables
* this extra firmware so RX/TX streams can be routed by the driver.
*/
/* #define AUDIENCE_EARSMART_IC */
#endif // SAMSUNG_AUDIO_H

View File

@@ -0,0 +1,160 @@
<mixer>
<!-- ########## Initial mixer settings ########## -->
<!-- Disable Speaker -->
<ctl name="SPK Switch" value="0" />
<!--
#######################################################
### AUDIO ROUTING
#######################################################
-->
<path name="none">
<!-- Empty path -->
</path>
<!-- ########## Playback ########## -->
<path name="earpiece">
<!-- Empty path -->
</path>
<path name="speaker">
<!-- Empty path -->
</path>
<path name="headphones">
<!-- Empty path -->
</path>
<path name="speaker-and-headphones">
<!-- Empty path -->
</path>
<path name="voice-earpiece">
<!-- Empty path -->
</path>
<path name="voice-earpiece-wb">
<!-- Empty path -->
</path>
<path name="voice-speaker">
<!-- Empty path -->
</path>
<path name="voice-speaker-wb">
<!-- Empty path -->
</path>
<path name="voice-headphones">
<!-- Empty path -->
</path>
<path name="voice-headphones-wb">
<!-- Empty path -->
</path>
<path name="voice-bt-sco-headset">
<!-- Empty path -->
</path>
<path name="voice-bt-sco-headset-wb">
<!-- Empty path -->
</path>
<path name="hdmi">
<!-- Empty path -->
</path>
<path name="speaker-and-hdmi">
<!-- Empty path -->
</path>
<path name="bt-sco-headset">
<!-- Empty path -->
</path>
<!-- ########## Capture ########## -->
<path name="earpiece-mic">
<!-- Empty path -->
</path>
<path name="speaker-mic">
<!-- Empty path -->
</path>
<path name="voice-mic">
<!-- Configure builtin mic only -->
<!-- Empty path -->
</path>
<!-- Two mic -->
<path name="voice-earpiece-mic">
<!-- Should be main mic and back mic -->
<!-- Capture channel set to main mic -->
<!-- Empty path -->
</path>
<path name="voice-earpiece-mic-wb">
<!-- Should be main mic and back mic -->
<!-- Capture channel set to main mic -->
<!-- Empty path -->
</path>
<path name="voice-speaker-mic">
<!-- Should be main mic and back mic -->
<!-- Capture channel set to back mic -->
<!-- Empty path -->
</path>
<path name="voice-speaker-mic-wb">
<!-- Should be main mic and back mic -->
<!-- Capture channel set to back mic -->
<!-- Empty path -->
</path>
<path name="voice-headset-mic">
<!-- Empty path -->
</path>
<path name="voice-headset-mic-wb">
<!-- Empty path -->
</path>
<path name="voice-bt-sco-mic">
<!-- Empty path -->
</path>
<path name="voice-bt-sco-mic-wb">
<!-- Empty path -->
</path>
<path name="hdmi-mic">
<!-- Empty path -->
</path>
<path name="bt-sco-mic">
<!-- Empty path -->
</path>
<path name="voice-rec-headset-mic">
<!-- Empty path -->
</path>
<path name="voice-rec-mic">
<!-- Empty path -->
</path>
<path name="camcorder-mic">
<!-- Should be builtin and back mic -->
<!-- Empty path -->
</path>
<path name="loopback-aec">
<!-- Empty path -->
</path>
</mixer>

276
audio/ril_interface.c Normal file
View File

@@ -0,0 +1,276 @@
/*
* Copyright (C) 2013 The CyanogenMod Project
* Copyright (C) 2017 Andreas Schneider <asn@cryptomilk.org>
*
* 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_ril"
/*#define LOG_NDEBUG 0*/
#include <errno.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <utils/Log.h>
#include <cutils/properties.h>
#include "ril_interface.h"
#define VOLUME_STEPS_DEFAULT "5"
#define VOLUME_STEPS_PROPERTY "ro.config.vc_call_vol_steps"
/* Audio WB AMR callback */
/*
* TODO:
* struct audio_device {
* HRilClient client;
* void *data
* }
* static struct audio_device _audio_devices[64];
*
* When registering a call back we should store it in the array and when
* the callback is triggered find the data pointer based on the client
* passed in.
*/
static ril_wb_amr_callback _wb_amr_callback;
static void *_wb_amr_data = NULL;
/* This is the callback function that the RIL uses to
set the wideband AMR state */
static int ril_internal_wb_amr_callback(HRilClient client __unused,
const void *data,
size_t datalen)
{
int wb_amr_type = 0;
if (_wb_amr_data == NULL || _wb_amr_callback == NULL) {
return -1;
}
if (datalen != 1) {
return -1;
}
wb_amr_type = *((int *)data);
_wb_amr_callback(_wb_amr_data, wb_amr_type);
return 0;
}
static int ril_connect_if_required(struct ril_handle *ril)
{
int ok;
int rc;
if (ril->client == NULL) {
ALOGE("ril->client is NULL");
return -1;
}
ok = isConnected_RILD(ril->client);
if (ok) {
return 0;
}
rc = Connect_RILD(ril->client);
if (rc != RIL_CLIENT_ERR_SUCCESS) {
ALOGE("FATAL: Failed to connect to RILD: %s",
strerror(errno));
return -1;
}
return 0;
}
int ril_open(struct ril_handle *ril)
{
char property[PROPERTY_VALUE_MAX];
if (ril == NULL) {
return -1;
}
ril->client = OpenClient_RILD();
if (ril->client == NULL) {
ALOGE("OpenClient_RILD() failed");
return -1;
}
property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT);
ril->volume_steps_max = atoi(property);
/*
* This catches the case where VOLUME_STEPS_PROPERTY does not contain
* an integer
*/
if (ril->volume_steps_max == 0) {
ril->volume_steps_max = atoi(VOLUME_STEPS_DEFAULT);
}
return 0;
}
int ril_close(struct ril_handle *ril)
{
int rc;
if (ril == NULL || ril->client == NULL) {
return -1;
}
rc = Disconnect_RILD(ril->client);
if (rc != RIL_CLIENT_ERR_SUCCESS) {
ALOGE("Disconnect_RILD failed");
return -1;
}
rc = CloseClient_RILD(ril->client);
if (rc != RIL_CLIENT_ERR_SUCCESS) {
ALOGE("CloseClient_RILD() failed");
return -1;
}
ril->client = NULL;
return 0;
}
int ril_set_wb_amr_callback(struct ril_handle *ril,
ril_wb_amr_callback fn,
void *data)
{
int rc;
if (fn == NULL || data == NULL) {
return -1;
}
_wb_amr_callback = fn;
_wb_amr_data = data;
ALOGV("%s: RegisterUnsolicitedHandler(%d, %p)",
__func__,
RIL_UNSOL_SNDMGR_WB_AMR_REPORT,
ril_set_wb_amr_callback);
/* register the wideband AMR callback */
rc = RegisterUnsolicitedHandler(ril->client,
RIL_UNSOL_SNDMGR_WB_AMR_REPORT,
(RilOnUnsolicited)ril_internal_wb_amr_callback);
if (rc != RIL_CLIENT_ERR_SUCCESS) {
ALOGE("%s: Failed to register WB_AMR callback", __func__);
ril_close(ril);
return -1;
}
return 0;
}
int ril_set_call_volume(struct ril_handle *ril,
enum _SoundType sound_type,
float volume)
{
int rc;
rc = ril_connect_if_required(ril);
if (rc != 0) {
ALOGE("%s: Failed to connect to RIL (%s)", __func__, strerror(rc));
return 0;
}
rc = SetCallVolume(ril->client,
sound_type,
(int)(volume * ril->volume_steps_max));
if (rc != 0) {
ALOGE("%s: SetCallVolume() failed, rc=%d", __func__, rc);
}
return rc;
}
int ril_set_call_audio_path(struct ril_handle *ril, enum _AudioPath path)
{
int rc;
rc = ril_connect_if_required(ril);
if (rc != 0) {
ALOGE("%s: Failed to connect to RIL (%s)", __func__, strerror(rc));
return 0;
}
rc = SetCallAudioPath(ril->client, path);
if (rc != 0) {
ALOGE("%s: SetCallAudioPath() failed, rc=%d", __func__, rc);
}
return rc;
}
int ril_set_call_clock_sync(struct ril_handle *ril,
enum _SoundClockCondition condition)
{
int rc;
rc = ril_connect_if_required(ril);
if (rc != 0) {
ALOGE("%s: Failed to connect to RIL (%s)", __func__, strerror(rc));
return 0;
}
rc = SetCallClockSync(ril->client, condition);
if (rc != 0) {
ALOGE("%s: SetCallClockSync() failed, rc=%d", __func__, rc);
}
return rc;
}
int ril_set_mute(struct ril_handle *ril, enum _MuteCondition condition)
{
int rc;
rc = ril_connect_if_required(ril);
if (rc != 0) {
ALOGE("%s: Failed to connect to RIL (%s)", __func__, strerror(rc));
return 0;
}
rc = SetMute(ril->client, condition);
if (rc != 0) {
ALOGE("%s: SetMute() failed, rc=%d", __func__, rc);
}
return rc;
}
int ril_set_two_mic_control(struct ril_handle *ril,
enum __TwoMicSolDevice device,
enum __TwoMicSolReport report)
{
int rc;
rc = ril_connect_if_required(ril);
if (rc != 0) {
ALOGE("%s: Failed to connect to RIL (%s)", __func__, strerror(rc));
return 0;
}
rc = SetTwoMicControl(ril->client, device, report);
if (rc != 0) {
ALOGE("%s: SetTwoMicControl() failed, rc=%d", __func__, rc);
}
return rc;
}

65
audio/ril_interface.h Normal file
View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.
*/
#ifndef RIL_INTERFACE_H
#define RIL_INTERFACE_H
#include <samsung_audio.h>
#include <secril-client.h>
/**
* @brief The callback to change to wideband which should
* be implemented by the audio HAL.
*
* @param[in] data User data poiner
* @param[in] wb_amr_type 0 = disable WB, 1 = enable WB,
* 2 = WB (and probably NS)
*/
typedef void (*ril_wb_amr_callback)(void *data, int wb_amr_type);
struct ril_handle
{
void *client;
int volume_steps_max;
};
/* Function prototypes */
int ril_open(struct ril_handle *ril);
int ril_close(struct ril_handle *ril);
int ril_set_call_volume(struct ril_handle *ril,
enum _SoundType sound_type,
float volume);
int ril_set_call_audio_path(struct ril_handle *ril,
enum _AudioPath path);
int ril_set_call_clock_sync(struct ril_handle *ril,
enum _SoundClockCondition condition);
int ril_set_mute(struct ril_handle *ril, enum _MuteCondition condition);
int ril_set_two_mic_control(struct ril_handle *ril,
enum __TwoMicSolDevice device,
enum __TwoMicSolReport report);
int ril_set_wb_amr_callback(struct ril_handle *ril,
ril_wb_amr_callback fn,
void *data);
#endif

470
audio/voice.c Normal file
View File

@@ -0,0 +1,470 @@
/*
* Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
*
* 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_voice"
#define LOG_NDEBUG 0
/*#define VERY_VERY_VERBOSE_LOGGING*/
#ifdef VERY_VERY_VERBOSE_LOGGING
#define ALOGVV ALOGV
#else
#define ALOGVV(a...) do { } while(0)
#endif
#include <stdlib.h>
#include <pthread.h>
#include <cutils/log.h>
#include <cutils/properties.h>
#include <samsung_audio.h>
#include "audio_hw.h"
#include "voice.h"
#ifdef AUDIENCE_EARSMART_IC
#include "audience.h"
#endif
static struct pcm_config pcm_config_voicecall = {
.channels = 2,
.rate = 8000,
.period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY,
.period_count = CAPTURE_PERIOD_COUNT_LOW_LATENCY,
.format = PCM_FORMAT_S16_LE,
};
static struct pcm_config pcm_config_voicecall_wideband = {
.channels = 2,
.rate = 16000,
.period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY,
.period_count = CAPTURE_PERIOD_COUNT_LOW_LATENCY,
.format = PCM_FORMAT_S16_LE,
};
struct pcm_config pcm_config_voice_sco = {
.channels = 1,
.rate = SCO_DEFAULT_SAMPLING_RATE,
.period_size = SCO_PERIOD_SIZE,
.period_count = SCO_PERIOD_COUNT,
.format = PCM_FORMAT_S16_LE,
};
struct pcm_config pcm_config_voice_sco_wb = {
.channels = 1,
.rate = SCO_WB_SAMPLING_RATE,
.period_size = SCO_PERIOD_SIZE,
.period_count = SCO_PERIOD_COUNT,
.format = PCM_FORMAT_S16_LE,
};
/* Prototypes */
int start_voice_call(struct audio_device *adev);
int stop_voice_call(struct audio_device *adev);
void set_voice_session_audio_path(struct voice_session *session)
{
enum _AudioPath device_type;
int rc;
switch(session->out_device) {
case AUDIO_DEVICE_OUT_SPEAKER:
device_type = SOUND_AUDIO_PATH_SPEAKER;
break;
case AUDIO_DEVICE_OUT_EARPIECE:
device_type = SOUND_AUDIO_PATH_EARPIECE;
break;
case AUDIO_DEVICE_OUT_WIRED_HEADSET:
device_type = SOUND_AUDIO_PATH_HEADSET;
break;
case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
device_type = SOUND_AUDIO_PATH_HEADPHONE;
break;
case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
device_type = SOUND_AUDIO_PATH_BLUETOOTH;
break;
default:
/* if output device isn't supported, use earpiece by default */
device_type = SOUND_AUDIO_PATH_EARPIECE;
break;
}
ALOGV("%s: ril_set_call_audio_path(%d)", __func__, device_type);
rc = ril_set_call_audio_path(&session->ril, device_type);
ALOGE_IF(rc != 0, "Failed to set audio path: (%d)", rc);
}
/*
* This decides based on the output device, if we enable
* two mic control
*/
void prepare_voice_session(struct voice_session *session,
audio_devices_t active_out_devices)
{
ALOGV("%s: active_out_devices: 0x%x", __func__, active_out_devices);
session->out_device = active_out_devices;
switch (session->out_device) {
case AUDIO_DEVICE_OUT_EARPIECE:
case AUDIO_DEVICE_OUT_SPEAKER:
session->two_mic_control = true;
break;
default:
session->two_mic_control = false;
break;
}
if (session->two_mic_disabled) {
session->two_mic_control = false;
}
}
/*
* This must be called with the hw device mutex locked, OK to hold other
* mutexes.
*/
void stop_voice_session_bt_sco(struct audio_device *adev) {
ALOGV("%s: Closing SCO PCMs", __func__);
if (adev->pcm_sco_rx != NULL) {
pcm_stop(adev->pcm_sco_rx);
pcm_close(adev->pcm_sco_rx);
adev->pcm_sco_rx = NULL;
}
if (adev->pcm_sco_tx != NULL) {
pcm_stop(adev->pcm_sco_tx);
pcm_close(adev->pcm_sco_tx);
adev->pcm_sco_tx = NULL;
}
/* audio codecs like wm5201 need open modem pcm while using bt sco */
if (adev->mode != AUDIO_MODE_IN_CALL)
stop_voice_session(adev->voice.session);
}
/* must be called with the hw device mutex locked, OK to hold other mutexes */
void start_voice_session_bt_sco(struct audio_device *adev)
{
struct pcm_config *voice_sco_config;
if (adev->pcm_sco_rx != NULL || adev->pcm_sco_tx != NULL) {
ALOGW("%s: SCO PCMs already open!\n", __func__);
return;
}
ALOGV("%s: Opening SCO PCMs", __func__);
if (adev->voice.bluetooth_wb) {
ALOGV("%s: pcm_config wideband", __func__);
voice_sco_config = &pcm_config_voice_sco_wb;
} else {
ALOGV("%s: pcm_config narrowband", __func__);
voice_sco_config = &pcm_config_voice_sco;
}
adev->pcm_sco_rx = pcm_open(SOUND_CARD,
SOUND_PLAYBACK_SCO_DEVICE,
PCM_OUT|PCM_MONOTONIC,
voice_sco_config);
if (adev->pcm_sco_rx != NULL && !pcm_is_ready(adev->pcm_sco_rx)) {
ALOGE("%s: cannot open PCM SCO RX stream: %s",
__func__, pcm_get_error(adev->pcm_sco_rx));
goto err_sco_rx;
}
adev->pcm_sco_tx = pcm_open(SOUND_CARD,
SOUND_CAPTURE_SCO_DEVICE,
PCM_IN|PCM_MONOTONIC,
voice_sco_config);
if (adev->pcm_sco_tx && !pcm_is_ready(adev->pcm_sco_tx)) {
ALOGE("%s: cannot open PCM SCO TX stream: %s",
__func__, pcm_get_error(adev->pcm_sco_tx));
goto err_sco_tx;
}
pcm_start(adev->pcm_sco_rx);
pcm_start(adev->pcm_sco_tx);
/* audio codecs like wm5201 need open modem pcm while using bt sco */
if (adev->mode != AUDIO_MODE_IN_CALL)
start_voice_session(adev->voice.session);
return;
err_sco_tx:
pcm_close(adev->pcm_sco_tx);
adev->pcm_sco_tx = NULL;
err_sco_rx:
pcm_close(adev->pcm_sco_rx);
adev->pcm_sco_rx = NULL;
}
/*
* This function must be called with hw device mutex locked, OK to hold other
* mutexes
*/
int start_voice_session(struct voice_session *session)
{
struct pcm_config *voice_config;
if (session->pcm_voice_rx != NULL || session->pcm_voice_tx != NULL) {
ALOGW("%s: Voice PCMs already open!\n", __func__);
return 0;
}
ALOGV("%s: Opening voice PCMs", __func__);
/* TODO: Handle wb_amr=2 */
if (session->wb_amr_type >= 1) {
ALOGV("%s: pcm_config wideband", __func__);
voice_config = &pcm_config_voicecall_wideband;
} else {
ALOGV("%s: pcm_config narrowband", __func__);
voice_config = &pcm_config_voicecall;
}
/* Open modem PCM channels */
session->pcm_voice_rx = pcm_open(SOUND_CARD,
SOUND_PLAYBACK_VOICE_DEVICE,
PCM_OUT|PCM_MONOTONIC,
voice_config);
if (session->pcm_voice_rx != NULL && !pcm_is_ready(session->pcm_voice_rx)) {
ALOGE("%s: cannot open PCM voice RX stream: %s",
__func__,
pcm_get_error(session->pcm_voice_rx));
pcm_close(session->pcm_voice_tx);
session->pcm_voice_tx = NULL;
return -ENOMEM;
}
session->pcm_voice_tx = pcm_open(SOUND_CARD,
SOUND_CAPTURE_VOICE_DEVICE,
PCM_IN|PCM_MONOTONIC,
voice_config);
if (session->pcm_voice_tx != NULL && !pcm_is_ready(session->pcm_voice_tx)) {
ALOGE("%s: cannot open PCM voice TX stream: %s",
__func__,
pcm_get_error(session->pcm_voice_tx));
pcm_close(session->pcm_voice_rx);
session->pcm_voice_rx = NULL;
return -ENOMEM;
}
pcm_start(session->pcm_voice_rx);
pcm_start(session->pcm_voice_tx);
#ifdef AUDIENCE_EARSMART_IC
ALOGV("%s: Enabling Audience IC", __func__);
es_start_voice_session(session);
#endif
if (session->two_mic_control) {
ALOGV("%s: enabling two mic control", __func__);
ril_set_two_mic_control(&session->ril, AUDIENCE, TWO_MIC_SOLUTION_ON);
} else {
ALOGV("%s: disabling two mic control", __func__);
ril_set_two_mic_control(&session->ril, AUDIENCE, TWO_MIC_SOLUTION_OFF);
}
return 0;
}
/*
* This function must be called with hw device mutex locked, OK to hold other
* mutexes
*/
void stop_voice_session(struct voice_session *session)
{
int status = 0;
ril_set_call_clock_sync(&session->ril, SOUND_CLOCK_STOP);
ALOGV("%s: Closing active PCMs", __func__);
if (session->pcm_voice_rx != NULL) {
pcm_stop(session->pcm_voice_rx);
pcm_close(session->pcm_voice_rx);
session->pcm_voice_rx = NULL;
status++;
}
if (session->pcm_voice_tx != NULL) {
pcm_stop(session->pcm_voice_tx);
pcm_close(session->pcm_voice_tx);
session->pcm_voice_tx = NULL;
status++;
}
#ifdef AUDIENCE_EARSMART_IC
ALOGV("%s: Disabling Audience IC", __func__);
es_stop_voice_session();
#endif
session->out_device = AUDIO_DEVICE_NONE;
ALOGV("%s: Successfully closed %d active PCMs", __func__, status);
}
void set_voice_session_volume(struct voice_session *session, float volume)
{
enum _SoundType sound_type;
switch (session->out_device) {
case AUDIO_DEVICE_OUT_EARPIECE:
sound_type = SOUND_TYPE_VOICE;
break;
case AUDIO_DEVICE_OUT_SPEAKER:
sound_type = SOUND_TYPE_SPEAKER;
break;
case AUDIO_DEVICE_OUT_WIRED_HEADSET:
case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
sound_type = SOUND_TYPE_HEADSET;
break;
case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
sound_type = SOUND_TYPE_BTVOICE;
break;
default:
sound_type = SOUND_TYPE_VOICE;
}
ril_set_call_volume(&session->ril, sound_type, volume);
}
void set_voice_session_mic_mute(struct voice_session *session, bool state)
{
enum _MuteCondition mute_condition = state ? TX_MUTE : TX_UNMUTE;
ril_set_mute(&session->ril, mute_condition);
}
bool voice_session_uses_twomic(struct voice_session *session)
{
if (session->two_mic_disabled) {
return false;
}
return session->two_mic_control;
}
bool voice_session_uses_wideband(struct voice_session *session)
{
if (session->out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
return session->vdata->bluetooth_wb;
}
return session->wb_amr_type >= 1;
}
static void voice_session_wb_amr_callback(void *data, int wb_amr_type)
{
struct audio_device *adev = (struct audio_device *)data;
struct voice_session *session =
(struct voice_session *)adev->voice.session;
pthread_mutex_lock(&adev->lock);
if (session->wb_amr_type != wb_amr_type) {
session->wb_amr_type = wb_amr_type;
/* reopen the modem PCMs at the new rate */
if (adev->voice.in_call) {
ALOGV("%s: %s wide band voice call (WB_AMR=%d)",
__func__,
wb_amr_type > 0 ? "Enable" : "Disable",
wb_amr_type);
/* TODO Handle wb_amr_type=2 */
/*
* We need stop the PCM and start with the
* wide band pcm_config.
*/
stop_voice_call(adev);
start_voice_call(adev);
}
}
pthread_mutex_unlock(&adev->lock);
}
struct voice_session *voice_session_init(struct audio_device *adev)
{
char voice_config[PROPERTY_VALUE_MAX];
struct voice_session *session;
int ret;
session = calloc(1, sizeof(struct voice_session));
if (session == NULL) {
return NULL;
}
/* Two mic control */
ret = property_get_bool("ro.vendor.audio_hal.disable_two_mic", false);
if (ret > 0) {
session->two_mic_disabled = true;
}
/* Do this as the last step so we do not have to close it on error */
ret = ril_open(&session->ril);
if (ret != 0) {
free(session);
return NULL;
}
ret = property_get("ro.vendor.audio_hal.force_voice_config", voice_config, "");
if (ret > 0) {
if ((strncmp(voice_config, "narrow", 6)) == 0)
session->wb_amr_type = 0;
else if ((strncmp(voice_config, "wide", 4)) == 0)
session->wb_amr_type = 1;
ALOGV("%s: Forcing voice config: %s", __func__, voice_config);
} else {
if (RIL_UNSOL_SNDMGR_WB_AMR_REPORT > 0) {
/* register callback for wideband AMR setting */
ret = ril_set_wb_amr_callback(&session->ril,
voice_session_wb_amr_callback,
(void *)adev);
if (ret != 0) {
ALOGE("%s: Failed to register WB_AMR callback", __func__);
free(session);
return NULL;
}
ALOGV("%s: Registered WB_AMR callback", __func__);
} else {
ALOGV("%s: WB_AMR callback not supported", __func__);
}
}
session->vdata = &adev->voice;
return session;
}
void voice_session_deinit(struct voice_session *session)
{
ril_close(&session->ril);
free(session);
}

56
audio/voice.h Normal file
View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
*
* 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 VOICE_CALL_H
#define VOICE_CALL_H
#include "ril_interface.h"
struct voice_session {
struct ril_handle ril;
struct pcm *pcm_voice_rx;
struct pcm *pcm_voice_tx;
int wb_amr_type;
bool two_mic_control;
bool two_mic_disabled;
/* from uc_info */
audio_devices_t out_device;
/* parent container */
struct voice_data *vdata;
};
void prepare_voice_session(struct voice_session *session,
audio_devices_t active_out_devices);
int start_voice_session(struct voice_session *session);
void stop_voice_session(struct voice_session *session);
void set_voice_session_volume(struct voice_session *session, float volume);
void set_voice_session_audio_path(struct voice_session *session);
void set_voice_session_mic_mute(struct voice_session *session, bool state);
void start_voice_session_bt_sco(struct audio_device *adev);
void stop_voice_session_bt_sco(struct audio_device *adev);
bool voice_session_uses_twomic(struct voice_session *session);
bool voice_session_uses_wideband(struct voice_session *session);
struct voice_session *voice_session_init(struct audio_device *adev);
void voice_session_deinit(struct voice_session *s);
#endif /* VOICE_CALL_H */

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dolby_enable_title">Включи Dolby Atmos</string>
<string name="dolby_top_intro_summary">възпроизвеждане</string>
<string name="dolby_profile_auto">Авт.</string>
<string name="dolby_profile_game">Игра</string>
<string name="dolby_profile_game_1">Игра 1</string>
<string name="dolby_profile_game_2">Игра 2</string>
<string name="dolby_profile_movie">Филм</string>
<string name="dolby_profile_music">Музика</string>
<string name="dolby_profile_off">Без профил</string>
<string name="dolby_profile_spacial_audio">Специално аудио</string>
<string name="dolby_profile_voice">Глас</string>
</resources>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dolby_enable_title">Activar Dolby Atmos</string>
<string name="dolby_top_intro_summary">Experimenta un sonido innovador para la reproducción de medios que fluye por encima de ti y a tu alrededor</string>
<string name="dolby_profile_auto">Automático</string>
<string name="dolby_profile_game">Juego</string>
<string name="dolby_profile_game_1">Juego 1</string>
<string name="dolby_profile_game_2">Juego 2</string>
<string name="dolby_profile_movie">Cine</string>
<string name="dolby_profile_music">Música</string>
<string name="dolby_profile_off">Sin perfil</string>
<string name="dolby_profile_spacial_audio">Audio espacial</string>
<string name="dolby_profile_voice">Voz</string>
</resources>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dolby_enable_title">فعال کردن Dolby Atmos</string>
<string name="dolby_top_intro_summary">تجربه‌ی صدای پیشرفته برای پخش رسانه‌ای که بالای سر و اطرافتان جریان دارد.</string>
<string name="dolby_profile_auto">خودکار</string>
<string name="dolby_profile_game">بازی</string>
<string name="dolby_profile_game_1">بازی 1</string>
<string name="dolby_profile_game_2">بازی 2</string>
<string name="dolby_profile_movie">فیلم</string>
<string name="dolby_profile_music">موسیقی</string>
<string name="dolby_profile_off">بدون نمایه</string>
<string name="dolby_profile_spacial_audio">صدای فراگیر</string>
<string name="dolby_profile_voice">گفتار</string>
</resources>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dolby_enable_title">Cumasaigh Dolby Atmos</string>
<string name="dolby_top_intro_summary">Taithí fuaime cinn le haghaidh athsheinm meáin a shreabhann thuas agus timpeall ort</string>
<string name="dolby_profile_auto">Uath</string>
<string name="dolby_profile_game">Cluiche</string>
<string name="dolby_profile_game_1">Cluiche 1</string>
<string name="dolby_profile_game_2">Cluiche 2</string>
<string name="dolby_profile_movie">Scannán</string>
<string name="dolby_profile_music">Ceol</string>
<string name="dolby_profile_off">Gan próifíl</string>
<string name="dolby_profile_spacial_audio">Fuaim spásúil</string>
<string name="dolby_profile_voice">Guth</string>
</resources>

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dolby_enable_title">돌비 애트모스 사용</string>
<string name="dolby_top_intro_summary">사용자 주변을 타고 흐르는 듯한 강력하고 생동감 있는 오디오 경험 제공</string>
<string name="dolby_profile_auto">자동</string>
<string name="dolby_profile_game">게임</string>
<string name="dolby_profile_game_1">게임 1</string>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dolby_enable_title">Ativar Dolby Atmos</string>
<string name="dolby_enable_title">Habilitar Dolby Atmos</string>
<string name="dolby_top_intro_summary">Experimente uma mudança dramática no áudio para reprodução de mídia que flui acima e ao seu redor</string>
<string name="dolby_profile_auto">Automático</string>
<string name="dolby_profile_game">Jogo</string>

View File

@@ -1,14 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dolby_enable_title">Aktivera Dolby Atmos</string>
<string name="dolby_top_intro_summary">Upplev banbrytande ljud för mediauppspelning som flödar över och runt dig</string>
<string name="dolby_profile_auto">Auto</string>
<string name="dolby_profile_game">Spel</string>
<string name="dolby_profile_game_1">Spel 1</string>
<string name="dolby_profile_game_2">Spel 2</string>
<string name="dolby_profile_movie">Film</string>
<string name="dolby_profile_music">Musik</string>
<string name="dolby_profile_off">Ingen profil</string>
<string name="dolby_profile_spacial_audio">Rymligt ljud</string>
<string name="dolby_profile_voice">Röst</string>
</resources>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dolby_enable_title">டால்பி அட்மாஸை இயக்குக</string>
<string name="dolby_top_intro_summary">உங்களைச் சுற்றிலும் பாயும் ஊடக இயக்கத்திற்கான திருப்புமுனை ஒலியைப் பட்டறிக</string>
<string name="dolby_profile_auto">தன்னியக்கம்</string>
<string name="dolby_profile_game">ஆட்டம்</string>
<string name="dolby_profile_game_1">ஆட்டம் 1</string>
<string name="dolby_profile_game_2">ஆட்டம் 2</string>
<string name="dolby_profile_movie">திரைப்படம்</string>
<string name="dolby_profile_music">இசை</string>
<string name="dolby_profile_off">தனியமைப்பு இல்லை</string>
<string name="dolby_profile_spacial_audio">இடஞ்சார்ந்த ஒலி</string>
<string name="dolby_profile_voice">குரல்</string>
</resources>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dolby_enable_title">Dolby Atmos نى قوزغات</string>
<string name="dolby_top_intro_summary">ئۈستى ۋە ئەتراپىڭىزدىكى ۋاسىتە قويۇش تەسىراتى ئالاھىدە كۈچلۈك بولغان ئاۋاز</string>
<string name="dolby_profile_auto">ئاپتوماتىك</string>
<string name="dolby_profile_game">ئويۇن</string>
<string name="dolby_profile_game_1">ئويۇن 1</string>
<string name="dolby_profile_game_2">ئويۇن 2</string>
<string name="dolby_profile_movie">كىنو</string>
<string name="dolby_profile_music">نەغمە</string>
<string name="dolby_profile_off">سەپلىمە ھۆججەت يوق</string>
<string name="dolby_profile_spacial_audio">بوشلۇقتىكى ئاۋاز</string>
<string name="dolby_profile_voice">ئاۋاز</string>
</resources>

View File

@@ -9,6 +9,7 @@ android_app {
defaults: ["SettingsLibDefaults"],
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
certificate: "platform",
platform_apis: true,

View File

@@ -0,0 +1 @@
include $(all-subdir-makefiles)

View File

@@ -0,0 +1 @@
include $(all-subdir-makefiles)

View File

@@ -0,0 +1,7 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),)
include $(LOCAL_PATH)/exynos4/Android.mk
endif

View File

@@ -0,0 +1,14 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_AUDIO_PATH :=$(LOCAL_PATH)
ifeq ($(BOARD_USE_ALP_AUDIO), true)
include $(LOCAL_AUDIO_PATH)/srp/alp/Android.mk
else
ifeq ($(USE_ULP_AUDIO), true)
include $(LOCAL_AUDIO_PATH)/srp/ulp/Android.mk
include $(LOCAL_AUDIO_PATH)/srp/libsa_jni/Android.mk
endif
endif

View File

@@ -0,0 +1,26 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_COPY_HEADERS_TO := libsecmm
LOCAL_COPY_HEADERS := \
include/srp_api.h \
include/srp_ioctl.h \
include/srp_error.h
LOCAL_SRC_FILES := \
src/srp_api.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include
LOCAL_MODULE := libsrpapi
LOCAL_MODULE_TAGS := optional
LOCAL_ARM_MODE := arm
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
include $(BUILD_STATIC_LIBRARY)

View File

@@ -0,0 +1,52 @@
#ifndef __SRP_API_H__
#define __SRP_API_H__
#include "srp_ioctl.h"
#include "srp_error.h"
#define SRP_DEV_NAME "dev/srp"
#define SRP_INIT_BLOCK_MODE 0
#define SRP_INIT_NONBLOCK_MODE 1
#define SRP_PENDING_STATE_RUNNING 0
#define SRP_PENDING_STATE_PENDING 1
struct srp_buf_info {
void *mmapped_addr;
void *addr;
unsigned int mmapped_size;
unsigned int size;
int num;
};
struct srp_dec_info {
unsigned int sample_rate;
unsigned int channels;
};
#ifdef __cplusplus
extern "C" {
#endif
int SRP_Create(int block_mode);
int SRP_Init();
int SRP_Decode(void *buff, int size_byte);
int SRP_Send_EOS(void);
int SRP_SetParams(int id, unsigned long val);
int SRP_GetParams(int id, unsigned long *pval);
int SRP_Deinit(void);
int SRP_Terminate(void);
int SRP_IsOpen(void);
int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num);
int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num);
int SRP_Get_Dec_Info(struct srp_dec_info *dec_info);
int SRP_Get_PCM(void **addr, unsigned int *size);
int SRP_Flush(void);
#ifdef __cplusplus
}
#endif
#endif /*__SRP_API_H__ */

View File

@@ -0,0 +1,22 @@
#ifndef _SRP_ERROR_H_
#define _SRP_ERROR_H_
typedef enum {
SRP_RETURN_OK = 0,
SRP_ERROR_OPEN_FAIL = -1000,
SRP_ERROR_ALREADY_OPEN = -1001,
SRP_ERROR_NOT_READY = -1002,
SRP_ERROR_IBUF_OVERFLOW = -2000,
SRP_ERROR_IBUF_INFO = -2001,
SRP_ERROR_OBUF_READ = -3000,
SRP_ERROR_OBUF_INFO = -3001,
SRP_ERROR_OBUF_MMAP = -3002,
SRP_ERROR_INVALID_SETTING = -4000,
SRP_ERROR_GETINFO_FAIL = -4001
} SRP_ERRORTYPE;
#endif /* _SRP_ERROR_H_ */

View File

@@ -0,0 +1,23 @@
#ifndef __SRP_IOCTL_H__
#define __SRP_IOCTL_H__
#ifdef __cplusplus
extern "C" {
#endif
#define SRP_INIT (0x10000)
#define SRP_DEINIT (0x10001)
#define SRP_GET_MMAP_SIZE (0x10002)
#define SRP_FLUSH (0x20002)
#define SRP_SEND_EOS (0x20005)
#define SRP_GET_IBUF_INFO (0x20007)
#define SRP_GET_OBUF_INFO (0x20008)
#define SRP_STOP_EOS_STATE (0x30007)
#define SRP_GET_DEC_INFO (0x30008)
#ifdef __cplusplus
}
#endif
#endif /* __SRP_IOCTL_H__ */

View File

@@ -0,0 +1,265 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include "srp_api.h"
#define LOG_NDEBUG 1
#define LOG_TAG "libsrpapi"
#include <utils/Log.h>
static struct srp_buf_info ibuf_info;
static struct srp_buf_info obuf_info;
static struct srp_buf_info pcm_info;
static int srp_dev = -1;
static int srp_block_mode = SRP_INIT_BLOCK_MODE;
int SRP_Create(int block_mode)
{
if (srp_dev == -1) {
srp_block_mode = block_mode;
srp_dev = open(SRP_DEV_NAME, O_RDWR |
((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0));
if (srp_dev > 0)
return srp_dev;
else
return SRP_ERROR_OPEN_FAIL;
}
ALOGE("%s: Device is already opened", __func__);
return SRP_ERROR_ALREADY_OPEN;
}
int SRP_Init()
{
int ret = SRP_RETURN_OK;
unsigned int mmapped_size = 0;
if (srp_dev != -1) {
ret = ioctl(srp_dev, SRP_INIT);
if (ret < 0)
return ret;
/* mmap for OBUF */
ret = ioctl(srp_dev, SRP_GET_MMAP_SIZE, &mmapped_size);
if (ret < 0) {
ALOGE("%s: SRP_GET_MMAP_SIZE is failed", __func__);
return SRP_ERROR_OBUF_MMAP;
}
obuf_info.mmapped_addr = mmap(0, mmapped_size,
PROT_READ | PROT_WRITE, MAP_SHARED, srp_dev, 0);
if (!obuf_info.mmapped_addr) {
ALOGE("%s: mmap is failed", __func__);
return SRP_ERROR_OBUF_MMAP;
}
obuf_info.mmapped_size = mmapped_size;
ret = SRP_RETURN_OK;
} else {
ALOGE("%s: Device is not ready", __func__);
ret = SRP_ERROR_NOT_READY; /* device is not created */
}
return ret;
}
int SRP_Decode(void *buff, int size_byte)
{
int ret = SRP_RETURN_OK;
if (srp_dev != -1) {
if (size_byte > 0) {
ALOGV("%s: Send data to RP (%d bytes)", __func__, size_byte);
ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */
if (ret < 0) {
if (ret != SRP_ERROR_IBUF_OVERFLOW)
ALOGE("SRP_Decode returned error code: %d", ret);
}
return ret; /* Write Success */
} else {
return ret;
}
}
ALOGE("%s: Device is not ready", __func__);
return SRP_ERROR_NOT_READY;
}
int SRP_Send_EOS(void)
{
if (srp_dev != -1)
return ioctl(srp_dev, SRP_SEND_EOS);
return SRP_ERROR_NOT_READY;
}
int SRP_SetParams(int id, unsigned long val)
{
if (srp_dev != -1)
return 0; /* not yet */
return SRP_ERROR_NOT_READY;
}
int SRP_GetParams(int id, unsigned long *pval)
{
if (srp_dev != -1)
return ioctl(srp_dev, id, pval);
return SRP_ERROR_NOT_READY;
}
int SRP_Flush(void)
{
if (srp_dev != -1)
return ioctl(srp_dev, SRP_FLUSH);
return SRP_ERROR_NOT_READY;
}
int SRP_Get_PCM(void **addr, unsigned int *size)
{
int ret = SRP_RETURN_OK;
if (srp_dev != -1) {
ret = read(srp_dev, &pcm_info, 0);
if (ret == -1) {
*size = 0;
ALOGE("%s: PCM read fail", __func__);
return SRP_ERROR_OBUF_READ;
}
*addr = pcm_info.addr;
*size = pcm_info.size;
} else {
return SRP_ERROR_NOT_READY;
}
return ret; /* Read Success */
}
int SRP_Get_Dec_Info(struct srp_dec_info *dec_info)
{
int ret;
if (srp_dev != -1) {
ret = ioctl(srp_dev, SRP_GET_DEC_INFO, dec_info);
if (ret < 0) {
ALOGE("%s: Failed to get dec info", __func__);
return SRP_ERROR_GETINFO_FAIL;
}
ALOGV("numChannels(%d), samplingRate(%d)", dec_info->channels, dec_info->sample_rate);
ret = SRP_RETURN_OK;
} else {
ret = SRP_ERROR_NOT_READY;
}
return ret;
}
int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num)
{
int ret = SRP_RETURN_OK;
if (srp_dev != -1) {
ret = ioctl(srp_dev, SRP_GET_IBUF_INFO, &ibuf_info);
if (ret == -1) {
ALOGE("%s: Failed to get Ibuf info", __func__);
return SRP_ERROR_IBUF_INFO;
}
*addr = ibuf_info.addr;
*size = ibuf_info.size;
*num = ibuf_info.num;
if (*num == 0) {
ALOGE("%s: IBUF num is 0", __func__);
return SRP_ERROR_INVALID_SETTING;
}
ret = SRP_RETURN_OK;
} else {
ret = SRP_ERROR_NOT_READY;
}
return ret;
}
int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num)
{
int ret = SRP_RETURN_OK;
if (srp_dev != -1) {
if (obuf_info.addr == NULL) {
ret = ioctl(srp_dev, SRP_GET_OBUF_INFO, &obuf_info);
if (ret < 0) {
ALOGE("%s: SRP_GET_OBUF_INFO is failed", __func__);
return SRP_ERROR_OBUF_INFO;
}
}
*addr = obuf_info.addr;
*size = obuf_info.size;
*num = obuf_info.num;
if (*num == 0) {
ALOGE("%s: OBUF num is 0", __func__);
return SRP_ERROR_INVALID_SETTING;
}
ret = SRP_RETURN_OK;
} else {
ret = SRP_ERROR_NOT_READY;
}
return ret;
}
int SRP_Deinit(void)
{
if (srp_dev != -1) {
munmap(obuf_info.mmapped_addr, obuf_info.mmapped_size);
return ioctl(srp_dev, SRP_DEINIT);
}
return SRP_ERROR_NOT_READY;
}
int SRP_Terminate(void)
{
int ret;
if (srp_dev != -1) {
ret = close(srp_dev);
if (ret == 0) {
srp_dev = -1; /* device closed */
return SRP_RETURN_OK;
}
}
return SRP_ERROR_NOT_READY;
}
int SRP_IsOpen(void)
{
if (srp_dev == -1) {
ALOGV("%s: Device is not opened", __func__);
return 0;
}
ALOGV("%s: Device is opened", __func__);
return 1;
}

View File

@@ -0,0 +1,13 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libsa_jni
LOCAL_SRC_FILES := SACtrl.c
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_STATIC_LIBRARIES := libsrpapi
include $(BUILD_SHARED_LIBRARY)

View File

@@ -0,0 +1,33 @@
#include <jni.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "srp_api_ctrl.h"
#define LOG_TAG "libsa_jni"
#include <cutils/log.h>
void Java_com_android_music_SetSACtrlJNI_set(JNIEnv * env, jobject obj, int effect_num)
{
unsigned long effect_enable = effect_num ? 1 : 0;
unsigned int ret;
ALOGD("Sound effect[%d]", effect_num);
ret = SRP_Ctrl_Enable_Effect(effect_enable);
if (ret < 0) {
ALOGE("%s: Couldn't enabled effect\n", __func__);
return;
}
SRP_Ctrl_Set_Effect_Def(effect_num << 5);
if (ret < 0) {
ALOGE("%s: Couldn't defined effect\n", __func__);
return;
}
return;
}

View File

@@ -0,0 +1,23 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
src/srp_api.c \
src/srp_api_ctrl.c
LOCAL_MODULE := libsrpapi
LOCAL_MODULE_TAGS := optional
LOCAL_ARM_MODE := arm
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_COPY_HEADERS := \
include/srp_api.h \
include/srp_api_ctrl.h \
include/srp_ioctl.h
include $(BUILD_STATIC_LIBRARY)

View File

@@ -0,0 +1,55 @@
#ifndef __SRP_API_H__
#define __SRP_API_H__
#include "srp_ioctl.h"
#ifdef __cplusplus
extern "C" {
#endif
int SRP_Create(int block_mode);
int SRP_Init(unsigned int ibuf_size);
int SRP_Decode(void *buff, int size_byte);
int SRP_Send_EOS(void);
int SRP_Resume_EOS(void);
int SRP_Pause(void);
int SRP_Stop(void);
int SRP_Flush(void);
int SRP_SetParams(int id, unsigned long val);
int SRP_GetParams(int id, unsigned long *pval);
int SRP_Deinit(void);
int SRP_Terminate(void);
int SRP_IsOpen(void);
#define SRP_DEV_NAME "dev/srp"
#define SRP_INIT_BLOCK_MODE 0
#define SRP_INIT_NONBLOCK_MODE 1
#define SRP_PENDING_STATE_RUNNING 0
#define SRP_PENDING_STATE_PENDING 1
#define SRP_ERROR_LOSTSYNC 0x00101
#define SRP_ERROR_BADLAYER 0x00102
#define SRP_ERROR_BADBITRATE 0x00103
#define SRP_ERROR_BADSAMPLERATE 0x00104
#define SRP_ERROR_BADEMPHASIS 0x00105
#define SRP_ERROR_BADCRC 0x00201
#define SRP_ERROR_BADBITALLOC 0x00211
#define SRP_ERROR_BADBADSCALEFACTOR 0x00221
#define SRP_ERROR_BADFRAMELEN 0x00231
#define SRP_ERROR_BADBIGVALUES 0x00232
#define SRP_ERROR_BADBLOCKTYPE 0x00233
#define SRP_ERROR_BADSCFSI 0x00234
#define SRP_ERROR_BADDATAPTR 0x00235
#define SRP_ERROR_BADPART3LEN 0x00236
#define SRP_ERROR_BADHUFFTABLE 0x00237
#define SRP_ERROR_BADHUFFDATA 0x00238
#define SRP_ERROR_BADSTEREO 0x00239
#ifdef __cplusplus
}
#endif
#endif /*__SRP_API_H__ */

View File

@@ -0,0 +1,25 @@
#ifndef __SRP_API_CTRL_H__
#define __SRP_API_CTRL_H__
#ifdef __cplusplus
extern "C" {
#endif
#define SRP_CTRL_DEV_NAME "dev/srp_ctrl"
int SRP_Ctrl_Set_Effect(int effect); /* test only */
int SRP_Ctrl_Enable_Effect(int on);
int SRP_Ctrl_Set_Effect_Def(unsigned long effect_def);
int SRP_Ctrl_Set_Effect_EQ_User(unsigned long eq_user);
int SRP_Ctrl_Set_Pcm_Dump(int on);
int SRP_Ctrl_Get_Pcm_Dump_State(void);
int SRP_Ctrl_Set_Gain(float value);
int SRP_Ctrl_Get_Running_Stat(void);
int SRP_Ctrl_Get_Open_Stat(void);
short *SRP_Ctrl_Get_Pcm(void);
#ifdef __cplusplus
}
#endif
#endif /* __SRP_API_CTRL_H__ */

View File

@@ -0,0 +1,66 @@
#ifndef __SRP_IOCTL_H__
#define __SRP_IOCTL_H__
#ifdef __cplusplus
extern "C" {
#endif
/* constants for srp device node */
#define SRP_INIT (0x10000)
#define SRP_DEINIT (0x10001)
#define SRP_PAUSE (0x20000)
#define SRP_STOP (0x20001)
#define SRP_FLUSH (0x20002)
#define SRP_WAIT_EOS (0x20003)
#define SRP_EFFECT (0x20004)
#define SRP_SEND_EOS (0x20005)
#define SRP_RESUME_EOS (0x20006)
#define SRP_PENDING_STATE (0x30000)
#define SRP_ERROR_STATE (0x30001)
#define SRP_DECODED_FRAME_NO (0x30002)
#define SRP_DECODED_ONE_FRAME_SIZE (0x30003)
#define SRP_DECODED_FRAME_SIZE (0x30004)
#define SRP_DECODED_PCM_SIZE (0x30005)
#define SRP_CHANNEL_COUNT (0x30006)
#define SRP_STOP_EOS_STATE (0x30007)
/* constants for srp_ctrl device node*/
#define SRP_CTRL_SET_GAIN (0xFF000)
#define SRP_CTRL_SET_EFFECT (0xFF001)
#define SRP_CTRL_GET_PCM_1KFRAME (0xFF002)
#define SRP_CTRL_PCM_DUMP_OP (0xFF003)
#define SRP_CTRL_EFFECT_ENABLE (0xFF010)
#define SRP_CTRL_EFFECT_DEF (0xFF011)
#define SRP_CTRL_EFFECT_EQ_USR (0xFF012)
#define SRP_CTRL_EFFECT_SPEAKER (0xFF013)
#define SRP_CTRL_IS_RUNNING (0xFF100)
#define SRP_CTRL_IS_OPENED (0xFF101)
#define SRP_CTRL_GET_OP_LEVEL (0xFF102)
#define SRP_CTRL_IS_PCM_DUMP (0xFF103)
#define SRP_CTRL_ALTFW_STATE (0xFF200)
#define SRP_CTRL_ALTFW_LOAD (0xFF201)
/* constants for SRP firmware */
#define SRP_FW_CODE1 0
#define SRP_FW_CODE20 1
#define SRP_FW_CODE21 2
#define SRP_FW_CODE22 3
#define SRP_FW_CODE30 4
#define SRP_FW_CODE31 5
#define SRP_FW_VLIW 0
#define SRP_FW_CGA 1
#define SRP_FW_CGA_SA 2
#define SRP_FW_DATA 3
#ifdef __cplusplus
}
#endif
#endif /* __SRP_IOCTL_H__ */

View File

@@ -0,0 +1,381 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include "srp_api.h"
#define LOG_TAG "libsrpapi"
#include <cutils/log.h>
/* Disable ALOGD message */
#ifdef ALOGD
#undef ALOGD
#endif
#define ALOGD(...)
//#define _USE_WBUF_ /* Buffering before writing srp-rp device */
//#define _DUMP_TO_FILE_
//#define _USE_FW_FROM_DISK_
#ifdef _USE_WBUF_
#define WBUF_LEN_MUL 2
#endif
static int srp_dev = -1;
static int srp_ibuf_size = 0;
static int srp_block_mode = SRP_INIT_BLOCK_MODE;
static unsigned char *wbuf;
static int wbuf_size;
static int wbuf_pos;
#ifdef _DUMP_TO_FILE_
static FILE *fp_dump = NULL;
#endif
#ifdef _USE_WBUF_
static int WriteBuff_Init(void)
{
if (wbuf == NULL) {
wbuf_size = srp_ibuf_size * WBUF_LEN_MUL;
wbuf_pos = 0;
wbuf = (unsigned char *)malloc(wbuf_size);
ALOGD("%s: WriteBuffer %dbytes allocated", __func__, wbuf_size);
return 0;
}
ALOGE("%s: WriteBuffer already allocated", __func__);
return -1;
}
static int WriteBuff_Deinit(void)
{
if (wbuf != NULL) {
free(wbuf);
wbuf = NULL;
return 0;
}
ALOGE("%s: WriteBuffer is not ready", __func__);
return -1;
}
static int WriteBuff_Write(unsigned char *buff, int size_byte)
{
int write_byte;
if ((wbuf_pos + size_byte) < wbuf_size) {
memcpy(&wbuf[wbuf_pos], buff, size_byte);
wbuf_pos += size_byte;
} else {
ALOGE("%s: WriteBuffer is filled [%d], ignoring write [%d]", __func__, wbuf_pos, size_byte);
return -1; /* Insufficient buffer */
}
return wbuf_pos;
}
static void WriteBuff_Consume(void)
{
memcpy(wbuf, &wbuf[srp_ibuf_size], srp_ibuf_size * (WBUF_LEN_MUL - 1));
wbuf_pos -= srp_ibuf_size;
}
static void WriteBuff_Flush(void)
{
wbuf_pos = 0;
}
#endif
int SRP_Create(int block_mode)
{
if (srp_dev == -1) {
#ifdef _USE_FW_FROM_DISK_
SRP_Check_AltFirmware();
#endif
srp_block_mode = block_mode;
srp_dev = open(SRP_DEV_NAME, O_RDWR |
((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0));
return srp_dev;
}
ALOGE("%s: Device is not ready", __func__);
return -1; /* device alreay opened */
}
int SRP_Init(unsigned int ibuf_size)
{
int ret;
if (srp_dev != -1) {
srp_ibuf_size = ibuf_size;
ret = ioctl(srp_dev, SRP_INIT, srp_ibuf_size); /* Initialize IBUF size (4KB ~ 18KB) */
#ifdef _DUMP_TO_FILE_
char outname[256];
int cnt = 0;
while (1) {
sprintf(outname, "/data/rp_dump_%04d.mp3", cnt++);
if (fp_dump = fopen(outname, "rb")) { /* file exist? */
fclose(fp_dump);
} else {
break;
}
}
ALOGD("%s: Dump MP3 to %s", __func__, outname);
if (fp_dump = fopen(outname, "wb"))
ALOGD("%s: Success to open %s", __func__, outname);
else
ALOGD("%s: Fail to open %s", __func__, outname);
#endif
#ifdef _USE_WBUF_
if (ret != -1)
return WriteBuff_Init();
#else
return ret;
#endif
}
ALOGE("%s: Device is not ready", __func__);
return -1; /* device is not created */
}
#ifdef _USE_WBUF_
int SRP_Decode(void *buff, int size_byte)
{
int ret;
int val;
int err_code = 0;
if (srp_dev != -1) {
/* Check wbuf before writing buff */
while (wbuf_pos >= srp_ibuf_size) { /* Write_Buffer filled? (IBUF Size)*/
ALOGD("%s: Write Buffer is full, Send data to RP", __func__);
ret = write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */
if (ret == -1) { /* Fail? */
ioctl(srp_dev, SRP_ERROR_STATE, &val);
if (!val) { /* Write error? */
ALOGE("%s: IBUF write fail", __func__);
return -1;
} else { /* Write OK, but RP decode error? */
err_code = val;
ALOGE("%s: RP decode error [0x%05X]", __func__, err_code);
}
}
#ifdef _DUMP_TO_FILE_
if (fp_dump)
fwrite(wbuf, srp_ibuf_size, 1, fp_dump);
#endif
WriteBuff_Consume();
}
ret = WriteBuff_Write((unsigned char *)buff, size_byte);
if (ret == -1)
return -1; /* Buffering error */
ALOGD("%s: Write Buffer remain [%d]", __func__, wbuf_pos);
return err_code; /* Write Success */
}
ALOGE("%s: Device is not ready", __func__);
return -1; /* device is not created */
}
int SRP_Send_EOS(void)
{
int ret;
int val;
if (srp_dev != -1) {
/* Check wbuf before writing buff */
while (wbuf_pos) { /* Write_Buffer ramain?*/
if (wbuf_pos < srp_ibuf_size) {
memset(wbuf + wbuf_pos, 0xFF, srp_ibuf_size - wbuf_pos); /* Fill dummy data */
wbuf_pos = srp_ibuf_size;
}
ret = write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */
if (ret == -1) { /* Fail? */
ret = ioctl(srp_dev, SRP_ERROR_STATE, &val);
if (!val) { /* Write error? */
ALOGE("%s: IBUF write fail", __func__);
return -1;
} else { /* RP decoe error? */
ALOGE("%s: RP decode error [0x%05X]", __func__, val);
return -1;
}
} else { /* Success? */
#ifdef _DUMP_TO_FILE_
if (fp_dump)
fwrite(wbuf, srp_ibuf_size, 1, fp_dump);
#endif
WriteBuff_Consume();
}
}
memset(wbuf, 0xFF, srp_ibuf_size); /* Fill dummy data */
write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */
/* Wait until RP decoding over */
return ioctl(srp_dev, SRP_WAIT_EOS);
}
return -1; /* device is not created */
}
#else /* Without WBUF */
int SRP_Decode(void *buff, int size_byte)
{
int ret;
int val;
int err_code = 0;
if (srp_dev != -1) {
ALOGD("%s: Send data to RP (%d bytes)", __func__, size_byte);
ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */
if (ret == -1) { /* Fail? */
ioctl(srp_dev, SRP_ERROR_STATE, &val);
if (!val) { /* Write error? */
ALOGE("%s: IBUF write fail", __func__);
return -1;
} else { /* Write OK, but RP decode error? */
err_code = val;
ALOGE("%s: RP decode error [0x%05X]", __func__, err_code);
}
}
#ifdef _DUMP_TO_FILE_
if (fp_dump)
fwrite(buff, size_byte, 1, fp_dump);
#endif
return err_code; /* Write Success */
}
ALOGE("%s: Device is not ready", __func__);
return -1; /* device is not created */
}
int SRP_Send_EOS(void)
{
/* Wait until RP decoding over */
if (srp_dev != -1)
return ioctl(srp_dev, SRP_SEND_EOS);
return -1; /* device is not created */
}
int SRP_Resume_EOS(void)
{
if (srp_dev != -1)
return ioctl(srp_dev, SRP_RESUME_EOS);
return -1; /* device is not created */
}
#endif
int SRP_Pause(void)
{
if (srp_dev != -1)
return ioctl(srp_dev, SRP_PAUSE);
return -1; /* device is not created */
}
int SRP_Stop(void)
{
if (srp_dev != -1)
return ioctl(srp_dev, SRP_STOP);
return -1; /* device is not created */
}
int SRP_Flush(void)
{
if (srp_dev != -1) {
if (ioctl(srp_dev, SRP_FLUSH) != -1) {
#ifdef _USE_WBUF_
WriteBuff_Flush();
#endif
return 0;
}
}
return -1; /* device is not created */
}
int SRP_SetParams(int id, unsigned long val)
{
if (srp_dev != -1)
return 0; /* not yet */
return -1; /* device is not created */
}
int SRP_GetParams(int id, unsigned long *pval)
{
if (srp_dev != -1)
return ioctl(srp_dev, id, pval);
return -1; /* device is not created */
}
int SRP_Deinit(void)
{
if (srp_dev != -1) {
#ifdef _DUMP_TO_FILE_
if (fp_dump)
fclose(fp_dump);
#endif
#ifdef _USE_WBUF_
WriteBuff_Deinit();
#endif
return ioctl(srp_dev, SRP_DEINIT); /* Deinialize */
}
ALOGE("%s: Device is not ready", __func__);
return -1; /* device is not created */
}
int SRP_Terminate(void)
{
int ret;
if (srp_dev != -1) {
ret = close(srp_dev);
if (ret == 0) {
srp_dev = -1; /* device closed */
return 0;
}
}
ALOGE("%s: Device is not ready", __func__);
return -1; /* device is not created or close error*/
}
int SRP_IsOpen(void)
{
if (srp_dev == -1) {
ALOGD("%s: Device is not opened", __func__);
return 0;
}
ALOGD("%s: Device is opened", __func__);
return 1;
}

View File

@@ -0,0 +1,331 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include "srp_api_ctrl.h"
#include "srp_ioctl.h"
#define LOG_TAG "libsrpapi"
#include <cutils/log.h>
/* Disable ALOGD message */
#ifdef ALOGD
#undef ALOGD
#endif
#define ALOGD(...)
static int srp_ctrl = -1;
static int srp_ctrl_cnt = 0;
static short pcm_buf[2048]; /* 4KBytes data, 1K frames (16bit stereo data) */
#ifdef _USE_FW_FROM_DISK_
static char srp_alt_fw_name_pre[6][32] = {
"sdcard/rp_fw/rp_fw_code1",
"sdcard/rp_fw/rp_fw_code20",
"sdcard/rp_fw/rp_fw_code21",
"sdcard/rp_fw/rp_fw_code22",
"sdcard/rp_fw/rp_fw_code30",
"sdcard/rp_fw/rp_fw_code31",
};
#endif
static int SRP_Ctrl_Open(void)
{
if (srp_ctrl_cnt == 0) {
srp_ctrl = open(SRP_CTRL_DEV_NAME, O_RDWR | O_NDELAY);
if (srp_ctrl < 0) {
ALOGE("%s: Failed open device file %d", __func__, srp_ctrl);
return -1;
}
srp_ctrl_cnt++;
ALOGV("%s: Device is opened[%d]: cnt %d", __func__, srp_ctrl, srp_ctrl_cnt);
}
return srp_ctrl;
}
static int SRP_Ctrl_Close(void)
{
int ret = 0;
if (srp_ctrl_cnt == 1) {
ret = close(srp_ctrl);
if (ret < 0) {
ALOGE("%s: Failed closen device file %d", __func__, srp_ctrl);
return -1;
}
srp_ctrl_cnt--;
ALOGV("%s: Device is closed[%d]: cnt %d", __func__, srp_ctrl, srp_ctrl_cnt);
srp_ctrl = -1;
}
return ret;
}
#ifdef _USE_FW_FROM_DISK_
/* This will check & download alternate firmware */
static int SRP_Check_AltFirmware(void)
{
unsigned long *temp_buff;
FILE *fp = NULL;
char alt_fw_name[128];
unsigned long alt_fw_set;
unsigned long alt_fw_loaded = 0;
int alt_fw_text_ok,alt_fw_data_ok;
if ((srp_ctrl = SRP_Ctrl_Open()) >= 0) {
ioctl(srp_ctrl, SRP_CTRL_ALTFW_STATE, &alt_fw_loaded);
if (!alt_fw_loaded) { /* Not loaded yet? */
ALOGE("Try to download alternate RP firmware");
temp_buff = (unsigned long *)malloc(256*1024); /* temp buffer */
for (alt_fw_set = 0; alt_fw_set < 6; alt_fw_set++) {
sprintf(alt_fw_name, "%s_text.bin", srp_alt_fw_name_pre[alt_fw_set]);
if (fp = fopen(alt_fw_name, "rb")) {
ALOGE("RP Alt-Firmware Loading: %s", alt_fw_name);
fread(temp_buff, 64*1024, 1, fp);
close(fp);
alt_fw_text_ok = 1;
} else {
alt_fw_text_ok = 0;
}
sprintf(alt_fw_name, "%s_data.bin", srp_alt_fw_name_pre[alt_fw_set]);
if (fp = fopen(alt_fw_name, "rb")) {
ALOGE("RP Alt-Firmware Loading: %s", alt_fw_name);
fread(&temp_buff[64*1024/4], 96*1024, 1, fp);
close(fp);
alt_fw_data_ok = 1;
} else {
alt_fw_data_ok = 0;
}
if (alt_fw_text_ok && alt_fw_data_ok) {
temp_buff[160*1024/4] = alt_fw_set;
ioctl(srp_ctrl, SRP_CTRL_ALTFW_LOAD, temp_buff);
}
}
free(temp_buff);
}
SRP_Ctrl_Close();
}
return 0;
}
#endif
int SRP_Ctrl_Set_Effect(int effect)
{
int ret;
unsigned long effect_mode = (unsigned long)effect;
ret = SRP_Ctrl_Open();
if (ret < 0) {
ALOGE("%s: SRP_Ctrl_Open error", __func__);
return -1;
}
ioctl(srp_ctrl, SRP_CTRL_SET_EFFECT, effect_mode);
SRP_Ctrl_Close();
return 0;
}
int SRP_Ctrl_Enable_Effect(int on)
{
int ret;
unsigned long effect_switch = on ? 1 : 0;
ret = SRP_Ctrl_Open();
if (ret < 0) {
ALOGE("%s: SRP_Ctrl_Open error", __func__);
return -1;
}
ioctl(srp_ctrl, SRP_CTRL_EFFECT_ENABLE, effect_switch);
SRP_Ctrl_Close();
return 0;
}
int SRP_Ctrl_Set_Effect_Def(unsigned long effect_def)
{
int ret;
ret = SRP_Ctrl_Open();
if (ret < 0) {
ALOGE("%s: SRP_Ctrl_Open error", __func__);
return -1;
}
ioctl(srp_ctrl, SRP_CTRL_EFFECT_DEF, effect_def);
SRP_Ctrl_Close();
return 0;
}
int SRP_Ctrl_Set_Effect_EQ_User(unsigned long eq_user)
{
int ret;
ret = SRP_Ctrl_Open();
if (ret < 0) {
ALOGE("%s: SRP_Ctrl_Open error", __func__);
return -1;
}
ioctl(srp_ctrl, SRP_CTRL_EFFECT_EQ_USR, eq_user);
SRP_Ctrl_Close();
return 0;
}
int SRP_Ctrl_Set_Pcm_Dump(int on)
{
int ret;
ret = SRP_Ctrl_Open();
if (ret < 0) {
ALOGE("%s: SRP_Ctrl_Open error", __func__);
return -1;
}
ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, on);
ALOGV("dump_op: %d", on);
SRP_Ctrl_Close();
return 0;
}
int SRP_Ctrl_Get_Pcm_Dump_State(void)
{
int ret;
int srp_dump_stat = 0;
ret = SRP_Ctrl_Open();
if (ret < 0) {
ALOGE("%s: SRP_Ctrl_Open error", __func__);
return -1;
}
ioctl(srp_ctrl, SRP_CTRL_IS_PCM_DUMP, &srp_dump_stat);
ALOGV("srp_dump_stat: %d", srp_dump_stat);
SRP_Ctrl_Close();
return srp_dump_stat;
}
int SRP_Ctrl_Set_Gain(float value)
{
int ret;
unsigned long gain = 0;
ret = SRP_Ctrl_Open();
if (ret < 0) {
ALOGE("%s: SRP_Ctrl_Open error", __func__);
return -1;
}
gain = (unsigned long)((1 << 24) * value);
ioctl(srp_ctrl, SRP_CTRL_SET_GAIN, gain);
SRP_Ctrl_Close();
return 0;
}
int SRP_Ctrl_Get_Running_Stat(void)
{
int ret;
int srp_running_stat = 0;
ret = SRP_Ctrl_Open();
if (ret < 0) {
ALOGE("%s: SRP_Ctrl_Open error", __func__);
return -1;
}
ioctl(srp_ctrl, SRP_CTRL_IS_RUNNING, &srp_running_stat);
ALOGV("srp_running_stat: %d", srp_running_stat);
SRP_Ctrl_Close();
return srp_running_stat;
}
int SRP_Ctrl_Get_Open_Stat(void)
{
int ret;
int srp_open_stat = 0;
ret = SRP_Ctrl_Open();
if (ret < 0) {
ALOGE("%s: SRP_Ctrl_Open error", __func__);
return -1;
}
ioctl(srp_ctrl, SRP_CTRL_IS_OPENED, &srp_open_stat);
ALOGV("srp_open_stat: %d", srp_open_stat);
SRP_Ctrl_Close();
return srp_open_stat;
}
short *SRP_Ctrl_Get_Pcm(void)
{
int ret;
int rp_is_running = 0;
int dump_is_on = 0;
int rp_is_opened = 0;
ret = SRP_Ctrl_Open();
if (ret < 0) {
ALOGE("%s: SRP_Ctrl_Open error", __func__);
return NULL;
}
ioctl(srp_ctrl, SRP_CTRL_IS_RUNNING, &rp_is_running);
if (rp_is_running) {
ioctl(srp_ctrl, SRP_CTRL_IS_PCM_DUMP, &dump_is_on);
if (dump_is_on == 0) {
ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, 1);
dump_is_on = 1;
}
ioctl(srp_ctrl, SRP_CTRL_GET_PCM_1KFRAME, pcm_buf);
return pcm_buf;
}
/* SRP is not running */
if (srp_ctrl > 0) {
if (dump_is_on) {
ioctl(srp_ctrl, SRP_CTRL_IS_OPENED, &rp_is_opened);
if (rp_is_opened)
ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, 0);
}
SRP_Ctrl_Close();
}
return NULL;
}

View File

@@ -0,0 +1,7 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),)
include $(LOCAL_PATH)/exynos4/Android.mk
endif

View File

@@ -0,0 +1,11 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_VIDEO_PATH :=$(LOCAL_PATH)
ifeq ($(BOARD_USE_V4L2), true)
include $(LOCAL_VIDEO_PATH)/mfc_v4l2/Android.mk
else
include $(LOCAL_VIDEO_PATH)/mfc/Android.mk
endif

View File

@@ -0,0 +1,115 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_COPY_HEADERS_TO := libsecmm
LOCAL_COPY_HEADERS := \
include/mfc_errno.h \
include/mfc_interface.h \
include/SsbSipMfcApi.h
LOCAL_MODULE := libsecmfcapi
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
dec/src/SsbSipMfcDecAPI.c \
enc/src/SsbSipMfcEncAPI.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include/
LOCAL_PRELINK_MODULE := false
ifeq ($(BOARD_USES_MFC_FPS),true)
LOCAL_CFLAGS := -DCONFIG_MFC_FPS
#LOCAL_CFLAGS += -DCONFIG_MFC_PERF_ALOG
endif
ifeq ($(BOARD_USE_S3D_SUPPORT), true)
LOCAL_CFLAGS += -DS3D_SUPPORT
endif
LOCAL_ARM_MODE := arm
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES := liblog
include $(BUILD_STATIC_LIBRARY)
# Shared MFC Dec API
include $(CLEAR_VARS)
LOCAL_COPY_HEADERS_TO := libsecmm
LOCAL_COPY_HEADERS := \
include/mfc_errno.h \
include/mfc_interface.h \
include/SsbSipMfcApi.h
LOCAL_MODULE := libsecmfcdecapi
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
dec/src/SsbSipMfcDecAPI.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include/
LOCAL_PRELINK_MODULE := false
ifeq ($(BOARD_USES_MFC_FPS),true)
LOCAL_CFLAGS := -DCONFIG_MFC_FPS
#LOCAL_CFLAGS += -DCONFIG_MFC_PERF_ALOG
endif
ifeq ($(BOARD_USE_S3D_SUPPORT), true)
LOCAL_CFLAGS += -DS3D_SUPPORT
endif
LOCAL_ARM_MODE := arm
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES := liblog
include $(BUILD_SHARED_LIBRARY)
# Shared MFC Enc API
include $(CLEAR_VARS)
LOCAL_COPY_HEADERS_TO := libsecmm
LOCAL_COPY_HEADERS := \
include/mfc_errno.h \
include/mfc_interface.h \
include/SsbSipMfcApi.h
LOCAL_MODULE := libsecmfcencapi
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
enc/src/SsbSipMfcEncAPI.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include/
LOCAL_PRELINK_MODULE := false
ifeq ($(BOARD_USES_MFC_FPS),true)
LOCAL_CFLAGS := -DCONFIG_MFC_FPS
#LOCAL_CFLAGS += -DCONFIG_MFC_PERF_ALOG
endif
ifeq ($(BOARD_USE_S3D_SUPPORT), true)
LOCAL_CFLAGS += -DS3D_SUPPORT
endif
LOCAL_ARM_MODE := arm
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES := liblog
include $(BUILD_SHARED_LIBRARY)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,862 @@
/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
*
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <math.h>
#include "mfc_interface.h"
#include "SsbSipMfcApi.h"
#include <utils/Log.h>
/* #define LOG_NDEBUG 0 */
#undef LOG_TAG
#define LOG_TAG "MFC_ENC_APP"
#define _MFCLIB_MAGIC_NUMBER 0x92241001
static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME;
void SsbSipMfcEncSetMFCName(char *devicename)
{
mfc_dev_name = devicename;
}
void *SsbSipMfcEncOpen(void)
{
int hMFCOpen;
_MFCLIB *pCTX = NULL;
unsigned int mapped_addr;
int mapped_size;
struct mfc_common_args CommonArg;
ALOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR);
#if 0
if ((codecType != MPEG4_ENC) &&
(codecType != H264_ENC) &&
(codecType != H263_ENC)) {
ALOGE("SsbSipMfcEncOpen] Undefined codec type");
return NULL;
}
#endif
if (access(mfc_dev_name, F_OK) != 0) {
ALOGE("SsbSipMfcEncOpen] MFC device node not exists");
return NULL;
}
hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY);
if (hMFCOpen < 0) {
ALOGE("SsbSipMfcEncOpen] MFC Open failure");
return NULL;
}
pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
if (pCTX == NULL) {
ALOGE("SsbSipMfcEncOpen] malloc failed.");
close(hMFCOpen);
return NULL;
}
memset(pCTX, 0, sizeof(_MFCLIB));
mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg);
if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) {
ALOGE("SsbSipMfcEncOpen] IOCTL_MFC_GET_MMAP_SIZE failed");
free(pCTX);
close(hMFCOpen);
return NULL;
}
mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0);
if (!mapped_addr) {
ALOGE("SsbSipMfcEncOpen] FIMV5.x driver address mapping failed");
free(pCTX);
close(hMFCOpen);
return NULL;
}
pCTX->magic = _MFCLIB_MAGIC_NUMBER;
pCTX->hMFC = hMFCOpen;
pCTX->mapped_addr = mapped_addr;
pCTX->mapped_size = mapped_size;
pCTX->inter_buff_status = MFC_USE_NONE;
return (void *) pCTX;
}
void *SsbSipMfcEncOpenExt(void *value)
{
int hMFCOpen;
_MFCLIB *pCTX = NULL;
unsigned int mapped_addr;
int mapped_size;
int err;
struct mfc_common_args CommonArg;
ALOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR);
#if 0
if ((codecType != MPEG4_ENC) &&
(codecType != H264_ENC) &&
(codecType != H263_ENC)) {
ALOGE("SsbSipMfcEncOpen] Undefined codec type");
return NULL;
}
#endif
if (access(mfc_dev_name, F_OK) != 0) {
ALOGE("SsbSipMfcEncOpenExt] MFC device node not exists");
return NULL;
}
hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY);
if (hMFCOpen < 0) {
ALOGE("SsbSipMfcEncOpenExt] MFC Open failure");
return NULL;
}
pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
if (pCTX == NULL) {
ALOGE("SsbSipMfcEncOpenExt] malloc failed.");
close(hMFCOpen);
return NULL;
}
memset(pCTX, 0, sizeof(_MFCLIB));
CommonArg.args.mem_alloc.buf_cache_type = *(SSBIP_MFC_BUFFER_TYPE *)value;
err = ioctl(hMFCOpen, IOCTL_MFC_SET_BUF_CACHE, &CommonArg);
if ((err < 0) || (CommonArg.ret_code != MFC_OK)) {
ALOGE("SsbSipMfcEncOpenExt] IOCTL_MFC_SET_BUF_CACHE failed");
free(pCTX);
close(hMFCOpen);
return NULL;
}
mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg);
if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) {
ALOGE("SsbSipMfcEncOpenExt] IOCTL_MFC_GET_MMAP_SIZE failed");
free(pCTX);
close(hMFCOpen);
return NULL;
}
mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0);
if (!mapped_addr) {
ALOGE("SsbSipMfcEncOpenExt] FIMV5.x driver address mapping failed");
free(pCTX);
close(hMFCOpen);
return NULL;
}
pCTX->magic = _MFCLIB_MAGIC_NUMBER;
pCTX->hMFC = hMFCOpen;
pCTX->mapped_addr = mapped_addr;
pCTX->mapped_size = mapped_size;
pCTX->inter_buff_status = MFC_USE_NONE;
return (void *) pCTX;
}
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param)
{
int ret_code;
_MFCLIB *pCTX;
struct mfc_common_args EncArg;
SSBSIP_MFC_ENC_H264_PARAM *h264_arg;
SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg;
SSBSIP_MFC_ENC_H263_PARAM *h263_arg;
pCTX = (_MFCLIB *) openHandle;
memset(&EncArg, 0, sizeof(struct mfc_common_args));
pCTX->encode_cnt = 0;
mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param;
if (mpeg4_arg->codecType == MPEG4_ENC) {
pCTX->codecType= MPEG4_ENC;
} else {
h263_arg = (SSBSIP_MFC_ENC_H263_PARAM*)param;
if (h263_arg->codecType == H263_ENC) {
pCTX->codecType = H263_ENC;
} else {
h264_arg = (SSBSIP_MFC_ENC_H264_PARAM*)param;
if (h264_arg->codecType == H264_ENC) {
pCTX->codecType = H264_ENC;
} else {
ALOGE("SsbSipMfcEncInit] Undefined codec type");
return MFC_RET_INVALID_PARAM;
}
}
}
ALOGI("SsbSipMfcEncInit] Encode Init start");
switch (pCTX->codecType) {
case MPEG4_ENC:
ALOGI("SsbSipMfcEncInit] MPEG4 Encode");
mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param;
pCTX->width = mpeg4_arg->SourceWidth;
pCTX->height = mpeg4_arg->SourceHeight;
break;
case H263_ENC:
ALOGI("SsbSipMfcEncInit] H263 Encode");
h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param;
pCTX->width = h263_arg->SourceWidth;
pCTX->height = h263_arg->SourceHeight;
break;
case H264_ENC:
ALOGI("SsbSipMfcEncInit] H264 Encode");
h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param;
pCTX->width = h264_arg->SourceWidth;
pCTX->height = h264_arg->SourceHeight;
break;
default:
break;
}
switch (pCTX->codecType) {
case MPEG4_ENC:
mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param;
EncArg.args.enc_init.cmn.in_codec_type = pCTX->codecType;
EncArg.args.enc_init.cmn.in_width = mpeg4_arg->SourceWidth;
EncArg.args.enc_init.cmn.in_height = mpeg4_arg->SourceHeight;
EncArg.args.enc_init.cmn.in_gop_num = mpeg4_arg->IDRPeriod;
EncArg.args.enc_init.cmn.in_ms_mode = mpeg4_arg->SliceMode;
EncArg.args.enc_init.cmn.in_ms_arg = mpeg4_arg->SliceArgument;
EncArg.args.enc_init.cmn.in_mb_refresh = mpeg4_arg->RandomIntraMBRefresh;
/* rate control*/
EncArg.args.enc_init.cmn.in_rc_fr_en = mpeg4_arg->EnableFRMRateControl;
if ((mpeg4_arg->QSCodeMin > 31) || (mpeg4_arg->QSCodeMax > 31)) {
ALOGE("SsbSipMfcEncInit] No such Min/Max QP is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_rc_qbound_min = mpeg4_arg->QSCodeMin;
EncArg.args.enc_init.cmn.in_rc_qbound_max = mpeg4_arg->QSCodeMax;
EncArg.args.enc_init.cmn.in_rc_rpara = mpeg4_arg->CBRPeriodRf;
/* pad control */
EncArg.args.enc_init.cmn.in_pad_ctrl_on = mpeg4_arg->PadControlOn;
if ((mpeg4_arg->LumaPadVal > 255) || (mpeg4_arg->CbPadVal > 255) || (mpeg4_arg->CrPadVal > 255)) {
ALOGE("SsbSipMfcEncInit] No such Pad value is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_y_pad_val = mpeg4_arg->LumaPadVal;
EncArg.args.enc_init.cmn.in_cb_pad_val = mpeg4_arg->CbPadVal;
EncArg.args.enc_init.cmn.in_cr_pad_val = mpeg4_arg->CrPadVal;
/* Input stream Mode NV12_Linear or NV12_Tile*/
EncArg.args.enc_init.cmn.in_frame_map = mpeg4_arg->FrameMap;
EncArg.args.enc_init.cmn.in_rc_bitrate = mpeg4_arg->Bitrate;
if ((mpeg4_arg->FrameQp > 31) || (mpeg4_arg->FrameQp_P > 31)) {
ALOGE("SsbSipMfcEncInit] No such FrameQp is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_vop_quant = mpeg4_arg->FrameQp;
EncArg.args.enc_init.cmn.in_vop_quant_p = mpeg4_arg->FrameQp_P;
/* MPEG4 only */
EncArg.args.enc_init.codec.mpeg4.in_profile = mpeg4_arg->ProfileIDC;
EncArg.args.enc_init.codec.mpeg4.in_level = mpeg4_arg->LevelIDC;
if (mpeg4_arg->FrameQp_B > 31) {
ALOGE("SsbSipMfcEncInit] No such FrameQp is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.codec.mpeg4.in_vop_quant_b = mpeg4_arg->FrameQp_B;
if (mpeg4_arg->NumberBFrames > 2) {
ALOGE("SsbSipMfcEncInit] No such BframeNum is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.codec.mpeg4.in_bframenum = mpeg4_arg->NumberBFrames;
EncArg.args.enc_init.codec.mpeg4.in_quart_pixel = mpeg4_arg->DisableQpelME;
EncArg.args.enc_init.codec.mpeg4.in_TimeIncreamentRes = mpeg4_arg->TimeIncreamentRes;
EncArg.args.enc_init.codec.mpeg4.in_VopTimeIncreament = mpeg4_arg->VopTimeIncreament;
break;
case H263_ENC:
h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param;
EncArg.args.enc_init.cmn.in_codec_type = pCTX->codecType;
EncArg.args.enc_init.cmn.in_width = h263_arg->SourceWidth;
EncArg.args.enc_init.cmn.in_height = h263_arg->SourceHeight;
EncArg.args.enc_init.cmn.in_gop_num = h263_arg->IDRPeriod;
EncArg.args.enc_init.cmn.in_ms_mode = h263_arg->SliceMode;
EncArg.args.enc_init.cmn.in_ms_arg = 0;
EncArg.args.enc_init.cmn.in_mb_refresh = h263_arg->RandomIntraMBRefresh;
/* rate control*/
EncArg.args.enc_init.cmn.in_rc_fr_en = h263_arg->EnableFRMRateControl;
if ((h263_arg->QSCodeMin > 31) || (h263_arg->QSCodeMax > 31)) {
ALOGE("SsbSipMfcEncInit] No such Min/Max QP is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_rc_qbound_min = h263_arg->QSCodeMin;
EncArg.args.enc_init.cmn.in_rc_qbound_max = h263_arg->QSCodeMax;
EncArg.args.enc_init.cmn.in_rc_rpara = h263_arg->CBRPeriodRf;
/* pad control */
EncArg.args.enc_init.cmn.in_pad_ctrl_on = h263_arg->PadControlOn;
if ((h263_arg->LumaPadVal > 255) || (h263_arg->CbPadVal > 255) || (h263_arg->CrPadVal > 255)) {
ALOGE("SsbSipMfcEncInit] No such Pad value is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_y_pad_val = h263_arg->LumaPadVal;
EncArg.args.enc_init.cmn.in_cb_pad_val = h263_arg->CbPadVal;
EncArg.args.enc_init.cmn.in_cr_pad_val = h263_arg->CrPadVal;
/* Input stream Mode NV12_Linear or NV12_Tile*/
EncArg.args.enc_init.cmn.in_frame_map = h263_arg->FrameMap;
EncArg.args.enc_init.cmn.in_rc_bitrate = h263_arg->Bitrate;
if ((h263_arg->FrameQp > 31) || (h263_arg->FrameQp_P > 31)) {
ALOGE("SsbSipMfcEncInit] No such FrameQp is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_vop_quant = h263_arg->FrameQp;
EncArg.args.enc_init.cmn.in_vop_quant_p = h263_arg->FrameQp_P;
/* H.263 only */
EncArg.args.enc_init.codec.h263.in_rc_framerate = h263_arg->FrameRate;
break;
case H264_ENC:
h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param;
EncArg.args.enc_init.cmn.in_codec_type = H264_ENC;
EncArg.args.enc_init.cmn.in_width = h264_arg->SourceWidth;
EncArg.args.enc_init.cmn.in_height = h264_arg->SourceHeight;
EncArg.args.enc_init.cmn.in_gop_num = h264_arg->IDRPeriod;
if ((h264_arg->SliceMode == 0)||(h264_arg->SliceMode == 1)||
(h264_arg->SliceMode == 2)||(h264_arg->SliceMode == 4)) {
EncArg.args.enc_init.cmn.in_ms_mode = h264_arg->SliceMode;
} else {
ALOGE("SsbSipMfcEncInit] No such slice mode is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_ms_arg = h264_arg->SliceArgument;
EncArg.args.enc_init.cmn.in_mb_refresh = h264_arg->RandomIntraMBRefresh;
/* pad control */
EncArg.args.enc_init.cmn.in_pad_ctrl_on = h264_arg->PadControlOn;
if ((h264_arg->LumaPadVal > 255) || (h264_arg->CbPadVal > 255) || (h264_arg->CrPadVal > 255)) {
ALOGE("SsbSipMfcEncInit] No such Pad value is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_y_pad_val = h264_arg->LumaPadVal;
EncArg.args.enc_init.cmn.in_cb_pad_val = h264_arg->CbPadVal;
EncArg.args.enc_init.cmn.in_cr_pad_val = h264_arg->CrPadVal;
/* Input stream Mode NV12_Linear or NV12_Tile*/
EncArg.args.enc_init.cmn.in_frame_map = h264_arg->FrameMap;
/* rate control*/
EncArg.args.enc_init.cmn.in_rc_fr_en = h264_arg->EnableFRMRateControl;
EncArg.args.enc_init.cmn.in_rc_bitrate = h264_arg->Bitrate;
if ((h264_arg->FrameQp > 51) || (h264_arg->FrameQp_P > 51)) {
ALOGE("SsbSipMfcEncInit] No such FrameQp is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_vop_quant = h264_arg->FrameQp;
EncArg.args.enc_init.cmn.in_vop_quant_p = h264_arg->FrameQp_P;
if ((h264_arg->QSCodeMin > 51) || (h264_arg->QSCodeMax > 51)) {
ALOGE("SsbSipMfcEncInit] No such Min/Max QP is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_rc_qbound_min = h264_arg->QSCodeMin;
EncArg.args.enc_init.cmn.in_rc_qbound_max = h264_arg->QSCodeMax;
EncArg.args.enc_init.cmn.in_rc_rpara = h264_arg->CBRPeriodRf;
/* H.264 Only */
EncArg.args.enc_init.codec.h264.in_profile = h264_arg->ProfileIDC;
EncArg.args.enc_init.codec.h264.in_level = h264_arg->LevelIDC;
if (h264_arg->FrameQp_B > 51) {
ALOGE("SsbSipMfcEncInit] No such FrameQp is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.codec.h264.in_vop_quant_b = h264_arg->FrameQp_B;
if (h264_arg->NumberBFrames > 2) {
ALOGE("SsbSipMfcEncInit] No such BframeNum is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.codec.h264.in_bframenum = h264_arg->NumberBFrames;
EncArg.args.enc_init.codec.h264.in_interlace_mode = h264_arg->PictureInterlace;
if ((h264_arg->NumberRefForPframes > 2)||(h264_arg->NumberReferenceFrames >2)) {
ALOGE("SsbSipMfcEncInit] No such ref Num is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.codec.h264.in_reference_num = h264_arg->NumberReferenceFrames;
EncArg.args.enc_init.codec.h264.in_ref_num_p = h264_arg->NumberRefForPframes;
EncArg.args.enc_init.codec.h264.in_rc_framerate = h264_arg->FrameRate;
EncArg.args.enc_init.codec.h264.in_rc_mb_en = h264_arg->EnableMBRateControl;
EncArg.args.enc_init.codec.h264.in_rc_mb_dark_dis = h264_arg->DarkDisable;
EncArg.args.enc_init.codec.h264.in_rc_mb_smooth_dis = h264_arg->SmoothDisable;
EncArg.args.enc_init.codec.h264.in_rc_mb_static_dis = h264_arg->StaticDisable;
EncArg.args.enc_init.codec.h264.in_rc_mb_activity_dis = h264_arg->ActivityDisable;
EncArg.args.enc_init.codec.h264.in_deblock_dis = h264_arg->LoopFilterDisable;
if ((abs(h264_arg->LoopFilterAlphaC0Offset) > 6) || (abs(h264_arg->LoopFilterBetaOffset) > 6)) {
ALOGE("SsbSipMfcEncInit] No such AlphaC0Offset or BetaOffset is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.codec.h264.in_deblock_alpha_c0 = h264_arg->LoopFilterAlphaC0Offset;
EncArg.args.enc_init.codec.h264.in_deblock_beta = h264_arg->LoopFilterBetaOffset;
EncArg.args.enc_init.codec.h264.in_symbolmode = h264_arg->SymbolMode;
EncArg.args.enc_init.codec.h264.in_transform8x8_mode = h264_arg->Transform8x8Mode;
/* FIXME: is it removed? */
EncArg.args.enc_init.codec.h264.in_md_interweight_pps = 300;
EncArg.args.enc_init.codec.h264.in_md_intraweight_pps = 170;
break;
default:
ALOGE("SsbSipMfcEncInit] No such codec type is supported");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init.cmn.in_mapped_addr = pCTX->mapped_addr;
ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_INIT, &EncArg);
if (EncArg.ret_code != MFC_OK) {
ALOGE("SsbSipMfcEncInit] IOCTL_MFC_ENC_INIT failed");
return MFC_RET_ENC_INIT_FAIL;
}
pCTX->virStrmBuf = EncArg.args.enc_init.cmn.out_u_addr.strm_ref_y;
pCTX->phyStrmBuf = EncArg.args.enc_init.cmn.out_p_addr.strm_ref_y;
pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE;
pCTX->encodedHeaderSize = EncArg.args.enc_init.cmn.out_header_size;
pCTX->virMvRefYC = EncArg.args.enc_init.cmn.out_u_addr.mv_ref_yc;
pCTX->inter_buff_status |= MFC_USE_STRM_BUFF;
return MFC_RET_OK;
}
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle)
{
int ret_code;
_MFCLIB *pCTX;
struct mfc_common_args EncArg;
if (openHandle == NULL) {
ALOGE("SsbSipMfcEncExe] openHandle is NULL");
return MFC_RET_INVALID_PARAM;
}
pCTX = (_MFCLIB *)openHandle;
memset(&EncArg, 0x00, sizeof(struct mfc_common_args));
EncArg.args.enc_exe.in_codec_type = pCTX->codecType;
EncArg.args.enc_exe.in_Y_addr = (unsigned int)pCTX->phyFrmBuf.luma;
EncArg.args.enc_exe.in_CbCr_addr = (unsigned int)pCTX->phyFrmBuf.chroma;
#if 0 /* peter for debug */
EncArg.args.enc_exe.in_Y_addr_vir = (unsigned int)pCTX->virFrmBuf.luma;
EncArg.args.enc_exe.in_CbCr_addr_vir = (unsigned int)pCTX->virFrmBuf.chroma;
#endif
EncArg.args.enc_exe.in_frametag = pCTX->inframetag;
if (pCTX->encode_cnt == 0) {
EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf;
EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf;
} else {
EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2);
EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2);
}
ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_EXE, &EncArg);
if (EncArg.ret_code != MFC_OK) {
ALOGE("SsbSipMfcEncExe] IOCTL_MFC_ENC_EXE failed(ret : %d)", EncArg.ret_code);
return MFC_RET_ENC_EXE_ERR;
}
pCTX->encodedDataSize = EncArg.args.enc_exe.out_encoded_size;
pCTX->encodedframeType = EncArg.args.enc_exe.out_frame_type;
pCTX->encodedphyFrmBuf.luma = EncArg.args.enc_exe.out_Y_addr;
pCTX->encodedphyFrmBuf.chroma = EncArg.args.enc_exe.out_CbCr_addr;
pCTX->outframetagtop = EncArg.args.enc_exe.out_frametag_top;
pCTX->outframetagbottom = EncArg.args.enc_exe.out_frametag_bottom;
ALOGV("SsbSipMfcEncExe] Encode success ==================");
return MFC_RET_OK;
}
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle)
{
int ret_code;
_MFCLIB *pCTX;
struct mfc_common_args free_arg;
if (openHandle == NULL) {
ALOGE("SsbSipMfcEncClose] openHandle is NULL");
return MFC_RET_INVALID_PARAM;
}
pCTX = (_MFCLIB *)openHandle;
/* FIXME: free buffer? */
if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) {
free_arg.args.mem_free.key = pCTX->virFrmBuf.luma;
ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
}
if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) {
free_arg.args.mem_free.key = pCTX->virStrmBuf;
ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
free_arg.args.mem_free.key = pCTX->virMvRefYC;
ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
}
pCTX->inter_buff_status = MFC_USE_NONE;
munmap((void *)pCTX->mapped_addr, pCTX->mapped_size);
close(pCTX->hMFC);
free(pCTX);
return MFC_RET_OK;
}
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info)
{
int ret_code;
_MFCLIB *pCTX;
struct mfc_common_args user_addr_arg, real_addr_arg;
int y_size, c_size;
int aligned_y_size, aligned_c_size;
if (openHandle == NULL) {
ALOGE("SsbSipMfcEncGetInBuf] openHandle is NULL");
return MFC_RET_INVALID_PARAM;
}
pCTX = (_MFCLIB *) openHandle;
/* FIXME: */
y_size = pCTX->width * pCTX->height;
c_size = (pCTX->width * pCTX->height) >> 1;
/* lenear: 2KB, tile: 8KB */
aligned_y_size = Align(y_size, 64 * BUF_L_UNIT);
aligned_c_size = Align(c_size, 64 * BUF_L_UNIT);
/* Allocate luma & chroma buf */
user_addr_arg.args.mem_alloc.type = ENCODER;
user_addr_arg.args.mem_alloc.buff_size = aligned_y_size + aligned_c_size;
user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr;
ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg);
if (ret_code < 0) {
ALOGE("SsbSipMfcEncGetInBuf] IOCTL_MFC_GET_IN_BUF failed");
return MFC_RET_ENC_GET_INBUF_FAIL;
}
pCTX->virFrmBuf.luma = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset;
pCTX->virFrmBuf.chroma = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset + (unsigned int)aligned_y_size;
real_addr_arg.args.real_addr.key = user_addr_arg.args.mem_alloc.offset;
ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_REAL_ADDR, &real_addr_arg);
if (ret_code < 0) {
ALOGE("SsbSipMfcEncGetInBuf] IOCTL_MFC_GET_REAL_ADDR failed");
return MFC_RET_ENC_GET_INBUF_FAIL;
}
pCTX->phyFrmBuf.luma = real_addr_arg.args.real_addr.addr;
pCTX->phyFrmBuf.chroma = real_addr_arg.args.real_addr.addr + (unsigned int)aligned_y_size;
pCTX->sizeFrmBuf.luma = (unsigned int)y_size;
pCTX->sizeFrmBuf.chroma = (unsigned int)c_size;
pCTX->inter_buff_status |= MFC_USE_YUV_BUFF;
input_info->YPhyAddr = (void*)pCTX->phyFrmBuf.luma;
input_info->CPhyAddr = (void*)pCTX->phyFrmBuf.chroma;
input_info->YVirAddr = (void*)pCTX->virFrmBuf.luma;
input_info->CVirAddr = (void*)pCTX->virFrmBuf.chroma;
return MFC_RET_OK;
}
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info)
{
_MFCLIB *pCTX;
int ret_code;
struct mfc_common_args user_addr_arg, real_addr_arg;
int y_size, c_size;
int aligned_y_size, aligned_c_size;
if (openHandle == NULL) {
ALOGE("SsbSipMfcEncSetInBuf] openHandle is NULL");
return MFC_RET_INVALID_PARAM;
}
ALOGV("SsbSipMfcEncSetInBuf] input_info->YPhyAddr & input_info->CPhyAddr should be 64KB aligned");
pCTX = (_MFCLIB *) openHandle;
/* FIXME: */
y_size = pCTX->width * pCTX->height;
c_size = (pCTX->width * pCTX->height) >> 1;
/* lenear: 2KB, tile: 8KB */
aligned_y_size = Align(y_size, 64 * BUF_L_UNIT);
aligned_c_size = Align(c_size, 64 * BUF_L_UNIT);
pCTX->phyFrmBuf.luma = (unsigned int)input_info->YPhyAddr;
pCTX->phyFrmBuf.chroma = (unsigned int)input_info->CPhyAddr;
pCTX->sizeFrmBuf.luma = (unsigned int)input_info->YSize;
pCTX->sizeFrmBuf.chroma = (unsigned int)input_info->CSize;
return MFC_RET_OK;
}
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info)
{
_MFCLIB *pCTX;
if (openHandle == NULL) {
ALOGE("SsbSipMfcEncGetOutBuf] openHandle is NULL");
return MFC_RET_INVALID_PARAM;
}
pCTX = (_MFCLIB *)openHandle;
output_info->headerSize = pCTX->encodedHeaderSize;
output_info->dataSize = pCTX->encodedDataSize;
output_info->frameType = pCTX->encodedframeType;
if (pCTX->encode_cnt == 0) {
output_info->StrmPhyAddr = (void *)pCTX->phyStrmBuf;
output_info->StrmVirAddr = (unsigned char *)pCTX->virStrmBuf + pCTX->mapped_addr;
} else {
output_info->StrmPhyAddr = (unsigned char *)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2);
output_info->StrmVirAddr = (unsigned char *)pCTX->virStrmBuf + pCTX->mapped_addr + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2);
}
pCTX->encode_cnt ++;
pCTX->encode_cnt %= 2;
output_info->encodedYPhyAddr = (void*)pCTX->encodedphyFrmBuf.luma;
output_info->encodedCPhyAddr = (void*)pCTX->encodedphyFrmBuf.chroma;
return MFC_RET_OK;
}
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize)
{
_MFCLIB *pCTX;
if (openHandle == NULL) {
ALOGE("SsbSipMfcEncSetOutBuf] openHandle is NULL");
return MFC_RET_INVALID_PARAM;
}
pCTX = (_MFCLIB *) openHandle;
pCTX->phyStrmBuf = (int)phyOutbuf;
pCTX->virStrmBuf = (int)virOutbuf;
pCTX->sizeStrmBuf = outputBufferSize;
return MFC_RET_OK;
}
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value)
{
int ret_code;
_MFCLIB *pCTX;
struct mfc_common_args EncArg;
struct mfc_enc_vui_info vui_info;
struct mfc_enc_hier_p_qp hier_p_qp;
#ifdef S3D_SUPPORT
struct mfc_enc_set_config set_info;
struct mfc_frame_packing *frame_packing;
#endif
if (openHandle == NULL) {
ALOGE("SsbSipMfcEncSetConfig] openHandle is NULL");
return MFC_RET_INVALID_PARAM;
}
if (value == NULL) {
ALOGE("SsbSipMfcEncSetConfig] value is NULL");
return MFC_RET_INVALID_PARAM;
}
pCTX = (_MFCLIB *) openHandle;
memset(&EncArg, 0x00, sizeof(struct mfc_common_args));
#ifdef S3D_SUPPORT
EncArg.args.config.type = conf_type;
switch (conf_type) {
case MFC_ENC_SETCONF_FRAME_TAG:
pCTX->inframetag = *((unsigned int *)value);
return MFC_RET_OK;
case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP:
set_info = *((struct mfc_enc_set_config *) value);
EncArg.args.config.args.basic.values[0] = set_info.enable;
if (set_info.enable == 2)
EncArg.args.config.args.basic.values[1] = set_info.number;
else
EncArg.args.config.args.basic.values[1] = 0;
break;
case MFC_ENC_SETCONF_VUI_INFO:
set_info = *((struct mfc_enc_set_config *) value);
EncArg.args.config.args.basic.values[0] = set_info.enable;
if (set_info.enable == 255) //Re-check this part of code with Jeongtae Park
EncArg.args.config.args.basic.values[1] = set_info.number;
else
EncArg.args.config.args.basic.values[1] = 0;
EncArg.args.config.args.basic.values[1] = set_info.number;
break;
case MFC_ENC_SETCONF_FRAME_PACKING:
frame_packing = (struct mfc_frame_packing *)value;
/*
memcpy(&EncArg.args.config.args.frame_packing, frame_packing,
sizeof(struct mfc_frame_packing));
*/
EncArg.args.config.args.basic.values[0] = frame_packing->arrangement_type;
EncArg.args.config.args.basic.values[1] = frame_packing->current_frame_is_frame0_flag;
break;
case MFC_ENC_SETCONF_FRAME_TYPE:
case MFC_ENC_SETCONF_CHANGE_FRAME_RATE:
case MFC_ENC_SETCONF_CHANGE_BIT_RATE:
case MFC_ENC_SETCONF_I_PERIOD:
case MFC_ENC_SETCONF_HIER_P:
case MFC_ENC_SETCONF_SEI_GEN:
EncArg.args.config.args.basic.values[0] = *((int *) value);
EncArg.args.config.args.basic.values[1] = 0;
break;
default:
ALOGE("SsbSipMfcEncSetConfig] not supported type");
return MFC_RET_ENC_SET_CONF_FAIL;
}
#else
EncArg.args.set_config.in_config_param = conf_type;
switch (conf_type) {
case MFC_ENC_SETCONF_FRAME_TAG:
pCTX->inframetag = *((unsigned int *)value);
return MFC_RET_OK;
case MFC_ENC_SETCONF_VUI_INFO:
vui_info = *((struct mfc_enc_vui_info *) value);
EncArg.args.set_config.in_config_value[0] = (int)(vui_info.aspect_ratio_idc);
EncArg.args.set_config.in_config_value[1] = 0;
break;
case MFC_ENC_SETCONF_HIER_P:
hier_p_qp = *((struct mfc_enc_hier_p_qp *) value);
EncArg.args.set_config.in_config_value[0] = (int)(hier_p_qp.t0_frame_qp);
EncArg.args.set_config.in_config_value[1] = (int)(hier_p_qp.t2_frame_qp);
EncArg.args.set_config.in_config_value[2] = (int)(hier_p_qp.t3_frame_qp);
break;
default:
EncArg.args.set_config.in_config_value[0] = *((int *) value);
EncArg.args.set_config.in_config_value[1] = 0;
break;
}
#endif
ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &EncArg);
if (EncArg.ret_code != MFC_OK) {
ALOGE("SsbSipMfcEncSetConfig] IOCTL_MFC_SET_CONFIG failed(ret : %d)", EncArg.ret_code);
return MFC_RET_ENC_SET_CONF_FAIL;
}
return MFC_RET_OK;
}
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value)
{
_MFCLIB *pCTX;
/*
unsigned int *encoded_header_size;
*/
pCTX = (_MFCLIB *)openHandle;
if (openHandle == NULL) {
ALOGE("SsbSipMfcEncGetConfig] openHandle is NULL");
return MFC_RET_INVALID_PARAM;
}
if (value == NULL) {
ALOGE("SsbSipMfcEncGetConfig] value is NULL");
return MFC_RET_INVALID_PARAM;
}
switch (conf_type) {
case MFC_ENC_GETCONF_FRAME_TAG:
*((unsigned int *)value) = pCTX->outframetagtop;
break;
#if 0
case MFC_ENC_GETCONF_HEADER_SIZE:
encoded_header_size = (unsigned int *)value;
*encoded_header_size = pCTX->encodedHeaderSize;
break;
#endif
default:
ALOGE("SsbSipMfcEncGetConfig] No such conf_type is supported.");
return MFC_RET_INVALID_PARAM;
}
return MFC_RET_OK;
}

View File

@@ -0,0 +1,409 @@
/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Global header for Samsung MFC (Multi Function Codec - FIMV) driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, 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 _SSBSIP_MFC_API_H_
#define _SSBSIP_MFC_API_H_
/*--------------------------------------------------------------------------------*/
/* Definition */
/*--------------------------------------------------------------------------------*/
#define MAX_DECODER_INPUT_BUFFER_SIZE (1024 * 3072)
#define MAX_ENCODER_OUTPUT_BUFFER_SIZE (1024 * 3072)
#define SUPPORT_1080P 1
#if SUPPORT_1080P
#define MMAP_BUFFER_SIZE_MMAP (70*1024*1024) /* only C110 use this value. in C210, memory size is decided in menuconfig*/
#else
#define MMAP_BUFFER_SIZE_MMAP (62*1024*1024)
#endif
#define SAMSUNG_MFC_DEV_NAME "/dev/s3c-mfc"
/*--------------------------------------------------------------------------------*/
/* Structure and Type */
/*--------------------------------------------------------------------------------*/
typedef enum {
H264_DEC,
VC1_DEC, /* VC1 advaced Profile decoding */
MPEG4_DEC,
XVID_DEC,
MPEG1_DEC,
MPEG2_DEC,
H263_DEC,
VC1RCV_DEC, /* VC1 simple/main profile decoding */
FIMV1_DEC,
FIMV2_DEC,
FIMV3_DEC,
FIMV4_DEC,
H264_ENC,
MPEG4_ENC,
H263_ENC,
UNKNOWN_TYPE
} SSBSIP_MFC_CODEC_TYPE;
typedef enum {
DONT_CARE = 0,
I_FRAME = 1,
NOT_CODED = 2
} SSBSIP_MFC_FORCE_SET_FRAME_TYPE;
typedef enum {
NV12_LINEAR = 0,
NV12_TILE
} SSBSIP_MFC_INSTRM_MODE_TYPE;
typedef enum {
NO_CACHE = 0,
CACHE = 1
} SSBIP_MFC_BUFFER_TYPE;
typedef enum {
MFC_DEC_SETCONF_POST_ENABLE = 1,
MFC_DEC_SETCONF_EXTRA_BUFFER_NUM,
MFC_DEC_SETCONF_DISPLAY_DELAY,
MFC_DEC_SETCONF_IS_LAST_FRAME,
MFC_DEC_SETCONF_SLICE_ENABLE,
MFC_DEC_SETCONF_CRC_ENABLE,
MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT,
MFC_DEC_SETCONF_FRAME_TAG,
MFC_DEC_GETCONF_CRC_DATA,
MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT,
MFC_DEC_GETCONF_CROP_INFO,
MFC_DEC_GETCONF_FRAME_TAG,
/* C210 specific feature */
MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY,
MFC_DEC_SETCONF_DPB_FLUSH,
MFC_DEC_SETCONF_PIXEL_CACHE,
#ifndef S3D_SUPPORT
MFC_DEC_GETCONF_WIDTH_HEIGHT
#else
MFC_DEC_GETCONF_WIDTH_HEIGHT,
MFC_DEC_SETCONF_SEI_PARSE,
MFC_DEC_GETCONF_FRAME_PACKING
#endif
} SSBSIP_MFC_DEC_CONF;
typedef enum {
MFC_ENC_SETCONF_FRAME_TYPE = 100,
MFC_ENC_SETCONF_CHANGE_FRAME_RATE,
MFC_ENC_SETCONF_CHANGE_BIT_RATE,
MFC_ENC_SETCONF_FRAME_TAG,
MFC_ENC_SETCONF_ALLOW_FRAME_SKIP,
MFC_ENC_GETCONF_FRAME_TAG,
/* C210 specific feature */
MFC_ENC_SETCONF_VUI_INFO,
MFC_ENC_SETCONF_I_PERIOD,
#ifndef S3D_SUPPORT
MFC_ENC_SETCONF_HIER_P
#else
MFC_ENC_SETCONF_HIER_P,
MFC_ENC_SETCONF_SEI_GEN,
MFC_ENC_SETCONF_FRAME_PACKING
#endif
} SSBSIP_MFC_ENC_CONF;
typedef enum {
MFC_GETOUTBUF_STATUS_NULL = 0,
MFC_GETOUTBUF_DECODING_ONLY = 1,
MFC_GETOUTBUF_DISPLAY_DECODING,
MFC_GETOUTBUF_DISPLAY_ONLY,
MFC_GETOUTBUF_DISPLAY_END,
MFC_GETOUTBUF_CHANGE_RESOL
} SSBSIP_MFC_DEC_OUTBUF_STATUS;
typedef enum {
MFC_FRAME_TYPE_NOT_CODED,
MFC_FRAME_TYPE_I_FRAME,
MFC_FRAME_TYPE_P_FRAME,
MFC_FRAME_TYPE_B_FRAME,
MFC_FRAME_TYPE_OTHERS
} SSBSIP_MFC_FRAME_TYPE;
typedef enum {
MFC_RET_OK = 1,
MFC_RET_FAIL = -1000,
MFC_RET_OPEN_FAIL = -1001,
MFC_RET_CLOSE_FAIL = -1002,
MFC_RET_DEC_INIT_FAIL = -2000,
MFC_RET_DEC_EXE_TIME_OUT = -2001,
MFC_RET_DEC_EXE_ERR = -2002,
MFC_RET_DEC_GET_INBUF_FAIL = -2003,
MFC_RET_DEC_SET_INBUF_FAIL = -2004,
MFC_RET_DEC_GET_OUTBUF_FAIL = -2005,
MFC_RET_DEC_GET_CONF_FAIL = -2006,
MFC_RET_DEC_SET_CONF_FAIL = -2007,
MFC_RET_ENC_INIT_FAIL = -3000,
MFC_RET_ENC_EXE_TIME_OUT = -3001,
MFC_RET_ENC_EXE_ERR = -3002,
MFC_RET_ENC_GET_INBUF_FAIL = -3003,
MFC_RET_ENC_SET_INBUF_FAIL = -3004,
MFC_RET_ENC_GET_OUTBUF_FAIL = -3005,
MFC_RET_ENC_SET_OUTBUF_FAIL = -3006,
MFC_RET_ENC_GET_CONF_FAIL = -3007,
MFC_RET_ENC_SET_CONF_FAIL = -3008,
MFC_RET_INVALID_PARAM = -4000
} SSBSIP_MFC_ERROR_CODE;
typedef struct {
void *YPhyAddr; /* [OUT] physical address of Y */
void *CPhyAddr; /* [OUT] physical address of CbCr */
void *YVirAddr; /* [OUT] virtual address of Y */
void *CVirAddr; /* [OUT] virtual address of CbCr */
int img_width; /* [OUT] width of real image */
int img_height; /* [OUT] height of real image */
int buf_width; /* [OUT] width aligned to 16 */
int buf_height; /* [OUT] height alighed to 16 */
int timestamp_top; /* [OUT] timestamp of top filed(This is used for interlaced stream) */
int timestamp_bottom; /* [OUT] timestamp of bottom filed(This is used for interlaced stream) */
int consumedByte; /* [OUT] the number of byte consumed during decoding */
int res_change; /* [OUT] whether resolution is changed or not. 0: not change, 1: increased, 2: decreased */
int crop_top_offset; /* [OUT] crop information, top_offset */
int crop_bottom_offset; /* [OUT] crop information, bottom_offset */
int crop_left_offset; /* [OUT] crop information, left_offset */
int crop_right_offset; /* [OUT] crop information, right_offset */
int disp_pic_frame_type; /* [OUT] display picture frame type information */
/* C210 UMP feature */
unsigned int y_cookie; /* [OUT] cookie for Y address */
unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */
} SSBSIP_MFC_DEC_OUTPUT_INFO;
typedef struct {
void *YPhyAddr; /* [IN/OUT] physical address of Y */
void *CPhyAddr; /* [IN/OUT] physical address of CbCr */
void *YVirAddr; /* [IN/OUT] virtual address of Y */
void *CVirAddr; /* [IN/OUT] virtual address of CbCr */
int YSize; /* [IN/OUT] input size of Y data */
int CSize; /* [IN/OUT] input size of CbCr data */
/* C210 UMP feature */
unsigned int y_cookie; /* [OUT] cookie for Y address */
unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */
} SSBSIP_MFC_ENC_INPUT_INFO;
typedef struct {
unsigned int dataSize; /* [OUT] encoded data size(without header) */
unsigned int headerSize; /* [OUT] encoded header size */
unsigned int frameType; /* [OUT] frame type of encoded stream */
void *StrmPhyAddr; /* [OUT] physical address of Y */
void *StrmVirAddr; /* [OUT] virtual address of Y */
void *encodedYPhyAddr; /* [OUT] physical address of Y which is flushed */
void *encodedCPhyAddr; /* [OUT] physical address of C which is flushed */
/* C210 UMP feature */
unsigned int strm_cookie; /* [OUT] cooke for stream buffer */
unsigned int y_encoded_cookie; /* [OUT] cookie for Y address */
unsigned int c_encoded_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */
} SSBSIP_MFC_ENC_OUTPUT_INFO;
typedef struct {
/* common parameters */
SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */
int SourceWidth; /* [IN] width of video to be encoded */
int SourceHeight; /* [IN] height of video to be encoded */
int IDRPeriod; /* [IN] GOP number(interval of I-frame) */
int SliceMode; /* [IN] Multi slice mode */
int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */
int EnableFRMRateControl; /* [IN] frame based rate control enable */
int Bitrate; /* [IN] rate control parameter(bit rate) */
int FrameQp; /* [IN] The quantization parameter of the frame */
int FrameQp_P; /* [IN] The quantization parameter of the P frame */
int QSCodeMax; /* [IN] Maximum Quantization value */
int QSCodeMin; /* [IN] Minimum Quantization value */
int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */
int PadControlOn; /* [IN] Enable padding control */
int LumaPadVal; /* [IN] Luma pel value used to fill padding area */
int CbPadVal; /* [IN] CB pel value used to fill padding area */
int CrPadVal; /* [IN] CR pel value used to fill padding area */
int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */
/* H.264 specific parameters */
int ProfileIDC; /* [IN] profile */
int LevelIDC; /* [IN] level */
int FrameQp_B; /* [IN] The quantization parameter of the B frame */
int FrameRate; /* [IN] rate control parameter(frame rate) */
int SliceArgument; /* [IN] MB number or byte number */
int NumberBFrames; /* [IN] The number of consecutive B frame inserted */
int NumberReferenceFrames; /* [IN] The number of reference pictures used */
int NumberRefForPframes; /* [IN] The number of reference pictures used for encoding P pictures */
int LoopFilterDisable; /* [IN] disable the loop filter */
int LoopFilterAlphaC0Offset; /* [IN] Alpha & C0 offset for H.264 loop filter */
int LoopFilterBetaOffset; /* [IN] Beta offset for H.264 loop filter */
int SymbolMode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */
int PictureInterlace; /* [IN] Enables the interlace mode */
int Transform8x8Mode; /* [IN] Allow 8x8 transform(This is allowed only for high profile) */
int EnableMBRateControl; /* [IN] Enable macroblock-level rate control */
int DarkDisable; /* [IN] Disable adaptive rate control on dark region */
int SmoothDisable; /* [IN] Disable adaptive rate control on smooth region */
int StaticDisable; /* [IN] Disable adaptive rate control on static region */
int ActivityDisable; /* [IN] Disable adaptive rate control on high activity region */
} SSBSIP_MFC_ENC_H264_PARAM;
typedef struct {
/* common parameters */
SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */
int SourceWidth; /* [IN] width of video to be encoded */
int SourceHeight; /* [IN] height of video to be encoded */
int IDRPeriod; /* [IN] GOP number(interval of I-frame) */
int SliceMode; /* [IN] Multi slice mode */
int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */
int EnableFRMRateControl; /* [IN] frame based rate control enable */
int Bitrate; /* [IN] rate control parameter(bit rate) */
int FrameQp; /* [IN] The quantization parameter of the frame */
int FrameQp_P; /* [IN] The quantization parameter of the P frame */
int QSCodeMax; /* [IN] Maximum Quantization value */
int QSCodeMin; /* [IN] Minimum Quantization value */
int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */
int PadControlOn; /* [IN] Enable padding control */
int LumaPadVal; /* [IN] Luma pel value used to fill padding area */
int CbPadVal; /* [IN] CB pel value used to fill padding area */
int CrPadVal; /* [IN] CR pel value used to fill padding area */
int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */
/* MPEG4 specific parameters */
int ProfileIDC; /* [IN] profile */
int LevelIDC; /* [IN] level */
int FrameQp_B; /* [IN] The quantization parameter of the B frame */
int TimeIncreamentRes; /* [IN] frame rate */
int VopTimeIncreament; /* [IN] frame rate */
int SliceArgument; /* [IN] MB number or byte number */
int NumberBFrames; /* [IN] The number of consecutive B frame inserted */
int DisableQpelME; /* [IN] disable quarter-pixel motion estimation */
} SSBSIP_MFC_ENC_MPEG4_PARAM;
typedef struct {
/* common parameters */
SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */
int SourceWidth; /* [IN] width of video to be encoded */
int SourceHeight; /* [IN] height of video to be encoded */
int IDRPeriod; /* [IN] GOP number(interval of I-frame) */
int SliceMode; /* [IN] Multi slice mode */
int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */
int EnableFRMRateControl; /* [IN] frame based rate control enable */
int Bitrate; /* [IN] rate control parameter(bit rate) */
int FrameQp; /* [IN] The quantization parameter of the frame */
int FrameQp_P; /* [IN] The quantization parameter of the P frame */
int QSCodeMax; /* [IN] Maximum Quantization value */
int QSCodeMin; /* [IN] Minimum Quantization value */
int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */
int PadControlOn; /* [IN] Enable padding control */
int LumaPadVal; /* [IN] Luma pel value used to fill padding area */
int CbPadVal; /* [IN] CB pel value used to fill padding area */
int CrPadVal; /* [IN] CR pel value used to fill padding area */
int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */
/* H.263 specific parameters */
int FrameRate; /* [IN] rate control parameter(frame rate) */
} SSBSIP_MFC_ENC_H263_PARAM;
typedef struct {
int width;
int height;
int buf_width;
int buf_height;
} SSBSIP_MFC_IMG_RESOLUTION;
typedef struct {
int crop_top_offset;
int crop_bottom_offset;
int crop_left_offset;
int crop_right_offset;
} SSBSIP_MFC_CROP_INFORMATION;
#ifdef S3D_SUPPORT
typedef struct {
int available;
unsigned int arrangement_id;
int arrangement_cancel_flag;
unsigned char arrangement_type;
int quincunx_sampling_flag;
unsigned char content_interpretation_type;
int spatial_flipping_flag;
int frame0_flipped_flag;
int field_views_flag;
int current_frame_is_frame0_flag;
unsigned char frame0_grid_pos_x;
unsigned char frame0_grid_pos_y;
unsigned char frame1_grid_pos_x;
unsigned char frame1_grid_pos_y;
} SSBSIP_MFC_FRAME_PACKING;
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*--------------------------------------------------------------------------------*/
/* Decoding APIs */
/*--------------------------------------------------------------------------------*/
void *SsbSipMfcDecOpen(void);
void *SsbSipMfcDecOpenExt(void *value);
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng);
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill);
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle);
void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize);
#if (defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(USE_UMP))
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, unsigned int secure_id, int size);
#else
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size);
#endif
SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info);
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value);
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value);
/*--------------------------------------------------------------------------------*/
/* Encoding APIs */
/*--------------------------------------------------------------------------------*/
void *SsbSipMfcEncOpen(void);
void *SsbSipMfcEncOpenExt(void *value);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value);
#ifdef __cplusplus
}
#endif
#endif /* _SSBSIP_MFC_API_H_ */

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Global header for Samsung MFC (Multi Function Codec - FIMV) driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, 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 __MFC_ERRNO_H
#define __MFC_ERRNO_H __FILE__
enum mfc_ret_code {
MFC_OK = 1,
MFC_FAIL = -1000,
MFC_OPEN_FAIL = -1001,
MFC_CLOSE_FAIL = -1002,
MFC_DEC_INIT_FAIL = -2000,
MFC_DEC_EXE_TIME_OUT = -2001,
MFC_DEC_EXE_ERR = -2002,
MFC_DEC_GET_INBUF_FAIL = 2003,
MFC_DEC_SET_INBUF_FAIL = 2004,
MFC_DEC_GET_OUTBUF_FAIL = -2005,
MFC_DEC_GET_CONF_FAIL = -2006,
MFC_DEC_SET_CONF_FAIL = -2007,
MFC_ENC_INIT_FAIL = -3000,
MFC_ENC_EXE_TIME_OUT = -3001,
MFC_ENC_EXE_ERR = -3002,
MFC_ENC_GET_INBUF_FAIL = -3003,
MFC_ENC_SET_INBUF_FAIL = -3004,
MFC_ENC_GET_OUTBUF_FAIL = -3005,
MFC_ENC_SET_OUTBUF_FAIL = -3006,
MFC_ENC_GET_CONF_FAIL = -3007,
MFC_ENC_SET_CONF_FAIL = -3008,
MFC_STATE_INVALID = -4000,
MFC_DEC_HEADER_FAIL = -4001,
MFC_DEC_INIT_BUF_FAIL = -4002,
MFC_ENC_HEADER_FAIL = -5000,
MFC_ENC_PARAM_FAIL = -5001,
MFC_FRM_BUF_SIZE_FAIL = -6000,
MFC_FW_LOAD_FAIL = -6001,
MFC_FW_INIT_FAIL = -6002,
MFC_INST_NUM_EXCEEDED_FAIL = -6003,
MFC_MEM_ALLOC_FAIL = -6004,
MFC_MEM_INVALID_ADDR_FAIL = -6005,
MFC_MEM_MAPPING_FAIL = -6006,
MFC_GET_CONF_FAIL = -6007,
MFC_SET_CONF_FAIL = -6008,
MFC_INVALID_PARAM_FAIL = -6009,
MFC_API_FAIL = -9000,
MFC_CMD_FAIL = -1003,
MFC_SLEEP_FAIL = -1010,
MFC_WAKEUP_FAIL = -1020,
MFC_CLK_ON_FAIL = -1030,
MFC_CLK_OFF_FAIL = -1030,
MFC_PWR_ON_FAIL = -1040,
MFC_PWR_OFF_FAIL = -1041,
} ;
#endif /* __MFC_ERRNO_H */

View File

@@ -0,0 +1,524 @@
/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Global header for Samsung MFC (Multi Function Codec - FIMV) driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, 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 __MFC_INTERFACE_H
#define __MFC_INTERFACE_H __FILE__
#include "mfc_errno.h"
#include "SsbSipMfcApi.h"
#define IOCTL_MFC_DEC_INIT (0x00800001)
#define IOCTL_MFC_ENC_INIT (0x00800002)
#define IOCTL_MFC_DEC_EXE (0x00800003)
#define IOCTL_MFC_ENC_EXE (0x00800004)
#define IOCTL_MFC_GET_IN_BUF (0x00800010)
#define IOCTL_MFC_FREE_BUF (0x00800011)
#define IOCTL_MFC_GET_REAL_ADDR (0x00800012)
#define IOCTL_MFC_GET_MMAP_SIZE (0x00800014)
#define IOCTL_MFC_SET_IN_BUF (0x00800018)
#define IOCTL_MFC_SET_CONFIG (0x00800101)
#define IOCTL_MFC_GET_CONFIG (0x00800102)
#define IOCTL_MFC_SET_BUF_CACHE (0x00800201)
/* MFC H/W support maximum 32 extra DPB. */
#define MFC_MAX_EXTRA_DPB 5
#define MFC_MAX_DISP_DELAY 0xF
#define MFC_LIB_VER_MAJOR 1
#define MFC_LIB_VER_MINOR 00
#define BUF_L_UNIT (1024)
#define Align(x, alignbyte) (((x)+(alignbyte)-1)/(alignbyte)*(alignbyte))
enum inst_type {
DECODER = 0x1,
ENCODER = 0x2,
};
typedef enum {
MFC_UNPACKED_PB = 0,
MFC_PACKED_PB = 1
} mfc_packed_mode;
typedef enum
{
MFC_USE_NONE = 0x00,
MFC_USE_YUV_BUFF = 0x01,
MFC_USE_STRM_BUFF = 0x10
} s3c_mfc_interbuff_status;
typedef struct
{
int luma0; /* per frame (or top field) */
int chroma0; /* per frame (or top field) */
int luma1; /* per frame (or bottom field) */
int chroma1; /* per frame (or bottom field) */
} SSBSIP_MFC_CRC_DATA;
struct mfc_strm_ref_buf_arg {
unsigned int strm_ref_y;
unsigned int mv_ref_yc;
};
struct mfc_frame_buf_arg {
unsigned int luma;
unsigned int chroma;
};
struct mfc_enc_init_common_arg {
SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
int in_width; /* [IN] width of YUV420 frame to be encoded */
int in_height; /* [IN] height of YUV420 frame to be encoded */
int in_gop_num; /* [IN] GOP Number (interval of I-frame) */
int in_vop_quant; /* [IN] VOP quant */
int in_vop_quant_p; /* [IN] VOP quant for P frame */
/* [IN] RC enable */
/* [IN] RC enable (0:disable, 1:frame level RC) */
int in_rc_fr_en;
int in_rc_bitrate; /* [IN] RC parameter (bitrate in kbps) */
int in_rc_qbound_min; /* [IN] RC parameter (Q bound Min) */
int in_rc_qbound_max; /* [IN] RC parameter (Q bound Max) */
int in_rc_rpara; /* [IN] RC parameter (Reaction Coefficient) */
/* [IN] Multi-slice mode (0:single, 1:multiple) */
int in_ms_mode;
/* [IN] Multi-slice size (in num. of mb or byte) */
int in_ms_arg;
int in_mb_refresh; /* [IN] Macroblock refresh */
/* [IN] Enable (1) / Disable (0) padding with the specified values */
int in_pad_ctrl_on;
/* [IN] pad value if pad_ctrl_on is Enable */
int in_y_pad_val;
int in_cb_pad_val;
int in_cr_pad_val;
/* linear or tiled */
int in_frame_map;
unsigned int in_pixelcache;
unsigned int in_mapped_addr;
struct mfc_strm_ref_buf_arg out_u_addr;
struct mfc_strm_ref_buf_arg out_p_addr;
struct mfc_strm_ref_buf_arg out_buf_size;
unsigned int out_header_size;
};
struct mfc_enc_init_h263_arg {
int in_rc_framerate; /* [IN] RC parameter (framerate) */
};
struct mfc_enc_init_mpeg4_arg {
int in_profile; /* [IN] profile */
int in_level; /* [IN] level */
int in_vop_quant_b; /* [IN] VOP quant for B frame */
/* [IN] B frame number */
int in_bframenum;
/* [IN] Quarter-pel MC enable (1:enabled, 0:disabled) */
int in_quart_pixel;
int in_TimeIncreamentRes; /* [IN] VOP time resolution */
int in_VopTimeIncreament; /* [IN] Frame delta */
};
struct mfc_enc_init_h264_arg {
int in_profile; /* [IN] profile */
int in_level; /* [IN] level */
int in_vop_quant_b; /* [IN] VOP quant for B frame */
/* [IN] B frame number */
int in_bframenum;
/* [IN] interlace mode(0:progressive, 1:interlace) */
int in_interlace_mode;
/* [IN] reference number */
int in_reference_num;
/* [IN] reference number of P frame */
int in_ref_num_p;
int in_rc_framerate; /* [IN] RC parameter (framerate) */
int in_rc_mb_en; /* [IN] RC enable (0:disable, 1:MB level RC) */
/* [IN] MB level rate control dark region adaptive feature */
int in_rc_mb_dark_dis; /* (0:enable, 1:disable) */
/* [IN] MB level rate control smooth region adaptive feature */
int in_rc_mb_smooth_dis; /* (0:enable, 1:disable) */
/* [IN] MB level rate control static region adaptive feature */
int in_rc_mb_static_dis; /* (0:enable, 1:disable) */
/* [IN] MB level rate control activity region adaptive feature */
int in_rc_mb_activity_dis; /* (0:enable, 1:disable) */
/* [IN] disable deblocking filter idc */
int in_deblock_dis; /* (0: enable,1: disable, 2:Disable at slice boundary) */
/* [IN] slice alpha c0 offset of deblocking filter */
int in_deblock_alpha_c0;
/* [IN] slice beta offset of deblocking filter */
int in_deblock_beta;
/* [IN] ( 0 : CAVLC, 1 : CABAC ) */
int in_symbolmode;
/* [IN] (0: only 4x4 transform, 1: allow using 8x8 transform) */
int in_transform8x8_mode;
/* [IN] Inter weighted parameter for mode decision */
int in_md_interweight_pps;
/* [IN] Intra weighted parameter for mode decision */
int in_md_intraweight_pps;
};
struct mfc_enc_init_arg {
struct mfc_enc_init_common_arg cmn;
union {
struct mfc_enc_init_h264_arg h264;
struct mfc_enc_init_mpeg4_arg mpeg4;
struct mfc_enc_init_h263_arg h263;
} codec;
};
struct mfc_enc_exe_arg {
SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */
unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */
unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */
unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */
unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */
unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */
unsigned int in_frametag; /* [IN] unique frame ID */
unsigned int out_frame_type; /* [OUT] frame type */
int out_encoded_size; /* [OUT] Length of Encoded video stream */
unsigned int out_Y_addr; /* [OUT]Out-buffer addr of encoded Y component */
unsigned int out_CbCr_addr; /* [OUT]Out-buffer addr of encoded CbCr component */
unsigned int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */
unsigned int out_frametag_bottom; /* [OUT] unique frame ID of bottom field */
#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
unsigned int out_y_secure_id;
unsigned int out_c_secure_id;
#elif defined(CONFIG_S5P_VMEM)
unsigned int out_y_cookie;
unsigned int out_c_cookie;
#endif
};
struct mfc_dec_init_arg {
SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
int in_strm_buf; /* [IN] address of stream buffer */
int in_strm_size; /* [IN] filled size in stream buffer */
int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */
unsigned int in_crc; /* [IN] */
unsigned int in_pixelcache; /* [IN] */
unsigned int in_slice; /* [IN] */
unsigned int in_numextradpb; /* [IN] */
unsigned int in_mapped_addr;
int out_frm_width; /* [OUT] width of YUV420 frame */
int out_frm_height; /* [OUT] height of YUV420 frame */
int out_buf_width; /* [OUT] width of YUV420 frame */
int out_buf_height; /* [OUT] height of YUV420 frame */
int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding. */
int out_crop_right_offset; /* [OUT] crop information for h264 */
int out_crop_left_offset;
int out_crop_bottom_offset;
int out_crop_top_offset;
};
struct mfc_dec_exe_arg {
SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
int in_strm_buf; /* [IN] the physical address of STRM_BUF */
/* [IN] Size of video stream filled in STRM_BUF */
int in_strm_size;
/* [IN] the address of dpb FRAME_BUF */
struct mfc_frame_buf_arg in_frm_buf;
/* [IN] size of dpb FRAME_BUF */
struct mfc_frame_buf_arg in_frm_size;
/* [IN] Unique frame ID eg. application specific timestamp */
unsigned int in_frametag;
/* [IN] immdiate Display for seek,thumbnail and one frame */
int in_immediately_disp;
/* [OUT] the physical address of display buf */
int out_display_Y_addr;
/* [OUT] the physical address of display buf */
int out_display_C_addr;
int out_display_status;
/* [OUT] unique frame ID of an output frame or top field */
unsigned int out_frametag_top;
/* [OUT] unique frame ID of bottom field */
unsigned int out_frametag_bottom;
int out_pic_time_top;
int out_pic_time_bottom;
int out_consumed_byte;
int out_crop_right_offset;
int out_crop_left_offset;
int out_crop_bottom_offset;
int out_crop_top_offset;
/* in new driver, each buffer offset must be return to the user */
int out_y_offset;
int out_c_offset;
#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
unsigned int out_y_secure_id;
unsigned int out_c_secure_id;
#elif defined(CONFIG_S5P_VMEM)
unsigned int out_y_cookie;
unsigned int out_c_cookie;
#endif
int out_img_width; /* [OUT] width of YUV420 frame */
int out_img_height; /* [OUT] height of YUV420 frame */
int out_buf_width; /* [OUT] width of YUV420 frame */
int out_buf_height; /* [OUT] height of YUV420 frame */
int out_disp_pic_frame_type; /* [OUT] display picture frame type information */
};
#ifdef S3D_SUPPORT
struct mfc_basic_config {
int values[4];
};
struct mfc_frame_packing {
int available;
unsigned int arrangement_id;
int arrangement_cancel_flag;
unsigned char arrangement_type;
int quincunx_sampling_flag;
unsigned char content_interpretation_type;
int spatial_flipping_flag;
int frame0_flipped_flag;
int field_views_flag;
int current_frame_is_frame0_flag;
unsigned char frame0_grid_pos_x;
unsigned char frame0_grid_pos_y;
unsigned char frame1_grid_pos_x;
unsigned char frame1_grid_pos_y;
};
union _mfc_config_arg {
struct mfc_basic_config basic;
struct mfc_frame_packing frame_packing;
};
struct mfc_config_arg {
int type;
union _mfc_config_arg args;
};
#else
struct mfc_get_config_arg {
/* [IN] Configurable parameter type */
int in_config_param;
/* [IN] Values to get for the configurable parameter. */
/* Maximum four integer values can be obtained; */
int out_config_value[4];
};
struct mfc_set_config_arg {
/* [IN] Configurable parameter type */
int in_config_param;
/* [IN] Values to be set for the configurable parameter. */
/* Maximum four integer values can be set. */
int in_config_value[4];
};
#endif
struct mfc_get_real_addr_arg {
unsigned int key;
unsigned int addr;
};
struct mfc_buf_alloc_arg {
enum inst_type type;
int size;
/*
unsigned int mapped;
*/
unsigned int align;
unsigned int addr;
/*
unsigned int phys;
*/
#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
/* FIMXE: invalid secure id == -1 */
unsigned int secure_id;
#elif defined(CONFIG_S5P_VMEM)
unsigned int cookie;
#else
unsigned int offset;
#endif
};
struct mfc_buf_free_arg {
unsigned int addr;
};
/* RMVME */
struct mfc_mem_alloc_arg {
enum inst_type type;
int buff_size;
SSBIP_MFC_BUFFER_TYPE buf_cache_type;
unsigned int mapped_addr;
#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
unsigned int secure_id;
#elif defined(CONFIG_S5P_VMEM)
unsigned int cookie;
#else
unsigned int offset;
#endif
};
struct mfc_mem_free_arg {
unsigned int key;
};
/* RMVME */
union mfc_args {
/*
struct mfc_enc_init_arg enc_init;
struct mfc_enc_init_mpeg4_arg enc_init_mpeg4;
struct mfc_enc_init_mpeg4_arg enc_init_h263;
struct mfc_enc_init_h264_arg enc_init_h264;
*/
struct mfc_enc_init_arg enc_init;
struct mfc_enc_exe_arg enc_exe;
struct mfc_dec_init_arg dec_init;
struct mfc_dec_exe_arg dec_exe;
#ifdef S3D_SUPPORT
struct mfc_config_arg config;
#else
struct mfc_get_config_arg get_config;
struct mfc_set_config_arg set_config;
#endif
struct mfc_buf_alloc_arg buf_alloc;
struct mfc_buf_free_arg buf_free;
struct mfc_get_real_addr_arg real_addr;
/* RMVME */
struct mfc_mem_alloc_arg mem_alloc;
struct mfc_mem_free_arg mem_free;
/* RMVME */
};
struct mfc_common_args {
enum mfc_ret_code ret_code; /* [OUT] error code */
union mfc_args args;
};
struct mfc_enc_vui_info {
int aspect_ratio_idc;
};
struct mfc_dec_fimv1_info {
int width;
int height;
};
struct mfc_enc_hier_p_qp {
int t0_frame_qp;
int t2_frame_qp;
int t3_frame_qp;
};
#ifdef S3D_SUPPORT
struct mfc_enc_set_config {
int enable;
int number;
};
#endif
typedef struct
{
int magic;
int hMFC;
int hVMEM;
int width;
int height;
int sizeStrmBuf;
struct mfc_frame_buf_arg sizeFrmBuf;
int displayStatus;
int inter_buff_status;
unsigned int virFreeStrmAddr;
unsigned int phyStrmBuf;
unsigned int virStrmBuf;
unsigned int virMvRefYC;
struct mfc_frame_buf_arg phyFrmBuf;
struct mfc_frame_buf_arg virFrmBuf;
unsigned int mapped_addr;
unsigned int mapped_size;
struct mfc_common_args MfcArg;
SSBSIP_MFC_CODEC_TYPE codecType;
SSBSIP_MFC_DEC_OUTPUT_INFO decOutInfo;
unsigned int inframetag;
unsigned int outframetagtop;
unsigned int outframetagbottom;
unsigned int immediatelydisp;
unsigned int encodedHeaderSize;
int encodedDataSize;
unsigned int encodedframeType;
struct mfc_frame_buf_arg encodedphyFrmBuf;
unsigned int dec_crc;
unsigned int dec_pixelcache;
unsigned int dec_slice;
unsigned int dec_numextradpb;
int input_cookie;
int input_secure_id;
int input_size;
/* to support non-blocking mode */
unsigned int encode_cnt;
} _MFCLIB;
#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8))
#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8))
#endif /* __MFC_INTERFACE_H */

View File

@@ -0,0 +1,34 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_COPY_HEADERS_TO := libsecmm
LOCAL_COPY_HEADERS := \
include/mfc_errno.h \
include/mfc_interface.h \
include/SsbSipMfcApi.h
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
dec/src/SsbSipMfcDecAPI.c \
enc/src/SsbSipMfcEncAPI.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
device/samsung/$(TARGET_BOARD_PLATFORM)/include
LOCAL_MODULE := libsecmfcapi
LOCAL_PRELINK_MODULE := false
ifeq ($(BOARD_USES_MFC_FPS),true)
LOCAL_CFLAGS := -DCONFIG_MFC_FPS
endif
LOCAL_ARM_MODE := arm
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES := liblog
include $(BUILD_STATIC_LIBRARY)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,381 @@
/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Global header for Samsung MFC (Multi Function Codec - FIMV) driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, 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 _SSBSIP_MFC_API_H_
#define _SSBSIP_MFC_API_H_
/*--------------------------------------------------------------------------------*/
/* Definition */
/*--------------------------------------------------------------------------------*/
#define MAX_DECODER_INPUT_BUFFER_SIZE (1024 * 3072)
#define MAX_ENCODER_OUTPUT_BUFFER_SIZE (1024 * 3072)
#define SUPPORT_1080P 1
#if SUPPORT_1080P
#define MMAP_BUFFER_SIZE_MMAP (70*1024*1024) /* only C110 use this value. in C210, memory size is decided in menuconfig*/
#else
#define MMAP_BUFFER_SIZE_MMAP (62*1024*1024)
#endif
#define SAMSUNG_MFC_DEV_NAME "/dev/video"
#define SSBSIP_MFC_OK (1)
#define SSBSIP_MFC_FAIL (0)
/*--------------------------------------------------------------------------------*/
/* Structure and Type */
/*--------------------------------------------------------------------------------*/
typedef enum {
H264_DEC,
VC1_DEC, /* VC1 advaced Profile decoding */
MPEG4_DEC,
XVID_DEC,
MPEG1_DEC,
MPEG2_DEC,
H263_DEC,
VC1RCV_DEC, /* VC1 simple/main profile decoding */
FIMV1_DEC,
FIMV2_DEC,
FIMV3_DEC,
FIMV4_DEC,
H264_ENC,
MPEG4_ENC,
H263_ENC,
UNKNOWN_TYPE
} SSBSIP_MFC_CODEC_TYPE;
typedef enum {
DONT_CARE = 0,
I_FRAME = 1,
NOT_CODED = 2
} SSBSIP_MFC_FORCE_SET_FRAME_TYPE;
typedef enum {
NV12_LINEAR = 0,
NV12_TILE
} SSBSIP_MFC_INSTRM_MODE_TYPE;
typedef enum {
NO_CACHE = 0,
CACHE = 1
} SSBIP_MFC_BUFFER_TYPE;
typedef enum {
MFC_DEC_SETCONF_POST_ENABLE = 1,
MFC_DEC_SETCONF_EXTRA_BUFFER_NUM,
MFC_DEC_SETCONF_DISPLAY_DELAY,
MFC_DEC_SETCONF_IS_LAST_FRAME,
MFC_DEC_SETCONF_SLICE_ENABLE,
MFC_DEC_SETCONF_CRC_ENABLE,
MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT,
MFC_DEC_SETCONF_FRAME_TAG,
MFC_DEC_GETCONF_CRC_DATA,
MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT,
MFC_DEC_GETCONF_CROP_INFO,
MFC_DEC_GETCONF_FRAME_TAG,
/* C210 specific feature */
MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY,
MFC_DEC_SETCONF_DPB_FLUSH,
MFC_DEC_SETCONF_PIXEL_CACHE,
MFC_DEC_GETCONF_WIDTH_HEIGHT
} SSBSIP_MFC_DEC_CONF;
typedef enum {
MFC_ENC_SETCONF_FRAME_TYPE = 100,
MFC_ENC_SETCONF_CHANGE_FRAME_RATE,
MFC_ENC_SETCONF_CHANGE_BIT_RATE,
MFC_ENC_SETCONF_FRAME_TAG,
MFC_ENC_SETCONF_ALLOW_FRAME_SKIP,
MFC_ENC_GETCONF_FRAME_TAG,
/* C210 specific feature */
MFC_ENC_SETCONF_VUI_INFO,
MFC_ENC_SETCONF_I_PERIOD,
MFC_ENC_SETCONF_HIER_P
} SSBSIP_MFC_ENC_CONF;
typedef enum {
MFC_GETOUTBUF_STATUS_NULL = 0,
MFC_GETOUTBUF_DECODING_ONLY = 1,
MFC_GETOUTBUF_DISPLAY_DECODING,
MFC_GETOUTBUF_DISPLAY_ONLY,
MFC_GETOUTBUF_DISPLAY_END,
MFC_GETOUTBUF_CHANGE_RESOL
} SSBSIP_MFC_DEC_OUTBUF_STATUS;
typedef enum {
MFC_FRAME_TYPE_NOT_CODED,
MFC_FRAME_TYPE_I_FRAME,
MFC_FRAME_TYPE_P_FRAME,
MFC_FRAME_TYPE_B_FRAME,
MFC_FRAME_TYPE_OTHERS
} SSBSIP_MFC_FRAME_TYPE;
typedef enum {
MFC_RET_OK = 1,
MFC_RET_FAIL = -1000,
MFC_RET_OPEN_FAIL = -1001,
MFC_RET_CLOSE_FAIL = -1002,
MFC_RET_DEC_INIT_FAIL = -2000,
MFC_RET_DEC_EXE_TIME_OUT = -2001,
MFC_RET_DEC_EXE_ERR = -2002,
MFC_RET_DEC_GET_INBUF_FAIL = -2003,
MFC_RET_DEC_SET_INBUF_FAIL = -2004,
MFC_RET_DEC_GET_OUTBUF_FAIL = -2005,
MFC_RET_DEC_GET_CONF_FAIL = -2006,
MFC_RET_DEC_SET_CONF_FAIL = -2007,
MFC_RET_ENC_INIT_FAIL = -3000,
MFC_RET_ENC_EXE_TIME_OUT = -3001,
MFC_RET_ENC_EXE_ERR = -3002,
MFC_RET_ENC_GET_INBUF_FAIL = -3003,
MFC_RET_ENC_SET_INBUF_FAIL = -3004,
MFC_RET_ENC_GET_OUTBUF_FAIL = -3005,
MFC_RET_ENC_SET_OUTBUF_FAIL = -3006,
MFC_RET_ENC_GET_CONF_FAIL = -3007,
MFC_RET_ENC_SET_CONF_FAIL = -3008,
MFC_RET_INVALID_PARAM = -4000
} SSBSIP_MFC_ERROR_CODE;
typedef struct {
void *YPhyAddr; /* [OUT] physical address of Y */
void *CPhyAddr; /* [OUT] physical address of CbCr */
void *YVirAddr; /* [OUT] virtual address of Y */
void *CVirAddr; /* [OUT] virtual address of CbCr */
int img_width; /* [OUT] width of real image */
int img_height; /* [OUT] height of real image */
int buf_width; /* [OUT] width aligned to 16 */
int buf_height; /* [OUT] height alighed to 16 */
int timestamp_top; /* [OUT] timestamp of top filed(This is used for interlaced stream) */
int timestamp_bottom; /* [OUT] timestamp of bottom filed(This is used for interlaced stream) */
int consumedByte; /* [OUT] the number of byte consumed during decoding */
int res_change; /* [OUT] whether resolution is changed or not. 0: not change, 1: increased, 2: decreased */
int crop_top_offset; /* [OUT] crop information, top_offset */
int crop_bottom_offset; /* [OUT] crop information, bottom_offset */
int crop_left_offset; /* [OUT] crop information, left_offset */
int crop_right_offset; /* [OUT] crop information, right_offset */
int disp_pic_frame_type; /* [OUT] display picture frame type information */
/* C210 UMP feature */
unsigned int y_cookie; /* [OUT] cookie for Y address */
unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */
} SSBSIP_MFC_DEC_OUTPUT_INFO;
typedef struct {
void *YPhyAddr; /* [IN/OUT] physical address of Y */
void *CPhyAddr; /* [IN/OUT] physical address of CbCr */
void *YVirAddr; /* [IN/OUT] virtual address of Y */
void *CVirAddr; /* [IN/OUT] virtual address of CbCr */
int YSize; /* [IN/OUT] input size of Y data */
int CSize; /* [IN/OUT] input size of CbCr data */
/* C210 UMP feature */
unsigned int y_cookie; /* [OUT] cookie for Y address */
unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */
} SSBSIP_MFC_ENC_INPUT_INFO;
typedef struct {
unsigned int dataSize; /* [OUT] encoded data size(without header) */
unsigned int headerSize; /* [OUT] encoded header size */
unsigned int frameType; /* [OUT] frame type of encoded stream */
void *StrmPhyAddr; /* [OUT] physical address of Y */
void *StrmVirAddr; /* [OUT] virtual address of Y */
void *encodedYPhyAddr; /* [OUT] physical address of Y which is flushed */
void *encodedCPhyAddr; /* [OUT] physical address of C which is flushed */
/* C210 UMP feature */
unsigned int strm_cookie; /* [OUT] cooke for stream buffer */
unsigned int y_encoded_cookie; /* [OUT] cookie for Y address */
unsigned int c_encoded_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */
} SSBSIP_MFC_ENC_OUTPUT_INFO;
typedef struct {
/* common parameters */
SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */
int SourceWidth; /* [IN] width of video to be encoded */
int SourceHeight; /* [IN] height of video to be encoded */
int IDRPeriod; /* [IN] GOP number(interval of I-frame) */
int SliceMode; /* [IN] Multi slice mode */
int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */
int EnableFRMRateControl; /* [IN] frame based rate control enable */
int Bitrate; /* [IN] rate control parameter(bit rate) */
int FrameQp; /* [IN] The quantization parameter of the frame */
int FrameQp_P; /* [IN] The quantization parameter of the P frame */
int QSCodeMax; /* [IN] Maximum Quantization value */
int QSCodeMin; /* [IN] Minimum Quantization value */
int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */
int PadControlOn; /* [IN] Enable padding control */
int LumaPadVal; /* [IN] Luma pel value used to fill padding area */
int CbPadVal; /* [IN] CB pel value used to fill padding area */
int CrPadVal; /* [IN] CR pel value used to fill padding area */
int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */
/* H.264 specific parameters */
int ProfileIDC; /* [IN] profile */
int LevelIDC; /* [IN] level */
int FrameQp_B; /* [IN] The quantization parameter of the B frame */
int FrameRate; /* [IN] rate control parameter(frame rate) */
int SliceArgument; /* [IN] MB number or byte number */
int NumberBFrames; /* [IN] The number of consecutive B frame inserted */
int NumberReferenceFrames; /* [IN] The number of reference pictures used */
int NumberRefForPframes; /* [IN] The number of reference pictures used for encoding P pictures */
int LoopFilterDisable; /* [IN] disable the loop filter */
int LoopFilterAlphaC0Offset; /* [IN] Alpha & C0 offset for H.264 loop filter */
int LoopFilterBetaOffset; /* [IN] Beta offset for H.264 loop filter */
int SymbolMode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */
int PictureInterlace; /* [IN] Enables the interlace mode */
int Transform8x8Mode; /* [IN] Allow 8x8 transform(This is allowed only for high profile) */
int EnableMBRateControl; /* [IN] Enable macroblock-level rate control */
int DarkDisable; /* [IN] Disable adaptive rate control on dark region */
int SmoothDisable; /* [IN] Disable adaptive rate control on smooth region */
int StaticDisable; /* [IN] Disable adaptive rate control on static region */
int ActivityDisable; /* [IN] Disable adaptive rate control on high activity region */
} SSBSIP_MFC_ENC_H264_PARAM;
typedef struct {
/* common parameters */
SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */
int SourceWidth; /* [IN] width of video to be encoded */
int SourceHeight; /* [IN] height of video to be encoded */
int IDRPeriod; /* [IN] GOP number(interval of I-frame) */
int SliceMode; /* [IN] Multi slice mode */
int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */
int EnableFRMRateControl; /* [IN] frame based rate control enable */
int Bitrate; /* [IN] rate control parameter(bit rate) */
int FrameQp; /* [IN] The quantization parameter of the frame */
int FrameQp_P; /* [IN] The quantization parameter of the P frame */
int QSCodeMax; /* [IN] Maximum Quantization value */
int QSCodeMin; /* [IN] Minimum Quantization value */
int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */
int PadControlOn; /* [IN] Enable padding control */
int LumaPadVal; /* [IN] Luma pel value used to fill padding area */
int CbPadVal; /* [IN] CB pel value used to fill padding area */
int CrPadVal; /* [IN] CR pel value used to fill padding area */
int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */
/* MPEG4 specific parameters */
int ProfileIDC; /* [IN] profile */
int LevelIDC; /* [IN] level */
int FrameQp_B; /* [IN] The quantization parameter of the B frame */
int TimeIncreamentRes; /* [IN] frame rate */
int VopTimeIncreament; /* [IN] frame rate */
int SliceArgument; /* [IN] MB number or byte number */
int NumberBFrames; /* [IN] The number of consecutive B frame inserted */
int DisableQpelME; /* [IN] disable quarter-pixel motion estimation */
} SSBSIP_MFC_ENC_MPEG4_PARAM;
typedef struct {
/* common parameters */
SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */
int SourceWidth; /* [IN] width of video to be encoded */
int SourceHeight; /* [IN] height of video to be encoded */
int IDRPeriod; /* [IN] GOP number(interval of I-frame) */
int SliceMode; /* [IN] Multi slice mode */
int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */
int EnableFRMRateControl; /* [IN] frame based rate control enable */
int Bitrate; /* [IN] rate control parameter(bit rate) */
int FrameQp; /* [IN] The quantization parameter of the frame */
int FrameQp_P; /* [IN] The quantization parameter of the P frame */
int QSCodeMax; /* [IN] Maximum Quantization value */
int QSCodeMin; /* [IN] Minimum Quantization value */
int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */
int PadControlOn; /* [IN] Enable padding control */
int LumaPadVal; /* [IN] Luma pel value used to fill padding area */
int CbPadVal; /* [IN] CB pel value used to fill padding area */
int CrPadVal; /* [IN] CR pel value used to fill padding area */
int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */
/* H.263 specific parameters */
int FrameRate; /* [IN] rate control parameter(frame rate) */
} SSBSIP_MFC_ENC_H263_PARAM;
typedef struct {
int width;
int height;
int buf_width;
int buf_height;
} SSBSIP_MFC_IMG_RESOLUTION;
typedef struct {
int crop_top_offset;
int crop_bottom_offset;
int crop_left_offset;
int crop_right_offset;
} SSBSIP_MFC_CROP_INFORMATION;
#ifdef __cplusplus
extern "C" {
#endif
/*--------------------------------------------------------------------------------*/
/* Decoding APIs */
/*--------------------------------------------------------------------------------*/
void *SsbSipMfcDecOpen(void);
void *SsbSipMfcDecOpenExt(void *value);
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng);
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill);
//SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill);
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle);
void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize);
//SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info);
#if (defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(USE_UMP))
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, unsigned int secure_id, int size);
#else
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size);
#endif
SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info);
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value);
SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value);
/*--------------------------------------------------------------------------------*/
/* Encoding APIs */
/*--------------------------------------------------------------------------------*/
void *SsbSipMfcEncOpen(void);
void *SsbSipMfcEncOpenExt(void *value);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value);
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value);
#ifdef __cplusplus
}
#endif
#endif /* _SSBSIP_MFC_API_H_ */

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Global header for Samsung MFC (Multi Function Codec - FIMV) driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, 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 __MFC_ERRNO_H
#define __MFC_ERRNO_H __FILE__
enum mfc_ret_code {
MFC_OK = 1,
MFC_FAIL = -1000,
MFC_OPEN_FAIL = -1001,
MFC_CLOSE_FAIL = -1002,
MFC_DEC_INIT_FAIL = -2000,
MFC_DEC_EXE_TIME_OUT = -2001,
MFC_DEC_EXE_ERR = -2002,
MFC_DEC_GET_INBUF_FAIL = 2003,
MFC_DEC_SET_INBUF_FAIL = 2004,
MFC_DEC_GET_OUTBUF_FAIL = -2005,
MFC_DEC_GET_CONF_FAIL = -2006,
MFC_DEC_SET_CONF_FAIL = -2007,
MFC_ENC_INIT_FAIL = -3000,
MFC_ENC_EXE_TIME_OUT = -3001,
MFC_ENC_EXE_ERR = -3002,
MFC_ENC_GET_INBUF_FAIL = -3003,
MFC_ENC_SET_INBUF_FAIL = -3004,
MFC_ENC_GET_OUTBUF_FAIL = -3005,
MFC_ENC_SET_OUTBUF_FAIL = -3006,
MFC_ENC_GET_CONF_FAIL = -3007,
MFC_ENC_SET_CONF_FAIL = -3008,
MFC_STATE_INVALID = -4000,
MFC_DEC_HEADER_FAIL = -4001,
MFC_DEC_INIT_BUF_FAIL = -4002,
MFC_ENC_HEADER_FAIL = -5000,
MFC_ENC_PARAM_FAIL = -5001,
MFC_FRM_BUF_SIZE_FAIL = -6000,
MFC_FW_LOAD_FAIL = -6001,
MFC_FW_INIT_FAIL = -6002,
MFC_INST_NUM_EXCEEDED_FAIL = -6003,
MFC_MEM_ALLOC_FAIL = -6004,
MFC_MEM_INVALID_ADDR_FAIL = -6005,
MFC_MEM_MAPPING_FAIL = -6006,
MFC_GET_CONF_FAIL = -6007,
MFC_SET_CONF_FAIL = -6008,
MFC_INVALID_PARAM_FAIL = -6009,
MFC_API_FAIL = -9000,
MFC_CMD_FAIL = -1003,
MFC_SLEEP_FAIL = -1010,
MFC_WAKEUP_FAIL = -1020,
MFC_CLK_ON_FAIL = -1030,
MFC_CLK_OFF_FAIL = -1030,
MFC_PWR_ON_FAIL = -1040,
MFC_PWR_OFF_FAIL = -1041,
};
#endif /* __MFC_ERRNO_H */

View File

@@ -0,0 +1,541 @@
/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Global header for Samsung MFC (Multi Function Codec - FIMV) driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, 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 __MFC_INTERFACE_H
#define __MFC_INTERFACE_H
#include "mfc_errno.h"
#include "SsbSipMfcApi.h"
#define IOCTL_MFC_DEC_INIT (0x00800001)
#define IOCTL_MFC_ENC_INIT (0x00800002)
#define IOCTL_MFC_DEC_EXE (0x00800003)
#define IOCTL_MFC_ENC_EXE (0x00800004)
#define IOCTL_MFC_GET_IN_BUF (0x00800010)
#define IOCTL_MFC_FREE_BUF (0x00800011)
#define IOCTL_MFC_GET_REAL_ADDR (0x00800012)
#define IOCTL_MFC_GET_MMAP_SIZE (0x00800014)
#define IOCTL_MFC_SET_IN_BUF (0x00800018)
#define IOCTL_MFC_SET_CONFIG (0x00800101)
#define IOCTL_MFC_GET_CONFIG (0x00800102)
#define IOCTL_MFC_SET_BUF_CACHE (0x00800201)
/* MFC H/W support maximum 32 extra DPB. */
#define MFC_MAX_EXTRA_DPB 5
#define MFC_MAX_DISP_DELAY 0xF
#define MFC_LIB_VER_MAJOR 1
#define MFC_LIB_VER_MINOR 00
#define BUF_L_UNIT (1024)
#define Align(x, alignbyte) (((x)+(alignbyte)-1)/(alignbyte)*(alignbyte))
#define MFC_ENC_NUM_SRC_BUFS 2 /* Number of source buffers to request */
#define MFC_ENC_MAX_DST_BUFS 2 /* The maximum number of buffers */
#define MFC_ENC_NUM_PLANES 2 /* Number of planes used by MFC Input */
#define MFC_DEC_NUM_SRC_BUFS 2 /* Number of source buffers to request */
#define MFC_DEC_MAX_DST_BUFS 32 /* The maximum number of buffers */
#define MFC_DEC_NUM_PLANES 2 /* Number of planes used by MFC output */
enum inst_type {
DECODER = 0x1,
ENCODER = 0x2,
};
typedef enum {
MFC_UNPACKED_PB = 0,
MFC_PACKED_PB = 1
} mfc_packed_mode;
typedef enum {
SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED = 0,
SSBSIP_MFC_LAST_FRAME_RECEIVED = 1,
SSBSIP_MFC_LAST_FRAME_PROCESSED = 2
} SSBSIP_MFC_LAST_FRAME_STATUS;
typedef enum {
MFC_USE_NONE = 0x0000,
MFC_USE_YUV_BUFF = 0x0001,
MFC_USE_STRM_BUFF = 0x0010,
MFC_USE_SRC_STREAMON = 0x0100,
MFC_USE_DST_STREAMON = 0x1000,
} s3c_mfc_interbuff_status;
typedef struct {
int luma0; /* per frame (or top field) */
int chroma0; /* per frame (or top field) */
int luma1; /* per frame (or bottom field) */
int chroma1; /* per frame (or bottom field) */
} SSBSIP_MFC_CRC_DATA;
struct mfc_strm_ref_buf_arg {
unsigned int strm_ref_y;
unsigned int mv_ref_yc;
};
struct mfc_frame_buf_arg {
unsigned int luma;
unsigned int chroma;
};
struct mfc_enc_init_common_arg {
SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
int in_width; /* [IN] width of YUV420 frame to be encoded */
int in_height; /* [IN] height of YUV420 frame to be encoded */
int in_gop_num; /* [IN] GOP Number (interval of I-frame) */
int in_vop_quant; /* [IN] VOP quant */
int in_vop_quant_p; /* [IN] VOP quant for P frame */
/* [IN] RC enable */
/* [IN] RC enable (0:disable, 1:frame level RC) */
int in_rc_fr_en;
int in_rc_bitrate; /* [IN] RC parameter (bitrate in kbps) */
int in_rc_qbound_min; /* [IN] RC parameter (Q bound Min) */
int in_rc_qbound_max; /* [IN] RC parameter (Q bound Max) */
int in_rc_rpara; /* [IN] RC parameter (Reaction Coefficient) */
/* [IN] Multi-slice mode (0:single, 1:multiple) */
int in_ms_mode;
/* [IN] Multi-slice size (in num. of mb or byte) */
int in_ms_arg;
int in_mb_refresh; /* [IN] Macroblock refresh */
/* [IN] Enable (1) / Disable (0) padding with the specified values */
int in_pad_ctrl_on;
/* [IN] pad value if pad_ctrl_on is Enable */
int in_y_pad_val;
int in_cb_pad_val;
int in_cr_pad_val;
/* linear or tiled */
int in_frame_map;
unsigned int in_pixelcache;
unsigned int in_mapped_addr;
struct mfc_strm_ref_buf_arg out_u_addr;
struct mfc_strm_ref_buf_arg out_p_addr;
struct mfc_strm_ref_buf_arg out_buf_size;
unsigned int out_header_size;
};
struct mfc_enc_init_h263_arg {
int in_rc_framerate; /* [IN] RC parameter (framerate) */
};
struct mfc_enc_init_mpeg4_arg {
int in_profile; /* [IN] profile */
int in_level; /* [IN] level */
int in_vop_quant_b; /* [IN] VOP quant for B frame */
/* [IN] B frame number */
int in_bframenum;
/* [IN] Quarter-pel MC enable (1:enabled, 0:disabled) */
int in_quart_pixel;
int in_TimeIncreamentRes; /* [IN] VOP time resolution */
int in_VopTimeIncreament; /* [IN] Frame delta */
};
struct mfc_enc_init_h264_arg {
int in_profile; /* [IN] profile */
int in_level; /* [IN] level */
int in_vop_quant_b; /* [IN] VOP quant for B frame */
/* [IN] B frame number */
int in_bframenum;
/* [IN] interlace mode(0:progressive, 1:interlace) */
int in_interlace_mode;
/* [IN] reference number */
int in_reference_num;
/* [IN] reference number of P frame */
int in_ref_num_p;
int in_rc_framerate; /* [IN] RC parameter (framerate) */
int in_rc_mb_en; /* [IN] RC enable (0:disable, 1:MB level RC) */
/* [IN] MB level rate control dark region adaptive feature */
int in_rc_mb_dark_dis; /* (0:enable, 1:disable) */
/* [IN] MB level rate control smooth region adaptive feature */
int in_rc_mb_smooth_dis; /* (0:enable, 1:disable) */
/* [IN] MB level rate control static region adaptive feature */
int in_rc_mb_static_dis; /* (0:enable, 1:disable) */
/* [IN] MB level rate control activity region adaptive feature */
int in_rc_mb_activity_dis; /* (0:enable, 1:disable) */
/* [IN] disable deblocking filter idc */
int in_deblock_dis; /* (0: enable,1: disable, 2:Disable at slice boundary) */
/* [IN] slice alpha c0 offset of deblocking filter */
int in_deblock_alpha_c0;
/* [IN] slice beta offset of deblocking filter */
int in_deblock_beta;
/* [IN] ( 0 : CAVLC, 1 : CABAC ) */
int in_symbolmode;
/* [IN] (0: only 4x4 transform, 1: allow using 8x8 transform) */
int in_transform8x8_mode;
/* [IN] Inter weighted parameter for mode decision */
int in_md_interweight_pps;
/* [IN] Intra weighted parameter for mode decision */
int in_md_intraweight_pps;
};
struct mfc_enc_init_arg {
struct mfc_enc_init_common_arg cmn;
union {
struct mfc_enc_init_h264_arg h264;
struct mfc_enc_init_mpeg4_arg mpeg4;
struct mfc_enc_init_h263_arg h263;
} codec;
};
struct mfc_enc_exe_arg {
SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */
unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */
unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */
unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */
unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */
unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */
unsigned int in_frametag; /* [IN] unique frame ID */
unsigned int out_frame_type; /* [OUT] frame type */
int out_encoded_size; /* [OUT] Length of Encoded video stream */
unsigned int out_Y_addr; /*[OUT]Out-buffer addr of encoded Y component */
unsigned int out_CbCr_addr; /*[OUT]Out-buffer addr of encoded CbCr component */
unsigned int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */
unsigned int out_frametag_bottom;/* [OUT] unique frame ID of bottom field */
#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
unsigned int out_y_secure_id;
unsigned int out_c_secure_id;
#elif defined(CONFIG_S5P_VMEM)
unsigned int out_y_cookie;
unsigned int out_c_cookie;
#endif
};
struct mfc_dec_init_arg {
SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
int in_strm_buf; /* [IN] address of stream buffer */
int in_strm_size; /* [IN] filled size in stream buffer */
int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */
unsigned int in_crc; /* [IN] */
unsigned int in_pixelcache; /* [IN] */
unsigned int in_slice; /* [IN] */
unsigned int in_numextradpb; /* [IN] */
unsigned int in_mapped_addr;
int out_frm_width; /* [OUT] width of YUV420 frame */
int out_frm_height; /* [OUT] height of YUV420 frame */
int out_buf_width; /* [OUT] width of YUV420 frame */
int out_buf_height; /* [OUT] height of YUV420 frame */
int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding. */
int out_crop_right_offset; /* [OUT] crop information for h264 */
int out_crop_left_offset;
int out_crop_bottom_offset;
int out_crop_top_offset;
};
struct mfc_dec_exe_arg {
SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
int in_strm_buf; /* [IN] the physical address of STRM_BUF */
/* [IN] Size of video stream filled in STRM_BUF */
int in_strm_size;
/* [IN] the address of dpb FRAME_BUF */
struct mfc_frame_buf_arg in_frm_buf;
/* [IN] size of dpb FRAME_BUF */
struct mfc_frame_buf_arg in_frm_size;
/* [IN] Unique frame ID eg. application specific timestamp */
unsigned int in_frametag;
/* [IN] immdiate Display for seek,thumbnail and one frame */
int in_immediately_disp;
/* [OUT] the physical address of display buf */
int out_display_Y_addr;
/* [OUT] the physical address of display buf */
int out_display_C_addr;
int out_display_status;
/* [OUT] unique frame ID of an output frame or top field */
unsigned int out_frametag_top;
/* [OUT] unique frame ID of bottom field */
unsigned int out_frametag_bottom;
int out_pic_time_top;
int out_pic_time_bottom;
int out_consumed_byte;
int out_crop_right_offset;
int out_crop_left_offset;
int out_crop_bottom_offset;
int out_crop_top_offset;
/* in new driver, each buffer offset must be return to the user */
int out_y_offset;
int out_c_offset;
#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
unsigned int out_y_secure_id;
unsigned int out_c_secure_id;
#elif defined(CONFIG_S5P_VMEM)
unsigned int out_y_cookie;
unsigned int out_c_cookie;
#endif
int out_img_width; /* [OUT] width of YUV420 frame */
int out_img_height; /* [OUT] height of YUV420 frame */
int out_buf_width; /* [OUT] width of YUV420 frame */
int out_buf_height; /* [OUT] height of YUV420 frame */
int out_disp_pic_frame_type; /* [OUT] display picture frame type information */
};
struct mfc_get_config_arg {
/* [IN] Configurable parameter type */
int in_config_param;
/* [IN] Values to get for the configurable parameter. */
/* Maximum four integer values can be obtained; */
int out_config_value[4];
};
struct mfc_set_config_arg {
/* [IN] Configurable parameter type */
int in_config_param;
/* [IN] Values to be set for the configurable parameter. */
/* Maximum four integer values can be set. */
int in_config_value[4];
};
struct mfc_get_real_addr_arg {
unsigned int key;
unsigned int addr;
};
struct mfc_buf_alloc_arg {
enum inst_type type;
int size;
/*
unsigned int mapped;
*/
unsigned int align;
unsigned int addr;
/*
unsigned int phys;
*/
#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
/* FIMXE: invalid secure id == -1 */
unsigned int secure_id;
#elif defined(CONFIG_S5P_VMEM)
unsigned int cookie;
#else
unsigned int offset;
#endif
};
struct mfc_buf_free_arg {
unsigned int addr;
};
/* RMVME */
struct mfc_mem_alloc_arg {
enum inst_type type;
int buff_size;
SSBIP_MFC_BUFFER_TYPE buf_cache_type;
unsigned int mapped_addr;
#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
unsigned int secure_id;
#elif defined(CONFIG_S5P_VMEM)
unsigned int cookie;
#else
unsigned int offset;
#endif
};
struct mfc_mem_free_arg {
unsigned int key;
};
/* RMVME */
union mfc_args {
/*
struct mfc_enc_init_arg enc_init;
struct mfc_enc_init_mpeg4_arg enc_init_mpeg4;
struct mfc_enc_init_mpeg4_arg enc_init_h263;
struct mfc_enc_init_h264_arg enc_init_h264;
*/
struct mfc_enc_init_arg enc_init;
struct mfc_enc_exe_arg enc_exe;
struct mfc_dec_init_arg dec_init;
struct mfc_dec_exe_arg dec_exe;
struct mfc_get_config_arg get_config;
struct mfc_set_config_arg set_config;
struct mfc_buf_alloc_arg buf_alloc;
struct mfc_buf_free_arg buf_free;
struct mfc_get_real_addr_arg real_addr;
/* RMVME */
struct mfc_mem_alloc_arg mem_alloc;
struct mfc_mem_free_arg mem_free;
/* RMVME */
};
struct mfc_common_args {
enum mfc_ret_code ret_code; /* [OUT] error code */
union mfc_args args;
};
struct mfc_enc_vui_info {
int aspect_ratio_idc;
};
struct mfc_dec_fimv1_info {
int width;
int height;
};
struct mfc_enc_hier_p_qp {
int t0_frame_qp;
int t2_frame_qp;
int t3_frame_qp;
};
enum BUF_STATUS {
BUF_ENQUEUED,
BUF_DEQUEUED
};
struct mfc_dec_v4l2 {
char *mfc_src_bufs[MFC_DEC_NUM_SRC_BUFS]; /* information of source buffers */
char *mfc_dst_bufs[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* information of destination buffers */
char *mfc_dst_phys[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* cma information of destination buffers */
unsigned int mfc_src_bufs_len; /* needed for munmap */
unsigned int mfc_dst_bufs_len[MFC_DEC_NUM_PLANES]; /* needed for munmap */
unsigned int mfc_num_src_bufs; /* the number of source buffers */
unsigned int mfc_num_dst_bufs; /* the number of destination buffers */
char mfc_src_buf_flags[MFC_DEC_NUM_SRC_BUFS];
int bBeingFinalized;
int allocIndex;
int beingUsedIndex;
};
struct mfc_enc_v4l2 {
char *mfc_src_bufs[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES];
char *mfc_src_phys[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES];
char *mfc_dst_bufs[MFC_ENC_MAX_DST_BUFS];
unsigned int mfc_src_bufs_len[MFC_ENC_NUM_PLANES];
unsigned int mfc_dst_bufs_len;
unsigned int mfc_num_src_bufs;
unsigned int mfc_num_dst_bufs;
unsigned int mfc_dst_bufs_bytes_used_len;
char mfc_src_buf_flags[MFC_ENC_NUM_SRC_BUFS];
int bRunning;
int bInputPhyVir; /* Flag to use MFC src as physical or virtual 0: virtual 1: physical */
int beingUsedIndex;
};
typedef struct {
int magic;
int hMFC;
int hVMEM;
int width;
int height;
int sizeStrmBuf;
struct mfc_frame_buf_arg sizeFrmBuf;
int displayStatus;
int inter_buff_status;
unsigned int virFreeStrmAddr;
unsigned int phyStrmBuf;
unsigned int virStrmBuf;
unsigned int virMvRefYC;
struct mfc_frame_buf_arg phyFrmBuf;
struct mfc_frame_buf_arg virFrmBuf;
unsigned int mapped_addr;
unsigned int mapped_size;
struct mfc_common_args MfcArg;
SSBSIP_MFC_CODEC_TYPE codecType;
SSBSIP_MFC_DEC_OUTPUT_INFO decOutInfo;
unsigned int inframetag;
unsigned int outframetagtop;
unsigned int outframetagbottom;
unsigned int immediatelydisp;
unsigned int encodedHeaderSize;
int encodedDataSize;
unsigned int encodedframeType;
struct mfc_frame_buf_arg encodedphyFrmBuf;
unsigned int dec_crc;
unsigned int dec_pixelcache;
unsigned int dec_slice;
unsigned int dec_numextradpb;
int input_cookie;
int input_secure_id;
int input_size;
/* to support non-blocking mode */
unsigned int encode_cnt;
struct mfc_dec_v4l2 v4l2_dec;
struct mfc_enc_v4l2 v4l2_enc;
int enc_frameskip;
int cacheablebuffer;
struct mfc_dec_fimv1_info fimv1_res;
SSBSIP_MFC_LAST_FRAME_STATUS lastframe;
SSBSIP_MFC_INSTRM_MODE_TYPE framemap;
} _MFCLIB;
#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8))
#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8))
#define SSBSIP_MFC_FAIL (0)
#endif /* __MFC_INTERFACE_H */

View File

@@ -0,0 +1,23 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
SEC_OMX_Plugin.cpp
LOCAL_CFLAGS += $(PV_CFLAGS_MINUS_VISIBILITY)
LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/native/include/media/openmax \
LOCAL_SHARED_LIBRARIES := \
libbinder \
libutils \
libcutils \
libui \
libdl \
libstagefright_foundation
LOCAL_MODULE := libstagefrighthw
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)

View File

@@ -0,0 +1,147 @@
/*
* 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.
*/
#include "SEC_OMX_Plugin.h"
#include <dlfcn.h>
#include <media/hardware/HardwareAPI.h>
#include <media/stagefright/foundation/ADebug.h>
namespace android {
OMXPluginBase *createOMXPlugin() {
return new SECOMXPlugin;
}
SECOMXPlugin::SECOMXPlugin()
: mLibHandle(dlopen("libSEC_OMX_Core.so", RTLD_NOW)),
mInit(NULL),
mDeinit(NULL),
mComponentNameEnum(NULL),
mGetHandle(NULL),
mFreeHandle(NULL),
mGetRolesOfComponentHandle(NULL) {
if (mLibHandle != NULL) {
mInit = (InitFunc)dlsym(mLibHandle, "SEC_OMX_Init");
mDeinit = (DeinitFunc)dlsym(mLibHandle, "SEC_OMX_Deinit");
mComponentNameEnum =
(ComponentNameEnumFunc)dlsym(mLibHandle, "SEC_OMX_ComponentNameEnum");
mGetHandle = (GetHandleFunc)dlsym(mLibHandle, "SEC_OMX_GetHandle");
mFreeHandle = (FreeHandleFunc)dlsym(mLibHandle, "SEC_OMX_FreeHandle");
mGetRolesOfComponentHandle =
(GetRolesOfComponentFunc)dlsym(
mLibHandle, "SEC_OMX_GetRolesOfComponent");
(*mInit)();
}
}
SECOMXPlugin::~SECOMXPlugin() {
if (mLibHandle != NULL) {
(*mDeinit)();
dlclose(mLibHandle);
mLibHandle = NULL;
}
}
OMX_ERRORTYPE SECOMXPlugin::makeComponentInstance(
const char *name,
const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData,
OMX_COMPONENTTYPE **component) {
if (mLibHandle == NULL) {
return OMX_ErrorUndefined;
}
return (*mGetHandle)(
reinterpret_cast<OMX_HANDLETYPE *>(component),
const_cast<char *>(name),
appData, const_cast<OMX_CALLBACKTYPE *>(callbacks));
}
OMX_ERRORTYPE SECOMXPlugin::destroyComponentInstance(
OMX_COMPONENTTYPE *component) {
if (mLibHandle == NULL) {
return OMX_ErrorUndefined;
}
return (*mFreeHandle)(reinterpret_cast<OMX_HANDLETYPE *>(component));
}
OMX_ERRORTYPE SECOMXPlugin::enumerateComponents(
OMX_STRING name,
size_t size,
OMX_U32 index) {
if (mLibHandle == NULL) {
return OMX_ErrorUndefined;
}
return (*mComponentNameEnum)(name, size, index);
}
OMX_ERRORTYPE SECOMXPlugin::getRolesOfComponent(
const char *name,
Vector<String8> *roles) {
roles->clear();
if (mLibHandle == NULL) {
return OMX_ErrorUndefined;
}
OMX_U32 numRoles;
OMX_ERRORTYPE err = (*mGetRolesOfComponentHandle)(
const_cast<OMX_STRING>(name), &numRoles, NULL);
if (err != OMX_ErrorNone) {
return err;
}
if (numRoles > 0) {
OMX_U8 **array = new OMX_U8 *[numRoles];
for (OMX_U32 i = 0; i < numRoles; ++i) {
array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE];
}
OMX_U32 numRoles2;
err = (*mGetRolesOfComponentHandle)(
const_cast<OMX_STRING>(name), &numRoles2, array);
CHECK_EQ(err, OMX_ErrorNone);
CHECK_EQ(numRoles, numRoles2);
for (OMX_U32 i = 0; i < numRoles; ++i) {
String8 s((const char *)array[i]);
roles->push(s);
delete[] array[i];
array[i] = NULL;
}
delete[] array;
array = NULL;
}
return OMX_ErrorNone;
}
} // namespace android

Some files were not shown because too many files have changed in this diff Show More