package main
import (
"fmt"
"os"
"syscall"
ffmpeg "github.com/qrtc/ffmpeg-dev-go"
)
const (
AUDIO_INBUF_SIZE = 20480
AUDIO_REFILL_THRESH = 4096
)
func getFormatFromSampleFmt(sampleFmt ffmpeg.AVSampleFormat) (string, int32) {
sampleFmtEntry := []struct {
sampleFmt ffmpeg.AVSampleFormat
fmtBe string
fmtLe string
}{
{ffmpeg.AV_SAMPLE_FMT_U8, "u8", "u8"},
{ffmpeg.AV_SAMPLE_FMT_S16, "s16be", "s16le"},
{ffmpeg.AV_SAMPLE_FMT_S32, "s32be", "s32le"},
{ffmpeg.AV_SAMPLE_FMT_FLT, "f32be", "f32le"},
{ffmpeg.AV_SAMPLE_FMT_DBL, "f64be", "f64le"},
}
for _, entry := range sampleFmtEntry {
if sampleFmt == entry.sampleFmt {
return ffmpeg.AV_NE(entry.fmtBe, entry.fmtLe), 0
}
}
fmt.Fprintf(os.Stderr, "sample format %s is not supported as output format\n",
ffmpeg.AvGetSampleFmtName(sampleFmt))
return "", -1
}
func decode(decCtx *ffmpeg.AVCodecContext, pkt *ffmpeg.AVPacket, frame *ffmpeg.AVFrame, outfile *os.File) {
// send the packet with the compressed data to the decoder
ret := ffmpeg.AvCodecSendPacket(decCtx, pkt)
if ret < 0 {
fmt.Fprintf(os.Stderr, "Error submitting the packet to the decoder\n")
os.Exit(1)
}
// read all the output frames (in general there may be any number of them
for ret >= 0 {
ret = ffmpeg.AvCodecReceiveFrame(decCtx, frame)
if ret == ffmpeg.AVERROR(syscall.EAGAIN) || ret == ffmpeg.AVERROR_EOF {
return
} else if ret < 0 {
fmt.Fprintf(os.Stderr, "Error during decoding\n")
os.Exit(1)
}
dataSize := ffmpeg.AvGetBytesPerSample(decCtx.GetSampleFmt())
if dataSize < 0 {
// This should not occur, checking just for paranoia
fmt.Fprintf(os.Stderr, "Failed to calculate data size\n")
os.Exit(1)
}
for i := int32(0); i < frame.GetNbSamples(); i++ {
for ch := 0; ch < int(decCtx.GetChannels()); ch++ {
outfile.Write(ffmpeg.ByteSliceWithOffset(frame.GetDataIdx(ch), dataSize*i, dataSize))
}
}
}
}
func main() {
if len(os.Args) <= 2 {
fmt.Fprintf(os.Stdout, "Usage: %s