void CCDataManager::Run() { //this is register for all ffmpeg action av_register_all(); //this is for mutli-thread ffmpeg working if(av_lockmgr_register(ffmpegLockManager)) { // TODO Failure av_lockmgr_register } CCSystemAlarm::GetInstance()->RegisterSystemAlarm(this); std::string mediaUrl; AVFormatContext *pAVFormatContext = NULL; int asIndex = -1; int vsIndex = -1; DataManagerStatus status = DATA_MANAGER_STATUS_ENUM_INIT; unsigned int decodersStatus = DECODERS_STATUS_ENUM_NONE_READY; int audioPacketQueueSize = 0; int videoPacketQueueSize = 0; while(m_bRunning) { SmartPtr<Event> event; if(PopFrontMessage(event)) { //std::cout << "event.GetPtr()->type=" << event.GetPtr()->type << std::endl; switch(event.GetPtr()->type) { case MESSAGE_TYPE_ENUM_OPEN_FILE: { mediaUrl = any_cast<std::string>(event.GetPtr()->anyParams); //AVCodecContext* pAudioCtx = NULL; //AVCodecContext* pVideoCtx = NULL; int ret = OpenFile(mediaUrl, &pAVFormatContext, &asIndex, &vsIndex); if(ret == 0) if(ret == 0) { //GetCodecContext(pAVFormatContext, asIndex, &pAudioCtx); //GetCodecContext(pAVFormatContext, vsIndex, &pVideoCtx); //status = DATA_MANAGER_STATUS_ENUM_WORKING; } std::vector<Any> openedParams; openedParams.push_back(Any(ret)); openedParams.push_back(Any(pAVFormatContext)); openedParams.push_back(Any(asIndex)); openedParams.push_back(Any(vsIndex)); PostMessage(MESSAGE_OBJECT_ENUM_DATA_MANAGER, MESSAGE_OBJECT_ENUM_PLAYER, MESSAGE_TYPE_ENUM_OPENED_FILE, openedParams); } break; case MESSAGE_TYPE_ENUM_AUDIO_DECODER_READY: { decodersStatus += DECODERS_STATUS_ENUM_AUDIO_READY; if(decodersStatus == DECODERS_STATUS_ENUM_ALL_READY) { status = DATA_MANAGER_STATUS_ENUM_WORKING; } } break; case MESSAGE_TYPE_ENUM_VIDEO_DECODER_READY: { decodersStatus += DECODERS_STATUS_ENUM_VIDEO_READY; if(decodersStatus == DECODERS_STATUS_ENUM_ALL_READY) { status = DATA_MANAGER_STATUS_ENUM_WORKING; } } break; case MESSAGE_TYPE_ENUM_AUDIO_DEOCDER_A_PACKET: { //status = DATA_MANAGER_STATUS_ENUM_SLEEPING; //we decoded a audio packet audioPacketQueueSize --; } break; case MESSAGE_TYPE_ENUM_VIDEO_DECODER_A_PACKET: { //status = DATA_MANAGER_STATUS_ENUM_SLEEPING; //we decoded a video packet videoPacketQueueSize --; } break; case MESSAGE_TYPE_ENUM_CLIENT_STOP: { status = DATA_MANAGER_STATUS_ENUM_DEADED; } break; default: std::cout << "Unknow Data Manager Message" << std::endl; break; } } switch(status) { case DATA_MANAGER_STATUS_ENUM_INIT: { } break; case DATA_MANAGER_STATUS_ENUM_WORKING: { if(audioPacketQueueSize < MAX_AUDIO_PACKET_QUEUE_SIZE || videoPacketQueueSize < MAX_VIDEO_PACKET_QUEUE_SIZE) { SmartPtr<CCPacket> packet(new CCPacket()); if(av_read_frame(pAVFormatContext, packet.GetPtr()->GetPacketPointer()) < 0) { PostMessage(MESSAGE_OBJECT_ENUM_DATA_MANAGER, MESSAGE_OBJECT_ENUM_AUDIO_DECODER, MESSAGE_TYPE_ENUM_DATA_MANAGER_EOF, Any()); PostMessage(MESSAGE_OBJECT_ENUM_DATA_MANAGER, MESSAGE_OBJECT_ENUM_VIDEO_DECODER, MESSAGE_TYPE_ENUM_DATA_MANAGER_EOF, Any()); //std::cout << "endend==========================================endend" << std::endl; m_bRunning = false; continue; } //CCFrequencyWorker::Wait(); //Sleep(2); if(packet.GetPtr()->GetPacketPointer()->stream_index == asIndex) { PostMessage(MESSAGE_OBJECT_ENUM_DATA_MANAGER, MESSAGE_OBJECT_ENUM_AUDIO_DECODER, MESSAGE_TYPE_ENUM_GET_AUDIO_PACKET, Any(packet)); //we got a audio packet audioPacketQueueSize ++; }else if(packet.GetPtr()->GetPacketPointer()->stream_index == vsIndex) { PostMessage(MESSAGE_OBJECT_ENUM_DATA_MANAGER, MESSAGE_OBJECT_ENUM_VIDEO_DECODER, MESSAGE_TYPE_ENUM_GET_VIDEO_PACKET, Any(packet)); //we got a video packet videoPacketQueueSize ++; } }// if audio packet enough or video packet enough else { Sleep(10); } } break; case DATA_MANAGER_STATUS_ENUM_SLEEPING: { Sleep(50); //after we have a reset , we should working //status = DATA_MANAGER_STATUS_ENUM_WORKING; } break; case DATA_MANAGER_STATUS_ENUM_DEADING: { } break; case DATA_MANAGER_STATUS_ENUM_DEADED: { m_bRunning = false; continue; } break; } // end switch } CCSystemAlarm::GetInstance()->UnRegisterSystemAlarm(this); }
void CCPlayer::Run() { int isAllModuleAreDeaded = 0; while(m_bRunning) { SmartPtr<Event> event; if(PopFrontMessage(event)) { switch(event.GetPtr()->type) { case COMMAND_TYPE_ENUM_OPEN: { sleep(5); std::string mediaUrl = any_cast<std::string>(event.GetPtr()->anyParams); int ret = OpenFile(mediaUrl); if (ret == SUCCESS) { CCModuleManager::AddModule(MESSAGE_OBJECT_ENUM_DATA_MANAGER); } if(ret == SUCCESS && g_pPlayerContext->m_asIndex != -1) { CCModuleManager::AddModule(MESSAGE_OBJECT_ENUM_AUDIO_DECODER); CCModuleManager::AddModule(MESSAGE_OBJECT_ENUM_AUDIO_RENDER); } if(ret == SUCCESS && g_pPlayerContext->m_vsIndex != -1) { CCModuleManager::AddModule(MESSAGE_OBJECT_ENUM_VIDEO_DECODER); CCModuleManager::AddModule(MESSAGE_OBJECT_ENUM_VIDEO_RENDER); } if(m_pIPlayerDelegate != NULL) { m_pIPlayerDelegate->OnCommandOpen(ret); } } break; case COMMAND_TYPE_ENUM_CONTINUE: { CCMessageCenter::GetInstance()->PostMessage(MESSAGE_OBJECT_ENUM_PLAYER, MESSAGE_OBJECT_ENUM_AUDIO_RENDER, MESSAGE_TYPE_ENUM_AUDIO_CONTINUE, Any()); CCMessageCenter::GetInstance()->PostMessage(MESSAGE_OBJECT_ENUM_PLAYER, MESSAGE_OBJECT_ENUM_VIDEO_RENDER, MESSAGE_TYPE_ENUM_VIDEO_CONTINUE, Any()); } break; case COMMAND_TYPE_ENUM_PAUSE: { CCMessageCenter::GetInstance()->PostMessage(MESSAGE_OBJECT_ENUM_PLAYER, MESSAGE_OBJECT_ENUM_AUDIO_RENDER, MESSAGE_TYPE_ENUM_AUDIO_PAUSE, Any()); CCMessageCenter::GetInstance()->PostMessage(MESSAGE_OBJECT_ENUM_PLAYER, MESSAGE_OBJECT_ENUM_VIDEO_RENDER, MESSAGE_TYPE_ENUM_VIDEO_PAUSE, Any()); } break; //the user stop the player case COMMAND_TYPE_ENUM_STOP: { PostMessage(MESSAGE_OBJECT_ENUM_PLAYER, MESSAGE_OJBECT_ENUM_ALL, MESSAGE_TYPE_ENUM_CLIENT_STOP, Any()); } break; case MESSAGE_TYPE_ENUM_SET_VOLUME: { float volume = any_cast<float>(event.GetPtr()->anyParams); g_pPlayerContext->m_pALWrapper->SetVolume(volume); } break; case MESSAGE_TYPE_ENUM_AUDIO_RENDER_DEADED: { CCModuleManager::DeleteModule(MESSAGE_OBJECT_ENUM_AUDIO_RENDER); isAllModuleAreDeaded += AUDIO_RENDER_DEADED; if (isAllModuleAreDeaded == ALL_MODULE_ARE_DEADED) { DestructPlayerSystem(); } } break; case MESSAGE_TYPE_ENUM_AUDIO_DECODER_DEADED: { CCModuleManager::DeleteModule(MESSAGE_OBJECT_ENUM_AUDIO_DECODER); isAllModuleAreDeaded += AUDIO_DECODER_DEADED; if (isAllModuleAreDeaded == ALL_MODULE_ARE_DEADED) { DestructPlayerSystem(); } } break; case MESSAGE_TYPE_ENUM_VIDEO_RENDER_DEADED: { CCModuleManager::DeleteModule(MESSAGE_OBJECT_ENUM_VIDEO_RENDER); isAllModuleAreDeaded += VIDEO_RENDER_DEADED; if (isAllModuleAreDeaded == ALL_MODULE_ARE_DEADED) { DestructPlayerSystem(); } } break; case MESSAGE_TYPE_ENUM_VIDEO_DECODER_DEADED: { CCModuleManager::DeleteModule(MESSAGE_OBJECT_ENUM_VIDEO_DECODER); isAllModuleAreDeaded += VIDEO_DECODER_DEADED; if (isAllModuleAreDeaded == ALL_MODULE_ARE_DEADED) { DestructPlayerSystem(); } } break; case MESSAGE_OBJECT_ENUM_DATA_MANAGER_DEADED: { CCModuleManager::DeleteModule(MESSAGE_OBJECT_ENUM_DATA_MANAGER); isAllModuleAreDeaded += DATA_MANAGER_DEADED; if (isAllModuleAreDeaded == ALL_MODULE_ARE_DEADED) { DestructPlayerSystem(); } } break; } }else // end if get a message { //if nothing to do , just wait 10 ms , don't warry usleep(10 * 1000); } } // end of switch case }
void CCAudioRender::Run() { AudioRenderStatus status = AUDIO_RENDER_STATUS_ENUM_INITTED; bool bDataManagerEof = false; // ALenum audFormat = GetAudioFormat(g_pPlayerContext->m_channels, g_pPlayerContext->m_type); g_pPlayerContext->m_pALWrapper->SetAudioCtx(g_pPlayerContext->m_channels, g_pPlayerContext->m_rates, g_pPlayerContext->m_audFormat); while(m_bRunning) { SmartPtr<Event> event; if(PopFrontMessage(event)) { switch(event.GetPtr()->type) { case MESSAGE_TYPE_ENUM_SET_VOLUME: { float volume = any_cast<float>(event.GetPtr()->anyParams); g_pPlayerContext->m_pALWrapper->SetVolume(volume); } break; case MESSAGE_TYPE_ENUM_DATA_MANAGER_EOF: { bDataManagerEof = true; } break; case MESSAGE_TYPE_ENUM_AUDIO_PAUSE: { status = AUDIO_RENDER_STATUS_ENUM_SLEEPING; } break; case MESSAGE_TYPE_ENUM_AUDIO_CONTINUE: { status = AUDIO_RENDER_STATUS_ENUM_UPDATING; } break; case MESSAGE_TYPE_ENUM_CLIENT_STOP: { status = AUDIO_RENDER_STATUS_ENUM_DEADED; } } // end switch case } // end if get a message switch(status) { case AUDIO_RENDER_STATUS_ENUM_UNKNOW: { //do nothing at all } break; case AUDIO_RENDER_STATUS_ENUM_INITTED: { if(g_pPlayerContext->m_audioFrameQueue.size() >= AUDIO_BUFFER_NUMBER) { std::cout << "Init the audio buffers" << std::endl; for(int i=0; i<AUDIO_BUFFER_NUMBER;i++) { SmartPtr<AudioFrame> shrdAudioFrame = g_pPlayerContext->m_audioFrameQueue.front(); g_pPlayerContext->m_audioFrameQueue.pop(); g_pPlayerContext->m_pALWrapper->InitAudioFrame(shrdAudioFrame.GetPtr(), i); } g_pPlayerContext->m_pALWrapper->Play(); //usleep(30 * 1000); CCSystemClock::GetInstance()->SetVideoStartRender(true); status = AUDIO_RENDER_STATUS_ENUM_UPDATING; } } // case AUDIO_RENDER_STATUS_ENUM_INITTED break; case AUDIO_RENDER_STATUS_ENUM_UPDATING: { CCSystemClock::GetInstance()->SetRealPlayedTime(g_pPlayerContext->m_pALWrapper->GetReadPlayedTime()); usleep(20 * 1000); //std::cout << "audio frame empty()" << m_audioFrameQueue.empty()<< std::endl; if(g_pPlayerContext->m_pALWrapper->NeedData() && !g_pPlayerContext->m_audioFrameQueue.empty()) { //std::cout << "audio render data" << std::endl; SmartPtr<AudioFrame> shrdAudioFrame = g_pPlayerContext->m_audioFrameQueue.front(); g_pPlayerContext->m_audioFrameQueue.pop(); g_pPlayerContext->m_pALWrapper->UpdateAudioFrame(shrdAudioFrame.GetPtr()); PostMessage(MESSAGE_OBJECT_ENUM_AUDIO_RENDER, MESSAGE_OBJECT_ENUM_AUDIO_DECODER, MESSAGE_TYPE_ENUM_AUDIO_RENDER_A_FRAME, Any()); }else if(bDataManagerEof) { status = AUDIO_RENDER_STATUS_ENUM_DEADED; } g_pPlayerContext->m_pALWrapper->Play(); } //end case AUDIO_RENDER_STATUS_ENUM_UPDATING break; case AUDIO_RENDER_STATUS_ENUM_SLEEPING: { usleep(100 * 1000); //Sleep(100); } break; case AUDIO_REDNER_STATUS_ENUM_DEADING: { m_bRunning = false; continue; } break; case AUDIO_RENDER_STATUS_ENUM_DEADED: { PostMessage(MESSAGE_OBJECT_ENUM_AUDIO_RENDER, MESSAGE_OBJECT_ENUM_PLAYER, MESSAGE_TYPE_ENUM_AUDIO_RENDER_DEADED, Any()); m_bRunning = false; continue; } break; } // end switch(status) } std::cout << "The audio render is deaded" << std::endl; }
void CCAudioDecoder::Run() { AudioDecoderStatus status = AUDIO_DECODER_STATUS_ENUM_UNKNOW; AVFormatContext* pAVFormatCtx = NULL; AVCodecContext* pAudioCodecCtx = NULL; AVRational audioTimeBase; AVFrame* pDecodedFrame = NULL; int gotFrame = 0; int decodedLen = 0; int audioFrameQueueSize = 0; bool bDataManagerEof = false; while(m_bRunning) { SmartPtr<Event> event; if(PopFrontMessage(event)) { switch(event.GetPtr()->type) { case MESSAGE_TYPE_ENUM_FINDED_AUDIO_STREAM: { CCChannels channels = -1; CCRates rates = -1 ; CCType type = CCType::unknow; int asIndex = -1; std::vector<Any> audioStreamInfo = any_cast<std::vector<Any> >(event.GetPtr()->anyParams); pAVFormatCtx = any_cast<AVFormatContext*>(audioStreamInfo[0]); asIndex = any_cast<int>(audioStreamInfo[1]); GetCodecContext(pAVFormatCtx, asIndex, &pAudioCodecCtx, &audioTimeBase); int ret = GetAudioInformation(pAudioCodecCtx, &channels, &rates, &type); if(ret == 0) { std::vector<Any> audioInformartion; audioInformartion.push_back(Any(channels)); audioInformartion.push_back(Any(rates)); audioInformartion.push_back(Any(type)); PostMessage(MESSAGE_OBJECT_ENUM_AUDIO_DECODER, MESSAGE_OBJECT_ENUM_AUDIO_RENDER, MESSAGE_TYPE_ENUM_GET_AUDIO_INFORMATION, Any(audioInformartion)); //crate the frame buffer size pDecodedFrame = avcodec_alloc_frame(); PostMessage(MESSAGE_OBJECT_ENUM_AUDIO_DECODER, MESSAGE_OBJECT_ENUM_DATA_MANAGER, MESSAGE_TYPE_ENUM_AUDIO_DECODER_READY, Any()); //turn the audio decoder status to working status = AUDIO_DECODER_STATUS_ENUM_WORKING; } } break; case MESSAGE_TYPE_ENUM_GET_AUDIO_PACKET: { SmartPtr<CCPacket> shdPacket = any_cast<SmartPtr<CCPacket> >(event.GetPtr()->anyParams); m_audioPacketQueue.push(shdPacket); } break; case MESSAGE_TYPE_ENUM_AUDIO_RENDER_A_FRAME: { //status = AUDIO_DECODER_STATUS_ENUM_SLEEPING; //update audioFrameQueueSize --; } break; case MESSAGE_TYPE_ENUM_DATA_MANAGER_EOF: { bDataManagerEof = true; } break; case MESSAGE_TYPE_ENUM_CLIENT_STOP: { status = AUDIO_DECODER_STATUS_ENUM_DEADED; } break; } // end switch case }// end if get a message //working in somethings switch(status) { case AUDIO_DECODER_STATUS_ENUM_WORKING: { //std::cout << "Audio Decoder are working" << std::endl; if(audioFrameQueueSize < MAX_AUDIO_FRAME_QUEUE_SIZE) { if(!m_audioPacketQueue.empty()) { //static int count = 0; //std::cout << "decoder a audio packet" << ++count << std::endl; SmartPtr<CCPacket> shdPacket = m_audioPacketQueue.front(); m_audioPacketQueue.pop(); AVPacket packet = shdPacket.GetPtr()->GetPacket(); while(packet.size > 0) { avcodec_get_frame_defaults(pDecodedFrame); decodedLen = avcodec_decode_audio4(pAudioCodecCtx, pDecodedFrame, &gotFrame, &packet); packet.data += decodedLen; packet.size -= decodedLen; if(gotFrame) { //std::cout << "Get a frame" << std::endl; //count = 0; //increment the queue size count audioFrameQueueSize ++; int decodedDataSize = av_samples_get_buffer_size(NULL, pAudioCodecCtx->channels, pDecodedFrame->nb_samples, pAudioCodecCtx->sample_fmt, 1); SmartPtr<AudioFrame> audioFrame(new AudioFrame(pDecodedFrame->data[0], decodedDataSize)); PostMessage(MESSAGE_OBJECT_ENUM_AUDIO_DECODER, MESSAGE_OBJECT_ENUM_AUDIO_RENDER, MESSAGE_TYPE_ENUM_GET_AUDIO_FRAME, Any(audioFrame)); } }// end while decoder packet //tell the datamanager we have decoded a packet PostMessage(MESSAGE_OBJECT_ENUM_AUDIO_DECODER, MESSAGE_OBJECT_ENUM_DATA_MANAGER, MESSAGE_TYPE_ENUM_AUDIO_DEOCDER_A_PACKET, Any()); }// end the packet queue is not empty }// end not enough audio frame else if(bDataManagerEof)//there is no data for data manager { PostMessage(MESSAGE_OBJECT_ENUM_AUDIO_DECODER, MESSAGE_OBJECT_ENUM_AUDIO_RENDER, MESSAGE_TYPE_ENUM_DATA_MANAGER_EOF, Any()); m_bRunning = false; continue; }else { Sleep(10); } } break; case AUDIO_DECODER_STATUS_ENUM_SLEEPING: { Sleep(50); } break; case AUDIO_DECODER_STATUS_ENUM_UNKNOW: { } break; case AUDIO_DECODER_STATUS_ENUM_DEADED: { m_bRunning = false; continue; } break; }// end switch case } std::cout << "The audio decoder is deaded" << std::endl; }