Skip to content

Commit

Permalink
add 10/12bit encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
tuffr5 committed Apr 27, 2023
1 parent 0a9f168 commit 30d3a52
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 80 deletions.
33 changes: 25 additions & 8 deletions scripts/compile_ffmpeg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,27 @@ cd $HOME/ffmpeg_sources && \
wget -O x265.tar.bz2 https://bitbucket.org/multicoreware/x265_git/get/master.tar.bz2 && \
tar xjvf x265.tar.bz2 && \
cd multicoreware*/build/linux && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED=off ../../source && \
mkdir -p 8bit 10bit 12bit && \
cd 12bit && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DHIGH_BIT_DEPTH=ON -DEXPORT_C_API=OFF -DENABLE_SHARED=OFF -DENABLE_CLI=OFF -DMAIN12=ON ../../../source && \
PATH="$HOME/bin:$PATH" make -j$(nproc) && \
cd ../10bit && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DHIGH_BIT_DEPTH=ON -DEXPORT_C_API=OFF -DENABLE_SHARED=OFF -DENABLE_CLI=OFF ../../../source && \
PATH="$HOME/bin:$PATH" make -j$(nproc) && \
cd ../8bit && \
ln -sf ../10bit/libx265.a libx265_main10.a && \
ln -sf ../12bit/libx265.a libx265_main12.a && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DEXTRA_LIB="x265_main10.a;x265_main12.a" -DEXTRA_LINK_FLAGS=-L. -DLINKED_10BIT=ON -DLINKED_12BIT=ON ../../../source && \
PATH="$HOME/bin:$PATH" make -j$(nproc) && \
mv libx265.a libx265_main.a && \
ar -M <<EOF
CREATE libx265.a
ADDLIB libx265_main.a
ADDLIB libx265_main10.a
ADDLIB libx265_main12.a
SAVE
END
EOF
make install
}

Expand Down Expand Up @@ -101,7 +120,7 @@ cd $HOME/ffmpeg_sources && \
git -C SVT-AV1 pull 2> /dev/null || git clone https://gitlab.com/AOMediaCodec/SVT-AV1.git && \
mkdir -p SVT-AV1/build && \
cd SVT-AV1/build && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DCMAKE_BUILD_TYPE=Release -DBUILD_DEC=OFF -DBUILD_SHARED_LIBS=OFF .. && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DCMAKE_BUILD_TYPE=Release -DBUILD_DEC=OFF -DENABLE_AVX512=ON -DBUILD_SHARED_LIBS=OFF .. && \
PATH="$HOME/bin:$PATH" make -j$(nproc) && \
make install
}
Expand Down Expand Up @@ -146,7 +165,7 @@ ninja install
compileNVCodec(){
echo "Compling nv-codec-headers"
cd $HOME/ffmpeg_sources && \
# git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git && \
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git && \
cd nv-codec-headers && \
make -j$(nproc) && \
make install PREFIX="$HOME/ffmpeg_build"
Expand Down Expand Up @@ -189,8 +208,6 @@ make install && \
hash -r
}

# If got x265 not found by pkg-config error,
# delete the x265_config.h in ffmpeg_build/include.

#######################################################################################
# NOTE FOR NVCC ERROR WHILE COMPILING FFMPEG #
Expand All @@ -210,11 +227,11 @@ setupCondaEnv
# installYasm
compileLibX264
compileLibX265
compileLibVpx
compileLibaom
# compileLibVpx
# compileLibaom
compileLibsvtav1
compilelibrav1e
compileLibdav1d
compileNVCodec
# compileNVCodec
compileFfmpeg
echo "Complete!"
61 changes: 0 additions & 61 deletions scripts/recompile_and_run_example.sh

This file was deleted.

91 changes: 80 additions & 11 deletions src/ffmpeg_h5filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
#include <libavutil/log.h>

#include "ffmpeg_h5filter.h"

