Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/video_edit.cc
- This file was added.
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | |||||
| /** \file | |||||
| * \ingroup bke | |||||
| */ | |||||
| #include <string.h> | |||||
| #include "MEM_guardedalloc.h" | |||||
| #include "DNA_color_types.h" | |||||
| #include "DNA_defaults.h" | |||||
| #include "DNA_scene_types.h" | |||||
| #include "DNA_video_edit_types.h" | |||||
| #include "BLI_string.h" | |||||
| #include "BLI_utildefines.h" | |||||
| #include "BKE_anim_data.h" | |||||
| #include "BKE_animsys.h" | |||||
| #include "BKE_colortools.h" | |||||
| #include "BKE_idtype.h" | |||||
| #include "BKE_image_format.h" | |||||
| #include "BKE_lib_id.h" | |||||
| #include "BKE_video_edit.h" | |||||
| #include "BKE_idprop.h" | |||||
| #include "BLT_translation.h" | |||||
| #include "BLO_read_write.h" | |||||
| #include "BLO_readfile.h" | |||||
| #include "IMB_colormanagement.h" | |||||
| #include "SEQ_sequencer.h" | |||||
| static void video_edit_init_data(ID *id) | |||||
| { | |||||
| VideoEdit *video_edit = (VideoEdit *)id; | |||||
| BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(video_edit, id)); | |||||
| MEMCPY_STRUCT_AFTER(video_edit, DNA_struct_default_get(VideoEdit), id); | |||||
| video_edit->toolsettings = SEQ_tool_settings_init(); | |||||
| BLI_strncpy(video_edit->r.bake.filepath, U.renderdir, sizeof(video_edit->r.bake.filepath)); | |||||
| BLI_strncpy(video_edit->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(video_edit->r.engine)); | |||||
| BLI_strncpy(video_edit->r.pic, U.renderdir, sizeof(video_edit->r.pic)); | |||||
| CurveMapping *mblur_shutter_curve = &video_edit->r.mblur_shutter_curve; | |||||
| BKE_curvemapping_set_defaults(mblur_shutter_curve, 1, 0.0f, 0.0f, 1.0f, 1.0f); | |||||
| BKE_curvemapping_init(mblur_shutter_curve); | |||||
| BKE_curvemap_reset(mblur_shutter_curve->cm, | |||||
| &mblur_shutter_curve->clipr, | |||||
| CURVE_PRESET_MAX, | |||||
| CURVEMAP_SLOPE_POS_NEG); | |||||
| const char *colorspace_name = IMB_colormanagement_role_colorspace_name_get( | |||||
| COLOR_ROLE_DEFAULT_SEQUENCER); | |||||
| BKE_color_managed_display_settings_init(&video_edit->display_settings); | |||||
| BKE_color_managed_view_settings_init_render( | |||||
| &video_edit->view_settings, &video_edit->display_settings, "Filmic"); | |||||
| BLI_strncpy(video_edit->sequencer_colorspace_settings.name, | |||||
| colorspace_name, | |||||
| sizeof(video_edit->sequencer_colorspace_settings.name)); | |||||
| BKE_image_format_init(&video_edit->r.im_format, true); | |||||
| BKE_image_format_init(&video_edit->r.bake.im_format, true); | |||||
| /* TODO: multiview - stereo */ | |||||
| // BKE_scene_add_render_view(scene, STEREO_LEFT_NAME); | |||||
| // srv = static_cast<SceneRenderView *>(scene->r.views.first); | |||||
| // BLI_strncpy(srv->suffix, STEREO_LEFT_SUFFIX, sizeof(srv->suffix)); | |||||
| // BKE_scene_add_render_view(scene, STEREO_RIGHT_NAME); | |||||
| // srv = static_cast<SceneRenderView *>(scene->r.views.last); | |||||
| // BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix)); | |||||
| } | |||||
| static void video_edit_copy_data(Main *UNUSED(bmain), | |||||
| ID *UNUSED(id_dst), | |||||
| const ID *UNUSED(id_src), | |||||
| const int UNUSED(flag)) | |||||
| { | |||||
| /** TODO. */ | |||||
| } | |||||
| static void video_edit_free_data(ID *id) | |||||
| { | |||||
| VideoEdit *video_edit = (VideoEdit *)id; | |||||
| BKE_animdata_free(&video_edit->id, false); | |||||
| MEM_freeN(video_edit->toolsettings); | |||||
| video_edit->toolsettings = nullptr; | |||||
| if (video_edit->r.avicodecdata) { | |||||
| AviCodecData *acd = video_edit->r.avicodecdata; | |||||
| if (acd->lpFormat) { | |||||
| MEM_freeN(acd->lpFormat); | |||||
| acd->lpFormat = nullptr; | |||||
| acd->cbFormat = 0; | |||||
| } | |||||
| if (acd->lpParms) { | |||||
| MEM_freeN(acd->lpParms); | |||||
| acd->lpParms = nullptr; | |||||
| acd->cbParms = 0; | |||||
| } | |||||
| MEM_freeN(acd); | |||||
| video_edit->r.avicodecdata = nullptr; | |||||
| } | |||||
| BKE_image_format_free(&video_edit->r.im_format); | |||||
| BKE_image_format_free(&video_edit->r.bake.im_format); | |||||
| BKE_curvemapping_free_data(&video_edit->r.mblur_shutter_curve); | |||||
| BKE_video_edit_data_delete(video_edit, false); | |||||
| } | |||||
| static void video_edit_blend_write(BlendWriter *writer, ID *id, const void *id_address) | |||||
| { | |||||
| VideoEdit *video_edit = (VideoEdit *)id; | |||||
| BLO_write_id_struct(writer, VideoEdit, id_address, &video_edit->id); | |||||
| BKE_id_blend_write(writer, &video_edit->id); | |||||
| if (video_edit->adt) { | |||||
| BKE_animdata_blend_write(writer, video_edit->adt); | |||||
| } | |||||
| SequencerToolSettings *ts = video_edit->toolsettings; | |||||
| BLO_write_struct(writer, SequencerToolSettings, ts); | |||||
| LISTBASE_FOREACH (TimeMarker *, marker, &video_edit->markers) { | |||||
| BLO_write_struct(writer, TimeMarker, marker); | |||||
| if (marker->prop != nullptr) { | |||||
| IDP_BlendWrite(writer, marker->prop); | |||||
| } | |||||
| } | |||||
| SEQ_blend_write(writer, &video_edit->seqbase); | |||||
| LISTBASE_FOREACH (SeqTimelineChannel *, channel, &video_edit->channels) { | |||||
| BLO_write_struct(writer, SeqTimelineChannel, channel); | |||||
| } | |||||
| LISTBASE_FOREACH (MetaStack *, ms, &video_edit->metastack) { | |||||
| BLO_write_struct(writer, MetaStack, ms); | |||||
| } | |||||
| if (video_edit->r.avicodecdata) { | |||||
| BLO_write_struct(writer, AviCodecData, video_edit->r.avicodecdata); | |||||
| if (video_edit->r.avicodecdata->lpFormat) { | |||||
| BLO_write_raw(writer, | |||||
| size_t(video_edit->r.avicodecdata->cbFormat), | |||||
| video_edit->r.avicodecdata->lpFormat); | |||||
| } | |||||
| if (video_edit->r.avicodecdata->lpParms) { | |||||
| BLO_write_raw(writer, | |||||
| size_t(video_edit->r.avicodecdata->cbParms), | |||||
| video_edit->r.avicodecdata->lpParms); | |||||
| } | |||||
| } | |||||
| BKE_color_managed_view_settings_blend_write(writer, &video_edit->view_settings); | |||||
| BKE_image_format_blend_write(writer, &video_edit->r.im_format); | |||||
| BKE_image_format_blend_write(writer, &video_edit->r.bake.im_format); | |||||
| BKE_curvemapping_curves_blend_write(writer, &video_edit->r.mblur_shutter_curve); | |||||
| } | |||||
| /** Copied from scene.cc */ | |||||
| static void link_recurs_seq(BlendDataReader *reader, ListBase *lb) | |||||
| { | |||||
| BLO_read_list(reader, lb); | |||||
| LISTBASE_FOREACH_MUTABLE (Sequence *, seq, lb) { | |||||
| /* Sanity check. */ | |||||
| if (!SEQ_valid_strip_channel(seq)) { | |||||
| BLI_freelinkN(lb, seq); | |||||
| BLO_read_data_reports(reader)->count.sequence_strips_skipped++; | |||||
| } | |||||
| else if (seq->seqbase.first) { | |||||
| link_recurs_seq(reader, &seq->seqbase); | |||||
| } | |||||
| } | |||||
| } | |||||
| static void video_edit_blend_read_data(BlendDataReader *reader, ID *id) | |||||
| { | |||||
| VideoEdit *video_edit = (VideoEdit *)id; | |||||
| id_us_ensure_real(&video_edit->id); | |||||
| BLO_read_data_address(reader, &video_edit->adt); | |||||
| BKE_animdata_blend_read_data(reader, video_edit->adt); | |||||
| BLO_read_data_address(reader, &video_edit->toolsettings); | |||||
| BLO_read_list(reader, &(video_edit->markers)); | |||||
| LISTBASE_FOREACH (TimeMarker *, marker, &video_edit->markers) { | |||||
| BLO_read_data_address(reader, &marker->prop); | |||||
| IDP_BlendDataRead(reader, &marker->prop); | |||||
| } | |||||
| ListBase *old_seqbasep = &video_edit->seqbase; | |||||
| ListBase *old_displayed_channels = &video_edit->channels; | |||||
| BLO_read_data_address(reader, &video_edit); | |||||
| BLO_read_data_address(reader, &video_edit->act_seq); | |||||
| video_edit->cache = nullptr; | |||||
| video_edit->prefetch_job = nullptr; | |||||
| video_edit->runtime.sequence_lookup = nullptr; | |||||
| link_recurs_seq(reader, &video_edit->seqbase); | |||||
| SEQ_blend_read(reader, &video_edit->seqbase); | |||||
| BLO_read_list(reader, &video_edit->channels); | |||||
| Sequence temp; | |||||
| void *seqbase_poin; | |||||
| void *channels_poin; | |||||
| intptr_t seqbase_offset; | |||||
| intptr_t channels_offset; | |||||
| seqbase_offset = intptr_t(&(temp).seqbase) - intptr_t(&temp); | |||||
| channels_offset = intptr_t(&(temp).channels) - intptr_t(&temp); | |||||
| /* seqbase root pointer */ | |||||
| if (video_edit->seqbasep == old_seqbasep) { | |||||
| video_edit->seqbasep = &video_edit->seqbase; | |||||
| } | |||||
| else { | |||||
| seqbase_poin = POINTER_OFFSET(video_edit->seqbasep, -seqbase_offset); | |||||
| seqbase_poin = BLO_read_get_new_data_address(reader, seqbase_poin); | |||||
| if (seqbase_poin) { | |||||
| video_edit->seqbasep = (ListBase *)POINTER_OFFSET(seqbase_poin, seqbase_offset); | |||||
| } | |||||
| else { | |||||
| video_edit->seqbasep = &video_edit->seqbase; | |||||
| } | |||||
| } | |||||
| /* Active channels root pointer. */ | |||||
| if (ELEM(video_edit->displayed_channels, old_displayed_channels, nullptr)) { | |||||
| video_edit->displayed_channels = &video_edit->channels; | |||||
| } | |||||
| else { | |||||
| channels_poin = POINTER_OFFSET(video_edit->displayed_channels, -channels_offset); | |||||
| channels_poin = BLO_read_get_new_data_address(reader, channels_poin); | |||||
| if (channels_poin) { | |||||
| video_edit->displayed_channels = (ListBase *)POINTER_OFFSET(channels_poin, channels_offset); | |||||
| } | |||||
| else { | |||||
| video_edit->displayed_channels = &video_edit->channels; | |||||
| } | |||||
| } | |||||
| BLO_read_list(reader, &(video_edit->metastack)); | |||||
| LISTBASE_FOREACH (MetaStack *, ms, &video_edit->metastack) { | |||||
| BLO_read_data_address(reader, &ms->parseq); | |||||
| if (ms->oldbasep == old_seqbasep) { | |||||
| ms->oldbasep = &video_edit->seqbase; | |||||
| } | |||||
| else { | |||||
| seqbase_poin = POINTER_OFFSET(ms->oldbasep, -seqbase_offset); | |||||
| seqbase_poin = BLO_read_get_new_data_address(reader, seqbase_poin); | |||||
| if (seqbase_poin) { | |||||
| ms->oldbasep = (ListBase *)POINTER_OFFSET(seqbase_poin, seqbase_offset); | |||||
| } | |||||
| else { | |||||
| ms->oldbasep = &video_edit->seqbase; | |||||
| } | |||||
| } | |||||
| if (ELEM(ms->old_channels, old_displayed_channels, nullptr)) { | |||||
| ms->old_channels = &video_edit->channels; | |||||
| } | |||||
| else { | |||||
| channels_poin = POINTER_OFFSET(ms->old_channels, -channels_offset); | |||||
| channels_poin = BLO_read_get_new_data_address(reader, channels_poin); | |||||
| if (channels_poin) { | |||||
| ms->old_channels = (ListBase *)POINTER_OFFSET(channels_poin, channels_offset); | |||||
| } | |||||
| else { | |||||
| ms->old_channels = &video_edit->channels; | |||||
| } | |||||
| } | |||||
| } | |||||
| BLO_read_data_address(reader, &video_edit->r.avicodecdata); | |||||
| if (video_edit->r.avicodecdata) { | |||||
| BLO_read_data_address(reader, &video_edit->r.avicodecdata->lpFormat); | |||||
| BLO_read_data_address(reader, &video_edit->r.avicodecdata->lpParms); | |||||
| } | |||||
| BKE_color_managed_view_settings_blend_read_data(reader, &video_edit->view_settings); | |||||
| BKE_image_format_blend_read_data(reader, &video_edit->r.im_format); | |||||
| BKE_image_format_blend_read_data(reader, &video_edit->r.bake.im_format); | |||||
| BKE_curvemapping_blend_read(reader, &video_edit->r.mblur_shutter_curve); | |||||
| } | |||||
| static void video_edit_blend_read_lib(BlendLibReader *reader, ID *id) | |||||
| { | |||||
| VideoEdit *video_edit = (VideoEdit *)id; | |||||
| SEQ_blend_read_lib(reader, &video_edit->id, &video_edit->seqbase); | |||||
| } | |||||
| static void video_edit_blend_read_expand(BlendExpander *expander, ID *id) | |||||
| { | |||||
| VideoEdit *video_edit = (VideoEdit *)id; | |||||
| SEQ_blend_read_expand(expander, &video_edit->seqbase); | |||||
| } | |||||
| IDTypeInfo IDType_ID_VE = { | |||||
| /* id_code */ ID_VE, | |||||
| /* id_filter */ FILTER_ID_VE, | |||||
| /* main_listbase_index */ INDEX_ID_VE, | |||||
| /* struct_size */ sizeof(VideoEdit), | |||||
| /* name */ "VideoEdit", | |||||
| /* name_plural */ "video_edits", | |||||
| /* translation_context */ BLT_I18NCONTEXT_ID_VIDEOEDIT, | |||||
| /* flags */ 0, | |||||
| /* asset_type_info */ nullptr, | |||||
| /* init_data */ video_edit_init_data, | |||||
| /* copy_data */ video_edit_copy_data, | |||||
| /* free_data */ video_edit_free_data, | |||||
| /* make_local */ nullptr, | |||||
| /* foreach_id */ nullptr, | |||||
| /* foreach_cache */ nullptr, | |||||
| /* foreach_path */ nullptr, | |||||
| /* owner_pointer_get */ nullptr, | |||||
| /* blend_write */ video_edit_blend_write, | |||||
| /* blend_read_data */ video_edit_blend_read_data, | |||||
| /* blend_read_lib */ video_edit_blend_read_lib, | |||||
| /* blend_read_expand */ video_edit_blend_read_expand, | |||||
| /* blend_read_undo_preserve */ nullptr, | |||||
| /* lib_override_apply_post */ nullptr, | |||||
| }; | |||||
| void *BKE_video_edit_add(Main *bmain, const char *name) | |||||
| { | |||||
| VideoEdit *video_edit = static_cast<VideoEdit *>(BKE_id_new(bmain, ID_VE, name)); | |||||
| id_us_min(&video_edit->id); | |||||
| id_us_ensure_real(&video_edit->id); | |||||
| return video_edit; | |||||
| } | |||||
| void BKE_video_edit_data_delete(VideoEdit *video_edit, const bool do_id_user) | |||||
| { | |||||
| if (video_edit == nullptr) { | |||||
| return; | |||||
| } | |||||
| SEQ_editing_free_ex(nullptr, | |||||
| video_edit->prefetch_job, | |||||
| video_edit->cache, | |||||
| &video_edit->seqbase, | |||||
| &video_edit->metastack, | |||||
| &video_edit->channels, | |||||
| video_edit->runtime.sequence_lookup, | |||||
| do_id_user); | |||||
| video_edit->act_seq = nullptr; | |||||
| } | |||||