/*
 * Creates a new HTTP Protocol event and enqueues it in HTTPProtocolEventQ
 *
 * @param nserverCode
 * @param pReasonString
 * @param pEntityBody
 *
 * @return bool
 */
bool HTTPSourceMMIExtensionEventHandler::HTTPProtocolEventManager::SetHTTPProtocolEvent
(
  HTTPSourceMMIHelper *pHTTPSourceMMIHelper,
  void *protocolInfo,
  void *pClientData
)
{
  bool rsltCode = false;
  HTTPStackNotificationCbData *protocolData = (HTTPStackNotificationCbData*)protocolInfo;

  if (GetNotify())
  {
    HTTPProtocolEvent protocolEvent = { (uint32)protocolData->m_serverCode,
                                          protocolData->m_serverMessage,
                                          protocolData->m_entityBody };

    rsltCode = m_eventQManager.Enqueue(protocolEvent);
    if (rsltCode)
    {
       rsltCode = HTTPSourceMMIExtensionEventHandler::NotifyEvent(pHTTPSourceMMIHelper,
                                                                 OMX_ALL,
                                                          QOMX_HTTP_IndexConfigStreamingProtocolEvent,
                                                                 pClientData);
      QTV_MSG_PRIO1( QTVDIAG_STREAMING, QTVDIAG_PRIO_MEDIUM,
                     "HTTP Protocol Event Queued: serverCode:%d", protocolData->m_serverCode );
    }
  }
  else
  {
    QTV_MSG_PRIO1( QTVDIAG_STREAMING, QTVDIAG_PRIO_LOW,
                  "HTTPProtocolEventManager: Dropping the Protocol Event with Code:%d",
       protocolData->m_serverCode);
  }
  return rsltCode;
}
/** @brief PLAYLIST_READY state handler.
*
* @param[in] pDownloadHelper - Reference to
*       PlaylistDownloadHelper
* @return
* HTTPDL_WAITING - Data successfully written or no data available to write
*                  and download incomplete
* HTTPDL_SUCCESS - Download complete
* HTTPDL_ERROR_ABORT - Otherwise
*/
HTTPDownloadStatus PlaylistDownloadHelper::PlaylistReadyStateHandler::Execute
(
 PlaylistDownloadHelper* pDownloadHelper
 )
{
  QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW,
    "PlaylistDownloadHelper::PlaylistReadyStateHandler::Execute()" );
  HTTPDownloadStatus status = HTTPCommon::HTTPDL_ERROR_ABORT;
  PlaylistDownloadHelper* pSelf = pDownloadHelper;

  //Validity check
  if (pSelf)
  {
    char* pRepresentationBuf = pSelf->m_RepresentationBuffer;
    int numBytesToRead = STD_MAX(0, pSelf->m_nRepresentationLen - pSelf->m_nRepresentationBytesRead);
    HTTPStackInterface& HTTPStack = *(pSelf->m_pHTTPStack);
    QTV_MSG_PRIO2( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_MEDIUM,
      "numBytesToRead %d, (numBytesReceived %d)",
      numBytesToRead, pSelf->m_nRepresentationBytesRead );

    if (pSelf->m_RepresentationBuffer && numBytesToRead > 0)
    {
      status = HTTPCommon::HTTPDL_ERROR_ABORT;
      //Get a data chunk from HTTP stack
      size_t numBytesRead = 0;
      HTTPReturnCode result =
        HTTPStack.GetData(pSelf->m_nRequestID,
        pRepresentationBuf+pSelf->m_nRepresentationBytesRead,
        numBytesToRead,
        &numBytesRead);
      if (result != HTTP_FAILURE && result != HTTP_BADPARAM)
      {
        //Update total number of bytes dowloaded/written so far
        pSelf->m_nRepresentationBytesRead += (int)numBytesRead;
        status = HTTPCommon::HTTPDL_WAITING;
        if(result == HTTP_NOMOREDATA ||
          pSelf->m_nRepresentationBytesRead >= (pSelf->m_nRepresentationLen -1))
        {
          pSelf->m_nRepresentationLen = pSelf->m_nRepresentationBytesRead;
          status = HTTPCommon::HTTPDL_SUCCESS;
        }
        QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_HIGH,
          "Total numBytesReceived %d",  pSelf->m_nRepresentationBytesRead );
      }// result check
      else
      {
        //Data read failure
        QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR,
          "Error: Data read failure %d from HTTP stack", result );
      }
    }// if (HTTPSUCCEEDED(status))
  }// if (pSelf && pSelf->GetState() == DATA_READY)
  return status;
}
Vdec_ReturnType vdec_commit_memory(struct VDecoder* dec)
{
  unsigned frame_size = 0;
  unsigned output_sz = 0;
  unsigned input_sz = VDEC_INPUT_SIZE;
  unsigned off = 0;
  int n;
  int r;
  
  frame_size = dec->width * dec->height;
  output_sz = frame_size * 3/2;
  if (dec->ctxt->inputReq.bufferSize > VDEC_INPUT_SIZE)
  {
    input_sz = dec->ctxt->inputReq.bufferSize;
  }

  dec->arena_size = VDEC_NFRAMES * VDEC_INPUT_SIZE + dec->ctxt->outputBuffer.numBuffers * output_sz;
  if (pmem_alloc(&dec->arena, dec->arena_size)) {
    QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: failed to allocate pmem arena (%d bytes)\n",
                  dec->arena_size);
    return VDEC_EFAILED;
  }
	QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"vdec: allocated %d bytes of pmem\n", dec->arena_size);
  off = 0;
  for (n = 0; n < VDEC_NFRAMES; n++) {
    struct vdec_frame *fr = dec->input + n;
    fr->pmem_id = dec->arena.fd;
    fr->pmem_offset = off;
    fr->phys = dec->arena.phys + off;
    fr->base = ((unsigned char*) dec->arena.data) + off;
    off += input_sz;
    QTV_MSG_PRIO5(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"      input[%d]  base=%p phys=0x%08x off=0x%08x id=%d\n",
                  n, fr->base, fr->phys, fr->pmem_offset, fr->pmem_id);
  }
  for (n = 0; n < dec->ctxt->outputBuffer.numBuffers; n++) {
    struct vdec_frame *fr = dec->output + n;
    fr->pmem_id = dec->arena.fd;
    fr->pmem_offset = off;
    fr->phys = dec->arena.phys + off;
    fr->base = ((unsigned char*) dec->arena.data) + off;
    off += output_sz;
    memset(fr->base,0,frame_size);
    memset(&(((unsigned char*)fr->base)[frame_size]),128,frame_size>>1);
    QTV_MSG_PRIO5(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"      output[%d] base=%p phys=0x%08x off=0x%08x id=%d\n",
                  n, fr->base, fr->phys, fr->pmem_offset, fr->pmem_id);
  }

  dec->ctxt->inputBuffer.base        =(unsigned char*) (dec->input[0].base);
  dec->ctxt->inputBuffer.bufferSize  = input_sz;
  dec->ctxt->inputBuffer.numBuffers  = VDEC_NFRAMES;
  dec->ctxt->outputBuffer.base       = (unsigned char*) &(dec->output[0]); 
  dec->ctxt->outputBuffer.bufferSize = output_sz;
  return VDEC_SUCCESS;
}
示例#4
0
void *adsp_thread(void *_mod)
{
   struct adsp_module *mod = _mod;
   int n;
   struct vdec_msg vdecMsg;
   struct Vdec_FrameDetailsType vdec_frame;

   QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
           "adsp_thread: event thread start\n");
   while (!mod->dead) {
      if (!mod->init_done)
         continue;

      QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_MED,
               "adsp_thread: Calling IOCTL_GETMSG fd %d\n",
               mod->fd);
      if (ioctl(mod->fd, VDEC_IOCTL_GETMSG, &vdecMsg) < 0) {
         QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_HIGH,
                 "adsp_thread:VDEC_IOCTL_GETMSG failed\n");
         continue;
      }
      QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_MED,
               "adsp_thread: %d\n", vdecMsg.id);
      if (vdecMsg.id == VDEC_MSG_REUSEINPUTBUFFER) {
         QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_MED,
                  "adsp_thread: Reuse input buffer %d\n",
                  vdecMsg.buf_id);
         mod->buffer_done(mod->ctxt, (void *)vdecMsg.buf_id);
      } else if (vdecMsg.id == VDEC_MSG_FRAMEDONE) {
         QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_MED,
                  "adsp_thread: Frame done %x\n",
                  vdecMsg.vfr_info);
         convertFrameInfoToFrameDetails(&vdec_frame,
                         &vdecMsg.vfr_info);
