mirror of
https://github.com/Danile71/go-rtsp.git
synced 2025-09-26 20:21:15 +08:00
optimize code
add doc
This commit is contained in:
40
decoder.go
40
decoder.go
@@ -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
12
pkt.go
@@ -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
|
||||||
|
}
|
||||||
|
14
stream.go
14
stream.go
@@ -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))
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user