Discussion:
[Mlt-devel] Profile change of a created object (producer, consumer...)
alcinos
2017-03-12 22:34:41 UTC
Permalink
Hi everyone,

I have a question regarding profile change that I was not able to answer
from the doc.

The setting is the following: I have some Mlt objects (Producers and
Consumers) that are created with a given Profile 1, and then used for a bit.
Then I want to change the profile of all theses objects to another Profile
2 (without any assumptions on Profile 2, it may have different FPS,
ColorSpace,
)

What is the best method to do this? I've seen in the doc that the base
class "Service" has a setter "set_profile", but does that do what I expect
it to do ? In particular, if there are any filters attached to my objects
(created with the old Profile 1), how is that going to work?


Thanks in advance,

alcinos
Dan Dennedy
2017-03-13 03:17:43 UTC
Permalink
Post by alcinos
Hi everyone,
I have a question regarding profile change that I was not able to answer
from the doc.
The setting is the following: I have some Mlt objects (Producers and
Consumers) that are created with a given Profile 1, and then used for a bit.
Then I want to change the profile of all theses objects to another Profile
2 (without any assumptions on Profile 2, it may have different FPS,
ColorSpace,
)
What is the best method to do this? I've seen in the doc that the base
class "Service" has a setter "set_profile", but does that do what I expect
it to do ? In particular, if there are any filters attached to my objects
(created with the old Profile 1), how is that going to work?
Yes, set_profile() does what you want to do. I have never tried what you
want to do. If you try it, you should do it when the consumer is stopped.
In Shotcut, I update the existing profile using the attributes of a new,
different profile and then restart the consumer. That is easier than trying
to set_profile on all nodes of a potentially large graph.
See here:
https://github.com/mltframework/shotcut/blob/master/src/mltcontroller.cpp#L439

It is possible that a service has saved a value from the profile into
itself, but that should be very rare, and I do not recall any that do that.
alcinos
2017-03-13 14:17:47 UTC
Permalink
Thank you for your answer.
So if I understand correctly the logic of the code you've linked, if I
create my objects (filter, consumers, producers) with a pointer to the same
Profile object, then modifing properties of this profile object (fps, 
)
has the correct side-effects on all the other objects, is that it ? Besides
stopping the consumer(s), are there any pitfalls I should be aware of ?
Post by Dan Dennedy
Post by alcinos
Hi everyone,
I have a question regarding profile change that I was not able to answer
from the doc.
The setting is the following: I have some Mlt objects (Producers and
Consumers) that are created with a given Profile 1, and then used for a bit.
Then I want to change the profile of all theses objects to another
Profile 2 (without any assumptions on Profile 2, it may have different FPS,
ColorSpace,
)
What is the best method to do this? I've seen in the doc that the base
class "Service" has a setter "set_profile", but does that do what I expect
it to do ? In particular, if there are any filters attached to my objects
(created with the old Profile 1), how is that going to work?
Yes, set_profile() does what you want to do. I have never tried what you
want to do. If you try it, you should do it when the consumer is stopped.
In Shotcut, I update the existing profile using the attributes of a new,
different profile and then restart the consumer. That is easier than trying
to set_profile on all nodes of a potentially large graph.
See here: https://github.com/mltframework/shotcut/blob/
master/src/mltcontroller.cpp#L439
It is possible that a service has saved a value from the profile into
itself, but that should be very rare, and I do not recall any that do that.
Brian Matherly
2017-03-13 15:01:38 UTC
Permalink
Post by alcinos
Thank you for your answer.
So if I understand correctly the logic of the code you've linked, if I
create my objects (filter, consumers, producers) with a pointer to the
same Profile object, then modifing properties of this profile object
(fps, …) has the correct side-effects on all the other objects, is
that it ? Besides stopping the consumer(s), are there any pitfalls I
should be aware of ?
I expect that you would have some trouble with producers. Some producers
(e.g. avformat) calculate the length when they are first created. If you
change the profile to a different frame rate, I'm not sure if the length
will be re-calculated. You might need to experiment with that.

~Brian
alcinos
2017-03-14 10:09:45 UTC
Permalink
So I tried the following code:
Profile *profile1 = new Profile();

profile1->set_frame_rate(10,1);
profile1->set_explicit(true);