#if PROFILE_DECODER
         if (vdec_frame.status != VDEC_FLUSH_DONE) {
            QPERF_END_AND_START(dsp_decode);
         }
#endif
         mod->frame_done(mod->ctxt, &vdec_frame,
               vdecMsg.vfr_info.data2,
               vdecMsg.vfr_info.offset);
      } else {
         QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_MED,
                 "adsp_thread:VDEC_IOCTL_GETMSG Unknown Msg ID\n");
      }
   }
   QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
           "h264: event thread stop\n");
   return 0;
}
示例#5
0
int adsp_free_buffers(struct adsp_module *mod, struct adsp_buffer_info bufinfo)
{
   struct vdec_buffer mem;
   int r;

   if (NULL == mod) {
      QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
               "adsp_set_buffers() mod NULL: 0x%x\n", mod);
      return -1;
   }

   mem.pmem_id = bufinfo.buf.pmem_id;
   mem.buf.buf_type = bufinfo.buf_type;
   mem.buf.num_buf = bufinfo.numbuf;
   mem.buf.islast = bufinfo.is_last;

   mem.buf.region.src_id = 0x0106e429;
   mem.buf.region.offset = bufinfo.buf.offset;
   mem.buf.region.size = bufinfo.buf.size;

   if (ioctl(mod->fd, VDEC_IOCTL_FREEBUFFERS, &mem) < 0) {
      QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
              "VDEC_IOCTL_SETBUFFERS failed\n");
      return -1;
   }

   return 0;

}
int HTTPSourceMMIHelper::ProcessFlushDataStatus
(
 int32 /*portIdx*/,
 void *pBuffHdrParam
 )
{
  int ret = -1;
  MMI_BufferCmdType FillBuffCmdResp;
  OMX_BUFFERHEADERTYPE *pBuffHdr = (OMX_BUFFERHEADERTYPE *) pBuffHdrParam;

  QTV_NULL_PTR_CHECK(m_pHTTPSourceMMI, ret);
  QTV_NULL_PTR_CHECK(pBuffHdr, ret);

  pBuffHdr->nFilledLen = 0;
  pBuffHdr->nOffset = 0;
  //notify fillbufferdone
  FillBuffCmdResp.nPortIndex = pBuffHdr->nOutputPortIndex;
  FillBuffCmdResp.pBufferHdr = pBuffHdr;


  QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_MEDIUM,
    "FlushBuffer - portIdx:%u",
    (uint32)FillBuffCmdResp.nPortIndex);

  NotifyMmi(MMI_RESP_FILL_THIS_BUFFER,
    MMI_S_COMPLETE, sizeof(FillBuffCmdResp),
    &FillBuffCmdResp, m_pHTTPSourceMMI->m_pClientData);
  return 0;
}
/** @brief Notification from HTTP stack (e.g. redirect notification).
*
* @param[in] HTTPStackStatus - HTTP stack notification
* @return
*/
bool HTTPSourceMMIHelper::Notify
(
 HTTPStackNotifyCode HTTPStackStatus,
 void *pCbData
 )
{
  bool ret = false;

  QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_HIGH,
    "HTTPSourceMMIHelper::Notify - status %d", HTTPStackStatus );

  HTTPStackNotificationCbData *protocolData = (HTTPStackNotificationCbData*)pCbData;

  if (protocolData->m_protocolHeaders)
  {
    if (m_pHTTPSourceMMI &&
    m_pHTTPSourceMMI->m_pHTTPSourceMMIExtensionHandler.SetHTTPProtocolHeadersEvent(pCbData) == MMI_S_COMPLETE)
    {
      ret = true;
    }
  }
  if (m_pHTTPSourceMMI &&
    m_pHTTPSourceMMI->m_pHTTPSourceMMIExtensionHandler.SetHTTPProtocolEvent(pCbData) == MMI_S_COMPLETE)
  {
    ret = true;
  }

  return ret;
}
void
HTTPStackHelper::SetHTTPStackPtr(HTTPAuthorizationInterface *pHTTPStack)
{
  QTV_MSG_PRIO1(QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW,
                "SetHTTPStackPtr 0x%p to be passed in callback", (void*)pHTTPStack);
  m_pHTTPStack = pHTTPStack;
}
/* ==================================================================
FUNCTION ORDERED_LIST_INIT
DESCRIPTION
   Initializes an ordered list.
===================================================================== */
ordered_StreamList_type       * ordered_StreamList_init(
   ordered_StreamList_type       *StreamList_ptr,
   ordered_StreamList_config_type sort_order,
   ordered_StreamList_config_type compare_type,
   MM_HANDLE critSect /* Ptr to critical section. */
)
{
  StreamList_ptr->link.back_ptr  = NULL;
  StreamList_ptr->link.front_ptr = NULL;
  StreamList_ptr->link.size      = 0;
  StreamList_ptr->link.type      = sort_order | compare_type;

  if (StreamList_ptr->lock)
  {
    MM_CriticalSection_Release(StreamList_ptr->lock);
  }

  if (critSect)
  {
    // user supplied critical section cache it
    StreamList_ptr->lock = critSect;
  }
  else if(MM_CriticalSection_Create(&StreamList_ptr->lock) != 0)
  {
    QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_FATAL,
           "ordered_StreamList_init: Unable to create a critical section: %p",
           (void *)StreamList_ptr->lock);
  }
  return StreamList_ptr ;
} /* END */
/**
 * @brief
 *  Selects an audio track from the one of the param
 *  trackIndices.
 *  In order of preference:
 *    AAC
 *    Any audio codec other than AAC, EVRC, GSM, QCELP
 *    EVRC or GSM or QCELP High
 *    Bit Rate codec.
 *    Rejected track index with AAC codec.
 *
 * @param trackList
 * @param aacIdx
 * @param someAudioCodecTrackIdx
 * @param evrcOrGsmIdx
 * @param highRateCodecIndex
 * @param rejectedAACTrackIndex
 *
 * @return int    The selected track index. -1 if no audio track
 *                was selected.
 */
