/* * ======== AUDENC_processAsync ======== */ XDAS_Int32 AUDENC_processAsync(AUDENC_Handle handle, XDM_BufDesc *inBufs, XDM_BufDesc *outBufs, IAUDENC_InArgs *inArgs, IAUDENC_OutArgs *outArgs) { XDAS_Int32 retVal = AUDENC_EFAIL; /* * Note, we do this because someday we may allow dynamically changing * the global 'VISA_isChecked()' value on the fly. If we allow that, * we need to ensure the value stays consistent in the context of this call. */ Bool checked = VISA_isChecked(); GT_5trace(CURTRACE, GT_ENTER, "AUDENC_processAsync> " "Enter (handle=0x%x, inBufs=0x%x, outBufs=0x%x, inArgs=0x%x, " "outArgs=0x%x)\n", handle, inBufs, outBufs, inArgs, outArgs); if (handle) { IAUDENC_Handle alg = VISA_getAlgHandle((VISA_Handle)handle); if (alg != NULL) { if (checked) { /* * Zero out the outArgs struct (except for .size field); * it's write-only to the codec, so the app shouldn't pass * values through it, nor should the codec expect to * receive values through it. */ memset((void *)((XDAS_Int32)(outArgs) + sizeof(outArgs->size)), 0, (sizeof(*outArgs) - sizeof(outArgs->size))); } retVal = processAsync(alg, inBufs, outBufs, inArgs, outArgs); } } GT_2trace(CURTRACE, GT_ENTER, "AUDENC_processAsync> " "Exit (handle=0x%x, retVal=0x%x)\n", handle, retVal); return (retVal); }
/* * ======== VIDDEC2_processWait ======== */ XDAS_Int32 VIDDEC2BACK_processWait(VIDDEC2BACK_Handle handle, XDM_Context *context, VIDDEC2_OutArgs *outArgs, UInt timeout) { XDAS_Int32 retVal = VIDDEC2_EFAIL; /* * Note, we do this because someday we may allow dynamically changing * the global 'VISA_isChecked()' value on the fly. If we allow that, * we need to ensure the value stays consistent in the context of this call. */ Bool checked = VISA_isChecked(); Log_print4(Diags_ENTRY, "[+E] VIDDEC2BACK_processWait> " "Enter (handle=0x%x, context=0x%x, outArgs=0x%x (size=0x%x))", (IArg)handle, (IArg)context, (IArg)outArgs, (IArg)(outArgs->size)); if (handle) { IVIDDEC2BACK_Handle alg = VISA_getAlgHandle((VISA_Handle)handle); if (alg != NULL) { if (checked) { /* TBD */ } retVal = processWait(alg, context, outArgs, timeout); if (checked) { /* TBD */ } } } Log_print2(Diags_EXIT, "[+X] VIDDEC2BACK_processWait> " "Exit (handle=0x%x, retVal=0x%x)", (IArg)handle, (IArg)retVal); return (retVal); }
/* * ======== unmarshallMsg ======== */ static Void unmarshallMsg(IAUDDEC1_Handle h, XDM1_BufDesc *inBufs, XDM1_BufDesc *outBufs, IAUDDEC1_InArgs *inArgs, IAUDDEC1_OutArgs *outArgs, _AUDDEC1_Msg *msg) { VISA_Handle visa = (VISA_Handle)h; IAUDDEC1_OutArgs *pMsgOutArgs; /* * Do a wholesale replace of skeleton returned structure. */ pMsgOutArgs = (IAUDDEC1_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + inArgs->size); if (VISA_isChecked()) { /* ensure the codec didn't change outArgs->size */ Assert_isTrue(pMsgOutArgs->size == outArgs->size, (Assert_Id)NULL); } memcpy(outArgs, pMsgOutArgs, outArgs->size); /* * Note, we can keep the original outBufs, since audio * decoder codecs return buffers in order, and the caller's * outBufs already contains the virtual buffer pointers. * * Note also that we did *nothing* with inBufs nor inArgs. * * Note also that we _don't_ update inBufs->descs[].accessMask. * That's accurate, since the local processor _didn't_ * read the inBuf. */ VISA_freeMsg(visa, (VISA_Msg)msg); return; }
/* * ======== SPHENC_control ======== * This method must be the same for both local and remote invocation; * each call site in the client might be calling different implementations * (one that marshalls & sends and one that simply calls). This API * abstracts *all* speech encoders (both high and low complexity * encoders are envoked using this method). */ XDAS_Int32 SPHENC_control(SPHENC_Handle handle, ISPHENC_Cmd id, ISPHENC_DynamicParams *dynParams, ISPHENC_Status *status) { XDAS_Int32 retVal = SPHENC_EFAIL; SPHENC_DynamicParams refDynParams; XDAS_Int32 refStatusSize; /* * Note, we assign "VISA_isChecked()" results to a local variable * rather than repeatedly query it throughout this fxn because * someday we may allow dynamically changing the global * 'VISA_isChecked()' value on the fly. If we allow that, we need * to ensure the value stays consistent in the context of this * call. */ Bool checked = VISA_isChecked(); if (checked) { /* Ensure dynParams and status are non-NULL, per the XDM spec */ if ((!(XdmUtils_validateExtendedStruct(dynParams, sizeof(*dynParams), "dynParams"))) || (!(XdmUtils_validateExtendedStruct(status, sizeof(*status), "status")))) { /* for safety, return here before dereferencing and crashing */ return (retVal); } } GT_6trace(CURTRACE, GT_ENTER, "SPHENC_control> " "Enter (handle=0x%x, id=%d, dynParams=0x%x (size=0x%x), " "status=0x%x (size=0x%x)\n", handle, id, dynParams, dynParams->size, status, status->size); if (handle) { ISPHENC_Fxns *fxns = (ISPHENC_Fxns *)VISA_getAlgFxns((VISA_Handle)handle); ISPHENC_Handle alg = VISA_getAlgHandle((VISA_Handle)handle); if ((fxns != NULL) && (alg != NULL)) { Log_printf(ti_sdo_ce_dvtLog, "%s", (Arg)"SPHENC:control", (Arg)handle, (Arg)0); if (checked) { /* * Make a reference copy of dynParams, status->size, and * status->data.bufSize so we can check that the codec * didn't modify these read-only fields during control(). */ refDynParams = *dynParams; refStatusSize = status->size; } VISA_enter((VISA_Handle)handle); retVal = fxns->control(alg, id, dynParams, status); VISA_exit((VISA_Handle)handle); if (checked) { /* ensure the codec didn't modify the read-only dynParams */ if (memcmp(&refDynParams, dynParams, sizeof(*dynParams)) != 0) { GT_1trace(CURTRACE, GT_7CLASS, "ERROR> codec (0x%x) modified read-only dynParams " "struct!\n", handle); } /* ensure the codec didn't change status->size */ if (status->size != refStatusSize) { GT_1trace(CURTRACE, GT_7CLASS, "ERROR> codec (0x%x) modified read-only status->size " "field!\n", handle); } } } } GT_2trace(CURTRACE, GT_ENTER, "SPHENC_control> " "Exit (handle=0x%x, retVal=0x%x)\n", handle, retVal); return (retVal); }
/* * ======== SPHENC_process ======== * This method must be the same for both local and remote invocation; * each call site in the client might be calling different implementations * (one that marshalls & sends and one that simply calls). This API * abstracts *all* speech encoders (both high and low complexity * encoders are invoked using this method). */ XDAS_Int32 SPHENC_process(SPHENC_Handle handle, XDM_BufDesc *inBufs, XDM_BufDesc *outBufs, ISPHENC_InArgs *inArgs, ISPHENC_OutArgs *outArgs) { XDAS_Int32 retVal = SPHENC_EFAIL; SPHENC_InArgs refInArgs; /* * Note, we assign "VISA_isChecked()" results to a local variable * rather than repeatedly query it throughout this fxn because * someday we may allow dynamically changing the global * 'VISA_isChecked()' value on the fly. If we allow that, we need * to ensure the value stays consistent in the context of this * call. */ Bool checked = VISA_isChecked(); if (checked) { /* Ensure inArgs and outArgs are non-NULL, per the XDM spec */ if ((!(XdmUtils_validateExtendedStruct(inArgs, sizeof(*inArgs), "inArgs"))) || (!(XdmUtils_validateExtendedStruct(outArgs, sizeof(*outArgs), "outArgs")))) { /* for safety, return here before dereferencing and crashing */ return (retVal); } } GT_5trace(CURTRACE, GT_ENTER, "SPHENC_process> " "Enter (handle=0x%x, inBufs=0x%x, outBufs=0x%x, inArgs=0x%x, " "outArgs=0x%x)\n", handle, inBufs, outBufs, inArgs, outArgs); if (handle) { ISPHENC_Fxns *fxns = (ISPHENC_Fxns *)VISA_getAlgFxns((VISA_Handle)handle); ISPHENC_Handle alg = VISA_getAlgHandle((VISA_Handle)handle); if ((fxns != NULL) && (alg != NULL)) { Log_printf(ti_sdo_ce_dvtLog, "%s", (Arg)"SPHENC:process", (Arg)handle, (Arg)0); if (checked) { /* * Zero out the outArgs struct (except for .size field); * it's write-only to the codec, so the app shouldn't pass * values through it, nor should the codec expect to * receive values through it. */ memset((void *)((XDAS_Int32)(outArgs) + sizeof(outArgs->size)), 0, (sizeof(*outArgs) - sizeof(outArgs->size))); /* * Make a reference copy of inArgs so we can check that * the codec didn't modify them during process(). */ refInArgs = *inArgs; } VISA_enter((VISA_Handle)handle); retVal = fxns->process(alg, inBufs, outBufs, inArgs, outArgs); VISA_exit((VISA_Handle)handle); if (checked) { /* ensure the codec didn't modify the read-only inArgs */ if (memcmp(&refInArgs, inArgs, sizeof(*inArgs)) != 0) { GT_1trace(CURTRACE, GT_7CLASS, "ERROR> codec (0x%x) modified read-only inArgs " "struct!\n", handle); } } } } GT_2trace(CURTRACE, GT_ENTER, "SPHENC_process> " "Exit (handle=0x%x, retVal=0x%x)\n", handle, retVal); return (retVal); }
/* * ======== VIDDEC1_control ======== * This method must be the same for both local and remote invocation; * each call site in the client might be calling different implementations * (one that marshalls & sends and one that simply calls). This API * abstracts *all* video decoders (both high and low complexity * decoders are envoked using this method). */ XDAS_Int32 VIDDEC1_control(VIDDEC1_Handle handle, VIDDEC1_Cmd id, VIDDEC1_DynamicParams *dynParams, VIDDEC1_Status *status) { XDAS_Int32 retVal = VIDDEC1_EFAIL; VIDDEC1_DynamicParams refDynParams; XDAS_Int32 refStatusSize; XDAS_Int32 refStatusDataBufSize; /* * Note, we assign "VISA_isChecked()" results to a local variable * rather than repeatedly query it throughout this fxn because * someday we may allow dynamically changing the global * 'VISA_isChecked()' value on the fly. If we allow that, we need * to ensure the value stays consistent in the context of this * call. */ Bool checked = VISA_isChecked(); if (checked) { /* Ensure dynParams and status are non-NULL, per the XDM spec */ if ((!(XdmUtils_validateExtendedStruct(dynParams, sizeof(*dynParams), "dynParams"))) || (!(XdmUtils_validateExtendedStruct(status, sizeof(*status), "status")))) { /* for safety, return here before dereferencing and crashing */ return (retVal); } } Log_print6(Diags_ENTRY, "[+E] VIDDEC1_control> " "Enter (handle=0x%x, id=%d, dynParams=0x%x (size=0x%x), " "status=0x%x (size=0x%x)", (IArg)handle, (IArg)id, (IArg)dynParams, (IArg)(dynParams->size), (IArg)status, (IArg)(status->size)); if (handle) { IVIDDEC1_Fxns *fxns = (IVIDDEC1_Fxns *)VISA_getAlgFxns((VISA_Handle)handle); IVIDDEC1_Handle alg = VISA_getAlgHandle((VISA_Handle)handle); if ((fxns != NULL) && (alg != NULL)) { if (checked) { /* * Make a reference copy of dynParams, status->size, and * status->data.bufSize so we can check that the codec * didn't modify these read-only fields during control(). */ refDynParams = *dynParams; refStatusSize = status->size; refStatusDataBufSize = status->data.bufSize; } //Log_printf(ti_sdo_ce_dvtLog, "%s", (Arg)"VIDDEC1:control", // (Arg)handle, (Arg)0); VISA_enter((VISA_Handle)handle); retVal = fxns->control(alg, id, dynParams, status); VISA_exit((VISA_Handle)handle); if (checked) { /* ensure the codec didn't modify the read-only dynParams */ if (memcmp(&refDynParams, dynParams, sizeof(*dynParams)) != 0) { Log_print1(Diags_USER7, "[+7] ERROR> codec (0x%x) modified read-only dynParams " "struct!", (IArg)handle); } /* ensure the codec didn't change status->size */ if (status->size != refStatusSize) { Log_print1(Diags_USER7, "[+7] ERROR> codec (0x%x) modified read-only status->size " "field!", (IArg)handle); } /* ensure the codec didn't change status->data.bufSize */ if (status->data.bufSize != refStatusDataBufSize) { Log_print1(Diags_USER7, "[+7] ERROR> codec (0x%x) modified read-only " "status->data.bufSize field!", (IArg)handle); } } } } Log_print2(Diags_EXIT, "[+X] VIDDEC1_control> " "Exit (handle=0x%x, retVal=0x%x)", (IArg)handle, (IArg)retVal); return (retVal); }
/* * ======== VIDDEC1_process ======== * This method must be the same for both local and remote invocation; * each call site in the client might be calling different implementations * (one that marshalls & sends and one that simply calls). This API * abstracts *all* video decoders (both high and low complexity * decoders are invoked using this method). */ XDAS_Int32 VIDDEC1_process(VIDDEC1_Handle handle, XDM1_BufDesc *inBufs, XDM_BufDesc *outBufs, VIDDEC1_InArgs *inArgs, VIDDEC1_OutArgs *outArgs) { XDAS_Int32 retVal = VIDDEC1_EFAIL; VIDDEC1_InArgs refInArgs; Int32 i; /* * Note, we assign "VISA_isChecked()" results to a local variable * rather than repeatedly query it throughout this fxn because * someday we may allow dynamically changing the global * 'VISA_isChecked()' value on the fly. If we allow that, we need * to ensure the value stays consistent in the context of this * call. */ Bool checked = VISA_isChecked(); if (checked) { /* Ensure inArgs and outArgs are non-NULL, per the XDM spec */ if ((!(XdmUtils_validateExtendedStruct(inArgs, sizeof(*inArgs), "inArgs"))) || (!(XdmUtils_validateExtendedStruct(outArgs, sizeof(*outArgs), "outArgs")))) { /* for safety, return here before dereferencing and crashing */ return (retVal); } } Log_print5(Diags_ENTRY, "[+E] VIDDEC1_process> " "Enter (handle=0x%x, inBufs=0x%x, outBufs=0x%x, inArgs=0x%x, " "outArgs=0x%x)", (IArg)handle, (IArg)inBufs, (IArg)outBufs, (IArg)inArgs, (IArg)outArgs); if (handle) { IVIDDEC1_Fxns *fxns = (IVIDDEC1_Fxns *)VISA_getAlgFxns((VISA_Handle)handle); IVIDDEC1_Handle alg = VISA_getAlgHandle((VISA_Handle)handle); if ((fxns != NULL) && (alg != NULL)) { if (checked) { /* validate inArgs with ranges. */ if (inArgs->inputID == 0) { Log_print2(Diags_USER7, "[+7] ERROR> app provided codec (0x%x) with out of range " "inArgs->inputID field (0x%x)", (IArg)alg, (IArg)(inArgs->inputID)); } /* * Validate inBufs and outBufs. */ XdmUtils_validateSparseBufDesc1(inBufs, "inBufs"); XdmUtils_validateSparseBufDesc(outBufs, "outBufs"); /* * Make a reference copy of inArgs so we can check that * the codec didn't modify them during process(). */ refInArgs = *inArgs; } //Log_printf(ti_sdo_ce_dvtLog, "%s", (Arg)"VIDDEC1:process", // (Arg)handle, (Arg)0); VISA_enter((VISA_Handle)handle); retVal = fxns->process(alg, inBufs, outBufs, inArgs, outArgs); VISA_exit((VISA_Handle)handle); if (checked) { /* ensure the codec didn't modify the read-only inArgs */ if (memcmp(&refInArgs, inArgs, sizeof(*inArgs)) != 0) { Log_print1(Diags_USER7, "[+7] ERROR> codec (0x%x) modified read-only inArgs " "struct!", (IArg)handle); } /* only check these on successful return */ if ((retVal == IVIDDEC1_EOK) || (!(XDM_ISFATALERROR( outArgs->decodedBufs.extendedError)))) { /* Validate outArgs->decodedBufs */ XdmUtils_validateVideo1BufDesc(&(outArgs->decodedBufs), "decodedBufs"); } /* Validate outArgs->displayBufs */ for (i = 0; ((outArgs->outputID[i] != 0) && (i < XDM_MAX_IO_BUFFERS)); i++) { if ((retVal == IVIDDEC1_EOK) || (!(XDM_ISFATALERROR(outArgs-> displayBufs[i].extendedError)))) { XdmUtils_validateVideo1BufDesc(&(outArgs->displayBufs[i]), "displayBufs"); } } } } } Log_print2(Diags_EXIT, "[+X] VIDDEC1_process> " "Exit (handle=0x%x, retVal=0x%x)", (IArg)handle, (IArg)retVal); return (retVal); }
/* * ======== marshallMsg ======== */ static XDAS_Int32 marshallMsg(IVIDDEC2_Handle h, XDM1_BufDesc *inBufs, XDM_BufDesc *outBufs, IVIDDEC2_InArgs *inArgs, IVIDDEC2_OutArgs *outArgs, _VIDDEC2_Msg **pmsg) { XDAS_Int32 retVal = IVIDDEC2_EOK; VISA_Handle visa = (VISA_Handle)h; _VIDDEC2_Msg *msg; Int i; IVIDDEC2_OutArgs *pMsgOutArgs; Int numBufs; Int payloadSize; /* * Validate arguments. Do we want to do this _every_ time, or just in * checked builds? */ if ((inArgs == NULL) || (inArgs->size < sizeof(IVIDDEC2_InArgs)) || (outArgs == NULL) || (outArgs->size < sizeof(IVIDDEC2_OutArgs))) { /* invalid args, could even assert here, it's a spec violation. */ return (IVIDDEC2_EFAIL); } if (pmsg == NULL) { return (IVIDDEC2_EFAIL); } /* make sure it'll all fit! */ payloadSize = sizeof(VISA_MsgHeader) + (sizeof(*inBufs)) + (sizeof(outBufs[0]) * XDM_MAX_IO_BUFFERS) + sizeof(msg->cmd.process.numOutBufs) + (sizeof(msg->cmd.process.outBufSizes[0]) * XDM_MAX_IO_BUFFERS) + inArgs->size + outArgs->size; if (payloadSize > VISA_getMaxMsgSize(visa)) { /* Can't handle these large extended args. */ Log_print2(Diags_USER6, "[+6] process> invalid arguments - too big (0x%x > 0x%x). " "Validate .size fields", payloadSize, VISA_getMaxMsgSize(visa)); return (IVIDDEC2_EUNSUPPORTED); } /* get a message appropriate for this algorithm */ if ((msg = (_VIDDEC2_Msg *)VISA_allocMsg(visa)) == NULL) { return (IVIDDEC2_EFAIL); } /* zero out msg->cmd (not msg->visa!) */ memset(&(msg->cmd), 0, sizeof(msg->cmd)); /* * Marshall the command: copy the client-passed arguments into flattened * message data structures, converting every pointer address to alg. * data buffer into physical address. */ /* First specify the processing command that the skeleton should do */ msg->visa.cmd = _VIDDEC2_CPROCESS; /* commentary follows for marshalling the inBufs argument: */ /* 1) inBufs->numBufs is a plain integer, we just copy it */ msg->cmd.process.inBufs.numBufs = inBufs->numBufs; /* * 2) inBufs->bufSizes is a sparse array of integers, we copy them all. * * 3) inBufs->bufs is a pointer to a sparse array of pointers, so we take * individual pointers, convert them if non-NULL, and store them in the * message counterpart of inBufs->bufs. */ for (i = 0, numBufs = 0; ((numBufs < inBufs->numBufs) && (i < XDM_MAX_IO_BUFFERS)); i++) { if (inBufs->descs[i].buf != NULL) { /* valid member of sparse array, convert it */ msg->cmd.process.inBufs.descs[i].bufSize = inBufs->descs[i].bufSize; msg->cmd.process.inBufs.descs[i].buf = (XDAS_Int8 *) Memory_getBufferPhysicalAddress(inBufs->descs[i].buf, inBufs->descs[i].bufSize, NULL); if (msg->cmd.process.inBufs.descs[i].buf == NULL) { retVal = IVIDDEC2_EFAIL; goto exit; } /* Clear .accessMask; the local processor won't access this buf */ inBufs->descs[i].accessMask = 0; /* found, and handled, another buffer. */ numBufs++; } else { /* empty member of sparse array, no conversion needed. */ msg->cmd.process.inBufs.descs[i].bufSize = 0; msg->cmd.process.inBufs.descs[i].buf = NULL; } } if (VISA_isChecked()) { /* check that we found inBufs->numBufs pointers in inBufs->bufs[] */ Assert_isTrue(inBufs->numBufs == numBufs, (Assert_Id)NULL); } /* we're done (with inBufs). Because msg->cmd.process is non-cacheable * and contiguous (it has been allocated by MSGQ), we don't have to do * anything else. */ /* Now we repeat the procedure for outBufs. Note that * inArgs contains no pointers, so we can simply copy the * entire original structure, accounting for the first "size" field. */ msg->cmd.process.numOutBufs = outBufs->numBufs; for (i = 0, numBufs = 0; ((numBufs < outBufs->numBufs) && (i < XDM_MAX_IO_BUFFERS)); i++) { if (outBufs->bufs[i] != NULL) { /* valid member of sparse array, convert it */ msg->cmd.process.outBufSizes[i] = outBufs->bufSizes[i]; msg->cmd.process.outBufs[i] = (XDAS_Int8 *) Memory_getBufferPhysicalAddress(outBufs->bufs[i], outBufs->bufSizes[i], NULL); if (msg->cmd.process.outBufs[i] == NULL) { /* TODO:M - should add at least a trace statement when trace * is supported. Another good idea is to return something * more clear than EFAIL. */ retVal = IVIDDEC2_EFAIL; goto exit; } /* found, and handled, another buffer. */ numBufs++; } else { /* empty member of sparse array, no conversion needed */ msg->cmd.process.outBufSizes[i] = 0; msg->cmd.process.outBufs[i] = NULL; } } if (VISA_isChecked()) { /* check that we found outBufs->numBufs pointers in outBufs->bufs[] */ Assert_isTrue(outBufs->numBufs == numBufs, (Assert_Id)NULL); } /* inArgs has no pointers so simply memcpy "size" bytes into the msg */ memcpy(&(msg->cmd.process.inArgs), inArgs, inArgs->size); /* point at outArgs and set the "size" */ pMsgOutArgs = (IVIDDEC2_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + inArgs->size); /* set the size field - the rest is filled in by the codec */ pMsgOutArgs->size = outArgs->size; *pmsg = msg; return (retVal); exit: VISA_freeMsg(visa, (VISA_Msg)msg); return (retVal); }
/* * ======== control ======== * This is the stub-implementation for the control method */ static XDAS_Int32 control(IVIDDEC2_Handle h, IVIDDEC2_Cmd id, IVIDDEC2_DynamicParams *params, IVIDDEC2_Status *status) { XDAS_Int32 retVal; VISA_Handle visa = (VISA_Handle)h; _VIDDEC2_Msg *msg; IVIDDEC2_Status *pMsgStatus; XDAS_Int8 *virtAddr = NULL; Int payloadSize; /* * Validate arguments. Do we want to do this _every_ time, or just in * checked builds? */ if ((params == NULL) || (params->size < sizeof(IVIDDEC2_DynamicParams)) || (status == NULL) || (status->size < sizeof(IVIDDEC2_Status))) { /* invalid args, could even assert here, it's a spec violation. */ return (IVIDDEC2_EFAIL); } /* * Initialize extendedError to zero so we don't return something * uninitialized in extendedError. */ status->extendedError = 0; /* make sure it'll all fit! */ payloadSize = sizeof(VISA_MsgHeader) + sizeof(id) + params->size + status->size; if (payloadSize > VISA_getMaxMsgSize(visa)) { /* Can't handle these large extended args. */ Log_print2(Diags_USER6, "[+6] control> invalid arguments - too big (0x%x > 0x%x). " "Validate .size fields", payloadSize, VISA_getMaxMsgSize(visa)); return (IVIDDEC2_EUNSUPPORTED); } /* get a message appropriate for this algorithm */ if ((msg = (_VIDDEC2_Msg *)VISA_allocMsg(visa)) == NULL) { return (IVIDDEC2_EFAIL); } /* marshall the command */ msg->visa.cmd = _VIDDEC2_CCONTROL; msg->cmd.control.id = id; /* params has no pointers so simply memcpy "size" bytes into the msg */ memcpy(&(msg->cmd.control.params), params, params->size); /* unmarshall status based on the "size" of params */ pMsgStatus = (IVIDDEC2_Status *)((UInt)(&(msg->cmd.control.params)) + params->size); /* * Initialize the .size and .data fields - the rest are filled in by * the codec. */ pMsgStatus->size = status->size; if (status->data.buf != NULL) { pMsgStatus->data.bufSize = status->data.bufSize; /* save it for later */ virtAddr = status->data.buf; pMsgStatus->data.buf = (XDAS_Int8 *) Memory_getBufferPhysicalAddress(status->data.buf, status->data.bufSize, NULL); if (pMsgStatus->data.buf == NULL) { retVal = IVIDDEC2_EFAIL; goto exit; } } else { /* Place null into the msg so the skel knows it's invalid */ pMsgStatus->data.buf = NULL; } /* send the message to the skeleton and wait for completion */ retVal = VISA_call(visa, (VISA_Msg *)&msg); /* ensure we get CCONTROL msg (ensure async CPROCESS pipeline drained) */ Assert_isTrue(msg->visa.cmd == _VIDDEC2_CCONTROL, (Assert_Id)NULL); /* unmarshall status */ pMsgStatus = (IVIDDEC2_Status *)((UInt)(&(msg->cmd.control.params)) + params->size); if (VISA_isChecked()) { /* ensure codec didn't modify status->size */ Assert_isTrue(pMsgStatus->size == status->size, (Assert_Id)NULL); /* * TODO:L Should we also check that pMsgStatus->data.buf is the same * after the call as before? */ } memcpy(status, pMsgStatus, status->size); /* * And finally, restore status->data.buf to its original value. Note that * this works even when status->data.buf was NULL because virtAddr is * initialized to NULL. * * While potentially more confusing, this is just as correct as * (and faster than!) calling Memory_getVirtualBuffer(). */ status->data.buf = virtAddr; /* Clear .accessMask; the local processor didn't access the buffer */ status->data.accessMask = 0; exit: VISA_freeMsg(visa, (VISA_Msg)msg); return (retVal); }
/* * ======== IMGDEC1_processAsync ======== */ XDAS_Int32 IMGDEC1_processAsync(IMGDEC1_Handle handle, XDM1_BufDesc *inBufs, XDM1_BufDesc *outBufs, IMGDEC1_InArgs *inArgs, IMGDEC1_OutArgs *outArgs) { XDAS_Int32 retVal = IMGDEC1_EFAIL; /* * Note, we do this because someday we may allow dynamically changing * the global 'VISA_isChecked()' value on the fly. If we allow that, * we need to ensure the value stays consistent in the context of this call. */ Bool checked = VISA_isChecked(); Log_print5(Diags_ENTRY, "[+E] IMGDEC1_processAsync> " "Enter (handle=0x%x, inBufs=0x%x, outBufs=0x%x, inArgs=0x%x, " "outArgs=0x%x)", (IArg)handle, (IArg)inBufs, (IArg)outBufs, (IArg)inArgs, (IArg)outArgs); if (handle) { IIMGDEC1_Handle alg = VISA_getAlgHandle((VISA_Handle)handle); if (alg != NULL) { if (checked) { /* ensure valid sizes */ if (inArgs->size < sizeof(IIMGDEC1_InArgs)) { Log_print2(Diags_USER7, "[+7] ERROR> app provided codec (0x%x) with incorrectly " "sized InArgs struct (0x%x)field!", (IArg)handle, (IArg)(inArgs->size)); } if (outArgs->size < sizeof(IIMGDEC1_OutArgs)) { Log_print2(Diags_USER7, "[+7] ERROR> app provided codec (0x%x) with incorrectly " "sized outArgs struct (0x%x)field!", (IArg)handle, (IArg)(outArgs->size)); } /* * Validate inBufs and outBufs. */ XdmUtils_validateSparseBufDesc1(inBufs, "inBufs"); XdmUtils_validateSparseBufDesc1(outBufs, "outBufs"); /* * Zero out the outArgs struct (except for .size field); * it's write-only to the codec, so the app shouldn't pass * values through it, nor should the codec expect to * receive values through it. */ memset((void *)((XDAS_Int32)(outArgs) + sizeof(outArgs->size)), 0, (sizeof(*outArgs) - sizeof(outArgs->size))); } retVal = processAsync(alg, inBufs, outBufs, inArgs, outArgs); } } Log_print2(Diags_EXIT, "[+X] IMGDEC1_processAsync> " "Exit (handle=0x%x, retVal=0x%x)", (IArg)handle, (IArg)retVal); return (retVal); }
/* * ======== control ======== * This is the stub-implementation for the control method */ static XDAS_Int32 control(IVIDDEC2BACK_Handle h, XDM_Context *context, IVIDDEC2_Status *status) { XDAS_Int32 retVal; VISA_Handle visa = (VISA_Handle)h; _VIDDEC2BACK_Msg *msg; // IVIDDEC2_Status *pMsgStatus; // XDAS_Int8 *virtAddr = NULL; /* * Validate arguments. Do we want to do this _every_ time, or just in * checked builds? */ if ((context == NULL) || (status == NULL) || (status->size < sizeof(IVIDDEC2_Status))) { /* invalid args, could even assert here, it's a spec violation. */ return (IVIDDEC2_EFAIL); } if (/* size of "stuff to marshall" > message size */ (sizeof(VISA_MsgHeader) + sizeof(*context) + status->size) > sizeof(_VIDDEC2BACK_Msg)) { /* Can't handle these large extended args. */ Log_print0(Diags_USER6, "[+6] control> invalid arguments - validate .size fields"); return (IVIDDEC2_EUNSUPPORTED); } /* get a message appropriate for this algorithm */ if ((msg = (_VIDDEC2BACK_Msg *)VISA_allocMsg(visa)) == NULL) { return (IVIDDEC2_EFAIL); } /* marshall the command */ msg->visa.cmd = _VIDDEC2BACK_CCONTROL; /* * Initialize the .size and .data fields - the rest are filled in by * the codec. */ msg->cmd.control.status.size = status->size; #if 0 if (status->data.buf != NULL) { pMsgStatus->data.bufSize = status->data.bufSize; /* save it for later */ virtAddr = status->data.buf; pMsgStatus->data.buf = (XDAS_Int8 *) Memory_getBufferPhysicalAddress(status->data.buf, status->data.bufSize, NULL); if (pMsgStatus->data.buf == NULL) { retVal = IVIDDEC2_EFAIL; goto exit; } } else { /* Place null into the msg so the skel knows it's invalid */ pMsgStatus->data.buf = NULL; } #endif /* send the message to the skeleton and wait for completion */ retVal = VISA_call(visa, (VISA_Msg *)&msg); /* ensure we get CCONTROL msg (ensure async CPROCESS pipeline drained) */ Assert_isTrue(msg->visa.cmd == _VIDDEC2BACK_CCONTROL, (Assert_Id)NULL); if (VISA_isChecked()) { /* ensure codec didn't modify status->size */ Assert_isTrue(msg->cmd.control.status.size == status->size, (Assert_Id)NULL); /* * TODO:L Should we also check that pMsgStatus->data.buf is the same * after the call as before? */ } memcpy(status, &(msg->cmd.control.status), status->size); #if 0 /* * And finally, restore status->data.buf to its original value. Note that * this works even when status->data.buf was NULL because virtAddr is * initialized to NULL. * * While potentially more confusing, this is just as correct as * (and faster than!) calling Memory_getVirtualBuffer(). */ status->data.buf = virtAddr; /* Clear .accessMask; the local processor didn't access the buffer */ status->data.accessMask = 0; #endif //exit: VISA_freeMsg(visa, (VISA_Msg)msg); return (retVal); }
/* * ======== unmarshallMsg ======== */ static XDAS_Int32 unmarshallMsg(IVIDDEC2BACK_Handle h, XDM_Context *context, IVIDDEC2_OutArgs *outArgs, _VIDDEC2BACK_Msg *msg, XDAS_Int32 retVal) { VISA_Handle visa = (VISA_Handle)h; Int i; Int numBufs; #if 0 if (VISA_isChecked()) { /* ensure the codec didn't change outArgs->size */ Assert_isTrue(msg->cmd.process.outArgs.size == outArgs->size, (Assert_Id)NULL); } #endif memcpy(outArgs, &(msg->cmd.process.outArgs), outArgs->size); /* if VISA_call was successful, also unmarshall outBufs */ if (retVal == IVIDDEC2_EOK) { /* unmarshall the output data: outBufs and outArgs. */ if (VISA_isChecked()) { /* sanity check context */ Assert_isTrue(msg->cmd.process.context.numInBufs < XDM_MAX_CONTEXT_BUFFERS, (Assert_Id)NULL); Assert_isTrue(msg->cmd.process.context.numOutBufs < XDM_MAX_CONTEXT_BUFFERS, (Assert_Id)NULL); Assert_isTrue(msg->cmd.process.context.numInOutBufs == 0, (Assert_Id)NULL); } /* The outBufs may have changed, so don't rely on what was passed in */ context->numOutBufs = msg->cmd.process.context.numOutBufs; numBufs = copySparseSingleBufDescArrayWithP2V(context->outBufs, msg->cmd.process.context.outBufs, context->numOutBufs, XDM_MAX_CONTEXT_BUFFERS); if (numBufs == -1) { retVal = IVIDDEC2_EFAIL; goto exit; } if (VISA_isChecked()) { /* check that we found the indicated number of buffers */ Assert_isTrue(context->numOutBufs == numBufs, (Assert_Id)NULL); } /* address translate the decoded buffers */ copySingleBufDescArrayWithP2V(outArgs->decodedBufs.bufDesc, outArgs->decodedBufs.bufDesc, IVIDEO_MAX_YUV_BUFFERS); /* buffers in outArgs.displayBufs are physical, so convert them */ for (i = 0; i < IVIDDEC2_MAX_IO_BUFFERS; i++) { if (outArgs->outputID[i] != 0) { copySingleBufDescArrayWithP2V(outArgs->displayBufs[i].bufDesc, outArgs->displayBufs[i].bufDesc, IVIDEO_MAX_YUV_BUFFERS); } } /* and finally the mbDataBuf */ if (outArgs->mbDataBuf.buf != NULL) { Memory_getBufferVirtualAddress((UInt32)outArgs->mbDataBuf.buf, outArgs->mbDataBuf.bufSize); /* Clear .accessMask; the local processor didn't access this buf */ outArgs->mbDataBuf.accessMask = 0; } } exit: VISA_freeMsg(visa, (VISA_Msg)msg); return (retVal); }
/* * ======== marshallMsg ======== */ static XDAS_Int32 marshallMsg(IVIDDEC2BACK_Handle h, XDM_Context *context, IVIDDEC2_OutArgs *outArgs, _VIDDEC2BACK_Msg **pmsg) { XDAS_Int32 retVal = IVIDDEC2_EOK; VISA_Handle visa = (VISA_Handle)h; _VIDDEC2BACK_Msg *msg; Int numBufs; Assert_isTrue(pmsg != NULL, (Assert_Id)NULL); /* * Validate arguments. Do we want to do this _every_ time, or just in * checked builds? */ if ((context == NULL) || (outArgs == NULL) || (outArgs->size < sizeof(IVIDDEC2_OutArgs))) { /* invalid args, could even assert here, it's a spec violation. */ return (IVIDDEC2_EFAIL); } if (/* size of "stuff to marshall" > message size */ (sizeof(VISA_MsgHeader) + sizeof(XDM_Context) + outArgs->size) > sizeof(_VIDDEC2BACK_Msg)) { /* Can't handle these large extended args. */ Log_print0(Diags_USER6, "[+6] process> invalid arguments - outArgs.size field is too" " large"); return (IVIDDEC2_EUNSUPPORTED); } /* get a message appropriate for this algorithm */ if ((msg = (_VIDDEC2BACK_Msg *)VISA_allocMsg(visa)) == NULL) { Log_print0(Diags_USER6, "[+6] process> VISA_allocMsg failed"); return (IVIDDEC2_EFAIL); } /* zero out msg->cmd (not msg->visa!) */ memset(&(msg->cmd), 0, sizeof(msg->cmd)); /* * Marshall the command: copy the client-passed arguments into flattened * message data structures, converting every pointer address to alg. * data buffer into physical address. */ /* First specify the processing command that the skeleton should do */ msg->visa.cmd = _VIDDEC2BACK_CPROCESS; /* address translation of XDM_Context buffers */ if (context->algContext.buf != NULL) { msg->cmd.process.context.algContext.bufSize = context->algContext.bufSize; msg->cmd.process.context.algContext.buf = (XDAS_Int8 *) Memory_getBufferPhysicalAddress(context->algContext.buf, context->algContext.bufSize, NULL); if (msg->cmd.process.context.algContext.buf == NULL) { retVal = IVIDDEC2_EFAIL; goto exit; } } /* context->num*Bufs are plain integers, just copy them */ msg->cmd.process.context.numInBufs = context->numInBufs; msg->cmd.process.context.numOutBufs = context->numOutBufs; msg->cmd.process.context.numInOutBufs = context->numInOutBufs; /* address translate inBufs */ numBufs = copySparseSingleBufDescArrayWithV2P(msg->cmd.process.context.inBufs, context->inBufs, context->numInBufs, XDM_MAX_CONTEXT_BUFFERS); if (numBufs == -1) { retVal = IVIDDEC2_EFAIL; goto exit; } if (VISA_isChecked()) { /* check that we found context->numInBufs in context->inBufs */ Assert_isTrue(context->numInBufs == numBufs, (Assert_Id)NULL); } /* Repeat the procedure for outBufs and intermediateBufs. */ numBufs = copySparseSingleBufDescArrayWithV2P(msg->cmd.process.context.outBufs, context->outBufs, context->numOutBufs, XDM_MAX_CONTEXT_BUFFERS); if (numBufs == -1) { retVal = IVIDDEC2_EFAIL; goto exit; } if (VISA_isChecked()) { /* check that we found context->numOutBufs in context->outBufs */ Assert_isTrue(context->numOutBufs == numBufs, (Assert_Id)NULL); } numBufs = copySingleBufDescArrayWithV2P(msg->cmd.process.context.intermediateBufs, context->intermediateBufs, XDM_MAX_CONTEXT_BUFFERS); if (numBufs == -1) { retVal = IVIDDEC2_EFAIL; goto exit; } /* VIDDEC2BACK doesn't support any in/out buffers */ if (VISA_isChecked()) { Assert_isTrue(context->numInOutBufs == 0, (Assert_Id)NULL); } /* outArgs has no 'inputs', so only .size needs marshalled */ msg->cmd.process.outArgs.size = outArgs->size; *pmsg = msg; return (retVal); exit: VISA_freeMsg(visa, (VISA_Msg)msg); return retVal; }
/* * ======== VIDDEC2FRONT_process ======== * This method must be the same for both local and remote invocation; * each call site in the client might be calling different implementations * (one that marshalls & sends and one that simply calls). This API * abstracts *all* video decoders (both high and low complexity * decoders are envoked using this method). */ XDAS_Int32 VIDDEC2FRONT_process(VIDDEC2FRONT_Handle handle, VIDDEC2_InArgs *inArgs, XDM_Context *context, VIDDEC2FRONT_OutArgs *outArgs) { XDAS_Int32 retVal = VIDDEC2_EFAIL; VIDDEC2_InArgs refInArgs; /* * Note, we do this because someday we may allow dynamically changing * the global 'VISA_isChecked()' value on the fly. If we allow that, * we need to ensure the value stays consistent in the context of this call. */ Bool checked = VISA_isChecked(); GT_4trace(CURTRACE, GT_ENTER, "VIDDEC2FRONT_process> " "Enter (handle=0x%x, inArgs=0x%x, context=0x%x, outArgs=0x%x)\n", handle, inArgs, context, outArgs); if (handle) { IVIDDEC2FRONT_Fxns *fxns = (IVIDDEC2FRONT_Fxns *)VISA_getAlgFxns((VISA_Handle)handle); IVIDDEC2FRONT_Handle alg = VISA_getAlgHandle((VISA_Handle)handle); if (fxns && (alg != NULL)) { Log_printf(ti_sdo_ce_dvtLog, "%s", (Arg)"VIDDEC2FRONT:process", (Arg)handle, (Arg)0); if (checked) { /* validate inArgs with ranges. */ if (inArgs->inputID == 0) { GT_2trace(CURTRACE, GT_7CLASS, "ERROR> app provided codec (0x%x) with out of range" " inArgs->inputID field (0x%x)\n", alg, inArgs->inputID); } /* * Validate inBufs and outBufs. */ // XdmUtils_validateSparseBufDesc1(inBufs, "inBufs"); // XdmUtils_validateSparseBufDesc(outBufs, "outBufs"); /* * Make a reference copy of inArgs so we can check that * the codec didn't modify them during process(). */ refInArgs = *inArgs; /* inArgs->inputID == 0 is an application error */ if (inArgs->inputID == 0) { GT_1trace(CURTRACE, GT_7CLASS, "ERROR> codec (0x%x) received invalid " "inArgs->inputID == 0!\n", handle); } } VISA_enter((VISA_Handle)handle); retVal = fxns->process(alg, inArgs, context, outArgs); VISA_exit((VISA_Handle)handle); if (checked) { /* ensure the codec didn't modify the read-only inArgs */ if (memcmp(&refInArgs, inArgs, sizeof(*inArgs)) != 0) { GT_1trace(CURTRACE, GT_7CLASS, "ERROR> codec (0x%x) modified read-only inArgs " "struct!\n", handle); } } } } GT_2trace(CURTRACE, GT_ENTER, "VIDDEC2FRONT_process> " "Exit (handle=0x%x, retVal=0x%x)\n", handle, retVal); return (retVal); }
/* * ======== control ======== * This is the stub-implementation for the control method */ static XDAS_Int32 control(ISPHDEC_Handle h, ISPHDEC_Cmd id, ISPHDEC_DynamicParams *params, ISPHDEC_Status *status) { XDAS_Int32 retVal; VISA_Handle visa = (VISA_Handle)h; _SPHDEC_Msg *msg; ISPHDEC_Status *pMsgStatus; Int payloadSize; /* * Validate arguments. Do we want to do this _every_ time, or just in * checked builds? */ if ((params == NULL) || (params->size < sizeof(ISPHDEC_DynamicParams)) || (status == NULL) || (status->size < sizeof(ISPHDEC_Status))) { /* invalid args, could even assert here, it's a spec violation. */ return (SPHDEC_EFAIL); } /* make sure it'll all fit! */ payloadSize = sizeof(VISA_MsgHeader) + sizeof(id) + params->size + status->size; if (payloadSize > VISA_getMaxMsgSize(visa)) { /* Can't handle these large extended args. */ GT_2trace(CURTRACE, GT_6CLASS, "process> invalid arguments - too big (0x%x > 0x%x). " "Validate .size fields\n", payloadSize, VISA_getMaxMsgSize(visa)); return (SPHDEC_EFAIL); } /* get a message appropriate for this algorithm */ if ((msg = (_SPHDEC_Msg *)VISA_allocMsg(visa)) == NULL) { return (ISPHDEC_ERUNTIME); } /* marshall the command */ msg->visa.cmd = _SPHDEC_CCONTROL; msg->cmd.control.id = id; /* params has no pointers so simply memcpy "size" bytes into the msg */ memcpy(&(msg->cmd.control.params), params, params->size); /* unmarshall status based on the "size" of params */ pMsgStatus = (ISPHDEC_Status *)((UInt)(&(msg->cmd.control.params)) + params->size); /* set the size field - the rest is filled in by the codec */ /* TODO:H probably want to zero out the rest of the status struct */ pMsgStatus->size = status->size; /* send the message to the skeleton and wait for completion */ retVal = VISA_call(visa, (VISA_Msg *)&msg); /* ensure we get CCONTROL msg (ensure async CPROCESS pipeline drained) */ GT_assert(CURTRACE, msg->visa.cmd == _SPHDEC_CCONTROL); /* unmarshall status */ pMsgStatus = (ISPHDEC_Status *)((UInt)(&(msg->cmd.control.params)) + params->size); if (VISA_isChecked()) { /* ensure codec didn't modify status->size */ GT_assert(CURTRACE, pMsgStatus->size == status->size); } memcpy(status, pMsgStatus, status->size); VISA_freeMsg(visa, (VISA_Msg)msg); return (retVal); }
/* * ======== unmarshallMsg ======== */ static XDAS_Int32 unmarshallMsg(IVIDDEC2_Handle h, XDM1_BufDesc *inBufs, XDM_BufDesc *outBufs, IVIDDEC2_InArgs *inArgs, IVIDDEC2_OutArgs *outArgs, _VIDDEC2_Msg *msg, XDAS_Int32 retVal) { VISA_Handle visa = (VISA_Handle)h; IVIDDEC2_OutArgs *pMsgOutArgs; Int i, j; Int numBufs; /* * Do a wholesale replace of skeleton returned structure. * Pointer conversion of fields in outArgs is done below (only * in the case of a successful return value). */ pMsgOutArgs = (IVIDDEC2_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + inArgs->size); if (VISA_isChecked()) { /* ensure the codec didn't change outArgs->size */ Assert_isTrue(pMsgOutArgs->size == outArgs->size, (Assert_Id)NULL); } memcpy(outArgs, pMsgOutArgs, outArgs->size); /* if VISA_call was successful, unmarshall the necessary buffers. */ if (retVal == IVIDDEC2_EOK) { /* unmarshall the output data: outBufs and mbDataBuf. */ if (VISA_isChecked()) { /* ensure the codec didn't send back "too many" buffers */ Assert_isTrue(msg->cmd.process.numOutBufs < XDM_MAX_IO_BUFFERS, (Assert_Id)NULL); } /* The outBufs may have changed, so don't rely on what was passed in */ outBufs->numBufs = msg->cmd.process.numOutBufs; for (i = 0, numBufs = 0; ((numBufs < outBufs->numBufs) && (i < XDM_MAX_IO_BUFFERS)); i++) { if (msg->cmd.process.outBufs[i] != NULL) { /* valid member of sparse array, convert it */ outBufs->bufSizes[i] = msg->cmd.process.outBufSizes[i]; outBufs->bufs[i] = (XDAS_Int8 *) Memory_getBufferVirtualAddress( (UInt32)msg->cmd.process.outBufs[i], outBufs->bufSizes[i]); if (outBufs->bufs[i] == NULL) { /* TODO:M - should add at least a trace statement when trace * is supported. Another good idea is to return something * more clear than EFAIL. */ retVal = IVIDDEC2_EFAIL; goto exit; } /* found, and handled, another buffer. */ numBufs++; } else { /* empty member of sparse array, no conversion needed */ outBufs->bufSizes[i] = 0; outBufs->bufs[i] = NULL; } } /* convert mbDataBuf */ if (outArgs->mbDataBuf.buf != NULL) { Memory_getBufferVirtualAddress((UInt32)outArgs->mbDataBuf.buf, outArgs->mbDataBuf.bufSize); /* Clear .accessMask; the local processor didn't access this buf */ outArgs->mbDataBuf.accessMask = 0; } } /* * Note that buffers can also be returned if IVIDDEC_EFAIL is returned * with a non-fatal .extendedError in displayBufs[] and decodedBufs. */ /* address translate the decoded buffers if non-fatal error */ if ((retVal == IVIDDEC2_EOK) || (!(XDM_ISFATALERROR(outArgs->decodedBufs.extendedError)))) { for (i = 0; i < IVIDEO_MAX_YUV_BUFFERS; i++) { if (outArgs->decodedBufs.bufDesc[i].buf != NULL) { outArgs->decodedBufs.bufDesc[i].buf = Memory_getBufferVirtualAddress( (UInt32)outArgs->decodedBufs.bufDesc[i].buf, outArgs->decodedBufs.bufDesc[i].bufSize); /* Clear .accessMask; the local proc didn't access this buf */ outArgs->decodedBufs.bufDesc[i].accessMask = 0; } } } /* Buffers in outArgs.displayBufs are physical, so convert them if needed */ for (i = 0; i < IVIDDEC2_MAX_IO_BUFFERS; i++) { if (outArgs->outputID[i] != 0) { if ((retVal == IVIDDEC2_EOK) || (!(XDM_ISFATALERROR(outArgs-> displayBufs[i].extendedError)))) { for (j = 0; j < IVIDEO_MAX_YUV_BUFFERS; j++) { if (outArgs->displayBufs[i].bufDesc[j].buf != NULL) { outArgs->displayBufs[i].bufDesc[j].buf = Memory_getBufferVirtualAddress( (UInt32)outArgs->displayBufs[i].bufDesc[j].buf, outArgs->displayBufs[i].bufDesc[j].bufSize); /* * Clear .accessMask; the local processor didn't * access this buf. */ outArgs->displayBufs[i].bufDesc[j].accessMask = 0; } } } } } /* Note that we did *nothing* with inBufs nor inArgs. This should be ok. */ exit: VISA_freeMsg(visa, (VISA_Msg)msg); return (retVal); }
/* * ======== control ======== * This is the stub-implementation for the control method */ static XDAS_Int32 control(IAUDDEC_Handle h, IAUDDEC_Cmd id, IAUDDEC_DynamicParams *params, IAUDDEC_Status *status) { XDAS_Int32 retVal; VISA_Handle visa = (VISA_Handle)h; _AUDDEC_Msg *msg; IAUDDEC_Status *pMsgStatus; Int payloadSize; /* * Validate arguments. Do we want to do this _every_ time, or just in * checked builds? */ if ((params == NULL) || (params->size < sizeof(IAUDDEC_DynamicParams)) || (status == NULL) || (status->size < sizeof(IAUDDEC_Status))) { /* invalid args, could even assert here, it's a spec violation. */ return (IAUDDEC_EFAIL); } /* * Initialize extendedError to zero so we don't return something * uninitialized in extendedError. */ status->extendedError = 0; /* make sure it'll all fit! */ payloadSize = sizeof(VISA_MsgHeader) + sizeof(id) + params->size + status->size; if (payloadSize > VISA_getMaxMsgSize(visa)) { /* Can't handle these large extended args. */ Log_print2(Diags_USER6, "[+6] process> invalid arguments - too big (0x%x > 0x%x). " "Validate .size fields", payloadSize, VISA_getMaxMsgSize(visa)); return (IAUDDEC_EFAIL); } /* get a message appropriate for this algorithm */ if ((msg = (_AUDDEC_Msg *)VISA_allocMsg(visa)) == NULL) { return (IAUDDEC_ERUNTIME); } /* marshall the command */ msg->visa.cmd = _AUDDEC_CCONTROL; msg->cmd.control.id = id; /* params has no pointers so simply memcpy "size" bytes into the msg */ memcpy(&(msg->cmd.control.params), params, params->size); /* unmarshall status based on the "size" of params */ pMsgStatus = (IAUDDEC_Status *)((UInt)(&(msg->cmd.control.params)) + params->size); /* * Initialize the .size and .data fields - the rest are filled in by * the codec. */ pMsgStatus->size = status->size; /* send the message to the skeleton and wait for completion */ retVal = VISA_call(visa, (VISA_Msg *)&msg); /* ensure we get CCONTROL msg (ensure async CPROCESS pipeline drained) */ Assert_isTrue(msg->visa.cmd == _AUDDEC_CCONTROL, (Assert_Id)NULL); /* unmarshall status */ pMsgStatus = (IAUDDEC_Status *)((UInt)(&(msg->cmd.control.params)) + params->size); if (VISA_isChecked()) { /* ensure codec didn't modify status->size */ Assert_isTrue(pMsgStatus->size == status->size, (Assert_Id)NULL); } memcpy(status, pMsgStatus, status->size); VISA_freeMsg(visa, (VISA_Msg)msg); return (retVal); }
/* * ======== control ======== * This is the stub-implementation for the control method */ static XDAS_Int32 control(IUNIVERSAL_Handle h, IUNIVERSAL_Cmd id, IUNIVERSAL_DynamicParams *dynParams, IUNIVERSAL_Status *status) { XDAS_Int32 retVal; VISA_Handle visa = (VISA_Handle)h; _UNIVERSAL_Msg *msg; IUNIVERSAL_Status *pMsgStatus; XDAS_Int8 *virtAddr[XDM_MAX_IO_BUFFERS]; Int i; Int numBufs; Int payloadSize; /* * Validate arguments. Do we want to do this _every_ time, or just in * checked builds? */ if ((dynParams == NULL) || (dynParams->size < sizeof(IUNIVERSAL_DynamicParams)) || (status == NULL) || (status->size < sizeof(IUNIVERSAL_Status))) { /* invalid args, could even assert here, it's a spec violation. */ return (IUNIVERSAL_EFAIL); } /* * Initialize extendedError to zero so we don't return something * uninitialized in extendedError. */ status->extendedError = 0; /* make sure it'll all fit! */ payloadSize = sizeof(VISA_MsgHeader) + sizeof(id) + dynParams->size + status->size; if (payloadSize > VISA_getMaxMsgSize(visa)) { /* Can't handle these large extended args. */ Log_print2(Diags_USER6, "[+6] control> invalid arguments - too big (0x%x > 0x%x). " "Validate .size fields", payloadSize, VISA_getMaxMsgSize(visa)); return (IUNIVERSAL_EUNSUPPORTED); } /* get a message appropriate for this algorithm */ if ((msg = (_UNIVERSAL_Msg *)VISA_allocMsg(visa)) == NULL) { return (IUNIVERSAL_EFAIL); } /* marshall the command */ msg->visa.cmd = _UNIVERSAL_CCONTROL; msg->cmd.control.id = id; /* dynParams has no pointers so simply memcpy "size" bytes into the msg */ memcpy(&(msg->cmd.control.dynParams), dynParams, dynParams->size); /* point at status based on the "size" of dynParams */ pMsgStatus = (IUNIVERSAL_Status *)((UInt)(&(msg->cmd.control.dynParams)) + dynParams->size); /* * Initialize the .size and .data fields - the rest are filled in by * the codec. */ pMsgStatus->size = status->size; /* 1) pMsgStatus->data.numBufs is a plain integer, we just copy it */ pMsgStatus->data.numBufs = status->data.numBufs; /* * status->data.descs[] is a sparse array of buffer descriptors. Convert * them if non-NULL. */ for (i = 0, numBufs = 0; ((numBufs < status->data.numBufs) && (i < XDM_MAX_IO_BUFFERS)); i++) { if (status->data.descs[i].buf != NULL) { /* valid member of sparse array, convert it */ pMsgStatus->data.descs[i].bufSize = status->data.descs[i].bufSize; /* save it for later */ virtAddr[i] = status->data.descs[i].buf; pMsgStatus->data.descs[i].buf = (XDAS_Int8 *) Memory_getBufferPhysicalAddress(status->data.descs[i].buf, status->data.descs[i].bufSize, NULL); if (pMsgStatus->data.descs[i].buf == NULL) { retVal = IUNIVERSAL_EFAIL; goto exit; } /* found, and handled, another buffer. */ numBufs++; } else { /* empty member of sparse array, no conversion needed. */ pMsgStatus->data.descs[i].bufSize = 0; pMsgStatus->data.descs[i].buf = NULL; virtAddr[i] = NULL; } } if (VISA_isChecked()) { /* check that we found inBufs->numBufs pointers in inBufs->bufs[] */ Assert_isTrue(status->data.numBufs == numBufs, (Assert_Id)NULL); } /* send the message to the skeleton and wait for completion */ retVal = VISA_call(visa, (VISA_Msg *)&msg); /* ensure we get CCONTROL msg (ensure async CPROCESS pipeline drained) */ Assert_isTrue(msg->visa.cmd == _UNIVERSAL_CCONTROL, (Assert_Id)NULL); /* unmarshall status */ pMsgStatus = (IUNIVERSAL_Status *)((UInt)(&(msg->cmd.control.dynParams)) + dynParams->size); if (VISA_isChecked()) { /* ensure codec didn't modify status->size */ Assert_isTrue(pMsgStatus->size == status->size, (Assert_Id)NULL); /* * TODO:L Should we also check that pMsgStatus->data.buf is the same * after the call as before? */ } memcpy(status, pMsgStatus, status->size); /* * And finally, restore status->data.descs[].buf's to their original values. * * While potentially more confusing, this is just as correct as * (and faster than!) calling Memory_getVirtualBuffer(). */ for (i = 0, numBufs = 0; (numBufs < status->data.numBufs) && (i < XDM_MAX_IO_BUFFERS); i++) { status->data.descs[i].buf = virtAddr[i]; /* Clear .accessMask; the local processor didn't access the buffer */ status->data.descs[i].accessMask = 0; if (virtAddr[i] != NULL) { numBufs++; } } exit: VISA_freeMsg(visa, (VISA_Msg)msg); return (retVal); }