#ifndef _JPEG_DECODE_H__
#define _JPEG_DECODE_H__

#include <fstream>
#include <queue>
#include <pthread.h>

#include "NvJpegDecoder.h"
#include "NvVideoConverter.h"

#include "FF_CircleQueue.h"
#include "VCCommon.h"

#define NUM_FILE_DECODE 10

typedef struct
{
    NvVideoConverter *conv;
    NvJPEGDecoder *jpegdec;

    char *in_file_path[NUM_FILE_DECODE];
    std::ifstream * in_file[NUM_FILE_DECODE];
    uint64_t in_file_size;
    unsigned char *in_buffer;

    char *out_file_path[NUM_FILE_DECODE];
    std::ofstream * out_file[NUM_FILE_DECODE];

    int out_fd;
    bool got_error;
    bool use_fd;
    bool perf;
    int  stress_test;
    int num_files;
    int current_file;

    void* g_this;
    pthread_t decode_thread; // Current thread, decoding stream.
    uint32_t video_height;
    uint32_t video_width;
    uint32_t thread_num;
}jepg_context_t;


class JpegDecode
{
public:
    JpegDecode(FF_CircleQueue<VideoQBuffer*>* _InBufQueue, FF_CircleQueue<VideoQBuffer*>* _outBufQueue);
    ~JpegDecode();

    /** 
     * @brief 初始化通道
     */
    int InitJpegDecode(int chn, uint32_t inWidth = 1920, uint32_t inHeight = 1080);

    /** @brief 启动解码通道idx */
    int RunJpegDecoderChn(int chn);
    
private:
    void abort(jepg_context_t * ctx);
    static bool conv_capture_dqbuf_thread_callback(struct v4l2_buffer *v4l2_buf,
                        NvBuffer * buffer, NvBuffer * shared_buffer, void *arg);
    uint64_t get_file_size(ifstream * stream);
    static void* jpeg_decode_proc(void *pctx);
    int set_defaults(int chn, uint32_t inWidth, uint32_t inHeight);
    int read_input_data_from_queue(uint32_t ch_num, unsigned char* inbuffer);
    int write_video_frame_to_queue(int chn, NvBuffer &buffer);
private:

    FF_CircleQueue<VideoQBuffer*>* ff_InBufQueue;
    FF_CircleQueue<VideoQBuffer*>* ff_outBufQueue;

    bool m_StopProcBlocking; 

    jepg_context_t m_JpegDec_Ctx;

    FILE *pfile  = NULL;

#define JPEG_TEST_ERROR(cond, str, label) if(cond) { \
                                        cerr << str << endl; \
                                        error = 1; \
                                        goto label; }

};


#endif  //_JPEG_DECODE_H__