int DefaultTrackSelectionPolicy::ChoosePreferredAudioTrack(
  ITrackList& trackList,
  int aacIdx,
  int someAudioCodecTrackIdx,
  int evrcOrGsmIdx,
  int highRateCodecIndex,
  int rejectedAACTrackIndex)
{
  int selectedAudioTrack = -1;

  if ((selectedAudioTrack < 0) && (aacIdx >= 0))
  {
    if (trackList.SelectTrack(aacIdx))
    {
      selectedAudioTrack = aacIdx;
    }
  }

  if ((selectedAudioTrack < 0) && (someAudioCodecTrackIdx >= 0))
  {
    if (trackList.SelectTrack(someAudioCodecTrackIdx))
    {
      selectedAudioTrack = someAudioCodecTrackIdx;
    }
  }

  if ((selectedAudioTrack < 0) && (evrcOrGsmIdx >= 0))
  {
    if (trackList.SelectTrack(evrcOrGsmIdx))
    {
      selectedAudioTrack = evrcOrGsmIdx;
    }
  }

  if ((selectedAudioTrack < 0) && (highRateCodecIndex >= 0))
  {
    if (trackList.SelectTrack(highRateCodecIndex))
    {
      selectedAudioTrack = highRateCodecIndex;
      QTV_MSG_PRIO1(QTVDIAG_STREAMING, QTVDIAG_PRIO_MED, "Bit Rate selected = %d",
        trackList.GetBitrateBPS(highRateCodecIndex));
    }
  }

  // This is a work around for a server problem. In case of AAC PV server sends us wrong
  // config information in the SDP which results in we rejecting the track. If no other
  // track information is present in the SDP we will go ahead and select that track because
  // the PC version of PV player plays that track
  if ((selectedAudioTrack < 0) && (rejectedAACTrackIndex >= 0))
  {
    if (trackList.SelectTrack(rejectedAACTrackIndex))
    {
      selectedAudioTrack = rejectedAACTrackIndex;
    }
  }

  return selectedAudioTrack;
}
示例#11
0
Vdec_ReturnType vdec_release_frame(struct VDecoder *dec, struct vdec_frame *frame)
{
  VDEC_FRAME vdecFrame;
  VideoDecoder *pDec = (VideoDecoder*)(dec->core);
  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: release_frame %p\n", frame);  
  if (NULL == dec || NULL == frame)
  {
	  QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: error: encountered NULL parameter vdec: 0x%x frame: 0x%x", (unsigned int)dec, (unsigned int)frame);
      return VDEC_EFAILED;
  } 
  //vdecFrame.pBuf = (VDEC_BYTE*)frame->phys;
  vdecFrame.pBuf = (VDEC_BYTE*)frame->base;
  vdecFrame.timestamp = (unsigned long long)frame->timestamp;
  pDec->ReuseFrameBuffer(&vdecFrame);

  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: released_frame with ptr: 0x%x", (unsigned int)vdecFrame.pBuf);
  return VDEC_SUCCESS;
}
示例#12
0
int adsp_release_frame(struct adsp_module *mod, unsigned int *buf)
{
   if (NULL == mod) {
      QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
               "adsp_release_frame() mod NULL: 0x%x\n", mod);
      return -1;
   }
   return ioctl(mod->fd, VDEC_IOCTL_REUSEFRAMEBUFFER, buf);

}
示例#13
0
int adsp_flush(struct adsp_module *mod, unsigned int port)
{
   if (NULL == mod) {
      QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
               "adsp_flush() mod NULL: 0x%x\n", mod);
      return -1;
   }
   QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
           "adsp_flush() Before Flush \n");
   return ioctl(mod->fd, VDEC_IOCTL_FLUSH, &port);
}
示例#14
0
int adsp_performance_change_request(struct adsp_module *mod, unsigned int request_type)
{
   if (NULL == mod) {
      QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
               "adsp_performance_change_request() mod NULL: 0x%x\n", mod);
      return -1;
   }
   QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
           "adsp_performance_change_request()\n");
   return ioctl(mod->fd, VDEC_IOCTL_PERFORMANCE_CHANGE_REQ, &request_type);
}
/** @brief Convert the HTTP status code to MMI status code for
* Get tracks command.
*
* @param[in] HTTPStatus - HTTP streamer status code
* @param[in] pUserData - Reference to the registered MMI callback iface
*/
void HTTPSourceMMIHelper::ProcessGetTracksStatus
(
 const HTTPDownloadStatus HTTPStatus,
 void* pUserData
)
{
  OMX_U32 ret = MMI_S_EFAIL;

  if (HTTPSUCCEEDED(HTTPStatus))
  {
    if (m_pHTTPSourceMMI && m_pHTTPSourceMMI->m_pHTTPSourceMMITrackHandler)
    {
      m_pHTTPSourceMMI->m_pHTTPSourceMMITrackHandler->ProcessGetTracksStatus();
      ret = MMI_S_COMPLETE;
    }
    else
    {
      QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR,
                     "NULL objects HTTPSourceMMI %p or track handler",
                     (void *)m_pHTTPSourceMMI );
    }
  }
  else
  {
    QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR,
                   "ProcessGetTracksStatus failed with error %d", HTTPStatus );
    ret = MMI_S_EFAIL;
  }

  NotifyMmi(MMI_RESP_START, ret, 0, NULL, pUserData);

  if (m_pHTTPSourceMMI && ret == MMI_S_COMPLETE )
  {
    m_pHTTPSourceMMI->UpdatePorts();
  }
  ProcessQOENotification(QOMX_HTTP_IndexParamQOEPlay);
  return;
}
示例#16
0
static void* vdec_frame_buffer_malloc_cb_handler (const VDEC_STREAM_ID,
                                                  void *pContext,
                                                  unsigned long int size)
{
	QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: vdec_frame_buffer_malloc_cb_handler()\n");
  if(vdec_decoder_info->ctxt->outputBuffer.numBuffers <= vdec_output_frame_index)
  {
	  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: frame buffer malloc failed, index: %d\n", vdec_output_frame_index);
    return NULL;
  }
  else
  {
    //return (void*)vdec_decoder_info->output[vdec_output_frame_index++].phys;
    return (void*)vdec_decoder_info->output[vdec_output_frame_index++].base;
  }
}
HTTPReturnCode
HTTPStackHelper::SendRequestInternal(uint32 requestId)
{
  HTTPReturnCode result = HTTP_FAILURE;

  QTV_MSG_PRIO1(QTVDIAG_HTTP_STACK, QTVDIAG_PRIO_MED,
                "HTTPStackHelper::SendRequestInternal(%u)",requestId);

  result = CreateOrReuseConnectionObject();

  if (HTTP_SUCCESS == result)
  {
    QTV_MSG_PRIO(QTVDIAG_HTTP_STACK, QTVDIAG_PRIO_MED,
                 "HTTPStackHelper::SendRequest Request queued");
  }

  return result;
}
/**
 * @brief
 *  Notify QOE Event.
 *
 * @param pHTTPSourceMMIHelper
 * @param portID
 * @param eventID
 * @param pClientData
 *
 * @return status
 */
bool HTTPSourceMMIExtensionEventHandler::HTTPQOEEventManager::
      NotifyQOEEvent(HTTPSourceMMIHelper *pHTTPSourceMMIHelper,
                              const uint32 portID,
                              const uint32 eventID,
                              void *pClientData)
{
  bool status = false;
  if(m_bQOENotify)
  {
    QTV_MSG_PRIO1(QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW,
    "HTTPSourceMMIExtensionEventHandler::HTTPQOEEventManager::NotifyQOEEvent eventID = %u",eventID);
    status = NotifyEvent(
              pHTTPSourceMMIHelper,
              portID,
              eventID,
              pClientData);
  }
  return status;
}
示例#19
0
int adsp_post_input_buffer(struct adsp_module *mod, struct adsp_input_buf input,
            unsigned int eos)
{
   struct vdec_input_buf ip;
   struct vdec_queue_status stat;

   if (NULL == mod) {
      QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
               "adsp_post_input_buffer() mod NULL: 0x%x\n", mod);
      return -1;
   }
   ip.pmem_id = input.pmem_id;
   ip.buffer.avsync_state = input.avsync_state;
   ip.buffer.data = input.data;
   ip.buffer.offset = input.offset;
   ip.buffer.size = input.size;
   ip.buffer.timestamp_lo = input.timestamp_lo;
   ip.buffer.timestamp_hi = input.timestamp_hi;
   ip.buffer.flags = input.flags;
   ip.queue_status = &stat;

#if PROFILE_DECODER
   QPERF_START(dsp_decode);
