void CplayerDlg::OnDestroy() { CDialog::OnDestroy(); ReleaseDC(m_pDrawDC); // close player if (g_hplayer) { playerclose(g_hplayer); g_hplayer = NULL; } }
void CplayerDlg::PlayerOpenFile(void) { CFileDialog dlg(TRUE); TCHAR path[MAX_PATH]; char str [MAX_PATH]; // kill player progress timer KillTimer(TIMER_ID_PROGRESS); // stop player first if (g_hplayer) { playerclose(g_hplayer); g_hplayer = NULL; } // open file dialog if (dlg.DoModal() == IDOK) { wcscpy_s(path, dlg.GetPathName()); WideCharToMultiByte(CP_ACP, 0, path, -1, str, MAX_PATH, NULL, NULL); } else { OnOK(); return; } // player open file g_hplayer = playeropen(str, GetSafeHwnd()); if (g_hplayer) { m_bPlayPause = FALSE; playersetrect(g_hplayer, 0, 0, m_rtClient.right, m_rtClient.bottom - 2); playerplay(g_hplayer); SetTimer(TIMER_ID_PROGRESS, 500, NULL); } }
// 函数实现 void* playeropen(char *file, void *extra) { PLAYER *player = NULL; AVCodec *decoder = NULL; int vformat = 0; int width = 0; int height = 0; uint64_t alayout = 0; int aformat = 0; int arate = 0; uint32_t i = 0; // init log // log_init(TEXT("DEBUGER")); // av register all av_register_all(); // alloc player context player = (PLAYER*)malloc(sizeof(PLAYER)); memset(player, 0, sizeof(PLAYER)); // create packet queue pktqueue_create(&(player->PacketQueue)); // open input file if (avformat_open_input(&(player->pAVFormatContext), file, NULL, 0) != 0) { goto error_handler; } // find stream info if (avformat_find_stream_info(player->pAVFormatContext, NULL) < 0) { goto error_handler; } // get video & audio codec context player->iAudioStreamIndex = -1; player->iVideoStreamIndex = -1; for (i=0; i<player->pAVFormatContext->nb_streams; i++) { switch (player->pAVFormatContext->streams[i]->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: player->iAudioStreamIndex = i; player->pAudioCodecContext = player->pAVFormatContext->streams[i]->codec; player->dAudioTimeBase = av_q2d(player->pAVFormatContext->streams[i]->time_base) * 1000; break; case AVMEDIA_TYPE_VIDEO: player->iVideoStreamIndex = i; player->pVideoCodecContext = player->pAVFormatContext->streams[i]->codec; player->dVideoTimeBase = av_q2d(player->pAVFormatContext->streams[i]->time_base) * 1000; player->tVideoFrameRate = player->pAVFormatContext->streams[i]->r_frame_rate; if (player->tVideoFrameRate.num / player->tVideoFrameRate.den > 100) { player->tVideoFrameRate.num = 30; player->tVideoFrameRate.den = 1; } break; } } // open audio codec if (player->iAudioStreamIndex != -1) { decoder = avcodec_find_decoder(player->pAudioCodecContext->codec_id); if (!decoder || avcodec_open(player->pAudioCodecContext, decoder, NULL) < 0) { log_printf(TEXT("failed to find or open decoder for audio !\n")); player->iAudioStreamIndex = -1; } } // open video codec if (player->iVideoStreamIndex != -1) { decoder = avcodec_find_decoder(player->pVideoCodecContext->codec_id); if (!decoder || avcodec_open(player->pVideoCodecContext, decoder, NULL) < 0) { log_printf(TEXT("failed to find or open decoder for video !\n")); player->iVideoStreamIndex = -1; } } // for video if (player->iVideoStreamIndex != -1) { vformat = player->pVideoCodecContext->pix_fmt; width = player->pVideoCodecContext->width; height = player->pVideoCodecContext->height; } // for audio if (player->iAudioStreamIndex != -1) { alayout = player->pAudioCodecContext->channel_layout; //++ fix audio channel layout issue if (alayout == 0) { alayout = av_get_default_channel_layout(player->pAudioCodecContext->channels); } //-- fix audio channel layout issue aformat = player->pAudioCodecContext->sample_fmt; arate = player->pAudioCodecContext->sample_rate; } // open core render player->hCoreRender = renderopen(extra, player->tVideoFrameRate, vformat, width, height, arate, (AVSampleFormat)aformat, alayout); // make sure player status paused player->nPlayerStatus = 0xf; pthread_create(&(player->hAVDemuxThread), NULL, AVDemuxThreadProc , player); pthread_create(&(player->hADecodeThread), NULL, AudioDecodeThreadProc, player); pthread_create(&(player->hVDecodeThread), NULL, VideoDecodeThreadProc, player); return player; error_handler: playerclose(player); return NULL; }