#include "cvbridge.hpp"
|
|
#include <string.h>
|
#include <stdexcept>
|
|
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))
|
,buff_fill_(NULL)
|
{
|
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_;
|
}
|
if(buff_fill_){
|
free(buff_fill_);
|
}
|
}
|
|
bool cvbridge::copyPicture(uint8_t *out, AVFrame *in){
|
if(!scale_ || !pic_){
|
return false;
|
}
|
|
if(!scale_->scaleFrame(in, pic_->getAVFrame())){
|
return false;
|
}
|
|
memcpy(out, pic_->getAVPictureData(),
|
pic_->getAVPictureSize());
|
|
return true;
|
}
|
bool cvbridge::getAVFrame(uint8_t *in, const int w, const int h, AVFrame * &output){
|
int width = w;
|
int height = h;
|
|
AVFrame *temp_rgb_frame = av_frame_alloc();
|
temp_rgb_frame->format = (AVPixelFormat)scale_->srcFmt_;
|
temp_rgb_frame->width = width;
|
temp_rgb_frame->height = height;
|
|
//create a AVPicture frame from the opencv Mat input image
|
int ret = avpicture_fill((AVPicture *)temp_rgb_frame,
|
(uint8_t *)in,
|
(AVPixelFormat)scale_->srcFmt_,
|
width,
|
height);
|
if(ret < 0){
|
av_frame_free(&temp_rgb_frame);
|
return false;
|
}
|
// temp_rgb_frame->linesize[0] = frame.step;
|
|
|
output->format = (AVPixelFormat)scale_->dstFmt_;
|
output->width = width;
|
output->height = height;
|
|
ret = scale_->scaleFrame(temp_rgb_frame, output);
|
|
av_frame_free(&temp_rgb_frame);
|
|
if(ret)
|
return true;
|
|
return false;
|
}
|
|
AVFrame *cvbridge::getAVFrame(uint8_t *in, const int w, const int h){
|
int width = w;
|
int height = h;
|
|
if(!buff_fill_){
|
int size = avpicture_get_size((AVPixelFormat)scale_->dstFmt_, width, height);
|
buff_fill_ = (uint8_t *) malloc(size);
|
}
|
AVFrame * output = av_frame_alloc();
|
const int ret = avpicture_fill((AVPicture*)output, buff_fill_,
|
(AVPixelFormat)scale_->dstFmt_, width, height);
|
if(ret < 0){
|
av_frame_free(&output);
|
return NULL;
|
}
|
|
if(getAVFrame(in, w, h, output)){
|
return output;
|
}
|
av_frame_free(&output);
|
return NULL;
|
}
|
//////////////////////////////////////////////////////////////////////////////////
|
AVFrame *cvbridge::getAVFrame(AVFrame *in){
|
|
int size = avpicture_get_size((enum AVPixelFormat)in->format, in->width, in->height);
|
uint8_t *buff = (uint8_t*)malloc(size);
|
avpicture_layout((const AVPicture *)in, (enum AVPixelFormat)in->format,
|
in->width, in->height, (unsigned char *)buff, size);
|
|
AVFrame *output = getAVFrame(buff, in->width, in->height);
|
free(buff);
|
return output;
|
}
|
|
bool cvbridge::getAVFrame(AVFrame *in, AVFrame * &output){
|
|
int size = avpicture_get_size((enum AVPixelFormat)in->format, in->width, in->height);
|
uint8_t *buff = (uint8_t*)malloc(size);
|
avpicture_layout((const AVPicture *)in, (enum AVPixelFormat)in->format,
|
in->width, in->height, (unsigned char *)buff, size);
|
|
bool flag = getAVFrame(buff, in->width, in->height, output);
|
free(buff);
|
return flag;
|
}
|
|
}
|