#endif
   if (eos) {
      if (ioctl(mod->fd, VDEC_IOCTL_EOS, NULL) < 0) {
         QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
                 "adsp:VDEC_IOCTL_EOS failed\n");
         return -1;
      }
   } else {
      //usleep(1000000);
      if (ioctl(mod->fd, VDEC_IOCTL_QUEUE, &ip) < 0) {
         QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
                 "adsp:VDEC_IOCTL_QUEUE failed\n");
         return -1;
      }
   }

   return 0;
}
bool HTTPSourceMMIExtensionEventHandler::HTTPMMIEventQManager<T>::Enqueue
(
 const T& eventToWrite
)
{
  bool bOk = false;

  //Check if the queue is already full, if not push the new event
  //into the queue
  if (IsQFull())
  {
    QTV_MSG_PRIO( QTVDIAG_STREAMING, QTVDIAG_PRIO_MEDIUM,
                  "MMIEventQManager - MMI event queue full" );
  }
  else
  {
    (void)MM_CriticalSection_Enter(m_hEventQLock);
    if (m_nEventWriteIndex < ARR_SIZE(m_eventQ))
    {
      //Update the write index and number of queued events
      bOk = true;
      m_eventQ[m_nEventWriteIndex] = eventToWrite;
      m_nOutstandingEvents++;
      QTV_MSG_PRIO2( QTVDIAG_STREAMING, QTVDIAG_PRIO_MEDIUM,
                     "MMIEventQManager - Queued event to index %u, "
                     "%u events remain", m_nEventReadIndex, m_nOutstandingEvents );
      m_nEventWriteIndex = (m_nEventWriteIndex + 1) % (uint32)ARR_SIZE(m_eventQ);
    }
    else
    {
      QTV_MSG_PRIO1( QTVDIAG_STREAMING, QTVDIAG_PRIO_ERROR,
                     "MMIEventQManager - Invalid MMI event queue write index %u",
                     m_nEventWriteIndex );
    }
    (void)MM_CriticalSection_Leave(m_hEventQLock);
  }

  return bOk;
}
bool HTTPSourceMMIExtensionEventHandler::HTTPMMIEventQManager<T>::Dequeue
(
 T& eventToRead
)
{
  bool bOk = false;

  //Check if the queue is already empty, if not get the event from
  //the queue
  if (IsQEmpty())
  {
    QTV_MSG_PRIO( QTVDIAG_STREAMING, QTVDIAG_PRIO_MEDIUM,
                  "MMIEventQManager - MMI event queue empty" );
  }
  else
  {
    (void)MM_CriticalSection_Enter(m_hEventQLock);
    if (m_nEventReadIndex < ARR_SIZE(m_eventQ))
    {
      //Dequeue the event and update the read index and number of queued events
      bOk = true;
      eventToRead = m_eventQ[m_nEventReadIndex];
      m_nOutstandingEvents--;
      QTV_MSG_PRIO2( QTVDIAG_STREAMING, QTVDIAG_PRIO_MEDIUM,
                     "MMIEventQManager - Dequeued event from index %u, "
                     "%u events remain", m_nEventReadIndex, m_nOutstandingEvents );
      m_nEventReadIndex = (m_nEventReadIndex + 1) % (uint32)ARR_SIZE(m_eventQ);
    }
    else
    {
      QTV_MSG_PRIO1( QTVDIAG_STREAMING, QTVDIAG_PRIO_ERROR,
                     "MMIEventQManager - Invalid MMI event queue read index %u",
                     m_nEventReadIndex );
    }
    (void)MM_CriticalSection_Leave(m_hEventQLock);
  }
  return bOk;
}
示例#22
0
void adsp_close(struct adsp_module *mod)
{
#if PROFILE_DECODER
    QPERF_TERMINATE(dsp_decode);
    QPERF_RESET(dsp_decode);
#endif
#ifndef T_WINNT
   int ret;
   int thread_ret = 0;
   if (NULL == mod) {
      QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
               "adsp_close() mod NULL: 0x%x\n", mod);
      return ;
   }

   mod->dead = 1;

   if (ioctl(mod->fd, VDEC_IOCTL_CLOSE, NULL) < 0) {
      QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
              "VDEC_IOCTL_CLOSE failed\n");
      return;
   }

   QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW, "adsp_close: 0x%x",
            (unsigned)mod);

   /*Wait on the adsp event thread completion */

   ret = pthread_join(mod->thr, (void **)&thread_ret);

   if (ret != 0) {
      QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
               "*************adsp_close: Could not join on the adsp event thread err=%d!!\n",
               ret);
   }

   /*Wait on the adsp event thread completion */

   ret = close(mod->fd);
   if (ret < 0) {
      QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
              "*************adsp_close ERROR!");
   }

   QTV_MSG_PRIO2(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
            "adsp_close returned %d, fd: %d", ret, mod->fd);

#if DEBUG
   if (logFD) {
      pthread_mutex_lock(&logMTX);
      fclose(logFD);
      logFD = NULL;
      pthread_mutex_destroy(&logMTX);
   }
#endif

   //sleep(1); /* XXX need better way to stop thread XXX */
   free(mod);
   mod = NULL;
#endif //T_WINNT
}
示例#23
0
Vdec_ReturnType vdec_post_input_buffer(struct VDecoder *dec, video_input_frame_info *frame, void *cookie)
{
  QTV_MSG_PRIO3(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: post_input data=%p len=%d cookie=%p\n", frame->data, frame->len, cookie);
#ifdef LOG_INPUT_BUFFERS
  static int take_input = 1;
#endif
  int fatal_err = 0;

  /*checkBufAvail flag is needed since we do not need to checkout
   * YUV/Slice buffer incase the NAL corresponds to same frame.
   * This is required for multiple NALs in one input buffer
   */
  bool checkBufAvail = true;
  VDEC_INPUT_BUFFER input;
  VideoDecoder *pDec = (VideoDecoder*)(dec->core);
  VDEC_ERROR err  = VDEC_ERR_EVERYTHING_FINE;
  if (NULL == dec || NULL == frame || NULL == frame->data )
  {
	  QTV_MSG_PRIO3(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: error: encountered NULL parameter dec: 0x%x frame: 0x%x data: 0x%x\n", 
		   (unsigned int)dec, 
		   (unsigned int)frame,
		   (unsigned int)frame->data);
    return VDEC_EFAILED;
  }

  input.buffer[0]      = (unsigned char*)frame->data;
  input.timestamp[0]   = (long long)frame->timestamp;
  input.buffer_size[0] = (unsigned long int)frame->len;
  input.buffer_pos[0]  = 0;
  input.layers         = 1;
  input.eOSIndicator[0]= false;

  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"vdec: received ts: %lld", frame->timestamp);
  if (frame->timestamp < timestamp )
  {
	  QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"vdec: error: out of order stamp! %d < %d\n",
                  (int)(frame->timestamp&0xFFFFFFFF), timestamp);
  }
  timestamp = (int)frame->timestamp;

  QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"vdec: vdec_core_post_input. buffer_size[0]: %ld frame->flags: 0x%x\n",
                input.buffer_size[0], frame->flags);

  if (input.buffer_size[0] == 0 && frame->flags & FRAME_FLAG_EOS)
  {
	  QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: Zero-length buffer with EOS bit set\n");
          input.eOSIndicator[0] = true;

    if(pDec)
		err =  pDec->EOS( );
	else
		err = VDEC_ERR_NULL_STREAM_ID;

    if(VDEC_ERR_OUT_OF_BUFFERS == err) return VDEC_EOUTOFBUFFERS; 
    vdec_decoder_info->ctxt->buffer_done(vdec_decoder_info->ctxt, cookie);
    if (VDEC_ERR_EVERYTHING_FINE == err) return VDEC_SUCCESS;
    return VDEC_EFAILED;
  }

  QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: vdec_core_post_input\n");

#ifdef LOG_INPUT_BUFFERS
  if (take_input)
  {
    fwritex((unsigned char*)frame->data, frame->len, pInputFile);
	QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: frame %d frame->len %d\n", counter++, frame->len);
  }
#endif

  do {
    QPERF_TIME(arm_decode, err = pDec->Decode( &input, checkBufAvail ));
    if (VDEC_ERR_EVERYTHING_FINE != err)
    {
		QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: vdec_decoder error: %d\n", (int)err);
		if(VDEC_ERR_UNSUPPORTED_DIMENSIONS == err) {
			fatal_err = 1;
			break;
		}
    }
    checkBufAvail = false;
  } while( ( VDEC_ERR_EVERYTHING_FINE == err ) && ( 0 != input.buffer_size[0] ) );

#ifdef LOG_INPUT_BUFFERS
  take_input = (err==14?0:1);
