| | |
| | | #include "../ffmpeg/format/FormatIn.hpp" |
| | | #include "../ffmpeg/data/CodedData.hpp" |
| | | #include "../ffmpeg/log/log.hpp" |
| | | #include "../common.hpp" |
| | | |
| | | extern "C"{ |
| | | #include <libavformat/avformat.h> |
| | |
| | | |
| | | namespace cffmpeg_wrap |
| | | { |
| | | decoder::decoder(ffwrapper::FormatIn *dec, const int w, const int h, const int f) |
| | | :conv_(NULL) |
| | | ,conv_w_(w) |
| | | ,conv_h_(h) |
| | | ,conv_flag_(f) |
| | | ,decRef_(dec) |
| | | decoder::decoder(ffwrapper::FormatIn *dec) |
| | | :decRef_(dec) |
| | | {} |
| | | |
| | | decoder::~decoder(){ |
| | | |
| | | if (conv_){ |
| | | delete conv_; |
| | | std::lock_guard<std::mutex> l(mutex_frm_); |
| | | for(auto i : list_frm_){ |
| | | free(i.data); |
| | | } |
| | | |
| | | { |
| | | std::lock_guard<std::mutex> l(mutex_pic_); |
| | | for(auto &i : list_pic_){ |
| | | free(i.data); |
| | | } |
| | | list_pic_.clear(); |
| | | } |
| | | list_frm_.clear(); |
| | | } |
| | | |
| | | int decoder::initDecoder(){ |
| | |
| | | |
| | | bool flag = true; |
| | | flag = decRef_->openCodec(NULL); |
| | | auto dec_ctx = decRef_->getCodecContext(); |
| | | if(conv_){ |
| | | delete conv_; |
| | | conv_ = NULL; |
| | | } |
| | | conv_w_ = conv_w_ == 0 || conv_w_ > dec_ctx->width ? dec_ctx->width : conv_w_; |
| | | conv_h_ = conv_h_ == 0 || conv_h_ > dec_ctx->height ? dec_ctx->height : conv_h_; |
| | | AVPixelFormat pix_fmt = AV_PIX_FMT_BGR24; |
| | | conv_ = new cvbridge( |
| | | dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt, |
| | | conv_w_, conv_h_, pix_fmt, conv_flag_); |
| | | |
| | | if (!flag){ |
| | | logIt("FormatIn openCodec Failed!"); |
| | |
| | | return 0; |
| | | } |
| | | |
| | | int decoder::saveFrame(AVFrame *frame, int64_t &id){ |
| | | //缓存数据 |
| | | BGR24 pic; |
| | | AVFrame *frm = frame; |
| | | pic.w = conv_w_; |
| | | pic.h = conv_h_; |
| | | unsigned char *picData = (unsigned char*)malloc(pic.w * pic.h * 3); |
| | | conv_->copyPicture(picData, frm); |
| | | pic.data = picData; |
| | | pic.id = id; |
| | | std::lock_guard<std::mutex> l(mutex_pic_); |
| | | while(list_pic_.size() > 50){ |
| | | int decoder::saveFrame(AVFrame *frame, const int64_t &id){ |
| | | FRM frm; |
| | | frm.width = frame->width; |
| | | frm.height = frame->height; |
| | | frm.format = frame->format; |
| | | frm.id = id; |
| | | frm.data = cvbridge::extractFrame(frame, &frm.length); |
| | | |
| | | std::lock_guard<std::mutex> l(mutex_frm_); |
| | | while(list_frm_.size() > 50){ |
| | | for(int i = 0; i < 12; i++){ |
| | | auto t = list_pic_.front(); |
| | | auto t = list_frm_.front(); |
| | | free(t.data); |
| | | list_pic_.pop_front(); |
| | | list_frm_.pop_front(); |
| | | } |
| | | } |
| | | list_pic_.emplace_back(pic); |
| | | return list_pic_.size(); |
| | | if (!frm.data) return 0; |
| | | list_frm_.push_back(frm); |
| | | return list_frm_.size(); |
| | | } |
| | | |
| | | int decoder::SetFrame(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){ |
| | | int decoder::SetFrame(const CPacket &pkt){ |
| | | auto data = pkt.data; |
| | | |
| | | if (!data) return -1; |
| | | if (decRef_->isAudioPkt(&data->getAVPacket())) return -2; |
| | | if (!data) return -10; |
| | | if (!decRef_->isVideoPkt(&data->getAVPacket())) return -20; |
| | | |
| | | if (!conv_){ |
| | | if (initDecoder() != 0) return -3; |
| | | if (decRef_->getCodecContext() == NULL){ |
| | | if (initDecoder() != 0) return -30; |
| | | } |
| | | |
| | | AVFrame *frame = av_frame_alloc(); |
| | |
| | | av_packet_unref(&np); |
| | | |
| | | if (ret == 0){ |
| | | saveFrame(frame, id); |
| | | saveFrame(frame, pkt.v_id); |
| | | } |
| | | av_frame_free(&frame); |
| | | return ret; |
| | | } |
| | | |
| | | void decoder::GetFrame(unsigned char **data, int *w, int *h, int64_t *id){ |
| | | std::lock_guard<std::mutex> l(mutex_pic_); |
| | | if(list_pic_.empty()){ |
| | | void decoder::GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){ |
| | | |
| | | std::lock_guard<std::mutex> l(mutex_frm_); |
| | | if(list_frm_.empty()){ |
| | | *data = NULL; |
| | | *w = 0; |
| | | *h = 0; |
| | | *w = *h = 0; |
| | | *id = -1; |
| | | return; |
| | | } |
| | | auto p = list_pic_.front(); |
| | | *data = p.data; *w = p.w; *h = p.h; |
| | | auto p = list_frm_.front(); |
| | | list_frm_.pop_front(); |
| | | *data = p.data; |
| | | *id = p.id; |
| | | list_pic_.pop_front(); |
| | | *w = p.width; |
| | | *h = p.height; |
| | | *format = p.format; |
| | | *length = p.length; |
| | | } |
| | | |
| | | } // namespace cffmpeg_wrap |