func NewCapture(driver, device string) (*Capture, error) { id := Capture{index: -1} id.context = C.avformat_alloc_context() if id.context == (*C.AVFormatContext)(null) { return nil, fmt.Errorf("allocate output format context failed") } _driver := C.CString(driver) defer C.free(unsafe.Pointer(_driver)) ifmt := C.av_find_input_format(_driver) if ifmt == (*C.AVInputFormat)(null) { return nil, fmt.Errorf("cannot find input driver: %s", driver) } dev := C.CString(device) defer C.free(unsafe.Pointer(dev)) if C.avformat_open_input(&(id.context), dev, ifmt, (**C.AVDictionary)(null)) < 0 { return nil, fmt.Errorf("cannot open device %s", device) } if C.avformat_find_stream_info(id.context, (**C.AVDictionary)(null)) < 0 { return nil, fmt.Errorf("cannot find stream information") } num := int(id.context.nb_streams) streams := (*[1 << 30]*C.AVStream)(unsafe.Pointer(id.context.streams)) var deCtx *C.AVCodecContext for i := 0; i < num; i++ { if streams[i].codec.codec_type == C.AVMEDIA_TYPE_VIDEO { deCtx = streams[i].codec id.index = i break } } if id.index == -1 { return nil, fmt.Errorf("cannot find video stream") } codec := C.avcodec_find_decoder(deCtx.codec_id) if codec == (*C.AVCodec)(null) { return nil, fmt.Errorf("cannot find decode codec") } id.codec = C.avcodec_alloc_context3(codec) if C.avcodec_copy_context(id.codec, deCtx) != 0 { return nil, fmt.Errorf("cannot copy codec context") } if C.avcodec_open2(id.codec, codec, (**C.struct_AVDictionary)(null)) < 0 { return nil, fmt.Errorf("cannot open decode codec") } id.sws = C.sws_getContext(id.codec.width, id.codec.height, id.codec.pix_fmt, id.codec.width, id.codec.height, C.AV_PIX_FMT_YUV420P, C.SWS_BILINEAR, (*C.struct_SwsFilter)(null), (*C.struct_SwsFilter)(null), (*C.double)(null)) id.frame = C.av_frame_alloc() return &id, nil }
func NewEncoder(codec uint32, in image.Image, out io.Writer) (*Encoder, error) { _codec := C.avcodec_find_encoder(codec) if _codec == nil { return nil, fmt.Errorf("could not find codec") } c := C.avcodec_alloc_context3(_codec) f := C.avcodec_alloc_frame() c.bit_rate = 400000 // resolution must be a multiple of two w, h := C.int(in.Bounds().Dx()), C.int(in.Bounds().Dy()) if w%2 == 1 || h%2 == 1 { return nil, fmt.Errorf("Bad image dimensions (%d, %d), must be even", w, h) } log.Printf("Encoder dimensions: %d, %d", w, h) c.width = w c.height = h c.time_base = C.AVRational{1, 25} // FPS c.gop_size = 10 // emit one intra frame every ten frames c.max_b_frames = 1 underlying_im := image.NewYCbCr(in.Bounds(), image.YCbCrSubsampleRatio420) c.pix_fmt = C.PIX_FMT_YUV420P f.data[0] = ptr(underlying_im.Y) f.data[1] = ptr(underlying_im.Cb) f.data[2] = ptr(underlying_im.Cr) f.linesize[0] = w f.linesize[1] = w / 2 f.linesize[2] = w / 2 if C.avcodec_open2(c, _codec, nil) < 0 { return nil, fmt.Errorf("could not open codec") } _swscontext := C.sws_getContext(w, h, C.PIX_FMT_RGB0, w, h, C.PIX_FMT_YUV420P, C.SWS_BICUBIC, nil, nil, nil) e := &Encoder{codec, in, underlying_im, out, _codec, c, _swscontext, f, make([]byte, 16*1024)} return e, nil }
func NewCodecCtx(codec *Codec, options ...[]*Option) *CodecCtx { result := &CodecCtx{codec: codec} codecctx := C.avcodec_alloc_context3(codec.avCodec) if codecctx == nil { return nil } C.avcodec_get_context_defaults3(codecctx, codec.avCodec) result.avCodecCtx = codecctx // we're really expecting only one options-array — // variadic arg is used for backward compatibility if len(options) == 1 { for _, option := range options[0] { option.Set(result.avCodecCtx) } } return result }
func avcodec_alloc_context() *_CodecContext { return &_CodecContext{ctx: C.avcodec_alloc_context3(nil)} }
//Allocate an Context and set its fields to default values. func (c *Codec) AvcodecAllocContext3() *CodecContext { return (*CodecContext)(C.avcodec_alloc_context3((*C.struct_AVCodec)(c))) }
//Allocate an AVCodecContext and set its fields to default values. //AVCodecContext *avcodec_alloc_context3 (const AVCodec *codec) func Avcodec_alloc_context3(c *AVCodec) *AVCodecContext { return (*AVCodecContext)(C.avcodec_alloc_context3((*C.struct_AVCodec)(c))) }