From a418dae3b6e53aac023175cf0c608f2fbf530bdb Mon Sep 17 00:00:00 2001 From: danil_e71 Date: Fri, 20 May 2022 10:56:59 +0300 Subject: [PATCH] optimize code add doc --- decoder.go | 40 +++++++++++++--------------------------- pkt.go | 12 ++++++++++-- stream.go | 14 +++++++++++--- types_darwin.go | 1 + types_linux.go | 1 + types_windows.go | 1 + 6 files changed, 37 insertions(+), 32 deletions(-) diff --git a/decoder.go b/decoder.go index 6178842..d245210 100644 --- a/decoder.go +++ b/decoder.go @@ -59,16 +59,13 @@ func freeDecoder(decoder *decoder) { } } -func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { - pkt = &Packet{} +func (decoder *decoder) decode(packet *C.AVPacket) (pkt *Packet, err error) { + pkt = &Packet{ + streamIndex: int(packet.stream_index), + codecType: decoder.codecType, + } - pkt.streamIndex = int(packet.stream_index) - pkt.codecType = decoder.codecType - - switch decoder.codecType { - case int(C.AVMEDIA_TYPE_AUDIO): - case int(C.AVMEDIA_TYPE_VIDEO): - default: + if !pkt.IsAudio() && !pkt.IsVideo() { // do nothing return } @@ -91,15 +88,15 @@ func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { pkt.duration = int64(frame.pkt_duration) pkt.position = int64(frame.pkt_pos) - switch decoder.codecType { - case C.AVMEDIA_TYPE_VIDEO: + var encPacket C.AVPacket + defer C.av_packet_unref(&encPacket) + + switch { + case pkt.IsVideo(): pkt.width = int(frame.width) pkt.height = int(frame.height) pkt.keyFrame = int(frame.key_frame) == 1 - var encPacket C.AVPacket - defer C.av_packet_unref(&encPacket) - switch frame.format { case C.AV_PIX_FMT_NONE, C.AV_PIX_FMT_YUVJ420P: if cerr = C.rtsp_avcodec_encode_jpeg(decoder.codecCtx, frame, &encPacket); cerr != C.int(0) { @@ -114,9 +111,7 @@ func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { } } - pkt.data = decodeAVPacket(&encPacket) - - case C.AVMEDIA_TYPE_AUDIO: + case pkt.IsAudio(): pkt.bitRate = int(decoder.codecCtx.bit_rate) pkt.sampleRate = int(frame.sample_rate) pkt.channels = int(frame.channels) @@ -133,32 +128,23 @@ func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { } } - var encPacket C.AVPacket - defer C.av_packet_unref(&encPacket) - if cerr = C.rtsp_avcodec_encode_resample_wav(decoder.codecCtx, decoder.swrContext, frame, &encPacket); cerr < C.int(0) { err = fmt.Errorf("ffmpeg: rtsp_avcodec_encode_resample_wav failed: %s", CErr2Str(cerr)) return } - pkt.data = decodeAVPacket(&encPacket) case C.AV_SAMPLE_FMT_S16: - var encPacket C.AVPacket - defer C.av_packet_unref(&encPacket) - if cerr = C.rtsp_avcodec_encode_wav(decoder.codecCtx, frame, &encPacket); cerr != C.int(0) { err = fmt.Errorf("ffmpeg: rtsp_avcodec_encode_wav failed: %s", CErr2Str(cerr)) return } - pkt.data = decodeAVPacket(&encPacket) default: err = fmt.Errorf("ffmpeg: audio format %d not supported", frame.format) return } - - default: } + pkt.data = decodeAVPacket(&encPacket) return } diff --git a/pkt.go b/pkt.go index dc9b775..1457eb5 100644 --- a/pkt.go +++ b/pkt.go @@ -3,6 +3,7 @@ package rtsp // #include "ffmpeg.h" import "C" +// Image image meta type Image struct { // only image width int @@ -20,6 +21,7 @@ func (image *Image) Width() int { return image.width } +// Audio audio meta type Audio struct { // only audio sampleRate int @@ -42,6 +44,7 @@ func (audio *Audio) Channels() int { return audio.channels } +// Packet decoded media packet type Packet struct { streamIndex int codecType int @@ -59,12 +62,17 @@ func (packet *Packet) Data() []byte { return packet.data } -// IsAudio packet +// IsAudio is audio packet type func (packet *Packet) IsAudio() bool { return packet.codecType == C.AVMEDIA_TYPE_AUDIO } -// IsVideo packet +// IsVideo is video packet type func (packet *Packet) IsVideo() bool { return packet.codecType == C.AVMEDIA_TYPE_VIDEO } + +// Type packet type +func (packet *Packet) Type() int { + return packet.codecType +} diff --git a/stream.go b/stream.go index 5506034..4286177 100644 --- a/stream.go +++ b/stream.go @@ -13,14 +13,19 @@ import ( "unsafe" ) +// Type rtsp transport protocol type Type int const ( + // Auto auto change Auto Type = iota + // Tcp use tcp transport protocol Tcp + // Udp use udp transport protocol Udp ) +// Stream media stream type Stream struct { formatCtx *C.AVFormatContext dictionary *C.AVDictionary @@ -30,7 +35,7 @@ type Stream struct { uri string } -// New stream +// New media stream func New(uri string) (stream *Stream) { stream = &Stream{uri: uri} stream.decoders = make(map[int]*decoder) @@ -55,15 +60,17 @@ func free(stream *Stream) { } } +// ErrTimeout ETIMEDOUT type ErrTimeout struct { err error } +// Error error interface func (e ErrTimeout) Error() string { return e.err.Error() } -// Setup transport (tcp or udp) +// Setup transport protocol (tcp, udp or auto) func (stream *Stream) Setup(t Type) (err error) { transport := C.CString("rtsp_transport") defer C.free(unsafe.Pointer(transport)) @@ -134,6 +141,7 @@ func (stream *Stream) Setup(t Type) (err error) { return } +// ReadPacket read frame from stream and decode it to Packet func (stream *Stream) ReadPacket() (pkt *Packet, err error) { packet := C.av_packet_alloc() defer C.av_packet_free(&packet) @@ -153,7 +161,7 @@ func (stream *Stream) ReadPacket() (pkt *Packet, err error) { defer stream.mu.RUnlock() if decoder, ok := stream.decoders[int(packet.stream_index)]; ok { - return decoder.Decode(packet) + return decoder.decode(packet) } err = fmt.Errorf("ffmpeg: decoder not found %d", int(packet.stream_index)) diff --git a/types_darwin.go b/types_darwin.go index a849b68..f992314 100644 --- a/types_darwin.go +++ b/types_darwin.go @@ -10,6 +10,7 @@ import ( "unsafe" ) +// CErr2Str convert C error code to Go string func CErr2Str(code C.int) string { buf := make([]byte, 64) diff --git a/types_linux.go b/types_linux.go index a848802..35ae543 100644 --- a/types_linux.go +++ b/types_linux.go @@ -10,6 +10,7 @@ import ( "unsafe" ) +// CErr2Str convert C error code to Go string func CErr2Str(code C.int) string { buf := make([]byte, 64) diff --git a/types_windows.go b/types_windows.go index c224987..2d39d4c 100644 --- a/types_windows.go +++ b/types_windows.go @@ -10,6 +10,7 @@ import ( "unsafe" ) +// CErr2Str convert C error code to Go string func CErr2Str(code C.int) string { buf := make([]byte, 64)