add single decode fix rtmp
This commit is contained in:
		| @@ -6,6 +6,11 @@ int wrap_avcodec_decode_video2(AVCodecContext *ctx, AVFrame *frame, void *data, | ||||
| 	struct AVPacket pkt = {.data = data, .size = size}; | ||||
| 	return avcodec_decode_video2(ctx, frame, got, &pkt); | ||||
| } | ||||
|  | ||||
| int wrap_avcodec_decode_video2_empty(AVCodecContext *ctx, AVFrame *frame, void *data, int size, int *got) { | ||||
| 	struct AVPacket pkt = {.data = NULL, .size = 0}; | ||||
| 	return avcodec_decode_video2(ctx, frame, got, &pkt); | ||||
| } | ||||
| */ | ||||
| import "C" | ||||
| import ( | ||||
| @@ -91,6 +96,44 @@ func (self *VideoDecoder) Decode(pkt []byte) (img *VideoFrame, err error) { | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (self *VideoDecoder) DecodeSingle(pkt []byte) (img *VideoFrame, err error) { | ||||
| 	ff := &self.ff.ff | ||||
| 	cgotimg := C.int(0) | ||||
| 	frame := C.av_frame_alloc() | ||||
| 	cerr := C.wrap_avcodec_decode_video2(ff.codecCtx, frame, unsafe.Pointer(&pkt[0]), C.int(len(pkt)), &cgotimg) | ||||
| 	if cerr < C.int(0) { | ||||
| 		err = fmt.Errorf("ffmpeg: avcodec_decode_video2 failed: %d", cerr) | ||||
| 		return | ||||
| 	} | ||||
| 	//https://stackoverflow.com/questions/25431413/decode-compressed-frame-to-memory-using-libav-avcodec-decode-video2 | ||||
| 	if cgotimg == C.int(0) { | ||||
| 		cerr = C.wrap_avcodec_decode_video2_empty(ff.codecCtx, frame, unsafe.Pointer(&pkt[0]), C.int(0), &cgotimg) | ||||
| 		if cerr < C.int(0) { | ||||
| 			err = fmt.Errorf("ffmpeg: avcodec_decode_video2 failed: %d", cerr) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	if cgotimg != C.int(0) { | ||||
| 		w := int(frame.width) | ||||
| 		h := int(frame.height) | ||||
| 		ys := int(frame.linesize[0]) | ||||
| 		cs := int(frame.linesize[1]) | ||||
|  | ||||
| 		img = &VideoFrame{Image: image.YCbCr{ | ||||
| 			Y:              fromCPtr(unsafe.Pointer(frame.data[0]), ys*h), | ||||
| 			Cb:             fromCPtr(unsafe.Pointer(frame.data[1]), cs*h/2), | ||||
| 			Cr:             fromCPtr(unsafe.Pointer(frame.data[2]), cs*h/2), | ||||
| 			YStride:        ys, | ||||
| 			CStride:        cs, | ||||
| 			SubsampleRatio: image.YCbCrSubsampleRatio420, | ||||
| 			Rect:           image.Rect(0, 0, w, h), | ||||
| 		}, frame: frame} | ||||
| 		runtime.SetFinalizer(img, freeVideoFrame) | ||||
| 	} | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func NewVideoDecoder(stream av.CodecData) (dec *VideoDecoder, err error) { | ||||
| 	_dec := &VideoDecoder{} | ||||
| 	var id uint32 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Andrey Semochkin
					Andrey Semochkin