2023-10-22 11:46:19 CST W43D0

This commit is contained in:
aggresss
2023-10-22 11:46:19 +08:00
parent 0f95831c39
commit e163918619
62 changed files with 2326 additions and 355 deletions

View File

@@ -1,5 +1,113 @@
package main
func main() {
import (
"fmt"
"os"
ffmpeg "github.com/qrtc/ffmpeg-dev-go"
)
func typeString(_type int32) string {
switch _type {
case ffmpeg.AVIO_ENTRY_DIRECTORY:
return "<DIR>"
case ffmpeg.AVIO_ENTRY_FILE:
return "<FILE>"
case ffmpeg.AVIO_ENTRY_BLOCK_DEVICE:
return "<BLOCK DEVICE>"
case ffmpeg.AVIO_ENTRY_CHARACTER_DEVICE:
return "<CHARACTER DEVICE>"
case ffmpeg.AVIO_ENTRY_NAMED_PIPE:
return "<PIPE>"
case ffmpeg.AVIO_ENTRY_SYMBOLIC_LINK:
return "<LINK>"
case ffmpeg.AVIO_ENTRY_SOCKET:
return "<SOCKET>"
case ffmpeg.AVIO_ENTRY_SERVER:
return "<SERVER>"
case ffmpeg.AVIO_ENTRY_SHARE:
return "<SHARE>"
case ffmpeg.AVIO_ENTRY_WORKGROUP:
return "<WORKGROUP>"
case ffmpeg.AVIO_ENTRY_UNKNOWN:
default:
break
}
return "<UNKNOWN>"
}
func listOp(inputDir string) int32 {
var entry *ffmpeg.AVIODirEntry
var ctx *ffmpeg.AVIODirContext
var cnt, ret int32
var filemode, uidAndGid string
if ret = ffmpeg.AvIOOpenDir(&ctx, inputDir, nil); ret < 0 {
ffmpeg.AvLog(nil, ffmpeg.AV_LOG_ERROR, "Cannot open directory: %s.\n", ffmpeg.AvErr2str(ret))
goto fail
}
for {
if ret = ffmpeg.AvIOReadDir(ctx, &entry); ret < 0 {
ffmpeg.AvLog(nil, ffmpeg.AV_LOG_ERROR, "Cannot list directory: %s.\n", ffmpeg.AvErr2str(ret))
goto fail
}
if entry == nil {
break
}
if entry.GetFilemode() == -1 {
filemode = "???"
} else {
filemode = fmt.Sprintf("%3d", entry.GetFilemode())
}
uidAndGid = fmt.Sprintf("%d(%d)", entry.GetUserId(), entry.GetGroupId())
if cnt == 0 {
ffmpeg.AvLog(nil, ffmpeg.AV_LOG_INFO, "%-9s %12s %30s %10s %s %16s %16s %16s\n",
"TYPE", "SIZE", "NAME", "UID(GID)", "UGO", "MODIFIED",
"ACCESSED", "STATUS_CHANGED")
}
ffmpeg.AvLog(nil, ffmpeg.AV_LOG_INFO, "%-9s %12d %30s %10s %s %d %d %d\n",
typeString(entry.GetType()),
entry.GetSize(),
entry.GetName(),
uidAndGid,
filemode,
entry.GetModificationTimestamp(),
entry.GetAccessTimestamp(),
entry.GetStatusChangeTimestamp())
ffmpeg.AvIOFreeDirectoryEntry(&entry)
cnt++
}
fail:
ffmpeg.AvIOCloseDir(&ctx)
return ret
}
func usage(programName string) {
fmt.Fprintf(os.Stderr, "usage: %s input_dir\n"+
"API example program to show how to list files in directory "+
"accessed through AVIOContext.\n", programName)
os.Exit(1)
}
func main() {
var ret int32
ffmpeg.AvLogSetLevel(ffmpeg.AV_LOG_DEBUG)
if len(os.Args) < 2 {
usage(os.Args[0])
os.Exit(1)
}
ffmpeg.AvFormatNetworkInit()
ret = listOp(os.Args[1])
ffmpeg.AvFormatNetworkDeinit()
if ret < 0 {
os.Exit(1)
}
}

View File

@@ -1,5 +1,118 @@
package main
func main() {
/*
#include <stdlib.h>
int readPacket(void* opaque, uint8_t *buf, int bufSize);
*/
import "C"
import (
"fmt"
"os"
"runtime/cgo"
"syscall"
"unsafe"
ffmpeg "github.com/qrtc/ffmpeg-dev-go"
)
type bufferData struct {
ptr *uint8
size uintptr
}
//export readPacket
func readPacket(opaque unsafe.Pointer, buf *uint8, bufSize int32) int32 {
bd := (*(*cgo.Handle)(opaque)).Value().(*bufferData)
bufSize = ffmpeg.FFMIN(bufSize, int32(bd.size))
if bufSize == 0 {
return ffmpeg.AVERROR_EOF
}
fmt.Fprintf(os.Stdout, "ptr:%p size:%d\n", bd.ptr, bd.size)
// copy internal buffer data to buf
bd.ptr = ffmpeg.PointerOffset(bd.ptr, bufSize)
bd.size -= uintptr(bufSize)
return bufSize
}
func main() {
var fmtCtx *ffmpeg.AVFormatContext
var avioCtx *ffmpeg.AVIOContext
var buffer, avioCtxBuffer *uint8
var bufferSize uintptr
var avioCtxBufferSize uint = 4096
var ret int32
var bd bufferData
var opaqueHandle cgo.Handle
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "usage: %s input_file\n"+
"API example program to show how to read from a custom buffer "+
"accessed through AVIOContext.\n", os.Args[0])
os.Exit(1)
}
inputFilename := os.Args[1]
// slurp file content into buffer
if ret = ffmpeg.AvFileMap(inputFilename, &buffer, &bufferSize, 0, nil); ret < 0 {
goto end
}
// fill opaque structure used by the AVIOContext read callback
bd.ptr = buffer
bd.size = bufferSize
if fmtCtx = ffmpeg.AvFormatAllocContext(); fmtCtx == nil {
ret = ffmpeg.AVERROR(syscall.ENOMEM)
goto end
}
if avioCtxBuffer = (*uint8)(ffmpeg.AvMalloc(avioCtxBufferSize)); avioCtxBuffer == nil {
ret = ffmpeg.AVERROR(syscall.ENOMEM)
goto end
}
opaqueHandle = cgo.NewHandle(&bd)
if avioCtx = ffmpeg.AvIOAllocContext(avioCtxBuffer, int32(avioCtxBufferSize), 0,
&opaqueHandle, (ffmpeg.AVIOContextReadPacketFunc)(C.readPacket), nil, nil); avioCtx == nil {
ret = ffmpeg.AVERROR(syscall.ENOMEM)
goto end
}
fmtCtx.SetPb(avioCtx)
if ret = ffmpeg.AvFormatOpenInput(&fmtCtx, ffmpeg.NIL, nil, nil); ret < 0 {
fmt.Fprintf(os.Stderr, "Could not open input\n")
goto end
}
if ret = ffmpeg.AvFormatFindStreamInfo(fmtCtx, nil); ret < 0 {
fmt.Fprintf(os.Stderr, "Could not find stream information\n")
goto end
}
ffmpeg.AvDumpFormat(fmtCtx, 0, inputFilename, 0)
end:
ffmpeg.AvFormatCloseInput(&fmtCtx)
if opaqueHandle != 0 {
opaqueHandle.Delete()
}
// note: the internal buffer could have changed, and be != avio_ctx_buffer
if avioCtx != nil {
ffmpeg.AvFreep(avioCtx.GetBufferAddr())
}
ffmpeg.AvIOContextFree(&avioCtx)
ffmpeg.AvFileUnmap(buffer, bufferSize)
if ret < 0 {
fmt.Fprintf(os.Stderr, "Error occurred: %s\n", ffmpeg.AvErr2str(ret))
os.Exit(1)
}
}

