mirror of
https://github.com/pion/mediadevices.git
synced 2025-09-27 21:02:17 +08:00
Compare commits
9 Commits
v0.3.8
...
fork-v0.3.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f5e42ede9c | ||
![]() |
0a1b59cbc3 | ||
![]() |
6e80ae05a6 | ||
![]() |
bb19442836 | ||
![]() |
96d6c18c1f | ||
![]() |
25525f97c0 | ||
![]() |
916b1c483f | ||
![]() |
524bf8faad | ||
![]() |
8a2dfcd5ba |
3
go.mod
3
go.mod
@@ -2,12 +2,13 @@ module github.com/pion/mediadevices
|
||||
|
||||
go 1.13
|
||||
|
||||
replace github.com/pion/webrtc/v3 => github.com/EmrysMyrddin/webrtc/v3 v3.1.25-0.20220301142221-d92d68ff068f
|
||||
|
||||
require (
|
||||
github.com/blackjack/webcam v0.0.0-20220329180758-ba064708e165
|
||||
github.com/gen2brain/malgo v0.10.35
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/kbinani/screenshot v0.0.0-20210720154843-7d3a670d8329
|
||||
github.com/pion/interceptor v0.1.10
|
||||
github.com/pion/logging v0.2.2
|
||||
github.com/pion/rtcp v1.2.9
|
||||
github.com/pion/rtp v1.7.13
|
||||
|
22
go.sum
22
go.sum
@@ -1,3 +1,5 @@
|
||||
github.com/EmrysMyrddin/webrtc/v3 v3.1.25-0.20220301142221-d92d68ff068f h1:o7MCxR85nZxyOgjkmjtnXHsmPmchX3AEbWb/Bgpy3aI=
|
||||
github.com/EmrysMyrddin/webrtc/v3 v3.1.25-0.20220301142221-d92d68ff068f/go.mod h1:mO/yv7fBN3Lp7YNlnYcTj1jtpvNvssJG+7eh6itZ4xM=
|
||||
github.com/blackjack/webcam v0.0.0-20220329180758-ba064708e165 h1:QsIbRyO2tn5eSJZ/skuDqSTo0GWI5H4G1AT7Mm2H0Nw=
|
||||
github.com/blackjack/webcam v0.0.0-20220329180758-ba064708e165/go.mod h1:G0X+rEqYPWSq0dG8OMf8M446MtKytzpPjgS3HbdOJZ4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -49,12 +51,13 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/pion/datachannel v1.5.2 h1:piB93s8LGmbECrpO84DnkIVWasRMk3IimbcXkTQLE6E=
|
||||
github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ=
|
||||
github.com/pion/dtls/v2 v2.1.2/go.mod h1:o6+WvyLDAlXF7YiPB/RlskRoeK+/JtuaZa5emwQcWus=
|
||||
github.com/pion/dtls/v2 v2.1.3 h1:3UF7udADqous+M2R5Uo2q/YaP4EzUoWKdfX2oscCUio=
|
||||
github.com/pion/dtls/v2 v2.1.3/go.mod h1:o6+WvyLDAlXF7YiPB/RlskRoeK+/JtuaZa5emwQcWus=
|
||||
github.com/pion/ice/v2 v2.2.6 h1:R/vaLlI1J2gCx141L5PEwtuGAGcyS6e7E0hDeJFq5Ig=
|
||||
github.com/pion/ice/v2 v2.2.6/go.mod h1:SWuHiOGP17lGromHTFadUe1EuPgFh/oCU6FCMZHooVE=
|
||||
github.com/pion/interceptor v0.1.10 h1:DJ2GjMGm4XGIQgMJxuEpdaExdY/6RdngT7Uh4oVmquU=
|
||||
github.com/pion/interceptor v0.1.10/go.mod h1:Lh3JSl/cbJ2wP8I3ccrjh1K/deRGRn3UlSPuOTiHb6U=
|
||||
github.com/pion/ice/v2 v2.2.1 h1:R3MeuJZpU1ty3diPqpD5OxaxcZ15eprAc+EtUiSoFxg=
|
||||
github.com/pion/ice/v2 v2.2.1/go.mod h1:Op8jlPtjeiycsXh93Cs4jK82C9j/kh7vef6ztIOvtIQ=
|
||||
github.com/pion/interceptor v0.1.7 h1:HThW0tIIKT9RRoDWGURe8rlZVOx0fJHxBHpA0ej0+bo=
|
||||
github.com/pion/interceptor v0.1.7/go.mod h1:Lh3JSl/cbJ2wP8I3ccrjh1K/deRGRn3UlSPuOTiHb6U=
|
||||
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
|
||||
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
|
||||
github.com/pion/mdns v0.0.5 h1:Q2oj/JB3NqfzY9xGZ1fPzZzK7sDSD8rZPOvcIQ10BCw=
|
||||
@@ -85,24 +88,20 @@ github.com/pion/turn/v2 v2.0.8 h1:KEstL92OUN3k5k8qxsXHpr7WWfrdp7iJZHx99ud8muw=
|
||||
github.com/pion/turn/v2 v2.0.8/go.mod h1:+y7xl719J8bAEVpSXBXvTxStjJv3hbz9YFflvkpcGPw=
|
||||
github.com/pion/udp v0.1.1 h1:8UAPvyqmsxK8oOjloDk4wUt63TzFe9WEJkg5lChlj7o=
|
||||
github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M=
|
||||
github.com/pion/webrtc/v3 v3.1.34 h1:GUfv2zxWge77x1FhZ6Fge8KQd3bTzvX1CMN1/LmTazM=
|
||||
github.com/pion/webrtc/v3 v3.1.34/go.mod h1:jClfnbJzt8wtmewGxhPzgE5wZ0U/gNB78XCtmc/uz3k=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 h1:71vQrMauZZhcTVK6KdYM+rklehEEwb3E+ZhaE5jrPrE=
|
||||
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82 h1:KpZB5pUSBvrHltNEdK/tw0xlPeD13M6M6aGP32gKqiw=
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -116,9 +115,8 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220401154927-543a649e0bdd h1:zYlwaUHTmxuf6H7hwO2dgwqozQmH7zf4x+/qql4oVWc=
|
||||
golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@@ -21,26 +21,29 @@ Encoder *enc_new(const EncoderOptions opts, int *eresult) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
params.iUsageType = opts.usage_type;
|
||||
// TODO: Remove hardcoded values
|
||||
params.iUsageType = CAMERA_VIDEO_REAL_TIME;
|
||||
params.iPicWidth = opts.width;
|
||||
params.iPicHeight = opts.height;
|
||||
params.iTargetBitrate = opts.target_bitrate;
|
||||
params.iMaxBitrate = opts.target_bitrate;
|
||||
params.iRCMode = opts.rc_mode;
|
||||
params.iRCMode = RC_BITRATE_MODE;
|
||||
params.fMaxFrameRate = opts.max_fps;
|
||||
params.bEnableFrameSkip = opts.enable_frame_skip;
|
||||
params.uiMaxNalSize = opts.max_nal_size;
|
||||
params.uiIntraPeriod = opts.intra_period;
|
||||
params.iMultipleThreadIdc = opts.multiple_thread_idc;
|
||||
params.bEnableFrameSkip = true;
|
||||
params.uiMaxNalSize = 0;
|
||||
params.uiIntraPeriod = 30;
|
||||
// set to 0, so that it'll automatically use multi threads when needed
|
||||
params.iMultipleThreadIdc = 0;
|
||||
// The base spatial layer 0 is the only one we use.
|
||||
params.sSpatialLayers[0].iVideoWidth = params.iPicWidth;
|
||||
params.sSpatialLayers[0].iVideoHeight = params.iPicHeight;
|
||||
params.sSpatialLayers[0].fFrameRate = params.fMaxFrameRate;
|
||||
params.sSpatialLayers[0].iSpatialBitrate = params.iTargetBitrate;
|
||||
params.sSpatialLayers[0].iMaxSpatialBitrate = params.iTargetBitrate;
|
||||
params.sSpatialLayers[0].sSliceArgument.uiSliceNum = opts.slice_num;
|
||||
params.sSpatialLayers[0].sSliceArgument.uiSliceMode = opts.slice_mode;
|
||||
params.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = opts.slice_size_constraint;
|
||||
// Single NAL unit mode
|
||||
params.sSpatialLayers[0].sSliceArgument.uiSliceNum = 1;
|
||||
params.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_SIZELIMITED_SLICE;
|
||||
params.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 12800;
|
||||
|
||||
rv = engine->InitializeExt(¶ms);
|
||||
if (rv != 0) {
|
||||
|
@@ -22,15 +22,6 @@ typedef struct EncoderOptions {
|
||||
int width, height;
|
||||
int target_bitrate;
|
||||
float max_fps;
|
||||
EUsageType usage_type;
|
||||
RC_MODES rc_mode;
|
||||
bool enable_frame_skip;
|
||||
unsigned int max_nal_size;
|
||||
unsigned int intra_period;
|
||||
int multiple_thread_idc;
|
||||
unsigned int slice_num;
|
||||
SliceModeEnum slice_mode;
|
||||
unsigned int slice_size_constraint;
|
||||
} EncoderOptions;
|
||||
|
||||
typedef struct Encoder {
|
||||
|
@@ -33,19 +33,10 @@ func newEncoder(r video.Reader, p prop.Media, params Params) (codec.ReadCloser,
|
||||
|
||||
var rv C.int
|
||||
cEncoder := C.enc_new(C.EncoderOptions{
|
||||
width: C.int(p.Width),
|
||||
height: C.int(p.Height),
|
||||
target_bitrate: C.int(params.BitRate),
|
||||
max_fps: C.float(p.FrameRate),
|
||||
usage_type: C.EUsageType(params.UsageType),
|
||||
rc_mode: C.RC_MODES(params.RCMode),
|
||||
enable_frame_skip: C.bool(params.EnableFrameSkip),
|
||||
max_nal_size: C.uint(params.MaxNalSize),
|
||||
intra_period: C.uint(params.IntraPeriod),
|
||||
multiple_thread_idc: C.int(params.MultipleThreadIdc),
|
||||
slice_num: C.uint(params.SliceNum),
|
||||
slice_mode: C.SliceModeEnum(params.SliceMode),
|
||||
slice_size_constraint: C.uint(params.SliceSizeConstraint),
|
||||
width: C.int(p.Width),
|
||||
height: C.int(p.Height),
|
||||
target_bitrate: C.int(params.BitRate),
|
||||
max_fps: C.float(p.FrameRate),
|
||||
}, &rv)
|
||||
if err := errResult(rv); err != nil {
|
||||
return nil, fmt.Errorf("failed in creating encoder: %v", err)
|
||||
|
@@ -1,8 +1,5 @@
|
||||
package openh264
|
||||
|
||||
// #include <openh264/codec_api.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/pion/mediadevices/pkg/codec"
|
||||
"github.com/pion/mediadevices/pkg/io/video"
|
||||
@@ -12,62 +9,14 @@ import (
|
||||
// Params stores libopenh264 specific encoding parameters.
|
||||
type Params struct {
|
||||
codec.BaseParams
|
||||
UsageType UsageTypeEnum
|
||||
RCMode RCModeEnum
|
||||
EnableFrameSkip bool
|
||||
MaxNalSize uint
|
||||
IntraPeriod uint
|
||||
MultipleThreadIdc int
|
||||
SliceNum uint
|
||||
SliceMode SliceModeEnum
|
||||
SliceSizeConstraint uint
|
||||
}
|
||||
|
||||
type UsageTypeEnum int
|
||||
|
||||
const (
|
||||
CameraVideoRealTime UsageTypeEnum = C.CAMERA_VIDEO_REAL_TIME ///< camera video for real-time communication
|
||||
ScreenContentRealTime UsageTypeEnum = C.SCREEN_CONTENT_REAL_TIME ///< screen content signal
|
||||
CameraVideoNonRealTime UsageTypeEnum = C.CAMERA_VIDEO_NON_REAL_TIME
|
||||
ScreenContentNonRealTime UsageTypeEnum = C.SCREEN_CONTENT_NON_REAL_TIME
|
||||
InputContentTypeAll UsageTypeEnum = C.INPUT_CONTENT_TYPE_ALL
|
||||
)
|
||||
|
||||
type RCModeEnum int
|
||||
|
||||
const (
|
||||
RCQualityMode RCModeEnum = C.RC_QUALITY_MODE ///< quality mode
|
||||
RCBitrateMode RCModeEnum = C.RC_BITRATE_MODE ///< bitrate mode
|
||||
RCBufferbaseedMode RCModeEnum = C.RC_BUFFERBASED_MODE ///< no bitrate control,only using buffer status,adjust the video quality
|
||||
RCTimestampMode RCModeEnum = C.RC_TIMESTAMP_MODE //rate control based timestamp
|
||||
RCBitrateModePostSkip RCModeEnum = C.RC_BITRATE_MODE_POST_SKIP ///< this is in-building RC MODE, WILL BE DELETED after algorithm tuning!
|
||||
RCOffMode RCModeEnum = C.RC_OFF_MODE ///< rate control off mode
|
||||
)
|
||||
|
||||
type SliceModeEnum uint
|
||||
|
||||
const (
|
||||
SMSingleSlice SliceModeEnum = C.SM_SINGLE_SLICE ///< | SliceNum==1
|
||||
SMFixedslcnumSlice SliceModeEnum = C.SM_FIXEDSLCNUM_SLICE ///< | according to SliceNum | enabled dynamic slicing for multi-thread
|
||||
SMRasterSlice SliceModeEnum = C.SM_RASTER_SLICE ///< | according to SlicesAssign | need input of MB numbers each slice. In addition, if other constraint in SSliceArgument is presented, need to follow the constraints. Typically if MB num and slice size are both constrained, re-encoding may be involved.
|
||||
SMSizelimitedSlice SliceModeEnum = C.SM_SIZELIMITED_SLICE ///< | according to SliceSize | slicing according to size, the slicing will be dynamic(have no idea about slice_nums until encoding current frame)
|
||||
)
|
||||
|
||||
// NewParams returns default openh264 codec specific parameters.
|
||||
func NewParams() (Params, error) {
|
||||
return Params{
|
||||
BaseParams: codec.BaseParams{
|
||||
BitRate: 100000,
|
||||
},
|
||||
UsageType: CameraVideoRealTime,
|
||||
RCMode: RCBitrateMode,
|
||||
EnableFrameSkip: true,
|
||||
MaxNalSize: 0,
|
||||
IntraPeriod: 30,
|
||||
MultipleThreadIdc: 0, // Defaults to 0, so that it'll automatically use multi threads when needed
|
||||
SliceNum: 1, // Defaults to single NAL unit mode
|
||||
SliceMode: SMSizelimitedSlice,
|
||||
SliceSizeConstraint: 12800,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@@ -541,7 +541,7 @@ func (e *encoderVP8) Read() ([]byte, func(), error) {
|
||||
return encoded, func() {}, err
|
||||
}
|
||||
|
||||
func (e *encoderVP8) Controller() codec.EncoderController {
|
||||
func (e *encoder) Controller() codec.EncoderController {
|
||||
return e
|
||||
}
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVP8ShouldImplementBitRateControl(t *testing.T) {
|
||||
func TestShouldImplementBitRateControl(t *testing.T) {
|
||||
t.SkipNow() // TODO: Implement bit rate control
|
||||
|
||||
e := &encoderVP8{}
|
||||
@@ -17,7 +17,7 @@ func TestVP8ShouldImplementBitRateControl(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestVP8ShouldImplementKeyFrameControl(t *testing.T) {
|
||||
func TestShouldImplementKeyFrameControl(t *testing.T) {
|
||||
t.SkipNow() // TODO: Implement key frame control
|
||||
|
||||
e := &encoderVP8{}
|
||||
|
@@ -476,7 +476,7 @@ func (e *encoderVP9) Read() ([]byte, func(), error) {
|
||||
return encoded, func() {}, err
|
||||
}
|
||||
|
||||
func (e *encoderVP9) Controller() codec.EncoderController {
|
||||
func (e *encoder) Controller() codec.EncoderController {
|
||||
return e
|
||||
}
|
||||
|
||||
|
@@ -3,12 +3,7 @@
|
||||
|
||||
package vaapi
|
||||
|
||||
import (
|
||||
"github.com/pion/mediadevices/pkg/codec"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVP9ShouldImplementBitRateControl(t *testing.T) {
|
||||
func TestShouldImplementBitRateControl(t *testing.T) {
|
||||
t.SkipNow() // TODO: Implement bit rate control
|
||||
|
||||
e := &encoderVP9{}
|
||||
@@ -17,7 +12,7 @@ func TestVP9ShouldImplementBitRateControl(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestVP9ShouldImplementKeyFrameControl(t *testing.T) {
|
||||
func TestShouldImplementKeyFrameControl(t *testing.T) {
|
||||
t.SkipNow() // TODO: Implement key frame control
|
||||
|
||||
e := &encoderVP9{}
|
||||
|
@@ -124,9 +124,6 @@ func (e *encoder) Read() ([]byte, func(), error) {
|
||||
return encoded, func() {}, err
|
||||
}
|
||||
|
||||
// TODO: Implement bit rate control
|
||||
//var _ codec.BitRateController = (*encoder)(nil)
|
||||
|
||||
func (e *encoder) ForceKeyFrame() error {
|
||||
e.engine.force_key_frame = C.int(1)
|
||||
return nil
|
||||
|
@@ -49,8 +49,6 @@ func TestEncoder(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestShouldImplementKeyFrameControl(t *testing.T) {
|
||||
t.SkipNow() // TODO: Implement key frame control
|
||||
|
||||
e := &encoder{}
|
||||
if _, ok := e.Controller().(codec.KeyFrameController); !ok {
|
||||
t.Error()
|
||||
|
22
track.go
22
track.go
@@ -3,7 +3,6 @@ package mediadevices
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/pion/interceptor"
|
||||
"github.com/pion/rtcp"
|
||||
"image"
|
||||
"io"
|
||||
@@ -222,7 +221,7 @@ func (track *baseTrack) bind(ctx webrtc.TrackLocalContext, specializedTrack Trac
|
||||
if ok {
|
||||
stopRead = make(chan struct{})
|
||||
go func() {
|
||||
reader := ctx.RTCPReader()
|
||||
reader := ctx.ReadStream()
|
||||
for {
|
||||
select {
|
||||
case <-stopRead:
|
||||
@@ -230,15 +229,12 @@ func (track *baseTrack) bind(ctx webrtc.TrackLocalContext, specializedTrack Trac
|
||||
default:
|
||||
}
|
||||
|
||||
var readerBuffer []byte
|
||||
_, _, err := reader.Read(readerBuffer, interceptor.Attributes{})
|
||||
pkts, _, err := reader.ReadRTCP()
|
||||
if err != nil {
|
||||
track.onError(err)
|
||||
return
|
||||
}
|
||||
|
||||
pkts, err := rtcp.Unmarshal(readerBuffer)
|
||||
|
||||
for _, pkt := range pkts {
|
||||
switch pkt.(type) {
|
||||
case *rtcp.PictureLossIndication, *rtcp.FullIntraRequest:
|
||||
@@ -299,7 +295,7 @@ func newTrackFromDriver(d driver.Driver, constraints MediaTrackConstraints, sele
|
||||
type VideoTrack struct {
|
||||
*baseTrack
|
||||
*video.Broadcaster
|
||||
shouldCopyFrames bool
|
||||
ShouldCopyFrames bool
|
||||
}
|
||||
|
||||
// NewVideoTrack constructs a new VideoTrack
|
||||
@@ -307,16 +303,6 @@ func NewVideoTrack(source VideoSource, selector *CodecSelector) Track {
|
||||
return newVideoTrackFromReader(source, source, selector)
|
||||
}
|
||||
|
||||
// ShouldCopyFrames indicates if readers on this track should receive a clopy of the read buffer instead of sharing one.
|
||||
func (track *VideoTrack) ShouldCopyFrames() bool {
|
||||
return track.shouldCopyFrames
|
||||
}
|
||||
|
||||
// SetShouldCopyFrames enables frame copy for this track, sending each reader a different read buffer instead of sharing one.
|
||||
func (track *VideoTrack) SetShouldCopyFrames(shouldCopyFrames bool) {
|
||||
track.shouldCopyFrames = shouldCopyFrames
|
||||
}
|
||||
|
||||
func newVideoTrackFromReader(source Source, reader video.Reader, selector *CodecSelector) Track {
|
||||
base := newBaseTrack(source, VideoInput, selector)
|
||||
wrappedReader := video.ReaderFunc(func() (img image.Image, release func(), err error) {
|
||||
@@ -361,7 +347,7 @@ func (track *VideoTrack) Unbind(ctx webrtc.TrackLocalContext) error {
|
||||
}
|
||||
|
||||
func (track *VideoTrack) newEncodedReader(codecNames ...string) (EncodedReadCloser, *codec.RTPCodec, error) {
|
||||
reader := track.NewReader(track.shouldCopyFrames)
|
||||
reader := track.NewReader(track.ShouldCopyFrames)
|
||||
inputProp, err := detectCurrentVideoProp(track.Broadcaster)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
Reference in New Issue
Block a user