Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
HatsuneMikuFansYSQ
LYAVFoundation
提交
58f51ab0
L
LYAVFoundation
项目概览
HatsuneMikuFansYSQ
/
LYAVFoundation
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
LYAVFoundation
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
58f51ab0
编写于
8月 23, 2021
作者:
杨
杨时权
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
【需求】提交编码代码。
上级
8a373ef9
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
370 addition
and
19 deletion
+370
-19
project/iPhone/LWAVFoundation/LWAVFoundation.xcodeproj/project.pbxproj
...e/LWAVFoundation/LWAVFoundation.xcodeproj/project.pbxproj
+20
-6
project/iPhone/LWAVFoundation/LWAVFoundation/AVFoundation/LWAVConstValue.h
...AVFoundation/LWAVFoundation/AVFoundation/LWAVConstValue.h
+10
-0
project/iPhone/LWAVFoundation/LWAVFoundation/AVFoundation/LWVideoEncoder.h
...AVFoundation/LWAVFoundation/AVFoundation/LWVideoEncoder.h
+48
-0
project/iPhone/LWAVFoundation/LWAVFoundation/AVFoundation/LWVideoEncoder.m
...AVFoundation/LWAVFoundation/AVFoundation/LWVideoEncoder.m
+190
-0
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LWVideoCaptureConfig.h
...WAVFoundation/LWAVFoundation/Model/LWVideoCaptureConfig.h
+2
-7
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LWVideoEncoderConfig.h
...WAVFoundation/LWAVFoundation/Model/LWVideoEncoderConfig.h
+10
-1
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LWVideoEncoderConfig.m
...WAVFoundation/LWAVFoundation/Model/LWVideoEncoderConfig.m
+30
-0
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LWVideoOptions.h
...hone/LWAVFoundation/LWAVFoundation/Model/LWVideoOptions.h
+11
-0
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LWVideoOptions.m
...hone/LWAVFoundation/LWAVFoundation/Model/LWVideoOptions.m
+9
-0
project/iPhone/LWAVFoundation/LWAVFoundation/ViewController/CaptureViewController.m
...ion/LWAVFoundation/ViewController/CaptureViewController.m
+40
-5
未找到文件。
project/iPhone/LWAVFoundation/LWAVFoundation.xcodeproj/project.pbxproj
浏览文件 @
58f51ab0
...
...
@@ -20,9 +20,11 @@
A2847D7B26CF9E6500AF0E60
/* Author.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A2847D7A26CF9E6500AF0E60
/* Author.m */
;
};
A2847D8626CFB6BC00AF0E60
/* LWCheckBoxView.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A2847D8526CFB6BC00AF0E60
/* LWCheckBoxView.m */
;
};
A2847DB726D0BE1100AF0E60
/* LWCheckBoxButton.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A2847DB626D0BE1100AF0E60
/* LWCheckBoxButton.m */
;
};
A2847DBC26D0C7DA00AF0E60
/* LW
EncoderConfig.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A2847DBB26D0C7DA00AF0E60
/* LW
EncoderConfig.m */
;
};
A2847DBC26D0C7DA00AF0E60
/* LW
VideoEncoderConfig.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A2847DBB26D0C7DA00AF0E60
/* LWVideo
EncoderConfig.m */
;
};
A2847DC326D1FC2800AF0E60
/* LWVideoCaptureSession.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A2847DC226D1FC2800AF0E60
/* LWVideoCaptureSession.m */
;
};
A2847DC826D1FCF000AF0E60
/* LWVideoCaptureConfig.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A2847DC726D1FCF000AF0E60
/* LWVideoCaptureConfig.m */
;
};
A2847DF626D3849600AF0E60
/* LWVideoEncoder.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A2847DF526D3849500AF0E60
/* LWVideoEncoder.m */
;
};
A2847DFC26D387AC00AF0E60
/* LWVideoOptions.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A2847DFB26D387AC00AF0E60
/* LWVideoOptions.m */
;
};
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
...
...
@@ -49,12 +51,17 @@
A2847D8526CFB6BC00AF0E60
/* LWCheckBoxView.m */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.objc
;
path
=
LWCheckBoxView.m
;
sourceTree
=
"<group>"
;
};
A2847DB526D0BDF400AF0E60
/* LWCheckBoxButton.h */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
LWCheckBoxButton.h
;
sourceTree
=
"<group>"
;
};
A2847DB626D0BE1100AF0E60
/* LWCheckBoxButton.m */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.objc
;
path
=
LWCheckBoxButton.m
;
sourceTree
=
"<group>"
;
};
A2847DBA26D0C7C500AF0E60
/* LW
EncoderConfig.h */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
LW
EncoderConfig.h
;
sourceTree
=
"<group>"
;
};
A2847DBB26D0C7DA00AF0E60
/* LW
EncoderConfig.m */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.objc
;
path
=
LW
EncoderConfig.m
;
sourceTree
=
"<group>"
;
};
A2847DBA26D0C7C500AF0E60
/* LW
VideoEncoderConfig.h */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
LWVideo
EncoderConfig.h
;
sourceTree
=
"<group>"
;
};
A2847DBB26D0C7DA00AF0E60
/* LW
VideoEncoderConfig.m */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.objc
;
path
=
LWVideo
EncoderConfig.m
;
sourceTree
=
"<group>"
;
};
A2847DC126D1F83600AF0E60
/* LWVideoCaptureSession.h */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
LWVideoCaptureSession.h
;
sourceTree
=
"<group>"
;
};
A2847DC226D1FC2800AF0E60
/* LWVideoCaptureSession.m */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.objc
;
path
=
LWVideoCaptureSession.m
;
sourceTree
=
"<group>"
;
};
A2847DC626D1FCE400AF0E60
/* LWVideoCaptureConfig.h */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
LWVideoCaptureConfig.h
;
sourceTree
=
"<group>"
;
};
A2847DC726D1FCF000AF0E60
/* LWVideoCaptureConfig.m */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.objc
;
path
=
LWVideoCaptureConfig.m
;
sourceTree
=
"<group>"
;
};
A2847DF426D3848A00AF0E60
/* LWVideoEncoder.h */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
LWVideoEncoder.h
;
sourceTree
=
"<group>"
;
};
A2847DF526D3849500AF0E60
/* LWVideoEncoder.m */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.objc
;
path
=
LWVideoEncoder.m
;
sourceTree
=
"<group>"
;
};
A2847DFA26D3879E00AF0E60
/* LWVideoOptions.h */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
LWVideoOptions.h
;
sourceTree
=
"<group>"
;
};
A2847DFB26D387AC00AF0E60
/* LWVideoOptions.m */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.objc
;
path
=
LWVideoOptions.m
;
sourceTree
=
"<group>"
;
};
A2847E0026D38BF200AF0E60
/* LWAVConstValue.h */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
LWAVConstValue.h
;
sourceTree
=
"<group>"
;
};
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
...
...
@@ -123,10 +130,12 @@
children
=
(
A2847D7926CF9E5900AF0E60
/* Author.h */
,
A2847D7A26CF9E6500AF0E60
/* Author.m */
,
A2847DBA26D0C7C500AF0E60
/* LWEncoderConfig.h */
,
A2847DBB26D0C7DA00AF0E60
/* LWEncoderConfig.m */
,
A2847DBA26D0C7C500AF0E60
/* LW
Video
EncoderConfig.h */
,
A2847DBB26D0C7DA00AF0E60
/* LW
Video
EncoderConfig.m */
,
A2847DC626D1FCE400AF0E60
/* LWVideoCaptureConfig.h */
,
A2847DC726D1FCF000AF0E60
/* LWVideoCaptureConfig.m */
,
A2847DFA26D3879E00AF0E60
/* LWVideoOptions.h */
,
A2847DFB26D387AC00AF0E60
/* LWVideoOptions.m */
,
);
path
=
Model
;
sourceTree
=
"<group>"
;
...
...
@@ -147,6 +156,9 @@
children
=
(
A2847DC126D1F83600AF0E60
/* LWVideoCaptureSession.h */
,
A2847DC226D1FC2800AF0E60
/* LWVideoCaptureSession.m */
,
A2847DF426D3848A00AF0E60
/* LWVideoEncoder.h */
,
A2847DF526D3849500AF0E60
/* LWVideoEncoder.m */
,
A2847E0026D38BF200AF0E60
/* LWAVConstValue.h */
,
);
path
=
AVFoundation
;
sourceTree
=
"<group>"
;
...
...
@@ -223,6 +235,7 @@
files
=
(
A2847D8626CFB6BC00AF0E60
/* LWCheckBoxView.m in Sources */
,
A2847DC326D1FC2800AF0E60
/* LWVideoCaptureSession.m in Sources */
,
A2847DFC26D387AC00AF0E60
/* LWVideoOptions.m in Sources */
,
A2847B9626CE7B1D00AF0E60
/* ViewController.m in Sources */
,
A2847B9026CE7B1D00AF0E60
/* AppDelegate.m in Sources */
,
A2847D7B26CF9E6500AF0E60
/* Author.m in Sources */
,
...
...
@@ -230,9 +243,10 @@
A2847BA126CE7B1F00AF0E60
/* main.m in Sources */
,
A2847D7026CF5B3700AF0E60
/* HomeViewController.m in Sources */
,
A2847B9326CE7B1D00AF0E60
/* SceneDelegate.m in Sources */
,
A2847DBC26D0C7DA00AF0E60
/* LWEncoderConfig.m in Sources */
,
A2847DBC26D0C7DA00AF0E60
/* LW
Video
EncoderConfig.m in Sources */
,
A2847DB726D0BE1100AF0E60
/* LWCheckBoxButton.m in Sources */
,
A2847D7526CF9DD700AF0E60
/* CaptureViewController.m in Sources */
,
A2847DF626D3849600AF0E60
/* LWVideoEncoder.m in Sources */
,
);
runOnlyForDeploymentPostprocessing
=
0
;
};
...
...
project/iPhone/LWAVFoundation/LWAVFoundation/AVFoundation/LWAVConstValue.h
0 → 100644
浏览文件 @
58f51ab0
#ifndef LWAVConstValue_h
#define LWAVConstValue_h
typedef
NS_ENUM
(
NSUInteger
,
AVPixelBufferType
)
{
kAVCaptureOutputPixelBufferType_420v
=
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
,
kAVCaptureOutputPixelBufferType_420f
=
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
,
kAVCaptureOutputPixelBufferType_bgra
=
kCVPixelFormatType_32BGRA
,
};
#endif
/* LWAVConstValue_h */
project/iPhone/LWAVFoundation/LWAVFoundation/AVFoundation/LWVideoEncoder.h
0 → 100644
浏览文件 @
58f51ab0
#ifndef LWVideoEncoder_h
#define LWVideoEncoder_h
#import <AVFoundation/AVFoundation.h>
#import <VideoToolbox/VideoToolbox.h>
#import "LWVideoEncoderConfig.h"
typedef
NS_ENUM
(
NSUInteger
,
LWVideoEncodeStatus
)
{
kLWVideoEncodeStatus_Success
,
kLWVideoEncodeStatus_Err_Create
,
kLWVideoEncodeStatus_Err_Config
,
kLWVideoEncodeStatus_Err_Encode
,
kLWVideoEncodeStatus_Err_NO_Support
,
kLWVideoEncodeStatus_Err_NO_Initialized
,
kLWVideoEncodeStatus_Err_Invalid_Input
,
};
@protocol
LWVideoEncoderDelegate
<
NSObject
>
@required
-
(
void
)
onDidEncoded
:(
OSStatus
)
status
sourceFrameRef
:(
void
*
)
sourceFrameRef
info
:(
VTEncodeInfoFlags
)
infoFlags
sampleBuffer
:(
CMSampleBufferRef
)
sampleBuffer
;
@end
@interface
LWVideoEncoder
:
NSObject
@property
(
strong
,
readonly
,
nonatomic
)
LWVideoEncoderConfig
*
config
;
@property
(
weak
,
nonatomic
)
id
<
LWVideoEncoderDelegate
>
delegate
;
+
(
instancetype
)
newVideoEncoder
:(
LWVideoEncoderConfig
*
)
config
;
-
(
instancetype
)
initWithConfig
:(
LWVideoEncoderConfig
*
)
config
;
-
(
LWVideoEncodeStatus
)
encode
:(
CMSampleBufferRef
)
sampleBuffer
sourceFrameRef
:(
void
*
)
sourceFrameRef
;
-
(
LWVideoEncodeStatus
)
reconfig
:(
LWVideoEncoderConfig
*
)
config
;
-
(
LWVideoEncodeStatus
)
setOptionWithInt32
:(
NSString
*
)
key
value
:(
int32_t
)
value
;
-
(
LWVideoEncodeStatus
)
getOptionWithInt32
:(
NSString
*
)
key
value
:(
int32_t
*
)
value
;
@end
#endif
/* LWVideoEncoder_h */
project/iPhone/LWAVFoundation/LWAVFoundation/AVFoundation/LWVideoEncoder.m
0 → 100644
浏览文件 @
58f51ab0
#import <Foundation/Foundation.h>
#import "LWVideoEncoder.h"
@interface
LWVideoEncoder
()
{
VTCompressionSessionRef
_encoderSession
;
}
@end
@implementation
LWVideoEncoder
void
compressSessionOutputCallback
(
void
*
opaque
,
void
*
sourceFrameRef
,
OSStatus
compressStatus
,
VTEncodeInfoFlags
infoFlags
,
CMSampleBufferRef
sampleBuf
)
{
LWVideoEncoder
*
encoder
=
(
__bridge
LWVideoEncoder
*
)
opaque
;
if
(
encoder
&&
[
encoder
respondsToSelector
:
@selector
(
compressOutptuCallBack
:
status
:
info
:
sampleBuffer
:
)])
{
[
encoder
compressOutptuCallBack
:
sourceFrameRef
status
:
compressStatus
info
:
infoFlags
sampleBuffer
:
sampleBuf
];
}
}
+
(
instancetype
)
newVideoEncoder
:(
LWVideoEncoderConfig
*
)
config
{
return
[[
LWVideoEncoder
alloc
]
initWithConfig
:
config
];
}
-
(
instancetype
)
initWithConfig
:(
LWVideoEncoderConfig
*
)
config
{
if
(
self
=
[
super
init
])
{
if
([
self
createSession
:
config
]
!=
kLWVideoEncodeStatus_Success
)
{
return
nil
;
}
}
NSLog
(
@"%s:%d %@"
,
__func__
,
__LINE__
,
self
.
config
);
return
self
;
}
-
(
LWVideoEncodeStatus
)
encode
:(
CMSampleBufferRef
)
sampleBuffer
sourceFrameRef
:(
void
*
)
sourceFrameRef
{
if
(
!
sampleBuffer
)
{
return
kLWVideoEncodeStatus_Err_Invalid_Input
;
}
if
(
!
_encoderSession
)
{
return
kLWVideoEncodeStatus_Err_NO_Initialized
;
}
CMTime
pts
=
CMSampleBufferGetPresentationTimeStamp
(
sampleBuffer
);
CMTime
duration
=
CMSampleBufferGetDuration
(
sampleBuffer
);
CVImageBufferRef
pixelBuffer
=
CMSampleBufferGetImageBuffer
(
sampleBuffer
);
VTEncodeInfoFlags
infoFlags
=
0
;
OSStatus
status
=
VTCompressionSessionEncodeFrame
(
_encoderSession
,
pixelBuffer
,
pts
,
duration
,
nil
,
sourceFrameRef
,
&
infoFlags
);
if
(
status
!=
kCVReturnSuccess
)
{
if
(
status
==
kVTInvalidSessionErr
)
{
[
self
destroySession
];
[
self
createSession
:
self
.
config
];
}
return
kLWVideoEncodeStatus_Err_Encode
;
}
return
kLWVideoEncodeStatus_Success
;
}
-
(
void
)
dealloc
{
[
self
destroySession
];
}
#pragma mark private
-
(
LWVideoEncodeStatus
)
createSession
:(
LWVideoEncoderConfig
*
)
config
{
_config
=
config
;
OSStatus
status
=
0
;
// 生成相对应的sourceAttributes,用于配置编码器的ioSurface属性和输入文件格式。
long
pixelBufferType
=
self
.
config
.
pixelBufferType
;
CFDictionaryRef
ioSurfaceValue
=
CFDictionaryCreate
(
kCFAllocatorDefault
,
nil
,
nil
,
0
,
&
kCFTypeDictionaryKeyCallBacks
,
&
kCFTypeDictionaryValueCallBacks
);
CFTypeRef
pixelBufferFormatValue
=
(
__bridge
CFTypeRef
)
@
(
pixelBufferType
);
CFTypeRef
keys
[
3
]
=
{
kCVPixelBufferOpenGLESCompatibilityKey
,
kCVPixelBufferIOSurfacePropertiesKey
,
kCVPixelBufferPixelFormatTypeKey
};
CFTypeRef
values
[
3
]
=
{
kCFBooleanTrue
,
ioSurfaceValue
,
pixelBufferFormatValue
};
CFDictionaryRef
sourceAttributes
=
CFDictionaryCreate
(
kCFAllocatorDefault
,
keys
,
values
,
3
,
&
kCFTypeDictionaryKeyCallBacks
,
&
kCFTypeDictionaryValueCallBacks
);
if
(
ioSurfaceValue
)
{
CFRelease
(
ioSurfaceValue
);
ioSurfaceValue
=
nil
;
}
status
=
VTCompressionSessionCreate
(
nil
,
self
.
config
.
width
,
self
.
config
.
height
,
self
.
config
.
codecType
,
0
,
sourceAttributes
,
0
,
compressSessionOutputCallback
,
(
__bridge
void
*
_Nullable
)(
self
),
&
_encoderSession
);
if
(
sourceAttributes
)
{
CFRelease
(
sourceAttributes
);
sourceAttributes
=
nil
;
}
if
(
status
!=
kCVReturnSuccess
)
{
return
kLWVideoEncodeStatus_Err_Create
;
}
LWVideoEncodeStatus
result
=
[
self
configEncoder
];
return
result
;
}
-
(
void
)
destroySession
{
if
(
_encoderSession
)
{
VTCompressionSessionCompleteFrames
(
_encoderSession
,
kCMTimeInvalid
);
VTCompressionSessionInvalidate
(
_encoderSession
);
CFRelease
(
_encoderSession
);
_encoderSession
=
nil
;
}
NSLog
(
@"%s:%d"
,
__func__
,
__LINE__
);
}
-
(
LWVideoEncodeStatus
)
configEncoder
{
LWVideoEncodeStatus
status
=
kLWVideoEncodeStatus_Success
;
if
((
status
=
[
self
chooseProfileToEncoder
])
!=
kLWVideoEncodeStatus_Success
)
{
return
status
;
}
// 设置实时编码,打开,编码在低码率的情况下会有画质的亏损,严重情况下会出现马赛克,
// 不开启,编码在低码率的情况下依旧能保持一部分良好画质,但是会影响延时。
VTSessionSetProperty
(
_encoderSession
,
kVTCompressionPropertyKey_RealTime
,
self
.
config
.
useRealTime
?
kCFBooleanTrue
:
kCFBooleanFalse
);
// 是否使用B帧编码,打开,则使用,关闭,则不使用。
VTSessionSetProperty
(
_encoderSession
,
kVTCompressionPropertyKey_AllowFrameReordering
,
self
.
config
.
allowFrameReordering
?
kCFBooleanTrue
:
kCFBooleanFalse
);
// 只允许I帧编码,打开,则只会编码I帧,关闭,则会根据情况编码P帧和B帧。
VTSessionSetProperty
(
_encoderSession
,
kVTCompressionPropertyKey_AllowTemporalCompression
,
self
.
config
.
allowTemporalCompression
?
kCFBooleanTrue
:
kCFBooleanFalse
);
// 设置编码GOP大小
int
value
=
self
.
config
.
keyFrameInterval
*
self
.
config
.
framePerSecond
;
VTSessionSetProperty
(
_encoderSession
,
kVTCompressionPropertyKey_MaxKeyFrameInterval
,
(
__bridge
CFTypeRef
)
@
(
value
));
// 设置I帧的最大间隔,则value秒后必有一个I帧
value
=
self
.
config
.
keyFrameInterval
;
VTSessionSetProperty
(
_encoderSession
,
kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration
,
(
__bridge
CFTypeRef
)
@
(
value
));
[
self
setBitrate
:
self
.
config
.
bitrate
];
return
kLWVideoEncodeStatus_Success
;
}
-
(
LWVideoEncodeStatus
)
chooseProfileToEncoder
{
CFStringRef
profileStr
=
NULL
;
OSStatus
status
=
noErr
;
if
(
self
.
config
.
codecType
==
kCMVideoCodecType_H264
)
{
profileStr
=
kVTProfileLevel_H264_Baseline_AutoLevel
;
}
else
if
(
self
.
config
.
codecType
==
kCMVideoCodecType_HEVC
)
{
if
(
@available
(
iOS
11
.
0
,
*
))
{
profileStr
=
kVTProfileLevel_HEVC_Main_AutoLevel
;
}
}
if
(
profileStr
==
nil
)
{
return
kLWVideoEncodeStatus_Err_NO_Support
;
}
status
=
VTSessionSetProperty
(
_encoderSession
,
kVTCompressionPropertyKey_ProfileLevel
,
profileStr
);
if
(
status
!=
kCVReturnSuccess
)
{
return
kLWVideoEncodeStatus_Err_Config
;
}
NSLog
(
@"%s:%d choose encoder with profile(%s)"
,
__func__
,
__LINE__
,
CFStringGetCStringPtr
(
profileStr
,
kCFStringEncodingUTF8
));
return
kLWVideoEncodeStatus_Success
;
}
-
(
void
)
setBitrate
:(
int
)
bitrate
{
bitrate
=
bitrate
*
1024
;
VTSessionSetProperty
(
_encoderSession
,
kVTCompressionPropertyKey_AverageBitRate
,
(
__bridge
CFTypeRef
)
@
(
bitrate
));
}
#pragma mark callback
-
(
void
)
compressOutptuCallBack
:(
void
*
)
sourceFrameRef
status
:(
OSStatus
)
status
info
:(
VTEncodeInfoFlags
)
info
sampleBuffer
:(
CMSampleBufferRef
)
sampleBuffer
{
if
(
self
.
delegate
&&
[
self
.
delegate
respondsToSelector
:
@selector
(
onDidEncoded
:
sourceFrameRef
:
info
:
sampleBuffer
:
)])
{
[
self
.
delegate
onDidEncoded
:
status
sourceFrameRef
:
sourceFrameRef
info
:
info
sampleBuffer
:
sampleBuffer
];
}
}
@end
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LWVideoCaptureConfig.h
浏览文件 @
58f51ab0
...
...
@@ -2,12 +2,7 @@
#define LWCaptureConfig_h
#import <AVFoundation/AVFoundation.h>
typedef
NS_ENUM
(
NSUInteger
,
AVCaptureOutputPixelBufferType
)
{
kAVCaptureOutputPixelBufferType_420v
=
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
,
kAVCaptureOutputPixelBufferType_420f
=
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
,
kAVCaptureOutputPixelBufferType_bgra
=
kCVPixelFormatType_32BGRA
,
};
#import "LWAVConstValue.h"
@interface
LWVideoCaptureConfig
:
NSObject
...
...
@@ -18,7 +13,7 @@ typedef NS_ENUM(NSUInteger, AVCaptureOutputPixelBufferType) {
@property
(
assign
,
nonatomic
)
AVCaptureDevicePosition
position
;
// 指定输出的编码格式,有可能不支持
@property
(
assign
,
nonatomic
)
AV
CaptureOutput
PixelBufferType
pixelBufferType
;
@property
(
assign
,
nonatomic
)
AVPixelBufferType
pixelBufferType
;
// 视频的方向
@property
(
assign
,
nonatomic
)
AVCaptureVideoOrientation
orientation
;
...
...
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LWEncoderConfig.h
→
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LW
Video
EncoderConfig.h
浏览文件 @
58f51ab0
#ifndef LWEncoderConfig_h
#define LWEncoderConfig_h
@interface
LWEncoderConfig
:
NSObject
#import <VideoToolbox/VideoToolbox.h>
#import "LWAVConstValue.h"
@interface
LWVideoEncoderConfig
:
NSObject
// 启用相关编码,例如kCMVideoCodecType_H264或者kCMVideoCodecType_HEVC
@property
(
assign
,
nonatomic
)
CMVideoCodecType
codecType
;
// 视频的宽
@property
(
assign
,
nonatomic
)
int
width
;
...
...
@@ -27,6 +33,9 @@
// 是否开启P帧
@property
(
assign
,
nonatomic
)
BOOL
allowTemporalCompression
;
// 指定编码器的输入格式,必须与输入保持一致
@property
(
assign
,
nonatomic
)
AVPixelBufferType
pixelBufferType
;
+
(
instancetype
)
defaultConfig
;
-
(
instancetype
)
init
;
...
...
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LWEncoderConfig.m
→
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LW
Video
EncoderConfig.m
浏览文件 @
58f51ab0
#import <Foundation/Foundation.h>
#import "LWEncoderConfig.h"
#import "LW
Video
EncoderConfig.h"
@interface
LWEncoderConfig
()
@interface
LW
Video
EncoderConfig
()
@end
@implementation
LWEncoderConfig
@implementation
LW
Video
EncoderConfig
+
(
instancetype
)
defaultConfig
{
LW
EncoderConfig
*
config
=
[
LW
EncoderConfig
new
];
LW
VideoEncoderConfig
*
config
=
[
LWVideo
EncoderConfig
new
];
config
.
allowFrameReordering
=
YES
;
config
.
allowTemporalCompression
=
YES
;
config
.
useRealTime
=
NO
;
config
.
keyFrameInterval
=
3
;
config
.
codecType
=
kCMVideoCodecType_H264
;
return
config
;
}
-
(
instancetype
)
init
{
if
(
self
=
[
super
init
])
{
}
return
self
;
}
-
(
NSString
*
)
description
{
return
[
NSString
stringWithFormat
:
@"config{width:%d,height:%d,fps:%d,bitrate:%d,keyFrameInterval:%d,useRealTime:%d,allowFrameReordering:%d,allowTemporalCompression:%d}"
,
self
.
width
,
self
.
height
,
self
.
framePerSecond
,
self
.
bitrate
,
self
.
keyFrameInterval
,
self
.
useRealTime
,
self
.
allowFrameReordering
,
self
.
allowTemporalCompression
];;
}
@end
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LWVideoOptions.h
0 → 100644
浏览文件 @
58f51ab0
#ifndef LWVideoOptions_h
#define LWVideoOptions_h
extern
const
NSString
*
kLWVideoOptions_Width
;
extern
const
NSString
*
kLWVideoOptions_Height
;
extern
const
NSString
*
kLWVideoOptions_Bitrate
;
extern
const
NSString
*
kLWVideoOptions_FramePerSecond
;
extern
const
NSString
*
kLWVideoEncoderOptions_ForceKeyFrame
;
#endif
/* LWVideoEncoderOptions_h */
project/iPhone/LWAVFoundation/LWAVFoundation/Model/LWVideoOptions.m
0 → 100644
浏览文件 @
58f51ab0
#import <Foundation/Foundation.h>
#import "LWVideoOptions.h"
const
NSString
*
kLWVideoOptions_Width
=
@"kLWVideoOptions_Width"
;
const
NSString
*
kLWVideoOptions_Height
=
@"kLWVideoOptions_Height"
;
const
NSString
*
kLWVideoOptions_Bitrate
=
@"kLWVideoOptions_Bitrate"
;
const
NSString
*
kLWVideoOptions_FramePerSecond
=
@"kLWVideoOptions_FramePerSecond"
;
const
NSString
*
kLWVideoEncoderOptions_ForceKeyFrame
=
@"kLWVideoEncoderOptions_ForceKeyFrame"
;
project/iPhone/LWAVFoundation/LWAVFoundation/ViewController/CaptureViewController.m
浏览文件 @
58f51ab0
...
...
@@ -3,8 +3,9 @@
#import "CaptureViewController.h"
#import "LWCheckBoxView.h"
#import "LWVideoCaptureSession.h"
#import "LWVideoEncoder.h"
@interface
CaptureViewController
()
<
LWVideoCaptureSessionDelegate
,
LWCheckBoxViewDelegate
>
@interface
CaptureViewController
()
<
LWVideoCaptureSessionDelegate
,
LWCheckBoxViewDelegate
,
LWVideoEncoderDelegate
>
@property
(
strong
,
nonatomic
)
UIView
*
displayView
;
@property
(
strong
,
nonatomic
)
LWCheckBoxView
*
checkBoxView
;
@property
(
strong
,
nonatomic
)
UILabel
*
captureTypeLabel
;
...
...
@@ -13,6 +14,11 @@
@property
(
strong
,
nonatomic
)
LWVideoCaptureConfig
*
captureSessionConfig
;
@property
(
strong
,
nonatomic
)
LWVideoCaptureSession
*
captureSession
;
@property
(
strong
,
nonatomic
)
LWVideoEncoderConfig
*
encoderConfig
;
@property
(
strong
,
nonatomic
)
LWVideoEncoder
*
encoder
;
@property
(
strong
,
nonatomic
)
UIColor
*
hatsuneMiKuColor
;
@end
@implementation
CaptureViewController
...
...
@@ -22,6 +28,7 @@
int
displayViewY
=
20
;
int
displayViewW
=
[
UIScreen
mainScreen
].
bounds
.
size
.
width
;
int
displayViewH
=
displayViewW
/
16
*
9
;
self
.
hatsuneMiKuColor
=
[
UIColor
colorWithRed
:(
0x39
*
1
.
0
/
0xff
)
green
:(
0xc5
*
1
.
0
/
0xff
)
blue
:
(
0xbb
*
1
.
0
/
0xff
)
alpha
:
1
.
0
];
self
.
displayView
=
[[
UIView
alloc
]
initWithFrame
:
CGRectMake
(
displayViewX
,
displayViewY
,
displayViewW
,
displayViewH
)];
self
.
displayView
.
backgroundColor
=
[
UIColor
blackColor
];
[
self
.
view
addSubview
:
self
.
displayView
];
...
...
@@ -49,17 +56,27 @@
// self.startBtn.enabled = YES;
[
self
.
startBtn
setTitle
:
@"start"
forState
:
UIControlStateNormal
];
[
self
.
startBtn
setTitleColor
:[
UIColor
blackColor
]
forState
:
UIControlStateNormal
];
[
self
.
startBtn
setBackgroundColor
:
[
UIColor
whiteColor
]
];
[
self
.
startBtn
setBackgroundColor
:
self
.
hatsuneMiKuColor
];
[
self
.
startBtn
addTarget
:
self
action
:
@selector
(
startSender
:
)
forControlEvents
:
UIControlEventTouchUpInside
];
[
self
.
startBtn
.
layer
setMasksToBounds
:
YES
];
[
self
.
startBtn
.
layer
setCornerRadius
:
4
.
0
];
[
self
.
startBtn
.
layer
setBorderWidth
:
1
.
0
];
[
self
.
startBtn
.
layer
setBorderColor
:[
UIColor
blackColor
].
CGColor
];
[
self
.
view
addSubview
:
self
.
startBtn
];
self
.
stopBtn
=
[[
UIButton
alloc
]
initWithFrame
:
CGRectMake
([
UIScreen
mainScreen
].
bounds
.
size
.
width
/
2
,
checkBoxViewY
+
checkBoxViewH
+
10
,
[
UIScreen
mainScreen
].
bounds
.
size
.
width
/
2
,
30
)];
// self.startBtn.enabled = YES;
[
self
.
stopBtn
setTitle
:
@"stop"
forState
:
UIControlStateNormal
];
[
self
.
stopBtn
setTitleColor
:[
UIColor
blackColor
]
forState
:
UIControlStateNormal
];
[
self
.
stopBtn
setBackgroundColor
:
[
UIColor
whiteColor
]
];
[
self
.
stopBtn
setBackgroundColor
:
self
.
hatsuneMiKuColor
];
[
self
.
stopBtn
addTarget
:
self
action
:
@selector
(
stopSender
:
)
forControlEvents
:
UIControlEventTouchUpInside
];
[
self
.
stopBtn
.
layer
setMasksToBounds
:
YES
];
[
self
.
stopBtn
.
layer
setCornerRadius
:
4
.
0
];
[
self
.
stopBtn
.
layer
setBorderWidth
:
1
.
0
];
[
self
.
stopBtn
.
layer
setBorderColor
:[
UIColor
blackColor
].
CGColor
];
[
self
.
view
addSubview
:
self
.
stopBtn
];
self
.
captureSessionConfig
=
[[
LWVideoCaptureConfig
alloc
]
init
];
}
-
(
void
)
viewDidDisappear
:(
BOOL
)
animated
{
...
...
@@ -67,8 +84,8 @@
}
-
(
IBAction
)
startSender
:(
id
)
sender
{
self
.
captureSessionConfig
=
[[
LWVideoCaptureConfig
alloc
]
init
];
self
.
captureSession
=
[[
LWVideoCaptureSession
alloc
]
initWithConfig
:
self
.
captureSessionConfig
];
self
.
captureSession
.
delegate
=
self
;
[
self
.
captureSession
startCapture
];
...
...
@@ -76,6 +93,14 @@
layer
.
frame
=
CGRectMake
(
0
,
0
,
self
.
displayView
.
frame
.
size
.
width
,
self
.
displayView
.
frame
.
size
.
height
);
layer
.
videoGravity
=
AVLayerVideoGravityResizeAspectFill
;
[
self
.
displayView
.
layer
addSublayer
:
layer
];
self
.
encoderConfig
=
[
LWVideoEncoderConfig
defaultConfig
];
self
.
encoderConfig
.
width
=
1280
;
self
.
encoderConfig
.
height
=
720
;
self
.
encoderConfig
.
framePerSecond
=
30
;
self
.
encoderConfig
.
bitrate
=
2000
;
self
.
encoder
=
[
LWVideoEncoder
newVideoEncoder
:
self
.
encoderConfig
];
self
.
encoder
.
delegate
=
self
;
}
-
(
IBAction
)
stopSender
:(
id
)
sender
{
...
...
@@ -86,11 +111,14 @@
[
self
.
captureSession
stopCapture
];
self
.
captureSession
=
nil
;
self
.
encoder
=
nil
;
}
#pragma mark LWVideoCaptureSessionDelegate
-
(
void
)
onVideoWithSampleBuffer
:(
CMSampleBufferRef
)
sampleBuffer
{
if
(
self
.
encoder
)
{
[
self
.
encoder
encode
:
sampleBuffer
sourceFrameRef
:
nil
];
}
}
#pragma mark LWCheckBoxViewDelegate
...
...
@@ -102,4 +130,11 @@
}
}
#pragma mark LWVideoEncoderDelegate
-
(
void
)
onDidEncoded
:(
OSStatus
)
status
sourceFrameRef
:(
void
*
)
sourceFrameRef
info
:(
VTEncodeInfoFlags
)
infoFlags
sampleBuffer
:(
CMSampleBufferRef
)
sampleBuffer
{
}
@end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录