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
This commit is contained in:
Aras Pranckevicius 2024-02-21 12:57:36 +01:00 committed by Aras Pranckevicius
parent eac8c381a0
commit e76b848697
5 changed files with 86 additions and 90 deletions

View File

@ -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,

View File

@ -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. */

View File

@ -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<FFMpegContext *>(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<FFMpegContext *>(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);
}
}
}

View File

@ -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()

View File

@ -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))
{