Producer producer(*profile1, "small_movie.mp4");

std::cout<<producer.get_playtime()<<std::endl;

profile1->set_frame_rate(15,1);
std::cout<<producer.get_playtime()<<std::endl;

producer.set_profile(*profile1);
std::cout<<producer.get_playtime()<<std::endl;


I would have expected it to print "10 15 15" or "10 10 15" but instead I
get "10 10 10", which tends to confirm what Brian pointed out.
So what's the best way to change profile in that case?

Thanks in advance
Post by Brian Matherly
Post by alcinos
Thank you for your answer.
So if I understand correctly the logic of the code you've linked, if I
create my objects (filter, consumers, producers) with a pointer to the same
Profile object, then modifing properties of this profile object (fps, 
)
has the correct side-effects on all the other objects, is that it ? Besides
stopping the consumer(s), are there any pitfalls I should be aware of ?
I expect that you would have some trouble with producers. Some producers
(e.g. avformat) calculate the length when they are first created. If you
change the profile to a different frame rate, I'm not sure if the length
will be re-calculated. You might need to experiment with that.
~Brian
Dan Dennedy
2017-03-14 15:31:27 UTC
Permalink
Why are you changing frame rate? There is no way to do what you are trying
to do at this time. After a change to add a no_profile option to the xml
consumer, you will have to serialize to XML using cock values for time and
then deserialize.
Post by alcinos
Profile *profile1 = new Profile();
profile1->set_frame_rate(10,1);
profile1->set_explicit(true);
Producer producer(*profile1, "small_movie.mp4");
std::cout<<producer.get_playtime()<<std::endl;
profile1->set_frame_rate(15,1);
std::cout<<producer.get_playtime()<<std::endl;
producer.set_profile(*profile1);
std::cout<<producer.get_playtime()<<std::endl;
I would have expected it to print "10 15 15" or "10 10 15" but instead I
get "10 10 10", which tends to confirm what Brian pointed out.
So what's the best way to change profile in that case?
Thanks in advance
Thank you for your answer.
So if I understand correctly the logic of the code you've linked, if I
create my objects (filter, consumers, producers) with a pointer to the same
Profile object, then modifing properties of this profile object (fps, 
)
has the correct side-effects on all the other objects, is that it ? Besides
stopping the consumer(s), are there any pitfalls I should be aware of ?
I expect that you would have some trouble with producers. Some producers
(e.g. avformat) calculate the length when they are first created. If you
change the profile to a different frame rate, I'm not sure if the length
will be re-calculated. You might need to experiment with that.
~Brian
alcinos
2017-03-14 18:21:21 UTC
Permalink
Hum the user could well change her mind about the FPS she wants to work
with


So what you are essentially advising is a clone of the producer ? Isn't
there a more direct way to do that than going to XML and back ? This is
slow and not proved to be thread safe (cf recent bugs
)
Post by Dan Dennedy
Why are you changing frame rate? There is no way to do what you are trying
to do at this time. After a change to add a no_profile option to the xml
consumer, you will have to serialize to XML using cock values for time and
then deserialize.
Post by alcinos
Profile *profile1 = new Profile();
profile1->set_frame_rate(10,1);
profile1->set_explicit(true);
Producer producer(*profile1, "small_movie.mp4");
std::cout<<producer.get_playtime()<<std::endl;
profile1->set_frame_rate(15,1);
std::cout<<producer.get_playtime()<<std::endl;
producer.set_profile(*profile1);
std::cout<<producer.get_playtime()<<std::endl;
I would have expected it to print "10 15 15" or "10 10 15" but instead I
get "10 10 10", which tends to confirm what Brian pointed out.
So what's the best way to change profile in that case?
Thanks in advance
Thank you for your answer.
So if I understand correctly the logic of the code you've linked, if I
create my objects (filter, consumers, producers) with a pointer to the same
Profile object, then modifing properties of this profile object (fps, 
)
has the correct side-effects on all the other objects, is that it ? Besides
stopping the consumer(s), are there any pitfalls I should be aware of ?
I expect that you would have some trouble with producers. Some producers
(e.g. avformat) calculate the length when they are first created. If you
change the profile to a different frame rate, I'm not sure if the length
will be re-calculated. You might need to experiment with that.
~Brian
Loading...