mirror of
https://github.com/qrtc/ffmpeg-dev-go.git
synced 2025-10-17 21:21:47 +08:00
2023-10-19 14:31:46 CST W42D4
This commit is contained in:
@@ -13,9 +13,9 @@ const (
|
||||
AUDIO_REFILL_THRESH = 4096
|
||||
)
|
||||
|
||||
func getFormatFromSampleFmt(sampleFmt ffmpeg.AvSampleFormat) (string, int32) {
|
||||
func getFormatFromSampleFmt(sampleFmt ffmpeg.AVSampleFormat) (string, int32) {
|
||||
sampleFmtEntry := []struct {
|
||||
sampleFmt ffmpeg.AvSampleFormat
|
||||
sampleFmt ffmpeg.AVSampleFormat
|
||||
fmtBe string
|
||||
fmtLe string
|
||||
}{
|
||||
@@ -37,7 +37,7 @@ func getFormatFromSampleFmt(sampleFmt ffmpeg.AvSampleFormat) (string, int32) {
|
||||
return "", -1
|
||||
}
|
||||
|
||||
func decode(decCtx *ffmpeg.AvCodecContext, pkt *ffmpeg.AvPacket, frame *ffmpeg.AvFrame, outfile *os.File) {
|
||||
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 {
|
||||
@@ -48,7 +48,7 @@ func decode(decCtx *ffmpeg.AvCodecContext, pkt *ffmpeg.AvPacket, frame *ffmpeg.A
|
||||
// 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(int32(syscall.EAGAIN)) || ret == ffmpeg.AVERROR_EOF {
|
||||
if ret == ffmpeg.AVERROR(syscall.EAGAIN) || ret == ffmpeg.AVERROR_EOF {
|
||||
return
|
||||
} else if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error during decoding\n")
|
||||
@@ -62,7 +62,7 @@ func decode(decCtx *ffmpeg.AvCodecContext, pkt *ffmpeg.AvPacket, frame *ffmpeg.A
|
||||
}
|
||||
for i := int32(0); i < frame.GetNbSamples(); i++ {
|
||||
for ch := 0; ch < int(decCtx.GetChannels()); ch++ {
|
||||
outfile.Write(ffmpeg.SliceWithOffset(frame.GetDataIdx(ch), dataSize*i, dataSize))
|
||||
outfile.Write(ffmpeg.ByteSliceWithOffset(frame.GetDataIdx(ch), dataSize*i, dataSize))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,7 +114,7 @@ func main() {
|
||||
}
|
||||
|
||||
// decode until eof
|
||||
var decodedFrame *ffmpeg.AvFrame
|
||||
var decodedFrame *ffmpeg.AVFrame
|
||||
inbuf := make([]byte, AUDIO_INBUF_SIZE+ffmpeg.AV_INPUT_BUFFER_PADDING_SIZE)
|
||||
dataOffset := 0
|
||||
dataSize, err := f.Read(inbuf[:AUDIO_INBUF_SIZE])
|
||||
|
@@ -17,12 +17,12 @@ func pgmSave(buf *uint8, wrap, xsize, ysize int32, filename string) {
|
||||
f, _ := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
fmt.Fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255)
|
||||
for i := int32(0); i < ysize; i++ {
|
||||
f.Write(ffmpeg.SliceWithOffset(buf, i+wrap, xsize))
|
||||
f.Write(ffmpeg.ByteSliceWithOffset(buf, i+wrap, xsize))
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
|
||||
func decode(decCtx *ffmpeg.AvCodecContext, frame *ffmpeg.AvFrame, pkt *ffmpeg.AvPacket, filename string) {
|
||||
func decode(decCtx *ffmpeg.AVCodecContext, frame *ffmpeg.AVFrame, pkt *ffmpeg.AVPacket, filename string) {
|
||||
ret := ffmpeg.AvCodecSendPacket(decCtx, pkt)
|
||||
if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error sending a packet for decoding\n")
|
||||
@@ -31,7 +31,7 @@ func decode(decCtx *ffmpeg.AvCodecContext, frame *ffmpeg.AvFrame, pkt *ffmpeg.Av
|
||||
|
||||
for ret >= 0 {
|
||||
ret = ffmpeg.AvCodecReceiveFrame(decCtx, frame)
|
||||
if ret == ffmpeg.AVERROR(int32(syscall.EAGAIN)) || ret == ffmpeg.AVERROR_EOF {
|
||||
if ret == ffmpeg.AVERROR(syscall.EAGAIN) || ret == ffmpeg.AVERROR_EOF {
|
||||
return
|
||||
} else if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error during decoding\n")
|
||||
|
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
// check that a given sample format is supported by the encoder
|
||||
func checkSampleFmt(codec *ffmpeg.AvCodec, sampleFmt ffmpeg.AvSampleFormat) int32 {
|
||||
func checkSampleFmt(codec *ffmpeg.AVCodec, sampleFmt ffmpeg.AVSampleFormat) int32 {
|
||||
for _, f := range codec.GetSampleFmts() {
|
||||
if f == sampleFmt {
|
||||
return 1
|
||||
@@ -20,7 +20,7 @@ func checkSampleFmt(codec *ffmpeg.AvCodec, sampleFmt ffmpeg.AvSampleFormat) int3
|
||||
return 0
|
||||
}
|
||||
|
||||
func selectSampleRate(codec *ffmpeg.AvCodec) int32 {
|
||||
func selectSampleRate(codec *ffmpeg.AVCodec) int32 {
|
||||
var bestSamplerate int32
|
||||
ss := codec.GetSupportedSamplerates()
|
||||
if len(ss) == 0 {
|
||||
@@ -35,7 +35,7 @@ func selectSampleRate(codec *ffmpeg.AvCodec) int32 {
|
||||
}
|
||||
|
||||
// select layout with the highest channel count
|
||||
func selectChannelLayout(codec *ffmpeg.AvCodec) uint64 {
|
||||
func selectChannelLayout(codec *ffmpeg.AVCodec) uint64 {
|
||||
var bestChLayout uint64
|
||||
var bestNbChannels int32
|
||||
ls := codec.GetChannelLayouts()
|
||||
@@ -55,7 +55,7 @@ func selectChannelLayout(codec *ffmpeg.AvCodec) uint64 {
|
||||
return bestChLayout
|
||||
}
|
||||
|
||||
func encode(ctx *ffmpeg.AvCodecContext, frame *ffmpeg.AvFrame, pkt *ffmpeg.AvPacket, output *os.File) {
|
||||
func encode(ctx *ffmpeg.AVCodecContext, frame *ffmpeg.AVFrame, pkt *ffmpeg.AVPacket, output *os.File) {
|
||||
// send the frame for encoding
|
||||
ret := ffmpeg.AvCodecSendFrame(ctx, frame)
|
||||
if ret < 0 {
|
||||
@@ -66,14 +66,14 @@ func encode(ctx *ffmpeg.AvCodecContext, frame *ffmpeg.AvFrame, pkt *ffmpeg.AvPac
|
||||
// read all the available output packets (in general there may be any number of them
|
||||
for ret >= 0 {
|
||||
ret = ffmpeg.AvCodecReceivePacket(ctx, pkt)
|
||||
if ret == ffmpeg.AVERROR(int32(syscall.EAGAIN)) || ret == ffmpeg.AVERROR_EOF {
|
||||
if ret == ffmpeg.AVERROR(syscall.EAGAIN) || ret == ffmpeg.AVERROR_EOF {
|
||||
return
|
||||
} else if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error encoding audio frame\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
output.Write(ffmpeg.Slice(pkt.GetData(), pkt.GetSize()))
|
||||
output.Write(ffmpeg.ByteSlice(pkt.GetData(), pkt.GetSize()))
|
||||
ffmpeg.AvPacketUnref(pkt)
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
ffmpeg "github.com/qrtc/ffmpeg-dev-go"
|
||||
)
|
||||
|
||||
func encode(encCtx *ffmpeg.AvCodecContext, frame *ffmpeg.AvFrame, pkt *ffmpeg.AvPacket, outfile *os.File) {
|
||||
func encode(encCtx *ffmpeg.AVCodecContext, frame *ffmpeg.AVFrame, pkt *ffmpeg.AVPacket, outfile *os.File) {
|
||||
if frame != nil {
|
||||
fmt.Fprintf(os.Stdout, "Send frame %3d\n", frame.GetPts())
|
||||
}
|
||||
@@ -22,7 +22,7 @@ func encode(encCtx *ffmpeg.AvCodecContext, frame *ffmpeg.AvFrame, pkt *ffmpeg.Av
|
||||
|
||||
for ret >= 0 {
|
||||
ret = ffmpeg.AvCodecReceivePacket(encCtx, pkt)
|
||||
if ret == ffmpeg.AVERROR(int32(syscall.EAGAIN)) || ret == ffmpeg.AVERROR_EOF {
|
||||
if ret == ffmpeg.AVERROR(syscall.EAGAIN) || ret == ffmpeg.AVERROR_EOF {
|
||||
return
|
||||
} else if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error during encoding\n")
|
||||
|
@@ -19,22 +19,22 @@ const (
|
||||
FRAME_SIZE = 1024
|
||||
)
|
||||
|
||||
func initFilterGraph() (graph *ffmpeg.AvFilterGraph, src *ffmpeg.AvFilterContext, sink *ffmpeg.AvFilterContext, ret int32) {
|
||||
var filterGraph *ffmpeg.AvFilterGraph
|
||||
var abufferCtx *ffmpeg.AvFilterContext
|
||||
var abuffer *ffmpeg.AvFilter
|
||||
var volumeCtx *ffmpeg.AvFilterContext
|
||||
var volume *ffmpeg.AvFilter
|
||||
var aformatCtx *ffmpeg.AvFilterContext
|
||||
var aformat *ffmpeg.AvFilter
|
||||
var abuffersinkCtx *ffmpeg.AvFilterContext
|
||||
var abuffersink *ffmpeg.AvFilter
|
||||
var optionsDict *ffmpeg.AvDictionary
|
||||
func initFilterGraph() (graph *ffmpeg.AVFilterGraph, src *ffmpeg.AVFilterContext, sink *ffmpeg.AVFilterContext, ret int32) {
|
||||
var filterGraph *ffmpeg.AVFilterGraph
|
||||
var abufferCtx *ffmpeg.AVFilterContext
|
||||
var abuffer *ffmpeg.AVFilter
|
||||
var volumeCtx *ffmpeg.AVFilterContext
|
||||
var volume *ffmpeg.AVFilter
|
||||
var aformatCtx *ffmpeg.AVFilterContext
|
||||
var aformat *ffmpeg.AVFilter
|
||||
var abuffersinkCtx *ffmpeg.AVFilterContext
|
||||
var abuffersink *ffmpeg.AVFilter
|
||||
var optionsDict *ffmpeg.AVDictionary
|
||||
|
||||
// Create a new filtergraph, which will contain all the filters.
|
||||
if filterGraph = ffmpeg.AvFilterGraphAlloc(); filterGraph == nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to create filter graph.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, nil, nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
|
||||
// Create the abuffer filter;
|
||||
@@ -46,16 +46,16 @@ func initFilterGraph() (graph *ffmpeg.AvFilterGraph, src *ffmpeg.AvFilterContext
|
||||
|
||||
if abufferCtx = ffmpeg.AvFilterGraphAllocFilter(filterGraph, abuffer, "src"); abufferCtx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate the abuffer instance.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, nil, nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
|
||||
ffmpeg.AvOptSet(unsafe.Pointer(abufferCtx), "channel_layout",
|
||||
ffmpeg.AvOptSet(abufferCtx, "channel_layout",
|
||||
ffmpeg.AvGetChannelLayoutString(0, INPUT_CHANNEL_LAYOUT), ffmpeg.AV_OPT_SEARCH_CHILDREN)
|
||||
ffmpeg.AvOptSet(unsafe.Pointer(abufferCtx), "sample_fmt",
|
||||
ffmpeg.AvOptSet(abufferCtx, "sample_fmt",
|
||||
ffmpeg.AvGetSampleFmtName(INPUT_FORMAT), ffmpeg.AV_OPT_SEARCH_CHILDREN)
|
||||
ffmpeg.AvOptSetQ(unsafe.Pointer(abufferCtx), "time_base",
|
||||
ffmpeg.AvOptSetQ(abufferCtx, "time_base",
|
||||
ffmpeg.AvMakeQ(1, INPUT_SAMPLERATE), ffmpeg.AV_OPT_SEARCH_CHILDREN)
|
||||
ffmpeg.AvOptSetInt(unsafe.Pointer(abufferCtx), "sample_rate",
|
||||
ffmpeg.AvOptSetInt(abufferCtx, "sample_rate",
|
||||
INPUT_SAMPLERATE, ffmpeg.AV_OPT_SEARCH_CHILDREN)
|
||||
|
||||
// Now initialize the filter; we pass NULL options, since we have already set all the options above.
|
||||
@@ -72,7 +72,7 @@ func initFilterGraph() (graph *ffmpeg.AvFilterGraph, src *ffmpeg.AvFilterContext
|
||||
|
||||
if volumeCtx = ffmpeg.AvFilterGraphAllocFilter(filterGraph, volume, "volume"); volumeCtx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate the volume instance.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, nil, nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
|
||||
// A different way of passing the options is as key/value pairs in a
|
||||
@@ -94,7 +94,7 @@ func initFilterGraph() (graph *ffmpeg.AvFilterGraph, src *ffmpeg.AvFilterContext
|
||||
|
||||
if aformatCtx = ffmpeg.AvFilterGraphAllocFilter(filterGraph, aformat, "aformat"); aformatCtx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate the aformat instance.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, nil, nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
|
||||
// A third way of passing the options is in a string of the form
|
||||
@@ -115,7 +115,7 @@ func initFilterGraph() (graph *ffmpeg.AvFilterGraph, src *ffmpeg.AvFilterContext
|
||||
|
||||
if abuffersinkCtx = ffmpeg.AvFilterGraphAllocFilter(filterGraph, abuffersink, "sink"); abuffersinkCtx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate the abuffersink instance.\n")
|
||||
return nil, nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, nil, nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
|
||||
// This filter takes no options.
|
||||
@@ -126,12 +126,12 @@ func initFilterGraph() (graph *ffmpeg.AvFilterGraph, src *ffmpeg.AvFilterContext
|
||||
|
||||
// Connect the filters;
|
||||
// in this simple case the filters just form a linear chain.
|
||||
ret = ffmpeg.AvFilterLink2(abufferCtx, 0, volumeCtx, 0)
|
||||
ret = ffmpeg.AvFilterLink(abufferCtx, 0, volumeCtx, 0)
|
||||
if ret >= 0 {
|
||||
ret = ffmpeg.AvFilterLink2(volumeCtx, 0, aformatCtx, 0)
|
||||
ret = ffmpeg.AvFilterLink(volumeCtx, 0, aformatCtx, 0)
|
||||
}
|
||||
if ret >= 0 {
|
||||
ret = ffmpeg.AvFilterLink2(aformatCtx, 0, abuffersinkCtx, 0)
|
||||
ret = ffmpeg.AvFilterLink(aformatCtx, 0, abuffersinkCtx, 0)
|
||||
}
|
||||
if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error connecting filters\n")
|
||||
@@ -149,7 +149,7 @@ func initFilterGraph() (graph *ffmpeg.AvFilterGraph, src *ffmpeg.AvFilterContext
|
||||
|
||||
// Do something useful with the filtered data: this simple
|
||||
// example just prints the MD5 checksum of each plane to stdout.
|
||||
func processOutput(md5 *ffmpeg.AvMD5, frame *ffmpeg.AvFrame) int32 {
|
||||
func processOutput(md5 *ffmpeg.AVMD5, frame *ffmpeg.AVFrame) int32 {
|
||||
planar := ffmpeg.AvSampleFmtIsPlanar(frame.GetFormat())
|
||||
channels := ffmpeg.AvGetChannelLayoutNbChannels(frame.GetChannelLayout())
|
||||
planes := channels
|
||||
@@ -181,7 +181,7 @@ func processOutput(md5 *ffmpeg.AvMD5, frame *ffmpeg.AvFrame) int32 {
|
||||
|
||||
// Construct a frame of audio data to be filtered;
|
||||
// this simple example just synthesizes a sine wave.
|
||||
func getInput(frame *ffmpeg.AvFrame, frameNum int32) int32 {
|
||||
func getInput(frame *ffmpeg.AVFrame, frameNum int32) int32 {
|
||||
// Set up the frame properties and allocate the buffer for the data.
|
||||
frame.SetSampleRate(INPUT_SAMPLERATE)
|
||||
frame.SetFormat(INPUT_FORMAT)
|
||||
@@ -208,10 +208,10 @@ func getInput(frame *ffmpeg.AvFrame, frameNum int32) int32 {
|
||||
}
|
||||
|
||||
func main() {
|
||||
var md5 *ffmpeg.AvMD5
|
||||
var graph *ffmpeg.AvFilterGraph
|
||||
var src, sink *ffmpeg.AvFilterContext
|
||||
var frame *ffmpeg.AvFrame
|
||||
var md5 *ffmpeg.AVMD5
|
||||
var graph *ffmpeg.AVFilterGraph
|
||||
var src, sink *ffmpeg.AVFilterContext
|
||||
var frame *ffmpeg.AVFrame
|
||||
var ret int32
|
||||
|
||||
if len(os.Args) < 2 {
|
||||
@@ -272,7 +272,7 @@ func main() {
|
||||
ffmpeg.AvFrameUnref(frame)
|
||||
}
|
||||
|
||||
if ret == ffmpeg.AVERROR(int32(syscall.EAGAIN)) {
|
||||
if ret == ffmpeg.AVERROR(syscall.EAGAIN) {
|
||||
// Need to feed more frames in.
|
||||
continue
|
||||
} else if ret == ffmpeg.AVERROR_EOF {
|
||||
@@ -287,7 +287,7 @@ func main() {
|
||||
|
||||
ffmpeg.AvFilterGraphFree(&graph)
|
||||
ffmpeg.AvFrameFree(&frame)
|
||||
ffmpeg.AvFreep(unsafe.Pointer(&md5))
|
||||
ffmpeg.AvFreep(&md5)
|
||||
return
|
||||
|
||||
fail:
|
||||
|
@@ -1,5 +1,243 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static int hw_pix_fmt;
|
||||
|
||||
static inline int get_hw_pix_fmt()
|
||||
{
|
||||
return hw_pix_fmt;
|
||||
}
|
||||
|
||||
static inline void set_hw_pix_fmt(int fmt)
|
||||
{
|
||||
hw_pix_fmt = fmt;
|
||||
}
|
||||
|
||||
struct AVCodecContext;
|
||||
|
||||
int get_hw_format(struct AVCodecContext *ctx, const int *pix_fmts)
|
||||
{
|
||||
const int *p;
|
||||
|
||||
fprintf(stderr, "get_hw_format called.\n");
|
||||
for (p = pix_fmts; *p != -1; p++) {
|
||||
if (*p == hw_pix_fmt)
|
||||
return *p;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Failed to get HW surface format.\n");
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/qrtc/ffmpeg-dev-go"
|
||||
)
|
||||
|
||||
var (
|
||||
hwDeviceCtx *ffmpeg.AVBufferRef
|
||||
outputFile *os.File
|
||||
)
|
||||
|
||||
func hwDecoderInit(ctx *ffmpeg.AVCodecContext, hwType ffmpeg.AVHWDeviceType) (ret int32) {
|
||||
if ret := ffmpeg.AvHWDeviceCtxCreate(&hwDeviceCtx, hwType, "", nil, 0); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Failed to create specified HW device.\n")
|
||||
return ret
|
||||
}
|
||||
ctx.SetHwDeviceCtx(ffmpeg.AvBufferRef(hwDeviceCtx))
|
||||
return ret
|
||||
}
|
||||
|
||||
func decodeWrite(avctx *ffmpeg.AVCodecContext, packet *ffmpeg.AVPacket) (ret int32) {
|
||||
var frame, swFrame, tmpFrame *ffmpeg.AVFrame
|
||||
var buffer *uint8
|
||||
var size int32
|
||||
|
||||
if ret = ffmpeg.AvCodecSendPacket(avctx, packet); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error during decoding\n")
|
||||
return ret
|
||||
}
|
||||
|
||||
for {
|
||||
if frame = ffmpeg.AvFrameAlloc(); frame == nil {
|
||||
fmt.Fprintf(os.Stderr, "Can not alloc frame\n")
|
||||
goto fail
|
||||
}
|
||||
if swFrame = ffmpeg.AvFrameAlloc(); swFrame == nil {
|
||||
fmt.Fprintf(os.Stderr, "Can not alloc sw frame\n")
|
||||
goto fail
|
||||
}
|
||||
|
||||
ret = ffmpeg.AvCodecReceiveFrame(avctx, frame)
|
||||
if ret == ffmpeg.AVERROR(syscall.EAGAIN) || ret == ffmpeg.AVERROR_EOF {
|
||||
ffmpeg.AvFrameFree(&frame)
|
||||
ffmpeg.AvFrameFree(&swFrame)
|
||||
return 0
|
||||
} else if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error while decoding\n")
|
||||
goto fail
|
||||
}
|
||||
|
||||
if frame.GetFormat() == (int32)(C.get_hw_pix_fmt()) {
|
||||
// retrieve data from GPU to CPU
|
||||
if ret = ffmpeg.AvHWFrameTransferData(swFrame, frame, 0); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Error transferring the data to system memory\n")
|
||||
goto fail
|
||||
}
|
||||
tmpFrame = swFrame
|
||||
} else {
|
||||
tmpFrame = frame
|
||||
}
|
||||
|
||||
size = ffmpeg.AvImageGetBufferSize(tmpFrame.GetFormat(), tmpFrame.GetWidth(),
|
||||
tmpFrame.GetHeight(), 1)
|
||||
buffer = (*uint8)(ffmpeg.AvMalloc(size))
|
||||
if buffer == nil {
|
||||
fmt.Fprintf(os.Stderr, "Can not alloc buffer\n")
|
||||
ret = ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
goto fail
|
||||
}
|
||||
|
||||
ret = ffmpeg.AvImageCopyToBuffer(buffer, size, tmpFrame.GetData(),
|
||||
tmpFrame.GetLinesize(), tmpFrame.GetFormat(),
|
||||
tmpFrame.GetWidth(), tmpFrame.GetHeight(), 1)
|
||||
if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Can not copy image to buffer\n")
|
||||
goto fail
|
||||
}
|
||||
if _, err := outputFile.Write(unsafe.Slice(buffer, size)); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to dump raw data.\n")
|
||||
goto fail
|
||||
}
|
||||
fail:
|
||||
ffmpeg.AvFrameFree(&frame)
|
||||
ffmpeg.AvFrameFree(&swFrame)
|
||||
ffmpeg.AvFreep(&buffer)
|
||||
if ret < 0 {
|
||||
return ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var inputCtx *ffmpeg.AVFormatContext
|
||||
var videoStream, ret int32
|
||||
var video *ffmpeg.AVStream
|
||||
var decoderCtx *ffmpeg.AVCodecContext
|
||||
var decoder *ffmpeg.AVCodec
|
||||
var packet ffmpeg.AVPacket
|
||||
var hwType ffmpeg.AVHWDeviceType
|
||||
|
||||
if len(os.Args) < 4 {
|
||||
fmt.Fprintf(os.Stderr, "Usage: %s <device type> <input file> <output file>\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
hwType = ffmpeg.AvHWDeviceFindTypeByName(os.Args[1])
|
||||
if hwType == ffmpeg.AV_HWDEVICE_TYPE_NONE {
|
||||
fmt.Fprintf(os.Stderr, "Device type %s is not supported.\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, "Available device types:")
|
||||
for hwType = ffmpeg.AvHWDeviceIterateTypes(hwType); hwType != ffmpeg.AV_HWDEVICE_TYPE_NONE; {
|
||||
fmt.Fprintf(os.Stderr, " %s", ffmpeg.AvHWDeviceGetTypeName(hwType))
|
||||
hwType = ffmpeg.AvHWDeviceIterateTypes(hwType)
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// open the input file
|
||||
if ret = ffmpeg.AvFormatOpenInput(&inputCtx, os.Args[2], nil, nil); ret != 0 {
|
||||
fmt.Fprintf(os.Stderr, "Cannot open input file '%s'\n", os.Args[2])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if ret = ffmpeg.AvFormatFindStreamInfo(inputCtx, nil); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Cannot find input stream information.\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// find the video stream information
|
||||
ret = ffmpeg.AvFindBestStream(inputCtx, ffmpeg.AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0)
|
||||
if ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Cannot find a video stream in the input file\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
videoStream = ret
|
||||
|
||||
for i := 0; ; i++ {
|
||||
config := ffmpeg.AvCodecGetHwConfig(decoder, i)
|
||||
if config == nil {
|
||||
fmt.Fprintf(os.Stderr, "Decoder %s does not support device type %s.\n",
|
||||
decoder.GetName(), ffmpeg.AvHWDeviceGetTypeName(hwType))
|
||||
os.Exit(1)
|
||||
}
|
||||
if (config.GetMethods()&ffmpeg.AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) != 0 &&
|
||||
config.GetDeviceType() == hwType {
|
||||
fmt.Fprintf(os.Stdout, "Support set_hw_pix_fmt. \n")
|
||||
C.set_hw_pix_fmt((C.int)(config.GetPixFmt()))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if decoderCtx = ffmpeg.AvCodecAllocContext3(decoder); decoderCtx == nil {
|
||||
os.Exit(int(ffmpeg.AVERROR(syscall.ENOMEM)))
|
||||
}
|
||||
|
||||
video = inputCtx.GetStreamsIdx(int(videoStream))
|
||||
if ret = ffmpeg.AvCodecParametersToContext(decoderCtx, video.GetCodecpar()); ret < 0 {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
decoderCtx.SetGetFormat((ffmpeg.AVCodecContextGetFormatFunc)(C.get_hw_format))
|
||||
|
||||
if ret = hwDecoderInit(decoderCtx, hwType); ret < 0 {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if ret = ffmpeg.AvCodecOpen2(decoderCtx, decoder, nil); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Failed to open codec for stream #%d\n", videoStream)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// open the file to dump raw data
|
||||
outputFile, _ = os.OpenFile(os.Args[3], os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
|
||||
// actual decoding and dump the raw data
|
||||
for ret >= 0 {
|
||||
if ret = ffmpeg.AvReadFrame(inputCtx, &packet); ret < 0 {
|
||||
break
|
||||
}
|
||||
if videoStream == packet.GetStreamIndex() {
|
||||
ret = decodeWrite(decoderCtx, &packet)
|
||||
}
|
||||
|
||||
ffmpeg.AvPacketUnref(&packet)
|
||||
}
|
||||
|
||||
// flush the decoder
|
||||
packet.SetData(nil)
|
||||
packet.SetSize(0)
|
||||
ret = decodeWrite(decoderCtx, &packet)
|
||||
ffmpeg.AvPacketUnref(&packet)
|
||||
|
||||
if outputFile != nil {
|
||||
outputFile.Close()
|
||||
}
|
||||
ffmpeg.AvCodecFreeContext(&decoderCtx)
|
||||
ffmpeg.AvFormatCloseInput(&inputCtx)
|
||||
ffmpeg.AvBufferUnref(&hwDeviceCtx)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Fprintf(os.Stderr, "(error '%s')\n", ffmpeg.AvErr2str(ret))
|
||||
}
|
||||
os.Exit(int(ret))
|
||||
}
|
||||
|
@@ -72,7 +72,7 @@ func main() {
|
||||
"fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
|
||||
ffmpeg.AvGetPixFmtName(srcPixFmt), srcW, srcH,
|
||||
ffmpeg.AvGetPixFmtName(dstPixFmt), dstW, dstH)
|
||||
ret = ffmpeg.AVERROR(int32(syscall.EINVAL))
|
||||
ret = ffmpeg.AVERROR(syscall.EINVAL)
|
||||
goto end
|
||||
}
|
||||
|
||||
@@ -106,8 +106,8 @@ func main() {
|
||||
|
||||
end:
|
||||
dstFile.Close()
|
||||
ffmpeg.AvFreep(unsafe.Pointer(&srcData[0]))
|
||||
ffmpeg.AvFreep(unsafe.Pointer(&dstData[0]))
|
||||
ffmpeg.AvFreep(&srcData[0])
|
||||
ffmpeg.AvFreep(&dstData[0])
|
||||
ffmpeg.SwsFreeContext(swsCtx)
|
||||
if ret < 0 {
|
||||
os.Exit(1)
|
||||
|
@@ -15,8 +15,8 @@ const (
|
||||
)
|
||||
|
||||
// Open an input file and the required decoder.
|
||||
func openInputFile(fileName string) (inputFormatContext *ffmpeg.AvFormatContext,
|
||||
inputCodecContext *ffmpeg.AvCodecContext, ret int32) {
|
||||
func openInputFile(fileName string) (inputFormatContext *ffmpeg.AVFormatContext,
|
||||
inputCodecContext *ffmpeg.AVCodecContext, ret int32) {
|
||||
|
||||
// Open the input file to read from it.
|
||||
if ret = ffmpeg.AvFormatOpenInput(&inputFormatContext, fileName, nil, nil); ret < 0 {
|
||||
@@ -51,7 +51,7 @@ func openInputFile(fileName string) (inputFormatContext *ffmpeg.AvFormatContext,
|
||||
if avctx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate a decoding context\n")
|
||||
ffmpeg.AvFormatCloseInput(&inputFormatContext)
|
||||
return nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
|
||||
// Initialize the stream parameters with demuxer information.
|
||||
@@ -76,13 +76,13 @@ func openInputFile(fileName string) (inputFormatContext *ffmpeg.AvFormatContext,
|
||||
}
|
||||
|
||||
// Open an output file and the required encoder.
|
||||
func openOutputFile(filename string, inputCodecContext *ffmpeg.AvCodecContext) (outputFormatContext *ffmpeg.AvFormatContext,
|
||||
outputCodecContext *ffmpeg.AvCodecContext, ret int32) {
|
||||
func openOutputFile(filename string, inputCodecContext *ffmpeg.AVCodecContext) (outputFormatContext *ffmpeg.AVFormatContext,
|
||||
outputCodecContext *ffmpeg.AVCodecContext, ret int32) {
|
||||
|
||||
var outputIOContext *ffmpeg.AvIOContext
|
||||
var outputCodec *ffmpeg.AvCodec
|
||||
var stream *ffmpeg.AvStream
|
||||
var avctx *ffmpeg.AvCodecContext
|
||||
var outputIOContext *ffmpeg.AVIOContext
|
||||
var outputCodec *ffmpeg.AVCodec
|
||||
var stream *ffmpeg.AVStream
|
||||
var avctx *ffmpeg.AVCodecContext
|
||||
|
||||
// Open the output file to write to it.
|
||||
if ret = ffmpeg.AvIOOpen(&outputIOContext, filename, ffmpeg.AVIO_FLAG_WRITE); ret < 0 {
|
||||
@@ -93,7 +93,7 @@ func openOutputFile(filename string, inputCodecContext *ffmpeg.AvCodecContext) (
|
||||
// Create a new format context for the output container format.
|
||||
if outputFormatContext = ffmpeg.AvFormatAllocContext(); outputFormatContext == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate output format context\n")
|
||||
return nil, nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
|
||||
// Associate the output file (pointer) with the container format context.
|
||||
@@ -109,7 +109,7 @@ func openOutputFile(filename string, inputCodecContext *ffmpeg.AvCodecContext) (
|
||||
outputFormatContext.SetUrl(filename)
|
||||
if len(outputFormatContext.GetUrl()) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate url.\n")
|
||||
ret = ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
ret = ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
goto cleanup
|
||||
}
|
||||
|
||||
@@ -122,13 +122,13 @@ func openOutputFile(filename string, inputCodecContext *ffmpeg.AvCodecContext) (
|
||||
// Create a new audio stream in the output file container.
|
||||
if stream = ffmpeg.AvFormatNewStream(outputFormatContext, nil); stream == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not create new stream\n")
|
||||
ret = ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
ret = ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
goto cleanup
|
||||
}
|
||||
|
||||
if avctx = ffmpeg.AvCodecAllocContext3(outputCodec); avctx == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate an encoding context\n")
|
||||
ret = ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
ret = ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
goto cleanup
|
||||
}
|
||||
|
||||
@@ -179,19 +179,19 @@ cleanup:
|
||||
}
|
||||
|
||||
// Initialize one data packet for reading or writing.
|
||||
func initPacket() (packet *ffmpeg.AvPacket, ret int32) {
|
||||
func initPacket() (packet *ffmpeg.AVPacket, ret int32) {
|
||||
if packet = ffmpeg.AvPacketAlloc(); packet == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate packet\n")
|
||||
return nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
return packet, 0
|
||||
}
|
||||
|
||||
// Initialize one audio frame for reading from the input file.
|
||||
func initInputFrame() (frame *ffmpeg.AvFrame, ret int32) {
|
||||
func initInputFrame() (frame *ffmpeg.AVFrame, ret int32) {
|
||||
if frame = ffmpeg.AvFrameAlloc(); frame == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate input frame\n")
|
||||
return nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
return frame, 0
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func initInputFrame() (frame *ffmpeg.AvFrame, ret int32) {
|
||||
// Initialize the audio resampler based on the input and output codec settings.
|
||||
// If the input and output sample formats differ, a conversion is required
|
||||
// libswresample takes care of this, but requires initialization.
|
||||
func initResampler(inputCodecContext, outputCodecContext *ffmpeg.AvCodecContext) (
|
||||
func initResampler(inputCodecContext, outputCodecContext *ffmpeg.AVCodecContext) (
|
||||
resampleContext *ffmpeg.SwrContext, ret int32) {
|
||||
|
||||
// Create a resampler context for the conversion.
|
||||
@@ -216,7 +216,7 @@ func initResampler(inputCodecContext, outputCodecContext *ffmpeg.AvCodecContext)
|
||||
inputCodecContext.GetSampleRate(),
|
||||
0, nil); resampleContext == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate resample context\n")
|
||||
return nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
|
||||
if outputCodecContext.GetSampleRate() != inputCodecContext.GetSampleRate() {
|
||||
@@ -233,18 +233,18 @@ func initResampler(inputCodecContext, outputCodecContext *ffmpeg.AvCodecContext)
|
||||
}
|
||||
|
||||
// Initialize a FIFO buffer for the audio samples to be encoded.
|
||||
func initFifo(outputCodecContext *ffmpeg.AvCodecContext) (fifo *ffmpeg.AvAudioFifo, ret int32) {
|
||||
func initFifo(outputCodecContext *ffmpeg.AVCodecContext) (fifo *ffmpeg.AVAudioFifo, ret int32) {
|
||||
// Create the FIFO buffer based on the specified output sample format
|
||||
if fifo = ffmpeg.AvAudioFifoAlloc(outputCodecContext.GetSampleFmt(),
|
||||
outputCodecContext.GetChannels(), 1); fifo == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate FIFO\n")
|
||||
return nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
return fifo, 0
|
||||
}
|
||||
|
||||
// Write the header of the output file container.
|
||||
func writeOutputFileHeader(outputFormatContext *ffmpeg.AvFormatContext) int32 {
|
||||
func writeOutputFileHeader(outputFormatContext *ffmpeg.AVFormatContext) int32 {
|
||||
if ret := ffmpeg.AvFormatWriteHeader(outputFormatContext, nil); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Could not write output file header (error '%s')\n", ffmpeg.AvErr2str(ret))
|
||||
return ret
|
||||
@@ -253,9 +253,9 @@ func writeOutputFileHeader(outputFormatContext *ffmpeg.AvFormatContext) int32 {
|
||||
}
|
||||
|
||||
// Decode one audio frame from the input file.
|
||||
func decodeAudioFrame(frame *ffmpeg.AvFrame,
|
||||
inputFormatContext *ffmpeg.AvFormatContext,
|
||||
inputCodecContext *ffmpeg.AvCodecContext) (dataPresent, finished, ret int32) {
|
||||
func decodeAudioFrame(frame *ffmpeg.AVFrame,
|
||||
inputFormatContext *ffmpeg.AVFormatContext,
|
||||
inputCodecContext *ffmpeg.AVCodecContext) (dataPresent, finished, ret int32) {
|
||||
// Packet used for temporary storage.
|
||||
inputPacket, ret := initPacket()
|
||||
if ret < 0 {
|
||||
@@ -285,7 +285,7 @@ func decodeAudioFrame(frame *ffmpeg.AvFrame,
|
||||
switch {
|
||||
// If the decoder asks for more data to be able to decode a frame,
|
||||
// return indicating that no data is present.
|
||||
case ret == ffmpeg.AVERROR(int32(syscall.EAGAIN)):
|
||||
case ret == ffmpeg.AVERROR(syscall.EAGAIN):
|
||||
ret = 0
|
||||
goto cleanup
|
||||
// If the end of the input file is reached, stop decoding.
|
||||
@@ -310,16 +310,16 @@ cleanup:
|
||||
// Initialize a temporary storage for the specified number of audio samples.
|
||||
// The conversion requires temporary storage due to the different format.
|
||||
// The number of audio samples to be allocated is specified in frame_size.
|
||||
func initConvertedSamples(outputCodecContext *ffmpeg.AvCodecContext,
|
||||
func initConvertedSamples(outputCodecContext *ffmpeg.AVCodecContext,
|
||||
frameSize int32) (convertedInputSamples **uint8, ret int32) {
|
||||
|
||||
// Allocate as many pointers as there are audio channels.
|
||||
// Each pointer will later point to the audio samples of the corresponding
|
||||
// channels (although it may be NULL for interleaved formats).
|
||||
if convertedInputSamples = (**uint8)(ffmpeg.AvCalloc(uint(outputCodecContext.GetChannels()),
|
||||
uint(unsafe.Sizeof(*convertedInputSamples)))); convertedInputSamples == nil {
|
||||
if convertedInputSamples = (**uint8)(ffmpeg.AvCalloc(outputCodecContext.GetChannels(),
|
||||
unsafe.Sizeof(*convertedInputSamples))); convertedInputSamples == nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate converted input sample pointers\n")
|
||||
return nil, ffmpeg.AVERROR(int32(syscall.ENOMEM))
|
||||
return nil, ffmpeg.AVERROR(syscall.ENOMEM)
|
||||
}
|
||||
|
||||
// Allocate memory for the samples of all channels in one consecutive
|
||||
@@ -329,7 +329,7 @@ func initConvertedSamples(outputCodecContext *ffmpeg.AvCodecContext,
|
||||
frameSize,
|
||||
outputCodecContext.GetSampleFmt(), 0); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Could not allocate converted input samples (error '%s')\n", ffmpeg.AvErr2str(ret))
|
||||
ffmpeg.AvFreep(unsafe.Pointer(&convertedInputSamples))
|
||||
ffmpeg.AvFreep(&convertedInputSamples)
|
||||
return nil, ret
|
||||
}
|
||||
return convertedInputSamples, 0
|
||||
@@ -340,9 +340,7 @@ func initConvertedSamples(outputCodecContext *ffmpeg.AvCodecContext,
|
||||
// specified by frame_size.
|
||||
func convertSamples(inputData, convertedData **uint8,
|
||||
frameSize int32, resampleContext *ffmpeg.SwrContext) (ret int32) {
|
||||
if ret = ffmpeg.SwrConvert(resampleContext,
|
||||
convertedData, frameSize,
|
||||
inputData, frameSize); ret < 0 {
|
||||
if ret = ffmpeg.SwrConvert(resampleContext, convertedData, frameSize, inputData, frameSize); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Could not convert input samples (error '%s')\n", ffmpeg.AvErr2str(ret))
|
||||
return ret
|
||||
}
|
||||
@@ -350,7 +348,7 @@ func convertSamples(inputData, convertedData **uint8,
|
||||
}
|
||||
|
||||
// Add converted input audio samples to the FIFO buffer for later processing.
|
||||
func addSamplesToFifo(fifo *ffmpeg.AvAudioFifo, convertedInputSamples **uint8, frameSize int32) int32 {
|
||||
func addSamplesToFifo(fifo *ffmpeg.AVAudioFifo, convertedInputSamples **uint8, frameSize int32) int32 {
|
||||
// Make the FIFO as large as it needs to be to hold both,
|
||||
// the old and the new samples.
|
||||
if ret := ffmpeg.AvAudioFifoRealloc(fifo, ffmpeg.AvAudioFifoSize(fifo)+frameSize); ret < 0 {
|
||||
@@ -359,8 +357,7 @@ func addSamplesToFifo(fifo *ffmpeg.AvAudioFifo, convertedInputSamples **uint8, f
|
||||
}
|
||||
|
||||
// Store the new samples in the FIFO buffer.
|
||||
if ret := ffmpeg.AvAudioFifoWrite(fifo, (*unsafe.Pointer)(unsafe.Pointer(convertedInputSamples)),
|
||||
frameSize); ret < frameSize {
|
||||
if ret := ffmpeg.AvAudioFifoWrite(fifo, convertedInputSamples, frameSize); ret < frameSize {
|
||||
fmt.Fprintf(os.Stderr, "Could not write data to FIFO\n")
|
||||
return ffmpeg.AVERROR_EXIT
|
||||
}
|
||||
@@ -368,14 +365,14 @@ func addSamplesToFifo(fifo *ffmpeg.AvAudioFifo, convertedInputSamples **uint8, f
|
||||
}
|
||||
|
||||
// Read one audio frame from the input file, decode, convert and store it in the FIFO buffer.
|
||||
func readDecodeConvertAndStore(fifo *ffmpeg.AvAudioFifo,
|
||||
inputFormatContext *ffmpeg.AvFormatContext,
|
||||
inputCodecContext *ffmpeg.AvCodecContext,
|
||||
outputCodecContext *ffmpeg.AvCodecContext,
|
||||
func readDecodeConvertAndStore(fifo *ffmpeg.AVAudioFifo,
|
||||
inputFormatContext *ffmpeg.AVFormatContext,
|
||||
inputCodecContext *ffmpeg.AVCodecContext,
|
||||
outputCodecContext *ffmpeg.AVCodecContext,
|
||||
resamplerContext *ffmpeg.SwrContext) (finished, ret int32) {
|
||||
|
||||
// Temporary storage of the input samples of the frame read from the file.
|
||||
var inputFrame *ffmpeg.AvFrame
|
||||
var inputFrame *ffmpeg.AVFrame
|
||||
// Temporary storage for the converted input samples.
|
||||
var convertedInputSamples **uint8
|
||||
var dataPresent int32
|
||||
@@ -423,7 +420,7 @@ func readDecodeConvertAndStore(fifo *ffmpeg.AvAudioFifo,
|
||||
|
||||
cleanup:
|
||||
if convertedInputSamples != nil {
|
||||
ffmpeg.AvFreep(unsafe.Pointer(&convertedInputSamples))
|
||||
ffmpeg.AvFreep(&convertedInputSamples)
|
||||
}
|
||||
ffmpeg.AvFrameFree(&inputFrame)
|
||||
|
||||
@@ -431,8 +428,8 @@ cleanup:
|
||||
}
|
||||
|
||||
// Initialize one input frame for writing to the output file.
|
||||
func initOutputFrame(outputcodecContext *ffmpeg.AvCodecContext,
|
||||
frameSize int32) (frame *ffmpeg.AvFrame, ret int32) {
|
||||
func initOutputFrame(outputcodecContext *ffmpeg.AVCodecContext,
|
||||
frameSize int32) (frame *ffmpeg.AVFrame, ret int32) {
|
||||
|
||||
// Create a new frame to store the audio samples.
|
||||
if frame = ffmpeg.AvFrameAlloc(); frame == nil {
|
||||
@@ -465,11 +462,11 @@ func initOutputFrame(outputcodecContext *ffmpeg.AvCodecContext,
|
||||
var pts int64
|
||||
|
||||
// Encode one frame worth of audio to the output file.
|
||||
func encodeAudioFrame(frame *ffmpeg.AvFrame,
|
||||
outputFormatContext *ffmpeg.AvFormatContext,
|
||||
outputCodecContext *ffmpeg.AvCodecContext) (dataPresent, ret int32) {
|
||||
func encodeAudioFrame(frame *ffmpeg.AVFrame,
|
||||
outputFormatContext *ffmpeg.AVFormatContext,
|
||||
outputCodecContext *ffmpeg.AVCodecContext) (dataPresent, ret int32) {
|
||||
// Packet used for temporary storage.
|
||||
var outputPacket *ffmpeg.AvPacket
|
||||
var outputPacket *ffmpeg.AVPacket
|
||||
|
||||
if outputPacket, ret = initPacket(); ret < 0 {
|
||||
return dataPresent, ret
|
||||
@@ -496,7 +493,7 @@ func encodeAudioFrame(frame *ffmpeg.AvFrame,
|
||||
ret = ffmpeg.AvCodecReceivePacket(outputCodecContext, outputPacket)
|
||||
// If the encoder asks for more data to be able to provide an
|
||||
// encoded frame, return indicating that no data is present.
|
||||
if ret == ffmpeg.AVERROR(int32(syscall.EAGAIN)) {
|
||||
if ret == ffmpeg.AVERROR(syscall.EAGAIN) {
|
||||
ret = 0
|
||||
goto cleanup
|
||||
} else if ret == ffmpeg.AVERROR_EOF {
|
||||
@@ -525,11 +522,11 @@ cleanup:
|
||||
}
|
||||
|
||||
// Load one audio frame from the FIFO buffer, encode and write it to the output file.
|
||||
func loadEncodeAndWrite(fifo *ffmpeg.AvAudioFifo,
|
||||
outputFormatContext *ffmpeg.AvFormatContext,
|
||||
outputCodecContext *ffmpeg.AvCodecContext) (ret int32) {
|
||||
func loadEncodeAndWrite(fifo *ffmpeg.AVAudioFifo,
|
||||
outputFormatContext *ffmpeg.AVFormatContext,
|
||||
outputCodecContext *ffmpeg.AVCodecContext) (ret int32) {
|
||||
// Temporary storage of the output samples of the frame written to the file.
|
||||
var outputFrame *ffmpeg.AvFrame
|
||||
var outputFrame *ffmpeg.AVFrame
|
||||
// Use the maximum number of possible samples per frame.
|
||||
// If there is less than the maximum possible frame size in the FIFO
|
||||
// buffer use this number. Otherwise, use the maximum possible frame size.
|
||||
@@ -542,8 +539,7 @@ func loadEncodeAndWrite(fifo *ffmpeg.AvAudioFifo,
|
||||
|
||||
// Read as many samples from the FIFO buffer as required to fill the frame.
|
||||
// The samples are stored in the frame temporarily.
|
||||
if ret = ffmpeg.AvAudioFifoRead(fifo,
|
||||
(*unsafe.Pointer)(unsafe.Pointer(outputFrame.GetData())), frameSize); ret < frameSize {
|
||||
if ret = ffmpeg.AvAudioFifoRead(fifo, outputFrame.GetData(), frameSize); ret < frameSize {
|
||||
fmt.Fprintf(os.Stderr, "Could not read data from FIFO\n")
|
||||
ffmpeg.AvFrameFree(&outputFrame)
|
||||
return ffmpeg.AVERROR_EXIT
|
||||
@@ -560,7 +556,7 @@ func loadEncodeAndWrite(fifo *ffmpeg.AvAudioFifo,
|
||||
}
|
||||
|
||||
// Write the trailer of the output file container.
|
||||
func writeOutputFileTrailer(outputFormatContext *ffmpeg.AvFormatContext) int32 {
|
||||
func writeOutputFileTrailer(outputFormatContext *ffmpeg.AVFormatContext) int32 {
|
||||
if ret := ffmpeg.AvWriteTrailer(outputFormatContext); ret < 0 {
|
||||
fmt.Fprintf(os.Stderr, "Could not write output file trailer (error '%s')\n", ffmpeg.AvErr2str(ret))
|
||||
return ret
|
||||
@@ -570,12 +566,12 @@ func writeOutputFileTrailer(outputFormatContext *ffmpeg.AvFormatContext) int32 {
|
||||
|
||||
func main() {
|
||||
var ret int32 = ffmpeg.AVERROR_EXIT
|
||||
var inputFormatContext *ffmpeg.AvFormatContext
|
||||
var inputCodecContext *ffmpeg.AvCodecContext
|
||||
var outputFormatContext *ffmpeg.AvFormatContext
|
||||
var outputCodecContext *ffmpeg.AvCodecContext
|
||||
var inputFormatContext *ffmpeg.AVFormatContext
|
||||
var inputCodecContext *ffmpeg.AVCodecContext
|
||||
var outputFormatContext *ffmpeg.AVFormatContext
|
||||
var outputCodecContext *ffmpeg.AVCodecContext
|
||||
var resampleContext *ffmpeg.SwrContext
|
||||
var fifo *ffmpeg.AvAudioFifo
|
||||
var fifo *ffmpeg.AVAudioFifo
|
||||
|
||||
if len(os.Args) != 3 {
|
||||
fmt.Fprintf(os.Stdout, "Usage: %s <input file> <output file>\n", os.Args[0])
|
||||
|
Reference in New Issue
Block a user