update new sdk
This commit is contained in:
parent
f33907443a
commit
744c72c133
1643 changed files with 83006 additions and 28021 deletions
25
android/frameworks/av/drm/libmediadrm/CryptoHal.cpp
Normal file → Executable file
25
android/frameworks/av/drm/libmediadrm/CryptoHal.cpp
Normal file → Executable file
|
@ -240,11 +240,12 @@ int32_t CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) {
|
|||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
int32_t seqNum = mHeapSeqNum++;
|
||||
|
||||
int fd = heap->getHeapID();
|
||||
nativeHandle->data[0] = fd;
|
||||
auto hidlHandle = hidl_handle(nativeHandle);
|
||||
auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize());
|
||||
mHeapBases.add(seqNum, mNextBufferId);
|
||||
mHeapBases.add(seqNum, HeapBase(mNextBufferId, heap->getSize()));
|
||||
Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++);
|
||||
ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
|
||||
return seqNum;
|
||||
|
@ -269,10 +270,26 @@ status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::
|
|||
return UNEXPECTED_NULL;
|
||||
}
|
||||
|
||||
// memory must be in the declared heap
|
||||
CHECK(mHeapBases.indexOfKey(seqNum) >= 0);
|
||||
// memory must be in one of the heaps that have been set
|
||||
if (mHeapBases.indexOfKey(seqNum) < 0) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
buffer->bufferId = mHeapBases.valueFor(seqNum);
|
||||
// heap must be the same size as the one that was set in setHeapBase
|
||||
if (mHeapBases.valueFor(seqNum).getSize() != heap->getSize()) {
|
||||
android_errorWriteLog(0x534e4554, "76221123");
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
// memory must be within the address space of the heap
|
||||
if (memory->pointer() != static_cast<uint8_t *>(heap->getBase()) + memory->offset() ||
|
||||
heap->getSize() < memory->offset() + memory->size() ||
|
||||
SIZE_MAX - memory->offset() < memory->size()) {
|
||||
android_errorWriteLog(0x534e4554, "76221123");
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
buffer->bufferId = mHeapBases.valueFor(seqNum).getBufferId();
|
||||
buffer->offset = offset >= 0 ? offset : 0;
|
||||
buffer->size = size;
|
||||
return OK;
|
||||
|
|
9
android/frameworks/av/drm/libmediadrm/ICrypto.cpp
Normal file → Executable file
9
android/frameworks/av/drm/libmediadrm/ICrypto.cpp
Normal file → Executable file
|
@ -225,8 +225,13 @@ IMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto");
|
|||
|
||||
void BnCrypto::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
|
||||
uint32_t size = data.readInt32();
|
||||
vector.insertAt((size_t)0, size);
|
||||
data.read(vector.editArray(), size);
|
||||
if (vector.insertAt((size_t)0, size) < 0) {
|
||||
vector.clear();
|
||||
}
|
||||
if (data.read(vector.editArray(), size) != NO_ERROR) {
|
||||
vector.clear();
|
||||
android_errorWriteWithInfoLog(0x534e4554, "62872384", -1, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void BnCrypto::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
|
||||
|
|
24
android/frameworks/av/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
Normal file → Executable file
24
android/frameworks/av/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
Normal file → Executable file
|
@ -118,9 +118,9 @@ status_t ClearKeyCasPlugin::openSession(CasSessionId* sessionId) {
|
|||
|
||||
status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) {
|
||||
ALOGV("closeSession: sessionId=%s", sessionIdToString(sessionId).string());
|
||||
sp<ClearKeyCasSession> session =
|
||||
std::shared_ptr<ClearKeyCasSession> session =
|
||||
ClearKeySessionLibrary::get()->findSession(sessionId);
|
||||
if (session == NULL) {
|
||||
if (session.get() == nullptr) {
|
||||
return ERROR_CAS_SESSION_NOT_OPENED;
|
||||
}
|
||||
|
||||
|
@ -132,9 +132,9 @@ status_t ClearKeyCasPlugin::setSessionPrivateData(
|
|||
const CasSessionId &sessionId, const CasData & /*data*/) {
|
||||
ALOGV("setSessionPrivateData: sessionId=%s",
|
||||
sessionIdToString(sessionId).string());
|
||||
sp<ClearKeyCasSession> session =
|
||||
std::shared_ptr<ClearKeyCasSession> session =
|
||||
ClearKeySessionLibrary::get()->findSession(sessionId);
|
||||
if (session == NULL) {
|
||||
if (session.get() == nullptr) {
|
||||
return ERROR_CAS_SESSION_NOT_OPENED;
|
||||
}
|
||||
return OK;
|
||||
|
@ -143,9 +143,9 @@ status_t ClearKeyCasPlugin::setSessionPrivateData(
|
|||
status_t ClearKeyCasPlugin::processEcm(
|
||||
const CasSessionId &sessionId, const CasEcm& ecm) {
|
||||
ALOGV("processEcm: sessionId=%s", sessionIdToString(sessionId).string());
|
||||
sp<ClearKeyCasSession> session =
|
||||
std::shared_ptr<ClearKeyCasSession> session =
|
||||
ClearKeySessionLibrary::get()->findSession(sessionId);
|
||||
if (session == NULL) {
|
||||
if (session.get() == nullptr) {
|
||||
return ERROR_CAS_SESSION_NOT_OPENED;
|
||||
}
|
||||
|
||||
|
@ -415,15 +415,15 @@ status_t ClearKeyDescramblerPlugin::setMediaCasSession(
|
|||
const CasSessionId &sessionId) {
|
||||
ALOGV("setMediaCasSession: sessionId=%s", sessionIdToString(sessionId).string());
|
||||
|
||||
sp<ClearKeyCasSession> session =
|
||||
std::shared_ptr<ClearKeyCasSession> session =
|
||||
ClearKeySessionLibrary::get()->findSession(sessionId);
|
||||
|
||||
if (session == NULL) {
|
||||
if (session.get() == nullptr) {
|
||||
ALOGE("ClearKeyDescramblerPlugin: session not found");
|
||||
return ERROR_CAS_SESSION_NOT_OPENED;
|
||||
}
|
||||
|
||||
mCASSession = session;
|
||||
std::atomic_store(&mCASSession, session);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -444,12 +444,14 @@ ssize_t ClearKeyDescramblerPlugin::descramble(
|
|||
subSamplesToString(subSamples, numSubSamples).string(),
|
||||
srcPtr, dstPtr, srcOffset, dstOffset);
|
||||
|
||||
if (mCASSession == NULL) {
|
||||
std::shared_ptr<ClearKeyCasSession> session = std::atomic_load(&mCASSession);
|
||||
|
||||
if (session.get() == nullptr) {
|
||||
ALOGE("Uninitialized CAS session!");
|
||||
return ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return mCASSession->decrypt(
|
||||
return session->decrypt(
|
||||
secure, scramblingControl,
|
||||
numSubSamples, subSamples,
|
||||
(uint8_t*)srcPtr + srcOffset,
|
||||
|
|
2
android/frameworks/av/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
Normal file → Executable file
2
android/frameworks/av/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
Normal file → Executable file
|
@ -120,7 +120,7 @@ public:
|
|||
AString *errorDetailMsg) override;
|
||||
|
||||
private:
|
||||
sp<ClearKeyCasSession> mCASSession;
|
||||
std::shared_ptr<ClearKeyCasSession> mCASSession;
|
||||
|
||||
String8 subSamplesToString(
|
||||
SubSample const *subSamples,
|
||||
|
|
8
android/frameworks/av/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
Normal file → Executable file
8
android/frameworks/av/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
Normal file → Executable file
|
@ -56,7 +56,7 @@ status_t ClearKeySessionLibrary::addSession(
|
|||
|
||||
Mutex::Autolock lock(mSessionsLock);
|
||||
|
||||
sp<ClearKeyCasSession> session = new ClearKeyCasSession(plugin);
|
||||
std::shared_ptr<ClearKeyCasSession> session(new ClearKeyCasSession(plugin));
|
||||
|
||||
uint8_t *byteArray = (uint8_t *) &mNextSessionId;
|
||||
sessionId->push_back(byteArray[3]);
|
||||
|
@ -69,7 +69,7 @@ status_t ClearKeySessionLibrary::addSession(
|
|||
return OK;
|
||||
}
|
||||
|
||||
sp<ClearKeyCasSession> ClearKeySessionLibrary::findSession(
|
||||
std::shared_ptr<ClearKeyCasSession> ClearKeySessionLibrary::findSession(
|
||||
const CasSessionId& sessionId) {
|
||||
Mutex::Autolock lock(mSessionsLock);
|
||||
|
||||
|
@ -88,7 +88,7 @@ void ClearKeySessionLibrary::destroySession(const CasSessionId& sessionId) {
|
|||
return;
|
||||
}
|
||||
|
||||
sp<ClearKeyCasSession> session = mIDToSessionMap.valueAt(index);
|
||||
std::shared_ptr<ClearKeyCasSession> session = mIDToSessionMap.valueAt(index);
|
||||
mIDToSessionMap.removeItemsAt(index);
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ void ClearKeySessionLibrary::destroyPlugin(CasPlugin *plugin) {
|
|||
Mutex::Autolock lock(mSessionsLock);
|
||||
|
||||
for (ssize_t index = mIDToSessionMap.size() - 1; index >= 0; index--) {
|
||||
sp<ClearKeyCasSession> session = mIDToSessionMap.valueAt(index);
|
||||
std::shared_ptr<ClearKeyCasSession> session = mIDToSessionMap.valueAt(index);
|
||||
if (session->getPlugin() == plugin) {
|
||||
mIDToSessionMap.removeItemsAt(index);
|
||||
}
|
||||
|
|
10
android/frameworks/av/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h
Normal file → Executable file
10
android/frameworks/av/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h
Normal file → Executable file
|
@ -32,6 +32,10 @@ class KeyFetcher;
|
|||
|
||||
class ClearKeyCasSession : public RefBase {
|
||||
public:
|
||||
explicit ClearKeyCasSession(CasPlugin *plugin);
|
||||
|
||||
virtual ~ClearKeyCasSession();
|
||||
|
||||
ssize_t decrypt(
|
||||
bool secure,
|
||||
DescramblerPlugin::ScramblingControl scramblingControl,
|
||||
|
@ -58,8 +62,6 @@ private:
|
|||
|
||||
friend class ClearKeySessionLibrary;
|
||||
|
||||
explicit ClearKeyCasSession(CasPlugin *plugin);
|
||||
virtual ~ClearKeyCasSession();
|
||||
CasPlugin* getPlugin() const { return mPlugin; }
|
||||
status_t decryptPayload(
|
||||
const AES_KEY& key, size_t length, size_t offset, char* buffer) const;
|
||||
|
@ -73,7 +75,7 @@ public:
|
|||
|
||||
status_t addSession(CasPlugin *plugin, CasSessionId *sessionId);
|
||||
|
||||
sp<ClearKeyCasSession> findSession(const CasSessionId& sessionId);
|
||||
std::shared_ptr<ClearKeyCasSession> findSession(const CasSessionId& sessionId);
|
||||
|
||||
void destroySession(const CasSessionId& sessionId);
|
||||
|
||||
|
@ -85,7 +87,7 @@ private:
|
|||
|
||||
Mutex mSessionsLock;
|
||||
uint32_t mNextSessionId;
|
||||
KeyedVector<CasSessionId, sp<ClearKeyCasSession>> mIDToSessionMap;
|
||||
KeyedVector<CasSessionId, std::shared_ptr<ClearKeyCasSession>> mIDToSessionMap;
|
||||
|
||||
ClearKeySessionLibrary();
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ClearKeySessionLibrary);
|
||||
|
|
65
android/frameworks/av/media/libaudioclient/IAudioPolicyService.cpp
Normal file → Executable file
65
android/frameworks/av/media/libaudioclient/IAudioPolicyService.cpp
Normal file → Executable file
|
@ -940,7 +940,7 @@ status_t BnAudioPolicyService::onTransact(
|
|||
audio_output_flags_t flags =
|
||||
static_cast <audio_output_flags_t>(data.readInt32());
|
||||
bool hasOffloadInfo = data.readInt32() != 0;
|
||||
audio_offload_info_t offloadInfo;
|
||||
audio_offload_info_t offloadInfo = {};
|
||||
if (hasOffloadInfo) {
|
||||
data.read(&offloadInfo, sizeof(audio_offload_info_t));
|
||||
}
|
||||
|
@ -956,7 +956,7 @@ status_t BnAudioPolicyService::onTransact(
|
|||
|
||||
case GET_OUTPUT_FOR_ATTR: {
|
||||
CHECK_INTERFACE(IAudioPolicyService, data, reply);
|
||||
audio_attributes_t attr;
|
||||
audio_attributes_t attr = {};
|
||||
bool hasAttributes = data.readInt32() != 0;
|
||||
if (hasAttributes) {
|
||||
data.read(&attr, sizeof(audio_attributes_t));
|
||||
|
@ -1024,7 +1024,7 @@ status_t BnAudioPolicyService::onTransact(
|
|||
|
||||
case GET_INPUT_FOR_ATTR: {
|
||||
CHECK_INTERFACE(IAudioPolicyService, data, reply);
|
||||
audio_attributes_t attr;
|
||||
audio_attributes_t attr = {};
|
||||
data.read(&attr, sizeof(audio_attributes_t));
|
||||
sanetizeAudioAttributes(&attr);
|
||||
audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
|
||||
|
@ -1125,8 +1125,11 @@ status_t BnAudioPolicyService::onTransact(
|
|||
|
||||
case GET_OUTPUT_FOR_EFFECT: {
|
||||
CHECK_INTERFACE(IAudioPolicyService, data, reply);
|
||||
effect_descriptor_t desc;
|
||||
data.read(&desc, sizeof(effect_descriptor_t));
|
||||
effect_descriptor_t desc = {};
|
||||
if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
|
||||
android_errorWriteLog(0x534e4554, "73126106");
|
||||
}
|
||||
(void)sanitizeEffectDescriptor(&desc);
|
||||
audio_io_handle_t output = getOutputForEffect(&desc);
|
||||
reply->writeInt32(static_cast <int>(output));
|
||||
return NO_ERROR;
|
||||
|
@ -1134,8 +1137,11 @@ status_t BnAudioPolicyService::onTransact(
|
|||
|
||||
case REGISTER_EFFECT: {
|
||||
CHECK_INTERFACE(IAudioPolicyService, data, reply);
|
||||
effect_descriptor_t desc;
|
||||
data.read(&desc, sizeof(effect_descriptor_t));
|
||||
effect_descriptor_t desc = {};
|
||||
if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
|
||||
android_errorWriteLog(0x534e4554, "73126106");
|
||||
}
|
||||
(void)sanitizeEffectDescriptor(&desc);
|
||||
audio_io_handle_t io = data.readInt32();
|
||||
uint32_t strategy = data.readInt32();
|
||||
audio_session_t session = (audio_session_t) data.readInt32();
|
||||
|
@ -1194,7 +1200,7 @@ status_t BnAudioPolicyService::onTransact(
|
|||
count = AudioEffect::kMaxPreProcessing;
|
||||
}
|
||||
uint32_t retCount = count;
|
||||
effect_descriptor_t *descriptors = new effect_descriptor_t[count];
|
||||
effect_descriptor_t *descriptors = new effect_descriptor_t[count]{};
|
||||
status_t status = queryDefaultPreProcessing(audioSession, descriptors, &retCount);
|
||||
reply->writeInt32(status);
|
||||
if (status != NO_ERROR && status != NO_MEMORY) {
|
||||
|
@ -1213,7 +1219,7 @@ status_t BnAudioPolicyService::onTransact(
|
|||
|
||||
case IS_OFFLOAD_SUPPORTED: {
|
||||
CHECK_INTERFACE(IAudioPolicyService, data, reply);
|
||||
audio_offload_info_t info;
|
||||
audio_offload_info_t info = {};
|
||||
data.read(&info, sizeof(audio_offload_info_t));
|
||||
bool isSupported = isOffloadSupported(info);
|
||||
reply->writeInt32(isSupported);
|
||||
|
@ -1268,7 +1274,7 @@ status_t BnAudioPolicyService::onTransact(
|
|||
|
||||
case CREATE_AUDIO_PATCH: {
|
||||
CHECK_INTERFACE(IAudioPolicyService, data, reply);
|
||||
struct audio_patch patch;
|
||||
struct audio_patch patch = {};
|
||||
data.read(&patch, sizeof(struct audio_patch));
|
||||
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
|
||||
if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) {
|
||||
|
@ -1284,7 +1290,7 @@ status_t BnAudioPolicyService::onTransact(
|
|||
|
||||
case RELEASE_AUDIO_PATCH: {
|
||||
CHECK_INTERFACE(IAudioPolicyService, data, reply);
|
||||
audio_patch_handle_t handle;
|
||||
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
|
||||
data.read(&handle, sizeof(audio_patch_handle_t));
|
||||
status_t status = releaseAudioPatch(handle);
|
||||
reply->writeInt32(status);
|
||||
|
@ -1323,8 +1329,9 @@ status_t BnAudioPolicyService::onTransact(
|
|||
|
||||
case SET_AUDIO_PORT_CONFIG: {
|
||||
CHECK_INTERFACE(IAudioPolicyService, data, reply);
|
||||
struct audio_port_config config;
|
||||
struct audio_port_config config = {};
|
||||
data.read(&config, sizeof(struct audio_port_config));
|
||||
(void)sanitizeAudioPortConfig(&config);
|
||||
status_t status = setAudioPortConfig(&config);
|
||||
reply->writeInt32(status);
|
||||
return NO_ERROR;
|
||||
|
@ -1398,9 +1405,10 @@ status_t BnAudioPolicyService::onTransact(
|
|||
|
||||
case START_AUDIO_SOURCE: {
|
||||
CHECK_INTERFACE(IAudioPolicyService, data, reply);
|
||||
struct audio_port_config source;
|
||||
struct audio_port_config source = {};
|
||||
data.read(&source, sizeof(struct audio_port_config));
|
||||
audio_attributes_t attributes;
|
||||
(void)sanitizeAudioPortConfig(&source);
|
||||
audio_attributes_t attributes = {};
|
||||
data.read(&attributes, sizeof(audio_attributes_t));
|
||||
sanetizeAudioAttributes(&attributes);
|
||||
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
|
||||
|
@ -1453,6 +1461,14 @@ status_t BnAudioPolicyService::onTransact(
|
|||
}
|
||||
}
|
||||
|
||||
/** returns true if string overflow was prevented by zero termination */
|
||||
template <size_t size>
|
||||
static bool preventStringOverflow(char (&s)[size]) {
|
||||
if (strnlen(s, size) < size) return false;
|
||||
s[size - 1] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
void BnAudioPolicyService::sanetizeAudioAttributes(audio_attributes_t* attr)
|
||||
{
|
||||
const size_t tagsMaxSize = AUDIO_ATTRIBUTES_TAGS_MAX_SIZE;
|
||||
|
@ -1462,6 +1478,27 @@ void BnAudioPolicyService::sanetizeAudioAttributes(audio_attributes_t* attr)
|
|||
attr->tags[tagsMaxSize - 1] = '\0';
|
||||
}
|
||||
|
||||
/** returns BAD_VALUE if sanitization was required. */
|
||||
status_t BnAudioPolicyService::sanitizeEffectDescriptor(effect_descriptor_t* desc)
|
||||
{
|
||||
if (preventStringOverflow(desc->name)
|
||||
| /* always */ preventStringOverflow(desc->implementor)) {
|
||||
android_errorWriteLog(0x534e4554, "73126106"); // SafetyNet logging
|
||||
return BAD_VALUE;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
/** returns BAD_VALUE if sanitization was required. */
|
||||
status_t BnAudioPolicyService::sanitizeAudioPortConfig(struct audio_port_config* config)
|
||||
{
|
||||
if (config->type == AUDIO_PORT_TYPE_DEVICE &&
|
||||
preventStringOverflow(config->ext.device.address)) {
|
||||
return BAD_VALUE;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
} // namespace android
|
||||
|
|
2
android/frameworks/av/media/libaudioclient/include/media/IAudioPolicyService.h
Normal file → Executable file
2
android/frameworks/av/media/libaudioclient/include/media/IAudioPolicyService.h
Normal file → Executable file
|
@ -185,6 +185,8 @@ public:
|
|||
uint32_t flags = 0);
|
||||
private:
|
||||
void sanetizeAudioAttributes(audio_attributes_t* attr);
|
||||
status_t sanitizeEffectDescriptor(effect_descriptor_t* desc);
|
||||
status_t sanitizeAudioPortConfig(struct audio_port_config* config);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
2
android/frameworks/av/media/libaudiohal/ConversionHelperHidl.cpp
Normal file → Executable file
2
android/frameworks/av/media/libaudiohal/ConversionHelperHidl.cpp
Normal file → Executable file
|
@ -77,7 +77,7 @@ void ConversionHelperHidl::parametersToHal(
|
|||
for (size_t i = 0; i < parameters.size(); ++i) {
|
||||
params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
|
||||
}
|
||||
values->setTo(params.keysToString());
|
||||
values->setTo(params.toString());
|
||||
}
|
||||
|
||||
ConversionHelperHidl::ConversionHelperHidl(const char* className)
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -6373,6 +6373,7 @@ static inline int processRenderThreadCommand(omx_vdec* pSelf, CdcMessage* pMsg)
|
|||
{
|
||||
case RENDER_THREAD_CMD_START:
|
||||
case RENDER_THREAD_CMD_EXECUT:
|
||||
ret = OMX_RESULT_EXECUT;
|
||||
case RENDER_THREAD_CMD_CONTINUE:
|
||||
break;
|
||||
case RENDER_THREAD_CMD_PAUSE:
|
||||
|
@ -6425,7 +6426,7 @@ static void* RenderThread(void* pThreadData)
|
|||
tryPostSem(&pSelf->m_render_cmd_lock);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
else if(ret == OMX_RESULT_EXECUT)
|
||||
{
|
||||
bPause = OMX_FALSE;
|
||||
}
|
||||
|
@ -6504,6 +6505,7 @@ static void* ComponentThread(void* pThreadData)
|
|||
|
||||
int64_t nTimeUs1;
|
||||
int64_t nTimeUs2;
|
||||
OMX_U32 nGetFbmBufInfoCount = 0;
|
||||
|
||||
int nSemVal;
|
||||
int nRetSemGetValue;
|
||||
|
@ -6574,6 +6576,15 @@ process_command:
|
|||
{
|
||||
OmxSetOutEos(pSelf);
|
||||
}
|
||||
|
||||
nGetFbmBufInfoCount++;
|
||||
if(nGetFbmBufInfoCount > 3000)
|
||||
{
|
||||
logw("*** someting is error, trigger error!");
|
||||
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
||||
OMX_EventError, 0x01, 0, NULL);
|
||||
}
|
||||
|
||||
if(CdcMessageQueueTryGetMessage(pSelf->mqMainThread, &msg, 20) == 0)
|
||||
{
|
||||
logw("*** get new command when get video fbm-buf-info");
|
||||
|
|
|
@ -168,23 +168,6 @@ static VIDEO_PROFILE_LEVEL_TYPE SupportedAVCProfileLevels[] = {
|
|||
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel5},
|
||||
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel51},
|
||||
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2 },
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3 },
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel41},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel5},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel51},
|
||||
|
||||
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1 },
|
||||
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b},
|
||||
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11},
|
||||
|
@ -202,6 +185,23 @@ static VIDEO_PROFILE_LEVEL_TYPE SupportedAVCProfileLevels[] = {
|
|||
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel5},
|
||||
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel51},
|
||||
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2 },
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3 },
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel41},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel5},
|
||||
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel51},
|
||||
|
||||
{-1,-1}
|
||||
};
|
||||
|
||||
|
|
|
@ -122,6 +122,11 @@ nWidth=%d, nHeight=%d nAlignStride = %d",
|
|||
pFbmCreateInfo->nFrameNum,
|
||||
pFbmCreateInfo->nDecoderNeededMiniFrameNum,
|
||||
nWidth, nHeight, nAlignStride);
|
||||
if(nWidth >= 7680 || nHeight >= 4320)
|
||||
{
|
||||
loge("width or height too large , can not create fbm buffer.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = (Fbm*)malloc(sizeof(Fbm));
|
||||
if(p == NULL)
|
||||
|
|
|
@ -562,7 +562,7 @@ static void detectWithStartCode(SbmFrame* pSbm)
|
|||
{
|
||||
if(supplyStreamData(pSbm) != 0)
|
||||
{
|
||||
if(pDetectInfo->bCurFrameStartCodeFound == 1 && pSbm->nEosFlag == 1)
|
||||
if(/*pDetectInfo->bCurFrameStartCodeFound == 1 &&*/ pSbm->nEosFlag == 1)
|
||||
{
|
||||
pDetectInfo->bCurFrameStartCodeFound = 0;
|
||||
chooseFramePts(pDetectInfo);
|
||||
|
|
15
android/frameworks/av/media/libmedia/include/media/CryptoHal.h
Normal file → Executable file
15
android/frameworks/av/media/libmedia/include/media/CryptoHal.h
Normal file → Executable file
|
@ -79,7 +79,20 @@ private:
|
|||
*/
|
||||
status_t mInitCheck;
|
||||
|
||||
KeyedVector<int32_t, uint32_t> mHeapBases;
|
||||
struct HeapBase {
|
||||
HeapBase() : mBufferId(0), mSize(0) {}
|
||||
HeapBase(uint32_t bufferId, size_t size) :
|
||||
mBufferId(bufferId), mSize(size) {}
|
||||
|
||||
uint32_t getBufferId() const {return mBufferId;}
|
||||
size_t getSize() const {return mSize;}
|
||||
|
||||
private:
|
||||
uint32_t mBufferId;
|
||||
size_t mSize;
|
||||
};
|
||||
|
||||
KeyedVector<int32_t, HeapBase> mHeapBases;
|
||||
uint32_t mNextBufferId;
|
||||
int32_t mHeapSeqNum;
|
||||
|
||||
|
|
3
android/frameworks/av/media/libstagefright/ItemTable.cpp
Normal file → Executable file
3
android/frameworks/av/media/libstagefright/ItemTable.cpp
Normal file → Executable file
|
@ -1335,7 +1335,8 @@ status_t ItemTable::buildImageItemsIfPossible(uint32_t type) {
|
|||
ALOGV("adding %s: itemId %d", image.isGrid() ? "grid" : "image", info.itemId);
|
||||
|
||||
if (image.isGrid()) {
|
||||
if (size > 12) {
|
||||
// ImageGrid struct is at least 8-byte, at most 12-byte (if flags&1)
|
||||
if (size < 8 || size > 12) {
|
||||
return ERROR_MALFORMED;
|
||||
}
|
||||
uint8_t buf[12];
|
||||
|
|
5
android/frameworks/av/media/libstagefright/MidiExtractor.cpp
Normal file → Executable file
5
android/frameworks/av/media/libstagefright/MidiExtractor.cpp
Normal file → Executable file
|
@ -246,8 +246,9 @@ MediaBuffer* MidiEngine::readBuffer() {
|
|||
EAS_I32 numRendered;
|
||||
EAS_RESULT result = EAS_Render(mEasData, p, mEasConfig->mixBufferSize, &numRendered);
|
||||
if (result != EAS_SUCCESS) {
|
||||
ALOGE("EAS_Render returned %ld", result);
|
||||
break;
|
||||
ALOGE("EAS_Render() returned %ld, numBytesOutput = %d", result, numBytesOutput);
|
||||
buffer->release();
|
||||
return NULL; // Stop processing to prevent infinite loops.
|
||||
}
|
||||
p += numRendered * mEasConfig->numChannels;
|
||||
numBytesOutput += numRendered * mEasConfig->numChannels * sizeof(EAS_PCM);
|
||||
|
|
5
android/frameworks/av/media/libstagefright/VideoFrameScheduler.cpp
Normal file → Executable file
5
android/frameworks/av/media/libstagefright/VideoFrameScheduler.cpp
Normal file → Executable file
|
@ -129,6 +129,11 @@ bool VideoFrameScheduler::PLL::fit(
|
|||
numSamplesToUse = mNumSamples;
|
||||
}
|
||||
|
||||
if ((period >> kPrecision) == 0 ) {
|
||||
ALOGW("Period is 0, or after including precision is 0 - would cause div0, returning");
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t sumX = 0;
|
||||
int64_t sumXX = 0;
|
||||
int64_t sumXY = 0;
|
||||
|
|
37
android/frameworks/av/media/libstagefright/httplive/M3UParser.cpp
Normal file → Executable file
37
android/frameworks/av/media/libstagefright/httplive/M3UParser.cpp
Normal file → Executable file
|
@ -56,7 +56,7 @@ struct M3UParser::MediaGroup : public RefBase {
|
|||
const char *language,
|
||||
uint32_t flags);
|
||||
|
||||
bool getActiveURI(AString *uri) const;
|
||||
bool getActiveURI(AString *uri, const char *baseURL) const;
|
||||
|
||||
void pickRandomMediaItems();
|
||||
status_t selectTrack(size_t index, bool select);
|
||||
|
@ -75,6 +75,7 @@ private:
|
|||
AString mURI;
|
||||
AString mLanguage;
|
||||
uint32_t mFlags;
|
||||
AString makeURL(const char *baseURL) const;
|
||||
};
|
||||
|
||||
Type mType;
|
||||
|
@ -227,12 +228,16 @@ sp<AMessage> M3UParser::MediaGroup::getTrackInfo(size_t index) const {
|
|||
return format;
|
||||
}
|
||||
|
||||
bool M3UParser::MediaGroup::getActiveURI(AString *uri) const {
|
||||
bool M3UParser::MediaGroup::getActiveURI(AString *uri, const char *baseURL) const {
|
||||
for (size_t i = 0; i < mMediaItems.size(); ++i) {
|
||||
if (mSelectedIndex >= 0 && i == (size_t)mSelectedIndex) {
|
||||
const Media &item = mMediaItems.itemAt(i);
|
||||
|
||||
*uri = item.mURI;
|
||||
if (item.mURI.empty()) {
|
||||
*uri = "";
|
||||
} else {
|
||||
*uri = item.makeURL(baseURL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +326,7 @@ bool M3UParser::itemAt(size_t index, AString *uri, sp<AMessage> *meta) {
|
|||
}
|
||||
|
||||
if (uri) {
|
||||
*uri = mItems.itemAt(index).mURI;
|
||||
*uri = mItems.itemAt(index).makeURL(mBaseURI.c_str());
|
||||
}
|
||||
|
||||
if (meta) {
|
||||
|
@ -427,7 +432,7 @@ bool M3UParser::getTypeURI(size_t index, const char *key, AString *uri) const {
|
|||
AString groupID;
|
||||
if (!meta->findString(key, &groupID)) {
|
||||
if (uri != NULL) {
|
||||
*uri = mItems.itemAt(index).mURI;
|
||||
*uri = mItems.itemAt(index).makeURL(mBaseURI.c_str());
|
||||
}
|
||||
|
||||
AString codecs;
|
||||
|
@ -458,12 +463,12 @@ bool M3UParser::getTypeURI(size_t index, const char *key, AString *uri) const {
|
|||
// don't care about the active URI (or if there is an active one)
|
||||
if (uri != NULL) {
|
||||
sp<MediaGroup> group = mMediaGroups.valueFor(groupID);
|
||||
if (!group->getActiveURI(uri)) {
|
||||
if (!group->getActiveURI(uri, mBaseURI.c_str())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((*uri).empty()) {
|
||||
*uri = mItems.itemAt(index).mURI;
|
||||
*uri = mItems.itemAt(index).makeURL(mBaseURI.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -544,6 +549,18 @@ static bool MakeURL(const char *baseURL, const char *url, AString *out) {
|
|||
return true;
|
||||
}
|
||||
|
||||
AString M3UParser::Item::makeURL(const char *baseURL) const {
|
||||
AString out;
|
||||
CHECK(MakeURL(baseURL, mURI.c_str(), &out));
|
||||
return out;
|
||||
}
|
||||
|
||||
AString M3UParser::MediaGroup::Media::makeURL(const char *baseURL) const {
|
||||
AString out;
|
||||
CHECK(MakeURL(baseURL, mURI.c_str(), &out));
|
||||
return out;
|
||||
}
|
||||
|
||||
status_t M3UParser::parse(const void *_data, size_t size) {
|
||||
int32_t lineNo = 0;
|
||||
|
||||
|
@ -674,7 +691,7 @@ status_t M3UParser::parse(const void *_data, size_t size) {
|
|||
mItems.push();
|
||||
Item *item = &mItems.editItemAt(mItems.size() - 1);
|
||||
|
||||
CHECK(MakeURL(mBaseURI.c_str(), line.c_str(), &item->mURI));
|
||||
item->mURI = line;
|
||||
|
||||
item->mMeta = itemMeta;
|
||||
|
||||
|
@ -1186,9 +1203,7 @@ status_t M3UParser::parseMedia(const AString &line) {
|
|||
|
||||
AString tmp(val, 1, val.size() - 2);
|
||||
|
||||
if (!MakeURL(mBaseURI.c_str(), tmp.c_str(), &groupURI)) {
|
||||
ALOGI("Failed to make absolute URI from '%s'.", tmp.c_str());
|
||||
}
|
||||
groupURI = tmp;
|
||||
|
||||
haveGroupURI = true;
|
||||
}
|
||||
|
|
1
android/frameworks/av/media/libstagefright/httplive/M3UParser.h
Normal file → Executable file
1
android/frameworks/av/media/libstagefright/httplive/M3UParser.h
Normal file → Executable file
|
@ -64,6 +64,7 @@ private:
|
|||
struct Item {
|
||||
AString mURI;
|
||||
sp<AMessage> mMeta;
|
||||
AString makeURL(const char *baseURL) const;
|
||||
};
|
||||
|
||||
status_t mInitCheck;
|
||||
|
|
24
android/frameworks/av/media/libstagefright/id3/ID3.cpp
Normal file → Executable file
24
android/frameworks/av/media/libstagefright/id3/ID3.cpp
Normal file → Executable file
|
@ -328,12 +328,25 @@ struct id3_header {
|
|||
}
|
||||
|
||||
void ID3::removeUnsynchronization() {
|
||||
for (size_t i = 0; i + 1 < mSize; ++i) {
|
||||
if (mData[i] == 0xff && mData[i + 1] == 0x00) {
|
||||
memmove(&mData[i + 1], &mData[i + 2], mSize - i - 2);
|
||||
--mSize;
|
||||
|
||||
// This file has "unsynchronization", so we have to replace occurrences
|
||||
// of 0xff 0x00 with just 0xff in order to get the real data.
|
||||
|
||||
size_t writeOffset = 1;
|
||||
for (size_t readOffset = 1; readOffset < mSize; ++readOffset) {
|
||||
if (mData[readOffset - 1] == 0xff && mData[readOffset] == 0x00) {
|
||||
continue;
|
||||
}
|
||||
// Only move data if there's actually something to move.
|
||||
// This handles the special case of the data being only [0xff, 0x00]
|
||||
// which should be converted to just 0xff if unsynchronization is on.
|
||||
mData[writeOffset++] = mData[readOffset];
|
||||
}
|
||||
|
||||
if (writeOffset < mSize) {
|
||||
mSize = writeOffset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void WriteSyncsafeInteger(uint8_t *dst, size_t x) {
|
||||
|
@ -593,6 +606,9 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
|
|||
// UCS-2
|
||||
// API wants number of characters, not number of bytes...
|
||||
int len = n / 2;
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
const char16_t *framedata = (const char16_t *) (frameData + 1);
|
||||
char16_t *framedatacopy = NULL;
|
||||
if (*framedata == 0xfffe) {
|
||||
|
|
86
android/frameworks/av/media/libstagefright/omx/OMXNodeInstance.cpp
Normal file → Executable file
86
android/frameworks/av/media/libstagefright/omx/OMXNodeInstance.cpp
Normal file → Executable file
|
@ -686,6 +686,7 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
|
|||
|
||||
CLOG_CONFIG(setPortMode, "%s(%d), port %d", asString(mode), mode, portIndex);
|
||||
|
||||
status_t err = OK;
|
||||
switch (mode) {
|
||||
case IOMX::kPortModeDynamicANWBuffer:
|
||||
{
|
||||
|
@ -694,17 +695,19 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
|
|||
CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
|
||||
"not setting port mode to %s(%d) on output",
|
||||
asString(mode), mode);
|
||||
return StatusFromOMXError(OMX_ErrorUnsupportedIndex);
|
||||
err = StatusFromOMXError(OMX_ErrorUnsupportedIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
status_t err = enableNativeBuffers_l(
|
||||
err = enableNativeBuffers_l(
|
||||
portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
|
||||
return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
|
||||
err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
case IOMX::kPortModeDynamicNativeHandle:
|
||||
|
@ -712,13 +715,15 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
|
|||
if (portIndex != kPortIndexInput) {
|
||||
CLOG_ERROR(setPortMode, BAD_VALUE,
|
||||
"%s(%d) mode is only supported on input port", asString(mode), mode);
|
||||
return BAD_VALUE;
|
||||
err = BAD_VALUE;
|
||||
break;
|
||||
}
|
||||
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
|
||||
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
|
||||
|
||||
MetadataBufferType metaType = kMetadataBufferTypeNativeHandleSource;
|
||||
return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
|
||||
err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
|
||||
break;
|
||||
}
|
||||
|
||||
case IOMX::kPortModePresetSecureBuffer:
|
||||
|
@ -726,7 +731,8 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
|
|||
// Allow on both input and output.
|
||||
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
|
||||
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
|
||||
return enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
|
||||
err = enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
case IOMX::kPortModePresetANWBuffer:
|
||||
|
@ -734,7 +740,8 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
|
|||
if (portIndex != kPortIndexOutput) {
|
||||
CLOG_ERROR(setPortMode, BAD_VALUE,
|
||||
"%s(%d) mode is only supported on output port", asString(mode), mode);
|
||||
return BAD_VALUE;
|
||||
err = BAD_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if we're simulating legacy mode with metadata mode,
|
||||
|
@ -743,7 +750,7 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
|
|||
if (storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL) == OK) {
|
||||
CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
|
||||
"metdata mode enabled successfully");
|
||||
return OK;
|
||||
break;
|
||||
}
|
||||
|
||||
CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
|
||||
|
@ -754,15 +761,15 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
|
|||
|
||||
// Disable secure buffer and enable graphic buffer
|
||||
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
|
||||
status_t err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
|
||||
err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
|
||||
// Not running experiment, or metadata is not supported.
|
||||
// Disable metadata mode and use legacy mode.
|
||||
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
|
||||
return OK;
|
||||
break;
|
||||
}
|
||||
|
||||
case IOMX::kPortModePresetByteBuffer:
|
||||
|
@ -771,15 +778,19 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
|
|||
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
|
||||
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
|
||||
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
|
||||
return OK;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CLOG_ERROR(setPortMode, BAD_VALUE, "invalid port mode %d", mode);
|
||||
return BAD_VALUE;
|
||||
default:
|
||||
CLOG_ERROR(setPortMode, BAD_VALUE, "invalid port mode %d", mode);
|
||||
err = BAD_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (err == OK) {
|
||||
mPortMode[portIndex] = mode;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
status_t OMXNodeInstance::enableNativeBuffers_l(
|
||||
|
@ -1057,28 +1068,52 @@ status_t OMXNodeInstance::useBuffer(
|
|||
}
|
||||
|
||||
switch (omxBuffer.mBufferType) {
|
||||
case OMXBuffer::kBufferTypePreset:
|
||||
case OMXBuffer::kBufferTypePreset: {
|
||||
if (mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer
|
||||
&& mPortMode[portIndex] != IOMX::kPortModeDynamicNativeHandle) {
|
||||
break;
|
||||
}
|
||||
return useBuffer_l(portIndex, NULL, NULL, buffer);
|
||||
}
|
||||
|
||||
case OMXBuffer::kBufferTypeSharedMem:
|
||||
case OMXBuffer::kBufferTypeSharedMem: {
|
||||
if (mPortMode[portIndex] != IOMX::kPortModePresetByteBuffer
|
||||
&& mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer) {
|
||||
break;
|
||||
}
|
||||
return useBuffer_l(portIndex, omxBuffer.mMem, NULL, buffer);
|
||||
}
|
||||
|
||||
case OMXBuffer::kBufferTypeANWBuffer:
|
||||
case OMXBuffer::kBufferTypeANWBuffer: {
|
||||
if (mPortMode[portIndex] != IOMX::kPortModePresetANWBuffer
|
||||
&& mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer) {
|
||||
break;
|
||||
}
|
||||
return useGraphicBuffer_l(portIndex, omxBuffer.mGraphicBuffer, buffer);
|
||||
}
|
||||
|
||||
case OMXBuffer::kBufferTypeHidlMemory: {
|
||||
if (mPortMode[portIndex] != IOMX::kPortModePresetByteBuffer
|
||||
&& mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer
|
||||
&& mPortMode[portIndex] != IOMX::kPortModeDynamicNativeHandle) {
|
||||
break;
|
||||
}
|
||||
sp<IHidlMemory> hidlMemory = mapMemory(omxBuffer.mHidlMemory);
|
||||
if (hidlMemory == nullptr) {
|
||||
ALOGE("OMXNodeInstance useBuffer() failed to map memory");
|
||||
return NO_MEMORY;
|
||||
}
|
||||
return useBuffer_l(portIndex, NULL, hidlMemory, buffer);
|
||||
}
|
||||
}
|
||||
default:
|
||||
return BAD_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return BAD_VALUE;
|
||||
ALOGE("b/77486542 : bufferType = %d vs. portMode = %d",
|
||||
omxBuffer.mBufferType, mPortMode[portIndex]);
|
||||
android_errorWriteLog(0x534e4554, "77486542");
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
|
||||
status_t OMXNodeInstance::useBuffer_l(
|
||||
|
@ -1514,6 +1549,11 @@ status_t OMXNodeInstance::allocateSecureBuffer(
|
|||
android_errorWriteLog(0x534e4554, "35467458");
|
||||
return BAD_VALUE;
|
||||
}
|
||||
if (mPortMode[portIndex] != IOMX::kPortModePresetSecureBuffer) {
|
||||
ALOGE("b/77486542");
|
||||
android_errorWriteLog(0x534e4554, "77486542");
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
BufferMeta *buffer_meta = new BufferMeta(portIndex);
|
||||
|
||||
OMX_BUFFERHEADERTYPE *header;
|
||||
|
|
8
android/frameworks/av/media/ndk/NdkMediaCodec.cpp
Normal file → Executable file
8
android/frameworks/av/media/ndk/NdkMediaCodec.cpp
Normal file → Executable file
|
@ -553,7 +553,13 @@ AMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new(
|
|||
size_t *encryptedbytes) {
|
||||
|
||||
// size needed to store all the crypto data
|
||||
size_t cryptosize = sizeof(AMediaCodecCryptoInfo) + sizeof(size_t) * numsubsamples * 2;
|
||||
size_t cryptosize;
|
||||
// = sizeof(AMediaCodecCryptoInfo) + sizeof(size_t) * numsubsamples * 2;
|
||||
if (__builtin_mul_overflow(sizeof(size_t) * 2, numsubsamples, &cryptosize) ||
|
||||
__builtin_add_overflow(cryptosize, sizeof(AMediaCodecCryptoInfo), &cryptosize)) {
|
||||
ALOGE("crypto size overflow");
|
||||
return NULL;
|
||||
}
|
||||
AMediaCodecCryptoInfo *ret = (AMediaCodecCryptoInfo*) malloc(cryptosize);
|
||||
if (!ret) {
|
||||
ALOGE("couldn't allocate %zu bytes", cryptosize);
|
||||
|
|
1
android/frameworks/av/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
Normal file → Executable file
1
android/frameworks/av/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
Normal file → Executable file
|
@ -385,6 +385,7 @@ AudioPortConfig::AudioPortConfig()
|
|||
mSamplingRate = 0;
|
||||
mChannelMask = AUDIO_CHANNEL_NONE;
|
||||
mFormat = AUDIO_FORMAT_INVALID;
|
||||
memset(&mGain, 0, sizeof(struct audio_gain_config));
|
||||
mGain.index = -1;
|
||||
}
|
||||
|
||||
|
|
4
android/frameworks/av/services/oboeservice/AAudioServiceEndpoint.h
Normal file → Executable file
4
android/frameworks/av/services/oboeservice/AAudioServiceEndpoint.h
Normal file → Executable file
|
@ -49,9 +49,9 @@ public:
|
|||
|
||||
virtual aaudio_result_t close() = 0;
|
||||
|
||||
virtual aaudio_result_t registerStream(android::sp<AAudioServiceStreamBase> stream);
|
||||
aaudio_result_t registerStream(android::sp<AAudioServiceStreamBase> stream);
|
||||
|
||||
virtual aaudio_result_t unregisterStream(android::sp<AAudioServiceStreamBase> stream);
|
||||
aaudio_result_t unregisterStream(android::sp<AAudioServiceStreamBase> stream);
|
||||
|
||||
virtual aaudio_result_t startStream(android::sp<AAudioServiceStreamBase> stream,
|
||||
audio_port_handle_t *clientHandle) = 0;
|
||||
|
|
57
android/frameworks/av/services/oboeservice/AAudioServiceStreamBase.cpp
Normal file → Executable file
57
android/frameworks/av/services/oboeservice/AAudioServiceStreamBase.cpp
Normal file → Executable file
|
@ -104,6 +104,9 @@ aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest
|
|||
goto error;
|
||||
}
|
||||
|
||||
// This is not protected by a lock because the stream cannot be
|
||||
// referenced until the service returns a handle to the client.
|
||||
// So only one thread can open a stream.
|
||||
mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService,
|
||||
request,
|
||||
sharingMode);
|
||||
|
@ -112,6 +115,9 @@ aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest
|
|||
result = AAUDIO_ERROR_UNAVAILABLE;
|
||||
goto error;
|
||||
}
|
||||
// Save a weak pointer that we will use to access the endpoint.
|
||||
mServiceEndpointWeak = mServiceEndpoint;
|
||||
|
||||
mFramesPerBurst = mServiceEndpoint->getFramesPerBurst();
|
||||
copyFrom(*mServiceEndpoint);
|
||||
}
|
||||
|
@ -130,15 +136,19 @@ aaudio_result_t AAudioServiceStreamBase::close() {
|
|||
|
||||
stop();
|
||||
|
||||
if (mServiceEndpoint == nullptr) {
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
result = AAUDIO_ERROR_INVALID_STATE;
|
||||
} else {
|
||||
mServiceEndpoint->unregisterStream(this);
|
||||
AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
|
||||
mEndpointManager.closeEndpoint(mServiceEndpoint);
|
||||
mServiceEndpoint.clear();
|
||||
endpoint->unregisterStream(this);
|
||||
AAudioEndpointManager &endpointManager = AAudioEndpointManager::getInstance();
|
||||
endpointManager.closeEndpoint(endpoint);
|
||||
|
||||
// AAudioService::closeStream() prevents two threads from closing at the same time.
|
||||
mServiceEndpoint.clear(); // endpoint will hold the pointer until this method returns.
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
|
||||
stopTimestampThread();
|
||||
|
@ -152,7 +162,12 @@ aaudio_result_t AAudioServiceStreamBase::close() {
|
|||
|
||||
aaudio_result_t AAudioServiceStreamBase::startDevice() {
|
||||
mClientHandle = AUDIO_PORT_HANDLE_NONE;
|
||||
return mServiceEndpoint->startStream(this, &mClientHandle);
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
ALOGE("%s() has no endpoint", __func__);
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
return endpoint->startStream(this, &mClientHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,16 +177,11 @@ aaudio_result_t AAudioServiceStreamBase::startDevice() {
|
|||
*/
|
||||
aaudio_result_t AAudioServiceStreamBase::start() {
|
||||
aaudio_result_t result = AAUDIO_OK;
|
||||
|
||||
if (isRunning()) {
|
||||
return AAUDIO_OK;
|
||||
}
|
||||
|
||||
if (mServiceEndpoint == nullptr) {
|
||||
ALOGE("AAudioServiceStreamBase::start() missing endpoint");
|
||||
result = AAUDIO_ERROR_INVALID_STATE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Start with fresh presentation timestamps.
|
||||
mAtomicTimestamp.clear();
|
||||
|
||||
|
@ -198,10 +208,6 @@ aaudio_result_t AAudioServiceStreamBase::pause() {
|
|||
if (!isRunning()) {
|
||||
return result;
|
||||
}
|
||||
if (mServiceEndpoint == nullptr) {
|
||||
ALOGE("AAudioServiceStreamShared::pause() missing endpoint");
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
// Send it now because the timestamp gets rounded up when stopStream() is called below.
|
||||
// Also we don't need the timestamps while we are shutting down.
|
||||
|
@ -213,7 +219,12 @@ aaudio_result_t AAudioServiceStreamBase::pause() {
|
|||
return result;
|
||||
}
|
||||
|
||||
result = mServiceEndpoint->stopStream(this, mClientHandle);
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
ALOGE("%s() has no endpoint", __func__);
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
result = endpoint->stopStream(this, mClientHandle);
|
||||
if (result != AAUDIO_OK) {
|
||||
ALOGE("AAudioServiceStreamShared::pause() mServiceEndpoint returned %d", result);
|
||||
disconnect(); // TODO should we return or pause Base first?
|
||||
|
@ -230,11 +241,6 @@ aaudio_result_t AAudioServiceStreamBase::stop() {
|
|||
return result;
|
||||
}
|
||||
|
||||
if (mServiceEndpoint == nullptr) {
|
||||
ALOGE("AAudioServiceStreamShared::stop() missing endpoint");
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
// Send it now because the timestamp gets rounded up when stopStream() is called below.
|
||||
// Also we don't need the timestamps while we are shutting down.
|
||||
sendCurrentTimestamp(); // warning - this calls a virtual function
|
||||
|
@ -244,8 +250,13 @@ aaudio_result_t AAudioServiceStreamBase::stop() {
|
|||
return result;
|
||||
}
|
||||
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
ALOGE("%s() has no endpoint", __func__);
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
// TODO wait for data to be played out
|
||||
result = mServiceEndpoint->stopStream(this, mClientHandle);
|
||||
result = endpoint->stopStream(this, mClientHandle);
|
||||
if (result != AAUDIO_OK) {
|
||||
ALOGE("AAudioServiceStreamShared::stop() mServiceEndpoint returned %d", result);
|
||||
disconnect();
|
||||
|
|
5
android/frameworks/av/services/oboeservice/AAudioServiceStreamBase.h
Normal file → Executable file
5
android/frameworks/av/services/oboeservice/AAudioServiceStreamBase.h
Normal file → Executable file
|
@ -233,7 +233,12 @@ protected:
|
|||
SimpleDoubleBuffer<Timestamp> mAtomicTimestamp;
|
||||
|
||||
android::AAudioService &mAudioService;
|
||||
|
||||
// The mServiceEndpoint variable can be accessed by multiple threads.
|
||||
// So we access it by locally promoting a weak pointer to a smart pointer,
|
||||
// which is thread-safe.
|
||||
android::sp<AAudioServiceEndpoint> mServiceEndpoint;
|
||||
android::wp<AAudioServiceEndpoint> mServiceEndpointWeak;
|
||||
|
||||
private:
|
||||
aaudio_handle_t mHandle = -1;
|
||||
|
|
55
android/frameworks/av/services/oboeservice/AAudioServiceStreamMMAP.cpp
Normal file → Executable file
55
android/frameworks/av/services/oboeservice/AAudioServiceStreamMMAP.cpp
Normal file → Executable file
|
@ -70,14 +70,19 @@ aaudio_result_t AAudioServiceStreamMMAP::open(const aaudio::AAudioStreamRequest
|
|||
return result;
|
||||
}
|
||||
|
||||
result = mServiceEndpoint->registerStream(keep);
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
ALOGE("%s() has no endpoint", __func__);
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
result = endpoint->registerStream(keep);
|
||||
if (result != AAUDIO_OK) {
|
||||
goto error;
|
||||
return result;
|
||||
}
|
||||
|
||||
setState(AAUDIO_STREAM_STATE_OPEN);
|
||||
|
||||
error:
|
||||
return AAUDIO_OK;
|
||||
}
|
||||
|
||||
|
@ -122,21 +127,37 @@ aaudio_result_t AAudioServiceStreamMMAP::stop() {
|
|||
|
||||
aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client,
|
||||
audio_port_handle_t *clientHandle) {
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
ALOGE("%s() has no endpoint", __func__);
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
// Start the client on behalf of the application. Generate a new porthandle.
|
||||
aaudio_result_t result = mServiceEndpoint->startClient(client, clientHandle);
|
||||
aaudio_result_t result = endpoint->startClient(client, clientHandle);
|
||||
return result;
|
||||
}
|
||||
|
||||
aaudio_result_t AAudioServiceStreamMMAP::stopClient(audio_port_handle_t clientHandle) {
|
||||
aaudio_result_t result = mServiceEndpoint->stopClient(clientHandle);
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
ALOGE("%s() has no endpoint", __func__);
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
aaudio_result_t result = endpoint->stopClient(clientHandle);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get free-running DSP or DMA hardware position from the HAL.
|
||||
aaudio_result_t AAudioServiceStreamMMAP::getFreeRunningPosition(int64_t *positionFrames,
|
||||
int64_t *timeNanos) {
|
||||
sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
|
||||
static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
ALOGE("%s() has no endpoint", __func__);
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
|
||||
static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
|
||||
|
||||
aaudio_result_t result = serviceEndpointMMAP->getFreeRunningPosition(positionFrames, timeNanos);
|
||||
if (result == AAUDIO_OK) {
|
||||
Timestamp timestamp(*positionFrames, *timeNanos);
|
||||
|
@ -152,8 +173,15 @@ aaudio_result_t AAudioServiceStreamMMAP::getFreeRunningPosition(int64_t *positio
|
|||
// Get timestamp that was written by getFreeRunningPosition()
|
||||
aaudio_result_t AAudioServiceStreamMMAP::getHardwareTimestamp(int64_t *positionFrames,
|
||||
int64_t *timeNanos) {
|
||||
sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
|
||||
static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
|
||||
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
ALOGE("%s() has no endpoint", __func__);
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
|
||||
static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
|
||||
|
||||
// TODO Get presentation timestamp from the HAL
|
||||
if (mAtomicTimestamp.isValid()) {
|
||||
Timestamp timestamp = mAtomicTimestamp.read();
|
||||
|
@ -171,7 +199,12 @@ aaudio_result_t AAudioServiceStreamMMAP::getHardwareTimestamp(int64_t *positionF
|
|||
aaudio_result_t AAudioServiceStreamMMAP::getAudioDataDescription(
|
||||
AudioEndpointParcelable &parcelable)
|
||||
{
|
||||
sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
|
||||
static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
ALOGE("%s() has no endpoint", __func__);
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
|
||||
static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
|
||||
return serviceEndpointMMAP->getDownDataDescription(parcelable);
|
||||
}
|
||||
|
|
29
android/frameworks/av/services/oboeservice/AAudioServiceStreamShared.cpp
Normal file → Executable file
29
android/frameworks/av/services/oboeservice/AAudioServiceStreamShared.cpp
Normal file → Executable file
|
@ -128,6 +128,11 @@ aaudio_result_t AAudioServiceStreamShared::open(const aaudio::AAudioStreamReques
|
|||
|
||||
const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
|
||||
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
result = AAUDIO_ERROR_INVALID_STATE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Is the request compatible with the shared endpoint?
|
||||
setFormat(configurationInput.getFormat());
|
||||
|
@ -141,20 +146,20 @@ aaudio_result_t AAudioServiceStreamShared::open(const aaudio::AAudioStreamReques
|
|||
|
||||
setSampleRate(configurationInput.getSampleRate());
|
||||
if (getSampleRate() == AAUDIO_UNSPECIFIED) {
|
||||
setSampleRate(mServiceEndpoint->getSampleRate());
|
||||
} else if (getSampleRate() != mServiceEndpoint->getSampleRate()) {
|
||||
setSampleRate(endpoint->getSampleRate());
|
||||
} else if (getSampleRate() != endpoint->getSampleRate()) {
|
||||
ALOGE("AAudioServiceStreamShared::open() mSampleRate = %d, need %d",
|
||||
getSampleRate(), mServiceEndpoint->getSampleRate());
|
||||
getSampleRate(), endpoint->getSampleRate());
|
||||
result = AAUDIO_ERROR_INVALID_RATE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
setSamplesPerFrame(configurationInput.getSamplesPerFrame());
|
||||
if (getSamplesPerFrame() == AAUDIO_UNSPECIFIED) {
|
||||
setSamplesPerFrame(mServiceEndpoint->getSamplesPerFrame());
|
||||
} else if (getSamplesPerFrame() != mServiceEndpoint->getSamplesPerFrame()) {
|
||||
setSamplesPerFrame(endpoint->getSamplesPerFrame());
|
||||
} else if (getSamplesPerFrame() != endpoint->getSamplesPerFrame()) {
|
||||
ALOGE("AAudioServiceStreamShared::open() mSamplesPerFrame = %d, need %d",
|
||||
getSamplesPerFrame(), mServiceEndpoint->getSamplesPerFrame());
|
||||
getSamplesPerFrame(), endpoint->getSamplesPerFrame());
|
||||
result = AAUDIO_ERROR_OUT_OF_RANGE;
|
||||
goto error;
|
||||
}
|
||||
|
@ -181,9 +186,9 @@ aaudio_result_t AAudioServiceStreamShared::open(const aaudio::AAudioStreamReques
|
|||
}
|
||||
|
||||
ALOGD("AAudioServiceStreamShared::open() actual rate = %d, channels = %d, deviceId = %d",
|
||||
getSampleRate(), getSamplesPerFrame(), mServiceEndpoint->getDeviceId());
|
||||
getSampleRate(), getSamplesPerFrame(), endpoint->getDeviceId());
|
||||
|
||||
result = mServiceEndpoint->registerStream(keep);
|
||||
result = endpoint->registerStream(keep);
|
||||
if (result != AAUDIO_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
@ -250,7 +255,13 @@ aaudio_result_t AAudioServiceStreamShared::getHardwareTimestamp(int64_t *positio
|
|||
int64_t *timeNanos) {
|
||||
|
||||
int64_t position = 0;
|
||||
aaudio_result_t result = mServiceEndpoint->getTimestamp(&position, timeNanos);
|
||||
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
|
||||
if (endpoint == nullptr) {
|
||||
ALOGE("%s() has no endpoint", __func__);
|
||||
return AAUDIO_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
aaudio_result_t result = endpoint->getTimestamp(&position, timeNanos);
|
||||
if (result == AAUDIO_OK) {
|
||||
int64_t offset = mTimestampPositionOffset.load();
|
||||
// TODO, do not go below starting value
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue