2023-10-19 14:31:46 CST W42D4

This commit is contained in:
aggresss
2023-10-19 14:31:46 +08:00
parent 762aa14362
commit 0f95831c39
52 changed files with 9140 additions and 4324 deletions

View File

@@ -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])

View File

@@ -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")

View File

@@ -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)
}

View File

@@ -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")

View File

@@ -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:

View File

@@ -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))
}

View File

@@ -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)

View File

@@ -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])