#endif
  if(VDEC_ERR_OUT_OF_BUFFERS == err) return VDEC_EOUTOFBUFFERS;
  vdec_input_buffer_release_cb_handler(pDec,&input,cookie);
  if(VDEC_ERR_EVERYTHING_FINE == err) return VDEC_SUCCESS;
  if(fatal_err) {
      static struct vdec_frame frame;
      memset(&frame, 0, sizeof(frame));
      frame.flags |= FRAME_FLAG_FATAL_ERROR;
      QPERF_END(frame_data);
      vdec_decoder_info->ctxt->frame_done(vdec_decoder_info->ctxt, &frame);
  }
  return VDEC_EFAILED;
}
示例#24
0
struct VDecoder *vdec_open(struct vdec_context *ctxt)
{
  struct VDecoder *dec = NULL;
  VDEC_ERROR err = 0;
  const VDEC_CONCURRENCY_CONFIG concurrencyConfig = VDEC_CONCURRENT_NONE;
  VideoDecoder* pDec = NULL;
  dec = (VDecoder*)calloc(1, sizeof(struct VDecoder));
  if (!dec) { 
    return 0;
  }
  dec->ctxt = ctxt;
  dec->width = ctxt->width;
  dec->height = ctxt->height;
  dec->ctxt->outputBuffer.numBuffers = ctxt->outputBuffer.numBuffers;
  if(VDEC_SUCCESS != vdec_commit_memory(dec)) {	
    return 0;
  }

  QPERF_RESET(arm_decode);
  QPERF_RESET(frame_data);
  nFrameDoneCnt = 0;
  nGoodFrameCnt = 0;
#ifdef PROFILE_DECODER
  qperf_total_frame_cnt = 0;
#endif

  vdec_output_frame_index = 0;
  timestamp = 0;
  int i;
  VDEC_PARAMETER_DATA codeDetectionEnable;
  codeDetectionEnable.startCodeDetection.bStartCodeDetectionEnable = false; // by default set to false; MPEG4 doesnt require it

  QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: vdec_open(). width: %d, height: %d\n", dec->width, dec->height);

  vdec_decoder_info = dec;
  QTV_MSG_PRIO3(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: vdec_open(). width: %d, height: %d kind[%s]\n", 
                                                   vdec_decoder_info->ctxt->width, vdec_decoder_info->ctxt->height, 
                                                   vdec_decoder_info->ctxt->kind);

  if(!strcmp(vdec_decoder_info->ctxt->kind,"OMX.qcom.video.decoder.avc"))
  {
	dec->core = reinterpret_cast<VDEC_STREAM_ID>(pCreateFnH264(&err));
	QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: Creating H264 Decoder [%p]\n",dec->core);
	VDEC_PARAMETER_DATA sizeOfNalLengthField;
        sizeOfNalLengthField.sizeOfNalLengthField.sizeOfNalLengthField = dec->ctxt->size_of_nal_length_field;
		QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: NAL lenght [%d]\n",dec->ctxt->size_of_nal_length_field);
        pDec = (VideoDecoder*)(dec->core);
        if (0 == dec->ctxt->size_of_nal_length_field) 
        {
		   QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: START CODE....\n");
	       codeDetectionEnable.startCodeDetection.bStartCodeDetectionEnable = true;
		   if(!pDec) 
	          err = VDEC_ERR_NULL_STREAM_ID;
	       else
		      err = pDec->SetParameter(VDEC_PARM_START_CODE_DETECTION,&codeDetectionEnable);
           if (VDEC_ERR_EVERYTHING_FINE != err)
           {
		      // TBD- printx("[vdec_core] set start code detection parameter failed: %d", (int)err);
		      QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"[vdec_core] set start code detection parameter failed: %d", (int)err);
              goto fail_initialize;
           }
        }
        else if(dec->ctxt->size_of_nal_length_field > 0 && dec->ctxt->size_of_nal_length_field <= 4)
        {
			QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: NALU LENGTH[%d]\n",dec->ctxt->size_of_nal_length_field);
           // test size of NAL length field decoder support 
	       if(!pDec) 
	          err = VDEC_ERR_NULL_STREAM_ID;
	       else
             err = pDec->SetParameter( VDEC_PARM_SIZE_OF_NAL_LENGTH_FIELD, &sizeOfNalLengthField );
	       if (VDEC_ERR_EVERYTHING_FINE != err)
           {
             // TBD- printx("[vdec_core] set start code detection parameter failed: %d", (int)err);
             goto fail_initialize;
           }
	    }
	    else
        {
			QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: Invalid size of nal length field: %d\n", dec->ctxt->size_of_nal_length_field);
            goto fail_core;
        } 
  }
  else if ((!strcmp(vdec_decoder_info->ctxt->kind,"OMX.qcom.video.decoder.mpeg4")) 
	       || (!strcmp(vdec_decoder_info->ctxt->kind,"OMX.qcom.video.decoder.h263")))
  {
	  dec->core = reinterpret_cast<VDEC_STREAM_ID>(pCreateFnMpeg4(&err));
	  pDec = (VideoDecoder*)(dec->core);
	  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: Creating MP4 Decoder [%p]\n",dec->core);
  }
  else if (!strcmp(vdec_decoder_info->ctxt->kind,"OMX.qcom.video.decoder.vc1"))
  {
	  dec->core = reinterpret_cast<VDEC_STREAM_ID>(pCreateFnWmv(&err));
	  pDec = (VideoDecoder*)(dec->core);
	  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: Creating WMV Decoder [%p]\n",dec->core);
  }
  else
  { 
	QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"Incorrect codec kind\n");
    goto fail_core;
  }

  if (VDEC_ERR_EVERYTHING_FINE != err || NULL == dec->core)
  {
	  QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: create failed\n");
      goto fail_core;
  }

  for(i=0; i<VDEC_NFRAMES; i++)
  {
    slice_buffer_info[i].base = (char*)dec->input[i].base;
    //slice_buffer_info[i].phys = dec->input[i].phys;
    slice_buffer_info[i].fd = dec->input[i].pmem_id;
  }
  
  VDEC_DIMENSIONS frameSize;
  frameSize.height = dec->height;
  frameSize.width = dec->width;
  QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: Init width: %d height %d\n", frameSize.width, frameSize.height);

/*  
  VDEC_PARAMETER_DATA deblockerInfo;
  deblockerInfo.deblockerEnable.bDeblockerEnable = true;

  QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"[vdec_core] SetParameter\n"); 
  err = vdec_set_parameter(dec->core, VDEC_PARM_DEBLOCKER_ENABLE, &deblockerInfo); 
  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"[vdec_core] after SetParameter\n",err); 
  if (VDEC_ERR_EVERYTHING_FINE != err)
  {
    //TBD - printx("[vdec_core] set deblocker enable parameter failed: %d", (int)err);
    goto fail_initialize;
  }
*/

 
  QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: vdec_initialize\n"); 
  if(!pDec) 
	  err = VDEC_ERR_NULL_STREAM_ID;
  else
  {
      err = pDec->Initialize(1,
			                 vdec_frame_buffer_malloc_cb_handler,
				             vdec_frame_buffer_free_cb_handler,
                             vdec_frame_cb_handler,
				             NULL,
				             frameSize,
				             VDEC_CONCURRENT_NONE,
				             slice_buffer_info,
					     dec->ctxt->outputBuffer.numBuffers,
					     ctxt->adsp_fd);
  }

  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: vdec_initialize\n",err); 
  if (err != VDEC_ERR_EVERYTHING_FINE)
  {
	  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: initialization failed: %d\n", (int)err);
      goto fail_initialize;
  }

#if NEED_VDEC_LP
#ifdef _ANDROID_
  dec->fake = adsp_open("/dev/adsp/VDEC_LP_MODE", dec->core, core_msg_func);
#else
  dec->fake = adsp_open("/dev/VDEC_LP_MODE", dec->core, core_msg_func);
#endif //_ANDROID_
  if (!dec->fake)
  {
	  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: adsp_open() failed error: %s\n", strerror(errno));
    goto fail_initialize;
  }
  if (adsp_enable((adsp_module*)dec->fake)) goto fail_enable;
#endif

#ifdef LOG_YUV_FRAMES
#ifdef T_WINNT
  pYUVFile = fopen ( "../debug/yuvframes.yuv" , "wb" );
#elif _ANDROID_
  pYUVFile = fopen ( "/data/yuvframes.yuv" , "wb" );
#else
  pYUVFile = fopen ( "yuvframes.yuv" , "wb" );
#endif
#endif

#ifdef LOG_INPUT_BUFFERS
#ifdef T_WINNT
  pInputFile = fopen ( "../debug/inputbuffers.bin" , "wb" );
#elif _ANDROID_
  pInputFile = fopen ( "/data/inputbuffers.bin" , "wb" );
