mirror of
https://github.com/giorgisio/goav.git
synced 2024-04-21 12:31:56 +00:00
Working tutorial; More hooks to libav API; removes debbuging print
Missing constants, additional functions, remove errors
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
.idea/
|
||||
.vscode/
|
||||
@@ -1 +0,0 @@
|
||||
theme: jekyll-theme-slate
|
||||
@@ -33,6 +33,7 @@ type (
|
||||
BitStreamFilterContext C.struct_AVBitStreamFilterContext
|
||||
Rational C.struct_AVRational
|
||||
Class C.struct_AVClass
|
||||
AvCodecParameters C.struct_AVCodecParameters
|
||||
AvHWAccel C.struct_AVHWAccel
|
||||
AvPacketSideData C.struct_AVPacketSideData
|
||||
AvPanScan C.struct_AVPanScan
|
||||
@@ -56,6 +57,30 @@ type (
|
||||
AvSampleFormat C.enum_AVSampleFormat
|
||||
)
|
||||
|
||||
func (cp *AvCodecParameters) AvCodecGetId() CodecId {
|
||||
return *((*CodecId)(unsafe.Pointer(&cp.codec_id)))
|
||||
}
|
||||
|
||||
func (cp *AvCodecParameters) AvCodecGetType() MediaType {
|
||||
return *((*MediaType)(unsafe.Pointer(&cp.codec_type)))
|
||||
}
|
||||
|
||||
func (cp *AvCodecParameters) AvCodecGetWidth() int {
|
||||
return *((*int)(unsafe.Pointer(&cp.width)))
|
||||
}
|
||||
|
||||
func (cp *AvCodecParameters) AvCodecGetHeight() int {
|
||||
return *((*int)(unsafe.Pointer(&cp.height)))
|
||||
}
|
||||
|
||||
func (cp *AvCodecParameters) AvCodecGetChannels() int {
|
||||
return *((*int)(unsafe.Pointer(&cp.channels)))
|
||||
}
|
||||
|
||||
func (cp *AvCodecParameters) AvCodecGetSampleRate() int {
|
||||
return *((*int)(unsafe.Pointer(&cp.sample_rate)))
|
||||
}
|
||||
|
||||
func (c *Codec) AvCodecGetMaxLowres() int {
|
||||
return int(C.av_codec_get_max_lowres((*C.struct_AVCodec)(c)))
|
||||
}
|
||||
@@ -136,6 +161,10 @@ func AvsubtitleFree(s *AvSubtitle) {
|
||||
C.avsubtitle_free((*C.struct_AVSubtitle)(s))
|
||||
}
|
||||
|
||||
func AvPacketAlloc() *Packet {
|
||||
return (*Packet)(C.av_packet_alloc())
|
||||
}
|
||||
|
||||
//Pack a dictionary for use in side_data.
|
||||
func AvPacketPackDictionary(d *Dictionary, s *int) *uint8 {
|
||||
return (*uint8)(C.av_packet_pack_dictionary((*C.struct_AVDictionary)(d), (*C.int)(unsafe.Pointer(s))))
|
||||
@@ -151,6 +180,10 @@ func AvcodecFindDecoder(id CodecId) *Codec {
|
||||
return (*Codec)(C.avcodec_find_decoder((C.enum_AVCodecID)(id)))
|
||||
}
|
||||
|
||||
func AvCodecIterate(p *unsafe.Pointer) *Codec {
|
||||
return (*Codec)(C.av_codec_iterate(p))
|
||||
}
|
||||
|
||||
//Find a registered decoder with the specified name.
|
||||
func AvcodecFindDecoderByName(n string) *Codec {
|
||||
return (*Codec)(C.avcodec_find_decoder_by_name(C.CString(n)))
|
||||
|
||||
+13
-12
@@ -8,22 +8,15 @@ package avcodec
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/selfmodify/goav/common"
|
||||
)
|
||||
|
||||
func (ctxt *Context) AvCodecGetPktTimebase() Rational {
|
||||
return (Rational)(C.av_codec_get_pkt_timebase((*C.struct_AVCodecContext)(ctxt)))
|
||||
return Rational(C.av_codec_get_pkt_timebase((*C.struct_AVCodecContext)(ctxt)))
|
||||
}
|
||||
|
||||
// AvCodecGetPktTimebase2 returns the timebase rational number as numerator and denominator
|
||||
func (ctxt *Context) AvCodecGetPktTimebase2() (timebase common.AVRational) {
|
||||
r := ctxt.AvCodecGetPktTimebase()
|
||||
timebase = common.AVRational{
|
||||
Num: int(r.num),
|
||||
Den: int(r.den),
|
||||
}
|
||||
return
|
||||
func (ctxt *Context) AvCodecGetPktTimebase2() Rational {
|
||||
return ctxt.AvCodecGetPktTimebase()
|
||||
}
|
||||
|
||||
func (ctxt *Context) AvCodecSetPktTimebase(r Rational) {
|
||||
@@ -179,7 +172,7 @@ func (ctxt *Context) SetTimebase(num1 int, den1 int) {
|
||||
ctxt.time_base.den = C.int(den1)
|
||||
}
|
||||
|
||||
func (ctxt *Context) SetEncodeParams2(width int, height int, pxlFmt common.PixelFormat, hasBframes bool, gopSize int) {
|
||||
func (ctxt *Context) SetEncodeParams2(width int, height int, pxlFmt PixelFormat, hasBframes bool, gopSize int) {
|
||||
ctxt.width = C.int(width)
|
||||
ctxt.height = C.int(height)
|
||||
// ctxt.bit_rate = 1000000
|
||||
@@ -197,6 +190,14 @@ func (ctxt *Context) SetEncodeParams2(width int, height int, pxlFmt common.Pixel
|
||||
// C.av_opt_set(ctxt.priv_data, "preset", "ultrafast", 0)
|
||||
}
|
||||
|
||||
func (ctxt *Context) SetEncodeParams(width int, height int, pxlFmt common.PixelFormat) {
|
||||
func (ctxt *Context) SetEncodeParams(width int, height int, pxlFmt PixelFormat) {
|
||||
ctxt.SetEncodeParams2(width, height, pxlFmt, false /*no b frames*/, 10)
|
||||
}
|
||||
|
||||
func (ctxt *Context) AvcodecSendPacket(packet *Packet) int {
|
||||
return (int)(C.avcodec_send_packet((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVPacket)(packet)))
|
||||
}
|
||||
|
||||
func (ctxt *Context) AvcodecReceiveFrame(frame *Frame) int {
|
||||
return (int)(C.avcodec_receive_frame((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVFrame)(frame)))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
// Giorgis (habtom@giorgis.io)
|
||||
|
||||
package avcodec
|
||||
|
||||
//#cgo pkg-config: libavcodec
|
||||
//#include <libavcodec/avcodec.h>
|
||||
import "C"
|
||||
|
||||
const (
|
||||
AV_CODEC_FLAG_UNALIGNED = int(C.AV_CODEC_FLAG_UNALIGNED)
|
||||
AV_CODEC_FLAG_QSCALE = int(C.AV_CODEC_FLAG_QSCALE)
|
||||
AV_CODEC_FLAG_4MV = int(C.AV_CODEC_FLAG_4MV)
|
||||
AV_CODEC_FLAG_OUTPUT_CORRUPT = int(C.AV_CODEC_FLAG_OUTPUT_CORRUPT)
|
||||
AV_CODEC_FLAG_QPEL = int(C.AV_CODEC_FLAG_QPEL)
|
||||
AV_CODEC_FLAG_PASS1 = int(C.AV_CODEC_FLAG_PASS1)
|
||||
AV_CODEC_FLAG_PASS2 = int(C.AV_CODEC_FLAG_PASS2)
|
||||
AV_CODEC_FLAG_LOOP_FILTER = int(C.AV_CODEC_FLAG_LOOP_FILTER)
|
||||
AV_CODEC_FLAG_GRAY = int(C.AV_CODEC_FLAG_GRAY)
|
||||
AV_CODEC_FLAG_PSNR = int(C.AV_CODEC_FLAG_PSNR)
|
||||
AV_CODEC_FLAG_TRUNCATED = int(C.AV_CODEC_FLAG_TRUNCATED)
|
||||
AV_CODEC_FLAG_INTERLACED_DCT = int(C.AV_CODEC_FLAG_INTERLACED_DCT)
|
||||
AV_CODEC_FLAG_LOW_DELAY = int(C.AV_CODEC_FLAG_LOW_DELAY)
|
||||
AV_CODEC_FLAG_GLOBAL_HEADER = int(C.AV_CODEC_FLAG_GLOBAL_HEADER)
|
||||
AV_CODEC_FLAG_BITEXACT = int(C.AV_CODEC_FLAG_BITEXACT)
|
||||
AV_CODEC_FLAG_AC_PRED = int(C.AV_CODEC_FLAG_AC_PRED)
|
||||
AV_CODEC_FLAG_INTERLACED_ME = int(C.AV_CODEC_FLAG_INTERLACED_ME)
|
||||
AV_CODEC_FLAG_CLOSED_GOP = int(C.AV_CODEC_FLAG_CLOSED_GOP)
|
||||
AV_CODEC_FLAG2_FAST = int(C.AV_CODEC_FLAG2_FAST)
|
||||
AV_CODEC_FLAG2_NO_OUTPUT = int(C.AV_CODEC_FLAG2_NO_OUTPUT)
|
||||
AV_CODEC_FLAG2_LOCAL_HEADER = int(C.AV_CODEC_FLAG2_LOCAL_HEADER)
|
||||
AV_CODEC_FLAG2_DROP_FRAME_TIMECODE = int(C.AV_CODEC_FLAG2_DROP_FRAME_TIMECODE)
|
||||
AV_CODEC_FLAG2_CHUNKS = int(C.AV_CODEC_FLAG2_CHUNKS)
|
||||
AV_CODEC_FLAG2_IGNORE_CROP = int(C.AV_CODEC_FLAG2_IGNORE_CROP)
|
||||
AV_CODEC_FLAG2_SHOW_ALL = int(C.AV_CODEC_FLAG2_SHOW_ALL)
|
||||
AV_CODEC_FLAG2_EXPORT_MVS = int(C.AV_CODEC_FLAG2_EXPORT_MVS)
|
||||
AV_CODEC_FLAG2_SKIP_MANUAL = int(C.AV_CODEC_FLAG2_SKIP_MANUAL)
|
||||
AV_CODEC_FLAG2_RO_FLUSH_NOOP = int(C.AV_CODEC_FLAG2_RO_FLUSH_NOOP)
|
||||
)
|
||||
@@ -10,9 +10,17 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
AV_PKT_FLAG_KEY = int(C.AV_PKT_FLAG_KEY)
|
||||
AV_PKT_FLAG_CORRUPT = int(C.AV_PKT_FLAG_CORRUPT)
|
||||
AV_PKT_FLAG_DISCARD = int(C.AV_PKT_FLAG_DISCARD)
|
||||
)
|
||||
|
||||
//Initialize optional fields of a packet with default values.
|
||||
func (p *Packet) AvInitPacket() {
|
||||
C.av_init_packet((*C.struct_AVPacket)(p))
|
||||
p.size = 0
|
||||
p.data = nil
|
||||
}
|
||||
|
||||
//Allocate the payload of a packet and initialize its fields with default values.
|
||||
|
||||
@@ -16,6 +16,9 @@ func (p *Packet) Duration() int {
|
||||
func (p *Packet) Flags() int {
|
||||
return int(p.flags)
|
||||
}
|
||||
func (p *Packet) SetFlags(flags int) {
|
||||
p.flags = C.int(flags)
|
||||
}
|
||||
func (p *Packet) SideDataElems() int {
|
||||
return int(p.side_data_elems)
|
||||
}
|
||||
@@ -25,18 +28,27 @@ func (p *Packet) Size() int {
|
||||
func (p *Packet) StreamIndex() int {
|
||||
return int(p.stream_index)
|
||||
}
|
||||
func (p *Packet) SetStreamIndex(idx int) {
|
||||
p.stream_index = C.int(idx)
|
||||
}
|
||||
func (p *Packet) ConvergenceDuration() int64 {
|
||||
return int64(p.convergence_duration)
|
||||
}
|
||||
func (p *Packet) Dts() int64 {
|
||||
return int64(p.dts)
|
||||
}
|
||||
func (p *Packet) SetDts(dts int64) {
|
||||
p.dts = C.int64_t(dts)
|
||||
}
|
||||
func (p *Packet) Pos() int64 {
|
||||
return int64(p.pos)
|
||||
}
|
||||
func (p *Packet) Pts() int64 {
|
||||
return int64(p.pts)
|
||||
}
|
||||
func (p *Packet) SetPts(pts int64) {
|
||||
p.dts = C.int64_t(pts)
|
||||
}
|
||||
func (p *Packet) Data() *uint8 {
|
||||
return (*uint8)(p.data)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
// Giorgis (habtom@giorgis.io)
|
||||
|
||||
//Package avcodec contains the codecs (decoders and encoders) provided by the libavcodec library
|
||||
//Provides some generic global options, which can be set on all the encoders and decoders.
|
||||
package avcodec
|
||||
|
||||
//#cgo pkg-config: libavformat libavcodec libavutil
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <inttypes.h>
|
||||
//#include <stdint.h>
|
||||
//#include <string.h>
|
||||
//#include <libavformat/avformat.h>
|
||||
//#include <libavcodec/avcodec.h>
|
||||
//#include <libavutil/avutil.h>
|
||||
//#include <libswscale/swscale.h>
|
||||
import "C"
|
||||
|
||||
const (
|
||||
AV_PIX_FMT_YUV = 0
|
||||
AV_PIX_FMT_YUV420P9 = C.AV_PIX_FMT_YUV420P9
|
||||
AV_PIX_FMT_YUV422P9 = C.AV_PIX_FMT_YUV422P9
|
||||
AV_PIX_FMT_YUV444P9 = C.AV_PIX_FMT_YUV444P9
|
||||
AV_PIX_FMT_YUV420P10 = C.AV_PIX_FMT_YUV420P10
|
||||
AV_PIX_FMT_YUV422P10 = C.AV_PIX_FMT_YUV422P10
|
||||
AV_PIX_FMT_YUV440P10 = C.AV_PIX_FMT_YUV440P10
|
||||
AV_PIX_FMT_YUV444P10 = C.AV_PIX_FMT_YUV444P10
|
||||
AV_PIX_FMT_YUV420P12 = C.AV_PIX_FMT_YUV420P12
|
||||
AV_PIX_FMT_YUV422P12 = C.AV_PIX_FMT_YUV422P12
|
||||
AV_PIX_FMT_YUV440P12 = C.AV_PIX_FMT_YUV440P12
|
||||
AV_PIX_FMT_YUV444P12 = C.AV_PIX_FMT_YUV444P12
|
||||
AV_PIX_FMT_YUV420P14 = C.AV_PIX_FMT_YUV420P14
|
||||
AV_PIX_FMT_YUV422P14 = C.AV_PIX_FMT_YUV422P14
|
||||
AV_PIX_FMT_YUV444P14 = C.AV_PIX_FMT_YUV444P14
|
||||
AV_PIX_FMT_YUV420P16 = C.AV_PIX_FMT_YUV420P16
|
||||
AV_PIX_FMT_YUV422P16 = C.AV_PIX_FMT_YUV422P16
|
||||
AV_PIX_FMT_YUV444P16 = C.AV_PIX_FMT_YUV444P16
|
||||
AV_PIX_FMT_YUVA420P9 = C.AV_PIX_FMT_YUVA420P9
|
||||
AV_PIX_FMT_YUVA422P9 = C.AV_PIX_FMT_YUVA422P9
|
||||
AV_PIX_FMT_YUVA444P9 = C.AV_PIX_FMT_YUVA444P9
|
||||
AV_PIX_FMT_YUVA420P10 = C.AV_PIX_FMT_YUVA420P10
|
||||
AV_PIX_FMT_YUVA422P10 = C.AV_PIX_FMT_YUVA422P10
|
||||
AV_PIX_FMT_YUVA444P10 = C.AV_PIX_FMT_YUVA444P10
|
||||
AV_PIX_FMT_YUVA420P16 = C.AV_PIX_FMT_YUVA420P16
|
||||
AV_PIX_FMT_YUVA422P16 = C.AV_PIX_FMT_YUVA422P16
|
||||
AV_PIX_FMT_YUVA444P16 = C.AV_PIX_FMT_YUVA444P16
|
||||
AV_PIX_FMT_RGB24 = C.AV_PIX_FMT_RGB24
|
||||
AV_PIX_FMT_RGBA = C.AV_PIX_FMT_RGBA
|
||||
|
||||
SWS_FAST_BILINEAR = C.SWS_FAST_BILINEAR
|
||||
SWS_BILINEAR = C.SWS_BILINEAR
|
||||
SWS_BICUBIC = C.SWS_BICUBIC
|
||||
SWS_X = C.SWS_X
|
||||
SWS_POINT = C.SWS_POINT
|
||||
SWS_AREA = C.SWS_AREA
|
||||
SWS_BICUBLIN = C.SWS_BICUBLIN
|
||||
SWS_GAUSS = C.SWS_GAUSS
|
||||
SWS_SINC = C.SWS_SINC
|
||||
SWS_LANCZOS = C.SWS_LANCZOS
|
||||
SWS_SPLINE = C.SWS_SPLINE
|
||||
SWS_SRC_V_CHR_DROP_MASK = C.SWS_SRC_V_CHR_DROP_MASK
|
||||
SWS_SRC_V_CHR_DROP_SHIFT = C.SWS_SRC_V_CHR_DROP_SHIFT
|
||||
SWS_PARAM_DEFAULT = C.SWS_PARAM_DEFAULT
|
||||
SWS_PRINT_INFO = C.SWS_PRINT_INFO
|
||||
SWS_FULL_CHR_H_INT = C.SWS_FULL_CHR_H_INT
|
||||
SWS_FULL_CHR_H_INP = C.SWS_FULL_CHR_H_INP
|
||||
SWS_DIRECT_BGR = C.SWS_DIRECT_BGR
|
||||
SWS_ACCURATE_RND = C.SWS_ACCURATE_RND
|
||||
SWS_BITEXACT = C.SWS_BITEXACT
|
||||
SWS_ERROR_DIFFUSION = C.SWS_ERROR_DIFFUSION
|
||||
SWS_MAX_REDUCE_CUTOFF = C.SWS_MAX_REDUCE_CUTOFF
|
||||
SWS_CS_ITU709 = C.SWS_CS_ITU709
|
||||
SWS_CS_FCC = C.SWS_CS_FCC
|
||||
SWS_CS_ITU601 = C.SWS_CS_ITU601
|
||||
SWS_CS_ITU624 = C.SWS_CS_ITU624
|
||||
SWS_CS_SMPTE170M = C.SWS_CS_SMPTE170M
|
||||
SWS_CS_SMPTE240M = C.SWS_CS_SMPTE240M
|
||||
SWS_CS_DEFAULT = C.SWS_CS_DEFAULT
|
||||
SWS_CS_BT2020 = C.SWS_CS_BT2020
|
||||
)
|
||||
|
||||
func (pf PixelFormat) String() string {
|
||||
switch int(pf) {
|
||||
case AV_PIX_FMT_YUV420P9:
|
||||
return "YUV420P9"
|
||||
|
||||
case AV_PIX_FMT_YUV422P9:
|
||||
return "YUV422P9"
|
||||
|
||||
case AV_PIX_FMT_YUV444P9:
|
||||
return "YUV444P9"
|
||||
|
||||
case AV_PIX_FMT_YUV420P10:
|
||||
return "YUV420P10"
|
||||
|
||||
case AV_PIX_FMT_YUV422P10:
|
||||
return "YUV422P10"
|
||||
|
||||
case AV_PIX_FMT_YUV440P10:
|
||||
return "YUV440P10"
|
||||
|
||||
case AV_PIX_FMT_YUV444P10:
|
||||
return "YUV444P10"
|
||||
|
||||
case AV_PIX_FMT_YUV420P12:
|
||||
return "YUV420P12"
|
||||
|
||||
case AV_PIX_FMT_YUV422P12:
|
||||
return "YUV422P12"
|
||||
|
||||
case AV_PIX_FMT_YUV440P12:
|
||||
return "YUV440P12"
|
||||
|
||||
case AV_PIX_FMT_YUV444P12:
|
||||
return "YUV444P12"
|
||||
|
||||
case AV_PIX_FMT_YUV420P14:
|
||||
return "YUV420P14"
|
||||
|
||||
case AV_PIX_FMT_YUV422P14:
|
||||
return "YUV422P14"
|
||||
|
||||
case AV_PIX_FMT_YUV444P14:
|
||||
return "YUV444P14"
|
||||
|
||||
case AV_PIX_FMT_YUV420P16:
|
||||
return "YUV420P16"
|
||||
|
||||
case AV_PIX_FMT_YUV422P16:
|
||||
return "YUV422P16"
|
||||
|
||||
case AV_PIX_FMT_YUV444P16:
|
||||
return "YUV444P16"
|
||||
|
||||
case AV_PIX_FMT_YUVA420P9:
|
||||
return "YUVA420P9"
|
||||
|
||||
case AV_PIX_FMT_YUVA422P9:
|
||||
return "YUVA422P9"
|
||||
|
||||
case AV_PIX_FMT_YUVA444P9:
|
||||
return "YUVA444P9"
|
||||
|
||||
case AV_PIX_FMT_YUVA420P10:
|
||||
return "YUVA420P10"
|
||||
|
||||
case AV_PIX_FMT_YUVA422P10:
|
||||
return "YUVA422P10"
|
||||
|
||||
case AV_PIX_FMT_YUVA444P10:
|
||||
return "YUVA444P10"
|
||||
|
||||
case AV_PIX_FMT_YUVA420P16:
|
||||
return "YUVA420P16"
|
||||
|
||||
case AV_PIX_FMT_YUVA422P16:
|
||||
return "YUVA422P16"
|
||||
|
||||
case AV_PIX_FMT_YUVA444P16:
|
||||
return "YUVA444P16"
|
||||
|
||||
case AV_PIX_FMT_RGB24:
|
||||
return "RGB24"
|
||||
|
||||
case AV_PIX_FMT_RGBA:
|
||||
return "RGBA"
|
||||
}
|
||||
|
||||
return "{UNKNOWN}"
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
// Giorgis (habtom@giorgis.io)
|
||||
|
||||
//Package avcodec contains the codecs (decoders and encoders) provided by the libavcodec library
|
||||
//Provides some generic global options, which can be set on all the encoders and decoders.
|
||||
package avcodec
|
||||
|
||||
//#cgo pkg-config: libavformat libavcodec libavutil
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <inttypes.h>
|
||||
//#include <stdint.h>
|
||||
//#include <string.h>
|
||||
//#include <libavformat/avformat.h>
|
||||
//#include <libavcodec/avcodec.h>
|
||||
//#include <libavutil/avutil.h>
|
||||
import "C"
|
||||
import "fmt"
|
||||
|
||||
func (r Rational) Num() int {
|
||||
return int(r.num)
|
||||
}
|
||||
|
||||
func (r Rational) Den() int {
|
||||
return int(r.den)
|
||||
}
|
||||
|
||||
func (r Rational) String() string {
|
||||
return fmt.Sprintln("%d/%d", int(r.num), int(r.den))
|
||||
}
|
||||
|
||||
func (r *Rational) Assign(o Rational) {
|
||||
r.Set(o.Num(), o.Den())
|
||||
}
|
||||
|
||||
func (r *Rational) Set(num, den int) {
|
||||
r.num, r.den = C.int(num), C.int(den)
|
||||
}
|
||||
|
||||
func NewRational(num, den int) Rational {
|
||||
return Rational{
|
||||
num: C.int(num),
|
||||
den: C.int(den),
|
||||
}
|
||||
}
|
||||
+24
-10
@@ -20,6 +20,9 @@ package avformat
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/giorgisio/goav/avcodec"
|
||||
"github.com/giorgisio/goav/avutil"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -35,10 +38,8 @@ type (
|
||||
AvProgram C.struct_AVProgram
|
||||
AvChapter C.struct_AVChapter
|
||||
AvPacketList C.struct_AVPacketList
|
||||
Packet C.struct_AVPacket
|
||||
CodecParserContext C.struct_AVCodecParserContext
|
||||
AvIOContext C.struct_AVIOContext
|
||||
Rational C.struct_AVRational
|
||||
AvCodec C.struct_AVCodec
|
||||
AvCodecTag C.struct_AVCodecTag
|
||||
Class C.struct_AVClass
|
||||
@@ -57,13 +58,17 @@ type (
|
||||
type File C.FILE
|
||||
|
||||
//Allocate and read the payload of a packet and initialize its fields with default values.
|
||||
func (ctxt *AvIOContext) AvGetPacket(pkt *Packet, s int) int {
|
||||
return int(C.av_get_packet((*C.struct_AVIOContext)(ctxt), (*C.struct_AVPacket)(pkt), C.int(s)))
|
||||
func (ctxt *AvIOContext) AvGetPacket(pkt *avcodec.Packet, s int) int {
|
||||
return int(C.av_get_packet((*C.struct_AVIOContext)(ctxt), toCPacket(pkt), C.int(s)))
|
||||
}
|
||||
|
||||
//Read data and append it to the current content of the Packet.
|
||||
func (ctxt *AvIOContext) AvAppendPacket(pkt *Packet, s int) int {
|
||||
return int(C.av_append_packet((*C.struct_AVIOContext)(ctxt), (*C.struct_AVPacket)(pkt), C.int(s)))
|
||||
func (ctxt *AvIOContext) AvAppendPacket(pkt *avcodec.Packet, s int) int {
|
||||
return int(C.av_append_packet((*C.struct_AVIOContext)(ctxt), toCPacket(pkt), C.int(s)))
|
||||
}
|
||||
|
||||
func (ctxt *AvIOContext) Close() error {
|
||||
return avutil.ErrorFromCode(int(C.avio_close((*C.AVIOContext)(unsafe.Pointer(ctxt)))))
|
||||
}
|
||||
|
||||
func (f *InputFormat) AvRegisterInputFormat() {
|
||||
@@ -190,13 +195,13 @@ func AvHexDumpLog(a, l int, b *uint8, s int) {
|
||||
}
|
||||
|
||||
//Send a nice dump of a packet to the specified file stream.
|
||||
func AvPktDump2(f *File, pkt *Packet, dp int, st *Stream) {
|
||||
C.av_pkt_dump2((*C.FILE)(f), (*C.struct_AVPacket)(pkt), C.int(dp), (*C.struct_AVStream)(st))
|
||||
func AvPktDump2(f *File, pkt *avcodec.Packet, dp int, st *Stream) {
|
||||
C.av_pkt_dump2((*C.FILE)(f), toCPacket(pkt), C.int(dp), (*C.struct_AVStream)(st))
|
||||
}
|
||||
|
||||
//Send a nice dump of a packet to the log.
|
||||
func AvPktDumpLog2(a int, l int, pkt *Packet, dp int, st *Stream) {
|
||||
C.av_pkt_dump_log2(unsafe.Pointer(&a), C.int(l), (*C.struct_AVPacket)(pkt), C.int(dp), (*C.struct_AVStream)(st))
|
||||
func AvPktDumpLog2(a int, l int, pkt *avcodec.Packet, dp int, st *Stream) {
|
||||
C.av_pkt_dump_log2(unsafe.Pointer(&a), C.int(l), toCPacket(pkt), C.int(dp), (*C.struct_AVStream)(st))
|
||||
}
|
||||
|
||||
//enum CodecId av_codec_get_id (const struct AvCodecTag *const *tags, unsigned int tag)
|
||||
@@ -273,3 +278,12 @@ func AvformatGetMovVideoTags() *AvCodecTag {
|
||||
func AvformatGetMovAudioTags() *AvCodecTag {
|
||||
return (*AvCodecTag)(C.avformat_get_mov_audio_tags())
|
||||
}
|
||||
|
||||
func AvIOOpen(url string, flags int) (res *AvIOContext, err error) {
|
||||
urlStr := C.CString(url)
|
||||
defer C.free(unsafe.Pointer(urlStr))
|
||||
|
||||
err = avutil.ErrorFromCode(int(C.avio_open((**C.AVIOContext)(unsafe.Pointer(&res)), urlStr, C.int(flags))))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
// Giorgis (habtom@giorgis.io)
|
||||
|
||||
//Package avformat provides some generic global options, which can be set on all the muxers and demuxers.
|
||||
//In addition each muxer or demuxer may support so-called private options, which are specific for that component.
|
||||
//Supported formats (muxers and demuxers) provided by the libavformat library
|
||||
package avformat
|
||||
|
||||
//#cgo pkg-config: libavformat libavcodec libavutil libavdevice libavfilter libswresample libswscale
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <inttypes.h>
|
||||
//#include <stdint.h>
|
||||
//#include <string.h>
|
||||
//#include <libavformat/avformat.h>
|
||||
//#include <libavcodec/avcodec.h>
|
||||
import "C"
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/giorgisio/goav/avcodec"
|
||||
)
|
||||
|
||||
func (cctxt *CodecContext) Type() MediaType {
|
||||
return MediaType(cctxt.codec_type)
|
||||
}
|
||||
|
||||
func (cctxt *CodecContext) SetBitRate(br int64) {
|
||||
cctxt.bit_rate = C.int64_t(br)
|
||||
}
|
||||
|
||||
func (cctxt *CodecContext) GetCodecId() CodecId {
|
||||
return CodecId(cctxt.codec_id)
|
||||
}
|
||||
|
||||
func (cctxt *CodecContext) SetCodecId(codecId CodecId) {
|
||||
cctxt.codec_id = C.enum_AVCodecID(codecId)
|
||||
}
|
||||
|
||||
func (cctxt *CodecContext) GetCodecType() MediaType {
|
||||
return MediaType(cctxt.codec_type)
|
||||
}
|
||||
|
||||
func (cctxt *CodecContext) SetCodecType(ctype MediaType) {
|
||||
cctxt.codec_type = C.enum_AVMediaType(ctype)
|
||||
}
|
||||
|
||||
func (cctxt *CodecContext) GetTimeBase() avcodec.Rational {
|
||||
return newRational(cctxt.time_base)
|
||||
}
|
||||
|
||||
func (cctxt *CodecContext) SetTimeBase(timeBase avcodec.Rational) {
|
||||
cctxt.time_base.num = C.int(timeBase.Num())
|
||||
cctxt.time_base.den = C.int(timeBase.Den())
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) GetWidth() int {
|
||||
return int(cctx.width)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) SetWidth(w int) {
|
||||
cctx.width = C.int(w)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) GetHeight() int {
|
||||
return int(cctx.height)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) SetHeight(h int) {
|
||||
cctx.height = C.int(h)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) GetPixelFormat() avcodec.PixelFormat {
|
||||
return avcodec.PixelFormat(C.int(cctx.pix_fmt))
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) SetPixelFormat(fmt avcodec.PixelFormat) {
|
||||
cctx.pix_fmt = C.enum_AVPixelFormat(C.int(fmt))
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) GetFlags() int {
|
||||
return int(cctx.flags)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) SetFlags(flags int) {
|
||||
cctx.flags = C.int(flags)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) GetMeRange() int {
|
||||
return int(cctx.me_range)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) SetMeRange(r int) {
|
||||
cctx.me_range = C.int(r)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) GetMaxQDiff() int {
|
||||
return int(cctx.max_qdiff)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) SetMaxQDiff(v int) {
|
||||
cctx.max_qdiff = C.int(v)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) GetQMin() int {
|
||||
return int(cctx.qmin)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) SetQMin(v int) {
|
||||
cctx.qmin = C.int(v)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) GetQMax() int {
|
||||
return int(cctx.qmax)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) SetQMax(v int) {
|
||||
cctx.qmax = C.int(v)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) GetQCompress() float32 {
|
||||
return float32(cctx.qcompress)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) SetQCompress(v float32) {
|
||||
cctx.qcompress = C.float(v)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) GetExtraData() []byte {
|
||||
header := reflect.SliceHeader{
|
||||
Data: uintptr(unsafe.Pointer(cctx.extradata)),
|
||||
Len: int(cctx.extradata_size),
|
||||
Cap: int(cctx.extradata_size),
|
||||
}
|
||||
|
||||
return *((*[]byte)(unsafe.Pointer(&header)))
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) SetExtraData(data []byte) {
|
||||
header := (*reflect.SliceHeader)(unsafe.Pointer(&data))
|
||||
|
||||
cctx.extradata = (*C.uint8_t)(unsafe.Pointer(header.Data))
|
||||
cctx.extradata_size = C.int(header.Len)
|
||||
}
|
||||
|
||||
func (cctx *CodecContext) Release() {
|
||||
C.avcodec_close((*C.struct_AVCodecContext)(unsafe.Pointer(cctx)))
|
||||
C.av_freep(unsafe.Pointer(cctx))
|
||||
}
|
||||
+14
-15
@@ -10,8 +10,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/selfmodify/goav/avcodec"
|
||||
"github.com/selfmodify/goav/common"
|
||||
"github.com/giorgisio/goav/avcodec"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -106,7 +105,7 @@ func AvFindBestStream(ic *Context, t MediaType, ws, rs int, c **AvCodec, f int)
|
||||
|
||||
//Return the next frame of a stream.
|
||||
func (s *Context) AvReadFrame(pkt *avcodec.Packet) int {
|
||||
return int(C.av_read_frame((*C.struct_AVFormatContext)(unsafe.Pointer(s)), (*C.struct_AVPacket)(unsafe.Pointer(pkt))))
|
||||
return int(C.av_read_frame((*C.struct_AVFormatContext)(unsafe.Pointer(s)), toCPacket(pkt)))
|
||||
}
|
||||
|
||||
//Seek to the keyframe at timestamp.
|
||||
@@ -116,8 +115,8 @@ func (s *Context) AvSeekFrame(st int, t int64, f int) int {
|
||||
|
||||
// AvSeekFrameTime seeks to a specified time location.
|
||||
// |timebase| is codec specific and can be obtained by calling AvCodecGetPktTimebase2
|
||||
func (s *Context) AvSeekFrameTime(st int, at time.Duration, timebase common.AVRational) int {
|
||||
t2 := C.double(C.double(at.Seconds())*C.double(timebase.Den)) / (C.double(timebase.Num))
|
||||
func (s *Context) AvSeekFrameTime(st int, at time.Duration, timebase avcodec.Rational) int {
|
||||
t2 := C.double(C.double(at.Seconds())*C.double(timebase.Den())) / (C.double(timebase.Num()))
|
||||
// log.Printf("Seeking to time :%v TimebaseTime:%v ActualTimebase:%v", at, t2, timebase)
|
||||
return int(C.av_seek_frame((*C.struct_AVFormatContext)(s), C.int(st), C.int64_t(t2), AvseekFlagBackward))
|
||||
}
|
||||
@@ -139,7 +138,7 @@ func (s *Context) AvReadPause() int {
|
||||
|
||||
//Close an opened input Context.
|
||||
func (s *Context) AvformatCloseInput() {
|
||||
C.avformat_close_input((**C.struct_AVFormatContext)(unsafe.Pointer(s)))
|
||||
C.avformat_close_input((**C.struct_AVFormatContext)(unsafe.Pointer(&s)))
|
||||
}
|
||||
|
||||
//Allocate the stream private data and write the stream header to an output media file.
|
||||
@@ -148,13 +147,13 @@ func (s *Context) AvformatWriteHeader(o **Dictionary) int {
|
||||
}
|
||||
|
||||
//Write a packet to an output media file.
|
||||
func (s *Context) AvWriteFrame(pkt *Packet) int {
|
||||
return int(C.av_write_frame((*C.struct_AVFormatContext)(s), (*C.struct_AVPacket)(pkt)))
|
||||
func (s *Context) AvWriteFrame(pkt *avcodec.Packet) int {
|
||||
return int(C.av_write_frame((*C.struct_AVFormatContext)(s), toCPacket(pkt)))
|
||||
}
|
||||
|
||||
//Write a packet to an output media file ensuring correct interleaving.
|
||||
func (s *Context) AvInterleavedWriteFrame(pkt *Packet) int {
|
||||
return int(C.av_interleaved_write_frame((*C.struct_AVFormatContext)(s), (*C.struct_AVPacket)(pkt)))
|
||||
func (s *Context) AvInterleavedWriteFrame(pkt *avcodec.Packet) int {
|
||||
return int(C.av_interleaved_write_frame((*C.struct_AVFormatContext)(s), toCPacket(pkt)))
|
||||
}
|
||||
|
||||
//Write a uncoded frame to an output media file.
|
||||
@@ -192,13 +191,13 @@ func (s *Context) AvDumpFormat(i int, url string, io int) {
|
||||
}
|
||||
|
||||
//Guess the sample aspect ratio of a frame, based on both the stream and the frame aspect ratio.
|
||||
func (s *Context) AvGuessSampleAspectRatio(st *Stream, fr *Frame) Rational {
|
||||
return (Rational)(C.av_guess_sample_aspect_ratio((*C.struct_AVFormatContext)(s), (*C.struct_AVStream)(st), (*C.struct_AVFrame)(fr)))
|
||||
func (s *Context) AvGuessSampleAspectRatio(st *Stream, fr *Frame) avcodec.Rational {
|
||||
return newRational(C.av_guess_sample_aspect_ratio((*C.struct_AVFormatContext)(s), (*C.struct_AVStream)(st), (*C.struct_AVFrame)(fr)))
|
||||
}
|
||||
|
||||
//Guess the frame rate, based on both the container and codec information.
|
||||
func (s *Context) AvGuessFrameRate(st *Stream, fr *Frame) Rational {
|
||||
return (Rational)(C.av_guess_frame_rate((*C.struct_AVFormatContext)(s), (*C.struct_AVStream)(st), (*C.struct_AVFrame)(fr)))
|
||||
func (s *Context) AvGuessFrameRate(st *Stream, fr *Frame) avcodec.Rational {
|
||||
return newRational(C.av_guess_frame_rate((*C.struct_AVFormatContext)(s), (*C.struct_AVStream)(st), (*C.struct_AVFrame)(fr)))
|
||||
}
|
||||
|
||||
//Check if the stream st contained in s is matched by the stream specifier spec.
|
||||
@@ -212,7 +211,7 @@ func (s *Context) AvformatQueueAttachedPictures() int {
|
||||
|
||||
func (s *Context) AvformatNewStream2(c *AvCodec) *Stream {
|
||||
stream := (*Stream)(C.avformat_new_stream((*C.struct_AVFormatContext)(s), (*C.struct_AVCodec)(c)))
|
||||
stream.codec.pix_fmt = int32(common.AV_PIX_FMT_YUV)
|
||||
stream.codec.pix_fmt = int32(avcodec.AV_PIX_FMT_YUV)
|
||||
stream.codec.width = 640
|
||||
stream.codec.height = 480
|
||||
stream.time_base.num = 1
|
||||
|
||||
@@ -7,6 +7,7 @@ package avformat
|
||||
//#include <libavformat/avformat.h>
|
||||
import "C"
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -42,12 +43,24 @@ func (ctxt *Context) InterruptCallback() AvIOInterruptCB {
|
||||
return AvIOInterruptCB(ctxt.interrupt_callback)
|
||||
}
|
||||
|
||||
func (ctxt *Context) Programs() **AvProgram {
|
||||
return (**AvProgram)(unsafe.Pointer(ctxt.programs))
|
||||
func (ctxt *Context) Programs() []*AvProgram {
|
||||
header := reflect.SliceHeader{
|
||||
Data: uintptr(unsafe.Pointer(ctxt.programs)),
|
||||
Len: int(ctxt.NbPrograms()),
|
||||
Cap: int(ctxt.NbPrograms()),
|
||||
}
|
||||
|
||||
return *((*[]*AvProgram)(unsafe.Pointer(&header)))
|
||||
}
|
||||
|
||||
func (ctxt *Context) Streams() *Stream {
|
||||
return (*Stream)(unsafe.Pointer(*ctxt.streams))
|
||||
func (ctxt *Context) Streams() []*Stream {
|
||||
header := reflect.SliceHeader{
|
||||
Data: uintptr(unsafe.Pointer(ctxt.streams)),
|
||||
Len: int(ctxt.NbStreams()),
|
||||
Cap: int(ctxt.NbStreams()),
|
||||
}
|
||||
|
||||
return *((*[]*Stream)(unsafe.Pointer(&header)))
|
||||
}
|
||||
|
||||
func (ctxt *Context) Filename() string {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
// Giorgis (habtom@giorgis.io)
|
||||
|
||||
//Package avformat provides some generic global options, which can be set on all the muxers and demuxers.
|
||||
//In addition each muxer or demuxer may support so-called private options, which are specific for that component.
|
||||
//Supported formats (muxers and demuxers) provided by the libavformat library
|
||||
package avformat
|
||||
|
||||
//#cgo pkg-config: libavformat libavcodec libavutil libavdevice libavfilter libswresample libswscale
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <inttypes.h>
|
||||
//#include <stdint.h>
|
||||
//#include <string.h>
|
||||
//#include <libavformat/avformat.h>
|
||||
//#include <libavformat/avio.h>
|
||||
import "C"
|
||||
|
||||
const (
|
||||
AVIO_FLAG_READ = int(C.AVIO_FLAG_READ)
|
||||
AVIO_FLAG_WRITE = int(C.AVIO_FLAG_WRITE)
|
||||
AVIO_FLAG_READ_WRITE = int(C.AVIO_FLAG_READ_WRITE)
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
|
||||
package avformat
|
||||
|
||||
//#cgo pkg-config: libavutil
|
||||
//#include <libavutil/avutil.h>
|
||||
import "C"
|
||||
|
||||
const (
|
||||
AVMEDIA_TYPE_UNKNOWN = C.AVMEDIA_TYPE_UNKNOWN
|
||||
AVMEDIA_TYPE_VIDEO = C.AVMEDIA_TYPE_VIDEO
|
||||
AVMEDIA_TYPE_AUDIO = C.AVMEDIA_TYPE_AUDIO
|
||||
AVMEDIA_TYPE_DATA = C.AVMEDIA_TYPE_DATA
|
||||
AVMEDIA_TYPE_SUBTITLE = C.AVMEDIA_TYPE_SUBTITLE
|
||||
AVMEDIA_TYPE_ATTACHMENT = C.AVMEDIA_TYPE_ATTACHMENT
|
||||
AVMEDIA_TYPE_NB = C.AVMEDIA_TYPE_NB
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
// Giorgis (habtom@giorgis.io)
|
||||
|
||||
package avformat
|
||||
|
||||
//#cgo pkg-config: libavformat
|
||||
//#include <libavformat/avformat.h>
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/giorgisio/goav/avcodec"
|
||||
)
|
||||
|
||||
func toCPacket(pkt *avcodec.Packet) *C.struct_AVPacket {
|
||||
return (*C.struct_AVPacket)(unsafe.Pointer(pkt))
|
||||
}
|
||||
|
||||
func fromCPacket(pkt *C.struct_AVPacket) *avcodec.Packet {
|
||||
return (*avcodec.Packet)(unsafe.Pointer(pkt))
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
// Giorgis (habtom@giorgis.io)
|
||||
|
||||
package avformat
|
||||
|
||||
//#cgo pkg-config: libavutil
|
||||
//#include <libavutil/avutil.h>
|
||||
import "C"
|
||||
import "github.com/giorgisio/goav/avcodec"
|
||||
|
||||
func newRational(r C.struct_AVRational) avcodec.Rational {
|
||||
return avcodec.NewRational(int(r.num), int(r.den))
|
||||
}
|
||||
+12
-4
@@ -6,15 +6,23 @@ package avformat
|
||||
//#cgo pkg-config: libavformat
|
||||
//#include <libavformat/avformat.h>
|
||||
import "C"
|
||||
import (
|
||||
"github.com/giorgisio/goav/avcodec"
|
||||
)
|
||||
|
||||
//Rational av_stream_get_r_frame_rate (const Stream *s)
|
||||
func (s *Stream) AvStreamGetRFrameRate() Rational {
|
||||
return (Rational)(C.av_stream_get_r_frame_rate((*C.struct_AVStream)(s)))
|
||||
func (s *Stream) AvStreamGetRFrameRate() avcodec.Rational {
|
||||
return newRational(C.av_stream_get_r_frame_rate((*C.struct_AVStream)(s)))
|
||||
}
|
||||
|
||||
//void av_stream_set_r_frame_rate (Stream *s, Rational r)
|
||||
func (s *Stream) AvStreamSetRFrameRate(r Rational) {
|
||||
C.av_stream_set_r_frame_rate((*C.struct_AVStream)(s), (C.struct_AVRational)(r))
|
||||
func (s *Stream) AvStreamSetRFrameRate(r avcodec.Rational) {
|
||||
rat := C.struct_AVRational{
|
||||
num: C.int(r.Num()),
|
||||
den: C.int(r.Den()),
|
||||
}
|
||||
|
||||
C.av_stream_set_r_frame_rate((*C.struct_AVStream)(s), rat)
|
||||
}
|
||||
|
||||
//struct CodecParserContext * av_stream_get_parser (const Stream *s)
|
||||
|
||||
+20
-10
@@ -8,8 +8,14 @@ package avformat
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/giorgisio/goav/avcodec"
|
||||
)
|
||||
|
||||
func (avs *Stream) CodecParameters() *avcodec.AvCodecParameters {
|
||||
return (*avcodec.AvCodecParameters)(unsafe.Pointer(avs.codecpar))
|
||||
}
|
||||
|
||||
func (avs *Stream) Codec() *CodecContext {
|
||||
return (*CodecContext)(unsafe.Pointer(avs.codec))
|
||||
}
|
||||
@@ -22,8 +28,8 @@ func (avs *Stream) IndexEntries() *AvIndexEntry {
|
||||
return (*AvIndexEntry)(unsafe.Pointer(avs.index_entries))
|
||||
}
|
||||
|
||||
func (avs *Stream) AttachedPic() Packet {
|
||||
return Packet(avs.attached_pic)
|
||||
func (avs *Stream) AttachedPic() avcodec.Packet {
|
||||
return *fromCPacket(&avs.attached_pic)
|
||||
}
|
||||
|
||||
func (avs *Stream) SideData() *AvPacketSideData {
|
||||
@@ -34,24 +40,24 @@ func (avs *Stream) ProbeData() AvProbeData {
|
||||
return AvProbeData(avs.probe_data)
|
||||
}
|
||||
|
||||
func (avs *Stream) AvgFrameRate() Rational {
|
||||
return Rational(avs.avg_frame_rate)
|
||||
func (avs *Stream) AvgFrameRate() avcodec.Rational {
|
||||
return newRational(avs.avg_frame_rate)
|
||||
}
|
||||
|
||||
// func (avs *Stream) DisplayAspectRatio() *Rational {
|
||||
// return (*Rational)(unsafe.Pointer(avs.display_aspect_ratio))
|
||||
// }
|
||||
|
||||
func (avs *Stream) RFrameRate() Rational {
|
||||
return Rational(avs.r_frame_rate)
|
||||
func (avs *Stream) RFrameRate() avcodec.Rational {
|
||||
return newRational(avs.r_frame_rate)
|
||||
}
|
||||
|
||||
func (avs *Stream) SampleAspectRatio() Rational {
|
||||
return Rational(avs.sample_aspect_ratio)
|
||||
func (avs *Stream) SampleAspectRatio() avcodec.Rational {
|
||||
return newRational(avs.sample_aspect_ratio)
|
||||
}
|
||||
|
||||
func (avs *Stream) TimeBase() Rational {
|
||||
return Rational(avs.time_base)
|
||||
func (avs *Stream) TimeBase() avcodec.Rational {
|
||||
return newRational(avs.time_base)
|
||||
}
|
||||
|
||||
// func (avs *Stream) RecommendedEncoderConfiguration() string {
|
||||
@@ -225,3 +231,7 @@ func (avs *Stream) PtsReorderErrorCount() uint8 {
|
||||
func (avs *Stream) IndexEntriesAllocatedSize() uint {
|
||||
return uint(avs.index_entries_allocated_size)
|
||||
}
|
||||
|
||||
func (avs *Stream) Free() {
|
||||
C.av_freep(unsafe.Pointer(avs))
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ type (
|
||||
Rational C.struct_AVRational
|
||||
MediaType C.enum_AVMediaType
|
||||
AvPictureType C.enum_AVPictureType
|
||||
PixelFormat C.enum_AVPixelFormat
|
||||
File C.FILE
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
// Giorgis (habtom@giorgis.io)
|
||||
|
||||
// Package avutil is a utility library to aid portable multimedia programming.
|
||||
// It contains safe portable string functions, random number generators, data structures,
|
||||
// additional mathematics functions, cryptography and multimedia related functionality.
|
||||
// Some generic features and utilities provided by the libavutil library
|
||||
package avutil
|
||||
|
||||
//#cgo pkg-config: libavutil
|
||||
//#include <libavutil/error.h>
|
||||
//#include <stdlib.h>
|
||||
//static const char *error2string(int code) { return av_err2str(code); }
|
||||
import "C"
|
||||
import "errors"
|
||||
|
||||
const (
|
||||
AvErrorEOF = -('E' | ('O' << 8) | ('F' << 16) | (' ' << 24))
|
||||
AvErrorEAGAIN = -35
|
||||
)
|
||||
|
||||
func ErrorFromCode(code int) error {
|
||||
if code >= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.New(C.GoString(C.error2string(C.int(code))))
|
||||
}
|
||||
+4
-4
@@ -25,9 +25,9 @@ type (
|
||||
AvFrameSideDataType C.enum_AVFrameSideDataType
|
||||
)
|
||||
|
||||
// func AvprivFrameGetMetadatap(f *Frame) **Dictionary {
|
||||
// return (**Dictionary)(unsafe.Pointer(C.avpriv_frame_get_metadatap((*C.struct_AVFrame)(unsafe.Pointer(f)))))
|
||||
// }
|
||||
func AvprivFrameGetMetadatap(f *Frame) *Dictionary {
|
||||
return (*Dictionary)(unsafe.Pointer(f.metadata))
|
||||
}
|
||||
|
||||
func AvFrameSetQpTable(f *Frame, b *AvBufferRef, s, q int) int {
|
||||
return int(C.av_frame_set_qp_table((*C.struct_AVFrame)(unsafe.Pointer(f)), (*C.struct_AVBufferRef)(unsafe.Pointer(b)), C.int(s), C.int(q)))
|
||||
@@ -44,7 +44,7 @@ func AvFrameAlloc() *Frame {
|
||||
|
||||
//Free the frame and any dynamically allocated objects in it, e.g.
|
||||
func AvFrameFree(f *Frame) {
|
||||
C.av_frame_free((**C.struct_AVFrame)(unsafe.Pointer(f)))
|
||||
C.av_frame_free((**C.struct_AVFrame)(unsafe.Pointer(&f)))
|
||||
}
|
||||
|
||||
//Allocate new buffer(s) for audio or video data.
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
|
||||
package common
|
||||
|
||||
// Common types used across all av packages.
|
||||
|
||||
// AVRational exposes the numerator and denominator part of the undrelying 'Rational' structure.
|
||||
type AVRational struct {
|
||||
Num int
|
||||
Den int
|
||||
}
|
||||
|
||||
type PixelFormat int
|
||||
|
||||
const (
|
||||
AV_PIX_FMT_YUV PixelFormat = 0
|
||||
AV_PIX_FMT_RGB24 = 3
|
||||
AV_PIX_FMT_RGBA = 28
|
||||
)
|
||||
+182
-222
@@ -1,247 +1,207 @@
|
||||
//Example 01
|
||||
package main
|
||||
|
||||
// tutorial01.c
|
||||
// Code based on a tutorial at http://dranger.com/ffmpeg/tutorial01.html
|
||||
|
||||
// A small sample program that shows how to use libavformat and libavcodec to
|
||||
// read video from a file.
|
||||
//
|
||||
// Use
|
||||
//
|
||||
// gcc -o tutorial01 tutorial01.c -lavformat -lavcodec -lswscale -lz
|
||||
//
|
||||
// to build (assuming libavformat and libavcodec are correctly installed
|
||||
// your system).
|
||||
//
|
||||
// Run using
|
||||
//
|
||||
// tutorial01 myvideofile.mpg
|
||||
//
|
||||
// to write the first five frames from "myvideofile.mpg" to disk in PPM
|
||||
// format.
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/giorgisio/goav/avcodec"
|
||||
"github.com/giorgisio/goav/avformat"
|
||||
"github.com/giorgisio/goav/avutil"
|
||||
"github.com/giorgisio/goav/swscale"
|
||||
"log"
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
"github.com/giorgisio/goav/swscale"
|
||||
|
||||
"github.com/giorgisio/goav/avcodec"
|
||||
"github.com/giorgisio/goav/avformat"
|
||||
"github.com/giorgisio/goav/avutil"
|
||||
)
|
||||
|
||||
// SaveFrame writes a single frame to disk as a PPM file
|
||||
func SaveFrame(frame *avutil.Frame, width, height, frameNumber int) {
|
||||
// Open file
|
||||
fileName := fmt.Sprintf("frame%d.ppm", frameNumber)
|
||||
file, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
log.Println("Error Reading")
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Write header
|
||||
header := fmt.Sprintf("P6\n%d %d\n255\n", width, height)
|
||||
file.Write([]byte(header))
|
||||
|
||||
// Write pixel data
|
||||
for y := 0; y < height; y++ {
|
||||
data0 := avutil.Data(frame)[0]
|
||||
buf := make([]byte, width*3)
|
||||
startPos := uintptr(unsafe.Pointer(data0)) + uintptr(y)*uintptr(avutil.Linesize(frame)[0])
|
||||
for i := 0; i < width*3; i++ {
|
||||
element := *(*uint8)(unsafe.Pointer(startPos + uintptr(i)))
|
||||
buf[i] = element
|
||||
}
|
||||
file.Write(buf)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
filename := "sample.mp4"
|
||||
|
||||
var (
|
||||
ctxtFormat *avformat.Context
|
||||
ctxtSource *avcodec.Context
|
||||
ctxtDest *avcodec.Context
|
||||
videoCodec *avcodec.Codec
|
||||
videoFrame *avutil.Frame
|
||||
videoFrameRGB *avutil.Frame
|
||||
packet *avcodec.Packet
|
||||
ctxtSws *swscale.Context
|
||||
videoStream int
|
||||
frameFinished int
|
||||
numBytes int
|
||||
url string
|
||||
)
|
||||
//media_type *avutil.MediaType
|
||||
|
||||
// Register all formats and codecs
|
||||
avformat.AvRegisterAll()
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("Please provide a movie file")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Open video file
|
||||
if avformat.AvformatOpenInput(&ctxtFormat, filename, nil, nil) != 0 {
|
||||
log.Println("Error: Couldn't open file.")
|
||||
return
|
||||
pFormatContext := avformat.AvformatAllocContext()
|
||||
if avformat.AvformatOpenInput(&pFormatContext, os.Args[1], nil, nil) != 0 {
|
||||
fmt.Printf("Unable to open file %s\n", os.Args[1])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Retrieve stream information
|
||||
if ctxtFormat.AvformatFindStreamInfo(nil) < 0 {
|
||||
log.Println("Error: Couldn't find stream information.")
|
||||
return
|
||||
if pFormatContext.AvformatFindStreamInfo(nil) < 0 {
|
||||
fmt.Println("Couldn't find stream information")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Dump information about file onto standard error
|
||||
ctxtFormat.AvDumpFormat(0, url, 0)
|
||||
pFormatContext.AvDumpFormat(0, os.Args[1], 0)
|
||||
|
||||
// Find the first video stream
|
||||
videoStream = -1
|
||||
for i := 0; i < int(pFormatContext.NbStreams()); i++ {
|
||||
switch pFormatContext.Streams()[i].CodecParameters().AvCodecGetType() {
|
||||
case avformat.AVMEDIA_TYPE_VIDEO:
|
||||
|
||||
//ctxtFormat->nb_streams
|
||||
n := ctxtFormat.NbStreams()
|
||||
|
||||
//ctxtFormat->streams[]
|
||||
s := ctxtFormat.Streams()
|
||||
//s2 := avformat.StreamsOne(ctxtFormat, 1)
|
||||
|
||||
log.Print("Number of Streams:", n)
|
||||
|
||||
for i := 0; i < int(n); i++ {
|
||||
// ctxtFormat->streams[i]->codec->codec_type
|
||||
log.Println("Stream Number:", i)
|
||||
|
||||
//FIX: AvMEDIA_TYPE_VIDEO
|
||||
if (*avformat.CodecContext)(s.Codec()) != nil {
|
||||
videoStream = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if videoStream == -1 {
|
||||
log.Println("Couldn't find a video stream")
|
||||
return
|
||||
}
|
||||
|
||||
codec := s.Codec()
|
||||
|
||||
// Get a pointer to the codec context for the video stream
|
||||
//ctxtSource = ctxtFormat.streams[videoStream].codec
|
||||
ctxtSource = (*avcodec.Context)(unsafe.Pointer(&codec))
|
||||
log.Println("Bit Rate:", ctxtSource.BitRate())
|
||||
log.Println("Channels:", ctxtSource.Channels())
|
||||
log.Println("Coded_height:", ctxtSource.CodedHeight())
|
||||
log.Println("Coded_width:", ctxtSource.CodedWidth())
|
||||
log.Println("Coder_type:", ctxtSource.CoderType())
|
||||
log.Println("Height:", ctxtSource.Height())
|
||||
log.Println("Profile:", ctxtSource.Profile())
|
||||
log.Println("Width:", ctxtSource.Width())
|
||||
log.Println("Codec ID:", ctxtSource.CodecId())
|
||||
|
||||
//C.enum_AVCodecID
|
||||
codec_id := ctxtSource.CodecId()
|
||||
|
||||
// Find the decoder for the video stream
|
||||
videoCodec = avcodec.AvcodecFindDecoder(codec_id)
|
||||
if videoCodec == nil {
|
||||
log.Println("Error: Unsupported codec!")
|
||||
return // Codec not found
|
||||
}
|
||||
|
||||
// Copy context
|
||||
ctxtDest = videoCodec.AvcodecAllocContext3()
|
||||
|
||||
if ctxtDest.AvcodecCopyContext(ctxtSource) != 0 {
|
||||
log.Println("Error: Couldn't copy codec context")
|
||||
return // Error copying codec context
|
||||
}
|
||||
|
||||
// Open codec
|
||||
if ctxtDest.AvcodecOpen2(videoCodec, nil) < 0 {
|
||||
return // Could not open codec
|
||||
}
|
||||
|
||||
// Allocate video frame
|
||||
videoFrame = avutil.AvFrameAlloc()
|
||||
|
||||
// Allocate an Frame structure
|
||||
if videoFrameRGB = avutil.AvFrameAlloc(); videoFrameRGB == nil {
|
||||
return
|
||||
}
|
||||
|
||||
//##TODO
|
||||
var a swscale.PixelFormat
|
||||
var b int
|
||||
//avcodec.PixelFormat
|
||||
//avcodec.PIX_FMT_RGB24
|
||||
//avcodec.SWS_BILINEAR
|
||||
|
||||
w := ctxtDest.Width()
|
||||
h := ctxtDest.Height()
|
||||
pix_fmt := ctxtDest.PixFmt()
|
||||
|
||||
// Determine required buffer size and allocate buffer
|
||||
numBytes = avcodec.AvpictureGetSize((avcodec.PixelFormat)(a), w, h)
|
||||
|
||||
buffer := avutil.AvMalloc(uintptr(numBytes))
|
||||
|
||||
// Assign appropriate parts of buffer to image planes in videoFrameRGB
|
||||
// Note that videoFrameRGB is an Frame, but Frame is a superset
|
||||
// of Picture
|
||||
avp := (*avcodec.Picture)(unsafe.Pointer(videoFrameRGB))
|
||||
avp.AvpictureFill((*uint8)(buffer), (avcodec.PixelFormat)(a), w, h)
|
||||
|
||||
// initialize SWS context for software scaling
|
||||
ctxtSws = swscale.SwsGetcontext(w,
|
||||
h,
|
||||
(swscale.PixelFormat)(pix_fmt),
|
||||
w,
|
||||
h,
|
||||
a,
|
||||
b,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
// Read frames and save first five frames to disk
|
||||
i := 0
|
||||
|
||||
for ctxtFormat.AvReadFrame(packet) >= 0 {
|
||||
// Is this a packet from the video stream?
|
||||
s := packet.StreamIndex()
|
||||
if s == videoStream {
|
||||
// Decode video frame
|
||||
ctxtDest.AvcodecDecodeVideo2((*avcodec.Frame)(unsafe.Pointer(videoFrame)), &frameFinished, packet)
|
||||
|
||||
// Did we get a video frame?
|
||||
if frameFinished > 0 {
|
||||
// Convert the image from its native format to RGB
|
||||
d := avutil.Data(videoFrame)
|
||||
l := avutil.Linesize(videoFrame)
|
||||
dr := avutil.Data(videoFrameRGB)
|
||||
lr := avutil.Linesize(videoFrameRGB)
|
||||
swscale.SwsScale(ctxtSws,
|
||||
d,
|
||||
l,
|
||||
0,
|
||||
h,
|
||||
dr,
|
||||
lr,
|
||||
)
|
||||
|
||||
// Save the frame to disk
|
||||
if i <= 5 {
|
||||
saveFrame(videoFrameRGB, w, h, i)
|
||||
}
|
||||
i++
|
||||
// Get a pointer to the codec context for the video stream
|
||||
pCodecCtxOrig := pFormatContext.Streams()[i].Codec()
|
||||
// Find the decoder for the video stream
|
||||
pCodec := avcodec.AvcodecFindDecoder(avcodec.CodecId(pCodecCtxOrig.GetCodecId()))
|
||||
if pCodec == nil {
|
||||
fmt.Println("Unsupported codec!")
|
||||
os.Exit(1)
|
||||
}
|
||||
// Copy context
|
||||
pCodecCtx := pCodec.AvcodecAllocContext3()
|
||||
if pCodecCtx.AvcodecCopyContext((*avcodec.Context)(unsafe.Pointer(pCodecCtxOrig))) != 0 {
|
||||
fmt.Println("Couldn't copy codec context")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Open codec
|
||||
if pCodecCtx.AvcodecOpen2(pCodec, nil) < 0 {
|
||||
fmt.Println("Could not open codec")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Allocate video frame
|
||||
pFrame := avutil.AvFrameAlloc()
|
||||
|
||||
// Allocate an AVFrame structure
|
||||
pFrameRGB := avutil.AvFrameAlloc()
|
||||
if pFrameRGB == nil {
|
||||
fmt.Println("Unable to allocate RGB Frame")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Determine required buffer size and allocate buffer
|
||||
numBytes := uintptr(avcodec.AvpictureGetSize(avcodec.AV_PIX_FMT_RGB24, pCodecCtx.Width(),
|
||||
pCodecCtx.Height()))
|
||||
buffer := avutil.AvMalloc(numBytes)
|
||||
|
||||
// Assign appropriate parts of buffer to image planes in pFrameRGB
|
||||
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
|
||||
// of AVPicture
|
||||
avp := (*avcodec.Picture)(unsafe.Pointer(pFrameRGB))
|
||||
avp.AvpictureFill((*uint8)(buffer), avcodec.AV_PIX_FMT_RGB24, pCodecCtx.Width(), pCodecCtx.Height())
|
||||
|
||||
// initialize SWS context for software scaling
|
||||
swsCtx := swscale.SwsGetcontext(
|
||||
pCodecCtx.Width(),
|
||||
pCodecCtx.Height(),
|
||||
(swscale.PixelFormat)(pCodecCtx.PixFmt()),
|
||||
pCodecCtx.Width(),
|
||||
pCodecCtx.Height(),
|
||||
avcodec.AV_PIX_FMT_RGB24,
|
||||
avcodec.SWS_BILINEAR,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
// Read frames and save first five frames to disk
|
||||
frameNumber := 1
|
||||
packet := avcodec.AvPacketAlloc()
|
||||
for pFormatContext.AvReadFrame(packet) >= 0 {
|
||||
// Is this a packet from the video stream?
|
||||
if packet.StreamIndex() == i {
|
||||
// Decode video frame
|
||||
response := pCodecCtx.AvcodecSendPacket(packet)
|
||||
if response < 0 {
|
||||
fmt.Printf("Error while sending a packet to the decoder: %s\n", avutil.ErrorFromCode(response))
|
||||
}
|
||||
for response >= 0 {
|
||||
response = pCodecCtx.AvcodecReceiveFrame((*avcodec.Frame)(unsafe.Pointer(pFrame)))
|
||||
if response == avutil.AvErrorEAGAIN || response == avutil.AvErrorEOF {
|
||||
break
|
||||
} else if response < 0 {
|
||||
fmt.Printf("Error while receiving a frame from the decoder: %s\n", avutil.ErrorFromCode(response))
|
||||
return
|
||||
}
|
||||
|
||||
if frameNumber <= 5 {
|
||||
// Convert the image from its native format to RGB
|
||||
swscale.SwsScale2(swsCtx, avutil.Data(pFrame),
|
||||
avutil.Linesize(pFrame), 0, pCodecCtx.Height(),
|
||||
avutil.Data(pFrameRGB), avutil.Linesize(pFrameRGB))
|
||||
|
||||
// Save the frame to disk
|
||||
fmt.Printf("Writing frame %d\n", frameNumber)
|
||||
SaveFrame(pFrameRGB, pCodecCtx.Width(), pCodecCtx.Height(), frameNumber)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
frameNumber++
|
||||
}
|
||||
}
|
||||
|
||||
// Free the packet that was allocated by av_read_frame
|
||||
packet.AvFreePacket()
|
||||
}
|
||||
|
||||
// Free the RGB image
|
||||
avutil.AvFree(buffer)
|
||||
avutil.AvFrameFree(pFrameRGB)
|
||||
|
||||
// Free the YUV frame
|
||||
avutil.AvFrameFree(pFrame)
|
||||
|
||||
// Close the codecs
|
||||
pCodecCtx.AvcodecClose()
|
||||
(*avcodec.Context)(unsafe.Pointer(pCodecCtxOrig)).AvcodecClose()
|
||||
|
||||
// Close the video file
|
||||
pFormatContext.AvformatCloseInput()
|
||||
|
||||
// Stop after saving frames of first video straem
|
||||
break
|
||||
|
||||
default:
|
||||
fmt.Println("Didn't find a video stream")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Free the packet that was allocated by av_read_frame
|
||||
packet.AvFreePacket()
|
||||
}
|
||||
|
||||
// Free the RGB image
|
||||
avutil.AvFree(buffer)
|
||||
avutil.AvFrameFree(videoFrameRGB)
|
||||
|
||||
// Free the YUV frame
|
||||
avutil.AvFrameFree(videoFrame)
|
||||
|
||||
// Close the codecs
|
||||
ctxtDest.AvcodecClose()
|
||||
ctxtSource.AvcodecClose()
|
||||
|
||||
// Close the video file
|
||||
ctxtFormat.AvformatCloseInput()
|
||||
|
||||
}
|
||||
|
||||
func saveFrame(videoFrame *avutil.Frame, width int, height int, iFrame int) {
|
||||
|
||||
var szFilename string
|
||||
var y int
|
||||
var file *os.File
|
||||
var err error
|
||||
|
||||
szFilename = ""
|
||||
|
||||
// Open file
|
||||
szFilename = fmt.Sprintf("frame%d.ppm", iFrame)
|
||||
|
||||
if file, err = os.Open(szFilename); err != nil {
|
||||
log.Println("Error Reading")
|
||||
}
|
||||
|
||||
// Write header
|
||||
fh := fmt.Sprintf("P6\n%d %d\n255\n", width, height)
|
||||
log.Println(fh)
|
||||
|
||||
// Write pixel data
|
||||
for y = 0; y < height; y++ {
|
||||
// d := avutil.Data(videoFrame)
|
||||
// l := avutil.Linesize(videoFrame)
|
||||
//##TODO
|
||||
f := make([]byte, 100)
|
||||
file.Write(f)
|
||||
}
|
||||
|
||||
file.Close()
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/giorgisio/goav/avcodec"
|
||||
"github.com/giorgisio/goav/avdevice"
|
||||
"github.com/giorgisio/goav/avfilter"
|
||||
@@ -8,7 +10,6 @@ import (
|
||||
"github.com/giorgisio/goav/avutil"
|
||||
"github.com/giorgisio/goav/swresample"
|
||||
"github.com/giorgisio/goav/swscale"
|
||||
"log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
module github.com/giorgisio/goav
|
||||
|
||||
require (
|
||||
github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd // indirect
|
||||
github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1 // indirect
|
||||
)
|
||||
@@ -0,0 +1,4 @@
|
||||
github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd h1:1e+0Z+T4t1mKL5xxvxXh5FkjuiToQGKreCobLu7lR3Y=
|
||||
github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8=
|
||||
github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1 h1:4iPLwzjiWGBQnYdtKbg/JNlGlEEvklrrMdjypdA1LKQ=
|
||||
github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
|
||||
Reference in New Issue
Block a user