refactor: FFmpeg 7.1 support (#101)
* feat: FFmpeg 7.1 * test: reset golden * fix encoder * test: update golden files
This commit is contained in:
parent
1b26cf82f8
commit
d01256b982
35 changed files with 73 additions and 65 deletions
19
.github/workflows/test.yml
vendored
19
.github/workflows/test.yml
vendored
|
|
@ -13,17 +13,17 @@ jobs:
|
|||
env:
|
||||
CGO_CFLAGS_ALLOW: -Xpreprocessor
|
||||
VIPS_VERSION: 8.17.1
|
||||
FFMPEG_VERSION: 5.1.2
|
||||
V: 4
|
||||
FFMPEG_VERSION: 7.1.1
|
||||
V: 5
|
||||
|
||||
steps:
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: ^1.24
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install linux dependencies
|
||||
run: |
|
||||
|
|
@ -38,7 +38,7 @@ jobs:
|
|||
libopenslide-dev libcfitsio-dev liborc-0.4-dev libpango1.0-dev \
|
||||
libtiff5-dev libgsf-1-dev giflib-tools libwebp-dev \
|
||||
yasm libx264-dev libx265-dev libnuma-dev libvpx-dev libtheora-dev \
|
||||
librtmp-dev libvorbis-dev \
|
||||
librtmp-dev libvorbis-dev libdav1d-dev libaom-dev \
|
||||
libopenjp2-7-dev libcgif-dev
|
||||
# Install newer libheif from backports
|
||||
sudo apt-get install -y -t jammy-backports libheif-dev || sudo apt-get install -y libheif-dev
|
||||
|
|
@ -78,13 +78,12 @@ jobs:
|
|||
restore-keys: |
|
||||
${{ runner.os }}-ffmpeg-${{ env.V }}-
|
||||
|
||||
|
||||
- name: Build ffmpeg from source
|
||||
run: |
|
||||
if [ ! -d "ffmpeg-${{ env.FFMPEG_VERSION }}" ]
|
||||
then
|
||||
wget https://ffmpeg.org/releases/ffmpeg-${{ env.FFMPEG_VERSION }}.tar.bz2
|
||||
tar jvxf ffmpeg-${{ env.FFMPEG_VERSION }}.tar.bz2
|
||||
wget https://ffmpeg.org/releases/ffmpeg-${{ env.FFMPEG_VERSION }}.tar.xz
|
||||
tar xf ffmpeg-${{ env.FFMPEG_VERSION }}.tar.xz
|
||||
fi
|
||||
cd ffmpeg-${{ env.FFMPEG_VERSION }}
|
||||
./configure --prefix=/usr/local \
|
||||
|
|
@ -101,7 +100,9 @@ jobs:
|
|||
--enable-libwebp \
|
||||
--enable-libvpx \
|
||||
--enable-libx265 \
|
||||
--enable-libx264
|
||||
--enable-libx264 \
|
||||
--enable-libdav1d \
|
||||
--enable-libaom
|
||||
make && sudo make install
|
||||
sudo ldconfig
|
||||
|
||||
|
|
|
|||
15
Dockerfile
15
Dockerfile
|
|
@ -1,14 +1,13 @@
|
|||
ARG GOLANG_VERSION=1.24.5
|
||||
FROM golang:${GOLANG_VERSION}-bookworm as builder
|
||||
|
||||
ARG FFMPEG_VERSION=5.1.2
|
||||
ARG FFMPEG_VERSION=7.1.1
|
||||
ARG VIPS_VERSION=8.17.1
|
||||
ARG TARGETARCH
|
||||
|
||||
ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
|
||||
ENV MAKEFLAGS="-j8"
|
||||
|
||||
|
||||
# Installs libvips + required libraries
|
||||
RUN DEBIAN_FRONTEND=noninteractive \
|
||||
apt-get update && \
|
||||
|
|
@ -21,7 +20,7 @@ RUN DEBIAN_FRONTEND=noninteractive \
|
|||
swig libpango1.0-dev libmatio-dev libopenslide-dev libcfitsio-dev libopenjp2-7-dev \
|
||||
libgsf-1-dev libfftw3-dev liborc-0.4-dev librsvg2-dev libimagequant-dev libaom-dev libheif-dev \
|
||||
yasm libx264-dev libx265-dev libnuma-dev libvpx-dev libtheora-dev \
|
||||
libspng-dev libcgif-dev librtmp-dev libvorbis-dev && \
|
||||
libspng-dev libcgif-dev librtmp-dev libvorbis-dev libdav1d-dev && \
|
||||
cd /tmp && \
|
||||
curl -fsSLO https://github.com/libvips/libvips/releases/download/v${VIPS_VERSION}/vips-${VIPS_VERSION}.tar.xz && \
|
||||
tar xf vips-${VIPS_VERSION}.tar.xz && \
|
||||
|
|
@ -36,8 +35,8 @@ RUN DEBIAN_FRONTEND=noninteractive \
|
|||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd /tmp && \
|
||||
curl -fsSLO https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2 && \
|
||||
tar jvxf ffmpeg-${FFMPEG_VERSION}.tar.bz2 && \
|
||||
curl -fsSLO https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.xz && \
|
||||
tar xf ffmpeg-${FFMPEG_VERSION}.tar.xz && \
|
||||
cd /tmp/ffmpeg-${FFMPEG_VERSION} && \
|
||||
./configure --prefix=/usr/local \
|
||||
--disable-debug \
|
||||
|
|
@ -53,7 +52,9 @@ RUN DEBIAN_FRONTEND=noninteractive \
|
|||
--enable-libwebp \
|
||||
--enable-libvpx \
|
||||
--enable-libx265 \
|
||||
--enable-libx264 && \
|
||||
--enable-libx264 \
|
||||
--enable-libdav1d \
|
||||
--enable-libaom && \
|
||||
make && make install && \
|
||||
ldconfig && \
|
||||
rm -rf /usr/local/lib/python* && \
|
||||
|
|
@ -89,7 +90,7 @@ RUN echo "deb http://deb.debian.org/debian bookworm-backports main" > /etc/apt/s
|
|||
libpango1.0-0 libmatio11 libopenslide0 libopenjp2-7 libjemalloc2 \
|
||||
libgsf-1-114 libfftw3-bin liborc-0.4-0 librsvg2-2 libcfitsio10 libimagequant0 libaom3 \
|
||||
libx264-dev libx265-dev libnuma-dev libvpx7 libtheora0 libvorbis-dev \
|
||||
libspng0 libcgif0 && \
|
||||
libspng0 libcgif0 libdav1d6 && \
|
||||
apt-get install --no-install-recommends -y -t bookworm-backports libheif1 && \
|
||||
ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so && \
|
||||
apt-get autoremove -y && \
|
||||
|
|
|
|||
|
|
@ -210,23 +210,28 @@ AVFrame *convert_frame_to_rgb(AVFrame *frame, int alpha) {
|
|||
return output_frame;
|
||||
}
|
||||
|
||||
AVPacket create_packet() {
|
||||
AVPacket *create_packet() {
|
||||
AVPacket *pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
return NULL;
|
||||
}
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
return *pkt;
|
||||
return pkt;
|
||||
}
|
||||
|
||||
int
|
||||
obtain_next_frame(AVFormatContext *fmt_ctx, AVCodecContext *dec_ctx, int stream_index, AVPacket *pkt, AVFrame **frame) {
|
||||
int obtain_next_frame(AVFormatContext *fmt_ctx, AVCodecContext *dec_ctx, int stream_index, AVPacket *pkt, AVFrame **frame) {
|
||||
int err = 0, retry = 0;
|
||||
if (!(*frame) && !(*frame = av_frame_alloc())) {
|
||||
err = AVERROR(ENOMEM);
|
||||
return err;
|
||||
}
|
||||
|
||||
// Try to receive a frame from the decoder first
|
||||
if ((err = avcodec_receive_frame(dec_ctx, *frame)) != AVERROR(EAGAIN)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if ((err = av_read_frame(fmt_ctx, pkt)) < 0) {
|
||||
break;
|
||||
|
|
@ -239,6 +244,7 @@ obtain_next_frame(AVFormatContext *fmt_ctx, AVCodecContext *dec_ctx, int stream_
|
|||
if (retry++ >= 10) {
|
||||
break;
|
||||
}
|
||||
av_packet_unref(pkt);
|
||||
continue;
|
||||
}
|
||||
if (!(*frame) && !(*frame = av_frame_alloc())) {
|
||||
|
|
@ -251,7 +257,7 @@ obtain_next_frame(AVFormatContext *fmt_ctx, AVCodecContext *dec_ctx, int stream_
|
|||
}
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
if (pkt->buf) {
|
||||
if (pkt->data) {
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -301,8 +301,13 @@ func populateFrames(av *AVContext, frames <-chan *C.AVFrame) <-chan struct{} {
|
|||
|
||||
func createThumbContext(av *AVContext, maxFrames C.int) error {
|
||||
pkt := C.create_packet()
|
||||
if pkt == nil {
|
||||
return avError(C.int(ErrNoMem))
|
||||
}
|
||||
defer C.av_packet_free(&pkt)
|
||||
|
||||
var frame *C.AVFrame
|
||||
err := C.obtain_next_frame(av.formatContext, av.codecContext, av.stream.index, &pkt, &frame)
|
||||
err := C.obtain_next_frame(av.formatContext, av.codecContext, av.stream.index, pkt, &frame)
|
||||
if err >= 0 {
|
||||
incrementDuration(av, frame, 0)
|
||||
av.thumbContext = C.create_thumb_context(av.stream, frame)
|
||||
|
|
@ -311,9 +316,6 @@ func createThumbContext(av *AVContext, maxFrames C.int) error {
|
|||
}
|
||||
}
|
||||
if err < 0 {
|
||||
if pkt.buf != nil {
|
||||
C.av_packet_unref(&pkt)
|
||||
}
|
||||
if frame != nil {
|
||||
C.av_frame_free(&frame)
|
||||
}
|
||||
|
|
@ -332,18 +334,20 @@ func createThumbContext(av *AVContext, maxFrames C.int) error {
|
|||
frames := make(chan *C.AVFrame, n)
|
||||
done := populateFrames(av, frames)
|
||||
frames <- frame
|
||||
if pkt.buf != nil {
|
||||
C.av_packet_unref(&pkt)
|
||||
}
|
||||
return populateThumbContext(av, frames, n, done)
|
||||
}
|
||||
|
||||
func populateThumbContext(av *AVContext, frames chan *C.AVFrame, n C.int, done <-chan struct{}) error {
|
||||
pkt := C.create_packet()
|
||||
if pkt == nil {
|
||||
return avError(C.int(ErrNoMem))
|
||||
}
|
||||
defer C.av_packet_free(&pkt)
|
||||
|
||||
var frame *C.AVFrame
|
||||
var err C.int
|
||||
for i := C.int(1); i < n; i++ {
|
||||
err = C.obtain_next_frame(av.formatContext, av.codecContext, av.stream.index, &pkt, &frame)
|
||||
err = C.obtain_next_frame(av.formatContext, av.codecContext, av.stream.index, pkt, &frame)
|
||||
if err < 0 {
|
||||
break
|
||||
}
|
||||
|
|
@ -362,9 +366,6 @@ func populateThumbContext(av *AVContext, frames chan *C.AVFrame, n C.int, done <
|
|||
av.selectedIndex = av.availableIndex
|
||||
}
|
||||
close(frames)
|
||||
if pkt.buf != nil {
|
||||
C.av_packet_unref(&pkt)
|
||||
}
|
||||
if frame != nil {
|
||||
C.av_frame_free(&frame)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,10 +47,9 @@ int create_codec_context(AVStream *video_stream, AVCodecContext **dec_ctx);
|
|||
|
||||
AVFrame *convert_frame_to_rgb(AVFrame *frame, int alpha);
|
||||
|
||||
AVPacket create_packet();
|
||||
AVPacket *create_packet();
|
||||
|
||||
int
|
||||
obtain_next_frame(AVFormatContext *fmt_ctx, AVCodecContext *dec_ctx, int stream_index, AVPacket *pkt, AVFrame **frame);
|
||||
int obtain_next_frame(AVFormatContext *fmt_ctx, AVCodecContext *dec_ctx, int stream_index, AVPacket *pkt, AVFrame **frame);
|
||||
|
||||
ThumbContext *create_thumb_context(AVStream *stream, AVFrame *frame);
|
||||
|
||||
|
|
|
|||
2
testdata/golden/meta/macabre.mp4-1.meta.json
vendored
2
testdata/golden/meta/macabre.mp4-1.meta.json
vendored
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":3925,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":3924,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":3925,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":3924,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
2
testdata/golden/meta/macabre.mp4-5.meta.json
vendored
2
testdata/golden/meta/macabre.mp4-5.meta.json
vendored
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":3925,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":3924,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":3925,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":3924,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":3925,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":3924,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
2
testdata/golden/meta/macabre.mp4.meta.json
vendored
2
testdata/golden/meta/macabre.mp4.meta.json
vendored
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":3925,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":3924,"width":492,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
2
testdata/golden/meta/schizo_0.mp4.meta.json
vendored
2
testdata/golden/meta/schizo_0.mp4.meta.json
vendored
|
|
@ -1 +1 @@
|
|||
{"orientation":1,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":1,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":3,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":3,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":3,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":3,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":3,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":3,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":3,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":3,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":3,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":3,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":3,"duration":2544,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":3,"duration":2535,"width":480,"height":360,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":6,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":6,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":6,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":6,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":6,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":6,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":6,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":6,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":6,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":6,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":6,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":6,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":8,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":8,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":8,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":8,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":8,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":8,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":8,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":8,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
|
|
@ -1 +1 @@
|
|||
{"orientation":8,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":8,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
2
testdata/golden/meta/schizo_90.mp4.meta.json
vendored
2
testdata/golden/meta/schizo_90.mp4.meta.json
vendored
|
|
@ -1 +1 @@
|
|||
{"orientation":8,"duration":2544,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
{"orientation":8,"duration":2535,"width":360,"height":480,"fps":29.97002997002997,"has_video":true,"has_audio":true}
|
||||
Loading…
Add table
Add a link
Reference in a new issue