-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathMediaTimeline.h
1544 lines (1363 loc) · 66.3 KB
/
MediaTimeline.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
Copyright (c) 2023-2024 CodeWin
This program 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 3 of the License, or
(at your option) any later version.
This program 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 program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <imgui.h>
#include <imgui_json.h>
#include <imgui_extra_widget.h>
#include <ImMaskCreator.h>
#include "Overview.h"
#include "Snapshot.h"
#include "MediaReader.h"
#include "MultiTrackVideoReader.h"
#include "MultiTrackAudioReader.h"
#include "VideoTransformFilter.h"
#include "MediaEncoder.h"
#include "AudioRender.h"
#include "SubtitleTrack.h"
#include "UI.h"
#include "MecProject.h"
#include "Event.h"
#include "EventStackFilter.h"
#include "VideoTransformFilterUiCtrl.h"
#include "MediaPlayer.h"
#include <thread>
#include <string>
#include <vector>
#include <list>
#include <unordered_set>
#include <chrono>
#define PLOT_IMPLOT 0
#define PLOT_TEXTURE 1
#define ICON_SORT_ID u8"\uf887"
#define ICON_SORT_TYPE u8"\uf885"
#define ICON_SORT_NAME u8"\uf882"
#define ICON_FILTER_NONE u8"\uf031"
#define ICON_MEDIA_FINDER u8"\uf07b"
#define ICON_MEDIA_TIMELINE u8"\uf538"
#define ICON_MEDIA_BANK u8"\ue907"
#define ICON_MEDIA_TRANS u8"\ue927"
#define ICON_MEDIA_FILTERS u8"\ue663"
#define ICON_MEDIA_OUTPUT u8"\uf197"
#define ICON_MEDIA_PREVIEW u8"\ue04a"
#define ICON_MEDIA_VIDEO u8"\ue04b"
#define ICON_MEDIA_AUDIO u8"\ue050"
#define ICON_MEDIA_WAVE u8"\ue4e8" //u8"\ue495"
#define ICON_MEDIA_MIDI u8"\ue48f"
#define ICON_MEDIA_IMAGE u8"\ue3f4"
#define ICON_MEDIA_TEXT u8"\ue8e2"
#define ICON_MEDIA_DIAGNOSIS u8"\uf551"
#define ICON_MEDIA_DELETE u8"\ue92b"
#define ICON_MEDIA_DELETE_CLIP u8"\ue92e"
#define ICON_MEDIA_GROUP u8"\ue595"
#define ICON_MEDIA_UNGROUP u8"\ue593"
#define ICON_SLIDER_MINIMUM u8"\uf424"
#define ICON_SLIDER_MAXIMUM u8"\uf422"
#define ICON_SLIDER_FRAME u8"\ue8eb"
#define ICON_SLIDER_CLIP u8"\ue8ed"
#define ICON_CURRENT_TIME u8"\ue3e8"
#define ICON_VIEW u8"\ue8f4"
#define ICON_VIEW_DISABLE u8"\ue8f5"
#define ICON_ENABLE u8"\uf205"
#define ICON_DISABLE u8"\uf204"
#define ICON_ZOOM_IN u8"\ue94f"
#define ICON_ZOOM_OUT u8"\ue94d"
#define ICON_ZOOM u8"\uf3ee"
#define ICON_ITEM_CUT u8"\ue14e"
#define ICON_SPEAKER u8"\ue050"
#define ICON_SPEAKER_MUTE u8"\ue04f"
#define ICON_FILTER u8"\uf331"
#define ICON_MUSIC u8"\ue3a1"
#define ICON_MUSIC_DISABLE u8"\ue440"
#define ICON_AUDIO_MIXING u8"\ue429"
#define ICON_MUSIC_RECT u8"\ue030"
#define ICON_MAGIC_3 u8"\ue663"
#define ICON_MAGIC_1 u8"\ue664"
#define ICON_MAGIC_DISABlE u8"\ue665"
#define ICON_HDR u8"\ue3ee"
#define ICON_HDR_DISABLE u8"\ue3ed"
#define ICON_PALETTE u8"\uf53f"
#define ICON_CROP u8"\uf125"
#define ICON_ROTATE u8"\ue437"
#define ICON_LOCKED u8"\ue897"
#define ICON_UNLOCK u8"\ue898"
#define ICON_TRASH u8"\uf014"
#define ICON_CLONE u8"\uf2d2"
#define ICON_ADD u8"\uf067"
#define ICON_ALIGN_START u8"\ue419"
#define ICON_CROPPING_LEFT u8"\ue045"
#define ICON_CROPPING_RIGHT u8"\ue044"
#define ICON_REMOVE_CUT u8"\ue011"
#define ICON_CUTTING u8"\uf0c4"
#define ICON_MOVING u8"\ue41f"
#define ICON_TRANS u8"\ue882"
#define ICON_BANK u8"\uf1b3"
#define ICON_BLUE_PRINT u8"\ueabe"
#define ICON_BRAIN u8"\uf5dc"
#define ICON_NEW_PROJECT u8"\uf271"
#define ICON_OPEN_PROJECT u8"\uf115"
#define ICON_SAVE u8"\uf0c7"
#define ICON_CLIP_START u8"\uf090"
#define ICON_CLIP_END u8"\uf08b"
#define ICON_RETURN_DEFAULT u8"\ue4e0"
#define ICON_RETURN_ALL u8"\uec20"
#define ICON_NODE u8"\uf542"
#define ICON_WATCH u8"\ue8f4"
#define ICON_UNWATCH u8"\ue8f5"
#define ICON_DELETE u8"\ue92b"
#define ICON_CURVE u8"\ue463"
#define ICON_MAKE_VIDEO u8"\ue52a"
#define ICON_BP_VALID u8"\ueb5b"
#define ICON_BP_EDITING u8"\uf044"
#define ICON_TRACK_ZIP u8"\ueacf"
#define ICON_TRACK_UNZIP u8"\uead0"
#define ICON_FILTER_EDITOR u8"\ueb03"
#define ICON_DELETE_CLIPS u8"\ue16f"
#define ICON_MASK u8"\ueb63"
#define ICON_CLIP_ATTRIBUTE ICON_MD_FORMAT_SHAPES
#define ICON_FONT_BOLD u8"\ue238"
#define ICON_FONT_ITALIC u8"\ue23f"
#define ICON_FONT_UNDERLINE u8"\ue249"
#define ICON_FONT_STRIKEOUT u8"\ue257"
#define ICON_PLAY_FORWARD u8"\uf04b"
#define ICON_PLAY_BACKWARD u8"\uf04b" // need mirror
#define ICON_PAUSE u8"\uf04c"
#define ICON_STOP u8"\uf04d"
#define ICON_FAST_BACKWARD u8"\uf04a"
#define ICON_FAST_FORWARD u8"\uf04e"
#define ICON_FAST_TO_START u8"\uf049"
#define ICON_TO_START u8"\uf048"
#define ICON_FAST_TO_END u8"\uf050"
#define ICON_TO_END u8"\uf051"
#define ICON_EJECT u8"\uf052"
#define ICON_STEP_BACKWARD u8"\uf053"
#define ICON_STEP_FORWARD u8"\uf054"
#define ICON_LOOP u8"\ue9d6"
#define ICON_LOOP_ONE u8"\ue9d7"
#define ICON_COMPARE u8"\uf0db"
#define ICON_CROPED u8"\ue3e8"
#define ICON_SCALED u8"\ue433"
#define ICON_UI_DEBUG u8"\ue868"
#define ICON_1K u8"\ue95c"
#define ICON_1K_PLUS u8"\ue95d"
#define ICON_2K u8"\ue963"
#define ICON_2K_PLUS u8"\ue964"
#define ICON_3K u8"\ue966"
#define ICON_3K_PLUS u8"\ue967"
#define ICON_4K_PLUS u8"\ue969"
#define ICON_5K u8"\ue96b"
#define ICON_5K_PLUS u8"\ue96c"
#define ICON_6K u8"\ue96e"
#define ICON_6K_PLUS u8"\ue96f"
#define ICON_7K u8"\ue971"
#define ICON_7K_PLUS u8"\ue972"
#define ICON_8K u8"\ue974"
#define ICON_8K_PLUS u8"\ue975"
#define ICON_9K u8"\ue977"
#define ICON_9K_PLUS u8"\ue978"
#define ICON_10K u8"\ue951"
#define ICON_ONE u8"\ue3d0"
#define ICON_TWO u8"\ue3d1"
#define ICON_THREE u8"\ue3d2"
#define ICON_FOUR u8"\ue3d3"
#define ICON_FIVE u8"\ue3d4"
#define ICON_SIX u8"\ue3d5"
#define ICON_SEVEN u8"\ue3d6"
#define ICON_EIGHT u8"\ue3d7"
#define ICON_NINE u8"\ue3d8"
#define ICON_STEREO u8"\uf58f"
#define ICON_MONO u8"\uf590"
#define ICON_MORE u8"\ue945"
#define ICON_SETTING u8"\ue8b8"
#define ICON_HISTOGRAM u8"\ue4a9"
#define ICON_WAVEFORM u8"\ue495"
#define ICON_CIE u8"\ue49e"
#define ICON_VECTOR u8"\ue49f"
#define ICON_AUDIOVECTOR u8"\uf20e"
#define ICON_WAVE u8"\ue4ad"
#define ICON_FFT u8"\ue4e8"
#define ICON_DB u8"\ue451"
#define ICON_DB_LEVEL u8"\ue4a9"
#define ICON_SPECTROGRAM u8"\ue4a0"
#define ICON_DRAWING_PIN u8"\uf08d"
#define ICON_EXPAND u8"\uf0b2"
#define ICON_EXPAND_EVENT u8"\ue8be"
#define ICON_EVENT_ZOOM u8"\uf247"
#define ICON_SUBMENU_INDICATOR u8"\ue315"
#define ICON_SETTING_LINK u8"\uf0c1"
#define ICON_SETTING_UNLINK u8"\uf127"
#define ICON_LINK_UP u8"\u2510"
#define ICON_LINK_DOWN u8"\u2518"
#define ICON_EVENT_VIEW u8"\ue8d7"
#define ICON_EVENT_HIDE u8"\ue89d"
#define ICON_ENEVT_CHANNEL_ADD u8"\ue97b"
#define ICON_ERROR_MEDIA u8"\ue160"
#define ICON_ERROR_FRAME u8"\uf410"
#define ICON_ERROR_AUDIO u8"\ue440"
#define ICON_TOOLBAR_START u8"\uf142"
#define ICON_MARK_IN u8"\ueaf2"
#define ICON_MARK_OUT u8"\ueaea"
#define ICON_MARK_NONE u8"\ueaf4"
#define ICON_EMPTY_TRACK u8"\ue3c0"
#define COL_FRAME_RECT IM_COL32( 16, 16, 96, 255)
#define COL_LIGHT_BLUR IM_COL32( 16, 128, 255, 255)
#define COL_CANVAS_BG IM_COL32( 36, 36, 36, 255)
#define COL_LEGEND_BG IM_COL32( 33, 33, 38, 255)
#define COL_PANEL_BG IM_COL32( 36, 36, 40, 255)
#define COL_MARK IM_COL32(255, 255, 255, 128)
#define COL_MARK_HALF IM_COL32(128, 128, 128, 128)
#define COL_RULE_TEXT IM_COL32(224, 224, 224, 255)
#define COL_SLOT_DEFAULT IM_COL32( 80, 80, 100, 255)
#define COL_SLOT_ODD IM_COL32( 58, 58, 58, 255)
#define COL_SLOT_EVEN IM_COL32( 64, 64, 64, 255)
#define COL_EVENT_ODD IM_COL32( 24, 24, 24, 255)
#define COL_EVENT_EVEN IM_COL32( 32, 32, 32, 255)
#define COL_EVENT_ODD_DARK IM_COL32( 10, 10, 10, 255)
#define COL_EVENT_EVEN_DARK IM_COL32( 18, 18, 18, 255)
#define COL_EVENT_HOVERED IM_COL32( 48, 48, 48, 255)
#define COL_SLOT_SELECTED IM_COL32(255, 64, 64, 255)
#define COL_SLOT_V_LINE IM_COL32( 32, 32, 32, 96)
#define COL_SLIDER_BG IM_COL32( 32, 32, 48, 255)
#define COL_SLIDER_THUMB_IN IM_COL32(224, 224, 224, 255)
#define COL_SLIDER_IN IM_COL32(192, 192, 192, 255)
#define COL_SLIDER_MOVING IM_COL32(144, 144, 144, 255)
#define COL_SLIDER_HANDLE IM_COL32(112, 112, 112, 255)
#define COL_SLIDER_SIZING IM_COL32(170, 170, 170, 255)
#define COL_CURSOR_ARROW IM_COL32( 0, 255, 0, 192)
#define COL_CURSOR_LINE IM_COL32( 0, 255, 0, 128)
#define COL_CURSOR_TEXT_BG IM_COL32( 0, 128, 0, 144)
#define COL_CURSOR_TEXT IM_COL32( 0, 255, 0, 255)
#define COL_CURSOR_TEXT_BG2 IM_COL32(128, 128, 0, 128)
#define COL_CURSOR_TEXT2 IM_COL32(255, 255, 0, 255)
#define COL_CURSOR_ARROW_R IM_COL32(255, 0, 0, 192)
#define COL_CURSOR_LINE_R IM_COL32(255, 0, 0, 128)
#define COL_CURSOR_TEXT_BR IM_COL32(128, 0, 0, 144)
#define COL_CURSOR_TEXT_R IM_COL32(255, 160, 160, 255)
#define COL_DARK_ONE IM_COL32( 33, 33, 38, 255)
#define COL_DARK_TWO IM_COL32( 40, 40, 46, 255)
#define COL_DARK_PANEL IM_COL32( 48, 48, 54, 255)
#define COL_DEEP_DARK IM_COL32( 23, 24, 26, 255)
#define COL_BLACK_DARK IM_COL32( 16, 16, 16, 255)
#define COL_GRATICULE_DARK IM_COL32(128, 96, 0, 128)
#define COL_GRATICULE IM_COL32(255, 196, 0, 128)
#define COL_GRATICULE_HALF IM_COL32(255, 196, 0, 64)
#define COL_GRAY_GRATICULE IM_COL32( 96, 96, 96, 128)
#define COL_GRAY_TEXT IM_COL32(128, 128, 128, 128)
#define COL_MARK_BAR IM_COL32(128, 128, 128, 96)
#define COL_MARK_DOT IM_COL32(170, 170, 170, 224)
#define COL_MARK_DOT_LIGHT IM_COL32(255, 255, 255, 224)
#define COL_ERROR_MEDIA IM_COL32(160, 0, 0, 224)
#define COL_TITLE_COLOR IM_COL32(192, 192, 192, 255)
#define COL_TITLE_OUTLINE IM_COL32( 32, 32, 192, 128)
//#define COL_MIXING_BG IM_COL32( 10, 20, 17, 255)
//#define COL_MIXING_BG_MID IM_COL32( 17, 28, 19, 255)
//#define COL_MIXING_BG_HIGH IM_COL32( 25, 35, 20, 255)
#define COL_MIXING_BG IM_COL32( 10, 10, 10, 255)
#define COL_MIXING_BG_MID IM_COL32( 20, 20, 20, 255)
#define COL_MIXING_BG_HIGH IM_COL32( 30, 30, 30, 255)
#define COL_MIXING_BORDER_LOW IM_COL32( 30, 50, 60, 255)
#define COL_MIXING_BORDER IM_COL32( 60, 100, 120, 255)
#define HALF_COLOR(c) (c & 0xFFFFFF) | 0x40000000;
#define TIMELINE_OVER_LENGTH 5000 // add 5 seconds end of timeline
namespace MediaTimeline
{
#define DEFAULT_TRACK_HEIGHT 0
#define DEFAULT_VIDEO_TRACK_HEIGHT 32
#define DEFAULT_AUDIO_TRACK_HEIGHT 20
#define DEFAULT_TEXT_TRACK_HEIGHT 20
#define DEFAULT_EVENT_TRACK_HEIGHT 20
#define PREVIEW_TEXTURE_POOL_NAME "PreviewTexturePool"
#define ARBITRARY_SIZE_TEXTURE_POOL_NAME "ArbitrarySizeTexturePool"
#define VIDEOITEM_OVERVIEW_GRID_TEXTURE_POOL_NAME "VideoItemOverviewGridTexturePool"
#define VIDEOCLIP_SNAPSHOT_GRID_TEXTURE_POOL_NAME "VideoClipSnapshotGridTexturePool"
#define EDITING_VIDEOCLIP_SNAPSHOT_GRID_TEXTURE_POOL_NAME "EditingVideoClipSnapshotGridTexturePool"
#define MEDIA_UNKNOWN 0
#define MEDIA_DUMMY 0x80000000
#define MEDIA_VIDEO 0x00000100
#define MEDIA_SUBTYPE_VIDEO_IMAGE (MEDIA_VIDEO+1)
#define MEDIA_SUBTYPE_VIDEO_IMAGE_SEQUENCE (MEDIA_VIDEO+2)
#define MEDIA_AUDIO 0x00000200
#define MEDIA_SUBTYPE_AUDIO_MIDI (MEDIA_AUDIO+1)
#define MEDIA_TEXT 0x00000400
#define MEDIA_SUBTYPE_TEXT_SUBTITLE (MEDIA_TEXT+1)
#define MEDIA_EVENT 0x00000800
#define MEDIA_CUSTOM 0x40000000
#define IS_DUMMY(t) (((t) & MEDIA_DUMMY) != 0)
#define IS_VIDEO(t) (((t) & MEDIA_VIDEO) != 0)
#define IS_IMAGE(t) ((t) == MEDIA_SUBTYPE_VIDEO_IMAGE)
#define IS_IMAGESEQ(t) ((t) == MEDIA_SUBTYPE_VIDEO_IMAGE_SEQUENCE)
#define IS_AUDIO(t) (((t) & MEDIA_AUDIO) != 0)
#define IS_MIDI(t) ((t) == MEDIA_SUBTYPE_AUDIO_MIDI)
#define IS_TEXT(t) (((t) & MEDIA_TEXT) != 0)
#define IS_SUBTITLE(t) ((t) == MEDIA_SUBTYPE_TEXT_SUBTITLE)
#define IS_EVENT(t) (((t) & MEDIA_EVENT) != 0)
#define IS_SAME_TYPE(t1, t2) ((t1) & (t2) & 0xFFFFFF00)
static inline uint32_t EstimateMediaType(std::string file_suffix)
{
uint32_t type = MEDIA_UNKNOWN;
std::transform(file_suffix.begin(), file_suffix.end(), file_suffix.begin(), [](auto c) { return std::tolower(c); });
if (!file_suffix.empty())
{
if ((file_suffix.compare(".mp4") == 0) ||
(file_suffix.compare(".mov") == 0) ||
(file_suffix.compare(".mkv") == 0) ||
(file_suffix.compare(".mxf") == 0) ||
(file_suffix.compare(".avi") == 0) ||
(file_suffix.compare(".webm") == 0) ||
(file_suffix.compare(".ts") == 0))
type = MEDIA_VIDEO;
else
if ((file_suffix.compare(".wav") == 0) ||
(file_suffix.compare(".mp3") == 0) ||
(file_suffix.compare(".aac") == 0) ||
(file_suffix.compare(".ac3") == 0) ||
(file_suffix.compare(".dts") == 0) ||
(file_suffix.compare(".ogg") == 0))
type = MEDIA_AUDIO;
else
if ((file_suffix.compare(".mid") == 0) ||
(file_suffix.compare(".midi") == 0))
type = MEDIA_SUBTYPE_AUDIO_MIDI;
else
if ((file_suffix.compare(".jpg") == 0) ||
(file_suffix.compare(".jpeg") == 0) ||
(file_suffix.compare(".png") == 0) ||
(file_suffix.compare(".gif") == 0) ||
(file_suffix.compare(".tiff") == 0) ||
(file_suffix.compare(".webp") == 0))
type = MEDIA_SUBTYPE_VIDEO_IMAGE;
else
if ((file_suffix.compare(".txt") == 0) ||
(file_suffix.compare(".srt") == 0) ||
(file_suffix.compare(".ass") == 0) ||
(file_suffix.compare(".stl") == 0) ||
(file_suffix.compare(".lrc") == 0) ||
(file_suffix.compare(".xml") == 0))
type = MEDIA_SUBTYPE_TEXT_SUBTITLE;
}
else
{
type = MEDIA_SUBTYPE_VIDEO_IMAGE_SEQUENCE;
}
return type;
}
enum AudioVectorScopeMode : int
{
LISSAJOUS,
LISSAJOUS_XY,
POLAR,
MODE_NB,
};
struct IDGenerator
{
int64_t GenerateID();
void SetState(int64_t state);
int64_t State() const;
private:
int64_t m_State = ImGui::get_current_time_usec();
};
struct MediaItem
{
int64_t mID; // media ID
std::string mName;
std::string mPath;
void* mHandle;
bool mValid {false}; // Media source is valid
bool mSelected {false}; // Media source is selected by double clicked
bool mShowContextMenu {false}; // shwo context menu
int64_t mSrcLength {0}; // whole Media end in ms
uint32_t mMediaType {MEDIA_UNKNOWN};
MediaCore::MediaParser::Holder mhParser;
MediaCore::Overview::Holder mMediaOverview;
RenderUtils::TextureManager::Holder mTxMgr;
std::vector<RenderUtils::ManagedTexture::Holder> mMediaThumbnail;
std::vector<ImTextureID> mWaveformTextures;
MediaItem(const std::string& name, const std::string& path, uint32_t type, void* handle);
MediaItem(MediaCore::MediaParser::Holder hParser, void* handle);
~MediaItem();
bool Initialize();
bool ChangeSource(const std::string& name, const std::string& path);
void ReleaseItem();
void UpdateThumbnail();
imgui_json::value mMetaData;
bool HasMetaData(const std::string& name) const
{ return mMetaData.contains(name); }
bool FindMetaData(const std::string& name, imgui_json::value& value) const
{
if (!mMetaData.contains(name))
return false;
value = mMetaData[name];
return true;
}
bool AddMetaData(const std::string& name, const imgui_json::value& value, bool overwrite = false)
{
if (mMetaData.contains(name) && !overwrite)
return false;
mMetaData[name] = value;
return true;
}
};
struct VideoSnapshotInfo
{
ImRect rc;
int64_t time_stamp;
int64_t duration;
float frame_width;
};
struct Snapshot
{
ImTextureID texture {nullptr};
int64_t time_stamp {0};
int64_t estimate_time {0};
bool available{false};
};
struct Overlap
{
int64_t mID {-1}; // overlap ID, project saved
uint32_t mType {MEDIA_UNKNOWN};
int64_t mStart {0}; // overlap start time at timeline, project saved
int64_t mEnd {0}; // overlap end time at timeline, project saved
int64_t mCurrent {0}; // overlap current time, project saved
bool bPlay {false}; // overlap play status
bool bForward {true}; // overlap play direction
bool bSeeking {false}; // overlap is seeking
bool bEditing {false}; // overlap is editing
std::pair<int64_t, int64_t> m_Clip; // overlaped clip's pair, project saved
imgui_json::value mTransitionBP; // overlap transion blueprint, project saved
ImGui::KeyPointEditor mTransitionKeyPoints; // overlap key points, project saved
void * mHandle {nullptr}; // overlap belong to timeline
Overlap(int64_t start, int64_t end, int64_t clip_first, int64_t clip_second, uint32_t type, void* handle);
~Overlap();
bool IsOverlapValid(bool fixRange = false);
bool IsOverlapEmpty();
void Update(int64_t start, int64_t start_clip_id, int64_t end, int64_t end_clip_id);
void Seek();
static Overlap * Load(const imgui_json::value& value, void * handle);
void Save(imgui_json::value& value);
};
#define EVENT_SELECTED_BIT 0
#define EVENT_HOVERED_BIT 1
#define EVENT_NEED_SCROLL 2
#define EVENT_SELECTED (1UL << EVENT_SELECTED_BIT)
#define EVENT_HOVERED (1UL << EVENT_HOVERED_BIT)
#define EVENT_SCROLLING (1UL << EVENT_NEED_SCROLL)
struct EventTrack
{
EventTrack(int64_t id, void* handle);
int64_t mID {-1}; // event track ID, project saved
int64_t mClipID {-1}; // event track belong to clip ID, project saved
bool mExpanded {false}; // event track is expanded for curve, project saved
std::vector<int64_t> m_Events; // track clips, project saved(id only)
void * mHandle {nullptr}; // Event track belong to timeline
static EventTrack* Load(const imgui_json::value& value, void * handle);
void Save(imgui_json::value& value);
bool DrawContent(ImDrawList *draw_list, ImRect rect, int event_height, int curve_height, int64_t view_start, int64_t view_end, float pixelWidthMS, bool editable, bool& changed);
void SelectEvent(MEC::Event::Holder event, bool appand);
MEC::Event::Holder FindPreviousEvent(int64_t id);
MEC::Event::Holder FindNextEvent(int64_t id);
int64_t FindEventSpace(int64_t time);
void Update();
};
struct TimeLine;
struct MediaTrack;
struct Clip
{
int64_t mID {-1}; // clip ID, project saved
int64_t mMediaID {-1}; // MediaItem ID, project saved
MediaItem* mpMediaItem {nullptr};
int64_t mGroupID {-1}; // Group ID clip belong, project saved
uint32_t mType {MEDIA_UNKNOWN}; // clip type, project saved
std::string mName; // clip name, project saved
std::string mPath; // clip media path, project saved
bool bSelected {false}; // clip is selected, project saved
std::mutex mLock; // clip mutex, not using yet
void* mHandle {nullptr}; // clip belong to timeline
MediaCore::MediaParser::Holder mMediaParser;
MediaCore::Overview::Holder mhOverview;
int64_t mViewWndDur {0};
float mPixPerMs {0};
int mTrackHeight {0};
bool bMoving {false}; // clip is moving
bool bHovered {false}; // clip is under mouse
imgui_json::value mClipJson;
bool bAttributeScrolling {false}; // need scrolling UI to attribute setting
MEC::EventStack* mEventStack {nullptr};// clip event stack,
std::vector<EventTrack*> mEventTracks; // clip event tracks, contain event IDs only, project saved
int64_t mDragAnchorTime{-1};
int64_t firstTime = 0;
int64_t lastTime = 0;
int64_t visibleTime = 0;
float msPixelWidthTarget = -1.f;
virtual ~Clip();
virtual int64_t Moving(int64_t& diff, int mouse_track);
virtual int64_t Cropping(int64_t& diff, int type);
void Cutting(int64_t pos, int64_t gid, int64_t newClipId, std::list<imgui_json::value>* pActionList = nullptr);
void Cutting(std::vector<int64_t>& cutPosAry, int64_t gid, std::list<imgui_json::value>* pActionList = nullptr);
bool isLinkedWith(Clip * clip);
virtual void ConfigViewWindow(int64_t wndDur, float pixPerMs) { mViewWndDur = wndDur; mPixPerMs = pixPerMs; }
virtual void SetTrackHeight(int trackHeight) { mTrackHeight = trackHeight; }
virtual void SetViewWindowStart(int64_t millisec) {}
virtual void DrawContent(ImDrawList* drawList, const ImVec2& leftTop, const ImVec2& rightBottom, const ImRect& clipRect, bool updated = false) { drawList->AddRect(leftTop, rightBottom, IM_COL32_BLACK); }
virtual void DrawTooltips() {};
virtual bool ReloadSource(MediaItem* pMediaItem) = 0;
virtual void SyncStateToDataLayer() {}
virtual void SyncStateFromDataLayer() {}
virtual bool LoadFromJson(const imgui_json::value& j);
virtual imgui_json::value SaveAsJson();
int64_t Start() const { return mStart; }
int64_t End() const { return mEnd; }
int64_t Length() const { return mEnd-mStart; }
int64_t StartOffset() const { return mStartOffset; }
int64_t EndOffset() const { return mEndOffset; }
void SetPositionAndRange(int64_t start, int64_t end, int64_t startOffset, int64_t endOffset)
{ mStart = start; mEnd = end; mStartOffset = startOffset; mEndOffset = endOffset; }
bool IsInClipRange(int64_t pos) const { return pos >= mStart && pos < mEnd; }
int AddEventTrack();
MEC::Event::Holder FindEventByID(int64_t event_id);
MEC::Event::Holder FindSelectedEvent();
bool hasSelectedEvent();
void EventMoving(int64_t event_id, int64_t diff, int64_t mouse, std::list<imgui_json::value>* pActionList);
int64_t EventCropping(int64_t event_id, int64_t diff, int type, std::list<imgui_json::value>* pActionList);
bool AddEvent(int64_t id, int evtTrackIndex, int64_t start, int64_t duration, const BluePrint::Node* node, std::list<imgui_json::value>* pActionList);
bool AddEvent(int64_t id, int evtTrackIndex, int64_t start, int64_t duration, ID_TYPE nodeTypeId, const std::string& nodeName, std::list<imgui_json::value>* pActionList);
bool AppendEvent(MEC::Event::Holder event, void* data);
bool DeleteEvent(int64_t evtId, std::list<imgui_json::value>* pActionList);
bool DeleteEvent(MEC::Event::Holder event, std::list<imgui_json::value>* pActionList);
void SelectEvent(MEC::Event::Holder event, bool appand = false);
void ChangeStart(int64_t pos);
void ChangeStartOffset(int64_t newOffset);
void ChangeEndOffset(int64_t newOffset);
protected:
Clip(TimeLine* pOwner, uint32_t u32Type);
Clip(TimeLine* pOwner, uint32_t u32Type, const std::string& strName, int64_t i64Start, int64_t i64End, int64_t i64StartOffset = 0, int64_t i64EndOffset = 0);
protected:
int64_t mStart {0}; // clip start time in timeline, project saved
int64_t mEnd {0}; // clip end time in timeline, project saved
int64_t mStartOffset {0}; // clip start time in media, project saved
int64_t mEndOffset {0}; // clip end time in media, project saved
};
struct VideoClip : Clip
{
// video info
MediaCore::Snapshot::Viewer::Holder mhSsViewer;
std::vector<VideoSnapshotInfo> mVideoSnapshotInfos; // clip snapshots info, with all croped range
// image info
int mWidth {0}; // image width, project saved
int mHeight {0}; // image height, project saved
static VideoClip* CreateInstance(TimeLine* pOwner, const std::string& strName, MediaItem* pMediaItem, int64_t i64Start, int64_t i64End, int64_t i64StartOffset = 0, int64_t i64EndOffset = 0);
static VideoClip* CreateInstance(TimeLine* pOwner, MediaItem* pMediaItem, int64_t i64Start);
virtual ~VideoClip();
void CalcDisplayParams();
void SetTrackHeight(int trackHeight) override;
void SetViewWindowStart(int64_t millisec) override;
void DrawContent(ImDrawList* drawList, const ImVec2& leftTop, const ImVec2& rightBottom, const ImRect& clipRect, bool updated = false) override;
bool ReloadSource(MediaItem* pMediaItem) override;
static VideoClip* CreateInstanceFromJson(const imgui_json::value& j, TimeLine* pOwner);
imgui_json::value SaveAsJson() override;
void SetDataLayer(MediaCore::VideoClip::Holder hVClip, bool bSyncStateToDataLayer);
MediaCore::VideoClip::Holder GetDataLayer() const { return mhDataLayerClip; }
RenderUtils::ManagedTexture::Holder GetImageTexture() const { return mhImageTx; }
private:
VideoClip(TimeLine* pOwner) : Clip(pOwner, MEDIA_VIDEO) {}
VideoClip(TimeLine* pOwner, const std::string& strName, int64_t i64Start, int64_t i64End, int64_t i64StartOffset = 0, int64_t i64EndOffset = 0)
: Clip(pOwner, MEDIA_VIDEO, strName, i64Start, i64End, i64StartOffset, i64EndOffset)
{}
bool UpdateClip(MediaItem* pMediaItem);
void SyncStateToDataLayer() override;
void SyncStateFromDataLayer() override;
private:
float mSnapWidth {0};
float mSnapHeight {0};
int64_t mClipViewStartPos;
MediaCore::VideoClip::Holder mhDataLayerClip;
std::vector<MediaCore::Snapshot::Image> mSnapImages;
RenderUtils::ManagedTexture::Holder mhImageTx;
};
struct AudioClip : Clip
{
int mAudioChannels {0}; // clip audio channels, project saved
int mAudioSampleRate {0}; // clip audio sample rate, project saved
MediaCore::Overview::Waveform::Holder mWaveform {nullptr}; // clip audio snapshot
MediaCore::Overview::Holder mOverview;
ImTextureID mWaveformTexture {nullptr}; // clip waveform texture
static AudioClip* CreateInstance(TimeLine* pOwner, const std::string& strName, MediaItem* pMediaItem, int64_t i64Start, int64_t i64End, int64_t i64StartOffset = 0, int64_t i64EndOffset = 0);
static AudioClip* CreateInstance(TimeLine* pOwner, MediaItem* pMediaItem, int64_t i64Start);
virtual ~AudioClip();
void DrawContent(ImDrawList* drawList, const ImVec2& leftTop, const ImVec2& rightBottom, const ImRect& clipRect, bool updated = false) override;
bool ReloadSource(MediaItem* pMediaItem) override;
static AudioClip* CreateInstanceFromJson(const imgui_json::value& j, TimeLine* pOwner);
imgui_json::value SaveAsJson() override;
MediaCore::AudioClip::Holder mhDataLayerClip;
void SetDataLayer(MediaCore::AudioClip::Holder hVClip, bool bSyncStateToDataLayer);
private:
AudioClip(TimeLine* pOwner) : Clip(pOwner, MEDIA_AUDIO) {}
AudioClip(TimeLine* pOwner, const std::string& strName, int64_t i64Start, int64_t i64End, int64_t i64StartOffset = 0, int64_t i64EndOffset = 0)
: Clip(pOwner, MEDIA_AUDIO, strName, i64Start, i64End, i64StartOffset, i64EndOffset)
{}
bool UpdateClip(MediaItem* pMediaItem);
void SyncStateToDataLayer() override;
void SyncStateFromDataLayer() override;
};
struct TextClip : Clip
{
static TextClip* CreateInstance(TimeLine* pOwner, const std::string& strText, int64_t i64Start, int64_t i64Length = 0);
virtual ~TextClip();
void SetClipDefault(const MediaCore::SubtitleStyle & style);
void SetClipDefault(const TextClip* clip);
void SyncClipAttributes();
void EnableUsingTrackStyle(bool enable);
void DrawContent(ImDrawList* drawList, const ImVec2& leftTop, const ImVec2& rightBottom, const ImRect& clipRect, bool updated = false) override;
void DrawTooltips() override;
int64_t Moving(int64_t& diff, int mouse_track) override;
int64_t Cropping(int64_t& diff, int type) override;
bool ReloadSource(MediaItem* pMediaItem) override;
static TextClip* CreateInstanceFromJson(const imgui_json::value& j, TimeLine* pOwner);
imgui_json::value SaveAsJson() override;
void CreateDataLayer(MediaTrack* pTrack);
std::string mText;
std::string mFontName;
ImGui::KeyPointEditor mAttributeKeyPoints;
bool mTrackStyle {true};
bool mScaleSettingLink {true};
float mFontScaleX {1.0f};
float mFontScaleY {1.0f};
float mFontSpacing {1.0f};
float mFontAngleX {0.0f};
float mFontAngleY {0.0f};
float mFontAngleZ {0.0f};
float mFontOutlineWidth {1.0f};
int mFontAlignment {2};
bool mFontBold {false};
bool mFontItalic {false};
bool mFontUnderLine {false};
bool mFontStrikeOut {false};
float mFontPosX {0.0f};
float mFontPosY {0.0f};
float mFontOffsetH {0.f};
float mFontOffsetV {0.f};
float mFontShadowDepth {0.f};
ImVec4 mFontPrimaryColor {0, 0, 0, 0};
ImVec4 mFontOutlineColor {0, 0, 0, 0};
ImVec4 mFontBackColor {0, 0, 0, 0};
bool mIsInited {false};
MediaCore::SubtitleClipHolder mhDataLayerClip;
void* mTrack {nullptr};
private:
TextClip(TimeLine* pOwner) : Clip(pOwner, MEDIA_TEXT) {}
TextClip(TimeLine* pOwner, const std::string& strText, int64_t i64Start, int64_t i64End)
: Clip(pOwner, MEDIA_TEXT, "", i64Start, i64End, 0, 0), mText(strText)
{
mAttributeKeyPoints.SetMin({0, 0, 0, 0});
mAttributeKeyPoints.SetMax(ImVec4(1, 1, 1, Length()), true);
}
};
class BluePrintVideoTransition : public MediaCore::VideoTransition
{
public:
BluePrintVideoTransition(void * handle);
~BluePrintVideoTransition();
MediaCore::VideoTransition::Holder Clone() override;
void ApplyTo(MediaCore::VideoOverlap* overlap) override { mOverlap = overlap; }
ImGui::ImMat MixTwoImages(const ImGui::ImMat& vmat1, const ImGui::ImMat& vmat2, int64_t pos, int64_t dur) override;
void SetBluePrintFromJson(imgui_json::value& bpJson);
void SetKeyPoint(ImGui::KeyPointEditor &keypoint) { mKeyPoints = keypoint; };
imgui_json::value SaveAsJson() const override;
public:
BluePrint::BluePrintUI* mBp{nullptr};
ImGui::KeyPointEditor mKeyPoints;
private:
static int OnBluePrintChange(int type, std::string name, void* handle);
MediaCore::VideoOverlap* mOverlap;
std::mutex mBpLock;
void * mHandle {nullptr};
};
class BluePrintAudioTransition : public MediaCore::AudioTransition
{
public:
BluePrintAudioTransition(void * handle);
~BluePrintAudioTransition();
void ApplyTo(MediaCore::AudioOverlap* overlap) override { mOverlap = overlap; }
ImGui::ImMat MixTwoAudioMats(const ImGui::ImMat& amat1, const ImGui::ImMat& amat2, int64_t pos) override;
void SetBluePrintFromJson(imgui_json::value& bpJson);
void SetKeyPoint(ImGui::KeyPointEditor &keypoint) { mKeyPoints = keypoint; };
public:
BluePrint::BluePrintUI* mBp{nullptr};
ImGui::KeyPointEditor mKeyPoints;
private:
static int OnBluePrintChange(int type, std::string name, void* handle);
MediaCore::AudioOverlap* mOverlap;
std::mutex mBpLock;
void * mHandle {nullptr};
};
struct BaseEditingClip
{
void* mHandle {nullptr}; // main timeline handle
int64_t mID {-1}; // editing clip ID
int64_t mMediaID {-1}; // editing meida(item) ID
uint32_t mType {MEDIA_UNKNOWN};
int64_t mStart {0};
int64_t mEnd {0};
int64_t mStartOffset {0}; // editing clip start time in media
int64_t mEndOffset {0}; // editing clip end time in media
int64_t mDuration {0};
int64_t mCurrentTime {-1};
ImVec2 mViewWndSize {0, 0};
bool bSeeking {false};
bool bEditingAttribute {false}; // editing clip attribute mode, unique UI layout
int64_t firstTime = 0;
int64_t lastTime = 0;
int64_t visibleTime = 0;
float msPixelWidthTarget = -1.f;
BaseEditingClip(int64_t id, int64_t mid, uint32_t type, int64_t start, int64_t end, int64_t startOffset, int64_t endOffset, void* handle)
: mID(id), mMediaID(mid), mType(type), mStart(start), mEnd(end), mStartOffset(startOffset), mEndOffset(endOffset), mHandle(handle)
{}
virtual ~BaseEditingClip() {};
Clip * GetClip();
void UpdateCurrent(bool forward, int64_t currentTime);
virtual int64_t GetPreviewTime(bool bResetIfOutOfRange = true)
{
auto i64PreViewTime = mCurrentTime+mStart;
if (bResetIfOutOfRange && (mCurrentTime < 0 || mCurrentTime >= mDuration))
{
i64PreViewTime = mStart;
mCurrentTime = 0;
}
return i64PreViewTime;
}
virtual void CalcDisplayParams(int64_t viewWndDur) = 0;
virtual void UpdateClipRange(Clip* clip) = 0;
virtual void Save() = 0;
virtual void DrawContent(ImDrawList* drawList, const ImVec2& leftTop, const ImVec2& rightBottom, bool updated = false) = 0;
virtual void RefreshDataLayer() {}
};
struct EditingVideoClip : BaseEditingClip
{
MediaCore::Snapshot::Generator::Holder mSsGen;
MediaCore::Snapshot::Viewer::Holder mSsViewer;
ImVec2 mSnapSize {0, 0};
uint32_t mWidth {0};
uint32_t mHeight {0};
// for image clip
RenderUtils::ManagedTexture::Holder mhImgTx;
// for attribute editor
RenderUtils::ManagedTexture::Holder mhTransformOutputTx;
RenderUtils::ManagedTexture::Holder mhFilterInputTx;
RenderUtils::ManagedTexture::Holder mhFilterOutputTx;
MediaCore::CorrelativeFrame::Phase meOutputFramePhase {MediaCore::CorrelativeFrame::PHASE_AFTER_MIXING};
MediaCore::CorrelativeFrame::Phase meAttrOutFramePhase {MediaCore::CorrelativeFrame::PHASE_AFTER_MIXING};
ImGui::ImMat mFilterOutputMat;
MediaCore::VideoFilter::Holder mhVideoFilter;
MediaCore::VideoTransformFilter::Holder mhTransformFilter;
BluePrint::BluePrintUI* mFilterBp {nullptr};
ImGui::KeyPointEditor* mFilterKp {nullptr};
ImGui::MaskCreator::Holder mhMaskCreator;
int64_t mMaskEventId {-1}, mMaskNodeId {-1};
int mMaskIndex {-1};
int64_t mMaskEventStart, mMaskEventEnd;
public:
EditingVideoClip(VideoClip* vidclip);
virtual ~EditingVideoClip();
void InitAttrCurveEditor();
void CalcDisplayParams(int64_t viewWndDur) override;
void UpdateClipRange(Clip* clip) override;
void Save() override;
bool UpdatePreviewTexture(bool blocking = false);
void DrawContent(ImDrawList* drawList, const ImVec2& leftTop, const ImVec2& rightBottom, bool updated = false) override;
void SelectEditingMask(MEC::Event::Holder hEvent, int64_t nodeId, int maskIndex, ImGui::MaskCreator::Holder hMaskCreator = nullptr);
void UnselectEditingMask();
MEC::VideoTransformFilterUiCtrl* GetTransformFilterUiCtrl() { return mpTransFilterUiCtrl; }
bool DrawAttributeCurves(const ImVec2& v2ViewSize, float fViewScaleX, float fViewOffsetX, bool* pCurveUpdated, ImDrawList* pDrawList);
ImGui::ImNewCurve::Editor::Holder GetAttributeCurveEditor() const { return mhAttrCurveEditor; }
void RefreshDataLayer() override;
enum {
CURVE_IDX_CROP = 0,
CURVE_IDX_POSOFFSET = 4,
CURVE_IDX_SCALE = 6,
CURVE_IDX_ROTATION = 8,
CURVE_IDX_OPACITY = 9,
};
bool IsCurveVisibleOnCrop() const { return mhAttrCurveEditor->IsCurveVisible(CURVE_IDX_CROP); }
void SetCurveVisibleOnCrop(bool bVisible)
{
mhAttrCurveEditor->SetCurveVisible(CURVE_IDX_CROP , bVisible);
mhAttrCurveEditor->SetCurveVisible(CURVE_IDX_CROP+1, bVisible);
mhAttrCurveEditor->SetCurveVisible(CURVE_IDX_CROP+2, bVisible);
mhAttrCurveEditor->SetCurveVisible(CURVE_IDX_CROP+3, bVisible);
}
bool IsCurveVisibleOnPosOffset() const { return mhAttrCurveEditor->IsCurveVisible(CURVE_IDX_POSOFFSET); }
void SetCurveVisibleOnPosOffset(bool bVisible)
{
mhAttrCurveEditor->SetCurveVisible(CURVE_IDX_POSOFFSET , bVisible);
mhAttrCurveEditor->SetCurveVisible(CURVE_IDX_POSOFFSET+1, bVisible);
}
bool IsCurveVisibleOnScale() const { return mhAttrCurveEditor->IsCurveVisible(CURVE_IDX_SCALE); }
void SetCurveVisibleOnScale(bool bVisible)
{
mhAttrCurveEditor->SetCurveVisible(CURVE_IDX_SCALE , bVisible);
mhAttrCurveEditor->SetCurveVisible(CURVE_IDX_SCALE+1, bVisible);
}
bool IsCurveVisibleOnRotation() const { return mhAttrCurveEditor->IsCurveVisible(CURVE_IDX_ROTATION); }
void SetCurveVisibleOnRotation(bool bVisible)
{
mhAttrCurveEditor->SetCurveVisible(CURVE_IDX_ROTATION, bVisible);
}
bool IsCurveVisibleOnOpacity() const { return mhAttrCurveEditor->IsCurveVisible(CURVE_IDX_OPACITY); }
void SetCurveVisibleOnOpacity(bool bVisible)
{
mhAttrCurveEditor->SetCurveVisible(CURVE_IDX_OPACITY, bVisible);
}
private:
MEC::VideoTransformFilterUiCtrl* mpTransFilterUiCtrl {nullptr};
ImGui::ImNewCurve::Editor::Holder mhAttrCurveEditor;
};
struct EditingAudioClip : BaseEditingClip
{
int mAudioChannels {2};
int mAudioSampleRate {44100};
MediaCore::Overview::Waveform::Holder mWaveform {nullptr};
std::vector<ImTextureID> mWaveformTextures;
BluePrint::BluePrintUI* mFilterBp {nullptr};
ImGui::KeyPointEditor* mFilterKp {nullptr};
MediaCore::AudioFilter::Holder mhAudioFilter;
public:
EditingAudioClip(AudioClip* vidclip);
virtual ~EditingAudioClip();
void CalcDisplayParams(int64_t viewWndDur) override;
void UpdateClipRange(Clip* clip) override;
void Save() override;
void DrawContent(ImDrawList* drawList, const ImVec2& leftTop, const ImVec2& rightBottom, bool updated = false) override;
};
struct EditingTextClip : BaseEditingClip
{
std::string mText;
public:
EditingTextClip(TextClip* clip);
virtual ~EditingTextClip();
void CalcDisplayParams(int64_t viewWndDur) override;
void UpdateClipRange(Clip* clip) override;
void Save() override;
void DrawContent(ImDrawList* drawList, const ImVec2& leftTop, const ImVec2& rightBottom, bool updated = false) override;
public:
void UpdateClip(Clip* clip);
};
struct BaseEditingOverlap
{
void* mHandle {nullptr}; // main timeline handle
int64_t mID {-1}; // overlap ID
int64_t mStart {0};
int64_t mEnd {0};
int64_t mDuration {0};
int64_t mCurrentTime {-1};
ImVec2 mViewWndSize {0, 0};
float msPixelWidth {0};
bool bSeeking {false};
BaseEditingOverlap(int64_t id, void* handle) { mID = id; mHandle = handle; }
virtual ~BaseEditingOverlap() {};
std::pair<int64_t, int64_t> m_StartOffset;
virtual void Seek(int64_t pos, bool enterSeekingState) = 0;
virtual void Step(bool forward, int64_t step = 0) = 0;
virtual bool GetFrame(std::pair<std::pair<ImGui::ImMat, ImGui::ImMat>, ImGui::ImMat>& in_out_frame, bool preview_frame = true) = 0;
virtual void DrawContent(ImDrawList* drawList, const ImVec2& leftTop, const ImVec2& rightBottom, bool updated = false) = 0;
virtual void Save() = 0;
};
struct EditingVideoOverlap : BaseEditingOverlap
{
VideoClip *mClip1, *mClip2;
MediaCore::Snapshot::Generator::Holder mSsGen1, mSsGen2;
MediaCore::Snapshot::Viewer::Holder mViewer1, mViewer2;
RenderUtils::ManagedTexture::Holder mhImgTx1;
RenderUtils::ManagedTexture::Holder mhImgTx2;
ImVec2 mSnapSize{0, 0};
BluePrintVideoTransition* mTransition{nullptr};
public:
EditingVideoOverlap(int64_t id, void* handle);
virtual ~EditingVideoOverlap();
void Seek(int64_t pos, bool enterSeekingState) override;
void Step(bool forward, int64_t step = 0) override;
bool GetFrame(std::pair<std::pair<ImGui::ImMat, ImGui::ImMat>, ImGui::ImMat>& in_out_frame, bool preview_frame = true) override;
void DrawContent(ImDrawList* drawList, const ImVec2& leftTop, const ImVec2& rightBottom, bool updated = false) override;
void Save() override;