optimize code

add doc
This commit is contained in:
danil_e71
2022-05-20 10:56:59 +03:00
parent fbb1285025
commit a418dae3b6
6 changed files with 37 additions and 32 deletions

View File

@@ -59,16 +59,13 @@ func freeDecoder(decoder *decoder) {
} }
} }
func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { func (decoder *decoder) decode(packet *C.AVPacket) (pkt *Packet, err error) {
pkt = &Packet{} pkt = &Packet{
streamIndex: int(packet.stream_index),
codecType: decoder.codecType,
}
pkt.streamIndex = int(packet.stream_index) if !pkt.IsAudio() && !pkt.IsVideo() {
pkt.codecType = decoder.codecType
switch decoder.codecType {
case int(C.AVMEDIA_TYPE_AUDIO):
case int(C.AVMEDIA_TYPE_VIDEO):
default:
// do nothing // do nothing
return return
} }
@@ -91,15 +88,15 @@ func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) {
pkt.duration = int64(frame.pkt_duration) pkt.duration = int64(frame.pkt_duration)
pkt.position = int64(frame.pkt_pos) pkt.position = int64(frame.pkt_pos)
switch decoder.codecType { var encPacket C.AVPacket
case C.AVMEDIA_TYPE_VIDEO: defer C.av_packet_unref(&encPacket)
switch {
case pkt.IsVideo():
pkt.width = int(frame.width) pkt.width = int(frame.width)
pkt.height = int(frame.height) pkt.height = int(frame.height)
pkt.keyFrame = int(frame.key_frame) == 1 pkt.keyFrame = int(frame.key_frame) == 1
var encPacket C.AVPacket
defer C.av_packet_unref(&encPacket)
switch frame.format { switch frame.format {
case C.AV_PIX_FMT_NONE, C.AV_PIX_FMT_YUVJ420P: 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) { 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 pkt.IsAudio():
case C.AVMEDIA_TYPE_AUDIO:
pkt.bitRate = int(decoder.codecCtx.bit_rate) pkt.bitRate = int(decoder.codecCtx.bit_rate)
pkt.sampleRate = int(frame.sample_rate) pkt.sampleRate = int(frame.sample_rate)
pkt.channels = int(frame.channels) 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) { 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)) err = fmt.Errorf("ffmpeg: rtsp_avcodec_encode_resample_wav failed: %s", CErr2Str(cerr))
return return
} }
pkt.data = decodeAVPacket(&encPacket)
case C.AV_SAMPLE_FMT_S16: 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) { 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)) err = fmt.Errorf("ffmpeg: rtsp_avcodec_encode_wav failed: %s", CErr2Str(cerr))
return return
} }
pkt.data = decodeAVPacket(&encPacket)
default: default:
err = fmt.Errorf("ffmpeg: audio format %d not supported", frame.format) err = fmt.Errorf("ffmpeg: audio format %d not supported", frame.format)
return return
} }
default:
} }
pkt.data = decodeAVPacket(&encPacket)
return return
} }

12
pkt.go
View File

