Refactor: Logging: Use CLOG for video and ffmpeg
The --debug-ffmpeg flag now is the same as --log video, and only exists for backwards compatibility. The ffmpeg verbosity can now be controlled with --log-level. Pull Request: https://projects.blender.org/blender/blender/pulls/143447
This commit is contained in:
@@ -32,6 +32,7 @@ set(LIB
|
||||
PRIVATE bf::blenlib
|
||||
PUBLIC bf::imbuf
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
PRIVATE bf::intern::clog
|
||||
)
|
||||
|
||||
if(WITH_CODEC_FFMPEG)
|
||||
|
||||
@@ -23,12 +23,16 @@
|
||||
#include "BLI_time.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "MOV_read.hh"
|
||||
|
||||
#include "ffmpeg_swscale.hh"
|
||||
#include "movie_proxy_indexer.hh"
|
||||
#include "movie_read.hh"
|
||||
|
||||
static CLG_LogRef LOG = {"video.proxy"};
|
||||
|
||||
#ifdef WITH_FFMPEG
|
||||
extern "C" {
|
||||
# include "ffmpeg_compat.h"
|
||||
@@ -72,10 +76,10 @@ static MovieIndexBuilder *index_builder_create(const char *filepath)
|
||||
rv->fp = BLI_fopen(rv->filepath_temp, "wb");
|
||||
|
||||
if (!rv->fp) {
|
||||
fprintf(stderr,
|
||||
"Failed to build index for '%s': could not open '%s' for writing\n",
|
||||
filepath,
|
||||
rv->filepath_temp);
|
||||
CLOG_ERROR(&LOG,
|
||||
"Failed to build index for '%s': could not open '%s' for writing",
|
||||
filepath,
|
||||
rv->filepath_temp);
|
||||
MEM_freeN(rv);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -128,7 +132,7 @@ static MovieIndex *movie_index_open(const char *filepath)
|
||||
constexpr int64_t header_size = 12;
|
||||
char header[header_size + 1];
|
||||
if (fread(header, header_size, 1, fp) != 1) {
|
||||
fprintf(stderr, "Couldn't read indexer file: %s\n", filepath);
|
||||
CLOG_ERROR(&LOG, "Couldn't read indexer file: %s", filepath);
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -136,13 +140,13 @@ static MovieIndex *movie_index_open(const char *filepath)
|
||||
header[header_size] = 0;
|
||||
|
||||
if (memcmp(header, binary_header_str, 8) != 0) {
|
||||
fprintf(stderr, "Error reading %s: Binary file type string mismatch\n", filepath);
|
||||
CLOG_ERROR(&LOG, "Error reading %s: Binary file type string mismatch", filepath);
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (atoi(header + 9) != INDEX_FILE_VERSION) {
|
||||
fprintf(stderr, "Error reading %s: File version mismatch\n", filepath);
|
||||
CLOG_ERROR(&LOG, "Error reading %s: File version mismatch", filepath);
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -175,7 +179,7 @@ static MovieIndex *movie_index_open(const char *filepath)
|
||||
}
|
||||
|
||||
if (items_read != num_entries * 5) {
|
||||
fprintf(stderr, "Error: Element data size mismatch in: %s\n", filepath);
|
||||
CLOG_ERROR(&LOG, "Error: Element data size mismatch in: %s", filepath);
|
||||
MEM_delete(idx);
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
@@ -406,7 +410,7 @@ static proxy_output_ctx *alloc_proxy_output_ffmpeg(MovieReader *anim,
|
||||
rv->c = avcodec_alloc_context3(rv->codec);
|
||||
|
||||
if (!rv->codec) {
|
||||
fprintf(stderr, "Could not build proxy '%s': failed to create video encoder\n", filepath);
|
||||
CLOG_ERROR(&LOG, "Could not build proxy '%s': failed to create video encoder", filepath);
|
||||
avcodec_free_context(&rv->c);
|
||||
avformat_free_context(rv->of);
|
||||
MEM_freeN(rv);
|
||||
@@ -477,10 +481,10 @@ static proxy_output_ctx *alloc_proxy_output_ffmpeg(MovieReader *anim,
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
|
||||
fprintf(stderr,
|
||||
"Could not build proxy '%s': failed to create output file (%s)\n",
|
||||
filepath,
|
||||
error_str);
|
||||
CLOG_ERROR(&LOG,
|
||||
"Could not build proxy '%s': failed to create output file (%s)",
|
||||
filepath,
|
||||
error_str);
|
||||
avcodec_free_context(&rv->c);
|
||||
avformat_free_context(rv->of);
|
||||
MEM_freeN(rv);
|
||||
@@ -492,10 +496,8 @@ static proxy_output_ctx *alloc_proxy_output_ffmpeg(MovieReader *anim,
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
|
||||
fprintf(stderr,
|
||||
"Could not build proxy '%s': failed to open video codec (%s)\n",
|
||||
filepath,
|
||||
error_str);
|
||||
CLOG_ERROR(
|
||||
&LOG, "Could not build proxy '%s': failed to open video codec (%s)", filepath, error_str);
|
||||
avcodec_free_context(&rv->c);
|
||||
avformat_free_context(rv->of);
|
||||
MEM_freeN(rv);
|
||||
@@ -535,8 +537,8 @@ static proxy_output_ctx *alloc_proxy_output_ffmpeg(MovieReader *anim,
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
|
||||
fprintf(
|
||||
stderr, "Could not build proxy '%s': failed to write header (%s)\n", filepath, error_str);
|
||||
CLOG_ERROR(
|
||||
&LOG, "Could not build proxy '%s': failed to write header (%s)", filepath, error_str);
|
||||
|
||||
if (rv->frame) {
|
||||
av_frame_free(&rv->frame);
|
||||
@@ -575,8 +577,8 @@ static void add_to_proxy_output_ffmpeg(proxy_output_ctx *ctx, AVFrame *frame)
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
|
||||
fprintf(
|
||||
stderr, "Building proxy '%s': failed to send video frame (%s)\n", ctx->of->url, error_str);
|
||||
CLOG_ERROR(
|
||||
&LOG, "Building proxy '%s': failed to send video frame (%s)", ctx->of->url, error_str);
|
||||
return;
|
||||
}
|
||||
AVPacket *packet = av_packet_alloc();
|
||||
@@ -592,11 +594,11 @@ static void add_to_proxy_output_ffmpeg(proxy_output_ctx *ctx, AVFrame *frame)
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
|
||||
fprintf(stderr,
|
||||
"Building proxy '%s': error encoding frame #%i (%s)\n",
|
||||
ctx->of->url,
|
||||
ctx->cfra - 1,
|
||||
error_str);
|
||||
CLOG_ERROR(&LOG,
|
||||
"Building proxy '%s': error encoding frame #%i (%s)",
|
||||
ctx->of->url,
|
||||
ctx->cfra - 1,
|
||||
error_str);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -611,11 +613,11 @@ static void add_to_proxy_output_ffmpeg(proxy_output_ctx *ctx, AVFrame *frame)
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, write_ret);
|
||||
|
||||
fprintf(stderr,
|
||||
"Building proxy '%s': error writing frame #%i (%s)\n",
|
||||
ctx->of->url,
|
||||
ctx->cfra - 1,
|
||||
error_str);
|
||||
CLOG_ERROR(&LOG,
|
||||
"Building proxy '%s': error writing frame #%i (%s)",
|
||||
ctx->of->url,
|
||||
ctx->cfra - 1,
|
||||
error_str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -939,7 +941,7 @@ static int index_rebuild_ffmpeg(MovieProxyBuilder *context,
|
||||
if (ret < 0) {
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Error decoding proxy frame: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Error decoding proxy frame: %s", error_str);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -975,7 +977,7 @@ static int index_rebuild_ffmpeg(MovieProxyBuilder *context,
|
||||
if (ret < 0) {
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Error flushing proxy frame: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Error flushing proxy frame: %s", error_str);
|
||||
break;
|
||||
}
|
||||
index_rebuild_ffmpeg_proc_decoded_frame(context, in_frame);
|
||||
@@ -1015,7 +1017,7 @@ static int indexer_performance_get_decode_rate(MovieProxyBuilder *context,
|
||||
if (ret < 0) {
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Error decoding proxy frame: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Error decoding proxy frame: %s", error_str);
|
||||
break;
|
||||
}
|
||||
frames_decoded++;
|
||||
@@ -1095,8 +1097,9 @@ static bool indexer_need_to_build_proxy(MovieProxyBuilder *context)
|
||||
const int max_gop_size = indexer_performance_get_max_gop_size(context);
|
||||
|
||||
if (max_gop_size <= 10 || max_gop_size < decode_rate) {
|
||||
printf("Skipping proxy building for %s: Decoding performance is already good.\n",
|
||||
context->iFormatCtx->url);
|
||||
CLOG_INFO_NOCHECK(&LOG,
|
||||
"Skipping proxy building for %s: Decoding performance is already good.",
|
||||
context->iFormatCtx->url);
|
||||
context->building_cancelled = true;
|
||||
return false;
|
||||
}
|
||||
@@ -1148,7 +1151,7 @@ MovieProxyBuilder *MOV_proxy_builder_start(MovieReader *anim,
|
||||
if (!get_proxy_filepath(anim, proxy_size, filepath, false)) {
|
||||
return nullptr;
|
||||
}
|
||||
printf("Skipping proxy: %s\n", filepath);
|
||||
CLOG_INFO_NOCHECK(&LOG, "Skipping proxy: %s", filepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include "IMB_imbuf.hh"
|
||||
#include "IMB_imbuf_types.hh"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "MOV_read.hh"
|
||||
|
||||
#include "IMB_metadata.hh"
|
||||
@@ -53,6 +55,8 @@ extern "C" {
|
||||
|
||||
#endif /* WITH_FFMPEG */
|
||||
|
||||
static CLG_LogRef LOG = {"video.read"};
|
||||
|
||||
#ifdef WITH_FFMPEG
|
||||
static void free_anim_ffmpeg(MovieReader *anim);
|
||||
#endif
|
||||
@@ -483,7 +487,7 @@ static int startffmpeg(MovieReader *anim)
|
||||
|
||||
const size_t align = ffmpeg_get_buffer_alignment();
|
||||
if (av_frame_get_buffer(anim->pFrameRGB, align) < 0) {
|
||||
fprintf(stderr, "Could not allocate frame data.\n");
|
||||
CLOG_ERROR(&LOG, "Could not allocate frame data.");
|
||||
avcodec_free_context(&anim->pCodecCtx);
|
||||
avformat_close_input(&anim->pFormatCtx);
|
||||
av_packet_free(&anim->cur_packet);
|
||||
@@ -530,11 +534,11 @@ static int startffmpeg(MovieReader *anim)
|
||||
SWS_ACCURATE_RND);
|
||||
|
||||
if (!anim->img_convert_ctx) {
|
||||
fprintf(stderr,
|
||||
"ffmpeg: swscale can't transform from pixel format %s to %s (%s)\n",
|
||||
av_get_pix_fmt_name(anim->pCodecCtx->pix_fmt),
|
||||
av_get_pix_fmt_name((AVPixelFormat)anim->pFrameRGB->format),
|
||||
anim->filepath);
|
||||
CLOG_ERROR(&LOG,
|
||||
"ffmpeg: swscale can't transform from pixel format %s to %s (%s)",
|
||||
av_get_pix_fmt_name(anim->pCodecCtx->pix_fmt),
|
||||
av_get_pix_fmt_name((AVPixelFormat)anim->pFrameRGB->format),
|
||||
anim->filepath);
|
||||
avcodec_free_context(&anim->pCodecCtx);
|
||||
avformat_close_input(&anim->pFormatCtx);
|
||||
av_packet_free(&anim->cur_packet);
|
||||
@@ -706,9 +710,9 @@ static void ffmpeg_postprocess(MovieReader *anim, AVFrame *input, ImBuf *ibuf)
|
||||
if (input->data[0] == nullptr && input->data[1] == nullptr && input->data[2] == nullptr &&
|
||||
input->data[3] == nullptr)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"ffmpeg_fetchibuf: "
|
||||
"data not read properly...\n");
|
||||
CLOG_ERROR(&LOG,
|
||||
"ffmpeg_fetchibuf: "
|
||||
"data not read properly...");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "BLI_path_utils.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "MOV_enums.hh"
|
||||
@@ -16,13 +17,12 @@
|
||||
|
||||
#include "ffmpeg_swscale.hh"
|
||||
#include "movie_util.hh"
|
||||
#include <mutex>
|
||||
|
||||
#ifdef WITH_FFMPEG
|
||||
|
||||
# include "BLI_string.h"
|
||||
|
||||
# include "BKE_global.hh"
|
||||
|
||||
extern "C" {
|
||||
# include "ffmpeg_compat.h"
|
||||
# include <libavcodec/avcodec.h>
|
||||
@@ -31,6 +31,8 @@ extern "C" {
|
||||
# include <libavutil/log.h>
|
||||
}
|
||||
|
||||
static CLG_LogRef LOG = {"video.ffmpeg"};
|
||||
|
||||
static char ffmpeg_last_error_buffer[1024];
|
||||
|
||||
/* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */
|
||||
@@ -39,23 +41,76 @@ static char ffmpeg_last_error_buffer[1024];
|
||||
# pragma GCC diagnostic ignored "-Wmissing-format-attribute"
|
||||
# endif
|
||||
|
||||
static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg)
|
||||
static size_t ffmpeg_log_to_buffer(char *buffer,
|
||||
const size_t buffer_size,
|
||||
const char *format,
|
||||
va_list arg)
|
||||
{
|
||||
if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
|
||||
size_t n;
|
||||
va_list args_cpy;
|
||||
va_list args_cpy;
|
||||
size_t n;
|
||||
|
||||
va_copy(args_cpy, arg);
|
||||
n = VSNPRINTF(ffmpeg_last_error_buffer, format, args_cpy);
|
||||
va_end(args_cpy);
|
||||
va_copy(args_cpy, arg);
|
||||
n = BLI_vsnprintf(buffer, buffer_size, format, args_cpy);
|
||||
va_end(args_cpy);
|
||||
|
||||
/* strip trailing \n */
|
||||
return n;
|
||||
}
|
||||
|
||||
static void ffmpeg_log_callback(void * /*ptr*/, int level, const char *format, va_list arg)
|
||||
{
|
||||
CLG_Level clg_level;
|
||||
|
||||
switch (level) {
|
||||
case AV_LOG_PANIC:
|
||||
case AV_LOG_FATAL:
|
||||
clg_level = CLG_LEVEL_FATAL;
|
||||
break;
|
||||
case AV_LOG_ERROR:
|
||||
clg_level = CLG_LEVEL_ERROR;
|
||||
break;
|
||||
case AV_LOG_WARNING:
|
||||
clg_level = CLG_LEVEL_WARN;
|
||||
break;
|
||||
case AV_LOG_INFO:
|
||||
clg_level = CLG_LEVEL_INFO;
|
||||
break;
|
||||
case AV_LOG_VERBOSE:
|
||||
case AV_LOG_DEBUG:
|
||||
clg_level = CLG_LEVEL_DEBUG;
|
||||
break;
|
||||
case AV_LOG_TRACE:
|
||||
default:
|
||||
clg_level = CLG_LEVEL_TRACE;
|
||||
break;
|
||||
}
|
||||
|
||||
static std::mutex mutex;
|
||||
std::scoped_lock lock(mutex);
|
||||
|
||||
if (ELEM(clg_level, CLG_LEVEL_FATAL, CLG_LEVEL_ERROR)) {
|
||||
const size_t n = ffmpeg_log_to_buffer(
|
||||
ffmpeg_last_error_buffer, sizeof(ffmpeg_last_error_buffer), format, arg);
|
||||
/* Strip trailing \n. */
|
||||
ffmpeg_last_error_buffer[n - 1] = '\0';
|
||||
}
|
||||
|
||||
if (G.debug & G_DEBUG_FFMPEG) {
|
||||
/* call default logger to print all message to console */
|
||||
av_log_default_callback(ptr, level, format, arg);
|
||||
if (CLOG_CHECK(&LOG, clg_level)) {
|
||||
/* FFmpeg calls this multiple times without a line ending, so accumulate until
|
||||
* we reach a line ending. This will not work well with multithreading, but the
|
||||
* output would be garbled either way. */
|
||||
static char buffer[1024];
|
||||
static int buffer_used = 0;
|
||||
|
||||
buffer_used += ffmpeg_log_to_buffer(
|
||||
buffer + buffer_used, sizeof(buffer) - buffer_used, format, arg);
|
||||
|
||||
if (buffer_used >= sizeof(buffer) || (buffer_used > 0 && buffer[buffer_used - 1] == '\n')) {
|
||||
if (buffer[buffer_used - 1] == '\n') {
|
||||
buffer[buffer_used - 1] = '\0';
|
||||
}
|
||||
CLOG_STR_AT_LEVEL(&LOG, clg_level, buffer);
|
||||
buffer_used = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,9 +569,15 @@ void MOV_init()
|
||||
|
||||
ffmpeg_last_error_buffer[0] = '\0';
|
||||
|
||||
if (G.debug & G_DEBUG_FFMPEG) {
|
||||
if (CLOG_CHECK(&LOG, CLG_LEVEL_INFO)) {
|
||||
av_log_set_level(AV_LOG_INFO);
|
||||
}
|
||||
else if (CLOG_CHECK(&LOG, CLG_LEVEL_DEBUG)) {
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
}
|
||||
else if (CLOG_CHECK(&LOG, CLG_LEVEL_TRACE)) {
|
||||
av_log_set_level(AV_LOG_TRACE);
|
||||
}
|
||||
|
||||
/* set separate callback which could store last error to report to UI */
|
||||
av_log_set_callback(ffmpeg_log_callback);
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
# include "BLI_threads.h"
|
||||
# include "BLI_utildefines.h"
|
||||
|
||||
# include "BKE_global.hh"
|
||||
# include "BKE_image.hh"
|
||||
# include "BKE_main.hh"
|
||||
# include "BKE_path_templates.hh"
|
||||
@@ -42,15 +41,14 @@
|
||||
|
||||
# include "IMB_colormanagement.hh"
|
||||
|
||||
# include "CLG_log.h"
|
||||
|
||||
# include "ffmpeg_swscale.hh"
|
||||
# include "movie_util.hh"
|
||||
|
||||
static CLG_LogRef LOG = {"video.write"};
|
||||
static constexpr int64_t ffmpeg_autosplit_size = 2'000'000'000;
|
||||
|
||||
# define FF_DEBUG_PRINT \
|
||||
if (G.debug & G_DEBUG_FFMPEG) \
|
||||
printf
|
||||
|
||||
static void ffmpeg_dict_set_int(AVDictionary **dict, const char *key, int value)
|
||||
{
|
||||
av_dict_set_int(dict, key, value, 0);
|
||||
@@ -163,7 +161,7 @@ static bool write_video_frame(MovieWriter *context, AVFrame *frame, ReportList *
|
||||
if (ret < 0) {
|
||||
/* Can't send frame to encoder. This shouldn't happen. */
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Can't send video frame: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Can't send video frame: %s", error_str);
|
||||
success = -1;
|
||||
}
|
||||
|
||||
@@ -176,7 +174,7 @@ static bool write_video_frame(MovieWriter *context, AVFrame *frame, ReportList *
|
||||
}
|
||||
if (ret < 0) {
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Error encoding frame: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Error encoding frame: %s", error_str);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -195,7 +193,7 @@ static bool write_video_frame(MovieWriter *context, AVFrame *frame, ReportList *
|
||||
if (!success) {
|
||||
BKE_report(reports, RPT_ERROR, "Error writing frame");
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
FF_DEBUG_PRINT("ffmpeg: error writing video frame: %s\n", error_str);
|
||||
CLOG_INFO(&LOG, "ffmpeg: error writing video frame: %s", error_str);
|
||||
}
|
||||
|
||||
av_packet_free(&packet);
|
||||
@@ -836,7 +834,7 @@ static AVStream *alloc_video_stream(MovieWriter *context,
|
||||
codec = avcodec_find_encoder(codec_id);
|
||||
}
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Couldn't find valid video codec\n");
|
||||
CLOG_ERROR(&LOG, "Couldn't find valid video codec");
|
||||
context->video_codec = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -905,7 +903,7 @@ static AVStream *alloc_video_stream(MovieWriter *context,
|
||||
deadline_name = "realtime";
|
||||
break;
|
||||
default:
|
||||
printf("Unknown preset number %i, ignoring.\n", context->ffmpeg_preset);
|
||||
CLOG_WARN(&LOG, "Unknown preset number %i, ignoring.", context->ffmpeg_preset);
|
||||
}
|
||||
/* "codec_id != AV_CODEC_ID_AV1" is required due to "preset" already being set by an AV1 codec.
|
||||
*/
|
||||
@@ -1074,12 +1072,12 @@ static AVStream *alloc_video_stream(MovieWriter *context,
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "ffmpeg: invalid profile %d\n", context->ffmpeg_profile);
|
||||
CLOG_ERROR(&LOG, "ffmpeg: invalid profile %d", context->ffmpeg_profile);
|
||||
}
|
||||
}
|
||||
|
||||
if (of->oformat->flags & AVFMT_GLOBALHEADER) {
|
||||
FF_DEBUG_PRINT("ffmpeg: using global video header\n");
|
||||
CLOG_STR_INFO(&LOG, "ffmpeg: using global video header");
|
||||
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
|
||||
@@ -1132,7 +1130,7 @@ static AVStream *alloc_video_stream(MovieWriter *context,
|
||||
if (ret < 0) {
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Couldn't initialize video codec: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Couldn't initialize video codec: %s\n", error_str);
|
||||
BLI_strncpy(error, ffmpeg_last_error(), error_size);
|
||||
av_dict_free(&opts);
|
||||
avcodec_free_context(&c);
|
||||
@@ -1237,22 +1235,22 @@ static bool start_ffmpeg_impl(MovieWriter *context,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
FF_DEBUG_PRINT(
|
||||
"ffmpeg: starting output to %s:\n"
|
||||
" type=%d, codec=%d, audio_codec=%d,\n"
|
||||
" video_bitrate=%d, audio_bitrate=%d,\n"
|
||||
" gop_size=%d, autosplit=%d\n"
|
||||
" width=%d, height=%d\n",
|
||||
filepath,
|
||||
context->ffmpeg_type,
|
||||
context->ffmpeg_codec,
|
||||
context->ffmpeg_audio_codec,
|
||||
context->ffmpeg_video_bitrate,
|
||||
context->ffmpeg_audio_bitrate,
|
||||
context->ffmpeg_gop_size,
|
||||
context->ffmpeg_autosplit,
|
||||
rectx,
|
||||
recty);
|
||||
CLOG_INFO(&LOG,
|
||||
"ffmpeg: starting output to %s:\n"
|
||||
" type=%d, codec=%d, audio_codec=%d,\n"
|
||||
" video_bitrate=%d, audio_bitrate=%d,\n"
|
||||
" gop_size=%d, autosplit=%d\n"
|
||||
" width=%d, height=%d",
|
||||
filepath,
|
||||
context->ffmpeg_type,
|
||||
context->ffmpeg_codec,
|
||||
context->ffmpeg_audio_codec,
|
||||
context->ffmpeg_video_bitrate,
|
||||
context->ffmpeg_audio_bitrate,
|
||||
context->ffmpeg_gop_size,
|
||||
context->ffmpeg_autosplit,
|
||||
rectx,
|
||||
recty);
|
||||
|
||||
/* Sanity checks for the output file extensions. */
|
||||
exts = get_file_extensions(context->ffmpeg_type);
|
||||
@@ -1351,15 +1349,15 @@ static bool start_ffmpeg_impl(MovieWriter *context,
|
||||
if (video_codec != AV_CODEC_ID_NONE) {
|
||||
context->video_stream = alloc_video_stream(
|
||||
context, rd, video_codec, of, rectx, recty, error, sizeof(error));
|
||||
FF_DEBUG_PRINT("ffmpeg: alloc video stream %p\n", context->video_stream);
|
||||
CLOG_INFO(&LOG, "ffmpeg: alloc video stream %p", context->video_stream);
|
||||
if (!context->video_stream) {
|
||||
if (error[0]) {
|
||||
BKE_report(reports, RPT_ERROR, error);
|
||||
FF_DEBUG_PRINT("ffmpeg: video stream error: %s\n", error);
|
||||
CLOG_INFO(&LOG, "ffmpeg: video stream error: %s", error);
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR, "Error initializing video stream");
|
||||
FF_DEBUG_PRINT("ffmpeg: error initializing video stream\n");
|
||||
CLOG_STR_INFO(&LOG, "ffmpeg: error initializing video stream");
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
@@ -1376,11 +1374,11 @@ static bool start_ffmpeg_impl(MovieWriter *context,
|
||||
if (!context->audio_stream) {
|
||||
if (error[0]) {
|
||||
BKE_report(reports, RPT_ERROR, error);
|
||||
FF_DEBUG_PRINT("ffmpeg: audio stream error: %s\n", error);
|
||||
CLOG_INFO(&LOG, "ffmpeg: audio stream error: %s", error);
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR, "Error initializing audio stream");
|
||||
FF_DEBUG_PRINT("ffmpeg: error initializing audio stream\n");
|
||||
CLOG_STR_INFO(&LOG, "ffmpeg: error initializing audio stream");
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
@@ -1388,7 +1386,7 @@ static bool start_ffmpeg_impl(MovieWriter *context,
|
||||
if (!(fmt->flags & AVFMT_NOFILE)) {
|
||||
if (avio_open(&of->pb, filepath, AVIO_FLAG_WRITE) < 0) {
|
||||
BKE_report(reports, RPT_ERROR, "Could not open file for writing");
|
||||
FF_DEBUG_PRINT("ffmpeg: could not open file %s for writing\n", filepath);
|
||||
CLOG_INFO(&LOG, "ffmpeg: could not open file %s for writing", filepath);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
@@ -1405,7 +1403,7 @@ static bool start_ffmpeg_impl(MovieWriter *context,
|
||||
"Could not initialize streams, probably unsupported codec combination");
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
FF_DEBUG_PRINT("ffmpeg: could not write media header: %s\n", error_str);
|
||||
CLOG_INFO(&LOG, "ffmpeg: could not write media header: %s", error_str);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -1448,7 +1446,7 @@ static void flush_delayed_frames(AVCodecContext *c, AVStream *stream, AVFormatCo
|
||||
}
|
||||
if (ret < 0) {
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Error encoding delayed frame: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Error encoding delayed frame: %s", error_str);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1461,7 +1459,7 @@ static void flush_delayed_frames(AVCodecContext *c, AVStream *stream, AVFormatCo
|
||||
int write_ret = av_interleaved_write_frame(outfile, packet);
|
||||
if (write_ret != 0) {
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Error writing delayed frame: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Error writing delayed frame: %s", error_str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1626,7 +1624,7 @@ static bool ffmpeg_movie_append(MovieWriter *context,
|
||||
AVFrame *avframe;
|
||||
bool success = true;
|
||||
|
||||
FF_DEBUG_PRINT("ffmpeg: writing frame #%i (%ix%i)\n", frame, image->x, image->y);
|
||||
CLOG_INFO(&LOG, "ffmpeg: writing frame #%i (%ix%i)", frame, image->x, image->y);
|
||||
|
||||
if (context->video_stream) {
|
||||
avframe = generate_video_frame(context, image);
|
||||
@@ -1653,17 +1651,17 @@ static bool ffmpeg_movie_append(MovieWriter *context,
|
||||
|
||||
static void end_ffmpeg_impl(MovieWriter *context, bool is_autosplit)
|
||||
{
|
||||
FF_DEBUG_PRINT("ffmpeg: closing\n");
|
||||
CLOG_STR_INFO(&LOG, "ffmpeg: closing");
|
||||
|
||||
movie_audio_close(context, is_autosplit);
|
||||
|
||||
if (context->video_stream) {
|
||||
FF_DEBUG_PRINT("ffmpeg: flush delayed video frames\n");
|
||||
CLOG_STR_INFO(&LOG, "ffmpeg: flush delayed video frames");
|
||||
flush_delayed_frames(context->video_codec, context->video_stream, context->outfile);
|
||||
}
|
||||
|
||||
if (context->audio_stream) {
|
||||
FF_DEBUG_PRINT("ffmpeg: flush delayed audio frames\n");
|
||||
CLOG_STR_INFO(&LOG, "ffmpeg: flush delayed audio frames");
|
||||
flush_delayed_frames(context->audio_codec, context->audio_stream, context->outfile);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
# include "BKE_report.hh"
|
||||
# include "BKE_sound.h"
|
||||
|
||||
# include "CLG_log.h"
|
||||
|
||||
static CLG_LogRef LOG = {"video.write"};
|
||||
|
||||
/* If any of these codecs, we prefer the float sample format (if supported) */
|
||||
static bool request_float_audio_buffer(int codec_id)
|
||||
{
|
||||
@@ -98,7 +102,7 @@ static int write_audio_frame(MovieWriter *context)
|
||||
if (ret < 0) {
|
||||
/* Can't send frame to encoder. This shouldn't happen. */
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Can't send audio frame: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Can't send audio frame: %s", error_str);
|
||||
success = -1;
|
||||
}
|
||||
|
||||
@@ -112,7 +116,7 @@ static int write_audio_frame(MovieWriter *context)
|
||||
}
|
||||
if (ret < 0) {
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Error encoding audio frame: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Error encoding audio frame: %s", error_str);
|
||||
success = -1;
|
||||
}
|
||||
|
||||
@@ -127,7 +131,7 @@ static int write_audio_frame(MovieWriter *context)
|
||||
int write_ret = av_interleaved_write_frame(context->outfile, pkt);
|
||||
if (write_ret != 0) {
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Error writing audio packet: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Error writing audio packet: %s", error_str);
|
||||
success = -1;
|
||||
break;
|
||||
}
|
||||
@@ -227,7 +231,7 @@ AVStream *alloc_audio_stream(MovieWriter *context,
|
||||
|
||||
codec = avcodec_find_encoder(codec_id);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Couldn't find valid audio codec\n");
|
||||
CLOG_ERROR(&LOG, "Couldn't find valid audio codec");
|
||||
context->audio_codec = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -318,7 +322,7 @@ AVStream *alloc_audio_stream(MovieWriter *context,
|
||||
if (ret < 0) {
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
||||
fprintf(stderr, "Couldn't initialize audio codec: %s\n", error_str);
|
||||
CLOG_ERROR(&LOG, "Couldn't initialize audio codec: %s", error_str);
|
||||
BLI_strncpy(error, ffmpeg_last_error(), error_size);
|
||||
avcodec_free_context(&c);
|
||||
context->audio_codec = nullptr;
|
||||
|
||||
@@ -435,11 +435,6 @@ static int bpy_app_binary_path_set(PyObject * /*self*/, PyObject *value, void *
|
||||
|
||||
static PyGetSetDef bpy_app_getsets[] = {
|
||||
{"debug", bpy_app_debug_get, bpy_app_debug_set, bpy_app_debug_doc, (void *)G_DEBUG},
|
||||
{"debug_ffmpeg",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_FFMPEG},
|
||||
{"debug_freestyle",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
|
||||
@@ -726,9 +726,6 @@ static void print_help(bArgs *ba, bool all)
|
||||
|
||||
PRINT("\n");
|
||||
BLI_args_print_arg_doc(ba, "--debug-events");
|
||||
if (defs.with_ffmpeg) {
|
||||
BLI_args_print_arg_doc(ba, "--debug-ffmpeg");
|
||||
}
|
||||
BLI_args_print_arg_doc(ba, "--debug-handlers");
|
||||
if (defs.with_libmv) {
|
||||
BLI_args_print_arg_doc(ba, "--debug-libmv");
|
||||
@@ -1323,9 +1320,6 @@ static int arg_handle_debug_mode_set(int /*argc*/, const char ** /*argv*/, void
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char arg_handle_debug_mode_generic_set_doc_ffmpeg[] =
|
||||
"\n\t"
|
||||
"Enable debug messages from FFmpeg library.";
|
||||
static const char arg_handle_debug_mode_generic_set_doc_freestyle[] =
|
||||
"\n\t"
|
||||
"Enable debug messages for Freestyle.";
|
||||
@@ -1440,6 +1434,16 @@ static int arg_handle_debug_mode_cycles(int /*argc*/, const char ** /*argv*/, vo
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char arg_handle_debug_mode_ffmpeg_doc[] =
|
||||
"\n\t"
|
||||
"Enable debug messages from FFmpeg video input and output.";
|
||||
static int arg_handle_debug_mode_ffmpeg(int /*argc*/, const char ** /*argv*/, void * /*data*/)
|
||||
{
|
||||
const char *video_filter = "video.*";
|
||||
CLG_type_filter_include(video_filter, strlen(video_filter));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char arg_handle_debug_mode_memory_set_doc[] =
|
||||
"\n\t"
|
||||
"Enable fully guarded memory allocation and debugging.";
|
||||
@@ -2783,11 +2787,7 @@ void main_args_setup(bContext *C, bArgs *ba, bool all)
|
||||
BLI_args_add(ba, "-d", "--debug", CB(arg_handle_debug_mode_set), ba);
|
||||
|
||||
if (defs.with_ffmpeg) {
|
||||
BLI_args_add(ba,
|
||||
nullptr,
|
||||
"--debug-ffmpeg",
|
||||
CB_EX(arg_handle_debug_mode_generic_set, ffmpeg),
|
||||
(void *)G_DEBUG_FFMPEG);
|
||||
BLI_args_add(ba, nullptr, "--debug-ffmpeg", CB(arg_handle_debug_mode_ffmpeg), nullptr);
|
||||
}
|
||||
|
||||
if (defs.with_freestyle) {
|
||||
|
||||
Reference in New Issue
Block a user