From 18a05d269516a5e33d8460291c2f93e73d95adce Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期二, 26 十二月 2023 10:45:31 +0800
Subject: [PATCH] GetYUV format is NV12

---
 csrc/ffmpeg/bridge/cvbridge.cpp |  131 ++++++++++++++++++-------------------------
 1 files changed, 54 insertions(+), 77 deletions(-)

diff --git a/csrc/ffmpeg/bridge/cvbridge.cpp b/csrc/ffmpeg/bridge/cvbridge.cpp
index 0ab95d5..0749f12 100644
--- a/csrc/ffmpeg/bridge/cvbridge.cpp
+++ b/csrc/ffmpeg/bridge/cvbridge.cpp
@@ -2,6 +2,7 @@
 
 #include <string.h>
 #include <stdexcept>
+#include <memory>
 
 extern "C"{
 #include <libavcodec/avcodec.h>
@@ -22,7 +23,6 @@
 				 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;
@@ -39,106 +39,83 @@
 		if(pic_){
 			delete pic_;
 		}
-        if(buff_fill_){
-            free(buff_fill_);
-        }
 	}
 
-	bool cvbridge::copyPicture(uint8_t *out, AVFrame *in){
+	uint8_t* cvbridge::convert2Data(AVFrame *in){
 		if(!scale_ || !pic_){
-			return false;
+			return NULL;
 		}
 
 		if(!scale_->scaleFrame(in, pic_->getAVFrame())){
-			return false;
+			return NULL;
 		}
 
+        uint8_t *out = (uint8_t*)malloc(pic_->getAVPictureSize());
 		memcpy(out, pic_->getAVPictureData(), 
 					pic_->getAVPictureSize());
 
-		return true;		
+		return out;		
 	}
-    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;
+    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_);
         }
-        // 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;
+        free(out);
+        return frm;
     }
 
-    AVFrame *cvbridge::getAVFrame(uint8_t *in, const int w, const int h){
+/////////////////////////////////////////////////////////////////
+
+    AVFrame *cvbridge::fillFrame(uint8_t *in, const int w, const int h, const int f){
         int width = w;
         int height = h;
+        int format = f;
 
-        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);
+        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(&output);
+            av_frame_free(&frame);
             return NULL;
         }
+        return frame;
+    }
 
-        if(getAVFrame(in, w, h, output)){
-            return output;
+    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;
         }
-        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;
+        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;
     }
 
 }

--
Gitblit v1.8.0