#include "cvbridge.hpp" #include #include extern "C"{ #include } #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; } }