#else
  pInputFile = fopen ( "inputbuffers.bin" , "wb" );
#endif
#endif

  return dec;
fail_enable:
#if NEED_VDEC_LP
  adsp_close((adsp_module*)dec->fake);
#endif
fail_initialize:
  if(pDec) {
	  pDec->Suspend( );
	  QTV_Delete( pDec );
  }
fail_core:
  if (dec) {
    dec->dead = 1;
    free(dec);
  }
  return NULL;

}
/**
 * @brief
 *  Update data structures related to event id passed.for QOE data.
 *
 * @param pHTTPSourceMMIHelper
 * @param eventID
 *
 * @return None
 */
void HTTPSourceMMIExtensionEventHandler::HTTPQOEEventManager::
     UpdateQOEData(HTTPSourceMMIHelper *pHTTPSourceMMIHelper,
                   const uint32 eventID)
{
  if(m_bQOENotify)
  {
    QTV_MSG_PRIO1(QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW,
      "HTTPSourceMMIExtensionEventHandler::HTTPQOEEventManager::UpdateQOEData eventID = %u",eventID);
    char* pVideoURL = NULL;
    uint32 nBandwidth = 0;
    uint32 nBufCount = 0;
    size_t nURLSize = 0;
    size_t nIPAddrSize = 0;
    size_t    nStopPhraseSize = 0;
    bool   bUpdateRequired = false;
    uint64 currMSeconds = 0;
    (void)MM_Time_GetCurrentTimeInMilliSecsFromEpoch(&currMSeconds);
    switch(eventID)
    {
      case QOMX_HTTP_IndexParamQOEPlay:
        if(!dataPlay)
        {
          dataPlay = (QOMX_QOE_DATA_PLAY *)QTV_Malloc(sizeof(QOMX_QOE_DATA_PLAY));
        }
        if(dataPlay)
        {
          memset(dataPlay,0,sizeof(QOMX_QOE_DATA_PLAY));
          dataPlay->size = (OMX_U32)sizeof(QOMX_QOE_DATA_PLAY);
          dataPlay->timeOfDay = currMSeconds;
        }
        break;
      case QOMX_HTTP_IndexParamQOESwitch:
        {
          if(pHTTPSourceMMIHelper)
          {
            pHTTPSourceMMIHelper->GetQOEData(nBandwidth,nBufCount,NULL,nURLSize,NULL,nIPAddrSize,NULL,nStopPhraseSize);
          }
          if(!dataSwitch)
          {
            dataSwitch = (QOMX_QOE_DATA_SWITCH *)QTV_Malloc(sizeof(QOMX_QOE_DATA_SWITCH));
          }
          if(dataSwitch)
          {
            memset(dataSwitch,0,sizeof(QOMX_QOE_DATA_SWITCH));
            dataSwitch->bandwidth  = nBandwidth;
            dataSwitch->reBufCount = nBufCount;
            dataSwitch->timeOfDay  = currMSeconds;
          }
        }
        break;
      case QOMX_HTTP_IndexParamQOEPeriodic:
        {
          char* pIPAddress = NULL;
          if(pHTTPSourceMMIHelper)
          {
            pHTTPSourceMMIHelper->GetQOEData(nBandwidth,nBufCount,pVideoURL,nURLSize,pIPAddress,nIPAddrSize,NULL,nStopPhraseSize);
            if(pVideoURL == NULL && nURLSize)
            {
              pVideoURL = (char*)QTV_Malloc(nURLSize+1);
              if(pVideoURL)
              {
                bUpdateRequired = true;
              }
            }
            if(pIPAddress == NULL && nIPAddrSize)
            {
              pIPAddress = (char*)QTV_Malloc(nIPAddrSize+1);
              if(pIPAddress)
              {
                bUpdateRequired = true;
              }
            }
            if(bUpdateRequired)
            {
              pHTTPSourceMMIHelper->GetQOEData(nBandwidth,nBufCount,pVideoURL,nURLSize,pIPAddress,nIPAddrSize,NULL,nStopPhraseSize);
              bUpdateRequired = false;
            }
          }
          size_t nSize = sizeof(QOMX_QOE_DATA_PERIODIC)+nURLSize+1+nIPAddrSize+1;
          if(dataPeriodic)
          {
            QTV_Free(dataPeriodic);
          }
          dataPeriodic = (QOMX_QOE_DATA_PERIODIC *)QTV_Malloc(nSize);
          if(dataPeriodic)
          {
            memset(dataPeriodic,0,nSize);
            dataPeriodic->size = (uint32)nSize;
            dataPeriodic->bandwidth = nBandwidth;
            dataPeriodic->timeOfDay = currMSeconds;
            dataPeriodic->nInfoPeriodicLen = (OMX_U32)(nURLSize+1+nIPAddrSize+1);
            if(pIPAddress)
            {
              std_memmove(dataPeriodic->infoPeriodic,pIPAddress,std_strlen(pIPAddress)+1);
              dataPeriodic->nIpAddressLen = (OMX_U32)std_strlen(pIPAddress)+1;
            }
            if(pVideoURL)
            {
              std_memmove(dataPeriodic->infoPeriodic+dataPeriodic->nIpAddressLen,pVideoURL,std_strlen(pVideoURL)+1);
              dataPeriodic->nVideoURLLen =  (OMX_U32)std_strlen(pVideoURL)+1;
            }
          }
          if(pIPAddress)
          {
            QTV_Free(pIPAddress);
            pIPAddress = NULL;
          }
        }
        break;
      case QOMX_HTTP_IndexParamQOEStop:
        {
          char* pStopPhrase = NULL;
          if(pHTTPSourceMMIHelper)
          {
            pHTTPSourceMMIHelper->GetQOEData(nBandwidth,nBufCount,pVideoURL,nURLSize,NULL,nIPAddrSize,pStopPhrase,nStopPhraseSize);
            if(pVideoURL == NULL && nURLSize)
            {
              pVideoURL = (char*)QTV_Malloc(nURLSize+1);
              if(pVideoURL)
              {
                bUpdateRequired = true;
              }
            }
            if(pStopPhrase == NULL && nStopPhraseSize)
            {
              pStopPhrase = (char*)QTV_Malloc(nStopPhraseSize+1);
              if(pStopPhrase)
              {
                bUpdateRequired = true;
              }
            }
            if(bUpdateRequired)
            {
              pHTTPSourceMMIHelper->GetQOEData(nBandwidth,nBufCount,pVideoURL,nURLSize,NULL,nIPAddrSize,pStopPhrase,nStopPhraseSize);
              bUpdateRequired = false;
            }
          }
          size_t nSize = sizeof(QOMX_QOE_DATA_STOP)+nURLSize+1+nStopPhraseSize+1;
          if(dataStop)
          {
            QTV_Free(dataStop);
          }
          dataStop = (QOMX_QOE_DATA_STOP *)QTV_Malloc(nSize);
          if(dataStop)
          {
            memset(dataStop,0,nSize);
            dataStop->size = (OMX_U32)nSize;
            dataStop->bandwidth = (OMX_U32)nBandwidth;
            dataStop->reBufCount = nBufCount;
            dataStop->timeOfDay = currMSeconds;
            dataStop->nInfoStopLen = (OMX_U32)(nURLSize+1+nStopPhraseSize+1);
            if(pStopPhrase)
            {
              std_memmove(dataStop->infoStop,pStopPhrase,std_strlen(pStopPhrase)+1);
              dataStop->nStopPhraseLen = (OMX_U32)(std_strlen(pStopPhrase)+1);
            }

            if(pVideoURL)
            {
              std_memmove(dataStop->infoStop+dataStop->nStopPhraseLen,pVideoURL,std_strlen(pVideoURL)+1);
              dataStop->nVideoURLLen = (OMX_U32)(std_strlen(pVideoURL)+1);
            }
          }
          if(pStopPhrase)
          {
            QTV_Free(pStopPhrase);
            pStopPhrase = NULL;
          }
        }
        break;
      default:
        break;
    }
    if(pVideoURL)
    {
      QTV_Free(pVideoURL);
      pVideoURL = NULL;
    }
  }
}
示例#26
0
Vdec_ReturnType vdec_close(struct VDecoder *dec)
{
  VDEC_ERROR err;
  VideoDecoder* pDec = (VideoDecoder*)(dec->core);
  QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: vdec_close()\n");
#ifdef PROFILE_DECODER
  usecs_t time_taken_by_arm = QPERF_TERMINATE(arm_decode);
  float avArmTime = (float)time_taken_by_arm/(qperf_total_frame_cnt*1000);
  usecs_t frame_data_time = QPERF_TERMINATE(frame_data);
  QTV_PERF_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"===========================================================\n");
  QTV_PERF_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"                     Arm Statistics                        \n");
  QTV_PERF_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"===========================================================\n");
  QTV_PERF_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"Total number of frames decoded = %ld\n",qperf_total_frame_cnt);
  QTV_PERF_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"Average Arm time/frame(ms)     = %f\n",avArmTime);
  QTV_PERF_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"Frames Arm Decoded/sec         = %f\n",1000/avArmTime);
  QTV_PERF_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"===========================================================\n");
  QTV_PERF_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"                    Frame Done Statistics                  \n");
  QTV_PERF_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"===========================================================\n");
  QTV_PERF_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"Frame done cumulative time     = %lld\n",frame_data_time);
  QTV_PERF_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"Frames Done per second         = %f\n",(float)(qperf_total_frame_cnt-1)*1000000/frame_data_time);
  QTV_PERF_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"===========================================================\n");
