29# include <libavcodec/avcodec.h>
30# include <libavdevice/avdevice.h>
31# include <libavformat/avformat.h>
32# include <libavutil/log.h>
37static char ffmpeg_last_error_buffer[1024];
41# pragma GCC diagnostic push
42# pragma GCC diagnostic ignored "-Wmissing-format-attribute"
45static size_t ffmpeg_log_to_buffer(
char *buffer,
46 const size_t buffer_size,
53 va_copy(args_cpy, arg);
60static void ffmpeg_log_callback(
void * ,
int level,
const char *
format, va_list arg)
86 static std::mutex
mutex;
89 if (
ELEM(level, AV_LOG_PANIC, AV_LOG_FATAL, AV_LOG_ERROR)) {
90 const size_t n = ffmpeg_log_to_buffer(
91 ffmpeg_last_error_buffer,
sizeof(ffmpeg_last_error_buffer),
format, arg);
93 ffmpeg_last_error_buffer[n - 1] =
'\0';
100 static char buffer[1024];
101 static int buffer_used = 0;
103 buffer_used += ffmpeg_log_to_buffer(
104 buffer + buffer_used,
sizeof(buffer) - buffer_used,
format, arg);
106 if (buffer_used >=
sizeof(buffer) || (buffer_used > 0 && buffer[buffer_used - 1] ==
'\n')) {
107 if (buffer[buffer_used - 1] ==
'\n') {
108 buffer[buffer_used - 1] =
'\0';
117# pragma GCC diagnostic pop
120const char *ffmpeg_last_error()
122 return ffmpeg_last_error_buffer;
125static int isffmpeg(
const char *filepath)
127 AVFormatContext *pFormatCtx =
nullptr;
130 const AVCodec *pCodec;
150 if (avformat_open_input(&pFormatCtx, filepath,
nullptr,
nullptr) != 0) {
154 if (avformat_find_stream_info(pFormatCtx,
nullptr) < 0) {
155 avformat_close_input(&pFormatCtx);
161 for (
i = 0;
i < pFormatCtx->nb_streams;
i++) {
162 if (pFormatCtx->streams[
i] && pFormatCtx->streams[
i]->codecpar &&
163 (pFormatCtx->streams[
i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO))
170 if (videoStream == -1) {
171 avformat_close_input(&pFormatCtx);
175 AVCodecParameters *codec_par = pFormatCtx->streams[videoStream]->codecpar;
178 pCodec = avcodec_find_decoder(codec_par->codec_id);
179 if (pCodec ==
nullptr) {
180 avformat_close_input(&pFormatCtx);
184 avformat_close_input(&pFormatCtx);
192# define MAX_NEG_CROP 1024
194# define times4(x) x, x, x, x
195# define times256(x) times4(times4(times4(times4(times4(x)))))
197static const uint8_t ff_compat_crop_tab[256 + 2 * MAX_NEG_CROP] = {
198 times256(0x00), 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
199 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
200 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
201 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
202 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
203 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
204 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
205 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
206 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
207 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
208 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82,
209 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
210 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
211 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
212 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2,
213 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
214 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
215 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
216 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2,
217 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE,
218 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
219 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, times256(0xFF)};
226 const uint8_t *lum_m4,
227 const uint8_t *lum_m3,
228 const uint8_t *lum_m2,
229 const uint8_t *lum_m1,
233 const uint8_t *cm = ff_compat_crop_tab + MAX_NEG_CROP;
238 sum += lum_m3[0] << 2;
239 sum += lum_m2[0] << 1;
240 sum += lum_m1[0] << 2;
242 dst[0] = cm[(
sum + 4) >> 3];
253 uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
int size)
255 const uint8_t *cm = ff_compat_crop_tab + MAX_NEG_CROP;
260 sum += lum_m3[0] << 2;
261 sum += lum_m2[0] << 1;
262 lum_m4[0] = lum_m2[0];
263 sum += lum_m1[0] << 2;
265 lum_m2[0] = cm[(
sum + 4) >> 3];
279 uint8_t *dst,
int dst_wrap,
const uint8_t *src1,
int src_wrap,
int width,
int height)
281 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
286 src_0 = &src_m1[src_wrap];
287 src_p1 = &src_0[src_wrap];
288 src_p2 = &src_p1[src_wrap];
289 for (
y = 0;
y < (height - 2);
y += 2) {
290 memcpy(dst, src_m1, width);
292 deinterlace_line(dst, src_m2, src_m1, src_0, src_p1, src_p2, width);
296 src_p1 += 2 * src_wrap;
297 src_p2 += 2 * src_wrap;
300 memcpy(dst, src_m1, width);
303 deinterlace_line(dst, src_m2, src_m1, src_0, src_0, src_0, width);
306FFMPEG_INLINE int deinterlace_bottom_field_inplace(uint8_t *src1,
311 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
315 return AVERROR(ENOMEM);
319 memcpy(buf, src_m1, width);
320 src_0 = &src_m1[src_wrap];
321 src_p1 = &src_0[src_wrap];
322 src_p2 = &src_p1[src_wrap];
323 for (
y = 0;
y < (height - 2);
y += 2) {
324 deinterlace_line_inplace(buf, src_m1, src_0, src_p1, src_p2, width);
327 src_p1 += 2 * src_wrap;
328 src_p2 += 2 * src_wrap;
331 deinterlace_line_inplace(buf, src_m1, src_0, src_0, src_0, width);
336int ffmpeg_deinterlace(
337 AVFrame *dst,
const AVFrame *src,
enum AVPixelFormat pix_fmt,
int width,
int height)
352 if ((width & 3) != 0 || (height & 3) != 0) {
356 for (
i = 0;
i < 3;
i++) {
359 case AV_PIX_FMT_YUVJ420P:
360 case AV_PIX_FMT_YUV420P:
364 case AV_PIX_FMT_YUV422P:
365 case AV_PIX_FMT_YUVJ422P:
368 case AV_PIX_FMT_YUV411P:
374 if (pix_fmt == AV_PIX_FMT_GRAY8) {
379 ret = deinterlace_bottom_field_inplace(dst->data[
i], dst->linesize[
i], width, height);
385 deinterlace_bottom_field(
386 dst->data[
i], dst->linesize[
i], src->data[
i], src->linesize[
i], width, height);
396 return AV_CODEC_ID_NONE;
398 return AV_CODEC_ID_MPEG1VIDEO;
400 return AV_CODEC_ID_MPEG2VIDEO;
402 return AV_CODEC_ID_MPEG4;
404 return AV_CODEC_ID_FLV1;
406 return AV_CODEC_ID_DVVIDEO;
408 return AV_CODEC_ID_HUFFYUV;
410 return AV_CODEC_ID_H264;
412 return AV_CODEC_ID_THEORA;
414 return AV_CODEC_ID_FFV1;
416 return AV_CODEC_ID_QTRLE;
418 return AV_CODEC_ID_PNG;
420 return AV_CODEC_ID_DNXHD;
422 return AV_CODEC_ID_VP9;
424 return AV_CODEC_ID_H265;
426 return AV_CODEC_ID_AV1;
428 return AV_CODEC_ID_PRORES;
430 return AV_CODEC_ID_PCM_S16LE;
432 return AV_CODEC_ID_MP2;
434 return AV_CODEC_ID_MP3;
436 return AV_CODEC_ID_AAC;
438 return AV_CODEC_ID_AC3;
440 return AV_CODEC_ID_VORBIS;
442 return AV_CODEC_ID_FLAC;
444 return AV_CODEC_ID_OPUS;
448 return AV_CODEC_ID_NONE;
451static void ffmpeg_preset_set(
RenderData *rd,
int preset)
453 bool is_ntsc = (rd->
frs_sec != 25);
506 if (
ELEM(av_codec_id,
515 if (
ELEM(av_codec_id, AV_CODEC_ID_H265, AV_CODEC_ID_AV1, AV_CODEC_ID_FFV1)) {
518 if (
ELEM(av_codec_id, AV_CODEC_ID_FFV1)) {
526 if (av_codec_id == AV_CODEC_ID_PRORES) {
529 return ELEM(av_codec_id,
534 AV_CODEC_ID_HUFFYUV);
539 return ELEM(av_codec_id,
547int MOV_thread_count()
560 if (isffmpeg(filepath)) {
573 avdevice_register_all();
575 ffmpeg_last_error_buffer[0] =
'\0';
578 av_log_set_level(AV_LOG_INFO);
581 av_log_set_level(AV_LOG_DEBUG);
584 av_log_set_level(AV_LOG_TRACE);
588 av_log_set_callback(ffmpeg_log_callback);
#define BLI_assert_unreachable()
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool BLI_path_extension_check_n(const char *path,...) ATTR_NONNULL(1) ATTR_SENTINEL(0)
size_t BLI_vsnprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format, va_list arg) ATTR_PRINTF_FORMAT(3
int BLI_system_thread_count(void)
#define CLOG_CHECK(clg_ref, verbose_level,...)
#define CLOG_STR_AT_LEVEL(clg_ref, verbose_level, str)
@ FFMPEG_CODEC_ID_MPEG1VIDEO
@ FFMPEG_CODEC_ID_PCM_S16LE
@ FFMPEG_CODEC_ID_HUFFYUV
@ FFMPEG_CODEC_ID_DVVIDEO
@ FFMPEG_CODEC_ID_MPEG2VIDEO
@ FFM_PRORES_PROFILE_4444_XQ
@ FFM_PRORES_PROFILE_4444
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static T sum(const btAlignedObjectArray< T > &items)
bool MOV_is_movie_file(const char *filepath)
int MOV_codec_valid_bit_depths(IMB_Ffmpeg_Codec_ID codec_id)
bool MOV_codec_supports_alpha(IMB_Ffmpeg_Codec_ID codec_id, int ffmpeg_profile)
void MOV_validate_output_settings(RenderData *rd, const ImageFormatData *imf)
bool MOV_codec_supports_crf(IMB_Ffmpeg_Codec_ID codec_id)
struct FFMpegCodecData ffcodecdata