nsresult
AppleMP3Reader::ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags)
{
MOZ_ASSERT(OnTaskQueue());
*aTags = nullptr;
/*
* Feed bytes into the parser until we have all the metadata we need to
* set up the decoder. When the parser has enough data, it will
* synchronously call back to |AudioMetadataCallback| below.
*/
OSStatus rv;
nsresult readrv;
uint32_t offset = 0;
do {
char bytes[AUDIO_READ_BYTES];
uint32_t numBytes = AUDIO_READ_BYTES;
readrv = Read(&numBytes, bytes);
rv = AudioFileStreamParseBytes(mAudioFileStream,
numBytes,
bytes,
0 /* flags */);
mMP3FrameParser.Parse(reinterpret_cast<uint8_t*>(bytes), numBytes, offset);
offset += numBytes;
// We have to do our decoder setup from the callback. When it's done it will
// set mStreamReady.
} while (!mStreamReady && !rv && NS_SUCCEEDED(readrv));
if (rv) {
LOGE("Error decoding audio stream metadata\n");
return NS_ERROR_FAILURE;
}
if (!mAudioConverter) {
LOGE("Failed to setup the AudioToolbox audio decoder\n");
return NS_ERROR_FAILURE;
}
if (!mMP3FrameParser.IsMP3()) {
LOGE("Frame parser failed to parse MP3 stream\n");
return NS_ERROR_FAILURE;
}
if (mStreamReady) {
aInfo->mAudio.mRate = mAudioSampleRate;
aInfo->mAudio.mChannels = mAudioChannels;
}
// This special snowflake reader doesn't seem to set *aInfo = mInfo like all
// the others. Yuck.
mDuration = mMP3FrameParser.GetDuration();
mInfo.mMetadataDuration.emplace(TimeUnit::FromMicroseconds(mDuration));
aInfo->mMetadataDuration.emplace(TimeUnit::FromMicroseconds(mDuration));
return NS_OK;
}
bool TangoData::SetConfig(bool is_auto_recovery) {
// Get the default TangoConfig.
// We get the default config first and change the config
// flag as needed.
config_ = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
if (config_ == NULL) {
LOGE("TangoService_getConfig(): Failed");
return false;
}
// Turn on auto recovery for motion tracking.
// Note that the auto-recovery is on by default.
if (TangoConfig_setBool(config_, "config_enable_auto_recovery",
is_auto_recovery) != TANGO_SUCCESS) {
LOGE("config_enable_auto_recovery(): Failed");
return false;
}
// Get library version string from service.
TangoConfig_getString(config_, "tango_service_library_version",
const_cast<char*>(lib_version_string.c_str()),
kVersionStringLength);
// Setting up the start of service to ADF frame for the onPoseAvailable
// callback,
// it will check the localization status.
TangoCoordinateFramePair pair;
pair.base = TANGO_COORDINATE_FRAME_AREA_DESCRIPTION;
pair.target = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
// Attach onPoseAvailable callback.
// The callback will be called after the service is connected.
if (TangoService_connectOnPoseAvailable(1, &pair, onPoseAvailable) !=
TANGO_SUCCESS) {
LOGE("TangoService_connectOnPoseAvailable(): Failed");
return false;
}
// Attach onEventAvailable callback.
// The callback will be called after the service is connected.
if (TangoService_connectOnTangoEvent(onTangoEvent) != TANGO_SUCCESS) {
LOGE("TangoService_connectOnTangoEvent(): Failed");
return false;
}
// Load the most recent ADF.
char* uuid_list;
// uuid_list will contain a comma separated list of UUIDs.
if (TangoService_getAreaDescriptionUUIDList(&uuid_list) != TANGO_SUCCESS) {
LOGI("TangoService_getAreaDescriptionUUIDList");
}
// Parse the uuid_list to get the individual uuids.
if (uuid_list != NULL && uuid_list[0] != '\0') {
vector<string> adf_list;
char* parsing_char;
parsing_char = strtok(uuid_list, ",");
while (parsing_char != NULL) {
string s = string(parsing_char);
adf_list.push_back(s);
parsing_char = strtok(NULL, ",");
}
int list_size = adf_list.size();
if (list_size == 0) {
LOGE("List size is 0");
return false;
}
cur_uuid = adf_list[list_size - 1];
if (TangoConfig_setString(config_, "config_load_area_description_UUID",
adf_list[list_size - 1].c_str()) !=
TANGO_SUCCESS) {
LOGE("config_load_area_description_uuid Failed");
return false;
} else {
LOGI("Load ADF: %s", adf_list[list_size - 1].c_str());
}
} else {
LOGE("No area description file available, no file loaded.");
}
is_localized = false;
return true;
}
/*
* Invoke a method, using the specified arguments and return type, through
* one of the reflection interfaces. Could be a virtual or direct method
* (including constructors). Used for reflection.
*
* Deals with boxing/unboxing primitives and performs widening conversions.
*
* "invokeObj" will be null for a static method.
*
* If the invocation returns with an exception raised, we have to wrap it.
*/
Object* dvmInvokeMethod(Object* obj, const Method* method,
ArrayObject* argList, ArrayObject* params, ClassObject* returnType,
bool noAccessCheck)
{
ClassObject* clazz;
Object* retObj = NULL;
Thread* self = dvmThreadSelf();
s4* ins;
int verifyCount, argListLength;
JValue retval;
/* verify arg count */
if (argList != NULL)
argListLength = argList->length;
else
argListLength = 0;
if (argListLength != (int) params->length) {
LOGI("invoke: expected %d args, received %d args\n",
params->length, argListLength);
dvmThrowException("Ljava/lang/IllegalArgumentException;",
"wrong number of arguments");
return NULL;
}
clazz = callPrep(self, method, obj, !noAccessCheck);
if (clazz == NULL)
return NULL;
/* "ins" for new frame start at frame pointer plus locals */
ins = ((s4*)self->curFrame) + (method->registersSize - method->insSize);
verifyCount = 0;
//LOGD(" FP is %p, INs live at >= %p\n", self->curFrame, ins);
/* put "this" pointer into in0 if appropriate */
if (!dvmIsStaticMethod(method)) {
assert(obj != NULL);
*ins++ = (s4) obj;
verifyCount++;
}
/*
* Copy the args onto the stack. Primitive types are converted when
* necessary, and object types are verified.
*/
DataObject** args;
ClassObject** types;
int i;
args = (DataObject**) argList->contents;
types = (ClassObject**) params->contents;
for (i = 0; i < argListLength; i++) {
int width;
width = dvmConvertArgument(*args++, *types++, ins);
if (width < 0) {
if (*(args-1) != NULL) {
LOGV("invoke: type mismatch on arg %d ('%s' '%s')\n",
i, (*(args-1))->obj.clazz->descriptor,
(*(types-1))->descriptor);
}
dvmPopFrame(self); // throw wants to pull PC out of stack
dvmThrowException("Ljava/lang/IllegalArgumentException;",
"argument type mismatch");
goto bail_popped;
}
ins += width;
verifyCount += width;
}
if (verifyCount != method->insSize) {
LOGE("Got vfycount=%d insSize=%d for %s.%s\n", verifyCount,
method->insSize, clazz->descriptor, method->name);
assert(false);
goto bail;
}
//dvmDumpThreadStack(dvmThreadSelf());
if (dvmIsNativeMethod(method)) {
/*
* Because we leave no space for local variables, "curFrame" points
* directly at the method arguments.
*/
(*method->nativeFunc)(self->curFrame, &retval, method, self);
} else {
dvmInterpret(self, method, &retval);
}
//.........这里部分代码省略.........
/**
* @brief Handle inotify events
*
* Calls the callcbacks
*
* @param files nb max of logs destination directories (crashlog,
* aplogs, bz... )
*
* @return 0 on success, -1 on error.
*/
int receive_inotify_events(int inotify_fd) {
int len = 0, orig_len, idx, wd, missing_bytes;
char orig_buffer[sizeof(struct inotify_event)+PATHMAX], *buffer, lastevent[sizeof(struct inotify_event)+PATHMAX];
struct inotify_event *event;
struct watch_entry *entry = NULL;
len = read(inotify_fd, orig_buffer, sizeof(orig_buffer));
if (len < 0) {
LOGE("%s: Cannot read file_monitor_fd, error is %s\n", __FUNCTION__, strerror(errno));
return -errno;
}
buffer = &orig_buffer[0];
orig_len = len;
event = (struct inotify_event *)buffer;
/* Preinitialize lastevent (in case it was not used so it is not dumped) */
((struct inotify_event *)lastevent)->wd = 0;
((struct inotify_event *)lastevent)->mask = 0;
((struct inotify_event *)lastevent)->cookie = 0;
((struct inotify_event *)lastevent)->len = 0;
while (1) {
if (len == 0) {
/* End of the events to read */
return 0;
}
if ((unsigned int)len < sizeof(struct inotify_event)) {
/* Not enough room for an empty event */
LOGI("%s: incomplete inotify_event received (%d bytes), complete it\n", __FUNCTION__, len);
/* copy the last bytes received */
if( (unsigned int)len <= sizeof(lastevent) )
memcpy(lastevent, buffer, len);
else {
LOGE("%s: Cannot copy buffer\n", __FUNCTION__);
return -1;
}
/* read the missing bytes to get the full length */
missing_bytes = (int)sizeof(struct inotify_event)-len;
if(((int) len + missing_bytes) < ((int)sizeof(lastevent))) {
if (read(inotify_fd, &lastevent[len], missing_bytes) != missing_bytes ){
LOGE("%s: Cannot complete the last inotify_event received (structure part) - %s\n", __FUNCTION__, strerror(errno));
return -1;
}
}
else {
LOGE("%s: Cannot read missing bytes, not enought space in lastevent\n", __FUNCTION__);
return -1;
}
event = (struct inotify_event*)lastevent;
/* now, reads the full last event, including its name field */
if ( read(inotify_fd, &lastevent[sizeof(struct inotify_event)],
event->len) != (int)event->len) {
LOGE("%s: Cannot complete the last inotify_event received (name part) - %s\n",
__FUNCTION__, strerror(errno));
return -1;
}
len = 0;
/* now, the last event is complete, we can continue the parsing */
} else if ( (unsigned int)len < sizeof(struct inotify_event) + event->len ) {
int res, missing_bytes = (int)sizeof(struct inotify_event) + event->len - len;
event = (struct inotify_event*)lastevent;
/* The event was truncated */
LOGI("%s: truncated inotify_event received (%d bytes missing), complete it\n", __FUNCTION__, missing_bytes);
/* Robustness : check 'lastevent' array size before reading inotify fd*/
if( (unsigned int)len > sizeof(lastevent) ) {
LOGE("%s: not enough space on array lastevent.\n", __FUNCTION__);
return -1;
}
/* copy the last bytes received */
memcpy(lastevent, buffer, len);
/* now, reads the full last event, including its name field */
res = read(inotify_fd, &lastevent[len], missing_bytes);
if ( res != missing_bytes ) {
LOGE("%s: Cannot complete the last inotify_event received (name part2); received %d bytes, expected %d bytes - %s\n",
__FUNCTION__, res, missing_bytes, strerror(errno));
return -1;
}
len = 0;
/* now, the last event is complete, we can continue the parsing */
} else {
event = (struct inotify_event *)buffer;
buffer += sizeof(struct inotify_event) + event->len;
len -= sizeof(struct inotify_event) + event->len;
}
/* Handle the event read from the buffer*/
/* First check the kind of the subject of this event (file or directory?) */
if (!(event->mask & IN_ISDIR)) {
/* event concerns a file into a watched directory */
//.........这里部分代码省略.........
int libxl__openptys(libxl__openpty_state *op,
struct termios *termp,
struct winsize *winp) {
/*
* This is completely crazy. openpty calls grantpt which the spec
* says may fork, and may not be called with a SIGCHLD handler.
* Now our application may have a SIGCHLD handler so that's bad.
* We could perhaps block it but we'd need to block it on all
* threads. This is just Too Hard.
*
* So instead, we run openpty in a child process. That child
* process then of course has only our own thread and our own
* signal handlers. We pass the fds back.
*
* Since our only current caller actually wants two ptys, we
* support calling openpty multiple times for a single fork.
*/
STATE_AO_GC(op->ao);
int count = op->count;
int r, i, rc, sockets[2], ptyfds[count][2];
libxl__carefd *for_child = 0;
pid_t pid = -1;
for (i=0; i<count; i++) {
ptyfds[i][0] = ptyfds[i][1] = -1;
libxl__openpty_result *res = &op->results[i];
assert(!res->master);
assert(!res->slave);
}
sockets[0] = sockets[1] = -1; /* 0 is for us, 1 for our child */
libxl__carefd_begin();
r = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
if (r) { sockets[0] = sockets[1] = -1; }
for_child = libxl__carefd_opened(CTX, sockets[1]);
if (r) { LOGE(ERROR,"socketpair failed"); rc = ERROR_FAIL; goto out; }
pid = libxl__ev_child_fork(gc, &op->child, openpty_exited);
if (pid == -1) {
rc = ERROR_FAIL;
goto out;
}
if (!pid) {
/* child */
close(sockets[0]);
signal(SIGCHLD, SIG_DFL);
for (i=0; i<count; i++) {
r = openpty(&ptyfds[i][0], &ptyfds[i][1], NULL, termp, winp);
if (r) { LOGE(ERROR,"openpty failed"); _exit(-1); }
}
rc = libxl__sendmsg_fds(gc, sockets[1], "",1,
2*count, &ptyfds[0][0], "ptys");
if (rc) { LOGE(ERROR,"sendmsg to parent failed"); _exit(-1); }
_exit(0);
}
libxl__carefd_close(for_child);
for_child = 0;
/* this should be fast so do it synchronously */
libxl__carefd_begin();
char buf[1];
rc = libxl__recvmsg_fds(gc, sockets[0], buf,1,
2*count, &ptyfds[0][0], "ptys");
if (!rc) {
for (i=0; i<count; i++) {
libxl__openpty_result *res = &op->results[i];
res->master = libxl__carefd_record(CTX, ptyfds[i][0]);
res->slave = libxl__carefd_record(CTX, ptyfds[i][1]);
}
}
/* now the pty fds are in the carefds, if they were ever open */
libxl__carefd_unlock();
if (rc)
goto out;
rc = 0;
out:
if (sockets[0] >= 0) close(sockets[0]);
libxl__carefd_close(for_child);
if (libxl__ev_child_inuse(&op->child)) {
op->rc = rc;
/* we will get a callback when the child dies */
return 0;
}
assert(rc);
openpty_cleanup(op);
return rc;
}
/*
* Issue a method call with a variable number of arguments. We process
* the contents of "args" by scanning the method signature.
*
* Pass in NULL for "obj" on calls to static methods.
*
* We don't need to take the class as an argument because, in Dalvik,
* we don't need to worry about static synchronized methods.
*/
void dvmCallMethodV(Thread* self, const Method* method, Object* obj,
JValue* pResult, va_list args)
{
const char* desc = &(method->shorty[1]); // [0] is the return type.
int verifyCount = 0;
ClassObject* clazz;
u4* ins;
clazz = callPrep(self, method, obj, false);
if (clazz == NULL)
return;
/* "ins" for new frame start at frame pointer plus locals */
ins = ((u4*)self->curFrame) + (method->registersSize - method->insSize);
//LOGD(" FP is %p, INs live at >= %p\n", self->curFrame, ins);
/* put "this" pointer into in0 if appropriate */
if (!dvmIsStaticMethod(method)) {
#ifdef WITH_EXTRA_OBJECT_VALIDATION
assert(obj != NULL && dvmIsValidObject(obj));
#endif
*ins++ = (u4) obj;
verifyCount++;
}
while (*desc != '\0') {
switch (*(desc++)) {
case 'D': case 'J': {
u8 val = va_arg(args, u8);
memcpy(ins, &val, 8); // EABI prevents direct store
ins += 2;
verifyCount += 2;
break;
}
case 'F': {
/* floats were normalized to doubles; convert back */
float f = (float) va_arg(args, double);
*ins++ = dvmFloatToU4(f);
verifyCount++;
break;
}
#ifdef WITH_EXTRA_OBJECT_VALIDATION
case 'L': { /* 'shorty' descr uses L for all refs, incl array */
Object* argObj = (Object*) va_arg(args, u4);
assert(obj == NULL || dvmIsValidObject(obj));
*ins++ = (u4) argObj;
verifyCount++;
break;
}
#endif
default: {
*ins++ = va_arg(args, u4);
verifyCount++;
break;
}
}
}
#ifndef NDEBUG
if (verifyCount != method->insSize) {
LOGE("Got vfycount=%d insSize=%d for %s.%s\n", verifyCount,
method->insSize, clazz->descriptor, method->name);
assert(false);
goto bail;
}
#endif
//dvmDumpThreadStack(dvmThreadSelf());
if (dvmIsNativeMethod(method)) {
/*
* Because we leave no space for local variables, "curFrame" points
* directly at the method arguments.
*/
(*method->nativeFunc)(self->curFrame, pResult, method, self);
} else {
dvmInterpret(self, method, pResult);
}
bail:
dvmPopFrame(self);
}
请发表评论