func encode(cc *CodecCtx, avFrame *C.struct_AVFrame, mediaType int32) (*Packet, bool, error) { var gotOutput int var ret int p := NewPacket() switch mediaType { case AVMEDIA_TYPE_AUDIO: ret = int(C.avcodec_encode_audio2(cc.avCodecCtx, &p.avPacket, avFrame, (*C.int)(unsafe.Pointer(&gotOutput)))) if ret < 0 { return nil, false, errors.New(fmt.Sprintf("Unable to encode video packet, averror: %s", AvError(int(ret)))) } case AVMEDIA_TYPE_VIDEO: cc.avCodecCtx.field_order = C.AV_FIELD_PROGRESSIVE ret = int(C.avcodec_encode_video2(cc.avCodecCtx, &p.avPacket, avFrame, (*C.int)(unsafe.Pointer(&gotOutput)))) if ret < 0 { return nil, false, errors.New(fmt.Sprintf("Unable to encode video packet, averror: %s", AvError(int(ret)))) } default: return nil, false, errors.New(fmt.Sprintf("Unknown codec type: %v", mediaType)) } return p, (gotOutput > 0), nil }
func (m *H264Encoder) Encode(img *image.YCbCr) (out h264Out, err error) { var f *C.AVFrame if img == nil { f = nil } else { if img.SubsampleRatio != m.Pixfmt { err = errors.New("image pixfmt not match") return } if img.Rect.Dx() != m.W || img.Rect.Dy() != m.H { err = errors.New("image size not match") return } f = m.m.f f.data[0] = (*C.uint8_t)(unsafe.Pointer(&img.Y[0])) f.data[1] = (*C.uint8_t)(unsafe.Pointer(&img.Cb[0])) f.data[2] = (*C.uint8_t)(unsafe.Pointer(&img.Cr[0])) f.linesize[0] = (C.int)(img.YStride) f.linesize[1] = (C.int)(img.CStride) f.linesize[2] = (C.int)(img.CStride) } C.av_init_packet(&m.m.pkt) r := C.avcodec_encode_video2(m.m.ctx, &m.m.pkt, f, &m.m.got) defer C.av_free_packet(&m.m.pkt) if int(r) < 0 { err = errors.New("encode failed") return } if m.m.got == 0 { err = errors.New("no picture") return } if m.m.pkt.size == 0 { err = errors.New("packet size == 0") return } out.Data = make([]byte, m.m.pkt.size) C.memcpy( unsafe.Pointer(&out.Data[0]), unsafe.Pointer(m.m.pkt.data), (C.size_t)(m.m.pkt.size), ) out.Key = (m.m.pkt.flags & C.AV_PKT_FLAG_KEY) != 0 return }
func (m *Muxer) writeVideoFrame(frame *C.AVFrame) bool { if m.capture.Read(frame) != nil { return false } if m.display != nil { m.display.Render(frame) } pkt := C.AVPacket{} C.av_init_packet(&pkt) frame.pts = C.int64_t(m.videoStream.ts) m.videoStream.ts++ got_packet := C.int(0) if C.avcodec_encode_video2(m.videoStream.stream.codec, &pkt, frame, &got_packet) < 0 { C.av_free_packet(&pkt) return false } if got_packet == 0 { return false } C.av_packet_rescale_ts(&pkt, m.videoStream.stream.codec.time_base, m.videoStream.stream.time_base) pkt.stream_index = m.videoStream.stream.index return C.av_interleaved_write_frame(m.context, &pkt) == 0 }
//Encode a frame of video func (ctxt *Context) AvcodecEncodeVideo2(p *Packet, f *Frame, gp *int) int { return int(C.avcodec_encode_video2((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVPacket)(p), (*C.struct_AVFrame)(f), (*C.int)(unsafe.Pointer(gp)))) }