#endif
#ifdef LOG_YUV_FRAMES
  if (pYUVFile)
  {
    fclose (pYUVFile);
	pYUVFile = NULL;
  }
#endif
#ifdef LOG_INPUT_BUFFERS
  if (pInputFile)
  {
    fclose (pInputFile);
  }
#endif
  vdec_output_frame_index = 0;

#if NEED_VDEC_LP
  if (vdec->fake)
  {
    //jlk - adsp_close() calls adsp_disable right now.  Calling adsp_disable() twice causes problems
    //Renable this line when we fix the kernel driver
    //adsp_disable((adsp_module*)vdec->fake);
    adsp_close((adsp_module*)vdec->fake);
  }
  else
  {
	  QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: adsp modules is NULL\n");
  }
#endif
  nFrameDoneCnt = 0;
  nGoodFrameCnt = 0;

  if (dec->core)
  {
	QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: calling Suspend");
    err = pDec->Suspend( );
    if (VDEC_ERR_EVERYTHING_FINE != err)
    {
		QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: Suspend returned error: %d\n", (int)err);
    }
	QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: calling vdec_destroy"); 
	QTV_Delete( (VideoDecoder*)(dec->core) );
  }
  else
  {
	  QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: core is NULL");
  }
    pmem_free(&dec->arena);
	free(dec);
	QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"vdec: closed\n");
	return VDEC_SUCCESS;
}
示例#27
0
void vdec_frame_cb_handler ( const VDEC_STREAM_ID /*stream*/,
                             VDEC_CB_STATUS       status,
                             VDEC_FRAME * const   pFrame,
                             unsigned long int               /*nBytesConsumed*/,
                             void * const         pCbData )
{
  int index;
 
  ++nFrameDoneCnt;
  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"vdec: frame done cb cnt: %d", nFrameDoneCnt); 
  switch(status)
  {
    case VDEC_STATUS_GOOD_FRAME:
    case VDEC_STATUS_FLUSH:
    {
      if (NULL == pFrame)
      {
		  QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: pFrame parameter is NULL, dropping frame\n");
        break;
      }

      //Iterate through the output frame array to locate corresponding index
      for (index=0; index<vdec_decoder_info->ctxt->outputBuffer.numBuffers; index++)
      {
        //if (pFrame->pBuf == (VDEC_BYTE*)vdec_decoder_info->output[index].phys)
        if (pFrame->pBuf == (VDEC_BYTE*)vdec_decoder_info->output[index].base)
        {
           break;
        }
      }
      if (vdec_decoder_info->ctxt->outputBuffer.numBuffers == index)
      {
		  QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: error: unable to map address %p, dropping frame\n", pFrame->pBuf);
      }
      else
      {
        if(VDEC_STATUS_FLUSH == status)
        {
          vdec_decoder_info->output[index].flags |= FRAME_FLAG_FLUSHED;
        }
        else
        {
          ++nGoodFrameCnt;
#ifdef PROFILE_DECODER
          ++qperf_total_frame_cnt;
#endif
          vdec_decoder_info->output[index].flags = 0;
          QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: callback status good frame, cnt: %d\n", nGoodFrameCnt);
        
#ifdef LOG_YUV_FRAMES
          if (pYUVFile)
          {
            int size = vdec_decoder_info->width*vdec_decoder_info->height*1.5;
        fwritex(vdec_decoder_info->output[index].base, size, pYUVFile);
          }
#endif
        }
        if(nGoodFrameCnt >1) 
        {
          QPERF_END(frame_data);
        }
	QPERF_START(frame_data);
        vdec_decoder_info->output[index].timestamp = pFrame->timestamp;
	if(pFrame->frameType == VDEC_FRAMETYPE_I)
        {
            vdec_decoder_info->output[index].frameDetails.ePicType[0] = VDEC_PICTURE_TYPE_I;
        }
        if(pFrame->frameType == VDEC_FRAMETYPE_B)
        {
            vdec_decoder_info->output[index].frameDetails.ePicType[0] = VDEC_PICTURE_TYPE_B;
        }
        if(pFrame->frameType == VDEC_FRAMETYPE_P)
        {
            vdec_decoder_info->output[index].frameDetails.ePicType[0] = VDEC_PICTURE_TYPE_P;
        }
        vdec_decoder_info->ctxt->frame_done(vdec_decoder_info->ctxt, &vdec_decoder_info->output[index]);
      }
      break;
    }

    case VDEC_STATUS_DECODE_ERROR:
    {
		QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"vdec: callback status decode error\n");
      break;
    }

    case VDEC_STATUS_FATAL_ERROR:
    {
      QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"vdec: callback status error fatal\n");
      //Iterate through the output frame array to locate corresponding index
      for (index=0; index<vdec_decoder_info->ctxt->outputBuffer.numBuffers; index++)
      {
        if (pFrame->pBuf == (VDEC_BYTE*)vdec_decoder_info->output[index].base)
        {
           break;
        }
      }
      if (vdec_decoder_info->ctxt->outputBuffer.numBuffers == index)
      {
        QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,
                      "vdec: error: unable to map address %p for VDEC_STATUS_FATAL_ERROR, dropping frame\n", pFrame->pBuf);
      }
      else
      {
        QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_FATAL,"vdec: frame done index = %d\n",index);
        vdec_decoder_info->output[index].flags = FRAME_FLAG_FATAL_ERROR;
        vdec_decoder_info->ctxt->frame_done(vdec_decoder_info->ctxt, &vdec_decoder_info->output[index]);
      }
      break;
    }

    case VDEC_STATUS_VOP_NOT_CODED:
    {
		QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: callback status not coded\n");
      break;
    }

    case VDEC_STATUS_SUSPEND_DONE:
    {
		QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"vdec: callback status suspend done\n");
      break;
    }

    case VDEC_STATUS_EOS:
    {
      static struct vdec_frame frame;
      memset(&frame, 0, sizeof(frame));
      frame.flags |= FRAME_FLAG_EOS;
      QPERF_END(frame_data);
      vdec_decoder_info->ctxt->frame_done(vdec_decoder_info->ctxt, &frame);
      
	  QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_LOW,"vdec: callback status EOS\n");
      break;
    }

    default:
		QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"vdec: callback status unknown status\n");
      break;
  }

  return;
}
示例#28
0
int adsp_init(struct adsp_module *mod, struct adsp_init *init)
{
   struct vdec_init vi;
   struct vdec_buf_req buf;
   struct vdec_version ver;
   if (NULL == mod) {
      QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW,
               "adsp_init() mod NULL: 0x%x\n", mod);
      return -1;
   }

   /* Get the driver version */
   if (ioctl(mod->fd, VDEC_IOCTL_GETVERSION, &ver) < 0) {
     QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
              "VDEC_IOCTL_GETVERSION failed setting to default version\n");
     ver.major = 1;
     ver.minor = 0;
   }

   vi.sps_cfg.cfg.width = init->width;
   vi.sps_cfg.cfg.height = init->height;
   vi.sps_cfg.cfg.order = init->order;
   vi.sps_cfg.cfg.notify_enable = init->notify_enable;
   vi.sps_cfg.cfg.fourcc = init->fourcc;
   vi.sps_cfg.cfg.vc1_rowbase = init->vc1_rowbase;
   vi.sps_cfg.cfg.h264_startcode_detect = init->h264_startcode_detect;
   vi.sps_cfg.cfg.h264_nal_len_size = init->h264_nal_len_size;
   vi.sps_cfg.cfg.postproc_flag = init->postproc_flag;
   vi.sps_cfg.cfg.fruc_enable = init->fruc_enable;
   vi.sps_cfg.cfg.color_format = init->color_format;
   vi.sps_cfg.seq.header = init->seq_header;
   vi.sps_cfg.seq.len = init->seq_len;
   vi.buf_req = &buf;

   /* set the color format based on version */
   if (ver.major < 2 && init->color_format != 0) {
     QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
              "VDEC_IOCTL_INITIALIZE wrong value for reserved field\n");
     vi.sps_cfg.cfg.color_format = 0;
   }

   if (ioctl(mod->fd, VDEC_IOCTL_INITIALIZE, &vi) < 0) {
      QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
              "VDEC_IOCTL_INITIALIZE failed\n");
      mod->dead = 1;
      return -1;
   }
   init->buf_req->input.bufnum_min = vi.buf_req->input.num_min_buffers;
   init->buf_req->input.bufnum_max = vi.buf_req->input.num_max_buffers;
   init->buf_req->input.bufsize = vi.buf_req->input.bufsize;
   init->buf_req->output.bufnum_min = vi.buf_req->output.num_min_buffers;
   init->buf_req->output.bufnum_max = vi.buf_req->output.num_max_buffers;
   init->buf_req->output.bufsize = vi.buf_req->output.bufsize;
   init->buf_req->dec_req1.bufnum_min =
       vi.buf_req->dec_req1.num_min_buffers;
   init->buf_req->dec_req1.bufnum_max =
       vi.buf_req->dec_req1.num_max_buffers;
   init->buf_req->dec_req1.bufsize = vi.buf_req->dec_req1.bufsize;
   init->buf_req->dec_req2.bufnum_min =
       vi.buf_req->dec_req2.num_min_buffers;
   init->buf_req->dec_req2.bufnum_max =
       vi.buf_req->dec_req2.num_max_buffers;
   init->buf_req->dec_req2.bufsize = vi.buf_req->dec_req2.bufsize;

   return 0;

}
/** @brief Convert the HTTP status code to MMI status code for Download.
*
* @param[in] HTTPStatus - HTTP streamer status code
* @param[in] pUserData - Reference to the registered MMI callback iface
*/
void HTTPSourceMMIHelper::ProcessDownloadStatus
(
 const HTTPDownloadStatus HTTPStatus,
 void* pUserData
 )
{
  bool bSuppressNotification = false;
  bool result = false;
  unsigned int ret = MMI_S_EFAIL;
  bool bOpenComplete = false;
  OMX_U32 nEvtCode = MMI_RESP_START;
  void *pEventData = NULL;
  MMI_ResourceLostMsgType resourceLostMsg;
  uint32 nEventDataSize = 0;
  if (m_pHTTPSourceMMI == NULL)
  {
    return;
  }

  bOpenComplete = m_pHTTPSourceMMI->IsOpenComplete();

  switch (HTTPStatus)
  {
  case HTTPCommon::HTTPDL_ERROR_ABORT:
  case HTTPCommon::HTTPDL_TIMEOUT:
  case HTTPCommon::HTTPDL_OUT_OF_MEMORY:
  case HTTPCommon::HTTPDL_UNSUPPORTED:
    ret = MMI_S_EFAIL;
    break;
  case HTTPCommon::HTTPDL_INTERRUPTED:
  case HTTPCommon::HTTPDL_DATA_END:
    //Download interrupted - don't notify if Open is complete,
    //because being here means a user-ininitated stop
    if (bOpenComplete)
    {
      bSuppressNotification = true;
      break;
    }
    ret = MMI_S_EFAIL;
    break;
  case HTTPCommon::HTTPDL_SUCCESS:
    //Download succeeded
    bSuppressNotification = true;
    result = true;
    QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_HIGH, "Download complete" );
    break;
  case HTTPCommon::HTTPDL_TRACKS_AVALIABLE:
    QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_HIGH, "Tracks available" );

    if (!m_pHTTPSourceMMI->IsOpenComplete())
    {
      m_pHTTPSourceMMI->SetOpenComplete(true);
      bOpenComplete = true;
    }
    //Create the thread to process FTB calls
    m_pHTTPSourceMMI->StartDataRequestProcessing();

    ProcessGetTracksStatus(HTTPCommon::HTTPDL_SUCCESS, pUserData);

    bSuppressNotification = true;
    break;
  default:
    //Ignore other events
    bSuppressNotification = true;
    break;
  }

  if (bOpenComplete && !bSuppressNotification)
  {
    //if open complete, i.e. we'd sent start response
    //so send an resource lost event for any error now
    nEvtCode = MMI_EVT_RESOURCES_LOST;
    ret = MMI_S_COMPLETE;
    resourceLostMsg.bSuspendable = OMX_FALSE;
    pEventData = &resourceLostMsg;
    nEventDataSize = (uint32)sizeof(MMI_ResourceLostMsgType);
    m_pHTTPSourceMMI->UpdateStopPhrase((char*)STOP_ERROR_STRING);
    QTV_MSG_PRIO1(QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR,
      "HttpMmi download error, status %d",
      HTTPStatus);
  }

  if (!bSuppressNotification && !bOpenComplete)
  {
    //set open complete if we encounter any timeout,
    //any other error while downloading
    m_pHTTPSourceMMI->SetOpenComplete(true);
  }

  if (!bSuppressNotification)
  {
    NotifyMmi(nEvtCode, ret, nEventDataSize, pEventData, pUserData);
  }
  else
  {
    QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW,
      "HTTP MMI notification suppressed" );
  }
}
示例#30
0
struct adsp_module *adsp_open(const char *name, struct adsp_open_info info,
               void *context, int32 vdec_fd)
{

   QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_LOW, "adsp_open: %s", name);
   int fds[2], r;
   struct adsp_module *mod;

   mod = calloc(1, sizeof(*mod));
   if (!mod)
      return 0;

   mod->ctxt = context;
   mod->frame_done = info.frame_done;
   mod->buffer_done = info.buffer_done;

