#include "cvbridge.hpp"
|
|
#include <string.h>
|
#include <stdexcept>
|
#include <memory>
|
|
extern "C"{
|
#include <libavcodec/avcodec.h>
|
}
|
|
#include "../swscale/swscale_wrapper.hpp"
|
#include "../data/PicData.hpp"
|
|
#include "../configure/conf.hpp"
|
|
using namespace ffwrapper;
|
|
namespace ffwrapper{
|
cvbridge::cvbridge(int srcW, int srcH, int srcFmt,
|
int dstW, int dstH, int dstFmt, int flags/*=4*/,
|
void *srcFilter/*=NULL*/,
|
void *dstFilter/*=NULL*/,
|
double *param/*=NULL*/)
|
:scale_(new swscale_wrapper)
|
,pic_(new PicData(dstW, dstH, dstFmt))
|
{
|
bool flag = !!scale_ && !!pic_;
|
flag = scale_->initContext(srcW, srcH, srcFmt, dstW, dstH, dstFmt, flags) && flag;
|
|
if(!flag){
|
throw std::runtime_error("init swscale error");
|
}
|
}
|
|
cvbridge::~cvbridge(){
|
if(scale_){
|
delete scale_;
|
}
|
if(pic_){
|
delete pic_;
|
}
|
}
|
|
uint8_t* cvbridge::convert2Data(AVFrame *in){
|
if(!scale_ || !pic_){
|
return NULL;
|
}
|
|
if(!scale_->scaleFrame(in, pic_->getAVFrame())){
|
return NULL;
|
}
|
|
uint8_t *out = (uint8_t*)malloc(pic_->getAVPictureSize());
|
memcpy(out, pic_->getAVPictureData(),
|
pic_->getAVPictureSize());
|
|
return out;
|
}
|
|
AVFrame* cvbridge::convert2Frame(AVFrame *in){
|
if(!scale_ || !pic_){
|
return NULL;
|
}
|
|
uint8_t *out = convert2Data(in);
|
AVFrame *frm = NULL;
|
if (out){
|
frm = fillFrame(out, scale_->dstW_, scale_->dstH_, scale_->dstFmt_);
|
}
|
free(out);
|
return frm;
|
}
|
|
/////////////////////////////////////////////////////////////////
|
|
AVFrame *cvbridge::fillFrame(uint8_t *in, const int w, const int h, const int f){
|
int width = w;
|
int height = h;
|
int format = f;
|
|
AVFrame *frame = av_frame_alloc();
|
frame->format = format;
|
frame->width = width;
|
frame->height = height;
|
|
// int size = avpicture_get_size((enum AVPixelFormat)frame->format, frame->width, frame->height);
|
// if (size <= 0){
|
// return NULL;
|
// }
|
// printf("size: %d, res: %dx%d, format: %d\n", size, w, h, f);
|
// uint8_t *spare = (uint8_t*)malloc(size);
|
// memcpy(spare, in, size);
|
|
int ret = avpicture_fill((AVPicture *)frame,
|
(uint8_t *)in,
|
(AVPixelFormat)frame->format,
|
frame->width,
|
frame->height);
|
if(ret < 0){
|
av_frame_free(&frame);
|
return NULL;
|
}
|
return frame;
|
}
|
|
uint8_t* cvbridge::extractFrame(AVFrame *in, int *length){
|
*length = avpicture_get_size((enum AVPixelFormat)in->format, in->width, in->height);
|
if (*length <= 0){
|
return NULL;
|
}
|
uint8_t *buff = (uint8_t*)malloc(*length);
|
int ret = avpicture_layout((const AVPicture *)in, (enum AVPixelFormat)in->format,
|
in->width, in->height, (unsigned char *)buff, *length);
|
if (ret < 0){
|
free(buff);
|
return NULL;
|
}
|
return buff;
|
}
|
|
}
|