Add watermark through HAL layer video, available for all cameras

The implementation method of adding watermark in the project is directly available in comparison with Git submission records.

 

diff --git a/hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.cpp b/hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.cpp

--- a/hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.cpp
+++ b/hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.cpp
@@ -1022,6 +1022,7 @@ QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
       mAdvancedCaptureConfigured(false),
       mFPSReconfigure(false)
 {
+   mWatermarkBuf = NULL;
 #ifdef TARGET_TS_MAKEUP
     mMakeUpBuf = NULL;
     memset(&mFaceRect, -1, sizeof(mFaceRect));
@@ -2222,6 +2223,13 @@ int QCamera2HardwareInterface::startRecording()
     if (rc == NO_ERROR) {
         rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
     }
+   
+   if (mWatermarkBuf == NULL) {
+        int vid_width, vid_height;
+        mParameters.getVideoSize(&vid_width, &vid_height);
+        mWatermarkBuf = new unsigned char[vid_width*vid_height*3/2];
+        CDBG_HIGH("vid_width=%d,vid_height=%d",vid_width, vid_height);
+    }

 #ifdef HAS_MULTIMEDIA_HINTS
     if (rc == NO_ERROR) {
@@ -2259,6 +2267,11 @@ int QCamera2HardwareInterface::stopRecording()
         }
     }
 #endif
+
+   if (mWatermarkBuf) {
+        delete []mWatermarkBuf;
+        mWatermarkBuf=NULL;
+    }
     CDBG_HIGH("%s: X", __func__);
     return rc;
 }
 
//
 
diff --git a/hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.h b/hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.h
--- a/hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.h
+++ b/hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.h
@@ -656,6 +656,11 @@ private:
     int32_t mNumPreviewFaces;
     bool mAdvancedCaptureConfigured;
     bool mFPSReconfigure;
+   
+   unsigned char *mWatermarkBuf;
+   bool WatermarkProcess_Video(mm_camera_buf_def_t *pFrame,QCameraStream * pStream);
+   bool WatermarkProcess(mm_camera_buf_def_t *pFrame,QCameraStream * pStream,unsigned char *pOutBuf);
+  

//
     
    //ts add for makeup
 #ifdef TARGET_TS_MAKEUP
     TSRect mFaceRect;
diff --git a/hardware/qcom/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp b/hardware/qcom/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp
--- a/hardware/qcom/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp
+++ b/hardware/qcom/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp
@@ -37,6 +37,7 @@
 #include <utils/Trace.h>
 #include <utils/Timers.h>
 #include "QCamera2HWI.h"
+#include "digital_data.h"

 namespace qcamera {

@@ -552,6 +553,87 @@ bool QCamera2HardwareInterface::TsMakeupProcess(mm_camera_buf_def_t *pFrame,
     return bRet;
 }
 #endif
+
+bool QCamera2HardwareInterface::WatermarkProcess_Video(mm_camera_buf_def_t *pFrame,
+        QCameraStream * pStream) {
+    CDBG("%s begin",__func__);
+    bool bRet = false;
+    if (pStream == NULL || pFrame == NULL) {
+        bRet = false;
+        CDBG_HIGH("%s pStream == NULL || pFrame == NULL",__func__);
+    } else {
+        bRet = WatermarkProcess(pFrame,pStream,mWatermarkBuf);
+    }
+    CDBG("%s end bRet = %d ",__func__,bRet);
+    return bRet;
+}

+bool QCamera2HardwareInterface::WatermarkProcess(mm_camera_buf_def_t *pFrame,
+        QCameraStream * pStream,unsigned char *pOutBuf) {
+    bool bRet = false;
+    CDBG("%s begin",__func__);
+   if (pStream == NULL || pFrame == NULL || pOutBuf == NULL) {
+        bRet = false;
+        CDBG_HIGH("%s pStream == NULL || pFrame == NULL || pMakeupOutBuf == NULL",__func__);
+    }
+   
+   cam_dimension_t dim;
+    pStream->getFrameDimension(dim);
+   
+   int width = dim.width;   
+    int height = dim.height;   
+    unsigned char *_ptr;
+   _ptr = (unsigned char*)pFrame->buffer;      
+ 
+    if (NULL != _ptr) {        
+        char dateTime[] = "2016-12-22 09:00:00";
+        time_t timer;   
+        struct tm* t_tm;   
+              
+        time(&timer);   
+        t_tm = localtime(&timer);   
+        memset(dateTime, 0, sizeof(dateTime));  
+        sprintf(dateTime,"%4d-%02d-%02d %02d:%02d:%02d", t_tm->tm_year+1900, t_tm->tm_mon+1, t_tm->tm_mday, t_tm->tm_hour, t_tm->tm_min, t_tm->tm_sec);   
+              
+        //ALOGE("==========  timestampUs:%d, systemTime():%d, dateTime:%s",timestampUs, systemTime()/1000, dateTime);   
+        int digitalNums[10+8+1+ 1] = {-1};  // 10:-      11 ::      12:blank  
+        memset(digitalNums, -1, sizeof(digitalNums));  
+        for(int i = 0; i<19; i++){  
+            char num = dateTime[i];  
+            if(('0' <= num) && (num <= '9'))  
+            {  
+                digitalNums[i] = num - '0';  
+            }else if(num == '-'){  
+                digitalNums[i] = 10;  
+            }else if(num == ':'){  
+                digitalNums[i] = 11;  
+            }else if(num == ' '){  
+                digitalNums[i] = 12;  
+            }  
+        }
+
+       //for 1280 x 720
+       int left_offset = 776;  // width - digital_width * srtlen(dateTime) - digital_width * 2
+       int top_offset = 620;   // height - 100
+        for(int j = 0; j<digital_height; j++) {  
+            for(volatile int k=0; k<19; k++) {    
+                const unsigned char* str = (digitalNums[k] < 12 && digitalNums[k] != -1) ? DigitalArray[digitalNums[k]] : NULL;  
+                if(str != NULL) {   
+                    for(volatile int h=0; h<digital_width; h++) {      
+                        if(*(str+(digital_height - 1 - j)*digital_width + h) != 0x00) {  
+                            *(_ptr+top_offset*width + left_offset + j*width + k*(gap_width+digital_width) + h) = *(str+(digital_height - 1 - j)*digital_width + h);
+                        }  
+                    }  
+                }  
+            }          
+        }  
+  
+    }
+
+    CDBG("%s end bRet = %d ",__func__,bRet);
+    return bRet;
+}

 /
 
@@ -1119,6 +1201,9 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
         return;
     }
     mm_camera_buf_def_t *frame = super_frame->bufs[0];
