#include "playthread.h"
#include <QImage>
#include <QDebug>

PlayThread::PlayThread(QObject *parent)
    : QThread(parent)
{
    mPlayState = -1;
}

void PlayThread::setMedia(HMedia media)
{
    mMedia = media;
}

void PlayThread::setPlayState(int state)
{
    if(state >= -1 && mPlayState <= 1)
        mPlayState = state;
}

void PlayThread::run()
{
    mPlayState = 1;

    videoPlay.open(mMedia);
    while(true)
    {
        if(mPlayState == -1)
        {
            videoPlay.stop();
            return;
        }
        else if(mPlayState == 0)
        {
            videoPlay.pause();
            return;
        }

        if (videoPlay.pImpl_player->pop_frame(&mFrame) == 0)
        {

            int width = mFrame.w;
            int height = mFrame.h;
            unsigned char *yuv = (unsigned char *)mFrame.buf.data();

            //        unsigned char *img_yuv = NULL;
            //        unsigned char *img_rgb = NULL;

            int size = width * height * 3;
            // unsigned char* rgb = (unsigned char*)malloc(size);
            unsigned char *rgb = new unsigned char[size];
            yuv420ToRgb(yuv, rgb, width, height, true);

            // 浅拷贝
            QImage qimg(rgb, width, height, QImage::Format_RGB888);
            // 深拷贝
            QImage _qimg = qimg.copy(QRect());

            emit sendFrame(_qimg);

            delete []rgb;

//            std::this_thread::sleep_for(std::chrono::milliseconds(40));

        }
        std::this_thread::sleep_for(std::chrono::milliseconds(40));
    }

}

bool PlayThread::yuv420ToRgb(unsigned char *pYUV, unsigned char *pRGB, int width, int height, bool rgbState)
{
    // 找到Y、U、V在内存中的首地址
    unsigned char *pY = pYUV;
    unsigned char *pU = pYUV + height * width;
    unsigned char *pV = pU + (height * width / 4);

    unsigned char *pBGR = NULL;
    unsigned char R = 0;
    unsigned char G = 0;
    unsigned char B = 0;
    unsigned char Y = 0;
    unsigned char U = 0;
    unsigned char V = 0;
    double temp = 0;
    // 矩阵处理，对每个像素点进行转换
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            // 找到相应的RGB首地址
            pBGR = pRGB + i * width * 3 + j * 3;

            // 取Y、U、V的数据值
            Y = *(pY + i * width + j);
            U = *pU;
            V = *pV;

            // yuv转rgb公式
            temp = Y + ((1.773) * (U - 128));
            B = temp < 0 ? 0 : (temp > 255 ? 255 : (unsigned char)temp);

            temp = (Y - (0.344) * (U - 128) - (0.714) * (V - 128));
            G = temp < 0 ? 0 : (temp > 255 ? 255 : (unsigned char)temp);

            temp = (Y + (1.403) * (V - 128));
            R = temp < 0 ? 0 : (temp > 255 ? 255 : (unsigned char)temp);

            // 将转化后的rgb保存在rgb内存中，注意放入的顺序b是最低位
            if (rgbState)
            {
                *pBGR = R;
                *(pBGR + 1) = G;
                *(pBGR + 2) = B;
            }
            else
            {
                *pBGR = B;
                *(pBGR + 1) = G;
                *(pBGR + 2) = R;
            }

            if (j % 2 != 0)
            {
                *pU++;
                *pV++;
            }
        }
        if (i % 2 == 0)
        {
            pU = pU - width / 2;
            pV = pV - width / 2;
        }
    }
    return true;
}