View File

@@ -34,7 +34,7 @@ func getFormatFromSampleFmt(sampleFmt ffmpeg.AVSampleFormat) (string, int32) {
fmt.Fprintf(os.Stderr, "sample format %s is not supported as output format\n",
ffmpeg.AvGetSampleFmtName(sampleFmt))
return "", -1
return ffmpeg.NIL, -1
}
func decode(decCtx *ffmpeg.AVCodecContext, pkt *ffmpeg.AVPacket, frame *ffmpeg.AVFrame, outfile *os.File) {
@@ -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.ByteSliceWithOffset(frame.GetDataIdx(ch), dataSize*i, dataSize))
outfile.Write(ffmpeg.ByteSliceWithOffset(frame.GetData()[ch], dataSize*i, dataSize))
}
}
}

View File

@@ -42,7 +42,7 @@ func decode(decCtx *ffmpeg.AVCodecContext, frame *ffmpeg.AVFrame, pkt *ffmpeg.AV
// the picture is allocated by the decoder. no need to free it
fname := fmt.Sprintf("%s-%d", filename, decCtx.GetFrameNumber())
pgmSave(frame.GetDataIdx(0), frame.GetLinesizeIdx(0), frame.GetWidth(), frame.GetHeight(), fname)
pgmSave(frame.GetData()[0], frame.GetLinesize()[0], frame.GetWidth(), frame.GetHeight(), fname)
}
}

