HTTPReturnCode HTTPStackHelper::GetContentType(uint32 requestId, char *contentType, size_t contentTypeLen, size_t *contentTypeLenReq) { HTTPReturnCode result = HTTP_FAILURE; if (NULL == m_HTTPState) { QTV_MSG_PRIO(QTVDIAG_HTTP_STACK, QTVDIAG_PRIO_ERROR, "HTTPStackHelper::GetContentType : m_HTTPState is NULL"); } else { GetContentTypeArgument arg(contentType, contentTypeLen, contentTypeLenReq); const char *respContentType = m_HTTPStateInfo.GetContentType(requestId); if (NULL == contentType) { if(NULL != respContentType) { *contentTypeLenReq = std_strlen(respContentType) + 1; result = HTTP_SUCCESS; } } else { if (NULL != respContentType) { std_strlcpy(contentType, respContentType, contentTypeLen); result = HTTP_SUCCESS; } } } return result; }
/** @brief Process HTTP event notification from HTTPDataRequestHandler. * * @param[in] HTTPCommand - HTTP data command * @param[in] HTTPStatus - Command execution status * @param[in] pCbData - Reference to the registered MMI callback iface */ void HTTPSourceMMIHelper::NotifyHTTPEvent ( const HTTPDataCommand HTTPCommand, const HTTPDownloadStatus HTTPStatus, void* pCbData ) { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW, "HTTPSourceMMIHelper::NotifyHTTPEvent" ); //Convert HTTP event/status to MMI event/status switch (HTTPCommand) { case HTTPCommon::FLUSH: ProcessFlushStatus(HTTPStatus, pCbData); break; default: //Ignore other events break; } }
HTTPReturnCode HTTPStackHelper::SetHeader(uint32 requestId, const char * key, int keyLen, const char *value, int valueLen) { HTTPReturnCode result = HTTP_FAILURE; if (NULL == m_HTTPState) { QTV_MSG_PRIO(QTVDIAG_HTTP_STACK, QTVDIAG_PRIO_ERROR, "HTTPStackHelper::SetHeader : m_HTTPState is NULL"); } else { bool isHeaderSet = m_HTTPStateInfo.SetHeader(requestId, key, keyLen, value, valueLen); result = (true == isHeaderSet ? HTTP_SUCCESS : HTTP_FAILURE); } return result; }
HTTPStackHelper::HTTPStackHelper( void *pOwner, NotifyCallback NotifyCb, HTTPCookieMgr& cookieMgr) : m_HTTPStateInfo(cookieMgr), m_ProxyServerName(NULL), m_ProxyServerPort(0), m_HTTPState(&(HTTPStackStateObjects::HTTPStateIdleObj)), m_pCStreamNetwork(NULL), m_pOwner(pOwner), m_fNotifyCallback(NotifyCb) { ResetOptions(); m_NetworkIfaceId = -1; m_PrimaryPDPProfileNo = -1; m_pCStreamNetwork = CStreamNetwork::CreateInstance(true); if (NULL == m_pCStreamNetwork) { QTV_MSG_PRIO(QTVDIAG_HTTP_STACK, QTVDIAG_PRIO_ERROR, "HTTPStackHelper Failed to create instance of m_pCStreamNetwork"); } }
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; }
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; }
/** @brief DownloadAndUpdatePlaylist. * * @return * HTTPDL_WAITING - Download In progress - check back later * HTTPDL_SUCCESS - Download Complete * HTTPDL_ERROR_ABORT - Otherwise */ HTTPDownloadStatus PlaylistDownloadHelper::DownloadAndUpdatePlaylist() { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW, "PlaylistDownloadHelper::DownloadAndUpdatePlaylist()" ); return CurrentStateHandler(this); }
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; }
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; }
/** @brief Convert the HTTP status code to MMI status code for Seek. * * @param[in] HTTPStatus - HTTP streamer status code * @param[in] pUserData - Reference to the registered MMI callback iface */ void HTTPSourceMMIHelper::ProcessSeekStatus ( const HTTPDownloadStatus HTTPStatus, void* pUserData ) { bool bNotify = true; if (m_pHTTPSourceMMI == NULL) { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "MMI notification suppressed since m_pHTTPSourceMMI is NULL" ); return; } (void)MM_CriticalSection_Enter(m_pHTTPSourceMMI->m_pHTTPSourceMMIDataLock); if (HTTPSUCCEEDED(HTTPStatus) || HTTPStatus == HTTPCommon::HTTPDL_DATA_END) { if(m_pHTTPSourceMMI->m_pHTTPDataInterface) { OMX_U32 ret = MMI_S_COMPLETE; //Seek is complete, adjust OMX buffer flags, notify track handler and check if //there is another pending seek int64 currSeekTime = m_pHTTPSourceMMI->m_nCurrentSeekTime; int64 pendingSeekTime = m_pHTTPSourceMMI->m_nPendingSeekTime; m_pHTTPSourceMMI->m_pHTTPSourceMMITrackHandler->SetAbsoluteSeekOffset(currSeekTime); m_pHTTPSourceMMI->SetStartTimeBufferFlag(); if(HTTPStatus == HTTPCommon::HTTPDL_DATA_END) { //Return seek success. Later when FTBs come, if EOSbuffer flag is set, return EOS sample from MMI directly m_pHTTPSourceMMI->SetEOSBufferFlag(); QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "recvd HTTPDL_DATA_END" ); } if (pendingSeekTime != currSeekTime) { m_pHTTPSourceMMI->SetSeekPending(false); ret = m_pHTTPSourceMMI->Seek(pendingSeekTime, NULL); } else if(ret == MMI_S_COMPLETE) { bool isAudioPortConfigPending = false; bool isVideoPortConfigPending = false; bool isOtherPortConfigPending = false; if(HTTPStatus != HTTPCommon::HTTPDL_DATA_END) { //After seek is completed compare and update all the tracks and port information. //Delay port config change event for the track untill seekpending flag //becomes false, so that AAL would get only updated port information //TODO: Delaying of port config change event would be avoided if AAL //issue discontinuety to framwork upon getting port setting change event //and framwork start querying the scan source for the port if(m_pHTTPSourceMMI->CompareAndUpdatePorts(isAudioPortConfigPending, isVideoPortConfigPending, isOtherPortConfigPending) == HTTPCommon::HTTPDL_ERROR_ABORT) { ret = MMI_S_EFAIL; } } m_pHTTPSourceMMI->SetSeekPending(false); // Check and send port config event after seek pernding flag becomes false if((HTTPStatus != HTTPCommon::HTTPDL_DATA_END) && (MMI_S_EFAIL != ret)) { m_pHTTPSourceMMI->CheckAndSendPortConfigChangeEvent(HTTPCommon::HTTP_AUDIO_TYPE, 0, isAudioPortConfigPending); m_pHTTPSourceMMI->CheckAndSendPortConfigChangeEvent(HTTPCommon::HTTP_VIDEO_TYPE, 0, isVideoPortConfigPending); m_pHTTPSourceMMI->CheckAndSendPortConfigChangeEvent(HTTPCommon::HTTP_TEXT_TYPE, 0, isOtherPortConfigPending); } //Resume data command processing if(m_pHTTPSourceMMI->m_pHTTPDataReqHandler) { m_pHTTPSourceMMI->m_pHTTPDataReqHandler->Resume(); } const char *pCachedSelectRepresentations = m_pHTTPSourceMMI->GetCachedSelectedRepresentations(); if (pCachedSelectRepresentations) { QTV_MSG_PRIO(QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_HIGH, "ProcessSeekStatus: Queue pending AdaptationSet change cmd"); if(m_pHTTPSourceMMI->m_pHTTPController->SelectRepresentations(pCachedSelectRepresentations)) { ret = MMI_S_COMPLETE; m_pHTTPSourceMMI->SetSelectRepresentationsPending(true); m_pHTTPSourceMMI->ClearCachedSelectRepresentions(); } } } if(ret == MMI_S_COMPLETE) { bNotify = false; } } } //Only failure before posting a SEEK on File Source is captured here. //Seek status is notified by File Source if it has been posted if (bNotify) { if (m_pHTTPSourceMMI->m_pHTTPSourceMMITrackHandler) { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "MMI_EVT_RESOURCES_LOST to be sent, clearing track desc" ); (void)m_pHTTPSourceMMI->m_pHTTPSourceMMITrackHandler->ResetPortInfo(); } m_pHTTPSourceMMI->SetSeekPending(false); MMI_ResourceLostMsgType resourceLostMsg; resourceLostMsg.bSuspendable = OMX_FALSE; m_pHTTPSourceMMI->UpdateStopPhrase((char*)STOP_ERROR_STRING); NotifyMmi(MMI_EVT_RESOURCES_LOST, MMI_S_EFAIL, sizeof(MMI_ResourceLostMsgType), (void *)&resourceLostMsg, pUserData); } (void)MM_CriticalSection_Leave(m_pHTTPSourceMMI->m_pHTTPSourceMMIDataLock); }
HTTPReturnCode HTTPStackHelper::NotifyEvent(uint32 requestId, HTTPStackNotifyCode notifyCode) { HTTPReturnCode rsltCode = HTTP_FAILURE; HTTPStackNotificationCbData cbData = {0,NULL,NULL,false,NULL,NULL,NULL}; cbData.m_serverCode = m_HTTPStateInfo.GetHTTPResponseCode(requestId); cbData.m_serverMessage = (char*)m_HTTPStateInfo.GetReasonPhraseStr(requestId); cbData.m_entityBody = (char*)m_HTTPStateInfo.GetEntityBody(requestId); cbData.m_method = (char *)HTTPStackCommon::GetStringForMethod(m_HTTPStateInfo.GetRequestMethod(requestId)); cbData.m_protocolHeaders = NULL; cbData.m_pHTTPStack = m_pHTTPStack; int reqLen = 0; /** * This commented code is in line with what is specified for * protocol header events. However, current decision is to send * protocol header event for authorization or porxy-authoirzation * only. If this changes then this can be uncommented and th the * code following this can be * removed. * * httpResponse.GetHeaders(NULL, 0, reqLen); * * if (reqLen > 0) *{ * int bufSize = reqLen; cbData.m_protocolHeaders = (char * * *)QTV_Malloc(bufSize * sizeof(char)); * * if (cbData.m_protocolHeaders) * { * httpResponse.GetHeaders(cbData.m_protocolHeaders,bufSize, *reqLen); * } * } * else { * QTV_MSG_PRIO1(QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, * * "HTTPStackHelper::NotifyEvent Did not find headers for * response. ServerCode %d", cbData.m_serverCode); * } */ static const int AUTHENTICATE_KEY_LEN = (int)std_strlen(HTTPStackCommon::AUTHENTICATE_KEY); static const int PROXY_AUTHENTICATE_KEY_LEN = (int)std_strlen(HTTPStackCommon::PROXY_AUTHENTICATE_KEY); static const char *DELIM = ": "; static const int DELIM_LEN = (int)std_strlen(DELIM); static const char *TERMINATE = "\r\n\r\n"; static const int TERMINATE_LEN = (int)std_strlen(TERMINATE); m_HTTPStateInfo.GetHeaderValue(requestId, HTTPStackCommon::AUTHENTICATE_KEY, AUTHENTICATE_KEY_LEN, NULL, 0, &reqLen); if (reqLen > 0) { // response header contains "WWW-Authenticate" int reqdBufSize = AUTHENTICATE_KEY_LEN + DELIM_LEN + reqLen + TERMINATE_LEN + 1; cbData.m_protocolHeaders = (char *)QTV_Malloc(reqdBufSize * sizeof(char)); if (cbData.m_protocolHeaders) { std_strlcpy(cbData.m_protocolHeaders, HTTPStackCommon::AUTHENTICATE_KEY, reqdBufSize); std_strlcat(cbData.m_protocolHeaders, DELIM, reqdBufSize); int tmpLen = reqLen; m_HTTPStateInfo.GetHeaderValue(requestId, HTTPStackCommon::AUTHENTICATE_KEY, AUTHENTICATE_KEY_LEN, cbData.m_protocolHeaders + AUTHENTICATE_KEY_LEN + DELIM_LEN, reqLen, &tmpLen); std_strlcat(cbData.m_protocolHeaders, TERMINATE, reqdBufSize); } else { QTV_MSG_PRIO(QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "cbData.m_protocolHeaders for authentication is NULL"); } } else { m_HTTPStateInfo.GetHeaderValue(requestId, HTTPStackCommon::PROXY_AUTHENTICATE_KEY, PROXY_AUTHENTICATE_KEY_LEN, NULL, 0, &reqLen); if (reqLen > 0) { int reqdBufSize = PROXY_AUTHENTICATE_KEY_LEN + DELIM_LEN + reqLen + TERMINATE_LEN + 1; cbData.m_protocolHeaders = (char *)QTV_Malloc(reqdBufSize * sizeof(char)); if (cbData.m_protocolHeaders) { std_strlcpy(cbData.m_protocolHeaders, HTTPStackCommon::PROXY_AUTHENTICATE_KEY, reqdBufSize); std_strlcat(cbData.m_protocolHeaders, DELIM, reqdBufSize); int tmpLen = reqLen; m_HTTPStateInfo.GetHeaderValue(requestId, HTTPStackCommon::PROXY_AUTHENTICATE_KEY, PROXY_AUTHENTICATE_KEY_LEN, cbData.m_protocolHeaders + PROXY_AUTHENTICATE_KEY_LEN + DELIM_LEN, reqLen, &tmpLen); std_strlcat(cbData.m_protocolHeaders, TERMINATE, reqdBufSize); } else { QTV_MSG_PRIO(QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "cbData.m_protocolHeaders for proxy-authentication is NULL"); } } } rsltCode = m_fNotifyCallback(requestId, notifyCode,&cbData, m_pOwner); return rsltCode; }
HTTPReturnCode HTTPStackHelper::SetProxyServer (const char* proxyServer, size_t proxyServerLen) { HTTPReturnCode result = HTTP_FAILURE; char *localProxyUrl = NULL; if (proxyServerLen > (size_t)HTTPStackCommon::MAX_PROXY_URL_LEN) { result = HTTP_BADPARAM; QTV_MSG_PRIO1(QTVDIAG_HTTP_STACK, QTVDIAG_PRIO_ERROR, "HTTPStackHelper::SetProxyServer : Invalid proxyServerLen '%d'", proxyServerLen); } else { localProxyUrl = (char *)QTV_Malloc( (proxyServerLen + 1) * sizeof(char)); if (NULL == localProxyUrl) { QTV_MSG_PRIO(QTVDIAG_HTTP_STACK, QTVDIAG_PRIO_ERROR, "HTTPStackHelper::SetProxyServer : Failed to allocate localProxyUrl"); } else { std_strlcpy(localProxyUrl, proxyServer, proxyServerLen + 1); localProxyUrl[proxyServerLen] = 0; if (NULL != m_ProxyServerName) { QTV_Free(m_ProxyServerName); m_ProxyServerName = NULL; } m_ProxyServerName = (char *)QTV_Malloc((proxyServerLen + 1) * sizeof(char)); if (NULL == m_ProxyServerName) { QTV_MSG_PRIO(QTVDIAG_HTTP_STACK, QTVDIAG_PRIO_ERROR, "HTTPStackHelper::SetProxyServer : Failed to allocate m_ProxyServerName"); } else { result = HTTP_SUCCESS; char *posPort = std_strstr(localProxyUrl, ":"); if (NULL == posPort) { m_ProxyServerPort = HTTPStackCommon::DEFAULT_HTTP_PORT; std_strlcpy(m_ProxyServerName, localProxyUrl, (proxyServerLen + 1)); } else { int32 m_temp_ProxyServerPort = atoi(posPort+1); if (!m_temp_ProxyServerPort) { // not able to parse QTV_MSG_PRIO(QTVDIAG_HTTP_STACK, QTVDIAG_PRIO_ERROR, "HTTPStackHelper::SetProxyServer - Error in parsing"); } else { m_ProxyServerPort = (unsigned short)m_temp_ProxyServerPort; } *posPort = '\0'; std_strlcpy(m_ProxyServerName, localProxyUrl, proxyServerLen + 1); } } // end if (m_ProxyServerName...) } // end if(localProxyUrl...) if (localProxyUrl) { QTV_Free(localProxyUrl); localProxyUrl = NULL; } } if (result == HTTP_SUCCESS) { result = m_HTTPStateInfo.SetProxyInfo(m_ProxyServerName,m_ProxyServerPort); } return result; }
/** @brief WAITING_FOR_PLAYLIST state handler. * * @param[in] pDownloadHelper - Reference to * PlaylistDownloadHelper * @return * HTTPDL_WAITING - In progress - check back later * HTTPDL_SUCCESS - GET response received * HTTPDL_ERROR_ABORT - Otherwise */ HTTPDownloadStatus PlaylistDownloadHelper::WaitingForPlaylistStateHandler::Execute ( PlaylistDownloadHelper* pDownloadHelper ) { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW, "PlaylistDownloadHelper::WaitingForPlaylistStateHandler::Execute()" ); HTTPDownloadStatus status = HTTPCommon::HTTPDL_ERROR_ABORT; PlaylistDownloadHelper* pSelf = pDownloadHelper; //Validity check if (pSelf) { HTTPStackInterface& HTTPStack = *(pSelf->m_pHTTPStack); //Check if GET response is received HTTPReturnCode result = HTTPStack.IsResponseReceived(pSelf->m_nRequestID); if (HTTP_SUCCESS == result) { uint32 nServerCode = 0; HTTPStack.GetResponseCode(pSelf->m_nRequestID, nServerCode); if (!(nServerCode >= 200 && nServerCode <= 206)) { result = HTTP_FAILURE; } } if (result == HTTP_WAIT || result == HTTP_SUCCESS) { //Could be WAIT or SUCCESS status = HTTPCommon::HTTPDL_WAITING; if (result == HTTP_SUCCESS) { //Get Representation length int representationLen = 0; (void)HTTPStack.GetContentLength(pSelf->m_nRequestID, (int64*)&representationLen); if (representationLen <= 0) { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "Error: Invalid content length using max length for representation" ); representationLen = MAX_REPRESENTATION_LEN; } //Playlist response received if (pSelf->m_RepresentationBuffer) { QTV_Free(pSelf->m_RepresentationBuffer); pSelf->m_RepresentationBuffer = NULL; pSelf->m_nRepresentationLen = 0; } pSelf->m_nRepresentationLen = representationLen + 1; pSelf->m_RepresentationBuffer = (char*)QTV_Malloc(pSelf->m_nRepresentationLen); if(pSelf->m_RepresentationBuffer) { std_memset(pSelf->m_RepresentationBuffer,0x0,pSelf->m_nRepresentationLen); pSelf->m_nRepresentationBytesRead=0; pSelf->SetStateHandler(&pSelf->m_PlaylistReadyStateHandler); QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_MEDIUM, "PLAYLIST_READY - moving on to reading data" ); } else { status = HTTPCommon::HTTPDL_OUT_OF_MEMORY; } }// if (result == HTTP_SUCCESS) else if( result == HTTP_WAIT ) { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_MEDIUM, "Waiting for GET response" ); } }// if (result == HTTP_WAIT || result == HTTP_SUCCESS) else { status = HTTPCommon::HTTPDL_ERROR_ABORT; } }// if (pSelf && pSelf->GetState() == WAITING_FOR_PLAYLIST) return status; }
/** @brief IDLE state handler. * * @param[in] pDownloadHelper - Reference to PlaylistDownloadHelper * @return * HTTPDL_WAITING - Successfully initiated connection and GET request posted * to the HTTP stack * HTTPDL_ERROR_ABORT - Otherwise */ HTTPDownloadStatus PlaylistDownloadHelper::IdleStateHandler::Execute ( PlaylistDownloadHelper* pDownloadHelper ) { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW, "PlaylistDownloadHelper::IdleStateHandler::Execute()" ); HTTPDownloadStatus status = HTTPCommon::HTTPDL_ERROR_ABORT; PlaylistDownloadHelper* pSelf = pDownloadHelper; //Validity check if (pSelf) { char* pLaunchURL = pSelf->m_pLaunchURL; //Fill in default port if port already not present in URL if (pSelf->ParseURL(HTTP_DEFAULT_PORT, pLaunchURL) && pLaunchURL) { HTTPMethodType methodType = HTTP_GET; status = HTTPCommon::HTTPDL_SUCCESS; pSelf->m_pLaunchURL = pLaunchURL; HTTPStackInterface& HTTPStack = *(pSelf->m_pHTTPStack); if(HTTPStack.CreateRequest(pSelf->m_nRequestID) == HTTP_SUCCESS) { URL url = pSelf->GetURL(); char hostName[HTTP_MAX_HOSTNAME_LEN] = {0}; if (url.GetHost(hostName, sizeof(hostName)) == URL::URL_OK) { (void)HTTPStack.SetHeader(pSelf->m_nRequestID, "Host", (int)std_strlen("Host"), hostName, (int)std_strlen(hostName)); } const char* pUserAgent = (pSelf->m_sessionInfo).GetUserAgent(); if (pUserAgent) { (void)HTTPStack.SetHeader(pSelf->m_nRequestID, "User-Agent", (int)std_strlen("User-Agent"), pUserAgent, (int)std_strlen(pUserAgent)); } HTTPCommon::AddIPStreamProtocolHeaders(pSelf->m_sessionInfo,HTTPStack,methodType, pSelf->m_nRequestID); //Send GET to get the playlist HTTPReturnCode result = HTTPStack.SendRequest(pSelf->m_nRequestID, methodType, pLaunchURL, (int)std_strlen(pLaunchURL)); if (result == HTTP_SUCCESS) { //HTTP GET request successfully composed and posted to the HTTP stack. //So change state to WAITING_FOR_PLAYLIST and check back later status = HTTPCommon::HTTPDL_WAITING; pSelf->SetStateHandler(&pSelf->m_WaitingForPlaylistStateHandler); QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_HIGH, "HTTP GET request to get playlist successfully composed and posted " "to HTTP stack - proceeding to WAITING_FOR_PLAYLIST" ); } else { QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "Error: HTTP GET request send failed %d", result ); status = HTTPCommon::HTTPDL_ERROR_ABORT; } } else { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "Error Creating Request"); } } else { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "Error: ParseURL failed" ); }// if (pSelf->ParseURL(HTTP_DEFAULT_PORT, pLaunchURL) && pLaunchURL) }// if (pSelf && pSelf->GetState() == IDLE) return status; }
/** @brief Parses the input URL and fills in the default port if port already * not present. * * @param[in] pDefaultPort - Default HTTP port to use if port not present in URL * @param[out] pLaunchURL - Launch URL used to connect to server * @return * TRUE - Launch URL ready * FALSE - Otherwise */ bool PlaylistDownloadHelper::ParseURL ( const char* pDefaultPort, char*& pLaunchURL ) { bool bOk = false; URL url(GetURL()); size_t launchURLLen = url.GetUrlLength() + 1; uint32 port = 0; if (pLaunchURL) { QTV_Free(pLaunchURL); pLaunchURL = NULL; } if (url.GetPort(&port) == URL::URL_OK) { if (port) { pLaunchURL = (char*)QTV_Malloc(launchURLLen); if (pLaunchURL && url.GetUrlBuffer()) { bOk = true; (void)std_strlcpy(pLaunchURL, url.GetUrlBuffer(), launchURLLen); } } else if (pDefaultPort) { char hostName[HTTP_MAX_HOSTNAME_LEN] = {0}; //Extra space for ":9300" launchURLLen += std_strlen(pDefaultPort) + 1; pLaunchURL = (char*)QTV_Malloc(launchURLLen); if (pLaunchURL && url.GetHost(hostName, sizeof(hostName)) == URL::URL_OK) { //Write http:// size_t arg2 = std_strlen("http://") + 1; size_t dstBufLen = STD_MIN(launchURLLen, arg2); size_t numURLBytes = std_strlcpy(pLaunchURL, "http://", dstBufLen); //Write hostname arg2 = std_strlen(hostName) + 1; dstBufLen = STD_MIN(launchURLLen - numURLBytes, arg2); numURLBytes += std_strlcpy(pLaunchURL + numURLBytes, hostName, dstBufLen); //Write : arg2 = std_strlen(":") + 1; dstBufLen = STD_MIN(launchURLLen - numURLBytes, arg2); numURLBytes += std_strlcpy(pLaunchURL + numURLBytes, ":", dstBufLen); //Write default port arg2 = std_strlen(pDefaultPort) + 1; dstBufLen = STD_MIN(launchURLLen - numURLBytes, arg2); numURLBytes += std_strlcpy(pLaunchURL + numURLBytes, pDefaultPort, dstBufLen); //Write / arg2 = std_strlen("/") + 1; dstBufLen = STD_MIN(launchURLLen - numURLBytes, arg2); numURLBytes += std_strlcpy(pLaunchURL + numURLBytes, "/", dstBufLen); //Write clipname dstBufLen = launchURLLen - numURLBytes; char* pClipName = NULL; pClipName = (char*)QTV_Malloc(dstBufLen); if (pClipName) { if (url.GetClipName(pClipName, dstBufLen) == URL::URL_OK) { bOk = true; (void)std_strlcpy(pLaunchURL + numURLBytes, pClipName, dstBufLen); } QTV_Free(pClipName); } } } else { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "Error: Invalid port" ); } } if(!bOk) { if(pLaunchURL) { QTV_Free(pLaunchURL); } } return bOk; }
/** @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" ); } }
/** @brief Process HTTP event notification from HTTP controller. * * @param[in] HTTPCommand - HTTP controller command * @param[in] HTTPStatus - Command execution status * @param[in] pCbData - Reference to the registered MMI callback iface */ void HTTPSourceMMIHelper::NotifyHTTPEvent ( const HTTPControllerCommand HTTPCommand, const HTTPDownloadStatus HTTPStatus, void* pCbData ) { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW, "HTTPSourceMMIHelper::NotifyHTTPEvent" ); //Convert HTTP event/status to MMI event/status switch (HTTPCommand) { case HTTPCommon::OPEN: ProcessOpenStatus(HTTPStatus, pCbData); break; case HTTPCommon::CLOSE: ProcessCloseStatus(HTTPStatus, pCbData); break; case HTTPCommon::START: ProcessStartStatus(HTTPStatus, pCbData); break; case HTTPCommon::STOP: ProcessGenericCmdStatus(HTTPStatus, pCbData); break; case HTTPCommon::PLAY: ProcessPlayStatus(HTTPStatus, pCbData); break; case HTTPCommon::PAUSE: ProcessPauseStatus(HTTPStatus, pCbData); break; case HTTPCommon::DOWNLOAD: ProcessDownloadStatus(HTTPStatus, pCbData); break; case HTTPCommon::SEEK: ProcessSeekStatus(HTTPStatus, pCbData); break; case HTTPCommon::GET_TRACKS: ProcessGetTracksStatus(HTTPStatus, pCbData); break; case HTTPCommon::SET_TRACK_STATE: ProcessSetTrackStateStatus(HTTPStatus, pCbData); break; case HTTPCommon::WAIT_FOR_RESOURCES: ProcessWaitForResourcesStatus(HTTPStatus, pCbData); break; case HTTPCommon::NOTIFY_CURRENT_WATERMARK_STATUS: ProcessNotifyWatermarkEventStatus(HTTPStatus, pCbData); break; case HTTPCommon::SELECT_REPRESENTATIONS: ProcessSelectRepresentationsStatus(HTTPStatus, pCbData); break; default: //Ignore other events break; } }
/** @brief IDLE state handler. * * @param[in] pHttpResolver - Reference to HTTPResolver * @return * HTTPDL_WAITING - Successfully posted GET request to the HTTP stack * HTTPDL_ERROR_ABORT - Error */ HTTPDownloadStatus HTTPResolver::IdleStateHandler::Execute ( HTTPResolver* pHttpResolver ) { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW, "HTTPResolver::IdleStateHandler::Execute()" ); HTTPDownloadStatus status = HTTPCommon::HTTPDL_ERROR_ABORT; HTTPResolver* pSelf = static_cast<HTTPResolver *> (pHttpResolver); //Validity check if (pSelf) { HTTPSessionInfo& sessionInfo = pSelf->m_sessionInfo; URL url = sessionInfo.GetURL(); char* pLaunchURL = pSelf->m_pLaunchURL; HTTPMethodType methodType = HTTP_GET; //Prepare launch URL if (HTTPCommon::ParseURL(url, HTTP_DEFAULT_PORT, pLaunchURL) && pLaunchURL) { pSelf->m_pLaunchURL = pLaunchURL; HTTPStackInterface& HTTPStack = pSelf->m_pHTTPStack; if(HTTPStack.CreateRequest(pSelf->m_nRequestID) == HTTP_SUCCESS ) { //Add HTTP headers char hostName[HTTP_MAX_HOSTNAME_LEN] = {0}; if (url.GetHost(hostName, sizeof(hostName)) == URL::URL_OK) { (void)HTTPStack.SetHeader(pSelf->m_nRequestID, "Host", (int)std_strlen("Host"), hostName, (int)std_strlen(hostName)); } char range[HTTP_MAX_RANGE_LEN] = {0}; if (pSelf->m_nMaxRequestSize >= 0) { (void)std_strlprintf(range, sizeof(range), "bytes=%d-%d", 0, (int)pSelf->m_nMaxRequestSize); } else { (void)std_strlprintf(range, sizeof(range), "bytes=%d-", 0); } (void)HTTPStack.SetHeader(pSelf->m_nRequestID, "Range", (int)std_strlen("Range"), range, (int)std_strlen(range)); const char* pUserAgent = sessionInfo.GetUserAgent(); if (pUserAgent) { (void)HTTPStack.SetHeader(pSelf->m_nRequestID, "User-Agent", (int)std_strlen("User-Agent"), pUserAgent, (int)std_strlen(pUserAgent)); } //Add any OEM headers HTTPCommon::AddIPStreamProtocolHeaders(sessionInfo, HTTPStack, methodType, pSelf->m_nRequestID); //Send HTTP GET request QTV_MSG_SPRINTF_PRIO_2( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_HIGH, "HTTPResolver::IdleStateHandler: Posting GET %s for %s", range, pLaunchURL ); HTTPReturnCode result = HTTPStack.SendRequest(pSelf->m_nRequestID, methodType, pLaunchURL, (int)std_strlen(pLaunchURL)); if (result == HTTP_SUCCESS) { //HTTP GET request successfully composed and posted to the HTTP stack, //move to WAIT_FOR_DATA status = HTTPCommon::HTTPDL_WAITING; pSelf->SetStateHandler(&pSelf->m_WaitForDataStateHandler); QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_MEDIUM, "HTTPResolver::IdleStateHandler: HTTP GET request successfully " "composed and posted to HTTP stack - moving to WAIT_FOR_DATA" ); } else { QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "HTTPResolver::IdleStateHandler: Posting HTTP GET failed %d", result ); } } else { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "Error Creating Request"); } }// if (HTTPCommon::ParseURL()) }// if (pSelf) return status; }
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; }
/** @brief Waiting for data state handler. * * @param[in] pHttpResolver - Reference to HTTPResolver * @return * HTTPDL_WAITING - Successfully posted GET request to the HTTP stack * HTTPDL_SUCCESS - Received GET response * HTTPDL_ERROR_ABORT - Otherwise */ HTTPDownloadStatus HTTPResolver::WaitForDataStateHandler::Execute ( HTTPResolver* pHttpResolver ) { QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW, "HTTPResolver::WaitForDataStateHandler::Execute()" ); HTTPDownloadStatus status = HTTPCommon::HTTPDL_ERROR_ABORT; HTTPResolver* pSelf = static_cast<HTTPResolver *> (pHttpResolver); //Validity check if (pSelf) { HTTPStackInterface& HTTPStack = pSelf->m_pHTTPStack; //Check if GET response is received HTTPReturnCode result = HTTPStack.IsResponseReceived(pSelf->m_nRequestID); if (HTTP_SUCCESS == result) { uint32 nVal = 0; HTTPStack.GetResponseCode(pSelf->m_nRequestID, nVal); if (!(nVal >= 200 && nVal <= 206)) { result = HTTP_FAILURE; } } if (result == HTTP_WAIT || result == HTTP_SUCCESS) { //Could be WAIT or SUCCESS if (result == HTTP_SUCCESS) { status = HTTPCommon::HTTPDL_SUCCESS; int64 contentLength = -1; char* pContentType = NULL; (void)HTTPCommon::GetContentLengthAndType(pSelf->m_nRequestID, HTTPStack, contentLength, pContentType); if (pContentType) { pSelf->SetContentType(pContentType); QTV_Free(pContentType); pSelf->SetStateHandler(&pSelf->m_IdleStateHandler); } } else { status = HTTPCommon::HTTPDL_WAITING; QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW, "HTTPResolver::WaitForDataStateHandler: Waiting for GET response" ); } } else { QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR, "HTTPResolver::WaitForDataStateHandler: GET failed %d...closing connection", result ); pSelf->SetStateHandler(&pSelf->m_IdleStateHandler); }//if (result == HTTP_WAIT || result == HTTP_SUCCESS) }// if (pSelf) return status; }
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; }
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 }
void core_msg_func(void *cookie, unsigned msgid, void *data, unsigned length) { QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"vdec: core_msg_func()\n"); }
/** * @brief * Select audio tracks. * Preferrance order: * 1. AAC * 2. Other audio codec * 3. EVRC, GSM, QCELP * 4. high bitrate codec * * @param trackList */ void DefaultTrackSelectionPolicy::SelectAudioTracks(ITrackList& trackList) { int aacIdx = -1; int someAudioCodecTrackIdx = -1; int evrcOrGsmIdx = -1; int highRateCodecIndex = -1; int rejectedAACTrackIndex = -1; int numTracks = trackList.GetNumTracksAvailable(); for (int i = 0; i < (int) numTracks; i++) { StreamMediaHelper::CodecType codecType = trackList.GetCodecType(i); if (false == StreamMediaHelper::IsAudioCodec(codecType)) { continue; } //Check whether player can play this track. if (!trackList.IsPlayable(i)) { if (codecType == StreamMediaHelper::AAC_CODEC ) { rejectedAACTrackIndex = i; } continue; } if ((m_selectionCriteria == PERFORMANCE_BASED_STREAMING_CODEC_CRITERIA) || (m_selectionCriteria == DEFAULT_CRITERIA) ) { switch (codecType) { case StreamMediaHelper::AAC_CODEC: if (aacIdx < 0) { aacIdx = i; } break; case StreamMediaHelper::GSM_AMR_CODEC: case StreamMediaHelper::EVRC_CODEC: case StreamMediaHelper::QCELP_CODEC: //Look for first GSM/EVRC track. if (evrcOrGsmIdx < 0) { //save this index but don't select the track yet, //since we still want to look for AAC. evrcOrGsmIdx = i; } break; // Disable audio if it's WMA on LTK, since the LTK doesn't // support it yet. case StreamMediaHelper::WMA_CODEC: case StreamMediaHelper::WMA_PRO_CODEC: case StreamMediaHelper::WMA_PRO_PLUS_CODEC: someAudioCodecTrackIdx = i; break; default: if (someAudioCodecTrackIdx < 0) { someAudioCodecTrackIdx = i; } break; } // end of switch (codecType) } else { QTV_MSG_PRIO(QTVDIAG_STREAMING, QTVDIAG_PRIO_MED, "Codec Selection based on BitRate"); int32 trackBitRate = 0; if (highRateCodecIndex == -1) { trackBitRate = trackList.GetBitrateBPS(i); highRateCodecIndex = i; } else { if (trackBitRate < trackList.GetBitrateBPS(i)) { highRateCodecIndex = i; } } } } ChoosePreferredAudioTrack(trackList, aacIdx, someAudioCodecTrackIdx, evrcOrGsmIdx, highRateCodecIndex, rejectedAACTrackIndex); return; }