mirror of
https://github.com/qrtc/ffmpeg-dev-go.git
synced 2025-10-04 15:23:13 +08:00
2023-10-17 15:38:39 CST W42D2
This commit is contained in:
11
README.md
11
README.md
@@ -8,15 +8,14 @@ Go bindings for FFmpeg.
|
||||
- macOS
|
||||
|
||||
```shell
|
||||
brew install ffmpeg
|
||||
brew install pkg-config ffmpeg
|
||||
```
|
||||
- Debian
|
||||
|
||||
```shell
|
||||
apt install \
|
||||
libavdevice-dev libavformat-dev libavfilter-dev \
|
||||
libavresample-dev libavcodec-dev libpostproc-dev \
|
||||
libswscale-dev libswresample-dev libavutil-dev
|
||||
sudo apt install build-essential pkg-config \
|
||||
libavdevice-dev libavformat-dev libavfilter-dev libavcodec-dev \
|
||||
libpostproc-dev libswscale-dev libswresample-dev libavutil-dev
|
||||
```
|
||||
- Custom
|
||||
|
||||
@@ -44,7 +43,7 @@ func main() {
|
||||
### Step 3: Get ffmpeg-go-dev
|
||||
|
||||
```shell
|
||||
go get github.com/qrtc/ffmpeg-dev-go@4.4
|
||||
go get github.com/qrtc/ffmpeg-dev-go@<FFMPEG_VERSION>
|
||||
```
|
||||
|
||||
### Step 4: Verify
|
||||
|
22
avcodec.go
22
avcodec.go
@@ -17,7 +17,7 @@ const (
|
||||
)
|
||||
|
||||
// AvDiscard
|
||||
type AvDiscard int32
|
||||
type AvDiscard = C.enum_AVDiscard
|
||||
|
||||
const (
|
||||
AVDISCARD_NONE = AvDiscard(C.AVDISCARD_NONE)
|
||||
@@ -30,7 +30,7 @@ const (
|
||||
)
|
||||
|
||||
// AvAudioServiceType
|
||||
type AvAudioServiceType int32
|
||||
type AvAudioServiceType = C.enum_AVAudioServiceType
|
||||
|
||||
const (
|
||||
AV_AUDIO_SERVICE_TYPE_MAIN = AvAudioServiceType(C.AV_AUDIO_SERVICE_TYPE_MAIN)
|
||||
@@ -215,8 +215,8 @@ func (avctx *AvCodecContext) SetPrivData(v unsafe.Pointer) {
|
||||
}
|
||||
|
||||
// Custom: GetPrivDataAddr gets `AVCodecContext.priv_data` address.
|
||||
func (avctx *AvCodecContext) GetPrivDataAddr() *unsafe.Pointer {
|
||||
return (*unsafe.Pointer)(&avctx.priv_data)
|
||||
func (avctx *AvCodecContext) GetPrivDataAddr() unsafe.Pointer {
|
||||
return (unsafe.Pointer)(&avctx.priv_data)
|
||||
}
|
||||
|
||||
// Custom: Get Opaque gets `AVCodecContext.opaque` value.
|
||||
@@ -230,8 +230,8 @@ func (avctx *AvCodecContext) SetOpaque(v unsafe.Pointer) {
|
||||
}
|
||||
|
||||
// Custom: GetOpaqueAddr gets `AVCodecContext.opaque` address.
|
||||
func (avctx *AvCodecContext) GetOpaqueAddr() *unsafe.Pointer {
|
||||
return (*unsafe.Pointer)(&avctx.opaque)
|
||||
func (avctx *AvCodecContext) GetOpaqueAddr() unsafe.Pointer {
|
||||
return (unsafe.Pointer)(&avctx.opaque)
|
||||
}
|
||||
|
||||
// Custom: Get BitRate gets `AVCodecContext.bit_rate` value.
|
||||
@@ -2176,8 +2176,8 @@ func (avctx *AvCodecContext) SetHwaccelContext(v unsafe.Pointer) {
|
||||
}
|
||||
|
||||
// Custom: GetHwaccelContextAddr gets `AVCodecContext.hwaccel_context` address.
|
||||
func (avctx *AvCodecContext) GetHwaccelContextAddr() *unsafe.Pointer {
|
||||
return (*unsafe.Pointer)(&avctx.hwaccel_context)
|
||||
func (avctx *AvCodecContext) GetHwaccelContextAddr() unsafe.Pointer {
|
||||
return (unsafe.Pointer)(&avctx.hwaccel_context)
|
||||
}
|
||||
|
||||
// Custom: Get DctAlgo gets `AVCodecContext.dct_algo` value.
|
||||
@@ -3168,7 +3168,7 @@ const (
|
||||
type AvPicture C.struct_AVPicture
|
||||
|
||||
// AvSubtitleType
|
||||
type AvSubtitleType int32
|
||||
type AvSubtitleType = C.enum_AVSubtitleType
|
||||
|
||||
const (
|
||||
SUBTITLE_NONE = AvSubtitleType(C.SUBTITLE_NONE)
|
||||
@@ -3377,7 +3377,7 @@ func AvCodecGetHwFramesParameters(avctx *AvCodecContext, deviceRef *AvBufferRef,
|
||||
}
|
||||
|
||||
// AvPictureStructure
|
||||
type AvPictureStructure int32
|
||||
type AvPictureStructure = C.enum_AVPictureStructure
|
||||
|
||||
const (
|
||||
AV_PICTURE_STRUCTURE_UNKNOWN = AvPictureStructure(C.AV_PICTURE_STRUCTURE_UNKNOWN)
|
||||
@@ -3706,7 +3706,7 @@ func AvHwaccelNext(hwaccel *AvHWAccel) *AvHWAccel {
|
||||
}
|
||||
|
||||
// AvLockOp
|
||||
type AvLockOp int32
|
||||
type AvLockOp = C.enum_AVLockOp
|
||||
|
||||
const (
|
||||
AV_LOCK_CREATE = AvLockOp(C.AV_LOCK_CREATE)
|
||||
|
@@ -59,7 +59,7 @@ func AvMdctEnd(s *FftContext) {
|
||||
C.av_mdct_end((*C.struct_FFTContext)(s))
|
||||
}
|
||||
|
||||
type RDFTransformType int32
|
||||
type RDFTransformType = C.enum_RDFTransformType
|
||||
|
||||
const (
|
||||
DFT_R2C = RDFTransformType(C.DFT_R2C)
|
||||
@@ -88,7 +88,7 @@ func AvRdftEnd(r *RDFTContext) {
|
||||
|
||||
type DCTContext C.struct_DCTContext
|
||||
|
||||
type DCTTransformType int32
|
||||
type DCTTransformType = C.enum_DCTTransformType
|
||||
|
||||
const (
|
||||
DCT_II = DCTTransformType(C.DCT_II)
|
||||
|
154
avcodec_bsf.go
154
avcodec_bsf.go
@@ -12,9 +12,163 @@ type AvBSFInternal C.struct_AVBSFInternal
|
||||
// AvBSFContext
|
||||
type AvBSFContext C.struct_AVBSFContext
|
||||
|
||||
// Custom: GetAvClass gets `AVBSFContext.av_class` value.
|
||||
func (bsfc *AvBSFContext) GetAvClass() *AvClass {
|
||||
return (*AvClass)(bsfc.av_class)
|
||||
}
|
||||
|
||||
// Custom: SetAvClass sets `AVBSFContext.av_class` value.
|
||||
func (bsfc *AvBSFContext) SetAvClass(v *AvClass) {
|
||||
bsfc.av_class = (*C.struct_AVClass)(v)
|
||||
}
|
||||
|
||||
// Custom: GetAvClassAddr gets `AVBSFContext.av_class` address.
|
||||
func (bsfc *AvBSFContext) GetAvClassAddr() **AvClass {
|
||||
return (**AvClass)(unsafe.Pointer(&bsfc.av_class))
|
||||
}
|
||||
|
||||
// Custom: GetFilter gets `AVBSFContext.filter` value.
|
||||
func (bsfc *AvBSFContext) GetFilter() *AvBitStreamFilter {
|
||||
return (*AvBitStreamFilter)(bsfc.filter)
|
||||
}
|
||||
|
||||
// Custom: SetFilter sets `AVBSFContext.filter` value.
|
||||
func (bsfc *AvBSFContext) SetFilter(v *AvBitStreamFilter) {
|
||||
bsfc.filter = (*C.struct_AVBitStreamFilter)(v)
|
||||
}
|
||||
|
||||
// Custom: GetFilterAddr gets `AVBSFContext.filter` address.
|
||||
func (bsfc *AvBSFContext) GetFilterAddr() **AvBitStreamFilter {
|
||||
return (**AvBitStreamFilter)(unsafe.Pointer(&bsfc.filter))
|
||||
}
|
||||
|
||||
// Custom: GetInternal gets `AVBSFContext.internal` value.
|
||||
func (bsfc *AvBSFContext) GetInternal() *AvBSFInternal {
|
||||
return (*AvBSFInternal)(bsfc.internal)
|
||||
}
|
||||
|
||||
// Custom: SetInternal sets `AVBSFContext.internal` value.
|
||||
func (bsfc *AvBSFContext) SetInternal(v *AvBSFInternal) {
|
||||
bsfc.internal = (*C.struct_AVBSFInternal)(v)
|
||||
}
|
||||
|
||||
// Custom: GetInternalAddr gets `AVBSFContext.internal` address.
|
||||
func (bsfc *AvBSFContext) GetInternalAddr() **AvBSFInternal {
|
||||
return (**AvBSFInternal)(unsafe.Pointer(&bsfc.internal))
|
||||
}
|
||||
|
||||
// Custom: GetPrivData gets `AVBSFContext.priv_data` value.
|
||||
func (bsfc *AvBSFContext) GetPrivData() unsafe.Pointer {
|
||||
return bsfc.priv_data
|
||||
}
|
||||
|
||||
// Custom: SetPrivData sets `AVBSFContext.priv_data` value.
|
||||
func (bsfc *AvBSFContext) SetPrivData(v unsafe.Pointer) {
|
||||
bsfc.priv_data = v
|
||||
}
|
||||
|
||||
// Custom: GetPrivDataAddr gets `AVBSFContext.priv_data` address.
|
||||
func (bsfc *AvBSFContext) GetPrivDataAddr() unsafe.Pointer {
|
||||
return (unsafe.Pointer)(&bsfc.priv_data)
|
||||
}
|
||||
|
||||
// Custom: GetParIn gets `AVBSFContext.par_in` value.
|
||||
func (bsfc *AvBSFContext) GetParIn() *AvCodecParameters {
|
||||
return (*AvCodecParameters)(bsfc.par_in)
|
||||
}
|
||||
|
||||
// Custom: SetParIn sets `AVBSFContext.par_in` value.
|
||||
func (bsfc *AvBSFContext) SetParIn(v *AvCodecParameters) {
|
||||
bsfc.par_in = (*C.struct_AVCodecParameters)(v)
|
||||
}
|
||||
|
||||
// Custom: GetParInAddr gets `AVBSFContext.par_in` address.
|
||||
func (bsfc *AvBSFContext) GetParInAddr() **AvCodecParameters {
|
||||
return (**AvCodecParameters)(unsafe.Pointer(&bsfc.par_in))
|
||||
}
|
||||
|
||||
// Custom: GetParOut gets `AVBSFContext.par_out` value.
|
||||
func (bsfc *AvBSFContext) GetParOut() *AvCodecParameters {
|
||||
return (*AvCodecParameters)(bsfc.par_out)
|
||||
}
|
||||
|
||||
// Custom: SetParOut sets `AVBSFContext.par_out` value.
|
||||
func (bsfc *AvBSFContext) SetParOut(v *AvCodecParameters) {
|
||||
bsfc.par_out = (*C.struct_AVCodecParameters)(v)
|
||||
}
|
||||
|
||||
// Custom: GetParOutAddr gets `AVBSFContext.par_out` address.
|
||||
func (bsfc *AvBSFContext) GetParOutAddr() **AvCodecParameters {
|
||||
return (**AvCodecParameters)(unsafe.Pointer(&bsfc.par_out))
|
||||
}
|
||||
|
||||
// Custom: GetTimeBaseIn gets `AVBSFContext.time_base_in` value.
|
||||
func (bsfc *AvBSFContext) GetTimeBaseIn() AvRational {
|
||||
return (AvRational)(bsfc.time_base_in)
|
||||
}
|
||||
|
||||
// Custom: SetTimeBaseIn sets `AVBSFContext.time_base_in` value.
|
||||
func (bsfc *AvBSFContext) SetTimeBaseIn(v AvRational) {
|
||||
bsfc.time_base_in = (C.AVRational)(v)
|
||||
}
|
||||
|
||||
// Custom: GetTimeBaseInAddr gets `AVBSFContext.time_base_in` address.
|
||||
func (bsfc *AvBSFContext) GetTimeBaseInAddr() *AvRational {
|
||||
return (*AvRational)(&bsfc.time_base_in)
|
||||
}
|
||||
|
||||
// Custom: GetTimeBaseOut gets `AVBSFContext.time_base_out` value.
|
||||
func (bsfc *AvBSFContext) GetTimeBaseOut() AvRational {
|
||||
return (AvRational)(bsfc.time_base_out)
|
||||
}
|
||||
|
||||
// Custom: SetTimeBaseOut sets `AVBSFContext.time_base_out` value.
|
||||
func (bsfc *AvBSFContext) SetTimeBaseOut(v AvRational) {
|
||||
bsfc.time_base_out = (C.AVRational)(v)
|
||||
}
|
||||
|
||||
// Custom: GetTimeBaseOutAddr gets `AVBSFContext.time_base_out` address.
|
||||
func (bsfc *AvBSFContext) GetTimeBaseOutAddr() *AvRational {
|
||||
return (*AvRational)(&bsfc.time_base_out)
|
||||
}
|
||||
|
||||
// AvBitStreamFilter
|
||||
type AvBitStreamFilter C.struct_AVBitStreamFilter
|
||||
|
||||
// Custom: GetName gets `AVBitStreamFilter.name` value.
|
||||
func (bsf *AvBitStreamFilter) GetName() string {
|
||||
return C.GoString(bsf.name)
|
||||
}
|
||||
|
||||
// Custom: GetCodecIds gets `AVBitStreamFilter.codec_ids` value.
|
||||
func (bsf *AvBitStreamFilter) GetCodecIds() (v []AvCodecID) {
|
||||
if bsf.codec_ids == nil {
|
||||
return v
|
||||
}
|
||||
ptr := (*AvCodecID)(bsf.codec_ids)
|
||||
for *ptr != AV_CODEC_ID_NONE {
|
||||
v = append(v, *ptr)
|
||||
ptr = (*AvCodecID)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) +
|
||||
uintptr(unsafe.Sizeof(*ptr))))
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Custom: GetPrivClass gets `AVBitStreamFilter.priv_class` value.
|
||||
func (bsf *AvBitStreamFilter) GetPrivClass() *AvClass {
|
||||
return (*AvClass)(bsf.priv_class)
|
||||
}
|
||||
|
||||
// Custom: SetPrivClass sets `AVBitStreamFilter.priv_class` value.
|
||||
func (bsf *AvBitStreamFilter) SetPrivClass(v *AvClass) {
|
||||
bsf.priv_class = (*C.struct_AVClass)(v)
|
||||
}
|
||||
|
||||
// Custom: GetPrivClassAddr gets `AVBitStreamFilter.priv_class` address.
|
||||
func (bsf *AvBitStreamFilter) GetPrivClassAddr() **AvClass {
|
||||
return (**AvClass)(unsafe.Pointer(&bsf.priv_class))
|
||||
}
|
||||
|
||||
// AvBsfGetByName returns a bitstream filter with the specified name or NULL if no such
|
||||
// bitstream filter exists.
|
||||
func AvBsfGetByName(name string) *AvBitStreamFilter {
|
||||
|
@@ -6,7 +6,7 @@ package ffmpeg
|
||||
import "C"
|
||||
|
||||
// AvCodecID
|
||||
type AvCodecID int32
|
||||
type AvCodecID = C.enum_AVCodecID
|
||||
|
||||
const (
|
||||
AV_CODEC_ID_NONE = AvCodecID(C.AV_CODEC_ID_NONE)
|
||||
|
@@ -6,7 +6,7 @@ package ffmpeg
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
type AvFieldOrder int32
|
||||
type AvFieldOrder = C.enum_AVFieldOrder
|
||||
|
||||
const (
|
||||
AV_FIELD_UNKNOWN = AvFieldOrder(C.AV_FIELD_UNKNOWN)
|
||||
|
@@ -7,7 +7,7 @@ import "C"
|
||||
import "unsafe"
|
||||
|
||||
// AvPacketSideDataType
|
||||
type AvPacketSideDataType int32
|
||||
type AvPacketSideDataType = C.enum_AVPacketSideDataType
|
||||
|
||||
const (
|
||||
AV_PKT_DATA_PALETTE = AvPacketSideDataType(C.AV_PKT_DATA_PALETTE)
|
||||
@@ -247,7 +247,7 @@ const (
|
||||
)
|
||||
|
||||
// AvSideDataParamChangeFlags
|
||||
type AvSideDataParamChangeFlags int32
|
||||
type AvSideDataParamChangeFlags = C.enum_AVSideDataParamChangeFlags
|
||||
|
||||
const (
|
||||
AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = AvSideDataParamChangeFlags(C.AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT)
|
||||
|
@@ -50,7 +50,7 @@ func AvOutputVideoDeviceNext(d *AvOutputFormat) *AvOutputFormat {
|
||||
type AvDeviceRect C.struct_AVDeviceRect
|
||||
|
||||
// AvAppToDevMessageType
|
||||
type AvAppToDevMessageType int32
|
||||
type AvAppToDevMessageType = C.enum_AVAppToDevMessageType
|
||||
|
||||
const (
|
||||
AV_APP_TO_DEV_NONE = AvAppToDevMessageType(C.AV_APP_TO_DEV_NONE)
|
||||
@@ -68,7 +68,7 @@ const (
|
||||
)
|
||||
|
||||
// AvDevToAppMessageType
|
||||
type AvDevToAppMessageType int32
|
||||
type AvDevToAppMessageType = C.enum_AVDevToAppMessageType
|
||||
|
||||
const (
|
||||
AV_DEV_TO_APP_NONE = AvDevToAppMessageType(C.AV_DEV_TO_APP_NONE)
|
||||
|
74
avfilter.go
74
avfilter.go
@@ -59,6 +59,76 @@ const (
|
||||
// callback functions used to interact with the filter.
|
||||
type AvFilter C.struct_AVFilter
|
||||
|
||||
// Custom: GetName gets `AVMotionVector.name` value.
|
||||
func (flt *AvFilter) GetName() string {
|
||||
return C.GoString(flt.name)
|
||||
}
|
||||
|
||||
// Custom: GetDescription gets `AVMotionVector.description` value.
|
||||
func (flt *AvFilter) GetDescription() string {
|
||||
return C.GoString(flt.description)
|
||||
}
|
||||
|
||||
// Custom: GetInputs gets `AVMotionVector.inputs` value.
|
||||
func (flt *AvFilter) GetInputs() *AvFilterPad {
|
||||
return (*AvFilterPad)(flt.inputs)
|
||||
}
|
||||
|
||||
// Custom: SetInputs sets `AVMotionVector.inputs` value.
|
||||
func (flt *AvFilter) SetInputs(v *AvFilterPad) {
|
||||
flt.inputs = (*C.struct_AVFilterPad)(v)
|
||||
}
|
||||
|
||||
// Custom: GetInputsAddr gets `AVMotionVector.inputs` address.
|
||||
func (flt *AvFilter) GetInputsAddr() **AvFilterPad {
|
||||
return (**AvFilterPad)(unsafe.Pointer(&flt.inputs))
|
||||
}
|
||||
|
||||
// Custom: GetOutputs gets `AVMotionVector.outputs` value.
|
||||
func (flt *AvFilter) GetOutputs() *AvFilterPad {
|
||||
return (*AvFilterPad)(flt.outputs)
|
||||
}
|
||||
|
||||
// Custom: SetOutputs sets `AVMotionVector.outputs` value.
|
||||
func (flt *AvFilter) SetOutputs(v *AvFilterPad) {
|
||||
flt.outputs = (*C.struct_AVFilterPad)(v)
|
||||
}
|
||||
|
||||
// Custom: GetOutputsAddr gets `AVMotionVector.outputs` address.
|
||||
func (flt *AvFilter) GetOutputsAddr() **AvFilterPad {
|
||||
return (**AvFilterPad)(unsafe.Pointer(&flt.outputs))
|
||||
}
|
||||
|
||||
// Custom: GetPrivClass gets `AVMotionVector.priv_class` value.
|
||||
func (flt *AvFilter) GetPrivClass() *AvClass {
|
||||
return (*AvClass)(flt.priv_class)
|
||||
}
|
||||
|
||||
// Custom: SetPrivClass sets `AVMotionVector.priv_class` value.
|
||||
func (flt *AvFilter) SetPrivClass(v *AvClass) {
|
||||
flt.priv_class = (*C.struct_AVClass)(v)
|
||||
}
|
||||
|
||||
// Custom: GetPrivClassAddr gets `AVMotionVector.priv_class` address.
|
||||
func (flt *AvFilter) GetPrivClassAddr() **AvClass {
|
||||
return (**AvClass)(unsafe.Pointer(&flt.priv_class))
|
||||
}
|
||||
|
||||
// Custom: GetFlags gets `AVMotionVector.flags` value.
|
||||
func (flt *AvFilter) GetFlags() int32 {
|
||||
return (int32)(flt.flags)
|
||||
}
|
||||
|
||||
// Custom: SetFlags sets `AVMotionVector.flags` value.
|
||||
func (flt *AvFilter) SetFlags(v int32) {
|
||||
flt.flags = (C.int)(v)
|
||||
}
|
||||
|
||||
// Custom: GetFlagsAddr gets `AVMotionVector.flags` address.
|
||||
func (flt *AvFilter) GetFlagsAddr() *int32 {
|
||||
return (*int32)(&flt.flags)
|
||||
}
|
||||
|
||||
const (
|
||||
AVFILTER_THREAD_SLICE = C.AVFILTER_THREAD_SLICE
|
||||
)
|
||||
@@ -75,8 +145,8 @@ type AvFilterFormatsConfig C.struct_AVFilterFormatsConfig
|
||||
// AvFilterLink
|
||||
type AvFilterLink C.struct_AVFilterLink
|
||||
|
||||
// AvFilterContextLink links two filters together.
|
||||
func AvFilterContextLink(src *AvFilterContext, srcpad uint32,
|
||||
// AvFilterLink2 links two filters together.
|
||||
func AvFilterLink2(src *AvFilterContext, srcpad uint32,
|
||||
dst *AvFilterContext, dstpad uint32) int32 {
|
||||
return (int32)(C.avfilter_link((*C.struct_AVFilterContext)(src), (C.uint)(srcpad),
|
||||
(*C.struct_AVFilterContext)(dst), (C.uint)(dstpad)))
|
||||
|
35
avformat.go
35
avformat.go
@@ -208,7 +208,7 @@ func (ifmt *AvInputFormat) GetMimeType() string {
|
||||
}
|
||||
|
||||
// AvStreamParseType
|
||||
type AvStreamParseType int32
|
||||
type AvStreamParseType = C.enum_AVStreamParseType
|
||||
|
||||
const (
|
||||
AVSTREAM_PARSE_NONE = AvStreamParseType(C.AVSTREAM_PARSE_NONE)
|
||||
@@ -312,8 +312,8 @@ func (stm *AvStream) SetPrivData(v unsafe.Pointer) {
|
||||
}
|
||||
|
||||
// Custom: GetPrivDataAddr gets `AVStream.priv_data` address.
|
||||
func (stm *AvStream) GetPrivDataAddr() *unsafe.Pointer {
|
||||
return &stm.priv_data
|
||||
func (stm *AvStream) GetPrivDataAddr() unsafe.Pointer {
|
||||
return (unsafe.Pointer)(&stm.priv_data)
|
||||
}
|
||||
|
||||
// Custom: GetTimeBase gets `AVStream.time_base` value.
|
||||
@@ -831,7 +831,7 @@ type AvFormatControlMessageFunc C.av_format_control_message
|
||||
type AvOpenCallbackFunc C.AVOpenCallback
|
||||
|
||||
// AvDurationEstimationMethod
|
||||
type AvDurationEstimationMethod int32
|
||||
type AvDurationEstimationMethod = C.enum_AVDurationEstimationMethod
|
||||
|
||||
const (
|
||||
AVFMT_DURATION_FROM_PTS = AvDurationEstimationMethod(C.AVFMT_DURATION_FROM_PTS)
|
||||
@@ -901,8 +901,8 @@ func (s *AvFormatContext) SetPrivData(v unsafe.Pointer) {
|
||||
}
|
||||
|
||||
// Custom: GetPrivDataAddr gets `AVFormatContext.priv_data` address.
|
||||
func (s *AvFormatContext) GetPrivDataAddr() *unsafe.Pointer {
|
||||
return (*unsafe.Pointer)(unsafe.Pointer(&s.priv_data))
|
||||
func (s *AvFormatContext) GetPrivDataAddr() unsafe.Pointer {
|
||||
return (unsafe.Pointer)(&s.priv_data)
|
||||
}
|
||||
|
||||
// Custom: GetPb gets `AVFormatContext.pb` value.
|
||||
@@ -990,7 +990,7 @@ func (s *AvFormatContext) SetUrl(v string) {
|
||||
if s.url != nil {
|
||||
C.free(unsafe.Pointer(s.url))
|
||||
}
|
||||
s.url = vPtr
|
||||
s.url = (*C.char)(vPtr)
|
||||
}
|
||||
|
||||
// Custom: GetStartTime gets `AVFormatContext.start_time` value.
|
||||
@@ -1782,8 +1782,8 @@ func (s *AvFormatContext) SetOpaque(v unsafe.Pointer) {
|
||||
}
|
||||
|
||||
// Custom: GetOpaqueAddr gets `AVFormatContext.opaque` address.
|
||||
func (s *AvFormatContext) GetOpaqueAddr() *unsafe.Pointer {
|
||||
return (*unsafe.Pointer)(&s.opaque)
|
||||
func (s *AvFormatContext) GetOpaqueAddr() unsafe.Pointer {
|
||||
return (unsafe.Pointer)(&s.opaque)
|
||||
}
|
||||
|
||||
// Custom: GetOutputTsOffset gets `AVFormatContext.output_ts_offset` value.
|
||||
@@ -2336,16 +2336,23 @@ func AvGetOutputTimestamp(ic *AvFormatContext, stream int32, dts, wall *int64) i
|
||||
(C.int)(stream), (*C.int64_t)(dts), (*C.int64_t)(wall)))
|
||||
}
|
||||
|
||||
// TODO. av_hex_dump
|
||||
// AvHexDump sends a nice hexadecimal dump of a buffer to the specified file stream.
|
||||
func AvHexDump(f *FILE, buf *uint8, size int32) {
|
||||
C.av_hex_dump((*C.FILE)(f), (*C.uint8_t)(buf), (C.int)(size))
|
||||
}
|
||||
|
||||
// AvHexDumpLog
|
||||
// AvHexDumpLog sends a nice hexadecimal dump of a buffer to the log.
|
||||
func AvHexDumpLog(avcl unsafe.Pointer, level int32, buf *uint8, size int32) {
|
||||
C.av_hex_dump_log(avcl, (C.int)(level), (*C.uint8_t)(buf), (C.int)(size))
|
||||
}
|
||||
|
||||
// TODO. av_pkt_dump2
|
||||
// AvPktDump2 sends a nice dump of a packet to the specified file stream.
|
||||
func AvPktDump2(f *FILE, pkt *AvPacket, dumpPayload int32, st *AvStream) {
|
||||
C.av_pkt_dump2((*C.FILE)(f), (*C.struct_AVPacket)(pkt),
|
||||
(C.int)(dumpPayload), (*C.struct_AVStream)(st))
|
||||
}
|
||||
|
||||
// AvPktDumpLog2
|
||||
// AvPktDumpLog2 sends a nice dump of a packet to the log.
|
||||
func av_pkt_dump_log2(avcl unsafe.Pointer, level int32, pkt *AvPacket, dumpPayload int32, st *AvStream) {
|
||||
C.av_pkt_dump_log2(avcl, (C.int)(level), (*C.struct_AVPacket)(pkt),
|
||||
(C.int)(dumpPayload), (*C.struct_AVStream)(st))
|
||||
@@ -2526,7 +2533,7 @@ func AvApplyBitstreamFilters(codec *AvCodecContext, pkt *AvPacket, bsfc *AvBitSt
|
||||
}
|
||||
|
||||
// AvTimebaseSource
|
||||
type AvTimebaseSource int32
|
||||
type AvTimebaseSource = C.enum_AVTimebaseSource
|
||||
|
||||
const (
|
||||
AVFMT_TBCF_AUTO = AvTimebaseSource(C.AVFMT_TBCF_AUTO)
|
||||
|
@@ -6,9 +6,16 @@ package ffmpeg
|
||||
typedef int (*avio_context_read_packet_func)(void *opaque, uint8_t *buf, int buf_size);
|
||||
typedef int (*avio_context_write_packet_func)(void *opaque, uint8_t *buf, int buf_size);
|
||||
typedef int64_t (*avio_context_seek_func)(void *opaque, int64_t offset, int whence);
|
||||
|
||||
int avio_printf_wrap(AVIOContext *s, const char *fmt) {
|
||||
return avio_printf(s, fmt, NULL);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
AVIO_SEEKABLE_NORMAL = C.AVIO_SEEKABLE_NORMAL
|
||||
@@ -22,7 +29,7 @@ type AvIOInterruptCB C.struct_AVIOInterruptCB
|
||||
type AvIODirEntry C.struct_AVIODirEntry
|
||||
|
||||
// AvIODirEntryType
|
||||
type AvIODirEntryType int32
|
||||
type AvIODirEntryType = C.enum_AVIODirEntryType
|
||||
|
||||
const (
|
||||
AVIO_ENTRY_UNKNOWN = AvIODirEntryType(C.AVIO_ENTRY_UNKNOWN)
|
||||
@@ -42,7 +49,7 @@ const (
|
||||
type AvIODirContext C.struct_AVIODirContext
|
||||
|
||||
// AvIODataMarkerType
|
||||
type AvIODataMarkerType int32
|
||||
type AvIODataMarkerType = C.enum_AVIODataMarkerType
|
||||
|
||||
const (
|
||||
AVIO_DATA_MARKER_HEADER = AvIODataMarkerType(C.AVIO_DATA_MARKER_HEADER)
|
||||
@@ -247,11 +254,22 @@ func AvIOFeof(s *AvIOContext) int32 {
|
||||
return (int32)(C.avio_feof((*C.struct_AVIOContext)(s)))
|
||||
}
|
||||
|
||||
// TODO. avio_printf
|
||||
// AvIOPrintf Writes a formatted string to the context.
|
||||
func AvIOPrintf(s *AvIOContext, _fmt string, va ...any) int32 {
|
||||
fmtPtr, fmtFunc := StringCasting(fmt.Sprintf(_fmt, va...))
|
||||
defer fmtFunc()
|
||||
return (int32)(C.avio_printf_wrap((*C.struct_AVIOContext)(s), (*C.char)(fmtPtr)))
|
||||
}
|
||||
|
||||
// TODO. avio_print_string_array
|
||||
// NONEED: avio_print_string_array
|
||||
|
||||
// TODO. avio_print
|
||||
// AvIOPrint
|
||||
func AvIOPrint(s *AvIOContext, va ...any) {
|
||||
fmtPtr, fmtFunc := StringCasting(fmt.Sprint(va...))
|
||||
defer fmtFunc()
|
||||
fmtArray := []*C.char{(*C.char)(fmtPtr), nil}
|
||||
C.avio_print_string_array((*C.struct_AVIOContext)(s), &fmtArray[0])
|
||||
}
|
||||
|
||||
// AvIOFlush forces flushing of buffered data.
|
||||
func AvIOFlush(s *AvIOContext) {
|
||||
|
164
avresample.go
164
avresample.go
@@ -1,164 +0,0 @@
|
||||
package ffmpeg
|
||||
|
||||
/*
|
||||
#include <libavresample/avresample.h>
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
AVRESAMPLE_MAX_CHANNELS = C.AVRESAMPLE_MAX_CHANNELS
|
||||
)
|
||||
|
||||
type AvAudioResampleContext C.struct_AVAudioResampleContext
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
type AvMixCoeffType int32
|
||||
|
||||
const (
|
||||
AV_MIX_COEFF_TYPE_Q8 = AvMixCoeffType(C.AV_MIX_COEFF_TYPE_Q8)
|
||||
AV_MIX_COEFF_TYPE_Q15 = AvMixCoeffType(C.AV_MIX_COEFF_TYPE_Q15)
|
||||
AV_MIX_COEFF_TYPE_FLT = AvMixCoeffType(C.AV_MIX_COEFF_TYPE_FLT)
|
||||
AV_MIX_COEFF_TYPE_NB = AvMixCoeffType(C.AV_MIX_COEFF_TYPE_NB)
|
||||
)
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
type AvResampleFilterType int32
|
||||
|
||||
const (
|
||||
AV_RESAMPLE_FILTER_TYPE_CUBIC = AvResampleFilterType(C.AV_RESAMPLE_FILTER_TYPE_CUBIC)
|
||||
AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL = AvResampleFilterType(C.AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL)
|
||||
AV_RESAMPLE_FILTER_TYPE_KAISER = AvResampleFilterType(C.AV_RESAMPLE_FILTER_TYPE_KAISER)
|
||||
)
|
||||
|
||||
type AvResampleDitherMethod int32
|
||||
|
||||
const (
|
||||
AV_RESAMPLE_DITHER_NONE = AvResampleDitherMethod(C.AV_RESAMPLE_DITHER_NONE)
|
||||
AV_RESAMPLE_DITHER_RECTANGULAR = AvResampleDitherMethod(C.AV_RESAMPLE_DITHER_RECTANGULAR)
|
||||
AV_RESAMPLE_DITHER_TRIANGULAR = AvResampleDitherMethod(C.AV_RESAMPLE_DITHER_TRIANGULAR)
|
||||
AV_RESAMPLE_DITHER_TRIANGULAR_HP = AvResampleDitherMethod(C.AV_RESAMPLE_DITHER_TRIANGULAR_HP)
|
||||
AV_RESAMPLE_DITHER_TRIANGULAR_NS = AvResampleDitherMethod(C.AV_RESAMPLE_DITHER_TRIANGULAR_NS)
|
||||
AV_RESAMPLE_DITHER_NB = AvResampleDitherMethod(C.AV_RESAMPLE_DITHER_NB)
|
||||
)
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleVersion() uint32 {
|
||||
return (uint32)(C.avresample_version())
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleConfiguration() string {
|
||||
return C.GoString(C.avresample_configuration())
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleLicense() string {
|
||||
return C.GoString(C.avresample_license())
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleGetClass() *AvClass {
|
||||
return (*AvClass)(C.avresample_get_class())
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleAllocContext() *AvAudioResampleContext {
|
||||
return (*AvAudioResampleContext)(C.avresample_alloc_context())
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleOpen(avr *AvAudioResampleContext) int32 {
|
||||
return (int32)(C.avresample_open((*C.struct_AVAudioResampleContext)(avr)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleIsOpen(avr *AvAudioResampleContext) int32 {
|
||||
return (int32)(C.avresample_is_open((*C.struct_AVAudioResampleContext)(avr)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleClose(avr *AvAudioResampleContext) {
|
||||
C.avresample_close((*C.struct_AVAudioResampleContext)(avr))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleFree(avr **AvAudioResampleContext) {
|
||||
C.avresample_free((**C.struct_AVAudioResampleContext)(unsafe.Pointer(avr)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleBuildMatrix(inLayout, outLayout uint64,
|
||||
centerMixLevel, surroundMixLevel, lfeMixLevel float64,
|
||||
normalize int32, matrix *float64, stride int32, matrixEncoding AvMatrixEncoding) int32 {
|
||||
return (int32)(C.avresample_build_matrix((C.uint64_t)(inLayout), (C.uint64_t)(outLayout),
|
||||
(C.double)(centerMixLevel), (C.double)(surroundMixLevel), (C.double)(lfeMixLevel),
|
||||
(C.int)(normalize), (*C.double)(matrix), (C.int)(stride),
|
||||
(C.enum_AVMatrixEncoding)(matrixEncoding)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleGetMatrix(avr *AvAudioResampleContext, matrix *float64, stride int32) int32 {
|
||||
return (int32)(C.avresample_get_matrix((*C.struct_AVAudioResampleContext)(avr),
|
||||
(*C.double)(matrix), (C.int)(stride)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleSetMatrix(avr *AvAudioResampleContext, matrix *float64, stride int32) int32 {
|
||||
return (int32)(C.avresample_set_matrix((*C.struct_AVAudioResampleContext)(avr),
|
||||
(*C.double)(matrix), (C.int)(stride)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleSetChannelMapping(avr *AvAudioResampleContext, channelMap *int32) int32 {
|
||||
return (int32)(C.avresample_set_channel_mapping((*C.struct_AVAudioResampleContext)(avr),
|
||||
(*C.int)(channelMap)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleSetCompensation(avr *AvAudioResampleContext, sampleDelta, compensationDistance int32) int32 {
|
||||
return (int32)(C.avresample_set_compensation((*C.struct_AVAudioResampleContext)(avr),
|
||||
(C.int)(sampleDelta), (C.int)(compensationDistance)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleGetOutSamples(avr *AvAudioResampleContext, inNbSamples int32) int32 {
|
||||
return (int32)(C.avresample_get_out_samples((*C.struct_AVAudioResampleContext)(avr),
|
||||
(C.int)(inNbSamples)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleConvert(avr *AvAudioResampleContext, output **uint8, outPlaneSize, outSamples int32,
|
||||
input **uint8, inPlaneSize, inSamples int32) int32 {
|
||||
return (int32)(C.avresample_convert((*C.struct_AVAudioResampleContext)(avr),
|
||||
(**C.uint8_t)(unsafe.Pointer(output)), (C.int)(outPlaneSize), (C.int)(outSamples),
|
||||
(**C.uint8_t)(unsafe.Pointer(input)), (C.int)(inPlaneSize), (C.int)(inSamples)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleGetDelay(avr *AvAudioResampleContext) int32 {
|
||||
return (int32)(C.avresample_get_delay((*C.struct_AVAudioResampleContext)(avr)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleAvailable(avr *AvAudioResampleContext) int32 {
|
||||
return (int32)(C.avresample_available((*C.struct_AVAudioResampleContext)(avr)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleRead(avr *AvAudioResampleContext, output **uint8, nbSamples int32) int32 {
|
||||
return (int32)(C.avresample_read((*C.struct_AVAudioResampleContext)(avr),
|
||||
(**C.uint8_t)(unsafe.Pointer(output)), (C.int)(nbSamples)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleConvertFrame(avr *AvAudioResampleContext, output, input *AvFrame) int32 {
|
||||
return (int32)(C.avresample_convert_frame((*C.struct_AVAudioResampleContext)(avr),
|
||||
(*C.struct_AVFrame)(output), (*C.struct_AVFrame)(input)))
|
||||
}
|
||||
|
||||
// Deprecated: Use libswresample
|
||||
func AvResampleConfig(avr *AvAudioResampleContext, out, in *AvFrame) int32 {
|
||||
return (int32)(C.avresample_config((*C.struct_AVAudioResampleContext)(avr),
|
||||
(*C.struct_AVFrame)(out), (*C.struct_AVFrame)(in)))
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
package ffmpeg
|
||||
|
||||
/*
|
||||
#include <libavresample/version.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
const (
|
||||
LIBAVRESAMPLE_VERSION_MAJOR = C.LIBAVRESAMPLE_VERSION_MAJOR
|
||||
LIBAVRESAMPLE_VERSION_MINOR = C.LIBAVRESAMPLE_VERSION_MINOR
|
||||
LIBAVRESAMPLE_VERSION_MICRO = C.LIBAVRESAMPLE_VERSION_MICRO
|
||||
)
|
25
avutil.go
25
avutil.go
@@ -4,7 +4,11 @@ package ffmpeg
|
||||
#include <libavutil/avutil.h>
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type FILE C.FILE
|
||||
|
||||
// AvutilVersion returns the LIBAVUTIL_VERSION_INT constant.
|
||||
func AvutilVersion() uint32 {
|
||||
@@ -27,7 +31,7 @@ func AvutilLicense() string {
|
||||
}
|
||||
|
||||
// Media Type
|
||||
type AvMediaType int32
|
||||
type AvMediaType = C.enum_AVMediaType
|
||||
|
||||
const (
|
||||
AVMEDIA_TYPE_UNKNOWN = AvMediaType(C.AVMEDIA_TYPE_UNKNOWN)
|
||||
@@ -64,7 +68,7 @@ var (
|
||||
)
|
||||
|
||||
// AvPictureType, pixel formats and basic image planes manipulation.
|
||||
type AvPictureType int32
|
||||
type AvPictureType = C.enum_AVPictureType
|
||||
|
||||
const (
|
||||
AV_PICTURE_TYPE_NONE = AvPictureType(C.AV_PICTURE_TYPE_NONE)
|
||||
@@ -93,9 +97,20 @@ func AvIntListLengthForSize(elsize uint32, list unsafe.Pointer, term uint64) uin
|
||||
return (uint32)(C.av_int_list_length_for_size((C.uint)(elsize), list, (C.uint64_t)(term)))
|
||||
}
|
||||
|
||||
// TODO. av_int_list_length
|
||||
// AvIntListLength
|
||||
func AvIntListLength[T any](list *T, term uint64) uint32 {
|
||||
elsize := unsafe.Sizeof(*list)
|
||||
return (uint32)(C.av_int_list_length_for_size((C.uint)(elsize), (unsafe.Pointer)(list), (C.uint64_t)(term)))
|
||||
}
|
||||
|
||||
// TODO. av_fopen_utf8
|
||||
// AvFopenUtf8
|
||||
func AvFopenUtf8(path, mode string) *FILE {
|
||||
pathPtr, pathFunc := StringCasting(path)
|
||||
defer pathFunc()
|
||||
modePtr, modeFunc := StringCasting(mode)
|
||||
defer modeFunc()
|
||||
return (*FILE)(C.av_fopen_utf8((*C.char)(pathPtr), (*C.char)(modePtr)))
|
||||
}
|
||||
|
||||
// AvGetTimeBaseQ returns the fractional representation of the internal time base.
|
||||
func AvGetTimeBaseQ() AvRational {
|
||||
|
@@ -73,7 +73,7 @@ const (
|
||||
AV_CH_LAYOUT_22POINT2 = uint64(C.AV_CH_LAYOUT_22POINT2)
|
||||
)
|
||||
|
||||
type AvMatrixEncoding int32
|
||||
type AvMatrixEncoding = C.enum_AVMatrixEncoding
|
||||
|
||||
const (
|
||||
AV_MATRIX_ENCODING_NONE = AvMatrixEncoding(C.AV_MATRIX_ENCODING_NONE)
|
||||
@@ -101,10 +101,14 @@ func AvGetExtendedChannelLayout(name string, channelLayout *uint64, nbChannels *
|
||||
(*C.uint64_t)(channelLayout), (*C.int32_t)(nbChannels)))
|
||||
}
|
||||
|
||||
const AV_CH_LAYOUT_MAX_STRING_SIZE = 256
|
||||
|
||||
// AvGetChannelLayoutString returns a description of a channel layout.
|
||||
func AvGetChannelLayoutString(buf *int8, bufSize, nbChannels int32, channelLayout uint64) {
|
||||
C.av_get_channel_layout_string((*C.char)(buf), (C.int)(bufSize),
|
||||
func AvGetChannelLayoutString(nbChannels int32, channelLayout uint64) string {
|
||||
buf := make([]C.char, AV_CH_LAYOUT_MAX_STRING_SIZE)
|
||||
C.av_get_channel_layout_string((*C.char)(&buf[0]), (C.int)(AV_CH_LAYOUT_MAX_STRING_SIZE),
|
||||
(C.int)(nbChannels), (C.uint64_t)(channelLayout))
|
||||
return C.GoString((*C.char)(&buf[0]))
|
||||
}
|
||||
|
||||
// AvBprintChannelLayout appends a description of a channel layout to a bprint buffer.
|
||||
|
@@ -35,7 +35,7 @@ func AvDictCount(m *AvDictionary) int32 {
|
||||
}
|
||||
|
||||
// AvDictSet sets the given entry in *pm, overwriting an existing entry.
|
||||
func av_dict_set(pm **AvDictionary, key, value string, flags int32) int32 {
|
||||
func AvDictSet(pm **AvDictionary, key, value string, flags int32) int32 {
|
||||
keyPtr, keyFunc := StringCasting(key)
|
||||
defer keyFunc()
|
||||
valuePtr, valueFunc := StringCasting(value)
|
||||
@@ -71,7 +71,7 @@ func AvDictCopy(dst **AvDictionary, src *AvDictionary, flags int32) int32 {
|
||||
}
|
||||
|
||||
// AvDictFree frees all the memory allocated for an AVDictionary struct and all keys and values.
|
||||
func AvDictFree(m *AvDictionary) {
|
||||
func AvDictFree(m **AvDictionary) {
|
||||
C.av_dict_free((**C.struct_AVDictionary)(unsafe.Pointer(m)))
|
||||
}
|
||||
|
||||
|
@@ -53,7 +53,10 @@ const (
|
||||
AVERROR_HTTP_NOT_FOUND = int32(C.AVERROR_HTTP_NOT_FOUND)
|
||||
AVERROR_HTTP_OTHER_4XX = int32(C.AVERROR_HTTP_OTHER_4XX)
|
||||
AVERROR_HTTP_SERVER_ERROR = int32(C.AVERROR_HTTP_SERVER_ERROR)
|
||||
AV_ERROR_MAX_STRING_SIZE = int32(C.AV_ERROR_MAX_STRING_SIZE)
|
||||
)
|
||||
|
||||
const (
|
||||
AV_ERROR_MAX_STRING_SIZE = int32(C.AV_ERROR_MAX_STRING_SIZE)
|
||||
)
|
||||
|
||||
// AvStrerror puts a description of the AVERROR code errnum in errbuf.
|
||||
|
@@ -7,7 +7,7 @@ import "C"
|
||||
import "unsafe"
|
||||
|
||||
// AvFrameSideDataType
|
||||
type AvFrameSideDataType int32
|
||||
type AvFrameSideDataType = C.enum_AVFrameSideDataType
|
||||
|
||||
const (
|
||||
AV_FRAME_DATA_PANSCAN = AvFrameSideDataType(C.AV_FRAME_DATA_PANSCAN)
|
||||
@@ -37,7 +37,7 @@ const (
|
||||
)
|
||||
|
||||
// AvActiveFormatDescription
|
||||
type AvActiveFormatDescription int32
|
||||
type AvActiveFormatDescription = C.enum_AVActiveFormatDescription
|
||||
|
||||
const (
|
||||
AV_AFD_SAME = AvActiveFormatDescription(C.AV_AFD_SAME)
|
||||
@@ -127,6 +127,18 @@ func (frame *AvFrame) GetExtendedDataAddr() ***uint8 {
|
||||
return (***uint8)(unsafe.Pointer(&frame.extended_data))
|
||||
}
|
||||
|
||||
// Custom: GetExtendedDataIdx gets `AVFrame.extended_data` index value.
|
||||
func (frame *AvFrame) GetExtendedDataIdx(idx int) *uint8 {
|
||||
if frame.extended_data == nil {
|
||||
return nil
|
||||
}
|
||||
return *(**uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(frame.extended_data)) +
|
||||
uintptr(unsafe.Sizeof(*frame.extended_data))*(uintptr(idx))))
|
||||
|
||||
// Another way.
|
||||
// return unsafe.Slice((**uint8)(unsafe.Pointer(frame.extended_data)), idx+1)[idx]
|
||||
}
|
||||
|
||||
// Custom: GetWidth gets `AVFrame.width` value.
|
||||
func (frame *AvFrame) GetWidth() int32 {
|
||||
return (int32)(frame.width)
|
||||
|
203
avutil_imgutils.go
Normal file
203
avutil_imgutils.go
Normal file
@@ -0,0 +1,203 @@
|
||||
package ffmpeg
|
||||
|
||||
/*
|
||||
#include <libavutil/imgutils.h>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// AvImageFillMaxPixsteps computes the max pixel step for each plane of an image with a
|
||||
// format described by pixdesc.
|
||||
func AvImageFillMaxPixsteps(maxPixsteps, maxPixstepComps []int32, pixdesc *AvPixFmtDescriptor) {
|
||||
if len(maxPixsteps) != 4 {
|
||||
panic("maxPixsteps need len = 4")
|
||||
}
|
||||
if len(maxPixstepComps) != 4 {
|
||||
panic("maxPixstepComps need len = 4")
|
||||
}
|
||||
C.av_image_fill_max_pixsteps((*C.int)(&maxPixsteps[0]), (*C.int)(&maxPixstepComps[0]),
|
||||
(*C.struct_AVPixFmtDescriptor)(pixdesc))
|
||||
}
|
||||
|
||||
// AvImageGetLinesize computes the size of an image line with format pix_fmt and width
|
||||
// width for the plane plane.
|
||||
func AvImageGetLinesize(pixFmt AvPixelFormat, width, plane int32) int32 {
|
||||
return (int32)(C.av_image_get_linesize((C.enum_AVPixelFormat)(pixFmt),
|
||||
(C.int)(width), (C.int)(plane)))
|
||||
}
|
||||
|
||||
// AvImageFillLinesizes fills plane linesizes for an image with pixel format pix_fmt and width width.
|
||||
func AvImageFillLinesizes(linesizes []int32, pixFmt AvPixelFormat, width int32) int32 {
|
||||
if len(linesizes) != 4 {
|
||||
panic("linesizes need len = 4")
|
||||
}
|
||||
return (int32)(C.av_image_fill_linesizes((*C.int)(&linesizes[0]),
|
||||
(C.enum_AVPixelFormat)(pixFmt), (C.int)(width)))
|
||||
}
|
||||
|
||||
// AvImageFillPlaneSizes fills plane sizes for an image with pixel format pix_fmt and height height.
|
||||
func AvImageFillPlaneSizes(size []uint, pixFmt AvPixelFormat, height int32, linesizes []int) int32 {
|
||||
if len(size) != 4 {
|
||||
panic("size need len = 4")
|
||||
}
|
||||
if len(linesizes) != 4 {
|
||||
panic("linesizes need len = 4")
|
||||
}
|
||||
return (int32)(C.av_image_fill_plane_sizes((*C.size_t)(unsafe.Pointer(&size[0])),
|
||||
(C.enum_AVPixelFormat)(pixFmt), (C.int)(height), (*C.ptrdiff_t)(unsafe.Pointer(&linesizes[0]))))
|
||||
}
|
||||
|
||||
// AvImageFillPointers fills plane data pointers for an image with pixel format pix_fmt and height height.
|
||||
func AvImageFillPointers(data []*uint8, pixFmt AvPixelFormat,
|
||||
height int32, ptr *uint8, linesizes []int32) int32 {
|
||||
if len(data) != 4 {
|
||||
panic("data need len = 4")
|
||||
}
|
||||
if len(linesizes) != 4 {
|
||||
panic("linesizes need len = 4")
|
||||
}
|
||||
return (int32)(C.av_image_fill_pointers((**C.uint8_t)(unsafe.Pointer(&data[0])),
|
||||
(C.enum_AVPixelFormat)(pixFmt), (C.int)(height), (*C.uint8_t)(ptr),
|
||||
(*C.int)(&linesizes[0])))
|
||||
}
|
||||
|
||||
// AvImageAlloc allocates an image with size w and h and pixel format pix_fmt, and
|
||||
// fill pointers and linesizes accordingly.
|
||||
func AvImageAlloc(pointers []*uint8, linesizes []int32, w, h int32,
|
||||
pixFmt AvPixelFormat, align int32) int32 {
|
||||
if len(pointers) != 4 {
|
||||
panic("pointers need len = 4")
|
||||
}
|
||||
if len(linesizes) != 4 {
|
||||
panic("linesizes need len = 4")
|
||||
}
|
||||
return (int32)(C.av_image_alloc((**C.uint8_t)(unsafe.Pointer(&pointers[0])),
|
||||
(*C.int)(&linesizes[0]),
|
||||
(C.int)(w), (C.int)(h), (C.enum_AVPixelFormat)(pixFmt), (C.int)(align)))
|
||||
}
|
||||
|
||||
// AvImageCopyPlane copies image plane from src to dst.
|
||||
func AvImageCopyPlane(dst *uint8, dstLinesize int32, src *uint8,
|
||||
srcLinesize int32, bytewidth, height int32) {
|
||||
C.av_image_copy_plane((*C.uint8_t)(dst), (C.int)(dstLinesize),
|
||||
(*C.uint8_t)(src), (C.int)(srcLinesize),
|
||||
(C.int)(bytewidth), (C.int)(height))
|
||||
}
|
||||
|
||||
// AvImageCopy copies image in src_data to dst_data.
|
||||
func AvImageCopy(dstData []*uint8, dstLinesizes []int32, srcData []*uint8, srcLinesizes []int32,
|
||||
pixFmt AvPixelFormat, width, height int32) {
|
||||
if len(dstData) != 4 {
|
||||
panic("dstData need len = 4")
|
||||
}
|
||||
if len(dstLinesizes) != 4 {
|
||||
panic("dstLinesizes need len = 4")
|
||||
}
|
||||
if len(srcData) != 4 {
|
||||
panic("srcData need len = 4")
|
||||
}
|
||||
if len(srcLinesizes) != 4 {
|
||||
panic("srcLinesizes need len = 4")
|
||||
}
|
||||
C.av_image_copy((**C.uint8_t)(unsafe.Pointer(&dstData[0])),
|
||||
(*C.int)(&dstLinesizes[0]),
|
||||
(**C.uint8_t)(unsafe.Pointer(&srcData[0])),
|
||||
(*C.int)(&srcLinesizes[0]),
|
||||
(C.enum_AVPixelFormat)(pixFmt), (C.int)(width), (C.int)(height))
|
||||
}
|
||||
|
||||
// AvImageCopyUcFrom copies image data located in uncacheable (e.g. GPU mapped) memory.
|
||||
func AvImageCopyUcFrom(dstData []*uint8, dstLinesizes []int, srcData []*uint8, srcLinesizes []int,
|
||||
pixFmt AvPixelFormat, width, height int32) {
|
||||
if len(dstData) != 4 {
|
||||
panic("dstData need len = 4")
|
||||
}
|
||||
if len(dstLinesizes) != 4 {
|
||||
panic("dstLinesizes need len = 4")
|
||||
}
|
||||
if len(srcData) != 4 {
|
||||
panic("srcData need len = 4")
|
||||
}
|
||||
if len(srcLinesizes) != 4 {
|
||||
panic("srcLinesizes need len = 4")
|
||||
}
|
||||
C.av_image_copy_uc_from((**C.uint8_t)(unsafe.Pointer(&dstData[0])),
|
||||
(*C.ptrdiff_t)(unsafe.Pointer(&dstLinesizes[0])),
|
||||
(**C.uint8_t)(unsafe.Pointer(&srcData[0])),
|
||||
(*C.ptrdiff_t)(unsafe.Pointer(&srcLinesizes[0])),
|
||||
(C.enum_AVPixelFormat)(pixFmt), (C.int)(width), (C.int)(height))
|
||||
}
|
||||
|
||||
// AvImageFillArrays setups the data pointers and linesizes based on the specified image
|
||||
// parameters and the provided array.
|
||||
func AvImageFillArrays(dstData []*uint8, dstLinesize []int32, src *uint8,
|
||||
pixFmt AvPixelFormat, width, height, align int32) {
|
||||
if len(dstData) != 4 {
|
||||
panic("dstData need len = 4")
|
||||
}
|
||||
if len(dstLinesize) != 4 {
|
||||
panic("dstLinesize need len = 4")
|
||||
}
|
||||
C.av_image_fill_arrays((**C.uint8_t)(unsafe.Pointer(&dstData[0])),
|
||||
(*C.int)(&dstLinesize[0]),
|
||||
(*C.uint8_t)(src),
|
||||
(C.enum_AVPixelFormat)(pixFmt), (C.int)(width), (C.int)(height), (C.int)(align))
|
||||
}
|
||||
|
||||
// AvImageGetBufferSize Return the size in bytes of the amount of data required to store an
|
||||
// image with the given parameters.
|
||||
func AvImageGetBufferSize(pixFmt AvPixelFormat, width, height, align int32) int32 {
|
||||
return (int32)(C.av_image_get_buffer_size((C.enum_AVPixelFormat)(pixFmt),
|
||||
(C.int)(width), (C.int)(height), (C.int)(align)))
|
||||
}
|
||||
|
||||
// av_image_copy_to_buffer
|
||||
func av_image_copy_to_buffer(dst *uint8, dstSize int32, srcData []*uint8, srcLinesize []int32,
|
||||
pixFmt AvPixelFormat, width, height, align int32) {
|
||||
if len(srcData) != 4 {
|
||||
panic("srcData need len = 4")
|
||||
}
|
||||
if len(srcLinesize) != 4 {
|
||||
panic("srcLinesize need len = 4")
|
||||
}
|
||||
C.av_image_copy_to_buffer((*C.uint8_t)(dst), (C.int)(dstSize),
|
||||
(**C.uint8_t)(unsafe.Pointer(&srcData[0])), (*C.int)(&srcLinesize[0]),
|
||||
(C.enum_AVPixelFormat)(pixFmt), (C.int)(width), (C.int)(height), (C.int)(align))
|
||||
}
|
||||
|
||||
// AvImageCheckSize checks if the given dimension of an image is valid, meaning that all
|
||||
// bytes of the image can be addressed with a signed int.
|
||||
func AvImageCheckSize(w, h uint32, logOffset int32, logCtx unsafe.Pointer) int32 {
|
||||
return (int32)(C.av_image_check_size((C.uint)(w), (C.uint)(h), (C.int)(logOffset), logCtx))
|
||||
}
|
||||
|
||||
// AvImageCheckSize2 checks if the given dimension of an image is valid, meaning that all
|
||||
// bytes of a plane of an image with the specified pix_fmt can be addressed with a signed int.
|
||||
func AvImageCheckSize2(w, h uint32, maxPixels int64, pixFmt AvPixelFormat,
|
||||
logOffset int32, logCtx unsafe.Pointer) int32 {
|
||||
return (int32)(C.av_image_check_size2((C.uint)(w), (C.uint)(h),
|
||||
(C.int64_t)(maxPixels), (C.enum_AVPixelFormat)(pixFmt),
|
||||
(C.int)(logOffset), logCtx))
|
||||
}
|
||||
|
||||
// AvImageCheckSar checks if the given sample aspect ratio of an image is valid.
|
||||
func AvImageCheckSar(w, h uint32, sar AvRational) int32 {
|
||||
return (int32)(C.av_image_check_sar((C.uint)(w), (C.uint)(h), (C.struct_AVRational)(sar)))
|
||||
}
|
||||
|
||||
// AvImageFillBlack overwrites the image data with black.
|
||||
func AvImageFillBlack(dstData []*uint8, dstLinesize []int,
|
||||
pixFmt AvPixelFormat, _range AvColorRange, width, height int32) int32 {
|
||||
if len(dstData) != 4 {
|
||||
panic("dstData need len = 4")
|
||||
}
|
||||
if len(dstLinesize) != 4 {
|
||||
panic("dstLinesize need len = 4")
|
||||
}
|
||||
return (int32)(C.av_image_fill_black((**C.uint8_t)(unsafe.Pointer(&dstData[0])),
|
||||
(*C.ptrdiff_t)(unsafe.Pointer(&dstLinesize[0])),
|
||||
(C.enum_AVPixelFormat)(pixFmt), (C.enum_AVColorRange)(_range),
|
||||
(C.int)(width), (C.int)(height)))
|
||||
}
|
@@ -2,11 +2,26 @@ package ffmpeg
|
||||
|
||||
/*
|
||||
#include <libavutil/log.h>
|
||||
|
||||
void av_log_wrap(void *avcl, int level, char *fmt) {
|
||||
av_log(avcl, level, fmt, NULL);
|
||||
}
|
||||
|
||||
void av_log_once_wrap(void* avcl, int initial_level, int subsequent_level, int *state, char *fmt) {
|
||||
av_log_once(avcl, initial_level, subsequent_level, state, fmt, NULL);
|
||||
}
|
||||
|
||||
typedef void (*av_log_callback_func)(void*, int, const char*, va_list);
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// AvClassCategory
|
||||
type AvClassCategory int32
|
||||
type AvClassCategory = int32
|
||||
|
||||
const (
|
||||
AV_CLASS_CATEGORY_NA = AvClassCategory(C.AV_CLASS_CATEGORY_NA)
|
||||
@@ -44,31 +59,81 @@ func AV_IS_OUTPUT_DEVICE(c AvClassCategory) bool {
|
||||
// AvClass
|
||||
type AvClass C.struct_AVClass
|
||||
|
||||
// AvLogLevelType
|
||||
type AvLogLevelType int32
|
||||
|
||||
const (
|
||||
AV_LOG_QUIET = AvLogLevelType(C.AV_LOG_QUIET)
|
||||
AV_LOG_PANIC = AvLogLevelType(C.AV_LOG_PANIC)
|
||||
AV_LOG_FATAL = AvLogLevelType(C.AV_LOG_FATAL)
|
||||
AV_LOG_ERROR = AvLogLevelType(C.AV_LOG_ERROR)
|
||||
AV_LOG_WARNING = AvLogLevelType(C.AV_LOG_WARNING)
|
||||
AV_LOG_INFO = AvLogLevelType(C.AV_LOG_INFO)
|
||||
AV_LOG_VERBOSE = AvLogLevelType(C.AV_LOG_VERBOSE)
|
||||
AV_LOG_DEBUG = AvLogLevelType(C.AV_LOG_DEBUG)
|
||||
AV_LOG_TRACE = AvLogLevelType(C.AV_LOG_TRACE)
|
||||
AV_LOG_QUIET = int32(C.AV_LOG_QUIET)
|
||||
AV_LOG_PANIC = int32(C.AV_LOG_PANIC)
|
||||
AV_LOG_FATAL = int32(C.AV_LOG_FATAL)
|
||||
AV_LOG_ERROR = int32(C.AV_LOG_ERROR)
|
||||
AV_LOG_WARNING = int32(C.AV_LOG_WARNING)
|
||||
AV_LOG_INFO = int32(C.AV_LOG_INFO)
|
||||
AV_LOG_VERBOSE = int32(C.AV_LOG_VERBOSE)
|
||||
AV_LOG_DEBUG = int32(C.AV_LOG_DEBUG)
|
||||
AV_LOG_TRACE = int32(C.AV_LOG_TRACE)
|
||||
)
|
||||
|
||||
const (
|
||||
AV_LOG_MAX_OFFSET = int32(C.AV_LOG_MAX_OFFSET)
|
||||
)
|
||||
|
||||
// AV_LOG_C sets additional colors for extended debugging sessions.
|
||||
func AV_LOG_C(x int32) int32 {
|
||||
return x << 8
|
||||
}
|
||||
|
||||
// AvLog sends the specified message to the log if the level is less than or equal
|
||||
// to the current av_log_level. By default, all logging messages are sent to stderr.
|
||||
// This behavior can be altered by setting a different logging callback function.
|
||||
func AvLog(avcl unsafe.Pointer, level int32, _fmt string, va ...any) {
|
||||
strPtr, strFunc := StringCasting(fmt.Sprintf(_fmt, va...))
|
||||
defer strFunc()
|
||||
C.av_log_wrap(avcl, (C.int)(level), (*C.char)(strPtr))
|
||||
}
|
||||
|
||||
// AvLogOnce sends the specified message to the log once with the initial_level and then with
|
||||
// the subsequent_level. By default, all logging messages are sent to stderr.
|
||||
// This behavior can be altered by setting a different logging callback function.
|
||||
func AvLogOnce(avcl unsafe.Pointer, initialLevel, subsequentLevel int32, state *int32, _fmt string, va ...any) {
|
||||
fmtPtr, fmtFunc := StringCasting(fmt.Sprintf(_fmt, va...))
|
||||
defer fmtFunc()
|
||||
C.av_log_once_wrap(avcl, (C.int)(initialLevel), (C.int)(subsequentLevel), (*C.int)(state), (*C.char)(fmtPtr))
|
||||
}
|
||||
|
||||
// NONEED: av_vlog
|
||||
|
||||
// AvLogGetLevel gets the current log level
|
||||
func AvLogGetLevel() int32 {
|
||||
return (int32)(C.av_log_get_level())
|
||||
}
|
||||
|
||||
// AvLogSetLevel sets the log level
|
||||
func AvLogSetLevel(level AvLogLevelType) {
|
||||
func AvLogSetLevel(level int32) {
|
||||
C.av_log_set_level(C.int(level))
|
||||
}
|
||||
|
||||
// AvLogGetLevel gets the current log level
|
||||
func AvLogGetLevel() AvLogLevelType {
|
||||
return AvLogLevelType(C.av_log_get_level())
|
||||
// typedef void (*av_log_callback_func)(void*, int, const char*, va_list)
|
||||
type AvLogCallbackFunc C.av_log_callback_func
|
||||
|
||||
// AvLogSetCallback sets the logging callback
|
||||
func AvLogSetCallback(f AvLogCallbackFunc) {
|
||||
C.av_log_set_callback(f)
|
||||
}
|
||||
|
||||
// NONEED: av_log_default_callback
|
||||
|
||||
// AvDefaultItemName returns the context name
|
||||
func AvDefaultItemName(ctx unsafe.Pointer) string {
|
||||
return C.GoString(C.av_default_item_name(ctx))
|
||||
}
|
||||
|
||||
// AvDefaultGetCategory
|
||||
func AvDefaultGetCategory(ptr unsafe.Pointer) AvClassCategory {
|
||||
return (AvClassCategory)(C.av_default_get_category(ptr))
|
||||
}
|
||||
|
||||
// NONEED: av_log_format_line
|
||||
|
||||
// NONEED: av_log_format_line2
|
||||
|
||||
const (
|
||||
AV_LOG_SKIP_REPEATED = C.AV_LOG_SKIP_REPEATED
|
||||
AV_LOG_PRINT_LEVEL = C.AV_LOG_PRINT_LEVEL
|
||||
|
@@ -5,7 +5,7 @@ package ffmpeg
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type AvRounding int32
|
||||
type AvRounding = C.enum_AVRounding
|
||||
|
||||
const (
|
||||
AV_ROUND_ZERO = AvRounding(C.AV_ROUND_ZERO)
|
||||
|
38
avutil_md5.go
Normal file
38
avutil_md5.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package ffmpeg
|
||||
|
||||
/*
|
||||
#include <libavutil/md5.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
var (
|
||||
AvMd5Size = C.av_md5_size
|
||||
)
|
||||
|
||||
// AvMD5
|
||||
type AvMD5 C.struct_AVMD5
|
||||
|
||||
// AvMd5Alloc allocates an AvMD5 context.
|
||||
func AvMd5Alloc() *AvMD5 {
|
||||
return (*AvMD5)(C.av_md5_alloc())
|
||||
}
|
||||
|
||||
// AvMd5Init initializes MD5 hashing.
|
||||
func AvMd5Init(ctx *AvMD5) {
|
||||
C.av_md5_init((*C.struct_AVMD5)(ctx))
|
||||
}
|
||||
|
||||
// AvMd5Update updates hash value.
|
||||
func AvMd5Update(ctx *AvMD5, src *uint8, len int32) {
|
||||
C.av_md5_update((*C.struct_AVMD5)(ctx), (*C.uint8_t)(src), (C.int)(len))
|
||||
}
|
||||
|
||||
// AvMd5Final finishs hashing and output digest value.
|
||||
func AvMd5Final(ctx *AvMD5, dst *uint8) {
|
||||
C.av_md5_final((*C.struct_AVMD5)(ctx), (*C.uint8_t)(dst))
|
||||
}
|
||||
|
||||
// AvMd5Sum hashes an array of data.
|
||||
func AvMd5Sum(dst, src *uint8, len int32) {
|
||||
C.av_md5_sum((*C.uint8_t)(dst), (*C.uint8_t)(src), (C.int)(len))
|
||||
}
|
173
avutil_motion_vector.go
Normal file
173
avutil_motion_vector.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package ffmpeg
|
||||
|
||||
/*
|
||||
#include <libavutil/motion_vector.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type AvMotionVector C.struct_AVMotionVector
|
||||
|
||||
// Custom: GetSource gets `AVMotionVector.source` value.
|
||||
func (mv *AvMotionVector) GetSource() int32 {
|
||||
return (int32)(mv.source)
|
||||
}
|
||||
|
||||
// Custom: SetSource sets `AVMotionVector.source` value.
|
||||
func (mv *AvMotionVector) SetSource(v int32) {
|
||||
mv.source = (C.int32_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetSourceAddr gets `AVMotionVector.source` address.
|
||||
func (mv *AvMotionVector) GetSourceAddr() *int32 {
|
||||
return (*int32)(&mv.source)
|
||||
}
|
||||
|
||||
// Custom: GetW gets `AVMotionVector.w` value.
|
||||
func (mv *AvMotionVector) GetW() uint8 {
|
||||
return (uint8)(mv.w)
|
||||
}
|
||||
|
||||
// Custom: SetW sets `AVMotionVector.w` value.
|
||||
func (mv *AvMotionVector) SetW(v uint8) {
|
||||
mv.w = (C.uint8_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetWAddr gets `AVMotionVector.w` address.
|
||||
func (mv *AvMotionVector) GetWAddr() *uint8 {
|
||||
return (*uint8)(&mv.w)
|
||||
}
|
||||
|
||||
// Custom: GetH gets `AVMotionVector.h` value.
|
||||
func (mv *AvMotionVector) GetH() uint8 {
|
||||
return (uint8)(mv.h)
|
||||
}
|
||||
|
||||
// Custom: SetH sets `AVMotionVector.h` value.
|
||||
func (mv *AvMotionVector) SetH(v uint8) {
|
||||
mv.h = (C.uint8_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetHAddr gets `AVMotionVector.h` address.
|
||||
func (mv *AvMotionVector) GetHAddr() *uint8 {
|
||||
return (*uint8)(&mv.h)
|
||||
}
|
||||
|
||||
// Custom: GetSrcX gets `AVMotionVector.src_x` value.
|
||||
func (mv *AvMotionVector) GetSrcX() int16 {
|
||||
return (int16)(mv.src_x)
|
||||
}
|
||||
|
||||
// Custom: SetSrcX sets `AVMotionVector.src_x` value.
|
||||
func (mv *AvMotionVector) SetSrcX(v int16) {
|
||||
mv.src_x = (C.int16_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetSrcXAddr gets `AVMotionVector.src_x` address.
|
||||
func (mv *AvMotionVector) GetSrcXAddr() *int16 {
|
||||
return (*int16)(&mv.src_x)
|
||||
}
|
||||
|
||||
// Custom: GetSrcY gets `AVMotionVector.src_y` value.
|
||||
func (mv *AvMotionVector) GetSrcY() int16 {
|
||||
return (int16)(mv.src_y)
|
||||
}
|
||||
|
||||
// Custom: SetSrcY sets `AVMotionVector.src_y` value.
|
||||
func (mv *AvMotionVector) SetSrcY(v int16) {
|
||||
mv.src_y = (C.int16_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetSrcYAddr gets `AVMotionVector.src_y` address.
|
||||
func (mv *AvMotionVector) GetSrcYAddr() *int16 {
|
||||
return (*int16)(&mv.src_y)
|
||||
}
|
||||
|
||||
// Custom: GetDstX gets `AVMotionVector.dst_x` value.
|
||||
func (mv *AvMotionVector) GetDstX() int16 {
|
||||
return (int16)(mv.dst_x)
|
||||
}
|
||||
|
||||
// Custom: SetDstX sets `AVMotionVector.dst_x` value.
|
||||
func (mv *AvMotionVector) SetDstX(v int16) {
|
||||
mv.dst_x = (C.int16_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetDstXAddr gets `AVMotionVector.dst_x` address.
|
||||
func (mv *AvMotionVector) GetDstXAddr() *int16 {
|
||||
return (*int16)(&mv.dst_x)
|
||||
}
|
||||
|
||||
// Custom: GetDstY gets `AVMotionVector.dst_y` value.
|
||||
func (mv *AvMotionVector) GetDstY() int16 {
|
||||
return (int16)(mv.dst_y)
|
||||
}
|
||||
|
||||
// Custom: SetDstY sets `AVMotionVector.dst_y` value.
|
||||
func (mv *AvMotionVector) SetDstY(v int16) {
|
||||
mv.dst_y = (C.int16_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetDstYAddr gets `AVMotionVector.dst_y` address.
|
||||
func (mv *AvMotionVector) GetDstYAddr() *int16 {
|
||||
return (*int16)(&mv.dst_y)
|
||||
}
|
||||
|
||||
// Custom: GetFlags gets `AVMotionVector.flags` value.
|
||||
func (mv *AvMotionVector) GetFlags() uint64 {
|
||||
return (uint64)(mv.flags)
|
||||
}
|
||||
|
||||
// Custom: SetFlags sets `AVMotionVector.flags` value.
|
||||
func (mv *AvMotionVector) SetFlags(v uint64) {
|
||||
mv.flags = (C.uint64_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetFlagsAddr gets `AVMotionVector.flags` address.
|
||||
func (mv *AvMotionVector) GetFlagsAddr() *uint64 {
|
||||
return (*uint64)(&mv.flags)
|
||||
}
|
||||
|
||||
// Custom: GetMotionX gets `AVMotionVector.motion_x` value.
|
||||
func (mv *AvMotionVector) GetMotionX() int32 {
|
||||
return (int32)(mv.motion_x)
|
||||
}
|
||||
|
||||
// Custom: SetMotionX sets `AVMotionVector.motion_x` value.
|
||||
func (mv *AvMotionVector) SetMotionX(v int32) {
|
||||
mv.motion_x = (C.int32_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetMotionXAddr gets `AVMotionVector.motion_x` address.
|
||||
func (mv *AvMotionVector) GetMotionXAddr() *int32 {
|
||||
return (*int32)(&mv.motion_x)
|
||||
}
|
||||
|
||||
// Custom: GetMotionY gets `AVMotionVector.motion_y` value.
|
||||
func (mv *AvMotionVector) GetMotionY() int32 {
|
||||
return (int32)(mv.motion_y)
|
||||
}
|
||||
|
||||
// Custom: SetMotionY sets `AVMotionVector.motion_y` value.
|
||||
func (mv *AvMotionVector) SetMotionY(v int32) {
|
||||
mv.motion_y = (C.int32_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetMotionYAddr gets `AVMotionVector.motion_y` address.
|
||||
func (mv *AvMotionVector) GetMotionYAddr() *int32 {
|
||||
return (*int32)(&mv.motion_y)
|
||||
}
|
||||
|
||||
// Custom: GetMotionScale gets `AVMotionVector.motion_scale` value.
|
||||
func (mv *AvMotionVector) GetMotionScale() uint16 {
|
||||
return (uint16)(mv.motion_scale)
|
||||
}
|
||||
|
||||
// Custom: SetMotionScale sets `AVMotionVector.motion_scale` value.
|
||||
func (mv *AvMotionVector) SetMotionScale(v uint16) {
|
||||
mv.motion_scale = (C.uint16_t)(v)
|
||||
}
|
||||
|
||||
// Custom: GetMotionScaleAddr gets `AVMotionVector.motion_scale` address.
|
||||
func (mv *AvMotionVector) GetMotionScaleAddr() *uint16 {
|
||||
return (*uint16)(&mv.motion_scale)
|
||||
}
|
36
avutil_murmur3.go
Normal file
36
avutil_murmur3.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package ffmpeg
|
||||
|
||||
/*
|
||||
#include <libavutil/murmur3.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type AvMurMur3 C.struct_AVMurMur3
|
||||
|
||||
// AvMurmur3Alloc allocates an AVMurMur3 hash context.
|
||||
func AvMurmur3Alloc() *AvMurMur3 {
|
||||
return (*AvMurMur3)(C.av_murmur3_alloc())
|
||||
}
|
||||
|
||||
// AvMurmur3InitSeeded initializes or reinitializes an AvMurMur3 hash context with a seed.
|
||||
func AvMurmur3InitSeeded(c *AvMurMur3, seed uint64) {
|
||||
C.av_murmur3_init_seeded((*C.struct_AVMurMur3)(c), (C.uint64_t)(seed))
|
||||
}
|
||||
|
||||
// AvMurmur3Init initializes or reinitializes an AVMurMur3 hash context.
|
||||
func AvMurmur3Init(c *AvMurMur3) {
|
||||
C.av_murmur3_init((*C.struct_AVMurMur3)(c))
|
||||
}
|
||||
|
||||
// AvMurmur3Update updates hash context with new data.
|
||||
func AvMurmur3Update(c *AvMurMur3, src *uint8, len int32) {
|
||||
C.av_murmur3_update((*C.struct_AVMurMur3)(c), (*C.uint8_t)(src), (C.int)(len))
|
||||
}
|
||||
|
||||
// av_murmur3_final
|
||||
func av_murmur3_final(c *AvMurMur3, dst []uint8) {
|
||||
if len(dst) != 16 {
|
||||
panic("dst need len = 16")
|
||||
}
|
||||
C.av_murmur3_final((*C.struct_AVMurMur3)(c), (*C.uint8_t)(&dst[0]))
|
||||
}
|
@@ -2,32 +2,42 @@ package ffmpeg
|
||||
|
||||
/*
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
int av_opt_set_int_list_wrap(void *obj, const char *name, void *val, uint64_t term, int flags, int size) {
|
||||
if (av_int_list_length(val, term) > INT_MAX / size) {
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
return av_opt_set_bin(obj, name, (const uint8_t *)val, av_int_list_length(val, term) * size , flags);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type AvOptionType int32
|
||||
// AvOptionType
|
||||
type AvOptionType = int32
|
||||
|
||||
const (
|
||||
AV_OPT_TYPE_FLAGS = int32(C.AV_OPT_TYPE_FLAGS)
|
||||
AV_OPT_TYPE_INT = int32(C.AV_OPT_TYPE_INT)
|
||||
AV_OPT_TYPE_INT64 = int32(C.AV_OPT_TYPE_INT64)
|
||||
AV_OPT_TYPE_DOUBLE = int32(C.AV_OPT_TYPE_DOUBLE)
|
||||
AV_OPT_TYPE_FLOAT = int32(C.AV_OPT_TYPE_FLOAT)
|
||||
AV_OPT_TYPE_STRING = int32(C.AV_OPT_TYPE_STRING)
|
||||
AV_OPT_TYPE_RATIONAL = int32(C.AV_OPT_TYPE_RATIONAL)
|
||||
AV_OPT_TYPE_BINARY = int32(C.AV_OPT_TYPE_BINARY)
|
||||
AV_OPT_TYPE_DICT = int32(C.AV_OPT_TYPE_DICT)
|
||||
AV_OPT_TYPE_UINT64 = int32(C.AV_OPT_TYPE_UINT64)
|
||||
AV_OPT_TYPE_CONST = int32(C.AV_OPT_TYPE_CONST)
|
||||
AV_OPT_TYPE_IMAGE_SIZE = int32(C.AV_OPT_TYPE_IMAGE_SIZE)
|
||||
AV_OPT_TYPE_PIXEL_FMT = int32(C.AV_OPT_TYPE_PIXEL_FMT)
|
||||
AV_OPT_TYPE_SAMPLE_FMT = int32(C.AV_OPT_TYPE_SAMPLE_FMT)
|
||||
AV_OPT_TYPE_VIDEO_RATE = int32(C.AV_OPT_TYPE_VIDEO_RATE)
|
||||
AV_OPT_TYPE_DURATION = int32(C.AV_OPT_TYPE_DURATION)
|
||||
AV_OPT_TYPE_COLOR = int32(C.AV_OPT_TYPE_COLOR)
|
||||
AV_OPT_TYPE_CHANNEL_LAYOUT = int32(C.AV_OPT_TYPE_CHANNEL_LAYOUT)
|
||||
AV_OPT_TYPE_BOOL = int32(C.AV_OPT_TYPE_BOOL)
|
||||
AV_OPT_TYPE_FLAGS = AvOptionType(C.AV_OPT_TYPE_FLAGS)
|
||||
AV_OPT_TYPE_INT = AvOptionType(C.AV_OPT_TYPE_INT)
|
||||
AV_OPT_TYPE_INT64 = AvOptionType(C.AV_OPT_TYPE_INT64)
|
||||
AV_OPT_TYPE_DOUBLE = AvOptionType(C.AV_OPT_TYPE_DOUBLE)
|
||||
AV_OPT_TYPE_FLOAT = AvOptionType(C.AV_OPT_TYPE_FLOAT)
|
||||
AV_OPT_TYPE_STRING = AvOptionType(C.AV_OPT_TYPE_STRING)
|
||||
AV_OPT_TYPE_RATIONAL = AvOptionType(C.AV_OPT_TYPE_RATIONAL)
|
||||
AV_OPT_TYPE_BINARY = AvOptionType(C.AV_OPT_TYPE_BINARY)
|
||||
AV_OPT_TYPE_DICT = AvOptionType(C.AV_OPT_TYPE_DICT)
|
||||
AV_OPT_TYPE_UINT64 = AvOptionType(C.AV_OPT_TYPE_UINT64)
|
||||
AV_OPT_TYPE_CONST = AvOptionType(C.AV_OPT_TYPE_CONST)
|
||||
AV_OPT_TYPE_IMAGE_SIZE = AvOptionType(C.AV_OPT_TYPE_IMAGE_SIZE)
|
||||
AV_OPT_TYPE_PIXEL_FMT = AvOptionType(C.AV_OPT_TYPE_PIXEL_FMT)
|
||||
AV_OPT_TYPE_SAMPLE_FMT = AvOptionType(C.AV_OPT_TYPE_SAMPLE_FMT)
|
||||
AV_OPT_TYPE_VIDEO_RATE = AvOptionType(C.AV_OPT_TYPE_VIDEO_RATE)
|
||||
AV_OPT_TYPE_DURATION = AvOptionType(C.AV_OPT_TYPE_DURATION)
|
||||
AV_OPT_TYPE_COLOR = AvOptionType(C.AV_OPT_TYPE_COLOR)
|
||||
AV_OPT_TYPE_CHANNEL_LAYOUT = AvOptionType(C.AV_OPT_TYPE_CHANNEL_LAYOUT)
|
||||
AV_OPT_TYPE_BOOL = AvOptionType(C.AV_OPT_TYPE_BOOL)
|
||||
)
|
||||
|
||||
type AvOption C.struct_AVOption
|
||||
@@ -82,7 +92,7 @@ func AvSetOptionsString(ctx unsafe.Pointer, opts, keyValSep, pairsSep string) in
|
||||
(*C.char)(keyValSepPtr), (*C.char)(pairsSepPtr)))
|
||||
}
|
||||
|
||||
// TODO. av_opt_set_from_string
|
||||
// NONEED: av_opt_set_from_string
|
||||
|
||||
// AvOptFree frees all allocated objects in obj.
|
||||
func AvOptFree(obj unsafe.Pointer) {
|
||||
@@ -109,7 +119,7 @@ func AvOptSetDict2(obj unsafe.Pointer, options **AvDictionary, searchFlags int32
|
||||
(C.int)(searchFlags)))
|
||||
}
|
||||
|
||||
// TODO. av_opt_get_key_value
|
||||
// NONEED: av_opt_get_key_value
|
||||
|
||||
const (
|
||||
AV_OPT_FLAG_IMPLICIT_KEY = int32(C.AV_OPT_FLAG_IMPLICIT_KEY)
|
||||
@@ -171,7 +181,8 @@ func AvOptFind(obj unsafe.Pointer, name, unit string, optFlags, searchFlags int3
|
||||
defer nameFunc()
|
||||
unitPtr, unitFunc := StringCasting(unit)
|
||||
defer unitFunc()
|
||||
return (*AvOption)(C.av_opt_find(obj, namePtr, unitPtr, (C.int)(optFlags), (C.int)(searchFlags)))
|
||||
return (*AvOption)(C.av_opt_find(obj, (*C.char)(namePtr), (*C.char)(unitPtr),
|
||||
(C.int)(optFlags), (C.int)(searchFlags)))
|
||||
}
|
||||
|
||||
// AvOptFind2 looks for an option in an object. Consider only options which
|
||||
@@ -182,7 +193,7 @@ func AvOptFind2(obj unsafe.Pointer, name, unit string, optFlags, searchFlags int
|
||||
defer nameFunc()
|
||||
unitPtr, unitFunc := StringCasting(unit)
|
||||
defer unitFunc()
|
||||
return (*AvOption)(C.av_opt_find2(obj, namePtr, unitPtr,
|
||||
return (*AvOption)(C.av_opt_find2(obj, (*C.char)(namePtr), (*C.char)(unitPtr),
|
||||
(C.int)(optFlags), (C.int)(searchFlags), targetObj))
|
||||
}
|
||||
|
||||
@@ -286,7 +297,15 @@ func AvOptSetDictVal(obj unsafe.Pointer, name string, val *AvDictionary, searchF
|
||||
return (int32)(C.av_opt_set_dict_val(obj, (*C.char)(namePtr), (*C.struct_AVDictionary)(val), (C.int)(searchFlags)))
|
||||
}
|
||||
|
||||
// TODO. av_opt_set_int_list
|
||||
// AvOptSetIntList sets a binary option to an integer list.
|
||||
func av_opt_set_int_list[T HelperInteger](obj unsafe.Pointer, name string,
|
||||
val *T, term uint64, flags int32) int32 {
|
||||
namePtr, nameFunc := StringCasting(name)
|
||||
defer nameFunc()
|
||||
size := (int32)(unsafe.Sizeof(*val))
|
||||
return (int32)(C.av_opt_set_int_list_wrap(obj, (*C.char)(namePtr),
|
||||
unsafe.Pointer(val), (C.uint64_t)(term), (C.int)(flags), (C.int)(size)))
|
||||
}
|
||||
|
||||
// AvOptGet
|
||||
func AvOptGet(obj unsafe.Pointer, name string, searchFlags int32, outVal **uint8) int32 {
|
||||
|
72
avutil_parseutils.go
Normal file
72
avutil_parseutils.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package ffmpeg
|
||||
|
||||
/*
|
||||
#include <libavutil/parseutils.h>
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
// AvParseRatio parses str and store the parsed ratio in q.
|
||||
func AvParseRatio(q *AvRational, str string, max, logOffset int32, logCtx unsafe.Pointer) int32 {
|
||||
strPtr, strFunc := StringCasting(str)
|
||||
defer strFunc()
|
||||
return (int32)(C.av_parse_ratio((*C.struct_AVRational)(q),
|
||||
(*C.char)(strPtr), (C.int)(max), (C.int)(logOffset), logCtx))
|
||||
}
|
||||
|
||||
// AvParseRatioQuiet
|
||||
func AvParseRatioQuiet(q *AvRational, str string, max int32) int32 {
|
||||
strPtr, strFunc := StringCasting(str)
|
||||
defer strFunc()
|
||||
return (int32)(C.av_parse_ratio((*C.struct_AVRational)(q),
|
||||
(*C.char)(strPtr), (C.int)(max), (C.int)(AV_LOG_MAX_OFFSET), nil))
|
||||
}
|
||||
|
||||
// AvParseVideoSize parses str and put in width_ptr and height_ptr the detected values.
|
||||
func AvParseVideoSize(widthPtr, heightPtr *int32, str string) int32 {
|
||||
strPtr, strFunc := StringCasting(str)
|
||||
defer strFunc()
|
||||
return (int32)(C.av_parse_video_size((*C.int)(widthPtr), (*C.int)(heightPtr), (*C.char)(strPtr)))
|
||||
}
|
||||
|
||||
// AvParseVideoRate parses str and store the detected values in *rate.
|
||||
func AvParseVideoRate(rate *AvRational, str string) int32 {
|
||||
strPtr, strFunc := StringCasting(str)
|
||||
defer strFunc()
|
||||
return (int32)(C.av_parse_video_rate((*C.struct_AVRational)(rate), (*C.char)(strPtr)))
|
||||
}
|
||||
|
||||
// AvParseColor puts the RGBA values that correspond to color_string in rgba_color.
|
||||
func AvParseColor(rgbaColor *uint8, colorString string, slen int32, logCtx unsafe.Pointer) int32 {
|
||||
strPtr, strFunc := StringCasting(colorString)
|
||||
defer strFunc()
|
||||
return (int32)(C.av_parse_color((*C.uint8_t)(rgbaColor), (*C.char)(strPtr), (C.int)(slen), logCtx))
|
||||
}
|
||||
|
||||
// AvGetKnownColorName gets the name of a color from the internal table of hard-coded named colors.
|
||||
func AvGetKnownColorName(colorIdx int32, rgb **uint8) string {
|
||||
return C.GoString(C.av_get_known_color_name((C.int)(colorIdx), (**C.uint8_t)(unsafe.Pointer(rgb))))
|
||||
}
|
||||
|
||||
// AvParseTime parse timestr and return in *time a corresponding number of microseconds.
|
||||
func AvParseTime(timeval *int64, timestr string, duration int32) int32 {
|
||||
strPtr, strFunc := StringCasting(timestr)
|
||||
defer strFunc()
|
||||
return (int32)(C.av_parse_time((*C.int64_t)(timeval), (*C.char)(strPtr), (C.int)(duration)))
|
||||
}
|
||||
|
||||
// AvFindInfoTag attempts to find a specific tag in a URL.
|
||||
func AvFindInfoTag(tag1, info string) (val string, ret int32) {
|
||||
tag1Ptr, tag1Func := StringCasting(tag1)
|
||||
defer tag1Func()
|
||||
infoPtr, infoFunc := StringCasting(info)
|
||||
defer infoFunc()
|
||||
infoBuf := make([]C.char, len(info))
|
||||
ret = (int32)(C.av_find_info_tag(&infoBuf[0], (C.int)(len(info)),
|
||||
(*C.char)(tag1Ptr), (*C.char)(infoPtr)))
|
||||
return C.GoString(&infoBuf[0]), ret
|
||||
}
|
||||
|
||||
// NONEED: av_small_strptime
|
||||
|
||||
// NONEED: av_timegm
|
@@ -145,8 +145,14 @@ func AvGetPixFmtString(buf *int8, bufSize int32, pixFmt AvPixelFormat) string {
|
||||
|
||||
// AvReadImageLine2 reads a line from an image, and write the values of the
|
||||
// pixel format component c to dst.
|
||||
func AvReadImageLine2(dst unsafe.Pointer, data [4]*uint8, linesize [4]int,
|
||||
func AvReadImageLine2(dst unsafe.Pointer, data []*uint8, linesize []int,
|
||||
desc *AvPixFmtDescriptor, x, y, c, w, readPalComponent, dstElementSize int32) {
|
||||
if len(data) != 4 {
|
||||
panic("data need len = 4")
|
||||
}
|
||||
if len(linesize) != 4 {
|
||||
panic("linesize need len = 4")
|
||||
}
|
||||
C.av_read_image_line2(dst,
|
||||
(**C.uint8_t)(unsafe.Pointer(&data[0])),
|
||||
(*C.int)(unsafe.Pointer(&linesize[0])),
|
||||
@@ -157,8 +163,14 @@ func AvReadImageLine2(dst unsafe.Pointer, data [4]*uint8, linesize [4]int,
|
||||
|
||||
// AvReadImageLine reads a line from an image, and write the values of the
|
||||
// pixel format component c to dst.
|
||||
func AvReadImageLine(dst *uint16, data [4]*uint8, linesize [4]int,
|
||||
func AvReadImageLine(dst *uint16, data []*uint8, linesize []int,
|
||||
desc *AvPixFmtDescriptor, x, y, c, w, readPalComponent int32) {
|
||||
if len(data) != 4 {
|
||||
panic("data need len = 4")
|
||||
}
|
||||
if len(linesize) != 4 {
|
||||
panic("linesize need len = 4")
|
||||
}
|
||||
C.av_read_image_line((*C.uint16_t)(dst),
|
||||
(**C.uint8_t)(unsafe.Pointer(&data[0])),
|
||||
(*C.int)(unsafe.Pointer(&linesize[0])),
|
||||
@@ -168,8 +180,14 @@ func AvReadImageLine(dst *uint16, data [4]*uint8, linesize [4]int,
|
||||
}
|
||||
|
||||
// AvWriteImageLine2 writes the values from src to the pixel format component c of an image line.
|
||||
func AvWriteImageLine2(src unsafe.Pointer, data [4]*uint8, linesize [4]int,
|
||||
func AvWriteImageLine2(src unsafe.Pointer, data []*uint8, linesize []int,
|
||||
desc *AvPixFmtDescriptor, x, y, c, w, srcElementSize int32) {
|
||||
if len(data) != 4 {
|
||||
panic("data need len = 4")
|
||||
}
|
||||
if len(linesize) != 4 {
|
||||
panic("linesize need len = 4")
|
||||
}
|
||||
C.av_write_image_line2(src,
|
||||
(**C.uint8_t)(unsafe.Pointer(&data[0])),
|
||||
(*C.int)(unsafe.Pointer(&linesize[0])),
|
||||
@@ -179,8 +197,14 @@ func AvWriteImageLine2(src unsafe.Pointer, data [4]*uint8, linesize [4]int,
|
||||
}
|
||||
|
||||
// AvWriteImageLine writes the values from src to the pixel format component c of an image line.
|
||||
func AvWriteImageLine(src *uint16, data [4]*uint8, linesize [4]int,
|
||||
func AvWriteImageLine(src *uint16, data []*uint8, linesize []int,
|
||||
desc *AvPixFmtDescriptor, x, y, c, w int32) {
|
||||
if len(data) != 4 {
|
||||
panic("data need len = 4")
|
||||
}
|
||||
if len(linesize) != 4 {
|
||||
panic("linesize need len = 4")
|
||||
}
|
||||
C.av_write_image_line((*C.uint16_t)(src),
|
||||
(**C.uint8_t)(unsafe.Pointer(&data[0])),
|
||||
(*C.int)(unsafe.Pointer(&linesize[0])),
|
||||
|
17
avutil_pixelutils.go
Normal file
17
avutil_pixelutils.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package ffmpeg
|
||||
|
||||
/*
|
||||
#include <libavutil/pixelutils.h>
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
type AvPixelutilsSadFn C.av_pixelutils_sad_fn
|
||||
|
||||
// AvPixelutilsGetSadFn gets a potentially optimized pointer to a Sum-of-absolute-differences
|
||||
// function (see the av_pixelutils_sad_fn prototype).
|
||||
func AvPixelutilsGetSadFn(wBits, hBits, aligned int32, logCtx unsafe.Pointer) AvPixelutilsSadFn {
|
||||
return (AvPixelutilsSadFn)(C.av_pixelutils_get_sad_fn((C.int)(wBits), (C.int)(hBits),
|
||||
(C.int)(aligned), logCtx))
|
||||
}
|
@@ -6,7 +6,7 @@ package ffmpeg
|
||||
import "C"
|
||||
|
||||
// Pixel format.
|
||||
type AvPixelFormat int32
|
||||
type AvPixelFormat = C.enum_AVPixelFormat
|
||||
|
||||
const (
|
||||
AV_PIX_FMT_NONE = AvPixelFormat(C.AV_PIX_FMT_NONE)
|
||||
@@ -343,7 +343,7 @@ const (
|
||||
)
|
||||
|
||||
// Chromaticity coordinates of the source primaries.
|
||||
type AvColorPrimaries int32
|
||||
type AvColorPrimaries = C.enum_AVColorPrimaries
|
||||
|
||||
const (
|
||||
AVCOL_PRI_RESERVED0 = AvColorPrimaries(C.AVCOL_PRI_RESERVED0)
|
||||
@@ -367,7 +367,7 @@ const (
|
||||
)
|
||||
|
||||
// Color Transfer Characteristic.
|
||||
type AvColorTransferCharacteristic int32
|
||||
type AvColorTransferCharacteristic = C.enum_AVColorTransferCharacteristic
|
||||
|
||||
const (
|
||||
AVCOL_TRC_RESERVED0 = AvColorTransferCharacteristic(C.AVCOL_TRC_RESERVED0)
|
||||
@@ -395,7 +395,7 @@ const (
|
||||
)
|
||||
|
||||
// AvColorSpace
|
||||
type AvColorSpace int32
|
||||
type AvColorSpace = C.enum_AVColorSpace
|
||||
|
||||
const (
|
||||
AVCOL_SPC_RGB = AvColorSpace(C.AVCOL_SPC_RGB)
|
||||
@@ -418,7 +418,7 @@ const (
|
||||
)
|
||||
|
||||
// AvColorRange
|
||||
type AvColorRange int32
|
||||
type AvColorRange = C.enum_AVColorRange
|
||||
|
||||
const (
|
||||
AVCOL_RANGE_UNSPECIFIED = AvColorRange(C.AVCOL_RANGE_UNSPECIFIED)
|
||||
@@ -428,7 +428,7 @@ const (
|
||||
)
|
||||
|
||||
// AvChromaLocation
|
||||
type AvChromaLocation int32
|
||||
type AvChromaLocation = C.enum_AVChromaLocation
|
||||
|
||||
const (
|
||||
AVCHROMA_LOC_UNSPECIFIED = AvChromaLocation(C.AVCHROMA_LOC_UNSPECIFIED)
|
||||
|
@@ -7,7 +7,7 @@ import "C"
|
||||
import "unsafe"
|
||||
|
||||
// AvSampleFormat
|
||||
type AvSampleFormat int32
|
||||
type AvSampleFormat = C.enum_AVSampleFormat
|
||||
|
||||
const (
|
||||
AV_SAMPLE_FMT_NONE = AvSampleFormat(C.AV_SAMPLE_FMT_NONE)
|
||||
|
@@ -141,7 +141,7 @@ func main() {
|
||||
}
|
||||
|
||||
frame.SetNbSamples(avctx.GetFrameSize())
|
||||
frame.SetFormat(int32(avctx.GetSampleFmt()))
|
||||
frame.SetFormat(avctx.GetSampleFmt())
|
||||
frame.SetChannelLayout(avctx.GetChannelLayout())
|
||||
|
||||
// allocate the data buffers
|
||||
|
@@ -101,7 +101,7 @@ func main() {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate video frame\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
frame.SetFormat(int32(avctx.GetPixFmt()))
|
||||
frame.SetFormat(avctx.GetPixFmt())
|
||||
frame.SetWidth(avctx.GetWidth())
|
||||
frame.SetHeight(avctx.GetHeight())
|
||||
|
||||
|
@@ -1,5 +1,296 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/qrtc/ffmpeg-dev-go"
|
||||
)
|
||||
|
||||
const (
|
||||
INPUT_SAMPLERATE = 48000
|
||||
INPUT_FORMAT = ffmpeg.AV_SAMPLE_FMT_FLTP
|
||||
INPUT_CHANNEL_LAYOUT = ffmpeg.AV_CH_LAYOUT_5POINT0
|
||||
VOLUME_VAL = 0.90
|
||||
FRAME_SIZE = 1024
|
||||
)
|
||||
|
||||
func initFilterGraph() (graph *ffmpeg.AvFilterGraph, src *ffmpeg.AvFilterContext, sink *ffmpeg.AvFilterContext, ret int32) {
|
||||
var filterGraph *ffmpeg.AvFilterGraph
|
||||
var abufferCtx *ffmpeg.AvFilterContext
|
||||
var abuffer *ffmpeg.AvFilter
|
||||
var volumeCtx *ffmpeg.AvFilterContext
|
||||
var volume *ffmpeg.AvFilter
|
||||
var aformatCtx *ffmpeg.AvFilterContext
|
||||
var aformat *ffmpeg.AvFilter
|
||||
var abuffersinkCtx *ffmpeg.AvFilterContext
|
||||
var abuffersink *ffmpeg.AvFilter
|
||||
var optionsDict *ffmpeg.AvDictionary
|
||||
|
||||
// Create a new filtergraph, which will contain all the filters.
|
||||
if filterGraph = ffmpeg.AvFilterGraphAlloc(); filterGraph == nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to create filter graph.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
}
|
||||
|
||||
// Create the abuffer filter;
|
||||
// it will be used for feeding the data into the graph.
|
||||
if abuffer = ffmpeg.AvFilterGetByName("abuffer"); abuffer == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not find the abuffer filter.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR_FILTER_NOT_FOUND
|
||||
}
|
||||
|
||||
if abufferCtx = ffmpeg.AvFilterGraphAllocFilter(filterGraph, abuffer, "src"); abufferCtx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate the abuffer instance.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
}
|
||||
|
||||
ffmpeg.AvOptSet(unsafe.Pointer(abufferCtx), "channel_layout",
|
||||
ffmpeg.AvGetChannelLayoutString(0, INPUT_CHANNEL_LAYOUT), ffmpeg.AV_OPT_SEARCH_CHILDREN)
|
||||
ffmpeg.AvOptSet(unsafe.Pointer(abufferCtx), "sample_fmt",
|
||||
ffmpeg.AvGetSampleFmtName(INPUT_FORMAT), ffmpeg.AV_OPT_SEARCH_CHILDREN)
|
||||
ffmpeg.AvOptSetQ(unsafe.Pointer(abufferCtx), "time_base",
|
||||
ffmpeg.AvMakeQ(1, INPUT_SAMPLERATE), ffmpeg.AV_OPT_SEARCH_CHILDREN)
|
||||
ffmpeg.AvOptSetInt(unsafe.Pointer(abufferCtx), "sample_rate",
|
||||
INPUT_SAMPLERATE, ffmpeg.AV_OPT_SEARCH_CHILDREN)
|
||||
|
||||
// Now initialize the filter; we pass NULL options, since we have already set all the options above.
|
||||
if ret = ffmpeg.AvFilterInitStr(abufferCtx, ""); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Could not initialize the abuffer filter.\n")
|
||||
return nil, nil, nil, ret
|
||||
}
|
||||
|
||||
// Create volume filter.
|
||||
if volume = ffmpeg.AvFilterGetByName("volume"); volume == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not find the volume filter.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR_FILTER_NOT_FOUND
|
||||
}
|
||||
|
||||
if volumeCtx = ffmpeg.AvFilterGraphAllocFilter(filterGraph, volume, "volume"); volumeCtx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate the volume instance.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
}
|
||||
|
||||
// A different way of passing the options is as key/value pairs in a
|
||||
// dictionary.
|
||||
ffmpeg.AvDictSet(&optionsDict, "volume", fmt.Sprintf("%f", VOLUME_VAL), 0)
|
||||
ret = ffmpeg.AvFilterInitDict(volumeCtx, &optionsDict)
|
||||
ffmpeg.AvDictFree(&optionsDict)
|
||||
if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Could not initialize the volume filter.\n")
|
||||
return nil, nil, nil, ret
|
||||
}
|
||||
|
||||
// Create the aformat filter;
|
||||
// it ensures that the output is of the format we want.
|
||||
if aformat = ffmpeg.AvFilterGetByName("aformat"); aformat == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not find the aformat filter.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR_FILTER_NOT_FOUND
|
||||
}
|
||||
|
||||
if aformatCtx = ffmpeg.AvFilterGraphAllocFilter(filterGraph, aformat, "aformat"); aformatCtx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate the aformat instance.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
}
|
||||
|
||||
// A third way of passing the options is in a string of the form
|
||||
// key1=value1:key2=value2....
|
||||
optionsStr := fmt.Sprintf("sample_fmts=%s:sample_rates=%d:channel_layouts=0x%d",
|
||||
ffmpeg.AvGetSampleFmtName(ffmpeg.AV_SAMPLE_FMT_S16), 44100, (uint64)(ffmpeg.AV_CH_LAYOUT_STEREO))
|
||||
if ret = ffmpeg.AvFilterInitStr(aformatCtx, optionsStr); ret < 0 {
|
||||
ffmpeg.AvLog(nil, ffmpeg.AV_LOG_ERROR, "Could not initialize the aformat filter.\n")
|
||||
return nil, nil, nil, ret
|
||||
}
|
||||
|
||||
// Finally create the abuffersink filter;
|
||||
// it will be used to get the filtered data out of the graph.
|
||||
if abuffersink = ffmpeg.AvFilterGetByName("abuffersink"); abuffersink == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not find the abuffersink filter.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR_FILTER_NOT_FOUND
|
||||
}
|
||||
|
||||
if abuffersinkCtx = ffmpeg.AvFilterGraphAllocFilter(filterGraph, abuffersink, "sink"); abuffersinkCtx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate the abuffersink instance.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
}
|
||||
|
||||
// This filter takes no options.
|
||||
if ret = ffmpeg.AvFilterInitStr(abuffersinkCtx, ""); ret < 0 {
|
||||
ffmpeg.AvLog(nil, ffmpeg.AV_LOG_ERROR, "Could not initialize the abuffersink instance.\n")
|
||||
return nil, nil, nil, ret
|
||||
}
|
||||
|
||||
// Connect the filters;
|
||||
// in this simple case the filters just form a linear chain.
|
||||
ret = ffmpeg.AvFilterLink2(abufferCtx, 0, volumeCtx, 0)
|
||||
if ret >= 0 {
|
||||
ret = ffmpeg.AvFilterLink2(volumeCtx, 0, aformatCtx, 0)
|
||||
}
|
||||
if ret >= 0 {
|
||||
ret = ffmpeg.AvFilterLink2(aformatCtx, 0, abuffersinkCtx, 0)
|
||||
}
|
||||
if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error connecting filters\n")
|
||||
return nil, nil, nil, ret
|
||||
}
|
||||
|
||||
// Configure the graph.
|
||||
if ret = ffmpeg.AvFilterGraphConfig(filterGraph, nil); ret < 0 {
|
||||
ffmpeg.AvLog(nil, ffmpeg.AV_LOG_ERROR, "Error configuring the filter graph\n")
|
||||
return nil, nil, nil, ret
|
||||
}
|
||||
|
||||
return filterGraph, abufferCtx, abuffersinkCtx, 0
|
||||
}
|
||||
|
||||
// Do something useful with the filtered data: this simple
|
||||
// example just prints the MD5 checksum of each plane to stdout.
|
||||
func processOutput(md5 *ffmpeg.AvMD5, frame *ffmpeg.AvFrame) int32 {
|
||||
planar := ffmpeg.AvSampleFmtIsPlanar(frame.GetFormat())
|
||||
channels := ffmpeg.AvGetChannelLayoutNbChannels(frame.GetChannelLayout())
|
||||
planes := channels
|
||||
if planar == 0 {
|
||||
planes = 1
|
||||
}
|
||||
bps := ffmpeg.AvGetBytesPerSample(frame.GetFormat())
|
||||
planeSize := bps * frame.GetNbSamples()
|
||||
if planar == 0 {
|
||||
planeSize *= channels
|
||||
}
|
||||
|
||||
for i := 0; i < int(planes); i++ {
|
||||
var checksum [16]uint8
|
||||
|
||||
ffmpeg.AvMd5Init(md5)
|
||||
ffmpeg.AvMd5Sum(&checksum[0], frame.GetExtendedDataIdx(i), planeSize)
|
||||
|
||||
fmt.Fprintf(os.Stdout, "plane %d: 0x", i)
|
||||
for j := 0; j < len(checksum); j++ {
|
||||
fmt.Fprintf(os.Stdout, "%02X", checksum[j])
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "\n")
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "\n")
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// Construct a frame of audio data to be filtered;
|
||||
// this simple example just synthesizes a sine wave.
|
||||
func getInput(frame *ffmpeg.AvFrame, frameNum int32) int32 {
|
||||
// Set up the frame properties and allocate the buffer for the data.
|
||||
frame.SetSampleRate(INPUT_SAMPLERATE)
|
||||
frame.SetFormat(INPUT_FORMAT)
|
||||
frame.SetChannelLayout(INPUT_CHANNEL_LAYOUT)
|
||||
frame.SetNbSamples(FRAME_SIZE)
|
||||
frame.SetPts(int64(frameNum) * FRAME_SIZE)
|
||||
|
||||
if ret := ffmpeg.AvFrameGetBuffer(frame, 0); ret < 0 {
|
||||
return ret
|
||||
}
|
||||
|
||||
// Fill the data for each channel.
|
||||
for i := 0; i < 5; i++ {
|
||||
dataLen := int(frame.GetNbSamples())
|
||||
data := (*float32)(unsafe.Pointer(frame.GetExtendedDataIdx(i)))
|
||||
dataSlice := unsafe.Slice(data, dataLen)
|
||||
|
||||
for j := 0; j < dataLen; j++ {
|
||||
dataSlice[j] = (float32)(math.Sin(2 * math.Pi * (float64)(int(frameNum)+j) * (float64)(i+1) / FRAME_SIZE))
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
var md5 *ffmpeg.AvMD5
|
||||
var graph *ffmpeg.AvFilterGraph
|
||||
var src, sink *ffmpeg.AvFilterContext
|
||||
var frame *ffmpeg.AvFrame
|
||||
var ret int32
|
||||
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Fprintf(os.Stderr, "Usage: %s <duration>\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
duration, err := strconv.ParseFloat(os.Args[1], 32)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Invalid duration: %s\n", os.Args[1])
|
||||
os.Exit(1)
|
||||
}
|
||||
nbFrames := (int32)(duration * INPUT_SAMPLERATE / FRAME_SIZE)
|
||||
if nbFrames <= 0 {
|
||||
fmt.Fprintf(os.Stderr, "Invalid duration: %s\n", os.Args[1])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Allocate the frame we will be using to store the data.
|
||||
if frame = ffmpeg.AvFrameAlloc(); frame == nil {
|
||||
fmt.Fprintf(os.Stderr, "Error allocating the frame\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if md5 = ffmpeg.AvMd5Alloc(); md5 == nil {
|
||||
fmt.Fprintf(os.Stderr, "Error allocating the MD5 context\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Set up the filtergraph.
|
||||
if graph, src, sink, ret = initFilterGraph(); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Unable to init filter graph:")
|
||||
goto fail
|
||||
}
|
||||
|
||||
// the main filtering loop
|
||||
for i := int32(0); i < nbFrames; i++ {
|
||||
// get an input frame to be filtered
|
||||
if ret = getInput(frame, i); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error generating input frame:")
|
||||
goto fail
|
||||
}
|
||||
|
||||
// Send the frame to the input of the filtergraph.
|
||||
if ret = ffmpeg.AvBuffersrcAddFrame(src, frame); ret < 0 {
|
||||
ffmpeg.AvFrameUnref(frame)
|
||||
fmt.Fprintf(os.Stderr, "Error submitting the frame to the filtergraph:")
|
||||
goto fail
|
||||
}
|
||||
|
||||
// Get all the filtered output that is available.
|
||||
for ffmpeg.AvBuffersinkGetFrame(sink, frame) >= 0 {
|
||||
// now do something with our filtered frame
|
||||
if ret = processOutput(md5, frame); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error processing the filtered frame:")
|
||||
goto fail
|
||||
}
|
||||
ffmpeg.AvFrameUnref(frame)
|
||||
}
|
||||
|
||||
if ret == ffmpeg.AVERROR(int32(syscall.EAGAIN)) {
|
||||
// Need to feed more frames in.
|
||||
continue
|
||||
} else if ret == ffmpeg.AVERROR_EOF {
|
||||
// Nothing more to do, finish.
|
||||
break
|
||||
} else if ret < 0 {
|
||||
// An error occurred.
|
||||
fmt.Fprintf(os.Stderr, "Error filtering the data:")
|
||||
goto fail
|
||||
}
|
||||
}
|
||||
|
||||
ffmpeg.AvFilterGraphFree(&graph)
|
||||
ffmpeg.AvFrameFree(&frame)
|
||||
ffmpeg.AvFreep(unsafe.Pointer(&md5))
|
||||
return
|
||||
|
||||
fail:
|
||||
fmt.Fprintf(os.Stderr, "%s\n", ffmpeg.AvErr2str(ret))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
@@ -1,5 +1,115 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
ffmpeg "github.com/qrtc/ffmpeg-dev-go"
|
||||
)
|
||||
|
||||
func fillYuvImage(data [4]*uint8, linesize [4]int32, width, height, frameIndex int32) {
|
||||
// Y
|
||||
data0 := unsafe.Slice(data[0], height*linesize[0]+width)
|
||||
for y := int32(0); y < height; y++ {
|
||||
for x := int32(0); x < width; x++ {
|
||||
data0[y*linesize[0]+x] = (uint8)(x + y + frameIndex*3)
|
||||
}
|
||||
}
|
||||
|
||||
// Cb and Cr
|
||||
data1 := unsafe.Slice(data[1], height*width/4)
|
||||
data2 := unsafe.Slice(data[2], height*width/4)
|
||||
for y := int32(0); y < height/2; y++ {
|
||||
for x := int32(0); x < width/2; x++ {
|
||||
data1[y*linesize[1]+x] = (uint8)(128 + y + frameIndex*2)
|
||||
data2[y*linesize[2]+x] = (uint8)(64 + x + frameIndex*5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var ret int32
|
||||
var dstBufsize int32
|
||||
var srcW int32 = 320
|
||||
var srcH int32 = 240
|
||||
var dstW, dstH int32
|
||||
var srcData, dstData [4]*uint8
|
||||
var srcLinesize, dstLinesize [4]int32
|
||||
var srcPixFmt = ffmpeg.AV_PIX_FMT_YUV420P
|
||||
var dstPixFmt = ffmpeg.AV_PIX_FMT_RGB24
|
||||
|
||||
if len(os.Args) != 3 {
|
||||
fmt.Fprintf(os.Stderr, "Usage: %s output_file output_size\n"+
|
||||
"API example program to show how to scale an image with libswscale.\n"+
|
||||
"This program generates a series of pictures, rescales them to the given "+
|
||||
"output_size and saves them to an output file named output_file\n."+
|
||||
"\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
dstFilename := os.Args[1]
|
||||
dstSize := os.Args[2]
|
||||
|
||||
if ret = ffmpeg.AvParseVideoSize(&dstW, &dstH, dstSize); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"Invalid size '%s', must be in the form WxH or a valid size abbreviation\n", dstSize)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
dstFile, err := os.OpenFile(dstFilename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not open %s\n", dstFilename)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// create scaling context
|
||||
swsCtx := ffmpeg.SwsGetContext(srcW, srcH, srcPixFmt,
|
||||
dstW, dstH, dstPixFmt,
|
||||
ffmpeg.SWS_BILINEAR, nil, nil, nil)
|
||||
if swsCtx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Impossible to create scale context for the conversion "+
|
||||
"fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
|
||||
ffmpeg.AvGetPixFmtName(srcPixFmt), srcW, srcH,
|
||||
ffmpeg.AvGetPixFmtName(dstPixFmt), dstW, dstH)
|
||||
ret = ffmpeg.AVERROR(int32(syscall.EINVAL))
|
||||
goto end
|
||||
}
|
||||
|
||||
// allocate source and destination image buffers
|
||||
if ret = ffmpeg.AvImageAlloc(srcData[:], srcLinesize[:], srcW, srcH, srcPixFmt, 16); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate source image\n")
|
||||
goto end
|
||||
}
|
||||
|
||||
// buffer is going to be written to rawvideo file, no alignment
|
||||
if ret = ffmpeg.AvImageAlloc(dstData[:], dstLinesize[:], dstW, dstH, dstPixFmt, 1); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate destination image\n")
|
||||
goto end
|
||||
}
|
||||
dstBufsize = ret
|
||||
|
||||
for i := int32(0); i < 100; i++ {
|
||||
// generate synthetic video
|
||||
fillYuvImage(srcData, srcLinesize, srcW, srcH, i)
|
||||
|
||||
// convert to destination format
|
||||
ffmpeg.SwsScale(swsCtx, srcData[:], srcLinesize[:], 0, srcH, dstData[:], dstLinesize[:])
|
||||
|
||||
// write scaled image to file
|
||||
dstFile.Write(unsafe.Slice(dstData[0], dstBufsize))
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "Scaling succeeded. Play the output file with the command:\n"+
|
||||
"ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
|
||||
ffmpeg.AvGetPixFmtName(dstPixFmt), dstW, dstH, dstFilename)
|
||||
|
||||
end:
|
||||
dstFile.Close()
|
||||
ffmpeg.AvFreep(unsafe.Pointer(&srcData[0]))
|
||||
ffmpeg.AvFreep(unsafe.Pointer(&dstData[0]))
|
||||
ffmpeg.SwsFreeContext(swsCtx)
|
||||
if ret < 0 {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@@ -447,7 +447,7 @@ func initOutputFrame(outputcodecContext *ffmpeg.AvCodecContext,
|
||||
// are assumed for simplicity.
|
||||
frame.SetNbSamples(frameSize)
|
||||
frame.SetChannelLayout(outputcodecContext.GetChannelLayout())
|
||||
frame.SetFormat(int32(outputcodecContext.GetSampleFmt()))
|
||||
frame.SetFormat(outputcodecContext.GetSampleFmt())
|
||||
frame.SetSampleRate(outputcodecContext.GetSampleRate())
|
||||
|
||||
// Allocate the samples of the created frame. This call will make
|
||||
|
@@ -2,6 +2,6 @@ package ffmpeg
|
||||
|
||||
/*
|
||||
#cgo CPPFLAGS: -Wno-deprecated-declarations
|
||||
#cgo pkg-config: libavdevice libavformat libavfilter libavresample libavcodec libpostproc libswscale libswresample libavutil
|
||||
#cgo pkg-config: libavdevice libavformat libavfilter libavcodec libpostproc libswscale libswresample libavutil
|
||||
*/
|
||||
import "C"
|
||||
|
10
postproc.go
10
postproc.go
@@ -30,11 +30,17 @@ type PpContext C.pp_context
|
||||
type PpMode C.pp_mode
|
||||
|
||||
// PpPostprocess
|
||||
func PpPostprocess(src [3]*uint8, srcStride []int32,
|
||||
dst [3]*uint8, dstStride []int32,
|
||||
func PpPostprocess(src []*uint8, srcStride []int32,
|
||||
dst []*uint8, dstStride []int32,
|
||||
horizontalSize, verticalSize int32,
|
||||
QPStore *int8, QPStride int32,
|
||||
ppMode *PpMode, ppContext *PpContext, pictType int32) {
|
||||
if len(src) != 3 {
|
||||
panic("src need len = 3")
|
||||
}
|
||||
if len(dst) != 3 {
|
||||
panic("dst need len = 3")
|
||||
}
|
||||
C.pp_postprocess((**C.uint8_t)(unsafe.Pointer(&src[0])), (*C.int)(&srcStride[0]),
|
||||
(**C.uint8_t)(unsafe.Pointer(&dst[0])), (*C.int)(&dstStride[0]),
|
||||
(C.int)(horizontalSize), (C.int)(verticalSize),
|
||||
|
@@ -11,7 +11,7 @@ const (
|
||||
)
|
||||
|
||||
// Dithering algorithms
|
||||
type SwrDitherType int32
|
||||
type SwrDitherType = C.enum_SwrDitherType
|
||||
|
||||
const (
|
||||
SWR_DITHER_NONE = SwrDitherType(C.SWR_DITHER_NONE)
|
||||
@@ -30,7 +30,7 @@ const (
|
||||
)
|
||||
|
||||
// Resampling Engines
|
||||
type SwrEngine int32
|
||||
type SwrEngine = C.enum_SwrEngine
|
||||
|
||||
const (
|
||||
SWR_ENGINE_SWR = SwrEngine(C.SWR_ENGINE_SWR)
|
||||
@@ -39,7 +39,7 @@ const (
|
||||
)
|
||||
|
||||
// Resampling Filter Types
|
||||
type SwrFilterType int32
|
||||
type SwrFilterType = C.enum_SwrFilterType
|
||||
|
||||
const (
|
||||
SWR_FILTER_TYPE_CUBIC = SwrFilterType(C.SWR_FILTER_TYPE_CUBIC)
|
||||
|
26
swscale.go
26
swscale.go
@@ -109,12 +109,12 @@ func SwsInitContext(sctx *SwsContext, srcFilter, dstFilter *SwsFilter) int32 {
|
||||
}
|
||||
|
||||
// SwsFreecontext frees the swscaler context swsContext.
|
||||
func SwsFreecontext(sctx *SwsContext) {
|
||||
func SwsFreeContext(sctx *SwsContext) {
|
||||
C.sws_freeContext((*C.struct_SwsContext)(sctx))
|
||||
}
|
||||
|
||||
// SwsGetcontext allocates and returns an SwsContext.
|
||||
func SwsGetcontext(srcW, srcH int32, srcFormat AvPixelFormat,
|
||||
func SwsGetContext(srcW, srcH int32, srcFormat AvPixelFormat,
|
||||
dstW, dstH int32, dstFormat AvPixelFormat,
|
||||
flags int32, srcFilter, dstFilter *SwsFilter, param *float64) *SwsContext {
|
||||
return (*SwsContext)(C.sws_getContext((C.int)(srcW), (C.int)(srcH), (C.enum_AVPixelFormat)(srcFormat),
|
||||
@@ -135,17 +135,29 @@ func SwsScale(sctx *SwsContext, srcSlice []*uint8, srcStride []int32,
|
||||
}
|
||||
|
||||
// SwsSetColorspaceDetails
|
||||
func SwsSetColorspaceDetails(sctx *SwsContext, invTable [4]int32, srcRange int32,
|
||||
table [4]int32, dstRange int32, brightness, contrast, saturation int32) int32 {
|
||||
func SwsSetColorSpaceDetails(sctx *SwsContext, invTable []int32, srcRange int32,
|
||||
table []int32, dstRange int32, brightness, contrast, saturation int32) int32 {
|
||||
if len(invTable) != 4 {
|
||||
panic("invTable need len = 4")
|
||||
}
|
||||
if len(table) != 4 {
|
||||
panic("table need len = 4")
|
||||
}
|
||||
return (int32)(C.sws_setColorspaceDetails((*C.struct_SwsContext)(sctx),
|
||||
(*C.int)(unsafe.Pointer(&invTable[0])), (C.int)(srcRange),
|
||||
(*C.int)(unsafe.Pointer(&table[0])), (C.int)(dstRange),
|
||||
(C.int)(brightness), (C.int)(contrast), (C.int)(saturation)))
|
||||
}
|
||||
|
||||
// SwsGetColorspaceDetails
|
||||
func SwsGetColorspaceDetails(sctx *SwsContext, invTable [4]int32, srcRange *int32,
|
||||
table [4]int32, dstRange *int32, brightness, contrast, saturation *int32) int32 {
|
||||
// SwsGetColorSpaceDetails
|
||||
func SwsGetColorSpaceDetails(sctx *SwsContext, invTable []int32, srcRange *int32,
|
||||
table []int32, dstRange *int32, brightness, contrast, saturation *int32) int32 {
|
||||
if len(invTable) != 4 {
|
||||
panic("invTable need len = 4")
|
||||
}
|
||||
if len(table) != 4 {
|
||||
panic("table need len = 4")
|
||||
}
|
||||
invTablePtr := unsafe.Pointer(&invTable[0])
|
||||
tablePtr := unsafe.Pointer(&table[0])
|
||||
return (int32)(C.sws_getColorspaceDetails((*C.struct_SwsContext)(sctx),
|
||||
|
Reference in New Issue
Block a user