Beispiel #1
0
func (m *Muxer) AddVideoStream(codecId uint32, width, height int) bool {
	codec := C.avcodec_find_encoder(codecId)
	if codec == (*C.AVCodec)(null) {
		return false
	}
	m.context.oformat.video_codec = codecId
	stream := C.avformat_new_stream(m.context, codec)
	if stream == (*C.AVStream)(null) {
		return false
	}
	m.videoStream = Stream{stream, 0}
	c := m.videoStream.stream.codec
	c.codec_id = codecId
	c.codec_type = C.AVMEDIA_TYPE_VIDEO
	c.bit_rate = 400000
	c.width = C.int(width)
	c.height = C.int(height)
	m.videoStream.stream.time_base = C.AVRational{1, 30}
	c.time_base = m.videoStream.stream.time_base
	c.gop_size = 12
	c.pix_fmt = C.AV_PIX_FMT_YUV420P
	if m.context.oformat.flags&C.AVFMT_GLOBALHEADER != 0 {
		c.flags |= C.CODEC_FLAG_GLOBAL_HEADER
	}
	if C.avcodec_open2(c, (*C.AVCodec)(null), (**C.AVDictionary)(null)) < 0 {
		return false
	}
	m.recl = append(m.recl, func() {
		C.avcodec_close(c)
	})
	return true
}
Beispiel #2
0
func FindEncoder(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_encoder_by_name(cname)
		break

	case int:
		avc = C.avcodec_find_encoder(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
}
Beispiel #3
0
func (m *Muxer) AddAudioStream(codecId uint32) bool {
	codec := C.avcodec_find_encoder(codecId)
	if codec == (*C.AVCodec)(null) {
		return false
	}
	m.context.oformat.audio_codec = codecId
	stream := C.avformat_new_stream(m.context, codec)
	if stream == (*C.AVStream)(null) {
		return false
	}
	m.audioStream = Stream{stream, 0}
	c := m.audioStream.stream.codec
	c.bit_rate = 48000
	c.sample_fmt = C.AV_SAMPLE_FMT_S16
	if C.check_sample_fmt(codec, c.sample_fmt) == 0 {
		return false
	}
	c.channels = 1
	c.channel_layout = C.uint64_t(C.av_get_default_channel_layout(c.channels))
	c.sample_rate = 44100
	m.audioStream.stream.time_base = C.AVRational{1, c.sample_rate}
	c.time_base = m.audioStream.stream.time_base
	if m.context.oformat.flags&C.AVFMT_GLOBALHEADER != 0 {
		c.flags |= C.CODEC_FLAG_GLOBAL_HEADER
	}
	if codecId == C.AV_CODEC_ID_AAC {
		m.fifo = C.av_audio_fifo_alloc(c.sample_fmt, c.channels, 1)
		if m.fifo == (*C.AVAudioFifo)(null) {
			return false
		}
		m.recl = append(m.recl, func() {
			C.av_audio_fifo_free(m.fifo)
		})
	}
	if C.avcodec_open2(c, (*C.AVCodec)(null), (**C.AVDictionary)(null)) < 0 {
		return false
	}
	m.recl = append(m.recl, func() {
		C.avcodec_close(c)
	})
	if c.codec.capabilities&C.CODEC_CAP_VARIABLE_FRAME_SIZE != 0 {
		c.frame_size = 10000
	}
	return true
}
Beispiel #4
0
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
}
Beispiel #5
0
func avcodec_find_encoder(codec_id int32) _Codec {
	return _Codec{codec: C.avcodec_find_encoder(uint32(codec_id))}
}
Beispiel #6
0
//Find a registered encoder with a matching codec ID.
func AvcodecFindEncoder(id CodecId) *Codec {
	return (*Codec)(C.avcodec_find_encoder((C.enum_AVCodecID)(id)))
}
Beispiel #7
0
//Find a registered encoder with a matching codec ID.
//AVCodec *avcodec_find_encoder (enum AVCodecID id)
func Avcodec_find_encoder(id AVCodecID) *AVCodec {
	return (*AVCodec)(C.avcodec_find_encoder((C.enum_AVCodecID)(id)))
}
func avcodec_find_encoder(codec_id int32) Codec {
	var codec Codec
	codec.codec = C.avcodec_find_encoder(uint32(codec_id))
	return codec
}