View File

@@ -159,7 +159,7 @@ func main() {
if ret := ffmpeg.AvFrameMakeWritable(frame); ret < 0 {
os.Exit(1)
}
samples := unsafe.Slice((*uint16)(unsafe.Pointer(frame.GetDataIdx(0))), 2*avctx.GetFrameSize()+avctx.GetChannels())
samples := unsafe.Slice((*uint16)(unsafe.Pointer(frame.GetData()[0])), avctx.GetFrameSize()*avctx.GetChannels())
for j := 0; j < int(avctx.GetFrameSize()); j++ {
samples[2*j] = (uint16)(math.Sin(t) * 10000)

View File

@@ -120,20 +120,20 @@ func main() {
}
// prepare a dummy image
data0 := unsafe.Slice(frame.GetDataIdx(0), avctx.GetHeight()*frame.GetLinesizeIdx(0)+avctx.GetWidth())
data1 := unsafe.Slice(frame.GetDataIdx(1), (avctx.GetHeight()/2)*frame.GetLinesizeIdx(1)+(avctx.GetWidth()/2))
data2 := unsafe.Slice(frame.GetDataIdx(2), (avctx.GetHeight()/2)*frame.GetLinesizeIdx(2)+(avctx.GetWidth()/2))
data0 := unsafe.Slice(frame.GetData()[0], avctx.GetHeight()*frame.GetLinesize()[0])
data1 := unsafe.Slice(frame.GetData()[1], (avctx.GetHeight()/2)*frame.GetLinesize()[1])
data2 := unsafe.Slice(frame.GetData()[2], (avctx.GetHeight()/2)*frame.GetLinesize()[2])
// Y
for y := 0; y < int(avctx.GetHeight()); y++ {
for x := 0; x < int(avctx.GetWidth()); x++ {
data0[y*int(frame.GetLinesizeIdx(0))+x] = uint8(x + y + i*3)
data0[y*int(frame.GetLinesize()[0])+x] = uint8(x + y + i*3)
}
}
// Cb and Cr
for y := 0; y < int(avctx.GetHeight()/2); y++ {
for x := 0; x < int(avctx.GetWidth()/2); x++ {
data1[y*int(frame.GetLinesizeIdx(1))+x] = uint8(128 + y + i*2)
data2[y*int(frame.GetLinesizeIdx(2))+x] = uint8(64 + x + i*5)
data1[y*int(frame.GetLinesize()[1])+x] = uint8(128 + y + i*2)
data2[y*int(frame.GetLinesize()[2])+x] = uint8(64 + x + i*5)
}
}

View File

@@ -1,5 +1,9 @@
package main
// filter-audio 0.05
// plane 0: 0x3A1E227C0C1A0DA59EAA91C35653125C
// plane 0: 0xA7922B09261B407E49C545A68B671572
import (
"fmt"
"math"

View File

@@ -22,7 +22,7 @@ int get_hw_format(struct AVCodecContext *ctx, const int *pix_fmts)
{
const int *p;
fprintf(stderr, "get_hw_format called.\n");
fprintf(stderr, "get_hw_format ballback has been invoked.\n");
for (p = pix_fmts; *p != -1; p++) {
if (*p == hw_pix_fmt)
return *p;
@@ -44,20 +44,20 @@ import (
)
var (
hwDeviceCtx *ffmpeg.AVBufferRef
outputFile *os.File
// Note: Gobal variable as argument pass to C world may be cause panic.
// `runtime error: cgo argument has Go pointer to unpinned Go pointer`
)
func hwDecoderInit(ctx *ffmpeg.AVCodecContext, hwType ffmpeg.AVHWDeviceType) (ret int32) {
if ret := ffmpeg.AvHWDeviceCtxCreate(&hwDeviceCtx, hwType, "", nil, 0); ret < 0 {
func hwDecoderInit(ctx *ffmpeg.AVCodecContext, hwType ffmpeg.AVHWDeviceType) (hwDeviceCtx *ffmpeg.AVBufferRef, ret int32) {
if ret := ffmpeg.AvHWDeviceCtxCreate(&hwDeviceCtx, hwType, ffmpeg.NIL, nil, 0); ret < 0 {
fmt.Fprintf(os.Stderr, "Failed to create specified HW device.\n")
return ret
return nil, ret
}
ctx.SetHwDeviceCtx(ffmpeg.AvBufferRef(hwDeviceCtx))
return ret
return hwDeviceCtx, ret
}
func decodeWrite(avctx *ffmpeg.AVCodecContext, packet *ffmpeg.AVPacket) (ret int32) {
func decodeWrite(avctx *ffmpeg.AVCodecContext, packet *ffmpeg.AVPacket, outputFile *os.File) (ret int32) {
var frame, swFrame, tmpFrame *ffmpeg.AVFrame
var buffer *uint8
var size int32
@@ -129,6 +129,8 @@ func decodeWrite(avctx *ffmpeg.AVCodecContext, packet *ffmpeg.AVPacket) (ret int
}
func main() {
var outputFile *os.File
var hwDeviceCtx *ffmpeg.AVBufferRef
var inputCtx *ffmpeg.AVFormatContext
var videoStream, ret int32
var video *ffmpeg.AVStream
@@ -182,7 +184,6 @@ func main() {
}
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
}
@@ -192,14 +193,14 @@ func main() {
os.Exit(int(ffmpeg.AVERROR(syscall.ENOMEM)))
}
video = inputCtx.GetStreamsIdx(int(videoStream))
video = inputCtx.GetStreams()[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 {
if hwDeviceCtx, ret = hwDecoderInit(decoderCtx, hwType); ret < 0 {
os.Exit(1)
}
@@ -217,7 +218,7 @@ func main() {
break
}
if videoStream == packet.GetStreamIndex() {
ret = decodeWrite(decoderCtx, &packet)
ret = decodeWrite(decoderCtx, &packet, outputFile)
}
ffmpeg.AvPacketUnref(&packet)
@@ -226,7 +227,7 @@ func main() {
// flush the decoder
packet.SetData(nil)
packet.SetSize(0)
ret = decodeWrite(decoderCtx, &packet)
ret = decodeWrite(decoderCtx, &packet, outputFile)
ffmpeg.AvPacketUnref(&packet)
if outputFile != nil {

View File

@@ -1,5 +1,40 @@
package main
func main() {
import (
"fmt"
"os"
ffmpeg "github.com/qrtc/ffmpeg-dev-go"
)
func main() {
var fmtCtx *ffmpeg.AVFormatContext
var tag *ffmpeg.AVDictionaryEntry
var ret int32
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "usage: %s <input_file>\n"+
"example program to demonstrate the use of the libavformat metadata API.\n"+
"\n", os.Args[0])
os.Exit(1)
}
if ret = ffmpeg.AvFormatOpenInput(&fmtCtx, os.Args[1], nil, nil); ret != 0 {
os.Exit(int(ret))
}
if ret = ffmpeg.AvFormatFindStreamInfo(fmtCtx, nil); ret < 0 {
ffmpeg.AvLog(nil, ffmpeg.AV_LOG_ERROR, "Cannot find stream information\n")
os.Exit(int(ret))
}
for {
if tag = ffmpeg.AvDictGet(fmtCtx.GetMetadata(), "", tag, ffmpeg.AV_DICT_IGNORE_SUFFIX); tag == nil {
break
}
fmt.Fprintf(os.Stdout, "%s=%s\n", tag.GetKey(), tag.GetValue())
}
ffmpeg.AvFormatCloseInput(&fmtCtx)
os.Exit(0)
}

View File

@@ -11,7 +11,7 @@ import (
func fillYuvImage(data [4]*uint8, linesize [4]int32, width, height, frameIndex int32) {
// Y
data0 := unsafe.Slice(data[0], height*linesize[0]+width)
data0 := unsafe.Slice(data[0], height*linesize[0])
for y := int32(0); y < height; y++ {
for x := int32(0); x < width; x++ {
data0[y*linesize[0]+x] = (uint8)(x + y + frameIndex*3)

View File

@@ -100,7 +100,7 @@ func openOutputFile(filename string, inputCodecContext *ffmpeg.AVCodecContext) (
outputFormatContext.SetPb(outputIOContext)
// Guess the desired container format based on the file extension.
outputFormatContext.SetOformat(ffmpeg.AvGuessFormat("", filename, ""))
outputFormatContext.SetOformat(ffmpeg.AvGuessFormat(ffmpeg.NIL, filename, ffmpeg.NIL))
if outputFormatContext.GetOformat() == nil {
fmt.Fprintf(os.Stderr, "Could not find output file format\n")
goto cleanup