| | |
| | | |
| | | std::lock_guard<std::mutex> l(mutex_frm_); |
| | | for(auto i : list_frm_){ |
| | | free(i.data); |
| | | if (i.avframe) |
| | | av_frame_free(&i.avframe); |
| | | } |
| | | list_frm_.clear(); |
| | | } |
| | |
| | | return 0; |
| | | } |
| | | |
| | | 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; |
| | | uint8_t *origin = cvbridge::extractFrame(frame, &frm.length); |
| | | if (!origin) return -1; |
| | | |
| | | uint8_t *finale = NULL; |
| | | if (frame->format != AV_PIX_FMT_NV12){ |
| | | finale = (uint8_t*)malloc(frm.length); |
| | | |
| | | unsigned char* SrcU = origin + frm.width * frm.height; |
| | | unsigned char* SrcV = SrcU + frm.width * frm.height / 4 ; |
| | | unsigned char* DstU = finale + frm.width * frm.height; |
| | | memcpy(finale, origin, frm.width * frm.height); |
| | | int i = 0; |
| | | for( i = 0 ; i < frm.width * frm.height / 4 ; i++ ){ |
| | | *(DstU++) = *(SrcU++); |
| | | *(DstU++) = *(SrcV++); |
| | | } |
| | | free(origin); |
| | | }else{ |
| | | finale = origin; |
| | | } |
| | | frm.data = finale; |
| | | |
| | | std::lock_guard<std::mutex> l(mutex_frm_); |
| | | while(list_frm_.size() > 50){ |
| | | for(int i = 0; i < 12; i++){ |
| | | auto t = list_frm_.front(); |
| | | free(t.data); |
| | | list_frm_.pop_front(); |
| | | } |
| | | } |
| | | if (!frm.data) return 0; |
| | | list_frm_.push_back(frm); |
| | | return list_frm_.size(); |
| | | } |
| | | |
| | | int decoder::SetFrame(const CPacket &pkt){ |
| | | auto data = pkt.data; |
| | | |
| | |
| | | av_packet_unref(&np); |
| | | |
| | | if (ret == 0){ |
| | | saveFrame(frame, pkt.v_id); |
| | | return saveFrame(frame, pkt.v_id); |
| | | } |
| | | av_frame_free(&frame); |
| | | |
| | | return ret; |
| | | } |
| | | |
| | | void decoder::GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){ |
| | | |
| | | FRM frm; |
| | | { |
| | | std::lock_guard<std::mutex> l(mutex_frm_); |
| | | if(list_frm_.empty()){ |
| | | *data = NULL; |
| | | *w = *h = 0; |
| | | *id = -1; |
| | | return; |
| | | } |
| | | auto p = list_frm_.front(); |
| | | frm = list_frm_.front(); |
| | | list_frm_.pop_front(); |
| | | *data = p.data; |
| | | *id = p.id; |
| | | *w = p.width; |
| | | *h = p.height; |
| | | *format = p.format; |
| | | *length = p.length; |
| | | } |
| | | |
| | | AVFrame *frame = frm.avframe; |
| | | int pix_fmt = frame->format; |
| | | uint8_t *origin = cvbridge::extractFrame(frame, &frm.length); |
| | | av_frame_free(&frame); |
| | | if (!origin) return; |
| | | |
| | | uint8_t *finale = NULL; |
| | | if (pix_fmt != AV_PIX_FMT_NV12){ |
| | | finale = (uint8_t*)malloc(frm.length); |
| | | |
| | | unsigned char* SrcU = origin + frm.width * frm.height; |
| | | unsigned char* SrcV = SrcU + frm.width * frm.height / 4 ; |
| | | unsigned char* DstU = finale + frm.width * frm.height; |
| | | memcpy(finale, origin, frm.width * frm.height); |
| | | int i = 0; |
| | | for( i = 0 ; i < frm.width * frm.height / 4 ; i++ ){ |
| | | *(DstU++) = *(SrcU++); |
| | | *(DstU++) = *(SrcV++); |
| | | } |
| | | free(origin); |
| | | }else{ |
| | | finale = origin; |
| | | } |
| | | |
| | | *data = finale; |
| | | *id = frm.id; |
| | | *w = frm.width; |
| | | *h = frm.height; |
| | | *format = pix_fmt; |
| | | *length = frm.length; |
| | | } |
| | | //////////////////////////////////////////////////////////////////////// |
| | | static const int maxSize = 5; |
| | | int decoder::saveFrame(AVFrame *frame, const int64_t &id){ |
| | | FRM frm; |
| | | frm.avframe = frame; |
| | | frm.width = frame->width; |
| | | frm.height = frame->height; |
| | | frm.id = id; |
| | | |
| | | std::lock_guard<std::mutex> l(mutex_frm_); |
| | | while(list_frm_.size() > maxSize){ |
| | | for(int i = 0; i < (maxSize>1); i++){ |
| | | auto t = list_frm_.front(); |
| | | av_frame_free(&t.avframe); |
| | | list_frm_.pop_front(); |
| | | } |
| | | } |
| | | |
| | | list_frm_.push_back(frm); |
| | | return list_frm_.size(); |
| | | } |
| | | |
| | | } // namespace cffmpeg_wrap |