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}; | 	struct AVPacket pkt = {.data = data, .size = size}; | ||||||
| 	return avcodec_decode_video2(ctx, frame, got, &pkt); | 	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 "C" | ||||||
| import ( | import ( | ||||||
| @@ -91,6 +96,44 @@ func (self *VideoDecoder) Decode(pkt []byte) (img *VideoFrame, err error) { | |||||||
| 	return | 	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) { | func NewVideoDecoder(stream av.CodecData) (dec *VideoDecoder, err error) { | ||||||
| 	_dec := &VideoDecoder{} | 	_dec := &VideoDecoder{} | ||||||
| 	var id uint32 | 	var id uint32 | ||||||
|   | |||||||
| @@ -354,7 +354,7 @@ var CodecTypes = flv.CodecTypes | |||||||
|  |  | ||||||
| func (self *Conn) writeBasicConf() (err error) { | func (self *Conn) writeBasicConf() (err error) { | ||||||
| 	// > SetChunkSize | 	// > SetChunkSize | ||||||
| 	if err = self.writeSetChunkSize(1024 * 1024 * 128); err != nil { | 	if err = self.writeSetChunkSize(1024 * 128); err != nil { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	// > WindowAckSize | 	// > WindowAckSize | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Andrey Semochkin
					Andrey Semochkin