video analysis2.0拆分,ffmpeg封装go接口库
zhangmeng
2020-09-01 e62936fa4a4b626a359bce8981ebbbaddcd4aada
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#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;
    }
 
}