|
@@ -1,6 +1,7 @@
|
|
|
#include "mainwindow.h"
|
|
|
#include "ui_mainwindow.h"
|
|
|
|
|
|
+#include <QMessageBox>
|
|
|
#include <QInputDialog>
|
|
|
#include <iostream>
|
|
|
|
|
@@ -12,6 +13,9 @@ MainWindow::MainWindow(QWidget *parent) :
|
|
|
ui(new Ui::MainWindow)
|
|
|
{
|
|
|
ui->setupUi(this);
|
|
|
+
|
|
|
+ mstrrtspurl = ServiceRTSPViewIni.GetRTSPURL();
|
|
|
+
|
|
|
mprtspdown = new rtspclientdown(mstrrtspurl);
|
|
|
mph264decode = new ivh264framedecode(mnframewidth,mnframeheight,false);
|
|
|
|
|
@@ -27,6 +31,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
|
|
|
|
|
connect(this,SIGNAL(CamUpdate()),this,SLOT(onCamUpdate()));
|
|
|
|
|
|
+ setWindowTitle("RTSP View");
|
|
|
+
|
|
|
}
|
|
|
|
|
|
MainWindow::~MainWindow()
|
|
@@ -46,7 +52,9 @@ void MainWindow::on_actionSet_URL_triggered()
|
|
|
|
|
|
if(ok &!strurl.isEmpty())
|
|
|
{
|
|
|
-
|
|
|
+ mstrrtspurl = strurl.toStdString();
|
|
|
+ ServiceRTSPViewIni.SetRTSPURL(mstrrtspurl);
|
|
|
+ QMessageBox::information(this,tr("Info"),tr("Restart app, setting come into force."),QMessageBox::YesAll);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -65,9 +73,152 @@ void MainWindow::threadframe()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static float YUV2RGB10753[256], YUV2RGB15075[256];
|
|
|
+static float YUV2RGB03441[256], YUV2RGB06084[256];
|
|
|
+static float YUV2RGB17718[256], YUV2RGB01043[256];
|
|
|
+void InitLookupTable()
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ for (i = 0; i < 256; i++) YUV2RGB10753[i] = (float)1.0753 * i;
|
|
|
+ for (i = 0; i < 256; i++) YUV2RGB15075[i] = (float)1.5075 * (i - 128);
|
|
|
+ for (i = 0; i < 256; i++) YUV2RGB03441[i] = (float)0.3441 * (i - 128);
|
|
|
+ for (i = 0; i < 256; i++) YUV2RGB06084[i] = (float)0.6084 * (i - 128);
|
|
|
+ for (i = 0; i < 256; i++) YUV2RGB17718[i] = (float)1.7718 * (i - 128);
|
|
|
+ for (i = 0; i < 256; i++) YUV2RGB01043[i] = (float)0.1043 * (i - 128);
|
|
|
+}
|
|
|
+
|
|
|
+unsigned char* extendUV(unsigned char* buffer,int h,int w)
|
|
|
+{
|
|
|
+ unsigned char* buffer_extend = new unsigned char[h * w];
|
|
|
+ for (int i = 0; i < h; i++) {
|
|
|
+ for (int j = 0; j < w; j++) {
|
|
|
+ buffer_extend[i * w + j] = buffer[int(i/2)*(w/2) + int(j/2)];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return buffer_extend;
|
|
|
+}
|
|
|
+inline int limitValue(int value)
|
|
|
+{
|
|
|
+ return value > 255 ? 255:
|
|
|
+ (value < 0 ? 0 : value);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+inline unsigned char getR(unsigned char Y, unsigned char U, unsigned char V)
|
|
|
+{
|
|
|
+ (void)U;
|
|
|
+ double R = YUV2RGB10753[Y] + YUV2RGB15075[V];
|
|
|
+ return limitValue(R);
|
|
|
+}
|
|
|
+inline unsigned char getG(unsigned char Y, unsigned char U, unsigned char V)
|
|
|
+{
|
|
|
+ double G = YUV2RGB10753[Y] - YUV2RGB03441[U] - YUV2RGB06084[V];
|
|
|
+ return limitValue(G);
|
|
|
+}
|
|
|
+inline unsigned char getB(unsigned char Y, unsigned char U, unsigned char V)
|
|
|
+{
|
|
|
+ double B = YUV2RGB10753[Y] + YUV2RGB17718[U]+ YUV2RGB01043[V];
|
|
|
+ return limitValue(B);
|
|
|
+}
|
|
|
+
|
|
|
+void YUV2RGB(unsigned char* y_buffer,unsigned char* u_buffer, unsigned char* v_buffer,unsigned char * rgbdata,int width,int height)
|
|
|
+{
|
|
|
+ //初始化查找表
|
|
|
+ InitLookupTable();
|
|
|
+
|
|
|
+ //扩展U、V
|
|
|
+ unsigned char* u_buffer_extend = extendUV(u_buffer, height, width);
|
|
|
+ unsigned char* v_buffer_extend = extendUV(v_buffer, height, width);
|
|
|
+
|
|
|
+ //转化为RGB
|
|
|
+// unsigned char* r_buffer = rgbdata;
|
|
|
+// unsigned char* g_buffer = rgbdata + height * width;
|
|
|
+// unsigned char* b_buffer = rgbdata + 2 * height * width;
|
|
|
+ for (int i = 0; i < height * width; i++) {
|
|
|
+// r_buffer[i] = getR(y_buffer[i], u_buffer_extend[i], v_buffer_extend[i]);
|
|
|
+// g_buffer[i] = getG(y_buffer[i], u_buffer_extend[i], v_buffer_extend[i]);
|
|
|
+// b_buffer[i] = getB(y_buffer[i], u_buffer_extend[i], v_buffer_extend[i]);
|
|
|
+ rgbdata[i*3] = getR(y_buffer[i], u_buffer_extend[i], v_buffer_extend[i]);
|
|
|
+ rgbdata[i*3+1] = getG(y_buffer[i], u_buffer_extend[i], v_buffer_extend[i]);
|
|
|
+ rgbdata[i*3+2] = getB(y_buffer[i], u_buffer_extend[i], v_buffer_extend[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+#include<iostream>
|
|
|
+#include<fstream>
|
|
|
+using namespace std;
|
|
|
+
|
|
|
+
|
|
|
+// yuv为4:2:0格式,且图像宽高都为偶数
|
|
|
+void yuv2bgr(unsigned char * y,unsigned char* u,unsigned char* v, unsigned char * buffer_bgr,int width, int height)
|
|
|
+{
|
|
|
+ int i, k = 0;
|
|
|
+ int w = width;
|
|
|
+ int h = height;
|
|
|
+
|
|
|
+
|
|
|
+ unsigned char* temple_u = new unsigned char[w * h]; // 存储Y和虚假的UV
|
|
|
+ unsigned char* temple_v = new unsigned char[w * h];
|
|
|
+ int* temple_bgr = new int[w * h * 3]; // 由于unsigned char的取值范围,存储虚假的bgr数据
|
|
|
+
|
|
|
+ for (i = 0; i < w * h / 4; i++)
|
|
|
+ {
|
|
|
+ temple_u[k] = u[i]; // 将一个值赋给小正方形里面的四个值
|
|
|
+ temple_u[k + 1] = u[i];
|
|
|
+ temple_u[k + w] = u[i];
|
|
|
+ temple_u[k + 1 + w] = u[i];
|
|
|
+ temple_v[k] = v[i];
|
|
|
+ temple_v[k + 1] = v[i];
|
|
|
+ temple_v[k + w] = v[i];
|
|
|
+ temple_v[k + 1 + w] = v[i];
|
|
|
+ if ((k + 2) % w == 0) // 换行
|
|
|
+ {
|
|
|
+ k = k + w + 2;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ k = k + 2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ k = 0;
|
|
|
+ for (i = 0; i < w * h; i++)
|
|
|
+ {
|
|
|
+ // 反过来得到bgr
|
|
|
+ buffer_bgr[k] = y[i] + 1.7718 * (temple_u[i] - 128);
|
|
|
+ buffer_bgr[k + 1] = y[i] - 0.3441 * (temple_u[i] - 128) - 0.7139 * (temple_v[i] - 128);
|
|
|
+ buffer_bgr[k + 2] = y[i] + 1.4020 * (temple_v[i] - 128);
|
|
|
+ k = k + 3;
|
|
|
+ }
|
|
|
+ for (i = 0; i < w * h * 3; i++)
|
|
|
+ {
|
|
|
+ // 由于unsigned char类型范围为0到255,所以高于255置255,低于0置0
|
|
|
+ if (temple_bgr[i] > 255) {
|
|
|
+ temple_bgr[i] = 255;
|
|
|
+ }
|
|
|
+ else if (temple_bgr[i] < 0)
|
|
|
+ {
|
|
|
+ temple_bgr[i] = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (i = 0; i < w * h * 3; i++)
|
|
|
+ {
|
|
|
+ buffer_bgr[i] = temple_bgr[i];
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ delete[]temple_u;
|
|
|
+ delete[]temple_v;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#include <QTime>
|
|
|
void MainWindow::threadpic()
|
|
|
{
|
|
|
|
|
|
+// QTime xTime;
|
|
|
while(mbthreadrun)
|
|
|
{
|
|
|
int nindex = mph264decode->GetUpdatedIndex(10);
|
|
@@ -76,20 +227,36 @@ void MainWindow::threadpic()
|
|
|
iv::framedecodebuf * pbuf = mph264decode->LockReadBuff(nindex);
|
|
|
int cy = pbuf->frameheight;
|
|
|
int cx = pbuf->framewidth;
|
|
|
- cv::Mat rgbImg(cy, cx,CV_8UC3);
|
|
|
|
|
|
|
|
|
+#ifndef USEJPEG_NOOPENCV
|
|
|
+ cv::Mat rgbImg(cy, cx,CV_8UC3);
|
|
|
+// xTime.start();
|
|
|
cv::cvtColor(pbuf->myuvImg, rgbImg, CV_YUV2RGB_I420);
|
|
|
+// std::cout<<" time use : "<<xTime.elapsed()<<std::endl;
|
|
|
|
|
|
mph264decode->UnlockReadBuff(nindex);
|
|
|
|
|
|
QImage image2 = QImage((uchar*)(rgbImg.data), rgbImg.cols, rgbImg.rows, QImage::Format_RGB888);
|
|
|
|
|
|
+
|
|
|
+#else
|
|
|
+ char * pdata = new char[cy*cx*3];
|
|
|
+ xTime.start();
|
|
|
+ YUV2RGB((unsigned char *)pbuf->mpyuv_ptr.get(),(unsigned char *)(pbuf->mpyuv_ptr.get() + cy*cx),(unsigned char *)(pbuf->mpyuv_ptr.get()+cy*cx*5/4),
|
|
|
+ (unsigned char*)pdata,cx,cy);
|
|
|
+ std::cout<<"conver time: "<<xTime.elapsed()<<std::endl;
|
|
|
+ mph264decode->UnlockReadBuff(nindex);
|
|
|
+
|
|
|
+ QImage image2 = QImage((uchar*)pdata, cx, cy, QImage::Format_RGB888);
|
|
|
+// delete pdata;
|
|
|
+#endif
|
|
|
mMutexCam.lock();
|
|
|
// emit CamUpdate(ncampos,image2);
|
|
|
*mpImageCam = image2.copy();
|
|
|
mbCamUpdate = true;
|
|
|
mMutexCam.unlock();
|
|
|
+
|
|
|
emit CamUpdate();
|
|
|
}
|
|
|
}
|