You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
4.4 KiB
160 lines
4.4 KiB
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Copyright (C) 2022 Sophgo Technologies Inc. All rights reserved.
|
|
//
|
|
// SOPHON-DEMO is licensed under the 2-Clause BSD License except for the
|
|
// third-party components.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
/*
|
|
* This is a wrapper header of BMruntime & BMCV, aiming to simplify user's program.
|
|
*/
|
|
#include <iostream>
|
|
#include <queue>
|
|
#include <mutex>
|
|
#include <pthread.h>
|
|
#include "bmruntime_interface.h"
|
|
#include "bmcv_api_ext.h"
|
|
#include "bmlib_runtime.h"
|
|
#include "opencv2/opencv.hpp"
|
|
#include <opencv2/core.hpp>
|
|
#include "libyuv.h"
|
|
#include "bm_wrapper.hpp"
|
|
extern "C"
|
|
{
|
|
#include <libavformat/avformat.h>
|
|
#include <libavutil/imgutils.h>
|
|
#include <libavutil/macros.h>
|
|
#include <libswscale/swscale.h>
|
|
}
|
|
#if LIBAVCODEC_VERSION_MAJOR > 58
|
|
static int avcodec_decode_video2(AVCodecContext* dec_ctx, AVFrame *frame, int *got_picture, AVPacket* pkt)
|
|
{
|
|
int ret;
|
|
*got_picture = 0;
|
|
ret = avcodec_send_packet(dec_ctx, pkt);
|
|
if (ret == AVERROR_EOF) {
|
|
ret = 0;
|
|
}
|
|
else if (ret < 0) {
|
|
char err[256] = {0};
|
|
av_strerror(ret, err, sizeof(err));
|
|
fprintf(stderr, "Error sending a packet for decoding, %s\n", err);
|
|
return -1;
|
|
}
|
|
while (ret >= 0) {
|
|
ret = avcodec_receive_frame(dec_ctx, frame);
|
|
if (ret == AVERROR(EAGAIN)) {
|
|
ret = 0;
|
|
break;
|
|
}else if (ret == AVERROR_EOF) {
|
|
printf("File end!\n");
|
|
avcodec_flush_buffers(dec_ctx);
|
|
ret = 0;
|
|
break;
|
|
}
|
|
else if (ret < 0) {
|
|
fprintf(stderr, "Error during decoding\n");
|
|
break;
|
|
}
|
|
*got_picture += 1;
|
|
break;
|
|
}
|
|
if (*got_picture > 1) {
|
|
printf("got picture %d\n", *got_picture);
|
|
}
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
#define QUEUE_MAX_SIZE 5
|
|
#define EXTRA_FRAME_BUFFER_NUM 5
|
|
#define USEING_MEM_HEAP2 4
|
|
#define USEING_MEM_HEAP1 2
|
|
|
|
#define FF_ALIGN(x, a) (((x)+(a)-1)&~((a)-1))
|
|
|
|
|
|
typedef struct {
|
|
uint8_t* start;
|
|
int size;
|
|
int pos;
|
|
} bs_buffer_t;
|
|
|
|
int read_buffer(void *opaque, uint8_t *buf, int buf_size);
|
|
|
|
/**
|
|
* @brief convert avframe pix format to bm_image pix format.
|
|
* @return bm_image_format_ext.
|
|
*/
|
|
int map_avformat_to_bmformat(int avformat);
|
|
|
|
/**
|
|
* @brief convert avformat to bm_image.
|
|
*/
|
|
bm_status_t avframe_to_bm_image(bm_handle_t &handle, AVFrame *in, bm_image *out, bool is_jpeg, bool data_on_device_mem, int coded_width=-1, int coded_height=-1);
|
|
|
|
/**
|
|
* @brief picture decode. support jpg and png
|
|
*/
|
|
bm_status_t picDec(bm_handle_t &handle, const char *path, bm_image &img);
|
|
bm_status_t jpgDec(bm_handle_t& handle, uint8_t* bs_buffer, int numBytes, bm_image& img);
|
|
bm_status_t miscDec(bm_handle_t& handle, uint8_t* bs_buffer, int numBytes, int type, bm_image& img);
|
|
|
|
/**
|
|
* video decode class
|
|
* support video file and rtsp stream.
|
|
*
|
|
* VideoDecFFM create a thread to decode, convert AVFrame to bm_image, push bm_image into the cache queue.
|
|
* When the queue is full, for video file, the decode thread will sleep. For rtsp stream, the decode thread
|
|
* will pop the front element of the queue.
|
|
*
|
|
*/
|
|
class VideoDecFFM
|
|
{
|
|
public:
|
|
VideoDecFFM();
|
|
~VideoDecFFM();
|
|
|
|
/* open video decoder, decode, convert avFrame to bm_image, push it into the cache queue */
|
|
int openDec(bm_handle_t *dec_handle, const char *input);
|
|
|
|
/* grab a bm_image from the cache queue*/
|
|
bm_image *grab();
|
|
|
|
private:
|
|
bool quit_flag = false;
|
|
|
|
int is_rtsp;
|
|
int width;
|
|
int height;
|
|
int coded_width;
|
|
int coded_height;
|
|
int pix_fmt;
|
|
bool data_on_device_mem = true;
|
|
|
|
int video_stream_idx;
|
|
int refcount;
|
|
// "101" for compressed and "0" for linear
|
|
int output_format = 0;
|
|
|
|
AVFrame *frame;
|
|
AVPacket pkt;
|
|
AVFormatContext *ifmt_ctx;
|
|
AVCodec *decoder;
|
|
AVCodecContext *video_dec_ctx;
|
|
AVCodecParameters *video_dec_par;
|
|
|
|
bm_handle_t *handle;
|
|
std::mutex lock;
|
|
std::queue<bm_image *> queue;
|
|
|
|
int openCodecContext(int *stream_idx, AVCodecContext **dec_ctx, AVFormatContext *fmt_ctx,
|
|
enum AVMediaType type, int sophon_idx);
|
|
|
|
void *vidPushImage();
|
|
AVFrame *grabFrame();
|
|
AVFrame* flushDecoder();
|
|
void closeDec();
|
|
};
|