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 NewContextForInput() (*Context, error) { cCtx := C.avformat_alloc_context() if cCtx == nil { return nil, ErrAllocationError } return NewContextFromC(unsafe.Pointer(cCtx)), nil }
// @todo return error if avCtx is null // @todo start_time is it needed? func NewCtx() *FmtCtx { ctx := &FmtCtx{ avCtx: C.avformat_alloc_context(), streams: make(map[int]*Stream), } ctx.avCtx.start_time = 0 return ctx }
//export OpenMediaFile func OpenMediaFile(filename string) { println("try openning the media file ") println(filename) cfilename := C.CString(filename) C.avcodec_register_all() C.av_register_all() ctx := C.avformat_alloc_context() result := C.av_open_input_file(&ctx, cfilename, nil, 0, nil) println(result) result = C.av_find_stream_info(ctx) C.free(unsafe.Pointer(cfilename)) C.av_close_input_file(ctx) //C.free(unsafe.Pointer(ctx)); }
func (src *DataSource) Connect() bool { src.Valid = false cfilename := C.CString(src.Locator.Filename) src.Ctx = C.avformat_alloc_context() result := C.av_open_input_file(&src.Ctx, cfilename, nil, 0, nil) C.free(unsafe.Pointer(cfilename)) if result != 0 { return src.Valid } result = C.av_find_stream_info(src.Ctx) if result < 0 { return src.Valid } src.Valid = true return src.Valid }
func NewMuxer(source *MediaSource, format, uri string) (*Muxer, error) { m := Muxer{done: make(chan bool), recl: make([]reclaimer, 0, 8)} m.context = C.avformat_alloc_context() if m.context == (*C.AVFormatContext)(null) { return nil, fmt.Errorf("allocate output format context failed") } m.recl = append(m.recl, func() { C.avformat_free_context(m.context) }) var f *C.char = C.CString(format) var u *C.char = C.CString(uri) defer C.free(unsafe.Pointer(f)) defer C.free(unsafe.Pointer(u)) m.context.oformat = C.av_guess_format(f, u, (*C.char)(null)) if m.context.oformat == (*C.AVOutputFormat)(null) { return nil, fmt.Errorf("output format not supported") } C.av_strlcpy(&m.context.filename[0], u, C.size_t(unsafe.Sizeof(m.context.filename))) var err error if m.capture, err = NewCapture(source.Video.driver, source.Video.device); err != nil { return nil, err } return &m, nil }
func avformat_alloc_context() *FormatContext { return &FormatContext{ctx: C.avformat_alloc_context()} }
//Allocate an Context. func AvformatAllocContext() *Context { return (*Context)(C.avformat_alloc_context()) }
//AVFormatContext * avformat_alloc_context (void) //Allocate an AVFormatContext. func Avformat_alloc_context() *AVFormatContext { return (*AVFormatContext)(C.avformat_alloc_context()) }
// NewGenerator returns new generator of screenshots for the video file fn. func NewGenerator(fn string) (_ *Generator, err error) { avfCtx := C.avformat_alloc_context() cfn := C.CString(fn) defer C.free(unsafe.Pointer(cfn)) if C.avformat_open_input(&avfCtx, cfn, nil, nil) != 0 { return nil, errors.New("can't open input stream") } defer func() { if err != nil { C.avformat_close_input(&avfCtx) } }() if C.avformat_find_stream_info(avfCtx, nil) < 0 { return nil, errors.New("can't get stream info") } duration := int64(avfCtx.duration) / 1000 bitrate := int(avfCtx.bit_rate) / 1000 numberOfStreams := int(avfCtx.nb_streams) hdr := reflect.SliceHeader{ Data: uintptr(unsafe.Pointer(avfCtx.streams)), Len: numberOfStreams, Cap: numberOfStreams, } streams := *(*[]*C.struct_AVStream)(unsafe.Pointer(&hdr)) vStreamIndex := -1 aStreamIndex := -1 for i := 0; i < numberOfStreams; i++ { if streams[i].codec.codec_type == C.AVMEDIA_TYPE_VIDEO { vStreamIndex = i } else if streams[i].codec.codec_type == C.AVMEDIA_TYPE_AUDIO { aStreamIndex = i } } if vStreamIndex == -1 { return nil, errors.New("no video stream") } avcCtx := streams[vStreamIndex].codec vCodec := C.avcodec_find_decoder(avcCtx.codec_id) if vCodec == nil { return nil, errors.New("can't find decoder") } if C.avcodec_open2(avcCtx, vCodec, nil) != 0 { return nil, errors.New("can't initialize codec context") } width := int(avcCtx.width) height := int(avcCtx.height) fps := (float64(streams[vStreamIndex].r_frame_rate.num) / float64(streams[vStreamIndex].r_frame_rate.den)) vCodecName := strings.ToUpper(C.GoString(vCodec.name)) vCodecHuman := C.GoString(vCodec.long_name) aCodecName := "" aCodecHuman := "" if aStreamIndex != -1 { aacCtx := streams[aStreamIndex].codec aCodec := C.avcodec_find_decoder(aacCtx.codec_id) if aCodec != nil { aCodecName = strings.ToUpper(C.GoString(aCodec.name)) aCodecHuman = C.GoString(aCodec.long_name) } } return &Generator{ Width: width, Height: height, Duration: duration, VideoCodec: vCodecName, VideoCodecLongName: vCodecHuman, AudioCodec: aCodecName, AudioCodecLongName: aCodecHuman, numberOfStreams: numberOfStreams, vStreamIndex: vStreamIndex, aStreamIndex: aStreamIndex, FPS: fps, Bitrate: bitrate, streams: streams, avfContext: avfCtx, avcContext: avcCtx, }, nil }