#ifndef VIDEODECODER_H
#define VIDEODECODER_H

#include <QThread>
#include <QQueue>
#include <QImage>
#include <QPixmap>
#include <QMutex>
#include <QReadWriteLock>

class CCycleBuffer;
#define TUNE(r) ( r < 0 ? 0 : (r > 255 ? 255 : r) )

class VideoDecoder : public QThread
{
     Q_OBJECT
public:
    VideoDecoder(CCycleBuffer *m_capture, CCycleBuffer *m_encoder, int width, int height, int size, int format);
    ~VideoDecoder();
    void takePhoto(uint8_t *buf, int size, int format);
    int decoder_init(CCycleBuffer *buf,int format, int width, int height, int size);
    int decoder_deinit();
    int ffmepg_decode_init();
    int ffmpeg_decode_frame(uint8_t *buf);

    QImage m_frame[2];
    int m_frame_flag;
    char *m_frame_buf[2];
    int m_rgb_size;
    char *m_rgb_buf;
    int m_yuv_size;
    char *m_yuv_buf[2];
    char *m_jpeg_buf;
    int m_yuv_type;
    QPixmap m_pixmap;
    char m_photo_name[255];

     int m_buf_size;
     uint8_t *m_buf, *m_buf1;
     int m_width;
     int m_height;
     int m_dstWidth;
     int m_dstHeight;

     int m_format;

     int m_state;

     bool m_photo_clicked;
     bool m_video_clicked;
     bool m_video_start;
     bool m_stopped;
     bool m_run_stopped;
     bool m_display_mirror;
     bool m_quit = false;
     QMutex m_mutex;

Q_SIGNALS:
    void frameReceived(uchar *ptr, uint width, uint height);
    void runingStop();
    void photoError();
    void format_fix(uint width, uint height);

private:

    void run();
    int yuv2Rgb(char *pRGB, char *pYUV, int size);
    void YUYV_To_I420(uint8_t *src, uint8_t *dst, int width, int height);
    void UYVY_To_I420(uint8_t *src, uint8_t *dst, int width, int height);
    void I422_To_I420(uint8_t *src, uint8_t *dst, int width, int height);
    void I420_To_NV12(uint8_t *src, uint8_t *dst, int width, int height);
    void I420_To_RGB(uint8_t *src, uint8_t *dst, int width, int height);
    void mirrorI420(uint8_t *src, uint8_t *dst, int width, int height);
    void mirrorjpeg(uint8_t *src, int jpeg_size, uint8_t **dst, long unsigned int *dst_size, int width, int height);
    int jpeg2Yuv(uint8_t *jpeg_buffer, int jpeg_size, uint8_t *yuv_buffer, int *yuv_size, int *yuv_type);
    int jpeg2Yuv2(uint8_t *jpeg_buffer, int jpeg_size, uint8_t *yuv_buffer, int &des_width, int &des_height,
                  int *yuv_size, int *yuv_type);
    int yuv2jpeg(uint8_t *yuv_buffre, int yuv_size, int width, int height, int subsample, uint8_t **jpeg_buffer, unsigned long *jpeg_size, int quality);

    FILE *m_fp;

    CCycleBuffer *m_capture_buf;
    CCycleBuffer *m_encoder_buf;

    bool m_bFirst;

};

#endif // VIDEODECODER_H