#ifndef T_WINNT
   mod->dead = 0;
   mod->init_done = 0;
   r = pthread_create(&mod->thr, 0, adsp_thread, mod);
   if (r < 0) {
      QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
              "Error - unable to create adsp_thread\n");
      goto fail_thread;
   }

   mod->fd = vdec_fd;
   if(mod->fd < 0) {
      mod->fd = open("/dev/vdec", O_RDWR);
      if (mod->fd < 0) {
         QTV_MSG_PRIO3(QTVDIAG_GENERAL, QTVDIAG_PRIO_FATAL,
                  "adsp: cannot open '%s', fd: %d (%s)\n", name,
                  mod->fd, strerror(errno));
         goto fail_open;
      }
   }
#if DEBUG
   if (pthread_mutex_init(&logMTX, NULL) == 0) {
      if (pthread_mutex_lock(&logMTX) == 0) {
         if (!logFD) {
            logFD = fopen(logFN, "a");
         }
         if (logFD) {
            fprintf(logFD, "\n");
            pthread_mutex_unlock(&logMTX);
         }
      }
      if (!logFD) {
         pthread_mutex_destroy(&logMTX);
      }
   }
   if (!logFD) {
      QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,
              "adsp: unable to log adsp writes\n");
   }
#endif

#endif

   return mod;
      fail_open:
   mod->dead = 1;
      fail_thread:
   free(mod);
   return 0;
}