av_dict_set(&opts, "rtsp_transport", "tcp", 0); //设置tcp or udp
av_dict_set(&opts, "stimeout", "3000000", 0); //设置超时3秒
avformat_find_stream_info(pFormatCtx, NULL)
int CGdiPlay::run()
{
hdcDes = GetDC(m_hWnd);
hdcSrc = CreateCompatibleDC(hdcDes);
packet = av_packet_alloc();
CalcVideoWH(m_hWnd);
::CoInitialize(NULL);
while (bStateFlag)
{
if (packet == NULL)
{
packet = av_packet_alloc();
av_usleep(20 * 1000);
continue;
}
if (av_read_frame(pFormatCtx, packet) >= 0)
{
if (packet->stream_index == vindex)
{
//下面处理size
GetClientRect(m_hWnd, &rc);
if (rc.left != screenRect.left || rc.right != screenRect.right || rc.top != screenRect.top || rc.bottom != screenRect.bottom)
CalcVideoWH(m_hWnd);
if (avcodec_send_packet(pCodecCtx, packet) == 0)
{
if (avcodec_receive_frame(pCodecCtx, pFrame) == 0)
{
sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrameRGB->data, pFrameRGB->linesize);
hBitmap = CreateDIBSection(hdcSrc, &bmpinfo, DIB_RGB_COLORS, &pbit, NULL, 0);
GetObject(hBitmap, sizeof(BITMAP), &bmp);
memcpy(pbit, out_bufRgb, (sW)* (sH) * 4);
SelectObject(hdcSrc, hBitmap);
BitBlt(hdcDes, 0, 0, sW, sH, hdcSrc, 0, 0, SRCCOPY);
DeleteObject(hBitmap);
av_usleep(40 * 1000);
}
else
continue;
}
else
break;
}
}
av_packet_unref(packet);
}
avformat_close_input(&pFormatCtx);
av_packet_unref(packet);
::CoUninitialize();
return 0;
}
int CGdiPlay::play(string filepath)
{
if (bStateFlag)
stop();
av_register_all();
pFormatCtx = avformat_alloc_context();
if (avformat_open_input(&pFormatCtx, filepath.c_str(), NULL, NULL) < 0)
return 0;
//很卡
//if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
// return 0;
for (int i = 0; i < (int)pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
vindex = i;
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
aindex = i;
}
pCodecCtx = avcodec_alloc_context3(NULL);
if (avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[vindex]->codecpar) < 0)
av_log(NULL, AV_LOG_ERROR, "video avcodec_parameters_to_context faild");
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL)
return 0;
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
return 0;
//解码线程开始
bStateFlag = true;
m_th = std::thread(std::bind(&CGdiPlay::run, this));
m_th.detach(); //线程后台运行
return 1;
}