@@ -3,6 +3,7 @@ package rtsp
// #include "ffmpeg.h" // #include "ffmpeg.h"
import "C" import "C"
// Image image meta
type Image struct { type Image struct {
// only image // only image
width int width int
@@ -20,6 +21,7 @@ func (image *Image) Width() int {
return image.width return image.width
} }
// Audio audio meta
type Audio struct { type Audio struct {
// only audio // only audio
sampleRate int sampleRate int
@@ -42,6 +44,7 @@ func (audio *Audio) Channels() int {
return audio.channels return audio.channels
} }
// Packet decoded media packet
type Packet struct { type Packet struct {
streamIndex int streamIndex int
codecType int codecType int
@@ -59,12 +62,17 @@ func (packet *Packet) Data() []byte {
return packet.data return packet.data
} }
// IsAudio packet // IsAudio is audio packet type
func (packet *Packet) IsAudio() bool { func (packet *Packet) IsAudio() bool {
return packet.codecType == C.AVMEDIA_TYPE_AUDIO return packet.codecType == C.AVMEDIA_TYPE_AUDIO
} }
// IsVideo packet // IsVideo is video packet type
func (packet *Packet) IsVideo() bool { func (packet *Packet) IsVideo() bool {
return packet.codecType == C.AVMEDIA_TYPE_VIDEO return packet.codecType == C.AVMEDIA_TYPE_VIDEO
} }
// Type packet type
func (packet *Packet) Type() int {
return packet.codecType
}

View File

@@ -13,14 +13,19 @@ import (
"unsafe" "unsafe"
) )
// Type rtsp transport protocol
type Type int type Type int
const ( const (
// Auto auto change
Auto Type = iota Auto Type = iota
// Tcp use tcp transport protocol
Tcp Tcp
// Udp use udp transport protocol
Udp Udp
) )
// Stream media stream
type Stream struct { type Stream struct {
formatCtx *C.AVFormatContext formatCtx *C.AVFormatContext
dictionary *C.AVDictionary dictionary *C.AVDictionary
@@ -30,7 +35,7 @@ type Stream struct {
uri string uri string
} }
// New stream // New media stream
func New(uri string) (stream *Stream) { func New(uri string) (stream *Stream) {
stream = &Stream{uri: uri} stream = &Stream{uri: uri}
stream.decoders = make(map[int]*decoder) stream.decoders = make(map[int]*decoder)
@@ -55,15 +60,17 @@ func free(stream *Stream) {
} }
} }
// ErrTimeout ETIMEDOUT
type ErrTimeout struct { type ErrTimeout struct {
err error err error
} }
// Error error interface
func (e ErrTimeout) Error() string { func (e ErrTimeout) Error() string {
return e.err.Error() return e.err.Error()
} }
// Setup transport (tcp or udp) // Setup transport protocol (tcp, udp or auto)
func (stream *Stream) Setup(t Type) (err error) { func (stream *Stream) Setup(t Type) (err error) {
transport := C.CString("rtsp_transport") transport := C.CString("rtsp_transport")
defer C.free(unsafe.Pointer(transport)) defer C.free(unsafe.Pointer(transport))
@@ -134,6 +141,7 @@ func (stream *Stream) Setup(t Type) (err error) {
return return
} }
// ReadPacket read frame from stream and decode it to Packet
func (stream *Stream) ReadPacket() (pkt *Packet, err error) { func (stream *Stream) ReadPacket() (pkt *Packet, err error) {
packet := C.av_packet_alloc() packet := C.av_packet_alloc()
defer C.av_packet_free(&packet) defer C.av_packet_free(&packet)
@@ -153,7 +161,7 @@ func (stream *Stream) ReadPacket() (pkt *Packet, err error) {
defer stream.mu.RUnlock() defer stream.mu.RUnlock()
if decoder, ok := stream.decoders[int(packet.stream_index)]; ok { 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)) err = fmt.Errorf("ffmpeg: decoder not found %d", int(packet.stream_index))

View File

@@ -10,6 +10,7 @@ import (
"unsafe" "unsafe"
) )
// CErr2Str convert C error code to Go string
func CErr2Str(code C.int) string { func CErr2Str(code C.int) string {
buf := make([]byte, 64) buf := make([]byte, 64)

View File

@@ -10,6 +10,7 @@ import (
"unsafe" "unsafe"
) )
// CErr2Str convert C error code to Go string
func CErr2Str(code C.int) string { func CErr2Str(code C.int) string {
buf := make([]byte, 64) buf := make([]byte, 64)

View File

@@ -10,6 +10,7 @@ import (
"unsafe" "unsafe"
) )
// CErr2Str convert C error code to Go string
func CErr2Str(code C.int) string { func CErr2Str(code C.int) string {
buf := make([]byte, 64) buf := make([]byte, 64)