Openshot-qt: Importing many pictures slow

Created on 26 Dec 2016  路  15Comments  路  Source: OpenShot/openshot-qt

Openshot 2.2.0:
Importing just 74 pictures (each 1024x768) is very slow.
I've observed that the project files view is updated (completely redrawn) for each new imported file.
Better: Do a delayed redraw and update only the region which has changed. If sorting matters then sort the files when the import has finished.
I'm not sure if you use multithreading/multiprocessing for file import. If not then please use this.

Best regards,

Martin

bug

Most helpful comment

This might not be the right spot but while looking for fixes i figured out a workaround for this issue which speeds importing images up quite a lot and might help someone in my situation.

I start the images importing then i click into the Video tab (which in my case is empty), that way it doesn't constantly refresh and it seems to import at about 15% extra CPU load and about 10x as quick. Hope this is helpful in some way, first time I've registered an account here and i'm not a programmer... Maybe you could code it to change tab to video whenever importing images and vice versa just as a temp fix?

Cheers, Cod

All 15 comments

550

@brmmm3 - I agree. It is very slow and also does redraw the files area after every file import.

This issue has been tested with the latest version. I confirm that it does not exist anymore.

This issue has been tested with the latest version. I confirm that it does not exist anymore.

Please test again. It most definitely does still exist.

(Also, just to be a pedant, you can't "confirm" something that nobody has claimed before.)

Oh, wow. And actually, if you want to see _really_ slow, select all of those $many_dozen imported images and choose "Remove from Project...". That trundles along at about half the speed of the (slow) import process. This is all due to the fact that OpenShot unnecessarily rebuilds (not just redraws, but actually _deletes_ and completely recreates) the Files model for each and every individual add/remove operation..

(Also, just to be a pedant, you can't "confirm" something that nobody has claimed before.)

copy that @ferdnyc thanks!

Oh, wow. And actually, if you want to see _really_ slow, select all of those $many_dozen imported images and choose "Remove from Project...". That trundles along at about half the speed of the (slow) import process. This is all due to the fact that OpenShot unnecessarily rebuilds (not just redraws, but actually _deletes_ and completely recreates) the Files model for each and every individual add/remove operation..

:/ Do you know the reason for that design decision? It doesn't make sense to me, isn't it fixable with a few lines? Or it is an issue with the GUI control/widget itself?

@Twenkid

It doesn't make sense to me, isn't it fixable with a few lines?

It desperately _needs_ to be fixed, but it won't be easy, as unfortunately the current implementation sort of backed itself into a corner.

Or it is an issue with the GUI control/widget itself?

Not at all, it has to do with how OpenShot (ab)uses Qt's Model-View architecture to display the files list, which is in turn influenced by how its undo/redo tracking was implemented, and how it tracks data to begin with. I didn't write any of the code in question, so I can't say _why_ it was done this way, but I can explain _how_ it works to the best of my interpretation.

In OpenShot, all of the project data is held in a set of Python objects. But, because you can't populate a Qt TreeView or ListView widget from Python data, a QStandardItemModel is constructed from all of the File objects in the project. On insertion, it just updates the existing model, but deletions cause it to clear out all of the existing data and rebuild the model completely.

For small sets of files, or for changes to a large group of items, that would actually make sense. Keeping the Files objects and a persistent model in sync would be a complex operation prone to bugs, so treating the model as "disposable" and only worrying about making sure it represents the Files objects accurately is the simpler approach. Deleting the model also takes almost no time at all, and constructing a new one is a quick operation compared to searching and selectively removing individual items.

But there's a size beyond which that equation completely flips in the other direction, so when you have a _lot_ of files it's far slower. And that's especially true if you're making changes one at a time, instead of all at once. Which unfortunately we are, due to the way undo/redo tracking in OpenShot is performed.

Changes to project data are only tracked on a very granular level, and each change creates a separate item (or more) on the undo or redo list. That's why, if you delete three items from the Project Files list, you have to hit Undo three times to get them all back. (If you import three items, you have to hit Undo SIX times, two for each file. Which now that I've noticed it feels like a bug.)

Because each of these file insertion/removals is a completely separate operation, the model has to be updated separately for each of them, and unfortunately for file deletion "update" means a complete rebuild.

So, two things would help here, neither of them a very easy fix:

  1. Fix the undo/redo tracking of project files changes, to batch changes that involve the import or deletion of multiple files at once. And, with that done, only update the files model _once_ for each batched import/deletion.
  2. Treat the files model as persistent data, only to be discarded when loading or creating a project. Perform deletions by selectively removing items, rather than destructively clearing and rebuilding the entire model.

The first would actually have a bigger benefit to the users. (It would also mean we could fix the issue where the "Slice All > Keep Both Sides" timeline operation takes _three_ Undos per Clip to reverse.) But it's also _much_ harder, because the undo/redo tracking is a complex system with tendrils that are snaked through the entire codebase. I'm kind of afraid to even touch it, to be perfectly honest.

The second is significantly easier, and while it wouldn't fix undo/redo it _would_ address other small annoyances with how the Project Files list works. (Like the fact that, every time you switch Project Files from Thumbnails View to Details View or back again, your current selection is lost. That's because the selection list is part of the model, and switching views also causes the model to be regenerated for no good reason.) Fixing this would also plug up one of OpenShot's memory leaks, since I discovered that the memory for the old model data isn't being properly freed each time it's rebuilt.

I'd already begun working on code to address the second item a few weeks ago (after I spotted the memory leak), though I ended up putting it on hold for #2976 and some other more-pressing bugs.

(If you import three items, you have to hit Undo SIX times, two for each file. Which now that I've noticed it feels like a bug.)

That part, at least, I managed to find and fix (#3112) easily enough.

2. Treat the files model as persistent data, only to be discarded when loading or creating a project. Perform deletions by selectively removing items, rather than destructively clearing and rebuilding the entire model.

One further complication here, BTW, is how the Project Files list implements filtering. Because the model data is treated as disposable, something that can be regenerated from the Files objects as needed, you can probably guess what happens when the Show All / Video / Audio / Image buttons are used, or the filter text is changed: Yup, the model is cleared and a new, filtered model is generated in its place.

So, the entire filtering implementation has to be thrown out and reimplemented as a QSortFilterProxyModel that operates on the persistent file model, instead of replacing it. (But on the plus side, doing that should give us the long-requested sorting feature basically for free.)

This might not be the right spot but while looking for fixes i figured out a workaround for this issue which speeds importing images up quite a lot and might help someone in my situation.

I start the images importing then i click into the Video tab (which in my case is empty), that way it doesn't constantly refresh and it seems to import at about 15% extra CPU load and about 10x as quick. Hope this is helpful in some way, first time I've registered an account here and i'm not a programmer... Maybe you could code it to change tab to video whenever importing images and vice versa just as a temp fix?

Cheers, Cod

@codral It is very good finding. By using it in slightly different way I was able to reduce time required for some items delete when the file list is huge and consist of about 40 images.

@codral It is very good finding. By using it in slightly different way I was able to reduce time required for some items delete when the file list is huge and consist of about 40 images.

Glad i could be of some help, I should have mentioned i'm processing about 1400 images at 1.5GB, interesting that it also helps on such relatively fewer images

The new import code should have cleared this up by orders of magnitude, and #3784 will add a progress display to make it seem less like the import just hangs the UI indefinitely.

Was this page helpful?
0 / 5 - 0 ratings