예제 #1
1
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
}
예제 #2
0
파일: codec.go 프로젝트: Dim0N22/gmf
func FindDecoder(i interface{}) (*Codec, error) {
	var avc *C.AVCodec

	switch t := i.(type) {
	case string:
		cname := C.CString(i.(string))
		defer C.free(unsafe.Pointer(cname))

		avc = C.avcodec_find_decoder_by_name(cname)
		break

	case int:
		avc = C.avcodec_find_decoder(uint32(i.(int)))
		break

	default:
		return nil, errors.New(fmt.Sprintf("Unable to find codec, unexpected arguments type '%v'", t))
	}

	if avc == nil {
		return nil, errors.New(fmt.Sprintf("Unable to find codec by value '%v'", i))
	}

	return &Codec{avCodec: avc}, nil
}
예제 #3
0
func (stream *Stream) init() error {
	// need to allocate this first so that it can be closed on error
	stream.Frames = make(chan *Frame)

	if stream.avstream == nil {
		close(stream.Frames)
		return errors.New("nil avstream")
	}

	if stream.cdcctx != nil {
		stream.freeCodecContext()
	}
	stream.cdcctx = stream.avstream.codec

	if decoder := C.avcodec_find_decoder(stream.cdcctx.codec_id); decoder == nil || C.avcodec_open2(stream.cdcctx, decoder, nil) < 0 {
		stream.cdcctx = nil
		close(stream.Frames)
		return errors.New("Cannot find decoder for " + C.GoString(C.avcodec_get_name(stream.cdcctx.codec_id)))
	}

	stream.packets = make(chan *C.AVPacket)
	stream.frame = &Frame{}
	switch stream.avstream.codec.codec_type {
	case C.AVMEDIA_TYPE_AUDIO:
		stream.decodeF = avcodec_decode_audio
	case C.AVMEDIA_TYPE_VIDEO:
		stream.decodeF = avcodec_decode_video
	default:
		stream.freeCodecContext()
		close(stream.Frames)
		return errors.New("unsupported codec")
	}

	return nil
}
예제 #4
0
파일: context.go 프로젝트: ovr/goav
func (codecContext *CodecContext) Codec() *Codec {
	if codecContext.CodecIsOpen() == false {
		codec := C.avcodec_find_decoder(codecContext.codec_id)
		if codec == nil {
			panic("Codec not found")
		}

		C.avcodec_open2((*C.struct_AVCodecContext)(codecContext), codec, nil)
	}

	return (*Codec)(codecContext.codec)
}
예제 #5
0
파일: decoder.go 프로젝트: reusee/player
func NewDecoder(filename string) (*Decoder, error) {
	self := new(Decoder)

	// format context
	var formatContext *C.AVFormatContext
	if C.avformat_open_input(&formatContext, C.CString(filename), nil, nil) != C.int(0) {
		return nil, errors.New(fmt.Sprintf("can't open %d", filename))
	}
	if C.avformat_find_stream_info(formatContext, nil) < 0 {
		return nil, errors.New("find stream info error")
	}
	C.av_dump_format(formatContext, 0, C.CString(filename), 0)
	self.FormatContext = formatContext

	// streams
	var streams []*C.AVStream
	header := (*reflect.SliceHeader)(unsafe.Pointer(&streams))
	header.Cap = int(formatContext.nb_streams)
	header.Len = int(formatContext.nb_streams)
	header.Data = uintptr(unsafe.Pointer(formatContext.streams))
	self.Streams = streams
	for _, stream := range streams {
		switch stream.codec.codec_type {
		case C.AVMEDIA_TYPE_VIDEO:
			self.VideoStreams = append(self.VideoStreams, stream)
		case C.AVMEDIA_TYPE_AUDIO:
			self.AudioStreams = append(self.AudioStreams, stream)
		default: //TODO other stream
		}
	}

	// codecs
	for _, stream := range self.Streams {
		codec := C.avcodec_find_decoder(stream.codec.codec_id)
		if codec == nil {
			continue
		}
		var options *C.AVDictionary
		if C.avcodec_open2(stream.codec, codec, &options) < 0 {
			return nil, errors.New(fmt.Sprintf("open codec error %v", stream.codec))
		}
		self.openedCodecs = append(self.openedCodecs, stream.codec)
	}

	// output channels
	self.audioFrames = make(chan *AudioFrame, 1024)
	self.timedFrames = make(chan *C.AVFrame)

	return self, nil
}
예제 #6
0
func (c *Coder) Open() {
	c.prepare()
	c.Codec = C.avcodec_find_decoder(c.Ctx.codec_id)
	if c.Codec == nil {
		log.Printf("could not find Codec for id %d", c.Ctx.codec_id)
		return
	}
	avcodec_mutex.Lock()
	res := C.avcodec_open(c.Ctx, c.Codec)
	avcodec_mutex.Unlock()

	if res < 0 {
		println("error openning codec")
		return
	}
	println("codec openned")
	c.Valid = true
}
예제 #7
0
파일: avcodec.go 프로젝트: adityanatraj/gmf
func avcodec_find_decoder(codec_id int32) _Codec {
	return _Codec{codec: C.avcodec_find_decoder(uint32(codec_id))}
}
예제 #8
0
파일: avcodec.go 프로젝트: hbdlb/goav
//Find a registered decoder with a matching codec ID.
func AvcodecFindDecoder(id CodecId) *Codec {
	return (*Codec)(C.avcodec_find_decoder((C.enum_AVCodecID)(id)))
}
예제 #9
0
//Find a registered decoder with a matching codec ID.
//AVCodec *avcodec_find_decoder (enum AVCodecID id)
func Avcodec_find_decoder(id AVCodecID) *AVCodec {
	return (*AVCodec)(C.avcodec_find_decoder((C.enum_AVCodecID)(id)))
}
예제 #10
0
// 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
}
예제 #11
0
func avcodec_find_decoder(codec_id int32) Codec {
	var codec Codec
	codec.codec = C.avcodec_find_decoder(uint32(codec_id))
	return codec
}