//
// Created by 阳坤 on 2022/3/1.
//

#ifndef BYTESFLOW_OPENCV_MEDIA_AV_DECODE_H
#define BYTESFLOW_OPENCV_MEDIA_AV_DECODE_H

extern "C" {
#include "av_tools.h"
};

#include "../utils/pq_blockingqueue.hpp"
#include "vector"
#include "list"

using namespace std;

typedef enum DisableMediaType {
    DEFAULT = -1,
    VIDEO = 0,
    AUDIO,
} DisableMediaType;

typedef struct ImageHashModel {
    int64_t pts;
    /*图片指纹个数*/
    int img_len;
    /*帧对应的指纹*/
     char *image_hash;
} ImageHashModel;

typedef struct VideoSimilarityModel {
    /*图片指纹个数*/
    int img_len;
    /*帧对应的指纹*/
    const char *image_hash;
    int pict_type;
    long pts;
    int64_t startTimeMs, endTimeMs;

    std::vector<ImageHashModel *> hashs;
} VideoSimilarityModel;

typedef struct VideoSimilarity {
    const char *videoPath;
    std::vector<VideoSimilarityModel *> clips;
} VideoSimilarity;


typedef struct DecoderContext {
    /**
     * 封装格式上下文
     */
    AVFormatContext *avformatContext;
    /**
    /**
     * 视频解码器上下文
     */
    AVCodecContext *videoCodecContext;
    /**
     * 音频解码器上下文
     */
    AVCodecContext *audioCodecContext;

    /**
     * 文件偏移
     */
    int64_t offset;
    /**
     * 输入数据
     */
    const char *url;
    /**
     * 流索引
     */
    int st_index[AVMEDIA_TYPE_NB];

    /**
     * 视频参数
     */
    int width, height, v_bit_rate, vformat, rotate, fps;
    /**
     * 音频参数
     */
    int sampleRate, channels, aformat, channels_layout, a_bit_rate;
    int o_aformat;
    /**
     * ffmpeg 解码参数
     */
    int ffthread_count;

    /**
     * 解码器 ID
     */
    enum AVCodecID v_codec_id, a_codec_id;

    /**
     * 起点
     */
    long start_time;

    /**
     * 关闭媒体资源类型
     */
    enum DisableMediaType disableType;

    /*强制 I frame 输出, 解码多少帧*/
    long force_Iframe, decode_frame_ms, end_time;
    long totalMs;

    //音视频解码器缓存队列
    BlockQueue<AVFrame *> *video_queue;
    BlockQueue<AVFrame *> *audio_queue;

    pthread_t thread_id;

    vector<VideoSimilarityModel *> vs_decodes;
};

/*最简单的解码器实现*/
long initDecoder(const char *url, int force_Iframe, DisableMediaType disableMediaType);

void seekToMs(DecoderContext *dctx, int64_t offset);

int av_read_decode_frame(long decodec_id);

static void *av_read_decode_thread(void *pVoid);

void close_decoder(long decodec_id);

#endif //BYTESFLOW_OPENCV_MEDIA_AV_DECODE_H
