-
Notifications
You must be signed in to change notification settings - Fork 324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upstreaming Krita Animation Plugin #961
Closed
emmetoneillpdx
wants to merge
16
commits into
mltframework:master
from
emmetoneillpdx:mlt-krita-plugins
Closed
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
1458c3e
Initial krita repository setup...
Eoin-ONeill-Yokai b4a8bea
More krita work.
Eoin-ONeill-Yokai 69d38f0
Added more options to enable or disable frame range limits.
Eoin-ONeill-Yokai bc2fd9d
Add support for variable play speeds.
Eoin-ONeill-Yokai 3679229
Remove remnants of old experimentation.
Eoin-ONeill-Yokai a027ac2
Fix compilation on Windows with Clang 15
dimula73 5761ef3
Renamed 'producer_ranged' to 'producer_krita'.
emmetoneillpdx 27de4d0
Fix rename of the files producer_ranged -> producer_krita
dimula73 175c9f2
Fix a memory leak in the MLT's producer_krita
dimula73 5be2320
Fix two memory leaks in MLT library
dimula73 238f40a
Ran clang-format on appropriate files.
emmetoneillpdx cb16673
Fixup incorrect info in producer_krita.c file header.
emmetoneillpdx 1ece39e
Improved producer_krita.yml manifest information.
emmetoneillpdx bc24505
Fixed bad strcmps and cleaned up property_changed func.
emmetoneillpdx 4bbdcfa
Cleanup: Stripped out a bunch of unneeded stuff.
emmetoneillpdx e3b0de9
Removed incorrect information from comment.
emmetoneillpdx File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
add_library(mltkrita MODULE | ||
factory.c | ||
producer_krita.c | ||
) | ||
|
||
target_compile_options(mltkrita PRIVATE ${MLT_COMPILE_OPTIONS}) | ||
|
||
target_link_libraries(mltkrita PRIVATE mlt m) | ||
|
||
set_target_properties(mltkrita PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") | ||
|
||
install(TARGETS mltkrita LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) | ||
|
||
install(FILES | ||
producer_krita.yml | ||
DESTINATION ${MLT_INSTALL_DATA_DIR}/krita | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* factory.c -- the factory method interfaces | ||
* Copyright (C) 2022 Eoin O'Neill <eoinoneill1991@gmail.com> | ||
* Copyright (C) 2022 Emmet O'Neill <emmetoneill.pdx@gmail.com> | ||
* | ||
* This library is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 2.1 of the License, or (at your option) any later version. | ||
* | ||
* This library is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this library; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
|
||
#include <framework/mlt.h> | ||
#include <limits.h> | ||
#include <string.h> | ||
|
||
extern mlt_producer producer_krita_init(mlt_profile profile, | ||
mlt_service_type type, | ||
const char *id, | ||
char *arg); | ||
|
||
static mlt_properties metadata(mlt_service_type type, const char *id, void *data) | ||
{ | ||
char file[PATH_MAX]; | ||
snprintf(file, PATH_MAX, "%s/krita/%s", mlt_environment("MLT_DATA"), (char *) data); | ||
return mlt_properties_parse_yaml(file); | ||
} | ||
|
||
MLT_REPOSITORY | ||
{ | ||
MLT_REGISTER(mlt_service_producer_type, "krita", producer_krita_init); | ||
MLT_REGISTER_METADATA(mlt_service_producer_type, "krita", metadata, "producer_krita.yml"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
/* | ||
* producer_krita.c -- Produces variable-speed audio within a restricted range of frames. Used internally by Krita to drive audio-synced animation playback. | ||
* Copyright (C) 2022 Eoin O'Neill <eoinoneill1991@gmail.com> | ||
* Copyright (C) 2022 Emmet O'Neill <emmetoneill.pdx@gmail.com> | ||
* | ||
* This library is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 2.1 of the License, or (at your option) any later version. | ||
* | ||
* This library is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this library; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
|
||
#include <framework/mlt.h> | ||
#include <limits.h> | ||
#include <math.h> | ||
#include <stdbool.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#include <framework/mlt_factory.h> | ||
#include <framework/mlt_frame.h> | ||
#include <framework/mlt_producer.h> | ||
#include <framework/mlt_property.h> | ||
#include <framework/mlt_service.h> | ||
|
||
typedef struct | ||
{ | ||
mlt_producer producer_internal; | ||
} private_data; | ||
|
||
/** Restricts frame index to within range by modulus wrapping (not clamping). | ||
*/ | ||
static int restrict_range(int index, int min, int max) | ||
{ | ||
const int span = max - min; | ||
return (MAX(index - min, 0) % (span + 1)) + min; | ||
} | ||
|
||
static int is_valid_range(const int frame_start, const int frame_end) | ||
{ | ||
const bool NON_NEGATIVE = frame_start >= 0 && frame_end >= 0; | ||
const bool NON_INVERTED = frame_end > frame_start; | ||
|
||
return NON_NEGATIVE && NON_INVERTED; | ||
} | ||
|
||
static int producer_get_audio(mlt_frame frame, | ||
void **buffer, | ||
mlt_audio_format *format, | ||
int *frequency, | ||
int *channels, | ||
int *samples) | ||
{ | ||
mlt_producer producer = mlt_frame_pop_audio(frame); | ||
|
||
struct mlt_audio_s audio; | ||
|
||
mlt_audio_set_values(&audio, *buffer, *frequency, *format, *samples, *channels); | ||
|
||
int error = mlt_frame_get_audio(frame, | ||
&audio.data, | ||
&audio.format, | ||
&audio.frequency, | ||
&audio.channels, | ||
&audio.samples); | ||
|
||
mlt_properties props = MLT_PRODUCER_PROPERTIES(producer); | ||
|
||
// Scale the frequency to account for the dynamic speed (normalized). | ||
const double SPEED = mlt_properties_get_double(props, "speed"); | ||
|
||
audio.frequency = (double) audio.frequency * fabs(SPEED); | ||
if (SPEED < 0.0) { | ||
mlt_audio_reverse(&audio); | ||
} | ||
|
||
mlt_audio_get_values(&audio, buffer, frequency, format, samples, channels); | ||
|
||
return error; | ||
} | ||
|
||
static int producer_get_frame(mlt_producer producer, mlt_frame_ptr frame, int index) | ||
{ | ||
mlt_properties props = MLT_PRODUCER_PROPERTIES(producer); | ||
const int FRAME_START = mlt_properties_get_int(props, "start_frame"); | ||
const int FRAME_END = mlt_properties_get_int(props, "end_frame"); | ||
const bool IS_RANGE_LIMITED = mlt_properties_get_int(props, "limit_enabled"); | ||
|
||
private_data *pdata = (private_data *) producer->child; | ||
const int POSITION = mlt_producer_position(pdata->producer_internal); | ||
|
||
if (IS_RANGE_LIMITED && is_valid_range(FRAME_START, FRAME_END)) { | ||
mlt_properties_set_position(MLT_PRODUCER_PROPERTIES(pdata->producer_internal), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does mlt_producer_seek() work here instead of modifying a private property directly? |
||
"_position", | ||
restrict_range(POSITION, FRAME_START, FRAME_END)); | ||
} | ||
|
||
int retval = mlt_service_get_frame((mlt_service) pdata->producer_internal, frame, index); | ||
|
||
if (!mlt_frame_is_test_audio(*frame)) { | ||
mlt_frame_push_audio(*frame, producer); | ||
mlt_frame_push_audio(*frame, producer_get_audio); | ||
} | ||
|
||
return retval; | ||
} | ||
|
||
static int producer_seek(mlt_producer producer, mlt_position position) | ||
{ | ||
private_data *pdata = (private_data *) producer->child; | ||
|
||
int retval = mlt_producer_seek(pdata->producer_internal, position); | ||
|
||
return retval; | ||
} | ||
|
||
static void producer_close(mlt_producer producer) | ||
{ | ||
private_data *pdata = (private_data *) producer->child; | ||
|
||
if (pdata) { | ||
mlt_producer_close(pdata->producer_internal); | ||
free(pdata); | ||
} | ||
|
||
producer->close = NULL; | ||
mlt_producer_close(producer); | ||
free(producer); | ||
} | ||
|
||
/** Constructor for the producer. | ||
*/ | ||
mlt_producer producer_krita_init(mlt_profile profile, | ||
mlt_service_type type, | ||
const char *id, | ||
char *arg) | ||
{ | ||
// Create a new producer object | ||
mlt_producer producer = mlt_producer_new(profile); | ||
private_data *pdata = (private_data *) calloc(1, sizeof(private_data)); | ||
|
||
if (arg && producer && pdata) { | ||
mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES(producer); | ||
|
||
// Initialize the producer | ||
mlt_properties_set(producer_properties, "resource", arg); | ||
producer->child = pdata; | ||
producer->get_frame = producer_get_frame; | ||
producer->seek = producer_seek; | ||
producer->close = (mlt_destructor) producer_close; | ||
|
||
// Get the resource to be passed to the clip producer | ||
char *resource = arg; | ||
|
||
// Create internal producer | ||
pdata->producer_internal = mlt_factory_producer(profile, "abnormal", resource); | ||
|
||
if (pdata->producer_internal) { | ||
mlt_producer_set_speed(pdata->producer_internal, 1.0); | ||
} | ||
} | ||
|
||
const bool INVALID_CONTEXT = !producer || !pdata || !pdata->producer_internal; | ||
if (INVALID_CONTEXT) { // Clean up early... | ||
if (pdata) { | ||
mlt_producer_close(pdata->producer_internal); | ||
free(pdata); | ||
} | ||
|
||
if (producer) { | ||
producer->child = NULL; | ||
producer->close = NULL; | ||
mlt_producer_close(producer); | ||
free(producer); | ||
producer = NULL; | ||
} | ||
} | ||
|
||
return producer; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation of this is still wrong; it uses 4 spaces now instead of tabs. Our
.clang-format
file covers that.