From e76b848697d5a4a43ce336fcef8aae9f8d317866 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Wed, 21 Feb 2024 12:57:36 +0100 Subject: [PATCH] Cleanup: Video: change bMovieHandle function to take ImBuf as input Towards #118493: make movie writing functionality take ImBuf instead of int* to pixel data. While at it, make other bMovieHandle functions use "bool" return type when it is strictly a success/failure result. Pull Request: https://projects.blender.org/blender/blender/pulls/118559 --- source/blender/blenkernel/BKE_writeffmpeg.hh | 30 ++++---- source/blender/blenkernel/BKE_writemovie.hh | 27 ++++--- .../blender/blenkernel/intern/writeffmpeg.cc | 75 ++++++++++--------- .../blender/blenkernel/intern/writemovie.cc | 36 +++++---- source/blender/render/intern/pipeline.cc | 8 +- 5 files changed, 86 insertions(+), 90 deletions(-) diff --git a/source/blender/blenkernel/BKE_writeffmpeg.hh b/source/blender/blenkernel/BKE_writeffmpeg.hh index d63e1cfcf25..8086cea58c9 100644 --- a/source/blender/blenkernel/BKE_writeffmpeg.hh +++ b/source/blender/blenkernel/BKE_writeffmpeg.hh @@ -41,24 +41,24 @@ struct ReportList; struct Scene; struct SwsContext; -int BKE_ffmpeg_start(void *context_v, - const Scene *scene, - RenderData *rd, - int rectx, - int recty, - ReportList *reports, - bool preview, - const char *suffix); -void BKE_ffmpeg_end(void *context_v); -int BKE_ffmpeg_append(void *context_v, +struct ImBuf; + +bool BKE_ffmpeg_start(void *context_v, + const Scene *scene, RenderData *rd, - int start_frame, - int frame, - int *pixels, int rectx, int recty, - const char *suffix, - ReportList *reports); + ReportList *reports, + bool preview, + const char *suffix); +void BKE_ffmpeg_end(void *context_v); +bool BKE_ffmpeg_append(void *context_v, + RenderData *rd, + int start_frame, + int frame, + const ImBuf *image, + const char *suffix, + ReportList *reports); void BKE_ffmpeg_filepath_get(char filepath[/*FILE_MAX*/ 1024], const RenderData *rd, bool preview, diff --git a/source/blender/blenkernel/BKE_writemovie.hh b/source/blender/blenkernel/BKE_writemovie.hh index e4028fa700a..89c5e021529 100644 --- a/source/blender/blenkernel/BKE_writemovie.hh +++ b/source/blender/blenkernel/BKE_writemovie.hh @@ -10,28 +10,27 @@ /* generic blender movie support, could move to own module */ +struct ImBuf; struct RenderData; struct ReportList; struct Scene; struct bMovieHandle { - int (*start_movie)(void *context_v, - const Scene *scene, - RenderData *rd, - int rectx, - int recty, - ReportList *reports, - bool preview, - const char *suffix); - int (*append_movie)(void *context_v, + bool (*start_movie)(void *context_v, + const Scene *scene, RenderData *rd, - int start_frame, - int frame, - int *pixels, int rectx, int recty, - const char *suffix, - ReportList *reports); + ReportList *reports, + bool preview, + const char *suffix); + bool (*append_movie)(void *context_v, + RenderData *rd, + int start_frame, + int frame, + const ImBuf *image, + const char *suffix, + ReportList *reports); void (*end_movie)(void *context_v); /* Optional function. */ diff --git a/source/blender/blenkernel/intern/writeffmpeg.cc b/source/blender/blenkernel/intern/writeffmpeg.cc index cbac7afa118..48bb1a1438d 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.cc +++ b/source/blender/blenkernel/intern/writeffmpeg.cc @@ -338,7 +338,7 @@ static const char **get_file_extensions(int format) } /* Write a frame to the output file */ -static int write_video_frame(FFMpegContext *context, AVFrame *frame, ReportList *reports) +static bool write_video_frame(FFMpegContext *context, AVFrame *frame, ReportList *reports) { int ret, success = 1; AVPacket *packet = av_packet_alloc(); @@ -394,8 +394,14 @@ static int write_video_frame(FFMpegContext *context, AVFrame *frame, ReportList } /* read and encode a frame of video from the buffer */ -static AVFrame *generate_video_frame(FFMpegContext *context, const uint8_t *pixels) +static AVFrame *generate_video_frame(FFMpegContext *context, const ImBuf *image) { + /* For now only 8-bit/channel images are supported. */ + const uint8_t *pixels = image->byte_buffer.data; + if (pixels == nullptr) { + return nullptr; + } + AVCodecParameters *codec = context->video_stream->codecpar; int height = codec->height; AVFrame *rgb_frame; @@ -1273,12 +1279,12 @@ static void ffmpeg_add_metadata_callback(void *data, av_dict_set(metadata, propname, propvalue, 0); } -static int start_ffmpeg_impl(FFMpegContext *context, - RenderData *rd, - int rectx, - int recty, - const char *suffix, - ReportList *reports) +static bool start_ffmpeg_impl(FFMpegContext *context, + RenderData *rd, + int rectx, + int recty, + const char *suffix, + ReportList *reports) { /* Handle to the output file */ AVFormatContext *of; @@ -1324,19 +1330,19 @@ static int start_ffmpeg_impl(FFMpegContext *context, exts = get_file_extensions(context->ffmpeg_type); if (!exts) { BKE_report(reports, RPT_ERROR, "No valid formats found"); - return 0; + return false; } fmt = av_guess_format(nullptr, exts[0], nullptr); if (!fmt) { BKE_report(reports, RPT_ERROR, "No valid formats found"); - return 0; + return false; } of = avformat_alloc_context(); if (!of) { BKE_report(reports, RPT_ERROR, "Can't allocate FFmpeg format context"); - return 0; + return false; } enum AVCodecID audio_codec = context->ffmpeg_audio_codec; @@ -1469,7 +1475,7 @@ static int start_ffmpeg_impl(FFMpegContext *context, context->outfile = of; av_dump_format(of, 0, filepath, 1); - return 1; + return true; fail: if (of->pb) { @@ -1485,7 +1491,7 @@ fail: } avformat_free_context(of); - return 0; + return false; } /** @@ -1626,23 +1632,22 @@ void BKE_ffmpeg_filepath_get(char filepath[/*FILE_MAX*/ 1024], ffmpeg_filepath_get(nullptr, filepath, rd, preview, suffix); } -int BKE_ffmpeg_start(void *context_v, - const Scene *scene, - RenderData *rd, - int rectx, - int recty, - ReportList *reports, - bool preview, - const char *suffix) +bool BKE_ffmpeg_start(void *context_v, + const Scene *scene, + RenderData *rd, + int rectx, + int recty, + ReportList *reports, + bool preview, + const char *suffix) { - int success; FFMpegContext *context = static_cast(context_v); context->ffmpeg_autosplit_count = 0; context->ffmpeg_preview = preview; context->stamp_data = BKE_stamp_info_from_scene_static(scene); - success = start_ffmpeg_impl(context, rd, rectx, recty, suffix, reports); + bool success = start_ffmpeg_impl(context, rd, rectx, recty, suffix, reports); # ifdef WITH_AUDASPACE if (context->audio_stream) { AVCodecContext *c = context->audio_codec; @@ -1699,24 +1704,22 @@ static void write_audio_frames(FFMpegContext *context, double to_pts) } # endif -int BKE_ffmpeg_append(void *context_v, - RenderData *rd, - int start_frame, - int frame, - int *pixels, - int rectx, - int recty, - const char *suffix, - ReportList *reports) +bool BKE_ffmpeg_append(void *context_v, + RenderData *rd, + int start_frame, + int frame, + const ImBuf *image, + const char *suffix, + ReportList *reports) { FFMpegContext *context = static_cast(context_v); AVFrame *avframe; - int success = 1; + bool success = true; - PRINT("Writing frame %i, render width=%d, render height=%d\n", frame, rectx, recty); + PRINT("Writing frame %i, render width=%d, render height=%d\n", frame, image->x, image->y); if (context->video_stream) { - avframe = generate_video_frame(context, (uchar *)pixels); + avframe = generate_video_frame(context, image); success = (avframe && write_video_frame(context, avframe, reports)); # ifdef WITH_AUDASPACE /* Add +1 frame because we want to encode audio up until the next video frame. */ @@ -1731,7 +1734,7 @@ int BKE_ffmpeg_append(void *context_v, end_ffmpeg_impl(context, true); context->ffmpeg_autosplit_count++; - success &= start_ffmpeg_impl(context, rd, rectx, recty, suffix, reports); + success &= start_ffmpeg_impl(context, rd, image->x, image->y, suffix, reports); } } } diff --git a/source/blender/blenkernel/intern/writemovie.cc b/source/blender/blenkernel/intern/writemovie.cc index 08717ee767b..30b1fbe365e 100644 --- a/source/blender/blenkernel/intern/writemovie.cc +++ b/source/blender/blenkernel/intern/writemovie.cc @@ -23,31 +23,29 @@ #include "BKE_writemovie.hh" -static int start_stub(void * /*context_v*/, - const Scene * /*scene*/, - RenderData * /*rd*/, - int /*rectx*/, - int /*recty*/, - ReportList * /*reports*/, - bool /*preview*/, - const char * /*suffix*/) +static bool start_stub(void * /*context_v*/, + const Scene * /*scene*/, + RenderData * /*rd*/, + int /*rectx*/, + int /*recty*/, + ReportList * /*reports*/, + bool /*preview*/, + const char * /*suffix*/) { - return 0; + return false; } static void end_stub(void * /*context_v*/) {} -static int append_stub(void * /*context_v*/, - RenderData * /*rd*/, - int /*start_frame*/, - int /*frame*/, - int * /*pixels*/, - int /*rectx*/, - int /*recty*/, - const char * /*suffix*/, - ReportList * /*reports*/) +static bool append_stub(void * /*context_v*/, + RenderData * /*rd*/, + int /*start_frame*/, + int /*frame*/, + const ImBuf * /*image*/, + const char * /*suffix*/, + ReportList * /*reports*/) { - return 0; + return false; } static void *context_create_stub() diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc index 5acaddb6a09..76c1ad16040 100644 --- a/source/blender/render/intern/pipeline.cc +++ b/source/blender/render/intern/pipeline.cc @@ -2092,9 +2092,7 @@ bool RE_WriteRenderViewsMovie(ReportList *reports, rd, preview ? scene->r.psfra : scene->r.sfra, scene->r.cfra, - (int *)ibuf->byte_buffer.data, - ibuf->x, - ibuf->y, + ibuf, suffix, reports)) { @@ -2126,9 +2124,7 @@ bool RE_WriteRenderViewsMovie(ReportList *reports, rd, preview ? scene->r.psfra : scene->r.sfra, scene->r.cfra, - (int *)ibuf_arr[2]->byte_buffer.data, - ibuf_arr[2]->x, - ibuf_arr[2]->y, + ibuf_arr[2], "", reports)) {