diff --git a/cgo/ffmpeg/video.go b/cgo/ffmpeg/video.go index 36741bb..76a7671 100644 --- a/cgo/ffmpeg/video.go +++ b/cgo/ffmpeg/video.go @@ -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 diff --git a/format/rtmp/rtmp.go b/format/rtmp/rtmp.go index f610e19..f9359b8 100644 --- a/format/rtmp/rtmp.go +++ b/format/rtmp/rtmp.go @@ -354,7 +354,7 @@ var CodecTypes = flv.CodecTypes func (self *Conn) writeBasicConf() (err error) { // > SetChunkSize - if err = self.writeSetChunkSize(1024 * 1024 * 128); err != nil { + if err = self.writeSetChunkSize(1024 * 128); err != nil { return } // > WindowAckSize