基础
ffmpeg使用设备先注册
avdevice_register_all();
使用常用得CCameraDS 取获取名称,这里使用第一个摄像头。这里我们使用SDL来渲染得时候,启动一个定时器来定时给一个事件让SDL来刷新
SDLSDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
所以使用video和timer来完成这种渲染。
渲染流程这里使用bgr24来渲染,使用sdl 创建表面,指定opengl来做 1 创建窗口 2 创建刷新线程 3 线程中发送更新事件 4 main主循环捕获事件,获取一帧rgb24,刷新界面渲染
这里面可以修改变成这样 刷新线程渲染获取一帧,推给主线程,主线程负责编码发送,同时渲染,这里是示例,没有这么做。
int main()
{
avdevice_register_all();
int w = 1280;
int h = 720;
g_fps = 10;
std::wstring cname;
CCameraDS::CameraName(0, cname);
std::string name = UnicodeToUTF8(cname);
TFFCap cap;
int ret = cap.OpenCameraRGB(name.c_str(), 1280, 720);
if (ret != 0)
return -1;
int screen_w, screen_h;
SDL_Window *screen;
SDL_Renderer *sdlRenderer;
SDL_Texture *sdlTexture;
SDL_Rect sdlRect;
SDL_Thread *video_tid;
SDL_Event event;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
screen_w = w; //w;
screen_h = h;
//screen_h = screen_w * 9 / 16;
screen = SDL_CreateWindow("FF", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screen_w, screen_h, SDL_WINDOW_OPENGL);
if (!screen)
{
std::cout codecpar->width;
//h = m_pFormatCtx->streams[i]->codecpar->height;
m_videoIndex = i;
break;
}
}
if (-1 == m_videoIndex)
{
return -1;
}
if(m_pCodecCtx == NULL)
m_pCodecCtx = avcodec_alloc_context3(NULL);
if (m_pCodecCtx == NULL)
{
return -1;
}
avcodec_parameters_to_context(m_pCodecCtx, m_pFormatCtx->streams[m_videoIndex]->codecpar);
m_pCodec = avcodec_find_decoder(m_pCodecCtx->codec_id);
if (m_pCodec == NULL)
{
//std::cout data,
m_pFrame->linesize, 0,
m_pCodecCtx->height,
m_pFrameDst->data, m_pFrameDst->linesize);
}
av_packet_unref(&packet);
}
}
//返回上一帧
if (got_picture)
return out_buffer;
return NULL;
}
void TFFCap::UnInit()
{
av_frame_free(&m_pFrameDst);
av_frame_free(&m_pFrame);
if(m_img_convert_ctx!= nullptr)
sws_freeContext(m_img_convert_ctx);
avcodec_close(m_pCodecCtx);
avcodec_free_context(&m_pCodecCtx);
avformat_close_input(&m_pFormatCtx);
}
效果
代码里面还有一些是可以修改得,仅仅作为示例,代表可行