总体思路:在主函数中初始化SDL,读取文件,将数据交给线程Main,在线程Main中,通过while循环,以及用户设置的fps,根据fps的计算,读取数据进入View()函数中进行处理。
主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| SDLQtRGB::SDLQtRGB(QWidget *parent) : QWidget(parent) { ui.setupUi(this); yuv_file.open("400_300_25.yuv", std::ios::binary);
yuv_file.seekg(0, ios::end); file_size = yuv_file.tellg(); yuv_file.seekg(0, ios::beg);
connect(this, SIGNAL(ViewS()), this, SLOT(View()));
view_fps = new QLabel(this); view_fps->setText("fps: 100");
set_fps = new QSpinBox(this); set_fps->move(200, 0); set_fps->setValue(25); set_fps->setRange(1, 50);
sdl_width = 400; sdl_height = 300; this->resize(sdl_width, sdl_height); ui.label->resize(sdl_width, sdl_height); view = XVideoView::Create(); view->Init(sdl_width, sdl_height, XVideoView::YUV420P, (void*)ui.label->winId()); frame = av_frame_alloc(); frame->width = sdl_width; frame->height = sdl_height; frame->format = AV_PIX_FMT_YUV420P;
frame->linesize[0] = sdl_width; frame->linesize[1] = sdl_width / 2; frame->linesize[2] = sdl_width / 2;
auto re = av_frame_get_buffer(frame, 16);
if (re != 0) { char buf[1024] = { 0 }; av_strerror(re, buf, sizeof(buf)); std::cerr << buf << std::endl; }
th_ = std::thread(&SDLQtRGB::Main, this); }
|
AVFrame 介绍
线程Main
控制播放速度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| void SDLQtRGB::Main() { while (!is_exit_) { ViewS(); if (fps > 0) { MSleep(1000 / fps); } else MSleep(40); } }
void MSleep(unsigned int ms) { auto beg = clock(); for (int i = 0; i < ms; i++) { this_thread::sleep_for(1ms); if ((clock() - beg) / (CLOCKS_PER_SEC / 1000) >= ms) break; } }
|
View函数
YUV格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| void SDLQtRGB::View() { yuv_file.read((char*)frame->data[0], sdl_width * sdl_height); yuv_file.read((char*)frame->data[1], sdl_width * sdl_height / 4); yuv_file.read((char*)frame->data[2], sdl_width * sdl_height / 4);
if (yuv_file.tellg() == file_size) { yuv_file.seekg(0, ios::beg); }
if (view->IsExit()) { view->Close(); exit(0); }
view->DrawFrame(frame); stringstream ss; ss << "fps: " << view->render_fps();
view_fps->setText(ss.str().c_str()); fps = set_fps->value(); }
|