Expand Down Expand Up @@ -609,7 +610,7 @@ size_t ffmpeg_h5_filter(unsigned flags, size_t cd_nelmts, const unsigned int cd_
AVFrame *src_frame = NULL, *dst_frame = NULL;
AVPacket *pkt;
struct SwsContext *sws_context = NULL;
// int thread_count = 1; // single thread
// int thread_count = 16; // single thread

char *codec_name, *preset, *tune;
enum EncoderCodecEnum c_id;
Expand Down Expand Up @@ -640,6 +641,9 @@ size_t ffmpeg_h5_filter(unsigned flags, size_t cd_nelmts, const unsigned int cd_
film_grain = cd_values[9]; // for svt-av1 particularly
gpu_id = cd_values[10]; // for nvenc only

// av_log_set_level(AV_LOG_ERROR);
av_log_set_level(AV_LOG_INFO);

codec_name = calloc(1, 50);
find_encoder_name(c_id, codec_name);

Expand Down Expand Up @@ -702,11 +706,40 @@ size_t ffmpeg_h5_filter(unsigned flags, size_t cd_nelmts, const unsigned int cd_
c->width = width;
c->height = height;

if (strstr(codec_name, "nvenc") || strstr(codec_name, "qsv"))
// use this pix_fmt for hardware accelerated encoding
c->pix_fmt = AV_PIX_FMT_NV12;
else
switch (c_id)
{
// list those who support 10bit encoding (actually using 16bit)
case FFH5_ENC_X264:
case FFH5_ENC_SVTAV1:
case FFH5_ENC_RAV1E:
c->pix_fmt = (color_mode == 0) ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10;
break;
case FFH5_ENC_X265:
switch (color_mode)
{
case 0: //8bit
c->pix_fmt = AV_PIX_FMT_YUV420P;
break;
case 1: //10bit
c->pix_fmt = AV_PIX_FMT_YUV420P10;
break;
case 2: //12bit
c->pix_fmt = AV_PIX_FMT_YUV420P12;
break;
default:
c->pix_fmt = AV_PIX_FMT_YUV420P;
}
break;
// We have to use NV12
case FFH5_ENC_H264_NV:
case FFH5_ENC_HEVC_NV:
case FFH5_ENC_AV1_NV:
c->pix_fmt = (color_mode == 0) ? AV_PIX_FMT_NV12 : AV_PIX_FMT_P010;
break;
default:
// common supported pixel format 8bit (actually using 16bit)
c->pix_fmt = AV_PIX_FMT_YUV420P;
}

/* frames per second */
c->time_base = (AVRational){1, 25};
Expand Down Expand Up @@ -773,6 +806,10 @@ size_t ffmpeg_h5_filter(unsigned flags, size_t cd_nelmts, const unsigned int cd_
stpcpy(tune, "film-grain=");
strcat(tune, film_grain_buffer);
}
strcat(tune, ":enable-tf=0");
if (color_mode == 1)
strcat(tune, ":enable-hdr=1");

av_opt_set(c->priv_data, "svtav1-params", tune, 0);
if (crf < 64)
av_opt_set_int(c->priv_data, "crf", crf, 0);
Expand Down Expand Up @@ -831,7 +868,7 @@ size_t ffmpeg_h5_filter(unsigned flags, size_t cd_nelmts, const unsigned int cd_
return 0;
}

src_frame->format = (color_mode == 0) ? AV_PIX_FMT_GRAY8 : AV_PIX_FMT_RGB24;
src_frame->format = (color_mode == 0) ? AV_PIX_FMT_GRAY8 : AV_PIX_FMT_GRAY10;
src_frame->width = c->width;
src_frame->height = c->height;

Expand All @@ -843,7 +880,7 @@ size_t ffmpeg_h5_filter(unsigned flags, size_t cd_nelmts, const unsigned int cd_

p_data = (uint8_t *)*buf;

frame_size = (color_mode == 0) ? width * height : width * height * 3;
frame_size = (color_mode == 0) ? width * height : width * height * 2;
expected_size = frame_size * depth / EXPECTED_CS_RATIO;
out_data = calloc(1, expected_size);

Expand Down Expand Up @@ -890,6 +927,7 @@ size_t ffmpeg_h5_filter(unsigned flags, size_t cd_nelmts, const unsigned int cd_
}

dst_frame->pts = i;
dst_frame->quality = c->global_quality;

/* encode the frame */
encode(c, dst_frame, pkt, &out_size, &out_data, &expected_size);
Expand Down Expand Up @@ -1040,8 +1078,39 @@ size_t ffmpeg_h5_filter(unsigned flags, size_t cd_nelmts, const unsigned int cd_
fprintf(stderr, "Could not allocate video frame due to out of memory problem\n");
return 0;
}

src_frame->format = (strstr(codec_name, "cuvid")) ? AV_PIX_FMT_NV12 : AV_PIX_FMT_YUV420P;
switch (c_id)
{
// list those who support 10bit encoding
case FFH5_DEC_H264:
case FFH5_DEC_AOMAV1:
case FFH5_DEC_DAV1D:
src_frame->format = (color_mode == 0) ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10;
break;
case FFH5_DEC_HEVC:
switch (color_mode)
{
case 0: //8bit
src_frame->format = AV_PIX_FMT_YUV420P;
break;
case 1: //10bit
src_frame->format = AV_PIX_FMT_YUV420P10;
break;
case 2: //12bit
src_frame->format = AV_PIX_FMT_YUV420P12;
break;
default:
src_frame->format = AV_PIX_FMT_YUV420P;
}
break;
case FFH5_DEC_H264_CUVID:
case FFH5_DEC_HEVC_CUVID:
case FFH5_DEC_AV1_CUVID:
src_frame->format = (color_mode == 0) ? AV_PIX_FMT_NV12 : AV_PIX_FMT_P010;
break;
default:
// common supported pixel format 8bit
src_frame->format = AV_PIX_FMT_YUV420P;
}
src_frame->width = c->width;
src_frame->height = c->height;

Expand All @@ -1052,14 +1121,14 @@ size_t ffmpeg_h5_filter(unsigned flags, size_t cd_nelmts, const unsigned int cd_
return 0;
}

dst_frame->format = (color_mode == 1) ? AV_PIX_FMT_RGB24 : AV_PIX_FMT_GRAY8;
dst_frame->format = (color_mode == 0) ? AV_PIX_FMT_GRAY8 : AV_PIX_FMT_GRAY10;
dst_frame->width = c->width;
dst_frame->height = c->height;

p_data = (uint8_t *)*buf;
p_data_size = *buf_size;

frame_size = (color_mode == 0) ? width * height : width * height * 3;
frame_size = (color_mode == 0) ? width * height : width * height * 2;
out_data = calloc(1, frame_size * depth + AV_INPUT_BUFFER_PADDING_SIZE);

if (out_data == NULL)
Expand Down

0 comments on commit 30d3a52

Please sign in to comment.