func (e *Encoder) Close() { // Process "delayed" frames for { outsize := C.avcodec_encode_video(e._context, ptr(e._outbuf), C.int(len(e._outbuf)), nil) if outsize == 0 { break } n, err := e.Output.Write(e._outbuf[:outsize]) if err != nil { panic(err) } if n < int(outsize) { panic(fmt.Errorf("Short write, expected %d, wrote %d", outsize, n)) } } n, err := e.Output.Write([]byte{0, 0, 1, 0xb7}) if err != nil || n != 4 { log.Panicf("Error finishing mpeg file: %q; n = %d", err, n) } C.avcodec_close((*C.AVCodecContext)(unsafe.Pointer(e._context))) C.av_free(unsafe.Pointer(e._context)) C.av_free(unsafe.Pointer(e._frame)) e._frame, e._codec = nil, nil }
func avcodec_encode_video(ctx *_CodecContext, buffer []byte, size *int, frame *Frame) int { return int(C.avcodec_encode_video( ctx.ctx, (*C.uint8_t)(unsafe.Pointer(&buffer[0])), C.int(*size), (*C.AVFrame)(frame.avframe))) }
func (e *Encoder) WriteFrame() error { e._frame.pts = C.int64_t(e._context.frame_number) var input_data [3]*C.uint8_t var input_linesize [3]C.int switch im := e.im.(type) { case *image.RGBA: bpp := 4 input_data = [3]*C.uint8_t{ptr(im.Pix)} input_linesize = [3]C.int{C.int(e.im.Bounds().Dx() * bpp)} case *image.NRGBA: bpp := 4 input_data = [3]*C.uint8_t{ptr(im.Pix)} input_linesize = [3]C.int{C.int(e.im.Bounds().Dx() * bpp)} default: panic("Unknown input image type") } // Perform scaling from input type to output type C.sws_scale(e._swscontext, &input_data[0], &input_linesize[0], 0, e._context.height, &e._frame.data[0], &e._frame.linesize[0]) outsize := C.avcodec_encode_video(e._context, ptr(e._outbuf), C.int(len(e._outbuf)), e._frame) if outsize == 0 { return nil } n, err := e.Output.Write(e._outbuf[:outsize]) if err != nil { return err } if n < int(outsize) { return fmt.Errorf("Short write, expected %d, wrote %d", outsize, n) } return nil }