+   
+   //ysm
+   pme->WatermarkProcess_Video(frame,stream);

     if (pme->needDebugFps()) {
         pme->debugShowVideoFPS();
		 
		 
		 
		 
		 
		 
		 
======CameraSource.cpp========================= 
		#include "digital_data.h"
		int width  = mVideoSize.width; 
		int height = mVideoSize.height; 
		uint8_t *_ptr = (uint8_t *)data->pointer(); 
		//int offset = 240; 
		int offset = height - 100; 
		int margin_left = width - 18*digital_width - 100;
		//ALOGE("!!! draw line, ptr: %p, offset: %d, stride: %d, height: %d", _ptr, offset, width,height); 
		if (NULL != _ptr) { 
			// 显示紫色条块, 这个Buffer的格式是YUV420 Planer格式,即先放Y,再放U,最后放V
			//int bar_width = 80;
			//memset(_ptr + offset*width , 0x80, width * bar_width); //Clear Y 
			//memset(_ptr + (height*width) + offset*width/4 , 0x40, width*bar_width/4); // Clear U 
			//memset(_ptr + (height*width + height*width/4) + offset*width/4, 0x40, width*bar_width/4); // Clear V 

			//得到时间
			char dateTime[] = "2020-08-13 10:16:28";// 默认时间,测试图片数据
			time_t timer; 
			struct tm* t_tm; 
			time(&timer); 
			t_tm = localtime(&timer); 
			memset(dateTime, 0, sizeof(dateTime));
			sprintf(dateTime,"%4d-%02d-%02d %02d:%02d:%02d", t_tm->tm_year+1900, t_tm->tm_mon+1, t_tm->tm_mday, t_tm->tm_hour, t_tm->tm_min, t_tm->tm_sec); 
			//ALOGE("==========  timestampUs:%d, systemTime():%d, dateTime:%s",timestampUs, systemTime()/1000, dateTime); 

			int digitalNums[10+8+1+ 1] = {-1};	// 10:-  11::  12:blank
			memset(digitalNums, -1, sizeof(digitalNums));

			for(int i = 0; i<strlen(dateTime); i++){
				char num = dateTime[i];
				if(('0' <= num) && (num <= '9'))
				{
					digitalNums[i] = num - '0';
				}else if(num == '-'){
					digitalNums[i] = 10;
				}else if(num == ':'){
					digitalNums[i] = 11;
				}else if(num == ' '){
					digitalNums[i] = 12;
				}
			}

			//绘制时间戳图片	
			//int pos_offset =  offset*width + margin_left;	// 起始位置
			for(int j = 0; j<digital_height; j++){
				//pos_offset = offset*width + margin_left + j*width;	// 下一行数据

				for(int k=0; k<10+1+8; k++){
					//改变水平位置
					//pos_offset += gap_width+digital_width;
					const unsigned char* str = (digitalNums[k] < 12 && digitalNums[k] != -1) ? DigitalArray[digitalNums[k]] : NULL;
					if(str != NULL) {
						// 摄像头旋转了180°,数据也需要旋转一下
						//只绘制白色,忽略掉黑色(类似png的通透效果)
						for(int h=0; h<digital_width; h++){
							if(*(str+(digital_height - 1 - j)*digital_width + h) != 0x00) {
								*(_ptr+offset*width + margin_left + j*width + k*(gap_width+digital_width) + h) = *(str+(digital_height - 1 - j)*digital_width + h);
							}
						}
					}
				}
			}
		} 

 

Code download

Effect picture:

Guess you like

Origin blog.csdn.net/u011694328/article/details/108886818