Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
avmIntergration
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
马乐
avmIntergration
Commits
b97bd49c
Commit
b97bd49c
authored
Oct 20, 2023
by
马乐
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
融合图全屏
parent
59027733
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
753 additions
and
47 deletions
+753
-47
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+5
-2
MainActivity.kt
app/src/main/java/com/intergration/avm/MainActivity.kt
+12
-15
avm.kt
app/src/main/java/com/intergration/avm/avm.kt
+6
-6
CameraGLSurfaceView.java
...a/com/intergration/avm/glsurface/CameraGLSurfaceView.java
+427
-0
GLUtils.java
...src/main/java/com/intergration/avm/glsurface/GLUtils.java
+273
-0
AuxiliaryScreenPresentation.kt
...ergration/avm/presentation/AuxiliaryScreenPresentation.kt
+17
-14
MultiScreenService.kt
...a/com/intergration/avm/presentation/MultiScreenService.kt
+7
-7
Utils.kt
app/src/main/java/com/intergration/avm/utils/Utils.kt
+3
-1
layout_presentation.xml
app/src/main/res/layout/layout_presentation.xml
+3
-2
No files found.
app/src/main/AndroidManifest.xml
View file @
b97bd49c
...
...
@@ -38,7 +38,8 @@
tools:targetApi=
"31"
>
<activity
android:name=
".MainActivity"
android:exported=
"true"
>
android:exported=
"true"
android:screenOrientation=
"landscape"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
...
...
@@ -47,7 +48,8 @@
</activity>
<service
android:name=
".presentation.MultiScreenService"
android:enabled=
"true"
android:exported=
"true"
/>
android:exported=
"true"
android:screenOrientation=
"landscape"
/>
</application>
</manifest>
\ No newline at end of file
app/src/main/java/com/intergration/avm/MainActivity.kt
View file @
b97bd49c
...
...
@@ -12,6 +12,8 @@ import androidx.activity.result.contract.ActivityResultContracts
import
androidx.appcompat.app.AppCompatActivity
import
androidx.core.app.ActivityCompat
import
androidx.core.content.ContextCompat
import
com.arcsoft.imageutil.ArcSoftImageFormat
import
com.arcsoft.imageutil.ArcSoftImageUtil
import
com.arcsoft.visdrive.avmsdk.ArcErrorInfo
import
com.arcsoft.visdrive.avmsdk.ArcVisDriveAVMEngine
import
com.arcsoft.visdrive.avmsdk.constant.avm.ArcAVMType
...
...
@@ -21,6 +23,7 @@ import com.arcsoft.visdrive.avmsdk.model.avm.ArcAVMLookupTable
import
com.arcsoft.visdrive.avmsdk.model.avm.ArcAVMOutputImage
import
com.arcsoft.visdrive.avmsdk.model.common.ArcActiveEnvParam
import
com.blankj.utilcode.util.FileUtils
import
com.blankj.utilcode.util.ImageUtils
import
com.blankj.utilcode.util.LogUtils
import
com.intergration.avm.databinding.ActivityMainBinding
import
com.intergration.avm.utils.ArcAVMInputImageFactory
...
...
@@ -212,14 +215,13 @@ class MainActivity : AppCompatActivity() {
}
avmPlayJob
=
avmStartScope
?.
launch
{
try
{
val
frontScope
=
CoroutineScope
(
Dispatchers
.
Default
)
avmFrontCamera
.
startPictureSequence
(
PictureSequenceSource
.
GENERAL_CAMERA
,
configCameraSequence
(
avmDir
.
absolutePath
)
{
_
,
_
,
status
,
data
,
_
->
if
(
status
==
SpmCameraDevice
.
ImageDataCallback
.
IMAGE_STATUS_SUCCEEDED
)
{
ArcAVMInputImageFactory
.
ofFront
(
data
).
also
{
avmInputImages
[
0
]
=
it
frontScope
.
launch
{
launch
{
ensureActive
()
channel
.
send
(
true
)
}
...
...
@@ -227,14 +229,13 @@ class MainActivity : AppCompatActivity() {
}
}
)
val
rightScope
=
CoroutineScope
(
Dispatchers
.
Default
)
avmRightCamera
.
startPictureSequence
(
PictureSequenceSource
.
GENERAL_CAMERA
,
configCameraSequence
(
avmDir
.
absolutePath
)
{
_
,
_
,
status
,
data
,
_
->
if
(
status
==
SpmCameraDevice
.
ImageDataCallback
.
IMAGE_STATUS_SUCCEEDED
)
{
ArcAVMInputImageFactory
.
ofRight
(
data
).
also
{
avmInputImages
[
1
]
=
it
rightScope
.
launch
{
launch
{
ensureActive
()
channel
.
send
(
true
)
}
...
...
@@ -242,14 +243,13 @@ class MainActivity : AppCompatActivity() {
}
}
)
val
backScope
=
CoroutineScope
(
Dispatchers
.
Default
)
avmBackCamera
.
startPictureSequence
(
PictureSequenceSource
.
GENERAL_CAMERA
,
configCameraSequence
(
avmDir
.
absolutePath
)
{
_
,
_
,
status
,
data
,
_
->
if
(
status
==
SpmCameraDevice
.
ImageDataCallback
.
IMAGE_STATUS_SUCCEEDED
)
{
ArcAVMInputImageFactory
.
ofBack
(
data
).
also
{
avmInputImages
[
2
]
=
it
backScope
.
launch
{
launch
{
ensureActive
()
channel
.
send
(
true
)
}
...
...
@@ -257,14 +257,13 @@ class MainActivity : AppCompatActivity() {
}
}
)
val
leftScope
=
CoroutineScope
(
Dispatchers
.
Default
)
avmLeftCamera
.
startPictureSequence
(
PictureSequenceSource
.
GENERAL_CAMERA
,
configCameraSequence
(
avmDir
.
absolutePath
)
{
_
,
_
,
status
,
data
,
_
->
if
(
status
==
SpmCameraDevice
.
ImageDataCallback
.
IMAGE_STATUS_SUCCEEDED
)
{
ArcAVMInputImageFactory
.
ofLeft
(
data
).
also
{
avmInputImages
[
3
]
=
it
l
eftScope
.
l
aunch
{
launch
{
ensureActive
()
channel
.
send
(
true
)
}
...
...
@@ -287,7 +286,7 @@ class MainActivity : AppCompatActivity() {
)
if
(
result
==
ArcErrorInfo
.
ARC_ERROR_OK
)
{
if
(
outputImageList
.
isNotEmpty
())
{
feedData
(
outputImageList
[
0
].
imageData
)
feedData
(
outputImageList
[
0
].
imageData
,
outputImageList
[
0
].
width
,
outputImageList
[
0
].
height
)
}
}
}
...
...
@@ -351,12 +350,10 @@ class MainActivity : AppCompatActivity() {
override
fun
onDestroy
()
{
super
.
onDestroy
()
SmartPlatformManager
.
get
().
run
{
closeCameraDevice
(
avmFrontCamera
)
closeCameraDevice
(
avmBackCamera
)
closeCameraDevice
(
avmLeftCamera
)
closeCameraDevice
(
avmRightCamera
)
}
smartPlatformManager
.
closeCameraDevice
(
avmFrontCamera
)
smartPlatformManager
.
closeCameraDevice
(
avmBackCamera
)
smartPlatformManager
.
closeCameraDevice
(
avmLeftCamera
)
smartPlatformManager
.
closeCameraDevice
(
avmRightCamera
)
job
?.
cancel
(
CancellationException
(
"MainActivity Destroyed"
))
}
...
...
app/src/main/java/com/intergration/avm/avm.kt
View file @
b97bd49c
...
...
@@ -104,8 +104,8 @@ fun ArcVisDriveAVMEngine.initializeAvmParams(calibResultPath:File,lookupPath:Fil
calibInfo
.
singleImageWidth
=
IMAGE_WIDTH
calibInfo
.
singleImageHeight
=
IMAGE_HEIGHT
val
carInfo
=
ArcAVMCarInfo
()
carInfo
.
width
=
59
0
carInfo
.
length
=
1
8
00
carInfo
.
width
=
60
0
carInfo
.
length
=
1
2
00
carInfo
.
blinkAreaFront
=
0
carInfo
.
blinkAreaRight
=
0
carInfo
.
blinkAreaBack
=
0
...
...
@@ -133,10 +133,10 @@ fun ArcVisDriveAVMEngine.initializeAvmParams(calibResultPath:File,lookupPath:Fil
fun
ArcVisDriveAVMEngine
.
autoCalib
(
calibResultPath
:
File
,
lookupPath
:
File
):
Int
{
val
clothInfo
=
ArcAVMClothInfo
()
clothInfo
.
d1
=
120
clothInfo
.
d3
=
6
90
clothInfo
.
d4
=
6
90
clothInfo
.
d5
=
69
0
clothInfo
.
d6
=
69
0
clothInfo
.
d3
=
5
90
clothInfo
.
d4
=
5
90
clothInfo
.
d5
=
55
0
clothInfo
.
d6
=
55
0
val
chessInfoFront
=
ArcAVMChessInfo
(
ArcAVMCameraPosType
.
TYPE_FRONT
)
val
chessInfoRight
=
ArcAVMChessInfo
(
ArcAVMCameraPosType
.
TYPE_RIGHT
)
val
chessInfoBack
=
ArcAVMChessInfo
(
ArcAVMCameraPosType
.
TYPE_BACK
)
...
...
app/src/main/java/com/intergration/avm/glsurface/CameraGLSurfaceView.java
0 → 100644
View file @
b97bd49c
package
com
.
intergration
.
avm
.
glsurface
;
import
android.content.Context
;
import
android.graphics.Outline
;
import
android.graphics.Rect
;
import
android.opengl.GLES20
;
import
android.opengl.GLSurfaceView
;
import
android.util.AttributeSet
;
import
android.view.View
;
import
android.view.ViewOutlineProvider
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteOrder
;
import
java.nio.FloatBuffer
;
import
javax.microedition.khronos.egl.EGLConfig
;
import
javax.microedition.khronos.opengles.GL10
;
public
class
CameraGLSurfaceView
extends
GLSurfaceView
{
private
static
final
String
TAG
=
"CameraGLSurfaceView"
;
// 源视频帧宽/高
private
int
frameWidth
,
frameHeight
;
private
boolean
isMirror
;
private
int
rotateDegree
=
0
;
// 用于判断preview数据是否被传入,避免在初始化时有一段时间的绿色背景(y、u、v均全为0)
private
boolean
dataInput
=
false
;
// 圆角半径
private
int
radius
=
0
;
private
ByteBuffer
yBuf
=
null
,
uBuf
=
null
,
vBuf
=
null
;
// 纹理id
private
int
[]
yTexture
=
new
int
[
1
];
private
int
[]
uTexture
=
new
int
[
1
];
private
int
[]
vTexture
=
new
int
[
1
];
//YUV分量
private
byte
[]
yArray
;
private
byte
[]
uArray
;
private
byte
[]
vArray
;
private
static
final
int
FLOAT_SIZE_BYTES
=
4
;
//片段着色器的效果
private
String
fragmentShaderCode
=
GLUtils
.
FRAG_SHADER_NORMAL
;
private
FloatBuffer
squareVertices
=
null
;
private
FloatBuffer
coordVertices
=
null
;
private
boolean
rendererReady
=
false
;
private
float
[]
coordVertice
=
null
;
private
int
lastWidth
;
private
int
lastHeight
;
public
CameraGLSurfaceView
(
Context
context
)
{
this
(
context
,
null
);
}
public
CameraGLSurfaceView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
setEGLContextClientVersion
(
2
);
//设置Renderer到GLSurfaceView
setRenderer
(
new
YUVRenderer
());
// 只有在绘制数据改变时才绘制view
setRenderMode
(
RENDERMODE_WHEN_DIRTY
);
setOutlineProvider
(
new
ViewOutlineProvider
()
{
@Override
public
void
getOutline
(
View
view
,
Outline
outline
)
{
Rect
rect
=
new
Rect
(
0
,
0
,
view
.
getMeasuredWidth
(),
view
.
getMeasuredHeight
());
outline
.
setRoundRect
(
rect
,
radius
);
}
});
setClipToOutline
(
true
);
}
public
void
turnRound
()
{
invalidateOutline
();
}
public
int
getRadius
()
{
return
radius
;
}
public
void
setRadius
(
int
radius
)
{
this
.
radius
=
radius
;
}
/**
* 设置不同的片段着色器代码以达到不同的预览效果
*
* @param fragmentShaderCode 片段着色器代码
*/
public
void
setFragmentShaderCode
(
String
fragmentShaderCode
)
{
this
.
fragmentShaderCode
=
fragmentShaderCode
;
}
public
void
init
(
boolean
isMirror
,
int
rotateDegree
,
int
frameWidth
,
int
frameHeight
)
{
if
(
this
.
frameWidth
==
frameWidth
&&
this
.
frameHeight
==
frameHeight
&&
this
.
rotateDegree
==
rotateDegree
&&
this
.
isMirror
==
isMirror
)
{
return
;
}
dataInput
=
false
;
this
.
frameWidth
=
frameWidth
;
this
.
frameHeight
=
frameHeight
;
this
.
rotateDegree
=
rotateDegree
;
this
.
isMirror
=
isMirror
;
yArray
=
new
byte
[
this
.
frameWidth
*
this
.
frameHeight
];
uArray
=
new
byte
[
this
.
frameWidth
*
this
.
frameHeight
/
4
];
vArray
=
new
byte
[
this
.
frameWidth
*
this
.
frameHeight
/
4
];
int
yFrameSize
=
this
.
frameHeight
*
this
.
frameWidth
;
int
uvFrameSize
=
yFrameSize
>>
2
;
yBuf
=
ByteBuffer
.
allocateDirect
(
yFrameSize
);
yBuf
.
order
(
ByteOrder
.
nativeOrder
()).
position
(
0
);
uBuf
=
ByteBuffer
.
allocateDirect
(
uvFrameSize
);
uBuf
.
order
(
ByteOrder
.
nativeOrder
()).
position
(
0
);
vBuf
=
ByteBuffer
.
allocateDirect
(
uvFrameSize
);
vBuf
.
order
(
ByteOrder
.
nativeOrder
()).
position
(
0
);
// 顶点坐标
squareVertices
=
ByteBuffer
.
allocateDirect
(
GLUtils
.
SQUARE_VERTICES
.
length
*
FLOAT_SIZE_BYTES
)
.
order
(
ByteOrder
.
nativeOrder
())
.
asFloatBuffer
();
squareVertices
.
put
(
GLUtils
.
SQUARE_VERTICES
).
position
(
0
);
//纹理坐标
if
(
isMirror
)
{
switch
(
rotateDegree
)
{
case
0
:
coordVertice
=
GLUtils
.
MIRROR_COORD_VERTICES
;
break
;
case
90
:
coordVertice
=
GLUtils
.
ROTATE_90_MIRROR_COORD_VERTICES
;
break
;
case
180
:
coordVertice
=
GLUtils
.
ROTATE_180_MIRROR_COORD_VERTICES
;
break
;
case
270
:
coordVertice
=
GLUtils
.
ROTATE_270_MIRROR_COORD_VERTICES
;
break
;
default
:
break
;
}
}
else
{
switch
(
rotateDegree
)
{
case
0
:
coordVertice
=
GLUtils
.
COORD_VERTICES
;
break
;
case
90
:
coordVertice
=
GLUtils
.
ROTATE_90_COORD_VERTICES
;
break
;
case
180
:
coordVertice
=
GLUtils
.
ROTATE_180_COORD_VERTICES
;
break
;
case
270
:
coordVertice
=
GLUtils
.
ROTATE_270_COORD_VERTICES
;
break
;
default
:
break
;
}
}
coordVertices
=
ByteBuffer
.
allocateDirect
(
coordVertice
.
length
*
FLOAT_SIZE_BYTES
).
order
(
ByteOrder
.
nativeOrder
()).
asFloatBuffer
();
coordVertices
.
put
(
coordVertice
).
position
(
0
);
}
/**
* 创建OpenGL Program并关联GLSL中的变量
*
* @param fragmentShaderCode 片段着色器代码
*/
private
void
createGLProgram
(
String
fragmentShaderCode
)
{
int
programHandleMain
=
GLUtils
.
createShaderProgram
(
fragmentShaderCode
);
if
(
programHandleMain
!=
-
1
)
{
// 使用着色器程序
GLES20
.
glUseProgram
(
programHandleMain
);
// 获取顶点着色器变量
int
glPosition
=
GLES20
.
glGetAttribLocation
(
programHandleMain
,
"attr_position"
);
int
textureCoord
=
GLES20
.
glGetAttribLocation
(
programHandleMain
,
"attr_tc"
);
// 获取片段着色器变量
int
ySampler
=
GLES20
.
glGetUniformLocation
(
programHandleMain
,
"ySampler"
);
int
uSampler
=
GLES20
.
glGetUniformLocation
(
programHandleMain
,
"uSampler"
);
int
vSampler
=
GLES20
.
glGetUniformLocation
(
programHandleMain
,
"vSampler"
);
//给变量赋值
/*
* GLES20.GL_TEXTURE0 和 ySampler 绑定
* GLES20.GL_TEXTURE1 和 uSampler 绑定
* GLES20.GL_TEXTURE2 和 vSampler 绑定
*
* 也就是说 glUniform1i的第二个参数代表图层序号
*/
GLES20
.
glUniform1i
(
ySampler
,
0
);
GLES20
.
glUniform1i
(
uSampler
,
1
);
GLES20
.
glUniform1i
(
vSampler
,
2
);
GLES20
.
glEnableVertexAttribArray
(
glPosition
);
GLES20
.
glEnableVertexAttribArray
(
textureCoord
);
/*
* 设置Vertex Shader数据
*/
if
(
squareVertices
==
null
)
{
squareVertices
=
ByteBuffer
.
allocateDirect
(
GLUtils
.
SQUARE_VERTICES
.
length
*
FLOAT_SIZE_BYTES
)
.
order
(
ByteOrder
.
nativeOrder
())
.
asFloatBuffer
();
squareVertices
.
put
(
GLUtils
.
SQUARE_VERTICES
).
position
(
0
);
}
squareVertices
.
position
(
0
);
GLES20
.
glVertexAttribPointer
(
glPosition
,
GLUtils
.
COUNT_PER_SQUARE_VERTICE
,
GLES20
.
GL_FLOAT
,
false
,
8
,
squareVertices
);
if
(
coordVertices
==
null
)
{
coordVertices
=
ByteBuffer
.
allocateDirect
(
coordVertice
.
length
*
FLOAT_SIZE_BYTES
).
order
(
ByteOrder
.
nativeOrder
()).
asFloatBuffer
();
coordVertices
.
put
(
GLUtils
.
MIRROR_COORD_VERTICES
).
position
(
0
);
}
coordVertices
.
position
(
0
);
GLES20
.
glVertexAttribPointer
(
textureCoord
,
GLUtils
.
COUNT_PER_COORD_VERTICES
,
GLES20
.
GL_FLOAT
,
false
,
8
,
coordVertices
);
}
}
public
class
YUVRenderer
implements
Renderer
{
private
void
initRenderer
()
{
rendererReady
=
false
;
createGLProgram
(
fragmentShaderCode
);
//启用纹理
GLES20
.
glEnable
(
GLES20
.
GL_TEXTURE_2D
);
//创建纹理
createTexture
(
frameWidth
,
frameHeight
,
GLES20
.
GL_LUMINANCE
,
yTexture
);
createTexture
(
frameWidth
/
2
,
frameHeight
/
2
,
GLES20
.
GL_LUMINANCE
,
uTexture
);
createTexture
(
frameWidth
/
2
,
frameHeight
/
2
,
GLES20
.
GL_LUMINANCE
,
vTexture
);
rendererReady
=
true
;
}
@Override
public
void
onSurfaceCreated
(
GL10
unused
,
EGLConfig
config
)
{
initRenderer
();
}
// 根据宽高和格式创建纹理
private
void
createTexture
(
int
width
,
int
height
,
int
format
,
int
[]
textureId
)
{
//创建纹理
GLES20
.
glGenTextures
(
1
,
textureId
,
0
);
//绑定纹理
GLES20
.
glBindTexture
(
GLES20
.
GL_TEXTURE_2D
,
textureId
[
0
]);
/**
* {@link GLES20#GL_TEXTURE_WRAP_S}代表左右方向的纹理环绕模式
* {@link GLES20#GL_TEXTURE_WRAP_T}代表上下方向的纹理环绕模式
*
* {@link GLES20#GL_REPEAT}:重复
* {@link GLES20#GL_MIRRORED_REPEAT}:镜像重复
* {@link GLES20#GL_CLAMP_TO_EDGE}:忽略边框截取
*
* 例如我们使用{@link GLES20#GL_REPEAT}:
*
* squareVertices coordVertices
* -1.0f, -1.0f, 1.0f, 1.0f,
* 1.0f, -1.0f, 1.0f, 0.0f, -> 和textureView预览相同
* -1.0f, 1.0f, 0.0f, 1.0f,
* 1.0f, 1.0f 0.0f, 0.0f
*
* squareVertices coordVertices
* -1.0f, -1.0f, 2.0f, 2.0f,
* 1.0f, -1.0f, 2.0f, 0.0f, -> 和textureView预览相比,分割成了4 块相同的预览(左下,右下,左上,右上)
* -1.0f, 1.0f, 0.0f, 2.0f,
* 1.0f, 1.0f 0.0f, 0.0f
*/
GLES20
.
glTexParameteri
(
GLES20
.
GL_TEXTURE_2D
,
GLES20
.
GL_TEXTURE_WRAP_S
,
GLES20
.
GL_REPEAT
);
GLES20
.
glTexParameteri
(
GLES20
.
GL_TEXTURE_2D
,
GLES20
.
GL_TEXTURE_WRAP_T
,
GLES20
.
GL_REPEAT
);
/**
* {@link GLES20#GL_TEXTURE_MIN_FILTER}代表所显示的纹理比加载进来的纹理小时的情况
* {@link GLES20#GL_TEXTURE_MAG_FILTER}代表所显示的纹理比加载进来的纹理大时的情况
*
* {@link GLES20#GL_NEAREST}:使用纹理中坐标最接近的一个像素的颜色作为需要绘制的像素颜色
* {@link GLES20#GL_LINEAR}:使用纹理中坐标最接近的若干个颜色,通过加权平均算法得到需要绘制的像素颜色
*/
GLES20
.
glTexParameteri
(
GLES20
.
GL_TEXTURE_2D
,
GLES20
.
GL_TEXTURE_MIN_FILTER
,
GLES20
.
GL_NEAREST
);
GLES20
.
glTexParameteri
(
GLES20
.
GL_TEXTURE_2D
,
GLES20
.
GL_TEXTURE_MAG_FILTER
,
GLES20
.
GL_LINEAR
);
GLES20
.
glTexImage2D
(
GLES20
.
GL_TEXTURE_2D
,
0
,
format
,
width
,
height
,
0
,
format
,
GLES20
.
GL_UNSIGNED_BYTE
,
null
);
}
@Override
public
void
onDrawFrame
(
GL10
gl
)
{
// 分别对每个纹理做激活、绑定、设置数据操作
if
(
dataInput
)
{
//y
GLES20
.
glActiveTexture
(
GLES20
.
GL_TEXTURE0
);
GLES20
.
glBindTexture
(
GLES20
.
GL_TEXTURE_2D
,
yTexture
[
0
]);
GLES20
.
glTexSubImage2D
(
GLES20
.
GL_TEXTURE_2D
,
0
,
0
,
0
,
frameWidth
,
frameHeight
,
GLES20
.
GL_LUMINANCE
,
GLES20
.
GL_UNSIGNED_BYTE
,
yBuf
);
//u
GLES20
.
glActiveTexture
(
GLES20
.
GL_TEXTURE1
);
GLES20
.
glBindTexture
(
GLES20
.
GL_TEXTURE_2D
,
uTexture
[
0
]);
GLES20
.
glTexSubImage2D
(
GLES20
.
GL_TEXTURE_2D
,
0
,
0
,
0
,
frameWidth
>>
1
,
frameHeight
>>
1
,
GLES20
.
GL_LUMINANCE
,
GLES20
.
GL_UNSIGNED_BYTE
,
uBuf
);
//v
GLES20
.
glActiveTexture
(
GLES20
.
GL_TEXTURE2
);
GLES20
.
glBindTexture
(
GLES20
.
GL_TEXTURE_2D
,
vTexture
[
0
]);
GLES20
.
glTexSubImage2D
(
GLES20
.
GL_TEXTURE_2D
,
0
,
0
,
0
,
frameWidth
>>
1
,
frameHeight
>>
1
,
GLES20
.
GL_LUMINANCE
,
GLES20
.
GL_UNSIGNED_BYTE
,
vBuf
);
//在数据绑定完成后进行绘制
GLES20
.
glDrawArrays
(
GLES20
.
GL_TRIANGLE_STRIP
,
0
,
4
);
}
}
@Override
public
void
onSurfaceChanged
(
GL10
unused
,
int
width
,
int
height
)
{
GLES20
.
glViewport
(
0
,
0
,
width
,
height
);
}
}
/**
* 传入NV21刷新帧
*
* @param data NV21数据
*/
public
void
refreshFrameNV21
(
byte
[]
data
)
{
if
(
rendererReady
)
{
yBuf
.
clear
();
uBuf
.
clear
();
vBuf
.
clear
();
putNV21
(
data
,
frameWidth
,
frameHeight
);
dataInput
=
true
;
requestRender
();
}
}
/**
* 传入YV12数据刷新帧
*
* @param data YV12数据
*/
public
void
refreshFrameYV12
(
byte
[]
data
)
{
if
(
rendererReady
)
{
yBuf
.
clear
();
uBuf
.
clear
();
vBuf
.
clear
();
putYV12
(
data
,
frameWidth
,
frameHeight
);
dataInput
=
true
;
requestRender
();
}
}
/**
* 将NV21数据的Y、U、V分量取出
*
* @param src nv21帧数据
* @param width 宽度
* @param height 高度
*/
private
void
putNV21
(
byte
[]
src
,
int
width
,
int
height
)
{
int
ySize
=
width
*
height
;
int
frameSize
=
ySize
*
3
/
2
;
//取分量y值
System
.
arraycopy
(
src
,
0
,
yArray
,
0
,
ySize
);
int
k
=
0
;
//取分量uv值
int
index
=
ySize
;
while
(
index
<
frameSize
)
{
vArray
[
k
]
=
src
[
index
++];
uArray
[
k
++]
=
src
[
index
++];
}
yBuf
.
put
(
yArray
).
position
(
0
);
uBuf
.
put
(
vArray
).
position
(
0
);
vBuf
.
put
(
uArray
).
position
(
0
);
}
/**
* 将YV12数据的Y、U、V分量取出
*
* @param src YV12帧数据
* @param width 宽度
* @param height 高度
*/
private
void
putYV12
(
byte
[]
src
,
int
width
,
int
height
)
{
int
ySize
=
width
*
height
;
int
frameSize
=
ySize
*
3
/
2
;
//取分量y值
System
.
arraycopy
(
src
,
0
,
yArray
,
0
,
ySize
);
int
k
=
0
;
//取分量uv值
int
index
=
ySize
;
while
(
index
<
frameSize
)
{
vArray
[
k
]
=
src
[
index
++];
uArray
[
k
++]
=
src
[
index
++];
}
yBuf
.
put
(
yArray
).
position
(
0
);
uBuf
.
put
(
uArray
).
position
(
0
);
vBuf
.
put
(
vArray
).
position
(
0
);
}
}
app/src/main/java/com/intergration/avm/glsurface/GLUtils.java
0 → 100644
View file @
b97bd49c
package
com
.
intergration
.
avm
.
glsurface
;
import
android.opengl.GLES20
;
import
java.nio.IntBuffer
;
public
class
GLUtils
{
private
static
final
String
TAG
=
"GLUtils"
;
/**
* 顶点着色器
*/
private
static
String
VERTEX_SHADER
=
" attribute vec4 attr_position;\n"
+
" attribute vec2 attr_tc;\n"
+
" varying vec2 tc;\n"
+
" void main() {\n"
+
" gl_Position = attr_position;\n"
+
" tc = attr_tc;\n"
+
" }"
;
/**
* 片段着色器,正常效果
*/
public
static
String
FRAG_SHADER_NORMAL
=
"precision mediump float;\n"
+
" varying vec2 tc;\n"
+
" uniform sampler2D ySampler;\n"
+
" uniform sampler2D uSampler;\n"
+
" uniform sampler2D vSampler;\n"
+
" const mat3 convertMat = mat3(1.0, 1.0, 1.0, 0, -0.344, 1.77, 1.403, -0.714,0);\n"
+
" void main()\n"
+
" {\n"
+
" vec3 yuv;\n"
+
" yuv.x = texture2D(ySampler, tc).r;\n"
+
" yuv.y = texture2D(vSampler, tc).r - 0.5;\n"
+
" yuv.z = texture2D(uSampler, tc).r - 0.5;\n"
+
" gl_FragColor = vec4(convertMat * yuv, 1.0);\n"
+
" }"
;
/**
* 片段着色器,灰度效果。不需要 U V 数据(Java代码中可以做对应修改,仅需拷贝NV21数据中的Y分量即可)
*/
public
static
String
FRAG_SHADER_GRAY
=
"precision mediump float;\n"
+
" varying vec2 tc;\n"
+
" uniform sampler2D ySampler;\n"
+
" void main()\n"
+
" {\n"
+
" vec3 yuv;\n"
+
" yuv.x = texture2D(ySampler, tc).r;\n"
+
" gl_FragColor = vec4(vec3(yuv.x), 1.0);\n"
+
" }"
;
/**
* 片段着色器,浮雕效果。不需要 U V 数据(Java代码中可以做对应修改,仅需拷贝NV21数据中的Y分量即可)
*/
public
static
String
FRAG_SHADER_SCULPTURE
=
"precision mediump float;\n"
+
"varying vec2 tc;\n"
+
" uniform sampler2D ySampler;\n"
+
" const vec2 texSize = vec2(100.0, 100.0);\n"
+
" const vec4 sculptureColor = vec4(0.5, 0.5, 0.5, 1.0);\n"
+
"\n"
+
"void main()\n"
+
"{\n"
+
" vec2 upLeftCoord = vec2(tc.x-1.0/texSize.x, tc.y-1.0/texSize.y);\n"
+
" vec4 curColor = texture2D(ySampler, tc);\n"
+
" vec4 upLeftColor = texture2D(ySampler, upLeftCoord);\n"
+
" vec4 delColor = curColor - upLeftColor;\n"
+
" gl_FragColor = vec4(vec3(delColor), 0.0) + sculptureColor;\n"
+
"}"
;
//SQUARE_VERTICES每2个值作为一个顶点
static
final
int
COUNT_PER_SQUARE_VERTICE
=
2
;
//COORD_VERTICES每2个值作为一个顶点
static
final
int
COUNT_PER_COORD_VERTICES
=
2
;
/**
* 显示的顶点
*/
static
final
float
[]
SQUARE_VERTICES
=
{
-
1.0f
,
-
1.0f
,
1.0f
,
-
1.0f
,
-
1.0f
,
1.0f
,
1.0f
,
1.0f
};
/**
* 原数据显示
* 0,1***********1,1
* * *
* * *
* * *
* * *
* * *
* 0,0***********1,0
*/
static
final
float
[]
COORD_VERTICES
=
{
0.0f
,
1.0f
,
1.0f
,
1.0f
,
0.0f
,
0.0f
,
1.0f
,
0.0f
};
/**
* 逆时针旋转90度显示
* 1,1***********1,0
* * *
* * *
* * *
* * *
* * *
* 0,1***********0,0
*/
static
final
float
[]
ROTATE_90_COORD_VERTICES
=
{
1.0f
,
1.0f
,
1.0f
,
0.0f
,
0.0f
,
1.0f
,
0.0f
,
0.0f
};
/**
* 逆时针旋转180度显示
* 0,1***********1,1
* * *
* * *
* * *
* * *
* * *
* 0,0***********1,0
*/
static
final
float
[]
ROTATE_180_COORD_VERTICES
=
{
1.0f
,
0.0f
,
0.0f
,
0.0f
,
1.0f
,
1.0f
,
0.0f
,
1.0f
};
/**
* 逆时针旋转270度显示
* 0,1***********1,1
* * *
* * *
* * *
* * *
* * *
* 0,0***********1,0
*/
static
final
float
[]
ROTATE_270_COORD_VERTICES
=
{
0.0f
,
0.0f
,
0.0f
,
1.0f
,
1.0f
,
0.0f
,
1.0f
,
1.0f
};
/**
* 镜像显示
* 1,1***********0,1
* * *
* * *
* * *
* * *
* * *
* 1,0***********0,0
*/
static
final
float
[]
MIRROR_COORD_VERTICES
=
{
1.0f
,
1.0f
,
0.0f
,
1.0f
,
1.0f
,
0.0f
,
0.0f
,
0.0f
};
/**
* 镜像并逆时针旋转90度显示
* 0,1***********0,0
* * *
* * *
* * *
* * *
* * *
* 1,1***********1,0
*/
static
final
float
[]
ROTATE_90_MIRROR_COORD_VERTICES
=
{
0.0f
,
1.0f
,
0.0f
,
0.0f
,
1.0f
,
1.0f
,
1.0f
,
0.0f
};
/**
* 镜像并逆时针旋转180度显示
* 1,0***********0,0
* * *
* * *
* * *
* * *
* * *
* 1,1***********0,1
*/
static
final
float
[]
ROTATE_180_MIRROR_COORD_VERTICES
=
{
1.0f
,
0.0f
,
0.0f
,
0.0f
,
1.0f
,
1.0f
,
0.0f
,
1.0f
};
/**
* 镜像并逆时针旋转270度显示
* 1,0***********1,1
* * *
* * *
* * *
* * *
* * *
* 0,0***********0,1
*/
static
final
float
[]
ROTATE_270_MIRROR_COORD_VERTICES
=
{
1.0f
,
0.0f
,
1.0f
,
1.0f
,
0.0f
,
0.0f
,
0.0f
,
1.0f
};
/**
* 创建OpenGL Program,并链接
*
* @param fragmentShaderCode 片段着色器代码
* @return OpenGL Program对象的引用
*/
static
int
createShaderProgram
(
String
fragmentShaderCode
)
{
int
vertexShader
=
loadShader
(
GLES20
.
GL_VERTEX_SHADER
,
VERTEX_SHADER
);
int
fragmentShader
=
loadShader
(
GLES20
.
GL_FRAGMENT_SHADER
,
fragmentShaderCode
);
// 创建一个空的OpenGL ES Program
int
mProgram
=
GLES20
.
glCreateProgram
();
// 将vertex shader添加到program
GLES20
.
glAttachShader
(
mProgram
,
vertexShader
);
// 将fragment shader添加到program
GLES20
.
glAttachShader
(
mProgram
,
fragmentShader
);
// 链接创建好的 OpenGL ES program
GLES20
.
glLinkProgram
(
mProgram
);
// 检查链接状态
IntBuffer
linked
=
IntBuffer
.
allocate
(
1
);
GLES20
.
glGetProgramiv
(
mProgram
,
GLES20
.
GL_LINK_STATUS
,
linked
);
if
(
linked
.
get
(
0
)
==
0
)
{
return
-
1
;
}
return
mProgram
;
}
/**
* 加载着色器
*
* @param type 着色器类型,可以是片段着色器{@link GLES20#GL_FRAGMENT_SHADER}或顶点着色器{@link GLES20#GL_VERTEX_SHADER}
* @param shaderCode 着色器代码
* @return 着色器对象的引用
*/
private
static
int
loadShader
(
int
type
,
String
shaderCode
)
{
//创建空的shader
int
shader
=
GLES20
.
glCreateShader
(
type
);
//加载shader代码
GLES20
.
glShaderSource
(
shader
,
shaderCode
);
//编译shader
GLES20
.
glCompileShader
(
shader
);
//检查编译是否成功
IntBuffer
compiled
=
IntBuffer
.
allocate
(
1
);
GLES20
.
glGetShaderiv
(
shader
,
GLES20
.
GL_COMPILE_STATUS
,
compiled
);
if
(
compiled
.
get
(
0
)
==
0
)
{
return
0
;
}
return
shader
;
}
}
app/src/main/java/com/intergration/avm/presentation/AuxiliaryScreenPresentation.kt
View file @
b97bd49c
...
...
@@ -6,10 +6,12 @@ import android.os.Bundle
import
android.view.Display
import
android.widget.FrameLayout
import
com.intergration.avm.R
import
com.intergration.avm.glsurface.CameraGLSurfaceView
import
com.intergration.avm.glsurface.GLUtils
import
com.intergration.avm.glsurface.MyGLSurfaceView
import
com.intergration.avm.utils.IMAGE_HEIGHT
import
com.intergration.avm.utils.IMAGE_WIDTH
import
com.mediatek.smartplatform.PictureConfiguration
import
com.intergration.avm.glsurface.MyGLSurfaceView
class
AuxiliaryScreenPresentation
(
outerContext
:
Context
,
display
:
Display
)
:
Presentation
(
outerContext
,
display
)
{
...
...
@@ -18,15 +20,15 @@ class AuxiliaryScreenPresentation(outerContext: Context, display: Display) :
lateinit
var
frameLayout
:
FrameLayout
private
lateinit
var
rendererView
:
My
GLSurfaceView
private
lateinit
var
rendererView
:
Camera
GLSurfaceView
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
frameLayout
=
layoutInflater
.
inflate
(
R
.
layout
.
layout_presentation
,
null
)
as
FrameLayout
setContentView
(
frameLayout
)
rendererView
=
frameLayout
.
findViewById
<
MyGLSurfaceView
?>(
R
.
id
.
rendererView
).
also
{
it
.
setYuvDataSize
(
IMAGE_HEIGHT
,
IMAGE_WIDTH
)
}
rendererView
=
frameLayout
.
findViewById
(
R
.
id
.
rendererView
)
rendererView
.
setFragmentShaderCode
(
GLUtils
.
FRAG_SHADER_NORMAL
)
rendererView
.
init
(
true
,
0
,
IMAGE_HEIGHT
,
IMAGE_WIDTH
)
}
/**
...
...
@@ -59,17 +61,17 @@ class AuxiliaryScreenPresentation(outerContext: Context, display: Display) :
fun
feedData
(
data
:
ByteArray
){
rendererView
.
feedData
(
data
,
2
)
rendererView
.
refreshFrameNV21
(
data
)
}
@Synchronized
fun
setDisplayOrientation
(
degree
:
Int
){
rendererView
.
setDisplayOrientation
(
degree
)
}
//
@Synchronized
//
fun setDisplayOrientation(degree:Int){
//
rendererView.setDisplayOrientation(degree)
//
}
@Synchronized
fun
setYuvDataSize
(
width
:
Int
,
height
:
Int
){
rendererView
.
setYuvDataSize
(
width
,
height
)
}
//
@Synchronized
//
fun setYuvDataSize(width:Int,height:Int){
//
rendererView.setYuvDataSize(width,height)
//
}
}
\ No newline at end of file
app/src/main/java/com/intergration/avm/presentation/MultiScreenService.kt
View file @
b97bd49c
...
...
@@ -69,13 +69,13 @@ class MultiScreenService : Service() {
presentation
?.
feedData
(
data
)
}
fun
setDisplayOrientation
(
degree
:
Int
){
presentation
?.
setDisplayOrientation
(
270
)
}
fun
setYuvDataSize
(
width
:
Int
,
height
:
Int
){
presentation
?.
setYuvDataSize
(
width
,
height
)
}
//
fun setDisplayOrientation(degree:Int){
//
presentation?.setDisplayOrientation(270)
//
}
//
//
fun setYuvDataSize(width:Int,height:Int){
//
presentation?.setYuvDataSize(width,height)
//
}
inner
class
MultiScreenBinder
:
Binder
()
{
fun
getService
():
MultiScreenService
{
...
...
app/src/main/java/com/intergration/avm/utils/Utils.kt
View file @
b97bd49c
...
...
@@ -5,6 +5,7 @@ import android.content.Context
import
android.content.Intent
import
android.content.ServiceConnection
import
android.os.IBinder
import
android.text.style.LineHeightSpan
import
com.blankj.utilcode.util.LogUtils
import
com.blankj.utilcode.util.SPUtils
import
com.intergration.avm.presentation.MultiScreenService
...
...
@@ -61,7 +62,8 @@ fun Context.closeAuxiliaryPresentation(){
}
}
fun
feedData
(
data
:
ByteArray
){
fun
feedData
(
data
:
ByteArray
,
width
:
Int
=
0
,
height
:
Int
=
0
){
// multiScreenService?.setYuvDataSize(width = width,height = height)
multiScreenService
?.
feedNv21Data
(
data
)
}
app/src/main/res/layout/layout_presentation.xml
View file @
b97bd49c
...
...
@@ -9,8 +9,8 @@
android:textSize=
"24sp"
android:textColor=
"@android:color/holo_blue_light"
android:layout_gravity=
"center_horizontal|top"
/>
<com.intergration.avm.glsurface.
My
GLSurfaceView
<com.intergration.avm.glsurface.
Camera
GLSurfaceView
android:id=
"@+id/rendererView"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
android:layout_height=
"match_parent"
/>
</FrameLayout>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment