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:
parent
eac8c381a0
commit
e76b848697
|
@ -41,24 +41,24 @@ struct ReportList;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
struct SwsContext;
|
struct SwsContext;
|
||||||
|
|
||||||
int BKE_ffmpeg_start(void *context_v,
|
struct ImBuf;
|
||||||
const Scene *scene,
|
|
||||||
RenderData *rd,
|
bool BKE_ffmpeg_start(void *context_v,
|
||||||
int rectx,
|
const Scene *scene,
|
||||||
int recty,
|
|
||||||
ReportList *reports,
|
|
||||||
bool preview,
|
|
||||||
const char *suffix);
|
|
||||||
void BKE_ffmpeg_end(void *context_v);
|
|
||||||
int BKE_ffmpeg_append(void *context_v,
|
|
||||||
RenderData *rd,
|
RenderData *rd,
|
||||||
int start_frame,
|
|
||||||
int frame,
|
|
||||||
int *pixels,
|
|
||||||
int rectx,
|
int rectx,
|
||||||
int recty,
|
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],
|
void BKE_ffmpeg_filepath_get(char filepath[/*FILE_MAX*/ 1024],
|
||||||
const RenderData *rd,
|
const RenderData *rd,
|
||||||
bool preview,
|
bool preview,
|
||||||
|
|
|
@ -10,28 +10,27 @@
|
||||||
|
|
||||||
/* generic blender movie support, could move to own module */
|
/* generic blender movie support, could move to own module */
|
||||||
|
|
||||||
|
struct ImBuf;
|
||||||
struct RenderData;
|
struct RenderData;
|
||||||
struct ReportList;
|
struct ReportList;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
|
|
||||||
struct bMovieHandle {
|
struct bMovieHandle {
|
||||||
int (*start_movie)(void *context_v,
|
bool (*start_movie)(void *context_v,
|
||||||
const Scene *scene,
|
const Scene *scene,
|
||||||
RenderData *rd,
|
|
||||||
int rectx,
|
|
||||||
int recty,
|
|
||||||
ReportList *reports,
|
|
||||||
bool preview,
|
|
||||||
const char *suffix);
|
|
||||||
int (*append_movie)(void *context_v,
|
|
||||||
RenderData *rd,
|
RenderData *rd,
|
||||||
int start_frame,
|
|
||||||
int frame,
|
|
||||||
int *pixels,
|
|
||||||
int rectx,
|
int rectx,
|
||||||
int recty,
|
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);
|
void (*end_movie)(void *context_v);
|
||||||
|
|
||||||
/* Optional function. */
|
/* Optional function. */
|
||||||
|
|
|
@ -338,7 +338,7 @@ static const char **get_file_extensions(int format)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write a frame to the output file */
|
/* 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;
|
int ret, success = 1;
|
||||||
AVPacket *packet = av_packet_alloc();
|
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 */
|
/* 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;
|
AVCodecParameters *codec = context->video_stream->codecpar;
|
||||||
int height = codec->height;
|
int height = codec->height;
|
||||||
AVFrame *rgb_frame;
|
AVFrame *rgb_frame;
|
||||||
|
@ -1273,12 +1279,12 @@ static void ffmpeg_add_metadata_callback(void *data,
|
||||||
av_dict_set(metadata, propname, propvalue, 0);
|
av_dict_set(metadata, propname, propvalue, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int start_ffmpeg_impl(FFMpegContext *context,
|
static bool start_ffmpeg_impl(FFMpegContext *context,
|
||||||
RenderData *rd,
|
RenderData *rd,
|
||||||
int rectx,
|
int rectx,
|
||||||
int recty,
|
int recty,
|
||||||
const char *suffix,
|
const char *suffix,
|
||||||
ReportList *reports)
|
ReportList *reports)
|
||||||
{
|
{
|
||||||
/* Handle to the output file */
|
/* Handle to the output file */
|
||||||
AVFormatContext *of;
|
AVFormatContext *of;
|
||||||
|
@ -1324,19 +1330,19 @@ static int start_ffmpeg_impl(FFMpegContext *context,
|
||||||
exts = get_file_extensions(context->ffmpeg_type);
|
exts = get_file_extensions(context->ffmpeg_type);
|
||||||
if (!exts) {
|
if (!exts) {
|
||||||
BKE_report(reports, RPT_ERROR, "No valid formats found");
|
BKE_report(reports, RPT_ERROR, "No valid formats found");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt = av_guess_format(nullptr, exts[0], nullptr);
|
fmt = av_guess_format(nullptr, exts[0], nullptr);
|
||||||
if (!fmt) {
|
if (!fmt) {
|
||||||
BKE_report(reports, RPT_ERROR, "No valid formats found");
|
BKE_report(reports, RPT_ERROR, "No valid formats found");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
of = avformat_alloc_context();
|
of = avformat_alloc_context();
|
||||||
if (!of) {
|
if (!of) {
|
||||||
BKE_report(reports, RPT_ERROR, "Can't allocate FFmpeg format context");
|
BKE_report(reports, RPT_ERROR, "Can't allocate FFmpeg format context");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AVCodecID audio_codec = context->ffmpeg_audio_codec;
|
enum AVCodecID audio_codec = context->ffmpeg_audio_codec;
|
||||||
|
@ -1469,7 +1475,7 @@ static int start_ffmpeg_impl(FFMpegContext *context,
|
||||||
context->outfile = of;
|
context->outfile = of;
|
||||||
av_dump_format(of, 0, filepath, 1);
|
av_dump_format(of, 0, filepath, 1);
|
||||||
|
|
||||||
return 1;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (of->pb) {
|
if (of->pb) {
|
||||||
|
@ -1485,7 +1491,7 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
avformat_free_context(of);
|
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);
|
ffmpeg_filepath_get(nullptr, filepath, rd, preview, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
int BKE_ffmpeg_start(void *context_v,
|
bool BKE_ffmpeg_start(void *context_v,
|
||||||
const Scene *scene,
|
const Scene *scene,
|
||||||
RenderData *rd,
|
RenderData *rd,
|
||||||
int rectx,
|
int rectx,
|
||||||
int recty,
|
int recty,
|
||||||
ReportList *reports,
|
ReportList *reports,
|
||||||
bool preview,
|
bool preview,
|
||||||
const char *suffix)
|
const char *suffix)
|
||||||
{
|
{
|
||||||
int success;
|
|
||||||
FFMpegContext *context = static_cast<FFMpegContext *>(context_v);
|
FFMpegContext *context = static_cast<FFMpegContext *>(context_v);
|
||||||
|
|
||||||
context->ffmpeg_autosplit_count = 0;
|
context->ffmpeg_autosplit_count = 0;
|
||||||
context->ffmpeg_preview = preview;
|
context->ffmpeg_preview = preview;
|
||||||
context->stamp_data = BKE_stamp_info_from_scene_static(scene);
|
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
|
# ifdef WITH_AUDASPACE
|
||||||
if (context->audio_stream) {
|
if (context->audio_stream) {
|
||||||
AVCodecContext *c = context->audio_codec;
|
AVCodecContext *c = context->audio_codec;
|
||||||
|
@ -1699,24 +1704,22 @@ static void write_audio_frames(FFMpegContext *context, double to_pts)
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
int BKE_ffmpeg_append(void *context_v,
|
bool BKE_ffmpeg_append(void *context_v,
|
||||||
RenderData *rd,
|
RenderData *rd,
|
||||||
int start_frame,
|
int start_frame,
|
||||||
int frame,
|
int frame,
|
||||||
int *pixels,
|
const ImBuf *image,
|
||||||
int rectx,
|
const char *suffix,
|
||||||
int recty,
|
ReportList *reports)
|
||||||
const char *suffix,
|
|
||||||
ReportList *reports)
|
|
||||||
{
|
{
|
||||||
FFMpegContext *context = static_cast<FFMpegContext *>(context_v);
|
FFMpegContext *context = static_cast<FFMpegContext *>(context_v);
|
||||||
AVFrame *avframe;
|
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) {
|
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));
|
success = (avframe && write_video_frame(context, avframe, reports));
|
||||||
# ifdef WITH_AUDASPACE
|
# ifdef WITH_AUDASPACE
|
||||||
/* Add +1 frame because we want to encode audio up until the next video frame. */
|
/* 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);
|
end_ffmpeg_impl(context, true);
|
||||||
context->ffmpeg_autosplit_count++;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,31 +23,29 @@
|
||||||
|
|
||||||
#include "BKE_writemovie.hh"
|
#include "BKE_writemovie.hh"
|
||||||
|
|
||||||
static int start_stub(void * /*context_v*/,
|
static bool start_stub(void * /*context_v*/,
|
||||||
const Scene * /*scene*/,
|
const Scene * /*scene*/,
|
||||||
RenderData * /*rd*/,
|
RenderData * /*rd*/,
|
||||||
int /*rectx*/,
|
int /*rectx*/,
|
||||||
int /*recty*/,
|
int /*recty*/,
|
||||||
ReportList * /*reports*/,
|
ReportList * /*reports*/,
|
||||||
bool /*preview*/,
|
bool /*preview*/,
|
||||||
const char * /*suffix*/)
|
const char * /*suffix*/)
|
||||||
{
|
{
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_stub(void * /*context_v*/) {}
|
static void end_stub(void * /*context_v*/) {}
|
||||||
|
|
||||||
static int append_stub(void * /*context_v*/,
|
static bool append_stub(void * /*context_v*/,
|
||||||
RenderData * /*rd*/,
|
RenderData * /*rd*/,
|
||||||
int /*start_frame*/,
|
int /*start_frame*/,
|
||||||
int /*frame*/,
|
int /*frame*/,
|
||||||
int * /*pixels*/,
|
const ImBuf * /*image*/,
|
||||||
int /*rectx*/,
|
const char * /*suffix*/,
|
||||||
int /*recty*/,
|
ReportList * /*reports*/)
|
||||||
const char * /*suffix*/,
|
|
||||||
ReportList * /*reports*/)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *context_create_stub()
|
static void *context_create_stub()
|
||||||
|
|
|
@ -2092,9 +2092,7 @@ bool RE_WriteRenderViewsMovie(ReportList *reports,
|
||||||
rd,
|
rd,
|
||||||
preview ? scene->r.psfra : scene->r.sfra,
|
preview ? scene->r.psfra : scene->r.sfra,
|
||||||
scene->r.cfra,
|
scene->r.cfra,
|
||||||
(int *)ibuf->byte_buffer.data,
|
ibuf,
|
||||||
ibuf->x,
|
|
||||||
ibuf->y,
|
|
||||||
suffix,
|
suffix,
|
||||||
reports))
|
reports))
|
||||||
{
|
{
|
||||||
|
@ -2126,9 +2124,7 @@ bool RE_WriteRenderViewsMovie(ReportList *reports,
|
||||||
rd,
|
rd,
|
||||||
preview ? scene->r.psfra : scene->r.sfra,
|
preview ? scene->r.psfra : scene->r.sfra,
|
||||||
scene->r.cfra,
|
scene->r.cfra,
|
||||||
(int *)ibuf_arr[2]->byte_buffer.data,
|
ibuf_arr[2],
|
||||||
ibuf_arr[2]->x,
|
|
||||||
ibuf_arr[2]->y,
|
|
||||||
"",
|
"",
|
||||||
reports))
|
reports))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue