func avcodec_decode_video(cdcctx *C.AVCodecContext, frame *Frame, packet *C.AVPacket) (bool, error) { var gotFrame C.int if C.avcodec_decode_video2(cdcctx, &frame.avframe, &gotFrame, packet) < 0 { return false, errors.New("error decoding video") } if gotFrame != 0 { frame.PTS = int64(C.av_frame_get_best_effort_timestamp(&frame.avframe)) } return gotFrame != 0, nil }
func (g *Generator) NextFrame() (image.Image, int64, error) { img := image.NewRGBA(image.Rect(0, 0, g.Width, g.Height)) frame := C.av_frame_alloc() var pkt C.struct_AVPacket var frameFinished C.int for C.av_read_frame(g.avfContext, &pkt) == 0 { if int(pkt.stream_index) != g.vStreamIndex { C.av_free_packet(&pkt) continue } if C.avcodec_decode_video2(g.avcContext, frame, &frameFinished, &pkt) <= 0 { C.av_free_packet(&pkt) return nil, 0, errors.New("can't decode frame") } C.av_free_packet(&pkt) if frameFinished == 0 { continue } ctx := C.sws_getContext( C.int(g.Width), C.int(g.Height), g.avcContext.pix_fmt, C.int(g.Width), C.int(g.Height), C.PIX_FMT_RGBA, C.SWS_BICUBIC, nil, nil, nil, ) if ctx == nil { return nil, 0, errors.New("can't allocate scaling context") } srcSlice := (**C.uint8_t)(&frame.data[0]) srcStride := (*C.int)(&frame.linesize[0]) dst := (**C.uint8_t)(unsafe.Pointer(&img.Pix)) dstStride := (*C.int)(unsafe.Pointer(&[1]int{img.Stride})) C.sws_scale( ctx, srcSlice, srcStride, C.int(0), g.avcContext.height, dst, dstStride, ) break } timestamp := int64(C.av_frame_get_best_effort_timestamp(frame)) return img, timestamp, nil }
func (f *Frame) BestEffortTimestamp() int64 { return int64(C.av_frame_get_best_effort_timestamp(f.CAVFrame)) }
func (this *Frame) SetBestPts() { this.avFrame.pts = C.av_frame_get_best_effort_timestamp(this.avFrame) }
func (this *Frame) TimeStamp() int { return int(C.av_frame_get_best_effort_timestamp(this.avFrame)) }