From 17b5a97b9bbe00b442a58a5065498e67b497af09 Mon Sep 17 00:00:00 2001 From: ddennedy Date: Fri, 8 May 2009 03:48:36 +0000 Subject: [PATCH] Rough file addition and cleanup. Not yet ready for use. Signed-off-by: Dan Dennedy git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/melted@1426 d19143bc-622f-0410-bfdd-b5b2a6649095 --- demo/README | 217 --- demo/circle.png | Bin 5239 -> 0 bytes demo/circle.svg | 1 - demo/consumers.ini | 12 - demo/demo | 106 -- demo/demo.ini | 28 - demo/demo.kino | 13 - demo/entity.westley | 11 - demo/luma1.pgm | Bin 414735 -> 0 bytes demo/mlt_all | 3 - demo/mlt_attributes | 7 - demo/mlt_audio_stuff | 6 - demo/mlt_avantika_title | 3 - demo/mlt_bouncy | 10 - demo/mlt_bouncy_ball | 14 - demo/mlt_clock_in_and_out | 7 - demo/mlt_composite_transition | 7 - demo/mlt_effect_in_middle | 4 - demo/mlt_fade_black | 9 - demo/mlt_fade_in_and_out | 9 - demo/mlt_intro | 9 - demo/mlt_jcut | 10 - demo/mlt_lcut | 12 - demo/mlt_levels | 5 - demo/mlt_my_name_is | 10 - demo/mlt_news | 18 - demo/mlt_obscure | 5 - demo/mlt_push | 18 - demo/mlt_slideshow | 4 - demo/mlt_slideshow_black | 3 - demo/mlt_squeeze | 9 - demo/mlt_squeeze_box | 9 - demo/mlt_ticker | 15 - demo/mlt_title_over_gfx | 25 - demo/mlt_titleshadow_watermark | 10 - demo/mlt_voiceover | 36 - demo/mlt_watermark | 6 - demo/new.westley | 51 - demo/pango.westley | 34 - demo/svg.westley | 50 - demo/watermark1.png | Bin 1353 -> 0 bytes docs/framework.txt | 1341 -------------- docs/inigo.txt | 401 ----- docs/services.txt | 1582 ----------------- docs/westley.txt | 574 ------ mlt++/AUTHORS | 5 - mlt++/COPYING | 504 ------ mlt++/ChangeLog | 552 ------ mlt++/HOWTO | 473 ----- mlt++/README | 135 -- mlt++/mlt++.sln | 21 - mlt++/mlt++.vcproj | 265 --- mlt++/src/Mlt.h | 52 - mlt++/src/MltConsumer.cpp | 137 -- mlt++/src/MltConsumer.h | 58 - mlt++/src/MltDeque.cpp | 68 - mlt++/src/MltDeque.h | 47 - mlt++/src/MltEvent.cpp | 61 - mlt++/src/MltEvent.h | 46 - mlt++/src/MltFactory.cpp | 77 - mlt++/src/MltFactory.h | 60 - mlt++/src/MltField.cpp | 64 - mlt++/src/MltField.h | 52 - mlt++/src/MltFilter.cpp | 113 -- mlt++/src/MltFilter.h | 55 - mlt++/src/MltFilteredConsumer.cpp | 118 -- mlt++/src/MltFilteredConsumer.h | 53 - mlt++/src/MltFilteredProducer.cpp | 86 - mlt++/src/MltFilteredProducer.h | 50 - mlt++/src/MltFrame.cpp | 90 - mlt++/src/MltFrame.h | 52 - mlt++/src/MltGeometry.cpp | 100 -- mlt++/src/MltGeometry.h | 80 - mlt++/src/MltMultitrack.cpp | 86 - mlt++/src/MltMultitrack.h | 55 - mlt++/src/MltPlaylist.cpp | 316 ---- mlt++/src/MltPlaylist.h | 108 -- mlt++/src/MltProducer.cpp | 193 -- mlt++/src/MltProducer.h | 74 - mlt++/src/MltProfile.cpp | 122 -- mlt++/src/MltProfile.h | 63 - mlt++/src/MltProperties.cpp | 261 --- mlt++/src/MltProperties.h | 88 - mlt++/src/MltPushConsumer.cpp | 146 -- mlt++/src/MltPushConsumer.h | 51 - mlt++/src/MltRepository.cpp | 81 - mlt++/src/MltRepository.h | 57 - mlt++/src/MltService.cpp | 121 -- mlt++/src/MltService.h | 63 - mlt++/src/MltTokeniser.cpp | 56 - mlt++/src/MltTokeniser.h | 45 - mlt++/src/MltTractor.cpp | 159 -- mlt++/src/MltTractor.h | 67 - mlt++/src/MltTransition.cpp | 92 - mlt++/src/MltTransition.h | 50 - mlt++/swig/java/Play.java | 54 - mlt++/swig/perl/play.pl | 46 - mlt++/swig/php/play.php | 21 - mlt++/swig/python/play.py | 36 - mlt++/swig/ruby/play.rb | 41 - mlt++/swig/ruby/thumbs.rb | 41 - mlt++/swig/tcl/play.tcl | 18 - mlt++/test/play.cpp | 15 - mlt-framework.pc.in | 7 - profiles/Makefile | 18 - profiles/atsc_1080i_50 | 10 - profiles/atsc_1080i_60 | 10 - profiles/atsc_1080p_2398 | 10 - profiles/atsc_1080p_24 | 10 - profiles/atsc_1080p_25 | 10 - profiles/atsc_1080p_2997 | 10 - profiles/atsc_1080p_30 | 10 - profiles/atsc_720p_30 | 10 - profiles/cif_15 | 10 - profiles/cif_ntsc | 10 - profiles/cif_pal | 10 - profiles/cvd_ntsc | 10 - profiles/cvd_pal | 10 - profiles/dv_ntsc | 10 - profiles/dv_ntsc_wide | 10 - profiles/dv_pal | 10 - profiles/dv_pal_wide | 10 - profiles/hdv_1080_25p | 10 - profiles/hdv_1080_30p | 10 - profiles/hdv_1080_50i | 10 - profiles/hdv_1080_60i | 10 - profiles/hdv_720_25p | 10 - profiles/hdv_720_30p | 10 - profiles/hdv_720_50p | 10 - profiles/hdv_720_60p | 10 - profiles/qcif_15 | 10 - profiles/qcif_ntsc | 10 - profiles/qcif_pal | 10 - profiles/quarter_15 | 10 - profiles/quarter_ntsc | 10 - profiles/quarter_ntsc_wide | 10 - profiles/quarter_pal | 10 - profiles/quarter_pal_wide | 10 - profiles/square_ntsc | 10 - profiles/square_ntsc_wide | 10 - profiles/square_pal | 10 - profiles/square_pal_wide | 10 - profiles/svcd_ntsc | 10 - profiles/svcd_ntsc_wide | 10 - profiles/svcd_pal | 10 - profiles/svcd_pal_wide | 10 - profiles/vcd_ntsc | 10 - profiles/vcd_pal | 10 - setenv | 26 - setenv_mc | 9 - src/framework/Makefile | 109 -- src/framework/configure | 2 - src/framework/metaschema.yaml | 129 -- src/framework/mlt.h | 58 - src/framework/mlt_cache.c | 451 ----- src/framework/mlt_cache.h | 38 - src/framework/mlt_consumer.c | 1010 ----------- src/framework/mlt_consumer.h | 135 -- src/framework/mlt_deque.c | 398 ----- src/framework/mlt_deque.h | 54 - src/framework/mlt_events.c | 503 ------ src/framework/mlt_events.h | 63 - src/framework/mlt_factory.c | 378 ---- src/framework/mlt_factory.h | 54 - src/framework/mlt_field.c | 270 --- src/framework/mlt_field.h | 41 - src/framework/mlt_filter.c | 275 --- src/framework/mlt_filter.h | 67 - src/framework/mlt_frame.c | 1314 -------------- src/framework/mlt_frame.h | 144 -- src/framework/mlt_geometry.c | 700 -------- src/framework/mlt_geometry.h | 73 - src/framework/mlt_log.c | 80 - src/framework/mlt_log.h | 95 - src/framework/mlt_multitrack.c | 514 ------ src/framework/mlt_multitrack.h | 73 - src/framework/mlt_parser.c | 245 --- src/framework/mlt_parser.h | 60 - src/framework/mlt_playlist.c | 1839 -------------------- src/framework/mlt_playlist.h | 124 -- src/framework/mlt_pool.c | 391 ----- src/framework/mlt_pool.h | 34 - src/framework/mlt_producer.c | 1031 ----------- src/framework/mlt_producer.h | 118 -- src/framework/mlt_profile.c | 303 ---- src/framework/mlt_profile.h | 55 - src/framework/mlt_properties.c | 1754 ------------------- src/framework/mlt_properties.h | 87 - src/framework/mlt_property.c | 512 ------ src/framework/mlt_property.h | 46 - src/framework/mlt_repository.c | 428 ----- src/framework/mlt_repository.h | 71 - src/framework/mlt_service.c | 738 -------- src/framework/mlt_service.h | 100 -- src/framework/mlt_tokeniser.c | 172 -- src/framework/mlt_tokeniser.h | 50 - src/framework/mlt_tractor.c | 540 ------ src/framework/mlt_tractor.h | 66 - src/framework/mlt_transition.c | 388 ----- src/framework/mlt_transition.h | 79 - src/framework/mlt_types.h | 124 -- src/inigo/Makefile | 37 - src/inigo/inigo.c | 574 ------ src/inigo/io.c | 196 --- src/inigo/io.h | 45 - src/modules/Makefile | 31 - src/modules/avformat/Makefile | 86 - src/modules/avformat/audioconvert.h | 111 -- src/modules/avformat/configure | 168 -- src/modules/avformat/consumer_avformat.c | 1371 --------------- src/modules/avformat/factory.c | 165 -- src/modules/avformat/filter_avcolour_space.c | 247 --- src/modules/avformat/filter_avdeinterlace.c | 356 ---- src/modules/avformat/filter_avresample.c | 196 --- src/modules/avformat/filter_swscale.c | 197 --- src/modules/avformat/mmx.h | 243 --- src/modules/avformat/producer_avformat.c | 1469 ---------------- src/modules/avformat/producer_avformat.yml | 171 -- src/modules/configure | 42 - src/modules/core/Makefile | 63 - src/modules/core/composite_line_yuv_mmx.S | 211 --- src/modules/core/consumer_null.c | 181 -- src/modules/core/factory.c | 79 - src/modules/core/filter_brightness.c | 104 -- src/modules/core/filter_channelcopy.c | 96 - src/modules/core/filter_crop.c | 166 -- src/modules/core/filter_data_feed.c | 177 -- src/modules/core/filter_data_show.c | 343 ---- src/modules/core/filter_gamma.c | 88 - src/modules/core/filter_greyscale.c | 62 - src/modules/core/filter_luma.c | 149 -- src/modules/core/filter_mirror.c | 335 ---- src/modules/core/filter_mono.c | 94 - src/modules/core/filter_obscure.c | 309 ---- src/modules/core/filter_region.c | 89 - src/modules/core/filter_rescale.c | 325 ---- src/modules/core/filter_resize.c | 194 -- src/modules/core/filter_transition.c | 115 -- src/modules/core/filter_watermark.c | 264 --- src/modules/core/producer_colour.c | 244 --- src/modules/core/producer_consumer.c | 227 --- src/modules/core/producer_noise.c | 177 -- src/modules/core/producer_ppm.c | 273 --- src/modules/core/transition_composite.c | 1342 -------------- src/modules/core/transition_composite.h | 31 - src/modules/core/transition_luma.c | 596 ------- src/modules/core/transition_mix.c | 169 -- src/modules/core/transition_region.c | 449 ----- src/modules/core/transition_region.h | 28 - src/modules/data_fx.properties | 250 --- src/modules/dgraft/Makefile | 33 - src/modules/dgraft/factory.c | 28 - src/modules/dgraft/filter_telecide.c | 1230 ------------- src/modules/dv/Makefile | 36 - src/modules/dv/configure | 17 - src/modules/dv/consumer_libdv.c | 449 ----- src/modules/dv/factory.c | 32 - src/modules/dv/producer_libdv.c | 546 ------ src/modules/effectv/Makefile | 35 - src/modules/effectv/factory.c | 29 - src/modules/effectv/filter_burn.c | 213 --- src/modules/effectv/image.c | 308 ---- src/modules/effectv/utils.c | 58 - src/modules/effectv/utils.h | 48 - src/modules/feeds/Makefile | 15 - src/modules/feeds/NTSC/data_fx.properties | 250 --- src/modules/feeds/NTSC/obscure.properties | 26 - src/modules/feeds/PAL/border.properties | 22 - src/modules/feeds/PAL/data_fx.properties | 76 - src/modules/feeds/PAL/etv.properties | 186 -- src/modules/feeds/PAL/example.properties | 12 - src/modules/feeds/PAL/obscure.properties | 35 - src/modules/fezzik.dict | 39 - src/modules/fezzik.ini | 14 - src/modules/fezzik/Makefile | 36 - src/modules/fezzik/factory.c | 31 - src/modules/fezzik/producer_fezzik.c | 187 -- src/modules/fezzik/producer_hold.c | 201 --- src/modules/frei0r/Makefile | 37 - src/modules/frei0r/configure | 14 - src/modules/frei0r/factory.c | 335 ---- src/modules/frei0r/filter_frei0r.c | 56 - src/modules/frei0r/frei0r_helper.c | 161 -- src/modules/frei0r/frei0r_helper.h | 22 - src/modules/frei0r/producer_frei0r.c | 101 -- src/modules/frei0r/transition_frei0r.c | 85 - src/modules/gtk2/Makefile | 62 - src/modules/gtk2/configure | 38 - src/modules/gtk2/consumer_gtk2.c | 55 - src/modules/gtk2/factory.c | 82 - src/modules/gtk2/filter_rescale.c | 158 -- src/modules/gtk2/have_mmx.S | 53 - src/modules/gtk2/pixops.c | 769 -------- src/modules/gtk2/pixops.h | 72 - src/modules/gtk2/producer_pango.c | 721 -------- src/modules/gtk2/producer_pixbuf.c | 539 ------ src/modules/gtk2/scale_line_22_yuv_mmx.S | 227 --- src/modules/inigo/Makefile | 33 - src/modules/inigo/factory.c | 31 - src/modules/inigo/producer_inigo.c | 454 ----- src/modules/jackrack/Makefile | 47 - src/modules/jackrack/configure | 28 - src/modules/jackrack/factory.c | 31 - src/modules/jackrack/filter_jackrack.c | 372 ---- src/modules/jackrack/filter_ladspa.c | 190 -- src/modules/jackrack/jack_rack.c | 359 ---- src/modules/jackrack/jack_rack.h | 72 - src/modules/jackrack/lock_free_fifo.c | 117 -- src/modules/jackrack/lock_free_fifo.h | 53 - src/modules/jackrack/plugin.c | 596 ------- src/modules/jackrack/plugin.h | 88 - src/modules/jackrack/plugin_desc.c | 417 ----- src/modules/jackrack/plugin_desc.h | 81 - src/modules/jackrack/plugin_mgr.c | 321 ---- src/modules/jackrack/plugin_mgr.h | 53 - src/modules/jackrack/plugin_settings.c | 395 ----- src/modules/jackrack/plugin_settings.h | 76 - src/modules/jackrack/process.c | 600 ------- src/modules/jackrack/process.h | 76 - src/modules/kdenlive/Makefile | 37 - src/modules/kdenlive/factory.c | 34 - src/modules/kdenlive/filter_boxblur.c | 233 --- src/modules/kdenlive/filter_freeze.c | 118 -- src/modules/kdenlive/filter_wave.c | 139 -- src/modules/kdenlive/producer_framebuffer.c | 284 --- src/modules/kino/Makefile | 48 - src/modules/kino/avi.cc | 1707 ------------------ src/modules/kino/avi.h | 447 ----- src/modules/kino/configure | 31 - src/modules/kino/endian_types.h | 279 --- src/modules/kino/error.cc | 103 -- src/modules/kino/error.h | 51 - src/modules/kino/factory.c | 29 - src/modules/kino/filehandler.cc | 941 ---------- src/modules/kino/filehandler.h | 217 --- src/modules/kino/kino_wrapper.cc | 111 -- src/modules/kino/kino_wrapper.h | 45 - src/modules/kino/producer_kino.c | 145 -- src/modules/kino/riff.cc | 713 -------- src/modules/kino/riff.h | 143 -- src/modules/lumas/Makefile | 23 - src/modules/lumas/configure | 26 - src/modules/lumas/create_lumas | 48 - src/modules/lumas/luma.c | 441 ----- src/modules/motion_est/Makefile | 55 - src/modules/motion_est/README | 97 - src/modules/motion_est/arrow_code.c | 165 -- src/modules/motion_est/arrow_code.h | 26 - src/modules/motion_est/factory.c | 33 - .../motion_est/filter_autotrack_rectangle.c | 328 ---- src/modules/motion_est/filter_crop_detect.c | 244 --- src/modules/motion_est/filter_motion_est.c | 1115 ------------ src/modules/motion_est/filter_motion_est.h | 42 - src/modules/motion_est/filter_vismv.c | 144 -- src/modules/motion_est/producer_slowmotion.c | 419 ----- src/modules/motion_est/sad_sse.h | 429 ----- src/modules/normalize/Makefile | 33 - src/modules/normalize/factory.c | 29 - src/modules/normalize/filter_volume.c | 461 ----- src/modules/oldfilm/Makefile | 43 - src/modules/oldfilm/dust1.svg | 83 - src/modules/oldfilm/dust2.svg | 99 -- src/modules/oldfilm/dust3.svg | 59 - src/modules/oldfilm/dust4.svg | 113 -- src/modules/oldfilm/dust5.svg | 59 - src/modules/oldfilm/factory.c | 57 - src/modules/oldfilm/fdust.svg | 100 -- src/modules/oldfilm/filter_dust.c | 224 --- src/modules/oldfilm/filter_dust.yml | 47 - src/modules/oldfilm/filter_grain.c | 87 - src/modules/oldfilm/filter_grain.yml | 58 - src/modules/oldfilm/filter_lines.c | 134 -- src/modules/oldfilm/filter_lines.yml | 73 - src/modules/oldfilm/filter_oldfilm.c | 140 -- src/modules/oldfilm/filter_oldfilm.yml | 84 - src/modules/oldfilm/filter_tcolor.c | 85 - src/modules/oldfilm/filter_tcolor.yml | 45 - src/modules/oldfilm/filter_vignette.c | 127 -- src/modules/oldfilm/filter_vignette.yml | 35 - src/modules/oldfilm/grain.svg | 102 -- src/modules/oldfilm/lines.svg | 67 - src/modules/oldfilm/oldfilm.svg | 69 - src/modules/oldfilm/tcolor.svg | 87 - src/modules/oldfilm/vignette.svg | 96 - src/modules/plus/Makefile | 37 - src/modules/plus/factory.c | 37 - src/modules/plus/filter_affine.c | 133 -- src/modules/plus/filter_charcoal.c | 174 -- src/modules/plus/filter_invert.c | 89 - src/modules/plus/filter_sepia.c | 100 -- src/modules/plus/transition_affine.c | 610 ------- src/modules/qimage/Makefile | 41 - src/modules/qimage/configure | 128 -- src/modules/qimage/factory.c | 29 - src/modules/qimage/producer_qimage.c | 318 ---- src/modules/qimage/qimage_wrapper.cpp | 295 ---- src/modules/qimage/qimage_wrapper.h | 62 - src/modules/resample/Makefile | 35 - src/modules/resample/configure | 16 - src/modules/resample/factory.c | 29 - src/modules/resample/filter_resample.c | 200 --- src/modules/sdl/Makefile | 52 - src/modules/sdl/configure | 23 - src/modules/sdl/consumer_sdl.c | 856 --------- src/modules/sdl/consumer_sdl_osx_hack.h | 37 - src/modules/sdl/consumer_sdl_preview.c | 423 ----- src/modules/sdl/consumer_sdl_still.c | 645 ------- src/modules/sdl/factory.c | 40 - src/modules/sdl/producer_sdl_image.c | 262 --- src/modules/sox/Makefile | 35 - src/modules/sox/configure | 84 - src/modules/sox/factory.c | 29 - src/modules/sox/filter_sox.c | 500 ------ src/modules/valerie/Makefile | 34 - src/modules/valerie/consumer_valerie.c | 174 -- src/modules/valerie/factory.c | 29 - src/modules/vmfx/Makefile | 37 - src/modules/vmfx/factory.c | 37 - src/modules/vmfx/filter_chroma.c | 99 -- src/modules/vmfx/filter_chroma_hold.c | 100 -- src/modules/vmfx/filter_mono.c | 103 -- src/modules/vmfx/filter_shape.c | 230 --- src/modules/vmfx/producer_pgm.c | 209 --- src/modules/vorbis/Makefile | 37 - src/modules/vorbis/configure | 16 - src/modules/vorbis/factory.c | 29 - src/modules/vorbis/producer_vorbis.c | 371 ---- src/modules/westley/Makefile | 37 - src/modules/westley/configure | 16 - src/modules/westley/consumer_westley.c | 744 -------- src/modules/westley/factory.c | 32 - src/modules/westley/producer_westley.c | 1515 ---------------- src/modules/westley/westley.dtd | 64 - src/modules/xine/Makefile | 38 - src/modules/xine/attributes.h | 46 - src/modules/xine/cpu_accel.c | 232 --- src/modules/xine/deinterlace.c | 860 --------- src/modules/xine/deinterlace.h | 47 - src/modules/xine/factory.c | 29 - src/modules/xine/filter_deinterlace.c | 106 -- src/modules/xine/xineutils.h | 1098 ------------ src/tests/Makefile | 41 - src/tests/charlie.c | 193 -- src/tests/clock16ntsc.pgm | Bin 691217 -> 0 bytes src/tests/clock16pal.pgm | Bin 829457 -> 0 bytes src/tests/dan.c | 27 - src/tests/dissolve.c | 71 - src/tests/hello.c | 136 -- src/tests/io.c | 208 --- src/tests/io.h | 45 - src/tests/luma.c | 75 - src/tests/pango.c | 77 - src/tests/pixbuf.c | 72 - src/tests/setenv | 7 - src/tests/test.png | Bin 1352 -> 0 bytes 455 files changed, 0 insertions(+), 77707 deletions(-) delete mode 100644 demo/README delete mode 100644 demo/circle.png delete mode 100644 demo/circle.svg delete mode 100644 demo/consumers.ini delete mode 100755 demo/demo delete mode 100644 demo/demo.ini delete mode 100644 demo/demo.kino delete mode 100644 demo/entity.westley delete mode 100644 demo/luma1.pgm delete mode 100644 demo/mlt_all delete mode 100644 demo/mlt_attributes delete mode 100644 demo/mlt_audio_stuff delete mode 100644 demo/mlt_avantika_title delete mode 100644 demo/mlt_bouncy delete mode 100644 demo/mlt_bouncy_ball delete mode 100644 demo/mlt_clock_in_and_out delete mode 100644 demo/mlt_composite_transition delete mode 100644 demo/mlt_effect_in_middle delete mode 100644 demo/mlt_fade_black delete mode 100644 demo/mlt_fade_in_and_out delete mode 100644 demo/mlt_intro delete mode 100644 demo/mlt_jcut delete mode 100644 demo/mlt_lcut delete mode 100644 demo/mlt_levels delete mode 100644 demo/mlt_my_name_is delete mode 100644 demo/mlt_news delete mode 100644 demo/mlt_obscure delete mode 100644 demo/mlt_push delete mode 100644 demo/mlt_slideshow delete mode 100644 demo/mlt_slideshow_black delete mode 100644 demo/mlt_squeeze delete mode 100644 demo/mlt_squeeze_box delete mode 100644 demo/mlt_ticker delete mode 100644 demo/mlt_title_over_gfx delete mode 100644 demo/mlt_titleshadow_watermark delete mode 100644 demo/mlt_voiceover delete mode 100644 demo/mlt_watermark delete mode 100644 demo/new.westley delete mode 100644 demo/pango.westley delete mode 100644 demo/svg.westley delete mode 100644 demo/watermark1.png delete mode 100644 docs/framework.txt delete mode 100644 docs/inigo.txt delete mode 100644 docs/services.txt delete mode 100644 docs/westley.txt delete mode 100644 mlt++/AUTHORS delete mode 100644 mlt++/COPYING delete mode 100644 mlt++/ChangeLog delete mode 100644 mlt++/HOWTO delete mode 100644 mlt++/README delete mode 100644 mlt++/mlt++.sln delete mode 100644 mlt++/mlt++.vcproj delete mode 100644 mlt++/src/Mlt.h delete mode 100644 mlt++/src/MltConsumer.cpp delete mode 100644 mlt++/src/MltConsumer.h delete mode 100644 mlt++/src/MltDeque.cpp delete mode 100644 mlt++/src/MltDeque.h delete mode 100644 mlt++/src/MltEvent.cpp delete mode 100644 mlt++/src/MltEvent.h delete mode 100644 mlt++/src/MltFactory.cpp delete mode 100644 mlt++/src/MltFactory.h delete mode 100644 mlt++/src/MltField.cpp delete mode 100644 mlt++/src/MltField.h delete mode 100644 mlt++/src/MltFilter.cpp delete mode 100644 mlt++/src/MltFilter.h delete mode 100644 mlt++/src/MltFilteredConsumer.cpp delete mode 100644 mlt++/src/MltFilteredConsumer.h delete mode 100644 mlt++/src/MltFilteredProducer.cpp delete mode 100644 mlt++/src/MltFilteredProducer.h delete mode 100644 mlt++/src/MltFrame.cpp delete mode 100644 mlt++/src/MltFrame.h delete mode 100644 mlt++/src/MltGeometry.cpp delete mode 100644 mlt++/src/MltGeometry.h delete mode 100644 mlt++/src/MltMultitrack.cpp delete mode 100644 mlt++/src/MltMultitrack.h delete mode 100644 mlt++/src/MltPlaylist.cpp delete mode 100644 mlt++/src/MltPlaylist.h delete mode 100644 mlt++/src/MltProducer.cpp delete mode 100644 mlt++/src/MltProducer.h delete mode 100644 mlt++/src/MltProfile.cpp delete mode 100644 mlt++/src/MltProfile.h delete mode 100644 mlt++/src/MltProperties.cpp delete mode 100644 mlt++/src/MltProperties.h delete mode 100644 mlt++/src/MltPushConsumer.cpp delete mode 100644 mlt++/src/MltPushConsumer.h delete mode 100644 mlt++/src/MltRepository.cpp delete mode 100644 mlt++/src/MltRepository.h delete mode 100644 mlt++/src/MltService.cpp delete mode 100644 mlt++/src/MltService.h delete mode 100644 mlt++/src/MltTokeniser.cpp delete mode 100644 mlt++/src/MltTokeniser.h delete mode 100644 mlt++/src/MltTractor.cpp delete mode 100644 mlt++/src/MltTractor.h delete mode 100644 mlt++/src/MltTransition.cpp delete mode 100644 mlt++/src/MltTransition.h delete mode 100644 mlt++/swig/java/Play.java delete mode 100755 mlt++/swig/perl/play.pl delete mode 100755 mlt++/swig/php/play.php delete mode 100755 mlt++/swig/python/play.py delete mode 100755 mlt++/swig/ruby/play.rb delete mode 100755 mlt++/swig/ruby/thumbs.rb delete mode 100755 mlt++/swig/tcl/play.tcl delete mode 100644 mlt++/test/play.cpp delete mode 100644 mlt-framework.pc.in delete mode 100644 profiles/Makefile delete mode 100644 profiles/atsc_1080i_50 delete mode 100644 profiles/atsc_1080i_60 delete mode 100644 profiles/atsc_1080p_2398 delete mode 100644 profiles/atsc_1080p_24 delete mode 100644 profiles/atsc_1080p_25 delete mode 100644 profiles/atsc_1080p_2997 delete mode 100644 profiles/atsc_1080p_30 delete mode 100644 profiles/atsc_720p_30 delete mode 100644 profiles/cif_15 delete mode 100644 profiles/cif_ntsc delete mode 100644 profiles/cif_pal delete mode 100644 profiles/cvd_ntsc delete mode 100644 profiles/cvd_pal delete mode 100644 profiles/dv_ntsc delete mode 100644 profiles/dv_ntsc_wide delete mode 100644 profiles/dv_pal delete mode 100644 profiles/dv_pal_wide delete mode 100644 profiles/hdv_1080_25p delete mode 100644 profiles/hdv_1080_30p delete mode 100644 profiles/hdv_1080_50i delete mode 100644 profiles/hdv_1080_60i delete mode 100644 profiles/hdv_720_25p delete mode 100644 profiles/hdv_720_30p delete mode 100644 profiles/hdv_720_50p delete mode 100644 profiles/hdv_720_60p delete mode 100644 profiles/qcif_15 delete mode 100644 profiles/qcif_ntsc delete mode 100644 profiles/qcif_pal delete mode 100644 profiles/quarter_15 delete mode 100644 profiles/quarter_ntsc delete mode 100644 profiles/quarter_ntsc_wide delete mode 100644 profiles/quarter_pal delete mode 100644 profiles/quarter_pal_wide delete mode 100644 profiles/square_ntsc delete mode 100644 profiles/square_ntsc_wide delete mode 100644 profiles/square_pal delete mode 100644 profiles/square_pal_wide delete mode 100644 profiles/svcd_ntsc delete mode 100644 profiles/svcd_ntsc_wide delete mode 100644 profiles/svcd_pal delete mode 100644 profiles/svcd_pal_wide delete mode 100644 profiles/vcd_ntsc delete mode 100644 profiles/vcd_pal delete mode 100644 setenv delete mode 100644 setenv_mc delete mode 100644 src/framework/Makefile delete mode 100755 src/framework/configure delete mode 100644 src/framework/metaschema.yaml delete mode 100644 src/framework/mlt.h delete mode 100644 src/framework/mlt_cache.c delete mode 100644 src/framework/mlt_cache.h delete mode 100644 src/framework/mlt_consumer.c delete mode 100644 src/framework/mlt_consumer.h delete mode 100644 src/framework/mlt_deque.c delete mode 100644 src/framework/mlt_deque.h delete mode 100644 src/framework/mlt_events.c delete mode 100644 src/framework/mlt_events.h delete mode 100644 src/framework/mlt_factory.c delete mode 100644 src/framework/mlt_factory.h delete mode 100644 src/framework/mlt_field.c delete mode 100644 src/framework/mlt_field.h delete mode 100644 src/framework/mlt_filter.c delete mode 100644 src/framework/mlt_filter.h delete mode 100644 src/framework/mlt_frame.c delete mode 100644 src/framework/mlt_frame.h delete mode 100644 src/framework/mlt_geometry.c delete mode 100644 src/framework/mlt_geometry.h delete mode 100644 src/framework/mlt_log.c delete mode 100644 src/framework/mlt_log.h delete mode 100644 src/framework/mlt_multitrack.c delete mode 100644 src/framework/mlt_multitrack.h delete mode 100644 src/framework/mlt_parser.c delete mode 100644 src/framework/mlt_parser.h delete mode 100644 src/framework/mlt_playlist.c delete mode 100644 src/framework/mlt_playlist.h delete mode 100644 src/framework/mlt_pool.c delete mode 100644 src/framework/mlt_pool.h delete mode 100644 src/framework/mlt_producer.c delete mode 100644 src/framework/mlt_producer.h delete mode 100644 src/framework/mlt_profile.c delete mode 100644 src/framework/mlt_profile.h delete mode 100644 src/framework/mlt_properties.c delete mode 100644 src/framework/mlt_properties.h delete mode 100644 src/framework/mlt_property.c delete mode 100644 src/framework/mlt_property.h delete mode 100644 src/framework/mlt_repository.c delete mode 100644 src/framework/mlt_repository.h delete mode 100644 src/framework/mlt_service.c delete mode 100644 src/framework/mlt_service.h delete mode 100644 src/framework/mlt_tokeniser.c delete mode 100644 src/framework/mlt_tokeniser.h delete mode 100644 src/framework/mlt_tractor.c delete mode 100644 src/framework/mlt_tractor.h delete mode 100644 src/framework/mlt_transition.c delete mode 100644 src/framework/mlt_transition.h delete mode 100644 src/framework/mlt_types.h delete mode 100644 src/inigo/Makefile delete mode 100755 src/inigo/configure delete mode 100644 src/inigo/inigo.c delete mode 100644 src/inigo/io.c delete mode 100644 src/inigo/io.h delete mode 100644 src/modules/Makefile delete mode 100644 src/modules/avformat/Makefile delete mode 100644 src/modules/avformat/audioconvert.h delete mode 100755 src/modules/avformat/configure delete mode 100644 src/modules/avformat/consumer_avformat.c delete mode 100644 src/modules/avformat/factory.c delete mode 100644 src/modules/avformat/filter_avcolour_space.c delete mode 100644 src/modules/avformat/filter_avdeinterlace.c delete mode 100644 src/modules/avformat/filter_avresample.c delete mode 100644 src/modules/avformat/filter_swscale.c delete mode 100644 src/modules/avformat/mmx.h delete mode 100644 src/modules/avformat/producer_avformat.c delete mode 100644 src/modules/avformat/producer_avformat.yml delete mode 100755 src/modules/configure delete mode 100644 src/modules/core/Makefile delete mode 100644 src/modules/core/composite_line_yuv_mmx.S delete mode 100644 src/modules/core/consumer_null.c delete mode 100644 src/modules/core/factory.c delete mode 100644 src/modules/core/filter_brightness.c delete mode 100644 src/modules/core/filter_channelcopy.c delete mode 100644 src/modules/core/filter_crop.c delete mode 100644 src/modules/core/filter_data_feed.c delete mode 100644 src/modules/core/filter_data_show.c delete mode 100644 src/modules/core/filter_gamma.c delete mode 100644 src/modules/core/filter_greyscale.c delete mode 100644 src/modules/core/filter_luma.c delete mode 100644 src/modules/core/filter_mirror.c delete mode 100644 src/modules/core/filter_mono.c delete mode 100644 src/modules/core/filter_obscure.c delete mode 100644 src/modules/core/filter_region.c delete mode 100644 src/modules/core/filter_rescale.c delete mode 100644 src/modules/core/filter_resize.c delete mode 100644 src/modules/core/filter_transition.c delete mode 100644 src/modules/core/filter_watermark.c delete mode 100644 src/modules/core/producer_colour.c delete mode 100644 src/modules/core/producer_consumer.c delete mode 100644 src/modules/core/producer_noise.c delete mode 100644 src/modules/core/producer_ppm.c delete mode 100644 src/modules/core/transition_composite.c delete mode 100644 src/modules/core/transition_composite.h delete mode 100644 src/modules/core/transition_luma.c delete mode 100644 src/modules/core/transition_mix.c delete mode 100644 src/modules/core/transition_region.c delete mode 100644 src/modules/core/transition_region.h delete mode 100644 src/modules/data_fx.properties delete mode 100644 src/modules/dgraft/Makefile delete mode 100644 src/modules/dgraft/factory.c delete mode 100644 src/modules/dgraft/filter_telecide.c delete mode 100644 src/modules/dgraft/gpl delete mode 100644 src/modules/dv/Makefile delete mode 100755 src/modules/dv/configure delete mode 100644 src/modules/dv/consumer_libdv.c delete mode 100644 src/modules/dv/factory.c delete mode 100644 src/modules/dv/producer_libdv.c delete mode 100644 src/modules/effectv/Makefile delete mode 100644 src/modules/effectv/factory.c delete mode 100644 src/modules/effectv/filter_burn.c delete mode 100644 src/modules/effectv/gpl delete mode 100644 src/modules/effectv/image.c delete mode 100644 src/modules/effectv/utils.c delete mode 100644 src/modules/effectv/utils.h delete mode 100644 src/modules/feeds/Makefile delete mode 100644 src/modules/feeds/NTSC/data_fx.properties delete mode 100644 src/modules/feeds/NTSC/obscure.properties delete mode 100644 src/modules/feeds/PAL/border.properties delete mode 100644 src/modules/feeds/PAL/data_fx.properties delete mode 100644 src/modules/feeds/PAL/etv.properties delete mode 100644 src/modules/feeds/PAL/example.properties delete mode 100644 src/modules/feeds/PAL/obscure.properties delete mode 100644 src/modules/fezzik.dict delete mode 100644 src/modules/fezzik.ini delete mode 100644 src/modules/fezzik/Makefile delete mode 100644 src/modules/fezzik/factory.c delete mode 100644 src/modules/fezzik/producer_fezzik.c delete mode 100644 src/modules/fezzik/producer_hold.c delete mode 100644 src/modules/frei0r/Makefile delete mode 100755 src/modules/frei0r/configure delete mode 100644 src/modules/frei0r/factory.c delete mode 100644 src/modules/frei0r/filter_frei0r.c delete mode 100644 src/modules/frei0r/frei0r_helper.c delete mode 100644 src/modules/frei0r/frei0r_helper.h delete mode 100644 src/modules/frei0r/producer_frei0r.c delete mode 100644 src/modules/frei0r/transition_frei0r.c delete mode 100644 src/modules/gtk2/Makefile delete mode 100755 src/modules/gtk2/configure delete mode 100644 src/modules/gtk2/consumer_gtk2.c delete mode 100644 src/modules/gtk2/factory.c delete mode 100644 src/modules/gtk2/filter_rescale.c delete mode 100644 src/modules/gtk2/have_mmx.S delete mode 100644 src/modules/gtk2/pixops.c delete mode 100644 src/modules/gtk2/pixops.h delete mode 100644 src/modules/gtk2/producer_pango.c delete mode 100644 src/modules/gtk2/producer_pixbuf.c delete mode 100644 src/modules/gtk2/scale_line_22_yuv_mmx.S delete mode 100644 src/modules/inigo/Makefile delete mode 100644 src/modules/inigo/factory.c delete mode 100644 src/modules/inigo/producer_inigo.c delete mode 100644 src/modules/jackrack/Makefile delete mode 100755 src/modules/jackrack/configure delete mode 100644 src/modules/jackrack/factory.c delete mode 100644 src/modules/jackrack/filter_jackrack.c delete mode 100644 src/modules/jackrack/filter_ladspa.c delete mode 100644 src/modules/jackrack/gpl delete mode 100644 src/modules/jackrack/jack_rack.c delete mode 100644 src/modules/jackrack/jack_rack.h delete mode 100644 src/modules/jackrack/lock_free_fifo.c delete mode 100644 src/modules/jackrack/lock_free_fifo.h delete mode 100644 src/modules/jackrack/plugin.c delete mode 100644 src/modules/jackrack/plugin.h delete mode 100644 src/modules/jackrack/plugin_desc.c delete mode 100644 src/modules/jackrack/plugin_desc.h delete mode 100644 src/modules/jackrack/plugin_mgr.c delete mode 100644 src/modules/jackrack/plugin_mgr.h delete mode 100644 src/modules/jackrack/plugin_settings.c delete mode 100644 src/modules/jackrack/plugin_settings.h delete mode 100644 src/modules/jackrack/process.c delete mode 100644 src/modules/jackrack/process.h delete mode 100644 src/modules/kdenlive/Makefile delete mode 100644 src/modules/kdenlive/factory.c delete mode 100644 src/modules/kdenlive/filter_boxblur.c delete mode 100644 src/modules/kdenlive/filter_freeze.c delete mode 100644 src/modules/kdenlive/filter_wave.c delete mode 100644 src/modules/kdenlive/producer_framebuffer.c delete mode 100644 src/modules/kino/Makefile delete mode 100644 src/modules/kino/avi.cc delete mode 100644 src/modules/kino/avi.h delete mode 100755 src/modules/kino/configure delete mode 100644 src/modules/kino/endian_types.h delete mode 100644 src/modules/kino/error.cc delete mode 100644 src/modules/kino/error.h delete mode 100644 src/modules/kino/factory.c delete mode 100644 src/modules/kino/filehandler.cc delete mode 100644 src/modules/kino/filehandler.h delete mode 100644 src/modules/kino/gpl delete mode 100644 src/modules/kino/kino_wrapper.cc delete mode 100644 src/modules/kino/kino_wrapper.h delete mode 100644 src/modules/kino/producer_kino.c delete mode 100644 src/modules/kino/riff.cc delete mode 100644 src/modules/kino/riff.h delete mode 100644 src/modules/lumas/Makefile delete mode 100755 src/modules/lumas/configure delete mode 100755 src/modules/lumas/create_lumas delete mode 100644 src/modules/lumas/luma.c delete mode 100644 src/modules/motion_est/Makefile delete mode 100644 src/modules/motion_est/README delete mode 100644 src/modules/motion_est/arrow_code.c delete mode 100644 src/modules/motion_est/arrow_code.h delete mode 100644 src/modules/motion_est/factory.c delete mode 100644 src/modules/motion_est/filter_autotrack_rectangle.c delete mode 100644 src/modules/motion_est/filter_crop_detect.c delete mode 100644 src/modules/motion_est/filter_motion_est.c delete mode 100644 src/modules/motion_est/filter_motion_est.h delete mode 100644 src/modules/motion_est/filter_vismv.c delete mode 100644 src/modules/motion_est/gpl delete mode 100644 src/modules/motion_est/producer_slowmotion.c delete mode 100644 src/modules/motion_est/sad_sse.h delete mode 100644 src/modules/normalize/Makefile delete mode 100644 src/modules/normalize/factory.c delete mode 100644 src/modules/normalize/filter_volume.c delete mode 100644 src/modules/normalize/gpl delete mode 100644 src/modules/oldfilm/Makefile delete mode 100644 src/modules/oldfilm/dust1.svg delete mode 100644 src/modules/oldfilm/dust2.svg delete mode 100644 src/modules/oldfilm/dust3.svg delete mode 100644 src/modules/oldfilm/dust4.svg delete mode 100644 src/modules/oldfilm/dust5.svg delete mode 100644 src/modules/oldfilm/factory.c delete mode 100644 src/modules/oldfilm/fdust.svg delete mode 100644 src/modules/oldfilm/filter_dust.c delete mode 100644 src/modules/oldfilm/filter_dust.yml delete mode 100644 src/modules/oldfilm/filter_grain.c delete mode 100644 src/modules/oldfilm/filter_grain.yml delete mode 100644 src/modules/oldfilm/filter_lines.c delete mode 100644 src/modules/oldfilm/filter_lines.yml delete mode 100644 src/modules/oldfilm/filter_oldfilm.c delete mode 100644 src/modules/oldfilm/filter_oldfilm.yml delete mode 100644 src/modules/oldfilm/filter_tcolor.c delete mode 100644 src/modules/oldfilm/filter_tcolor.yml delete mode 100644 src/modules/oldfilm/filter_vignette.c delete mode 100644 src/modules/oldfilm/filter_vignette.yml delete mode 100644 src/modules/oldfilm/grain.svg delete mode 100644 src/modules/oldfilm/lines.svg delete mode 100644 src/modules/oldfilm/oldfilm.svg delete mode 100644 src/modules/oldfilm/tcolor.svg delete mode 100644 src/modules/oldfilm/vignette.svg delete mode 100644 src/modules/plus/Makefile delete mode 100644 src/modules/plus/factory.c delete mode 100644 src/modules/plus/filter_affine.c delete mode 100644 src/modules/plus/filter_charcoal.c delete mode 100644 src/modules/plus/filter_invert.c delete mode 100644 src/modules/plus/filter_sepia.c delete mode 100644 src/modules/plus/transition_affine.c delete mode 100644 src/modules/qimage/Makefile delete mode 100755 src/modules/qimage/configure delete mode 100644 src/modules/qimage/factory.c delete mode 100644 src/modules/qimage/gpl delete mode 100644 src/modules/qimage/producer_qimage.c delete mode 100644 src/modules/qimage/qimage_wrapper.cpp delete mode 100644 src/modules/qimage/qimage_wrapper.h delete mode 100644 src/modules/resample/Makefile delete mode 100755 src/modules/resample/configure delete mode 100644 src/modules/resample/factory.c delete mode 100644 src/modules/resample/filter_resample.c delete mode 100644 src/modules/resample/gpl delete mode 100644 src/modules/sdl/Makefile delete mode 100755 src/modules/sdl/configure delete mode 100644 src/modules/sdl/consumer_sdl.c delete mode 100644 src/modules/sdl/consumer_sdl_osx_hack.h delete mode 100644 src/modules/sdl/consumer_sdl_preview.c delete mode 100644 src/modules/sdl/consumer_sdl_still.c delete mode 100644 src/modules/sdl/factory.c delete mode 100644 src/modules/sdl/producer_sdl_image.c delete mode 100644 src/modules/sox/Makefile delete mode 100755 src/modules/sox/configure delete mode 100644 src/modules/sox/factory.c delete mode 100644 src/modules/sox/filter_sox.c delete mode 100644 src/modules/valerie/Makefile delete mode 100644 src/modules/valerie/consumer_valerie.c delete mode 100644 src/modules/valerie/factory.c delete mode 100644 src/modules/vmfx/Makefile delete mode 100644 src/modules/vmfx/factory.c delete mode 100644 src/modules/vmfx/filter_chroma.c delete mode 100644 src/modules/vmfx/filter_chroma_hold.c delete mode 100644 src/modules/vmfx/filter_mono.c delete mode 100644 src/modules/vmfx/filter_shape.c delete mode 100644 src/modules/vmfx/producer_pgm.c delete mode 100644 src/modules/vorbis/Makefile delete mode 100755 src/modules/vorbis/configure delete mode 100644 src/modules/vorbis/factory.c delete mode 100644 src/modules/vorbis/producer_vorbis.c delete mode 100644 src/modules/westley/Makefile delete mode 100755 src/modules/westley/configure delete mode 100644 src/modules/westley/consumer_westley.c delete mode 100644 src/modules/westley/factory.c delete mode 100644 src/modules/westley/producer_westley.c delete mode 100644 src/modules/westley/westley.dtd delete mode 100644 src/modules/xine/Makefile delete mode 100644 src/modules/xine/attributes.h delete mode 100644 src/modules/xine/cpu_accel.c delete mode 100644 src/modules/xine/deinterlace.c delete mode 100644 src/modules/xine/deinterlace.h delete mode 100644 src/modules/xine/factory.c delete mode 100644 src/modules/xine/filter_deinterlace.c delete mode 100644 src/modules/xine/gpl delete mode 100644 src/modules/xine/xineutils.h delete mode 100644 src/tests/Makefile delete mode 100644 src/tests/charlie.c delete mode 100644 src/tests/clock16ntsc.pgm delete mode 100644 src/tests/clock16pal.pgm delete mode 100644 src/tests/dan.c delete mode 100644 src/tests/dissolve.c delete mode 100644 src/tests/hello.c delete mode 100644 src/tests/io.c delete mode 100644 src/tests/io.h delete mode 100644 src/tests/luma.c delete mode 100644 src/tests/pango.c delete mode 100644 src/tests/pixbuf.c delete mode 100644 src/tests/setenv delete mode 100644 src/tests/test.png diff --git a/demo/README b/demo/README deleted file mode 100644 index a9a5a08..0000000 --- a/demo/README +++ /dev/null @@ -1,217 +0,0 @@ -MLT Demo Notes - -Before running the demo script, make sure you '. setenv' from the parent -directory. Also, please create clips clip1.dv, clip2.dv, clip3.dv, clip1.mpeg, -clip2.mpeg, clip3.mpeg, and music1.ogg. Please make sure clips are at least 500 -frames duration. - -These notes explain the the concepts presented in each demonstration and -what details to look for. - -First, a note on consumers. When you start the script, the main menu asks -you to choose a consumer. A consumer is like a viewer, but it could also -write to a stream/file. The "SDL" consumer is the popular Simple DirectMedia -Layer audio and video output. The "Westley" consumer generates an XML -representation of the service network. That can be played directly due to the -westley producer plugin. See docs/westley.txt for more information. The -"MainConcept DV" consumer refers to the proprietary MLT plugin required to -use MLT with MainConcept DV, DVCPro, and MPEG codecs. "/dev/dv1394/0" refers -to a device file for transmitting DV over FireWire using the Linux dv1394 kernel -module. The "BlueFish444" consumer is another proprietary plugin to use -the BlueFish444 manufactured SDI video/audio output cards with MLT. - -And now the demos... - -All clips - - Simply builds a playlist containing each video clip, and you can transport - between them using j and k keys. - -Filter in/out - - A video filter can be applied to a portion of a producer (clip, playlist, - or multitrack). This examples shows the greyscale filter. - -Watermark - - A graphic can overlay video in realtime with support for alpha channel. - This example uses a PNG file with an alpha channel. Distortion is explicitly - enabled here so the otherwise circular graphic is scaled to fill the - compositing region. By default, compositing honours the aspect ratio of the - overlay. - -My name is... - - Titles are very easy to composite in realtime. The titler uses Pango - with the FreeType2 rendering backend. This means it supports high - quality scalable font rendering with anti-aliasing, unicode (UTF-8), - and Pango markup capabilities. The compsiting here respects the aspect - ratio of the rendered title in the first two title pieces but distorts - the final one. This demo also shows the motion and scaling capabilities - of the compositor in conjunction with honouring aspect. The compositor - is doing field-based rendering. So, when displayed non-progressively - with SDL, you can see motion artifacts during animation. - -A composite transition - - The compositor also handles video over video as demonstrated in this - usage of the compositor to create a special transition. This demonstration - also crossfades the audio during the transition! Progressive rendering - is explicitly enabled on the compositor due to the poor results that - would otherwise occur due to scaling an interleaved video frame and moving - the video in a reverse direction horizontally. - -Fade in and out - - A simple series of transitions betwen 3 clips using dissolves and audio - crossfades. This is easy :-). - -Clock in and out - - Wipe transitions are very easy and highly extensible as they are generated - using a very convenient lookup table based upon the luma of an image. - This image can be a 16 bit PGM (grayscale bitmap) or the luma channel of - any video producer. A number of high quality wipes can be downloaded from - http://mlt.sf.net/. It also performs field rendering. - The second wipe demonstrates the ability to control the direction of the - wipe as well. - -Obscure - - A popular requirement in news production is to obscure a face, obscenity, - or trademarked logo. This demonstrates using a simple rectangular - obscure filter applied to a region of the image. The second example is more - advanced and shows using the "region" filter to select the image area and a - property of the region filter to "shape" the region using the alpha channel - of another image (circle.png) and another property to "filter" the region - using the obscure filter. - -Audio Stuff - - A music bed sound track can be mixed with a video. The sound track of the - video clip has a "floating" amplitude normalisation filter applied. - Typically, audio normalisation applies a constant gain factor across the - entire duration of an audio segment from a single source where the - gain factor is automatically determined by anaylsing the maximum "power" - or peak levels. However, in news production, a popular requirement is to - to dynamically boost the amplitude in soft areas and reduce the amplitude - in louder areas. Thus, the gain analysis is performed using a "sliding - window" approach. This example also applies a constant gain factor of - 0.5 (50%) to the normalised audio of the video clip (to get a nicer - mix level). - -Audio and Video Levels - - Audio can be normalised by setting a target amplitude level in decibels. - A gamma curve can be applied to the luma channel of video. - -Shadowed Title and Watermark - - Two instances of the titler are used to create a shadow effect. - The aspect ratio of the watermark in this example is not distorted. Since - the original image is a circle with square pixels--a computer-generated - image--and ITU BT.601 video is not composed of square samples. Therefore, - the compositor normalises the pixel aspect ratio of the overlay to the - destination image, and the circular image remains circular on the analog - video output. Finally, a greyscale filter is applied to the watermark - while its opacity is set at 30%. - -Station Promo into Story? - - Here is fun demo that might show using a still graphic with some music - to introduce a show. A luma wipe with an audio crossfade transitions from - the show title or station promotional material. - -Voiceover 2 clips with title - - A common news production requirement to have a "voiceover" audio track - to a clip or even multiple clips as demonstrated here. Likewise, it is - common to place a title caption on the video at the same time! This - demo has a little fun with the titler at the sake of practicality :-) - The foreground of the title is transparent while the opacity of the - background is reduced to blend with the video. Meanwhile, the compositor - stretches the image to fill the bottom slice of the video--not suitable - for overscan displays ;-) - - Also, pay close attention to the mixing levels of the audio tracks. - The audio of the video fades out as the voiceover track (just music - in this demo) fades in. Then, the voiceover remains mixed with the - ambient audio at a 60% level. Finally, the voiceover fades out smoothly - from the 60% level to nothing. - -GJ-TTAvantika title - - This demo requires a special TrueType font called Avantika. If you have the - font, register it with fontconfig using the fc-cache utility. This - demonstrates i18n capabilities of the titler and the alignment capabilities - of both the titler and the compositor. The titler centre aligns - the two lines of text, and the compositor centre aligns the title - horizontally on the frame. - -Title over graphic - - You can superimpose a title over a graphic over video! Also, - you can apply a luma wipe to the compositor! - -Slideshow - - This demo requires any number of JPEG images with the extension ".jpg" - in a subdirectory named "Scotland." - -Bouncy, Bouncy - - The "watermark" filter encapsulates the compositor, and you have full - control over the compositor properties. Who says a watermark can not - also be a video?! - -Bouncy, Bouncy Ball - - A variation on the above Bouncy, Bouncy demo that applies a shape, or - alpha producer, to the the compositing region. - -Breaking News - - This demonstrates layout capabilities of the compositor. - -Squeeze Transitions - - This demonstrates a distorting barndoor-like wipe. - - -J Cut - - A J cut is an edit where the audio cuts before the video. - It gets its name from the way it looks on a NLE timeline user interface. - When the audio cuts over, it does an audio crossfade over the duration of - one frame. This makes the audio cut slightly less abrupt and avoids any - "click" due to mismatched sample levels at the edit point. The video edit - is a hard cut. - -L Cut - - An L cut is an edit where the video cuts before the audio. - It gets its name from the way it looks on a NLE timeline user interface. - This demo shows a very quick dissolve over 5 frames for a soft video cut. - Like the J Cut demo, an audio crossfade for the duration of one frame makes - an audio edit nearly instantaneous while being slightly softened and - avoiding aberrations. - -Fade from/to black/silence - - Of course, it is possible using MLT to fade from black on video and silence - on audio as well fade to black and silence. - -Push wipe - - A push wipe is a somewhat fancier transition than most standard wipes - because it involves motion. The new video clip "pushes" the old video - clip off one edge. If you can preview on an analog monitor you will notice - how smooth the motion is due to field-based rendering. - -Ticker tape - - A very minimal reverse crawling title neard the bottom of the screen. - The goal of the demo is show fluid motion of the field-based rendering of - the compositor when viewed on an analog monitor using a DV or BlueFish444 - consumer. The demo also shows the potientional for using and extending the - existing set of services for a full blown news ticker implementation. diff --git a/demo/circle.png b/demo/circle.png deleted file mode 100644 index b597928620f1e8fa94978fd1c66f41fc28dcdbf0..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 5239 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 diff --git a/demo/consumers.ini b/demo/consumers.ini deleted file mode 100644 index b02695f..0000000 --- a/demo/consumers.ini +++ /dev/null @@ -1,12 +0,0 @@ -SDL Default sdl -SDL Half D1 sdl:360x288 rescale=nearest resize=1 -SDL High Latency sdl buffer=12 rescale=none -SDL Progressive sdl progressive=1 -Westley to Terminal westley -Westley to File westley: -MainConcept DV to /dev/dv1394/0 mcdv:/dev/dv1394/0 rescale=nearest buffer=25 -libdv to /dev/dv1394/0 libdv:/dev/dv1394/0 rescale=nearest buffer=25 -BlueFish444 PAL bluefish:1 -BlueFish444 NTSC bluefish:1 standard=NTSC -BlueFish444 PAL Prog LL bluefish:1 progressive=1 buffer=1 frames=4 -BlueFish444 NTSC Prog LL bluefish:1 standard=NTSC progressive=1 buffer=1 frames=4 diff --git a/demo/demo b/demo/demo deleted file mode 100755 index 98777ca..0000000 --- a/demo/demo +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/bash - -function show_consumers( ) -{ - awk -F '\t' '{ printf( "%d. %s\n", ++ i, $1 ); }' < consumers.ini -} - -function get_consumer( ) -{ - option=$1 - [ "$option" != "" ] && [ $option -gt 0 ] && sed 's/\t\+/\t/g' < consumers.ini | cut -f 2 | head -n $option | tail -n -1 -} - -function show_menu( ) -{ - sed 's/\t\+/\t/g' < demo.ini | - awk -F '\t' '{ printf( "%2d. %-30.30s", ++ i, $2 ); if ( i % 2 == 0 ) printf( "\n" ); } END { if ( i % 2 == 1 ) printf( "\n" ); }' -} - -function check_dependencies( ) -{ - option=$1 - if [ $option -gt 0 ] - then - deps=`sed 's/\t\+/\t/g' < demo.ini | cut -f 3 | head -n $option | tail -n -1` - if [ "$deps" != "" ] - then - echo "$deps" | - tr ',' '\n' | - while read dep - do - ls $dep > /dev/null 2>&1 - val=$? - [ $val != 0 ] && echo Failed to find $dep >&2 && echo $val - done - fi - echo 0 - fi -} - -function get_demo( ) -{ - option=$1 - if [ $option -gt 0 ] - then - cut -f 1 demo.ini | head -n $option | tail -n -1 - fi -} - -while [ 1 ] -do - - echo Select Consumer - echo - - show_consumers - - echo - echo 0. Exit - echo - echo -n "Option: " - read option - echo - - [ "$option" == "0" ] && break - - export MLT_CONSUMER=`get_consumer $option` - - while [ "$option" != "0" -a "$MLT_CONSUMER" != "" ] - do - echo Choose Demo - echo - - show_menu - - echo - echo -n "Option: " - read option - echo - - [ "$option" == "" ] && break - - demo=`get_demo $option` - usable=`check_dependencies $option` - - if [ "$usable" = "0" -a "$demo" != "" ] - then - if [ "$MLT_CONSUMER" == "westley:" ] - then export WESTLEY_CONSUMER="westley:$demo.westley" - bash $demo -consumer $WESTLEY_CONSUMER - inigo +$demo.txt out=100 $demo.westley $demo.westley -filter watermark:watermark1.png composite.fill=1 composite.geometry=85%,5%:10%x10% - elif [ "$MLT_CONSUMER" == "westley" ] - then bash $demo -consumer $MLT_CONSUMER | less - else bash $demo -consumer $MLT_CONSUMER - fi - elif [ "$usable" != "" ] - then - echo - echo Unable to locate suitable files for the demo - please provide them. - read pause - fi - - stty sane - done - -done diff --git a/demo/demo.ini b/demo/demo.ini deleted file mode 100644 index b01b049..0000000 --- a/demo/demo.ini +++ /dev/null @@ -1,28 +0,0 @@ -mlt_all All clips clip* -mlt_effect_in_middle Filter in/out clip1.mpeg -mlt_watermark Watermark clip2.dv,watermark1.png -mlt_my_name_is My name is... clip3.dv -mlt_composite_transition A composite transition clip1.dv,clip2.mpeg -mlt_fade_in_and_out Fade in and out clip1.dv,clip2.mpeg,clip3.dv -mlt_clock_in_and_out Clock in and out clip2.dv,clip1.dv,clip3.mpeg -mlt_obscure Obscure clip2.mpeg,circle.png -mlt_audio_stuff Audio Stuff clip*.dv,music1.ogg -mlt_levels Audio and Video Levels clip*.dv -mlt_titleshadow_watermark Shadowed Title and Watermark clip3.dv -mlt_intro Station Promo into Story? watermark1.png,clip3.mpeg,music1.ogg -mlt_voiceover Voiceover 2 clips with title clip1.dv,clip2.mpeg,music1.ogg -mlt_avantika_title GJ-TTAvantika title pango.westley -mlt_title_over_gfx Title over graphic watermark1.png,clip1.dv -mlt_slideshow Slideshow Scotland -mlt_bouncy Bouncy, Bouncy clip1.dv,clip3.dv -mlt_bouncy_ball Bouncy, Bouncy Ball clip1.mpeg,clip3.mpeg,circle.png -mlt_news Breaking News clip1.dv,clip2.dv -mlt_squeeze Squeeze Transitions clip1.dv,clip2.dv,clip3.dv -mlt_squeeze_box Squeeze Box clip1.dv,clip2.dv,clip3.dv -mlt_jcut J Cut clip1.dv,clip2.dv -mlt_lcut L Cut clip1.dv,clip2.dv -mlt_fade_black Fade from/to black/silence clip3.mpeg -mlt_push Push wipe clip1.mpeg, clip2.mpeg -mlt_ticker Ticker tape clip1.dv -mlt_attributes Attributes clip1.dv -mlt_slideshow_black Composite slideshow Scotland diff --git a/demo/demo.kino b/demo/demo.kino deleted file mode 100644 index 99e8767..0000000 --- a/demo/demo.kino +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/demo/entity.westley b/demo/entity.westley deleted file mode 100644 index 0f6a6b9..0000000 --- a/demo/entity.westley +++ /dev/null @@ -1,11 +0,0 @@ - - -]> - - - pango - Hello &name;, -My name is Inigo Montoya. - - diff --git a/demo/luma1.pgm b/demo/luma1.pgm deleted file mode 100644 index ac689e5bd7b1afea69b2619d440722853caa1405..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 414735 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 z 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 - - - - - clip2.mpeg - - - - - - - - clip3.mpeg - - - - - - greyscale - - - luma - - - - - - - - - - - - - - - - - - - - - luma - - - 1 - - - - diff --git a/demo/pango.westley b/demo/pango.westley deleted file mode 100644 index 4684d48..0000000 --- a/demo/pango.westley +++ /dev/null @@ -1,34 +0,0 @@ - - - - clip1.dv - - - pango - +.txt - GJ-TTAvantika 36 - 1 - 0xffffddff - 0x8c101080 - 8 - - - - - - - - - composite - 1 - 0 - -70%,65%:100%x35%:0 - 0,65%:100%x35%:100 - 0,65%:100%x35%:100 - 0,65%:100%x35%:0 - centre - centre - - - diff --git a/demo/svg.westley b/demo/svg.westley deleted file mode 100644 index a41ff4a..0000000 --- a/demo/svg.westley +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - -]> - - - - - pixbuf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/watermark1.png b/demo/watermark1.png deleted file mode 100644 index 1ec3e5770f11e04f3a560ad3533be07a17c5ad29..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 1353 zc-jF;1-AN$P)+A}IxIA!t5eX)>6}C|Ef+fB0}NunzcLQN30F3aF@FSy8$u^jbg2p99%zeyCabD6T4#1C~WD5XOD=n#(8G&7j z>Rpf$sHoog>0kg}Ux>D@FaQsv1`dhlQdF-p0;s6oB4B&UKu#2=DK1gPcQ?}{Bw}@8)2TFZUrC`g)_edIe0q2cjtnH!dfylRc@E_yzHo6wi=i` z8ZZ>rIPU2~sjy(T87M6>QeczG%Fr#71eDs1)Kq6t`-omHHv>^RyCaEe{`PsAPD#L| z#L=t_iFGg7`Sh)^eEg<^n(8bB(Ayv7)lFBqa7FK4cAK6Dng+)`eMF+VRn{zt+DEMH ze#61n8%oK^jJtahfCQQ&Hd0Y)=HNTyd3;J1ca1esS!QOvYG+GbF&48l0tz4m>^#!V zjFqi4?!V4&e}&?6dyo0)4Mtf+ZR5ga-5N)Mf$jAr6y(YT`lGy(VCmFK3k{3)k^#8X8X5)z5FJA< z73}~e1$vKe>kKn6sGqdUAK|6<+By5jEda`jjBHy`f;CGT0ez?{lMh}i9<33y4*@v` zaI;s>sQV_GslF#8zG`4lW9j=>X+E!amkGs2KCCMt!z4yPPoEE>C9MdEab!pJGJtu1 zwhc08x)q~AP@`mX;%pz?0X^W6C>-+yx&Q7AO7aa9KrHcjn*0)Q1nBAL4zqr57XTS1!H)V8${n}cRyd+jzx5ie9fJVOud$ME)f4Jg zNaKs<-jt>RKe%1aRshNEa)!`vY7U(Vu;-{BfH65T+g23c0S)v=Y20@m0D~-2-G@m; ztc`ues&XSkLEU`d1_w^|-T@tNzkTV;lAaYBx8t5hn%yqvSMmJ-K2KBFQN7FqJOjw5 zehN~MYoM~sjKwTb`=}LJ5)_Rw@cO)bEM|#)$9p*H?n?*j1ZMg?P2F)@6K56Gs{%V> z|1UmaLw$102rZXd2UzrOd%Vz7NCOcm8T4YV&o+-%Xu@|lf -Last Revision: 2004-10-08 - - -MLT FRAMEWORK -------------- - -Preamble: - - MLT is a multimedia framework designed for television broadcasting. As such, - it provides a pluggable architecture for the inclusion of new audio/video - sources, filters, transitions and playback devices. - - The framework provides the structure and utility functionality on which - all of the MLT applications and services are defined. - - On its own, the framework provides little more than 'abstract classes' and - utilities for managing resources, such as memory, properties, dynamic object - loading and service instantiation. - - This document is split roughly into 3 sections. The first section provides a - basic overview of MLT, the second section shows how it's used and the final - section shows structure and design, with an emphasis on how the system is - extended. - - -Target Audience: - - This document is provided as a 'road map' for the framework and should be - considered mandatory reading for anyone wishing to develop code at the MLT - level. - - This includes: - - 1. framework maintainers; - 2. module developers; - 3. application developers; - 4. anyone interested in MLT. - - The emphasis of the document is in explaining the public interfaces, as - opposed to the implementation details. - - It is not required reading for the MLT client/server integration - please - refer to valerie.txt and dvcp.txt for more details on this area. - - -SECTION 1 - BASIC OVERVIEW --------------------------- - -Basic Design Information: - - MLT is written in C. - - The framework has no dependencies other than the standard C99 and POSIX - libraries. - - It follows a basic Object Oriented design paradigm, and as such, much of the - design is loosely based on the Producer/Consumer design pattern. - - It employs Reverse Polish Notation for the application of audio and video FX. - - The framework is designed to be colour space neutral - the currently - implemented modules, however, are very much 8bit YUV422 oriented. In theory, - the modules could be entirely replaced. - - A vague understanding of these terms is assumed throughout the remainder of - this document. - - -Structure and Flow: - - The general structure of an MLT 'network' is simply the connection of a - 'producer' to a 'consumer': - - +--------+ +--------+ - |Producer|-->|Consumer| - +--------+ +--------+ - - A typical consumer requests MLT Frame objects from the producer, does - something with them and when finished with a frame, closes it. - - /\ A common confusion with the producer/consumer terminology used here is - /!!\ that a consumer may 'produce' something. For example, the libdv consumer - \!!/ produces DV and the libdv producer seems to consume DV. However, the - \/ naming conventions refer only to producers and consumers of MLT Frames. - - To put it another way - a producer produces MLT Frame objects and a consumer - consumes MLT Frame objects. - - An MLT Frame essentially provides an uncompressed image and its associated - audio samples. - - Filters may also be placed between the producer and the consumer: - - +--------+ +------+ +--------+ - |Producer|-->|Filter|-->|Consumer| - +--------+ +------+ +--------+ - - A service is the collective name for producers, filters, transitions and - consumers. - - The communications between a connected consumer and producer or service are - carried out in 3 phases: - - * get the frame - * get the image - * get the audio - - MLT employs 'lazy evaluation' - the image and audio need not be extracted - from the source until the get image and audio methods are invoked. - - In essence, the consumer pulls from what it's connected to - this means that - threading is typically in the domain of the consumer implementation and some - basic functionality is provided on the consumer class to ensure realtime - throughput. - - -SECTION 2 - USAGE ------------------ - -Hello World: - - Before we go in to the specifics of the framework architecture, a working - example of usage is provided. - - The following simply provides a media player: - - #include - #include - #include - - int main( int argc, char *argv[] ) - { - // Initialise the factory - if ( mlt_factory_init( NULL ) == 0 ) - { - // Create the default consumer - mlt_consumer hello = mlt_factory_consumer( NULL, NULL ); - - // Create via the default producer - mlt_producer world = mlt_factory_producer( NULL, argv[ 1 ] ); - - // Connect the producer to the consumer - mlt_consumer_connect( hello, mlt_producer_service( world ) ); - - // Start the consumer - mlt_consumer_start( hello ); - - // Wait for the consumer to terminate - while( !mlt_consumer_is_stopped( hello ) ) - sleep( 1 ); - - // Close the consumer - mlt_consumer_close( hello ); - - // Close the producer - mlt_producer_close( world ); - - // Close the factory - mlt_factory_close( ); - } - else - { - // Report an error during initialisation - fprintf( stderr, "Unable to locate factory modules\n" ); - } - - // End of program - return 0; - } - - This is a simple example - it doesn't provide any seeking capabilities or - runtime configuration options. - - The first step of any MLT application is the factory initialisation - this - ensures that the environment is configured and MLT can function. The factory - is covered in more detail below. - - All services are instantiated via the factories, as shown by the - mlt_factory_consumer and mlt_factory_producer calls above. There are similar - factories for filters and transitions. There are details on all the standard - services in services.txt. - - The defaults requested here are a special case - the NULL usage requests - that we use the default producers and consumers. - - The default producer is "fezzik". This producer matches file names to - locate a service to use and attaches 'normalising filters' (such as scalers, - deinterlacers, resamplers and field normalisers) to the loaded content - - these filters ensure that the consumer gets what it asks for. - - The default consumer is "sdl". The combination of fezzik and sdl will - provide a media player. - - In this example, we connect the producer and then start the consumer. We - then wait until the consumer is stopped (in this case, by the action of the - user closing the SDL window) and finally close the consumer, producer and - factory before exiting the application. - - Note that the consumer is threaded - waiting for an event of some sort is - always required after starting and before stopping or closing the consumer. - - Also note, you can override the defaults as follows: - - $ MLT_CONSUMER=westley ./hello file.avi - - This will create a westley xml document on stdout. - - $ MLT_CONSUMER=westley MLT_PRODUCER=avformat ./hello file.avi - - This will play the video using the avformat producer directly, thus it will - bypass the normalising functions. - - $ MLT_CONSUMER=libdv ./hello file.avi > /dev/dv1394 - - This might, if you're lucky, do on the fly, realtime conversions of file.avi - to DV and broadcast it to your DV device. - - -Factories: - - As shown in the 'Hello World' example, factories create service objects. - - The framework itself provides no services - they are provided in the form of - a plugin structure. A plugin is organised in the form of a 'module' and a - module can provide many services of different types. - - Once the factory is initialised, all the configured services are available - for use. - - The complete set of methods associated to the factory are as follows: - - int mlt_factory_init( char *prefix ); - const char *mlt_factory_prefix( ); - char *mlt_environment( char *name ); - mlt_producer mlt_factory_producer( char *name, void *input ); - mlt_filter mlt_factory_filter( char *name, void *input ); - mlt_transition mlt_factory_transition( char *name, void *input ); - mlt_consumer mlt_factory_consumer( char *name, void *input ); - void mlt_factory_close( ); - - The mlt_factory_prefix returns the path to the location of the installed - modules directory. This can be specified in the mlt_factory_init call - itself, or it can be specified via the MLT_REPOSITORY environment variable, - or in the absence of either of those, it will default to the install - prefix/shared/mlt/modules. - - The mlt_environment provides read only access to a collection of name=value - pairs as shown in the following table: - - +------------------+------------------------------------+------------------+ - |Name |Description |Values | - +------------------+------------------------------------+------------------+ - |MLT_NORMALISATION |The normalisation of the system |PAL or NTSC | - +------------------+------------------------------------+------------------+ - |MLT_PRODUCER |The default producer |"fezzik" or other | - +------------------+------------------------------------+------------------+ - |MLT_CONSUMER |The default consumer |"sdl" or other | - +------------------+------------------------------------+------------------+ - |MLT_TEST_CARD |The default test card producer |any producer | - +------------------+------------------------------------+------------------+ - - These values are initialised from the environment variables of the same - name. - - As shown above, a producer can be created using the 'default normalising' - producer, and they can also be requested by name. Filters and transitions - are always requested by name - there is no concept of a 'default' for these. - - -Service Properties: - - As shown in the services.txt document, all services have their own set of - properties than can be manipulated to affect their behaviour. - - In order to set properties on a service, we need to retrieve the properties - object associated to it. For producers, this is done by invoking: - - mlt_properties properties = mlt_producer_properties( producer ); - - All services have a similar method associated to them. - - Once retrieved, setting and getting properties can be done directly on this - object, for example: - - mlt_properties_set( properties, "name", "value" ); - - A more complete description of the properties object is found below. - - -Playlists: - - So far, we've shown a simple producer/consumer configuration - the next - phase is to organise producers in playlists. - - Let's assume that we're adapting the Hello World example, and wish to queue - a number of files for playout, ie: - - hello *.avi - - Instead of invoking mlt_factory_producer directly, we'll create a new - function called create_playlist. This function is responsible for creating - the playlist, creating each producer and appending to the playlist. - - mlt_producer create_playlist( int argc, char **argv ) - { - // We're creating a playlist here - mlt_playlist playlist = mlt_playlist_init( ); - - // We need the playlist properties to ensure clean up - mlt_properties properties = mlt_playlist_properties( playlist ); - - // Loop through each of the arguments - int i = 0; - for ( i = 1; i < argc; i ++ ) - { - // Create the producer - mlt_producer producer = mlt_factory_producer( NULL, argv[ i ] ); - - // Add it to the playlist - mlt_playlist_append( playlist, producer ); - - // Close the producer (see below) - mlt_producer_close( producer ); - } - - // Return the playlist as a producer - return mlt_playlist_producer( playlist ); - } - - Notice that we close the producer after the append. Actually, what we're - doing is closing our reference to it - the playlist creates its own reference - to the producer on append and insert, and it will close its reference - when the playlist is destroyed[*]. - - Note also that if you append multiple instances of the same producer, it - will create multiple references to it. - - Now all we need do is to replace these lines in the main function: - - // Create a normalised producer - mlt_producer world = mlt_factory_producer( NULL, argv[ 1 ] ); - - with: - - // Create a playlist - mlt_producer world = create_playlist( argc, argv ); - - and we have a means to play multiple clips. - - [*] This reference functionality was introduced in mlt 0.1.2 - it is 100% - compatable with the early mechanism of registering the reference and - destructor with the properties of the playlist object. - - -Filters: - - Inserting filters between the producer and consumer is just a case of - instantiating the filters, connecting the first to the producer, the next - to the previous filter and the last filter to the consumer. - - For example: - - // Create a producer from something - mlt_producer producer = mlt_factory_producer( ... ); - - // Create a consumer from something - mlt_consumer consumer = mlt_factory_consumer( ... ); - - // Create a greyscale filter - mlt_filter filter = mlt_factory_filter( "greyscale", NULL ); - - // Connect the filter to the producer - mlt_filter_connect( filter, mlt_producer_service( producer ), 0 ); - - // Connect the consumer to filter - mlt_consumer_connect( consumer, mlt_filter_service( filter ) ); - - As with producers and consumers, filters can be manipulated via their - properties object - the mlt_filter_properties method can be invoked and - properties can be set as needed. - - The additional argument in the filter connection is an important one as it - dictates the 'track' on which the filter operates. For basic producers and - playlists, there's only one track (0), and as you will see in the next - section, even multiple tracks have a single track output. - - -Attached Filters: - - All services can have attached filters. - - Consider the following example: - - // Create a producer - mlt_producer producer = mlt_factory_producer( NULL, clip ); - - // Get the service object of the producer - mlt_producer service = mlt_producer_service( producer ); - - // Create a filter - mlt_filter filter = mlt_factory_filter( "greyscale" ); - - // Create a playlist - mlt_playlist playlist = mlt_playlist_init( ); - - // Attach the filter to the producer - mlt_service_attach( producer, filter ); - - // Construct a playlist with various cuts from the producer - mlt_playlist_append_io( producer, 0, 99 ); - mlt_playlist_append_io( producer, 450, 499 ); - mlt_playlist_append_io( producer, 200, 399 ); - - // We can close the producer and filter now - mlt_producer_close( producer ); - mlt_filter_close( filter ); - - When this is played out, the greyscale filter will be executed for each frame - in the playlist which comes from that producer. - - Further, each cut can have their own filters attached which are executed after - the producer's filters. As an example: - - // Create a new filter - filter = mlt_factory_filter( "invert", NULL ); - - // Get the second 'clip' in the playlist - producer = mlt_playlist_get_clip( 1 ); - - // Get the service object of the clip - service = mlt_producer_service( producer ); - - // Attach the filter - mlt_service_attach( producer, filter ); - - // Close the filter - mlt_filter_close( filter ); - - Even the playlist itself can have an attached filter: - - // Create a new filter - filter = mlt_factory_filter( "watermark", "+Hello.txt" ); - - // Get the service object of the playlist - service = mlt_playlist_service( playlist ); - - // Attach the filter - mlt_service_attach( service, filter ); - - // Close the filter - mlt_filter_close( filter ); - - And, of course, the playlist, being a producer, can be cut up and placed on - another playlist, and filters can be attached to those cuts or on the new - playlist itself and so on ad nauseum. - - The main advantage of attached filters is that they remain attached and don't - suffer from the maintenance problems associated with items being inserted and - displacing calculated in/out points - this being a major issue if you - exclusively use the connect or insert detached filters in a multitrack field - (described below). - - -Introducing the Mix: - - The mix is the simplest way to introduce transitions between adjacent clips - on a playlist. - - Consider the following playlist: - - +-+----------------------+----------------------------+-+ - |X|A |B |X| - +-+----------------------+----------------------------+-+ - - Let's assume that the 'X' is a 'black clip' of 50 frames long. - - When you play this out, you'll get a 50 frames of black, abrupt cut into - A, followed by an abrupt cut into B, and finally into black again. - - The intention is to convert this playlist into something like: - - +-+---------------------+-+------------------------+-+ - |X|A |A|B |B| - |A| |B| |X| - +-+---------------------+-+------------------------+-+ - - Where the clips which refer to 2 clips represent a transition. Notice that - the representation of the second playlist is shorter than the first - this is - to be expected - a single transition of 50 frames between two clips will - reduce the playtime of the result by 50 frames. - - This is done via the use of the mlt_playlist_mix method. So, assuming you get - a playlist as shown in the original diagram, to do the first mix, you could do - something like: - - // Create a transition - mlt_transition transition = mlt_factor_transition( "luma", NULL ); - - // Mix the first and second clips for 50 - mlt_playlist_mix( playlist, 0, 50, transition ); - - // Close the transition - mlt_transition_close( transition ); - - This would give you the first transition, subsequently, you would apply a similar - technique to mix clips 1 and 2. Note that this would create a new clip on the - playlist, so the next mix would be between 3 and 4. - - As a general hint, to simplify the requirement to know the next clip index, - you might find the following simpler: - - // Get the number of clips on the playlist - int i = mlt_playlist_count( ); - - // Iterate through them in reverse order - while ( i -- ) - { - // Create a transition - mlt_transition transition = mlt_factor_transition( "luma", NULL ); - - // Mix the first and second clips for 50 - mlt_playlist_mix( playlist, i, 50, transition ); - - // Close the transition - mlt_transition_close( transition ); - } - - There are other techniques, like using the mlt_playlist_join between the - current clip and the newly created one (you can determine if a new clip was - created by comparing the playlist length before and after the mix call). - - Internally, the mlt_playlist_mix call generates a tractor and multitrack as - described below. Like the attached filters, the mix makes life very simple - when you're inserting items into the playlist. - - Also note that it allows a simpler user interface - instead of enforcing the - use of a complex multitrack object, you can do many operations on a single - track. Thus, additional tracks can be used to introduce audio dubs, mixes - or composites which are independently positioned and aren't affected by - manipulations on other tracks. But hey, if you want a bombastic, confusing - and ultimately frustrating traditional NLE experience, that functionality - is provided too ;-). - - -Practicalities and Optimisations: - - In the previous two sections I've introduced some powerful functionality - designed to simplify MLT usage. However, a general issue comes into this - - what happens when you introduce a transition between two cuts from the same - bit of video footage? - - Anyone who is familiar with video compression will be aware that seeking - isn't always without consequence from a performance point of view. So if - you happen to require two frames from the same clip for a transition, the - processing is going to be excessive and the result will undoubtedly be very - unpleasant, especially if you're rendering in realtime... - - So how do we get round this? - - Actually, it's very simple - you invoke mlt_producer_optimise on the top - level object after a modification and MLT will determine how to handle it. - Internally, it determines the maximum number of overlapping instances - throughout the object and creates clones and assigns clone indexes as - required. - - In the mix example above, you can simply call: - - // Optimise the playlist - mlt_producer_optimise( mlt_playlist_producer( playlist ) ); - - after the mix calls have be done. Note that this is automatically applied - to deserialised westleys. - - -Multiple Tracks and Transitions: - - MLT's approach to multiple tracks is governed by two requirements: - - 1) The need for a consumer and producer to communicate with one another via - a single frame; - 2) The desire to be able to serialise and manipulate a 'network' (or filter - graph if you prefer). - - We can visualise a multitrack in the way that an NLE presents it: - - +-----------------+ +-----------------------+ - 0: |a1 | |a2 | - +---------------+-+--------------------------+-+---------------------+ - 1: |b1 | - +------------------------------+ - - The overlapping areas of track 0 and 1 would (presumably) have some kind of - transition - without a transition, the frames from b1 and b2 would be shown - during the areas of overlap (ie: by default, the higher numbered track takes - precedence over the lower numbered track). - - MLT has a multitrack object, but it is not a producer in the sense that it - can be connected directly to a consumer and everything will work correctly. - A consumer would treat it precisely as it would a normal producer, and, in - the case of the multitrack above, you would never see anything from track 1 - other than the transitions between the clips - the gap between a1 and a2 - would show test frames. - - This happens because a consumer pulls one frame from the producer it's - connected to while a multitrack will provide one frame per track. - Something, somewhere, must ensure that all frames are pulled from the - multitrack and elect the correct frame to pass on. - - Hence, MLT provides a wrapper for the multitrack, which is called a - 'tractor', and its the tractors task to ensure that all tracks are pulled - evenly, the correct frame is output and that we have 'producer like' - behaviour. - - Thus, a multitrack is conceptually 'pulled' by a tractor as shown here: - - +----------+ - |multitrack| - | +------+ | +-------+ - | |track0|-|--->|tractor| - | +------+ | |\ | - | | | \ | - | +------+ | | \ | - | |track1|-|--->|---o---|---> - | +------+ | | / | - | | | / | - | +------+ | |/ | - | |track2|-|--->| | - | +------+ | +-------+ - +----------+ - - With a combination of the two, we can now connect multitracks to consumers. - The last non-test card will be retrieved and passed on. - - The tracks can be producers, playlists, or even other tractors. - - Now we wish to insert filters and transitions between the multitrack and the - tractor. We can do this directly by inserting filters directly between the - tractor and the multitrack, but this involves a lot of connecting and - reconnecting left and right producers and consumers, and it seemed only fair - that we should be able to automate that process. - - So in keeping with our agricultural theme, the concept of the 'field' was - born. We 'plant' filters and transitions in the field and the tractor pulls - the multitrack (think of a combine harvester :-)) over the field and - produces a 'bail' (sorry - kidding - frame :-)). - - Conceptually, we can see it like this: - - +----------+ - |multitrack| - | +------+ | +-------------+ +-------+ - | |track0|-|--->|field |--->|tractor| - | +------+ | | | |\ | - | | | filters | | \ | - | +------+ | | and | | \ | - | |track1|-|--->| transitions |--->|---o---|---> - | +------+ | | | | / | - | | | | | / | - | +------+ | | | |/ | - | |track2|-|--->| |--->| | - | +------+ | +-------------+ +-------+ - +----------+ - - So, we need to create the tractor first, and from that we obtain the - multitrack and field objects. We can populate these and finally - connect the tractor to a consumer. - - In essence, this is how it looks to the consumer: - - +-----------------------------------------------+ - |tractor +--------------------------+ | - | +----------+ | +-+ +-+ +-+ +-+ | | - | |multitrack| | |f| |f| |t| |t| | | - | | +------+ | | |i| |i| |r| |r| | | - | | |track0|-|--->| |l|- ->|l|- ->|a|--->|a|\| | - | | +------+ | | |t| |t| |n| |n| | | - | | | | |e| |e| |s| |s| |\ | - | | +------+ | | |r| |r| |i| |i| | \| - | | |track1|-|- ->| |0|--->|1|--->|t|--->|t|-|--o---> - | | +------+ | | | | | | |i| |i| | /| - | | | | | | | | |o| |o| |/ | - | | +------+ | | | | | | |n| |n| | | - | | |track2|-|- ->| | |- ->| |--->|0|- ->|1|/| | - | | +------+ | | | | | | | | | | | | - | +----------+ | +-+ +-+ +-+ +-+ | | - | +--------------------------+ | - +-----------------------------------------------+ - - An example will hopefully clarify this. - - Let's assume that we want to provide a 'watermark' to our hello world - example. We have already extended the example to play multiple clips, - and now we will place a text based watermark, reading 'Hello World' in - the top left hand corner: - - mlt_producer create_tracks( int argc, char **argv ) - { - // Create the tractor - mlt_tractor tractor = mlt_tractor_new( ); - - // Obtain the field - mlt_field field = mlt_tractor_field( tractor ); - - // Obtain the multitrack - mlt_multitrack multitrack = mlt_tractor_multitrack( tractor ); - - // Create a composite transition - mlt_transition transition = mlt_factory_transition( "composite", "10%,10%:15%x15%" ); - - // Create track 0 - mlt_producer track0 = create_playlist( argc, argv ); - - // Create the watermark track - note we NEED fezzik for scaling here - mlt_producer track1 = mlt_factory_producer( "fezzik", "pango" ); - - // Get the length of track0 - mlt_position length = mlt_producer_get_playtime( track0 ); - - // Set the properties of track1 - mlt_properties properties = mlt_producer_properties( track1 ); - mlt_properties_set( properties, "text", "Hello\nWorld" ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", length - 1 ); - mlt_properties_set_position( properties, "length", length ); - mlt_properties_set_int( properties, "a_track", 0 ); - mlt_properties_set_int( properties, "b_track", 1 ); - - // Now set the properties on the transition - properties = mlt_transition_properties( transition ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", length - 1 ); - - // Add our tracks to the multitrack - mlt_multitrack_connect( multitrack, track0, 0 ); - mlt_multitrack_connect( multitrack, track1, 1 ); - - // Now plant the transition - mlt_field_plant_transition( field, transition, 0, 1 ); - - // Close our references - mlt_producer_close( track0 ); - mlt_producer_close( track1 ); - mlt_transition_close( transition ); - - // Return the tractor - return mlt_tractor_producer( tractor ); - } - - Now all we need do is to replace these lines in the main function: - - // Create a playlist - mlt_producer world = create_playlist( argc, argv ); - - with: - - // Create a watermarked playlist - mlt_producer world = create_tracks( argc, argv ); - - and we have a means to play multiple clips with a horribly obtrusive - watermark - just what the world needed, right? ;-) - - Incidentally, the same thing could be achieved with the more trivial - watermark filter inserted between the producer and the consumer. - - -SECTION 3 - STRUCTURE AND DESIGN --------------------------------- - -Class Hierarchy: - - The mlt framework consists of an OO class hierarchy which consists of the - following public classes and abstractions: - - mlt_properties - mlt_frame - mlt_service - mlt_producer - mlt_playlist - mlt_tractor - mlt_filter - mlt_transition - mlt_consumer - mlt_deque - mlt_pool - mlt_factory - - Each class defined above can be read as extending the classes above and to - the left. - - The following sections describe the properties, stacking/queuing and memory - pooling functionality provided by the framework - these are key components - and a basic understanding of these is required for the remainder of the - documentation. - - -mlt_properties: - - The properties class is the base class for the frame and service classes. - - It is designed to provide an efficient lookup table for various types of - information, such as strings, integers, floating points values and pointers - to data and data structures. - - All properties are indexed by a unique string. - - The most basic use of properties is as follows: - - // 1. Create a new, empty properties set; - mlt_properties properties = mlt_properties_new( ); - - // 2. Assign the value "world" to the property "hello"; - mlt_properties_set( properties, "hello", "world" ); - - // 3. Retrieve and print the value of "hello"; - printf( "%s\n", mlt_properties_get( properties, "hello" ) ); - - // 4. Reassign "hello" to "world!"; - mlt_properties_set( properties, "hello", "world!" ); - - // 5. Retrieve and print the value of "hello"; - printf( "%s\n", mlt_properties_get( properties, "hello" ) ); - - // 6. Assign the value "0" to "int"; - mlt_properties_set( properties, "int", "0" ); - - // 7. Retrieve and print the integer value of "int"; - printf( "%d\n", mlt_properties_get_int( properties, "int" ) ); - - // 8. Assign the integer value 50 to "int2"; - mlt_properties_set_int( properties, "int2", 50 ); - - // 9. Retrieve and print the double value of "int2"; - printf( "%s\n", mlt_properties_get( properties, "int2" ) ); - - Steps 2 through 5 demonstrate that the "name" is unique - set operations on - an existing "name" change the value. They also free up memory associated to - the previous value. Note that it also possible to change type in this way - too. - - Steps 6 and 7 demonstrate that the properties object handles deserialisation - from strings. The string value of "0" is set, the integer value of 0 is - retrieved. - - Steps 8 and 9 demonstrate that the properties object handles serialisation - to strings. - - To show all the name/value pairs in a properties, it is possible to iterate - through them: - - for ( i = 0; i < mlt_properties_count( properties ); i ++ ) - printf( "%s = %s\n", mlt_properties_get_name( properties, i ), - mlt_properties_get_value( properties, i ) ); - - Note that properties are retrieved in the order in which they are set. - - Properties are also used to hold pointers to memory. This is done via the - set_data call: - - uint8_t *image = malloc( size ); - mlt_properties_set_data( properties, "image", image, size, NULL, NULL ); - - In this example, we specify that the pointer can be retrieved from - properties by a subsequent request to get_data: - - image = mlt_properties_get_data( properties, "image", &size ); - - or: - - image = mlt_properties_get_data( properties, "image", NULL ); - - if we don't wish to retrieve the size. - - Two points here: - - 1) The allocated memory remains after the properties object is closed unless - you specify a destructor. In the case above, this can be done with: - - mlt_properties_set_data( properties, "image", image, size, free, NULL ); - - When the properties are closed, or the value of "image" is changed, the - destructor is invoked. - - 2) The string value returned by mlt_properties_get is NULL. Typically, you - wouldn't wish to serialise an image as a string, but other structures - might need such functionality - you can specify a serialiser as the last - argument if required (declaration is char *serialise( void * )). - - Properties also provides some more advanced usage capabilities. - - It has the ability to inherit all serialisable values from another properties - object: - - mlt_properties_inherit( this, that ); - - It has the ability to mirror properties set on this on another set of - properties: - - mlt_properties_mirror( this, that ); - - After this call, all serialisable values set on this are passed on to that. - - -mlt_deque: - - Stacks and queues are essential components in the MLT framework. Being of a - lazy disposition, we elected to implement a 'Double Ended Queue' (deque) - - this encapsulates the functionality of both. - - The API of the deque is defined as follows: - - mlt_deque mlt_deque_init( ); - int mlt_deque_count( mlt_deque this ); - int mlt_deque_push_back( mlt_deque this, void *item ); - void *mlt_deque_pop_back( mlt_deque this ); - int mlt_deque_push_front( mlt_deque this, void *item ); - void *mlt_deque_pop_front( mlt_deque this ); - void *mlt_deque_peek_back( mlt_deque this ); - void *mlt_deque_peek_front( mlt_deque this ); - void mlt_deque_close( mlt_deque this ); - - The stacking operations are used in a number of places: - - * Reverse Polish Notation (RPN) image and audio operations - * memory pooling - - The queuing operations are used in: - - * the consumer base class; - * consumer implementations may require further queues. - - -mlt_pool: - - The MLT framework provides memory pooling capabilities through the mlt_pool - API. Once initilialised, these can be seen as a straightforward drop in - replacement for malloc/realloc/free functionality. - - The background behind this API is that malloc/free operations are - notoriously inefficient, especially when dealing with large blocks of memory - (such as an image). On linux, malloc is optimised for memory allocations - less than 128k - memory blocks allocated of these sizes or less are retained - in the process heap for subsequent reuse, thus bypassing the kernel calls - for repeated allocation/frees for small blocks of memory. However, blocks of - memory larger than that require kernel calls and this has a detrimental - impact on performance. - - The mlt_pool design is simply to hold a list of stacks - there is one stack - per 2^n bytes (where n is between 8 and 31). When an alloc is called, the - requested size is rounded to the next 2^n, the stack is retrieved for that - size, and an item is popped or created if the stack is empty. - - Each item has a 'header', situated immediately before the returned address - - this holds the 'stack' to which the item belongs. - - When an item is released, we retrieve the header, obtain the stack and push - it back. - - Thus, from the programmers point of view, the API is the same as the - traditional malloc/realloc/free calls: - - void *mlt_pool_alloc( int size ); - void *mlt_pool_realloc( void *ptr, int size ); - void mlt_pool_release( void *release ); - - -mlt_frame: - - A frame object is essentially defined as: - - +------------+ - |frame | - +------------+ - | properties | - | image stack| - | audio stack| - +------------+ - - The life cycle of a frame can be represented as follows: - - +-----+----------------------+-----------------------+---------------------+ - |Stage|Producer |Filter |Consumer | - +-----+----------------------+-----------------------+---------------------+ - | 0.0 | | |Request frame | - +-----+----------------------+-----------------------+---------------------+ - | 0.1 | |Receives request | | - | | |Request frame | | - +-----+----------------------+-----------------------+---------------------+ - | 0.2 |Receives request | | | - | |Generates frame for | | | - | |current position | | | - | |Increments position | | | - +-----+----------------------+-----------------------+---------------------+ - | 0.3 | |Receives frame | | - | | |Updates frame | | - +-----+----------------------+-----------------------+---------------------+ - | 0.4 | | |Receives frame | - +-----+----------------------+-----------------------+---------------------+ - - Note that neither the filter nor the consumer have any conception of - 'position' until they receive a frame. Speed and position are properties of - the producer, and they are assigned to the frame object when the producer - creates it. - - Step 0.3 is a critical one here - if the filter determines that the frame is - of interest to it, then it should manipulate the image and/or audio stacks - and properties as required. - - Assuming that the filter deals with both image and audio, then it should - push data and methods on to the stacks which will deal with the processing. - This can be done with the mlt_frame_push_image and audio methods. In order for - the filter to register interest in the frame, the stacks should hold: - - image stack: - [ producer_get_image ] [ data1 ] [ data2 ] [ filter_get_image ] - - audio stack: - [ producer_get_audio ] [ data ] [ filter_get_audio ] - - The filter_get methods are invoked automatically when the consumer invokes a - get_image on the frame. - - +-----+----------------------+-----------------------+---------------------+ - |Stage|Producer |Filter |Consumer | - +-----+----------------------+-----------------------+---------------------+ - | 1.0 | | |frame_get_image | - +-----+----------------------+-----------------------+---------------------+ - | 1.1 | |filter_get_image: | | - | | | pop data2 and data1 | | - | | | frame_get_image | | - +-----+----------------------+-----------------------+---------------------+ - | 1.2 |producer_get_image | | | - | | Generates image | | | - +-----+----------------------+-----------------------+---------------------+ - | 1.3 | |Receives image | | - | | |Updates image | | - +-----+----------------------+-----------------------+---------------------+ - | 1.4 | | |Receives image | - +-----+----------------------+-----------------------+---------------------+ - - Obviously, if the filter isn't interested in the image, then it should leave - the stack alone, and then the consumer will retrieve its image directly from - the producer. - - Similarly, audio is handled as follows: - - +-----+----------------------+-----------------------+---------------------+ - |Stage|Producer |Filter |Consumer | - +-----+----------------------+-----------------------+---------------------+ - | 2.0 | | |frame_get_audio | - +-----+----------------------+-----------------------+---------------------+ - | 2.1 | |filter_get_audio: | | - | | | pop data | | - | | | frame_get_audio | | - +-----+----------------------+-----------------------+---------------------+ - | 2.2 |producer_get_audio | | | - | | Generates audio | | | - +-----+----------------------+-----------------------+---------------------+ - | 2.3 | |Receives audio | | - | | |Updates audio | | - +-----+----------------------+-----------------------+---------------------+ - | 2.4 | | |Receives audio | - +-----+----------------------+-----------------------+---------------------+ - - And finally, when the consumer is done with the frame, it should close it. - - Note that a consumer may not evaluate both image and audio for any given - frame, especially in a realtime environment. See 'Realtime Considerations' - below. - - By default, a frame has the following properties: - - +------------------+------------------------------------+------------------+ - |Name |Description |Values | - +------------------+------------------------------------+------------------+ - |_position |The producers frame position |0 to n | - +------------------+------------------------------------+------------------+ - |_speed |The producers speed |double | - +------------------+------------------------------------+------------------+ - |image |The generated image |NULL or pointer | - +------------------+------------------------------------+------------------+ - |alpha |The generated alpha mask |NULL or pointer | - +------------------+------------------------------------+------------------+ - |width |The width of the image | | - +------------------+------------------------------------+------------------+ - |height |The height of the image | | - +------------------+------------------------------------+------------------+ - |normalised_width |The normalised width of the image |720 | - +------------------+------------------------------------+------------------+ - |normalised_height |The normalised height of the image |576 or 480 | - +------------------+------------------------------------+------------------+ - |progressive |Indicates progressive/interlaced |0 or 1 | - +------------------+------------------------------------+------------------+ - |top_field_first |Indicates top field first |0 or 1 | - +------------------+------------------------------------+------------------+ - |audio |The generated audio |NULL or pointer | - +------------------+------------------------------------+------------------+ - |frequency |The frequency of the audio | | - +------------------+------------------------------------+------------------+ - |channels |The channels of the audio | | - +------------------+------------------------------------+------------------+ - |samples |The samples of the audio | | - +------------------+------------------------------------+------------------+ - |aspect_ratio |The sample aspect ratio of the image|double | - +------------------+------------------------------------+------------------+ - |test_image |Used to indicate no image available |0 or 1 | - +------------------+------------------------------------+------------------+ - |test_audio |Used to indicate no audio available |0 or 1 | - +------------------+------------------------------------+------------------+ - - The consumer can attach the following properties which affect the default - behaviour of a frame: - - +------------------+------------------------------------+------------------+ - |test_card_producer|Synthesise test images from here |NULL or pointer | - +------------------+------------------------------------+------------------+ - |consumer_aspect_ |Apply this aspect ratio to the test |double | - |ratio |card producer | | - +------------------+------------------------------------+------------------+ - |rescale.interp |Use this scale method for test image|"string" | - +------------------+------------------------------------+------------------+ - - While most of these are mainly self explanatory, the normalised_width and - normalised_height values require a little explanation. These are required - to ensure that effects are consistently handled as PAL or NTSC, regardless - of the consumers or producers width/height image request. - - The test_image and audio flags are used to determine when images and audio - should be synthesised. - - Additional properties may be provided by the producer implementation, and - filters, transitions and consumers may add additional properties to - communicate specific requests. These are documented in modules.txt. - - The complete API for the mlt frame is as follows: - - mlt_frame mlt_frame_init( ); - mlt_properties mlt_frame_properties( mlt_frame this ); - int mlt_frame_is_test_card( mlt_frame this ); - int mlt_frame_is_test_audio( mlt_frame this ); - double mlt_frame_get_aspect_ratio( mlt_frame this ); - int mlt_frame_set_aspect_ratio( mlt_frame this, double value ); - mlt_position mlt_frame_get_position( mlt_frame this ); - int mlt_frame_set_position( mlt_frame this, mlt_position value ); - int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ); - uint8_t *mlt_frame_get_alpha_mask( mlt_frame this ); - int mlt_frame_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ); - int mlt_frame_push_get_image( mlt_frame this, mlt_get_image get_image ); - mlt_get_image mlt_frame_pop_get_image( mlt_frame this ); - int mlt_frame_push_frame( mlt_frame this, mlt_frame that ); - mlt_frame mlt_frame_pop_frame( mlt_frame this ); - int mlt_frame_push_service( mlt_frame this, void *that ); - void *mlt_frame_pop_service( mlt_frame this ); - int mlt_frame_push_audio( mlt_frame this, void *that ); - void *mlt_frame_pop_audio( mlt_frame this ); - void mlt_frame_close( mlt_frame this ); - - -mlt_service: - - The service base class extends properties and allows 0 to m inputs and 0 to - n outputs and is represented as follows: - - +-----------+ - - ->| |- -> - - ->| Service |- -> - - ->| | - +-----------+ - | properties| - +-----------+ - - Descendents of service impose restrictions on how inputs and outputs can be - connected and will provide a basic set of properties. Typically, the service - instance is encapsulated by the descendent in order for it to ensure that - its connection rules are followed. - - A service does not define any properties when constructed. It should be - noted that producers, filters and transitions my be serialised (say, via the - westley consumer), and care should be taken to distinguish between - serialisable and transient properties. The convention used is to prefix - transient properties with an underscore. - - The public interface is defined by the following functions: - - int mlt_service_init( mlt_service this, void *child ); - mlt_properties mlt_service_properties( mlt_service this ); - int mlt_service_connect_producer( mlt_service this, mlt_service producer, int index ); - int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index ); - void mlt_service_close( mlt_service this ); - - Typically, only direct descendents of services need invoke these methods and - developers are encouraged to use those extensions when defining new services. - - -mlt_producer: - - A producer has 0 inputs and 1 output: - - +-----------+ - | | - | Producer |---> - | | - +-----------+ - | service | - +-----------+ - - A producer provides an abstraction for file readers, pipes, streams or any - other image or audio input. - - When instantiated, a producer has the following properties: - - +------------------+------------------------------------+------------------+ - |Name |Description |Values | - +------------------+------------------------------------+------------------+ - |mlt_type |The producers type |mlt_producer | - +------------------+------------------------------------+------------------+ - |_position |The producers frame position |0 to n | - +------------------+------------------------------------+------------------+ - |_speed |The producers speed |double | - +------------------+------------------------------------+------------------+ - |fps |The output frames per second |25 or 29.97 | - +------------------+------------------------------------+------------------+ - |in |The in point in frames |0 to length - 1 | - +------------------+------------------------------------+------------------+ - |out |The out point in frames |in to length - 1 | - +------------------+------------------------------------+------------------+ - |length |The length of the input in frames |0 to n | - +------------------+------------------------------------+------------------+ - |aspect_ratio |aspect_ratio of the source |0 to n | - +------------------+------------------------------------+------------------+ - |eof |end of clip behaviour |"pause" or "loop" | - +------------------+------------------------------------+------------------+ - |resource |Constructor argument (ie: file name)|"" | - +------------------+------------------------------------+------------------+ - - Additional properties may be provided by the producer implementation. - - The public interface is defined by the following functions: - - mlt_producer mlt_producer_new( ); - int mlt_producer_init( mlt_producer this, void *child ); - mlt_service mlt_producer_service( mlt_producer this ); - mlt_properties mlt_producer_properties( mlt_producer this ); - int mlt_producer_seek( mlt_producer this, mlt_position position ); - mlt_position mlt_producer_position( mlt_producer this ); - mlt_position mlt_producer_frame( mlt_producer this ); - int mlt_producer_set_speed( mlt_producer this, double speed ); - double mlt_producer_get_speed( mlt_producer this ); - double mlt_producer_get_fps( mlt_producer this ); - int mlt_producer_set_in_and_out( mlt_producer this, mlt_position in, mlt_position out ); - mlt_position mlt_producer_get_in( mlt_producer this ); - mlt_position mlt_producer_get_out( mlt_producer this ); - mlt_position mlt_producer_get_playtime( mlt_producer this ); - mlt_position mlt_producer_get_length( mlt_producer this ); - void mlt_producer_prepare_next( mlt_producer this ); - void mlt_producer_close( mlt_producer this ); - - -mlt_filter: - - The public interface is defined by the following functions: - - int mlt_filter_init( mlt_filter this, void *child ); - mlt_filter mlt_filter_new( ); - mlt_service mlt_filter_service( mlt_filter this ); - mlt_properties mlt_filter_properties( mlt_filter this ); - mlt_frame mlt_filter_process( mlt_filter this, mlt_frame that ); - int mlt_filter_connect( mlt_filter this, mlt_service producer, int index ); - void mlt_filter_set_in_and_out( mlt_filter this, mlt_position in, mlt_position out ); - int mlt_filter_get_track( mlt_filter this ); - mlt_position mlt_filter_get_in( mlt_filter this ); - mlt_position mlt_filter_get_out( mlt_filter this ); - void mlt_filter_close( mlt_filter ); - - -mlt_transition: - - The public interface is defined by the following functions: - - int mlt_transition_init( mlt_transition this, void *child ); - mlt_transition mlt_transition_new( ); - mlt_service mlt_transition_service( mlt_transition this ); - mlt_properties mlt_transition_properties( mlt_transition this ); - int mlt_transition_connect( mlt_transition this, mlt_service producer, int a_track, int b_track ); - void mlt_transition_set_in_and_out( mlt_transition this, mlt_position in, mlt_position out ); - int mlt_transition_get_a_track( mlt_transition this ); - int mlt_transition_get_b_track( mlt_transition this ); - mlt_position mlt_transition_get_in( mlt_transition this ); - mlt_position mlt_transition_get_out( mlt_transition this ); - mlt_frame mlt_transition_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame ); - void mlt_transition_close( mlt_transition this ); - - -mlt_consumer: - - The public interface is defined by the following functions: - - int mlt_consumer_init( mlt_consumer this, void *child ); - mlt_service mlt_consumer_service( mlt_consumer this ); - mlt_properties mlt_consumer_properties( mlt_consumer this ); - int mlt_consumer_connect( mlt_consumer this, mlt_service producer ); - int mlt_consumer_start( mlt_consumer this ); - mlt_frame mlt_consumer_get_frame( mlt_consumer this ); - mlt_frame mlt_consumer_rt_frame( mlt_consumer this ); - int mlt_consumer_stop( mlt_consumer this ); - int mlt_consumer_is_stopped( mlt_consumer this ); - void mlt_consumer_close( mlt_consumer ); - - -Specialised Producers: - - There are two major types of specialised producers - playlists and tractors. - - The following sections describe these. - - -mlt_playlist: - - mlt_playlist mlt_playlist_init( ); - mlt_producer mlt_playlist_producer( mlt_playlist this ); - mlt_service mlt_playlist_service( mlt_playlist this ); - mlt_properties mlt_playlist_properties( mlt_playlist this ); - int mlt_playlist_count( mlt_playlist this ); - int mlt_playlist_clear( mlt_playlist this ); - int mlt_playlist_append( mlt_playlist this, mlt_producer producer ); - int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, mlt_position in, mlt_position out ); - int mlt_playlist_blank( mlt_playlist this, mlt_position length ); - mlt_position mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index ); - int mlt_playlist_current_clip( mlt_playlist this ); - mlt_producer mlt_playlist_current( mlt_playlist this ); - int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index ); - int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_position in, mlt_position out ); - int mlt_playlist_remove( mlt_playlist this, int where ); - int mlt_playlist_move( mlt_playlist this, int from, int to ); - int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_position in, mlt_position out ); - void mlt_playlist_close( mlt_playlist this ); - -mlt_tractor: diff --git a/docs/inigo.txt b/docs/inigo.txt deleted file mode 100644 index 854c1c1..0000000 --- a/docs/inigo.txt +++ /dev/null @@ -1,401 +0,0 @@ -Inigo Documentation - -Copyright (C) 2004-2009 Ushodaya Enterprised Limited -Author: Charles Yates -Last Revision: 2009-01-21 - - -INIGO ------ - -Preamble: - - inigo was developed as a test tool for the MLT framework. It can be thought - of as a powerful, if somewhat obscure, multitrack command line oriented - video editor. - - The following details the usage of the tool and as a result, provides a lot - of insight into the workings of the MLT framework. - - -Usage: - - inigo [options] [producer [name=value]* ]+ - Options: - -attach filter[:arg] [name=value]* Attach a filter to the output - -attach-cut filter[:arg] [name=value]* Attach a filter to a cut - -attach-track filter[:arg] [name=value]* Attach a filter to a track - -attach-clip filter[:arg] [name=value]* Attach a filter to a producer - -audio-track | -hide-video Add an audio-only track - -blank frames Add blank silence to a track - -consumer id[:arg] [name=value]* Set the consumer (sink) - -debug Set the logging level to debug - -filter filter[:arg] [name=value]* Add a filter to the current track - -group [name=value]* Apply properties repeatedly - -help Show this message - -join clips Join multiple clips into one cut - -mix length Add a mix between the last two cuts - -mixer transition Add a transition to the mix - -null-track | -hide-track Add a hidden track - -profile name Set the processing settings - -progress Display progress along with the position - -remove Remove the most recent cut - -repeat times Repeat the last cut - -query List all of the registered services - -query "consumers" | "consumer"=id List consumers or show info about one - -query "filters" | "filter"=id List filters or show info about one - -query "producers" | "producer"=id List producers or show info about one - -query "transitions" | "transition"=id List transitions or show info about one - -serialise [filename] Write the commands to a text file - -silent Do not display position/transport help - -split relative-frame Split the last cut into two cuts - -swap Rearrange the last two cuts - -track Add a track - -transition id[:arg] [name=value]* Add a transition - -verbose Set the logging level to verbose - -version Show the version and copyright message - -video-track | -hide-audio Add a video-only track - - -General rules: - - 1. Order is incredibly important; - - 2. Error checking on command line parsing is weak; - - 3. Please refer to services.txt for details on services available; - - 4. The MLT framework, from which inigo has inherited its naming convention, - is very mlt-centric. Producers produce MLT frame objects and consumers - consume MLT frame objects. The distinction is important - a DV producer - does not produce DV, it produces MLT frames from a DV source, and similarly - a DV consumer does not consume DV, it consumes MLT frames and produces DV - frames. - - -Terminology: - - 'Producers' typically refer to files but may also indicate devices (such as - dv1394 input or video4linux). Hence, the more generic term is used [the more - generic usage is out of scope for now...]. - - 'Filters' are frame modifiers - they always guarantee that for every frame - they receive, they output *precisely* one frame. Never more, never less, - ever. Nothing says that a filter cannot generate frames though - - 'Transitions' collect frames from two tracks (a and b) and output 1 - modified frame on their 'a track', and 1 unmodified frame on their 'b track'. - Never more, never less, ever. - - 'Consumers' collect frames from a producer, do something with them and - destroy them. - - Collectively, these are known as 'services'. - - All services have 'properties' associated to them. These are typically - defaulted or evaluated and may be overriden on a case by case basis. - - All services except consumers obey in and out properties. - - Consumers have no say in the flow of frames [though they may give the - illusion that they do]. They get frames from a connected producer, use them, - destroy them and get more. - - -Basics: - - To play a file with the default SDL PAL consumer, usage is: - - $ inigo file - - Note that 'file' can be anything that inigo has a known 'producer' mapping - for (so this can be anything from .dv to .txt). - - You can also specify the producer directly, for example: - - $ inigo avformat:file.mpeg - - Would force the direct use of avformat for loading the file. - - -Properties: - - Properties can be assigned to the producer by adding additional name=value - pairs after the producer: - - $ inigo file in=50 out=100 something="something else" - - Note that while some properties have meaning to all producers (for example: - in, out and length are guaranteed to be valid for all, though typically, - length is determined automatically), the validity of others are dependent on - the producer - however, properties will always be assigned and silently - ignored if they won't be used. - - -Multiple Files: - - Multiple files of different types can be used: - - $ inigo a.dv b.mpg c.png - - Properties can be assigned to each file: - - $ inigo a.dv in=50 out=100 b.mpg out=500 c.png out=500 - - MLT will take care of 'normalising' the output of a producer to ensure - that the consumer gets what it needs. So, in the case above, the mlt - framework will ensure that images are rescaled and audio resampled to meet - the requirements of your configuration (which, by default, will be PAL). - See 'Appendix A: Normalisation Rules' below. - - -Filters: - - Filters are frame modifiers - they can change the contents of the audio or - the images associated to a frame. - - $ inigo a.dv -filter greyscale - - As with producers, properties may be specified on filters too. - - Again, in and out properties are common to all, so to apply a filter to a - range of frames, you would use something like: - - $ inigo a.dv -filter greyscale in=0 out=50 - - Again, filters have their own set of rules about properties and will - silently ignore properties that do not apply. - - -Groups: - - The -group switch is provided to force default properties on the following - 'services'. For example: - - $ inigo -group in=0 out=49 clip* - - would play the first 50 frames of all clips that match the wild card - pattern. - - Note that the last -group settings also apply to the following filters, - transitions and consumers, so: - - $ inigo -group in=0 out=49 clip* -filter greyscale - - is *probably not* what you want (ie: the greyscale filter would only be - applied to the first 50 frames). - - To shed the group properties, you can use any empty group: - - $ inigo -group in=0 out=49 clip* -group -filter greyscale - - -Attached Filters: - - As described above, the -filter switch applies filters to an entire track. To - localise filters to a specific clip on a track, you have to know information - about the lengths of the clip and all clips leading up to it. In practise, - this is horrifically impractical, especially at a command line level (and not - even that practical from a programing point of view...). - - The -attach family of switches simplify things enormously. By default, -attach - will attach a filter to the last service created, so: - - $ inigo clip1.dv clip2.dv -attach greyscale clip3.dv - - would only apply the filter to clip2.dv. You can further narrow down the area of - the effect by specifying in/out points on the attached filter. - - This might seem simple so far, but there is a catch... consider the following: - - $ ingo clip1.dv -attach watermark:+hello.txt -attach invert - - The second attached filter is actually attached to the watermark. You might - think, yay, nice (and it is :-)), but, it might not be what you want. For example - you might want to attach both to clip1.dv. To do that, you can use: - - $ ingo clip1.dv -attach-cut watermark:+hello.txt -attach-cut invert - - As you shall see below, there are still another couple of gotchas associated to - -attach, and even another variant :-). - - -Mixes: - - The -mix switch provides the simplest means to introduce transitions between - adjacent clips. - - For example: - - $ inigo clip1.dv clip2.dv -mix 25 -mixer luma -mixer mix:-1 - - would provide both an audio and video transition between clip1 and clip2. - - This functionality supercedes the enforced use of the -track and -transition - switches from earlier versions of inigo and makes life a lot easier :-). - - These can be used in combination, so you can for example do a fade from black - and to black using the following: - - $ inigo colour:black out=24 clip1.dv -mix 25 -mixer luma \ - colour:black out=24 -mix 25 -mixer luma - - while this may not be immediately obvious, consider what's happening as the - command line is being parsed from left to right: - - Input: Track - ----------------------- ----------------------------------------------------- - colour:black out=24 [black] - clip1.dv [black][clip1.dv] - -mix 25 [black+clip1.dv][clip1.dv] - -mixer luma [luma:black+clip1.dv][clip1.dv] - colour:black out=24 [luma:black+clip1.dv][clip1.dv][black] - -mix 25 [luma:black+clip1.dv][clip1.dv][clip1.dv+black] - -mixer luma [luma:black+clip1.dv][clip1.dv][luma:clip1.dv+black] - - Obviously, the clip1.dv instances refer to different parts of the clip, but - hopefully that will demonstrate what happens as we construct the track. - - You will find more details on the mix in the framework.txt. - - -Mix and Attach: - - As noted, -attach normally applies to the last created service - so, you can - attach a filter to the transition region using: - - $ inigo clip1.dv clip2.dv -mix 25 -mixer luma -attach watermark:+Transition.txt - - Again, nice, but take care - if you want the attached filter to be associated - to the region following the transition, use -attach-cut instead. - - -Splits, Joins, Removes and Swaps: - - COMPLEX - needs simplification.... - - -Introducing Tracks and Blanks: - - So far, all of the examples have shown the definition of a single - playlist, or more accurately, track. - - When multiple tracks exist, the consumer will receive a frame - from the 'highest numbered' track that is generating a non-blank - frame. - - It is best to visualise a track arrangement, so we'll start with - an example: - - $ inigo a.dv -track b.dv in=0 out=49 - - This can be visualised as follows: - - +------------------+ - |a | - +-------+----------+ - |b | - +-------+ - - Playout will show the first 50 frames of b and the 51st frame shown will be - the 51st frame of a. - - This rule also applies to audio only producers on the second track, for - example, the following would show the video from the a track, but the audio - would come from the second track: - - $ inigo a.dv -track b.mp3 in=0 out=49 - - To have the 51st frame be the first frame of b, we can use the -blank switch: - - $ inigo a.dv out=49 -track -blank 49 b.dv - - Which we can visualise as: - - +-------+ - |a | - +-------+-------------------+ - |b | - +-------------------+ - - Now playout will continue as though a and b clips are on the - same track (which on its own, is about as useful as reversing the - process of slicing bread). - - -Transitions: - - Where tracks become useful is in the placing of transitions. - - Here we need tracks to overlap, so a useful multitrack - definition could be given as: - - $ inigo a.dv out=49 \ - -track \ - -blank 24 b.dv \ - -transition luma in=25 out=49 a_track=0 b_track=1 - - Now we're cooking - our visualisation would be something like: - - +-------+ - |a | - +---+---+--------------+ - |b | - +------------------+ - - Playout will now show the first 25 frames of a and then a fade - transition for 25 frames between a and b, and will finally - playout the remainder of b. - - -Reversing a Transition: - - When we visualise a track definition, we also see situations - like: - - +-------+ +----------+ - |a1 | |a2 | - +---+---+--------------+----+-----+ - |b | - +-----------------------+ - - In this case, we have two transitions, a1 to b and b to a2. - - In this scenario, we define a command line as follows: - - $ inigo a.dv out=49 -blank 49 a2.dv \ - -track \ - -blank 24 b.dv out=99 \ - -transition luma in=25 out=49 a_track=0 b_track=1 \ - -transition luma in=100 out=124 reverse=1 a_track=0 b_track=1 - - -Serialisation: - - Inigo has a built in serialisation mechanism - you can build up - your command, test it via any consumer and then add a -serialise - file.inigo switch to save it. - - The saved file can be subsequently used as a clip by either - miracle or inigo. Take care though - paths to files are saved as - provided on the command line.... - - A more expressive serialisation can be obtained with the westley consumer - - this will provide an xml document which can be used freely in inigo and - miracle. - - See westley.txt for more information. - - -Missing Features: - - Some filters/transitions should be applied on the output frame regardless - of which track it comes from - for example, you might have a 3rd text - track or a watermark which you want composited on every frame, and of - course, there's the obscure filter.... - - inigo only supports this in two invocations - as a simple example: - - $ inigo a.dv -track -blank 100 b.dv -consumer westley:basic.westley - $ inigo basic.westley -filter watermark:watermark.png - diff --git a/docs/services.txt b/docs/services.txt deleted file mode 100644 index 63d6c5a..0000000 --- a/docs/services.txt +++ /dev/null @@ -1,1582 +0,0 @@ -Service Documentation - -Authors: Charles Yates - Dan Dennedy -Last Revision: $Date$ - - -SERVICES --------- - - Services marked as "(Proprietary)" are not distributed with the LGPL - version of mlt. - -Producers ---------- - - avformat - - Description - - ffmpeg libavformat based producer for video and audio. - - Constructor Argument - - 'file' - a filename specification or URL in the form: - [{protocol}|{format}]:{resource}[?{format-parameter}[&{format-parameter}...]] - For example, video4linux:/dev/video1?width:320&height:240 - Note: on the bash command line, & must be escaped as '\&'. - Also, note the use of ':' instead of '=' for parameters. - Use 'ffmpeg -formats' to see a list of supported protocols - and formats. - - Details - - Format parameters only appear to be useful with 'video4linux' or - 'audio_device' formats. For 'video4linux' the parameters are - width, height, frame_rate, frame_rate_base, and standard (ntsc|pal). - For 'audio_device' the parameters are channels and sample_rate. - - Initialisation Properties - - int video_index - index of video stream to use (-1 is off) - int audio_index - index of audio stream to use (-1 is off) - int in - in point - int out - out point - - Read Only Properties - - string resource - file location - double source_fps - the framerate of the resource - double aspect_ratio - sample aspect ratio of the resource - - this is determined on every frame read - - Dependencies - - ffmpeg - - Known Bugs - - Audio sync discrepancy with some content. - Not all libavformat supported formats are seekable. - Fails to play beyond first frame of video of sources with PTS not - starting at 0 (video4linux). - - fezzik - - Description - - A friendly giant that likes to rhyme and throw rocks - - Constructor Argument - - 'file' - a filename specification: - [{mlt-service}:]{resource} | {mlt-service} - - can also be the name of a producer service that can - accept the resource specified post construction. - - Initialisation Properties - - int in - in point - int out - out point - + all producer initialising properties - - Read Only Properties - - string resource - file location - + all producer read only properties - - Details - - This producer has two roles: - - 1. it handles the mappings of all file names to the other - producers; - 2. it attaches normalising filters (rescale, resize and resample) - to the producers (when necessary). - - This producer simplifies many aspects of use. Essentially, it - ensures that a consumer will receive images and audio precisely as - they request them. - - Dependencies - - all. - - Known Bugs - - None. - - - colour - - Description - - A simple colour generator. - - Constructor Argument - - colour - A colour value is a hexadecimal representation of RGB plus - alpha channel as 0xrrggbbaa. - - Also colours can be the words: white, black, red, green, - or blue. - - The default colour is black. - - Initialisation Properties - - none - - Read Only Properties - - none - - Dependencies - - none - - Known Bugs - - none - - - libdv - - Description - - libdv based decoder for video and audio. - - Constructor Argument - - 'file' - produce a/v from file - - Initialisation Properties - - int in - in point - int out - out point - - Read Only Properties - - string resource - file location - double fps - output frames per second - int length - duration of resource (in frames) - - Mutable Properties - - string quality - one of "best," "fast" or anything else chooses - medium. - - Dependencies - - libdv. - - Known Bugs - - DVCPRO is incorrectly identified as 16:9 aspect ratio. You must use - libdv from CVS or a post 0.101 release. - - mcdv (Proprietary) - - Description - - MainConcept based dv decoder for video and audio. - - Constructor Argument - - 'file' - produce a/v from file - - Initialisation Properties - - int in - in point - int out - out point - - Read Only Properties - - string resource - file location - double fps - output frames per second - int length - duration of resource (in frames) - - Dependencies - - MainConcept DV or DVCPRO SDK, libdv. - "dv_sdk" installed parallel to mlt. - - Known Bugs - - None - - mcmpeg (Proprietary) - - Description - - MainConcept based mpeg decoder for video and audio. - - Constructor Argument - - 'file' - produce a/v from file - - Initialisation Properties - - int in - in point - int out - out point - - Read Only Properties - - string resource - file location - double fps - output frames per second - double aspect_ratio - sample aspect ratio of video - int length - duration of resource (in frames) - - Dependencies - - MainConcept MPEG SDK. - "mpeg_sdk_release" installed parallel to mlt. - - Known Bugs - - None. - - noise - - Description - - White noise producer - - Constructor Argument - - none - - Initialisation Properties - - int in - in point - int out - out point - - Read Only Properties - - string resource - file location - double fps - output frames per second - double aspect_ratio - sample aspect ratio of video - int length - duration of resource (in frames) - - Dependencies - - none - - Known Bugs - - none - - pango - - Description - - A title generator that uses the Pango international text layout - and Freetype2 font renderer. - - Constructor Argument - - string file - a text file containing Pango markup, see: - http://developer.gnome.org/doc/API/2.0/pango/PangoMarkupFormat.html - - requires xml-like encoding special chars from: - <, >, & -to- <, >, & - - Details - - Supplying a filename with extension ".txt" causes the Fezzik - producer to load with pango. If the filename begins with "+" the - pango producer interprets the filename as pango text. This is a - shortcut to embed titles in inigo commands. For westley, it is - recommended that you embed the title text in the property value. - - Pango has builtin scaling. It will rescale the originally rendered - title to whatever the consumer requests. Therefore, it will lose - its aspect ratio if so requested, and it is up to the consumer to - request a proper width and height that maintains the image aspect. - - Initialisation Properties - - int in - in point - int out - out point - - Mutable Properties - - string markup - a string containing Pango markup see: - http://developer.gnome.org/doc/API/2.0/pango/PangoMarkupFormat.html - - requires xml-like encoding special chars from: - <, >, & -to- <, >, & - string fgcolour - an RGBA colour specification of the text - (i.e. 0xrrggbbaa) - string bgcolour - an RGBA colour of the background rectangle - string align - paragraph alignment: left, centre, right - - also, numbers 0, 1 and 2 can be used respectively. - int pad - the number of pixels to pad the background rectangle - beyond edges of text. default 0. - string markup - see constructor argument - string text - non-markup string in UTF-8 encoding (can contain - markup chars un-encoded) - string font - the default typeface to use when not using markup. - default "Sans 48". FreeType2 renders at 72 dpi. - string encoding - the text encoding type of the input if not UTF-8. - - see 'iconv --list' for a list of possible inputs. - int weight - the weight of the font (default is 400) - - Read Only Properties - - string resource - the text/markup file or "pango" if no file. - int real_width - the original, unscaled width of the rendered title. - int real_height - the original, unscaled height of the title. - int width - the last requested scaled image width. - int height - the last requested scaled image height. - - Dependencies - - libpango-1.0, libpangoft2-1.0, libfreetype, libgdk_pixbuf-2.0, - libglib-2.0, libgobject-2.0, libgmodule-2.0, libfontconfig. - - Known Bugs - - The foreground and background Pango markup span attributes are not - supported. - Word wrapping is not supported. - - pixbuf - - Description - - A still graphics to video generator using gdk-pixbuf - - Constructor Argument - - 'file' - The name of a graphics file loadable by - a gdk-pixbuf loader. see /usr/lib/gdk-pixbuf/loaders - definitely png, jpeg, tiff, pnm, and xpm - - If "%" in filename, the filename is used with sprintf - generate a filename from a counter for multi-file/flipbook - animation. The file sequence ends when numeric - discontinuity >100. - - If filename contains "/.all.", suffix with an extension to - load all pictures with matching extension from a directory. - - If filename contains the string "2 channels. - - rescale - - Description - - Scale the producer video frame size to match the consumer. - This filter is designed for use as a Fezzik normaliser. - - Constructor Argument - - None. - - Initialisation Properties - - int in - in point - int out - out point - - Mutable Properties - - If a property "consumer_aspect_ratio" exists on the frame, then - rescaler normalises the producer's aspect ratio and maximises the - size of the frame, but may not produce the consumer's requested - dimension. Therefore, this option works best in conjunction with the - resize filter. This behavior can be disabled by another service by - either removing the property, setting it to zero, or setting - frame property "distort" to 1. - - Dependencies - - none - - Known Bugs - - none but... it only implements a nearest neighbour scaling - it is - used as the base class for the gtkrescale and mcrescale filters. - - resize - - Description - - Image scaling and padding and field order adjustment. - - Details - - Normally resize is used to pad the producer's - output to what the consumer has requested after an upstream rescale - filter first scales the image to maximise usage of the image area. - This filter also adjusts the field order to lower field first - if the frame property "top_field_first" has been set to 1. - Therefore, when done, it sets the top_field_first to 0. - This filter is automatically invoked by Fezzik as part of image - sample aspect ratio normalisation. - - Constructor Argument - - scale - "affine" to use affine transform scaling, otherwise - center and pad. - - Initialisation Properties - - int in - in point - int out - out point - - Read Only Properties - - none - - Dependencies - - none - - Known Bugs - - Assumes lower field first output. - - volume - - Description - - Adjust an audio stream's volume level - - based on the 'normalize' utility - - Constructor Argument - - gain - a string containing one of: - - a floating point value of the gain adjustment - - a numeric value with the suffix "dB" to adjust in terms of decibels - - "normalise" to normalise the volume to the target amplitude -12dBFS - - Initialisation Properties - - int in - in point - int out - out point - int window - the number of video frames over which to smooth normalisation. - defaults to 75. - - Mutable Properties - - string gain - same as constructor argument above - - string normalise - normalise the volume to the amplitude: - - a numeric value with the suffix "dB" to set amplitude in decibels - - a floating point value of the relative volume - - an unspecified value uses the default -12dBFS - - string limiter - limit all samples above: - - a numeric value with the suffix "dB" - - a floating point value ( dB = 20 * log10(x) ) - - an unspecified value uses the default -6dBFS - - double max_gain - a floating point or decibel value of the maximum gain that - can be applied during normalisation. - - an unspecified value uses the default 20dB - - string end - a gain value just like the gain property above. - This causes the gain to be interpolated from 'gain' to 'end' - over the duration. - - int window - the size of the normalising smoothing buffer in video frame units. - - the smoothing buffer prevents erratic gain changes. - - the default value is 75 video frames. - - gain can be applied as a factor to the normalise amplitude! - - Dependencies - - none - - Known Bugs - - none - - watermark - - Description - - Add a watermark to the frames. - - Constructor Argument - - resource - the producer to use (ie: a .png) - - Initialisation Properties - - string resource - the producer to use - string factory - producer required for the resource ('fezzik') - string geometry - composite geometry - string distort - control scaling - int in - in point - int out - out point - - Mutable Properties - - none - - Dependencies - - mlt core modules and optionally, fezzik - - Known Bugs - - none - -Transitions ------------ - - composite - - Description - - A key-framable alpha-channel compositor for two frames. - - Details - - Performs dissolves and luma wipes in addition to alpha compositing. - - By default, the aspect ratio of the B frame is respected and the - size portion of the geometry specification simply defines a - bounding rectangle. - - This performs field-based rendering unless the A frame property - "progressive" or "consumer_progressive" or the transition property - "progressive" is set to 1. - - Constructor Argument - - none[*] - - Initialisation Properties - - int in - in point - int out - out point - string factory - The name of a factory service used as a non-PGM - producer loader. The default is fezzik. - - Read Only Properties - - none - - Mutable Properties - - - string geometry - key frame specification - - this is a ; delimited form of the deprecated start, - key[n], end properties - int progressive - set to 1 to disable field-based rendering. - string distort - when set, causes the B frame image to fill the WxH - completely with no regard to B's aspect ratio. - string halign - when not distorting, set the horizontal alignment - of B within the geometry rectangle. - - one of: left (0), centre (1), or right (2). - - the default is left. - string valign - when not distorting, set the vertical alignment of - B within the geometry rectangle. - - one of: top (0), middle (1), or bottom (2). - - the default is top. - string luma - the luma map file name. If not supplied, a dissolve. - double softness - only when using a luma map, how soft to make the - edges between A and B. 0.0 = no softness. 1.0 = - too soft. - Any property starting with "luma." is passed to the non-PGM luma - producer. - - Deprecated Properties - - string start - a geometry specification as X,Y:WxH[!][:mix] - - X, Y, W, H are assumed to pixel units unless they - have the suffix '%' - - '!' is a shortcut to specify distort, see below. - - mix is always a 2 digit percentage, defaults to 100. - - default is "85%,5%:10%x10%" - string end - the ending size and position. - string key[F] - X,Y:WxH[:mix] - set a key frame for geometry between - the in and out. F is a frame number and can be - negative to make it relative to the out point. - - Dependencies - - none - - Known Bugs - - Assumes lower field first during field rendering. - - luma - - Description - - A generic dissolve and wipe transition processor. - - Details - - luma gets its name - from how it uses a grayscale "map" file. As the luma value varies - over time, a threshold filter is applied to the map to determine - what parts of frame A vs. frame B to show. It reads PGM files - up to 16 bits! Alternatively, it can use the first frame from any - producer that outputs yuv, but it will be limited to the luma - gamut of 220 values. - This performs field-based rendering unless the A frame property - "progressive" or "consumer_progressive" or the transition property - "progressive" is set to 1. - - Constructor Argument - - string resource - the luma map file name - either PGM or any other - producable video. - - If not supplied, a dissolve. - - Initialisation Properties - - int in - in point - int out - out point - string factory - The name of a factory service used as a non-PGM - producer loader. The default is Fezzik. - - Mutable Properties - - string resource - same as above - double softness - only when using a luma map, how soft to make the - edges between A and B. 0.0 = no softness. 1.0 = - too soft. - int reverse - reverse the direction of the transition. - Any property starting with "producer." is passed to the non-PGM luma - producer. - - Read Only Properties - - none - - Dependencies - - none - - Known Bugs - - Assumes lower field first output. - - mix - - Description - - An two stream audio mixer. - - Constructor Argument - - start - see below - - Initalisation Properties - - int in - in point - int out - out point - - Mutable Properties - - double start - the mix level to apply to the second frame. - - any negative value causes an automatic crossfade from 0 to 1. - double end - the ending value of the mix level. mix level will be interpolated - from start to end over the in-out range. - int reverse - set to 1 to reverse the direction of the mix. - - Read Only Properties - - none - - Dependencies - - none - - Known Bugs - - Samples from the longer of the two frames are discarded. - - - region - - Description - - Apply zero or more filters to B frame as it is composited onto - a region of the A frame. The "shape" of the region can be defined - by the alpha channel of a third producer. - - Constructor Argument - - resource - a shape producer - - Initialisation Properties - - string resource - nothing is rectangle, "circle" is a pixbuf- - generated SVG circle, anything else is loaded by the factory. - string factory - the service that creates the shape producer. - - the default is fezzik. - string filter[N] - one or more filters to apply. All filter - properties are passed using the same filter "key" - Any property starting with "composite." is passed to the - encapsulated composite transition. - - Read Only Properties - - none - - Dependencies - - transition_composite - - Known Bugs - - none - - -Consumers ---------- - - avformat - - Description - - Multiformat transcoding consumer. - - Constructor Argument - - string target - the filename to write to, e.g. test.mpeg. - - Initialisation Properties - - int buffer - the number of frames to buffer, minimum 1, default 25. - string rescale - a rescale method, see the Filters/rescale. - int progressive - indicates whether to use progressive or field- - based rendering, default 0 (off). - - Read Only Properties - - none - - Dependencies - - libavformat - - Known Bugs - - Plenty. - - bluefish (Proprietary) - - Description - - BlueFish444 audio and video output module. - - Constructor Argument - - card - a numeric card id starting at 1, default is 1. - - Initialisation Properties - - string standard - "PAL" (default) or "NTSC" - - default is based upon MLT_NORMALISATION - environment variable, which defaults to PAL. - int frames - the number of DMA video frames. default is 8. - minimum is 2. maximum on my system is 11. - int buffer - the number of frames to buffer within MLT, minimum 1, - default 25. - string rescale - a rescale method, see the Filters/rescale. - - Read Only Properties - - none - - Dependencies - - BlueVelvet SDK installed parallel to mlt in "bluefish." - - Known Bugs - - Does not work with any service that uses pipes! - - If mlt crashes, you might need to reload the BlueDriver kernel - module due to unreleased DMA buffers. - - Only supports 2 channel audio at the moment. - - libdv - - Description - - libdv dv producer. - - Constructor Argument - - string target - the filename to write to, e.g. /dev/dv1394. - - Initialisation Properties - - int buffer - the number of frames to buffer, minimum 1, default 25. - string rescale - a rescale method, see the Filters/rescale. - - Mutable Properties - - int progressive - indicates whether to use progressive or field- - based rendering, default 0 (off). - - Read Only Properties - - none - - Dependencies - - libdv - - Known Bugs - - none - - mcmpeg - - Description - - Mainconcept MPEG encoder. - - Constructor Argument - - string target - the filename to write to. - - Initialisation Properties - - int buffer - the number of frames to buffer, minimum 1, default 25. - string rescale - a rescale method, see the Filters/rescale. - string format - vcd [default], svcd or dvd provide base settings - int motion_search_type - 0 to 16 - reduces quality/cpu usage - int gop - group of picture size (default: format dependent) - - Mutable Properties - - int progressive - indicates whether to use progressive or field- - based rendering, default 0 (off). - - Read Only Properties - - none - - Dependencies - - Mainconcept MPEG SDK - - Known Bugs - - none - - sdl - - Description - - Simple DirectMedia Layer audio and video output module. - - Constructor Argument - - string video_standard - "PAL" (default), "NTSC", or "WxH" - - Initialisation Properties - - int buffer - the number of frames to buffer, minimum 1, default 25. - string rescale - a rescale method, see the Filters/rescale. - - Hint: "none" works very good with SDL output. - - Mutable Properties - - double volume - audio level factor - int video_off - if 1, disable video output - int audio_off - if 1, disable audio output - int resize - TODO - int progressive - indicates whether to use progressive or field- - based rendering, default 0 (off). - int audio_buffer - size of the sdl audio buffer (default: 1024) - - Read Only Properties - - none - - Dependencies - - libSDL-1.2, libasound, libaudio, libXt, libX11, libXext, libSM, libICE - - Known Bugs - - none - - westley - - Description - - Serialise the service network to XML. - See docs/westley.txt for more information. - - Constructor Argument - - resource - the name of a file in which to store the XML. - - stdout is default. - - Initialisation Properties - - string resource - same as above. - - Dependencies - - libxml2 - - Known Bugs - - Untested arbitrary nesting of multitracks and playlists. - Property "id" is generated as service type followed by number if - no property named "id" exists, but it fails to guarantee uniqueness. diff --git a/docs/westley.txt b/docs/westley.txt deleted file mode 100644 index 1f42538..0000000 --- a/docs/westley.txt +++ /dev/null @@ -1,574 +0,0 @@ -Westley Documentation - -Copyright (C) 2004 Ushodaya Enterprised Limited -Authors: Charles Yates -Last Revision: 2004-03-20 - - -WESTLEY -------- - -Preamble: - - Westley is the MLT projects XML serialisation/deserialisation format - - as such, it closely mirrors the internal structure of the MLT API. - - If you just want to go straight to the DTD, then see - mlt/src/modules/westley/westley.dtd, which gets installed at - $(prefix)/share/mlt/modules/westley.dtd. Currently, the westley parser is - non-validating. - - -Introduction: - - A westley document is essentially a list of 'producers' - a producer is - an mlt object which generates mlt frames (images and associated audio - samples). - - There are 3 types of producer: - - * Basic Producers - these are typically file or device oriented feeds; - * Playlists - these are arrangements of multiple producers; - * Multitracks - these are the fx encapsulators. - - In the mlt model, producers are created and attached to 'consumers' - - consumers are software playback components (such as SDL), or wrappers for - hardware drivers (such as bluefish) or even the westley serialising - consumer itself (the latter doesn't receive frames - it merely - interrogates the connected producer for its configuration). - - Although westley was defined as a serialisation mechanism for instantiated - MLT components, this document will concentrate on the hand authoring of - westley documents. - - -Rules: - - As shall become apparent through the remainder of this document, the basic - tenet of westley authoring is to organise the document in the following - manner: - - 1) create producer elements for each unique media clip in the project; - 2) create playlists for each track; - 3) create a multitrack and specify filters and transitions; - 4) adding global filters. - - While other uses of westley exist, the approach taken here is to maximise - efficiency for complex projects. - - -Basic Producers: - - The simplest westley document is: - - - - clip1.dv - - - - The westley wrapping is of course superfluous here - loading this document - with MLT is identical to loading the clip directly. - - Of course, you can specify additional properties. For example, consider an - MPEG file with multiple soundtracks - you could define a westley document to - ensure that the second audio track is loaded: - - - - clip1.mpeg - 1 - - - - NB: This relies on the mpeg being handled by the avformat producer, rather - than the mcmpeg one. See services.txt for more details. - - A more useful example comes with the pango producer for a text producer. - - TODO: pango example... - - Notes: - - 1) It is better not to specify in/out points when defining basic producers - as these can be specified in the playlists. The reasoning is that in/out - restricts the amount of the clip available, and could lead to the same clip - being loaded multiple times if you need different regions of the clip - elsewhere; - 2) A westley can be specified as a resource, so westleys can naturally - encapsulate other westleys. - - -Playlists: - - Playlists provide a 'collection' structure for producers. These can be used - to define 'tracks' in the multitrack approach, or simple playlists for - sequential, single track playout. - - As an example, the following defines two basic producers and a playlist with 3 - items: - - - - clip1.dv - - - clip2.dv - - - - - - - - - Here we see how the playlist defines the in/out points of the basic - producers. - - Notes: - - 1) All in/out points are absolute frame positions relative to the producer - being appended to the playlist; - 2) Westley documents are currently authored for a specific normalisation; - 3) The last 'producer' in the document is the default for play out; - 4) Playlists can reference the same producer multiple times. In/out regions - do not need to be contiguous - duplication and skipping is acceptable. - - -Interlude - Introducing Multitracks: - - So far we've defined basic producers and playlists/tracks - the tractor is - the element that allows us to arrange our tracks and specify filters and - transitions. Similarly to a playlist, a tractor is a container. - - Note that MLT doesn't see a filter or a transition as a producer in the - normal sense - filters and transitions are passive when it comes to seeking. - Internally, seeks are carried out on the producers. This is an important - point - MLT does not follow a traditional graph oriented model. - - Visualising an MLT tractor and it's interaction with the consumer will - assist here: - - +----------------------------------------------+ - |tractor | - | +----------+ +-+ +-+ +-+ +-+ | - | |multitrack| |f| |f| |t| |t| | - | | +------+ | |i| |i| |r| |r| | - | | |track0|-|--->|l|- ->|l|- ->|a|--->|a|\ | - | | +------+ | |t| |t| |n| |n| \ | - | | | |e| |e| |s| |s| \ | - | | +------+ | |r| |r| |i| |i| \ | +--------+ - | | |track1|-|- ->|0|--->|1|--->|t|--->|t|-----|--->|consumer| - | | +------+ | | | | | |i| |i| / | +--------+ - | | | | | | | |o| |o| / | ^ - | | +------+ | | | | | |n| |n| / | | - | | |track2|-|- ->| |- ->| |--->|0|- ->|1|/ | | - | | +------+ | | | | | | | | | | | - | +----------+ +-+ +-+ +-+ +-+ | | - +----------------------------------------------+ | - ^ | - | | - +-----------+ | - |APPLICATION|--------------------------------------------+ - +-----------+ - - Internally, all frames from all tracks pass through all the filters and - transitions - these are told which tracks to deal and which regions of the - tracks to work on. - - Note that the application communicates with the producer - it can alter - playback speed, position, or even which producer is connected to which - consumer. - - The consumer receives the first non-blank frame (see below). It has no say - in the order in which gets them (the sdl consumer when used with inigo might - appear to be an exception - it isn't - it simply has a route back to the - application to allow the application to interpret key presses). - - -Tractors: - - To create a multitrack westley, we can use two playlists and introduce a - tractor. For the purposes of demonstration, I'll add a filter here too: - - - - clip1.dv - - - clip2.dv - - - - - - - - - - - - - - - - 0 - greyscale - - - - - Here we see that blank frames are inserted into the first playlist and a - blank is provided at the beginning of the second - this can be visualised in - the traditional timeline widget as follows: - - +-------+ +-------------+ - |a | |a | - +-------+---+-------------+ - |b | - +---+ - - Adding the filter on the top track, gives us: - - +-------+ +-------------+ - |a | |a | - +-------+---+-------------+ - |greyscale | - --------+---+-------------+ - |b | - +---+ - - Note that it's only applied to the visible parts of the top track. - - The requirement to apply a filter to the output, as opposed to a specific - track leads us to the final item in the Rules section above. As an example, - let's assume we wish to watermark all output, then we could use the - following: - - - - clip1.dv - - - clip2.dv - - - - - - - - - - - - - - - - 0 - greyscale - - - - - - - - watermark - watermark1.png - - - - - Here we employ another tractor and we define a single track (being the - tractor we previously defined) and apply a watermarking filter there. - - This is simply provided as an example - the watermarking functionality could - be better handled at the playout stage itself (ie: as a filter automatically - placed between all producers and the consumer). - - Tracks act like "layers" in an image processing program like the GIMP. The - bottom-most track takes highest priority and higher layers are overlays - and do not appear unless there are gaps in the lower layers or unless - a transition is applied that merges the tracks on the specifed region. - Practically speaking, for A/B video editing it does not mean too much, - and it will work as expected; however, as a general rule apply any CGI - (graphic overlays with pixbuf or titles with pango) on tracks higher than - your video tracks. Also, this means that any audio-only tracks that are - lower than your video tracks will play rather than the audio from the video - clip. Remember, nothing is affected like mixing or compositing until one - applies a transition or appropriate filter. - - - - clip1.dv - - - - - - clip2.mpeg - - - - - - - - - - - - 0 - 1 - luma - - - 0 - 1 - mix - 0.0 - 1.0 - - - - - A "luma" transition is a video wipe processor that takes a greyscale bitmap - for the wipe definition. When one does not specify a bitmap, luma performs - a dissolve. The "mix" transition does an audio mix, but it interpolates - between the gain scaling factors between the start and end properties - - in this example, from 0.0 (none of track B) to 1.0 (all of track B). - Because the bottom track starts out with a gap specified using the - element, the upper track appears during the blank segment. See the demos and - services.txt to get an idea of the capabilities of the included transitions. - -Flexibility: - - The information presented above is considered the MLT Westley "normal" - form. This is the output generated by the westley consumer, for example, - when used with inigo. It is the output generated when you use the - "Westley to File" consumer in the demo script, which beginners will find - most useful for learning to use westley XML. This section describes - alternative forms the westley producer accepts. - - First of all, the normal form is more of a linear format with producers - and playlists defined prior to their usage in a multitrack. Westley - also accepts a hierarchical format with producers as children of tracks - or playlist entries and with playlists as children of tracks: - - - - - - - - - clip1.dv - - - - - - - - - Obviously, this example is meant to demonstrate hierarchy and not effective - use of playlist or multitrack! - - Secondly, as part of error handling, westley is forgiving if you fail to - supply , , and where one can be understood. This - affords an abbreviated syntax that is less verbose and perhaps less - intimidating for a human to read and understand. One can simplify the - above example as: - - - - - - clip1.dv - - - - - - Yes, filters and transitions can be added to the above example after the - closing multitrack tag () because it is still enclosed within - the westley body tags. - - If you specify in and out on a producer and it has been enclosed within - an or , then the edit points apply to the playlist - entry and not to the producer itself. This facilitates re-use of media: - - - - clip1.dv - - - - - In the above example, the producer attribute of the entry element is - a reference to the preceding producer. All references must follow the - definition. The edit points supplied on the producer above will not affect - the entry that references it below because westley knows the clip is a - playlist entry and optimises this situation. The advantage is that one - does not need to determine every clip to be included ahead of time - and specify them outside the context of the mutlitrack timeline. - - This form of authoring will be easier for many to visualise as a non-linear - editor's timeline. Here is a more complex example: - - - - - - clip2.mpeg - - - - - - - - clip3.mpeg - - - - - - - - - - - - Did you notice something different in the last example? Properties can be - expressed using XML attributes on the element as well. However, only - non-service-specific properties are supported in this way. For example, - "mlt_service" is available to any producer, filter, or transition. However, - "resource" is actually service-specific. Notice the syntax of the last - property, on the last transition. Westley accepts property values using - the "value" attribute as well as using element text. - - We have seen a few different ways of expressing property values. There are - a couple more for properties that can accept XML data. For example, the - GDK pixbuf producer with librsvg can handle embedded SVG, and the Pango - producer can handle embedded Pango markup. You can enclose the embedded XML - using a CDATA section: - - ... ]]> - - Please ensure the opening CDATA tag immediately follows the opening - property tag and that the section closing tag immediately precedes the - closing property tag. - - However, westley can also accept inline embedded XML: - - - - - - - Currently, there is no namespace handling so a conflict will occur only on - any embedded XML that contains an element named "property" because - westley collects embedded XML until it reaches a closing property tag. - - -Entities and Parameterisation: - - The westley producer parser supports XML entities. An example: - - - - ]> - - - pango - &msg; - - - - If you are embedding another XML document into a property value not using - a CNODE section, then any DOCTYPE section must be relocated before any of - the xml elements to be well-formed. See demo/svg.westley for an example. - - Entities can be used to parameterise westley! Using the above example, the - entity declared serves as the default value for &msg;. The entity content - can be overridden from the resource property supplied to the westley - producer. The syntax is the familiar, url-encoded query string used with - HTTP, e.g.: file?name=value&name=value... - - There are a couple of rules of usage. The Miracle LOAD command and inigo - command line tool require you to preface the URL with "westley:" because - the query string destroys the filename extension matching peformed by - Fezzik. Also, inigo looks for '=' to tokenise property settings. Therefore, - one uses ':' between name and value instead of '='. Finally, since inigo - is run from the shell, one must enclose the URL within single quotes to - prevent shell filename expansion, or similar. - - Needless to say, the ability to parameterise westley XML compositions is - an extremely powerful tool. An example for you to play with is available in - demo/entity.westley. Try overriding the name from inigo: - inigo 'westley:entity.westley?name:Charlie' - - Technically, the entity declaration is not needed in the head of the XML - document if you always supply the parameter. However, you run the risk - of unpredictable behviour without one. Therefore, it is safest and a best - practice to always supply an entity declaration. It is improves the - readability as one does not need to search for the entity references to - see what parameters are available. - - -Tips and Technique: - - If one finds the above hierarchical, abbreviated format intuitive, - start with a simple template and fill and extend as needed: - - - - - ...add a playlist for each track... - - ...add filters and transitions... - - - By using a playlist for each track, it is easier to iteratively add new - clips and blank regions as you develop the project. You will not have to - use or later add when necessary. - - A more advanced template that allows sequencing multitracks is: - - - - - - ...add a playlist for each track... - - ...add filters and transitions... - - - - - - - ...add a playlist for each track... - - ...add filters and transitions... - - - - If you end up making a collection of templates for various situations, then - consider using XML Entities to make the template more effective by moving - anything that should parameterised into an entity. - - If you want to have a silent, black background for audio and video fades, - then make the top track simply . Then, - use composite and volume effects. See the "Fade from/to black/silence" - demo for an example (demo/mlt_fade_black). - - If you apply the reverse=1 property to a transition like "luma," then - be careful because it also inherently swaps the roles of A and B tracks. - Therefore, you need to might need to swap the a_track and b_track values - if it did not turn out the way you expected. See the "Clock in and out" - for an example (demo/mlt_clock_in_and_out). diff --git a/mlt++/AUTHORS b/mlt++/AUTHORS deleted file mode 100644 index 5c6280c..0000000 --- a/mlt++/AUTHORS +++ /dev/null @@ -1,5 +0,0 @@ -MLT++ was developed by: -Charles Yates - -MLT++ is maintained by: -Dan Dennedy diff --git a/mlt++/COPYING b/mlt++/COPYING deleted file mode 100644 index 223ede7..0000000 --- a/mlt++/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/mlt++/ChangeLog b/mlt++/ChangeLog deleted file mode 100644 index a55c3a0..0000000 --- a/mlt++/ChangeLog +++ /dev/null @@ -1,552 +0,0 @@ -2009-04-10 ddennedy - - * test/play.cpp, test/server.cpp: cleanup some warnings - - * src/MltResponse.cpp, src/MltResponse.h: const update for MltResponse - - * src/MltResponse.cpp, src/MltResponse.h: Constness changes - - * src/MltTransition.cpp, src/MltTransition.h: Constness changes - - * src/MltProducer.cpp, src/MltProducer.h: Constness changes - - * src/MltProperties.cpp, src/MltProperties.h: Constness changes - - * src/MltConsumer.cpp, src/MltConsumer.h: Constness changes - - * src/MltProperties.cpp, src/MltResponse.cpp: Constness changes - - * src/MltProperties.cpp, src/MltPushConsumer.cpp: Constness changes - - * src/MltFilter.cpp, src/MltFilter.h, src/MltProperties.cpp, - src/MltProperties.h: Constness changes - - * src/MltConsumer.cpp, src/MltField.cpp, src/MltFilter.cpp, src/MltFrame.cpp, - src/MltMultitrack.cpp, src/MltPlaylist.cpp, src/MltProducer.cpp, - src/MltTractor.cpp, src/MltTransition.cpp: Fix up warnings about explicit - base initializers in copy constructors - - * configure: Add more warnings - - * .gitignore: Add a .gitignore file - -2009-04-02 ddennedy - - * swig/ruby/thumbs.rb: thumbs.rb: fix setting size property for avformat - consumer - -2009-02-04 ddennedy - - * debian/changelog, debian/control, debian/copyright, debian/rules: remove - debian package subdirectory (they provide their own) - -2009-01-26 ddennedy - - * swig/configure, swig/php/build, swig/php/play.php: swig/configure, - swig/php/*: add php bindings - -2008-12-28 ddennedy - - * swig/java/build, swig/python/build, swig/python/play.py, swig/tcl/build: - swig/{java,python,tcl}/build: fix linking error __stack_chk_fail_local. - swig/python/play.py: fix syntax error reported by Jonathon Thomas. - -2008-12-27 ddennedy - - * swig/configure: swig/configure: use pkg-config mlt-framework instead of - deprecated mlt-config. - -2008-12-04 ddennedy - - * README: README: update instructions to use pkg-config instead of mlt-config - - * swig/java/build, swig/perl/Makefile.PL, swig/python/build, swig/ruby/build, - swig/tcl/build, test/Makefile: test/Makefile, swig/*/build: replace more - mlt-config with pkg-config - -2008-11-06 ddennedy - - * src/Makefile: src/Makefile: suppress warning on ldconfig failure - -2008-10-25 ddennedy - - * configure: configure: apply patch from Alberto Villa to fix build on - FreeBSD - -2008-10-20 ddennedy - - * configure: configure: convert to use pkg-config; mlt-config is deprecated - -2008-08-06 ddennedy - - * AUTHORS: update mlt++ AUTHORS - - * Makefile: fix make dist target - - * configure: bump versions for 0.3.0 release - - * Makefile: improve make dist target - - * swig/java/Play.java, swig/java/Play.sh, swig/java/build: swig/java: fixup - the java bindings build script and example (bug 1523941) - -2008-06-26 ddennedy - - * src/MltProducer.cpp, src/MltProducer.h, swig/mltpp.i: MltProducer.{h,cpp}, - mltpp.i: remove Producer::get_frame that is unncessary and introduced a - memory leak. - -2008-06-24 ddennedy - - * src/MltPlaylist.cpp: MltPlaylist.cpp: return null on clip_info method if - mlt_playlist_get_clip_info fails. - -2008-06-08 ddennedy - - * src/MltPlaylist.cpp: MltPlaylist.cpp: prevent strdup from crashing on a - null pointer. - -2008-04-23 ddennedy - - * src/MltProducer.cpp, src/MltProducer.h, swig/mltpp.i: MltProducer.{h,cpp}, - swig/mltpp.i: add method Producer::get_frame. - -2008-04-12 ddennedy - - * test/server.cpp: test/server.cpp: bugfix (1940389) compilation on gcc 4.3 - -2008-02-27 ddennedy - - * src/MltRepository.cpp, src/MltRepository.h: MltRepository.{h,cpp}: update - to latest mlt_repository.h change - finalization of callback declarations and - metadata handling - -2008-02-16 ddennedy - - * swig/python/build: swig/python/build: add -fPIC - - * src/MltRepository.cpp, src/MltRepository.h, swig/mltpp.i: - MltRepository.{h,cpp}, swig/mltpp.i: added consumers, filters, producers, - transitions, register_metadata, and metadata methods to Repository class - -2008-02-12 ddennedy - - * Makefile: do not make tests automatically - -2008-02-07 ddennedy - - * configure, src/Makefile: configure: add soversion variable src/Makefile: - improve library versioning by linking on interface version (soversion) - - * swig/ruby/thumbs.rb: thumbs.rb: fix error on Playlist.append due to args - not int - - * src/Makefile, src/Mlt.h, src/MltFactory.cpp, src/MltFactory.h, - src/MltRepository.cpp, src/MltRepository.h, swig/mltpp.i: Mlt.h, - MltFactory.{h,cpp}, MltRepository.{h,cpp}, swig/mltpp.i: update to deal with - changes and new capabilities in mlt_factory and mlt_repository. - -2008-02-04 ddennedy - - * COPYING: add COPYING to disclose license - -2008-02-02 ddennedy - - * src/Makefile, src/Mlt.h, src/MltConsumer.cpp, src/MltConsumer.h, - src/MltFactory.cpp, src/MltFactory.h, src/MltFilter.cpp, src/MltFilter.h, - src/MltFilteredConsumer.cpp, src/MltFilteredConsumer.h, - src/MltFilteredProducer.cpp, src/MltFilteredProducer.h, src/MltProducer.cpp, - src/MltProducer.h, src/MltProfile.cpp, src/MltProfile.h, - src/MltPushConsumer.cpp, src/MltPushConsumer.h, src/MltService.cpp, - src/MltService.h, src/MltTractor.cpp, src/MltTractor.h, - src/MltTransition.cpp, src/MltTransition.h, swig/mltpp.i, swig/perl/play.pl, - swig/python/play.py, swig/ruby/miracle.rb, swig/ruby/play.rb, - swig/ruby/thumbs.rb, swig/tcl/play.tcl, test/play.cpp, test/server.cpp: add - MltProfile and update examples - -2007-06-12 ddennedy - - * Makefile: added dist make targets - - * Makefile, src/Makefile, test/Makefile: added uninstall make targets - -2006-03-20 lilo_booter - - * src/MltFactory.h: + Fix for swig parsing - -2006-02-23 lilo_booter - - * src/Makefile: + Install of config.h for linux and os/x usage - - * src/config.h: + Added the config.h for win32 - - * mlt++.sln, mlt++.vcproj, src/Mlt.h, src/MltConsumer.h, src/MltDeque.h, - src/MltEvent.h, src/MltFactory.cpp, src/MltFactory.h, src/MltField.h, - src/MltFilter.h, src/MltFilteredConsumer.h, src/MltFilteredProducer.h, - src/MltFrame.cpp, src/MltFrame.h, src/MltGeometry.h, src/MltMultitrack.h, - src/MltParser.h, src/MltPlaylist.cpp, src/MltPlaylist.h, src/MltProducer.cpp, - src/MltProducer.h, src/MltProperties.cpp, src/MltProperties.h, - src/MltPushConsumer.h, src/MltService.h, src/MltTokeniser.h, - src/MltTractor.h, src/MltTransition.h: + Win32 port - dev studio is required - to avoid issues with C++ ABI compatibility + Fix for image render in NTSC - NB: mlt patch to follow (this one isn't much use without it :-)) - mlt build - is purely mingw32 of course - -2005-12-05 lilo_booter - - * configure, src/Makefile: + Fix for Darwin and soname logic - - * debian/changelog, debian/control, debian/copyright, debian/rules: + - Functional debian build rules - - * Makefile, configure, src/Makefile, test/Makefile: + MLT++ updates for 0.2.1 - - distclean corrected, soname usage in linking - -2005-11-29 lilo_booter - - * Makefile, configure: + Correction to a typo - - * swig/perl/Makefile.PL: + Perl compilation patch submitted by Torsten - Spindler - - * configure, src/Makefile: + Added a --libdir switch to the configure and - build and fixed test case compilation - -2005-11-22 lilo_booter - - * configure: + Allow LDFLAGS to be inherited from the environment - -2005-11-21 lilo_booter - - * src/Makefile: + Creates the lib directory on an install - -2005-11-10 lilo_booter - - * Makefile, src/Makefile: + DESTDIR patch from Anthony Green (green at redhat - dot com) - many thanks :-) - -2005-10-03 lilo_booter - - * src/MltProperties.cpp, src/MltProperties.h: OS/X gcc/g++ 4.x fix - - * configure, src/Makefile, src/MltProperties.cpp, src/MltProperties.h, - test/Makefile: + Whoops - had forgotten these OS/X patches... - -2005-09-29 lilo_booter - - * src/MltPushConsumer.cpp: + Oops - fix for memory leak - -2005-09-28 lilo_booter - - * src/Makefile, src/Mlt.h, src/MltPushConsumer.cpp, src/MltPushConsumer.h: + - Added a push based consumer wrapper - -2005-07-26 lilo_booter - - * swig/Makefile, swig/configure, swig/perl/Makefile.PL, swig/python/build, - swig/tcl/build: + Cleaned up swig build so it doesn't require an mlt++ - install first - Temporarily disabled java - -2005-06-27 lilo_booter - - * CUSTOMISING, test/server.cpp: CUSTOMISING + Replaced TBD for frame - rendering notification event test/server.cpp + Added an example frame - rendering callback that removes all shotcut related fx - -2005-06-26 lilo_booter - - * CUSTOMISING, swig/ruby/thumbs.rb: CUSTOMISING + Added an example of how to - hide a track on reception swig/ruby/thumbs.rb + Changed generator to run, - rather than sleep and poll - -2005-04-12 lilo_booter - - * CUSTOMISING: Minor doc updates - -2005-03-16 lilo_booter - - * CUSTOMISING, src/MltProperties.cpp, src/MltProperties.h, - src/MltResponse.cpp, src/MltResponse.h, test/server.cpp: Server customisation - - -2005-02-12 lilo_booter - - * src/MltService.cpp: Minor correction - -2005-01-14 lilo_booter - - * src/MltProperties.cpp, src/MltProperties.h: Const string usage in - properties - -2005-01-03 lilo_booter - - * src/MltGeometry.cpp, src/MltGeometry.h: Next/Prev key extraction - - * src/MltMiracle.cpp, src/MltMiracle.h, swig/mltpp.i: Fetch unit from miracle - server - -2004-12-31 lilo_booter - - * src/MltGeometry.h: Update for geometry - -2004-12-24 lilo_booter - - * src/Makefile, src/Mlt.h, src/MltGeometry.cpp, src/MltGeometry.h, - swig/mltpp.i: Geometry - -2004-12-12 lilo_booter - - * src/MltPlaylist.cpp, src/MltPlaylist.h: blank_at method added - -2004-12-11 lilo_booter - - * src/MltPlaylist.cpp, src/MltPlaylist.h: split_at method added - -2004-12-09 lilo_booter - - * src/MltTractor.cpp, src/MltTractor.h: Tractor constructor modifications - -2004-11-25 lilo_booter - - * swig/Makefile: Install makefile for swig - - * src/Makefile, src/Mlt.h, src/MltDeque.cpp, src/MltDeque.h, - src/MltFactory.cpp, src/MltFactory.h, src/MltProducer.cpp, src/MltProducer.h, - src/MltTransition.cpp, src/MltTransition.h: Deque added; simplified producer - parent access; transition in and out - -2004-11-22 lilo_booter - - * src/MltPlaylist.cpp, src/MltPlaylist.h, src/MltProducer.cpp, - src/MltProducer.h, src/MltProperties.cpp, src/MltService.cpp, - src/MltService.h, test/Makefile: More playlist modifications; service locking - - -2004-11-17 lilo_booter - - * src/MltProperties.cpp, src/MltProperties.h, src/MltTractor.cpp, - src/MltTractor.h: Ref count and event firing method on properties; locate_cut - on tractor - -2004-11-11 lilo_booter - - * src/MltPlaylist.cpp, src/MltPlaylist.h, src/MltProducer.cpp, - src/MltProducer.h, src/MltProperties.cpp, src/MltProperties.h, - src/MltTractor.cpp, src/MltTractor.h: Playlist reorganisation - -2004-11-07 lilo_booter - - * src/MltPlaylist.cpp, src/MltPlaylist.h, src/MltTractor.cpp, - src/MltTractor.h: Simplified playlist and track access - -2004-11-05 lilo_booter - - * src/MltProducer.cpp, src/MltProducer.h: Added cut related methods - -2004-10-31 lilo_booter - - * src/Makefile, src/Mlt.h, src/MltTokeniser.cpp, src/MltTokeniser.h, - test/server.cpp: Added courtesy tokenising class - -2004-10-27 lilo_booter - - * configure, swig/configure, swig/ruby/build, swig/ruby/miracle.rb: Config - changes - -2004-10-17 lilo_booter - - * src/MltMiracle.cpp, src/MltMiracle.h: id and log level for server - - * src/MltMiracle.cpp: Server shutdown state - -2004-10-14 lilo_booter - - * src/MltConsumer.cpp, src/MltConsumer.h, test/play.cpp: buffer fix and - tractor handling - - * HOWTO: Doc updates - - * src/MltMiracle.cpp, src/MltMiracle.h: Improved push capabilities - -2004-10-08 lilo_booter - - * src/MltProducer.cpp, src/MltProducer.h: Same and following clip - identification - -2004-10-05 lilo_booter - - * src/Makefile, src/Mlt.h, src/MltFrame.cpp, src/MltFrame.h, - src/MltParser.cpp, src/MltParser.h, src/MltService.cpp, src/MltService.h, - swig/mltpp.i: Added the parser object and moved type identity into mlt - -2004-09-29 lilo_booter - - * src/MltPlaylist.cpp, src/MltPlaylist.h, swig/mltpp.i: new mix related - methods - -2004-09-26 lilo_booter - - * README, src/MltPlaylist.cpp, src/MltPlaylist.h: Playlist repeat clip - functionality - -2004-09-24 lilo_booter - - * src/MltProducer.cpp, src/MltProducer.h, swig/mltpp.i: Cut management part 1 - - -2004-09-23 lilo_booter - - * src/MltService.cpp, swig/mltpp.i: get_frame and ruby listen fix - -2004-09-22 lilo_booter - - * src/MltFrame.cpp, src/MltProperties.cpp, src/MltProperties.h, swig/mltpp.i: - Event and frame handling - - * configure, src/MltMiracle.cpp: Server shutdown - -2004-09-19 lilo_booter - - * src/Makefile, src/Mlt.h, src/MltMiracle.cpp, src/MltMiracle.h, - src/MltResponse.cpp, src/MltResponse.h, swig/mltpp.i: Added the response - object - - * HOWTO, src/Makefile, src/Mlt.h, src/MltMiracle.cpp, src/MltMiracle.h, - swig/mltpp.i, swig/ruby/miracle.rb, test/Makefile, test/play.cpp, - test/server.cpp: Adding miracle - -2004-09-09 lilo_booter - - * src/MltPlaylist.cpp, src/MltPlaylist.h: Adding the mix part 1 - -2004-09-06 lilo_booter - - * src/MltFilteredConsumer.cpp, src/MltFilteredConsumer.h, - src/MltProducer.cpp, src/MltProducer.h, src/MltService.cpp, src/MltService.h, - swig/mltpp.i: Service attach filters - -2004-09-03 lilo_booter - - * HOWTO, src/MltProperties.cpp, src/MltProperties.h, swig/mltpp.i, - swig/perl/play.pl: More event stuff - -2004-09-02 lilo_booter - - * src/Makefile, src/Mlt.h, src/MltEvent.cpp, src/MltEvent.h, - src/MltProperties.cpp, src/MltProperties.h, swig/mltpp.i, swig/ruby/play.rb, - test/play.cpp: Event modifications - -2004-08-31 lilo_booter - - * HOWTO, src/Makefile, src/MltConsumer.cpp, src/MltConsumer.h, - src/MltFilter.cpp, src/MltFilter.h, src/MltFrame.cpp, src/MltFrame.h, - src/MltMultitrack.cpp, src/MltMultitrack.h, src/MltPlaylist.cpp, - src/MltPlaylist.h, src/MltProducer.cpp, src/MltProducer.h, - src/MltService.cpp, src/MltService.h, src/MltTractor.cpp, src/MltTractor.h, - src/MltTransition.cpp, src/MltTransition.h: Run time type identification - -2004-08-28 lilo_booter - - * README, src/MltMultitrack.cpp, src/MltMultitrack.h, src/MltTractor.cpp, - src/MltTractor.h, swig/mltpp.i: Tractor enhancements - - * src/Makefile, src/Mlt.h, src/MltField.cpp, src/MltField.h, - src/MltMultitrack.cpp, src/MltMultitrack.h, src/MltTractor.cpp, - src/MltTractor.h, swig/mltpp.i: Multitrack classes added - - * src/MltPlaylist.cpp, src/MltPlaylist.h, src/MltProducer.cpp, - src/MltProducer.h, swig/mltpp.i: Producer filter extraction method - -2004-08-27 lilo_booter - - * src/Makefile, src/Mlt.h, src/MltFilteredProducer.cpp, - src/MltFilteredProducer.h, src/MltProducer.cpp, src/MltProducer.h, - src/MltService.cpp, src/MltService.h, swig/mltpp.i: Removed FilteredProducer - -2004-08-26 lilo_booter - - * Makefile, test/Makefile, test/play.cpp: Build modifications - - * src/MltConsumer.cpp, src/MltConsumer.h, src/MltFilter.cpp, src/MltFilter.h, - src/MltFilteredConsumer.cpp, src/MltFilteredConsumer.h, src/MltFrame.cpp, - src/MltFrame.h, src/MltPlaylist.cpp, src/MltPlaylist.h, src/MltProducer.cpp, - src/MltProducer.h, src/MltProperties.cpp, src/MltProperties.h, - src/MltService.cpp, src/MltService.h, src/MltTransition.cpp, - src/MltTransition.h, swig/perl/play.pl: Mlt Ref Counts and Playlist - split/join - -2004-08-23 lilo_booter - - * swig/perl/play.pl: Added play.pl - - * src/Makefile, swig/mltpp.i: Workaround for perl - -2004-08-21 lilo_booter - - * src/MltConsumer.cpp, src/MltFilter.cpp, src/MltProperties.cpp, - src/MltProperties.h, src/MltTransition.cpp: Constructor clean up - - * src/MltConsumer.cpp, src/MltConsumer.h: consumer purge - -2004-08-20 lilo_booter - - * src/MltFilter.cpp, src/MltFilter.h, src/MltPlaylist.cpp, src/MltPlaylist.h, - swig/configure, swig/java/build, swig/ruby/build, swig/ruby/thumbs.rb: - mlt_position, /usr/bin/env and Instance fix - -2004-08-18 lilo_booter - - * src/MltFrame.cpp, src/MltFrame.h, src/MltProducer.cpp, src/MltProducer.h, - src/MltService.cpp, swig/mltpp.i, swig/ruby/play.rb: image handling - -2004-08-17 lilo_booter - - * swig/java/Play.java, swig/ruby/play.rb, swig/ruby/thumbs.rb: Fixes for mods - to api - - * src/Makefile, src/Mlt.h, src/MltConsumer.cpp, src/MltConsumer.h, - src/MltFilteredConsumer.cpp, src/MltFilteredConsumer.h, - src/MltFilteredProducer.cpp, src/MltFilteredProducer.h, src/MltService.cpp, - src/MltService.h, swig/mltpp.i: Filtered producers and consumers - - * test/play.cpp: oops - -2004-08-16 lilo_booter - - * swig/configure, swig/java/Play.java, swig/java/Play.sh, swig/java/build, - swig/mltpp.i, swig/perl/Makefile.PL, swig/perl/build, swig/python/build, - swig/python/play.py, swig/ruby/build, swig/ruby/play.rb, swig/ruby/thumbs.rb, - swig/tcl/build, swig/tcl/play.tcl: Experimental swig bindings - - * README, src/MltFactory.cpp, src/MltFactory.h, src/MltFilter.cpp, - src/MltPlaylist.cpp, src/MltPlaylist.h, src/MltProducer.cpp, - src/MltProperties.cpp, src/MltProperties.h, src/MltService.cpp, - src/MltService.h, src/MltTransition.cpp, test/Makefile: More cleanups - - * README, src/MltConsumer.cpp, src/MltConsumer.h, src/MltFactory.cpp, - src/MltFactory.h, src/MltFilter.cpp, src/MltFilter.h, src/MltFrame.cpp, - src/MltFrame.h, src/MltPlaylist.cpp, src/MltPlaylist.h, src/MltProducer.cpp, - src/MltProducer.h, src/MltProperties.cpp, src/MltProperties.h, - src/MltService.cpp, src/MltService.h, src/MltTransition.cpp, - src/MltTransition.h, test/play.cpp: Class rework and simplification - - * src/Makefile, src/Mlt.h: Added Mlt.h convenience header - - * src/MltPlaylist.cpp, src/MltPlaylist.h, src/MltProperties.cpp, - src/MltProperties.h, src/MltService.cpp: Complete methods for properties and - playlist; reversed NULL handling on service class - - * README, src/MltProperties.cpp, src/MltProperties.h, test/play.cpp: Object - validity checks - - * AUTHORS, Makefile, README, configure, src/Makefile, src/MltService.cpp, - test/play.cpp: Build and docs modifications - -2004-08-15 lilo_booter - - * src/Makefile, src/MltConsumer.cpp, src/MltConsumer.h, src/MltFactory.cpp, - src/MltFactory.h, src/MltFilter.cpp, src/MltFilter.h, src/MltFrame.cpp, - src/MltFrame.h, src/MltPlaylist.cpp, src/MltPlaylist.h, src/MltProducer.cpp, - src/MltProducer.h, src/MltProperties.cpp, src/MltProperties.h, - src/MltService.cpp, src/MltService.h, src/MltTransition.cpp, - src/MltTransition.h, test/Makefile, test/play.cpp: Initial revision diff --git a/mlt++/HOWTO b/mlt++/HOWTO deleted file mode 100644 index dbeca9a..0000000 --- a/mlt++/HOWTO +++ /dev/null @@ -1,473 +0,0 @@ -INTRODUCTION ------------- - - This document provides a brief tutorial on the use of the mlt++ wrapper - and bindings. - - -Hello World ------------ - - The mlt++ wrapper is a c++ wrapper for the mlt C library. As such, it - provides clean C++ access to the underlying library. - - An example of use is as follows: - - #include - using namespace Mlt; - - int main( void ) - { - Factory::init( ); - Producer p( "pango:", "Hello World" ); - Consumer c( "sdl" ); - c.connect( p ); - c.run( ); - return 0; - } - - This is a fairly typical example of mlt++ usage - create a 'producer' (an - object which produces 'frames'), create a 'consumer' (an object which consumes - frames), connect them together, start the consumer and wait until done (here - we just wait for the user to close the window). - - In this case, we construct a window as a consumer using the 'sdl' consumer - (SDL is a standard portable library which provides platform independent - access to accelerated video display and audio) and use the 'pango' - producer to generate frames with the words 'Hello World' (pango is a - library from the gtk toolkit). - - The main point of this example is to show that mlt uses existing libraries - to provide its functionality - this keeps the framework itself very small. - - Note that mlt is designed to be housed in GUI or server type applications - - typically, applications don't wait around for the consumer to be stopped in - the manner shown. - - So far, we've introduced the Producer and Consumer mlt classes. We'll cover - each of these in more detail later in the tutorial, but for now, we'll - briefly cover the remaining classes. - - -Playlists ---------- - - Another simple class is the Playlist - this is direct extension of Producer - and it allows you to maintain a list of producer objects. - - As a simple example of the Playlist in action, we'll convert the example - above into an application which plays multiple video or audio files. - - #include - using namespace Mlt; - - int main( int argc, char **argv ) - { - Factory::init( ); - Playlist list; - for ( int i = 1; i < argc; i ++ ) - { - Producer p( argv[i] ); - if ( p.is_valid( ) ) - list.append( p ); - } - Consumer c( "sdl" ); - c.connect( list ); - c.run( ); - return 0; - } - - Now you can run the program as: - - ./player *.avi *.mp3 *.jpg etc - - In this case, we construct a playlist by simply appending producers to it. - Notice that although the scope of the Producer is limited to the inner - for loop, we can safely add it to the playlist - this is due to the fact - that all mlt objects maintain reference counts and no object is really - destroyed until all the references are gone. In this case, when the list - object goes out of scope, all the producers we created will automatically - be destroyed. - - -Filters -------- - - So far, we've shown how you can load and play media. We've given a brief - intro to the Playlist container, now it's time to start manipulating - things... - - For the next example, I'll add a 'watermark' to the video - a watermark - is used by broadcasters to brand the channel and normally consists of a - logo of some sort. We'll just use some black text on a partially - transparent red background. - - #include - using namespace Mlt; - - int main( int argc, char **argv ) - { - Factory::init( ); - Playlist list; - for ( int i = 1; i < argc; i ++ ) - { - Producer p( argv[i] ); - if ( p.is_valid( ) ) - list.append( p ); - } - Filter f( "watermark", "pango:" ); - f.set( "producer.text", "MLT++" ); - f.set( "producer.fgcolour", "0x000000ff" ); - f.set( "producer.bgcolour", "0xff000080" ); - list.attach( f ); - Consumer c( "sdl" ); - c.connect( list ); - c.run( ); - return 0; - } - - Notice that the watermark filter reuses the 'pango' producer we showed in the - first example. In fact, you could use any producer here - if you wanted to - use a graphic or a video, you would just construct the filter with a full path - to that as the second argument. - - We manipulate the filter using the set method - this method was also shown - in the first example. - - Finally, we attach the filter to the playlist. This ensure that all frames - that are obtained from the playlist are watermarked. - - -Cuts ----- - - When you add a clip to a playlist, the a cut object is created - this is merely a - wrapper for the producer, spanning the specified in and out points. - - Whenever you retrieve a clip from a playlist, you will always get a cut object. - This allows you to attach filters to a specific part of a producer and should - the position of the cut in the playlist change, then the filter will remain - correctly associated to it. - - A producer and a cut are generally identical in behaviour, but should you need to - distinguish between them, you can use: - - if ( producer.is_cut( ) ) - - and to retrieve the parent of a cut, you can use: - - Producer parent = producer.parent_cut( ); - - Filters that are attached directly to a parent are executed before any filters - attached to the cut. - - -Tractor -------- - - A tractor is an object that allows the manipulation of multiple video and audio - tracks. - - Stepping away from the player example we've been tinkering with for a minute, - let's assume we want to do something like dub a video with some audio. This - a very trivial thing to do: - - Tractor *dub( char *video_file, char *audio_file ) - { - Tractor *tractor = new Tractor( ); - Producer video( video_file ); - Producer audio( audio_file ); - tractor->set_track( video, 0 ); - tractor->set_track( audio, 1 ); - return tractor; - } - - That's all that needs to be done - you can now connect the returned object to a - consumer, or add it to a playlist, or even apply it as a track to another tractor. - - -Transition ----------- - - Let's now assume we want to mix the audio between two tracks - to do this, we - need to introduce the concept of a transition. A transition in mlt is a service - which combines frames from two producers to produce a new frame. - - Tractor *mix( char *video_file, char *audio_file ) - { - Tractor *tractor = new Tractor( ); - Transition mix( "mix" ); - Producer video( video_file ); - Producer audio( audio_file ); - tractor.set_track( video, 0 ); - tractor.set_track( audio, 1 ); - tractor.field.plant_transition( mix, 0, 1 ); - return tractor; - } - - The tractor returned will now mix the audio from the original video and the - audio. - - -Mix ---- - - There is a convenience function which simplifies the process of applying - transitions betwee adjacent cuts on a playlist. This is often preferable - to use over the constuction of your own tractor and transition set up. - - To apply a 25 frame luma transition between the first and second cut on - the playlist, you could use: - - Transition luma; - playlist.mix( 0, 25, luma ); - - -Events ------- - - Typically, applications need to be informed when changes occur in an mlt++ object. - This facilitates application services such as undo/redo management, or project - rendering in a timeline type widget and many other types of operations which an - application needs. - - As an example, consider the following: - - class Westley - { - private: - Consumer consumer; - Tractor &tractor; - public: - Westley( MltTractor &tractor ) : - tractor( tractor ), - consumer( "westley" ) - { - consumer.connect( tractor ); - tractor.listen( tractor, "producer-changed", - ( mlt_listener )Westley::listener ); - } - - static void listener( Properties *tractor, Westley *object ) - { - object->activate( ); - } - - void activate( ) - { - consumer.start( ); - } - }; - - Now, each time the tractor is changed, the westley representation is output to - stderr. - - -Servers and Westley Docs ------------------------- - - One of the key features of MLT is its server capabilities. This feature - allows you to pass westley documents seamlessly from one process to - another and even to different computers on your network. - - The miracle playout server is one such example of an application which - uses this functionality - you can build your own servers into your own - processes with ease. - - A server process would be running as follows: - - #include - using namespace Mlt; - - int main( void ) - { - Miracle miracle( "miracle", 5250 ); - miracle.start( ); - miracle.execute( "uadd sdl" ); - miracle.execute( "play u0" ); - miracle.wait_for_shutdown( ); - return 0; - } - - Typically, when you have an MLT object such as a producer or a playlist, - you can send a westley representation of this to a running server with: - - Conumser valerie( "valerie", "localhost:5250" ); - valerie.connect( producer ); - valerie.start( ); - - The effect of the push will be to append the producer on to the first - unit (u0). - - You can completely customise the miracle server - an example of this - is shown below. - - -That's All Folks... -------------------- - - And that, believe it or not, is a fairly complete summary of the classes you'll - typically be interfacing with in mlt++. Obviously, there's a little more to it - than this - a couple of intrisinc classes have been glossed over (notably, the - Properties and Service base classes). The next section will cover all of the - above, but in much more detail... - - -DIGGING DEEPER --------------- - - The previous section was designed to give you a whistle stop tour through the major - framework classes. This section will take you through the scenic route. - - -Introducing Base Classes ------------------------- - - Services in mlt are the collective noun for Producers, Filters, Transitions and - Consumer. A Service is also the base class from which all of these classes - extend. It provides the basic connectivity which has been shown throughout the - examples in the previous section. - - Properties are the main way in which we communicate with the Services - - essentially, it provides get/set methods for named values. All services extend - Properties. - - -Properties ----------- - - Properties provide the general mechanism for communicating with Services - - through the Properties interface, we are able to manipulate and serialise - a services state. - - For example, to dump all the properties to stdout, you can use something - like: - - void dump( Properties &properties ) - { - for ( int i = 0; i < properties.count( ); i ++ ) - cout << Properties.get_name( i ) << " = " << Properties.get( i ) << endl; - } - - Note that the properties object handles type conversion, so the following - is acceptable: - - properties.set( "hello", "10.5" ); - int hello_int = properties.get_int( "hello" ); - double hello_double = properties.get_double( "hello" ); - - A couple of convenience methods are provide to examine or serialise property - objects. - - For example: - - properties.debug( ); - - will report all serialisable properties on stderr, in the form: - - Object: [ ref=1, in=0, out=0, track=0, u=75, v=150, _unique_id=15, - mlt_type=filter, mlt_service=sepia ] - - -Services --------- - - Typically, all the services are constructed via the specific classes - constructor. Often, you will receive Service objects rather than their - specific type. In order to access the extended classes interface, - you will need to create a reference. - - For example, given an arbitrary Service object, you can determine its - type by using the type method - this will return a 'service_type' which - has values of producer_type, filter_type etc. Alternatively, you can - create a wrapping object and check on its validity. - - bool do_we_have_a_producer( Service &service ) - { - Producer producer( service ); - return producer.is_valid( ); - } - - -Events ------- - - -Servers and Westley Docs ------------------------- - - For various reasons, you might want to serialise a producer to a string. - To do this, you just need to specify a property to write to: - - Consumer westley( "westley", "buffer" ); - westley.connect( producer ); - westley.start( ); - buffer = westley.get( "buffer" ); - - You can use any name you want, and you can change it using the "resource" - property. Any name with a '.' in it is considered to be a file. Hence, you - can use a westley consumer to store multiple instances of the same MLT - object - useful if you want to provide undo/redo capabilities in an - editing application. - - Should you receive an xml document as a string, and you want to send it - on to a server, you can use: - - Conumser valerie( "valerie", "localhost:5250" ); - valerie.set( "westley", buffer ); - valerie.start( ); - - If you need to obtain an MLT object from a string: - - Producer producer( "westley-xml", buffer ); - - The following shows a working example of an extended server: - - class ShotcutServer : public Miracle - { - public: - ShotcutServer( char *id, int port ) : - Miracle( id, port ) - { - } - - void set_receive_doc( bool doc ) - { - set( "push-parser-off", doc ); - } - - // Reject all commands other than push/receive - Response *execute( char *command ) - { - valerie_response response = valerie_response_init( ); - valerie_response_set_error( response, 400, "Not OK" ); - return new Response( response ); - } - - // Push document handler - Response *received( char *command, char *doc ) - { - valerie_response response = valerie_response_init( ); - // Use doc in some way and assign Response - if ( doc != NULL ) - valerie_response_set_error( response, 200, "OK" ); - return new Response( response ); - } - - // Push service handler - Response *push( char *command, Service *service ) - { - valerie_response response = valerie_response_init( ); - // Use service in some way and assign Response - if ( service != NULL ) - valerie_response_set_error( response, 200, "OK" ); - return new Response( response ); - } - }; - - NB: Should you be incorporating this into a GUI application, remember that the - execute, received and push methods are invoked from a thread - make sure that - you honour the locking requirements of your GUI toolkit before interacting with - the UI. - - diff --git a/mlt++/README b/mlt++/README deleted file mode 100644 index 54c6377..0000000 --- a/mlt++/README +++ /dev/null @@ -1,135 +0,0 @@ -MLT++ ------ - - This mlt sub-project provides a C++ wrapping for the MLT library. - -INSTALLATION ------------- - - ./configure [ --prefix=path ] - make - make install - -USAGE ------ - - Use the following definitions in a Makefile to compile and link with mlt++: - - CXXFLAGS=`pkg-config --cflags mlt-framework` -Wall - LDFLAGS=-lmlt++ `pkg-config --libs mlt-framework` - - Include files for the classes can either be explicitly included, ie: - - #include - etc - - Or you can include all using: - - #include - - All definitions are placed in an Mlt namespace, and adhere closely to the C - naming convention. Mappings always follow the pattern: - - Factory methods: - - mlt_factory_init ==> Mlt::Factory::init - mlt_factory_producer ==> Mlt::Factory::producer - mlt_factory_filter ==> Mlt::Factory::filter - mlt_factory_transition ==> Mlt::Factory::transition - mlt_factory_consumer ==> Mlt::Factory::consumer - mlt_factory_close ==> Mlt::Factory::close - - NB: Factory usage for service construction is optional. - - Types: - - mlt_properties ==> Mlt::Properties - mlt_frame ==> Mlt::Frame - mlt_service ==> Mlt::Service - mlt_producer ==> Mlt::Producer - mlt_filter ==> Mlt::Filter - mlt_transition ==> Mlt::Transition - mlt_consumer ==> Mlt::Consumer - - Methods: - - mlt_type_method ==> Mlt::Type.method - ie: mlt_playlist_append ==> Mlt::Playlist.append - - Parent methods are available directly on children. - - Additionally, you can specify: - - using namespace Mlt; - - To avoid the enforced use of the Mlt:: prefix. - - Enumerators and macros are reused directly from the C library. - -CLASS HIERARCHY ---------------- - - The currently mapped objects are shown in the following hierarchy: - - Factory - Properties - Frame - Service - Consumer - Field - Filter - Multitrack - Producer - Playlist - Tractor - Transition - - An additional set of classes allow apps to behave as, and communicate with, - client/server components - these components provide MLT with unique - possibilties for process to process or system to system communications. - - Miracle - Response - -SPECIAL CASES -------------- - - Care should be taken with wrapper objects. - - Taking, as an example, the C function that returns the immediate consumer of - a service: - - mlt_service mlt_service_consumer( mlt_service ); - - This maps to: - - Mlt::Service *Mlt::Service.consumer( ); - - Note that you get an object back - it is never the original c++ object, but - a wrapping object. This is done to keep consistency with the C api which may - instantiate C instances - therefore it cannot be assumed that a C++ object - exists for all mlt service instances. - - As such, it is mandatory that you delete these objects. The original will - not be affected. However, all other modifications (to properties or its - state of connection) will be reflected in the original object. - - This approach excludes the use of RTTI to determine the real type of the - object - this can only be done by parsing the objects properties. - - Objects may be invalid - always use the is_valid method to check validity - before use. - -LIMITATIONS ------------ - - The mechanisms for the definition of new services are deliberately - excluded from the C++ wrappings - this is done to ensure that service - networks constructed can be serialised and used by existing applications - which are based on the C API (such as miracle). - -SWIG ----- - - Experimental swig bindings based on mlt++ are provided. - diff --git a/mlt++/mlt++.sln b/mlt++/mlt++.sln deleted file mode 100644 index 1820fb8..0000000 --- a/mlt++/mlt++.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mlt++", "mlt++.vcproj", "{31B6CBDB-6A84-4BC7-AACF-A1BCE02444FD}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {31B6CBDB-6A84-4BC7-AACF-A1BCE02444FD}.Debug.ActiveCfg = Debug|Win32 - {31B6CBDB-6A84-4BC7-AACF-A1BCE02444FD}.Debug.Build.0 = Debug|Win32 - {31B6CBDB-6A84-4BC7-AACF-A1BCE02444FD}.Release.ActiveCfg = Release|Win32 - {31B6CBDB-6A84-4BC7-AACF-A1BCE02444FD}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/mlt++/mlt++.vcproj b/mlt++/mlt++.vcproj deleted file mode 100644 index 6faedb5..0000000 --- a/mlt++/mlt++.vcproj +++ /dev/null @@ -1,265 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mlt++/src/Mlt.h b/mlt++/src/Mlt.h deleted file mode 100644 index 4dab95a..0000000 --- a/mlt++/src/Mlt.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Mlt.h - Convenience header file for all mlt++ objects - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_H_ -#define _MLTPP_H_ - -#include "MltConsumer.h" -#include "MltDeque.h" -#include "MltEvent.h" -#include "MltFactory.h" -#include "MltField.h" -#include "MltFilter.h" -#include "MltFilteredConsumer.h" -#include "MltFrame.h" -#include "MltGeometry.h" -#ifndef WIN32 -#include "MltMiracle.h" -#endif -#include "MltMultitrack.h" -#include "MltParser.h" -#include "MltPlaylist.h" -#include "MltProducer.h" -#include "MltProfile.h" -#include "MltProperties.h" -#include "MltPushConsumer.h" -#include "MltRepository.h" -#ifndef WIN32 -#include "MltResponse.h" -#endif -#include "MltService.h" -#include "MltTokeniser.h" -#include "MltTractor.h" -#include "MltTransition.h" - -#endif diff --git a/mlt++/src/MltConsumer.cpp b/mlt++/src/MltConsumer.cpp deleted file mode 100644 index 1b5c4df..0000000 --- a/mlt++/src/MltConsumer.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/** - * MltConsumer.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include "MltConsumer.h" -#include "MltEvent.h" -#include "MltProfile.h" -using namespace Mlt; - -Consumer::Consumer( ) : - instance( NULL ) -{ - instance = mlt_factory_consumer( NULL, NULL, NULL ); -} - -Consumer::Consumer( Profile& profile ) : - instance( NULL ) -{ - instance = mlt_factory_consumer( profile.get_profile(), NULL, NULL ); -} - -Consumer::Consumer( Profile& profile, const char *id, const char *arg ) : - instance( NULL ) -{ - if ( id == NULL || arg != NULL ) - { - instance = mlt_factory_consumer( profile.get_profile(), id, arg ); - } - else - { - if ( strchr( id, ':' ) ) - { - char *temp = strdup( id ); - char *arg = strchr( temp, ':' ) + 1; - *( arg - 1 ) = '\0'; - instance = mlt_factory_consumer( profile.get_profile(), temp, arg ); - free( temp ); - } - else - { - instance = mlt_factory_consumer( profile.get_profile(), id, NULL ); - } - } -} - -Consumer::Consumer( Service &consumer ) : - instance( NULL ) -{ - if ( consumer.type( ) == consumer_type ) - { - instance = ( mlt_consumer )consumer.get_service( ); - inc_ref( ); - } -} - -Consumer::Consumer( Consumer &consumer ) : - Mlt::Service( consumer ), - instance( consumer.get_consumer( ) ) -{ - inc_ref( ); -} - -Consumer::Consumer( mlt_consumer consumer ) : - instance( consumer ) -{ - inc_ref( ); -} - -Consumer::~Consumer( ) -{ - mlt_consumer_close( instance ); -} - -mlt_consumer Consumer::get_consumer( ) -{ - return instance; -} - -mlt_service Consumer::get_service( ) -{ - return mlt_consumer_service( get_consumer( ) ); -} - -int Consumer::connect( Service &service ) -{ - return connect_producer( service ); -} - -int Consumer::start( ) -{ - return mlt_consumer_start( get_consumer( ) ); -} - -void Consumer::purge( ) -{ - mlt_consumer_purge( get_consumer( ) ); -} - -int Consumer::stop( ) -{ - return mlt_consumer_stop( get_consumer( ) ); -} - -bool Consumer::is_stopped( ) -{ - return mlt_consumer_is_stopped( get_consumer( ) ) != 0; -} - -int Consumer::run( ) -{ - int ret = start( ); - if ( !is_stopped( ) ) - { - Event *e = setup_wait_for( "consumer-stopped" ); - wait_for( e ); - delete e; - } - return ret; -} diff --git a/mlt++/src/MltConsumer.h b/mlt++/src/MltConsumer.h deleted file mode 100644 index 04948e8..0000000 --- a/mlt++/src/MltConsumer.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * MltConsumer.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_CONSUMER_H_ -#define _MLTPP_CONSUMER_H_ - -#include "config.h" - -#include - -#include "MltService.h" - -namespace Mlt -{ - class Service; - class Profile; - - class MLTPP_DECLSPEC Consumer : public Service - { - private: - mlt_consumer instance; - public: - Consumer( ); - Consumer( Profile& profile ); - Consumer( Profile& profile, const char *id , const char *service = NULL ); - Consumer( Service &consumer ); - Consumer( Consumer &consumer ); - Consumer( mlt_consumer consumer ); - virtual ~Consumer( ); - virtual mlt_consumer get_consumer( ); - mlt_service get_service( ); - virtual int connect( Service &service ); - int run( ); - int start( ); - void purge( ); - int stop( ); - bool is_stopped( ); - }; -} - -#endif diff --git a/mlt++/src/MltDeque.cpp b/mlt++/src/MltDeque.cpp deleted file mode 100644 index 8cd70e0..0000000 --- a/mlt++/src/MltDeque.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/** - * MltDeque.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltDeque.h" -using namespace Mlt; - -Deque::Deque( ) -{ - deque = mlt_deque_init( ); -} - -Deque::~Deque( ) -{ - mlt_deque_close( deque ); -} - -int Deque::count( ) -{ - return mlt_deque_count( deque ); -} - -int Deque::push_back( void *item ) -{ - return mlt_deque_push_back( deque, item ); -} - -void *Deque::pop_back( ) -{ - return mlt_deque_pop_back( deque ); -} - -int Deque::push_front( void *item ) -{ - return mlt_deque_push_front( deque, item ); -} - -void *Deque::pop_front( ) -{ - return mlt_deque_pop_front( deque ); -} - -void *Deque::peek_back( ) -{ - return mlt_deque_peek_back( deque ); -} - -void *Deque::peek_front( ) -{ - return mlt_deque_peek_front( deque ); -} - diff --git a/mlt++/src/MltDeque.h b/mlt++/src/MltDeque.h deleted file mode 100644 index 155bfd6..0000000 --- a/mlt++/src/MltDeque.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * MltDeque.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_DEQUE_H -#define _MLTPP_DEQUE_H - -#include "config.h" - -#include - -namespace Mlt -{ - class MLTPP_DECLSPEC Deque - { - private: - mlt_deque deque; - public: - Deque( ); - ~Deque( ); - int count( ); - int push_back( void *item ); - void *pop_back( ); - int push_front( void *item ); - void *pop_front( ); - void *peek_back( ); - void *peek_front( ); - }; -} - -#endif diff --git a/mlt++/src/MltEvent.cpp b/mlt++/src/MltEvent.cpp deleted file mode 100644 index d1e6c5e..0000000 --- a/mlt++/src/MltEvent.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * MltEvent.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltEvent.h" -using namespace Mlt; - - -Event::Event( mlt_event event ) : - instance( event ) -{ - mlt_event_inc_ref( instance ); -} - -Event::Event( Event &event ) : - instance( event.get_event( ) ) -{ - mlt_event_inc_ref( instance ); -} - -Event::~Event( ) -{ - mlt_event_close( instance ); -} - -mlt_event Event::get_event( ) -{ - return instance; -} - -bool Event::is_valid( ) -{ - return instance != NULL; -} - -void Event::block( ) -{ - mlt_event_block( get_event( ) ); -} - -void Event::unblock( ) -{ - mlt_event_unblock( get_event( ) ); -} - diff --git a/mlt++/src/MltEvent.h b/mlt++/src/MltEvent.h deleted file mode 100644 index 92b3917..0000000 --- a/mlt++/src/MltEvent.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * MltEvent.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_EVENT_H_ -#define _MLTPP_EVENT_H_ - -#include "config.h" - -#include - -namespace Mlt -{ - class MLTPP_DECLSPEC Event - { - private: - mlt_event instance; - public: - Event( mlt_event ); - Event( Event & ); - ~Event( ); - mlt_event get_event( ); - bool is_valid( ); - void block( ); - void unblock( ); - }; -} - -#endif - diff --git a/mlt++/src/MltFactory.cpp b/mlt++/src/MltFactory.cpp deleted file mode 100644 index d5815a4..0000000 --- a/mlt++/src/MltFactory.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/** - * MltFactory.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Copyright (C) 2008 Dan Dennedy - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltFactory.h" -#include "MltProducer.h" -#include "MltFilter.h" -#include "MltTransition.h" -#include "MltConsumer.h" -#include "MltRepository.h" -using namespace Mlt; - -Repository *Factory::init( const char *directory ) -{ - return new Repository( mlt_factory_init( directory ) ); -} - -Properties *Factory::event_object( ) -{ - return new Properties( mlt_factory_event_object( ) ); -} - -Producer *Factory::producer( Profile& profile, char *id, char *arg ) -{ - return new Producer( profile, id, arg ); -} - -Filter *Factory::filter( Profile& profile, char *id, char *arg ) -{ - return new Filter( profile, id, arg ); -} - -Transition *Factory::transition( Profile& profile, char *id, char *arg ) -{ - return new Transition( profile, id, arg ); -} - -Consumer *Factory::consumer( Profile& profile, char *id, char *arg ) -{ - return new Consumer( profile, id, arg ); -} - -#ifdef WIN32 -char *Factory::getenv( const char *name ) -{ - return mlt_getenv( name ); -} - -int Factory::setenv( const char *name, const char *value ) -{ - return mlt_setenv( name, value ); -} -#endif - -void Factory::close( ) -{ - mlt_factory_close( ); -} - - diff --git a/mlt++/src/MltFactory.h b/mlt++/src/MltFactory.h deleted file mode 100644 index aeec588..0000000 --- a/mlt++/src/MltFactory.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * MltFactory.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Copyright (C) 2008 Dan Dennedy - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_FACTORY_H_ -#define _MLTPP_FACTORY_H_ - -#include "config.h" - -#ifdef SWIG -#define MLTPP_DECLSPEC -#endif - -#include - -namespace Mlt -{ - class Properties; - class Producer; - class Filter; - class Transition; - class Consumer; - class Profile; - class Repository; - - class MLTPP_DECLSPEC Factory - { - public: - static Repository *init( const char *directory = NULL ); - static Properties *event_object( ); - static Producer *producer( Profile& profile, char *id, char *arg = NULL ); - static Filter *filter( Profile& profile, char *id, char *arg = NULL ); - static Transition *transition( Profile& profile, char *id, char *arg = NULL ); - static Consumer *consumer( Profile& profile, char *id, char *arg = NULL ); -#ifdef WIN32 - static char *getenv( const char * ); - static int setenv( const char *, const char * ); -#endif - static void close( ); - }; -} - -#endif diff --git a/mlt++/src/MltField.cpp b/mlt++/src/MltField.cpp deleted file mode 100644 index 8d89c83..0000000 --- a/mlt++/src/MltField.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/** - * MltField.cpp - Field wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltField.h" -#include "MltFilter.h" -#include "MltTransition.h" -using namespace Mlt; - -Field::Field( mlt_field field ) : - instance( field ) -{ - inc_ref( ); -} - -Field::Field( Field &field ) : - Mlt::Service( field ), - instance( field.get_field( ) ) -{ - inc_ref( ); -} - -Field::~Field( ) -{ - mlt_field_close( instance ); -} - -mlt_field Field::get_field( ) -{ - return instance; -} - -mlt_service Field::get_service( ) -{ - return mlt_field_service( get_field( ) ); -} - -int Field::plant_filter( Filter &filter, int track ) -{ - return mlt_field_plant_filter( get_field( ), filter.get_filter( ), track ); -} - -int Field::plant_transition( Transition &transition, int a_track, int b_track ) -{ - return mlt_field_plant_transition( get_field( ), transition.get_transition( ), a_track, b_track ); -} - - diff --git a/mlt++/src/MltField.h b/mlt++/src/MltField.h deleted file mode 100644 index 06e2d46..0000000 --- a/mlt++/src/MltField.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * MltField.h - Field wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_FIELD_H_ -#define _MLTPP_FIELD_H_ - -#include "config.h" - -#include - -#include "MltService.h" - -namespace Mlt -{ - class Service; - class Filter; - class Transition; - - class MLTPP_DECLSPEC Field : public Service - { - private: - mlt_field instance; - public: - Field( mlt_field field ); - Field( Field &field ); - virtual ~Field( ); - mlt_field get_field( ); - mlt_service get_service( ); - int plant_filter( Filter &filter, int track = 0 ); - int plant_transition( Transition &transition, int a_track = 0, int b_track = 1 ); - }; -} - -#endif - diff --git a/mlt++/src/MltFilter.cpp b/mlt++/src/MltFilter.cpp deleted file mode 100644 index 6fbc93a..0000000 --- a/mlt++/src/MltFilter.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/** - * MltFilter.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include "MltFilter.h" -#include "MltProfile.h" -using namespace Mlt; - -Filter::Filter( Profile& profile, const char *id, const char *arg ) : - instance( NULL ) -{ - if ( arg != NULL ) - { - instance = mlt_factory_filter( profile.get_profile(), id, arg ); - } - else - { - if ( strchr( id, ':' ) ) - { - char *temp = strdup( id ); - char *arg = strchr( temp, ':' ) + 1; - *( arg - 1 ) = '\0'; - instance = mlt_factory_filter( profile.get_profile(), temp, arg ); - free( temp ); - } - else - { - instance = mlt_factory_filter( profile.get_profile(), id, NULL ); - } - } -} - -Filter::Filter( Service &filter ) : - instance( NULL ) -{ - if ( filter.type( ) == filter_type ) - { - instance = ( mlt_filter )filter.get_service( ); - inc_ref( ); - } -} - -Filter::Filter( Filter &filter ) : - Mlt::Service( filter ), - instance( filter.get_filter( ) ) -{ - inc_ref( ); -} - -Filter::Filter( mlt_filter filter ) : - instance( filter ) -{ - inc_ref( ); -} - -Filter::~Filter( ) -{ - mlt_filter_close( instance ); -} - -mlt_filter Filter::get_filter( ) -{ - return instance; -} - -mlt_service Filter::get_service( ) -{ - return mlt_filter_service( get_filter( ) ); -} - -int Filter::connect( Service &service, int index ) -{ - return mlt_filter_connect( get_filter( ), service.get_service( ), index ); -} - -void Filter::set_in_and_out( int in, int out ) -{ - mlt_filter_set_in_and_out( get_filter( ), in, out ); -} - -int Filter::get_in( ) -{ - return mlt_filter_get_in( get_filter( ) ); -} - -int Filter::get_out( ) -{ - return mlt_filter_get_out( get_filter( ) ); -} - -int Filter::get_track( ) -{ - return mlt_filter_get_track( get_filter( ) ); -} - diff --git a/mlt++/src/MltFilter.h b/mlt++/src/MltFilter.h deleted file mode 100644 index bba1ee2..0000000 --- a/mlt++/src/MltFilter.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * MltFilter.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_FILTER_H_ -#define _MLTPP_FILTER_H_ - -#include "config.h" - -#include - -#include "MltService.h" - -namespace Mlt -{ - class Service; - class Profile; - - class MLTPP_DECLSPEC Filter : public Service - { - private: - mlt_filter instance; - public: - Filter( Profile& profile, const char *id, const char *service = NULL ); - Filter( Service &filter ); - Filter( Filter &filter ); - Filter( mlt_filter filter ); - virtual ~Filter( ); - virtual mlt_filter get_filter( ); - mlt_service get_service( ); - int connect( Service &service, int index = 0 ); - void set_in_and_out( int in, int out ); - int get_in( ); - int get_out( ); - int get_track( ); - }; -} - -#endif diff --git a/mlt++/src/MltFilteredConsumer.cpp b/mlt++/src/MltFilteredConsumer.cpp deleted file mode 100644 index 73ee474..0000000 --- a/mlt++/src/MltFilteredConsumer.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/** - * MltFilteredConsumer.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltFilteredConsumer.h" -using namespace Mlt; - -FilteredConsumer::FilteredConsumer( Profile& profile, char *id, char *arg ) : - Consumer( profile, id, arg ) -{ - // Create a reference to the first service - first = new Service( *this ); -} - -FilteredConsumer::FilteredConsumer( Consumer &consumer ) : - Consumer( consumer ) -{ - // Create a reference to the first service - first = new Service( *this ); -} - -FilteredConsumer::~FilteredConsumer( ) -{ - // Delete the reference to the first service - delete first; -} - -int FilteredConsumer::connect( Service &service ) -{ - // All producers must connect to the first service, hence the use of the virtual here - return first->connect_producer( service ); -} - -int FilteredConsumer::attach( Filter &filter ) -{ - int error = 0; - if ( filter.is_valid( ) ) - { - Service *producer = first->producer( ); - error = filter.connect( *producer ); - if ( error == 0 ) - { - first->connect_producer( filter ); - delete first; - first = new Service( filter ); - } - delete producer; - } - else - { - error = 1; - } - return error; -} - -int FilteredConsumer::last( Filter &filter ) -{ - int error = 0; - if ( filter.is_valid( ) ) - { - Service *producer = this->producer( ); - error = filter.connect( *producer ); - if ( error == 0 ) - connect_producer( filter ); - delete producer; - } - else - { - error = 1; - } - return error; -} - -int FilteredConsumer::detach( Filter &filter ) -{ - if ( filter.is_valid( ) ) - { - Service *it = new Service( *first ); - while ( it->is_valid( ) && it->get_service( ) != filter.get_service( ) ) - { - Service *consumer = it->consumer( ); - delete it; - it = consumer; - } - if ( it->get_service( ) == filter.get_service( ) ) - { - Service *producer = it->producer( ); - Service *consumer = it->consumer( ); - consumer->connect_producer( *producer ); - Service dummy( NULL ); - it->connect_producer( dummy ); - if ( first->get_service( ) == it->get_service( ) ) - { - delete first; - first = new Service( *consumer ); - } - } - delete it; - } - return 0; -} - diff --git a/mlt++/src/MltFilteredConsumer.h b/mlt++/src/MltFilteredConsumer.h deleted file mode 100644 index 21427ec..0000000 --- a/mlt++/src/MltFilteredConsumer.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * MltFilteredConsumer.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_FILTERED_CONSUMER_H_ -#define _MLTPP_FILTERED_CONSUMER_H_ - -#include "config.h" - -#include "MltConsumer.h" -#include "MltFilter.h" -#include "MltService.h" - -namespace Mlt -{ - class Consumer; - class Service; - class Filter; - class Profile; - - class MLTPP_DECLSPEC FilteredConsumer : public Consumer - { - private: - Service *first; - public: - FilteredConsumer( Profile& profile, char *id, char *arg = NULL ); - FilteredConsumer( Consumer &consumer ); - virtual ~FilteredConsumer( ); - int connect( Service &service ); - int attach( Filter &filter ); - int last( Filter &filter ); - int detach( Filter &filter ); - }; -} - -#endif - diff --git a/mlt++/src/MltFilteredProducer.cpp b/mlt++/src/MltFilteredProducer.cpp deleted file mode 100644 index 33d8a81..0000000 --- a/mlt++/src/MltFilteredProducer.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/** - * MltFilteredProducer.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltFilteredProducer.h" -using namespace Mlt; - -FilteredProducer::FilteredProducer( Profile& profile, char *id, char *arg ) : - Producer( profile, id, arg ) -{ - // Create a reference to the last service - last = new Service( *this ); -} - -FilteredProducer::~FilteredProducer( ) -{ - // Delete the reference to the last service - delete last; -} - -int FilteredProducer::attach( Filter &filter ) -{ - int error = 0; - if ( filter.is_valid( ) ) - { - Service *consumer = last->consumer( ); - filter.connect_producer( *last ); - if ( consumer->is_valid( ) ) - consumer->connect_producer( filter ); - delete consumer; - delete last; - last = new Service( filter ); - } - else - { - error = 1; - } - return error; -} - -int FilteredProducer::detach( Filter &filter ) -{ - if ( filter.is_valid( ) ) - { - Service *it = new Service( *last ); - while ( it->is_valid( ) && it->get_service( ) != filter.get_service( ) ) - { - Service *producer = it->producer( ); - delete it; - it = producer; - } - if ( it->get_service( ) == filter.get_service( ) ) - { - Service *producer = it->producer( ); - Service *consumer = it->consumer( ); - if ( consumer->is_valid( ) ) - consumer->connect_producer( *producer ); - Producer dummy( "colour" ); - dummy.connect_producer( *it ); - if ( last->get_service( ) == it->get_service( ) ) - { - delete last; - last = new Service( *producer ); - } - } - delete it; - } - return 0; -} - diff --git a/mlt++/src/MltFilteredProducer.h b/mlt++/src/MltFilteredProducer.h deleted file mode 100644 index 943f620..0000000 --- a/mlt++/src/MltFilteredProducer.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * MltFilteredProducer.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_FILTERED_PRODUCER_H_ -#define _MLTPP_FILTERED_PRODUCER_H_ - -#include "config.h" - -#include "MltProducer.h" -#include "MltFilter.h" -#include "MltService.h" - -namespace Mlt -{ - class Producer; - class Service; - class Filter; - class Profile; - - class MLTPP_DECLSPEC FilteredProducer : public Producer - { - private: - Service *last; - public: - FilteredProducer( Profile* profile, char *id, char *arg = NULL ); - virtual ~FilteredProducer( ); - int attach( Filter &filter ); - int detach( Filter &filter ); - }; -} - -#endif - diff --git a/mlt++/src/MltFrame.cpp b/mlt++/src/MltFrame.cpp deleted file mode 100644 index 643f419..0000000 --- a/mlt++/src/MltFrame.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/** - * MltFrame.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltFrame.h" -#include "MltProducer.h" -using namespace Mlt; - -Frame::Frame( mlt_frame frame ) : - instance( frame ) -{ - inc_ref( ); -} - -Frame::Frame( Frame &frame ) : - Mlt::Properties( frame ), - instance( frame.get_frame( ) ) -{ - inc_ref( ); -} - -Frame::~Frame( ) -{ - mlt_frame_close( instance ); -} - -mlt_frame Frame::get_frame( ) -{ - return instance; -} - -mlt_properties Frame::get_properties( ) -{ - return mlt_frame_properties( get_frame( ) ); -} - -uint8_t *Frame::get_image( mlt_image_format &format, int &w, int &h, int writable ) -{ - uint8_t *image = NULL; - if ( get_double( "consumer_aspect_ratio" ) == 0.0 ) - set( "consumer_aspect_ratio", 1.0 ); - mlt_frame_get_image( get_frame( ), &image, &format, &w, &h, writable ); - set( "format", format ); - set( "writable", writable ); - return image; -} - -unsigned char *Frame::fetch_image( mlt_image_format f, int w, int h, int writable ) -{ - uint8_t *image = NULL; - if ( get_double( "consumer_aspect_ratio" ) == 0.0 ) - set( "consumer_aspect_ratio", 1.0 ); - mlt_frame_get_image( get_frame( ), &image, &f, &w, &h, writable ); - set( "format", f ); - set( "writable", writable ); - return image; -} - -int16_t *Frame::get_audio( mlt_audio_format &format, int &frequency, int &channels, int &samples ) -{ - int16_t *audio = NULL; - mlt_frame_get_audio( get_frame( ), &audio, &format, &frequency, &channels, &samples ); - return audio; -} - -unsigned char *Frame::get_waveform( int w, int h ) -{ - return mlt_frame_get_waveform( get_frame( ), w, h ); -} - -Producer *Frame::get_original_producer( ) -{ - return new Producer( mlt_frame_get_original_producer( get_frame( ) ) ); -} diff --git a/mlt++/src/MltFrame.h b/mlt++/src/MltFrame.h deleted file mode 100644 index 9d564ab..0000000 --- a/mlt++/src/MltFrame.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * MltFilter.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_FRAME_H_ -#define _MLTPP_FRAME_H_ - -#include "config.h" - -#include -#include "MltProperties.h" - -namespace Mlt -{ - class Properties; - class Producer; - - class MLTPP_DECLSPEC Frame : public Properties - { - private: - mlt_frame instance; - public: - Frame( mlt_frame frame ); - Frame( Frame &frame ); - virtual ~Frame( ); - virtual mlt_frame get_frame( ); - mlt_properties get_properties( ); - uint8_t *get_image( mlt_image_format &format, int &w, int &h, int writable = 0 ); - unsigned char *fetch_image( mlt_image_format format, int w, int h, int writable = 0 ); - int16_t *get_audio( mlt_audio_format &format, int &frequency, int &channels, int &samples ); - unsigned char *get_waveform( int w, int h ); - Producer *get_original_producer( ); - }; -} - -#endif diff --git a/mlt++/src/MltGeometry.cpp b/mlt++/src/MltGeometry.cpp deleted file mode 100644 index 524a3d7..0000000 --- a/mlt++/src/MltGeometry.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/** - * MltGeometry.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include "MltGeometry.h" -using namespace Mlt; - -Geometry::Geometry( char *data, int length, int nw, int nh ) -{ - geometry = mlt_geometry_init( ); - parse( data, length, nw, nh ); -} - -Geometry::~Geometry( ) -{ - mlt_geometry_close( geometry ); -} - -int Geometry::parse( char *data, int length, int nw, int nh ) -{ - return mlt_geometry_parse( geometry, data, length, nw, nh ); -} - -// Fetch a geometry item for an absolute position -int Geometry::fetch( GeometryItem &item, float position ) -{ - return mlt_geometry_fetch( geometry, item.get_item( ), position ); -} - -int Geometry::fetch( GeometryItem *item, float position ) -{ - return mlt_geometry_fetch( geometry, item->get_item( ), position ); -} - -// Specify a geometry item at an absolute position -int Geometry::insert( GeometryItem &item ) -{ - return mlt_geometry_insert( geometry, item.get_item( ) ); -} - -int Geometry::insert( GeometryItem *item ) -{ - return mlt_geometry_insert( geometry, item->get_item( ) ); -} - -// Remove the key at the specified position -int Geometry::remove( int position ) -{ - return mlt_geometry_remove( geometry, position ); -} - -// Get the key at the position or the next following -int Geometry::next_key( GeometryItem &item, int position ) -{ - return mlt_geometry_next_key( geometry, item.get_item( ), position ); -} - -int Geometry::next_key( GeometryItem *item, int position ) -{ - return mlt_geometry_next_key( geometry, item->get_item( ), position ); -} - -int Geometry::prev_key( GeometryItem &item, int position ) -{ - return mlt_geometry_prev_key( geometry, item.get_item( ), position ); -} - -int Geometry::prev_key( GeometryItem *item, int position ) -{ - return mlt_geometry_prev_key( geometry, item->get_item( ), position ); -} - -// Serialise the current geometry -char *Geometry::serialise( int in, int out ) -{ - return mlt_geometry_serialise_cut( geometry, in, out ); -} - -char *Geometry::serialise( ) -{ - return mlt_geometry_serialise( geometry ); -} - diff --git a/mlt++/src/MltGeometry.h b/mlt++/src/MltGeometry.h deleted file mode 100644 index 0105467..0000000 --- a/mlt++/src/MltGeometry.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * MltGeometry.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_GEOMETRY_H -#define _MLTPP_GEOMETRY_H - -#include "config.h" - -#include - -namespace Mlt -{ - // Just for consistent naming purposes - class MLTPP_DECLSPEC GeometryItem - { - private: - struct mlt_geometry_item_s item; - public: - mlt_geometry_item get_item( ) { return &item; } - bool key( ) { return item.key != 0; } - int frame( ) { return item.frame; } - void frame( int value ) { item.frame = value; } - float x( ) { return item.x; } - void x( float value ) { item.f[0] = 1; item.x = value; } - float y( ) { return item.y; } - void y( float value ) { item.f[1] = 1; item.y = value; } - float w( ) { return item.w; } - void w( float value ) { item.f[2] = 1; item.w = value; } - float h( ) { return item.h; } - void h( float value ) { item.f[3] = 1; item.h = value; } - float mix( ) { return item.mix; } - void mix( float value ) { item.f[4] = 1; item.mix = value; } - }; - - class MLTPP_DECLSPEC Geometry - { - private: - mlt_geometry geometry; - public: - Geometry( char *data = NULL, int length = 0, int nw = -1, int nh = -1 ); - ~Geometry( ); - int parse( char *data, int length, int nw = -1, int nh = -1 ); - // Fetch a geometry item for an absolute position - int fetch( GeometryItem &item, float position ); - int fetch( GeometryItem *item, float position ); - // Specify a geometry item at an absolute position - int insert( GeometryItem &item ); - int insert( GeometryItem *item ); - // Remove the key at the specified position - int remove( int position ); - // Get the key at the position or the next following - int next_key( GeometryItem &item, int position ); - int next_key( GeometryItem *item, int position ); - int prev_key( GeometryItem &item, int position ); - int prev_key( GeometryItem *item, int position ); - // Serialise the current geometry - char *serialise( int in, int out ); - char *serialise( ); - }; -} - -#endif - diff --git a/mlt++/src/MltMultitrack.cpp b/mlt++/src/MltMultitrack.cpp deleted file mode 100644 index a0840f3..0000000 --- a/mlt++/src/MltMultitrack.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/** - * MltMultitrack.h - Multitrack wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltMultitrack.h" -#include "MltProducer.h" -using namespace Mlt; - -Multitrack::Multitrack( mlt_multitrack multitrack ) : - instance( multitrack ) -{ - inc_ref( ); -} - -Multitrack::Multitrack( Service &multitrack ) : - instance( NULL ) -{ - if ( multitrack.type( ) == multitrack_type ) - { - instance = ( mlt_multitrack )multitrack.get_service( ); - inc_ref( ); - } -} - -Multitrack::Multitrack( Multitrack &multitrack ) : - Mlt::Producer( multitrack ), - instance( multitrack.get_multitrack( ) ) -{ - inc_ref( ); -} - -Multitrack::~Multitrack( ) -{ - mlt_multitrack_close( instance ); -} - -mlt_multitrack Multitrack::get_multitrack( ) -{ - return instance; -} - -mlt_producer Multitrack::get_producer( ) -{ - return mlt_multitrack_producer( get_multitrack( ) ); -} - -int Multitrack::connect( Producer &producer, int index ) -{ - return mlt_multitrack_connect( get_multitrack( ), producer.get_producer( ), index ); -} - -int Multitrack::clip( mlt_whence whence, int index ) -{ - return mlt_multitrack_clip( get_multitrack( ), whence, index ); -} - -int Multitrack::count( ) -{ - return mlt_multitrack_count( get_multitrack( ) ); -} - -Producer *Multitrack::track( int index ) -{ - return new Producer( mlt_multitrack_track( get_multitrack( ), index ) ); -} - -void Multitrack::refresh( ) -{ - return mlt_multitrack_refresh( get_multitrack( ) ); -} diff --git a/mlt++/src/MltMultitrack.h b/mlt++/src/MltMultitrack.h deleted file mode 100644 index 75a49fa..0000000 --- a/mlt++/src/MltMultitrack.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * MltMultitrack.h - Multitrack wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_MULTITRACK_H_ -#define _MLTPP_MULTITRACK_H_ - -#include "config.h" - -#include - -#include "MltProducer.h" - -namespace Mlt -{ - class Service; - class Producer; - - class MLTPP_DECLSPEC Multitrack : public Producer - { - private: - mlt_multitrack instance; - public: - Multitrack( mlt_multitrack multitrack ); - Multitrack( Service &multitrack ); - Multitrack( Multitrack &multitrack ); - virtual ~Multitrack( ); - mlt_multitrack get_multitrack( ); - mlt_producer get_producer( ); - int connect( Producer &producer, int index ); - int clip( mlt_whence whence, int index ); - int count( ); - Producer *track( int index ); - void refresh( ); - }; -} - -#endif - diff --git a/mlt++/src/MltPlaylist.cpp b/mlt++/src/MltPlaylist.cpp deleted file mode 100644 index 1424594..0000000 --- a/mlt++/src/MltPlaylist.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/** - * MltPlaylist.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include "MltPlaylist.h" -#include "MltTransition.h" -using namespace Mlt; - -ClipInfo::ClipInfo( ) : - clip( 0 ), - producer( NULL ), - cut( NULL ), - start( 0 ), - resource( NULL ), - frame_in( 0 ), - frame_out( 0 ), - frame_count( 0 ), - length( 0 ), - fps( 0 ), - repeat( 0 ) -{ -} - -ClipInfo::ClipInfo( mlt_playlist_clip_info *info ) : - clip( info->clip ), - producer( new Producer( info->producer ) ), - cut( new Producer( info->cut ) ), - start( info->start ), - resource( info->resource? strdup( info->resource ) : 0 ), - frame_in( info->frame_in ), - frame_out( info->frame_out ), - frame_count( info->frame_count ), - length( info->length ), - fps( info->fps ), - repeat( info->repeat ) -{ -} - -ClipInfo::~ClipInfo( ) -{ - delete producer; - delete cut; - free( resource ); -} - -void ClipInfo::update( mlt_playlist_clip_info *info ) -{ - delete producer; - delete cut; - free( resource ); - clip = info->clip; - producer = new Producer( info->producer ); - cut = new Producer( info->cut ); - start = info->start; - resource = strdup( info->resource ); - frame_in = info->frame_in; - frame_out = info->frame_out; - frame_count = info->frame_count; - length = info->length; - fps = info->fps; - repeat = info->repeat; -} - -Playlist::Playlist( ) : - instance( NULL ) -{ - instance = mlt_playlist_init( ); -} - -Playlist::Playlist( Service &producer ) : - instance( NULL ) -{ - if ( producer.type( ) == playlist_type ) - { - instance = ( mlt_playlist )producer.get_service( ); - inc_ref( ); - } -} - -Playlist::Playlist( Playlist &playlist ) : - Mlt::Producer( playlist ), - instance( playlist.get_playlist( ) ) -{ - inc_ref( ); -} - -Playlist::Playlist( mlt_playlist playlist ) : - instance( playlist ) -{ - inc_ref( ); -} - -Playlist::~Playlist( ) -{ - mlt_playlist_close( instance ); -} - -mlt_playlist Playlist::get_playlist( ) -{ - return instance; -} - -mlt_producer Playlist::get_producer( ) -{ - return mlt_playlist_producer( get_playlist( ) ); -} - -int Playlist::count( ) -{ - return mlt_playlist_count( get_playlist( ) ); -} - -int Playlist::clear( ) -{ - return mlt_playlist_clear( get_playlist( ) ); -} - -int Playlist::append( Producer &producer, int in, int out ) -{ - return mlt_playlist_append_io( get_playlist( ), producer.get_producer( ), in, out ); -} - -int Playlist::blank( int length ) -{ - return mlt_playlist_blank( get_playlist( ), length ); -} - -int Playlist::clip( mlt_whence whence, int index ) -{ - return mlt_playlist_clip( get_playlist( ), whence, index ); -} - -int Playlist::current_clip( ) -{ - return mlt_playlist_current_clip( get_playlist( ) ); -} - -Producer *Playlist::current( ) -{ - return new Producer( mlt_playlist_current( get_playlist( ) ) ); -} - -ClipInfo *Playlist::clip_info( int index, ClipInfo *info ) -{ - mlt_playlist_clip_info clip_info; - if ( mlt_playlist_get_clip_info( get_playlist( ), &clip_info, index ) ) - return NULL; - if ( info == NULL ) - return new ClipInfo( &clip_info ); - info->update( &clip_info ); - return info; -} - -void Playlist::delete_clip_info( ClipInfo *info ) -{ - delete info; -} - -int Playlist::insert( Producer &producer, int where, int in, int out ) -{ - return mlt_playlist_insert( get_playlist( ), producer.get_producer( ), where, in, out ); -} - -int Playlist::remove( int where ) -{ - return mlt_playlist_remove( get_playlist( ), where ); -} - -int Playlist::move( int from, int to ) -{ - return mlt_playlist_move( get_playlist( ), from, to ); -} - -int Playlist::resize_clip( int clip, int in, int out ) -{ - return mlt_playlist_resize_clip( get_playlist( ), clip, in, out ); -} - -int Playlist::split( int clip, int position ) -{ - return mlt_playlist_split( get_playlist( ), clip, position ); -} - -int Playlist::split_at( int position, bool left ) -{ - return mlt_playlist_split_at( get_playlist( ), position, left ); -} - -int Playlist::join( int clip, int count, int merge ) -{ - return mlt_playlist_join( get_playlist( ), clip, count, merge ); -} - -int Playlist::mix( int clip, int length, Transition *transition ) -{ - return mlt_playlist_mix( get_playlist( ), clip, length, transition == NULL ? NULL : transition->get_transition( ) ); -} - -int Playlist::mix_add( int clip, Transition *transition ) -{ - return mlt_playlist_mix_add( get_playlist( ), clip, transition == NULL ? NULL : transition->get_transition( ) ); -} - -int Playlist::repeat( int clip, int count ) -{ - return mlt_playlist_repeat_clip( get_playlist( ), clip, count ); -} - -Producer *Playlist::get_clip( int clip ) -{ - mlt_producer producer = mlt_playlist_get_clip( get_playlist( ), clip ); - return producer != NULL ? new Producer( producer ) : NULL; -} - -Producer *Playlist::get_clip_at( int position ) -{ - mlt_producer producer = mlt_playlist_get_clip_at( get_playlist( ), position ); - return producer != NULL ? new Producer( producer ) : NULL; -} - -int Playlist::get_clip_index_at( int position ) -{ - return mlt_playlist_get_clip_index_at( get_playlist( ), position ); -} - -bool Playlist::is_mix( int clip ) -{ - return mlt_playlist_clip_is_mix( get_playlist( ), clip ) != 0; -} - -bool Playlist::is_blank( int clip ) -{ - return mlt_playlist_is_blank( get_playlist( ), clip ) != 0; -} - -bool Playlist::is_blank_at( int position ) -{ - return mlt_playlist_is_blank_at( get_playlist( ), position ) != 0; -} - -Producer *Playlist::replace_with_blank( int clip ) -{ - mlt_producer producer = mlt_playlist_replace_with_blank( get_playlist( ), clip ); - Producer *object = producer != NULL ? new Producer( producer ) : NULL; - mlt_producer_close( producer ); - return object; -} - -void Playlist::consolidate_blanks( int keep_length ) -{ - return mlt_playlist_consolidate_blanks( get_playlist( ), keep_length ); -} - -void Playlist::insert_blank( int clip, int length ) -{ - mlt_playlist_insert_blank( get_playlist( ), clip, length ); -} - -void Playlist::pad_blanks( int position, int length, int find ) -{ - mlt_playlist_pad_blanks( get_playlist( ), position, length, find ); -} - -int Playlist::insert_at( int position, Producer *producer, int mode ) -{ - return mlt_playlist_insert_at( get_playlist( ), position, producer->get_producer( ), mode ); -} - -int Playlist::insert_at( int position, Producer &producer, int mode ) -{ - return mlt_playlist_insert_at( get_playlist( ), position, producer.get_producer( ), mode ); -} - -int Playlist::clip_start( int clip ) -{ - return mlt_playlist_clip_start( get_playlist( ), clip ); -} - -int Playlist::blanks_from( int clip, int bounded ) -{ - return mlt_playlist_blanks_from( get_playlist( ), clip, bounded ); -} - -int Playlist::clip_length( int clip ) -{ - return mlt_playlist_clip_length( get_playlist( ), clip ); -} - -int Playlist::remove_region( int position, int length ) -{ - return mlt_playlist_remove_region( get_playlist( ), position, length ); -} - -int Playlist::move_region( int position, int length, int new_position ) -{ - return mlt_playlist_move_region( get_playlist( ), position, length, new_position ); -} - diff --git a/mlt++/src/MltPlaylist.h b/mlt++/src/MltPlaylist.h deleted file mode 100644 index 0cd17b0..0000000 --- a/mlt++/src/MltPlaylist.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * MltPlaylist.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_PLAYLIST_H_ -#define _MLTPP_PLAYLIST_H_ - -#include "config.h" - -#include - -#include "MltProducer.h" - -namespace Mlt -{ - class Producer; - class Service; - class Playlist; - class Transition; - - class MLTPP_DECLSPEC ClipInfo - { - public: - ClipInfo( ); - ClipInfo( mlt_playlist_clip_info *info ); - ~ClipInfo( ); - void update( mlt_playlist_clip_info *info ); - int clip; - Producer *producer; - Producer *cut; - int start; - char *resource; - int frame_in; - int frame_out; - int frame_count; - int length; - float fps; - int repeat; - }; - - class MLTPP_DECLSPEC Playlist : public Producer - { - private: - mlt_playlist instance; - public: - Playlist( ); - Playlist( Service &playlist ); - Playlist( Playlist &playlist ); - Playlist( mlt_playlist playlist ); - virtual ~Playlist( ); - virtual mlt_playlist get_playlist( ); - mlt_producer get_producer( ); - int count( ); - int clear( ); - int append( Producer &producer, int in = -1, int out = -1 ); - int blank( int length ); - int clip( mlt_whence whence, int index ); - int current_clip( ); - Producer *current( ); - ClipInfo *clip_info( int index, ClipInfo *info = NULL ); - static void delete_clip_info( ClipInfo *info ); - int insert( Producer &producer, int where, int in = -1, int out = -1 ); - int remove( int where ); - int move( int from, int to ); - int resize_clip( int clip, int in, int out ); - int split( int clip, int position ); - int split_at( int position, bool left = true ); - int join( int clip, int count = 1, int merge = 1 ); - int mix( int clip, int length, Transition *transition = NULL ); - int mix_add( int clip, Transition *transition ); - int repeat( int clip, int count ); - Producer *get_clip( int clip ); - Producer *get_clip_at( int position ); - int get_clip_index_at( int position ); - bool is_mix( int clip ); - bool is_blank( int clip ); - bool is_blank_at( int position ); - void consolidate_blanks( int keep_length = 0 ); - Producer *replace_with_blank( int clip ); - void insert_blank( int clip, int length ); - void pad_blanks( int position, int length, int find = 0 ); - int insert_at( int position, Producer *producer, int mode = 0 ); - int insert_at( int position, Producer &producer, int mode = 0 ); - int clip_start( int clip ); - int clip_length( int clip ); - int blanks_from( int clip, int bounded = 0 ); - int remove_region( int position, int length ); - int move_region( int position, int length, int new_position ); - }; -} - -#endif diff --git a/mlt++/src/MltProducer.cpp b/mlt++/src/MltProducer.cpp deleted file mode 100644 index 4302243..0000000 --- a/mlt++/src/MltProducer.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/** - * MltProducer.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltProducer.h" -#include "MltFilter.h" -#include "MltProfile.h" -using namespace Mlt; - -Producer::Producer( ) : - instance( NULL ), - parent_( NULL ) -{ -} - -Producer::Producer( Profile& profile, const char *id, const char *service ) : - instance( NULL ), - parent_( NULL ) -{ - if ( id != NULL && service != NULL ) - instance = mlt_factory_producer( profile.get_profile(), id, service ); - else - instance = mlt_factory_producer( profile.get_profile(), "fezzik", id != NULL ? id : service ); -} - -Producer::Producer( Service &producer ) : - instance( NULL ), - parent_( NULL ) -{ - mlt_service_type type = producer.type( ); - if ( type == producer_type || type == playlist_type || - type == tractor_type || type == multitrack_type ) - { - instance = ( mlt_producer )producer.get_service( ); - inc_ref( ); - } -} - -Producer::Producer( mlt_producer producer ) : - instance( producer ), - parent_( NULL ) -{ - inc_ref( ); -} - -Producer::Producer( Producer &producer ) : - Mlt::Service( producer ), - instance( producer.get_producer( ) ), - parent_( NULL ) -{ - inc_ref( ); -} - -Producer::Producer( Producer *producer ) : - instance( producer != NULL ? producer->get_producer( ) : NULL ), - parent_( NULL ) -{ - if ( is_valid( ) ) - inc_ref( ); -} - -Producer::~Producer( ) -{ - delete parent_; - mlt_producer_close( instance ); - instance = NULL; -} - -mlt_producer Producer::get_producer( ) -{ - return instance; -} - -mlt_producer Producer::get_parent( ) -{ - return get_producer( ) != NULL && mlt_producer_cut_parent( get_producer( ) ) != NULL ? mlt_producer_cut_parent( get_producer( ) ) : get_producer( ); -} - -Producer &Producer::parent( ) -{ - if ( is_cut( ) && parent_ == NULL ) - parent_ = new Producer( get_parent( ) ); - return parent_ == NULL ? *this : *parent_; -} - -mlt_service Producer::get_service( ) -{ - return mlt_producer_service( get_producer( ) ); -} - -int Producer::seek( int position ) -{ - return mlt_producer_seek( get_producer( ), position ); -} - -int Producer::position( ) -{ - return mlt_producer_position( get_producer( ) ); -} - -int Producer::frame( ) -{ - return mlt_producer_frame( get_producer( ) ); -} - -int Producer::set_speed( double speed ) -{ - return mlt_producer_set_speed( get_producer( ), speed ); -} - -double Producer::get_speed( ) -{ - return mlt_producer_get_speed( get_producer( ) ); -} - -double Producer::get_fps( ) -{ - return mlt_producer_get_fps( get_producer( ) ); -} - -int Producer::set_in_and_out( int in, int out ) -{ - return mlt_producer_set_in_and_out( get_producer( ), in, out ); -} - -int Producer::get_in( ) -{ - return mlt_producer_get_in( get_producer( ) ); -} - -int Producer::get_out( ) -{ - return mlt_producer_get_out( get_producer( ) ); -} - -int Producer::get_length( ) -{ - return mlt_producer_get_length( get_producer( ) ); -} - -int Producer::get_playtime( ) -{ - return mlt_producer_get_playtime( get_producer( ) ); -} - -Producer *Producer::cut( int in, int out ) -{ - mlt_producer producer = mlt_producer_cut( get_producer( ), in, out ); - Producer *result = new Producer( producer ); - mlt_producer_close( producer ); - return result; -} - -bool Producer::is_cut( ) -{ - return mlt_producer_is_cut( get_producer( ) ) != 0; -} - -bool Producer::is_blank( ) -{ - return mlt_producer_is_blank( get_producer( ) ) != 0; -} - -bool Producer::same_clip( Producer &that ) -{ - return mlt_producer_cut_parent( get_producer( ) ) == mlt_producer_cut_parent( that.get_producer( ) ); -} - -bool Producer::runs_into( Producer &that ) -{ - return same_clip( that ) && get_out( ) == ( that.get_in( ) - 1 ); -} - -void Producer::optimise( ) -{ - mlt_producer_optimise( get_producer( ) ); -} diff --git a/mlt++/src/MltProducer.h b/mlt++/src/MltProducer.h deleted file mode 100644 index 7b28e94..0000000 --- a/mlt++/src/MltProducer.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * MltProducer.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_PRODUCER_H_ -#define _MLTPP_PRODUCER_H_ - -#include "config.h" - -#include - -#include "MltService.h" - -namespace Mlt -{ - class Service; - class Filter; - class Profile; - class Frame; - - class MLTPP_DECLSPEC Producer : public Service - { - private: - mlt_producer instance; - Producer *parent_; - public: - Producer( ); - Producer( Profile& profile, const char *id, const char *service = NULL ); - Producer( Service &producer ); - Producer( mlt_producer producer ); - Producer( Producer &producer ); - Producer( Producer *producer ); - virtual ~Producer( ); - virtual mlt_producer get_producer( ); - Producer &parent( ); - mlt_producer get_parent( ); - mlt_service get_service( ); - int seek( int position ); - int position( ); - int frame( ); - int set_speed( double speed ); - double get_speed( ); - double get_fps( ); - int set_in_and_out( int in, int out ); - int get_in( ); - int get_out( ); - int get_length( ); - int get_playtime( ); - Producer *cut( int in = 0, int out = -1 ); - bool is_cut( ); - bool is_blank( ); - bool same_clip( Producer &that ); - bool runs_into( Producer &that ); - void optimise( ); - }; -} - -#endif diff --git a/mlt++/src/MltProfile.cpp b/mlt++/src/MltProfile.cpp deleted file mode 100644 index 0df73dc..0000000 --- a/mlt++/src/MltProfile.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/** - * MltProfile.cpp - MLT Wrapper - * Copyright (C) 2008 Dan Dennedy - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltProfile.h" -#include "MltProperties.h" -using namespace Mlt; - -Profile::Profile( ) : - instance( NULL ) -{ - instance = mlt_profile_init( NULL ); -} - -Profile::Profile( const char* name ) : - instance( NULL ) -{ - instance = mlt_profile_init( name ); -} - -Profile::Profile( Properties& properties ) : - instance( NULL ) -{ - instance = mlt_profile_load_properties( properties.get_properties() ); -} - -Profile::Profile( mlt_profile profile ) : - instance( profile ) -{ -} - -Profile::~Profile( ) -{ - if ( instance ) - mlt_profile_close( instance ); - instance = NULL; -} - -mlt_profile Profile::get_profile( ) const -{ - return instance; -} - -char* Profile::description() const -{ - return instance->description; -} - -int Profile::frame_rate_num() const -{ - return instance->frame_rate_num; -} - -int Profile::frame_rate_den() const -{ - return instance->frame_rate_den; -} - -double Profile::fps() const -{ - return mlt_profile_fps( instance ); -} - -int Profile::width() const -{ - return instance->width; -} - -int Profile::height() const -{ - return instance->height; -} - -bool Profile::progressive() const -{ - return instance->progressive; -} - -int Profile::sample_aspect_num() const -{ - return instance->sample_aspect_num; -} - -int Profile::sample_aspect_den() const -{ - return instance->sample_aspect_den; -} - -double Profile::sar() const -{ - return mlt_profile_sar( instance ); -} - -int Profile::display_aspect_num() const -{ - return instance->display_aspect_num; -} - -int Profile::display_aspect_den() const -{ - return instance->display_aspect_den; -} - -double Profile::dar() const -{ - return mlt_profile_dar( instance ); -} diff --git a/mlt++/src/MltProfile.h b/mlt++/src/MltProfile.h deleted file mode 100644 index 2a1f891..0000000 --- a/mlt++/src/MltProfile.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * MltProfile.h - MLT Wrapper - * Copyright (C) 2008 Dan Dennedy - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_PROFILE_H_ -#define _MLTPP_PROFILE_H_ - -#include "config.h" - -#ifdef SWIG -#define MLTPP_DECLSPEC -#endif - -#include - -namespace Mlt -{ - class Properties; - - class MLTPP_DECLSPEC Profile - { - private: - mlt_profile instance; - public: - Profile( ); - Profile( const char* name ); - Profile( Properties& properties ); - Profile( mlt_profile profile ); - ~Profile(); - - mlt_profile get_profile( ) const; - char* description() const; - int frame_rate_num() const; - int frame_rate_den() const; - double fps() const; - int width() const; - int height() const; - bool progressive() const; - int sample_aspect_num() const; - int sample_aspect_den() const; - double sar() const; - int display_aspect_num() const; - int display_aspect_den() const; - double dar() const; - }; -} - -#endif diff --git a/mlt++/src/MltProperties.cpp b/mlt++/src/MltProperties.cpp deleted file mode 100644 index 078d69f..0000000 --- a/mlt++/src/MltProperties.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/** - * MltProperties.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltProperties.h" -#include "MltEvent.h" -using namespace Mlt; - -Properties::Properties( ) : - instance( NULL ) -{ - instance = mlt_properties_new( ); -} - -Properties::Properties( bool /*dummy*/ ) : - instance( NULL ) -{ -} - -Properties::Properties( Properties &properties ) : - instance( properties.get_properties( ) ) -{ - inc_ref( ); -} - -Properties::Properties( mlt_properties properties ) : - instance( properties ) -{ - inc_ref( ); -} - -Properties::Properties( const char *file ) : - instance( NULL ) -{ - instance = mlt_properties_load( file ); -} - -Properties::~Properties( ) -{ - mlt_properties_close( instance ); -} - -mlt_properties Properties::get_properties( ) -{ - return instance; -} - -int Properties::inc_ref( ) -{ - return mlt_properties_inc_ref( get_properties( ) ); -} - -int Properties::dec_ref( ) -{ - return mlt_properties_dec_ref( get_properties( ) ); -} - -int Properties::ref_count( ) -{ - return mlt_properties_ref_count( get_properties( ) ); -} - -void Properties::block( void *object ) -{ - mlt_events_block( get_properties( ), object != NULL ? object : get_properties( ) ); -} - -void Properties::unblock( void *object ) -{ - mlt_events_unblock( get_properties( ), object != NULL ? object : get_properties( ) ); -} - -void Properties::fire_event( const char *event ) -{ - mlt_events_fire( get_properties( ), event, NULL ); -} - -bool Properties::is_valid( ) -{ - return get_properties( ) != NULL; -} - -int Properties::count( ) -{ - return mlt_properties_count( get_properties( ) ); -} - -char *Properties::get( const char *name ) -{ - return mlt_properties_get( get_properties( ), name ); -} - -int Properties::get_int( const char *name ) -{ - return mlt_properties_get_int( get_properties( ), name ); -} - -double Properties::get_double( const char *name ) -{ - return mlt_properties_get_double( get_properties( ), name ); -} - -void *Properties::get_data( const char *name, int &size ) -{ - return mlt_properties_get_data( get_properties( ), name, &size ); -} - -void *Properties::get_data( const char *name ) -{ - return mlt_properties_get_data( get_properties( ), name, NULL ); -} - -int Properties::set( const char *name, const char *value ) -{ - return mlt_properties_set( get_properties( ), name, value ); -} - -int Properties::set( const char *name, int value ) -{ - return mlt_properties_set_int( get_properties( ), name, value ); -} - -int Properties::set( const char *name, double value ) -{ - return mlt_properties_set_double( get_properties( ), name, value ); -} - -int Properties::set( const char *name, void *value, int size, mlt_destructor destructor, mlt_serialiser serialiser ) -{ - return mlt_properties_set_data( get_properties( ), name, value, size, destructor, serialiser ); -} - -int Properties::pass_values( Properties &that, const char *prefix ) -{ - return mlt_properties_pass( get_properties( ), that.get_properties( ), prefix ); -} - -int Properties::parse( const char *namevalue ) -{ - return mlt_properties_parse( get_properties( ), namevalue ); -} - -char *Properties::get_name( int index ) -{ - return mlt_properties_get_name( get_properties( ), index ); -} - -char *Properties::get( int index ) -{ - return mlt_properties_get_value( get_properties( ), index ); -} - -void *Properties::get_data( int index, int &size ) -{ - return mlt_properties_get_data_at( get_properties( ), index, &size ); -} - -void Properties::mirror( Properties &that ) -{ - mlt_properties_mirror( get_properties( ), that.get_properties( ) ); -} - -int Properties::inherit( Properties &that ) -{ - return mlt_properties_inherit( get_properties( ), that.get_properties( ) ); -} - -int Properties::rename( const char *source, const char *dest ) -{ - return mlt_properties_rename( get_properties( ), source, dest ); -} - -void Properties::dump( FILE *output ) -{ - mlt_properties_dump( get_properties( ), output ); -} - -void Properties::debug( const char *title, FILE *output ) -{ - mlt_properties_debug( get_properties( ), title, output ); -} - -void Properties::load( const char *file ) -{ - mlt_properties properties = mlt_properties_load( file ); - if ( properties != NULL ) - mlt_properties_pass( get_properties( ), properties, "" ); - mlt_properties_close( properties ); -} - -int Properties::save( const char *file ) -{ -#ifdef WIN32 - return mlt_properties_save( get_properties( ), file ); -#else - int error = 0; - FILE *f = fopen( file, "w" ); - if ( f != NULL ) - { - dump( f ); - fclose( f ); - } - else - { - error = 1; - } - return error; -#endif -} - -#if defined( __DARWIN__ ) && GCC_VERSION < 40000 - -Event *Properties::listen( const char *id, void *object, void (*listener)( ... ) ) -{ - mlt_event event = mlt_events_listen( get_properties( ), object, id, ( mlt_listener )listener ); - return new Event( event ); -} - -#else - -Event *Properties::listen( const char *id, void *object, mlt_listener listener ) -{ - mlt_event event = mlt_events_listen( get_properties( ), object, id, listener ); - return new Event( event ); -} - -#endif - -Event *Properties::setup_wait_for( const char *id ) -{ - return new Event( mlt_events_setup_wait_for( get_properties( ), id ) ); -} - -void Properties::delete_event( Event *event ) -{ - delete event; -} - -void Properties::wait_for( Event *event, bool destroy ) -{ - mlt_events_wait_for( get_properties( ), event->get_event( ) ); - if ( destroy ) - mlt_events_close_wait_for( get_properties( ), event->get_event( ) ); -} - diff --git a/mlt++/src/MltProperties.h b/mlt++/src/MltProperties.h deleted file mode 100644 index e236675..0000000 --- a/mlt++/src/MltProperties.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * MltProperties.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_PROPERTIES_H_ -#define _MLTPP_PROPERTIES_H_ - -#include "config.h" - -#include -#include - -namespace Mlt -{ - class Event; - - /** Abstract Properties class. - */ - - class MLTPP_DECLSPEC Properties - { - private: - mlt_properties instance; - public: - Properties( ); - Properties( bool dummy ); - Properties( Properties &properties ); - Properties( mlt_properties properties ); - Properties( const char *file ); - virtual ~Properties( ); - virtual mlt_properties get_properties( ); - int inc_ref( ); - int dec_ref( ); - int ref_count( ); - void block( void *object = NULL ); - void unblock( void *object = NULL ); - void fire_event( const char *event ); - bool is_valid( ); - int count( ); - char *get( const char *name ); - int get_int( const char *name ); - double get_double( const char *name ); - void *get_data( const char *name, int &size ); - void *get_data( const char *name ); - int set( const char *name, const char *value ); - int set( const char *name, int value ); - int set( const char *name, double value ); - int set( const char *name, void *value, int size, mlt_destructor destroy = NULL, mlt_serialiser serial = NULL ); - int pass_values( Properties &that, const char *prefix ); - int parse( const char *namevalue ); - char *get_name( int index ); - char *get( int index ); - void *get_data( int index, int &size ); - void mirror( Properties &that ); - int inherit( Properties &that ); - int rename( const char *source, const char *dest ); - void dump( FILE *output = stderr ); - void debug( const char *title = "Object", FILE *output = stderr ); - void load( const char *file ); - int save( const char *file ); - #if defined( __DARWIN__ ) && GCC_VERSION < 40000 - Event *listen( const char *id, void *object, void (*)( ... ) ); - #else - Event *listen( const char *id, void *object, mlt_listener ); - #endif - static void delete_event( Event * ); - Event *setup_wait_for( const char *id ); - void wait_for( Event *, bool destroy = true ); - }; -} - -#endif diff --git a/mlt++/src/MltPushConsumer.cpp b/mlt++/src/MltPushConsumer.cpp deleted file mode 100644 index d8465ba..0000000 --- a/mlt++/src/MltPushConsumer.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/** - * MltPushConsumer.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltPushConsumer.h" -#include "MltFilter.h" -using namespace Mlt; - -namespace Mlt -{ - class PushPrivate - { - public: - PushPrivate( ) - { - } - }; -} - -static void filter_destructor( void *arg ) -{ - Filter *filter = ( Filter * )arg; - delete filter; -} - -PushConsumer::PushConsumer( Profile& profile, char *id , char *service ) : - Consumer( profile, id, service ), - m_private( new PushPrivate( ) ) -{ - if ( is_valid( ) ) - { - // Set up push mode (known as put mode in mlt) - set( "real_time", 0 ); - set( "put_mode", 1 ); - set( "terminate_on_pause", 0 ); - set( "buffer", 0 ); - - // We might need resize and rescale filters so we'll create them now - // NB: Try to use the best rescaler available here - Filter *resize = new Filter( profile, "resize" ); - Filter *rescale = new Filter( profile, "mcrescale" ); - if ( !rescale->is_valid( ) ) - { - delete rescale; - rescale = new Filter( profile, "gtkrescale" ); - } - if ( !rescale->is_valid( ) ) - { - delete rescale; - rescale = new Filter( profile, "rescale" ); - } - - Filter *convert = new Filter( profile, "avcolour_space" ); - - set( "filter_convert", convert, 0, filter_destructor ); - set( "filter_resize", resize, 0, filter_destructor ); - set( "filter_rescale", rescale, 0, filter_destructor ); - } -} - -PushConsumer::~PushConsumer( ) -{ -} - -void PushConsumer::set_render( int width, int height, double aspect_ratio ) -{ - set( "render_width", width ); - set( "render_height", height ); - set( "render_aspect_ratio", aspect_ratio ); -} - -int PushConsumer::connect( Service &/*service*/ ) -{ - return -1; -} - -int PushConsumer::push( Frame *frame ) -{ - frame->inc_ref( ); - - // Here we have the option to process the frame at a render resolution (this will - // typically be PAL or NTSC) prior to scaling according to the consumers profile - // This is done to optimise quality, esp. with regard to compositing positions - if ( get_int( "render_width" ) ) - { - // Process the projects render resolution first - mlt_image_format format = mlt_image_yuv422; - int w = get_int( "render_width" ); - int h = get_int( "render_height" ); - frame->set( "consumer_aspect_ratio", get_double( "render_aspect_ratio" ) ); - frame->set( "consumer_deinterlace", get_int( "deinterlace" ) ); - frame->set( "deinterlace_method", get_int( "deinterlace_method" ) ); - frame->set( "rescale.interp", get( "rescale" ) ); - - // Render the frame - frame->get_image( format, w, h ); - - // Now set up the post image scaling - Filter *convert = ( Filter * )get_data( "filter_convert" ); - mlt_filter_process( convert->get_filter( ), frame->get_frame( ) ); - Filter *rescale = ( Filter * )get_data( "filter_rescale" ); - mlt_filter_process( rescale->get_filter( ), frame->get_frame( ) ); - Filter *resize = ( Filter * )get_data( "filter_resize" ); - mlt_filter_process( resize->get_filter( ), frame->get_frame( ) ); - } - - return mlt_consumer_put_frame( ( mlt_consumer )get_service( ), frame->get_frame( ) ); -} - -int PushConsumer::push( Frame &frame ) -{ - return push( &frame ); -} - -int PushConsumer::drain( ) -{ - return 0; -} - -// Convenience function - generates a frame with an image of a given size -Frame *PushConsumer::construct( int size ) -{ - mlt_frame f = mlt_frame_init( get_service() ); - Frame *frame = new Frame( f ); - uint8_t *buffer = ( uint8_t * )mlt_pool_alloc( size ); - frame->set( "image", buffer, size, mlt_pool_release ); - mlt_frame_close( f ); - return frame; -} - diff --git a/mlt++/src/MltPushConsumer.h b/mlt++/src/MltPushConsumer.h deleted file mode 100644 index 1eacf93..0000000 --- a/mlt++/src/MltPushConsumer.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * MltPushConsumer.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef MLTPP_PUSH_CONSUMER_H -#define MLTPP_PUSH_CONSUMER_H - -#include "config.h" - -#include "MltConsumer.h" - -namespace Mlt -{ - class Frame; - class Service; - class PushPrivate; - class Profile; - - class MLTPP_DECLSPEC PushConsumer : public Consumer - { - private: - PushPrivate *m_private; - public: - PushConsumer( Profile& profile, char *id , char *service = NULL ); - virtual ~PushConsumer( ); - void set_render( int width, int height, double aspect_ratio ); - virtual int connect( Service &service ); - int push( Frame *frame ); - int push( Frame &frame ); - int drain( ); - Frame *construct( int ); - }; -} - -#endif diff --git a/mlt++/src/MltRepository.cpp b/mlt++/src/MltRepository.cpp deleted file mode 100644 index d8984a2..0000000 --- a/mlt++/src/MltRepository.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/** - * MltRepository.cpp - MLT Wrapper - * Copyright (C) 2008 Dan Dennedy - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltRepository.h" -#include "MltProfile.h" -#include "MltProperties.h" -using namespace Mlt; - -Repository::Repository( const char* directory ) : - instance( NULL ) -{ - instance = mlt_repository_init( directory ); -} - -Repository::Repository( mlt_repository repository ) : - instance( repository ) -{ -} - -Repository::~Repository( ) -{ - if ( instance ) - mlt_repository_close( instance ); - instance = NULL; -} - -void Repository::register_service( mlt_service_type service_type, const char *service, mlt_register_callback symbol ) -{ - mlt_repository_register( instance, service_type, service, symbol ); -} - -void *Repository::create( Profile& profile, mlt_service_type type, const char *service, void *arg ) -{ - return mlt_repository_create( instance, profile.get_profile(), type, service, arg ); -} - -Properties *Repository::consumers( ) const -{ - return new Properties( mlt_repository_consumers( instance ) ); -} - -Properties *Repository::filters( ) const -{ - return new Properties( mlt_repository_filters( instance ) ); -} - -Properties *Repository::producers( ) const -{ - return new Properties( mlt_repository_producers( instance ) ); -} - -Properties *Repository::transitions( ) const -{ - return new Properties( mlt_repository_transitions( instance ) ); -} - -void Repository::register_metadata( mlt_service_type type, const char *service, mlt_metadata_callback callback, void *callback_data ) -{ - mlt_repository_register_metadata( instance, type, service, callback, callback_data ); -} - -Properties *Repository::metadata( mlt_service_type type, const char *service ) const -{ - return new Properties( mlt_repository_metadata( instance, type, service ) ); -} diff --git a/mlt++/src/MltRepository.h b/mlt++/src/MltRepository.h deleted file mode 100644 index 87d3161..0000000 --- a/mlt++/src/MltRepository.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * MltRepository.h - MLT Wrapper - * Copyright (C) 2008 Dan Dennedy - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_REPOSITORY_H_ -#define _MLTPP_REPOSITORY_H_ - -#include "config.h" - -#ifdef SWIG -#define MLTPP_DECLSPEC -#endif - -#include - -namespace Mlt -{ - class Profile; - class Properties; - - class MLTPP_DECLSPEC Repository - { - private: - mlt_repository instance; - Repository( ) { } - public: - Repository( const char* directory ); - Repository( mlt_repository repository ); - ~Repository(); - - void register_service( mlt_service_type service_type, const char *service, mlt_register_callback symbol ); - void *create( Profile& profile, mlt_service_type type, const char *service, void *arg ); - Properties *consumers( ) const; - Properties *filters( ) const; - Properties *producers( ) const; - Properties *transitions( ) const; - void register_metadata( mlt_service_type type, const char *service, mlt_metadata_callback, void *callback_data ); - Properties *metadata( mlt_service_type type, const char *service ) const; - }; -} - -#endif diff --git a/mlt++/src/MltService.cpp b/mlt++/src/MltService.cpp deleted file mode 100644 index 88751ab..0000000 --- a/mlt++/src/MltService.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/** - * MltService.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include "MltService.h" -#include "MltFilter.h" -#include "MltProfile.h" -using namespace Mlt; - -Service::Service( ) : - Properties( false ), - instance( NULL ) -{ -} - -Service::Service( Service &service ) : - Properties( false ), - instance( service.get_service( ) ) -{ - inc_ref( ); -} - -Service::Service( mlt_service service ) : - Properties( false ), - instance( service ) -{ - inc_ref( ); -} - -Service::~Service( ) -{ - mlt_service_close( instance ); -} - -mlt_service Service::get_service( ) -{ - return instance; -} - -mlt_properties Service::get_properties( ) -{ - return mlt_service_properties( get_service( ) ); -} - -void Service::lock( ) -{ - mlt_service_lock( get_service( ) ); -} - -void Service::unlock( ) -{ - mlt_service_unlock( get_service( ) ); -} - -int Service::connect_producer( Service &producer, int index ) -{ - return mlt_service_connect_producer( get_service( ), producer.get_service( ), index ); -} - -Service *Service::producer( ) -{ - return new Service( mlt_service_producer( get_service( ) ) ); -} - -Service *Service::consumer( ) -{ - return new Service( mlt_service_consumer( get_service( ) ) ); -} - -Profile *Service::profile( ) -{ - return new Profile( mlt_service_profile( get_service() ) ); -} - -Frame *Service::get_frame( int index ) -{ - mlt_frame frame = NULL; - mlt_service_get_frame( get_service( ), &frame, index ); - Frame *result = new Frame( frame ); - mlt_frame_close( frame ); - return result; -} - -mlt_service_type Service::type( ) -{ - return mlt_service_identify( get_service( ) ); -} - -int Service::attach( Filter &filter ) -{ - return mlt_service_attach( get_service( ), filter.get_filter( ) ); -} - -int Service::detach( Filter &filter ) -{ - return mlt_service_detach( get_service( ), filter.get_filter( ) ); -} - -Filter *Service::filter( int index ) -{ - mlt_filter result = mlt_service_filter( get_service( ), index ); - return result == NULL ? NULL : new Filter( result ); -} - diff --git a/mlt++/src/MltService.h b/mlt++/src/MltService.h deleted file mode 100644 index 2079614..0000000 --- a/mlt++/src/MltService.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * MltService.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_SERVICE_H_ -#define _MLTPP_SERVICE_H_ - -#include "config.h" - -#include - -#include "MltProperties.h" -#include "MltFrame.h" - -namespace Mlt -{ - class Properties; - class Filter; - class Frame; - class Profile; - - class MLTPP_DECLSPEC Service : public Properties - { - private: - mlt_service instance; - public: - Service( ); - Service( Service &service ); - Service( mlt_service service ); - virtual ~Service( ); - virtual mlt_service get_service( ); - void lock( ); - void unlock( ); - virtual mlt_properties get_properties( ); - int connect_producer( Service &producer, int index = 0 ); - Service *consumer( ); - Service *producer( ); - Profile *profile( ); - Frame *get_frame( int index = 0 ); - mlt_service_type type( ); - int attach( Filter &filter ); - int detach( Filter &filter ); - Filter *filter( int index ); - }; -} - -#endif diff --git a/mlt++/src/MltTokeniser.cpp b/mlt++/src/MltTokeniser.cpp deleted file mode 100644 index ed1287d..0000000 --- a/mlt++/src/MltTokeniser.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** - * MltTokeniser.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include "MltTokeniser.h" -using namespace Mlt; - -Tokeniser::Tokeniser( char *text, char *delimiter ) -{ - tokens = mlt_tokeniser_init( ); - if ( text != NULL ) - mlt_tokeniser_parse_new( tokens, text, delimiter ); -} - -Tokeniser::~Tokeniser( ) -{ - mlt_tokeniser_close( tokens ); -} - -int Tokeniser::parse( char *text, char *delimiter ) -{ - return mlt_tokeniser_parse_new( tokens, text, delimiter ); -} - -int Tokeniser::count( ) -{ - return mlt_tokeniser_count( tokens ); -} - -char *Tokeniser::get( int index ) -{ - return mlt_tokeniser_get_string( tokens, index ); -} - -char *Tokeniser::input( ) -{ - return mlt_tokeniser_get_input( tokens ); -} - diff --git a/mlt++/src/MltTokeniser.h b/mlt++/src/MltTokeniser.h deleted file mode 100644 index 7b0bda9..0000000 --- a/mlt++/src/MltTokeniser.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * MltTokeniser.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_TOKENISER_H -#define _MLTPP_TOKENISER_H - -#include "config.h" - -#include - -namespace Mlt -{ - class MLTPP_DECLSPEC Tokeniser - { - private: - mlt_tokeniser tokens; - public: - Tokeniser( char *text = NULL, char *delimiter = " " ); - ~Tokeniser( ); - int parse( char *text, char *delimiter = " " ); - int count( ); - char *get( int index ); - char *input( ); - }; -} - -#endif - diff --git a/mlt++/src/MltTractor.cpp b/mlt++/src/MltTractor.cpp deleted file mode 100644 index 43bbced..0000000 --- a/mlt++/src/MltTractor.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/** - * MltTractor.cpp - Tractor wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "MltTractor.h" -#include "MltMultitrack.h" -#include "MltField.h" -#include "MltTransition.h" -#include "MltFilter.h" -#include "MltPlaylist.h" -using namespace Mlt; - -Tractor::Tractor( ) : - instance( mlt_tractor_new( ) ) -{ -} - -Tractor::Tractor( Service &tractor ) : - instance( NULL ) -{ - if ( tractor.type( ) == tractor_type ) - { - instance = ( mlt_tractor )tractor.get_service( ); - inc_ref( ); - } -} - -Tractor::Tractor( mlt_tractor tractor ) : - instance( tractor ) -{ - inc_ref( ); -} - -Tractor::Tractor( Tractor &tractor ) : - Mlt::Producer( tractor ), - instance( tractor.get_tractor( ) ) -{ - inc_ref( ); -} - -Tractor::Tractor( Profile& profile, char *id, char *resource ) : - instance( NULL ) -{ - Producer producer( profile, id, resource ); - if ( producer.is_valid( ) && producer.type( ) == tractor_type ) - { - instance = ( mlt_tractor )producer.get_producer( ); - inc_ref( ); - } - else if ( producer.is_valid( ) ) - { - instance = mlt_tractor_new( ); - set_track( producer, 0 ); - } -} - -Tractor::~Tractor( ) -{ - mlt_tractor_close( instance ); -} - -mlt_tractor Tractor::get_tractor( ) -{ - return instance; -} - -mlt_producer Tractor::get_producer( ) -{ - return mlt_tractor_producer( get_tractor( ) ); -} - -Multitrack *Tractor::multitrack( ) -{ - return new Multitrack( mlt_tractor_multitrack( get_tractor( ) ) ); -} - -Field *Tractor::field( ) -{ - return new Field( mlt_tractor_field( get_tractor( ) ) ); -} - -void Tractor::refresh( ) -{ - return mlt_tractor_refresh( get_tractor( ) ); -} - -int Tractor::set_track( Producer &producer, int index ) -{ - return mlt_tractor_set_track( get_tractor( ), producer.get_producer( ), index ); -} - -Producer *Tractor::track( int index ) -{ - mlt_producer producer = mlt_tractor_get_track( get_tractor( ), index ); - return producer != NULL ? new Producer( producer ) : NULL; -} - -int Tractor::count( ) -{ - return mlt_multitrack_count( mlt_tractor_multitrack( get_tractor( ) ) ); -} - -void Tractor::plant_transition( Transition &transition, int a_track, int b_track ) -{ - mlt_field_plant_transition( mlt_tractor_field( get_tractor( ) ), transition.get_transition( ), a_track, b_track ); -} - -void Tractor::plant_transition( Transition *transition, int a_track, int b_track ) -{ - if ( transition != NULL ) - mlt_field_plant_transition( mlt_tractor_field( get_tractor( ) ), transition->get_transition( ), a_track, b_track ); -} - -void Tractor::plant_filter( Filter &filter, int track ) -{ - mlt_field_plant_filter( mlt_tractor_field( get_tractor( ) ), filter.get_filter( ), track ); -} - -void Tractor::plant_filter( Filter *filter, int track ) -{ - mlt_field_plant_filter( mlt_tractor_field( get_tractor( ) ), filter->get_filter( ), track ); -} - -bool Tractor::locate_cut( Producer *producer, int &track, int &cut ) -{ - bool found = false; - - for ( track = 0; producer != NULL && !found && track < count( ); track ++ ) - { - Playlist playlist( ( mlt_playlist )mlt_tractor_get_track( get_tractor( ), track ) ); - for ( cut = 0; !found && cut < playlist.count( ); cut ++ ) - { - Producer *clip = playlist.get_clip( cut ); - found = producer->get_producer( ) == clip->get_producer( ); - delete clip; - } - } - - track --; - cut --; - - return found; -} diff --git a/mlt++/src/MltTractor.h b/mlt++/src/MltTractor.h deleted file mode 100644 index 9fe5d79..0000000 --- a/mlt++/src/MltTractor.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * MltTractor.h - Tractor wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_TRACTOR_H_ -#define _MLTPP_TRACTOR_H_ - -#include "config.h" - -#include - -#include "MltProducer.h" - -namespace Mlt -{ - class Producer; - class Field; - class Multitrack; - class Transition; - class Filter; - class Profile; - - class MLTPP_DECLSPEC Tractor : public Producer - { - private: - mlt_tractor instance; - public: - Tractor( ); - Tractor( Service &tractor ); - Tractor( mlt_tractor tractor ); - Tractor( Tractor &tractor ); - Tractor( Profile& profile, char *id, char *arg = NULL ); - virtual ~Tractor( ); - virtual mlt_tractor get_tractor( ); - mlt_producer get_producer( ); - Multitrack *multitrack( ); - Field *field( ); - void refresh( ); - int set_track( Producer &producer, int index ); - Producer *track( int index ); - int count( ); - void plant_transition( Transition &transition, int a_track = 0, int b_track = 1 ); - void plant_transition( Transition *transition, int a_track = 0, int b_track = 1 ); - void plant_filter( Filter &filter, int track = 0 ); - void plant_filter( Filter *filter, int track = 0 ); - bool locate_cut( Producer *producer, int &track, int &cut ); - }; -} - -#endif - diff --git a/mlt++/src/MltTransition.cpp b/mlt++/src/MltTransition.cpp deleted file mode 100644 index 39bce7c..0000000 --- a/mlt++/src/MltTransition.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/** - * MltTransition.cpp - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include "MltTransition.h" -#include "MltProfile.h" -using namespace Mlt; - -Transition::Transition( Profile& profile, const char *id, const char *arg ) : - instance( NULL ) -{ - if ( arg != NULL ) - { - instance = mlt_factory_transition( profile.get_profile(), id, arg ); - } - else - { - if ( strchr( id, ':' ) ) - { - char *temp = strdup( id ); - char *arg = strchr( temp, ':' ) + 1; - *( arg - 1 ) = '\0'; - instance = mlt_factory_transition( profile.get_profile(), temp, arg ); - free( temp ); - } - else - { - instance = mlt_factory_transition( profile.get_profile(), id, NULL ); - } - } -} - -Transition::Transition( Service &transition ) : - instance( NULL ) -{ - if ( transition.type( ) == transition_type ) - { - instance = ( mlt_transition )transition.get_service( ); - inc_ref( ); - } -} - -Transition::Transition( Transition &transition ) : - Mlt::Service( transition ), - instance( transition.get_transition( ) ) -{ - inc_ref( ); -} - -Transition::Transition( mlt_transition transition ) : - instance( transition ) -{ - inc_ref( ); -} - -Transition::~Transition( ) -{ - mlt_transition_close( instance ); -} - -mlt_transition Transition::get_transition( ) -{ - return instance; -} - -mlt_service Transition::get_service( ) -{ - return mlt_transition_service( get_transition( ) ); -} - -void Transition::set_in_and_out( int in, int out ) -{ - mlt_transition_set_in_and_out( get_transition( ), in, out ); -} diff --git a/mlt++/src/MltTransition.h b/mlt++/src/MltTransition.h deleted file mode 100644 index 4dc90e1..0000000 --- a/mlt++/src/MltTransition.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * MltTransition.h - MLT Wrapper - * Copyright (C) 2004-2005 Charles Yates - * Author: Charles Yates - * - * 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 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MLTPP_TRANSITION_H_ -#define _MLTPP_TRANSITION_H_ - -#include "config.h" - -#include -#include "MltService.h" - -namespace Mlt -{ - class Service; - class Profile; - - class MLTPP_DECLSPEC Transition : public Service - { - private: - mlt_transition instance; - public: - Transition( Profile& profile, const char *id, const char *arg = NULL ); - Transition( Service &transition ); - Transition( Transition &transition ); - Transition( mlt_transition transition ); - virtual ~Transition( ); - virtual mlt_transition get_transition( ); - mlt_service get_service( ); - void set_in_and_out( int in, int out ); - }; -} - -#endif diff --git a/mlt++/swig/java/Play.java b/mlt++/swig/java/Play.java deleted file mode 100644 index 35918db..0000000 --- a/mlt++/swig/java/Play.java +++ /dev/null @@ -1,54 +0,0 @@ -import net.sourceforge.mltpp.*; - -public class Play { - - static { - System.loadLibrary("mltpp_java"); - } - - public static void main (String[] args) { - - // Start the mlt system - Factory.init( null ); - - // Set the output profile - Profile profile = new Profile( "" ); - - // Create the producer - Producer p = new Producer( profile, args[0], null ); - - if ( p.is_valid() ) { - - p.set ("eof", "loop"); - - // Create the consumer - Consumer c = new Consumer( profile, "sdl", null); - - // Turn off the default rescaling - c.set("rescale", "none"); - - // Connect the producer to the consumer - c.connect(p); - - // Start the consumer - c.start(); - - // Wait until the user stops the consumer - Object o = new Object(); - while ( !c.is_stopped() ) { - synchronized (o) { - try { - o.wait(1000); - } catch (InterruptedException e) { - // ignored - } - } - } - - // Stop it anyway - c.stop(); - } else { - System.out.println ("Unable to open " + args[0]); - } - } -} diff --git a/mlt++/swig/perl/play.pl b/mlt++/swig/perl/play.pl deleted file mode 100755 index 87047b9..0000000 --- a/mlt++/swig/perl/play.pl +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env perl - -# Import required modules -use mltpp; - -# Not sure why the mltpp::Factory.init method fails... -mltpp::mlt_factory_init( undef ); - -# Establish the MLT profile -$profile = new mltpp::Profile( undef ); - -# Create the producer -$p = new mltpp::Producer( $profile, $ARGV[0] ); - -if ( $p->is_valid( ) ) -{ - # Loop the video - $p->set( "eof", "loop" ); - - # Create the consumer - $c = new mltpp::FilteredConsumer( $profile, "sdl" ); - - # Turn of the default rescaling - $c->set( "rescale", "none" ); - - # Connect the producer to the consumer - $c->connect( $p ); - - $e = $c->setup_wait_for( "consumer-stopped" ); - - # Start the consumer - $c->start; - - # Wait until the user stops the consumer - $c->wait_for( $e ); - - $e = undef; - $c = undef; - $p = undef; -} -else -{ - print "Unable to open $ARGV[0]\n"; -} - -mltpp::mlt_factory_close( ); diff --git a/mlt++/swig/php/play.php b/mlt++/swig/php/play.php deleted file mode 100755 index 7cfa2fd..0000000 --- a/mlt++/swig/php/play.php +++ /dev/null @@ -1,21 +0,0 @@ - - diff --git a/mlt++/swig/python/play.py b/mlt++/swig/python/play.py deleted file mode 100755 index 72116ae..0000000 --- a/mlt++/swig/python/play.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python - -# Import required modules -import mltpp -import time -import sys - -# Start the mlt system -mltpp.Factory().init( ) - -# Establish a profile -profile = mltpp.Profile( ) - -# Create the producer -p = mltpp.Producer( profile, sys.argv[1] ) - -if p: - # Create the consumer - c = mltpp.Consumer( profile, "sdl" ) - - # Turn off the default rescaling - c.set( "rescale", "none" ) - - # Connect the producer to the consumer - c.connect( p ) - - # Start the consumer - c.start( ) - - # Wait until the user stops the consumer - while c.is_stopped( ) == 0: - time.sleep( 1 ) -else: - # Diagnostics - print "Unable to open ", sys.argv[ 1 ] - diff --git a/mlt++/swig/ruby/play.rb b/mlt++/swig/ruby/play.rb deleted file mode 100755 index 1ec995b..0000000 --- a/mlt++/swig/ruby/play.rb +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env ruby - -# Import required modules -require 'mltpp' - -# Create the mlt system -Mltpp::Factory::init - -# Establish the mlt profile -profile = Mltpp::Profile.new - -# Get and check the argument -file = ARGV.shift -raise "Usage: test.rb file" if file.nil? - -# Create the producer -producer = Mltpp::Factory::producer( profile, file ) -raise "Unable to load #{file}" if !producer.is_valid - -# Create the consumer -consumer = Mltpp::Consumer.new( profile, "sdl" ) -raise "Unable to open sdl consumer" if !consumer.is_valid - -# Turn off the default rescaling -consumer.set( "rescale", "none" ) - -# Set up a 'wait for' event -event = consumer.setup_wait_for( "consumer-stopped" ) - -# Start the consumer -consumer.start - -# Connect the producer to the consumer -consumer.connect( producer ) - -# Wait until the user stops the consumer -consumer.wait_for( event ) - -# Clean up consumer -consumer.stop - diff --git a/mlt++/swig/ruby/thumbs.rb b/mlt++/swig/ruby/thumbs.rb deleted file mode 100755 index 9cb6799..0000000 --- a/mlt++/swig/ruby/thumbs.rb +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env ruby - -# Required modules -require 'mltpp' - -# Create the mlt system -Mltpp::Factory::init - -# Establish the mlt profile -profile = Mltpp::Profile.new( "quarter_pal" ) - -# Get and check the argument -file = ARGV.shift -name = ARGV.shift -size = ARGV.shift -size = "176x144" if size.nil? -raise "Usage: thumbs.rb file name [ size ]" if file.nil? || name.nil? - -# Create the producer -producer = Mltpp::Producer.new( profile, file ) -raise "Unable to load #{file}" if !producer.is_valid - -# Construct the playlist -playlist = Mltpp::Playlist.new( ) - -# Get the out point -out = producer.get_int( "out" ); - -# Calculate position of frames -[ 0, 0.25, 0.5, 0.75, 1 ].each { |x| playlist.append( producer, Integer(x*out), Integer(x*out) ) } - -# Create the thumb nail generator -generator = Mltpp::Consumer.new( profile, "avformat", "#{name}%d.jpg" ) -generator.set( "real_time", "0" ) -generator.set( "progressive", "1" ) -generator.set( "s", size ) - -# Connect the consumer -generator.connect( playlist ); -generator.run - diff --git a/mlt++/swig/tcl/play.tcl b/mlt++/swig/tcl/play.tcl deleted file mode 100755 index 2b182c7..0000000 --- a/mlt++/swig/tcl/play.tcl +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env tclsh - -load mltpp.so -mltpp.Factory.init -set profile [Profile] -set arg1 [lindex $argv 0] -set p [factory_producer $profile fezzik $arg1] -set c [factory_consumer $profile sdl ""] -set r [mlt_consumer_properties $c] -mlt_properties_set $r "rescale" "none" -consumer_connect $c $p -mlt_consumer_start $c -while { ![mlt_consumer_is_stopped $c] } { - after 1000 -} -mlt_consumer_close $c -mlt_producer_close $p -factory_close diff --git a/mlt++/test/play.cpp b/mlt++/test/play.cpp deleted file mode 100644 index e83c5a9..0000000 --- a/mlt++/test/play.cpp +++ /dev/null @@ -1,15 +0,0 @@ - -#include -using namespace Mlt; - -int main( int, char **argv ) -{ - Factory::init( NULL ); - Profile profile; - Producer producer( profile, argv[ 1 ] ); - Consumer consumer( profile ); - consumer.set( "rescale", "none" ); - consumer.connect( producer ); - consumer.run( ); - return 0; -} diff --git a/mlt-framework.pc.in b/mlt-framework.pc.in deleted file mode 100644 index 5748867..0000000 --- a/mlt-framework.pc.in +++ /dev/null @@ -1,7 +0,0 @@ - -Name: mlt-framework -Description: MLT multimedia framework -Version: ${version} -Requires: -Libs: -L${libdir} ${libs} -Cflags: ${cflags} diff --git a/profiles/Makefile b/profiles/Makefile deleted file mode 100644 index 9ad9f62..0000000 --- a/profiles/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -include ../config.mak - -all: - -depend: - -distclean: - -clean: - -install: all uninstall - install -d "$(DESTDIR)$(prefix)/share/mlt/profiles" - install -m 644 * "$(DESTDIR)$(prefix)/share/mlt/profiles" - rm -f "$(DESTDIR)$(prefix)/share/mlt/profiles/"*~ - rm -f "$(DESTDIR)$(prefix)/share/mlt/profiles/Makefile" - -uninstall: - rm -rf "$(DESTDIR)$(prefix)/share/mlt/profiles" diff --git a/profiles/atsc_1080i_50 b/profiles/atsc_1080i_50 deleted file mode 100644 index 4309b0f..0000000 --- a/profiles/atsc_1080i_50 +++ /dev/null @@ -1,10 +0,0 @@ -description=ATSC 1080i 50Hz -frame_rate_num=25 -frame_rate_den=1 -width=1920 -height=1080 -progressive=0 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/atsc_1080i_60 b/profiles/atsc_1080i_60 deleted file mode 100644 index 3c95886..0000000 --- a/profiles/atsc_1080i_60 +++ /dev/null @@ -1,10 +0,0 @@ -description=ATSC 1080i 60Hz -frame_rate_num=30000 -frame_rate_den=1001 -width=1920 -height=1080 -progressive=0 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/atsc_1080p_2398 b/profiles/atsc_1080p_2398 deleted file mode 100644 index e8a1415..0000000 --- a/profiles/atsc_1080p_2398 +++ /dev/null @@ -1,10 +0,0 @@ -description=ATSC 1080p 23.98Hz -frame_rate_num=24000 -frame_rate_den=1001 -width=1920 -height=1080 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/atsc_1080p_24 b/profiles/atsc_1080p_24 deleted file mode 100644 index 49f6422..0000000 --- a/profiles/atsc_1080p_24 +++ /dev/null @@ -1,10 +0,0 @@ -description=ATSC 1080p 24Hz -frame_rate_num=24 -frame_rate_den=1 -width=1920 -height=1080 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/atsc_1080p_25 b/profiles/atsc_1080p_25 deleted file mode 100644 index 769200a..0000000 --- a/profiles/atsc_1080p_25 +++ /dev/null @@ -1,10 +0,0 @@ -description=ATSC 1080p 25Hz -frame_rate_num=25 -frame_rate_den=1 -width=1920 -height=1080 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/atsc_1080p_2997 b/profiles/atsc_1080p_2997 deleted file mode 100644 index 9633cd6..0000000 --- a/profiles/atsc_1080p_2997 +++ /dev/null @@ -1,10 +0,0 @@ -description=ATSC 1080p 29.97Hz -frame_rate_num=30000 -frame_rate_den=1001 -width=1920 -height=1080 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/atsc_1080p_30 b/profiles/atsc_1080p_30 deleted file mode 100644 index 1b00238..0000000 --- a/profiles/atsc_1080p_30 +++ /dev/null @@ -1,10 +0,0 @@ -description=ATSC 1080p 30Hz -frame_rate_num=30 -frame_rate_den=1 -width=1920 -height=1080 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/atsc_720p_30 b/profiles/atsc_720p_30 deleted file mode 100644 index beb6cc9..0000000 --- a/profiles/atsc_720p_30 +++ /dev/null @@ -1,10 +0,0 @@ -description=ATSC 720p 30Hz -frame_rate_num=30000 -frame_rate_den=1001 -width=1280 -height=720 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/cif_15 b/profiles/cif_15 deleted file mode 100644 index 7b590d2..0000000 --- a/profiles/cif_15 +++ /dev/null @@ -1,10 +0,0 @@ -description=CIF 15 fps -frame_rate_num=15 -frame_rate_den=1 -width=352 -height=288 -progressive=1 -sample_aspect_num=59 -sample_aspect_den=54 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/cif_ntsc b/profiles/cif_ntsc deleted file mode 100644 index 48279a5..0000000 --- a/profiles/cif_ntsc +++ /dev/null @@ -1,10 +0,0 @@ -description=CIF NTSC -frame_rate_num=30000 -frame_rate_den=1001 -width=352 -height=288 -progressive=1 -sample_aspect_num=10 -sample_aspect_den=11 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/cif_pal b/profiles/cif_pal deleted file mode 100644 index a7f66d4..0000000 --- a/profiles/cif_pal +++ /dev/null @@ -1,10 +0,0 @@ -description=CIF PAL -frame_rate_num=25 -frame_rate_den=1 -width=352 -height=288 -progressive=1 -sample_aspect_num=59 -sample_aspect_den=54 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/cvd_ntsc b/profiles/cvd_ntsc deleted file mode 100644 index 508b3cc..0000000 --- a/profiles/cvd_ntsc +++ /dev/null @@ -1,10 +0,0 @@ -description=CVD NTSC -frame_rate_num=30000 -frame_rate_den=1001 -width=352 -height=480 -progressive=0 -sample_aspect_num=20 -sample_aspect_den=11 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/cvd_pal b/profiles/cvd_pal deleted file mode 100644 index 2415c77..0000000 --- a/profiles/cvd_pal +++ /dev/null @@ -1,10 +0,0 @@ -description=CVD PAL -frame_rate_num=25 -frame_rate_den=1 -width=352 -height=576 -progressive=0 -sample_aspect_num=59 -sample_aspect_den=27 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/dv_ntsc b/profiles/dv_ntsc deleted file mode 100644 index ff1f24e..0000000 --- a/profiles/dv_ntsc +++ /dev/null @@ -1,10 +0,0 @@ -description=DV NTSC -frame_rate_num=30000 -frame_rate_den=1001 -width=720 -height=480 -progressive=0 -sample_aspect_num=8 -sample_aspect_den=9 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/dv_ntsc_wide b/profiles/dv_ntsc_wide deleted file mode 100644 index d512d6c..0000000 --- a/profiles/dv_ntsc_wide +++ /dev/null @@ -1,10 +0,0 @@ -description=DV NTSC Widescreen -frame_rate_num=30000 -frame_rate_den=1001 -width=720 -height=480 -progressive=0 -sample_aspect_num=32 -sample_aspect_den=27 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/dv_pal b/profiles/dv_pal deleted file mode 100644 index d569140..0000000 --- a/profiles/dv_pal +++ /dev/null @@ -1,10 +0,0 @@ -description=DV PAL -frame_rate_num=25 -frame_rate_den=1 -width=720 -height=576 -progressive=0 -sample_aspect_num=16 -sample_aspect_den=15 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/dv_pal_wide b/profiles/dv_pal_wide deleted file mode 100644 index a52b9cf..0000000 --- a/profiles/dv_pal_wide +++ /dev/null @@ -1,10 +0,0 @@ -description=DV PAL Widescreen -frame_rate_num=25 -frame_rate_den=1 -width=720 -height=576 -progressive=0 -sample_aspect_num=64 -sample_aspect_den=45 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/hdv_1080_25p b/profiles/hdv_1080_25p deleted file mode 100644 index bba72e8..0000000 --- a/profiles/hdv_1080_25p +++ /dev/null @@ -1,10 +0,0 @@ -description=HDV 1080 25p -frame_rate_num=25 -frame_rate_den=1 -width=1440 -height=1080 -progressive=1 -sample_aspect_num=4 -sample_aspect_den=3 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/hdv_1080_30p b/profiles/hdv_1080_30p deleted file mode 100644 index 7321364..0000000 --- a/profiles/hdv_1080_30p +++ /dev/null @@ -1,10 +0,0 @@ -description=HDV 1080 30p -frame_rate_num=30000 -frame_rate_den=1001 -width=1440 -height=1080 -progressive=1 -sample_aspect_num=4 -sample_aspect_den=3 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/hdv_1080_50i b/profiles/hdv_1080_50i deleted file mode 100644 index 6544470..0000000 --- a/profiles/hdv_1080_50i +++ /dev/null @@ -1,10 +0,0 @@ -description=HDV 1080 50i -frame_rate_num=25 -frame_rate_den=1 -width=1440 -height=1080 -progressive=0 -sample_aspect_num=4 -sample_aspect_den=3 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/hdv_1080_60i b/profiles/hdv_1080_60i deleted file mode 100644 index 9c3e6fc..0000000 --- a/profiles/hdv_1080_60i +++ /dev/null @@ -1,10 +0,0 @@ -description=HDV 1080 60i -frame_rate_num=30000 -frame_rate_den=1001 -width=1440 -height=1080 -progressive=0 -sample_aspect_num=4 -sample_aspect_den=3 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/hdv_720_25p b/profiles/hdv_720_25p deleted file mode 100644 index 7bd6eed..0000000 --- a/profiles/hdv_720_25p +++ /dev/null @@ -1,10 +0,0 @@ -description=HDV 720 25p -frame_rate_num=25 -frame_rate_den=1 -width=1280 -height=720 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/hdv_720_30p b/profiles/hdv_720_30p deleted file mode 100644 index 68caaf9..0000000 --- a/profiles/hdv_720_30p +++ /dev/null @@ -1,10 +0,0 @@ -description=HDV 720 30p -frame_rate_num=30000 -frame_rate_den=1001 -width=1280 -height=720 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/hdv_720_50p b/profiles/hdv_720_50p deleted file mode 100644 index 2a93230..0000000 --- a/profiles/hdv_720_50p +++ /dev/null @@ -1,10 +0,0 @@ -description=HDV 720 50p -frame_rate_num=50 -frame_rate_den=1 -width=1280 -height=720 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/hdv_720_60p b/profiles/hdv_720_60p deleted file mode 100644 index 11189cb..0000000 --- a/profiles/hdv_720_60p +++ /dev/null @@ -1,10 +0,0 @@ -description=HDV 720 60p -frame_rate_num=60000 -frame_rate_den=1001 -width=1280 -height=720 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/qcif_15 b/profiles/qcif_15 deleted file mode 100644 index 70d286d..0000000 --- a/profiles/qcif_15 +++ /dev/null @@ -1,10 +0,0 @@ -description=QCIF 15fps -frame_rate_num=15 -frame_rate_den=1 -width=176 -height=144 -progressive=1 -sample_aspect_num=59 -sample_aspect_den=54 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/qcif_ntsc b/profiles/qcif_ntsc deleted file mode 100644 index 0e90157..0000000 --- a/profiles/qcif_ntsc +++ /dev/null @@ -1,10 +0,0 @@ -description=QCIF NTSC -frame_rate_num=30000 -frame_rate_den=1001 -width=176 -height=144 -progressive=1 -sample_aspect_num=10 -sample_aspect_den=11 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/qcif_pal b/profiles/qcif_pal deleted file mode 100644 index 21667ee..0000000 --- a/profiles/qcif_pal +++ /dev/null @@ -1,10 +0,0 @@ -description=QCIF PAL -frame_rate_num=25 -frame_rate_den=1 -width=176 -height=144 -progressive=1 -sample_aspect_num=59 -sample_aspect_den=54 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/quarter_15 b/profiles/quarter_15 deleted file mode 100644 index 7ba8eef..0000000 --- a/profiles/quarter_15 +++ /dev/null @@ -1,10 +0,0 @@ -description=QVGA 15fps -frame_rate_num=15 -frame_rate_den=1 -width=320 -height=240 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/quarter_ntsc b/profiles/quarter_ntsc deleted file mode 100644 index fb37cd7..0000000 --- a/profiles/quarter_ntsc +++ /dev/null @@ -1,10 +0,0 @@ -description=Quarter Square NTSC -frame_rate_num=30000 -frame_rate_den=1001 -width=320 -height=240 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/quarter_ntsc_wide b/profiles/quarter_ntsc_wide deleted file mode 100644 index 8c7be94..0000000 --- a/profiles/quarter_ntsc_wide +++ /dev/null @@ -1,10 +0,0 @@ -description=Quarter Square NTSC Widescreen -frame_rate_num=30000 -frame_rate_den=1001 -width=426 -height=240 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/quarter_pal b/profiles/quarter_pal deleted file mode 100644 index beec207..0000000 --- a/profiles/quarter_pal +++ /dev/null @@ -1,10 +0,0 @@ -description=Quarter Square PAL -frame_rate_num=25 -frame_rate_den=1 -width=384 -height=288 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/quarter_pal_wide b/profiles/quarter_pal_wide deleted file mode 100644 index 195410a..0000000 --- a/profiles/quarter_pal_wide +++ /dev/null @@ -1,10 +0,0 @@ -description=Quarter Square PAL Widescreen -frame_rate_num=25 -frame_rate_den=1 -width=512 -height=288 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/square_ntsc b/profiles/square_ntsc deleted file mode 100644 index e139c3e..0000000 --- a/profiles/square_ntsc +++ /dev/null @@ -1,10 +0,0 @@ -description=Square NTSC -frame_rate_num=30000 -frame_rate_den=1001 -width=640 -height=480 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/square_ntsc_wide b/profiles/square_ntsc_wide deleted file mode 100644 index da2de3e..0000000 --- a/profiles/square_ntsc_wide +++ /dev/null @@ -1,10 +0,0 @@ -description=Square NTSC Widescreen -frame_rate_num=30000 -frame_rate_den=1001 -width=854 -height=480 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/square_pal b/profiles/square_pal deleted file mode 100644 index a69c8d6..0000000 --- a/profiles/square_pal +++ /dev/null @@ -1,10 +0,0 @@ -description=Square PAL -frame_rate_num=25 -frame_rate_den=1 -width=768 -height=576 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/square_pal_wide b/profiles/square_pal_wide deleted file mode 100644 index 316a80d..0000000 --- a/profiles/square_pal_wide +++ /dev/null @@ -1,10 +0,0 @@ -description=Square PAL Widescreen -frame_rate_num=25 -frame_rate_den=1 -width=1024 -height=576 -progressive=1 -sample_aspect_num=1 -sample_aspect_den=1 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/svcd_ntsc b/profiles/svcd_ntsc deleted file mode 100644 index fd6f13a..0000000 --- a/profiles/svcd_ntsc +++ /dev/null @@ -1,10 +0,0 @@ -description=SVCD NTSC -frame_rate_num=30000 -frame_rate_den=1001 -width=480 -height=480 -progressive=0 -sample_aspect_num=15 -sample_aspect_den=11 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/svcd_ntsc_wide b/profiles/svcd_ntsc_wide deleted file mode 100644 index 174960a..0000000 --- a/profiles/svcd_ntsc_wide +++ /dev/null @@ -1,10 +0,0 @@ -description=SVCD NTSC Widescreen -frame_rate_num=30000 -frame_rate_den=1001 -width=480 -height=480 -progressive=0 -sample_aspect_num=20 -sample_aspect_den=11 -display_aspect_num=16 -display_aspect_den=9 diff --git a/profiles/svcd_pal b/profiles/svcd_pal deleted file mode 100644 index 2049270..0000000 --- a/profiles/svcd_pal +++ /dev/null @@ -1,10 +0,0 @@ -description=SVCD PAL -frame_rate_num=25 -frame_rate_den=1 -width=480 -height=576 -progressive=0 -sample_aspect_num=59 -sample_aspect_den=36 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/svcd_pal_wide b/profiles/svcd_pal_wide deleted file mode 100644 index 3aea87a..0000000 --- a/profiles/svcd_pal_wide +++ /dev/null @@ -1,10 +0,0 @@ -description=SVCD PAL Widescreen -frame_rate_num=25 -frame_rate_den=1 -width=480 -height=576 -progressive=0 -sample_aspect_num=59 -sample_aspect_den=27 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/vcd_ntsc b/profiles/vcd_ntsc deleted file mode 100644 index e58f4f2..0000000 --- a/profiles/vcd_ntsc +++ /dev/null @@ -1,10 +0,0 @@ -description=VCD NTSC -frame_rate_num=30000 -frame_rate_den=1001 -width=352 -height=240 -progressive=1 -sample_aspect_num=10 -sample_aspect_den=11 -display_aspect_num=4 -display_aspect_den=3 diff --git a/profiles/vcd_pal b/profiles/vcd_pal deleted file mode 100644 index 5f4e03f..0000000 --- a/profiles/vcd_pal +++ /dev/null @@ -1,10 +0,0 @@ -description=VCD PAL -frame_rate_num=25 -frame_rate_den=1 -width=352 -height=288 -progressive=1 -sample_aspect_num=59 -sample_aspect_den=54 -display_aspect_num=4 -display_aspect_den=3 diff --git a/setenv b/setenv deleted file mode 100644 index 53b5f6e..0000000 --- a/setenv +++ /dev/null @@ -1,26 +0,0 @@ - -# Environment variable settings to allow execution without install - -export MLT_REPOSITORY=`pwd`/src/modules -export MLT_DATA=`pwd`/src/modules -export MLT_PROFILES_PATH=`pwd`/profiles - -export LD_LIBRARY_PATH=\ -`pwd`/src/framework:\ -`pwd`/src/valerie:\ -`pwd`/src/miracle:\ -`pwd`/src/modules/bluefish:\ -`pwd`/../BlueLinuxDriver/install/lib:\ -`pwd`/../mpeg_sdk_release/bin:\ -`pwd`/../dvcpro_sdk_release/lib:\ -`pwd`/../sr_sdk_release:\ -$LD_LIBRARY_PATH - -[ $(uname -s) = Darwin ] && export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH - -export PATH=\ -`pwd`/src/albino:\ -`pwd`/src/inigo:\ -`pwd`/src/humperdink:\ -`pwd`/src/miracle:\ -$PATH diff --git a/setenv_mc b/setenv_mc deleted file mode 100644 index 705d4e2..0000000 --- a/setenv_mc +++ /dev/null @@ -1,9 +0,0 @@ - -# Environment variable settings to allow execution without install - -export LD_LIBRARY_PATH=\ -`pwd`/../mpeg_sdk_release/bin:\ -`pwd`/../dvcpro_sdk_release/lib:\ -`pwd`/../sr_sdk_release/lib:\ -$LD_LIBRARY_PATH - diff --git a/src/framework/Makefile b/src/framework/Makefile deleted file mode 100644 index 58b3899..0000000 --- a/src/framework/Makefile +++ /dev/null @@ -1,109 +0,0 @@ -include ../../config.mak - -NAME = libmlt$(LIBSUF) -TARGET = $(NAME).$(version) - -ifneq ($(targetos), Darwin) -NAME = libmlt$(LIBSUF) -TARGET = $(NAME).$(version) -SONAME = $(NAME).$(soversion) -SHFLAGS += -Wl,-soname,$(SONAME) -else -NAME = libmlt$(LIBSUF) -TARGET = libmlt.$(version)$(LIBSUF) -SONAME = libmlt.$(soversion)$(LIBSUF) -SHFLAGS += -install_name $(libdir)/$(SONAME) -current_version $(version) -compatibility_version $(soversion) -endif - -OBJS = mlt_frame.o \ - mlt_geometry.o \ - mlt_deque.o \ - mlt_property.o \ - mlt_properties.o \ - mlt_events.o \ - mlt_parser.o \ - mlt_service.o \ - mlt_producer.o \ - mlt_multitrack.o \ - mlt_playlist.o \ - mlt_consumer.o \ - mlt_filter.o \ - mlt_transition.o \ - mlt_field.o \ - mlt_tractor.o \ - mlt_factory.o \ - mlt_repository.o \ - mlt_pool.o \ - mlt_tokeniser.o \ - mlt_profile.o \ - mlt_log.o \ - mlt_cache.o - -INCS = mlt_consumer.h \ - mlt_factory.h \ - mlt_filter.h \ - mlt.h \ - mlt_multitrack.h \ - mlt_pool.h \ - mlt_properties.h \ - mlt_events.h \ - mlt_parser.h \ - mlt_repository.h \ - mlt_tractor.h \ - mlt_types.h \ - mlt_deque.h \ - mlt_field.h \ - mlt_frame.h \ - mlt_geometry.h \ - mlt_playlist.h \ - mlt_producer.h \ - mlt_property.h \ - mlt_service.h \ - mlt_transition.h \ - mlt_tokeniser.h \ - mlt_profile.h \ - mlt_log.h \ - mlt_cache.h - -SRCS := $(OBJS:.o=.c) - -CFLAGS += $(RDYNAMIC) -DPREFIX="\"$(prefix)\"" -DLIBDIR="\"$(libdir)\"" - -LDFLAGS += -lm $(LIBDL) -lpthread - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - ln -sf $(TARGET) $(NAME) - ln -sf $(TARGET) $(SONAME) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) $(NAME) - -install: - install -d $(DESTDIR)$(libdir) - install -m 755 $(TARGET) $(DESTDIR)$(libdir) - ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(SONAME) - ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(NAME) - install -d "$(DESTDIR)$(prefix)/include/mlt/framework" - install -m 644 $(INCS) "$(DESTDIR)$(prefix)/include/mlt/framework" - install -d "$(DESTDIR)$(prefix)/share/mlt" - install -m 644 metaschema.yaml "$(DESTDIR)$(prefix)/share/mlt/" - -uninstall: - rm -f "$(DESTDIR)$(libdir)/$(TARGET)" - rm -f "$(DESTDIR)$(libdir)/$(SONAME)" - rm -f "$(DESTDIR)$(libdir)/$(NAME)" - rm -rf "$(DESTDIR)$(prefix)/include/mlt/framework" - rm "$(DESTDIR)$(prefix)/share/mlt/metaschema.yaml" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/framework/configure b/src/framework/configure deleted file mode 100755 index 52655ae..0000000 --- a/src/framework/configure +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -echo "framework -I$prefix/include -I$prefix/include/mlt -D_REENTRANT -L$libdir -lmlt" >> ../../packages.dat diff --git a/src/framework/metaschema.yaml b/src/framework/metaschema.yaml deleted file mode 100644 index 9c7c78f..0000000 --- a/src/framework/metaschema.yaml +++ /dev/null @@ -1,129 +0,0 @@ ---- # A metadata schema in Kwalify: http://www.kuwata-lab.com/kwalify/ -# Version: 0.1 -type: map -mapping: - "schema_version": # This should match the version comment above - type: float - required: yes - "type": # A service type - type: str - required: yes - enum: [consumer, filter, producer, transition] - "identifier": # The same value used to register and create the service - type: str - required: yes - unique: yes - "title": # The UI can use this for a field label - type: str - "copyright": # Who owns the rights to the module and/or service? - type: str - "version": # The version of the service implementation - type: text - "license": # The software license for the service implementation - type: str - "language": # A 2 character ISO 639-1 language code - type: str - required: yes - "url": # A hyperlink to a related website - type: str - "creator": # The name and/or e-mail address of the original author - type: str - "contributor": # The name and/or e-mail of all source code contributors - type: seq - sequence: - - type: str - "tags": # A set of categories, this might become an enum - type: seq - sequence: - - type: str - "description": # A slightly longer description than title - type: str - "icon": # A graphical representation of the effect - type: map - mapping: - "filename": - type: str - "content-type": - type: str - "content-encoding": - type: str - "content": - type: str - "notes": # Details about the usage and/or implementation - can be long - type: str - "bugs": # A list of known problems that users can try to avoid - type: seq - sequence: - - type: str # Can be a sentence or paragraph, preferably not a hyperlink - "parameters": # A list of all of the options for the service - type: seq - sequence: - - type: map - mapping: - "identifier": # The key that must be used to set the mlt_property - type: str - required: yes - "type": # An mlt_property_type - type: str - enum: - - float - - geometry - - integer - - properties # for passing options to encapsulated services - - string - - time # currently, mlt_position (frame), soon to be a time value - "service-name": # for type: properties, a reference to another service - type: str # format: type.service, e.g. transition.composite - "title": # A UI can use this for a field label - type: str - "description": # A UI can use this for a tool tip or what's-this - type: str - "readonly": # If you set this property, it will be ignored - type: bool - default: no - "required": # Is this property required? - type: bool - default: no - "mutable": # The service will change behavior if this is set after - # processing the first frame - type: bool - default: no - "widget": # A hint to the UI about how to let the user set this - type: str - enum: - - checkbox - - color - - combo - - curve - - directory - - fileopen - - filesave - - font - - knob - - listbox - - dropdown # aka HTML select or GtkOptionMenu - - radio - - rectangle # for use with type: geometry - - slider - - spinner - - text - - textbox # multi-line - - timecode - "minimum": # For numeric types, the minimal value - type: number - "maximum": # For numeric types, the maximal value - type: number - "default": # The default value to be used in a UI - type: scalar # If not specified, the UI might be able to display - # this as blank - "unit": # A UI can display this as a label after the widget (e.g. %) - type: str - "scale": # the number of digits after decimal point when type: float - type: int - "format": # A hint about a custom string encoding, possibly scanf - "values": # A list of acceptable string values - type: seq # A UI can allow something outside the list with - # widget: combo or if "other" is in this sequence - sequence: - - type: scalar - diff --git a/src/framework/mlt.h b/src/framework/mlt.h deleted file mode 100644 index 6836540..0000000 --- a/src/framework/mlt.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * \file mlt.h - * \brief header file for lazy client and implementation code :-) - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_H_ -#define _MLT_H_ - -#define LIBMLT_VERSION_INT ((0<<16)+(3<<8)+9) -#define LIBMLT_VERSION 0.3.9 - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "mlt_factory.h" -#include "mlt_frame.h" -#include "mlt_deque.h" -#include "mlt_multitrack.h" -#include "mlt_producer.h" -#include "mlt_transition.h" -#include "mlt_consumer.h" -#include "mlt_filter.h" -#include "mlt_playlist.h" -#include "mlt_properties.h" -#include "mlt_field.h" -#include "mlt_tractor.h" -#include "mlt_tokeniser.h" -#include "mlt_parser.h" -#include "mlt_geometry.h" -#include "mlt_profile.h" -#include "mlt_repository.h" -#include "mlt_log.h" - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/framework/mlt_cache.c b/src/framework/mlt_cache.c deleted file mode 100644 index 5a18871..0000000 --- a/src/framework/mlt_cache.c +++ /dev/null @@ -1,451 +0,0 @@ -/** - * \file mlt_profile.c - * \brief least recently used cache - * \see mlt_profile_s - * - * Copyright (C) 2007-2009 Ushodaya Enterprises Limited - * \author Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_types.h" -#include "mlt_log.h" -#include "mlt_properties.h" -#include "mlt_cache.h" - -#include -#include - -/** the maximum number of data objects to cache per line */ -#define CACHE_SIZE (10) - -/** \brief Cache item class - * - * A cache item is a structure holding information about a data object including - * a reference count that is used to control its lifetime. When you get a - * a cache item from the cache, you hold a reference that prevents the data - * from being released when the cache is full and something new is added. - * When you close the cache item, the reference count is decremented. - * The data object is destroyed when all cache items are closed and the cache - * releases its reference. - */ - -typedef struct mlt_cache_item_s -{ - mlt_cache cache; /**< a reference to the cache to which this belongs */ - void *object; /**< a parent object to the cache data that uniquely identifies this cached item */ - void *data; /**< the opaque pointer to the cached data */ - int size; /**< the size of the cached data */ - int refcount; /**< a reference counter to control when destructor is called */ - mlt_destructor destructor; /**< a function to release or destroy the cached data */ -} mlt_cache_item_s; - -/** \brief Cache class - * - * This is a utility class for implementing a Least Recently Used (LRU) cache - * of data blobs indexed by the address of some other object (e.g., a service). - * Instead of sorting and manipulating linked lists, it tries to be simple and - * elegant by copying pointers between two arrays of fixed size to shuffle the - * order of elements. - * - * This class is useful if you have a service that wants to cache something - * somewhat large, but will not scale if there are many instances of the service. - * Of course, the service will need to know how to recreate the cached element - * if it gets flushed from the cache, - * - * The most obvious examples are the pixbuf and qimage producers that cache their - * respective objects representing a picture read from a file. If the picture - * is no longer in the cache, it can simply re-read it from file. However, a - * picture is often repeated over many frames and makes sense to cache instead - * of continually reading, parsing, and decoding. On the other hand, you might - * want to load hundreds of pictures as individual producers, which would use - * a lot of memory if every picture is held in memory! - */ - -struct mlt_cache_s -{ - int count; /**< the number of items currently in the cache */ - void* *current; /**< pointer to the current array of pointers */ - void* A[ CACHE_SIZE ]; - void* B[ CACHE_SIZE ]; - pthread_mutex_t mutex; /**< a mutex to prevent multi-threaded race conditions */ - mlt_properties active; /**< a list of cache items some of which may no longer - be in \p current but to which there are - outstanding references */ - mlt_properties garbage;/**< a list cache items pending release. A cache item - is copied to this list when it is updated but there - are outstanding references to the old data object. */ -}; - -/** Get the data pointer from the cache item. - * - * \public \memberof mlt_cache_s - * \param item a cache item - * \param[out] size the number of bytes pointed at, if supplied when putting the data into the cache - * \return the data pointer - */ - -void *mlt_cache_item_data( mlt_cache_item item, int *size ) -{ - if ( size && item ) - *size = item->size; - return item? item->data : NULL; -} - -/** Close a cache item given its parent object pointer. - * - * \private \memberof mlt_cache_s - * \param cache a cache - * \param object the object to which the data object belongs - * \param data the data object, which might be in the garbage list (optional) - */ - -static void cache_object_close( mlt_cache cache, void *object, void* data ) -{ - char key[19]; - - // Fetch the cache item from the active list by its owner's address - sprintf( key, "%p", object ); - pthread_mutex_lock( &cache->mutex ); - mlt_cache_item item = mlt_properties_get_data( cache->active, key, NULL ); - if ( item ) - { - mlt_log( NULL, MLT_LOG_DEBUG, "%s: item %p object %p data %p refcount %d\n", __FUNCTION__, - item, item->object, item->data, item->refcount ); - if ( item->destructor && --item->refcount <= 0 ) - { - // Destroy the data object - item->destructor( item->data ); - item->data = NULL; - item->destructor = NULL; - // Do not dispose of the cache item because it could likely be used - // again. - } - } - - // Fetch the cache item from the garbage collection by its data address - if ( data ) - { - sprintf( key, "%p", data ); - item = mlt_properties_get_data( cache->garbage, key, NULL ); - if ( item ) - { - mlt_log( NULL, MLT_LOG_DEBUG, "collecting garbage item %p object %p data %p refcount %d\n", - item, item->object, item->data, item->refcount ); - if ( item->destructor && --item->refcount <= 0 ) - { - item->destructor( item->data ); - item->data = NULL; - item->destructor = NULL; - // We do not need the garbage-collected cache item - mlt_properties_set_data( cache->garbage, key, NULL, 0, NULL, NULL ); - } - } - } - pthread_mutex_unlock( &cache->mutex ); -} - -/** Close a cache item. - * - * Release a reference and call the destructor on the data object when all - * references are released. - * - * \public \memberof mlt_cache_item_s - * \param item a cache item - */ - -void mlt_cache_item_close( mlt_cache_item item ) -{ - if ( item ) - cache_object_close( item->cache, item->object, item->data ); -} - -/** Create a new cache. - * - * \public \memberof mlt_cache_s - * \return a new cache or NULL if there was an error - */ - -mlt_cache mlt_cache_init() -{ - mlt_cache result = calloc( 1, sizeof( struct mlt_cache_s ) ); - if ( result ) - { - result->current = result->A; - pthread_mutex_init( &result->mutex, NULL ); - result->active = mlt_properties_new(); - result->garbage = mlt_properties_new(); - } - return result; -} - -/** Destroy a cache. - * - * \public \memberof mlt_cache_s - * \param cache the cache to detroy - */ - -void mlt_cache_close( mlt_cache cache ) -{ - if ( cache ) - { - while ( cache->count-- ) - { - void *object = cache->current[ cache->count ]; - mlt_log( NULL, MLT_LOG_DEBUG, "%s: %d = %p\n", __FUNCTION__, cache->count, object ); - cache_object_close( cache, object, NULL ); - } - mlt_properties_close( cache->active ); - mlt_properties_close( cache->garbage ); - pthread_mutex_destroy( &cache->mutex ); - free( cache ); - } -} - -/** Remove cache entries for an object. - * - * \public \memberof mlt_cache_s - * \param cache a cache - * \param object the object that owns the cached data - */ - -void mlt_cache_purge( mlt_cache cache, void *object ) -{ - pthread_mutex_lock( &cache->mutex ); - if ( cache && object ) - { - int i, j; - void **alt = cache->current == cache->A ? cache->B : cache->A; - - for ( i = 0, j = 0; i < cache->count; i++ ) - { - void *o = cache->current[ i ]; - - if ( o == object ) - { - pthread_mutex_unlock( &cache->mutex ); - cache_object_close( cache, o, NULL ); - pthread_mutex_lock( &cache->mutex ); - } - else - { - alt[ j++ ] = o; - } - } - cache->count = j; - cache->current = alt; - - // Remove the object's data from the active list regardless of refcount - char key[19]; - sprintf( key, "%p", object ); - mlt_cache_item item = mlt_properties_get_data( cache->active, key, NULL ); - if ( item && item->destructor ) - { - item->destructor( item->data ); - item->data = NULL; - item->destructor = NULL; - mlt_properties_set_data( cache->active, key, NULL, 0, NULL, NULL ); - } - - // Remove the object's items from the garbage collection regardless of refcount - i = mlt_properties_count( cache->garbage ); - while ( i-- ) - { - item = mlt_properties_get_data_at( cache->garbage, i, NULL ); - if ( object == item->object && item->destructor ) - { - sprintf( key, "%p", item->data ); - item->destructor( item->data ); - item->data = NULL; - item->destructor = NULL; - mlt_properties_set_data( cache->garbage, key, NULL, 0, NULL, NULL ); - } - } - } - pthread_mutex_unlock( &cache->mutex ); -} - -/** Shuffle the cache entries between the two arrays and return the cache entry for an object. - * - * \private \memberof mlt_cache_s - * \param cache a cache object - * \param object the object that owns the cached data - * \return a cache entry if there was a hit or NULL for a miss - */ - -static void** shuffle_get_hit( mlt_cache cache, void *object ) -{ - int i = cache->count; - int j = cache->count - 1; - void **hit = NULL; - void **alt = cache->current == cache->A ? cache->B : cache->A; - - if ( cache->count > 0 && cache->count < CACHE_SIZE ) - { - // first determine if we have a hit - while ( i-- && !hit ) - { - void **o = &cache->current[ i ]; - if ( *o == object ) - hit = o; - } - // if there was no hit, we will not be shuffling out an entry - // and are still filling the cache - if ( !hit ) - ++j; - // reset these - i = cache->count; - hit = NULL; - } - - // shuffle the existing entries to the alternate array - while ( i-- ) - { - void **o = &cache->current[ i ]; - - if ( !hit && *o == object ) - { - hit = o; - } - else if ( j > 0 ) - { - alt[ --j ] = *o; -// mlt_log( NULL, MLT_LOG_DEBUG, "%s: shuffle %d = %p\n", __FUNCTION__, j, alt[j] ); - } - } - return hit; -} - -/** Put a chunk of data in the cache. - * - * \public \memberof mlt_cache_s - * \param cache a cache object - * \param object the object to which this data belongs - * \param data an opaque pointer to the data to cache - * \param size the size of the data in bytes - * \param destructor a pointer to a function that can destroy or release a reference to the data. - */ - -void mlt_cache_put( mlt_cache cache, void *object, void* data, int size, mlt_destructor destructor ) -{ - pthread_mutex_lock( &cache->mutex ); - void **hit = shuffle_get_hit( cache, object ); - void **alt = cache->current == cache->A ? cache->B : cache->A; - - // add the object to the cache - if ( hit ) - { - // release the old data - pthread_mutex_unlock( &cache->mutex ); - cache_object_close( cache, *hit, NULL ); - pthread_mutex_lock( &cache->mutex ); - // the MRU end gets the updated data - hit = &alt[ cache->count - 1 ]; - } - else if ( cache->count < CACHE_SIZE ) - { - // more room in cache, add it to MRU end - hit = &alt[ cache->count++ ]; - } - else - { - // release the entry at the LRU end - pthread_mutex_unlock( &cache->mutex ); - cache_object_close( cache, cache->current[0], NULL ); - pthread_mutex_lock( &cache->mutex ); - - // The MRU end gets the new item - hit = &alt[ cache->count - 1 ]; - } - *hit = object; - mlt_log( NULL, MLT_LOG_DEBUG, "%s: put %d = %p, %p\n", __FUNCTION__, cache->count - 1, object, data ); - - // Fetch the cache item - char key[19]; - sprintf( key, "%p", object ); - mlt_cache_item item = mlt_properties_get_data( cache->active, key, NULL ); - if ( !item ) - { - item = calloc( 1, sizeof( mlt_cache_item_s ) ); - if ( item ) - mlt_properties_set_data( cache->active, key, item, 0, free, NULL ); - } - if ( item ) - { - // If updating the cache item but not all references are released - // copy the item to the garbage collection. - if ( item->refcount > 0 && item->data ) - { - mlt_cache_item orphan = calloc( 1, sizeof( mlt_cache_item_s ) ); - if ( orphan ) - { - mlt_log( NULL, MLT_LOG_DEBUG, "adding to garbage collection object %p data %p\n", item->object, item->data ); - *orphan = *item; - sprintf( key, "%p", orphan->data ); - // We store in the garbage collection by data address, not the owner's! - mlt_properties_set_data( cache->garbage, key, orphan, 0, free, NULL ); - } - } - - // Set/update the cache item - item->cache = cache; - item->object = object; - item->data = data; - item->size = size; - item->destructor = destructor; - item->refcount = 1; - } - - // swap the current array - cache->current = alt; - pthread_mutex_unlock( &cache->mutex ); -} - -/** Get a chunk of data from the cache. - * - * \public \memberof mlt_cache_s - * \param cache a cache object - * \param object the object for which you are trying to locate the data - * \return a mlt_cache_item if found or NULL if not found or has been flushed from the cache - */ - -mlt_cache_item mlt_cache_get( mlt_cache cache, void *object ) -{ - mlt_cache_item result = NULL; - pthread_mutex_lock( &cache->mutex ); - void **hit = shuffle_get_hit( cache, object ); - void **alt = cache->current == cache->A ? cache->B : cache->A; - - if ( hit ) - { - // copy the hit to the MRU end - alt[ cache->count - 1 ] = *hit; - hit = &alt[ cache->count - 1 ]; - - char key[19]; - sprintf( key, "%p", *hit ); - result = mlt_properties_get_data( cache->active, key, NULL ); - if ( result && result->data ) - result->refcount++; - mlt_log( NULL, MLT_LOG_DEBUG, "%s: get %d = %p, %p\n", __FUNCTION__, cache->count - 1, *hit, result->data ); - - // swap the current array - cache->current = alt; - } - pthread_mutex_unlock( &cache->mutex ); - - return result; -} diff --git a/src/framework/mlt_cache.h b/src/framework/mlt_cache.h deleted file mode 100644 index aaec935..0000000 --- a/src/framework/mlt_cache.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * \file mlt_cache.h - * \brief least recently used cache - * \see mlt_cache_s - * - * Copyright (C) 2007-2009 Ushodaya Enterprises Limited - * \author Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_CACHE_H -#define _MLT_CACHE_H - -#include "mlt_types.h" - -extern void *mlt_cache_item_data( mlt_cache_item item, int *size ); -extern void mlt_cache_item_close( mlt_cache_item item ); - -extern mlt_cache mlt_cache_init(); -extern void mlt_cache_close( mlt_cache cache ); -extern void mlt_cache_purge( mlt_cache cache, void *object ); -extern void mlt_cache_put( mlt_cache cache, void *object, void* data, int size, mlt_destructor destructor ); -extern mlt_cache_item mlt_cache_get( mlt_cache cache, void *object ); - -#endif diff --git a/src/framework/mlt_consumer.c b/src/framework/mlt_consumer.c deleted file mode 100644 index 93afe44..0000000 --- a/src/framework/mlt_consumer.c +++ /dev/null @@ -1,1010 +0,0 @@ -/** - * \file mlt_consumer.c - * \brief abstraction for all consumer services - * \see mlt_consumer_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_consumer.h" -#include "mlt_factory.h" -#include "mlt_producer.h" -#include "mlt_frame.h" -#include "mlt_profile.h" -#include "mlt_log.h" - -#include -#include -#include -#include - -/** Define this if you want an automatic deinterlace (if necessary) when the - * consumer's producer is not running at normal speed. - */ -#undef DEINTERLACE_ON_NOT_NORMAL_SPEED - -static void mlt_consumer_frame_render( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ); -static void mlt_consumer_frame_show( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ); -static void mlt_consumer_property_changed( mlt_service owner, mlt_consumer this, char *name ); -static void apply_profile_properties( mlt_consumer this, mlt_profile profile, mlt_properties properties ); - -/** Initialize a consumer service. - * - * \public \memberof mlt_consumer_s - * \param this the consumer to initialize - * \param child a pointer to the object for the subclass - * \param profile the \p mlt_profile_s to use (optional but recommended, - * uses the environment variable MLT if this is NULL) - * \return true if there was an error - */ - -int mlt_consumer_init( mlt_consumer this, void *child, mlt_profile profile ) -{ - int error = 0; - memset( this, 0, sizeof( struct mlt_consumer_s ) ); - this->child = child; - error = mlt_service_init( &this->parent, this ); - if ( error == 0 ) - { - // Get the properties from the service - mlt_properties properties = MLT_SERVICE_PROPERTIES( &this->parent ); - - // Apply profile to properties - if ( profile == NULL ) - { - // Normally the application creates the profile and controls its lifetime - // This is the fallback exception handling - profile = mlt_profile_init( NULL ); - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - mlt_properties_set_data( properties, "_profile", profile, 0, (mlt_destructor)mlt_profile_close, NULL ); - } - apply_profile_properties( this, profile, properties ); - - // Default rescaler for all consumers - mlt_properties_set( properties, "rescale", "bilinear" ); - - // Default read ahead buffer size - mlt_properties_set_int( properties, "buffer", 25 ); - - // Default audio frequency and channels - mlt_properties_set_int( properties, "frequency", 48000 ); - mlt_properties_set_int( properties, "channels", 2 ); - - // Default of all consumers is real time - mlt_properties_set_int( properties, "real_time", 1 ); - - // Default to environment test card - mlt_properties_set( properties, "test_card", mlt_environment( "MLT_TEST_CARD" ) ); - - // Hmm - default all consumers to yuv422 :-/ - this->format = mlt_image_yuv422; - - mlt_events_register( properties, "consumer-frame-show", ( mlt_transmitter )mlt_consumer_frame_show ); - mlt_events_register( properties, "consumer-frame-render", ( mlt_transmitter )mlt_consumer_frame_render ); - mlt_events_register( properties, "consumer-stopped", NULL ); - - // Register a property-changed listener to handle the profile property - - // subsequent properties can override the profile - this->event_listener = mlt_events_listen( properties, this, "property-changed", ( mlt_listener )mlt_consumer_property_changed ); - - // Create the push mutex and condition - pthread_mutex_init( &this->put_mutex, NULL ); - pthread_cond_init( &this->put_cond, NULL ); - - } - return error; -} - -/** Convert the profile into properties on the consumer. - * - * \private \memberof mlt_consumer_s - * \param this a consumer - * \param profile a profile - * \param properties a properties list (typically, the consumer's) - */ - -static void apply_profile_properties( mlt_consumer this, mlt_profile profile, mlt_properties properties ) -{ - mlt_event_block( this->event_listener ); - mlt_properties_set_double( properties, "fps", mlt_profile_fps( profile ) ); - mlt_properties_set_int( properties, "frame_rate_num", profile->frame_rate_num ); - mlt_properties_set_int( properties, "frame_rate_den", profile->frame_rate_den ); - mlt_properties_set_int( properties, "width", profile->width ); - mlt_properties_set_int( properties, "height", profile->height ); - mlt_properties_set_int( properties, "progressive", profile->progressive ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) ); - mlt_properties_set_int( properties, "sample_aspect_num", profile->sample_aspect_num ); - mlt_properties_set_int( properties, "sample_aspect_den", profile->sample_aspect_den ); - mlt_properties_set_double( properties, "display_ratio", mlt_profile_dar( profile ) ); - mlt_properties_set_int( properties, "display_aspect_num", profile->display_aspect_num ); - mlt_properties_set_int( properties, "display_aspect_num", profile->display_aspect_num ); - mlt_event_unblock( this->event_listener ); -} - -/** The property-changed event listener - * - * \private \memberof mlt_consumer_s - * \param owner the service a service (ignored) - * \param this the consumer - * \param name the name of the property that changed - */ - -static void mlt_consumer_property_changed( mlt_service owner, mlt_consumer this, char *name ) -{ - if ( !strcmp( name, "profile" ) ) - { - // Get the properies - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Get the current profile - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - - // Load the new profile - mlt_profile new_profile = mlt_profile_init( mlt_properties_get( properties, name ) ); - - if ( new_profile ) - { - // Copy the profile - if ( profile != NULL ) - { - free( profile->description ); - memcpy( profile, new_profile, sizeof( struct mlt_profile_s ) ); - profile->description = strdup( new_profile->description ); - mlt_profile_close( new_profile ); - } - else - { - profile = new_profile; - } - - // Apply to properties - apply_profile_properties( this, profile, properties ); - } - } - else if ( !strcmp( name, "frame_rate_num" ) ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - if ( profile ) - { - profile->frame_rate_num = mlt_properties_get_int( properties, "frame_rate_num" ); - mlt_properties_set_double( properties, "fps", mlt_profile_fps( profile ) ); - } - } - else if ( !strcmp( name, "frame_rate_den" ) ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - if ( profile ) - { - profile->frame_rate_den = mlt_properties_get_int( properties, "frame_rate_den" ); - mlt_properties_set_double( properties, "fps", mlt_profile_fps( profile ) ); - } - } - else if ( !strcmp( name, "width" ) ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - if ( profile ) - profile->width = mlt_properties_get_int( properties, "width" ); - } - else if ( !strcmp( name, "height" ) ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - if ( profile ) - profile->height = mlt_properties_get_int( properties, "height" ); - } - else if ( !strcmp( name, "progressive" ) ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - if ( profile ) - profile->progressive = mlt_properties_get_int( properties, "progressive" ); - } - else if ( !strcmp( name, "sample_aspect_num" ) ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - profile->sample_aspect_num = mlt_properties_get_int( properties, "sample_aspect_num" ); - if ( profile ) - mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) ); - } - else if ( !strcmp( name, "sample_aspect_den" ) ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - profile->sample_aspect_den = mlt_properties_get_int( properties, "sample_aspect_den" ); - if ( profile ) - mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) ); - } - else if ( !strcmp( name, "display_aspect_num" ) ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - if ( profile ) - { - profile->display_aspect_num = mlt_properties_get_int( properties, "display_aspect_num" ); - mlt_properties_set_double( properties, "display_ratio", mlt_profile_dar( profile ) ); - } - } - else if ( !strcmp( name, "display_aspect_den" ) ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - if ( profile ) - { - profile->display_aspect_den = mlt_properties_get_int( properties, "display_aspect_den" ); - mlt_properties_set_double( properties, "display_ratio", mlt_profile_dar( profile ) ); - } - } -} - -/** The transmitter for the consumer-frame-show event - * - * Invokes the listener. - * - * \private \memberof mlt_consumer_s - * \param listener a function pointer that will be invoked - * \param owner a properties list that will be passed to \p listener - * \param this a service that will be passed to \p listener - * \param args an array of pointers - the first entry is passed as a string to \p listener - */ - -static void mlt_consumer_frame_show( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ) -{ - if ( listener != NULL ) - listener( owner, this, ( mlt_frame )args[ 0 ] ); -} - -/** The transmitter for the consumer-frame-render event - * - * Invokes the listener. - * - * \private \memberof mlt_consumer_s - * \param listener a function pointer that will be invoked - * \param owner a properties list that will be passed to \p listener - * \param this a service that will be passed to \p listener - * \param args an array of pointers - the first entry is passed as a string to \p listener - */ - -static void mlt_consumer_frame_render( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ) -{ - if ( listener != NULL ) - listener( owner, this, ( mlt_frame )args[ 0 ] ); -} - -/** Create a new consumer. - * - * \public \memberof mlt_consumer_s - * \param profile a profile (optional, but recommended) - * \return a new consumer - */ - -mlt_consumer mlt_consumer_new( mlt_profile profile ) -{ - // Create the memory for the structure - mlt_consumer this = malloc( sizeof( struct mlt_consumer_s ) ); - - // Initialise it - if ( this != NULL ) - mlt_consumer_init( this, NULL, profile ); - - // Return it - return this; -} - -/** Get the parent service object. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - * \return the parent service class - * \see MLT_CONSUMER_SERVICE - */ - -mlt_service mlt_consumer_service( mlt_consumer this ) -{ - return this != NULL ? &this->parent : NULL; -} - -/** Get the consumer properties. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - * \return the consumer's properties list - * \see MLT_CONSUMER_PROPERTIES - */ - -mlt_properties mlt_consumer_properties( mlt_consumer this ) -{ - return this != NULL ? MLT_SERVICE_PROPERTIES( &this->parent ) : NULL; -} - -/** Connect the consumer to the producer. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - * \param producer a producer - * \return > 0 warning, == 0 success, < 0 serious error, - * 1 = this service does not accept input, - * 2 = the producer is invalid, - * 3 = the producer is already registered with this consumer - */ - -int mlt_consumer_connect( mlt_consumer this, mlt_service producer ) -{ - return mlt_service_connect_producer( &this->parent, producer, 0 ); -} - -/** Start the consumer. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - * \return true if there was an error - */ - -int mlt_consumer_start( mlt_consumer this ) -{ - // Stop listening to the property-changed event - mlt_event_block( this->event_listener ); - - // Get the properies - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Determine if there's a test card producer - char *test_card = mlt_properties_get( properties, "test_card" ); - - // Just to make sure nothing is hanging around... - mlt_frame_close( this->put ); - this->put = NULL; - this->put_active = 1; - - // Deal with it now. - if ( test_card != NULL ) - { - if ( mlt_properties_get_data( properties, "test_card_producer", NULL ) == NULL ) - { - // Create a test card producer - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - mlt_producer producer = mlt_factory_producer( profile, NULL, test_card ); - - // Do we have a producer - if ( producer != NULL ) - { - // Test card should loop I guess... - mlt_properties_set( MLT_PRODUCER_PROPERTIES( producer ), "eof", "loop" ); - //mlt_producer_set_speed( producer, 0 ); - //mlt_producer_set_in_and_out( producer, 0, 0 ); - - // Set the test card on the consumer - mlt_properties_set_data( properties, "test_card_producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); - } - } - } - else - { - // Allow the hash table to speed things up - mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL ); - } - - // Set the frame duration in microseconds for the frame-dropping heuristic - int frame_duration = 1000000 / mlt_properties_get_int( properties, "frame_rate_num" ) * - mlt_properties_get_int( properties, "frame_rate_den" ); - mlt_properties_set_int( properties, "frame_duration", frame_duration ); - - // Check and run an ante command - if ( mlt_properties_get( properties, "ante" ) ) - if ( system( mlt_properties_get( properties, "ante" ) ) == -1 ) - mlt_log( MLT_CONSUMER_SERVICE( this ), MLT_LOG_ERROR, "system(%s) failed!\n", mlt_properties_get( properties, "ante" ) ); - - // Set the real_time preference - this->real_time = mlt_properties_get_int( properties, "real_time" ); - - // Start the service - if ( this->start != NULL ) - return this->start( this ); - - return 0; -} - -/** An alternative method to feed frames into the consumer. - * - * Only valid if the consumer itself is not connected. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - * \param frame a frame - * \return true (ignore this for now) - */ - -int mlt_consumer_put_frame( mlt_consumer this, mlt_frame frame ) -{ - int error = 1; - - // Get the service assoicated to the consumer - mlt_service service = MLT_CONSUMER_SERVICE( this ); - - if ( mlt_service_producer( service ) == NULL ) - { - struct timeval now; - struct timespec tm; - pthread_mutex_lock( &this->put_mutex ); - while ( this->put_active && this->put != NULL ) - { - gettimeofday( &now, NULL ); - tm.tv_sec = now.tv_sec + 1; - tm.tv_nsec = now.tv_usec * 1000; - pthread_cond_timedwait( &this->put_cond, &this->put_mutex, &tm ); - } - if ( this->put_active && this->put == NULL ) - this->put = frame; - else - mlt_frame_close( frame ); - pthread_cond_broadcast( &this->put_cond ); - pthread_mutex_unlock( &this->put_mutex ); - } - else - { - mlt_frame_close( frame ); - } - - return error; -} - -/** Protected method for consumer to get frames from connected service - * - * \public \memberof mlt_consumer_s - * \param this a consumer - * \return a frame - */ - -mlt_frame mlt_consumer_get_frame( mlt_consumer this ) -{ - // Frame to return - mlt_frame frame = NULL; - - // Get the service assoicated to the consumer - mlt_service service = MLT_CONSUMER_SERVICE( this ); - - // Get the consumer properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Get the frame - if ( mlt_service_producer( service ) == NULL && mlt_properties_get_int( properties, "put_mode" ) ) - { - struct timeval now; - struct timespec tm; - pthread_mutex_lock( &this->put_mutex ); - while ( this->put_active && this->put == NULL ) - { - gettimeofday( &now, NULL ); - tm.tv_sec = now.tv_sec + 1; - tm.tv_nsec = now.tv_usec * 1000; - pthread_cond_timedwait( &this->put_cond, &this->put_mutex, &tm ); - } - frame = this->put; - this->put = NULL; - pthread_cond_broadcast( &this->put_cond ); - pthread_mutex_unlock( &this->put_mutex ); - if ( frame != NULL ) - mlt_service_apply_filters( service, frame, 0 ); - } - else if ( mlt_service_producer( service ) != NULL ) - { - mlt_service_get_frame( service, &frame, 0 ); - } - else - { - frame = mlt_frame_init( service ); - } - - if ( frame != NULL ) - { - // Get the frame properties - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Get the test card producer - mlt_producer test_card = mlt_properties_get_data( properties, "test_card_producer", NULL ); - - // Attach the test frame producer to it. - if ( test_card != NULL ) - mlt_properties_set_data( frame_properties, "test_card_producer", test_card, 0, NULL, NULL ); - - // Attach the rescale property - mlt_properties_set( frame_properties, "rescale.interp", mlt_properties_get( properties, "rescale" ) ); - - // Aspect ratio and other jiggery pokery - mlt_properties_set_double( frame_properties, "consumer_aspect_ratio", mlt_properties_get_double( properties, "aspect_ratio" ) ); - mlt_properties_set_int( frame_properties, "consumer_deinterlace", mlt_properties_get_int( properties, "progressive" ) | mlt_properties_get_int( properties, "deinterlace" ) ); - mlt_properties_set( frame_properties, "deinterlace_method", mlt_properties_get( properties, "deinterlace_method" ) ); - } - - // Return the frame - return frame; -} - -/** Compute the time difference between now and a time value. - * - * \private \memberof mlt_consumer_s - * \param time1 a time value to be compared against now - * \return the difference in microseconds - */ - -static inline long time_difference( struct timeval *time1 ) -{ - struct timeval time2; - time2.tv_sec = time1->tv_sec; - time2.tv_usec = time1->tv_usec; - gettimeofday( time1, NULL ); - return time1->tv_sec * 1000000 + time1->tv_usec - time2.tv_sec * 1000000 - time2.tv_usec; -} - -/** The thread procedure for asynchronously pulling frames through the service - * network connected to a consumer. - * - * \private \memberof mlt_consumer_s - * \param arg a consumer - */ - -static void *consumer_read_ahead_thread( void *arg ) -{ - // The argument is the consumer - mlt_consumer this = arg; - - // Get the properties of the consumer - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Get the width and height - int width = mlt_properties_get_int( properties, "width" ); - int height = mlt_properties_get_int( properties, "height" ); - - // See if video is turned off - int video_off = mlt_properties_get_int( properties, "video_off" ); - int preview_off = mlt_properties_get_int( properties, "preview_off" ); - int preview_format = mlt_properties_get_int( properties, "preview_format" ); - - // Get the audio settings - mlt_audio_format afmt = mlt_audio_pcm; - int counter = 0; - double fps = mlt_properties_get_double( properties, "fps" ); - int channels = mlt_properties_get_int( properties, "channels" ); - int frequency = mlt_properties_get_int( properties, "frequency" ); - int samples = 0; - int16_t *pcm = NULL; - - // See if audio is turned off - int audio_off = mlt_properties_get_int( properties, "audio_off" ); - - // Get the maximum size of the buffer - int buffer = mlt_properties_get_int( properties, "buffer" ) + 1; - - // General frame variable - mlt_frame frame = NULL; - uint8_t *image = NULL; - - // Time structures - struct timeval ante; - - // Average time for get_frame and get_image - int count = 1; - int skipped = 0; - int64_t time_wait = 0; - int64_t time_frame = 0; - int64_t time_process = 0; - int skip_next = 0; - mlt_service lock_object = NULL; - - if ( preview_off && preview_format != 0 ) - this->format = preview_format; - - // Get the first frame - frame = mlt_consumer_get_frame( this ); - - // Get the lock object - lock_object = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "consumer_lock_service", NULL ); - - // Lock it - if ( lock_object ) mlt_service_lock( lock_object ); - - // Get the image of the first frame - if ( !video_off ) - { - mlt_events_fire( MLT_CONSUMER_PROPERTIES( this ), "consumer-frame-render", frame, NULL ); - mlt_frame_get_image( frame, &image, &this->format, &width, &height, 0 ); - } - - if ( !audio_off ) - { - samples = mlt_sample_calculator( fps, frequency, counter++ ); - mlt_frame_get_audio( frame, &pcm, &afmt, &frequency, &channels, &samples ); - } - - // Unlock the lock object - if ( lock_object ) mlt_service_unlock( lock_object ); - - // Mark as rendered - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "rendered", 1 ); - - // Get the starting time (can ignore the times above) - gettimeofday( &ante, NULL ); - - // Continue to read ahead - while ( this->ahead ) - { - // Fetch width/height again - width = mlt_properties_get_int( properties, "width" ); - height = mlt_properties_get_int( properties, "height" ); - - // Put the current frame into the queue - pthread_mutex_lock( &this->mutex ); - while( this->ahead && mlt_deque_count( this->queue ) >= buffer ) - pthread_cond_wait( &this->cond, &this->mutex ); - mlt_deque_push_back( this->queue, frame ); - pthread_cond_broadcast( &this->cond ); - pthread_mutex_unlock( &this->mutex ); - - time_wait += time_difference( &ante ); - - // Get the next frame - frame = mlt_consumer_get_frame( this ); - time_frame += time_difference( &ante ); - - // If there's no frame, we're probably stopped... - if ( frame == NULL ) - continue; - - // Attempt to fetch the lock object - lock_object = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "consumer_lock_service", NULL ); - - // Increment the count - count ++; - - // Lock if there's a lock object - if ( lock_object ) mlt_service_lock( lock_object ); - - // All non normal playback frames should be shown - if ( mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "_speed" ) != 1 ) - { -#ifdef DEINTERLACE_ON_NOT_NORMAL_SPEED - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "consumer_deinterlace", 1 ); -#endif - skipped = 0; - time_frame = 0; - time_process = 0; - time_wait = 0; - count = 1; - skip_next = 0; - } - - // Get the image - if ( !skip_next || this->real_time == -1 ) - { - // Get the image, mark as rendered and time it - if ( !video_off ) - { - mlt_events_fire( MLT_CONSUMER_PROPERTIES( this ), "consumer-frame-render", frame, NULL ); - mlt_frame_get_image( frame, &image, &this->format, &width, &height, 0 ); - } - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "rendered", 1 ); - } - else - { - // Increment the number of sequentially skipped frames - skipped ++; - skip_next = 0; - - // If we've reached an unacceptable level, reset everything - if ( skipped > 5 ) - { - skipped = 0; - time_frame = 0; - time_process = 0; - time_wait = 0; - count = 1; - } - } - - // Always process audio - if ( !audio_off ) - { - samples = mlt_sample_calculator( fps, frequency, counter++ ); - mlt_frame_get_audio( frame, &pcm, &afmt, &frequency, &channels, &samples ); - } - - // Increment the time take for this frame - time_process += time_difference( &ante ); - - // Determine if the next frame should be skipped - if ( mlt_deque_count( this->queue ) <= 5 ) - { - int frame_duration = mlt_properties_get_int( properties, "frame_duration" ); - if ( ( ( time_wait + time_frame + time_process ) / count ) > frame_duration ) - skip_next = 1; - } - - // Unlock if there's a lock object - if ( lock_object ) mlt_service_unlock( lock_object ); - } - - // Remove the last frame - mlt_frame_close( frame ); - - return NULL; -} - -/** Start the read/render thread. - * - * \private \memberof mlt_consumer_s - * \param this a consumer - */ - -static void consumer_read_ahead_start( mlt_consumer this ) -{ - // We're running now - this->ahead = 1; - - // Create the frame queue - this->queue = mlt_deque_init( ); - - // Create the mutex - pthread_mutex_init( &this->mutex, NULL ); - - // Create the condition - pthread_cond_init( &this->cond, NULL ); - - // Create the read ahead - if ( mlt_properties_get( MLT_CONSUMER_PROPERTIES( this ), "priority" ) ) - { - struct sched_param priority; - priority.sched_priority = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( this ), "priority" ); - pthread_attr_t thread_attributes; - pthread_attr_init( &thread_attributes ); - pthread_attr_setschedpolicy( &thread_attributes, SCHED_OTHER ); - pthread_attr_setschedparam( &thread_attributes, &priority ); - pthread_attr_setinheritsched( &thread_attributes, PTHREAD_EXPLICIT_SCHED ); - pthread_attr_setscope( &thread_attributes, PTHREAD_SCOPE_SYSTEM ); - if ( pthread_create( &this->ahead_thread, &thread_attributes, consumer_read_ahead_thread, this ) < 0 ) - pthread_create( &this->ahead_thread, NULL, consumer_read_ahead_thread, this ); - pthread_attr_destroy( &thread_attributes ); - } - else - { - pthread_create( &this->ahead_thread, NULL, consumer_read_ahead_thread, this ); - } -} - -/** Stop the read/render thread. - * - * \private \memberof mlt_consumer_s - * \param this a consumer - */ - -static void consumer_read_ahead_stop( mlt_consumer this ) -{ - // Make sure we're running - if ( this->ahead ) - { - // Inform thread to stop - this->ahead = 0; - - // Broadcast to the condition in case it's waiting - pthread_mutex_lock( &this->mutex ); - pthread_cond_broadcast( &this->cond ); - pthread_mutex_unlock( &this->mutex ); - - // Broadcast to the put condition in case it's waiting - pthread_mutex_lock( &this->put_mutex ); - pthread_cond_broadcast( &this->put_cond ); - pthread_mutex_unlock( &this->put_mutex ); - - // Join the thread - pthread_join( this->ahead_thread, NULL ); - - // Destroy the mutex - pthread_mutex_destroy( &this->mutex ); - - // Destroy the condition - pthread_cond_destroy( &this->cond ); - - // Wipe the queue - while ( mlt_deque_count( this->queue ) ) - mlt_frame_close( mlt_deque_pop_back( this->queue ) ); - - // Close the queue - mlt_deque_close( this->queue ); - } -} - -/** Flush the read/render thread's buffer. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - */ - -void mlt_consumer_purge( mlt_consumer this ) -{ - if ( this->ahead ) - { - pthread_mutex_lock( &this->mutex ); - while ( mlt_deque_count( this->queue ) ) - mlt_frame_close( mlt_deque_pop_back( this->queue ) ); - pthread_cond_broadcast( &this->cond ); - pthread_mutex_unlock( &this->mutex ); - } -} - -/** Get the next frame from the producer connected to a consumer. - * - * Typically, one uses this instead of \p mlt_consumer_get_frame to make - * the asynchronous/real-time behavior configurable at runtime. - * You should close the frame returned from this when you are done with it. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - * \return a frame - */ - -mlt_frame mlt_consumer_rt_frame( mlt_consumer this ) -{ - // Frame to return - mlt_frame frame = NULL; - - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Check if the user has requested real time or not - if ( this->real_time ) - { - int size = 1; - - // Is the read ahead running? - if ( this->ahead == 0 ) - { - int buffer = mlt_properties_get_int( properties, "buffer" ); - int prefill = mlt_properties_get_int( properties, "prefill" ); - consumer_read_ahead_start( this ); - if ( buffer > 1 ) - size = prefill > 0 && prefill < buffer ? prefill : buffer; - } - - // Get frame from queue - pthread_mutex_lock( &this->mutex ); - while( this->ahead && mlt_deque_count( this->queue ) < size ) - pthread_cond_wait( &this->cond, &this->mutex ); - frame = mlt_deque_pop_front( this->queue ); - pthread_cond_broadcast( &this->cond ); - pthread_mutex_unlock( &this->mutex ); - } - else - { - // Get the frame in non real time - frame = mlt_consumer_get_frame( this ); - - // This isn't true, but from the consumers perspective it is - if ( frame != NULL ) - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "rendered", 1 ); - } - - return frame; -} - -/** Callback for the implementation to indicate a stopped condition. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - */ - -void mlt_consumer_stopped( mlt_consumer this ) -{ - mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( this ), "running", 0 ); - mlt_events_fire( MLT_CONSUMER_PROPERTIES( this ), "consumer-stopped", NULL ); - mlt_event_unblock( this->event_listener ); -} - -/** Stop the consumer. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - * \return true if there was an error - */ - -int mlt_consumer_stop( mlt_consumer this ) -{ - // Get the properies - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Just in case... - mlt_log( MLT_CONSUMER_SERVICE( this ), MLT_LOG_DEBUG, "stopping put waiting\n" ); - pthread_mutex_lock( &this->put_mutex ); - this->put_active = 0; - pthread_cond_broadcast( &this->put_cond ); - pthread_mutex_unlock( &this->put_mutex ); - - // Stop the consumer - mlt_log( MLT_CONSUMER_SERVICE( this ), MLT_LOG_DEBUG, "stopping consumer\n" ); - if ( this->stop != NULL ) - this->stop( this ); - - // Check if the user has requested real time or not and stop if necessary - mlt_log( MLT_CONSUMER_SERVICE( this ), MLT_LOG_DEBUG, "stopping read_ahead\n" ); - if ( mlt_properties_get_int( properties, "real_time" ) ) - consumer_read_ahead_stop( this ); - - // Kill the test card - mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL ); - - // Check and run a post command - if ( mlt_properties_get( properties, "post" ) ) - if (system( mlt_properties_get( properties, "post" ) ) == -1 ) - mlt_log( MLT_CONSUMER_SERVICE( this ), MLT_LOG_ERROR, "system(%s) failed!\n", mlt_properties_get( properties, "post" ) ); - - mlt_log( MLT_CONSUMER_SERVICE( this ), MLT_LOG_DEBUG, "stopped\n" ); - - return 0; -} - -/** Determine if the consumer is stopped. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - * \return true if the consumer is stopped - */ - -int mlt_consumer_is_stopped( mlt_consumer this ) -{ - // Check if the consumer is stopped - if ( this->is_stopped != NULL ) - return this->is_stopped( this ); - - return 0; -} - -/** Close and destroy the consumer. - * - * \public \memberof mlt_consumer_s - * \param this a consumer - */ - -void mlt_consumer_close( mlt_consumer this ) -{ - if ( this != NULL && mlt_properties_dec_ref( MLT_CONSUMER_PROPERTIES( this ) ) <= 0 ) - { - // Get the childs close function - void ( *consumer_close )( ) = this->close; - - if ( consumer_close ) - { - // Just in case... - //mlt_consumer_stop( this ); - - this->close = NULL; - consumer_close( this ); - } - else - { - // Make sure it only gets called once - this->parent.close = NULL; - - // Destroy the push mutex and condition - pthread_mutex_destroy( &this->put_mutex ); - pthread_cond_destroy( &this->put_cond ); - - mlt_service_close( &this->parent ); - } - } -} diff --git a/src/framework/mlt_consumer.h b/src/framework/mlt_consumer.h deleted file mode 100644 index 736d0a2..0000000 --- a/src/framework/mlt_consumer.h +++ /dev/null @@ -1,135 +0,0 @@ -/** - * \file mlt_consumer.h - * \brief abstraction for all consumer services - * \see mlt_consumer_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_CONSUMER_H_ -#define _MLT_CONSUMER_H_ - -#include "mlt_service.h" -#include "mlt_events.h" -#include - -/** \brief Consumer abstract service class - * - * A consumer is a service that pulls audio and video from the connected - * producers, filters, and transitions. Typically a consumer is used to - * output audio and/or video to a device, file, or socket. - * - * \extends mlt_service_s - * \properties \em rescale the scaling algorithm to pass on to all scaling - * filters, defaults to "bilinear" - * \properties \em buffer the number of frames to use in the asynchronous - * render thread, defaults to 25 - * \properties \em frequency the audio sample rate to use in Hertz, defaults to 48000 - * \properties \em channels the number of audio channels to use, defaults to 2 - * \properties \em real_time the asynchronous behavior: 1 (default) for asynchronous - * with frame dropping, -1 for asynchronous without frame dropping, 0 to disable (synchronous) - * \properties \em test_card the name of a resource to use as the test card, defaults to - * environment variable MLT_TEST_CARD. If undefined, the hard-coded default test card is - * white silence. A test card is what appears when nothing is produced. - * \event \em consumer-frame-show Subclass implementations should fire this. - * \event \em consumer-frame-render The abstract class fires this. - * \event \em consumer-stopped - * \properties \em fps video frames per second as floating point (read only) - * \properties \em frame_rate_num the numerator of the video frame rate, overrides \p mlt_profile_s - * \properties \em frame_rate_den the denominator of the video frame rate, overrides \p mlt_profile_s - * \properties \em width the horizontal video resolution, overrides \p mlt_profile_s - * \properties \em height the vertical video resolution, overrides \p mlt_profile_s - * \properties \em progressive a flag that indicates if the video is interlaced - * or progressive, overrides \p mlt_profile_s - * \properties \em aspect_ratio the video sample (pixel) aspect ratio as floating point (read only) - * \properties \em sample_aspect_num the numerator of the sample aspect ratio, overrides \p mlt_profile_s - * \properties \em sample_aspect_den the denominator of the sample aspect ratio, overrides \p mlt_profile_s - * \properties \em display_ratio the video frame aspect ratio as floating point (read only) - * \properties \em display_aspect_num the numerator of the video frame aspect ratio, overrides \p mlt_profile_s - * \properties \em display_aspect_den the denominator of the video frame aspect ratio, overrides \p mlt_profile_s - * - */ - -struct mlt_consumer_s -{ - /** A consumer is a service. */ - struct mlt_service_s parent; - - /** Start the consumer to pull frames (virtual function). - * - * \param mlt_consumer a consumer - * \return true if there was an error - */ - int ( *start )( mlt_consumer ); - - /** Stop the consumer (virtual function). - * - * \param mlt_consumer a consumer - * \return true if there was an error - */ - int ( *stop )( mlt_consumer ); - - /** Get whether the consumer is running or stopped (virtual function). - * - * \param mlt_consumer a consumer - * \return true if the consumer is stopped - */ - int ( *is_stopped )( mlt_consumer ); - - /** The destructor virtual function - * - * \param mlt_consumer a consumer - */ - void ( *close )( mlt_consumer ); - - void *local; /**< \private instance object */ - void *child; /**< \private the object of a subclass */ - - int real_time; - int ahead; - mlt_image_format format; - mlt_deque queue; - pthread_t ahead_thread; - pthread_mutex_t mutex; - pthread_cond_t cond; - pthread_mutex_t put_mutex; - pthread_cond_t put_cond; - mlt_frame put; - int put_active; - mlt_event event_listener; -}; - -#define MLT_CONSUMER_SERVICE( consumer ) ( &( consumer )->parent ) -#define MLT_CONSUMER_PROPERTIES( consumer ) MLT_SERVICE_PROPERTIES( MLT_CONSUMER_SERVICE( consumer ) ) - -extern int mlt_consumer_init( mlt_consumer self, void *child, mlt_profile profile ); -extern mlt_consumer mlt_consumer_new( mlt_profile profile ); -extern mlt_service mlt_consumer_service( mlt_consumer self ); -extern mlt_properties mlt_consumer_properties( mlt_consumer self ); -extern int mlt_consumer_connect( mlt_consumer self, mlt_service producer ); -extern int mlt_consumer_start( mlt_consumer self ); -extern void mlt_consumer_purge( mlt_consumer self ); -extern int mlt_consumer_put_frame( mlt_consumer self, mlt_frame frame ); -extern mlt_frame mlt_consumer_get_frame( mlt_consumer self ); -extern mlt_frame mlt_consumer_rt_frame( mlt_consumer self ); -extern int mlt_consumer_stop( mlt_consumer self ); -extern int mlt_consumer_is_stopped( mlt_consumer self ); -extern void mlt_consumer_stopped( mlt_consumer self ); -extern void mlt_consumer_close( mlt_consumer ); - -#endif diff --git a/src/framework/mlt_deque.c b/src/framework/mlt_deque.c deleted file mode 100644 index ad65a2b..0000000 --- a/src/framework/mlt_deque.c +++ /dev/null @@ -1,398 +0,0 @@ -/** - * \file mlt_deque.c - * \brief double ended queue - * \see mlt_deque_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// Local header files -#include "mlt_deque.h" - -// System header files -#include -#include - -/** \brief Deque entry class - * - */ - -typedef union -{ - void *addr; - int value; - double floating; -} -deque_entry; - -/** \brief Double-Ended Queue (deque) class - * - * The double-ended queue is a very versatile data structure. MLT uses it as - * list, stack, and circular queue. - */ - -struct mlt_deque_s -{ - deque_entry *list; - int size; - int count; -}; - -/** Create a deque. - * - * \public \memberof mlt_deque_s - * \return a new deque - */ - -mlt_deque mlt_deque_init( ) -{ - mlt_deque this = malloc( sizeof( struct mlt_deque_s ) ); - if ( this != NULL ) - { - this->list = NULL; - this->size = 0; - this->count = 0; - } - return this; -} - -/** Return the number of items in the deque. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return the number of items - */ - -int mlt_deque_count( mlt_deque this ) -{ - return this->count; -} - -/** Allocate space on the deque. - * - * \private \memberof mlt_deque_s - * \param this a deque - * \return true if there was an error - */ - -static int mlt_deque_allocate( mlt_deque this ) -{ - if ( this->count == this->size ) - { - this->list = realloc( this->list, sizeof( deque_entry ) * ( this->size + 20 ) ); - this->size += 20; - } - return this->list == NULL; -} - -/** Push an item to the end. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \param item an opaque pointer - * \return true if there was an error - */ - -int mlt_deque_push_back( mlt_deque this, void *item ) -{ - int error = mlt_deque_allocate( this ); - - if ( error == 0 ) - this->list[ this->count ++ ].addr = item; - - return error; -} - -/** Pop an item. - * - * \public \memberof mlt_deque_s - * \param this a pointer - * \return an opaque pointer - */ - -void *mlt_deque_pop_back( mlt_deque this ) -{ - return this->count > 0 ? this->list[ -- this->count ].addr : NULL; -} - -/** Queue an item at the start. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \param item an opaque pointer - * \return true if there was an error - */ - -int mlt_deque_push_front( mlt_deque this, void *item ) -{ - int error = mlt_deque_allocate( this ); - - if ( error == 0 ) - { - memmove( &this->list[ 1 ], this->list, ( this->count ++ ) * sizeof( deque_entry ) ); - this->list[ 0 ].addr = item; - } - - return error; -} - -/** Remove an item from the start. - * - * \public \memberof mlt_deque_s - * \param this a pointer - * \return an opaque pointer - */ - -void *mlt_deque_pop_front( mlt_deque this ) -{ - void *item = NULL; - - if ( this->count > 0 ) - { - item = this->list[ 0 ].addr; - memmove( this->list, &this->list[ 1 ], ( -- this->count ) * sizeof( deque_entry ) ); - } - - return item; -} - -/** Inquire on item at back of deque but don't remove. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return an opaque pointer - */ - -void *mlt_deque_peek_back( mlt_deque this ) -{ - return this->count > 0 ? this->list[ this->count - 1 ].addr : NULL; -} - -/** Inquire on item at front of deque but don't remove. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return an opaque pointer - */ - -void *mlt_deque_peek_front( mlt_deque this ) -{ - return this->count > 0 ? this->list[ 0 ].addr : NULL; -} - -/** Push an integer to the end. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \param item an integer - * \return true if there was an error - */ - -int mlt_deque_push_back_int( mlt_deque this, int item ) -{ - int error = mlt_deque_allocate( this ); - - if ( error == 0 ) - this->list[ this->count ++ ].value = item; - - return error; -} - -/** Pop an integer. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return an integer - */ - -int mlt_deque_pop_back_int( mlt_deque this ) -{ - return this->count > 0 ? this->list[ -- this->count ].value : 0; -} - -/** Queue an integer at the start. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \param item an integer - * \return true if there was an error - */ - -int mlt_deque_push_front_int( mlt_deque this, int item ) -{ - int error = mlt_deque_allocate( this ); - - if ( error == 0 ) - { - memmove( &this->list[ 1 ], this->list, ( this->count ++ ) * sizeof( deque_entry ) ); - this->list[ 0 ].value = item; - } - - return error; -} - -/** Remove an integer from the start. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return an integer - */ - -int mlt_deque_pop_front_int( mlt_deque this ) -{ - int item = 0; - - if ( this->count > 0 ) - { - item = this->list[ 0 ].value; - memmove( this->list, &this->list[ 1 ], ( -- this->count ) * sizeof( deque_entry ) ); - } - - return item; -} - -/** Inquire on an integer at back of deque but don't remove. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return an integer - */ - -int mlt_deque_peek_back_int( mlt_deque this ) -{ - return this->count > 0 ? this->list[ this->count - 1 ].value : 0; -} - -/** Inquire on an integer at front of deque but don't remove. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return an integer - */ - -int mlt_deque_peek_front_int( mlt_deque this ) -{ - return this->count > 0 ? this->list[ 0 ].value : 0; -} - -/** Push a double float to the end. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \param item a double float - * \return true if there was an error - */ - -int mlt_deque_push_back_double( mlt_deque this, double item ) -{ - int error = mlt_deque_allocate( this ); - - if ( error == 0 ) - this->list[ this->count ++ ].floating = item; - - return error; -} - -/** Pop a double float. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return a double float - */ - -double mlt_deque_pop_back_double( mlt_deque this ) -{ - return this->count > 0 ? this->list[ -- this->count ].floating : 0; -} - -/** Queue a double float at the start. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \param item a double float - * \return true if there was an error - */ - -int mlt_deque_push_front_double( mlt_deque this, double item ) -{ - int error = mlt_deque_allocate( this ); - - if ( error == 0 ) - { - memmove( &this->list[ 1 ], this->list, ( this->count ++ ) * sizeof( deque_entry ) ); - this->list[ 0 ].floating = item; - } - - return error; -} - -/** Remove a double float from the start. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return a double float - */ - -double mlt_deque_pop_front_double( mlt_deque this ) -{ - double item = 0; - - if ( this->count > 0 ) - { - item = this->list[ 0 ].floating; - memmove( this->list, &this->list[ 1 ], ( -- this->count ) * sizeof( deque_entry ) ); - } - - return item; -} - -/** Inquire on a double float at back of deque but don't remove. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return a double float - */ - -double mlt_deque_peek_back_double( mlt_deque this ) -{ - return this->count > 0 ? this->list[ this->count - 1 ].floating : 0; -} - -/** Inquire on a double float at front of deque but don't remove. - * - * \public \memberof mlt_deque_s - * \param this a deque - * \return a double float - */ - -double mlt_deque_peek_front_double( mlt_deque this ) -{ - return this->count > 0 ? this->list[ 0 ].floating : 0; -} - -/** Destroy the queue. - * - * \public \memberof mlt_deque_s - * \param this a deque - */ - -void mlt_deque_close( mlt_deque this ) -{ - free( this->list ); - free( this ); -} diff --git a/src/framework/mlt_deque.h b/src/framework/mlt_deque.h deleted file mode 100644 index d895798..0000000 --- a/src/framework/mlt_deque.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * \file mlt_deque.h - * \brief double ended queue - * \see mlt_deque_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_DEQUE_H_ -#define _MLT_DEQUE_H_ - -#include "mlt_types.h" - -extern mlt_deque mlt_deque_init( ); -extern int mlt_deque_count( mlt_deque self ); -extern int mlt_deque_push_back( mlt_deque self, void *item ); -extern void *mlt_deque_pop_back( mlt_deque self ); -extern int mlt_deque_push_front( mlt_deque self, void *item ); -extern void *mlt_deque_pop_front( mlt_deque self ); -extern void *mlt_deque_peek_back( mlt_deque self ); -extern void *mlt_deque_peek_front( mlt_deque self ); - -extern int mlt_deque_push_back_int( mlt_deque self, int item ); -extern int mlt_deque_pop_back_int( mlt_deque self ); -extern int mlt_deque_push_front_int( mlt_deque self, int item ); -extern int mlt_deque_pop_front_int( mlt_deque self ); -extern int mlt_deque_peek_back_int( mlt_deque self ); -extern int mlt_deque_peek_front_int( mlt_deque self ); - -extern int mlt_deque_push_back_double( mlt_deque self, double item ); -extern double mlt_deque_pop_back_double( mlt_deque self ); -extern int mlt_deque_push_front_double( mlt_deque self, double item ); -extern double mlt_deque_pop_front_double( mlt_deque self ); -extern double mlt_deque_peek_back_double( mlt_deque self ); -extern double mlt_deque_peek_front_double( mlt_deque self ); - -extern void mlt_deque_close( mlt_deque self ); - -#endif diff --git a/src/framework/mlt_events.c b/src/framework/mlt_events.c deleted file mode 100644 index 5c84190..0000000 --- a/src/framework/mlt_events.c +++ /dev/null @@ -1,503 +0,0 @@ -/** - * \file mlt_events.c - * \brief event handling - * \see mlt_events_struct - * - * Copyright (C) 2004-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include "mlt_properties.h" -#include "mlt_events.h" - -/* Memory leak checks. */ - -#undef _MLT_EVENT_CHECKS_ - -#ifdef _MLT_EVENT_CHECKS_ -static int events_created = 0; -static int events_destroyed = 0; -#endif - -/** \brief Events class - * - * Events provide messages and notifications between services and the application. - * A service can register an event and fire/send it upon certain conditions or times. - * Likewise, a service or an application can listen/receive specific events on specific - * services. - */ - -struct mlt_events_struct -{ - mlt_properties owner; - mlt_properties list; -}; - -typedef struct mlt_events_struct *mlt_events; - -/** \brief Event class - * - */ - -struct mlt_event_struct -{ - mlt_events owner; - int ref_count; - int block_count; - mlt_listener listener; - void *service; -}; - -/** Increment the reference count on this event. - * - * \public \memberof mlt_event_struct - * \param this an event - */ - -void mlt_event_inc_ref( mlt_event this ) -{ - if ( this != NULL ) - this->ref_count ++; -} - -/** Increment the block count on this event. - * - * \public \memberof mlt_event_struct - * \param this an event - */ - -void mlt_event_block( mlt_event this ) -{ - if ( this != NULL && this->owner != NULL ) - this->block_count ++; -} - -/** Decrement the block count on this event. - * - * \public \memberof mlt_event_struct - * \param this an event - */ - -void mlt_event_unblock( mlt_event this ) -{ - if ( this != NULL && this->owner != NULL ) - this->block_count --; -} - -/** Close this event. - * - * \public \memberof mlt_event_struct - * \param this an event - */ - -void mlt_event_close( mlt_event this ) -{ - if ( this != NULL ) - { - if ( -- this->ref_count == 1 ) - this->owner = NULL; - if ( this->ref_count <= 0 ) - { -#ifdef _MLT_EVENT_CHECKS_ - mlt_log( NULL, MLT_LOG_DEBUG, "Events created %d, destroyed %d\n", events_created, ++events_destroyed ); -#endif - free( this ); - } - } -} - -/* Forward declaration to private functions. -*/ - -static mlt_events mlt_events_fetch( mlt_properties ); -static void mlt_events_store( mlt_properties, mlt_events ); -static void mlt_events_close( mlt_events ); - -/** Initialise the events structure. - * - * \public \memberof mlt_events_struct - * \param this a properties list - */ - -void mlt_events_init( mlt_properties this ) -{ - mlt_events events = mlt_events_fetch( this ); - if ( events == NULL ) - { - events = malloc( sizeof( struct mlt_events_struct ) ); - events->list = mlt_properties_new( ); - mlt_events_store( this, events ); - } -} - -/** Register an event and transmitter. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param id the name of an event - * \param transmitter the callback function to send an event message - * \return true if there was an error - */ - -int mlt_events_register( mlt_properties this, const char *id, mlt_transmitter transmitter ) -{ - int error = 1; - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - mlt_properties list = events->list; - char temp[ 128 ]; - error = mlt_properties_set_data( list, id, transmitter, 0, NULL, NULL ); - sprintf( temp, "list:%s", id ); - if ( mlt_properties_get_data( list, temp, NULL ) == NULL ) - mlt_properties_set_data( list, temp, mlt_properties_new( ), 0, ( mlt_destructor )mlt_properties_close, NULL ); - } - return error; -} - -/** Fire an event. - * - * This takes a variable number of arguments to supply to the listener. - - * \public \memberof mlt_events_struct - * \param this a properties list - * \param id the name of an event - */ - -void mlt_events_fire( mlt_properties this, const char *id, ... ) -{ - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - int i = 0; - va_list alist; - void *args[ 10 ]; - mlt_properties list = events->list; - mlt_properties listeners = NULL; - char temp[ 128 ]; - mlt_transmitter transmitter = mlt_properties_get_data( list, id, NULL ); - sprintf( temp, "list:%s", id ); - listeners = mlt_properties_get_data( list, temp, NULL ); - - va_start( alist, id ); - do - args[ i ] = va_arg( alist, void * ); - while( args[ i ++ ] != NULL ); - va_end( alist ); - - if ( listeners != NULL ) - { - for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) - { - mlt_event event = mlt_properties_get_data_at( listeners, i, NULL ); - if ( event != NULL && event->owner != NULL && event->block_count == 0 ) - { - if ( transmitter != NULL ) - transmitter( event->listener, event->owner, event->service, args ); - else - event->listener( event->owner, event->service ); - } - } - } - } -} - -/** Register a listener. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param service an opaque pointer - * \param id the name of the event to listen for - * \param listener the callback to receive an event message - * \return - */ - -mlt_event mlt_events_listen( mlt_properties this, void *service, const char *id, mlt_listener listener ) -{ - mlt_event event = NULL; - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - mlt_properties list = events->list; - mlt_properties listeners = NULL; - char temp[ 128 ]; - sprintf( temp, "list:%s", id ); - listeners = mlt_properties_get_data( list, temp, NULL ); - if ( listeners != NULL ) - { - int first_null = -1; - int i = 0; - for ( i = 0; event == NULL && i < mlt_properties_count( listeners ); i ++ ) - { - mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - if ( entry != NULL && entry->owner != NULL ) - { - if ( entry->service == service && entry->listener == listener ) - event = entry; - } - else if ( ( entry == NULL || entry->owner == NULL ) && first_null == -1 ) - { - first_null = i; - } - } - - if ( event == NULL ) - { - event = malloc( sizeof( struct mlt_event_struct ) ); - if ( event != NULL ) - { -#ifdef _MLT_EVENT_CHECKS_ - events_created ++; -#endif - sprintf( temp, "%d", first_null == -1 ? mlt_properties_count( listeners ) : first_null ); - event->owner = events; - event->ref_count = 0; - event->block_count = 0; - event->listener = listener; - event->service = service; - mlt_properties_set_data( listeners, temp, event, 0, ( mlt_destructor )mlt_event_close, NULL ); - mlt_event_inc_ref( event ); - } - } - - } - } - return event; -} - -/** Block all events for a given service. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param service an opaque pointer - */ - -void mlt_events_block( mlt_properties this, void *service ) -{ - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - int i = 0, j = 0; - mlt_properties list = events->list; - for ( j = 0; j < mlt_properties_count( list ); j ++ ) - { - char *temp = mlt_properties_get_name( list, j ); - if ( !strncmp( temp, "list:", 5 ) ) - { - mlt_properties listeners = mlt_properties_get_data( list, temp, NULL ); - for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) - { - mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - if ( entry != NULL && entry->service == service ) - mlt_event_block( entry ); - } - } - } - } -} - -/** Unblock all events for a given service. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param service an opaque pointer - */ - -void mlt_events_unblock( mlt_properties this, void *service ) -{ - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - int i = 0, j = 0; - mlt_properties list = events->list; - for ( j = 0; j < mlt_properties_count( list ); j ++ ) - { - char *temp = mlt_properties_get_name( list, j ); - if ( !strncmp( temp, "list:", 5 ) ) - { - mlt_properties listeners = mlt_properties_get_data( list, temp, NULL ); - for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) - { - mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - if ( entry != NULL && entry->service == service ) - mlt_event_unblock( entry ); - } - } - } - } -} - -/** Disconnect all events for a given service. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param service an opaque pointer - */ - -void mlt_events_disconnect( mlt_properties this, void *service ) -{ - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - int i = 0, j = 0; - mlt_properties list = events->list; - for ( j = 0; j < mlt_properties_count( list ); j ++ ) - { - char *temp = mlt_properties_get_name( list, j ); - if ( !strncmp( temp, "list:", 5 ) ) - { - mlt_properties listeners = mlt_properties_get_data( list, temp, NULL ); - for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) - { - mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - char *name = mlt_properties_get_name( listeners, i ); - if ( entry != NULL && entry->service == service ) - mlt_properties_set_data( listeners, name, NULL, 0, NULL, NULL ); - } - } - } - } -} - -/** \brief private to mlt_events_struct, used by mlt_events_wait_for() */ - -typedef struct -{ - int done; - pthread_cond_t cond; - pthread_mutex_t mutex; -} -condition_pair; - -/** The event listener callback for the wait functions. - * - * \private \memberof mlt_events_struct - * \param this a properties list - * \param pair a condition pair - */ - -static void mlt_events_listen_for( mlt_properties this, condition_pair *pair ) -{ - pthread_mutex_lock( &pair->mutex ); - if ( pair->done == 0 ) - { - pthread_cond_signal( &pair->cond ); - pthread_mutex_unlock( &pair->mutex ); - } -} - -/** Prepare to wait for an event. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param id the name of the event to wait for - * \return an event - */ - -mlt_event mlt_events_setup_wait_for( mlt_properties this, const char *id ) -{ - condition_pair *pair = malloc( sizeof( condition_pair ) ); - pair->done = 0; - pthread_cond_init( &pair->cond, NULL ); - pthread_mutex_init( &pair->mutex, NULL ); - pthread_mutex_lock( &pair->mutex ); - return mlt_events_listen( this, pair, id, ( mlt_listener )mlt_events_listen_for ); -} - -/** Wait for an event. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param event an event - */ - -void mlt_events_wait_for( mlt_properties this, mlt_event event ) -{ - if ( event != NULL ) - { - condition_pair *pair = event->service; - pthread_cond_wait( &pair->cond, &pair->mutex ); - } -} - -/** Cleanup after waiting for an event. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param event an event - */ - -void mlt_events_close_wait_for( mlt_properties this, mlt_event event ) -{ - if ( event != NULL ) - { - condition_pair *pair = event->service; - event->owner = NULL; - pair->done = 0; - pthread_mutex_unlock( &pair->mutex ); - pthread_mutex_destroy( &pair->mutex ); - pthread_cond_destroy( &pair->cond ); - } -} - -/** Fetch the events object. - * - * \private \memberof mlt_events_struct - * \param this a properties list - * \return an events object - */ - -static mlt_events mlt_events_fetch( mlt_properties this ) -{ - mlt_events events = NULL; - if ( this != NULL ) - events = mlt_properties_get_data( this, "_events", NULL ); - return events; -} - -/** Store the events object. - * - * \private \memberof mlt_events_struct - * \param this a properties list - * \param events an events object - */ - -static void mlt_events_store( mlt_properties this, mlt_events events ) -{ - if ( this != NULL && events != NULL ) - mlt_properties_set_data( this, "_events", events, 0, ( mlt_destructor )mlt_events_close, NULL ); -} - -/** Close the events object. - * - * \private \memberof mlt_events_struct - * \param events an events object - */ - -static void mlt_events_close( mlt_events events ) -{ - if ( events != NULL ) - { - mlt_properties_close( events->list ); - free( events ); - } -} diff --git a/src/framework/mlt_events.h b/src/framework/mlt_events.h deleted file mode 100644 index 55bb18f..0000000 --- a/src/framework/mlt_events.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * \file mlt_events.h - * \brief event handling - * \see mlt_events_struct - * - * Copyright (C) 2004-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_EVENTS_H_ -#define _MLT_EVENTS_H_ - -#include "mlt_types.h" - -#if GCC_VERSION >= 40000 -typedef void ( *mlt_transmitter )( void *, ... ); -typedef void ( *mlt_listener )( void *, ... ); -#else -/** callback function to send an event message - * - */ -typedef void ( *mlt_transmitter )( ); -/** event handler when receiving an event message - * \param the properties object on which the event was registered - * \param an opaque pointer to a service or really an object - * \param variable args supplied by the transmitter - */ -typedef void ( *mlt_listener )( ); -#endif - -extern void mlt_events_init( mlt_properties self ); -extern int mlt_events_register( mlt_properties self, const char *id, mlt_transmitter transmitter ); -extern void mlt_events_fire( mlt_properties self, const char *id, ... ); -extern mlt_event mlt_events_listen( mlt_properties self, void *service, const char *id, mlt_listener listener ); -extern void mlt_events_block( mlt_properties self, void *service ); -extern void mlt_events_unblock( mlt_properties self, void *service ); -extern void mlt_events_disconnect( mlt_properties self, void *service ); - -extern mlt_event mlt_events_setup_wait_for( mlt_properties self, const char *id ); -extern void mlt_events_wait_for( mlt_properties self, mlt_event event ); -extern void mlt_events_close_wait_for( mlt_properties self, mlt_event event ); - -extern void mlt_event_inc_ref( mlt_event self ); -extern void mlt_event_block( mlt_event self ); -extern void mlt_event_unblock( mlt_event self ); -extern void mlt_event_close( mlt_event self ); - -#endif - diff --git a/src/framework/mlt_factory.c b/src/framework/mlt_factory.c deleted file mode 100644 index 552b8ce..0000000 --- a/src/framework/mlt_factory.c +++ /dev/null @@ -1,378 +0,0 @@ -/** - * \file mlt_factory.c - * \brief the factory method interfaces - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt.h" -#include "mlt_repository.h" - -#include -#include -#include - -/** the default subdirectory of the libdir for holding modules (plugins) */ -#define PREFIX_LIB LIBDIR "/mlt" -/** the default subdirectory of the install prefix for holding module (plugin) data */ -#define PREFIX_DATA PREFIX "/share/mlt" - - -/** holds the full path to the modules directory - initialized and retained for the entire session */ -static char *mlt_directory = NULL; -/** a global properties list for holding environment config data and things needing session-oriented cleanup */ -static mlt_properties global_properties = NULL; -/** the global repository singleton */ -static mlt_repository repository = NULL; -/** the events object for the factory events */ -static mlt_properties event_object = NULL; -/** for tracking the unique_id set on each constructed service */ -static int unique_id = 0; - -/* Event transmitters. */ - -/** the -create-request event transmitter - * - * \param listener - * \param owner - * \param this - * \param args - */ - -static void mlt_factory_create_request( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ) -{ - if ( listener != NULL ) - listener( owner, this, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service * )args[ 2 ] ); -} - -/** the -create-done event transmitter - * - * \param listener - * \param owner - * \param this - * \param args - */ - -static void mlt_factory_create_done( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ) -{ - if ( listener != NULL ) - listener( owner, this, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service )args[ 2 ] ); -} - -/** Construct the repository and factories. - * - * The environment variable MLT_PRODUCER is the name of a default producer often used by other services, defaults to "fezzil". - * - * The environment variable MLT_CONSUMER is the name of a default consumer, defaults to "sdl". - * - * The environment variable MLT_TEST_CARD is the name of a producer or file to be played when nothing is available (all tracks blank). - * - * The environment variable MLT_DATA overrides the default full path to the MLT and module supplemental data files, defaults to \p PREFIX_DATA. - * - * The environment variable MLT_PROFILE defaults to "dv_pal." - * - * The environment variable MLT_REPOSITORY overrides the default location of the plugin modules, defaults to \p PREFIX_LIB. - * - * \param directory an optional full path to a directory containing the modules that overrides the default and - * the MLT_REPOSITORY environment variable - * \return the repository - */ - -mlt_repository mlt_factory_init( const char *directory ) -{ - // Only initialise once - if ( mlt_directory == NULL ) - { - // Allow user over rides - if ( directory == NULL || !strcmp( directory, "" ) ) - directory = getenv( "MLT_REPOSITORY" ); - - // If no directory is specified, default to install directory - if ( directory == NULL ) - directory = PREFIX_LIB; - - // Store the prefix for later retrieval - mlt_directory = strdup( directory ); - - // Initialise the pool - mlt_pool_init( ); - - // Create and set up the events object - event_object = mlt_properties_new( ); - mlt_events_init( event_object ); - mlt_events_register( event_object, "producer-create-request", ( mlt_transmitter )mlt_factory_create_request ); - mlt_events_register( event_object, "producer-create-done", ( mlt_transmitter )mlt_factory_create_done ); - mlt_events_register( event_object, "filter-create-request", ( mlt_transmitter )mlt_factory_create_request ); - mlt_events_register( event_object, "filter-create-done", ( mlt_transmitter )mlt_factory_create_done ); - mlt_events_register( event_object, "transition-create-request", ( mlt_transmitter )mlt_factory_create_request ); - mlt_events_register( event_object, "transition-create-done", ( mlt_transmitter )mlt_factory_create_done ); - mlt_events_register( event_object, "consumer-create-request", ( mlt_transmitter )mlt_factory_create_request ); - mlt_events_register( event_object, "consumer-create-done", ( mlt_transmitter )mlt_factory_create_done ); - - // Create the global properties - global_properties = mlt_properties_new( ); - - // Create the repository of services - repository = mlt_repository_init( directory ); - - // Force a clean up when app closes - atexit( mlt_factory_close ); - } - - // Allow property refresh on a subsequent initialisation - if ( global_properties != NULL ) - { - mlt_properties_set_or_default( global_properties, "MLT_NORMALISATION", getenv( "MLT_NORMALISATION" ), "PAL" ); - mlt_properties_set_or_default( global_properties, "MLT_PRODUCER", getenv( "MLT_PRODUCER" ), "fezzik" ); - mlt_properties_set_or_default( global_properties, "MLT_CONSUMER", getenv( "MLT_CONSUMER" ), "sdl" ); - mlt_properties_set( global_properties, "MLT_TEST_CARD", getenv( "MLT_TEST_CARD" ) ); - mlt_properties_set_or_default( global_properties, "MLT_PROFILE", getenv( "MLT_PROFILE" ), "dv_pal" ); - mlt_properties_set_or_default( global_properties, "MLT_DATA", getenv( "MLT_DATA" ), PREFIX_DATA ); - } - - - return repository; -} - -/** Fetch the events object. - * - * \return the global factory event object - */ - -mlt_properties mlt_factory_event_object( ) -{ - return event_object; -} - -/** Fetch the module directory used in this instance. - * - * \return the full path to the module directory that this session is using - */ - -const char *mlt_factory_directory( ) -{ - return mlt_directory; -} - -/** Get a value from the environment. - * - * \param name the name of a MLT (runtime configuration) environment variable - * \return the value of the variable - */ - -char *mlt_environment( const char *name ) -{ - if ( global_properties ) - return mlt_properties_get( global_properties, name ); - else - return NULL; -} - -/** Set a value in the environment. - * - * \param name the name of a MLT environment variable - * \param value the value of the variable - * \return true on error - */ - -int mlt_environment_set( const char *name, const char *value ) -{ - if ( global_properties ) - return mlt_properties_set( global_properties, name, value ); - else - return -1; -} - -/** Set some properties common to all services. - * - * This sets _unique_id, \p mlt_type, \p mlt_service (unless _mlt_service_hidden), and _profile. - * - * \param properties a service's properties list - * \param profile the \p mlt_profile supplied to the factory function - * \param type the MLT service class - * \param service the name of the service - */ - -static void set_common_properties( mlt_properties properties, mlt_profile profile, const char *type, const char *service ) -{ - mlt_properties_set_int( properties, "_unique_id", ++ unique_id ); - mlt_properties_set( properties, "mlt_type", type ); - if ( mlt_properties_get_int( properties, "_mlt_service_hidden" ) == 0 ) - mlt_properties_set( properties, "mlt_service", service ); - if ( profile != NULL ) - mlt_properties_set_data( properties, "_profile", profile, 0, NULL, NULL ); -} - -/** Fetch a producer from the repository. - * - * \param profile the \p mlt_profile to use - * \param service the name of the producer (optional, defaults to MLT_PRODUCER) - * \param input an optional argument to the producer constructor, typically a string - * \return a new producer - */ - -mlt_producer mlt_factory_producer( mlt_profile profile, const char *service, const void *input ) -{ - mlt_producer obj = NULL; - - // Pick up the default normalising producer if necessary - if ( service == NULL ) - service = mlt_environment( "MLT_PRODUCER" ); - - // Offer the application the chance to 'create' - mlt_events_fire( event_object, "producer-create-request", service, input, &obj, NULL ); - - // Try to instantiate via the specified service - if ( obj == NULL ) - { - obj = mlt_repository_create( repository, profile, producer_type, service, input ); - mlt_events_fire( event_object, "producer-create-done", service, input, obj, NULL ); - if ( obj != NULL ) - { - mlt_properties properties = MLT_PRODUCER_PROPERTIES( obj ); - set_common_properties( properties, profile, "producer", service ); - } - } - return obj; -} - -/** Fetch a filter from the repository. - * - * \param profile the \p mlt_profile to use - * \param service the name of the filter - * \param input an optional argument to the filter constructor, typically a string - * \return a new filter - */ - -mlt_filter mlt_factory_filter( mlt_profile profile, const char *service, const void *input ) -{ - mlt_filter obj = NULL; - - // Offer the application the chance to 'create' - mlt_events_fire( event_object, "filter-create-request", service, input, &obj, NULL ); - - if ( obj == NULL ) - { - obj = mlt_repository_create( repository, profile, filter_type, service, input ); - mlt_events_fire( event_object, "filter-create-done", service, input, obj, NULL ); - } - - if ( obj != NULL ) - { - mlt_properties properties = MLT_FILTER_PROPERTIES( obj ); - set_common_properties( properties, profile, "filter", service ); - } - return obj; -} - -/** Fetch a transition from the repository. - * - * \param profile the \p mlt_profile to use - * \param service the name of the transition - * \param input an optional argument to the transition constructor, typically a string - * \return a new transition - */ - -mlt_transition mlt_factory_transition( mlt_profile profile, const char *service, const void *input ) -{ - mlt_transition obj = NULL; - - // Offer the application the chance to 'create' - mlt_events_fire( event_object, "transition-create-request", service, input, &obj, NULL ); - - if ( obj == NULL ) - { - obj = mlt_repository_create( repository, profile, transition_type, service, input ); - mlt_events_fire( event_object, "transition-create-done", service, input, obj, NULL ); - } - - if ( obj != NULL ) - { - mlt_properties properties = MLT_TRANSITION_PROPERTIES( obj ); - set_common_properties( properties, profile, "transition", service ); - } - return obj; -} - -/** Fetch a consumer from the repository. - * - * \param profile the \p mlt_profile to use - * \param service the name of the consumer (optional, defaults to MLT_CONSUMER) - * \param input an optional argument to the consumer constructor, typically a string - * \return a new consumer - */ - -mlt_consumer mlt_factory_consumer( mlt_profile profile, const char *service, const void *input ) -{ - mlt_consumer obj = NULL; - - if ( service == NULL ) - service = mlt_environment( "MLT_CONSUMER" ); - - // Offer the application the chance to 'create' - mlt_events_fire( event_object, "consumer-create-request", service, input, &obj, NULL ); - - if ( obj == NULL ) - { - obj = mlt_repository_create( repository, profile, consumer_type, service, input ); - mlt_events_fire( event_object, "consumer-create-done", service, input, obj, NULL ); - } - - if ( obj != NULL ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( obj ); - set_common_properties( properties, profile, "consumer", service ); - } - return obj; -} - -/** Register an object for clean up. - * - * \param ptr an opaque pointer to anything allocated on the heap - * \param destructor the function pointer of the deallocation subroutine (e.g., free or \p mlt_pool_release) - */ - -void mlt_factory_register_for_clean_up( void *ptr, mlt_destructor destructor ) -{ - char unique[ 256 ]; - sprintf( unique, "%08d", mlt_properties_count( global_properties ) ); - mlt_properties_set_data( global_properties, unique, ptr, 0, destructor, NULL ); -} - -/** Close the factory. - * - * Cleanup all resources for the session. - */ - -void mlt_factory_close( ) -{ - if ( mlt_directory != NULL ) - { - mlt_properties_close( event_object ); - mlt_properties_close( global_properties ); - mlt_repository_close( repository ); - free( mlt_directory ); - mlt_directory = NULL; - mlt_pool_close( ); - } -} - -mlt_properties mlt_global_properties( ) -{ - return global_properties; -} diff --git a/src/framework/mlt_factory.h b/src/framework/mlt_factory.h deleted file mode 100644 index 29dc62a..0000000 --- a/src/framework/mlt_factory.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * \file mlt_factory.h - * \brief the factory method interfaces - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_FACTORY_H -#define _MLT_FACTORY_H - -#include "mlt_types.h" -#include "mlt_profile.h" -#include "mlt_repository.h" - -/** - * \event \em producer-create-request fired when mlt_factory_producer is called - * \event \em producer-create-done fired when a producer registers itself - * \event \em filter-create-request fired when mlt_factory_filter is called - * \event \em filter-create-done fired when a filter registers itself - * \event \em transition-create-request fired when mlt_factory_transition is called - * \event \em transition-create-done fired when a transition registers itself - * \event \em consumer-create-request fired when mlt_factory_consumer is called - * \event \em consumer-create-done fired when a consumer registers itself - */ - -extern mlt_repository mlt_factory_init( const char *directory ); -extern const char *mlt_factory_directory( ); -extern char *mlt_environment( const char *name ); -extern int mlt_environment_set( const char *name, const char *value ); -extern mlt_properties mlt_factory_event_object( ); -extern mlt_producer mlt_factory_producer( mlt_profile profile, const char *name, const void *input ); -extern mlt_filter mlt_factory_filter( mlt_profile profile, const char *name, const void *input ); -extern mlt_transition mlt_factory_transition( mlt_profile profile, const char *name, const void *input ); -extern mlt_consumer mlt_factory_consumer( mlt_profile profile, const char *name, const void *input ); -extern void mlt_factory_register_for_clean_up( void *ptr, mlt_destructor destructor ); -extern void mlt_factory_close( ); -extern mlt_properties mlt_global_properties( ); - -#endif diff --git a/src/framework/mlt_field.c b/src/framework/mlt_field.c deleted file mode 100644 index c988ae6..0000000 --- a/src/framework/mlt_field.c +++ /dev/null @@ -1,270 +0,0 @@ -/** - * \file mlt_field.c - * \brief a field for planting multiple transitions and filters - * \see mlt_field_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_field.h" -#include "mlt_service.h" -#include "mlt_filter.h" -#include "mlt_transition.h" -#include "mlt_multitrack.h" -#include "mlt_tractor.h" - -#include -#include - -/** \brief Field class - * - * The field is a convenience class that works with the tractor and multitrack classes to manage track filters and transitions. - */ - -struct mlt_field_s -{ - /// This is the producer we're connected to - mlt_service producer; - - /// Multitrack - mlt_multitrack multitrack; - - /// Tractor - mlt_tractor tractor; -}; - -/** Construct a field, mulitrack, and tractor. - * - * \public \memberof mlt_field_s - * \return a new field - */ - -mlt_field mlt_field_init( ) -{ - // Initialise the field - mlt_field this = calloc( sizeof( struct mlt_field_s ), 1 ); - - // Initialise it - if ( this != NULL ) - { - // Construct a multitrack - this->multitrack = mlt_multitrack_init( ); - - // Construct a tractor - this->tractor = mlt_tractor_init( ); - - // The first plant will be connected to the mulitrack - this->producer = MLT_MULTITRACK_SERVICE( this->multitrack ); - - // Connect the tractor to the multitrack - mlt_tractor_connect( this->tractor, this->producer ); - } - - // Return this - return this; -} - -/** Construct a field and initialize with supplied multitrack and tractor. - * - * \public \memberof mlt_field_s - * \param multitrack a multitrack - * \param tractor a tractor - * \return a new field - */ - -mlt_field mlt_field_new( mlt_multitrack multitrack, mlt_tractor tractor ) -{ - // Initialise the field - mlt_field this = calloc( sizeof( struct mlt_field_s ), 1 ); - - // Initialise it - if ( this != NULL ) - { - // Construct a multitrack - this->multitrack = multitrack; - - // Construct a tractor - this->tractor = tractor; - - // The first plant will be connected to the mulitrack - this->producer = MLT_MULTITRACK_SERVICE( this->multitrack ); - - // Connect the tractor to the multitrack - mlt_tractor_connect( this->tractor, this->producer ); - } - - // Return this - return this; -} - -/** Get the service associated to this field. - * - * \public \memberof mlt_field_s - * \param this a field - * \return the tractor as a service - */ - -mlt_service mlt_field_service( mlt_field this ) -{ - return MLT_TRACTOR_SERVICE( this->tractor ); -} - -/** Get the multitrack. - * - * \public \memberof mlt_field_s - * \param this a field - * \return the multitrack - */ - -mlt_multitrack mlt_field_multitrack( mlt_field this ) -{ - return this != NULL ? this->multitrack : NULL; -} - -/** Get the tractor. - * - * \public \memberof mlt_field_s - * \param this a field - * \return the tractor - */ - -mlt_tractor mlt_field_tractor( mlt_field this ) -{ - return this != NULL ? this->tractor : NULL; -} - -/** Get the properties associated to this field. - * - * \public \memberof mlt_field_s - * \param this a field - * \return a properties list - */ - -mlt_properties mlt_field_properties( mlt_field this ) -{ - return MLT_SERVICE_PROPERTIES( mlt_field_service( this ) ); -} - -/** Plant a filter. - * - * \public \memberof mlt_field_s - * \param this a field - * \param that a filter - * \param track the track index - * \return true if there was an error - */ - -int mlt_field_plant_filter( mlt_field this, mlt_filter that, int track ) -{ - // Connect the filter to the last producer - int result = mlt_filter_connect( that, this->producer, track ); - - // If sucessful, then we'll use this for connecting in the future - if ( result == 0 ) - { - // This is now the new producer - this->producer = MLT_FILTER_SERVICE( that ); - - // Reconnect tractor to new producer - mlt_tractor_connect( this->tractor, this->producer ); - - // Fire an event - mlt_events_fire( mlt_field_properties( this ), "service-changed", NULL ); - } - - return result; -} - -/** Plant a transition. - * - * \public \memberof mlt_field_s - * \param this a field - * \param that a transition - * \param a_track input A's track index - * \param b_track input B's track index - * \return true if there was an error - */ - -int mlt_field_plant_transition( mlt_field this, mlt_transition that, int a_track, int b_track ) -{ - // Connect the transition to the last producer - int result = mlt_transition_connect( that, this->producer, a_track, b_track ); - - // If sucessful, then we'll use this for connecting in the future - if ( result == 0 ) - { - // This is now the new producer - this->producer = MLT_TRANSITION_SERVICE( that ); - - // Reconnect tractor to new producer - mlt_tractor_connect( this->tractor, this->producer ); - - // Fire an event - mlt_events_fire( mlt_field_properties( this ), "service-changed", NULL ); - } - - return 0; -} - -/** Close the field. - * - * \public \memberof mlt_field_s - * \param this a field - */ - -void mlt_field_close( mlt_field this ) -{ - if ( this != NULL && mlt_properties_dec_ref( mlt_field_properties( this ) ) <= 0 ) - { - //mlt_tractor_close( this->tractor ); - //mlt_multitrack_close( this->multitrack ); - free( this ); - } -} - -/** Remove a filter or transition from the field. - * - * \public \memberof mlt_field_s - * \param self a field - * \param service the filter or transition to remove - */ - -void mlt_field_disconnect_service( mlt_field self, mlt_service service ) -{ - mlt_service p = mlt_service_producer( service ); - mlt_service c = mlt_service_consumer( service); - int i; - switch ( mlt_service_identify(c) ) - { - case filter_type: - i = mlt_filter_get_track( MLT_FILTER(c) ); - mlt_service_connect_producer( c, p, i ); - break; - case transition_type: - i = mlt_transition_get_a_track ( MLT_TRANSITION(c) ); - mlt_service_connect_producer( c, p, i ); - MLT_TRANSITION(c)->producer = p; - break; - case tractor_type: - self->producer = p; - mlt_tractor_connect( MLT_TRACTOR(c), p ); - default: - break; - } - mlt_events_fire( mlt_field_properties( self ), "service-changed", NULL ); -} diff --git a/src/framework/mlt_field.h b/src/framework/mlt_field.h deleted file mode 100644 index a54db54..0000000 --- a/src/framework/mlt_field.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * \file mlt_field.h - * \brief a field for planting multiple transitions and services - * \see mlt_field_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_FIELD_H_ -#define _MLT_FIELD_H_ - -#include "mlt_types.h" - -extern mlt_field mlt_field_init( ); -extern mlt_field mlt_field_new( mlt_multitrack multitrack, mlt_tractor tractor ); -extern mlt_service mlt_field_service( mlt_field self ); -extern mlt_tractor mlt_field_tractor( mlt_field self ); -extern mlt_multitrack mlt_field_multitrack( mlt_field self ); -extern mlt_properties mlt_field_properties( mlt_field self ); -extern int mlt_field_plant_filter( mlt_field self, mlt_filter that, int track ); -extern int mlt_field_plant_transition( mlt_field self, mlt_transition that, int a_track, int b_track ); -extern void mlt_field_close( mlt_field self ); -extern void mlt_field_disconnect_service( mlt_field self, mlt_service service ); - -#endif - diff --git a/src/framework/mlt_filter.c b/src/framework/mlt_filter.c deleted file mode 100644 index 9a04352..0000000 --- a/src/framework/mlt_filter.c +++ /dev/null @@ -1,275 +0,0 @@ -/** - * \file mlt_filter.c - * \brief abstraction for all filter services - * \see mlt_filter_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_filter.h" -#include "mlt_frame.h" - -#include -#include -#include - -static int filter_get_frame( mlt_service this, mlt_frame_ptr frame, int index ); - -/** Initialize a new filter. - * - * \public \memberof mlt_filter_s - * \param this a filter - * \param child the object of a subclass - * \return true if there was an error - */ - -int mlt_filter_init( mlt_filter this, void *child ) -{ - mlt_service service = &this->parent; - memset( this, 0, sizeof( struct mlt_filter_s ) ); - this->child = child; - if ( mlt_service_init( service, this ) == 0 ) - { - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - // Override the get_frame method - service->get_frame = filter_get_frame; - - // Define the destructor - service->close = ( mlt_destructor )mlt_filter_close; - service->close_object = this; - - // Default in, out, track properties - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", 0 ); - mlt_properties_set_int( properties, "track", 0 ); - - return 0; - } - return 1; -} - -/** Create a new filter and initialize it. - * - * \public \memberof mlt_filter_s - * \return a new filter - */ - -mlt_filter mlt_filter_new( ) -{ - mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) ); - if ( this != NULL ) - mlt_filter_init( this, NULL ); - return this; -} - -/** Get the service class interface. - * - * \public \memberof mlt_filter_s - * \param this a filter - * \return the service parent class - * \see MLT_FILTER_SERVICE - */ - -mlt_service mlt_filter_service( mlt_filter this ) -{ - return this != NULL ? &this->parent : NULL; -} - -/** Get the filter properties. - * - * \public \memberof mlt_filter_s - * \param this a filter - * \return the properties list for the filter - * \see MLT_FILTER_PROPERTIES - */ - -mlt_properties mlt_filter_properties( mlt_filter this ) -{ - return MLT_SERVICE_PROPERTIES( MLT_FILTER_SERVICE( this ) ); -} - -/** Connect this filter to a producers track. Note that a filter only operates - * on a single track, and by default it operates on the entirety of that track. - * - * \public \memberof mlt_filter_s - * \param this a filter - * \param producer the producer to which to connect this filter - * \param index which of potentially multiple producers to this service (0 based) - */ - -int mlt_filter_connect( mlt_filter this, mlt_service producer, int index ) -{ - int ret = mlt_service_connect_producer( &this->parent, producer, index ); - - // If the connection was successful, grab the producer, track and reset in/out - if ( ret == 0 ) - { - mlt_properties properties = MLT_SERVICE_PROPERTIES( &this->parent ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", 0 ); - mlt_properties_set_int( properties, "track", index ); - } - - return ret; -} - -/** Set the starting and ending time. - * - * \public \memberof mlt_filter_s - * \param this a filter - * \param in the time relative to the producer at which start applying the filter - * \param out the time relative to the producer at which to stop applying the filter - */ - - -void mlt_filter_set_in_and_out( mlt_filter this, mlt_position in, mlt_position out ) -{ - mlt_properties properties = MLT_SERVICE_PROPERTIES( &this->parent ); - mlt_properties_set_position( properties, "in", in ); - mlt_properties_set_position( properties, "out", out ); -} - -/** Return the track that this filter is operating on. - * - * \public \memberof mlt_filter_s - * \param this a filter - * \return true on error - */ - - -int mlt_filter_get_track( mlt_filter this ) -{ - mlt_properties properties = MLT_SERVICE_PROPERTIES( &this->parent ); - return mlt_properties_get_int( properties, "track" ); -} - -/** Get the in point. - * - * \public \memberof mlt_filter_s - * \param this a filter - * \return the start time for the filter relative to the producer - */ - - -mlt_position mlt_filter_get_in( mlt_filter this ) -{ - mlt_properties properties = MLT_SERVICE_PROPERTIES( &this->parent ); - return mlt_properties_get_position( properties, "in" ); -} - -/** Get the out point. - * - * \public \memberof mlt_filter_s - * \param this a filter - * \return the ending time for the filter relative to the producer - */ - - -mlt_position mlt_filter_get_out( mlt_filter this ) -{ - mlt_properties properties = MLT_SERVICE_PROPERTIES( &this->parent ); - return mlt_properties_get_position( properties, "out" ); -} - -/** Process the frame. - * - * \public \memberof mlt_filter_s - * \param this a filter - * \param frame a frame - * \return a frame - */ - - -mlt_frame mlt_filter_process( mlt_filter this, mlt_frame frame ) -{ - int disable = mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "disable" ); - if ( disable || this->process == NULL ) - return frame; - else - return this->process( this, frame ); -} - -/** Get a frame from this filter. - * - * \private \memberof mlt_filter_s - * \param service a service - * \param[out] frame a frame by reference - * \param index as determined by the producer - * \return true on error - */ - - -static int filter_get_frame( mlt_service service, mlt_frame_ptr frame, int index ) -{ - mlt_filter this = service->child; - - // Get coords in/out/track - int track = mlt_filter_get_track( this ); - int in = mlt_filter_get_in( this ); - int out = mlt_filter_get_out( this ); - - // Get the producer this is connected to - mlt_service producer = mlt_service_producer( &this->parent ); - - // If the frame request is for this filters track, we need to process it - if ( index == track || track == -1 ) - { - int ret = mlt_service_get_frame( producer, frame, index ); - if ( ret == 0 ) - { - mlt_position position = mlt_frame_get_position( *frame ); - if ( position >= in && ( out == 0 || position <= out ) ) - *frame = mlt_filter_process( this, *frame ); - return 0; - } - else - { - *frame = mlt_frame_init( service ); - return 0; - } - } - else - { - return mlt_service_get_frame( producer, frame, index ); - } -} - -/** Close and destroy the filter. - * - * \public \memberof mlt_filter_s - * \param this a filter - */ - - -void mlt_filter_close( mlt_filter this ) -{ - if ( this != NULL && mlt_properties_dec_ref( MLT_FILTER_PROPERTIES( this ) ) <= 0 ) - { - if ( this->close != NULL ) - { - this->close( this ); - } - else - { - this->parent.close = NULL; - mlt_service_close( &this->parent ); - } - free( this ); - } -} diff --git a/src/framework/mlt_filter.h b/src/framework/mlt_filter.h deleted file mode 100644 index 66e2e47..0000000 --- a/src/framework/mlt_filter.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * \file mlt_filter.h - * \brief abstraction for all filter services - * \see mlt_filter_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_FILTER_H_ -#define _MLT_FILTER_H_ - -#include "mlt_service.h" - -/** \brief Filter abstract service class - * - * A filter is a service that may modify the output of a single producer. - * - * \extends mlt_service_s - * \properties \em track the index of the track of a multitrack on which the filter is applied - */ - -struct mlt_filter_s -{ - /** We're implementing service here */ - struct mlt_service_s parent; - - /** public virtual */ - void ( *close )( mlt_filter ); - - /** protected filter method */ - mlt_frame ( *process )( mlt_filter, mlt_frame ); - - /** Protected */ - void *child; -}; - -#define MLT_FILTER_SERVICE( filter ) ( &( filter )->parent ) -#define MLT_FILTER_PROPERTIES( filter ) MLT_SERVICE_PROPERTIES( MLT_FILTER_SERVICE( filter ) ) - -extern int mlt_filter_init( mlt_filter self, void *child ); -extern mlt_filter mlt_filter_new( ); -extern mlt_service mlt_filter_service( mlt_filter self ); -extern mlt_properties mlt_filter_properties( mlt_filter self ); -extern mlt_frame mlt_filter_process( mlt_filter self, mlt_frame that ); -extern int mlt_filter_connect( mlt_filter self, mlt_service producer, int index ); -extern void mlt_filter_set_in_and_out( mlt_filter self, mlt_position in, mlt_position out ); -extern int mlt_filter_get_track( mlt_filter self ); -extern mlt_position mlt_filter_get_in( mlt_filter self ); -extern mlt_position mlt_filter_get_out( mlt_filter self ); -extern void mlt_filter_close( mlt_filter ); - -#endif diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c deleted file mode 100644 index 0899b06..0000000 --- a/src/framework/mlt_frame.c +++ /dev/null @@ -1,1314 +0,0 @@ -/** - * \file mlt_frame.c - * \brief interface for all frame classes - * \see mlt_frame_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_frame.h" -#include "mlt_producer.h" -#include "mlt_factory.h" -#include "mlt_profile.h" - -#include -#include -#include -#include - -/** Constructor for a frame. -*/ - -mlt_frame mlt_frame_init( mlt_service service ) -{ - // Allocate a frame - mlt_frame this = calloc( sizeof( struct mlt_frame_s ), 1 ); - - if ( this != NULL ) - { - mlt_profile profile = mlt_service_profile( service ); - - // Initialise the properties - mlt_properties properties = &this->parent; - mlt_properties_init( properties, this ); - - // Set default properties on the frame - mlt_properties_set_position( properties, "_position", 0.0 ); - mlt_properties_set_data( properties, "image", NULL, 0, NULL, NULL ); - mlt_properties_set_int( properties, "width", profile? profile->width : 720 ); - mlt_properties_set_int( properties, "height", profile? profile->height : 576 ); - mlt_properties_set_int( properties, "normalised_width", profile? profile->width : 720 ); - mlt_properties_set_int( properties, "normalised_height", profile? profile->height : 576 ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( NULL ) ); - mlt_properties_set_data( properties, "audio", NULL, 0, NULL, NULL ); - mlt_properties_set_data( properties, "alpha", NULL, 0, NULL, NULL ); - - // Construct stacks for frames and methods - this->stack_image = mlt_deque_init( ); - this->stack_audio = mlt_deque_init( ); - this->stack_service = mlt_deque_init( ); - } - - return this; -} - -/** Fetch the frames properties. -*/ - -mlt_properties mlt_frame_properties( mlt_frame this ) -{ - return this != NULL ? &this->parent : NULL; -} - -/** Check if we have a way to derive something other than a test card. -*/ - -int mlt_frame_is_test_card( mlt_frame this ) -{ - return mlt_deque_count( this->stack_image ) == 0 || mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "test_image" ); -} - -/** Check if we have a way to derive something other than test audio. -*/ - -int mlt_frame_is_test_audio( mlt_frame this ) -{ - return mlt_deque_count( this->stack_audio ) == 0 || mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "test_audio" ); -} - -/** Get the aspect ratio of the frame. -*/ - -double mlt_frame_get_aspect_ratio( mlt_frame this ) -{ - return mlt_properties_get_double( MLT_FRAME_PROPERTIES( this ), "aspect_ratio" ); -} - -/** Set the aspect ratio of the frame. -*/ - -int mlt_frame_set_aspect_ratio( mlt_frame this, double value ) -{ - return mlt_properties_set_double( MLT_FRAME_PROPERTIES( this ), "aspect_ratio", value ); -} - -/** Get the position of this frame. -*/ - -mlt_position mlt_frame_get_position( mlt_frame this ) -{ - int pos = mlt_properties_get_position( MLT_FRAME_PROPERTIES( this ), "_position" ); - return pos < 0 ? 0 : pos; -} - -/** Set the position of this frame. -*/ - -int mlt_frame_set_position( mlt_frame this, mlt_position value ) -{ - return mlt_properties_set_position( MLT_FRAME_PROPERTIES( this ), "_position", value ); -} - -/** Stack a get_image callback. -*/ - -int mlt_frame_push_get_image( mlt_frame this, mlt_get_image get_image ) -{ - return mlt_deque_push_back( this->stack_image, get_image ); -} - -/** Pop a get_image callback. -*/ - -mlt_get_image mlt_frame_pop_get_image( mlt_frame this ) -{ - return mlt_deque_pop_back( this->stack_image ); -} - -/** Push a frame. -*/ - -int mlt_frame_push_frame( mlt_frame this, mlt_frame that ) -{ - return mlt_deque_push_back( this->stack_image, that ); -} - -/** Pop a frame. -*/ - -mlt_frame mlt_frame_pop_frame( mlt_frame this ) -{ - return mlt_deque_pop_back( this->stack_image ); -} - -/** Push a service. -*/ - -int mlt_frame_push_service( mlt_frame this, void *that ) -{ - return mlt_deque_push_back( this->stack_image, that ); -} - -/** Pop a service. -*/ - -void *mlt_frame_pop_service( mlt_frame this ) -{ - return mlt_deque_pop_back( this->stack_image ); -} - -/** Push a service. -*/ - -int mlt_frame_push_service_int( mlt_frame this, int that ) -{ - return mlt_deque_push_back_int( this->stack_image, that ); -} - -/** Pop a service. -*/ - -int mlt_frame_pop_service_int( mlt_frame this ) -{ - return mlt_deque_pop_back_int( this->stack_image ); -} - -/** Push an audio item on the stack. -*/ - -int mlt_frame_push_audio( mlt_frame this, void *that ) -{ - return mlt_deque_push_back( this->stack_audio, that ); -} - -/** Pop an audio item from the stack -*/ - -void *mlt_frame_pop_audio( mlt_frame this ) -{ - return mlt_deque_pop_back( this->stack_audio ); -} - -/** Return the service stack -*/ - -mlt_deque mlt_frame_service_stack( mlt_frame this ) -{ - return this->stack_service; -} - -/** Replace image stack with the information provided. - - This might prove to be unreliable and restrictive - the idea is that a transition - which normally uses two images may decide to only use the b frame (ie: in the case - of a composite where the b frame completely obscures the a frame). - - The image must be writable and the destructor for the image itself must be taken - care of on another frame and that frame cannot have a replace applied to it... - Further it assumes that no alpha mask is in use. - - For these reasons, it can only be used in a specific situation - when you have - multiple tracks each with their own transition and these transitions are applied - in a strictly reversed order (ie: highest numbered [lowest track] is processed - first). - - More reliable approach - the cases should be detected during the process phase - and the upper tracks should simply not be invited to stack... -*/ - -void mlt_frame_replace_image( mlt_frame this, uint8_t *image, mlt_image_format format, int width, int height ) -{ - // Remove all items from the stack - while( mlt_deque_pop_back( this->stack_image ) ) ; - - // Update the information - mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "image", image, 0, NULL, NULL ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "width", width ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "height", height ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "format", format ); - this->get_alpha_mask = NULL; -} - -/** Get the image associated to the frame. -*/ - -int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - mlt_get_image get_image = mlt_frame_pop_get_image( this ); - mlt_producer producer = mlt_properties_get_data( properties, "test_card_producer", NULL ); - int error = 0; - - if ( get_image != NULL ) - { - mlt_properties_set_int( properties, "image_count", mlt_properties_get_int( properties, "image_count" ) - 1 ); - mlt_position position = mlt_frame_get_position( this ); - error = get_image( this, buffer, format, width, height, writable ); - mlt_properties_set_int( properties, "width", *width ); - mlt_properties_set_int( properties, "height", *height ); - mlt_properties_set_int( properties, "format", *format ); - mlt_frame_set_position( this, position ); - } - else if ( mlt_properties_get_data( properties, "image", NULL ) != NULL ) - { - *format = mlt_properties_get_int( properties, "format" ); - *buffer = mlt_properties_get_data( properties, "image", NULL ); - *width = mlt_properties_get_int( properties, "width" ); - *height = mlt_properties_get_int( properties, "height" ); - } - else if ( producer != NULL ) - { - mlt_frame test_frame = NULL; - mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &test_frame, 0 ); - if ( test_frame != NULL ) - { - mlt_properties test_properties = MLT_FRAME_PROPERTIES( test_frame ); - mlt_properties_set_double( test_properties, "consumer_aspect_ratio", mlt_properties_get_double( properties, "consumer_aspect_ratio" ) ); - mlt_properties_set( test_properties, "rescale.interp", mlt_properties_get( properties, "rescale.interp" ) ); - mlt_frame_get_image( test_frame, buffer, format, width, height, writable ); - mlt_properties_set_data( properties, "test_card_frame", test_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); - mlt_properties_set_data( properties, "image", *buffer, *width * *height * 2, NULL, NULL ); - mlt_properties_set_int( properties, "width", *width ); - mlt_properties_set_int( properties, "height", *height ); - mlt_properties_set_int( properties, "format", *format ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( test_frame ) ); - } - else - { - mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL ); - mlt_frame_get_image( this, buffer, format, width, height, writable ); - } - } - else - { - register uint8_t *p; - register uint8_t *q; - int size = 0; - - *width = *width == 0 ? 720 : *width; - *height = *height == 0 ? 576 : *height; - size = *width * *height; - - mlt_properties_set_int( properties, "format", *format ); - mlt_properties_set_int( properties, "width", *width ); - mlt_properties_set_int( properties, "height", *height ); - mlt_properties_set_int( properties, "aspect_ratio", 0 ); - - switch( *format ) - { - case mlt_image_none: - size = 0; - *buffer = NULL; - break; - case mlt_image_rgb24: - size *= 3; - size += *width * 3; - *buffer = mlt_pool_alloc( size ); - if ( *buffer ) - memset( *buffer, 255, size ); - break; - case mlt_image_rgb24a: - case mlt_image_opengl: - size *= 4; - size += *width * 4; - *buffer = mlt_pool_alloc( size ); - if ( *buffer ) - memset( *buffer, 255, size ); - break; - case mlt_image_yuv422: - size *= 2; - size += *width * 2; - *buffer = mlt_pool_alloc( size ); - p = *buffer; - q = p + size; - while ( p != NULL && p != q ) - { - *p ++ = 235; - *p ++ = 128; - } - break; - case mlt_image_yuv420p: - size = size * 3 / 2; - *buffer = mlt_pool_alloc( size ); - if ( *buffer ) - memset( *buffer, 255, size ); - break; - } - - mlt_properties_set_data( properties, "image", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "test_image", 1 ); - } - - mlt_properties_set_int( properties, "scaled_width", *width ); - mlt_properties_set_int( properties, "scaled_height", *height ); - - return error; -} - -uint8_t *mlt_frame_get_alpha_mask( mlt_frame this ) -{ - uint8_t *alpha = NULL; - if ( this != NULL ) - { - if ( this->get_alpha_mask != NULL ) - alpha = this->get_alpha_mask( this ); - if ( alpha == NULL ) - alpha = mlt_properties_get_data( &this->parent, "alpha", NULL ); - if ( alpha == NULL ) - { - int size = mlt_properties_get_int( &this->parent, "scaled_width" ) * mlt_properties_get_int( &this->parent, "scaled_height" ); - alpha = mlt_pool_alloc( size ); - memset( alpha, 255, size ); - mlt_properties_set_data( &this->parent, "alpha", alpha, size, mlt_pool_release, NULL ); - } - } - return alpha; -} - -int mlt_frame_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - mlt_get_audio get_audio = mlt_frame_pop_audio( this ); - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - int hide = mlt_properties_get_int( properties, "test_audio" ); - - if ( hide == 0 && get_audio != NULL ) - { - mlt_position position = mlt_frame_get_position( this ); - get_audio( this, buffer, format, frequency, channels, samples ); - mlt_frame_set_position( this, position ); - } - else if ( mlt_properties_get_data( properties, "audio", NULL ) ) - { - *buffer = mlt_properties_get_data( properties, "audio", NULL ); - *frequency = mlt_properties_get_int( properties, "audio_frequency" ); - *channels = mlt_properties_get_int( properties, "audio_channels" ); - *samples = mlt_properties_get_int( properties, "audio_samples" ); - } - else - { - int size = 0; - *samples = *samples <= 0 ? 1920 : *samples; - *channels = *channels <= 0 ? 2 : *channels; - *frequency = *frequency <= 0 ? 48000 : *frequency; - size = *samples * *channels * sizeof( int16_t ); - *buffer = mlt_pool_alloc( size ); - if ( *buffer != NULL ) - memset( *buffer, 0, size ); - mlt_properties_set_data( properties, "audio", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "test_audio", 1 ); - } - - mlt_properties_set_int( properties, "audio_frequency", *frequency ); - mlt_properties_set_int( properties, "audio_channels", *channels ); - mlt_properties_set_int( properties, "audio_samples", *samples ); - - if ( mlt_properties_get( properties, "meta.volume" ) ) - { - double value = mlt_properties_get_double( properties, "meta.volume" ); - - if ( value == 0.0 ) - { - memset( *buffer, 0, *samples * *channels * 2 ); - } - else if ( value != 1.0 ) - { - int total = *samples * *channels; - int16_t *p = *buffer; - while ( total -- ) - { - *p = *p * value; - p ++; - } - } - - mlt_properties_set( properties, "meta.volume", NULL ); - } - - return 0; -} - -unsigned char *mlt_frame_get_waveform( mlt_frame this, int w, int h ) -{ - int16_t *pcm = NULL; - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - mlt_audio_format format = mlt_audio_pcm; - int frequency = 32000; // lower frequency available? - int channels = 2; - double fps = mlt_profile_fps( NULL ); - int samples = mlt_sample_calculator( fps, frequency, mlt_frame_get_position( this ) ); - - // Get the pcm data - mlt_frame_get_audio( this, &pcm, &format, &frequency, &channels, &samples ); - - // Make an 8-bit buffer large enough to hold rendering - int size = w * h; - unsigned char *bitmap = ( unsigned char* )mlt_pool_alloc( size ); - if ( bitmap != NULL ) - memset( bitmap, 0, size ); - mlt_properties_set_data( properties, "waveform", bitmap, size, ( mlt_destructor )mlt_pool_release, NULL ); - - // Render vertical lines - int16_t *ubound = pcm + samples * channels; - int skip = samples / w - 1; - int i, j, k; - - // Iterate sample stream and along x coordinate - for ( i = 0; i < w && pcm < ubound; i++ ) - { - // pcm data has channels interleaved - for ( j = 0; j < channels; j++ ) - { - // Determine sample's magnitude from 2s complement; - int pcm_magnitude = *pcm < 0 ? ~(*pcm) + 1 : *pcm; - // The height of a line is the ratio of the magnitude multiplied by - // half the vertical resolution - int height = ( int )( ( double )( pcm_magnitude ) / 32768 * h / 2 ); - // Determine the starting y coordinate - left channel above center, - // right channel below - currently assumes 2 channels - int displacement = ( h / 2 ) - ( 1 - j ) * height; - // Position buffer pointer using y coordinate, stride, and x coordinate - unsigned char *p = &bitmap[ i + displacement * w ]; - - // Draw vertical line - for ( k = 0; k < height; k++ ) - p[ w * k ] = 0xFF; - - pcm++; - } - pcm += skip * channels; - } - - return bitmap; -} - -mlt_producer mlt_frame_get_original_producer( mlt_frame this ) -{ - if ( this != NULL ) - return mlt_properties_get_data( MLT_FRAME_PROPERTIES( this ), "_producer", NULL ); - return NULL; -} - -void mlt_frame_close( mlt_frame this ) -{ - if ( this != NULL && mlt_properties_dec_ref( MLT_FRAME_PROPERTIES( this ) ) <= 0 ) - { - mlt_deque_close( this->stack_image ); - mlt_deque_close( this->stack_audio ); - while( mlt_deque_peek_back( this->stack_service ) ) - mlt_service_close( mlt_deque_pop_back( this->stack_service ) ); - mlt_deque_close( this->stack_service ); - mlt_properties_close( &this->parent ); - free( this ); - } -} - -/***** convenience functions *****/ - -int mlt_convert_yuv422_to_rgb24a( uint8_t *yuv, uint8_t *rgba, unsigned int total ) -{ - int ret = 0; - int yy, uu, vv; - int r,g,b; - total /= 2; - while (total--) - { - yy = yuv[0]; - uu = yuv[1]; - vv = yuv[3]; - YUV2RGB(yy, uu, vv, r, g, b); - rgba[0] = r; - rgba[1] = g; - rgba[2] = b; - rgba[3] = 255; - yy = yuv[2]; - YUV2RGB(yy, uu, vv, r, g, b); - rgba[4] = r; - rgba[5] = g; - rgba[6] = b; - rgba[7] = 255; - yuv += 4; - rgba += 8; - } - return ret; -} - -int mlt_convert_rgb24a_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha ) -{ - int ret = 0; - register int y0, y1, u0, u1, v0, v1; - register int r, g, b; - register uint8_t *d = yuv; - register int i, j; - - if ( alpha ) - for ( i = 0; i < height; i++ ) - { - register uint8_t *s = rgba + ( stride * i ); - for ( j = 0; j < ( width / 2 ); j++ ) - { - r = *s++; - g = *s++; - b = *s++; - *alpha++ = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - r = *s++; - g = *s++; - b = *s++; - *alpha++ = *s++; - RGB2YUV (r, g, b, y1, u1 , v1); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; - } - if ( width % 2 ) - { - r = *s++; - g = *s++; - b = *s++; - *alpha++ = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - *d++ = y0; - *d++ = u0; - } - } - else - for ( i = 0; i < height; i++ ) - { - register uint8_t *s = rgba + ( stride * i ); - for ( j = 0; j < ( width / 2 ); j++ ) - { - r = *s++; - g = *s++; - b = *s++; - s++; - RGB2YUV (r, g, b, y0, u0 , v0); - r = *s++; - g = *s++; - b = *s++; - s++; - RGB2YUV (r, g, b, y1, u1 , v1); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; - } - if ( width % 2 ) - { - r = *s++; - g = *s++; - b = *s++; - s++; - RGB2YUV (r, g, b, y0, u0 , v0); - *d++ = y0; - *d++ = u0; - } - } - - return ret; -} - -int mlt_convert_rgb24_to_yuv422( uint8_t *rgb, int width, int height, int stride, uint8_t *yuv ) -{ - int ret = 0; - register int y0, y1, u0, u1, v0, v1; - register int r, g, b; - register uint8_t *d = yuv; - register int i, j; - - for ( i = 0; i < height; i++ ) - { - register uint8_t *s = rgb + ( stride * i ); - for ( j = 0; j < ( width / 2 ); j++ ) - { - r = *s++; - g = *s++; - b = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - r = *s++; - g = *s++; - b = *s++; - RGB2YUV (r, g, b, y1, u1 , v1); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; - } - if ( width % 2 ) - { - r = *s++; - g = *s++; - b = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - *d++ = y0; - *d++ = u0; - } - } - return ret; -} - -int mlt_convert_bgr24a_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha ) -{ - int ret = 0; - register int y0, y1, u0, u1, v0, v1; - register int r, g, b; - register uint8_t *d = yuv; - register int i, j; - - if ( alpha ) - for ( i = 0; i < height; i++ ) - { - register uint8_t *s = rgba + ( stride * i ); - for ( j = 0; j < ( width / 2 ); j++ ) - { - b = *s++; - g = *s++; - r = *s++; - *alpha++ = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - b = *s++; - g = *s++; - r = *s++; - *alpha++ = *s++; - RGB2YUV (r, g, b, y1, u1 , v1); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; - } - if ( width % 2 ) - { - b = *s++; - g = *s++; - r = *s++; - *alpha++ = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - *d++ = y0; - *d++ = u0; - } - } - else - for ( i = 0; i < height; i++ ) - { - register uint8_t *s = rgba + ( stride * i ); - for ( j = 0; j < ( width / 2 ); j++ ) - { - b = *s++; - g = *s++; - r = *s++; - s++; - RGB2YUV (r, g, b, y0, u0 , v0); - b = *s++; - g = *s++; - r = *s++; - s++; - RGB2YUV (r, g, b, y1, u1 , v1); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; - } - if ( width % 2 ) - { - b = *s++; - g = *s++; - r = *s++; - s++; - RGB2YUV (r, g, b, y0, u0 , v0); - *d++ = y0; - *d++ = u0; - } - } - return ret; -} - -int mlt_convert_bgr24_to_yuv422( uint8_t *rgb, int width, int height, int stride, uint8_t *yuv ) -{ - int ret = 0; - register int y0, y1, u0, u1, v0, v1; - register int r, g, b; - register uint8_t *d = yuv; - register int i, j; - - for ( i = 0; i < height; i++ ) - { - register uint8_t *s = rgb + ( stride * i ); - for ( j = 0; j < ( width / 2 ); j++ ) - { - b = *s++; - g = *s++; - r = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - b = *s++; - g = *s++; - r = *s++; - RGB2YUV (r, g, b, y1, u1 , v1); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; - } - if ( width % 2 ) - { - b = *s++; - g = *s++; - r = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - *d++ = y0; - *d++ = u0; - } - } - return ret; -} - -int mlt_convert_argb_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha ) -{ - int ret = 0; - register int y0, y1, u0, u1, v0, v1; - register int r, g, b; - register uint8_t *d = yuv; - register int i, j; - - if ( alpha ) - for ( i = 0; i < height; i++ ) - { - register uint8_t *s = rgba + ( stride * i ); - for ( j = 0; j < ( width / 2 ); j++ ) - { - *alpha++ = *s++; - r = *s++; - g = *s++; - b = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - *alpha++ = *s++; - r = *s++; - g = *s++; - b = *s++; - RGB2YUV (r, g, b, y1, u1 , v1); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; - } - if ( width % 2 ) - { - *alpha++ = *s++; - r = *s++; - g = *s++; - b = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - *d++ = y0; - *d++ = u0; - } - } - else - for ( i = 0; i < height; i++ ) - { - register uint8_t *s = rgba + ( stride * i ); - for ( j = 0; j < ( width / 2 ); j++ ) - { - s++; - r = *s++; - g = *s++; - b = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - s++; - r = *s++; - g = *s++; - b = *s++; - RGB2YUV (r, g, b, y1, u1 , v1); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; - } - if ( width % 2 ) - { - s++; - r = *s++; - g = *s++; - b = *s++; - RGB2YUV (r, g, b, y0, u0 , v0); - *d++ = y0; - *d++ = u0; - } - } - return ret; -} - -int mlt_convert_yuv420p_to_yuv422( uint8_t *yuv420p, int width, int height, int stride, uint8_t *yuv ) -{ - int ret = 0; - register int i, j; - - int half = width >> 1; - - uint8_t *Y = yuv420p; - uint8_t *U = Y + width * height; - uint8_t *V = U + width * height / 4; - - register uint8_t *d = yuv; - - for ( i = 0; i < height; i++ ) - { - register uint8_t *u = U + ( i / 2 ) * ( half ); - register uint8_t *v = V + ( i / 2 ) * ( half ); - - for ( j = 0; j < half; j++ ) - { - *d ++ = *Y ++; - *d ++ = *u ++; - *d ++ = *Y ++; - *d ++ = *v ++; - } - } - return ret; -} - -uint8_t *mlt_resize_alpha( uint8_t *input, int owidth, int oheight, int iwidth, int iheight, uint8_t alpha_value ) -{ - uint8_t *output = NULL; - - if ( input != NULL && ( iwidth != owidth || iheight != oheight ) && ( owidth > 6 && oheight > 6 ) ) - { - uint8_t *out_line; - int offset_x = ( owidth - iwidth ) / 2; - int offset_y = ( oheight - iheight ) / 2; - int iused = iwidth; - - output = mlt_pool_alloc( owidth * oheight ); - memset( output, alpha_value, owidth * oheight ); - - offset_x -= offset_x % 2; - - out_line = output + offset_y * owidth; - out_line += offset_x; - - // Loop for the entirety of our output height. - while ( iheight -- ) - { - // We're in the input range for this row. - memcpy( out_line, input, iused ); - - // Move to next input line - input += iwidth; - - // Move to next output line - out_line += owidth; - } - } - - return output; -} - -void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input, int iwidth, int iheight ) -{ - // Calculate strides - int istride = iwidth * 2; - int ostride = owidth * 2; - int offset_x = ( owidth - iwidth ); - int offset_y = ( oheight - iheight ) / 2; - uint8_t *in_line = input; - uint8_t *out_line; - int size = owidth * oheight; - uint8_t *p = output; - - // Optimisation point - if ( output == NULL || input == NULL || ( owidth <= 6 || oheight <= 6 || iwidth <= 6 || oheight <= 6 ) ) - { - return; - } - else if ( iwidth == owidth && iheight == oheight ) - { - memcpy( output, input, iheight * istride ); - return; - } - - while( size -- ) - { - *p ++ = 16; - *p ++ = 128; - } - - offset_x -= offset_x % 4; - - out_line = output + offset_y * ostride; - out_line += offset_x; - - // Loop for the entirety of our output height. - while ( iheight -- ) - { - // We're in the input range for this row. - memcpy( out_line, in_line, iwidth * 2 ); - - // Move to next input line - in_line += istride; - - // Move to next output line - out_line += ostride; - } -} - -/** A resizing function for yuv422 frames - this does not rescale, but simply - resizes. It assumes yuv422 images available on the frame so use with care. -*/ - -uint8_t *mlt_frame_resize_yuv422( mlt_frame this, int owidth, int oheight ) -{ - // Get properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get the input image, width and height - uint8_t *input = mlt_properties_get_data( properties, "image", NULL ); - uint8_t *alpha = mlt_frame_get_alpha_mask( this ); - - int iwidth = mlt_properties_get_int( properties, "width" ); - int iheight = mlt_properties_get_int( properties, "height" ); - - // If width and height are correct, don't do anything - if ( iwidth != owidth || iheight != oheight ) - { - uint8_t alpha_value = mlt_properties_get_int( properties, "resize_alpha" ); - - // Create the output image - uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 ); - - // Call the generic resize - mlt_resize_yuv422( output, owidth, oheight, input, iwidth, iheight ); - - // Now update the frame - mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", owidth ); - mlt_properties_set_int( properties, "height", oheight ); - - // We should resize the alpha too - alpha = mlt_resize_alpha( alpha, owidth, oheight, iwidth, iheight, alpha_value ); - if ( alpha != NULL ) - { - mlt_properties_set_data( properties, "alpha", alpha, owidth * oheight, ( mlt_destructor )mlt_pool_release, NULL ); - this->get_alpha_mask = NULL; - } - - // Return the output - return output; - } - // No change, return input - return input; -} - -/** A rescaling function for yuv422 frames - low quality, and provided for testing - only. It assumes yuv422 images available on the frame so use with care. -*/ - -uint8_t *mlt_frame_rescale_yuv422( mlt_frame this, int owidth, int oheight ) -{ - // Get properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get the input image, width and height - uint8_t *input = mlt_properties_get_data( properties, "image", NULL ); - int iwidth = mlt_properties_get_int( properties, "width" ); - int iheight = mlt_properties_get_int( properties, "height" ); - - // If width and height are correct, don't do anything - if ( iwidth != owidth || iheight != oheight ) - { - // Create the output image - uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 ); - - // Calculate strides - int istride = iwidth * 2; - int ostride = owidth * 2; - - iwidth = iwidth - ( iwidth % 4 ); - - // Derived coordinates - int dy, dx; - - // Calculate ranges - int out_x_range = owidth / 2; - int out_y_range = oheight / 2; - int in_x_range = iwidth / 2; - int in_y_range = iheight / 2; - - // Output pointers - register uint8_t *out_line = output; - register uint8_t *out_ptr; - - // Calculate a middle pointer - uint8_t *in_middle = input + istride * in_y_range + in_x_range * 2; - uint8_t *in_line; - - // Generate the affine transform scaling values - register int scale_width = ( iwidth << 16 ) / owidth; - register int scale_height = ( iheight << 16 ) / oheight; - register int base = 0; - - int outer = out_x_range * scale_width; - int bottom = out_y_range * scale_height; - - // Loop for the entirety of our output height. - for ( dy = - bottom; dy < bottom; dy += scale_height ) - { - // Start at the beginning of the line - out_ptr = out_line; - - // Pointer to the middle of the input line - in_line = in_middle + ( dy >> 16 ) * istride; - - // Loop for the entirety of our output row. - for ( dx = - outer; dx < outer; dx += scale_width ) - { - base = dx >> 15; - base &= 0xfffffffe; - *out_ptr ++ = *( in_line + base ); - base &= 0xfffffffc; - *out_ptr ++ = *( in_line + base + 1 ); - dx += scale_width; - base = dx >> 15; - base &= 0xfffffffe; - *out_ptr ++ = *( in_line + base ); - base &= 0xfffffffc; - *out_ptr ++ = *( in_line + base + 3 ); - } - - // Move to next output line - out_line += ostride; - } - - // Now update the frame - mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", owidth ); - mlt_properties_set_int( properties, "height", oheight ); - - // Return the output - return output; - } - - // No change, return input - return input; -} - -int mlt_frame_mix_audio( mlt_frame this, mlt_frame that, float weight_start, float weight_end, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - int ret = 0; - int16_t *src, *dest; - int frequency_src = *frequency, frequency_dest = *frequency; - int channels_src = *channels, channels_dest = *channels; - int samples_src = *samples, samples_dest = *samples; - int i, j; - double d = 0, s = 0; - - mlt_frame_get_audio( that, &src, format, &frequency_src, &channels_src, &samples_src ); - mlt_frame_get_audio( this, &dest, format, &frequency_dest, &channels_dest, &samples_dest ); - - int silent = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "silent_audio" ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "silent_audio", 0 ); - if ( silent ) - memset( dest, 0, samples_dest * channels_dest * sizeof( int16_t ) ); - - silent = mlt_properties_get_int( MLT_FRAME_PROPERTIES( that ), "silent_audio" ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( that ), "silent_audio", 0 ); - if ( silent ) - memset( src, 0, samples_src * channels_src * sizeof( int16_t ) ); - - if ( channels_src > 6 ) - channels_src = 0; - if ( channels_dest > 6 ) - channels_dest = 0; - if ( samples_src > 4000 ) - samples_src = 0; - if ( samples_dest > 4000 ) - samples_dest = 0; - - // determine number of samples to process - *samples = samples_src < samples_dest ? samples_src : samples_dest; - *channels = channels_src < channels_dest ? channels_src : channels_dest; - *buffer = dest; - *frequency = frequency_dest; - - // Compute a smooth ramp over start to end - float weight = weight_start; - float weight_step = ( weight_end - weight_start ) / *samples; - - if ( src == dest ) - { - *samples = samples_src; - *channels = channels_src; - *buffer = src; - *frequency = frequency_src; - return ret; - } - - // Mixdown - for ( i = 0; i < *samples; i++ ) - { - for ( j = 0; j < *channels; j++ ) - { - if ( j < channels_dest ) - d = (double) dest[ i * channels_dest + j ]; - if ( j < channels_src ) - s = (double) src[ i * channels_src + j ]; - dest[ i * channels_dest + j ] = s * weight + d * ( 1.0 - weight ); - } - weight += weight_step; - } - - return ret; -} - -// Replacement for broken mlt_frame_audio_mix - this filter uses an inline low pass filter -// to allow mixing without volume hacking -int mlt_frame_combine_audio( mlt_frame this, mlt_frame that, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - int ret = 0; - int16_t *src, *dest; - int frequency_src = *frequency, frequency_dest = *frequency; - int channels_src = *channels, channels_dest = *channels; - int samples_src = *samples, samples_dest = *samples; - int i, j; - double vp[ 6 ]; - double b_weight = 1.0; - - if ( mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "meta.mixdown" ) ) - b_weight = 1.0 - mlt_properties_get_double( MLT_FRAME_PROPERTIES( this ), "meta.volume" ); - - mlt_frame_get_audio( that, &src, format, &frequency_src, &channels_src, &samples_src ); - mlt_frame_get_audio( this, &dest, format, &frequency_dest, &channels_dest, &samples_dest ); - - int silent = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "silent_audio" ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "silent_audio", 0 ); - if ( silent ) - memset( dest, 0, samples_dest * channels_dest * sizeof( int16_t ) ); - - silent = mlt_properties_get_int( MLT_FRAME_PROPERTIES( that ), "silent_audio" ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( that ), "silent_audio", 0 ); - if ( silent ) - memset( src, 0, samples_src * channels_src * sizeof( int16_t ) ); - - if ( src == dest ) - { - *samples = samples_src; - *channels = channels_src; - *buffer = src; - *frequency = frequency_src; - return ret; - } - - // determine number of samples to process - *samples = samples_src < samples_dest ? samples_src : samples_dest; - *channels = channels_src < channels_dest ? channels_src : channels_dest; - *buffer = dest; - *frequency = frequency_dest; - - for ( j = 0; j < *channels; j++ ) - vp[ j ] = ( double )dest[ j ]; - - double Fc = 0.5; - double B = exp(-2.0 * M_PI * Fc); - double A = 1.0 - B; - double v; - - for ( i = 0; i < *samples; i++ ) - { - for ( j = 0; j < *channels; j++ ) - { - v = ( double )( b_weight * dest[ i * channels_dest + j ] + src[ i * channels_src + j ] ); - v = v < -32767 ? -32767 : v > 32768 ? 32768 : v; - vp[ j ] = dest[ i * channels_dest + j ] = ( int16_t )( v * A + vp[ j ] * B ); - } - } - - return ret; -} - -/* Will this break when mlt_position is converted to double? -Zach */ -int mlt_sample_calculator( float fps, int frequency, int64_t position ) -{ - int samples = 0; - - if ( ( int )( fps * 100 ) == 2997 ) - { - samples = frequency / 30; - - switch ( frequency ) - { - case 48000: - if ( position % 5 != 0 ) - samples += 2; - break; - case 44100: - if ( position % 300 == 0 ) - samples = 1471; - else if ( position % 30 == 0 ) - samples = 1470; - else if ( position % 2 == 0 ) - samples = 1472; - else - samples = 1471; - break; - case 32000: - if ( position % 30 == 0 ) - samples = 1068; - else if ( position % 29 == 0 ) - samples = 1067; - else if ( position % 4 == 2 ) - samples = 1067; - else - samples = 1068; - break; - default: - samples = 0; - } - } - else if ( fps != 0 ) - { - samples = frequency / fps; - } - - return samples; -} - -int64_t mlt_sample_calculator_to_now( float fps, int frequency, int64_t frame ) -{ - int64_t samples = 0; - - // TODO: Correct rules for NTSC and drop the * 100 hack - if ( ( int )( fps * 100 ) == 2997 ) - { - samples = ( ( double )( frame * frequency ) / 30 ); - switch( frequency ) - { - case 48000: - samples += 2 * ( frame / 5 ); - break; - case 44100: - samples += frame + ( frame / 2 ) - ( frame / 30 ) + ( frame / 300 ); - break; - case 32000: - samples += ( 2 * frame ) - ( frame / 4 ) - ( frame / 29 ); - break; - } - } - else if ( fps != 0 ) - { - samples = ( ( frame * frequency ) / ( int )fps ); - } - - return samples; -} diff --git a/src/framework/mlt_frame.h b/src/framework/mlt_frame.h deleted file mode 100644 index bd586a7..0000000 --- a/src/framework/mlt_frame.h +++ /dev/null @@ -1,144 +0,0 @@ -/** - * \file mlt_frame.h - * \brief interface for all frame classes - * \see mlt_frame_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_FRAME_H_ -#define _MLT_FRAME_H_ - -#include "mlt_properties.h" -#include "mlt_deque.h" -#include "mlt_service.h" - -/** callback function to get video data - * - */ - -typedef int ( *mlt_get_image )( mlt_frame self, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ); - -/** callback function to get audio data - * - */ - -typedef int ( *mlt_get_audio )( mlt_frame self, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ); - -/** \brief Frame class - * - * \properties \em test_image set if the frame holds a "test card" image - * \properties \em test_audio set if the frame holds "test card" audio - * \properties \em _producer holds a reference to the frame's end producer - * \properties \em _speed the current speed of the producer that generated the frame - * \properties \em _position the position of the frame - * \properties \em meta.* holds metadata - * \properties \em hide set to 1 to hide the video, 2 to mute the audio - * \properties \em last_track a flag to indicate an end-of-tracks frame - */ - -struct mlt_frame_s -{ - /* We're extending properties here */ - struct mlt_properties_s parent; - - /* Virtual methods */ - uint8_t * ( *get_alpha_mask )( mlt_frame self ); - - /* Private properties */ - mlt_deque stack_image; - mlt_deque stack_audio; - mlt_deque stack_service; -}; - -#define MLT_FRAME_PROPERTIES( frame ) ( &( frame )->parent ) -#define MLT_FRAME_SERVICE_STACK( frame ) ( ( frame )->stack_service ) -#define MLT_FRAME_IMAGE_STACK( frame ) ( ( frame )->stack_image ) -#define MLT_FRAME_AUDIO_STACK( frame ) ( ( frame )->stack_audio ) - -extern mlt_frame mlt_frame_init( mlt_service service ); -extern mlt_properties mlt_frame_properties( mlt_frame self ); -extern int mlt_frame_is_test_card( mlt_frame self ); -extern int mlt_frame_is_test_audio( mlt_frame self ); -extern double mlt_frame_get_aspect_ratio( mlt_frame self ); -extern int mlt_frame_set_aspect_ratio( mlt_frame self, double value ); -extern mlt_position mlt_frame_get_position( mlt_frame self ); -extern int mlt_frame_set_position( mlt_frame self, mlt_position value ); -extern void mlt_frame_replace_image( mlt_frame self, uint8_t *image, mlt_image_format format, int width, int height ); -extern int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ); -extern uint8_t *mlt_frame_get_alpha_mask( mlt_frame self ); -extern int mlt_frame_get_audio( mlt_frame self, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ); -extern unsigned char *mlt_frame_get_waveform( mlt_frame self, int w, int h ); -extern int mlt_frame_push_get_image( mlt_frame self, mlt_get_image get_image ); -extern mlt_get_image mlt_frame_pop_get_image( mlt_frame self ); -extern int mlt_frame_push_frame( mlt_frame self, mlt_frame that ); -extern mlt_frame mlt_frame_pop_frame( mlt_frame self ); -extern int mlt_frame_push_service( mlt_frame self, void *that ); -extern void *mlt_frame_pop_service( mlt_frame self ); -extern int mlt_frame_push_service_int( mlt_frame self, int that ); -extern int mlt_frame_pop_service_int( mlt_frame self ); -extern int mlt_frame_push_audio( mlt_frame self, void *that ); -extern void *mlt_frame_pop_audio( mlt_frame self ); -extern mlt_deque mlt_frame_service_stack( mlt_frame self ); -extern mlt_producer mlt_frame_get_original_producer( mlt_frame self ); -extern void mlt_frame_close( mlt_frame self ); - -/* convenience functions */ -extern int mlt_convert_yuv422_to_rgb24a( uint8_t *yuv, uint8_t *rgba, unsigned int total ); -extern int mlt_convert_rgb24a_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha ); -extern int mlt_convert_rgb24_to_yuv422( uint8_t *rgb, int width, int height, int stride, uint8_t *yuv ); -extern int mlt_convert_bgr24a_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha ); -extern int mlt_convert_argb_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha ); -extern int mlt_convert_bgr24_to_yuv422( uint8_t *rgb, int width, int height, int stride, uint8_t *yuv ); -extern int mlt_convert_yuv420p_to_yuv422( uint8_t *yuv420p, int width, int height, int stride, uint8_t *yuv ); -extern uint8_t *mlt_frame_resize_yuv422( mlt_frame self, int owidth, int oheight ); -extern uint8_t *mlt_frame_rescale_yuv422( mlt_frame self, int owidth, int oheight ); -extern void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input, int iwidth, int iheight ); -extern int mlt_frame_mix_audio( mlt_frame self, mlt_frame that, float weight_start, float weight_end, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ); -extern int mlt_frame_combine_audio( mlt_frame self, mlt_frame that, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ); -extern int mlt_sample_calculator( float fps, int frequency, int64_t position ); -extern int64_t mlt_sample_calculator_to_now( float fps, int frequency, int64_t position ); - -/** This macro scales rgb into the yuv gamut - y is scaled by 219/255 and uv by 224/255. */ -#define RGB2YUV(r, g, b, y, u, v)\ - y = ((263*r + 516*g + 100*b) >> 10) + 16;\ - u = ((-152*r - 298*g + 450*b) >> 10) + 128;\ - v = ((450*r - 377*g - 73*b) >> 10) + 128; - -/** This macro assumes the user has already scaled their rgb down into the broadcast limits. **/ -#define RGB2YUV_UNSCALED(r, g, b, y, u, v)\ - y = (299*r + 587*g + 114*b) >> 10;\ - u = ((-169*r - 331*g + 500*b) >> 10) + 128;\ - v = ((500*r - 419*g - 81*b) >> 10) + 128;\ - y = y < 16 ? 16 : y;\ - u = u < 16 ? 16 : u;\ - v = v < 16 ? 16 : v;\ - y = y > 235 ? 235 : y;\ - u = u > 240 ? 240 : u;\ - v = v > 240 ? 240 : v - -/** This macro converts a YUV value to the RGB color space. */ -#define YUV2RGB( y, u, v, r, g, b ) \ - r = ((1192 * ( y - 16 ) + 1634 * ( v - 128 ) ) >> 10 ); \ - g = ((1192 * ( y - 16 ) - 832 * ( v - 128 ) - 400 * ( u - 128 ) ) >> 10 ); \ - b = ((1192 * ( y - 16 ) + 2066 * ( u - 128 ) ) >> 10 ); \ - r = r < 0 ? 0 : r > 255 ? 255 : r; \ - g = g < 0 ? 0 : g > 255 ? 255 : g; \ - b = b < 0 ? 0 : b > 255 ? 255 : b; - -#endif diff --git a/src/framework/mlt_geometry.c b/src/framework/mlt_geometry.c deleted file mode 100644 index db9c877..0000000 --- a/src/framework/mlt_geometry.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * mlt_geometry.c -- provides the geometry API - * Copyright (C) 2004-2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_geometry.h" -#include "mlt_tokeniser.h" -#include "mlt_factory.h" -#include "mlt_profile.h" - -#include -#include -#include -#include - -typedef struct geometry_item_s -{ - struct mlt_geometry_item_s data; - struct geometry_item_s *next, *prev; -} -*geometry_item; - -typedef struct -{ - char *data; - int length; - int nw; - int nh; - geometry_item item; -} -geometry_s, *geometry; - -// Create a new geometry structure -mlt_geometry mlt_geometry_init( ) -{ - mlt_geometry this = calloc( 1, sizeof( struct mlt_geometry_s ) ); - if ( this != NULL ) - { - this->local = calloc( 1, sizeof( geometry_s ) ); - if ( this->local != NULL ) - { - geometry self = this->local; - self->nw = 720; - self->nh = 576; - } - else - { - free( this ); - this = NULL; - } - } - return this; -} - -/** A linear step -*/ - -static inline double linearstep( double start, double end, double position, int length ) -{ - double o = ( end - start ) / length; - return start + position * o; -} - -static void mlt_geometry_virtual_refresh( mlt_geometry this ) -{ - geometry self = this->local; - - // Parse of all items to ensure unspecified keys are calculated correctly - if ( self->item != NULL ) - { - int i = 0; - for ( i = 0; i < 5; i ++ ) - { - geometry_item current = self->item; - while( current != NULL ) - { - int fixed = current->data.f[ i ]; - if ( !fixed ) - { - geometry_item prev = current->prev; - geometry_item next = current->next; - - double prev_value = 0; - double next_value = 0; - double value = 0; - - while( prev != NULL && !prev->data.f[ i ] ) prev = prev->prev; - while( next != NULL && !next->data.f[ i ] ) next = next->next; - - switch( i ) - { - case 0: - if ( prev ) prev_value = prev->data.x; - if ( next ) next_value = next->data.x; - break; - case 1: - if ( prev ) prev_value = prev->data.y; - if ( next ) next_value = next->data.y; - break; - case 2: - if ( prev ) prev_value = prev->data.w; - if ( next ) next_value = next->data.w; - break; - case 3: - if ( prev ) prev_value = prev->data.h; - if ( next ) next_value = next->data.h; - break; - case 4: - if ( prev ) prev_value = prev->data.mix; - if ( next ) next_value = next->data.mix; - break; - } - - // This should never happen - if ( prev == NULL ) - current->data.f[ i ] = 1; - else if ( next == NULL ) - value = prev_value; - else - value = linearstep( prev_value, next_value, current->data.frame - prev->data.frame, next->data.frame - prev->data.frame ); - - switch( i ) - { - case 0: current->data.x = value; break; - case 1: current->data.y = value; break; - case 2: current->data.w = value; break; - case 3: current->data.h = value; break; - case 4: current->data.mix = value; break; - } - } - - // Move to the next item - current = current->next; - } - } - } -} - -static int mlt_geometry_drop( mlt_geometry this, geometry_item item ) -{ - geometry self = this->local; - - if ( item == self->item ) - { - self->item = item->next; - if ( self->item != NULL ) - self->item->prev = NULL; - // To ensure correct seeding, ensure all values are fixed - if ( self->item != NULL ) - { - self->item->data.f[0] = 1; - self->item->data.f[1] = 1; - self->item->data.f[2] = 1; - self->item->data.f[3] = 1; - self->item->data.f[4] = 1; - } - } - else if ( item->next != NULL && item->prev != NULL ) - { - item->prev->next = item->next; - item->next->prev = item->prev; - } - else if ( item->next != NULL ) - { - item->next->prev = item->prev; - } - else if ( item->prev != NULL ) - { - item->prev->next = item->next; - } - - free( item ); - - return 0; -} - -static void mlt_geometry_clean( mlt_geometry this ) -{ - geometry self = this->local; - free( self->data ); - self->data = NULL; - while( self->item ) - mlt_geometry_drop( this, self->item ); -} - -// Parse the geometry specification for a given length and normalised width/height (-1 for default) -// data is constructed as: [frame=]X,Y:WxH[:mix][;[frame=]X,Y:WxH[:mix]]* -// and X, Y, W and H can have trailing % chars to indicate percentage of normalised size -int mlt_geometry_parse( mlt_geometry this, char *data, int length, int nw, int nh ) -{ - int i = 0; - - // Create a tokeniser - mlt_tokeniser tokens = mlt_tokeniser_init( ); - - // Get the local/private structure - geometry self = this->local; - - // Clean the existing geometry - mlt_geometry_clean( this ); - - // Update the info on the data - if ( length != -1 ) - self->length = length; - if ( nw != -1 ) - self->nw = nw; - if ( nh != -1 ) - self->nh = nh; - if ( data != NULL ) - self->data = strdup( data ); - - // Tokenise - if ( data != NULL ) - mlt_tokeniser_parse_new( tokens, data, ";" ); - - // Iterate through each token - for ( i = 0; i < mlt_tokeniser_count( tokens ); i ++ ) - { - struct mlt_geometry_item_s item; - char *value = mlt_tokeniser_get_string( tokens, i ); - - // Set item to 0 - memset( &item, 0, sizeof( struct mlt_geometry_item_s ) ); - - // Now parse the item - mlt_geometry_parse_item( this, &item, value ); - - // Now insert into place - mlt_geometry_insert( this, &item ); - } - - // Remove the tokeniser - mlt_tokeniser_close( tokens ); - - // ??? - return 0; -} - -// Conditionally refresh in case of a change -int mlt_geometry_refresh( mlt_geometry this, char *data, int length, int nw, int nh ) -{ - geometry self = this->local; - int changed = ( length != -1 && length != self->length ); - changed = changed || ( nw != -1 && nw != self->nw ); - changed = changed || ( nh != -1 && nh != self->nh ); - changed = changed || ( data != NULL && ( self->data == NULL || strcmp( data, self->data ) ) ); - if ( changed ) - return mlt_geometry_parse( this, data, length, nw, nh ); - return -1; -} - -int mlt_geometry_get_length( mlt_geometry this ) -{ - // Get the local/private structure - geometry self = this->local; - - // return the length - return self->length; -} - -void mlt_geometry_set_length( mlt_geometry this, int length ) -{ - // Get the local/private structure - geometry self = this->local; - - // set the length - self->length = length; -} - -int mlt_geometry_parse_item( mlt_geometry this, mlt_geometry_item item, char *value ) -{ - int ret = 0; - - // Get the local/private structure - geometry self = this->local; - - if ( value != NULL && strcmp( value, "" ) ) - { - char *p = strchr( value, '=' ); - int count = 0; - double temp; - - // Determine if a position has been specified - if ( p != NULL ) - { - temp = atof( value ); - if ( temp > -1 && temp < 1 ) - item->frame = temp * self->length; - else - item->frame = temp; - value = p + 1; - } - - // Special case - frame < 0 - if ( item->frame < 0 ) - item->frame += self->length; - - // Obtain the current value at this position - this allows new - // frames to be created which don't specify all values - mlt_geometry_fetch( this, item, item->frame ); - - // Special case - when an empty string is specified, all values are fixed - // TODO: Check if this is logical - it's convenient, but it's also odd... - if ( !*value ) - { - item->f[0] = 1; - item->f[1] = 1; - item->f[2] = 1; - item->f[3] = 1; - item->f[4] = 1; - } - - // Iterate through the remainder of value - while( *value ) - { - // Get the value - temp = strtod( value, &p ); - - // Check if a value was specified - if ( p != value ) - { - // Handle the % case - if ( *p == '%' ) - { - if ( count == 0 || count == 2 ) - temp *= self->nw / 100.0; - else if ( count == 1 || count == 3 ) - temp *= self->nh / 100.0; - p ++; - } - - // Special case - distort token - if ( *p == '!' || *p == '*' ) - { - p ++; - item->distort = 1; - } - - // Actually, we don't care about the delimiter at all.. - if ( *p ) p ++; - - // Assign to the item - switch( count ) - { - case 0: item->x = temp; item->f[0] = 1; break; - case 1: item->y = temp; item->f[1] = 1; break; - case 2: item->w = temp; item->f[2] = 1; break; - case 3: item->h = temp; item->f[3] = 1; break; - case 4: item->mix = temp; item->f[4] = 1; break; - } - } - else - { - p ++; - } - - // Update the value pointer - value = p; - count ++; - } - } - else - { - ret = 1; - } - - return ret; -} - -// Fetch a geometry item for an absolute position -int mlt_geometry_fetch( mlt_geometry this, mlt_geometry_item item, float position ) -{ - // Get the local geometry - geometry self = this->local; - - // Need to find the nearest key to the position specifed - geometry_item key = self->item; - - // Iterate through the keys until we reach last or have - while( key != NULL && key->next != NULL && position >= key->next->data.frame ) - key = key->next; - - if ( key != NULL ) - { - // Position is situated before the first key - all zeroes - if ( position < key->data.frame ) - { - memset( item, 0, sizeof( struct mlt_geometry_item_s ) ); - item->mix = 100; - } - // Position is a key itself - no iterpolation need - else if ( position == key->data.frame ) - { - memcpy( item, &key->data, sizeof( struct mlt_geometry_item_s ) ); - } - // Position is after the last key - no interpolation, but not a key frame - else if ( key->next == NULL ) - { - memcpy( item, &key->data, sizeof( struct mlt_geometry_item_s ) ); - item->key = 0; - item->f[ 0 ] = 0; - item->f[ 1 ] = 0; - item->f[ 2 ] = 0; - item->f[ 3 ] = 0; - item->f[ 4 ] = 0; - } - // Interpolation is needed - position > key and there is a following key - else - { - item->key = 0; - item->frame = position; - position -= key->data.frame; - item->x = linearstep( key->data.x, key->next->data.x, position, key->next->data.frame - key->data.frame ); - item->y = linearstep( key->data.y, key->next->data.y, position, key->next->data.frame - key->data.frame ); - item->w = linearstep( key->data.w, key->next->data.w, position, key->next->data.frame - key->data.frame ); - item->h = linearstep( key->data.h, key->next->data.h, position, key->next->data.frame - key->data.frame ); - item->mix = linearstep( key->data.mix, key->next->data.mix, position, key->next->data.frame - key->data.frame ); - item->distort = key->data.distort; - position += key->data.frame; - } - - item->frame = position; - } - else - { - memset( item, 0, sizeof( struct mlt_geometry_item_s ) ); - item->frame = position; - item->mix = 100; - } - - return key == NULL; -} - -// Specify a geometry item at an absolute position -int mlt_geometry_insert( mlt_geometry this, mlt_geometry_item item ) -{ - // Get the local/private geometry structure - geometry self = this->local; - - // Create a new local item (this may be removed if a key already exists at this position) - geometry_item new = calloc( 1, sizeof( struct geometry_item_s ) ); - memcpy( &new->data, item, sizeof( struct mlt_geometry_item_s ) ); - new->data.key = 1; - - // Determine if we need to insert or append to the list, or if it's a new list - if ( self->item != NULL ) - { - // Get the first item - geometry_item place = self->item; - - // Locate an existing nearby item - while ( place->next != NULL && item->frame > place->data.frame ) - place = place->next; - - if ( item->frame < place->data.frame ) - { - if ( place == self->item ) - self->item = new; - if ( place->prev ) - place->prev->next = new; - new->next = place; - new->prev = place->prev; - place->prev = new; - } - else if ( item->frame > place->data.frame ) - { - if ( place->next ) - place->next->prev = new; - new->next = place->next; - new->prev = place; - place->next = new; - } - else - { - memcpy( &place->data, &new->data, sizeof( struct mlt_geometry_item_s ) ); - free( new ); - } - } - else - { - // Set the first item - self->item = new; - - // To ensure correct seeding, ensure all values are fixed - self->item->data.f[0] = 1; - self->item->data.f[1] = 1; - self->item->data.f[2] = 1; - self->item->data.f[3] = 1; - self->item->data.f[4] = 1; - } - - // Refresh all geometries - mlt_geometry_virtual_refresh( this ); - - // TODO: Error checking - return 0; -} - -// Remove the key at the specified position -int mlt_geometry_remove( mlt_geometry this, int position ) -{ - int ret = 1; - - // Get the local/private geometry structure - geometry self = this->local; - - // Get the first item - geometry_item place = self->item; - - while( place != NULL && position != place->data.frame ) - place = place->next; - - if ( place != NULL && position == place->data.frame ) - ret = mlt_geometry_drop( this, place ); - - // Refresh all geometries - mlt_geometry_virtual_refresh( this ); - - return ret; -} - -// Get the key at the position or the next following -int mlt_geometry_next_key( mlt_geometry this, mlt_geometry_item item, int position ) -{ - // Get the local/private geometry structure - geometry self = this->local; - - // Get the first item - geometry_item place = self->item; - - while( place != NULL && position > place->data.frame ) - place = place->next; - - if ( place != NULL ) - memcpy( item, &place->data, sizeof( struct mlt_geometry_item_s ) ); - - return place == NULL; -} - -// Get the key at the position or the previous key -int mlt_geometry_prev_key( mlt_geometry this, mlt_geometry_item item, int position ) -{ - // Get the local/private geometry structure - geometry self = this->local; - - // Get the first item - geometry_item place = self->item; - - while( place != NULL && place->next != NULL && position >= place->next->data.frame ) - place = place->next; - - if ( place != NULL ) - memcpy( item, &place->data, sizeof( struct mlt_geometry_item_s ) ); - - return place == NULL; -} - -char *mlt_geometry_serialise_cut( mlt_geometry this, int in, int out ) -{ - geometry self = this->local; - struct mlt_geometry_item_s item; - char *ret = malloc( 1000 ); - int used = 0; - int size = 1000; - - if ( in == -1 ) - in = 0; - if ( out == -1 ) - out = mlt_geometry_get_length( this ); - - if ( ret != NULL ) - { - char temp[ 100 ]; - - strcpy( ret, "" ); - - item.frame = in; - - while( 1 ) - { - strcpy( temp, "" ); - - // If it's the first frame, then it's not necessarily a key - if ( item.frame == in ) - { - if ( mlt_geometry_fetch( this, &item, item.frame ) ) - break; - - // If the first key is larger than the current position - // then do nothing here - if ( self->item->data.frame > item.frame ) - { - item.frame ++; - continue; - } - - // To ensure correct seeding, ensure all values are fixed - item.f[0] = 1; - item.f[1] = 1; - item.f[2] = 1; - item.f[3] = 1; - item.f[4] = 1; - } - // Typically, we move from key to key - else if ( item.frame < out ) - { - if ( mlt_geometry_next_key( this, &item, item.frame ) ) - break; - - // Special case - crop at the out point - if ( item.frame > out ) - mlt_geometry_fetch( this, &item, out ); - } - // We've handled the last key - else - { - break; - } - - if ( item.frame - in != 0 ) - sprintf( temp, "%d=", item.frame - in ); - - if ( item.f[0] ) - sprintf( temp + strlen( temp ), "%.0f", item.x ); - strcat( temp, "," ); - if ( item.f[1] ) - sprintf( temp + strlen( temp ), "%.0f", item.y ); - strcat( temp, ":" ); - if ( item.f[2] ) - sprintf( temp + strlen( temp ), "%.0f", item.w ); - strcat( temp, "x" ); - if ( item.f[3] ) - sprintf( temp + strlen( temp ), "%.0f", item.h ); - if ( item.f[4] ) - sprintf( temp + strlen( temp ), ":%.0f", item.mix ); - - if ( used + strlen( temp ) > size ) - { - size += 1000; - ret = realloc( ret, size ); - } - - if ( ret != NULL && used != 0 ) - { - used ++; - strcat( ret, ";" ); - } - if ( ret != NULL ) - { - used += strlen( temp ); - strcat( ret, temp ); - } - - item.frame ++; - } - } - - return ret; -} - -// Serialise the current geometry -char *mlt_geometry_serialise( mlt_geometry this ) -{ - geometry self = this->local; - char *ret = mlt_geometry_serialise_cut( this, 0, self->length ); - if ( ret ) - { - free( self->data ); - self->data = ret; - } - return ret; -} - -// Close the geometry -void mlt_geometry_close( mlt_geometry this ) -{ - if ( this != NULL ) - { - mlt_geometry_clean( this ); - free( this->local ); - free( this ); - } -} - - diff --git a/src/framework/mlt_geometry.h b/src/framework/mlt_geometry.h deleted file mode 100644 index 8120184..0000000 --- a/src/framework/mlt_geometry.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * mlt_geometry.h -- provides the geometry API - * Copyright (C) 2004-2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_GEOMETRY_H -#define _MLT_GEOMETRY_H - -#include "mlt_types.h" - -struct mlt_geometry_item_s -{ - /* Will be 1 when this is a key frame */ - int key; - /* The actual frame this corresponds to */ - int frame; - /* Distort */ - int distort; - /* x,y are upper left */ - float x, y, w, h, mix; - /* Indicates which values are fixed */ - int f[ 5 ]; -}; - -struct mlt_geometry_s -{ - void *local; -}; - -/* Create a new geometry structure */ -extern mlt_geometry mlt_geometry_init( ); -/* Parse the geometry specification for a given length and normalised width/height (-1 for default) */ -extern int mlt_geometry_parse( mlt_geometry self, char *data, int length, int nw, int nh ); -/* Conditionally refresh the geometry if it's modified */ -extern int mlt_geometry_refresh( mlt_geometry self, char *data, int length, int nw, int nh ); -/* Get and set the length */ -extern int mlt_geometry_get_length( mlt_geometry self ); -extern void mlt_geometry_set_length( mlt_geometry self, int length ); -/* Parse an item - doesn't affect the geometry itself but uses current information for evaluation */ -/* (item->frame should be specified if not included in the data itself) */ -extern int mlt_geometry_parse_item( mlt_geometry self, mlt_geometry_item item, char *data ); -/* Fetch a geometry item for an absolute position */ -extern int mlt_geometry_fetch( mlt_geometry self, mlt_geometry_item item, float position ); -/* Specify a geometry item at an absolute position */ -extern int mlt_geometry_insert( mlt_geometry self, mlt_geometry_item item ); -/* Remove the key at the specified position */ -extern int mlt_geometry_remove( mlt_geometry self, int position ); -/* Get the key at the position or the next following */ -extern int mlt_geometry_next_key( mlt_geometry self, mlt_geometry_item item, int position ); -extern int mlt_geometry_prev_key( mlt_geometry self, mlt_geometry_item item, int position ); -/* Serialise the current geometry */ -extern char *mlt_geometry_serialise_cut( mlt_geometry self, int in, int out ); -extern char *mlt_geometry_serialise( mlt_geometry self ); -/* Close the geometry */ -extern void mlt_geometry_close( mlt_geometry self ); - -#endif - diff --git a/src/framework/mlt_log.c b/src/framework/mlt_log.c deleted file mode 100644 index 9a4c70b..0000000 --- a/src/framework/mlt_log.c +++ /dev/null @@ -1,80 +0,0 @@ -/** - * \file mlt_log.c - * \brief logging functions - * - * Copyright (c) 2003 Michel Bardiaux - * - * This file was a part of FFmpeg. - * - * FFmpeg 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. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mlt_log.h" -#include "mlt_service.h" - -#include - -static int log_level = MLT_LOG_INFO; - -void default_callback( void* ptr, int level, const char* fmt, va_list vl ) -{ - static int print_prefix = 1; - mlt_properties properties = ptr ? MLT_SERVICE_PROPERTIES( ( mlt_service )ptr ) : NULL; - - if ( level > log_level ) - return; - if ( print_prefix && properties ) - { - char *mlt_type = mlt_properties_get( properties, "mlt_type" ); - char *resource = mlt_properties_get( properties, "resource" ); - - if ( resource && *resource && resource[0] == '<' && resource[ strlen(resource) - 1 ] == '>' ) - mlt_type = resource; - fprintf( stderr, "[%s @ %p]", mlt_type, ptr ); - } - print_prefix = strstr( fmt, "\n" ) != NULL; - vfprintf( stderr, fmt, vl ); -} - -static void ( *callback )( void*, int, const char*, va_list ) = default_callback; - -void mlt_log( void* service, int level, const char *fmt, ...) -{ - va_list vl; - - va_start( vl, fmt ); - mlt_vlog( service, level, fmt, vl ); - va_end( vl ); -} - -void mlt_vlog( void* service, int level, const char *fmt, va_list vl ) -{ - if ( callback ) callback( service, level, fmt, vl ); -} - -int mlt_log_get_level( void ) -{ - return log_level; -} - -void mlt_log_set_level( int level ) -{ - log_level = level; -} - -void mlt_log_set_callback( void (*new_callback)( void*, int, const char*, va_list ) ) -{ - callback = new_callback; -} diff --git a/src/framework/mlt_log.h b/src/framework/mlt_log.h deleted file mode 100644 index ec9a134..0000000 --- a/src/framework/mlt_log.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * \file mlt_log.h - * \brief logging functions - * - * copyright (c) 2006 Michael Niedermayer - * - * This file was a part of FFmpeg. - * - * FFmpeg 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. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MLT_LOG_H -#define MLT_LOG_H - -#include - -#define MLT_LOG_QUIET -8 - -/** - * something went really wrong and we will crash now - */ -#define MLT_LOG_PANIC 0 - -/** - * something went wrong and recovery is not possible - * like no header in a format which depends on it or a combination - * of parameters which are not allowed - */ -#define MLT_LOG_FATAL 8 - -/** - * something went wrong and cannot losslessly be recovered - * but not all future data is affected - */ -#define MLT_LOG_ERROR 16 - -/** - * something somehow does not look correct / something which may or may not - * lead to some problems - */ -#define MLT_LOG_WARNING 24 - -#define MLT_LOG_INFO 32 -#define MLT_LOG_VERBOSE 40 - -/** - * stuff which is only useful for MLT developers - */ -#define MLT_LOG_DEBUG 48 - -/** - * Send the specified message to the log if the level is less than or equal to - * the current logging level. By default, all logging messages are sent to - * stderr. This behavior can be altered by setting a different mlt_vlog callback - * function. - * - * \param service An optional pointer to a \p mlt_service_s. - * \param level The importance level of the message, lower values signifying - * higher importance. - * \param fmt The format string (printf-compatible) that specifies how - * subsequent arguments are converted to output. - * \see mlt_vlog - */ -#ifdef __GNUC__ -void mlt_log( void *service, int level, const char *fmt, ... ) __attribute__ ((__format__ (__printf__, 3, 4))); -#else -void mlt_log( void *service, int level, const char *fmt, ... ); -#endif - -#define mlt_log_panic(service, format, args...) mlt_log((service), MLT_LOG_PANIC, (format), ## args) -#define mlt_log_fatal(service, format, args...) mlt_log((service), MLT_LOG_FATAL, (format), ## args) -#define mlt_log_error(service, format, args...) mlt_log((service), MLT_LOG_ERROR, (format), ## args) -#define mlt_log_warning(service, format, args...) mlt_log((service), MLT_LOG_WARNING, (format), ## args) -#define mlt_log_info(service, format, args...) mlt_log((service), MLT_LOG_INFO, (format), ## args) -#define mlt_log_verbose(service, format, args...) mlt_log((service), MLT_LOG_VERBOSE, (format), ## args) -#define mlt_log_debug(service, format, args...) mlt_log((service), MLT_LOG_DEBUG, (format), ## args) - -void mlt_vlog( void *service, int level, const char *fmt, va_list ); -int mlt_log_get_level( void ); -void mlt_log_set_level( int ); -void mlt_log_set_callback( void (*)( void*, int, const char*, va_list ) ); - -#endif /* MLT_LOG_H */ diff --git a/src/framework/mlt_multitrack.c b/src/framework/mlt_multitrack.c deleted file mode 100644 index a98d412..0000000 --- a/src/framework/mlt_multitrack.c +++ /dev/null @@ -1,514 +0,0 @@ -/** - * \file mlt_multitrack.c - * \brief multitrack service class - * \see mlt_multitrack_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_multitrack.h" -#include "mlt_playlist.h" -#include "mlt_frame.h" - -#include -#include - -/* Forward reference. */ - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ); - -/** Construct and initialize a new multitrack. - * - * Sets the resource property to "". - * - * \public \memberof mlt_multitrack_s - * \return a new multitrack - */ - -mlt_multitrack mlt_multitrack_init( ) -{ - // Allocate the multitrack object - mlt_multitrack this = calloc( sizeof( struct mlt_multitrack_s ), 1 ); - - if ( this != NULL ) - { - mlt_producer producer = &this->parent; - if ( mlt_producer_init( producer, this ) == 0 ) - { - mlt_properties properties = MLT_MULTITRACK_PROPERTIES( this ); - producer->get_frame = producer_get_frame; - mlt_properties_set_data( properties, "multitrack", this, 0, NULL, NULL ); - mlt_properties_set( properties, "log_id", "multitrack" ); - mlt_properties_set( properties, "resource", "" ); - mlt_properties_set_int( properties, "in", 0 ); - mlt_properties_set_int( properties, "out", -1 ); - mlt_properties_set_int( properties, "length", 0 ); - producer->close = ( mlt_destructor )mlt_multitrack_close; - } - else - { - free( this ); - this = NULL; - } - } - - return this; -} - -/** Get the producer associated to this multitrack. - * - * \public \memberof mlt_multitrack_s - * \param this a multitrack - * \return the producer object - * \see MLT_MULTITRACK_PRODUCER - */ - -mlt_producer mlt_multitrack_producer( mlt_multitrack this ) -{ - return this != NULL ? &this->parent : NULL; -} - -/** Get the service associated this multitrack. - * - * \public \memberof mlt_multitrack_s - * \param this a multitrack - * \return the service object - * \see MLT_MULTITRACK_SERVICE - */ - -mlt_service mlt_multitrack_service( mlt_multitrack this ) -{ - return MLT_MULTITRACK_SERVICE( this ); -} - -/** Get the properties associated this multitrack. - * - * \public \memberof mlt_multitrack_s - * \param this a multitrack - * \return the multitrack's property list - * \see MLT_MULTITRACK_PROPERTIES - */ - -mlt_properties mlt_multitrack_properties( mlt_multitrack this ) -{ - return MLT_MULTITRACK_PROPERTIES( this ); -} - -/** Initialize position related information. - * - * \public \memberof mlt_multitrack_s - * \param this a multitrack - */ - -void mlt_multitrack_refresh( mlt_multitrack this ) -{ - int i = 0; - - // Obtain the properties of this multitrack - mlt_properties properties = MLT_MULTITRACK_PROPERTIES( this ); - - // We need to ensure that the multitrack reports the longest track as its length - mlt_position length = 0; - - // Obtain stats on all connected services - for ( i = 0; i < this->count; i ++ ) - { - // Get the producer from this index - mlt_track track = this->list[ i ]; - mlt_producer producer = track->producer; - - // If it's allocated then, update our stats - if ( producer != NULL ) - { - // If we have more than 1 track, we must be in continue mode - if ( this->count > 1 ) - mlt_properties_set( MLT_PRODUCER_PROPERTIES( producer ), "eof", "continue" ); - - // Determine the longest length - //if ( !mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( producer ), "hide" ) ) - length = mlt_producer_get_playtime( producer ) > length ? mlt_producer_get_playtime( producer ) : length; - } - } - - // Update multitrack properties now - we'll not destroy the in point here - mlt_events_block( properties, properties ); - mlt_properties_set_position( properties, "length", length ); - mlt_events_unblock( properties, properties ); - mlt_properties_set_position( properties, "out", length - 1 ); -} - -/** Listener for producers on the playlist. - * - * \private \memberof mlt_multitrack_s - * \param producer a producer - * \param this a multitrack - */ - -static void mlt_multitrack_listener( mlt_producer producer, mlt_multitrack this ) -{ - mlt_multitrack_refresh( this ); -} - -/** Connect a producer to a given track. - * - * Note that any producer can be connected here, but see special case treatment - * of playlist in clip point determination below. - * - * \public \memberof mlt_multitrack_s - * \param this a multitrack - * \param producer the producer to connect to the multitrack producer - * \param track the 0-based index of the track on which to connect the multitrack - * \return true on error - */ - -int mlt_multitrack_connect( mlt_multitrack this, mlt_producer producer, int track ) -{ - // Connect to the producer to ourselves at the specified track - int result = mlt_service_connect_producer( MLT_MULTITRACK_SERVICE( this ), MLT_PRODUCER_SERVICE( producer ), track ); - - if ( result == 0 ) - { - // Resize the producer list if need be - if ( track >= this->size ) - { - int i; - this->list = realloc( this->list, ( track + 10 ) * sizeof( mlt_track ) ); - for ( i = this->size; i < track + 10; i ++ ) - this->list[ i ] = NULL; - this->size = track + 10; - } - - if ( this->list[ track ] != NULL ) - { - mlt_event_close( this->list[ track ]->event ); - mlt_producer_close( this->list[ track ]->producer ); - } - else - { - this->list[ track ] = malloc( sizeof( struct mlt_track_s ) ); - } - - // Assign the track in our list here - this->list[ track ]->producer = producer; - this->list[ track ]->event = mlt_events_listen( MLT_PRODUCER_PROPERTIES( producer ), this, - "producer-changed", ( mlt_listener )mlt_multitrack_listener ); - mlt_properties_inc_ref( MLT_PRODUCER_PROPERTIES( producer ) ); - mlt_event_inc_ref( this->list[ track ]->event ); - - // Increment the track count if need be - if ( track >= this->count ) - this->count = track + 1; - - // Refresh our stats - mlt_multitrack_refresh( this ); - } - - return result; -} - -/** Get the number of tracks. - * - * \public \memberof mlt_multitrack_s - * \param this a multitrack - * \return the number of tracks - */ - -int mlt_multitrack_count( mlt_multitrack this ) -{ - return this->count; -} - -/** Get an individual track as a producer. - * - * \public \memberof mlt_multitrack_s - * \param this a multitrack - * \param track the 0-based index of the producer to get - * \return the producer or NULL if not valid - */ - -mlt_producer mlt_multitrack_track( mlt_multitrack this, int track ) -{ - mlt_producer producer = NULL; - - if ( this->list != NULL && track < this->count ) - producer = this->list[ track ]->producer; - - return producer; -} - -/** Position comparison function for sorting. - * - * \private \memberof mlt_multitrack_s - * \param p1 a position - * \param p2 another position - * \return <0 if \p p1 is less than \p p2, 0 if equal, >0 if greater - */ - -static int position_compare( const void *p1, const void *p2 ) -{ - return *( const mlt_position * )p1 - *( const mlt_position * )p2; -} - -/** Add a position to a set. - * - * \private \memberof mlt_multitrack_s - * \param array an array of positions (the set) - * \param size the current number of positions in the array (not the capacity of the array) - * \param position the position to add - * \return the new size of the array - */ - -static int add_unique( mlt_position *array, int size, mlt_position position ) -{ - int i = 0; - for ( i = 0; i < size; i ++ ) - if ( array[ i ] == position ) - break; - if ( i == size ) - array[ size ++ ] = position; - return size; -} - -/** Determine the clip point. - * - *

- * Special case here: a 'producer' has no concept of multiple clips - only the
- * playlist and multitrack producers have clip functionality. Further to that a
- * multitrack determines clip information from any connected tracks that happen
- * to be playlists.
- *
- * Additionally, it must locate clips in the correct order, for example, consider
- * the following track arrangement:
- *
- * playlist1 |0.0     |b0.0      |0.1          |0.1         |0.2           |
- * playlist2 |b1.0  |1.0           |b1.1     |1.1             |
- *
- * Note - b clips represent blanks. They are also reported as clip positions.
- *
- * When extracting clip positions from these playlists, we should get a sequence of:
- *
- * 0.0, 1.0, b0.0, 0.1, b1.1, 1.1, 0.1, 0.2, [out of playlist2], [out of playlist1]
- * 
- * - * \public \memberof mlt_multitrack_s - * \param this a multitrack - * \param whence from where to extract - * \param index the 0-based index of which clip to extract - * \return the position of clip \p index relative to \p whence - */ - -mlt_position mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int index ) -{ - mlt_position position = 0; - int i = 0; - int j = 0; - mlt_position *map = malloc( 1000 * sizeof( mlt_position ) ); - int count = 0; - - for ( i = 0; i < this->count; i ++ ) - { - // Get the producer for this track - mlt_producer producer = this->list[ i ]->producer; - - // If it's assigned and not a hidden track - if ( producer != NULL ) - { - // Get the properties of this producer - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Determine if it's a playlist - mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); - - // Special case consideration of playlists - if ( playlist != NULL ) - { - for ( j = 0; j < mlt_playlist_count( playlist ); j ++ ) - count = add_unique( map, count, mlt_playlist_clip( playlist, mlt_whence_relative_start, j ) ); - count = add_unique( map, count, mlt_producer_get_out( producer ) + 1 ); - } - else - { - count = add_unique( map, count, 0 ); - count = add_unique( map, count, mlt_producer_get_out( producer ) + 1 ); - } - } - } - - // Now sort the map - qsort( map, count, sizeof( mlt_position ), position_compare ); - - // Now locate the requested index - switch( whence ) - { - case mlt_whence_relative_start: - if ( index < count ) - position = map[ index ]; - else - position = map[ count - 1 ]; - break; - - case mlt_whence_relative_current: - position = mlt_producer_position( MLT_MULTITRACK_PRODUCER( this ) ); - for ( i = 0; i < count - 2; i ++ ) - if ( position >= map[ i ] && position < map[ i + 1 ] ) - break; - index += i; - if ( index >= 0 && index < count ) - position = map[ index ]; - else if ( index < 0 ) - position = map[ 0 ]; - else - position = map[ count - 1 ]; - break; - - case mlt_whence_relative_end: - if ( index < count ) - position = map[ count - index - 1 ]; - else - position = map[ 0 ]; - break; - } - - // Free the map - free( map ); - - return position; -} - -/** Get frame method. - * - *
- * Special case here: The multitrack must be used in a conjunction with a downstream
- * tractor-type service, ie:
- *
- * Producer1 \
- * Producer2 - multitrack - { filters/transitions } - tractor - consumer
- * Producer3 /
- *
- * The get_frame of a tractor pulls frames from it's connected service on all tracks and
- * will terminate as soon as it receives a test card with a last_track property. The
- * important case here is that the mulitrack does not move to the next frame until all
- * tracks have been pulled.
- *
- * Reasoning: In order to seek on a network such as above, the multitrack needs to ensure
- * that all producers are positioned on the same frame. It uses the 'last track' logic
- * to determine when to move to the next frame.
- *
- * Flaw: if a transition is configured to read from a b-track which happens to trigger
- * the last frame logic (ie: it's configured incorrectly), then things are going to go
- * out of sync.
- *
- * See playlist logic too.
- * 
- * - * \private \memberof mlt_multitrack_s - * \param parent the producer interface to a mulitrack - * \param[out] frame a frame by reference - * \param index the 0-based track index - * \return true if there was an error - */ - -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ) -{ - // Get the mutiltrack object - mlt_multitrack this = parent->child; - - // Check if we have a track for this index - if ( index < this->count && this->list[ index ] != NULL ) - { - // Get the producer for this track - mlt_producer producer = this->list[ index ]->producer; - - // Get the track hide property - int hide = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( producer ) ), "hide" ); - - // Obtain the current position - mlt_position position = mlt_producer_frame( parent ); - - // Get the parent properties - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( parent ); - - // Get the speed - double speed = mlt_properties_get_double( producer_properties, "_speed" ); - - // Make sure we're at the same point - mlt_producer_seek( producer, position ); - - // Get the frame from the producer - mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), frame, 0 ); - - // Indicate speed of this producer - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - mlt_properties_set_double( properties, "_speed", speed ); - mlt_properties_set_position( properties, "_position", position ); - mlt_properties_set_int( properties, "hide", hide ); - } - else - { - // Generate a test frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( parent ) ); - - // Update position on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( parent ) ); - - // Move on to the next frame - if ( index >= this->count ) - { - // Let tractor know if we've reached the end - mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "last_track", 1 ); - - // Move to the next frame - mlt_producer_prepare_next( parent ); - } - } - - return 0; -} - -/** Close this instance and free its resources. - * - * \public \memberof mlt_multitrack_s - * \param this a multitrack - */ - -void mlt_multitrack_close( mlt_multitrack this ) -{ - if ( this != NULL && mlt_properties_dec_ref( MLT_MULTITRACK_PROPERTIES( this ) ) <= 0 ) - { - int i = 0; - for ( i = 0; i < this->count; i ++ ) - { - if ( this->list[ i ] != NULL ) - { - mlt_event_close( this->list[ i ]->event ); - mlt_producer_close( this->list[ i ]->producer ); - free( this->list[ i ] ); - } - } - - // Close the producer - this->parent.close = NULL; - mlt_producer_close( &this->parent ); - - // Free the list - free( this->list ); - - // Free the object - free( this ); - } -} diff --git a/src/framework/mlt_multitrack.h b/src/framework/mlt_multitrack.h deleted file mode 100644 index 427083c..0000000 --- a/src/framework/mlt_multitrack.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * \file mlt_multitrack.h - * \brief multitrack service class - * \see mlt_multitrack_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_MULITRACK_H_ -#define _MLT_MULITRACK_H_ - -#include "mlt_producer.h" - -/** \brief Track class used by mlt_multitrack_s - */ - -struct mlt_track_s -{ - mlt_producer producer; - mlt_event event; -}; - -typedef struct mlt_track_s *mlt_track; - -/** \brief Multitrack class - * - * A multitrack is a parallel container of producers that acts a single producer. - * - * \extends mlt_producer_s - * \properties \em log_id not currently used, but sets it to "mulitrack" - */ - -struct mlt_multitrack_s -{ - /** We're extending producer here */ - struct mlt_producer_s parent; - mlt_track *list; - int size; - int count; -}; - -#define MLT_MULTITRACK_PRODUCER( multitrack ) ( &( multitrack )->parent ) -#define MLT_MULTITRACK_SERVICE( multitrack ) MLT_PRODUCER_SERVICE( MLT_MULTITRACK_PRODUCER( multitrack ) ) -#define MLT_MULTITRACK_PROPERTIES( multitrack ) MLT_SERVICE_PROPERTIES( MLT_MULTITRACK_SERVICE( multitrack ) ) - -extern mlt_multitrack mlt_multitrack_init( ); -extern mlt_producer mlt_multitrack_producer( mlt_multitrack self ); -extern mlt_service mlt_multitrack_service( mlt_multitrack self ); -extern mlt_properties mlt_multitrack_properties( mlt_multitrack self ); -extern int mlt_multitrack_connect( mlt_multitrack self, mlt_producer producer, int track ); -extern mlt_position mlt_multitrack_clip( mlt_multitrack self, mlt_whence whence, int index ); -extern void mlt_multitrack_close( mlt_multitrack self ); -extern int mlt_multitrack_count( mlt_multitrack self ); -extern void mlt_multitrack_refresh( mlt_multitrack self ); -extern mlt_producer mlt_multitrack_track( mlt_multitrack self, int track ); - -#endif - diff --git a/src/framework/mlt_parser.c b/src/framework/mlt_parser.c deleted file mode 100644 index c5dd4ec..0000000 --- a/src/framework/mlt_parser.c +++ /dev/null @@ -1,245 +0,0 @@ -/** - * \file mlt_parser.c - * \brief service parsing functionality - * \see mlt_parser_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt.h" -#include - -static int on_invalid( mlt_parser this, mlt_service object ) -{ - return 0; -} - -static int on_unknown( mlt_parser this, mlt_service object ) -{ - return 0; -} - -static int on_start_producer( mlt_parser this, mlt_producer object ) -{ - return 0; -} - -static int on_end_producer( mlt_parser this, mlt_producer object ) -{ - return 0; -} - -static int on_start_playlist( mlt_parser this, mlt_playlist object ) -{ - return 0; -} - -static int on_end_playlist( mlt_parser this, mlt_playlist object ) -{ - return 0; -} - -static int on_start_tractor( mlt_parser this, mlt_tractor object ) -{ - return 0; -} - -static int on_end_tractor( mlt_parser this, mlt_tractor object ) -{ - return 0; -} - -static int on_start_multitrack( mlt_parser this, mlt_multitrack object ) -{ - return 0; -} - -static int on_end_multitrack( mlt_parser this, mlt_multitrack object ) -{ - return 0; -} - -static int on_start_track( mlt_parser this ) -{ - return 0; -} - -static int on_end_track( mlt_parser this ) -{ - return 0; -} - -static int on_start_filter( mlt_parser this, mlt_filter object ) -{ - return 0; -} - -static int on_end_filter( mlt_parser this, mlt_filter object ) -{ - return 0; -} - -static int on_start_transition( mlt_parser this, mlt_transition object ) -{ - return 0; -} - -static int on_end_transition( mlt_parser this, mlt_transition object ) -{ - return 0; -} - -mlt_parser mlt_parser_new( ) -{ - mlt_parser this = calloc( 1, sizeof( struct mlt_parser_s ) ); - if ( this != NULL && mlt_properties_init( &this->parent, this ) == 0 ) - { - this->on_invalid = on_invalid; - this->on_unknown = on_unknown; - this->on_start_producer = on_start_producer; - this->on_end_producer = on_end_producer; - this->on_start_playlist = on_start_playlist; - this->on_end_playlist = on_end_playlist; - this->on_start_tractor = on_start_tractor; - this->on_end_tractor = on_end_tractor; - this->on_start_multitrack = on_start_multitrack; - this->on_end_multitrack = on_end_multitrack; - this->on_start_track = on_start_track; - this->on_end_track = on_end_track; - this->on_start_filter = on_start_filter; - this->on_end_filter = on_end_filter; - this->on_start_transition = on_start_transition; - this->on_end_transition = on_end_transition; - } - return this; -} - -mlt_properties mlt_parser_properties( mlt_parser this ) -{ - return &this->parent; -} - -int mlt_parser_start( mlt_parser this, mlt_service object ) -{ - int error = 0; - mlt_service_type type = mlt_service_identify( object ); - switch( type ) - { - case invalid_type: - error = this->on_invalid( this, object ); - break; - case unknown_type: - error = this->on_unknown( this, object ); - break; - case producer_type: - if ( mlt_producer_is_cut( ( mlt_producer )object ) ) - error = mlt_parser_start( this, ( mlt_service )mlt_producer_cut_parent( ( mlt_producer )object ) ); - error = this->on_start_producer( this, ( mlt_producer )object ); - if ( error == 0 ) - { - int i = 0; - while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL ) - error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) ); - } - error = this->on_end_producer( this, ( mlt_producer )object ); - break; - case playlist_type: - error = this->on_start_playlist( this, ( mlt_playlist )object ); - if ( error == 0 ) - { - int i = 0; - while ( error == 0 && i < mlt_playlist_count( ( mlt_playlist )object ) ) - mlt_parser_start( this, ( mlt_service )mlt_playlist_get_clip( ( mlt_playlist )object, i ++ ) ); - i = 0; - while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL ) - error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) ); - } - error = this->on_end_playlist( this, ( mlt_playlist )object ); - break; - case tractor_type: - error = this->on_start_tractor( this, ( mlt_tractor )object ); - if ( error == 0 ) - { - int i = 0; - mlt_service next = mlt_service_producer( object ); - mlt_parser_start( this, ( mlt_service )mlt_tractor_multitrack( ( mlt_tractor )object ) ); - while ( next != ( mlt_service )mlt_tractor_multitrack( ( mlt_tractor )object ) ) - { - mlt_parser_start( this, next ); - next = mlt_service_producer( next ); - } - while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL ) - error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) ); - } - error = this->on_end_tractor( this, ( mlt_tractor )object ); - break; - case multitrack_type: - error = this->on_start_multitrack( this, ( mlt_multitrack )object ); - if ( error == 0 ) - { - int i = 0; - while ( i < mlt_multitrack_count( ( mlt_multitrack )object ) ) - { - this->on_start_track( this ); - mlt_parser_start( this, ( mlt_service )mlt_multitrack_track( ( mlt_multitrack )object , i ++ ) ); - this->on_end_track( this ); - } - i = 0; - while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL ) - error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) ); - } - error = this->on_end_multitrack( this, ( mlt_multitrack )object ); - break; - case filter_type: - error = this->on_start_filter( this, ( mlt_filter )object ); - if ( error == 0 ) - { - int i = 0; - while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL ) - error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) ); - } - error = this->on_end_filter( this, ( mlt_filter )object ); - break; - case transition_type: - error = this->on_start_transition( this, ( mlt_transition )object ); - if ( error == 0 ) - { - int i = 0; - while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL ) - error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) ); - } - error = this->on_end_transition( this, ( mlt_transition )object ); - break; - case field_type: - break; - case consumer_type: - break; - } - return error; -} - -void mlt_parser_close( mlt_parser this ) -{ - if ( this != NULL ) - { - mlt_properties_close( &this->parent ); - free( this ); - } -} - - diff --git a/src/framework/mlt_parser.h b/src/framework/mlt_parser.h deleted file mode 100644 index e82149c..0000000 --- a/src/framework/mlt_parser.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * \file mlt_parser.h - * \brief service parsing functionality - * \see mlt_parser_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_PARSER_H_ -#define _MLT_PARSER_H_ - -#include "mlt_types.h" - -/** \brief Parser class - * - * \extends mlt_properties_s - */ - -struct mlt_parser_s -{ - struct mlt_properties_s parent; - int ( *on_invalid )( mlt_parser self, mlt_service object ); - int ( *on_unknown )( mlt_parser self, mlt_service object ); - int ( *on_start_producer )( mlt_parser self, mlt_producer object ); - int ( *on_end_producer )( mlt_parser self, mlt_producer object ); - int ( *on_start_playlist )( mlt_parser self, mlt_playlist object ); - int ( *on_end_playlist )( mlt_parser self, mlt_playlist object ); - int ( *on_start_tractor )( mlt_parser self, mlt_tractor object ); - int ( *on_end_tractor )( mlt_parser self, mlt_tractor object ); - int ( *on_start_multitrack )( mlt_parser self, mlt_multitrack object ); - int ( *on_end_multitrack )( mlt_parser self, mlt_multitrack object ); - int ( *on_start_track )( mlt_parser self ); - int ( *on_end_track )( mlt_parser self ); - int ( *on_start_filter )( mlt_parser self, mlt_filter object ); - int ( *on_end_filter )( mlt_parser self, mlt_filter object ); - int ( *on_start_transition )( mlt_parser self, mlt_transition object ); - int ( *on_end_transition )( mlt_parser self, mlt_transition object ); -}; - -extern mlt_parser mlt_parser_new( ); -extern mlt_properties mlt_parser_properties( mlt_parser self ); -extern int mlt_parser_start( mlt_parser self, mlt_service object ); -extern void mlt_parser_close( mlt_parser self ); - -#endif diff --git a/src/framework/mlt_playlist.c b/src/framework/mlt_playlist.c deleted file mode 100644 index 91f9fa8..0000000 --- a/src/framework/mlt_playlist.c +++ /dev/null @@ -1,1839 +0,0 @@ -/** - * \file mlt_playlist.c - * \brief playlist service class - * \see mlt_playlist_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_playlist.h" -#include "mlt_tractor.h" -#include "mlt_multitrack.h" -#include "mlt_field.h" -#include "mlt_frame.h" -#include "mlt_transition.h" - -#include -#include -#include - -/** \brief Virtual playlist entry used by mlt_playlist_s -*/ - -struct playlist_entry_s -{ - mlt_producer producer; - mlt_position frame_in; - mlt_position frame_out; - mlt_position frame_count; - int repeat; - mlt_position producer_length; - mlt_event event; - int preservation_hack; -}; - -/* Forward declarations -*/ - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ); -static int mlt_playlist_unmix( mlt_playlist this, int clip ); -static int mlt_playlist_resize_mix( mlt_playlist this, int clip, int in, int out ); - -/** Construct a playlist. - * - * Sets the resource property to "". - * Set the mlt_type to property to "mlt_producer". - * \public \memberof mlt_playlist_s - * \return a new playlist - */ - -mlt_playlist mlt_playlist_init( ) -{ - mlt_playlist this = calloc( sizeof( struct mlt_playlist_s ), 1 ); - if ( this != NULL ) - { - mlt_producer producer = &this->parent; - - // Construct the producer - mlt_producer_init( producer, this ); - - // Override the producer get_frame - producer->get_frame = producer_get_frame; - - // Define the destructor - producer->close = ( mlt_destructor )mlt_playlist_close; - producer->close_object = this; - - // Initialise blank - mlt_producer_init( &this->blank, NULL ); - mlt_properties_set( MLT_PRODUCER_PROPERTIES( &this->blank ), "mlt_service", "blank" ); - mlt_properties_set( MLT_PRODUCER_PROPERTIES( &this->blank ), "resource", "blank" ); - - // Indicate that this producer is a playlist - mlt_properties_set_data( MLT_PLAYLIST_PROPERTIES( this ), "playlist", this, 0, NULL, NULL ); - - // Specify the eof condition - mlt_properties_set( MLT_PLAYLIST_PROPERTIES( this ), "eof", "pause" ); - mlt_properties_set( MLT_PLAYLIST_PROPERTIES( this ), "resource", "" ); - mlt_properties_set( MLT_PLAYLIST_PROPERTIES( this ), "mlt_type", "mlt_producer" ); - mlt_properties_set_position( MLT_PLAYLIST_PROPERTIES( this ), "in", 0 ); - mlt_properties_set_position( MLT_PLAYLIST_PROPERTIES( this ), "out", -1 ); - mlt_properties_set_position( MLT_PLAYLIST_PROPERTIES( this ), "length", 0 ); - - this->size = 10; - this->list = malloc( this->size * sizeof( playlist_entry * ) ); - } - - return this; -} - -/** Get the producer associated to this playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \return the producer interface - * \see MLT_PLAYLIST_PRODUCER - */ - -mlt_producer mlt_playlist_producer( mlt_playlist this ) -{ - return this != NULL ? &this->parent : NULL; -} - -/** Get the service associated to this playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \return the service interface - * \see MLT_PLAYLIST_SERVICE - */ - -mlt_service mlt_playlist_service( mlt_playlist this ) -{ - return MLT_PRODUCER_SERVICE( &this->parent ); -} - -/** Get the properties associated to this playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \return the playlist's properties list - * \see MLT_PLAYLIST_PROPERTIES - */ - -mlt_properties mlt_playlist_properties( mlt_playlist this ) -{ - return MLT_PRODUCER_PROPERTIES( &this->parent ); -} - -/** Refresh the playlist after a clip has been changed. - * - * \private \memberof mlt_playlist_s - * \param this a playlist - * \return false - */ - -static int mlt_playlist_virtual_refresh( mlt_playlist this ) -{ - // Obtain the properties - mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); - int i = 0; - mlt_position frame_count = 0; - - for ( i = 0; i < this->count; i ++ ) - { - // Get the producer - mlt_producer producer = this->list[ i ]->producer; - if ( producer ) - { - int current_length = mlt_producer_get_out( producer ) - mlt_producer_get_in( producer ) + 1; - - // Check if the length of the producer has changed - if ( this->list[ i ]->frame_in != mlt_producer_get_in( producer ) || - this->list[ i ]->frame_out != mlt_producer_get_out( producer ) ) - { - // This clip should be removed... - if ( current_length < 1 ) - { - this->list[ i ]->frame_in = 0; - this->list[ i ]->frame_out = -1; - this->list[ i ]->frame_count = 0; - } - else - { - this->list[ i ]->frame_in = mlt_producer_get_in( producer ); - this->list[ i ]->frame_out = mlt_producer_get_out( producer ); - this->list[ i ]->frame_count = current_length; - } - - // Update the producer_length - this->list[ i ]->producer_length = current_length; - } - } - - // Calculate the frame_count - this->list[ i ]->frame_count = ( this->list[ i ]->frame_out - this->list[ i ]->frame_in + 1 ) * this->list[ i ]->repeat; - - // Update the frame_count for this clip - frame_count += this->list[ i ]->frame_count; - } - - // Refresh all properties - mlt_events_block( properties, properties ); - mlt_properties_set_position( properties, "length", frame_count ); - mlt_events_unblock( properties, properties ); - mlt_properties_set_position( properties, "out", frame_count - 1 ); - - return 0; -} - -/** Listener for producers on the playlist. - * - * Refreshes the playlist whenever an entry receives producer-changed. - * \private \memberof mlt_playlist_s - * \param producer a producer - * \param this a playlist - */ - -static void mlt_playlist_listener( mlt_producer producer, mlt_playlist this ) -{ - mlt_playlist_virtual_refresh( this ); -} - -/** Append to the virtual playlist. - * - * \private \memberof mlt_playlist_s - * \param this a playlist - * \param source a producer - * \param in the producer's starting time - * \param out the producer's ending time - * \return true if there was an error - */ - -static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer source, mlt_position in, mlt_position out ) -{ - mlt_producer producer = NULL; - mlt_properties properties = NULL; - mlt_properties parent = NULL; - - // If we have a cut, then use the in/out points from the cut - if ( mlt_producer_is_blank( source ) ) - { - // Make sure the blank is long enough to accomodate the length specified - if ( out - in + 1 > mlt_producer_get_length( &this->blank ) ) - { - mlt_properties blank_props = MLT_PRODUCER_PROPERTIES( &this->blank ); - mlt_events_block( blank_props, blank_props ); - mlt_producer_set_in_and_out( &this->blank, in, out ); - mlt_events_unblock( blank_props, blank_props ); - } - - // Now make sure the cut comes from this this->blank - if ( source == NULL ) - { - producer = mlt_producer_cut( &this->blank, in, out ); - } - else if ( !mlt_producer_is_cut( source ) || mlt_producer_cut_parent( source ) != &this->blank ) - { - producer = mlt_producer_cut( &this->blank, in, out ); - } - else - { - producer = source; - mlt_properties_inc_ref( MLT_PRODUCER_PROPERTIES( producer ) ); - } - - properties = MLT_PRODUCER_PROPERTIES( producer ); - } - else if ( mlt_producer_is_cut( source ) ) - { - producer = source; - if ( in == -1 ) - in = mlt_producer_get_in( producer ); - if ( out == -1 || out > mlt_producer_get_out( producer ) ) - out = mlt_producer_get_out( producer ); - properties = MLT_PRODUCER_PROPERTIES( producer ); - mlt_properties_inc_ref( properties ); - } - else - { - producer = mlt_producer_cut( source, in, out ); - if ( in == -1 || in < mlt_producer_get_in( producer ) ) - in = mlt_producer_get_in( producer ); - if ( out == -1 || out > mlt_producer_get_out( producer ) ) - out = mlt_producer_get_out( producer ); - properties = MLT_PRODUCER_PROPERTIES( producer ); - } - - // Fetch the cuts parent properties - parent = MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( producer ) ); - - // Remove fezzik normalisers for fx cuts - if ( mlt_properties_get_int( parent, "meta.fx_cut" ) ) - { - mlt_service service = MLT_PRODUCER_SERVICE( mlt_producer_cut_parent( producer ) ); - mlt_filter filter = mlt_service_filter( service, 0 ); - while ( filter != NULL && mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "_fezzik" ) ) - { - mlt_service_detach( service, filter ); - filter = mlt_service_filter( service, 0 ); - } - mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( producer ), "meta.fx_cut", 1 ); - } - - // Check that we have room - if ( this->count >= this->size ) - { - int i; - this->list = realloc( this->list, ( this->size + 10 ) * sizeof( playlist_entry * ) ); - for ( i = this->size; i < this->size + 10; i ++ ) this->list[ i ] = NULL; - this->size += 10; - } - - // Create the entry - this->list[ this->count ] = calloc( sizeof( playlist_entry ), 1 ); - if ( this->list[ this->count ] != NULL ) - { - this->list[ this->count ]->producer = producer; - this->list[ this->count ]->frame_in = in; - this->list[ this->count ]->frame_out = out; - this->list[ this->count ]->frame_count = out - in + 1; - this->list[ this->count ]->repeat = 1; - this->list[ this->count ]->producer_length = mlt_producer_get_out( producer ) - mlt_producer_get_in( producer ) + 1; - this->list[ this->count ]->event = mlt_events_listen( parent, this, "producer-changed", ( mlt_listener )mlt_playlist_listener ); - mlt_event_inc_ref( this->list[ this->count ]->event ); - mlt_properties_set( properties, "eof", "pause" ); - mlt_producer_set_speed( producer, 0 ); - this->count ++; - } - - return mlt_playlist_virtual_refresh( this ); -} - -/** Locate a producer by index. - * - * \private \memberof mlt_playlist_s - * \param this a playlist - * \param[in, out] position the time at which to locate the producer, returns the time relative to the producer's starting point - * \param[out] clip the index of the playlist entry - * \param[out] total the duration of the playlist up to and including this producer - * \return a producer or NULL if not found - */ - -static mlt_producer mlt_playlist_locate( mlt_playlist this, mlt_position *position, int *clip, int *total ) -{ - // Default producer to NULL - mlt_producer producer = NULL; - - // Loop for each producer until found - for ( *clip = 0; *clip < this->count; *clip += 1 ) - { - // Increment the total - *total += this->list[ *clip ]->frame_count; - - // Check if the position indicates that we have found the clip - // Note that 0 length clips get skipped automatically - if ( *position < this->list[ *clip ]->frame_count ) - { - // Found it, now break - producer = this->list[ *clip ]->producer; - break; - } - else - { - // Decrement position by length of this entry - *position -= this->list[ *clip ]->frame_count; - } - } - - return producer; -} - -/** Seek in the virtual playlist. - * - * This gets the producer at the current position and seeks on the producer - * while doing repeat and end-of-file handling. This is also responsible for - * closing producers previous to the preceding playlist if the autoclose - * property is set. - * \private \memberof mlt_playlist_s - * \param this a playlist - * \param[out] progressive true if the producer should be displayed progressively - * \return the service interface of the producer at the play head - * \see producer_get_frame - */ - -static mlt_service mlt_playlist_virtual_seek( mlt_playlist this, int *progressive ) -{ - // Map playlist position to real producer in virtual playlist - mlt_position position = mlt_producer_frame( &this->parent ); - - // Keep the original position since we change it while iterating through the list - mlt_position original = position; - - // Clip index and total - int i = 0; - int total = 0; - - // Locate the producer for the position - mlt_producer producer = mlt_playlist_locate( this, &position, &i, &total ); - - // Get the properties - mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); - - // Automatically close previous producers if requested - if ( i > 1 // keep immediate previous in case app wants to get info about what just finished - && position < 2 // tolerate off-by-one error on going to next clip - && mlt_properties_get_int( properties, "autoclose" ) ) - { - int j; - // They might have jumped ahead! - for ( j = 0; j < i - 1; j++ ) - { - mlt_service_lock( MLT_PRODUCER_SERVICE( this->list[ j ]->producer ) ); - mlt_producer p = this->list[ j ]->producer; - if ( p ) - { - this->list[ j ]->producer = NULL; - mlt_service_unlock( MLT_PRODUCER_SERVICE( p ) ); - mlt_producer_close( p ); - } - // If p is null, the lock will not have been "taken" - } - } - - // Get the eof handling - char *eof = mlt_properties_get( properties, "eof" ); - - // Seek in real producer to relative position - if ( producer != NULL ) - { - int count = this->list[ i ]->frame_count / this->list[ i ]->repeat; - *progressive = count == 1; - mlt_producer_seek( producer, (int)position % count ); - } - else if ( !strcmp( eof, "pause" ) && total > 0 ) - { - playlist_entry *entry = this->list[ this->count - 1 ]; - int count = entry->frame_count / entry->repeat; - mlt_producer this_producer = MLT_PLAYLIST_PRODUCER( this ); - mlt_producer_seek( this_producer, original - 1 ); - producer = entry->producer; - mlt_producer_seek( producer, (int)entry->frame_out % count ); - mlt_producer_set_speed( this_producer, 0 ); - mlt_producer_set_speed( producer, 0 ); - *progressive = count == 1; - } - else if ( !strcmp( eof, "loop" ) && total > 0 ) - { - playlist_entry *entry = this->list[ 0 ]; - mlt_producer this_producer = MLT_PLAYLIST_PRODUCER( this ); - mlt_producer_seek( this_producer, 0 ); - producer = entry->producer; - mlt_producer_seek( producer, 0 ); - } - else - { - producer = &this->blank; - } - - return MLT_PRODUCER_SERVICE( producer ); -} - -/** Invoked when a producer indicates that it has prematurely reached its end. - * - * \private \memberof mlt_playlist_s - * \param this a playlist - * \return a producer - * \see producer_get_frame - */ - -static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this ) -{ - // Default producer to blank - mlt_producer producer = &this->blank; - - // Map playlist position to real producer in virtual playlist - mlt_position position = mlt_producer_frame( &this->parent ); - - // Loop through the virtual playlist - int i = 0; - - for ( i = 0; i < this->count; i ++ ) - { - if ( position < this->list[ i ]->frame_count ) - { - // Found it, now break - producer = this->list[ i ]->producer; - break; - } - else - { - // Decrement position by length of this entry - position -= this->list[ i ]->frame_count; - } - } - - // Seek in real producer to relative position - if ( i < this->count && this->list[ i ]->frame_out != position ) - { - // Update the frame_count for the changed clip (hmmm) - this->list[ i ]->frame_out = position; - this->list[ i ]->frame_count = this->list[ i ]->frame_out - this->list[ i ]->frame_in + 1; - - // Refresh the playlist - mlt_playlist_virtual_refresh( this ); - } - - return producer; -} - -/** Obtain the current clips index. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \return the index of the playlist entry at the current position - */ - -int mlt_playlist_current_clip( mlt_playlist this ) -{ - // Map playlist position to real producer in virtual playlist - mlt_position position = mlt_producer_frame( &this->parent ); - - // Loop through the virtual playlist - int i = 0; - - for ( i = 0; i < this->count; i ++ ) - { - if ( position < this->list[ i ]->frame_count ) - { - // Found it, now break - break; - } - else - { - // Decrement position by length of this entry - position -= this->list[ i ]->frame_count; - } - } - - return i; -} - -/** Obtain the current clips producer. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \return the producer at the current position - */ - -mlt_producer mlt_playlist_current( mlt_playlist this ) -{ - int i = mlt_playlist_current_clip( this ); - if ( i < this->count ) - return this->list[ i ]->producer; - else - return &this->blank; -} - -/** Get the position which corresponds to the start of the next clip. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param whence the location from which to make the index relative: - * start of playlist, end of playlist, or current position - * \param index the playlist entry index relative to whence - * \return the time at which the referenced clip starts - */ - -mlt_position mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index ) -{ - mlt_position position = 0; - int absolute_clip = index; - int i = 0; - - // Determine the absolute clip - switch ( whence ) - { - case mlt_whence_relative_start: - absolute_clip = index; - break; - - case mlt_whence_relative_current: - absolute_clip = mlt_playlist_current_clip( this ) + index; - break; - - case mlt_whence_relative_end: - absolute_clip = this->count - index; - break; - } - - // Check that we're in a valid range - if ( absolute_clip < 0 ) - absolute_clip = 0; - else if ( absolute_clip > this->count ) - absolute_clip = this->count; - - // Now determine the position - for ( i = 0; i < absolute_clip; i ++ ) - position += this->list[ i ]->frame_count; - - return position; -} - -/** Get all the info about the clip specified. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param info a clip info struct - * \param index a playlist entry index - * \return true if there was an error - */ - -int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index ) -{ - int error = index < 0 || index >= this->count || this->list[ index ]->producer == NULL; - memset( info, 0, sizeof( mlt_playlist_clip_info ) ); - if ( !error ) - { - mlt_producer producer = mlt_producer_cut_parent( this->list[ index ]->producer ); - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - info->clip = index; - info->producer = producer; - info->cut = this->list[ index ]->producer; - info->start = mlt_playlist_clip( this, mlt_whence_relative_start, index ); - info->resource = mlt_properties_get( properties, "resource" ); - info->frame_in = this->list[ index ]->frame_in; - info->frame_out = this->list[ index ]->frame_out; - info->frame_count = this->list[ index ]->frame_count; - info->repeat = this->list[ index ]->repeat; - info->length = mlt_producer_get_length( producer ); - info->fps = mlt_producer_get_fps( producer ); - } - - return error; -} - -/** Get number of clips in the playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \return the number of playlist entries - */ - -int mlt_playlist_count( mlt_playlist this ) -{ - return this->count; -} - -/** Clear the playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \return true if there was an error - */ - -int mlt_playlist_clear( mlt_playlist this ) -{ - int i; - for ( i = 0; i < this->count; i ++ ) - { - mlt_event_close( this->list[ i ]->event ); - mlt_producer_close( this->list[ i ]->producer ); - } - this->count = 0; - return mlt_playlist_virtual_refresh( this ); -} - -/** Append a producer to the playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param producer the producer to append - * \return true if there was an error - */ - -int mlt_playlist_append( mlt_playlist this, mlt_producer producer ) -{ - // Append to virtual list - return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) - 1 ); -} - -/** Append a producer to the playlist with in/out points. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param producer the producer to append - * \param in the starting point on the producer - * \param out the ending point on the producer - * \return true if there was an error - */ - -int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, mlt_position in, mlt_position out ) -{ - // Append to virtual list - if ( in != -1 && out != -1 ) - return mlt_playlist_virtual_append( this, producer, in, out ); - else - return mlt_playlist_append( this, producer ); -} - -/** Append a blank to the playlist of a given length. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param length the ending time of the blank entry, not its duration - * \return true if there was an error - */ - -int mlt_playlist_blank( mlt_playlist this, mlt_position length ) -{ - // Append to the virtual list - if (length >= 0) - return mlt_playlist_virtual_append( this, &this->blank, 0, length ); - else - return 1; -} - -/** Insert a producer into the playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param producer the producer to insert - * \param where the producer's playlist entry index - * \param in the starting point on the producer - * \param out the ending point on the producer - * \return true if there was an error - */ - -int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_position in, mlt_position out ) -{ - // Append to end - mlt_events_block( MLT_PLAYLIST_PROPERTIES( this ), this ); - mlt_playlist_append_io( this, producer, in, out ); - - // Move to the position specified - mlt_playlist_move( this, this->count - 1, where ); - mlt_events_unblock( MLT_PLAYLIST_PROPERTIES( this ), this ); - - return mlt_playlist_virtual_refresh( this ); -} - -/** Remove an entry in the playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param where the playlist entry index - * \return true if there was an error - */ - -int mlt_playlist_remove( mlt_playlist this, int where ) -{ - int error = where < 0 || where >= this->count; - if ( error == 0 && mlt_playlist_unmix( this, where ) != 0 ) - { - // We need to know the current clip and the position within the playlist - int current = mlt_playlist_current_clip( this ); - mlt_position position = mlt_producer_position( MLT_PLAYLIST_PRODUCER( this ) ); - - // We need all the details about the clip we're removing - mlt_playlist_clip_info where_info; - playlist_entry *entry = this->list[ where ]; - mlt_properties properties = MLT_PRODUCER_PROPERTIES( entry->producer ); - - // Loop variable - int i = 0; - - // Get the clip info - mlt_playlist_get_clip_info( this, &where_info, where ); - - // Make sure the clip to be removed is valid and correct if necessary - if ( where < 0 ) - where = 0; - if ( where >= this->count ) - where = this->count - 1; - - // Reorganise the list - for ( i = where + 1; i < this->count; i ++ ) - this->list[ i - 1 ] = this->list[ i ]; - this->count --; - - if ( entry->preservation_hack == 0 ) - { - // Decouple from mix_in/out if necessary - if ( mlt_properties_get_data( properties, "mix_in", NULL ) != NULL ) - { - mlt_properties mix = mlt_properties_get_data( properties, "mix_in", NULL ); - mlt_properties_set_data( mix, "mix_out", NULL, 0, NULL, NULL ); - } - if ( mlt_properties_get_data( properties, "mix_out", NULL ) != NULL ) - { - mlt_properties mix = mlt_properties_get_data( properties, "mix_out", NULL ); - mlt_properties_set_data( mix, "mix_in", NULL, 0, NULL, NULL ); - } - - if ( mlt_properties_ref_count( MLT_PRODUCER_PROPERTIES( entry->producer ) ) == 1 ) - mlt_producer_clear( entry->producer ); - } - - // Close the producer associated to the clip info - mlt_event_close( entry->event ); - mlt_producer_close( entry->producer ); - - // Correct position - if ( where == current ) - mlt_producer_seek( MLT_PLAYLIST_PRODUCER( this ), where_info.start ); - else if ( where < current && this->count > 0 ) - mlt_producer_seek( MLT_PLAYLIST_PRODUCER( this ), position - where_info.frame_count ); - else if ( this->count == 0 ) - mlt_producer_seek( MLT_PLAYLIST_PRODUCER( this ), 0 ); - - // Free the entry - free( entry ); - - // Refresh the playlist - mlt_playlist_virtual_refresh( this ); - } - - return error; -} - -/** Move an entry in the playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param src an entry index - * \param dest an entry index - * \return false - */ - -int mlt_playlist_move( mlt_playlist this, int src, int dest ) -{ - int i; - - /* We need to ensure that the requested indexes are valid and correct it as necessary */ - if ( src < 0 ) - src = 0; - if ( src >= this->count ) - src = this->count - 1; - - if ( dest < 0 ) - dest = 0; - if ( dest >= this->count ) - dest = this->count - 1; - - if ( src != dest && this->count > 1 ) - { - int current = mlt_playlist_current_clip( this ); - mlt_position position = mlt_producer_position( MLT_PLAYLIST_PRODUCER( this ) ); - playlist_entry *src_entry = NULL; - - // We need all the details about the current clip - mlt_playlist_clip_info current_info; - - mlt_playlist_get_clip_info( this, ¤t_info, current ); - position -= current_info.start; - - if ( current == src ) - current = dest; - else if ( current > src && current < dest ) - current ++; - else if ( current == dest ) - current = src; - - src_entry = this->list[ src ]; - if ( src > dest ) - { - for ( i = src; i > dest; i -- ) - this->list[ i ] = this->list[ i - 1 ]; - } - else - { - for ( i = src; i < dest; i ++ ) - this->list[ i ] = this->list[ i + 1 ]; - } - this->list[ dest ] = src_entry; - - mlt_playlist_get_clip_info( this, ¤t_info, current ); - mlt_producer_seek( MLT_PLAYLIST_PRODUCER( this ), current_info.start + position ); - mlt_playlist_virtual_refresh( this ); - } - - return 0; -} - -/** Repeat the specified clip n times. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip a playlist entry index - * \param repeat the number of times to repeat the clip - * \return true if there was an error - */ - -int mlt_playlist_repeat_clip( mlt_playlist this, int clip, int repeat ) -{ - int error = repeat < 1 || clip < 0 || clip >= this->count; - if ( error == 0 ) - { - playlist_entry *entry = this->list[ clip ]; - entry->repeat = repeat; - mlt_playlist_virtual_refresh( this ); - } - return error; -} - -/** Resize the specified clip. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \param in the new starting time on the clip's producer - * \param out the new ending time on the clip's producer - * \return true if there was an error - */ - -int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_position in, mlt_position out ) -{ - int error = clip < 0 || clip >= this->count; - if ( error == 0 && mlt_playlist_resize_mix( this, clip, in, out ) != 0 ) - { - playlist_entry *entry = this->list[ clip ]; - mlt_producer producer = entry->producer; - mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); - - mlt_events_block( properties, properties ); - - if ( mlt_producer_is_blank( producer ) ) - { - // Make sure the blank is long enough to accomodate the length specified - if ( out - in + 1 > mlt_producer_get_length( &this->blank ) ) - { - mlt_properties blank_props = MLT_PRODUCER_PROPERTIES( &this->blank ); - mlt_properties_set_int( blank_props, "length", out - in + 1 ); - mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( producer ), "length", out - in + 1 ); - mlt_producer_set_in_and_out( &this->blank, 0, out - in ); - } - } - - if ( in <= -1 ) - in = 0; - if ( out <= -1 || out >= mlt_producer_get_length( producer ) ) - out = mlt_producer_get_length( producer ) - 1; - - if ( out < in ) - { - mlt_position t = in; - in = out; - out = t; - } - - mlt_producer_set_in_and_out( producer, in, out ); - mlt_events_unblock( properties, properties ); - mlt_playlist_virtual_refresh( this ); - } - return error; -} - -/** Split a clip on the playlist at the given position. - * - * This splits after the specified frame. - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \param position the time at which to split relative to the beginning of the clip or its end if negative - * \return true if there was an error - */ - -int mlt_playlist_split( mlt_playlist this, int clip, mlt_position position ) -{ - int error = clip < 0 || clip >= this->count; - if ( error == 0 ) - { - playlist_entry *entry = this->list[ clip ]; - position = position < 0 ? entry->frame_count + position - 1 : position; - if ( position >= 0 && position < entry->frame_count - 1 ) - { - int in = entry->frame_in; - int out = entry->frame_out; - mlt_events_block( MLT_PLAYLIST_PROPERTIES( this ), this ); - mlt_playlist_resize_clip( this, clip, in, in + position ); - if ( !mlt_producer_is_blank( entry->producer ) ) - { - int i = 0; - mlt_properties entry_properties = MLT_PRODUCER_PROPERTIES( entry->producer ); - mlt_producer split = mlt_producer_cut( entry->producer, in + position + 1, out ); - mlt_properties split_properties = MLT_PRODUCER_PROPERTIES( split ); - mlt_playlist_insert( this, split, clip + 1, 0, -1 ); - for ( i = 0; i < mlt_properties_count( entry_properties ); i ++ ) - { - char *name = mlt_properties_get_name( entry_properties, i ); - if ( name != NULL && !strncmp( name, "meta.", 5 ) ) - mlt_properties_set( split_properties, name, mlt_properties_get_value( entry_properties, i ) ); - } - mlt_producer_close( split ); - } - else - { - mlt_playlist_insert( this, &this->blank, clip + 1, 0, out - position - 1 ); - } - mlt_events_unblock( MLT_PLAYLIST_PROPERTIES( this ), this ); - mlt_playlist_virtual_refresh( this ); - } - else - { - error = 1; - } - } - return error; -} - -/** Split the playlist at the absolute position. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param position the time at which to split relative to the beginning of the clip - * \param left true to split before the frame starting at position - * \return true if there was an error - */ - -int mlt_playlist_split_at( mlt_playlist this, mlt_position position, int left ) -{ - int result = this == NULL ? -1 : 0; - if ( !result ) - { - if ( position >= 0 && position < mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( this ) ) ) - { - int clip = mlt_playlist_get_clip_index_at( this, position ); - mlt_playlist_clip_info info; - mlt_playlist_get_clip_info( this, &info, clip ); - if ( left && position != info.start ) - mlt_playlist_split( this, clip, position - info.start - 1 ); - else if ( !left ) - mlt_playlist_split( this, clip, position - info.start ); - result = position; - } - else if ( position <= 0 ) - { - result = 0; - } - else - { - result = mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( this ) ); - } - } - return result; -} - -/** Join 1 or more consecutive clips. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the starting playlist entry index - * \param count the number of entries to merge - * \param merge ignored - * \return true if there was an error - */ - -int mlt_playlist_join( mlt_playlist this, int clip, int count, int merge ) -{ - int error = clip < 0 || clip >= this->count; - if ( error == 0 ) - { - int i = clip; - mlt_playlist new_clip = mlt_playlist_init( ); - mlt_events_block( MLT_PLAYLIST_PROPERTIES( this ), this ); - if ( clip + count >= this->count ) - count = this->count - clip - 1; - for ( i = 0; i <= count; i ++ ) - { - playlist_entry *entry = this->list[ clip ]; - mlt_playlist_append( new_clip, entry->producer ); - mlt_playlist_repeat_clip( new_clip, i, entry->repeat ); - entry->preservation_hack = 1; - mlt_playlist_remove( this, clip ); - } - mlt_events_unblock( MLT_PLAYLIST_PROPERTIES( this ), this ); - mlt_playlist_insert( this, MLT_PLAYLIST_PRODUCER( new_clip ), clip, 0, -1 ); - mlt_playlist_close( new_clip ); - } - return error; -} - -/** Mix consecutive clips for a specified length and apply transition if specified. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \param length the number of frames over which to create the mix - * \param transition the transition to use for the mix - * \return true if there was an error - */ - -int mlt_playlist_mix( mlt_playlist this, int clip, int length, mlt_transition transition ) -{ - int error = ( clip < 0 || clip + 1 >= this->count ); - if ( error == 0 ) - { - playlist_entry *clip_a = this->list[ clip ]; - playlist_entry *clip_b = this->list[ clip + 1 ]; - mlt_producer track_a = NULL; - mlt_producer track_b = NULL; - mlt_tractor tractor = mlt_tractor_new( ); - mlt_events_block( MLT_PLAYLIST_PROPERTIES( this ), this ); - - // Check length is valid for both clips and resize if necessary. - int max_size = clip_a->frame_count > clip_b->frame_count ? clip_a->frame_count : clip_b->frame_count; - length = length > max_size ? max_size : length; - - // Create the a and b tracks/cuts if necessary - note that no cuts are required if the length matches - if ( length != clip_a->frame_count ) - track_a = mlt_producer_cut( clip_a->producer, clip_a->frame_out - length + 1, clip_a->frame_out ); - else - track_a = clip_a->producer; - - if ( length != clip_b->frame_count ) - track_b = mlt_producer_cut( clip_b->producer, clip_b->frame_in, clip_b->frame_in + length - 1 ); - else - track_b = clip_b->producer; - - // Set the tracks on the tractor - mlt_tractor_set_track( tractor, track_a, 0 ); - mlt_tractor_set_track( tractor, track_b, 1 ); - - // Insert the mix object into the playlist - mlt_playlist_insert( this, MLT_TRACTOR_PRODUCER( tractor ), clip + 1, -1, -1 ); - mlt_properties_set_data( MLT_TRACTOR_PROPERTIES( tractor ), "mlt_mix", tractor, 0, NULL, NULL ); - - // Attach the transition - if ( transition != NULL ) - { - mlt_field field = mlt_tractor_field( tractor ); - mlt_field_plant_transition( field, transition, 0, 1 ); - mlt_transition_set_in_and_out( transition, 0, length - 1 ); - } - - // Close our references to the tracks if we created new cuts above (the tracks can still be used here) - if ( track_a != clip_a->producer ) - mlt_producer_close( track_a ); - if ( track_b != clip_b->producer ) - mlt_producer_close( track_b ); - - // Check if we have anything left on the right hand clip - if ( track_b == clip_b->producer ) - { - clip_b->preservation_hack = 1; - mlt_playlist_remove( this, clip + 2 ); - } - else if ( clip_b->frame_out - clip_b->frame_in > length ) - { - mlt_playlist_resize_clip( this, clip + 2, clip_b->frame_in + length, clip_b->frame_out ); - mlt_properties_set_data( MLT_PRODUCER_PROPERTIES( clip_b->producer ), "mix_in", tractor, 0, NULL, NULL ); - mlt_properties_set_data( MLT_TRACTOR_PROPERTIES( tractor ), "mix_out", clip_b->producer, 0, NULL, NULL ); - } - else - { - mlt_producer_clear( clip_b->producer ); - mlt_playlist_remove( this, clip + 2 ); - } - - // Check if we have anything left on the left hand clip - if ( track_a == clip_a->producer ) - { - clip_a->preservation_hack = 1; - mlt_playlist_remove( this, clip ); - } - else if ( clip_a->frame_out - clip_a->frame_in > length ) - { - mlt_playlist_resize_clip( this, clip, clip_a->frame_in, clip_a->frame_out - length ); - mlt_properties_set_data( MLT_PRODUCER_PROPERTIES( clip_a->producer ), "mix_out", tractor, 0, NULL, NULL ); - mlt_properties_set_data( MLT_TRACTOR_PROPERTIES( tractor ), "mix_in", clip_a->producer, 0, NULL, NULL ); - } - else - { - mlt_producer_clear( clip_a->producer ); - mlt_playlist_remove( this, clip ); - } - - // Unblock and force a fire off of change events to listeners - mlt_events_unblock( MLT_PLAYLIST_PROPERTIES( this ), this ); - mlt_playlist_virtual_refresh( this ); - mlt_tractor_close( tractor ); - } - return error; -} - -/** Add a transition to an existing mix. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \param transition a transition - * \return true if there was an error - */ - -int mlt_playlist_mix_add( mlt_playlist this, int clip, mlt_transition transition ) -{ - mlt_producer producer = mlt_producer_cut_parent( mlt_playlist_get_clip( this, clip ) ); - mlt_properties properties = producer != NULL ? MLT_PRODUCER_PROPERTIES( producer ) : NULL; - mlt_tractor tractor = properties != NULL ? mlt_properties_get_data( properties, "mlt_mix", NULL ) : NULL; - int error = transition == NULL || tractor == NULL; - if ( error == 0 ) - { - mlt_field field = mlt_tractor_field( tractor ); - mlt_field_plant_transition( field, transition, 0, 1 ); - mlt_transition_set_in_and_out( transition, 0, this->list[ clip ]->frame_count - 1 ); - } - return error; -} - -/** Return the clip at the clip index. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of a playlist entry - * \return a producer or NULL if there was an error - */ - -mlt_producer mlt_playlist_get_clip( mlt_playlist this, int clip ) -{ - if ( clip >= 0 && clip < this->count ) - return this->list[ clip ]->producer; - return NULL; -} - -/** Return the clip at the specified position. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param position a time relative to the beginning of the playlist - * \return a producer or NULL if not found - */ - -mlt_producer mlt_playlist_get_clip_at( mlt_playlist this, mlt_position position ) -{ - int index = 0, total = 0; - return mlt_playlist_locate( this, &position, &index, &total ); -} - -/** Return the clip index of the specified position. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param position a time relative to the beginning of the playlist - * \return the index of the playlist entry - */ - -int mlt_playlist_get_clip_index_at( mlt_playlist this, mlt_position position ) -{ - int index = 0, total = 0; - mlt_playlist_locate( this, &position, &index, &total ); - return index; -} - -/** Determine if the clip is a mix. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \return true if the producer is a mix - */ - -int mlt_playlist_clip_is_mix( mlt_playlist this, int clip ) -{ - mlt_producer producer = mlt_producer_cut_parent( mlt_playlist_get_clip( this, clip ) ); - mlt_properties properties = producer != NULL ? MLT_PRODUCER_PROPERTIES( producer ) : NULL; - mlt_tractor tractor = properties != NULL ? mlt_properties_get_data( properties, "mlt_mix", NULL ) : NULL; - return tractor != NULL; -} - -/** Remove a mixed clip - ensure that the cuts included in the mix find their way - * back correctly on to the playlist. - * - * \private \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \return true if there was an error - */ - -static int mlt_playlist_unmix( mlt_playlist this, int clip ) -{ - int error = ( clip < 0 || clip >= this->count ); - - // Ensure that the clip request is actually a mix - if ( error == 0 ) - { - mlt_producer producer = mlt_producer_cut_parent( this->list[ clip ]->producer ); - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - error = mlt_properties_get_data( properties, "mlt_mix", NULL ) == NULL || - this->list[ clip ]->preservation_hack; - } - - if ( error == 0 ) - { - playlist_entry *mix = this->list[ clip ]; - mlt_tractor tractor = ( mlt_tractor )mlt_producer_cut_parent( mix->producer ); - mlt_properties properties = MLT_TRACTOR_PROPERTIES( tractor ); - mlt_producer clip_a = mlt_properties_get_data( properties, "mix_in", NULL ); - mlt_producer clip_b = mlt_properties_get_data( properties, "mix_out", NULL ); - int length = mlt_producer_get_playtime( MLT_TRACTOR_PRODUCER( tractor ) ); - mlt_events_block( MLT_PLAYLIST_PROPERTIES( this ), this ); - - if ( clip_a != NULL ) - { - mlt_producer_set_in_and_out( clip_a, mlt_producer_get_in( clip_a ), mlt_producer_get_out( clip_a ) + length ); - } - else - { - mlt_producer cut = mlt_tractor_get_track( tractor, 0 ); - mlt_playlist_insert( this, cut, clip, -1, -1 ); - clip ++; - } - - if ( clip_b != NULL ) - { - mlt_producer_set_in_and_out( clip_b, mlt_producer_get_in( clip_b ) - length, mlt_producer_get_out( clip_b ) ); - } - else - { - mlt_producer cut = mlt_tractor_get_track( tractor, 1 ); - mlt_playlist_insert( this, cut, clip + 1, -1, -1 ); - } - - mlt_properties_set_data( properties, "mlt_mix", NULL, 0, NULL, NULL ); - mlt_playlist_remove( this, clip ); - mlt_events_unblock( MLT_PLAYLIST_PROPERTIES( this ), this ); - mlt_playlist_virtual_refresh( this ); - } - return error; -} - -/** Resize a mix clip. - * - * \private \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \param in the new starting point - * \param out the new ending point - * \return true if there was an error - */ - -static int mlt_playlist_resize_mix( mlt_playlist this, int clip, int in, int out ) -{ - int error = ( clip < 0 || clip >= this->count ); - - // Ensure that the clip request is actually a mix - if ( error == 0 ) - { - mlt_producer producer = mlt_producer_cut_parent( this->list[ clip ]->producer ); - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - error = mlt_properties_get_data( properties, "mlt_mix", NULL ) == NULL; - } - - if ( error == 0 ) - { - playlist_entry *mix = this->list[ clip ]; - mlt_tractor tractor = ( mlt_tractor )mlt_producer_cut_parent( mix->producer ); - mlt_properties properties = MLT_TRACTOR_PROPERTIES( tractor ); - mlt_producer clip_a = mlt_properties_get_data( properties, "mix_in", NULL ); - mlt_producer clip_b = mlt_properties_get_data( properties, "mix_out", NULL ); - mlt_producer track_a = mlt_tractor_get_track( tractor, 0 ); - mlt_producer track_b = mlt_tractor_get_track( tractor, 1 ); - int length = out - in + 1; - int length_diff = length - mlt_producer_get_playtime( MLT_TRACTOR_PRODUCER( tractor ) ); - mlt_events_block( MLT_PLAYLIST_PROPERTIES( this ), this ); - - if ( clip_a != NULL ) - mlt_producer_set_in_and_out( clip_a, mlt_producer_get_in( clip_a ), mlt_producer_get_out( clip_a ) - length_diff ); - - if ( clip_b != NULL ) - mlt_producer_set_in_and_out( clip_b, mlt_producer_get_in( clip_b ) + length_diff, mlt_producer_get_out( clip_b ) ); - - mlt_producer_set_in_and_out( track_a, mlt_producer_get_in( track_a ) - length_diff, mlt_producer_get_out( track_a ) ); - mlt_producer_set_in_and_out( track_b, mlt_producer_get_in( track_b ), mlt_producer_get_out( track_b ) + length_diff ); - mlt_producer_set_in_and_out( MLT_MULTITRACK_PRODUCER( mlt_tractor_multitrack( tractor ) ), in, out ); - mlt_producer_set_in_and_out( MLT_TRACTOR_PRODUCER( tractor ), in, out ); - mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( mix->producer ), "length", out - in + 1 ); - mlt_producer_set_in_and_out( mix->producer, in, out ); - - mlt_events_unblock( MLT_PLAYLIST_PROPERTIES( this ), this ); - mlt_playlist_virtual_refresh( this ); - } - return error; -} - -/** Consolidate adjacent blank producers. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param keep_length set false to remove the last entry if it is blank - */ - -void mlt_playlist_consolidate_blanks( mlt_playlist this, int keep_length ) -{ - if ( this != NULL ) - { - int i = 0; - mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); - - mlt_events_block( properties, properties ); - for ( i = 1; i < this->count; i ++ ) - { - playlist_entry *left = this->list[ i - 1 ]; - playlist_entry *right = this->list[ i ]; - - if ( mlt_producer_is_blank( left->producer ) && mlt_producer_is_blank( right->producer ) ) - { - mlt_playlist_resize_clip( this, i - 1, 0, left->frame_count + right->frame_count - 1 ); - mlt_playlist_remove( this, i -- ); - } - } - - if ( !keep_length && this->count > 0 ) - { - playlist_entry *last = this->list[ this->count - 1 ]; - if ( mlt_producer_is_blank( last->producer ) ) - mlt_playlist_remove( this, this->count - 1 ); - } - - mlt_events_unblock( properties, properties ); - mlt_playlist_virtual_refresh( this ); - } -} - -/** Determine if the specified clip index is a blank. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \return true if there was an error - */ - -int mlt_playlist_is_blank( mlt_playlist this, int clip ) -{ - return this == NULL || mlt_producer_is_blank( mlt_playlist_get_clip( this, clip ) ); -} - -/** Determine if the specified position is a blank. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param position a time relative to the start or end (negative) of the playlist - * \return true if there was an error - */ - -int mlt_playlist_is_blank_at( mlt_playlist this, mlt_position position ) -{ - return this == NULL || mlt_producer_is_blank( mlt_playlist_get_clip_at( this, position ) ); -} - -/** Replace the specified clip with a blank and return the clip. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \return a producer or NULL if there was an error - */ - -mlt_producer mlt_playlist_replace_with_blank( mlt_playlist this, int clip ) -{ - mlt_producer producer = NULL; - if ( !mlt_playlist_is_blank( this, clip ) ) - { - playlist_entry *entry = this->list[ clip ]; - int in = entry->frame_in; - int out = entry->frame_out; - mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); - producer = entry->producer; - mlt_properties_inc_ref( MLT_PRODUCER_PROPERTIES( producer ) ); - mlt_events_block( properties, properties ); - mlt_playlist_remove( this, clip ); - mlt_playlist_blank( this, out - in ); - mlt_playlist_move( this, this->count - 1, clip ); - mlt_events_unblock( properties, properties ); - mlt_playlist_virtual_refresh( this ); - mlt_producer_set_in_and_out( producer, in, out ); - } - return producer; -} - -/** Insert blank space. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the new blank section - * \param length the ending time of the new blank section (duration - 1) - */ - -void mlt_playlist_insert_blank( mlt_playlist this, int clip, int length ) -{ - if ( this != NULL && length >= 0 ) - { - mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); - mlt_events_block( properties, properties ); - mlt_playlist_blank( this, length ); - mlt_playlist_move( this, this->count - 1, clip ); - mlt_events_unblock( properties, properties ); - mlt_playlist_virtual_refresh( this ); - } -} - -/** Resize a blank entry. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param position the time at which the blank entry exists relative to the start or end (negative) of the playlist. - * \param length the additional amount of blank frames to add - * \param find true to fist locate the blank after the clip at position - */ -void mlt_playlist_pad_blanks( mlt_playlist this, mlt_position position, int length, int find ) -{ - if ( this != NULL && length != 0 ) - { - int clip = mlt_playlist_get_clip_index_at( this, position ); - mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); - mlt_events_block( properties, properties ); - if ( find && clip < this->count && !mlt_playlist_is_blank( this, clip ) ) - clip ++; - if ( clip < this->count && mlt_playlist_is_blank( this, clip ) ) - { - mlt_playlist_clip_info info; - mlt_playlist_get_clip_info( this, &info, clip ); - if ( info.frame_out + length > info.frame_in ) - mlt_playlist_resize_clip( this, clip, info.frame_in, info.frame_out + length ); - else - mlt_playlist_remove( this, clip ); - } - else if ( find && clip < this->count && length > 0 ) - { - mlt_playlist_insert_blank( this, clip, length ); - } - mlt_events_unblock( properties, properties ); - mlt_playlist_virtual_refresh( this ); - } -} - -/** Insert a clip at a specific time. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param position the time at which to insert - * \param producer the producer to insert - * \param mode true if you want to overwrite any blank section - * \return true if there was an error - */ - -int mlt_playlist_insert_at( mlt_playlist this, mlt_position position, mlt_producer producer, int mode ) -{ - int ret = this == NULL || position < 0 || producer == NULL; - if ( ret == 0 ) - { - mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); - int length = mlt_producer_get_playtime( producer ); - int clip = mlt_playlist_get_clip_index_at( this, position ); - mlt_playlist_clip_info info; - mlt_playlist_get_clip_info( this, &info, clip ); - mlt_events_block( properties, this ); - if ( clip < this->count && mlt_playlist_is_blank( this, clip ) ) - { - // Split and move to new clip if need be - if ( position != info.start && mlt_playlist_split( this, clip, position - info.start - 1 ) == 0 ) - mlt_playlist_get_clip_info( this, &info, ++ clip ); - - // Split again if need be - if ( length < info.frame_count ) - mlt_playlist_split( this, clip, length - 1 ); - - // Remove - mlt_playlist_remove( this, clip ); - - // Insert - mlt_playlist_insert( this, producer, clip, -1, -1 ); - ret = clip; - } - else if ( clip < this->count ) - { - if ( position > info.start + info.frame_count / 2 ) - clip ++; - if ( mode == 1 && clip < this->count && mlt_playlist_is_blank( this, clip ) ) - { - mlt_playlist_get_clip_info( this, &info, clip ); - if ( length < info.frame_count ) - mlt_playlist_split( this, clip, length ); - mlt_playlist_remove( this, clip ); - } - mlt_playlist_insert( this, producer, clip, -1, -1 ); - ret = clip; - } - else - { - if ( mode == 1 ) { - if ( position == info.start ) - mlt_playlist_remove( this, clip ); - else - mlt_playlist_blank( this, position - mlt_properties_get_int( properties, "length" ) - 1 ); - } - mlt_playlist_append( this, producer ); - ret = this->count - 1; - } - mlt_events_unblock( properties, this ); - mlt_playlist_virtual_refresh( this ); - } - else - { - ret = -1; - } - return ret; -} - -/** Get the time at which the clip starts relative to the playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \return the starting time - */ - -int mlt_playlist_clip_start( mlt_playlist this, int clip ) -{ - mlt_playlist_clip_info info; - if ( mlt_playlist_get_clip_info( this, &info, clip ) == 0 ) - return info.start; - return clip < 0 ? 0 : mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( this ) ); -} - -/** Get the playable duration of the clip. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \return the duration of the playlist entry - */ - -int mlt_playlist_clip_length( mlt_playlist this, int clip ) -{ - mlt_playlist_clip_info info; - if ( mlt_playlist_get_clip_info( this, &info, clip ) == 0 ) - return info.frame_count; - return 0; -} - -/** Get the duration of a blank space. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param clip the index of the playlist entry - * \param bounded the maximum number of blank entries or 0 for all - * \return the duration of a blank section - */ - -int mlt_playlist_blanks_from( mlt_playlist this, int clip, int bounded ) -{ - int count = 0; - mlt_playlist_clip_info info; - if ( this != NULL && clip < this->count ) - { - mlt_playlist_get_clip_info( this, &info, clip ); - if ( mlt_playlist_is_blank( this, clip ) ) - count += info.frame_count; - if ( bounded == 0 ) - bounded = this->count; - for ( clip ++; clip < this->count && bounded >= 0; clip ++ ) - { - mlt_playlist_get_clip_info( this, &info, clip ); - if ( mlt_playlist_is_blank( this, clip ) ) - count += info.frame_count; - else - bounded --; - } - } - return count; -} - -/** Remove a portion of the playlist by time. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - * \param position the starting time - * \param length the duration of time to remove - * \return the new entry index at the position - */ - -int mlt_playlist_remove_region( mlt_playlist this, mlt_position position, int length ) -{ - int index = mlt_playlist_get_clip_index_at( this, position ); - if ( index >= 0 && index < this->count ) - { - mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); - int clip_start = mlt_playlist_clip_start( this, index ); - int clip_length = mlt_playlist_clip_length( this, index ); - int list_length = mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( this ) ); - mlt_events_block( properties, this ); - - if ( position + length > list_length ) - length -= ( position + length - list_length ); - - if ( clip_start < position ) - { - mlt_playlist_split( this, index ++, position - clip_start ); - clip_length -= position - clip_start; - } - - while( length > 0 ) - { - if ( mlt_playlist_clip_length( this, index ) > length ) - mlt_playlist_split( this, index, length ); - length -= mlt_playlist_clip_length( this, index ); - mlt_playlist_remove( this, index ); - } - - mlt_playlist_consolidate_blanks( this, 0 ); - mlt_events_unblock( properties, this ); - mlt_playlist_virtual_refresh( this ); - - // Just to be sure, we'll get the clip index again... - index = mlt_playlist_get_clip_index_at( this, position ); - } - return index; -} - -/** Not implemented - * - * \deprecated not implemented - * \public \memberof mlt_playlist_s - * \param this - * \param position - * \param length - * \param new_position - * \return - */ - -int mlt_playlist_move_region( mlt_playlist this, mlt_position position, int length, int new_position ) -{ - if ( this != NULL ) - { - } - return 0; -} - -/** Get the current frame. - * - * The implementation of the get_frame virtual function. - * \private \memberof mlt_playlist_s - * \param producer a producer - * \param frame a frame by reference - * \param index the time at which to get the frame - * \return false - */ - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Check that we have a producer - if ( producer == NULL ) - { - *frame = NULL; - return -1; - } - - // Get this mlt_playlist - mlt_playlist this = producer->child; - - // Need to ensure the frame is deinterlaced when repeating 1 frame - int progressive = 0; - - // Get the real producer - mlt_service real = mlt_playlist_virtual_seek( this, &progressive ); - - // Check that we have a producer - if ( real == NULL ) - { - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - return 0; - } - - // Get the frame - if ( !mlt_properties_get_int( MLT_SERVICE_PROPERTIES( real ), "meta.fx_cut" ) ) - { - mlt_service_get_frame( real, frame, index ); - } - else - { - mlt_producer parent = mlt_producer_cut_parent( ( mlt_producer )real ); - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( parent ) ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "fx_cut", 1 ); - mlt_frame_push_service( *frame, NULL ); - mlt_frame_push_audio( *frame, NULL ); - mlt_service_apply_filters( MLT_PRODUCER_SERVICE( parent ), *frame, 0 ); - mlt_service_apply_filters( real, *frame, 0 ); - mlt_deque_pop_front( MLT_FRAME_IMAGE_STACK( *frame ) ); - mlt_deque_pop_front( MLT_FRAME_AUDIO_STACK( *frame ) ); - } - - // Check if we're at the end of the clip - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - if ( mlt_properties_get_int( properties, "end_of_clip" ) ) - mlt_playlist_virtual_set_out( this ); - - // Set the consumer progressive property - if ( progressive ) - { - mlt_properties_set_int( properties, "consumer_deinterlace", progressive ); - mlt_properties_set_int( properties, "test_audio", 1 ); - } - - // Check for notifier and call with appropriate argument - mlt_properties playlist_properties = MLT_PRODUCER_PROPERTIES( producer ); - void ( *notifier )( void * ) = mlt_properties_get_data( playlist_properties, "notifier", NULL ); - if ( notifier != NULL ) - { - void *argument = mlt_properties_get_data( playlist_properties, "notifier_arg", NULL ); - notifier( argument ); - } - - // Update position on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_frame( producer ) ); - - // Position ourselves on the next frame - mlt_producer_prepare_next( producer ); - - return 0; -} - -/** Close the playlist. - * - * \public \memberof mlt_playlist_s - * \param this a playlist - */ - -void mlt_playlist_close( mlt_playlist this ) -{ - if ( this != NULL && mlt_properties_dec_ref( MLT_PLAYLIST_PROPERTIES( this ) ) <= 0 ) - { - int i = 0; - this->parent.close = NULL; - for ( i = 0; i < this->count; i ++ ) - { - mlt_event_close( this->list[ i ]->event ); - mlt_producer_close( this->list[ i ]->producer ); - free( this->list[ i ] ); - } - mlt_producer_close( &this->blank ); - mlt_producer_close( &this->parent ); - free( this->list ); - free( this ); - } -} diff --git a/src/framework/mlt_playlist.h b/src/framework/mlt_playlist.h deleted file mode 100644 index a636431..0000000 --- a/src/framework/mlt_playlist.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * \file mlt_playlist.h - * \brief playlist service class - * \see mlt_playlist_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_PLAYLIST_H_ -#define _MLT_PLAYLIST_H_ - -#include "mlt_producer.h" - -/** \brief structure for returning clip information from a playlist entry - */ - -typedef struct -{ - int clip; /**< the index of the clip within the playlist */ - mlt_producer producer; /**< the clip's producer (or parent producer of a cut) */ - mlt_producer cut; /**< the clips' cut producer */ - mlt_position start; /**< the time this begins relative to the beginning of the playlist */ - char *resource; /**< the file name or address of the clip */ - mlt_position frame_in; /**< the clip's in point */ - mlt_position frame_out; /**< the clip's out point */ - mlt_position frame_count; /**< the duration of the clip */ - mlt_position length; /**< the unedited duration of the clip */ - float fps; /**< the frame rate of the clip */ - int repeat; /**< the number of times the clip is repeated */ -} -mlt_playlist_clip_info; - -/** Playlist Entry -*/ - -typedef struct playlist_entry_s playlist_entry; - -/** \brief Playlist class - * - * A playlist is a sequential container of producers and blank spaces. The class provides all - * sorts of playlist assembly and manipulation routines. A playlist is also a producer within - * the framework. - * - * \extends mlt_producer_s - * \properties \em autoclose Set this true if you are doing sequential processing and want to - * automatically close producers as they are finished being used to free resources. - * \properties \em meta.fx_cut Set true on a producer to indicate that it is a "fx_cut," - * which is a way to add filters as a playlist entry - useful only in a multitrack. See FxCut on the wiki. - * \properties \em mix_in - * \properties \em mix_out - */ - -struct mlt_playlist_s -{ - struct mlt_producer_s parent; - struct mlt_producer_s blank; - - int size; - int count; - playlist_entry **list; -}; - -#define MLT_PLAYLIST_PRODUCER( playlist ) ( &( playlist )->parent ) -#define MLT_PLAYLIST_SERVICE( playlist ) MLT_PRODUCER_SERVICE( MLT_PLAYLIST_PRODUCER( playlist ) ) -#define MLT_PLAYLIST_PROPERTIES( playlist ) MLT_SERVICE_PROPERTIES( MLT_PLAYLIST_SERVICE( playlist ) ) - -extern mlt_playlist mlt_playlist_init( ); -extern mlt_producer mlt_playlist_producer( mlt_playlist self ); -extern mlt_service mlt_playlist_service( mlt_playlist self ); -extern mlt_properties mlt_playlist_properties( mlt_playlist self ); -extern int mlt_playlist_count( mlt_playlist self ); -extern int mlt_playlist_clear( mlt_playlist self ); -extern int mlt_playlist_append( mlt_playlist self, mlt_producer producer ); -extern int mlt_playlist_append_io( mlt_playlist self, mlt_producer producer, mlt_position in, mlt_position out ); -extern int mlt_playlist_blank( mlt_playlist self, mlt_position length ); -extern mlt_position mlt_playlist_clip( mlt_playlist self, mlt_whence whence, int index ); -extern int mlt_playlist_current_clip( mlt_playlist self ); -extern mlt_producer mlt_playlist_current( mlt_playlist self ); -extern int mlt_playlist_get_clip_info( mlt_playlist self, mlt_playlist_clip_info *info, int index ); -extern int mlt_playlist_insert( mlt_playlist self, mlt_producer producer, int where, mlt_position in, mlt_position out ); -extern int mlt_playlist_remove( mlt_playlist self, int where ); -extern int mlt_playlist_move( mlt_playlist self, int from, int to ); -extern int mlt_playlist_resize_clip( mlt_playlist self, int clip, mlt_position in, mlt_position out ); -extern int mlt_playlist_repeat_clip( mlt_playlist self, int clip, int repeat ); -extern int mlt_playlist_split( mlt_playlist self, int clip, mlt_position position ); -extern int mlt_playlist_split_at( mlt_playlist self, mlt_position position, int left ); -extern int mlt_playlist_join( mlt_playlist self, int clip, int count, int merge ); -extern int mlt_playlist_mix( mlt_playlist self, int clip, int length, mlt_transition transition ); -extern int mlt_playlist_mix_add( mlt_playlist self, int clip, mlt_transition transition ); -extern mlt_producer mlt_playlist_get_clip( mlt_playlist self, int clip ); -extern mlt_producer mlt_playlist_get_clip_at( mlt_playlist self, mlt_position position ); -extern int mlt_playlist_get_clip_index_at( mlt_playlist self, mlt_position position ); -extern int mlt_playlist_clip_is_mix( mlt_playlist self, int clip ); -extern void mlt_playlist_consolidate_blanks( mlt_playlist self, int keep_length ); -extern int mlt_playlist_is_blank( mlt_playlist self, int clip ); -extern int mlt_playlist_is_blank_at( mlt_playlist self, mlt_position position ); -extern void mlt_playlist_insert_blank( mlt_playlist self, int clip, int length ); -extern void mlt_playlist_pad_blanks( mlt_playlist self, mlt_position position, int length, int find ); -extern mlt_producer mlt_playlist_replace_with_blank( mlt_playlist self, int clip ); -extern int mlt_playlist_insert_at( mlt_playlist self, mlt_position position, mlt_producer producer, int mode ); -extern int mlt_playlist_clip_start( mlt_playlist self, int clip ); -extern int mlt_playlist_clip_length( mlt_playlist self, int clip ); -extern int mlt_playlist_blanks_from( mlt_playlist self, int clip, int bounded ); -extern int mlt_playlist_remove_region( mlt_playlist self, mlt_position position, int length ); -extern int mlt_playlist_move_region( mlt_playlist self, mlt_position position, int length, int new_position ); -extern void mlt_playlist_close( mlt_playlist self ); - -#endif - diff --git a/src/framework/mlt_pool.c b/src/framework/mlt_pool.c deleted file mode 100644 index ebf0081..0000000 --- a/src/framework/mlt_pool.c +++ /dev/null @@ -1,391 +0,0 @@ -/** - * \file mlt_pool.c - * \brief memory pooling functionality - * \see mlt_pool_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_properties.h" -#include "mlt_deque.h" - -#include -#include -#include - -// Not nice - memalign is defined here apparently? -#ifdef linux -#include -#endif - -/** global singleton for tracking pools */ - -static mlt_properties pools = NULL; - -/** \brief Pool (memory) class - */ - -typedef struct mlt_pool_s -{ - pthread_mutex_t lock; ///< lock to prevent race conditions - mlt_deque stack; ///< a stack of addresses to memory blocks - int size; ///< the size of the memory block as a power of 2 - int count; ///< the number of blocks in the pool -} -*mlt_pool; - -/** \brief private to mlt_pool_s, for tracking items to release - */ - -typedef struct mlt_release_s -{ - mlt_pool pool; - int references; -} -*mlt_release; - -/** Create a pool. - * - * \private \memberof mlt_pool_s - * \param size the size of the memory blocks to hold as some power of two - * \return a new pool object - */ - -static mlt_pool pool_init( int size ) -{ - // Create the pool - mlt_pool this = calloc( 1, sizeof( struct mlt_pool_s ) ); - - // Initialise it - if ( this != NULL ) - { - // Initialise the mutex - pthread_mutex_init( &this->lock, NULL ); - - // Create the stack - this->stack = mlt_deque_init( ); - - // Assign the size - this->size = size; - } - - // Return it - return this; -} - -/** Get an item from the pool. - * - * \private \memberof mlt_pool_s - * \param this a pool - * \return an opaque pointer - */ - -static void *pool_fetch( mlt_pool this ) -{ - // We will generate a release object - void *ptr = NULL; - - // Sanity check - if ( this != NULL ) - { - // Lock the pool - pthread_mutex_lock( &this->lock ); - - // Check if the stack is empty - if ( mlt_deque_count( this->stack ) != 0 ) - { - // Pop the top of the stack - ptr = mlt_deque_pop_back( this->stack ); - - // Assign the reference - ( ( mlt_release )ptr )->references = 1; - } - else - { - // We need to generate a release item -#ifdef linux - mlt_release release = memalign( 16, this->size ); -#else - mlt_release release = malloc( this->size ); -#endif - - // Initialise it - if ( release != NULL ) - { - // Increment the number of items allocated to this pool - this->count ++; - - // Assign the pool - release->pool = this; - - // Assign the reference - release->references = 1; - - // Determine the ptr - ptr = ( char * )release + sizeof( struct mlt_release_s ); - } - } - - // Unlock the pool - pthread_mutex_unlock( &this->lock ); - } - - // Return the generated release object - return ptr; -} - -/** Return an item to the pool. - * - * \private \memberof mlt_pool_s - * \param ptr an opaque pointer - */ - -static void pool_return( void *ptr ) -{ - // Sanity checks - if ( ptr != NULL ) - { - // Get the release pointer - mlt_release that = ( void * )(( char * )ptr - sizeof( struct mlt_release_s )); - - // Get the pool - mlt_pool this = that->pool; - - if ( this != NULL ) - { - // Lock the pool - pthread_mutex_lock( &this->lock ); - - // Push the that back back on to the stack - mlt_deque_push_back( this->stack, ptr ); - - // Unlock the pool - pthread_mutex_unlock( &this->lock ); - - // Ensure that we don't clean up - ptr = NULL; - } - } - - // Tidy up - this will only occur if the returned item is incorrect - if ( ptr != NULL ) - { - // Free the release itself - free( ( char * )ptr - sizeof( struct mlt_release_s ) ); - } -} - -/** Destroy a pool. - * - * \private \memberof mlt_pool_s - * \param this a pool - */ - -static void pool_close( mlt_pool this ) -{ - if ( this != NULL ) - { - // We need to free up all items in the pool - void *release = NULL; - - // Iterate through the stack until depleted - while ( ( release = mlt_deque_pop_back( this->stack ) ) != NULL ) - { - // We'll free this item now - free( ( char * )release - sizeof( struct mlt_release_s ) ); - } - - // We can now close the stack - mlt_deque_close( this->stack ); - - // Destroy the mutex - pthread_mutex_destroy( &this->lock ); - - // Close the pool - free( this ); - } -} - -/** Initialise the global pool. - * - * \public \memberof mlt_pool_s - */ - -void mlt_pool_init( ) -{ - // Loop variable used to create the pools - int i = 0; - - // Create the pools - pools = mlt_properties_new( ); - - // Create the pools - for ( i = 8; i < 31; i ++ ) - { - // Each properties item needs a name - char name[ 32 ]; - - // Construct a pool - mlt_pool pool = pool_init( 1 << i ); - - // Generate a name - sprintf( name, "%d", i ); - - // Register with properties - mlt_properties_set_data( pools, name, pool, 0, ( mlt_destructor )pool_close, NULL ); - } -} - -/** Allocate size bytes from the pool. - * - * \public \memberof mlt_pool_s - * \param size the number of bytes - */ - -void *mlt_pool_alloc( int size ) -{ - // This will be used to obtain the pool to use - mlt_pool pool = NULL; - - // Determines the index of the pool to use - int index = 8; - - // Minimum size pooled is 256 bytes - size = size + sizeof( mlt_release ); - while ( ( 1 << index ) < size ) - index ++; - - // Now get the pool at the index - pool = mlt_properties_get_data_at( pools, index - 8, NULL ); - - // Now get the real item - return pool_fetch( pool ); -} - -/** Allocate size bytes from the pool. - * - * \public \memberof mlt_pool_s - * \param ptr an opaque pointer - can be in the pool or a new block to allocate - * \param size the number of bytes - */ - -void *mlt_pool_realloc( void *ptr, int size ) -{ - // Result to return - void *result = NULL; - - // Check if we actually have an address - if ( ptr != NULL ) - { - // Get the release pointer - mlt_release that = ( void * )(( char * )ptr - sizeof( struct mlt_release_s )); - - // If the current pool this ptr belongs to is big enough - if ( size > that->pool->size - sizeof( struct mlt_release_s ) ) - { - // Allocate - result = mlt_pool_alloc( size ); - - // Copy - memcpy( result, ptr, that->pool->size - sizeof( struct mlt_release_s ) ); - - // Release - mlt_pool_release( ptr ); - } - else - { - // Nothing to do - result = ptr; - } - } - else - { - // Simply allocate - result = mlt_pool_alloc( size ); - } - - return result; -} - -/** Purge unused items in the pool. - * - * A form of garbage collection. - * \public \memberof mlt_pool_s - */ - -void mlt_pool_purge( ) -{ - int i = 0; - - // For each pool - for ( i = 0; i < mlt_properties_count( pools ); i ++ ) - { - // Get the pool - mlt_pool this = mlt_properties_get_data_at( pools, i, NULL ); - - // Pointer to unused memory - void *release = NULL; - - // Lock the pool - pthread_mutex_lock( &this->lock ); - - // We'll free all unused items now - while ( ( release = mlt_deque_pop_back( this->stack ) ) != NULL ) - free( ( char * )release - sizeof( struct mlt_release_s ) ); - - // Unlock the pool - pthread_mutex_unlock( &this->lock ); - } -} - -/** Release the allocated memory. - * - * \public \memberof mlt_pool_s - * \param release an opaque pointer of a block in the pool - */ - -void mlt_pool_release( void *release ) -{ - // Return to the pool - pool_return( release ); -} - -/** Close the pool. - * - * \public \memberof mlt_pool_s - */ - -void mlt_pool_close( ) -{ -#ifdef _MLT_POOL_CHECKS_ - // Stats dump on close - int i = 0; - for ( i = 0; i < mlt_properties_count( pools ); i ++ ) - { - mlt_pool pool = mlt_properties_get_data_at( pools, i, NULL ); - if ( pool->count ) - mlt_log( NULL, MLT_LOG_DEBUG, "%s: size %d allocated %d returned %d %c\n", __FUNCTION__, - pool->size, pool->count, mlt_deque_count( pool->stack ), - pool->count != mlt_deque_count( pool->stack ) ? '*' : ' ' ); - } -#endif - - // Close the properties - mlt_properties_close( pools ); -} - diff --git a/src/framework/mlt_pool.h b/src/framework/mlt_pool.h deleted file mode 100644 index caf983d..0000000 --- a/src/framework/mlt_pool.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * \file mlt_pool.h - * \brief memory pooling functionality - * \see mlt_pool_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_POOL_H -#define _MLT_POOL_H - -extern void mlt_pool_init( ); -extern void *mlt_pool_alloc( int size ); -extern void *mlt_pool_realloc( void *ptr, int size ); -extern void mlt_pool_release( void *release ); -extern void mlt_pool_purge( ); -extern void mlt_pool_close( ); - -#endif diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c deleted file mode 100644 index f43738b..0000000 --- a/src/framework/mlt_producer.c +++ /dev/null @@ -1,1031 +0,0 @@ -/** - * \file mlt_producer.c - * \brief abstraction for all producer services - * \see mlt_producer_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_producer.h" -#include "mlt_factory.h" -#include "mlt_frame.h" -#include "mlt_parser.h" -#include "mlt_profile.h" -#include "mlt_log.h" - -#include -#include -#include -#include - -/* Forward references. */ - -static int producer_get_frame( mlt_service this, mlt_frame_ptr frame, int index ); -static void mlt_producer_property_changed( mlt_service owner, mlt_producer this, char *name ); -static void mlt_producer_service_changed( mlt_service owner, mlt_producer this ); - -/* for debugging */ -//#define _MLT_PRODUCER_CHECKS_ 1 -#ifdef _MLT_PRODUCER_CHECKS_ -static int producers_created = 0; -static int producers_destroyed = 0; -#endif - -/** Initialize a producer service. - * - * \public \memberof mlt_producer_s - * \param this the producer structure to initialize - * \param child a pointer to the child object for the subclass - * \return true if there was an error - */ - -int mlt_producer_init( mlt_producer this, void *child ) -{ - // Check that we haven't received NULL - int error = this == NULL; - - // Continue if no error - if ( error == 0 ) - { -#ifdef _MLT_PRODUCER_CHECKS_ - producers_created ++; -#endif - - // Initialise the producer - memset( this, 0, sizeof( struct mlt_producer_s ) ); - - // Associate with the child - this->child = child; - - // Initialise the service - if ( mlt_service_init( &this->parent, this ) == 0 ) - { - // The parent is the service - mlt_service parent = &this->parent; - - // Define the parent close - parent->close = ( mlt_destructor )mlt_producer_close; - parent->close_object = this; - - // For convenience, we'll assume the close_object is this - this->close_object = this; - - // Get the properties of the parent - mlt_properties properties = MLT_SERVICE_PROPERTIES( parent ); - - // Set the default properties - mlt_properties_set( properties, "mlt_type", "mlt_producer" ); - mlt_properties_set_position( properties, "_position", 0.0 ); - mlt_properties_set_double( properties, "_frame", 0 ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( NULL ) ); - mlt_properties_set_double( properties, "_speed", 1.0 ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", 14999 ); - mlt_properties_set_position( properties, "length", 15000 ); - mlt_properties_set( properties, "eof", "pause" ); - mlt_properties_set( properties, "resource", "" ); - - // Override service get_frame - parent->get_frame = producer_get_frame; - - mlt_events_listen( properties, this, "service-changed", ( mlt_listener )mlt_producer_service_changed ); - mlt_events_listen( properties, this, "property-changed", ( mlt_listener )mlt_producer_property_changed ); - mlt_events_register( properties, "producer-changed", NULL ); - } - } - - return error; -} - -/** Listener for property changes. - * - * If the in, out, or length properties changed, fire a "producer-changed" event. - * - * \private \memberof mlt_producer_s - * \param owner a service (ignored) - * \param this the producer - * \param name the property that changed - */ - -static void mlt_producer_property_changed( mlt_service owner, mlt_producer this, char *name ) -{ - if ( !strcmp( name, "in" ) || !strcmp( name, "out" ) || !strcmp( name, "length" ) ) - mlt_events_fire( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( this ) ), "producer-changed", NULL ); -} - -/** Listener for service changes. - * - * Fires the "producer-changed" event. - * - * \private \memberof mlt_producer_s - * \param owner a service (ignored) - * \param this the producer - */ - -static void mlt_producer_service_changed( mlt_service owner, mlt_producer this ) -{ - mlt_events_fire( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( this ) ), "producer-changed", NULL ); -} - -/** Create and initialize a new producer. - * - * \public \memberof mlt_producer_s - * \return the new producer - */ - -mlt_producer mlt_producer_new( ) -{ - mlt_producer this = malloc( sizeof( struct mlt_producer_s ) ); - mlt_producer_init( this, NULL ); - return this; -} - -/** Determine if producer is a cut. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return true if \p this is a "cut" producer - * \see mlt_producer_cut - */ - -int mlt_producer_is_cut( mlt_producer this ) -{ - return mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( this ), "_cut" ); -} - -/** Determine if producer is a mix. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return true if this is a "mix" producer - * \todo Define a mix producer. - */ - -int mlt_producer_is_mix( mlt_producer this ) -{ - mlt_properties properties = this != NULL ? MLT_PRODUCER_PROPERTIES( this ) : NULL; - mlt_tractor tractor = properties != NULL ? mlt_properties_get_data( properties, "mlt_mix", NULL ) : NULL; - return tractor != NULL; -} - -/** Determine if the producer is a blank. - * - * Blank producers should only appear as an item in a playlist. - * \public \memberof mlt_producer_s - * \param this a producer - * \return true if this is a "blank" producer - * \see mlt_playlist_insert_blank - */ - -int mlt_producer_is_blank( mlt_producer this ) -{ - return this == NULL || !strcmp( mlt_properties_get( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( this ) ), "resource" ), "blank" ); -} - -/** Obtain the parent producer. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return either the parent producer if this is a "cut" producer or \p this otherwise. - */ - -mlt_producer mlt_producer_cut_parent( mlt_producer this ) -{ - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - if ( mlt_producer_is_cut( this ) ) - return mlt_properties_get_data( properties, "_cut_parent", NULL ); - else - return this; -} - -/** Create a cut of this producer. - * - * A "cut" is a portion of another (parent) producer. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \param in the beginning - * \param out the end - * \return the new producer - * \todo Expand on the value of a cut. - */ - -mlt_producer mlt_producer_cut( mlt_producer this, int in, int out ) -{ - mlt_producer result = mlt_producer_new( ); - mlt_producer parent = mlt_producer_cut_parent( this ); - mlt_properties properties = MLT_PRODUCER_PROPERTIES( result ); - mlt_properties parent_props = MLT_PRODUCER_PROPERTIES( parent ); - - mlt_events_block( MLT_PRODUCER_PROPERTIES( result ), MLT_PRODUCER_PROPERTIES( result ) ); - // Special case - allow for a cut of the entire producer (this will squeeze all other cuts to 0) - if ( in <= 0 ) - in = 0; - if ( ( out < 0 || out >= mlt_producer_get_length( parent ) ) && !mlt_producer_is_blank( this ) ) - out = mlt_producer_get_length( parent ) - 1; - - mlt_properties_inc_ref( parent_props ); - mlt_properties_set_int( properties, "_cut", 1 ); - mlt_properties_set_data( properties, "_cut_parent", parent, 0, ( mlt_destructor )mlt_producer_close, NULL ); - mlt_properties_set_position( properties, "length", mlt_properties_get_position( parent_props, "length" ) ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( parent_props, "aspect_ratio" ) ); - mlt_producer_set_in_and_out( result, in, out ); - - return result; -} - -/** Get the parent service object. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return the service parent class - * \see MLT_PRODUCER_SERVICE - */ - -mlt_service mlt_producer_service( mlt_producer this ) -{ - return this != NULL ? &this->parent : NULL; -} - -/** Get the producer properties. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return the producer's property list - * \see MLT_PRODUCER_PROPERTIES - */ - -mlt_properties mlt_producer_properties( mlt_producer this ) -{ - return MLT_SERVICE_PROPERTIES( &this->parent ); -} - -/** Seek to a specified position. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \param position set the "play head" position of the producer - * \return false - * \todo Document how the properties affect behavior. - */ - -int mlt_producer_seek( mlt_producer this, mlt_position position ) -{ - // Determine eof handling - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - char *eof = mlt_properties_get( properties, "eof" ); - int use_points = 1 - mlt_properties_get_int( properties, "ignore_points" ); - - // Recursive behaviour for cuts - repositions parent and then repositions cut - // hence no return on this condition - if ( mlt_producer_is_cut( this ) ) - mlt_producer_seek( mlt_producer_cut_parent( this ), position + mlt_producer_get_in( this ) ); - - // Check bounds - if ( position < 0 || mlt_producer_get_playtime( this ) == 0 ) - { - position = 0; - } - else if ( use_points && ( eof == NULL || !strcmp( eof, "pause" ) ) && position >= mlt_producer_get_playtime( this ) ) - { - mlt_producer_set_speed( this, 0 ); - position = mlt_producer_get_playtime( this ) - 1; - } - else if ( use_points && !strcmp( eof, "loop" ) && position >= mlt_producer_get_playtime( this ) ) - { - position = (int)position % (int)mlt_producer_get_playtime( this ); - } - - // Set the position - mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( this ), "_position", position ); - - // Calculate the absolute frame - mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( this ), "_frame", use_points * mlt_producer_get_in( this ) + position ); - - return 0; -} - -/** Get the current position (relative to in point). - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return the position of the "play head" relative to its beginning - */ - -mlt_position mlt_producer_position( mlt_producer this ) -{ - return mlt_properties_get_position( MLT_PRODUCER_PROPERTIES( this ), "_position" ); -} - -/** Get the current position (relative to start of producer). - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return the position of the "play head" regardless of the in point - */ - -mlt_position mlt_producer_frame( mlt_producer this ) -{ - return mlt_properties_get_position( MLT_PRODUCER_PROPERTIES( this ), "_frame" ); -} - -/** Set the playing speed. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \param speed the new speed as a relative factor (1.0 = normal) - * \return - */ - -int mlt_producer_set_speed( mlt_producer this, double speed ) -{ - return mlt_properties_set_double( MLT_PRODUCER_PROPERTIES( this ), "_speed", speed ); -} - -/** Get the playing speed. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return the speed as a relative factor (1.0 = normal) - */ - -double mlt_producer_get_speed( mlt_producer this ) -{ - return mlt_properties_get_double( MLT_PRODUCER_PROPERTIES( this ), "_speed" ); -} - -/** Get the frames per second. - * - * This is determined by the producer's profile. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return the video refresh rate - */ - -double mlt_producer_get_fps( mlt_producer this ) -{ - mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( this ) ); - return mlt_profile_fps( profile ); -} - -/** Set the in and out points. - * - * The in point is where play out should start relative to the natural start - * of the underlying file. The out point is where play out should end, also - * relative to the start of the underlying file. If the underlying resource is - * a live stream, then the in point is an offset relative to first usable - * sample. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \param in the relative starting time - * \param out the relative ending time - * \return false - */ - -int mlt_producer_set_in_and_out( mlt_producer this, mlt_position in, mlt_position out ) -{ - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Correct ins and outs if necessary - if ( in < 0 ) - in = 0; - else if ( in >= mlt_producer_get_length( this ) ) - in = mlt_producer_get_length( this ) - 1; - - if ( out < 0 ) - out = 0; - else if ( out >= mlt_producer_get_length( this ) && !mlt_producer_is_blank( this ) ) - out = mlt_producer_get_length( this ) - 1; - else if ( out >= mlt_producer_get_length( this ) && mlt_producer_is_blank( this ) ) - mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( this ), "length", out + 1 ); - - // Swap ins and outs if wrong - if ( out < in ) - { - mlt_position t = in; - in = out; - out = t; - } - - // Set the values - mlt_events_block( properties, properties ); - mlt_properties_set_position( properties, "in", in ); - mlt_events_unblock( properties, properties ); - mlt_properties_set_position( properties, "out", out ); - - return 0; -} - -/** Physically reduce the producer (typically a cut) to a 0 length. - * Essentially, all 0 length cuts should be immediately removed by containers. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return false - */ - -int mlt_producer_clear( mlt_producer this ) -{ - if ( this != NULL ) - { - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - mlt_events_block( properties, properties ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_events_unblock( properties, properties ); - mlt_properties_set_position( properties, "out", -1 ); - } - return 0; -} - -/** Get the in point. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return the in point - */ - -mlt_position mlt_producer_get_in( mlt_producer this ) -{ - return mlt_properties_get_position( MLT_PRODUCER_PROPERTIES( this ), "in" ); -} - -/** Get the out point. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return the out point - */ - -mlt_position mlt_producer_get_out( mlt_producer this ) -{ - return mlt_properties_get_position( MLT_PRODUCER_PROPERTIES( this ), "out" ); -} - -/** Get the total play time. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return the playable (based on in and out points) duration - */ - -mlt_position mlt_producer_get_playtime( mlt_producer this ) -{ - return mlt_producer_get_out( this ) - mlt_producer_get_in( this ) + 1; -} - -/** Get the total, unedited length of the producer. - * - * The value returned by a live streaming producer is unknown. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \return the duration of the producer regardless of in and out points - */ - -mlt_position mlt_producer_get_length( mlt_producer this ) -{ - return mlt_properties_get_position( MLT_PRODUCER_PROPERTIES( this ), "length" ); -} - -/** Prepare for next frame. - * - * Advance the play out position. If the speed is less than zero, it will - * move the play out position in the reverse direction. - * - * \public \memberof mlt_producer_s - * \param this a producer - */ - -void mlt_producer_prepare_next( mlt_producer this ) -{ - if ( mlt_producer_get_speed( this ) != 0 ) - mlt_producer_seek( this, mlt_producer_position( this ) + mlt_producer_get_speed( this ) ); -} - -/** Get a frame. - * - * This is the implementation of the \p get_frame virtual function. - * It requests a new frame object from the actual producer for the current - * play out position. The producer and its filters can add information and - * operations to the frame object in their get_frame handlers. - * - * \private \memberof mlt_producer_s - * \param service a service - * \param[out] frame a frame by reference - * \param index as determined by the actual producer - * \return true if there was an error - * \todo Learn more about the details and document how certain properties affect - * its behavior. - */ - -static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int index ) -{ - int result = 1; - mlt_producer this = service != NULL ? service->child : NULL; - - if ( this != NULL && !mlt_producer_is_cut( this ) ) - { - // Get the properties of this producer - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Determine eof handling - char *eof = mlt_properties_get( MLT_PRODUCER_PROPERTIES( this ), "eof" ); - - // Get the speed of the producer - double speed = mlt_producer_get_speed( this ); - - // We need to use the clone if it's specified - mlt_producer clone = mlt_properties_get_data( properties, "use_clone", NULL ); - - // If no clone is specified, use this - clone = clone == NULL ? this : clone; - - // A properly instatiated producer will have a get_frame method... - if ( this->get_frame == NULL || ( !strcmp( eof, "continue" ) && mlt_producer_position( this ) > mlt_producer_get_out( this ) ) ) - { - // Generate a test frame - *frame = mlt_frame_init( service ); - - // Set the position - result = mlt_frame_set_position( *frame, mlt_producer_position( this ) ); - - // Mark as a test card - mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_image", 1 ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_audio", 1 ); - - // Calculate the next position - mlt_producer_prepare_next( this ); - } - else - { - // Get the frame from the implementation - result = this->get_frame( clone, frame, index ); - } - - // Copy the fps and speed of the producer onto the frame - properties = MLT_FRAME_PROPERTIES( *frame ); - mlt_properties_set_double( properties, "_speed", speed ); - mlt_properties_set_int( properties, "test_audio", mlt_frame_is_test_audio( *frame ) ); - mlt_properties_set_int( properties, "test_image", mlt_frame_is_test_card( *frame ) ); - if ( mlt_properties_get_data( properties, "_producer", NULL ) == NULL ) - mlt_properties_set_data( properties, "_producer", service, 0, NULL, NULL ); - } - else if ( this != NULL ) - { - // Get the speed of the cut - double speed = mlt_producer_get_speed( this ); - - // Get the parent of this cut - mlt_producer parent = mlt_producer_cut_parent( this ); - - // Get the properties of the parent - mlt_properties parent_properties = MLT_PRODUCER_PROPERTIES( parent ); - - // Get the properties of the cut - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Determine the clone index - int clone_index = mlt_properties_get_int( properties, "_clone" ); - - // Determine the clone to use - mlt_producer clone = this; - - if ( clone_index > 0 ) - { - char key[ 25 ]; - sprintf( key, "_clone.%d", clone_index - 1 ); - clone = mlt_properties_get_data( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( this ) ), key, NULL ); - if ( clone == NULL ) mlt_log( service, MLT_LOG_ERROR, "requested clone doesn't exist %d\n", clone_index ); - clone = clone == NULL ? this : clone; - } - else - { - clone = parent; - } - - // We need to seek to the correct position in the clone - mlt_producer_seek( clone, mlt_producer_get_in( this ) + mlt_properties_get_int( properties, "_position" ) ); - - // Assign the clone property to the parent - mlt_properties_set_data( parent_properties, "use_clone", clone, 0, NULL, NULL ); - - // Now get the frame from the parents service - result = mlt_service_get_frame( MLT_PRODUCER_SERVICE( parent ), frame, index ); - - // We're done with the clone now - mlt_properties_set_data( parent_properties, "use_clone", NULL, 0, NULL, NULL ); - - // This is useful and required by always_active transitions to determine in/out points of the cut - if ( mlt_properties_get_data( MLT_FRAME_PROPERTIES( *frame ), "_producer", NULL ) == MLT_PRODUCER_SERVICE( parent ) ) - mlt_properties_set_data( MLT_FRAME_PROPERTIES( *frame ), "_producer", this, 0, NULL, NULL ); - - mlt_properties_set_double( MLT_FRAME_PROPERTIES( *frame ), "_speed", speed ); - mlt_producer_prepare_next( this ); - } - else - { - *frame = mlt_frame_init( service ); - result = 0; - } - - // Pass on all meta properties from the producer/cut on to the frame - if ( *frame != NULL && this != NULL ) - { - int i = 0; - mlt_properties p_props = MLT_PRODUCER_PROPERTIES( this ); - mlt_properties f_props = MLT_FRAME_PROPERTIES( *frame ); - int count = mlt_properties_count( p_props ); - for ( i = 0; i < count; i ++ ) - { - char *name = mlt_properties_get_name( p_props, i ); - if ( !strncmp( name, "meta.", 5 ) ) - mlt_properties_set( f_props, name, mlt_properties_get( p_props, name ) ); - else if ( !strncmp( name, "set.", 4 ) ) - mlt_properties_set( f_props, name + 4, mlt_properties_get( p_props, name ) ); - } - } - - return result; -} - -/** Attach a filter. - * - * \public \memberof mlt_producer_s - * \param this a producer - * \param filter the filter to attach - * \return true if there was an error - */ - -int mlt_producer_attach( mlt_producer this, mlt_filter filter ) -{ - return mlt_service_attach( MLT_PRODUCER_SERVICE( this ), filter ); -} - -/** Detach a filter. - * - * \public \memberof mlt_producer_s - * \param this a service - * \param filter the filter to detach - * \return true if there was an error - */ - -int mlt_producer_detach( mlt_producer this, mlt_filter filter ) -{ - return mlt_service_detach( MLT_PRODUCER_SERVICE( this ), filter ); -} - -/** Retrieve a filter. - * - * \public \memberof mlt_producer_s - * \param this a service - * \param index which filter to retrieve - * \return the filter or null if there was an error - */ - -mlt_filter mlt_producer_filter( mlt_producer this, int index ) -{ - return mlt_service_filter( MLT_PRODUCER_SERVICE( this ), index ); -} - -/** Clone this producer. - * - * \private \memberof mlt_producer_s - * \param this a producer - * \return a new producer that is a copy of \p this - * \see mlt_producer_set_clones - */ - -static mlt_producer mlt_producer_clone( mlt_producer this ) -{ - mlt_producer clone = NULL; - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - char *resource = mlt_properties_get( properties, "resource" ); - char *service = mlt_properties_get( properties, "mlt_service" ); - mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( this ) ); - - mlt_events_block( mlt_factory_event_object( ), mlt_factory_event_object( ) ); - - if ( service != NULL ) - clone = mlt_factory_producer( profile, service, resource ); - - if ( clone == NULL && resource != NULL ) - clone = mlt_factory_producer( profile, mlt_environment( "MLT_PRODUCER" ), resource ); - - if ( clone != NULL ) - mlt_properties_inherit( MLT_PRODUCER_PROPERTIES( clone ), properties ); - - mlt_events_unblock( mlt_factory_event_object( ), mlt_factory_event_object( ) ); - - return clone; -} - -/** Create clones. - * - * \private \memberof mlt_producer_s - * \param this a producer - * \param clones the number of copies to make - * \see mlt_producer_optimise - */ - -static void mlt_producer_set_clones( mlt_producer this, int clones ) -{ - mlt_producer parent = mlt_producer_cut_parent( this ); - mlt_properties properties = MLT_PRODUCER_PROPERTIES( parent ); - int existing = mlt_properties_get_int( properties, "_clones" ); - int i = 0; - char key[ 25 ]; - - // If the number of existing clones is different, then create/remove as necessary - if ( existing != clones ) - { - if ( existing < clones ) - { - for ( i = existing; i < clones; i ++ ) - { - mlt_producer clone = mlt_producer_clone( parent ); - sprintf( key, "_clone.%d", i ); - mlt_properties_set_data( properties, key, clone, 0, ( mlt_destructor )mlt_producer_close, NULL ); - } - } - else - { - for ( i = clones; i < existing; i ++ ) - { - sprintf( key, "_clone.%d", i ); - mlt_properties_set_data( properties, key, NULL, 0, NULL, NULL ); - } - } - } - - // Ensure all properties on the parent are passed to the clones - for ( i = 0; i < clones; i ++ ) - { - mlt_producer clone = NULL; - sprintf( key, "_clone.%d", i ); - clone = mlt_properties_get_data( properties, key, NULL ); - if ( clone != NULL ) - mlt_properties_pass( MLT_PRODUCER_PROPERTIES( clone ), properties, "" ); - } - - // Update the number of clones on the properties - mlt_properties_set_int( properties, "_clones", clones ); -} - -/** \brief private to mlt_producer_s, used by mlt_producer_optimise() */ - -typedef struct -{ - int multitrack; - int track; - int position; - int length; - int offset; -} -track_info; - -/** \brief private to mlt_producer_s, used by mlt_producer_optimise() */ - -typedef struct -{ - mlt_producer cut; - int start; - int end; -} -clip_references; - -static int intersect( clip_references *a, clip_references *b ) -{ - int diff = ( a->start - b->start ) + ( a->end - b->end ); - return diff >= 0 && diff < ( a->end - a->start + 1 ); -} - -static int push( mlt_parser this, int multitrack, int track, int position ) -{ - mlt_properties properties = mlt_parser_properties( this ); - mlt_deque stack = mlt_properties_get_data( properties, "stack", NULL ); - track_info *info = malloc( sizeof( track_info ) ); - info->multitrack = multitrack; - info->track = track; - info->position = position; - info->length = 0; - info->offset = 0; - return mlt_deque_push_back( stack, info ); -} - -static track_info *pop( mlt_parser this ) -{ - mlt_properties properties = mlt_parser_properties( this ); - mlt_deque stack = mlt_properties_get_data( properties, "stack", NULL ); - return mlt_deque_pop_back( stack ); -} - -static track_info *peek( mlt_parser this ) -{ - mlt_properties properties = mlt_parser_properties( this ); - mlt_deque stack = mlt_properties_get_data( properties, "stack", NULL ); - return mlt_deque_peek_back( stack ); -} - -static int on_start_multitrack( mlt_parser this, mlt_multitrack object ) -{ - track_info *info = peek( this ); - return push( this, info->multitrack ++, info->track, info->position ); -} - -static int on_start_track( mlt_parser this ) -{ - track_info *info = peek( this ); - info->position -= info->offset; - info->length -= info->offset; - return push( this, info->multitrack, info->track ++, info->position ); -} - -static int on_start_producer( mlt_parser this, mlt_producer object ) -{ - mlt_properties properties = mlt_parser_properties( this ); - mlt_properties producers = mlt_properties_get_data( properties, "producers", NULL ); - mlt_producer parent = mlt_producer_cut_parent( object ); - if ( mlt_service_identify( ( mlt_service )mlt_producer_cut_parent( object ) ) == producer_type && mlt_producer_is_cut( object ) ) - { - int ref_count = 0; - clip_references *old_refs = NULL; - clip_references *refs = NULL; - char key[ 50 ]; - int count = 0; - track_info *info = peek( this ); - sprintf( key, "%p", parent ); - mlt_properties_get_data( producers, key, &count ); - mlt_properties_set_data( producers, key, parent, ++ count, NULL, NULL ); - old_refs = mlt_properties_get_data( properties, key, &ref_count ); - refs = malloc( ( ref_count + 1 ) * sizeof( clip_references ) ); - if ( old_refs != NULL ) - memcpy( refs, old_refs, ref_count * sizeof( clip_references ) ); - mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( object ), "_clone", -1 ); - refs[ ref_count ].cut = object; - refs[ ref_count ].start = info->position; - refs[ ref_count ].end = info->position + mlt_producer_get_playtime( object ) - 1; - mlt_properties_set_data( properties, key, refs, ++ ref_count, free, NULL ); - info->position += mlt_producer_get_playtime( object ); - info->length += mlt_producer_get_playtime( object ); - } - return 0; -} - -static int on_end_track( mlt_parser this ) -{ - track_info *track = pop( this ); - track_info *multi = peek( this ); - multi->length += track->length; - multi->position += track->length; - multi->offset = track->length; - free( track ); - return 0; -} - -static int on_end_multitrack( mlt_parser this, mlt_multitrack object ) -{ - track_info *multi = pop( this ); - track_info *track = peek( this ); - track->position += multi->length; - track->length += multi->length; - free( multi ); - return 0; -} - -/** Optimise for overlapping cuts from the same clip. - * - * \todo learn more about this - * \public \memberof mlt_producer_s - * \param this a producer - * \return true if there was an error - */ - -int mlt_producer_optimise( mlt_producer this ) -{ - int error = 1; - mlt_parser parser = mlt_parser_new( ); - if ( parser != NULL ) - { - int i = 0, j = 0, k = 0; - mlt_properties properties = mlt_parser_properties( parser ); - mlt_properties producers = mlt_properties_new( ); - mlt_deque stack = mlt_deque_init( ); - mlt_properties_set_data( properties, "producers", producers, 0, ( mlt_destructor )mlt_properties_close, NULL ); - mlt_properties_set_data( properties, "stack", stack, 0, ( mlt_destructor )mlt_deque_close, NULL ); - parser->on_start_producer = on_start_producer; - parser->on_start_track = on_start_track; - parser->on_end_track = on_end_track; - parser->on_start_multitrack = on_start_multitrack; - parser->on_end_multitrack = on_end_multitrack; - push( parser, 0, 0, 0 ); - mlt_parser_start( parser, MLT_PRODUCER_SERVICE( this ) ); - free( pop( parser ) ); - for ( k = 0; k < mlt_properties_count( producers ); k ++ ) - { - char *name = mlt_properties_get_name( producers, k ); - int count = 0; - int clones = 0; - int max_clones = 0; - mlt_producer producer = mlt_properties_get_data( producers, name, &count ); - if ( producer != NULL && count > 1 ) - { - clip_references *refs = mlt_properties_get_data( properties, name, &count ); - for ( i = 0; i < count; i ++ ) - { - clones = 0; - for ( j = i + 1; j < count; j ++ ) - { - if ( intersect( &refs[ i ], &refs[ j ] ) ) - { - clones ++; - mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( refs[ j ].cut ), "_clone", clones ); - } - } - if ( clones > max_clones ) - max_clones = clones; - } - - for ( i = 0; i < count; i ++ ) - { - mlt_producer cut = refs[ i ].cut; - if ( mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( cut ), "_clone" ) == -1 ) - mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( cut ), "_clone", 0 ); - } - - mlt_producer_set_clones( producer, max_clones ); - } - else if ( producer != NULL ) - { - clip_references *refs = mlt_properties_get_data( properties, name, &count ); - for ( i = 0; i < count; i ++ ) - { - mlt_producer cut = refs[ i ].cut; - mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( cut ), "_clone", 0 ); - } - mlt_producer_set_clones( producer, 0 ); - } - } - mlt_parser_close( parser ); - } - return error; -} - -/** Close the producer. - * - * Destroys the producer and deallocates its resources managed by its - * properties list. This will call the close virtual function. Therefore, a - * subclass that defines its own close function should set its virtual close - * function to NULL prior to calling this to avoid circular calls. - * - * \public \memberof mlt_producer_s - * \param this a producer - */ - -void mlt_producer_close( mlt_producer this ) -{ - if ( this != NULL && mlt_properties_dec_ref( MLT_PRODUCER_PROPERTIES( this ) ) <= 0 ) - { - this->parent.close = NULL; - - if ( this->close != NULL ) - { - this->close( this->close_object ); - } - else - { - int destroy = mlt_producer_is_cut( this ); - -#if _MLT_PRODUCER_CHECKS_ == 1 - // Show debug info - mlt_properties_debug( MLT_PRODUCER_PROPERTIES( this ), "Producer closing", stderr ); -#endif - -#ifdef _MLT_PRODUCER_CHECKS_ - // Show current stats - these should match when the app is closed - mlt_log( MLT_PRODUCER_SERVICE( this ), MLT_LOG_DEBUG, "Producers created %d, destroyed %d\n", producers_created, ++producers_destroyed ); -#endif - - mlt_service_close( &this->parent ); - - if ( destroy ) - free( this ); - } - } -} diff --git a/src/framework/mlt_producer.h b/src/framework/mlt_producer.h deleted file mode 100644 index 37ba2ba..0000000 --- a/src/framework/mlt_producer.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * \file mlt_producer.h - * \brief abstraction for all producer services - * \see mlt_producer_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_PRODUCER_H_ -#define _MLT_PRODUCER_H_ - -#include "mlt_service.h" -#include "mlt_filter.h" - -/** \brief Producer abstract service class - * - * A producer is a service that generates audio, video, and metadata. - * Some day it may also generate text (subtitles). This is not to say - * a producer "synthesizes," rather that is an origin of data within the - * service network - that could be through synthesis or reading a stream. - * - * \extends mlt_service - * \event \em producer-changed - * \properties \em mlt_type the name of the service subclass, e.g. mlt_producer - * \properties \em mlt_service the name of a producer subclass - * \properties \em _position the current position of the play head, relative to the in point - * \properties \em _frame the current position of the play head, relative to the beginning of the resource - * \properties \em _speed the current speed factor, where 1.0 is normal - * \properties \em aspect_ratio sample aspect ratio - * \properties \em length the duration of the cut in frames - * \properties \em eof the end-of-file behavior, one of: pause, continue, loop - * \properties \em resource the file name, stream address, or the class name in angle brackets - * \properties \em _cut set if this producer is a "cut" producer - * \properties \em mlt_mix stores the data for a "mix" producer - * \properties \em _cut_parent holds a reference to the cut's parent producer - * \properties \em ignore_points Set this to temporarily disable the in and out points. - * \properties \em use_clone holds a reference to a clone's producer, as created by mlt_producer_optimise - * \properties \em _clone is the index of the clone in the list of clones stored on the clone's producer - * \properties \em _clones is the number of clones of the producer, as created by mlt_producer_optimise - * \properties \em _clone.{N} holds a reference to the N'th clone of the producer, as created by mlt_producer_optimise - * \properties \em meta.* holds metadata - there is a loose taxonomy to be defined - * \properties \em set.* holds properties to set on a frame produced - * \todo define the media metadata taxonomy - */ - -struct mlt_producer_s -{ - /** A producer is a service. */ - struct mlt_service_s parent; - - /** Get a frame of data (virtual function). - * - * \param mlt_producer a producer - * \param mlt_frame_ptr a frame pointer by reference - * \param int an index - * \return true if there was an error - */ - int ( *get_frame )( mlt_producer, mlt_frame_ptr, int ); - - /** the destructor virtual function */ - mlt_destructor close; - void *close_object; /**< the object supplied to the close virtual function */ - - void *local; /**< \private instance object */ - void *child; /**< \private the object of a subclass */ -}; - -/* - * Public final methods - */ - -#define MLT_PRODUCER_SERVICE( producer ) ( &( producer )->parent ) -#define MLT_PRODUCER_PROPERTIES( producer ) MLT_SERVICE_PROPERTIES( MLT_PRODUCER_SERVICE( producer ) ) - -extern int mlt_producer_init( mlt_producer self, void *child ); -extern mlt_producer mlt_producer_new( ); -extern mlt_service mlt_producer_service( mlt_producer self ); -extern mlt_properties mlt_producer_properties( mlt_producer self ); -extern int mlt_producer_seek( mlt_producer self, mlt_position position ); -extern mlt_position mlt_producer_position( mlt_producer self ); -extern mlt_position mlt_producer_frame( mlt_producer self ); -extern int mlt_producer_set_speed( mlt_producer self, double speed ); -extern double mlt_producer_get_speed( mlt_producer self ); -extern double mlt_producer_get_fps( mlt_producer self ); -extern int mlt_producer_set_in_and_out( mlt_producer self, mlt_position in, mlt_position out ); -extern int mlt_producer_clear( mlt_producer self ); -extern mlt_position mlt_producer_get_in( mlt_producer self ); -extern mlt_position mlt_producer_get_out( mlt_producer self ); -extern mlt_position mlt_producer_get_playtime( mlt_producer self ); -extern mlt_position mlt_producer_get_length( mlt_producer self ); -extern void mlt_producer_prepare_next( mlt_producer self ); -extern int mlt_producer_attach( mlt_producer self, mlt_filter filter ); -extern int mlt_producer_detach( mlt_producer self, mlt_filter filter ); -extern mlt_filter mlt_producer_filter( mlt_producer self, int index ); -extern mlt_producer mlt_producer_cut( mlt_producer self, int in, int out ); -extern int mlt_producer_is_cut( mlt_producer self ); -extern int mlt_producer_is_mix( mlt_producer self ); -extern int mlt_producer_is_blank( mlt_producer self ); -extern mlt_producer mlt_producer_cut_parent( mlt_producer self ); -extern int mlt_producer_optimise( mlt_producer self ); -extern void mlt_producer_close( mlt_producer self ); - -#endif diff --git a/src/framework/mlt_profile.c b/src/framework/mlt_profile.c deleted file mode 100644 index 3c01626..0000000 --- a/src/framework/mlt_profile.c +++ /dev/null @@ -1,303 +0,0 @@ -/** - * \file mlt_profile.c - * \brief video output definition - * \see mlt_profile_s - * - * Copyright (C) 2007-2009 Ushodaya Enterprises Limited - * \author Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_profile.h" -#include "mlt_factory.h" -#include "mlt_properties.h" - -#include -#include -#include - - -/** the default subdirectory of the prefix for holding profiles */ -#define PROFILES_DIR "/share/mlt/profiles/" - -/** Load a profile from the system folder. - * - * The environment variable MLT_PROFILES_PATH overrides the default \p PROFILES_DIR. - * - * \private \memberof mlt_profile_s - * \param name the name of a profile settings file located in the standard location or - * the full path name to a profile settings file - * \return a profile or NULL on error - */ - -static mlt_profile mlt_profile_select( const char *name ) -{ - char *filename = NULL; - const char *prefix = getenv( "MLT_PROFILES_PATH" ); - mlt_properties properties = mlt_properties_load( name ); - mlt_profile profile = NULL; - - // Try to load from file specification - if ( properties && mlt_properties_get_int( properties, "width" ) ) - { - filename = calloc( 1, strlen( name ) + 1 ); - } - // Load from $prefix/share/mlt/profiles - else if ( prefix == NULL ) - { - prefix = PREFIX; - filename = calloc( 1, strlen( prefix ) + strlen( PROFILES_DIR ) + strlen( name ) + 2 ); - strcpy( filename, prefix ); - if ( filename[ strlen( filename ) - 1 ] != '/' ) - filename[ strlen( filename ) ] = '/'; - strcat( filename, PROFILES_DIR ); - } - // Use environment variable instead - else - { - filename = calloc( 1, strlen( prefix ) + strlen( name ) + 2 ); - strcpy( filename, prefix ); - if ( filename[ strlen( filename ) - 1 ] != '/' ) - filename[ strlen( filename ) ] = '/'; - } - - // Finish loading - strcat( filename, name ); - profile = mlt_profile_load_file( filename ); - - // Cleanup - mlt_properties_close( properties ); - free( filename ); - - return profile; -} - -/** Construct a profile. - * - * This will never return NULL as it uses the dv_pal settings as hard-coded fallback default. - * - * \public \memberof mlt_profile_s - * @param name the name of a profile settings file located in the standard location or - * the full path name to a profile settings file - * @return a profile - */ - -mlt_profile mlt_profile_init( const char *name ) -{ - mlt_profile profile = NULL; - - // Explicit profile by name gets priority over environment variables - if ( name ) - profile = mlt_profile_select( name ); - - // Try to load by environment variable - if ( profile == NULL ) - { - // MLT_PROFILE is preferred environment variable - if ( getenv( "MLT_PROFILE" ) ) - profile = mlt_profile_select( getenv( "MLT_PROFILE" ) ); - // MLT_NORMALISATION backwards compatibility - else if ( getenv( "MLT_NORMALISATION" ) && strcmp( getenv( "MLT_NORMALISATION" ), "PAL" ) ) - profile = mlt_profile_select( "dv_ntsc" ); - else - profile = mlt_profile_select( "dv_pal" ); - - // If still not loaded (no profile files), default to PAL - if ( profile == NULL ) - { - profile = calloc( 1, sizeof( struct mlt_profile_s ) ); - if ( profile ) - { - mlt_environment_set( "MLT_PROFILE", "dv_pal" ); - profile->description = strdup( "PAL 4:3 DV or DVD" ); - profile->frame_rate_num = 25; - profile->frame_rate_den = 1; - profile->width = 720; - profile->height = 576; - profile->progressive = 0; - profile->sample_aspect_num = 16; - profile->sample_aspect_den = 15; - profile->display_aspect_num = 4; - profile->display_aspect_den = 3; - } - } - } - return profile; -} - -/** Load a profile from specific file. - * - * \public \memberof mlt_profile_s - * @param file the full path name to a properties file - * @return a profile or NULL on error - */ - -mlt_profile mlt_profile_load_file( const char *file ) -{ - mlt_profile profile = NULL; - - // Load the profile as properties - mlt_properties properties = mlt_properties_load( file ); - if ( properties ) - { - // Simple check if the profile is valid - if ( mlt_properties_get_int( properties, "width" ) ) - { - profile = mlt_profile_load_properties( properties ); - - // Set MLT_PROFILE to basename - char *filename = strdup( file ); - mlt_environment_set( "MLT_PROFILE", basename( filename ) ); - free( filename ); - } - mlt_properties_close( properties ); - } - - // Set MLT_NORMALISATION to appease legacy modules - char *profile_name = mlt_environment( "MLT_PROFILE" ); - if ( profile_name ) - { - if ( strstr( profile_name, "_ntsc" ) || - strstr( profile_name, "_60" ) || - strstr( profile_name, "_30" ) ) - { - mlt_environment_set( "MLT_NORMALISATION", "NTSC" ); - } - else if ( strstr( profile_name, "_pal" ) || - strstr( profile_name, "_50" ) || - strstr( profile_name, "_25" ) ) - { - mlt_environment_set( "MLT_NORMALISATION", "PAL" ); - } - } - return profile; -} - -/** Load a profile from a properties object. - * - * \public \memberof mlt_profile_s - * @param properties a properties list - * @return a profile or NULL if out of memory - */ - -mlt_profile mlt_profile_load_properties( mlt_properties properties ) -{ - mlt_profile profile = calloc( 1, sizeof( struct mlt_profile_s ) ); - if ( profile ) - { - if ( mlt_properties_get( properties, "name" ) ) - mlt_environment_set( "MLT_PROFILE", mlt_properties_get( properties, "name" ) ); - if ( mlt_properties_get( properties, "description" ) ) - profile->description = strdup( mlt_properties_get( properties, "description" ) ); - profile->frame_rate_num = mlt_properties_get_int( properties, "frame_rate_num" ); - profile->frame_rate_den = mlt_properties_get_int( properties, "frame_rate_den" ); - profile->width = mlt_properties_get_int( properties, "width" ); - profile->height = mlt_properties_get_int( properties, "height" ); - profile->progressive = mlt_properties_get_int( properties, "progressive" ); - profile->sample_aspect_num = mlt_properties_get_int( properties, "sample_aspect_num" ); - profile->sample_aspect_den = mlt_properties_get_int( properties, "sample_aspect_den" ); - profile->display_aspect_num = mlt_properties_get_int( properties, "display_aspect_num" ); - profile->display_aspect_den = mlt_properties_get_int( properties, "display_aspect_den" ); - } - return profile; -} - -/** Load an anonymous profile from string. - * - * \public \memberof mlt_profile_s - * @param string a newline-delimited list of properties as name=value pairs - * @return a profile or NULL if out of memory - */ - -mlt_profile mlt_profile_load_string( const char *string ) -{ - mlt_properties properties = mlt_properties_new(); - if ( properties ) - { - const char *p = string; - while ( p ) - { - if ( strcmp( p, "" ) && p[ 0 ] != '#' ) - mlt_properties_parse( properties, p ); - p = strchr( p, '\n' ); - if ( p ) p++; - } - } - return mlt_profile_load_properties( properties ); -} - -/** Get the video frame rate as a floating point value. - * - * \public \memberof mlt_profile_s - * @param aprofile a profile - * @return the frame rate - */ - -double mlt_profile_fps( mlt_profile aprofile ) -{ - if ( aprofile ) - return ( double ) aprofile->frame_rate_num / aprofile->frame_rate_den; - else - return 0; -} - -/** Get the sample aspect ratio as a floating point value. - * - * \public \memberof mlt_profile_s - * @param aprofile a profile - * @return the pixel aspect ratio - */ - -double mlt_profile_sar( mlt_profile aprofile ) -{ - if ( aprofile ) - return ( double ) aprofile->sample_aspect_num / aprofile->sample_aspect_den; - else - return 0; -} - -/** Get the display aspect ratio as floating point value. - * - * \public \memberof mlt_profile_s - * @param aprofile a profile - * @return the image aspect ratio - */ - -double mlt_profile_dar( mlt_profile aprofile ) -{ - if ( aprofile ) - return ( double ) aprofile->display_aspect_num / aprofile->display_aspect_den; - else - return 0; -} - -/** Free up the global profile resources. - * - * \public \memberof mlt_profile_s - * @param profile a profile - */ - -void mlt_profile_close( mlt_profile profile ) -{ - if ( profile ) - { - if ( profile->description ) - free( profile->description ); - profile->description = NULL; - free( profile ); - profile = NULL; - } -} diff --git a/src/framework/mlt_profile.h b/src/framework/mlt_profile.h deleted file mode 100644 index 6245640..0000000 --- a/src/framework/mlt_profile.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * \file mlt_profile.h - * \brief video output definition - * \see mlt_profile_s - * - * Copyright (C) 2007-2009 Ushodaya Enterprises Limited - * \author Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_PROFILE_H -#define _MLT_PROFILE_H - -#include "mlt_types.h" - -/** \brief Profile class - * - */ - -struct mlt_profile_s -{ - char* description; /**< a brief description suitable as a label in UI menu */ - int frame_rate_num; /**< the numerator of the video frame rate */ - int frame_rate_den; /**< the denominator of the video frame rate */ - int width; /**< the horizontal resolution of the video */ - int height; /**< the vertical resolution of the video */ - int progressive; /**< a flag to indicate if the video is progressive scan, interlace if not set */ - int sample_aspect_num; /**< the numerator of the pixel aspect ratio */ - int sample_aspect_den; /**< the denominator of the pixel aspect ratio */ - int display_aspect_num; /**< the numerator of the image aspect ratio in case it can not be simply derived (e.g. ITU-R 601) */ - int display_aspect_den; /**< the denominator of the image aspect ratio in case it can not be simply derived (e.g. ITU-R 601) */ -}; - -extern mlt_profile mlt_profile_init( const char *name ); -extern mlt_profile mlt_profile_load_file( const char *file ); -extern mlt_profile mlt_profile_load_properties( mlt_properties properties ); -extern mlt_profile mlt_profile_load_string( const char *string ); -extern double mlt_profile_fps( mlt_profile profile ); -extern double mlt_profile_sar( mlt_profile profile ); -extern double mlt_profile_dar( mlt_profile profile ); -extern void mlt_profile_close( mlt_profile profile ); -#endif diff --git a/src/framework/mlt_properties.c b/src/framework/mlt_properties.c deleted file mode 100644 index 97ee02d..0000000 --- a/src/framework/mlt_properties.c +++ /dev/null @@ -1,1754 +0,0 @@ -/** - * \file mlt_properties.c - * \brief Properties class definition - * \see mlt_properties_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * \author Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_properties.h" -#include "mlt_property.h" -#include "mlt_deque.h" -#include "mlt_log.h" - -#include -#include -#include -#include -#include -#include -#include -#include - - -/** \brief private implementation of the property list */ - -typedef struct -{ - int hash[ 199 ]; - char **name; - mlt_property *value; - int count; - int size; - mlt_properties mirror; - int ref_count; - pthread_mutex_t mutex; -} -property_list; - -/* Memory leak checks */ - -//#define _MLT_PROPERTY_CHECKS_ 2 -#ifdef _MLT_PROPERTY_CHECKS_ -static int properties_created = 0; -static int properties_destroyed = 0; -#endif - -/** Initialize a properties object that was already allocated. - * - * This does allocate its ::property_list, and it adds a reference count. - * \public \memberof mlt_properties_s - * \param this the properties structure to initialize - * \param child an opaque pointer to a subclass object - * \return true if failed - */ - -int mlt_properties_init( mlt_properties this, void *child ) -{ - if ( this != NULL ) - { -#ifdef _MLT_PROPERTY_CHECKS_ - // Increment number of properties created - properties_created ++; -#endif - - // NULL all methods - memset( this, 0, sizeof( struct mlt_properties_s ) ); - - // Assign the child of the object - this->child = child; - - // Allocate the local structure - this->local = calloc( sizeof( property_list ), 1 ); - - // Increment the ref count - ( ( property_list * )this->local )->ref_count = 1; - pthread_mutex_init( &( ( property_list * )this->local )->mutex, NULL );; - } - - // Check that initialisation was successful - return this != NULL && this->local == NULL; -} - -/** Create a properties object. - * - * This allocates the properties structure and calls mlt_properties_init() on it. - * Free the properties object with mlt_properties_close(). - * \public \memberof mlt_properties_s - * \return a new properties object - */ - -mlt_properties mlt_properties_new( ) -{ - // Construct a standalone properties object - mlt_properties this = calloc( sizeof( struct mlt_properties_s ), 1 ); - - // Initialise this - mlt_properties_init( this, NULL ); - - // Return the pointer - return this; -} - -/** Create a properties object by reading a .properties text file. - * - * Free the properties object with mlt_properties_close(). - * \deprecated Please start using mlt_properties_parse_yaml(). - * \public \memberof mlt_properties_s - * \param filename a string contain the absolute file name - * \return a new properties object - */ - -mlt_properties mlt_properties_load( const char *filename ) -{ - // Construct a standalone properties object - mlt_properties this = mlt_properties_new( ); - - if ( this != NULL ) - { - // Open the file - FILE *file = fopen( filename, "r" ); - - // Load contents of file - if ( file != NULL ) - { - // Temp string - char temp[ 1024 ]; - char last[ 1024 ] = ""; - - // Read each string from the file - while( fgets( temp, 1024, file ) ) - { - // Chomp the string - temp[ strlen( temp ) - 1 ] = '\0'; - - // Check if the line starts with a . - if ( temp[ 0 ] == '.' ) - { - char temp2[ 1024 ]; - sprintf( temp2, "%s%s", last, temp ); - strcpy( temp, temp2 ); - } - else if ( strchr( temp, '=' ) ) - { - strcpy( last, temp ); - *( strchr( last, '=' ) ) = '\0'; - } - - // Parse and set the property - if ( strcmp( temp, "" ) && temp[ 0 ] != '#' ) - mlt_properties_parse( this, temp ); - } - - // Close the file - fclose( file ); - } - } - - // Return the pointer - return this; -} - -/** Generate a hash key. - * - * \private \memberof mlt_properties_s - * \param name a string - * \return an integer - */ - -static inline int generate_hash( const char *name ) -{ - int hash = 0; - int i = 1; - while ( *name ) - hash = ( hash + ( i ++ * ( *name ++ & 31 ) ) ) % 199; - return hash; -} - -/** Copy a serializable property to properties list that is mirroring this one. - * - * Special case - when a container (such as fezzik) is protecting another - * producer, we need to ensure that properties are passed through to the - * real producer. - * \private \memberof mlt_properties_s - * \param this a properties list - * \param name the name of the property to copy - */ - -static inline void mlt_properties_do_mirror( mlt_properties this, const char *name ) -{ - property_list *list = this->local; - if ( list->mirror != NULL ) - { - char *value = mlt_properties_get( this, name ); - if ( value != NULL ) - mlt_properties_set( list->mirror, name, value ); - } -} - -/** Increment the reference count. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \return the new reference count - */ - -int mlt_properties_inc_ref( mlt_properties this ) -{ - int result = 0; - if ( this != NULL ) - { - property_list *list = this->local; - pthread_mutex_lock( &list->mutex ); - result = ++ list->ref_count; - pthread_mutex_unlock( &list->mutex ); - } - return result; -} - -/** Decrement the reference count. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \return the new reference count - */ - -int mlt_properties_dec_ref( mlt_properties this ) -{ - int result = 0; - if ( this != NULL ) - { - property_list *list = this->local; - pthread_mutex_lock( &list->mutex ); - result = -- list->ref_count; - pthread_mutex_unlock( &list->mutex ); - } - return result; -} - -/** Get the reference count. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \return the current reference count - */ - -int mlt_properties_ref_count( mlt_properties this ) -{ - if ( this != NULL ) - { - property_list *list = this->local; - return list->ref_count; - } - return 0; -} - -/** Set a properties list to be a mirror copy of another. - * - * Note that this does not copy all existing properties. Rather, you must - * call this before setting the properties that you wish to copy. - * \public \memberof mlt_properties_s - * \param that the properties which will receive copies of the properties as they are set. - * \param this the properties to mirror - */ - -void mlt_properties_mirror( mlt_properties this, mlt_properties that ) -{ - property_list *list = this->local; - list->mirror = that; -} - -/** Copy all serializable properties to another properties list. - * - * \public \memberof mlt_properties_s - * \param this The properties to copy to - * \param that The properties to copy from - * \return false - */ - -int mlt_properties_inherit( mlt_properties this, mlt_properties that ) -{ - int count = mlt_properties_count( that ); - int i = 0; - for ( i = 0; i < count; i ++ ) - { - char *value = mlt_properties_get_value( that, i ); - if ( value != NULL ) - { - char *name = mlt_properties_get_name( that, i ); - mlt_properties_set( this, name, value ); - } - } - return 0; -} - -/** Pass all serializable properties that match a prefix to another properties object - * - * \public \memberof mlt_properties_s - * \param this the properties to copy to - * \param that The properties to copy from - * \param prefix the property names to match (required) - * \return false - */ - -int mlt_properties_pass( mlt_properties this, mlt_properties that, const char *prefix ) -{ - int count = mlt_properties_count( that ); - int length = strlen( prefix ); - int i = 0; - for ( i = 0; i < count; i ++ ) - { - char *name = mlt_properties_get_name( that, i ); - if ( !strncmp( name, prefix, length ) ) - { - char *value = mlt_properties_get_value( that, i ); - if ( value != NULL ) - mlt_properties_set( this, name + length, value ); - } - } - return 0; -} - -/** Locate a property by name. - * - * \private \memberof mlt_properties_s - * \param this a properties list - * \param name the property to lookup by name - * \return the property or NULL for failure - */ - -static inline mlt_property mlt_properties_find( mlt_properties this, const char *name ) -{ - property_list *list = this->local; - mlt_property value = NULL; - int key = generate_hash( name ); - int i = list->hash[ key ] - 1; - - if ( i >= 0 ) - { - // Check if we're hashed - if ( list->count > 0 && - name[ 0 ] == list->name[ i ][ 0 ] && - !strcmp( list->name[ i ], name ) ) - value = list->value[ i ]; - - // Locate the item - for ( i = list->count - 1; value == NULL && i >= 0; i -- ) - if ( name[ 0 ] == list->name[ i ][ 0 ] && !strcmp( list->name[ i ], name ) ) - value = list->value[ i ]; - } - - return value; -} - -/** Add a new property. - * - * \private \memberof mlt_properties_s - * \param this a properties list - * \param name the name of the new property - * \return the new property - */ - -static mlt_property mlt_properties_add( mlt_properties this, const char *name ) -{ - property_list *list = this->local; - int key = generate_hash( name ); - - // Check that we have space and resize if necessary - if ( list->count == list->size ) - { - list->size += 50; - list->name = realloc( list->name, list->size * sizeof( const char * ) ); - list->value = realloc( list->value, list->size * sizeof( mlt_property ) ); - } - - // Assign name/value pair - list->name[ list->count ] = strdup( name ); - list->value[ list->count ] = mlt_property_init( ); - - // Assign to hash table - if ( list->hash[ key ] == 0 ) - list->hash[ key ] = list->count + 1; - - // Return and increment count accordingly - return list->value[ list->count ++ ]; -} - -/** Fetch a property by name and add one if not found. - * - * \private \memberof mlt_properties_s - * \param this a properties list - * \param name the property to lookup or add - * \return the property - */ - -static mlt_property mlt_properties_fetch( mlt_properties this, const char *name ) -{ - // Try to find an existing property first - mlt_property property = mlt_properties_find( this, name ); - - // If it wasn't found, create one - if ( property == NULL ) - property = mlt_properties_add( this, name ); - - // Return the property - return property; -} - -/** Copy a property to another properties list. - * - * \public \memberof mlt_properties_s - * \author Zach - * \param this the properties to copy to - * \param that the properties to copy from - * \param name the name of the property to copy - */ - -void mlt_properties_pass_property( mlt_properties this, mlt_properties that, const char *name ) -{ - // Make sure the source property isn't null. - mlt_property that_prop = mlt_properties_find( that, name ); - if( that_prop == NULL ) - return; - - mlt_property_pass( mlt_properties_fetch( this, name ), that_prop ); -} - -/** Copy all properties specified in a comma-separated list to another properties list. - * - * White space is also a delimiter. - * \public \memberof mlt_properties_s - * \author Zach - * \param this the properties to copy to - * \param that the properties to copy from - * \param list a delimited list of property names - * \return false - */ - - -int mlt_properties_pass_list( mlt_properties this, mlt_properties that, const char *list ) -{ - char *props = strdup( list ); - char *ptr = props; - const char *delim = " ,\t\n"; // Any combination of spaces, commas, tabs, and newlines - int count, done = 0; - - while( !done ) - { - count = strcspn( ptr, delim ); - - if( ptr[count] == '\0' ) - done = 1; - else - ptr[count] = '\0'; // Make it a real string - - mlt_properties_pass_property( this, that, ptr ); - - ptr += count + 1; - ptr += strspn( ptr, delim ); - } - - free( props ); - - return 0; -} - - -/** Set a property to a string. - * - * This makes a copy of the string value you supply. - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to set - * \param value the property's new value - * \return true if error - */ - -int mlt_properties_set( mlt_properties this, const char *name, const char *value ) -{ - int error = 1; - - // Fetch the property to work with - mlt_property property = mlt_properties_fetch( this, name ); - - // Set it if not NULL - if ( property == NULL ) - { - mlt_log( NULL, MLT_LOG_FATAL, "Whoops - %s not found (should never occur)\n", name ); - } - else if ( value == NULL ) - { - error = mlt_property_set_string( property, value ); - mlt_properties_do_mirror( this, name ); - } - else if ( *value != '@' ) - { - error = mlt_property_set_string( property, value ); - mlt_properties_do_mirror( this, name ); - } - else if ( value[ 0 ] == '@' ) - { - double total = 0; - double current = 0; - char id[ 255 ]; - char op = '+'; - - value ++; - - while ( *value != '\0' ) - { - int length = strcspn( value, "+-*/" ); - - // Get the identifier - strncpy( id, value, length ); - id[ length ] = '\0'; - value += length; - - // Determine the value - if ( isdigit( id[ 0 ] ) ) - current = atof( id ); - else - current = mlt_properties_get_double( this, id ); - - // Apply the operation - switch( op ) - { - case '+': - total += current; - break; - case '-': - total -= current; - break; - case '*': - total *= current; - break; - case '/': - total = total / current; - break; - } - - // Get the next op - op = *value != '\0' ? *value ++ : ' '; - } - - error = mlt_property_set_double( property, total ); - mlt_properties_do_mirror( this, name ); - } - - mlt_events_fire( this, "property-changed", name, NULL ); - - return error; -} - -/** Set or default a property to a string. - * - * This makes a copy of the string value you supply. - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to set - * \param value the string value to set or NULL to use the default - * \param def the default string if value is NULL - * \return true if error - */ - -int mlt_properties_set_or_default( mlt_properties this, const char *name, const char *value, const char *def ) -{ - return mlt_properties_set( this, name, value == NULL ? def : value ); -} - -/** Get a string value by name. - * - * Do not free the returned string. It's lifetime is controlled by the property - * and this properties object. - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to get - * \return the property's string value or NULL if it does not exist - */ - -char *mlt_properties_get( mlt_properties this, const char *name ) -{ - mlt_property value = mlt_properties_find( this, name ); - return value == NULL ? NULL : mlt_property_get_string( value ); -} - -/** Get a property name by index. - * - * Do not free the returned string. - * \public \memberof mlt_properties_s - * \param this a properties list - * \param index the numeric index of the property - * \return the name of the property or NULL if index is out of range - */ - -char *mlt_properties_get_name( mlt_properties this, int index ) -{ - property_list *list = this->local; - if ( index >= 0 && index < list->count ) - return list->name[ index ]; - return NULL; -} - -/** Get a property's string value by index. - * - * Do not free the returned string. - * \public \memberof mlt_properties_s - * \param this a properties list - * \param index the numeric index of the property - * \return the property value as a string or NULL if the index is out of range - */ - -char *mlt_properties_get_value( mlt_properties this, int index ) -{ - property_list *list = this->local; - if ( index >= 0 && index < list->count ) - return mlt_property_get_string( list->value[ index ] ); - return NULL; -} - -/** Get a data value by index. - * - * Do not free the returned pointer if you supplied a destructor function when you - * set this property. - * \public \memberof mlt_properties_s - * \param this a properties list - * \param index the numeric index of the property - * \param[out] size the size of the binary data in bytes or NULL if the index is out of range - */ - -void *mlt_properties_get_data_at( mlt_properties this, int index, int *size ) -{ - property_list *list = this->local; - if ( index >= 0 && index < list->count ) - return mlt_property_get_data( list->value[ index ], size ); - return NULL; -} - -/** Return the number of items in the list. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \return the number of property objects - */ - -int mlt_properties_count( mlt_properties this ) -{ - property_list *list = this->local; - return list->count; -} - -/** Set a value by parsing a name=value string. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param namevalue a string containing name and value delimited by '=' - * \return true if there was an error - */ - -int mlt_properties_parse( mlt_properties this, const char *namevalue ) -{ - char *name = strdup( namevalue ); - char *value = NULL; - int error = 0; - char *ptr = strchr( name, '=' ); - - if ( ptr ) - { - *( ptr ++ ) = '\0'; - - if ( *ptr != '\"' ) - { - value = strdup( ptr ); - } - else - { - ptr ++; - value = strdup( ptr ); - if ( value != NULL && value[ strlen( value ) - 1 ] == '\"' ) - value[ strlen( value ) - 1 ] = '\0'; - } - } - else - { - value = strdup( "" ); - } - - error = mlt_properties_set( this, name, value ); - - free( name ); - free( value ); - - return error; -} - -/** Get an integer associated to the name. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to get - * \return The integer value, 0 if not found (which may also be a legitimate value) - */ - -int mlt_properties_get_int( mlt_properties this, const char *name ) -{ - mlt_property value = mlt_properties_find( this, name ); - return value == NULL ? 0 : mlt_property_get_int( value ); -} - -/** Set a property to an integer value. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to set - * \param value the integer - * \return true if error - */ - -int mlt_properties_set_int( mlt_properties this, const char *name, int value ) -{ - int error = 1; - - // Fetch the property to work with - mlt_property property = mlt_properties_fetch( this, name ); - - // Set it if not NULL - if ( property != NULL ) - { - error = mlt_property_set_int( property, value ); - mlt_properties_do_mirror( this, name ); - } - - mlt_events_fire( this, "property-changed", name, NULL ); - - return error; -} - -/** Get a 64-bit integer associated to the name. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to get - * \return the integer value, 0 if not found (which may also be a legitimate value) - */ - -int64_t mlt_properties_get_int64( mlt_properties this, const char *name ) -{ - mlt_property value = mlt_properties_find( this, name ); - return value == NULL ? 0 : mlt_property_get_int64( value ); -} - -/** Set a property to a 64-bit integer value. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to set - * \param value the integer - * \return true if error - */ - -int mlt_properties_set_int64( mlt_properties this, const char *name, int64_t value ) -{ - int error = 1; - - // Fetch the property to work with - mlt_property property = mlt_properties_fetch( this, name ); - - // Set it if not NULL - if ( property != NULL ) - { - error = mlt_property_set_int64( property, value ); - mlt_properties_do_mirror( this, name ); - } - - mlt_events_fire( this, "property-changed", name, NULL ); - - return error; -} - -/** Get a floating point value associated to the name. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to get - * \return the floating point, 0 if not found (which may also be a legitimate value) - */ - -double mlt_properties_get_double( mlt_properties this, const char *name ) -{ - mlt_property value = mlt_properties_find( this, name ); - return value == NULL ? 0 : mlt_property_get_double( value ); -} - -/** Set a property to a floating point value. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to set - * \param value the floating point value - * \return true if error - */ - -int mlt_properties_set_double( mlt_properties this, const char *name, double value ) -{ - int error = 1; - - // Fetch the property to work with - mlt_property property = mlt_properties_fetch( this, name ); - - // Set it if not NULL - if ( property != NULL ) - { - error = mlt_property_set_double( property, value ); - mlt_properties_do_mirror( this, name ); - } - - mlt_events_fire( this, "property-changed", name, NULL ); - - return error; -} - -/** Get a position value associated to the name. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to get - * \return the position, 0 if not found (which may also be a legitimate value) - */ - -mlt_position mlt_properties_get_position( mlt_properties this, const char *name ) -{ - mlt_property value = mlt_properties_find( this, name ); - return value == NULL ? 0 : mlt_property_get_position( value ); -} - -/** Set a property to a position value. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to get - * \param value the position - * \return true if error - */ - -int mlt_properties_set_position( mlt_properties this, const char *name, mlt_position value ) -{ - int error = 1; - - // Fetch the property to work with - mlt_property property = mlt_properties_fetch( this, name ); - - // Set it if not NULL - if ( property != NULL ) - { - error = mlt_property_set_position( property, value ); - mlt_properties_do_mirror( this, name ); - } - - mlt_events_fire( this, "property-changed", name, NULL ); - - return error; -} - -/** Get a binary data value associated to the name. - * - * Do not free the returned pointer if you supplied a destructor function - * when you set this property. - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to get - * \param[out] length The size of the binary data in bytes, if available (often it is not, you should know) - */ - -void *mlt_properties_get_data( mlt_properties this, const char *name, int *length ) -{ - mlt_property value = mlt_properties_find( this, name ); - return value == NULL ? NULL : mlt_property_get_data( value, length ); -} - -/** Store binary data as a property. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param name the property to set - * \param value an opaque pointer to binary data - * \param length the size of the binary data in bytes (optional) - * \param destroy a function to dellacate the binary data when the property is closed (optional) - * \param serialise a function that can serialize the binary data as text (optional) - * \return true if error - */ - -int mlt_properties_set_data( mlt_properties this, const char *name, void *value, int length, mlt_destructor destroy, mlt_serialiser serialise ) -{ - int error = 1; - - // Fetch the property to work with - mlt_property property = mlt_properties_fetch( this, name ); - - // Set it if not NULL - if ( property != NULL ) - error = mlt_property_set_data( property, value, length, destroy, serialise ); - - mlt_events_fire( this, "property-changed", name, NULL ); - - return error; -} - -/** Rename a property. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param source the property to rename - * \param dest the new name - * \return true if the name is already in use - */ - -int mlt_properties_rename( mlt_properties this, const char *source, const char *dest ) -{ - mlt_property value = mlt_properties_find( this, dest ); - - if ( value == NULL ) - { - property_list *list = this->local; - int i = 0; - - // Locate the item - for ( i = 0; i < list->count; i ++ ) - { - if ( !strcmp( list->name[ i ], source ) ) - { - free( list->name[ i ] ); - list->name[ i ] = strdup( dest ); - list->hash[ generate_hash( dest ) ] = i + 1; - break; - } - } - } - - return value != NULL; -} - -/** Dump the properties to a file handle. - * - * \public \memberof mlt_properties_s - * \param this a properties list - * \param output a file handle - */ - -void mlt_properties_dump( mlt_properties this, FILE *output ) -{ - property_list *list = this->local; - int i = 0; - for ( i = 0; i < list->count; i ++ ) - if ( mlt_properties_get( this, list->name[ i ] ) != NULL ) - fprintf( output, "%s=%s\n", list->name[ i ], mlt_properties_get( this, list->name[ i ] ) ); -} - -/** Output the properties to a file handle. - * - * This version includes reference counts and does not put each property on a new line. - * \public \memberof mlt_properties_s - * \param this a properties pointer - * \param title a string to preface the output - * \param output a file handle - */ -void mlt_properties_debug( mlt_properties this, const char *title, FILE *output ) -{ - if ( output == NULL ) output = stderr; - fprintf( output, "%s: ", title ); - if ( this != NULL ) - { - property_list *list = this->local; - int i = 0; - fprintf( output, "[ ref=%d", list->ref_count ); - for ( i = 0; i < list->count; i ++ ) - if ( mlt_properties_get( this, list->name[ i ] ) != NULL ) - fprintf( output, ", %s=%s", list->name[ i ], mlt_properties_get( this, list->name[ i ] ) ); - else - fprintf( output, ", %s=%p", list->name[ i ], mlt_properties_get_data( this, list->name[ i ], NULL ) ); - fprintf( output, " ]" ); - } - fprintf( output, "\n" ); -} - -/** Save the properties to a file by name. - * - * This uses the dump format - one line per property. - * \public \memberof mlt_properties_s - * \param this a properties list - * \param filename the name of a file to create or overwrite - * \return true if there was an error - */ - -int mlt_properties_save( mlt_properties this, const char *filename ) -{ - int error = 1; - FILE *f = fopen( filename, "w" ); - if ( f != NULL ) - { - mlt_properties_dump( this, f ); - fclose( f ); - error = 0; - } - return error; -} - -/* This is a very basic cross platform fnmatch replacement - it will fail in - * many cases, but for the basic *.XXX and YYY*.XXX, it will work ok. - */ - -/** Test whether a filename or pathname matches a shell-style pattern. - * - * \private \memberof mlt_properties_s - * \param wild a string containing a wildcard pattern - * \param file the name of a file to test against - * \return true if the file name matches the wildcard pattern - */ - -static int mlt_fnmatch( const char *wild, const char *file ) -{ - int f = 0; - int w = 0; - - while( f < strlen( file ) && w < strlen( wild ) ) - { - if ( wild[ w ] == '*' ) - { - w ++; - if ( w == strlen( wild ) ) - f = strlen( file ); - while ( f != strlen( file ) && tolower( file[ f ] ) != tolower( wild[ w ] ) ) - f ++; - } - else if ( wild[ w ] == '?' || tolower( file[ f ] ) == tolower( wild[ w ] ) ) - { - f ++; - w ++; - } - else if ( wild[ 0 ] == '*' ) - { - w = 0; - } - else - { - return 0; - } - } - - return strlen( file ) == f && strlen( wild ) == w; -} - -/** Compare the string or serialized value of two properties. - * - * \private \memberof mlt_properties_s - * \param this a property - * \param that a property - * \return < 0 if 'this' less than 'that', 0 if equal, or > 0 if 'this' is greater than 'that' - */ - -static int mlt_compare( const void *this, const void *that ) -{ - return strcmp( mlt_property_get_string( *( const mlt_property * )this ), mlt_property_get_string( *( const mlt_property * )that ) ); -} - -/** Get the contents of a directory. - * - * Obtains an optionally sorted list of the files found in a directory with a specific wild card. - * Entries in the list have a numeric name (running from 0 to count - 1). Only values change - * position if sort is enabled. Designed to be posix compatible (linux, os/x, mingw etc). - * \public \memberof mlt_properties_s - * \param this a properties list - * \param dirname the name of the directory - * \param pattern a wildcard pattern to filter the directory listing - * \param sort Do you want to sort the directory listing? - * \return the number of items in the directory listing - */ - -int mlt_properties_dir_list( mlt_properties this, const char *dirname, const char *pattern, int sort ) -{ - DIR *dir = opendir( dirname ); - - if ( dir ) - { - char key[ 20 ]; - struct dirent *de = readdir( dir ); - char fullname[ 1024 ]; - while( de != NULL ) - { - sprintf( key, "%d", mlt_properties_count( this ) ); - snprintf( fullname, 1024, "%s/%s", dirname, de->d_name ); - if ( pattern == NULL ) - mlt_properties_set( this, key, fullname ); - else if ( de->d_name[ 0 ] != '.' && mlt_fnmatch( pattern, de->d_name ) ) - mlt_properties_set( this, key, fullname ); - de = readdir( dir ); - } - - closedir( dir ); - } - - if ( sort && mlt_properties_count( this ) ) - { - property_list *list = this->local; - qsort( list->value, mlt_properties_count( this ), sizeof( mlt_property ), mlt_compare ); - } - - return mlt_properties_count( this ); -} - -/** Close a properties object. - * - * Deallocates the properties object and everything it contains. - * \public \memberof mlt_properties_s - * \param this a properties object - */ - -void mlt_properties_close( mlt_properties this ) -{ - if ( this != NULL && mlt_properties_dec_ref( this ) <= 0 ) - { - if ( this->close != NULL ) - { - this->close( this->close_object ); - } - else - { - property_list *list = this->local; - int index = 0; - -#if _MLT_PROPERTY_CHECKS_ == 1 - // Show debug info - mlt_properties_debug( this, "Closing", stderr ); -#endif - -#ifdef _MLT_PROPERTY_CHECKS_ - // Increment destroyed count - properties_destroyed ++; - - // Show current stats - these should match when the app is closed - mlt_log( NULL, MLT_LOG_DEBUG, "Created %d, destroyed %d\n", properties_created, properties_destroyed ); -#endif - - // Clean up names and values - for ( index = list->count - 1; index >= 0; index -- ) - { - free( list->name[ index ] ); - mlt_property_close( list->value[ index ] ); - } - - // Clear up the list - pthread_mutex_destroy( &list->mutex ); - free( list->name ); - free( list->value ); - free( list ); - - // Free this now if this has no child - if ( this->child == NULL ) - free( this ); - } - } -} - -/** Determine if the properties list is really just a sequence or ordered list. - * - * \public \memberof mlt_properties_s - * \param properties a properties list - * \return true if all of the property names are numeric (a sequence) - */ - -int mlt_properties_is_sequence( mlt_properties properties ) -{ - int i; - int n = mlt_properties_count( properties ); - for ( i = 0; i < n; i++ ) - if ( ! isdigit( mlt_properties_get_name( properties, i )[0] ) ) - return 0; - return 1; -} - -/** \brief YAML Tiny Parser context structure - * - * YAML is a nifty text format popular in the Ruby world as a cleaner, - * less verbose alternative to XML. See this Wikipedia topic for an overview: - * http://en.wikipedia.org/wiki/YAML - * The YAML specification is at: - * http://yaml.org/ - * YAML::Tiny is a Perl module that specifies a subset of YAML that we are - * using here (for the same reasons): - * http://search.cpan.org/~adamk/YAML-Tiny-1.25/lib/YAML/Tiny.pm - * \private - */ - -struct yaml_parser_context -{ - mlt_deque stack; - unsigned int level; - unsigned int index; - char block; - char *block_name; - unsigned int block_indent; - -}; -typedef struct yaml_parser_context *yaml_parser; - -/** Remove spaces from the left side of a string. - * - * \param s the string to trim - * \return the number of characters removed - */ - -static unsigned int ltrim( char **s ) -{ - unsigned int i = 0; - char *c = *s; - int n = strlen( c ); - for ( i = 0; i < n && *c == ' '; i++, c++ ); - *s = c; - return i; -} - -/** Remove spaces from the right side of a string. - * - * \param s the string to trim - * \return the number of characters removed - */ - -static unsigned int rtrim( char *s ) -{ - int n = strlen( s ); - int i; - for ( i = n; i > 0 && s[i - 1] == ' '; --i ) - s[i - 1] = 0; - return n - i; -} - -/** Parse a line of YAML Tiny. - * - * Adds a property if needed. - * \private \memberof yaml_parser_context - * \param context a YAML Tiny Parser context - * \param namevalue a line of YAML Tiny - * \return true if there was an error - */ - -static int parse_yaml( yaml_parser context, const char *namevalue ) -{ - char *name_ = strdup( namevalue ); - char *name = name_; - char *value = NULL; - int error = 0; - char *ptr = strchr( name, ':' ); - unsigned int indent = ltrim( &name ); - mlt_properties properties = mlt_deque_peek_front( context->stack ); - - // Ascending one more levels in the tree - if ( indent < context->level ) - { - unsigned int i; - unsigned int n = ( context->level - indent ) / 2; - for ( i = 0; i < n; i++ ) - mlt_deque_pop_front( context->stack ); - properties = mlt_deque_peek_front( context->stack ); - context->level = indent; - } - - // Descending a level in the tree - else if ( indent > context->level && context->block == 0 ) - { - context->level = indent; - } - - // If there is a colon that is not part of a block - if ( ptr && ( indent == context->level ) ) - { - // Reset block processing - if ( context->block_name ) - { - free( context->block_name ); - context->block_name = NULL; - context->block = 0; - } - - // Terminate the name and setup the value pointer - *( ptr ++ ) = 0; - - // Trim comment - char *comment = strchr( ptr, '#' ); - if ( comment ) - { - *comment = 0; - } - - // Trim leading and trailing spaces from bare value - ltrim( &ptr ); - rtrim( ptr ); - - // No value means a child - if ( strcmp( ptr, "" ) == 0 ) - { - mlt_properties child = mlt_properties_new(); - mlt_properties_set_data( properties, name, child, 0, - ( mlt_destructor )mlt_properties_close, NULL ); - mlt_deque_push_front( context->stack, child ); - context->index = 0; - free( name_ ); - return error; - } - - // A dash indicates a sequence item - if ( name[0] == '-' ) - { - mlt_properties child = mlt_properties_new(); - char key[20]; - - snprintf( key, sizeof(key), "%d", context->index++ ); - mlt_properties_set_data( properties, key, child, 0, - ( mlt_destructor )mlt_properties_close, NULL ); - mlt_deque_push_front( context->stack, child ); - - name ++; - context->level += ltrim( &name ) + 1; - properties = child; - } - - // Value is quoted - if ( *ptr == '\"' ) - { - ptr ++; - value = strdup( ptr ); - if ( value && value[ strlen( value ) - 1 ] == '\"' ) - value[ strlen( value ) - 1 ] = 0; - } - - // Value is folded or unfolded block - else if ( *ptr == '|' || *ptr == '>' ) - { - context->block = *ptr; - context->block_name = strdup( name ); - context->block_indent = 0; - value = strdup( "" ); - } - - // Bare value - else - { - value = strdup( ptr ); - } - } - - // A list of scalars - else if ( name[0] == '-' ) - { - // Reset block processing - if ( context->block_name ) - { - free( context->block_name ); - context->block_name = NULL; - context->block = 0; - } - - char key[20]; - - snprintf( key, sizeof(key), "%d", context->index++ ); - ptr = name + 1; - - // Trim comment - char *comment = strchr( ptr, '#' ); - if ( comment ) - *comment = 0; - - // Trim leading and trailing spaces from bare value - ltrim( &ptr ); - rtrim( ptr ); - - // Value is quoted - if ( *ptr == '\"' ) - { - ptr ++; - value = strdup( ptr ); - if ( value && value[ strlen( value ) - 1 ] == '\"' ) - value[ strlen( value ) - 1 ] = 0; - } - - // Value is folded or unfolded block - else if ( *ptr == '|' || *ptr == '>' ) - { - context->block = *ptr; - context->block_name = strdup( key ); - context->block_indent = 0; - value = strdup( "" ); - } - - // Bare value - else - { - value = strdup( ptr ); - } - - free( name_ ); - name = name_ = strdup( key ); - } - - // Non-folded block - else if ( context->block == '|' ) - { - if ( context->block_indent == 0 ) - context->block_indent = indent; - if ( indent > context->block_indent ) - name = &name_[ context->block_indent ]; - rtrim( name ); - char *old_value = mlt_properties_get( properties, context->block_name ); - value = calloc( 1, strlen( old_value ) + strlen( name ) + 2 ); - strcpy( value, old_value ); - if ( strcmp( old_value, "" ) ) - strcat( value, "\n" ); - strcat( value, name ); - name = context->block_name; - } - - // Folded block - else if ( context->block == '>' ) - { - ltrim( &name ); - rtrim( name ); - char *old_value = mlt_properties_get( properties, context->block_name ); - - // Blank line (prepended with spaces) is new line - if ( strcmp( name, "" ) == 0 ) - { - value = calloc( 1, strlen( old_value ) + 2 ); - strcat( value, old_value ); - strcat( value, "\n" ); - } - // Concatenate with space - else - { - value = calloc( 1, strlen( old_value ) + strlen( name ) + 2 ); - strcat( value, old_value ); - if ( strcmp( old_value, "" ) && old_value[ strlen( old_value ) - 1 ] != '\n' ) - strcat( value, " " ); - strcat( value, name ); - } - name = context->block_name; - } - - else - { - value = strdup( "" ); - } - - error = mlt_properties_set( properties, name, value ); - - free( name_ ); - free( value ); - - return error; -} - -/** Parse a YAML Tiny file by name. - * - * \public \memberof mlt_properties_s - * \param filename the name of a text file containing YAML Tiny - * \return a new properties list - */ - -mlt_properties mlt_properties_parse_yaml( const char *filename ) -{ - // Construct a standalone properties object - mlt_properties this = mlt_properties_new( ); - - if ( this ) - { - // Open the file - FILE *file = fopen( filename, "r" ); - - // Load contents of file - if ( file ) - { - // Temp string - char temp[ 1024 ]; - char *ptemp = &temp[ 0 ]; - - // Parser context - yaml_parser context = calloc( 1, sizeof( struct yaml_parser_context ) ); - context->stack = mlt_deque_init(); - mlt_deque_push_front( context->stack, this ); - - // Read each string from the file - while( fgets( temp, 1024, file ) ) - { - // Check for end-of-stream - if ( strncmp( ptemp, "...", 3 ) == 0 ) - break; - - // Chomp the string - temp[ strlen( temp ) - 1 ] = '\0'; - - // Skip blank lines, comment lines, and document separator - if ( strcmp( ptemp, "" ) && ptemp[ 0 ] != '#' && strncmp( ptemp, "---", 3 ) - && strncmp( ptemp, "%YAML", 5 ) && strncmp( ptemp, "% YAML", 6 ) ) - parse_yaml( context, temp ); - } - - // Close the file - fclose( file ); - mlt_deque_close( context->stack ); - if ( context->block_name ) - free( context->block_name ); - free( context ); - } - } - - // Return the pointer - return this; -} - -/* - * YAML Tiny Serializer - */ - -/** How many bytes to grow at a time */ -#define STRBUF_GROWTH (1024) - -/** \brief Private to mlt_properties_s, a self-growing buffer for building strings - * \private - */ - -struct strbuf_s -{ - size_t size; - char *string; -}; - -typedef struct strbuf_s *strbuf; - -/** Create a new string buffer - * - * \private \memberof strbuf_s - * \return a new string buffer - */ - -static strbuf strbuf_new( ) -{ - strbuf buffer = calloc( 1, sizeof( struct strbuf_s ) ); - buffer->size = STRBUF_GROWTH; - buffer->string = calloc( 1, buffer->size ); - return buffer; -} - -/** Destroy a string buffer - * - * \private \memberof strbuf_s - * \param buffer the string buffer to close - */ - -static void strbuf_close( strbuf buffer ) -{ - // We do not free buffer->string; strbuf user must save that pointer - // and free it. - if ( buffer ) - free( buffer ); -} - -/** Format a string into a string buffer - * - * A variable number of arguments follows the format string - one for each - * format specifier. - * \private \memberof strbuf_s - * \param buffer the string buffer to write into - * \param format a string that contains text and formatting instructions - * \return the formatted string - */ - -static char *strbuf_printf( strbuf buffer, const char *format, ... ) -{ - while ( buffer->string ) - { - va_list ap; - va_start( ap, format ); - size_t len = strlen( buffer->string ); - size_t remain = buffer->size - len - 1; - int need = vsnprintf( buffer->string + len, remain, format, ap ); - va_end( ap ); - if ( need > -1 && need < remain ) - break; - buffer->string[ len ] = 0; - buffer->size += need + STRBUF_GROWTH; - buffer->string = realloc( buffer->string, buffer->size ); - } - return buffer->string; -} - -/** Indent a line of YAML Tiny. - * - * \private \memberof strbuf_s - * \param output a string buffer - * \param indent the number of spaces to indent - */ - -static inline void indent_yaml( strbuf output, int indent ) -{ - int j; - for ( j = 0; j < indent; j++ ) - strbuf_printf( output, " " ); -} - -/** Convert a line string into a YAML block literal. - * - * \private \memberof strbuf_s - * \param output a string buffer - * \param value the string to format as a block literal - * \param indent the number of spaces to indent - */ - -static void output_yaml_block_literal( strbuf output, const char *value, int indent ) -{ - char *v = strdup( value ); - char *sol = v; - char *eol = strchr( sol, '\n' ); - - while ( eol ) - { - indent_yaml( output, indent ); - *eol = '\0'; - strbuf_printf( output, "%s\n", sol ); - sol = eol + 1; - eol = strchr( sol, '\n' ); - } - indent_yaml( output, indent ); - strbuf_printf( output, "%s\n", sol ); -} - -/** Recursively serialize a properties list into a string buffer as YAML Tiny. - * - * \private \memberof mlt_properties_s - * \param this a properties list - * \param output a string buffer to hold the serialized YAML Tiny - * \param indent the number of spaces to indent (for recursion, initialize to 0) - * \param is_parent_sequence Is 'this' properties list really just a sequence (for recursion, initialize to 0)? - */ - -static void serialise_yaml( mlt_properties this, strbuf output, int indent, int is_parent_sequence ) -{ - property_list *list = this->local; - int i = 0; - - for ( i = 0; i < list->count; i ++ ) - { - // This implementation assumes that all data elements are property lists. - // Unfortunately, we do not have run time type identification. - mlt_properties child = mlt_property_get_data( list->value[ i ], NULL ); - - if ( mlt_properties_is_sequence( this ) ) - { - // Ignore hidden/non-serialisable items - if ( list->name[ i ][ 0 ] != '_' ) - { - // Indicate a sequence item - indent_yaml( output, indent ); - strbuf_printf( output, "- " ); - - // If the value can be represented as a string - const char *value = mlt_properties_get( this, list->name[ i ] ); - if ( value && strcmp( value, "" ) ) - { - // Determine if this is an unfolded block literal - if ( strchr( value, '\n' ) ) - { - strbuf_printf( output, "|\n" ); - output_yaml_block_literal( output, value, indent + strlen( list->name[ i ] ) + strlen( "|" ) ); - } - else - { - strbuf_printf( output, "%s\n", value ); - } - } - } - // Recurse on child - if ( child ) - serialise_yaml( child, output, indent + 2, 1 ); - } - else - { - // Assume this is a normal map-oriented properties list - const char *value = mlt_properties_get( this, list->name[ i ] ); - - // Ignore hidden/non-serialisable items - // If the value can be represented as a string - if ( list->name[ i ][ 0 ] != '_' && value && strcmp( value, "" ) ) - { - if ( is_parent_sequence == 0 ) - indent_yaml( output, indent ); - else - is_parent_sequence = 0; - - // Determine if this is an unfolded block literal - if ( strchr( value, '\n' ) ) - { - strbuf_printf( output, "%s: |\n", list->name[ i ] ); - output_yaml_block_literal( output, value, indent + strlen( list->name[ i ] ) + strlen( ": " ) ); - } - else - { - strbuf_printf( output, "%s: %s\n", list->name[ i ], value ); - } - } - - // Output a child as a map item - if ( child ) - { - indent_yaml( output, indent ); - strbuf_printf( output, "%s:\n", list->name[ i ] ); - - // Recurse on child - serialise_yaml( child, output, indent + 2, 0 ); - } - } - } -} - -/** Serialize a properties list as a string of YAML Tiny. - * - * The caller MUST free the returned string! - * This operates on properties containing properties as a hierarchical data - * structure. - * \public \memberof mlt_properties_s - * \param this a properties list - * \return a string containing YAML Tiny that represents the properties list - */ - -char *mlt_properties_serialise_yaml( mlt_properties this ) -{ - strbuf b = strbuf_new(); - strbuf_printf( b, "---\n" ); - serialise_yaml( this, b, 0, 0 ); - strbuf_printf( b, "...\n" ); - char *ret = b->string; - strbuf_close( b ); - return ret; -} diff --git a/src/framework/mlt_properties.h b/src/framework/mlt_properties.h deleted file mode 100644 index c5e15cc..0000000 --- a/src/framework/mlt_properties.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * \file mlt_properties.h - * \brief Properties class declaration - * \see mlt_properties_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * \author Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_PROPERTIES_H_ -#define _MLT_PROPERTIES_H_ - -#include "mlt_types.h" -#include "mlt_events.h" -#include - -/** \brief Properties class - * - * Properties is a combination list/dictionary of name/::mlt_property pairs. - * It is also a base class for many of the other MLT classes. - */ - -struct mlt_properties_s -{ - void *child; /**< \private the object of a subclass */ - void *local; /**< \private instance object */ - - /** the destructor virtual function */ - mlt_destructor close; - void *close_object; /**< the object supplied to the close virtual function */ -}; - -extern int mlt_properties_init( mlt_properties, void *child ); -extern mlt_properties mlt_properties_new( ); -extern mlt_properties mlt_properties_load( const char *file ); -extern int mlt_properties_inc_ref( mlt_properties self ); -extern int mlt_properties_dec_ref( mlt_properties self ); -extern int mlt_properties_ref_count( mlt_properties self ); -extern void mlt_properties_mirror( mlt_properties self, mlt_properties that ); -extern int mlt_properties_inherit( mlt_properties self, mlt_properties that ); -extern int mlt_properties_pass( mlt_properties self, mlt_properties that, const char *prefix ); -extern void mlt_properties_pass_property( mlt_properties self, mlt_properties that, const char *name ); -extern int mlt_properties_pass_list( mlt_properties self, mlt_properties that, const char *list ); -extern int mlt_properties_set( mlt_properties self, const char *name, const char *value ); -extern int mlt_properties_set_or_default( mlt_properties self, const char *name, const char *value, const char *def ); -extern int mlt_properties_parse( mlt_properties self, const char *namevalue ); -extern char *mlt_properties_get( mlt_properties self, const char *name ); -extern char *mlt_properties_get_name( mlt_properties self, int index ); -extern char *mlt_properties_get_value( mlt_properties self, int index ); -extern void *mlt_properties_get_data_at( mlt_properties self, int index, int *size ); -extern int mlt_properties_get_int( mlt_properties self, const char *name ); -extern int mlt_properties_set_int( mlt_properties self, const char *name, int value ); -extern int64_t mlt_properties_get_int64( mlt_properties self, const char *name ); -extern int mlt_properties_set_int64( mlt_properties self, const char *name, int64_t value ); -extern double mlt_properties_get_double( mlt_properties self, const char *name ); -extern int mlt_properties_set_double( mlt_properties self, const char *name, double value ); -extern mlt_position mlt_properties_get_position( mlt_properties self, const char *name ); -extern int mlt_properties_set_position( mlt_properties self, const char *name, mlt_position value ); -extern int mlt_properties_set_data( mlt_properties self, const char *name, void *value, int length, mlt_destructor, mlt_serialiser ); -extern void *mlt_properties_get_data( mlt_properties self, const char *name, int *length ); -extern int mlt_properties_rename( mlt_properties self, const char *source, const char *dest ); -extern int mlt_properties_count( mlt_properties self ); -extern void mlt_properties_dump( mlt_properties self, FILE *output ); -extern void mlt_properties_debug( mlt_properties self, const char *title, FILE *output ); -extern int mlt_properties_save( mlt_properties, const char * ); -extern int mlt_properties_dir_list( mlt_properties, const char *, const char *, int ); -extern void mlt_properties_close( mlt_properties self ); -extern int mlt_properties_is_sequence( mlt_properties self ); -extern mlt_properties mlt_properties_parse_yaml( const char *file ); -extern char *mlt_properties_serialise_yaml( mlt_properties self ); - -#endif diff --git a/src/framework/mlt_property.c b/src/framework/mlt_property.c deleted file mode 100644 index 7cbb681..0000000 --- a/src/framework/mlt_property.c +++ /dev/null @@ -1,512 +0,0 @@ -/** - * \file mlt_property.c - * \brief Property class definition - * \see mlt_property_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_property.h" - -#include -#include -#include - - -/** Bit pattern used internally to indicated representations available. -*/ - -typedef enum -{ - mlt_prop_none = 0, //!< not set - mlt_prop_int = 1, //!< set as an integer - mlt_prop_string = 2, //!< set as string or already converted to string - mlt_prop_position = 4,//!< set as a position - mlt_prop_double = 8, //!< set as a floating point - mlt_prop_data = 16, //!< set as opaque binary - mlt_prop_int64 = 32 //!< set as a 64-bit integer -} -mlt_property_type; - -/** \brief Property class - * - * A property is like a variant or dynamic type. They are used for many things - * in MLT, but in particular they are the parameter mechanism for the plugins. - */ - -struct mlt_property_s -{ - /// Stores a bit pattern of types available for this property - mlt_property_type types; - - /// Atomic type handling - int prop_int; - mlt_position prop_position; - double prop_double; - int64_t prop_int64; - - /// String handling - char *prop_string; - - /// Generic type handling - void *data; - int length; - mlt_destructor destructor; - mlt_serialiser serialiser; -}; - -/** Construct a property and initialize it - * \public \memberof mlt_property_s - */ - -mlt_property mlt_property_init( ) -{ - mlt_property this = malloc( sizeof( struct mlt_property_s ) ); - if ( this != NULL ) - { - this->types = 0; - this->prop_int = 0; - this->prop_position = 0; - this->prop_double = 0; - this->prop_int64 = 0; - this->prop_string = NULL; - this->data = NULL; - this->length = 0; - this->destructor = NULL; - this->serialiser = NULL; - } - return this; -} - -/** Clear (0/null) a property. - * - * Frees up any associated resources in the process. - * \private \memberof mlt_property_s - * \param this a property - */ - -static inline void mlt_property_clear( mlt_property this ) -{ - // Special case data handling - if ( this->types & mlt_prop_data && this->destructor != NULL ) - this->destructor( this->data ); - - // Special case string handling - if ( this->types & mlt_prop_string ) - free( this->prop_string ); - - // Wipe stuff - this->types = 0; - this->prop_int = 0; - this->prop_position = 0; - this->prop_double = 0; - this->prop_int64 = 0; - this->prop_string = NULL; - this->data = NULL; - this->length = 0; - this->destructor = NULL; - this->serialiser = NULL; -} - -/** Set the property to an integer value. - * - * \public \memberof mlt_property_s - * \param this a property - * \param value an integer - * \return false - */ - -int mlt_property_set_int( mlt_property this, int value ) -{ - mlt_property_clear( this ); - this->types = mlt_prop_int; - this->prop_int = value; - return 0; -} - -/** Set the property to a floating point value. - * - * \public \memberof mlt_property_s - * \param this a property - * \param value a double precision floating point value - * \return false - */ - -int mlt_property_set_double( mlt_property this, double value ) -{ - mlt_property_clear( this ); - this->types = mlt_prop_double; - this->prop_double = value; - return 0; -} - -/** Set the property to a position value. - * - * Position is a relative time value in frame units. - * \public \memberof mlt_property_s - * \param this a property - * \param value a position value - * \return false - */ - -int mlt_property_set_position( mlt_property this, mlt_position value ) -{ - mlt_property_clear( this ); - this->types = mlt_prop_position; - this->prop_position = value; - return 0; -} - -/** Set the property to a string value. - * - * This makes a copy of the string you supply so you do not need to track - * a new reference to it. - * \public \memberof mlt_property_s - * \param this a property - * \param value the string to copy to the property - * \return true if it failed - */ - -int mlt_property_set_string( mlt_property this, const char *value ) -{ - if ( value != this->prop_string ) - { - mlt_property_clear( this ); - this->types = mlt_prop_string; - if ( value != NULL ) - this->prop_string = strdup( value ); - } - else - { - this->types = mlt_prop_string; - } - return this->prop_string == NULL; -} - -/** Set the property to a 64-bit integer value. - * - * \public \memberof mlt_property_s - * \param this a property - * \param value a 64-bit integer - * \return false - */ - -int mlt_property_set_int64( mlt_property this, int64_t value ) -{ - mlt_property_clear( this ); - this->types = mlt_prop_int64; - this->prop_int64 = value; - return 0; -} - -/** Set a property to an opaque binary value. - * - * This does not make a copy of the data. You can use a Properties object - * with its reference tracking and the destructor function to control - * the lifetime of the data. Otherwise, pass NULL for the destructor - * function and control the lifetime yourself. - * \public \memberof mlt_property_s - * \param this a property - * \param value an opaque pointer - * \param length the number of bytes pointed to by value (optional) - * \param destructor a function to use to destroy this binary data (optional, assuming you manage the resource) - * \param serialiser a function to use to convert this binary data to a string (optional) - * \return false - */ - -int mlt_property_set_data( mlt_property this, void *value, int length, mlt_destructor destructor, mlt_serialiser serialiser ) -{ - if ( this->data == value ) - this->destructor = NULL; - mlt_property_clear( this ); - this->types = mlt_prop_data; - this->data = value; - this->length = length; - this->destructor = destructor; - this->serialiser = serialiser; - return 0; -} - -/** Convert a base 10 or base 16 string to an integer. - * - * The string must begin with '0x' to be interpreted as hexadecimal. - * Otherwise, it is interpreted as base 10. - * If the string begins with '#' it is interpreted as a hexadecimal color value - * in the form RRGGBB or AARRGGBB. Color values that begin with '0x' are - * always in the form RRGGBBAA where the alpha components are not optional. - * Applications and services should expect the binary color value in bytes to - * be in the following order: RGBA. This means they will have to cast the int - * to an unsigned int. This is especially important when they need to shift - * right to obtain RGB without alpha in order to make it do a logical instead - * of arithmetic shift. - * - * \private \memberof mlt_property_s - * \param value a string to convert - * \return the resultant integer - */ -static inline int mlt_property_atoi( const char *value ) -{ - if ( value == NULL ) - return 0; - // Parse a hex color value as #RRGGBB or #AARRGGBB. - if ( value[0] == '#' ) - { - unsigned int rgb = strtoul( value + 1, NULL, 16 ); - unsigned int alpha = ( strlen( value ) > 7 ) ? ( rgb >> 24 ) : 0xff; - return ( rgb << 8 ) | alpha; - } - // Do hex and decimal explicitly to avoid decimal value with leading zeros - // interpreted as octal. - else if ( value[0] == '0' && value[1] == 'x' ) - { - return strtoul( value + 2, NULL, 16 ); - } - else - { - return strtol( value, NULL, 10 ); - } -} - -/** Get the property as an integer. - * - * \public \memberof mlt_property_s - * \param this a property - * \return an integer value - */ - -int mlt_property_get_int( mlt_property this ) -{ - if ( this->types & mlt_prop_int ) - return this->prop_int; - else if ( this->types & mlt_prop_double ) - return ( int )this->prop_double; - else if ( this->types & mlt_prop_position ) - return ( int )this->prop_position; - else if ( this->types & mlt_prop_int64 ) - return ( int )this->prop_int64; - else if ( this->types & mlt_prop_string ) - return mlt_property_atoi( this->prop_string ); - return 0; -} - -/** Get the property as a floating point. - * - * \public \memberof mlt_property_s - * \param this a property - * \return a floating point value - */ - -double mlt_property_get_double( mlt_property this ) -{ - if ( this->types & mlt_prop_double ) - return this->prop_double; - else if ( this->types & mlt_prop_int ) - return ( double )this->prop_int; - else if ( this->types & mlt_prop_position ) - return ( double )this->prop_position; - else if ( this->types & mlt_prop_int64 ) - return ( double )this->prop_int64; - else if ( this->types & mlt_prop_string ) - return atof( this->prop_string ); - return 0; -} - -/** Get the property as a position. - * - * A position is an offset time in terms of frame units. - * \public \memberof mlt_property_s - * \param this a property - * \return the position in frames - */ - -mlt_position mlt_property_get_position( mlt_property this ) -{ - if ( this->types & mlt_prop_position ) - return this->prop_position; - else if ( this->types & mlt_prop_int ) - return ( mlt_position )this->prop_int; - else if ( this->types & mlt_prop_double ) - return ( mlt_position )this->prop_double; - else if ( this->types & mlt_prop_int64 ) - return ( mlt_position )this->prop_int64; - else if ( this->types & mlt_prop_string ) - return ( mlt_position )atol( this->prop_string ); - return 0; -} - -/** Convert a string to a 64-bit integer. - * - * If the string begins with '0x' it is interpreted as a hexadecimal value. - * \private \memberof mlt_property_s - * \param value a string - * \return a 64-bit integer - */ - -static inline int64_t mlt_property_atoll( const char *value ) -{ - if ( value == NULL ) - return 0; - else if ( value[0] == '0' && value[1] == 'x' ) - return strtoll( value + 2, NULL, 16 ); - else - return strtoll( value, NULL, 10 ); -} - -/** Get the property as a signed integer. - * - * \public \memberof mlt_property_s - * \param this a property - * \return a 64-bit integer - */ - -int64_t mlt_property_get_int64( mlt_property this ) -{ - if ( this->types & mlt_prop_int64 ) - return this->prop_int64; - else if ( this->types & mlt_prop_int ) - return ( int64_t )this->prop_int; - else if ( this->types & mlt_prop_double ) - return ( int64_t )this->prop_double; - else if ( this->types & mlt_prop_position ) - return ( int64_t )this->prop_position; - else if ( this->types & mlt_prop_string ) - return mlt_property_atoll( this->prop_string ); - return 0; -} - -/** Get the property as a string. - * - * The caller is not responsible for deallocating the returned string! - * The string is deallocated when the Property is closed. - * This tries its hardest to convert the property to string including using - * a serialization function for binary data, if supplied. - * \public \memberof mlt_property_s - * \param this a property - * \return a string representation of the property or NULL if failed - */ - -char *mlt_property_get_string( mlt_property this ) -{ - // Construct a string if need be - if ( ! ( this->types & mlt_prop_string ) ) - { - if ( this->types & mlt_prop_int ) - { - this->types |= mlt_prop_string; - this->prop_string = malloc( 32 ); - sprintf( this->prop_string, "%d", this->prop_int ); - } - else if ( this->types & mlt_prop_double ) - { - this->types |= mlt_prop_string; - this->prop_string = malloc( 32 ); - sprintf( this->prop_string, "%f", this->prop_double ); - } - else if ( this->types & mlt_prop_position ) - { - this->types |= mlt_prop_string; - this->prop_string = malloc( 32 ); - sprintf( this->prop_string, "%d", (int)this->prop_position ); /* I don't know if this is wanted. -Zach */ - } - else if ( this->types & mlt_prop_int64 ) - { - this->types |= mlt_prop_string; - this->prop_string = malloc( 32 ); - sprintf( this->prop_string, "%lld", (long long int)this->prop_int64 ); - } - else if ( this->types & mlt_prop_data && this->serialiser != NULL ) - { - this->types |= mlt_prop_string; - this->prop_string = this->serialiser( this->data, this->length ); - } - } - - // Return the string (may be NULL) - return this->prop_string; -} - -/** Get the binary data from a property. - * - * This only works if you previously put binary data into the property. - * This does not return a copy of the data; it returns a pointer to it. - * If you supplied a destructor function when setting the binary data, - * the destructor is used when the Property is closed to free the memory. - * Therefore, only free the returned pointer if you did not supply a - * destructor function. - * \public \memberof mlt_property_s - * \param this a property - * \param[out] length the size of the binary object in bytes (optional) - * \return an opaque data pointer or NULL if not available - */ - -void *mlt_property_get_data( mlt_property this, int *length ) -{ - // Assign length if not NULL - if ( length != NULL ) - *length = this->length; - - // Return the data (note: there is no conversion here) - return this->data; -} - -/** Destroy a property and free all related resources. - * - * \public \memberof mlt_property_s - * \param this a property - */ - -void mlt_property_close( mlt_property this ) -{ - mlt_property_clear( this ); - free( this ); -} - -/** Copy a property. - * - * A Property holding binary data only copies the data if a serialiser - * function was supplied when you set the Property. - * \public \memberof mlt_property_s - * \author Zach - * \param this a property - * \param that another property - */ -void mlt_property_pass( mlt_property this, mlt_property that ) -{ - mlt_property_clear( this ); - - this->types = that->types; - - if ( this->types & mlt_prop_int64 ) - this->prop_int64 = that->prop_int64; - else if ( this->types & mlt_prop_int ) - this->prop_int = that->prop_int; - else if ( this->types & mlt_prop_double ) - this->prop_double = that->prop_double; - else if ( this->types & mlt_prop_position ) - this->prop_position = that->prop_position; - else if ( this->types & mlt_prop_string ) - { - if ( that->prop_string != NULL ) - this->prop_string = strdup( that->prop_string ); - } - else if ( this->types & mlt_prop_data && this->serialiser != NULL ) - { - this->types = mlt_prop_string; - this->prop_string = this->serialiser( this->data, this->length ); - } -} diff --git a/src/framework/mlt_property.h b/src/framework/mlt_property.h deleted file mode 100644 index f33aa88..0000000 --- a/src/framework/mlt_property.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * \file mlt_property.h - * \brief Property class declaration - * \see mlt_property_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_PROPERTY_H_ -#define _MLT_PROPERTY_H_ - -#include "mlt_types.h" - -extern mlt_property mlt_property_init( ); -extern int mlt_property_set_int( mlt_property self, int value ); -extern int mlt_property_set_double( mlt_property self, double value ); -extern int mlt_property_set_position( mlt_property self, mlt_position value ); -extern int mlt_property_set_int64( mlt_property self, int64_t value ); -extern int mlt_property_set_string( mlt_property self, const char *value ); -extern int mlt_property_set_data( mlt_property self, void *value, int length, mlt_destructor destructor, mlt_serialiser serialiser ); -extern int mlt_property_get_int( mlt_property self ); -extern double mlt_property_get_double( mlt_property self ); -extern mlt_position mlt_property_get_position( mlt_property self ); -extern int64_t mlt_property_get_int64( mlt_property self ); -extern char *mlt_property_get_string( mlt_property self ); -extern void *mlt_property_get_data( mlt_property self, int *length ); -extern void mlt_property_close( mlt_property self ); - -extern void mlt_property_pass( mlt_property this, mlt_property that ); - -#endif diff --git a/src/framework/mlt_repository.c b/src/framework/mlt_repository.c deleted file mode 100644 index c843ecb..0000000 --- a/src/framework/mlt_repository.c +++ /dev/null @@ -1,428 +0,0 @@ -/** - * \file mlt_repository.c - * \brief provides a map between service and shared objects - * \see mlt_repository_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * \author Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_repository.h" -#include "mlt_properties.h" -#include "mlt_tokeniser.h" -#include "mlt_log.h" - -#include -#include -#include -#include - -/** \brief Repository class - * - * The Repository is a collection of plugin modules and their services and service metadata. - * - * \extends mlt_properties_s - * \properties \p language a cached list of user locales - */ - -struct mlt_repository_s -{ - struct mlt_properties_s parent; /// a list of object files - mlt_properties consumers; /// a list of entry points for consumers - mlt_properties filters; /// a list of entry points for filters - mlt_properties producers; /// a list of entry points for producers - mlt_properties transitions; /// a list of entry points for transitions -}; - -/** Construct a new repository. - * - * \public \memberof mlt_repository_s - * \param directory the full path of a directory from which to read modules - * \return a new repository or NULL if failed - */ - -mlt_repository mlt_repository_init( const char *directory ) -{ - // Safety check - if ( directory == NULL || strcmp( directory, "" ) == 0 ) - return NULL; - - // Construct the repository - mlt_repository this = calloc( sizeof( struct mlt_repository_s ), 1 ); - mlt_properties_init( &this->parent, this ); - this->consumers = mlt_properties_new(); - this->filters = mlt_properties_new(); - this->producers = mlt_properties_new(); - this->transitions = mlt_properties_new(); - - // Get the directory list - mlt_properties dir = mlt_properties_new(); - int count = mlt_properties_dir_list( dir, directory, NULL, 0 ); - int i; - - // Iterate over files - for ( i = 0; i < count; i++ ) - { - int flags = RTLD_NOW; - const char *object_name = mlt_properties_get_value( dir, i); - - // Very temporary hack to allow the quicktime plugins to work - // TODO: extend repository to allow this to be used on a case by case basis - if ( strstr( object_name, "libmltkino" ) ) - flags |= RTLD_GLOBAL; - - // Open the shared object - void *object = dlopen( object_name, flags ); - if ( object != NULL ) - { - // Get the registration function - mlt_repository_callback symbol_ptr = dlsym( object, "mlt_register" ); - - // Call the registration function - if ( symbol_ptr != NULL ) - { - symbol_ptr( this ); - - // Register the object file for closure - mlt_properties_set_data( &this->parent, object_name, object, 0, ( mlt_destructor )dlclose, NULL ); - } - else - { - dlclose( object ); - } - } - else if ( strstr( object_name, "libmlt" ) ) - { - mlt_log( NULL, MLT_LOG_WARNING, "%s: failed to dlopen %s\n (%s)\n", __FUNCTION__, object_name, dlerror() ); - } - } - - mlt_properties_close( dir ); - - return this; -} - -/** Create a properties list for a service holding a function pointer to its constructor function. - * - * \private \memberof mlt_repository_s - * \param symbol a pointer to a function that can create the service. - * \return a properties list - */ - -static mlt_properties new_service( void *symbol ) -{ - mlt_properties properties = mlt_properties_new(); - mlt_properties_set_data( properties, "symbol", symbol, 0, NULL, NULL ); - return properties; -} - -/** Register a service with the repository. - * - * Typically, this is invoked by a module within its mlt_register(). - * - * \public \memberof mlt_repository_s - * \param this a repository - * \param service_type a service class - * \param service the name of a service - * \param symbol a pointer to a function to create the service - */ - -void mlt_repository_register( mlt_repository this, mlt_service_type service_type, const char *service, mlt_register_callback symbol ) -{ - // Add the entry point to the corresponding service list - switch ( service_type ) - { - case consumer_type: - mlt_properties_set_data( this->consumers, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); - break; - case filter_type: - mlt_properties_set_data( this->filters, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); - break; - case producer_type: - mlt_properties_set_data( this->producers, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); - break; - case transition_type: - mlt_properties_set_data( this->transitions, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); - break; - default: - break; - } -} - -/** Get the repository properties for particular service class. - * - * \private \memberof mlt_repository_s - * \param this a repository - * \param type a service class - * \param service the name of a service - * \return a properties list or NULL if error - */ - -static mlt_properties get_service_properties( mlt_repository this, mlt_service_type type, const char *service ) -{ - mlt_properties service_properties = NULL; - - // Get the entry point from the corresponding service list - switch ( type ) - { - case consumer_type: - service_properties = mlt_properties_get_data( this->consumers, service, NULL ); - break; - case filter_type: - service_properties = mlt_properties_get_data( this->filters, service, NULL ); - break; - case producer_type: - service_properties = mlt_properties_get_data( this->producers, service, NULL ); - break; - case transition_type: - service_properties = mlt_properties_get_data( this->transitions, service, NULL ); - break; - default: - break; - } - return service_properties; -} - -/** Construct a new instance of a service. - * - * \public \memberof mlt_repository_s - * \param this a repository - * \param profile a \p mlt_profile to give the service - * \param type a service class - * \param service the name of the service - * \param input an optional argument to the service constructor - */ - -void *mlt_repository_create( mlt_repository this, mlt_profile profile, mlt_service_type type, const char *service, const void *input ) -{ - mlt_properties properties = get_service_properties( this, type, service ); - if ( properties != NULL ) - { - mlt_register_callback symbol_ptr = mlt_properties_get_data( properties, "symbol", NULL ); - - // Construct the service - return ( symbol_ptr != NULL ) ? symbol_ptr( profile, type, service, input ) : NULL; - } - return NULL; -} - -/** Destroy a repository and free its resources. - * - * \public \memberof mlt_repository_s - * \param this a repository - */ - -void mlt_repository_close( mlt_repository this ) -{ - mlt_properties_close( this->consumers ); - mlt_properties_close( this->filters ); - mlt_properties_close( this->producers ); - mlt_properties_close( this->transitions ); - mlt_properties_close( &this->parent ); - free( this ); -} - -/** Get the list of registered consumers. - * - * \public \memberof mlt_repository_s - * \param self a repository - * \return a properties list containing all of the consumers - */ - -mlt_properties mlt_repository_consumers( mlt_repository self ) -{ - return self->consumers; -} - -/** Get the list of registered filters. - * - * \public \memberof mlt_repository_s - * \param self a repository - * \return a properties list of all of the filters - */ - -mlt_properties mlt_repository_filters( mlt_repository self ) -{ - return self->filters; -} - -/** Get the list of registered producers. - * - * \public \memberof mlt_repository_s - * \param self a repository - * \return a properties list of all of the producers - */ - -mlt_properties mlt_repository_producers( mlt_repository self ) -{ - return self->producers; -} - -/** Get the list of registered transitions. - * - * \public \memberof mlt_repository_s - * \param self a repository - * \return a properties list of all of the transitions - */ - -mlt_properties mlt_repository_transitions( mlt_repository self ) -{ - return self->transitions; -} - -/** Register the metadata for a service. - * - * IMPORTANT: mlt_repository will take responsibility for deallocating the metadata properties - * that you supply! - * - * \public \memberof mlt_repository_s - * \param self a repository - * \param type a service class - * \param service the name of a service - * \param callback the pointer to a function that can supply metadata - * \param callback_data an opaque user data pointer to be supplied on the callback - */ - -void mlt_repository_register_metadata( mlt_repository self, mlt_service_type type, const char *service, mlt_metadata_callback callback, void *callback_data ) -{ - mlt_properties service_properties = get_service_properties( self, type, service ); - mlt_properties_set_data( service_properties, "metadata_cb", callback, 0, NULL, NULL ); - mlt_properties_set_data( service_properties, "metadata_cb_data", callback_data, 0, NULL, NULL ); -} - -/** Get the metadata about a service. - * - * Returns NULL if service or its metadata are unavailable. - * - * \public \memberof mlt_repository_s - * \param self a repository - * \param type a service class - * \param service the name of a service - * \return the service metadata as a structured properties list - */ - -mlt_properties mlt_repository_metadata( mlt_repository self, mlt_service_type type, const char *service ) -{ - mlt_properties metadata = NULL; - mlt_properties properties = get_service_properties( self, type, service ); - - // If this is a valid service - if ( properties ) - { - // Lookup cached metadata - metadata = mlt_properties_get_data( properties, "metadata", NULL ); - if ( ! metadata ) - { - // Not cached, so get the registered metadata callback function - mlt_metadata_callback callback = mlt_properties_get_data( properties, "metadata_cb", NULL ); - - // If a metadata callback function is registered - if ( callback ) - { - // Fetch the callback data arg - void *data = mlt_properties_get_data( properties, "metadata_cb_data", NULL ); - - // Fetch the metadata through the callback - metadata = callback( type, service, data ); - - // Cache the metadata - if ( metadata ) - // Include dellocation and serialisation - mlt_properties_set_data( properties, "metadata", metadata, 0, ( mlt_destructor )mlt_properties_close, ( mlt_serialiser )mlt_properties_serialise_yaml ); - } - } - } - return metadata; -} - -/** Try to determine the locale from some commonly used environment variables. - * - * \private \memberof mlt_repository_s - * \return a string containing the locale id or NULL if unknown - */ - -static char *getenv_locale() -{ - char *s = getenv( "LANGUAGE" ); - if ( s && s[0] ) - return s; - s = getenv( "LC_ALL" ); - if ( s && s[0] ) - return s; - s = getenv( "LC_MESSAGES" ); - if ( s && s[0] ) - return s; - s = getenv( "LANG" ); - if ( s && s[0] ) - return s; - return NULL; -} - -/** Return a list of user-preferred language codes taken from environment variables. - * - * A module should use this to locate a localized YAML Tiny file from which to build - * its metadata strucutured properties. - * - * \public \memberof mlt_repository_s - * \param self a repository - * \return a properties list that is a list (not a map) of locales, defaults to "en" if not - * overridden by environment variables, in order: LANGUAGE, LC_ALL, LC_MESSAGES, LANG - */ - -mlt_properties mlt_repository_languages( mlt_repository self ) -{ - mlt_properties languages = mlt_properties_get_data( &self->parent, "languages", NULL ); - if ( languages ) - return languages; - - languages = mlt_properties_new(); - char *locale = getenv_locale(); - if ( locale ) - { - locale = strdup( locale ); - mlt_tokeniser tokeniser = mlt_tokeniser_init(); - int count = mlt_tokeniser_parse_new( tokeniser, locale, ":" ); - if ( count ) - { - int i; - for ( i = 0; i < count; i++ ) - { - char *locale = mlt_tokeniser_get_string( tokeniser, i ); - if ( strcmp( locale, "C" ) == 0 || strcmp( locale, "POSIX" ) == 0 ) - locale = "en"; - else if ( strlen( locale ) > 2 ) - locale[2] = 0; - char string[21]; - snprintf( string, sizeof(string), "%d", i ); - mlt_properties_set( languages, string, locale ); - } - } - else - { - mlt_properties_set( languages, "0", "en" ); - } - free( locale ); - mlt_tokeniser_close( tokeniser ); - } - else - { - mlt_properties_set( languages, "0", "en" ); - } - mlt_properties_set_data( &self->parent, "languages", languages, 0, ( mlt_destructor )mlt_properties_close, NULL ); - return languages; -} diff --git a/src/framework/mlt_repository.h b/src/framework/mlt_repository.h deleted file mode 100644 index a653b49..0000000 --- a/src/framework/mlt_repository.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * \file mlt_repository.h - * \brief provides a map between service and shared objects - * \see mlt_repository_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * \author Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_REPOSITORY_H_ -#define _MLT_REPOSITORY_H_ - -#include "mlt_types.h" -#include "mlt_profile.h" - -/** This callback is the main entry point into a module, which must be exported - * with the symbol "mlt_register". - * - * Inside the callback, the module registers the additional callbacks below. - */ - -typedef void ( *mlt_repository_callback )( mlt_repository ); - -/** The callback function that modules implement to construct a service. - */ - -typedef void *( *mlt_register_callback )( mlt_profile, mlt_service_type, const char * /* service name */, const void * /* arg */ ); - -/** The callback function that modules implement to supply metadata as a properties list. - */ - -typedef mlt_properties ( *mlt_metadata_callback )( mlt_service_type, const char * /* service name */, void * /* callback_data */ ); - -/** A convenience macro to create an entry point for service registration. */ -#define MLT_REPOSITORY void mlt_register( mlt_repository repository ) - -/** A convenience macro to a register service in a more declarative manner. */ -#define MLT_REGISTER( type, service, symbol ) ( mlt_repository_register( repository, (type), (service), ( mlt_register_callback )(symbol) ) ) - -/** A convenience macro to a register metadata in a more declarative manner. */ -#define MLT_REGISTER_METADATA( type, service, callback, data ) ( mlt_repository_register_metadata( repository, (type), (service), ( mlt_metadata_callback )(callback), (data) ) ) - -extern mlt_repository mlt_repository_init( const char *directory ); -extern void mlt_repository_register( mlt_repository self, mlt_service_type service_type, const char *service, mlt_register_callback ); -extern void *mlt_repository_create( mlt_repository self, mlt_profile profile, mlt_service_type type, const char *service, const void *arg ); -extern void mlt_repository_close( mlt_repository self ); -extern mlt_properties mlt_repository_consumers( mlt_repository self ); -extern mlt_properties mlt_repository_filters( mlt_repository self ); -extern mlt_properties mlt_repository_producers( mlt_repository self ); -extern mlt_properties mlt_repository_transitions( mlt_repository self ); -extern void mlt_repository_register_metadata( mlt_repository self, mlt_service_type type, const char *service, mlt_metadata_callback, void *callback_data ); -extern mlt_properties mlt_repository_metadata( mlt_repository self, mlt_service_type type, const char *service ); -extern mlt_properties mlt_repository_languages( mlt_repository self ); - -#endif - diff --git a/src/framework/mlt_service.c b/src/framework/mlt_service.c deleted file mode 100644 index b5e8f82..0000000 --- a/src/framework/mlt_service.c +++ /dev/null @@ -1,738 +0,0 @@ -/** - * \file mlt_service.c - * \brief interface definition for all service classes - * \see mlt_service_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_service.h" -#include "mlt_filter.h" -#include "mlt_frame.h" -#include "mlt_cache.h" -#include "mlt_factory.h" -#include "mlt_log.h" - -#include -#include -#include -#include - - -/* IMPORTANT NOTES - - The base service implements a null frame producing service - as such, - it is functional without extension and will produce test cards frames - and PAL sized audio frames. - - PLEASE DO NOT CHANGE THIS BEHAVIOUR!!! OVERRIDE THE METHODS THAT - CONTROL THIS IN EXTENDING CLASSES. -*/ - -/** \brief private service definition */ - -typedef struct -{ - int size; - int count; - mlt_service *in; - mlt_service out; - int filter_count; - int filter_size; - mlt_filter *filters; - pthread_mutex_t mutex; -} -mlt_service_base; - -/* Private methods - */ - -static void mlt_service_disconnect( mlt_service this ); -static void mlt_service_connect( mlt_service this, mlt_service that ); -static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int index ); -static void mlt_service_property_changed( mlt_listener, mlt_properties owner, mlt_service this, void **args ); -static void purge_cache( mlt_service self ); - -/** Initialize a service. - * - * \public \memberof mlt_service_s - * \param this the service structure to initialize - * \param child pointer to the child object for the subclass - * \return true if there was an error - */ - -int mlt_service_init( mlt_service this, void *child ) -{ - int error = 0; - - // Initialise everything to NULL - memset( this, 0, sizeof( struct mlt_service_s ) ); - - // Assign the child - this->child = child; - - // Generate local space - this->local = calloc( sizeof( mlt_service_base ), 1 ); - - // Associate the methods - this->get_frame = service_get_frame; - - // Initialise the properties - error = mlt_properties_init( &this->parent, this ); - if ( error == 0 ) - { - this->parent.close = ( mlt_destructor )mlt_service_close; - this->parent.close_object = this; - - mlt_events_init( &this->parent ); - mlt_events_register( &this->parent, "service-changed", NULL ); - mlt_events_register( &this->parent, "property-changed", ( mlt_transmitter )mlt_service_property_changed ); - pthread_mutex_init( &( ( mlt_service_base * )this->local )->mutex, NULL ); - } - - return error; -} - -/** The transmitter for property changes. - * - * Invokes the listener. - * - * \private \memberof mlt_service_s - * \param listener a function pointer that will be invoked - * \param owner a properties list that will be passed to \p listener - * \param this a service that will be passed to \p listener - * \param args an array of pointers - the first entry is passed as a string to \p listener - */ - -static void mlt_service_property_changed( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ) -{ - if ( listener != NULL ) - listener( owner, this, ( char * )args[ 0 ] ); -} - -/** Acquire a mutual exclusion lock on this service. - * - * \public \memberof mlt_service_s - * \param this the service to lock - */ - -void mlt_service_lock( mlt_service this ) -{ - if ( this != NULL ) - pthread_mutex_lock( &( ( mlt_service_base * )this->local )->mutex ); -} - -/** Release a mutual exclusion lock on this service. - * - * \public \memberof mlt_service_s - * \param this the service to unlock - */ - -void mlt_service_unlock( mlt_service this ) -{ - if ( this != NULL ) - pthread_mutex_unlock( &( ( mlt_service_base * )this->local )->mutex ); -} - -/** Identify the subclass of the service. - * - * \public \memberof mlt_service_s - * \param this a service - * \return the subclass - */ - -mlt_service_type mlt_service_identify( mlt_service this ) -{ - mlt_service_type type = invalid_type; - if ( this != NULL ) - { - mlt_properties properties = MLT_SERVICE_PROPERTIES( this ); - char *mlt_type = mlt_properties_get( properties, "mlt_type" ); - char *resource = mlt_properties_get( properties, "resource" ); - if ( mlt_type == NULL ) - type = unknown_type; - else if (resource != NULL && !strcmp( resource, "" ) ) - type = playlist_type; - else if (resource != NULL && !strcmp( resource, "" ) ) - type = tractor_type; - else if (resource != NULL && !strcmp( resource, "" ) ) - type = multitrack_type; - else if ( !strcmp( mlt_type, "producer" ) ) - type = producer_type; - else if ( !strcmp( mlt_type, "filter" ) ) - type = filter_type; - else if ( !strcmp( mlt_type, "transition" ) ) - type = transition_type; - else if ( !strcmp( mlt_type, "consumer" ) ) - type = consumer_type; - else - type = unknown_type; - } - return type; -} - -/** Connect a producer to the service. - * - * \public \memberof mlt_service_s - * \param this a service - * \param producer a producer - * \param index which of potentially multiple producers to this service (0 based) - * \return > 0 warning, == 0 success, < 0 serious error, - * 1 = this service does not accept input, - * 2 = the producer is invalid, - * 3 = the producer is already registered with this consumer - */ - -int mlt_service_connect_producer( mlt_service this, mlt_service producer, int index ) -{ - int i = 0; - - // Get the service base - mlt_service_base *base = this->local; - - // Special case 'track' index - only works for last filter(s) in a particular chain - // but allows a filter to apply to the output frame regardless of which track it comes from - if ( index == -1 ) - index = 0; - - // Check if the producer is already registered with this service - for ( i = 0; i < base->count; i ++ ) - if ( base->in[ i ] == producer ) - return 3; - - // Allocate space - if ( index >= base->size ) - { - int new_size = base->size + index + 10; - base->in = realloc( base->in, new_size * sizeof( mlt_service ) ); - if ( base->in != NULL ) - { - for ( i = base->size; i < new_size; i ++ ) - base->in[ i ] = NULL; - base->size = new_size; - } - } - - // If we have space, assign the input - if ( base->in != NULL && index >= 0 && index < base->size ) - { - // Get the current service - mlt_service current = base->in[ index ]; - - // Increment the reference count on this producer - if ( producer != NULL ) - mlt_properties_inc_ref( MLT_SERVICE_PROPERTIES( producer ) ); - - // Now we disconnect the producer service from its consumer - mlt_service_disconnect( producer ); - - // Add the service to index specified - base->in[ index ] = producer; - - // Determine the number of active tracks - if ( index >= base->count ) - base->count = index + 1; - - // Now we connect the producer to its connected consumer - mlt_service_connect( producer, this ); - - // Close the current service - mlt_service_close( current ); - - // Inform caller that all went well - return 0; - } - else - { - return -1; - } -} - -/** Disconnect this service from its consumer. - * - * \public \memberof mlt_service_s - * \param this a service - */ - -static void mlt_service_disconnect( mlt_service this ) -{ - if ( this != NULL ) - { - // Get the service base - mlt_service_base *base = this->local; - - // Disconnect - base->out = NULL; - } -} - -/** Obtain the consumer this service is connected to. - * - * \public \memberof mlt_service_s - * \param this a service - * \return the consumer - */ - -mlt_service mlt_service_consumer( mlt_service this ) -{ - // Get the service base - mlt_service_base *base = this->local; - - // Return the connected consumer - return base->out; -} - -/** Obtain the producer this service is connected to. - * - * \public \memberof mlt_service_s - * \param this a service - * \return the last-most producer - */ - -mlt_service mlt_service_producer( mlt_service this ) -{ - // Get the service base - mlt_service_base *base = this->local; - - // Return the connected producer - return base->count > 0 ? base->in[ base->count - 1 ] : NULL; -} - -/** Associate this service to a consumer. - * - * Overwrites connection to any existing consumer. - * \private \memberof mlt_service_s - * \param this a service - * \param that a consumer - */ - -static void mlt_service_connect( mlt_service this, mlt_service that ) -{ - if ( this != NULL ) - { - // Get the service base - mlt_service_base *base = this->local; - - // There's a bit more required here... - base->out = that; - } -} - -/** Get the first connected producer. - * - * \public \memberof mlt_service_s - * \param this a service - * \return the first producer - */ - -mlt_service mlt_service_get_producer( mlt_service this ) -{ - mlt_service producer = NULL; - - // Get the service base - mlt_service_base *base = this->local; - - if ( base->in != NULL ) - producer = base->in[ 0 ]; - - return producer; -} - -/** Default implementation of the get_frame virtual function. - * - * \private \memberof mlt_service_s - * \param this a service - * \param[out] frame a frame by reference - * \param index as determined by the producer - * \return false - */ - -static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int index ) -{ - mlt_service_base *base = this->local; - if ( index < base->count ) - { - mlt_service producer = base->in[ index ]; - if ( producer != NULL ) - return mlt_service_get_frame( producer, frame, index ); - } - *frame = mlt_frame_init( this ); - return 0; -} - -/** Return the properties object. - * - * \public \memberof mlt_service_s - * \param this a service - * \return the properties - */ - -mlt_properties mlt_service_properties( mlt_service this ) -{ - return this != NULL ? &this->parent : NULL; -} - -/** Recursively apply attached filters. - * - * \public \memberof mlt_service_s - * \param this a service - * \param frame a frame - * \param index used to track depth of recursion, top caller should supply 0 - */ - -void mlt_service_apply_filters( mlt_service this, mlt_frame frame, int index ) -{ - int i; - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - mlt_properties service_properties = MLT_SERVICE_PROPERTIES( this ); - mlt_service_base *base = this->local; - mlt_position position = mlt_frame_get_position( frame ); - mlt_position this_in = mlt_properties_get_position( service_properties, "in" ); - mlt_position this_out = mlt_properties_get_position( service_properties, "out" ); - - if ( index == 0 || mlt_properties_get_int( service_properties, "_filter_private" ) == 0 ) - { - // Process the frame with the attached filters - for ( i = 0; i < base->filter_count; i ++ ) - { - if ( base->filters[ i ] != NULL ) - { - mlt_position in = mlt_filter_get_in( base->filters[ i ] ); - mlt_position out = mlt_filter_get_out( base->filters[ i ] ); - int disable = mlt_properties_get_int( MLT_FILTER_PROPERTIES( base->filters[ i ] ), "disable" ); - if ( !disable && ( ( in == 0 && out == 0 ) || ( position >= in && ( position <= out || out == 0 ) ) ) ) - { - mlt_properties_set_position( frame_properties, "in", in == 0 ? this_in : in ); - mlt_properties_set_position( frame_properties, "out", out == 0 ? this_out : out ); - mlt_filter_process( base->filters[ i ], frame ); - mlt_service_apply_filters( MLT_FILTER_SERVICE( base->filters[ i ] ), frame, index + 1 ); - } - } - } - } -} - -/** Obtain a frame. - * - * \public \memberof mlt_service_s - * \param this a service - * \param[out] frame a frame by reference - * \param index as determined by the producer - * \return true if there was an error - */ - -int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index ) -{ - int result = 0; - - // Lock the service - mlt_service_lock( this ); - - // Ensure that the frame is NULL - *frame = NULL; - - // Only process if we have a valid service - if ( this != NULL && this->get_frame != NULL ) - { - mlt_properties properties = MLT_SERVICE_PROPERTIES( this ); - mlt_position in = mlt_properties_get_position( properties, "in" ); - mlt_position out = mlt_properties_get_position( properties, "out" ); - - result = this->get_frame( this, frame, index ); - - if ( result == 0 ) - { - mlt_properties_inc_ref( properties ); - properties = MLT_FRAME_PROPERTIES( *frame ); - if ( in >=0 && out > 0 ) - { - mlt_properties_set_position( properties, "in", in ); - mlt_properties_set_position( properties, "out", out ); - } - mlt_service_apply_filters( this, *frame, 1 ); - mlt_deque_push_back( MLT_FRAME_SERVICE_STACK( *frame ), this ); - } - } - - // Make sure we return a frame - if ( *frame == NULL ) - *frame = mlt_frame_init( this ); - - // Unlock the service - mlt_service_unlock( this ); - - return result; -} - -/** The service-changed event handler. - * - * \private \memberof mlt_service_s - * \param owner ignored - * \param this the service on which the "service-changed" event is fired - */ - -static void mlt_service_filter_changed( mlt_service owner, mlt_service this ) -{ - mlt_events_fire( MLT_SERVICE_PROPERTIES( this ), "service-changed", NULL ); -} - -/** Attach a filter. - * - * \public \memberof mlt_service_s - * \param this a service - * \param filter the filter to attach - * \return true if there was an error - */ - -int mlt_service_attach( mlt_service this, mlt_filter filter ) -{ - int error = this == NULL || filter == NULL; - if ( error == 0 ) - { - int i = 0; - mlt_properties properties = MLT_SERVICE_PROPERTIES( this ); - mlt_service_base *base = this->local; - - for ( i = 0; error == 0 && i < base->filter_count; i ++ ) - if ( base->filters[ i ] == filter ) - error = 1; - - if ( error == 0 ) - { - if ( base->filter_count == base->filter_size ) - { - base->filter_size += 10; - base->filters = realloc( base->filters, base->filter_size * sizeof( mlt_filter ) ); - } - - if ( base->filters != NULL ) - { - mlt_properties props = MLT_FILTER_PROPERTIES( filter ); - mlt_properties_inc_ref( MLT_FILTER_PROPERTIES( filter ) ); - base->filters[ base->filter_count ++ ] = filter; - mlt_events_fire( properties, "service-changed", NULL ); - mlt_events_listen( props, this, "service-changed", ( mlt_listener )mlt_service_filter_changed ); - mlt_events_listen( props, this, "property-changed", ( mlt_listener )mlt_service_filter_changed ); - } - else - { - error = 2; - } - } - } - return error; -} - -/** Detach a filter. - * - * \public \memberof mlt_service_s - * \param this a service - * \param filter the filter to detach - * \return true if there was an error - */ - -int mlt_service_detach( mlt_service this, mlt_filter filter ) -{ - int error = this == NULL || filter == NULL; - if ( error == 0 ) - { - int i = 0; - mlt_service_base *base = this->local; - mlt_properties properties = MLT_SERVICE_PROPERTIES( this ); - - for ( i = 0; i < base->filter_count; i ++ ) - if ( base->filters[ i ] == filter ) - break; - - if ( i < base->filter_count ) - { - base->filters[ i ] = NULL; - for ( i ++ ; i < base->filter_count; i ++ ) - base->filters[ i - 1 ] = base->filters[ i ]; - base->filter_count --; - mlt_events_disconnect( MLT_FILTER_PROPERTIES( filter ), this ); - mlt_filter_close( filter ); - mlt_events_fire( properties, "service-changed", NULL ); - } - } - return error; -} - -/** Retrieve a filter. - * - * \public \memberof mlt_service_s - * \param this a service - * \param index which one of potentially multiple filters - * \return the filter or null if there was an error - */ - -mlt_filter mlt_service_filter( mlt_service this, int index ) -{ - mlt_filter filter = NULL; - if ( this != NULL ) - { - mlt_service_base *base = this->local; - if ( index >= 0 && index < base->filter_count ) - filter = base->filters[ index ]; - } - return filter; -} - -/** Retrieve the profile. - * - * \public \memberof mlt_service_s - * \param this a service - * \return the profile - */ - -mlt_profile mlt_service_profile( mlt_service this ) -{ - return mlt_properties_get_data( MLT_SERVICE_PROPERTIES( this ), "_profile", NULL ); -} - -/** Destroy a service. - * - * \public \memberof mlt_service_s - * \param this the service to destroy - */ - -void mlt_service_close( mlt_service this ) -{ - if ( this != NULL && mlt_properties_dec_ref( MLT_SERVICE_PROPERTIES( this ) ) <= 0 ) - { - if ( this->close != NULL ) - { - this->close( this->close_object ); - } - else - { - mlt_service_base *base = this->local; - int i = 0; - int count = base->filter_count; - mlt_events_block( MLT_SERVICE_PROPERTIES( this ), this ); - while( count -- ) - mlt_service_detach( this, base->filters[ 0 ] ); - free( base->filters ); - for ( i = 0; i < base->count; i ++ ) - if ( base->in[ i ] != NULL ) - mlt_service_close( base->in[ i ] ); - this->parent.close = NULL; - free( base->in ); - pthread_mutex_destroy( &base->mutex ); - free( base ); - purge_cache( this ); - mlt_properties_close( &this->parent ); - } - } - else - { - mlt_service_unlock( this ); - } -} - -/** Release a service's cache items. - * - * \private \memberof mlt_service_s - * \param self a service - */ - -static void purge_cache( mlt_service self ) -{ - mlt_properties caches = mlt_properties_get_data( mlt_global_properties(), "caches", NULL ); - - if ( caches ) - { - int i = mlt_properties_count( caches ); - while ( i-- ) - { - mlt_cache_purge( mlt_properties_get_data_at( caches, i, NULL ), self ); - mlt_properties_set_data( mlt_global_properties(), mlt_properties_get_name( caches, i ), NULL, 0, NULL, NULL ); - } - } -} - -/** Lookup the cache object for a service. - * - * \private \memberof mlt_service_s - * \param self a service - * \param name a name for the object - * \return a cache - */ - -static mlt_cache get_cache( mlt_service self, const char *name ) -{ - mlt_cache result = NULL; - mlt_properties caches = mlt_properties_get_data( mlt_global_properties(), "caches", NULL ); - - if ( !caches ) - { - caches = mlt_properties_new(); - mlt_properties_set_data( mlt_global_properties(), "caches", caches, 0, ( mlt_destructor )mlt_properties_close, NULL ); - } - if ( caches ) - { - result = mlt_properties_get_data( caches, name, NULL ); - if ( !result ) - { - result = mlt_cache_init(); - mlt_properties_set_data( caches, name, result, 0, ( mlt_destructor )mlt_cache_close, NULL ); - } - } - - return result; -} - -/** Put an object into a service's cache. - * - * \public \memberof mlt_service_s - * \param self a service - * \param name a name for the object that is unique to the service class, but not to the instance - * \param data an opaque pointer to the object to put into the cache - * \param size the number of bytes pointed to by data - * \param destructor a function that releases the data - */ - -void mlt_service_cache_put( mlt_service self, const char *name, void* data, int size, mlt_destructor destructor ) -{ - mlt_log( self, MLT_LOG_DEBUG, "%s: name %s object %p data %p\n", __FUNCTION__, name, self, data ); - mlt_cache cache = get_cache( self, name ); - - if ( cache ) - mlt_cache_put( cache, self, data, size, destructor ); -} - -/** Get an object from a service's cache. - * - * \public \memberof mlt_service_s - * \param self a service - * \param name a name for the object that is unique to the service class, but not to the instance - * \return a cache item or NULL if an object is not found - * \see mlt_cache_item_data - */ - -mlt_cache_item mlt_service_cache_get( mlt_service self, const char *name ) -{ - mlt_log( self, MLT_LOG_DEBUG, "%s: name %s object %p\n", __FUNCTION__, name, self ); - mlt_cache_item result = NULL; - mlt_cache cache = get_cache( self, name ); - - if ( cache ) - result = mlt_cache_get( cache, self ); - - return result; -} diff --git a/src/framework/mlt_service.h b/src/framework/mlt_service.h deleted file mode 100644 index ea451bf..0000000 --- a/src/framework/mlt_service.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * \file mlt_service.h - * \brief interface declaration for all service classes - * \see mlt_service_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_SERVICE_H_ -#define _MLT_SERVICE_H_ - -#include "mlt_properties.h" -#include "mlt_types.h" - -/** \brief Service abstract base class - * - * \extends mlt_properties - * The service is the base class for all of the interesting classes and - * plugins for MLT. A service can have multiple inputs connections to - * other services called its "producers" but only a single output to another - * service called its "consumer." A service that has both producer and - * consumer connections is called a filter. Any service can have zero or more - * filters "attached" to it. We call any collection of services and their - * connections a "service network," which is similar to what DirectShow calls - * a filter graph or what gstreamer calls an element pipeline. - * - * \event \em service-changed - * \event \em property-changed - * \properties \em mlt_type identifies the subclass - * \properties \em _mlt_service_hidden a flag that indicates whether to hide the mlt_service - * \properties \em mlt_service is the name of the implementation of the service - * \properties \em resource is either the stream identifier or grandchild-class - * \properties \em in when to start, what is started is service-specific - * \properties \em out when to stop - * \properties \em _filter_private Set this on a service to ensure that attached filters are handled privately. - * See modules/core/filter_region.c and modules/core/filter_watermark.c for examples. - * \properties \em disable Set this on a filter to disable it while keeping it in the object model. - * \properties \em _profile stores the mlt_profile for a service - * \properties \em _unique_id is a unique identifier - */ - -struct mlt_service_s -{ - struct mlt_properties_s parent; /**< \private */ - - /** Get a frame of data (virtual function). - * - * \param mlt_producer a producer - * \param mlt_frame_ptr a frame pointer by reference - * \param int an index - * \return true if there was an error - */ - int ( *get_frame )( mlt_service self, mlt_frame_ptr frame, int index ); - - /** the destructor virtual function */ - mlt_destructor close; - void *close_object; /**< the object supplied to the close virtual function */ - - void *local; /**< \private instance object */ - void *child; /**< \private the object of a subclass */ -}; - -#define MLT_SERVICE_PROPERTIES( service ) ( &( service )->parent ) - -extern int mlt_service_init( mlt_service self, void *child ); -extern void mlt_service_lock( mlt_service self ); -extern void mlt_service_unlock( mlt_service self ); -extern mlt_service_type mlt_service_identify( mlt_service self ); -extern int mlt_service_connect_producer( mlt_service self, mlt_service producer, int index ); -extern mlt_service mlt_service_get_producer( mlt_service self ); -extern int mlt_service_get_frame( mlt_service self, mlt_frame_ptr frame, int index ); -extern mlt_properties mlt_service_properties( mlt_service self ); -extern mlt_service mlt_service_consumer( mlt_service self ); -extern mlt_service mlt_service_producer( mlt_service self ); -extern int mlt_service_attach( mlt_service self, mlt_filter filter ); -extern int mlt_service_detach( mlt_service self, mlt_filter filter ); -extern void mlt_service_apply_filters( mlt_service self, mlt_frame frame, int index ); -extern mlt_filter mlt_service_filter( mlt_service self, int index ); -extern mlt_profile mlt_service_profile( mlt_service self ); -extern void mlt_service_close( mlt_service self ); -extern void mlt_service_cache_put( mlt_service self, const char *name, void* data, int size, mlt_destructor destructor ); -extern mlt_cache_item mlt_service_cache_get( mlt_service self, const char *name ); - -#endif - diff --git a/src/framework/mlt_tokeniser.c b/src/framework/mlt_tokeniser.c deleted file mode 100644 index 1fa28b0..0000000 --- a/src/framework/mlt_tokeniser.c +++ /dev/null @@ -1,172 +0,0 @@ -/** - * \file mlt_tokeniser.c - * \brief string tokeniser - * \see mlt_tokeniser_s - * - * Copyright (C) 2002-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* System header files */ -#include -#include - -/* Application header files */ -#include "mlt_tokeniser.h" - -/** Initialise a tokeniser. -*/ - -mlt_tokeniser mlt_tokeniser_init( ) -{ - return calloc( 1, sizeof( mlt_tokeniser_t ) ); -} - -/** Clear the tokeniser. -*/ - -static void mlt_tokeniser_clear( mlt_tokeniser tokeniser ) -{ - int index = 0; - for ( index = 0; index < tokeniser->count; index ++ ) - free( tokeniser->tokens[ index ] ); - tokeniser->count = 0; - free( tokeniser->input ); - tokeniser->input = NULL; -} - -/** Append a string to the tokeniser. -*/ - -static int mlt_tokeniser_append( mlt_tokeniser tokeniser, char *token ) -{ - int error = 0; - - if ( tokeniser->count == tokeniser->size ) - { - tokeniser->size += 20; - tokeniser->tokens = realloc( tokeniser->tokens, tokeniser->size * sizeof( char * ) ); - } - - if ( tokeniser->tokens != NULL ) - { - tokeniser->tokens[ tokeniser->count ++ ] = strdup( token ); - } - else - { - tokeniser->count = 0; - error = -1; - } - return error; -} - -/** Parse a string by splitting on the delimiter provided. -*/ - -int mlt_tokeniser_parse_new( mlt_tokeniser tokeniser, char *string, const char *delimiter ) -{ - int count = 0; - int length = strlen( string ); - int delimiter_size = strlen( delimiter ); - int index = 0; - char *token = strdup( string ); - - mlt_tokeniser_clear( tokeniser ); - tokeniser->input = strdup( string ); - strcpy( token, "" ); - - for ( index = 0; index < length; ) - { - char *start = string + index; - char *end = strstr( start, delimiter ); - - if ( end == NULL ) - { - strcat( token, start ); - mlt_tokeniser_append( tokeniser, token ); - index = length; - count ++; - } - else if ( start != end ) - { - strncat( token, start, end - start ); - index += end - start; - if ( strchr( token, '\"' ) == NULL || token[ strlen( token ) - 1 ] == '\"' ) - { - mlt_tokeniser_append( tokeniser, token ); - strcpy( token, "" ); - count ++; - } - else while ( strncmp( string + index, delimiter, delimiter_size ) == 0 ) - { - strncat( token, delimiter, delimiter_size ); - index += delimiter_size; - } - } - else - { - index += strlen( delimiter ); - } - } - - /* Special case - malformed string condition */ - if ( !strcmp( token, "" ) ) - { - count = 0 - ( count - 1 ); - mlt_tokeniser_append( tokeniser, token ); - } - - free( token ); - return count; -} - -/** Get the original input. -*/ - -char *mlt_tokeniser_get_input( mlt_tokeniser tokeniser ) -{ - return tokeniser->input; -} - -/** Get the number of tokens. -*/ - -int mlt_tokeniser_count( mlt_tokeniser tokeniser ) -{ - return tokeniser->count; -} - -/** Get a token as a string. -*/ - -char *mlt_tokeniser_get_string( mlt_tokeniser tokeniser, int index ) -{ - if ( index < tokeniser->count ) - return tokeniser->tokens[ index ]; - else - return NULL; -} - -/** Close the tokeniser. -*/ - -void mlt_tokeniser_close( mlt_tokeniser tokeniser ) -{ - mlt_tokeniser_clear( tokeniser ); - free( tokeniser->tokens ); - free( tokeniser ); -} diff --git a/src/framework/mlt_tokeniser.h b/src/framework/mlt_tokeniser.h deleted file mode 100644 index d4715af..0000000 --- a/src/framework/mlt_tokeniser.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * \file mlt_tokeniser.h - * \brief string tokeniser - * \see mlt_tokeniser_s - * - * Copyright (C) 2002-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_TOKENISER_H_ -#define _MLT_TOKENISER_H_ - -/** \brief Tokeniser class - * - */ - -typedef struct -{ - char *input; - char **tokens; - int count; - int size; -} -*mlt_tokeniser, mlt_tokeniser_t; - -/* Remote parser API. -*/ - -extern mlt_tokeniser mlt_tokeniser_init( ); -extern int mlt_tokeniser_parse_new( mlt_tokeniser self, char *text, const char *delimiter ); -extern char *mlt_tokeniser_get_input( mlt_tokeniser self ); -extern int mlt_tokeniser_count( mlt_tokeniser self ); -extern char *mlt_tokeniser_get_string( mlt_tokeniser self, int index ); -extern void mlt_tokeniser_close( mlt_tokeniser self ); - -#endif diff --git a/src/framework/mlt_tractor.c b/src/framework/mlt_tractor.c deleted file mode 100644 index 40c7821..0000000 --- a/src/framework/mlt_tractor.c +++ /dev/null @@ -1,540 +0,0 @@ -/** - * \file mlt_tractor.c - * \brief tractor service class - * \see mlt_tractor_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_tractor.h" -#include "mlt_frame.h" -#include "mlt_multitrack.h" -#include "mlt_field.h" -#include "mlt_log.h" - -#include -#include -#include -#include - -/* Forward references to static methods. -*/ - -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int track ); -static void mlt_tractor_listener( mlt_multitrack tracks, mlt_tractor this ); - -/** Construct a tractor without a field or multitrack. - * - * Sets the resource property to "", the mlt_type to "mlt_producer", - * and mlt_service to "tractor". - * - * \public \memberof mlt_tractor_s - * \return the new tractor - */ - -mlt_tractor mlt_tractor_init( ) -{ - mlt_tractor this = calloc( sizeof( struct mlt_tractor_s ), 1 ); - if ( this != NULL ) - { - mlt_producer producer = &this->parent; - if ( mlt_producer_init( producer, this ) == 0 ) - { - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - - mlt_properties_set( properties, "resource", "" ); - mlt_properties_set( properties, "mlt_type", "mlt_producer" ); - mlt_properties_set( properties, "mlt_service", "tractor" ); - mlt_properties_set_int( properties, "in", 0 ); - mlt_properties_set_int( properties, "out", -1 ); - mlt_properties_set_int( properties, "length", 0 ); - - producer->get_frame = producer_get_frame; - producer->close = ( mlt_destructor )mlt_tractor_close; - producer->close_object = this; - } - else - { - free( this ); - this = NULL; - } - } - return this; -} - -/** Construct a tractor as well as a field and multitrack. - * - * Sets the resource property to "", the mlt_type to "mlt_producer", - * and mlt_service to "tractor". - * - * \public \memberof mlt_tractor_s - * \return the new tractor - */ - -mlt_tractor mlt_tractor_new( ) -{ - mlt_tractor this = calloc( sizeof( struct mlt_tractor_s ), 1 ); - if ( this != NULL ) - { - mlt_producer producer = &this->parent; - if ( mlt_producer_init( producer, this ) == 0 ) - { - mlt_multitrack multitrack = mlt_multitrack_init( ); - mlt_field field = mlt_field_new( multitrack, this ); - mlt_properties props = MLT_PRODUCER_PROPERTIES( producer ); - - mlt_properties_set( props, "resource", "" ); - mlt_properties_set( props, "mlt_type", "mlt_producer" ); - mlt_properties_set( props, "mlt_service", "tractor" ); - mlt_properties_set_position( props, "in", 0 ); - mlt_properties_set_position( props, "out", 0 ); - mlt_properties_set_position( props, "length", 0 ); - mlt_properties_set_data( props, "multitrack", multitrack, 0, ( mlt_destructor )mlt_multitrack_close, NULL ); - mlt_properties_set_data( props, "field", field, 0, ( mlt_destructor )mlt_field_close, NULL ); - - mlt_events_listen( MLT_MULTITRACK_PROPERTIES( multitrack ), this, "producer-changed", ( mlt_listener )mlt_tractor_listener ); - - producer->get_frame = producer_get_frame; - producer->close = ( mlt_destructor )mlt_tractor_close; - producer->close_object = this; - } - else - { - free( this ); - this = NULL; - } - } - return this; -} - -/** Get the service object associated to the tractor. - * - * \public \memberof mlt_tractor_s - * \param this a tractor - * \return the parent service object - * \see MLT_TRACTOR_SERVICE - */ - -mlt_service mlt_tractor_service( mlt_tractor this ) -{ - return MLT_PRODUCER_SERVICE( &this->parent ); -} - -/** Get the producer object associated to the tractor. - * - * \public \memberof mlt_tractor_s - * \param this a tractor - * \return the parent producer object - * \see MLT_TRACTOR_PRODUCER - */ - -mlt_producer mlt_tractor_producer( mlt_tractor this ) -{ - return this != NULL ? &this->parent : NULL; -} - -/** Get the properties object associated to the tractor. - * - * \public \memberof mlt_tractor_s - * \param this a tractor - * \return the tractor's property list - * \see MLT_TRACTOR_PROPERTIES - */ - -mlt_properties mlt_tractor_properties( mlt_tractor this ) -{ - return MLT_PRODUCER_PROPERTIES( &this->parent ); -} - -/** Get the field this tractor is harvesting. - * - * \public \memberof mlt_tractor_s - * \param this a tractor - * \return a field or NULL if there is no field for this tractor - */ - -mlt_field mlt_tractor_field( mlt_tractor this ) -{ - return mlt_properties_get_data( MLT_TRACTOR_PROPERTIES( this ), "field", NULL ); -} - -/** Get the multitrack this tractor is pulling. - * - * \public \memberof mlt_tractor_s - * \param this a tractor - * \return a multitrack or NULL if there is none - */ - -mlt_multitrack mlt_tractor_multitrack( mlt_tractor this ) -{ - return mlt_properties_get_data( MLT_TRACTOR_PROPERTIES( this ), "multitrack", NULL ); -} - -/** Ensure the tractors in/out points match the multitrack. - * - * \public \memberof mlt_tractor_s - * \param this a tractor - */ - -void mlt_tractor_refresh( mlt_tractor this ) -{ - mlt_multitrack multitrack = mlt_tractor_multitrack( this ); - mlt_properties properties = MLT_MULTITRACK_PROPERTIES( multitrack ); - mlt_properties self = MLT_TRACTOR_PROPERTIES( this ); - mlt_events_block( properties, self ); - mlt_events_block( self, self ); - mlt_multitrack_refresh( multitrack ); - mlt_properties_set_position( self, "in", 0 ); - mlt_properties_set_position( self, "out", mlt_properties_get_position( properties, "out" ) ); - mlt_events_unblock( self, self ); - mlt_events_unblock( properties, self ); - mlt_properties_set_position( self, "length", mlt_properties_get_position( properties, "length" ) ); -} - -static void mlt_tractor_listener( mlt_multitrack tracks, mlt_tractor this ) -{ - mlt_tractor_refresh( this ); -} - -/** Connect the tractor. - * - * \public \memberof mlt_tractor_s - * \param this a tractor - * \param producer a producer - * \return true on error - */ - -int mlt_tractor_connect( mlt_tractor this, mlt_service producer ) -{ - int ret = mlt_service_connect_producer( MLT_TRACTOR_SERVICE( this ), producer, 0 ); - - // This is the producer we're going to connect to - if ( ret == 0 ) - this->producer = producer; - - return ret; -} - -/** Set the producer for a specific track. - * - * \public \memberof mlt_tractor_s - * \param this a tractor - * \param producer a producer - * \param index the 0-based track index - * \return true on error - */ - -int mlt_tractor_set_track( mlt_tractor this, mlt_producer producer, int index ) -{ - return mlt_multitrack_connect( mlt_tractor_multitrack( this ), producer, index ); -} - -/** Get the producer for a specific track. - * - * \public \memberof mlt_tractor_s - * \param this a tractor - * \param index the 0-based track index - * \return the producer for track \p index - */ - -mlt_producer mlt_tractor_get_track( mlt_tractor this, int index ) -{ - return mlt_multitrack_track( mlt_tractor_multitrack( this ), index ); -} - -static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - uint8_t *data = NULL; - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - mlt_frame frame = mlt_frame_pop_service( this ); - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - mlt_properties_set( frame_properties, "rescale.interp", mlt_properties_get( properties, "rescale.interp" ) ); - mlt_properties_set_int( frame_properties, "resize_alpha", mlt_properties_get_int( properties, "resize_alpha" ) ); - mlt_properties_set_int( frame_properties, "distort", mlt_properties_get_int( properties, "distort" ) ); - mlt_properties_set_double( frame_properties, "consumer_aspect_ratio", mlt_properties_get_double( properties, "consumer_aspect_ratio" ) ); - mlt_properties_set_int( frame_properties, "consumer_deinterlace", mlt_properties_get_int( properties, "consumer_deinterlace" ) ); - mlt_properties_set( frame_properties, "deinterlace_method", mlt_properties_get( properties, "deinterlace_method" ) ); - mlt_properties_set_int( frame_properties, "normalised_width", mlt_properties_get_int( properties, "normalised_width" ) ); - mlt_properties_set_int( frame_properties, "normalised_height", mlt_properties_get_int( properties, "normalised_height" ) ); - mlt_frame_get_image( frame, buffer, format, width, height, writable ); - mlt_properties_set_data( properties, "image", *buffer, *width * *height * 2, NULL, NULL ); - mlt_properties_set_int( properties, "width", *width ); - mlt_properties_set_int( properties, "height", *height ); - mlt_properties_set_int( properties, "format", *format ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( frame ) ); - mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( frame_properties, "progressive" ) ); - mlt_properties_set_int( properties, "distort", mlt_properties_get_int( frame_properties, "distort" ) ); - data = mlt_frame_get_alpha_mask( frame ); - mlt_properties_set_data( properties, "alpha", data, 0, NULL, NULL ); - return 0; -} - -static int producer_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - mlt_frame frame = mlt_frame_pop_audio( this ); - mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); - mlt_properties_set_data( properties, "audio", *buffer, 0, NULL, NULL ); - mlt_properties_set_int( properties, "frequency", *frequency ); - mlt_properties_set_int( properties, "channels", *channels ); - return 0; -} - -static void destroy_data_queue( void *arg ) -{ - if ( arg != NULL ) - { - // Assign the correct type - mlt_deque queue = arg; - - // Iterate through each item and destroy them - while ( mlt_deque_peek_front( queue ) != NULL ) - mlt_properties_close( mlt_deque_pop_back( queue ) ); - - // Close the deque - mlt_deque_close( queue ); - } -} - -/** Get the next frame. - * - * \private \memberof mlt_tractor_s - * \param parent the producer interface to the tractor - * \param[out] frame a frame by reference - * \param track the 0-based track index - * \return true on error - */ - -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int track ) -{ - mlt_tractor this = parent->child; - - // We only respond to the first track requests - if ( track == 0 && this->producer != NULL ) - { - int i = 0; - int done = 0; - mlt_frame temp = NULL; - int count = 0; - int image_count = 0; - - // Get the properties of the parent producer - mlt_properties properties = MLT_PRODUCER_PROPERTIES( parent ); - - // Try to obtain the multitrack associated to the tractor - mlt_multitrack multitrack = mlt_properties_get_data( properties, "multitrack", NULL ); - - // Or a specific producer - mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL ); - - // The output frame will hold the 'global' data feeds (ie: those which are targetted for the final frame) - mlt_deque data_queue = mlt_deque_init( ); - - // Determine whether this tractor feeds to the consumer or stops here - int global_feed = mlt_properties_get_int( properties, "global_feed" ); - - // If we don't have one, we're in trouble... - if ( multitrack != NULL ) - { - // Used to garbage collect all frames - char label[ 30 ]; - - // Get the id of the tractor - char *id = mlt_properties_get( properties, "_unique_id" ); - - // Will be used to store the frame properties object - mlt_properties frame_properties = NULL; - - // We'll store audio and video frames to use here - mlt_frame audio = NULL; - mlt_frame video = NULL; - mlt_frame first_video = NULL; - - // Temporary properties - mlt_properties temp_properties = NULL; - - // Get the multitrack's producer - mlt_producer target = MLT_MULTITRACK_PRODUCER( multitrack ); - mlt_producer_seek( target, mlt_producer_frame( parent ) ); - mlt_producer_set_speed( target, mlt_producer_get_speed( parent ) ); - - // We will create one frame and attach everything to it - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( parent ) ); - - // Get the properties of the frame - frame_properties = MLT_FRAME_PROPERTIES( *frame ); - - // Loop through each of the tracks we're harvesting - for ( i = 0; !done; i ++ ) - { - // Get a frame from the producer - mlt_service_get_frame( this->producer, &temp, i ); - - // Get the temporary properties - temp_properties = MLT_FRAME_PROPERTIES( temp ); - - // Check for last track - done = mlt_properties_get_int( temp_properties, "last_track" ); - - // Handle fx only tracks - if ( mlt_properties_get_int( temp_properties, "fx_cut" ) ) - { - int hide = ( video == NULL ? 1 : 0 ) | ( audio == NULL ? 2 : 0 ); - mlt_properties_set_int( temp_properties, "hide", hide ); - } - - // We store all frames with a destructor on the output frame - sprintf( label, "_%s_%d", id, count ++ ); - mlt_properties_set_data( frame_properties, label, temp, 0, ( mlt_destructor )mlt_frame_close, NULL ); - - // We want to append all 'final' feeds to the global queue - if ( !done && mlt_properties_get_data( temp_properties, "data_queue", NULL ) != NULL ) - { - // Move the contents of this queue on to the output frames data queue - mlt_deque sub_queue = mlt_properties_get_data( MLT_FRAME_PROPERTIES( temp ), "data_queue", NULL ); - mlt_deque temp = mlt_deque_init( ); - while ( global_feed && mlt_deque_count( sub_queue ) ) - { - mlt_properties p = mlt_deque_pop_back( sub_queue ); - if ( mlt_properties_get_int( p, "final" ) ) - mlt_deque_push_back( data_queue, p ); - else - mlt_deque_push_back( temp, p ); - } - while( mlt_deque_count( temp ) ) - mlt_deque_push_front( sub_queue, mlt_deque_pop_back( temp ) ); - mlt_deque_close( temp ); - } - - // Now do the same with the global queue but without the conditional behaviour - if ( mlt_properties_get_data( temp_properties, "global_queue", NULL ) != NULL ) - { - mlt_deque sub_queue = mlt_properties_get_data( MLT_FRAME_PROPERTIES( temp ), "global_queue", NULL ); - while ( mlt_deque_count( sub_queue ) ) - { - mlt_properties p = mlt_deque_pop_back( sub_queue ); - mlt_deque_push_back( data_queue, p ); - } - } - - // Pick up first video and audio frames - if ( !done && !mlt_frame_is_test_audio( temp ) && !( mlt_properties_get_int( temp_properties, "hide" ) & 2 ) ) - { - // Order of frame creation is starting to get problematic - if ( audio != NULL ) - { - mlt_deque_push_front( MLT_FRAME_AUDIO_STACK( temp ), producer_get_audio ); - mlt_deque_push_front( MLT_FRAME_AUDIO_STACK( temp ), audio ); - } - audio = temp; - } - if ( !done && !mlt_frame_is_test_card( temp ) && !( mlt_properties_get_int( temp_properties, "hide" ) & 1 ) ) - { - if ( video != NULL ) - { - mlt_deque_push_front( MLT_FRAME_IMAGE_STACK( temp ), producer_get_image ); - mlt_deque_push_front( MLT_FRAME_IMAGE_STACK( temp ), video ); - } - video = temp; - if ( first_video == NULL ) - first_video = temp; - - // Ensure that all frames know the aspect ratio of the background - mlt_properties_set_double( temp_properties, "output_ratio", - mlt_properties_get_double( MLT_FRAME_PROPERTIES( first_video ), "aspect_ratio" ) ); - - mlt_properties_set_int( MLT_FRAME_PROPERTIES( temp ), "image_count", ++ image_count ); - image_count = 1; - } - } - - // Now stack callbacks - if ( audio != NULL ) - { - mlt_frame_push_audio( *frame, audio ); - mlt_frame_push_audio( *frame, producer_get_audio ); - } - - if ( video != NULL ) - { - mlt_properties video_properties = MLT_FRAME_PROPERTIES( first_video ); - mlt_frame_push_service( *frame, video ); - mlt_frame_push_service( *frame, producer_get_image ); - if ( global_feed ) - mlt_properties_set_data( frame_properties, "data_queue", data_queue, 0, NULL, NULL ); - mlt_properties_set_data( video_properties, "global_queue", data_queue, 0, destroy_data_queue, NULL ); - mlt_properties_set_int( frame_properties, "width", mlt_properties_get_int( video_properties, "width" ) ); - mlt_properties_set_int( frame_properties, "height", mlt_properties_get_int( video_properties, "height" ) ); - mlt_properties_set_int( frame_properties, "real_width", mlt_properties_get_int( video_properties, "real_width" ) ); - mlt_properties_set_int( frame_properties, "real_height", mlt_properties_get_int( video_properties, "real_height" ) ); - mlt_properties_set_int( frame_properties, "progressive", mlt_properties_get_int( video_properties, "progressive" ) ); - mlt_properties_set_double( frame_properties, "aspect_ratio", mlt_properties_get_double( video_properties, "aspect_ratio" ) ); - mlt_properties_set_int( frame_properties, "image_count", image_count ); - } - else - { - destroy_data_queue( data_queue ); - } - - mlt_frame_set_position( *frame, mlt_producer_frame( parent ) ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_audio", audio == NULL ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_image", video == NULL ); - mlt_properties_set_data( MLT_FRAME_PROPERTIES( *frame ), "consumer_lock_service", this, 0, NULL, NULL ); - } - else if ( producer != NULL ) - { - mlt_producer_seek( producer, mlt_producer_frame( parent ) ); - mlt_producer_set_speed( producer, mlt_producer_get_speed( parent ) ); - mlt_service_get_frame( this->producer, frame, track ); - } - else - { - mlt_log( MLT_PRODUCER_SERVICE( parent ), MLT_LOG_ERROR, "tractor without a multitrack!!\n" ); - mlt_service_get_frame( this->producer, frame, track ); - } - - // Prepare the next frame - mlt_producer_prepare_next( parent ); - - // Indicate our found status - return 0; - } - else - { - // Generate a test card - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( parent ) ); - return 0; - } -} - -/** Close the tractor and free its resources. - * - * \public \memberof mlt_tractor_s - * \param this a tractor - */ - -void mlt_tractor_close( mlt_tractor this ) -{ - if ( this != NULL && mlt_properties_dec_ref( MLT_TRACTOR_PROPERTIES( this ) ) <= 0 ) - { - this->parent.close = NULL; - mlt_producer_close( &this->parent ); - free( this ); - } -} - diff --git a/src/framework/mlt_tractor.h b/src/framework/mlt_tractor.h deleted file mode 100644 index 73e0715..0000000 --- a/src/framework/mlt_tractor.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * \file mlt_tractor.h - * \brief tractor service class - * \see mlt_tractor_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_TRACTOR_H_ -#define _MLT_TRACTOR_H_ - -#include "mlt_producer.h" - -/** \brief Tractor class - * - * The tractor is a convenience class that works with the field class - * to manage a multitrack, track filters, and transitions. - * - * \extends mlt_producer_s - * \properties \em multitrack holds a reference to the mulitrack object that a tractor manages - * \properties \em field holds a reference to the field object that a tractor manages - * \properties \em producer holds a reference to an encapsulated producer - * \properties \em global_feed a flag to indicate whether this tractor feeds to the consumer or stops here - * \properties \em global_queue is something for the data_feed functionality in the core module - * \properties \em data_queue is something for the data_feed functionality in the core module - */ - -struct mlt_tractor_s -{ - struct mlt_producer_s parent; - mlt_service producer; -}; - -#define MLT_TRACTOR_PRODUCER( tractor ) ( &( tractor )->parent ) -#define MLT_TRACTOR_SERVICE( tractor ) MLT_PRODUCER_SERVICE( MLT_TRACTOR_PRODUCER( tractor ) ) -#define MLT_TRACTOR_PROPERTIES( tractor ) MLT_SERVICE_PROPERTIES( MLT_TRACTOR_SERVICE( tractor ) ) - -extern mlt_tractor mlt_tractor_init( ); -extern mlt_tractor mlt_tractor_new( ); -extern mlt_service mlt_tractor_service( mlt_tractor self ); -extern mlt_producer mlt_tractor_producer( mlt_tractor self ); -extern mlt_properties mlt_tractor_properties( mlt_tractor self ); -extern mlt_field mlt_tractor_field( mlt_tractor self ); -extern mlt_multitrack mlt_tractor_multitrack( mlt_tractor self ); -extern int mlt_tractor_connect( mlt_tractor self, mlt_service service ); -extern void mlt_tractor_refresh( mlt_tractor self ); -extern int mlt_tractor_set_track( mlt_tractor self, mlt_producer producer, int index ); -extern mlt_producer mlt_tractor_get_track( mlt_tractor self, int index ); -extern void mlt_tractor_close( mlt_tractor self ); - -#endif diff --git a/src/framework/mlt_transition.c b/src/framework/mlt_transition.c deleted file mode 100644 index 5077795..0000000 --- a/src/framework/mlt_transition.c +++ /dev/null @@ -1,388 +0,0 @@ -/** - * \file mlt_transition.c - * \brief abstraction for all transition services - * \see mlt_transition_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "mlt_transition.h" -#include "mlt_frame.h" -#include "mlt_log.h" - -#include -#include -#include - -/* Forward references */ - -static int transition_get_frame( mlt_service this, mlt_frame_ptr frame, int index ); - -/** Initialize a new transition. - * - * \public \memberof mlt_transition_s - * \param this a transition - * \param child the object of a subclass - * \return true on error - */ - -int mlt_transition_init( mlt_transition this, void *child ) -{ - mlt_service service = &this->parent; - memset( this, 0, sizeof( struct mlt_transition_s ) ); - this->child = child; - if ( mlt_service_init( service, this ) == 0 ) - { - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - service->get_frame = transition_get_frame; - service->close = ( mlt_destructor )mlt_transition_close; - service->close_object = this; - - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", 0 ); - mlt_properties_set_int( properties, "a_track", 0 ); - mlt_properties_set_int( properties, "b_track", 1 ); - - return 0; - } - return 1; -} - -/** Create and initialize a new transition. - * - * \public \memberof mlt_transition_s - * \return a new transition - */ - -mlt_transition mlt_transition_new( ) -{ - mlt_transition this = calloc( 1, sizeof( struct mlt_transition_s ) ); - if ( this != NULL ) - mlt_transition_init( this, NULL ); - return this; -} - -/** Get the service class interface. - * - * \public \memberof mlt_transition_s - * \param this a transition - * \return the service class - * \see MLT_TRANSITION_SERVICE - */ - -mlt_service mlt_transition_service( mlt_transition this ) -{ - return this != NULL ? &this->parent : NULL; -} - -/** Get the properties interface. - * - * \public \memberof mlt_transition_s - * \param this a transition - * \return the transition's properties - * \see MLT_TRANSITION_PROPERTIES - */ - -mlt_properties mlt_transition_properties( mlt_transition this ) -{ - return MLT_TRANSITION_PROPERTIES( this ); -} - -/** Connect this transition with a producers a and b tracks. - * - * \public \memberof mlt_transition_s - * \param this a transition - * \param producer a producer - * \param a_track the track index of the first input - * \param b_track the track index of the second index - * \return true on error - */ - -int mlt_transition_connect( mlt_transition this, mlt_service producer, int a_track, int b_track ) -{ - int ret = mlt_service_connect_producer( &this->parent, producer, a_track ); - if ( ret == 0 ) - { - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - this->producer = producer; - mlt_properties_set_int( properties, "a_track", a_track ); - mlt_properties_set_int( properties, "b_track", b_track ); - } - return ret; -} - -/** Set the starting and ending time for when the transition is active. - * - * \public \memberof mlt_transition_s - * \param this a transition - * \param in the starting time - * \param out the ending time - */ - -void mlt_transition_set_in_and_out( mlt_transition this, mlt_position in, mlt_position out ) -{ - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - mlt_properties_set_position( properties, "in", in ); - mlt_properties_set_position( properties, "out", out ); -} - -/** Get the index of the a track. - * - * \public \memberof mlt_transition_s - * \param this a transition - * \return the 0-based index of the track of the first producer - */ - -int mlt_transition_get_a_track( mlt_transition this ) -{ - return mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "a_track" ); -} - -/** Get the index of the b track. - * - * \public \memberof mlt_transition_s - * \param this a transition - * \return the 0-based index of the track of the second producer - */ - -int mlt_transition_get_b_track( mlt_transition this ) -{ - return mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "b_track" ); -} - -/** Get the in point. - * - * \public \memberof mlt_transition_s - * \param this a transition - * \return the starting time - */ - -mlt_position mlt_transition_get_in( mlt_transition this ) -{ - return mlt_properties_get_position( MLT_TRANSITION_PROPERTIES( this ), "in" ); -} - -/** Get the out point. - * - * \public \memberof mlt_transition_s - * \param this a transition - * \return the ending time - */ - -mlt_position mlt_transition_get_out( mlt_transition this ) -{ - return mlt_properties_get_position( MLT_TRANSITION_PROPERTIES( this ), "out" ); -} - -/** Process the frame. - * - * If we have no process method (unlikely), we simply return the a_frame unmolested. - * - * \public \memberof mlt_transition_s - * \param this a transition - * \param a_frame a frame from the first producer - * \param b_frame a frame from the second producer - * \return a frame - */ - -mlt_frame mlt_transition_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame ) -{ - if ( this->process == NULL ) - return a_frame; - else - return this->process( this, a_frame, b_frame ); -} - -/** Get a frame from this transition. - - The logic is complex here. A transition is typically applied to frames on the a and - b tracks specified in the connect method above and only if both contain valid info - for the transition type (this is either audio or image). - - However, the fixed a_track may not always contain data of the correct type, eg: -
-	+---------+                               +-------+
-	|c1       |                               |c5     | <-- A(0,1) <-- B(0,2) <-- get frame
-	+---------+                     +---------+-+-----+        |          |
-	                                |c4         |       <------+          |
-	         +----------+-----------+-+---------+                         |
-	         |c2        |c3           |                 <-----------------+
-	         +----------+-------------+
-
- During the overlap of c1 and c2, there is nothing for the A transition to do, so this - results in a no operation, but B is triggered. During the overlap of c2 and c3, again, - the A transition is inactive and because the B transition is pointing at track 0, - it too would be inactive. This isn't an ideal situation - it's better if the B - transition simply treats the frames from c3 as though they're the a track. - - For this to work, we cache all frames coming from all tracks between the a and b - tracks. Before we process, we determine that the b frame contains someting of the - right type and then we determine which frame to use as the a frame (selecting a - matching frame from a_track to b_track - 1). If both frames contain data of the - correct type, we process the transition. - - This method is invoked for each track and we return the cached frames as needed. - We clear the cache only when the requested frame is flagged as a 'last_track' frame. - - * \private \memberof mlt_transition_s - * \param service a service - * \param[out] frame a frame by reference - * \param index 0-based track index - * \return true on error - */ - -static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int index ) -{ - int error = 0; - mlt_transition this = service->child; - - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - int accepts_blanks = mlt_properties_get_int( properties, "accepts_blanks" ); - int a_track = mlt_properties_get_int( properties, "a_track" ); - int b_track = mlt_properties_get_int( properties, "b_track" ); - mlt_position in = mlt_properties_get_position( properties, "in" ); - mlt_position out = mlt_properties_get_position( properties, "out" ); - int always_active = mlt_properties_get_int( properties, "always_active" ); - int type = mlt_properties_get_int( properties, "_transition_type" ); - int reverse_order = 0; - - // Ensure that we have the correct order - if ( a_track > b_track ) - { - reverse_order = 1; - a_track = b_track; - b_track = mlt_properties_get_int( properties, "a_track" ); - } - - // Only act on this operation once per multitrack iteration from the tractor - if ( !this->held ) - { - int active = 0; - int i = 0; - int a_frame = a_track; - int b_frame = b_track; - mlt_position position; - int ( *invalid )( mlt_frame ) = type == 1 ? mlt_frame_is_test_card : mlt_frame_is_test_audio; - - // Initialise temporary store - if ( this->frames == NULL ) - this->frames = calloc( sizeof( mlt_frame ), b_track + 1 ); - - // Get all frames between a and b - for( i = a_track; i <= b_track; i ++ ) - mlt_service_get_frame( this->producer, &this->frames[ i ], i ); - - // We're holding these frames until the last_track frame property is received - this->held = 1; - - // When we need to locate the a_frame - switch( type ) - { - case 1: - case 2: - // Some transitions (esp. audio) may accept blank frames - active = accepts_blanks; - - // If we're not active then... - if ( !active ) - { - // Hunt for the a_frame - while( a_frame <= b_frame && invalid( this->frames[ a_frame ] ) ) - a_frame ++; - - // Determine if we're active now - active = a_frame != b_frame && !invalid( this->frames[ b_frame ] ); - } - break; - - default: - mlt_log( service, MLT_LOG_ERROR, "invalid transition type\n" ); - break; - } - - // Now handle the non-always active case - if ( active && !always_active ) - { - // For non-always-active transitions, we need the current position of the a frame - position = mlt_frame_get_position( this->frames[ a_frame ] ); - - // If a is in range, we're active - active = position >= in && position <= out; - } - - // Finally, process the a and b frames - if ( active ) - { - mlt_frame a_frame_ptr = this->frames[ !reverse_order ? a_frame : b_frame ]; - mlt_frame b_frame_ptr = this->frames[ !reverse_order ? b_frame : a_frame ]; - int a_hide = mlt_properties_get_int( MLT_FRAME_PROPERTIES( a_frame_ptr ), "hide" ); - int b_hide = mlt_properties_get_int( MLT_FRAME_PROPERTIES( b_frame_ptr ), "hide" ); - if ( !( a_hide & type ) && !( b_hide & type ) ) - { - // Process the transition - *frame = mlt_transition_process( this, a_frame_ptr, b_frame_ptr ); - - // We need to ensure that the tractor doesn't consider this frame for output - if ( *frame == a_frame_ptr ) - b_hide |= type; - else - a_hide |= type; - - mlt_properties_set_int( MLT_FRAME_PROPERTIES( a_frame_ptr ), "hide", a_hide ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( b_frame_ptr ), "hide", b_hide ); - } - } - } - - // Obtain the frame from the cache or the producer we're attached to - if ( index >= a_track && index <= b_track ) - *frame = this->frames[ index ]; - else - error = mlt_service_get_frame( this->producer, frame, index ); - - // Determine if that was the last track - this->held = !mlt_properties_get_int( MLT_FRAME_PROPERTIES( *frame ), "last_track" ); - - return error; -} - -/** Close and destroy the transition. - * - * \public \memberof mlt_transition_s - * \param this a transition - */ - -void mlt_transition_close( mlt_transition this ) -{ - if ( this != NULL && mlt_properties_dec_ref( MLT_TRANSITION_PROPERTIES( this ) ) <= 0 ) - { - this->parent.close = NULL; - if ( this->close != NULL ) - { - this->close( this ); - } - else - { - mlt_service_close( &this->parent ); - free( this->frames ); - free( this ); - } - } -} diff --git a/src/framework/mlt_transition.h b/src/framework/mlt_transition.h deleted file mode 100644 index 0f9879a..0000000 --- a/src/framework/mlt_transition.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * \file mlt_transition.h - * \brief abstraction for all transition services - * \see mlt_transition_s - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_TRANSITION_H_ -#define _MLT_TRANSITION_H_ - -#include "mlt_service.h" - -/** \brief Transition abstract service class - * - * A transition may modify the output of a producer based on the output of a second producer. - * - * \extends mlt_service_s - * \properties \em a_track the track index (0-based) of a multitrack of the first producer - * \properties \em b_track the track index (0-based) of a multitrack of the second producer - * \properties \em accepts_blanks a flag to indicate if the transition should accept blank frames - * \properties \em always_active a flag to indicate that the in and out points do not apply - * \properties \em _transition_type 1 for video, 2 for audio - */ - -struct mlt_transition_s -{ - /** We're implementing service here */ - struct mlt_service_s parent; - - /** public virtual */ - void ( *close )( mlt_transition ); - - /** protected transition method */ - mlt_frame ( *process )( mlt_transition, mlt_frame, mlt_frame ); - - /** Protected */ - void *child; - - /** track and in/out points */ - mlt_service producer; - - /** Private */ - mlt_frame *frames; - int held; -}; - -#define MLT_TRANSITION_SERVICE( transition ) ( &( transition )->parent ) -#define MLT_TRANSITION_PROPERTIES( transition ) MLT_SERVICE_PROPERTIES( MLT_TRANSITION_SERVICE( transition ) ) - -extern int mlt_transition_init( mlt_transition self, void *child ); -extern mlt_transition mlt_transition_new( ); -extern mlt_service mlt_transition_service( mlt_transition self ); -extern mlt_properties mlt_transition_properties( mlt_transition self ); -extern int mlt_transition_connect( mlt_transition self, mlt_service producer, int a_track, int b_track ); -extern void mlt_transition_set_in_and_out( mlt_transition self, mlt_position in, mlt_position out ); -extern int mlt_transition_get_a_track( mlt_transition self ); -extern int mlt_transition_get_b_track( mlt_transition self ); -extern mlt_position mlt_transition_get_in( mlt_transition self ); -extern mlt_position mlt_transition_get_out( mlt_transition self ); -extern mlt_frame mlt_transition_process( mlt_transition self, mlt_frame a_frame, mlt_frame b_frame ); -extern void mlt_transition_close( mlt_transition self ); - -#endif diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h deleted file mode 100644 index 921dd47..0000000 --- a/src/framework/mlt_types.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * \file mlt_types.h - * \brief Provides forward definitions of all public types - * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _MLT_TYPES_H_ -#define _MLT_TYPES_H_ - -#ifndef GCC_VERSION -#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#endif - -#include - -#include "mlt_pool.h" - -/** The set of supported image formats */ - -typedef enum -{ - mlt_image_none = 0,/**< image not available */ - mlt_image_rgb24, /**< 8-bit RGB */ - mlt_image_rgb24a, /**< 8-bit RGB with alpha channel */ - mlt_image_yuv422, /**< 8-bit YUV 4:2:2 packed */ - mlt_image_yuv420p, /**< 8-bit YUV 4:2:0 planar */ - mlt_image_opengl /**< suitable for OpenGL texture */ -} -mlt_image_format; - -/** The set of supported audio formats */ - -typedef enum -{ - mlt_audio_none = 0,/**< audio not available */ - mlt_audio_pcm /**< signed 16-bit interleaved PCM */ -} -mlt_audio_format; - -/** The relative time qualifiers */ - -typedef enum -{ - mlt_whence_relative_start, /**< relative to the beginning */ - mlt_whence_relative_current,/**< relative to the current position */ - mlt_whence_relative_end /**< relative to the end */ -} -mlt_whence; - -/** The recognized subclasses of mlt_service */ - -typedef enum -{ - invalid_type, /**< invalid service */ - unknown_type, /**< unknown class */ - producer_type, /**< Producer class */ - tractor_type, /**< Tractor class */ - playlist_type, /**< Playlist class */ - multitrack_type, /**< Multitrack class */ - filter_type, /**< Filter class */ - transition_type, /**< Transition class */ - consumer_type, /**< Consumer class */ - field_type /**< Field class */ -} -mlt_service_type; - -/* I don't want to break anyone's applications without warning. -Zach */ -#undef DOUBLE_MLT_POSITION -#ifdef DOUBLE_MLT_POSITION -typedef double mlt_position; -#else -typedef int32_t mlt_position; -#endif - -typedef struct mlt_frame_s *mlt_frame, **mlt_frame_ptr; /**< pointer to Frame object */ -typedef struct mlt_property_s *mlt_property; /**< pointer to Property object */ -typedef struct mlt_properties_s *mlt_properties; /**< pointer to Properties object */ -typedef struct mlt_event_struct *mlt_event; /**< pointer to Event object */ -typedef struct mlt_service_s *mlt_service; /**< pointer to Service object */ -typedef struct mlt_producer_s *mlt_producer; /**< pointer to Producer object */ -typedef struct mlt_playlist_s *mlt_playlist; /**< pointer to Playlist object */ -typedef struct mlt_multitrack_s *mlt_multitrack; /**< pointer to Multitrack object */ -typedef struct mlt_filter_s *mlt_filter; /**< pointer to Filter object */ -typedef struct mlt_transition_s *mlt_transition; /**< pointer to Transition object */ -typedef struct mlt_tractor_s *mlt_tractor; /**< pointer to Tractor object */ -typedef struct mlt_field_s *mlt_field; /**< pointer to Field object */ -typedef struct mlt_consumer_s *mlt_consumer; /**< pointer to Consumer object */ -typedef struct mlt_parser_s *mlt_parser; /**< pointer to Properties object */ -typedef struct mlt_deque_s *mlt_deque; /**< pointer to Deque object */ -typedef struct mlt_geometry_s *mlt_geometry; /**< pointer to Geometry object */ -typedef struct mlt_geometry_item_s *mlt_geometry_item; /**< pointer to Geometry Item object */ -typedef struct mlt_profile_s *mlt_profile; /**< pointer to Profile object */ -typedef struct mlt_repository_s *mlt_repository; /**< pointer to Repository object */ -typedef struct mlt_cache_s *mlt_cache; /**< pointer to Cache object */ -typedef struct mlt_cache_item_s *mlt_cache_item; /**< pointer to CacheItem object */ - -typedef void ( *mlt_destructor )( void * ); /**< pointer to destructor function */ -typedef char *( *mlt_serialiser )( void *, int length );/**< pointer to serialization function */ - -#define MLT_SERVICE(x) ( ( mlt_service )( x ) ) /**< Cast to a Service pointer */ -#define MLT_PRODUCER(x) ( ( mlt_producer )( x ) ) /**< Cast to a Producer pointer */ -#define MLT_MULTITRACK(x) ( ( mlt_multitrack )( x ) ) /**< Cast to a Multitrack pointer */ -#define MLT_PLAYLIST(x) ( ( mlt_playlist )( x ) ) /**< Cast to a Playlist pointer */ -#define MLT_TRACTOR(x) ( ( mlt_tractor )( x ) ) /**< Cast to a Tractor pointer */ -#define MLT_FILTER(x) ( ( mlt_filter )( x ) ) /**< Cast to a Filter pointer */ -#define MLT_TRANSITION(x) ( ( mlt_transition )( x ) ) /**< Cast to a Transition pointer */ - -#endif diff --git a/src/inigo/Makefile b/src/inigo/Makefile deleted file mode 100644 index c206a81..0000000 --- a/src/inigo/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -include ../../config.mak - -TARGET = inigo - -OBJS = inigo.o \ - io.o - -CFLAGS += -I.. $(RDYNAMIC) -DVERSION=\"$(version)\" - -LDFLAGS += -L../framework -lmlt -lpthread - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -d "$(DESTDIR)$(bindir)" - install -c -s -m 755 $(TARGET) "$(DESTDIR)$(bindir)" - -uninstall: - rm -f "$(DESTDIR)$(bindir)/$(TARGET)" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/inigo/configure b/src/inigo/configure deleted file mode 100755 index e69de29..0000000 diff --git a/src/inigo/inigo.c b/src/inigo/inigo.c deleted file mode 100644 index 698908e..0000000 --- a/src/inigo/inigo.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - * inigo.c -- MLT command line utility - * Copyright (C) 2002-2008 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include - -#include - -#ifdef __DARWIN__ -#include -#endif - -#include "io.h" - -static void transport_action( mlt_producer producer, char *value ) -{ - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - mlt_multitrack multitrack = mlt_properties_get_data( properties, "multitrack", NULL ); - mlt_consumer consumer = mlt_properties_get_data( properties, "transport_consumer", NULL ); - - mlt_properties_set_int( properties, "stats_off", 1 ); - - if ( strlen( value ) == 1 ) - { - switch( value[ 0 ] ) - { - case 'q': - mlt_properties_set_int( properties, "done", 1 ); - break; - case '0': - mlt_producer_set_speed( producer, 1 ); - mlt_producer_seek( producer, 0 ); - break; - case '1': - mlt_producer_set_speed( producer, -10 ); - break; - case '2': - mlt_producer_set_speed( producer, -5 ); - break; - case '3': - mlt_producer_set_speed( producer, -2 ); - break; - case '4': - mlt_producer_set_speed( producer, -1 ); - break; - case '5': - mlt_producer_set_speed( producer, 0 ); - break; - case '6': - case ' ': - mlt_producer_set_speed( producer, 1 ); - break; - case '7': - mlt_producer_set_speed( producer, 2 ); - break; - case '8': - mlt_producer_set_speed( producer, 5 ); - break; - case '9': - mlt_producer_set_speed( producer, 10 ); - break; - case 'd': - if ( multitrack != NULL ) - { - int i = 0; - mlt_position last = -1; - fprintf( stderr, "\n" ); - for ( i = 0; 1; i ++ ) - { - mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_start, i ); - if ( time == last ) - break; - last = time; - fprintf( stderr, "%d: %d\n", i, (int)time ); - } - } - break; - - case 'g': - if ( multitrack != NULL ) - { - mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 0 ); - mlt_producer_seek( producer, time ); - } - break; - case 'H': - if ( producer != NULL ) - { - mlt_position position = mlt_producer_position( producer ); - mlt_producer_seek( producer, position - ( mlt_producer_get_fps( producer ) * 60 ) ); - } - break; - case 'h': - if ( producer != NULL ) - { - mlt_position position = mlt_producer_position( producer ); - mlt_producer_set_speed( producer, 0 ); - mlt_producer_seek( producer, position - 1 ); - } - break; - case 'j': - if ( multitrack != NULL ) - { - mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 1 ); - mlt_producer_seek( producer, time ); - } - break; - case 'k': - if ( multitrack != NULL ) - { - mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, -1 ); - mlt_producer_seek( producer, time ); - } - break; - case 'l': - if ( producer != NULL ) - { - mlt_position position = mlt_producer_position( producer ); - if ( mlt_producer_get_speed( producer ) != 0 ) - mlt_producer_set_speed( producer, 0 ); - else - mlt_producer_seek( producer, position + 1 ); - } - break; - case 'L': - if ( producer != NULL ) - { - mlt_position position = mlt_producer_position( producer ); - mlt_producer_seek( producer, position + ( mlt_producer_get_fps( producer ) * 60 ) ); - } - break; - } - - mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( consumer ), "refresh", 1 ); - } - - mlt_properties_set_int( properties, "stats_off", 0 ); -} - -static mlt_consumer create_consumer( mlt_profile profile, char *id ) -{ - char *arg = id != NULL ? strchr( id, ':' ) : NULL; - if ( arg != NULL ) - *arg ++ = '\0'; - mlt_consumer consumer = mlt_factory_consumer( profile, id, arg ); - if ( consumer != NULL ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer ); - mlt_properties_set_data( properties, "transport_callback", transport_action, 0, NULL, NULL ); - } - return consumer; -} - -#ifdef __DARWIN__ - -static void event_handling( mlt_producer producer, mlt_consumer consumer ) -{ - SDL_Event event; - - while ( SDL_PollEvent( &event ) ) - { - switch( event.type ) - { - case SDL_QUIT: - mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( consumer ), "done", 1 ); - break; - - case SDL_KEYDOWN: - if ( event.key.keysym.unicode < 0x80 && event.key.keysym.unicode > 0 ) - { - char keyboard[ 2 ] = { event.key.keysym.unicode, 0 }; - transport_action( producer, keyboard ); - } - break; - } - } -} - -#endif - -static void transport( mlt_producer producer, mlt_consumer consumer ) -{ - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - int silent = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "silent" ); - int progress = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "progress" ); - struct timespec tm = { 0, 40000 }; - int total_length = mlt_producer_get_length( producer ); - int last_position = 0; - - if ( mlt_properties_get_int( properties, "done" ) == 0 && !mlt_consumer_is_stopped( consumer ) ) - { - if ( !silent && !progress ) - { - term_init( ); - - fprintf( stderr, "+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+\n" ); - fprintf( stderr, "|1=-10| |2= -5| |3= -2| |4= -1| |5= 0| |6= 1| |7= 2| |8= 5| |9= 10|\n" ); - fprintf( stderr, "+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+\n" ); - - fprintf( stderr, "+---------------------------------------------------------------------+\n" ); - fprintf( stderr, "| H = back 1 minute, L = forward 1 minute |\n" ); - fprintf( stderr, "| h = previous frame, l = next frame |\n" ); - fprintf( stderr, "| g = start of clip, j = next clip, k = previous clip |\n" ); - fprintf( stderr, "| 0 = restart, q = quit, space = play |\n" ); - fprintf( stderr, "+---------------------------------------------------------------------+\n" ); - } - - while( mlt_properties_get_int( properties, "done" ) == 0 && !mlt_consumer_is_stopped( consumer ) ) - { - int value = ( silent || progress )? -1 : term_read( ); - - if ( value != -1 ) - { - char string[ 2 ] = { value, 0 }; - transport_action( producer, string ); - } - -#ifdef __DARWIN__ - event_handling( producer, consumer ); -#endif - - if ( !silent && mlt_properties_get_int( properties, "stats_off" ) == 0 ) - { - if ( progress ) - { - int current_position = mlt_producer_position( producer ); - if ( current_position > last_position ) - { - fprintf( stderr, "Current Frame: %10d, percentage: %10d\r", - current_position, 100 * current_position / total_length ); - last_position = current_position; - } - } - else - { - fprintf( stderr, "Current Position: %10d\r", (int)mlt_producer_position( producer ) ); - } - } - - if ( silent ) - nanosleep( &tm, NULL ); - } - - if ( !silent ) - fprintf( stderr, "\n" ); - } -} - -static void query_metadata( mlt_repository repo, mlt_service_type type, const char *typestr, char *id ) -{ - mlt_properties metadata = mlt_repository_metadata( repo, type, id ); - if ( metadata ) - { - char *s = mlt_properties_serialise_yaml( metadata ); - fprintf( stderr, "%s", s ); - free( s ); - } - else - { - fprintf( stderr, "# No metadata for %s \"%s\"\n", typestr, id ); - } -} - -static void query_services( mlt_repository repo, mlt_service_type type ) -{ - mlt_properties services = NULL; - const char *typestr = NULL; - switch ( type ) - { - case consumer_type: - services = mlt_repository_consumers( repo ); - typestr = "consumers"; - break; - case filter_type: - services = mlt_repository_filters( repo ); - typestr = "filters"; - break; - case producer_type: - services = mlt_repository_producers( repo ); - typestr = "producers"; - break; - case transition_type: - services = mlt_repository_transitions( repo ); - typestr = "transitions"; - break; - default: - return; - } - fprintf( stderr, "---\n%s:\n", typestr ); - if ( services ) - { - int j; - for ( j = 0; j < mlt_properties_count( services ); j++ ) - fprintf( stderr, " - %s\n", mlt_properties_get_name( services, j ) ); - } - fprintf( stderr, "...\n" ); -} - -int main( int argc, char **argv ) -{ - int i; - mlt_consumer consumer = NULL; - mlt_producer inigo = NULL; - FILE *store = NULL; - char *name = NULL; - mlt_profile profile = NULL; - int is_progress = 0; - int is_silent = 0; - - // Construct the factory - mlt_repository repo = mlt_factory_init( NULL ); - - for ( i = 1; i < argc; i ++ ) - { - // Check for serialisation switch - if ( !strcmp( argv[ i ], "-serialise" ) ) - { - name = argv[ ++ i ]; - if ( name != NULL && strstr( name, ".inigo" ) ) - store = fopen( name, "w" ); - else - { - if ( name == NULL || name[0] == '-' ) - store = stdout; - name = NULL; - } - } - // Look for the profile option - else if ( !strcmp( argv[ i ], "-profile" ) ) - { - const char *pname = argv[ ++ i ]; - if ( pname && pname[0] != '-' ) - profile = mlt_profile_init( pname ); - } - else if ( !strcmp( argv[ i ], "-progress" ) ) - { - is_progress = 1; - } - // Look for the query option - else if ( !strcmp( argv[ i ], "-query" ) ) - { - const char *pname = argv[ ++ i ]; - if ( pname && pname[0] != '-' ) - { - if ( !strcmp( pname, "consumers" ) || !strcmp( pname, "consumer" ) ) - query_services( repo, consumer_type ); - else if ( !strcmp( pname, "filters" ) || !strcmp( pname, "filter" ) ) - query_services( repo, filter_type ); - else if ( !strcmp( pname, "producers" ) || !strcmp( pname, "producer" ) ) - query_services( repo, producer_type ); - else if ( !strcmp( pname, "transitions" ) || !strcmp( pname, "transition" ) ) - query_services( repo, transition_type ); - - else if ( !strncmp( pname, "consumer=", 9 ) ) - query_metadata( repo, consumer_type, "consumer", strchr( pname, '=' ) + 1 ); - else if ( !strncmp( pname, "filter=", 7 ) ) - query_metadata( repo, filter_type, "filter", strchr( pname, '=' ) + 1 ); - else if ( !strncmp( pname, "producer=", 9 ) ) - query_metadata( repo, producer_type, "producer", strchr( pname, '=' ) + 1 ); - else if ( !strncmp( pname, "transition=", 11 ) ) - query_metadata( repo, transition_type, "transition", strchr( pname, '=' ) + 1 ); - else - goto query_all; - } - else - { -query_all: - query_services( repo, consumer_type ); - query_services( repo, filter_type ); - query_services( repo, producer_type ); - query_services( repo, transition_type ); - fprintf( stderr, "# You can query the metadata for a specific service using:\n" - "# -query =\n" - "# where is one of: consumer, filter, producer, or transition.\n" ); - } - goto exit_factory; - } - else if ( !strcmp( argv[ i ], "-silent" ) ) - { - is_silent = 1; - } - else if ( !strcmp( argv[ i ], "-verbose" ) ) - { - mlt_log_set_level( MLT_LOG_VERBOSE ); - } - else if ( !strcmp( argv[ i ], "-version" ) || !strcmp( argv[ i ], "--version" ) ) - { - fprintf( stderr, "MLT inigo " VERSION "\n" - "Copyright (C) 2002-2008 Ushodaya Enterprises Limited\n" - "\n" - "This is free software; see the source for copying conditions. There is NO\n" - "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" - ); - goto exit_factory; - } - else if ( !strcmp( argv[ i ], "-debug" ) ) - { - mlt_log_set_level( MLT_LOG_DEBUG ); - } - } - - // Create profile if not set explicitly - if ( profile == NULL ) - profile = mlt_profile_init( NULL ); - - // Look for the consumer option - for ( i = 1; i < argc; i ++ ) - { - if ( !strcmp( argv[ i ], "-consumer" ) ) - { - consumer = create_consumer( profile, argv[ ++ i ] ); - if ( consumer ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer ); - while ( argv[ i + 1 ] != NULL && strstr( argv[ i + 1 ], "=" ) ) - mlt_properties_parse( properties, argv[ ++ i ] ); - } - } - } - - // If we have no consumer, default to sdl - if ( store == NULL && consumer == NULL ) - consumer = create_consumer( profile, NULL ); - - // Get inigo producer - if ( argc > 1 ) - inigo = mlt_factory_producer( profile, "inigo", &argv[ 1 ] ); - - // Set transport properties on consumer and produder - if ( consumer != NULL && inigo != NULL ) - { - mlt_properties_set_data( MLT_CONSUMER_PROPERTIES( consumer ), "transport_producer", inigo, 0, NULL, NULL ); - mlt_properties_set_data( MLT_PRODUCER_PROPERTIES( inigo ), "transport_consumer", consumer, 0, NULL, NULL ); - if ( is_progress ) - mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( consumer ), "progress", is_progress ); - if ( is_silent ) - mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( consumer ), "silent", is_silent ); - } - - if ( argc > 1 && inigo != NULL && mlt_producer_get_length( inigo ) > 0 ) - { - // Parse the arguments - for ( i = 1; i < argc; i ++ ) - { - if ( !strcmp( argv[ i ], "-serialise" ) ) - { - if ( store != stdout ) - i ++; - } - else - { - if ( store != NULL ) - fprintf( store, "%s\n", argv[ i ] ); - - i ++; - - while ( argv[ i ] != NULL && argv[ i ][ 0 ] != '-' ) - { - if ( store != NULL ) - fprintf( store, "%s\n", argv[ i ] ); - i += 1; - } - - i --; - } - } - - if ( consumer != NULL && store == NULL ) - { - // Get inigo's properties - mlt_properties inigo_props = MLT_PRODUCER_PROPERTIES( inigo ); - - // Get the last group - mlt_properties group = mlt_properties_get_data( inigo_props, "group", 0 ); - - // Apply group settings - mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer ); - mlt_properties_inherit( properties, group ); - - // Connect consumer to inigo - mlt_consumer_connect( consumer, MLT_PRODUCER_SERVICE( inigo ) ); - - // Start the consumer - mlt_consumer_start( consumer ); - - // Transport functionality - transport( inigo, consumer ); - - // Stop the consumer - mlt_consumer_stop( consumer ); - } - else if ( store != NULL && store != stdout && name != NULL ) - { - fprintf( stderr, "Project saved as %s.\n", name ); - fclose( store ); - } - } - else - { - fprintf( stderr, -"Usage: inigo [options] [producer [name=value]* ]+\n" -"Options:\n" -" -attach filter[:arg] [name=value]* Attach a filter to the output\n" -" -attach-cut filter[:arg] [name=value]* Attach a filter to a cut\n" -" -attach-track filter[:arg] [name=value]* Attach a filter to a track\n" -" -attach-clip filter[:arg] [name=value]* Attach a filter to a producer\n" -" -audio-track | -hide-video Add an audio-only track\n" -" -blank frames Add blank silence to a track\n" -" -consumer id[:arg] [name=value]* Set the consumer (sink)\n" -" -debug Set the logging level to debug\n" -" -filter filter[:arg] [name=value]* Add a filter to the current track\n" -" -group [name=value]* Apply properties repeatedly\n" -" -help Show this message\n" -" -join clips Join multiple clips into one cut\n" -" -mix length Add a mix between the last two cuts\n" -" -mixer transition Add a transition to the mix\n" -" -null-track | -hide-track Add a hidden track\n" -" -profile name Set the processing settings\n" -" -progress Display progress along with position\n" -" -remove Remove the most recent cut\n" -" -repeat times Repeat the last cut\n" -" -query List all of the registered services\n" -" -query \"consumers\" | \"consumer\"=id List consumers or show info about one\n" -" -query \"filters\" | \"filter\"=id List filters or show info about one\n" -" -query \"producers\" | \"producer\"=id List producers or show info about one\n" -" -query \"transitions\" | \"transition\"=id List transitions, show info about one\n" -" -serialise [filename] Write the commands to a text file\n" -" -silent Do not display position/transport\n" -" -split relative-frame Split the last cut into two cuts\n" -" -swap Rearrange the last two cuts\n" -" -track Add a track\n" -" -transition id[:arg] [name=value]* Add a transition\n" -" -verbose Set the logging level to verbose\n" -" -version Show the version and copyright\n" -" -video-track | -hide-audio Add a video-only track\n" -"For more help: \n" ); - } - - // Close the consumer - if ( consumer != NULL ) - mlt_consumer_close( consumer ); - - // Close the producer - if ( inigo != NULL ) - mlt_producer_close( inigo ); - - // Close the factory - mlt_profile_close( profile ); - -exit_factory: - - mlt_factory_close( ); - - return 0; -} diff --git a/src/inigo/io.c b/src/inigo/io.c deleted file mode 100644 index 77d13b9..0000000 --- a/src/inigo/io.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * io.c -- inigo input/output - * Copyright (C) 2002-2003 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* System header files */ -#include -#include -#include -#include -#include -#include -#include - -/* Application header files */ -#include "io.h" - -char *chomp( char *input ) -{ - if ( input != NULL ) - { - int length = strlen( input ); - if ( length && input[ length - 1 ] == '\n' ) - input[ length - 1 ] = '\0'; - if ( length > 1 && input[ length - 2 ] == '\r' ) - input[ length - 2 ] = '\0'; - } - return input; -} - -char *trim( char *input ) -{ - if ( input != NULL ) - { - int length = strlen( input ); - int first = 0; - while( first < length && isspace( input[ first ] ) ) - first ++; - memmove( input, input + first, length - first + 1 ); - length = length - first; - while ( length > 0 && isspace( input[ length - 1 ] ) ) - input[ -- length ] = '\0'; - } - return input; -} - -char *strip_quotes( char *input ) -{ - if ( input != NULL ) - { - char *ptr = strrchr( input, '\"' ); - if ( ptr != NULL ) - *ptr = '\0'; - if ( input[ 0 ] == '\"' ) - strcpy( input, input + 1 ); - } - return input; -} - -int *get_int( int *output, int use ) -{ - int *value = NULL; - char temp[ 132 ]; - *output = use; - if ( trim( chomp( fgets( temp, 132, stdin ) ) ) != NULL ) - { - if ( strcmp( temp, "" ) ) - *output = atoi( temp ); - value = output; - } - return value; -} - -/** This stores the previous settings -*/ - -static struct termios oldtty; -static int mode = 0; - -/** This is called automatically on application exit to restore the - previous tty settings. -*/ - -void term_exit(void) -{ - if ( mode == 1 ) - { - tcsetattr( 0, TCSANOW, &oldtty ); - mode = 0; - } -} - -/** Init terminal so that we can grab keys without blocking. -*/ - -void term_init( ) -{ - struct termios tty; - - tcgetattr( 0, &tty ); - oldtty = tty; - - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); - tty.c_oflag |= OPOST; - tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); - tty.c_cflag &= ~(CSIZE|PARENB); - tty.c_cflag |= CS8; - tty.c_cc[ VMIN ] = 1; - tty.c_cc[ VTIME ] = 0; - - tcsetattr( 0, TCSANOW, &tty ); - - mode = 1; - - atexit( term_exit ); -} - -/** Check for a keypress without blocking infinitely. - Returns: ASCII value of keypress or -1 if no keypress detected. -*/ - -int term_read( ) -{ - int n = 1; - unsigned char ch; - struct timeval tv; - fd_set rfds; - - FD_ZERO( &rfds ); - FD_SET( 0, &rfds ); - tv.tv_sec = 0; - tv.tv_usec = 40000; - n = select( 1, &rfds, NULL, NULL, &tv ); - if (n > 0) - { - n = read( 0, &ch, 1 ); - tcflush( 0, TCIFLUSH ); - if (n == 1) - return ch; - return n; - } - return -1; -} - -char get_keypress( ) -{ - char value = '\0'; - int pressed = 0; - - fflush( stdout ); - - term_init( ); - while ( ( pressed = term_read( ) ) == -1 ) ; - term_exit( ); - - value = (char)pressed; - - return value; -} - -void wait_for_any_key( char *message ) -{ - if ( message == NULL ) - printf( "Press any key to continue: " ); - else - printf( "%s", message ); - - get_keypress( ); - - printf( "\n\n" ); -} - -void beep( ) -{ - printf( "%c", 7 ); - fflush( stdout ); -} diff --git a/src/inigo/io.h b/src/inigo/io.h deleted file mode 100644 index 70387ba..0000000 --- a/src/inigo/io.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * io.h -- inigo input/output - * Copyright (C) 2002-2003 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _DEMO_IO_H_ -#define _DEMO_IO_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -extern char *chomp( char * ); -extern char *trim( char * ); -extern char *strip_quotes( char * ); -extern char *get_string( char *, int, char * ); -extern int *get_int( int *, int ); -extern void term_init( ); -extern int term_read( ); -extern void term_exit( ); -extern char get_keypress( ); -extern void wait_for_any_key( char * ); -extern void beep( ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/modules/Makefile b/src/modules/Makefile deleted file mode 100644 index fcbf3ea..0000000 --- a/src/modules/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -include ../../config.mak -include make.inc - -all clean depend: - list='$(SUBDIRS)'; \ - for subdir in $$list; do \ - if [ -f $$subdir/Makefile -a ! -f disable-$$subdir ] ; \ - then $(MAKE) -C $$subdir $@ || exit 1; \ - fi \ - done - -distclean: - rm -f consumers.dat filters.dat producers.dat transitions.dat make.inc; \ - list='$(SUBDIRS)'; \ - for subdir in $$list; do \ - if [ -f $$subdir/Makefile -a ! -f disable-$$subdir ] ; \ - then $(MAKE) -C $$subdir $@ || exit 1; \ - fi \ - done - -install: - list='$(SUBDIRS)'; \ - for subdir in $$list; do \ - if [ -f $$subdir/Makefile -a ! -f disable-$$subdir ] ; \ - then $(MAKE) DESTDIR=$(DESTDIR) -C $$subdir $@ || exit 1; \ - fi \ - done - -uninstall: - rm -rf "$(DESTDIR)$(libdir)/mlt" - diff --git a/src/modules/avformat/Makefile b/src/modules/avformat/Makefile deleted file mode 100644 index 7d88943..0000000 --- a/src/modules/avformat/Makefile +++ /dev/null @@ -1,86 +0,0 @@ -include ../../../config.mak - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -include config.mak - -LDFLAGS += -lavformat$(AVFORMAT_SUFFIX) -LDFLAGS += -lavcodec$(AVFORMAT_SUFFIX) -LDFLAGS += -lavutil$(AVFORMAT_SUFFIX) -LDFLAGS += -lavdevice$(AVFORMAT_SUFFIX) $(EXTRA_LIBS) - -ifndef CODECS -TARGET = ../libmltffmpeg$(LIBSUF) -else -TARGET = ../libmltavformat$(LIBSUF) -endif - -OBJS = factory.o - -ifdef FILTERS -OBJS += filter_avcolour_space.o \ - filter_avresample.o \ - filter_avdeinterlace.o -ifdef SWSCALE -OBJS += filter_swscale.o -endif -CFLAGS += -DFILTERS -endif - -ifdef CODECS -OBJS += producer_avformat.o \ - consumer_avformat.o -CFLAGS += -DCODECS -endif - -ifdef SWSCALE -CFLAGS += -DSWSCALE -LDFLAGS += -lswscale$(AVFORMAT_SUFFIX) -endif - -ifdef LOCAL_FFMPEG -LOCAL_FFMPEG_OBJS = ffmpeg/libavformat/libavformat$(AVFORMAT_SUFFIX) \ - ffmpeg/libavcodec/libavcodec$(AVFORMAT_SUFFIX) \ - ffmpeg/libavutil/libavutil$(AVFORMAT_SUFFIX) \ - ffmpeg/libavutil/libavdevice$(AVFORMAT_SUFFIX) -endif - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(LOCAL_FFMPEG_OBJS): - if [ $(LOCAL_FFMPEG) ] ; then \ - $(MAKE) -C ffmpeg ffmpeg ; \ - fi - -$(TARGET): $(OBJS) $(LOCAL_FFMPEG_OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - if [ $(LOCAL_FFMPEG) ] ; then $(MAKE) -C ffmpeg dep ; fi - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - if [ $(LOCAL_FFMPEG) ] ; then $(MAKE) -C ffmpeg distclean ; fi - rm -f .depend - -clean: - #if [ $(LOCAL_FFMPEG) ] ; then $(MAKE) -C ffmpeg clean ; fi - rm -f $(OBJS) ../libmltffmpeg$(LIBSUF) ../libmltavformat$(LIBSUF) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - install -d "$(DESTDIR)$(prefix)/share/mlt/avformat" - install -m 644 producer_avformat.yml "$(DESTDIR)$(prefix)/share/mlt/avformat" - -uninstall: - rm "$(DESTDIR)$(libdir)/mlt/libmltavformat$(LIBSUF)" 2> /dev/null || true - rm "$(DESTDIR)$(libdir)/mlt/libmltffmpeg$(LIBSUF)" 2> /dev/null || true - rm -rf "$(DESTDIR)$(prefix)/share/mlt/avformat" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/avformat/audioconvert.h b/src/modules/avformat/audioconvert.h deleted file mode 100644 index 4b76710..0000000 --- a/src/modules/avformat/audioconvert.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * audio conversion - * Copyright (c) 2006 Michael Niedermayer - * Copyright (c) 2008 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AUDIOCONVERT_H -#define AVCODEC_AUDIOCONVERT_H - -/** - * @file audioconvert.h - * Audio format conversion routines - */ - - -#include "avcodec.h" - - -/** - * Generate string corresponding to the sample format with - * number sample_fmt, or a header if sample_fmt is negative. - * - * @param[in] buf the buffer where to write the string - * @param[in] buf_size the size of buf - * @param[in] sample_fmt the number of the sample format to print the corresponding info string, or - * a negative value to print the corresponding header. - * Meaningful values for obtaining a sample format info vary from 0 to SAMPLE_FMT_NB -1. - */ -void avcodec_sample_fmt_string(char *buf, int buf_size, int sample_fmt); - -/** - * @return NULL on error - */ -const char *avcodec_get_sample_fmt_name(int sample_fmt); - -/** - * @return SAMPLE_FMT_NONE on error - */ -enum SampleFormat avcodec_get_sample_fmt(const char* name); - -/** - * @return NULL on error - */ -const char *avcodec_get_channel_name(int channel_id); - -/** - * Return description of channel layout - */ -void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout); - -/** - * Guess the channel layout - * @param nb_channels - * @param codec_id Codec identifier, or CODEC_ID_NONE if unknown - * @param fmt_name Format name, or NULL if unknown - * @return Channel layout mask - */ -int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name); - - -struct AVAudioConvert; -typedef struct AVAudioConvert AVAudioConvert; - -/** - * Create an audio sample format converter context - * @param out_fmt Output sample format - * @param out_channels Number of output channels - * @param in_fmt Input sample format - * @param in_channels Number of input channels - * @param[in] matrix Channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore. - * @param flags See FF_MM_xx - * @return NULL on error - */ -AVAudioConvert *av_audio_convert_alloc(enum SampleFormat out_fmt, int out_channels, - enum SampleFormat in_fmt, int in_channels, - const float *matrix, int flags); - -/** - * Free audio sample format converter context - */ -void av_audio_convert_free(AVAudioConvert *ctx); - -/** - * Convert between audio sample formats - * @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel. - * @param[in] out_stride distance between consecutive input samples (measured in bytes) - * @param[in] in array of input buffers for each channel - * @param[in] in_stride distance between consecutive output samples (measured in bytes) - * @param len length of audio frame size (measured in samples) - */ -int av_audio_convert(AVAudioConvert *ctx, - void * const out[6], const int out_stride[6], - const void * const in[6], const int in_stride[6], int len); - -#endif /* AVCODEC_AUDIOCONVERT_H */ diff --git a/src/modules/avformat/configure b/src/modules/avformat/configure deleted file mode 100755 index dc371a3..0000000 --- a/src/modules/avformat/configure +++ /dev/null @@ -1,168 +0,0 @@ -#!/bin/sh - -# Determine whether to recommend/use the HEAD revision of FFmpeg (unreleased) -# or a specific revision based upon whether the last digit of our version -# is even or odd. An odd MLT version number always represents unreleased. -svn_rev="17887" -micro_version=$(echo $version | cut -d . -f 3) -odd_version=$(($micro_version % 2)) -[ "$odd_version" -eq "1" ] && svn_rev="HEAD" - -if [ "$help" = "1" ] -then - cat << EOF -FFMPEG/avformat options: - - --avformat-svn - Obtain ffmpeg from Subversion - --avformat-svn-extra - Add extra configure options for --avformat-svn - --avformat-shared=path - Link against a shared installation of ffmpeg (default) - --avformat-static=path - Link against a static ffmpeg dev tree - --avformat-ldextra=libs - Provide additional libs to link with - --avformat-suffix=suff - Specify a custom suffix for an ffmpeg shared build - --avformat-swscale - Use ffmpeg libswcale instead of img_convert - --avformat-no-codecs - Disable the producer and consumer to avoid the FFmpeg codecs - --avformat-no-filters - Disable the filters to make a codecs+muxers-only plugin - - NOTE: The recommended version of FFmpeg is SVN-r$svn_rev. - -EOF - -else - targetos=$(uname -s) - case $targetos in - Darwin) - export LIBSUF=.dylib - ;; - Linux|FreeBSD) - export LIBSUF=.so - ;; - *) - ;; - esac - - bits=$(uname -m) - case $bits in - x86_64) - [ -d /usr/lib/lib64 ] && export LIBDIR=lib64 || export LIBDIR=lib - ;; - *) - export LIBDIR=lib - ;; - esac - - echo > config.mak - - export static_ffmpeg= - export shared_ffmpeg=$(pkg-config --variable=prefix libavformat) - export extra_libs= - export svn_ffmpeg= - export svn_ffmpeg_extra= - export avformat_suffix= - export swscale= - export codecs=true - export filters=true - - for i in "$@" - do - case $i in - --avformat-static=* ) static_ffmpeg="${i#--avformat-static=}" ;; - --avformat-shared=* ) shared_ffmpeg="${i#--avformat-shared=}" ;; - --avformat-ldextra=* ) extra_libs="${i#--avformat-ldextra=}" ;; - --avformat-svn ) svn_ffmpeg=true ;; - --avformat-svn-extra=* ) svn_ffmpeg_extra="${i#--avformat-svn-extra=}" ;; - --avformat-cvs ) svn_ffmpeg=true ;; - --avformat-suffix=* ) avformat_suffix="${i#--avformat-suffix=}" ;; - --avformat-swscale ) swscale=true ;; - --avformat-swscaler ) swscale=true ;; - --avformat-no-codecs ) codecs=false ;; - --avformat-no-filters ) filters=false ;; - esac - done - - if [ "$svn_ffmpeg" != "" ] - then - if [ "$gpl" = "true" ] - then - enable_gpl="--enable-gpl" - [ "$swscale" != "" ] && [ "$svn_rev" = "17887" ] && - enable_swscale="--enable-swscale" - fi - if [ ! -d "ffmpeg" ] - then - echo - echo "Checking out ffmpeg/avformat revision $svn_rev - no password required" - echo - if [ "$svn_rev" = "17887" ]; then - svn checkout -r $svn_rev svn://svn.mplayerhq.hu/ffmpeg/branches/0.5 ffmpeg - else - svn checkout -r $svn_rev svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg - fi - fi - [ -d "ffmpeg" ] && ( cd ffmpeg ; ./configure $enable_gpl $enable_swscale $svn_ffmpeg_extra ) - #[ ! -f "ffmpeg/ffmpeg.patch" ] && ( cd ffmpeg ; cp ../ffmpeg.patch . ; patch -p0 < ffmpeg.patch ) - echo "CFLAGS+=-I`pwd`/ffmpeg -I`pwd`/ffmpeg/libavformat -I`pwd`/ffmpeg/libavcodec -I`pwd`/ffmpeg/libavutil -I`pwd`/ffmpeg/libavdevice" >> config.mak - echo "LDFLAGS+=-L`pwd`/ffmpeg/libavformat -L`pwd`/ffmpeg/libavcodec -L`pwd`/ffmpeg/libavutil -L`pwd`/ffmpeg/libavdevice" >> config.mak - if [ "$swscale" != "" ] || [ "$svn_rev" = "HEAD" ] - then - echo "CFLAGS+=-I`pwd`/ffmpeg/libswscale" >> config.mak - echo "LDFLAGS+=-L`pwd`/ffmpeg/libswscale" >> config.mak - echo "SWSCALE=1" >> config.mak - fi - [ $targetos = "Darwin" ] && - echo "LDFLAGS+=-single_module" >> config.mak - echo "LOCAL_FFMPEG=1" >> config.mak - echo "LDFLAGS+=-Wl,-Bsymbolic" >> config.mak - extra_libs="$extra_libs -lz -lbz2" - elif [ "$static_ffmpeg" != "" ] - then - if [ -d "$static_ffmpeg" ] - then - echo "CFLAGS+=-I$static_ffmpeg/libavformat -I$static_ffmpeg/libavcodec -I$static_ffmpeg/libavutil -I$static_ffmpeg/libavdevice" >> config.mak - echo "LDFLAGS+=-L$static_ffmpeg/libavformat -L$static_ffmpeg/libavcodec -L$static_ffmpeg/libavutil -L$static_ffmpeg/libavdevice" >> config.mak - [ $targetos = "Darwin" ] && - echo "LDFLAGS+=-single_module" >> config.mak - if [ "$swscale" != "" ] - then - echo "CFLAGS+=-I$static_ffmpeg/libswscale" >> config.mak - echo "LDFLAGS+=-L$static_ffmpeg/libswscale" >> config.mak - echo "SWSCALE=1" >> config.mak - fi - echo "LDFLAGS+=-Wl,-Bsymbolic" >> config.mak - extra_libs="$extra_libs -lz" - else - echo "avformat: Invalid path specified: $static_ffmpeg" - touch ../disable-avformat - echo 0 - fi - elif [ "$shared_ffmpeg" != "" ] - then - echo "PREFIX=$shared_ffmpeg" >> config.mak - echo "CFLAGS+=$(pkg-config --cflags libavformat) $TMP_CFLAGS" >> config.mak - echo "LDFLAGS+=$(pkg-config --libs libavformat)" >> config.mak - [ -d "$shared_ffmpeg/include/ffmpeg/libavformat" ] && - echo "CFLAGS+=-I$shared_ffmpeg/include/ffmpeg/libavformat -I$shared_ffmpeg/include/ffmpeg/libavcodec" >> config.mak - [ -d "$shared_ffmpeg/include/libavformat" ] && - echo "CFLAGS+=-I$shared_ffmpeg/include/libavformat -I$shared_ffmpeg/include/libavcodec" >> config.mak - avcodec_version=$(pkg-config --modversion libavcodec) - if [ "$swscale" != "" ] || ( [ $(echo $avcodec_version | cut -d. -f1) -ge 52 ] && [ $(echo $avcodec_version | cut -d. -f2) -ge 21 ] ) - then - [ -d "$shared_ffmpeg/include/ffmpeg/libswscale" ] && - echo "CFLAGS+=-I$shared_ffmpeg/include/ffmpeg/libswscale" >> config.mak - [ -d "$shared_ffmpeg/include/libswscale" ] && - echo "CFLAGS+=-I$shared_ffmpeg/include/libswscale" >> config.mak - echo "SWSCALE=1" >> config.mak - fi - else - echo "avformat: No build environment found. " - echo " Try configuring mlt with --avformat-svn." - touch ../disable-avformat - exit 0 - fi - - echo "EXTRA_LIBS=$extra_libs" >> config.mak - echo "AVFORMAT_SUFFIX=$avformat_suffix" >> config.mak - [ "$codecs" = "true" ] && echo "CODECS=1" >> config.mak - [ "$filters" = "true" ] && echo "FILTERS=1" >> config.mak - exit 0 - -fi diff --git a/src/modules/avformat/consumer_avformat.c b/src/modules/avformat/consumer_avformat.c deleted file mode 100644 index bc83b0b..0000000 --- a/src/modules/avformat/consumer_avformat.c +++ /dev/null @@ -1,1371 +0,0 @@ -/* - * consumer_avformat.c -- an encoder based on avformat - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * Much code borrowed from ffmpeg.c: Copyright (c) 2000-2003 Fabrice Bellard - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// mlt Header files -#include -#include -#include - -// System header files -#include -#include -#include -#include -#include -#include -#include -#include - -// avformat header files -#include -#ifdef SWSCALE -#include -#endif -#include - -#if LIBAVUTIL_VERSION_INT < (50<<16) -#define PIX_FMT_RGB32 PIX_FMT_RGBA32 -#define PIX_FMT_YUYV422 PIX_FMT_YUV422 -#endif - -// -// This structure should be extended and made globally available in mlt -// - -typedef struct -{ - int16_t *buffer; - int size; - int used; - double time; - int frequency; - int channels; -} -*sample_fifo, sample_fifo_s; - -sample_fifo sample_fifo_init( int frequency, int channels ) -{ - sample_fifo this = calloc( 1, sizeof( sample_fifo_s ) ); - this->frequency = frequency; - this->channels = channels; - return this; -} - -// sample_fifo_clear and check are temporarily aborted (not working as intended) - -void sample_fifo_clear( sample_fifo this, double time ) -{ - int words = ( float )( time - this->time ) * this->frequency * this->channels; - if ( ( int )( ( float )time * 100 ) < ( int )( ( float )this->time * 100 ) && this->used > words && words > 0 ) - { - memmove( this->buffer, &this->buffer[ words ], ( this->used - words ) * sizeof( int16_t ) ); - this->used -= words; - this->time = time; - } - else if ( ( int )( ( float )time * 100 ) != ( int )( ( float )this->time * 100 ) ) - { - this->used = 0; - this->time = time; - } -} - -void sample_fifo_check( sample_fifo this, double time ) -{ - if ( this->used == 0 ) - { - if ( ( int )( ( float )time * 100 ) < ( int )( ( float )this->time * 100 ) ) - this->time = time; - } -} - -void sample_fifo_append( sample_fifo this, int16_t *samples, int count ) -{ - if ( ( this->size - this->used ) < count ) - { - this->size += count * 5; - this->buffer = realloc( this->buffer, this->size * sizeof( int16_t ) ); - } - - memcpy( &this->buffer[ this->used ], samples, count * sizeof( int16_t ) ); - this->used += count; -} - -int sample_fifo_used( sample_fifo this ) -{ - return this->used; -} - -int sample_fifo_fetch( sample_fifo this, int16_t *samples, int count ) -{ - if ( count > this->used ) - count = this->used; - - memcpy( samples, this->buffer, count * sizeof( int16_t ) ); - this->used -= count; - memmove( this->buffer, &this->buffer[ count ], this->used * sizeof( int16_t ) ); - - this->time += ( double )count / this->channels / this->frequency; - - return count; -} - -void sample_fifo_close( sample_fifo this ) -{ - free( this->buffer ); - free( this ); -} - -// Forward references. -static int consumer_start( mlt_consumer this ); -static int consumer_stop( mlt_consumer this ); -static int consumer_is_stopped( mlt_consumer this ); -static void *consumer_thread( void *arg ); -static void consumer_close( mlt_consumer this ); - -/** Initialise the dv consumer. -*/ - -mlt_consumer consumer_avformat_init( mlt_profile profile, char *arg ) -{ - // Allocate the consumer - mlt_consumer this = mlt_consumer_new( profile ); - - // If memory allocated and initialises without error - if ( this != NULL ) - { - // Get properties from the consumer - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Assign close callback - this->close = consumer_close; - - // Interpret the argument - if ( arg != NULL ) - mlt_properties_set( properties, "target", arg ); - - // sample and frame queue - mlt_properties_set_data( properties, "frame_queue", mlt_deque_init( ), 0, ( mlt_destructor )mlt_deque_close, NULL ); - - // Audio options not fully handled by AVOptions -#define QSCALE_NONE (-99999) - mlt_properties_set_int( properties, "aq", QSCALE_NONE ); - - // Video options not fully handled by AVOptions - mlt_properties_set_int( properties, "dc", 8 ); - - // Muxer options not fully handled by AVOptions - mlt_properties_set_double( properties, "muxdelay", 0.7 ); - mlt_properties_set_double( properties, "muxpreload", 0.5 ); - - // Ensure termination at end of the stream - mlt_properties_set_int( properties, "terminate_on_pause", 1 ); - - // Default to separate processing threads for producer and consumer with no frame dropping! - mlt_properties_set_int( properties, "real_time", -1 ); - mlt_properties_set_int( properties, "prefill", 1 ); - - // Set up start/stop/terminated callbacks - this->start = consumer_start; - this->stop = consumer_stop; - this->is_stopped = consumer_is_stopped; - } - - // Return this - return this; -} - -/** Start the consumer. -*/ - -static int consumer_start( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - int error = 0; - - // Report information about available muxers and codecs as YAML Tiny - char *s = mlt_properties_get( properties, "f" ); - if ( s && strcmp( s, "list" ) == 0 ) - { - fprintf( stderr, "---\nformats:\n" ); - AVOutputFormat *format = NULL; - while ( ( format = av_oformat_next( format ) ) ) - fprintf( stderr, " - %s\n", format->name ); - fprintf( stderr, "...\n" ); - error = 1; - } - s = mlt_properties_get( properties, "acodec" ); - if ( s && strcmp( s, "list" ) == 0 ) - { - fprintf( stderr, "---\naudio_codecs:\n" ); - AVCodec *codec = NULL; - while ( ( codec = av_codec_next( codec ) ) ) - if ( codec->encode && codec->type == CODEC_TYPE_AUDIO ) - fprintf( stderr, " - %s\n", codec->name ); - fprintf( stderr, "...\n" ); - error = 1; - } - s = mlt_properties_get( properties, "vcodec" ); - if ( s && strcmp( s, "list" ) == 0 ) - { - fprintf( stderr, "---\nvideo_codecs:\n" ); - AVCodec *codec = NULL; - while ( ( codec = av_codec_next( codec ) ) ) - if ( codec->encode && codec->type == CODEC_TYPE_VIDEO ) - fprintf( stderr, " - %s\n", codec->name ); - fprintf( stderr, "...\n" ); - error = 1; - } - - // Check that we're not already running - if ( !error && !mlt_properties_get_int( properties, "running" ) ) - { - // Allocate a thread - pthread_t *thread = calloc( 1, sizeof( pthread_t ) ); - - // Get the width and height - int width = mlt_properties_get_int( properties, "width" ); - int height = mlt_properties_get_int( properties, "height" ); - - // Obtain the size property - char *size = mlt_properties_get( properties, "s" ); - - // Interpret it - if ( size != NULL ) - { - int tw, th; - if ( sscanf( size, "%dx%d", &tw, &th ) == 2 && tw > 0 && th > 0 ) - { - width = tw; - height = th; - } - else - { - fprintf( stderr, "%s: Invalid size property %s - ignoring.\n", __FILE__, size ); - } - } - - // Now ensure we honour the multiple of two requested by libavformat - width = ( width / 2 ) * 2; - height = ( height / 2 ) * 2; - mlt_properties_set_int( properties, "width", width ); - mlt_properties_set_int( properties, "height", height ); - - // We need to set these on the profile as well because the s property is - // an alias to mlt properties that correspond to profile settings. - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - if ( profile ) - { - profile->width = width; - profile->height = height; - } - - // Handle the ffmpeg command line "-r" property for frame rate - if ( mlt_properties_get( properties, "r" ) ) - { - double frame_rate = mlt_properties_get_double( properties, "r" ); - AVRational rational = av_d2q( frame_rate, 255 ); - mlt_properties_set_int( properties, "frame_rate_num", rational.num ); - mlt_properties_set_int( properties, "frame_rate_den", rational.den ); - if ( profile ) - { - profile->frame_rate_num = rational.num; - profile->frame_rate_den = rational.den; - mlt_properties_set_double( properties, "fps", mlt_profile_fps( profile ) ); - } - } - - // Apply AVOptions that are synonyms for standard mlt_consumer options - if ( mlt_properties_get( properties, "ac" ) ) - mlt_properties_set_int( properties, "channels", mlt_properties_get_int( properties, "ac" ) ); - if ( mlt_properties_get( properties, "ar" ) ) - mlt_properties_set_int( properties, "frequency", mlt_properties_get_int( properties, "ar" ) ); - - // Assign the thread to properties - mlt_properties_set_data( properties, "thread", thread, sizeof( pthread_t ), free, NULL ); - - // Set the running state - mlt_properties_set_int( properties, "running", 1 ); - - // Create the thread - pthread_create( thread, NULL, consumer_thread, this ); - } - return error; -} - -/** Stop the consumer. -*/ - -static int consumer_stop( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Check that we're running - if ( mlt_properties_get_int( properties, "running" ) ) - { - // Get the thread - pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL ); - - // Stop the thread - mlt_properties_set_int( properties, "running", 0 ); - - // Wait for termination - pthread_join( *thread, NULL ); - } - - return 0; -} - -/** Determine if the consumer is stopped. -*/ - -static int consumer_is_stopped( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - return !mlt_properties_get_int( properties, "running" ); -} - -/** Process properties as AVOptions and apply to AV context obj -*/ - -static void apply_properties( void *obj, mlt_properties properties, int flags ) -{ - int i; - int count = mlt_properties_count( properties ); - for ( i = 0; i < count; i++ ) - { - const char *opt_name = mlt_properties_get_name( properties, i ); - const AVOption *opt = av_find_opt( obj, opt_name, NULL, flags, flags ); - if ( opt != NULL ) -#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(7<<8)+0) - av_set_string3( obj, opt_name, mlt_properties_get( properties, opt_name), 0, NULL ); -#elif LIBAVCODEC_VERSION_INT >= ((51<<16)+(59<<8)+0) - av_set_string2( obj, opt_name, mlt_properties_get( properties, opt_name), 0 ); -#else - av_set_string( obj, opt_name, mlt_properties_get( properties, opt_name) ); -#endif - } -} - -/** Add an audio output stream -*/ - -static AVStream *add_audio_stream( mlt_consumer this, AVFormatContext *oc, int codec_id ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Create a new stream - AVStream *st = av_new_stream( oc, 1 ); - - // If created, then initialise from properties - if ( st != NULL ) - { - AVCodecContext *c = st->codec; - - // Establish defaults from AVOptions - avcodec_get_context_defaults2( c, CODEC_TYPE_AUDIO ); - - c->codec_id = codec_id; - c->codec_type = CODEC_TYPE_AUDIO; - - // Setup multi-threading - int thread_count = mlt_properties_get_int( properties, "threads" ); - if ( thread_count == 0 && getenv( "MLT_AVFORMAT_THREADS" ) ) - thread_count = atoi( getenv( "MLT_AVFORMAT_THREADS" ) ); - if ( thread_count > 1 ) - avcodec_thread_init( c, thread_count ); - - if (oc->oformat->flags & AVFMT_GLOBALHEADER) - c->flags |= CODEC_FLAG_GLOBAL_HEADER; - - // Allow the user to override the audio fourcc - if ( mlt_properties_get( properties, "atag" ) ) - { - char *tail = NULL; - char *arg = mlt_properties_get( properties, "atag" ); - int tag = strtol( arg, &tail, 0); - if( !tail || *tail ) - tag = arg[ 0 ] + ( arg[ 1 ] << 8 ) + ( arg[ 2 ] << 16 ) + ( arg[ 3 ] << 24 ); - c->codec_tag = tag; - } - - // Process properties as AVOptions - apply_properties( c, properties, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM ); - - int audio_qscale = mlt_properties_get_int( properties, "aq" ); - if ( audio_qscale > QSCALE_NONE ) - { - c->flags |= CODEC_FLAG_QSCALE; - c->global_quality = st->quality = FF_QP2LAMBDA * audio_qscale; - } - - // Set parameters controlled by MLT - c->sample_rate = mlt_properties_get_int( properties, "frequency" ); - c->channels = mlt_properties_get_int( properties, "channels" ); - - if ( mlt_properties_get( properties, "alang" ) != NULL ) - strncpy( st->language, mlt_properties_get( properties, "alang" ), sizeof( st->language ) ); - } - else - { - fprintf( stderr, "%s: Could not allocate a stream for audio\n", __FILE__ ); - } - - return st; -} - -static int open_audio( AVFormatContext *oc, AVStream *st, int audio_outbuf_size ) -{ - // We will return the audio input size from here - int audio_input_frame_size = 0; - - // Get the context - AVCodecContext *c = st->codec; - - // Find the encoder - AVCodec *codec = avcodec_find_encoder( c->codec_id ); - - // Continue if codec found and we can open it - if ( codec != NULL && avcodec_open( c, codec ) >= 0 ) - { - // ugly hack for PCM codecs (will be removed ASAP with new PCM - // support to compute the input frame size in samples - if ( c->frame_size <= 1 ) - { - audio_input_frame_size = audio_outbuf_size / c->channels; - switch(st->codec->codec_id) - { - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_U16BE: - audio_input_frame_size >>= 1; - break; - default: - break; - } - } - else - { - audio_input_frame_size = c->frame_size; - } - - // Some formats want stream headers to be seperate (hmm) - if( !strcmp( oc->oformat->name, "mp4" ) || - !strcmp( oc->oformat->name, "mov" ) || - !strcmp( oc->oformat->name, "3gp" ) ) - c->flags |= CODEC_FLAG_GLOBAL_HEADER; - } - else - { - fprintf( stderr, "%s: Unable to encode audio - disabling audio output.\n", __FILE__ ); - } - - return audio_input_frame_size; -} - -static void close_audio( AVFormatContext *oc, AVStream *st ) -{ - avcodec_close( st->codec ); -} - -/** Add a video output stream -*/ - -static AVStream *add_video_stream( mlt_consumer this, AVFormatContext *oc, int codec_id ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Create a new stream - AVStream *st = av_new_stream( oc, 0 ); - - if ( st != NULL ) - { - char *pix_fmt = mlt_properties_get( properties, "pix_fmt" ); - AVCodecContext *c = st->codec; - - // Establish defaults from AVOptions - avcodec_get_context_defaults2( c, CODEC_TYPE_VIDEO ); - - c->codec_id = codec_id; - c->codec_type = CODEC_TYPE_VIDEO; - - // Setup multi-threading - int thread_count = mlt_properties_get_int( properties, "threads" ); - if ( thread_count == 0 && getenv( "MLT_AVFORMAT_THREADS" ) ) - thread_count = atoi( getenv( "MLT_AVFORMAT_THREADS" ) ); - if ( thread_count > 1 ) - avcodec_thread_init( c, thread_count ); - - // Process properties as AVOptions - apply_properties( c, properties, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM ); - - // Set options controlled by MLT - c->width = mlt_properties_get_int( properties, "width" ); - c->height = mlt_properties_get_int( properties, "height" ); - c->time_base.num = mlt_properties_get_int( properties, "frame_rate_den" ); - c->time_base.den = mlt_properties_get_int( properties, "frame_rate_num" ); - if ( st->time_base.den == 0 ) - st->time_base = c->time_base; - c->pix_fmt = pix_fmt ? avcodec_get_pix_fmt( pix_fmt ) : PIX_FMT_YUV420P; - - if ( mlt_properties_get( properties, "aspect" ) ) - { - // "-aspect" on ffmpeg command line is display aspect ratio - double ar = mlt_properties_get_double( properties, "aspect" ); - AVRational rational = av_d2q( ar, 255 ); - - // Update the profile and properties as well since this is an alias - // for mlt properties that correspond to profile settings - mlt_properties_set_int( properties, "display_aspect_num", rational.num ); - mlt_properties_set_int( properties, "display_aspect_den", rational.den ); - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( this ) ); - if ( profile ) - { - profile->display_aspect_num = rational.num; - profile->display_aspect_den = rational.den; - mlt_properties_set_double( properties, "display_ratio", mlt_profile_dar( profile ) ); - } - - // Now compute the sample aspect ratio - rational = av_d2q( ar * c->height / c->width, 255 ); - c->sample_aspect_ratio = rational; - // Update the profile and properties as well since this is an alias - // for mlt properties that correspond to profile settings - mlt_properties_set_int( properties, "sample_aspect_num", rational.num ); - mlt_properties_set_int( properties, "sample_aspect_den", rational.den ); - if ( profile ) - { - profile->sample_aspect_num = rational.num; - profile->sample_aspect_den = rational.den; - mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) ); - } - } - else - { - c->sample_aspect_ratio.num = mlt_properties_get_int( properties, "sample_aspect_num" ); - c->sample_aspect_ratio.den = mlt_properties_get_int( properties, "sample_aspect_den" ); - } -#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(21<<8)+0) - st->sample_aspect_ratio = c->sample_aspect_ratio; -#endif - - if ( mlt_properties_get_double( properties, "qscale" ) > 0 ) - { - c->flags |= CODEC_FLAG_QSCALE; - st->quality = FF_QP2LAMBDA * mlt_properties_get_double( properties, "qscale" ); - } - - // Allow the user to override the video fourcc - if ( mlt_properties_get( properties, "vtag" ) ) - { - char *tail = NULL; - const char *arg = mlt_properties_get( properties, "vtag" ); - int tag = strtol( arg, &tail, 0); - if( !tail || *tail ) - tag = arg[ 0 ] + ( arg[ 1 ] << 8 ) + ( arg[ 2 ] << 16 ) + ( arg[ 3 ] << 24 ); - c->codec_tag = tag; - } - - // Some formats want stream headers to be seperate - if ( oc->oformat->flags & AVFMT_GLOBALHEADER ) - c->flags |= CODEC_FLAG_GLOBAL_HEADER; - - // Translate these standard mlt consumer properties to ffmpeg - if ( mlt_properties_get_int( properties, "progressive" ) == 0 && - mlt_properties_get_int( properties, "deinterlace" ) == 0 ) - { - if ( ! mlt_properties_get( properties, "ildct" ) || mlt_properties_get_int( properties, "ildct" ) ) - c->flags |= CODEC_FLAG_INTERLACED_DCT; - if ( ! mlt_properties_get( properties, "ilme" ) || mlt_properties_get_int( properties, "ilme" ) ) - c->flags |= CODEC_FLAG_INTERLACED_ME; - } - - // parse the ratecontrol override string - int i; - char *rc_override = mlt_properties_get( properties, "rc_override" ); - for ( i = 0; rc_override; i++ ) - { - int start, end, q; - int e = sscanf( rc_override, "%d,%d,%d", &start, &end, &q ); - if ( e != 3 ) - fprintf( stderr, "%s: Error parsing rc_override\n", __FILE__ ); - c->rc_override = av_realloc( c->rc_override, sizeof( RcOverride ) * ( i + 1 ) ); - c->rc_override[i].start_frame = start; - c->rc_override[i].end_frame = end; - if ( q > 0 ) - { - c->rc_override[i].qscale = q; - c->rc_override[i].quality_factor = 1.0; - } - else - { - c->rc_override[i].qscale = 0; - c->rc_override[i].quality_factor = -q / 100.0; - } - rc_override = strchr( rc_override, '/' ); - if ( rc_override ) - rc_override++; - } - c->rc_override_count = i; - if ( !c->rc_initial_buffer_occupancy ) - c->rc_initial_buffer_occupancy = c->rc_buffer_size * 3/4; - c->intra_dc_precision = mlt_properties_get_int( properties, "dc" ) - 8; - - // Setup dual-pass - i = mlt_properties_get_int( properties, "pass" ); - if ( i == 1 ) - c->flags |= CODEC_FLAG_PASS1; - else if ( i == 2 ) - c->flags |= CODEC_FLAG_PASS2; - if ( codec_id != CODEC_ID_H264 && ( c->flags & ( CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2 ) ) ) - { - char logfilename[1024]; - FILE *f; - int size; - char *logbuffer; - - snprintf( logfilename, sizeof(logfilename), "%s_2pass.log", - mlt_properties_get( properties, "passlogfile" ) ? mlt_properties_get( properties, "passlogfile" ) : mlt_properties_get( properties, "target" ) ); - if ( c->flags & CODEC_FLAG_PASS1 ) - { - f = fopen( logfilename, "w" ); - if ( !f ) - perror( logfilename ); - else - mlt_properties_set_data( properties, "_logfile", f, 0, ( mlt_destructor )fclose, NULL ); - } - else - { - /* read the log file */ - f = fopen( logfilename, "r" ); - if ( !f ) - { - perror(logfilename); - } - else - { - mlt_properties_set( properties, "_logfilename", logfilename ); - fseek( f, 0, SEEK_END ); - size = ftell( f ); - fseek( f, 0, SEEK_SET ); - logbuffer = av_malloc( size + 1 ); - if ( !logbuffer ) - fprintf( stderr, "%s: Could not allocate log buffer\n", __FILE__ ); - else - { - size = fread( logbuffer, 1, size, f ); - fclose( f ); - logbuffer[size] = '\0'; - c->stats_in = logbuffer; - mlt_properties_set_data( properties, "_logbuffer", logbuffer, 0, ( mlt_destructor )av_free, NULL ); - } - } - } - } - } - else - { - fprintf( stderr, "%s: Could not allocate a stream for video\n", __FILE__ ); - } - - return st; -} - -static AVFrame *alloc_picture( int pix_fmt, int width, int height ) -{ - // Allocate a frame - AVFrame *picture = avcodec_alloc_frame(); - - // Determine size of the - int size = avpicture_get_size(pix_fmt, width, height); - - // Allocate the picture buf - uint8_t *picture_buf = av_malloc(size); - - // If we have both, then fill the image - if ( picture != NULL && picture_buf != NULL ) - { - // Fill the frame with the allocated buffer - avpicture_fill( (AVPicture *)picture, picture_buf, pix_fmt, width, height); - } - else - { - // Something failed - clean up what we can - av_free( picture ); - av_free( picture_buf ); - picture = NULL; - } - - return picture; -} - -static int open_video(AVFormatContext *oc, AVStream *st) -{ - // Get the codec - AVCodecContext *video_enc = st->codec; - - // find the video encoder - AVCodec *codec = avcodec_find_encoder( video_enc->codec_id ); - - if( codec && codec->pix_fmts ) - { - const enum PixelFormat *p = codec->pix_fmts; - for( ; *p!=-1; p++ ) - { - if( *p == video_enc->pix_fmt ) - break; - } - if( *p == -1 ) - video_enc->pix_fmt = codec->pix_fmts[ 0 ]; - } - - // Open the codec safely - return codec != NULL && avcodec_open( video_enc, codec ) >= 0; -} - -void close_video(AVFormatContext *oc, AVStream *st) -{ - avcodec_close(st->codec); -} - -static inline long time_difference( struct timeval *time1 ) -{ - struct timeval time2; - gettimeofday( &time2, NULL ); - return time2.tv_sec * 1000000 + time2.tv_usec - time1->tv_sec * 1000000 - time1->tv_usec; -} - -/** The main thread - the argument is simply the consumer. -*/ - -static void *consumer_thread( void *arg ) -{ - // Map the argument to the object - mlt_consumer this = arg; - - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Get the terminate on pause property - int terminate_on_pause = mlt_properties_get_int( properties, "terminate_on_pause" ); - int terminated = 0; - - // Determine if feed is slow (for realtime stuff) - int real_time_output = mlt_properties_get_int( properties, "real_time" ); - - // Time structures - struct timeval ante; - - // Get the frame rate - double fps = mlt_properties_get_double( properties, "fps" ); - - // Get width and height - int width = mlt_properties_get_int( properties, "width" ); - int height = mlt_properties_get_int( properties, "height" ); - int img_width = width; - int img_height = height; - - // Get default audio properties - mlt_audio_format aud_fmt = mlt_audio_pcm; - int channels = mlt_properties_get_int( properties, "channels" ); - int frequency = mlt_properties_get_int( properties, "frequency" ); - int16_t *pcm = NULL; - int samples = 0; - - // AVFormat audio buffer and frame size - int audio_outbuf_size = 10000; - uint8_t *audio_outbuf = av_malloc( audio_outbuf_size ); - int audio_input_frame_size = 0; - - // AVFormat video buffer and frame count - int frame_count = 0; - int video_outbuf_size = ( 1024 * 1024 ); - uint8_t *video_outbuf = av_malloc( video_outbuf_size ); - - // Used for the frame properties - mlt_frame frame = NULL; - mlt_properties frame_properties = NULL; - - // Get the queues - mlt_deque queue = mlt_properties_get_data( properties, "frame_queue", NULL ); - sample_fifo fifo = mlt_properties_get_data( properties, "sample_fifo", NULL ); - - // Need two av pictures for converting - AVFrame *output = NULL; - AVFrame *input = alloc_picture( PIX_FMT_YUYV422, width, height ); - - // For receiving images from an mlt_frame - uint8_t *image; - mlt_image_format img_fmt = mlt_image_yuv422; - - // For receiving audio samples back from the fifo - int16_t *buffer = av_malloc( 48000 * 2 ); - int count = 0; - - // Allocate the context - AVFormatContext *oc = av_alloc_format_context( ); - - // Streams - AVStream *audio_st = NULL; - AVStream *video_st = NULL; - - // Time stamps - double audio_pts = 0; - double video_pts = 0; - - // Loop variable - int i; - - // Frames despatched - long int frames = 0; - long int total_time = 0; - - // Determine the format - AVOutputFormat *fmt = NULL; - const char *filename = mlt_properties_get( properties, "target" ); - char *format = mlt_properties_get( properties, "f" ); - char *vcodec = mlt_properties_get( properties, "vcodec" ); - char *acodec = mlt_properties_get( properties, "acodec" ); - - // Used to store and override codec ids - int audio_codec_id; - int video_codec_id; - - // Check for user selected format first - if ( format != NULL ) - fmt = guess_format( format, NULL, NULL ); - - // Otherwise check on the filename - if ( fmt == NULL && filename != NULL ) - fmt = guess_format( NULL, filename, NULL ); - - // Otherwise default to mpeg - if ( fmt == NULL ) - fmt = guess_format( "mpeg", NULL, NULL ); - - // We need a filename - default to stdout? - if ( filename == NULL || !strcmp( filename, "" ) ) - filename = "pipe:"; - - // Get the codec ids selected - audio_codec_id = fmt->audio_codec; - video_codec_id = fmt->video_codec; - - // Check for audio codec overides - if ( ( acodec && strcmp( "acodec", "none" ) == 0 ) || mlt_properties_get_int( properties, "an" ) ) - audio_codec_id = CODEC_ID_NONE; - else if ( acodec ) - { - AVCodec *p = avcodec_find_encoder_by_name( acodec ); - if ( p != NULL ) - audio_codec_id = p->id; - else - fprintf( stderr, "%s: audio codec %s unrecognised - ignoring\n", __FILE__, acodec ); - } - - // Check for video codec overides - if ( ( vcodec && strcmp( "vcodec", "none" ) == 0 ) || mlt_properties_get_int( properties, "vn" ) ) - video_codec_id = CODEC_ID_NONE; - else if ( vcodec ) - { - AVCodec *p = avcodec_find_encoder_by_name( vcodec ); - if ( p != NULL ) - video_codec_id = p->id; - else - fprintf( stderr, "%s: video codec %s unrecognised - ignoring\n", __FILE__, vcodec ); - } - - // Write metadata - char *tmp = NULL; - int metavalue; - - tmp = mlt_properties_get( properties, "meta.attr.title.markup"); - if (tmp != NULL) snprintf( oc->title, sizeof(oc->title), "%s", tmp ); - - tmp = mlt_properties_get( properties, "meta.attr.comment.markup"); - if (tmp != NULL) snprintf( oc->comment, sizeof(oc->comment), "%s", tmp ); - - tmp = mlt_properties_get( properties, "meta.attr.author.markup"); - if (tmp != NULL) snprintf( oc->author, sizeof(oc->author), "%s", tmp ); - - tmp = mlt_properties_get( properties, "meta.attr.copyright.markup"); - if (tmp != NULL) snprintf( oc->copyright, sizeof(oc->copyright), "%s", tmp ); - - tmp = mlt_properties_get( properties, "meta.attr.album.markup"); - if (tmp != NULL) snprintf( oc->album, sizeof(oc->album), "%s", tmp ); - - metavalue = mlt_properties_get_int( properties, "meta.attr.year.markup"); - if (metavalue != 0) oc->year = metavalue; - - metavalue = mlt_properties_get_int( properties, "meta.attr.track.markup"); - if (metavalue != 0) oc->track = metavalue; - - oc->oformat = fmt; - snprintf( oc->filename, sizeof(oc->filename), "%s", filename ); - - // Add audio and video streams - if ( video_codec_id != CODEC_ID_NONE ) - video_st = add_video_stream( this, oc, video_codec_id ); - if ( audio_codec_id != CODEC_ID_NONE ) - audio_st = add_audio_stream( this, oc, audio_codec_id ); - - // Set the parameters (even though we have none...) - if ( av_set_parameters(oc, NULL) >= 0 ) - { - oc->preload = ( int )( mlt_properties_get_double( properties, "muxpreload" ) * AV_TIME_BASE ); - oc->max_delay= ( int )( mlt_properties_get_double( properties, "muxdelay" ) * AV_TIME_BASE ); - - // Process properties as AVOptions - apply_properties( oc, properties, AV_OPT_FLAG_ENCODING_PARAM ); - - if ( video_st && !open_video( oc, video_st ) ) - video_st = NULL; - if ( audio_st ) - audio_input_frame_size = open_audio( oc, audio_st, audio_outbuf_size ); - - // Open the output file, if needed - if ( !( fmt->flags & AVFMT_NOFILE ) ) - { - if ( url_fopen( &oc->pb, filename, URL_WRONLY ) < 0 ) - { - fprintf( stderr, "%s: Could not open '%s'\n", __FILE__, filename ); - mlt_properties_set_int( properties, "running", 0 ); - } - } - - // Write the stream header, if any - if ( mlt_properties_get_int( properties, "running" ) ) - av_write_header( oc ); - } - else - { - fprintf( stderr, "%s: Invalid output format parameters\n", __FILE__ ); - mlt_properties_set_int( properties, "running", 0 ); - } - - // Allocate picture - if ( video_st ) - output = alloc_picture( video_st->codec->pix_fmt, width, height ); - - // Last check - need at least one stream - if ( audio_st == NULL && video_st == NULL ) - mlt_properties_set_int( properties, "running", 0 ); - - // Get the starting time (can ignore the times above) - gettimeofday( &ante, NULL ); - - // Loop while running - while( mlt_properties_get_int( properties, "running" ) && !terminated ) - { - // Get the frame - frame = mlt_consumer_rt_frame( this ); - - // Check that we have a frame to work with - if ( frame != NULL ) - { - // Increment frames despatched - frames ++; - - // Default audio args - frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Check for the terminated condition - terminated = terminate_on_pause && mlt_properties_get_double( frame_properties, "_speed" ) == 0.0; - - // Get audio and append to the fifo - if ( !terminated && audio_st ) - { - samples = mlt_sample_calculator( fps, frequency, count ++ ); - mlt_frame_get_audio( frame, &pcm, &aud_fmt, &frequency, &channels, &samples ); - - // Create the fifo if we don't have one - if ( fifo == NULL ) - { - fifo = sample_fifo_init( frequency, channels ); - mlt_properties_set_data( properties, "sample_fifo", fifo, 0, ( mlt_destructor )sample_fifo_close, NULL ); - } - - if ( mlt_properties_get_double( frame_properties, "_speed" ) != 1.0 ) - memset( pcm, 0, samples * channels * 2 ); - - // Append the samples - sample_fifo_append( fifo, pcm, samples * channels ); - total_time += ( samples * 1000000 ) / frequency; - } - - // Encode the image - if ( !terminated && video_st ) - mlt_deque_push_back( queue, frame ); - else - mlt_frame_close( frame ); - } - - // While we have stuff to process, process... - while ( 1 ) - { - if (audio_st) - audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den; - else - audio_pts = 0.0; - - if (video_st) - video_pts = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den; - else - video_pts = 0.0; - - // Write interleaved audio and video frames - if ( !video_st || ( video_st && audio_st && audio_pts < video_pts ) ) - { - if ( channels * audio_input_frame_size < sample_fifo_used( fifo ) ) - { - AVCodecContext *c; - AVPacket pkt; - av_init_packet( &pkt ); - - c = audio_st->codec; - - sample_fifo_fetch( fifo, buffer, channels * audio_input_frame_size ); - - pkt.size = avcodec_encode_audio( c, audio_outbuf, audio_outbuf_size, buffer ); - // Write the compressed frame in the media file - if ( c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE ) - pkt.pts = av_rescale_q( c->coded_frame->pts, c->time_base, audio_st->time_base ); - pkt.flags |= PKT_FLAG_KEY; - pkt.stream_index= audio_st->index; - pkt.data= audio_outbuf; - - if ( pkt.size ) - if ( av_interleaved_write_frame( oc, &pkt ) != 0) - fprintf( stderr, "%s: Error while writing audio frame\n", __FILE__ ); - - audio_pts += c->frame_size; - } - else - { - break; - } - } - else if ( video_st ) - { - if ( mlt_deque_count( queue ) ) - { - int out_size, ret; - AVCodecContext *c; - - frame = mlt_deque_pop_front( queue ); - frame_properties = MLT_FRAME_PROPERTIES( frame ); - - c = video_st->codec; - - if ( mlt_properties_get_int( frame_properties, "rendered" ) ) - { - int i = 0; - int j = 0; - uint8_t *p; - uint8_t *q; - - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); - - mlt_frame_get_image( frame, &image, &img_fmt, &img_width, &img_height, 0 ); - - q = image; - - // Convert the mlt frame to an AVPicture - for ( i = 0; i < height; i ++ ) - { - p = input->data[ 0 ] + i * input->linesize[ 0 ]; - j = width; - while( j -- ) - { - *p ++ = *q ++; - *p ++ = *q ++; - } - } - - // Do the colour space conversion -#ifdef SWSCALE - struct SwsContext *context = sws_getContext( width, height, PIX_FMT_YUYV422, - width, height, video_st->codec->pix_fmt, SWS_FAST_BILINEAR, NULL, NULL, NULL); - sws_scale( context, input->data, input->linesize, 0, height, - output->data, output->linesize); - sws_freeContext( context ); -#else - img_convert( ( AVPicture * )output, video_st->codec->pix_fmt, ( AVPicture * )input, PIX_FMT_YUYV422, width, height ); -#endif - - // Apply the alpha if applicable - if ( video_st->codec->pix_fmt == PIX_FMT_RGB32 ) - { - uint8_t *alpha = mlt_frame_get_alpha_mask( frame ); - register int n; - - for ( i = 0; i < height; i ++ ) - { - n = ( width + 7 ) / 8; - p = output->data[ 0 ] + i * output->linesize[ 0 ]; - - #ifndef __DARWIN__ - p += 3; - #endif - - switch( width % 8 ) - { - case 0: do { *p = *alpha++; p += 4; - case 7: *p = *alpha++; p += 4; - case 6: *p = *alpha++; p += 4; - case 5: *p = *alpha++; p += 4; - case 4: *p = *alpha++; p += 4; - case 3: *p = *alpha++; p += 4; - case 2: *p = *alpha++; p += 4; - case 1: *p = *alpha++; p += 4; - } - while( --n ); - } - } - } - } - - if (oc->oformat->flags & AVFMT_RAWPICTURE) - { - // raw video case. The API will change slightly in the near future for that - AVPacket pkt; - av_init_packet(&pkt); - - pkt.flags |= PKT_FLAG_KEY; - pkt.stream_index= video_st->index; - pkt.data= (uint8_t *)output; - pkt.size= sizeof(AVPicture); - - ret = av_write_frame(oc, &pkt); - video_pts += c->frame_size; - } - else - { - // Set the quality - output->quality = video_st->quality; - - // Set frame interlace hints - output->interlaced_frame = !mlt_properties_get_int( frame_properties, "progressive" ); - output->top_field_first = mlt_properties_get_int( frame_properties, "top_field_first" ); - - // Encode the image - out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, output ); - - // If zero size, it means the image was buffered - if (out_size > 0) - { - AVPacket pkt; - av_init_packet( &pkt ); - - if ( c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE ) - pkt.pts= av_rescale_q( c->coded_frame->pts, c->time_base, video_st->time_base ); - if( c->coded_frame && c->coded_frame->key_frame ) - pkt.flags |= PKT_FLAG_KEY; - pkt.stream_index= video_st->index; - pkt.data= video_outbuf; - pkt.size= out_size; - - // write the compressed frame in the media file - ret = av_interleaved_write_frame(oc, &pkt); - video_pts += c->frame_size; - - // Dual pass logging - if ( mlt_properties_get_data( properties, "_logfile", NULL ) && c->stats_out) - fprintf( mlt_properties_get_data( properties, "_logfile", NULL ), "%s", c->stats_out ); - } - else - { - fprintf( stderr, "%s: error with video encode\n", __FILE__ ); - } - } - frame_count++; - mlt_frame_close( frame ); - } - else - { - break; - } - } - } - - if ( real_time_output == 1 && frames % 12 == 0 ) - { - long passed = time_difference( &ante ); - if ( fifo != NULL ) - { - long pending = ( ( ( long )sample_fifo_used( fifo ) * 1000 ) / frequency ) * 1000; - passed -= pending; - } - if ( passed < total_time ) - { - long total = ( total_time - passed ); - struct timespec t = { total / 1000000, ( total % 1000000 ) * 1000 }; - nanosleep( &t, NULL ); - } - } - } - -#ifdef FLUSH - if ( ! real_time_output ) - { - // Flush audio fifo - if ( audio_st && audio_st->codec->frame_size > 1 ) for (;;) - { - AVCodecContext *c = audio_st->codec; - AVPacket pkt; - av_init_packet( &pkt ); - pkt.size = 0; - - if ( /*( c->capabilities & CODEC_CAP_SMALL_LAST_FRAME ) &&*/ - ( channels * audio_input_frame_size < sample_fifo_used( fifo ) ) ) - { - sample_fifo_fetch( fifo, buffer, channels * audio_input_frame_size ); - pkt.size = avcodec_encode_audio( c, audio_outbuf, audio_outbuf_size, buffer ); - } - if ( pkt.size <= 0 ) - pkt.size = avcodec_encode_audio( c, audio_outbuf, audio_outbuf_size, NULL ); - if ( pkt.size <= 0 ) - break; - - // Write the compressed frame in the media file - if ( c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE ) - pkt.pts = av_rescale_q( c->coded_frame->pts, c->time_base, audio_st->time_base ); - pkt.flags |= PKT_FLAG_KEY; - pkt.stream_index = audio_st->index; - pkt.data = audio_outbuf; - if ( av_interleaved_write_frame( oc, &pkt ) != 0 ) - { - fprintf( stderr, "%s: Error while writing flushed audio frame\n", __FILE__ ); - break; - } - } - - // Flush video - if ( video_st && !( oc->oformat->flags & AVFMT_RAWPICTURE ) ) for (;;) - { - AVCodecContext *c = video_st->codec; - AVPacket pkt; - av_init_packet( &pkt ); - - // Encode the image - pkt.size = avcodec_encode_video( c, video_outbuf, video_outbuf_size, NULL ); - if ( pkt.size <= 0 ) - break; - - if ( c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE ) - pkt.pts= av_rescale_q( c->coded_frame->pts, c->time_base, video_st->time_base ); - if( c->coded_frame && c->coded_frame->key_frame ) - pkt.flags |= PKT_FLAG_KEY; - pkt.stream_index = video_st->index; - pkt.data = video_outbuf; - - // write the compressed frame in the media file - if ( av_interleaved_write_frame( oc, &pkt ) != 0 ) - { - fprintf( stderr, "%s: Error while writing flushed video frame\n". __FILE__ ); - break; - } - } - } -#endif - - // close each codec - if (video_st) - close_video(oc, video_st); - if (audio_st) - close_audio(oc, audio_st); - - // Write the trailer, if any - av_write_trailer(oc); - - // Free the streams - for(i = 0; i < oc->nb_streams; i++) - av_freep(&oc->streams[i]); - - // Close the output file - if (!(fmt->flags & AVFMT_NOFILE)) -#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(0<<8)+0) - url_fclose(oc->pb); -#else - url_fclose(&oc->pb); -#endif - - // Clean up input and output frames - if ( output ) - av_free( output->data[0] ); - av_free( output ); - av_free( input->data[0] ); - av_free( input ); - av_free( video_outbuf ); - av_free( buffer ); - - // Free the stream - av_free(oc); - - // Just in case we terminated on pause - mlt_properties_set_int( properties, "running", 0 ); - - mlt_consumer_stopped( this ); - - if ( mlt_properties_get_int( properties, "pass" ) == 2 ) - { - // Remove the dual pass log file - if ( mlt_properties_get( properties, "_logfilename" ) ) - remove( mlt_properties_get( properties, "_logfilename" ) ); - - // Remove the x264 dual pass logs - char *cwd = getcwd( NULL, 0 ); - const char *file = "x264_2pass.log"; - char *full = malloc( strlen( cwd ) + strlen( file ) + 2 ); - sprintf( full, "%s/%s", cwd, file ); - remove( full ); - free( full ); - file = "x264_2pass.log.temp"; - full = malloc( strlen( cwd ) + strlen( file ) + 2 ); - sprintf( full, "%s/%s", cwd, file ); - remove( full ); - free( full ); - free( cwd ); - remove( "x264_2pass.log.temp" ); - } - - return NULL; -} - -/** Close the consumer. -*/ - -static void consumer_close( mlt_consumer this ) -{ - // Stop the consumer - mlt_consumer_stop( this ); - - // Close the parent - mlt_consumer_close( this ); - - // Free the memory - free( this ); -} diff --git a/src/modules/avformat/factory.c b/src/modules/avformat/factory.c deleted file mode 100644 index 54adf93..0000000 --- a/src/modules/avformat/factory.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include - -extern mlt_consumer consumer_avformat_init( mlt_profile profile, char *file ); -extern mlt_filter filter_avcolour_space_init( void *arg ); -extern mlt_filter filter_avdeinterlace_init( void *arg ); -extern mlt_filter filter_avresample_init( char *arg ); -extern mlt_filter filter_swscale_init( mlt_profile profile, char *arg ); -extern mlt_producer producer_avformat_init( mlt_profile profile, char *file ); - -// ffmpeg Header files -#include - -// A static flag used to determine if avformat has been initialised -static int avformat_initialised = 0; - -// A locking mutex -static pthread_mutex_t avformat_mutex; - -#if 0 -// These 3 functions should override the alloc functions in libavformat -// but some formats or codecs seem to crash when used (wmv in particular) - -void *av_malloc( unsigned int size ) -{ - return mlt_pool_alloc( size ); -} - -void *av_realloc( void *ptr, unsigned int size ) -{ - return mlt_pool_realloc( ptr, size ); -} - -void av_free( void *ptr ) -{ - return mlt_pool_release( ptr ); -} -#endif - -void avformat_destroy( void *ignore ) -{ - // Clean up - // av_free_static( ); -XXX this is deprecated - - // Destroy the mutex - pthread_mutex_destroy( &avformat_mutex ); -} - -void avformat_lock( ) -{ - // Lock the mutex now - pthread_mutex_lock( &avformat_mutex ); -} - -void avformat_unlock( ) -{ - // Unlock the mutex now - pthread_mutex_unlock( &avformat_mutex ); -} - -static void avformat_init( ) -{ - // Initialise avformat if necessary - if ( avformat_initialised == 0 ) - { - avformat_initialised = 1; - pthread_mutex_init( &avformat_mutex, NULL ); - av_register_all( ); - mlt_factory_register_for_clean_up( NULL, avformat_destroy ); - av_log_set_level( mlt_log_get_level() ); - } -} - -static void *create_service( mlt_profile profile, mlt_service_type type, const char *id, void *arg ) -{ - avformat_init( ); -#ifdef CODECS - if ( !strcmp( id, "avformat" ) ) - { - if ( type == producer_type ) - return producer_avformat_init( profile, arg ); - else if ( type == consumer_type ) - return consumer_avformat_init( profile, arg ); - } -#endif -#ifdef FILTERS - if ( !strcmp( id, "avcolour_space" ) ) - return filter_avcolour_space_init( arg ); - if ( !strcmp( id, "avdeinterlace" ) ) - return filter_avdeinterlace_init( arg ); - if ( !strcmp( id, "avresample" ) ) - return filter_avresample_init( arg ); -#ifdef SWSCALE - if ( !strcmp( id, "swscale" ) ) - return filter_swscale_init( profile, arg ); -#endif -#endif - return NULL; -} - -static mlt_properties avformat_metadata( mlt_service_type type, const char *id, void *data ) -{ - char file[ PATH_MAX ]; - const char *service_type = NULL; - switch ( type ) - { - case consumer_type: - service_type = "consumer"; - break; - case filter_type: - service_type = "filter"; - break; - case producer_type: - service_type = "producer"; - break; - case transition_type: - service_type = "transition"; - break; - default: - return NULL; - } - snprintf( file, PATH_MAX, "%s/avformat/%s_%s.yml", mlt_environment( "MLT_DATA" ), service_type, id ); - return mlt_properties_parse_yaml( file ); -} - -MLT_REPOSITORY -{ -#ifdef CODECS - MLT_REGISTER( consumer_type, "avformat", create_service ); - MLT_REGISTER( producer_type, "avformat", create_service ); - MLT_REGISTER_METADATA( producer_type, "avformat", avformat_metadata, NULL ); -#endif -#ifdef FILTERS - MLT_REGISTER( filter_type, "avcolour_space", create_service ); - MLT_REGISTER( filter_type, "avcolor_space", create_service ); - MLT_REGISTER( filter_type, "avdeinterlace", create_service ); - MLT_REGISTER( filter_type, "avresample", create_service ); -#ifdef SWSCALE - MLT_REGISTER( filter_type, "swscale", create_service ); -#endif -#endif -} diff --git a/src/modules/avformat/filter_avcolour_space.c b/src/modules/avformat/filter_avcolour_space.c deleted file mode 100644 index 7ca8e49..0000000 --- a/src/modules/avformat/filter_avcolour_space.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * filter_avcolour_space.c -- Colour space filter - * Copyright (C) 2004-2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -// ffmpeg Header files -#include -#ifdef SWSCALE -#include -#endif - -#if LIBAVUTIL_VERSION_INT < (50<<16) -#define PIX_FMT_RGB32 PIX_FMT_RGBA32 -#define PIX_FMT_YUYV422 PIX_FMT_YUV422 -#endif - -#include -#include - -static inline int is_big_endian( ) -{ - union { int i; char c[ 4 ]; } big_endian_test; - big_endian_test.i = 1; - - return big_endian_test.c[ 0 ] != 1; -} - -static inline int convert_mlt_to_av_cs( mlt_image_format format ) -{ - int value = 0; - - switch( format ) - { - case mlt_image_rgb24: - value = PIX_FMT_RGB24; - break; - case mlt_image_rgb24a: - value = PIX_FMT_RGB32; - break; - case mlt_image_yuv422: - value = PIX_FMT_YUYV422; - break; - case mlt_image_yuv420p: - value = PIX_FMT_YUV420P; - break; - case mlt_image_opengl: - case mlt_image_none: - fprintf( stderr, "Invalid format...\n" ); - break; - } - - return value; -} - -static inline void convert_image( uint8_t *out, uint8_t *in, int out_fmt, int in_fmt, int width, int height ) -{ - AVPicture input; - AVPicture output; - avpicture_fill( &input, in, in_fmt, width, height ); - avpicture_fill( &output, out, out_fmt, width, height ); -#ifdef SWSCALE - struct SwsContext *context = sws_getContext( width, height, in_fmt, - width, height, out_fmt, SWS_FAST_BILINEAR, NULL, NULL, NULL); - sws_scale( context, input.data, input.linesize, 0, height, - output.data, output.linesize); - sws_freeContext( context ); -#else - img_convert( &output, out_fmt, &input, in_fmt, width, height ); -#endif -} - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_filter filter = mlt_frame_pop_service( this ); - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - int output_format = *format; - mlt_image_format forced = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "forced" ); - int error = 0; - - // Allow this filter to force processing in a colour space other than requested - *format = forced != 0 ? forced : *format; - - error = mlt_frame_get_image( this, image, format, width, height, 0 ); - - if ( error == 0 && *format != output_format && *image != NULL && output_format != mlt_image_opengl ) - { - int in_fmt = convert_mlt_to_av_cs( *format ); - int out_fmt = convert_mlt_to_av_cs( output_format ); - int size = avpicture_get_size( out_fmt, *width, *height ); - uint8_t *output = mlt_pool_alloc( size ); - convert_image( output, *image, out_fmt, in_fmt, *width, *height ); - - // Special case for alpha rgb input - if ( *format == mlt_image_rgb24a ) - { - register uint8_t *alpha = mlt_frame_get_alpha_mask( this ); - register int len = *width * *height; - register uint8_t *bits = *image; - register int n = ( len + 7 ) / 8; - - if( !is_big_endian( ) ) - bits += 3; - - // Extract alpha mask from the image using Duff's Device - switch( len % 8 ) - { - case 0: do { *alpha ++ = *bits; bits += 4; - case 7: *alpha ++ = *bits; bits += 4; - case 6: *alpha ++ = *bits; bits += 4; - case 5: *alpha ++ = *bits; bits += 4; - case 4: *alpha ++ = *bits; bits += 4; - case 3: *alpha ++ = *bits; bits += 4; - case 2: *alpha ++ = *bits; bits += 4; - case 1: *alpha ++ = *bits; bits += 4; - } - while( --n ); - } - } - - // Update the output - *image = output; - *format = output_format; - mlt_properties_set_data( properties, "image", output, size, mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "format", output_format ); - - // Special case for alpha rgb output - if ( *format == mlt_image_rgb24a ) - { - // Fetch the alpha - register uint8_t *alpha = mlt_frame_get_alpha_mask( this ); - - if ( alpha != NULL ) - { - register uint8_t *bits = *image; - register int len = *width * *height; - register int n = ( len + 7 ) / 8; - - if( !is_big_endian( ) ) - bits += 3; - - // Merge the alpha mask into the RGB image using Duff's Device - switch( len % 8 ) - { - case 0: do { *bits = *alpha++; bits += 4; - case 7: *bits = *alpha++; bits += 4; - case 6: *bits = *alpha++; bits += 4; - case 5: *bits = *alpha++; bits += 4; - case 4: *bits = *alpha++; bits += 4; - case 3: *bits = *alpha++; bits += 4; - case 2: *bits = *alpha++; bits += 4; - case 1: *bits = *alpha++; bits += 4; - } - while( --n ); - } - } - } - } - else if ( error == 0 && *format != output_format && *image != NULL && output_format == mlt_image_opengl ) - { - if ( *format == mlt_image_yuv422 ) - { - int size = *width * *height * 4; - uint8_t *output = mlt_pool_alloc( size ); - int h = *height; - int w = *width; - uint8_t *o = output + size; - int ostride = w * 4; - uint8_t *p = *image; - uint8_t *alpha = mlt_frame_get_alpha_mask( this ) + *width * *height; - int r, g, b; - - while( h -- ) - { - w = *width; - o -= ostride; - alpha -= *width; - while( w >= 2 ) - { - YUV2RGB( *p, *( p + 1 ), *( p + 3 ), r, g, b ); - *o ++ = r; - *o ++ = g; - *o ++ = b; - *o ++ = *alpha ++; - YUV2RGB( *( p + 2 ), *( p + 1 ), *( p + 3 ), r, g, b ); - *o ++ = r; - *o ++ = g; - *o ++ = b; - *o ++ = *alpha ++; - w -= 2; - p += 4; - } - o -= ostride; - alpha -= *width; - } - - mlt_properties_set_data( properties, "image", output, size, mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "format", output_format ); - *image = output; - *format = output_format; - } - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_avcolour_space_init( void *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - this->process = filter_process; - return this; -} - diff --git a/src/modules/avformat/filter_avdeinterlace.c b/src/modules/avformat/filter_avdeinterlace.c deleted file mode 100644 index d4afa35..0000000 --- a/src/modules/avformat/filter_avdeinterlace.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * filter_avdeinterlace.c -- deinterlace filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include - -// ffmpeg Header files -#include - -#ifdef USE_MMX -#include "mmx.h" -#else -#define MAX_NEG_CROP 1024 -extern uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP]; -#endif - -#ifdef USE_MMX -#define DEINT_INPLACE_LINE_LUM \ - movd_m2r(lum_m4[0],mm0);\ - movd_m2r(lum_m3[0],mm1);\ - movd_m2r(lum_m2[0],mm2);\ - movd_m2r(lum_m1[0],mm3);\ - movd_m2r(lum[0],mm4);\ - punpcklbw_r2r(mm7,mm0);\ - movd_r2m(mm2,lum_m4[0]);\ - punpcklbw_r2r(mm7,mm1);\ - punpcklbw_r2r(mm7,mm2);\ - punpcklbw_r2r(mm7,mm3);\ - punpcklbw_r2r(mm7,mm4);\ - paddw_r2r(mm3,mm1);\ - psllw_i2r(1,mm2);\ - paddw_r2r(mm4,mm0);\ - psllw_i2r(2,mm1);\ - paddw_r2r(mm6,mm2);\ - paddw_r2r(mm2,mm1);\ - psubusw_r2r(mm0,mm1);\ - psrlw_i2r(3,mm1);\ - packuswb_r2r(mm7,mm1);\ - movd_r2m(mm1,lum_m2[0]); - -#define DEINT_LINE_LUM \ - movd_m2r(lum_m4[0],mm0);\ - movd_m2r(lum_m3[0],mm1);\ - movd_m2r(lum_m2[0],mm2);\ - movd_m2r(lum_m1[0],mm3);\ - movd_m2r(lum[0],mm4);\ - punpcklbw_r2r(mm7,mm0);\ - punpcklbw_r2r(mm7,mm1);\ - punpcklbw_r2r(mm7,mm2);\ - punpcklbw_r2r(mm7,mm3);\ - punpcklbw_r2r(mm7,mm4);\ - paddw_r2r(mm3,mm1);\ - psllw_i2r(1,mm2);\ - paddw_r2r(mm4,mm0);\ - psllw_i2r(2,mm1);\ - paddw_r2r(mm6,mm2);\ - paddw_r2r(mm2,mm1);\ - psubusw_r2r(mm0,mm1);\ - psrlw_i2r(3,mm1);\ - packuswb_r2r(mm7,mm1);\ - movd_r2m(mm1,dst[0]); -#endif - -#if LIBAVUTIL_VERSION_INT < (50<<16) -#define PIX_FMT_YUYV422 PIX_FMT_YUV422 -#endif - -/* filter parameters: [-1 4 2 4 -1] // 8 */ -static inline void deinterlace_line(uint8_t *dst, - const uint8_t *lum_m4, const uint8_t *lum_m3, - const uint8_t *lum_m2, const uint8_t *lum_m1, - const uint8_t *lum, - int size) -{ -#ifndef USE_MMX - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - int sum; - - for(;size > 0;size--) { - sum = -lum_m4[0]; - sum += lum_m3[0] << 2; - sum += lum_m2[0] << 1; - sum += lum_m1[0] << 2; - sum += -lum[0]; - dst[0] = cm[(sum + 4) >> 3]; - lum_m4++; - lum_m3++; - lum_m2++; - lum_m1++; - lum++; - dst++; - } -#else - - { - mmx_t rounder; - rounder.uw[0]=4; - rounder.uw[1]=4; - rounder.uw[2]=4; - rounder.uw[3]=4; - pxor_r2r(mm7,mm7); - movq_m2r(rounder,mm6); - } - for (;size > 3; size-=4) { - DEINT_LINE_LUM - lum_m4+=4; - lum_m3+=4; - lum_m2+=4; - lum_m1+=4; - lum+=4; - dst+=4; - } -#endif -} -static inline void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, - int size) -{ -#ifndef USE_MMX - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - int sum; - - for(;size > 0;size--) { - sum = -lum_m4[0]; - sum += lum_m3[0] << 2; - sum += lum_m2[0] << 1; - lum_m4[0]=lum_m2[0]; - sum += lum_m1[0] << 2; - sum += -lum[0]; - lum_m2[0] = cm[(sum + 4) >> 3]; - lum_m4++; - lum_m3++; - lum_m2++; - lum_m1++; - lum++; - } -#else - - { - mmx_t rounder; - rounder.uw[0]=4; - rounder.uw[1]=4; - rounder.uw[2]=4; - rounder.uw[3]=4; - pxor_r2r(mm7,mm7); - movq_m2r(rounder,mm6); - } - for (;size > 3; size-=4) { - DEINT_INPLACE_LINE_LUM - lum_m4+=4; - lum_m3+=4; - lum_m2+=4; - lum_m1+=4; - lum+=4; - } -#endif -} - -/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The - top field is copied as is, but the bottom field is deinterlaced - against the top field. */ -static inline void deinterlace_bottom_field(uint8_t *dst, int dst_wrap, - const uint8_t *src1, int src_wrap, - int width, int height) -{ - const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2; - int y; - - src_m2 = src1; - src_m1 = src1; - src_0=&src_m1[src_wrap]; - src_p1=&src_0[src_wrap]; - src_p2=&src_p1[src_wrap]; - for(y=0;y<(height-2);y+=2) { - memcpy(dst,src_m1,width); - dst += dst_wrap; - deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width); - src_m2 = src_0; - src_m1 = src_p1; - src_0 = src_p2; - src_p1 += 2*src_wrap; - src_p2 += 2*src_wrap; - dst += dst_wrap; - } - memcpy(dst,src_m1,width); - dst += dst_wrap; - /* do last line */ - deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width); -} - -static inline void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, - int width, int height) -{ - uint8_t *src_m1, *src_0, *src_p1, *src_p2; - int y; - uint8_t *buf; - buf = (uint8_t*)av_malloc(width); - - src_m1 = src1; - memcpy(buf,src_m1,width); - src_0=&src_m1[src_wrap]; - src_p1=&src_0[src_wrap]; - src_p2=&src_p1[src_wrap]; - for(y=0;y<(height-2);y+=2) { - deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width); - src_m1 = src_p1; - src_0 = src_p2; - src_p1 += 2*src_wrap; - src_p2 += 2*src_wrap; - } - /* do last line */ - deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width); - av_free(buf); -} - - -/* deinterlace - if not supported return -1 */ -static int mlt_avpicture_deinterlace(AVPicture *dst, const AVPicture *src, - int pix_fmt, int width, int height) -{ - int i; - - if (pix_fmt != PIX_FMT_YUV420P && - pix_fmt != PIX_FMT_YUV422P && - pix_fmt != PIX_FMT_YUYV422 && - pix_fmt != PIX_FMT_YUV444P && - pix_fmt != PIX_FMT_YUV411P) - return -1; - if ((width & 3) != 0 || (height & 3) != 0) - return -1; - - if ( pix_fmt != PIX_FMT_YUYV422 ) - { - for(i=0;i<3;i++) { - if (i == 1) { - switch(pix_fmt) { - case PIX_FMT_YUV420P: - width >>= 1; - height >>= 1; - break; - case PIX_FMT_YUV422P: - width >>= 1; - break; - case PIX_FMT_YUV411P: - width >>= 2; - break; - default: - break; - } - } - if (src == dst) { - deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i], - width, height); - } else { - deinterlace_bottom_field(dst->data[i],dst->linesize[i], - src->data[i], src->linesize[i], - width, height); - } - } - } - else { - if (src == dst) { - deinterlace_bottom_field_inplace(dst->data[0], dst->linesize[0], - width<<1, height); - } else { - deinterlace_bottom_field(dst->data[0],dst->linesize[0], - src->data[0], src->linesize[0], - width<<1, height); - } - } - -#ifdef USE_MMX - emms(); -#endif - return 0; -} - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - int error = 0; - int deinterlace = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "consumer_deinterlace" ); - - // Determine if we need a writable version or not - if ( deinterlace && !writable ) - writable = !mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "progressive" ); - - // Get the input image - error = mlt_frame_get_image( this, image, format, width, height, writable ); - - // Check that we want progressive and we aren't already progressive - if ( deinterlace && *format == mlt_image_yuv422 && *image != NULL && !mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "progressive" ) ) - { - // Create a picture - AVPicture *output = mlt_pool_alloc( sizeof( AVPicture ) ); - - // Fill the picture - if ( *format == mlt_image_yuv422 ) - { - avpicture_fill( output, *image, PIX_FMT_YUYV422, *width, *height ); - mlt_avpicture_deinterlace( output, output, PIX_FMT_YUYV422, *width, *height ); - } - - // Free the picture - mlt_pool_release( output ); - - // Make sure that others know the frame is deinterlaced - mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "progressive", 1 ); - } - - return error; -} - -/** Deinterlace filter processing - this should be lazy evaluation here... -*/ - -static mlt_frame deinterlace_process( mlt_filter this, mlt_frame frame ) -{ - // Push the get_image method on to the stack - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_avdeinterlace_init( void *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - this->process = deinterlace_process; - return this; -} - diff --git a/src/modules/avformat/filter_avresample.c b/src/modules/avformat/filter_avresample.c deleted file mode 100644 index 3252246..0000000 --- a/src/modules/avformat/filter_avresample.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * filter_avresample.c -- adjust audio sample frequency - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - -// ffmpeg Header files -#include - -/** Get the audio. -*/ - -static int resample_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the properties of the frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Get the filter service - mlt_filter filter = mlt_frame_pop_audio( frame ); - - // Get the filter properties - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - - // Get the resample information - int output_rate = mlt_properties_get_int( filter_properties, "frequency" ); - int16_t *sample_buffer = mlt_properties_get_data( filter_properties, "buffer", NULL ); - - // Obtain the resample context if it exists - ReSampleContext *resample = mlt_properties_get_data( filter_properties, "audio_resample", NULL ); - - // Used to return number of channels in the source - int channels_avail = *channels; - - // Loop variable - int i; - - // If no resample frequency is specified, default to requested value - if ( output_rate == 0 ) - output_rate = *frequency; - - // Get the producer's audio - mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples ); - - // Duplicate channels as necessary - if ( channels_avail < *channels ) - { - int size = *channels * *samples * sizeof( int16_t ); - int16_t *new_buffer = mlt_pool_alloc( size ); - int j, k = 0; - - // Duplicate the existing channels - for ( i = 0; i < *samples; i++ ) - { - for ( j = 0; j < *channels; j++ ) - { - new_buffer[ ( i * *channels ) + j ] = (*buffer)[ ( i * channels_avail ) + k ]; - k = ( k + 1 ) % channels_avail; - } - } - - // Update the audio buffer now - destroys the old - mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - - *buffer = new_buffer; - } - else if ( channels_avail == 6 && *channels == 2 ) - { - // Nasty hack for ac3 5.1 audio - may be a cause of failure? - int size = *channels * *samples * sizeof( int16_t ); - int16_t *new_buffer = mlt_pool_alloc( size ); - - // Drop all but the first *channels - for ( i = 0; i < *samples; i++ ) - { - new_buffer[ ( i * *channels ) + 0 ] = (*buffer)[ ( i * channels_avail ) + 2 ]; - new_buffer[ ( i * *channels ) + 1 ] = (*buffer)[ ( i * channels_avail ) + 3 ]; - } - - // Update the audio buffer now - destroys the old - mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - - *buffer = new_buffer; - } - - // Return now if no work to do - if ( output_rate != *frequency ) - { - // Will store number of samples created - int used = 0; - - // Create a resampler if nececessary - if ( resample == NULL || *frequency != mlt_properties_get_int( filter_properties, "last_frequency" ) ) - { - // Create the resampler - resample = audio_resample_init( *channels, *channels, output_rate, *frequency ); - - // And store it on properties - mlt_properties_set_data( filter_properties, "audio_resample", resample, 0, ( mlt_destructor )audio_resample_close, NULL ); - - // And remember what it was created for - mlt_properties_set_int( filter_properties, "last_frequency", *frequency ); - } - - // Resample the audio - used = audio_resample( resample, sample_buffer, *buffer, *samples ); - - // Resize if necessary - if ( used > *samples ) - { - *buffer = mlt_pool_realloc( *buffer, *samples * *channels * sizeof( int16_t ) ); - mlt_properties_set_data( properties, "audio", *buffer, *channels * used * sizeof( int16_t ), mlt_pool_release, NULL ); - } - - // Copy samples - memcpy( *buffer, sample_buffer, *channels * used * sizeof( int16_t ) ); - - // Update output variables - *samples = used; - *frequency = output_rate; - } - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Only call this if we have a means to get audio - if ( mlt_frame_is_test_audio( frame ) == 0 ) - { - // Push the filter on to the stack - mlt_frame_push_audio( frame, this ); - - // Assign our get_audio method - mlt_frame_push_audio( frame, resample_get_audio ); - } - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_avresample_init( char *arg ) -{ - // Create a filter - mlt_filter this = mlt_filter_new( ); - - // Initialise if successful - if ( this != NULL ) - { - // Calculate size of the buffer - int size = AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof( int16_t ); - - // Allocate the buffer - int16_t *buffer = mlt_pool_alloc( size ); - - // Assign the process method - this->process = filter_process; - - // Deal with argument - if ( arg != NULL ) - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "frequency", arg ); - - // Default to 2 channel output - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "channels", 2 ); - - // Store the buffer - mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), "buffer", buffer, size, mlt_pool_release, NULL ); - } - - return this; -} diff --git a/src/modules/avformat/filter_swscale.c b/src/modules/avformat/filter_swscale.c deleted file mode 100644 index d1266ae..0000000 --- a/src/modules/avformat/filter_swscale.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * filter_swscale.c -- image scaling filter - * Copyright (C) 2008-2009 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - - -// ffmpeg Header files -#include -#include - -#include -#include -#include -#include - -#if LIBAVUTIL_VERSION_INT < (50<<16) -#define PIX_FMT_RGB32 PIX_FMT_RGBA32 -#define PIX_FMT_YUYV422 PIX_FMT_YUV422 -#endif - -static inline int is_big_endian( ) -{ - union { int i; char c[ 4 ]; } big_endian_test; - big_endian_test.i = 1; - - return big_endian_test.c[ 0 ] != 1; -} - -static inline int convert_mlt_to_av_cs( mlt_image_format format ) -{ - int value = 0; - - switch( format ) - { - case mlt_image_rgb24: - value = PIX_FMT_RGB24; - break; - case mlt_image_rgb24a: - value = PIX_FMT_RGB32; - break; - case mlt_image_yuv422: - value = PIX_FMT_YUYV422; - break; - case mlt_image_yuv420p: - value = PIX_FMT_YUV420P; - break; - case mlt_image_opengl: - case mlt_image_none: - fprintf( stderr, "Invalid format...\n" ); - break; - } - - return value; -} - -static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iformat, mlt_image_format oformat, int iwidth, int iheight, int owidth, int oheight ) -{ - // Get the properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get the requested interpolation method - char *interps = mlt_properties_get( properties, "rescale.interp" ); - - // Convert to the SwScale flag - int interp = SWS_BILINEAR; - if ( strcmp( interps, "nearest" ) == 0 || strcmp( interps, "neighbor" ) == 0 ) - interp = SWS_POINT; - else if ( strcmp( interps, "tiles" ) == 0 || strcmp( interps, "fast_bilinear" ) == 0 ) - interp = SWS_FAST_BILINEAR; - else if ( strcmp( interps, "bilinear" ) == 0 ) - interp = SWS_BILINEAR; - else if ( strcmp( interps, "bicubic" ) == 0 ) - interp = SWS_BICUBIC; - else if ( strcmp( interps, "bicublin" ) == 0 ) - interp = SWS_BICUBLIN; - else if ( strcmp( interps, "gauss" ) == 0 ) - interp = SWS_GAUSS; - else if ( strcmp( interps, "sinc" ) == 0 ) - interp = SWS_SINC; - else if ( strcmp( interps, "hyper" ) == 0 || strcmp( interps, "lanczos" ) == 0 ) - interp = SWS_LANCZOS; - else if ( strcmp( interps, "spline" ) == 0 ) - interp = SWS_SPLINE; - - AVPicture input; - AVPicture output; - uint8_t *outbuf = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 ); - - // Convert the pixel formats - iformat = convert_mlt_to_av_cs( iformat ); - oformat = convert_mlt_to_av_cs( oformat ); - - avpicture_fill( &input, *image, iformat, iwidth, iheight ); - avpicture_fill( &output, outbuf, oformat, owidth, oheight ); - - // Extract the alpha channel - if ( iformat == PIX_FMT_RGB32 && oformat == PIX_FMT_YUYV422 ) - { - // Allocate the alpha mask - uint8_t *alpha = mlt_pool_alloc( iwidth * ( iheight + 1 ) ); - if ( alpha ) - { - // Convert the image and extract alpha - mlt_convert_rgb24a_to_yuv422( *image, iwidth, iheight, iwidth * 4, outbuf, alpha ); - mlt_properties_set_data( properties, "alpha", alpha, iwidth * ( iheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL ); - iformat = PIX_FMT_YUYV422; - avpicture_fill( &input, outbuf, iformat, iwidth, iheight ); - avpicture_fill( &output, *image, oformat, owidth, oheight ); - } - } - - // Create the context and output image - struct SwsContext *context = sws_getContext( iwidth, iheight, iformat, owidth, oheight, oformat, interp, NULL, NULL, NULL); - assert(context); - - // Perform the scaling - sws_scale( context, input.data, input.linesize, 0, iheight, output.data, output.linesize); - sws_freeContext( context ); - - // Now update the frame - mlt_properties_set_data( properties, "image", output.data[0], owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", owidth ); - mlt_properties_set_int( properties, "height", oheight ); - - // Return the output - *image = output.data[0]; - - // Scale the alpha channel only if exists and not correct size - int alpha_size = 0; - mlt_properties_get_data( properties, "alpha", &alpha_size ); - if ( alpha_size > 0 && alpha_size != ( owidth * oheight ) ) - { - // Create the context and output image - uint8_t *alpha = mlt_frame_get_alpha_mask( this ); - if ( alpha ) - { - iformat = oformat = PIX_FMT_GRAY8; - struct SwsContext *context = sws_getContext( iwidth, iheight, iformat, owidth, oheight, oformat, interp, NULL, NULL, NULL); - avpicture_fill( &input, alpha, iformat, iwidth, iheight ); - outbuf = mlt_pool_alloc( owidth * oheight ); - avpicture_fill( &output, outbuf, oformat, owidth, oheight ); - - // Perform the scaling - sws_scale( context, input.data, input.linesize, 0, iheight, output.data, output.linesize); - sws_freeContext( context ); - - // Set it back on the frame - mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", output.data[0], owidth * oheight, mlt_pool_release, NULL ); - } - } - - return 0; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_swscale_init( mlt_profile profile, void *arg ) -{ - // Create a new scaler - mlt_filter this = mlt_factory_filter( profile, "rescale", arg ); - - // If successful, then initialise it - if ( this != NULL ) - { - // Get the properties - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Set the inerpolation - mlt_properties_set( properties, "interpolation", arg == NULL ? "bilinear" : arg ); - - // Set the method - mlt_properties_set_data( properties, "method", filter_scale, 0, NULL, NULL ); - } - - return this; -} diff --git a/src/modules/avformat/mmx.h b/src/modules/avformat/mmx.h deleted file mode 100644 index 7e94cfd..0000000 --- a/src/modules/avformat/mmx.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * mmx.h - * Copyright (C) 1997-2001 H. Dietz and R. Fisher - */ -#ifndef AVCODEC_I386MMX_H -#define AVCODEC_I386MMX_H - -/* - * The type of an value that fits in an MMX register (note that long - * long constant values MUST be suffixed by LL and unsigned long long - * values by ULL, lest they be truncated by the compiler) - */ - -typedef union { - long long q; /* Quadword (64-bit) value */ - unsigned long long uq; /* Unsigned Quadword */ - int d[2]; /* 2 Doubleword (32-bit) values */ - unsigned int ud[2]; /* 2 Unsigned Doubleword */ - short w[4]; /* 4 Word (16-bit) values */ - unsigned short uw[4]; /* 4 Unsigned Word */ - char b[8]; /* 8 Byte (8-bit) values */ - unsigned char ub[8]; /* 8 Unsigned Byte */ - float s[2]; /* Single-precision (32-bit) value */ -} mmx_t; /* On an 8-byte (64-bit) boundary */ - - -#define mmx_i2r(op,imm,reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "i" (imm) ) - -#define mmx_m2r(op,mem,reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "m" (mem)) - -#define mmx_r2m(op,reg,mem) \ - __asm__ __volatile__ (#op " %%" #reg ", %0" \ - : "=m" (mem) \ - : /* nothing */ ) - -#define mmx_r2r(op,regs,regd) \ - __asm__ __volatile__ (#op " %" #regs ", %" #regd) - - -#define emms() __asm__ __volatile__ ("emms") - -#define movd_m2r(var,reg) mmx_m2r (movd, var, reg) -#define movd_r2m(reg,var) mmx_r2m (movd, reg, var) -#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd) - -#define movq_m2r(var,reg) mmx_m2r (movq, var, reg) -#define movq_r2m(reg,var) mmx_r2m (movq, reg, var) -#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd) - -#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg) -#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd) -#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg) -#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd) - -#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg) -#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd) - -#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg) -#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd) -#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg) -#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd) -#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg) -#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd) - -#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg) -#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd) -#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg) -#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd) - -#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg) -#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd) -#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg) -#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd) - -#define pand_m2r(var,reg) mmx_m2r (pand, var, reg) -#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd) - -#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg) -#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd) - -#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg) -#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd) -#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg) -#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd) -#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg) -#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd) - -#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg) -#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd) -#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg) -#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd) -#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg) -#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd) - -#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg) -#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd) - -#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg) -#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd) - -#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg) -#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd) - -#define por_m2r(var,reg) mmx_m2r (por, var, reg) -#define por_r2r(regs,regd) mmx_r2r (por, regs, regd) - -#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg) -#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg) -#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd) -#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg) -#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg) -#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd) -#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg) -#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg) -#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd) - -#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg) -#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg) -#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd) -#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg) -#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg) -#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd) - -#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg) -#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg) -#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd) -#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg) -#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg) -#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd) -#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg) -#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg) -#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd) - -#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg) -#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd) -#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg) -#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd) -#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg) -#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd) - -#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg) -#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd) -#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg) -#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd) - -#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg) -#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd) -#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg) -#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd) - -#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg) -#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd) -#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg) -#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd) -#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg) -#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd) - -#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg) -#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd) -#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg) -#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd) -#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg) -#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd) - -#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg) -#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd) - - -/* 3DNOW extensions */ - -#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg) -#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd) - - -/* AMD MMX extensions - also available in intel SSE */ - - -#define mmx_m2ri(op,mem,reg,imm) \ - __asm__ __volatile__ (#op " %1, %0, %%" #reg \ - : /* nothing */ \ - : "X" (mem), "X" (imm)) -#define mmx_r2ri(op,regs,regd,imm) \ - __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ - : /* nothing */ \ - : "X" (imm) ) - -#define mmx_fetch(mem,hint) \ - __asm__ __volatile__ ("prefetch" #hint " %0" \ - : /* nothing */ \ - : "X" (mem)) - - -#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg) - -#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var) - -#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg) -#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd) -#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg) -#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd) - -#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm) - -#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm) - -#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg) -#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd) - -#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg) -#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd) - -#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg) -#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd) - -#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg) -#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd) - -#define pmovmskb(mmreg,reg) \ - __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg) - -#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg) -#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd) - -#define prefetcht0(mem) mmx_fetch (mem, t0) -#define prefetcht1(mem) mmx_fetch (mem, t1) -#define prefetcht2(mem) mmx_fetch (mem, t2) -#define prefetchnta(mem) mmx_fetch (mem, nta) - -#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg) -#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd) - -#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm) -#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm) - -#define sfence() __asm__ __volatile__ ("sfence\n\t") - -#endif /* AVCODEC_I386MMX_H */ diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c deleted file mode 100644 index 2474f9a..0000000 --- a/src/modules/avformat/producer_avformat.c +++ /dev/null @@ -1,1469 +0,0 @@ -/* - * producer_avformat.c -- avformat producer - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * Much code borrowed from ffmpeg.c: Copyright (c) 2000-2003 Fabrice Bellard - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// MLT Header files -#include -#include -#include - -// ffmpeg Header files -#include -#include -#ifdef SWSCALE -# include -#endif -#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0)) -# include "audioconvert.h" -#endif - -// System header files -#include -#include -#include -#include - -#if LIBAVUTIL_VERSION_INT < (50<<16) -#define PIX_FMT_YUYV422 PIX_FMT_YUV422 -#endif - -void avformat_lock( ); -void avformat_unlock( ); - -// Forward references. -static int producer_open( mlt_producer this, mlt_profile profile, char *file ); -static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ); - -/** Constructor for libavformat. -*/ - -mlt_producer producer_avformat_init( mlt_profile profile, char *file ) -{ - int error = 0; - - // Report information about available demuxers and codecs as YAML Tiny - if ( file && strstr( file, "f-list" ) ) - { - fprintf( stderr, "---\nformats:\n" ); - AVInputFormat *format = NULL; - while ( ( format = av_iformat_next( format ) ) ) - fprintf( stderr, " - %s\n", format->name ); - fprintf( stderr, "...\n" ); - error = 1; - } - if ( file && strstr( file, "acodec-list" ) ) - { - fprintf( stderr, "---\naudio_codecs:\n" ); - AVCodec *codec = NULL; - while ( ( codec = av_codec_next( codec ) ) ) - if ( codec->decode && codec->type == CODEC_TYPE_AUDIO ) - fprintf( stderr, " - %s\n", codec->name ); - fprintf( stderr, "...\n" ); - error = 1; - } - if ( file && strstr( file, "vcodec-list" ) ) - { - fprintf( stderr, "---\nvideo_codecs:\n" ); - AVCodec *codec = NULL; - while ( ( codec = av_codec_next( codec ) ) ) - if ( codec->decode && codec->type == CODEC_TYPE_VIDEO ) - fprintf( stderr, " - %s\n", codec->name ); - fprintf( stderr, "...\n" ); - error = 1; - } - if ( error ) - return NULL; - - mlt_producer this = NULL; - - // Check that we have a non-NULL argument - if ( file != NULL ) - { - // Construct the producer - this = calloc( 1, sizeof( struct mlt_producer_s ) ); - - // Initialise it - if ( mlt_producer_init( this, NULL ) == 0 ) - { - // Get the properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Set the resource property (required for all producers) - mlt_properties_set( properties, "resource", file ); - - // Register our get_frame implementation - this->get_frame = producer_get_frame; - - // Open the file - if ( producer_open( this, profile, file ) != 0 ) - { - // Clean up - mlt_producer_close( this ); - this = NULL; - } - else - { - // Close the file to release resources for large playlists - reopen later as needed - mlt_properties_set_data( properties, "dummy_context", NULL, 0, NULL, NULL ); - mlt_properties_set_data( properties, "audio_context", NULL, 0, NULL, NULL ); - mlt_properties_set_data( properties, "video_context", NULL, 0, NULL, NULL ); - - // Default the user-selectable indices from the auto-detected indices - mlt_properties_set_int( properties, "audio_index", mlt_properties_get_int( properties, "_audio_index" ) ); - mlt_properties_set_int( properties, "video_index", mlt_properties_get_int( properties, "_video_index" ) ); - } - } - } - - return this; -} - -/** Find the default streams. -*/ - -static mlt_properties find_default_streams( mlt_properties meta_media, AVFormatContext *context, int *audio_index, int *video_index ) -{ - int i; - char key[200]; - - mlt_properties_set_int( meta_media, "meta.media.nb_streams", context->nb_streams ); - - // Allow for multiple audio and video streams in the file and select first of each (if available) - for( i = 0; i < context->nb_streams; i++ ) - { - // Get the codec context - AVStream *stream = context->streams[ i ]; - if ( ! stream ) continue; - AVCodecContext *codec_context = stream->codec; - if ( ! codec_context ) continue; - AVCodec *codec = avcodec_find_decoder( codec_context->codec_id ); - if ( ! codec ) continue; - - snprintf( key, sizeof(key), "meta.media.%d.stream.type", i ); - - // Determine the type and obtain the first index of each type - switch( codec_context->codec_type ) - { - case CODEC_TYPE_VIDEO: - if ( *video_index < 0 ) - *video_index = i; - mlt_properties_set( meta_media, key, "video" ); - snprintf( key, sizeof(key), "meta.media.%d.stream.frame_rate", i ); - mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->r_frame_rate ) ); -#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(21<<8)+0) - snprintf( key, sizeof(key), "meta.media.%d.stream.sample_aspect_ratio", i ); - mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->sample_aspect_ratio ) ); -#endif - snprintf( key, sizeof(key), "meta.media.%d.codec.pix_fmt", i ); - mlt_properties_set( meta_media, key, avcodec_get_pix_fmt_name( codec_context->pix_fmt ) ); - snprintf( key, sizeof(key), "meta.media.%d.codec.sample_aspect_ratio", i ); - mlt_properties_set_double( meta_media, key, av_q2d( codec_context->sample_aspect_ratio ) ); - break; - case CODEC_TYPE_AUDIO: - if ( *audio_index < 0 ) - *audio_index = i; - mlt_properties_set( meta_media, key, "audio" ); -#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0)) - snprintf( key, sizeof(key), "meta.media.%d.codec.sample_fmt", i ); - mlt_properties_set( meta_media, key, avcodec_get_sample_fmt_name( codec_context->sample_fmt ) ); -#endif - snprintf( key, sizeof(key), "meta.media.%d.codec.sample_rate", i ); - mlt_properties_set_int( meta_media, key, codec_context->sample_rate ); - snprintf( key, sizeof(key), "meta.media.%d.codec.channels", i ); - mlt_properties_set_int( meta_media, key, codec_context->channels ); - break; - default: - break; - } -// snprintf( key, sizeof(key), "meta.media.%d.stream.time_base", i ); -// mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->time_base ) ); - snprintf( key, sizeof(key), "meta.media.%d.codec.name", i ); - mlt_properties_set( meta_media, key, codec->name ); -#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(55<<8)+0)) - snprintf( key, sizeof(key), "meta.media.%d.codec.long_name", i ); - mlt_properties_set( meta_media, key, codec->long_name ); -#endif - snprintf( key, sizeof(key), "meta.media.%d.codec.bit_rate", i ); - mlt_properties_set_int( meta_media, key, codec_context->bit_rate ); -// snprintf( key, sizeof(key), "meta.media.%d.codec.time_base", i ); -// mlt_properties_set_double( meta_media, key, av_q2d( codec_context->time_base ) ); - snprintf( key, sizeof(key), "meta.media.%d.codec.profile", i ); - mlt_properties_set_int( meta_media, key, codec_context->profile ); - snprintf( key, sizeof(key), "meta.media.%d.codec.level", i ); - mlt_properties_set_int( meta_media, key, codec_context->level ); - } - - return meta_media; -} - -/** Producer file destructor. -*/ - -static void producer_file_close( void *context ) -{ - if ( context != NULL ) - { - // Lock the mutex now - avformat_lock( ); - - // Close the file - av_close_input_file( context ); - - // Unlock the mutex now - avformat_unlock( ); - } -} - -/** Producer file destructor. -*/ - -static void producer_codec_close( void *codec ) -{ - if ( codec != NULL ) - { - // Lock the mutex now - avformat_lock( ); - - // Close the file - avcodec_close( codec ); - - // Unlock the mutex now - avformat_unlock( ); - } -} - -static inline int dv_is_pal( AVPacket *pkt ) -{ - return pkt->data[3] & 0x80; -} - -static int dv_is_wide( AVPacket *pkt ) -{ - int i = 80 /* block size */ *3 /* VAUX starts at block 3 */ +3 /* skip block header */; - - for ( ; i < pkt->size; i += 5 /* packet size */ ) - { - if ( pkt->data[ i ] == 0x61 ) - { - uint8_t x = pkt->data[ i + 2 ] & 0x7; - return ( x == 2 ) || ( x == 7 ); - } - } - return 0; -} - -static double get_aspect_ratio( AVStream *stream, AVCodecContext *codec_context, AVPacket *pkt ) -{ - double aspect_ratio = 1.0; - - if ( codec_context->codec_id == CODEC_ID_DVVIDEO ) - { - if ( pkt ) - { - if ( dv_is_pal( pkt ) ) - { - aspect_ratio = dv_is_wide( pkt ) - ? 64.0/45.0 // 16:9 PAL - : 16.0/15.0; // 4:3 PAL - } - else - { - aspect_ratio = dv_is_wide( pkt ) - ? 32.0/27.0 // 16:9 NTSC - : 8.0/9.0; // 4:3 NTSC - } - } - else - { - AVRational ar = -#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(21<<8)+0) - stream->sample_aspect_ratio; -#else - codec_context->sample_aspect_ratio; -#endif - // Override FFmpeg's notion of DV aspect ratios, which are - // based upon a width of 704. Since we do not have a normaliser - // that crops (nor is cropping 720 wide ITU-R 601 video always desirable) - // we just coerce the values to facilitate a passive behaviour through - // the rescale normaliser when using equivalent producers and consumers. - // = display_aspect / (width * height) - if ( ar.num == 10 && ar.den == 11 ) - aspect_ratio = 8.0/9.0; // 4:3 NTSC - else if ( ar.num == 59 && ar.den == 54 ) - aspect_ratio = 16.0/15.0; // 4:3 PAL - else if ( ar.num == 40 && ar.den == 33 ) - aspect_ratio = 32.0/27.0; // 16:9 NTSC - else if ( ar.num == 118 && ar.den == 81 ) - aspect_ratio = 64.0/45.0; // 16:9 PAL - } - } - else - { - AVRational codec_sar = codec_context->sample_aspect_ratio; - AVRational stream_sar = -#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(21<<8)+0) - stream->sample_aspect_ratio; -#else - { 0, 1 }; -#endif - if ( codec_sar.num > 0 ) - aspect_ratio = av_q2d( codec_sar ); - else if ( stream_sar.num > 0 ) - aspect_ratio = av_q2d( stream_sar ); - } - return aspect_ratio; -} - -/** Open the file. -*/ - -static int producer_open( mlt_producer this, mlt_profile profile, char *file ) -{ - // Return an error code (0 == no error) - int error = 0; - - // Context for avformat - AVFormatContext *context = NULL; - - // Get the properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // We will treat everything with the producer fps - double fps = mlt_profile_fps( profile ); - - // Lock the mutex now - avformat_lock( ); - - // If "MRL", then create AVInputFormat - AVInputFormat *format = NULL; - AVFormatParameters *params = NULL; - char *standard = NULL; - char *mrl = strchr( file, ':' ); - - // AV option (0 = both, 1 = video, 2 = audio) - int av = 0; - - // Setting lowest log level - av_log_set_level( -1 ); - - // Only if there is not a protocol specification that avformat can handle - if ( mrl && !url_exist( file ) ) - { - // 'file' becomes format abbreviation - mrl[0] = 0; - - // Lookup the format - format = av_find_input_format( file ); - - // Eat the format designator - file = ++mrl; - - if ( format ) - { - // Allocate params - params = calloc( sizeof( AVFormatParameters ), 1 ); - - // These are required by video4linux (defaults) - params->width = 640; - params->height = 480; - params->time_base= (AVRational){1,25}; - // params->device = file; - params->channels = 2; - params->sample_rate = 48000; - } - - // XXX: this does not work anymore since avdevice - // TODO: make producer_avddevice? - // Parse out params - mrl = strchr( file, '?' ); - while ( mrl ) - { - mrl[0] = 0; - char *name = strdup( ++mrl ); - char *value = strchr( name, ':' ); - if ( value ) - { - value[0] = 0; - value++; - char *t = strchr( value, '&' ); - if ( t ) - t[0] = 0; - if ( !strcmp( name, "frame_rate" ) ) - params->time_base.den = atoi( value ); - else if ( !strcmp( name, "frame_rate_base" ) ) - params->time_base.num = atoi( value ); - else if ( !strcmp( name, "sample_rate" ) ) - params->sample_rate = atoi( value ); - else if ( !strcmp( name, "channels" ) ) - params->channels = atoi( value ); - else if ( !strcmp( name, "width" ) ) - params->width = atoi( value ); - else if ( !strcmp( name, "height" ) ) - params->height = atoi( value ); - else if ( !strcmp( name, "standard" ) ) - { - standard = strdup( value ); - params->standard = standard; - } - else if ( !strcmp( name, "av" ) ) - av = atoi( value ); - } - free( name ); - mrl = strchr( mrl, '&' ); - } - } - - // Now attempt to open the file - error = av_open_input_file( &context, file, format, 0, params ) < 0; - - // Cleanup AVFormatParameters - free( standard ); - free( params ); - - // If successful, then try to get additional info - if ( error == 0 ) - { - // Get the stream info - error = av_find_stream_info( context ) < 0; - - // Continue if no error - if ( error == 0 ) - { - // We will default to the first audio and video streams found - int audio_index = -1; - int video_index = -1; - int av_bypass = 0; - - // Now set properties where we can (use default unknowns if required) - if ( context->duration != AV_NOPTS_VALUE ) - { - // This isn't going to be accurate for all formats - mlt_position frames = ( mlt_position )( ( ( double )context->duration / ( double )AV_TIME_BASE ) * fps + 0.5 ); - mlt_properties_set_position( properties, "out", frames - 1 ); - mlt_properties_set_position( properties, "length", frames ); - } - - // Find default audio and video streams - find_default_streams( properties, context, &audio_index, &video_index ); - - if ( context->start_time != AV_NOPTS_VALUE ) - mlt_properties_set_double( properties, "_start_time", context->start_time ); - - // Check if we're seekable (something funny about mpeg here :-/) - if ( strcmp( file, "pipe:" ) && strncmp( file, "http://", 6 ) && strncmp( file, "udp:", 4 ) && strncmp( file, "tcp:", 4 ) && strncmp( file, "rtsp:", 5 ) && strncmp( file, "rtp:", 4 ) ) - { - mlt_properties_set_int( properties, "seekable", av_seek_frame( context, -1, mlt_properties_get_double( properties, "_start_time" ), AVSEEK_FLAG_BACKWARD ) >= 0 ); - mlt_properties_set_data( properties, "dummy_context", context, 0, producer_file_close, NULL ); - av_open_input_file( &context, file, NULL, 0, NULL ); - av_find_stream_info( context ); - } - else - av_bypass = 1; - - // Store selected audio and video indexes on properties - mlt_properties_set_int( properties, "_audio_index", audio_index ); - mlt_properties_set_int( properties, "_video_index", video_index ); - mlt_properties_set_int( properties, "_last_position", -1 ); - - // Fetch the width, height and aspect ratio - if ( video_index != -1 ) - { - AVCodecContext *codec_context = context->streams[ video_index ]->codec; - mlt_properties_set_int( properties, "width", codec_context->width ); - mlt_properties_set_int( properties, "height", codec_context->height ); - - if ( codec_context->codec_id == CODEC_ID_DVVIDEO ) - { - // Fetch the first frame of DV so we can read it directly - AVPacket pkt; - int ret = 0; - while ( ret >= 0 ) - { - ret = av_read_frame( context, &pkt ); - if ( ret >= 0 && pkt.stream_index == video_index && pkt.size > 0 ) - { - mlt_properties_set_double( properties, "aspect_ratio", - get_aspect_ratio( context->streams[ video_index ], codec_context, &pkt ) ); - break; - } - } - } - else - { - mlt_properties_set_double( properties, "aspect_ratio", - get_aspect_ratio( context->streams[ video_index ], codec_context, NULL ) ); - } - } - - // Read Metadata - if (context->title != NULL) - mlt_properties_set(properties, "meta.attr.title.markup", context->title ); - if (context->author != NULL) - mlt_properties_set(properties, "meta.attr.author.markup", context->author ); - if (context->copyright != NULL) - mlt_properties_set(properties, "meta.attr.copyright.markup", context->copyright ); - if (context->comment != NULL) - mlt_properties_set(properties, "meta.attr.comment.markup", context->comment ); - if (context->album != NULL) - mlt_properties_set(properties, "meta.attr.album.markup", context->album ); - if (context->year != 0) - mlt_properties_set_int(properties, "meta.attr.year.markup", context->year ); - if (context->track != 0) - mlt_properties_set_int(properties, "meta.attr.track.markup", context->track ); - - // We're going to cheat here - for a/v files, we will have two contexts (reasoning will be clear later) - if ( av == 0 && audio_index != -1 && video_index != -1 ) - { - // We'll use the open one as our video_context - mlt_properties_set_data( properties, "video_context", context, 0, producer_file_close, NULL ); - - // And open again for our audio context - av_open_input_file( &context, file, NULL, 0, NULL ); - av_find_stream_info( context ); - - // Audio context - mlt_properties_set_data( properties, "audio_context", context, 0, producer_file_close, NULL ); - } - else if ( av != 2 && video_index != -1 ) - { - // We only have a video context - mlt_properties_set_data( properties, "video_context", context, 0, producer_file_close, NULL ); - } - else if ( audio_index != -1 ) - { - // We only have an audio context - mlt_properties_set_data( properties, "audio_context", context, 0, producer_file_close, NULL ); - } - else - { - // Something has gone wrong - error = -1; - } - - mlt_properties_set_int( properties, "av_bypass", av_bypass ); - } - } - - // Unlock the mutex now - avformat_unlock( ); - - return error; -} - -/** Convert a frame position to a time code. -*/ - -static double producer_time_of_frame( mlt_producer this, mlt_position position ) -{ - return ( double )position / mlt_producer_get_fps( this ); -} - -static inline void convert_image( AVFrame *frame, uint8_t *buffer, int pix_fmt, mlt_image_format format, int width, int height ) -{ -#ifdef SWSCALE - if ( format == mlt_image_yuv420p ) - { - struct SwsContext *context = sws_getContext( width, height, pix_fmt, - width, height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL); - AVPicture output; - output.data[0] = buffer; - output.data[1] = buffer + width * height; - output.data[2] = buffer + ( 3 * width * height ) / 2; - output.linesize[0] = width; - output.linesize[1] = width >> 1; - output.linesize[2] = width >> 1; - sws_scale( context, frame->data, frame->linesize, 0, height, - output.data, output.linesize); - sws_freeContext( context ); - } - else if ( format == mlt_image_rgb24 ) - { - struct SwsContext *context = sws_getContext( width, height, pix_fmt, - width, height, PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL); - AVPicture output; - avpicture_fill( &output, buffer, PIX_FMT_RGB24, width, height ); - sws_scale( context, frame->data, frame->linesize, 0, height, - output.data, output.linesize); - sws_freeContext( context ); - } - else - { - struct SwsContext *context = sws_getContext( width, height, pix_fmt, - width, height, PIX_FMT_YUYV422, SWS_FAST_BILINEAR, NULL, NULL, NULL); - AVPicture output; - avpicture_fill( &output, buffer, PIX_FMT_YUYV422, width, height ); - sws_scale( context, frame->data, frame->linesize, 0, height, - output.data, output.linesize); - sws_freeContext( context ); - } -#else - if ( format == mlt_image_yuv420p ) - { - AVPicture pict; - pict.data[0] = buffer; - pict.data[1] = buffer + width * height; - pict.data[2] = buffer + ( 3 * width * height ) / 2; - pict.linesize[0] = width; - pict.linesize[1] = width >> 1; - pict.linesize[2] = width >> 1; - img_convert( &pict, PIX_FMT_YUV420P, (AVPicture *)frame, pix_fmt, width, height ); - } - else if ( format == mlt_image_rgb24 ) - { - AVPicture output; - avpicture_fill( &output, buffer, PIX_FMT_RGB24, width, height ); - img_convert( &output, PIX_FMT_RGB24, (AVPicture *)frame, pix_fmt, width, height ); - } - else - { - AVPicture output; - avpicture_fill( &output, buffer, PIX_FMT_YUYV422, width, height ); - img_convert( &output, PIX_FMT_YUYV422, (AVPicture *)frame, pix_fmt, width, height ); - } -#endif -} - -/** Allocate the image buffer and set it on the frame. -*/ - -static int allocate_buffer( mlt_properties frame_properties, AVCodecContext *codec_context, uint8_t **buffer, mlt_image_format *format, int *width, int *height ) -{ - int size = 0; - - if ( codec_context->width == 0 || codec_context->height == 0 ) - return size; - - *width = codec_context->width; - *height = codec_context->height; - mlt_properties_set_int( frame_properties, "width", *width ); - mlt_properties_set_int( frame_properties, "height", *height ); - - switch ( *format ) - { - case mlt_image_yuv420p: - size = *width * 3 * ( *height + 1 ) / 2; - break; - case mlt_image_rgb24: - size = *width * ( *height + 1 ) * 3; - break; - default: - *format = mlt_image_yuv422; - size = *width * ( *height + 1 ) * 2; - break; - } - - // Construct the output image - *buffer = mlt_pool_alloc( size ); - if ( *buffer ) - mlt_properties_set_data( frame_properties, "image", *buffer, size, (mlt_destructor)mlt_pool_release, NULL ); - else - size = 0; - - return size; -} - -/** Get an image from a frame. -*/ - -static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the properties from the frame - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the frame number of this frame - mlt_position position = mlt_properties_get_position( frame_properties, "avformat_position" ); - - // Get the producer - mlt_producer this = mlt_properties_get_data( frame_properties, "avformat_producer", NULL ); - - // Get the producer properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Fetch the video_context - AVFormatContext *context = mlt_properties_get_data( properties, "video_context", NULL ); - - // Get the video_index - int index = mlt_properties_get_int( properties, "video_index" ); - - // Obtain the expected frame numer - mlt_position expected = mlt_properties_get_position( properties, "_video_expected" ); - - // Get the video stream - AVStream *stream = context->streams[ index ]; - - // Get codec context - AVCodecContext *codec_context = stream->codec; - - // Packet - AVPacket pkt; - - // Get the conversion frame - AVFrame *av_frame = mlt_properties_get_data( properties, "av_frame", NULL ); - - // Special case pause handling flag - int paused = 0; - - // Special case ffwd handling - int ignore = 0; - - // We may want to use the source fps if available - double source_fps = mlt_properties_get_double( properties, "source_fps" ); - double fps = mlt_producer_get_fps( this ); - - // This is the physical frame position in the source - int req_position = ( int )( position / fps * source_fps + 0.5 ); - - // Get the seekable status - int seekable = mlt_properties_get_int( properties, "seekable" ); - - // Hopefully provide better support for streams... - int av_bypass = mlt_properties_get_int( properties, "av_bypass" ); - - // Determines if we have to decode all frames in a sequence - int must_decode = 1; - - // Temporary hack to improve intra frame only - must_decode = strcmp( codec_context->codec->name, "dnxhd" ) && - strcmp( codec_context->codec->name, "dvvideo" ) && - strcmp( codec_context->codec->name, "huffyuv" ) && - strcmp( codec_context->codec->name, "mjpeg" ) && - strcmp( codec_context->codec->name, "rawvideo" ); - - // Seek if necessary - if ( position != expected ) - { - if ( av_frame != NULL && position + 1 == expected ) - { - // We're paused - use last image - paused = 1; - } - else if ( !seekable && position > expected && ( position - expected ) < 250 ) - { - // Fast forward - seeking is inefficient for small distances - just ignore following frames - ignore = ( int )( ( position - expected ) / fps * source_fps ); - } - else if ( seekable && ( position < expected || position - expected >= 12 ) ) - { - // Calculate the timestamp for the requested frame - int64_t timestamp = ( int64_t )( ( double )req_position / source_fps * AV_TIME_BASE + 0.5 ); - if ( ( uint64_t )context->start_time != AV_NOPTS_VALUE ) - timestamp += context->start_time; - if ( must_decode ) - timestamp -= AV_TIME_BASE; - if ( timestamp < 0 ) - timestamp = 0; - - // Set to the timestamp - av_seek_frame( context, -1, timestamp, AVSEEK_FLAG_BACKWARD ); - - // Remove the cached info relating to the previous position - mlt_properties_set_int( properties, "_current_position", -1 ); - mlt_properties_set_int( properties, "_last_position", -1 ); - mlt_properties_set_data( properties, "av_frame", NULL, 0, NULL, NULL ); - av_frame = NULL; - } - } - - // Duplicate the last image if necessary (see comment on rawvideo below) - int current_position = mlt_properties_get_int( properties, "_current_position" ); - int got_picture = mlt_properties_get_int( properties, "_got_picture" ); - if ( av_frame != NULL && got_picture && ( paused || current_position >= req_position ) && av_bypass == 0 ) - { - // Duplicate it - if ( allocate_buffer( frame_properties, codec_context, buffer, format, width, height ) ) - convert_image( av_frame, *buffer, codec_context->pix_fmt, *format, *width, *height ); - else - mlt_frame_get_image( frame, buffer, format, width, height, writable ); - } - else - { - int ret = 0; - int int_position = 0; - got_picture = 0; - - av_init_packet( &pkt ); - - // Construct an AVFrame for YUV422 conversion - if ( av_frame == NULL ) - av_frame = avcodec_alloc_frame( ); - - while( ret >= 0 && !got_picture ) - { - // Read a packet - ret = av_read_frame( context, &pkt ); - - // We only deal with video from the selected video_index - if ( ret >= 0 && pkt.stream_index == index && pkt.size > 0 ) - { - // Determine time code of the packet - int_position = ( int )( av_q2d( stream->time_base ) * pkt.dts * source_fps + 0.5 ); - if ( context->start_time != AV_NOPTS_VALUE ) - int_position -= ( int )( context->start_time * source_fps / AV_TIME_BASE + 0.5 ); - int last_position = mlt_properties_get_int( properties, "_last_position" ); - if ( int_position == last_position ) - int_position = last_position + 1; - mlt_properties_set_int( properties, "_last_position", int_position ); - - // Decode the image - if ( must_decode || int_position >= req_position ) - ret = avcodec_decode_video( codec_context, av_frame, &got_picture, pkt.data, pkt.size ); - - if ( got_picture ) - { - // Handle ignore - if ( int_position < req_position ) - { - ignore = 0; - got_picture = 0; - } - else if ( int_position >= req_position ) - { - ignore = 0; - } - else if ( ignore -- ) - { - got_picture = 0; - } - } - av_free_packet( &pkt ); - } - else if ( ret >= 0 ) - { - av_free_packet( &pkt ); - } - - // Now handle the picture if we have one - if ( got_picture ) - { - if ( allocate_buffer( frame_properties, codec_context, buffer, format, width, height ) ) - { - convert_image( av_frame, *buffer, codec_context->pix_fmt, *format, *width, *height ); - mlt_properties_set_int( frame_properties, "progressive", !av_frame->interlaced_frame ); - mlt_properties_set_int( properties, "top_field_first", av_frame->top_field_first ); - mlt_properties_set_int( properties, "_current_position", int_position ); - mlt_properties_set_int( properties, "_got_picture", 1 ); - mlt_properties_set_data( properties, "av_frame", av_frame, 0, av_free, NULL ); - } - else - { - got_picture = 0; - } - } - } - if ( !got_picture ) - mlt_frame_get_image( frame, buffer, format, width, height, writable ); - } - - // Very untidy - for rawvideo, the packet contains the frame, hence the free packet - // above will break the pause behaviour - so we wipe the frame now - if ( !strcmp( codec_context->codec->name, "rawvideo" ) ) - mlt_properties_set_data( properties, "av_frame", NULL, 0, NULL, NULL ); - - // Set the field order property for this frame - mlt_properties_set_int( frame_properties, "top_field_first", mlt_properties_get_int( properties, "top_field_first" ) ); - - // Regardless of speed, we expect to get the next frame (cos we ain't too bright) - mlt_properties_set_position( properties, "_video_expected", position + 1 ); - - return 0; -} - -/** Process properties as AVOptions and apply to AV context obj -*/ - -static void apply_properties( void *obj, mlt_properties properties, int flags ) -{ - int i; - int count = mlt_properties_count( properties ); - for ( i = 0; i < count; i++ ) - { - const char *opt_name = mlt_properties_get_name( properties, i ); - const AVOption *opt = av_find_opt( obj, opt_name, NULL, flags, flags ); - if ( opt != NULL ) -#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(7<<8)+0) - av_set_string3( obj, opt_name, mlt_properties_get( properties, opt_name), 0, NULL ); -#elif LIBAVCODEC_VERSION_INT >= ((51<<16)+(59<<8)+0) - av_set_string2( obj, opt_name, mlt_properties_get( properties, opt_name), 0 ); -#else - av_set_string( obj, opt_name, mlt_properties_get( properties, opt_name) ); -#endif - } -} - -/** Set up video handling. -*/ - -static void producer_set_up_video( mlt_producer this, mlt_frame frame ) -{ - // Get the properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Fetch the video_context - AVFormatContext *context = mlt_properties_get_data( properties, "video_context", NULL ); - - // Get the video_index - int index = mlt_properties_get_int( properties, "video_index" ); - - // Reopen the file if necessary - if ( !context && index > -1 ) - { - mlt_events_block( properties, this ); - producer_open( this, mlt_service_profile( MLT_PRODUCER_SERVICE(this) ), - mlt_properties_get( properties, "resource" ) ); - context = mlt_properties_get_data( properties, "video_context", NULL ); - mlt_properties_set_data( properties, "dummy_context", NULL, 0, NULL, NULL ); - mlt_events_unblock( properties, this ); - - // Process properties as AVOptions - apply_properties( context, properties, AV_OPT_FLAG_DECODING_PARAM ); - } - - // Exception handling for video_index - if ( context && index >= (int) context->nb_streams ) - { - // Get the last video stream - for ( index = context->nb_streams - 1; index >= 0 && context->streams[ index ]->codec->codec_type != CODEC_TYPE_VIDEO; --index ); - mlt_properties_set_int( properties, "video_index", index ); - } - if ( context && index > -1 && context->streams[ index ]->codec->codec_type != CODEC_TYPE_VIDEO ) - { - // Invalidate the video stream - index = -1; - mlt_properties_set_int( properties, "video_index", index ); - } - - // Get the frame properties - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - if ( context && index > -1 ) - { - // Get the video stream - AVStream *stream = context->streams[ index ]; - - // Get codec context - AVCodecContext *codec_context = stream->codec; - - // Get the codec - AVCodec *codec = mlt_properties_get_data( properties, "video_codec", NULL ); - - // Update the video properties if the index changed - if ( index != mlt_properties_get_int( properties, "_video_index" ) ) - { - // Reset the video properties if the index changed - mlt_properties_set_int( properties, "_video_index", index ); - mlt_properties_set_data( properties, "video_codec", NULL, 0, NULL, NULL ); - mlt_properties_set_int( properties, "width", codec_context->width ); - mlt_properties_set_int( properties, "height", codec_context->height ); - // TODO: get the first usable AVPacket and reset the stream position - mlt_properties_set_double( properties, "aspect_ratio", - get_aspect_ratio( context->streams[ index ], codec_context, NULL ) ); - codec = NULL; - } - - // Initialise the codec if necessary - if ( codec == NULL ) - { - // Initialise multi-threading - int thread_count = mlt_properties_get_int( properties, "threads" ); - if ( thread_count == 0 && getenv( "MLT_AVFORMAT_THREADS" ) ) - thread_count = atoi( getenv( "MLT_AVFORMAT_THREADS" ) ); - if ( thread_count > 1 ) - { - avcodec_thread_init( codec_context, thread_count ); - codec_context->thread_count = thread_count; - } - - // Find the codec - codec = avcodec_find_decoder( codec_context->codec_id ); - - // If we don't have a codec and we can't initialise it, we can't do much more... - avformat_lock( ); - if ( codec != NULL && avcodec_open( codec_context, codec ) >= 0 ) - { - // Now store the codec with its destructor - mlt_properties_set_data( properties, "video_codec", codec_context, 0, producer_codec_close, NULL ); - } - else - { - // Remember that we can't use this later - mlt_properties_set_int( properties, "video_index", -1 ); - index = -1; - } - avformat_unlock( ); - - // Process properties as AVOptions - apply_properties( codec_context, properties, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM ); - } - - // No codec, no show... - if ( codec && index > -1 ) - { - double source_fps = 0; - double force_aspect_ratio = mlt_properties_get_double( properties, "force_aspect_ratio" ); - double aspect_ratio = ( force_aspect_ratio > 0.0 ) ? - force_aspect_ratio : mlt_properties_get_double( properties, "aspect_ratio" ); - - // Determine the fps - source_fps = ( double )codec_context->time_base.den / ( codec_context->time_base.num == 0 ? 1 : codec_context->time_base.num ); - - // We'll use fps if it's available - if ( source_fps > 0 ) - mlt_properties_set_double( properties, "source_fps", source_fps ); - else - mlt_properties_set_double( properties, "source_fps", mlt_producer_get_fps( this ) ); - mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio ); - - // Set the width and height - mlt_properties_set_int( frame_properties, "width", codec_context->width ); - mlt_properties_set_int( frame_properties, "height", codec_context->height ); - mlt_properties_set_int( frame_properties, "real_width", codec_context->width ); - mlt_properties_set_int( frame_properties, "real_height", codec_context->height ); - mlt_properties_set_double( frame_properties, "aspect_ratio", aspect_ratio ); - - mlt_frame_push_get_image( frame, producer_get_image ); - mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL ); - } - else - { - mlt_properties_set_int( frame_properties, "test_image", 1 ); - } - } - else - { - mlt_properties_set_int( frame_properties, "test_image", 1 ); - } -} - -/** Get the audio from a frame. -*/ - -static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the properties from the frame - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the frame number of this frame - mlt_position position = mlt_properties_get_position( frame_properties, "avformat_position" ); - - // Get the producer - mlt_producer this = mlt_properties_get_data( frame_properties, "avformat_producer", NULL ); - - // Get the producer properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Fetch the audio_context - AVFormatContext *context = mlt_properties_get_data( properties, "audio_context", NULL ); - - // Get the audio_index - int index = mlt_properties_get_int( properties, "audio_index" ); - - // Get the seekable status - int seekable = mlt_properties_get_int( properties, "seekable" ); - - // Obtain the expected frame numer - mlt_position expected = mlt_properties_get_position( properties, "_audio_expected" ); - - // Obtain the resample context if it exists (not always needed) - ReSampleContext *resample = mlt_properties_get_data( properties, "audio_resample", NULL ); - -#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0)) - // Get the format converter context if it exists - AVAudioConvert *convert = mlt_properties_get_data( properties, "audio_convert", NULL ); -#endif - - // Obtain the audio buffers - int16_t *audio_buffer = mlt_properties_get_data( properties, "audio_buffer", NULL ); - int16_t *decode_buffer = mlt_properties_get_data( properties, "decode_buffer", NULL ); - int16_t *convert_buffer = mlt_properties_get_data( properties, "convert_buffer", NULL ); - - // Get amount of audio used - int audio_used = mlt_properties_get_int( properties, "_audio_used" ); - - // Calculate the real time code - double real_timecode = producer_time_of_frame( this, position ); - - // Get the audio stream - AVStream *stream = context->streams[ index ]; - - // Get codec context - AVCodecContext *codec_context = stream->codec; - - // Packet - AVPacket pkt; - - // Number of frames to ignore (for ffwd) - int ignore = 0; - - // Flag for paused (silence) - int paused = 0; - - // Check for resample and create if necessary - if ( resample == NULL && codec_context->channels <= 2 ) - { - // Create the resampler - resample = audio_resample_init( *channels, codec_context->channels, *frequency, codec_context->sample_rate ); - - // And store it on properties - mlt_properties_set_data( properties, "audio_resample", resample, 0, ( mlt_destructor )audio_resample_close, NULL ); - } - else if ( resample == NULL ) - { - *channels = codec_context->channels; - *frequency = codec_context->sample_rate; - } - -#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0)) - // Check for audio format converter and create if necessary - // TODO: support higher resolutions than 16-bit. - if ( convert == NULL && codec_context->sample_fmt != SAMPLE_FMT_S16 ) - { - // Create single channel converter for interleaved with no mixing matrix - convert = av_audio_convert_alloc( SAMPLE_FMT_S16, 1, codec_context->sample_fmt, 1, NULL, 0 ); - mlt_properties_set_data( properties, "audio_convert", convert, 0, ( mlt_destructor )av_audio_convert_free, NULL ); - } -#endif - - // Check for audio buffer and create if necessary - if ( audio_buffer == NULL ) - { - // Allocate the audio buffer - audio_buffer = mlt_pool_alloc( AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof( int16_t ) ); - - // And store it on properties for reuse - mlt_properties_set_data( properties, "audio_buffer", audio_buffer, 0, ( mlt_destructor )mlt_pool_release, NULL ); - } - - // Check for decoder buffer and create if necessary - if ( decode_buffer == NULL ) - { - // Allocate the audio buffer - decode_buffer = av_malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof( int16_t ) ); - - // And store it on properties for reuse - mlt_properties_set_data( properties, "decode_buffer", decode_buffer, 0, ( mlt_destructor )av_free, NULL ); - } - -#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0)) - // Check for format converter buffer and create if necessary - if ( resample && convert && convert_buffer == NULL ) - { - // Allocate the audio buffer - convert_buffer = mlt_pool_alloc( AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof( int16_t ) ); - - // And store it on properties for reuse - mlt_properties_set_data( properties, "convert_buffer", convert_buffer, 0, ( mlt_destructor )mlt_pool_release, NULL ); - } -#endif - - // Seek if necessary - if ( position != expected ) - { - if ( position + 1 == expected ) - { - // We're paused - silence required - paused = 1; - } - else if ( !seekable && position > expected && ( position - expected ) < 250 ) - { - // Fast forward - seeking is inefficient for small distances - just ignore following frames - ignore = position - expected; - } - else if ( position < expected || position - expected >= 12 ) - { - int64_t timestamp = ( int64_t )( real_timecode * AV_TIME_BASE + 0.5 ); - if ( context->start_time != AV_NOPTS_VALUE ) - timestamp += context->start_time; - if ( timestamp < 0 ) - timestamp = 0; - - // Set to the real timecode - if ( av_seek_frame( context, -1, timestamp, AVSEEK_FLAG_BACKWARD ) != 0 ) - paused = 1; - - // Clear the usage in the audio buffer - audio_used = 0; - } - } - - // Get the audio if required - if ( !paused ) - { - int ret = 0; - int got_audio = 0; - - av_init_packet( &pkt ); - - while( ret >= 0 && !got_audio ) - { - // Check if the buffer already contains the samples required - if ( audio_used >= *samples && ignore == 0 ) - { - got_audio = 1; - break; - } - - // Read a packet - ret = av_read_frame( context, &pkt ); - - int len = pkt.size; - uint8_t *ptr = pkt.data; - - // We only deal with audio from the selected audio_index - while ( ptr != NULL && ret >= 0 && pkt.stream_index == index && len > 0 ) - { - int data_size = sizeof( int16_t ) * AVCODEC_MAX_AUDIO_FRAME_SIZE; - - // Decode the audio -#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(29<<8)+0)) - ret = avcodec_decode_audio2( codec_context, decode_buffer, &data_size, ptr, len ); -#else - ret = avcodec_decode_audio( codec_context, decode_buffer, &data_size, ptr, len ); -#endif - if ( ret < 0 ) - { - ret = 0; - break; - } - - len -= ret; - ptr += ret; - - if ( data_size > 0 ) - { - int src_stride[6]= { av_get_bits_per_sample_format( codec_context->sample_fmt ) / 8 }; - int dst_stride[6]= { av_get_bits_per_sample_format( SAMPLE_FMT_S16 ) / 8 }; - - if ( resample ) - { - int16_t *source = decode_buffer; - int16_t *dest = &audio_buffer[ audio_used * *channels ]; - int convert_samples = data_size / src_stride[0]; - -#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0)) - if ( convert ) - { - const void *src_buf[6] = { decode_buffer }; - void *dst_buf[6] = { convert_buffer }; - av_audio_convert( convert, dst_buf, dst_stride, src_buf, src_stride, convert_samples ); - source = convert_buffer; - } -#endif - audio_used += audio_resample( resample, dest, source, convert_samples / codec_context->channels ); - } - else - { -#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0)) - if ( convert ) - { - const void *src_buf[6] = { decode_buffer }; - void *dst_buf[6] = { &audio_buffer[ audio_used * *channels ] }; - av_audio_convert( convert, dst_buf, dst_stride, src_buf, src_stride, data_size / src_stride[0] ); - } - else -#endif - { - memcpy( &audio_buffer[ audio_used * *channels ], decode_buffer, data_size ); - } - audio_used += data_size / *channels / src_stride[0]; - } - - // Handle ignore - while ( ignore && audio_used > *samples ) - { - ignore --; - audio_used -= *samples; - memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * sizeof( int16_t ) ); - } - } - - // If we're behind, ignore this packet - if ( pkt.pts >= 0 ) - { - double current_pts = av_q2d( stream->time_base ) * pkt.pts; - double source_fps = mlt_properties_get_double( properties, "source_fps" ); - int req_position = ( int )( real_timecode * source_fps + 0.5 ); - int int_position = ( int )( current_pts * source_fps + 0.5 ); - - if ( context->start_time != AV_NOPTS_VALUE ) - int_position -= ( int )( context->start_time * source_fps / AV_TIME_BASE + 0.5 ); - if ( seekable && !ignore && int_position < req_position ) - ignore = 1; - } - } - - // We're finished with this packet regardless - av_free_packet( &pkt ); - } - - *buffer = mlt_pool_alloc( *samples * *channels * sizeof( int16_t ) ); - mlt_properties_set_data( frame_properties, "audio", *buffer, 0, ( mlt_destructor )mlt_pool_release, NULL ); - - // Now handle the audio if we have enough - if ( audio_used >= *samples ) - { - memcpy( *buffer, audio_buffer, *samples * *channels * sizeof( int16_t ) ); - audio_used -= *samples; - memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * *channels * sizeof( int16_t ) ); - } - else - { - memset( *buffer, 0, *samples * *channels * sizeof( int16_t ) ); - } - - // Store the number of audio samples still available - mlt_properties_set_int( properties, "_audio_used", audio_used ); - } - else - { - // Get silence and don't touch the context - mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); - } - - // Regardless of speed (other than paused), we expect to get the next frame - if ( !paused ) - mlt_properties_set_position( properties, "_audio_expected", position + 1 ); - - return 0; -} - -/** Set up audio handling. -*/ - -static void producer_set_up_audio( mlt_producer this, mlt_frame frame ) -{ - // Get the properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Fetch the audio_context - AVFormatContext *context = mlt_properties_get_data( properties, "audio_context", NULL ); - - // Get the audio_index - int index = mlt_properties_get_int( properties, "audio_index" ); - - // Reopen the file if necessary - if ( !context && index > -1 ) - { - mlt_events_block( properties, this ); - producer_open( this, mlt_service_profile( MLT_PRODUCER_SERVICE(this) ), - mlt_properties_get( properties, "resource" ) ); - context = mlt_properties_get_data( properties, "audio_context", NULL ); - mlt_properties_set_data( properties, "dummy_context", NULL, 0, NULL, NULL ); - mlt_events_unblock( properties, this ); - } - - // Exception handling for audio_index - if ( context && index >= (int) context->nb_streams ) - { - for ( index = context->nb_streams - 1; index >= 0 && context->streams[ index ]->codec->codec_type != CODEC_TYPE_AUDIO; --index ); - mlt_properties_set_int( properties, "audio_index", index ); - } - if ( context && index > -1 && context->streams[ index ]->codec->codec_type != CODEC_TYPE_AUDIO ) - { - index = -1; - mlt_properties_set_int( properties, "audio_index", index ); - } - - // Update the audio properties if the index changed - if ( index > -1 && index != mlt_properties_get_int( properties, "_audio_index" ) ) - { - mlt_properties_set_int( properties, "_audio_index", index ); - mlt_properties_set_data( properties, "audio_codec", NULL, 0, NULL, NULL ); - } - - // Deal with audio context - if ( context != NULL && index > -1 ) - { - // Get the frame properties - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Get the audio stream - AVStream *stream = context->streams[ index ]; - - // Get codec context - AVCodecContext *codec_context = stream->codec; - - // Get the codec - AVCodec *codec = mlt_properties_get_data( properties, "audio_codec", NULL ); - - // Initialise the codec if necessary - if ( codec == NULL ) - { - // Find the codec - codec = avcodec_find_decoder( codec_context->codec_id ); - - // If we don't have a codec and we can't initialise it, we can't do much more... - avformat_lock( ); - if ( codec != NULL && avcodec_open( codec_context, codec ) >= 0 ) - { - // Now store the codec with its destructor - mlt_properties_set_data( properties, "audio_codec", codec_context, 0, producer_codec_close, NULL ); - - } - else - { - // Remember that we can't use this later - mlt_properties_set_int( properties, "audio_index", -1 ); - index = -1; - } - avformat_unlock( ); - - // Process properties as AVOptions - apply_properties( codec_context, properties, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM ); - } - - // No codec, no show... - if ( codec && index > -1 ) - { - mlt_frame_push_audio( frame, producer_get_audio ); - mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL ); - mlt_properties_set_int( frame_properties, "frequency", codec_context->sample_rate ); - mlt_properties_set_int( frame_properties, "channels", codec_context->channels ); - } - } -} - -/** Our get frame implementation. -*/ - -static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ) -{ - // Create an empty frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( this ) ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( this ) ); - - // Set the position of this producer - mlt_properties_set_position( MLT_FRAME_PROPERTIES( *frame ), "avformat_position", mlt_producer_frame( this ) ); - - // Set up the video - producer_set_up_video( this, *frame ); - - // Set up the audio - producer_set_up_audio( this, *frame ); - - // Set the aspect_ratio - mlt_properties_set_double( MLT_FRAME_PROPERTIES( *frame ), "aspect_ratio", mlt_properties_get_double( MLT_PRODUCER_PROPERTIES( this ), "aspect_ratio" ) ); - - // Calculate the next timecode - mlt_producer_prepare_next( this ); - - return 0; -} diff --git a/src/modules/avformat/producer_avformat.yml b/src/modules/avformat/producer_avformat.yml deleted file mode 100644 index 86ce738..0000000 --- a/src/modules/avformat/producer_avformat.yml +++ /dev/null @@ -1,171 +0,0 @@ -schema_version: 0.1 -type: producer # consumer, filter, producer, or transition -identifier: avformat -title: FFmpeg Reader -version: 0.2.5 -copyright: Copyright (C) 2003-2008 Ushodaya Enterprises Limited -license: LGPL -language: en -url: http://www.ffmpeg.org/ -creator: Charles Yates -contributor: - - Dan Dennedy -tags: - - Audio # this may produce audio - - Video # this may produce video -description: Read an audio and/or video file using FFmpeg -icon: - filename: avformat/producer.png # relative to $MLT_DATA/modules/ - content-type: image/png - content-encoding: base64 # could also be hex or none if inline SVG - content: | - iVBORw0KGgoAAAANSUhEUgAAABgAAAAPCAYAAAD+pA/bAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI - WXMAAAsSAAALEgHS3X78AAAAB3RJTUUH1gsBEgMLZIL+swAAAB10RVh0Q29tbWVudABDcmVhdGVk - IHdpdGggVGhlIEdJTVDvZCVuAAAEgUlEQVQ4y2VUSWwbZRT+5p/xP4v3eIntceLEThOylKgkB070 - UAUOCNFDFYkIVeqBijMHQKiCAwLEDbVIPVQCUalFQggph6pUoWKRWoS6RCGJ04biOG7sOI638TJe - xjM/FwwRfKf3vve99+kd3uNubNxgVb0Km2W7Tbt06fQLpwv4G8u3k6/88nvJcXYhnJ+dGfsRR/Dl - 8tqpfKkZJ736d++cf6nU53Nra0utTOarVrMpdCj9XFhJr2C1sQq1pZ6ac8zNAljpi7ezzc+e5Lvx - je29H8rlyk8DA14GAOl05tT1n6tf39uqBM69GFgAsNjvaezsvKVfuyZkKxXIi4tvknn/PCQi4cA4 - QMQf+aIv3Nvbm0sVTGe9zfDg8eGxUrk83689eFQcyhStQLluYG+/NNfny6VSsLW5Ge3pOjSHAy2e - /4TwjP84KAfBKRzW99f59G7aAQCVav20SZQAtdlQbfGxteTuNACkd/dsguR8W9NNiKKEVFbjisUi - BQAtnz8rFAq+LgAWDjN/IpEkk97JzYQjAdkhI2fkwtVG9X0AWN+pwTA5iJSH1qEoaMZC8tFjfv3J - IckcdiYNk0GUZVRbXKipt5YAoP7wYZDXNKHOGKR4fCs+NbVGBpwDt3zw3VEUBbqo437qvjuXy7kr - HbtqWQzUJgC8Ar2Dpe1UXpgZC763W+RAOAaR2tAxRTmV3kvsJJPjSrf7umEYqAoC1NnZVCAY3CLD - 6nBpfnC+4hJc4B08DGqc1xr1l5126RzAIHAWqCjjj1wb8eHQq9uZ6nS9a4PAmaACD8bLWN16itrG - hoJ8Ptw2TVjRKAZjsWUAIABACHk3RmOQ7BIyegbpg/1oqWGBoAc0U5BFAt20o1CqXSk26YLZM8Aa - u5AEAwKV4XQNLHpGRq5zpRJ0QuCdmUGpUPgGAAQAoKBPJ5wTyDfzKLMyGMGntRZAmIHxMA/TTnDA - e3FvM+siXhfMdgXjIQbmUpCvMjTa7fFG5imUdhtNSYIcCCxHx8Y6/2zgUTwNq2Nd8FIvYAHFch1d - RmHjuhhVfdnjI1LPYVeQaw3gsMZAmYYTk+oT1SdBkiSU6z3U6k30AHR9PrhU9WYoHP7XYHR41Jpw - TxSDQhAuzgXLtIMQG0RioFwuX3IrwiWPnUByDsKyGPxKB5S3Phj0UkgiRdMQ0FYcqBECFgj8GY7F - 7vZvg/QDl+S66mg5fg2IATDBC45jkPgOJhODLa8dN4d8BJQKYN06RgfF/eNTibRpWVcdsg2MV1An - FJrbDfXEiWxEVdf/ZxCPxVvTnmkjqgzB4p0gMGGnPUyMjUANupNusXNHpDxYt4wR1XtrKBq9a3W0 - B047hSg7ofUIxMlJePz+K0d/FjmahLyh146rzyUNw0Jby8LGWvckSbwcjUayx1RpzWZWELR3jZln - Eh8CwDFVgcLr4HpNVDtMi588ecEbCHx7dKZwNBkODed+W318Zipk3Rx1iTG9GbwYiUQMAAj53Zef - H2u/Ua16L4ZCgykA8A94vn/W1DdH3dK0wIdXwkNDH+E/+Avfv/E5LPIz8wAAAABJRU5ErkJggg== - -notes: Implementation or additional usage notes go here. -bugs: # this can be just for documentation, or the tool may disclose it to help user avoid pitfalls - - Audio sync discrepancy with some content. - - Not all libavformat supported formats are seekable. - - > - Seeking is not always accurate. Sometimes it doesn't seek to I-frames so you - may get junk for a few frames. - - > - Fails to play beyond first frame of video of sources with PTS not starting - at 0 (video4linux). - -parameters: - - identifier: argument # 'argument' is a reserved name for a value supplied to the factory - title: File # the title can be used as a label for the widget - type: string - description: | - A file name specification or URL in the form: - [{protocol}|{format}]:{resource}[?{format-parameter}[&{format-parameter}...]] - For example, video4linux:/dev/video1?width:320&height:240 - Note: on the bash command line, & must be escaped as '\&'. - Also, note the use of ':' instead of '=' for parameters. - Use 'f-list' to see a list of supported file formats. - Use 'vcodec-list' to see a list of supported video decoders. - Use 'acodec-list' to see a list of supported audio decoders. - readonly: no - required: yes - mutable: no - widget: fileopen # could provide a button to use a file-open dialog - - - identifier: audio_index # the name is the mlt_properties name - title: Audio Index - type: integer - # the description can be used in a tool tip - description: Choose the index of audio stream to use (-1 is off) - readonly: no - mutable: no - minimum: -1 - # when maximum not specified, the scalar limit is used - default: 0 - widget: spinner - - - identifier: video_index - title: Video Index - type: integer - description: Choose the index of video stream to use (-1 is off) - readonly: no - mutable: no - minimum: -1 - default: 0 - widget: spinner - - - identifier: in - title: In Point - type: time # time is not implemented, but it will correspond to the mlt_position replacement - description: Set the start time offset to use within the clip - readonly: no - mutable: no - minimum: 0 - default: 0 - widget: timecode # this is a special form of time value/code entry (e.g. see Kino) - - - identifier: out - title: Out Point - type: time - description: Set the ending time offset to use within the clip - readonly: no - minimum: 0 - mutable: no - widget: timecode # as opposed to time, which could be confused for a wallclock-style time widget - - - identifier: threads - title: Decoding Threads - type: integer - description: Choose the number of threads to use in the decoder(s) - readonly: no - mutable: no - minimum: 0 - maximum: 4 - default: 1 - widget: spinner - unit: threads # the unit is a label that appears after the widget - - - identifier: force_aspect_ratio - title: Sample Aspect Ratio - type: float - description: Optionally override a (mis)detected aspect ratio - readonly: no - mutable: yes - minimum: 0.001 # just a UI suggestion - maximum: 9.999 # just a suggestion - # no default property means it should be blank in the UI and not applied unless provided - - - identifier: resource - title: File - type: string - description: file or protocol specification - readonly: yes - - - identifier: source_fps - title: Frame Rate - type: float - scale: 2 # scale is the number of digits to display after the decimal point - description: the framerate of the resource - readonly: yes - unit: frames/second - - - identifier: aspect_ratio - title: Sample Aspect Ratio - type: float - description: > - The sample aspect ratio of the resource. - This is determined on every frame read. - readonly: yes - - - identifier: length - title: Duration - type: time - description: duration - readonly: yes - widget: timecode - - - identifier: seekable - title: Supports Seek - type: integer - description: if the resource can seek - readonly: yes diff --git a/src/modules/configure b/src/modules/configure deleted file mode 100755 index e80a585..0000000 --- a/src/modules/configure +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -# Clean up disables if not in help mode -[ "$help" != "1" ] && rm -f disable-* producers.dat filters.dat transitions.dat consumers.dat - -# Create the make.inc file -echo SUBDIRS = `find . -maxdepth 1 -type d | grep -v .svn | grep -v "^.$" | sed 's/\.\///'` > make.inc - -# Iterate through arguments -for i in "$@" -do - case $i in - --disable-* ) touch disable-${i#--disable-} ;; - esac -done - -# Iterate through each of the components -for i in * -do - if [ -d $i -a \( "$help" = "1" -o ! -f disable-$i \) ] - then - if [ "$gpl" = "true" -o ! -f $i/gpl ] - then - [ -f $i/Makefile -a "$help" = "0" ] && echo "Configuring modules/$i:" - if [ -x $i/configure ] - then - olddir2=`pwd` - cd $i - ./configure "$@" - [ $? != 0 ] && exit 1 - cd $olddir2 - elif [ -f $i/configure ] - then - echo " configure script is not set executable!" - fi - elif [ "$help" = "0" ] - then - touch disable-$i - fi - fi -done - diff --git a/src/modules/core/Makefile b/src/modules/core/Makefile deleted file mode 100644 index a3132ae..0000000 --- a/src/modules/core/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltcore$(LIBSUF) - -OBJS = factory.o \ - producer_colour.o \ - producer_consumer.o \ - producer_noise.o \ - producer_ppm.o \ - filter_brightness.o \ - filter_channelcopy.o \ - filter_crop.o \ - filter_data_feed.o \ - filter_data_show.o \ - filter_gamma.o \ - filter_greyscale.o \ - filter_luma.o \ - filter_mirror.o \ - filter_mono.o \ - filter_obscure.o \ - filter_region.o \ - filter_rescale.o \ - filter_resize.o \ - filter_transition.o \ - filter_watermark.o \ - transition_composite.o \ - transition_luma.o \ - transition_mix.o \ - transition_region.o \ - consumer_null.o - -ASM_OBJS = - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) $(ASM_OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(ASM_OBJS) $(LDFLAGS) - -composite_line_yuv_mmx.o: composite_line_yuv_mmx.S - $(CC) -o $@ -c composite_line_yuv_mmx.S - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(ASM_OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - install -m 644 ../data_fx.properties "$(DESTDIR)$(prefix)/share/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/core/composite_line_yuv_mmx.S b/src/modules/core/composite_line_yuv_mmx.S deleted file mode 100644 index 27af4dc..0000000 --- a/src/modules/core/composite_line_yuv_mmx.S +++ /dev/null @@ -1,211 +0,0 @@ - .file "composite_line_yuv_mmx" - .version "01.01" - -gcc2_compiled.: -.data - -.text - .align 16 - -#if !defined(__MINGW32__) && !defined(__CYGWIN__) -.globl composite_line_yuv_mmx - .type composite_line_yuv_mmx,@function -composite_line_yuv_mmx: -#else -.globl _composite_line_yuv_mmx -_composite_line_yuv_mmx: -#endif - -/* - * Arguments - * - * dest: 8(%ebp) %esi - * src: 12(%ebp) - * width_src: 16(%ebp) - * alpha: 20(%ebp) - * weight: 24(%ebp) - * luma: 28(%ebp) - * softness: 32(%ebp) - */ - -/* - * Function call entry - */ - pushl %ebp - movl %esp,%ebp - subl $28,%esp - pushl %edi - pushl %esi - pushl %ebx - -/* Initialise */ - movl 8(%ebp), %esi # get dest - movl $0, %edx # j = 0 - -.loop: - - movl $0xffff, %ecx # a = 255 - cmpl $0, 20(%ebp) # if alpha == NULL - je .noalpha - movl 20(%ebp), %edi # a = alpha[ j ] - movb (%edi,%edx), %cl -.noalpha: - movl %ecx, -24(%ebp) # save ecx - - movl 24(%ebp), %eax # mix = weight - cmpl $0, 28(%ebp) # if luma == NULL - je .noluma - movl 28(%ebp), %edi # mix = ... - movl %edx, %ebx - sall $1, %ebx - movw (%edi,%ebx), %bx # luma[ j*2 ] - cmpl %ebx, %eax - jl .luma0 - movl %ebx, %ecx - addl 32(%ebp), %ecx # + softness - cmpl %ecx, %eax - jge .luma1 - /* TODO: linear interpolate between edges */ - subw %bx, %ax - sall $8, %eax - subw %bx, %cx - movl %edx, %ebx - divw %cx - movl %ebx, %edx - jmp .noluma -.luma0: - movl $0, %eax - jmp .noluma -.luma1: - movl $0xffff, %eax -.noluma: - shrl $8, %eax - - movl %edx, %ebx # edx will be destroyed by mulw - movl -24(%ebp), %ecx # restore ecx - mull %ecx # mix = mix * a... - movl %ebx, %edx # restore edx - shrl $8, %eax # >>8 - andl $0xff, %eax - -/* put alpha and (1-alpha) into mm0 */ -/* 0 aa 0 1-a 0 aa 0 1-a */ - - /* duplicate word */ - movl %eax, %ecx - shll $16, %ecx - orl %eax, %ecx - - movd %ecx, %mm1 - - /* (1 << 16) - mix */ - movl $0x000000ff, %ecx - subl %eax, %ecx - andl $0xff, %ecx - - /* duplicate word */ - movl %ecx, %eax - shll $16, %eax - orl %eax, %ecx - - movd %ecx, %mm0 - - /* unpack words into double words */ - punpcklwd %mm1, %mm0 - -/* put src yuv and dest yuv into mm1 */ -/* 0 UVs 0 UVd 0 Ys 0 Yd */ - - movl 12(%ebp), %edi # get src - movb (%edi), %cl - shll $8, %ecx - movb 1(%edi), %al - shll $24, %eax - orl %eax, %ecx - - movb (%esi), %al # get dest - orl %eax, %ecx - movb 1(%esi), %al - shll $16, %eax - orl %eax, %ecx - - movd %ecx, %mm1 - punpcklbw %mm4, %mm1 - -/* alpha composite */ - pmaddwd %mm1, %mm0 - psrld $8, %mm0 - -/* store result */ - movd %mm0, %eax - movb %al, (%esi) - pextrw $2, %mm0, %eax - movl $128, %eax - movb %al, 1(%esi) - -/* for..next */ - addl $1, %edx # j++ - cmpl 16(%ebp), %edx # if ( j == width_src ) - jge .out - - addl $2, %esi - addl $2, 12(%ebp) - - jmp .loop - -.out: - emms - leal -40(%ebp),%esp - popl %ebx - popl %esi - popl %edi - movl %ebp,%esp - popl %ebp - ret - - -/********************************************/ - -.align 8 -#if !defined(__MINGW32__) && !defined(__CYGWIN__) -.globl composite_have_mmx - .type composite_have_mmx,@function -composite_have_mmx: -#else -.globl _composite_have_mmx -_composite_have_mmx: -#endif - - push %ebx - -# Check if bit 21 in flags word is writeable - - pushfl - popl %eax - movl %eax,%ebx - xorl $0x00200000, %eax - pushl %eax - popfl - pushfl - popl %eax - - cmpl %eax, %ebx - - je .notfound - -# OK, we have CPUID - - movl $1, %eax - cpuid - - test $0x00800000, %edx - jz .notfound - - movl $1, %eax - jmp .out2 - -.notfound: - movl $0, %eax -.out2: - popl %ebx - ret diff --git a/src/modules/core/consumer_null.c b/src/modules/core/consumer_null.c deleted file mode 100644 index e96c8cd..0000000 --- a/src/modules/core/consumer_null.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * consumer_null.c -- a null consumer - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// mlt Header files -#include -#include - -// System header files -#include -#include -#include -#include - -// Forward references. -static int consumer_start( mlt_consumer this ); -static int consumer_stop( mlt_consumer this ); -static int consumer_is_stopped( mlt_consumer this ); -static void *consumer_thread( void *arg ); -static void consumer_close( mlt_consumer this ); - -/** Initialise the dv consumer. -*/ - -mlt_consumer consumer_null_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Allocate the consumer - mlt_consumer this = mlt_consumer_new( profile ); - - // If memory allocated and initialises without error - if ( this != NULL ) - { - // Assign close callback - this->close = consumer_close; - - // Set up start/stop/terminated callbacks - this->start = consumer_start; - this->stop = consumer_stop; - this->is_stopped = consumer_is_stopped; - } - - // Return this - return this; -} - -/** Start the consumer. -*/ - -static int consumer_start( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Check that we're not already running - if ( !mlt_properties_get_int( properties, "running" ) ) - { - // Allocate a thread - pthread_t *thread = calloc( 1, sizeof( pthread_t ) ); - - // Assign the thread to properties - mlt_properties_set_data( properties, "thread", thread, sizeof( pthread_t ), free, NULL ); - - // Set the running state - mlt_properties_set_int( properties, "running", 1 ); - mlt_properties_set_int( properties, "joined", 0 ); - - // Create the thread - pthread_create( thread, NULL, consumer_thread, this ); - } - return 0; -} - -/** Stop the consumer. -*/ - -static int consumer_stop( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Check that we're running - if ( !mlt_properties_get_int( properties, "joined" ) ) - { - // Get the thread - pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL ); - - // Stop the thread - mlt_properties_set_int( properties, "running", 0 ); - mlt_properties_set_int( properties, "joined", 1 ); - - // Wait for termination - pthread_join( *thread, NULL ); - } - - return 0; -} - -/** Determine if the consumer is stopped. -*/ - -static int consumer_is_stopped( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - return !mlt_properties_get_int( properties, "running" ); -} - -/** The main thread - the argument is simply the consumer. -*/ - -static void *consumer_thread( void *arg ) -{ - // Map the argument to the object - mlt_consumer this = arg; - - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Convenience functionality - int terminate_on_pause = mlt_properties_get_int( properties, "terminate_on_pause" ); - int terminated = 0; - - // Frame and size - mlt_frame frame = NULL; - - // Loop while running - while( !terminated && mlt_properties_get_int( properties, "running" ) ) - { - // Get the frame - frame = mlt_consumer_rt_frame( this ); - - // Check for termination - if ( terminate_on_pause && frame != NULL ) - terminated = mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ) == 0.0; - - // Check that we have a frame to work with - if ( frame != NULL ) - { - // Close the frame - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); - mlt_frame_close( frame ); - } - } - - // Indicate that the consumer is stopped - mlt_properties_set_int( properties, "running", 0 ); - mlt_consumer_stopped( this ); - - return NULL; -} - -/** Close the consumer. -*/ - -static void consumer_close( mlt_consumer this ) -{ - // Stop the consumer - mlt_consumer_stop( this ); - - // Close the parent - mlt_consumer_close( this ); - - // Free the memory - free( this ); -} diff --git a/src/modules/core/factory.c b/src/modules/core/factory.c deleted file mode 100644 index 755597f..0000000 --- a/src/modules/core/factory.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -extern mlt_consumer consumer_null_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_brightness_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_channelcopy_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_crop_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_data_feed_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_data_show_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_gamma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_greyscale_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_luma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_mirror_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_mono_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_obscure_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_region_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_rescale_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_resize_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_transition_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_watermark_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_colour_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_consumer_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_noise_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_ppm_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -#include "transition_composite.h" -extern mlt_transition transition_luma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_transition transition_mix_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -#include "transition_region.h" - -MLT_REPOSITORY -{ - MLT_REGISTER( consumer_type, "null", consumer_null_init ); - MLT_REGISTER( filter_type, "brightness", filter_brightness_init ); - MLT_REGISTER( filter_type, "channelcopy", filter_channelcopy_init ); - MLT_REGISTER( filter_type, "crop", filter_crop_init ); - MLT_REGISTER( filter_type, "data_feed", filter_data_feed_init ); - MLT_REGISTER( filter_type, "data_show", filter_data_show_init ); - MLT_REGISTER( filter_type, "gamma", filter_gamma_init ); - MLT_REGISTER( filter_type, "greyscale", filter_greyscale_init ); - MLT_REGISTER( filter_type, "grayscale", filter_greyscale_init ); - MLT_REGISTER( filter_type, "luma", filter_luma_init ); - MLT_REGISTER( filter_type, "mirror", filter_mirror_init ); - MLT_REGISTER( filter_type, "mono", filter_mono_init ); - MLT_REGISTER( filter_type, "obscure", filter_obscure_init ); - MLT_REGISTER( filter_type, "region", filter_region_init ); - MLT_REGISTER( filter_type, "rescale", filter_rescale_init ); - MLT_REGISTER( filter_type, "resize", filter_resize_init ); - MLT_REGISTER( filter_type, "transition", filter_transition_init ); - MLT_REGISTER( filter_type, "watermark", filter_watermark_init ); - MLT_REGISTER( producer_type, "color", producer_colour_init ); - MLT_REGISTER( producer_type, "colour", producer_colour_init ); - MLT_REGISTER( producer_type, "consumer", producer_consumer_init ); - MLT_REGISTER( producer_type, "noise", producer_noise_init ); - MLT_REGISTER( producer_type, "ppm", producer_ppm_init ); - MLT_REGISTER( transition_type, "composite", transition_composite_init ); - MLT_REGISTER( transition_type, "luma", transition_luma_init ); - MLT_REGISTER( transition_type, "mix", transition_mix_init ); - MLT_REGISTER( transition_type, "region", transition_region_init ); -} diff --git a/src/modules/core/filter_brightness.c b/src/modules/core/filter_brightness.c deleted file mode 100644 index 07dce1c..0000000 --- a/src/modules/core/filter_brightness.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * filter_brightness.c -- gamma filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - -#define CLAMP( x, min, max ) (x) < (min) ? (min) : (x) > (max) ? (max) : (x) - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the image - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - // Only process if we have no error and a valid colour space - if ( error == 0 && *format == mlt_image_yuv422 ) - { - // Get the brightness level - double level = mlt_properties_get_double( MLT_FRAME_PROPERTIES( this ), "brightness" ); - - // Only process if level is something other than 1 - if ( level != 1.0 ) - { - int i = *width * *height + 1; - uint8_t *p = *image; - int32_t m = level * ( 1 << 16 ); - int32_t n = 128 * ( ( 1 << 16 ) - m ); - - while ( --i ) - { - p[0] = CLAMP( (p[0] * m) >> 16, 16, 235 ); - p[1] = CLAMP( (p[1] * m + n) >> 16, 16, 240 ); - p += 2; - } - } - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Get the starting brightness level - double level = fabs( mlt_properties_get_double( MLT_FILTER_PROPERTIES( this ), "start" ) ); - - // If there is an end adjust gain to the range - if ( mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "end" ) != NULL ) - { - // Determine the time position of this frame in the transition duration - mlt_position in = mlt_filter_get_in( this ); - mlt_position out = mlt_filter_get_out( this ); - mlt_position time = mlt_frame_get_position( frame ); - double position = ( double )( time - in ) / ( double )( out - in + 1 ); - double end = fabs( mlt_properties_get_double( MLT_FILTER_PROPERTIES( this ), "end" ) ); - level += ( end - level ) * position; - } - - // Push the frame filter - mlt_properties_set_double( MLT_FRAME_PROPERTIES( frame ), "brightness", level ); - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_brightness_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "start", arg == NULL ? "1" : arg ); - } - return this; -} - diff --git a/src/modules/core/filter_channelcopy.c b/src/modules/core/filter_channelcopy.c deleted file mode 100644 index d4dd697..0000000 --- a/src/modules/core/filter_channelcopy.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * filter_channelcopy.c -- copy one audio channel to another - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#define __USE_ISOC99 1 -#include - -/** Get the audio. -*/ - -static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the properties of the a frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - int i, j; - int from = mlt_properties_get_int( properties, "channelcopy.from" ); - int to = mlt_properties_get_int( properties, "channelcopy.to" ); - - // Get the producer's audio - mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); - - // Duplicate channels as necessary - { - int size = *channels * *samples * 2; - int16_t *new_buffer = mlt_pool_alloc( size ); - - mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - - // Duplicate the existing channels - for ( i = 0; i < *samples; i++ ) - { - for ( j = 0; j < *channels; j++ ) - { - new_buffer[ ( i * *channels ) + j ] = (*buffer)[ ( i * *channels ) + ( j == to ? from : j ) ]; - } - } - *buffer = new_buffer; - } - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - mlt_properties frame_props = MLT_FRAME_PROPERTIES( frame ); - - // Propogate the parameters - mlt_properties_set_int( frame_props, "channelcopy.to", mlt_properties_get_int( properties, "to" ) ); - mlt_properties_set_int( frame_props, "channelcopy.from", mlt_properties_get_int( properties, "from" ) ); - - // Override the get_audio method - mlt_frame_push_audio( frame, filter_get_audio ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_channelcopy_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - if ( arg != NULL ) - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "to", atoi( arg ) ); - else - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "to", 1 ); - } - return this; -} diff --git a/src/modules/core/filter_crop.c b/src/modules/core/filter_crop.c deleted file mode 100644 index 0857c1d..0000000 --- a/src/modules/core/filter_crop.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * filter_crop.c -- cropping filter - * Copyright (C) 2009 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include -#include - -static void crop( uint8_t *src, uint8_t *dest, int bpp, int width, int height, int left, int right, int top, int bottom ) -{ - int stride = ( width - left - right ) * bpp + 1; - int y = height - top - bottom + 1; - uint8_t *s = &src[ ( ( top * width ) + left ) * bpp ]; - - while ( --y ) - { - int x = stride; - while ( --x ) - *dest ++ = *s ++; - s += ( right + left ) * bpp; - } -} - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - int error = 0; - - // Get the properties from the frame - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Correct Width/height if necessary - if ( *width == 0 || *height == 0 ) - { - *width = mlt_properties_get_int( properties, "normalised_width" ); - *height = mlt_properties_get_int( properties, "normalised_height" ); - } - - // Now get the image - error = mlt_frame_get_image( this, image, format, width, height, writable ); - - int left = mlt_properties_get_int( properties, "crop.left" ); - int right = mlt_properties_get_int( properties, "crop.right" ); - int top = mlt_properties_get_int( properties, "crop.top" ); - int bottom = mlt_properties_get_int( properties, "crop.bottom" ); - int owidth = *width - left - right; - int oheight = *height - top - bottom; - - // We only know how to process yuv422 at the moment - if ( ( owidth != *width || oheight != *height ) && - error == 0 && *format == mlt_image_yuv422 && *image != NULL && owidth > 0 && oheight > 0 ) - { - // Provides a manual override for misreported field order - if ( mlt_properties_get( properties, "meta.top_field_first" ) ) - { - mlt_properties_set_int( properties, "top_field_first", mlt_properties_get_int( properties, "meta.top_field_first" ) ); - mlt_properties_set_int( properties, "meta.top_field_first", 0 ); - } - - if ( top % 2 ) - mlt_properties_set_int( properties, "top_field_first", !mlt_properties_get_int( properties, "top_field_first" ) ); - - left -= left % 2; - owidth = *width - left - right; - - // Create the output image - uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 ); - if ( output ) - { - // Call the generic resize - crop( *image, output, 2, *width, *height, left, right, top, bottom ); - - // Now update the frame - *image = output; - mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", owidth ); - mlt_properties_set_int( properties, "height", oheight ); - } - - // We should resize the alpha too - uint8_t *alpha = mlt_frame_get_alpha_mask( this ); - if ( alpha != NULL ) - { - uint8_t *newalpha = mlt_pool_alloc( owidth * oheight ); - if ( newalpha ) - { - crop( alpha, newalpha, 1, *width, *height, left, right, top, bottom ); - mlt_properties_set_data( properties, "alpha", newalpha, owidth * oheight, ( mlt_destructor )mlt_pool_release, NULL ); - this->get_alpha_mask = NULL; - } - } - *width = owidth; - *height = oheight; - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - if ( mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "active" ) ) - { - // Push the get_image method on to the stack - mlt_frame_push_get_image( frame, filter_get_image ); - } - else - { - mlt_properties filter_props = MLT_FILTER_PROPERTIES( this ); - mlt_properties frame_props = MLT_FRAME_PROPERTIES( frame ); - int left = mlt_properties_get_int( filter_props, "left" ); - int right = mlt_properties_get_int( filter_props, "right" ); - int top = mlt_properties_get_int( filter_props, "top" ); - int bottom = mlt_properties_get_int( filter_props, "bottom" ); - int width = mlt_properties_get_int( frame_props, "real_width" ); - int height = mlt_properties_get_int( frame_props, "real_height" ); - - mlt_properties_set_int( frame_props, "crop.left", left ); - mlt_properties_set_int( frame_props, "crop.right", right ); - mlt_properties_set_int( frame_props, "crop.top", top ); - mlt_properties_set_int( frame_props, "crop.bottom", bottom ); - mlt_properties_set_int( frame_props, "real_width", width - left - right ); - mlt_properties_set_int( frame_props, "real_height", height - top - bottom ); - } - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_crop_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 ); - if ( mlt_filter_init( this, this ) == 0 ) - { - this->process = filter_process; - if ( arg ) - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "active", atoi( arg ) ); - } - return this; -} diff --git a/src/modules/core/filter_data_feed.c b/src/modules/core/filter_data_feed.c deleted file mode 100644 index e3cf81d..0000000 --- a/src/modules/core/filter_data_feed.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * filter_data_feed.c -- data feed filter - * Copyright (C) 2004-2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -/** This filter should be used in conjuction with the data_show filter. - The concept of the data_feed is that it can be used to pass titles - or images to render on the frame, but doesn't actually do it - itself. data_feed imposes few rules on what's passed on and the - validity is confirmed in data_show before use. -*/ - -/** Data queue destructor. -*/ - -static void destroy_data_queue( void *arg ) -{ - if ( arg != NULL ) - { - // Assign the correct type - mlt_deque queue = arg; - - // Iterate through each item and destroy them - while ( mlt_deque_peek_front( queue ) != NULL ) - mlt_properties_close( mlt_deque_pop_back( queue ) ); - - // Close the deque - mlt_deque_close( queue ); - } -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Get the filter properties - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( this ); - - // Get the frame properties - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Get the data queue - mlt_deque data_queue = mlt_properties_get_data( frame_properties, "data_queue", NULL ); - - // Get the type of the data feed - char *type = mlt_properties_get( filter_properties, "type" ); - - // Get the in and out points of this filter - int in = mlt_filter_get_in( this ); - int out = mlt_filter_get_out( this ); - - // Create the data queue if it doesn't exist - if ( data_queue == NULL ) - { - // Create the queue - data_queue = mlt_deque_init( ); - - // Assign it to the frame with the destructor - mlt_properties_set_data( frame_properties, "data_queue", data_queue, 0, destroy_data_queue, NULL ); - } - - // Now create the data feed - if ( data_queue != NULL && type != NULL && !strcmp( type, "attr_check" ) ) - { - int i = 0; - int count = mlt_properties_count( frame_properties ); - - for ( i = 0; i < count; i ++ ) - { - char *name = mlt_properties_get_name( frame_properties, i ); - - // Only deal with meta.attr.name values here - these should have a value of 1 to be considered - // Additional properties of the form are meta.attr.name.property are passed down on the feed - if ( !strncmp( name, "meta.attr.", 10 ) && strchr( name + 10, '.' ) == NULL && mlt_properties_get_int( frame_properties, name ) == 1 ) - { - // Temp var to hold name + '.' for pass method - char temp[ 132 ]; - - // Create a new data feed - mlt_properties feed = mlt_properties_new( ); - - // Assign it the base properties - mlt_properties_set( feed, "id", mlt_properties_get( filter_properties, "_unique_id" ) ); - mlt_properties_set( feed, "type", strrchr( name, '.' ) + 1 ); - mlt_properties_set_position( feed, "position", mlt_frame_get_position( frame ) ); - - // Assign in/out of service we're connected to - mlt_properties_set_position( feed, "in", mlt_properties_get_position( frame_properties, "in" ) ); - mlt_properties_set_position( feed, "out", mlt_properties_get_position( frame_properties, "out" ) ); - - // Pass all meta properties - sprintf( temp, "%s.", name ); - mlt_properties_pass( feed, frame_properties, temp ); - - // Push it on to the queue - mlt_deque_push_back( data_queue, feed ); - - // Make sure this attribute only gets processed once - mlt_properties_set_int( frame_properties, name, 0 ); - } - } - } - else if ( data_queue != NULL ) - { - // Create a new data feed - mlt_properties feed = mlt_properties_new( ); - - // Assign it the base properties - mlt_properties_set( feed, "id", mlt_properties_get( filter_properties, "_unique_id" ) ); - mlt_properties_set( feed, "type", type ); - mlt_properties_set_position( feed, "position", mlt_frame_get_position( frame ) ); - - // Assign in/out of service we're connected to - mlt_properties_set_position( feed, "in", mlt_properties_get_position( frame_properties, "in" ) ); - mlt_properties_set_position( feed, "out", mlt_properties_get_position( frame_properties, "out" ) ); - - // Correct in/out to the filter if specified - if ( in != 0 ) - mlt_properties_set_position( feed, "in", in ); - if ( out != 0 ) - mlt_properties_set_position( feed, "out", out ); - - // Pass the properties which start with a "feed." prefix - // Note that 'feed.text' in the filter properties becomes 'text' on the feed - mlt_properties_pass( feed, filter_properties, "feed." ); - - // Push it on to the queue - mlt_deque_push_back( data_queue, feed ); - } - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_data_feed_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create the filter - mlt_filter this = mlt_filter_new( ); - - // Initialise it - if ( this != NULL ) - { - // Get the properties - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Assign the argument (default to titles) - mlt_properties_set( properties, "type", arg == NULL ? "titles" : arg ); - - // Specify the processing method - this->process = filter_process; - } - - return this; -} - diff --git a/src/modules/core/filter_data_show.c b/src/modules/core/filter_data_show.c deleted file mode 100644 index d62bd58..0000000 --- a/src/modules/core/filter_data_show.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * filter_data_show.c -- data feed filter - * Copyright (C) 2004-2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -/** Handle the profile. -*/ - -static mlt_filter obtain_filter( mlt_filter filter, char *type ) -{ - // Result to return - mlt_filter result = NULL; - - // Miscelaneous variable - int i = 0; - int type_len = strlen( type ); - - // Get the properties of the data show filter - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - - // Get the profile properties - mlt_properties profile_properties = mlt_properties_get_data( filter_properties, "profile_properties", NULL ); - - // Obtain the profile_properties if we haven't already - if ( profile_properties == NULL ) - { - char temp[ 512 ]; - - // Get the profile requested - char *profile = mlt_properties_get( filter_properties, "resource" ); - - // If none is specified, pick up the default for this normalisation - if ( profile == NULL ) - sprintf( temp, "%s/feeds/%s/data_fx.properties", mlt_environment( "MLT_DATA" ), mlt_environment( "MLT_NORMALISATION" ) ); - else if ( strchr( profile, '%' ) ) - sprintf( temp, "%s/feeds/%s/%s", mlt_environment( "MLT_DATA" ), mlt_environment( "MLT_NORMALISATION" ), strchr( profile, '%' ) + 1 ); - else - strcpy( temp, profile ); - - // Load the specified profile or use the default - profile_properties = mlt_properties_load( temp ); - - // Store for later retrieval - mlt_properties_set_data( filter_properties, "profile_properties", profile_properties, 0, ( mlt_destructor )mlt_properties_close, NULL ); - } - - if ( profile_properties != NULL ) - { - for ( i = 0; i < mlt_properties_count( profile_properties ); i ++ ) - { - char *name = mlt_properties_get_name( profile_properties, i ); - char *value = mlt_properties_get_value( profile_properties, i ); - - if ( result == NULL && !strcmp( name, type ) && result == NULL ) - result = mlt_factory_filter( mlt_service_profile( MLT_FILTER_SERVICE( filter ) ), value, NULL ); - else if ( result != NULL && !strncmp( name, type, type_len ) && name[ type_len ] == '.' ) - mlt_properties_set( MLT_FILTER_PROPERTIES( result ), name + type_len + 1, value ); - else if ( result != NULL ) - break; - } - } - - return result; -} - -/** Retrieve medatata value -*/ - -char* metadata_value(mlt_properties properties, char* name) -{ - if (name == NULL) return NULL; - char *meta = malloc( strlen(name) + 18 ); - sprintf( meta, "meta.attr.%s.markup", name); - char *result = mlt_properties_get( properties, meta); - free(meta); - return result; -} - -/** Convert frames to Timecode -*/ - -char* frame_to_timecode( int frames , int fps) -{ - if (fps == 0) return strdup("-"); - char *res = malloc(12); - int seconds = frames / (int) fps; - frames = frames % ((int) fps); - int minutes = seconds / 60; - seconds = seconds % 60; - int hours = minutes / 60; - minutes = minutes % 60; - sprintf(res, "%.2d:%.2d:%.2d:%.2d", hours, minutes, seconds, frames); - return res; -} - -/** Process the frame for the requested type -*/ - -static int process_feed( mlt_properties feed, mlt_filter filter, mlt_frame frame ) -{ - // Error return - int error = 1; - - // Get the properties of the data show filter - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - - // Get the type requested by the feeding filter - char *type = mlt_properties_get( feed, "type" ); - - // Fetch the filter associated to this type - mlt_filter requested = mlt_properties_get_data( filter_properties, type, NULL ); - - // If it doesn't exist, then create it now - if ( requested == NULL ) - { - // Source filter from profile - requested = obtain_filter( filter, type ); - - // Store it on the properties for subsequent retrieval/destruction - mlt_properties_set_data( filter_properties, type, requested, 0, ( mlt_destructor )mlt_filter_close, NULL ); - } - - // If we have one, then process it now... - if ( requested != NULL ) - { - int i = 0; - mlt_properties properties = MLT_FILTER_PROPERTIES( requested ); - static const char *prefix = "properties."; - int len = strlen( prefix ); - - // Determine if this is an absolute or relative feed - int absolute = mlt_properties_get_int( feed, "absolute" ); - - // Make do with what we have - int length = !absolute ? - mlt_properties_get_int( feed, "out" ) - mlt_properties_get_int( feed, "in" ) + 1 : - mlt_properties_get_int( feed, "out" ) + 1; - - // Repeat period - int period = mlt_properties_get_int( properties, "period" ); - period = period == 0 ? 1 : period; - - // Pass properties from feed into requested - for ( i = 0; i < mlt_properties_count( properties ); i ++ ) - { - char *name = mlt_properties_get_name( properties, i ); - char *key = mlt_properties_get_value( properties, i ); - if ( !strncmp( name, prefix, len ) ) - { - if ( !strncmp( name + len, "length[", 7 ) ) - { - mlt_properties_set_position( properties, key, ( length - period ) / period ); - } - else - { - char *value = mlt_properties_get( feed, name + len ); - if ( value != NULL ) - { - // check for metadata keywords in metadata markup if user requested so - if ( mlt_properties_get_int( filter_properties, "dynamic" ) == 1 && !strcmp( name + strlen( name ) - 6, "markup") ) - { - // Find keywords which should be surrounded by '#', like: #title# - char* keywords = strtok( value, "#" ); - char result[512] = ""; // XXX: how much is enough? - int ct = 0; - int fromStart = ( value[0] == '#' ) ? 1 : 0; - - while ( keywords != NULL ) - { - if ( ct % 2 == fromStart ) - { - // backslash in front of # suppresses substitution - if ( keywords[ strlen( keywords ) -1 ] == '\\' ) - { - // keep characters except backslash - strncat( result, keywords, strlen( keywords ) -1 ); - strcat( result, "#" ); - ct++; - } - else - { - strcat( result, keywords ); - } - } - else if ( !strcmp( keywords, "timecode" ) ) - { - // special case: replace #timecode# with current frame timecode - int pos = mlt_properties_get_int( feed, "position" ); - char *tc = frame_to_timecode( pos, mlt_profile_fps( mlt_service_profile( MLT_FILTER_SERVICE( filter ) ) ) ); - strcat( result, tc ); - free( tc ); - } - else - { - // replace keyword with metadata value - char *metavalue = metadata_value( MLT_FRAME_PROPERTIES( frame ), keywords ); - strcat( result, metavalue ? metavalue : "-" ); - } - keywords = strtok( NULL, "#" ); - ct++; - } - mlt_properties_set( properties, key, (char*) result ); - } - else mlt_properties_set( properties, key, value ); - } - } - } - } - - // Set the original position on the frame - if ( absolute == 0 ) - mlt_frame_set_position( frame, mlt_properties_get_int( feed, "position" ) - mlt_properties_get_int( feed, "in" ) ); - else - mlt_frame_set_position( frame, mlt_properties_get_int( feed, "position" ) ); - - // Process the filter - mlt_filter_process( requested, frame ); - - // Should be ok... - error = 0; - } - - return error; -} - -void process_queue( mlt_deque data_queue, mlt_frame frame, mlt_filter filter ) -{ - if ( data_queue != NULL ) - { - // Create a new queue for those that we can't handle - mlt_deque temp_queue = mlt_deque_init( ); - - // Iterate through each entry on the queue - while ( mlt_deque_peek_front( data_queue ) != NULL ) - { - // Get the data feed - mlt_properties feed = mlt_deque_pop_front( data_queue ); - - if ( mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "debug" ) != NULL ) - mlt_properties_debug( feed, mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "debug" ), stderr ); - - // Process the data feed... - if ( process_feed( feed, filter, frame ) == 0 ) - mlt_properties_close( feed ); - else - mlt_deque_push_back( temp_queue, feed ); - } - - // Now put the unprocessed feeds back on the stack - while ( mlt_deque_peek_front( temp_queue ) ) - { - // Get the data feed - mlt_properties feed = mlt_deque_pop_front( temp_queue ); - - // Put it back on the data queue - mlt_deque_push_back( data_queue, feed ); - } - - // Close the temporary queue - mlt_deque_close( temp_queue ); - } -} - -/** Get the image. -*/ - -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Pop the service - mlt_filter filter = mlt_frame_pop_service( frame ); - - // Get the frame properties - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Track specific - process_queue( mlt_properties_get_data( frame_properties, "data_queue", NULL ), frame, filter ); - - // Global - process_queue( mlt_properties_get_data( frame_properties, "global_queue", NULL ), frame, filter ); - - // Need to get the image - return mlt_frame_get_image( frame, image, format, width, height, 1 ); -} - - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push the filter - mlt_frame_push_service( frame, this ); - - // Register the get image method - mlt_frame_push_get_image( frame, filter_get_image ); - - // Return the frame - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_data_show_init( mlt_profile profile, mlt_service_type type, const char *id, void *arg ) -{ - // Create the filter - mlt_filter this = mlt_filter_new( ); - - // Initialise it - if ( this != NULL ) - { - // Get the properties - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Assign the argument (default to titles) - mlt_properties_set( properties, "resource", arg == NULL ? NULL : arg ); - - // Specify the processing method - this->process = filter_process; - } - - return this; -} - diff --git a/src/modules/core/filter_gamma.c b/src/modules/core/filter_gamma.c deleted file mode 100644 index e4fe15b..0000000 --- a/src/modules/core/filter_gamma.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * filter_gamma.c -- gamma filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - if ( error == 0 && *format == mlt_image_yuv422 ) - { - // Get the gamma value - double gamma = mlt_properties_get_double( MLT_FRAME_PROPERTIES( this ), "gamma" ); - - if ( gamma != 1.0 ) - { - uint8_t *p = *image; - uint8_t *q = *image + *width * *height * 2; - - // Calculate the look up table - double exp = 1 / gamma; - uint8_t lookup[ 256 ]; - int i; - - for( i = 0; i < 256; i ++ ) - lookup[ i ] = ( uint8_t )( pow( ( double )i / 255.0, exp ) * 255 ); - - while ( p != q ) - { - *p = lookup[ *p ]; - p += 2; - } - } - } - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - double gamma = mlt_properties_get_double( MLT_FILTER_PROPERTIES( this ), "gamma" ); - gamma = gamma <= 0 ? 1 : gamma; - mlt_properties_set_double( MLT_FRAME_PROPERTIES( frame ), "gamma", gamma ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_gamma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "gamma", arg == NULL ? "1" : arg ); - } - return this; -} diff --git a/src/modules/core/filter_greyscale.c b/src/modules/core/filter_greyscale.c deleted file mode 100644 index fd618c0..0000000 --- a/src/modules/core/filter_greyscale.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * filter_greyscale.c -- greyscale filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - if ( error == 0 && *format == mlt_image_yuv422 ) - { - uint8_t *p = *image; - uint8_t *q = *image + *width * *height * 2; - while ( p ++ != q ) - *p ++ = 128; - } - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_greyscale_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - this->process = filter_process; - return this; -} - diff --git a/src/modules/core/filter_luma.c b/src/modules/core/filter_luma.c deleted file mode 100644 index f05d6c4..0000000 --- a/src/modules/core/filter_luma.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * filter_luma.c -- luma filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - int error = 0; - mlt_filter filter = mlt_frame_pop_service( this ); - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - mlt_transition luma = mlt_properties_get_data( properties, "luma", NULL ); - mlt_frame b_frame = mlt_properties_get_data( properties, "frame", NULL ); - mlt_properties b_frame_props = b_frame ? MLT_FRAME_PROPERTIES( b_frame ) : NULL; - int out = mlt_properties_get_int( properties, "period" ); - - if ( out == 0 ) - out = 24; - - if ( b_frame == NULL || mlt_properties_get_int( b_frame_props, "width" ) != *width || mlt_properties_get_int( b_frame_props, "height" ) != *height ) - { - b_frame = mlt_frame_init( MLT_FILTER_SERVICE( filter ) ); - mlt_properties_set_data( properties, "frame", b_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); - } - - if ( luma == NULL ) - { - char *resource = mlt_properties_get( properties, "resource" ); - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) ); - luma = mlt_factory_transition( profile, "luma", resource ); - if ( luma != NULL ) - { - mlt_properties luma_properties = MLT_TRANSITION_PROPERTIES( luma ); - mlt_properties_set_int( luma_properties, "in", 0 ); - mlt_properties_set_int( luma_properties, "out", out ); - mlt_properties_set_int( luma_properties, "reverse", 1 ); - mlt_properties_set_data( properties, "luma", luma, 0, ( mlt_destructor )mlt_transition_close, NULL ); - } - - // Prime the filter with the first image to prevent a transition from the white - // of a test card. - error = mlt_frame_get_image( this, image, format, width, height, 1 ); - if ( error == 0 ) - { - mlt_properties a_props = MLT_FRAME_PROPERTIES( this ); - int size = 0; - uint8_t *src = mlt_properties_get_data( a_props, "image", &size ); - uint8_t *dst = mlt_pool_alloc( size ); - - if ( dst != NULL ) - { - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - memcpy( dst, src, size ); - mlt_properties_set_data( b_props, "image", dst, size, mlt_pool_release, NULL ); - mlt_properties_set_int( b_props, "width", *width ); - mlt_properties_set_int( b_props, "height", *height ); - mlt_properties_set_int( b_props, "format", *format ); - } - } - } - - if ( luma != NULL && - ( mlt_properties_get( properties, "blur" ) != NULL || - (int)mlt_frame_get_position( this ) % ( out + 1 ) != out ) ) - { - mlt_properties luma_properties = MLT_TRANSITION_PROPERTIES( luma ); - mlt_properties_pass( luma_properties, properties, "luma." ); - mlt_transition_process( luma, this, b_frame ); - } - - error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - if ( error == 0 ) - { - mlt_properties a_props = MLT_FRAME_PROPERTIES( this ); - int size = 0; - uint8_t *src = mlt_properties_get_data( a_props, "image", &size ); - uint8_t *dst = mlt_pool_alloc( size ); - - if ( dst != NULL ) - { - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - memcpy( dst, src, size ); - mlt_properties_set_data( b_props, "image", dst, size, mlt_pool_release, NULL ); - mlt_properties_set_int( b_props, "width", *width ); - mlt_properties_set_int( b_props, "height", *height ); - mlt_properties_set_int( b_props, "format", *format ); - } - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push the filter on to the stack - mlt_frame_push_service( frame, this ); - - // Push the get_image on to the stack - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_luma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - this->process = filter_process; - if ( arg != NULL ) - mlt_properties_set( properties, "resource", arg ); - } - return this; -} diff --git a/src/modules/core/filter_mirror.c b/src/modules/core/filter_mirror.c deleted file mode 100644 index 3dd6dbf..0000000 --- a/src/modules/core/filter_mirror.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * filter_mirror.c -- mirror filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Pop the mirror filter from the stack - mlt_filter this = mlt_frame_pop_service( frame ); - - // Get the mirror type - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Get the properties - char *mirror = mlt_properties_get( properties, "mirror" ); - - // Determine if reverse is required - int reverse = mlt_properties_get_int( properties, "reverse" ); - - // Get the image - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - // Get the alpha - uint8_t *alpha = mlt_frame_get_alpha_mask( frame ); - - // If we have an image of the right colour space - if ( error == 0 && *format == mlt_image_yuv422 ) - { - // We'll KISS here - int hh = *height / 2; - - if ( !strcmp( mirror, "horizontal" ) ) - { - uint8_t *p = NULL; - uint8_t *q = NULL; - uint8_t *a = NULL; - uint8_t *b = NULL; - int i; - int uneven_w = ( *width % 2 ) * 2; - for ( i = 0; i < *height; i ++ ) - { - p = ( uint8_t * )*image + i * *width * 2; - q = p + *width * 2; - a = alpha + i * *width; - b = a + *width - 1; - if ( !reverse ) - { - while ( p < q ) - { - *p ++ = *( q - 2 ); - *p ++ = *( q - 3 - uneven_w ); - *p ++ = *( q - 4 ); - *p ++ = *( q - 1 - uneven_w ); - q -= 4; - *a ++ = *b --; - *a ++ = *b --; - } - } - else - { - while ( p < q ) - { - *( q - 2 ) = *p ++; - *( q - 3 - uneven_w ) = *p ++; - *( q - 4 ) = *p ++; - *( q - 1 - uneven_w ) = *p ++; - q -= 4; - *b -- = *a ++; - *b -- = *a ++; - } - } - } - } - else if ( !strcmp( mirror, "vertical" ) ) - { - uint16_t *end = ( uint16_t *)*image + *width * *height; - uint16_t *p = NULL; - uint16_t *q = NULL; - uint8_t *a = NULL; - uint8_t *b = NULL; - int i; - int j; - for ( i = 0; i < hh; i ++ ) - { - p = ( uint16_t * )*image + i * *width; - q = end - ( i + 1 ) * *width; - j = *width; - a = alpha + i * *width; - b = alpha + ( *height - i - 1 ) * *width; - if ( !reverse ) - { - while ( j -- ) - { - *p ++ = *q ++; - *a ++ = *b ++; - } - } - else - { - while ( j -- ) - { - *q ++ = *p ++; - *b ++ = *a ++; - } - } - } - } - else if ( !strcmp( mirror, "diagonal" ) ) - { - uint8_t *end = ( uint8_t *)*image + *width * *height * 2; - uint8_t *p = NULL; - uint8_t *q = NULL; - uint8_t *a = NULL; - uint8_t *b = NULL; - int i; - int j; - int uneven_w = ( *width % 2 ) * 2; - for ( i = 0; i < *height; i ++ ) - { - p = ( uint8_t * )*image + i * *width * 2; - q = end - i * *width * 2; - j = ( ( *width * ( *height - i ) ) / *height ) / 2; - a = alpha + i * *width; - b = alpha + ( *height - i - 1 ) * *width; - if ( !reverse ) - { - while ( j -- ) - { - *p ++ = *( q - 2 ); - *p ++ = *( q - 3 - uneven_w ); - *p ++ = *( q - 4 ); - *p ++ = *( q - 1 - uneven_w ); - q -= 4; - *a ++ = *b --; - *a ++ = *b --; - } - } - else - { - while ( j -- ) - { - *( q - 2 ) = *p ++; - *( q - 3 - uneven_w ) = *p ++; - *( q - 4 ) = *p ++; - *( q - 1 - uneven_w ) = *p ++; - q -= 4; - *b -- = *a ++; - *b -- = *a ++; - } - } - } - } - else if ( !strcmp( mirror, "xdiagonal" ) ) - { - uint8_t *end = ( uint8_t *)*image + *width * *height * 2; - uint8_t *p = NULL; - uint8_t *q = NULL; - int i; - int j; - uint8_t *a = NULL; - uint8_t *b = NULL; - int uneven_w = ( *width % 2 ) * 2; - for ( i = 0; i < *height; i ++ ) - { - p = ( uint8_t * )*image + ( i + 1 ) * *width * 2; - q = end - ( i + 1 ) * *width * 2; - j = ( ( *width * ( *height - i ) ) / *height ) / 2; - a = alpha + ( i + 1 ) * *width - 1; - b = alpha + ( *height - i - 1 ) * *width; - if ( !reverse ) - { - while ( j -- ) - { - *q ++ = *( p - 2 ); - *q ++ = *( p - 3 - uneven_w ); - *q ++ = *( p - 4 ); - *q ++ = *( p - 1 - uneven_w ); - p -= 4; - *b ++ = *a --; - *b ++ = *a --; - } - } - else - { - while ( j -- ) - { - *( p - 2 ) = *q ++; - *( p - 3 - uneven_w ) = *q ++; - *( p - 4 ) = *q ++; - *( p - 1 - uneven_w ) = *q ++; - p -= 4; - *a -- = *b ++; - *a -- = *b ++; - } - } - } - } - else if ( !strcmp( mirror, "flip" ) ) - { - uint8_t t[ 4 ]; - uint8_t *p = NULL; - uint8_t *q = NULL; - int i; - uint8_t *a = NULL; - uint8_t *b = NULL; - uint8_t c; - int uneven_w = ( *width % 2 ) * 2; - for ( i = 0; i < *height; i ++ ) - { - p = ( uint8_t * )*image + i * *width * 2; - q = p + *width * 2; - a = alpha + i * *width; - b = a + *width - 1; - while ( p < q ) - { - t[ 0 ] = p[ 0 ]; - t[ 1 ] = p[ 1 + uneven_w ]; - t[ 2 ] = p[ 2 ]; - t[ 3 ] = p[ 3 + uneven_w ]; - *p ++ = *( q - 2 ); - *p ++ = *( q - 3 - uneven_w ); - *p ++ = *( q - 4 ); - *p ++ = *( q - 1 - uneven_w ); - *( -- q ) = t[ 3 ]; - *( -- q ) = t[ 0 ]; - *( -- q ) = t[ 1 ]; - *( -- q ) = t[ 2 ]; - c = *a; - *a ++ = *b; - *b -- = c; - c = *a; - *a ++ = *b; - *b -- = c; - } - } - } - else if ( !strcmp( mirror, "flop" ) ) - { - uint16_t *end = ( uint16_t *)*image + *width * *height; - uint16_t *p = NULL; - uint16_t *q = NULL; - uint16_t t; - uint8_t *a = NULL; - uint8_t *b = NULL; - uint8_t c; - int i; - int j; - for ( i = 0; i < hh; i ++ ) - { - p = ( uint16_t * )*image + i * *width; - q = end - ( i + 1 ) * *width; - a = alpha + i * *width; - b = alpha + ( *height - i - 1 ) * *width; - j = *width; - while ( j -- ) - { - t = *p; - *p ++ = *q; - *q ++ = t; - c = *a; - *a ++ = *b; - *b ++ = c; - } - } - } - } - - // Return the error - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push the service on to the stack - mlt_frame_push_service( frame, this ); - - // Push the filter method on to the stack - mlt_frame_push_service( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_mirror_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Construct a new filter - mlt_filter this = mlt_filter_new( ); - - // If we have a filter, initialise it - if ( this != NULL ) - { - // Get the properties - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Set the default mirror type - mlt_properties_set_or_default( properties, "mirror", arg, "horizontal" ); - - // Assign the process method - this->process = filter_process; - } - - // Return the filter - return this; -} - diff --git a/src/modules/core/filter_mono.c b/src/modules/core/filter_mono.c deleted file mode 100644 index 882d6f3..0000000 --- a/src/modules/core/filter_mono.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * filter_mono.c -- mix all channels to a mono signal across n channels - * Copyright (C) 2003-2006 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include - -/** Get the audio. -*/ - -static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the properties of the a frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - int channels_out = mlt_properties_get_int( properties, "mono.channels" ); - int i, j, size; - int16_t *new_buffer; - - // Get the producer's audio - mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); - - size = *samples * channels_out * sizeof( int16_t ); - new_buffer = mlt_pool_alloc( size ); - mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - - // Mix - for ( i = 0; i < *samples; i++ ) - { - int16_t mixdown = 0; - for ( j = 0; j < *channels; j++ ) - mixdown += (*buffer)[ ( i * *channels ) + j ] / *channels; - for ( j = 0; j < channels_out; j++ ) - new_buffer[ ( i * channels_out ) + j ] = mixdown; - } - - // Apply results - *buffer = new_buffer; - *channels = channels_out; - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - mlt_properties frame_props = MLT_FRAME_PROPERTIES( frame ); - - // Propogate the parameters - mlt_properties_set_int( frame_props, "mono.channels", mlt_properties_get_int( properties, "channels" ) ); - - // Override the get_audio method - mlt_frame_push_audio( frame, filter_get_audio ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_mono_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - if ( arg != NULL ) - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "channels", atoi( arg ) ); - else - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "channels", 2 ); - } - return this; -} diff --git a/src/modules/core/filter_obscure.c b/src/modules/core/filter_obscure.c deleted file mode 100644 index 7256f6c..0000000 --- a/src/modules/core/filter_obscure.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * filter_obscure.c -- obscure filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include - -/** Geometry struct. -*/ - -struct geometry_s -{ - int nw; - int nh; - float x; - float y; - float w; - float h; - int mask_w; - int mask_h; -}; - -/** Parse a value from a geometry string. -*/ - -static inline float parse_value( char **ptr, int normalisation, char delim, float defaults ) -{ - float value = defaults; - - if ( *ptr != NULL && **ptr != '\0' ) - { - char *end = NULL; - value = strtod( *ptr, &end ); - if ( end != NULL ) - { - if ( *end == '%' ) - value = ( value / 100.0 ) * normalisation; - while ( *end == delim || *end == '%' ) - end ++; - } - *ptr = end; - } - - return value; -} - -/** Parse a geometry property string. -*/ - -static void geometry_parse( struct geometry_s *geometry, struct geometry_s *defaults, char *property, int nw, int nh ) -{ - // Assign normalised width and height - geometry->nw = nw; - geometry->nh = nh; - - // Assign from defaults if available - if ( defaults != NULL ) - { - geometry->x = defaults->x; - geometry->y = defaults->y; - geometry->w = defaults->w; - geometry->h = defaults->h; - geometry->mask_w = defaults->mask_w; - geometry->mask_h = defaults->mask_h; - } - else - { - geometry->x = 0; - geometry->y = 0; - geometry->w = nw; - geometry->h = nh; - geometry->mask_w = 20; - geometry->mask_h = 20; - } - - // Parse the geomtry string - if ( property != NULL ) - { - char *ptr = property; - geometry->x = parse_value( &ptr, nw, ',', geometry->x ); - geometry->y = parse_value( &ptr, nh, ':', geometry->y ); - geometry->w = parse_value( &ptr, nw, 'x', geometry->w ); - geometry->h = parse_value( &ptr, nh, ':', geometry->h ); - geometry->mask_w = parse_value( &ptr, nw, 'x', geometry->mask_w ); - geometry->mask_h = parse_value( &ptr, nh, ' ', geometry->mask_h ); - } -} - -/** A Timism but not as clean ;-). -*/ - -static float lerp( float value, float lower, float upper ) -{ - if ( value < lower ) - return lower; - else if ( value > upper ) - return upper; - return value; -} - -/** Calculate real geometry. -*/ - -static void geometry_calculate( struct geometry_s *output, struct geometry_s *in, struct geometry_s *out, float position, int ow, int oh ) -{ - // Calculate this frames geometry - output->x = lerp( ( in->x + ( out->x - in->x ) * position ) / ( float )out->nw * ow, 0, ow ); - output->y = lerp( ( in->y + ( out->y - in->y ) * position ) / ( float )out->nh * oh, 0, oh ); - output->w = lerp( ( in->w + ( out->w - in->w ) * position ) / ( float )out->nw * ow, 0, ow - output->x ); - output->h = lerp( ( in->h + ( out->h - in->h ) * position ) / ( float )out->nh * oh, 0, oh - output->y ); - output->mask_w = in->mask_w + ( out->mask_w - in->mask_w ) * position; - output->mask_h = in->mask_h + ( out->mask_h - in->mask_h ) * position; -} - -/** Calculate the position for this frame. -*/ - -static float position_calculate( mlt_filter this, mlt_frame frame ) -{ - // Get the in and out position - mlt_position in = mlt_filter_get_in( this ); - mlt_position out = mlt_filter_get_out( this ); - - // Get the position of the frame - mlt_position position = mlt_frame_get_position( frame ); - - // Now do the calcs - return ( float )( position - in ) / ( float )( out - in + 1 ); -} - -/** The averaging function... -*/ - -static inline void obscure_average( uint8_t *start, int width, int height, int stride ) -{ - register int y; - register int x; - register int Y = ( *start + *( start + 2 ) ) / 2; - register int U = *( start + 1 ); - register int V = *( start + 3 ); - register uint8_t *p; - register int components = width >> 1; - - y = height; - while( y -- ) - { - p = start; - x = components; - while( x -- ) - { - Y = ( Y + *p ++ ) >> 1; - U = ( U + *p ++ ) >> 1; - Y = ( Y + *p ++ ) >> 1; - V = ( V + *p ++ ) >> 1; - } - start += stride; - } - - start -= height * stride; - y = height; - while( y -- ) - { - p = start; - x = components; - while( x -- ) - { - *p ++ = Y; - *p ++ = U; - *p ++ = Y; - *p ++ = V; - } - start += stride; - } -} - - -/** The obscurer rendering function... -*/ - -static void obscure_render( uint8_t *image, int width, int height, struct geometry_s result ) -{ - int area_x = result.x; - int area_y = result.y; - int area_w = result.w; - int area_h = result.h; - - int mw = result.mask_w; - int mh = result.mask_h; - int w; - int h; - int aw; - int ah; - - uint8_t *p = image + area_y * width * 2 + area_x * 2; - - for ( w = 0; w < area_w; w += mw ) - { - for ( h = 0; h < area_h; h += mh ) - { - aw = w + mw > area_w ? mw - ( w + mw - area_w ) : mw; - ah = h + mh > area_h ? mh - ( h + mh - area_h ) : mh; - if ( aw > 1 && ah > 1 ) - obscure_average( p + h * ( width << 1 ) + ( w << 1 ), aw, ah, width << 1 ); - } - } -} - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the frame properties - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Pop the top of stack now - mlt_filter this = mlt_frame_pop_service( frame ); - - // Get the image from the frame - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - // Get the image from the frame - if ( error == 0 && *format == mlt_image_yuv422 ) - { - if ( this != NULL ) - { - // Get the filter properties - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Obtain the normalised width and height from the frame - int normalised_width = mlt_properties_get_int( frame_properties, "normalised_width" ); - int normalised_height = mlt_properties_get_int( frame_properties, "normalised_height" ); - - // Structures for geometry - struct geometry_s result; - struct geometry_s start; - struct geometry_s end; - - // Retrieve the position - float position = mlt_properties_get_double(frame_properties, "filter_position"); - - // Now parse the geometries - geometry_parse( &start, NULL, mlt_properties_get( properties, "start" ), normalised_width, normalised_height ); - geometry_parse( &end, &start, mlt_properties_get( properties, "end" ), normalised_width, normalised_height ); - - // Do the calculation - geometry_calculate( &result, &start, &end, position, *width, *height ); - - // Now actually render it - obscure_render( *image, *width, *height, result ); - } - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push this on to the service stack - mlt_frame_push_service( frame, this ); - - // Calculate the position for the filter effect - float position = position_calculate( this, frame ); - mlt_properties_set_double( MLT_FRAME_PROPERTIES( frame ), "filter_position", position ); - - // Push the get image call - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_obscure_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - this->process = filter_process; - mlt_properties_set( properties, "start", arg != NULL ? arg : "0%,0%:100%x100%" ); - mlt_properties_set( properties, "end", "" ); - } - return this; -} - diff --git a/src/modules/core/filter_region.c b/src/modules/core/filter_region.c deleted file mode 100644 index 8fd8e8d..0000000 --- a/src/modules/core/filter_region.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * filter_region.c -- region filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "transition_region.h" - -#include -#include - -#include -#include -#include - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Get the properties of the filter - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Get the region transition - mlt_transition transition = mlt_properties_get_data( properties, "_transition", NULL ); - - // Create the transition if not available - if ( transition == NULL ) - { - // Create the transition - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) ); - transition = mlt_factory_transition( profile, "region", NULL ); - - // Register with the filter - mlt_properties_set_data( properties, "_transition", transition, 0, ( mlt_destructor )mlt_transition_close, NULL ); - - // Pass a reference to this filter down - mlt_properties_set_data( MLT_TRANSITION_PROPERTIES( transition ), "_region_filter", this, 0, NULL, NULL ); - } - - // Pass all properties down - mlt_properties_pass( MLT_TRANSITION_PROPERTIES( transition ), properties, "" ); - - // Process the frame - return mlt_transition_process( transition, frame, NULL ); -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_region_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create a new filter - mlt_filter this = mlt_filter_new( ); - - // Further initialisation - if ( this != NULL ) - { - // Get the properties from the filter - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Assign the filter process method - this->process = filter_process; - - // Resource defines the shape of the region - mlt_properties_set( properties, "resource", arg == NULL ? "rectangle" : arg ); - - // Ensure that attached filters are handled privately - mlt_properties_set_int( properties, "_filter_private", 1 ); - } - - // Return the filter - return this; -} - diff --git a/src/modules/core/filter_rescale.c b/src/modules/core/filter_rescale.c deleted file mode 100644 index 25ca5fc..0000000 --- a/src/modules/core/filter_rescale.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * filter_rescale.c -- scale the producer video frame size to match the consumer - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include -#include - -typedef int ( *image_scaler )( mlt_frame this, uint8_t **image, mlt_image_format iformat, mlt_image_format oformat, int iwidth, int iheight, int owidth, int oheight ); - -static void scale_alpha( mlt_frame this, int iwidth, int iheight, int owidth, int oheight ); - -static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iformat, mlt_image_format oformat, int iwidth, int iheight, int owidth, int oheight ) -{ - // Get the properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get the rescaling interpolsation - char *interps = mlt_properties_get( properties, "rescale.interp" ); - - // Carry out the rescaling - if ( iformat == mlt_image_yuv422 && oformat == mlt_image_yuv422 ) - { - // Scale the frame - mlt_frame_rescale_yuv422( this, owidth, oheight ); - - // Return the output - *image = mlt_properties_get_data( properties, "image", NULL ); - - // Scale the alpha channel only if exists and not correct size - int alpha_size = 0; - mlt_properties_get_data( properties, "alpha", &alpha_size ); - if ( alpha_size > 0 && alpha_size != ( owidth * oheight ) ) - scale_alpha( this, iwidth, iheight, owidth, oheight ); - } - else if ( iformat == mlt_image_rgb24 || iformat == mlt_image_rgb24a ) - { - int bpp = (iformat == mlt_image_rgb24a ? 4 : 3 ); - - // Create the yuv image - uint8_t *output = mlt_pool_alloc( iwidth * ( iheight + 1 ) * 2 ); - - if ( strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) ) - { - // Extract YUV422 and alpha - if ( bpp == 4 ) - { - // Allocate the alpha mask - uint8_t *alpha = mlt_pool_alloc( iwidth * ( iheight + 1 ) ); - - // Convert the image and extract alpha - mlt_convert_rgb24a_to_yuv422( *image, iwidth, iheight, iwidth * 4, output, alpha ); - - mlt_properties_set_data( properties, "alpha", alpha, iwidth * ( iheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL ); - - scale_alpha( this, iwidth, iheight, owidth, oheight ); - } - else - { - // No alpha to extract - mlt_convert_rgb24_to_yuv422( *image, iwidth, iheight, iwidth * 3, output ); - } - - mlt_properties_set_data( properties, "image", output, iwidth * ( iheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); - - // Scale the frame - output = mlt_frame_rescale_yuv422( this, owidth, oheight ); - - } - else - { - // Extract YUV422 and alpha - if ( bpp == 4 ) - { - // Allocate the alpha mask - uint8_t *alpha = mlt_pool_alloc( owidth * ( oheight + 1 ) ); - - // Convert the image and extract alpha - mlt_convert_rgb24a_to_yuv422( *image, owidth, oheight, owidth * 4, output, alpha ); - - mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL ); - - scale_alpha( this, iwidth, iheight, owidth, oheight ); - } - else - { - // No alpha to extract - mlt_convert_rgb24_to_yuv422( *image, owidth, oheight, owidth * 3, output ); - } - } - - // Now update the frame - mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", owidth ); - mlt_properties_set_int( properties, "height", oheight ); - - *image = output; - } - - return 0; -} - -static void scale_alpha( mlt_frame this, int iwidth, int iheight, int owidth, int oheight ) -{ - // Scale the alpha - uint8_t *output = NULL; - uint8_t *input = mlt_frame_get_alpha_mask( this ); - - if ( input != NULL ) - { - uint8_t *out_line; - int x, y; - int ox = ( iwidth << 10 ) / owidth; - int oy = ( iheight << 10 ) / oheight; - - output = mlt_pool_alloc( owidth * oheight ); - out_line = output; - - // Loop for the entirety of our output height. - for ( y = 0; y < oheight; y ++ ) - for ( x = 0; x < owidth; x ++ ) - *out_line ++ = *( input + ( ( 512 + ( y * oy * iwidth ) + x * ox ) >> 10 ) ); - - // Set it back on the frame - mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", output, owidth * oheight, mlt_pool_release, NULL ); - } -} - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the frame properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get the filter from the stack - mlt_filter filter = mlt_frame_pop_service( this ); - - // Get the filter properties - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - - // Get the image scaler method - image_scaler scaler_method = mlt_properties_get_data( filter_properties, "method", NULL ); - - // Correct Width/height if necessary - if ( *width == 0 || *height == 0 ) - { - *width = mlt_properties_get_int( properties, "normalised_width" ); - *height = mlt_properties_get_int( properties, "normalised_height" ); - } - - // There can be problems with small images - avoid them (by hacking - gah) - if ( *width >= 6 && *height >= 6 ) - { - int iwidth = *width; - int iheight = *height; - int owidth = *width; - int oheight = *height; - char *interps = mlt_properties_get( properties, "rescale.interp" ); - int wanted_format = *format; - - // Default from the scaler if not specifed on the frame - if ( interps == NULL ) - { - interps = mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "interpolation" ); - mlt_properties_set( properties, "rescale.interp", interps ); - } - - // If real_width/height exist, we want that as minimum information - if ( mlt_properties_get_int( properties, "real_width" ) ) - { - iwidth = mlt_properties_get_int( properties, "real_width" ); - iheight = mlt_properties_get_int( properties, "real_height" ); - } - - // Let the producer know what we are actually requested to obtain - if ( *format == mlt_image_yuv422 && strcmp( interps, "none" ) ) - { - mlt_properties_set_int( properties, "rescale_width", *width ); - mlt_properties_set_int( properties, "rescale_height", *height ); - } - else - { - // When no scaling is requested, revert the requested dimensions if possible - mlt_properties_set_int( properties, "rescale_width", iwidth ); - mlt_properties_set_int( properties, "rescale_height", iheight ); - } - - // Deinterlace if height is changing to prevent fields mixing on interpolation - // One exception: non-interpolated, integral scaling - if ( iheight != oheight && ( strcmp( interps, "nearest" ) || ( iheight % oheight != 0 ) ) ) - mlt_properties_set_int( properties, "consumer_deinterlace", 1 ); - - // Get the image as requested - mlt_frame_get_image( this, image, format, &iwidth, &iheight, writable ); - - // Get rescale interpretation again, in case the producer wishes to override scaling - interps = mlt_properties_get( properties, "rescale.interp" ); - - if ( *image != NULL && ( *format != mlt_image_yuv422 || ( iwidth != owidth || iheight != oheight ) ) ) - { - // If the colour space is correct and scaling is off, do nothing - if ( *format == mlt_image_yuv422 && !strcmp( interps, "none" ) ) - { - *width = iwidth; - *height = iheight; - } - else if ( *format == mlt_image_yuv422 ) - { - // Call the local scaler - scaler_method( this, image, *format, mlt_image_yuv422, iwidth, iheight, owidth, oheight ); - *width = owidth; - *height = oheight; - } - else if ( *format == mlt_image_rgb24 && wanted_format == mlt_image_rgb24 ) - { - // Call the local scaler - scaler_method( this, image, *format, mlt_image_rgb24, iwidth, iheight, owidth, oheight ); - - // Return the output - *width = owidth; - *height = oheight; - } - else if ( *format == mlt_image_rgb24 || *format == mlt_image_rgb24a ) - { - // Call the local scaler - scaler_method( this, image, *format, mlt_image_yuv422, iwidth, iheight, owidth, oheight ); - - // Return the output - *format = mlt_image_yuv422; - *width = owidth; - *height = oheight; - } - else - { - *width = iwidth; - *height = iheight; - } - } - else - { - *width = iwidth; - *height = iheight; - } - } - else - { - // Store the requested width/height - int iwidth = *width; - int iheight = *height; - - // Get the image as requested - mlt_frame_get_image( this, image, format, &iwidth, &iheight, writable ); - - // Too small - for now just assign as though we got what we wanted - *width = iwidth; - *height = iheight; - } - - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push the filter - mlt_frame_push_service( frame, this ); - - // Push the get image method - mlt_frame_push_service( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_rescale_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create a new scaler - mlt_filter this = mlt_filter_new( ); - - // If successful, then initialise it - if ( this != NULL ) - { - // Get the properties - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Set the process method - this->process = filter_process; - - // Set the inerpolation - mlt_properties_set( properties, "interpolation", arg == NULL ? "bilinear" : arg ); - - // Set the method - mlt_properties_set_data( properties, "method", filter_scale, 0, NULL, NULL ); - } - - return this; -} - diff --git a/src/modules/core/filter_resize.c b/src/modules/core/filter_resize.c deleted file mode 100644 index 68244bf..0000000 --- a/src/modules/core/filter_resize.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * filter_resize.c -- resizing filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include -#include - -/** Swapbytes inline. -*/ - -static inline void swap_bytes( uint8_t *upper, uint8_t *lower ) -{ - uint8_t t = *lower; - *lower = *upper; - *upper = t; -} - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - int error = 0; - - // Get the properties from the frame - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Pop the top of stack now - mlt_filter filter = mlt_frame_pop_service( this ); - - // Retrieve the aspect ratio - double aspect_ratio = mlt_deque_pop_back_double( MLT_FRAME_IMAGE_STACK( this ) ); - - // Correct Width/height if necessary - if ( *width == 0 || *height == 0 ) - { - *width = mlt_properties_get_int( properties, "normalised_width" ); - *height = mlt_properties_get_int( properties, "normalised_height" ); - } - - // Assign requested width/height from our subordinate - int owidth = *width; - int oheight = *height; - - // Check for the special case - no aspect ratio means no problem :-) - if ( aspect_ratio == 0.0 ) - aspect_ratio = mlt_properties_get_double( properties, "consumer_aspect_ratio" ); - - // Reset the aspect ratio - mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio ); - - // Hmmm... - char *rescale = mlt_properties_get( properties, "rescale.interp" ); - if ( rescale != NULL && !strcmp( rescale, "none" ) ) - return mlt_frame_get_image( this, image, format, width, height, writable ); - - if ( mlt_properties_get_int( properties, "distort" ) == 0 ) - { - // Normalise the input and out display aspect - int normalised_width = mlt_properties_get_int( properties, "normalised_width" ); - int normalised_height = mlt_properties_get_int( properties, "normalised_height" ); - int real_width = mlt_properties_get_int( properties, "real_width" ); - int real_height = mlt_properties_get_int( properties, "real_height" ); - if ( real_width == 0 ) - real_width = mlt_properties_get_int( properties, "width" ); - if ( real_height == 0 ) - real_height = mlt_properties_get_int( properties, "height" ); - double input_ar = aspect_ratio * real_width / real_height; - double output_ar = mlt_properties_get_double( properties, "consumer_aspect_ratio" ) * owidth / oheight; - -// fprintf( stderr, "real %dx%d normalised %dx%d output %dx%d sar %f in-dar %f out-dar %f\n", -// real_width, real_height, normalised_width, normalised_height, owidth, oheight, aspect_ratio, input_ar, output_ar); - - // Optimised for the input_ar > output_ar case (e.g. widescreen on standard) - int scaled_width = rint( ( input_ar * normalised_width ) / output_ar ); - int scaled_height = normalised_height; - - // Now ensure that our images fit in the output frame - if ( scaled_width > normalised_width ) - { - scaled_width = normalised_width; - scaled_height = rint( ( output_ar * normalised_height ) / input_ar ); - } - - // Now calculate the actual image size that we want - owidth = rint( scaled_width * owidth / normalised_width ); - oheight = rint( scaled_height * oheight / normalised_height ); - - // Tell frame we have conformed the aspect to the consumer - mlt_frame_set_aspect_ratio( this, mlt_properties_get_double( properties, "consumer_aspect_ratio" ) ); - } - - mlt_properties_set_int( properties, "distort", 0 ); - - // Now pass on the calculations down the line - mlt_properties_set_int( properties, "resize_width", *width ); - mlt_properties_set_int( properties, "resize_height", *height ); - - // Now get the image - error = mlt_frame_get_image( this, image, format, &owidth, &oheight, writable ); - - // We only know how to process yuv422 at the moment - if ( error == 0 && *format == mlt_image_yuv422 && *image != NULL ) - { - // Get the requested scale operation - char *op = mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "scale" ); - - // Provides a manual override for misreported field order - if ( mlt_properties_get( properties, "meta.top_field_first" ) ) - mlt_properties_set_int( properties, "top_field_first", mlt_properties_get_int( properties, "meta.top_field_first" ) ); - - // Correct field order if needed - if ( mlt_properties_get_int( properties, "top_field_first" ) == 1 ) - { - // Get the input image, width and height - int size; - uint8_t *image = mlt_properties_get_data( properties, "image", &size ); - uint8_t *ptr = image + owidth * 2; - memmove( ptr, image, size - owidth * 2 ); - - // Set the normalised field order - mlt_properties_set_int( properties, "top_field_first", 0 ); - mlt_properties_set_int( properties, "meta.top_field_first", 0 ); - } - - if ( !strcmp( op, "affine" ) ) - { - *image = mlt_frame_rescale_yuv422( this, *width, *height ); - } - else if ( strcmp( op, "none" ) != 0 ) - { - *image = mlt_frame_resize_yuv422( this, *width, *height ); - } - else - { - *width = owidth; - *height = oheight; - } - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Store the aspect ratio reported by the source - mlt_deque_push_back_double( MLT_FRAME_IMAGE_STACK( frame ), mlt_frame_get_aspect_ratio( frame ) ); - - // Push this on to the service stack - mlt_frame_push_service( frame, this ); - - // Push the get_image method on to the stack - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_resize_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 ); - if ( mlt_filter_init( this, this ) == 0 ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "scale", arg == NULL ? "off" : arg ); - } - return this; -} diff --git a/src/modules/core/filter_transition.c b/src/modules/core/filter_transition.c deleted file mode 100644 index cd3f462..0000000 --- a/src/modules/core/filter_transition.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * filter_transition.c -- Convert any transition into a filter - * Copyright (C) 2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -/** Get the image via the transition. - NB: Not all transitions will accept a and b frames being the same... -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_transition transition = mlt_frame_pop_service( this ); - if ( mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "image_count" ) >= 1 ) - mlt_transition_process( transition, this, this ); - return mlt_frame_get_image( this, image, format, width, height, writable ); -} - -/** Get the audio via the transition. - NB: Not all transitions will accept a and b frames being the same... -*/ - -static int filter_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Obtain the transition instance - mlt_transition transition = mlt_frame_pop_audio( this ); - mlt_transition_process( transition, this, this ); - return mlt_frame_get_audio( this, buffer, format, frequency, channels, samples ); -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Obtain the transition instance - mlt_transition transition = mlt_properties_get_data( MLT_FILTER_PROPERTIES( this ), "instance", NULL ); - - // If we haven't created the instance, do it now - if ( transition == NULL ) - { - char *name = mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "transition" ); - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) ); - transition = mlt_factory_transition( profile, name, NULL ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), "instance", transition, 0, ( mlt_destructor )mlt_transition_close, NULL ); - } - - // We may still not have a transition... - if ( transition != NULL ) - { - // Get the transition type - int type = mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( transition ), "_transition_type" ); - - // Set the basic info - mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "in", mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "in" ) ); - mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "out", mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "out" ) ); - - // Refresh with current user values - mlt_properties_pass( MLT_TRANSITION_PROPERTIES( transition ), MLT_FILTER_PROPERTIES( this ), "transition." ); - - if ( type & 1 && !mlt_frame_is_test_card( frame ) && !( mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "hide" ) & 1 ) ) - { - mlt_frame_push_service( frame, transition ); - mlt_frame_push_get_image( frame, filter_get_image ); - } - if ( type & 2 && !mlt_frame_is_test_audio( frame ) && !( mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "hide" ) & 2 ) ) - { - mlt_frame_push_audio( frame, transition ); - mlt_frame_push_audio( frame, filter_get_audio ); - } - - if ( type == 0 ) - mlt_properties_debug( MLT_TRANSITION_PROPERTIES( transition ), "unknown transition type", stderr ); - } - else - { - mlt_properties_debug( MLT_FILTER_PROPERTIES( this ), "no transition", stderr ); - } - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_transition_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "transition", arg ); - this->process = filter_process; - } - return this; -} - diff --git a/src/modules/core/filter_watermark.c b/src/modules/core/filter_watermark.c deleted file mode 100644 index 2e88e08..0000000 --- a/src/modules/core/filter_watermark.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * filter_watermark.c -- watermark filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Error we will return - int error = 0; - - // Get the watermark filter object - mlt_filter this = mlt_frame_pop_service( frame ); - - // Get the properties of the filter - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Get the producer from the filter - mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL ); - - // Get the composite from the filter - mlt_transition composite = mlt_properties_get_data( properties, "composite", NULL ); - - // Get the resource to use - char *resource = mlt_properties_get( properties, "resource" ); - - // Get the old resource - char *old_resource = mlt_properties_get( properties, "_old_resource" ); - - // Create a composite if we don't have one - if ( composite == NULL ) - { - // Create composite via the factory - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) ); - composite = mlt_factory_transition( profile, "composite", NULL ); - - // Register the composite for reuse/destruction - if ( composite != NULL ) - mlt_properties_set_data( properties, "composite", composite, 0, ( mlt_destructor )mlt_transition_close, NULL ); - } - - // If we have one - if ( composite != NULL ) - { - // Get the properties - mlt_properties composite_properties = MLT_TRANSITION_PROPERTIES( composite ); - - // Pass all the composite. properties on the filter down - mlt_properties_pass( composite_properties, properties, "composite." ); - - if ( mlt_properties_get( properties, "composite.out" ) == NULL ) - mlt_properties_set_int( composite_properties, "out", mlt_properties_get_int( properties, "_out" ) ); - - // Force a refresh - mlt_properties_set_int( composite_properties, "refresh", 1 ); - } - - // Create a producer if don't have one - if ( producer == NULL || ( old_resource != NULL && strcmp( resource, old_resource ) ) ) - { - // Get the factory producer service - char *factory = mlt_properties_get( properties, "factory" ); - - // Create the producer - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) ); - producer = mlt_factory_producer( profile, factory, resource ); - - // If we have one - if ( producer != NULL ) - { - // Register the producer for reuse/destruction - mlt_properties_set_data( properties, "producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); - - // Ensure that we loop - mlt_properties_set( MLT_PRODUCER_PROPERTIES( producer ), "eof", "loop" ); - - // Set the old resource - mlt_properties_set( properties, "_old_resource", resource ); - } - } - - if ( producer != NULL ) - { - // Get the producer properties - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Now pass all producer. properties on the filter down - mlt_properties_pass( producer_properties, properties, "producer." ); - } - - // Only continue if we have both producer and composite - if ( composite != NULL && producer != NULL ) - { - // Get the service of the producer - mlt_service service = MLT_PRODUCER_SERVICE( producer ); - - // We will get the 'b frame' from the producer - mlt_frame b_frame = NULL; - - // Get the unique id of the filter (used to reacquire the producer position) - char *name = mlt_properties_get( properties, "_unique_id" ); - - // Get the original producer position - mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( frame ), name ); - - // Make sure the producer is in the correct position - mlt_producer_seek( producer, position ); - - // Resetting position to appease the composite transition - mlt_frame_set_position( frame, position ); - - // Get the b frame and process with composite if successful - if ( mlt_service_get_frame( service, &b_frame, 0 ) == 0 ) - { - // Get the a and b frame properties - mlt_properties a_props = MLT_FRAME_PROPERTIES( frame ); - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - - // Set the b frame to be in the same position and have same consumer requirements - mlt_frame_set_position( b_frame, position ); - mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - mlt_properties_set_int( b_props, "consumer_deinterlace", mlt_properties_get_int( a_props, "consumer_deinterlace" ) || mlt_properties_get_int( properties, "deinterlace" ) ); - mlt_properties_set_double( b_props, "output_ratio", mlt_properties_get_double( a_props, "output_ratio" ) ); - - // Check for the special case - no aspect ratio means no problem :-) - if ( mlt_frame_get_aspect_ratio( b_frame ) == 0 ) - mlt_properties_set_double( b_props, "aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - if ( mlt_frame_get_aspect_ratio( frame ) == 0 ) - mlt_properties_set_double( a_props, "aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - - mlt_properties_set_int( b_props, "normalised_width", mlt_properties_get_int( a_props, "normalised_width" ) ); - mlt_properties_set_int( b_props, "normalised_height", mlt_properties_get_int( a_props, "normalised_height" ) ); - - if ( mlt_properties_get_int( properties, "distort" ) ) - { - mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( composite ), "distort", 1 ); - mlt_properties_set_int( a_props, "distort", 1 ); - mlt_properties_set_int( b_props, "distort", 1 ); - } - - if ( mlt_properties_get_int( properties, "reverse" ) == 0 ) - { - // Apply all filters that are attached to this filter to the b frame - mlt_service_apply_filters( MLT_FILTER_SERVICE( this ), b_frame, 0 ); - - // Process the frame - mlt_transition_process( composite, frame, b_frame ); - - // Get the image - error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - } - else - { - char temp[ 132 ]; - int count = 0; - uint8_t *alpha = NULL; - const char *rescale = mlt_properties_get( a_props, "rescale.interp" ); - if ( rescale == NULL || !strcmp( rescale, "none" ) ) - rescale = "hyper"; - mlt_transition_process( composite, b_frame, frame ); - mlt_properties_set_int( a_props, "consumer_deinterlace", 1 ); - mlt_properties_set_int( b_props, "consumer_deinterlace", 1 ); - mlt_properties_set( a_props, "rescale.interp", rescale ); - mlt_properties_set( b_props, "rescale.interp", rescale ); - mlt_service_apply_filters( MLT_FILTER_SERVICE( this ), b_frame, 0 ); - error = mlt_frame_get_image( b_frame, image, format, width, height, 1 ); - alpha = mlt_frame_get_alpha_mask( b_frame ); - mlt_properties_set_data( a_props, "image", *image, *width * *height * 2, NULL, NULL ); - mlt_properties_set_data( a_props, "alpha", alpha, *width * *height, NULL, NULL ); - mlt_properties_set_int( a_props, "width", *width ); - mlt_properties_set_int( a_props, "height", *height ); - mlt_properties_set_int( a_props, "progressive", 1 ); - mlt_properties_inc_ref( b_props ); - strcpy( temp, "_b_frame" ); - while( mlt_properties_get_data( a_props, temp, NULL ) != NULL ) - sprintf( temp, "_b_frame%d", count ++ ); - mlt_properties_set_data( a_props, temp, b_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); - } - } - - // Close the b frame - mlt_frame_close( b_frame ); - } - else - { - // Get the image from the frame without running fx - error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Get the properties of the frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Get a unique name to store the frame position - char *name = mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "_unique_id" ); - - // Assign the frame out point to the filter (just in case we need it later) - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "_out", mlt_properties_get_int( properties, "out" ) ); - - // Assign the current position to the name - mlt_properties_set_position( properties, name, mlt_frame_get_position( frame ) - mlt_filter_get_in( this ) ); - - // Push the filter on to the stack - mlt_frame_push_service( frame, this ); - - // Push the get_image on to the stack - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_watermark_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - this->process = filter_process; - mlt_properties_set( properties, "factory", "fezzik" ); - if ( arg != NULL ) - mlt_properties_set( properties, "resource", arg ); - // Ensure that attached filters are handled privately - mlt_properties_set_int( properties, "_filter_private", 1 ); - } - return this; -} - diff --git a/src/modules/core/producer_colour.c b/src/modules/core/producer_colour.c deleted file mode 100644 index ac42001..0000000 --- a/src/modules/core/producer_colour.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * producer_colour.c -- raster image loader based upon gdk-pixbuf - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include - - -typedef struct -{ - uint8_t r, g, b, a; -} rgba_color; - -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer parent ); - -mlt_producer producer_colour_init( mlt_profile profile, mlt_service_type type, const char *id, char *colour ) -{ - mlt_producer producer = calloc( 1, sizeof( struct mlt_producer_s ) ); - if ( producer != NULL && mlt_producer_init( producer, NULL ) == 0 ) - { - // Get the properties interface - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Callback registration - producer->get_frame = producer_get_frame; - producer->close = ( mlt_destructor )producer_close; - - // Set the default properties - mlt_properties_set( properties, "resource", colour == NULL ? "0x000000ff" : colour ); - mlt_properties_set( properties, "_resource", "" ); - mlt_properties_set_double( properties, "aspect_ratio", 0 ); - - return producer; - } - free( producer ); - return NULL; -} - -rgba_color parse_color( char *color, unsigned int color_int ) -{ - rgba_color result = { 0xff, 0xff, 0xff, 0xff }; - - if ( !strcmp( color, "red" ) ) - { - result.r = 0xff; - result.g = 0x00; - result.b = 0x00; - } - else if ( !strcmp( color, "green" ) ) - { - result.r = 0x00; - result.g = 0xff; - result.b = 0x00; - } - else if ( !strcmp( color, "blue" ) ) - { - result.r = 0x00; - result.g = 0x00; - result.b = 0xff; - } - else if ( strcmp( color, "white" ) ) - { - result.r = ( color_int >> 24 ) & 0xff; - result.g = ( color_int >> 16 ) & 0xff; - result.b = ( color_int >> 8 ) & 0xff; - result.a = ( color_int ) & 0xff; - } - - return result; -} - -static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - // May need to know the size of the image to clone it - int size = 0; - - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the producer for this frame - mlt_producer producer = mlt_properties_get_data( properties, "producer_colour", NULL ); - - // Obtain properties of producer - mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); - - // Get the current and previous colour strings - char *now = mlt_properties_get( producer_props, "resource" ); - char *then = mlt_properties_get( producer_props, "_resource" ); - - // Get the current image and dimensions cached in the producer - uint8_t *image = mlt_properties_get_data( producer_props, "image", &size ); - int current_width = mlt_properties_get_int( producer_props, "_width" ); - int current_height = mlt_properties_get_int( producer_props, "_height" ); - - // Parse the colour - if ( now && strchr( now, '/' ) ) - { - now = strrchr( now, '/' ) + 1; - mlt_properties_set( producer_props, "resource", now ); - } - rgba_color color = parse_color( now, mlt_properties_get_int( producer_props, "resource" ) ); - - // See if we need to regenerate - if ( strcmp( now, then ) || *width != current_width || *height != current_height ) - { - // Color the image - uint8_t y, u, v; - int i = *height; - int j = 0; - int uneven = *width % 2; - int count = ( *width - uneven ) / 2; - uint8_t *p = NULL; - - // Allocate the image - size = *width * *height * 2; - image = mlt_pool_alloc( size ); - - // Update the producer - mlt_properties_set_data( producer_props, "image", image, size, mlt_pool_release, NULL ); - mlt_properties_set_int( producer_props, "_width", *width ); - mlt_properties_set_int( producer_props, "_height", *height ); - mlt_properties_set( producer_props, "_resource", now ); - - RGB2YUV( color.r, color.g, color.b, y, u, v ); - - p = image; - - while ( i -- ) - { - j = count; - while ( j -- ) - { - *p ++ = y; - *p ++ = u; - *p ++ = y; - *p ++ = v; - } - if ( uneven ) - { - *p ++ = y; - *p ++ = u; - } - } - } - - // Update the frame - mlt_properties_set_int( properties, "width", *width ); - mlt_properties_set_int( properties, "height", *height ); - - // Clone if necessary (deemed always necessary) - if ( 1 ) - { - // Create the alpha channel - uint8_t *alpha = mlt_pool_alloc( size >> 1 ); - - // Clone our image - uint8_t *copy = mlt_pool_alloc( size ); - memcpy( copy, image, size ); - - // We're going to pass the copy on - image = copy; - - // Initialise the alpha - if ( alpha ) - memset( alpha, color.a, size >> 1 ); - - // Now update properties so we free the copy after - mlt_properties_set_data( properties, "image", copy, size, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "alpha", alpha, size >> 1, mlt_pool_release, NULL ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) ); - } - - // Pass on the image - *buffer = image; - *format = mlt_image_yuv422; - - return 0; -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Generate a frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - if ( *frame != NULL ) - { - // Obtain properties of frame and producer - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Obtain properties of producer - mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); - - // Set the producer on the frame properties - mlt_properties_set_data( properties, "producer_colour", producer, 0, NULL, NULL ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Set producer-specific frame properties - mlt_properties_set_int( properties, "progressive", 1 ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) ); - - // colour is an alias for resource - if ( mlt_properties_get( producer_props, "colour" ) != NULL ) - mlt_properties_set( producer_props, "resource", mlt_properties_get( producer_props, "colour" ) ); - - // Push the get_image method - mlt_frame_push_get_image( *frame, producer_get_image ); - } - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer producer ) -{ - producer->close = NULL; - mlt_producer_close( producer ); - free( producer ); -} diff --git a/src/modules/core/producer_consumer.c b/src/modules/core/producer_consumer.c deleted file mode 100644 index 78c5bcc..0000000 --- a/src/modules/core/producer_consumer.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * producer_consumer.c -- produce as a consumer of an encapsulated producer - * Copyright (C) 2008 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include -#include -#include -#include - -struct context_s { - mlt_producer this; - mlt_producer producer; - mlt_consumer consumer; - mlt_profile profile; - int is_close_profile; -}; -typedef struct context_s *context; - - -static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - context cx = mlt_frame_pop_service( frame ); - mlt_frame nested_frame = mlt_frame_pop_service( frame ); - - *width = cx->profile->width; - *height = cx->profile->height; - - int result = mlt_frame_get_image( nested_frame, image, format, width, height, writable ); - - // Allocate the image - int size = *width * *height * ( *format == mlt_image_yuv422 ? 2 : *format == mlt_image_rgb24 ? 3 : *format == mlt_image_rgb24a ? 4 : ( 3 / 2 ) ); - uint8_t *new_image = mlt_pool_alloc( size ); - - // Update the frame - mlt_properties properties = mlt_frame_properties( frame ); - mlt_properties_set_data( properties, "image", new_image, size, mlt_pool_release, NULL ); - memcpy( new_image, *image, size ); - mlt_frame_close( nested_frame ); - *image = new_image; - -// mlt_properties_debug( properties, "frame", stderr ); -// mlt_properties_debug( mlt_frame_properties( nested_frame ), "nested_frame", stderr ); - - return result; -} - -static int get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - mlt_frame nested_frame = mlt_frame_pop_audio( frame ); - int result = mlt_frame_get_audio( nested_frame, buffer, format, frequency, channels, samples ); - int size = *channels * *samples * sizeof( int16_t ); - int16_t *new_buffer = mlt_pool_alloc( size ); - mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), "audio", new_buffer, size, mlt_pool_release, NULL ); - memcpy( new_buffer, *buffer, size ); - *buffer = new_buffer; - mlt_frame_close( nested_frame ); - return result; -} - -static int get_frame( mlt_producer this, mlt_frame_ptr frame, int index ) -{ - mlt_properties properties = MLT_PRODUCER_PROPERTIES(this); - context cx = mlt_properties_get_data( properties, "context", NULL ); - - if ( !cx ) - { - // Allocate and initialize our context - cx = mlt_pool_alloc( sizeof( struct context_s ) ); - mlt_properties_set_data( properties, "context", cx, 0, mlt_pool_release, NULL ); - cx->this = this; - char *profile_name = mlt_properties_get( properties, "profile" ); - mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( this ) ); - - if ( profile_name ) - { - cx->profile = mlt_profile_init( profile_name ); - cx->is_close_profile = 1; - } - else - { - cx->profile = profile; - cx->is_close_profile = 0; - } - - // For now, we must conform the nested network's frame rate to the parent network's - // framerate. - cx->profile->frame_rate_num = profile->frame_rate_num; - cx->profile->frame_rate_den = profile->frame_rate_den; - - // We will encapsulate a consumer - cx->consumer = mlt_consumer_new( cx->profile ); - // Do not use _pass_list on real_time so that it defaults to 0 in the absence of - // an explicit real_time property. - mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( cx->consumer ), "real_time", - mlt_properties_get_int( properties, "real_time" ) ); - mlt_properties_pass_list( MLT_CONSUMER_PROPERTIES( cx->consumer ), properties, - "buffer, prefill" ); - - // Encapsulate a real producer for the resource - cx->producer = mlt_factory_producer( cx->profile, mlt_environment( "MLT_PRODUCER" ), - mlt_properties_get( properties, "resource" ) ); - mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( cx->producer ), - "out, length" ); - - // Since we control the seeking, prevent it from seeking on its own - mlt_producer_set_speed( cx->producer, 0 ); - - // Connect it all together - mlt_consumer_connect( cx->consumer, MLT_PRODUCER_SERVICE( cx->producer ) ); - mlt_consumer_start( cx->consumer ); - } - - // Generate a frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( this ) ); - if ( frame ) - { - // Our "in" needs to be the same, keep it so - mlt_properties_pass_list( MLT_PRODUCER_PROPERTIES( cx->producer ), properties, "in, out" ); - - // Seek the producer to the correct place - // Calculate our positions - double actual_position = mlt_producer_get_speed( this ) * (double)mlt_producer_position( this ); - mlt_position need_first = floor( actual_position ); - mlt_producer_seek( cx->producer, need_first ); - - // Get the nested frame - mlt_frame nested_frame = mlt_consumer_rt_frame( cx->consumer ); - - // Stack the producer and our methods on the nested frame - mlt_frame_push_service( *frame, nested_frame ); - mlt_frame_push_service( *frame, cx ); - mlt_frame_push_get_image( *frame, get_image ); - mlt_frame_push_audio( *frame, nested_frame ); - mlt_frame_push_audio( *frame, get_audio ); - - // Give the returned frame temporal identity - mlt_frame_set_position( *frame, mlt_producer_position( this ) ); - - // Put additional references on the frame so both get_image and get_audio - // methods can close it. - mlt_properties_inc_ref( MLT_FRAME_PROPERTIES( nested_frame ) ); - - // Inform the normalizers about our video properties - mlt_properties frame_props = MLT_FRAME_PROPERTIES( *frame ); - mlt_properties_set_double( frame_props, "aspect_ratio", mlt_profile_sar( cx->profile ) ); - mlt_properties_set_int( frame_props, "width", cx->profile->width ); - mlt_properties_set_int( frame_props, "height", cx->profile->height ); - mlt_properties_set_int( frame_props, "real_width", cx->profile->width ); - mlt_properties_set_int( frame_props, "real_height", cx->profile->height ); - mlt_properties_set_int( frame_props, "progressive", cx->profile->progressive ); - } - - // Calculate the next timecode - mlt_producer_prepare_next( this ); - - return 0; -} - -static void producer_close( mlt_producer this ) -{ - context cx = mlt_properties_get_data( MLT_PRODUCER_PROPERTIES( this ), "context", NULL ); - - // Shut down all the encapsulated services - if ( cx ) - { - mlt_consumer_stop( cx->consumer ); - mlt_consumer_close( cx->consumer ); - mlt_producer_close( cx->producer ); - if ( cx->is_close_profile ) - mlt_profile_close( cx->profile ); - } - - this->close = NULL; - mlt_producer_close( this ); - free( this ); -} - -mlt_producer producer_consumer_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_producer this = mlt_producer_new( ); - - // Encapsulate the real producer - mlt_producer real_producer = mlt_factory_producer( profile, mlt_environment( "MLT_PRODUCER" ), arg ); - - if ( this && real_producer ) - { - // Override some producer methods - this->close = ( mlt_destructor )producer_close; - this->get_frame = get_frame; - - // Get the properties of this producer - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - mlt_properties_set( properties, "resource", arg ); - mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( real_producer ), "out, length" ); - - // Done with the producer - will re-open later when we have the profile property - mlt_producer_close( real_producer ); - } - else - { - if ( this ) - mlt_producer_close( this ); - if ( real_producer ) - mlt_producer_close( real_producer ); - - this = NULL; - } - return this; -} diff --git a/src/modules/core/producer_noise.c b/src/modules/core/producer_noise.c deleted file mode 100644 index 825f591..0000000 --- a/src/modules/core/producer_noise.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * producer_noise.c -- noise generating producer - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include - -/** Random number generator -*/ - -static unsigned int seed_x = 521288629; -static unsigned int seed_y = 362436069; - -static inline unsigned int fast_rand( ) -{ - static unsigned int a = 18000, b = 30903; - seed_x = a * ( seed_x & 65535 ) + ( seed_x >> 16 ); - seed_y = b * ( seed_y & 65535 ) + ( seed_y >> 16 ); - return ( ( seed_x << 16 ) + ( seed_y & 65535 ) ); -} - -// Foward declarations -static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer this ); - -/** Initialise. -*/ - -mlt_producer producer_noise_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create a new producer object - mlt_producer this = mlt_producer_new( ); - - // Initialise the producer - if ( this != NULL ) - { - // Callback registration - this->get_frame = producer_get_frame; - this->close = ( mlt_destructor )producer_close; - } - - return this; -} - -static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Calculate the size of the image - int size = *width * *height * 2; - - // Set the format being returned - *format = mlt_image_yuv422; - - // Allocate the image - *buffer = mlt_pool_alloc( size ); - - // Update the frame - mlt_properties_set_data( properties, "image", *buffer, size, mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", *width ); - mlt_properties_set_int( properties, "height", *height ); - - // Before we write to the image, make sure we have one - if ( *buffer != NULL ) - { - // Calculate the end of the buffer - uint8_t *p = *buffer + *width * *height * 2; - - // Value to hold a random number - uint32_t value; - - // Generate random noise - while ( p != *buffer ) - { - value = fast_rand( ) & 0xff; - *( -- p ) = 128; - *( -- p ) = value < 16 ? 16 : value > 240 ? 240 : value; - } - } - - return 0; -} - -static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the frame properties - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - int size = 0; - - // Correct the returns if necessary - *samples = *samples <= 0 ? 1920 : *samples; - *channels = *channels <= 0 ? 2 : *channels; - *frequency = *frequency <= 0 ? 48000 : *frequency; - - // Calculate the size of the buffer - size = *samples * *channels * sizeof( int16_t ); - - // Allocate the buffer - *buffer = mlt_pool_alloc( size ); - - // Make sure we got one and fill it - if ( *buffer != NULL ) - { - int16_t *p = *buffer + size / 2; - while ( p != *buffer ) - *( -- p ) = fast_rand( ) & 0x0f00; - } - - // Set the buffer for destruction - mlt_properties_set_data( properties, "audio", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - - return 0; -} - -static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ) -{ - // Generate a frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( this ) ); - - // Check that we created a frame and initialise it - if ( *frame != NULL ) - { - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Aspect ratio is whatever it needs to be - mlt_properties_set_double( properties, "aspect_ratio", 0 ); - - // Set producer-specific frame properties - mlt_properties_set_int( properties, "progressive", 1 ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( this ) ); - - // Push the get_image method - mlt_frame_push_get_image( *frame, producer_get_image ); - - // Specify the audio - mlt_frame_push_audio( *frame, producer_get_audio ); - } - - // Calculate the next timecode - mlt_producer_prepare_next( this ); - - return 0; -} - -static void producer_close( mlt_producer this ) -{ - this->close = NULL; - mlt_producer_close( this ); - free( this ); -} - diff --git a/src/modules/core/producer_ppm.c b/src/modules/core/producer_ppm.c deleted file mode 100644 index 0121579..0000000 --- a/src/modules/core/producer_ppm.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * producer_ppm.c -- simple ppm test case - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include - -typedef struct producer_ppm_s *producer_ppm; - -struct producer_ppm_s -{ - struct mlt_producer_s parent; - char *command; - FILE *video; - FILE *audio; - uint64_t expected; -}; - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer parent ); - -mlt_producer producer_ppm_init( mlt_profile profile, mlt_service_type type, const char *id, char *command ) -{ - producer_ppm this = calloc( sizeof( struct producer_ppm_s ), 1 ); - if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) - { - mlt_producer producer = &this->parent; - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - - producer->get_frame = producer_get_frame; - producer->close = ( mlt_destructor )producer_close; - - if ( command != NULL ) - { - mlt_properties_set( properties, "resource", command ); - this->command = strdup( command ); - } - else - { - mlt_properties_set( properties, "resource", "ppm test" ); - } - - return producer; - } - free( this ); - return NULL; -} - -static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - if ( mlt_properties_get_int( properties, "has_image" ) ) - { - // Get the RGB image - uint8_t *rgb = mlt_properties_get_data( properties, "image", NULL ); - - // Get width and height - *width = mlt_properties_get_int( properties, "width" ); - *height = mlt_properties_get_int( properties, "height" ); - - // Convert to requested format - if ( *format == mlt_image_yuv422 ) - { - uint8_t *image = mlt_pool_alloc( *width * ( *height + 1 ) * 2 ); - mlt_convert_rgb24_to_yuv422( rgb, *width, *height, *width * 3, image ); - mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); - *buffer = image; - } - else if ( *format == mlt_image_rgb24 ) - { - *buffer = rgb; - } - } - else - { - mlt_frame_get_image( this, buffer, format, width, height, writable ); - } - - return 0; -} - -FILE *producer_ppm_run_video( producer_ppm this ) -{ - if ( this->video == NULL ) - { - if ( this->command == NULL ) - { - this->video = popen( "image2raw -k -r 25 -ppm /usr/share/pixmaps/*.png", "r" ); - } - else - { - char command[ 1024 ]; - float fps = mlt_producer_get_fps( &this->parent ); - float position = mlt_producer_position( &this->parent ); - sprintf( command, "ffmpeg -i \"%s\" -ss %f -f imagepipe -r %f -img ppm - 2>/dev/null", this->command, position, fps ); - this->video = popen( command, "r" ); - } - } - return this->video; -} - -FILE *producer_ppm_run_audio( producer_ppm this ) -{ - if ( this->audio == NULL ) - { - if ( this->command != NULL ) - { - char command[ 1024 ]; - float position = mlt_producer_position( &this->parent ); - sprintf( command, "ffmpeg -i \"%s\" -ss %f -f s16le -ar 48000 -ac 2 - 2>/dev/null", this->command, position ); - this->audio = popen( command, "r" ); - } - } - return this->audio; -} - -static void producer_ppm_position( producer_ppm this, uint64_t requested ) -{ - if ( requested != this->expected ) - { - if ( this->video != NULL ) - pclose( this->video ); - this->video = NULL; - if ( this->audio != NULL ) - pclose( this->audio ); - this->audio = NULL; - } - - // This is the next frame we expect - this->expected = mlt_producer_frame( &this->parent ) + 1; - - // Open the pipe - this->video = producer_ppm_run_video( this ); - - // Open the audio pipe - this->audio = producer_ppm_run_audio( this ); - -} - -static int producer_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - FILE *pipe = mlt_properties_get_data( properties, "audio.pipe", NULL ); - - *frequency = 48000; - *channels = 2; - *samples = 1920; - - // Size - int size = *samples * *channels * 2; - - // Allocate an image - *buffer = malloc( size ); - - // Read it - if ( pipe != NULL ) - fread( *buffer, size, 1, pipe ); - else - memset( *buffer, 0, size ); - - // Pass the data on the frame properties - mlt_properties_set_data( properties, "audio", *buffer, size, free, NULL ); - - return 0; -} - -static int read_ppm_header( FILE *video, int *width, int *height ) -{ - int count = 0; - { - char temp[ 132 ]; - fgets( temp, 132, video ); - fgets( temp, 132, video ); - count += sscanf( temp, "%d %d", width, height ); - fgets( temp, 132, video ); - } - return count; -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - producer_ppm this = producer->child; - int width; - int height; - - // Construct a test frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - // Are we at the position expected? - producer_ppm_position( this, mlt_producer_frame( producer ) ); - - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - FILE *video = this->video; - FILE *audio = this->audio; - - // Read the video - if ( video != NULL && read_ppm_header( video, &width, &height ) == 2 ) - { - // Allocate an image - uint8_t *image = mlt_pool_alloc( width * ( height + 1 ) * 3 ); - - // Read it - fread( image, width * height * 3, 1, video ); - - // Pass the data on the frame properties - mlt_properties_set_data( properties, "image", image, width * ( height + 1 ) * 3, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", width ); - mlt_properties_set_int( properties, "height", height ); - mlt_properties_set_int( properties, "has_image", 1 ); - mlt_properties_set_int( properties, "progressive", 1 ); - mlt_properties_set_double( properties, "aspect_ratio", 1 ); - - // Push the image callback - mlt_frame_push_get_image( *frame, producer_get_image ); - } - else - { - // Push the image callback - mlt_frame_push_get_image( *frame, producer_get_image ); - } - - // Set the audio pipe - mlt_properties_set_data( properties, "audio.pipe", audio, 0, NULL, NULL ); - - // Hmm - register audio callback - mlt_frame_push_audio( *frame, producer_get_audio ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer parent ) -{ - producer_ppm this = parent->child; - if ( this->video ) - pclose( this->video ); - if ( this->audio ) - pclose( this->audio ); - free( this->command ); - parent->close = NULL; - mlt_producer_close( parent ); - free( this ); -} diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c deleted file mode 100644 index 04a518f..0000000 --- a/src/modules/core/transition_composite.c +++ /dev/null @@ -1,1342 +0,0 @@ -/* - * transition_composite.c -- compose one image over another using alpha channel - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "transition_composite.h" -#include - -#include -#include -#include -#include -#include - -typedef void ( *composite_line_fn )( uint8_t *dest, uint8_t *src, int width_src, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int softness ); - -/** Geometry struct. -*/ - -struct geometry_s -{ - struct mlt_geometry_item_s item; - int nw; // normalised width - int nh; // normalised height - int sw; // scaled width, not including consumer scale based upon w/nw - int sh; // scaled height, not including consumer scale based upon h/nh - int halign; // horizontal alignment: 0=left, 1=center, 2=right - int valign; // vertical alignment: 0=top, 1=middle, 2=bottom - int x_src; - int y_src; -}; - -/** Parse the alignment properties into the geometry. -*/ - -static int alignment_parse( char* align ) -{ - int ret = 0; - - if ( align == NULL ); - else if ( isdigit( align[ 0 ] ) ) - ret = atoi( align ); - else if ( align[ 0 ] == 'c' || align[ 0 ] == 'm' ) - ret = 1; - else if ( align[ 0 ] == 'r' || align[ 0 ] == 'b' ) - ret = 2; - - return ret; -} - -/** Calculate real geometry. -*/ - -static void geometry_calculate( mlt_transition this, struct geometry_s *output, double position ) -{ - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - mlt_geometry geometry = mlt_properties_get_data( properties, "geometries", NULL ); - int mirror_off = mlt_properties_get_int( properties, "mirror_off" ); - int repeat_off = mlt_properties_get_int( properties, "repeat_off" ); - int length = mlt_geometry_get_length( geometry ); - - // Allow wrapping - if ( !repeat_off && position >= length && length != 0 ) - { - int section = position / length; - position -= section * length; - if ( !mirror_off && section % 2 == 1 ) - position = length - position; - } - - // Fetch the key for the position - mlt_geometry_fetch( geometry, &output->item, position ); -} - -static mlt_geometry transition_parse_keys( mlt_transition this, int normalised_width, int normalised_height ) -{ - // Loop variable for property interrogation - int i = 0; - - // Get the properties of the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - // Create an empty geometries object - mlt_geometry geometry = mlt_geometry_init( ); - - // Get the in and out position - mlt_position in = mlt_transition_get_in( this ); - mlt_position out = mlt_transition_get_out( this ); - int length = out - in + 1; - double cycle = mlt_properties_get_double( properties, "cycle" ); - - // Get the new style geometry string - char *property = mlt_properties_get( properties, "geometry" ); - - // Allow a geometry repeat cycle - if ( cycle >= 1 ) - length = cycle; - else if ( cycle > 0 ) - length *= cycle; - - // Parse the geometry if we have one - mlt_geometry_parse( geometry, property, length, normalised_width, normalised_height ); - - // Check if we're using the old style geometry - if ( property == NULL ) - { - // DEPRECATED: Multiple keys for geometry information is inefficient and too rigid for - // practical use - while deprecated, it has been slightly extended too - keys can now - // be specified out of order, and can be blanked or NULL to simulate removal - - // Structure to use for parsing and inserting - struct mlt_geometry_item_s item; - - // Parse the start property - item.frame = 0; - if ( mlt_geometry_parse_item( geometry, &item, mlt_properties_get( properties, "start" ) ) == 0 ) - mlt_geometry_insert( geometry, &item ); - - // Parse the keys in between - for ( i = 0; i < mlt_properties_count( properties ); i ++ ) - { - // Get the name of the property - char *name = mlt_properties_get_name( properties, i ); - - // Check that it's valid - if ( !strncmp( name, "key[", 4 ) ) - { - // Get the value of the property - char *value = mlt_properties_get_value( properties, i ); - - // Determine the frame number - item.frame = atoi( name + 4 ); - - // Parse and add to the list - if ( mlt_geometry_parse_item( geometry, &item, value ) == 0 ) - mlt_geometry_insert( geometry, &item ); - else - fprintf( stderr, "Invalid Key - skipping %s = %s\n", name, value ); - } - } - - // Parse the end - item.frame = -1; - if ( mlt_geometry_parse_item( geometry, &item, mlt_properties_get( properties, "end" ) ) == 0 ) - mlt_geometry_insert( geometry, &item ); - } - - return geometry; -} - -/** Adjust position according to scaled size and alignment properties. -*/ - -static void alignment_calculate( struct geometry_s *geometry ) -{ - geometry->item.x += ( geometry->item.w - geometry->sw ) * geometry->halign / 2; - geometry->item.y += ( geometry->item.h - geometry->sh ) * geometry->valign / 2; -} - -/** Calculate the position for this frame. -*/ - -static int position_calculate( mlt_transition this, mlt_position position ) -{ - // Get the in and out position - mlt_position in = mlt_transition_get_in( this ); - - // Now do the calcs - return position - in; -} - -/** Calculate the field delta for this frame - position between two frames. -*/ - -static inline double delta_calculate( mlt_transition this, mlt_frame frame, mlt_position position ) -{ - // Get the in and out position - mlt_position in = mlt_transition_get_in( this ); - mlt_position out = mlt_transition_get_out( this ); - double length = out - in + 1; - - // Now do the calcs - double x = ( double )( position - in ) / length; - double y = ( double )( position + 1 - in ) / length; - - return length * ( y - x ) / 2.0; -} - -static int get_value( mlt_properties properties, const char *preferred, const char *fallback ) -{ - int value = mlt_properties_get_int( properties, preferred ); - if ( value == 0 ) - value = mlt_properties_get_int( properties, fallback ); - return value; -} - -/** A linear threshold determination function. -*/ - -static inline int32_t linearstep( int32_t edge1, int32_t edge2, int32_t a ) -{ - if ( a < edge1 ) - return 0; - - if ( a >= edge2 ) - return 0x10000; - - return ( ( a - edge1 ) << 16 ) / ( edge2 - edge1 ); -} - -/** A smoother, non-linear threshold determination function. -*/ - -static inline int32_t smoothstep( int32_t edge1, int32_t edge2, uint32_t a ) -{ - if ( a < edge1 ) - return 0; - - if ( a >= edge2 ) - return 0x10000; - - a = ( ( a - edge1 ) << 16 ) / ( edge2 - edge1 ); - - return ( ( ( a * a ) >> 16 ) * ( ( 3 << 16 ) - ( 2 * a ) ) ) >> 16; -} - -/** Load the luma map from PGM stream. -*/ - -static void luma_read_pgm( FILE *f, uint16_t **map, int *width, int *height ) -{ - uint8_t *data = NULL; - while (1) - { - char line[128]; - char comment[128]; - int i = 2; - int maxval; - int bpp; - uint16_t *p; - - line[127] = '\0'; - - // get the magic code - if ( fgets( line, 127, f ) == NULL ) - break; - - // skip comments - while ( sscanf( line, " #%s", comment ) > 0 ) - if ( fgets( line, 127, f ) == NULL ) - break; - - if ( line[0] != 'P' || line[1] != '5' ) - break; - - // skip white space and see if a new line must be fetched - for ( i = 2; i < 127 && line[i] != '\0' && isspace( line[i] ); i++ ); - if ( ( line[i] == '\0' || line[i] == '#' ) && fgets( line, 127, f ) == NULL ) - break; - - // skip comments - while ( sscanf( line, " #%s", comment ) > 0 ) - if ( fgets( line, 127, f ) == NULL ) - break; - - // get the dimensions - if ( line[0] == 'P' ) - i = sscanf( line, "P5 %d %d %d", width, height, &maxval ); - else - i = sscanf( line, "%d %d %d", width, height, &maxval ); - - // get the height value, if not yet - if ( i < 2 ) - { - if ( fgets( line, 127, f ) == NULL ) - break; - - // skip comments - while ( sscanf( line, " #%s", comment ) > 0 ) - if ( fgets( line, 127, f ) == NULL ) - break; - - i = sscanf( line, "%d", height ); - if ( i == 0 ) - break; - else - i = 2; - } - - // get the maximum gray value, if not yet - if ( i < 3 ) - { - if ( fgets( line, 127, f ) == NULL ) - break; - - // skip comments - while ( sscanf( line, " #%s", comment ) > 0 ) - if ( fgets( line, 127, f ) == NULL ) - break; - - i = sscanf( line, "%d", &maxval ); - if ( i == 0 ) - break; - } - - // determine if this is one or two bytes per pixel - bpp = maxval > 255 ? 2 : 1; - - // allocate temporary storage for the raw data - data = mlt_pool_alloc( *width * *height * bpp ); - if ( data == NULL ) - break; - - // read the raw data - if ( fread( data, *width * *height * bpp, 1, f ) != 1 ) - break; - - // allocate the luma bitmap - *map = p = (uint16_t*)mlt_pool_alloc( *width * *height * sizeof( uint16_t ) ); - if ( *map == NULL ) - break; - - // proces the raw data into the luma bitmap - for ( i = 0; i < *width * *height * bpp; i += bpp ) - { - if ( bpp == 1 ) - *p++ = data[ i ] << 8; - else - *p++ = ( data[ i ] << 8 ) + data[ i + 1 ]; - } - - break; - } - - if ( data != NULL ) - mlt_pool_release( data ); -} - -/** Generate a luma map from any YUV image. -*/ - -static void luma_read_yuv422( uint8_t *image, uint16_t **map, int width, int height ) -{ - int i; - - // allocate the luma bitmap - uint16_t *p = *map = ( uint16_t* )mlt_pool_alloc( width * height * sizeof( uint16_t ) ); - if ( *map == NULL ) - return; - - // proces the image data into the luma bitmap - for ( i = 0; i < width * height * 2; i += 2 ) - *p++ = ( image[ i ] - 16 ) * 299; // 299 = 65535 / 219 -} - -static inline int calculate_mix( uint16_t *luma, int j, int soft, int weight, int alpha ) -{ - return ( ( ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + soft, weight + soft ) ) * alpha ) >> 8; -} - -static inline uint8_t sample_mix( uint8_t dest, uint8_t src, int mix ) -{ - return ( src * mix + dest * ( ( 1 << 16 ) - mix ) ) >> 16; -} - -/** Composite a source line over a destination line -*/ - -static void composite_line_yuv( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int soft ) -{ - register int j; - register int mix; - - for ( j = 0; j < width; j ++ ) - { - mix = calculate_mix( luma, j, soft, weight, *alpha_b ++ ); - *dest = sample_mix( *dest, *src++, mix ); - dest++; - *dest = sample_mix( *dest, *src++, mix ); - dest++; - *alpha_a = ( mix >> 8 ) | *alpha_a; - alpha_a ++; - } -} - -static void composite_line_yuv_or( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int soft ) -{ - register int j; - register int mix; - - for ( j = 0; j < width; j ++ ) - { - mix = calculate_mix( luma, j, soft, weight, *alpha_b ++ | *alpha_a ); - *dest = sample_mix( *dest, *src++, mix ); - dest++; - *dest = sample_mix( *dest, *src++, mix ); - dest++; - *alpha_a ++ = mix >> 8; - } -} - -static void composite_line_yuv_and( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int soft ) -{ - register int j; - register int mix; - - for ( j = 0; j < width; j ++ ) - { - mix = calculate_mix( luma, j, soft, weight, *alpha_b ++ & *alpha_a ); - *dest = sample_mix( *dest, *src++, mix ); - dest++; - *dest = sample_mix( *dest, *src++, mix ); - dest++; - *alpha_a ++ = mix >> 8; - } -} - -static void composite_line_yuv_xor( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int soft ) -{ - register int j; - register int mix; - - for ( j = 0; j < width; j ++ ) - { - mix = calculate_mix( luma, j, soft, weight, *alpha_b ++ ^ *alpha_a ); - *dest = sample_mix( *dest, *src++, mix ); - dest++; - *dest = sample_mix( *dest, *src++, mix ); - dest++; - *alpha_a ++ = mix >> 8; - } -} - -/** Composite function. -*/ - -static int composite_yuv( uint8_t *p_dest, int width_dest, int height_dest, uint8_t *p_src, int width_src, int height_src, uint8_t *alpha_b, uint8_t *alpha_a, struct geometry_s geometry, int field, uint16_t *p_luma, int32_t softness, composite_line_fn line_fn ) -{ - int ret = 0; - int i; - int x_src = -geometry.x_src, y_src = -geometry.y_src; - int uneven_x_src = ( x_src % 2 ); - int32_t weight = ( ( 1 << 16 ) - 1 ) * ( geometry.item.mix / 100 ); - int step = ( field > -1 ) ? 2 : 1; - int bpp = 2; - int stride_src = geometry.sw * bpp; - int stride_dest = width_dest * bpp; - - // Adjust to consumer scale - int x = rint( geometry.item.x * width_dest / geometry.nw ); - int y = rint( geometry.item.y * height_dest / geometry.nh ); - int uneven_x = ( x % 2 ); - - // optimization points - no work to do - if ( width_src <= 0 || height_src <= 0 || y_src >= height_src || x_src >= width_src ) - return ret; - - if ( ( x < 0 && -x >= width_src ) || ( y < 0 && -y >= height_src ) ) - return ret; - - // cropping affects the source width - if ( x_src > 0 ) - { - width_src -= x_src; - // and it implies cropping - if ( width_src > geometry.item.w ) - width_src = geometry.item.w; - } - - // cropping affects the source height - if ( y_src > 0 ) - { - height_src -= y_src; - // and it implies cropping - if ( height_src > geometry.item.h ) - height_src = geometry.item.h; - } - - // crop overlay off the left edge of frame - if ( x < 0 ) - { - x_src = -x; - width_src -= x_src; - x = 0; - } - - // crop overlay beyond right edge of frame - if ( x + width_src > width_dest ) - width_src = width_dest - x; - - // crop overlay off the top edge of the frame - if ( y < 0 ) - { - y_src = -y; - height_src -= y_src; - y = 0; - } - - // crop overlay below bottom edge of frame - if ( y + height_src > height_dest ) - height_src = height_dest - y; - - // offset pointer into overlay buffer based on cropping - p_src += x_src * bpp + y_src * stride_src; - - // offset pointer into frame buffer based upon positive coordinates only! - p_dest += ( x < 0 ? 0 : x ) * bpp + ( y < 0 ? 0 : y ) * stride_dest; - - // offset pointer into alpha channel based upon cropping - alpha_b += x_src + y_src * stride_src / bpp; - alpha_a += x + y * stride_dest / bpp; - - // offset pointer into luma channel based upon cropping - if ( p_luma ) - p_luma += x_src + y_src * stride_src / bpp; - - // Assuming lower field first - // Special care is taken to make sure the b_frame is aligned to the correct field. - // field 0 = lower field and y should be odd (y is 0-based). - // field 1 = upper field and y should be even. - if ( ( field > -1 ) && ( y % 2 == field ) ) - { - if ( ( field == 1 && y < height_dest - 1 ) || ( field == 0 && y == 0 ) ) - p_dest += stride_dest; - else - p_dest -= stride_dest; - } - - // On the second field, use the other lines from b_frame - if ( field == 1 ) - { - p_src += stride_src; - alpha_b += stride_src / bpp; - alpha_a += stride_dest / bpp; - height_src--; - } - - stride_src *= step; - stride_dest *= step; - int alpha_b_stride = stride_src / bpp; - int alpha_a_stride = stride_dest / bpp; - - // Align chroma of source and destination - if ( uneven_x != uneven_x_src ) - { - p_src += 2; - width_src -= 2; - alpha_b += 1; - } - - // now do the compositing only to cropped extents - for ( i = 0; i < height_src; i += step ) - { - line_fn( p_dest, p_src, width_src, alpha_b, alpha_a, weight, p_luma, softness ); - - p_src += stride_src; - p_dest += stride_dest; - alpha_b += alpha_b_stride; - alpha_a += alpha_a_stride; - if ( p_luma ) - p_luma += alpha_b_stride; - } - - return ret; -} - - -/** Scale 16bit greyscale luma map using nearest neighbor. -*/ - -static inline void -scale_luma ( uint16_t *dest_buf, int dest_width, int dest_height, const uint16_t *src_buf, int src_width, int src_height, int invert ) -{ - register int i, j; - register int x_step = ( src_width << 16 ) / dest_width; - register int y_step = ( src_height << 16 ) / dest_height; - register int x, y = 0; - - for ( i = 0; i < dest_height; i++ ) - { - const uint16_t *src = src_buf + ( y >> 16 ) * src_width; - x = 0; - - for ( j = 0; j < dest_width; j++ ) - { - *dest_buf++ = src[ x >> 16 ] ^ invert; - x += x_step; - } - y += y_step; - } -} - -static uint16_t* get_luma( mlt_transition this, mlt_properties properties, int width, int height ) -{ - // The cached luma map information - int luma_width = mlt_properties_get_int( properties, "_luma.width" ); - int luma_height = mlt_properties_get_int( properties, "_luma.height" ); - uint16_t *luma_bitmap = mlt_properties_get_data( properties, "_luma.bitmap", NULL ); - int invert = mlt_properties_get_int( properties, "luma_invert" ); - - // If the filename property changed, reload the map - char *resource = mlt_properties_get( properties, "luma" ); - - char temp[ 512 ]; - - if ( luma_width == 0 || luma_height == 0 ) - { - luma_width = width; - luma_height = height; - } - - if ( resource && resource[0] && strchr( resource, '%' ) ) - { - // TODO: Clean up quick and dirty compressed/existence check - FILE *test; - sprintf( temp, "%s/lumas/%s/%s", mlt_environment( "MLT_DATA" ), mlt_environment( "MLT_NORMALISATION" ), strchr( resource, '%' ) + 1 ); - test = fopen( temp, "r" ); - if ( test == NULL ) - strcat( temp, ".png" ); - else - fclose( test ); - resource = temp; - } - - if ( resource && resource[0] ) - { - char *old_luma = mlt_properties_get( properties, "_luma" ); - int old_invert = mlt_properties_get_int( properties, "_luma_invert" ); - - if ( invert != old_invert || ( old_luma && old_luma[0] && strcmp( resource, old_luma ) ) ) - { - mlt_properties_set_data( properties, "_luma.orig_bitmap", NULL, 0, NULL, NULL ); - luma_bitmap = NULL; - } - } - else { - char *old_luma = mlt_properties_get( properties, "_luma" ); - if ( old_luma && old_luma[0] ) - { - mlt_properties_set_data( properties, "_luma.orig_bitmap", NULL, 0, NULL, NULL ); - luma_bitmap = NULL; - mlt_properties_set( properties, "_luma", NULL); - } - } - - if ( resource && resource[0] && ( luma_bitmap == NULL || luma_width != width || luma_height != height ) ) - { - uint16_t *orig_bitmap = mlt_properties_get_data( properties, "_luma.orig_bitmap", NULL ); - luma_width = mlt_properties_get_int( properties, "_luma.orig_width" ); - luma_height = mlt_properties_get_int( properties, "_luma.orig_height" ); - - // Load the original luma once - if ( orig_bitmap == NULL ) - { - char *extension = strrchr( resource, '.' ); - - // See if it is a PGM - if ( extension != NULL && strcmp( extension, ".pgm" ) == 0 ) - { - // Open PGM - FILE *f = fopen( resource, "r" ); - if ( f != NULL ) - { - // Load from PGM - luma_read_pgm( f, &orig_bitmap, &luma_width, &luma_height ); - fclose( f ); - - // Remember the original size for subsequent scaling - mlt_properties_set_data( properties, "_luma.orig_bitmap", orig_bitmap, luma_width * luma_height * 2, mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "_luma.orig_width", luma_width ); - mlt_properties_set_int( properties, "_luma.orig_height", luma_height ); - } - } - else - { - // Get the factory producer service - char *factory = mlt_properties_get( properties, "factory" ); - - // Create the producer - mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( this ) ); - mlt_producer producer = mlt_factory_producer( profile, factory, resource ); - - // If we have one - if ( producer != NULL ) - { - // Get the producer properties - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Ensure that we loop - mlt_properties_set( producer_properties, "eof", "loop" ); - - // Now pass all producer. properties on the transition down - mlt_properties_pass( producer_properties, properties, "luma." ); - - // We will get the alpha frame from the producer - mlt_frame luma_frame = NULL; - - // Get the luma frame - if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &luma_frame, 0 ) == 0 ) - { - uint8_t *luma_image; - mlt_image_format luma_format = mlt_image_yuv422; - - // Get image from the luma producer - mlt_properties_set( MLT_FRAME_PROPERTIES( luma_frame ), "rescale.interp", "none" ); - mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 ); - - // Generate the luma map - if ( luma_image != NULL && luma_format == mlt_image_yuv422 ) - luma_read_yuv422( luma_image, &orig_bitmap, luma_width, luma_height ); - - // Remember the original size for subsequent scaling - mlt_properties_set_data( properties, "_luma.orig_bitmap", orig_bitmap, luma_width * luma_height * 2, mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "_luma.orig_width", luma_width ); - mlt_properties_set_int( properties, "_luma.orig_height", luma_height ); - - // Cleanup the luma frame - mlt_frame_close( luma_frame ); - } - - // Cleanup the luma producer - mlt_producer_close( producer ); - } - } - } - // Scale luma map - luma_bitmap = mlt_pool_alloc( width * height * sizeof( uint16_t ) ); - scale_luma( luma_bitmap, width, height, orig_bitmap, luma_width, luma_height, invert * ( ( 1 << 16 ) - 1 ) ); - - // Remember the scaled luma size to prevent unnecessary scaling - mlt_properties_set_int( properties, "_luma.width", width ); - mlt_properties_set_int( properties, "_luma.height", height ); - mlt_properties_set_data( properties, "_luma.bitmap", luma_bitmap, width * height * 2, mlt_pool_release, NULL ); - mlt_properties_set( properties, "_luma", resource ); - mlt_properties_set_int( properties, "_luma_invert", invert ); - } - return luma_bitmap; -} - -/** Get the properly sized image from b_frame. -*/ - -static int get_b_frame_image( mlt_transition this, mlt_frame b_frame, uint8_t **image, int *width, int *height, struct geometry_s *geometry ) -{ - int ret = 0; - mlt_image_format format = mlt_image_yuv422; - - // Get the properties objects - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - uint8_t resize_alpha = mlt_properties_get_int( b_props, "resize_alpha" ); - - // Do not scale if we are cropping - the compositing rectangle can crop the b image - // TODO: Use the animatable w and h of the crop geometry to scale independently of crop rectangle - if ( mlt_properties_get( properties, "crop" ) ) - { - int real_width = get_value( b_props, "real_width", "width" ); - int real_height = get_value( b_props, "real_height", "height" ); - double input_ar = mlt_properties_get_double( b_props, "aspect_ratio" ); - double consumer_ar = mlt_properties_get_double( b_props, "consumer_aspect_ratio" ); - double background_ar = mlt_properties_get_double( b_props, "output_ratio" ); - double output_ar = background_ar != 0.0 ? background_ar : consumer_ar; - int scaled_width = rint( ( input_ar == 0.0 ? output_ar : input_ar ) / output_ar * real_width ); - int scaled_height = real_height; - geometry->sw = scaled_width; - geometry->sh = scaled_height; - } - // Normalise aspect ratios and scale preserving aspect ratio - else if ( mlt_properties_get_int( properties, "aligned" ) && mlt_properties_get_int( properties, "distort" ) == 0 && mlt_properties_get_int( b_props, "distort" ) == 0 && geometry->item.distort == 0 ) - { - // Adjust b_frame pixel aspect - int normalised_width = geometry->item.w; - int normalised_height = geometry->item.h; - int real_width = get_value( b_props, "real_width", "width" ); - int real_height = get_value( b_props, "real_height", "height" ); - double input_ar = mlt_properties_get_double( b_props, "aspect_ratio" ); - double consumer_ar = mlt_properties_get_double( b_props, "consumer_aspect_ratio" ); - double background_ar = mlt_properties_get_double( b_props, "output_ratio" ); - double output_ar = background_ar != 0.0 ? background_ar : consumer_ar; - int scaled_width = rint( ( input_ar == 0.0 ? output_ar : input_ar ) / output_ar * real_width ); - int scaled_height = real_height; -// fprintf(stderr, "%s: scaled %dx%d norm %dx%d real %dx%d output_ar %f => %f\n", __FILE__, -// scaled_width, scaled_height, normalised_width, normalised_height, real_width, real_height, -// background_ar, output_ar); - - // Now ensure that our images fit in the normalised frame - if ( scaled_width > normalised_width ) - { - scaled_height = rint( scaled_height * normalised_width / scaled_width ); - scaled_width = normalised_width; - } - if ( scaled_height > normalised_height ) - { - scaled_width = rint( scaled_width * normalised_height / scaled_height ); - scaled_height = normalised_height; - } - - // Honour the fill request - this will scale the image to fill width or height while maintaining a/r - // ????: Shouln't this be the default behaviour? - if ( mlt_properties_get_int( properties, "fill" ) && scaled_width > 0 && scaled_height > 0 ) - { - if ( scaled_height < normalised_height && scaled_width * normalised_height / scaled_height <= normalised_width ) - { - scaled_width = rint( scaled_width * normalised_height / scaled_height ); - scaled_height = normalised_height; - } - else if ( scaled_width < normalised_width && scaled_height * normalised_width / scaled_width < normalised_height ) - { - scaled_height = rint( scaled_height * normalised_width / scaled_width ); - scaled_width = normalised_width; - } - } - - // Save the new scaled dimensions - geometry->sw = scaled_width; - geometry->sh = scaled_height; - } - else - { - geometry->sw = geometry->item.w; - geometry->sh = geometry->item.h; - } - - // We want to ensure that we bypass resize now... - if ( resize_alpha == 0 ) - mlt_properties_set_int( b_props, "distort", mlt_properties_get_int( properties, "distort" ) ); - - // If we're not aligned, we want a non-transparent background - if ( mlt_properties_get_int( properties, "aligned" ) == 0 ) - mlt_properties_set_int( b_props, "resize_alpha", 255 ); - - // Take into consideration alignment for optimisation (titles are a special case) - if ( !mlt_properties_get_int( properties, "titles" ) && - mlt_properties_get( properties, "crop" ) == NULL ) - alignment_calculate( geometry ); - - // Adjust to consumer scale - *width = rint( geometry->sw * *width / geometry->nw ); - *height = rint( geometry->sh * *height / geometry->nh ); -// fprintf(stderr, "%s: scaled %dx%d norm %dx%d resize %dx%d\n", __FILE__, -// geometry->sw, geometry->sh, geometry->nw, geometry->nh, *width, *height); - - ret = mlt_frame_get_image( b_frame, image, &format, width, height, 1 ); - - // Set the frame back - mlt_properties_set_int( b_props, "resize_alpha", resize_alpha ); - - return ret && image != NULL; -} - -static void crop_calculate( mlt_transition this, mlt_properties properties, struct geometry_s *result, double position ) -{ - // Initialize panning info - result->x_src = 0; - result->y_src = 0; - if ( mlt_properties_get( properties, "crop" ) ) - { - mlt_geometry crop = mlt_properties_get_data( properties, "crop_geometry", NULL ); - if ( !crop ) - { - crop = mlt_geometry_init(); - mlt_position in = mlt_transition_get_in( this ); - mlt_position out = mlt_transition_get_out( this ); - int length = out - in + 1; - double cycle = mlt_properties_get_double( properties, "cycle" ); - - // Allow a geometry repeat cycle - if ( cycle >= 1 ) - length = cycle; - else if ( cycle > 0 ) - length *= cycle; - mlt_geometry_parse( crop, mlt_properties_get( properties, "crop" ), length, result->sw, result->sh ); - mlt_properties_set_data( properties, "crop_geometry", crop, 0, (mlt_destructor)mlt_geometry_close, NULL ); - } - - // Repeat processing - int length = mlt_geometry_get_length( crop ); - int mirror_off = mlt_properties_get_int( properties, "mirror_off" ); - int repeat_off = mlt_properties_get_int( properties, "repeat_off" ); - if ( !repeat_off && position >= length && length != 0 ) - { - int section = position / length; - position -= section * length; - if ( !mirror_off && section % 2 == 1 ) - position = length - position; - } - - // Compute the pan - struct mlt_geometry_item_s crop_item; - mlt_geometry_fetch( crop, &crop_item, position ); - result->x_src = rint( crop_item.x ); - result->y_src = rint( crop_item.y ); - } -} - -static mlt_geometry composite_calculate( mlt_transition this, struct geometry_s *result, mlt_frame a_frame, double position ) -{ - // Get the properties from the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - // Get the properties from the frame - mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); - - // Structures for geometry - mlt_geometry start = mlt_properties_get_data( properties, "geometries", NULL ); - - // Obtain the normalised width and height from the a_frame - int normalised_width = mlt_properties_get_int( a_props, "normalised_width" ); - int normalised_height = mlt_properties_get_int( a_props, "normalised_height" ); - - char *name = mlt_properties_get( properties, "_unique_id" ); - char key[ 256 ]; - - sprintf( key, "%s.in", name ); - if ( mlt_properties_get( a_props, key ) ) - { - sscanf( mlt_properties_get( a_props, key ), "%f,%f,%f,%f,%f,%d,%d", &result->item.x, &result->item.y, &result->item.w, &result->item.h, &result->item.mix, &result->nw, &result->nh ); - } - else - { - // Now parse the geometries - if ( start == NULL ) - { - // Parse the transitions properties - start = transition_parse_keys( this, normalised_width, normalised_height ); - - // Assign to properties to ensure we get destroyed - mlt_properties_set_data( properties, "geometries", start, 0, ( mlt_destructor )mlt_geometry_close, NULL ); - } - else - { - int length = mlt_transition_get_out( this ) - mlt_transition_get_in( this ) + 1; - double cycle = mlt_properties_get_double( properties, "cycle" ); - if ( cycle > 1 ) - length = cycle; - else if ( cycle > 0 ) - length *= cycle; - mlt_geometry_refresh( start, mlt_properties_get( properties, "geometry" ), length, normalised_width, normalised_height ); - } - - // Do the calculation - geometry_calculate( this, result, position ); - - // Assign normalised info - result->nw = normalised_width; - result->nh = normalised_height; - } - - // Now parse the alignment - result->halign = alignment_parse( mlt_properties_get( properties, "halign" ) ); - result->valign = alignment_parse( mlt_properties_get( properties, "valign" ) ); - - crop_calculate( this, properties, result, position ); - - return start; -} - -mlt_frame composite_copy_region( mlt_transition this, mlt_frame a_frame, mlt_position frame_position ) -{ - // Create a frame to return - mlt_frame b_frame = mlt_frame_init( MLT_TRANSITION_SERVICE( this ) ); - - // Get the properties of the a frame - mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); - - // Get the properties of the b frame - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - - // Get the position - int position = position_calculate( this, frame_position ); - - // Get the unique id of the transition - char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( this ), "_unique_id" ); - char key[ 256 ]; - - // Destination image - uint8_t *dest = NULL; - - // Get the image and dimensions - uint8_t *image = mlt_properties_get_data( a_props, "image", NULL ); - int width = mlt_properties_get_int( a_props, "width" ); - int height = mlt_properties_get_int( a_props, "height" ); - int format = mlt_properties_get_int( a_props, "format" ); - - // Pointers for copy operation - uint8_t *p; - - // Coordinates - int w = 0; - int h = 0; - int x = 0; - int y = 0; - - int ss = 0; - int ds = 0; - - // Will need to know region to copy - struct geometry_s result; - - // Calculate the region now - composite_calculate( this, &result, a_frame, position ); - - // Need to scale down to actual dimensions - x = rint( result.item.x * width / result.nw ); - y = rint( result.item.y * height / result.nh ); - w = rint( result.item.w * width / result.nw ); - h = rint( result.item.h * height / result.nh ); - - if ( x % 2 ) - { - x --; - w ++; - } - - // Store the key - sprintf( key, "%s.in=%d,%d,%d,%d,%f,%d,%d", name, x, y, w, h, result.item.mix, width, height ); - mlt_properties_parse( a_props, key ); - sprintf( key, "%s.out=%d,%d,%d,%d,%f,%d,%d", name, x, y, w, h, result.item.mix, width, height ); - mlt_properties_parse( a_props, key ); - - ds = w * 2; - ss = width * 2; - - // Now we need to create a new destination image - dest = mlt_pool_alloc( w * h * 2 ); - - // Assign to the new frame - mlt_properties_set_data( b_props, "image", dest, w * h * 2, mlt_pool_release, NULL ); - mlt_properties_set_int( b_props, "width", w ); - mlt_properties_set_int( b_props, "height", h ); - mlt_properties_set_int( b_props, "format", format ); - - if ( y < 0 ) - { - dest += ( ds * -y ); - h += y; - y = 0; - } - - if ( y + h > height ) - h -= ( y + h - height ); - - if ( x < 0 ) - { - dest += -x * 2; - w += x; - x = 0; - } - - if ( w > 0 && h > 0 ) - { - // Copy the region of the image - p = image + y * ss + x * 2; - - while ( h -- ) - { - memcpy( dest, p, w * 2 ); - dest += ds; - p += ss; - } - } - - // Assign this position to the b frame - mlt_frame_set_position( b_frame, frame_position ); - mlt_properties_set_int( b_props, "distort", 1 ); - - // Return the frame - return b_frame; -} - -/** Get the image. -*/ - -static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the b frame from the stack - mlt_frame b_frame = mlt_frame_pop_frame( a_frame ); - - // Get the transition from the a frame - mlt_transition this = mlt_frame_pop_service( a_frame ); - - // Get in and out - double position = mlt_deque_pop_back_double( MLT_FRAME_IMAGE_STACK( a_frame ) ); - int out = mlt_frame_pop_service_int( a_frame ); - int in = mlt_frame_pop_service_int( a_frame ); - - // Get the properties from the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - // TODO: clean up always_active behaviour - if ( mlt_properties_get_int( properties, "always_active" ) ) - { - mlt_events_block( properties, properties ); - mlt_properties_set_int( properties, "in", in ); - mlt_properties_set_int( properties, "out", out ); - mlt_events_unblock( properties, properties ); - } - - // This compositer is yuv422 only - *format = mlt_image_yuv422; - - if ( b_frame != NULL ) - { - // Get the properties of the a frame - mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); - - // Get the properties of the b frame - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - - // Structures for geometry - struct geometry_s result; - - // Calculate the position - double delta = delta_calculate( this, a_frame, position ); - - // Get the image from the b frame - uint8_t *image_b = NULL; - int width_b = *width; - int height_b = *height; - - // Vars for alphas - uint8_t *alpha_a = NULL; - uint8_t *alpha_b = NULL; - - // Composites always need scaling... defaulting to lowest - const char *rescale = mlt_properties_get( a_props, "rescale.interp" ); - if ( rescale == NULL || !strcmp( rescale, "none" ) ) - rescale = "nearest"; - mlt_properties_set( a_props, "rescale.interp", rescale ); - mlt_properties_set( b_props, "rescale.interp", rescale ); - - // Do the calculation - // NB: Locks needed here since the properties are being modified - mlt_service_lock( MLT_TRANSITION_SERVICE( this ) ); - composite_calculate( this, &result, a_frame, position ); - mlt_service_unlock( MLT_TRANSITION_SERVICE( this ) ); - - // Since we are the consumer of the b_frame, we must pass along these - // consumer properties from the a_frame - mlt_properties_set_int( b_props, "consumer_deinterlace", mlt_properties_get_int( a_props, "consumer_deinterlace" ) || mlt_properties_get_int( properties, "deinterlace" ) ); - mlt_properties_set( b_props, "consumer_deinterlace_method", mlt_properties_get( a_props, "consumer_deinterlace_method" ) ); - mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - - // TODO: Dangerous/temporary optimisation - if nothing to do, then do nothing - if ( mlt_properties_get_int( properties, "no_alpha" ) && - result.item.x == 0 && result.item.y == 0 && result.item.w == *width && result.item.h == *height && result.item.mix == 100 ) - { - mlt_frame_get_image( b_frame, image, format, width, height, 1 ); - if ( !mlt_frame_is_test_card( a_frame ) ) - mlt_frame_replace_image( a_frame, *image, *format, *width, *height ); - return 0; - } - - if ( a_frame == b_frame ) - { - double aspect_ratio = mlt_frame_get_aspect_ratio( b_frame ); - get_b_frame_image( this, b_frame, &image_b, &width_b, &height_b, &result ); - alpha_b = mlt_frame_get_alpha_mask( b_frame ); - mlt_properties_set_double( a_props, "aspect_ratio", aspect_ratio ); - } - - // Get the image from the a frame - mlt_frame_get_image( a_frame, image, format, width, height, 1 ); - alpha_a = mlt_frame_get_alpha_mask( a_frame ); - - // Optimisation - no compositing required - if ( result.item.mix == 0 || ( result.item.w == 0 && result.item.h == 0 ) ) - return 0; - - // Need to keep the width/height of the a_frame on the b_frame for titling - if ( mlt_properties_get( a_props, "dest_width" ) == NULL ) - { - mlt_properties_set_int( a_props, "dest_width", *width ); - mlt_properties_set_int( a_props, "dest_height", *height ); - mlt_properties_set_int( b_props, "dest_width", *width ); - mlt_properties_set_int( b_props, "dest_height", *height ); - } - else - { - mlt_properties_set_int( b_props, "dest_width", mlt_properties_get_int( a_props, "dest_width" ) ); - mlt_properties_set_int( b_props, "dest_height", mlt_properties_get_int( a_props, "dest_height" ) ); - } - - // Special case for titling... - if ( mlt_properties_get_int( properties, "titles" ) ) - { - if ( mlt_properties_get( b_props, "rescale.interp" ) == NULL ) - mlt_properties_set( b_props, "rescale.interp", "hyper" ); - width_b = mlt_properties_get_int( a_props, "dest_width" ); - height_b = mlt_properties_get_int( a_props, "dest_height" ); - } - - if ( *image != image_b && ( image_b != NULL || get_b_frame_image( this, b_frame, &image_b, &width_b, &height_b, &result ) == 0 ) ) - { - uint8_t *dest = *image; - uint8_t *src = image_b; - int progressive = - mlt_properties_get_int( a_props, "consumer_deinterlace" ) || - mlt_properties_get_int( properties, "progressive" ); - int field; - - int32_t luma_softness = mlt_properties_get_double( properties, "softness" ) * ( 1 << 16 ); - uint16_t *luma_bitmap = get_luma( this, properties, width_b, height_b ); - char *operator = mlt_properties_get( properties, "operator" ); - - alpha_b = alpha_b == NULL ? mlt_frame_get_alpha_mask( b_frame ) : alpha_b; - - composite_line_fn line_fn = composite_line_yuv; - - // Replacement and override - if ( operator != NULL ) - { - if ( !strcmp( operator, "or" ) ) - line_fn = composite_line_yuv_or; - if ( !strcmp( operator, "and" ) ) - line_fn = composite_line_yuv_and; - if ( !strcmp( operator, "xor" ) ) - line_fn = composite_line_yuv_xor; - } - - // Allow the user to completely obliterate the alpha channels from both frames - if ( mlt_properties_get( properties, "alpha_a" ) ) - memset( alpha_a, mlt_properties_get_int( properties, "alpha_a" ), *width * *height ); - - if ( mlt_properties_get( properties, "alpha_b" ) ) - memset( alpha_b, mlt_properties_get_int( properties, "alpha_b" ), width_b * height_b ); - - for ( field = 0; field < ( progressive ? 1 : 2 ); field++ ) - { - // Assume lower field (0) first - double field_position = position + field * delta; - - // Do the calculation if we need to - // NB: Locks needed here since the properties are being modified - mlt_service_lock( MLT_TRANSITION_SERVICE( this ) ); - composite_calculate( this, &result, a_frame, field_position ); - mlt_service_unlock( MLT_TRANSITION_SERVICE( this ) ); - - if ( mlt_properties_get_int( properties, "titles" ) ) - { - result.item.w = rint( *width * ( result.item.w / result.nw ) ); - result.nw = result.item.w; - result.item.h = rint( *height * ( result.item.h / result.nh ) ); - result.nh = *height; - result.sw = width_b; - result.sh = height_b; - } - - // Enforce cropping - if ( mlt_properties_get( properties, "crop" ) ) - { - if ( result.x_src == 0 ) - width_b = width_b > result.item.w ? result.item.w : width_b; - if ( result.y_src == 0 ) - height_b = height_b > result.item.h ? result.item.h : height_b; - } - else - { - // Otherwise, align - alignment_calculate( &result ); - } - - // Composite the b_frame on the a_frame - composite_yuv( dest, *width, *height, src, width_b, height_b, alpha_b, alpha_a, result, progressive ? -1 : field, luma_bitmap, luma_softness, line_fn ); - } - } - } - else - { - mlt_frame_get_image( a_frame, image, format, width, height, 1 ); - } - - return 0; -} - -/** Composition transition processing. -*/ - -static mlt_frame composite_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame ) -{ - // UGH - this is a TODO - find a more reliable means of obtaining in/out for the always_active case - if ( mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "always_active" ) == 0 ) - { - mlt_frame_push_service_int( a_frame, mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "in" ) ); - mlt_frame_push_service_int( a_frame, mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "out" ) ); - mlt_deque_push_back_double( MLT_FRAME_IMAGE_STACK( a_frame ), position_calculate( this, mlt_frame_get_position( a_frame ) ) ); - } - else - { - mlt_properties props = mlt_properties_get_data( MLT_FRAME_PROPERTIES( b_frame ), "_producer", NULL ); - mlt_frame_push_service_int( a_frame, mlt_properties_get_int( props, "in" ) ); - mlt_frame_push_service_int( a_frame, mlt_properties_get_int( props, "out" ) ); - mlt_deque_push_back_double( MLT_FRAME_IMAGE_STACK( a_frame ), mlt_properties_get_int( props, "_frame" ) - mlt_properties_get_int( props, "in" ) ); - } - - mlt_frame_push_service( a_frame, this ); - mlt_frame_push_frame( a_frame, b_frame ); - mlt_frame_push_get_image( a_frame, transition_get_image ); - return a_frame; -} - -/** Constructor for the filter. -*/ - -mlt_transition transition_composite_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_transition this = calloc( sizeof( struct mlt_transition_s ), 1 ); - if ( this != NULL && mlt_transition_init( this, NULL ) == 0 ) - { - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - this->process = composite_process; - - // Default starting motion and zoom - mlt_properties_set( properties, "start", arg != NULL ? arg : "0,0:100%x100%" ); - - // Default factory - mlt_properties_set( properties, "factory", "fezzik" ); - - // Use alignment (and hence alpha of b frame) - mlt_properties_set_int( properties, "aligned", 1 ); - - // Inform apps and framework that this is a video only transition - mlt_properties_set_int( properties, "_transition_type", 1 ); - } - return this; -} diff --git a/src/modules/core/transition_composite.h b/src/modules/core/transition_composite.h deleted file mode 100644 index 6523b95..0000000 --- a/src/modules/core/transition_composite.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * transition_composite.h -- compose one image over another using alpha channel - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _TRANSITION_COMPOSITE_H_ -#define _TRANSITION_COMPOSITE_H_ - -#include - -extern mlt_transition transition_composite_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -// Courtesy functionality - allows regionalised filtering -extern mlt_frame composite_copy_region( mlt_transition, mlt_frame, mlt_position ); - -#endif diff --git a/src/modules/core/transition_luma.c b/src/modules/core/transition_luma.c deleted file mode 100644 index f08d84f..0000000 --- a/src/modules/core/transition_luma.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * transition_luma.c -- a generic dissolve/wipe processor - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * Adapted from Kino Plugin Timfx, which is - * Copyright (C) 2002 Timothy M. Shead - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include -#include -#include -#include -#include - -/** Calculate the position for this frame. -*/ - -static float position_calculate( mlt_transition this, mlt_frame frame ) -{ - // Get the in and out position - mlt_position in = mlt_transition_get_in( this ); - mlt_position out = mlt_transition_get_out( this ); - - // Get the position of the frame - char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( this ), "_unique_id" ); - mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( frame ), name ); - - // Now do the calcs - return ( float )( position - in ) / ( float )( out - in + 1 ); -} - -/** Calculate the field delta for this frame - position between two frames. -*/ - -static float delta_calculate( mlt_transition this, mlt_frame frame ) -{ - // Get the in and out position - mlt_position in = mlt_transition_get_in( this ); - mlt_position out = mlt_transition_get_out( this ); - - // Get the position of the frame - mlt_position position = mlt_frame_get_position( frame ); - - // Now do the calcs - float x = ( float )( position - in ) / ( float )( out - in + 1 ); - float y = ( float )( position + 1 - in ) / ( float )( out - in + 1 ); - - return ( y - x ) / 2.0; -} - -static inline int dissolve_yuv( mlt_frame this, mlt_frame that, float weight, int width, int height ) -{ - int ret = 0; - int width_src = width, height_src = height; - mlt_image_format format = mlt_image_yuv422; - uint8_t *p_src, *p_dest; - uint8_t *p, *q; - uint8_t *limit; - uint8_t *alpha_src; - uint8_t *alpha_dst; - - int32_t weigh = weight * ( 1 << 16 ); - int32_t weigh_complement = ( 1 - weight ) * ( 1 << 16 ); - - if ( mlt_properties_get( &this->parent, "distort" ) ) - mlt_properties_set( &that->parent, "distort", mlt_properties_get( &this->parent, "distort" ) ); - mlt_properties_set_int( &that->parent, "consumer_deinterlace", mlt_properties_get_int( &this->parent, "consumer_deinterlace" ) ); - mlt_frame_get_image( this, &p_dest, &format, &width, &height, 1 ); - alpha_dst = mlt_frame_get_alpha_mask( this ); - mlt_frame_get_image( that, &p_src, &format, &width_src, &height_src, 0 ); - alpha_src = mlt_frame_get_alpha_mask( that ); - - // Pick the lesser of two evils ;-) - width_src = width_src > width ? width : width_src; - height_src = height_src > height ? height : height_src; - - p = p_dest; - q = alpha_dst; - limit = p_dest + height_src * width_src * 2; - - while ( p < limit ) - { - *p_dest++ = ( *p_src++ * weigh + *p++ * weigh_complement ) >> 16; - *p_dest++ = ( *p_src++ * weigh + *p++ * weigh_complement ) >> 16; - *alpha_dst++ = ( *alpha_src++ * weigh + *q++ * weigh_complement ) >> 16; - } - - return ret; -} - -// image processing functions - -static inline int32_t smoothstep( int32_t edge1, int32_t edge2, uint32_t a ) -{ - if ( a < edge1 ) - return 0; - - if ( a >= edge2 ) - return 0x10000; - - a = ( ( a - edge1 ) << 16 ) / ( edge2 - edge1 ); - - return ( ( ( a * a ) >> 16 ) * ( ( 3 << 16 ) - ( 2 * a ) ) ) >> 16; -} - -/** powerful stuff - - \param field_order -1 = progressive, 0 = lower field first, 1 = top field first -*/ -static void luma_composite( mlt_frame a_frame, mlt_frame b_frame, int luma_width, int luma_height, - uint16_t *luma_bitmap, float pos, float frame_delta, float softness, int field_order, - int *width, int *height ) -{ - int width_src = *width, height_src = *height; - int width_dest = *width, height_dest = *height; - mlt_image_format format_src = mlt_image_yuv422, format_dest = mlt_image_yuv422; - uint8_t *p_src, *p_dest; - int i, j; - int stride_src; - int stride_dest; - uint16_t weight = 0; - - format_src = mlt_image_yuv422; - format_dest = mlt_image_yuv422; - - if ( mlt_properties_get( &a_frame->parent, "distort" ) ) - mlt_properties_set( &b_frame->parent, "distort", mlt_properties_get( &a_frame->parent, "distort" ) ); - mlt_properties_set_int( &b_frame->parent, "consumer_deinterlace", mlt_properties_get_int( &a_frame->parent, "consumer_deinterlace" ) ); - mlt_frame_get_image( a_frame, &p_dest, &format_dest, &width_dest, &height_dest, 1 ); - mlt_frame_get_image( b_frame, &p_src, &format_src, &width_src, &height_src, 0 ); - - if ( *width == 0 || *height == 0 ) - return; - - // Pick the lesser of two evils ;-) - width_src = width_src > width_dest ? width_dest : width_src; - height_src = height_src > height_dest ? height_dest : height_src; - - stride_src = width_src * 2; - stride_dest = width_dest * 2; - - // Offset the position based on which field we're looking at ... - int32_t field_pos[ 2 ]; - field_pos[ 0 ] = ( pos + ( ( field_order == 0 ? 1 : 0 ) * frame_delta * 0.5 ) ) * ( 1 << 16 ) * ( 1.0 + softness ); - field_pos[ 1 ] = ( pos + ( ( field_order == 0 ? 0 : 1 ) * frame_delta * 0.5 ) ) * ( 1 << 16 ) * ( 1.0 + softness ); - - register uint8_t *p; - register uint8_t *q; - register uint8_t *o; - uint16_t *l; - - uint32_t value; - - int32_t x_diff = ( luma_width << 16 ) / *width; - int32_t y_diff = ( luma_height << 16 ) / *height; - int32_t x_offset = 0; - int32_t y_offset = 0; - uint8_t *p_row; - uint8_t *q_row; - - int32_t i_softness = softness * ( 1 << 16 ); - - int field_count = field_order < 0 ? 1 : 2; - int field_stride_src = field_count * stride_src; - int field_stride_dest = field_count * stride_dest; - int field = 0; - - // composite using luma map - while ( field < field_count ) - { - p_row = p_src + field * stride_src; - q_row = p_dest + field * stride_dest; - y_offset = field << 16; - i = field; - - while ( i < height_src ) - { - p = p_row; - q = q_row; - o = q; - l = luma_bitmap + ( y_offset >> 16 ) * ( luma_width * field_count ); - x_offset = 0; - j = width_src; - - while( j -- ) - { - weight = l[ x_offset >> 16 ]; - value = smoothstep( weight, i_softness + weight, field_pos[ field ] ); - *o ++ = ( *p ++ * value + *q++ * ( ( 1 << 16 ) - value ) ) >> 16; - *o ++ = ( *p ++ * value + *q++ * ( ( 1 << 16 ) - value ) ) >> 16; - x_offset += x_diff; - } - - y_offset += y_diff; - i += field_count; - p_row += field_stride_src; - q_row += field_stride_dest; - } - - field ++; - } -} - -/** Load the luma map from PGM stream. -*/ - -static void luma_read_pgm( FILE *f, uint16_t **map, int *width, int *height ) -{ - uint8_t *data = NULL; - while (1) - { - char line[128]; - char comment[128]; - int i = 2; - int maxval; - int bpp; - uint16_t *p; - - line[127] = '\0'; - - // get the magic code - if ( fgets( line, 127, f ) == NULL ) - break; - - // skip comments - while ( sscanf( line, " #%s", comment ) > 0 ) - if ( fgets( line, 127, f ) == NULL ) - break; - - if ( line[0] != 'P' || line[1] != '5' ) - break; - - // skip white space and see if a new line must be fetched - for ( i = 2; i < 127 && line[i] != '\0' && isspace( line[i] ); i++ ); - if ( ( line[i] == '\0' || line[i] == '#' ) && fgets( line, 127, f ) == NULL ) - break; - - // skip comments - while ( sscanf( line, " #%s", comment ) > 0 ) - if ( fgets( line, 127, f ) == NULL ) - break; - - // get the dimensions - if ( line[0] == 'P' ) - i = sscanf( line, "P5 %d %d %d", width, height, &maxval ); - else - i = sscanf( line, "%d %d %d", width, height, &maxval ); - - // get the height value, if not yet - if ( i < 2 ) - { - if ( fgets( line, 127, f ) == NULL ) - break; - - // skip comments - while ( sscanf( line, " #%s", comment ) > 0 ) - if ( fgets( line, 127, f ) == NULL ) - break; - - i = sscanf( line, "%d", height ); - if ( i == 0 ) - break; - else - i = 2; - } - - // get the maximum gray value, if not yet - if ( i < 3 ) - { - if ( fgets( line, 127, f ) == NULL ) - break; - - // skip comments - while ( sscanf( line, " #%s", comment ) > 0 ) - if ( fgets( line, 127, f ) == NULL ) - break; - - i = sscanf( line, "%d", &maxval ); - if ( i == 0 ) - break; - } - - // determine if this is one or two bytes per pixel - bpp = maxval > 255 ? 2 : 1; - - // allocate temporary storage for the raw data - data = mlt_pool_alloc( *width * *height * bpp ); - if ( data == NULL ) - break; - - // read the raw data - if ( fread( data, *width * *height * bpp, 1, f ) != 1 ) - break; - - // allocate the luma bitmap - *map = p = (uint16_t*)mlt_pool_alloc( *width * *height * sizeof( uint16_t ) ); - if ( *map == NULL ) - break; - - // proces the raw data into the luma bitmap - for ( i = 0; i < *width * *height * bpp; i += bpp ) - { - if ( bpp == 1 ) - *p++ = data[ i ] << 8; - else - *p++ = ( data[ i ] << 8 ) + data[ i+1 ]; - } - - break; - } - - if ( data != NULL ) - mlt_pool_release( data ); -} - -/** Generate a luma map from an RGB image. -*/ - -static void luma_read_yuv422( uint8_t *image, uint16_t **map, int width, int height ) -{ - int i; - int size = width * height * 2; - - // allocate the luma bitmap - uint16_t *p = *map = ( uint16_t* )mlt_pool_alloc( width * height * sizeof( uint16_t ) ); - if ( *map == NULL ) - return; - - // proces the image data into the luma bitmap - for ( i = 0; i < size; i += 2 ) - *p++ = ( image[ i ] - 16 ) * 299; // 299 = 65535 / 219 -} - -/** Generate a luma map from a YUV image. -*/ -static void luma_read_rgb24( uint8_t *image, uint16_t **map, int width, int height ) -{ -} - -/** Get the image. -*/ - -static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the b frame from the stack - mlt_frame b_frame = mlt_frame_pop_frame( a_frame ); - - // Get the transition object - mlt_transition transition = mlt_frame_pop_service( a_frame ); - - // Get the properties of the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition ); - - // Get the properties of the a frame - mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); - - // Get the properties of the b frame - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - - // This compositer is yuv422 only - *format = mlt_image_yuv422; - - // The cached luma map information - int luma_width = mlt_properties_get_int( properties, "width" ); - int luma_height = mlt_properties_get_int( properties, "height" ); - uint16_t *luma_bitmap = mlt_properties_get_data( properties, "bitmap", NULL ); - char *current_resource = mlt_properties_get( properties, "_resource" ); - - // If the filename property changed, reload the map - char *resource = mlt_properties_get( properties, "resource" ); - - // Correct width/height if not specified - if ( luma_width == 0 || luma_height == 0 ) - { - luma_width = mlt_properties_get_int( a_props, "width" ); - luma_height = mlt_properties_get_int( a_props, "height" ); - } - - if ( resource != current_resource ) - { - char temp[ 512 ]; - char *extension = strrchr( resource, '.' ); - - if ( strchr( resource, '%' ) ) - { - FILE *test; - sprintf( temp, "%s/lumas/%s/%s", mlt_environment( "MLT_DATA" ), mlt_environment( "MLT_NORMALISATION" ), strchr( resource, '%' ) + 1 ); - test = fopen( temp, "r" ); - if ( test == NULL ) - strcat( temp, ".png" ); - else - fclose( test ); - resource = temp; - extension = strrchr( resource, '.' ); - } - - // See if it is a PGM - if ( extension != NULL && strcmp( extension, ".pgm" ) == 0 ) - { - // Open PGM - FILE *f = fopen( resource, "r" ); - if ( f != NULL ) - { - // Load from PGM - luma_read_pgm( f, &luma_bitmap, &luma_width, &luma_height ); - fclose( f ); - - // Set the transition properties - mlt_properties_set_int( properties, "width", luma_width ); - mlt_properties_set_int( properties, "height", luma_height ); - mlt_properties_set( properties, "_resource", resource ); - mlt_properties_set_data( properties, "bitmap", luma_bitmap, luma_width * luma_height * 2, mlt_pool_release, NULL ); - } - } - else if (!*resource) - { - luma_bitmap = NULL; - mlt_properties_set( properties, "_resource", NULL ); - mlt_properties_set_data( properties, "bitmap", luma_bitmap, 0, mlt_pool_release, NULL ); - } - else - { - // Get the factory producer service - char *factory = mlt_properties_get( properties, "factory" ); - - // Create the producer - mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) ); - mlt_producer producer = mlt_factory_producer( profile, factory, resource ); - - // If we have one - if ( producer != NULL ) - { - // Get the producer properties - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Ensure that we loop - mlt_properties_set( producer_properties, "eof", "loop" ); - - // Now pass all producer. properties on the transition down - mlt_properties_pass( producer_properties, properties, "producer." ); - - // We will get the alpha frame from the producer - mlt_frame luma_frame = NULL; - - // Get the luma frame - if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &luma_frame, 0 ) == 0 ) - { - uint8_t *luma_image = NULL; - mlt_image_format luma_format = mlt_image_yuv422; - - // Get image from the luma producer - mlt_properties_set( MLT_FRAME_PROPERTIES( luma_frame ), "rescale.interp", "nearest" ); - mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 ); - - // Generate the luma map - if ( luma_image != NULL && luma_format == mlt_image_yuv422 ) - luma_read_yuv422( luma_image, &luma_bitmap, luma_width, luma_height ); - - else if ( luma_image != NULL && luma_format == mlt_image_rgb24 ) - luma_read_rgb24( luma_image, &luma_bitmap, luma_width, luma_height ); - - // Set the transition properties - mlt_properties_set_int( properties, "width", luma_width ); - mlt_properties_set_int( properties, "height", luma_height ); - mlt_properties_set( properties, "_resource", resource); - mlt_properties_set_data( properties, "bitmap", luma_bitmap, luma_width * luma_height * 2, mlt_pool_release, NULL ); - - // Cleanup the luma frame - mlt_frame_close( luma_frame ); - } - - // Cleanup the luma producer - mlt_producer_close( producer ); - } - } - } - - // Arbitrary composite defaults - float mix = position_calculate( transition, a_frame ); - float frame_delta = delta_calculate( transition, a_frame ); - - float luma_softness = mlt_properties_get_double( properties, "softness" ); - int progressive = - mlt_properties_get_int( a_props, "consumer_deinterlace" ) || - mlt_properties_get_int( properties, "progressive" ) || - mlt_properties_get_int( b_props, "luma.progressive" ); - int top_field_first = mlt_properties_get_int( b_props, "top_field_first" ); - int reverse = mlt_properties_get_int( properties, "reverse" ); - int invert = mlt_properties_get_int( properties, "invert" ); - - if ( mlt_properties_get( a_props, "rescale.interp" ) == NULL || !strcmp( mlt_properties_get( a_props, "rescale.interp" ), "none" ) ) - mlt_properties_set( a_props, "rescale.interp", "nearest" ); - - // Since we are the consumer of the b_frame, we must pass along this - // consumer property from the a_frame - if ( mlt_properties_get_double( a_props, "aspect_ratio" ) == 0.0 ) - mlt_properties_set_double( a_props, "aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - if ( mlt_properties_get_double( b_props, "aspect_ratio" ) == 0.0 ) - mlt_properties_set_double( b_props, "aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - - // Honour the reverse here - if ( mix >= 1.0 ) - mix -= floor( mix ); - - mix = reverse || invert ? 1 - mix : mix; - frame_delta *= reverse || invert ? -1.0 : 1.0; - - // Ensure we get scaling on the b_frame - if ( mlt_properties_get( b_props, "rescale.interp" ) == NULL || !strcmp( mlt_properties_get( b_props, "rescale.interp" ), "none" ) ) - mlt_properties_set( b_props, "rescale.interp", "nearest" ); - - if ( mlt_properties_get( properties, "fixed" ) ) - mix = mlt_properties_get_double( properties, "fixed" ); - - if ( luma_width > 0 && luma_height > 0 && luma_bitmap != NULL ) - // Composite the frames using a luma map - luma_composite( !invert ? a_frame : b_frame, !invert ? b_frame : a_frame, luma_width, luma_height, luma_bitmap, mix, frame_delta, - luma_softness, progressive ? -1 : top_field_first, width, height ); - else - // Dissolve the frames using the time offset for mix value - dissolve_yuv( a_frame, b_frame, mix, *width, *height ); - - // Extract the a_frame image info - *width = mlt_properties_get_int( !invert ? a_props : b_props, "width" ); - *height = mlt_properties_get_int( !invert ? a_props : b_props, "height" ); - *image = mlt_properties_get_data( !invert ? a_props : b_props, "image", NULL ); - - return 0; -} - - -/** Luma transition processing. -*/ - -static mlt_frame transition_process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame ) -{ - // Get a unique name to store the frame position - char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( transition ), "_unique_id" ); - - // Assign the current position to the name - mlt_properties_set_position( MLT_FRAME_PROPERTIES( a_frame ), name, mlt_frame_get_position( a_frame ) ); - - // Push the transition on to the frame - mlt_frame_push_service( a_frame, transition ); - - // Push the b_frame on to the stack - mlt_frame_push_frame( a_frame, b_frame ); - - // Push the transition method - mlt_frame_push_get_image( a_frame, transition_get_image ); - - return a_frame; -} - -/** Constructor for the filter. -*/ - -mlt_transition transition_luma_init( mlt_profile profile, mlt_service_type type, const char *id, char *lumafile ) -{ - mlt_transition transition = mlt_transition_new( ); - if ( transition != NULL ) - { - // Set the methods - transition->process = transition_process; - - // Default factory - mlt_properties_set( MLT_TRANSITION_PROPERTIES( transition ), "factory", "fezzik" ); - - // Set the main property - mlt_properties_set( MLT_TRANSITION_PROPERTIES( transition ), "resource", lumafile ); - - // Inform apps and framework that this is a video only transition - mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "_transition_type", 1 ); - - return transition; - } - return NULL; -} diff --git a/src/modules/core/transition_mix.c b/src/modules/core/transition_mix.c deleted file mode 100644 index b2b3790..0000000 --- a/src/modules/core/transition_mix.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * transition_mix.c -- mix two audio streams - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include - - -/** Get the audio. -*/ - -static int transition_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the b frame from the stack - mlt_frame b_frame = mlt_frame_pop_audio( frame ); - - // Get the effect - mlt_transition effect = mlt_frame_pop_audio( frame ); - - // Get the properties of the b frame - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - - if ( mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( effect ), "combine" ) == 0 ) - { - double mix_start = 0.5, mix_end = 0.5; - if ( mlt_properties_get( b_props, "audio.previous_mix" ) != NULL ) - mix_start = mlt_properties_get_double( b_props, "audio.previous_mix" ); - if ( mlt_properties_get( b_props, "audio.mix" ) != NULL ) - mix_end = mlt_properties_get_double( b_props, "audio.mix" ); - if ( mlt_properties_get_int( b_props, "audio.reverse" ) ) - { - mix_start = 1 - mix_start; - mix_end = 1 - mix_end; - } - - mlt_frame_mix_audio( frame, b_frame, mix_start, mix_end, buffer, format, frequency, channels, samples ); - } - else - { - mlt_frame_combine_audio( frame, b_frame, buffer, format, frequency, channels, samples ); - } - - return 0; -} - - -/** Mix transition processing. -*/ - -static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame ) -{ - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - - // Only if mix is specified, otherwise a producer may set the mix - if ( mlt_properties_get( properties, "start" ) != NULL ) - { - // Determine the time position of this frame in the transition duration - mlt_properties props = mlt_properties_get_data( MLT_FRAME_PROPERTIES( b_frame ), "_producer", NULL ); - int always_active = mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "always_active" ); - mlt_position in = !always_active ? mlt_transition_get_in( this ) : mlt_properties_get_int( props, "in" ); - mlt_position out = !always_active ? mlt_transition_get_out( this ) : mlt_properties_get_int( props, "out" ); - int length = mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "length" ); - mlt_position time = !always_active ? mlt_frame_get_position( b_frame ) : mlt_properties_get_int( props, "_frame" ); - double mix = ( double )( time - in ) / ( double )( out - in + 1 ); - - // TODO: Check the logic here - shouldn't we be computing current and next mixing levels in all cases? - if ( length == 0 ) - { - // If there is an end mix level adjust mix to the range - if ( mlt_properties_get( properties, "end" ) != NULL ) - { - double start = mlt_properties_get_double( properties, "start" ); - double end = mlt_properties_get_double( properties, "end" ); - mix = start + ( end - start ) * mix; - } - // A negative means total crossfade (uses position) - else if ( mlt_properties_get_double( properties, "start" ) >= 0 ) - { - // Otherwise, start/constructor is a constant mix level - mix = mlt_properties_get_double( properties, "start" ); - } - - // Finally, set the mix property on the frame - mlt_properties_set_double( b_props, "audio.mix", mix ); - - // Initialise transition previous mix value to prevent an inadvertant jump from 0 - mlt_position last_position = mlt_properties_get_position( properties, "_last_position" ); - mlt_position current_position = mlt_frame_get_position( b_frame ); - if ( mlt_properties_get( properties, "_previous_mix" ) == NULL - || current_position != last_position + 1 ) - mlt_properties_set_double( properties, "_previous_mix", mix ); - - // Tell b frame what the previous mix level was - mlt_properties_set_double( b_props, "audio.previous_mix", mlt_properties_get_double( properties, "_previous_mix" ) ); - - // Save the current mix level for the next iteration - mlt_properties_set_double( properties, "_previous_mix", mlt_properties_get_double( b_props, "audio.mix" ) ); - - mlt_properties_set_double( b_props, "audio.reverse", mlt_properties_get_double( properties, "reverse" ) ); - } - else - { - double level = mlt_properties_get_double( properties, "start" ); - double mix_start = level; - double mix_end = mix_start; - double mix_increment = 1.0 / length; - if ( time - in < length ) - { - mix_start = mix_start * ( ( double )( time - in ) / length ); - mix_end = mix_start + mix_increment; - } - else if ( time > out - length ) - { - mix_end = mix_start * ( ( double )( out - time - in ) / length ); - mix_start = mix_end - mix_increment; - } - - mix_start = mix_start < 0 ? 0 : mix_start > level ? level : mix_start; - mix_end = mix_end < 0 ? 0 : mix_end > level ? level : mix_end; - mlt_properties_set_double( b_props, "audio.previous_mix", mix_start ); - mlt_properties_set_double( b_props, "audio.mix", mix_end ); - } - } - - // Override the get_audio method - mlt_frame_push_audio( a_frame, this ); - mlt_frame_push_audio( a_frame, b_frame ); - mlt_frame_push_audio( a_frame, transition_get_audio ); - - return a_frame; -} - -/** Constructor for the transition. -*/ - -mlt_transition transition_mix_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_transition this = calloc( sizeof( struct mlt_transition_s ), 1 ); - if ( this != NULL && mlt_transition_init( this, NULL ) == 0 ) - { - this->process = transition_process; - if ( arg != NULL ) - mlt_properties_set_double( MLT_TRANSITION_PROPERTIES( this ), "start", atof( arg ) ); - // Inform apps and framework that this is an audio only transition - mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( this ), "_transition_type", 2 ); - } - return this; -} - diff --git a/src/modules/core/transition_region.c b/src/modules/core/transition_region.c deleted file mode 100644 index 52bcb0f..0000000 --- a/src/modules/core/transition_region.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * transition_region.c -- region transition - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "transition_region.h" -#include "transition_composite.h" - -#include - -#include -#include -#include - -static int create_instance( mlt_transition this, char *name, char *value, int count ) -{ - // Return from this function - int error = 0; - - // Duplicate the value - char *type = strdup( value ); - - // Pointer to filter argument - char *arg = type == NULL ? NULL : strchr( type, ':' ); - - // New filter being created - mlt_filter filter = NULL; - - // Cleanup type and arg - if ( arg != NULL ) - *arg ++ = '\0'; - - // Create the filter - mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( this ) ); - filter = mlt_factory_filter( profile, type, arg ); - - // If we have a filter, then initialise and store it - if ( filter != NULL ) - { - // Properties of this - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - // String to hold the property name - char id[ 256 ]; - - // String to hold the passdown key - char key[ 256 ]; - - // Construct id - sprintf( id, "_filter_%d", count ); - - // Counstruct key - sprintf( key, "%s.", name ); - - // Just in case, let's assume that the filter here has a composite - //mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "composite.geometry", "0%,0%:100%x100%" ); - //mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "composite.fill", 1 ); - - // Pass all the key properties on the filter down - mlt_properties_pass( MLT_FILTER_PROPERTIES( filter ), properties, key ); - - // Ensure that filter is assigned - mlt_properties_set_data( properties, id, filter, 0, ( mlt_destructor )mlt_filter_close, NULL ); - } - else - { - // Indicate that an error has occurred - error = 1; - } - - // Cleanup - free( type ); - - // Return error condition - return error; -} - -static uint8_t *filter_get_alpha_mask( mlt_frame this ) -{ - uint8_t *alpha = NULL; - - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get the shape frame - mlt_frame shape_frame = mlt_properties_get_data( properties, "shape_frame", NULL ); - - // Get the width and height of the image - int region_width = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "width" ); - int region_height = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "height" ); - uint8_t *image = NULL; - mlt_image_format format = mlt_image_yuv422; - - // Get the shape image to trigger alpha creation - mlt_properties_set_int( MLT_FRAME_PROPERTIES( shape_frame ), "distort", 1 ); - mlt_frame_get_image( shape_frame, &image, &format, ®ion_width, ®ion_height, 0 ); - - alpha = mlt_frame_get_alpha_mask( shape_frame ); - - // Generate from the Y component of the image if no alpha available - if ( alpha == NULL ) - { - int size = region_width * region_height; - uint8_t *p = mlt_pool_alloc( size ); - alpha = p; - while ( size -- ) - { - *p ++ = ( int )( ( ( *image ++ - 16 ) * 299 ) / 255 ); - image ++; - } - mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", alpha, region_width * region_height, mlt_pool_release, NULL ); - } - else - { - mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", alpha, region_width * region_height, NULL, NULL ); - } - - this->get_alpha_mask = NULL; - - return alpha; -} - -/** Do it :-). -*/ - -static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Error we will return - int error = 0; - - // We will get the 'b frame' from the frame stack - mlt_frame b_frame = mlt_frame_pop_frame( frame ); - - // Get the watermark transition object - mlt_transition this = mlt_frame_pop_service( frame ); - - // Get the properties of the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - // Get the composite from the transition - mlt_transition composite = mlt_properties_get_data( properties, "composite", NULL ); - - // Look for the first filter - mlt_filter filter = mlt_properties_get_data( properties, "_filter_0", NULL ); - - // Get the unique id of the filter (used to reacquire the producer position) - char *name = mlt_properties_get( properties, "_unique_id" ); - - // Get the original producer position - mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( frame ), name ); - - // Create a composite if we don't have one - if ( composite == NULL ) - { - // Create composite via the factory - mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( this ) ); - composite = mlt_factory_transition( profile, "composite", NULL ); - - // If we have one - if ( composite != NULL ) - { - // Get the properties - mlt_properties composite_properties = MLT_TRANSITION_PROPERTIES( composite ); - - // We want to ensure that we don't get a wobble... - //mlt_properties_set_int( composite_properties, "distort", 1 ); - mlt_properties_set_int( composite_properties, "progressive", 1 ); - - // Pass all the composite. properties on the transition down - mlt_properties_pass( composite_properties, properties, "composite." ); - - // Register the composite for reuse/destruction - mlt_properties_set_data( properties, "composite", composite, 0, ( mlt_destructor )mlt_transition_close, NULL ); - } - } - else - { - // Pass all current properties down - mlt_properties composite_properties = MLT_TRANSITION_PROPERTIES( composite ); - mlt_properties_pass( composite_properties, properties, "composite." ); - } - - // Create filters - if ( filter == NULL ) - { - // Loop Variable - int i = 0; - - // Number of filters created - int count = 0; - - // Loop for all properties - for ( i = 0; i < mlt_properties_count( properties ); i ++ ) - { - // Get the name of this property - char *name = mlt_properties_get_name( properties, i ); - - // If the name does not contain a . and matches filter - if ( strchr( name, '.' ) == NULL && !strncmp( name, "filter", 6 ) ) - { - // Get the filter constructor - char *value = mlt_properties_get_value( properties, i ); - - // Create an instance - if ( create_instance( this, name, value, count ) == 0 ) - count ++; - } - } - - // Look for the first filter again - filter = mlt_properties_get_data( properties, "_filter_0", NULL ); - } - else - { - // Pass all properties down - mlt_filter temp = NULL; - - // Loop Variable - int i = 0; - - // Number of filters found - int count = 0; - - // Loop for all properties - for ( i = 0; i < mlt_properties_count( properties ); i ++ ) - { - // Get the name of this property - char *name = mlt_properties_get_name( properties, i ); - - // If the name does not contain a . and matches filter - if ( strchr( name, '.' ) == NULL && !strncmp( name, "filter", 6 ) ) - { - // Strings to hold the id and pass down key - char id[ 256 ]; - char key[ 256 ]; - - // Construct id and key - sprintf( id, "_filter_%d", count ); - sprintf( key, "%s.", name ); - - // Get the filter - temp = mlt_properties_get_data( properties, id, NULL ); - - if ( temp != NULL ) - { - mlt_properties_pass( MLT_FILTER_PROPERTIES( temp ), properties, key ); - count ++; - } - } - } - } - - // Get the image - error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - // Only continue if we have both filter and composite - if ( composite != NULL ) - { - // Get the resource of this filter (could be a shape [rectangle/circle] or an alpha provider of choice - const char *resource = mlt_properties_get( properties, "resource" ); - - // Get the old resource in case it's changed - char *old_resource = mlt_properties_get( properties, "_old_resource" ); - - // String to hold the filter to query on - char id[ 256 ]; - - // Index to hold the count - int i = 0; - - // We will get the 'b frame' from the composite only if it's NULL - if ( b_frame == NULL ) - { - // Copy the region - b_frame = composite_copy_region( composite, frame, position ); - - // Ensure a destructor - mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), name, b_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); - } - - // Set the position of the b_frame - mlt_frame_set_position( b_frame, position ); - - // Make sure the filter is in the correct position - while ( filter != NULL ) - { - // Stack this filter - if ( mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "off" ) == 0 ) - mlt_filter_process( filter, b_frame ); - - // Generate the key for the next - sprintf( id, "_filter_%d", ++ i ); - - // Get the next filter - filter = mlt_properties_get_data( properties, id, NULL ); - } - - // Allow filters to be attached to a region filter - filter = mlt_properties_get_data( properties, "_region_filter", NULL ); - if ( filter != NULL ) - mlt_service_apply_filters( MLT_FILTER_SERVICE( filter ), b_frame, 0 ); - - // Hmm - this is probably going to go wrong.... - mlt_frame_set_position( frame, position ); - - // Get the b frame and process with composite if successful - mlt_transition_process( composite, frame, b_frame ); - - // If we have a shape producer copy the alpha mask from the shape frame to the b_frame - if ( strcmp( resource, "rectangle" ) != 0 ) - { - // Get the producer from the transition - mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL ); - - // If We have no producer then create one - if ( producer == NULL || ( old_resource != NULL && strcmp( resource, old_resource ) ) ) - { - // Get the factory producer service - char *factory = mlt_properties_get( properties, "factory" ); - - // Store the old resource - mlt_properties_set( properties, "_old_resource", resource ); - - // Special case circle resource - if ( strcmp( resource, "circle" ) == 0 ) - resource = "pixbuf:"; - - // Create the producer - mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( this ) ); - producer = mlt_factory_producer( profile, factory, resource ); - - // If we have one - if ( producer != NULL ) - { - // Get the producer properties - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Ensure that we loop - mlt_properties_set( producer_properties, "eof", "loop" ); - - // Now pass all producer. properties on the transition down - mlt_properties_pass( producer_properties, properties, "producer." ); - - // Register the producer for reuse/destruction - mlt_properties_set_data( properties, "producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); - } - } - - // Now use the shape producer - if ( producer != NULL ) - { - // We will get the alpha frame from the producer - mlt_frame shape_frame = NULL; - - // Make sure the producer is in the correct position - mlt_producer_seek( producer, position ); - - // Get the shape frame - if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &shape_frame, 0 ) == 0 ) - { - // Ensure that the shape frame will be closed - mlt_properties_set_data( MLT_FRAME_PROPERTIES( b_frame ), "shape_frame", shape_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); - - // Specify the callback for evaluation - b_frame->get_alpha_mask = filter_get_alpha_mask; - } - } - } - - // Get the image - error = mlt_frame_get_image( frame, image, format, width, height, 0 ); - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame ) -{ - // Get the properties of the frame - mlt_properties properties = MLT_FRAME_PROPERTIES( a_frame ); - - // Get a unique name to store the frame position - char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( this ), "_unique_id" ); - - // Assign the current position to the name - mlt_properties_set_position( properties, name, mlt_frame_get_position( a_frame ) ); - - // Push the transition on to the frame - mlt_frame_push_service( a_frame, this ); - - // Push the b_frame on to the stack - mlt_frame_push_frame( a_frame, b_frame ); - - // Push the transition method - mlt_frame_push_get_image( a_frame, transition_get_image ); - - // Return the frame - return a_frame; -} - -/** Constructor for the transition. -*/ - -mlt_transition transition_region_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create a new transition - mlt_transition this = mlt_transition_new( ); - - // Further initialisation - if ( this != NULL ) - { - // Get the properties from the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - // Assign the transition process method - this->process = transition_process; - - // Default factory - mlt_properties_set( properties, "factory", "fezzik" ); - - // Resource defines the shape of the region - mlt_properties_set( properties, "resource", arg == NULL ? "rectangle" : arg ); - - // Inform apps and framework that this is a video only transition - mlt_properties_set_int( properties, "_transition_type", 1 ); - } - - // Return the transition - return this; -} - diff --git a/src/modules/core/transition_region.h b/src/modules/core/transition_region.h deleted file mode 100644 index f08ad0e..0000000 --- a/src/modules/core/transition_region.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * transition_region.h -- region transition - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _TRANSITION_REGION_H_ -#define _TRANSITION_REGION_H_ - -#include - -extern mlt_transition transition_region_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -#endif diff --git a/src/modules/data_fx.properties b/src/modules/data_fx.properties deleted file mode 100644 index f7dc2e9..0000000 --- a/src/modules/data_fx.properties +++ /dev/null @@ -1,250 +0,0 @@ -# This properties file describes the fx available to the data_send and -# data_show filters -# -# Syntax is as follows: -# -# name= -# name.description= -# name.properties.= -# name.=value -# etc -# -# Typically, the is a 'region' and additional filters are -# included as properties using the normal region filter syntax. -# - -# -# The titles filter definition -# - -titles=region -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%,70%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:0;5=0%,0%:100%x100%:40 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%,0%:100%x100%:0;8=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 - -# -# The top titles filter definition -# - -top-titles=region -.description=Top Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%,5%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:0;5=0%,0%:100%x100%:40 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%,0%:100%x100%:0;8=0%,0%:100%x100%:100 -.filter[1].composite.halign=centre -.filter[1].composite.titles=1 - -# -# OK - Silly example... -# - -tickertape=region -.description=Tickertape -.properties.markup=filter[1].producer.markup -.type.markup=text -.properties.length[0]=filter[1].composite.out -.composite.geometry=0%,93%:100%x7% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=100%,0%:300%x100%:100;-1=-300%,0%:300%x100%:100 -.filter[1].producer.font=San 32 -.filter[1].composite.titles=1 - -# -# ETV Location -# - -location=region -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=0,80:230x30 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=-100%,0%:100%x100%:100;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup= -.filter[1].producer.font=San 24 -.filter[1].composite.geometry=0%,0%:100%x100%:0;24=0%,0%:100%x100%:0;49=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=center - -courtesy=region -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=0,115:230x30 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=-100%,0%:100%x100%:0;12=-100%,0%:100%x100%:0;37=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=ETV Exclusive -.filter[1].producer.font=San 24 -.filter[1].composite.geometry=0%,0%:100%x100%:0;37=0%,0%:100%x100%:0;61=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=right - -exclusive=region -.description=Exclusive -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=0,115:230x30 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=ETV Exclusive -.filter[1].producer.font=San 24 -.filter[1].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=right - -file_shot=region -.description=Titles -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=590,160:80x25 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=File Shot -.filter[1].producer.font=San 18 -.filter[1].composite.geometry=0%,0%:100%x100%:15;25=0%,0%:100%x100%:100 -.filter[1].composite.titles=0 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -special=region -.description=Titles -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=465,375:255x35 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=100%,0%:100%x100%:0;49=100%,0%:100%x100%:0;74=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Special -.filter[1].producer.font=San 24 -.filter[1].composite.geometry=100%,0%:100%x100%:0;49=100%,0%:100%x100%:0;74=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -ticker=region -.description=Tickertape -.properties.markup=filter[1].producer.markup -.type.markup=text -.properties.length[0]=filter[1].composite.out -.composite.geometry=0,500:722x75 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Ticker - provided for reference -.filter[1].composite.geometry=0%,0%:100%x100%:100 -.filter[1].composite.titles=0 -.filter[1].producer.font=San 24 -.filter[1].composite.halign=centre -.filter[1].composite.titles=1 -.filter[1].composite.valign=centre - -super=region -.description=Transcription -.properties.0=filter[1].producer.markup -.properties.1=filter[2].producer.markup -.properties.align=filter[1].composite.valign -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.properties.length[2]=filter[2].composite.out -.period=2 -.composite.geometry=0,410:720x90 -.filter[0]=watermark -.filter[0].resource=colour:0xbbbbbb00 -.filter[0].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[0].composite.luma=%luma18.pgm -.filter[0].composite.out=25 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup= -.filter[1].producer.font=San 32 -.filter[1].producer.fgcolour=0x6c0101ff -.filter[1].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=top -.filter[2]=watermark -.filter[2].resource=pango: -.filter[2].producer.markup= -.filter[2].producer.font=San 32 -.filter[2].producer.fgcolour=0x6c0101ff -.filter[2].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[2].composite.titles=1 -.filter[2].composite.halign=centre -.filter[2].composite.valign=bottom - -obscure=region -.description=Obscure -.properties.geometry=composite.geometry -.properties.resource=resource -.properties.length[0]=composite.out -.composite.geometry= -.resource=rectangle -.composite.refresh=1 -.filter[0]=obscure -.filter[0].start=0,0:100%x100% - diff --git a/src/modules/dgraft/Makefile b/src/modules/dgraft/Makefile deleted file mode 100644 index 7e17749..0000000 --- a/src/modules/dgraft/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltdgraft$(LIBSUF) - -OBJS = factory.o \ - filter_telecide.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/dgraft/factory.c b/src/modules/dgraft/factory.c deleted file mode 100644 index e0f2825..0000000 --- a/src/modules/dgraft/factory.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2008 Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -extern mlt_filter filter_telecide_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "telecide", filter_telecide_init ); -} diff --git a/src/modules/dgraft/filter_telecide.c b/src/modules/dgraft/filter_telecide.c deleted file mode 100644 index 9bb1149..0000000 --- a/src/modules/dgraft/filter_telecide.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* - * filter_telecide.c -- Donald Graft's Inverse Telecine Filter - * Copyright (C) 2003 Donald A. Graft - * Copyright (C) 2008 Dan Dennedy - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include - -#include -#include -#include -#include - -//#define DEBUG_PATTERN_GUIDANCE - -#define MAX_CYCLE 6 -#define BLKSIZE 24 -#define BLKSIZE_TIMES2 (2 * BLKSIZE) -#define GUIDE_32 1 -#define GUIDE_22 2 -#define GUIDE_32322 3 -#define AHEAD 0 -#define BEHIND 1 -#define POST_METRICS 1 -#define POST_FULL 2 -#define POST_FULL_MAP 3 -#define POST_FULL_NOMATCH 4 -#define POST_FULL_NOMATCH_MAP 5 -#define CACHE_SIZE 100000 -#define P 0 -#define C 1 -#define N 2 -#define PBLOCK 3 -#define CBLOCK 4 - -#define NO_BACK 0 -#define BACK_ON_COMBED 1 -#define ALWAYS_BACK 2 - -struct CACHE_ENTRY -{ - unsigned int frame; - unsigned int metrics[5]; - unsigned int chosen; -}; - -struct PREDICTION -{ - unsigned int metric; - unsigned int phase; - unsigned int predicted; - unsigned int predicted_metric; -}; - -struct context_s { - int is_configured; - mlt_properties image_cache; - int out; - - int tff, chroma, blend, hints, show, debug; - float dthresh, gthresh, vthresh, vthresh_saved, bthresh; - int y0, y1, nt, guide, post, back, back_saved; - int pitch, dpitch, pitchover2, pitchtimes4; - int w, h, wover2, hover2, hplus1over2, hminus2; - int xblocks, yblocks; -#ifdef WINDOWED_MATCH - unsigned int *matchc, *matchp, highest_matchc, highest_matchp; -#endif - unsigned int *sumc, *sump, highest_sumc, highest_sump; - int vmetric; - unsigned int *overrides, *overrides_p; - int film, override, inpattern, found; - int force; - - // Used by field matching. - unsigned char *fprp, *fcrp, *fcrp_saved, *fnrp; -// unsigned char *fprpU, *fcrpU, *fcrp_savedU, *fnrpU; -// unsigned char *fprpV, *fcrpV, *fcrp_savedV, *fnrpV; - unsigned char *dstp, *finalp; -// unsigned char *dstpU, *dstpV; - int chosen; - unsigned int p, c, pblock, cblock, lowest, predicted, predicted_metric; - unsigned int np, nc, npblock, ncblock, nframe; - float mismatch; - int pframe, x, y; - unsigned char *crp, *prp; - unsigned char *crpU, *prpU; - unsigned char *crpV, *prpV; - int hard; - char status[80]; - - // Metrics cache. - struct CACHE_ENTRY *cache; - - // Pattern guidance data. - int cycle; - struct PREDICTION pred[MAX_CYCLE+1]; -}; -typedef struct context_s *context; - - -static inline -void BitBlt(uint8_t* dstp, int dst_pitch, const uint8_t* srcp, - int src_pitch, int row_size, int height) -{ - uint32_t y; - for(y=0;ychosen == P) use = 'p'; - else if (cx->chosen == C) use = 'c'; - else use = 'n'; - snprintf(buf, sizeof(buf), "Telecide: frame %d: matches: %d %d %d\n", frame, cx->p, cx->c, cx->np); - if ( cx->post ) - snprintf(buf, sizeof(buf), "%sTelecide: frame %d: vmetrics: %d %d %d [chosen=%d]\n", buf, frame, cx->pblock, cx->cblock, cx->npblock, cx->vmetric); - if ( cx->guide ) - snprintf(buf, sizeof(buf), "%spattern mismatch=%0.2f%%\n", buf, cx->mismatch); - snprintf(buf, sizeof(buf), "%sTelecide: frame %d: [%s %c]%s %s\n", buf, frame, cx->found ? "forcing" : "using", use, - cx->post ? (cx->film ? " [progressive]" : " [interlaced]") : "", - cx->guide ? cx->status : ""); - mlt_properties_set( properties, "meta.attr.telecide.markup", buf ); -} - -static void Debug(context cx, int frame) -{ - char use; - - if (cx->chosen == P) use = 'p'; - else if (cx->chosen == C) use = 'c'; - else use = 'n'; - fprintf(stderr, "Telecide: frame %d: matches: %d %d %d\n", frame, cx->p, cx->c, cx->np); - if ( cx->post ) - fprintf(stderr, "Telecide: frame %d: vmetrics: %d %d %d [chosen=%d]\n", frame, cx->pblock, cx->cblock, cx->npblock, cx->vmetric); - if ( cx->guide ) - fprintf(stderr, "pattern mismatch=%0.2f%%\n", cx->mismatch); - fprintf(stderr, "Telecide: frame %d: [%s %c]%s %s\n", frame, cx->found ? "forcing" : "using", use, - cx->post ? (cx->film ? " [progressive]" : " [interlaced]") : "", - cx->guide ? cx->status : ""); -} - -static void WriteHints(int film, int inpattern, mlt_properties frame_properties) -{ - mlt_properties_set_int( frame_properties, "telecide.progressive", film); - mlt_properties_set_int( frame_properties, "telecide.in_pattern", inpattern); -} - -static void PutChosen(context cx, int frame, unsigned int chosen) -{ - int f = frame % CACHE_SIZE; - if (frame < 0 || frame > cx->out || cx->cache[f].frame != frame) - return; - cx->cache[f].chosen = chosen; -} - -static void CacheInsert(context cx, int frame, unsigned int p, unsigned int pblock, - unsigned int c, unsigned int cblock) -{ - int f = frame % CACHE_SIZE; - if (frame < 0 || frame > cx->out) - fprintf( stderr, "%s: internal error: invalid frame %d for CacheInsert", __FUNCTION__, frame); - cx->cache[f].frame = frame; - cx->cache[f].metrics[P] = p; - if (f) cx->cache[f-1].metrics[N] = p; - cx->cache[f].metrics[C] = c; - cx->cache[f].metrics[PBLOCK] = pblock; - cx->cache[f].metrics[CBLOCK] = cblock; - cx->cache[f].chosen = 0xff; -} - -static int CacheQuery(context cx, int frame, unsigned int *p, unsigned int *pblock, - unsigned int *c, unsigned int *cblock) -{ - int f; - - f = frame % CACHE_SIZE; - if (frame < 0 || frame > cx->out) - fprintf( stderr, "%s: internal error: invalid frame %d for CacheQuery", __FUNCTION__, frame); - if (cx->cache[f].frame != frame) - { - return 0; - } - *p = cx->cache[f].metrics[P]; - *c = cx->cache[f].metrics[C]; - *pblock = cx->cache[f].metrics[PBLOCK]; - *cblock = cx->cache[f].metrics[CBLOCK]; - return 1; -} - -static int PredictHardYUY2(context cx, int frame, unsigned int *predicted, unsigned int *predicted_metric) -{ - // Look for pattern in the actual delivered matches of the previous cycle of frames. - // If a pattern is found, use that to predict the current match. - if ( cx->guide == GUIDE_22 ) - { - if (cx->cache[(frame- cx->cycle)%CACHE_SIZE ].chosen == 0xff || - cx->cache[(frame- cx->cycle+1)%CACHE_SIZE].chosen == 0xff) - return 0; - switch ((cx->cache[(frame- cx->cycle)%CACHE_SIZE ].chosen << 4) + - (cx->cache[(frame- cx->cycle+1)%CACHE_SIZE].chosen)) - { - case 0x11: - *predicted = C; - *predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; - break; - case 0x22: - *predicted = N; - *predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; - break; - default: return 0; - } - } - else if ( cx->guide == GUIDE_32 ) - { - if (cx->cache[(frame-cx->cycle)%CACHE_SIZE ].chosen == 0xff || - cx->cache[(frame-cx->cycle+1)%CACHE_SIZE].chosen == 0xff || - cx->cache[(frame-cx->cycle+2)%CACHE_SIZE].chosen == 0xff || - cx->cache[(frame-cx->cycle+3)%CACHE_SIZE].chosen == 0xff || - cx->cache[(frame-cx->cycle+4)%CACHE_SIZE].chosen == 0xff) - return 0; - - switch ((cx->cache[(frame-cx->cycle)%CACHE_SIZE ].chosen << 16) + - (cx->cache[(frame-cx->cycle+1)%CACHE_SIZE].chosen << 12) + - (cx->cache[(frame-cx->cycle+2)%CACHE_SIZE].chosen << 8) + - (cx->cache[(frame-cx->cycle+3)%CACHE_SIZE].chosen << 4) + - (cx->cache[(frame-cx->cycle+4)%CACHE_SIZE].chosen)) - { - case 0x11122: - case 0x11221: - case 0x12211: - case 0x12221: - case 0x21122: - case 0x11222: - *predicted = C; - *predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; - break; - case 0x22111: - case 0x21112: - case 0x22112: - case 0x22211: - *predicted = N; - *predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; - break; - default: return 0; - } - } - else if ( cx->guide == GUIDE_32322 ) - { - if (cx->cache[(frame- cx->cycle)%CACHE_SIZE ].chosen == 0xff || - cx->cache[(frame- cx->cycle +1)%CACHE_SIZE].chosen == 0xff || - cx->cache[(frame- cx->cycle +2)%CACHE_SIZE].chosen == 0xff || - cx->cache[(frame- cx->cycle +3)%CACHE_SIZE].chosen == 0xff || - cx->cache[(frame- cx->cycle +4)%CACHE_SIZE].chosen == 0xff || - cx->cache[(frame- cx->cycle +5)%CACHE_SIZE].chosen == 0xff) - return 0; - - switch ((cx->cache[(frame- cx->cycle)%CACHE_SIZE ].chosen << 20) + - (cx->cache[(frame- cx->cycle +1)%CACHE_SIZE].chosen << 16) + - (cx->cache[(frame- cx->cycle +2)%CACHE_SIZE].chosen << 12) + - (cx->cache[(frame- cx->cycle +3)%CACHE_SIZE].chosen << 8) + - (cx->cache[(frame- cx->cycle +4)%CACHE_SIZE].chosen << 4) + - (cx->cache[(frame- cx->cycle +5)%CACHE_SIZE].chosen)) - { - case 0x111122: - case 0x111221: - case 0x112211: - case 0x122111: - case 0x111222: - case 0x112221: - case 0x122211: - case 0x222111: - *predicted = C; - *predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; - break; - case 0x221111: - case 0x211112: - - case 0x221112: - case 0x211122: - *predicted = N; - *predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; - break; - default: return 0; - } - } -#ifdef DEBUG_PATTERN_GUIDANCE - fprintf( stderr, "%s: pos=%d HARD: predicted=%d\n", __FUNCTION__, frame, *predicted); -#endif - return 1; -} - -static struct PREDICTION *PredictSoftYUY2(context cx, int frame ) -{ - // Use heuristics to look forward for a match. - int i, j, y, c, n, phase; - unsigned int metric; - - cx->pred[0].metric = 0xffffffff; - if (frame < 0 || frame > cx->out - cx->cycle) return cx->pred; - - // Look at the next cycle of frames. - for (y = frame + 1; y <= frame + cx->cycle; y++) - { - // Look for a frame where the current and next match values are - // very close. Those are candidates to predict the phase, because - // that condition should occur only once per cycle. Store the candidate - // phases and predictions in a list sorted by goodness. The list will - // be used by the caller to try the phases in order. - c = cx->cache[y%CACHE_SIZE].metrics[C]; - n = cx->cache[y%CACHE_SIZE].metrics[N]; - if (c == 0) c = 1; - metric = (100 * abs (c - n)) / c; - phase = y % cx->cycle; - if (metric < 5) - { - // Place the new candidate phase in sorted order in the list. - // Find the insertion point. - i = 0; - while (metric > cx->pred[i].metric) i++; - // Find the end-of-list marker. - j = 0; - while (cx->pred[j].metric != 0xffffffff) j++; - // Shift all items below the insertion point down by one to make - // room for the insertion. - j++; - for (; j > i; j--) - { - cx->pred[j].metric = cx->pred[j-1].metric; - cx->pred[j].phase = cx->pred[j-1].phase; - cx->pred[j].predicted = cx->pred[j-1].predicted; - cx->pred[j].predicted_metric = cx->pred[j-1].predicted_metric; - } - // Insert the new candidate data. - cx->pred[j].metric = metric; - cx->pred[j].phase = phase; - if ( cx->guide == GUIDE_32 ) - { - switch ((frame % cx->cycle) - phase) - { - case -4: cx->pred[j].predicted = N; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; break; - case -3: cx->pred[j].predicted = N; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; break; - case -2: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - case -1: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - case 0: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - case +1: cx->pred[j].predicted = N; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; break; - case +2: cx->pred[j].predicted = N; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; break; - case +3: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - case +4: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - } - } - else if ( cx->guide == GUIDE_32322 ) - { - switch ((frame % cx->cycle) - phase) - { - case -5: cx->pred[j].predicted = N; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; break; - case -4: cx->pred[j].predicted = N; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; break; - case -3: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - case -2: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - case -1: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - case 0: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - case +1: cx->pred[j].predicted = N; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; break; - case +2: cx->pred[j].predicted = N; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[N]; break; - case +3: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - case +4: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - case +5: cx->pred[j].predicted = C; cx->pred[j].predicted_metric = cx->cache[frame%CACHE_SIZE].metrics[C]; break; - } - } - } -#ifdef DEBUG_PATTERN_GUIDANCE - fprintf( stderr, "%s: pos=%d metric=%d phase=%d\n", __FUNCTION__, frame, metric, phase); -#endif - } - return cx->pred; -} - -static -void CalculateMetrics(context cx, int frame, unsigned char *fcrp, unsigned char *fcrpU, unsigned char *fcrpV, - unsigned char *fprp, unsigned char *fprpU, unsigned char *fprpV) -{ - int x, y, p, c, tmp1, tmp2, skip; - int vc; - unsigned char *currbot0, *currbot2, *prevbot0, *prevbot2; - unsigned char *prevtop0, *prevtop2, *prevtop4, *currtop0, *currtop2, *currtop4; - unsigned char *a0, *a2, *b0, *b2, *b4; - unsigned int diff, index; -# define T 4 - - /* Clear the block sums. */ - for (y = 0; y < cx->yblocks; y++) - { - for (x = 0; x < cx->xblocks; x++) - { -#ifdef WINDOWED_MATCH - matchp[y*xblocks+x] = 0; - matchc[y*xblocks+x] = 0; -#endif - cx->sump[y * cx->xblocks + x] = 0; - cx->sumc[y * cx->xblocks + x] = 0; - } - } - - /* Find the best field match. Subsample the frames for speed. */ - currbot0 = fcrp + cx->pitch; - currbot2 = fcrp + 3 * cx->pitch; - currtop0 = fcrp; - currtop2 = fcrp + 2 * cx->pitch; - currtop4 = fcrp + 4 * cx->pitch; - prevbot0 = fprp + cx->pitch; - prevbot2 = fprp + 3 * cx->pitch; - prevtop0 = fprp; - prevtop2 = fprp + 2 * cx->pitch; - prevtop4 = fprp + 4 * cx->pitch; - if ( cx->tff ) - { - a0 = prevbot0; - a2 = prevbot2; - b0 = currtop0; - b2 = currtop2; - b4 = currtop4; - } - else - { - a0 = currbot0; - a2 = currbot2; - b0 = prevtop0; - b2 = prevtop2; - b4 = prevtop4; - } - p = c = 0; - - // Calculate the field match and film/video metrics. -// if (vi.IsYV12()) skip = 1; -// else - skip = 1 + ( !cx->chroma ); - for (y = 0, index = 0; y < cx->h - 4; y+=4) - { - /* Exclusion band. Good for ignoring subtitles. */ - if (cx->y0 == cx->y1 || y < cx->y0 || y > cx->y1) - { - for (x = 0; x < cx->w;) - { -// if (vi.IsYV12()) -// index = (y/BLKSIZE)*xblocks + x/BLKSIZE; -// else - index = (y/BLKSIZE) * cx->xblocks + x/BLKSIZE_TIMES2; - - // Test combination with current frame. - tmp1 = ((long)currbot0[x] + (long)currbot2[x]); -// diff = abs((long)currtop0[x] - (tmp1 >> 1)); - diff = abs((((long)currtop0[x] + (long)currtop2[x] + (long)currtop4[x])) - (tmp1 >> 1) - tmp1); - if (diff > cx->nt) - { - c += diff; -#ifdef WINDOWED_MATCH - matchc[index] += diff; -#endif - } - - tmp1 = currbot0[x] + T; - tmp2 = currbot0[x] - T; - vc = (tmp1 < currtop0[x] && tmp1 < currtop2[x]) || - (tmp2 > currtop0[x] && tmp2 > currtop2[x]); - if (vc) - { - cx->sumc[index]++; - } - - // Test combination with previous frame. - tmp1 = ((long)a0[x] + (long)a2[x]); - diff = abs((((long)b0[x] + (long)b2[x] + (long)b4[x])) - (tmp1 >> 1) - tmp1); - if (diff > cx->nt) - { - p += diff; -#ifdef WINDOWED_MATCH - matchp[index] += diff; -#endif - } - - tmp1 = a0[x] + T; - tmp2 = a0[x] - T; - vc = (tmp1 < b0[x] && tmp1 < b2[x]) || - (tmp2 > b0[x] && tmp2 > b2[x]); - if (vc) - { - cx->sump[index]++; - } - - x += skip; - if (!(x&3)) x += 4; - } - } - currbot0 += cx->pitchtimes4; - currbot2 += cx->pitchtimes4; - currtop0 += cx->pitchtimes4; - currtop2 += cx->pitchtimes4; - currtop4 += cx->pitchtimes4; - a0 += cx->pitchtimes4; - a2 += cx->pitchtimes4; - b0 += cx->pitchtimes4; - b2 += cx->pitchtimes4; - b4 += cx->pitchtimes4; - } - -// if (vi.IsYV12() && chroma == true) -// { -// int z; -// -// for (z = 0; z < 2; z++) -// { -// // Do the same for the U plane. -// if (z == 0) -// { -// currbot0 = fcrpU + pitchover2; -// currbot2 = fcrpU + 3 * pitchover2; -// currtop0 = fcrpU; -// currtop2 = fcrpU + 2 * pitchover2; -// currtop4 = fcrpU + 4 * pitchover2; -// prevbot0 = fprpU + pitchover2; -// prevbot2 = fprpU + 3 * pitchover2; -// prevtop0 = fprpU; -// prevtop2 = fprpU + 2 * pitchover2; -// prevtop4 = fprpU + 4 * pitchover2; -// } -// else -// { -// currbot0 = fcrpV + pitchover2; -// currbot2 = fcrpV + 3 * pitchover2; -// currtop0 = fcrpV; -// currtop2 = fcrpV + 2 * pitchover2; -// currtop4 = fcrpV + 4 * pitchover2; -// prevbot0 = fprpV + pitchover2; -// prevbot2 = fprpV + 3 * pitchover2; -// prevtop0 = fprpV; -// prevtop2 = fprpV + 2 * pitchover2; -// prevtop4 = fprpV + 4 * pitchover2; -// } -// if (tff == true) -// { -// a0 = prevbot0; -// a2 = prevbot2; -// b0 = currtop0; -// b2 = currtop2; -// b4 = currtop4; -// } -// else -// { -// a0 = currbot0; -// a2 = currbot2; -// b0 = prevtop0; -// b2 = prevtop2; -// b4 = prevtop4; -// } -// -// for (y = 0, index = 0; y < hover2 - 4; y+=4) -// { -// /* Exclusion band. Good for ignoring subtitles. */ -// if (y0 == y1 || y < y0/2 || y > y1/2) -// { -// for (x = 0; x < wover2;) -// { -// if (vi.IsYV12()) -// index = (y/BLKSIZE)*xblocks + x/BLKSIZE; -// else -// index = (y/BLKSIZE)*xblocks + x/BLKSIZE_TIMES2; -// -// // Test combination with current frame. -// tmp1 = ((long)currbot0[x] + (long)currbot2[x]); -// diff = abs((((long)currtop0[x] + (long)currtop2[x] + (long)currtop4[x])) - (tmp1 >> 1) - tmp1); -// if (diff > nt) -// { -// c += diff; -//#ifdef WINDOWED_MATCH -// matchc[index] += diff; -//#endif -// } -// -// tmp1 = currbot0[x] + T; -// tmp2 = currbot0[x] - T; -// vc = (tmp1 < currtop0[x] && tmp1 < currtop2[x]) || -// (tmp2 > currtop0[x] && tmp2 > currtop2[x]); -// if (vc) -// { -// sumc[index]++; -// } -// -// // Test combination with previous frame. -// tmp1 = ((long)a0[x] + (long)a2[x]); -// diff = abs((((long)b0[x] + (long)b2[x] + (long)b4[x])) - (tmp1 >> 1) - tmp1); -// if (diff > nt) -// { -// p += diff; -//#ifdef WINDOWED_MATCH -// matchp[index] += diff; -//#endif -// } -// -// tmp1 = a0[x] + T; -// tmp2 = a0[x] - T; -// vc = (tmp1 < b0[x] && tmp1 < b2[x]) || -// (tmp2 > b0[x] && tmp2 > b2[x]); -// if (vc) -// { -// sump[index]++; -// } -// -// x ++; -// if (!(x&3)) x += 4; -// } -// } -// currbot0 += 4*pitchover2; -// currbot2 += 4*pitchover2; -// currtop0 += 4*pitchover2; -// currtop2 += 4*pitchover2; -// currtop4 += 4*pitchover2; -// a0 += 4*pitchover2; -// a2 += 4*pitchover2; -// b0 += 4*pitchover2; -// b2 += 4*pitchover2; -// b4 += 4*pitchover2; -// } -// } -// } -// -// // Now find the blocks that have the greatest differences. -//#ifdef WINDOWED_MATCH -// highest_matchp = 0; -// for (y = 0; y < yblocks; y++) -// { -// for (x = 0; x < xblocks; x++) -// { -//if (frame == 45 && matchp[y * xblocks + x] > 2500) -//{ -// sprintf(buf, "%d/%d = %d\n", x, y, matchp[y * xblocks + x]); -// OutputDebugString(buf); -//} -// if (matchp[y * xblocks + x] > highest_matchp) -// { -// highest_matchp = matchp[y * xblocks + x]; -// } -// } -// } -// highest_matchc = 0; -// for (y = 0; y < yblocks; y++) -// { -// for (x = 0; x < xblocks; x++) -// { -//if (frame == 44 && matchc[y * xblocks + x] > 2500) -//{ -// sprintf(buf, "%d/%d = %d\n", x, y, matchc[y * xblocks + x]); -// OutputDebugString(buf); -//} -// if (matchc[y * xblocks + x] > highest_matchc) -// { -// highest_matchc = matchc[y * xblocks + x]; -// } -// } -// } -//#endif - if ( cx->post ) - { - cx->highest_sump = 0; - for (y = 0; y < cx->yblocks; y++) - { - for (x = 0; x < cx->xblocks; x++) - { - if (cx->sump[y * cx->xblocks + x] > cx->highest_sump) - { - cx->highest_sump = cx->sump[y * cx->xblocks + x]; - } - } - } - cx->highest_sumc = 0; - for (y = 0; y < cx->yblocks; y++) - { - for (x = 0; x < cx->xblocks; x++) - { - if (cx->sumc[y * cx->xblocks + x] > cx->highest_sumc) - { - cx->highest_sumc = cx->sumc[y * cx->xblocks + x]; - } - } - } - } -#ifdef WINDOWED_MATCH - CacheInsert(frame, highest_matchp, highest_sump, highest_matchc, highest_sumc); -#else - CacheInsert( cx, frame, p, cx->highest_sump, c, cx->highest_sumc); -#endif -} - - -/** Process the image. -*/ - -static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the filter service - mlt_filter filter = mlt_frame_pop_service( frame ); - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - mlt_properties frame_properties = mlt_frame_properties( frame ); - context cx = mlt_properties_get_data( properties, "context", NULL ); - mlt_service producer = mlt_service_producer( mlt_filter_service( filter ) ); - cx->out = producer? mlt_producer_get_playtime( MLT_PRODUCER( producer ) ) : 999999; - - if ( ! cx->is_configured ) - { - cx->back = mlt_properties_get_int( properties, "back" ); - cx->chroma = mlt_properties_get_int( properties, "chroma" ); - cx->guide = mlt_properties_get_int( properties, "guide" ); - cx->gthresh = mlt_properties_get_double( properties, "gthresh" ); - cx->post = mlt_properties_get_int( properties, "post" ); - cx->vthresh = mlt_properties_get_double( properties, "vthresh" ); - cx->bthresh = mlt_properties_get_double( properties, "bthresh" ); - cx->dthresh = mlt_properties_get_double( properties, "dthresh" ); - cx->blend = mlt_properties_get_int( properties, "blend" ); - cx->nt = mlt_properties_get_int( properties, "nt" ); - cx->y0 = mlt_properties_get_int( properties, "y0" ); - cx->y1 = mlt_properties_get_int( properties, "y1" ); - cx->hints = mlt_properties_get_int( properties, "hints" ); - cx->debug = mlt_properties_get_int( properties, "debug" ); - cx->show = mlt_properties_get_int( properties, "show" ); - } - - // Get the image - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - if ( ! cx->sump ) - { - int guide = mlt_properties_get_int( properties, "guide" ); - cx->cycle = 0; - if ( guide == GUIDE_32 ) - { - // 24fps to 30 fps telecine. - cx->cycle = 5; - } - else if ( guide == GUIDE_22 ) - { - // PAL guidance (expect the current match to be continued). - cx->cycle = 2; - } - else if ( guide == GUIDE_32322 ) - { - // 25fps to 30 fps telecine. - cx->cycle = 6; - } - - cx->xblocks = (*width+BLKSIZE-1) / BLKSIZE; - cx->yblocks = (*height+BLKSIZE-1) / BLKSIZE; - cx->sump = (unsigned int *) mlt_pool_alloc( cx->xblocks * cx->yblocks * sizeof(unsigned int) ); - cx->sumc = (unsigned int *) mlt_pool_alloc( cx->xblocks * cx->yblocks * sizeof(unsigned int) ); - mlt_properties_set_data( properties, "sump", cx->sump, cx->xblocks * cx->yblocks * sizeof(unsigned int), (mlt_destructor)mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "sumc", cx->sumc, cx->xblocks * cx->yblocks * sizeof(unsigned int), (mlt_destructor)mlt_pool_release, NULL ); - cx->tff = mlt_properties_get_int( frame_properties, "top_field_first" ); - // fprintf(stderr, "%s: TOP FIELD FIRST %d\n", __FUNCTION__, cx->tff ); - } - - // Only process if we have no error and a valid colour space - if ( error == 0 && *format == mlt_image_yuv422 ) - { - // Put the current image into the image cache, keyed on position - size_t image_size = (*width * *height) << 1; - mlt_position pos = mlt_frame_get_position( frame ); - uint8_t *image_copy = mlt_pool_alloc( image_size ); - memcpy( image_copy, *image, image_size ); - char key[20]; - sprintf( key, "%d", pos ); - mlt_properties_set_data( cx->image_cache, key, image_copy, image_size, (mlt_destructor)mlt_pool_release, NULL ); - - // Only if we have enough frame images cached - if ( pos > 1 && pos > cx->cycle + 1 ) - { - pos -= cx->cycle + 1; - // Get the current frame image - sprintf( key, "%d", pos ); - cx->fcrp = mlt_properties_get_data( cx->image_cache, key, NULL ); - if (!cx->fcrp) return error; - - // Get the previous frame image - cx->pframe = pos == 0 ? 0 : pos - 1; - sprintf( key, "%d", cx->pframe ); - cx->fprp = mlt_properties_get_data( cx->image_cache, key, NULL ); - if (!cx->fprp) return error; - - // Get the next frame image - cx->nframe = pos > cx->out ? cx->out : pos + 1; - sprintf( key, "%d", cx->nframe ); - cx->fnrp = mlt_properties_get_data( cx->image_cache, key, NULL ); - if (!cx->fnrp) return error; - - cx->pitch = *width << 1; - cx->pitchover2 = cx->pitch >> 1; - cx->pitchtimes4 = cx->pitch << 2; - cx->w = *width << 1; - cx->h = *height; - if ((cx->w/2) & 1) - fprintf( stderr, "%s: width must be a multiple of 2\n", __FUNCTION__ ); - if (cx->h & 1) - fprintf( stderr, "%s: height must be a multiple of 2\n", __FUNCTION__ ); - cx->wover2 = cx->w/2; - cx->hover2 = cx->h/2; - cx->hplus1over2 = (cx->h+1)/2; - cx->hminus2 = cx->h - 2; - cx->dpitch = cx->pitch; - - // Ensure that the metrics for the frames - // after the current frame are in the cache. They will be used for - // pattern guidance. - if ( cx->guide ) - { - for ( cx->y = pos + 1; (cx->y <= pos + cx->cycle + 1) && (cx->y <= cx->out); cx->y++ ) - { - if ( ! CacheQuery( cx, cx->y, &cx->p, &cx->pblock, &cx->c, &cx->cblock ) ) - { - sprintf( key, "%d", cx->y ); - cx->crp = (unsigned char *) mlt_properties_get_data( cx->image_cache, key, NULL ); - sprintf( key, "%d", cx->y ? cx->y - 1 : 1 ); - cx->prp = (unsigned char *) mlt_properties_get_data( cx->image_cache, key, NULL ); - CalculateMetrics( cx, cx->y, cx->crp, NULL, NULL, cx->prp, NULL, NULL ); } - } - } - - // Check for manual overrides of the field matching. - cx->found = 0; - cx->film = 1; - cx->override = 0; - cx->inpattern = 0; - cx->vthresh = cx->vthresh; - cx->back = cx->back_saved; - - // Get the metrics for the current-previous (p), current-current (c), and current-next (n) match candidates. - if ( ! CacheQuery( cx, pos, &cx->p, &cx->pblock, &cx->c, &cx->cblock ) ) - { - CalculateMetrics( cx, pos, cx->fcrp, NULL, NULL, cx->fprp, NULL, NULL ); - CacheQuery( cx, pos, &cx->p, &cx->pblock, &cx->c, &cx->cblock ); - } - if ( ! CacheQuery( cx, cx->nframe, &cx->np, &cx->npblock, &cx->nc, &cx->ncblock ) ) - { - CalculateMetrics( cx, cx->nframe, cx->fnrp, NULL, NULL, cx->fcrp, NULL, NULL ); - CacheQuery( cx, cx->nframe, &cx->np, &cx->npblock, &cx->nc, &cx->ncblock ); - } - - // Determine the best candidate match. - if ( !cx->found ) - { - cx->lowest = cx->c; - cx->chosen = C; - if ( cx->back == ALWAYS_BACK && cx->p < cx->lowest ) - { - cx->lowest = cx->p; - cx->chosen = P; - } - if ( cx->np < cx->lowest ) - { - cx->lowest = cx->np; - cx->chosen = N; - } - } - if ((pos == 0 && cx->chosen == P) || (pos == cx->out && cx->chosen == N)) - { - cx->chosen = C; - cx->lowest = cx->c; - } - - // See if we can apply pattern guidance. - cx->mismatch = 100.0; - if ( cx->guide ) - { - cx->hard = 0; - if ( pos >= cx->cycle && PredictHardYUY2( cx, pos, &cx->predicted, &cx->predicted_metric) ) - { - cx->inpattern = 1; - cx->mismatch = 0.0; - cx->hard = 1; - if ( cx->chosen != cx->predicted ) - { - // The chosen frame doesn't match the prediction. - if ( cx->predicted_metric == 0 ) - cx->mismatch = 0.0; - else - cx->mismatch = (100.0 * abs( cx->predicted_metric - cx->lowest ) ) / cx->predicted_metric; - if ( cx->mismatch < cx->gthresh ) - { - // It's close enough, so use the predicted one. - if ( !cx->found ) - { - cx->chosen = cx->predicted; - cx->override = 1; - } - } - else - { - cx->hard = 0; - cx->inpattern = 0; - } - } - } - - if ( !cx->hard && cx->guide != GUIDE_22 ) - { - int i; - struct PREDICTION *pred = PredictSoftYUY2( cx, pos ); - - if ( ( pos <= cx->out - cx->cycle) && ( pred[0].metric != 0xffffffff ) ) - { - // Apply pattern guidance. - // If the predicted match metric is within defined percentage of the - // best calculated one, then override the calculated match with the - // predicted match. - i = 0; - while ( pred[i].metric != 0xffffffff ) - { - cx->predicted = pred[i].predicted; - cx->predicted_metric = pred[i].predicted_metric; -#ifdef DEBUG_PATTERN_GUIDANCE - fprintf(stderr, "%s: pos=%d predicted=%d\n", __FUNCTION__, pos, cx->predicted); -#endif - if ( cx->chosen != cx->predicted ) - { - // The chosen frame doesn't match the prediction. - if ( cx->predicted_metric == 0 ) - cx->mismatch = 0.0; - else - cx->mismatch = (100.0 * abs( cx->predicted_metric - cx->lowest )) / cx->predicted_metric; - if ( (int) cx->mismatch <= cx->gthresh ) - { - // It's close enough, so use the predicted one. - if ( !cx->found ) - { - cx->chosen = cx->predicted; - cx->override = 1; - } - cx->inpattern = 1; - break; - } - else - { - // Looks like we're not in a predictable pattern. - cx->inpattern = 0; - } - } - else - { - cx->inpattern = 1; - cx->mismatch = 0.0; - break; - } - i++; - } - } - } - } - - // Check the match for progressive versus interlaced. - if ( cx->post ) - { - if (cx->chosen == P) cx->vmetric = cx->pblock; - else if (cx->chosen == C) cx->vmetric = cx->cblock; - else if (cx->chosen == N) cx->vmetric = cx->npblock; - - if ( !cx->found && cx->back == BACK_ON_COMBED && cx->vmetric > cx->bthresh && cx->p < cx->lowest ) - { - // Backward match. - cx->vmetric = cx->pblock; - cx->chosen = P; - cx->inpattern = 0; - cx->mismatch = 100; - } - if ( cx->vmetric > cx->vthresh ) - { - // After field matching and pattern guidance the frame is still combed. - cx->film = 0; - if ( !cx->found && ( cx->post == POST_FULL_NOMATCH || cx->post == POST_FULL_NOMATCH_MAP ) ) - { - cx->chosen = C; - cx->vmetric = cx->cblock; - cx->inpattern = 0; - cx->mismatch = 100; - } - } - } - cx->vthresh = cx->vthresh_saved; - - // Setup strings for debug info. - if ( cx->inpattern && !cx->override ) strcpy( cx->status, "[in-pattern]" ); - else if ( cx->inpattern && cx->override ) strcpy( cx->status, "[in-pattern*]" ); - else strcpy( cx->status, "[out-of-pattern]" ); - - // Assemble and output the reconstructed frame according to the final match. - cx->dstp = *image; - if ( cx->chosen == N ) - { - // The best match was with the next frame. - if ( cx->tff ) - { - BitBlt( cx->dstp, 2 * cx->dpitch, cx->fnrp, 2 * cx->pitch, cx->w, cx->hover2 ); - BitBlt( cx->dstp + cx->dpitch, 2 * cx->dpitch, cx->fcrp + cx->pitch, 2 * cx->pitch, cx->w, cx->hover2 ); - } - else - { - BitBlt( cx->dstp, 2 * cx->dpitch, cx->fcrp, 2 * cx->pitch, cx->w, cx->hplus1over2 ); - BitBlt( cx->dstp + cx->dpitch, 2 * cx->dpitch, cx->fnrp + cx->pitch, 2 * cx->pitch, cx->w, cx->hover2 ); - } - } - else if ( cx->chosen == C ) - { - // The best match was with the current frame. - BitBlt( cx->dstp, 2 * cx->dpitch, cx->fcrp, 2 * cx->pitch, cx->w, cx->hplus1over2 ); - BitBlt( cx->dstp + cx->dpitch, 2 * cx->dpitch, cx->fcrp + cx->pitch, 2 * cx->pitch, cx->w, cx->hover2 ); - } - else if ( ! cx->tff ) - { - // The best match was with the previous frame. - BitBlt( cx->dstp, 2 * cx->dpitch, cx->fprp, 2 * cx->pitch, cx->w, cx->hplus1over2 ); - BitBlt( cx->dstp + cx->dpitch, 2 * cx->dpitch, cx->fcrp + cx->pitch, 2 * cx->pitch, cx->w, cx->hover2 ); - } - else - { - // The best match was with the previous frame. - BitBlt( cx->dstp, 2 * cx->dpitch, cx->fcrp, 2 * cx->pitch, cx->w, cx->hplus1over2 ); - BitBlt( cx->dstp + cx->dpitch, 2 * cx->dpitch, cx->fprp + cx->pitch, 2 * cx->pitch, cx->w, cx->hover2 ); - } - if ( cx->guide ) - PutChosen( cx, pos, cx->chosen ); - - if ( !cx->post || cx->post == POST_METRICS ) - { - if ( cx->force == '+') cx->film = 0; - else if ( cx->force == '-' ) cx->film = 1; - } - else if ((cx->force == '+') || - ((cx->post == POST_FULL || cx->post == POST_FULL_MAP || cx->post == POST_FULL_NOMATCH || cx->post == POST_FULL_NOMATCH_MAP) - && (cx->film == 0 && cx->force != '-'))) - { - unsigned char *dstpp, *dstpn; - int v1, v2; - - if ( cx->blend ) - { - // Do first and last lines. - uint8_t *final = mlt_pool_alloc( image_size ); - cx->finalp = final; - mlt_properties_set_data( frame_properties, "image", final, image_size, (mlt_destructor)mlt_pool_release, NULL ); - dstpn = cx->dstp + cx->dpitch; - for ( cx->x = 0; cx->x < cx->w; cx->x++ ) - { - cx->finalp[cx->x] = (((int)cx->dstp[cx->x] + (int)dstpn[cx->x]) >> 1); - } - cx->finalp = final + (cx->h-1)*cx->dpitch; - cx->dstp = *image + (cx->h-1)*cx->dpitch; - dstpp = cx->dstp - cx->dpitch; - for ( cx->x = 0; cx->x < cx->w; cx->x++ ) - { - cx->finalp[cx->x] = (((int)cx->dstp[cx->x] + (int)dstpp[cx->x]) >> 1); - } - // Now do the rest. - cx->dstp = *image + cx->dpitch; - dstpp = cx->dstp - cx->dpitch; - dstpn = cx->dstp + cx->dpitch; - cx->finalp = final + cx->dpitch; - for ( cx->y = 1; cx->y < cx->h - 1; cx->y++ ) - { - for ( cx->x = 0; cx->x < cx->w; cx->x++ ) - { - v1 = (int) cx->dstp[cx->x] - cx->dthresh; - if ( v1 < 0 ) - v1 = 0; - v2 = (int) cx->dstp[cx->x] + cx->dthresh; - if (v2 > 235) v2 = 235; - if ((v1 > dstpp[cx->x] && v1 > dstpn[cx->x]) || (v2 < dstpp[cx->x] && v2 < dstpn[cx->x])) - { - if ( cx->post == POST_FULL_MAP || cx->post == POST_FULL_NOMATCH_MAP ) - { - if (cx->x & 1) cx->finalp[cx->x] = 128; - else cx->finalp[cx->x] = 235; - } - else - cx->finalp[cx->x] = ((int)dstpp[cx->x] + (int)dstpn[cx->x] + (int)cx->dstp[cx->x] + (int)cx->dstp[cx->x]) >> 2; - } - else cx->finalp[cx->x] = cx->dstp[cx->x]; - } - cx->finalp += cx->dpitch; - cx->dstp += cx->dpitch; - dstpp += cx->dpitch; - dstpn += cx->dpitch; - } - - - if (cx->show ) Show( cx, pos, frame_properties); - if (cx->debug) Debug(cx, pos); - if (cx->hints) WriteHints(cx->film, cx->inpattern, frame_properties); - goto final; - } - - // Interpolate mode. - cx->dstp = *image + cx->dpitch; - dstpp = cx->dstp - cx->dpitch; - dstpn = cx->dstp + cx->dpitch; - for ( cx->y = 1; cx->y < cx->h - 1; cx->y+=2 ) - { - for ( cx->x = 0; cx->x < cx->w; cx->x++ ) - { - v1 = (int) cx->dstp[cx->x] - cx->dthresh; - if (v1 < 0) v1 = 0; - v2 = (int) cx->dstp[cx->x] + cx->dthresh; - if (v2 > 235) v2 = 235; - if ((v1 > dstpp[cx->x] && v1 > dstpn[cx->x]) || (v2 < dstpp[cx->x] && v2 < dstpn[cx->x])) - { - if ( cx->post == POST_FULL_MAP || cx->post == POST_FULL_NOMATCH_MAP ) - { - if (cx->x & 1) cx->dstp[cx->x] = 128; - else cx->dstp[cx->x] = 235; - } - else - cx->dstp[cx->x] = (dstpp[cx->x] + dstpn[cx->x]) >> 1; - } - } - cx->dstp += 2 * cx->dpitch; - dstpp += 2 * cx->dpitch; - dstpn += 2 * cx->dpitch; - } - } - if (cx->show ) Show( cx, pos, frame_properties); - if (cx->debug) Debug(cx, pos); - if (cx->hints) WriteHints(cx->film, cx->inpattern, frame_properties); - -final: - // Flush frame at tail of period from the cache - sprintf( key, "%d", pos - 1 ); - mlt_properties_set_data( cx->image_cache, key, NULL, 0, NULL, NULL ); - } - else - { - // Signal the first {cycle} frames as invalid - mlt_properties_set_int( frame_properties, "garbage", 1 ); - } - } - else if ( error == 0 && *format == mlt_image_yuv420p ) - { - fprintf(stderr,"%s: %d pos %d\n", __FUNCTION__, *width * *height * 3/2, mlt_frame_get_position(frame) ); - } - - return error; -} - -/** Process the frame object. -*/ - -static mlt_frame process( mlt_filter this, mlt_frame frame ) -{ - // Push the filter on to the stack - mlt_frame_push_service( frame, this ); - - // Push the frame filter - mlt_frame_push_get_image( frame, get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_telecide_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = process; - - // Allocate the context and set up for garbage collection - context cx = (context) mlt_pool_alloc( sizeof(struct context_s) ); - memset( cx, 0, sizeof( struct context_s ) ); - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - mlt_properties_set_data( properties, "context", cx, sizeof(struct context_s), (mlt_destructor)mlt_pool_release, NULL ); - - // Allocate the metrics cache and set up for garbage collection - cx->cache = (struct CACHE_ENTRY *) mlt_pool_alloc(CACHE_SIZE * sizeof(struct CACHE_ENTRY )); - mlt_properties_set_data( properties, "cache", cx->cache, CACHE_SIZE * sizeof(struct CACHE_ENTRY), (mlt_destructor)mlt_pool_release, NULL ); - int i; - for (i = 0; i < CACHE_SIZE; i++) - { - cx->cache[i].frame = 0xffffffff; - cx->cache[i].chosen = 0xff; - } - - // Allocate the image cache and set up for garbage collection - cx->image_cache = mlt_properties_new(); - mlt_properties_set_data( properties, "image_cache", cx->image_cache, 0, (mlt_destructor)mlt_properties_close, NULL ); - - // Initialize the parameter defaults - mlt_properties_set_int( properties, "guide", 0 ); - mlt_properties_set_int( properties, "back", 0 ); - mlt_properties_set_int( properties, "chroma", 0 ); - mlt_properties_set_int( properties, "post", POST_FULL ); - mlt_properties_set_double( properties, "gthresh", 10.0 ); - mlt_properties_set_double( properties, "vthresh", 50.0 ); - mlt_properties_set_double( properties, "bthresh", 50.0 ); - mlt_properties_set_double( properties, "dthresh", 7.0 ); - mlt_properties_set_int( properties, "blend", 0 ); - mlt_properties_set_int( properties, "nt", 10 ); - mlt_properties_set_int( properties, "y0", 0 ); - mlt_properties_set_int( properties, "y1", 0 ); - mlt_properties_set_int( properties, "hints", 1 ); - } - return this; -} - diff --git a/src/modules/dgraft/gpl b/src/modules/dgraft/gpl deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/dv/Makefile b/src/modules/dv/Makefile deleted file mode 100644 index 8c5ef1b..0000000 --- a/src/modules/dv/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltdv$(LIBSUF) - -OBJS = factory.o \ - producer_libdv.o \ - consumer_libdv.o - -CFLAGS += -I../.. -CFLAGS += `pkg-config --cflags libdv` - -LDFLAGS += -L../../framework -lmlt -LDFLAGS += `pkg-config --libs libdv` - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/dv/configure b/src/modules/dv/configure deleted file mode 100755 index 6712ea6..0000000 --- a/src/modules/dv/configure +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - - pkg-config libdv 2> /dev/null - disable_libdv=$? - - if [ "$disable_libdv" != "0" ] - then - echo "- libdv not found: disabling" - touch ../disable-dv - exit 0 - fi - -fi - diff --git a/src/modules/dv/consumer_libdv.c b/src/modules/dv/consumer_libdv.c deleted file mode 100644 index 2ee9b20..0000000 --- a/src/modules/dv/consumer_libdv.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * consumer_libdv.c -- a DV encoder based on libdv - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// mlt Header files -#include -#include - -// System header files -#include -#include -#include -#include - -// libdv header files -#include - -#define FRAME_SIZE_525_60 10 * 150 * 80 -#define FRAME_SIZE_625_50 12 * 150 * 80 - -// Forward references. -static int consumer_start( mlt_consumer this ); -static int consumer_stop( mlt_consumer this ); -static int consumer_is_stopped( mlt_consumer this ); -static int consumer_encode_video( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame ); -static void consumer_encode_audio( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame ); -static void consumer_output( mlt_consumer this, uint8_t *dv_frame, int size, mlt_frame frame ); -static void *consumer_thread( void *arg ); -static void consumer_close( mlt_consumer this ); - -/** Initialise the dv consumer. -*/ - -mlt_consumer consumer_libdv_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Allocate the consumer - mlt_consumer this = calloc( 1, sizeof( struct mlt_consumer_s ) ); - - // If memory allocated and initialises without error - if ( this != NULL && mlt_consumer_init( this, NULL, profile ) == 0 ) - { - // Get properties from the consumer - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Assign close callback - this->close = consumer_close; - - // Interpret the argument - if ( arg != NULL ) - mlt_properties_set( properties, "target", arg ); - - // Set the encode and output handling method - mlt_properties_set_data( properties, "video", consumer_encode_video, 0, NULL, NULL ); - mlt_properties_set_data( properties, "audio", consumer_encode_audio, 0, NULL, NULL ); - mlt_properties_set_data( properties, "output", consumer_output, 0, NULL, NULL ); - - // Terminate at end of the stream by default - mlt_properties_set_int( properties, "terminate_on_pause", 1 ); - - // Set up start/stop/terminated callbacks - this->start = consumer_start; - this->stop = consumer_stop; - this->is_stopped = consumer_is_stopped; - } - else - { - // Clean up in case of init failure - free( this ); - this = NULL; - } - - // Return this - return this; -} - -/** Start the consumer. -*/ - -static int consumer_start( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Check that we're not already running - if ( !mlt_properties_get_int( properties, "running" ) ) - { - // Allocate a thread - pthread_t *thread = calloc( 1, sizeof( pthread_t ) ); - - // Assign the thread to properties - mlt_properties_set_data( properties, "thread", thread, sizeof( pthread_t ), free, NULL ); - - // Set the running state - mlt_properties_set_int( properties, "running", 1 ); - - // Create the thread - pthread_create( thread, NULL, consumer_thread, this ); - } - return 0; -} - -/** Stop the consumer. -*/ - -static int consumer_stop( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Check that we're running - if ( mlt_properties_get_int( properties, "running" ) ) - { - // Get the thread - pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL ); - - // Stop the thread - mlt_properties_set_int( properties, "running", 0 ); - - // Wait for termination - pthread_join( *thread, NULL ); - - // Close the output file :-) - this is obtuse - doesn't matter if output file - // exists or not - the destructor will kick in if it does - mlt_properties_set_data( properties, "output_file", NULL, 0, NULL, NULL ); - } - - return 0; -} - -/** Determine if the consumer is stopped. -*/ - -static int consumer_is_stopped( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - return !mlt_properties_get_int( properties, "running" ); -} - -/** Get or create a new libdv encoder. -*/ - -static dv_encoder_t *libdv_get_encoder( mlt_consumer this, mlt_frame frame ) -{ - // Get the properties of the consumer - mlt_properties this_properties = MLT_CONSUMER_PROPERTIES( this ); - - // Obtain the dv_encoder - dv_encoder_t *encoder = mlt_properties_get_data( this_properties, "dv_encoder", NULL ); - - // Construct one if we don't have one - if ( encoder == NULL ) - { - // Get the fps of the consumer (for now - should be from frame) - double fps = mlt_properties_get_double( this_properties, "fps" ); - - // Create the encoder - encoder = dv_encoder_new( 0, 0, 0 ); - - // Encoder settings - encoder->isPAL = fps == 25; - encoder->is16x9 = 0; - encoder->vlc_encode_passes = 1; - encoder->static_qno = 0; - encoder->force_dct = DV_DCT_AUTO; - - // Store the encoder on the properties - mlt_properties_set_data( this_properties, "dv_encoder", encoder, 0, ( mlt_destructor )dv_encoder_free, NULL ); - } - - // Return the encoder - return encoder; -} - - -/** The libdv encode video method. -*/ - -static int consumer_encode_video( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame ) -{ - // Obtain the dv_encoder - dv_encoder_t *encoder = libdv_get_encoder( this, frame ); - - // Get the properties of the consumer - mlt_properties this_properties = MLT_CONSUMER_PROPERTIES( this ); - - // This will hold the size of the dv frame - int size = 0; - - // Is the image rendered - int rendered = mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "rendered" ); - - // Get width and height - int width = mlt_properties_get_int( this_properties, "width" ); - int height = mlt_properties_get_int( this_properties, "height" ); - - // If we get an encoder, then encode the image - if ( rendered && encoder != NULL ) - { - // Specify desired image properties - mlt_image_format fmt = mlt_image_yuv422; - uint8_t *image = NULL; - - // Get the image - mlt_events_fire( this_properties, "consumer-frame-show", frame, NULL ); - mlt_frame_get_image( frame, &image, &fmt, &width, &height, 0 ); - - // Check that we get what we expected - if ( fmt != mlt_image_yuv422 || - width != mlt_properties_get_int( this_properties, "width" ) || - height != mlt_properties_get_int( this_properties, "height" ) || - image == NULL ) - { - // We should try to recover here - fprintf( stderr, "We have a problem houston...\n" ); - } - else - { - // Calculate the size of the dv frame - size = height == 576 ? FRAME_SIZE_625_50 : FRAME_SIZE_525_60; - } - - // Process the frame - if ( size != 0 ) - { - // Encode the image - dv_encode_full_frame( encoder, &image, e_dv_color_yuv, dv_frame ); - } - } - else if ( encoder != NULL ) - { - // Calculate the size of the dv frame (duplicate of previous) - size = height == 576 ? FRAME_SIZE_625_50 : FRAME_SIZE_525_60; - } - - return size; -} - -/** The libdv encode audio method. -*/ - -static void consumer_encode_audio( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame ) -{ - // Get the properties of the consumer - mlt_properties this_properties = MLT_CONSUMER_PROPERTIES( this ); - - // Get the properties of the frame - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the dv_encoder - dv_encoder_t *encoder = libdv_get_encoder( this, frame ); - - // Only continue if we have an encoder - if ( encoder != NULL ) - { - // Get the frame count - int count = mlt_properties_get_int( this_properties, "count" ); - - // Default audio args - mlt_audio_format fmt = mlt_audio_pcm; - int channels = 2; - int frequency = mlt_properties_get_int( this_properties, "frequency" ); - int samples = mlt_sample_calculator( mlt_properties_get_double( this_properties, "fps" ), frequency, count ); - int16_t *pcm = NULL; - - // Get the frame number - time_t start = time( NULL ); - int height = mlt_properties_get_int( this_properties, "height" ); - int is_pal = height == 576; - int is_wide = mlt_properties_get_int( this_properties, "display_aspect_num" ) == 16; - - // Temporary - audio buffer allocation - int16_t *audio_buffers[ 4 ]; - int i = 0; - int j = 0; - for ( i = 0 ; i < 4; i ++ ) - audio_buffers[ i ] = mlt_pool_alloc( 2 * DV_AUDIO_MAX_SAMPLES ); - - // Get the audio - mlt_frame_get_audio( frame, &pcm, &fmt, &frequency, &channels, &samples ); - - // Inform the encoder of the number of audio samples - encoder->samples_this_frame = samples; - - // Fill the audio buffers correctly - if ( mlt_properties_get_double( frame_properties, "_speed" ) == 1.0 ) - { - for ( i = 0; i < samples; i ++ ) - for ( j = 0; j < channels; j++ ) - audio_buffers[ j ][ i ] = *pcm ++; - } - else - { - for ( j = 0; j < channels; j++ ) - memset( audio_buffers[ j ], 0, 2 * DV_AUDIO_MAX_SAMPLES ); - } - - // Encode audio on frame - dv_encode_full_audio( encoder, audio_buffers, channels, frequency, dv_frame ); - - // Specify meta data on the frame - dv_encode_metadata( dv_frame, is_pal, is_wide, &start, count ); - dv_encode_timecode( dv_frame, is_pal, count ); - - // Update properties - mlt_properties_set_int( this_properties, "count", ++ count ); - - // Temporary - free audio buffers - for ( i = 0 ; i < 4; i ++ ) - mlt_pool_release( audio_buffers[ i ] ); - } -} - -/** The libdv output method. -*/ - -static void consumer_output( mlt_consumer this, uint8_t *dv_frame, int size, mlt_frame frame ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - FILE *output = stdout; - char *target = mlt_properties_get( properties, "target" ); - - if ( target != NULL ) - { - output = mlt_properties_get_data( properties, "output_file", NULL ); - if ( output == NULL ) - { - output = fopen( target, "w" ); - if ( output != NULL ) - mlt_properties_set_data( properties, "output_file", output, 0, ( mlt_destructor )fclose, 0 ); - } - } - - if ( output != NULL ) - { - fwrite( dv_frame, size, 1, output ); - fflush( output ); - } - else - { - fprintf( stderr, "Unable to open %s\n", target ); - } -} - -/** The main thread - the argument is simply the consumer. -*/ - -static void *consumer_thread( void *arg ) -{ - // Map the argument to the object - mlt_consumer this = arg; - - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Get the terminate_on_pause property - int top = mlt_properties_get_int( properties, "terminate_on_pause" ); - - // Get the handling methods - int ( *video )( mlt_consumer, uint8_t *, mlt_frame ) = mlt_properties_get_data( properties, "video", NULL ); - int ( *audio )( mlt_consumer, uint8_t *, mlt_frame ) = mlt_properties_get_data( properties, "audio", NULL ); - int ( *output )( mlt_consumer, uint8_t *, int, mlt_frame ) = mlt_properties_get_data( properties, "output", NULL ); - - // Allocate a single PAL frame for encoding - uint8_t *dv_frame = mlt_pool_alloc( FRAME_SIZE_625_50 ); - - // Frame and size - mlt_frame frame = NULL; - int size = 0; - - // Loop while running - while( mlt_properties_get_int( properties, "running" ) ) - { - // Get the frame - frame = mlt_consumer_rt_frame( this ); - - // Check that we have a frame to work with - if ( frame != NULL ) - { - // Terminate on pause - if ( top && mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ) == 0 ) - { - mlt_frame_close( frame ); - break; - } - - // Obtain the dv_encoder - if ( libdv_get_encoder( this, frame ) != NULL ) - { - // Encode the image - size = video( this, dv_frame, frame ); - - // Encode the audio - if ( size > 0 ) - audio( this, dv_frame, frame ); - - // Output the frame - output( this, dv_frame, size, frame ); - - // Close the frame - mlt_frame_close( frame ); - } - else - { - fprintf( stderr, "Unable to obtain dv encoder.\n" ); - } - } - } - - // Tidy up - mlt_pool_release( dv_frame ); - - mlt_consumer_stopped( this ); - - return NULL; -} - -/** Close the consumer. -*/ - -static void consumer_close( mlt_consumer this ) -{ - // Stop the consumer - mlt_consumer_stop( this ); - - // Close the parent - mlt_consumer_close( this ); - - // Free the memory - free( this ); -} diff --git a/src/modules/dv/factory.c b/src/modules/dv/factory.c deleted file mode 100644 index 305fb9c..0000000 --- a/src/modules/dv/factory.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include - -extern mlt_consumer consumer_libdv_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_libdv_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( consumer_type, "libdv", consumer_libdv_init ); - MLT_REGISTER( producer_type, "libdv", producer_libdv_init ); -} diff --git a/src/modules/dv/producer_libdv.c b/src/modules/dv/producer_libdv.c deleted file mode 100644 index 6fd012c..0000000 --- a/src/modules/dv/producer_libdv.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * producer_libdv.c -- simple libdv test case - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define FRAME_SIZE_525_60 10 * 150 * 80 -#define FRAME_SIZE_625_50 12 * 150 * 80 - -/** To conserve resources, we maintain a stack of dv decoders. -*/ - -static pthread_mutex_t decoder_lock = PTHREAD_MUTEX_INITIALIZER; -static mlt_properties dv_decoders = NULL; - -dv_decoder_t *dv_decoder_alloc( ) -{ - // We'll return a dv_decoder - dv_decoder_t *this = NULL; - - // Lock the mutex - pthread_mutex_lock( &decoder_lock ); - - // Create the properties if necessary - if ( dv_decoders == NULL ) - { - // Create the properties - dv_decoders = mlt_properties_new( ); - - // Create the stack - mlt_properties_set_data( dv_decoders, "stack", mlt_deque_init( ), 0, ( mlt_destructor )mlt_deque_close, NULL ); - - // Register the properties for clean up - mlt_factory_register_for_clean_up( dv_decoders, ( mlt_destructor )mlt_properties_close ); - } - - // Now try to obtain a decoder - if ( dv_decoders != NULL ) - { - // Obtain the stack - mlt_deque stack = mlt_properties_get_data( dv_decoders, "stack", NULL ); - - // Pop the top of the stack - this = mlt_deque_pop_back( stack ); - - // Create a new decoder if none available - if ( this == NULL ) - { - // We'll need a unique property ID for this - char label[ 256 ]; - - // Configure the decoder - this = dv_decoder_new( FALSE, FALSE, FALSE ); - this->quality = DV_QUALITY_COLOR | DV_QUALITY_AC_2; - this->audio->arg_audio_emphasis = 2; - dv_set_audio_correction( this, DV_AUDIO_CORRECT_AVERAGE ); - dv_set_error_log( this, NULL ); - - // Register it with the properties to ensure clean up - sprintf( label, "%p", this ); - mlt_properties_set_data( dv_decoders, label, this, 0, ( mlt_destructor )dv_decoder_free, NULL ); - } - } - - // Unlock the mutex - pthread_mutex_unlock( &decoder_lock ); - - return this; -} - -void dv_decoder_return( dv_decoder_t *this ) -{ - // Lock the mutex - pthread_mutex_lock( &decoder_lock ); - - // Now try to return the decoder - if ( dv_decoders != NULL ) - { - // Obtain the stack - mlt_deque stack = mlt_properties_get_data( dv_decoders, "stack", NULL ); - - // Push it back - mlt_deque_push_back( stack, this ); - } - - // Unlock the mutex - pthread_mutex_unlock( &decoder_lock ); -} - - -typedef struct producer_libdv_s *producer_libdv; - -struct producer_libdv_s -{ - struct mlt_producer_s parent; - int fd; - int is_pal; - uint64_t file_size; - int frame_size; - long frames_in_file; - mlt_producer alternative; -}; - -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer parent ); - -static int producer_collect_info( producer_libdv this, mlt_profile profile ); - -mlt_producer producer_libdv_init( mlt_profile profile, mlt_service_type type, const char *id, char *filename ) -{ - producer_libdv this = calloc( sizeof( struct producer_libdv_s ), 1 ); - - if ( filename != NULL && this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) - { - int destroy = 0; - mlt_producer producer = &this->parent; - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Set the resource property (required for all producers) - mlt_properties_set( properties, "resource", filename ); - - // Register transport implementation with the producer - producer->close = ( mlt_destructor )producer_close; - - // Register our get_frame implementation with the producer - producer->get_frame = producer_get_frame; - - // If we have mov or dv, then we'll use an alternative producer - if ( strchr( filename, '.' ) != NULL && ( - strncasecmp( strrchr( filename, '.' ), ".avi", 4 ) == 0 || - strncasecmp( strrchr( filename, '.' ), ".mov", 4 ) == 0 ) ) - { - // Load via an alternative mechanism - mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ); - this->alternative = mlt_factory_producer( profile, "kino", filename ); - - // If it's unavailable, then clean up - if ( this->alternative == NULL ) - destroy = 1; - else - mlt_properties_pass( properties, MLT_PRODUCER_PROPERTIES( this->alternative ), "" ); - this->is_pal = ( ( int ) mlt_producer_get_fps( producer ) ) == 25; - } - else - { - // Open the file if specified - this->fd = open( filename, O_RDONLY ); - - // Collect info - if ( this->fd == -1 || !producer_collect_info( this, profile ) ) - destroy = 1; - } - - // If we couldn't open the file, then destroy it now - if ( destroy ) - { - mlt_producer_close( producer ); - producer = NULL; - } - - // Return the producer - return producer; - } - free( this ); - return NULL; -} - -static int read_frame( int fd, uint8_t* frame_buf, int *isPAL ) -{ - int result = read( fd, frame_buf, FRAME_SIZE_525_60 ) == FRAME_SIZE_525_60; - if ( result ) - { - *isPAL = ( frame_buf[3] & 0x80 ); - if ( *isPAL ) - { - int diff = FRAME_SIZE_625_50 - FRAME_SIZE_525_60; - result = read( fd, frame_buf + FRAME_SIZE_525_60, diff ) == diff; - } - } - - return result; -} - -static int producer_collect_info( producer_libdv this, mlt_profile profile ) -{ - int valid = 0; - - uint8_t *dv_data = mlt_pool_alloc( FRAME_SIZE_625_50 ); - - if ( dv_data != NULL ) - { - // Read the first frame - valid = read_frame( this->fd, dv_data, &this->is_pal ); - - // If it looks like a valid frame, the get stats - if ( valid ) - { - // Get the properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( &this->parent ); - - // Get a dv_decoder - dv_decoder_t *dv_decoder = dv_decoder_alloc( ); - - // Determine the file size - struct stat buf; - fstat( this->fd, &buf ); - - // Store the file size - this->file_size = buf.st_size; - - // Determine the frame size - this->frame_size = this->is_pal ? FRAME_SIZE_625_50 : FRAME_SIZE_525_60; - - // Determine the number of frames in the file - this->frames_in_file = this->file_size / this->frame_size; - - // Calculate default in/out points - int fps = 1000 * ( this->is_pal ? 25 : ( 30000.0 / 1001.0 ) ); - if ( ( int )( mlt_profile_fps( profile ) * 1000 ) == fps ) - { - if ( this->frames_in_file > 0 ) - { - mlt_properties_set_position( properties, "length", this->frames_in_file ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", this->frames_in_file - 1 ); - } - } - else - { - valid = 0; - } - - // Parse the header for meta info - dv_parse_header( dv_decoder, dv_data ); - mlt_properties_set_double( properties, "aspect_ratio", - dv_format_wide( dv_decoder ) ? ( this->is_pal ? 118.0/81.0 : 40.0/33.0 ) : ( this->is_pal ? 59.0/54.0 : 10.0/11.0 ) ); - mlt_properties_set_double( properties, "source_fps", this->is_pal ? 25 : ( 30000.0 / 1001.0 ) ); - mlt_properties_set_int( properties, "meta.media.nb_streams", 2 ); - mlt_properties_set_int( properties, "video_index", 0 ); - mlt_properties_set( properties, "meta.media.0.stream.type", "video" ); - mlt_properties_set( properties, "meta.media.0.codec.name", "dvvideo" ); - mlt_properties_set( properties, "meta.media.0.codec.long_name", "DV (Digital Video)" ); - mlt_properties_set_int( properties, "audio_index", 1 ); - mlt_properties_set( properties, "meta.media.1.stream.type", "audio" ); - mlt_properties_set( properties, "meta.media.1.codec.name", "pcm_s16le" ); - mlt_properties_set( properties, "meta.media.1.codec.long_name", "signed 16-bit little-endian PCM" ); - - // Return the decoder - dv_decoder_return( dv_decoder ); - } - - mlt_pool_release( dv_data ); - } - - return valid; -} - -static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - int pitches[3] = { 0, 0, 0 }; - uint8_t *pixels[3] = { NULL, NULL, NULL }; - - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get a dv_decoder - dv_decoder_t *decoder = dv_decoder_alloc( ); - - // Get the dv data - uint8_t *dv_data = mlt_properties_get_data( properties, "dv_data", NULL ); - - // Get and set the quality request - char *quality = mlt_frame_pop_service( this ); - - if ( quality != NULL ) - { - if ( strncmp( quality, "fast", 4 ) == 0 ) - decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_DC ); - else if ( strncmp( quality, "best", 4 ) == 0 ) - decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_AC_2 ); - else - decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_AC_1 ); - } - - // Parse the header for meta info - dv_parse_header( decoder, dv_data ); - - // Assign width and height according to the frame - *width = 720; - *height = dv_data[ 3 ] & 0x80 ? 576 : 480; - - // Extract an image of the format requested - if ( *format == mlt_image_yuv422 || *format == mlt_image_yuv420p ) - { - // Allocate an image - uint8_t *image = mlt_pool_alloc( *width * ( *height + 1 ) * 2 ); - - // Pass to properties for clean up - mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); - - // Decode the image - pitches[ 0 ] = *width * 2; - pixels[ 0 ] = image; - dv_decode_full_frame( decoder, dv_data, e_dv_color_yuv, pixels, pitches ); - - // Assign result - *buffer = image; - *format = mlt_image_yuv422; - } - else - { - // Allocate an image - uint8_t *image = mlt_pool_alloc( *width * ( *height + 1 ) * 3 ); - - // Pass to properties for clean up - mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 3, ( mlt_destructor )mlt_pool_release, NULL ); - - // Decode the frame - pitches[ 0 ] = 720 * 3; - pixels[ 0 ] = image; - dv_decode_full_frame( decoder, dv_data, e_dv_color_rgb, pixels, pitches ); - - // Assign result - *buffer = image; - *format = mlt_image_rgb24; - } - - // Return the decoder - dv_decoder_return( decoder ); - - return 0; -} - -static int producer_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - int16_t *p; - int i, j; - int16_t *audio_channels[ 4 ]; - - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get a dv_decoder - dv_decoder_t *decoder = dv_decoder_alloc( ); - - // Get the dv data - uint8_t *dv_data = mlt_properties_get_data( properties, "dv_data", NULL ); - - // Parse the header for meta info - dv_parse_header( decoder, dv_data ); - - // Check that we have audio - if ( decoder->audio->num_channels > 0 ) - { - // Obtain required values - *frequency = decoder->audio->frequency; - *samples = decoder->audio->samples_this_frame; - *channels = decoder->audio->num_channels; - - // Create a temporary workspace - for ( i = 0; i < 4; i++ ) - audio_channels[ i ] = mlt_pool_alloc( DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ) ); - - // Create a workspace for the result - *buffer = mlt_pool_alloc( *channels * DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ) ); - - // Pass the allocated audio buffer as a property - mlt_properties_set_data( properties, "audio", *buffer, *channels * DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ), ( mlt_destructor )mlt_pool_release, NULL ); - - // Decode the audio - dv_decode_full_audio( decoder, dv_data, audio_channels ); - - // Interleave the audio - p = *buffer; - for ( i = 0; i < *samples; i++ ) - for ( j = 0; j < *channels; j++ ) - *p++ = audio_channels[ j ][ i ]; - - // Free the temporary work space - for ( i = 0; i < 4; i++ ) - mlt_pool_release( audio_channels[ i ] ); - } - else - { - // No audio available on the frame, so get test audio (silence) - mlt_frame_get_audio( this, buffer, format, frequency, channels, samples ); - } - - // Return the decoder - dv_decoder_return( decoder ); - - return 0; -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Access the private data - producer_libdv this = producer->child; - - // Will carry the frame data - uint8_t *data = NULL; - - // Obtain the current frame number - uint64_t position = mlt_producer_frame( producer ); - - if ( this->alternative == NULL ) - { - // Convert timecode to a file position (ensuring that we're on a frame boundary) - uint64_t offset = position * this->frame_size; - - // Allocate space - data = mlt_pool_alloc( FRAME_SIZE_625_50 ); - - // Create an empty frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - // Seek and fetch - if ( this->fd != 0 && - lseek( this->fd, offset, SEEK_SET ) == offset && - read_frame( this->fd, data, &this->is_pal ) ) - { - // Pass the dv data - mlt_properties_set_data( MLT_FRAME_PROPERTIES( *frame ), "dv_data", data, FRAME_SIZE_625_50, ( mlt_destructor )mlt_pool_release, NULL ); - } - else - { - mlt_pool_release( data ); - data = NULL; - } - } - else - { - // Seek - mlt_producer_seek( this->alternative, position ); - - // Fetch - mlt_service_get_frame( MLT_PRODUCER_SERVICE( this->alternative ), frame, 0 ); - - // Verify - if ( *frame != NULL ) - data = mlt_properties_get_data( MLT_FRAME_PROPERTIES( *frame ), "dv_data", NULL ); - } - - if ( data != NULL ) - { - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Get a dv_decoder - dv_decoder_t *dv_decoder = dv_decoder_alloc( ); - - mlt_properties_set_int( properties, "test_image", 0 ); - mlt_properties_set_int( properties, "test_audio", 0 ); - - // Update other info on the frame - mlt_properties_set_int( properties, "width", 720 ); - mlt_properties_set_int( properties, "height", this->is_pal ? 576 : 480 ); - mlt_properties_set_int( properties, "real_width", 720 ); - mlt_properties_set_int( properties, "real_height", this->is_pal ? 576 : 480 ); - mlt_properties_set_int( properties, "top_field_first", !this->is_pal ? 0 : ( data[ 5 ] & 0x07 ) == 0 ? 0 : 1 ); - - // Parse the header for meta info - dv_parse_header( dv_decoder, data ); - //mlt_properties_set_int( properties, "progressive", dv_is_progressive( dv_decoder ) ); - mlt_properties_set_double( properties, "aspect_ratio", - dv_format_wide( dv_decoder ) ? ( this->is_pal ? 118.0/81.0 : 40.0/33.0 ) : ( this->is_pal ? 59.0/54.0 : 10.0/11.0 ) ); - - - mlt_properties_set_int( properties, "frequency", dv_decoder->audio->frequency ); - mlt_properties_set_int( properties, "channels", dv_decoder->audio->num_channels ); - - // Register audio callback - if ( mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( producer ), "audio_index" ) > 0 ) - mlt_frame_push_audio( *frame, producer_get_audio ); - - if ( mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( producer ), "video_index" ) > -1 ) - { - // Push the quality string - mlt_frame_push_service( *frame, mlt_properties_get( MLT_PRODUCER_PROPERTIES( producer ), "quality" ) ); - - // Push the get_image method on to the stack - mlt_frame_push_get_image( *frame, producer_get_image ); - } - - // Return the decoder - dv_decoder_return( dv_decoder ); - } - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer parent ) -{ - // Obtain this - producer_libdv this = parent->child; - - // Close the file - if ( this->fd > 0 ) - close( this->fd ); - - if ( this->alternative ) - mlt_producer_close( this->alternative ); - - // Close the parent - parent->close = NULL; - mlt_producer_close( parent ); - - // Free the memory - free( this ); -} diff --git a/src/modules/effectv/Makefile b/src/modules/effectv/Makefile deleted file mode 100644 index a8f5f62..0000000 --- a/src/modules/effectv/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmlteffectv$(LIBSUF) - -OBJS = factory.o \ - filter_burn.o \ - image.o \ - utils.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/effectv/factory.c b/src/modules/effectv/factory.c deleted file mode 100644 index e28d765..0000000 --- a/src/modules/effectv/factory.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2007 Stephane Fillod - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -extern mlt_filter filter_burn_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "BurningTV", filter_burn_init ); - MLT_REGISTER( filter_type, "burningtv", filter_burn_init ); -} diff --git a/src/modules/effectv/filter_burn.c b/src/modules/effectv/filter_burn.c deleted file mode 100644 index 967e263..0000000 --- a/src/modules/effectv/filter_burn.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * filter_burn.c -- burning filter - * Copyright (C) 2007 Stephane Fillod - * - * Filter taken from EffecTV - Realtime Digital Video Effector - * Copyright (C) 2001-2006 FUKUCHI Kentaro - * - * BurningTV - burns incoming objects. - * Copyright (C) 2001-2002 FUKUCHI Kentaro - * - * Fire routine is taken from Frank Jan Sorensen's demo program. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -#include -#include -#include -#include -#include "utils.h" - - -#define MaxColor 120 -#define Decay 15 -#define MAGIC_THRESHOLD "50" - -static RGB32 palette[256]; - -/* FIXME: endianess? */ -static void makePalette(void) -{ - int i, r, g, b; - - for(i=0; i> 8)); - i++; - } - i += 2; - } - - mlt_convert_rgb24a_to_yuv422((uint8_t *)dest, *width, *height, *width * sizeof(RGB32), - *image, NULL ); - - mlt_pool_release(dest); - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push the frame filter - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_burn_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "foreground", "0" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "threshold", MAGIC_THRESHOLD ); - } - if (!palette[128]) - { - makePalette(); - } - return this; -} - diff --git a/src/modules/effectv/gpl b/src/modules/effectv/gpl deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/effectv/image.c b/src/modules/effectv/image.c deleted file mode 100644 index ce8157f..0000000 --- a/src/modules/effectv/image.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * EffecTV - Realtime Digital Video Effector - * Copyright (C) 2001-2006 FUKUCHI Kentaro - * - * image.c: utilities for image processing. - * - */ - -#include -#include -#include "utils.h" - - -/* - * Collection of background subtraction functions - */ - -/* checks only fake-Y value */ -/* In these function Y value is treated as R*2+G*4+B. */ - -int image_set_threshold_y(int threshold) -{ - int y_threshold = threshold * 7; /* fake-Y value is timed by 7 */ - - return y_threshold; -} - -void image_bgset_y(RGB32 *background, const RGB32 *src, int video_area, int y_threshold) -{ - int i; - int R, G, B; - const RGB32 *p; - short *q; - - p = src; - q = (short *)background; - for(i=0; i>(16-1); - G = ((*p)&0xff00)>>(8-2); - B = (*p)&0xff; - *q = (short)(R + G + B); - p++; - q++; - } -} - -void image_bgsubtract_y(unsigned char *diff, const RGB32 *background, const RGB32 *src, int video_area, int y_threshold) -{ - int i; - int R, G, B; - const RGB32 *p; - const short *q; - unsigned char *r; - int v; - - p = src; - q = (const short *)background; - r = diff; - for(i=0; i>(16-1); - G = ((*p)&0xff00)>>(8-2); - B = (*p)&0xff; - v = (R + G + B) - (int)(*q); - *r = ((v + y_threshold)>>24) | ((y_threshold - v)>>24); - - p++; - q++; - r++; - } - -/* The origin of subtraction function is; - * diff(src, dest) = (abs(src - dest) > threshold) ? 0xff : 0; - * - * This functions is transformed to; - * (threshold > (src - dest) > -threshold) ? 0 : 0xff; - * - * (v + threshold)>>24 is 0xff when v is less than -threshold. - * (v - threshold)>>24 is 0xff when v is less than threshold. - * So, ((v + threshold)>>24) | ((threshold - v)>>24) will become 0xff when - * abs(src - dest) > threshold. - */ -} - -/* Background image is refreshed every frame */ -void image_bgsubtract_update_y(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, int y_threshold) -{ - int i; - int R, G, B; - const RGB32 *p; - short *q; - unsigned char *r; - int v; - - p = src; - q = (short *)background; - r = diff; - for(i=0; i>(16-1); - G = ((*p)&0xff00)>>(8-2); - B = (*p)&0xff; - v = (R + G + B) - (int)(*q); - *q = (short)(R + G + B); - *r = ((v + y_threshold)>>24) | ((y_threshold - v)>>24); - - p++; - q++; - r++; - } -} - -/* checks each RGB value */ - -/* The range of r, g, b are [0..7] */ -RGB32 image_set_threshold_RGB(int r, int g, int b) -{ - unsigned char R, G, B; - RGB32 rgb_threshold; - - R = G = B = 0xff; - R = R<>8); - b = b ^ 0xffffff; - a = a ^ b; - a = a & rgb_threshold; - *r++ = (0 - a)>>24; - } -} - -void image_bgsubtract_update_RGB(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, RGB32 rgb_threshold) -{ - int i; - const RGB32 *p; - RGB32 *q; - unsigned a, b; - unsigned char *r; - - p = src; - q = background; - r = diff; - for(i=0; i>8); - b = b ^ 0xffffff; - a = a ^ b; - a = a & rgb_threshold; - *r++ = (0 - a)>>24; - } -} - -/* noise filter for subtracted image. */ -void image_diff_filter(unsigned char *diff2, const unsigned char *diff, int width, int height) -{ - int x, y; - const unsigned char *src; - unsigned char *dest; - unsigned int count; - unsigned int sum1, sum2, sum3; - - src = diff; - dest = diff2 + width +1; - for(y=1; y>24; - src++; - } - dest += 2; - } -} - -/* Y value filters */ -void image_y_over(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold) -{ - int i; - int R, G, B, v; - unsigned char *p = diff; - - for(i = video_area; i>0; i--) { - R = ((*src)&0xff0000)>>(16-1); - G = ((*src)&0xff00)>>(8-2); - B = (*src)&0xff; - v = y_threshold - (R + G + B); - *p = (unsigned char)(v>>24); - src++; - p++; - } -} - -void image_y_under(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold) -{ - int i; - int R, G, B, v; - unsigned char *p = diff; - - for(i = video_area; i>0; i--) { - R = ((*src)&0xff0000)>>(16-1); - G = ((*src)&0xff00)>>(8-2); - B = (*src)&0xff; - v = (R + G + B) - y_threshold; - *p = (unsigned char)(v>>24); - src++; - p++; - } -} - -/* tiny edge detection */ -void image_edge(unsigned char *diff2, const RGB32 *src, int width, int height, int y_threshold) -{ - int x, y; - const unsigned char *p; - unsigned char *q; - int r, g, b; - int ar, ag, ab; - int w; - - p = (const unsigned char *)src; - q = diff2; - w = width * sizeof(RGB32); - - for(y=0; y y_threshold) { - *q = 255; - } else { - *q = 0; - } - q++; - p += 4; - } - p += 4; - *q++ = 0; - } - memset(q, 0, width); -} - -/* horizontal flipping */ -void image_hflip(const RGB32 *src, RGB32 *dest, int width, int height) -{ - int x, y; - - src += width - 1; - for(y=0; y -#include "utils.h" - -/* - * HSI color system utilities - */ -static int itrunc(double f) -{ - int i; - - i=(int)f; - if(i<0)i=0; - if(i>255)i=255; - return i; -} - -void HSItoRGB(double H, double S, double I, int *r, int *g, int *b) -{ - double T,Rv,Gv,Bv; - - Rv=1+S*sin(H-2*M_PI/3); - Gv=1+S*sin(H); - Bv=1+S*sin(H+2*M_PI/3); - T=255.999*I/2; - *r=itrunc(Rv*T); - *g=itrunc(Gv*T); - *b=itrunc(Bv*T); -} - -/* - * fastrand - fast fake random number generator - * Warning: The low-order bits of numbers generated by fastrand() - * are bad as random numbers. For example, fastrand()%4 - * generates 1,2,3,0,1,2,3,0... - * You should use high-order bits. - */ -#ifdef __DARWIN__ -static -#endif -unsigned int fastrand_val; - -unsigned int fastrand(void) -{ - return (fastrand_val=fastrand_val*1103515245+12345); -} - -void fastsrand(unsigned int seed) -{ - fastrand_val = seed; -} diff --git a/src/modules/effectv/utils.h b/src/modules/effectv/utils.h deleted file mode 100644 index 4461898..0000000 --- a/src/modules/effectv/utils.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * EffecTV - Realtime Digital Video Effector - * Copyright (C) 2001-2006 FUKUCHI Kentaro - * - * utils.h: header file for utils - * - */ - -#ifndef __UTILS_H__ -#define __UTILS_H__ - -#include - -typedef uint32_t RGB32; - -/* DEFINE's by nullset@dookie.net */ -#define RED(n) ((n>>16) & 0x000000FF) -#define GREEN(n) ((n>>8) & 0x000000FF) -#define BLUE(n) ((n>>0) & 0x000000FF) -#define RGB(r,g,b) ((0<<24) + (r<<16) + (g <<8) + (b)) -#define INTENSITY(n) ( ( (RED(n)+GREEN(n)+BLUE(n))/3)) - -/* utils.c */ -void HSItoRGB(double H, double S, double I, int *r, int *g, int *b); - -#ifndef __DARWIN__ -extern unsigned int fastrand_val; -#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) -#endif -unsigned int fastrand(void); -void fastsrand(unsigned int); - -/* image.c */ -int image_set_threshold_y(int threshold); -void image_bgset_y(RGB32 *background, const RGB32 *src, int video_area, int y_threshold); -void image_bgsubtract_y(unsigned char *diff, const RGB32 *background, const RGB32 *src, int video_area, int y_threshold); -void image_bgsubtract_update_y(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, int y_threshold); -RGB32 image_set_threshold_RGB(int r, int g, int b); -void image_bgset_RGB(RGB32 *background, const RGB32 *src, int video_area); -void image_bgsubtract_RGB(unsigned char *diff, const RGB32 *background, const RGB32 *src, int video_area, RGB32 rgb_threshold); -void image_bgsubtract_update_RGB(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, RGB32 rgb_threshold); -void image_diff_filter(unsigned char *diff2, const unsigned char *diff, int width, int height); -void image_y_over(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold); -void image_y_under(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold); -void image_edge(unsigned char *diff2, const RGB32 *src, int width, int height, int y_threshold); -void image_hflip(const RGB32 *src, RGB32 *dest, int width, int height); - -#endif /* __UTILS_H__ */ diff --git a/src/modules/feeds/Makefile b/src/modules/feeds/Makefile deleted file mode 100644 index 748ce47..0000000 --- a/src/modules/feeds/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -include ../../../config.mak - -all: - -depend: - -distclean: - -clean: - -install: all - install -d $(DESTDIR)$(prefix)/share/mlt/feeds/PAL - install -d $(DESTDIR)$(prefix)/share/mlt/feeds/NTSC - install -m 644 PAL/*.* $(DESTDIR)$(prefix)/share/mlt/feeds/PAL - install -m 644 NTSC/*.* $(DESTDIR)$(prefix)/share/mlt/feeds/NTSC diff --git a/src/modules/feeds/NTSC/data_fx.properties b/src/modules/feeds/NTSC/data_fx.properties deleted file mode 100644 index 03832aa..0000000 --- a/src/modules/feeds/NTSC/data_fx.properties +++ /dev/null @@ -1,250 +0,0 @@ -# This properties file describes the fx available to the data_feed and -# data_show filters -# -# Syntax is as follows: -# -# name= -# name.description= -# name.properties.= -# name.=value -# etc -# -# Typically, the is a 'region' and additional filters are -# included as properties using the normal region filter syntax. -# - -# -# The titles filter definition -# - -titles=region -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%,70%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:0;5=0%,0%:100%x100%:40 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%,0%:100%x100%:0;8=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 - -# -# The top titles filter definition -# - -top-titles=region -.description=Top Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%,5%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:0;5=0%,0%:100%x100%:40 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%,0%:100%x100%:0;8=0%,0%:100%x100%:100 -.filter[1].composite.halign=centre -.filter[1].composite.titles=1 - -# -# OK - Silly example... -# - -tickertape=region -.description=Tickertape -.properties.markup=filter[1].producer.markup -.type.markup=text -.properties.length[0]=filter[1].composite.out -.composite.geometry=0%,93%:100%x7% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=100%,0%:300%x100%:100;-1=-300%,0%:300%x100%:100 -.filter[1].producer.font=San 32 -.filter[1].composite.titles=1 - -# -# ETV Location -# - -location=region -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=0,80:230x30 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=-100%,0%:100%x100%:100;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup= -.filter[1].producer.font=San 24 -.filter[1].composite.geometry=0%,0%:100%x100%:0;24=0%,0%:100%x100%:0;49=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=center - -courtesy=region -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=0,115:230x30 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=-100%,0%:100%x100%:0;12=-100%,0%:100%x100%:0;37=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=ETV Exclusive -.filter[1].producer.font=San 24 -.filter[1].composite.geometry=0%,0%:100%x100%:0;37=0%,0%:100%x100%:0;61=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=right - -exclusive=region -.description=Exclusive -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=0,115:230x30 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=ETV Exclusive -.filter[1].producer.font=San 24 -.filter[1].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=right - -file_shot=region -.description=Titles -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=590,160:80x25 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=File Shot -.filter[1].producer.font=San 20 -.filter[1].composite.geometry=1%,1%:99%x99%:15;25=1%,1%:99%x99%:100 -.filter[1].composite.titles=0 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -special=region -.description=Titles -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=465,375:255x35 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=100%,0%:100%x100%:0;49=100%,0%:100%x100%:0;74=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Special -.filter[1].producer.font=San 24 -.filter[1].composite.geometry=100%,0%:100%x100%:0;49=100%,0%:100%x100%:0;74=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -ticker=region -.description=Tickertape -.properties.markup=filter[1].producer.markup -.type.markup=text -.properties.length[0]=filter[1].composite.out -.composite.geometry=0,500:722x75 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Ticker - provided for reference -.filter[1].composite.geometry=0%,0%:100%x100%:100 -.filter[1].composite.titles=0 -.filter[1].producer.font=San 24 -.filter[1].composite.halign=centre -.filter[1].composite.titles=1 -.filter[1].composite.valign=centre - -super=region -.description=Transcription -.properties.0=filter[1].producer.markup -.properties.1=filter[2].producer.markup -.properties.align=filter[1].composite.valign -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.properties.length[2]=filter[2].composite.out -.period=2 -.composite.geometry=0,410:720x90 -.filter[0]=watermark -.filter[0].resource=colour:0xbbbbbb00 -.filter[0].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[0].composite.luma=%luma18.pgm -.filter[0].composite.out=25 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup= -.filter[1].producer.font=San 32 -.filter[1].producer.fgcolour=0x6c0101ff -.filter[1].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=top -.filter[2]=watermark -.filter[2].resource=pango: -.filter[2].producer.markup= -.filter[2].producer.font=San 32 -.filter[2].producer.fgcolour=0x6c0101ff -.filter[2].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[2].composite.titles=1 -.filter[2].composite.halign=centre -.filter[2].composite.valign=bottom - -obscure=region -.description=Obscure -.properties.geometry=composite.geometry -.properties.resource=resource -.properties.length[0]=composite.out -.composite.geometry= -.resource=rectangle -.composite.refresh=1 -.filter[0]=obscure -.filter[0].start=0,0:100%x100% - diff --git a/src/modules/feeds/NTSC/obscure.properties b/src/modules/feeds/NTSC/obscure.properties deleted file mode 100644 index 7eba160..0000000 --- a/src/modules/feeds/NTSC/obscure.properties +++ /dev/null @@ -1,26 +0,0 @@ -# This properties file describes the fx available to the data_feed and -# data_show filters -# -# Syntax is as follows: -# -# name= -# name.description= -# name.properties.= -# name.=value -# etc -# -# Typically, the is a 'region' and additional filters are -# included as properties using the normal region filter syntax. -# - -obscure=region -.description=Obscure -.properties.geometry=composite.geometry -.properties.resource=resource -.properties.length[0]=composite.out -.composite.geometry= -.resource=rectangle -.composite.refresh=1 -.filter[0]=obscure -.filter[0].start=0,0:100%x100% - diff --git a/src/modules/feeds/PAL/border.properties b/src/modules/feeds/PAL/border.properties deleted file mode 100644 index e02ab35..0000000 --- a/src/modules/feeds/PAL/border.properties +++ /dev/null @@ -1,22 +0,0 @@ -border_left=watermark -.description=Border Left -.resource=colour:black -.reverse=1 -.period=2 -.properties.length[0]=composite.out -.composite.geometry=0,0:100%x100%;25=2.5%,17.5%:45%x45% -.composite.halign=c -.composite.valign=c -.composite.fill=1 - -border_right=watermark -.description=Border Right -.resource=colour:black -.reverse=1 -.period=2 -.properties.length[0]=composite.out -.composite.geometry=0,0:100%x100%;25=52.5%,17.5%:45%x45% -.composite.halign=c -.composite.valign=c -.composite.fill=1 - diff --git a/src/modules/feeds/PAL/data_fx.properties b/src/modules/feeds/PAL/data_fx.properties deleted file mode 100644 index e2e483b..0000000 --- a/src/modules/feeds/PAL/data_fx.properties +++ /dev/null @@ -1,76 +0,0 @@ -# This properties file describes the fx available to the data_send and -# data_show filters -# -# Syntax is as follows: -# -# name= -# name.description= -# name.properties.= -# name.=value -# etc -# -# Typically, the is a 'region' and additional filters are -# included as properties using the normal region filter syntax. -# - -# -# The titles filter definition -# - -titles=region -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%,70%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:0;5=0%,0%:100%x100%:40 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%,0%:100%x100%:0;8=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 - -# -# The top titles filter definition -# - -top-titles=region -.description=Top Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%,5%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:0;5=0%,0%:100%x100%:40 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%,0%:100%x100%:0;8=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 - -# -# OK - Silly example... -# - -tickertape=region -.description=Tickertape -.properties.markup=filter[1].producer.markup -.type.markup=text -.properties.length[0]=filter[1].composite.out -.composite.geometry=0%,93%:100%x7% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=100%,0%:300%x100%:100;-1=-300%,0%:300%x100%:100 -.filter[1].producer.font=San 32 -.filter[1].composite.titles=1 - diff --git a/src/modules/feeds/PAL/etv.properties b/src/modules/feeds/PAL/etv.properties deleted file mode 100644 index 07be453..0000000 --- a/src/modules/feeds/PAL/etv.properties +++ /dev/null @@ -1,186 +0,0 @@ -# This properties file describes the fx available to the data_feed and -# data_show filters -# -# Syntax is as follows: -# -# name= -# name.description= -# name.properties.= -# name.=value -# etc -# -# Typically, the is a 'region' and additional filters are -# included as properties using the normal region filter syntax. -# - -location=region -.description=Titles -.properties.markup=filter[1].producer.text -.properties.font=filter[1].producer.font -.properties.size=filter[1].producer.size -.period=2 -.properties.length[0]=composite.out -.composite.geometry=0,80:230x30:0;12=,:x:100 -.composite.luma=%luma01.pgm -.composite.softness=.3 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text= -.filter[1].producer.font=Sans -.filter[1].producer.size=24 -.filter[1].composite.geometry=0,0:95%x100% -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=center - -courtesy=region -.description=Courtesy -.properties.markup=filter[1].producer.text -.properties.font=filter[1].producer.font -.properties.size=filter[1].producer.size -.period=2 -.properties.length[0]=composite.out -.composite.geometry=0,115:230x30:0;12=,:x:100 -.composite.luma=%luma01.pgm -.composite.softness=.3 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text= -.filter[1].producer.font=Sans -.filter[1].producer.size=24 -.filter[1].composite.geometry=0,0:95%x100% -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=centre - -exclusive=region -.description=Exclusive -.properties.markup=filter[1].producer.text -.properties.font=filter[1].producer.font -.properties.size=filter[1].producer.size -.period=2 -.properties.length[0]=composite.out -.composite.geometry=-230,115:230x30;12=0 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=ETV Exclusive -.filter[1].producer.font=Sans -.filter[1].producer.size=24 -.filter[1].producer.weight=700 -.filter[1].composite.geometry=0,0:95%x100% -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=centre - -file_shot=region -.description=Titles -.period=2 -.properties.font=filter[1].producer.font -.properties.size=filter[1].producer.size -.properties.length[0]=composite.out -.composite.geometry=590,160:80x25:0;12=,:x:100 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=File Shot -.filter[1].producer.font=Sans -.filter[1].producer.size=18 -.filter[1].producer.weight=700 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -special=region -.description=Special -.period=2 -.properties.font=filter[1].producer.font -.properties.size=filter[1].producer.size -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=465,375:255x35 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.geometry=100%,0%:100%x100%:0;12=0%,0%:x:100 -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=Special -.filter[1].producer.font=Sans -.filter[1].producer.size=24 -.filter[1].producer.weight=700 -.filter[1].composite.geometry=100%,0%:100%x100%:0;12=0%,0%:x:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -ticker=region -.description=Tickertape -.properties.markup=filter[1].producer.text -.properties.font=filter[1].producer.font -.properties.size=filter[1].producer.size -.properties.length[0]=filter[1].composite.out -.composite.geometry=0,500:722x75 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=Ticker - provided for reference -.filter[1].producer.font=Sans -.filter[1].producer.size=24 -.filter[1].producer.weight=700 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -super=region -.description=Transcription -.properties.0=filter[1].producer.text -.properties.1=filter[2].producer.text -.properties.align=filter[1].composite.valign -.properties.weight=filter[1].producer.weight -.properties.f0=filter[1].producer.font -.properties.s0=filter[1].producer.size -.properties.f1=filter[2].producer.font -.properties.s1=filter[2].producer.size -.properties.length[0]=composite.out -.period=2 -.composite.geometry=0,410:720x90:0;25=,:x:100 -.composite.luma=%luma01.pgm -.composite.luma_invert=1 -.composite.softness=.3 -.filter[0]=watermark -.filter[0].resource=colour:0xbbbbbbff -.filter[0].composite.geometry=0,0:100%:100%:70 -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text= -.filter[1].producer.font=Sans -.filter[1].producer.size=32 -.filter[1].producer.weight=700 -.filter[1].producer.fgcolour=0x6c0101ff -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=top -.filter[2]=watermark -.filter[2].resource=pango: -.filter[2].producer.text= -.filter[2].producer.font=Sans -.filter[2].producer.size=32 -.filter[2].producer.fgcolour=0x6c0101ff -.filter[2].composite.titles=1 -.filter[2].composite.halign=centre -.filter[2].composite.valign=bottom - diff --git a/src/modules/feeds/PAL/example.properties b/src/modules/feeds/PAL/example.properties deleted file mode 100644 index 0509fff..0000000 --- a/src/modules/feeds/PAL/example.properties +++ /dev/null @@ -1,12 +0,0 @@ -greyscale=greyscale -.description=Greyscale - -sepia=sepia -.description=Sepia - -charcoal=charcoal -.description=Charcoal - -invert=invert -.description=Invert - diff --git a/src/modules/feeds/PAL/obscure.properties b/src/modules/feeds/PAL/obscure.properties deleted file mode 100644 index 3917d9a..0000000 --- a/src/modules/feeds/PAL/obscure.properties +++ /dev/null @@ -1,35 +0,0 @@ -# This properties file describes the fx available to the data_feed and -# data_show filters -# -# Syntax is as follows: -# -# name= -# name.description= -# name.properties.= -# name.=value -# etc -# -# Typically, the is a 'region' and additional filters are -# included as properties using the normal region filter syntax. -# - -obscure0=region -.description=Primary Obscure -.properties.geometry=composite.geometry -.properties.resource=resource -.properties.length[0]=composite.out -.composite.geometry= -.resource=rectangle -.composite.refresh=1 -.filter[0]=obscure - -obscure1=region -.description=Secondary Obscure -.properties.geometry=composite.geometry -.properties.resource=resource -.properties.length[0]=composite.out -.composite.geometry= -.resource=rectangle -.composite.refresh=1 -.filter[0]=obscure - diff --git a/src/modules/fezzik.dict b/src/modules/fezzik.dict deleted file mode 100644 index bdcc0e1..0000000 --- a/src/modules/fezzik.dict +++ /dev/null @@ -1,39 +0,0 @@ -http://*=avformat -.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - install -m 644 ../fezzik.dict "$(DESTDIR)$(prefix)/share/mlt" - install -m 644 ../fezzik.ini "$(DESTDIR)$(prefix)/share/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/fezzik/factory.c b/src/modules/fezzik/factory.c deleted file mode 100644 index 87f22b9..0000000 --- a/src/modules/fezzik/factory.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -extern mlt_producer producer_fezzik_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_hold_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( producer_type, "fezzik", producer_fezzik_init ); - MLT_REGISTER( producer_type, "hold", producer_hold_init ); -} diff --git a/src/modules/fezzik/producer_fezzik.c b/src/modules/fezzik/producer_fezzik.c deleted file mode 100644 index 816c1bd..0000000 --- a/src/modules/fezzik/producer_fezzik.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * producer_fezzik.c -- a normalising filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include - -static mlt_properties dictionary = NULL; -static mlt_properties normalisers = NULL; - -static mlt_producer create_from( mlt_profile profile, char *file, char *services ) -{ - mlt_producer producer = NULL; - char *temp = strdup( services ); - char *service = temp; - do - { - char *p = strchr( service, ',' ); - if ( p != NULL ) - *p ++ = '\0'; - producer = mlt_factory_producer( profile, service, file ); - service = p; - } - while ( producer == NULL && service != NULL ); - free( temp ); - return producer; -} - -static mlt_producer create_producer( mlt_profile profile, char *file ) -{ - mlt_producer result = NULL; - - // 1st Line - check for service:resource handling - if ( strchr( file, ':' ) ) - { - char *temp = strdup( file ); - char *service = temp; - char *resource = strchr( temp, ':' ); - *resource ++ = '\0'; - result = mlt_factory_producer( profile, service, resource ); - free( temp ); - } - - // 2nd Line preferences - if ( result == NULL ) - { - int i = 0; - char *lookup = strdup( file ); - char *p = lookup; - - // We only need to load the dictionary once - if ( dictionary == NULL ) - { - char temp[ 1024 ]; - sprintf( temp, "%s/fezzik.dict", mlt_environment( "MLT_DATA" ) ); - dictionary = mlt_properties_load( temp ); - mlt_factory_register_for_clean_up( dictionary, ( mlt_destructor )mlt_properties_close ); - } - - // Convert the lookup string to lower case - while ( *p ) - { - *p = tolower( *p ); - p ++; - } - - // Iterate through the dictionary - for ( i = 0; result == NULL && i < mlt_properties_count( dictionary ); i ++ ) - { - char *name = mlt_properties_get_name( dictionary, i ); - if ( fnmatch( name, lookup, 0 ) == 0 ) - result = create_from( profile, file, mlt_properties_get_value( dictionary, i ) ); - } - - free( lookup ); - } - - // Finally, try just loading as service - if ( result == NULL ) - result = mlt_factory_producer( profile, file, NULL ); - - return result; -} - -static void create_filter( mlt_profile profile, mlt_producer producer, char *effect, int *created ) -{ - // The swscale filter can not handle images with a width > 2048 and the - // sdl_image producer does not scale on its own - if ( strncmp( effect, "swscale", 7 ) == 0 && - mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( producer ), "_real_width" ) > 2048 && - strcmp( mlt_properties_get( MLT_PRODUCER_PROPERTIES( producer ), "mlt_service" ), "sdl_image" ) == 0 ) - return; - - char *id = strdup( effect ); - char *arg = strchr( id, ':' ); - if ( arg != NULL ) - *arg ++ = '\0'; - mlt_filter filter = mlt_factory_filter( profile, id, arg ); - if ( filter != NULL ) - { - mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "_fezzik", 1 ); - mlt_producer_attach( producer, filter ); - mlt_filter_close( filter ); - *created = 1; - } - free( id ); -} - -static void attach_normalisers( mlt_profile profile, mlt_producer producer ) -{ - // Loop variable - int i; - - // Tokeniser - mlt_tokeniser tokeniser = mlt_tokeniser_init( ); - - // We only need to load the normalising properties once - if ( normalisers == NULL ) - { - char temp[ 1024 ]; - sprintf( temp, "%s/fezzik.ini", mlt_environment( "MLT_DATA" ) ); - normalisers = mlt_properties_load( temp ); - mlt_factory_register_for_clean_up( normalisers, ( mlt_destructor )mlt_properties_close ); - } - - // Apply normalisers - for ( i = 0; i < mlt_properties_count( normalisers ); i ++ ) - { - int j = 0; - int created = 0; - char *value = mlt_properties_get_value( normalisers, i ); - mlt_tokeniser_parse_new( tokeniser, value, "," ); - for ( j = 0; !created && j < mlt_tokeniser_count( tokeniser ); j ++ ) - create_filter( profile, producer, mlt_tokeniser_get_string( tokeniser, j ), &created ); - } - - // Close the tokeniser - mlt_tokeniser_close( tokeniser ); -} - -mlt_producer producer_fezzik_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create the producer - mlt_producer producer = NULL; - mlt_properties properties = NULL; - - if ( arg != NULL ) - producer = create_producer( profile, arg ); - - if ( producer != NULL ) - properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Attach filters if we have a producer and it isn't already westley'd :-) - if ( producer != NULL && mlt_properties_get( properties, "westley" ) == NULL && \ - mlt_properties_get( properties, "_westley" ) == NULL && \ - mlt_properties_get( properties, "fezzik_normalised" ) == NULL ) - attach_normalisers( profile, producer ); - - // Now make sure we don't lose our identity - if ( properties != NULL ) - mlt_properties_set_int( properties, "_mlt_service_hidden", 1 ); - - // Return the producer - return producer; -} diff --git a/src/modules/fezzik/producer_hold.c b/src/modules/fezzik/producer_hold.c deleted file mode 100644 index f30aa0c..0000000 --- a/src/modules/fezzik/producer_hold.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * producer_hold.c -- frame holding producer - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include - -// Forward references -static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer this ); - -/** Constructor for the frame holding producer. Basically, all this producer does is - provide a producer wrapper for the requested producer, allows the specifcation of - the frame required and will then repeatedly obtain that frame for each get_frame - and get_image requested. -*/ - -mlt_producer producer_hold_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Construct a new holding producer - mlt_producer this = mlt_producer_new( ); - - // Construct the requested producer via fezzik - mlt_producer producer = mlt_factory_producer( profile, "fezzik", arg ); - - // Initialise the frame holding capabilities - if ( this != NULL && producer != NULL ) - { - // Get the properties of this producer - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Store the producer - mlt_properties_set_data( properties, "producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); - - // Set frame, in, out and length for this producer - mlt_properties_set_position( properties, "frame", 0 ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", 25 ); - mlt_properties_set_position( properties, "length", 15000 ); - mlt_properties_set( properties, "resource", arg ); - mlt_properties_set( properties, "method", "onefield" ); - - // Override the get_frame method - this->get_frame = producer_get_frame; - this->close = ( mlt_destructor )producer_close; - } - else - { - // Clean up (not sure which one failed, can't be bothered to find out, so close both) - if ( this ) - mlt_producer_close( this ); - if ( producer ) - mlt_producer_close( producer ); - - // Make sure we return NULL - this = NULL; - } - - // Return this producer - return this; -} - -static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the properties of the frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the real frame - mlt_frame real_frame = mlt_frame_pop_service( frame ); - - // Get the image from the real frame - int size = 0; - *buffer = mlt_properties_get_data( MLT_FRAME_PROPERTIES( real_frame ), "image", &size ); - *width = mlt_properties_get_int( MLT_FRAME_PROPERTIES( real_frame ), "width" ); - *height = mlt_properties_get_int( MLT_FRAME_PROPERTIES( real_frame ), "height" ); - - // If this is the first time, get it from the producer - if ( *buffer == NULL ) - { - mlt_properties_pass( MLT_FRAME_PROPERTIES( real_frame ), properties, "" ); - - // We'll deinterlace on the downstream deinterlacer - mlt_properties_set_int( MLT_FRAME_PROPERTIES( real_frame ), "consumer_deinterlace", 1 ); - - // We want distorted to ensure we don't hit the resize filter twice - mlt_properties_set_int( MLT_FRAME_PROPERTIES( real_frame ), "distort", 1 ); - - // Get the image - mlt_frame_get_image( real_frame, buffer, format, width, height, writable ); - - // Make sure we get the size - *buffer = mlt_properties_get_data( MLT_FRAME_PROPERTIES( real_frame ), "image", &size ); - } - - mlt_properties_pass( properties, MLT_FRAME_PROPERTIES( real_frame ), "" ); - - // Set the values obtained on the frame - if ( *buffer != NULL ) - { - uint8_t *image = mlt_pool_alloc( size ); - memcpy( image, *buffer, size ); - *buffer = image; - mlt_properties_set_data( properties, "image", *buffer, size, mlt_pool_release, NULL ); - } - else - { - // Pass the current image as is - mlt_properties_set_data( properties, "image", *buffer, size, NULL, NULL ); - } - - // Make sure that no further scaling is done - mlt_properties_set( properties, "rescale.interps", "none" ); - mlt_properties_set( properties, "scale", "off" ); - - // All done - return 0; -} - -static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ) -{ - // Get the properties of this producer - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Construct a new frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( this ) ); - - // If we have a frame, then stack the producer itself and the get_image method - if ( *frame != NULL ) - { - // Define the real frame - mlt_frame real_frame = mlt_properties_get_data( properties, "real_frame", NULL ); - - // Obtain real frame if we don't have it - if ( real_frame == NULL ) - { - // Get the producer - mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL ); - - // Get the frame position requested - mlt_position position = mlt_properties_get_position( properties, "frame" ); - - // Seek the producer to the correct place - mlt_producer_seek( producer, position ); - - // Get the real frame - mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &real_frame, index ); - - // Ensure that the real frame gets wiped eventually - mlt_properties_set_data( properties, "real_frame", real_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); - } - else - { - // Temporary fix - ensure that we aren't seen as a test frame - int8_t *image = mlt_properties_get_data( MLT_FRAME_PROPERTIES( real_frame ), "image", NULL ); - mlt_properties_set_data( MLT_FRAME_PROPERTIES( *frame ), "image", image, 0, NULL, NULL ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_image", 0 ); - } - - // Stack the real frame and method - mlt_frame_push_service( *frame, real_frame ); - mlt_frame_push_service( *frame, producer_get_image ); - - // Ensure that the consumer sees what the real frame has - mlt_properties_pass( MLT_FRAME_PROPERTIES( *frame ), MLT_FRAME_PROPERTIES( real_frame ), "" ); - - mlt_properties_set( MLT_FRAME_PROPERTIES( real_frame ), "deinterlace_method", - mlt_properties_get( properties, "method" ) ); - } - - // Move to the next position - mlt_producer_prepare_next( this ); - - return 0; -} - -static void producer_close( mlt_producer this ) -{ - this->close = NULL; - mlt_producer_close( this ); - free( this ); -} - diff --git a/src/modules/frei0r/Makefile b/src/modules/frei0r/Makefile deleted file mode 100644 index 2c3762d..0000000 --- a/src/modules/frei0r/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltfrei0r$(LIBSUF) - -OBJS = factory.o \ - producer_frei0r.o \ - filter_frei0r.o \ - transition_frei0r.o \ - frei0r_helper.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt -LDFLAGS += -lm - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/frei0r/configure b/src/modules/frei0r/configure deleted file mode 100755 index 73757a4..0000000 --- a/src/modules/frei0r/configure +++ /dev/null @@ -1,14 +0,0 @@ -#! /bin/sh - -if [ "$help" != "1" ] -then - - echo "#include int main(){ f0r_plugin_info_t test; test.name;return 0;}"| gcc $CFLAGS -c -x c - >/dev/null 2>&1 - - if [ "$?" = "1" ] - then - touch ../disable-frei0r - echo "- frei0r plugin disabled. Install frei0r-plugins and make sure frei0r.h is available." - fi - -fi diff --git a/src/modules/frei0r/factory.c b/src/modules/frei0r/factory.c deleted file mode 100644 index 8e2ab99..0000000 --- a/src/modules/frei0r/factory.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (c) 2008 Marco Gittler - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define FREI0R_PLUGIN_PATH "/usr/lib/frei0r-1:/usr/local/lib/frei0r-1:/usr/lib64/frei0r-1:/opt/local/lib/frei0r-1" - -extern mlt_filter filter_frei0r_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_frame filter_process( mlt_filter this, mlt_frame frame ); -extern void filter_close( mlt_filter this ); -extern int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ); -extern void producer_close( mlt_producer this ); -extern void transition_close( mlt_transition this ); -extern mlt_frame transition_process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame ); - -static mlt_properties fill_param_info ( mlt_service_type type, const char *service_name, char *name ) -{ - char file[ PATH_MAX ]; - char servicetype[ 1024 ]=""; - struct stat stat_buff; - - switch ( type ) { - case producer_type: - strcpy ( servicetype , "producer" ); - break; - case filter_type: - strcpy ( servicetype , "filter" ); - break; - case transition_type: - strcpy ( servicetype , "transition" ) ; - break; - default: - strcpy ( servicetype , "" ); - }; - - snprintf( file, PATH_MAX, "%s/frei0r/%s_%s.yml", mlt_environment( "MLT_DATA" ), servicetype, service_name ); - stat(file,&stat_buff); - - if (S_ISREG(stat_buff.st_mode)){ - return mlt_properties_parse_yaml( file ); - } - - void* handle=dlopen(name,RTLD_LAZY); - if (!handle) return NULL; - void (*plginfo)(f0r_plugin_info_t*)=dlsym(handle,"f0r_get_plugin_info"); - void (*param_info)(f0r_param_info_t*,int param_index)=dlsym(handle,"f0r_get_param_info"); - if (!plginfo || !param_info) { - dlclose(handle); - return NULL; - } - mlt_properties metadata = mlt_properties_new(); - f0r_plugin_info_t info; - char string[48]; - int j=0; - - plginfo(&info); - snprintf ( string, sizeof(string) , "%d.%d" , info.major_version , info.minor_version ); - mlt_properties_set ( metadata, "schema_version" , "0.1" ); - mlt_properties_set ( metadata, "title" , info.name ); - mlt_properties_set ( metadata, "version", string ); - mlt_properties_set ( metadata, "identifier" , service_name ); - mlt_properties_set ( metadata, "description" , info.explanation ); - mlt_properties_set ( metadata, "creator" , info.author ); - switch (type){ - case producer_type: - mlt_properties_set ( metadata, "type" , "producer" ); - break; - case filter_type: - mlt_properties_set ( metadata, "type" , "filter" ); - break; - case transition_type: - mlt_properties_set ( metadata, "type" , "transition" ); - break; - default: - break; - } - - mlt_properties parameter = mlt_properties_new ( ); - mlt_properties_set_data ( metadata , "parameters" , parameter , 0 , ( mlt_destructor )mlt_properties_close, NULL ); - mlt_properties tags = mlt_properties_new ( ); - mlt_properties_set_data ( metadata , "tags" , tags , 0 , ( mlt_destructor )mlt_properties_close, NULL ); - mlt_properties_set ( tags , "0" , "Video" ); - - for (j=0;jget_frame = producer_get_frame; - this->close = ( mlt_destructor )producer_close; - f0r_init(); - properties=MLT_PRODUCER_PROPERTIES ( this ); - - for (i=0;iprocess = filter_process; - this->close = filter_close; - f0r_init(); - properties=MLT_FILTER_PROPERTIES ( this ); - - for (i=0;iprocess = transition_process; - transition->close = transition_close; - properties=MLT_TRANSITION_PROPERTIES( transition ); - mlt_properties_set_int(properties, "_transition_type", 1 ); - - ret=transition; - } - } - mlt_properties_set_data(properties, "_dlclose_handle", handle , sizeof (void*) , NULL , NULL ); - mlt_properties_set_data(properties, "_dlclose", dlclose , sizeof (void*) , NULL , NULL ); - mlt_properties_set_data(properties, "f0r_construct", f0r_construct , sizeof(void*),NULL,NULL); - mlt_properties_set_data(properties, "f0r_update", f0r_update , sizeof(void*),NULL,NULL); - if (f0r_update2) - mlt_properties_set_data(properties, "f0r_update2", f0r_update2 , sizeof(void*),NULL,NULL); - mlt_properties_set_data(properties, "f0r_destruct", f0r_destruct , sizeof(void*),NULL,NULL); - mlt_properties_set_data(properties, "f0r_get_plugin_info", f0r_get_plugin_info , sizeof(void*),NULL,NULL); - mlt_properties_set_data(properties, "f0r_get_param_info", f0r_get_param_info , sizeof(void*),NULL,NULL); - mlt_properties_set_data(properties, "f0r_set_param_value", f0r_set_param_value , sizeof(void*),NULL,NULL); - mlt_properties_set_data(properties, "f0r_get_param_value", f0r_get_param_value , sizeof(void*),NULL,NULL); - - - return ret; - }else{ - printf("some was wrong\n"); - dlerror(); - } - return NULL; -} - -static void * create_frei0r_item ( mlt_profile profile, mlt_service_type type, const char *id, void *arg){ - - mlt_tokeniser tokeniser = mlt_tokeniser_init ( ); - int dircount=mlt_tokeniser_parse_new ( - tokeniser, - getenv("MLT_FREI0R_PLUGIN_PATH") ? getenv("MLT_FREI0R_PLUGIN_PATH") : FREI0R_PLUGIN_PATH, - ":" - ); - void* ret=NULL; - while (dircount--){ - char soname[1024]=""; - - char *save_firstptr = NULL; - char *firstname=strtok_r(strdup(id),".",&save_firstptr); - - firstname=strtok_r(NULL,".",&save_firstptr); - sprintf(soname,"%s/%s.so", mlt_tokeniser_get_string( tokeniser , dircount ) , firstname ); - - if (firstname){ - - void* handle=dlopen(soname,RTLD_LAZY); - - if (handle ){ - ret=load_lib ( profile , type , handle ); - }else{ - dlerror(); - } - } - } - mlt_tokeniser_close ( tokeniser ); - return ret; -} - - -MLT_REPOSITORY -{ - int i=0; - mlt_tokeniser tokeniser = mlt_tokeniser_init ( ); - int dircount=mlt_tokeniser_parse_new ( - tokeniser , - getenv("MLT_FREI0R_PLUGIN_PATH") ? getenv("MLT_FREI0R_PLUGIN_PATH") : FREI0R_PLUGIN_PATH, - ":" - ); - - while (dircount--){ - - mlt_properties direntries = mlt_properties_new(); - char* dirname = mlt_tokeniser_get_string ( tokeniser , dircount ) ; - mlt_properties_dir_list(direntries, dirname ,"*.so",1); - - for (i=0;i - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include "frei0r_helper.h" -#include -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - mlt_filter filter = mlt_frame_pop_service( this ); - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - if ( error == 0 && *image && *format == mlt_image_yuv422 ) - { - mlt_position in = mlt_filter_get_in( filter ); - mlt_position out = mlt_filter_get_out( filter ); - mlt_position time = mlt_frame_get_position( this ); - double position = ( double )( time - in ) / ( double )( out - in + 1 ); - - process_frei0r_item( filter_type , position, MLT_FILTER_PROPERTIES ( filter ), this , image, format , width , height , writable ); - - } - - return error; -} - - -mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -void filter_close( mlt_filter this ){ - - destruct( MLT_FILTER_PROPERTIES ( this ) ); - -} diff --git a/src/modules/frei0r/frei0r_helper.c b/src/modules/frei0r/frei0r_helper.c deleted file mode 100644 index e42b06e..0000000 --- a/src/modules/frei0r/frei0r_helper.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * frei0r_helper.c -- frei0r helper - * Copyright (c) 2008 Marco Gittler - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "frei0r_helper.h" -#include -#include -#include - -static void parse_color( int color, f0r_param_color_t *fcolor ) -{ - fcolor->r = ( color >> 24 ) & 0xff; - fcolor->r /= 255; - fcolor->g = ( color >> 16 ) & 0xff; - fcolor->g /= 255; - fcolor->b = ( color >> 8 ) & 0xff; - fcolor->b /= 255; -} - -int process_frei0r_item( mlt_service_type type, double position , mlt_properties prop , mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ){ - - int i=0; - f0r_instance_t ( *f0r_construct ) ( unsigned int , unsigned int ) = mlt_properties_get_data( prop , "f0r_construct" ,NULL); - void (*f0r_update)(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe)=mlt_properties_get_data( prop , "f0r_update" ,NULL); - void (*f0r_destruct)(f0r_instance_t instance)=mlt_properties_get_data( prop , "f0r_destruct" ,NULL); - - void (*f0r_get_plugin_info)(f0r_plugin_info_t*)=mlt_properties_get_data( prop, "f0r_get_plugin_info" ,NULL); - void (*f0r_get_param_info)(f0r_param_info_t* info, int param_index)=mlt_properties_get_data( prop , "f0r_get_param_info" ,NULL); - void (*f0r_set_param_value)(f0r_instance_t instance, f0r_param_t param, int param_index)=mlt_properties_get_data( prop , "f0r_set_param_value" ,NULL); - void (*f0r_get_param_value)(f0r_instance_t instance, f0r_param_t param, int param_index)=mlt_properties_get_data( prop , "f0r_get_param_value" ,NULL); - void (*f0r_update2) (f0r_instance_t instance, double time, - const uint32_t* inframe1,const uint32_t* inframe2,const uint32_t* inframe3, - uint32_t* outframe)=mlt_properties_get_data( prop , "f0r_update2" ,NULL); - - - //use as name the width and height - f0r_instance_t inst; - char ctorname[1024]=""; - sprintf(ctorname,"ctor-%dx%d",*width,*height); - - void* neu=mlt_properties_get_data( prop , ctorname ,NULL ); - if (!f0r_construct){ - //printf("no ctor\n"); - return -1; - } - if ( neu == 0 ){ - inst= f0r_construct(*width,*height); - mlt_properties_set_data( prop , ctorname , inst, sizeof(void*) , f0r_destruct , NULL );; - }else{ - inst=mlt_properties_get_data( prop , ctorname , NULL ); - } - if (f0r_get_plugin_info){ - f0r_plugin_info_t info; - f0r_get_plugin_info(&info); - for (i=0;i - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include - -int process_frei0r_item( mlt_service_type type, double position , mlt_properties prop , mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ); -void destruct (mlt_properties prop ); diff --git a/src/modules/frei0r/producer_frei0r.c b/src/modules/frei0r/producer_frei0r.c deleted file mode 100644 index ae1a26d..0000000 --- a/src/modules/frei0r/producer_frei0r.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * producer_frei0r.c -- frei0r producer - * Copyright (c) 2009 Jean-Baptiste Mardelle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include "frei0r_helper.h" - -#include -#include - -static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the producer for this frame - mlt_producer producer = mlt_properties_get_data( properties, "producer_frei0r", NULL ); - - // Obtain properties of producer - mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); - - // Allocate the image - int size = *width * ( *height + 1 ) * 2; - - // Allocate the image - *buffer = mlt_pool_alloc( size ); - - // Update the frame - mlt_properties_set_data( properties, "image", *buffer, size, mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", *width ); - mlt_properties_set_int( properties, "height", *height ); - - *format = mlt_image_yuv422; - if ( *buffer != NULL ) - { - mlt_position in = mlt_producer_get_in( producer ); - mlt_position out = mlt_producer_get_out( producer ); - mlt_position time = mlt_frame_get_position( frame ); - double position = ( double )( time - in ) / ( double )( out - in + 1 ); - process_frei0r_item( producer_type , position, producer_props, frame , buffer, format , width , height , writable ); - } - - return 0; -} - -int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Generate a frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - if ( *frame != NULL ) - { - // Obtain properties of frame and producer - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Obtain properties of producer - mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); - - // Set the producer on the frame properties - mlt_properties_set_data( properties, "producer_frei0r", producer, 0, NULL, NULL ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Set producer-specific frame properties - mlt_properties_set_int( properties, "progressive", 1 ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) ); - - // Push the get_image method - mlt_frame_push_get_image( *frame, producer_get_image ); - } - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -void producer_close( mlt_producer producer ) -{ - producer->close = NULL; - mlt_producer_close( producer ); - free( producer ); -} diff --git a/src/modules/frei0r/transition_frei0r.c b/src/modules/frei0r/transition_frei0r.c deleted file mode 100644 index 4fb6846..0000000 --- a/src/modules/frei0r/transition_frei0r.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * transition_frei0r.c -- frei0r transition - * Copyright (c) 2008 Marco Gittler - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include "frei0r_helper.h" -#include - -static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ){ - - if (*format!=mlt_image_yuv422 ){ - return -1; - } - - mlt_frame b_frame = mlt_frame_pop_frame( a_frame ); - mlt_transition transition = mlt_frame_pop_service( a_frame ); - mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition ); - mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - - int invert = mlt_properties_get_int( properties, "invert" ); - - if ( mlt_properties_get( a_props, "rescale.interp" ) == NULL || !strcmp( mlt_properties_get( a_props, "rescale.interp" ), "none" ) ) - mlt_properties_set( a_props, "rescale.interp", "nearest" ); - - // set consumer_aspect_ratio for a and b frame - if ( mlt_properties_get_double( a_props, "aspect_ratio" ) == 0.0 ) - mlt_properties_set_double( a_props, "aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - if ( mlt_properties_get_double( b_props, "aspect_ratio" ) == 0.0 ) - mlt_properties_set_double( b_props, "aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - - if ( mlt_properties_get( b_props, "rescale.interp" ) == NULL || !strcmp( mlt_properties_get( b_props, "rescale.interp" ), "none" ) ) - mlt_properties_set( b_props, "rescale.interp", "nearest" ); - - uint8_t *images[]={NULL,NULL,NULL}; - - mlt_frame_get_image( a_frame, &images[0], format, width, height, 1 ); - mlt_frame_get_image( b_frame, &images[1], format, width, height, 1 ); - - mlt_position in = mlt_transition_get_in( transition ); - mlt_position out = mlt_transition_get_out( transition ); - - // Get the position of the frame - char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( transition ), "_unique_id" ); - mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( a_frame ), name ); - - float pos=( float )( position - in ) / ( float )( out - in + 1 ); - - process_frei0r_item( transition_type , pos , properties, !invert ? a_frame : b_frame , images , format, width,height, writable ); - - *width = mlt_properties_get_int( !invert ? a_props : b_props, "width" ); - *height = mlt_properties_get_int( !invert ? a_props : b_props, "height" ); - *image = mlt_properties_get_data( !invert ? a_props : b_props , "image", NULL ); - return 0; -} - -mlt_frame transition_process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame ) -{ - char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( transition ), "_unique_id" ); - mlt_properties_set_position( MLT_FRAME_PROPERTIES( a_frame ), name, mlt_frame_get_position( a_frame ) ); - mlt_frame_push_service( a_frame, transition ); - mlt_frame_push_frame( a_frame, b_frame ); - mlt_frame_push_get_image( a_frame, transition_get_image ); - return a_frame; -} - -void transition_close( mlt_transition this ){ - destruct ( MLT_TRANSITION_PROPERTIES ( this ) ); -} diff --git a/src/modules/gtk2/Makefile b/src/modules/gtk2/Makefile deleted file mode 100644 index de5fa2f..0000000 --- a/src/modules/gtk2/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -include ../../../config.mak -include config.mak - -TARGET = ../libmltgtk2$(LIBSUF) - -OBJS = factory.o - -CFLAGS += -I../.. -LDFLAGS += -L../../framework -lmlt - -ifdef USE_GTK2 -OBJS += consumer_gtk2.o -CFLAGS += `pkg-config gtk+-2.0 --cflags` -LDFLAGS += `pkg-config gtk+-2.0 --libs` -endif - -ifdef USE_PIXBUF -OBJS += producer_pixbuf.o pixops.o filter_rescale.o -CFLAGS += `pkg-config gdk-pixbuf-2.0 --cflags` -LDFLAGS += `pkg-config gdk-pixbuf-2.0 --libs` -endif - -ifdef MMX_FLAGS -ifndef ARCH_X86_64 -ASM_OBJS = have_mmx.o scale_line_22_yuv_mmx.o -endif -endif - -ifdef USE_PANGO -OBJS += producer_pango.o -CFLAGS += `pkg-config pangoft2 --cflags` -LDFLAGS += `pkg-config pangoft2 --libs` -endif - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) $(ASM_OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(ASM_OBJS) $(LDFLAGS) - -have_mmx.o: - $(CC) -o $@ -c have_mmx.S - -scale_line_22_yuv_mmx.o: scale_line_22_yuv_mmx.S - $(CC) -o $@ -c scale_line_22_yuv_mmx.S - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(ASM_OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/gtk2/configure b/src/modules/gtk2/configure deleted file mode 100755 index 299da4b..0000000 --- a/src/modules/gtk2/configure +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - - pkg-config gtk+-2.0 2> /dev/null - disable_gtk2=$? - - pkg-config gdk-pixbuf-2.0 2> /dev/null - disable_pixbuf=$? - - pkg-config pangoft2 2> /dev/null - disable_pango=$? - - if [ "$disable_gtk2" != "0" -a "$disable_pixbuf" != 0 -a "$disable_pango" != "0" ] - then - echo "- GTK2 components not found: disabling" - touch ../disable-gtk2 - exit 0 - fi - - [ "$disable_gtk2" != "0" ] && echo "- gtk2 not found: gtk2 preview disabled" - [ "$disable_pixbuf" != "0" ] && echo "- pixbuf not found: pixbuf loader and rescaler disabled" - [ "$disable_pango" != "0" ] && echo "- pango not found: pango titler disabled" - - echo > config.h - [ "$disable_gtk2" = "0" ] && echo "#define USE_GTK2" >> config.h - [ "$disable_pixbuf" = "0" ] && echo "#define USE_PIXBUF" >> config.h - [ "$disable_pango" = "0" ] && echo "#define USE_PANGO" >> config.h - - echo > config.mak - [ "$disable_gtk2" = "0" ] && echo "USE_GTK2=1" >> config.mak - [ "$disable_pixbuf" = "0" ] && echo "USE_PIXBUF=1" >> config.mak - [ "$disable_pango" = "0" ] && echo "USE_PANGO=1" >> config.mak - - exit 0 -fi - diff --git a/src/modules/gtk2/consumer_gtk2.c b/src/modules/gtk2/consumer_gtk2.c deleted file mode 100644 index dc1619e..0000000 --- a/src/modules/gtk2/consumer_gtk2.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * consumer_gtk2.c -- A consumer for GTK2 apps - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -mlt_consumer consumer_gtk2_preview_init( mlt_profile profile, GtkWidget *widget ) -{ - // Create an sdl preview consumer - mlt_consumer consumer = NULL; - - // This is a nasty little hack which is required by SDL - if ( widget != NULL ) - { - Window xwin = GDK_WINDOW_XWINDOW( widget->window ); - char windowhack[ 32 ]; - sprintf( windowhack, "%ld", xwin ); - setenv( "SDL_WINDOWID", windowhack, 1 ); - } - - // Create an sdl preview consumer - consumer = mlt_factory_consumer( profile, "sdl_preview", NULL ); - - // Now assign the lock/unlock callbacks - if ( consumer != NULL ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer ); - mlt_properties_set_int( properties, "app_locked", 1 ); - mlt_properties_set_data( properties, "app_lock", gdk_threads_enter, 0, NULL, NULL ); - mlt_properties_set_data( properties, "app_unlock", gdk_threads_leave, 0, NULL, NULL ); - } - - return consumer; -} diff --git a/src/modules/gtk2/factory.c b/src/modules/gtk2/factory.c deleted file mode 100644 index 34d62e2..0000000 --- a/src/modules/gtk2/factory.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" -#include -#include -#include - -#ifdef USE_PIXBUF -extern mlt_producer producer_pixbuf_init( char *filename ); -extern mlt_filter filter_rescale_init( mlt_profile profile, char *arg ); -#endif - -#ifdef USE_GTK2 -extern mlt_consumer consumer_gtk2_preview_init( mlt_profile profile, void *widget ); -#endif - -#ifdef USE_PANGO -extern mlt_producer producer_pango_init( const char *filename ); -#endif - -static void initialise( ) -{ - static int init = 0; - if ( init == 0 ) - { - init = 1; - g_type_init( ); - } -} - -void *create_service( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - initialise( ); - -#ifdef USE_PIXBUF - if ( !strcmp( id, "pixbuf" ) ) - return producer_pixbuf_init( arg ); -#endif - -#ifdef USE_PANGO - if ( !strcmp( id, "pango" ) ) - return producer_pango_init( arg ); -#endif - -#ifdef USE_PIXBUF - if ( !strcmp( id, "gtkrescale" ) ) - return filter_rescale_init( profile, arg ); -#endif - -#ifdef USE_GTK2 - if ( !strcmp( id, "gtk2_preview" ) ) - return consumer_gtk2_preview_init( profile, arg ); -#endif - - return NULL; -} - -MLT_REPOSITORY -{ - MLT_REGISTER( consumer_type, "gtk2_preview", create_service ); - MLT_REGISTER( filter_type, "gtkrescale", create_service ); - MLT_REGISTER( producer_type, "pango", create_service ); - MLT_REGISTER( producer_type, "pixbuf", create_service ); -} diff --git a/src/modules/gtk2/filter_rescale.c b/src/modules/gtk2/filter_rescale.c deleted file mode 100644 index e3b6d17..0000000 --- a/src/modules/gtk2/filter_rescale.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * filter_rescale.c -- scale the producer video frame size to match the consumer - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "pixops.h" - -#include -#include -#include - -#include -#include -#include -#include - -static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iformat, mlt_image_format oformat, int iwidth, int iheight, int owidth, int oheight ) -{ - // Get the properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get the requested interpolation method - char *interps = mlt_properties_get( properties, "rescale.interp" ); - - // Convert to the GTK flag - int interp = PIXOPS_INTERP_BILINEAR; - - if ( strcmp( interps, "nearest" ) == 0 ) - interp = PIXOPS_INTERP_NEAREST; - else if ( strcmp( interps, "tiles" ) == 0 ) - interp = PIXOPS_INTERP_TILES; - else if ( strcmp( interps, "hyper" ) == 0 ) - interp = PIXOPS_INTERP_HYPER; - - // Carry out the rescaling - if ( iformat == mlt_image_yuv422 && oformat == mlt_image_yuv422 ) - { - // Create the output image - uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 ); - - // Calculate strides - int istride = iwidth * 2; - int ostride = owidth * 2; - - yuv422_scale_simple( output, owidth, oheight, ostride, *image, iwidth, iheight, istride, interp ); - - // Now update the frame - mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", owidth ); - mlt_properties_set_int( properties, "height", oheight ); - - // Return the output - *image = output; - } - else if ( iformat == mlt_image_rgb24 || iformat == mlt_image_rgb24a ) - { - int bpp = (iformat == mlt_image_rgb24a ? 4 : 3 ); - - // Create the yuv image - uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 ); - - if ( strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) ) - { - GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( *image, GDK_COLORSPACE_RGB, - ( iformat == mlt_image_rgb24a ), 8, iwidth, iheight, - iwidth * bpp, NULL, NULL ); - - GdkPixbuf *scaled = gdk_pixbuf_scale_simple( pixbuf, owidth, oheight, interp ); - g_object_unref( pixbuf ); - - // Extract YUV422 and alpha - if ( bpp == 4 ) - { - // Allocate the alpha mask - uint8_t *alpha = mlt_pool_alloc( owidth * ( oheight + 1 ) ); - - // Convert the image and extract alpha - mlt_convert_rgb24a_to_yuv422( gdk_pixbuf_get_pixels( scaled ), owidth, oheight, gdk_pixbuf_get_rowstride( scaled ), output, alpha ); - - mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL ); - } - else - { - // No alpha to extract - mlt_convert_rgb24_to_yuv422( gdk_pixbuf_get_pixels( scaled ), owidth, oheight, gdk_pixbuf_get_rowstride( scaled ), output ); - } - g_object_unref( scaled ); - } - else - { - // Extract YUV422 and alpha - if ( bpp == 4 ) - { - // Allocate the alpha mask - uint8_t *alpha = mlt_pool_alloc( owidth * ( oheight + 1 ) ); - - // Convert the image and extract alpha - mlt_convert_rgb24a_to_yuv422( *image, owidth, oheight, owidth * 4, output, alpha ); - - mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL ); - } - else - { - // No alpha to extract - mlt_convert_rgb24_to_yuv422( *image, owidth, oheight, owidth * 3, output ); - } - } - - // Now update the frame - mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", owidth ); - mlt_properties_set_int( properties, "height", oheight ); - - *image = output; - } - - return 0; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_rescale_init( mlt_profile profile, char *arg ) -{ - // Create a new scaler - mlt_filter this = mlt_factory_filter( profile, "rescale", arg ); - - // If successful, then initialise it - if ( this != NULL ) - { - // Get the properties - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Set the inerpolation - mlt_properties_set( properties, "interpolation", arg == NULL ? "bilinear" : arg ); - - // Set the method - mlt_properties_set_data( properties, "method", filter_scale, 0, NULL, NULL ); - } - - return this; -} - diff --git a/src/modules/gtk2/have_mmx.S b/src/modules/gtk2/have_mmx.S deleted file mode 100644 index 4f8f5d8..0000000 --- a/src/modules/gtk2/have_mmx.S +++ /dev/null @@ -1,53 +0,0 @@ - .file "have_mmx.S" - .version "01.01" -gcc2_compiled.: -.text - .align 16 - -#if !defined(__MINGW32__) && !defined(__CYGWIN__) - -.globl pixops_have_mmx - .type pixops_have_mmx,@function -pixops_have_mmx: - -#else - -.globl _pixops_have_mmx -_pixops_have_mmx: - -#endif - - push %ebx - -# Check if bit 21 in flags word is writeable - - pushfl - popl %eax - movl %eax,%ebx - xorl $0x00200000, %eax - pushl %eax - popfl - pushfl - popl %eax - - cmpl %eax, %ebx - - je .notfound - -# OK, we have CPUID - - movl $1, %eax - cpuid - - test $0x00800000, %edx - jz .notfound - - movl $1, %eax - jmp .out - -.notfound: - movl $0, %eax -.out: - popl %ebx - ret - diff --git a/src/modules/gtk2/pixops.c b/src/modules/gtk2/pixops.c deleted file mode 100644 index 05b8292..0000000 --- a/src/modules/gtk2/pixops.c +++ /dev/null @@ -1,769 +0,0 @@ -/* GdkPixbuf library - Scaling and compositing functions - * - * Original: - * Copyright (C) 2000 Red Hat, Inc - * Author: Owen Taylor - * - * Modification for MLT: - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include -#include -#include - -#include "pixops.h" - -#define SUBSAMPLE_BITS 4 -#define SUBSAMPLE (1 << SUBSAMPLE_BITS) -#define SUBSAMPLE_MASK ((1 << SUBSAMPLE_BITS)-1) -#define SCALE_SHIFT 16 - -typedef struct _PixopsFilter PixopsFilter; -typedef struct _PixopsFilterDimension PixopsFilterDimension; - -struct _PixopsFilterDimension -{ - int n; - double offset; - double *weights; -}; - -struct _PixopsFilter -{ - PixopsFilterDimension x; - PixopsFilterDimension y; - double overall_alpha; -}; - -typedef guchar *( *PixopsLineFunc ) ( int *weights, int n_x, int n_y, - guchar *dest, int dest_x, guchar *dest_end, - guchar **src, - int x_init, int x_step, int src_width ); - -typedef void ( *PixopsPixelFunc ) ( guchar *dest, guint y1, guint cr, guint y2, guint cb ); - - -/* mmx function declarations */ -#if defined(USE_MMX) && !defined(ARCH_X86_64) -guchar *pixops_scale_line_22_yuv_mmx ( guint32 weights[ 16 ][ 8 ], guchar *p, guchar *q1, guchar *q2, int x_step, guchar *p_stop, int x_init, int destx ); -int pixops_have_mmx ( void ); -#endif - -static inline int -get_check_shift ( int check_size ) -{ - int check_shift = 0; - g_return_val_if_fail ( check_size >= 0, 4 ); - - while ( !( check_size & 1 ) ) - { - check_shift++; - check_size >>= 1; - } - - return check_shift; -} - -static inline void -pixops_scale_nearest ( guchar *dest_buf, - int render_x0, - int render_y0, - int render_x1, - int render_y1, - int dest_rowstride, - const guchar *src_buf, - int src_width, - int src_height, - int src_rowstride, - double scale_x, - double scale_y ) -{ - register int i, j; - register int x_step = ( 1 << SCALE_SHIFT ) / scale_x; - register int y_step = ( 1 << SCALE_SHIFT ) / scale_y; - register int x, x_scaled; - - for ( i = 0; i < ( render_y1 - render_y0 ); i++ ) - { - const guchar *src = src_buf + ( ( ( i + render_y0 ) * y_step + ( y_step >> 1 ) ) >> SCALE_SHIFT ) * src_rowstride; - guchar *dest = dest_buf + i * dest_rowstride; - x = render_x0 * x_step + ( x_step >> 1 ); - - for ( j = 0; j < ( render_x1 - render_x0 ); j++ ) - { - x_scaled = x >> SCALE_SHIFT; - *dest++ = src[ x_scaled << 1 ]; - *dest++ = src[ ( ( x_scaled >> 1 ) << 2 ) + ( ( j & 1 ) << 1 ) + 1 ]; - x += x_step; - } - } -} - - -static inline guchar * -scale_line ( int *weights, int n_x, int n_y, - guchar *dest, int dest_x, guchar *dest_end, - guchar **src, - int x_init, int x_step, int src_width ) -{ - register int x = x_init; - register int i, j, x_scaled, y_index, uv_index; - - while ( dest < dest_end ) - { - unsigned int y = 0, uv = 0; - int *pixel_weights = weights + ( ( x >> ( SCALE_SHIFT - SUBSAMPLE_BITS ) ) & SUBSAMPLE_MASK ) * n_x * n_y; - - x_scaled = x >> SCALE_SHIFT; - y_index = x_scaled << 1; - uv_index = ( ( x_scaled >> 1 ) << 2 ) + ( ( dest_x & 1 ) << 1 ) + 1; - - for ( i = 0; i < n_y; i++ ) - { - int *line_weights = pixel_weights + n_x * i; - guchar *q = src[ i ]; - - for ( j = 0; j < n_x; j ++ ) - { - unsigned int ta = line_weights[ j ]; - - y += ta * q[ y_index ]; - uv += ta * q[ uv_index ]; - } - } - - *dest++ = ( y + 0xffff ) >> SCALE_SHIFT; - *dest++ = ( uv + 0xffff ) >> SCALE_SHIFT; - - x += x_step; - dest_x++; - } - - return dest; -} - -#if defined(USE_MMX) && !defined(ARCH_X86_64) -static inline guchar * -scale_line_22_yuv_mmx_stub ( int *weights, int n_x, int n_y, - guchar *dest, int dest_x, guchar *dest_end, - guchar **src, - int x_init, int x_step, int src_width ) -{ - guint32 mmx_weights[ 16 ][ 8 ]; - int j; - - for ( j = 0; j < 16; j++ ) - { - mmx_weights[ j ][ 0 ] = 0x00010001 * ( weights[ 4 * j ] >> 8 ); - mmx_weights[ j ][ 1 ] = 0x00010001 * ( weights[ 4 * j ] >> 8 ); - mmx_weights[ j ][ 2 ] = 0x00010001 * ( weights[ 4 * j + 1 ] >> 8 ); - mmx_weights[ j ][ 3 ] = 0x00010001 * ( weights[ 4 * j + 1 ] >> 8 ); - mmx_weights[ j ][ 4 ] = 0x00010001 * ( weights[ 4 * j + 2 ] >> 8 ); - mmx_weights[ j ][ 5 ] = 0x00010001 * ( weights[ 4 * j + 2 ] >> 8 ); - mmx_weights[ j ][ 6 ] = 0x00010001 * ( weights[ 4 * j + 3 ] >> 8 ); - mmx_weights[ j ][ 7 ] = 0x00010001 * ( weights[ 4 * j + 3 ] >> 8 ); - } - - return pixops_scale_line_22_yuv_mmx ( mmx_weights, dest, src[ 0 ], src[ 1 ], x_step, dest_end, x_init, dest_x ); -} -#endif /* USE_MMX */ - -static inline guchar * -scale_line_22_yuv ( int *weights, int n_x, int n_y, - guchar *dest, int dest_x, guchar *dest_end, - guchar **src, - int x_init, int x_step, int src_width ) -{ - register int x = x_init; - register guchar *src0 = src[ 0 ]; - register guchar *src1 = src[ 1 ]; - register unsigned int p; - register guchar *q0, *q1; - register int w1, w2, w3, w4; - register int x_scaled, x_aligned, uv_index; - - while ( dest < dest_end ) - { - int *pixel_weights = weights + ( ( x >> ( SCALE_SHIFT - SUBSAMPLE_BITS ) ) & SUBSAMPLE_MASK ) * 4; - - x_scaled = x >> SCALE_SHIFT; - - w1 = pixel_weights[ 0 ]; - w2 = pixel_weights[ 1 ]; - w3 = pixel_weights[ 2 ]; - w4 = pixel_weights[ 3 ]; - - /* process Y */ - q0 = src0 + ( x_scaled << 1 ); - q1 = src1 + ( x_scaled << 1 ); - p = w1 * q0[ 0 ]; - p += w2 * q0[ 2 ]; - p += w3 * q1[ 0 ]; - p += w4 * q1[ 2 ]; - *dest++ = ( p + 0x8000 ) >> SCALE_SHIFT; - - /* process U/V */ - x_aligned = ( ( x_scaled >> 1 ) << 2 ); - uv_index = ( ( dest_x & 1 ) << 1 ) + 1; - - q0 = src0 + x_aligned; - q1 = src1 + x_aligned; - p = w1 * q0[ uv_index ]; - p += w3 * q1[ uv_index ]; - p += w2 * q0[ uv_index ]; - p += w4 * q1[ uv_index ]; - - x += x_step; - dest_x ++; - - *dest++ = ( p + 0x8000 ) >> SCALE_SHIFT; - } - - return dest; -} - - -static inline void -process_pixel ( int *weights, int n_x, int n_y, - guchar *dest, int dest_x, int dest_channels, - guchar **src, int src_channels, - int x_start, int src_width ) -{ - register unsigned int y = 0, uv = 0; - register int i, j; - int uv_index = ( ( dest_x & 1 ) << 1 ) + 1; - - for ( i = 0; i < n_y; i++ ) - { - int *line_weights = weights + n_x * i; - - for ( j = 0; j < n_x; j++ ) - { - unsigned int ta = 0xff * line_weights[ j ]; - - if ( x_start + j < 0 ) - { - y += ta * src[ i ][ 0 ]; - uv += ta * src[ i ][ uv_index ]; - } - else if ( x_start + j < src_width ) - { - y += ta * src[ i ][ ( x_start + j ) << 1 ]; - uv += ta * src[ i ][ ( ( ( x_start + j ) >> 1 ) << 2) + uv_index ]; - } - else - { - y += ta * src[ i ][ ( src_width - 1 ) << 1 ]; - uv += ta * src[ i ][ ( ( ( src_width - 1 ) >> 1 ) << 2) + uv_index ]; - } - } - } - - *dest++ = ( y + 0xffffff ) >> 24; - *dest++ = ( uv + 0xffffff ) >> 24; -} - - -static inline void -correct_total ( int *weights, - int n_x, - int n_y, - int total, - double overall_alpha ) -{ - int correction = ( int ) ( 0.5 + 65536 * overall_alpha ) - total; - int remaining, c, d, i; - - if ( correction != 0 ) - { - remaining = correction; - for ( d = 1, c = correction; c != 0 && remaining != 0; d++, c = correction / d ) - for ( i = n_x * n_y - 1; i >= 0 && c != 0 && remaining != 0; i-- ) - if ( *( weights + i ) + c >= 0 ) - { - *( weights + i ) += c; - remaining -= c; - if ( ( 0 < remaining && remaining < c ) || - ( 0 > remaining && remaining > c ) ) - c = remaining; - } - } -} - - -static inline int * -make_filter_table ( PixopsFilter *filter ) -{ - int i_offset, j_offset; - int n_x = filter->x.n; - int n_y = filter->y.n; - int *weights = g_new ( int, SUBSAMPLE * SUBSAMPLE * n_x * n_y ); - - for ( i_offset = 0; i_offset < SUBSAMPLE; i_offset++ ) - for ( j_offset = 0; j_offset < SUBSAMPLE; j_offset++ ) - { - double weight; - int *pixel_weights = weights + ( ( i_offset * SUBSAMPLE ) + j_offset ) * n_x * n_y; - int total = 0; - int i, j; - - for ( i = 0; i < n_y; i++ ) - for ( j = 0; j < n_x; j++ ) - { - weight = filter->x.weights[ ( j_offset * n_x ) + j ] * - filter->y.weights[ ( i_offset * n_y ) + i ] * - filter->overall_alpha * 65536 + 0.5; - - total += ( int ) weight; - - *( pixel_weights + n_x * i + j ) = weight; - } - - correct_total ( pixel_weights, n_x, n_y, total, filter->overall_alpha ); - } - - return weights; -} - - -static inline void -pixops_process ( guchar *dest_buf, - int render_x0, - int render_y0, - int render_x1, - int render_y1, - int dest_rowstride, - int dest_channels, - gboolean dest_has_alpha, - const guchar *src_buf, - int src_width, - int src_height, - int src_rowstride, - int src_channels, - gboolean src_has_alpha, - double scale_x, - double scale_y, - int check_x, - int check_y, - int check_size, - guint32 color1, - guint32 color2, - PixopsFilter *filter, - PixopsLineFunc line_func ) -{ - int i, j; - int x, y; /* X and Y position in source (fixed_point) */ - - guchar **line_bufs = g_new ( guchar *, filter->y.n ); - int *filter_weights = make_filter_table ( filter ); - - int x_step = ( 1 << SCALE_SHIFT ) / scale_x; /* X step in source (fixed point) */ - int y_step = ( 1 << SCALE_SHIFT ) / scale_y; /* Y step in source (fixed point) */ - - int check_shift = check_size ? get_check_shift ( check_size ) : 0; - - int scaled_x_offset = floor ( filter->x.offset * ( 1 << SCALE_SHIFT ) ); - - /* Compute the index where we run off the end of the source buffer. The furthest - * source pixel we access at index i is: - * - * ((render_x0 + i) * x_step + scaled_x_offset) >> SCALE_SHIFT + filter->x.n - 1 - * - * So, run_end_index is the smallest i for which this pixel is src_width, i.e, for which: - * - * (i + render_x0) * x_step >= ((src_width - filter->x.n + 1) << SCALE_SHIFT) - scaled_x_offset - * - */ -#define MYDIV(a,b) ((a) > 0 ? (a) / (b) : ((a) - (b) + 1) / (b)) /* Division so that -1/5 = -1 */ - - int run_end_x = ( ( ( src_width - filter->x.n + 1 ) << SCALE_SHIFT ) - scaled_x_offset ); - int run_end_index = MYDIV ( run_end_x + x_step - 1, x_step ) - render_x0; - run_end_index = MIN ( run_end_index, render_x1 - render_x0 ); - - y = render_y0 * y_step + floor ( filter->y.offset * ( 1 << SCALE_SHIFT ) ); - for ( i = 0; i < ( render_y1 - render_y0 ); i++ ) - { - int dest_x; - int y_start = y >> SCALE_SHIFT; - int x_start; - int *run_weights = filter_weights + - ( ( y >> ( SCALE_SHIFT - SUBSAMPLE_BITS ) ) & SUBSAMPLE_MASK ) * - filter->x.n * filter->y.n * SUBSAMPLE; - guchar *new_outbuf; - guint32 tcolor1, tcolor2; - - guchar *outbuf = dest_buf + dest_rowstride * i; - guchar *outbuf_end = outbuf + dest_channels * ( render_x1 - render_x0 ); - - if ( ( ( i + check_y ) >> check_shift ) & 1 ) - { - tcolor1 = color2; - tcolor2 = color1; - } - else - { - tcolor1 = color1; - tcolor2 = color2; - } - - for ( j = 0; j < filter->y.n; j++ ) - { - if ( y_start < 0 ) - line_bufs[ j ] = ( guchar * ) src_buf; - else if ( y_start < src_height ) - line_bufs[ j ] = ( guchar * ) src_buf + src_rowstride * y_start; - else - line_bufs[ j ] = ( guchar * ) src_buf + src_rowstride * ( src_height - 1 ); - - y_start++; - } - - dest_x = check_x; - x = render_x0 * x_step + scaled_x_offset; - x_start = x >> SCALE_SHIFT; - - while ( x_start < 0 && outbuf < outbuf_end ) - { - process_pixel ( run_weights + ( ( x >> ( SCALE_SHIFT - SUBSAMPLE_BITS ) ) & SUBSAMPLE_MASK ) * ( filter->x.n * filter->y.n ), - filter->x.n, filter->y.n, - outbuf, dest_x, dest_channels, - line_bufs, src_channels, - x >> SCALE_SHIFT, src_width ); - - x += x_step; - x_start = x >> SCALE_SHIFT; - dest_x++; - outbuf += dest_channels; - } - - new_outbuf = ( *line_func ) ( run_weights, filter->x.n, filter->y.n, - outbuf, dest_x, - dest_buf + dest_rowstride * i + run_end_index * dest_channels, - line_bufs, - x, x_step, src_width ); - - dest_x += ( new_outbuf - outbuf ) / dest_channels; - - x = ( dest_x - check_x + render_x0 ) * x_step + scaled_x_offset; - outbuf = new_outbuf; - - while ( outbuf < outbuf_end ) - { - process_pixel ( run_weights + ( ( x >> ( SCALE_SHIFT - SUBSAMPLE_BITS ) ) & SUBSAMPLE_MASK ) * ( filter->x.n * filter->y.n ), - filter->x.n, filter->y.n, - outbuf, dest_x, dest_channels, - line_bufs, src_channels, - x >> SCALE_SHIFT, src_width ); - - x += x_step; - dest_x++; - outbuf += dest_channels; - } - - y += y_step; - } - - g_free ( line_bufs ); - g_free ( filter_weights ); -} - - -/* Compute weights for reconstruction by replication followed by - * sampling with a box filter - */ -static inline void -tile_make_weights ( PixopsFilterDimension *dim, - double scale ) -{ - int n = ceil ( 1 / scale + 1 ); - double *pixel_weights = g_new ( double, SUBSAMPLE * n ); - int offset; - int i; - - dim->n = n; - dim->offset = 0; - dim->weights = pixel_weights; - - for ( offset = 0; offset < SUBSAMPLE; offset++ ) - { - double x = ( double ) offset / SUBSAMPLE; - double a = x + 1 / scale; - - for ( i = 0; i < n; i++ ) - { - if ( i < x ) - { - if ( i + 1 > x ) - * ( pixel_weights++ ) = ( MIN ( i + 1, a ) - x ) * scale; - else - *( pixel_weights++ ) = 0; - } - else - { - if ( a > i ) - * ( pixel_weights++ ) = ( MIN ( i + 1, a ) - i ) * scale; - else - *( pixel_weights++ ) = 0; - } - } - } -} - -/* Compute weights for a filter that, for minification - * is the same as 'tiles', and for magnification, is bilinear - * reconstruction followed by a sampling with a delta function. - */ -static inline void -bilinear_magnify_make_weights ( PixopsFilterDimension *dim, - double scale ) -{ - double * pixel_weights; - int n; - int offset; - int i; - - if ( scale > 1.0 ) /* Linear */ - { - n = 2; - dim->offset = 0.5 * ( 1 / scale - 1 ); - } - else /* Tile */ - { - n = ceil ( 1.0 + 1.0 / scale ); - dim->offset = 0.0; - } - - dim->n = n; - dim->weights = g_new ( double, SUBSAMPLE * n ); - - pixel_weights = dim->weights; - - for ( offset = 0; offset < SUBSAMPLE; offset++ ) - { - double x = ( double ) offset / SUBSAMPLE; - - if ( scale > 1.0 ) /* Linear */ - { - for ( i = 0; i < n; i++ ) - *( pixel_weights++ ) = ( ( ( i == 0 ) ? ( 1 - x ) : x ) / scale ) * scale; - } - else /* Tile */ - { - double a = x + 1 / scale; - - /* x - * ---------|--.-|----|--.-|------- SRC - * ------------|---------|--------- DEST - */ - for ( i = 0; i < n; i++ ) - { - if ( i < x ) - { - if ( i + 1 > x ) - * ( pixel_weights++ ) = ( MIN ( i + 1, a ) - x ) * scale; - else - *( pixel_weights++ ) = 0; - } - else - { - if ( a > i ) - * ( pixel_weights++ ) = ( MIN ( i + 1, a ) - i ) * scale; - else - *( pixel_weights++ ) = 0; - } - } - } - } -} - -/* Computes the integral from b0 to b1 of - * - * f(x) = x; 0 <= x < 1 - * f(x) = 0; otherwise - * - * We combine two of these to compute the convolution of - * a box filter with a triangular spike. - */ -static inline double -linear_box_half ( double b0, double b1 ) -{ - double a0, a1; - double x0, x1; - - a0 = 0.; - a1 = 1.; - - if ( a0 < b0 ) - { - if ( a1 > b0 ) - { - x0 = b0; - x1 = MIN ( a1, b1 ); - } - else - return 0; - } - else - { - if ( b1 > a0 ) - { - x0 = a0; - x1 = MIN ( a1, b1 ); - } - else - return 0; - } - - return 0.5 * ( x1 * x1 - x0 * x0 ); -} - -/* Compute weights for reconstructing with bilinear - * interpolation, then sampling with a box filter - */ -static inline void -bilinear_box_make_weights ( PixopsFilterDimension *dim, - double scale ) -{ - int n = ceil ( 1 / scale + 2.0 ); - double *pixel_weights = g_new ( double, SUBSAMPLE * n ); - double w; - int offset, i; - - dim->offset = -1.0; - dim->n = n; - dim->weights = pixel_weights; - - for ( offset = 0 ; offset < SUBSAMPLE; offset++ ) - { - double x = ( double ) offset / SUBSAMPLE; - double a = x + 1 / scale; - - for ( i = 0; i < n; i++ ) - { - w = linear_box_half ( 0.5 + i - a, 0.5 + i - x ); - w += linear_box_half ( 1.5 + x - i, 1.5 + a - i ); - - *( pixel_weights++ ) = w * scale; - } - } -} - - -static inline void -make_weights ( PixopsFilter *filter, - PixopsInterpType interp_type, - double scale_x, - double scale_y ) -{ - switch ( interp_type ) - { - case PIXOPS_INTERP_NEAREST: - g_assert_not_reached (); - break; - - case PIXOPS_INTERP_TILES: - tile_make_weights ( &filter->x, scale_x ); - tile_make_weights ( &filter->y, scale_y ); - break; - - case PIXOPS_INTERP_BILINEAR: - bilinear_magnify_make_weights ( &filter->x, scale_x ); - bilinear_magnify_make_weights ( &filter->y, scale_y ); - break; - - case PIXOPS_INTERP_HYPER: - bilinear_box_make_weights ( &filter->x, scale_x ); - bilinear_box_make_weights ( &filter->y, scale_y ); - break; - } -} - - -void -yuv422_scale ( guchar *dest_buf, - int render_x0, - int render_y0, - int render_x1, - int render_y1, - int dest_rowstride, - int dest_channels, - gboolean dest_has_alpha, - const guchar *src_buf, - int src_width, - int src_height, - int src_rowstride, - int src_channels, - gboolean src_has_alpha, - double scale_x, - double scale_y, - PixopsInterpType interp_type ) -{ - PixopsFilter filter = { { 0, 0, 0}, { 0, 0, 0 }, 0 }; - PixopsLineFunc line_func; - -#if defined(USE_MMX) && !defined(ARCH_X86_64) - gboolean found_mmx = pixops_have_mmx(); -#endif - - //g_return_if_fail ( !( dest_channels == 3 && dest_has_alpha ) ); - //g_return_if_fail ( !( src_channels == 3 && src_has_alpha ) ); - //g_return_if_fail ( !( src_has_alpha && !dest_has_alpha ) ); - - if ( scale_x == 0 || scale_y == 0 ) - return ; - - if ( interp_type == PIXOPS_INTERP_NEAREST ) - { - pixops_scale_nearest ( dest_buf, render_x0, render_y0, render_x1, render_y1, - dest_rowstride, - src_buf, src_width, src_height, src_rowstride, - scale_x, scale_y ); - return; - } - - filter.overall_alpha = 1.0; - make_weights ( &filter, interp_type, scale_x, scale_y ); - - if ( filter.x.n == 2 && filter.y.n == 2 ) - { -#if defined(USE_MMX) && !defined(ARCH_X86_64) - if ( found_mmx ) - { - //fprintf( stderr, "rescale: using mmx\n" ); - line_func = scale_line_22_yuv_mmx_stub; - } - else -#endif - - line_func = scale_line_22_yuv; - } - else - line_func = scale_line; - - pixops_process ( dest_buf, render_x0, render_y0, render_x1, render_y1, - dest_rowstride, dest_channels, dest_has_alpha, - src_buf, src_width, src_height, src_rowstride, src_channels, - src_has_alpha, scale_x, scale_y, 0, 0, 0, 0, 0, - &filter, line_func ); - - g_free ( filter.x.weights ); - g_free ( filter.y.weights ); -} - diff --git a/src/modules/gtk2/pixops.h b/src/modules/gtk2/pixops.h deleted file mode 100644 index 5b159fa..0000000 --- a/src/modules/gtk2/pixops.h +++ /dev/null @@ -1,72 +0,0 @@ -/* GdkPixbuf library - Scaling and compositing functions - * - * Original: - * Copyright (C) 2000 Red Hat, Inc - * Author: Owen Taylor - * - * Modification for MLT: - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef PIXOPS_H -#define PIXOPS_H - -#include - -/* Interpolation modes; must match GdkInterpType */ -typedef enum { - PIXOPS_INTERP_NEAREST, - PIXOPS_INTERP_TILES, - PIXOPS_INTERP_BILINEAR, - PIXOPS_INTERP_HYPER -} PixopsInterpType; - -/* Scale src_buf from src_width / src_height by factors scale_x, scale_y - * and composite the portion corresponding to - * render_x, render_y, render_width, render_height in the new - * coordinate system into dest_buf starting at 0, 0 - */ -void yuv422_scale (guchar *dest_buf, - int render_x0, - int render_y0, - int render_x1, - int render_y1, - int dest_rowstride, - int dest_channels, - int dest_has_alpha, - const guchar *src_buf, - int src_width, - int src_height, - int src_rowstride, - int src_channels, - int src_has_alpha, - double scale_x, - double scale_y, - PixopsInterpType interp_type); - -#define yuv422_scale_simple( dest_buf, dest_width, dest_height, dest_rowstride, src_buf, src_width, src_height, src_rowstride, interp_type ) \ - yuv422_scale( (dest_buf), 0, 0, \ - (dest_width), (dest_height), \ - (dest_rowstride), 2, 0, \ - (src_buf), (src_width), (src_height), \ - (src_rowstride), 2, 0, \ - (double) (dest_width) / (src_width), (double) (dest_height) / (src_height), \ - (PixopsInterpType) interp_type ); - -#endif diff --git a/src/modules/gtk2/producer_pango.c b/src/modules/gtk2/producer_pango.c deleted file mode 100644 index 3398e79..0000000 --- a/src/modules/gtk2/producer_pango.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * producer_pango.c -- a pango-based titler - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct producer_pango_s *producer_pango; - -typedef enum -{ - pango_align_left = 0, - pango_align_center, - pango_align_right -} pango_align; - -static pthread_mutex_t pango_mutex = PTHREAD_MUTEX_INITIALIZER; - -struct producer_pango_s -{ - struct mlt_producer_s parent; - int width; - int height; - uint8_t *image; - uint8_t *alpha; - char *fgcolor; - char *bgcolor; - int align; - int pad; - char *markup; - char *text; - char *font; - int weight; -}; - -// special color type used by internal pango routines -typedef struct -{ - uint8_t r, g, b, a; -} rgba_color; - -// Forward declarations -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer parent ); -static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg ); -static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, - rgba_color fg, rgba_color bg, int pad, int align, int weight, int size ); - -/** Return nonzero if the two strings are equal, ignoring case, up to - the first n characters. -*/ -int strncaseeq(const char *s1, const char *s2, size_t n) -{ - for ( ; n > 0; n--) - { - if (tolower(*s1++) != tolower(*s2++)) - return 0; - } - return 1; -} - -/** Parse the alignment property. -*/ - -static int alignment_parse( char* align ) -{ - int ret = pango_align_left; - - if ( align == NULL ); - else if ( isdigit( align[ 0 ] ) ) - ret = atoi( align ); - else if ( align[ 0 ] == 'c' || align[ 0 ] == 'm' ) - ret = pango_align_center; - else if ( align[ 0 ] == 'r' ) - ret = pango_align_right; - - return ret; -} - -static PangoFT2FontMap *fontmap = NULL; - -mlt_producer producer_pango_init( const char *filename ) -{ - producer_pango this = calloc( sizeof( struct producer_pango_s ), 1 ); - if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) - { - mlt_producer producer = &this->parent; - - pthread_mutex_lock( &pango_mutex ); - if ( fontmap == NULL ) - fontmap = (PangoFT2FontMap*) pango_ft2_font_map_new(); - g_type_init(); - pthread_mutex_unlock( &pango_mutex ); - - producer->get_frame = producer_get_frame; - producer->close = ( mlt_destructor )producer_close; - - // Get the properties interface - mlt_properties properties = MLT_PRODUCER_PROPERTIES( &this->parent ); - - // Set the default properties - mlt_properties_set( properties, "fgcolour", "0xffffffff" ); - mlt_properties_set( properties, "bgcolour", "0x00000000" ); - mlt_properties_set_int( properties, "align", pango_align_left ); - mlt_properties_set_int( properties, "pad", 0 ); - mlt_properties_set( properties, "text", "" ); - mlt_properties_set( properties, "font", "Sans 48" ); - mlt_properties_set( properties, "encoding", "UTF-8" ); - mlt_properties_set_int( properties, "weight", PANGO_WEIGHT_NORMAL ); - - if ( filename == NULL ) - { - mlt_properties_set( properties, "markup", "" ); - } - else if ( filename[ 0 ] == '+' || strstr( filename, "/+" ) ) - { - char *copy = strdup( filename + 1 ); - char *markup = copy; - if ( strstr( markup, "/+" ) ) - markup = strstr( markup, "/+" ) + 2; - ( *strrchr( markup, '.' ) ) = '\0'; - while ( strchr( markup, '~' ) ) - ( *strchr( markup, '~' ) ) = '\n'; - mlt_properties_set( properties, "resource", filename ); - mlt_properties_set( properties, "markup", markup ); - free( copy ); - } - else if ( strstr( filename, ".mpl" ) ) - { - int i = 0; - mlt_properties contents = mlt_properties_load( filename ); - mlt_geometry key_frames = mlt_geometry_init( ); - struct mlt_geometry_item_s item; - mlt_properties_set( properties, "resource", filename ); - mlt_properties_set_data( properties, "contents", contents, 0, ( mlt_destructor )mlt_properties_close, NULL ); - mlt_properties_set_data( properties, "key_frames", key_frames, 0, ( mlt_destructor )mlt_geometry_close, NULL ); - - // Make sure we have at least one entry - if ( mlt_properties_get( contents, "0" ) == NULL ) - mlt_properties_set( contents, "0", "" ); - - for ( i = 0; i < mlt_properties_count( contents ); i ++ ) - { - char *name = mlt_properties_get_name( contents, i ); - char *value = mlt_properties_get_value( contents, i ); - while ( value != NULL && strchr( value, '~' ) ) - ( *strchr( value, '~' ) ) = '\n'; - item.frame = atoi( name ); - mlt_geometry_insert( key_frames, &item ); - } - } - else - { - FILE *f = fopen( filename, "r" ); - if ( f != NULL ) - { - char line[81]; - char *markup = NULL; - size_t size = 0; - line[80] = '\0'; - - while ( fgets( line, 80, f ) ) - { - size += strlen( line ) + 1; - if ( markup ) - { - markup = realloc( markup, size ); - strcat( markup, line ); - } - else - { - markup = strdup( line ); - } - } - fclose( f ); - - if ( markup[ strlen( markup ) - 1 ] == '\n' ) - markup[ strlen( markup ) - 1 ] = '\0'; - - mlt_properties_set( properties, "resource", filename ); - mlt_properties_set( properties, "markup", ( markup == NULL ? "" : markup ) ); - free( markup ); - } - else - { - mlt_properties_set( properties, "markup", "" ); - } - } - - return producer; - } - free( this ); - return NULL; -} - -static void set_string( char **string, const char *value, const char *fallback ) -{ - if ( value != NULL ) - { - free( *string ); - *string = strdup( value ); - } - else if ( *string == NULL && fallback != NULL ) - { - *string = strdup( fallback ); - } - else if ( *string != NULL && fallback == NULL ) - { - free( *string ); - *string = NULL; - } -} - -rgba_color parse_color( char *color ) -{ - rgba_color result = { 0xff, 0xff, 0xff, 0xff }; - - if ( !strncmp( color, "0x", 2 ) ) - { - unsigned int temp = 0; - sscanf( color + 2, "%x", &temp ); - result.r = ( temp >> 24 ) & 0xff; - result.g = ( temp >> 16 ) & 0xff; - result.b = ( temp >> 8 ) & 0xff; - result.a = ( temp ) & 0xff; - } - else if ( !strcmp( color, "red" ) ) - { - result.r = 0xff; - result.g = 0x00; - result.b = 0x00; - } - else if ( !strcmp( color, "green" ) ) - { - result.r = 0x00; - result.g = 0xff; - result.b = 0x00; - } - else if ( !strcmp( color, "blue" ) ) - { - result.r = 0x00; - result.g = 0x00; - result.b = 0xff; - } - else - { - unsigned int temp = 0; - sscanf( color, "%d", &temp ); - result.r = ( temp >> 24 ) & 0xff; - result.g = ( temp >> 16 ) & 0xff; - result.b = ( temp >> 8 ) & 0xff; - result.a = ( temp ) & 0xff; - } - - return result; -} - -/** Convert a string property to UTF-8 -*/ -static int iconv_utf8( mlt_properties properties, const char *prop_name, const char* encoding ) -{ - char *text = mlt_properties_get( properties, prop_name ); - int result = -1; - - iconv_t cd = iconv_open( "UTF-8", encoding ); - if ( cd != ( iconv_t )-1 ) - { - char *inbuf_p = text; - size_t inbuf_n = strlen( text ); - size_t outbuf_n = inbuf_n * 6; - char *outbuf = mlt_pool_alloc( outbuf_n ); - char *outbuf_p = outbuf; - - memset( outbuf, 0, outbuf_n ); - - if ( text != NULL && strcmp( text, "" ) && iconv( cd, &inbuf_p, &inbuf_n, &outbuf_p, &outbuf_n ) != -1 ) - mlt_properties_set( properties, prop_name, outbuf ); - else - mlt_properties_set( properties, prop_name, "" ); - - mlt_pool_release( outbuf ); - iconv_close( cd ); - result = 0; - } - return result; -} - -static void refresh_image( mlt_frame frame, int width, int height ) -{ - // Pixbuf - GdkPixbuf *pixbuf = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "pixbuf", NULL ); - - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the producer pango for this frame - producer_pango this = mlt_properties_get_data( properties, "producer_pango", NULL ); - - // Obtain the producer - mlt_producer producer = &this->parent; - - // Obtain the producer properties - mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); - - // Get producer properties - char *fg = mlt_properties_get( producer_props, "fgcolour" ); - char *bg = mlt_properties_get( producer_props, "bgcolour" ); - int align = alignment_parse( mlt_properties_get( producer_props, "align" ) ); - int pad = mlt_properties_get_int( producer_props, "pad" ); - char *markup = mlt_properties_get( producer_props, "markup" ); - char *text = mlt_properties_get( producer_props, "text" ); - char *font = mlt_properties_get( producer_props, "font" ); - char *encoding = mlt_properties_get( producer_props, "encoding" ); - int weight = mlt_properties_get_int( producer_props, "weight" ); - int size = mlt_properties_get_int( producer_props, "size" ); - int property_changed = 0; - - if ( pixbuf == NULL ) - { - // Check for file support - int position = mlt_properties_get_position( properties, "pango_position" ); - mlt_properties contents = mlt_properties_get_data( producer_props, "contents", NULL ); - mlt_geometry key_frames = mlt_properties_get_data( producer_props, "key_frames", NULL ); - struct mlt_geometry_item_s item; - if ( contents != NULL ) - { - char temp[ 20 ]; - mlt_geometry_prev_key( key_frames, &item, position ); - sprintf( temp, "%d", item.frame ); - markup = mlt_properties_get( contents, temp ); - } - - // See if any properties changed - property_changed = ( align != this->align ); - property_changed = property_changed || ( this->fgcolor == NULL || ( fg && strcmp( fg, this->fgcolor ) ) ); - property_changed = property_changed || ( this->bgcolor == NULL || ( bg && strcmp( bg, this->bgcolor ) ) ); - property_changed = property_changed || ( pad != this->pad ); - property_changed = property_changed || ( markup && this->markup && strcmp( markup, this->markup ) ); - property_changed = property_changed || ( text && this->text && strcmp( text, this->text ) ); - property_changed = property_changed || ( font && this->font && strcmp( font, this->font ) ); - property_changed = property_changed || ( weight != this->weight ); - - // Save the properties for next comparison - this->align = align; - this->pad = pad; - set_string( &this->fgcolor, fg, "0xffffffff" ); - set_string( &this->bgcolor, bg, "0x00000000" ); - set_string( &this->markup, markup, NULL ); - set_string( &this->text, text, NULL ); - set_string( &this->font, font, "Sans 48" ); - this->weight = weight; - } - - if ( pixbuf == NULL && property_changed ) - { - rgba_color fgcolor = parse_color( this->fgcolor ); - rgba_color bgcolor = parse_color( this->bgcolor ); - - mlt_pool_release( this->image ); - mlt_pool_release( this->alpha ); - this->image = NULL; - this->alpha = NULL; - - // Convert from specified encoding to UTF-8 - if ( encoding != NULL && !strncaseeq( encoding, "utf-8", 5 ) && !strncaseeq( encoding, "utf8", 4 ) ) - { - if ( markup != NULL && iconv_utf8( producer_props, "markup", encoding ) != -1 ) - { - markup = mlt_properties_get( producer_props, "markup" ); - set_string( &this->markup, markup, NULL ); - } - if ( text != NULL && iconv_utf8( producer_props, "text", encoding ) != -1 ) - { - text = mlt_properties_get( producer_props, "text" ); - set_string( &this->text, text, NULL ); - } - } - - // Render the title - pixbuf = pango_get_pixbuf( markup, text, font, fgcolor, bgcolor, pad, align, weight, size ); - - if ( pixbuf != NULL ) - { - // Register this pixbuf for destruction and reuse - mlt_properties_set_data( producer_props, "pixbuf", pixbuf, 0, ( mlt_destructor )g_object_unref, NULL ); - g_object_ref( pixbuf ); - mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), "pixbuf", pixbuf, 0, ( mlt_destructor )g_object_unref, NULL ); - - mlt_properties_set_int( producer_props, "real_width", gdk_pixbuf_get_width( pixbuf ) ); - mlt_properties_set_int( producer_props, "real_height", gdk_pixbuf_get_height( pixbuf ) ); - - // Store the width/height of the pixbuf temporarily - this->width = gdk_pixbuf_get_width( pixbuf ); - this->height = gdk_pixbuf_get_height( pixbuf ); - } - } - else if ( pixbuf == NULL && ( width > 0 && ( this->image == NULL || width != this->width || height != this->height ) ) ) - { - mlt_pool_release( this->image ); - mlt_pool_release( this->alpha ); - this->image = NULL; - this->alpha = NULL; - - pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL ); - } - - // If we have a pixbuf and a valid width - if ( pixbuf && width > 0 ) - { - char *interps = mlt_properties_get( properties, "rescale.interp" ); - int interp = GDK_INTERP_BILINEAR; - - if ( strcmp( interps, "nearest" ) == 0 ) - interp = GDK_INTERP_NEAREST; - else if ( strcmp( interps, "tiles" ) == 0 ) - interp = GDK_INTERP_TILES; - else if ( strcmp( interps, "hyper" ) == 0 ) - interp = GDK_INTERP_HYPER; - -// fprintf(stderr,"%s: scaling from %dx%d to %dx%d\n", __FILE__, this->width, this->height, width, height); - - // Note - the original pixbuf is already safe and ready for destruction - pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, interp ); - - // Store width and height - this->width = width; - this->height = height; - - // Allocate/define image - this->image = mlt_pool_alloc( width * ( height + 1 ) * 2 ); - this->alpha = mlt_pool_alloc( this->width * this->height ); - - // Convert the image - mlt_convert_rgb24a_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ), - this->width, this->height, - gdk_pixbuf_get_rowstride( pixbuf ), - this->image, this->alpha ); - - // Finished with pixbuf now - g_object_unref( pixbuf ); - } - - // Set width/height - mlt_properties_set_int( properties, "width", this->width ); - mlt_properties_set_int( properties, "height", this->height ); - mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "real_width" ) ); - mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "real_height" ) ); - - // pass the image data without destructor - mlt_properties_set_data( properties, "image", this->image, this->width * ( this->height + 1 ) * 2, NULL, NULL ); - mlt_properties_set_data( properties, "alpha", this->alpha, this->width * this->height, NULL, NULL ); -} - -static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // We need to know the size of the image to clone it - int image_size = 0; - int alpha_size = 0; - - // Alpha channel - uint8_t *alpha = NULL; - - *width = mlt_properties_get_int( properties, "rescale_width" ); - *height = mlt_properties_get_int( properties, "rescale_height" ); - - // Refresh the image - pthread_mutex_lock( &pango_mutex ); - refresh_image( frame, *width, *height ); - - // Get the image - *buffer = mlt_properties_get_data( properties, "image", &image_size ); - alpha = mlt_properties_get_data( properties, "alpha", &alpha_size ); - - // Get width and height - *width = mlt_properties_get_int( properties, "width" ); - *height = mlt_properties_get_int( properties, "height" ); - - // Always clone here to allow 'animated' text - if ( *buffer != NULL ) - { - // Clone the image and the alpha - uint8_t *image_copy = mlt_pool_alloc( image_size ); - uint8_t *alpha_copy = mlt_pool_alloc( alpha_size ); - - memcpy( image_copy, *buffer, image_size ); - - // Copy or default the alpha - if ( alpha != NULL ) - memcpy( alpha_copy, alpha, alpha_size ); - else - memset( alpha_copy, 255, alpha_size ); - - // Now update properties so we free the copy after - mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "alpha", alpha_copy, alpha_size, mlt_pool_release, NULL ); - - // We're going to pass the copy on - *buffer = image_copy; - } - else - { - // TODO: Review all cases of invalid images - *buffer = mlt_pool_alloc( 50 * 50 * 2 ); - mlt_properties_set_data( properties, "image", *buffer, image_size, mlt_pool_release, NULL ); - *width = 50; - *height = 50; - } - - pthread_mutex_unlock( &pango_mutex ); - - return 0; -} - -static uint8_t *producer_get_alpha_mask( mlt_frame this ) -{ - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Return the alpha mask - return mlt_properties_get_data( properties, "alpha", NULL ); -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - producer_pango this = producer->child; - - // Generate a frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - // Obtain properties of frame and producer - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Set the producer on the frame properties - mlt_properties_set_data( properties, "producer_pango", this, 0, NULL, NULL ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - mlt_properties_set_position( properties, "pango_position", mlt_producer_frame( producer ) ); - - // Refresh the pango image - pthread_mutex_lock( &pango_mutex ); - refresh_image( *frame, 0, 0 ); - pthread_mutex_unlock( &pango_mutex ); - - // Set producer-specific frame properties - mlt_properties_set_int( properties, "progressive", 1 ); - mlt_properties_set_double( properties, "aspect_ratio", 1 ); - - // Set alpha call back - ( *frame )->get_alpha_mask = producer_get_alpha_mask; - - // Stack the get image callback - mlt_frame_push_get_image( *frame, producer_get_image ); - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer parent ) -{ - producer_pango this = parent->child; - mlt_pool_release( this->image ); - mlt_pool_release( this->alpha ); - free( this->fgcolor ); - free( this->bgcolor ); - free( this->markup ); - free( this->text ); - free( this->font ); - parent->close = NULL; - mlt_producer_close( parent ); - free( this ); -} - -static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg ) -{ - int ww = gdk_pixbuf_get_width( pixbuf ); - int hh = gdk_pixbuf_get_height( pixbuf ); - uint8_t *p = gdk_pixbuf_get_pixels( pixbuf ); - int i, j; - - for ( j = 0; j < hh; j++ ) - { - for ( i = 0; i < ww; i++ ) - { - *p++ = bg.r; - *p++ = bg.g; - *p++ = bg.b; - *p++ = bg.a; - } - } -} - -static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, rgba_color fg, rgba_color bg, int pad, int align, int weight, int size ) -{ - PangoContext *context = pango_ft2_font_map_create_context( fontmap ); - PangoLayout *layout = pango_layout_new( context ); - int w, h, x; - int i, j; - GdkPixbuf *pixbuf = NULL; - FT_Bitmap bitmap; - uint8_t *src = NULL; - uint8_t* dest = NULL; - uint8_t *d, *s, a; - int stride; - PangoFontDescription *desc = pango_font_description_from_string( font ); - - pango_ft2_font_map_set_resolution( fontmap, 72, 72 ); - pango_layout_set_width( layout, -1 ); // set wrapping constraints - pango_font_description_set_weight( desc, ( PangoWeight ) weight ); - if ( size != 0 ) - pango_font_description_set_absolute_size( desc, PANGO_SCALE * size ); - pango_layout_set_font_description( layout, desc ); -// pango_layout_set_spacing( layout, space ); - pango_layout_set_alignment( layout, ( PangoAlignment ) align ); - if ( markup != NULL && strcmp( markup, "" ) != 0 ) - { - pango_layout_set_markup( layout, markup, strlen( markup ) ); - } - else if ( text != NULL && strcmp( text, "" ) != 0 ) - { - // Replace all ~'s with a line feed (silly convention, but handy) - char *copy = strdup( text ); - while ( strchr( copy, '~' ) ) - ( *strchr( copy, '~' ) ) = '\n'; - pango_layout_set_text( layout, copy, strlen( copy ) ); - free( copy ); - } - else - { - // Pango doesn't like empty strings - pango_layout_set_text( layout, " ", 2 ); - } - pango_layout_get_pixel_size( layout, &w, &h ); - - // Interpret size property as an absolute pixel height and compensate for - // freetype's "interpretation" of our absolute size request. This gives - // precise control over compositing and better quality by reducing scaling - // artifacts with composite geometries that constrain the dimensions. - // If you do not want this, then put the size in the font property or in - // the pango markup. - if ( size != 0 ) - { - pango_font_description_set_absolute_size( desc, PANGO_SCALE * size * size/h ); - pango_layout_set_font_description( layout, desc ); - pango_layout_get_pixel_size( layout, &w, &h ); - } - - pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE /* has alpha */, 8, w + 2 * pad, h + 2 * pad ); - pango_draw_background( pixbuf, bg ); - - stride = gdk_pixbuf_get_rowstride( pixbuf ); - - bitmap.width = w; - bitmap.pitch = 32 * ( ( w + 31 ) / 31 ); - bitmap.rows = h; - bitmap.buffer = mlt_pool_alloc( h * bitmap.pitch ); - bitmap.num_grays = 256; - bitmap.pixel_mode = ft_pixel_mode_grays; - - memset( bitmap.buffer, 0, h * bitmap.pitch ); - - pango_ft2_render_layout( &bitmap, layout, 0, 0 ); - - src = bitmap.buffer; - x = ( gdk_pixbuf_get_width( pixbuf ) - w - 2 * pad ) * align / 2 + pad; - dest = gdk_pixbuf_get_pixels( pixbuf ) + 4 * x + pad * stride; - j = h; - - while( j -- ) - { - d = dest; - s = src; - i = w; - while( i -- ) - { - a = *s ++; - *d++ = ( a * fg.r + ( 255 - a ) * bg.r ) >> 8; - *d++ = ( a * fg.g + ( 255 - a ) * bg.g ) >> 8; - *d++ = ( a * fg.b + ( 255 - a ) * bg.b ) >> 8; - *d++ = ( a * fg.a + ( 255 - a ) * bg.a ) >> 8; - } - dest += stride; - src += bitmap.pitch; - } - mlt_pool_release( bitmap.buffer ); - pango_font_description_free( desc ); - g_object_unref( layout ); - g_object_unref( context ); - - return pixbuf; -} diff --git a/src/modules/gtk2/producer_pixbuf.c b/src/modules/gtk2/producer_pixbuf.c deleted file mode 100644 index 70df32c..0000000 --- a/src/modules/gtk2/producer_pixbuf.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - * producer_pixbuf.c -- raster image loader based upon gdk-pixbuf - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; - -typedef struct producer_pixbuf_s *producer_pixbuf; - -struct producer_pixbuf_s -{ - struct mlt_producer_s parent; - - // File name list - mlt_properties filenames; - int count; - int image_idx; - - int width; - int height; - uint8_t *image; - uint8_t *alpha; - mlt_cache_item image_cache; - mlt_cache_item alpha_cache; - pthread_mutex_t mutex; -}; - -static void load_filenames( producer_pixbuf this, mlt_properties producer_properties ); -static void refresh_image( producer_pixbuf this, mlt_frame frame, int width, int height ); -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer parent ); - -mlt_producer producer_pixbuf_init( char *filename ) -{ - producer_pixbuf this = calloc( sizeof( struct producer_pixbuf_s ), 1 ); - if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) - { - mlt_producer producer = &this->parent; - - // Get the properties interface - mlt_properties properties = MLT_PRODUCER_PROPERTIES( &this->parent ); - - // Callback registration - producer->get_frame = producer_get_frame; - producer->close = ( mlt_destructor )producer_close; - - // Set the default properties - mlt_properties_set( properties, "resource", filename ); - mlt_properties_set_int( properties, "ttl", 25 ); - mlt_properties_set_int( properties, "aspect_ratio", 1 ); - mlt_properties_set_int( properties, "progressive", 1 ); - - // Validate the resource - if ( filename ) - load_filenames( this, properties ); - if ( this->count ) - { - mlt_frame frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - if ( frame ) - { - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - pthread_mutex_init( &this->mutex, NULL ); - mlt_properties_set_data( frame_properties, "producer_pixbuf", this, 0, NULL, NULL ); - mlt_frame_set_position( frame, mlt_producer_position( producer ) ); - mlt_properties_set_position( frame_properties, "pixbuf_position", mlt_producer_position( producer ) ); - refresh_image( this, frame, 0, 0 ); - mlt_frame_close( frame ); - } - } - if ( this->width == 0 ) - { - producer_close( producer ); - producer = NULL; - } - return producer; - } - free( this ); - return NULL; -} - -static void load_filenames( producer_pixbuf this, mlt_properties producer_properties ) -{ - char *filename = mlt_properties_get( producer_properties, "resource" ); - this->filenames = mlt_properties_new( ); - - // Read xml string - if ( strstr( filename, " -1 ) - { - // Write the svg into the temp file - ssize_t remaining_bytes; - char *xml = filename; - - // Strip leading crap - while ( xml[0] != '<' ) - xml++; - - remaining_bytes = strlen( xml ); - while ( remaining_bytes > 0 ) - remaining_bytes -= write( fd, xml + strlen( xml ) - remaining_bytes, remaining_bytes ); - close( fd ); - - mlt_properties_set( this->filenames, "0", fullname ); - - // Teehe - when the producer closes, delete the temp file and the space allo - mlt_properties_set_data( producer_properties, "__temporary_file__", fullname, 0, ( mlt_destructor )unlink, NULL ); - } - } - // Obtain filenames - else if ( strchr( filename, '%' ) != NULL ) - { - // handle picture sequences - int i = mlt_properties_get_int( producer_properties, "begin" ); - int gap = 0; - char full[1024]; - int keyvalue = 0; - char key[ 50 ]; - - while ( gap < 100 ) - { - struct stat buf; - snprintf( full, 1023, filename, i ++ ); - if ( stat( full, &buf ) == 0 ) - { - sprintf( key, "%d", keyvalue ++ ); - mlt_properties_set( this->filenames, key, full ); - gap = 0; - } - else - { - gap ++; - } - } - } - else if ( strstr( filename, "/.all." ) != NULL ) - { - char wildcard[ 1024 ]; - char *dir_name = strdup( filename ); - char *extension = strrchr( dir_name, '.' ); - - *( strstr( dir_name, "/.all." ) + 1 ) = '\0'; - sprintf( wildcard, "*%s", extension ); - - mlt_properties_dir_list( this->filenames, dir_name, wildcard, 1 ); - - free( dir_name ); - } - else - { - mlt_properties_set( this->filenames, "0", filename ); - } - - this->count = mlt_properties_count( this->filenames ); -} - -static void refresh_image( producer_pixbuf this, mlt_frame frame, int width, int height ) -{ - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the producer - mlt_producer producer = &this->parent; - - // Obtain properties of producer - mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); - - // Obtain the cache flag and structure - int use_cache = mlt_properties_get_int( producer_props, "cache" ); - mlt_properties cache = mlt_properties_get_data( producer_props, "_cache", NULL ); - int update_cache = 0; - - // restore GdkPixbuf - pthread_mutex_lock( &this->mutex ); - mlt_cache_item pixbuf_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.pixbuf" ); - GdkPixbuf *pixbuf = mlt_cache_item_data( pixbuf_cache, NULL ); - GError *error = NULL; - - // restore scaled image - this->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image" ); - this->image = mlt_cache_item_data( this->image_cache, NULL ); - - // restore alpha channel - this->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha" ); - this->alpha = mlt_cache_item_data( this->alpha_cache, NULL ); - - // Check if user wants us to reload the image - if ( mlt_properties_get_int( producer_props, "force_reload" ) ) - { - pixbuf = NULL; - this->image = NULL; - mlt_properties_set_int( producer_props, "force_reload", 0 ); - } - - // Get the time to live for each frame - double ttl = mlt_properties_get_int( producer_props, "ttl" ); - - // Get the original position of this frame - mlt_position position = mlt_properties_get_position( properties, "pixbuf_position" ); - position += mlt_producer_get_in( producer ); - - // Image index - int image_idx = ( int )floor( ( double )position / ttl ) % this->count; - - // Key for the cache - char image_key[ 10 ]; - sprintf( image_key, "%d", image_idx ); - - pthread_mutex_lock( &g_mutex ); - - // Check if the frame is already loaded - if ( use_cache ) - { - if ( cache == NULL ) - { - cache = mlt_properties_new( ); - mlt_properties_set_data( producer_props, "_cache", cache, 0, ( mlt_destructor )mlt_properties_close, NULL ); - } - - mlt_frame cached = mlt_properties_get_data( cache, image_key, NULL ); - - if ( cached ) - { - this->image_idx = image_idx; - mlt_properties cached_props = MLT_FRAME_PROPERTIES( cached ); - this->width = mlt_properties_get_int( cached_props, "width" ); - this->height = mlt_properties_get_int( cached_props, "height" ); - mlt_properties_set_int( producer_props, "_real_width", mlt_properties_get_int( cached_props, "real_width" ) ); - mlt_properties_set_int( producer_props, "_real_height", mlt_properties_get_int( cached_props, "real_height" ) ); - this->image = mlt_properties_get_data( cached_props, "image", NULL ); - this->alpha = mlt_properties_get_data( cached_props, "alpha", NULL ); - - if ( width != 0 && ( width != this->width || height != this->height ) ) - this->image = NULL; - } - } - - // optimization for subsequent iterations on single picture - if ( width != 0 && ( image_idx != this->image_idx || width != this->width || height != this->height ) ) - this->image = NULL; - if ( image_idx != this->image_idx ) - pixbuf = NULL; - if ( pixbuf == NULL && ( width == 0 || this->image == NULL ) ) - { - this->image = NULL; - this->image_idx = image_idx; - pixbuf = gdk_pixbuf_new_from_file( mlt_properties_get_value( this->filenames, image_idx ), &error ); - - if ( pixbuf ) - { - // Register this pixbuf for destruction and reuse - mlt_cache_item_close( pixbuf_cache ); - mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.pixbuf", pixbuf, 0, ( mlt_destructor )g_object_unref ); - pixbuf_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.pixbuf" ); - - mlt_events_block( producer_props, NULL ); - mlt_properties_set_int( producer_props, "_real_width", gdk_pixbuf_get_width( pixbuf ) ); - mlt_properties_set_int( producer_props, "_real_height", gdk_pixbuf_get_height( pixbuf ) ); - mlt_events_unblock( producer_props, NULL ); - - // Store the width/height of the pixbuf temporarily - this->width = gdk_pixbuf_get_width( pixbuf ); - this->height = gdk_pixbuf_get_height( pixbuf ); - } - } - - // If we have a pixbuf and we need an image - if ( pixbuf && width > 0 && this->image == NULL ) - { - char *interps = mlt_properties_get( properties, "rescale.interp" ); - int interp = GDK_INTERP_BILINEAR; - - if ( strcmp( interps, "nearest" ) == 0 ) - interp = GDK_INTERP_NEAREST; - else if ( strcmp( interps, "tiles" ) == 0 ) - interp = GDK_INTERP_TILES; - else if ( strcmp( interps, "hyper" ) == 0 ) - interp = GDK_INTERP_HYPER; - - // Note - the original pixbuf is already safe and ready for destruction - pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, interp ); - - // Store width and height - this->width = width; - this->height = height; - - // Allocate/define image - this->image = mlt_pool_alloc( width * ( height + 1 ) * 2 ); - if ( !use_cache ) - mlt_cache_item_close( this->image_cache ); - mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image", this->image, width * ( height + 1 ) * 2, mlt_pool_release ); - this->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image" ); - - // Extract YUV422 and alpha - if ( gdk_pixbuf_get_has_alpha( pixbuf ) ) - { - // Allocate the alpha mask - this->alpha = mlt_pool_alloc( this->width * this->height ); - if ( !use_cache ) - mlt_cache_item_close( this->alpha_cache ); - mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha", this->alpha, width * height, mlt_pool_release ); - this->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha" ); - - // Convert the image - mlt_convert_rgb24a_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ), - this->width, this->height, - gdk_pixbuf_get_rowstride( pixbuf ), - this->image, this->alpha ); - } - else - { - // No alpha to extract - mlt_convert_rgb24_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ), - this->width, this->height, - gdk_pixbuf_get_rowstride( pixbuf ), - this->image ); - } - - // Finished with pixbuf now - g_object_unref( pixbuf ); - - // Ensure we update the cache when we need to - update_cache = use_cache; - } - - // release references no longer needed - mlt_cache_item_close( pixbuf_cache ); - if ( width == 0 ) - { - pthread_mutex_unlock( &this->mutex ); - mlt_cache_item_close( this->image_cache ); - mlt_cache_item_close( this->alpha_cache ); - } - - // Set width/height of frame - mlt_properties_set_int( properties, "width", this->width ); - mlt_properties_set_int( properties, "height", this->height ); - mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "_real_width" ) ); - mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "_real_height" ) ); - - if ( update_cache ) - { - mlt_frame cached = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - mlt_properties cached_props = MLT_FRAME_PROPERTIES( cached ); - mlt_properties_set_int( cached_props, "width", this->width ); - mlt_properties_set_int( cached_props, "height", this->height ); - mlt_properties_set_int( cached_props, "real_width", mlt_properties_get_int( producer_props, "_real_width" ) ); - mlt_properties_set_int( cached_props, "real_height", mlt_properties_get_int( producer_props, "_real_height" ) ); - mlt_properties_set_data( cached_props, "image", this->image, this->width * ( this->height + 1 ) * 2, mlt_pool_release, NULL ); - mlt_properties_set_data( cached_props, "alpha", this->alpha, this->width * this->height, mlt_pool_release, NULL ); - mlt_properties_set_data( cache, image_key, cached, 0, ( mlt_destructor )mlt_frame_close, NULL ); - } - - pthread_mutex_unlock( &g_mutex ); -} - -static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the producer for this frame - producer_pixbuf this = mlt_properties_get_data( properties, "producer_pixbuf", NULL ); - - *width = mlt_properties_get_int( properties, "rescale_width" ); - *height = mlt_properties_get_int( properties, "rescale_height" ); - - // Refresh the image - refresh_image( this, frame, *width, *height ); - - // Get the image size - int image_size = this->width * ( this->height + 1 ) * 2; - int alpha_size = this->width * this->height; - - // Get width and height (may have changed during the refresh) - *width = mlt_properties_get_int( properties, "width" ); - *height = mlt_properties_get_int( properties, "height" ); - - // NB: Cloning is necessary with this producer (due to processing of images ahead of use) - // The fault is not in the design of mlt, but in the implementation of the pixbuf producer... - if ( this->image ) - { - if ( *format == mlt_image_yuv422 || *format == mlt_image_yuv420p ) - { - // Clone the image and the alpha - uint8_t *image_copy = mlt_pool_alloc( image_size ); - uint8_t *alpha_copy = mlt_pool_alloc( alpha_size ); - - memcpy( image_copy, this->image, image_size ); - - // Copy or default the alpha - if ( this->alpha != NULL ) - memcpy( alpha_copy, this->alpha, alpha_size ); - else - memset( alpha_copy, 255, alpha_size ); - - // Now update properties so we free the copy after - mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "alpha", alpha_copy, alpha_size, mlt_pool_release, NULL ); - - // We're going to pass the copy on - *buffer = image_copy; - } - else if ( *format == mlt_image_rgb24a ) - { - // Clone the image and the alpha - image_size = *width * ( *height + 1 ) * 4; - alpha_size = *width * ( *height + 1 ); - uint8_t *image_copy = mlt_pool_alloc( image_size ); - uint8_t *alpha_copy = mlt_pool_alloc( alpha_size ); - - mlt_convert_yuv422_to_rgb24a( this->image, image_copy, (*width)*(*height) ); - - // Now update properties so we free the copy after - mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "alpha", alpha_copy, alpha_size, mlt_pool_release, NULL ); - - // We're going to pass the copy on - *buffer = image_copy; - } - - } - else - { - // TODO: Review all cases of invalid images - *buffer = mlt_pool_alloc( 50 * 50 * 2 ); - mlt_properties_set_data( properties, "image", *buffer, image_size, mlt_pool_release, NULL ); - *width = 50; - *height = 50; - } - - // Release references and locks - pthread_mutex_unlock( &this->mutex ); - mlt_cache_item_close( this->image_cache ); - mlt_cache_item_close( this->alpha_cache ); - - return 0; -} - -static uint8_t *producer_get_alpha_mask( mlt_frame this ) -{ - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Return the alpha mask - return mlt_properties_get_data( properties, "alpha", NULL ); -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Get the real structure for this producer - producer_pixbuf this = producer->child; - - // Fetch the producers properties - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - if ( this->filenames == NULL && mlt_properties_get( producer_properties, "resource" ) != NULL ) - load_filenames( this, producer_properties ); - - // Generate a frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - if ( *frame != NULL && this->count > 0 ) - { - // Obtain properties of frame and producer - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Set the producer on the frame properties - mlt_properties_set_data( properties, "producer_pixbuf", this, 0, NULL, NULL ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Ensure that we have a way to obtain the position in the get_image - mlt_properties_set_position( properties, "pixbuf_position", mlt_producer_position( producer ) ); - - // Refresh the image - refresh_image( this, *frame, 0, 0 ); - - // Set producer-specific frame properties - mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( producer_properties, "progressive" ) ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_properties, "aspect_ratio" ) ); - - // Set alpha call back - ( *frame )->get_alpha_mask = producer_get_alpha_mask; - - // Push the get_image method - mlt_frame_push_get_image( *frame, producer_get_image ); - } - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer parent ) -{ - producer_pixbuf this = parent->child; - pthread_mutex_destroy( &this->mutex ); - parent->close = NULL; - mlt_producer_close( parent ); - mlt_properties_close( this->filenames ); - free( this ); -} diff --git a/src/modules/gtk2/scale_line_22_yuv_mmx.S b/src/modules/gtk2/scale_line_22_yuv_mmx.S deleted file mode 100644 index d78b341..0000000 --- a/src/modules/gtk2/scale_line_22_yuv_mmx.S +++ /dev/null @@ -1,227 +0,0 @@ -/* - * scale_line_22_yuv_mmx.S -- scale line in YUY2 format - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - .file "scale_line_22_yuv_mmx.S" - .version "01.01" - -.extern printf - -gcc2_compiled.: -.data -MSG: .ascii "scale_line_22_yuv_mmx: %d %d\n" - -.text - .align 16 - -#if !defined(__MINGW32__) && !defined(__CYGWIN__) - -.globl pixops_scale_line_22_yuv_mmx - .type pixops_scale_line_22_yuv_mmx,@function -pixops_scale_line_22_yuv_mmx: - -#else - -.globl _pixops_scale_line_22_yuv_mmx -_pixops_scale_line_22_yuv_mmx: - -#endif -/* - * Arguments - * - * weights: 8(%ebp) - * p (dest): 12(%ebp) %esi - * q1 (src0): 16(%ebp) - * q2 (src1): 20(%ebp) - * xstep: 24(%ebp) - * p_end: 28(%ebp) - * xinit: 32(%ebp) - * dest_x: 36(%ebp) - * - */ - -/* - * Function call entry - */ - pushl %ebp - movl %esp,%ebp - subl $28,%esp - pushl %edi - pushl %esi - pushl %ebx -/* Locals: - * int x %ebx - * int x_scaled -24(%ebp) - * int dest_x 36(%ebp) - */ - -/* - * Setup - */ -/* Initialize variables */ - movl 36(%ebp),%eax # destx - movl %eax,36(%ebp) - movl 32(%ebp),%ebx # x - movl 12(%ebp),%esi # dest - - cmpl 28(%ebp),%esi # dest == dest_end ? - jnb .out - -/* For the body of this loop, %mm0, %mm1, %mm2, %mm3 hold the 4 adjoining - * points we are interpolating between, as: - * - * 00VV00Y200UU00Y1 - */ - - pxor %mm4, %mm4 -/* - * Load next component values into mm1 (src0) and mm3 (src1) - */ - movl %ebx, %eax # x_scaled - sarl $15, %eax - andl $0xfffffffe, %eax - movl %eax, %edx # x_aligned - andl $0xfffffffc, %edx - - movl 16(%ebp), %edi # get src0 - movl (%edi,%eax), %ecx # get y - andl $0x00ff00ff, %ecx # mask off y - movl (%edi,%edx), %eax # get uv - andl $0xff00ff00, %eax # mask off uv - orl %eax, %ecx # composite y, uv - movd %ecx, %mm1 # move to mmx1 - punpcklbw %mm4, %mm1 - - movl 20(%ebp), %edi # get src1 - movl (%edi,%edx), %ecx # get y - andl $0x00ff00ff, %ecx # mask off y - movl (%edi,%edx), %eax # get uv - andl $0xff00ff00, %eax # mask off uv - orl %eax, %ecx # composite y, uv - movd %ecx, %mm3 # move to mmx3 - punpcklbw %mm4, %mm3 - - jmp .newx - - .p2align 4,,7 -.loop: - -/* short *pixel_weights = weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * n_x * n_y - * 16 4 0xf 2 2 - */ - movl 8(%ebp), %edi # get weights pointer - movl %ebx, %eax - andl $0xf000, %eax - shrl $7, %eax - -/* At this point, %edi holds weights. Load the 4 weights into - * %mm4,%mm5,%mm6,%mm7, multiply and accumulate. - */ - movq (%edi,%eax), %mm4 - pmullw %mm0, %mm4 - movq 8(%edi,%eax), %mm5 - pmullw %mm1, %mm5 - movq 16(%edi,%eax), %mm6 - pmullw %mm2,%mm6 - movq 24(%edi,%eax), %mm7 - pmullw %mm3,%mm7 - - paddw %mm4, %mm5 - paddw %mm6, %mm7 - paddw %mm5, %mm7 - -/* %mm7 holds the accumulated sum. Compute (C + 0x80) / 256 - */ - pxor %mm4, %mm4 - movl $0x80808080, %eax - movd %eax, %mm6 - punpcklbw %mm4, %mm6 - paddw %mm6, %mm7 - psrlw $8, %mm7 - -/* Pack into %eax and store result - */ - packuswb %mm7, %mm7 - movd %mm7, %eax - - movb %al, (%esi) # *dest = y - - movl 36(%ebp), %ecx # get dest_x - andl $1, %ecx # select u or v - sall $1, %ecx # determine offset - addl $1, %ecx # relative to x_aligned - sall $3, %ecx # offset * 8 bits/byte - - movd %mm7, %eax - shrl %cl, %eax - movb %al, 1(%esi) # *dest = uv - - addl $2, %esi # dest += 2 - cmpl %esi,28(%ebp) # if dest == dest_end - je .out # then exit - - addl $1, 36(%ebp) # dest_x++ - -.newx: - - addl 24(%ebp), %ebx # x += x_step -/* - * Load current component values into mm0 (src0) and mm2 (src1) - */ - movq %mm1, %mm0 - movq %mm3, %mm2 - -/* - * Load next component values into mm1 (src0) and mm3 (src1) - */ - movl %ebx, %eax # x_scaled - sarl $15, %eax - andl $0xfffffffe, %eax - movl %eax, %edx # x_aligned - andl $0xfffffffc, %edx - - movl 16(%ebp), %edi # get src0 - movl (%edi,%eax), %ecx # get y - andl $0x00ff00ff, %ecx # mask off y - movl (%edi,%edx), %eax # get uv - andl $0xff00ff00, %eax # mask off uv - orl %eax, %ecx # composite y, uv - movd %ecx, %mm1 # move to mmx1 - punpcklbw %mm4, %mm1 - - movl 20(%ebp), %edi # get src1 - movl (%edi,%edx), %ecx # get y - andl $0x00ff00ff, %ecx # mask off y - movl (%edi,%edx), %eax # get uv - andl $0xff00ff00, %eax # mask off uv - orl %eax, %ecx # composite y, uv - movd %ecx, %mm3 # move to mmx3 - punpcklbw %mm4, %mm3 - - jmp .loop - -.out: - movl %esi,%eax - emms - leal -40(%ebp),%esp - popl %ebx - popl %esi - popl %edi - movl %ebp,%esp - popl %ebp - ret diff --git a/src/modules/inigo/Makefile b/src/modules/inigo/Makefile deleted file mode 100644 index b2e297f..0000000 --- a/src/modules/inigo/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltinigo$(LIBSUF) - -OBJS = factory.o \ - producer_inigo.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/inigo/factory.c b/src/modules/inigo/factory.c deleted file mode 100644 index c1b2d0e..0000000 --- a/src/modules/inigo/factory.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -extern mlt_producer producer_inigo_file_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_inigo_init( mlt_profile profile, mlt_service_type type, const char *id, char **argv ); - -MLT_REPOSITORY -{ - MLT_REGISTER( producer_type, "inigo", producer_inigo_init ); - MLT_REGISTER( producer_type, "inigo_file", producer_inigo_file_init ); -} diff --git a/src/modules/inigo/producer_inigo.c b/src/modules/inigo/producer_inigo.c deleted file mode 100644 index 88ea2a5..0000000 --- a/src/modules/inigo/producer_inigo.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - * producer_inigo.c -- simple inigo test case - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include - -mlt_producer producer_inigo_init( mlt_profile profile, mlt_service_type type, const char *id, char **argv ); - -mlt_producer producer_inigo_file_init( mlt_profile profile, mlt_service_type type, const char *id, char *file ) -{ - FILE *input = fopen( file, "r" ); - char **args = calloc( sizeof( char * ), 1000 ); - int count = 0; - char temp[ 2048 ]; - - if ( input != NULL ) - { - while( fgets( temp, 2048, input ) ) - { - temp[ strlen( temp ) - 1 ] = '\0'; - if ( strcmp( temp, "" ) ) - args[ count ++ ] = strdup( temp ); - } - } - - mlt_producer result = producer_inigo_init( profile, type, id, args ); - - if ( result != NULL ) - { - mlt_properties properties = MLT_PRODUCER_PROPERTIES( result ); - mlt_properties_set( properties, "resource", file ); - } - - while( count -- ) - free( args[ count ] ); - free( args ); - - return result; -} - -static void track_service( mlt_field field, void *service, mlt_destructor destructor ) -{ - mlt_properties properties = mlt_field_properties( field ); - int registered = mlt_properties_get_int( properties, "registered" ); - char *key = mlt_properties_get( properties, "registered" ); - mlt_properties_set_data( properties, key, service, 0, destructor, NULL ); - mlt_properties_set_int( properties, "registered", ++ registered ); -} - -static mlt_producer create_producer( mlt_profile profile, mlt_field field, char *file ) -{ - mlt_producer result = mlt_factory_producer( profile, "fezzik", file ); - - if ( result != NULL ) - track_service( field, result, ( mlt_destructor )mlt_producer_close ); - - return result; -} - -static mlt_filter create_attach( mlt_profile profile, mlt_field field, char *id, int track ) -{ - char *temp = strdup( id ); - char *arg = strchr( temp, ':' ); - if ( arg != NULL ) - *arg ++ = '\0'; - mlt_filter filter = mlt_factory_filter( profile, temp, arg ); - if ( filter != NULL ) - track_service( field, filter, ( mlt_destructor )mlt_filter_close ); - free( temp ); - return filter; -} - -static mlt_filter create_filter( mlt_profile profile, mlt_field field, char *id, int track ) -{ - char *temp = strdup( id ); - char *arg = strchr( temp, ':' ); - if ( arg != NULL ) - *arg ++ = '\0'; - mlt_filter filter = mlt_factory_filter( profile, temp, arg ); - if ( filter != NULL ) - { - mlt_field_plant_filter( field, filter, track ); - track_service( field, filter, ( mlt_destructor )mlt_filter_close ); - } - free( temp ); - return filter; -} - -static mlt_transition create_transition( mlt_profile profile, mlt_field field, char *id, int track ) -{ - char *arg = strchr( id, ':' ); - if ( arg != NULL ) - *arg ++ = '\0'; - mlt_transition transition = mlt_factory_transition( profile, id, arg ); - if ( transition != NULL ) - { - mlt_field_plant_transition( field, transition, track, track + 1 ); - track_service( field, transition, ( mlt_destructor )mlt_transition_close ); - } - return transition; -} - -mlt_producer producer_inigo_init( mlt_profile profile, mlt_service_type type, const char *id, char **argv ) -{ - int i; - int track = 0; - mlt_producer producer = NULL; - mlt_tractor mix = NULL; - mlt_playlist playlist = mlt_playlist_init( ); - mlt_properties group = mlt_properties_new( ); - mlt_tractor tractor = mlt_tractor_new( ); - mlt_properties properties = MLT_TRACTOR_PROPERTIES( tractor ); - mlt_field field = mlt_tractor_field( tractor ); - mlt_properties field_properties = mlt_field_properties( field ); - mlt_multitrack multitrack = mlt_tractor_multitrack( tractor ); - char *title = NULL; - - // Assistance for template construction (allows -track usage to specify the first track) - mlt_properties_set_int( MLT_PLAYLIST_PROPERTIES( playlist ), "_inigo_first", 1 ); - - // We need to track the number of registered filters - mlt_properties_set_int( field_properties, "registered", 0 ); - - // Parse the arguments - if ( argv ) - for ( i = 0; argv[ i ] != NULL; i ++ ) - { - if ( !strcmp( argv[ i ], "-group" ) ) - { - if ( mlt_properties_count( group ) != 0 ) - { - mlt_properties_close( group ); - group = mlt_properties_new( ); - } - if ( group != NULL ) - properties = group; - } - else if ( !strcmp( argv[ i ], "-attach" ) || - !strcmp( argv[ i ], "-attach-cut" ) || - !strcmp( argv[ i ], "-attach-track" ) || - !strcmp( argv[ i ], "-attach-clip" ) ) - { - int type = !strcmp( argv[ i ], "-attach" ) ? 0 : - !strcmp( argv[ i ], "-attach-cut" ) ? 1 : - !strcmp( argv[ i ], "-attach-track" ) ? 2 : 3; - mlt_filter filter = create_attach( profile, field, argv[ ++ i ], track ); - if ( producer != NULL && !mlt_producer_is_cut( producer ) ) - { - mlt_playlist_clip_info info; - mlt_playlist_append( playlist, producer ); - mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 ); - producer = info.cut; - } - - if ( type == 1 || type == 2 ) - { - mlt_playlist_clip_info info; - mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 ); - producer = info.cut; - } - - if ( filter != NULL && mlt_playlist_count( playlist ) > 0 ) - { - if ( type == 0 ) - mlt_service_attach( ( mlt_service )properties, filter ); - else if ( type == 1 ) - mlt_service_attach( ( mlt_service )producer, filter ); - else if ( type == 2 ) - mlt_service_attach( ( mlt_service )playlist, filter ); - else if ( type == 3 ) - mlt_service_attach( ( mlt_service )mlt_producer_cut_parent( producer ), filter ); - - properties = MLT_FILTER_PROPERTIES( filter ); - mlt_properties_inherit( properties, group ); - } - else if ( filter != NULL ) - { - mlt_service_attach( ( mlt_service )playlist, filter ); - properties = MLT_FILTER_PROPERTIES( filter ); - mlt_properties_inherit( properties, group ); - } - } - else if ( !strcmp( argv[ i ], "-repeat" ) ) - { - int repeat = atoi( argv[ ++ i ] ); - if ( producer != NULL && !mlt_producer_is_cut( producer ) ) - mlt_playlist_append( playlist, producer ); - producer = NULL; - if ( mlt_playlist_count( playlist ) > 0 ) - { - mlt_playlist_clip_info info; - mlt_playlist_repeat_clip( playlist, mlt_playlist_count( playlist ) - 1, repeat ); - mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 ); - producer = info.cut; - properties = MLT_PRODUCER_PROPERTIES( producer ); - } - } - else if ( !strcmp( argv[ i ], "-split" ) ) - { - int split = atoi( argv[ ++ i ] ); - if ( producer != NULL && !mlt_producer_is_cut( producer ) ) - mlt_playlist_append( playlist, producer ); - producer = NULL; - if ( mlt_playlist_count( playlist ) > 0 ) - { - mlt_playlist_clip_info info; - mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 ); - split = split < 0 ? info.frame_out + split : split; - mlt_playlist_split( playlist, mlt_playlist_count( playlist ) - 1, split ); - mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 ); - producer = info.cut; - properties = MLT_PRODUCER_PROPERTIES( producer ); - } - } - else if ( !strcmp( argv[ i ], "-swap" ) ) - { - if ( producer != NULL && !mlt_producer_is_cut( producer ) ) - mlt_playlist_append( playlist, producer ); - producer = NULL; - if ( mlt_playlist_count( playlist ) >= 2 ) - { - mlt_playlist_clip_info info; - mlt_playlist_move( playlist, mlt_playlist_count( playlist ) - 2, mlt_playlist_count( playlist ) - 1 ); - mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 ); - producer = info.cut; - properties = MLT_PRODUCER_PROPERTIES( producer ); - } - } - else if ( !strcmp( argv[ i ], "-join" ) ) - { - int clips = atoi( argv[ ++ i ] ); - if ( producer != NULL && !mlt_producer_is_cut( producer ) ) - mlt_playlist_append( playlist, producer ); - producer = NULL; - if ( mlt_playlist_count( playlist ) > 0 ) - { - mlt_playlist_clip_info info; - int clip = clips <= 0 ? 0 : mlt_playlist_count( playlist ) - clips - 1; - if ( clip < 0 ) clip = 0; - if ( clip >= mlt_playlist_count( playlist ) ) clip = mlt_playlist_count( playlist ) - 2; - if ( clips < 0 ) clips = mlt_playlist_count( playlist ) - 1; - mlt_playlist_join( playlist, clip, clips, 0 ); - mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 ); - producer = info.cut; - properties = MLT_PRODUCER_PROPERTIES( producer ); - } - } - else if ( !strcmp( argv[ i ], "-remove" ) ) - { - if ( producer != NULL && !mlt_producer_is_cut( producer ) ) - mlt_playlist_append( playlist, producer ); - producer = NULL; - if ( mlt_playlist_count( playlist ) > 0 ) - { - mlt_playlist_clip_info info; - mlt_playlist_remove( playlist, mlt_playlist_count( playlist ) - 1 ); - mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 ); - producer = info.cut; - properties = MLT_PRODUCER_PROPERTIES( producer ); - } - } - else if ( !strcmp( argv[ i ], "-mix" ) ) - { - int length = atoi( argv[ ++ i ] ); - if ( producer != NULL && !mlt_producer_is_cut( producer ) ) - mlt_playlist_append( playlist, producer ); - producer = NULL; - if ( mlt_playlist_count( playlist ) >= 2 ) - { - if ( mlt_playlist_mix( playlist, mlt_playlist_count( playlist ) - 2, length, NULL ) == 0 ) - { - mlt_playlist_clip_info info; - mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 ); - if ( mlt_properties_get_data( ( mlt_properties )info.producer, "mlt_mix", NULL ) == NULL ) - mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 2 ); - mix = ( mlt_tractor )mlt_properties_get_data( ( mlt_properties )info.producer, "mlt_mix", NULL ); - properties = NULL; - } - else - { - fprintf( stderr, "Mix failed?\n" ); - } - } - else - { - fprintf( stderr, "Invalid position for a mix...\n" ); - } - } - else if ( !strcmp( argv[ i ], "-mixer" ) ) - { - if ( mix != NULL ) - { - char *id = strdup( argv[ ++ i ] ); - char *arg = strchr( id, ':' ); - mlt_field field = mlt_tractor_field( mix ); - mlt_transition transition = NULL; - if ( arg != NULL ) - *arg ++ = '\0'; - transition = mlt_factory_transition( profile, id, arg ); - if ( transition != NULL ) - { - properties = MLT_TRANSITION_PROPERTIES( transition ); - mlt_properties_inherit( properties, group ); - mlt_field_plant_transition( field, transition, 0, 1 ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", mlt_producer_get_out( ( mlt_producer )mix ) ); - mlt_transition_close( transition ); - } - free( id ); - } - else - { - fprintf( stderr, "Invalid mixer...\n" ); - } - } - else if ( !strcmp( argv[ i ], "-filter" ) ) - { - mlt_filter filter = create_filter( profile, field, argv[ ++ i ], track ); - if ( filter != NULL ) - { - properties = MLT_FILTER_PROPERTIES( filter ); - mlt_properties_inherit( properties, group ); - } - } - else if ( !strcmp( argv[ i ], "-transition" ) ) - { - mlt_transition transition = create_transition( profile, field, argv[ ++ i ], track - 1 ); - if ( transition != NULL ) - { - properties = MLT_TRANSITION_PROPERTIES( transition ); - mlt_properties_inherit( properties, group ); - } - } - else if ( !strcmp( argv[ i ], "-blank" ) ) - { - if ( producer != NULL && !mlt_producer_is_cut( producer ) ) - mlt_playlist_append( playlist, producer ); - producer = NULL; - mlt_playlist_blank( playlist, atof( argv[ ++ i ] ) ); - } - else if ( !strcmp( argv[ i ], "-track" ) || - !strcmp( argv[ i ], "-null-track" ) || - !strcmp( argv[ i ], "-video-track" ) || - !strcmp( argv[ i ], "-audio-track" ) || - !strcmp( argv[ i ], "-hide-track" ) || - !strcmp( argv[ i ], "-hide-video" ) || - !strcmp( argv[ i ], "-hide-audio" ) ) - { - if ( producer != NULL && !mlt_producer_is_cut( producer ) ) - mlt_playlist_append( playlist, producer ); - producer = NULL; - if ( !mlt_properties_get_int( MLT_PLAYLIST_PROPERTIES( playlist ), "_inigo_first" ) || - mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( playlist ) ) > 0 ) - { - mlt_multitrack_connect( multitrack, MLT_PLAYLIST_PRODUCER( playlist ), track ++ ); - track_service( field, playlist, ( mlt_destructor )mlt_playlist_close ); - playlist = mlt_playlist_init( ); - } - if ( playlist != NULL ) - { - properties = MLT_PLAYLIST_PROPERTIES( playlist ); - if ( !strcmp( argv[ i ], "-null-track" ) || !strcmp( argv[ i ], "-hide-track" ) ) - mlt_properties_set_int( properties, "hide", 3 ); - else if ( !strcmp( argv[ i ], "-audio-track" ) || !strcmp( argv[ i ], "-hide-video" ) ) - mlt_properties_set_int( properties, "hide", 1 ); - else if ( !strcmp( argv[ i ], "-video-track" ) || !strcmp( argv[ i ], "-hide-audio" ) ) - mlt_properties_set_int( properties, "hide", 2 ); - } - } - else if ( strchr( argv[ i ], '=' ) && strstr( argv[ i ], " 0 ) - mlt_multitrack_connect( multitrack, MLT_PLAYLIST_PRODUCER( playlist ), track ); - - mlt_producer prod = MLT_TRACTOR_PRODUCER( tractor ); - mlt_producer_optimise( prod ); - mlt_properties props = MLT_TRACTOR_PROPERTIES( tractor ); - mlt_properties_set_data( props, "group", group, 0, ( mlt_destructor )mlt_properties_close, NULL ); - mlt_properties_set_position( props, "length", mlt_producer_get_out( MLT_MULTITRACK_PRODUCER( multitrack ) ) + 1 ); - mlt_producer_set_in_and_out( prod, 0, mlt_producer_get_out( MLT_MULTITRACK_PRODUCER( multitrack ) ) ); - if ( title != NULL ) - mlt_properties_set( props, "title", strchr( title, '/' ) ? strrchr( title, '/' ) + 1 : title ); - - return prod; -} diff --git a/src/modules/jackrack/Makefile b/src/modules/jackrack/Makefile deleted file mode 100644 index 50d7d88..0000000 --- a/src/modules/jackrack/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltjackrack$(LIBSUF) - -OBJS = factory.o \ - jack_rack.o \ - lock_free_fifo.o \ - plugin.o \ - plugin_desc.o \ - plugin_mgr.o \ - plugin_settings.o \ - process.o \ - filter_jackrack.o \ - filter_ladspa.o - -CFLAGS += -I../.. -CFLAGS += `pkg-config --cflags jack` -CFLAGS += `xml2-config --cflags` -CFLAGS += `pkg-config glib-2.0 --cflags` - -LDFLAGS += -L../../framework -lmlt -LDFLAGS += `pkg-config --libs jack` -LDFLAGS += `xml2-config --libs` -LDFLAGS += `pkg-config glib-2.0 --libs` - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/jackrack/configure b/src/modules/jackrack/configure deleted file mode 100755 index d10b294..0000000 --- a/src/modules/jackrack/configure +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - - pkg-config jack - disable_jack=$? - - which xml2-config > /dev/null 2>&1 - disable_xml2=$? - - disable_ladspa=1 - ladspa_prefix=`which listplugins 2> /dev/null` - if [ "$ladspa_prefix" != "" ] - then - ladspa_prefix=`dirname "$ladspa_prefix"` - disable_ladspa=`[ -f "$ladspa_prefix/include/ladspa.h" ] && echo 1 || echo 0` - fi - - if [ "$disable_jack" = "1" -o "$disable_xml2" = "1" -o "$disable_ladspa" = "1" ] - then - [ "$disable_jack" = "1" ] && echo "- jackrack not found: disabling" - [ "$disable_xml2" = "1" ] && echo "- xml2 not found: disabling jackrack" - [ "$disable_ladspa" = "1" ] && echo "- ladspa not found; disabling" - touch ../disable-jackrack - fi - exit 0 -fi diff --git a/src/modules/jackrack/factory.c b/src/modules/jackrack/factory.c deleted file mode 100644 index 1476b15..0000000 --- a/src/modules/jackrack/factory.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -extern mlt_filter filter_jackrack_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_ladspa_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "jackrack", filter_jackrack_init ); - MLT_REGISTER( filter_type, "ladspa", filter_ladspa_init ); -} diff --git a/src/modules/jackrack/filter_jackrack.c b/src/modules/jackrack/filter_jackrack.c deleted file mode 100644 index 0c9fe9b..0000000 --- a/src/modules/jackrack/filter_jackrack.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * filter_jackrack.c -- filter audio through Jack and/or LADSPA plugins - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "jack_rack.h" - -#define BUFFER_LEN 204800 * 3 - -static void initialise_jack_ports( mlt_properties properties ) -{ - int i; - char mlt_name[20], rack_name[30]; - jack_port_t **port = NULL; - jack_client_t *jack_client = mlt_properties_get_data( properties, "jack_client", NULL ); - jack_nframes_t jack_buffer_size = jack_get_buffer_size( jack_client ); - - // Propogate these for the Jack processing callback - int channels = mlt_properties_get_int( properties, "channels" ); - - // Start JackRack - if ( mlt_properties_get( properties, "src" ) ) - { - snprintf( rack_name, sizeof( rack_name ), "jackrack%d", getpid() ); - jack_rack_t *jackrack = jack_rack_new( rack_name, mlt_properties_get_int( properties, "channels" ) ); - jack_rack_open_file( jackrack, mlt_properties_get( properties, "src" ) ); - - mlt_properties_set_data( properties, "jackrack", jackrack, 0, NULL, NULL ); - mlt_properties_set( properties, "_rack_client_name", rack_name ); - } - - // Allocate buffers and ports - jack_ringbuffer_t **output_buffers = mlt_pool_alloc( sizeof( jack_ringbuffer_t *) * channels ); - jack_ringbuffer_t **input_buffers = mlt_pool_alloc( sizeof( jack_ringbuffer_t *) * channels ); - jack_port_t **jack_output_ports = mlt_pool_alloc( sizeof(jack_port_t *) * channels ); - jack_port_t **jack_input_ports = mlt_pool_alloc( sizeof(jack_port_t *) * channels ); - float **jack_output_buffers = mlt_pool_alloc( sizeof(float *) * jack_buffer_size ); - float **jack_input_buffers = mlt_pool_alloc( sizeof(float *) * jack_buffer_size ); - - // Set properties - released inside filter_close - mlt_properties_set_data( properties, "output_buffers", output_buffers, sizeof( jack_ringbuffer_t *) * channels, NULL, NULL ); - mlt_properties_set_data( properties, "input_buffers", input_buffers, sizeof( jack_ringbuffer_t *) * channels, NULL, NULL ); - mlt_properties_set_data( properties, "jack_output_ports", jack_output_ports, sizeof( jack_port_t *) * channels, NULL, NULL ); - mlt_properties_set_data( properties, "jack_input_ports", jack_input_ports, sizeof( jack_port_t *) * channels, NULL, NULL ); - mlt_properties_set_data( properties, "jack_output_buffers", jack_output_buffers, sizeof( float *) * channels, NULL, NULL ); - mlt_properties_set_data( properties, "jack_input_buffers", jack_input_buffers, sizeof( float *) * channels, NULL, NULL ); - - // Start Jack processing - required before registering ports - jack_activate( jack_client ); - - // Register Jack ports - for ( i = 0; i < channels; i++ ) - { - int in; - - output_buffers[i] = jack_ringbuffer_create( BUFFER_LEN * sizeof(float) ); - input_buffers[i] = jack_ringbuffer_create( BUFFER_LEN * sizeof(float) ); - snprintf( mlt_name, sizeof( mlt_name ), "obuf%d", i ); - mlt_properties_set_data( properties, mlt_name, output_buffers[i], BUFFER_LEN * sizeof(float), NULL, NULL ); - snprintf( mlt_name, sizeof( mlt_name ), "ibuf%d", i ); - mlt_properties_set_data( properties, mlt_name, input_buffers[i], BUFFER_LEN * sizeof(float), NULL, NULL ); - - for ( in = 0; in < 2; in++ ) - { - snprintf( mlt_name, sizeof( mlt_name ), "%s_%d", in ? "in" : "out", i + 1); - port = ( in ? &jack_input_ports[i] : &jack_output_ports[i] ); - - *port = jack_port_register( jack_client, mlt_name, JACK_DEFAULT_AUDIO_TYPE, - ( in ? JackPortIsInput : JackPortIsOutput ) | JackPortIsTerminal, 0 ); - } - } - - // Establish connections - for ( i = 0; i < channels; i++ ) - { - int in; - for ( in = 0; in < 2; in++ ) - { - port = ( in ? &jack_input_ports[i] : &jack_output_ports[i] ); - snprintf( mlt_name, sizeof( mlt_name ), "%s", jack_port_name( *port ) ); - - snprintf( rack_name, sizeof( rack_name ), "%s_%d", in ? "in" : "out", i + 1 ); - if ( mlt_properties_get( properties, "_rack_client_name" ) ) - snprintf( rack_name, sizeof( rack_name ), "%s:%s_%d", mlt_properties_get( properties, "_rack_client_name" ), in ? "out" : "in", i + 1); - else if ( mlt_properties_get( properties, rack_name ) ) - snprintf( rack_name, sizeof( rack_name ), "%s", mlt_properties_get( properties, rack_name ) ); - else - snprintf( rack_name, sizeof( rack_name ), "%s:%s_%d", mlt_properties_get( properties, "_client_name" ), in ? "out" : "in", i + 1); - - if ( in ) - { - fprintf( stderr, "jack connect %s to %s\n", rack_name, mlt_name ); - jack_connect( jack_client, rack_name, mlt_name ); - } - else - { - fprintf( stderr, "jack connect %s to %s\n", mlt_name, rack_name ); - jack_connect( jack_client, mlt_name, rack_name ); - } - } - } -} - -static int jack_process (jack_nframes_t frames, void * data) -{ - mlt_filter filter = (mlt_filter) data; - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - int channels = mlt_properties_get_int( properties, "channels" ); - int frame_size = mlt_properties_get_int( properties, "_samples" ) * sizeof(float); - int sync = mlt_properties_get_int( properties, "_sync" ); - int err = 0; - int i; - static int total_size = 0; - - jack_ringbuffer_t **output_buffers = mlt_properties_get_data( properties, "output_buffers", NULL ); - if ( output_buffers == NULL ) - return 0; - jack_ringbuffer_t **input_buffers = mlt_properties_get_data( properties, "input_buffers", NULL ); - jack_port_t **jack_output_ports = mlt_properties_get_data( properties, "jack_output_ports", NULL ); - jack_port_t **jack_input_ports = mlt_properties_get_data( properties, "jack_input_ports", NULL ); - float **jack_output_buffers = mlt_properties_get_data( properties, "jack_output_buffers", NULL ); - float **jack_input_buffers = mlt_properties_get_data( properties, "jack_input_buffers", NULL ); - pthread_mutex_t *output_lock = mlt_properties_get_data( properties, "output_lock", NULL ); - pthread_cond_t *output_ready = mlt_properties_get_data( properties, "output_ready", NULL ); - - for ( i = 0; i < channels; i++ ) - { - size_t jack_size = ( frames * sizeof(float) ); - size_t ring_size; - - // Send audio through out port - jack_output_buffers[i] = jack_port_get_buffer( jack_output_ports[i], frames ); - if ( ! jack_output_buffers[i] ) - { - fprintf( stderr, "%s: no jack buffer for output port %d\n", __FUNCTION__, i ); - err = 1; - break; - } - ring_size = jack_ringbuffer_read_space( output_buffers[i] ); - jack_ringbuffer_read( output_buffers[i], ( char * )jack_output_buffers[i], ring_size < jack_size ? ring_size : jack_size ); - - // Return audio through in port - jack_input_buffers[i] = jack_port_get_buffer( jack_input_ports[i], frames ); - if ( ! jack_input_buffers[i] ) - { - fprintf( stderr, "%s: no jack buffer for input port %d\n", __FUNCTION__, i ); - err = 1; - break; - } - - // Do not start returning audio until we have sent first mlt frame - if ( sync && i == 0 && frame_size > 0 ) - total_size += ring_size; - //fprintf(stderr, "sync %d frame_size %d ring_size %d jack_size %d\n", sync, frame_size, ring_size, jack_size ); - - if ( ! sync || ( frame_size > 0 && total_size >= frame_size ) ) - { - ring_size = jack_ringbuffer_write_space( input_buffers[i] ); - jack_ringbuffer_write( input_buffers[i], ( char * )jack_input_buffers[i], ring_size < jack_size ? ring_size : jack_size ); - - if ( sync ) - { - // Tell mlt that audio is available - pthread_mutex_lock( output_lock); - pthread_cond_signal( output_ready ); - pthread_mutex_unlock( output_lock); - - // Clear sync phase - mlt_properties_set_int( properties, "_sync", 0 ); - } - } - } - - return err; -} - - -/** Get the audio. -*/ - -static int jackrack_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the filter service - mlt_filter filter = mlt_frame_pop_audio( frame ); - - // Get the filter properties - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - - int jack_frequency = mlt_properties_get_int( filter_properties, "_sample_rate" ); - - // Get the producer's audio - mlt_frame_get_audio( frame, buffer, format, &jack_frequency, channels, samples ); - - // TODO: Deal with sample rate differences - if ( *frequency != jack_frequency ) - fprintf( stderr, "mismatching frequencies in filter jackrack\n" ); - *frequency = jack_frequency; - - // Initialise Jack ports and connections if needed - if ( mlt_properties_get_int( filter_properties, "_samples" ) == 0 ) - mlt_properties_set_int( filter_properties, "_samples", *samples ); - - // Get the filter-specific properties - jack_ringbuffer_t **output_buffers = mlt_properties_get_data( filter_properties, "output_buffers", NULL ); - jack_ringbuffer_t **input_buffers = mlt_properties_get_data( filter_properties, "input_buffers", NULL ); -// pthread_mutex_t *output_lock = mlt_properties_get_data( filter_properties, "output_lock", NULL ); -// pthread_cond_t *output_ready = mlt_properties_get_data( filter_properties, "output_ready", NULL ); - - // Process the audio - int16_t *q = *buffer; - float sample[ 2 ][ 10000 ]; - int i, j; -// struct timespec tm = { 0, 0 }; - - // Convert to floats and write into output ringbuffer - if ( jack_ringbuffer_write_space( output_buffers[0] ) >= ( *samples * sizeof(float) ) ) - { - for ( i = 0; i < *samples; i++ ) - for ( j = 0; j < *channels; j++ ) - sample[ j ][ i ] = ( float )( *q ++ ) / 32768.0; - - for ( j = 0; j < *channels; j++ ) - jack_ringbuffer_write( output_buffers[j], ( char * )sample[ j ], *samples * sizeof(float) ); - } - - // Synchronization phase - wait for signal from Jack process - while ( jack_ringbuffer_read_space( input_buffers[ *channels - 1 ] ) < ( *samples * sizeof(float) ) ) ; - //pthread_cond_wait( output_ready, output_lock ); - - // Read from input ringbuffer and convert from floats - if ( jack_ringbuffer_read_space( input_buffers[0] ) >= ( *samples * sizeof(float) ) ) - { - // Initialise to silence, but repeat last frame if available in case of - // buffer underrun - for ( j = 0; j < *channels; j++ ) - jack_ringbuffer_read( input_buffers[j], ( char * )sample[ j ], *samples * sizeof(float) ); - - q = *buffer; - for ( i = 0; i < *samples; i++ ) - for ( j = 0; j < *channels; j++ ) - { - if ( sample[ j ][ i ] > 1.0 ) - sample[ j ][ i ] = 1.0; - else if ( sample[ j ][ i ] < -1.0 ) - sample[ j ][ i ] = -1.0; - - if ( sample[ j ][ i ] > 0 ) - *q ++ = 32767 * sample[ j ][ i ]; - else - *q ++ = 32768 * sample[ j ][ i ]; - } - } - - return 0; -} - - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - { - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - mlt_frame_push_audio( frame, this ); - mlt_frame_push_audio( frame, jackrack_get_audio ); - - if ( mlt_properties_get_int( properties, "_sync" ) ) - initialise_jack_ports( properties ); - } - - return frame; -} - - -static void filter_close( mlt_filter this ) -{ - int i; - char mlt_name[20]; - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - jack_client_t *jack_client = mlt_properties_get_data( properties, "jack_client", NULL ); - - jack_deactivate( jack_client ); - jack_client_close( jack_client ); - for ( i = 0; i < mlt_properties_get_int( properties, "channels" ); i++ ) - { - snprintf( mlt_name, sizeof( mlt_name ), "obuf%d", i ); - jack_ringbuffer_free( mlt_properties_get_data( properties, mlt_name, NULL ) ); - snprintf( mlt_name, sizeof( mlt_name ), "ibuf%d", i ); - jack_ringbuffer_free( mlt_properties_get_data( properties, mlt_name, NULL ) ); - } - mlt_pool_release( mlt_properties_get_data( properties, "output_buffers", NULL ) ); - mlt_pool_release( mlt_properties_get_data( properties, "input_buffers", NULL ) ); - mlt_pool_release( mlt_properties_get_data( properties, "jack_output_ports", NULL ) ); - mlt_pool_release( mlt_properties_get_data( properties, "jack_input_ports", NULL ) ); - mlt_pool_release( mlt_properties_get_data( properties, "jack_output_buffers", NULL ) ); - mlt_pool_release( mlt_properties_get_data( properties, "jack_input_buffers", NULL ) ); - mlt_pool_release( mlt_properties_get_data( properties, "output_lock", NULL ) ); - mlt_pool_release( mlt_properties_get_data( properties, "output_ready", NULL ) ); - - jack_rack_t *jackrack = mlt_properties_get_data( properties, "jackrack", NULL ); - jack_rack_destroy( jackrack ); - - this->parent.close = NULL; - mlt_service_close( &this->parent ); -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_jackrack_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - char name[14]; - - snprintf( name, sizeof( name ), "mlt%d", getpid() ); - jack_client_t *jack_client = jack_client_new( name ); - if ( jack_client ) - { - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - pthread_mutex_t *output_lock = mlt_pool_alloc( sizeof( pthread_mutex_t ) ); - pthread_cond_t *output_ready = mlt_pool_alloc( sizeof( pthread_cond_t ) ); - - jack_set_process_callback( jack_client, jack_process, this ); - //TODO: jack_on_shutdown( jack_client, jack_shutdown_cb, this ); - this->process = filter_process; - this->close = filter_close; - pthread_mutex_init( output_lock, NULL ); - pthread_cond_init( output_ready, NULL ); - - mlt_properties_set( properties, "src", arg ); - mlt_properties_set( properties, "_client_name", name ); - mlt_properties_set_data( properties, "jack_client", jack_client, 0, NULL, NULL ); - mlt_properties_set_int( properties, "_sample_rate", jack_get_sample_rate( jack_client ) ); - mlt_properties_set_data( properties, "output_lock", output_lock, 0, NULL, NULL ); - mlt_properties_set_data( properties, "output_ready", output_ready, 0, NULL, NULL ); - mlt_properties_set_int( properties, "_sync", 1 ); - mlt_properties_set_int( properties, "channels", 2 ); - } - } - return this; -} diff --git a/src/modules/jackrack/filter_ladspa.c b/src/modules/jackrack/filter_ladspa.c deleted file mode 100644 index 7eff6fa..0000000 --- a/src/modules/jackrack/filter_ladspa.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * filter_ladspa.c -- filter audio through LADSPA plugins - * Copyright (C) 2004-2005 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "jack_rack.h" - -#define BUFFER_LEN 10000 - -static void initialise_jack_rack( mlt_properties properties, int channels ) -{ - int i; - char mlt_name[20]; - - // Propogate these for the Jack processing callback - mlt_properties_set_int( properties, "channels", channels ); - - // Start JackRack - if ( mlt_properties_get( properties, "src" ) ) - { - // Create JackRack without Jack client name so that it only uses LADSPA - jack_rack_t *jackrack = jack_rack_new( NULL, channels ); - mlt_properties_set_data( properties, "jackrack", jackrack, 0, NULL, NULL ); - jack_rack_open_file( jackrack, mlt_properties_get( properties, "src" ) ); - } - - // Allocate buffers - LADSPA_Data **input_buffers = mlt_pool_alloc( sizeof( LADSPA_Data ) * channels ); - LADSPA_Data **output_buffers = mlt_pool_alloc( sizeof( LADSPA_Data ) * channels ); - - // Set properties - released inside filter_close - mlt_properties_set_data( properties, "input_buffers", input_buffers, sizeof( LADSPA_Data *) * channels, NULL, NULL ); - mlt_properties_set_data( properties, "output_buffers", output_buffers, sizeof( LADSPA_Data *) * channels, NULL, NULL ); - - // Register Jack ports - for ( i = 0; i < channels; i++ ) - { - input_buffers[i] = mlt_pool_alloc( BUFFER_LEN * sizeof( LADSPA_Data ) ); - snprintf( mlt_name, sizeof( mlt_name ), "ibuf%d", i ); - mlt_properties_set_data( properties, mlt_name, input_buffers[i], BUFFER_LEN * sizeof( LADSPA_Data ), NULL, NULL ); - - output_buffers[i] = mlt_pool_alloc( BUFFER_LEN * sizeof( LADSPA_Data ) ); - snprintf( mlt_name, sizeof( mlt_name ), "obuf%d", i ); - mlt_properties_set_data( properties, mlt_name, output_buffers[i], BUFFER_LEN * sizeof( LADSPA_Data ), NULL, NULL ); - } -} - - -/** Get the audio. -*/ - -static int ladspa_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the filter service - mlt_filter filter = mlt_frame_pop_audio( frame ); - - // Get the filter properties - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - - // Get the producer's audio - mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); - - // Initialise LADSPA if needed - jack_rack_t *jackrack = mlt_properties_get_data( filter_properties, "jackrack", NULL ); - if ( jackrack == NULL ) - { - sample_rate = *frequency; - initialise_jack_rack( filter_properties, *channels ); - jackrack = mlt_properties_get_data( filter_properties, "jackrack", NULL ); - } - - // Get the filter-specific properties - LADSPA_Data **input_buffers = mlt_properties_get_data( filter_properties, "input_buffers", NULL ); - LADSPA_Data **output_buffers = mlt_properties_get_data( filter_properties, "output_buffers", NULL ); - - // Process the audio - int16_t *q = *buffer; - int i, j; - - // Convert to floats and write into output ringbuffer - for ( i = 0; i < *samples; i++ ) - for ( j = 0; j < *channels; j++ ) - input_buffers[ j ][ i ] = ( float )( *q ++ ) / 32768.0; - - // Do LADSPA processing - if ( jackrack && process_ladspa( jackrack->procinfo, *samples, input_buffers, output_buffers) == 0 ) - { - // Read from output buffer and convert from floats - q = *buffer; - for ( i = 0; i < *samples; i++ ) - for ( j = 0; j < *channels; j++ ) - { - if ( output_buffers[ j ][ i ] > 1.0 ) - output_buffers[ j ][ i ] = 1.0; - else if ( output_buffers[ j ][ i ] < -1.0 ) - output_buffers[ j ][ i ] = -1.0; - - if ( output_buffers[ j ][ i ] > 0 ) - *q ++ = 32767 * output_buffers[ j ][ i ]; - else - *q ++ = 32768 * output_buffers[ j ][ i ]; - } - } - - return 0; -} - - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - { - mlt_frame_push_audio( frame, this ); - mlt_frame_push_audio( frame, ladspa_get_audio ); - } - - return frame; -} - - -static void filter_close( mlt_filter this ) -{ - int i; - char mlt_name[20]; - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - if ( mlt_properties_get_data( properties, "jackrack", NULL ) != NULL ) - { - for ( i = 0; i < mlt_properties_get_int( properties, "channels" ); i++ ) - { - snprintf( mlt_name, sizeof( mlt_name ), "obuf%d", i ); - mlt_pool_release( mlt_properties_get_data( properties, mlt_name, NULL ) ); - snprintf( mlt_name, sizeof( mlt_name ), "ibuf%d", i ); - mlt_pool_release( mlt_properties_get_data( properties, mlt_name, NULL ) ); - } - mlt_pool_release( mlt_properties_get_data( properties, "output_buffers", NULL ) ); - mlt_pool_release( mlt_properties_get_data( properties, "input_buffers", NULL ) ); - - jack_rack_t *jackrack = mlt_properties_get_data( properties, "jackrack", NULL ); - jack_rack_destroy( jackrack ); - } - this->parent.close = NULL; - mlt_service_close( &this->parent ); -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_ladspa_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - this->process = filter_process; - this->close = filter_close; - - mlt_properties_set( properties, "src", arg ); - } - return this; -} diff --git a/src/modules/jackrack/gpl b/src/modules/jackrack/gpl deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/jackrack/jack_rack.c b/src/modules/jackrack/jack_rack.c deleted file mode 100644 index 92f8272..0000000 --- a/src/modules/jackrack/jack_rack.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include "jack_rack.h" -#include "lock_free_fifo.h" -#include "plugin_settings.h" - -#ifndef _ -#define _(x) x -#endif -#define _x (const xmlChar*) -#define _s (const char*) - -jack_rack_t * -jack_rack_new (const char * client_name, unsigned long channels) -{ - jack_rack_t *rack; - - rack = g_malloc (sizeof (jack_rack_t)); - rack->saved_plugins = NULL; - rack->channels = channels; - rack->procinfo = process_info_new (client_name, channels, FALSE, FALSE); - if (!rack->procinfo) { - g_free (rack); - return NULL; - } - rack->plugin_mgr = plugin_mgr_new (); - plugin_mgr_set_plugins (rack->plugin_mgr, channels); - - return rack; -} - - -void -jack_rack_destroy (jack_rack_t * jack_rack) -{ - process_quit (jack_rack->procinfo); - plugin_mgr_destroy (jack_rack->plugin_mgr); - process_info_destroy (jack_rack->procinfo); - g_slist_free (jack_rack->saved_plugins); - g_free (jack_rack); -} - -plugin_t * -jack_rack_instantiate_plugin (jack_rack_t * jack_rack, plugin_desc_t * desc) -{ - plugin_t * plugin; - - /* check whether or not the plugin is RT capable and confirm with the user if it isn't */ - if (!LADSPA_IS_HARD_RT_CAPABLE(desc->properties)) { - fprintf (stderr, "Plugin not RT capable. The plugin '%s' does not describe itself as being capable of real-time operation. You may experience drop outs or jack may even kick us out if you use it.\n", - desc->name); - } - - /* create the plugin */ - plugin = plugin_new (desc, jack_rack); - - if (!plugin) { - fprintf (stderr, "Error loading file plugin '%s' from file '%s'\n", - desc->name, desc->object_file); - } - - return plugin; -} - - -void -jack_rack_add_saved_plugin (jack_rack_t * jack_rack, saved_plugin_t * saved_plugin) -{ - plugin_t * plugin = jack_rack_instantiate_plugin (jack_rack, saved_plugin->settings->desc); - if (!plugin) - return; - jack_rack->saved_plugins = g_slist_append (jack_rack->saved_plugins, saved_plugin); - process_add_plugin (jack_rack->procinfo, plugin); - jack_rack_add_plugin (jack_rack, plugin); -} - - -void -jack_rack_add_plugin (jack_rack_t * jack_rack, plugin_t * plugin) -{ - saved_plugin_t * saved_plugin = NULL; - GSList * list; - unsigned long control, channel; - LADSPA_Data value; - guint copy; - - /* see if there's any saved settings that match the plugin id */ - for (list = jack_rack->saved_plugins; list; list = g_slist_next (list)) - { - saved_plugin = list->data; - - if (saved_plugin->settings->desc->id == plugin->desc->id) - { - /* process the settings! */ - jack_rack->saved_plugins = g_slist_remove (jack_rack->saved_plugins, saved_plugin); - break; - } - saved_plugin = NULL; - } - - /* initialize plugin parameters */ - plugin->enabled = settings_get_enabled (saved_plugin->settings); - plugin->wet_dry_enabled = settings_get_wet_dry_enabled (saved_plugin->settings); - - for (control = 0; control < saved_plugin->settings->desc->control_port_count; control++) - for (copy = 0; copy < plugin->copies; copy++) - { - value = settings_get_control_value (saved_plugin->settings, copy, control); - plugin->holders[copy].control_memory[control] = value; -//printf("setting control value %s (%d) = %f\n", saved_plugin->settings->desc->port_names[control], copy, value); -// lff_write (plugin->holders[copy].ui_control_fifos + control, &value); - } - if (plugin->wet_dry_enabled) - for (channel = 0; channel < jack_rack->channels; channel++) - { - value = settings_get_wet_dry_value (saved_plugin->settings, channel); - plugin->wet_dry_values[channel] = value; -//printf("setting wet/dry value %d = %f\n", channel, value); -// lff_write (plugin->wet_dry_fifos + channel, &value); - } -} - - -static void -saved_rack_parse_plugin (jack_rack_t * jack_rack, saved_rack_t * saved_rack, saved_plugin_t * saved_plugin, - const char * filename, xmlNodePtr plugin) -{ - plugin_desc_t * desc; - settings_t * settings = NULL; - xmlNodePtr node; - xmlNodePtr sub_node; - xmlChar *content; - unsigned long num; - unsigned long control = 0; - - for (node = plugin->children; node; node = node->next) - { - if (xmlStrcmp (node->name, _x("id")) == 0) - { - content = xmlNodeGetContent (node); - num = strtoul (_s(content), NULL, 10); - xmlFree (content); - - desc = plugin_mgr_get_any_desc (jack_rack->plugin_mgr, num); - if (!desc) - { - fprintf (stderr, _("The file '%s' contains an unknown plugin with ID '%ld'; skipping\n"), filename, num); - return; - } - - settings = settings_new (desc, saved_rack->channels, saved_rack->sample_rate); - } - else if (xmlStrcmp (node->name, _x("enabled")) == 0) - { - content = xmlNodeGetContent (node); - settings_set_enabled (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE); - xmlFree (content); - } - else if (xmlStrcmp (node->name, _x("wet_dry_enabled")) == 0) - { - content = xmlNodeGetContent (node); - settings_set_wet_dry_enabled (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE); - xmlFree (content); - } - else if (xmlStrcmp (node->name, _x("wet_dry_locked")) == 0) - { - content = xmlNodeGetContent (node); - settings_set_wet_dry_locked (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE); - xmlFree (content); - } - else if (xmlStrcmp (node->name, _x("wet_dry_values")) == 0) - { - unsigned long channel = 0; - - for (sub_node = node->children; sub_node; sub_node = sub_node->next) - { - if (xmlStrcmp (sub_node->name, _x("value")) == 0) - { - content = xmlNodeGetContent (sub_node); - settings_set_wet_dry_value (settings, channel, strtod (_s(content), NULL)); - xmlFree (content); - - channel++; - } - } - } - else if (xmlStrcmp (node->name, _x("lockall")) == 0) - { - content = xmlNodeGetContent (node); - settings_set_lock_all (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE); - xmlFree (content); - } - else if (xmlStrcmp (node->name, _x("controlrow")) == 0) - { - gint copy = 0; - - for (sub_node = node->children; sub_node; sub_node = sub_node->next) - { - if (xmlStrcmp (sub_node->name, _x("lock")) == 0) - { - content = xmlNodeGetContent (sub_node); - settings_set_lock (settings, control, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE); - xmlFree (content); - } - else if (xmlStrcmp (sub_node->name, _x("value")) == 0) - { - content = xmlNodeGetContent (sub_node); - settings_set_control_value (settings, copy, control, strtod (_s(content), NULL)); - xmlFree (content); - copy++; - } - } - - control++; - } - } - - if (settings) - saved_plugin->settings = settings; -} - -static void -saved_rack_parse_jackrack (jack_rack_t * jack_rack, saved_rack_t * saved_rack, const char * filename, xmlNodePtr jackrack) -{ - xmlNodePtr node; - xmlChar *content; - saved_plugin_t * saved_plugin; - - for (node = jackrack->children; node; node = node->next) - { - if (xmlStrcmp (node->name, _x("channels")) == 0) - { - content = xmlNodeGetContent (node); - saved_rack->channels = strtoul (_s(content), NULL, 10); - xmlFree (content); - } - else if (xmlStrcmp (node->name, _x("samplerate")) == 0) - { - content = xmlNodeGetContent (node); - saved_rack->sample_rate = strtoul (_s(content), NULL, 10); - xmlFree (content); - } - else if (xmlStrcmp (node->name, _x("plugin")) == 0) - { - saved_plugin = g_malloc0 (sizeof (saved_plugin_t)); - saved_rack->plugins = g_slist_append (saved_rack->plugins, saved_plugin); - saved_rack_parse_plugin (jack_rack, saved_rack, saved_plugin, filename, node); - } - } -} - -static saved_rack_t * -saved_rack_new (jack_rack_t * jack_rack, const char * filename, xmlDocPtr doc) -{ - xmlNodePtr node; - saved_rack_t *saved_rack; - - /* create the saved rack */ - saved_rack = g_malloc (sizeof (saved_rack_t)); - saved_rack->plugins = NULL; - saved_rack->sample_rate = 48000; - saved_rack->channels = 2; - - for (node = doc->children; node; node = node->next) - { - if (xmlStrcmp (node->name, _x("jackrack")) == 0) - saved_rack_parse_jackrack (jack_rack, saved_rack, filename, node); - } - - return saved_rack; -} - -static void -saved_rack_destroy (saved_rack_t * saved_rack) -{ - GSList * list; - - for (list = saved_rack->plugins; list; list = g_slist_next (list)) - settings_destroy (((saved_plugin_t *) list->data)->settings); - g_slist_free (saved_rack->plugins); - g_free (saved_rack); -} - - -int -jack_rack_open_file (jack_rack_t * jack_rack, const char * filename) -{ - xmlDocPtr doc; - saved_rack_t * saved_rack; - GSList * list; - saved_plugin_t * saved_plugin; - - doc = xmlParseFile (filename); - if (!doc) - { - fprintf (stderr, _("Could not parse file '%s'\n"), filename); - return 1; - } - - if (xmlStrcmp ( ((xmlDtdPtr)doc->children)->name, _x("jackrack")) != 0) - { - fprintf (stderr, _("The file '%s' is not a JACK Rack settings file\n"), filename); - return 1; - } - - saved_rack = saved_rack_new (jack_rack, filename, doc); - xmlFreeDoc (doc); - - if (!saved_rack) - return 1; - - for (list = saved_rack->plugins; list; list = g_slist_next (list)) - { - saved_plugin = list->data; - - settings_set_sample_rate (saved_plugin->settings, sample_rate); - - jack_rack_add_saved_plugin (jack_rack, saved_plugin); - } - - saved_rack_destroy (saved_rack); - - return 0; -} - - -/* EOF */ diff --git a/src/modules/jackrack/jack_rack.h b/src/modules/jackrack/jack_rack.h deleted file mode 100644 index 7936a8b..0000000 --- a/src/modules/jackrack/jack_rack.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __JR_JACK_RACK_H__ -#define __JR_JACK_RACK_H__ - -#include -#include - -#include "plugin.h" -#include "plugin_mgr.h" -#include "plugin_settings.h" -#include "process.h" - -typedef struct _saved_plugin saved_plugin_t; - -struct _saved_plugin -{ - settings_t *settings; -}; - -typedef struct _saved_rack saved_rack_t; - -struct _saved_rack -{ - unsigned long channels; - jack_nframes_t sample_rate; - GSList * plugins; -}; - -typedef struct _jack_rack jack_rack_t; - -struct _jack_rack -{ - plugin_mgr_t * plugin_mgr; - process_info_t * procinfo; - unsigned long channels; - GSList * saved_plugins; -}; - -jack_rack_t * jack_rack_new (const char * client_name, unsigned long channels); -void jack_rack_destroy (jack_rack_t * jack_rack); - -int jack_rack_open_file (jack_rack_t * jack_rack, const char * filename); -void jack_rack_add_plugin (jack_rack_t * jack_rack, plugin_t * plugin); -void jack_rack_add_saved_plugin (jack_rack_t * jack_rack, struct _saved_plugin * saved_plugin); - -plugin_t * jack_rack_instantiate_plugin (jack_rack_t * jack_rack, plugin_desc_t * desc); - -#endif /* __JR_JACK_RACK_H__ */ diff --git a/src/modules/jackrack/lock_free_fifo.c b/src/modules/jackrack/lock_free_fifo.c deleted file mode 100644 index 177f6b4..0000000 --- a/src/modules/jackrack/lock_free_fifo.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include - -#include - -#include "lock_free_fifo.h" - -/** initialise a lock free fifo */ - -void -lff_init (lff_t * lff, unsigned int size, size_t object_size) -{ - lff->size = size; - lff->object_size = object_size; - lff->read_index = 0; - lff->write_index = 0; - lff->data = g_malloc (object_size * size); -} - -lff_t * -lff_new (unsigned int size, size_t object_size) -{ - lff_t * lff; - - lff = g_malloc (sizeof (lff_t)); - - lff_init (lff, size, object_size); - - return lff; -} - -void -lff_free (lff_t * lff) -{ - g_free (lff->data); -} - -void -lff_destroy (lff_t * lff) -{ - lff_free (lff); - g_free (lff); -} - -/** read an element from the fifo into data. -returns 0 on success, non-zero if there were no elements to read */ -int lff_read (lff_t * lff, void * data) { - if (lff->read_index == lff->write_index) { - return -1; - } else { - memcpy (data, ((char *)lff->data) + (lff->read_index * lff->object_size), - lff->object_size); - lff->read_index++; - if (lff->read_index >= lff->size) { - lff->read_index = 0; - } - return 0; - } -} - -/** write an element from data to the fifo. -returns 0 on success, non-zero if there was no space */ -int lff_write (lff_t * lff, void * data) { - static unsigned int ri; - - /* got to read read_index only once for safety */ - ri = lff->read_index; - - /* lots of logic for when we're allowed to write to the fifo which basically - boils down to "don't write if we're one element behind the read index" */ - if ((ri > lff->write_index && ri - lff->write_index > 1) || - (lff->write_index >= ri && lff->write_index != lff->size - 1) || - (lff->write_index >= ri && lff->write_index == lff->size - 1 && ri != 0)) { - -/* if ((ri > lff->write_index && ri - lff->write_index > 1) || - (lff->write_index >= ri && (lff->write_index != lff->size - 1 || ri != 0))) { */ - - memcpy (((char *)lff->data) + (lff->write_index * lff->object_size), - data, lff->object_size); - - /* FIXME: is this safe? */ - lff->write_index++; - if (lff->write_index >= lff->size) { - lff->write_index = 0; - } - - return 0; - } else { - return -1; - } -} diff --git a/src/modules/jackrack/lock_free_fifo.h b/src/modules/jackrack/lock_free_fifo.h deleted file mode 100644 index 29abd3c..0000000 --- a/src/modules/jackrack/lock_free_fifo.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __JLH_LOCK_FREE_FIFO_H__ -#define __JLH_LOCK_FREE_FIFO_H__ - -/** lock free fifo ring buffer structure */ -typedef struct lock_free_fifo { - /** Size of the ringbuffer (in elements) */ - unsigned int size; - /** the memory containing the ringbuffer */ - void * data; - /** the size of an element */ - size_t object_size; - /** the current position of the reader */ - unsigned int read_index; - /** the current position of the writer */ - unsigned int write_index; -} lff_t; - -void lff_init (lff_t * lff, unsigned int size, size_t object_size); -void lff_free (lff_t * lff); - -lff_t * lff_new (unsigned int size, size_t object_size); -void lff_destroy (lff_t * lock_free_fifo); - -int lff_read (lff_t * lock_free_fifo, void * data); -int lff_write (lff_t * lock_free_fifo, void * data); - - -#endif /* __JLH_LOCK_FREE_FIFO_H__ */ diff --git a/src/modules/jackrack/plugin.c b/src/modules/jackrack/plugin.c deleted file mode 100644 index 6a483a8..0000000 --- a/src/modules/jackrack/plugin.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include - -#include - -#include "plugin.h" -#include "jack_rack.h" -#include "process.h" - -#define CONTROL_FIFO_SIZE 128 - - - -/* swap over the jack ports in two plugins */ -static void -plugin_swap_aux_ports (plugin_t * plugin, plugin_t * other) -{ - guint copy; - jack_port_t ** aux_ports_tmp; - - for (copy = 0; copy < plugin->copies; copy++) - { - aux_ports_tmp = other->holders[copy].aux_ports; - other->holders[copy].aux_ports = plugin->holders[copy].aux_ports; - plugin->holders[copy].aux_ports = aux_ports_tmp; - } -} - -/** connect up the ladspa instance's input buffers to the previous - plugin's audio memory. make sure to check that plugin->prev - exists. */ -void -plugin_connect_input_ports (plugin_t * plugin, LADSPA_Data ** inputs) -{ - gint copy; - unsigned long channel; - unsigned long rack_channel; - - if (!plugin || !inputs) - return; - - rack_channel = 0; - for (copy = 0; copy < plugin->copies; copy++) - { - for (channel = 0; channel < plugin->desc->channels; channel++) - { - plugin->descriptor-> - connect_port (plugin->holders[copy].instance, - plugin->desc->audio_input_port_indicies[channel], - inputs[rack_channel]); - rack_channel++; - } - } - - plugin->audio_input_memory = inputs; -} - -/** connect up a plugin's output ports to its own audio_output_memory output memory */ -void -plugin_connect_output_ports (plugin_t * plugin) -{ - gint copy; - unsigned long channel; - unsigned long rack_channel = 0; - - if (!plugin) - return; - - - for (copy = 0; copy < plugin->copies; copy++) - { - for (channel = 0; channel < plugin->desc->channels; channel++) - { - plugin->descriptor-> - connect_port (plugin->holders[copy].instance, - plugin->desc->audio_output_port_indicies[channel], - plugin->audio_output_memory[rack_channel]); - rack_channel++; - } - } -} - -void -process_add_plugin (process_info_t * procinfo, plugin_t * plugin) -{ - - /* sort out list pointers */ - plugin->next = NULL; - plugin->prev = procinfo->chain_end; - - if (procinfo->chain_end) - procinfo->chain_end->next = plugin; - else - procinfo->chain = plugin; - - procinfo->chain_end = plugin; - -} - - -/** remove a plugin from the chain */ -plugin_t * -process_remove_plugin (process_info_t * procinfo, plugin_t *plugin) -{ - /* sort out chain pointers */ - if (plugin->prev) - plugin->prev->next = plugin->next; - else - procinfo->chain = plugin->next; - - if (plugin->next) - plugin->next->prev = plugin->prev; - else - procinfo->chain_end = plugin->prev; - - /* sort out the aux ports */ - if (procinfo->jack_client && plugin->desc->aux_channels > 0) - { - plugin_t * other; - - for (other = plugin->next; other; other = other->next) - if (other->desc->id == plugin->desc->id) - plugin_swap_aux_ports (plugin, other); - } - - return plugin; -} - -/** enable/disable a plugin */ -void -process_ablise_plugin (process_info_t * procinfo, plugin_t *plugin, gboolean enable) -{ - plugin->enabled = enable; -} - -/** enable/disable a plugin */ -void -process_ablise_plugin_wet_dry (process_info_t * procinfo, plugin_t *plugin, gboolean enable) -{ - plugin->wet_dry_enabled = enable; -} - -/** move a plugin up or down one place in the chain */ -void -process_move_plugin (process_info_t * procinfo, plugin_t *plugin, gint up) -{ - /* other plugins in the chain */ - plugin_t *pp = NULL, *p, *n, *nn = NULL; - - /* note that we should never recieve an illogical move request - ie, there will always be at least 1 plugin before for an up - request or 1 plugin after for a down request */ - - /* these are pointers to the plugins surrounding the specified one: - { pp, p, plugin, n, nn } which makes things much clearer than - tptr, tptr2 etc */ - p = plugin->prev; - if (p) pp = p->prev; - n = plugin->next; - if (n) nn = n->next; - - if (up) - { - if (!p) - return; - - if (pp) - pp->next = plugin; - else - procinfo->chain = plugin; - - p->next = n; - p->prev = plugin; - - plugin->prev = pp; - plugin->next = p; - - if (n) - n->prev = p; - else - procinfo->chain_end = p; - - } - else - { - if (!n) - return; - - if (p) - p->next = n; - else - procinfo->chain = n; - - n->prev = p; - n->next = plugin; - - plugin->prev = n; - plugin->next = nn; - - if (nn) - nn->prev = plugin; - else - procinfo->chain_end = plugin; - } - - if (procinfo->jack_client && plugin->desc->aux_channels > 0) - { - plugin_t * other; - other = up ? plugin->next : plugin->prev; - - /* swap around the jack ports */ - if (other->desc->id == plugin->desc->id) - plugin_swap_aux_ports (plugin, other); - } -} - -/** exchange an existing plugin for a newly created one */ -plugin_t * -process_change_plugin (process_info_t * procinfo, - plugin_t *plugin, plugin_t * new_plugin) -{ - new_plugin->next = plugin->next; - new_plugin->prev = plugin->prev; - - if (plugin->prev) - plugin->prev->next = new_plugin; - else - procinfo->chain = new_plugin; - - if (plugin->next) - plugin->next->prev = new_plugin; - else - procinfo->chain_end = new_plugin; - - /* sort out the aux ports */ - if (procinfo->jack_client && plugin->desc->aux_channels > 0) - { - plugin_t * other; - - for (other = plugin->next; other; other = other->next) - if (other->desc->id == plugin->desc->id) - plugin_swap_aux_ports (plugin, other); - } - - return plugin; -} - - -/****************************************** - ************* non RT stuff *************** - ******************************************/ - - -static int -plugin_open_plugin (plugin_desc_t * desc, - void ** dl_handle_ptr, - const LADSPA_Descriptor ** descriptor_ptr) -{ - void * dl_handle; - const char * dlerr; - LADSPA_Descriptor_Function get_descriptor; - - /* open the object file */ - dl_handle = dlopen (desc->object_file, RTLD_NOW|RTLD_GLOBAL); - if (!dl_handle) - { - fprintf (stderr, "%s: error opening shared object file '%s': %s\n", - __FUNCTION__, desc->object_file, dlerror()); - return 1; - } - - - /* get the get_descriptor function */ - dlerror (); /* clear the error report */ - - get_descriptor = (LADSPA_Descriptor_Function) - dlsym (dl_handle, "ladspa_descriptor"); - - dlerr = dlerror(); - if (dlerr) - { - fprintf (stderr, "%s: error finding descriptor symbol in object file '%s': %s\n", - __FUNCTION__, desc->object_file, dlerr); - dlclose (dl_handle); - return 1; - } - - *descriptor_ptr = get_descriptor (desc->index); - *dl_handle_ptr = dl_handle; - - return 0; -} - -static int -plugin_instantiate (const LADSPA_Descriptor * descriptor, - unsigned long plugin_index, - gint copies, - LADSPA_Handle * instances) -{ - gint i; - - for (i = 0; i < copies; i++) - { - instances[i] = descriptor->instantiate (descriptor, sample_rate); - - if (!instances[i]) - { - unsigned long d; - - for (d = 0; d < i; d++) - descriptor->cleanup (instances[d]); - - return 1; - } - } - - return 0; -} - -static void -plugin_create_aux_ports (plugin_t * plugin, guint copy, jack_rack_t * jack_rack) -{ - plugin_desc_t * desc; -// plugin_slot_t * slot; - unsigned long aux_channel = 1; - unsigned long plugin_index = 1; - unsigned long i; - char port_name[64]; - char * plugin_name; - char * ptr; -// GList * list; - ladspa_holder_t * holder; - - desc = plugin->desc; - holder = plugin->holders + copy; - - holder->aux_ports = g_malloc (sizeof (jack_port_t *) * desc->aux_channels); - - /* make the plugin name jack worthy */ - ptr = plugin_name = g_strndup (plugin->desc->name, 7); - while (*ptr != '\0') - { - if (*ptr == ' ') - *ptr = '_'; - else - *ptr = tolower (*ptr); - - ptr++; - } - -/* - for (list = jack_rack->slots; list; list = g_list_next (list)) - { - slot = (plugin_slot_t *) list->data; - - if (slot->plugin->desc->id == plugin->desc->id) - plugin_index++; - } -*/ - - for (i = 0; i < desc->aux_channels; i++, aux_channel++) - { - sprintf (port_name, "%s_%ld-%d_%c%ld", - plugin_name, - plugin_index, - copy + 1, - desc->aux_are_input ? 'i' : 'o', - aux_channel); - - holder->aux_ports[i] = - jack_port_register (jack_rack->procinfo->jack_client, - port_name, - JACK_DEFAULT_AUDIO_TYPE, - desc->aux_are_input ? JackPortIsInput : JackPortIsOutput, - 0); - - if (!holder->aux_ports[i]) - { - fprintf (stderr, "Could not register jack port '%s'; aborting\n", port_name); - abort (); - } - } - - g_free (plugin_name); -} - -static LADSPA_Data unused_control_port_output; - -static void -plugin_init_holder (plugin_t * plugin, - guint copy, - LADSPA_Handle instance, - jack_rack_t * jack_rack) -{ - unsigned long i; - plugin_desc_t * desc; - ladspa_holder_t * holder; - - desc = plugin->desc; - holder = plugin->holders + copy; - - holder->instance = instance; - - if (desc->control_port_count > 0) - { - holder->ui_control_fifos = g_malloc (sizeof (lff_t) * desc->control_port_count); - holder->control_memory = g_malloc (sizeof (LADSPA_Data) * desc->control_port_count); - } - else - { - holder->ui_control_fifos = NULL; - holder->control_memory = NULL; - } - - for (i = 0; i < desc->control_port_count; i++) - { - lff_init (holder->ui_control_fifos + i, CONTROL_FIFO_SIZE, sizeof (LADSPA_Data)); - holder->control_memory[i] = - plugin_desc_get_default_control_value (desc, desc->control_port_indicies[i], sample_rate); - - plugin->descriptor-> - connect_port (instance, desc->control_port_indicies[i], holder->control_memory + i); - } - - for (i = 0; i < desc->port_count; i++) - { - if (!LADSPA_IS_PORT_CONTROL (desc->port_descriptors[i])) - continue; - - if (LADSPA_IS_PORT_OUTPUT (desc->port_descriptors[i])) - plugin->descriptor-> connect_port (instance, i, &unused_control_port_output); - } - - if (jack_rack->procinfo->jack_client && plugin->desc->aux_channels > 0) - plugin_create_aux_ports (plugin, copy, jack_rack); - - if (plugin->descriptor->activate) - plugin->descriptor->activate (instance); -} - - -plugin_t * -plugin_new (plugin_desc_t * desc, jack_rack_t * jack_rack) -{ - void * dl_handle; - const LADSPA_Descriptor * descriptor; - LADSPA_Handle * instances; - gint copies; - unsigned long i; - int err; - plugin_t * plugin; - - /* open the plugin */ - err = plugin_open_plugin (desc, &dl_handle, &descriptor); - if (err) - return NULL; - - /* create the instances */ - copies = plugin_desc_get_copies (desc, jack_rack->channels); - instances = g_malloc (sizeof (LADSPA_Handle) * copies); - - err = plugin_instantiate (descriptor, desc->index, copies, instances); - if (err) - { - g_free (instances); - dlclose (dl_handle); - return NULL; - } - - - plugin = g_malloc (sizeof (plugin_t)); - - plugin->descriptor = descriptor; - plugin->dl_handle = dl_handle; - plugin->desc = desc; - plugin->copies = copies; - plugin->enabled = FALSE; - plugin->next = NULL; - plugin->prev = NULL; - plugin->wet_dry_enabled = FALSE; - plugin->jack_rack = jack_rack; - - /* create audio memory and wet/dry stuff */ - plugin->audio_output_memory = g_malloc (sizeof (LADSPA_Data *) * jack_rack->channels); - plugin->wet_dry_fifos = g_malloc (sizeof (lff_t) * jack_rack->channels); - plugin->wet_dry_values = g_malloc (sizeof (LADSPA_Data) * jack_rack->channels); - - for (i = 0; i < jack_rack->channels; i++) - { - plugin->audio_output_memory[i] = g_malloc (sizeof (LADSPA_Data) * buffer_size); - lff_init (plugin->wet_dry_fifos + i, CONTROL_FIFO_SIZE, sizeof (LADSPA_Data)); - plugin->wet_dry_values[i] = 1.0; - } - - /* create holders and fill them out */ - plugin->holders = g_malloc (sizeof (ladspa_holder_t) * copies); - for (i = 0; i < copies; i++) - plugin_init_holder (plugin, i, instances[i], jack_rack); - - return plugin; -} - - -void -plugin_destroy (plugin_t * plugin) -{ - unsigned long i, j; - int err; - - /* destroy holders */ - for (i = 0; i < plugin->copies; i++) - { - if (plugin->descriptor->deactivate) - plugin->descriptor->deactivate (plugin->holders[i].instance); - -/* if (plugin->descriptor->cleanup) - plugin->descriptor->cleanup (plugin->holders[i].instance); */ - - if (plugin->desc->control_port_count > 0) - { - for (j = 0; j < plugin->desc->control_port_count; j++) - { - lff_free (plugin->holders[i].ui_control_fifos + j); - } - g_free (plugin->holders[i].ui_control_fifos); - g_free (plugin->holders[i].control_memory); - } - - /* aux ports */ - if (plugin->jack_rack->procinfo->jack_client && plugin->desc->aux_channels > 0) - { - for (j = 0; j < plugin->desc->aux_channels; j++) - { - err = jack_port_unregister (plugin->jack_rack->procinfo->jack_client, - plugin->holders[i].aux_ports[j]); - - if (err) - fprintf (stderr, "%s: could not unregister jack port\n", __FUNCTION__); - } - - g_free (plugin->holders[i].aux_ports); - } - } - - g_free (plugin->holders); - - for (i = 0; i < plugin->jack_rack->channels; i++) - { - g_free (plugin->audio_output_memory[i]); - lff_free (plugin->wet_dry_fifos + i); - } - - g_free (plugin->audio_output_memory); - g_free (plugin->wet_dry_fifos); - g_free (plugin->wet_dry_values); - - err = dlclose (plugin->dl_handle); - if (err) - { - fprintf (stderr, "%s: error closing shared object '%s': %s\n", - __FUNCTION__, plugin->desc->object_file, dlerror ()); - } - - g_free (plugin); -} - - -/* EOF */ diff --git a/src/modules/jackrack/plugin.h b/src/modules/jackrack/plugin.h deleted file mode 100644 index 576b803..0000000 --- a/src/modules/jackrack/plugin.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __JR_PLUGIN_H__ -#define __JR_PLUGIN_H__ - -#include -#include -#include - -#include "process.h" -#include "plugin_desc.h" - -typedef struct _ladspa_holder ladspa_holder_t; -typedef struct _plugin plugin_t; - -struct _ladspa_holder -{ - LADSPA_Handle instance; - lff_t * ui_control_fifos; - LADSPA_Data * control_memory; - - jack_port_t ** aux_ports; -}; - -struct _plugin -{ - plugin_desc_t * desc; - gint enabled; - - gint copies; - ladspa_holder_t * holders; - LADSPA_Data ** audio_input_memory; - LADSPA_Data ** audio_output_memory; - - gboolean wet_dry_enabled; - /* 1.0 = all wet, 0.0 = all dry, 0.5 = 50% wet/50% dry */ - LADSPA_Data * wet_dry_values; - lff_t * wet_dry_fifos; - - plugin_t * next; - plugin_t * prev; - - const LADSPA_Descriptor * descriptor; - void * dl_handle; - struct _jack_rack * jack_rack; - -}; - -void process_add_plugin (process_info_t *, plugin_t *plugin); -plugin_t * process_remove_plugin (process_info_t *, plugin_t *plugin); -void process_ablise_plugin (process_info_t *, plugin_t *plugin, gboolean able); -void process_ablise_plugin_wet_dry (process_info_t *, plugin_t *plugin, gboolean enable); -void process_move_plugin (process_info_t *, plugin_t *plugin, gint up); -plugin_t * process_change_plugin (process_info_t *, plugin_t *plugin, plugin_t * new_plugin); - -struct _jack_rack; -struct _ui; - -plugin_t * plugin_new (plugin_desc_t * plugin_desc, struct _jack_rack * jack_rack); -void plugin_destroy (plugin_t * plugin); - -void plugin_connect_input_ports (plugin_t * plugin, LADSPA_Data ** inputs); -void plugin_connect_output_ports (plugin_t * plugin); - -#endif /* __JR_PLUGIN_H__ */ diff --git a/src/modules/jackrack/plugin_desc.c b/src/modules/jackrack/plugin_desc.c deleted file mode 100644 index b325989..0000000 --- a/src/modules/jackrack/plugin_desc.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include - -#include "plugin_desc.h" -#include "plugin.h" - -#define set_string_property(property, value) \ - \ - if (property) \ - g_free (property); \ - \ - if (value) \ - (property) = g_strdup (value); \ - else \ - (property) = NULL; - - -void -plugin_desc_set_ports (plugin_desc_t * pd, - unsigned long port_count, - const LADSPA_PortDescriptor * port_descriptors, - const LADSPA_PortRangeHint * port_range_hints, - const char * const * port_names); - - - -static void -plugin_desc_init (plugin_desc_t * pd) -{ - pd->object_file = NULL; - pd->id = 0; - pd->name = NULL; - pd->properties = 0; - pd->channels = 0; - pd->port_count = 0; - pd->port_descriptors = NULL; - pd->port_range_hints = NULL; - pd->audio_input_port_indicies = NULL; - pd->audio_output_port_indicies = NULL; - pd->audio_aux_port_indicies = NULL; - pd->control_port_count = 0; - pd->control_port_indicies = NULL; - pd->aux_channels = 0; - pd->aux_are_input = TRUE; -} - -static void -plugin_desc_free_ports (plugin_desc_t * pd) -{ - if (pd->port_count) - { - g_free (pd->port_descriptors); - g_free (pd->port_range_hints); - pd->port_descriptors = NULL; - pd->port_range_hints = NULL; - pd->port_count = 0; - } -} - -static void -plugin_desc_free (plugin_desc_t * pd) -{ - plugin_desc_set_object_file (pd, NULL); - plugin_desc_set_name (pd, NULL); - plugin_desc_free_ports (pd); -} - -plugin_desc_t * -plugin_desc_new () -{ - plugin_desc_t * pd; - pd = g_malloc (sizeof (plugin_desc_t)); - plugin_desc_init (pd); - return pd; -} - -plugin_desc_t * -plugin_desc_new_with_descriptor (const char * object_file, - unsigned long index, - const LADSPA_Descriptor * descriptor) -{ - plugin_desc_t * pd; - pd = plugin_desc_new (); - - plugin_desc_set_object_file (pd, object_file); - plugin_desc_set_index (pd, index); - plugin_desc_set_id (pd, descriptor->UniqueID); - plugin_desc_set_name (pd, descriptor->Name); - plugin_desc_set_properties (pd, descriptor->Properties); - plugin_desc_set_ports (pd, - descriptor->PortCount, - descriptor->PortDescriptors, - descriptor->PortRangeHints, - descriptor->PortNames); - - pd->rt = LADSPA_IS_HARD_RT_CAPABLE(pd->properties) ? TRUE : FALSE; - - return pd; -} - -void -plugin_desc_destroy (plugin_desc_t * pd) -{ - plugin_desc_free (pd); - g_free (pd); -} - -void -plugin_desc_set_object_file (plugin_desc_t * pd, const char * object_file) -{ - set_string_property (pd->object_file, object_file); -} - -void -plugin_desc_set_index (plugin_desc_t * pd, unsigned long index) -{ - pd->index = index; -} - - -void -plugin_desc_set_id (plugin_desc_t * pd, unsigned long id) -{ - pd->id = id; -} - -void -plugin_desc_set_name (plugin_desc_t * pd, const char * name) -{ - set_string_property (pd->name, name); -} - -void -plugin_desc_set_properties (plugin_desc_t * pd, LADSPA_Properties properties) -{ - pd->properties = properties; -} - -static void -plugin_desc_add_audio_port_index (unsigned long ** indicies, - unsigned long * current_port_count, - unsigned long index) -{ - (*current_port_count)++; - - if (*current_port_count == 0) - *indicies = g_malloc (sizeof (unsigned long) * *current_port_count); - else - *indicies = g_realloc (*indicies, sizeof (unsigned long) * *current_port_count); - - (*indicies)[*current_port_count - 1] = index; -} - -static void -plugin_desc_set_port_counts (plugin_desc_t * pd) -{ - unsigned long i; - unsigned long icount = 0; - unsigned long ocount = 0; - - for (i = 0; i < pd->port_count; i++) - { - if (LADSPA_IS_PORT_AUDIO (pd->port_descriptors[i])) - { - if (LADSPA_IS_PORT_INPUT (pd->port_descriptors[i])) - plugin_desc_add_audio_port_index (&pd->audio_input_port_indicies, &icount, i); - else - plugin_desc_add_audio_port_index (&pd->audio_output_port_indicies, &ocount, i); - } - else - { - if (LADSPA_IS_PORT_OUTPUT (pd->port_descriptors[i])) - continue; - - pd->control_port_count++; - if (pd->control_port_count == 0) - pd->control_port_indicies = g_malloc (sizeof (unsigned long) * pd->control_port_count); - else - pd->control_port_indicies = g_realloc (pd->control_port_indicies, - sizeof (unsigned long) * pd->control_port_count); - - pd->control_port_indicies[pd->control_port_count - 1] = i; - } - } - - if (icount == ocount) - pd->channels = icount; - else - { /* deal with auxilliary ports */ - unsigned long ** port_indicies; - unsigned long port_count; - unsigned long i, j; - - if (icount > ocount) - { - pd->channels = ocount; - pd->aux_channels = icount - ocount; - pd->aux_are_input = TRUE; - port_indicies = &pd->audio_input_port_indicies; - port_count = icount; - } - else - { - pd->channels = icount; - pd->aux_channels = ocount - icount; - pd->aux_are_input = FALSE; - port_indicies = &pd->audio_output_port_indicies; - port_count = ocount; - } - - /* allocate indicies */ - pd->audio_aux_port_indicies = g_malloc (sizeof (unsigned long) * pd->aux_channels); - - /* copy indicies */ - for (i = pd->channels, j = 0; i < port_count; i++, j++) - pd->audio_aux_port_indicies[j] = (*port_indicies)[i]; - - /* shrink the main indicies to only have channels indicies */ - *port_indicies = g_realloc (*port_indicies, sizeof (unsigned long) * pd->channels); - } -} - -void -plugin_desc_set_ports (plugin_desc_t * pd, - unsigned long port_count, - const LADSPA_PortDescriptor * port_descriptors, - const LADSPA_PortRangeHint * port_range_hints, - const char * const * port_names) -{ - unsigned long i; - - plugin_desc_free_ports (pd); - - if (!port_count) - return; - - pd->port_count = port_count; - pd->port_descriptors = g_malloc (sizeof (LADSPA_PortDescriptor) * port_count); - pd->port_range_hints = g_malloc (sizeof (LADSPA_PortRangeHint) * port_count); - pd->port_names = g_malloc (sizeof (char *) * port_count); - - memcpy (pd->port_descriptors, port_descriptors, sizeof (LADSPA_PortDescriptor) * port_count); - memcpy (pd->port_range_hints, port_range_hints, sizeof (LADSPA_PortRangeHint) * port_count); - - for (i = 0; i < port_count; i++) - pd->port_names[i] = g_strdup (port_names[i]); - - plugin_desc_set_port_counts (pd); -} - - -LADSPA_Data -plugin_desc_get_default_control_value (plugin_desc_t * pd, unsigned long port_index, guint32 sample_rate) -{ - LADSPA_Data upper, lower; - LADSPA_PortRangeHintDescriptor hint_descriptor; - - hint_descriptor = pd->port_range_hints[port_index].HintDescriptor; - - /* set upper and lower, possibly adjusted to the sample rate */ - if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { - upper = pd->port_range_hints[port_index].UpperBound * (LADSPA_Data) sample_rate; - lower = pd->port_range_hints[port_index].LowerBound * (LADSPA_Data) sample_rate; - } else { - upper = pd->port_range_hints[port_index].UpperBound; - lower = pd->port_range_hints[port_index].LowerBound; - } - - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) - { - if (lower < FLT_EPSILON) - lower = FLT_EPSILON; - } - - - if (LADSPA_IS_HINT_HAS_DEFAULT(hint_descriptor)) { - - if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hint_descriptor)) { - - return lower; - - } else if (LADSPA_IS_HINT_DEFAULT_LOW(hint_descriptor)) { - - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - return exp(log(lower) * 0.75 + log(upper) * 0.25); - } else { - return lower * 0.75 + upper * 0.25; - } - - } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) { - - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - return exp(log(lower) * 0.5 + log(upper) * 0.5); - } else { - return lower * 0.5 + upper * 0.5; - } - - } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint_descriptor)) { - - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - return exp(log(lower) * 0.25 + log(upper) * 0.75); - } else { - return lower * 0.25 + upper * 0.75; - } - - } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) { - - return upper; - - } else if (LADSPA_IS_HINT_DEFAULT_0(hint_descriptor)) { - - return 0.0; - - } else if (LADSPA_IS_HINT_DEFAULT_1(hint_descriptor)) { - - if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { - return (LADSPA_Data) sample_rate; - } else { - return 1.0; - } - - } else if (LADSPA_IS_HINT_DEFAULT_100(hint_descriptor)) { - - if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { - return 100.0 * (LADSPA_Data) sample_rate; - } else { - return 100.0; - } - - } else if (LADSPA_IS_HINT_DEFAULT_440(hint_descriptor)) { - - if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { - return 440.0 * (LADSPA_Data) sample_rate; - } else { - return 440.0; - } - - } - - } else { /* try and find a reasonable default */ - - if (LADSPA_IS_HINT_BOUNDED_BELOW(hint_descriptor)) { - return lower; - } else if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) { - return upper; - } - } - - return 0.0; -} - -LADSPA_Data -plugin_desc_change_control_value (plugin_desc_t * pd, - unsigned long control_index, - LADSPA_Data value, - guint32 old_sample_rate, - guint32 new_sample_rate) -{ - - if (LADSPA_IS_HINT_SAMPLE_RATE (pd->port_range_hints[control_index].HintDescriptor)) - { - LADSPA_Data old_sr, new_sr; - - old_sr = (LADSPA_Data) old_sample_rate; - new_sr = (LADSPA_Data) new_sample_rate; - - value /= old_sr; - value *= new_sr; - } - - return value; -} - -gint -plugin_desc_get_copies (plugin_desc_t * pd, unsigned long rack_channels) -{ - gint copies = 1; - - if (pd->channels > rack_channels) - return 0; - - while (pd->channels * copies < rack_channels) - copies++; - - if (pd->channels * copies > rack_channels) - return 0; - - return copies; -} - -/* EOF */ diff --git a/src/modules/jackrack/plugin_desc.h b/src/modules/jackrack/plugin_desc.h deleted file mode 100644 index d6b5ca3..0000000 --- a/src/modules/jackrack/plugin_desc.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __JR_PLUGIN_DESC_H__ -#define __JR_PLUGIN_DESC_H__ - -#include -#include - -typedef struct _plugin_desc plugin_desc_t; - -struct _plugin_desc -{ - char * object_file; - unsigned long index; - unsigned long id; - char * name; - LADSPA_Properties properties; - gboolean rt; - - unsigned long channels; - - gboolean aux_are_input; - unsigned long aux_channels; - - unsigned long port_count; - LADSPA_PortDescriptor * port_descriptors; - LADSPA_PortRangeHint * port_range_hints; - char ** port_names; - - unsigned long * audio_input_port_indicies; - unsigned long * audio_output_port_indicies; - - unsigned long * audio_aux_port_indicies; - - unsigned long control_port_count; - unsigned long * control_port_indicies; -}; - -plugin_desc_t * plugin_desc_new (); -plugin_desc_t * plugin_desc_new_with_descriptor (const char * object_file, - unsigned long index, - const LADSPA_Descriptor * descriptor); -void plugin_desc_destroy (); - -void plugin_desc_set_object_file (plugin_desc_t * pd, const char * object_file); -void plugin_desc_set_index (plugin_desc_t * pd, unsigned long index); -void plugin_desc_set_id (plugin_desc_t * pd, unsigned long id); -void plugin_desc_set_name (plugin_desc_t * pd, const char * name); -void plugin_desc_set_properties (plugin_desc_t * pd, LADSPA_Properties properties); - -struct _plugin * plugin_desc_instantiate (plugin_desc_t * pd); - -LADSPA_Data plugin_desc_get_default_control_value (plugin_desc_t * pd, unsigned long port_index, guint32 sample_rate); -LADSPA_Data plugin_desc_change_control_value (plugin_desc_t *, unsigned long, LADSPA_Data, guint32, guint32); - -gint plugin_desc_get_copies (plugin_desc_t * pd, unsigned long rack_channels); - -#endif /* __JR_PLUGIN_DESC_H__ */ diff --git a/src/modules/jackrack/plugin_mgr.c b/src/modules/jackrack/plugin_mgr.c deleted file mode 100644 index ca80609..0000000 --- a/src/modules/jackrack/plugin_mgr.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "plugin_mgr.h" -#include "plugin_desc.h" - - -static gboolean -plugin_is_valid (const LADSPA_Descriptor * descriptor) -{ - unsigned long i; - unsigned long icount = 0; - unsigned long ocount = 0; - - for (i = 0; i < descriptor->PortCount; i++) - { - if (!LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[i])) - continue; - - if (LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[i])) - icount++; - else - ocount++; - } - - if (icount == 0 || ocount == 0) - return FALSE; - - return TRUE; -} - -static void -plugin_mgr_get_object_file_plugins (plugin_mgr_t * plugin_mgr, const char * filename) -{ - const char * dlerr; - void * dl_handle; - LADSPA_Descriptor_Function get_descriptor; - const LADSPA_Descriptor * descriptor; - unsigned long plugin_index; - plugin_desc_t * desc, * other_desc = NULL; - GSList * list; - gboolean exists; - int err; - - /* open the object file */ - dl_handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL); - if (!dl_handle) - { - fprintf (stderr, "%s: error opening shared object file '%s': %s\n", - __FUNCTION__, filename, dlerror()); - return; - } - - - /* get the get_descriptor function */ - dlerror (); /* clear the error report */ - - get_descriptor = (LADSPA_Descriptor_Function) - dlsym (dl_handle, "ladspa_descriptor"); - - dlerr = dlerror(); - if (dlerr) { - fprintf (stderr, "%s: error finding ladspa_descriptor symbol in object file '%s': %s\n", - __FUNCTION__, filename, dlerr); - dlclose (dl_handle); - return; - } - - plugin_index = 0; - while ( (descriptor = get_descriptor (plugin_index)) ) - { - if (!plugin_is_valid (descriptor)) - { - plugin_index++; - continue; - } - - - /* check it doesn't already exist */ - exists = FALSE; - for (list = plugin_mgr->all_plugins; list; list = g_slist_next (list)) - { - other_desc = (plugin_desc_t *) list->data; - - if (other_desc->id == descriptor->UniqueID) - { - exists = TRUE; - break; - } - } - - if (exists) - { - printf ("Plugin %ld exists in both '%s' and '%s'; using version in '%s'\n", - descriptor->UniqueID, other_desc->object_file, filename, other_desc->object_file); - plugin_index++; - continue; - } - - - desc = plugin_desc_new_with_descriptor (filename, plugin_index, descriptor); - plugin_mgr->all_plugins = g_slist_append (plugin_mgr->all_plugins, desc); - plugin_index++; - plugin_mgr->plugin_count++; - - /* print in the splash screen */ - /* printf ("Loaded plugin '%s'\n", desc->name); */ - } - - err = dlclose (dl_handle); - if (err) - { - fprintf (stderr, "%s: error closing object file '%s': %s\n", - __FUNCTION__, filename, dlerror ()); - } -} - -static void -plugin_mgr_get_dir_plugins (plugin_mgr_t * plugin_mgr, const char * dir) -{ - DIR * dir_stream; - struct dirent * dir_entry; - char * file_name; - int err; - size_t dirlen; - - dir_stream = opendir (dir); - if (!dir_stream) - { -/* fprintf (stderr, "%s: error opening directory '%s': %s\n", - __FUNCTION__, dir, strerror (errno)); */ - return; - } - - dirlen = strlen (dir); - - while ( (dir_entry = readdir (dir_stream)) ) - { - struct stat info; - - if (strcmp (dir_entry->d_name, ".") == 0 || - strcmp (dir_entry->d_name, "..") == 0) - continue; - - file_name = g_malloc (dirlen + 1 + strlen (dir_entry->d_name) + 1); - - strcpy (file_name, dir); - if (file_name[dirlen - 1] == '/') - strcpy (file_name + dirlen, dir_entry->d_name); - else - { - file_name[dirlen] = '/'; - strcpy (file_name + dirlen + 1, dir_entry->d_name); - } - - stat (file_name, &info); - if (S_ISDIR (info.st_mode)) - plugin_mgr_get_dir_plugins (plugin_mgr, file_name); - else - plugin_mgr_get_object_file_plugins (plugin_mgr, file_name); - - g_free (file_name); - } - - err = closedir (dir_stream); - if (err) - fprintf (stderr, "%s: error closing directory '%s': %s\n", - __FUNCTION__, dir, strerror (errno)); -} - -static void -plugin_mgr_get_path_plugins (plugin_mgr_t * plugin_mgr) -{ - char * ladspa_path, * dir; - - ladspa_path = g_strdup (getenv ("LADSPA_PATH")); - if (!ladspa_path) - ladspa_path = g_strdup ("/usr/local/lib/ladspa:/usr/lib/ladspa:/usr/lib64/ladspa"); - - dir = strtok (ladspa_path, ":"); - do - plugin_mgr_get_dir_plugins (plugin_mgr, dir); - while ((dir = strtok (NULL, ":"))); - - g_free (ladspa_path); -} - -static gint -plugin_mgr_sort (gconstpointer a, gconstpointer b) -{ - const plugin_desc_t * da; - const plugin_desc_t * db; - da = (const plugin_desc_t *) a; - db = (const plugin_desc_t *) b; - - return strcasecmp (da->name, db->name); -} - -plugin_mgr_t * -plugin_mgr_new () -{ - plugin_mgr_t * pm; - - pm = g_malloc (sizeof (plugin_mgr_t)); - pm->all_plugins = NULL; - pm->plugins = NULL; - pm->plugin_count = 0; - - plugin_mgr_get_path_plugins (pm); - - if (!pm->all_plugins) - { - fprintf (stderr, "No LADSPA plugins were found!\n\nCheck your LADSPA_PATH environment variable.\n"); - abort (); - } - - pm->all_plugins = g_slist_sort (pm->all_plugins, plugin_mgr_sort); - - return pm; -} - -void -plugin_mgr_destroy (plugin_mgr_t * plugin_mgr) -{ - GSList * list; - - for (list = plugin_mgr->all_plugins; list; list = g_slist_next (list)) - plugin_desc_destroy ((plugin_desc_t *) list->data); - - g_slist_free (plugin_mgr->plugins); - g_slist_free (plugin_mgr->all_plugins); - free (plugin_mgr); -} - - -void -plugin_mgr_set_plugins (plugin_mgr_t * plugin_mgr, unsigned long rack_channels) -{ - GSList * list; - plugin_desc_t * desc; - - /* clear the current plugins */ - g_slist_free (plugin_mgr->plugins); - plugin_mgr->plugins = NULL; - - for (list = plugin_mgr->all_plugins; list; list = g_slist_next (list)) - { - desc = (plugin_desc_t *) list->data; - - if (plugin_desc_get_copies (desc, rack_channels) != 0) - plugin_mgr->plugins = g_slist_append (plugin_mgr->plugins, desc); - } -} - -static plugin_desc_t * -plugin_mgr_find_desc (plugin_mgr_t * plugin_mgr, GSList * plugins, unsigned long id) -{ - GSList * list; - plugin_desc_t * desc; - - for (list = plugins; list; list = g_slist_next (list)) - { - desc = (plugin_desc_t *) list->data; - - if (desc->id == id) - return desc; - } - - return NULL; -} - -plugin_desc_t * -plugin_mgr_get_desc (plugin_mgr_t * plugin_mgr, unsigned long id) -{ - return plugin_mgr_find_desc (plugin_mgr, plugin_mgr->plugins, id); -} - -plugin_desc_t * -plugin_mgr_get_any_desc (plugin_mgr_t * plugin_mgr, unsigned long id) -{ - return plugin_mgr_find_desc (plugin_mgr, plugin_mgr->all_plugins, id); -} - - -/* EOF */ diff --git a/src/modules/jackrack/plugin_mgr.h b/src/modules/jackrack/plugin_mgr.h deleted file mode 100644 index bc70237..0000000 --- a/src/modules/jackrack/plugin_mgr.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __JR_PLUGIN_MANAGER_H__ -#define __JR_PLUGIN_MANAGER_H__ - -#include - -#include "plugin_desc.h" - -typedef struct _plugin_mgr plugin_mgr_t; - -struct _plugin_mgr -{ - GSList * all_plugins; - - GSList * plugins; - unsigned long plugin_count; -}; - -struct _ui; - -plugin_mgr_t * plugin_mgr_new (); -void plugin_mgr_destroy (plugin_mgr_t * plugin_mgr); - -void plugin_mgr_set_plugins (plugin_mgr_t * plugin_mgr, unsigned long rack_channels); - -plugin_desc_t * plugin_mgr_get_desc (plugin_mgr_t * plugin_mgr, unsigned long id); -plugin_desc_t * plugin_mgr_get_any_desc (plugin_mgr_t * plugin_mgr, unsigned long id); - -#endif /* __JR_PLUGIN_MANAGER_H__ */ diff --git a/src/modules/jackrack/plugin_settings.c b/src/modules/jackrack/plugin_settings.c deleted file mode 100644 index 7284b80..0000000 --- a/src/modules/jackrack/plugin_settings.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define _GNU_SOURCE - -#include - -#include "plugin_settings.h" - - -static void -settings_set_to_default (settings_t * settings, guint32 sample_rate) -{ - unsigned long control; - guint copy; - LADSPA_Data value; - - for (control = 0; control < settings->desc->control_port_count; control++) - { - value = plugin_desc_get_default_control_value (settings->desc, control, sample_rate); - - for (copy = 0; copy < settings->copies; copy++) - { - settings->control_values[copy][control] = value; - } - - settings->locks[control] = TRUE; - } -} - -settings_t * -settings_new (plugin_desc_t * desc, unsigned long channels, guint32 sample_rate) -{ - settings_t * settings; - unsigned long channel; - guint copies; - - settings = g_malloc (sizeof (settings_t)); - copies = plugin_desc_get_copies (desc, channels); - - settings->sample_rate = sample_rate; - settings->desc = desc; - settings->copies = copies; - settings->channels = channels; - settings->lock_all = TRUE; - settings->enabled = FALSE; - settings->locks = NULL; - settings->control_values = NULL; - settings->wet_dry_enabled = FALSE; - settings->wet_dry_locked = TRUE; - - /* control settings */ - if (desc->control_port_count > 0) - { - guint copy; - - settings->locks = g_malloc (sizeof (gboolean) * desc->control_port_count); - - settings->control_values = g_malloc (sizeof (LADSPA_Data *) * copies); - for (copy = 0; copy < copies; copy++) - { - settings->control_values[copy] = g_malloc (sizeof (LADSPA_Data) * desc->control_port_count); - } - - settings_set_to_default (settings, sample_rate); - } - - /* wet/dry settings */ - settings->wet_dry_values = g_malloc (sizeof (LADSPA_Data) * channels); - for (channel = 0; channel < channels; channel++) - settings->wet_dry_values[channel] = 1.0; - - return settings; -} - -settings_t * -settings_dup (settings_t * other) -{ - settings_t * settings; - plugin_desc_t * desc; - unsigned long channel; - - settings = g_malloc (sizeof (settings_t)); - - settings->sample_rate = other->sample_rate; - settings->desc = other->desc; - settings->copies = settings_get_copies (other); - settings->channels = settings_get_channels (other); - settings->wet_dry_enabled = settings_get_wet_dry_enabled (other); - settings->wet_dry_locked = settings_get_wet_dry_locked (other); - settings->lock_all = settings_get_lock_all (other); - settings->enabled = settings_get_enabled (other); - settings->locks = NULL; - settings->control_values = NULL; - - desc = other->desc; - - if (desc->control_port_count > 0) - { - guint copy; - unsigned long control; - - settings->locks = g_malloc (sizeof (gboolean) * desc->control_port_count); - for (control = 0; control < desc->control_port_count; control++) - settings_set_lock (settings, control, settings_get_lock (other, control)); - - settings->control_values = g_malloc (sizeof (LADSPA_Data *) * settings->copies); - for (copy = 0; copy < settings->copies; copy++) - { - settings->control_values[copy] = g_malloc (sizeof (LADSPA_Data) * desc->control_port_count); - - for (control = 0; control < desc->control_port_count; control++) - { - settings->control_values[copy][control] = settings_get_control_value (other, copy, control); - } - } - } - - settings->wet_dry_values = g_malloc (sizeof (LADSPA_Data) * settings->channels); - for (channel = 0; channel < settings->channels; channel++) - settings->wet_dry_values[channel] = settings_get_wet_dry_value (other, channel); - - return settings; -} - -void -settings_destroy (settings_t * settings) -{ - if (settings->desc->control_port_count > 0) - { - guint i; - for (i = 0; i < settings->copies; i++) - g_free (settings->control_values[i]); - - g_free (settings->control_values); - g_free (settings->locks); - } - - g_free (settings->wet_dry_values); - - g_free (settings); -} - -static void -settings_set_copies (settings_t * settings, guint copies) -{ - guint copy; - guint last_copy; - unsigned long control; - - if (copies <= settings->copies) - return; - - last_copy = settings->copies - 1; - - settings->control_values = g_realloc (settings->control_values, - sizeof (LADSPA_Data *) * copies); - - /* copy over the last settings to the new copies */ - for (copy = settings->copies; copy < copies; copy++) - { - for (control = 0; control < settings->desc->control_port_count; control++) - { - settings->control_values[copy][control] = - settings->control_values[last_copy][control]; - } - } - - settings->copies = copies; -} - -static void -settings_set_channels (settings_t * settings, unsigned long channels) -{ - unsigned long channel; - LADSPA_Data last_value; - - if (channels <= settings->channels) - return; - - settings->wet_dry_values = g_realloc (settings->wet_dry_values, sizeof (LADSPA_Data) * channels); - - last_value = settings->wet_dry_values[settings->channels - 1]; - - for (channel = settings->channels; channel < channels; channel++) - settings->wet_dry_values[channel] = last_value; - - settings->channels = channels; -} - -void -settings_set_sample_rate (settings_t * settings, guint32 sample_rate) -{ - LADSPA_Data old_sample_rate; - LADSPA_Data new_sample_rate; - - g_return_if_fail (settings != NULL); - - if (settings->sample_rate == sample_rate) - return; - - if (settings->desc->control_port_count > 0) - { - unsigned long control; - guint copy; - - new_sample_rate = (LADSPA_Data) sample_rate; - old_sample_rate = (LADSPA_Data) settings->sample_rate; - - for (control = 0; control < settings->desc->control_port_count; control++) - { - for (copy = 0; copy < settings->copies; copy++) - { - if (LADSPA_IS_HINT_SAMPLE_RATE (settings->desc->port_range_hints[control].HintDescriptor)) - { - settings->control_values[copy][control] = - (settings->control_values[copy][control] / old_sample_rate) * new_sample_rate; - } - } - } - } - - settings->sample_rate = sample_rate; -} - -void -settings_set_control_value (settings_t * settings, guint copy, unsigned long control_index, LADSPA_Data value) -{ - g_return_if_fail (settings != NULL); - g_return_if_fail (control_index < settings->desc->control_port_count); - - if (copy >= settings->copies) - settings_set_copies (settings, copy + 1); - - settings->control_values[copy][control_index] = value; -} - -void -settings_set_lock (settings_t * settings, unsigned long control_index, gboolean locked) -{ - g_return_if_fail (settings != NULL); - g_return_if_fail (control_index < settings->desc->control_port_count); - - settings->locks[control_index] = locked; -} - -void -settings_set_lock_all (settings_t * settings, gboolean lock_all) -{ - g_return_if_fail (settings != NULL); - - settings->lock_all = lock_all; -} - -void -settings_set_enabled (settings_t * settings, gboolean enabled) -{ - g_return_if_fail (settings != NULL); - - settings->enabled = enabled; -} - -void -settings_set_wet_dry_enabled (settings_t * settings, gboolean enabled) -{ - g_return_if_fail (settings != NULL); - - settings->wet_dry_enabled = enabled; -} - -void -settings_set_wet_dry_locked (settings_t * settings, gboolean locked) -{ - g_return_if_fail (settings != NULL); - - settings->wet_dry_locked = locked; -} - -void -settings_set_wet_dry_value (settings_t * settings, unsigned long channel, LADSPA_Data value) -{ - g_return_if_fail (settings != NULL); - - if (channel >= settings->channels) - settings_set_channels (settings, channel + 1); - - settings->wet_dry_values[channel] = value; -} - - -LADSPA_Data -settings_get_control_value (settings_t * settings, guint copy, unsigned long control_index) -{ - g_return_val_if_fail (settings != NULL, NAN); - g_return_val_if_fail (control_index < settings->desc->control_port_count, NAN); - - if (copy >= settings->copies) - settings_set_copies (settings, copy - 1); - - return settings->control_values[copy][control_index]; -} - -gboolean -settings_get_lock (const settings_t * settings, unsigned long control_index) -{ - g_return_val_if_fail (settings != NULL, FALSE); - - return settings->locks[control_index]; -} - -gboolean -settings_get_lock_all (const settings_t * settings) -{ - g_return_val_if_fail (settings != NULL, FALSE); - - return settings->lock_all; -} - -gboolean -settings_get_enabled (const settings_t * settings) -{ - g_return_val_if_fail (settings != NULL, FALSE); - - return settings->enabled; -} - -guint -settings_get_copies (const settings_t * settings) -{ - g_return_val_if_fail (settings != NULL, 0); - - return settings->copies; -} - - -unsigned long -settings_get_channels (const settings_t * settings) -{ - g_return_val_if_fail (settings != NULL, 0); - - return settings->channels; -} - -gboolean -settings_get_wet_dry_enabled (const settings_t * settings) -{ - g_return_val_if_fail (settings != NULL, FALSE); - - return settings->wet_dry_enabled; -} - -gboolean -settings_get_wet_dry_locked (const settings_t * settings) -{ - g_return_val_if_fail (settings != NULL, FALSE); - - return settings->wet_dry_locked; -} - -LADSPA_Data -settings_get_wet_dry_value (settings_t * settings, unsigned long channel) -{ - g_return_val_if_fail (settings != NULL, NAN); - - if (channel >= settings->channels) - settings_set_channels (settings, channel + 1); - - return settings->wet_dry_values[channel]; -} - - - -/* EOF */ diff --git a/src/modules/jackrack/plugin_settings.h b/src/modules/jackrack/plugin_settings.h deleted file mode 100644 index 852333b..0000000 --- a/src/modules/jackrack/plugin_settings.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __JR_PLUGIN_SETTINGS_H__ -#define __JR_PLUGIN_SETTINGS_H__ - -#include -#include - -#include "plugin_mgr.h" -#include "plugin_desc.h" - -typedef struct _settings settings_t; - -struct _settings -{ - guint32 sample_rate; - plugin_desc_t * desc; - guint copies; - LADSPA_Data ** control_values; - gboolean * locks; - gboolean lock_all; - gboolean enabled; - unsigned long channels; - gboolean wet_dry_enabled; - gboolean wet_dry_locked; - LADSPA_Data * wet_dry_values; -}; - -settings_t * settings_new (plugin_desc_t * desc, unsigned long channels, guint32 sample_rate); -settings_t * settings_dup (settings_t * settings); -void settings_destroy (settings_t * settings); - -void settings_set_control_value (settings_t * settings, guint copy, unsigned long control_index, LADSPA_Data value); -void settings_set_lock (settings_t * settings, unsigned long control_index, gboolean locked); -void settings_set_lock_all (settings_t * settings, gboolean lock_all); -void settings_set_enabled (settings_t * settings, gboolean enabled); -void settings_set_wet_dry_enabled (settings_t * settings, gboolean enabled); -void settings_set_wet_dry_locked (settings_t * settings, gboolean locked); -void settings_set_wet_dry_value (settings_t * settings, unsigned long channel, LADSPA_Data value); - -LADSPA_Data settings_get_control_value (settings_t * settings, guint copy, unsigned long control_index); -gboolean settings_get_lock (const settings_t * settings, unsigned long control_index); -gboolean settings_get_lock_all (const settings_t * settings); -gboolean settings_get_enabled (const settings_t * settings); -guint settings_get_copies (const settings_t * settings); -unsigned long settings_get_channels (const settings_t * settings); -gboolean settings_get_wet_dry_enabled (const settings_t * settings); -gboolean settings_get_wet_dry_locked (const settings_t * settings); -LADSPA_Data settings_get_wet_dry_value (settings_t * settings, unsigned long channel); - -void settings_set_sample_rate (settings_t * settings, guint32 sample_rate); - -#endif /* __JR_PLUGIN_SETTINGS_H__ */ diff --git a/src/modules/jackrack/process.c b/src/modules/jackrack/process.c deleted file mode 100644 index efd497f..0000000 --- a/src/modules/jackrack/process.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "process.h" -#include "lock_free_fifo.h" -#include "plugin.h" -#include "jack_rack.h" - -#ifndef _ -#define _(x) x -#endif - -#define USEC_PER_SEC 1000000 -#define MSEC_PER_SEC 1000 -#define TIME_RUN_SKIP_COUNT 5 -#define MAX_BUFFER_SIZE 4096 - -jack_nframes_t sample_rate; -jack_nframes_t buffer_size; - -static void -jack_shutdown_cb (void * data) -{ - process_info_t * procinfo = data; - - procinfo->quit = TRUE; -} - -/** process messages for plugins' control ports */ -void process_control_port_messages (process_info_t * procinfo) { - plugin_t * plugin; - unsigned long control; - unsigned long channel; - gint copy; - - if (!procinfo->chain) return; - - for (plugin = procinfo->chain; plugin; plugin = plugin->next) - { - if (plugin->desc->control_port_count > 0) - for (control = 0; control < plugin->desc->control_port_count; control++) - for (copy = 0; copy < plugin->copies; copy++) - { - while (lff_read (plugin->holders[copy].ui_control_fifos + control, - plugin->holders[copy].control_memory + control) == 0); - } - - if (plugin->wet_dry_enabled) - for (channel = 0; channel < procinfo->channels; channel++) - { - while (lff_read (plugin->wet_dry_fifos + channel, - plugin->wet_dry_values + channel) == 0); - } - } -} - -int get_jack_buffers (process_info_t * procinfo, jack_nframes_t frames) { - unsigned long channel; - - for (channel = 0; channel < procinfo->channels; channel++) - { - procinfo->jack_input_buffers[channel] = jack_port_get_buffer (procinfo->jack_input_ports[channel], frames); - if (!procinfo->jack_input_buffers[channel]) - { - fprintf (stderr, "%s: no jack buffer for input port %ld\n", __FUNCTION__, channel); - return 1; - } - - procinfo->jack_output_buffers[channel] = jack_port_get_buffer (procinfo->jack_output_ports[channel], frames); - if (!procinfo->jack_output_buffers[channel]) - { - fprintf (stderr, "%s: no jack buffer for output port %ld\n", __FUNCTION__, channel); - return 1; - } - } - - return 0; -} - -plugin_t * -get_first_enabled_plugin (process_info_t * procinfo) -{ - plugin_t * first_enabled; - - if (!procinfo->chain) return NULL; - - for (first_enabled = procinfo->chain; - first_enabled; - first_enabled = first_enabled->next) - { - if (first_enabled->enabled) return first_enabled; - } - - return NULL; -} - -plugin_t * -get_last_enabled_plugin (process_info_t * procinfo) -{ - plugin_t * last_enabled; - - if (!procinfo->chain) return NULL; - - for (last_enabled = procinfo->chain_end; - last_enabled; - last_enabled = last_enabled->prev) - { - if (last_enabled->enabled) return last_enabled; - } - - return NULL; -} - -void -connect_chain (process_info_t * procinfo, jack_nframes_t frames) -{ - plugin_t * first_enabled, * last_enabled, * plugin; - gint copy; - unsigned long channel; - if (!procinfo->chain) return; - - first_enabled = get_first_enabled_plugin (procinfo); - if (!first_enabled) return; - - last_enabled = get_last_enabled_plugin (procinfo); - - /* sort out the aux ports */ - plugin = first_enabled; - do - { - if (plugin->desc->aux_channels > 0 && plugin->enabled) - { - if (procinfo->jack_client) - { - for (copy = 0; copy < plugin->copies; copy++) - for (channel = 0; channel < plugin->desc->aux_channels; channel++) - plugin->descriptor-> - connect_port (plugin->holders[copy].instance, - plugin->desc->audio_aux_port_indicies[channel], - jack_port_get_buffer (plugin->holders[copy].aux_ports[channel], frames)); - } - else - { - for (copy = 0; copy < frames; copy++) - procinfo->silent_buffer[copy] = 0.0; - - for (copy = 0; copy < plugin->copies; copy++) - for (channel = 0; channel < plugin->desc->aux_channels; channel++) - plugin->descriptor-> - connect_port (plugin->holders[copy].instance, - plugin->desc->audio_aux_port_indicies[channel], - procinfo->silent_buffer); - } - } - } - while ( (plugin != last_enabled) && (plugin = plugin->next) ); - - /* ensure that all the of the enabled plugins are connected to their memory */ - plugin_connect_output_ports (first_enabled); - if (first_enabled != last_enabled) - { - plugin_connect_input_ports (last_enabled, last_enabled->prev->audio_output_memory); - for (plugin = first_enabled->next; plugin; plugin = plugin->next) - { - if (plugin->enabled) - { - plugin_connect_input_ports (plugin, plugin->prev->audio_output_memory); - plugin_connect_output_ports (plugin); - } - } - } - - /* input buffers for first plugin */ - plugin_connect_input_ports (first_enabled, procinfo->jack_input_buffers); -} - -void -process_chain (process_info_t * procinfo, jack_nframes_t frames) -{ - plugin_t * first_enabled; - plugin_t * last_enabled = NULL; - plugin_t * plugin; - unsigned long channel; - unsigned long i; - - if (procinfo->jack_client) - { - LADSPA_Data zero_signal[frames]; - guint copy; - - /* set the zero signal to zero */ - for (channel = 0; channel < frames; channel++) - zero_signal[channel] = 0.0; - - /* possibly set aux output channels to zero if they're not enabled */ - for (plugin = procinfo->chain; plugin; plugin = plugin->next) - if (!plugin->enabled && - plugin->desc->aux_channels > 0 && - !plugin->desc->aux_are_input) - for (copy = 0; copy < plugin->copies; copy++) - for (channel = 0; channel < plugin->desc->aux_channels; channel++) - memcpy (jack_port_get_buffer (plugin->holders[copy].aux_ports[channel], frames), - zero_signal, sizeof (LADSPA_Data) * frames); - } - - first_enabled = get_first_enabled_plugin (procinfo); - - /* no chain; just copy input to output */ - if (!procinfo->chain || !first_enabled) - { - unsigned long channel; - for (channel = 0; channel < procinfo->channels; channel++) - { - memcpy (procinfo->jack_output_buffers[channel], - procinfo->jack_input_buffers[channel], - sizeof(LADSPA_Data) * frames); - } - return; - } - - /* all past here is guaranteed to have at least 1 enabled plugin */ - - last_enabled = get_last_enabled_plugin (procinfo); - - for (plugin = first_enabled; - plugin; - plugin = plugin->next) - { - if (plugin->enabled) - { - for (i = 0; i < plugin->copies; i++) - plugin->descriptor->run (plugin->holders[i].instance, frames); - - if (plugin->wet_dry_enabled) - for (channel = 0; channel < procinfo->channels; channel++) - for (i = 0; i < frames; i++) - { - plugin->audio_output_memory[channel][i] *= plugin->wet_dry_values[channel]; - plugin->audio_output_memory[channel][i] += plugin->audio_input_memory[channel][i] * (1.0 - plugin->wet_dry_values[channel]); - } - - if (plugin == last_enabled) - break; - } - else - { - - /* copy the data through */ - for (i = 0; i < procinfo->channels; i++) - memcpy (plugin->audio_output_memory[i], - plugin->prev->audio_output_memory[i], - sizeof(LADSPA_Data) * frames); - } - } - - /* copy the last enabled data to the jack ports */ - for (i = 0; i < procinfo->channels; i++) - memcpy (procinfo->jack_output_buffers[i], - last_enabled->audio_output_memory[i], - sizeof(LADSPA_Data) * frames); - -} - -int process_ladspa (process_info_t * procinfo, jack_nframes_t frames, - LADSPA_Data ** inputs, LADSPA_Data ** outputs) { - unsigned long channel; - - if (!procinfo) - { - fprintf (stderr, "%s: no process_info from jack!\n", __FUNCTION__); - return 1; - } - - if (procinfo->quit == TRUE) - return 1; - - process_control_port_messages (procinfo); - - for (channel = 0; channel < procinfo->channels; channel++) - { - procinfo->jack_input_buffers[channel] = inputs[channel]; - if (!procinfo->jack_input_buffers[channel]) - { - fprintf (stderr, "%s: no jack buffer for input port %ld\n", __FUNCTION__, channel); - return 1; - } - - procinfo->jack_output_buffers[channel] = outputs[channel]; - if (!procinfo->jack_output_buffers[channel]) - { - fprintf (stderr, "%s: no jack buffer for output port %ld\n", __FUNCTION__, channel); - return 1; - } - } - - connect_chain (procinfo, frames); - - process_chain (procinfo, frames); - - return 0; -} - -int process_jack (jack_nframes_t frames, void * data) { - int err; - process_info_t * procinfo; - - procinfo = (process_info_t *) data; - - if (!procinfo) - { - fprintf (stderr, "%s: no process_info from jack!\n", __FUNCTION__); - return 1; - } - - if (procinfo->port_count == 0) - return 0; - - if (procinfo->quit == TRUE) - return 1; - - process_control_port_messages (procinfo); - - err = get_jack_buffers (procinfo, frames); - if (err) - { - fprintf(stderr, "%s: failed to get jack ports, not processing\n", __FUNCTION__); - return 0; - } - - connect_chain (procinfo, frames); - - process_chain (procinfo, frames); - - return 0; -} - - - -/******************************************* - ************** non RT stuff *************** - *******************************************/ - -static int -process_info_connect_jack (process_info_t * procinfo) -{ - printf (_("Connecting to JACK server with client name '%s'\n"), procinfo->jack_client_name); - - procinfo->jack_client = jack_client_new (procinfo->jack_client_name); - - if (!procinfo->jack_client) - { - fprintf (stderr, "%s: could not create jack client; is the jackd server running?\n", __FUNCTION__); - return 1; - } - - printf (_("Connected to JACK server\n")); - - jack_set_process_callback (procinfo->jack_client, process_jack, procinfo); - jack_on_shutdown (procinfo->jack_client, jack_shutdown_cb, procinfo); - - return 0; -} - -static void -process_info_connect_port (process_info_t * procinfo, - gshort in, - unsigned long port_index, - const char * port_name) -{ - const char ** jack_ports; - unsigned long jack_port_index; - int err; - char * full_port_name; - - jack_ports = jack_get_ports (procinfo->jack_client, NULL, NULL, - JackPortIsPhysical | (in ? JackPortIsOutput : JackPortIsInput)); - - if (!jack_ports) - return; - - for (jack_port_index = 0; - jack_ports[jack_port_index] && jack_port_index <= port_index; - jack_port_index++) - { - if (jack_port_index != port_index) - continue; - - full_port_name = g_strdup_printf ("%s:%s", procinfo->jack_client_name, port_name); - - printf (_("Connecting ports '%s' and '%s'\n"), full_port_name, jack_ports[jack_port_index]); - - err = jack_connect (procinfo->jack_client, - in ? jack_ports[jack_port_index] : full_port_name, - in ? full_port_name : jack_ports[jack_port_index]); - - if (err) - fprintf (stderr, "%s: error connecting ports '%s' and '%s'\n", - __FUNCTION__, full_port_name, jack_ports[jack_port_index]); - else - printf (_("Connected ports '%s' and '%s'\n"), full_port_name, jack_ports[jack_port_index]); - - free (full_port_name); - } - - free (jack_ports); -} - -int -process_info_set_port_count (process_info_t * procinfo, - unsigned long port_count, gboolean connect_inputs, gboolean connect_outputs) -{ - unsigned long i; - char * port_name; - jack_port_t ** port_ptr; - gshort in; - - if (procinfo->port_count >= port_count) - return -1; - - if (procinfo->port_count == 0) - { - procinfo->jack_input_ports = g_malloc (sizeof (jack_port_t *) * port_count); - procinfo->jack_output_ports = g_malloc (sizeof (jack_port_t *) * port_count); - - procinfo->jack_input_buffers = g_malloc (sizeof (LADSPA_Data *) * port_count); - procinfo->jack_output_buffers = g_malloc (sizeof (LADSPA_Data *) * port_count); - } - else - { - procinfo->jack_input_ports = g_realloc (procinfo->jack_input_ports, sizeof (jack_port_t *) * port_count); - procinfo->jack_output_ports = g_realloc (procinfo->jack_output_ports, sizeof (jack_port_t *) * port_count); - - procinfo->jack_input_buffers = g_realloc (procinfo->jack_input_buffers, sizeof (LADSPA_Data *) * port_count); - procinfo->jack_output_buffers = g_realloc (procinfo->jack_output_buffers, sizeof (LADSPA_Data *) * port_count); - } - - for (i = procinfo->port_count; i < port_count; i++) - { - for (in = 0; in < 2; in++) - { - port_name = g_strdup_printf ("%s_%ld", in ? "in" : "out", i + 1); - - //printf (_("Creating %s port %s\n"), in ? "input" : "output", port_name); - - port_ptr = (in ? &procinfo->jack_input_ports[i] - : &procinfo->jack_output_ports[i]); - - *port_ptr = jack_port_register (procinfo->jack_client, - port_name, - JACK_DEFAULT_AUDIO_TYPE, - in ? JackPortIsInput : JackPortIsOutput, - 0); - - if (!*port_ptr) - { - fprintf (stderr, "%s: could not register port '%s'; aborting\n", - __FUNCTION__, port_name); - return 1; - } - - //printf (_("Created %s port %s\n"), in ? "input" : "output", port_name); - - if ((in && connect_inputs) || (!in && connect_outputs)) - process_info_connect_port (procinfo, in, i, port_name); - - g_free (port_name); - } - } - - procinfo->port_count = port_count; - - return 0; -} - -void -process_info_set_channels (process_info_t * procinfo, - unsigned long channels, gboolean connect_inputs, gboolean connect_outputs) -{ - process_info_set_port_count (procinfo, channels, connect_inputs, connect_outputs); - procinfo->channels = channels; -} - -process_info_t * -process_info_new (const char * client_name, unsigned long rack_channels, - gboolean connect_inputs, gboolean connect_outputs) -{ - process_info_t * procinfo; - char * jack_client_name; - int err; - - procinfo = g_malloc (sizeof (process_info_t)); - - procinfo->chain = NULL; - procinfo->chain_end = NULL; - procinfo->jack_client = NULL; - procinfo->port_count = 0; - procinfo->jack_input_ports = NULL; - procinfo->jack_output_ports = NULL; - procinfo->channels = rack_channels; - procinfo->quit = FALSE; - - if ( client_name == NULL ) - { - sample_rate = 48000; // should be set externally before calling process_ladspa - buffer_size = MAX_BUFFER_SIZE; - procinfo->silent_buffer = g_malloc (sizeof (LADSPA_Data) * buffer_size ); - procinfo->jack_input_buffers = g_malloc (sizeof (LADSPA_Data *) * rack_channels); - procinfo->jack_output_buffers = g_malloc (sizeof (LADSPA_Data *) * rack_channels); - - return procinfo; - } - - /* sort out the client name */ - procinfo->jack_client_name = jack_client_name = strdup (client_name); - for (err = 0; jack_client_name[err] != '\0'; err++) - { - if (jack_client_name[err] == ' ') - jack_client_name[err] = '_'; - else if (!isalnum (jack_client_name[err])) - { /* shift all the chars up one (to remove the non-alphanumeric char) */ - int i; - for (i = err; jack_client_name[i] != '\0'; i++) - jack_client_name[i] = jack_client_name[i + 1]; - } - else if (isupper (jack_client_name[err])) - jack_client_name[err] = tolower (jack_client_name[err]); - } - - err = process_info_connect_jack (procinfo); - if (err) - { -/* g_free (procinfo); */ - return NULL; -/* abort (); */ - } - - sample_rate = jack_get_sample_rate (procinfo->jack_client); - buffer_size = jack_get_sample_rate (procinfo->jack_client); - - jack_set_process_callback (procinfo->jack_client, process_jack, procinfo); - jack_on_shutdown (procinfo->jack_client, jack_shutdown_cb, procinfo); - - jack_activate (procinfo->jack_client); - - err = process_info_set_port_count (procinfo, rack_channels, connect_inputs, connect_outputs); - if (err) - return NULL; - - return procinfo; -} - -void -process_info_destroy (process_info_t * procinfo) { - if (procinfo->jack_client) - { - jack_deactivate (procinfo->jack_client); - jack_client_close (procinfo->jack_client); - } - g_free (procinfo->silent_buffer); - g_free (procinfo->jack_input_ports); - g_free (procinfo->jack_output_ports); - g_free (procinfo->jack_input_buffers); - g_free (procinfo->jack_output_buffers); - g_free (procinfo); -} - -void process_quit (process_info_t * procinfo) { - procinfo->quit = TRUE; -} diff --git a/src/modules/jackrack/process.h b/src/modules/jackrack/process.h deleted file mode 100644 index 8b0c365..0000000 --- a/src/modules/jackrack/process.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * JACK Rack - * - * Original: - * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) - * - * Modification for MLT: - * Copyright (C) 2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __JLH_PROCESS_H__ -#define __JLH_PROCESS_H__ - -#include -#include -#include - -#include "lock_free_fifo.h" - -typedef struct _process_info process_info_t; - -/** this is what gets passed to the process() callback and contains all - the data the process callback will need */ -struct _process_info { - - /** the plugin instance chain */ - struct _plugin * chain; - struct _plugin * chain_end; - - jack_client_t * jack_client; - unsigned long port_count; - jack_port_t ** jack_input_ports; - jack_port_t ** jack_output_ports; - - unsigned long channels; - LADSPA_Data ** jack_input_buffers; - LADSPA_Data ** jack_output_buffers; - LADSPA_Data * silent_buffer; - - char * jack_client_name; - int quit; -}; - -extern jack_nframes_t sample_rate; -extern jack_nframes_t buffer_size; - -process_info_t * process_info_new (const char * client_name, - unsigned long rack_channels, gboolean connect_inputs, gboolean connect_outputs); -void process_info_destroy (process_info_t * procinfo); - -void process_info_set_channels (process_info_t * procinfo, - unsigned long channels, gboolean connect_inputs, gboolean connect_outputs); - -int process_ladspa (process_info_t * procinfo, jack_nframes_t frames, - LADSPA_Data ** inputs, LADSPA_Data ** outputs); - -int process_jack (jack_nframes_t frames, void * data); - -void process_quit (process_info_t * procinfo); - -#endif /* __JLH_PROCESS_H__ */ diff --git a/src/modules/kdenlive/Makefile b/src/modules/kdenlive/Makefile deleted file mode 100644 index d32ab0c..0000000 --- a/src/modules/kdenlive/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltkdenlive$(LIBSUF) - -OBJS = factory.o \ - filter_boxblur.o \ - filter_freeze.o \ - filter_wave.o \ - producer_framebuffer.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt -LDFLAGS += -lm - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/kdenlive/factory.c b/src/modules/kdenlive/factory.c deleted file mode 100644 index 80914c7..0000000 --- a/src/modules/kdenlive/factory.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2007 Jean-Baptiste Mardelle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -extern mlt_filter filter_boxblur_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_freeze_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_wave_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_framebuffer_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "boxblur", filter_boxblur_init ); - MLT_REGISTER( filter_type, "freeze", filter_freeze_init ); - MLT_REGISTER( filter_type, "wave", filter_wave_init ); - MLT_REGISTER( producer_type, "framebuffer", producer_framebuffer_init ); -} diff --git a/src/modules/kdenlive/filter_boxblur.c b/src/modules/kdenlive/filter_boxblur.c deleted file mode 100644 index f1d5425..0000000 --- a/src/modules/kdenlive/filter_boxblur.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * filter_boxblur.c -- blur filter - * Copyright (C) ?-2007 Leny Grisel - * Copyright (C) 2007 Jean-Baptiste Mardelle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - - -static void PreCompute(uint8_t *yuv, int32_t *rgb, int width, int height) -{ - register int x, y, z; - register int uneven = width % 2; - int w = (width - uneven ) / 2; - int yy, uu, vv; - int r, g, b; - int32_t pts[3]; - for (y=0; y0) pts[z]+=rgb[-3]; - if (y>0) pts[z]+=rgb[-(width*3)]; - if (x>0 && y>0) pts[z]-=rgb[-((width+1)*3)]; - *rgb++=pts[z]; - } - - yy = yuv[2]; - YUV2RGB(yy, uu, vv, r, g, b); - pts[0] = r; - pts[1] = g; - pts[2] = b; - for (z = 0; z < 3; z++) - { - pts[z]+=rgb[-3]; - if (y>0) - { - pts[z]+=rgb[-(width*3)]; - pts[z]-=rgb[-((width+1)*3)]; - } - *rgb++=pts[z]; - } - yuv += 4; - } - if (uneven) - { - uu = yuv[1]; - vv = yuv[3]; - yy = yuv[0]; - YUV2RGB(yy, uu, vv, r, g, b); - pts[0] = r; - pts[1] = g; - pts[2] = b; - for (z = 0; z < 3; z++) - { - pts[z]+=rgb[-3]; - if (y>0) - { - pts[z]+=rgb[-(width*3)]; - pts[z]-=rgb[-((width+1)*3)]; - } - *rgb++=pts[z]; - } - yuv += 2; - } - } -} - -static int32_t GetRGB(int32_t *rgb, unsigned int w, unsigned int h, unsigned int x, int offsetx, unsigned int y, int offsety, unsigned int z) -{ - int xtheo = x * 2 + offsetx; - int ytheo = y + offsety; - if (xtheo < 0) xtheo = 0; else if (xtheo >= w) xtheo = w - 1; - if (ytheo < 0) ytheo = 0; else if (ytheo >= h) ytheo = h - 1; - return rgb[3*(xtheo+ytheo*w)+z]; -} - -static int32_t GetRGB2(int32_t *rgb, unsigned int w, unsigned int h, unsigned int x, int offsetx, unsigned int y, int offsety, unsigned int z) -{ - int xtheo = x * 2 + 1 + offsetx; - int ytheo = y + offsety; - if (xtheo < 0) xtheo = 0; else if (xtheo >= w) xtheo = w - 1; - if (ytheo < 0) ytheo = 0; else if (ytheo >= h) ytheo = h - 1; - return rgb[3*(xtheo+ytheo*w)+z]; -} - -static void DoBoxBlur(uint8_t *yuv, int32_t *rgb, unsigned int width, unsigned int height, unsigned int boxw, unsigned int boxh) -{ - register int x, y; - int32_t r, g, b; - register int uneven = width % 2; - register int y0, y1, u0, u1, v0, v1; - int w = (width - uneven ) / 2; - float mul = 1.f / ((boxw*2) * (boxh*2)); - - for (y = 0; y < height; y++) - { - for (x = 0; x < w; x++) - { - r = GetRGB(rgb, width, height, x, +boxw, y, +boxh, 0) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 0) - GetRGB(rgb, width, height, x, -boxw, y, + boxh, 0) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 0); - g = GetRGB(rgb, width, height, x, +boxw, y, +boxh, 1) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 1) - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 1) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 1); - b = GetRGB(rgb, width, height, x, +boxw, y, +boxh, 2) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 2) - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 2) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 2); - r = (int32_t) (r * mul); - g = (int32_t) (g * mul); - b = (int32_t) (b * mul); - RGB2YUV (r, g, b, y0, u0, v0); - - r = GetRGB2(rgb, width, height, x, +boxw, y, +boxh, 0) + GetRGB2(rgb, width, height, x, -boxw, y, -boxh, 0) - GetRGB2(rgb, width, height, x, -boxw, y, +boxh, 0) - GetRGB2(rgb, width, height, x, +boxw, y, -boxh, 0); - g = GetRGB2(rgb, width, height, x, +boxw, y, +boxh, 1) + GetRGB2(rgb, width, height, x, -boxw, y, -boxh, 1) - GetRGB2(rgb, width, height, x, -boxw, y, +boxh, 1) - GetRGB2(rgb, width, height, x, +boxw, y, -boxh, 1); - b = GetRGB2(rgb, width, height, x, +boxw, y, +boxh, 2) + GetRGB2(rgb, width, height, x, -boxw, y, -boxh, 2) - GetRGB2(rgb, width, height, x, -boxw, y, +boxh, 2) - GetRGB2(rgb, width, height, x, +boxw, y, -boxh, 2); - r = (int32_t) (r * mul); - g = (int32_t) (g * mul); - b = (int32_t) (b * mul); - RGB2YUV (r, g, b, y1, u1, v1); - *yuv++ = y0; - *yuv++ = (u0+u1) >> 1; - *yuv++ = y1; - *yuv++ = (v0+v1) >> 1; - } - if (uneven) - { - r = GetRGB(rgb, width, height, x, +boxw, y, +boxh, 0) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 0) - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 0) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 0); - g = GetRGB(rgb, width, height, x, +boxw, y, +boxh, 1) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 1) - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 1) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 1); - b = GetRGB(rgb, width, height, x, +boxw, y, +boxh, 2) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 2) - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 2) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 2); - r = (int32_t) (r * mul); - g = (int32_t) (g * mul); - b = (int32_t) (b * mul); - RGB2YUV (r, g, b, y0, u0, v0); - *yuv++ = mul * y0; - *yuv++ = mul * u0; - } - } -} - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the image - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - short hori = mlt_properties_get_int(MLT_FRAME_PROPERTIES( this ), "hori" ); - short vert = mlt_properties_get_int(MLT_FRAME_PROPERTIES( this ), "vert" ); - - // Only process if we have no error and a valid colour space - if ( error == 0 && *format == mlt_image_yuv422 ) - { - double factor = mlt_properties_get_double( MLT_FRAME_PROPERTIES( this ), "boxblur" ); - if (factor != 0) { - int h = *height + 1; - int32_t *rgb = mlt_pool_alloc (3 * *width * h * sizeof(int32_t)); - PreCompute (*image, rgb, *width, h); - DoBoxBlur (*image, rgb, *width, h, (int) factor*hori, (int) factor*vert); - mlt_pool_release (rgb); - } - } - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Get the starting blur level - double blur = (double) mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "start" ); - short hori = mlt_properties_get_int(MLT_FILTER_PROPERTIES( this ), "hori" ); - short vert = mlt_properties_get_int(MLT_FILTER_PROPERTIES( this ), "vert" ); - - // If there is an end adjust gain to the range - if ( mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "end" ) != NULL ) - { - // Determine the time position of this frame in the transition duration - mlt_position in = mlt_filter_get_in( this ); - mlt_position out = mlt_filter_get_out( this ); - mlt_position time = mlt_frame_get_position( frame ); - double position = (double) ( time - in ) / ( out - in + 1.0 ); - double end = (double) mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "end" ); - blur += ( end - blur ) * position; - } - - // Push the frame filter - mlt_properties_set_double( MLT_FRAME_PROPERTIES( frame ), "boxblur", blur ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "hori", hori ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "vert", vert ); - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_boxblur_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "start", arg == NULL ? "10" : arg); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "hori", arg == NULL ? "1" : arg); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "vert", arg == NULL ? "1" : arg); - } - return this; -} - - - diff --git a/src/modules/kdenlive/filter_freeze.c b/src/modules/kdenlive/filter_freeze.c deleted file mode 100644 index ef85423..0000000 --- a/src/modules/kdenlive/filter_freeze.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * filter_freeze.c -- simple frame freezing filter - * Copyright (C) 2007 Jean-Baptiste Mardelle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the image - mlt_filter filter = mlt_frame_pop_service( this ); - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - - mlt_frame freeze_frame = NULL;; - int freeze_before = mlt_properties_get_int( properties, "freeze_before" ); - int freeze_after = mlt_properties_get_int( properties, "freeze_after" ); - mlt_position pos = mlt_properties_get_position( properties, "frame" ); - mlt_position currentpos = mlt_properties_get_position( properties, "_seek_frame" ); - - int do_freeze = 0; - if (freeze_before == 0 && freeze_after == 0) { - do_freeze = 1; - } else if (freeze_before != 0 && pos > currentpos) { - do_freeze = 1; - } else if (freeze_after != 0 && pos < currentpos) { - do_freeze = 1; - } - - if (do_freeze == 1) { - freeze_frame = mlt_properties_get_data( properties, "freeze_frame", NULL ); - - if( freeze_frame == NULL || mlt_properties_get_position( properties, "_frame" ) != pos ) - { - // freeze_frame has not been fetched yet, so fetch it and cache it. - mlt_producer producer = mlt_frame_get_original_producer(this); - mlt_producer_seek( producer, pos ); - - // Get the frame - mlt_service_get_frame( mlt_producer_service(producer), &freeze_frame, 0 ); - - mlt_properties props = MLT_FRAME_PROPERTIES( this ); - mlt_properties freeze_properties = MLT_FRAME_PROPERTIES( freeze_frame ); - mlt_properties_set_double( freeze_properties, "consumer_aspect_ratio", mlt_properties_get_double( props, "consumer_aspect_ratio" ) ); - mlt_properties_set( freeze_properties, "rescale.interp", mlt_properties_get( props, "rescale.interp" ) ); - mlt_properties_set_double( freeze_properties, "aspect_ratio", mlt_frame_get_aspect_ratio( this ) ); - mlt_properties_set_int( freeze_properties, "progressive", mlt_properties_get_int( props, "progressive" ) ); - - mlt_properties_set_data( properties, "freeze_frame", freeze_frame, 0, NULL, NULL ); - mlt_properties_set_position( properties, "_frame", pos ); - } - int error = mlt_frame_get_image( freeze_frame, image, format, width, height, 1 ); - return error; - } - - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - // Push the filter on to the stack - mlt_frame_push_service( frame, this ); - - // Determine the time position of this frame - mlt_properties_set_position( MLT_FILTER_PROPERTIES( this ), "_seek_frame", mlt_frame_get_position( frame ) - mlt_filter_get_in( this ) ); - - // Push the frame filter - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_freeze_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - // Set the frame which will be chosen for freeze - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "frame", "0" ); - - // If freeze_after = 1, only frames after the "frame" value will be frozen - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "freeze_after", "0" ); - - // If freeze_before = 1, only frames after the "frame" value will be frozen - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "freeze_before", "0" ); - } - return this; -} - - - diff --git a/src/modules/kdenlive/filter_wave.c b/src/modules/kdenlive/filter_wave.c deleted file mode 100644 index d01944f..0000000 --- a/src/modules/kdenlive/filter_wave.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * wave.c -- wave filter - * Copyright (C) ?-2007 Leny Grisel - * Copyright (C) 2007 Jean-Baptiste Mardelle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include -#include - -// this is a utility function used by DoWave below -static uint8_t getPoint(uint8_t *src, int w, int h, int x, int y, int z) -{ - if (x<0) x+=-((-x)%w)+w; else if (x>=w) x=x%w; - if (y<0) y+=-((-y)%h)+h; else if (y>=h) y=y%h; - return src[(x+y*w)*4+z]; -} - -// the main meat of the algorithm lies here -static void DoWave(uint8_t *src, int src_w, int src_h, uint8_t *dst, mlt_position position, int speed, int factor, int deformX, int deformY) -{ - register int x, y; - int decalY, decalX, z; - float amplitude, phase, pulsation; - register int uneven = src_w % 2; - int w = (src_w - uneven ) / 2; - amplitude = factor; - pulsation = 0.5 / factor; // smaller means bigger period - phase = position * pulsation * speed / 10; // smaller means longer - for (y=0;yprocess = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "start", arg == NULL ? "10" : arg); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "speed", arg == NULL ? "5" : arg); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "deformX", arg == NULL ? "1" : arg); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "deformY", arg == NULL ? "1" : arg); - } - return this; -} - - - diff --git a/src/modules/kdenlive/producer_framebuffer.c b/src/modules/kdenlive/producer_framebuffer.c deleted file mode 100644 index 10dc22f..0000000 --- a/src/modules/kdenlive/producer_framebuffer.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * producer_framebuffer.c -- create subspeed frames - * Copyright (C) 2007 Jean-Baptiste Mardelle - * Author: Jean-Baptiste Mardelle, based on the code of motion_est by Zachary Drew - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include -#include -#include -#include -#include -#include - -// Forward references. -static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ); - -/** Image stack(able) method -*/ - -static int framebuffer_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - // Get the filter object and properties - mlt_producer producer = mlt_frame_pop_service( this ); - mlt_frame first_frame = mlt_frame_pop_service( this ); - - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Frame properties objects - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( this ); - mlt_properties first_frame_properties = MLT_FRAME_PROPERTIES( first_frame ); - - *width = mlt_properties_get_int( frame_properties, "width" ); - *height = mlt_properties_get_int( frame_properties, "height" ); - - int size; - switch ( *format ) - { - case mlt_image_yuv420p: - size = *width * 3 * ( *height + 1 ) / 2; - break; - case mlt_image_rgb24: - size = *width * ( *height + 1 ) * 3; - break; - default: - *format = mlt_image_yuv422; - size = *width * ( *height + 1 ) * 2; - break; - } - - uint8_t *output = mlt_properties_get_data( producer_properties, "output_buffer", NULL ); - - if( output == NULL ) - { - output = mlt_pool_alloc( size ); - - // Let someone else clean up - mlt_properties_set_data( producer_properties, "output_buffer", output, size, mlt_pool_release, NULL ); - } - - uint8_t *first_image = mlt_properties_get_data( first_frame_properties, "image", NULL ); - - // which frames are buffered? - - int error = 0; - - if( first_image == NULL ) - { - mlt_properties props = MLT_FRAME_PROPERTIES( this ); - mlt_properties test_properties = MLT_FRAME_PROPERTIES( first_frame ); - mlt_properties_set_double( test_properties, "consumer_aspect_ratio", mlt_properties_get_double( props, "consumer_aspect_ratio" ) ); - mlt_properties_set( test_properties, "rescale.interp", mlt_properties_get( props, "rescale.interp" ) ); - - error = mlt_frame_get_image( first_frame, &first_image, format, width, height, writable ); - - if( error != 0 ) { - fprintf(stderr, "first_image == NULL get image died\n"); - return error; - } - } - - // Start with a base image - memcpy( output, first_image, size ); - - *image = output; - mlt_properties_set_data( frame_properties, "image", output, size, NULL, NULL ); - - // Make sure that no further scaling is done - mlt_properties_set( frame_properties, "rescale.interps", "none" ); - mlt_properties_set( frame_properties, "scale", "off" ); - - mlt_frame_close( first_frame ); - - return 0; -} - -static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ) -{ - // Construct a new frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( this ) ); - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - if( frame != NULL ) - { - mlt_frame first_frame = mlt_properties_get_data( properties, "first_frame", NULL ); - - mlt_position first_position = (first_frame != NULL) ? mlt_frame_get_position( first_frame ) : -1; - - // Get the real producer - mlt_producer real_producer = mlt_properties_get_data( properties, "producer", NULL ); - - // get properties - int strobe = mlt_properties_get_int( properties, "strobe"); - int freeze = mlt_properties_get_int( properties, "freeze"); - int freeze_after = mlt_properties_get_int( properties, "freeze_after"); - int freeze_before = mlt_properties_get_int( properties, "freeze_before"); - - mlt_position need_first; - - if (!freeze || freeze_after || freeze_before) { - double prod_speed = mlt_properties_get_double( properties, "_speed"); - double actual_position = prod_speed * (double) mlt_producer_position( this ); - - if (mlt_properties_get_int( properties, "reverse")) actual_position = mlt_producer_get_playtime(this) - actual_position; - - if (strobe < 2) - { - need_first = floor( actual_position ); - } - else - { - // Strobe effect wanted, calculate frame position - need_first = floor( actual_position ); - need_first -= need_first%strobe; - } - if (freeze) - { - if (freeze_after && need_first > freeze) need_first = freeze; - else if (freeze_before && need_first < freeze) need_first = freeze; - } - } - else need_first = freeze; - - if( need_first != first_position ) - { - mlt_frame_close( first_frame ); - first_position = -1; - first_frame = NULL; - } - - if( first_frame == NULL ) - { - // Seek the producer to the correct place - mlt_producer_seek( real_producer, need_first ); - - // Get the frame - mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &first_frame, index ); - } - - // Make sure things are in their place - mlt_properties_set_data( properties, "first_frame", first_frame, 0, NULL, NULL ); - - // Stack the producer and producer's get image - mlt_frame_push_service( *frame, first_frame ); - mlt_properties_inc_ref( MLT_FRAME_PROPERTIES( first_frame ) ); - - mlt_frame_push_service( *frame, this ); - mlt_frame_push_service( *frame, framebuffer_get_image ); - - - // Give the returned frame temporal identity - mlt_frame_set_position( *frame, mlt_producer_position( this ) ); - } - - return 0; -} - - -mlt_producer producer_framebuffer_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - if ( !arg ) return NULL; - mlt_producer this = NULL; - this = calloc( 1, sizeof( struct mlt_producer_s ) ); - mlt_producer_init( this, NULL ); - - // Wrap fezzik - mlt_producer real_producer; - - // Check if a speed was specified. - /** - - * Speed must be appended to the filename with '?'. To play your video at 50%: - inigo framebuffer:my_video.mpg?0.5 - - * Stroboscope effect can be obtained by adding a stobe=x parameter, where - x is the number of frames that will be ignored. - - * You can play the movie backwards by adding reverse=1 - - * You can freeze the clip at a determined position by adding freeze=frame_pos - add freeze_after=1 to freeze only paste position or freeze_before to freeze before it - - **/ - - double speed = 0.0; - char *props = strdup( arg ); - char *ptr = strrchr( props, '?' ); - - if ( ptr ) - { - speed = atof( ptr + 1 ); - if ( speed != 0.0 ) - // If speed was valid, then strip it and the delimiter. - // Otherwise, an invalid speed probably means this '?' was not a delimiter. - *ptr = '\0'; - } - - real_producer = mlt_factory_producer( profile, "fezzik", props ); - free( props ); - - if (speed == 0.0) speed = 1.0; - - if ( this != NULL && real_producer != NULL) - { - // Get the properties of this producer - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Fezzik normalised it for us already - mlt_properties_set_int( properties, "fezzik_normalised", 1); - mlt_properties_set( properties, "resource", arg); - - // Store the producer and fitler - mlt_properties_set_data( properties, "producer", real_producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); - - // Grab some stuff from the real_producer - mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( real_producer ), "length, width,height" ); - - if ( speed < 0 ) - { - speed = -speed; - mlt_properties_set_int( properties, "reverse", 1 ); - } - - if ( speed != 1.0 ) - { - double real_length = ( (double) mlt_producer_get_length( real_producer ) ) / speed; - mlt_properties_set_position( properties, "length", real_length ); - } - mlt_properties_set_position( properties, "out", mlt_producer_get_length( this ) - 1 ); - - // Since we control the seeking, prevent it from seeking on its own - mlt_producer_set_speed( real_producer, 0 ); - mlt_producer_set_speed( this, speed ); - - // Override the get_frame method - this->get_frame = producer_get_frame; - } - else - { - if ( this ) - mlt_producer_close( this ); - if ( real_producer ) - mlt_producer_close( real_producer ); - - this = NULL; - } - return this; -} diff --git a/src/modules/kino/Makefile b/src/modules/kino/Makefile deleted file mode 100644 index 32cdeaa..0000000 --- a/src/modules/kino/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -include ../../../config.mak -include config.mak - -TARGET = ../libmltkino.so - -OBJS = factory.o producer_kino.o -CPPOBJS = kino_wrapper.o avi.o error.o filehandler.o riff.o - -CFLAGS += -I../../ -CXXFLAGS += $(CFLAGS) -Wno-deprecated - -LDFLAGS += -L../../framework -lmlt -LDFLAGS += -lstdc++ - -ifdef HAVE_LIBQUICKTIME -CFLAGS += `pkg-config --cflags libquicktime` -CXXFLAGS += `pkg-config --cflags libquicktime` -LDFLAGS += `pkg-config --libs libquicktime` -endif - -ifdef HAVE_LIBDV -CFLAGS += `pkg-config --cflags libdv` -LDFLAGS += `pkg-config --libs libdv` -endif - - -SRCS := $(OBJS:.o=.c) $(CPPOBJS:.o=.cc) - -all: $(TARGET) - -$(TARGET): $(OBJS) $(CPPOBJS) - $(CC) -shared -o $@ $(OBJS) $(CPPOBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend config.h config.mak - -clean: - rm -f $(OBJS) $(TARGET) $(CPPOBJS) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/kino/avi.cc b/src/modules/kino/avi.cc deleted file mode 100644 index ced8993..0000000 --- a/src/modules/kino/avi.cc +++ /dev/null @@ -1,1707 +0,0 @@ -/* -* avi.cc library for AVI file format i/o -* Copyright (C) 2000 - 2002 Arne Schirmacher -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "config.h" - -// C++ includes - -#include -#include -#include - -using std::cout; -using std::hex; -using std::dec; -using std::setw; -using std::setfill; -using std::endl; - -// C includes - -#include -#include -#include -#include -#include - -// local includes - -#include "error.h" -#include "riff.h" -#include "avi.h" - -#define PADDING_SIZE (512) -#define PADDING_1GB (0x40000000) -#define IX00_INDEX_SIZE (4028) - -#define AVIF_HASINDEX 0x00000010 -#define AVIF_MUSTUSEINDEX 0x00000020 -#define AVIF_TRUSTCKTYPE 0x00000800 -#define AVIF_ISINTERLEAVED 0x00000100 -#define AVIF_WASCAPTUREFILE 0x00010000 -#define AVIF_COPYRIGHTED 0x00020000 - - -//static char g_zeroes[ PADDING_SIZE ]; - -/** The constructor - - \todo mainHdr not initialized - \todo add checking for NULL pointers - -*/ - -AVIFile::AVIFile() : RIFFFile(), - idx1( NULL ), file_list( -1 ), riff_list( -1 ), - hdrl_list( -1 ), avih_chunk( -1 ), movi_list( -1 ), junk_chunk( -1 ), idx1_chunk( -1 ), - index_type( -1 ), current_ix00( -1 ), odml_list( -1 ), dmlh_chunk( -1 ), isUpdateIdx1( true ) -{ - // cerr << "0x" << hex << (long)this << dec << " AVIFile::AVIFile() : RIFFFile(), ..." << endl; - - for ( int i = 0; i < 2; ++i ) - { - indx[ i ] = new AVISuperIndex; - memset( indx[ i ], 0, sizeof( AVISuperIndex ) ); - ix[ i ] = new AVIStdIndex; - memset( ix[ i ], 0, sizeof( AVIStdIndex ) ); - indx_chunk[ i ] = -1; - ix_chunk[ i ] = -1; - strl_list[ i ] = -1; - strh_chunk[ i ] = -1; - strf_chunk[ i ] = -1; - } - idx1 = new AVISimpleIndex; - memset( idx1, 0, sizeof( AVISimpleIndex ) ); -} - - -/** The copy constructor - - \todo add checking for NULL pointers - -*/ - -AVIFile::AVIFile( const AVIFile& avi ) : RIFFFile( avi ) -{ - // cerr << "0x" << hex << (long)this << dec << " 0x" << hex << (long)&avi << dec << " AVIFile::AVIFile(const AVIFile& avi) : RIFFFile(avi)" << endl; - - mainHdr = avi.mainHdr; - idx1 = new AVISimpleIndex; - *idx1 = *avi.idx1; - file_list = avi.file_list; - riff_list = avi.riff_list; - hdrl_list = avi.hdrl_list; - avih_chunk = avi.avih_chunk; - movi_list = avi.movi_list; - junk_chunk = avi.junk_chunk; - idx1_chunk = avi.idx1_chunk; - - for ( int i = 0; i < 2; ++i ) - { - indx[ i ] = new AVISuperIndex; - *indx[ i ] = *avi.indx[ i ]; - ix[ i ] = new AVIStdIndex; - *ix[ i ] = *avi.ix[ i ]; - indx_chunk[ i ] = avi.indx_chunk[ i ]; - ix_chunk[ i ] = avi.ix_chunk[ i ]; - strl_list[ i ] = avi.strl_list[ i ]; - strh_chunk[ i ] = avi.strh_chunk[ i ]; - strf_chunk[ i ] = avi.strf_chunk[ i ]; - } - - index_type = avi.index_type; - current_ix00 = avi.current_ix00; - - for ( int i = 0; i < 62; ++i ) - dmlh[ i ] = avi.dmlh[ i ]; - - isUpdateIdx1 = avi.isUpdateIdx1; - -} - - -/** The assignment operator - -*/ - -AVIFile& AVIFile::operator=( const AVIFile& avi ) -{ - // cerr << "0x" << hex << (long)this << dec << " 0x" << hex << (long)&avi << dec << " AVIFile& AVIFile::operator=(const AVIFile& avi)" << endl; - - if ( this != &avi ) - { - RIFFFile::operator=( avi ); - mainHdr = avi.mainHdr; - *idx1 = *avi.idx1; - file_list = avi.file_list; - riff_list = avi.riff_list; - hdrl_list = avi.hdrl_list; - avih_chunk = avi.avih_chunk; - movi_list = avi.movi_list; - junk_chunk = avi.junk_chunk; - idx1_chunk = avi.idx1_chunk; - - for ( int i = 0; i < 2; ++i ) - { - *indx[ i ] = *avi.indx[ i ]; - *ix[ i ] = *avi.ix[ i ]; - indx_chunk[ i ] = avi.indx_chunk[ i ]; - ix_chunk[ i ] = avi.ix_chunk[ i ]; - strl_list[ i ] = avi.strl_list[ i ]; - strh_chunk[ i ] = avi.strh_chunk[ i ]; - strf_chunk[ i ] = avi.strf_chunk[ i ]; - } - - index_type = avi.index_type; - current_ix00 = avi.current_ix00; - - for ( int i = 0; i < 62; ++i ) - dmlh[ i ] = avi.dmlh[ i ]; - - isUpdateIdx1 = avi.isUpdateIdx1; - } - return *this; -} - - -/** The destructor - -*/ - -AVIFile::~AVIFile() -{ - // cerr << "0x" << hex << (long)this << dec << " AVIFile::~AVIFile()" << endl; - - for ( int i = 0; i < 2; ++i ) - { - delete ix[ i ]; - delete indx[ i ]; - } - delete idx1; -} - -/** Initialize the AVI structure to its initial state, either for PAL or NTSC format - - Initialize the AVIFile attributes: mainHdr, indx, ix00, idx1 - - \todo consolidate AVIFile::Init, AVI1File::Init, AVI2File::Init. They are somewhat redundant. - \param format pass AVI_PAL or AVI_NTSC - \param sampleFrequency the sample frequency of the audio content - \param indexType pass AVI_SMALL_INDEX or AVI_LARGE_INDEX - -*/ - -void AVIFile::Init( int format, int sampleFrequency, int indexType ) -{ - int i, j; - - assert( ( format == AVI_PAL ) || ( format == AVI_NTSC ) ); - - index_type = indexType; - - switch ( format ) - { - case AVI_PAL: - mainHdr.dwMicroSecPerFrame = 40000; - mainHdr.dwSuggestedBufferSize = 144008; - break; - - case AVI_NTSC: - mainHdr.dwMicroSecPerFrame = 33366; - mainHdr.dwSuggestedBufferSize = 120008; - break; - - default: /* no default allowed */ - assert( 0 ); - break; - } - - /* Initialize the 'avih' chunk */ - - mainHdr.dwMaxBytesPerSec = 3600000 + sampleFrequency * 4; - mainHdr.dwPaddingGranularity = PADDING_SIZE; - mainHdr.dwFlags = AVIF_TRUSTCKTYPE; - if ( indexType & AVI_SMALL_INDEX ) - mainHdr.dwFlags |= AVIF_HASINDEX; - mainHdr.dwTotalFrames = 0; - mainHdr.dwInitialFrames = 0; - mainHdr.dwStreams = 1; - mainHdr.dwWidth = 0; - mainHdr.dwHeight = 0; - mainHdr.dwReserved[ 0 ] = 0; - mainHdr.dwReserved[ 1 ] = 0; - mainHdr.dwReserved[ 2 ] = 0; - mainHdr.dwReserved[ 3 ] = 0; - - /* Initialize the 'idx1' chunk */ - - for ( int i = 0; i < 8000; ++i ) - { - idx1->aIndex[ i ].dwChunkId = 0; - idx1->aIndex[ i ].dwFlags = 0; - idx1->aIndex[ i ].dwOffset = 0; - idx1->aIndex[ i ].dwSize = 0; - } - idx1->nEntriesInUse = 0; - - /* Initialize the 'indx' chunk */ - - for ( i = 0; i < 2; ++i ) - { - indx[ i ] ->wLongsPerEntry = 4; - indx[ i ] ->bIndexSubType = 0; - indx[ i ] ->bIndexType = KINO_AVI_INDEX_OF_INDEXES; - indx[ i ] ->nEntriesInUse = 0; - indx[ i ] ->dwReserved[ 0 ] = 0; - indx[ i ] ->dwReserved[ 1 ] = 0; - indx[ i ] ->dwReserved[ 2 ] = 0; - for ( j = 0; j < 2014; ++j ) - { - indx[ i ] ->aIndex[ j ].qwOffset = 0; - indx[ i ] ->aIndex[ j ].dwSize = 0; - indx[ i ] ->aIndex[ j ].dwDuration = 0; - } - } - - /* The ix00 and ix01 chunk will be added dynamically in avi_write_frame - as needed */ - - /* Initialize the 'dmlh' chunk. I have no clue what this means - though */ - - for ( i = 0; i < 62; ++i ) - dmlh[ i ] = 0; - //dmlh[0] = -1; /* frame count + 1? */ - -} - - -/** Find position and size of a given frame in the file - - Depending on which index is available, search one of them to - find position and frame size - - \todo the size parameter is redundant. All frames have the same size, which is also in the mainHdr. - \todo all index related operations should be isolated - \param offset the file offset to the start of the frame - \param size the size of the frame - \param frameNum the number of the frame we wish to find - \return 0 if the frame could be found, -1 otherwise -*/ - -int AVIFile::GetDVFrameInfo( off_t &offset, int &size, int frameNum ) -{ - switch ( index_type ) - { - case AVI_LARGE_INDEX: - - /* find relevant index in indx0 */ - - int i; - - for ( i = 0; frameNum >= indx[ 0 ] ->aIndex[ i ].dwDuration; frameNum -= indx[ 0 ] ->aIndex[ i ].dwDuration, ++i ) - ; - - if ( i != current_ix00 ) - { - fail_if( lseek( fd, indx[ 0 ] ->aIndex[ i ].qwOffset + RIFF_HEADERSIZE, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, ix[ 0 ], indx[ 0 ] ->aIndex[ i ].dwSize - RIFF_HEADERSIZE ) ); - current_ix00 = i; - } - - if ( frameNum < ix[ 0 ] ->nEntriesInUse ) - { - offset = ix[ 0 ] ->qwBaseOffset + ix[ 0 ] ->aIndex[ frameNum ].dwOffset; - size = ix[ 0 ] ->aIndex[ frameNum ].dwSize; - return 0; - } - else - return -1; - break; - - case AVI_SMALL_INDEX: - int index = -1; - int frameNumIndex = 0; - for ( int i = 0; i < idx1->nEntriesInUse; ++i ) - { - FOURCC chunkID1 = make_fourcc( "00dc" ); - FOURCC chunkID2 = make_fourcc( "00db" ); - if ( idx1->aIndex[ i ].dwChunkId == chunkID1 || - idx1->aIndex[ i ].dwChunkId == chunkID2 ) - { - if ( frameNumIndex == frameNum ) - { - index = i; - break; - } - ++frameNumIndex; - } - } - if ( index != -1 ) - { - // compatibility check for broken dvgrab dv2 format - if ( idx1->aIndex[ 0 ].dwOffset > GetDirectoryEntry( movi_list ).offset ) - { - offset = idx1->aIndex[ index ].dwOffset + RIFF_HEADERSIZE; - } - else - { - // new, correct dv2 format - offset = idx1->aIndex[ index ].dwOffset + RIFF_HEADERSIZE + GetDirectoryEntry( movi_list ).offset; - } - size = idx1->aIndex[ index ].dwSize; - return 0; - } - else - return -1; - break; - } - return -1; -} - -/** Find position and size of a given frame in the file - - Depending on which index is available, search one of them to - find position and frame size - - \todo the size parameter is redundant. All frames have the same size, which is also in the mainHdr. - \todo all index related operations should be isolated - \param offset the file offset to the start of the frame - \param size the size of the frame - \param frameNum the number of the frame we wish to find - \param chunkID the ID of the type of chunk we want - \return 0 if the frame could be found, -1 otherwise -*/ - -int AVIFile::GetFrameInfo( off_t &offset, int &size, int frameNum, FOURCC chunkID ) -{ - if ( index_type & AVI_LARGE_INDEX ) - { - int i; - - for ( i = 0; frameNum >= indx[ 0 ] ->aIndex[ i ].dwDuration; frameNum -= indx[ 0 ] ->aIndex[ i ].dwDuration, ++i ) - ; - - if ( i != current_ix00 ) - { - fail_if( lseek( fd, indx[ 0 ] ->aIndex[ i ].qwOffset + RIFF_HEADERSIZE, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, ix[ 0 ], indx[ 0 ] ->aIndex[ i ].dwSize - RIFF_HEADERSIZE ) ); - current_ix00 = i; - } - - if ( frameNum < ix[ 0 ] ->nEntriesInUse ) - { - if ( ( FOURCC ) ix[ 0 ] ->dwChunkId == chunkID ) - { - offset = ix[ 0 ] ->qwBaseOffset + ix[ 0 ] ->aIndex[ frameNum ].dwOffset; - size = ix[ 0 ] ->aIndex[ frameNum ].dwSize; - return 0; - } - } - } - if ( index_type & AVI_SMALL_INDEX ) - { - int index = -1; - int frameNumIndex = 0; - for ( int i = 0; i < idx1->nEntriesInUse; ++i ) - { - if ( idx1->aIndex[ i ].dwChunkId == chunkID ) - { - if ( frameNumIndex == frameNum ) - { - index = i; - break; - } - ++frameNumIndex; - } - } - if ( index != -1 ) - { - // compatibility check for broken dvgrab dv2 format - if ( idx1->aIndex[ 0 ].dwOffset > GetDirectoryEntry( movi_list ).offset ) - { - offset = idx1->aIndex[ index ].dwOffset + RIFF_HEADERSIZE; - } - else - { - // new, correct dv2 format - offset = idx1->aIndex[ index ].dwOffset + RIFF_HEADERSIZE + GetDirectoryEntry( movi_list ).offset; - } - size = idx1->aIndex[ index ].dwSize; - return 0; - } - } - return -1; -} - -/** Read in a frame - - \todo we actually don't need the frame here, we could use just a void pointer - \param frame a reference to the frame object that will receive the frame data - \param frameNum the frame number to read - \return 0 if the frame could be read, -1 otherwise -*/ - -int AVIFile::GetDVFrame( uint8_t *data, int frameNum ) -{ - off_t offset; - int size; - - if ( GetDVFrameInfo( offset, size, frameNum ) != 0 || size < 0 ) - return -1; - pthread_mutex_lock( &file_mutex ); - fail_if( lseek( fd, offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, data, size ) ); - pthread_mutex_unlock( &file_mutex ); - - return 0; -} - -/** Read in a frame - - \param data a pointer to the audio buffer - \param frameNum the frame number to read - \param chunkID the ID of the type of chunk we want - \return the size the of the frame data, 0 if could not be read -*/ - -int AVIFile::getFrame( void *data, int frameNum, FOURCC chunkID ) -{ - off_t offset; - int size; - - if ( GetFrameInfo( offset, size, frameNum, chunkID ) != 0 ) - return 0; - fail_if( lseek( fd, offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, data, size ) ); - - return size; -} - -int AVIFile::GetTotalFrames() const -{ - return mainHdr.dwTotalFrames; -} - - -/** prints out a directory entry in text form - - Every subclass of RIFFFile is supposed to override this function - and to implement it for the entry types it knows about. For all - other entry types it should call its parent::PrintDirectoryData. - - \todo use 64 bit routines - \param entry the entry to print -*/ - -void AVIFile::PrintDirectoryEntryData( const RIFFDirEntry &entry ) const -{ - static FOURCC lastStreamType = make_fourcc( " " ); - - if ( entry.type == make_fourcc( "avih" ) ) - { - - int i; - MainAVIHeader main_avi_header; - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &main_avi_header, sizeof( MainAVIHeader ) ) ); - - cout << " dwMicroSecPerFrame: " << ( int ) main_avi_header.dwMicroSecPerFrame << endl - << " dwMaxBytesPerSec: " << ( int ) main_avi_header.dwMaxBytesPerSec << endl - << " dwPaddingGranularity: " << ( int ) main_avi_header.dwPaddingGranularity << endl - << " dwFlags: " << ( int ) main_avi_header.dwFlags << endl - << " dwTotalFrames: " << ( int ) main_avi_header.dwTotalFrames << endl - << " dwInitialFrames: " << ( int ) main_avi_header.dwInitialFrames << endl - << " dwStreams: " << ( int ) main_avi_header.dwStreams << endl - << " dwSuggestedBufferSize: " << ( int ) main_avi_header.dwSuggestedBufferSize << endl - << " dwWidth: " << ( int ) main_avi_header.dwWidth << endl - << " dwHeight: " << ( int ) main_avi_header.dwHeight << endl; - for ( i = 0; i < 4; ++i ) - cout << " dwReserved[" << i << "]: " << ( int ) main_avi_header.dwReserved[ i ] << endl; - - } - else if ( entry.type == make_fourcc( "strh" ) ) - { - - AVIStreamHeader avi_stream_header; - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &avi_stream_header, sizeof( AVIStreamHeader ) ) ); - - lastStreamType = avi_stream_header.fccType; - - cout << " fccType: '" - << ((char *)&avi_stream_header.fccType)[0] - << ((char *)&avi_stream_header.fccType)[1] - << ((char *)&avi_stream_header.fccType)[2] - << ((char *)&avi_stream_header.fccType)[3] - << '\'' << endl - << " fccHandler: '" - << ((char *)&avi_stream_header.fccHandler)[0] - << ((char *)&avi_stream_header.fccHandler)[1] - << ((char *)&avi_stream_header.fccHandler)[2] - << ((char *)&avi_stream_header.fccHandler)[3] - << '\'' << endl - << " dwFlags: " << ( int ) avi_stream_header.dwFlags << endl - << " wPriority: " << ( int ) avi_stream_header.wPriority << endl - << " wLanguage: " << ( int ) avi_stream_header.wLanguage << endl - << " dwInitialFrames: " << ( int ) avi_stream_header.dwInitialFrames << endl - << " dwScale: " << ( int ) avi_stream_header.dwScale << endl - << " dwRate: " << ( int ) avi_stream_header.dwRate << endl - << " dwLength: " << ( int ) avi_stream_header.dwLength << endl - << " dwQuality: " << ( int ) avi_stream_header.dwQuality << endl - << " dwSampleSize: " << ( int ) avi_stream_header.dwSampleSize << endl; - - } - else if ( entry.type == make_fourcc( "indx" ) ) - { - - int i; - AVISuperIndex avi_super_index; - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &avi_super_index, sizeof( AVISuperIndex ) ) ); - - cout << " wLongsPerEntry: " << ( int ) avi_super_index.wLongsPerEntry - << endl - << " bIndexSubType: " << ( int ) avi_super_index.bIndexSubType << endl - << " bIndexType: " << ( int ) avi_super_index.bIndexType << endl - << " nEntriesInUse: " << ( int ) avi_super_index.nEntriesInUse << endl - << " dwChunkId: '" - << ((char *)&avi_super_index.dwChunkId)[0] - << ((char *)&avi_super_index.dwChunkId)[1] - << ((char *)&avi_super_index.dwChunkId)[2] - << ((char *)&avi_super_index.dwChunkId)[3] - << '\'' << endl - << " dwReserved[0]: " << ( int ) avi_super_index.dwReserved[ 0 ] << endl - << " dwReserved[1]: " << ( int ) avi_super_index.dwReserved[ 1 ] << endl - << " dwReserved[2]: " << ( int ) avi_super_index.dwReserved[ 2 ] << endl; - for ( i = 0; i < avi_super_index.nEntriesInUse; ++i ) - { - cout << ' ' << setw( 4 ) << setfill( ' ' ) << i - << ": qwOffset : 0x" << setw( 12 ) << setfill( '0' ) << hex << avi_super_index.aIndex[ i ].qwOffset << endl - << " dwSize : 0x" << setw( 8 ) << avi_super_index.aIndex[ i ].dwSize << endl - << " dwDuration : " << dec << avi_super_index.aIndex[ i ].dwDuration << endl; - } - } - else if ( entry.type == make_fourcc( "strf" ) ) - { - if ( lastStreamType == make_fourcc( "auds" ) ) - { - WAVEFORMATEX waveformatex; - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &waveformatex, sizeof( WAVEFORMATEX ) ) ); - cout << " waveformatex.wFormatTag : " << waveformatex.wFormatTag << endl; - cout << " waveformatex.nChannels : " << waveformatex.nChannels << endl; - cout << " waveformatex.nSamplesPerSec : " << waveformatex.nSamplesPerSec << endl; - cout << " waveformatex.nAvgBytesPerSec: " << waveformatex.nAvgBytesPerSec << endl; - cout << " waveformatex.nBlockAlign : " << waveformatex.nBlockAlign << endl; - cout << " waveformatex.wBitsPerSample : " << waveformatex.wBitsPerSample << endl; - cout << " waveformatex.cbSize : " << waveformatex.cbSize << endl; - } - else if ( lastStreamType == make_fourcc( "vids" ) ) - { - BITMAPINFOHEADER bitmapinfo; - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &bitmapinfo, sizeof( BITMAPINFOHEADER ) ) ); - cout << " bitmapinfo.biSize : " << bitmapinfo.biSize << endl; - cout << " bitmapinfo.biWidth : " << bitmapinfo.biWidth << endl; - cout << " bitmapinfo.biHeight : " << bitmapinfo.biHeight << endl; - cout << " bitmapinfo.biPlanes : " << bitmapinfo.biPlanes << endl; - cout << " bitmapinfo.biBitCount : " << bitmapinfo.biBitCount << endl; - cout << " bitmapinfo.biCompression : " << bitmapinfo.biCompression << endl; - cout << " bitmapinfo.biSizeImage : " << bitmapinfo.biSizeImage << endl; - cout << " bitmapinfo.biXPelsPerMeter: " << bitmapinfo.biXPelsPerMeter << endl; - cout << " bitmapinfo.biYPelsPerMeter: " << bitmapinfo.biYPelsPerMeter << endl; - cout << " bitmapinfo.biClrUsed : " << bitmapinfo.biClrUsed << endl; - cout << " bitmapinfo.biClrImportant : " << bitmapinfo.biClrImportant << endl; - } - else if ( lastStreamType == make_fourcc( "iavs" ) ) - { - DVINFO dvinfo; - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &dvinfo, sizeof( DVINFO ) ) ); - cout << " dvinfo.dwDVAAuxSrc : 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVAAuxSrc << endl; - cout << " dvinfo.dwDVAAuxCtl : 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVAAuxCtl << endl; - cout << " dvinfo.dwDVAAuxSrc1: 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVAAuxSrc1 << endl; - cout << " dvinfo.dwDVAAuxCtl1: 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVAAuxCtl1 << endl; - cout << " dvinfo.dwDVVAuxSrc : 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVVAuxSrc << endl; - cout << " dvinfo.dwDVVAuxCtl : 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVVAuxCtl << endl; - } - } - - /* This is the Standard Index. It is an array of offsets and - sizes relative to some start offset. */ - - else if ( ( entry.type == make_fourcc( "ix00" ) ) || ( entry.type == make_fourcc( "ix01" ) ) ) - { - - int i; - AVIStdIndex avi_std_index; - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &avi_std_index, sizeof( AVIStdIndex ) ) ); - - cout << " wLongsPerEntry: " << ( int ) avi_std_index.wLongsPerEntry - << endl - << " bIndexSubType: " << ( int ) avi_std_index.bIndexSubType << endl - << " bIndexType: " << ( int ) avi_std_index.bIndexType << endl - << " nEntriesInUse: " << ( int ) avi_std_index.nEntriesInUse << endl - << " dwChunkId: '" - << ((char *)&avi_std_index.dwChunkId)[0] - << ((char *)&avi_std_index.dwChunkId)[1] - << ((char *)&avi_std_index.dwChunkId)[2] - << ((char *)&avi_std_index.dwChunkId)[3] - << '\'' << endl - << " qwBaseOffset: 0x" << setw( 12 ) << hex << avi_std_index.qwBaseOffset << endl - << " dwReserved: " << dec << ( int ) avi_std_index.dwReserved << endl; - for ( i = 0; i < avi_std_index.nEntriesInUse; ++i ) - { - cout << ' ' << setw( 4 ) << setfill( ' ' ) << i - << ": dwOffset : 0x" << setw( 8 ) << setfill( '0' ) << hex << avi_std_index.aIndex[ i ].dwOffset - << " (0x" << setw( 12 ) << avi_std_index.qwBaseOffset + avi_std_index.aIndex[ i ].dwOffset << ')' << endl - << " dwSize : 0x" << setw( 8 ) << avi_std_index.aIndex[ i ].dwSize << dec << endl; - } - - } - else if ( entry.type == make_fourcc( "idx1" ) ) - { - - int i; - int numEntries = entry.length / sizeof( int ) / 4; - DWORD *idx1 = new DWORD[ numEntries * 4 ]; - // FOURCC movi_list = FindDirectoryEntry(make_fourcc("movi")); - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, idx1, entry.length ) ); - - for ( i = 0; i < numEntries; ++i ) - { - - cout << ' ' << setw( 4 ) << setfill( ' ' ) << i << setfill( '0' ) << ": dwChunkId : '" - << ((char *)&idx1[ i * 4 + 0 ])[0] - << ((char *)&idx1[ i * 4 + 0 ])[1] - << ((char *)&idx1[ i * 4 + 0 ])[2] - << ((char *)&idx1[ i * 4 + 0 ])[3] - << '\'' << endl - << " dwType : 0x" << setw( 8 ) << hex << idx1[ i * 4 + 1 ] << endl - << " dwOffset : 0x" << setw( 8 ) << idx1[ i * 4 + 2 ] << endl - // << " (0x" << setw(8) << idx1[i * 4 + 2] + GetDirectoryEntry(movi_list).offset << ')' << endl - << " dwSize : 0x" << setw( 8 ) << idx1[ i * 4 + 3 ] << dec << endl; - } - - delete[] idx1; - } - else if ( entry.type == make_fourcc( "dmlh" ) ) - { - int i; - int numEntries = entry.length / sizeof( int ); - DWORD *dmlh = new DWORD[ numEntries ]; - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, dmlh, entry.length ) ); - - for ( i = 0; i < numEntries; ++i ) - { - cout << ' ' << setw( 4 ) << setfill( ' ' ) << i << setfill( '0' ) << ": " - << " dwTotalFrames: 0x" << setw( 8 ) << hex << dmlh[ i ] - << " (" << dec << dmlh[ i ] << ")" << endl; - } - delete[] dmlh; - } -} - - -/** If this is not a movi list, read its contents - -*/ - -void AVIFile::ParseList( int parent ) -{ - FOURCC type; - FOURCC name; - DWORD length; - int list; - off_t pos; - off_t listEnd; - - /* Read in the chunk header (type and length). */ - fail_neg( read( fd, &type, sizeof( type ) ) ); - fail_neg( read( fd, &length, sizeof( length ) ) ); - if ( length & 1 ) - length++; - - /* The contents of the list starts here. Obtain its offset. The list - name (4 bytes) is already part of the contents). */ - - pos = lseek( fd, 0, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - fail_neg( read( fd, &name, sizeof( name ) ) ); - - /* if we encounter a movi list, do not read it. It takes too much time - and we don't need it anyway. */ - - if ( name != make_fourcc( "movi" ) ) - { - // if (1) { - - /* Add an entry for this list. */ - list = AddDirectoryEntry( type, name, sizeof( name ), parent ); - - /* Read in any chunks contained in this list. This list is the - parent for all chunks it contains. */ - - listEnd = pos + length; - while ( pos < listEnd ) - { - ParseChunk( list ); - pos = lseek( fd, 0, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - } - } - else - { - /* Add an entry for this list. */ - - movi_list = AddDirectoryEntry( type, name, length, parent ); - - pos = lseek( fd, length - 4, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - } -} - - -void AVIFile::ParseRIFF() -{ - RIFFFile::ParseRIFF(); - - avih_chunk = FindDirectoryEntry( make_fourcc( "avih" ) ); - if ( avih_chunk != -1 ) - ReadChunk( avih_chunk, ( void* ) & mainHdr, sizeof( MainAVIHeader ) ); -} - - -void AVIFile::ReadIndex() -{ - indx_chunk[ 0 ] = FindDirectoryEntry( make_fourcc( "indx" ) ); - if ( indx_chunk[ 0 ] != -1 ) - { - ReadChunk( indx_chunk[ 0 ], ( void* ) indx[ 0 ], sizeof( AVISuperIndex ) ); - index_type = AVI_LARGE_INDEX; - - /* recalc number of frames from each index */ - mainHdr.dwTotalFrames = 0; - for ( int i = 0; - i < indx[ 0 ] ->nEntriesInUse; - mainHdr.dwTotalFrames += indx[ 0 ] ->aIndex[ i++ ].dwDuration ) - ; - return ; - } - idx1_chunk = FindDirectoryEntry( make_fourcc( "idx1" ) ); - if ( idx1_chunk != -1 ) - { - ReadChunk( idx1_chunk, ( void* ) idx1, sizeof( AVISuperIndex ) ); - idx1->nEntriesInUse = GetDirectoryEntry( idx1_chunk ).length / 16; - index_type = AVI_SMALL_INDEX; - - /* recalc number of frames from the simple index */ - int frameNumIndex = 0; - FOURCC chunkID1 = make_fourcc( "00dc" ); - FOURCC chunkID2 = make_fourcc( "00db" ); - for ( int i = 0; i < idx1->nEntriesInUse; ++i ) - { - if ( idx1->aIndex[ i ].dwChunkId == chunkID1 || - idx1->aIndex[ i ].dwChunkId == chunkID2 ) - { - ++frameNumIndex; - } - } - mainHdr.dwTotalFrames = frameNumIndex; - return ; - } -} - - -void AVIFile::FlushIndx( int stream ) -{ - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - int i; - - /* Write out the previous index. When this function is - entered for the first time, there is no index to - write. Note: this may be an expensive operation - because of a time consuming seek to the former file - position. */ - - if ( ix_chunk[ stream ] != -1 ) - WriteChunk( ix_chunk[ stream ], ix[ stream ] ); - - /* make a new ix chunk. */ - - if ( stream == 0 ) - type = make_fourcc( "ix00" ); - else - type = make_fourcc( "ix01" ); - ix_chunk[ stream ] = AddDirectoryEntry( type, 0, sizeof( AVIStdIndex ), movi_list ); - GetDirectoryEntry( ix_chunk[ stream ], type, name, length, offset, parent ); - - /* fill out all required fields. The offsets in the - array are relative to qwBaseOffset, so fill in the - offset to the next free location in the file - there. */ - - ix[ stream ] ->wLongsPerEntry = 2; - ix[ stream ] ->bIndexSubType = 0; - ix[ stream ] ->bIndexType = KINO_AVI_INDEX_OF_CHUNKS; - ix[ stream ] ->nEntriesInUse = 0; - ix[ stream ] ->dwChunkId = indx[ stream ] ->dwChunkId; - ix[ stream ] ->qwBaseOffset = offset + length; - ix[ stream ] ->dwReserved = 0; - - for ( i = 0; i < IX00_INDEX_SIZE; ++i ) - { - ix[ stream ] ->aIndex[ i ].dwOffset = 0; - ix[ stream ] ->aIndex[ i ].dwSize = 0; - } - - /* add a reference to this new index in our super - index. */ - - i = indx[ stream ] ->nEntriesInUse++; - indx[ stream ] ->aIndex[ i ].qwOffset = offset - RIFF_HEADERSIZE; - indx[ stream ] ->aIndex[ i ].dwSize = length + RIFF_HEADERSIZE; - indx[ stream ] ->aIndex[ i ].dwDuration = 0; -} - - -void AVIFile::UpdateIndx( int stream, int chunk, int duration ) -{ - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - int i; - - /* update the appropiate entry in the super index. It reflects - the number of frames in the referenced index. */ - - i = indx[ stream ] ->nEntriesInUse - 1; - indx[ stream ] ->aIndex[ i ].dwDuration += duration; - - /* update the standard index. Calculate the file position of - the new frame. */ - - GetDirectoryEntry( chunk, type, name, length, offset, parent ); - - indx[ stream ] ->dwChunkId = type; - i = ix[ stream ] ->nEntriesInUse++; - ix[ stream ] ->aIndex[ i ].dwOffset = offset - ix[ stream ] ->qwBaseOffset; - ix[ stream ] ->aIndex[ i ].dwSize = length; -} - - -void AVIFile::UpdateIdx1( int chunk, int flags ) -{ - if ( idx1->nEntriesInUse < 20000 ) - { - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - - GetDirectoryEntry( chunk, type, name, length, offset, parent ); - - idx1->aIndex[ idx1->nEntriesInUse ].dwChunkId = type; - idx1->aIndex[ idx1->nEntriesInUse ].dwFlags = flags; - idx1->aIndex[ idx1->nEntriesInUse ].dwOffset = offset - GetDirectoryEntry( movi_list ).offset - RIFF_HEADERSIZE; - idx1->aIndex[ idx1->nEntriesInUse ].dwSize = length; - idx1->nEntriesInUse++; - } -} - -bool AVIFile::verifyStreamFormat( FOURCC type ) -{ - int i, j = 0; - AVIStreamHeader avi_stream_header; - BITMAPINFOHEADER bih; - FOURCC strh = make_fourcc( "strh" ); - FOURCC strf = make_fourcc( "strf" ); - - while ( ( i = FindDirectoryEntry( strh, j++ ) ) != -1 ) - { - ReadChunk( i, ( void* ) & avi_stream_header, sizeof( AVIStreamHeader ) ); - if ( avi_stream_header.fccHandler == type ) - return true; - } - j = 0; - while ( ( i = FindDirectoryEntry( strf, j++ ) ) != -1 ) - { - ReadChunk( i, ( void* ) & bih, sizeof( BITMAPINFOHEADER ) ); - if ( ( FOURCC ) bih.biCompression == type ) - return true; - } - - return false; -} - -bool AVIFile::verifyStream( FOURCC type ) -{ - int i, j = 0; - AVIStreamHeader avi_stream_header; - FOURCC strh = make_fourcc( "strh" ); - - while ( ( i = FindDirectoryEntry( strh, j++ ) ) != -1 ) - { - ReadChunk( i, ( void* ) & avi_stream_header, sizeof( AVIStreamHeader ) ); - if ( avi_stream_header.fccType == type ) - return true; - } - return false; -} - -bool AVIFile::isOpenDML( void ) -{ - int i, j = 0; - FOURCC dmlh = make_fourcc( "dmlh" ); - - while ( ( i = FindDirectoryEntry( dmlh, j++ ) ) != -1 ) - { - return true; - } - return false; -} - -AVI1File::AVI1File() : AVIFile() -{} - - -AVI1File::~AVI1File() -{} - - -/* Initialize the AVI structure to its initial state, either for PAL - or NTSC format */ - -void AVI1File::Init( int format, int sampleFrequency, int indexType ) -{ - int num_blocks; - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - - assert( ( format == AVI_PAL ) || ( format == AVI_NTSC ) ); - - AVIFile::Init( format, sampleFrequency, indexType ); - - switch ( format ) - { - case AVI_PAL: - mainHdr.dwWidth = 720; - mainHdr.dwHeight = 576; - - streamHdr[ 0 ].dwScale = 1; - streamHdr[ 0 ].dwRate = 25; - streamHdr[ 0 ].dwSuggestedBufferSize = 144008; - - /* initialize the 'strf' chunk */ - - /* Meaning of the DV stream format chunk per Microsoft - dwDVAAuxSrc - Specifies the Audio Auxiliary Data Source Pack for the first audio block - (first 5 DV DIF sequences for 525-60 systems or 6 DV DIF sequences for 625-50 systems) of - a frame. A DIF sequence is a data block that contains 150 DIF blocks. A DIF block consists - of 80 bytes. The Audio Auxiliary Data Source Pack is defined in section D.7.1 of Part 2, - Annex D, "The Pack Header Table and Contents of Packs" of the Specification of - Consumer-use Digital VCRs. - dwDVAAuxCtl - Specifies the Audio Auxiliary Data Source Control Pack for the first audio block of a - frame. The Audio Auxiliary Data Control Pack is defined in section D.7.2 of Part 2, - Annex D, "The Pack Header Table and Contents of Packs" of the Specification of - Consumer-use Digital VCRs. - dwDVAAuxSrc1 - Specifies the Audio Auxiliary Data Source Pack for the second audio block - (second 5 DV DIF sequences for 525-60 systems or 6 DV DIF sequences for 625-50 systems) of a frame. - dwDVAAuxCtl1 - Specifies the Audio Auxiliary Data Source Control Pack for the second audio block of a frame. - dwDVVAuxSrc - Specifies the Video Auxiliary Data Source Pack as defined in section D.8.1 of Part 2, - Annex D, "The Pack Header Table and Contents of Packs" of the Specification of - Consumer-use Digital VCRs. - dwDVVAuxCtl - Specifies the Video Auxiliary Data Source Control Pack as defined in section D.8.2 of Part 2, - Annex D, "The Pack Header Table and Contents of Packs" of the Specification of - Consumer-use Digital VCRs. - dwDVReserved[2] - Reserved. Set this array to zero. - */ - - dvinfo.dwDVAAuxSrc = 0xd1e030d0; - dvinfo.dwDVAAuxCtl = 0xffa0cf3f; - dvinfo.dwDVAAuxSrc1 = 0xd1e03fd0; - dvinfo.dwDVAAuxCtl1 = 0xffa0cf3f; - dvinfo.dwDVVAuxSrc = 0xff20ffff; - dvinfo.dwDVVAuxCtl = 0xfffdc83f; - dvinfo.dwDVReserved[ 0 ] = 0; - dvinfo.dwDVReserved[ 1 ] = 0; - break; - - case AVI_NTSC: - mainHdr.dwWidth = 720; - mainHdr.dwHeight = 480; - - streamHdr[ 0 ].dwScale = 1001; - streamHdr[ 0 ].dwRate = 30000; - streamHdr[ 0 ].dwSuggestedBufferSize = 120008; - - /* initialize the 'strf' chunk */ - dvinfo.dwDVAAuxSrc = 0xc0c000c0; - dvinfo.dwDVAAuxCtl = 0xffa0cf3f; - dvinfo.dwDVAAuxSrc1 = 0xc0c001c0; - dvinfo.dwDVAAuxCtl1 = 0xffa0cf3f; - dvinfo.dwDVVAuxSrc = 0xff80ffff; - dvinfo.dwDVVAuxCtl = 0xfffcc83f; - dvinfo.dwDVReserved[ 0 ] = 0; - dvinfo.dwDVReserved[ 1 ] = 0; - break; - - default: /* no default allowed */ - assert( 0 ); - break; - } - - indx[ 0 ] ->dwChunkId = make_fourcc( "00__" ); - - /* Initialize the 'strh' chunk */ - - streamHdr[ 0 ].fccType = make_fourcc( "iavs" ); - streamHdr[ 0 ].fccHandler = make_fourcc( "dvsd" ); - streamHdr[ 0 ].dwFlags = 0; - streamHdr[ 0 ].wPriority = 0; - streamHdr[ 0 ].wLanguage = 0; - streamHdr[ 0 ].dwInitialFrames = 0; - streamHdr[ 0 ].dwStart = 0; - streamHdr[ 0 ].dwLength = 0; - streamHdr[ 0 ].dwQuality = 0; - streamHdr[ 0 ].dwSampleSize = 0; - streamHdr[ 0 ].rcFrame.top = 0; - streamHdr[ 0 ].rcFrame.bottom = 0; - streamHdr[ 0 ].rcFrame.left = 0; - streamHdr[ 0 ].rcFrame.right = 0; - - /* This is a simple directory structure setup. For details see the - "OpenDML AVI File Format Extensions" document. - - An AVI file contains basically two types of objects, a - "chunk" and a "list" object. The list object contains any - number of chunks. Since a list is also a chunk, it is - possible to create a hierarchical "list of lists" - structure. - - Every AVI file starts with a "RIFF" object, which is a list - of several other required objects. The actual DV data is - contained in a "movi" list, each frame is in its own chunk. - - Old AVI files (pre OpenDML V. 1.02) contain only one RIFF - chunk of less than 1 GByte size per file. The current - format which allow for almost arbitrary sizes can contain - several RIFF chunks of less than 1 GByte size. Old software - however would only deal with the first RIFF chunk. - - Note that the first entry (FILE) isn�t actually part - of the AVI file. I use this (pseudo-) directory entry to - keep track of the RIFF chunks and their positions in the - AVI file. - */ - - /* Create the container directory entry */ - - file_list = AddDirectoryEntry( make_fourcc( "FILE" ), make_fourcc( "FILE" ), 0, RIFF_NO_PARENT ); - - /* Create a basic directory structure. Only chunks defined from here on will be written to the AVI file. */ - - riff_list = AddDirectoryEntry( make_fourcc( "RIFF" ), make_fourcc( "AVI " ), RIFF_LISTSIZE, file_list ); - hdrl_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "hdrl" ), RIFF_LISTSIZE, riff_list ); - avih_chunk = AddDirectoryEntry( make_fourcc( "avih" ), 0, sizeof( MainAVIHeader ), hdrl_list ); - strl_list[ 0 ] = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "strl" ), RIFF_LISTSIZE, hdrl_list ); - strh_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "strh" ), 0, sizeof( AVIStreamHeader ), strl_list[ 0 ] ); - strf_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "strf" ), 0, sizeof( dvinfo ), strl_list[ 0 ] ); - if ( index_type & AVI_LARGE_INDEX ) - indx_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "indx" ), 0, sizeof( AVISuperIndex ), strl_list[ 0 ] ); - - odml_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "odml" ), RIFF_LISTSIZE, hdrl_list ); - dmlh_chunk = AddDirectoryEntry( make_fourcc( "dmlh" ), 0, 0x00f8, odml_list ); - - /* align movi list to block */ - GetDirectoryEntry( hdrl_list, type, name, length, offset, parent ); - num_blocks = length / PADDING_SIZE + 1; - length = num_blocks * PADDING_SIZE - length - 5 * RIFF_HEADERSIZE; // why 5? - junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, length, riff_list ); - - movi_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "movi" ), RIFF_LISTSIZE, riff_list ); - - /* The ix00 chunk will be added dynamically to the movi_list in avi_write_frame - as needed */ - - ix_chunk[ 0 ] = -1; -} - - -/* Write a DV video frame. This is somewhat complex... */ - -#if 0 -bool AVI1File::WriteFrame( const Frame &frame ) -{ - int frame_chunk; - int junk_chunk; - int num_blocks; - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - - /* exit if no large index and 1GB reached */ - if ( !( index_type & AVI_LARGE_INDEX ) && isUpdateIdx1 == false ) - return false; - - /* Check if we need a new ix00 Standard Index. It has a - capacity of IX00_INDEX_SIZE frames. Whenever we exceed that - number, we need a new index. The new ix00 chunk is also - part of the movi list. */ - - if ( ( index_type & AVI_LARGE_INDEX ) && ( ( ( streamHdr[ 0 ].dwLength - 0 ) % IX00_INDEX_SIZE ) == 0 ) ) - FlushIndx( 0 ); - - /* Write the DV frame data. - - Make a new 00__ chunk for the new frame, write out the - frame. */ - - frame_chunk = AddDirectoryEntry( make_fourcc( "00__" ), 0, frame.GetFrameSize(), movi_list ); - if ( ( index_type & AVI_LARGE_INDEX ) && ( streamHdr[ 0 ].dwLength % IX00_INDEX_SIZE ) == 0 ) - { - GetDirectoryEntry( frame_chunk, type, name, length, offset, parent ); - ix[ 0 ] ->qwBaseOffset = offset - RIFF_HEADERSIZE; - } - WriteChunk( frame_chunk, frame.data ); - // num_blocks = (frame.GetFrameSize() + RIFF_HEADERSIZE) / PADDING_SIZE + 1; - // length = num_blocks * PADDING_SIZE - frame.GetFrameSize() - 2 * RIFF_HEADERSIZE; - // junk_chunk = AddDirectoryEntry(make_fourcc("JUNK"), 0, length, movi_list); - // WriteChunk(junk_chunk, g_zeroes); - - if ( index_type & AVI_LARGE_INDEX ) - UpdateIndx( 0, frame_chunk, 1 ); - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - UpdateIdx1( frame_chunk, 0x10 ); - - /* update some variables with the new frame count. */ - - if ( isUpdateIdx1 ) - ++mainHdr.dwTotalFrames; - ++streamHdr[ 0 ].dwLength; - ++dmlh[ 0 ]; - - /* Find out if the current riff list is close to 1 GByte in - size. If so, start a new (extended) RIFF. The only allowed - item in the new RIFF chunk is a movi list (with video - frames and indexes as usual). */ - - GetDirectoryEntry( riff_list, type, name, length, offset, parent ); - if ( length > 0x3f000000 ) - { - /* write idx1 only once and before end of first GB */ - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - { - int idx1_chunk = AddDirectoryEntry( make_fourcc( "idx1" ), 0, idx1->nEntriesInUse * 16, riff_list ); - WriteChunk( idx1_chunk, ( void* ) idx1 ); - } - isUpdateIdx1 = false; - - if ( index_type & AVI_LARGE_INDEX ) - { - /* pad out to 1GB */ - //GetDirectoryEntry(riff_list, type, name, length, offset, parent); - //junk_chunk = AddDirectoryEntry(make_fourcc("JUNK"), 0, PADDING_1GB - length - 5 * RIFF_HEADERSIZE, riff_list); - //WriteChunk(junk_chunk, g_zeroes); - - /* padding for alignment */ - GetDirectoryEntry( riff_list, type, name, length, offset, parent ); - num_blocks = ( length + 4 * RIFF_HEADERSIZE ) / PADDING_SIZE + 1; - length = ( num_blocks * PADDING_SIZE ) - length - 4 * RIFF_HEADERSIZE - 2 * RIFF_LISTSIZE; - if ( length > 0 ) - { - junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, length, riff_list ); - WriteChunk( junk_chunk, g_zeroes ); - } - - riff_list = AddDirectoryEntry( make_fourcc( "RIFF" ), make_fourcc( "AVIX" ), RIFF_LISTSIZE, file_list ); - movi_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "movi" ), RIFF_LISTSIZE, riff_list ); - } - } - return true; -} -#endif - -void AVI1File::WriteRIFF() -{ - - WriteChunk( avih_chunk, ( void* ) & mainHdr ); - WriteChunk( strh_chunk[ 0 ], ( void* ) & streamHdr[ 0 ] ); - WriteChunk( strf_chunk[ 0 ], ( void* ) & dvinfo ); - WriteChunk( dmlh_chunk, ( void* ) & dmlh ); - - if ( index_type & AVI_LARGE_INDEX ) - { - WriteChunk( indx_chunk[ 0 ], ( void* ) indx[ 0 ] ); - WriteChunk( ix_chunk[ 0 ], ( void* ) ix[ 0 ] ); - } - - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - { - int idx1_chunk = AddDirectoryEntry( make_fourcc( "idx1" ), 0, idx1->nEntriesInUse * 16, riff_list ); - WriteChunk( idx1_chunk, ( void* ) idx1 ); - } - - RIFFFile::WriteRIFF(); -} - - -AVI2File::AVI2File() : AVIFile() -{} - - -AVI2File::~AVI2File() -{} - - -/* Initialize the AVI structure to its initial state, either for PAL - or NTSC format */ - -void AVI2File::Init( int format, int sampleFrequency, int indexType ) -{ - int num_blocks; - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - - assert( ( format == AVI_PAL ) || ( format == AVI_NTSC ) ); - - AVIFile::Init( format, sampleFrequency, indexType ); - - switch ( format ) - { - - case AVI_PAL: - mainHdr.dwStreams = 2; - mainHdr.dwWidth = 720; - mainHdr.dwHeight = 576; - - /* Initialize the 'strh' chunk */ - - streamHdr[ 0 ].fccType = make_fourcc( "vids" ); - streamHdr[ 0 ].fccHandler = make_fourcc( "dvsd" ); - streamHdr[ 0 ].dwFlags = 0; - streamHdr[ 0 ].wPriority = 0; - streamHdr[ 0 ].wLanguage = 0; - streamHdr[ 0 ].dwInitialFrames = 0; - streamHdr[ 0 ].dwScale = 1; - streamHdr[ 0 ].dwRate = 25; - streamHdr[ 0 ].dwStart = 0; - streamHdr[ 0 ].dwLength = 0; - streamHdr[ 0 ].dwSuggestedBufferSize = 144008; - streamHdr[ 0 ].dwQuality = -1; - streamHdr[ 0 ].dwSampleSize = 0; - streamHdr[ 0 ].rcFrame.top = 0; - streamHdr[ 0 ].rcFrame.bottom = 0; - streamHdr[ 0 ].rcFrame.left = 0; - streamHdr[ 0 ].rcFrame.right = 0; - - bitmapinfo.biSize = sizeof( bitmapinfo ); - bitmapinfo.biWidth = 720; - bitmapinfo.biHeight = 576; - bitmapinfo.biPlanes = 1; - bitmapinfo.biBitCount = 24; - bitmapinfo.biCompression = make_fourcc( "dvsd" ); - bitmapinfo.biSizeImage = 144000; - bitmapinfo.biXPelsPerMeter = 0; - bitmapinfo.biYPelsPerMeter = 0; - bitmapinfo.biClrUsed = 0; - bitmapinfo.biClrImportant = 0; - - streamHdr[ 1 ].fccType = make_fourcc( "auds" ); - streamHdr[ 1 ].fccHandler = 0; - streamHdr[ 1 ].dwFlags = 0; - streamHdr[ 1 ].wPriority = 0; - streamHdr[ 1 ].wLanguage = 0; - streamHdr[ 1 ].dwInitialFrames = 0; - streamHdr[ 1 ].dwScale = 2 * 2; - streamHdr[ 1 ].dwRate = sampleFrequency * 2 * 2; - streamHdr[ 1 ].dwStart = 0; - streamHdr[ 1 ].dwLength = 0; - streamHdr[ 1 ].dwSuggestedBufferSize = 8192; - streamHdr[ 1 ].dwQuality = -1; - streamHdr[ 1 ].dwSampleSize = 2 * 2; - streamHdr[ 1 ].rcFrame.top = 0; - streamHdr[ 1 ].rcFrame.bottom = 0; - streamHdr[ 1 ].rcFrame.left = 0; - streamHdr[ 1 ].rcFrame.right = 0; - - break; - - case AVI_NTSC: - mainHdr.dwTotalFrames = 0; - mainHdr.dwStreams = 2; - mainHdr.dwWidth = 720; - mainHdr.dwHeight = 480; - - /* Initialize the 'strh' chunk */ - - streamHdr[ 0 ].fccType = make_fourcc( "vids" ); - streamHdr[ 0 ].fccHandler = make_fourcc( "dvsd" ); - streamHdr[ 0 ].dwFlags = 0; - streamHdr[ 0 ].wPriority = 0; - streamHdr[ 0 ].wLanguage = 0; - streamHdr[ 0 ].dwInitialFrames = 0; - streamHdr[ 0 ].dwScale = 1001; - streamHdr[ 0 ].dwRate = 30000; - streamHdr[ 0 ].dwStart = 0; - streamHdr[ 0 ].dwLength = 0; - streamHdr[ 0 ].dwSuggestedBufferSize = 120008; - streamHdr[ 0 ].dwQuality = -1; - streamHdr[ 0 ].dwSampleSize = 0; - streamHdr[ 0 ].rcFrame.top = 0; - streamHdr[ 0 ].rcFrame.bottom = 0; - streamHdr[ 0 ].rcFrame.left = 0; - streamHdr[ 0 ].rcFrame.right = 0; - - bitmapinfo.biSize = sizeof( bitmapinfo ); - bitmapinfo.biWidth = 720; - bitmapinfo.biHeight = 480; - bitmapinfo.biPlanes = 1; - bitmapinfo.biBitCount = 24; - bitmapinfo.biCompression = make_fourcc( "dvsd" ); - bitmapinfo.biSizeImage = 120000; - bitmapinfo.biXPelsPerMeter = 0; - bitmapinfo.biYPelsPerMeter = 0; - bitmapinfo.biClrUsed = 0; - bitmapinfo.biClrImportant = 0; - - streamHdr[ 1 ].fccType = make_fourcc( "auds" ); - streamHdr[ 1 ].fccHandler = 0; - streamHdr[ 1 ].dwFlags = 0; - streamHdr[ 1 ].wPriority = 0; - streamHdr[ 1 ].wLanguage = 0; - streamHdr[ 1 ].dwInitialFrames = 1; - streamHdr[ 1 ].dwScale = 2 * 2; - streamHdr[ 1 ].dwRate = sampleFrequency * 2 * 2; - streamHdr[ 1 ].dwStart = 0; - streamHdr[ 1 ].dwLength = 0; - streamHdr[ 1 ].dwSuggestedBufferSize = 8192; - streamHdr[ 1 ].dwQuality = 0; - streamHdr[ 1 ].dwSampleSize = 2 * 2; - streamHdr[ 1 ].rcFrame.top = 0; - streamHdr[ 1 ].rcFrame.bottom = 0; - streamHdr[ 1 ].rcFrame.left = 0; - streamHdr[ 1 ].rcFrame.right = 0; - - break; - } - waveformatex.wFormatTag = 1; - waveformatex.nChannels = 2; - waveformatex.nSamplesPerSec = sampleFrequency; - waveformatex.nAvgBytesPerSec = sampleFrequency * 2 * 2; - waveformatex.nBlockAlign = 4; - waveformatex.wBitsPerSample = 16; - waveformatex.cbSize = 0; - - file_list = AddDirectoryEntry( make_fourcc( "FILE" ), make_fourcc( "FILE" ), 0, RIFF_NO_PARENT ); - - /* Create a basic directory structure. Only chunks defined from here on will be written to the AVI file. */ - - riff_list = AddDirectoryEntry( make_fourcc( "RIFF" ), make_fourcc( "AVI " ), RIFF_LISTSIZE, file_list ); - hdrl_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "hdrl" ), RIFF_LISTSIZE, riff_list ); - avih_chunk = AddDirectoryEntry( make_fourcc( "avih" ), 0, sizeof( MainAVIHeader ), hdrl_list ); - - strl_list[ 0 ] = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "strl" ), RIFF_LISTSIZE, hdrl_list ); - strh_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "strh" ), 0, sizeof( AVIStreamHeader ), strl_list[ 0 ] ); - strf_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "strf" ), 0, sizeof( BITMAPINFOHEADER ), strl_list[ 0 ] ); - if ( index_type & AVI_LARGE_INDEX ) - { - indx_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "indx" ), 0, sizeof( AVISuperIndex ), strl_list[ 0 ] ); - ix_chunk[ 0 ] = -1; - indx[ 0 ] ->dwChunkId = make_fourcc( "00dc" ); - } - - strl_list[ 1 ] = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "strl" ), RIFF_LISTSIZE, hdrl_list ); - strh_chunk[ 1 ] = AddDirectoryEntry( make_fourcc( "strh" ), 0, sizeof( AVIStreamHeader ), strl_list[ 1 ] ); - strf_chunk[ 1 ] = AddDirectoryEntry( make_fourcc( "strf" ), 0, sizeof( WAVEFORMATEX ) - 2, strl_list[ 1 ] ); - junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, 2, strl_list[ 1 ] ); - if ( index_type & AVI_LARGE_INDEX ) - { - indx_chunk[ 1 ] = AddDirectoryEntry( make_fourcc( "indx" ), 0, sizeof( AVISuperIndex ), strl_list[ 1 ] ); - ix_chunk[ 1 ] = -1; - indx[ 1 ] ->dwChunkId = make_fourcc( "01wb" ); - - odml_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "odml" ), RIFF_LISTSIZE, hdrl_list ); - dmlh_chunk = AddDirectoryEntry( make_fourcc( "dmlh" ), 0, 0x00f8, odml_list ); - } - - /* align movi list to block */ - GetDirectoryEntry( hdrl_list, type, name, length, offset, parent ); - num_blocks = length / PADDING_SIZE + 1; - length = num_blocks * PADDING_SIZE - length - 5 * RIFF_HEADERSIZE; // why 5 headers? - junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, length, riff_list ); - - movi_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "movi" ), RIFF_LISTSIZE, riff_list ); - - idx1->aIndex[ idx1->nEntriesInUse ].dwChunkId = make_fourcc( "7Fxx" ); - idx1->aIndex[ idx1->nEntriesInUse ].dwFlags = 0; - idx1->aIndex[ idx1->nEntriesInUse ].dwOffset = 0; - idx1->aIndex[ idx1->nEntriesInUse ].dwSize = 0; - idx1->nEntriesInUse++; -} - - -void AVI2File::WriteRIFF() -{ - WriteChunk( avih_chunk, ( void* ) & mainHdr ); - WriteChunk( strh_chunk[ 0 ], ( void* ) & streamHdr[ 0 ] ); - WriteChunk( strf_chunk[ 0 ], ( void* ) & bitmapinfo ); - if ( index_type & AVI_LARGE_INDEX ) - { - WriteChunk( dmlh_chunk, ( void* ) & dmlh ); - WriteChunk( indx_chunk[ 0 ], ( void* ) indx[ 0 ] ); - WriteChunk( ix_chunk[ 0 ], ( void* ) ix[ 0 ] ); - } - WriteChunk( strh_chunk[ 1 ], ( void* ) & streamHdr[ 1 ] ); - WriteChunk( strf_chunk[ 1 ], ( void* ) & waveformatex ); - if ( index_type & AVI_LARGE_INDEX ) - { - WriteChunk( indx_chunk[ 1 ], ( void* ) indx[ 1 ] ); - WriteChunk( ix_chunk[ 1 ], ( void* ) ix[ 1 ] ); - } - - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - { - int idx1_chunk = AddDirectoryEntry( make_fourcc( "idx1" ), 0, idx1->nEntriesInUse * 16, riff_list ); - WriteChunk( idx1_chunk, ( void* ) idx1 ); - } - RIFFFile::WriteRIFF(); -} - - -/** Write a DV video frame - - \param frame the frame to write -*/ - -#if 0 -bool AVI2File::WriteFrame( const Frame &frame ) -{ - int audio_chunk; - int frame_chunk; - int junk_chunk; - char soundbuf[ 20000 ]; - int audio_size; - int num_blocks; - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - - /* exit if no large index and 1GB reached */ - if ( !( index_type & AVI_LARGE_INDEX ) && isUpdateIdx1 == false ) - return false; - - /* Check if we need a new ix00 Standard Index. It has a - capacity of IX00_INDEX_SIZE frames. Whenever we exceed that - number, we need a new index. The new ix00 chunk is also - part of the movi list. */ - - if ( ( index_type & AVI_LARGE_INDEX ) && ( ( ( streamHdr[ 0 ].dwLength - 0 ) % IX00_INDEX_SIZE ) == 0 ) ) - { - FlushIndx( 0 ); - FlushIndx( 1 ); - } - - /* Write audio data if we have it */ - - audio_size = frame.ExtractAudio( soundbuf ); - if ( audio_size > 0 ) - { - audio_chunk = AddDirectoryEntry( make_fourcc( "01wb" ), 0, audio_size, movi_list ); - if ( ( index_type & AVI_LARGE_INDEX ) && ( streamHdr[ 0 ].dwLength % IX00_INDEX_SIZE ) == 0 ) - { - GetDirectoryEntry( audio_chunk, type, name, length, offset, parent ); - ix[ 1 ] ->qwBaseOffset = offset - RIFF_HEADERSIZE; - } - WriteChunk( audio_chunk, soundbuf ); - // num_blocks = (audio_size + RIFF_HEADERSIZE) / PADDING_SIZE + 1; - // length = num_blocks * PADDING_SIZE - audio_size - 2 * RIFF_HEADERSIZE; - // junk_chunk = AddDirectoryEntry(make_fourcc("JUNK"), 0, length, movi_list); - // WriteChunk(junk_chunk, g_zeroes); - if ( index_type & AVI_LARGE_INDEX ) - UpdateIndx( 1, audio_chunk, audio_size / waveformatex.nChannels / 2 ); - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - UpdateIdx1( audio_chunk, 0x00 ); - streamHdr[ 1 ].dwLength += audio_size / waveformatex.nChannels / 2; - - } - - /* Write video data */ - - frame_chunk = AddDirectoryEntry( make_fourcc( "00dc" ), 0, frame.GetFrameSize(), movi_list ); - if ( ( index_type & AVI_LARGE_INDEX ) && ( streamHdr[ 0 ].dwLength % IX00_INDEX_SIZE ) == 0 ) - { - GetDirectoryEntry( frame_chunk, type, name, length, offset, parent ); - ix[ 0 ] ->qwBaseOffset = offset - RIFF_HEADERSIZE; - } - WriteChunk( frame_chunk, frame.data ); - // num_blocks = (frame.GetFrameSize() + RIFF_HEADERSIZE) / PADDING_SIZE + 1; - // length = num_blocks * PADDING_SIZE - frame.GetFrameSize() - 2 * RIFF_HEADERSIZE; - // junk_chunk = AddDirectoryEntry(make_fourcc("JUNK"), 0, length, movi_list); - // WriteChunk(junk_chunk, g_zeroes); - if ( index_type & AVI_LARGE_INDEX ) - UpdateIndx( 0, frame_chunk, 1 ); - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - UpdateIdx1( frame_chunk, 0x10 ); - - /* update some variables with the new frame count. */ - - if ( isUpdateIdx1 ) - ++mainHdr.dwTotalFrames; - ++streamHdr[ 0 ].dwLength; - ++dmlh[ 0 ]; - - /* Find out if the current riff list is close to 1 GByte in - size. If so, start a new (extended) RIFF. The only allowed - item in the new RIFF chunk is a movi list (with video - frames and indexes as usual). */ - - GetDirectoryEntry( riff_list, type, name, length, offset, parent ); - if ( length > 0x3f000000 ) - { - - /* write idx1 only once and before end of first GB */ - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - { - int idx1_chunk = AddDirectoryEntry( make_fourcc( "idx1" ), 0, idx1->nEntriesInUse * 16, riff_list ); - WriteChunk( idx1_chunk, ( void* ) idx1 ); - } - isUpdateIdx1 = false; - - if ( index_type & AVI_LARGE_INDEX ) - { - /* padding for alignment */ - GetDirectoryEntry( riff_list, type, name, length, offset, parent ); - num_blocks = ( length + 4 * RIFF_HEADERSIZE ) / PADDING_SIZE + 1; - length = ( num_blocks * PADDING_SIZE ) - length - 4 * RIFF_HEADERSIZE - 2 * RIFF_LISTSIZE; - if ( length > 0 ) - { - junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, length, riff_list ); - WriteChunk( junk_chunk, g_zeroes ); - } - - riff_list = AddDirectoryEntry( make_fourcc( "RIFF" ), make_fourcc( "AVIX" ), RIFF_LISTSIZE, file_list ); - movi_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "movi" ), RIFF_LISTSIZE, riff_list ); - } - } - return true; -} -#endif - -void AVI1File::setDVINFO( DVINFO &info ) -{ - // do not do this until debugged audio against DirectShow - return ; - - dvinfo.dwDVAAuxSrc = info.dwDVAAuxSrc; - dvinfo.dwDVAAuxCtl = info.dwDVAAuxCtl; - dvinfo.dwDVAAuxSrc1 = info.dwDVAAuxSrc1; - dvinfo.dwDVAAuxCtl1 = info.dwDVAAuxCtl1; - dvinfo.dwDVVAuxSrc = info.dwDVVAuxSrc; - dvinfo.dwDVVAuxCtl = info.dwDVVAuxCtl; -} - - -void AVI2File::setDVINFO( DVINFO &info ) -{} - -void AVIFile::setFccHandler( FOURCC type, FOURCC handler ) -{ - for ( int i = 0; i < mainHdr.dwStreams; i++ ) - { - if ( streamHdr[ i ].fccType == type ) - { - int k, j = 0; - FOURCC strf = make_fourcc( "strf" ); - BITMAPINFOHEADER bih; - - streamHdr[ i ].fccHandler = handler; - - while ( ( k = FindDirectoryEntry( strf, j++ ) ) != -1 ) - { - ReadChunk( k, ( void* ) & bih, sizeof( BITMAPINFOHEADER ) ); - bih.biCompression = handler; - } - } - } -} - -bool AVIFile::getStreamFormat( void* data, FOURCC type ) -{ - int i, j = 0; - FOURCC strh = make_fourcc( "strh" ); - FOURCC strf = make_fourcc( "strf" ); - AVIStreamHeader avi_stream_header; - bool result = false; - - while ( ( result == false ) && ( i = FindDirectoryEntry( strh, j++ ) ) != -1 ) - { - ReadChunk( i, ( void* ) & avi_stream_header, sizeof( AVIStreamHeader ) ); - if ( avi_stream_header.fccType == type ) - { - FOURCC chunkID; - int size; - - pthread_mutex_lock( &file_mutex ); - fail_neg( read( fd, &chunkID, sizeof( FOURCC ) ) ); - if ( chunkID == strf ) - { - fail_neg( read( fd, &size, sizeof( int ) ) ); - fail_neg( read( fd, data, size ) ); - result = true; - } - pthread_mutex_unlock( &file_mutex ); - } - } - return result; -} diff --git a/src/modules/kino/avi.h b/src/modules/kino/avi.h deleted file mode 100644 index d22d5e6..0000000 --- a/src/modules/kino/avi.h +++ /dev/null @@ -1,447 +0,0 @@ -/* -* avi.h library for AVI file format i/o -* Copyright (C) 2000 - 2002 Arne Schirmacher -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Tag: $Name$ -* -* Change log: -* -* $Log$ -* Revision 1.4 2005/07/25 07:21:39 lilo_booter -* + fixes for opendml dv avi -* -* Revision 1.3 2005/06/21 20:59:39 lilo_booter -* src/framework/mlt_consumer.c src/framework/mlt_consumer.h -* + Added a general profile handling for size, aspect ratio and display ratio -* -* src/framework/mlt_producer.c -* + Correction to aspect ratio properties -* -* src/inigo/inigo.c -* + Minimalist support for sdl_preview (still not very good) -* -* src/modules/avformat/consumer_avformat.c -* + Takes consumer profile into account -* -* src/modules/core/filter_resize.c -* + Corrections for synthesised producers and aspect ratio (inherits from consumer) -* -* src/modules/core/producer_colour.c -* src/modules/core/producer_noise.c -* src/modules/gtk2/producer_pango.c -* + Ensures that resize picks up consumer aspect ratio -* -* src/modules/dv/consumer_libdv.c -* + Honour wide screen output -* -* src/modules/gtk2/producer_pixbuf.c -* + Correction for 1:1 aspect ratio -* -* src/modules/kino/Makefile -* src/modules/kino/avi.cc -* src/modules/kino/avi.h -* src/modules/kino/configure -* src/modules/kino/filehandler.cc -* + Attempt to allow mov dv files to provide audio -* -* src/modules/sdl/consumer_sdl.c -* src/modules/sdl/consumer_sdl_preview.c -* src/modules/sdl/consumer_sdl_still.c -* + Takes consumer profile into account -* -* Revision 1.2 2005/04/15 14:37:03 lilo_booter -* Minor correction -* -* Revision 1.1 2005/04/15 14:28:26 lilo_booter -* Initial version -* -* Revision 1.16 2005/04/01 23:43:10 ddennedy -* apply endian fixes from Daniel Kobras -* -* Revision 1.15 2004/10/11 01:37:11 ddennedy -* mutex safety locks in RIFF and AVI classes, type 2 AVI optimization, mencoder export script -* -* Revision 1.14 2003/11/25 23:00:52 ddennedy -* cleanup and a few bugfixes -* -* Revision 1.13 2003/10/21 16:34:32 ddennedy -* GNOME2 port phase 1: initial checkin -* -* Revision 1.11.2.5 2003/07/24 14:13:57 ddennedy -* support for distinct audio stream in type2 AVI and Quicktime; support for more DV FOURCCs -* -* Revision 1.11.2.4 2003/06/10 23:53:36 ddennedy -* Daniel Kobras' WriteFrame error handling and automatic OpenDML, bugfixes in scene list updates, export AV/C Record -* -* Revision 1.11.2.3 2003/02/20 21:59:57 ddennedy -* bugfixes to capture and AVI -* -* Revision 1.11.2.2 2003/01/13 05:15:31 ddennedy -* added More Info panel and supporting methods -* -* Revision 1.11.2.1 2002/11/25 04:48:31 ddennedy -* bugfix to report errors when loading files -* -* Revision 1.11 2002/10/08 07:46:41 ddennedy -* AVI bugfixes, compatibility, optimization, warn bad file in capture and export dv file, allow no mplex -* -* Revision 1.10 2002/05/17 08:04:25 ddennedy -* revert const-ness of Frame references in Frame, FileHandler, and AVI classes -* -* Revision 1.9 2002/05/15 04:39:35 ddennedy -* bugfixes to dv2 AVI write, audio export, Xv init -* -* Revision 1.8 2002/04/29 05:09:22 ddennedy -* raw dv file support, Frame::ExtractAudio uses libdv, audioScrub prefs -* -* Revision 1.7 2002/04/09 06:53:42 ddennedy -* cleanup, new libdv 0.9.5, large AVI, dnd storyboard -* -* Revision 1.7 2002/03/25 21:34:25 arne -* Support for large (64 bit) files mostly completed -* -* Revision 1.6 2002/03/10 13:29:41 arne -* more changes for 64 bit access -* -* Revision 1.5 2002/03/09 17:59:28 arne -* moved index routines to AVIFile -* -* Revision 1.4 2002/03/09 10:26:26 arne -* improved constructors and assignment operator -* -* Revision 1.3 2002/03/09 08:55:57 arne -* moved a few variables to AVIFile -* -* Revision 1.2 2002/03/04 19:22:43 arne -* updated to latest Kino avi code -* -* Revision 1.1.1.1 2002/03/03 19:08:08 arne -* import of version 1.01 -* -*/ - -/** Common AVI declarations - - Some of this comes from the public domain AVI specification, which - explains the microsoft-style definitions. - - \file avi.h -*/ - -#ifndef _AVI_H -#define _AVI_H 1 - -#include -#include "riff.h" - -#define PACKED(x) __attribute__((packed)) x - -#define AVI_SMALL_INDEX (0x01) -#define AVI_LARGE_INDEX (0x02) -#define KINO_AVI_INDEX_OF_INDEXES (0x00) -#define KINO_AVI_INDEX_OF_CHUNKS (0x01) -#define AVI_INDEX_2FIELD (0x01) - -enum { AVI_PAL, AVI_NTSC, AVI_AUDIO_48KHZ, AVI_AUDIO_44KHZ, AVI_AUDIO_32KHZ }; - -/** Declarations of the main AVI file header - - The contents of this struct goes into the 'avih' chunk. */ - -typedef struct -{ - /// frame display rate (or 0L) - DWORD dwMicroSecPerFrame; - - /// max. transfer rate - DWORD dwMaxBytesPerSec; - - /// pad to multiples of this size, normally 2K - DWORD dwPaddingGranularity; - - /// the ever-present flags - DWORD dwFlags; - - /// # frames in file - DWORD dwTotalFrames; - DWORD dwInitialFrames; - DWORD dwStreams; - DWORD dwSuggestedBufferSize; - - DWORD dwWidth; - DWORD dwHeight; - - DWORD dwReserved[ 4 ]; -} -PACKED(MainAVIHeader); - -typedef struct -{ - WORD top, bottom, left, right; -} -PACKED(RECT); - -/** Declaration of a stream header - - The contents of this struct goes into the 'strh' header. */ - -typedef struct -{ - FOURCC fccType; - FOURCC fccHandler; - DWORD dwFlags; /* Contains AVITF_* flags */ - WORD wPriority; - WORD wLanguage; - DWORD dwInitialFrames; - DWORD dwScale; - DWORD dwRate; /* dwRate / dwScale == samples/second */ - DWORD dwStart; - DWORD dwLength; /* In units above... */ - DWORD dwSuggestedBufferSize; - DWORD dwQuality; - DWORD dwSampleSize; - RECT rcFrame; -} -PACKED(AVIStreamHeader); - -typedef struct -{ - DWORD dwDVAAuxSrc; - DWORD dwDVAAuxCtl; - DWORD dwDVAAuxSrc1; - DWORD dwDVAAuxCtl1; - DWORD dwDVVAuxSrc; - DWORD dwDVVAuxCtl; - DWORD dwDVReserved[ 2 ]; -} -PACKED(DVINFO); - -typedef struct -{ - DWORD biSize; - LONG biWidth; - LONG biHeight; - WORD biPlanes; - WORD biBitCount; - DWORD biCompression; - DWORD biSizeImage; - LONG biXPelsPerMeter; - LONG biYPelsPerMeter; - DWORD biClrUsed; - DWORD biClrImportant; - char dummy[ 1040 ]; -} -PACKED(BITMAPINFOHEADER); - -typedef struct -{ - WORD wFormatTag; - WORD nChannels; - DWORD nSamplesPerSec; - DWORD nAvgBytesPerSec; - WORD nBlockAlign; - WORD wBitsPerSample; - WORD cbSize; - WORD dummy; -} -PACKED(WAVEFORMATEX); - -typedef struct -{ - WORD wLongsPerEntry; - BYTE bIndexSubType; - BYTE bIndexType; - DWORD nEntriesInUse; - FOURCC dwChunkId; - DWORD dwReserved[ 3 ]; - struct avisuperindex_entry - { - QUADWORD qwOffset; - DWORD dwSize; - DWORD dwDuration; - } - aIndex[ 3198 ]; -} -PACKED(AVISuperIndex); - -typedef struct -{ - WORD wLongsPerEntry; - BYTE bIndexSubType; - BYTE bIndexType; - DWORD nEntriesInUse; - FOURCC dwChunkId; - QUADWORD qwBaseOffset; - DWORD dwReserved; - struct avifieldindex_entry - { - DWORD dwOffset; - DWORD dwSize; - } - aIndex[ 17895 ]; -} -PACKED(AVIStdIndex); - -typedef struct -{ - struct avisimpleindex_entry - { - FOURCC dwChunkId; - DWORD dwFlags; - DWORD dwOffset; - DWORD dwSize; - } - aIndex[ 20000 ]; - DWORD nEntriesInUse; -} -PACKED(AVISimpleIndex); - -typedef struct -{ - DWORD dirEntryType; - DWORD dirEntryName; - DWORD dirEntryLength; - size_t dirEntryOffset; - int dirEntryWrittenFlag; - int dirEntryParentList; -} -AviDirEntry; - - -/** base class for all AVI type files - - It contains methods and members which are the same in all AVI type files regardless of the particular compression, number - of streams etc. - - The AVIFile class also contains methods for handling several indexes to the video frame content. */ - -class AVIFile : public RIFFFile -{ -public: - AVIFile(); - AVIFile( const AVIFile& ); - virtual ~AVIFile(); - virtual AVIFile& operator=( const AVIFile& ); - - virtual void Init( int format, int sampleFrequency, int indexType ); - virtual int GetDVFrameInfo( off_t &offset, int &size, int frameNum ); - virtual int GetFrameInfo( off_t &offset, int &size, int frameNum, FOURCC chunkID ); - virtual int GetDVFrame( uint8_t *data, int frameNum ); - virtual int getFrame( void *data, int frameNum, FOURCC chunkID ); - virtual int GetTotalFrames() const; - virtual void PrintDirectoryEntryData( const RIFFDirEntry &entry ) const; - //virtual bool WriteFrame( const Frame &frame ) { return false; } - virtual void ParseList( int parent ); - virtual void ParseRIFF( void ); - virtual void ReadIndex( void ); - virtual void WriteRIFF( void ) - { } - virtual void FlushIndx( int stream ); - virtual void UpdateIndx( int stream, int chunk, int duration ); - virtual void UpdateIdx1( int chunk, int flags ); - virtual bool verifyStreamFormat( FOURCC type ); - virtual bool verifyStream( FOURCC type ); - virtual bool isOpenDML( void ); - virtual void setDVINFO( DVINFO& ) - { } - virtual void setFccHandler( FOURCC type, FOURCC handler ); - virtual bool getStreamFormat( void* data, FOURCC type ); - -protected: - MainAVIHeader mainHdr; - AVISimpleIndex *idx1; - int file_list; - int riff_list; - int hdrl_list; - int avih_chunk; - int movi_list; - int junk_chunk; - int idx1_chunk; - - AVIStreamHeader streamHdr[ 2 ]; - AVISuperIndex *indx[ 2 ]; - AVIStdIndex *ix[ 2 ]; - int indx_chunk[ 2 ]; - int ix_chunk[ 2 ]; - int strl_list[ 2 ]; - int strh_chunk[ 2 ]; - int strf_chunk[ 2 ]; - - int index_type; - int current_ix00; - - DWORD dmlh[ 62 ]; - int odml_list; - int dmlh_chunk; - bool isUpdateIdx1; - -}; - - -/** writing Type 1 DV AVIs - -*/ - -class AVI1File : public AVIFile -{ -public: - AVI1File(); - virtual ~AVI1File(); - - virtual void Init( int format, int sampleFrequency, int indexType ); - //virtual bool WriteFrame( const Frame &frame ); - virtual void WriteRIFF( void ); - virtual void setDVINFO( DVINFO& ); - -private: - DVINFO dvinfo; - - AVI1File( const AVI1File& ); - AVI1File& operator=( const AVI1File& ); -}; - - -/** writing Type 2 (separate audio data) DV AVIs - -This file type contains both audio and video tracks. It is therefore more compatible -to certain Windows programs, which expect any AVI having both audio and video tracks. -The video tracks contain the raw DV data (as in type 1) and the extracted audio tracks. - -Note that because the DV data contains audio information anyway, this means duplication -of data and a slight increase of file size. - -*/ - -class AVI2File : public AVIFile -{ -public: - AVI2File(); - virtual ~AVI2File(); - - virtual void Init( int format, int sampleFrequency, int indexType ); - //virtual bool WriteFrame( const Frame &frame ); - virtual void WriteRIFF( void ); - virtual void setDVINFO( DVINFO& ); - -private: - BITMAPINFOHEADER bitmapinfo; - WAVEFORMATEX waveformatex; - - AVI2File( const AVI2File& ); - AVI2File& operator=( const AVI2File& ); -}; -#endif diff --git a/src/modules/kino/configure b/src/modules/kino/configure deleted file mode 100755 index f6524f3..0000000 --- a/src/modules/kino/configure +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - - if [ "$targetos" = "Darwin" ] - then - echo "- does not build on Darwin: disabling" - touch ../disable-kino - exit 0 - fi - - # Entirely optional... - pkg-config libquicktime 2> /dev/null - lqt_disabled=$? - - pkg-config libdv 2> /dev/null - libdv_disabled=$? - - echo > config.h - [ "$lqt_disabled" = "0" ] && echo "#define HAVE_LIBQUICKTIME" >> config.h - [ "$libdv_disabled" = "0" ] && echo "#define HAVE_LIBDV" >> config.h - echo > config.mak - [ "$lqt_disabled" = "0" ] && echo "HAVE_LIBQUICKTIME=1" >> config.mak - [ "$libdv_disabled" = "0" ] && echo "HAVE_LIBDV=1" >> config.mak - - [ "$lqt_disabled" != "0" ] && echo "- libquicktime not found: only enabling dv avi support" - [ "$libdv_disabled" != "0" -a "$lqt_disabled" = "0" ] && echo "- libdv not found: mov dv may not have audio" - - exit 0 -fi diff --git a/src/modules/kino/endian_types.h b/src/modules/kino/endian_types.h deleted file mode 100644 index d66cdb6..0000000 --- a/src/modules/kino/endian_types.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - * - * Quick hack to handle endianness and word length issues. - * Defines _le, _be, and _ne variants to standard ISO types - * like int32_t, that are stored in little-endian, big-endian, - * and native-endian byteorder in memory, respectively. - * Caveat: int32_le_t and friends cannot be used in vararg - * functions like printf() without an explicit cast. - * - * Copyright (c) 2003-2005 Daniel Kobras - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _ENDIAN_TYPES_H -#define _ENDIAN_TYPES_H - -/* Needed for BYTE_ORDER and BIG/LITTLE_ENDIAN macros. */ -#ifndef _BSD_SOURCE -# define _BSD_SOURCE -#ifndef __FreeBSD__ -# include -#else -# include -#endif /* __FreeBSD__ */ -# undef _BSD_SOURCE -#else -#ifndef __FreeBSD__ -# include -#else -# include -#endif /* __FreeBSD__ */ -#endif - -#include -#ifndef __FreeBSD__ -#include -#else -#define bswap_16(x) bswap16(x) -#define bswap_32(x) bswap32(x) -#define bswap_64(x) bswap64(x) -#endif /* __FreeBSD__ */ - -static inline int8_t bswap(const int8_t& x) -{ - return x; -} - -static inline u_int8_t bswap(const u_int8_t& x) -{ - return x; -} - -static inline int16_t bswap(const int16_t& x) -{ - return bswap_16(x); -} - -static inline u_int16_t bswap(const u_int16_t& x) -{ - return bswap_16(x); -} - -static inline int32_t bswap(const int32_t& x) -{ - return bswap_32(x); -} - -static inline u_int32_t bswap(const u_int32_t& x) -{ - return bswap_32(x); -} - -static inline int64_t bswap(const int64_t& x) -{ - return bswap_64(x); -} - -static inline u_int64_t bswap(const u_int64_t& x) -{ - return bswap_64(x); -} - -#define le_to_cpu cpu_to_le -#define be_to_cpu cpu_to_be - -template static inline T cpu_to_le(const T& x) -{ -#if BYTE_ORDER == LITTLE_ENDIAN - return x; -#else - return bswap(x); -#endif -} - -template static inline T cpu_to_be(const T& x) -{ -#if BYTE_ORDER == LITTLE_ENDIAN - return bswap(x); -#else - return x; -#endif -} - -template class le_t { - T m; - T read() const { - return le_to_cpu(m); - }; - void write(const T& n) { - m = cpu_to_le(n); - }; -public: - le_t(void) { - m = 0; - }; - le_t(const T& o) { - write(o); - }; - operator T() const { - return read(); - }; - le_t operator++() { - write(read() + 1); - return *this; - }; - le_t operator++(int) { - write(read() + 1); - return *this; - }; - le_t operator--() { - write(read() - 1); - return *this; - }; - le_t operator--(int) { - write(read() - 1); - return *this; - }; - le_t& operator+=(const T& t) { - write(read() + t); - return *this; - }; - le_t& operator-=(const T& t) { - write(read() - t); - return *this; - }; - le_t& operator&=(const le_t& t) { - m &= t.m; - return *this; - }; - le_t& operator|=(const le_t& t) { - m |= t.m; - return *this; - }; -} __attribute__((packed)); - -/* Just copy-and-pasted from le_t. Too lazy to do it right. */ - -template class be_t { - T m; - T read() const { - return be_to_cpu(m); - }; - void write(const T& n) { - m = cpu_to_be(n); - }; -public: - be_t(void) { - m = 0; - }; - be_t(const T& o) { - write(o); - }; - operator T() const { - return read(); - }; - be_t operator++() { - write(read() + 1); - return *this; - }; - be_t operator++(int) { - write(read() + 1); - return *this; - }; - be_t operator--() { - write(read() - 1); - return *this; - }; - be_t operator--(int) { - write(read() - 1); - return *this; - }; - be_t& operator+=(const T& t) { - write(read() + t); - return *this; - }; - be_t& operator-=(const T& t) { - write(read() - t); - return *this; - }; - be_t& operator&=(const be_t& t) { - m &= t.m; - return *this; - }; - be_t& operator|=(const be_t& t) { - m |= t.m; - return *this; - }; -} __attribute__((packed)); - -/* Define types of native endianness similar to the little and big endian - * versions below. Not really necessary but useful occasionally to emphasize - * endianness of data. - */ - -typedef int8_t int8_ne_t; -typedef int16_t int16_ne_t; -typedef int32_t int32_ne_t; -typedef int64_t int64_ne_t; -typedef u_int8_t u_int8_ne_t; -typedef u_int16_t u_int16_ne_t; -typedef u_int32_t u_int32_ne_t; -typedef u_int64_t u_int64_ne_t; - - -/* The classes work on their native endianness as well, but obviously - * introduce some overhead. Use the faster typedefs to native types - * therefore, unless you're debugging. - */ - -#if BYTE_ORDER == LITTLE_ENDIAN -typedef int8_ne_t int8_le_t; -typedef int16_ne_t int16_le_t; -typedef int32_ne_t int32_le_t; -typedef int64_ne_t int64_le_t; -typedef u_int8_ne_t u_int8_le_t; -typedef u_int16_ne_t u_int16_le_t; -typedef u_int32_ne_t u_int32_le_t; -typedef u_int64_ne_t u_int64_le_t; -typedef int8_t int8_be_t; -typedef be_t int16_be_t; -typedef be_t int32_be_t; -typedef be_t int64_be_t; -typedef u_int8_t u_int8_be_t; -typedef be_t u_int16_be_t; -typedef be_t u_int32_be_t; -typedef be_t u_int64_be_t; -#else -typedef int8_ne_t int8_be_t; -typedef int16_ne_t int16_be_t; -typedef int32_ne_t int32_be_t; -typedef int64_ne_t int64_be_t; -typedef u_int8_ne_t u_int8_be_t; -typedef u_int16_ne_t u_int16_be_t; -typedef u_int32_ne_t u_int32_be_t; -typedef u_int64_ne_t u_int64_be_t; -typedef int8_t int8_le_t; -typedef le_t int16_le_t; -typedef le_t int32_le_t; -typedef le_t int64_le_t; -typedef u_int8_t u_int8_le_t; -typedef le_t u_int16_le_t; -typedef le_t u_int32_le_t; -typedef le_t u_int64_le_t; -#endif - -#endif diff --git a/src/modules/kino/error.cc b/src/modules/kino/error.cc deleted file mode 100644 index e2b8510..0000000 --- a/src/modules/kino/error.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* -* error.cc Error handling -* Copyright (C) 2000 Arne Schirmacher -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -// C++ includes - -#include -#include -#include -#include - -using std::ostringstream; -using std::string; -using std::endl; -using std::ends; -using std::cerr; - -// C includes - -#include -#include - -// local includes - -#include "error.h" - -void real_fail_neg( int eval, const char *eval_str, const char *func, const char *file, int line ) -{ - if ( eval < 0 ) - { - string exc; - ostringstream sb; - - sb << file << ":" << line << ": In function \"" << func << "\": \"" << eval_str << "\" evaluated to " << eval; - if ( errno != 0 ) - sb << endl << file << ":" << line << ": errno: " << errno << " (" << strerror( errno ) << ")"; - sb << ends; - exc = sb.str(); - cerr << exc << endl; - throw exc; - } -} - - -/** error handler for NULL result codes - - Whenever this is called with a NULL argument, it will throw an - exception. Typically used with functions like malloc() and new(). - -*/ - -void real_fail_null( const void *eval, const char *eval_str, const char *func, const char *file, int line ) -{ - if ( eval == NULL ) - { - - string exc; - ostringstream sb; - - sb << file << ":" << line << ": In function \"" << func << "\": " << eval_str << " is NULL" << ends; - exc = sb.str(); - cerr << exc << endl; - throw exc; - } -} - - -void real_fail_if( bool eval, const char *eval_str, const char *func, const char *file, int line ) -{ - if ( eval == true ) - { - - string exc; - ostringstream sb; - - sb << file << ":" << line << ": In function \"" << func << "\": condition \"" << eval_str << "\" is true"; - if ( errno != 0 ) - sb << endl << file << ":" << line << ": errno: " << errno << " (" << strerror( errno ) << ")"; - sb << ends; - exc = sb.str(); - cerr << exc << endl; - throw exc; - } -} diff --git a/src/modules/kino/error.h b/src/modules/kino/error.h deleted file mode 100644 index 9c04894..0000000 --- a/src/modules/kino/error.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* error.h Error handling -* Copyright (C) 2000 Arne Schirmacher -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef _ERROR_H -#define _ERROR_H 1 - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* - * Should check for gcc/g++ and version > 2.6 I suppose - */ -#ifndef __ASSERT_FUNCTION -# define __ASSERT_FUNCTION __PRETTY_FUNCTION__ -#endif - -#define fail_neg(eval) real_fail_neg (eval, #eval, __ASSERT_FUNCTION, __FILE__, __LINE__) -#define fail_null(eval) real_fail_null (eval, #eval, __ASSERT_FUNCTION, __FILE__, __LINE__) -#define fail_if(eval) real_fail_if (eval, #eval, __ASSERT_FUNCTION, __FILE__, __LINE__) - - void real_fail_neg ( int eval, const char * eval_str, const char * func, const char * file, int line ); - void real_fail_null ( const void * eval, const char * eval_str, const char * func, const char * file, int line ); - void real_fail_if ( bool eval, const char * eval_str, const char * func, const char * file, int line ); - - extern void sigpipe_clear( ); - extern int sigpipe_get( ); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/modules/kino/factory.c b/src/modules/kino/factory.c deleted file mode 100644 index 13e8def..0000000 --- a/src/modules/kino/factory.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -extern mlt_producer producer_kino_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( producer_type, "kino", producer_kino_init ); -} diff --git a/src/modules/kino/filehandler.cc b/src/modules/kino/filehandler.cc deleted file mode 100644 index e5e552c..0000000 --- a/src/modules/kino/filehandler.cc +++ /dev/null @@ -1,941 +0,0 @@ -/* -* filehandler.cc -- saving DV data into different file formats -* Copyright (C) 2000 Arne Schirmacher -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "config.h" - -extern "C" { -#include -} - -#include -#include -#include -#include - -using std::cerr; -using std::endl; -using std::ostringstream; -using std::setw; -using std::setfill; - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// libdv header files -#ifdef HAVE_LIBDV -#include -#endif - -#include "filehandler.h" -#include "error.h" -#include "riff.h" -#include "avi.h" - -FileTracker *FileTracker::instance = NULL; - -FileTracker::FileTracker( ) : mode( CAPTURE_MOVIE_APPEND ) -{ - cerr << ">> Constructing File Capture tracker" << endl; -} - -FileTracker::~FileTracker( ) -{ - cerr << ">> Destroying File Capture tracker" << endl; -} - -FileTracker &FileTracker::GetInstance( ) -{ - if ( instance == NULL ) - instance = new FileTracker(); - - return *instance; -} - -void FileTracker::SetMode( FileCaptureMode mode ) -{ - this->mode = mode; -} - -FileCaptureMode FileTracker::GetMode( ) -{ - return this->mode; -} - -char *FileTracker::Get( int index ) -{ - return list[ index ]; -} - -void FileTracker::Add( const char *file ) -{ - if ( this->mode != CAPTURE_IGNORE ) - { - cerr << ">>>> Registering " << file << " with the tracker" << endl; - list.push_back( strdup( file ) ); - } -} - -unsigned int FileTracker::Size( ) -{ - return list.size(); -} - -void FileTracker::Clear( ) -{ - while ( Size() > 0 ) - { - free( list[ Size() - 1 ] ); - list.pop_back( ); - } - this->mode = CAPTURE_MOVIE_APPEND; -} - -FileHandler::FileHandler() : done( false ), autoSplit( false ), maxFrameCount( 999999 ), - framesWritten( 0 ), filename( "" ) -{ - /* empty body */ -} - - -FileHandler::~FileHandler() -{ - /* empty body */ -} - - -bool FileHandler::GetAutoSplit() const -{ - return autoSplit; -} - - -bool FileHandler::GetTimeStamp() const -{ - return timeStamp; -} - - -string FileHandler::GetBaseName() const -{ - return base; -} - - -string FileHandler::GetExtension() const -{ - return extension; -} - - -int FileHandler::GetMaxFrameCount() const -{ - return maxFrameCount; -} - -off_t FileHandler::GetMaxFileSize() const -{ - return maxFileSize; -} - -string FileHandler::GetFilename() const -{ - return filename; -} - - -void FileHandler::SetAutoSplit( bool flag ) -{ - autoSplit = flag; -} - - -void FileHandler::SetTimeStamp( bool flag ) -{ - timeStamp = flag; -} - - -void FileHandler::SetBaseName( const string& s ) -{ - base = s; -} - - -void FileHandler::SetMaxFrameCount( int count ) -{ - assert( count >= 0 ); - maxFrameCount = count; -} - - -void FileHandler::SetEveryNthFrame( int every ) -{ - assert ( every > 0 ); - - everyNthFrame = every; -} - - -void FileHandler::SetMaxFileSize( off_t size ) -{ - assert ( size >= 0 ); - maxFileSize = size; -} - - -#if 0 -void FileHandler::SetSampleFrame( const Frame& sample ) -{ - /* empty body */ -} -#endif - -bool FileHandler::Done() -{ - return done; -} - -#if 0 -bool FileHandler::WriteFrame( const Frame& frame ) -{ - static TimeCode prevTimeCode; - TimeCode timeCode; - - /* If the user wants autosplit, start a new file if a - new recording is detected. */ - prevTimeCode.sec = -1; - frame.GetTimeCode( timeCode ); - int time_diff = timeCode.sec - prevTimeCode.sec; - bool discontinuity = prevTimeCode.sec != -1 && ( time_diff > 1 || ( time_diff < 0 && time_diff > -59 ) ); - if ( FileIsOpen() && GetAutoSplit() == true && ( frame.IsNewRecording() || discontinuity ) ) - { - Close(); - } - - if ( FileIsOpen() == false ) - { - - string filename; - static int counter = 0; - - if ( GetTimeStamp() == true ) - { - ostringstream sb, sb2; - struct tm date; - string recDate; - - if ( ! frame.GetRecordingDate( date ) ) - { - struct timeval tv; - struct timezone tz; - gettimeofday( &tv, &tz ); - localtime_r( static_cast< const time_t * >( &tv.tv_sec ), &date ); - } - sb << setfill( '0' ) - << setw( 4 ) << date.tm_year + 1900 << '.' - << setw( 2 ) << date.tm_mon + 1 << '.' - << setw( 2 ) << date.tm_mday << '_' - << setw( 2 ) << date.tm_hour << '-' - << setw( 2 ) << date.tm_min << '-' - << setw( 2 ) << date.tm_sec; - recDate = sb.str(); - sb2 << GetBaseName() << recDate << GetExtension(); - filename = sb2.str(); - cerr << ">>> Trying " << filename << endl; - } - else - { - struct stat stats; - do - { - ostringstream sb; - sb << GetBaseName() << setfill( '0' ) << setw( 3 ) << ++ counter << GetExtension(); - filename = sb.str(); - cerr << ">>> Trying " << filename << endl; - } - while ( stat( filename.c_str(), &stats ) == 0 ); - } - - SetSampleFrame( frame ); - if ( Create( filename ) == false ) - { - cerr << ">>> Error creating file!" << endl; - return false; - } - framesWritten = 0; - framesToSkip = 0; - } - - /* write frame */ - - if ( framesToSkip == 0 ) - { - if ( 0 > Write( frame ) ) - { - cerr << ">>> Error writing frame!" << endl; - return false; - } - framesToSkip = everyNthFrame; - ++framesWritten; - } - framesToSkip--; - - /* If the frame count is exceeded, close the current file. - If the autosplit flag is set, a new file will be created in the next iteration. - If the flag is not set, we are done. */ - - if ( ( GetMaxFrameCount() > 0 ) && - ( framesWritten >= GetMaxFrameCount() ) ) - { - Close(); - done = !GetAutoSplit(); - } - - /* If the file size could be exceeded by another frame, close the current file. - If the autosplit flag is set, a new file will be created on the next iteration. - If the flag is not set, we are done. */ - /* not exact, but should be good enough to prevent going over. */ - if ( FileIsOpen() ) - { - AudioInfo info; - frame.GetAudioInfo( info ); - if ( ( GetFileSize() > 0 ) && ( GetMaxFileSize() > 0 ) && - ( GetFileSize() + frame.GetFrameSize() + info.samples * 4 + 12 ) - >= GetMaxFileSize() ) - { // 12 = sizeof chunk metadata - Close(); - done = !GetAutoSplit(); - } - } - prevTimeCode.sec = timeCode.sec; - return true; -} -#endif - -RawHandler::RawHandler() : fd( -1 ) -{ - extension = ".dv"; -} - - -RawHandler::~RawHandler() -{ - Close(); -} - - -bool RawHandler::FileIsOpen() -{ - return fd != -1; -} - - -bool RawHandler::Create( const string& filename ) -{ - fd = open( filename.c_str(), O_CREAT | O_TRUNC | O_RDWR | O_NONBLOCK, 0644 ); - if ( fd != -1 ) - { - FileTracker::GetInstance().Add( filename.c_str() ); - this->filename = filename; - } - return ( fd != -1 ); -} - - -#if 0 -int RawHandler::Write( const Frame& frame ) -{ - int result = write( fd, frame.data, frame.GetFrameSize() ); - return result; -} -#endif - -int RawHandler::Close() -{ - if ( fd != -1 ) - { - close( fd ); - fd = -1; - } - return 0; -} - - -off_t RawHandler::GetFileSize() -{ - struct stat file_status; - fstat( fd, &file_status ); - return file_status.st_size; -} - -int RawHandler::GetTotalFrames() -{ - return GetFileSize() / ( 480 * numBlocks ); -} - - -bool RawHandler::Open( const char *s ) -{ - unsigned char data[ 4 ]; - assert( fd == -1 ); - fd = open( s, O_RDONLY | O_NONBLOCK ); - if ( fd < 0 ) - return false; - if ( read( fd, data, 4 ) < 0 ) - return false; - lseek( fd, 0, SEEK_SET ); - numBlocks = ( ( data[ 3 ] & 0x80 ) == 0 ) ? 250 : 300; - filename = s; - return true; - -} - -int RawHandler::GetFrame( uint8_t *data, int frameNum ) -{ - assert( fd != -1 ); - int size = 480 * numBlocks; - if ( frameNum < 0 ) - return -1; - off_t offset = ( ( off_t ) frameNum * ( off_t ) size ); - fail_if( lseek( fd, offset, SEEK_SET ) == ( off_t ) - 1 ); - if ( read( fd, data, size ) > 0 ) - return 0; - else - return -1; -} - - -/***************************************************************************/ - - -AVIHandler::AVIHandler( int format ) : avi( NULL ), aviFormat( format ), isOpenDML( false ), - fccHandler( make_fourcc( "dvsd" ) ), channels( 2 ), isFullyInitialized( false ), - audioBuffer( NULL ) -{ - extension = ".avi"; - for ( int c = 0; c < 4; c++ ) - audioChannels[ c ] = NULL; -} - - -AVIHandler::~AVIHandler() -{ - if ( audioBuffer != NULL ) - { - delete audioBuffer; - audioBuffer = NULL; - } - for ( int c = 0; c < 4; c++ ) - { - if ( audioChannels[ c ] != NULL ) - { - delete audioChannels[ c ]; - audioChannels[ c ] = NULL; - } - } - - delete avi; -} - -#if 0 -void AVIHandler::SetSampleFrame( const Frame& sample ) -{ - Pack pack; - sample.GetAudioInfo( audioInfo ); - sample.GetVideoInfo( videoInfo ); - - sample.GetAAUXPack( 0x50, pack ); - dvinfo.dwDVAAuxSrc = *( DWORD* ) ( pack.data + 1 ); - sample.GetAAUXPack( 0x51, pack ); - dvinfo.dwDVAAuxCtl = *( DWORD* ) ( pack.data + 1 ); - - sample.GetAAUXPack( 0x52, pack ); - dvinfo.dwDVAAuxSrc1 = *( DWORD* ) ( pack.data + 1 ); - sample.GetAAUXPack( 0x53, pack ); - dvinfo.dwDVAAuxCtl1 = *( DWORD* ) ( pack.data + 1 ); - - sample.GetVAUXPack( 0x60, pack ); - dvinfo.dwDVVAuxSrc = *( DWORD* ) ( pack.data + 1 ); - sample.GetVAUXPack( 0x61, pack ); - dvinfo.dwDVVAuxCtl = *( DWORD* ) ( pack.data + 1 ); - -#ifdef WITH_LIBDV - - if ( sample.decoder->std == e_dv_std_smpte_314m ) - fccHandler = make_fourcc( "dv25" ); -#endif -} -#endif - -bool AVIHandler::FileIsOpen() -{ - return avi != NULL; -} - - -bool AVIHandler::Create( const string& filename ) -{ - assert( avi == NULL ); - - switch ( aviFormat ) - { - - case AVI_DV1_FORMAT: - fail_null( avi = new AVI1File ); - if ( avi->Create( filename.c_str() ) == false ) - return false; - //avi->Init( videoInfo.isPAL ? AVI_PAL : AVI_NTSC, audioInfo.frequency, AVI_LARGE_INDEX ); - break; - - case AVI_DV2_FORMAT: - fail_null( avi = new AVI2File ); - if ( avi->Create( filename.c_str() ) == false ) - return false; - //if ( GetOpenDML() ) - //avi->Init( videoInfo.isPAL ? AVI_PAL : AVI_NTSC, audioInfo.frequency, - //( AVI_SMALL_INDEX | AVI_LARGE_INDEX ) ); - //else - //avi->Init( videoInfo.isPAL ? AVI_PAL : AVI_NTSC, audioInfo.frequency, - //( AVI_SMALL_INDEX ) ); - break; - - default: - assert( aviFormat == AVI_DV1_FORMAT || aviFormat == AVI_DV2_FORMAT ); - } - - avi->setDVINFO( dvinfo ); - avi->setFccHandler( make_fourcc( "iavs" ), fccHandler ); - avi->setFccHandler( make_fourcc( "vids" ), fccHandler ); - this->filename = filename; - FileTracker::GetInstance().Add( filename.c_str() ); - return ( avi != NULL ); -} - -#if 0 -int AVIHandler::Write( const Frame& frame ) -{ - assert( avi != NULL ); - try - { - return avi->WriteFrame( frame ) ? 0 : -1; - } - catch (...) - { - return -1; - } -} -#endif - -int AVIHandler::Close() -{ - if ( avi != NULL ) - { - avi->WriteRIFF(); - delete avi; - avi = NULL; - } - if ( audioBuffer != NULL ) - { - delete audioBuffer; - audioBuffer = NULL; - } - for ( int c = 0; c < 4; c++ ) - { - if ( audioChannels[ c ] != NULL ) - { - delete audioChannels[ c ]; - audioChannels[ c ] = NULL; - } - } - isFullyInitialized = false; - return 0; -} - -off_t AVIHandler::GetFileSize() -{ - return avi->GetFileSize(); -} - -int AVIHandler::GetTotalFrames() -{ - return avi->GetTotalFrames(); -} - - -bool AVIHandler::Open( const char *s ) -{ - assert( avi == NULL ); - fail_null( avi = new AVI1File ); - if ( avi->Open( s ) ) - { - avi->ParseRIFF(); - if ( ! ( - avi->verifyStreamFormat( make_fourcc( "dvsd" ) ) || - avi->verifyStreamFormat( make_fourcc( "DVSD" ) ) || - avi->verifyStreamFormat( make_fourcc( "dvcs" ) ) || - avi->verifyStreamFormat( make_fourcc( "DVCS" ) ) || - avi->verifyStreamFormat( make_fourcc( "dvcp" ) ) || - avi->verifyStreamFormat( make_fourcc( "DVCP" ) ) || - avi->verifyStreamFormat( make_fourcc( "CDVC" ) ) || - avi->verifyStreamFormat( make_fourcc( "cdvc" ) ) || - avi->verifyStreamFormat( make_fourcc( "DV25" ) ) || - avi->verifyStreamFormat( make_fourcc( "dv25" ) ) ) ) - return false; - avi->ReadIndex(); - if ( avi->verifyStream( make_fourcc( "auds" ) ) ) - aviFormat = AVI_DV2_FORMAT; - else - aviFormat = AVI_DV1_FORMAT; - isOpenDML = avi->isOpenDML(); - filename = s; - return true; - } - else - return false; - -} - -int AVIHandler::GetFrame( uint8_t *data, int frameNum ) -{ - int result = avi->GetDVFrame( data, frameNum ); -#if 0 - if ( result == 0 ) - { - /* get the audio from the audio stream, if available */ - if ( aviFormat == AVI_DV2_FORMAT ) - { - WAVEFORMATEX wav; - - if ( ! isFullyInitialized && - avi->getStreamFormat( ( void* ) &wav, make_fourcc( "auds" ) ) ) - { - if ( channels > 0 && channels < 5 ) - { - // Allocate interleaved audio buffer - audioBuffer = new int16_t[ 2 * DV_AUDIO_MAX_SAMPLES * channels ]; - - // Allocate non-interleaved audio buffers - for ( int c = 0; c < channels; c++ ) - audioChannels[ c ] = new int16_t[ 2 * DV_AUDIO_MAX_SAMPLES ]; - - // Get the audio parameters from AVI for subsequent calls to method - audioInfo.channels = wav.nChannels; - audioInfo.frequency = wav.nSamplesPerSec; - - // Skip initialization on subsequent calls to method - isFullyInitialized = true; - cerr << ">>> using audio from separate AVI audio stream" << endl; - } - } - - // Get the frame from AVI - int n = avi->getFrame( audioBuffer, frameNum, make_fourcc( "01wb" ) ); - if ( n > 0 ) - { - // Temporary pointer to audio scratch buffer - int16_t * s = audioBuffer; - - // Determine samples in this frame - audioInfo.samples = n / audioInfo.channels / sizeof( int16_t ); - - // Convert interleaved audio into non-interleaved - for ( int n = 0; n < audioInfo.samples; ++n ) - for ( int i = 0; i < audioInfo.channels; i++ ) - audioChannels[ i ][ n ] = *s++; - - // Write interleaved audio into frame - frame.EncodeAudio( audioInfo, audioChannels ); - } - } - - // Parse important metadata in DV bitstream - frame.ExtractHeader(); - } -#endif - return result; -} - - -void AVIHandler::SetOpenDML( bool flag ) -{ - isOpenDML = flag; -} - - -bool AVIHandler::GetOpenDML() const -{ - return isOpenDML; -} - - -/***************************************************************************/ - -#ifdef HAVE_LIBQUICKTIME - -#ifndef HAVE_LIBDV -#define DV_AUDIO_MAX_SAMPLES 1944 -#endif - -// Missing fourcc's in libquicktime (allows compilation) -#ifndef QUICKTIME_DV_AVID -#define QUICKTIME_DV_AVID "AVdv" -#endif - -#ifndef QUICKTIME_DV_AVID_A -#define QUICKTIME_DV_AVID_A "dvcp" -#endif - -#ifndef QUICKTIME_DVCPRO -#define QUICKTIME_DVCPRO "dvpp" -#endif - -QtHandler::QtHandler() : fd( NULL ) -{ - extension = ".mov"; - Init(); -} - - -QtHandler::~QtHandler() -{ - Close(); -} - -void QtHandler::Init() -{ - if ( fd != NULL ) - Close(); - - fd = NULL; - samplingRate = 0; - samplesPerBuffer = 0; - channels = 2; - audioBuffer = NULL; - audioChannelBuffer = NULL; - isFullyInitialized = false; -} - - -bool QtHandler::FileIsOpen() -{ - return fd != NULL; -} - - -bool QtHandler::Create( const string& filename ) -{ - Init(); - - if ( open( filename.c_str(), O_CREAT | O_TRUNC | O_RDWR | O_NONBLOCK, 0644 ) != -1 ) - { - fd = quicktime_open( const_cast( filename.c_str() ), 0, 1 ); - if ( fd != NULL ) - FileTracker::GetInstance().Add( filename.c_str() ); - } - else - return false; - this->filename = filename; - return true; -} - -void QtHandler::AllocateAudioBuffers() -{ - if ( channels > 0 && channels < 5 ) - { - audioBufferSize = DV_AUDIO_MAX_SAMPLES * 2; - audioBuffer = new int16_t[ audioBufferSize * channels ]; - - audioChannelBuffer = new short int * [ channels ]; - for ( int c = 0; c < channels; c++ ) - audioChannelBuffer[ c ] = new short int[ audioBufferSize ]; - isFullyInitialized = true; - } -} - -inline void QtHandler::DeinterlaceStereo16( void* pInput, int iBytes, - void* pLOutput, void* pROutput ) -{ - short int * piSampleInput = ( short int* ) pInput; - short int* piSampleLOutput = ( short int* ) pLOutput; - short int* piSampleROutput = ( short int* ) pROutput; - - while ( ( char* ) piSampleInput < ( ( char* ) pInput + iBytes ) ) - { - *piSampleLOutput++ = *piSampleInput++; - *piSampleROutput++ = *piSampleInput++; - } -} - -#if 0 -int QtHandler::Write( const Frame& frame ) -{ - if ( ! isFullyInitialized ) - { - AudioInfo audio; - - if ( frame.GetAudioInfo( audio ) ) - { - channels = 2; - quicktime_set_audio( fd, channels, audio.frequency, 16, QUICKTIME_TWOS ); - } - else - { - channels = 0; - } - - quicktime_set_video( fd, 1, 720, frame.IsPAL() ? 576 : 480, - frame.GetFrameRate(), QUICKTIME_DV ); - AllocateAudioBuffers(); - } - - int result = quicktime_write_frame( fd, const_cast( frame.data ), - frame.GetFrameSize(), 0 ); - - if ( channels > 0 ) - { - AudioInfo audio; - if ( frame.GetAudioInfo( audio ) && ( unsigned int ) audio.samples < audioBufferSize ) - { - long bytesRead = frame.ExtractAudio( audioBuffer ); - - DeinterlaceStereo16( audioBuffer, bytesRead, - audioChannelBuffer[ 0 ], - audioChannelBuffer[ 1 ] ); - - quicktime_encode_audio( fd, audioChannelBuffer, NULL, audio.samples ); - } - } - return result; -} -#endif - -int QtHandler::Close() -{ - if ( fd != NULL ) - { - quicktime_close( fd ); - fd = NULL; - } - if ( audioBuffer != NULL ) - { - delete audioBuffer; - audioBuffer = NULL; - } - if ( audioChannelBuffer != NULL ) - { - for ( int c = 0; c < channels; c++ ) - delete audioChannelBuffer[ c ]; - delete audioChannelBuffer; - audioChannelBuffer = NULL; - } - return 0; -} - - -off_t QtHandler::GetFileSize() -{ - struct stat file_status; - stat( filename.c_str(), &file_status ); - return file_status.st_size; -} - - -int QtHandler::GetTotalFrames() -{ - return ( int ) quicktime_video_length( fd, 0 ); -} - - -bool QtHandler::Open( const char *s ) -{ - Init(); - - fd = quicktime_open( s, 1, 0 ); - if ( fd == NULL ) - { - fprintf( stderr, "Error opening: %s\n", s ); - return false; - } - - if ( quicktime_has_video( fd ) <= 0 ) - { - fprintf( stderr, "There must be at least one video track in the input file (%s).\n", - s ); - Close(); - return false; - } - char * fcc = quicktime_video_compressor( fd, 0 ); - if ( strncmp( fcc, QUICKTIME_DV, 4 ) != 0 && - strncmp( fcc, QUICKTIME_DV_AVID, 4 ) != 0 && - strncmp( fcc, QUICKTIME_DV_AVID_A, 4 ) != 0 && - strncmp( fcc, QUICKTIME_DVCPRO, 4 ) != 0 ) - { - Close(); - return false; - } - if ( quicktime_has_audio( fd ) ) - channels = quicktime_track_channels( fd, 0 ); - filename = s; - return true; -} - -int QtHandler::GetFrame( uint8_t *data, int frameNum ) -{ - assert( fd != NULL ); - - quicktime_set_video_position( fd, frameNum, 0 ); - quicktime_read_frame( fd, data, 0 ); - -#ifdef HAVE_LIBDV - if ( quicktime_has_audio( fd ) ) - { - if ( ! isFullyInitialized ) - AllocateAudioBuffers(); - - // Fetch the frequency of the audio track and calc number of samples needed - int frequency = quicktime_sample_rate( fd, 0 ); - float fps = ( data[ 3 ] & 0x80 ) ? 25.0f : 29.97f; - int samples = mlt_sample_calculator( fps, frequency, frameNum ); - int64_t seek = mlt_sample_calculator_to_now( fps, frequency, frameNum ); - - // Obtain a dv encoder and initialise it with minimal info - dv_encoder_t *encoder = dv_encoder_new( 0, 0, 0 ); - encoder->isPAL = ( data[ 3 ] & 0x80 ); - encoder->samples_this_frame = samples; - - // Seek to the calculated position and decode - quicktime_set_audio_position( fd, seek, 0 ); - lqt_decode_audio( fd, audioChannelBuffer, NULL, (long) samples ); - - // Encode the audio on the frame and done - dv_encode_full_audio( encoder, audioChannelBuffer, channels, frequency, data ); - dv_encoder_free( encoder ); - } -#endif - - return 0; -} -#endif diff --git a/src/modules/kino/filehandler.h b/src/modules/kino/filehandler.h deleted file mode 100644 index d7292ab..0000000 --- a/src/modules/kino/filehandler.h +++ /dev/null @@ -1,217 +0,0 @@ -/* -* filehandler.h -* Copyright (C) 2000 Arne Schirmacher -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef _FILEHANDLER_H -#define _FILEHANDLER_H - -// enum { PAL_FORMAT, NTSC_FORMAT, AVI_DV1_FORMAT, AVI_DV2_FORMAT, QT_FORMAT, RAW_FORMAT, TEST_FORMAT, UNDEFINED }; - -#include -using std::vector; - -#include -using std::string; - -#include "riff.h" -#include "avi.h" -#include -#include - -enum { AVI, PLAYLIST, RAW_DV, QT, UNKNOWN_FORMAT }; -enum { PAL_FORMAT, NTSC_FORMAT, AVI_DV1_FORMAT, AVI_DV2_FORMAT, QT_FORMAT, RAW_FORMAT, TEST_FORMAT, UNDEFINED }; -enum { DISPLAY_XX, DISPLAY_GDKRGB, DISPLAY_GDKRGB32, DISPLAY_XV, DISPLAY_SDL }; - -enum { NORM_UNSPECIFIED=0, NORM_PAL=1, NORM_NTSC=2 }; -enum { AUDIO_32KHZ=0, AUDIO_44KHZ=1, AUDIO_48KHZ=2 }; -enum { ASPECT_43=0, ASPECT_169=1 }; - -enum FileCaptureMode { - CAPTURE_IGNORE, - CAPTURE_FRAME_APPEND, - CAPTURE_FRAME_INSERT, - CAPTURE_MOVIE_APPEND -}; - -class FileTracker -{ -protected: - FileTracker(); - ~FileTracker(); -public: - static FileTracker &GetInstance( ); - void SetMode( FileCaptureMode ); - FileCaptureMode GetMode( ); - unsigned int Size(); - char *Get( int ); - void Add( const char * ); - void Clear( ); -private: - static FileTracker *instance; - vector list; - FileCaptureMode mode; -}; - -class FileHandler -{ -public: - - FileHandler(); - virtual ~FileHandler(); - - virtual bool GetAutoSplit() const; - virtual bool GetTimeStamp() const; - virtual string GetBaseName() const; - virtual string GetExtension() const; - virtual int GetMaxFrameCount() const; - virtual off_t GetMaxFileSize() const; - virtual off_t GetFileSize() = 0; - virtual int GetTotalFrames() = 0; - virtual string GetFilename() const; - - virtual void SetAutoSplit( bool ); - virtual void SetTimeStamp( bool ); - virtual void SetBaseName( const string& base ); - virtual void SetMaxFrameCount( int ); - virtual void SetEveryNthFrame( int ); - virtual void SetMaxFileSize( off_t ); - //virtual void SetSampleFrame( const Frame& sample ); - - //virtual bool WriteFrame( const Frame& frame ); - virtual bool FileIsOpen() = 0; - virtual bool Create( const string& filename ) = 0; - //virtual int Write( const Frame& frame ) = 0; - virtual int Close() = 0; - virtual bool Done( void ); - - virtual bool Open( const char *s ) = 0; - virtual int GetFrame( uint8_t *data, int frameNum ) = 0; - int GetFramesWritten() const - { - return framesWritten; - } - -protected: - bool done; - bool autoSplit; - bool timeStamp; - int maxFrameCount; - int framesWritten; - int everyNthFrame; - int framesToSkip; - off_t maxFileSize; - string base; - string extension; - string filename; -}; - - -class RawHandler: public FileHandler -{ -public: - int fd; - - RawHandler(); - ~RawHandler(); - - bool FileIsOpen(); - bool Create( const string& filename ); - //int Write( const Frame& frame ); - int Close(); - off_t GetFileSize(); - int GetTotalFrames(); - bool Open( const char *s ); - int GetFrame( uint8_t *data, int frameNum ); -private: - int numBlocks; -}; - - -class AVIHandler: public FileHandler -{ -public: - AVIHandler( int format = AVI_DV1_FORMAT ); - ~AVIHandler(); - - //void SetSampleFrame( const Frame& sample ); - bool FileIsOpen(); - bool Create( const string& filename ); - //int Write( const Frame& frame ); - int Close(); - off_t GetFileSize(); - int GetTotalFrames(); - bool Open( const char *s ); - int GetFrame( uint8_t *data, int frameNum ); - bool GetOpenDML() const; - void SetOpenDML( bool ); - int GetFormat() const - { - return aviFormat; - } - -protected: - AVIFile *avi; - int aviFormat; - //AudioInfo audioInfo; - //VideoInfo videoInfo; - bool isOpenDML; - DVINFO dvinfo; - FOURCC fccHandler; - int channels; - bool isFullyInitialized; - int16_t *audioBuffer; - int16_t *audioChannels[ 4 ]; -}; - - -#ifdef HAVE_LIBQUICKTIME -#include - -class QtHandler: public FileHandler -{ -public: - QtHandler(); - ~QtHandler(); - - bool FileIsOpen(); - bool Create( const string& filename ); - //int Write( const Frame& frame ); - int Close(); - off_t GetFileSize(); - int GetTotalFrames(); - bool Open( const char *s ); - int GetFrame( uint8_t *data, int frameNum ); - void AllocateAudioBuffers(); - -private: - quicktime_t *fd; - long samplingRate; - int samplesPerBuffer; - int channels; - bool isFullyInitialized; - unsigned int audioBufferSize; - int16_t *audioBuffer; - short int** audioChannelBuffer; - - void Init(); - inline void DeinterlaceStereo16( void* pInput, int iBytes, void* pLOutput, void* pROutput ); - -}; -#endif - -#endif diff --git a/src/modules/kino/gpl b/src/modules/kino/gpl deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/kino/kino_wrapper.cc b/src/modules/kino/kino_wrapper.cc deleted file mode 100644 index dd0e5a5..0000000 --- a/src/modules/kino/kino_wrapper.cc +++ /dev/null @@ -1,111 +0,0 @@ -/* - * kino_wrapper.cc -- c wrapper for kino file handler - * Copyright (C) 2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include - -#include "kino_wrapper.h" -#include "filehandler.h" - -extern "C" -{ - -#include - -struct kino_wrapper_s -{ - FileHandler *handler; - int is_pal; -}; - -kino_wrapper kino_wrapper_init( ) -{ - kino_wrapper self = ( kino_wrapper )malloc( sizeof( kino_wrapper_s ) ); - if ( self != NULL ) - self->handler = NULL; - return self; -} - -int kino_wrapper_open( kino_wrapper self, char *src ) -{ - if ( self != NULL ) - { - // Rough file determination based on file type - if ( strncasecmp( strrchr( src, '.' ), ".avi", 4 ) == 0 ) - self->handler = new AVIHandler( ); - else if ( strncasecmp( strrchr( src, '.' ), ".dv", 3 ) == 0 || strncasecmp( strrchr( src, '.' ), ".dif", 4 ) == 0 ) - self->handler = new RawHandler( ); - #ifdef HAVE_LIBQUICKTIME - else if ( strncasecmp( strrchr( src, '.' ), ".mov", 4 ) == 0 ) - self->handler = new QtHandler( ); - #endif - - // Open the file if we have a handler - if ( self->handler != NULL ) - if ( !self->handler->Open( src ) ) - self = NULL; - - // Check the first frame to see if it's PAL or NTSC - if ( self != NULL && self->handler != NULL ) - { - uint8_t *data = ( uint8_t * )mlt_pool_alloc( 144000 ); - if ( self->handler->GetFrame( data, 0 ) == 0 ) - self->is_pal = data[3] & 0x80; - else - self = NULL; - mlt_pool_release( data ); - } - } - - return kino_wrapper_is_open( self ); -} - -int kino_wrapper_get_frame_count( kino_wrapper self ) -{ - return self != NULL && self->handler != NULL ? self->handler->GetTotalFrames( ) : 0; -} - -int kino_wrapper_is_open( kino_wrapper self ) -{ - return self != NULL && self->handler != NULL ? self->handler->FileIsOpen( ) : 0; -} - -int kino_wrapper_is_pal( kino_wrapper self ) -{ - return self != NULL ? self->is_pal : 0; -} - -int kino_wrapper_get_frame( kino_wrapper self, uint8_t *data, int index ) -{ - return self != NULL && self->handler != NULL ? !self->handler->GetFrame( data, index ) : 0; -} - -void kino_wrapper_close( kino_wrapper self ) -{ - if ( self ) - delete self->handler; - free( self ); -} - -} - - diff --git a/src/modules/kino/kino_wrapper.h b/src/modules/kino/kino_wrapper.h deleted file mode 100644 index 0e73b21..0000000 --- a/src/modules/kino/kino_wrapper.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * kino_wrapper.h -- c wrapper for kino file handler - * Copyright (C) 2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef MLT_PRODUCER_KINO_WRAPPER_H_ -#define MLT_PRODUCER_KINO_WRAPPER_H_ - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -typedef struct kino_wrapper_s *kino_wrapper; - -extern kino_wrapper kino_wrapper_init( ); -extern int kino_wrapper_open( kino_wrapper, char * ); -extern int kino_wrapper_is_open( kino_wrapper ); -extern int kino_wrapper_is_pal( kino_wrapper ); -extern int kino_wrapper_get_frame_count( kino_wrapper ); -extern int kino_wrapper_get_frame( kino_wrapper, uint8_t *, int ); -extern void kino_wrapper_close( kino_wrapper ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/modules/kino/producer_kino.c b/src/modules/kino/producer_kino.c deleted file mode 100644 index 7f94a9e..0000000 --- a/src/modules/kino/producer_kino.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * producer_kino.c -- a DV file format parser - * Copyright (C) 2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include "kino_wrapper.h" - -/* NB: This is an abstract producer - it provides no codec support whatsoever. */ - -#define FRAME_SIZE_525_60 10 * 150 * 80 -#define FRAME_SIZE_625_50 12 * 150 * 80 - -typedef struct producer_kino_s *producer_kino; - -struct producer_kino_s -{ - struct mlt_producer_s parent; - kino_wrapper wrapper; -}; - -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer parent ); - -mlt_producer producer_kino_init( mlt_profile profile, mlt_service_type type, const char *id, char *filename ) -{ - kino_wrapper wrapper = kino_wrapper_init( ); - - if ( kino_wrapper_open( wrapper, filename ) ) - { - producer_kino this = calloc( sizeof( struct producer_kino_s ), 1 ); - - if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) - { - mlt_producer producer = &this->parent; - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - double fps = kino_wrapper_is_pal( wrapper ) ? 25 : 30000.0 / 1001.0; - - // Assign the wrapper - this->wrapper = wrapper; - - // Pass wrapper properties (frame rate, count etc) - mlt_properties_set_position( properties, "length", kino_wrapper_get_frame_count( wrapper ) ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", kino_wrapper_get_frame_count( wrapper ) - 1 ); - mlt_properties_set_double( properties, "real_fps", fps ); - mlt_properties_set( properties, "resource", filename ); - - // Register transport implementation with the producer - producer->close = ( mlt_destructor )producer_close; - - // Register our get_frame implementation with the producer - producer->get_frame = producer_get_frame; - - // Return the producer - return producer; - } - free( this ); - } - - kino_wrapper_close( wrapper ); - - return NULL; -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - producer_kino this = producer->child; - uint8_t *data = mlt_pool_alloc( FRAME_SIZE_625_50 ); - - // Obtain the current frame number - uint64_t position = mlt_producer_frame( producer ); - - // Create an empty frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - // Seek and fetch - if ( kino_wrapper_get_frame( this->wrapper, data, position ) ) - { - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Determine if we're PAL or NTSC - int is_pal = kino_wrapper_is_pal( this->wrapper ); - - // Pass the dv data - mlt_properties_set_data( properties, "dv_data", data, FRAME_SIZE_625_50, ( mlt_destructor )mlt_pool_release, NULL ); - - // Update other info on the frame - mlt_properties_set_int( properties, "width", 720 ); - mlt_properties_set_int( properties, "height", is_pal ? 576 : 480 ); - mlt_properties_set_int( properties, "top_field_first", is_pal ? 0 : ( data[ 5 ] & 0x07 ) == 0 ? 0 : 1 ); - } - else - { - mlt_pool_release( data ); - } - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer parent ) -{ - if ( parent != NULL ) - { - // Obtain this - producer_kino this = parent->child; - - // Close the file - if ( this != NULL ) - kino_wrapper_close( this->wrapper ); - - // Close the parent - parent->close = NULL; - mlt_producer_close( parent ); - - // Free the memory - free( this ); - } -} diff --git a/src/modules/kino/riff.cc b/src/modules/kino/riff.cc deleted file mode 100644 index 44a082c..0000000 --- a/src/modules/kino/riff.cc +++ /dev/null @@ -1,713 +0,0 @@ -/* -* riff.cc library for RIFF file format i/o -* Copyright (C) 2000 - 2002 Arne Schirmacher -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Tag: $Name$ -* -* Change log: -* -* $Log$ -* Revision 1.3 2005/07/25 14:41:29 lilo_booter -* + Minor correction for entry length being less than the data length -* -* Revision 1.2 2005/07/25 07:21:39 lilo_booter -* + fixes for opendml dv avi -* -* Revision 1.1 2005/04/15 14:28:26 lilo_booter -* Initial version -* -* Revision 1.18 2005/04/01 23:43:10 ddennedy -* apply endian fixes from Daniel Kobras -* -* Revision 1.17 2004/10/11 01:37:11 ddennedy -* mutex safety locks in RIFF and AVI classes, type 2 AVI optimization, mencoder export script -* -* Revision 1.16 2003/11/25 23:01:24 ddennedy -* cleanup and a few bugfixes -* -* Revision 1.15 2003/10/21 16:34:34 ddennedy -* GNOME2 port phase 1: initial checkin -* -* Revision 1.13.2.3 2003/08/26 20:39:00 ddennedy -* relocate mutex unlock and add assert includes -* -* Revision 1.13.2.2 2003/01/28 12:54:13 lilo_booter -* New 'no change' image transition -* -* Revision 1.13.2.1 2002/11/25 04:48:31 ddennedy -* bugfix to report errors when loading files -* -* Revision 1.13 2002/09/13 06:49:49 ddennedy -* build update, cleanup, bugfixes -* -* Revision 1.12 2002/04/21 06:36:40 ddennedy -* kindler avc and 1394 bus reset support in catpure page, honor max file size -* -* Revision 1.11 2002/04/09 06:53:42 ddennedy -* cleanup, new libdv 0.9.5, large AVI, dnd storyboard -* -* Revision 1.4 2002/03/25 21:34:25 arne -* Support for large (64 bit) files mostly completed -* -* Revision 1.3 2002/03/10 21:28:29 arne -* release 1.1b1, 64 bit support for type 1 avis -* -* Revision 1.2 2002/03/04 19:22:43 arne -* updated to latest Kino avi code -* -* Revision 1.1.1.1 2002/03/03 19:08:08 arne -* import of version 1.01 -* -*/ - -#include "config.h" - -// C++ includes - -#include -//#include -#include -#include -#ifndef __FreeBSD__ -#include -#endif /* __FreeBSD__ */ - -using std::cout; -using std::hex; -using std::dec; -using std::setw; -using std::setfill; -using std::endl; - -// C includes - -#include -#include -#include - -// local includes - -#include "error.h" -#include "riff.h" - - -/** make a 32 bit "string-id" - - \param s a pointer to 4 chars - \return the 32 bit "string id" - \bugs It is not checked whether we really have 4 characters - - Some compilers understand constants like int id = 'ABCD'; but I - could not get it working on the gcc compiler so I had to use this - workaround. We can now use id = make_fourcc("ABCD") instead. */ - -FOURCC make_fourcc( const char *s ) -{ - if ( s[ 0 ] == 0 ) - return 0; - else - return *( ( FOURCC* ) s ); -} - - -RIFFDirEntry::RIFFDirEntry() -{} - - -RIFFDirEntry::RIFFDirEntry ( FOURCC t, FOURCC n, int l, int o, int p ) : type( t ), name( n ), length( l ), offset( o ), parent( p ), written( 0 ) -{} - - -/** Creates the object without an output file. - -*/ - -RIFFFile::RIFFFile() : fd( -1 ) -{ - pthread_mutex_init( &file_mutex, NULL ); -} - - -/* Copy constructor - - Duplicate the file descriptor -*/ - -RIFFFile::RIFFFile( const RIFFFile& riff ) : fd( -1 ) -{ - if ( riff.fd != -1 ) - { - fd = dup( riff.fd ); - } - directory = riff.directory; -} - - -/** Destroys the object. - - If it has an associated opened file, close it. */ - -RIFFFile::~RIFFFile() -{ - Close(); - pthread_mutex_destroy( &file_mutex ); -} - - -RIFFFile& RIFFFile::operator=( const RIFFFile& riff ) -{ - if ( fd != riff.fd ) - { - Close(); - if ( riff.fd != -1 ) - { - fd = dup( riff.fd ); - } - directory = riff.directory; - } - return *this; -} - - -/** Creates or truncates the file. - - \param s the filename -*/ - -bool RIFFFile::Create( const char *s ) -{ - fd = open( s, O_RDWR | O_NONBLOCK | O_CREAT | O_TRUNC, 00644 ); - - if ( fd == -1 ) - return false; - else - return true; -} - - -/** Opens the file read only. - - \param s the filename -*/ - -bool RIFFFile::Open( const char *s ) -{ - fd = open( s, O_RDONLY | O_NONBLOCK ); - - if ( fd == -1 ) - return false; - else - return true; -} - - -/** Destroys the object. - - If it has an associated opened file, close it. */ - -void RIFFFile::Close() -{ - if ( fd != -1 ) - { - close( fd ); - fd = -1; - } -} - - -/** Adds an entry to the list of containers. - - \param type the type of this entry - \param name the name - \param length the length of the data in the container - \param list the container in which this object is contained. - \return the ID of the newly created entry - - The topmost object is not contained in any other container. Use - the special ID RIFF_NO_PARENT to create the topmost object. */ - -int RIFFFile::AddDirectoryEntry( FOURCC type, FOURCC name, off_t length, int list ) -{ - /* Put all parameters in an RIFFDirEntry object. The offset is - currently unknown. */ - - RIFFDirEntry entry( type, name, length, 0 /* offset */, list ); - - /* If the new chunk is in a list, then get the offset and size - of that list. The offset of this chunk is the end of the list - (parent_offset + parent_length) plus the size of the chunk - header. */ - - if ( list != RIFF_NO_PARENT ) - { - RIFFDirEntry parent = GetDirectoryEntry( list ); - entry.offset = parent.offset + parent.length + RIFF_HEADERSIZE; - } - - /* The list which this new chunk is a member of has now increased in - size. Get that directory entry and bump up its length by the size - of the chunk. Since that list may also be contained in another - list, walk up to the top of the tree. */ - - while ( list != RIFF_NO_PARENT ) - { - RIFFDirEntry parent = GetDirectoryEntry( list ); - parent.length += RIFF_HEADERSIZE + length; - SetDirectoryEntry( list, parent ); - list = parent.parent; - } - - directory.insert( directory.end(), entry ); - - return directory.size() - 1; -} - - -/** Modifies an entry. - - \param i the ID of the entry which is to modify - \param type the type of this entry - \param name the name - \param length the length of the data in the container - \param list the container in which this object is contained. - \note Do not change length, offset, or the parent container. - \note Do not change an empty name ("") to a name and vice versa */ - -void RIFFFile::SetDirectoryEntry( int i, FOURCC type, FOURCC name, off_t length, off_t offset, int list ) -{ - RIFFDirEntry entry( type, name, length, offset, list ); - - assert( i >= 0 && i < ( int ) directory.size() ); - - directory[ i ] = entry; -} - - -/** Modifies an entry. - - The entry.written flag is set to false because the contents has been modified - - \param i the ID of the entry which is to modify - \param entry the new entry - \note Do not change length, offset, or the parent container. - \note Do not change an empty name ("") to a name and vice versa */ - -void RIFFFile::SetDirectoryEntry( int i, RIFFDirEntry &entry ) -{ - assert( i >= 0 && i < ( int ) directory.size() ); - - entry.written = false; - directory[ i ] = entry; -} - - -/** Retrieves an entry. - - Gets the most important member variables. - - \param i the ID of the entry to retrieve - \param type - \param name - \param length - \param offset - \param list */ - -void RIFFFile::GetDirectoryEntry( int i, FOURCC &type, FOURCC &name, off_t &length, off_t &offset, int &list ) const -{ - RIFFDirEntry entry; - - assert( i >= 0 && i < ( int ) directory.size() ); - - entry = directory[ i ]; - type = entry.type; - name = entry.name; - length = entry.length; - offset = entry.offset; - list = entry.parent; -} - - -/** Retrieves an entry. - - Gets the whole RIFFDirEntry object. - - \param i the ID of the entry to retrieve - \return the entry */ - -RIFFDirEntry RIFFFile::GetDirectoryEntry( int i ) const -{ - assert( i >= 0 && i < ( int ) directory.size() ); - - return directory[ i ]; -} - - -/** Calculates the total size of the file - - \return the size the file in bytes -*/ - -off_t RIFFFile::GetFileSize( void ) const -{ - - /* If we have at least one entry, return the length field - of the FILE entry, which is the length of its contents, - which is the actual size of whatever is currently in the - AVI directory structure. - - Note that the first entry does not belong to the AVI - file. - - If we don't have any entry, the file size is zero. */ - - if ( directory.size() > 0 ) - return directory[ 0 ].length; - else - return 0; -} - - -/** prints the attributes of the entry - - \param i the ID of the entry to print -*/ - -void RIFFFile::PrintDirectoryEntry ( int i ) const -{ - RIFFDirEntry entry; - RIFFDirEntry parent; - FOURCC entry_name; - FOURCC list_name; - - /* Get all attributes of the chunk object. If it is contained - in a list, get the name of the list too (otherwise the name of - the list is blank). If the chunk object doesn´t have a name (only - LISTs and RIFFs have a name), the name is blank. */ - - entry = GetDirectoryEntry( i ); - if ( entry.parent != RIFF_NO_PARENT ) - { - parent = GetDirectoryEntry( entry.parent ); - list_name = parent.name; - } - else - { - list_name = make_fourcc( " " ); - } - if ( entry.name != 0 ) - { - entry_name = entry.name; - } - else - { - entry_name = make_fourcc( " " ); - } - - /* Print out the ascii representation of type and name, as well as - length and file offset. */ - - cout << hex << setfill( '0' ) << "type: " - << ((char *)&entry.type)[0] - << ((char *)&entry.type)[1] - << ((char *)&entry.type)[2] - << ((char *)&entry.type)[3] - << " name: " - << ((char *)&entry_name)[0] - << ((char *)&entry_name)[1] - << ((char *)&entry_name)[2] - << ((char *)&entry_name)[3] - << " length: 0x" << setw( 12 ) << entry.length - << " offset: 0x" << setw( 12 ) << entry.offset - << " list: " - << ((char *)&list_name)[0] - << ((char *)&list_name)[1] - << ((char *)&list_name)[2] - << ((char *)&list_name)[3] << dec << endl; - - /* print the content itself */ - - PrintDirectoryEntryData( entry ); -} - - -/** prints the contents of the entry - - Prints a readable representation of the contents of an index. - Override this to print out any objects you store in the RIFF file. - - \param entry the entry to print */ - -void RIFFFile::PrintDirectoryEntryData( const RIFFDirEntry &entry ) const - {} - - -/** prints the contents of the whole directory - - Prints a readable representation of the contents of an index. - Override this to print out any objects you store in the RIFF file. - - \param entry the entry to print */ - -void RIFFFile::PrintDirectory() const -{ - int i; - int count = directory.size(); - - for ( i = 0; i < count; ++i ) - PrintDirectoryEntry( i ); -} - - -/** finds the index - - finds the index of a given directory entry type - - \todo inefficient if the directory has lots of items - \param type the type of the entry to find - \param n the zero-based instance of type to locate - \return the index of the found object in the directory, or -1 if not found */ - -int RIFFFile::FindDirectoryEntry ( FOURCC type, int n ) const -{ - int i, j = 0; - int count = directory.size(); - - for ( i = 0; i < count; ++i ) - if ( directory[ i ].type == type ) - { - if ( j == n ) - return i; - j++; - } - - return -1; -} - - -/** Reads all items that are contained in one list - - Read in one chunk and add it to the directory. If the chunk - happens to be of type LIST, then call ParseList recursively for - it. - - \param parent The id of the item to process -*/ - -void RIFFFile::ParseChunk( int parent ) -{ - FOURCC type; - DWORD length; - int typesize; - - /* Check whether it is a LIST. If so, let ParseList deal with it */ - - fail_if( read( fd, &type, sizeof( type ) ) != sizeof( type )); - if ( type == make_fourcc( "LIST" ) ) - { - typesize = (int) -sizeof( type ); - fail_if( lseek( fd, typesize, SEEK_CUR ) == ( off_t ) - 1 ); - ParseList( parent ); - } - - /* it is a normal chunk, create a new directory entry for it */ - - else - { - fail_neg( read( fd, &length, sizeof( length ) ) ); - if ( length & 1 ) - length++; - AddDirectoryEntry( type, 0, length, parent ); - fail_if( lseek( fd, length, SEEK_CUR ) == ( off_t ) - 1 ); - } -} - - -/** Reads all items that are contained in one list - - \param parent The id of the list to process - -*/ - -void RIFFFile::ParseList( int parent ) -{ - FOURCC type; - FOURCC name; - int list; - DWORD length; - off_t pos; - off_t listEnd; - - /* Read in the chunk header (type and length). */ - fail_neg( read( fd, &type, sizeof( type ) ) ); - fail_neg( read( fd, &length, sizeof( length ) ) ); - - if ( length & 1 ) - length++; - - /* The contents of the list starts here. Obtain its offset. The list - name (4 bytes) is already part of the contents). */ - - pos = lseek( fd, 0, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - fail_neg( read( fd, &name, sizeof( name ) ) ); - - /* Add an entry for this list. */ - - list = AddDirectoryEntry( type, name, sizeof( name ), parent ); - - /* Read in any chunks contained in this list. This list is the - parent for all chunks it contains. */ - - listEnd = pos + length; - while ( pos < listEnd ) - { - ParseChunk( list ); - pos = lseek( fd, 0, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - } -} - - -/** Reads the directory structure of the whole RIFF file - -*/ - -void RIFFFile::ParseRIFF( void ) -{ - FOURCC type; - DWORD length; - off_t filesize; - off_t pos; - int container = AddDirectoryEntry( make_fourcc( "FILE" ), make_fourcc( "FILE" ), 0, RIFF_NO_PARENT ); - - pos = lseek( fd, 0, SEEK_SET ); - - /* calculate file size from RIFF header instead from physical file. */ - - while ( ( read( fd, &type, sizeof( type ) ) > 0 ) && - ( read( fd, &length, sizeof( length ) ) > 0 ) && - ( type == make_fourcc( "RIFF" ) ) ) - { - - filesize += length + RIFF_HEADERSIZE; - - fail_if( lseek( fd, pos, SEEK_SET ) == ( off_t ) - 1 ); - ParseList( container ); - pos = lseek( fd, 0, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - } -} - - -/** Reads one item including its contents from the RIFF file - - \param chunk_index The index of the item to write - \param data A pointer to the data - -*/ - -void RIFFFile::ReadChunk( int chunk_index, void *data, off_t data_len ) -{ - RIFFDirEntry entry; - - entry = GetDirectoryEntry( chunk_index ); - pthread_mutex_lock( &file_mutex ); - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, data, entry.length > data_len ? data_len : entry.length ) ); - pthread_mutex_unlock( &file_mutex ); -} - - -/** Writes one item including its contents to the RIFF file - - \param chunk_index The index of the item to write - \param data A pointer to the data - -*/ - -void RIFFFile::WriteChunk( int chunk_index, const void *data ) -{ - RIFFDirEntry entry; - - entry = GetDirectoryEntry( chunk_index ); - pthread_mutex_lock( &file_mutex ); - fail_if( lseek( fd, entry.offset - RIFF_HEADERSIZE, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( write( fd, &entry.type, sizeof( entry.type ) ) ); - DWORD length = entry.length; - fail_neg( write( fd, &length, sizeof( length ) ) ); - fail_neg( write( fd, data, entry.length ) ); - pthread_mutex_unlock( &file_mutex ); - - /* Remember that this entry already has been written. */ - - directory[ chunk_index ].written = true; -} - - -/** Writes out the directory structure - - For all items in the directory list that have not been written - yet, it seeks to the file position where that item should be - stored and writes the type and length field. If the item has a - name, it will also write the name field. - - \note It does not write the contents of any item. Use WriteChunk to do that. */ - -void RIFFFile::WriteRIFF( void ) -{ - int i; - RIFFDirEntry entry; - int count = directory.size(); - - /* Start at the second entry (RIFF), since the first entry (FILE) - is needed only for internal purposes and is not written to the - file. */ - - for ( i = 1; i < count; ++i ) - { - - /* Only deal with entries that haven´t been written */ - - entry = GetDirectoryEntry( i ); - if ( entry.written == false ) - { - - /* A chunk entry consist of its type and length, a list - entry has an additional name. Look up the entry, seek - to the start of the header, which is at the offset of - the data start minus the header size and write out the - items. */ - - fail_if( lseek( fd, entry.offset - RIFF_HEADERSIZE, SEEK_SET ) == ( off_t ) - 1 ) ; - fail_neg( write( fd, &entry.type, sizeof( entry.type ) ) ); - DWORD length = entry.length; - fail_neg( write( fd, &length, sizeof( length ) ) ); - - /* If it has a name, it is a list. Write out the extra name - field. */ - - if ( entry.name != 0 ) - { - fail_neg( write( fd, &entry.name, sizeof( entry.name ) ) ); - } - - /* Remember that this entry already has been written. */ - - directory[ i ].written = true; - } - } -} diff --git a/src/modules/kino/riff.h b/src/modules/kino/riff.h deleted file mode 100644 index 72021fb..0000000 --- a/src/modules/kino/riff.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -* riff.h library for RIFF file format i/o -* Copyright (C) 2000 - 2002 Arne Schirmacher -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Tag: $Name$ -* -* Change log: -* -* $Log$ -* Revision 1.2 2005/07/25 07:21:39 lilo_booter -* + fixes for opendml dv avi -* -* Revision 1.1 2005/04/15 14:28:26 lilo_booter -* Initial version -* -* Revision 1.14 2005/04/01 23:43:10 ddennedy -* apply endian fixes from Daniel Kobras -* -* Revision 1.13 2004/10/11 01:37:11 ddennedy -* mutex safety locks in RIFF and AVI classes, type 2 AVI optimization, mencoder export script -* -* Revision 1.12 2004/01/06 22:53:42 ddennedy -* metadata editing tweaks and bugfixes, new ui elements in preparation for publish functions -* -* Revision 1.11 2003/11/25 23:01:25 ddennedy -* cleanup and a few bugfixes -* -* Revision 1.10 2003/10/21 16:34:34 ddennedy -* GNOME2 port phase 1: initial checkin -* -* Revision 1.8.4.1 2002/11/25 04:48:31 ddennedy -* bugfix to report errors when loading files -* -* Revision 1.8 2002/04/21 06:36:40 ddennedy -* kindler avc and 1394 bus reset support in catpure page, honor max file size -* -* Revision 1.7 2002/04/09 06:53:42 ddennedy -* cleanup, new libdv 0.9.5, large AVI, dnd storyboard -* -* Revision 1.3 2002/03/25 21:34:25 arne -* Support for large (64 bit) files mostly completed -* -* Revision 1.2 2002/03/04 19:22:43 arne -* updated to latest Kino avi code -* -* Revision 1.1.1.1 2002/03/03 19:08:08 arne -* import of version 1.01 -* -*/ - -#ifndef _RIFF_H -#define _RIFF_H 1 - -#include -using std::vector; - -#include - -#include "endian_types.h" - -#define QUADWORD int64_le_t -#define DWORD int32_le_t -#define LONG u_int32_le_t -#define WORD int16_le_t -#define BYTE u_int8_le_t -#define FOURCC u_int32_t // No endian conversion needed. - -#define RIFF_NO_PARENT (-1) -#define RIFF_LISTSIZE (4) -#define RIFF_HEADERSIZE (8) - -#ifdef __cplusplus -extern "C" -{ - FOURCC make_fourcc( const char * s ); -} -#endif - -class RIFFDirEntry -{ -public: - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - int written; - - RIFFDirEntry(); - RIFFDirEntry( FOURCC t, FOURCC n, int l, int o, int p ); -}; - - -class RIFFFile -{ -public: - RIFFFile(); - RIFFFile( const RIFFFile& ); - virtual ~RIFFFile(); - RIFFFile& operator=( const RIFFFile& ); - - virtual bool Open( const char *s ); - virtual bool Create( const char *s ); - virtual void Close(); - virtual int AddDirectoryEntry( FOURCC type, FOURCC name, off_t length, int list ); - virtual void SetDirectoryEntry( int i, FOURCC type, FOURCC name, off_t length, off_t offset, int list ); - virtual void SetDirectoryEntry( int i, RIFFDirEntry &entry ); - virtual void GetDirectoryEntry( int i, FOURCC &type, FOURCC &name, off_t &length, off_t &offset, int &list ) const; - virtual RIFFDirEntry GetDirectoryEntry( int i ) const; - virtual off_t GetFileSize( void ) const; - virtual void PrintDirectoryEntry( int i ) const; - virtual void PrintDirectoryEntryData( const RIFFDirEntry &entry ) const; - virtual void PrintDirectory( void ) const; - virtual int FindDirectoryEntry( FOURCC type, int n = 0 ) const; - virtual void ParseChunk( int parent ); - virtual void ParseList( int parent ); - virtual void ParseRIFF( void ); - virtual void ReadChunk( int chunk_index, void *data, off_t data_len ); - virtual void WriteChunk( int chunk_index, const void *data ); - virtual void WriteRIFF( void ); - -protected: - int fd; - pthread_mutex_t file_mutex; - -private: - vector directory; -}; -#endif diff --git a/src/modules/lumas/Makefile b/src/modules/lumas/Makefile deleted file mode 100644 index 14079e0..0000000 --- a/src/modules/lumas/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -include ../../../config.mak -LDFLAGS= - -all: luma create_lumas - @./create_lumas - -luma: luma.c - -create_lumas: - -depend: - -distclean: - rm -rf PAL NTSC luma - -clean: - rm -f luma - -install: all - install -d $(DESTDIR)$(prefix)/share/mlt/lumas/PAL - install -d $(DESTDIR)$(prefix)/share/mlt/lumas/NTSC - install -m 644 PAL/* $(DESTDIR)$(prefix)/share/mlt/lumas/PAL - install -m 644 NTSC/* $(DESTDIR)$(prefix)/share/mlt/lumas/NTSC diff --git a/src/modules/lumas/configure b/src/modules/lumas/configure deleted file mode 100755 index e9ce870..0000000 --- a/src/modules/lumas/configure +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -if [ "$help" = "1" ] -then - cat << EOF -Luma options: - - --luma-compress - Produce compressed (png) lumas - --luma-8bpp - Produce 8 bit pgm lumas (defaut is 16 bit) - -EOF - -else - - rm -f .8bit .compress .executed - - for i in "$@" - do - case $i in - --luma-compress ) touch .compress ;; - --luma-8bit ) touch .8bit ;; - esac - done - -fi - diff --git a/src/modules/lumas/create_lumas b/src/modules/lumas/create_lumas deleted file mode 100755 index 05a9c06..0000000 --- a/src/modules/lumas/create_lumas +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - -[ \( -d PAL \) -a \( ! $0 -nt .executed \) ] && exit 0 - -bpp=16 -[ -f .8bit ] && bpp=8 - -for i in PAL NTSC -do - mkdir -p $i - rm -f $i/*.pgm $i/*.png - - [ "$i" = "PAL" ] && h=576 || h=480 - ./luma -h $h -bpp $bpp > $i/luma01.pgm - ./luma -h $h -bpp $bpp -bands $h > $i/luma02.pgm - ./luma -h $h -bpp $bpp -hmirror 1 > $i/luma03.pgm - ./luma -h $h -bpp $bpp -bands $h -vmirror 1 > $i/luma04.pgm - ./luma -h $h -bpp $bpp -offset 32768 -dmirror 1 > $i/luma05.pgm - ./luma -h $h -bpp $bpp -offset 32768 -dmirror 1 -flip 1 > $i/luma06.pgm - ./luma -h $h -bpp $bpp -offset 32768 -dmirror 1 -quart 1 > $i/luma07.pgm - ./luma -h $h -bpp $bpp -offset 32768 -dmirror 1 -quart 1 -flip 1 > $i/luma08.pgm - ./luma -h $h -bpp $bpp -bands 12 -rband 0 > $i/luma09.pgm - ./luma -h $h -bpp $bpp -bands 12 -rband 0 -rotate 1 -flop 1 > $i/luma10.pgm - ./luma -h $h -bpp $bpp -bands 12 -rband 1 > $i/luma11.pgm - ./luma -h $h -bpp $bpp -bands 12 -rband 1 -vmirror 1 > $i/luma12.pgm - ./luma -h $h -bpp $bpp -bands 12 -rband 1 -rotate 1 -flop 1 > $i/luma13.pgm - ./luma -h $h -bpp $bpp -bands 12 -rband 1 -rotate 1 -vmirror 1 > $i/luma14.pgm - ./luma -h $h -bpp $bpp -offset 32768 -dmirror 1 -hmirror 1 > $i/luma15.pgm - ./luma -h $h -bpp $bpp -type 1 > $i/luma16.pgm - ./luma -h $h -bpp $bpp -type 1 -bands 2 -rband 1 > $i/luma17.pgm - ./luma -h $h -bpp $bpp -type 2 > $i/luma18.pgm - ./luma -h $h -bpp $bpp -type 2 -quart 1 > $i/luma19.pgm - ./luma -h $h -bpp $bpp -type 2 -quart 1 -flip 1 > $i/luma20.pgm - ./luma -h $h -bpp $bpp -type 2 -quart 1 -bands 2 > $i/luma21.pgm - ./luma -h $h -bpp $bpp -type 3 > $i/luma22.pgm - - if [ -f .compress ] - then - for f in $i/*.pgm - do - convert $f $f.png - rm -f $f - done - fi -done - -touch .executed - diff --git a/src/modules/lumas/luma.c b/src/modules/lumas/luma.c deleted file mode 100644 index 0889612..0000000 --- a/src/modules/lumas/luma.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * luma.c -- image generator for transition_luma - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -typedef struct -{ - int type; - int w; - int h; - int bands; - int rband; - int vmirror; - int hmirror; - int dmirror; - int invert; - int offset; - int flip; - int flop; - int pflip; - int pflop; - int quart; - int rotate; -} -luma; - -void luma_init( luma *this ) -{ - memset( this, 0, sizeof( luma ) ); - this->type = 0; - this->w = 720; - this->h = 576; - this->bands = 1; - this->rband = 0; - this->vmirror = 0; - this->hmirror = 0; - this->dmirror = 0; - this->invert = 0; - this->offset = 0; - this->flip = 0; - this->flop = 0; - this->quart = 0; - this->pflop = 0; - this->pflip = 0; -} - -static inline int sqrti( int n ) -{ - int p = 0; - int q = 1; - int r = n; - int h = 0; - - while( q <= n ) - q = 4 * q; - - while( q != 1 ) - { - q = q / 4; - h = p + q; - p = p / 2; - if ( r >= h ) - { - p = p + q; - r = r - h; - } - } - - return p; -} - -uint16_t *luma_render( luma *this ) -{ - int i = 0; - int j = 0; - int k = 0; - - if ( this->quart ) - { - this->w *= 2; - this->h *= 2; - } - - if ( this->rotate ) - { - int t = this->w; - this->w = this->h; - this->h = t; - } - - int max = ( 1 << 16 ) - 1; - uint16_t *image = malloc( this->w * this->h * sizeof( uint16_t ) ); - uint16_t *end = image + this->w * this->h; - uint16_t *p = image; - uint16_t *r = image; - int lower = 0; - int lpb = this->h / this->bands; - int rpb = max / this->bands; - int direction = 1; - - int half_w = this->w / 2; - int half_h = this->h / 2; - - if ( !this->dmirror && ( this->hmirror || this->vmirror ) ) - rpb *= 2; - - for ( i = 0; i < this->bands; i ++ ) - { - lower = i * rpb; - direction = 1; - - if ( this->rband && i % 2 == 1 ) - { - direction = -1; - lower += rpb; - } - - switch( this->type ) - { - case 1: - { - int length = sqrti( half_w * half_w + lpb * lpb / 4 ); - int value; - int x = 0; - int y = 0; - for ( j = 0; j < lpb; j ++ ) - { - y = j - lpb / 2; - for ( k = 0; k < this->w; k ++ ) - { - x = k - half_w; - value = sqrti( x * x + y * y ); - *p ++ = lower + ( direction * rpb * ( ( max * value ) / length ) / max ) + ( j * this->offset * 2 / lpb ) + ( j * this->offset / lpb ); - } - } - } - break; - - case 2: - { - for ( j = 0; j < lpb; j ++ ) - { - int value = ( ( j * this->w ) / lpb ) - half_w; - if ( value > 0 ) - value = - value; - for ( k = - half_w; k < value; k ++ ) - *p ++ = lower + ( direction * rpb * ( ( max * abs( k ) ) / half_w ) / max ); - for ( k = value; k < abs( value ); k ++ ) - *p ++ = lower + ( direction * rpb * ( ( max * abs( value ) ) / half_w ) / max ) + ( j * this->offset * 2 / lpb ) + ( j * this->offset / lpb ); - for ( k = abs( value ); k < half_w; k ++ ) - *p ++ = lower + ( direction * rpb * ( ( max * abs( k ) ) / half_w ) / max ); - } - } - break; - - case 3: - { - int length; - for ( j = -half_h; j < half_h; j ++ ) - { - if ( j < 0 ) - { - for ( k = - half_w; k < half_w; k ++ ) - { - length = sqrti( k * k + j * j ); - *p ++ = ( max / 4 * k ) / ( length + 1 ); - } - } - else - { - for ( k = half_w; k > - half_w; k -- ) - { - length = sqrti( k * k + j * j ); - *p ++ = ( max / 2 ) + ( max / 4 * k ) / ( length + 1 ); - } - } - } - } - break; - - default: - for ( j = 0; j < lpb; j ++ ) - for ( k = 0; k < this->w; k ++ ) - *p ++ = lower + ( direction * ( rpb * ( ( k * max ) / this->w ) / max ) ) + ( j * this->offset * 2 / lpb ); - break; - } - } - - if ( this->quart ) - { - this->w /= 2; - this->h /= 2; - for ( i = 1; i < this->h; i ++ ) - { - p = image + i * this->w; - r = image + i * 2 * this->w; - j = this->w; - while ( j -- > 0 ) - *p ++ = *r ++; - } - } - - if ( this->dmirror ) - { - for ( i = 0; i < this->h; i ++ ) - { - p = image + i * this->w; - r = end - i * this->w; - j = ( this->w * ( this->h - i ) ) / this->h; - while ( j -- ) - *( -- r ) = *p ++; - } - } - - if ( this->flip ) - { - uint16_t t; - for ( i = 0; i < this->h; i ++ ) - { - p = image + i * this->w; - r = p + this->w; - while( p != r ) - { - t = *p; - *p ++ = *( -- r ); - *r = t; - } - } - } - - if ( this->flop ) - { - uint16_t t; - r = end; - for ( i = 1; i < this->h / 2; i ++ ) - { - p = image + i * this->w; - j = this->w; - while( j -- ) - { - t = *( -- p ); - *p = *( -- r ); - *r = t; - } - } - } - - if ( this->hmirror ) - { - p = image; - while ( p < end ) - { - r = p + this->w; - while ( p != r ) - *( -- r ) = *p ++; - p += this->w / 2; - } - } - - if ( this->vmirror ) - { - p = image; - r = end; - while ( p != r ) - *( -- r ) = *p ++; - } - - if ( this->invert ) - { - p = image; - r = image; - while ( p < end ) - *p ++ = max - *r ++; - } - - if ( this->pflip ) - { - uint16_t t; - for ( i = 0; i < this->h; i ++ ) - { - p = image + i * this->w; - r = p + this->w; - while( p != r ) - { - t = *p; - *p ++ = *( -- r ); - *r = t; - } - } - } - - if ( this->pflop ) - { - uint16_t t; - end = image + this->w * this->h; - r = end; - for ( i = 1; i < this->h / 2; i ++ ) - { - p = image + i * this->w; - j = this->w; - while( j -- ) - { - t = *( -- p ); - *p = *( -- r ); - *r = t; - } - } - } - - if ( this->rotate ) - { - uint16_t *image2 = malloc( this->w * this->h * sizeof( uint16_t ) ); - for ( i = 0; i < this->h; i ++ ) - { - p = image + i * this->w; - r = image2 + this->h - i - 1; - for ( j = 0; j < this->w; j ++ ) - { - *r = *( p ++ ); - r += this->h; - } - } - i = this->w; - this->w = this->h; - this->h = i; - free( image ); - image = image2; - } - - return image; -} - -int main( int argc, char **argv ) -{ - int arg = 1; - int bpp = 8; - - luma this; - uint16_t *image = NULL; - - luma_init( &this ); - - for ( arg = 1; arg < argc - 1; arg ++ ) - { - if ( !strcmp( argv[ arg ], "-bpp" ) ) - bpp = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-type" ) ) - this.type = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-w" ) ) - this.w = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-h" ) ) - this.h = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-bands" ) ) - this.bands = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-rband" ) ) - this.rband = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-hmirror" ) ) - this.hmirror = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-vmirror" ) ) - this.vmirror = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-dmirror" ) ) - this.dmirror = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-offset" ) ) - this.offset = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-invert" ) ) - this.invert = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-flip" ) ) - this.flip = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-flop" ) ) - this.flop = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-pflip" ) ) - this.pflip = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-pflop" ) ) - this.pflop = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-quart" ) ) - this.quart = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-rotate" ) ) - this.rotate = atoi( argv[ ++ arg ] ); - else - fprintf( stderr, "ignoring %s\n", argv[ arg ] ); - } - - if ( bpp != 8 && bpp != 16 ) - { - fprintf( stderr, "Invalid bpp %d\n", bpp ); - return 1; - } - - image = luma_render( &this ); - - if ( bpp == 16 ) - { - uint16_t *end = image + this.w * this.h; - uint16_t *p = image; - uint8_t *q = ( uint8_t * )image; - while ( p < end ) - { - *p ++ = ( *q << 8 ) + *( q + 1 ); - q += 2; - } - printf( "P5\n" ); - printf( "%d %d\n", this.w, this.h ); - printf( "65535\n" ); - fwrite( image, this.w * this.h * sizeof( uint16_t ), 1, stdout ); - } - else - { - uint16_t *end = image + this.w * this.h; - uint16_t *p = image; - uint8_t *q = ( uint8_t * )image; - while ( p < end ) - *q ++ = ( uint8_t )( *p ++ >> 8 ); - printf( "P5\n" ); - printf( "%d %d\n", this.w, this.h ); - printf( "255\n" ); - fwrite( image, this.w * this.h, 1, stdout ); - } - - return 0; -} - diff --git a/src/modules/motion_est/Makefile b/src/modules/motion_est/Makefile deleted file mode 100644 index 953f898..0000000 --- a/src/modules/motion_est/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltmotion_est.so - -OBJS = factory.o \ - filter_motion_est.o \ - filter_crop_detect.o \ - filter_autotrack_rectangle.o \ - arrow_code.o \ - filter_vismv.o \ - producer_slowmotion.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -test: $(TARGET) - ~/mlt-devel/mlt/src/inigo/inigo -filter motion_est -filter vismv -filter benchmark -consumer sdl rescale=none real_time=0 audio_off=1 silent=1 /media/cdrecorder/BBC.The.Private.Life.Of.Plants.Pt5.Living.Together.DivX505.AC3.www.MVGroup.org.uk.avi in=50000 - -hist: $(TARGET) - ~/mlt-devel/mlt/src/inigo/inigo -filter motion_est -filter histogram -consumer sdl rescale=none real_time=0 audio_off=1 silent=1 /media/cdrecorder/BBC.The.Private.Life.Of.Plants.Pt5.Living.Together.DivX505.AC3.www.MVGroup.org.uk.avi in=40000 - - -test2: $(TARGET) - inigo colour:black -filter watermark:"+mello.txt" composite.geometry="0,0:10%x10%;99=90%,90%" composite.out=99 -filter crop_detect -filter motion_est -filter vismv - -realtime: $(TARGET) - ~/mlt-devel/mlt/src/inigo/inigo -filter motion_est -filter vismv -consumer sdl rescale=none /media/cdrecorder/BBC.The.Private.Life.Of.Plants.Pt5.Living.Together.DivX505.AC3.www.MVGroup.org.uk.avi in=30000 - -testhist: $(TARGET) - ~/mlt-devel/mlt/src/inigo/inigo -consumer sdl rescale=none silent=1 -filter motion_est -filter histogram -filter vismv /media/cdrecorder/BBC.The.Private.Life.Of.Plants.Pt5.Living.Together.DivX505.AC3.www.MVGroup.org.uk.avi in=10000 - - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/motion_est/README b/src/modules/motion_est/README deleted file mode 100644 index 5542d3f..0000000 --- a/src/modules/motion_est/README +++ /dev/null @@ -1,97 +0,0 @@ -INTRO: - -This module is designed to provide application agnostic motion estimation. -I wrote it from scratch because I found the other Open Source code to be -limited by their difficulty of reuse. - - -COMPILE: - -To compile this module, you must supply these options to the root configure script: - ---enable-gpl --enable-motion-est - - -EXAMPLES: - -Estimate the motion: - - > inigo -filter motion_est - -To display the motion vectors as pretty arrows: - - > inigo -filter motion_est -filter vismv - -If your using a movie file that contains a crop, you will get better results with this: - - > inigo -filter crop_detect -filter motion_est -filter vismv - -If your computer is unable to do the above examples in real time, try this: - - > inigo -filter motion_est -filter vismv -consumer inigo real_time=0 - -If you'd like to see the motion vectors without the median denoising function, do this: - - > inigo -filter motion_est denoise=0 -filter vismv - -To reconstruct each frame by applying the motion to the previous frame: - - > inigo -filter motion_est show_reconstruction=1 - -To compare the reconstructed frame and the real frame (while paused): - - > inigo -filter motion_est show_reconstruction=1 toggle_when_paused=1 - -To show the difference (residual) between the reconstructed frame the real frame: - - > inigo -filter motion_est show_residual=1 - -To automatically track an object in the frame, try this: - - > inigo -filter autotrack_rectangle:X,Y:WxH debug=1 - -(Where X,Y is the origin of the rectangle indexed from upper left and WxH is the dimensions of the rectangle.) - -To obscure that same object in the frame, try this: - - > inigo -filter autotrack_rectangle:X,Y:WxH obscure=1 - -There is now a slow motion producer that does interpolation based on the motion vectors: - - > inigo slowmotion: _speed=0.1 method=1 debug=1 - -NOTES (and deficiencies): - -1. Ignore shot change detection when your using the autotrack_rectangle filter. - -2. Don't assume motion vectors displayed while stepping backwards and forward are that same vectors - that would be calculated while playing the footage from start to finish, nonstop. Stepping forward - should be fine after a few frames, however. - -3. SSE instructions are lazily assumed. MMX, Altivec, and SIMD-less would be good too. - -4. Motion estimation is only performed in the luma color space. - -5. Motion vectors should have sub-pixel accuracy. - -6. Motion vectors are not serializable yet. - -7. A diligent test suite is needed. (show_reconstruction & show_residual are a start) - -8. Multithreaded code will see HUGE benefits on multi-CPU systems. Donations of a multi-core cpu or a - multi-cpu system to the author will encourage development. - -9. Macroblock sizes are not dynamic (Though settable at runtime.) - -10. Notes (5), (7), and (9) would go a long ways to making this code suitable for a modern video encoder. - -11. Shot change works well but arbitrarily chosen thresholds need to be tuned. - -12. Given the documentation of other motion estimation code bases, I will GLADLY clarify and - document any piece of code upon request. - -13. Considerable effort has been put into the speed. I usually experience 10ms or less per frame for PAL on 2.8GHZ p4. - -Zachary Drew -drew0054@tc.umn.edu - diff --git a/src/modules/motion_est/arrow_code.c b/src/modules/motion_est/arrow_code.c deleted file mode 100644 index 08c0f69..0000000 --- a/src/modules/motion_est/arrow_code.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * /brief Draw arrows - * /author Zachary Drew, Copyright 2004 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include "arrow_code.h" - -#include -#include -#include -#include - -#define MIN(a,b) ((a) > (b) ? (b) : (a)) - -#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - - -static int w; -static int h; -static int xstride; -static int ystride; -static mlt_image_format format; - -int init_arrows( mlt_image_format *image_format, int width, int height ) -{ - w = width; - h = height; - format = *image_format; - switch( *image_format ) { - case mlt_image_yuv422: - xstride = 2; - ystride = xstride * w; - break; - default: - // I don't know - return 0; - } - return 1; - -} - -// ffmpeg borrowed -static inline int clip(int a, int amin, int amax) -{ - if (a < amin) - return amin; - else if (a > amax) - return amax; - else - return a; -} - - -/** - * draws an line from (ex, ey) -> (sx, sy). - * Credits: modified from ffmpeg project - * @param ystride stride/linesize of the image - * @param xstride stride/element size of the image - * @param color color of the arrow - */ -void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, int color) -{ - int t, x, y, fr, f; - - - sx= clip(sx, 0, w-1); - sy= clip(sy, 0, h-1); - ex= clip(ex, 0, w-1); - ey= clip(ey, 0, h-1); - - buf[sy*ystride + sx*xstride]+= color; - - if(ABS(ex - sx) > ABS(ey - sy)){ - if(sx > ex){ - t=sx; sx=ex; ex=t; - t=sy; sy=ey; ey=t; - } - buf+= sx*xstride + sy*ystride; - ex-= sx; - f= ((ey-sy)<<16)/ex; - for(x= 0; x <= ex; x++){ - y = (x*f)>>16; - fr= (x*f)&0xFFFF; - buf[ y *ystride + x*xstride]+= (color*(0x10000-fr))>>16; - buf[(y+1)*ystride + x*xstride]+= (color* fr )>>16; - } - }else{ - if(sy > ey){ - t=sx; sx=ex; ex=t; - t=sy; sy=ey; ey=t; - } - buf+= sx*xstride + sy*ystride; - ey-= sy; - if(ey) f= ((ex-sx)<<16)/ey; - else f= 0; - for(y= 0; y <= ey; y++){ - x = (y*f)>>16; - fr= (y*f)&0xFFFF; - buf[y*ystride + x *xstride]+= (color*(0x10000-fr))>>16;; - buf[y*ystride + (x+1)*xstride]+= (color* fr )>>16;; - } - } -} - -void draw_rectangle_fill(uint8_t *buf, int x, int y, int w, int h, int color) -{ - int i,j; - for ( i = 0; i < w; i++ ) - for ( j = 0; j < h; j++ ) - buf[ (y+j)*ystride + (x+i)*xstride] = color; -} - -void draw_rectangle_outline(uint8_t *buf, int x, int y, int w, int h, int color) -{ - int i,j; - for ( i = 0; i < w; i++ ) { - buf[ y*ystride + (x+i)*xstride ] += color; - buf[ (y+h)*ystride + (x+i)*xstride ] += color; - } - for ( j = 1; j < h+1; j++ ) { - buf[ (y+j)*ystride + x*xstride ] += color; - buf[ (y+j)*ystride + (x+w)*xstride ] += color; - } -} -/** - * draws an arrow from (ex, ey) -> (sx, sy). - * Credits: modified from ffmpeg project - * @param stride stride/linesize of the image - * @param color color of the arrow - */ -void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int ey, int color){ - - int dx,dy; - dx= ex - sx; - dy= ey - sy; - - if(dx*dx + dy*dy > 3*3){ - int rx= dx + dy; - int ry= -dx + dy; - int length= sqrt((rx*rx + ry*ry)<<8); - - rx= ROUNDED_DIV(rx*3<<4, length); - ry= ROUNDED_DIV(ry*3<<4, length); - - draw_line(buf, sx, sy, sx + rx, sy + ry, color); - draw_line(buf, sx, sy, sx - ry, sy + rx, color); - } - draw_line(buf, sx, sy, ex, ey, color); -} diff --git a/src/modules/motion_est/arrow_code.h b/src/modules/motion_est/arrow_code.h deleted file mode 100644 index 0fe5219..0000000 --- a/src/modules/motion_est/arrow_code.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * file: arrow_code.h - * - * /brief Misc functions to draw arrows - * /author Zachary Drew, Copyright 2004 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -extern int init_arrows( mlt_image_format *image_format, int width, int height ); -extern void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, int color); -extern void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int ey, int color); -extern void draw_rectangle_fill(uint8_t *buf, int x, int y, int w, int h, int color); -extern void draw_rectangle_outline(uint8_t *buf, int x, int y, int w, int h, int color); diff --git a/src/modules/motion_est/factory.c b/src/modules/motion_est/factory.c deleted file mode 100644 index 1df0929..0000000 --- a/src/modules/motion_est/factory.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -extern mlt_filter filter_motion_est_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_vismv_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_crop_detect_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_autotrack_rectangle_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_slowmotion_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "motion_est", filter_motion_est_init ); - MLT_REGISTER( filter_type, "vismv", filter_vismv_init ); - MLT_REGISTER( filter_type, "crop_detect", filter_crop_detect_init ); - MLT_REGISTER( filter_type, "autotrack_rectangle", filter_autotrack_rectangle_init ); - MLT_REGISTER( producer_type, "slowmotion", producer_slowmotion_init ); -} diff --git a/src/modules/motion_est/filter_autotrack_rectangle.c b/src/modules/motion_est/filter_autotrack_rectangle.c deleted file mode 100644 index 0d526e4..0000000 --- a/src/modules/motion_est/filter_autotrack_rectangle.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * filter_autotrack_rectangle.c - * - * /brief - * /author Zachary Drew, Copyright 2005 - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "filter_motion_est.h" -#include "arrow_code.h" - -#include - -#include -#include -#include -#include - -#define MIN(a,b) ((a) > (b) ? (b) : (a)) - -#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - -void caculate_motion( struct motion_vector_s *vectors, - mlt_geometry_item boundry, - int macroblock_width, - int macroblock_height, - int mv_buffer_width, - int method, - int width, - int height ) -{ - - - // translate pixel units (from bounds) to macroblock units - // make sure whole macroblock stay within bounds - int left_mb = ( boundry->x + macroblock_width - 1 ) / macroblock_width; - int top_mb = ( boundry->y + macroblock_height - 1 ) / macroblock_height; - int right_mb = ( boundry->x + boundry->w ) / macroblock_width - 1; - int bottom_mb = ( boundry->y + boundry->h ) / macroblock_height - 1; - - int i, j, n = 0; - - int average_x = 0, average_y = 0; - - #define CURRENT ( vectors + j*mv_buffer_width + i ) - - for( i = left_mb; i <= right_mb; i++ ){ - for( j = top_mb; j <= bottom_mb; j++ ) - { - n++; - average_x += CURRENT->dx; - average_y += CURRENT->dy; - } - } - - if ( n == 0 ) return; - - average_x /= n; - average_y /= n; - - n = 0; - int average2_x = 0, average2_y = 0; - for( i = left_mb; i <= right_mb; i++ ){ - for( j = top_mb; j <= bottom_mb; j++ ){ - - if( ABS(CURRENT->dx - average_x) < 3 && - ABS(CURRENT->dy - average_y) < 3 ) - { - n++; - average2_x += CURRENT->dx; - average2_y += CURRENT->dy; - } - } - } - - if ( n == 0 ) return; - - boundry->x -= (double)average2_x / (double)n; - boundry->y -= (double)average2_y / (double)n; - - if ( boundry->x < 0 ) - boundry->x = 0; - - if ( boundry->y < 0 ) - boundry->y = 0; - - if ( boundry->x + boundry->w > width ) - boundry->x = width - boundry->w; - - if ( boundry->y + boundry->h > height ) - boundry->y = height - boundry->h; -} - -// Image stack(able) method -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - // Get the filter object - mlt_filter filter = mlt_frame_pop_service( frame ); - - // Get the filter's property object - mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter); - - // Get the frame properties - mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame); - - // Get the frame position - mlt_position position = mlt_frame_get_position( frame ); - - // Get the new image - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - if( error != 0 ) - mlt_properties_debug( frame_properties, "error after mlt_frame_get_image() in autotrack_rectangle", stderr ); - - // Get the geometry object - mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL); - - // Get the current geometry item - struct mlt_geometry_item_s boundry; - mlt_geometry_fetch(geometry, &boundry, position); - - // Get the motion vectors - struct motion_vector_s *vectors = mlt_properties_get_data( frame_properties, "motion_est.vectors", NULL ); - - // How did the rectangle move? - if( vectors != NULL && - boundry.key != 1 ) // Paused? - { - - int method = mlt_properties_get_int( filter_properties, "method" ); - - // Get the size of macroblocks in pixel units - int macroblock_height = mlt_properties_get_int( frame_properties, "motion_est.macroblock_height" ); - int macroblock_width = mlt_properties_get_int( frame_properties, "motion_est.macroblock_width" ); - int mv_buffer_width = *width / macroblock_width; - - caculate_motion( vectors, &boundry, macroblock_width, macroblock_height, mv_buffer_width, method, *width, *height ); - - - // Make the geometry object a real boy - boundry.key = 1; - boundry.f[0] = 1; - boundry.f[1] = 1; - boundry.f[2] = 1; - boundry.f[3] = 1; - boundry.f[4] = 1; - mlt_geometry_insert(geometry, &boundry); - } - - if( mlt_properties_get_int( filter_properties, "debug" ) == 1 ) - { - init_arrows( format, *width, *height ); - draw_rectangle_outline(*image, boundry.x, boundry.y, boundry.w, boundry.h, 100); - } - - if( mlt_properties_get_int( filter_properties, "obscure" ) == 1 ) - { - mlt_filter obscure = mlt_properties_get_data( filter_properties, "_obscure", NULL ); - - mlt_properties_pass_list( MLT_FILTER_PROPERTIES(obscure), filter_properties, "in, out"); - - // Because filter_obscure needs to be rewritten to use mlt_geometry - char geom[100]; - sprintf( geom, "%d,%d:%dx%d", (int)boundry.x, (int)boundry.y, (int)boundry.w, (int)boundry.h ); - mlt_properties_set( MLT_FILTER_PROPERTIES( obscure ), "start", geom ); - mlt_properties_set( MLT_FILTER_PROPERTIES( obscure ), "end", geom ); - } - - if( mlt_properties_get_int( filter_properties, "collect" ) == 1 ) - { - printf( "%d,%d,%d,%d\n", (int)boundry.x, (int)boundry.y, (int)boundry.w, (int)boundry.h ); - fflush( stdout ); - } - - return error; -} - -static int attach_boundry_to_frame( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the filter object - mlt_filter filter = mlt_frame_pop_service( frame ); - - // Get the filter's property object - mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter); - - // Get the frame properties - mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame); - - // Get the frame position - mlt_position position = mlt_frame_get_position( frame ); - - // Get the geometry object - mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL); - if (geometry == NULL) { - mlt_geometry geom = mlt_geometry_init(); - char *arg = mlt_properties_get(filter_properties, "geometry"); - - // Initialize with the supplied geometry - struct mlt_geometry_item_s item; - mlt_geometry_parse_item( geom, &item, arg ); - - item.frame = 0; - item.key = 1; - item.mix = 100; - - mlt_geometry_insert( geom, &item ); - mlt_properties_set_data( filter_properties, "filter_geometry", geom, 0, (mlt_destructor)mlt_geometry_close, (mlt_serialiser)mlt_geometry_serialise ); - geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL); - } - - // Get the current geometry item - mlt_geometry_item geometry_item = mlt_pool_alloc( sizeof( struct mlt_geometry_item_s ) ); - mlt_geometry_fetch(geometry, geometry_item, position); - - mlt_properties_set_data( frame_properties, "bounds", geometry_item, sizeof( struct mlt_geometry_item_s ), mlt_pool_release, NULL ); - - // Get the new image - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - if( error != 0 ) - mlt_properties_debug( frame_properties, "error after mlt_frame_get_image() in autotrack_rectangle attach_boundry_to_frame", stderr ); - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - /* modify the frame with the current geometry */ - mlt_frame_push_service( frame, this); - mlt_frame_push_get_image( frame, attach_boundry_to_frame ); - - - - /* apply the motion estimation filter */ - mlt_filter motion_est = mlt_properties_get_data( MLT_FILTER_PROPERTIES(this), "_motion_est", NULL ); - mlt_filter_process( motion_est, frame); - - - - /* calculate the new geometry based on the motion */ - mlt_frame_push_service( frame, this); - mlt_frame_push_get_image( frame, filter_get_image ); - - - /* visualize the motion vectors */ - if( mlt_properties_get_int( MLT_FILTER_PROPERTIES(this), "debug" ) == 1 ) - { - mlt_filter vismv = mlt_properties_get_data( MLT_FILTER_PROPERTIES(this), "_vismv", NULL ); - if( vismv == NULL ) - { - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) ); - vismv = mlt_factory_filter( profile, "vismv", NULL ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES(this), "_vismv", vismv, 0, (mlt_destructor)mlt_filter_close, NULL ); - } - - mlt_filter_process( vismv, frame ); - } - - if( mlt_properties_get_int( MLT_FILTER_PROPERTIES(this), "obscure" ) == 1 ) - { - mlt_filter obscure = mlt_properties_get_data( MLT_FILTER_PROPERTIES(this), "_obscure", NULL ); - if( obscure == NULL ) - { - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) ); - obscure = mlt_factory_filter( profile, "obscure", NULL ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES(this), "_obscure", obscure, 0, (mlt_destructor)mlt_filter_close, NULL ); - } - - mlt_filter_process( obscure, frame ); - } - - return frame; -} - -/** Constructor for the filter. -*/ - - -mlt_filter filter_autotrack_rectangle_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - - // Initialize with the supplied geometry if ther is one - if( arg != NULL ) - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "geometry", arg ); - else - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "geometry", "100,100:100x100" ); - - // create an instance of the motion_est and obscure filter - mlt_filter motion_est = mlt_factory_filter( profile, "motion_est", NULL ); - if( motion_est != NULL ) - mlt_properties_set_data( MLT_FILTER_PROPERTIES(this), "_motion_est", motion_est, 0, (mlt_destructor)mlt_filter_close, NULL ); - else { - mlt_filter_close( this ); - return NULL; - } - - - } - - return this; -} - -/** This source code will self destruct in 5...4...3... -*/ diff --git a/src/modules/motion_est/filter_crop_detect.c b/src/modules/motion_est/filter_crop_detect.c deleted file mode 100644 index 8165141..0000000 --- a/src/modules/motion_est/filter_crop_detect.c +++ /dev/null @@ -1,244 +0,0 @@ -/** - * /brief Crop Detection filter - * - * /author Zachary Drew, Copyright 2005 - * - * inspired by mplayer's cropdetect filter - * - * Note: The goemetry generated is zero-indexed and is inclusive of the end values - * - * Options: - * -filter crop_detect debug=1 // Visualize crop - * -filter crop_detect frequency=25 // Detect the crop once a second - * -filter crop_detect frequency=0 // Never detect unless the producer changes - * -filter crop_detect thresh=100 // Changes the threshold (default = 25) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#define DEBUG -#define DEFAULT_THRESH 20 - -#include - -#include -#include -#include -#include -#include "arrow_code.h" - -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - -// Image stack(able) method -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - // Get the filter object and properties - mlt_filter filter = mlt_frame_pop_service( this ); - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - - // Get the new image - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - if( error != 0 ) { - mlt_properties_debug( MLT_FRAME_PROPERTIES(this), "error after mlt_frame_get_image()", stderr ); - return error; - } - - // Parameter that describes how often to check for the crop - int frequency = mlt_properties_get_int( properties, "frequency"); - - // Producers may start with blank footage, by default we will skip, oh, 5 frames unless overridden - int skip = mlt_properties_get_int( properties, "skip"); - - // The result - mlt_geometry_item bounds = mlt_properties_get_data( properties, "bounds", NULL ); - - // Initialize if needed - if( bounds == NULL ) { - bounds = calloc( 1, sizeof( struct mlt_geometry_item_s ) ); - bounds->w = *width; - bounds->h = *height; - mlt_properties_set_data( properties, "bounds", bounds, sizeof( struct mlt_geometry_item_s ), free, NULL ); - } - - // For periodic detection (with offset of 'skip') - if( frequency == 0 || (int)(mlt_frame_get_position(this)+skip) % frequency != 0) - { - // Inject in stream - mlt_properties_set_data( MLT_FRAME_PROPERTIES(this), "bounds", bounds, sizeof( struct mlt_geometry_item_s ), NULL, NULL ); - - return 0; - } - - - // There is no way to detect a crop for sure, so make up an arbitrary one - int thresh = mlt_properties_get_int( properties, "thresh" ); - - int xstride, ystride; - - switch( *format ) { - case mlt_image_yuv422: - xstride = 2; - ystride = 2 * *width; - break; - default: - fprintf(stderr, "image format not supported by filter_crop_detect\n"); - return -1; - } - - int x, y, average_brightness, deviation; // Scratch variables - uint8_t *q; - - // Top crop - for( y = 0; y < *height/2; y++ ) { - bounds->y = y; - average_brightness = 0; - deviation = 0; - q = *image + y*ystride; - for( x = 0; x < *width; x++ ) - average_brightness += q[x*xstride]; - - average_brightness /= *width; - - for( x = 0; x < *width; x++ ) - deviation += abs(average_brightness - q[x*xstride]); - - if( deviation*10 >= thresh * *width ) - break; - } - - // Bottom crop - for( y = *height - 1; y >= *height/2; y-- ) { - bounds->h = y; - average_brightness = 0; - deviation = 0; - q = *image + y*ystride; - for( x = 0; x < *width; x++ ) - average_brightness += q[x*xstride]; - - average_brightness /= *width; - - for( x = 0; x < *width; x++ ) - deviation += abs(average_brightness - q[x*xstride]); - - if( deviation*10 >= thresh * *width) - break; - } - - // Left crop - for( x = 0; x < *width/2; x++ ) { - bounds->x = x; - average_brightness = 0; - deviation = 0; - q = *image + x*xstride; - for( y = 0; y < *height; y++ ) - average_brightness += q[y*ystride]; - - average_brightness /= *height; - - for( y = 0; y < *height; y++ ) - deviation += abs(average_brightness - q[y*ystride]); - - if( deviation*10 >= thresh * *width ) - break; - } - - // Right crop - for( x = *width - 1; x >= *width/2; x-- ) { - bounds->w = x; - average_brightness = 0; - deviation = 0; - q = *image + x*xstride; - for( y = 0; y < *height; y++ ) - average_brightness += q[y*ystride]; - - average_brightness /= *height; - - for( y = 0; y < *height; y++ ) - deviation += abs(average_brightness - q[y*ystride]); - - if( deviation*10 >= thresh * *width ) - break; - } - - /* Debug: Draw arrows to show crop */ - if( mlt_properties_get_int( properties, "debug") == 1 ) - { - init_arrows( format, *width, *height ); - - draw_arrow(*image, bounds->x, *height/2, bounds->x+50, *height/2, 100); - draw_arrow(*image, *width/2, bounds->y, *width/2, bounds->y+50, 100); - draw_arrow(*image, bounds->w, *height/2, bounds->w-50, *height/2, 100); - draw_arrow(*image, *width/2, bounds->h, *width/2, bounds->h-50, 100); - draw_arrow(*image, bounds->x, bounds->y, bounds->x+40, bounds->y+30, 100); - draw_arrow(*image, bounds->x, bounds->h, bounds->x+40, bounds->h-30, 100); - draw_arrow(*image, bounds->w, bounds->y, bounds->w-40, bounds->y+30, 100); - draw_arrow(*image, bounds->w, bounds->h, bounds->w-40, bounds->h-30, 100); - } - - // Convert to width and correct indexing - bounds->w -= bounds->x - 1; - bounds->h -= bounds->y - 1; - - if( mlt_properties_get_int( properties, "debug") == 1 ) - fprintf(stderr, "Top:%f Left:%f Width:%f Height:%f\n", bounds->y, bounds->x, bounds->w, bounds->h); - - /* inject into frame */ - mlt_properties_set_data( MLT_FRAME_PROPERTIES(this), "bounds", bounds, sizeof( struct mlt_geometry_item_s ), NULL, NULL ); - - return error; -} - - - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - // Put the filter object somewhere we can find it - mlt_frame_push_service( frame, this); - - // Push the frame filter - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ -mlt_filter filter_crop_detect_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - - /* defaults */ - mlt_properties_set_int( MLT_FILTER_PROPERTIES(this), "frequency", 1); - mlt_properties_set_int( MLT_FILTER_PROPERTIES(this), "thresh", 5); - mlt_properties_set_int( MLT_FILTER_PROPERTIES(this), "clip", 5); - mlt_properties_set_int( MLT_FILTER_PROPERTIES(this), "former_producer_id", -1); - - } - - return this; -} - -/** This source code will self destruct in 5...4...3... -*/ - diff --git a/src/modules/motion_est/filter_motion_est.c b/src/modules/motion_est/filter_motion_est.c deleted file mode 100644 index 6e8b021..0000000 --- a/src/modules/motion_est/filter_motion_est.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * /brief fast motion estimation filter - * /author Zachary Drew, Copyright 2005 - * - * Currently only uses Gamma data for comparisonon (bug or feature?) - * SSE optimized where available. - * - * Vector orientation: The vector data that is generated for the current frame specifies - * the motion from the previous frame to the current frame. To know how a macroblock - * in the current frame will move in the future, the next frame is needed. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#include "filter_motion_est.h" -#include -#include -#include -#include -#include -#include -#include - -#ifdef USE_SSE -#include "sad_sse.h" -#endif - -#define NDEBUG -#include - -#undef DEBUG -#undef DEBUG_ASM -#undef BENCHMARK -#undef COUNT_COMPARES - -#define DIAMOND_SEARCH 0x0 -#define FULL_SEARCH 0x1 -#define SHIFT 8 -#define MIN(a,b) ((a) > (b) ? (b) : (a)) -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - - -struct motion_est_context_s -{ - int initialized; // true if filter has been initialized - -#ifdef COUNT_COMPARES - int compares; -#endif - - /* same as mlt_frame's parameters */ - int width, height; - - /* Operational details */ - int mb_w, mb_h; - int xstride, ystride; - uint8_t *cache_image; // Copy of current frame - uint8_t *former_image; // Copy of former frame - int search_method; - int skip_prediction; - int shot_change; - int limit_x, limit_y; // max x and y of a motion vector - int initial_thresh; - int check_chroma; // if check_chroma == 1 then compare chroma - int denoise; - int previous_msad; - int show_reconstruction; - int toggle_when_paused; - int show_residual; - - /* bounds */ - struct mlt_geometry_item_s bounds; // Current bounds (from filters crop_detect, autotrack rectangle, or other) - - /* bounds in macroblock units; macroblocks are completely contained within the boundry */ - int left_mb, prev_left_mb, right_mb, prev_right_mb; - int top_mb, prev_top_mb, bottom_mb, prev_bottom_mb; - - /* size of our vector buffers */ - int mv_buffer_height, mv_buffer_width, mv_size; - - /* vector buffers */ - int former_vectors_valid; // right || x2 + *w > right ) - w_remains = right - ((*x > x2) ? *x : x2); - - // Origin of macroblock moves above image boundy - if( *y < top || y2 < top ) { - h_remains = *h - top + ((*y < y2) ? *y : y2); - *y += *h - h_remains; - } - // Portion of macroblock moves bellow image boundry - else if( *y + *h > bottom || y2 + *h > bottom ) - h_remains = bottom - ((*y > y2) ? *y : y2); - - if( w_remains == *w && h_remains == *h ) return penalty; - if( w_remains <= 0 || h_remains <= 0) return 0; // Block is clipped out of existance - penalty = (*w * *h * penalty) - / ( w_remains * h_remains); // Recipricol of the fraction of the block that remains - - assert(*x >= left); assert(x2 + *w - w_remains >= left); - assert(*y >= top); assert(y2 + *h - h_remains >= top); - assert(*x + w_remains <= right); assert(x2 + w_remains <= right); - assert(*y + h_remains <= bottom); assert(y2 + h_remains <= bottom); - - *w = w_remains; // Update the width and height - *h = h_remains; - - return penalty; -} - -/** /brief Reference Sum of Absolute Differences comparison function -* -*/ -static int sad_reference( uint8_t *block1, uint8_t *block2, const int xstride, const int ystride, const int w, const int h ) -{ - int i, j, score = 0; - for ( j = 0; j < h; j++ ){ - for ( i = 0; i < w; i++ ){ - score += ABS( block1[i*xstride] - block2[i*xstride] ); - } - block1 += ystride; - block2 += ystride; - } - - return score; -} - - -/** /brief Abstracted block comparison function -*/ -inline static int block_compare( uint8_t *block1, - uint8_t *block2, - int x, - int y, - int dx, - int dy, - struct motion_est_context_s *c) -{ - -#ifdef COUNT_COMPARES - c->compares++; -#endif - - int score; - - // Default comparison may be overridden by the slower, more capable reference comparison - int (*cmp)(uint8_t *, uint8_t *, int, int, int, int) = c->compare_optimized; - - // vector displacement limited has been exceeded - if( ABS( dx ) >= c->limit_x || ABS( dy ) >= c->limit_y ) - return MAX_MSAD; - - int mb_w = c->mb_w; // Some writeable local copies - int mb_h = c->mb_h; - - // Determine if either macroblock got clipped - int penalty = constrain( &x, &y, &mb_w, &mb_h, dx, dy, 0, c->width, 0, c->height); - - // Some gotchas - if( penalty == 0 ) // Clipped out of existance: Return worst score - return MAX_MSAD; - else if( penalty != 1<compare_reference; - - // Calculate the memory locations of the macroblocks - block1 += x * c->xstride + y * c->ystride; - block2 += (x+dx) * c->xstride + (y+dy) * c->ystride; - - #ifdef DEBUG_ASM - if( penalty == 1<compare_reference( block1, block2, c->xstride, c->ystride, mb_w, mb_h ); - int score2 = c->compare_optimized( block1, block2, c->xstride, c->ystride, mb_w, mb_h ); - if ( score != score2 ) - fprintf(stderr, "Your assembly doesn't work! Reference: %d Asm: %d\n", score, score2); - } - else - #endif - - score = cmp( block1, block2, c->xstride, c->ystride, mb_w, mb_h ); - - return ( score * penalty ) >> SHIFT; // Ditch the extra precision -} - -static inline void check_candidates ( uint8_t *ref, - uint8_t *candidate_base, - const int x, - const int y, - const motion_vector *candidates,// Contains to_x & to_y - const int count, // Number of candidates - const int unique, // Sometimes we know the candidates are unique - motion_vector *result, - struct motion_est_context_s *c ) -{ - int score, i, j; - /* Scan for the best candidate */ - for ( i = 0; i < count; i++ ) - { - // this little dohicky ignores duplicate candidates, if they are possible - if ( unique == 0 ) { - j = 0; - while ( j < i ) - { - if ( candidates[j].dx == candidates[i].dx && - candidates[j].dy == candidates[i].dy ) - goto next_for_loop; - - j++; - } - } - - // Luma - score = block_compare( ref, candidate_base, - x, y, - candidates[i].dx, // from - candidates[i].dy, - c); - - if ( score < result->msad ) { // New minimum - result->dx = candidates[i].dx; - result->dy = candidates[i].dy; - result->msad = score; - } - next_for_loop:; - } -} - -/* /brief Diamond search -* Operates on a single macroblock -*/ -static inline void diamond_search( - uint8_t *ref, //dx; - current.dy = result->dy; - - if ( first == 1 ) // Set the initial pattern - { - candidates[0].dx = result->dx + 1; candidates[0].dy = result->dy + 0; - candidates[1].dx = result->dx + 0; candidates[1].dy = result->dy + 1; - candidates[2].dx = result->dx - 1; candidates[2].dy = result->dy + 0; - candidates[3].dx = result->dx + 0; candidates[3].dy = result->dy - 1; - i = 4; - } - else // Construct the next portion of the search pattern - { - candidates[0].dx = result->dx + best.dx; - candidates[0].dy = result->dy + best.dy; - if (best.dx == former.dx && best.dy == former.dy) { - candidates[1].dx = result->dx + best.dy; - candidates[1].dy = result->dy + best.dx; // Yes, the wires - candidates[2].dx = result->dx - best.dy; // are crossed - candidates[2].dy = result->dy - best.dx; - i = 3; - } else { - candidates[1].dx = result->dx + former.dx; - candidates[1].dy = result->dy + former.dy; - i = 2; - } - - former.dx = best.dx; former.dy = best.dy; // Keep track of new former best - } - - check_candidates ( ref, candidate_base, x, y, candidates, i, 1, result, c ); - - // Which candidate was the best? - best.dx = result->dx - current.dx; - best.dy = result->dy - current.dy; - - // A better canidate was not found - if ( best.dx == 0 && best.dy == 0 ) - return; - - if ( first == 1 ){ - first = 0; - former.dx = best.dx; former.dy = best.dy; // First iteration, sensible value for former.d* - } - } -} - -/* /brief Full (brute) search -* Operates on a single macroblock -*/ -__attribute__((used)) -static void full_search( - uint8_t *ref, //mb_w; i <= c->mb_w; i++ ){ - for( j = -c->mb_h; j <= c->mb_h; j++ ){ - - score = block_compare( ref, candidate_base, - x, - y, - x + i, - y + j, - c); - - if ( score < result->msad ) { - result->dx = i; - result->dy = j; - result->msad = score; - } - } - } -} - -// Macros for pointer calculations -#define CURRENT(i,j) ( c->current_vectors + (j)*c->mv_buffer_width + (i) ) -#define FORMER(i,j) ( c->former_vectors + (j)*c->mv_buffer_width + (i) ) -#define DENOISE(i,j) ( c->denoise_vectors + (j)*c->mv_buffer_width + (i) ) - -int ncompare (const void * a, const void * b) -{ - return ( *(const int*)a - *(const int*)b ); -} - -// motion vector denoising -// for x and y components seperately, -// change the vector to be the median value of the 9 adjacent vectors -static void median_denoise( motion_vector *v, struct motion_est_context_s *c ) -{ - int xvalues[9], yvalues[9]; - - int i,j,n; - for( j = c->top_mb; j <= c->bottom_mb; j++ ) - for( i = c->left_mb; i <= c->right_mb; i++ ){ - { - n = 0; - - xvalues[n ] = CURRENT(i,j)->dx; // Center - yvalues[n++] = CURRENT(i,j)->dy; - - if( i > c->left_mb ) // Not in First Column - { - xvalues[n ] = CURRENT(i-1,j)->dx; // Left - yvalues[n++] = CURRENT(i-1,j)->dy; - - if( j > c->top_mb ) { - xvalues[n ] = CURRENT(i-1,j-1)->dx; // Upper Left - yvalues[n++] = CURRENT(i-1,j-1)->dy; - } - - if( j < c->bottom_mb ) { - xvalues[n ] = CURRENT(i-1,j+1)->dx; // Bottom Left - yvalues[n++] = CURRENT(i-1,j+1)->dy; - } - } - if( i < c->right_mb ) // Not in Last Column - { - xvalues[n ] = CURRENT(i+1,j)->dx; // Right - yvalues[n++] = CURRENT(i+1,j)->dy; - - - if( j > c->top_mb ) { - xvalues[n ] = CURRENT(i+1,j-1)->dx; // Upper Right - yvalues[n++] = CURRENT(i+1,j-1)->dy; - } - - if( j < c->bottom_mb ) { - xvalues[n ] = CURRENT(i+1,j+1)->dx; // Bottom Right - yvalues[n++] = CURRENT(i+1,j+1)->dy; - } - } - if( j > c->top_mb ) // Not in First Row - { - xvalues[n ] = CURRENT(i,j-1)->dx; // Top - yvalues[n++] = CURRENT(i,j-1)->dy; - } - - if( j < c->bottom_mb ) // Not in Last Row - { - xvalues[n ] = CURRENT(i,j+1)->dx; // Bottom - yvalues[n++] = CURRENT(i,j+1)->dy; - } - - qsort (xvalues, n, sizeof(int), ncompare); - qsort (yvalues, n, sizeof(int), ncompare); - - if( n % 2 == 1 ) { - DENOISE(i,j)->dx = xvalues[n/2]; - DENOISE(i,j)->dy = yvalues[n/2]; - } - else { - DENOISE(i,j)->dx = (xvalues[n/2] + xvalues[n/2+1])/2; - DENOISE(i,j)->dy = (yvalues[n/2] + yvalues[n/2+1])/2; - } - } - } - - motion_vector *t = c->current_vectors; - c->current_vectors = c->denoise_vectors; - c->denoise_vectors = t; - -} - -// Credits: ffmpeg -// return the median -static inline int median_predictor(int a, int b, int c) { - if ( a > b ){ - if ( c > b ){ - if ( c > a ) b = a; - else b = c; - } - } else { - if ( b > c ){ - if ( c > a ) b = c; - else b = a; - } - } - return b; -} - - -/** /brief Motion search -* -* For each macroblock in the current frame, estimate the block from the last frame that -* matches best. -* -* Vocab: Colocated - the pixel in the previous frame at the current position -* -* Based on enhanced predictive zonal search. [Tourapis 2002] -*/ -static void motion_search( uint8_t *from, //left_mb; i <= c->right_mb; i++ ){ - for( j = c->top_mb; j <= c->bottom_mb; j++ ){ - - here = CURRENT(i,j); - here->valid = 1; - here->color = 100; - here->msad = MAX_MSAD; - count++; - n = 0; - - - /* Stack the predictors [i.e. checked in reverse order] */ - - /* Adjacent to collocated */ - if( c->former_vectors_valid ) - { - // Top of colocated - if( j > c->prev_top_mb ){// && COL_TOP->valid ){ - candidates[n ].dx = FORMER(i,j-1)->dx; - candidates[n++].dy = FORMER(i,j-1)->dy; - } - - // Left of colocated - if( i > c->prev_left_mb ){// && COL_LEFT->valid ){ - candidates[n ].dx = FORMER(i-1,j)->dx; - candidates[n++].dy = FORMER(i-1,j)->dy; - } - - // Right of colocated - if( i < c->prev_right_mb ){// && COL_RIGHT->valid ){ - candidates[n ].dx = FORMER(i+1,j)->dx; - candidates[n++].dy = FORMER(i+1,j)->dy; - } - - // Bottom of colocated - if( j < c->prev_bottom_mb ){// && COL_BOTTOM->valid ){ - candidates[n ].dx = FORMER(i,j+1)->dx; - candidates[n++].dy = FORMER(i,j+1)->dy; - } - - // And finally, colocated - candidates[n ].dx = FORMER(i,j)->dx; - candidates[n++].dy = FORMER(i,j)->dy; - } - - // For macroblocks not in the top row - if ( j > c->top_mb) { - - // Top if ( TOP->valid ) { - candidates[n ].dx = CURRENT(i,j-1)->dx; - candidates[n++].dy = CURRENT(i,j-1)->dy; - //} - - // Top-Right, macroblocks not in the right row - if ( i < c->right_mb ){// && TOP_RIGHT->valid ) { - candidates[n ].dx = CURRENT(i+1,j-1)->dx; - candidates[n++].dy = CURRENT(i+1,j-1)->dy; - } - } - - // Left, Macroblocks not in the left column - if ( i > c->left_mb ){// && LEFT->valid ) { - candidates[n ].dx = CURRENT(i-1,j)->dx; - candidates[n++].dy = CURRENT(i-1,j)->dy; - } - - /* Median predictor vector (median of left, top, and top right adjacent vectors) */ - if ( i > c->left_mb && j > c->top_mb && i < c->right_mb - )//&& LEFT->valid && TOP->valid && TOP_RIGHT->valid ) - { - candidates[n ].dx = median_predictor( CURRENT(i-1,j)->dx, CURRENT(i,j-1)->dx, CURRENT(i+1,j-1)->dx); - candidates[n++].dy = median_predictor( CURRENT(i-1,j)->dy, CURRENT(i,j-1)->dy, CURRENT(i+1,j-1)->dy); - } - - // Zero vector - candidates[n ].dx = 0; - candidates[n++].dy = 0; - - int x = i * c->mb_w; - int y = j * c->mb_h; - check_candidates ( to, from, x, y, candidates, n, 0, here, c ); - - -#ifndef FULLSEARCH - diamond_search( to, from, x, y, here, c); -#else - full_search( to, from, x, y, here, c); -#endif - - assert( x + c->mb_w + here->dx > 0 ); // All macroblocks must have area > 0 - assert( y + c->mb_h + here->dy > 0 ); - assert( x + here->dx < c->width ); - assert( y + here->dy < c->height ); - - } /* End column loop */ - } /* End row loop */ - -#ifdef USE_SSE - asm volatile ( "emms" ); -#endif - -#ifdef COUNT_COMPARES - fprintf(stderr, "%d comparisons per block were made", compares/count); -#endif - return; -} - -void collect_post_statistics( struct motion_est_context_s *c ) { - - c->comparison_average = 0; - c->average_length = 0; - c->average_x = 0; - c->average_y = 0; - - int i, j, count = 0; - - for ( i = c->left_mb; i <= c->right_mb; i++ ){ - for ( j = c->top_mb; j <= c->bottom_mb; j++ ){ - - count++; - c->comparison_average += CURRENT(i,j)->msad; - c->average_x += CURRENT(i,j)->dx; - c->average_y += CURRENT(i,j)->dy; - - - } - } - - if ( count > 0 ) - { - c->comparison_average /= count; - c->average_x /= count; - c->average_y /= count; - c->average_length = sqrt( c->average_x * c->average_x + c->average_y * c->average_y ); - } - -} - -static void init_optimizations( struct motion_est_context_s *c ) -{ - switch(c->mb_w){ -#ifdef USE_SSE - case 4: if(c->mb_h == 4) c->compare_optimized = sad_sse_422_luma_4x4; - else c->compare_optimized = sad_sse_422_luma_4w; - break; - case 8: if(c->mb_h == 8) c->compare_optimized = sad_sse_422_luma_8x8; - else c->compare_optimized = sad_sse_422_luma_8w; - break; - case 16: if(c->mb_h == 16) c->compare_optimized = sad_sse_422_luma_16x16; - else c->compare_optimized = sad_sse_422_luma_16w; - break; - case 32: if(c->mb_h == 32) c->compare_optimized = sad_sse_422_luma_32x32; - else c->compare_optimized = sad_sse_422_luma_32w; - break; - case 64: c->compare_optimized = sad_sse_422_luma_64w; - break; -#endif - default: c->compare_optimized = sad_reference; - break; - } -} - -inline static void set_red(uint8_t *image, struct motion_est_context_s *c) -{ - int n; - for( n = 0; n < c->width * c->height * 2; n+=4 ) - { - image[n] = 79; - image[n+1] = 91; - image[n+2] = 79; - image[n+3] = 237; - } - -} - -static void show_residual( uint8_t *result, struct motion_est_context_s *c ) -{ - int i, j; - int x,y,w,h; - int dx, dy; - int tx,ty; - uint8_t *b, *r; - -// set_red(result,c); - - for( j = c->top_mb; j <= c->bottom_mb; j++ ){ - for( i = c->left_mb; i <= c->right_mb; i++ ){ - - dx = CURRENT(i,j)->dx; - dy = CURRENT(i,j)->dy; - w = c->mb_w; - h = c->mb_h; - x = i * w; - y = j * h; - - // Denoise function caused some blocks to be completely clipped, ignore them - if (constrain( &x, &y, &w, &h, dx, dy, 0, c->width, 0, c->height) == 0 ) - continue; - - for( ty = y; ty < y + h ; ty++ ){ - for( tx = x; tx < x + w ; tx++ ){ - - b = c->former_image + (tx+dx)*c->xstride + (ty+dy)*c->ystride; - r = result + tx*c->xstride + ty*c->ystride; - - r[0] = 16 + ABS( r[0] - b[0] ); - - if( dx % 2 == 0 ) - r[1] = 128 + ABS( r[1] - b[1] ); - else - // FIXME: may exceed boundies - r[1] = 128 + ABS( r[1] - ( *(b-1) + b[3] ) /2 ); - } - } - } - } -} - -static void show_reconstruction( uint8_t *result, struct motion_est_context_s *c ) -{ - int i, j; - int x,y,w,h; - int dx,dy; - uint8_t *r, *s; - int tx,ty; - - for( i = c->left_mb; i <= c->right_mb; i++ ){ - for( j = c->top_mb; j <= c->bottom_mb; j++ ){ - - dx = CURRENT(i,j)->dx; - dy = CURRENT(i,j)->dy; - w = c->mb_w; - h = c->mb_h; - x = i * w; - y = j * h; - - // Denoise function caused some blocks to be completely clipped, ignore them - if (constrain( &x, &y, &w, &h, dx, dy, 0, c->width, 0, c->height) == 0 ) - continue; - - for( ty = y; ty < y + h ; ty++ ){ - for( tx = x; tx < x + w ; tx++ ){ - - r = result + tx*c->xstride + ty*c->ystride; - s = c->former_image + (tx+dx)*c->xstride + (ty+dy)*c->ystride; - - r[0] = s[0]; - - if( dx % 2 == 0 ) - r[1] = s[1]; - else - // FIXME: may exceed boundies - r[1] = ( *(s-1) + s[3] ) /2; - } - } - } - } -} - -// Image stack(able) method -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the filter - mlt_filter filter = mlt_frame_pop_service( frame ); - - // Get the motion_est context object - struct motion_est_context_s *c = mlt_properties_get_data( MLT_FILTER_PROPERTIES( filter ), "context", NULL); - - - // Get the new image and frame number - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - #ifdef BENCHMARK - struct timeval start; gettimeofday(&start, NULL ); - #endif - - - if( error != 0 ) - mlt_properties_debug( MLT_FRAME_PROPERTIES(frame), "error after mlt_frame_get_image() in motion_est", stderr ); - - c->current_frame_position = mlt_frame_get_position( frame ); - - /* Context Initialization */ - if ( c->initialized == 0 ) { - - // Get the filter properties object - mlt_properties properties = mlt_filter_properties( filter ); - - c->width = *width; - c->height = *height; - - /* Get parameters that may have been overridden */ - if( mlt_properties_get( properties, "macroblock_width") != NULL ) - c->mb_w = mlt_properties_get_int( properties, "macroblock_width"); - - if( mlt_properties_get( properties, "macroblock_height") != NULL ) - c->mb_h = mlt_properties_get_int( properties, "macroblock_height"); - - if( mlt_properties_get( properties, "prediction_thresh") != NULL ) - c->initial_thresh = mlt_properties_get_int( properties, "prediction_thresh" ); - else - c->initial_thresh = c->mb_w * c->mb_h; - - if( mlt_properties_get( properties, "search_method") != NULL ) - c->search_method = mlt_properties_get_int( properties, "search_method"); - - if( mlt_properties_get( properties, "skip_prediction") != NULL ) - c->skip_prediction = mlt_properties_get_int( properties, "skip_prediction"); - - if( mlt_properties_get( properties, "limit_x") != NULL ) - c->limit_x = mlt_properties_get_int( properties, "limit_x"); - - if( mlt_properties_get( properties, "limit_y") != NULL ) - c->limit_y = mlt_properties_get_int( properties, "limit_y"); - - if( mlt_properties_get( properties, "check_chroma" ) != NULL ) - c->check_chroma = mlt_properties_get_int( properties, "check_chroma" ); - - if( mlt_properties_get( properties, "denoise" ) != NULL ) - c->denoise = mlt_properties_get_int( properties, "denoise" ); - - if( mlt_properties_get( properties, "show_reconstruction" ) != NULL ) - c->show_reconstruction = mlt_properties_get_int( properties, "show_reconstruction" ); - - if( mlt_properties_get( properties, "show_residual" ) != NULL ) - c->show_residual = mlt_properties_get_int( properties, "show_residual" ); - - if( mlt_properties_get( properties, "toggle_when_paused" ) != NULL ) - c->toggle_when_paused = mlt_properties_get_int( properties, "toggle_when_paused" ); - - init_optimizations( c ); - - // Calculate the dimensions in macroblock units - c->mv_buffer_width = (*width / c->mb_w); - c->mv_buffer_height = (*height / c->mb_h); - - // Size of the motion vector buffer - c->mv_size = c->mv_buffer_width * c->mv_buffer_height * sizeof(struct motion_vector_s); - - // Allocate the motion vector buffers - c->former_vectors = mlt_pool_alloc( c->mv_size ); - c->current_vectors = mlt_pool_alloc( c->mv_size ); - c->denoise_vectors = mlt_pool_alloc( c->mv_size ); - - // Register motion buffers for destruction - mlt_properties_set_data( properties, "current_motion_vectors", (void *)c->current_vectors, 0, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "former_motion_vectors", (void *)c->former_vectors, 0, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "denoise_motion_vectors", (void *)c->denoise_vectors, 0, mlt_pool_release, NULL ); - - c->former_vectors_valid = 0; - memset( c->former_vectors, 0, c->mv_size ); - - // Calculate the size of our steps (the number of bytes that seperate adjacent pixels in X and Y direction) - switch( *format ) { - case mlt_image_yuv422: - c->xstride = 2; - c->ystride = c->xstride * *width; - break; - default: - // I don't know - fprintf(stderr, "\"I am unfamiliar with your new fangled pixel format!\" -filter_motion_est\n"); - return -1; - } - - // Allocate a cache for the previous frame's image - c->former_image = mlt_pool_alloc( *width * *height * 2 ); - c->cache_image = mlt_pool_alloc( *width * *height * 2 ); - - // Register for destruction - mlt_properties_set_data( properties, "cache_image", (void *)c->cache_image, 0, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "former_image", (void *)c->former_image, 0, mlt_pool_release, NULL ); - - c->former_frame_position = c->current_frame_position; - c->previous_msad = 0; - - c->initialized = 1; - } - - /* Check to see if somebody else has given us bounds */ - struct mlt_geometry_item_s *bounds = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "bounds", NULL ); - - if( bounds != NULL ) { - // translate pixel units (from bounds) to macroblock units - // make sure whole macroblock stays within bounds - c->left_mb = ( bounds->x + c->mb_w - 1 ) / c->mb_w; - c->top_mb = ( bounds->y + c->mb_h - 1 ) / c->mb_h; - c->right_mb = ( bounds->x + bounds->w ) / c->mb_w - 1; - c->bottom_mb = ( bounds->y + bounds->h ) / c->mb_h - 1; - c->bounds.x = bounds->x; - c->bounds.y = bounds->y; - c->bounds.w = bounds->w; - c->bounds.h = bounds->h; - } else { - c->left_mb = c->prev_left_mb = 0; - c->top_mb = c->prev_top_mb = 0; - c->right_mb = c->prev_right_mb = c->mv_buffer_width - 1; // Zero indexed - c->bottom_mb = c->prev_bottom_mb = c->mv_buffer_height - 1; - c->bounds.x = 0; - c->bounds.y = 0; - c->bounds.w = *width; - c->bounds.h = *height; - } - - // If video is advancing, run motion vector algorithm and etc... - if( c->former_frame_position + 1 == c->current_frame_position ) - { - - // Swap the motion vector buffers and reuse allocated memory - struct motion_vector_s *temp = c->current_vectors; - c->current_vectors = c->former_vectors; - c->former_vectors = temp; - - // This is done because filter_vismv doesn't pay attention to frame boundry - memset( c->current_vectors, 0, c->mv_size ); - - // Perform the motion search - motion_search( c->cache_image, *image, c ); - - collect_post_statistics( c ); - - - // Detect shot changes - if( c->comparison_average > 10 * c->mb_w * c->mb_h && - c->comparison_average > c->previous_msad * 2 ) - { - fprintf(stderr, " - SAD: %d <>\n", c->comparison_average); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "shot_change", 1); - // c->former_vectors_valid = 0; // Invalidate the previous frame's predictors - c->shot_change = 1; - } - else { - c->former_vectors_valid = 1; - c->shot_change = 0; - //fprintf(stderr, " - SAD: %d\n", c->comparison_average); - } - - c->previous_msad = c->comparison_average; - - if( c->comparison_average != 0 ) { // If the frame is not a duplicate of the previous frame - - // denoise the vector buffer - if( c->denoise ) - median_denoise( c->current_vectors, c ); - - // Pass the new vector data into the frame - mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), "motion_est.vectors", - (void*)c->current_vectors, c->mv_size, NULL, NULL ); - - // Cache the frame's image. Save the old cache. Reuse memory. - // After this block, exactly two unique frames will be cached - uint8_t *timg = c->cache_image; - c->cache_image = c->former_image; - c->former_image = timg; - memcpy( c->cache_image, *image, *width * *height * c->xstride ); - - - } - else { - // Undo the Swap, This fixes the ugliness caused by a duplicate frame - temp = c->current_vectors; - c->current_vectors = c->former_vectors; - c->former_vectors = temp; - mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), "motion_est.vectors", - (void*)c->former_vectors, c->mv_size, NULL, NULL ); - } - - - if( c->shot_change == 1) - ; - else if( c->show_reconstruction ) - show_reconstruction( *image, c ); - else if( c->show_residual ) - show_residual( *image, c ); - - } - // paused - else if( c->former_frame_position == c->current_frame_position ) - { - // Pass the old vector data into the frame if it's valid - if( c->former_vectors_valid == 1 ) { - mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), "motion_est.vectors", - (void*)c->current_vectors, c->mv_size, NULL, NULL ); - - if( c->shot_change == 1) - ; - else if( c->toggle_when_paused == 1 ) { - if( c->show_reconstruction ) - show_reconstruction( *image, c ); - else if( c->show_residual ) - show_residual( *image, c ); - c->toggle_when_paused = 2; - } - else if( c->toggle_when_paused == 2 ) - c->toggle_when_paused = 1; - else { - if( c->show_reconstruction ) - show_reconstruction( *image, c ); - else if( c->show_residual ) - show_residual( *image, c ); - } - - } - - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "shot_change", c->shot_change); - } - // there was jump in frame number - else { -// fprintf(stderr, "Warning: there was a frame number jumped from %d to %d.\n", c->former_frame_position, c->current_frame_position); - c->former_vectors_valid = 0; - } - - - // Cache our bounding geometry for the next frame's processing - c->prev_left_mb = c->left_mb; - c->prev_top_mb = c->top_mb; - c->prev_right_mb = c->right_mb; - c->prev_bottom_mb = c->bottom_mb; - - // Remember which frame this is - c->former_frame_position = c->current_frame_position; - - - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.macroblock_width", c->mb_w ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.macroblock_height", c->mb_h ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.left_mb", c->left_mb ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.right_mb", c->right_mb ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.top_mb", c->top_mb ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.bottom_mb", c->bottom_mb ); - - #ifdef BENCHMARK - struct timeval finish; gettimeofday(&finish, NULL ); int difference = (finish.tv_sec - start.tv_sec) * 1000000 + (finish.tv_usec - start.tv_usec); - fprintf(stderr, " in frame %d:%d usec\n", c->current_frame_position, difference); - #endif - - - return error; -} - - - -/** filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - // Keeps tabs on the filter object - mlt_frame_push_service( frame, this); - - // Push the frame filter - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ -mlt_filter filter_motion_est_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - // Get the properties object - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Initialize the motion estimation context - struct motion_est_context_s *context; - context = mlt_pool_alloc( sizeof(struct motion_est_context_s) ); - mlt_properties_set_data( properties, "context", (void *)context, sizeof( struct motion_est_context_s ), - mlt_pool_release, NULL ); - - - // Register the filter - this->process = filter_process; - - /* defaults that may be overridden */ - context->mb_w = 16; - context->mb_h = 16; - context->skip_prediction = 0; - context->limit_x = 64; - context->limit_y = 64; - context->search_method = DIAMOND_SEARCH; // FIXME: not used - context->check_chroma = 0; - context->denoise = 1; - context->show_reconstruction = 0; - context->show_residual = 0; - context->toggle_when_paused = 0; - - /* reference functions that may have optimized versions */ - context->compare_reference = sad_reference; - - // The rest of the buffers will be initialized when the filter is first processed - context->initialized = 0; - } - return this; -} diff --git a/src/modules/motion_est/filter_motion_est.h b/src/modules/motion_est/filter_motion_est.h deleted file mode 100644 index 296287e..0000000 --- a/src/modules/motion_est/filter_motion_est.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Perform motion estimation - * Zachary K Drew, Copyright 2004 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _FILTER_MOTION_EST_H_ -#define _FILTER_MOTION_EST_H_ - -#include - -extern mlt_filter filter_motion_est_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -#define MAX_MSAD 0xffff - -struct motion_vector_s -{ - int msad; // - -#include -#include -#include -#include - -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - -static void paint_arrows( uint8_t *image, struct motion_vector_s *vectors, int w, int h, int mb_w, int mb_h ) -{ - int i, j, x, y; - struct motion_vector_s *p; - for( i = 0; i < w/mb_w; i++ ){ - for( j = 0; j < h/mb_h; j++ ){ - x = i*mb_w; - y = j*mb_h; - p = vectors + (w/mb_w)*j + i; - - if ( p->valid == 1 ) { - //draw_rectangle_outline(image, x-1, y-1, mb_w+1, mb_h+1,100); - //x += mb_w/4; - //y += mb_h/4; - //draw_rectangle_outline(image, x + p->dx, y + p->dy, mb_w, mb_h,100); - x += mb_w/2; - y += mb_h/2; - draw_arrow(image, x, y, x + p->dx, y + p->dy, 100); - //draw_rectangle_fill(image, x + p->dx, y + p->dy, mb_w, mb_h, 100); - } - else if ( p->valid == 2 ) { - draw_rectangle_outline(image, x+1, y+1, mb_w-2, mb_h-2,100); - } - else if ( p->valid == 3 ) { - draw_rectangle_fill(image, x-p->dx, y-p->dy, mb_w, mb_h,0); - } - else if ( p->valid == 4 ) { - draw_line(image, x, y, x + 4, y, 100); - draw_line(image, x, y, x, y + 4, 100); - draw_line(image, x + 4, y, x, y + 4, 100); - - draw_line(image, x+mb_w-1, y+mb_h-1, x+mb_w-5, y+mb_h-1, 100); - draw_line(image, x+mb_w-1, y+mb_h-1, x+mb_w-1, y+mb_h-5, 100); - draw_line(image, x+mb_w-5, y+mb_h-1, x+mb_w-1, y+mb_h-5, 100); - } - } - } -} - -// Image stack(able) method -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the frame properties - mlt_properties properties = MLT_FRAME_PROPERTIES(frame); - - // Get the new image - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - if( error != 0 ) - mlt_properties_debug( MLT_FRAME_PROPERTIES(frame), "error after mlt_frame_get_image()", stderr ); - - - // Get the size of macroblocks in pixel units - int macroblock_height = mlt_properties_get_int( properties, "motion_est.macroblock_height" ); - int macroblock_width = mlt_properties_get_int( properties, "motion_est.macroblock_width" ); - - // Get the motion vectors - struct motion_vector_s *current_vectors = mlt_properties_get_data( properties, "motion_est.vectors", NULL ); - - init_arrows( format, *width, *height ); - - if ( mlt_properties_get_int( properties, "shot_change" ) == 1 ) - { - draw_line(*image, 0, 0, *width, *height, 100); - draw_line(*image, 0, *height, *width, 0, 100); - } - if( current_vectors != NULL ) { - paint_arrows( *image, current_vectors, *width, *height, macroblock_width, macroblock_height); - } - - return error; -} - - - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push the frame filter - mlt_frame_push_get_image( frame, filter_get_image ); - - - return frame; -} - -/** Constructor for the filter. -*/ - - -mlt_filter filter_vismv_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - - } - - return this; -} - -/** This source code will self destruct in 5...4...3... -*/ - - - - - - - - diff --git a/src/modules/motion_est/gpl b/src/modules/motion_est/gpl deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/motion_est/producer_slowmotion.c b/src/modules/motion_est/producer_slowmotion.c deleted file mode 100644 index e66db09..0000000 --- a/src/modules/motion_est/producer_slowmotion.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * producer_slowmotion.c -- create subspeed frames - * Author: Zachary Drew - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "filter_motion_est.h" -#include - -#include -#include -#include -#include -#include -#include -#define SHIFT 8 -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - -// This is used to constrains pixel operations between two blocks to be within the image boundry -inline static int constrain( int *x, int *y, int *w, int *h, - const int dx, const int dy, - const int left, const int right, - const int top, const int bottom) -{ - uint32_t penalty = 1 << SHIFT; // Retain a few extra bits of precision - int x2 = *x + dx; - int y2 = *y + dy; - int w_remains = *w; - int h_remains = *h; - - // Origin of macroblock moves left of image boundy - if( *x < left || x2 < left ) { - w_remains = *w - left + ((*x < x2) ? *x : x2); - *x += *w - w_remains; - } - // Portion of macroblock moves right of image boundry - else if( *x + *w > right || x2 + *w > right ) - w_remains = right - ((*x > x2) ? *x : x2); - - // Origin of macroblock moves above image boundy - if( *y < top || y2 < top ) { - h_remains = *h - top + ((*y < y2) ? *y : y2); - *y += *h - h_remains; - } - // Portion of macroblock moves bellow image boundry - else if( *y + *h > bottom || y2 + *h > bottom ) - h_remains = bottom - ((*y > y2) ? *y : y2); - - if( w_remains == *w && h_remains == *h ) return penalty; - if( w_remains <= 0 || h_remains <= 0) return 0; // Block is clipped out of existance - penalty = (*w * *h * penalty) - / ( w_remains * h_remains); // Recipricol of the fraction of the block that remains - - *w = w_remains; // Update the width and height - *h = h_remains; - - return penalty; -} - -static void motion_interpolate( uint8_t *first_image, uint8_t *second_image, uint8_t *output, - int top_mb, int bottom_mb, int left_mb, int right_mb, - int mb_w, int mb_h, - int width, int height, - int xstride, int ystride, - double scale, - motion_vector *vectors ) -{ - assert ( scale >= 0.0 && scale <= 1.0 ); - - int i, j; - int x,y,w,h; - int dx, dy; - int scaled_dx, scaled_dy; - int tx,ty; - uint8_t *f,*s,*r; - motion_vector *here; - int mv_width = width / mb_w; - - for( j = top_mb; j <= bottom_mb; j++ ){ - for( i = left_mb; i <= right_mb; i++ ){ - - here = vectors + j*mv_width + i; - scaled_dx = (1.0 - scale) * (double)here->dx; - scaled_dy = (1.0 - scale) * (double)here->dy; - dx = here->dx; - dy = here->dy; - w = mb_w; h = mb_h; - x = i * w; y = j * h; - - // Denoise function caused some blocks to be completely clipped, ignore them - if (constrain( &x, &y, &w, &h, dx, dy, 0, width, 0, height) == 0 ) - continue; - - for( ty = y; ty < y + h ; ty++ ){ - for( tx = x; tx < x + w ; tx++ ){ - - f = first_image + (tx + dx )*xstride + (ty + dy )*ystride; - s = second_image + (tx )*xstride + (ty )*ystride; - r = output + (tx+scaled_dx)*xstride + (ty+scaled_dy)*ystride; -/* - if( ABS(f[0] - s[0]) > 3 * here->msad / (mb_w * mb_h * 2) ) - { - r[0] = f[0]; - r[1] = f[1]; - } - - else - { - -*/ - r[0] = ( 1.0 - scale ) * (double)f[0] + scale * (double)s[0]; - - if( dx % 2 == 0 ) - { - if( scaled_dx % 2 == 0 ) - r[1] = ( 1.0 - scale ) * (double)f[1] + scale * (double) s[1]; - else - *(r-1) = ( 1.0 - scale ) * (double)f[1] + scale * (double) s[1]; - } - else - { - if( scaled_dx %2 == 0 ) - // FIXME: may exceed boundies - r[1] = ( 1.0 - scale ) * ( (double)(*(f-1) + (double)f[3]) / 2.0 ) + scale * (double) s[1]; - else - // FIXME: may exceed boundies - *(r-1) = ( 1.0 - scale ) * ( (double)(*(f-1) + (double)f[3]) / 2.0 ) + scale * (double) s[1]; - } -// } - } - } - } - } -} - -// Image stack(able) method -static int slowmotion_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - // Get the filter object and properties - mlt_producer producer = mlt_frame_pop_service( this ); - mlt_frame second_frame = mlt_frame_pop_service( this ); - mlt_frame first_frame = mlt_frame_pop_service( this ); - - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Frame properties objects - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( this ); - mlt_properties first_frame_properties = MLT_FRAME_PROPERTIES( first_frame ); - mlt_properties second_frame_properties = MLT_FRAME_PROPERTIES( second_frame ); - - // image stride - int size, xstride, ystride; - switch( *format ){ - case mlt_image_yuv422: - size = *width * *height * 2; - xstride = 2; - ystride = 2 * *width; - break; - default: - fprintf(stderr, "Unsupported image format\n"); - return -1; - } - - uint8_t *output = mlt_properties_get_data( producer_properties, "output_buffer", 0 ); - if( output == NULL ) - { - output = mlt_pool_alloc( size ); - - // Let someone else clean up - mlt_properties_set_data( producer_properties, "output_buffer", output, size, mlt_pool_release, NULL ); - } - - uint8_t *first_image = mlt_properties_get_data( first_frame_properties, "image", NULL ); - uint8_t *second_image = mlt_properties_get_data( second_frame_properties, "image", NULL ); - - // which frames are buffered? - - int error = 0; - - if( first_image == NULL ) - { - error = mlt_frame_get_image( first_frame, &first_image, format, width, height, writable ); - - if( error != 0 ) { - fprintf(stderr, "first_image == NULL get image died\n"); - return error; - } - } - - if( second_image == NULL ) - { - error = mlt_frame_get_image( second_frame, &second_image, format, width, height, writable ); - - if( error != 0 ) { - fprintf(stderr, "second_image == NULL get image died\n"); - return error; - } - } - - // These need to passed onto the frame for other - mlt_properties_pass_list( frame_properties, second_frame_properties, - "motion_est.left_mb, motion_est.right_mb, \ - motion_est.top_mb, motion_est.bottom_mb, \ - motion_est.macroblock_width, motion_est.macroblock_height" ); - - // Pass the pointer to the vectors without serializing - mlt_properties_set_data( frame_properties, "motion_est.vectors", - mlt_properties_get_data( second_frame_properties, "motion_est.vectors", NULL ), - 0, NULL, NULL ); - - - // Start with a base image - memcpy( output, first_image, size ); - - if( mlt_properties_get_int( producer_properties, "method" ) == 1 ) { - - mlt_position first_position = mlt_frame_get_position( first_frame ); - double actual_position = mlt_producer_get_speed( producer ) * (double)mlt_frame_get_position( this ); - double scale = actual_position - first_position; - - motion_interpolate - ( - first_image, second_image, output, - mlt_properties_get_int( second_frame_properties, "motion_est.top_mb" ), - mlt_properties_get_int( second_frame_properties, "motion_est.bottom_mb" ), - mlt_properties_get_int( second_frame_properties, "motion_est.left_mb" ), - mlt_properties_get_int( second_frame_properties, "motion_est.right_mb" ), - mlt_properties_get_int( second_frame_properties, "motion_est.macroblock_width" ), - mlt_properties_get_int( second_frame_properties, "motion_est.macroblock_height" ), - *width, *height, - xstride, ystride, - scale, - mlt_properties_get_data( second_frame_properties, "motion_est.vectors", NULL ) - ); - - if( mlt_properties_get_int( producer_properties, "debug" ) == 1 ) { - mlt_filter watermark = mlt_properties_get_data( producer_properties, "watermark", NULL ); - - if( watermark == NULL ) { - mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ); - watermark = mlt_factory_filter( profile, "watermark", NULL ); - mlt_properties_set_data( producer_properties, "watermark", watermark, 0, (mlt_destructor)mlt_filter_close, NULL ); - mlt_producer_attach( producer, watermark ); - } - - mlt_properties wm_properties = MLT_FILTER_PROPERTIES( watermark ); - - char disp[30]; - sprintf(disp, "+%10.2f.txt", actual_position); - mlt_properties_set( wm_properties, "resource", disp ); - - } - - } - - *image = output; - mlt_properties_set_data( frame_properties, "image", output, size, NULL, NULL ); - - // Make sure that no further scaling is done - mlt_properties_set( frame_properties, "rescale.interps", "none" ); - mlt_properties_set( frame_properties, "scale", "off" ); - - mlt_frame_close( first_frame ); - mlt_frame_close( second_frame ); - - return 0; -} - -static int slowmotion_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ) -{ - // Construct a new frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( this ) ); - - mlt_properties properties = MLT_PRODUCER_PROPERTIES(this); - - - if( frame != NULL ) - { - - mlt_frame first_frame = mlt_properties_get_data( properties, "first_frame", NULL ); - mlt_frame second_frame = mlt_properties_get_data( properties, "second_frame", NULL ); - - mlt_position first_position = (first_frame != NULL) ? mlt_frame_get_position( first_frame ) : -1; - mlt_position second_position = (second_frame != NULL) ? mlt_frame_get_position( second_frame ) : -1; - - // Get the real producer - mlt_producer real_producer = mlt_properties_get_data( properties, "producer", NULL ); - - // Our "in" needs to be the same, keep it so - mlt_properties_pass_list( MLT_PRODUCER_PROPERTIES( real_producer ), properties, "in" ); - - // Calculate our positions - double actual_position = mlt_producer_get_speed( this ) * (double)mlt_producer_position( this ); - mlt_position need_first = floor( actual_position ); - mlt_position need_second = need_first + 1; - - if( need_first != first_position ) - { - mlt_frame_close( first_frame ); - first_position = -1; - first_frame = NULL; - } - - if( need_second != second_position) - { - mlt_frame_close( second_frame ); - second_position = -1; - second_frame = NULL; - } - - if( first_frame == NULL ) - { - // Seek the producer to the correct place - mlt_producer_seek( real_producer, need_first ); - - // Get the frame - mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &first_frame, index ); - } - - if( second_frame == NULL ) - { - // Seek the producer to the correct place - mlt_producer_seek( real_producer, need_second ); - - // Get the frame - mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &second_frame, index ); - } - - // Make sure things are in their place - mlt_properties_set_data( properties, "first_frame", first_frame, 0, NULL, NULL ); - mlt_properties_set_data( properties, "second_frame", second_frame, 0, NULL, NULL ); - - mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_image", 0 ); - - // Stack the producer and producer's get image - mlt_frame_push_service( *frame, first_frame ); - mlt_properties_inc_ref( MLT_FRAME_PROPERTIES( first_frame ) ); - - mlt_frame_push_service( *frame, second_frame ); - mlt_properties_inc_ref( MLT_FRAME_PROPERTIES( second_frame ) ); - - mlt_frame_push_service( *frame, this ); - mlt_frame_push_service( *frame, slowmotion_get_image ); - - // Give the returned frame temporal identity - mlt_frame_set_position( *frame, mlt_producer_position( this ) ); - } - - return 0; -} - -mlt_producer producer_slowmotion_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_producer this = mlt_producer_new( ); - - // Wrap fezzik - mlt_producer real_producer = mlt_factory_producer( profile, "fezzik", arg ); - - // We need to apply the motion estimation filter manually - mlt_filter filter = mlt_factory_filter( profile, "motion_est", NULL ); - - if ( this != NULL && real_producer != NULL && filter != NULL) - { - // attach the motion_est filter to the real producer - mlt_producer_attach( real_producer, filter ); - - // Get the properties of this producer - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Fezzik normalised it for us already - mlt_properties_set_int( properties, "fezzik_normalised", 1); - - // Store the producer and fitler - mlt_properties_set_data( properties, "producer", real_producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); - mlt_properties_set_data( properties, "motion_est", filter, 0, ( mlt_destructor )mlt_filter_close, NULL ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "macroblock_width", 16 ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "macroblock_height", 16 ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "denoise", 0 ); - - // Grap some stuff from the real_producer - mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( real_producer ), - "in, out, length, resource" ); - - // Since we control the seeking, prevent it from seeking on its own - mlt_producer_set_speed( real_producer, 0 ); - - //mlt_properties_set( properties, "method", "onefield" ); - - // Override the get_frame method - this->get_frame = slowmotion_get_frame; - - } - else - { - if ( this ) - mlt_producer_close( this ); - if ( real_producer ) - mlt_producer_close( real_producer ); - if ( filter ) - mlt_filter_close( filter ); - - this = NULL; - } - return this; -} diff --git a/src/modules/motion_est/sad_sse.h b/src/modules/motion_est/sad_sse.h deleted file mode 100644 index b14a5f6..0000000 --- a/src/modules/motion_est/sad_sse.h +++ /dev/null @@ -1,429 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -#define SAD_SSE_INIT \ - asm volatile ( "pxor %%mm6,%%mm6\n\t" :: );\ - -// Sum two 8x1 pixel blocks -#define SAD_SSE_SUM_8(OFFSET) \ - "movq " #OFFSET "(%0),%%mm0 \n\t"\ - "movq " #OFFSET "(%1),%%mm1 \n\t"\ - "psadbw %%mm1,%%mm0 \n\t"\ - "paddw %%mm0,%%mm6 \n\t"\ - -#define SAD_SSE_FINISH(RESULT) \ - asm volatile( "movd %%mm6,%0" : "=r" (RESULT) : ); - -// Advance by ystride -#define SAD_SSE_NEXTROW \ - "add %2,%0 \n\t"\ - "add %2,%1 \n\t"\ - -// BROKEN! -inline static int sad_sse_4x4( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_INIT - #define ROW SAD_SSE_SUM_8(0) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((long int)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -inline static int sad_sse_8x8( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_INIT - #define ROW SAD_SSE_SUM_8(0) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((long int)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -inline static int sad_sse_16x16( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_INIT - #define ROW SAD_SSE_SUM_8(0) SAD_SSE_SUM_8(8) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((long int)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -inline static int sad_sse_32x32( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_INIT - #define ROW SAD_SSE_SUM_8(0) SAD_SSE_SUM_8(8) SAD_SSE_SUM_8(16) SAD_SSE_SUM_8(24)\ - SAD_SSE_NEXTROW - - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((long int)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} -// BROKEN! -inline static int sad_sse_4w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_SUM_8(0) - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -inline static int sad_sse_8w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_SUM_8(0) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -inline static int sad_sse_16w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_SUM_8(0) - SAD_SSE_SUM_8(8) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -inline static int sad_sse_32w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_SUM_8(0) - SAD_SSE_SUM_8(8) - SAD_SSE_SUM_8(16) - SAD_SSE_SUM_8(24) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -inline static int sad_sse_64w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_SUM_8(0) - SAD_SSE_SUM_8(8) - SAD_SSE_SUM_8(16) - SAD_SSE_SUM_8(24) - SAD_SSE_SUM_8(32) - SAD_SSE_SUM_8(40) - SAD_SSE_SUM_8(48) - SAD_SSE_SUM_8(56) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} -static __attribute__((used)) __attribute__((aligned(8))) uint64_t sad_sse_422_mask_chroma = 0x00ff00ff00ff00ffULL; - -#define SAD_SSE_422_LUMA_INIT \ - asm volatile ( "movq %0,%%mm7\n\t"\ - "pxor %%mm6,%%mm6\n\t" :: "m" (sad_sse_422_mask_chroma) );\ - -// Sum two 4x1 pixel blocks -#define SAD_SSE_422_LUMA_SUM_4(OFFSET) \ - "movq " #OFFSET "(%0),%%mm0 \n\t"\ - "movq " #OFFSET "(%1),%%mm1 \n\t"\ - "pand %%mm7,%%mm0 \n\t"\ - "pand %%mm7,%%mm1 \n\t"\ - "psadbw %%mm1,%%mm0 \n\t"\ - "paddw %%mm0,%%mm6 \n\t"\ - -static int sad_sse_422_luma_4x4( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_422_LUMA_INIT - #define ROW SAD_SSE_422_LUMA_SUM_4(0) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((long int)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -static int sad_sse_422_luma_8x8( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_422_LUMA_INIT - #define ROW SAD_SSE_422_LUMA_SUM_4(0) SAD_SSE_422_LUMA_SUM_4(8) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((long int)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -static int sad_sse_422_luma_16x16( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_422_LUMA_INIT - #define ROW SAD_SSE_422_LUMA_SUM_4(0) SAD_SSE_422_LUMA_SUM_4(8) SAD_SSE_422_LUMA_SUM_4(16) SAD_SSE_422_LUMA_SUM_4(24) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((long int)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -static int sad_sse_422_luma_32x32( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_422_LUMA_INIT - #define ROW SAD_SSE_422_LUMA_SUM_4(0) SAD_SSE_422_LUMA_SUM_4(8) SAD_SSE_422_LUMA_SUM_4(16) SAD_SSE_422_LUMA_SUM_4(24)\ - SAD_SSE_422_LUMA_SUM_4(32) SAD_SSE_422_LUMA_SUM_4(40) SAD_SSE_422_LUMA_SUM_4(48) SAD_SSE_422_LUMA_SUM_4(56)\ - SAD_SSE_NEXTROW - - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((long int)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -static int sad_sse_422_luma_4w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_422_LUMA_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_422_LUMA_SUM_4(0) - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -static int sad_sse_422_luma_8w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_422_LUMA_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_422_LUMA_SUM_4(0) - SAD_SSE_422_LUMA_SUM_4(8) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -static int sad_sse_422_luma_16w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_422_LUMA_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_422_LUMA_SUM_4(0) - SAD_SSE_422_LUMA_SUM_4(8) - SAD_SSE_422_LUMA_SUM_4(16) - SAD_SSE_422_LUMA_SUM_4(24) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -static int sad_sse_422_luma_32w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_422_LUMA_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_422_LUMA_SUM_4(0) - SAD_SSE_422_LUMA_SUM_4(8) - SAD_SSE_422_LUMA_SUM_4(16) - SAD_SSE_422_LUMA_SUM_4(24) - SAD_SSE_422_LUMA_SUM_4(32) - SAD_SSE_422_LUMA_SUM_4(40) - SAD_SSE_422_LUMA_SUM_4(48) - SAD_SSE_422_LUMA_SUM_4(56) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -static int sad_sse_422_luma_64w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_422_LUMA_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_422_LUMA_SUM_4(0) - SAD_SSE_422_LUMA_SUM_4(8) - SAD_SSE_422_LUMA_SUM_4(16) - SAD_SSE_422_LUMA_SUM_4(24) - SAD_SSE_422_LUMA_SUM_4(32) - SAD_SSE_422_LUMA_SUM_4(40) - SAD_SSE_422_LUMA_SUM_4(48) - SAD_SSE_422_LUMA_SUM_4(56) - SAD_SSE_422_LUMA_SUM_4(64) - SAD_SSE_422_LUMA_SUM_4(72) - SAD_SSE_422_LUMA_SUM_4(80) - SAD_SSE_422_LUMA_SUM_4(88) - SAD_SSE_422_LUMA_SUM_4(96) - SAD_SSE_422_LUMA_SUM_4(104) - SAD_SSE_422_LUMA_SUM_4(112) - SAD_SSE_422_LUMA_SUM_4(120) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; -} diff --git a/src/modules/normalize/Makefile b/src/modules/normalize/Makefile deleted file mode 100644 index 096e2e3..0000000 --- a/src/modules/normalize/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltnormalize$(LIBSUF) - -OBJS = factory.o \ - filter_volume.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/normalize/factory.c b/src/modules/normalize/factory.c deleted file mode 100644 index 3736d7d..0000000 --- a/src/modules/normalize/factory.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -extern mlt_filter filter_volume_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "volume", filter_volume_init ); -} diff --git a/src/modules/normalize/filter_volume.c b/src/modules/normalize/filter_volume.c deleted file mode 100644 index 3bc747c..0000000 --- a/src/modules/normalize/filter_volume.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - * filter_volume.c -- adjust audio volume - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -#include -#include -#include -#include -#include - -#define MAX_CHANNELS 6 -#define EPSILON 0.00001 - -/* The following normalise functions come from the normalize utility: - Copyright (C) 1999--2002 Chris Vaill */ - -#define samp_width 16 - -#ifndef ROUND -# define ROUND(x) floor((x) + 0.5) -#endif - -#define DBFSTOAMP(x) pow(10,(x)/20.0) - -/** Return nonzero if the two strings are equal, ignoring case, up to - the first n characters. -*/ -int strncaseeq(const char *s1, const char *s2, size_t n) -{ - for ( ; n > 0; n--) - { - if (tolower(*s1++) != tolower(*s2++)) - return 0; - } - return 1; -} - -/** Limiter function. - - / tanh((x + lev) / (1-lev)) * (1-lev) - lev (for x < -lev) - | - x' = | x (for |x| <= lev) - | - \ tanh((x - lev) / (1-lev)) * (1-lev) + lev (for x > lev) - - With limiter level = 0, this is equivalent to a tanh() function; - with limiter level = 1, this is equivalent to clipping. -*/ -static inline double limiter( double x, double lmtr_lvl ) -{ - double xp = x; - - if (x < -lmtr_lvl) - xp = tanh((x + lmtr_lvl) / (1-lmtr_lvl)) * (1-lmtr_lvl) - lmtr_lvl; - else if (x > lmtr_lvl) - xp = tanh((x - lmtr_lvl) / (1-lmtr_lvl)) * (1-lmtr_lvl) + lmtr_lvl; - -// if ( x != xp ) -// fprintf( stderr, "filter_volume: sample %f limited %f\n", x, xp ); - - return xp; -} - - -/** Takes a full smoothing window, and returns the value of the center - element, smoothed. - - Currently, just does a mean filter, but we could do a median or - gaussian filter here instead. -*/ -static inline double get_smoothed_data( double *buf, int count ) -{ - int i, j; - double smoothed = 0; - - for ( i = 0, j = 0; i < count; i++ ) - { - if ( buf[ i ] != -1.0 ) - { - smoothed += buf[ i ]; - j++; - } - } - smoothed /= j; -// fprintf( stderr, "smoothed over %d values, result %f\n", j, smoothed ); - - return smoothed; -} - -/** Get the max power level (using RMS) and peak level of the audio segment. - */ -double signal_max_power( int16_t *buffer, int channels, int samples, int16_t *peak ) -{ - // Determine numeric limits - int bytes_per_samp = (samp_width - 1) / 8 + 1; - int16_t max = (1 << (bytes_per_samp * 8 - 1)) - 1; - int16_t min = -max - 1; - - double *sums = (double *) calloc( channels, sizeof(double) ); - int c, i; - int16_t sample; - double pow, maxpow = 0; - - /* initialize peaks to effectively -inf and +inf */ - int16_t max_sample = min; - int16_t min_sample = max; - - for ( i = 0; i < samples; i++ ) - { - for ( c = 0; c < channels; c++ ) - { - sample = *buffer++; - sums[ c ] += (double) sample * (double) sample; - - /* track peak */ - if ( sample > max_sample ) - max_sample = sample; - else if ( sample < min_sample ) - min_sample = sample; - } - } - for ( c = 0; c < channels; c++ ) - { - pow = sums[ c ] / (double) samples; - if ( pow > maxpow ) - maxpow = pow; - } - - free( sums ); - - /* scale the pow value to be in the range 0.0 -- 1.0 */ - maxpow /= ( (double) min * (double) min); - - if ( -min_sample > max_sample ) - *peak = min_sample / (double) min; - else - *peak = max_sample / (double) max; - - return sqrt( maxpow ); -} - -/* ------ End normalize functions --------------------------------------- */ - -/** Get the audio. -*/ - -static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the properties of the a frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - double gain = mlt_properties_get_double( properties, "volume.gain" ); - double max_gain = mlt_properties_get_double( properties, "volume.max_gain" ); - double limiter_level = 0.5; /* -6 dBFS */ - int normalise = mlt_properties_get_int( properties, "volume.normalise" ); - double amplitude = mlt_properties_get_double( properties, "volume.amplitude" ); - int i, j; - double sample; - int16_t peak; - - // Get the filter from the frame - mlt_filter this = mlt_properties_get_data( properties, "filter_volume", NULL ); - - // Get the properties from the filter - mlt_properties filter_props = MLT_FILTER_PROPERTIES( this ); - - if ( mlt_properties_get( properties, "volume.limiter" ) != NULL ) - limiter_level = mlt_properties_get_double( properties, "volume.limiter" ); - - // Get the producer's audio - mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); -// fprintf( stderr, "filter_volume: frequency %d\n", *frequency ); - - // Determine numeric limits - int bytes_per_samp = (samp_width - 1) / 8 + 1; - int samplemax = (1 << (bytes_per_samp * 8 - 1)) - 1; - int samplemin = -samplemax - 1; - - if ( normalise ) - { - int window = mlt_properties_get_int( filter_props, "window" ); - double *smooth_buffer = mlt_properties_get_data( filter_props, "smooth_buffer", NULL ); - - if ( window > 0 && smooth_buffer != NULL ) - { - int smooth_index = mlt_properties_get_int( filter_props, "_smooth_index" ); - - // Compute the signal power and put into smoothing buffer - smooth_buffer[ smooth_index ] = signal_max_power( *buffer, *channels, *samples, &peak ); -// fprintf( stderr, "filter_volume: raw power %f ", smooth_buffer[ smooth_index ] ); - if ( smooth_buffer[ smooth_index ] > EPSILON ) - { - mlt_properties_set_int( filter_props, "_smooth_index", ( smooth_index + 1 ) % window ); - - // Smooth the data and compute the gain -// fprintf( stderr, "smoothed %f over %d frames\n", get_smoothed_data( smooth_buffer, window ), window ); - gain *= amplitude / get_smoothed_data( smooth_buffer, window ); - } - } - else - { - gain *= amplitude / signal_max_power( *buffer, *channels, *samples, &peak ); - } - } - -// if ( gain > 1.0 && normalise ) -// fprintf(stderr, "filter_volume: limiter level %f gain %f\n", limiter_level, gain ); - - if ( max_gain > 0 && gain > max_gain ) - gain = max_gain; - - // Initialise filter's previous gain value to prevent an inadvertant jump from 0 - mlt_position last_position = mlt_properties_get_position( filter_props, "_last_position" ); - mlt_position current_position = mlt_frame_get_position( frame ); - if ( mlt_properties_get( filter_props, "_previous_gain" ) == NULL - || current_position != last_position + 1 ) - mlt_properties_set_double( filter_props, "_previous_gain", gain ); - - // Start the gain out at the previous - double previous_gain = mlt_properties_get_double( filter_props, "_previous_gain" ); - - // Determine ramp increment - double gain_step = ( gain - previous_gain ) / *samples; -// fprintf( stderr, "filter_volume: previous gain %f current gain %f step %f\n", previous_gain, gain, gain_step ); - - // Save the current gain for the next iteration - mlt_properties_set_double( filter_props, "_previous_gain", gain ); - mlt_properties_set_position( filter_props, "_last_position", current_position ); - - // Ramp from the previous gain to the current - gain = previous_gain; - - int16_t *p = *buffer; - - // Apply the gain - for ( i = 0; i < *samples; i++ ) - { - for ( j = 0; j < *channels; j++ ) - { - sample = *p * gain; - *p = ROUND( sample ); - - if ( gain > 1.0 ) - { - /* use limiter function instead of clipping */ - if ( normalise ) - *p = ROUND( samplemax * limiter( sample / (double) samplemax, limiter_level ) ); - - /* perform clipping */ - else if ( sample > samplemax ) - *p = samplemax; - else if ( sample < samplemin ) - *p = samplemin; - } - p++; - } - gain += gain_step; - } - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - mlt_properties filter_props = MLT_FILTER_PROPERTIES( this ); - - // Parse the gain property - if ( mlt_properties_get( properties, "gain" ) == NULL ) - { - double gain = 1.0; // no adjustment - - if ( mlt_properties_get( filter_props, "gain" ) != NULL ) - { - char *p = mlt_properties_get( filter_props, "gain" ); - - if ( strncaseeq( p, "normalise", 9 ) ) - mlt_properties_set( filter_props, "normalise", "" ); - else - { - if ( strcmp( p, "" ) != 0 ) - gain = fabs( strtod( p, &p) ); - - while ( isspace( *p ) ) - p++; - - /* check if "dB" is given after number */ - if ( strncaseeq( p, "db", 2 ) ) - gain = DBFSTOAMP( gain ); - - // If there is an end adjust gain to the range - if ( mlt_properties_get( filter_props, "end" ) != NULL ) - { - // Determine the time position of this frame in the transition duration - mlt_position in = mlt_filter_get_in( this ); - mlt_position out = mlt_filter_get_out( this ); - mlt_position time = mlt_frame_get_position( frame ); - double position = ( double )( time - in ) / ( double )( out - in + 1 ); - - double end = -1; - char *p = mlt_properties_get( filter_props, "end" ); - if ( strcmp( p, "" ) != 0 ) - end = fabs( strtod( p, &p) ); - - while ( isspace( *p ) ) - p++; - - /* check if "dB" is given after number */ - if ( strncaseeq( p, "db", 2 ) ) - end = DBFSTOAMP( gain ); - - if ( end != -1 ) - gain += ( end - gain ) * position; - } - } - } - mlt_properties_set_double( properties, "volume.gain", gain ); - } - - // Parse the maximum gain property - if ( mlt_properties_get( filter_props, "max_gain" ) != NULL ) - { - char *p = mlt_properties_get( filter_props, "max_gain" ); - double gain = fabs( strtod( p, &p) ); // 0 = no max - - while ( isspace( *p ) ) - p++; - - /* check if "dB" is given after number */ - if ( strncaseeq( p, "db", 2 ) ) - gain = DBFSTOAMP( gain ); - - mlt_properties_set_double( properties, "volume.max_gain", gain ); - } - - // Parse the limiter property - if ( mlt_properties_get( filter_props, "limiter" ) != NULL ) - { - char *p = mlt_properties_get( filter_props, "limiter" ); - double level = 0.5; /* -6dBFS */ - if ( strcmp( p, "" ) != 0 ) - level = strtod( p, &p); - - while ( isspace( *p ) ) - p++; - - /* check if "dB" is given after number */ - if ( strncaseeq( p, "db", 2 ) ) - { - if ( level > 0 ) - level = -level; - level = DBFSTOAMP( level ); - } - else - { - if ( level < 0 ) - level = -level; - } - mlt_properties_set_double( properties, "volume.limiter", level ); - } - - // Parse the normalise property - if ( mlt_properties_get( filter_props, "normalise" ) != NULL ) - { - char *p = mlt_properties_get( filter_props, "normalise" ); - double amplitude = 0.2511886431509580; /* -12dBFS */ - if ( strcmp( p, "" ) != 0 ) - amplitude = strtod( p, &p); - - while ( isspace( *p ) ) - p++; - - /* check if "dB" is given after number */ - if ( strncaseeq( p, "db", 2 ) ) - { - if ( amplitude > 0 ) - amplitude = -amplitude; - amplitude = DBFSTOAMP( amplitude ); - } - else - { - if ( amplitude < 0 ) - amplitude = -amplitude; - if ( amplitude > 1.0 ) - amplitude = 1.0; - } - - // If there is an end adjust gain to the range - if ( mlt_properties_get( filter_props, "end" ) != NULL ) - { - // Determine the time position of this frame in the transition duration - mlt_position in = mlt_filter_get_in( this ); - mlt_position out = mlt_filter_get_out( this ); - mlt_position time = mlt_frame_get_position( frame ); - double position = ( double )( time - in ) / ( double )( out - in + 1 ); - amplitude *= position; - } - mlt_properties_set_int( properties, "volume.normalise", 1 ); - mlt_properties_set_double( properties, "volume.amplitude", amplitude ); - } - - // Parse the window property and allocate smoothing buffer if needed - int window = mlt_properties_get_int( filter_props, "window" ); - if ( mlt_properties_get( filter_props, "smooth_buffer" ) == NULL && window > 1 ) - { - // Create a smoothing buffer for the calculated "max power" of frame of audio used in normalisation - double *smooth_buffer = (double*) calloc( window, sizeof( double ) ); - int i; - for ( i = 0; i < window; i++ ) - smooth_buffer[ i ] = -1.0; - mlt_properties_set_data( filter_props, "smooth_buffer", smooth_buffer, 0, free, NULL ); - } - - // Put a filter reference onto the frame - mlt_properties_set_data( properties, "filter_volume", this, 0, NULL, NULL ); - - // Override the get_audio method - mlt_frame_push_audio( frame, filter_get_audio ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_volume_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 ); - if ( this != NULL && mlt_filter_init( this, NULL ) == 0 ) - { - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - this->process = filter_process; - if ( arg != NULL ) - mlt_properties_set( properties, "gain", arg ); - - mlt_properties_set_int( properties, "window", 75 ); - mlt_properties_set( properties, "max_gain", "20dB" ); - } - return this; -} diff --git a/src/modules/normalize/gpl b/src/modules/normalize/gpl deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/oldfilm/Makefile b/src/modules/oldfilm/Makefile deleted file mode 100644 index 90c13c3..0000000 --- a/src/modules/oldfilm/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltoldfilm$(LIBSUF) - -OBJS = factory.o \ - filter_oldfilm.o \ - filter_dust.o \ - filter_lines.o \ - filter_grain.o \ - filter_tcolor.o \ - filter_vignette.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt -LDFLAGS += -lm - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - install -d $(DESTDIR)$(prefix)/share/mlt/oldfilm - install -m 644 *.svg "$(DESTDIR)$(prefix)/share/mlt/oldfilm" - install -m 644 *.yml "$(DESTDIR)$(prefix)/share/mlt/oldfilm" - - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/oldfilm/dust1.svg b/src/modules/oldfilm/dust1.svg deleted file mode 100644 index db59d4d..0000000 --- a/src/modules/oldfilm/dust1.svg +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - diff --git a/src/modules/oldfilm/dust2.svg b/src/modules/oldfilm/dust2.svg deleted file mode 100644 index 055a1d3..0000000 --- a/src/modules/oldfilm/dust2.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/src/modules/oldfilm/dust3.svg b/src/modules/oldfilm/dust3.svg deleted file mode 100644 index d9c4089..0000000 --- a/src/modules/oldfilm/dust3.svg +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - diff --git a/src/modules/oldfilm/dust4.svg b/src/modules/oldfilm/dust4.svg deleted file mode 100644 index 19b5a19..0000000 --- a/src/modules/oldfilm/dust4.svg +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - diff --git a/src/modules/oldfilm/dust5.svg b/src/modules/oldfilm/dust5.svg deleted file mode 100644 index ca9b24b..0000000 --- a/src/modules/oldfilm/dust5.svg +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - diff --git a/src/modules/oldfilm/factory.c b/src/modules/oldfilm/factory.c deleted file mode 100644 index bb7c074..0000000 --- a/src/modules/oldfilm/factory.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (c) 2007 Marco Gittler - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -extern mlt_filter filter_dust_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_grain_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_lines_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_oldfilm_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_tcolor_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_vignette_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -static mlt_properties oldfilm_metadata( mlt_service_type type, const char *id, void *data ) -{ - char file[ PATH_MAX ]; - snprintf( file, PATH_MAX, "%s/oldfilm/filter_%s.yml", mlt_environment( "MLT_DATA" ), id ); - return mlt_properties_parse_yaml( file ); -} - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "oldfilm", filter_oldfilm_init ); - MLT_REGISTER( filter_type, "dust", filter_dust_init ); - MLT_REGISTER( filter_type, "lines", filter_lines_init ); - MLT_REGISTER( filter_type, "grain", filter_grain_init ); - MLT_REGISTER( filter_type, "tcolor", filter_tcolor_init ); - MLT_REGISTER( filter_type, "vignette", filter_vignette_init ); - - MLT_REGISTER_METADATA( filter_type, "vignette", oldfilm_metadata, NULL ); - MLT_REGISTER_METADATA( filter_type, "tcolor", oldfilm_metadata, NULL ); - MLT_REGISTER_METADATA( filter_type, "grain", oldfilm_metadata, NULL ); - MLT_REGISTER_METADATA( filter_type, "lines", oldfilm_metadata, NULL ); - MLT_REGISTER_METADATA( filter_type, "dust", oldfilm_metadata, NULL ); - MLT_REGISTER_METADATA( filter_type, "oldfilm", oldfilm_metadata, NULL ); - -} - - - diff --git a/src/modules/oldfilm/fdust.svg b/src/modules/oldfilm/fdust.svg deleted file mode 100644 index 693aa39..0000000 --- a/src/modules/oldfilm/fdust.svg +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/src/modules/oldfilm/filter_dust.c b/src/modules/oldfilm/filter_dust.c deleted file mode 100644 index fc62024..0000000 --- a/src/modules/oldfilm/filter_dust.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * filter_dust.c -- dust filter - * Copyright (c) 2007 Marco Gittler - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//#include -//#include -#include - -#include -#include -#include -#include -#include - -static void overlay_image(uint8_t *src, int src_width, int src_height , uint8_t * overlay, int overlay_width, int overlay_height, uint8_t * alpha , int xpos, int ypos, int upsidedown , int mirror ){ - int x,y; - - for (y=ypos;y=0 && (y-ypos)0 ){ - int overlay_x = mirror ? overlay_width - ( x - xpos ) -1 : ( x - xpos ); - double alp=(double)*(alpha+ overlay_width * overlay_y + overlay_x )/255.0; - uint8_t* image_pixel = scanline_image + x * 2; - uint8_t* overlay_pixel = scanline_overlay + overlay_x * 2; - - *image_pixel=(double)(*overlay_pixel)*alp+ (double)*image_pixel*(1.0-alp) ; - if (xpos%2==0) - image_pixel++; - else - image_pixel+=3; - - mirror? overlay_pixel-- : overlay_pixel++; - - *image_pixel=(double)(*(overlay_pixel))*alp + (double)(*image_pixel )*(1.0-alp) ; - } - - } - } - } -} - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_filter filter = mlt_frame_pop_service( this ); - - int maxdia = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "maxdiameter" ); - int maxcount = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "maxcount" ); - - mlt_position in = mlt_filter_get_in( filter ); - mlt_position out = mlt_filter_get_out( filter ); - mlt_position time = mlt_frame_get_position( this ); - double position = ( double )( time - in ) / ( double )( out - in + 1 ); - - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - // load svg - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - char *factory = mlt_properties_get( properties, "factory" ); - char temp[1204]=""; - sprintf( temp, "%s/oldfilm/", mlt_environment( "MLT_DATA" ) ); - - mlt_properties direntries=mlt_properties_new(); - mlt_properties_dir_list(direntries,temp,"dust*.svg",1); - - if (!maxcount) - return 0; - srand(position*10000); - - int im=rand()%maxcount; - int piccount=mlt_properties_count(direntries); - while (im-- && piccount){ - - int picnum=rand()%piccount; - - int y1=rand()%*height; - int x1=rand()%*width; - char resource[1024]=""; - char savename[1024]="",savename1[1024]="", cachedy[100]; - int dx=(*width*maxdia/100); - int luma_width,luma_height; - uint8_t *luma_image = NULL; - uint8_t *alpha =NULL; - int updown= rand()%2; - int mirror=rand()%2; - - sprintf(resource,"%s",mlt_properties_get_value(direntries,picnum)); - sprintf(savename,"cache-%d-%d",picnum,dx); - sprintf(savename1,"cache-alpha-%d-%d",picnum,dx); - sprintf(cachedy,"cache-dy-%d-%d",picnum,dx); - - luma_image= mlt_properties_get_data( properties , savename , NULL ); - alpha= mlt_properties_get_data( properties , savename1 , NULL ); - - if (luma_image == NULL || alpha == NULL ){ - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) ); - mlt_producer producer = mlt_factory_producer( profile, factory, resource ); - - if ( producer != NULL ) - { - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - mlt_properties_set( producer_properties, "eof", "loop" ); - mlt_frame luma_frame = NULL; - - if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &luma_frame, 0 ) == 0 ){ - - mlt_properties_set_double ( MLT_FRAME_PROPERTIES ( luma_frame ) , "consumer_aspect_ratio" , 1.0 ); - mlt_image_format luma_format = mlt_image_yuv422; - luma_width = dx; - luma_height = luma_width * mlt_properties_get_int( MLT_FRAME_PROPERTIES ( luma_frame ) , "height" ) / mlt_properties_get_int( MLT_FRAME_PROPERTIES ( luma_frame ) , "width" ); - - mlt_properties_set( MLT_FRAME_PROPERTIES( luma_frame ), "rescale.interp", "best" );// none/nearest/tiles/hyper - - mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 ); - alpha =mlt_frame_get_alpha_mask(luma_frame); - - uint8_t* savealpha=mlt_pool_alloc ( luma_width * luma_height ); - uint8_t* savepic=mlt_pool_alloc ( luma_width * luma_height * 2); - - if (savealpha && savepic ){ - memcpy (savealpha, alpha , luma_width * luma_height ); - memcpy (savepic, luma_image , luma_width * luma_height * 2); - - mlt_properties_set_data ( properties , savename , savepic , sizeof(uint8_t*) , mlt_pool_release, NULL ); - mlt_properties_set_data ( properties , savename1 , savealpha , sizeof(uint8_t*) , mlt_pool_release, NULL ); - mlt_properties_set_int ( properties , cachedy , luma_height ); - - overlay_image(*image,*width,*height,luma_image,luma_width,luma_height, alpha, x1, y1 , updown , mirror ); - } - mlt_frame_close( luma_frame ); - } - mlt_producer_close( producer ); - } - }else { - overlay_image ( *image , *width, *height , luma_image , dx , mlt_properties_get_int ( properties , cachedy ) , alpha , x1 , y1 , updown , mirror ); - } - } - if (piccount>0 ) - return 0; - if ( error == 0 && *image && *format == mlt_image_yuv422 ) - { - - int h = *height; - int w = *width; - if (maxcount==0) - return 0; - - int im=rand()%maxcount; - - while (im-- ){ - int type=im%2; - int y1=rand()%h; - int x1=rand()%w; - int dx=rand()%maxdia; - int dy=rand()%maxdia; - int x=0,y=0;//,v=0; - double v=0.0; - for ( x = -dx ; x < dx ; x++ ) - for ( y = -dy ; y < dy ; y++ ) { - if ( x1+x < w && x1+x > 0 && y1+y < h && y1+y > 0 ){ - uint8_t *pix=*image+(y+y1)*w*2+(x+x1)*2; - //v=(1.0-fabs(x)/dx)*(1.0-fabs(y)/dy); - v=pow((double)x/(double)dx*5.0,2.0)+pow((double)y/(double)dy*5.0,2.0); - if (v>10) - v=10; - v=1.0-(v/10.0); - - switch(type){ - case 0: - *pix-=(*pix)*v; - break; - case 1: - *pix+=(255-*pix)*v; - break; - } - } - } - } - } - - return error; -} - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - - -mlt_filter filter_dust_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "maxdiameter", "2" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "maxcount", "10" ); - } - return this; -} - - diff --git a/src/modules/oldfilm/filter_dust.yml b/src/modules/oldfilm/filter_dust.yml deleted file mode 100644 index 7460b60..0000000 --- a/src/modules/oldfilm/filter_dust.yml +++ /dev/null @@ -1,47 +0,0 @@ -schema_version: 0.1 -type: filter # consumer, filter, producer, or transition -identifier: dust -title: Dust -version: 0.2.5 -copyright: Copyright (C) 2008 Marco Gittler -license: GPL -language: en -url: none -creator: Marco Gittler -tags: - - Video # this may produce video -description: Add dust and specks to the Video, as in old movies -icon: - filename: oldfilm/fdust.svg # relative to $MLT_DATA/modules/ - content-type: image/svg - -notes: Implementation or additional usage notes go here. -bugs: # this can be just for documentation, or the tool may disclose it to help user avoid pitfalls - - need to do some speed improvement. - -parameters: - - identifier: maxdiameter - title: Maximal Diameter - type: integer - description: Maximal diameter of a dust piece - readonly: no - required: yes - minimum: 0 - maximum: 100 - default: 2 - mutable: no - widget: spinner - unit: % - - - identifier: maxcount - title: Maximal number of dust - type: integer - description: How many dust pieces are on the image - readonly: no - required: yes - minimum: 0 - maximum: 400 - default: 10 - mutable: no - widget: spinner - diff --git a/src/modules/oldfilm/filter_grain.c b/src/modules/oldfilm/filter_grain.c deleted file mode 100644 index 296da5a..0000000 --- a/src/modules/oldfilm/filter_grain.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * filter_grain.c -- grain filter - * Copyright (c) 2007 Marco Gittler - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include -#define MIN(a,b) (ab?a:b) - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - mlt_filter filter = mlt_frame_pop_service( this ); - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - if ( error == 0 && *image && *format == mlt_image_yuv422 ) - { - int h = *height; - int w = *width; - - mlt_position in = mlt_filter_get_in( filter ); - mlt_position out = mlt_filter_get_out( filter ); - mlt_position time = mlt_frame_get_position( this ); - double position = ( double )( time - in ) / ( double )( out - in + 1 ); - srand(position*10000); - - int noise = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "noise" ); - double contrast = mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "contrast" )/100.0; - double brightness = 127.0 * (mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "brightness" )-100.0)/100.0; - - int x=0,y=0,pix=0; - for (x=0;x20){ - pix= MIN ( MAX ( ( (double)*pixel -127.0 ) * contrast + 127.0 + brightness , 0 ) , 255 ) ; - if (noise>0) - pix-=(rand()%noise-noise); - - *pixel= MIN ( MAX ( pix , 0 ) , 255 ); - } - //*(pixel+1)= MIN ( MAX ( ( (double)*(pixel+1) -127.0 ) * .5 + 127.0 , 0 ) , 255 ) ; - } - } - - return error; -} - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -mlt_filter filter_grain_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "noise", "40" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "contrast", "160" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "brightness", "70" ); - } - return this; -} - diff --git a/src/modules/oldfilm/filter_grain.yml b/src/modules/oldfilm/filter_grain.yml deleted file mode 100644 index b5e6153..0000000 --- a/src/modules/oldfilm/filter_grain.yml +++ /dev/null @@ -1,58 +0,0 @@ -schema_version: 0.1 -type: filter # consumer, filter, producer, or transition -identifier: grain -title: Grain -version: 0.2.5 -copyright: Copyright (C) 2008 Marco Gittler -license: GPL -language: en -url: none -creator: Marco Gittler -tags: - - Video # this may produce video -description: Grain over the Image -icon: - filename: oldfilm/grain.svg # relative to $MLT_DATA/modules/ - content-type: image/svg - -notes: Implementation or additional usage notes go here. -bugs: # this can be just for documentation, or the tool may disclose it to help user avoid pitfalls - - need to do some speed improvement. - -parameters: - - identifier: noise - title: Noise - type: integer - description: Maximal value of noise - readonly: no - required: yes - minimum: 0 - maximum: 200 - default: 40 - mutable: no - widget: spinner - unit: % - - - identifier: contrast - title: Contrast - type: integer - description: Adjust contrast for the image - readonly: no - required: yes - minimum: 0 - maximum: 400 - default: 160 - mutable: no - widget: spinner - - - identifier: brightness - title: Brightness - type: integer - description: Adjust brightness for the image - readonly: no - required: yes - minimum: 0 - maximum: 400 - default: 70 - mutable: no - widget: spinner diff --git a/src/modules/oldfilm/filter_lines.c b/src/modules/oldfilm/filter_lines.c deleted file mode 100644 index 7d3e415..0000000 --- a/src/modules/oldfilm/filter_lines.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * filter_lines.c -- lines filter - * Copyright (c) 2007 Marco Gittler - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - mlt_filter filter = mlt_frame_pop_service( this ); - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - if ( error == 0 && *image && *format == mlt_image_yuv422 ) - { - int h = *height; - int w = *width; - - int width_line = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "width" ); - int num = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "num" ); - double maxdarker= (double)mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "darker" ) ; - double maxlighter=(double)mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "lighter" ) ; - //int frame = mlt_properties_get_int( this, "_position" ); - char buf[256]; - char typebuf[256]; - - mlt_position in = mlt_filter_get_in( filter ); - mlt_position out = mlt_filter_get_out( filter ); - mlt_position time = mlt_frame_get_position( this ); - double position = ( double )( time - in ) / ( double )( out - in + 1 ); - srand(position*10000); - if (!width_line) - return 0; - - while (num--){ - int type=(rand()%3)+1; - int x1=(double)w*rand()/RAND_MAX; - int dx=rand()%width_line; - int x=0,y=0; - int ystart=rand()%h; - int yend=rand()%h; - - sprintf(buf,"line%d",num); - sprintf(typebuf,"typeline%d",num); - maxlighter+=rand()%30-15; - maxdarker+=rand()%30-15; - - if (mlt_properties_get_int(MLT_FILTER_PROPERTIES( filter ),buf)==0){ - mlt_properties_set_int(MLT_FILTER_PROPERTIES( filter ),buf,x1); - } - - if (mlt_properties_get_int(MLT_FILTER_PROPERTIES( filter ),typebuf)==0 ){ - mlt_properties_set_int(MLT_FILTER_PROPERTIES( filter ),typebuf,type); - } - - - x1=mlt_properties_get_int(MLT_FILTER_PROPERTIES( filter ),buf); - type=mlt_properties_get_int(MLT_FILTER_PROPERTIES( filter ),typebuf); - if (position!=mlt_properties_get_double(MLT_FILTER_PROPERTIES( filter ),"last_oldfilm_line_pos")){ - x1+=(rand()%11-5); - } - - if (yend0){ - uint8_t* pixel=(*image+(y)*w*2+(x+x1)*2); - double diff=1.0-fabs(x)/dx; - switch(type){ - case 1: //blackline - *pixel-=((double)*pixel*diff*maxdarker/100.0); - break; - case 2: //whiteline - *pixel+=((255.0-(double)*pixel)*diff*maxlighter/100.0); - break; - case 3: //greenline - *(pixel+1)-=((*(pixel+1))*diff*maxlighter/100.0); - break; - } - - } - mlt_properties_set_int(MLT_FILTER_PROPERTIES( filter ),buf,x1); - } - mlt_properties_set_double(MLT_FILTER_PROPERTIES( filter ),"last_oldfilm_line_pos",position); - } - - return error; -} - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -mlt_filter filter_lines_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "width", "2" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "num", "5" ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "darker" , 40 ) ; - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "lighter" , 40 ) ; - } - return this; -} - - diff --git a/src/modules/oldfilm/filter_lines.yml b/src/modules/oldfilm/filter_lines.yml deleted file mode 100644 index 5f13c51..0000000 --- a/src/modules/oldfilm/filter_lines.yml +++ /dev/null @@ -1,73 +0,0 @@ -schema_version: 0.1 -type: filter # consumer, filter, producer, or transition -identifier: lines -title: Scratchlines -version: 0.2.5 -copyright: Copyright (C) 2008 Marco Gittler -license: GPL -language: en -url: none -creator: Marco Gittler -tags: - - Video # this may produce video -description: Scratchlines over the Picture -icon: - filename: oldfilm/lines.svg # relative to $MLT_DATA/modules/ - content-type: image/svg - -notes: Implementation or additional usage notes go here. -bugs: # this can be just for documentation, or the tool may disclose it to help user avoid pitfalls - - need to do some speed improvement. - -parameters: - - identifier: width - title: Width of line - type: integer - description: Linewidth in picture - readonly: no - required: yes - minimum: 0 - maximum: 100 - default: 2 - mutable: no - widget: spinner - unit: pixel - - - identifier: num - title: Max number of lines - type: integer - description: Maximal number of lines in picture - readonly: no - required: yes - minimum: 0 - maximum: 100 - default: 5 - mutable: no - widget: spinner - unit: lines - - - identifier: darker - title: Max darker - type: integer - description: Make image up to n values darker behind line - readonly: no - required: yes - minimum: 0 - maximum: 100 - default: 40 - mutable: no - widget: spinner - - - identifier: lighter - title: Max lighter - type: integer - description: Make image up to n values lighter behind line - readonly: no - required: yes - minimum: 0 - maximum: 100 - default: 40 - mutable: no - widget: spinner - - diff --git a/src/modules/oldfilm/filter_oldfilm.c b/src/modules/oldfilm/filter_oldfilm.c deleted file mode 100644 index 11a6c3e..0000000 --- a/src/modules/oldfilm/filter_oldfilm.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * filter_oldfilm.c -- oldfilm filter - * Copyright (c) 2007 Marco Gittler - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - mlt_filter filter = mlt_frame_pop_service( this ); - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - if ( error == 0 && *image && *format == mlt_image_yuv422 ) - { - int h = *height; - int w = *width; - - int x=0; - int y=0; - - mlt_position in = mlt_filter_get_in( filter ); - mlt_position out = mlt_filter_get_out( filter ); - mlt_position time = mlt_frame_get_position( this ); - double position = ( double )( time - in ) / ( double )( out - in + 1 ); - srand(position*10000); - - int delta = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "delta" ); - int every = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "every" ); - - int bdu = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "brightnessdelta_up" ); - int bdd = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "brightnessdelta_down" ); - int bevery = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "brightnessdelta_every" ); - - int diffpic=0; - if (delta) - diffpic=rand()%delta*2-delta; - - int brightdelta=0; - if ((bdu+bdd)!=0) - brightdelta=rand()%(bdu+bdd)-bdd; - if (rand()%100>every) - diffpic=0; - if (rand()%100>bevery) - brightdelta=0; - int yend,ydiff; - if (diffpic<=0){ - y=h; - yend=0; - ydiff=-1; - }else{ - y=0; - yend=h; - ydiff=1; - } - - while(y!=yend){ - //int newy=y+diffpic; - for (x=0;x0 && newyw)?w-x:-1; - int randy=((newy)<=frameborder)?(newy):((newy)+frameborder>h)?h-(y+diffpic):-1; - if (randx>=0 ){ - oldval=oldval*pow(((double)randx/(double)frameborder),1.5); - } - if (randy>=0 ){ - oldval=oldval*pow(((double)randy/(double)frameborder),1.5); - } - if (randx>=0 && randy>=0){ - //oldval=oldval*(randx*randy)/500.0; - } - */ - if ( ((int) oldval + brightdelta ) >255) - *pic=255; - else if ( ( (int) oldval+brightdelta ) <0){ - *pic=0; - }else - *pic=oldval+brightdelta; - *(pic+1)=*(pic+diffpic*w*2+1); - - }else{ - *pic=0; - //*(pic-1)=127; - } - - } - y+=ydiff; - } - } - - return error; -} - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -mlt_filter filter_oldfilm_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "delta", "14" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "every", "20" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "brightnessdelta_up" , "20" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "brightnessdelta_down" , "30" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "brightnessdelta_every" , "70" ); - } - return this; -} - diff --git a/src/modules/oldfilm/filter_oldfilm.yml b/src/modules/oldfilm/filter_oldfilm.yml deleted file mode 100644 index e0bdcaa..0000000 --- a/src/modules/oldfilm/filter_oldfilm.yml +++ /dev/null @@ -1,84 +0,0 @@ -schema_version: 0.1 -type: filter # consumer, filter, producer, or transition -identifier: oldfilm -title: Oldfilm -version: 0.2.5 -copyright: Copyright (C) 2008 Marco Gittler -license: GPL -language: en -url: none -creator: Marco Gittler -tags: - - Video # this may produce video -description: Moves the Picture up and down and random brightness change -icon: - filename: oldfilm/oldfilm.svg # relative to $MLT_DATA/modules/ - content-type: image/svg - -notes: Implementation or additional usage notes go here. -bugs: # this can be just for documentation, or the tool may disclose it to help user avoid pitfalls - - need to do some speed improvement. - -parameters: - - identifier: delta - title: Y-Delta - type: integer - description: Maximum delta value of Up/Down move - readonly: no - required: yes - minimum: 0 - maximum: 400 - default: 14 - mutable: no - widget: spinner - unit: pixel - - - identifier: every - title: % of picture have a delta - type: integer - description: n'th % have a Y-Delta in picture - readonly: no - required: yes - minimum: 0 - maximum: 100 - default: 20 - mutable: no - widget: spinner - unit: % - - - identifier: brightnessdelta_up - title: Brightness up - type: integer - description: Makes image n values lighter - readonly: no - required: yes - minimum: 0 - maximum: 100 - default: 20 - mutable: no - widget: spinner - - - identifier: brightnessdelta_down - title: Brightness down - type: integer - description: Makes image n values darker - readonly: no - required: yes - minimum: 0 - maximum: 100 - default: 20 - mutable: no - widget: spinner - - - identifier: brightnessdelta_every - title: Brightness every - type: integer - description: Change value only for n/100 - readonly: no - required: yes - minimum: 0 - maximum: 100 - default: 70 - mutable: no - widget: spinner - unit: % diff --git a/src/modules/oldfilm/filter_tcolor.c b/src/modules/oldfilm/filter_tcolor.c deleted file mode 100644 index 824f107..0000000 --- a/src/modules/oldfilm/filter_tcolor.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * filter_tcolor.c -- tcolor filter - * Copyright (c) 2007 Marco Gittler - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - -#define MIN(a,b) (aprocess = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "oversaturate_cr", "190" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "oversaturate_cb", "190" ); - } - return this; -} - - diff --git a/src/modules/oldfilm/filter_tcolor.yml b/src/modules/oldfilm/filter_tcolor.yml deleted file mode 100644 index fb8327e..0000000 --- a/src/modules/oldfilm/filter_tcolor.yml +++ /dev/null @@ -1,45 +0,0 @@ -schema_version: 0.1 -type: filter # consumer, filter, producer, or transition -identifier: tcolor -title: Technicolor -version: 0.2.5 -copyright: Copyright (C) 2008 Marco Gittler -license: GPL -language: en -url: none -creator: Marco Gittler -tags: - - Video # this may produce video -description: Oversaturate the Color in Video, like in old Technicolor movies -icon: -filename: oldfilm/tcolor.svg # relative to $MLT_DATA/modules/ - content-type: image/svg - -notes: Implementation or additional usage notes go here. -bugs: # this can be just for documentation, or the tool may disclose it to help user avoid pitfalls - - need to do some speed improvement. - -parameters: - - identifier: oversaturate_cr # 'argument' is a reserved name for a value supplied to the factory - title: Blue/Yellow- axis - type: integer - description: Adjust factor for Blue/Yellow axis - readonly: no - required: yes - minimum: -400 - maximum: 400 - default: 190 - mutable: no - widget: spinner - - - identifier: oversaturate_cb - title: Red/Green-axis - type: integer - description: Adjust factor for Red/Green axis - readonly: no - required: yes - minimum: -400 - maximum: 400 - default: 190 - mutable: no - widget: spinner diff --git a/src/modules/oldfilm/filter_vignette.c b/src/modules/oldfilm/filter_vignette.c deleted file mode 100644 index e9e3f5d..0000000 --- a/src/modules/oldfilm/filter_vignette.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * filter_vignette.c -- vignette filter - * Copyright (c) 2007 Marco Gittler - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include -#define MIN(a,b) (adx){ //center, make not darker - continue; - } - else if (radius+smooth<=dx){//max dark after smooth area - delta=0.0; - }else{ - //double sigx=5.0-10.0*(double)(dx-radius+smooth)/(2.0*smooth);//smooth >10 inner area, <-10 in dark area - //delta=pow2[((int)((sigx+10.0)*SIGMOD_STEPS/20.0))];//sigmoidal - delta = ((double)(radius+smooth-dx)/(2.0*smooth));//linear - } - delta=MAX(max_opac,delta); - *pix=(double)(*pix)*delta; - *(pix+1)=((double)(*(pix+1)-127.0)*delta)+127.0; - } - } - // short a, short b, short c, short d - // a= gray val pix 1 - // b: +=blue, -=yellow - // c: =gray pix 2 - // d: +=red,-=green - } - - return error; -} - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - - -mlt_filter filter_vignette_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - //int i=0; - if ( this != NULL ) - { - /* - for (i=-SIGMOD_STEPS/2;iprocess = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "geometry", "80:50%:50%:50%:0" ); - //mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "end", "" ); - - } - return this; -} - - diff --git a/src/modules/oldfilm/filter_vignette.yml b/src/modules/oldfilm/filter_vignette.yml deleted file mode 100644 index a63bd47..0000000 --- a/src/modules/oldfilm/filter_vignette.yml +++ /dev/null @@ -1,35 +0,0 @@ -schema_version: 0.1 -type: filter # consumer, filter, producer, or transition -identifier: vignette -title: Vignette Effect -version: 0.2.5 -copyright: Copyright (C) 2008 Marco Gittler -license: GPL -language: en -url: none -creator: Marco Gittler -tags: - - Video # this may produce video -description: | - Vigentte around a point with adjustable smooth, radius, position - and transparency -icon: -filename: oldfilm/vignette.svg # relative to $MLT_DATA/modules/ - content-type: image/svg - -notes: Implementation or additional usage notes go here. -bugs: # this can be just for documentation, or the tool may disclose it to help user avoid pitfalls - - need to do some speed improvement. - -parameters: - - identifier: geometry # 'argument' is a reserved name for a value supplied to the factory - title: Geometry Value # the title can be used as a label for the widget - type: geometry - description: Start position, "smooth":"radius","X"x"Y","maxopac" - readonly: no - required: yes - mutable: no - format: %d:%d:%dx%d:%d - minimum: 0:0:0:0:0 - maximum: 100:100:100:100:100 - default: 80:50%:50%:50%:0 diff --git a/src/modules/oldfilm/grain.svg b/src/modules/oldfilm/grain.svg deleted file mode 100644 index bbf11b2..0000000 --- a/src/modules/oldfilm/grain.svg +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/src/modules/oldfilm/lines.svg b/src/modules/oldfilm/lines.svg deleted file mode 100644 index e517574..0000000 --- a/src/modules/oldfilm/lines.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/src/modules/oldfilm/oldfilm.svg b/src/modules/oldfilm/oldfilm.svg deleted file mode 100644 index b3a521f..0000000 --- a/src/modules/oldfilm/oldfilm.svg +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/src/modules/oldfilm/tcolor.svg b/src/modules/oldfilm/tcolor.svg deleted file mode 100644 index 1e5c452..0000000 --- a/src/modules/oldfilm/tcolor.svg +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/src/modules/oldfilm/vignette.svg b/src/modules/oldfilm/vignette.svg deleted file mode 100644 index 4758eb0..0000000 --- a/src/modules/oldfilm/vignette.svg +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/src/modules/plus/Makefile b/src/modules/plus/Makefile deleted file mode 100644 index 4003b42..0000000 --- a/src/modules/plus/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltplus$(LIBSUF) - -OBJS = factory.o \ - filter_affine.o \ - filter_charcoal.o \ - filter_invert.o \ - filter_sepia.o \ - transition_affine.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/plus/factory.c b/src/modules/plus/factory.c deleted file mode 100644 index 2666f7f..0000000 --- a/src/modules/plus/factory.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -extern mlt_filter filter_affine_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_charcoal_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_invert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_sepia_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_transition transition_affine_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "affine", filter_affine_init ); - MLT_REGISTER( filter_type, "charcoal", filter_charcoal_init ); - MLT_REGISTER( filter_type, "invert", filter_invert_init ); - MLT_REGISTER( filter_type, "sepia", filter_sepia_init ); - MLT_REGISTER( transition_type, "affine", transition_affine_init ); -} diff --git a/src/modules/plus/filter_affine.c b/src/modules/plus/filter_affine.c deleted file mode 100644 index cbf6caa..0000000 --- a/src/modules/plus/filter_affine.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * filter_affine.c -- affine filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the filter - mlt_filter filter = mlt_frame_pop_service( this ); - - // Get the properties - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - - // Get the image - int error = 0; //mlt_frame_get_image( this, image, format, width, height, 0 ); - - // Only process if we have no error and a valid colour space - if ( error == 0 && *format == mlt_image_yuv422 ) - { - mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL ); - mlt_transition transition = mlt_properties_get_data( properties, "transition", NULL ); - mlt_frame a_frame = NULL; - - if ( producer == NULL ) - { - char *background = mlt_properties_get( properties, "background" ); - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) ); - producer = mlt_factory_producer( profile, "fezzik", background ); - mlt_properties_set_data( properties, "producer", producer, 0, (mlt_destructor)mlt_producer_close, NULL ); - } - - if ( transition == NULL ) - { - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) ); - transition = mlt_factory_transition( profile, "affine", NULL ); - mlt_properties_set_data( properties, "transition", transition, 0, (mlt_destructor)mlt_transition_close, NULL ); - } - - if ( producer != NULL && transition != NULL ) - { - char *name = mlt_properties_get( properties, "_unique_id" ); - mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( this ), name ); - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( this ); - double consumer_ar = mlt_properties_get_double( frame_properties, "consumer_aspect_ratio" ); - mlt_properties_set_position( MLT_TRANSITION_PROPERTIES( transition ), "in", mlt_filter_get_in( filter ) ); - mlt_properties_set_position( MLT_TRANSITION_PROPERTIES( transition ), "out", mlt_filter_get_out( filter ) ); - mlt_producer_seek( producer, position ); - mlt_frame_set_position( this, position ); - mlt_properties_pass( MLT_PRODUCER_PROPERTIES( producer ), properties, "producer." ); - mlt_properties_pass( MLT_TRANSITION_PROPERTIES( transition ), properties, "transition." ); - mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &a_frame, 0 ); - mlt_properties_set( MLT_FRAME_PROPERTIES( a_frame ), "rescale.interp", "nearest" ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( a_frame ), "distort", 1 ); - - // Special case - aspect_ratio = 0 - if ( mlt_properties_get_double( frame_properties, "aspect_ratio" ) == 0 ) - mlt_properties_set_double( frame_properties, "aspect_ratio", consumer_ar ); - if ( mlt_properties_get_double( MLT_FRAME_PROPERTIES( a_frame ), "aspect_ratio" ) == 0 ) - mlt_properties_set_double( MLT_FRAME_PROPERTIES( a_frame ), "aspect_ratio", consumer_ar ); - mlt_properties_set_double( MLT_FRAME_PROPERTIES( a_frame ), "consumer_aspect_ratio", consumer_ar ); - - mlt_transition_process( transition, a_frame, this ); - mlt_frame_get_image( a_frame, image, format, width, height, writable ); - mlt_properties_set_data( frame_properties, "affine_frame", a_frame, 0, (mlt_destructor)mlt_frame_close, NULL ); - mlt_properties_set_data( frame_properties, "image", *image, *width * *height * 2, NULL, NULL ); - mlt_properties_set_data( frame_properties, "alpha", mlt_frame_get_alpha_mask( a_frame ), *width * *height, NULL, NULL ); - } - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Get the properties of the frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Get a unique name to store the frame position - char *name = mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "_unique_id" ); - - // Assign the current position to the name - mlt_properties_set_position( properties, name, mlt_frame_get_position( frame ) - mlt_filter_get_in( this ) ); - - // Push the frame filter - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_affine_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "background", "colour:black" ); - } - return this; -} - - diff --git a/src/modules/plus/filter_charcoal.c b/src/modules/plus/filter_charcoal.c deleted file mode 100644 index e99981a..0000000 --- a/src/modules/plus/filter_charcoal.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * filter_charcoal.c -- charcoal filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - -static inline int get_Y( uint8_t *pixels, int width, int height, int x, int y ) -{ - if ( x < 0 || x >= width || y < 0 || y >= height ) - { - return 235; - } - else - { - uint8_t *pixel = pixels + y * ( width << 1 ) + ( x << 1 ); - return *pixel; - } -} - -static inline int sqrti( int n ) -{ - int p = 0; - int q = 1; - int r = n; - int h = 0; - - while( q <= n ) - q = q << 2; - - while( q != 1 ) - { - q = q >> 2; - h = p + q; - p = p >> 1; - if ( r >= h ) - { - p = p + q; - r = r - h; - } - } - - return p; -} - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the filter - mlt_filter filter = mlt_frame_pop_service( this ); - - // Get the image - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - // Only process if we have no error and a valid colour space - if ( error == 0 && *format == mlt_image_yuv422 ) - { - // Get the charcoal scatter value - int x_scatter = mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "x_scatter" ); - int y_scatter = mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "y_scatter" ); - float scale = mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "scale" ); - float mix = mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "mix" ); - int invert = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "invert" ); - - // We'll process pixel by pixel - int x = 0; - int y = 0; - - // We need to create a new frame as this effect modifies the input - uint8_t *temp = mlt_pool_alloc( *width * *height * 2 ); - uint8_t *p = temp; - uint8_t *q = *image; - - // Calculations are carried out on a 3x3 matrix - int matrix[ 3 ][ 3 ]; - - // Used to carry out the matrix calculations - int sum1; - int sum2; - float sum; - int val; - - // Loop for each row - for ( y = 0; y < *height; y ++ ) - { - // Loop for each pixel - for ( x = 0; x < *width; x ++ ) - { - // Populate the matrix - matrix[ 0 ][ 0 ] = get_Y( *image, *width, *height, x - x_scatter, y - y_scatter ); - matrix[ 0 ][ 1 ] = get_Y( *image, *width, *height, x , y - y_scatter ); - matrix[ 0 ][ 2 ] = get_Y( *image, *width, *height, x + x_scatter, y - y_scatter ); - matrix[ 1 ][ 0 ] = get_Y( *image, *width, *height, x - x_scatter, y ); - matrix[ 1 ][ 2 ] = get_Y( *image, *width, *height, x + x_scatter, y ); - matrix[ 2 ][ 0 ] = get_Y( *image, *width, *height, x - x_scatter, y + y_scatter ); - matrix[ 2 ][ 1 ] = get_Y( *image, *width, *height, x , y + y_scatter ); - matrix[ 2 ][ 2 ] = get_Y( *image, *width, *height, x + x_scatter, y + y_scatter ); - - // Do calculations - sum1 = (matrix[2][0] - matrix[0][0]) + ( (matrix[2][1] - matrix[0][1]) << 1 ) + (matrix[2][2] - matrix[2][0]); - sum2 = (matrix[0][2] - matrix[0][0]) + ( (matrix[1][2] - matrix[1][0]) << 1 ) + (matrix[2][2] - matrix[2][0]); - sum = scale * sqrti( sum1 * sum1 + sum2 * sum2 ); - - // Assign value - *p ++ = !invert ? ( sum >= 16 && sum <= 235 ? 251 - sum : sum < 16 ? 235 : 16 ) : - ( sum >= 16 && sum <= 235 ? sum : sum < 16 ? 16 : 235 ); - q ++; - val = 128 + mix * ( *q ++ - 128 ); - val = val < 16 ? 16 : val > 240 ? 240 : val; - *p ++ = val; - } - } - - // Return the created image - *image = temp; - - // Store new and destroy old - mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "image", *image, *width * *height * 2, mlt_pool_release, NULL ); - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push the frame filter - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_charcoal_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "x_scatter", "1" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "y_scatter", "1" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "scale", "1.5" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "mix", "0" ); - } - return this; -} - diff --git a/src/modules/plus/filter_invert.c b/src/modules/plus/filter_invert.c deleted file mode 100644 index 4385fc8..0000000 --- a/src/modules/plus/filter_invert.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * filter_invert.c -- invert filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include -#include - -static inline int clamp( int v, int l, int u ) -{ - return v < l ? l : ( v > u ? u : v ); -} - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the image - mlt_filter filter = mlt_frame_pop_service( this ); - int mask = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "alpha" ); - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - // Only process if we have no error and a valid colour space - if ( error == 0 && *format == mlt_image_yuv422 ) - { - uint8_t *p = *image; - uint8_t *q = *image + *width * *height * 2; - uint8_t *r = *image; - - while ( p != q ) - { - *p ++ = clamp( 251 - *r ++, 16, 235 ); - *p ++ = clamp( 256 - *r ++, 16, 240 ); - } - - if ( mask ) - { - uint8_t *alpha = mlt_frame_get_alpha_mask( this ); - int size = *width * *height; - memset( alpha, mask, size ); - } - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push the frame filter - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_invert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - this->process = filter_process; - return this; -} - diff --git a/src/modules/plus/filter_sepia.c b/src/modules/plus/filter_sepia.c deleted file mode 100644 index aa20b23..0000000 --- a/src/modules/plus/filter_sepia.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * filter_sepia.c -- sepia filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the filter - mlt_filter filter = mlt_frame_pop_service( this ); - - // Get the image - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - // Only process if we have no error and a valid colour space - if ( error == 0 && *image && *format == mlt_image_yuv422 ) - { - // We modify the whole image - uint8_t *p = *image; - int h = *height; - int uneven = *width % 2; - int w = ( *width - uneven ) / 2; - int t; - - // Get u and v values - int u = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "u" ); - int v = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "v" ); - - // Loop through image - while( h -- ) - { - t = w; - while( t -- ) - { - p ++; - *p ++ = u; - p ++; - *p ++ = v; - } - if ( uneven ) - { - p ++; - *p ++ = u; - } - } - } - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push the frame filter - mlt_frame_push_service( frame, this ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_sepia_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "u", "75" ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "v", "150" ); - } - return this; -} - diff --git a/src/modules/plus/transition_affine.c b/src/modules/plus/transition_affine.c deleted file mode 100644 index 7197056..0000000 --- a/src/modules/plus/transition_affine.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - * transition_affine.c -- affine transformations - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include -#include -#include -#include -#include - -/** Calculate real geometry. -*/ - -static void geometry_calculate( mlt_transition this, const char *store, struct mlt_geometry_item_s *output, float position ) -{ - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - mlt_geometry geometry = mlt_properties_get_data( properties, store, NULL ); - int mirror_off = mlt_properties_get_int( properties, "mirror_off" ); - int repeat_off = mlt_properties_get_int( properties, "repeat_off" ); - int length = mlt_geometry_get_length( geometry ); - - // Allow wrapping - if ( !repeat_off && position >= length && length != 0 ) - { - int section = position / length; - position -= section * length; - if ( !mirror_off && section % 2 == 1 ) - position = length - position; - } - - // Fetch the key for the position - mlt_geometry_fetch( geometry, output, position ); -} - - -static mlt_geometry transition_parse_keys( mlt_transition this, const char *name, const char *store, int normalised_width, int normalised_height ) -{ - // Get the properties of the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - // Try to fetch it first - mlt_geometry geometry = mlt_properties_get_data( properties, store, NULL ); - - // Get the in and out position - mlt_position in = mlt_transition_get_in( this ); - mlt_position out = mlt_transition_get_out( this ); - - // Determine length and obtain cycle - int length = out - in + 1; - double cycle = mlt_properties_get_double( properties, "cycle" ); - - // Allow a geometry repeat cycle - if ( cycle >= 1 ) - length = cycle; - else if ( cycle > 0 ) - length *= cycle; - - if ( geometry == NULL ) - { - // Get the new style geometry string - char *property = mlt_properties_get( properties, name ); - - // Create an empty geometries object - geometry = mlt_geometry_init( ); - - // Parse the geometry if we have one - mlt_geometry_parse( geometry, property, length, normalised_width, normalised_height ); - - // Store it - mlt_properties_set_data( properties, store, geometry, 0, ( mlt_destructor )mlt_geometry_close, NULL ); - } - else - { - // Check for updates and refresh if necessary - mlt_geometry_refresh( geometry, mlt_properties_get( properties, name ), length, normalised_width, normalised_height ); - } - - return geometry; -} - -static mlt_geometry composite_calculate( mlt_transition this, struct mlt_geometry_item_s *result, int nw, int nh, float position ) -{ - // Structures for geometry - mlt_geometry start = transition_parse_keys( this, "geometry", "geometries", nw, nh ); - - // Do the calculation - geometry_calculate( this, "geometries", result, position ); - - return start; -} - -static inline float composite_calculate_key( mlt_transition this, const char *name, const char *store, int norm, float position ) -{ - // Struct for the result - struct mlt_geometry_item_s result; - - // Structures for geometry - transition_parse_keys( this, name, store, norm, 0 ); - - // Do the calculation - geometry_calculate( this, store, &result, position ); - - return result.x; -} - -typedef struct -{ - float matrix[3][3]; -} -affine_t; - -static void affine_init( float this[3][3] ) -{ - this[0][0] = 1; - this[0][1] = 0; - this[0][2] = 0; - this[1][0] = 0; - this[1][1] = 1; - this[1][2] = 0; - this[2][0] = 0; - this[2][1] = 0; - this[2][2] = 1; -} - -// Multiply two this affine transform with that -static void affine_multiply( float this[3][3], float that[3][3] ) -{ - float output[3][3]; - int i; - int j; - - for ( i = 0; i < 3; i ++ ) - for ( j = 0; j < 3; j ++ ) - output[i][j] = this[i][0] * that[j][0] + this[i][1] * that[j][1] + this[i][2] * that[j][2]; - - this[0][0] = output[0][0]; - this[0][1] = output[0][1]; - this[0][2] = output[0][2]; - this[1][0] = output[1][0]; - this[1][1] = output[1][1]; - this[1][2] = output[1][2]; - this[2][0] = output[2][0]; - this[2][1] = output[2][1]; - this[2][2] = output[2][2]; -} - -// Rotate by a given angle -static void affine_rotate_x( float this[3][3], float angle ) -{ - float affine[3][3]; - affine[0][0] = cos( angle * M_PI / 180 ); - affine[0][1] = 0 - sin( angle * M_PI / 180 ); - affine[0][2] = 0; - affine[1][0] = sin( angle * M_PI / 180 ); - affine[1][1] = cos( angle * M_PI / 180 ); - affine[1][2] = 0; - affine[2][0] = 0; - affine[2][1] = 0; - affine[2][2] = 1; - affine_multiply( this, affine ); -} - -static void affine_rotate_y( float this[3][3], float angle ) -{ - float affine[3][3]; - affine[0][0] = cos( angle * M_PI / 180 ); - affine[0][1] = 0; - affine[0][2] = 0 - sin( angle * M_PI / 180 ); - affine[1][0] = 0; - affine[1][1] = 1; - affine[1][2] = 0; - affine[2][0] = sin( angle * M_PI / 180 ); - affine[2][1] = 0; - affine[2][2] = cos( angle * M_PI / 180 ); - affine_multiply( this, affine ); -} - -static void affine_rotate_z( float this[3][3], float angle ) -{ - float affine[3][3]; - affine[0][0] = 1; - affine[0][1] = 0; - affine[0][2] = 0; - affine[1][0] = 0; - affine[1][1] = cos( angle * M_PI / 180 ); - affine[1][2] = sin( angle * M_PI / 180 ); - affine[2][0] = 0; - affine[2][1] = - sin( angle * M_PI / 180 ); - affine[2][2] = cos( angle * M_PI / 180 ); - affine_multiply( this, affine ); -} - -static void affine_scale( float this[3][3], float sx, float sy ) -{ - float affine[3][3]; - affine[0][0] = sx; - affine[0][1] = 0; - affine[0][2] = 0; - affine[1][0] = 0; - affine[1][1] = sy; - affine[1][2] = 0; - affine[2][0] = 0; - affine[2][1] = 0; - affine[2][2] = 1; - affine_multiply( this, affine ); -} - -// Shear by a given value -static void affine_shear( float this[3][3], float shear_x, float shear_y, float shear_z ) -{ - float affine[3][3]; - affine[0][0] = 1; - affine[0][1] = tan( shear_x * M_PI / 180 ); - affine[0][2] = 0; - affine[1][0] = tan( shear_y * M_PI / 180 ); - affine[1][1] = 1; - affine[1][2] = tan( shear_z * M_PI / 180 ); - affine[2][0] = 0; - affine[2][1] = 0; - affine[2][2] = 1; - affine_multiply( this, affine ); -} - -static void affine_offset( float this[3][3], int x, int y ) -{ - this[0][2] += x; - this[1][2] += y; -} - -// Obtain the mapped x coordinate of the input -static inline double MapX( float this[3][3], int x, int y ) -{ - return this[0][0] * x + this[0][1] * y + this[0][2]; -} - -// Obtain the mapped y coordinate of the input -static inline double MapY( float this[3][3], int x, int y ) -{ - return this[1][0] * x + this[1][1] * y + this[1][2]; -} - -static inline double MapZ( float this[3][3], int x, int y ) -{ - return this[2][0] * x + this[2][1] * y + this[2][2]; -} - -#define MAX( x, y ) x > y ? x : y -#define MIN( x, y ) x < y ? x : y - -static void affine_max_output( float this[3][3], float *w, float *h, float dz ) -{ - int tlx = MapX( this, -720, 576 ) / dz; - int tly = MapY( this, -720, 576 ) / dz; - int trx = MapX( this, 720, 576 ) / dz; - int try = MapY( this, 720, 576 ) / dz; - int blx = MapX( this, -720, -576 ) / dz; - int bly = MapY( this, -720, -576 ) / dz; - int brx = MapX( this, 720, -576 ) / dz; - int bry = MapY( this, 720, -576 ) / dz; - - int max_x; - int max_y; - int min_x; - int min_y; - - max_x = MAX( tlx, trx ); - max_x = MAX( max_x, blx ); - max_x = MAX( max_x, brx ); - - min_x = MIN( tlx, trx ); - min_x = MIN( min_x, blx ); - min_x = MIN( min_x, brx ); - - max_y = MAX( tly, try ); - max_y = MAX( max_y, bly ); - max_y = MAX( max_y, bry ); - - min_y = MIN( tly, try ); - min_y = MIN( min_y, bly ); - min_y = MIN( min_y, bry ); - - *w = ( float )( max_x - min_x + 1 ) / 1440.0; - *h = ( float )( max_y - min_y + 1 ) / 1152.0; -} - -#define IN_RANGE( v, r ) ( v >= - r / 2 && v < r / 2 ) - -static inline void get_affine( affine_t *affine, mlt_transition this, float position ) -{ - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - int keyed = mlt_properties_get_int( properties, "keyed" ); - affine_init( affine->matrix ); - - if ( keyed == 0 ) - { - float fix_rotate_x = mlt_properties_get_double( properties, "fix_rotate_x" ); - float fix_rotate_y = mlt_properties_get_double( properties, "fix_rotate_y" ); - float fix_rotate_z = mlt_properties_get_double( properties, "fix_rotate_z" ); - float rotate_x = mlt_properties_get_double( properties, "rotate_x" ); - float rotate_y = mlt_properties_get_double( properties, "rotate_y" ); - float rotate_z = mlt_properties_get_double( properties, "rotate_z" ); - float fix_shear_x = mlt_properties_get_double( properties, "fix_shear_x" ); - float fix_shear_y = mlt_properties_get_double( properties, "fix_shear_y" ); - float fix_shear_z = mlt_properties_get_double( properties, "fix_shear_z" ); - float shear_x = mlt_properties_get_double( properties, "shear_x" ); - float shear_y = mlt_properties_get_double( properties, "shear_y" ); - float shear_z = mlt_properties_get_double( properties, "shear_z" ); - float ox = mlt_properties_get_double( properties, "ox" ); - float oy = mlt_properties_get_double( properties, "oy" ); - - affine_rotate_x( affine->matrix, fix_rotate_x + rotate_x * position ); - affine_rotate_y( affine->matrix, fix_rotate_y + rotate_y * position ); - affine_rotate_z( affine->matrix, fix_rotate_z + rotate_z * position ); - affine_shear( affine->matrix, - fix_shear_x + shear_x * position, - fix_shear_y + shear_y * position, - fix_shear_z + shear_z * position ); - affine_offset( affine->matrix, ox, oy ); - } - else - { - float rotate_x = composite_calculate_key( this, "rotate_x", "rotate_x_info", 360, position ); - float rotate_y = composite_calculate_key( this, "rotate_y", "rotate_y_info", 360, position ); - float rotate_z = composite_calculate_key( this, "rotate_z", "rotate_z_info", 360, position ); - float shear_x = composite_calculate_key( this, "shear_x", "shear_x_info", 360, position ); - float shear_y = composite_calculate_key( this, "shear_y", "shear_y_info", 360, position ); - float shear_z = composite_calculate_key( this, "shear_z", "shear_z_info", 360, position ); - - affine_rotate_x( affine->matrix, rotate_x ); - affine_rotate_y( affine->matrix, rotate_y ); - affine_rotate_z( affine->matrix, rotate_z ); - affine_shear( affine->matrix, shear_x, shear_y, shear_z ); - } -} - -/** Get the image. -*/ - -static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the b frame from the stack - mlt_frame b_frame = mlt_frame_pop_frame( a_frame ); - - // Get the transition object - mlt_transition this = mlt_frame_pop_service( a_frame ); - - // Get the properties of the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - // Get the properties of the a frame - mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); - - // Get the properties of the b frame - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - - // Image, format, width, height and image for the b frame - uint8_t *b_image = NULL; - mlt_image_format b_format = mlt_image_yuv422; - int b_width; - int b_height; - - // Get the unique name to retrieve the frame position - char *name = mlt_properties_get( properties, "_unique_id" ); - - // Assign the current position to the name - mlt_position position = mlt_properties_get_position( a_props, name ); - mlt_position in = mlt_properties_get_position( properties, "in" ); - mlt_position out = mlt_properties_get_position( properties, "out" ); - int mirror = mlt_properties_get_position( properties, "mirror" ); - int length = out - in + 1; - - // Obtain the normalised width and height from the a_frame - int normalised_width = mlt_properties_get_int( a_props, "normalised_width" ); - int normalised_height = mlt_properties_get_int( a_props, "normalised_height" ); - - double consumer_ar = mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ; - - // Structures for geometry - struct mlt_geometry_item_s result; - - if ( mirror && position > length / 2 ) - position = abs( position - length ); - - // Fetch the a frame image - mlt_frame_get_image( a_frame, image, format, width, height, 1 ); - - // Calculate the region now - composite_calculate( this, &result, normalised_width, normalised_height, ( float )position ); - - // Fetch the b frame image - result.w = ( int )( result.w * *width / normalised_width ); - result.h = ( int )( result.h * *height / normalised_height ); - result.x = ( int )( result.x * *width / normalised_width ); - result.y = ( int )( result.y * *height / normalised_height ); - //result.w -= ( int )abs( result.w ) % 2; - //result.x -= ( int )abs( result.x ) % 2; - b_width = result.w; - b_height = result.h; - - if ( mlt_properties_get_double( b_props, "aspect_ratio" ) == 0.0 ) - mlt_properties_set_double( b_props, "aspect_ratio", consumer_ar ); - - if ( !strcmp( mlt_properties_get( a_props, "rescale.interp" ), "none" ) ) - { - mlt_properties_set( b_props, "rescale.interp", "nearest" ); - mlt_properties_set_double( b_props, "consumer_aspect_ratio", consumer_ar ); - } - else - { - mlt_properties_set( b_props, "rescale.interp", mlt_properties_get( a_props, "rescale.interp" ) ); - mlt_properties_set_double( b_props, "consumer_aspect_ratio", consumer_ar ); - } - - mlt_properties_set_int( b_props, "distort", mlt_properties_get_int( properties, "distort" ) ); - mlt_frame_get_image( b_frame, &b_image, &b_format, &b_width, &b_height, 0 ); - result.w = b_width; - result.h = b_height; - - // Check that both images are of the correct format and process - if ( *format == mlt_image_yuv422 && b_format == mlt_image_yuv422 ) - { - register int x, y; - register int dx, dy; - double dz; - float sw, sh; - - // Get values from the transition - float scale_x = mlt_properties_get_double( properties, "scale_x" ); - float scale_y = mlt_properties_get_double( properties, "scale_y" ); - int scale = mlt_properties_get_int( properties, "scale" ); - - uint8_t *p = *image; - uint8_t *q = *image; - - int cx = result.x + ( b_width >> 1 ); - int cy = result.y + ( b_height >> 1 ); - cx -= cx % 2; - - int lower_x = 0 - cx; - int upper_x = *width - cx; - int lower_y = 0 - cy; - int upper_y = *height - cy; - - int b_stride = b_width << 1; - int a_stride = *width << 1; - int x_offset = ( int )result.w >> 1; - int y_offset = ( int )result.h >> 1; - - uint8_t *alpha = mlt_frame_get_alpha_mask( b_frame ); - uint8_t *mask = mlt_frame_get_alpha_mask( a_frame ); - uint8_t *pmask = mask; - float mix; - - affine_t affine; - - get_affine( &affine, this, ( float )position ); - - q = *image; - - dz = MapZ( affine.matrix, 0, 0 ); - - if ( mask == NULL ) - { - mask = mlt_pool_alloc( *width * *height ); - pmask = mask; - memset( mask, 255, *width * *height ); - } - - if ( ( int )abs( dz * 1000 ) < 25 ) - goto getout; - - if ( scale ) - { - affine_max_output( affine.matrix, &sw, &sh, dz ); - affine_scale( affine.matrix, sw, sh ); - } - else if ( scale_x != 0 && scale_y != 0 ) - { - affine_scale( affine.matrix, scale_x, scale_y ); - } - - if ( alpha == NULL ) - { - for ( y = lower_y; y < upper_y; y ++ ) - { - p = q; - - for ( x = lower_x; x < upper_x; x ++ ) - { - dx = MapX( affine.matrix, x, y ) / dz + x_offset; - dy = MapY( affine.matrix, x, y ) / dz + y_offset; - - if ( dx >= 0 && dx < b_width && dy >=0 && dy < b_height ) - { - pmask ++; - dx -= dx & 1; - *p ++ = *( b_image + dy * b_stride + ( dx << 1 ) ); - *p ++ = *( b_image + dy * b_stride + ( dx << 1 ) + ( ( x & 1 ) << 1 ) + 1 ); - } - else - { - p += 2; - pmask ++; - } - } - - q += a_stride; - } - } - else - { - for ( y = lower_y; y < upper_y; y ++ ) - { - p = q; - - for ( x = lower_x; x < upper_x; x ++ ) - { - dx = MapX( affine.matrix, x, y ) / dz + x_offset; - dy = MapY( affine.matrix, x, y ) / dz + y_offset; - - if ( dx >= 0 && dx < b_width && dy >=0 && dy < b_height ) - { - *pmask ++ = *( alpha + dy * b_width + dx ); - mix = ( float )*( alpha + dy * b_width + dx ) / 255.0; - dx -= dx & 1; - *p = *p * ( 1 - mix ) + mix * *( b_image + dy * b_stride + ( dx << 1 ) ); - p ++; - *p = *p * ( 1 - mix ) + mix * *( b_image + dy * b_stride + ( dx << 1 ) + ( ( x & 1 ) << 1 ) + 1 ); - p ++; - } - else - { - p += 2; - pmask ++; - } - } - - q += a_stride; - } - } - -getout: - a_frame->get_alpha_mask = NULL; - mlt_properties_set_data( a_props, "alpha", mask, 0, mlt_pool_release, NULL ); - } - - return 0; -} - -/** Affine transition processing. -*/ - -static mlt_frame transition_process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame ) -{ - // Get a unique name to store the frame position - char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( transition ), "_unique_id" ); - - // Assign the current position to the name - mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); - mlt_properties_set_position( a_props, name, mlt_frame_get_position( a_frame ) ); - - // Push the transition on to the frame - mlt_frame_push_service( a_frame, transition ); - - // Push the b_frame on to the stack - mlt_frame_push_frame( a_frame, b_frame ); - - // Push the transition method - mlt_frame_push_get_image( a_frame, transition_get_image ); - - return a_frame; -} - -/** Constructor for the filter. -*/ - -mlt_transition transition_affine_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_transition transition = mlt_transition_new( ); - if ( transition != NULL ) - { - mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "sx", 1 ); - mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "sy", 1 ); - mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "distort", 0 ); - mlt_properties_set( MLT_TRANSITION_PROPERTIES( transition ), "geometry", "0,0:100%x100%" ); - // Inform apps and framework that this is a video only transition - mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "_transition_type", 1 ); - transition->process = transition_process; - } - return transition; -} diff --git a/src/modules/qimage/Makefile b/src/modules/qimage/Makefile deleted file mode 100644 index 42bdc81..0000000 --- a/src/modules/qimage/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -include ../../../config.mak -include config.mak - -TARGET = ../libmltqimage$(LIBSUF) - -OBJS = factory.o producer_qimage.o -CPPOBJS = qimage_wrapper.o - -CFLAGS += -I../.. -CXXFLAGS += $(CFLAGS) $(QTCXXFLAGS) -Wno-deprecated - -LDFLAGS = -L../../framework -lmlt -LDFLAGS += $(QTLIBS) -LDFLAGS += -lstdc++ - -ifdef USE_KDE -LDFLAGS += -lkio -endif - -SRCS := $(OBJS:.o=.c) $(CPPOBJS:.o=.cpp) - -all: $(TARGET) - -$(TARGET): $(OBJS) $(CPPOBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(CPPOBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $(QTCXXFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend config.h config.mak - -clean: - rm -f $(OBJS) $(TARGET) $(CPPOBJS) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/qimage/configure b/src/modules/qimage/configure deleted file mode 100755 index 7111947..0000000 --- a/src/modules/qimage/configure +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh - -if [ "$help" = "1" ] -then - cat << EOF -QImage options: - - --force-qt3 - Force compile against Qt3 if Qt4 is present on the system - --qimage-libdir - Location of QT lib directory [/usr/lib/qt4 or /usr/lib/qt3] - --qimage-includedir - Location of QT include directory [/usr/include/qt4 or /usr/include/qt3] - --kde-libdir - Location of KDE lib directory [/usr/lib] - --kde-includedir - Location of KDE include directory [/usr/include/kde] - -EOF - -else - targetos=$(uname -s) - case $targetos in - MINGW32*) - export LIBSUF=.dll - ;; - Darwin) - export LIBSUF=.dylib - ;; - Linux|FreeBSD) - export LIBSUF=.so - ;; - *) - ;; - esac - - qimage_includedir=/usr/include/qt4 - qimage_libdir=/usr/lib/qt4 - - if [ ! -d "$qimage_libdir" -o ! -d "$qimage_includedir" ] - then - qimage_includedir=/usr/include/qt3 - qimage_libdir=/usr/lib/qt3 - kde_includedir=/usr/include/kde - kde_libdir=/usr/lib - if [ "$KDEDIR" != "" ] - then - kde_includedir="$KDEDIR/include" - kde_libdir="$KDEDIR" - fi - fi - - if [ "$QTDIR" != "" ] - then - qimage_includedir="$QTDIR/include" - qimage_libdir="$QTDIR/lib" - fi - - export force_qt3= - export qt4_found= - - for i in "$@" - do - case $i in - --qimage-libdir=* ) qimage_libdir="${i#--qimage-libdir=}" ;; - --qimage-includedir=* ) qimage_includedir="${i#--qimage-includedir=}" ;; - --kde-libdir=* ) kde_libdir="${i#--kde-libdir=}" ;; - --kde-includedir=* ) kde_includedir="${i#--kde-includedir=}" ;; - --force-qt3 ) force_qt3="true" ;; - esac - done - - pkg-config --exists 'QtGui >= 4' - if [ $? -eq 0 ] && [ "$force_qt3" = "" ] - then - echo "Qt version 4.x detected, will compile Qt4 qimage producer" - qt4_found=true - echo "#define USE_QT4" > config.h - echo "USE_QT4=1" > config.mak - echo QTCXXFLAGS=$(pkg-config --cflags QtGui) >> config.mak - echo QTLIBS=$(pkg-config --libs QtGui) >> config.mak - - elif [ -d "$qimage_libdir" -a -d "$qimage_includedir" ] - then - - # test if we have a Qt3 or Qt4 - if [ -f "$qimage_libdir/libQtCore.so" ] || [ -d "$qimage_libdir/QtGui.framework" ] && [ "$force_qt3" = "" ] - then - echo "Qt version 4.x detected, will compile Qt4 qimage producer" - qt4_found=true - else - echo "Qt version 3.x detected, will compile Qt3 qimage producer" - fi - - echo "Include directory: " $qimage_includedir - - echo > config.h - echo > config.mak - if [ "$qt4_found" != "" ] && [ "$force_qt3" = "" ] - then - echo "#define USE_QT4" >> config.h - echo "USE_QT4=1" >> config.mak - if [ -d "$qimage_libdir/QtGui.framework" ] - then - echo QTCXXFLAGS=$(pkg-config --cflags QtGui) >> config.mak - echo QTLIBS=$(pkg-config --libs QtGui) >> config.mak - else - echo QTCXXFLAGS=-I$qimage_includedir >> config.mak - echo QTLIBS=-L$qimage_libdir -lQtGui >> config.mak - fi - else - if [ -d "$kde_includedir" ] - then - echo "#define USE_KDE" >> config.h - echo "USE_KDE=1" >> config.mak - echo "#define USE_QT3" >> config.h - echo "USE_QT3=1" >> config.mak - echo QTCXXFLAGS=-I$qimage_includedir -I$kde_includedir -DQT_THREAD_SUPPORT >> config.mak - echo QTLIBS=-L$qimage_libdir -L$kde_libdir/lib -lqt-mt >> config.mak - else - echo "qimage: KDE environment not found - disabling extra image formats" - echo "#define USE_QT3" >> config.h - echo "USE_QT3=1" >> config.mak - echo QTCXXFLAGS=-I$qimage_includedir -DQT_THREAD_SUPPORT>> config.mak - echo QTLIBS=-L$qimage_libdir -lqt-mt >> config.mak - fi - fi - else - echo "qimage: QT environment not found - disabling" - touch ../disable-qimage - fi - -fi diff --git a/src/modules/qimage/factory.c b/src/modules/qimage/factory.c deleted file mode 100644 index 61cb0ec..0000000 --- a/src/modules/qimage/factory.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2006 Visual Media - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -extern mlt_producer producer_qimage_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( producer_type, "qimage", producer_qimage_init ); -} diff --git a/src/modules/qimage/gpl b/src/modules/qimage/gpl deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/qimage/producer_qimage.c b/src/modules/qimage/producer_qimage.c deleted file mode 100644 index 841b456..0000000 --- a/src/modules/qimage/producer_qimage.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * producer_image.c -- a QT/QImage based producer for MLT - * Copyright (C) 2006 Visual Media - * Author: Charles Yates - * - * NB: This module is designed to be functionally equivalent to the - * gtk2 image loading module so it can be used as replacement. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include "qimage_wrapper.h" - -#include -#include -#include -#include -#include -#include -#include - -static void load_filenames( producer_qimage this, mlt_properties producer_properties ); -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer parent ); - -mlt_producer producer_qimage_init( mlt_profile profile, mlt_service_type type, const char *id, char *filename ) -{ - producer_qimage this = calloc( sizeof( struct producer_qimage_s ), 1 ); - if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) - { - mlt_producer producer = &this->parent; - - // Get the properties interface - mlt_properties properties = MLT_PRODUCER_PROPERTIES( &this->parent ); - - // Callback registration -#ifdef USE_KDE - init_qimage(); -#endif - producer->get_frame = producer_get_frame; - producer->close = ( mlt_destructor )producer_close; - - // Set the default properties - mlt_properties_set( properties, "resource", filename ); - mlt_properties_set_int( properties, "ttl", 25 ); - mlt_properties_set_int( properties, "aspect_ratio", 1 ); - mlt_properties_set_int( properties, "progressive", 1 ); - - // Validate the resource - if ( filename ) - load_filenames( this, properties ); - if ( this->count ) - { - mlt_frame frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - if ( frame ) - { - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - pthread_mutex_init( &this->mutex, NULL ); - mlt_properties_set_data( frame_properties, "producer_qimage", this, 0, NULL, NULL ); - mlt_frame_set_position( frame, mlt_producer_position( producer ) ); - mlt_properties_set_position( frame_properties, "qimage_position", mlt_producer_position( producer ) ); - refresh_qimage( this, frame, 0, 0 ); - mlt_frame_close( frame ); - } - } - if ( this->current_width == 0 ) - { - producer_close( producer ); - producer = NULL; - } - return producer; - } - free( this ); - return NULL; -} - -static void load_filenames( producer_qimage this, mlt_properties producer_properties ) -{ - char *filename = mlt_properties_get( producer_properties, "resource" ); - this->filenames = mlt_properties_new( ); - - // Read xml string - if ( strstr( filename, " -1 ) - { - // Write the svg into the temp file - ssize_t remaining_bytes; - char *xml = filename; - - // Strip leading crap - while ( xml[0] != '<' ) - xml++; - - remaining_bytes = strlen( xml ); - while ( remaining_bytes > 0 ) - remaining_bytes -= write( fd, xml + strlen( xml ) - remaining_bytes, remaining_bytes ); - close( fd ); - - mlt_properties_set( this->filenames, "0", fullname ); - - // Teehe - when the producer closes, delete the temp file and the space allo - mlt_properties_set_data( producer_properties, "__temporary_file__", fullname, 0, ( mlt_destructor )unlink, NULL ); - } - } - // Obtain filenames - else if ( strchr( filename, '%' ) != NULL ) - { - // handle picture sequences - int i = mlt_properties_get_int( producer_properties, "begin" ); - int gap = 0; - char full[1024]; - int keyvalue = 0; - char key[ 50 ]; - - while ( gap < 100 ) - { - struct stat buf; - snprintf( full, 1023, filename, i ++ ); - if ( stat( full, &buf ) == 0 ) - { - sprintf( key, "%d", keyvalue ++ ); - mlt_properties_set( this->filenames, key, full ); - gap = 0; - } - else - { - gap ++; - } - } - } - else if ( strstr( filename, "/.all." ) != NULL ) - { - char wildcard[ 1024 ]; - char *dir_name = strdup( filename ); - char *extension = strrchr( dir_name, '.' ); - - *( strstr( dir_name, "/.all." ) + 1 ) = '\0'; - sprintf( wildcard, "*%s", extension ); - - mlt_properties_dir_list( this->filenames, dir_name, wildcard, 1 ); - - free( dir_name ); - } - else - { - mlt_properties_set( this->filenames, "0", filename ); - } - - this->count = mlt_properties_count( this->filenames ); -} - -static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the producer for this frame - producer_qimage this = mlt_properties_get_data( properties, "producer_qimage", NULL ); - - *width = mlt_properties_get_int( properties, "rescale_width" ); - *height = mlt_properties_get_int( properties, "rescale_height" ); - - // Refresh the image - refresh_qimage( this, frame, *width, *height ); - - // We need to know the size of the image to clone it - int image_size = this->current_width * ( this->current_height + 1 ) * 2; - int alpha_size = this->current_width * this->current_height; - - // Get width and height (may have changed during the refresh) - *width = mlt_properties_get_int( properties, "width" ); - *height = mlt_properties_get_int( properties, "height" ); - - // NB: Cloning is necessary with this producer (due to processing of images ahead of use) - // The fault is not in the design of mlt, but in the implementation of the qimage producer... - if ( this->current_image != NULL ) - { - if ( *format == mlt_image_yuv422 || *format == mlt_image_yuv420p ) - { - // Clone the image and the alpha - uint8_t *image_copy = mlt_pool_alloc( image_size ); - uint8_t *alpha_copy = mlt_pool_alloc( alpha_size ); - - memcpy( image_copy, this->current_image, image_size ); - - // Copy or default the alpha - if ( this->current_alpha ) - memcpy( alpha_copy, this->current_alpha, alpha_size ); - else - memset( alpha_copy, 255, alpha_size ); - - // Now update properties so we free the copy after - mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "alpha", alpha_copy, alpha_size, mlt_pool_release, NULL ); - - // We're going to pass the copy on - *buffer = image_copy; - } - else if ( *format == mlt_image_rgb24a ) - { - // Clone the image and the alpha - image_size = *width * ( *height + 1 ) * 4; - alpha_size = *width * ( *height + 1 ); - uint8_t *image_copy = mlt_pool_alloc( image_size ); - uint8_t *alpha_copy = mlt_pool_alloc( alpha_size ); - - mlt_convert_yuv422_to_rgb24a(this->current_image, image_copy, (*width)*(*height)); - - // Now update properties so we free the copy after - mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "alpha", alpha_copy, alpha_size, mlt_pool_release, NULL ); - - // We're going to pass the copy on - *buffer = image_copy; - } - } - else - { - // TODO: Review all cases of invalid images - *buffer = mlt_pool_alloc( 50 * 50 * 2 ); - mlt_properties_set_data( properties, "image", *buffer, image_size, mlt_pool_release, NULL ); - *width = 50; - *height = 50; - } - - // Release references and locks - pthread_mutex_unlock( &this->mutex ); - mlt_cache_item_close( this->image_cache ); - mlt_cache_item_close( this->alpha_cache ); - - return 0; -} - -static uint8_t *producer_get_alpha_mask( mlt_frame this ) -{ - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Return the alpha mask - return mlt_properties_get_data( properties, "alpha", NULL ); -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Get the real structure for this producer - producer_qimage this = producer->child; - - // Fetch the producers properties - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - if ( this->filenames == NULL && mlt_properties_get( producer_properties, "resource" ) != NULL ) - load_filenames( this, producer_properties ); - - // Generate a frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - if ( *frame != NULL && this->count > 0 ) - { - // Obtain properties of frame and producer - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Set the producer on the frame properties - mlt_properties_set_data( properties, "producer_qimage", this, 0, NULL, NULL ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Ensure that we have a way to obtain the position in the get_image - mlt_properties_set_position( properties, "qimage_position", mlt_producer_position( producer ) ); - - // Refresh the image - refresh_qimage( this, *frame, 0, 0 ); - - // Set producer-specific frame properties - mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( producer_properties, "progressive" ) ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_properties, "aspect_ratio" ) ); - - // Set alpha call back - ( *frame )->get_alpha_mask = producer_get_alpha_mask; - - // Push the get_image method - mlt_frame_push_get_image( *frame, producer_get_image ); - } - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer parent ) -{ - producer_qimage this = parent->child; - pthread_mutex_destroy( &this->mutex ); - parent->close = NULL; - mlt_producer_close( parent ); - mlt_properties_close( this->filenames ); - free( this ); -} diff --git a/src/modules/qimage/qimage_wrapper.cpp b/src/modules/qimage/qimage_wrapper.cpp deleted file mode 100644 index d8722e0..0000000 --- a/src/modules/qimage/qimage_wrapper.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/* - * qimage_wrapper.cpp -- a QT/QImage based producer for MLT - * Copyright (C) 2006 Visual Media - * Author: Charles Yates - * - * NB: This module is designed to be functionally equivalent to the - * gtk2 image loading module so it can be used as replacement. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "qimage_wrapper.h" - -#ifdef USE_QT3 -#include -#include - -#ifdef USE_KDE -#include -#include -#endif - -#endif - - -#ifdef USE_QT4 -#include -#include -#include -#endif - - -#include - -extern "C" { - -#include -#include - -#ifdef USE_KDE -static KInstance *instance = 0L; -#endif - -static void qimage_delete( void *data ) -{ - QImage *image = ( QImage * )data; - delete image; - image = NULL; -#ifdef USE_KDE - if (instance) delete instance; - instance = 0L; -#endif -} - -static QMutex g_mutex; - -#ifdef USE_KDE -void init_qimage() -{ - if (!instance) { - instance = new KInstance("qimage_prod"); - KImageIO::registerFormats(); - } -} -#endif - -void refresh_qimage( producer_qimage self, mlt_frame frame, int width, int height ) -{ - // Obtain properties of frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the producer - mlt_producer producer = &self->parent; - - // Obtain properties of producer - mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); - - // restore QImage - pthread_mutex_lock( &self->mutex ); - mlt_cache_item qimage_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.qimage" ); - QImage *qimage = static_cast( mlt_cache_item_data( qimage_cache, NULL ) ); - - // restore scaled image - self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.image" ); - self->current_image = static_cast( mlt_cache_item_data( self->image_cache, NULL ) ); - - // restore alpha channel - self->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.alpha" ); - self->current_alpha = static_cast( mlt_cache_item_data( self->alpha_cache, NULL ) ); - - // Check if user wants us to reload the image - if ( mlt_properties_get_int( producer_props, "force_reload" ) ) - { - qimage = NULL; - self->current_image = NULL; - mlt_properties_set_int( producer_props, "force_reload", 0 ); - } - - // Obtain the cache flag and structure - int use_cache = mlt_properties_get_int( producer_props, "cache" ); - mlt_properties cache = ( mlt_properties )mlt_properties_get_data( producer_props, "_cache", NULL ); - int update_cache = 0; - - // Get the time to live for each frame - double ttl = mlt_properties_get_int( producer_props, "ttl" ); - - // Get the original position of this frame - mlt_position position = mlt_properties_get_position( properties, "qimage_position" ); - position += mlt_producer_get_in( producer ); - - // Image index - int image_idx = ( int )floor( ( double )position / ttl ) % self->count; - - // Key for the cache - char image_key[ 10 ]; - sprintf( image_key, "%d", image_idx ); - - g_mutex.lock(); - - // Check if the frame is already loaded - if ( use_cache ) - { - if ( cache == NULL ) - { - cache = mlt_properties_new( ); - mlt_properties_set_data( producer_props, "_cache", cache, 0, ( mlt_destructor )mlt_properties_close, NULL ); - } - - mlt_frame cached = ( mlt_frame )mlt_properties_get_data( cache, image_key, NULL ); - - if ( cached ) - { - self->image_idx = image_idx; - mlt_properties cached_props = MLT_FRAME_PROPERTIES( cached ); - self->current_width = mlt_properties_get_int( cached_props, "width" ); - self->current_height = mlt_properties_get_int( cached_props, "height" ); - mlt_properties_set_int( producer_props, "_real_width", mlt_properties_get_int( cached_props, "real_width" ) ); - mlt_properties_set_int( producer_props, "_real_height", mlt_properties_get_int( cached_props, "real_height" ) ); - self->current_image = ( uint8_t * )mlt_properties_get_data( cached_props, "image", NULL ); - self->current_alpha = ( uint8_t * )mlt_properties_get_data( cached_props, "alpha", NULL ); - - if ( width != 0 && ( width != self->current_width || height != self->current_height ) ) - self->current_image = NULL; - } - } - - // optimization for subsequent iterations on single picture - if ( width != 0 && ( image_idx != self->image_idx || width != self->current_width || height != self->current_height ) ) - self->current_image = NULL; - if ( image_idx != self->image_idx ) - qimage = NULL; - if ( qimage == NULL && ( width == 0 || self->current_image == NULL ) ) - { - self->current_image = NULL; - self->image_idx = image_idx; - qimage = new QImage( mlt_properties_get_value( self->filenames, image_idx ) ); - - if ( !qimage->isNull( ) ) - { - // Store the width/height of the qimage - self->current_width = qimage->width( ); - self->current_height = qimage->height( ); - - // Register qimage for destruction and reuse - mlt_cache_item_close( qimage_cache ); - mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "qimage.qimage", qimage, 0, ( mlt_destructor )qimage_delete ); - qimage_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.qimage" ); - - mlt_events_block( producer_props, NULL ); - mlt_properties_set_int( producer_props, "_real_width", self->current_width ); - mlt_properties_set_int( producer_props, "_real_height", self->current_height ); - mlt_events_unblock( producer_props, NULL ); - } - else - { - delete qimage; - qimage = NULL; - } - } - - // If we have a pixbuf and this request specifies a valid dimension and we haven't already got a cached version... - if ( qimage && width > 0 && self->current_image == NULL ) - { - char *interps = mlt_properties_get( properties, "rescale.interp" ); - int interp = 0; - - // QImage has two scaling modes - we'll toggle between them here - if ( strcmp( interps, "tiles" ) == 0 ) - interp = 1; - else if ( strcmp( interps, "hyper" ) == 0 ) - interp = 1; - -#ifdef USE_QT4 - // Note - the original qimage is already safe and ready for destruction - QImage scaled = interp == 0 ? qimage->scaled( QSize( width, height)) : qimage->scaled( QSize(width, height), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - QImage temp; - bool hasAlpha = scaled.hasAlphaChannel(); - if (hasAlpha) - temp = scaled.convertToFormat(QImage::Format_ARGB32); - else - temp = scaled.convertToFormat(QImage::Format_RGB888); -#endif - -#ifdef USE_QT3 - // Note - the original qimage is already safe and ready for destruction - QImage scaled = interp == 0 ? qimage->scale( width, height, QImage::ScaleFree ) : qimage->smoothScale( width, height, QImage::ScaleFree ); - QImage temp = scaled.convertDepth( 32 ); - bool hasAlpha = true; -#endif - - // Store width and height - self->current_width = width; - self->current_height = height; - - // Allocate/define image - self->current_image = ( uint8_t * )mlt_pool_alloc( width * ( height + 1 ) * 2 ); - if ( !use_cache ) - mlt_cache_item_close( self->image_cache ); - mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "qimage.image", self->current_image, width * ( height + 1 ) * 2, mlt_pool_release ); - self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.image" ); - - if (!hasAlpha) { - mlt_convert_rgb24_to_yuv422( temp.bits(), self->current_width, self->current_height, temp.bytesPerLine(), self->current_image ); - } - else { - // Allocate the alpha mask - self->current_alpha = ( uint8_t * )mlt_pool_alloc( width * height ); - if ( !use_cache ) - mlt_cache_item_close( self->alpha_cache ); - mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "qimage.alpha", self->current_alpha, width * height, mlt_pool_release ); - self->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.alpha" ); - -#ifdef USE_QT4 - if ( QSysInfo::ByteOrder == QSysInfo::BigEndian ) - mlt_convert_argb_to_yuv422( temp.bits( ), self->current_width, self->current_height, temp.bytesPerLine(), self->current_image, self->current_alpha ); - else - mlt_convert_bgr24a_to_yuv422( temp.bits( ), self->current_width, self->current_height, temp.bytesPerLine( ), self->current_image, self->current_alpha ); -#endif - -#ifdef USE_QT3 - // Convert the image - if ( QImage::systemByteOrder( ) == QImage::BigEndian ) - mlt_convert_argb_to_yuv422( temp.bits( ), self->current_width, self->current_height, temp.bytesPerLine( ), self->current_image, self->current_alpha ); - else - mlt_convert_bgr24a_to_yuv422( temp.bits( ), self->current_width, self->current_height, temp.bytesPerLine( ), self->current_image, self->current_alpha ); -#endif - } - - // Ensure we update the cache when we need to - update_cache = use_cache; - } - - // release references no longer needed - mlt_cache_item_close( qimage_cache ); - if ( width == 0 ) - { - pthread_mutex_unlock( &self->mutex ); - mlt_cache_item_close( self->image_cache ); - mlt_cache_item_close( self->alpha_cache ); - } - - // Set width/height of frame - mlt_properties_set_int( properties, "width", self->current_width ); - mlt_properties_set_int( properties, "height", self->current_height ); - mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "_real_width" ) ); - mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "_real_height" ) ); - - if ( update_cache ) - { - mlt_frame cached = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - mlt_properties cached_props = MLT_FRAME_PROPERTIES( cached ); - mlt_properties_set_int( cached_props, "width", self->current_width ); - mlt_properties_set_int( cached_props, "height", self->current_height ); - mlt_properties_set_int( cached_props, "real_width", mlt_properties_get_int( producer_props, "_real_width" ) ); - mlt_properties_set_int( cached_props, "real_height", mlt_properties_get_int( producer_props, "_real_height" ) ); - mlt_properties_set_data( cached_props, "image", self->current_image, self->current_width * ( self->current_height + 1 ) * 2, mlt_pool_release, NULL ); - mlt_properties_set_data( cached_props, "alpha", self->current_alpha, self->current_width * self->current_height, mlt_pool_release, NULL ); - mlt_properties_set_data( cache, image_key, cached, 0, ( mlt_destructor )mlt_frame_close, NULL ); - } - g_mutex.unlock(); -} - -} // extern "C" diff --git a/src/modules/qimage/qimage_wrapper.h b/src/modules/qimage/qimage_wrapper.h deleted file mode 100644 index 9c9243e..0000000 --- a/src/modules/qimage/qimage_wrapper.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * qimage_wrapper.h -- a QT/QImage based producer for MLT - * Copyright (C) 2006 Visual Media - * Author: Charles Yates - * - * NB: This module is designed to be functionally equivalent to the - * gtk2 image loading module so it can be used as replacement. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef MLT_QIMAGE_WRAPPER -#define MLT_QIMAGE_WRAPPER - -#include - -#include "config.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct producer_qimage_s -{ - struct mlt_producer_s parent; - mlt_properties filenames; - int count; - int image_idx; - uint8_t *current_image; - uint8_t *current_alpha; - int current_width; - int current_height; - mlt_cache_item image_cache; - mlt_cache_item alpha_cache; - pthread_mutex_t mutex; -}; - -typedef struct producer_qimage_s *producer_qimage; - -extern void refresh_qimage( producer_qimage, mlt_frame, int width, int height ); -#ifdef USE_KDE -extern void init_qimage(); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/modules/resample/Makefile b/src/modules/resample/Makefile deleted file mode 100644 index faf00a8..0000000 --- a/src/modules/resample/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltresample$(LIBSUF) - -OBJS = factory.o \ - filter_resample.o - -CFLAGS += -I../.. -CFLAGS += `pkg-config --cflags samplerate` - -LDFLAGS += -L../../framework -lmlt -LDFLAGS += `pkg-config --libs samplerate` - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/resample/configure b/src/modules/resample/configure deleted file mode 100755 index 954cb04..0000000 --- a/src/modules/resample/configure +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - - pkg-config samplerate 2> /dev/null - disable_samplerate=$? - - if [ "$disable_samplerate" != "0" ] - then - echo "- libsamplerate not found: disabling" - touch ../disable-resample - fi - exit 0 -fi - diff --git a/src/modules/resample/factory.c b/src/modules/resample/factory.c deleted file mode 100644 index c61ec51..0000000 --- a/src/modules/resample/factory.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -extern mlt_filter filter_resample_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "resample", filter_resample_init ); -} diff --git a/src/modules/resample/filter_resample.c b/src/modules/resample/filter_resample.c deleted file mode 100644 index 6838465..0000000 --- a/src/modules/resample/filter_resample.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * filter_resample.c -- adjust audio sample frequency - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -#include -#include -#include -#define __USE_ISOC99 1 -#include - -#define BUFFER_LEN 20480 -#define RESAMPLE_TYPE SRC_SINC_FASTEST - -/** Get the audio. -*/ - -static int resample_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the properties of the frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Get the filter service - mlt_filter filter = mlt_frame_pop_audio( frame ); - - // Get the filter properties - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - - // Get the resample information - int output_rate = mlt_properties_get_int( filter_properties, "frequency" ); - SRC_STATE *state = mlt_properties_get_data( filter_properties, "state", NULL ); - float *input_buffer = mlt_properties_get_data( filter_properties, "input_buffer", NULL ); - float *output_buffer = mlt_properties_get_data( filter_properties, "output_buffer", NULL ); - int channels_avail = *channels; - SRC_DATA data; - int i; - - // If no resample frequency is specified, default to requested value - if ( output_rate == 0 ) - output_rate = *frequency; - - // Get the producer's audio - mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples ); - - // Duplicate channels as necessary - if ( channels_avail < *channels ) - { - int size = *channels * *samples * sizeof( int16_t ); - int16_t *new_buffer = mlt_pool_alloc( size ); - int j, k = 0; - - // Duplicate the existing channels - for ( i = 0; i < *samples; i++ ) - { - for ( j = 0; j < *channels; j++ ) - { - new_buffer[ ( i * *channels ) + j ] = (*buffer)[ ( i * channels_avail ) + k ]; - k = ( k + 1 ) % channels_avail; - } - } - - // Update the audio buffer now - destroys the old - mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - - *buffer = new_buffer; - } - else if ( channels_avail == 6 && *channels == 2 ) - { - // Nasty hack for ac3 5.1 audio - may be a cause of failure? - int size = *channels * *samples * sizeof( int16_t ); - int16_t *new_buffer = mlt_pool_alloc( size ); - - // Drop all but the first *channels - for ( i = 0; i < *samples; i++ ) - { - new_buffer[ ( i * *channels ) + 0 ] = (*buffer)[ ( i * channels_avail ) + 2 ]; - new_buffer[ ( i * *channels ) + 1 ] = (*buffer)[ ( i * channels_avail ) + 3 ]; - } - - // Update the audio buffer now - destroys the old - mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - - *buffer = new_buffer; - } - - // Return now if no work to do - if ( output_rate != *frequency ) - { - float *p = input_buffer; - float *end = p + *samples * *channels; - int16_t *q = *buffer; - - // Convert to floating point - while( p != end ) - *p ++ = ( float )( *q ++ ) / 32768.0; - - // Resample - data.data_in = input_buffer; - data.data_out = output_buffer; - data.src_ratio = ( float ) output_rate / ( float ) *frequency; - data.input_frames = *samples; - data.output_frames = BUFFER_LEN / *channels; - data.end_of_input = 0; - i = src_process( state, &data ); - if ( i == 0 ) - { - if ( data.output_frames_gen > *samples ) - { - *buffer = mlt_pool_realloc( *buffer, data.output_frames_gen * *channels * sizeof( int16_t ) ); - mlt_properties_set_data( properties, "audio", *buffer, *channels * data.output_frames_gen * 2, mlt_pool_release, NULL ); - } - - *samples = data.output_frames_gen; - *frequency = output_rate; - - p = output_buffer; - q = *buffer; - end = p + *samples * *channels; - - // Convert from floating back to signed 16bit - while( p != end ) - { - if ( *p > 1.0 ) - *p = 1.0; - if ( *p < -1.0 ) - *p = -1.0; - if ( *p > 0 ) - *q ++ = 32767 * *p ++; - else - *q ++ = 32768 * *p ++; - } - } - else - fprintf( stderr, "resample_get_audio: %s %d,%d,%d\n", src_strerror( i ), *frequency, *samples, output_rate ); - } - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - if ( mlt_frame_is_test_audio( frame ) == 0 ) - { - mlt_frame_push_audio( frame, this ); - mlt_frame_push_audio( frame, resample_get_audio ); - } - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_resample_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - int error; - SRC_STATE *state = src_new( RESAMPLE_TYPE, 2 /* channels */, &error ); - if ( error == 0 ) - { - void *input_buffer = mlt_pool_alloc( BUFFER_LEN ); - void *output_buffer = mlt_pool_alloc( BUFFER_LEN ); - this->process = filter_process; - if ( arg != NULL ) - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "frequency", atoi( arg ) ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "channels", 2 ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), "state", state, 0, (mlt_destructor)src_delete, NULL ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), "input_buffer", input_buffer, BUFFER_LEN, mlt_pool_release, NULL ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), "output_buffer", output_buffer, BUFFER_LEN, mlt_pool_release, NULL ); - } - else - { - fprintf( stderr, "filter_resample_init: %s\n", src_strerror( error ) ); - } - } - return this; -} diff --git a/src/modules/resample/gpl b/src/modules/resample/gpl deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/sdl/Makefile b/src/modules/sdl/Makefile deleted file mode 100644 index e2b5b36..0000000 --- a/src/modules/sdl/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -include ../../../config.mak - -include config.mak - -TARGET = ../libmltsdl$(LIBSUF) - -OBJS = factory.o \ - consumer_sdl.o \ - consumer_sdl_preview.o \ - consumer_sdl_still.o - -ifeq ($(targetos),Darwin) -CFLAGS += -ObjC -LDFLAGS += -lobjc -framework Foundation -else -LDFLAGS += -lX11 -endif - -CFLAGS += -I../.. -CFLAGS += `sdl-config --cflags` - -LDFLAGS += -L../../framework -lmlt -LDFLAGS += `sdl-config --libs` - -ifeq ($(WITH_SDL_IMAGE),1) -OBJS += producer_sdl_image.o -CFLAGS += -DWITH_SDL_IMAGE -LDFLAGS += -lSDL_image -endif - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/sdl/configure b/src/modules/sdl/configure deleted file mode 100755 index 43b90d9..0000000 --- a/src/modules/sdl/configure +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - - sdl-config --version > /dev/null 2>&1 - disable_sdl=$? - - if [ "$disable_sdl" = "0" ] - then - echo > config.mak - image=`sdl-config --prefix`/include/SDL/SDL_image.h - if [ -f "$image" ] - then - echo "WITH_SDL_IMAGE=1" >> config.mak - fi - else - echo "- sdl development libs not found: disabling" - touch ../disable-sdl - fi - exit 0 -fi - diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c deleted file mode 100644 index 9870e44..0000000 --- a/src/modules/sdl/consumer_sdl.c +++ /dev/null @@ -1,856 +0,0 @@ -/* - * consumer_sdl.c -- A Simple DirectMedia Layer consumer - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** This classes definition. -*/ - -typedef struct consumer_sdl_s *consumer_sdl; - -struct consumer_sdl_s -{ - struct mlt_consumer_s parent; - mlt_properties properties; - mlt_deque queue; - pthread_t thread; - int joined; - int running; - uint8_t audio_buffer[ 4096 * 10 ]; - int audio_avail; - pthread_mutex_t audio_mutex; - pthread_cond_t audio_cond; - pthread_mutex_t video_mutex; - pthread_cond_t video_cond; - int window_width; - int window_height; - int previous_width; - int previous_height; - int width; - int height; - int playing; - int sdl_flags; - SDL_Surface *sdl_screen; - SDL_Overlay *sdl_overlay; - SDL_Rect rect; - uint8_t *buffer; - int bpp; - int filtered; -}; - -/** Forward references to static functions. -*/ - -static int consumer_start( mlt_consumer parent ); -static int consumer_stop( mlt_consumer parent ); -static int consumer_is_stopped( mlt_consumer parent ); -static void consumer_close( mlt_consumer parent ); -static void *consumer_thread( void * ); -static int consumer_get_dimensions( int *width, int *height ); -static void consumer_sdl_event( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ); - -/** This is what will be called by the factory - anything can be passed in - via the argument, but keep it simple. -*/ - -mlt_consumer consumer_sdl_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create the consumer object - consumer_sdl this = calloc( sizeof( struct consumer_sdl_s ), 1 ); - - // If no malloc'd and consumer init ok - if ( this != NULL && mlt_consumer_init( &this->parent, this, profile ) == 0 ) - { - // Create the queue - this->queue = mlt_deque_init( ); - - // Get the parent consumer object - mlt_consumer parent = &this->parent; - - // We have stuff to clean up, so override the close method - parent->close = consumer_close; - - // get a handle on properties - mlt_service service = MLT_CONSUMER_SERVICE( parent ); - this->properties = MLT_SERVICE_PROPERTIES( service ); - - // Set the default volume - mlt_properties_set_double( this->properties, "volume", 1.0 ); - - // This is the initialisation of the consumer - pthread_mutex_init( &this->audio_mutex, NULL ); - pthread_cond_init( &this->audio_cond, NULL); - pthread_mutex_init( &this->video_mutex, NULL ); - pthread_cond_init( &this->video_cond, NULL); - - // Default scaler (for now we'll use nearest) - mlt_properties_set( this->properties, "rescale", "nearest" ); - - // Default buffer for low latency - mlt_properties_set_int( this->properties, "buffer", 1 ); - - // Default progressive true - mlt_properties_set_int( this->properties, "progressive", 0 ); - - // Default audio buffer - mlt_properties_set_int( this->properties, "audio_buffer", 512 ); - - // Ensure we don't join on a non-running object - this->joined = 1; - - // process actual param - if ( arg == NULL || sscanf( arg, "%dx%d", &this->width, &this->height ) != 2 ) - { - this->width = mlt_properties_get_int( this->properties, "width" ); - this->height = mlt_properties_get_int( this->properties, "height" ); - } - - // Set the sdl flags - this->sdl_flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_RESIZABLE | SDL_DOUBLEBUF; - - // Allow thread to be started/stopped - parent->start = consumer_start; - parent->stop = consumer_stop; - parent->is_stopped = consumer_is_stopped; - - // Register specific events - mlt_events_register( this->properties, "consumer-sdl-event", ( mlt_transmitter )consumer_sdl_event ); - - // Return the consumer produced - return parent; - } - - // malloc or consumer init failed - free( this ); - - // Indicate failure - return NULL; -} - -static void consumer_sdl_event( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ) -{ - if ( listener != NULL ) - listener( owner, this, ( SDL_Event * )args[ 0 ] ); -} - -int consumer_start( mlt_consumer parent ) -{ - consumer_sdl this = parent->child; - - if ( !this->running ) - { - int video_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "video_off" ); - int preview_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "preview_off" ); - int display_off = video_off | preview_off; - int audio_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "audio_off" ); - int sdl_started = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" ); - - consumer_stop( parent ); - - this->running = 1; - this->joined = 0; - - if ( mlt_properties_get_int( this->properties, "width" ) > 0 ) - this->width = mlt_properties_get_int( this->properties, "width" ); - if ( mlt_properties_get_int( this->properties, "height" ) > 0 ) - this->height = mlt_properties_get_int( this->properties, "height" ); - - this->bpp = mlt_properties_get_int( this->properties, "bpp" ); - - // Attach a colour space converter - if ( preview_off && !this->filtered ) - { - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( parent ) ); - mlt_filter filter = mlt_factory_filter( profile, "avcolour_space", NULL ); - if ( filter ) - { - mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "forced", mlt_image_yuv422 ); - mlt_service_attach( MLT_CONSUMER_SERVICE( parent ), filter ); - mlt_filter_close( filter ); - } - this->filtered = 1; - } - - if ( sdl_started == 0 && display_off == 0 ) - { - if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) < 0 ) - { - fprintf( stderr, "Failed to initialize SDL: %s\n", SDL_GetError() ); - return -1; - } - - SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); - SDL_EnableUNICODE( 1 ); - } - else if ( display_off == 0 ) - { - this->sdl_screen = SDL_GetVideoSurface( ); - } - - if ( audio_off == 0 ) - SDL_InitSubSystem( SDL_INIT_AUDIO ); - - // Default window size - double display_ratio = mlt_properties_get_double( this->properties, "display_ratio" ); - this->window_width = ( double )this->height * display_ratio; - this->window_height = this->height; - - if ( this->sdl_screen == NULL && display_off == 0 ) - { - if ( mlt_properties_get_int( this->properties, "fullscreen" ) ) - { - const SDL_VideoInfo *vi = SDL_GetVideoInfo(); - this->window_width = vi->current_w; - this->window_height = vi->current_h; - this->sdl_flags |= SDL_FULLSCREEN; - SDL_ShowCursor( SDL_DISABLE ); - } - this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags ); - } - - pthread_create( &this->thread, NULL, consumer_thread, this ); - } - - return 0; -} - -int consumer_stop( mlt_consumer parent ) -{ - // Get the actual object - consumer_sdl this = parent->child; - - if ( this->joined == 0 ) - { - // Kill the thread and clean up - this->joined = 1; - this->running = 0; - if ( this->thread ) - pthread_join( this->thread, NULL ); - - // internal cleanup - if ( this->sdl_overlay != NULL ) - SDL_FreeYUVOverlay( this->sdl_overlay ); - this->sdl_overlay = NULL; - - if ( !mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "audio_off" ) ) - { - pthread_mutex_lock( &this->audio_mutex ); - pthread_cond_broadcast( &this->audio_cond ); - pthread_mutex_unlock( &this->audio_mutex ); - SDL_QuitSubSystem( SDL_INIT_AUDIO ); - } - - if ( mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" ) == 0 ) - SDL_Quit( ); - - this->sdl_screen = NULL; - } - - return 0; -} - -int consumer_is_stopped( mlt_consumer parent ) -{ - consumer_sdl this = parent->child; - return !this->running; -} - -static int sdl_lock_display( ) -{ - SDL_Surface *screen = SDL_GetVideoSurface( ); - return screen != NULL && ( !SDL_MUSTLOCK( screen ) || SDL_LockSurface( screen ) >= 0 ); -} - -static void sdl_unlock_display( ) -{ - SDL_Surface *screen = SDL_GetVideoSurface( ); - if ( screen != NULL && SDL_MUSTLOCK( screen ) ) - SDL_UnlockSurface( screen ); -} - -static void sdl_fill_audio( void *udata, uint8_t *stream, int len ) -{ - consumer_sdl this = udata; - - // Get the volume - double volume = mlt_properties_get_double( this->properties, "volume" ); - - pthread_mutex_lock( &this->audio_mutex ); - - // Block until audio received - while ( this->running && len > this->audio_avail ) - pthread_cond_wait( &this->audio_cond, &this->audio_mutex ); - - if ( this->audio_avail >= len ) - { - // Place in the audio buffer - if ( volume != 1.0 ) - SDL_MixAudio( stream, this->audio_buffer, len, ( int )( ( float )SDL_MIX_MAXVOLUME * volume ) ); - else - memcpy( stream, this->audio_buffer, len ); - - // Remove len from the audio available - this->audio_avail -= len; - - // Remove the samples - memmove( this->audio_buffer, this->audio_buffer + len, this->audio_avail ); - } - else - { - // Just to be safe, wipe the stream first - memset( stream, 0, len ); - - // Mix the audio - SDL_MixAudio( stream, this->audio_buffer, len, ( int )( ( float )SDL_MIX_MAXVOLUME * volume ) ); - - // No audio left - this->audio_avail = 0; - } - - // We're definitely playing now - this->playing = 1; - - pthread_cond_broadcast( &this->audio_cond ); - pthread_mutex_unlock( &this->audio_mutex ); -} - -static int consumer_play_audio( consumer_sdl this, mlt_frame frame, int init_audio, int *duration ) -{ - // Get the properties of this consumer - mlt_properties properties = this->properties; - mlt_audio_format afmt = mlt_audio_pcm; - - // Set the preferred params of the test card signal - int channels = mlt_properties_get_int( properties, "channels" ); - int frequency = mlt_properties_get_int( properties, "frequency" ); - static int counter = 0; - - int samples = mlt_sample_calculator( mlt_properties_get_double( this->properties, "fps" ), frequency, counter++ ); - - int16_t *pcm; - int bytes; - - mlt_frame_get_audio( frame, &pcm, &afmt, &frequency, &channels, &samples ); - *duration = ( ( samples * 1000 ) / frequency ); - - if ( mlt_properties_get_int( properties, "audio_off" ) ) - { - this->playing = 1; - init_audio = 1; - return init_audio; - } - - if ( init_audio == 1 ) - { - SDL_AudioSpec request; - SDL_AudioSpec got; - - int audio_buffer = mlt_properties_get_int( properties, "audio_buffer" ); - - // specify audio format - memset( &request, 0, sizeof( SDL_AudioSpec ) ); - this->playing = 0; - request.freq = frequency; - request.format = AUDIO_S16SYS; - request.channels = channels; - request.samples = audio_buffer; - request.callback = sdl_fill_audio; - request.userdata = (void *)this; - if ( SDL_OpenAudio( &request, &got ) != 0 ) - { - fprintf( stderr, "SDL failed to open audio: %s\n", SDL_GetError() ); - init_audio = 2; - } - else if ( got.size != 0 ) - { - SDL_PauseAudio( 0 ); - init_audio = 0; - } - } - - if ( init_audio == 0 ) - { - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - bytes = ( samples * channels * 2 ); - pthread_mutex_lock( &this->audio_mutex ); - while ( this->running && bytes > ( sizeof( this->audio_buffer) - this->audio_avail ) ) - pthread_cond_wait( &this->audio_cond, &this->audio_mutex ); - if ( this->running ) - { - if ( mlt_properties_get_double( properties, "_speed" ) == 1 ) - memcpy( &this->audio_buffer[ this->audio_avail ], pcm, bytes ); - else - memset( &this->audio_buffer[ this->audio_avail ], 0, bytes ); - this->audio_avail += bytes; - } - pthread_cond_broadcast( &this->audio_cond ); - pthread_mutex_unlock( &this->audio_mutex ); - } - else - { - this->playing = 1; - } - - return init_audio; -} - -static int consumer_play_video( consumer_sdl this, mlt_frame frame ) -{ - // Get the properties of this consumer - mlt_properties properties = this->properties; - - mlt_image_format vfmt = mlt_image_yuv422; - int width = this->width, height = this->height; - uint8_t *image; - int changed = 0; - - int video_off = mlt_properties_get_int( properties, "video_off" ); - int preview_off = mlt_properties_get_int( properties, "preview_off" ); - mlt_image_format preview_format = mlt_properties_get_int( properties, "preview_format" ); - int display_off = video_off | preview_off; - - if ( this->running && display_off == 0 ) - { - // Get the image, width and height - mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "format", vfmt ); - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); - - // Handle events - if ( this->sdl_screen != NULL ) - { - SDL_Event event; - - sdl_lock_display( ); - changed = consumer_get_dimensions( &this->window_width, &this->window_height ); - sdl_unlock_display( ); - - while ( SDL_PollEvent( &event ) ) - { - mlt_events_fire( this->properties, "consumer-sdl-event", &event, NULL ); - - switch( event.type ) - { - case SDL_VIDEORESIZE: - this->window_width = event.resize.w; - this->window_height = event.resize.h; - changed = 1; - break; - case SDL_QUIT: - this->running = 0; - break; - case SDL_KEYDOWN: - { - mlt_producer producer = mlt_properties_get_data( properties, "transport_producer", NULL ); - char keyboard[ 2 ] = " "; - void (*callback)( mlt_producer, char * ) = mlt_properties_get_data( properties, "transport_callback", NULL ); - if ( callback != NULL && producer != NULL && event.key.keysym.unicode < 0x80 && event.key.keysym.unicode > 0 ) - { - keyboard[ 0 ] = ( char )event.key.keysym.unicode; - callback( producer, keyboard ); - } - } - break; - } - } - } - - sdl_lock_display(); - - if ( width != this->width || height != this->height ) - { - if ( this->sdl_overlay != NULL ) - SDL_FreeYUVOverlay( this->sdl_overlay ); - this->sdl_overlay = NULL; - } - - if ( this->running && ( this->sdl_screen == NULL || changed ) ) - { - // Force an overlay recreation - if ( this->sdl_overlay != NULL ) - SDL_FreeYUVOverlay( this->sdl_overlay ); - this->sdl_overlay = NULL; - - // open SDL window with video overlay, if possible - this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, this->bpp, this->sdl_flags ); - if ( consumer_get_dimensions( &this->window_width, &this->window_height ) ) - this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, this->bpp, this->sdl_flags ); - - uint32_t color = mlt_properties_get_int( this->properties, "window_background" ); - SDL_FillRect( this->sdl_screen, NULL, color >> 8 ); - SDL_Flip( this->sdl_screen ); - } - - if ( this->running ) - { - // Determine window's new display aspect ratio - double this_aspect = ( double )this->window_width / this->window_height; - - // Get the display aspect ratio - double display_ratio = mlt_properties_get_double( properties, "display_ratio" ); - - // Determine frame's display aspect ratio - double frame_aspect = mlt_frame_get_aspect_ratio( frame ) * width / height; - - // Store the width and height received - this->width = width; - this->height = height; - - // If using hardware scaler - if ( mlt_properties_get( properties, "rescale" ) != NULL && - !strcmp( mlt_properties_get( properties, "rescale" ), "none" ) ) - { - // Use hardware scaler to normalise display aspect ratio - this->rect.w = frame_aspect / this_aspect * this->window_width; - this->rect.h = this->window_height; - if ( this->rect.w > this->window_width ) - { - this->rect.w = this->window_width; - this->rect.h = this_aspect / frame_aspect * this->window_height; - } - } - // Special case optimisation to negate odd effect of sample aspect ratio - // not corresponding exactly with image resolution. - else if ( (int)( this_aspect * 1000 ) == (int)( display_ratio * 1000 ) ) - { - this->rect.w = this->window_width; - this->rect.h = this->window_height; - } - // Use hardware scaler to normalise sample aspect ratio - else if ( this->window_height * display_ratio > this->window_width ) - { - this->rect.w = this->window_width; - this->rect.h = this->window_width / display_ratio; - } - else - { - this->rect.w = this->window_height * display_ratio; - this->rect.h = this->window_height; - } - - this->rect.x = ( this->window_width - this->rect.w ) / 2; - this->rect.y = ( this->window_height - this->rect.h ) / 2; - this->rect.x -= this->rect.x % 2; - - mlt_properties_set_int( this->properties, "rect_x", this->rect.x ); - mlt_properties_set_int( this->properties, "rect_y", this->rect.y ); - mlt_properties_set_int( this->properties, "rect_w", this->rect.w ); - mlt_properties_set_int( this->properties, "rect_h", this->rect.h ); - - SDL_SetClipRect( this->sdl_screen, &this->rect ); - } - - if ( this->running && this->sdl_screen != NULL && this->sdl_overlay == NULL ) - { - SDL_SetClipRect( this->sdl_screen, &this->rect ); - this->sdl_overlay = SDL_CreateYUVOverlay( width, height, SDL_YUY2_OVERLAY, this->sdl_screen ); - } - - if ( this->running && this->sdl_screen != NULL && this->sdl_overlay != NULL ) - { - this->buffer = this->sdl_overlay->pixels[ 0 ]; - if ( SDL_LockYUVOverlay( this->sdl_overlay ) >= 0 ) - { - if ( image != NULL ) - memcpy( this->buffer, image, width * height * 2 ); - SDL_UnlockYUVOverlay( this->sdl_overlay ); - SDL_DisplayYUVOverlay( this->sdl_overlay, &this->sdl_screen->clip_rect ); - } - } - - sdl_unlock_display(); - } - else if ( this->running ) - { - vfmt = preview_format == mlt_image_none ? mlt_image_rgb24a : preview_format; - if ( !video_off ) - mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "format", vfmt ); - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); - } - - return 0; -} - -static void *video_thread( void *arg ) -{ - // Identify the arg - consumer_sdl this = arg; - - // Obtain time of thread start - struct timeval now; - int64_t start = 0; - int64_t elapsed = 0; - struct timespec tm; - mlt_frame next = NULL; - mlt_properties properties = NULL; - double speed = 0; - - // Get real time flag - int real_time = mlt_properties_get_int( this->properties, "real_time" ); - - // Get the current time - gettimeofday( &now, NULL ); - - // Determine start time - start = ( int64_t )now.tv_sec * 1000000 + now.tv_usec; - - while ( this->running ) - { - // Pop the next frame - pthread_mutex_lock( &this->video_mutex ); - next = mlt_deque_pop_front( this->queue ); - while ( next == NULL && this->running ) - { - pthread_cond_wait( &this->video_cond, &this->video_mutex ); - next = mlt_deque_pop_front( this->queue ); - } - pthread_mutex_unlock( &this->video_mutex ); - - if ( !this->running || next == NULL ) break; - - // Get the properties - properties = MLT_FRAME_PROPERTIES( next ); - - // Get the speed of the frame - speed = mlt_properties_get_double( properties, "_speed" ); - - // Get the current time - gettimeofday( &now, NULL ); - - // Get the elapsed time - elapsed = ( ( int64_t )now.tv_sec * 1000000 + now.tv_usec ) - start; - - // See if we have to delay the display of the current frame - if ( mlt_properties_get_int( properties, "rendered" ) == 1 && this->running ) - { - // Obtain the scheduled playout time - int64_t scheduled = mlt_properties_get_int( properties, "playtime" ); - - // Determine the difference between the elapsed time and the scheduled playout time - int64_t difference = scheduled - elapsed; - - // Smooth playback a bit - if ( real_time && ( difference > 20000 && speed == 1.0 ) ) - { - tm.tv_sec = difference / 1000000; - tm.tv_nsec = ( difference % 1000000 ) * 500; - nanosleep( &tm, NULL ); - } - - // Show current frame if not too old - if ( !real_time || ( difference > -10000 || speed != 1.0 || mlt_deque_count( this->queue ) < 2 ) ) - consumer_play_video( this, next ); - - // If the queue is empty, recalculate start to allow build up again - if ( real_time && ( mlt_deque_count( this->queue ) == 0 && speed == 1.0 ) ) - { - gettimeofday( &now, NULL ); - start = ( ( int64_t )now.tv_sec * 1000000 + now.tv_usec ) - scheduled + 20000; - } - } - - // This frame can now be closed - mlt_frame_close( next ); - next = NULL; - } - - if ( next != NULL ) - mlt_frame_close( next ); - - mlt_consumer_stopped( &this->parent ); - - return NULL; -} - -/** Threaded wrapper for pipe. -*/ - -static void *consumer_thread( void *arg ) -{ - // Identify the arg - consumer_sdl this = arg; - - // Get the consumer - mlt_consumer consumer = &this->parent; - - // Convenience functionality - int terminate_on_pause = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "terminate_on_pause" ); - int terminated = 0; - - // Video thread - pthread_t thread; - - // internal intialization - int init_audio = 1; - int init_video = 1; - mlt_frame frame = NULL; - mlt_properties properties = NULL; - int duration = 0; - int64_t playtime = 0; - struct timespec tm = { 0, 100000 }; - - // Loop until told not to - while( !terminated && this->running ) - { - // Get a frame from the attached producer - frame = mlt_consumer_rt_frame( consumer ); - - // Check for termination - if ( terminate_on_pause && frame != NULL ) - terminated = mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ) == 0.0; - - // Ensure that we have a frame - if ( frame != NULL ) - { - // Get the frame properties - properties = MLT_FRAME_PROPERTIES( frame ); - - // Play audio - init_audio = consumer_play_audio( this, frame, init_audio, &duration ); - - // Determine the start time now - if ( this->playing && init_video ) - { - // Create the video thread - pthread_create( &thread, NULL, video_thread, this ); - - // Video doesn't need to be initialised any more - init_video = 0; - } - - // Set playtime for this frame - mlt_properties_set_int( properties, "playtime", playtime ); - - while ( this->running && mlt_deque_count( this->queue ) > 15 ) - nanosleep( &tm, NULL ); - - // Push this frame to the back of the queue - pthread_mutex_lock( &this->video_mutex ); - mlt_deque_push_back( this->queue, frame ); - pthread_cond_broadcast( &this->video_cond ); - pthread_mutex_unlock( &this->video_mutex ); - - // Calculate the next playtime - playtime += ( duration * 1000 ); - } - } - - this->running = 0; - - // Kill the video thread - if ( init_video == 0 ) - { - pthread_mutex_lock( &this->video_mutex ); - pthread_cond_broadcast( &this->video_cond ); - pthread_mutex_unlock( &this->video_mutex ); - pthread_join( thread, NULL ); - } - - while( mlt_deque_count( this->queue ) ) - mlt_frame_close( mlt_deque_pop_back( this->queue ) ); - - this->sdl_screen = NULL; - this->audio_avail = 0; - - return NULL; -} - -static int consumer_get_dimensions( int *width, int *height ) -{ - int changed = 0; - - // SDL windows manager structure - SDL_SysWMinfo wm; - - // Specify the SDL Version - SDL_VERSION( &wm.version ); - - // Lock the display - //sdl_lock_display(); - -#ifndef __DARWIN__ - // Get the wm structure - if ( SDL_GetWMInfo( &wm ) == 1 ) - { - // Check that we have the X11 wm - if ( wm.subsystem == SDL_SYSWM_X11 ) - { - // Get the SDL window - Window window = wm.info.x11.window; - - // Get the display session - Display *display = wm.info.x11.display; - - // Get the window attributes - XWindowAttributes attr; - XGetWindowAttributes( display, window, &attr ); - - // Determine whether window has changed - changed = *width != attr.width || *height != attr.height; - - // Return width and height - *width = attr.width; - *height = attr.height; - } - } -#endif - - // Unlock the display - //sdl_unlock_display(); - - return changed; -} - -/** Callback to allow override of the close method. -*/ - -static void consumer_close( mlt_consumer parent ) -{ - // Get the actual object - consumer_sdl this = parent->child; - - // Stop the consumer - ///mlt_consumer_stop( parent ); - - // Now clean up the rest - mlt_consumer_close( parent ); - - // Close the queue - mlt_deque_close( this->queue ); - - // Destroy mutexes - pthread_mutex_destroy( &this->audio_mutex ); - pthread_cond_destroy( &this->audio_cond ); - - // Finally clean up this - free( this ); -} diff --git a/src/modules/sdl/consumer_sdl_osx_hack.h b/src/modules/sdl/consumer_sdl_osx_hack.h deleted file mode 100644 index dfd76d2..0000000 --- a/src/modules/sdl/consumer_sdl_osx_hack.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Purpose: A dummy thread object to inform Cocoa that it needs to be thread safe. - * Author: Zachary Drew - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import - -@interface DummyThread : NSObject -- init; -- (void)startThread:(id)arg; -@end - -@implementation DummyThread -- init -{ - [super init]; - return self; -} -- (void)startThread:(id)arg -{ - return; -} -@end diff --git a/src/modules/sdl/consumer_sdl_preview.c b/src/modules/sdl/consumer_sdl_preview.c deleted file mode 100644 index 12b7878..0000000 --- a/src/modules/sdl/consumer_sdl_preview.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * consumer_sdl_preview.c -- A Simple DirectMedia Layer consumer - * Copyright (C) 2004-2005 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct consumer_sdl_s *consumer_sdl; - -struct consumer_sdl_s -{ - struct mlt_consumer_s parent; - mlt_consumer active; - int ignore_change; - mlt_consumer play; - mlt_consumer still; - pthread_t thread; - int joined; - int running; - int sdl_flags; - double last_speed; - - pthread_cond_t refresh_cond; - pthread_mutex_t refresh_mutex; - int refresh_count; -}; - -/** Forward references to static functions. -*/ - -static int consumer_start( mlt_consumer parent ); -static int consumer_stop( mlt_consumer parent ); -static int consumer_is_stopped( mlt_consumer parent ); -static void consumer_close( mlt_consumer parent ); -static void *consumer_thread( void * ); -static void consumer_frame_show_cb( mlt_consumer sdl, mlt_consumer this, mlt_frame frame ); -static void consumer_sdl_event_cb( mlt_consumer sdl, mlt_consumer this, SDL_Event *event ); -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer this, char *name ); - -mlt_consumer consumer_sdl_preview_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - consumer_sdl this = calloc( sizeof( struct consumer_sdl_s ), 1 ); - if ( this != NULL && mlt_consumer_init( &this->parent, this, profile ) == 0 ) - { - // Get the parent consumer object - mlt_consumer parent = &this->parent; - - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( parent ); - - // Get the width and height - int width = mlt_properties_get_int( properties, "width" ); - int height = mlt_properties_get_int( properties, "height" ); - - // Process actual param - if ( arg == NULL || sscanf( arg, "%dx%d", &width, &height ) == 2 ) - { - mlt_properties_set_int( properties, "width", width ); - mlt_properties_set_int( properties, "height", height ); - } - - // Create child consumers - this->play = mlt_factory_consumer( profile, "sdl", arg ); - this->still = mlt_factory_consumer( profile, "sdl_still", arg ); - mlt_properties_set( MLT_CONSUMER_PROPERTIES( parent ), "real_time", "0" ); - mlt_properties_set( MLT_CONSUMER_PROPERTIES( parent ), "rescale", "nearest" ); - parent->close = consumer_close; - parent->start = consumer_start; - parent->stop = consumer_stop; - parent->is_stopped = consumer_is_stopped; - this->joined = 1; - mlt_events_listen( MLT_CONSUMER_PROPERTIES( this->play ), this, "consumer-frame-show", ( mlt_listener )consumer_frame_show_cb ); - mlt_events_listen( MLT_CONSUMER_PROPERTIES( this->still ), this, "consumer-frame-show", ( mlt_listener )consumer_frame_show_cb ); - mlt_events_listen( MLT_CONSUMER_PROPERTIES( this->play ), this, "consumer-sdl-event", ( mlt_listener )consumer_sdl_event_cb ); - mlt_events_listen( MLT_CONSUMER_PROPERTIES( this->still ), this, "consumer-sdl-event", ( mlt_listener )consumer_sdl_event_cb ); - pthread_cond_init( &this->refresh_cond, NULL ); - pthread_mutex_init( &this->refresh_mutex, NULL ); - mlt_events_listen( MLT_CONSUMER_PROPERTIES( parent ), this, "property-changed", ( mlt_listener )consumer_refresh_cb ); - return parent; - } - free( this ); - return NULL; -} - -void consumer_frame_show_cb( mlt_consumer sdl, mlt_consumer parent, mlt_frame frame ) -{ - consumer_sdl this = parent->child; - this->last_speed = mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ); - mlt_events_fire( MLT_CONSUMER_PROPERTIES( parent ), "consumer-frame-show", frame, NULL ); -} - -static void consumer_sdl_event_cb( mlt_consumer sdl, mlt_consumer parent, SDL_Event *event ) -{ - mlt_events_fire( MLT_CONSUMER_PROPERTIES( parent ), "consumer-sdl-event", event, NULL ); -} - -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer parent, char *name ) -{ - if ( !strcmp( name, "refresh" ) ) - { - consumer_sdl this = parent->child; - pthread_mutex_lock( &this->refresh_mutex ); - this->refresh_count = this->refresh_count <= 0 ? 1 : this->refresh_count ++; - pthread_cond_broadcast( &this->refresh_cond ); - pthread_mutex_unlock( &this->refresh_mutex ); - } -} - -static int consumer_start( mlt_consumer parent ) -{ - consumer_sdl this = parent->child; - - if ( !this->running ) - { - // properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( parent ); - mlt_properties play = MLT_CONSUMER_PROPERTIES( this->play ); - mlt_properties still = MLT_CONSUMER_PROPERTIES( this->still ); - - char *window_id = mlt_properties_get( properties, "window_id" ); - char *audio_driver = mlt_properties_get( properties, "audio_driver" ); - char *video_driver = mlt_properties_get( properties, "video_driver" ); - char *audio_device = mlt_properties_get( properties, "audio_device" ); - char *output_display = mlt_properties_get( properties, "output_display" ); - int progressive = mlt_properties_get_int( properties, "progressive" ) | mlt_properties_get_int( properties, "deinterlace" ); - - consumer_stop( parent ); - - this->running = 1; - this->joined = 0; - this->last_speed = 1; - - if ( output_display != NULL ) - setenv( "DISPLAY", output_display, 1 ); - - if ( window_id != NULL ) - setenv( "SDL_WINDOWID", window_id, 1 ); - - if ( video_driver != NULL ) - setenv( "SDL_VIDEODRIVER", video_driver, 1 ); - - if ( audio_driver != NULL ) - setenv( "SDL_AUDIODRIVER", audio_driver, 1 ); - - if ( audio_device != NULL ) - setenv( "AUDIODEV", audio_device, 1 ); - - if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) < 0 ) - { - fprintf( stderr, "Failed to initialize SDL: %s\n", SDL_GetError() ); - return -1; - } - - SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); - SDL_EnableUNICODE( 1 ); - - // Pass properties down - mlt_properties_set_data( play, "transport_producer", mlt_properties_get_data( properties, "transport_producer", NULL ), 0, NULL, NULL ); - mlt_properties_set_data( still, "transport_producer", mlt_properties_get_data( properties, "transport_producer", NULL ), 0, NULL, NULL ); - mlt_properties_set_data( play, "transport_callback", mlt_properties_get_data( properties, "transport_callback", NULL ), 0, NULL, NULL ); - mlt_properties_set_data( still, "transport_callback", mlt_properties_get_data( properties, "transport_callback", NULL ), 0, NULL, NULL ); - - mlt_properties_set_int( play, "progressive", progressive ); - mlt_properties_set_int( still, "progressive", progressive ); - - mlt_properties_pass_list( play, properties, "resize,rescale,width,height,aspect_ratio,display_ratio,volume" ); - mlt_properties_pass_list( still, properties, "resize,rescale,width,height,aspect_ratio,display_ratio" ); - mlt_properties_pass_list( play, properties, "deinterlace_method" ); - mlt_properties_pass_list( still, properties, "deinterlace_method" ); - mlt_properties_pass_list( play, properties, "preview_off,preview_format,window_background" ); - mlt_properties_pass_list( still, properties, "preview_off,preview_format,window_background" ); - - mlt_properties_pass( play, properties, "play." ); - mlt_properties_pass( still, properties, "still." ); - - mlt_properties_set_data( play, "app_lock", mlt_properties_get_data( properties, "app_lock", NULL ), 0, NULL, NULL ); - mlt_properties_set_data( still, "app_lock", mlt_properties_get_data( properties, "app_lock", NULL ), 0, NULL, NULL ); - mlt_properties_set_data( play, "app_unlock", mlt_properties_get_data( properties, "app_unlock", NULL ), 0, NULL, NULL ); - mlt_properties_set_data( still, "app_unlock", mlt_properties_get_data( properties, "app_unlock", NULL ), 0, NULL, NULL ); - - mlt_properties_set_int( play, "put_mode", 1 ); - mlt_properties_set_int( still, "put_mode", 1 ); - - // Start the still producer just to initialise the gui - mlt_consumer_start( this->still ); - this->active = this->still; - - // Inform child consumers that we control the sdl - mlt_properties_set_int( play, "sdl_started", 1 ); - mlt_properties_set_int( still, "sdl_started", 1 ); - - pthread_create( &this->thread, NULL, consumer_thread, this ); - } - - return 0; -} - -static int consumer_stop( mlt_consumer parent ) -{ - // Get the actual object - consumer_sdl this = parent->child; - - if ( this->joined == 0 ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( parent ); - int app_locked = mlt_properties_get_int( properties, "app_locked" ); - void ( *lock )( void ) = mlt_properties_get_data( properties, "app_lock", NULL ); - void ( *unlock )( void ) = mlt_properties_get_data( properties, "app_unlock", NULL ); - - if ( app_locked && unlock ) unlock( ); - - // Kill the thread and clean up - this->running = 0; - - pthread_mutex_lock( &this->refresh_mutex ); - pthread_cond_broadcast( &this->refresh_cond ); - pthread_mutex_unlock( &this->refresh_mutex ); - - pthread_join( this->thread, NULL ); - this->joined = 1; - - if ( app_locked && lock ) lock( ); - - SDL_Quit( ); - } - - return 0; -} - -static int consumer_is_stopped( mlt_consumer parent ) -{ - consumer_sdl this = parent->child; - return !this->running; -} - -static void *consumer_thread( void *arg ) -{ - // Identify the arg - consumer_sdl this = arg; - - // Get the consumer - mlt_consumer consumer = &this->parent; - - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer ); - - // internal intialization - int first = 1; - mlt_frame frame = NULL; - int last_position = -1; - - // Determine if the application is dealing with the preview - int preview_off = mlt_properties_get_int( properties, "preview_off" ); - - this->refresh_count = 0; - - // Loop until told not to - while( this->running ) - { - // Get a frame from the attached producer - frame = mlt_consumer_get_frame( consumer ); - - // Ensure that we have a frame - if ( this->running && frame != NULL ) - { - // Get the speed of the frame - double speed = mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ); - - // Lock during the operation - mlt_service_lock( MLT_CONSUMER_SERVICE( consumer ) ); - - // Get refresh request for the current frame - int refresh = mlt_properties_get_int( properties, "refresh" ); - - // Decrement refresh and clear changed - mlt_events_block( properties, properties ); - mlt_properties_set_int( properties, "refresh", 0 ); - mlt_events_unblock( properties, properties ); - - // Unlock after the operation - mlt_service_unlock( MLT_CONSUMER_SERVICE( consumer ) ); - - // Set the changed property on this frame for the benefit of still - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "refresh", refresh ); - - // Make sure the recipient knows that this frame isn't really rendered - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "rendered", 0 ); - - // Optimisation to reduce latency - if ( speed == 1.0 ) - { - if ( last_position != -1 && last_position + 1 != mlt_frame_get_position( frame ) ) - mlt_consumer_purge( this->play ); - last_position = mlt_frame_get_position( frame ); - } - else - { - //mlt_consumer_purge( this->play ); - last_position = -1; - } - - // If we're not the first frame and both consumers are stopped, then stop ourselves - if ( !first && mlt_consumer_is_stopped( this->play ) && mlt_consumer_is_stopped( this->still ) ) - { - this->running = 0; - mlt_frame_close( frame ); - } - // Allow a little grace time before switching consumers on speed changes - else if ( this->ignore_change -- > 0 && this->active != NULL && !mlt_consumer_is_stopped( this->active ) ) - { - mlt_consumer_put_frame( this->active, frame ); - } - // If we aren't playing normally, then use the still - else if ( speed != 1 ) - { - if ( !mlt_consumer_is_stopped( this->play ) ) - mlt_consumer_stop( this->play ); - if ( mlt_consumer_is_stopped( this->still ) ) - { - this->last_speed = speed; - this->active = this->still; - this->ignore_change = 0; - mlt_consumer_start( this->still ); - } - mlt_consumer_put_frame( this->still, frame ); - } - // Otherwise use the normal player - else - { - if ( !mlt_consumer_is_stopped( this->still ) ) - mlt_consumer_stop( this->still ); - if ( mlt_consumer_is_stopped( this->play ) ) - { - this->last_speed = speed; - this->active = this->play; - this->ignore_change = 25; - mlt_consumer_start( this->play ); - } - mlt_consumer_put_frame( this->play, frame ); - } - - // Copy the rectangle info from the active consumer - if ( this->running && preview_off == 0 ) - { - mlt_properties active = MLT_CONSUMER_PROPERTIES( this->active ); - mlt_service_lock( MLT_CONSUMER_SERVICE( consumer ) ); - mlt_properties_set_int( properties, "rect_x", mlt_properties_get_int( active, "rect_x" ) ); - mlt_properties_set_int( properties, "rect_y", mlt_properties_get_int( active, "rect_y" ) ); - mlt_properties_set_int( properties, "rect_w", mlt_properties_get_int( active, "rect_w" ) ); - mlt_properties_set_int( properties, "rect_h", mlt_properties_get_int( active, "rect_h" ) ); - mlt_service_unlock( MLT_CONSUMER_SERVICE( consumer ) ); - } - - if ( this->active == this->still ) - { - pthread_mutex_lock( &this->refresh_mutex ); - if ( this->running && speed == 0 && this->refresh_count <= 0 ) - pthread_cond_wait( &this->refresh_cond, &this->refresh_mutex ); - this->refresh_count --; - pthread_mutex_unlock( &this->refresh_mutex ); - } - - // We are definitely not waiting on the first frame any more - first = 0; - } - else - { - if ( frame ) mlt_frame_close( frame ); - mlt_consumer_put_frame( this->active, NULL ); - this->running = 0; - } - } - - if ( this->play ) mlt_consumer_stop( this->play ); - if ( this->still ) mlt_consumer_stop( this->still ); - - return NULL; -} - -/** Callback to allow override of the close method. -*/ - -static void consumer_close( mlt_consumer parent ) -{ - // Get the actual object - consumer_sdl this = parent->child; - - // Stop the consumer - mlt_consumer_stop( parent ); - - // Close the child consumers - mlt_consumer_close( this->play ); - mlt_consumer_close( this->still ); - - // Now clean up the rest - mlt_consumer_close( parent ); - - // Finally clean up this - free( this ); -} diff --git a/src/modules/sdl/consumer_sdl_still.c b/src/modules/sdl/consumer_sdl_still.c deleted file mode 100644 index 3efd8f4..0000000 --- a/src/modules/sdl/consumer_sdl_still.c +++ /dev/null @@ -1,645 +0,0 @@ -/* - * consumer_sdl_still.c -- A Simple DirectMedia Layer consumer - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** This classes definition. -*/ - -typedef struct consumer_sdl_s *consumer_sdl; - -struct consumer_sdl_s -{ - struct mlt_consumer_s parent; - mlt_properties properties; - pthread_t thread; - int joined; - int running; - int window_width; - int window_height; - int width; - int height; - int playing; - int sdl_flags; - SDL_Surface *sdl_screen; - SDL_Rect rect; - uint8_t *buffer; - int last_position; - mlt_producer last_producer; - int filtered; -}; - -/** Forward references to static functions. -*/ - -static int consumer_start( mlt_consumer parent ); -static int consumer_stop( mlt_consumer parent ); -static int consumer_is_stopped( mlt_consumer parent ); -static void consumer_close( mlt_consumer parent ); -static void *consumer_thread( void * ); -static int consumer_get_dimensions( int *width, int *height ); -static void consumer_sdl_event( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ); - -/** This is what will be called by the factory - anything can be passed in - via the argument, but keep it simple. -*/ - -mlt_consumer consumer_sdl_still_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create the consumer object - consumer_sdl this = calloc( sizeof( struct consumer_sdl_s ), 1 ); - - // If no malloc'd and consumer init ok - if ( this != NULL && mlt_consumer_init( &this->parent, this, profile ) == 0 ) - { - // Get the parent consumer object - mlt_consumer parent = &this->parent; - - // get a handle on properties - mlt_service service = MLT_CONSUMER_SERVICE( parent ); - this->properties = MLT_SERVICE_PROPERTIES( service ); - - // We have stuff to clean up, so override the close method - parent->close = consumer_close; - - // Default scaler (for now we'll use nearest) - mlt_properties_set( this->properties, "rescale", "nearest" ); - - // We're always going to run this in non-realtime mode - mlt_properties_set( this->properties, "real_time", "0" ); - - // Default progressive true - mlt_properties_set_int( this->properties, "progressive", 1 ); - - // Ensure we don't join on a non-running object - this->joined = 1; - - // process actual param - if ( arg == NULL || sscanf( arg, "%dx%d", &this->width, &this->height ) != 2 ) - { - this->width = mlt_properties_get_int( this->properties, "width" ); - this->height = mlt_properties_get_int( this->properties, "height" ); - } - else - { - mlt_properties_set_int( this->properties, "width", this->width ); - mlt_properties_set_int( this->properties, "height", this->height ); - } - - // Set the sdl flags - this->sdl_flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_RESIZABLE | SDL_DOUBLEBUF; - - // Allow thread to be started/stopped - parent->start = consumer_start; - parent->stop = consumer_stop; - parent->is_stopped = consumer_is_stopped; - - // Register specific events - mlt_events_register( this->properties, "consumer-sdl-event", ( mlt_transmitter )consumer_sdl_event ); - - // Return the consumer produced - return parent; - } - - // malloc or consumer init failed - free( this ); - - // Indicate failure - return NULL; -} - -static void consumer_sdl_event( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ) -{ - if ( listener != NULL ) - listener( owner, this, ( SDL_Event * )args[ 0 ] ); -} - -static int consumer_start( mlt_consumer parent ) -{ - consumer_sdl this = parent->child; - - if ( !this->running ) - { - int preview_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "preview_off" ); - int sdl_started = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" ); - - // Attach a colour space converter - if ( !this->filtered ) - { - mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( parent ) ); - mlt_filter filter = mlt_factory_filter( profile, "avcolour_space", NULL ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "forced", mlt_image_yuv422 ); - mlt_service_attach( MLT_CONSUMER_SERVICE( parent ), filter ); - mlt_filter_close( filter ); - this->filtered = 1; - } - - consumer_stop( parent ); - - this->last_position = -1; - this->running = 1; - this->joined = 0; - - // Allow the user to force resizing to window size - this->width = mlt_properties_get_int( this->properties, "width" ); - this->height = mlt_properties_get_int( this->properties, "height" ); - - // Default window size - double display_ratio = mlt_properties_get_double( this->properties, "display_ratio" ); - this->window_width = ( double )this->height * display_ratio; - this->window_height = this->height; - - if ( sdl_started == 0 && preview_off == 0 ) - { - if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) < 0 ) - { - fprintf( stderr, "Failed to initialize SDL: %s\n", SDL_GetError() ); - return -1; - } - - SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); - SDL_EnableUNICODE( 1 ); - } - else if ( preview_off == 0 ) - { - if ( SDL_GetVideoSurface( ) != NULL ) - { - this->sdl_screen = SDL_GetVideoSurface( ); - } - } - - if ( this->sdl_screen == NULL && preview_off == 0 ) - this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags ); - - pthread_create( &this->thread, NULL, consumer_thread, this ); - } - - return 0; -} - -static int consumer_stop( mlt_consumer parent ) -{ - // Get the actual object - consumer_sdl this = parent->child; - - if ( this->joined == 0 ) - { - int preview_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "preview_off" ); - int sdl_started = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" ); - - // Kill the thread and clean up - this->running = 0; - - pthread_join( this->thread, NULL ); - this->joined = 1; - - if ( sdl_started == 0 && preview_off == 0 ) - SDL_Quit( ); - - this->sdl_screen = NULL; - } - - return 0; -} - -static int consumer_is_stopped( mlt_consumer parent ) -{ - consumer_sdl this = parent->child; - return !this->running; -} - -static int sdl_lock_display( ) -{ - SDL_Surface *screen = SDL_GetVideoSurface( ); - return screen != NULL && ( !SDL_MUSTLOCK( screen ) || SDL_LockSurface( screen ) >= 0 ); -} - -static void sdl_unlock_display( ) -{ - SDL_Surface *screen = SDL_GetVideoSurface( ); - if ( screen != NULL && SDL_MUSTLOCK( screen ) ) - SDL_UnlockSurface( screen ); -} - -static inline void display_1( SDL_Surface *screen, SDL_Rect rect, uint8_t *image, int width, int height ) -{ - // Generate the affine transform scaling values - if ( rect.w == 0 || rect.h == 0 ) return; - int scale_width = ( width << 16 ) / rect.w; - int scale_height = ( height << 16 ) / rect.h; - int stride = width * 3; - int x, y, row_index; - uint8_t *q, *row; - - // Constants defined for clarity and optimisation - int scanlength = screen->pitch; - uint8_t *start = ( uint8_t * )screen->pixels + rect.y * scanlength + rect.x; - uint8_t *p; - - // Iterate through the screen using a very basic scaling algorithm - for ( y = 0; y < rect.h; y ++ ) - { - p = start; - row_index = ( 32768 + scale_height * y ) >> 16; - row = image + stride * row_index; - for ( x = 0; x < rect.w; x ++ ) - { - q = row + ( ( ( 32768 + scale_width * x ) >> 16 ) * 3 ); - *p ++ = SDL_MapRGB( screen->format, *q, *( q + 1 ), *( q + 2 ) ); - } - start += scanlength; - } -} - -static inline void display_2( SDL_Surface *screen, SDL_Rect rect, uint8_t *image, int width, int height ) -{ - // Generate the affine transform scaling values - if ( rect.w == 0 || rect.h == 0 ) return; - int scale_width = ( width << 16 ) / rect.w; - int scale_height = ( height << 16 ) / rect.h; - int stride = width * 3; - int x, y, row_index; - uint8_t *q, *row; - - // Constants defined for clarity and optimisation - int scanlength = screen->pitch / 2; - uint16_t *start = ( uint16_t * )screen->pixels + rect.y * scanlength + rect.x; - uint16_t *p; - - // Iterate through the screen using a very basic scaling algorithm - for ( y = 0; y < rect.h; y ++ ) - { - p = start; - row_index = ( 32768 + scale_height * y ) >> 16; - row = image + stride * row_index; - for ( x = 0; x < rect.w; x ++ ) - { - q = row + ( ( ( 32768 + scale_width * x ) >> 16 ) * 3 ); - *p ++ = SDL_MapRGB( screen->format, *q, *( q + 1 ), *( q + 2 ) ); - } - start += scanlength; - } -} - -static inline void display_3( SDL_Surface *screen, SDL_Rect rect, uint8_t *image, int width, int height ) -{ - // Generate the affine transform scaling values - if ( rect.w == 0 || rect.h == 0 ) return; - int scale_width = ( width << 16 ) / rect.w; - int scale_height = ( height << 16 ) / rect.h; - int stride = width * 3; - int x, y, row_index; - uint8_t *q, *row; - - // Constants defined for clarity and optimisation - int scanlength = screen->pitch; - uint8_t *start = ( uint8_t * )screen->pixels + rect.y * scanlength + rect.x; - uint8_t *p; - uint32_t pixel; - - // Iterate through the screen using a very basic scaling algorithm - for ( y = 0; y < rect.h; y ++ ) - { - p = start; - row_index = ( 32768 + scale_height * y ) >> 16; - row = image + stride * row_index; - for ( x = 0; x < rect.w; x ++ ) - { - q = row + ( ( ( 32768 + scale_width * x ) >> 16 ) * 3 ); - pixel = SDL_MapRGB( screen->format, *q, *( q + 1 ), *( q + 2 ) ); - *p ++ = (pixel & 0xFF0000) >> 16; - *p ++ = (pixel & 0x00FF00) >> 8; - *p ++ = (pixel & 0x0000FF); - } - start += scanlength; - } -} - -static inline void display_4( SDL_Surface *screen, SDL_Rect rect, uint8_t *image, int width, int height ) -{ - // Generate the affine transform scaling values - if ( rect.w == 0 || rect.h == 0 ) return; - int scale_width = ( width << 16 ) / rect.w; - int scale_height = ( height << 16 ) / rect.h; - int stride = width * 3; - int x, y, row_index; - uint8_t *q, *row; - - // Constants defined for clarity and optimisation - int scanlength = screen->pitch / 4; - uint32_t *start = ( uint32_t * )screen->pixels + rect.y * scanlength + rect.x; - uint32_t *p; - - // Iterate through the screen using a very basic scaling algorithm - for ( y = 0; y < rect.h; y ++ ) - { - p = start; - row_index = ( 32768 + scale_height * y ) >> 16; - row = image + stride * row_index; - for ( x = 0; x < rect.w; x ++ ) - { - q = row + ( ( ( 32768 + scale_width * x ) >> 16 ) * 3 ); - *p ++ = SDL_MapRGB( screen->format, *q, *( q + 1 ), *( q + 2 ) ); - } - start += scanlength; - } -} - -static int consumer_play_video( consumer_sdl this, mlt_frame frame ) -{ - // Get the properties of this consumer - mlt_properties properties = this->properties; - - mlt_image_format vfmt = mlt_image_rgb24; - int height = this->height; - int width = this->width; - uint8_t *image = NULL; - int changed = 0; - double display_ratio = mlt_properties_get_double( this->properties, "display_ratio" ); - - void ( *lock )( void ) = mlt_properties_get_data( properties, "app_lock", NULL ); - void ( *unlock )( void ) = mlt_properties_get_data( properties, "app_unlock", NULL ); - - if ( lock != NULL ) lock( ); - - sdl_lock_display(); - - // Handle events - if ( this->sdl_screen != NULL ) - { - SDL_Event event; - - changed = consumer_get_dimensions( &this->window_width, &this->window_height ); - - while ( SDL_PollEvent( &event ) ) - { - mlt_events_fire( this->properties, "consumer-sdl-event", &event, NULL ); - - switch( event.type ) - { - case SDL_VIDEORESIZE: - this->window_width = event.resize.w; - this->window_height = event.resize.h; - changed = 1; - break; - case SDL_QUIT: - this->running = 0; - break; - case SDL_KEYDOWN: - { - mlt_producer producer = mlt_properties_get_data( properties, "transport_producer", NULL ); - char keyboard[ 2 ] = " "; - void (*callback)( mlt_producer, char * ) = mlt_properties_get_data( properties, "transport_callback", NULL ); - if ( callback != NULL && producer != NULL && event.key.keysym.unicode < 0x80 && event.key.keysym.unicode > 0 ) - { - keyboard[ 0 ] = ( char )event.key.keysym.unicode; - callback( producer, keyboard ); - } - } - break; - } - } - } - - if ( this->sdl_screen == NULL || changed ) - { - // open SDL window - this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags ); - if ( consumer_get_dimensions( &this->window_width, &this->window_height ) ) - this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags ); - uint32_t color = mlt_properties_get_int( this->properties, "window_background" ); - SDL_FillRect( this->sdl_screen, NULL, color >> 8 ); - changed = 1; - } - else - { - changed = 1; - } - - if ( changed == 0 && - this->last_position == mlt_frame_get_position( frame ) && - this->last_producer == mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "_producer", NULL ) ) - { - sdl_unlock_display( ); - if ( unlock != NULL ) unlock( ); - return 0; - } - - // Update last frame shown info - this->last_position = mlt_frame_get_position( frame ); - this->last_producer = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "_producer", NULL ); - - // Get the image, width and height - mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 ); - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); - - if ( image != NULL ) - { - char *rescale = mlt_properties_get( properties, "rescale" ); - if ( rescale != NULL && strcmp( rescale, "none" ) ) - { - double this_aspect = display_ratio / ( ( double )this->window_width / ( double )this->window_height ); - this->rect.w = this_aspect * this->window_width; - this->rect.h = this->window_height; - if ( this->rect.w > this->window_width ) - { - this->rect.w = this->window_width; - this->rect.h = ( 1.0 / this_aspect ) * this->window_height; - } - } - else - { - double frame_aspect = mlt_frame_get_aspect_ratio( frame ) * width / height; - this->rect.w = frame_aspect * this->window_height; - this->rect.h = this->window_height; - if ( this->rect.w > this->window_width ) - { - this->rect.w = this->window_width; - this->rect.h = ( 1.0 / frame_aspect ) * this->window_width; - } - } - - this->rect.x = ( this->window_width - this->rect.w ) / 2; - this->rect.y = ( this->window_height - this->rect.h ) / 2; - - mlt_properties_set_int( this->properties, "rect_x", this->rect.x ); - mlt_properties_set_int( this->properties, "rect_y", this->rect.y ); - mlt_properties_set_int( this->properties, "rect_w", this->rect.w ); - mlt_properties_set_int( this->properties, "rect_h", this->rect.h ); - } - - if ( !mlt_consumer_is_stopped( &this->parent ) && SDL_GetVideoSurface( ) != NULL && this->sdl_screen != NULL && this->sdl_screen->pixels != NULL ) - { - switch( this->sdl_screen->format->BytesPerPixel ) - { - case 1: - display_1( this->sdl_screen, this->rect, image, width, height ); - break; - case 2: - display_2( this->sdl_screen, this->rect, image, width, height ); - break; - case 3: - display_3( this->sdl_screen, this->rect, image, width, height ); - break; - case 4: - display_4( this->sdl_screen, this->rect, image, width, height ); - break; - default: - fprintf( stderr, "Unsupported video depth %d\n", this->sdl_screen->format->BytesPerPixel ); - break; - } - - // Flip it into sight - SDL_Flip( this->sdl_screen ); - } - - sdl_unlock_display(); - - if ( unlock != NULL ) unlock( ); - - return 1; -} - -/** Threaded wrapper for pipe. -*/ - -static void *consumer_thread( void *arg ) -{ - // Identify the arg - consumer_sdl this = arg; - - // Get the consumer - mlt_consumer consumer = &this->parent; - mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer ); - - // internal intialization - mlt_frame frame = NULL; - mlt_image_format vfmt = mlt_image_rgb24a; - int height = this->height; - int width = this->width; - uint8_t *image = NULL; - - // Allow the hosting app to provide the preview - int preview_off = mlt_properties_get_int( properties, "preview_off" ); - mlt_image_format preview_format = mlt_properties_get_int( properties, "preview_format" ); - - // Check if a specific colour space has been requested - if ( preview_off && preview_format != mlt_image_none ) - vfmt = preview_format; - - // Loop until told not to - while( this->running ) - { - // Get a frame from the attached producer - frame = mlt_consumer_rt_frame( consumer ); - - // Ensure that we have a frame - if ( this->running && frame != NULL ) - { - if ( preview_off == 0 ) - { - consumer_play_video( this, frame ); - } - else - { - mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "format", vfmt ); - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); - } - mlt_frame_close( frame ); - } - else - { - if ( frame ) mlt_frame_close( frame ); - this->running = 0; - } - } - - return NULL; -} - -static int consumer_get_dimensions( int *width, int *height ) -{ - int changed = 0; - - // SDL windows manager structure - SDL_SysWMinfo wm; - - // Specify the SDL Version - SDL_VERSION( &wm.version ); - - // Get the wm structure - if ( SDL_GetWMInfo( &wm ) == 1 ) - { -#ifndef __DARWIN__ - // Check that we have the X11 wm - if ( wm.subsystem == SDL_SYSWM_X11 ) - { - // Get the SDL window - Window window = wm.info.x11.window; - - // Get the display session - Display *display = wm.info.x11.display; - - // Get the window attributes - XWindowAttributes attr; - XGetWindowAttributes( display, window, &attr ); - - // Determine whether window has changed - changed = *width != attr.width || *height != attr.height; - - // Return width and height - *width = attr.width; - *height = attr.height; - } -#endif - } - - return changed; -} - -/** Callback to allow override of the close method. -*/ - -static void consumer_close( mlt_consumer parent ) -{ - // Get the actual object - consumer_sdl this = parent->child; - - // Stop the consumer - mlt_consumer_stop( parent ); - - // Now clean up the rest - mlt_consumer_close( parent ); - - // Finally clean up this - free( this ); -} diff --git a/src/modules/sdl/factory.c b/src/modules/sdl/factory.c deleted file mode 100644 index 68301c2..0000000 --- a/src/modules/sdl/factory.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -extern mlt_consumer consumer_sdl_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_consumer consumer_sdl_still_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_consumer consumer_sdl_preview_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -#ifdef WITH_SDL_IMAGE -extern mlt_producer producer_sdl_image_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -#endif - -MLT_REPOSITORY -{ - MLT_REGISTER( consumer_type, "sdl", consumer_sdl_init ); - MLT_REGISTER( consumer_type, "sdl_preview", consumer_sdl_preview_init ); - MLT_REGISTER( consumer_type, "sdl_still", consumer_sdl_still_init ); -#ifdef WITH_SDL_IMAGE - MLT_REGISTER( producer_type, "sdl_image", producer_sdl_image_init ); -#endif -} diff --git a/src/modules/sdl/producer_sdl_image.c b/src/modules/sdl/producer_sdl_image.c deleted file mode 100644 index 19f4f4b..0000000 --- a/src/modules/sdl/producer_sdl_image.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * producer_sdl_image.c -- Image loader which wraps SDL_image - * Copyright (C) 2005 Visual Media FX - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static int producer_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - SDL_Surface *surface = mlt_properties_get_data( properties, "surface", NULL ); - SDL_Surface *converted = NULL; - uint8_t *alpha; - - *width = surface->w; - *height = surface->h; - *format = mlt_image_yuv422; - *image = mlt_pool_alloc( *width * *height * 2 ); - alpha = mlt_pool_alloc( *width * *height ); - - if ( surface->format->BitsPerPixel != 32 && surface->format->BitsPerPixel != 24 ) - { - SDL_PixelFormat fmt; - fmt.BitsPerPixel = 24; - fmt.BytesPerPixel = 3; - fmt.Rshift = 16; - fmt.Gshift = 8; - fmt.Bshift = 0; - fmt.Rmask = 0xff << 16; - fmt.Gmask = 0xff << 8; - fmt.Bmask = 0xff; - converted = SDL_ConvertSurface( surface, &fmt, 0 ); - } - - switch( surface->format->BitsPerPixel ) - { - case 32: - mlt_convert_rgb24a_to_yuv422( surface->pixels, *width, *height, surface->pitch, *image, alpha ); - break; - case 24: - mlt_convert_rgb24_to_yuv422( surface->pixels, *width, *height, surface->pitch, *image ); - memset( alpha, 255, *width * *height ); - break; - default: - mlt_convert_rgb24_to_yuv422( converted->pixels, *width, *height, converted->pitch, *image ); - memset( alpha, 255, *width * *height ); - break; - } - - if ( converted ) - SDL_FreeSurface( converted ); - - // Update the frame - mlt_properties_set_data( properties, "image", *image, *width * *height * 2, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "alpha", alpha, *width * *height, mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "width", *width ); - mlt_properties_set_int( properties, "height", *height ); - - return 0; -} - -static int filter_files( const struct dirent *de ) -{ - return de->d_name[ 0 ] != '.'; -} - -static mlt_properties parse_file_names( char *resource ) -{ - mlt_properties properties = mlt_properties_new( ); - - if ( strstr( resource, "/.all." ) != NULL ) - { - char *dir_name = strdup( resource ); - char *extension = strrchr( resource, '.' ); - *( strstr( dir_name, "/.all." ) + 1 ) = '\0'; - char fullname[ 1024 ]; - strcpy( fullname, dir_name ); - struct dirent **de = NULL; - int n = scandir( fullname, &de, filter_files, alphasort ); - int i; - struct stat info; - - for (i = 0; i < n; i++ ) - { - snprintf( fullname, 1023, "%s%s", dir_name, de[i]->d_name ); - if ( strstr( fullname, extension ) && lstat( fullname, &info ) == 0 && - ( S_ISREG( info.st_mode ) || info.st_mode | S_IXUSR ) ) - { - char temp[ 20 ]; - sprintf( temp, "%d", i ); - mlt_properties_set( properties, temp, fullname ); - } - free( de[ i ] ); - } - - free( de ); - free( dir_name ); - } - else - { - mlt_properties_set( properties, "0", resource ); - } - - return properties; -} - -static SDL_Surface *load_image( mlt_producer producer ) -{ - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - char *resource = mlt_properties_get( properties, "resource" ); - char *last_resource = mlt_properties_get( properties, "_last_resource" ); - int image_idx = 0; - char *this_resource = NULL; - double ttl = mlt_properties_get_int( properties, "ttl" ); - mlt_position position = mlt_producer_position( producer ); - SDL_Surface *surface = mlt_properties_get_data( properties, "_surface", NULL ); - mlt_properties filenames = mlt_properties_get_data( properties, "_filenames", NULL ); - - if ( filenames == NULL ) - { - filenames = parse_file_names( resource ); - mlt_properties_set_data( properties, "_surface", surface, 0, ( mlt_destructor )SDL_FreeSurface, 0 ); - } - - if ( mlt_properties_count( filenames ) ) - { - image_idx = ( int )floor( ( double )position / ttl ) % mlt_properties_count( filenames ); - this_resource = mlt_properties_get_value( filenames, image_idx ); - - if ( surface == NULL || last_resource == NULL || strcmp( last_resource, this_resource ) ) - { - surface = IMG_Load( this_resource ); - if ( surface != NULL ) - { - surface->refcount ++; - mlt_properties_set_data( properties, "_surface", surface, 0, ( mlt_destructor )SDL_FreeSurface, 0 ); - mlt_properties_set( properties, "_last_resource", this_resource ); - mlt_properties_set_int( properties, "_real_width", surface->w ); - mlt_properties_set_int( properties, "_real_height", surface->h ); - } - } - else if ( surface != NULL ) - { - surface->refcount ++; - } - } - - return surface; -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Generate a frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - if ( *frame != NULL ) - { - // Create the surface for the current image - SDL_Surface *surface = load_image( producer ); - - if ( surface != NULL ) - { - // Obtain properties of frame and producer - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Obtain properties of producer - mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Set producer-specific frame properties - mlt_properties_set_int( properties, "progressive", 1 ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) ); - mlt_properties_set_data( properties, "surface", surface, 0, ( mlt_destructor )SDL_FreeSurface, NULL ); - mlt_properties_set_int( properties, "real_width", surface->w ); - mlt_properties_set_int( properties, "real_height", surface->h ); - - // Push the get_image method - mlt_frame_push_get_image( *frame, producer_get_image ); - } - } - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer producer ) -{ - producer->close = NULL; - mlt_producer_close( producer ); - free( producer ); -} - -mlt_producer producer_sdl_image_init( mlt_profile profile, mlt_service_type type, const char *id, char *file ) -{ - mlt_producer producer = calloc( 1, sizeof( struct mlt_producer_s ) ); - if ( producer != NULL && mlt_producer_init( producer, NULL ) == 0 ) - { - // Get the properties interface - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Callback registration - producer->get_frame = producer_get_frame; - producer->close = ( mlt_destructor )producer_close; - - // Set the default properties - mlt_properties_set( properties, "resource", file ); - mlt_properties_set( properties, "_resource", "" ); - mlt_properties_set_double( properties, "aspect_ratio", 1 ); - mlt_properties_set_int( properties, "ttl", 25 ); - mlt_properties_set_int( properties, "progressive", 1 ); - - // Validate the resource - SDL_Surface *surface = NULL; - if ( file && ( surface = load_image( producer ) ) ) - { - SDL_FreeSurface( surface ); - mlt_properties_set_data( properties, "_surface", NULL, 0, NULL, NULL ); - } - else - { - producer_close( producer ); - producer = NULL; - } - return producer; - } - free( producer ); - return NULL; -} - - diff --git a/src/modules/sox/Makefile b/src/modules/sox/Makefile deleted file mode 100644 index 472c591..0000000 --- a/src/modules/sox/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -include ../../../config.mak - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -include config.mak - -TARGET = ../libmltsox$(LIBSUF) - -OBJS = factory.o \ - filter_sox.o - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/sox/configure b/src/modules/sox/configure deleted file mode 100755 index 9df730a..0000000 --- a/src/modules/sox/configure +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - # Determine how to lookup dependencies of executable for OS - targetos=$(uname -s) - case $targetos in - Darwin) - LDD="otool -L" - ;; - Linux|FreeBSD) - LDD="ldd" - ;; - *) - ;; - esac - - pkg-config sox - if [ $? -eq 0 ] - then - disable_sox=0 - echo "CFLAGS += $(pkg-config --cflags sox) -I$(pkg-config --variable=prefix sox)" > config.mak - echo "LDFLAGS += $(pkg-config --libs sox)" >> config.mak - [ $(pkg-config --modversion sox | cut -d. -f1) -gt 13 ] && echo "CFLAGS += -DSOX14" >> config.mak - else - which libst-config > /dev/null 2>&1 - if [ $? -eq 0 ] - then - disable_sox=0 - - # determine if we need libsndfile - $LDD $(which sox) | grep libsndfile > /dev/null - [ $? -eq 0 ] && libsndfile="-lsndfile" - - # determine if we need libsamplerate - $LDD $(which sox) | grep libsamplerate > /dev/null - [ $? -eq 0 ] && libsamplerate="-lsamplerate" - - echo "CFLAGS += $(libst-config --cflags) -I../.." > config.mak - echo "LDFLAGS += -lst $(libst-config --libs) $libsndfile $libsamplerate" >> config.mak - else - sox --version 2> /dev/null | grep 'v14.' > /dev/null - disable_sox=$? - if [ $disable_sox -eq 0 ] - then - LIBDIR=lib - bits=$(uname -m) - case $bits in - x86_64) - [ -d /usr/lib/lib64 ] && export LIBDIR=lib64 || export LIBDIR=lib - ;; - *) - export LIBDIR=lib - ;; - esac - - sox=$(which sox) - # chop sox - soxdir=$(dirname $sox) - # chop bin - soxdir=$(dirname $soxdir) - - # determine if we need libsamplerate - $LDD "$sox" | grep libsamplerate > /dev/null - [ $? -eq 0 ] && libsamplerate="-lsamplerate" - - # determine if we need libsfx - $LDD $(which sox) | grep libsfx > /dev/null - [ $? -eq 0 ] && libsfx="-lsfx" - - echo "CFLAGS += -DSOX14 -I$soxdir/include" > config.mak - echo "LDFLAGS += -L$soxdir/$LIBDIR -lsox $libsfx $libsamplerate" >> config.mak - fi - fi - fi - - if [ "$disable_sox" != "0" ] - then - echo "- sox not found: disabling" - touch ../disable-sox - fi - - exit 0 -fi diff --git a/src/modules/sox/factory.c b/src/modules/sox/factory.c deleted file mode 100644 index 048d3bc..0000000 --- a/src/modules/sox/factory.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -extern mlt_filter filter_sox_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "sox", filter_sox_init ); -} diff --git a/src/modules/sox/filter_sox.c b/src/modules/sox/filter_sox.c deleted file mode 100644 index 66cc54d..0000000 --- a/src/modules/sox/filter_sox.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * filter_sox.c -- apply any number of SOX effects using libst - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include -#include - -// TODO: does not support multiple effects with SoX v14.1.0+ - -#ifdef SOX14 -# include -# define ST_EOF SOX_EOF -# define ST_SUCCESS SOX_SUCCESS -# define st_sample_t sox_sample_t -# define eff_t sox_effect_t* -# define ST_LIB_VERSION_CODE SOX_LIB_VERSION_CODE -# define ST_LIB_VERSION SOX_LIB_VERSION -# if (ST_LIB_VERSION_CODE >= ST_LIB_VERSION(14,2,0)) -# define st_size_t size_t -# else -# define st_size_t sox_size_t -# endif -# define ST_SIGNED_WORD_TO_SAMPLE(d,clips) SOX_SIGNED_16BIT_TO_SAMPLE(d,clips) -# if (ST_LIB_VERSION_CODE >= ST_LIB_VERSION(14,1,0)) -# define ST_SSIZE_MIN SOX_SAMPLE_MIN -# else -# define ST_SSIZE_MIN SOX_SSIZE_MIN -# endif -# define ST_SAMPLE_TO_SIGNED_WORD(d,clips) SOX_SAMPLE_TO_SIGNED_16BIT(d,clips) -#else -# include -#endif - -#define BUFFER_LEN 8192 -#define AMPLITUDE_NORM 0.2511886431509580 /* -12dBFS */ -#define AMPLITUDE_MIN 0.00001 - -/** Compute the mean of a set of doubles skipping unset values flagged as -1 -*/ -static inline double mean( double *buf, int count ) -{ - double mean = 0; - int i; - int j = 0; - - for ( i = 0; i < count; i++ ) - { - if ( buf[ i ] != -1.0 ) - { - mean += buf[ i ]; - j ++; - } - } - if ( j > 0 ) - mean /= j; - - return mean; -} - -#if (ST_LIB_VERSION_CODE >= ST_LIB_VERSION(14,1,0)) -static void delete_effect( eff_t effp ) -{ - free( effp->priv ); - free( (void*)effp->in_encoding ); - free( effp ); -} -#endif - -/** Create an effect state instance for a channels -*/ -static int create_effect( mlt_filter this, char *value, int count, int channel, int frequency ) -{ - mlt_tokeniser tokeniser = mlt_tokeniser_init(); - char id[ 256 ]; - int error = 1; - - // Tokenise the effect specification - mlt_tokeniser_parse_new( tokeniser, value, " " ); - if ( tokeniser->count < 1 ) - return error; - - // Locate the effect - mlt_destructor effect_destructor = mlt_pool_release; -#ifdef SOX14 - //fprintf(stderr, "%s: effect %s count %d\n", __FUNCTION__, tokeniser->tokens[0], tokeniser->count ); -#if (ST_LIB_VERSION_CODE >= ST_LIB_VERSION(14,1,0)) - sox_effect_handler_t const *eff_handle = sox_find_effect( tokeniser->tokens[0] ); - if (eff_handle == NULL ) return error; - eff_t eff = sox_create_effect( eff_handle ); - effect_destructor = ( mlt_destructor ) delete_effect; - sox_encodinginfo_t *enc = calloc( 1, sizeof( sox_encodinginfo_t ) ); - enc->encoding = SOX_ENCODING_SIGN2; - enc->bits_per_sample = 16; - eff->in_encoding = eff->out_encoding = enc; -#else - eff_t eff = mlt_pool_alloc( sizeof( sox_effect_t ) ); - sox_create_effect( eff, sox_find_effect( tokeniser->tokens[0] ) ); -#endif - int opt_count = tokeniser->count - 1; -#else - eff_t eff = mlt_pool_alloc( sizeof( struct st_effect ) ); - int opt_count = st_geteffect_opt( eff, tokeniser->count, tokeniser->tokens ); -#endif - - // If valid effect - if ( opt_count != ST_EOF ) - { - // Supply the effect parameters -#ifdef SOX14 - if ( ( * eff->handler.getopts )( eff, opt_count, &tokeniser->tokens[ tokeniser->count > 1 ? 1 : 0 ] ) == ST_SUCCESS ) -#else - if ( ( * eff->h->getopts )( eff, opt_count, &tokeniser->tokens[ tokeniser->count - opt_count ] ) == ST_SUCCESS ) -#endif - { - // Set the sox signal parameters -#if (ST_LIB_VERSION_CODE >= ST_LIB_VERSION(14,1,0)) - eff->in_signal.rate = frequency; - eff->out_signal.rate = frequency; - eff->in_signal.channels = 1; - eff->out_signal.channels = 1; - eff->in_signal.precision = 16; - eff->out_signal.precision = 16; - eff->in_signal.length = 0; - eff->out_signal.length = 0; -#else - eff->ininfo.rate = frequency; - eff->outinfo.rate = frequency; - eff->ininfo.channels = 1; - eff->outinfo.channels = 1; -#endif - - // Start the effect -#ifdef SOX14 - if ( ( * eff->handler.start )( eff ) == ST_SUCCESS ) -#else - if ( ( * eff->h->start )( eff ) == ST_SUCCESS ) -#endif - { - // Construct id - sprintf( id, "_effect_%d_%d", count, channel ); - - // Save the effect state - mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), id, eff, 0, effect_destructor, NULL ); - error = 0; - } - } - } - // Some error occurred so delete the temp effect state - if ( error == 1 ) - effect_destructor( eff ); - - mlt_tokeniser_close( tokeniser ); - - return error; -} - -/** Get the audio. -*/ - -static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the properties of the frame - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - - // Get the filter service - mlt_filter filter = mlt_frame_pop_audio( frame ); - - // Get the filter properties - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - - // Get the properties - st_sample_t *input_buffer = mlt_properties_get_data( filter_properties, "input_buffer", NULL ); - st_sample_t *output_buffer = mlt_properties_get_data( filter_properties, "output_buffer", NULL ); - int channels_avail = *channels; - int i; // channel - int count = mlt_properties_get_int( filter_properties, "_effect_count" ); - - // Get the producer's audio - mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples ); - - // Duplicate channels as necessary - if ( channels_avail < *channels ) - { - int size = *channels * *samples * sizeof( int16_t ); - int16_t *new_buffer = mlt_pool_alloc( size ); - int j, k = 0; - - // Duplicate the existing channels - for ( i = 0; i < *samples; i++ ) - { - for ( j = 0; j < *channels; j++ ) - { - new_buffer[ ( i * *channels ) + j ] = (*buffer)[ ( i * channels_avail ) + k ]; - k = ( k + 1 ) % channels_avail; - } - } - - // Update the audio buffer now - destroys the old - mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - - *buffer = new_buffer; - } - else if ( channels_avail == 6 && *channels == 2 ) - { - // Nasty hack for ac3 5.1 audio - may be a cause of failure? - int size = *channels * *samples * sizeof( int16_t ); - int16_t *new_buffer = mlt_pool_alloc( size ); - - // Drop all but the first *channels - for ( i = 0; i < *samples; i++ ) - { - new_buffer[ ( i * *channels ) + 0 ] = (*buffer)[ ( i * channels_avail ) + 2 ]; - new_buffer[ ( i * *channels ) + 1 ] = (*buffer)[ ( i * channels_avail ) + 3 ]; - } - - // Update the audio buffer now - destroys the old - mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); - - *buffer = new_buffer; - } - - // Even though some effects are multi-channel aware, it is not reliable - // We must maintain a separate effect state for each channel - for ( i = 0; i < *channels; i++ ) - { - char id[ 256 ]; - sprintf( id, "_effect_0_%d", i ); - - // Get an existing effect state - eff_t e = mlt_properties_get_data( filter_properties, id, NULL ); - - // Validate the existing effect state -#if (ST_LIB_VERSION_CODE >= ST_LIB_VERSION(14,1,0)) - if ( e != NULL && ( e->in_signal.rate != *frequency || - e->out_signal.rate != *frequency ) ) -#else - if ( e != NULL && ( e->ininfo.rate != *frequency || - e->outinfo.rate != *frequency ) ) -#endif - e = NULL; - - // (Re)Create the effect state - if ( e == NULL ) - { - int j = 0; - - // Reset the count - count = 0; - - // Loop over all properties - for ( j = 0; j < mlt_properties_count( filter_properties ); j ++ ) - { - // Get the name of this property - char *name = mlt_properties_get_name( filter_properties, j ); - - // If the name does not contain a . and matches effect - if ( !strncmp( name, "effect", 6 ) ) - { - // Get the effect specification - char *value = mlt_properties_get( filter_properties, name ); - - // Create an instance - if ( create_effect( filter, value, count, i, *frequency ) == 0 ) - count ++; - } - } - - // Save the number of filters - mlt_properties_set_int( filter_properties, "_effect_count", count ); - - } - if ( *samples > 0 && count > 0 ) - { - st_sample_t *p = input_buffer; - st_sample_t *end = p + *samples; - int16_t *q = *buffer + i; - st_size_t isamp = *samples; - st_size_t osamp = *samples; - double rms = 0; - int j; - char *normalise = mlt_properties_get( filter_properties, "normalise" ); - double normalised_gain = 1.0; -#if (ST_LIB_VERSION_CODE >= ST_LIB_VERSION(13,0,0)) - st_sample_t dummy_clipped_count = 0; -#endif - - // Convert to sox encoding - while( p != end ) - { -#if (ST_LIB_VERSION_CODE >= ST_LIB_VERSION(13,0,0)) - *p = ST_SIGNED_WORD_TO_SAMPLE( *q, dummy_clipped_count ); -#else - *p = ST_SIGNED_WORD_TO_SAMPLE( *q ); -#endif - // Compute rms amplitude while we are accessing each sample - rms += ( double )*p * ( double )*p; - - p ++; - q += *channels; - } - - // Compute final rms amplitude - rms = sqrt( rms / *samples / ST_SSIZE_MIN / ST_SSIZE_MIN ); - - if ( normalise ) - { - int window = mlt_properties_get_int( filter_properties, "window" ); - double *smooth_buffer = mlt_properties_get_data( filter_properties, "smooth_buffer", NULL ); - double max_gain = mlt_properties_get_double( filter_properties, "max_gain" ); - - // Default the maximum gain factor to 20dBFS - if ( max_gain == 0 ) - max_gain = 10.0; - - // The smoothing buffer prevents radical shifts in the gain level - if ( window > 0 && smooth_buffer != NULL ) - { - int smooth_index = mlt_properties_get_int( filter_properties, "_smooth_index" ); - smooth_buffer[ smooth_index ] = rms; - - // Ignore very small values that adversely affect the mean - if ( rms > AMPLITUDE_MIN ) - mlt_properties_set_int( filter_properties, "_smooth_index", ( smooth_index + 1 ) % window ); - - // Smoothing is really just a mean over the past N values - normalised_gain = AMPLITUDE_NORM / mean( smooth_buffer, window ); - } - else if ( rms > 0 ) - { - // Determine gain to apply as current amplitude - normalised_gain = AMPLITUDE_NORM / rms; - } - - //printf("filter_sox: rms %.3f gain %.3f\n", rms, normalised_gain ); - - // Govern the maximum gain - if ( normalised_gain > max_gain ) - normalised_gain = max_gain; - } - - // For each effect - for ( j = 0; j < count; j++ ) - { - sprintf( id, "_effect_%d_%d", j, i ); - e = mlt_properties_get_data( filter_properties, id, NULL ); - - // We better have this guy - if ( e != NULL ) - { - float saved_gain = 1.0; - - // XXX: hack to apply the normalised gain level to the vol effect -#ifdef SOX14 - if ( normalise && strcmp( e->handler.name, "vol" ) == 0 ) -#else - if ( normalise && strcmp( e->name, "vol" ) == 0 ) -#endif - { - float *f = ( float * )( e->priv ); - saved_gain = *f; - *f = saved_gain * normalised_gain; - } - - // Apply the effect -#ifdef SOX14 - if ( ( * e->handler.flow )( e, input_buffer, output_buffer, &isamp, &osamp ) == ST_SUCCESS ) -#else - if ( ( * e->h->flow )( e, input_buffer, output_buffer, &isamp, &osamp ) == ST_SUCCESS ) -#endif - { - // Swap input and output buffer pointers for subsequent effects - p = input_buffer; - input_buffer = output_buffer; - output_buffer = p; - } - - // XXX: hack to restore the original vol gain to prevent accumulation -#ifdef SOX14 - if ( normalise && strcmp( e->handler.name, "vol" ) == 0 ) -#else - if ( normalise && strcmp( e->name, "vol" ) == 0 ) -#endif - { - float *f = ( float * )( e->priv ); - *f = saved_gain; - } - } - } - - // Convert back to signed 16bit - p = input_buffer; - q = *buffer + i; - end = p + *samples; - while ( p != end ) - { -#if (ST_LIB_VERSION_CODE >= ST_LIB_VERSION(13,0,0)) - *q = ST_SAMPLE_TO_SIGNED_WORD( *p ++, dummy_clipped_count ); -#else - *q = ST_SAMPLE_TO_SIGNED_WORD( *p ++ ); -#endif - q += *channels; - } - } - } - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - if ( mlt_frame_is_test_audio( frame ) == 0 ) - { - // Add the filter to the frame - mlt_frame_push_audio( frame, this ); - mlt_frame_push_audio( frame, filter_get_audio ); - - // Parse the window property and allocate smoothing buffer if needed - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - int window = mlt_properties_get_int( properties, "window" ); - if ( mlt_properties_get( properties, "smooth_buffer" ) == NULL && window > 1 ) - { - // Create a smoothing buffer for the calculated "max power" of frame of audio used in normalisation - double *smooth_buffer = (double*) calloc( window, sizeof( double ) ); - int i; - for ( i = 0; i < window; i++ ) - smooth_buffer[ i ] = -1.0; - mlt_properties_set_data( properties, "smooth_buffer", smooth_buffer, 0, free, NULL ); - } - } - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_sox_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - void *input_buffer = mlt_pool_alloc( BUFFER_LEN ); - void *output_buffer = mlt_pool_alloc( BUFFER_LEN ); - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - this->process = filter_process; - - if ( arg != NULL ) - mlt_properties_set( properties, "effect", arg ); - mlt_properties_set_data( properties, "input_buffer", input_buffer, BUFFER_LEN, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "output_buffer", output_buffer, BUFFER_LEN, mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "window", 75 ); - } - return this; -} - -// What to do when a libst internal failure occurs -void cleanup(void){} - -// Is there a build problem with my sox-devel package? -#ifndef gsm_create -void gsm_create(void){} -#endif -#ifndef gsm_decode -void gsm_decode(void){} -#endif -#ifndef gdm_encode -void gsm_encode(void){} -#endif -#ifndef gsm_destroy -void gsm_destroy(void){} -#endif -#ifndef gsm_option -void gsm_option(void){} -#endif diff --git a/src/modules/valerie/Makefile b/src/modules/valerie/Makefile deleted file mode 100644 index 9cdd020..0000000 --- a/src/modules/valerie/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltvalerie$(LIBSUF) - -OBJS = factory.o \ - consumer_valerie.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../valerie -lvalerie -LDFLAGS += -L../../framework -lmlt - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/valerie/consumer_valerie.c b/src/modules/valerie/consumer_valerie.c deleted file mode 100644 index 4d4c9a3..0000000 --- a/src/modules/valerie/consumer_valerie.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * consumer_valerie.c -- pushes a service via valerie - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static int consumer_is_stopped( mlt_consumer this ); -static int consumer_start( mlt_consumer this ); - -/** This is what will be called by the factory -*/ - -mlt_consumer consumer_valerie_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create the consumer object - mlt_consumer this = calloc( sizeof( struct mlt_consumer_s ), 1 ); - - // If no malloc'd and consumer init ok - if ( this != NULL && mlt_consumer_init( this, NULL, profile ) == 0 ) - { - if ( arg != NULL && strchr( arg, ':' ) ) - { - char *temp = NULL; - int port = atoi( strchr( arg, ':' ) + 1 ); - mlt_properties_set( MLT_CONSUMER_PROPERTIES( this ), "server", arg ); - temp = mlt_properties_get( MLT_CONSUMER_PROPERTIES( this ), "server" ); - *( strchr( temp, ':' ) ) = '\0'; - mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( this ), "port", port ); - } - else - { - mlt_properties_set( MLT_CONSUMER_PROPERTIES( this ), "server", arg == NULL ? "localhost" : arg ); - mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( this ), "port", 5250 ); - } - - mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( this ), "unit", 0 ); - mlt_properties_set( MLT_CONSUMER_PROPERTIES( this ), "command", "append" ); - - // Allow thread to be started/stopped - this->start = consumer_start; - this->is_stopped = consumer_is_stopped; - - // Return the consumer produced - return this; - } - - // malloc or consumer init failed - free( this ); - - // Indicate failure - return NULL; -} - -static int consumer_start( mlt_consumer this ) -{ - // Get the producer service - mlt_service service = mlt_service_producer( MLT_CONSUMER_SERVICE( this ) ); - - // Get the properties object - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Get all the properties now - char *server = mlt_properties_get( properties, "server" ); - int port = mlt_properties_get_int( properties, "port" ); - char *cmd = mlt_properties_get( properties, "command" ); - int unit = mlt_properties_get_int( properties, "unit" ); - char *title = mlt_properties_get( properties, "title" ); - char command[ 2048 ]; - - // If this is a reuse, then a valerie object will exist - valerie connection = mlt_properties_get_data( properties, "connection", NULL ); - - // Special case - we can get a doc too... - char *doc = mlt_properties_get( properties, "westley" ); - - // Set the title if provided - if ( service != NULL ) - { - if ( title != NULL ) - mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), "title", title ); - else if ( mlt_properties_get( MLT_SERVICE_PROPERTIES( service ), "title" ) == NULL ) - mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), "title", "Anonymous Submission" ); - title = mlt_properties_get( MLT_SERVICE_PROPERTIES( service ), "title" ); - } - - strcpy( command, cmd == NULL ? "" : cmd ); - if ( strstr( command, "title=" ) == NULL && title != NULL ) - { - strcat( command, " title=\"" ); - strcat( command, title ); - strcat( command, "\"" ); - } - - if ( service != NULL || doc != NULL ) - { - // Initiate the connection if required - if ( connection == NULL ) - { - valerie_parser parser = valerie_parser_init_remote( server, port ); - connection = valerie_init( parser ); - if ( valerie_connect( connection ) == valerie_ok ) - { - mlt_properties_set_data( properties, "connection", connection, 0, ( mlt_destructor )valerie_close, NULL ); - mlt_properties_set_data( properties, "parser", parser, 0, ( mlt_destructor )valerie_parser_close, NULL ); - } - else - { - fprintf( stderr, "Unable to connect to the server at %s:%d\n", server, port ); - mlt_properties_set_int( properties, "_error", 1 ); - valerie_close( connection ); - valerie_parser_close( parser ); - connection = NULL; - } - } - - // If we have connection, push the service over - if ( connection != NULL ) - { - if ( doc == NULL ) - { - int error; - - // Push the service - error = valerie_unit_push( connection, unit, command, service ); - - // Report error - if ( error != valerie_ok ) - fprintf( stderr, "Push failed on %s:%d %s u%d (%d)\n", server, port, command, unit, error ); - } - else - { - // Push the service - int error = valerie_unit_receive( connection, unit, command, doc ); - - // Report error - if ( error != valerie_ok ) - fprintf( stderr, "Send failed on %s:%d %s u%d (%d)\n", server, port, command, unit, error ); - } - } - } - - mlt_consumer_stop( this ); - mlt_consumer_stopped( this ); - - return 0; -} - -static int consumer_is_stopped( mlt_consumer this ) -{ - return 1; -} diff --git a/src/modules/valerie/factory.c b/src/modules/valerie/factory.c deleted file mode 100644 index 6dcae27..0000000 --- a/src/modules/valerie/factory.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -extern mlt_consumer consumer_valerie_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( consumer_type, "valerie", consumer_valerie_init ); -} diff --git a/src/modules/vmfx/Makefile b/src/modules/vmfx/Makefile deleted file mode 100644 index d18f568..0000000 --- a/src/modules/vmfx/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltvmfx$(LIBSUF) - -OBJS = factory.o \ - filter_chroma.o \ - filter_chroma_hold.o \ - filter_mono.o \ - filter_shape.o \ - producer_pgm.o - -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/vmfx/factory.c b/src/modules/vmfx/factory.c deleted file mode 100644 index 3477bb8..0000000 --- a/src/modules/vmfx/factory.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2005 Visual Media Fx Inc. - * Author: Charles Yates - * - * 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 2 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, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -extern mlt_filter filter_chroma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_chroma_hold_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_mono_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_shape_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_pgm_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "chroma", filter_chroma_init ); - MLT_REGISTER( filter_type, "chroma_hold", filter_chroma_hold_init ); - MLT_REGISTER( filter_type, "threshold", filter_mono_init ); - MLT_REGISTER( filter_type, "shape", filter_shape_init ); - MLT_REGISTER( producer_type, "pgm", producer_pgm_init ); -} diff --git a/src/modules/vmfx/filter_chroma.c b/src/modules/vmfx/filter_chroma.c deleted file mode 100644 index f13838b..0000000 --- a/src/modules/vmfx/filter_chroma.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * filter_chroma.c -- Maps a chroma key to the alpha channel - * Copyright (C) 2005 Visual Media Fx Inc. - * Author: Charles Yates - * - * 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 2 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, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -static inline int in_range( uint8_t v, uint8_t c, int var ) -{ - return ( ( int )v >= c - var ) && ( ( int )v <= c + var ); -} - -static inline uint8_t alpha_value( uint8_t a, uint8_t *p, uint8_t u, uint8_t v, int var, int odd ) -{ - if ( odd == 0 ) - return ( in_range( *( p + 1 ), u, var ) && in_range( *( p + 3 ), v, var ) ) ? 0 : a; - else - return ( in_range( ( *( p + 1 ) + *( p + 5 ) ) / 2, u, var ) && in_range( ( *( p + 3 ) + *( p + 7 ) ) / 2, v, var ) ) ? 0 : a; -} - -/** Get the images and map the chroma to the alpha of the frame. -*/ - -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_filter this = mlt_frame_pop_service( frame ); - int variance = 200 * mlt_properties_get_double( MLT_FILTER_PROPERTIES( this ), "variance" ); - int32_t key_val = mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "key" ); - uint8_t r = ( key_val >> 24 ) & 0xff; - uint8_t g = ( key_val >> 16 ) & 0xff; - uint8_t b = ( key_val >> 8 ) & 0xff; - uint8_t y, u, v; - - RGB2YUV( r, g, b, y, u, v ); - - if ( mlt_frame_get_image( frame, image, format, width, height, writable ) == 0 ) - { - uint8_t *alpha = mlt_frame_get_alpha_mask( frame ); - uint8_t *p = *image; - int size = *width * *height / 2; - while ( size -- ) - { - *alpha = alpha_value( *alpha, p, u, v, variance, 0 ); - alpha ++; - *alpha = alpha_value( *alpha, p, u, v, variance, 1 ); - alpha ++; - p += 4; - } - } - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - mlt_frame_push_service( frame, this ); - mlt_frame_push_service( frame, filter_get_image ); - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_chroma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "key", arg == NULL ? "0x0000ff00" : arg ); - mlt_properties_set_double( MLT_FILTER_PROPERTIES( this ), "variance", 0.15 ); - this->process = filter_process; - } - return this; -} - diff --git a/src/modules/vmfx/filter_chroma_hold.c b/src/modules/vmfx/filter_chroma_hold.c deleted file mode 100644 index 07ca4a8..0000000 --- a/src/modules/vmfx/filter_chroma_hold.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * filter_chroma.c -- Maps a chroma key to the alpha channel - * Copyright (C) 2005 Visual Media Fx Inc. - * Author: Charles Yates - * - * 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 2 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, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include - -static inline int in_range( uint8_t v, uint8_t c, int var ) -{ - return ( ( int )v >= c - var ) && ( ( int )v <= c + var ); -} - -static inline uint8_t alpha_value( uint8_t a, uint8_t *p, uint8_t u, uint8_t v, int var, int odd ) -{ - if ( odd == 0 ) - return ( in_range( *( p + 1 ), u, var ) && in_range( *( p + 3 ), v, var ) ) ? 0 : a; - else - return ( in_range( ( *( p + 1 ) + *( p + 5 ) ) / 2, u, var ) && in_range( ( *( p + 3 ) + *( p + 7 ) ) / 2, v, var ) ) ? 0 : a; -} - -/** Get the images and map the chroma to the alpha of the frame. -*/ - -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_filter this = mlt_frame_pop_service( frame ); - int variance = 200 * mlt_properties_get_double( MLT_FILTER_PROPERTIES( this ), "variance" ); - int32_t key_val = mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "key" ); - uint8_t r = ( key_val >> 24 ) & 0xff; - uint8_t g = ( key_val >> 16 ) & 0xff; - uint8_t b = ( key_val >> 8 ) & 0xff; - uint8_t y, u, v; - - RGB2YUV( r, g, b, y, u, v ); - - if ( mlt_frame_get_image( frame, image, format, width, height, writable ) == 0 ) - { - uint8_t alpha = 0; - uint8_t *p = *image; - int size = *width * *height / 2; - while ( size -- ) - { - alpha = alpha_value( 255, p, u, v, variance, 0 ); - if ( alpha ) - *( p + 1 )= 128; - alpha = alpha_value( 255, p, u, v, variance, 1 ); - if ( alpha ) - *( p + 3 ) = 128; - p += 4; - } - } - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - mlt_frame_push_service( frame, this ); - mlt_frame_push_service( frame, filter_get_image ); - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_chroma_hold_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "key", arg == NULL ? "0xc0000000" : arg ); - mlt_properties_set_double( MLT_FILTER_PROPERTIES( this ), "variance", 0.15 ); - this->process = filter_process; - } - return this; -} - diff --git a/src/modules/vmfx/filter_mono.c b/src/modules/vmfx/filter_mono.c deleted file mode 100644 index f7ea11d..0000000 --- a/src/modules/vmfx/filter_mono.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * filter_mono.c -- Arbitrary alpha channel shaping - * Copyright (C) 2005 Visual Media Fx Inc. - * Author: Charles Yates - * - * 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 2 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, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include - -/** Get the images and apply the luminance of the mask to the alpha of the frame. -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - int use_alpha = mlt_deque_pop_back_int( MLT_FRAME_IMAGE_STACK( this ) ); - int midpoint = mlt_deque_pop_back_int( MLT_FRAME_IMAGE_STACK( this ) ); - int invert = mlt_deque_pop_back_int( MLT_FRAME_IMAGE_STACK( this ) ); - - // Render the frame - if ( mlt_frame_get_image( this, image, format, width, height, writable ) == 0 ) - { - uint8_t *p = *image; - uint8_t A = invert? 235 : 16; - uint8_t B = invert? 16 : 235; - int size = *width * *height; - - if ( !use_alpha ) - { - while( size -- ) - { - if ( *p < midpoint ) - *p ++ = A; - else - *p ++ = B; - *p ++ = 128; - } - } - else - { - uint8_t *alpha = mlt_frame_get_alpha_mask( this ); - while( size -- ) - { - if ( *alpha ++ < midpoint ) - *p ++ = A; - else - *p ++ = B; - *p ++ = 128; - } - } - } - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - int midpoint = mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "midpoint" ); - int use_alpha = mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "use_alpha" ); - int invert = mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "invert" ); - mlt_deque_push_back_int( MLT_FRAME_IMAGE_STACK( frame ), invert ); - mlt_deque_push_back_int( MLT_FRAME_IMAGE_STACK( frame ), midpoint ); - mlt_deque_push_back_int( MLT_FRAME_IMAGE_STACK( frame ), use_alpha ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_mono_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "midpoint", 128 ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "use_alpha", 0 ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "invert", 0 ); - this->process = filter_process; - } - return this; -} - diff --git a/src/modules/vmfx/filter_shape.c b/src/modules/vmfx/filter_shape.c deleted file mode 100644 index fdd33e4..0000000 --- a/src/modules/vmfx/filter_shape.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * filter_shape.c -- Arbitrary alpha channel shaping - * Copyright (C) 2005 Visual Media Fx Inc. - * Author: Charles Yates - * - * 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 2 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, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include - -inline double smoothstep( const double e1, const double e2, const double a ) -{ - if ( a < e1 ) return 0.0; - if ( a > e2 ) return 1.0; - double v = ( a - e1 ) / ( e2 - e1 ); - return ( v * v * ( 3 - 2 * v ) ); -} - -/** Get the images and apply the luminance of the mask to the alpha of the frame. -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Fetch the data from the stack (mix, mask, filter) - double mix = mlt_deque_pop_back_double( MLT_FRAME_IMAGE_STACK( this ) ); - mlt_frame mask = mlt_frame_pop_service( this ); - mlt_filter filter = mlt_frame_pop_service( this ); - - // Obtain the constants - double softness = mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "softness" ); - int use_luminance = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "use_luminance" ); - int invert = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "invert" ) * 255; - - // Render the frame - if ( mlt_frame_get_image( this, image, format, width, height, writable ) == 0 && ( !use_luminance || ( int )mix != 1 ) ) - { - // Get the alpha mask of the source - uint8_t *alpha = mlt_frame_get_alpha_mask( this ); - - // Obtain a scaled/distorted mask to match - uint8_t *mask_img = NULL; - mlt_image_format mask_fmt = mlt_image_yuv422; - mlt_properties_set_int( MLT_FRAME_PROPERTIES( mask ), "distort", 1 ); - mlt_properties_pass_list( MLT_FRAME_PROPERTIES( mask ), MLT_FRAME_PROPERTIES( this ), "deinterlace,deinterlace_method,rescale.interp" ); - - if ( mlt_frame_get_image( mask, &mask_img, &mask_fmt, width, height, 0 ) == 0 ) - { - int size = *width * *height; - uint8_t *p = alpha; - double a = 0; - double b = 0; - if ( !use_luminance ) - { - uint8_t *q = mlt_frame_get_alpha_mask( mask ); - while( size -- ) - { - a = ( double )*q ++ / 255.0; - b = 1.0 - smoothstep( a, a + softness, mix ); - *p = ( uint8_t )( *p * b ) ^ invert; - p ++; - } - } - else if ( ( int )mix != 1 ) - { - uint8_t *q = mask_img; - // Ensure softness tends to zero has mix tends to 1 - softness *= ( 1.0 - mix ); - while( size -- ) - { - a = ( ( double )*q - 16 ) / 235.0; - b = smoothstep( a, a + softness, mix ); - *p = ( uint8_t )( *p * b ) ^ invert; - p ++; - q += 2; - } - } - } - } - - return 0; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Obtain the shape instance - char *resource = mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "resource" ); - char *last_resource = mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "_resource" ); - mlt_producer producer = mlt_properties_get_data( MLT_FILTER_PROPERTIES( this ), "instance", NULL ); - - // Get the key framed values - mlt_geometry alpha = mlt_properties_get_data( MLT_FILTER_PROPERTIES( this ), "_alpha", NULL ); - char *alpha_data = mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "mix" ); - double alpha_mix = 0.0; - - // Calculate the position and length - int position = mlt_frame_get_position( frame ) - mlt_filter_get_in( this ); - int in = mlt_filter_get_in( this ); - int out = mlt_filter_get_out( this ); - int length; - - // Special case for attached filters - in/out come through on the frame - if ( out == 0 ) - { - in = mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "in" ); - out = mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "out" ); - position -= in; - } - - // Duration of the shape - length = out - in + 1; - - // If we haven't created the instance or it's changed - if ( producer == NULL || strcmp( resource, last_resource ) ) - { - char temp[ 512 ]; - char *extension = strrchr( resource, '.' ); - - // Store the last resource now - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "_resource", resource ); - - // This is a hack - the idea is that we can indirectly reference the - // luma modules pgm or png images by a short cut like %luma01.pgm - we then replace - // the % with the full path to the image and use it if it exists, if not, check for - // the file ending in a .png, and failing that, default to a fade in - if ( strchr( resource, '%' ) ) - { - FILE *test; - sprintf( temp, "%s/lumas/%s/%s", mlt_environment( "MLT_DATA" ), mlt_environment( "MLT_NORMALISATION" ), strchr( resource, '%' ) + 1 ); - test = fopen( temp, "r" ); - - if ( test == NULL ) - { - strcat( temp, ".png" ); - test = fopen( temp, "r" ); - } - - if ( test ) - fclose( test ); - else - strcpy( temp, "colour:0x00000080" ); - - resource = temp; - extension = strrchr( resource, '.' ); - } - - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) ); - producer = mlt_factory_producer( profile, NULL, resource ); - if ( producer != NULL ) - mlt_properties_set( MLT_PRODUCER_PROPERTIES( producer ), "eof", "loop" ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), "instance", producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); - } - - // Construct the geometry item if needed, otherwise refresh it - if ( alpha == NULL ) - { - alpha = mlt_geometry_init( ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), "_alpha", alpha, 0, ( mlt_destructor )mlt_geometry_close, NULL ); - mlt_geometry_parse( alpha, alpha_data, length, 100, 100 ); - } - else - { - mlt_geometry_refresh( alpha, alpha_data, length, 100, 100 ); - } - - // We may still not have a producer in which case, we do nothing - if ( producer != NULL ) - { - mlt_frame mask = NULL; - struct mlt_geometry_item_s item; - mlt_geometry_fetch( alpha, &item, position ); - alpha_mix = item.x; - mlt_properties_pass( MLT_PRODUCER_PROPERTIES( producer ), MLT_FILTER_PROPERTIES( this ), "producer." ); - mlt_producer_seek( producer, position ); - if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &mask, 0 ) == 0 ) - { - char *name = mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "_unique_id" ); - mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), name, mask, 0, ( mlt_destructor )mlt_frame_close, NULL ); - mlt_frame_push_service( frame, this ); - mlt_frame_push_service( frame, mask ); - mlt_deque_push_back_double( MLT_FRAME_IMAGE_STACK( frame ), alpha_mix / 100.0 ); - mlt_frame_push_get_image( frame, filter_get_image ); - if ( mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "audio_match" ) ) - { - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "meta.mixdown", 1 ); - mlt_properties_set_double( MLT_FRAME_PROPERTIES( frame ), "meta.volume", alpha_mix / 100.0 ); - } - } - } - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_shape_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "resource", arg ); - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "mix", "100" ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "audio_match", 1 ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "invert", 0 ); - mlt_properties_set_double( MLT_FILTER_PROPERTIES( this ), "softness", 0.1 ); - this->process = filter_process; - } - return this; -} - diff --git a/src/modules/vmfx/producer_pgm.c b/src/modules/vmfx/producer_pgm.c deleted file mode 100644 index 6713317..0000000 --- a/src/modules/vmfx/producer_pgm.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * producer_pgm.c -- PGM producer - * Copyright (C) 2005 Visual Media Fx Inc. - * Author: Charles Yates - * - * 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 2 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, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include - -static int read_pgm( char *name, uint8_t **image, int *width, int *height, int *maxval ); -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer parent ); - -mlt_producer producer_pgm_init( mlt_profile profile, mlt_service_type type, const char *id, char *resource ) -{ - mlt_producer this = NULL; - uint8_t *image = NULL; - int width = 0; - int height = 0; - int maxval = 0; - - if ( read_pgm( resource, &image, &width, &height, &maxval ) == 0 ) - { - this = calloc( 1, sizeof( struct mlt_producer_s ) ); - if ( this != NULL && mlt_producer_init( this, NULL ) == 0 ) - { - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - this->get_frame = producer_get_frame; - this->close = ( mlt_destructor )producer_close; - mlt_properties_set( properties, "resource", resource ); - mlt_properties_set_data( properties, "image", image, 0, mlt_pool_release, NULL ); - mlt_properties_set_int( properties, "real_width", width ); - mlt_properties_set_int( properties, "real_height", height ); - } - else - { - mlt_pool_release( image ); - free( this ); - this = NULL; - } - } - - return this; -} - -/** Load the PGM file. -*/ - -static int read_pgm( char *name, uint8_t **image, int *width, int *height, int *maxval ) -{ - uint8_t *input = NULL; - int error = 0; - FILE *f = fopen( name, "r" ); - char data[ 512 ]; - - // Initialise - *image = NULL; - *width = 0; - *height = 0; - *maxval = 0; - - // Get the magic code - if ( f != NULL && fgets( data, 511, f ) != NULL && data[ 0 ] == 'P' && data[ 1 ] == '5' ) - { - char *p = data + 2; - int i = 0; - int val = 0; - - // PGM Header parser (probably needs to be strengthened) - for ( i = 0; !error && i < 3; i ++ ) - { - if ( *p != '\0' && *p != '\n' ) - val = strtol( p, &p, 10 ); - else - p = NULL; - - while ( error == 0 && p == NULL ) - { - if ( fgets( data, 511, f ) == NULL ) - error = 1; - else if ( data[ 0 ] != '#' ) - val = strtol( data, &p, 10 ); - } - - switch( i ) - { - case 0: *width = val; break; - case 1: *height = val; break; - case 2: *maxval = val; break; - } - } - - if ( !error ) - { - // Determine if this is one or two bytes per pixel - int bpp = *maxval > 255 ? 2 : 1; - int size = *width * *height * bpp; - uint8_t *p; - - // Allocate temporary storage for the data and the image - input = mlt_pool_alloc( *width * *height * bpp ); - *image = mlt_pool_alloc( *width * *height * sizeof( uint8_t ) * 2 ); - p = *image; - - error = *image == NULL || input == NULL; - - if ( !error ) - { - // Read the raw data - error = fread( input, *width * *height * bpp, 1, f ) != 1; - - if ( !error ) - { - // Convert to yuv422 (very lossy - need to extend this to allow 16 bit alpha out) - for ( i = 0; i < size; i += bpp ) - { - *p ++ = 16 + ( input[ i ] * 219 ) / 255; - *p ++ = 128; - } - } - } - } - - if ( error ) - mlt_pool_release( *image ); - mlt_pool_release( input ); - } - else - { - error = 1; - } - - if ( f != NULL ) - fclose( f ); - - return error; -} - -static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_producer producer = mlt_frame_pop_service( this ); - int real_width = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "real_width" ); - int real_height = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "real_height" ); - int size = real_width * real_height; - uint8_t *image = mlt_pool_alloc( size * 2 ); - uint8_t *source = mlt_properties_get_data( MLT_PRODUCER_PROPERTIES( producer ), "image", NULL ); - - mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "image", image, size * 2, mlt_pool_release, NULL ); - - *width = real_width; - *height = real_height; - *format = mlt_image_yuv422; - *buffer = image; - - if ( image != NULL && source != NULL ) - memcpy( image, source, size * 2 ); - - return 0; -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Construct a test frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Pass the data on the frame properties - mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( producer ), "real_width,real_height" ); - mlt_properties_set_int( properties, "has_image", 1 ); - mlt_properties_set_int( properties, "progressive", 1 ); - mlt_properties_set_double( properties, "aspect_ratio", 1 ); - - // Push the image callback - mlt_frame_push_service( *frame, producer ); - mlt_frame_push_get_image( *frame, producer_get_image ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer parent ) -{ - parent->close = NULL; - mlt_producer_close( parent ); - free( parent ); -} diff --git a/src/modules/vorbis/Makefile b/src/modules/vorbis/Makefile deleted file mode 100644 index f159a2a..0000000 --- a/src/modules/vorbis/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltvorbis$(LIBSUF) - -OBJS = factory.o \ - producer_vorbis.o - -CFLAGS += -I../.. -CFLAGS += `pkg-config --cflags vorbis` -CFLAGS += `pkg-config --cflags vorbisfile` - -LDFLAGS += -L../../framework -lmlt -LDFLAGS += `pkg-config --libs vorbis` -LDFLAGS += `pkg-config --libs vorbisfile` - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/vorbis/configure b/src/modules/vorbis/configure deleted file mode 100755 index 2f8c117..0000000 --- a/src/modules/vorbis/configure +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - - pkg-config vorbisfile 2> /dev/null - disable_vorbis=$? - - if [ "$disable_vorbis" != "0" ] - then - echo "- ogg vorbis not found: disabling" - touch ../disable-vorbis - fi - exit 0 -fi - diff --git a/src/modules/vorbis/factory.c b/src/modules/vorbis/factory.c deleted file mode 100644 index 3df2e75..0000000 --- a/src/modules/vorbis/factory.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -extern mlt_producer producer_vorbis_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( producer_type, "vorbis", producer_vorbis_init ); -} diff --git a/src/modules/vorbis/producer_vorbis.c b/src/modules/vorbis/producer_vorbis.c deleted file mode 100644 index 1c1e7ce..0000000 --- a/src/modules/vorbis/producer_vorbis.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * producer_vorbis.c -- vorbis producer - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// MLT Header files -#include -#include -#include - -// vorbis Header files -#include -#include - -// System header files -#include -#include -#include - -// Forward references. -static int producer_open( mlt_producer this, mlt_profile profile, char *file ); -static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ); - -/** Structure for metadata reading -*/ - -typedef struct _sw_metadata sw_metadata; - -struct _sw_metadata { - char * name; - char * content; -}; - -static sw_metadata *vorbis_metadata_from_str (char * str) -{ - sw_metadata * meta = NULL; - int i; - - for (i = 0; str[i]; i++) { - str[i] = tolower(str[i]); - if (str[i] == '=') { - str[i] = '\0'; - meta = malloc (sizeof (sw_metadata)); - meta->name = malloc( strlen(str) + 18 ); - sprintf(meta->name, "meta.attr.%s.markup", str); - meta->content = strdup (&str[i+1]); - break; - } - } - return meta; -} - -/** Constructor for libvorbis. -*/ - -mlt_producer producer_vorbis_init( mlt_profile profile, mlt_service_type type, const char *id, char *file ) -{ - mlt_producer this = NULL; - - // Check that we have a non-NULL argument - if ( file != NULL ) - { - // Construct the producer - this = calloc( 1, sizeof( struct mlt_producer_s ) ); - - // Initialise it - if ( mlt_producer_init( this, NULL ) == 0 ) - { - // Get the properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Set the resource property (required for all producers) - mlt_properties_set( properties, "resource", file ); - - // Register our get_frame implementation - this->get_frame = producer_get_frame; - - // Open the file - if ( producer_open( this, profile, file ) != 0 ) - { - // Clean up - mlt_producer_close( this ); - this = NULL; - } - } - } - - return this; -} - -/** Destuctor for ogg files. -*/ - -static void producer_file_close( void *file ) -{ - if ( file != NULL ) - { - // Close the ogg vorbis structure - ov_clear( file ); - - // Free the memory - free( file ); - } -} - -/** Open the file. -*/ - -static int producer_open( mlt_producer this, mlt_profile profile, char *file ) -{ - // FILE pointer for file - FILE *input = fopen( file, "r" ); - - // Error code to return - int error = input == NULL; - - // Continue if file is open - if ( error == 0 ) - { - // OggVorbis file structure - OggVorbis_File *ov = calloc( 1, sizeof( OggVorbis_File ) ); - - // Attempt to open the stream - error = ov == NULL || ov_open( input, ov, NULL, 0 ) != 0; - - // Assign to producer properties if successful - if ( error == 0 ) - { - // Get the properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Assign the ov structure - mlt_properties_set_data( properties, "ogg_vorbis_file", ov, 0, producer_file_close, NULL ); - - // Read metadata - sw_metadata * metadata = NULL; - char **ptr = ov_comment(ov, -1)->user_comments; - while(*ptr) { - metadata = vorbis_metadata_from_str (*ptr); - if (metadata != NULL) - mlt_properties_set(properties, metadata->name, metadata->content); - ++ptr; - } - - if ( ov_seekable( ov ) ) - { - // Get the length of the file - double length = ov_time_total( ov, -1 ); - - // We will treat everything with the producer fps - double fps = mlt_profile_fps( profile ); - - // Set out and length of file - mlt_properties_set_position( properties, "out", ( length * fps ) - 1 ); - mlt_properties_set_position( properties, "length", ( length * fps ) ); - - // Get the vorbis info - vorbis_info *vi = ov_info( ov, -1 ); - mlt_properties_set_int( properties, "frequency", (int) vi->rate ); - mlt_properties_set_int( properties, "channels", vi->channels ); - - // Set some media metadata - mlt_properties_set_int( properties, "meta.media.nb_streams", 1 ); - mlt_properties_set_int( properties, "audio_index", 0 ); - mlt_properties_set( properties, "meta.media.0.stream.type", "audio" ); - mlt_properties_set( properties, "meta.media.0.codec.name", "vorbis" ); - mlt_properties_set( properties, "meta.media.0.codec.long_name", "Vorbis" ); - } - } - else - { - // Clean up - free( ov ); - - // Must close input file when open fails - fclose( input ); - } - } - - return error; -} - -/** Convert a frame position to a time code. -*/ - -static double producer_time_of_frame( mlt_producer this, mlt_position position ) -{ - return ( double )position / mlt_producer_get_fps( this ); -} - -/** Get the audio from a frame. -*/ - -static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - // Get the properties from the frame - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the frame number of this frame - mlt_position position = mlt_properties_get_position( frame_properties, "vorbis_position" ); - - // Get the producer - mlt_producer this = mlt_frame_pop_audio( frame ); - - // Get the producer properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // Get the ogg vorbis file - OggVorbis_File *ov = mlt_properties_get_data( properties, "ogg_vorbis_file", NULL ); - - // Obtain the expected frame numer - mlt_position expected = mlt_properties_get_position( properties, "audio_expected" ); - - // Get the fps for this producer - double fps = mlt_producer_get_fps( this ); - - // Get the vorbis info - vorbis_info *vi = ov_info( ov, -1 ); - - // Obtain the audio buffer - int16_t *audio_buffer = mlt_properties_get_data( properties, "audio_buffer", NULL ); - - // Get amount of audio used - int audio_used = mlt_properties_get_int( properties, "audio_used" ); - - // Number of frames to ignore (for ffwd) - int ignore = 0; - - // Flag for paused (silence) - int paused = 0; - - // Check for audio buffer and create if necessary - if ( audio_buffer == NULL ) - { - // Allocate the audio buffer - audio_buffer = mlt_pool_alloc( 131072 * sizeof( int16_t ) ); - - // And store it on properties for reuse - mlt_properties_set_data( properties, "audio_buffer", audio_buffer, 0, mlt_pool_release, NULL ); - } - - // Seek if necessary - if ( position != expected ) - { - if ( position + 1 == expected ) - { - // We're paused - silence required - paused = 1; - } - else if ( position > expected && ( position - expected ) < 250 ) - { - // Fast forward - seeking is inefficient for small distances - just ignore following frames - ignore = position - expected; - } - else - { - // Seek to the required position - ov_time_seek( ov, producer_time_of_frame( this, position ) ); - expected = position; - audio_used = 0; - } - } - - // Return info in frame - *frequency = vi->rate; - *channels = vi->channels; - - // Get the audio if required - if ( !paused ) - { - // Bitstream section - int current_section; - - // Get the number of samples for the current frame - *samples = mlt_sample_calculator( fps, *frequency, expected ++ ); - - while( *samples > audio_used ) - { - // Read the samples - int bytes = ov_read( ov, ( char * )( &audio_buffer[ audio_used * 2 ] ), 4096, 0, 2, 1, ¤t_section ); - - // Break if error or eof - if ( bytes <= 0 ) - break; - - // Increment number of samples used - audio_used += bytes / ( sizeof( int16_t ) * *channels ); - - // Handle ignore - while ( ignore && audio_used >= *samples ) - { - ignore --; - audio_used -= *samples; - memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * sizeof( int16_t ) ); - *samples = mlt_sample_calculator( fps, *frequency, expected ++ ); - } - } - - // Now handle the audio if we have enough - if ( audio_used >= *samples ) - { - *buffer = mlt_pool_alloc( *samples * *channels * sizeof( int16_t ) ); - memcpy( *buffer, audio_buffer, *samples * *channels * sizeof( int16_t ) ); - audio_used -= *samples; - memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * *channels * sizeof( int16_t ) ); - mlt_properties_set_data( frame_properties, "audio", *buffer, 0, mlt_pool_release, NULL ); - } - else - { - mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); - audio_used = 0; - } - - // Store the number of audio samples still available - mlt_properties_set_int( properties, "audio_used", audio_used ); - } - else - { - // Get silence and don't touch the context - *samples = mlt_sample_calculator( fps, *frequency, position ); - mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); - } - - // Regardless of speed, we expect to get the next frame (cos we ain't too bright) - mlt_properties_set_position( properties, "audio_expected", position + 1 ); - - return 0; -} - -/** Our get frame implementation. -*/ - -static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ) -{ - // Create an empty frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( this ) ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( this ) ); - - // Set the position of this producer - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( *frame ); - mlt_properties_set_position( frame_properties, "vorbis_position", mlt_producer_frame( this ) ); - - // Set up the audio - mlt_frame_push_audio( *frame, this ); - mlt_frame_push_audio( *frame, producer_get_audio ); - - // Pass audio properties to the frame - mlt_properties_pass_list( frame_properties, MLT_PRODUCER_PROPERTIES( this ), "frequency, channels" ); - - // Calculate the next timecode - mlt_producer_prepare_next( this ); - - return 0; -} diff --git a/src/modules/westley/Makefile b/src/modules/westley/Makefile deleted file mode 100644 index 2ab4ed8..0000000 --- a/src/modules/westley/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltwestley$(LIBSUF) - -OBJS = factory.o \ - consumer_westley.o \ - producer_westley.o - -CFLAGS += -I../.. -CFLAGS += `xml2-config --cflags` - -LDFLAGS += -L../../framework -lmlt -LDFLAGS += `xml2-config --libs` - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - install -m 644 westley.dtd "$(DESTDIR)$(prefix)/share/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/westley/configure b/src/modules/westley/configure deleted file mode 100755 index 53aacd2..0000000 --- a/src/modules/westley/configure +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - - which xml2-config > /dev/null 2>&1 - disable_xml2=$? - - if [ "$disable_xml2" != "0" ] - then - echo "- xml2 not found: disabling westley modules" - touch ../disable-westley - fi - exit 0 -fi - diff --git a/src/modules/westley/consumer_westley.c b/src/modules/westley/consumer_westley.c deleted file mode 100644 index 29174be..0000000 --- a/src/modules/westley/consumer_westley.c +++ /dev/null @@ -1,744 +0,0 @@ -/* - * consumer_westley.c -- a libxml2 serialiser of mlt service networks - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#define ID_SIZE 128 - -#define _x (const xmlChar*) -#define _s (const char*) - -// This maintains counters for adding ids to elements -struct serialise_context_s -{ - mlt_properties id_map; - int producer_count; - int multitrack_count; - int playlist_count; - int tractor_count; - int filter_count; - int transition_count; - int pass; - mlt_properties hide_map; - char *root; - char *store; -}; -typedef struct serialise_context_s* serialise_context; - -/** Forward references to static functions. -*/ - -static int consumer_start( mlt_consumer parent ); -static int consumer_is_stopped( mlt_consumer this ); -static void serialise_service( serialise_context context, mlt_service service, xmlNode *node ); - -typedef enum -{ - westley_existing, - westley_producer, - westley_multitrack, - westley_playlist, - westley_tractor, - westley_filter, - westley_transition -} -westley_type; - -/** Create or retrieve an id associated to this service. -*/ - -static char *westley_get_id( serialise_context context, mlt_service service, westley_type type ) -{ - char *id = NULL; - int i = 0; - mlt_properties map = context->id_map; - - // Search the map for the service - for ( i = 0; i < mlt_properties_count( map ); i ++ ) - if ( mlt_properties_get_data_at( map, i, NULL ) == service ) - break; - - // If the service is not in the map, and the type indicates a new id is needed... - if ( i >= mlt_properties_count( map ) && type != westley_existing ) - { - // Attempt to reuse existing id - id = mlt_properties_get( MLT_SERVICE_PROPERTIES( service ), "id" ); - - // If no id, or the id is used in the map (for another service), then - // create a new one. - if ( id == NULL || mlt_properties_get_data( map, id, NULL ) != NULL ) - { - char temp[ ID_SIZE ]; - do - { - switch( type ) - { - case westley_producer: - sprintf( temp, "producer%d", context->producer_count ++ ); - break; - case westley_multitrack: - sprintf( temp, "multitrack%d", context->multitrack_count ++ ); - break; - case westley_playlist: - sprintf( temp, "playlist%d", context->playlist_count ++ ); - break; - case westley_tractor: - sprintf( temp, "tractor%d", context->tractor_count ++ ); - break; - case westley_filter: - sprintf( temp, "filter%d", context->filter_count ++ ); - break; - case westley_transition: - sprintf( temp, "transition%d", context->transition_count ++ ); - break; - case westley_existing: - // Never gets here - break; - } - } - while( mlt_properties_get_data( map, temp, NULL ) != NULL ); - - // Set the data at the generated name - mlt_properties_set_data( map, temp, service, 0, NULL, NULL ); - - // Get the pointer to the name (i is the end of the list) - id = mlt_properties_get_name( map, i ); - } - else - { - // Store the existing id in the map - mlt_properties_set_data( map, id, service, 0, NULL, NULL ); - } - } - else if ( type == westley_existing ) - { - id = mlt_properties_get_name( map, i ); - } - - return id; -} - -/** This is what will be called by the factory - anything can be passed in - via the argument, but keep it simple. -*/ - -mlt_consumer consumer_westley_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create the consumer object - mlt_consumer this = calloc( sizeof( struct mlt_consumer_s ), 1 ); - - // If no malloc'd and consumer init ok - if ( this != NULL && mlt_consumer_init( this, NULL, profile ) == 0 ) - { - // Allow thread to be started/stopped - this->start = consumer_start; - this->is_stopped = consumer_is_stopped; - - mlt_properties_set( MLT_CONSUMER_PROPERTIES( this ), "resource", arg ); - - // Return the consumer produced - return this; - } - - // malloc or consumer init failed - free( this ); - - // Indicate failure - return NULL; -} - -static void serialise_properties( serialise_context context, mlt_properties properties, xmlNode *node ) -{ - int i; - xmlNode *p; - - // Enumerate the properties - for ( i = 0; i < mlt_properties_count( properties ); i++ ) - { - char *name = mlt_properties_get_name( properties, i ); - if ( name != NULL && - name[ 0 ] != '_' && - mlt_properties_get_value( properties, i ) != NULL && - strcmp( name, "westley" ) != 0 && - strcmp( name, "in" ) != 0 && - strcmp( name, "out" ) != 0 && - strcmp( name, "id" ) != 0 && - strcmp( name, "title" ) != 0 && - strcmp( name, "root" ) != 0 && - strcmp( name, "width" ) != 0 && - strcmp( name, "height" ) != 0 ) - { - char *value = mlt_properties_get_value( properties, i ); - if ( strcmp( context->root, "" ) && !strncmp( value, context->root, strlen( context->root ) ) ) - value += strlen( context->root ) + 1; - p = xmlNewTextChild( node, NULL, _x("property"), _x(value) ); - xmlNewProp( p, _x("name"), _x(name) ); - } - } -} - -static void serialise_store_properties( serialise_context context, mlt_properties properties, xmlNode *node, const char *store ) -{ - int i; - xmlNode *p; - - // Enumerate the properties - for ( i = 0; store != NULL && i < mlt_properties_count( properties ); i++ ) - { - char *name = mlt_properties_get_name( properties, i ); - if ( !strncmp( name, store, strlen( store ) ) ) - { - char *value = mlt_properties_get_value( properties, i ); - if ( value != NULL ) - { - if ( strcmp( context->root, "" ) && !strncmp( value, context->root, strlen( context->root ) ) ) - value += strlen( context->root ) + 1; - p = xmlNewTextChild( node, NULL, _x("property"), _x(value) ); - xmlNewProp( p, _x("name"), _x(name) ); - } - } - } -} - -static inline void serialise_service_filters( serialise_context context, mlt_service service, xmlNode *node ) -{ - int i; - xmlNode *p; - mlt_filter filter = NULL; - - // Enumerate the filters - for ( i = 0; ( filter = mlt_producer_filter( MLT_PRODUCER( service ), i ) ) != NULL; i ++ ) - { - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - if ( mlt_properties_get_int( properties, "_fezzik" ) == 0 ) - { - // Get a new id - if already allocated, do nothing - char *id = westley_get_id( context, MLT_FILTER_SERVICE( filter ), westley_filter ); - if ( id != NULL ) - { - int in = mlt_properties_get_position( properties, "in" ); - int out = mlt_properties_get_position( properties, "out" ); - p = xmlNewChild( node, NULL, _x("filter"), NULL ); - xmlNewProp( p, _x("id"), _x(id) ); - if ( mlt_properties_get( properties, "title" ) ) - xmlNewProp( p, _x("title"), _x(mlt_properties_get( properties, "title" )) ); - if ( in != 0 || out != 0 ) - { - char temp[ 20 ]; - sprintf( temp, "%d", in ); - xmlNewProp( p, _x("in"), _x(temp) ); - sprintf( temp, "%d", out ); - xmlNewProp( p, _x("out"), _x(temp) ); - } - serialise_properties( context, properties, p ); - serialise_service_filters( context, MLT_FILTER_SERVICE( filter ), p ); - } - } - } -} - -static void serialise_producer( serialise_context context, mlt_service service, xmlNode *node ) -{ - xmlNode *child = node; - mlt_service parent = MLT_SERVICE( mlt_producer_cut_parent( MLT_PRODUCER( service ) ) ); - - if ( context->pass == 0 ) - { - mlt_properties properties = MLT_SERVICE_PROPERTIES( parent ); - // Get a new id - if already allocated, do nothing - char *id = westley_get_id( context, parent, westley_producer ); - if ( id == NULL ) - return; - - child = xmlNewChild( node, NULL, _x("producer"), NULL ); - - // Set the id - xmlNewProp( child, _x("id"), _x(id) ); - if ( mlt_properties_get( properties, "title" ) ) - xmlNewProp( child, _x("title"), _x(mlt_properties_get( properties, "title" )) ); - xmlNewProp( child, _x("in"), _x(mlt_properties_get( properties, "in" )) ); - xmlNewProp( child, _x("out"), _x(mlt_properties_get( properties, "out" )) ); - serialise_properties( context, properties, child ); - serialise_service_filters( context, service, child ); - - // Add producer to the map - mlt_properties_set_int( context->hide_map, id, mlt_properties_get_int( properties, "hide" ) ); - } - else - { - char *id = westley_get_id( context, parent, westley_existing ); - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - xmlNewProp( node, _x("parent"), _x(id) ); - xmlNewProp( node, _x("in"), _x(mlt_properties_get( properties, "in" )) ); - xmlNewProp( node, _x("out"), _x(mlt_properties_get( properties, "out" )) ); - } -} - -static void serialise_tractor( serialise_context context, mlt_service service, xmlNode *node ); - -static void serialise_multitrack( serialise_context context, mlt_service service, xmlNode *node ) -{ - int i; - - if ( context->pass == 0 ) - { - // Iterate over the tracks to collect the producers - for ( i = 0; i < mlt_multitrack_count( MLT_MULTITRACK( service ) ); i++ ) - { - mlt_producer producer = mlt_producer_cut_parent( mlt_multitrack_track( MLT_MULTITRACK( service ), i ) ); - serialise_service( context, MLT_SERVICE( producer ), node ); - } - } - else - { - // Get a new id - if already allocated, do nothing - char *id = westley_get_id( context, service, westley_multitrack ); - if ( id == NULL ) - return; - - // Serialise the tracks - for ( i = 0; i < mlt_multitrack_count( MLT_MULTITRACK( service ) ); i++ ) - { - xmlNode *track = xmlNewChild( node, NULL, _x("track"), NULL ); - int hide = 0; - mlt_producer producer = mlt_multitrack_track( MLT_MULTITRACK( service ), i ); - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - - mlt_service parent = MLT_SERVICE( mlt_producer_cut_parent( producer ) ); - - char *id = westley_get_id( context, MLT_SERVICE( parent ), westley_existing ); - xmlNewProp( track, _x("producer"), _x(id) ); - if ( mlt_producer_is_cut( producer ) ) - { - xmlNewProp( track, _x("in"), _x(mlt_properties_get( properties, "in" )) ); - xmlNewProp( track, _x("out"), _x(mlt_properties_get( properties, "out" )) ); - serialise_store_properties( context, MLT_PRODUCER_PROPERTIES( producer ), track, context->store ); - serialise_store_properties( context, MLT_PRODUCER_PROPERTIES( producer ), track, "meta." ); - serialise_service_filters( context, MLT_PRODUCER_SERVICE( producer ), track ); - } - - hide = mlt_properties_get_int( context->hide_map, id ); - if ( hide ) - xmlNewProp( track, _x("hide"), _x( hide == 1 ? "video" : ( hide == 2 ? "audio" : "both" ) ) ); - } - serialise_service_filters( context, service, node ); - } -} - -static void serialise_playlist( serialise_context context, mlt_service service, xmlNode *node ) -{ - int i; - xmlNode *child = node; - mlt_playlist_clip_info info; - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - if ( context->pass == 0 ) - { - // Get a new id - if already allocated, do nothing - char *id = westley_get_id( context, service, westley_playlist ); - if ( id == NULL ) - return; - - // Iterate over the playlist entries to collect the producers - for ( i = 0; i < mlt_playlist_count( MLT_PLAYLIST( service ) ); i++ ) - { - if ( ! mlt_playlist_get_clip_info( MLT_PLAYLIST( service ), &info, i ) ) - { - if ( info.producer != NULL ) - { - mlt_producer producer = mlt_producer_cut_parent( info.producer ); - char *service_s = mlt_properties_get( MLT_PRODUCER_PROPERTIES( producer ), "mlt_service" ); - char *resource_s = mlt_properties_get( MLT_PRODUCER_PROPERTIES( producer ), "resource" ); - if ( resource_s != NULL && !strcmp( resource_s, "" ) ) - serialise_playlist( context, MLT_SERVICE( producer ), node ); - else if ( service_s != NULL && strcmp( service_s, "blank" ) != 0 ) - serialise_service( context, MLT_SERVICE( producer ), node ); - } - } - } - - child = xmlNewChild( node, NULL, _x("playlist"), NULL ); - - // Set the id - xmlNewProp( child, _x("id"), _x(id) ); - if ( mlt_properties_get( properties, "title" ) ) - xmlNewProp( child, _x("title"), _x(mlt_properties_get( properties, "title" )) ); - - // Store application specific properties - serialise_store_properties( context, properties, child, context->store ); - serialise_store_properties( context, properties, child, "meta." ); - - // Add producer to the map - mlt_properties_set_int( context->hide_map, id, mlt_properties_get_int( properties, "hide" ) ); - - // Iterate over the playlist entries - for ( i = 0; i < mlt_playlist_count( MLT_PLAYLIST( service ) ); i++ ) - { - if ( ! mlt_playlist_get_clip_info( MLT_PLAYLIST( service ), &info, i ) ) - { - mlt_producer producer = mlt_producer_cut_parent( info.producer ); - char *service_s = mlt_properties_get( MLT_PRODUCER_PROPERTIES( producer ), "mlt_service" ); - if ( service_s != NULL && strcmp( service_s, "blank" ) == 0 ) - { - char length[ 20 ]; - length[ 19 ] = '\0'; - xmlNode *entry = xmlNewChild( child, NULL, _x("blank"), NULL ); - snprintf( length, 19, "%d", (int)info.frame_count ); - xmlNewProp( entry, _x("length"), _x(length) ); - } - else - { - char temp[ 20 ]; - xmlNode *entry = xmlNewChild( child, NULL, _x("entry"), NULL ); - id = westley_get_id( context, MLT_SERVICE( producer ), westley_existing ); - xmlNewProp( entry, _x("producer"), _x(id) ); - sprintf( temp, "%d", (int)info.frame_in ); - xmlNewProp( entry, _x("in"), _x(temp) ); - sprintf( temp, "%d", (int)info.frame_out ); - xmlNewProp( entry, _x("out"), _x(temp) ); - if ( info.repeat > 1 ) - { - sprintf( temp, "%d", info.repeat ); - xmlNewProp( entry, _x("repeat"), _x(temp) ); - } - if ( mlt_producer_is_cut( info.cut ) ) - { - serialise_store_properties( context, MLT_PRODUCER_PROPERTIES( info.cut ), entry, context->store ); - serialise_store_properties( context, MLT_PRODUCER_PROPERTIES( info.cut ), entry, "meta." ); - serialise_service_filters( context, MLT_PRODUCER_SERVICE( info.cut ), entry ); - } - } - } - } - - serialise_service_filters( context, service, child ); - } - else if ( xmlStrcmp( node->name, _x("tractor") ) != 0 ) - { - char *id = westley_get_id( context, service, westley_existing ); - xmlNewProp( node, _x("producer"), _x(id) ); - } -} - -static void serialise_tractor( serialise_context context, mlt_service service, xmlNode *node ) -{ - xmlNode *child = node; - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - if ( context->pass == 0 ) - { - // Recurse on connected producer - serialise_service( context, mlt_service_producer( service ), node ); - } - else - { - // Get a new id - if already allocated, do nothing - char *id = westley_get_id( context, service, westley_tractor ); - if ( id == NULL ) - return; - - child = xmlNewChild( node, NULL, _x("tractor"), NULL ); - - // Set the id - xmlNewProp( child, _x("id"), _x(id) ); - if ( mlt_properties_get( properties, "title" ) ) - xmlNewProp( child, _x("title"), _x(mlt_properties_get( properties, "title" )) ); - if ( mlt_properties_get( properties, "global_feed" ) ) - xmlNewProp( child, _x("global_feed"), _x(mlt_properties_get( properties, "global_feed" )) ); - xmlNewProp( child, _x("in"), _x(mlt_properties_get( properties, "in" )) ); - xmlNewProp( child, _x("out"), _x(mlt_properties_get( properties, "out" )) ); - - // Store application specific properties - serialise_store_properties( context, MLT_SERVICE_PROPERTIES( service ), child, context->store ); - serialise_store_properties( context, MLT_SERVICE_PROPERTIES( service ), child, "meta." ); - - // Recurse on connected producer - serialise_service( context, mlt_service_producer( service ), child ); - serialise_service_filters( context, service, child ); - } -} - -static void serialise_filter( serialise_context context, mlt_service service, xmlNode *node ) -{ - xmlNode *child = node; - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - // Recurse on connected producer - serialise_service( context, mlt_service_producer( service ), node ); - - if ( context->pass == 1 ) - { - // Get a new id - if already allocated, do nothing - char *id = westley_get_id( context, service, westley_filter ); - if ( id == NULL ) - return; - - child = xmlNewChild( node, NULL, _x("filter"), NULL ); - - // Set the id - xmlNewProp( child, _x("id"), _x(id) ); - if ( mlt_properties_get( properties, "title" ) ) - xmlNewProp( child, _x("title"), _x(mlt_properties_get( properties, "title" )) ); - xmlNewProp( child, _x("in"), _x(mlt_properties_get( properties, "in" )) ); - xmlNewProp( child, _x("out"), _x(mlt_properties_get( properties, "out" )) ); - - serialise_properties( context, properties, child ); - serialise_service_filters( context, service, child ); - } -} - -static void serialise_transition( serialise_context context, mlt_service service, xmlNode *node ) -{ - xmlNode *child = node; - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - // Recurse on connected producer - serialise_service( context, MLT_SERVICE( MLT_TRANSITION( service )->producer ), node ); - - if ( context->pass == 1 ) - { - // Get a new id - if already allocated, do nothing - char *id = westley_get_id( context, service, westley_transition ); - if ( id == NULL ) - return; - - child = xmlNewChild( node, NULL, _x("transition"), NULL ); - - // Set the id - xmlNewProp( child, _x("id"), _x(id) ); - if ( mlt_properties_get( properties, "title" ) ) - xmlNewProp( child, _x("title"), _x(mlt_properties_get( properties, "title" )) ); - xmlNewProp( child, _x("in"), _x(mlt_properties_get( properties, "in" )) ); - xmlNewProp( child, _x("out"), _x(mlt_properties_get( properties, "out" )) ); - - serialise_properties( context, properties, child ); - serialise_service_filters( context, service, child ); - } -} - -static void serialise_service( serialise_context context, mlt_service service, xmlNode *node ) -{ - // Iterate over consumer/producer connections - while ( service != NULL ) - { - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - char *mlt_type = mlt_properties_get( properties, "mlt_type" ); - - // Tell about the producer - if ( strcmp( mlt_type, "producer" ) == 0 ) - { - char *mlt_service = mlt_properties_get( properties, "mlt_service" ); - if ( mlt_properties_get( properties, "westley" ) == NULL && ( mlt_service != NULL && !strcmp( mlt_service, "tractor" ) ) ) - { - context->pass = 0; - serialise_tractor( context, service, node ); - context->pass = 1; - serialise_tractor( context, service, node ); - context->pass = 0; - break; - } - else - { - serialise_producer( context, service, node ); - } - if ( mlt_properties_get( properties, "westley" ) != NULL ) - break; - } - - // Tell about the framework container producers - else if ( strcmp( mlt_type, "mlt_producer" ) == 0 ) - { - char *resource = mlt_properties_get( properties, "resource" ); - - // Recurse on multitrack's tracks - if ( strcmp( resource, "" ) == 0 ) - { - serialise_multitrack( context, service, node ); - break; - } - - // Recurse on playlist's clips - else if ( strcmp( resource, "" ) == 0 ) - { - serialise_playlist( context, service, node ); - } - - // Recurse on tractor's producer - else if ( strcmp( resource, "" ) == 0 ) - { - context->pass = 0; - serialise_tractor( context, service, node ); - context->pass = 1; - serialise_tractor( context, service, node ); - context->pass = 0; - break; - } - - // Treat it as a normal producer - else - { - serialise_producer( context, service, node ); - } - } - - // Tell about a filter - else if ( strcmp( mlt_type, "filter" ) == 0 ) - { - serialise_filter( context, service, node ); - break; - } - - // Tell about a transition - else if ( strcmp( mlt_type, "transition" ) == 0 ) - { - serialise_transition( context, service, node ); - break; - } - - // Get the next connected service - service = mlt_service_producer( service ); - } -} - -xmlDocPtr westley_make_doc( mlt_consumer consumer, mlt_service service ) -{ - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - xmlDocPtr doc = xmlNewDoc( _x("1.0") ); - xmlNodePtr root = xmlNewNode( NULL, _x("westley") ); - struct serialise_context_s *context = calloc( 1, sizeof( struct serialise_context_s ) ); - - xmlDocSetRootElement( doc, root ); - - // If we have root, then deal with it now - if ( mlt_properties_get( properties, "root" ) != NULL ) - { - xmlNewProp( root, _x("root"), _x(mlt_properties_get( properties, "root" )) ); - context->root = strdup( mlt_properties_get( properties, "root" ) ); - } - else - { - context->root = strdup( "" ); - } - - // Assign the additional 'storage' pattern for properties - context->store = mlt_properties_get( MLT_CONSUMER_PROPERTIES( consumer ), "store" ); - - // Assign a title property - if ( mlt_properties_get( properties, "title" ) != NULL ) - xmlNewProp( root, _x("title"), _x(mlt_properties_get( properties, "title" )) ); - mlt_properties_set_int( properties, "global_feed", 1 ); - - // Construct the context maps - context->id_map = mlt_properties_new(); - context->hide_map = mlt_properties_new(); - - // Ensure producer is a framework producer - mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), "mlt_type", "mlt_producer" ); - - // In pass one, we serialise the end producers and playlists, - // adding them to a map keyed by address. - serialise_service( context, service, root ); - - // In pass two, we serialise the tractor and reference the - // producers and playlists - context->pass++; - serialise_service( context, service, root ); - - // Cleanup resource - mlt_properties_close( context->id_map ); - mlt_properties_close( context->hide_map ); - free( context->root ); - free( context ); - - return doc; -} - -static int consumer_start( mlt_consumer this ) -{ - xmlDocPtr doc = NULL; - - // Get the producer service - mlt_service service = mlt_service_producer( MLT_CONSUMER_SERVICE( this ) ); - if ( service != NULL ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - char *resource = mlt_properties_get( properties, "resource" ); - - // Set the title if provided - if ( mlt_properties_get( properties, "title" ) ) - mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), "title", mlt_properties_get( properties, "title" ) ); - else if ( mlt_properties_get( MLT_SERVICE_PROPERTIES( service ), "title" ) == NULL ) - mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), "title", "Anonymous Submission" ); - - // Check for a root on the consumer properties and pass to service - if ( mlt_properties_get( properties, "root" ) ) - mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), "root", mlt_properties_get( properties, "root" ) ); - - // Specify roots in other cases... - if ( resource != NULL && mlt_properties_get( properties, "root" ) == NULL ) - { - // Get the current working directory - char *cwd = getcwd( NULL, 0 ); - mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), "root", cwd ); - free( cwd ); - } - - // Make the document - doc = westley_make_doc( this, service ); - - // Handle the output - if ( resource == NULL || !strcmp( resource, "" ) ) - { - xmlDocFormatDump( stdout, doc, 1 ); - } - else if ( strchr( resource, '.' ) == NULL ) - { - xmlChar *buffer = NULL; - int length = 0; - xmlDocDumpMemoryEnc( doc, &buffer, &length, "utf-8" ); - mlt_properties_set( properties, resource, _s(buffer) ); - xmlFree( buffer ); - } - else - { - xmlSaveFormatFileEnc( resource, doc, "utf-8", 1 ); - } - - // Close the document - xmlFreeDoc( doc ); - } - - mlt_consumer_stop( this ); - - mlt_consumer_stopped( this ); - - return 0; -} - -static int consumer_is_stopped( mlt_consumer this ) -{ - return 1; -} diff --git a/src/modules/westley/factory.c b/src/modules/westley/factory.c deleted file mode 100644 index 87853f8..0000000 --- a/src/modules/westley/factory.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -extern mlt_consumer consumer_westley_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_westley_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( consumer_type, "westley", consumer_westley_init ); - MLT_REGISTER( producer_type, "westley", producer_westley_init ); - MLT_REGISTER( producer_type, "westley-xml", producer_westley_init ); -} diff --git a/src/modules/westley/producer_westley.c b/src/modules/westley/producer_westley.c deleted file mode 100644 index 35f7739..0000000 --- a/src/modules/westley/producer_westley.c +++ /dev/null @@ -1,1515 +0,0 @@ -/* - * producer_westley.c -- a libxml2 parser of mlt service networks - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Dan Dennedy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// TODO: destroy unreferenced producers (they are currently destroyed -// when the returned producer is closed). - -#include -#include -#include -#include -#include -#include - -#include -#include // for xmlCreateFileParserCtxt -#include - -#define STACK_SIZE 1000 -#define BRANCH_SIG_LEN 4000 - -#define _x (const xmlChar*) -#define _s (const char*) - -#undef DEBUG -#ifdef DEBUG -extern xmlDocPtr westley_make_doc( mlt_service service ); -#endif - -enum service_type -{ - mlt_invalid_type, - mlt_unknown_type, - mlt_producer_type, - mlt_playlist_type, - mlt_entry_type, - mlt_tractor_type, - mlt_multitrack_type, - mlt_filter_type, - mlt_transition_type, - mlt_consumer_type, - mlt_field_type, - mlt_services_type, - mlt_dummy_filter_type, - mlt_dummy_transition_type, - mlt_dummy_producer_type, -}; - -struct deserialise_context_s -{ - enum service_type stack_types[ STACK_SIZE ]; - mlt_service stack_service[ STACK_SIZE ]; - int stack_service_size; - mlt_properties producer_map; - mlt_properties destructors; - char *property; - int is_value; - xmlDocPtr value_doc; - xmlNodePtr stack_node[ STACK_SIZE ]; - int stack_node_size; - xmlDocPtr entity_doc; - int entity_is_replace; - int depth; - int branch[ STACK_SIZE ]; - const xmlChar *publicId; - const xmlChar *systemId; - mlt_properties params; - mlt_profile profile; -}; -typedef struct deserialise_context_s *deserialise_context; - -/** Convert the numerical current branch address to a dot-delimited string. -*/ -static char *serialise_branch( deserialise_context this, char *s ) -{ - int i; - - s[0] = 0; - for ( i = 0; i < this->depth; i++ ) - { - int len = strlen( s ); - snprintf( s + len, BRANCH_SIG_LEN - len, "%d.", this->branch[ i ] ); - } - return s; -} - -/** Push a service. -*/ - -static int context_push_service( deserialise_context this, mlt_service that, enum service_type type ) -{ - int ret = this->stack_service_size >= STACK_SIZE - 1; - if ( ret == 0 ) - { - this->stack_service[ this->stack_service_size ] = that; - this->stack_types[ this->stack_service_size++ ] = type; - - // Record the tree branch on which this service lives - if ( that != NULL && mlt_properties_get( MLT_SERVICE_PROPERTIES( that ), "_westley_branch" ) == NULL ) - { - char s[ BRANCH_SIG_LEN ]; - mlt_properties_set( MLT_SERVICE_PROPERTIES( that ), "_westley_branch", serialise_branch( this, s ) ); - } - } - return ret; -} - -/** Pop a service. -*/ - -static mlt_service context_pop_service( deserialise_context this, enum service_type *type ) -{ - mlt_service result = NULL; - if ( this->stack_service_size > 0 ) - { - result = this->stack_service[ -- this->stack_service_size ]; - if ( type != NULL ) - *type = this->stack_types[ this->stack_service_size ]; - } - return result; -} - -/** Push a node. -*/ - -static int context_push_node( deserialise_context this, xmlNodePtr node ) -{ - int ret = this->stack_node_size >= STACK_SIZE - 1; - if ( ret == 0 ) - this->stack_node[ this->stack_node_size ++ ] = node; - return ret; -} - -/** Pop a node. -*/ - -static xmlNodePtr context_pop_node( deserialise_context this ) -{ - xmlNodePtr result = NULL; - if ( this->stack_node_size > 0 ) - result = this->stack_node[ -- this->stack_node_size ]; - return result; -} - - -// Set the destructor on a new service -static void track_service( mlt_properties properties, void *service, mlt_destructor destructor ) -{ - int registered = mlt_properties_get_int( properties, "registered" ); - char *key = mlt_properties_get( properties, "registered" ); - mlt_properties_set_data( properties, key, service, 0, destructor, NULL ); - mlt_properties_set_int( properties, "registered", ++ registered ); -} - - -// Prepend the property value with the document root -static inline void qualify_property( deserialise_context context, mlt_properties properties, const char *name ) -{ - char *resource = mlt_properties_get( properties, name ); - if ( resource != NULL && resource[0] ) - { - // Qualify file name properties - char *root = mlt_properties_get( context->producer_map, "root" ); - if ( root != NULL && strcmp( root, "" ) ) - { - char *full_resource = malloc( strlen( root ) + strlen( resource ) + 2 ); - if ( resource[ 0 ] != '/' && strchr( resource, ':' ) == NULL ) - { - strcpy( full_resource, root ); - strcat( full_resource, "/" ); - strcat( full_resource, resource ); - } - else - { - strcpy( full_resource, resource ); - } - mlt_properties_set( properties, name, full_resource ); - free( full_resource ); - } - } -} - - -/** This function adds a producer to a playlist or multitrack when - there is no entry or track element. -*/ - -static int add_producer( deserialise_context context, mlt_service service, mlt_position in, mlt_position out ) -{ - // Return value (0 = service remains top of stack, 1 means it can be removed) - int result = 0; - - // Get the parent producer - enum service_type type = mlt_invalid_type; - mlt_service container = context_pop_service( context, &type ); - int contained = 0; - - if ( service != NULL && container != NULL ) - { - char *container_branch = mlt_properties_get( MLT_SERVICE_PROPERTIES( container ), "_westley_branch" ); - char *service_branch = mlt_properties_get( MLT_SERVICE_PROPERTIES( service ), "_westley_branch" ); - contained = !strncmp( container_branch, service_branch, strlen( container_branch ) ); - } - - if ( contained ) - { - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - char *hide_s = mlt_properties_get( properties, "hide" ); - - // Indicate that this service is no longer top of stack - result = 1; - - switch( type ) - { - case mlt_tractor_type: - { - mlt_multitrack multitrack = mlt_tractor_multitrack( MLT_TRACTOR( container ) ); - mlt_multitrack_connect( multitrack, MLT_PRODUCER( service ), mlt_multitrack_count( multitrack ) ); - } - break; - case mlt_multitrack_type: - { - mlt_multitrack_connect( MLT_MULTITRACK( container ), - MLT_PRODUCER( service ), - mlt_multitrack_count( MLT_MULTITRACK( container ) ) ); - } - break; - case mlt_playlist_type: - { - mlt_playlist_append_io( MLT_PLAYLIST( container ), MLT_PRODUCER( service ), in, out ); - } - break; - default: - result = 0; - fprintf( stderr, "Producer defined inside something that isn't a container\n" ); - break; - }; - - // Set the hide state of the track producer - if ( hide_s != NULL ) - { - if ( strcmp( hide_s, "video" ) == 0 ) - mlt_properties_set_int( properties, "hide", 1 ); - else if ( strcmp( hide_s, "audio" ) == 0 ) - mlt_properties_set_int( properties, "hide", 2 ); - else if ( strcmp( hide_s, "both" ) == 0 ) - mlt_properties_set_int( properties, "hide", 3 ); - } - } - - // Put the parent producer back - if ( container != NULL ) - context_push_service( context, container, type ); - - return result; -} - -/** Attach filters defined on that to this. -*/ - -static void attach_filters( mlt_service this, mlt_service that ) -{ - if ( that != NULL ) - { - int i = 0; - mlt_filter filter = NULL; - for ( i = 0; ( filter = mlt_service_filter( that, i ) ) != NULL; i ++ ) - { - mlt_service_attach( this, filter ); - attach_filters( MLT_FILTER_SERVICE( filter ), MLT_FILTER_SERVICE( filter ) ); - } - } -} - -static void on_start_tractor( deserialise_context context, const xmlChar *name, const xmlChar **atts) -{ - mlt_tractor tractor = mlt_tractor_new( ); - mlt_service service = MLT_TRACTOR_SERVICE( tractor ); - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - track_service( context->destructors, service, (mlt_destructor) mlt_tractor_close ); - - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), (const char*) atts[0], atts[1] == NULL ? "" : (const char*) atts[1] ); - - mlt_properties_set_int( MLT_TRACTOR_PROPERTIES( tractor ), "global_feed", 1 ); - - if ( mlt_properties_get( properties, "id" ) != NULL ) - mlt_properties_set_data( context->producer_map, mlt_properties_get( properties, "id" ), service, 0, NULL, NULL ); - - context_push_service( context, service, mlt_tractor_type ); -} - -static void on_end_tractor( deserialise_context context, const xmlChar *name ) -{ - // Get the tractor - enum service_type type; - mlt_service tractor = context_pop_service( context, &type ); - - if ( tractor != NULL && type == mlt_tractor_type ) - { - // See if the tractor should be added to a playlist or multitrack - if ( add_producer( context, tractor, 0, mlt_producer_get_out( MLT_PRODUCER( tractor ) ) ) == 0 ) - context_push_service( context, tractor, type ); - } - else - { - fprintf( stderr, "Invalid state for tractor\n" ); - } -} - -static void on_start_multitrack( deserialise_context context, const xmlChar *name, const xmlChar **atts) -{ - enum service_type type; - mlt_service parent = context_pop_service( context, &type ); - - // If we don't have a parent, then create one now, providing we're in a state where we can - if ( parent == NULL || ( type == mlt_playlist_type || type == mlt_multitrack_type ) ) - { - mlt_tractor tractor = NULL; - // Push the parent back - if ( parent != NULL ) - context_push_service( context, parent, type ); - - // Create a tractor to contain the multitrack - tractor = mlt_tractor_new( ); - parent = MLT_TRACTOR_SERVICE( tractor ); - track_service( context->destructors, parent, (mlt_destructor) mlt_tractor_close ); - type = mlt_tractor_type; - - // Flag it as a synthesised tractor for clean up later - mlt_properties_set_int( MLT_SERVICE_PROPERTIES( parent ), "fezzik_synth", 1 ); - } - - if ( type == mlt_tractor_type ) - { - mlt_service service = MLT_SERVICE( mlt_tractor_multitrack( MLT_TRACTOR( parent ) ) ); - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - mlt_properties_set( properties, (const char*) atts[0], atts[1] == NULL ? "" : (const char*) atts[1] ); - - if ( mlt_properties_get( properties, "id" ) != NULL ) - mlt_properties_set_data( context->producer_map, mlt_properties_get( properties,"id" ), service, 0, NULL, NULL ); - - context_push_service( context, parent, type ); - context_push_service( context, service, mlt_multitrack_type ); - } - else - { - fprintf( stderr, "Invalid multitrack position\n" ); - } -} - -static void on_end_multitrack( deserialise_context context, const xmlChar *name ) -{ - // Get the multitrack from the stack - enum service_type type; - mlt_service service = context_pop_service( context, &type ); - - if ( service == NULL || type != mlt_multitrack_type ) - fprintf( stderr, "End multitrack in the wrong state...\n" ); -} - -static void on_start_playlist( deserialise_context context, const xmlChar *name, const xmlChar **atts) -{ - mlt_playlist playlist = mlt_playlist_init( ); - mlt_service service = MLT_PLAYLIST_SERVICE( playlist ); - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - track_service( context->destructors, service, (mlt_destructor) mlt_playlist_close ); - - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - { - mlt_properties_set( properties, (const char*) atts[0], atts[1] == NULL ? "" : (const char*) atts[1] ); - - // Out will be overwritten later as we append, so we need to save it - if ( xmlStrcmp( atts[ 0 ], _x("out") ) == 0 ) - mlt_properties_set( properties, "_westley.out", ( const char* )atts[ 1 ] ); - } - - if ( mlt_properties_get( properties, "id" ) != NULL ) - mlt_properties_set_data( context->producer_map, mlt_properties_get( properties, "id" ), service, 0, NULL, NULL ); - - context_push_service( context, service, mlt_playlist_type ); -} - -static void on_end_playlist( deserialise_context context, const xmlChar *name ) -{ - // Get the playlist from the stack - enum service_type type; - mlt_service service = context_pop_service( context, &type ); - - if ( service != NULL && type == mlt_playlist_type ) - { - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - mlt_position in = mlt_properties_get_position( properties, "in" ); - mlt_position out = mlt_properties_get_position( properties, "out" ); - - // See if the playlist should be added to a playlist or multitrack - if ( add_producer( context, service, in, out ) == 0 ) - context_push_service( context, service, type ); - } - else - { - fprintf( stderr, "Invalid state of playlist end\n" ); - } -} - -static void on_start_producer( deserialise_context context, const xmlChar *name, const xmlChar **atts) -{ - // use a dummy service to hold properties to allow arbitrary nesting - mlt_service service = calloc( 1, sizeof( struct mlt_service_s ) ); - mlt_service_init( service, NULL ); - - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - context_push_service( context, service, mlt_dummy_producer_type ); - - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - mlt_properties_set( properties, (const char*) atts[0], atts[1] == NULL ? "" : (const char*) atts[1] ); -} - -// Parse a SMIL clock value (as produced by Kino 0.9.1) and return position in frames -static mlt_position parse_clock_value( char *value, double fps ) -{ - // This implementation expects a fully specified clock value - no optional - // parts (e.g. 1:05) - char *pos, *copy = strdup( value ); - int hh, mm, ss, ms; - mlt_position result = -1; - - value = copy; - pos = strchr( value, ':' ); - if ( !pos ) - return result; - *pos = '\0'; - hh = atoi( value ); - value = pos + 1; - - pos = strchr( value, ':' ); - if ( !pos ) - return result; - *pos = '\0'; - mm = atoi( value ); - value = pos + 1; - - pos = strchr( value, '.' ); - if ( !pos ) - return result; - *pos = '\0'; - ss = atoi( value ); - value = pos + 1; - - ms = atoi( value ); - free( copy ); - result = ( fps * ( ( (hh * 3600) + (mm * 60) + ss ) * 1000 + ms ) / 1000 + 0.5 ); - - return result; -} - -static void on_end_producer( deserialise_context context, const xmlChar *name ) -{ - enum service_type type; - mlt_service service = context_pop_service( context, &type ); - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - if ( service != NULL && type == mlt_dummy_producer_type ) - { - mlt_service producer = NULL; - - qualify_property( context, properties, "resource" ); - char *resource = mlt_properties_get( properties, "resource" ); - - // Let Kino-SMIL src be a synonym for resource - if ( resource == NULL ) - { - qualify_property( context, properties, "src" ); - resource = mlt_properties_get( properties, "src" ); - } - - // Instantiate the producer - if ( mlt_properties_get( properties, "mlt_service" ) != NULL ) - { - char temp[ 1024 ]; - strncpy( temp, mlt_properties_get( properties, "mlt_service" ), 1024 ); - if ( resource != NULL ) - { - strcat( temp, ":" ); - strncat( temp, resource, 1023 - strlen( temp ) ); - } - producer = MLT_SERVICE( mlt_factory_producer( context->profile, "fezzik", temp ) ); - } - - // Just in case the plugin requested doesn't exist... - if ( producer == NULL && resource != NULL ) - producer = MLT_SERVICE( mlt_factory_producer( context->profile, "fezzik", resource ) ); - - if ( producer == NULL ) - producer = MLT_SERVICE( mlt_factory_producer( context->profile, "fezzik", "+INVALID.txt" ) ); - - if ( producer == NULL ) - producer = MLT_SERVICE( mlt_factory_producer( context->profile, "fezzik", "colour:red" ) ); - - // Track this producer - track_service( context->destructors, producer, (mlt_destructor) mlt_producer_close ); - - // Propogate the properties - qualify_property( context, properties, "resource" ); - qualify_property( context, properties, "luma" ); - qualify_property( context, properties, "luma.resource" ); - qualify_property( context, properties, "composite.luma" ); - qualify_property( context, properties, "producer.resource" ); - - // Handle in/out properties separately - mlt_position in = -1; - mlt_position out = -1; - - // Get in - if ( mlt_properties_get( properties, "in" ) != NULL ) - in = mlt_properties_get_position( properties, "in" ); - // Let Kino-SMIL clipBegin be a synonym for in - if ( mlt_properties_get( properties, "clipBegin" ) != NULL ) - { - if ( strchr( mlt_properties_get( properties, "clipBegin" ), ':' ) ) - // Parse clock value - in = parse_clock_value( mlt_properties_get( properties, "clipBegin" ), - mlt_producer_get_fps( MLT_PRODUCER( producer ) ) ); - else - // Parse frames value - in = mlt_properties_get_position( properties, "clipBegin" ); - } - // Get out - if ( mlt_properties_get( properties, "out" ) != NULL ) - out = mlt_properties_get_position( properties, "out" ); - // Let Kino-SMIL clipEnd be a synonym for out - if ( mlt_properties_get( properties, "clipEnd" ) != NULL ) - { - if ( strchr( mlt_properties_get( properties, "clipEnd" ), ':' ) ) - // Parse clock value - out = parse_clock_value( mlt_properties_get( properties, "clipEnd" ), - mlt_producer_get_fps( MLT_PRODUCER( producer ) ) ); - else - // Parse frames value - out = mlt_properties_get_position( properties, "clipEnd" ); - } - // Remove in and out - mlt_properties_set( properties, "in", NULL ); - mlt_properties_set( properties, "out", NULL ); - - // Inherit the properties - mlt_properties_inherit( MLT_SERVICE_PROPERTIES( producer ), properties ); - - // Attach all filters from service onto producer - attach_filters( producer, service ); - - // Add the producer to the producer map - if ( mlt_properties_get( properties, "id" ) != NULL ) - mlt_properties_set_data( context->producer_map, mlt_properties_get(properties, "id"), producer, 0, NULL, NULL ); - - // See if the producer should be added to a playlist or multitrack - if ( add_producer( context, producer, in, out ) == 0 ) - { - // Otherwise, set in and out on... - if ( in != -1 || out != -1 ) - { - // Get the parent service - enum service_type type; - mlt_service parent = context_pop_service( context, &type ); - if ( parent != NULL ) - { - // Get the parent properties - properties = MLT_SERVICE_PROPERTIES( parent ); - - char *resource = mlt_properties_get( properties, "resource" ); - - // Put the parent producer back - context_push_service( context, parent, type ); - - // If the parent is a track or entry - if ( resource && ( strcmp( resource, "" ) == 0 ) ) - { - mlt_properties_set_position( properties, "in", in ); - mlt_properties_set_position( properties, "out", out ); - } - else - { - // Otherwise, set in and out on producer directly - mlt_producer_set_in_and_out( MLT_PRODUCER( producer ), in, out ); - } - } - else - { - // Otherwise, set in and out on producer directly - mlt_producer_set_in_and_out( MLT_PRODUCER( producer ), in, out ); - } - } - - // Push the producer onto the stack - context_push_service( context, producer, mlt_producer_type ); - } - - mlt_service_close( service ); - } -} - -static void on_start_blank( deserialise_context context, const xmlChar *name, const xmlChar **atts) -{ - // Get the playlist from the stack - enum service_type type; - mlt_service service = context_pop_service( context, &type ); - mlt_position length = 0; - - if ( type == mlt_playlist_type && service != NULL ) - { - // Look for the length attribute - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - { - if ( xmlStrcmp( atts[0], _x("length") ) == 0 ) - { - length = atoll( _s(atts[1]) ); - break; - } - } - - // Append a blank to the playlist - mlt_playlist_blank( MLT_PLAYLIST( service ), length - 1 ); - - // Push the playlist back onto the stack - context_push_service( context, service, type ); - } - else - { - fprintf( stderr, "blank without a playlist - a definite no no\n" ); - } -} - -static void on_start_entry( deserialise_context context, const xmlChar *name, const xmlChar **atts) -{ - mlt_producer entry = NULL; - mlt_properties temp = mlt_properties_new( ); - - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - { - mlt_properties_set( temp, (const char*) atts[0], atts[1] == NULL ? "" : (const char*) atts[1] ); - - // Look for the producer attribute - if ( xmlStrcmp( atts[ 0 ], _x("producer") ) == 0 ) - { - mlt_producer producer = mlt_properties_get_data( context->producer_map, (const char*) atts[1], NULL ); - if ( producer != NULL ) - mlt_properties_set_data( temp, "producer", producer, 0, NULL, NULL ); - } - } - - // If we have a valid entry - if ( mlt_properties_get_data( temp, "producer", NULL ) != NULL ) - { - mlt_playlist_clip_info info; - enum service_type parent_type = invalid_type; - mlt_service parent = context_pop_service( context, &parent_type ); - mlt_producer producer = mlt_properties_get_data( temp, "producer", NULL ); - - if ( parent_type == mlt_playlist_type ) - { - // Append the producer to the playlist - if ( mlt_properties_get( temp, "in" ) != NULL || mlt_properties_get( temp, "out" ) != NULL ) - { - mlt_playlist_append_io( MLT_PLAYLIST( parent ), producer, - mlt_properties_get_position( temp, "in" ), - mlt_properties_get_position( temp, "out" ) ); - } - else - { - mlt_playlist_append( MLT_PLAYLIST( parent ), producer ); - } - - // Handle the repeat property - if ( mlt_properties_get_int( temp, "repeat" ) > 0 ) - { - mlt_playlist_repeat_clip( MLT_PLAYLIST( parent ), - mlt_playlist_count( MLT_PLAYLIST( parent ) ) - 1, - mlt_properties_get_int( temp, "repeat" ) ); - } - - mlt_playlist_get_clip_info( MLT_PLAYLIST( parent ), &info, mlt_playlist_count( MLT_PLAYLIST( parent ) ) - 1 ); - entry = info.cut; - } - else - { - fprintf( stderr, "Entry not part of a playlist...\n" ); - } - - context_push_service( context, parent, parent_type ); - } - - // Push the cut onto the stack - context_push_service( context, MLT_PRODUCER_SERVICE( entry ), mlt_entry_type ); - - mlt_properties_close( temp ); -} - -static void on_end_entry( deserialise_context context, const xmlChar *name ) -{ - // Get the entry from the stack - enum service_type entry_type = invalid_type; - mlt_service entry = context_pop_service( context, &entry_type ); - - if ( entry == NULL && entry_type != mlt_entry_type ) - { - fprintf( stderr, "Invalid state at end of entry\n" ); - } -} - -static void on_start_track( deserialise_context context, const xmlChar *name, const xmlChar **atts) -{ - // use a dummy service to hold properties to allow arbitrary nesting - mlt_service service = calloc( 1, sizeof( struct mlt_service_s ) ); - mlt_service_init( service, NULL ); - - // Push the dummy service onto the stack - context_push_service( context, service, mlt_entry_type ); - - mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), "resource", "" ); - - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - { - mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), (const char*) atts[0], atts[1] == NULL ? "" : (const char*) atts[1] ); - - // Look for the producer attribute - if ( xmlStrcmp( atts[ 0 ], _x("producer") ) == 0 ) - { - mlt_producer producer = mlt_properties_get_data( context->producer_map, (const char*) atts[1], NULL ); - if ( producer != NULL ) - mlt_properties_set_data( MLT_SERVICE_PROPERTIES( service ), "producer", producer, 0, NULL, NULL ); - } - } -} - -static void on_end_track( deserialise_context context, const xmlChar *name ) -{ - // Get the track from the stack - enum service_type track_type; - mlt_service track = context_pop_service( context, &track_type ); - - if ( track != NULL && track_type == mlt_entry_type ) - { - mlt_properties track_props = MLT_SERVICE_PROPERTIES( track ); - enum service_type parent_type = invalid_type; - mlt_service parent = context_pop_service( context, &parent_type ); - mlt_multitrack multitrack = NULL; - - mlt_producer producer = mlt_properties_get_data( track_props, "producer", NULL ); - mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); - - if ( parent_type == mlt_tractor_type ) - multitrack = mlt_tractor_multitrack( MLT_TRACTOR( parent ) ); - else if ( parent_type == mlt_multitrack_type ) - multitrack = MLT_MULTITRACK( parent ); - else - fprintf( stderr, "track contained in an invalid container\n" ); - - if ( multitrack != NULL ) - { - // Set producer i/o if specified - if ( mlt_properties_get( track_props, "in" ) != NULL || - mlt_properties_get( track_props, "out" ) != NULL ) - { - mlt_producer cut = mlt_producer_cut( MLT_PRODUCER( producer ), - mlt_properties_get_position( track_props, "in" ), - mlt_properties_get_position( track_props, "out" ) ); - mlt_multitrack_connect( multitrack, cut, mlt_multitrack_count( multitrack ) ); - mlt_properties_inherit( MLT_PRODUCER_PROPERTIES( cut ), track_props ); - track_props = MLT_PRODUCER_PROPERTIES( cut ); - mlt_producer_close( cut ); - } - else - { - mlt_multitrack_connect( multitrack, producer, mlt_multitrack_count( multitrack ) ); - } - - // Set the hide state of the track producer - char *hide_s = mlt_properties_get( track_props, "hide" ); - if ( hide_s != NULL ) - { - if ( strcmp( hide_s, "video" ) == 0 ) - mlt_properties_set_int( producer_props, "hide", 1 ); - else if ( strcmp( hide_s, "audio" ) == 0 ) - mlt_properties_set_int( producer_props, "hide", 2 ); - else if ( strcmp( hide_s, "both" ) == 0 ) - mlt_properties_set_int( producer_props, "hide", 3 ); - } - } - - if ( parent != NULL ) - context_push_service( context, parent, parent_type ); - - mlt_service_close( track ); - } - else - { - fprintf( stderr, "Invalid state at end of track\n" ); - } -} - -static void on_start_filter( deserialise_context context, const xmlChar *name, const xmlChar **atts) -{ - // use a dummy service to hold properties to allow arbitrary nesting - mlt_service service = calloc( 1, sizeof( struct mlt_service_s ) ); - mlt_service_init( service, NULL ); - - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - context_push_service( context, service, mlt_dummy_filter_type ); - - // Set the properties - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - mlt_properties_set( properties, (const char*) atts[0], (const char*) atts[1] ); -} - -static void on_end_filter( deserialise_context context, const xmlChar *name ) -{ - enum service_type type; - mlt_service service = context_pop_service( context, &type ); - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - enum service_type parent_type = invalid_type; - mlt_service parent = context_pop_service( context, &parent_type ); - - if ( service != NULL && type == mlt_dummy_filter_type ) - { - mlt_service filter = MLT_SERVICE( mlt_factory_filter( context->profile, mlt_properties_get( properties, "mlt_service" ), NULL ) ); - mlt_properties filter_props = MLT_SERVICE_PROPERTIES( filter ); - - track_service( context->destructors, filter, (mlt_destructor) mlt_filter_close ); - - // Propogate the properties - qualify_property( context, properties, "resource" ); - qualify_property( context, properties, "luma" ); - qualify_property( context, properties, "luma.resource" ); - qualify_property( context, properties, "composite.luma" ); - qualify_property( context, properties, "producer.resource" ); - mlt_properties_inherit( filter_props, properties ); - - // Attach all filters from service onto filter - attach_filters( filter, service ); - - // Associate the filter with the parent - if ( parent != NULL ) - { - if ( parent_type == mlt_tractor_type ) - { - mlt_field field = mlt_tractor_field( MLT_TRACTOR( parent ) ); - mlt_field_plant_filter( field, MLT_FILTER( filter ), mlt_properties_get_int( properties, "track" ) ); - mlt_filter_set_in_and_out( MLT_FILTER( filter ), - mlt_properties_get_int( properties, "in" ), - mlt_properties_get_int( properties, "out" ) ); - } - else - { - mlt_service_attach( parent, MLT_FILTER( filter ) ); - } - - // Put the parent back on the stack - context_push_service( context, parent, parent_type ); - } - else - { - fprintf( stderr, "filter closed with invalid parent...\n" ); - } - - // Close the dummy filter service - mlt_service_close( service ); - } - else - { - fprintf( stderr, "Invalid top of stack on filter close\n" ); - } -} - -static void on_start_transition( deserialise_context context, const xmlChar *name, const xmlChar **atts) -{ - // use a dummy service to hold properties to allow arbitrary nesting - mlt_service service = calloc( 1, sizeof( struct mlt_service_s ) ); - mlt_service_init( service, NULL ); - - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - context_push_service( context, service, mlt_dummy_transition_type ); - - // Set the properties - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - mlt_properties_set( properties, (const char*) atts[0], (const char*) atts[1] ); -} - -static void on_end_transition( deserialise_context context, const xmlChar *name ) -{ - enum service_type type; - mlt_service service = context_pop_service( context, &type ); - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - enum service_type parent_type = invalid_type; - mlt_service parent = context_pop_service( context, &parent_type ); - - if ( service != NULL && type == mlt_dummy_transition_type ) - { - char *id = mlt_properties_get( properties, "mlt_service" ); - mlt_service effect = MLT_SERVICE( mlt_factory_transition( context->profile, id, NULL ) ); - mlt_properties effect_props = MLT_SERVICE_PROPERTIES( effect ); - - track_service( context->destructors, effect, (mlt_destructor) mlt_transition_close ); - - // Propogate the properties - qualify_property( context, properties, "resource" ); - qualify_property( context, properties, "luma" ); - qualify_property( context, properties, "luma.resource" ); - qualify_property( context, properties, "composite.luma" ); - qualify_property( context, properties, "producer.resource" ); - mlt_properties_inherit( effect_props, properties ); - - // Attach all filters from service onto effect - attach_filters( effect, service ); - - // Associate the filter with the parent - if ( parent != NULL ) - { - if ( parent_type == mlt_tractor_type ) - { - mlt_field field = mlt_tractor_field( MLT_TRACTOR( parent ) ); - if ( mlt_properties_get_int( properties, "a_track" ) == mlt_properties_get_int( properties, "b_track" ) ) - mlt_properties_set_int( properties, "b_track", mlt_properties_get_int( properties, "a_track" ) + 1 ); - mlt_field_plant_transition( field, MLT_TRANSITION( effect ), - mlt_properties_get_int( properties, "a_track" ), - mlt_properties_get_int( properties, "b_track" ) ); - mlt_transition_set_in_and_out( MLT_TRANSITION( effect ), - mlt_properties_get_int( properties, "in" ), - mlt_properties_get_int( properties, "out" ) ); - } - else - { - fprintf( stderr, "Misplaced transition - ignoring\n" ); - } - - // Put the parent back on the stack - context_push_service( context, parent, parent_type ); - } - else - { - fprintf( stderr, "transition closed with invalid parent...\n" ); - } - - // Close the dummy filter service - mlt_service_close( service ); - } - else - { - fprintf( stderr, "Invalid top of stack on transition close\n" ); - } -} - -static void on_start_property( deserialise_context context, const xmlChar *name, const xmlChar **atts) -{ - enum service_type type; - mlt_service service = context_pop_service( context, &type ); - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - const char *value = NULL; - - if ( service != NULL ) - { - // Set the properties - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - { - if ( xmlStrcmp( atts[ 0 ], _x("name") ) == 0 ) - context->property = strdup( _s(atts[ 1 ]) ); - else if ( xmlStrcmp( atts[ 0 ], _x("value") ) == 0 ) - value = _s(atts[ 1 ]); - } - - if ( context->property != NULL ) - mlt_properties_set( properties, context->property, value == NULL ? "" : value ); - - // Tell parser to collect any further nodes for serialisation - context->is_value = 1; - - context_push_service( context, service, type ); - } - else - { - fprintf( stderr, "Property without a service '%s'?\n", ( const char * )name ); - } -} - -static void on_end_property( deserialise_context context, const xmlChar *name ) -{ - enum service_type type; - mlt_service service = context_pop_service( context, &type ); - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - if ( service != NULL ) - { - // Tell parser to stop building a tree - context->is_value = 0; - - // See if there is a xml tree for the value - if ( context->property != NULL && context->value_doc != NULL ) - { - xmlChar *value; - int size; - - // Serialise the tree to get value - xmlDocDumpMemory( context->value_doc, &value, &size ); - mlt_properties_set( properties, context->property, _s(value) ); - xmlFree( value ); - xmlFreeDoc( context->value_doc ); - context->value_doc = NULL; - } - - // Close this property handling - free( context->property ); - context->property = NULL; - - context_push_service( context, service, type ); - } - else - { - fprintf( stderr, "Property without a service '%s'??\n", (const char *)name ); - } -} - -static void on_start_element( void *ctx, const xmlChar *name, const xmlChar **atts) -{ - struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx; - deserialise_context context = ( deserialise_context )( xmlcontext->_private ); - -//printf("on_start_element: %s\n", name ); - context->branch[ context->depth ] ++; - context->depth ++; - - // Build a tree from nodes within a property value - if ( context->is_value == 1 ) - { - xmlNodePtr node = xmlNewNode( NULL, name ); - - if ( context->value_doc == NULL ) - { - // Start a new tree - context->value_doc = xmlNewDoc( _x("1.0") ); - xmlDocSetRootElement( context->value_doc, node ); - } - else - { - // Append child to tree - xmlAddChild( context->stack_node[ context->stack_node_size - 1 ], node ); - } - context_push_node( context, node ); - - // Set the attributes - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - xmlSetProp( node, atts[ 0 ], atts[ 1 ] ); - } - else if ( xmlStrcmp( name, _x("tractor") ) == 0 ) - on_start_tractor( context, name, atts ); - else if ( xmlStrcmp( name, _x("multitrack") ) == 0 ) - on_start_multitrack( context, name, atts ); - else if ( xmlStrcmp( name, _x("playlist") ) == 0 || xmlStrcmp( name, _x("seq") ) == 0 || xmlStrcmp( name, _x("smil") ) == 0 ) - on_start_playlist( context, name, atts ); - else if ( xmlStrcmp( name, _x("producer") ) == 0 || xmlStrcmp( name, _x("video") ) == 0 ) - on_start_producer( context, name, atts ); - else if ( xmlStrcmp( name, _x("blank") ) == 0 ) - on_start_blank( context, name, atts ); - else if ( xmlStrcmp( name, _x("entry") ) == 0 ) - on_start_entry( context, name, atts ); - else if ( xmlStrcmp( name, _x("track") ) == 0 ) - on_start_track( context, name, atts ); - else if ( xmlStrcmp( name, _x("filter") ) == 0 ) - on_start_filter( context, name, atts ); - else if ( xmlStrcmp( name, _x("transition") ) == 0 ) - on_start_transition( context, name, atts ); - else if ( xmlStrcmp( name, _x("property") ) == 0 ) - on_start_property( context, name, atts ); - else if ( xmlStrcmp( name, _x("westley") ) == 0 ) - for ( ; atts != NULL && *atts != NULL; atts += 2 ) - mlt_properties_set( context->producer_map, ( const char * )atts[ 0 ], ( const char * )atts[ 1 ] ); -} - -static void on_end_element( void *ctx, const xmlChar *name ) -{ - struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx; - deserialise_context context = ( deserialise_context )( xmlcontext->_private ); - -//printf("on_end_element: %s\n", name ); - if ( context->is_value == 1 && xmlStrcmp( name, _x("property") ) != 0 ) - context_pop_node( context ); - else if ( xmlStrcmp( name, _x("multitrack") ) == 0 ) - on_end_multitrack( context, name ); - else if ( xmlStrcmp( name, _x("playlist") ) == 0 || xmlStrcmp( name, _x("seq") ) == 0 || xmlStrcmp( name, _x("smil") ) == 0 ) - on_end_playlist( context, name ); - else if ( xmlStrcmp( name, _x("track") ) == 0 ) - on_end_track( context, name ); - else if ( xmlStrcmp( name, _x("entry") ) == 0 ) - on_end_entry( context, name ); - else if ( xmlStrcmp( name, _x("tractor") ) == 0 ) - on_end_tractor( context, name ); - else if ( xmlStrcmp( name, _x("property") ) == 0 ) - on_end_property( context, name ); - else if ( xmlStrcmp( name, _x("producer") ) == 0 || xmlStrcmp( name, _x("video") ) == 0 ) - on_end_producer( context, name ); - else if ( xmlStrcmp( name, _x("filter") ) == 0 ) - on_end_filter( context, name ); - else if ( xmlStrcmp( name, _x("transition") ) == 0 ) - on_end_transition( context, name ); - - context->branch[ context->depth ] = 0; - context->depth --; -} - -static void on_characters( void *ctx, const xmlChar *ch, int len ) -{ - struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx; - deserialise_context context = ( deserialise_context )( xmlcontext->_private ); - char *value = calloc( len + 1, 1 ); - enum service_type type; - mlt_service service = context_pop_service( context, &type ); - mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - - if ( service != NULL ) - context_push_service( context, service, type ); - - value[ len ] = 0; - strncpy( value, (const char*) ch, len ); - - if ( context->stack_node_size > 0 ) - xmlNodeAddContent( context->stack_node[ context->stack_node_size - 1 ], ( xmlChar* )value ); - - // libxml2 generates an on_characters immediately after a get_entity within - // an element value, and we ignore it because it is called again during - // actual substitution. - else if ( context->property != NULL && context->entity_is_replace == 0 ) - { - char *s = mlt_properties_get( properties, context->property ); - if ( s != NULL ) - { - // Append new text to existing content - char *new = calloc( strlen( s ) + len + 1, 1 ); - strcat( new, s ); - strcat( new, value ); - mlt_properties_set( properties, context->property, new ); - free( new ); - } - else - mlt_properties_set( properties, context->property, value ); - } - context->entity_is_replace = 0; - - free( value); -} - -/** Convert parameters parsed from resource into entity declarations. -*/ -static void params_to_entities( deserialise_context context ) -{ - if ( context->params != NULL ) - { - int i; - - // Add our params as entitiy declarations - for ( i = 0; i < mlt_properties_count( context->params ); i++ ) - { - xmlChar *name = ( xmlChar* )mlt_properties_get_name( context->params, i ); - xmlAddDocEntity( context->entity_doc, name, XML_INTERNAL_GENERAL_ENTITY, - context->publicId, context->systemId, ( xmlChar* )mlt_properties_get( context->params, _s(name) ) ); - } - - // Flag completion - mlt_properties_close( context->params ); - context->params = NULL; - } -} - -// The following 3 facilitate entity substitution in the SAX parser -static void on_internal_subset( void *ctx, const xmlChar* name, - const xmlChar* publicId, const xmlChar* systemId ) -{ - struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx; - deserialise_context context = ( deserialise_context )( xmlcontext->_private ); - - context->publicId = publicId; - context->systemId = systemId; - xmlCreateIntSubset( context->entity_doc, name, publicId, systemId ); - - // Override default entities with our parameters - params_to_entities( context ); -} - -// TODO: Check this with Dan... I think this is for westley parameterisation -// but it's breaking standard escaped entities (like < etc). -static void on_entity_declaration( void *ctx, const xmlChar* name, int type, - const xmlChar* publicId, const xmlChar* systemId, xmlChar* content) -{ - struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx; - deserialise_context context = ( deserialise_context )( xmlcontext->_private ); - - xmlAddDocEntity( context->entity_doc, name, type, publicId, systemId, content ); -} - -// TODO: Check this functionality (see on_entity_declaration) -static xmlEntityPtr on_get_entity( void *ctx, const xmlChar* name ) -{ - struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx; - deserialise_context context = ( deserialise_context )( xmlcontext->_private ); - xmlEntityPtr e = NULL; - - // Setup for entity declarations if not ready - if ( xmlGetIntSubset( context->entity_doc ) == NULL ) - { - xmlCreateIntSubset( context->entity_doc, _x("westley"), _x(""), _x("") ); - context->publicId = _x(""); - context->systemId = _x(""); - } - - // Add our parameters if not already - params_to_entities( context ); - - e = xmlGetPredefinedEntity( name ); - - // Send signal to on_characters that an entity substitutin is pending - if ( e == NULL ) - { - e = xmlGetDocEntity( context->entity_doc, name ); - if ( e != NULL ) - context->entity_is_replace = 1; - } - - return e; -} - -/** Convert a hexadecimal character to its value. -*/ -static int tohex( char p ) -{ - return isdigit( p ) ? p - '0' : tolower( p ) - 'a' + 10; -} - -/** Decode a url-encoded string containing hexadecimal character sequences. -*/ -static char *url_decode( char *dest, char *src ) -{ - char *p = dest; - - while ( *src ) - { - if ( *src == '%' ) - { - *p ++ = ( tohex( *( src + 1 ) ) << 4 ) | tohex( *( src + 2 ) ); - src += 3; - } - else - { - *p ++ = *src ++; - } - } - - *p = *src; - return dest; -} - -/** Extract the filename from a URL attaching parameters to a properties list. -*/ -static void parse_url( mlt_properties properties, char *url ) -{ - int i; - int n = strlen( url ); - char *name = NULL; - char *value = NULL; - - for ( i = 0; i < n; i++ ) - { - switch ( url[ i ] ) - { - case '?': - url[ i++ ] = '\0'; - name = &url[ i ]; - break; - - case ':': - case '=': - url[ i++ ] = '\0'; - value = &url[ i ]; - break; - - case '&': - url[ i++ ] = '\0'; - if ( name != NULL && value != NULL ) - mlt_properties_set( properties, name, value ); - name = &url[ i ]; - value = NULL; - break; - } - } - if ( name != NULL && value != NULL ) - mlt_properties_set( properties, name, value ); -} - -// Quick workaround to avoid unecessary libxml2 warnings -static int file_exists( char *file ) -{ - char *name = strdup( file ); - int exists = 0; - if ( name != NULL && strchr( name, '?' ) ) - *( strchr( name, '?' ) ) = '\0'; - if ( name != NULL ) - { - FILE *f = fopen( name, "r" ); - exists = f != NULL; - if ( exists ) fclose( f ); - } - free( name ); - return exists; -} - -mlt_producer producer_westley_init( mlt_profile profile, mlt_service_type servtype, const char *id, char *data ) -{ - xmlSAXHandler *sax = calloc( 1, sizeof( xmlSAXHandler ) ); - struct deserialise_context_s *context = calloc( 1, sizeof( struct deserialise_context_s ) ); - mlt_properties properties = NULL; - int i = 0; - struct _xmlParserCtxt *xmlcontext; - int well_formed = 0; - char *filename = NULL; - int info = strcmp( id, "westley-xml" ) ? 0 : 1; - - if ( data == NULL || !strcmp( data, "" ) || ( info == 0 && !file_exists( data ) ) ) - return NULL; - - context = calloc( 1, sizeof( struct deserialise_context_s ) ); - if ( context == NULL ) - return NULL; - - context->producer_map = mlt_properties_new(); - context->destructors = mlt_properties_new(); - context->params = mlt_properties_new(); - context->profile = profile; - - // Decode URL and parse parameters - mlt_properties_set( context->producer_map, "root", "" ); - if ( info == 0 ) - { - filename = strdup( data ); - parse_url( context->params, url_decode( filename, data ) ); - - // We need the directory prefix which was used for the westley - if ( strchr( filename, '/' ) ) - { - char *root = NULL; - mlt_properties_set( context->producer_map, "root", filename ); - root = mlt_properties_get( context->producer_map, "root" ); - *( strrchr( root, '/' ) ) = '\0'; - - // If we don't have an absolute path here, we're heading for disaster... - if ( root[ 0 ] != '/' ) - { - char *cwd = getcwd( NULL, 0 ); - char *real = malloc( strlen( cwd ) + strlen( root ) + 2 ); - sprintf( real, "%s/%s", cwd, root ); - mlt_properties_set( context->producer_map, "root", real ); - free( real ); - free( cwd ); - } - } - } - - // We need to track the number of registered filters - mlt_properties_set_int( context->destructors, "registered", 0 ); - - // Setup SAX callbacks - sax->startElement = on_start_element; - sax->endElement = on_end_element; - sax->characters = on_characters; - sax->cdataBlock = on_characters; - sax->internalSubset = on_internal_subset; - sax->entityDecl = on_entity_declaration; - sax->getEntity = on_get_entity; - - // Setup libxml2 SAX parsing - xmlInitParser(); - xmlSubstituteEntitiesDefault( 1 ); - // This is used to facilitate entity substitution in the SAX parser - context->entity_doc = xmlNewDoc( _x("1.0") ); - if ( info == 0 ) - xmlcontext = xmlCreateFileParserCtxt( filename ); - else - xmlcontext = xmlCreateMemoryParserCtxt( data, strlen( data ) ); - - // Invalid context - clean up and return NULL - if ( xmlcontext == NULL ) - { - mlt_properties_close( context->producer_map ); - mlt_properties_close( context->destructors ); - mlt_properties_close( context->params ); - free( context ); - free( sax ); - free( filename ); - return NULL; - } - - xmlcontext->sax = sax; - xmlcontext->_private = ( void* )context; - - // Parse - xmlParseDocument( xmlcontext ); - well_formed = xmlcontext->wellFormed; - - // Cleanup after parsing - xmlFreeDoc( context->entity_doc ); - free( sax ); - xmlcontext->sax = NULL; - xmlcontext->_private = NULL; - xmlFreeParserCtxt( xmlcontext ); - xmlMemoryDump( ); // for debugging - - // Get the last producer on the stack - enum service_type type; - mlt_service service = context_pop_service( context, &type ); - if ( well_formed && service != NULL ) - { - // Verify it is a producer service (mlt_type="mlt_producer") - // (producer, playlist, multitrack) - char *type = mlt_properties_get( MLT_SERVICE_PROPERTIES( service ), "mlt_type" ); - if ( type == NULL || ( strcmp( type, "mlt_producer" ) != 0 && strcmp( type, "producer" ) != 0 ) ) - service = NULL; - } - -#ifdef DEBUG - xmlDocPtr doc = westley_make_doc( service ); - xmlDocFormatDump( stdout, doc, 1 ); - xmlFreeDoc( doc ); - service = NULL; -#endif - - if ( well_formed && service != NULL ) - { - char *title = mlt_properties_get( context->producer_map, "title" ); - - // Need the complete producer list for various reasons - properties = context->destructors; - - // Now make sure we don't have a reference to the service in the properties - for ( i = mlt_properties_count( properties ) - 1; i >= 1; i -- ) - { - char *name = mlt_properties_get_name( properties, i ); - if ( mlt_properties_get_data( properties, name, NULL ) == service ) - { - mlt_properties_set_data( properties, name, service, 0, NULL, NULL ); - break; - } - } - - // We are done referencing destructor property list - // Set this var to service properties for convenience - properties = MLT_SERVICE_PROPERTIES( service ); - - // Assign the title - mlt_properties_set( properties, "title", title ); - - // Optimise for overlapping producers - mlt_producer_optimise( MLT_PRODUCER( service ) ); - - // Handle deep copies - if ( getenv( "MLT_WESTLEY_DEEP" ) == NULL ) - { - // Now assign additional properties - if ( info == 0 ) - mlt_properties_set( properties, "resource", data ); - - // This tells consumer_westley not to deep copy - mlt_properties_set( properties, "westley", "was here" ); - } - else - { - // Allow the project to be edited - mlt_properties_set( properties, "_westley", "was here" ); - mlt_properties_set_int( properties, "_mlt_service_hidden", 1 ); - } - } - else - { - // Return null if not well formed - service = NULL; - } - - // Clean up - mlt_properties_close( context->producer_map ); - if ( context->params != NULL ) - mlt_properties_close( context->params ); - mlt_properties_close( context->destructors ); - free( context ); - free( filename ); - - return MLT_PRODUCER( service ); -} diff --git a/src/modules/westley/westley.dtd b/src/modules/westley/westley.dtd deleted file mode 100644 index 4b926d7..0000000 --- a/src/modules/westley/westley.dtd +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/modules/xine/Makefile b/src/modules/xine/Makefile deleted file mode 100644 index 5efb718..0000000 --- a/src/modules/xine/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -include ../../../config.mak - -TARGET = ../libmltxine$(LIBSUF) - -OBJS = factory.o \ - deinterlace.o \ - filter_deinterlace.o - -ifdef MMX_FLAGS -OBJS += cpu_accel.o -endif - -CFLAGS += -I../../ -DARCH_X86 - -LDFLAGS += -L../../framework -lmlt - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/xine/attributes.h b/src/modules/xine/attributes.h deleted file mode 100644 index c468b7b..0000000 --- a/src/modules/xine/attributes.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * attributes.h - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * - * mpeg2dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * mpeg2dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* use gcc attribs to align critical data structures */ - -#ifndef ATTRIBUTE_H_ -#define ATTRIBUTE_H_ - -#ifdef ATTRIBUTE_ALIGNED_MAX -#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align))) -#else -#define ATTR_ALIGN(align) -#endif - -/* disable GNU __attribute__ extension, when not compiling with GNU C */ -#if defined(__GNUC__) || defined (__ICC) -#ifndef ATTRIBUTE_PACKED -#define ATTRIBUTE_PACKED 1 -#endif -#else -#undef ATTRIBUTE_PACKED -#ifndef __attribute__ -#define __attribute__(x) /**/ -#endif /* __attribute __*/ -#endif - -#endif /* ATTRIBUTE_H_ */ - diff --git a/src/modules/xine/cpu_accel.c b/src/modules/xine/cpu_accel.c deleted file mode 100644 index f8c0b7a..0000000 --- a/src/modules/xine/cpu_accel.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * cpu_accel.c - * Copyright (C) 1999-2001 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * - * mpeg2dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * mpeg2dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//#include "config.h" - -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "cpu_accel" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include "xineutils.h" - -#if defined(ARCH_X86) || defined(ARCH_X86_64) -#if defined __x86_64__ -static uint32_t arch_accel (void) -{ - uint32_t caps; - /* No need to test for this on AMD64, we know what the - platform has. */ - caps = MM_ACCEL_X86_MMX | MM_ACCEL_X86_SSE | MM_ACCEL_X86_MMXEXT | MM_ACCEL_X86_SSE2; - - return caps; -} -#else -static uint32_t arch_accel (void) -{ -#ifndef _MSC_VER - - uint32_t eax, ebx, ecx, edx; - int AMD; - uint32_t caps; - -#ifndef PIC -#define cpuid(op,eax,ebx,ecx,edx) \ - __asm__ ("cpuid" \ - : "=a" (eax), \ - "=b" (ebx), \ - "=c" (ecx), \ - "=d" (edx) \ - : "a" (op) \ - : "cc") -#else /* PIC version : save ebx */ -#define cpuid(op,eax,ebx,ecx,edx) \ - __asm__ ("pushl %%ebx\n\t" \ - "cpuid\n\t" \ - "movl %%ebx,%1\n\t" \ - "popl %%ebx" \ - : "=a" (eax), \ - "=r" (ebx), \ - "=c" (ecx), \ - "=d" (edx) \ - : "a" (op) \ - : "cc") -#endif - - __asm__ ("pushfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "movl %0,%1\n\t" - "xorl $0x200000,%0\n\t" - "pushl %0\n\t" - "popfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "popfl" - : "=r" (eax), - "=r" (ebx) - : - : "cc"); - - if (eax == ebx) /* no cpuid */ - return 0; - - cpuid (0x00000000, eax, ebx, ecx, edx); - if (!eax) /* vendor string only */ - return 0; - - AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65); - - cpuid (0x00000001, eax, ebx, ecx, edx); - if (! (edx & 0x00800000)) /* no MMX */ - return 0; - - caps = MM_ACCEL_X86_MMX; - if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */ - caps |= MM_ACCEL_X86_SSE | MM_ACCEL_X86_MMXEXT; - - if (edx & 0x04000000) /* SSE2 */ - caps |= MM_ACCEL_X86_SSE2; - - cpuid (0x80000000, eax, ebx, ecx, edx); - if (eax < 0x80000001) /* no extended capabilities */ - return caps; - - cpuid (0x80000001, eax, ebx, ecx, edx); - - if (edx & 0x80000000) - caps |= MM_ACCEL_X86_3DNOW; - - if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */ - caps |= MM_ACCEL_X86_MMXEXT; - - return caps; -#else /* _MSC_VER */ - return 0; -#endif -} -#endif /* x86_64 */ - -static jmp_buf sigill_return; - -static void sigill_handler (int n) { - longjmp(sigill_return, 1); -} -#endif /* ARCH_X86 */ - -#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) -static sigjmp_buf jmpbuf; -static volatile sig_atomic_t canjump = 0; - -static void sigill_handler (int sig) -{ - if (!canjump) { - signal (sig, SIG_DFL); - raise (sig); - } - - canjump = 0; - siglongjmp (jmpbuf, 1); -} - -static uint32_t arch_accel (void) -{ - signal (SIGILL, sigill_handler); - if (sigsetjmp (jmpbuf, 1)) { - signal (SIGILL, SIG_DFL); - return 0; - } - - canjump = 1; - - __asm__ volatile ("mtspr 256, %0\n\t" - "vand %%v0, %%v0, %%v0" - : - : "r" (-1)); - - signal (SIGILL, SIG_DFL); - return MM_ACCEL_PPC_ALTIVEC; -} -#endif /* ARCH_PPC */ - -uint32_t xine_mm_accel (void) -{ - static int initialized = 0; - static uint32_t accel; - - if (!initialized) { -#if defined (ARCH_X86) || (defined (ARCH_PPC) && defined (ENABLE_ALTIVEC)) - accel = arch_accel (); -#elif defined (HAVE_MLIB) -#ifdef MLIB_LAZYLOAD - void *hndl; - - if ((hndl = dlopen("libmlib.so.2", RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE)) == NULL) { - accel = 0; - } - else { - dlclose(hndl); - accel = MM_ACCEL_MLIB; - } -#else - accel = MM_ACCEL_MLIB; -#endif -#else - accel = 0; -#endif - -#if defined(ARCH_X86) || defined(ARCH_X86_64) -#ifndef _MSC_VER - /* test OS support for SSE */ - if( accel & MM_ACCEL_X86_SSE ) { - void (*old_sigill_handler)(int); - - old_sigill_handler = signal (SIGILL, sigill_handler); - - if (setjmp(sigill_return)) { - lprintf ("OS doesn't support SSE instructions.\n"); - accel &= ~(MM_ACCEL_X86_SSE|MM_ACCEL_X86_SSE2); - } else { - __asm__ volatile ("xorps %xmm0, %xmm0"); - } - - signal (SIGILL, old_sigill_handler); - } -#endif /* _MSC_VER */ -#endif /* ARCH_X86 || ARCH_X86_64 */ - - if(getenv("XINE_NO_ACCEL")) { - accel = 0; - } - - initialized = 1; - } - - return accel; -} diff --git a/src/modules/xine/deinterlace.c b/src/modules/xine/deinterlace.c deleted file mode 100644 index 4a99e94..0000000 --- a/src/modules/xine/deinterlace.c +++ /dev/null @@ -1,860 +0,0 @@ - /* - * Copyright (C) 2001 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * Deinterlace routines by Miguel Freitas - * based of DScaler project sources (deinterlace.sourceforge.net) - * - * Currently only available for Xv driver and MMX extensions - * - * small todo list: - * - implement non-MMX versions for all methods - * - support MMX2 instructions - * - move some generic code from xv driver to this file - * - make it also work for yuy2 frames - * - */ - -#include -#include -#include "deinterlace.h" -#include "xineutils.h" - -#define xine_fast_memcpy memcpy -#define xine_fast_memmove memmove - -/* - DeinterlaceFieldBob algorithm - Based on Virtual Dub plugin by Gunnar Thalin - MMX asm version from dscaler project (deinterlace.sourceforge.net) - Linux version for Xine player by Miguel Freitas -*/ -static void deinterlace_bob_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], - int width, int height ) -{ -#ifdef USE_MMX - int Line; - uint64_t *YVal1; - uint64_t *YVal2; - uint64_t *YVal3; - uint64_t *Dest; - uint8_t* pEvenLines = psrc[0]; - uint8_t* pOddLines = psrc[0]+width; - int LineLength = width; - int SourcePitch = width * 2; - int IsOdd = 1; - long EdgeDetect = 625; - long JaggieThreshold = 73; - - int n; - - uint64_t qwEdgeDetect; - uint64_t qwThreshold; - - static mmx_t YMask = {ub:{0xff,0,0xff,0,0xff,0,0xff,0}}; - static mmx_t Mask = {ub:{0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe}}; - - qwEdgeDetect = EdgeDetect; - qwEdgeDetect += (qwEdgeDetect << 48) + (qwEdgeDetect << 32) + (qwEdgeDetect << 16); - qwThreshold = JaggieThreshold; - qwThreshold += (qwThreshold << 48) + (qwThreshold << 32) + (qwThreshold << 16); - - - // copy first even line no matter what, and the first odd line if we're - // processing an odd field. - xine_fast_memcpy(pdst, pEvenLines, LineLength); - if (IsOdd) - xine_fast_memcpy(pdst + LineLength, pOddLines, LineLength); - - height = height / 2; - for (Line = 0; Line < height - 1; ++Line) - { - if (IsOdd) - { - YVal1 = (uint64_t *)(pOddLines + Line * SourcePitch); - YVal2 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch); - YVal3 = (uint64_t *)(pOddLines + (Line + 1) * SourcePitch); - Dest = (uint64_t *)(pdst + (Line * 2 + 2) * LineLength); - } - else - { - YVal1 = (uint64_t *)(pEvenLines + Line * SourcePitch); - YVal2 = (uint64_t *)(pOddLines + Line * SourcePitch); - YVal3 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch); - Dest = (uint64_t *)(pdst + (Line * 2 + 1) * LineLength); - } - - // For ease of reading, the comments below assume that we're operating on an odd - // field (i.e., that bIsOdd is true). The exact same processing is done when we - // operate on an even field, but the roles of the odd and even fields are reversed. - // It's just too cumbersome to explain the algorithm in terms of "the next odd - // line if we're doing an odd field, or the next even line if we're doing an - // even field" etc. So wherever you see "odd" or "even" below, keep in mind that - // half the time this function is called, those words' meanings will invert. - - // Copy the odd line to the overlay verbatim. - xine_fast_memcpy((char *)Dest + LineLength, YVal3, LineLength); - - n = LineLength >> 3; - while( n-- ) - { - movq_m2r (*YVal1++, mm0); - movq_m2r (*YVal2++, mm1); - movq_m2r (*YVal3++, mm2); - - // get intensities in mm3 - 4 - movq_r2r ( mm0, mm3 ); - pand_m2r ( YMask, mm3 ); - movq_r2r ( mm1, mm4 ); - pand_m2r ( YMask, mm4 ); - movq_r2r ( mm2, mm5 ); - pand_m2r ( YMask, mm5 ); - - // get average in mm0 - pand_m2r ( Mask, mm0 ); - pand_m2r ( Mask, mm2 ); - psrlw_i2r ( 01, mm0 ); - psrlw_i2r ( 01, mm2 ); - paddw_r2r ( mm2, mm0 ); - - // work out (O1 - E) * (O2 - E) / 2 - EdgeDetect * (O1 - O2) ^ 2 >> 12 - // result will be in mm6 - - psrlw_i2r ( 01, mm3 ); - psrlw_i2r ( 01, mm4 ); - psrlw_i2r ( 01, mm5 ); - - movq_r2r ( mm3, mm6 ); - psubw_r2r ( mm4, mm6 ); //mm6 = O1 - E - - movq_r2r ( mm5, mm7 ); - psubw_r2r ( mm4, mm7 ); //mm7 = O2 - E - - pmullw_r2r ( mm7, mm6 ); // mm6 = (O1 - E) * (O2 - E) - - movq_r2r ( mm3, mm7 ); - psubw_r2r ( mm5, mm7 ); // mm7 = (O1 - O2) - pmullw_r2r ( mm7, mm7 ); // mm7 = (O1 - O2) ^ 2 - psrlw_i2r ( 12, mm7 ); // mm7 = (O1 - O2) ^ 2 >> 12 - pmullw_m2r ( *&qwEdgeDetect, mm7 );// mm7 = EdgeDetect * (O1 - O2) ^ 2 >> 12 - - psubw_r2r ( mm7, mm6 ); // mm6 is what we want - - pcmpgtw_m2r ( *&qwThreshold, mm6 ); - - movq_r2r ( mm6, mm7 ); - - pand_r2r ( mm6, mm0 ); - - pandn_r2r ( mm1, mm7 ); - - por_r2r ( mm0, mm7 ); - - movq_r2m ( mm7, *Dest++ ); - } - } - - // Copy last odd line if we're processing an even field. - if (! IsOdd) - { - xine_fast_memcpy(pdst + (height * 2 - 1) * LineLength, - pOddLines + (height - 1) * SourcePitch, - LineLength); - } - - // clear out the MMX registers ready for doing floating point - // again - emms(); -#endif -} - -/* Deinterlace the latest field, with a tendency to weave rather than bob. - Good for high detail on low-movement scenes. - Seems to produce bad output in general case, need to check if this - is normal or if the code is broken. -*/ -static int deinterlace_weave_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], - int width, int height ) -{ -#ifdef USE_MMX - - int Line; - uint64_t *YVal1; - uint64_t *YVal2; - uint64_t *YVal3; - uint64_t *YVal4; - uint64_t *Dest; - uint8_t* pEvenLines = psrc[0]; - uint8_t* pOddLines = psrc[0]+width; - uint8_t* pPrevLines; - - int LineLength = width; - int SourcePitch = width * 2; - int IsOdd = 1; - - long TemporalTolerance = 300; - long SpatialTolerance = 600; - long SimilarityThreshold = 25; - - int n; - - uint64_t qwSpatialTolerance; - uint64_t qwTemporalTolerance; - uint64_t qwThreshold; - - static mmx_t YMask = {ub:{0xff,0,0xff,0,0xff,0,0xff,0}}; - static mmx_t Mask = {ub:{0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe}}; - - - // Make sure we have all the data we need. - if ( psrc[0] == NULL || psrc[1] == NULL ) - return 0; - - if (IsOdd) - pPrevLines = psrc[1] + width; - else - pPrevLines = psrc[1]; - - // Since the code uses MMX to process 4 pixels at a time, we need our constants - // to be represented 4 times per quadword. - qwSpatialTolerance = SpatialTolerance; - qwSpatialTolerance += (qwSpatialTolerance << 48) + (qwSpatialTolerance << 32) + (qwSpatialTolerance << 16); - qwTemporalTolerance = TemporalTolerance; - qwTemporalTolerance += (qwTemporalTolerance << 48) + (qwTemporalTolerance << 32) + (qwTemporalTolerance << 16); - qwThreshold = SimilarityThreshold; - qwThreshold += (qwThreshold << 48) + (qwThreshold << 32) + (qwThreshold << 16); - - // copy first even line no matter what, and the first odd line if we're - // processing an even field. - xine_fast_memcpy(pdst, pEvenLines, LineLength); - if (!IsOdd) - xine_fast_memcpy(pdst + LineLength, pOddLines, LineLength); - - height = height / 2; - for (Line = 0; Line < height - 1; ++Line) - { - if (IsOdd) - { - YVal1 = (uint64_t *)(pEvenLines + Line * SourcePitch); - YVal2 = (uint64_t *)(pOddLines + Line * SourcePitch); - YVal3 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch); - YVal4 = (uint64_t *)(pPrevLines + Line * SourcePitch); - Dest = (uint64_t *)(pdst + (Line * 2 + 1) * LineLength); - } - else - { - YVal1 = (uint64_t *)(pOddLines + Line * SourcePitch); - YVal2 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch); - YVal3 = (uint64_t *)(pOddLines + (Line + 1) * SourcePitch); - YVal4 = (uint64_t *)(pPrevLines + (Line + 1) * SourcePitch); - Dest = (uint64_t *)(pdst + (Line * 2 + 2) * LineLength); - } - - // For ease of reading, the comments below assume that we're operating on an odd - // field (i.e., that bIsOdd is true). The exact same processing is done when we - // operate on an even field, but the roles of the odd and even fields are reversed. - // It's just too cumbersome to explain the algorithm in terms of "the next odd - // line if we're doing an odd field, or the next even line if we're doing an - // even field" etc. So wherever you see "odd" or "even" below, keep in mind that - // half the time this function is called, those words' meanings will invert. - - // Copy the even scanline below this one to the overlay buffer, since we'll be - // adapting the current scanline to the even lines surrounding it. The scanline - // above has already been copied by the previous pass through the loop. - xine_fast_memcpy((char *)Dest + LineLength, YVal3, LineLength); - - n = LineLength >> 3; - while( n-- ) - { - movq_m2r ( *YVal1++, mm0 ); // mm0 = E1 - movq_m2r ( *YVal2++, mm1 ); // mm1 = O - movq_m2r ( *YVal3++, mm2 ); // mm2 = E2 - - movq_r2r ( mm0, mm3 ); // mm3 = intensity(E1) - movq_r2r ( mm1, mm4 ); // mm4 = intensity(O) - movq_r2r ( mm2, mm6 ); // mm6 = intensity(E2) - - pand_m2r ( YMask, mm3 ); - pand_m2r ( YMask, mm4 ); - pand_m2r ( YMask, mm6 ); - - // Average E1 and E2 for interpolated bobbing. - // leave result in mm0 - pand_m2r ( Mask, mm0 ); // mm0 = E1 with lower chroma bit stripped off - pand_m2r ( Mask, mm2 ); // mm2 = E2 with lower chroma bit stripped off - psrlw_i2r ( 01, mm0 ); // mm0 = E1 / 2 - psrlw_i2r ( 01, mm2 ); // mm2 = E2 / 2 - paddb_r2r ( mm2, mm0 ); - - // The meat of the work is done here. We want to see whether this pixel is - // close in luminosity to ANY of: its top neighbor, its bottom neighbor, - // or its predecessor. To do this without branching, we use MMX's - // saturation feature, which gives us Z(x) = x if x>=0, or 0 if x<0. - // - // The formula we're computing here is - // Z(ST - (E1 - O) ^ 2) + Z(ST - (E2 - O) ^ 2) + Z(TT - (Oold - O) ^ 2) - // where ST is spatial tolerance and TT is temporal tolerance. The idea - // is that if a pixel is similar to none of its neighbors, the resulting - // value will be pretty low, probably zero. A high value therefore indicates - // that the pixel had a similar neighbor. The pixel in the same position - // in the field before last (Oold) is considered a neighbor since we want - // to be able to display 1-pixel-high horizontal lines. - - movq_m2r ( *&qwSpatialTolerance, mm7 ); - movq_r2r ( mm3, mm5 ); // mm5 = E1 - psubsw_r2r ( mm4, mm5 ); // mm5 = E1 - O - psraw_i2r ( 1, mm5 ); - pmullw_r2r ( mm5, mm5 ); // mm5 = (E1 - O) ^ 2 - psubusw_r2r ( mm5, mm7 ); // mm7 = ST - (E1 - O) ^ 2, or 0 if that's negative - - movq_m2r ( *&qwSpatialTolerance, mm3 ); - movq_r2r ( mm6, mm5 ); // mm5 = E2 - psubsw_r2r ( mm4, mm5 ); // mm5 = E2 - O - psraw_i2r ( 1, mm5 ); - pmullw_r2r ( mm5, mm5 ); // mm5 = (E2 - O) ^ 2 - psubusw_r2r ( mm5, mm3 ); // mm0 = ST - (E2 - O) ^ 2, or 0 if that's negative - paddusw_r2r ( mm3, mm7 ); // mm7 = (ST - (E1 - O) ^ 2) + (ST - (E2 - O) ^ 2) - - movq_m2r ( *&qwTemporalTolerance, mm3 ); - movq_m2r ( *YVal4++, mm5 ); // mm5 = Oold - pand_m2r ( YMask, mm5 ); - psubsw_r2r ( mm4, mm5 ); // mm5 = Oold - O - psraw_i2r ( 1, mm5 ); // XXX - pmullw_r2r ( mm5, mm5 ); // mm5 = (Oold - O) ^ 2 - psubusw_r2r ( mm5, mm3 ); /* mm0 = TT - (Oold - O) ^ 2, or 0 if that's negative */ - paddusw_r2r ( mm3, mm7 ); // mm7 = our magic number - - /* - * Now compare the similarity totals against our threshold. The pcmpgtw - * instruction will populate the target register with a bunch of mask bits, - * filling words where the comparison is true with 1s and ones where it's - * false with 0s. A few ANDs and NOTs and an OR later, we have bobbed - * values for pixels under the similarity threshold and weaved ones for - * pixels over the threshold. - */ - - pcmpgtw_m2r( *&qwThreshold, mm7 ); // mm7 = 0xffff where we're greater than the threshold, 0 elsewhere - movq_r2r ( mm7, mm6 ); // mm6 = 0xffff where we're greater than the threshold, 0 elsewhere - pand_r2r ( mm1, mm7 ); // mm7 = weaved data where we're greater than the threshold, 0 elsewhere - pandn_r2r ( mm0, mm6 ); // mm6 = bobbed data where we're not greater than the threshold, 0 elsewhere - por_r2r ( mm6, mm7 ); // mm7 = bobbed and weaved data - - movq_r2m ( mm7, *Dest++ ); - } - } - - // Copy last odd line if we're processing an odd field. - if (IsOdd) - { - xine_fast_memcpy(pdst + (height * 2 - 1) * LineLength, - pOddLines + (height - 1) * SourcePitch, - LineLength); - } - - // clear out the MMX registers ready for doing floating point - // again - emms(); - -#endif - - return 1; -} - - -// This is a simple lightweight DeInterlace method that uses little CPU time -// but gives very good results for low or intermedite motion. (MORE CPU THAN BOB) -// It defers frames by one field, but that does not seem to produce noticeable -// lip sync problems. -// -// The method used is to take either the older or newer weave pixel depending -// upon which give the smaller comb factor, and then clip to avoid large damage -// when wrong. -// -// I'd intended this to be part of a larger more elaborate method added to -// Blended Clip but this give too good results for the CPU to ignore here. -static int deinterlace_greedy_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], - int width, int height ) -{ -#ifdef USE_MMX - int Line; - int LoopCtr; - uint64_t *L1; // ptr to Line1, of 3 - uint64_t *L2; // ptr to Line2, the weave line - uint64_t *L3; // ptr to Line3 - uint64_t *LP2; // ptr to prev Line2 - uint64_t *Dest; - uint8_t* pEvenLines = psrc[0]; - uint8_t* pOddLines = psrc[0]+width; - uint8_t* pPrevLines; - - static mmx_t ShiftMask = {ub:{0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe}}; - - int LineLength = width; - int SourcePitch = width * 2; - int IsOdd = 1; - long GreedyMaxComb = 15; - static mmx_t MaxComb; - int i; - - if ( psrc[0] == NULL || psrc[1] == NULL ) - return 0; - - if (IsOdd) - pPrevLines = psrc[1] + width; - else - pPrevLines = psrc[1]; - - - for( i = 0; i < 8; i++ ) - MaxComb.ub[i] = GreedyMaxComb; // How badly do we let it weave? 0-255 - - - // copy first even line no matter what, and the first odd line if we're - // processing an EVEN field. (note diff from other deint rtns.) - xine_fast_memcpy(pdst, pEvenLines, LineLength); //DL0 - if (!IsOdd) - xine_fast_memcpy(pdst + LineLength, pOddLines, LineLength); //DL1 - - height = height / 2; - for (Line = 0; Line < height - 1; ++Line) - { - LoopCtr = LineLength / 8; // there are LineLength / 8 qwords per line - - if (IsOdd) - { - L1 = (uint64_t *)(pEvenLines + Line * SourcePitch); - L2 = (uint64_t *)(pOddLines + Line * SourcePitch); - L3 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch); - LP2 = (uint64_t *)(pPrevLines + Line * SourcePitch); // prev Odd lines - Dest = (uint64_t *)(pdst + (Line * 2 + 1) * LineLength); - } - else - { - L1 = (uint64_t *)(pOddLines + Line * SourcePitch); - L2 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch); - L3 = (uint64_t *)(pOddLines + (Line + 1) * SourcePitch); - LP2 = (uint64_t *)(pPrevLines + (Line + 1) * SourcePitch); //prev even lines - Dest = (uint64_t *)(pdst + (Line * 2 + 2) * LineLength); - } - - xine_fast_memcpy((char *)Dest + LineLength, L3, LineLength); - -// For ease of reading, the comments below assume that we're operating on an odd -// field (i.e., that info->IsOdd is true). Assume the obvious for even lines.. - - while( LoopCtr-- ) - { - movq_m2r ( *L1++, mm1 ); - movq_m2r ( *L2++, mm2 ); - movq_m2r ( *L3++, mm3 ); - movq_m2r ( *LP2++, mm0 ); - - // average L1 and L3 leave result in mm4 - movq_r2r ( mm1, mm4 ); // L1 - - pand_m2r ( ShiftMask, mm4 ); - psrlw_i2r ( 01, mm4 ); - movq_r2r ( mm3, mm5 ); // L3 - pand_m2r ( ShiftMask, mm5 ); - psrlw_i2r ( 01, mm5 ); - paddb_r2r ( mm5, mm4 ); // the average, for computing comb - - // get abs value of possible L2 comb - movq_r2r ( mm2, mm7 ); // L2 - psubusb_r2r ( mm4, mm7 ); // L2 - avg - movq_r2r ( mm4, mm5 ); // avg - psubusb_r2r ( mm2, mm5 ); // avg - L2 - por_r2r ( mm7, mm5 ); // abs(avg-L2) - movq_r2r ( mm4, mm6 ); // copy of avg for later - - // get abs value of possible LP2 comb - movq_r2r ( mm0, mm7 ); // LP2 - psubusb_r2r ( mm4, mm7 ); // LP2 - avg - psubusb_r2r ( mm0, mm4 ); // avg - LP2 - por_r2r ( mm7, mm4 ); // abs(avg-LP2) - - // use L2 or LP2 depending upon which makes smaller comb - psubusb_r2r ( mm5, mm4 ); // see if it goes to zero - psubusb_r2r ( mm5, mm5 ); // 0 - pcmpeqb_r2r ( mm5, mm4 ); // if (mm4=0) then FF else 0 - pcmpeqb_r2r ( mm4, mm5 ); // opposite of mm4 - - // if Comb(LP2) <= Comb(L2) then mm4=ff, mm5=0 else mm4=0, mm5 = 55 - pand_r2r ( mm2, mm5 ); // use L2 if mm5 == ff, else 0 - pand_r2r ( mm0, mm4 ); // use LP2 if mm4 = ff, else 0 - por_r2r ( mm5, mm4 ); // may the best win - - // Now lets clip our chosen value to be not outside of the range - // of the high/low range L1-L3 by more than abs(L1-L3) - // This allows some comb but limits the damages and also allows more - // detail than a boring oversmoothed clip. - - movq_r2r ( mm1, mm2 ); // copy L1 - psubusb_r2r ( mm3, mm2 ); // - L3, with saturation - paddusb_r2r ( mm3, mm2 ); // now = Max(L1,L3) - - pcmpeqb_r2r ( mm7, mm7 ); // all ffffffff - psubusb_r2r ( mm1, mm7 ); // - L1 - paddusb_r2r ( mm7, mm3 ); // add, may sat at fff.. - psubusb_r2r ( mm7, mm3 ); // now = Min(L1,L3) - - // allow the value to be above the high or below the low by amt of MaxComb - paddusb_m2r ( MaxComb, mm2 ); // increase max by diff - psubusb_m2r ( MaxComb, mm3 ); // lower min by diff - - psubusb_r2r ( mm3, mm4 ); // best - Min - paddusb_r2r ( mm3, mm4 ); // now = Max(best,Min(L1,L3) - - pcmpeqb_r2r ( mm7, mm7 ); // all ffffffff - psubusb_r2r ( mm4, mm7 ); // - Max(best,Min(best,L3) - paddusb_r2r ( mm7, mm2 ); // add may sat at FFF.. - psubusb_r2r ( mm7, mm2 ); // now = Min( Max(best, Min(L1,L3), L2 )=L2 clipped - - movq_r2m ( mm2, *Dest++ ); // move in our clipped best - - } - } - - /* Copy last odd line if we're processing an Odd field. */ - if (IsOdd) - { - xine_fast_memcpy(pdst + (height * 2 - 1) * LineLength, - pOddLines + (height - 1) * SourcePitch, - LineLength); - } - - /* clear out the MMX registers ready for doing floating point again */ - emms(); - -#endif - - return 1; -} - -/* Use one field to interpolate the other (low cpu utilization) - Will lose resolution but does not produce weaving effect - (good for fast moving scenes) also know as "linear interpolation" -*/ -static void deinterlace_onefield_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], - int width, int height ) -{ -#ifdef USE_MMX - int Line; - uint64_t *YVal1; - uint64_t *YVal3; - uint64_t *Dest; - uint8_t* pEvenLines = psrc[0]; - uint8_t* pOddLines = psrc[0]+width; - int LineLength = width; - int SourcePitch = width * 2; - int IsOdd = 1; - - int n; - - static mmx_t Mask = {ub:{0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe}}; - - /* - * copy first even line no matter what, and the first odd line if we're - * processing an odd field. - */ - - xine_fast_memcpy(pdst, pEvenLines, LineLength); - if (IsOdd) - xine_fast_memcpy(pdst + LineLength, pOddLines, LineLength); - - height = height / 2; - for (Line = 0; Line < height - 1; ++Line) - { - if (IsOdd) - { - YVal1 = (uint64_t *)(pOddLines + Line * SourcePitch); - YVal3 = (uint64_t *)(pOddLines + (Line + 1) * SourcePitch); - Dest = (uint64_t *)(pdst + (Line * 2 + 2) * LineLength); - } - else - { - YVal1 = (uint64_t *)(pEvenLines + Line * SourcePitch); - YVal3 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch); - Dest = (uint64_t *)(pdst + (Line * 2 + 1) * LineLength); - } - - // Copy the odd line to the overlay verbatim. - xine_fast_memcpy((char *)Dest + LineLength, YVal3, LineLength); - - n = LineLength >> 3; - while( n-- ) - { - movq_m2r (*YVal1++, mm0); - movq_m2r (*YVal3++, mm2); - - // get average in mm0 - pand_m2r ( Mask, mm0 ); - pand_m2r ( Mask, mm2 ); - psrlw_i2r ( 01, mm0 ); - psrlw_i2r ( 01, mm2 ); - paddw_r2r ( mm2, mm0 ); - - movq_r2m ( mm0, *Dest++ ); - } - } - - /* Copy last odd line if we're processing an even field. */ - if (! IsOdd) - { - xine_fast_memcpy(pdst + (height * 2 - 1) * LineLength, - pOddLines + (height - 1) * SourcePitch, - LineLength); - } - - /* clear out the MMX registers ready for doing floating point - * again - */ - emms(); -#endif -} - -/* Linear Blend filter - does a kind of vertical blurring on the image. - (idea borrowed from mplayer's sources) -*/ -static void deinterlace_linearblend_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], - int width, int height ) -{ -#ifdef USE_MMX - int Line; - uint64_t *YVal1; - uint64_t *YVal2; - uint64_t *YVal3; - uint64_t *Dest; - int LineLength = width; - - int n; - - /* Copy first line */ - xine_fast_memmove(pdst, psrc[0], LineLength); - - for (Line = 1; Line < height - 1; ++Line) - { - YVal1 = (uint64_t *)(psrc[0] + (Line - 1) * LineLength); - YVal2 = (uint64_t *)(psrc[0] + (Line) * LineLength); - YVal3 = (uint64_t *)(psrc[0] + (Line + 1) * LineLength); - Dest = (uint64_t *)(pdst + Line * LineLength); - - n = LineLength >> 3; - while( n-- ) - { - /* load data from 3 lines */ - movq_m2r (*YVal1++, mm0); - movq_m2r (*YVal2++, mm1); - movq_m2r (*YVal3++, mm2); - - /* expand bytes to words */ - punpckhbw_r2r (mm0, mm3); - punpckhbw_r2r (mm1, mm4); - punpckhbw_r2r (mm2, mm5); - punpcklbw_r2r (mm0, mm0); - punpcklbw_r2r (mm1, mm1); - punpcklbw_r2r (mm2, mm2); - - /* - * deinterlacing: - * deint_line = (line0 + 2*line1 + line2) / 4 - */ - psrlw_i2r (07, mm0); - psrlw_i2r (06, mm1); - psrlw_i2r (07, mm2); - psrlw_i2r (07, mm3); - psrlw_i2r (06, mm4); - psrlw_i2r (07, mm5); - paddw_r2r (mm1, mm0); - paddw_r2r (mm2, mm0); - paddw_r2r (mm4, mm3); - paddw_r2r (mm5, mm3); - psrlw_i2r (03, mm0); - psrlw_i2r (03, mm3); - - /* pack 8 words to 8 bytes in mm0 */ - packuswb_r2r (mm3, mm0); - - movq_r2m ( mm0, *Dest++ ); - } - } - - /* Copy last line */ - xine_fast_memmove(pdst + Line * LineLength, - psrc[0] + Line * LineLength, LineLength); - - /* clear out the MMX registers ready for doing floating point - * again - */ - emms(); -#endif -} - -/* Linear Blend filter - C version contributed by Rogerio Brito. - This algorithm has the same interface as the other functions. - - The destination "screen" (pdst) is constructed from the source - screen (psrc[0]) line by line. - - The i-th line of the destination screen is the average of 3 lines - from the source screen: the (i-1)-th, i-th and (i+1)-th lines, with - the i-th line having weight 2 in the computation. - - Remarks: - * each line on pdst doesn't depend on previous lines; - * due to the way the algorithm is defined, the first & last lines of the - screen aren't deinterlaced. - -*/ -static void deinterlace_linearblend_yuv( uint8_t *pdst, uint8_t *psrc[], - int width, int height ) -{ - register int x, y; - register uint8_t *l0, *l1, *l2, *l3; - - l0 = pdst; /* target line */ - l1 = psrc[0]; /* 1st source line */ - l2 = l1 + width; /* 2nd source line = line that follows l1 */ - l3 = l2 + width; /* 3rd source line = line that follows l2 */ - - /* Copy the first line */ - xine_fast_memcpy(l0, l1, width); - l0 += width; - - for (y = 1; y < height-1; ++y) { - /* computes avg of: l1 + 2*l2 + l3 */ - - for (x = 0; x < width; ++x) { - l0[x] = (l1[x] + (l2[x]<<1) + l3[x]) >> 2; - } - - /* updates the line pointers */ - l1 = l2; l2 = l3; l3 += width; - l0 += width; - } - - /* Copy the last line */ - xine_fast_memcpy(l0, l1, width); -} - -static int check_for_mmx(void) -{ -#ifdef USE_MMX -static int config_flags = -1; - - if ( config_flags == -1 ) - config_flags = xine_mm_accel(); - if (config_flags & MM_ACCEL_X86_MMX) - return 1; - return 0; -#else - return 0; -#endif -} - -/* generic YUV deinterlacer - pdst -> pointer to destination bitmap - psrc -> array of pointers to source bitmaps ([0] = most recent) - width,height -> dimension for bitmaps - method -> DEINTERLACE_xxx -*/ - -void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[], - int width, int height, int method ) -{ - switch( method ) { - case DEINTERLACE_NONE: - xine_fast_memcpy(pdst,psrc[0],width*height); - break; - case DEINTERLACE_BOB: - if( check_for_mmx() ) - deinterlace_bob_yuv_mmx(pdst,psrc,width,height); - else /* FIXME: provide an alternative? */ - xine_fast_memcpy(pdst,psrc[0],width*height); - break; - case DEINTERLACE_WEAVE: - if( check_for_mmx() ) - { - if( !deinterlace_weave_yuv_mmx(pdst,psrc,width,height) ) - xine_fast_memcpy(pdst,psrc[0],width*height); - } - else /* FIXME: provide an alternative? */ - xine_fast_memcpy(pdst,psrc[0],width*height); - break; - case DEINTERLACE_GREEDY: - if( check_for_mmx() ) - { - if( !deinterlace_greedy_yuv_mmx(pdst,psrc,width,height) ) - xine_fast_memcpy(pdst,psrc[0],width*height); - } - else /* FIXME: provide an alternative? */ - xine_fast_memcpy(pdst,psrc[0],width*height); - break; - case DEINTERLACE_ONEFIELD: - if( check_for_mmx() ) - deinterlace_onefield_yuv_mmx(pdst,psrc,width,height); - else /* FIXME: provide an alternative? */ - xine_fast_memcpy(pdst,psrc[0],width*height); - break; - case DEINTERLACE_ONEFIELDXV: - lprintf("ONEFIELDXV must be handled by the video driver.\n"); - break; - case DEINTERLACE_LINEARBLEND: - if( check_for_mmx() ) - deinterlace_linearblend_yuv_mmx(pdst,psrc,width,height); - else - deinterlace_linearblend_yuv(pdst,psrc,width,height); - break; - default: - lprintf("unknown method %d.\n",method); - break; - } -} - -int deinterlace_yuv_supported ( int method ) -{ - switch( method ) { - case DEINTERLACE_NONE: - return 1; - case DEINTERLACE_BOB: - case DEINTERLACE_WEAVE: - case DEINTERLACE_GREEDY: - case DEINTERLACE_ONEFIELD: - return check_for_mmx(); - case DEINTERLACE_ONEFIELDXV: - lprintf ("ONEFIELDXV must be handled by the video driver.\n"); - return 0; - case DEINTERLACE_LINEARBLEND: - return 1; - } - - return 0; -} - -const char *deinterlace_methods[] = { - "none", - "bob", - "weave", - "greedy", - "onefield", - "onefield_xv", - "linearblend", - NULL -}; - - diff --git a/src/modules/xine/deinterlace.h b/src/modules/xine/deinterlace.h deleted file mode 100644 index 0cad92a..0000000 --- a/src/modules/xine/deinterlace.h +++ /dev/null @@ -1,47 +0,0 @@ - /* - * Copyright (C) 2001 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * Deinterlace routines by Miguel Freitas - * based of DScaler project sources (deinterlace.sourceforge.net) - * - * Currently only available for Xv driver and MMX extensions - * - */ - -#ifndef __DEINTERLACE_H__ -#define __DEINTERLACE_H__ - -//#include "video_out.h" -#include - -int deinterlace_yuv_supported ( int method ); -void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[], - int width, int height, int method ); - -#define DEINTERLACE_NONE 0 -#define DEINTERLACE_BOB 1 -#define DEINTERLACE_WEAVE 2 -#define DEINTERLACE_GREEDY 3 -#define DEINTERLACE_ONEFIELD 4 -#define DEINTERLACE_ONEFIELDXV 5 -#define DEINTERLACE_LINEARBLEND 6 - -extern const char *deinterlace_methods[]; - -#endif diff --git a/src/modules/xine/factory.c b/src/modules/xine/factory.c deleted file mode 100644 index 11d2c15..0000000 --- a/src/modules/xine/factory.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -extern mlt_filter filter_deinterlace_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( filter_type, "deinterlace", filter_deinterlace_init ); -} diff --git a/src/modules/xine/filter_deinterlace.c b/src/modules/xine/filter_deinterlace.c deleted file mode 100644 index 01871cf..0000000 --- a/src/modules/xine/filter_deinterlace.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * filter_deinterlace.c -- deinterlace filter - * Copyright (C) 2003-2004 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include "deinterlace.h" - -#include - -#include -#include - -/** Do it :-). -*/ - -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - int error = 0; - int deinterlace = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "consumer_deinterlace" ); - - // Pop the service off the stack - mlt_filter filter = mlt_frame_pop_service( this ); - - // Determine if we need a writable version or not - if ( deinterlace && !writable ) - writable = !mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "progressive" ); - - // Get the input image - error = mlt_frame_get_image( this, image, format, width, height, writable ); - - // Check that we want progressive and we aren't already progressive - if ( deinterlace && *format == mlt_image_yuv422 && *image != NULL && !mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "progressive" ) ) - { - // Determine deinterlace method - char *method_str = mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "method" ); - int method = DEINTERLACE_LINEARBLEND; - char *frame_method_str = mlt_properties_get( MLT_FRAME_PROPERTIES( this ), "deinterlace_method" ); - - if ( frame_method_str != NULL ) - method_str = frame_method_str; - - if ( method_str == NULL ) - method = DEINTERLACE_LINEARBLEND; - else if ( strcmp( method_str, "bob" ) == 0 ) - method = DEINTERLACE_BOB; - else if ( strcmp( method_str, "weave" ) == 0 ) - method = DEINTERLACE_BOB; - else if ( strcmp( method_str, "greedy" ) == 0 ) - method = DEINTERLACE_GREEDY; - else if ( strcmp( method_str, "onefield" ) == 0 ) - method = DEINTERLACE_ONEFIELD; - - // Deinterlace the image - deinterlace_yuv( *image, image, *width * 2, *height, method ); - - // Make sure that others know the frame is deinterlaced - mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "progressive", 1 ); - } - - return error; -} - -/** Deinterlace filter processing - this should be lazy evaluation here... -*/ - -static mlt_frame deinterlace_process( mlt_filter this, mlt_frame frame ) -{ - // Push this on to the service stack - mlt_frame_push_service( frame, this ); - - // Push the get_image method on to the stack - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_deinterlace_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = deinterlace_process; - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "method", arg ); - } - return this; -} - diff --git a/src/modules/xine/gpl b/src/modules/xine/gpl deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/xine/xineutils.h b/src/modules/xine/xineutils.h deleted file mode 100644 index f0d74ce..0000000 --- a/src/modules/xine/xineutils.h +++ /dev/null @@ -1,1098 +0,0 @@ -/* - * Copyright (C) 2000-2004 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id$ - * - */ -#ifndef XINEUTILS_H -#define XINEUTILS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#if HAVE_LIBGEN_H -# include -#endif - -//#ifdef XINE_COMPILE -# include "attributes.h" -//# include "compat.h" -//# include "xmlparser.h" -//# include "xine_buffer.h" -//# include "configfile.h" -//#else -//# include -//# include -//# include -//# include -//# include -//#endif - -//#ifdef HAVE_CONFIG_H -//#include "config.h" -//#endif - -#include -#include - - /* - * debugable mutexes - */ - - typedef struct { - pthread_mutex_t mutex; - char id[80]; - char *locked_by; - } xine_mutex_t; - - int xine_mutex_init (xine_mutex_t *mutex, const pthread_mutexattr_t *mutexattr, - char *id); - - int xine_mutex_lock (xine_mutex_t *mutex, char *who); - int xine_mutex_unlock (xine_mutex_t *mutex, char *who); - int xine_mutex_destroy (xine_mutex_t *mutex); - - - - /* CPU Acceleration */ - -/* - * The type of an value that fits in an MMX register (note that long - * long constant values MUST be suffixed by LL and unsigned long long - * values by ULL, lest they be truncated by the compiler) - */ - -/* generic accelerations */ -#define MM_ACCEL_MLIB 0x00000001 - -/* x86 accelerations */ -#define MM_ACCEL_X86_MMX 0x80000000 -#define MM_ACCEL_X86_3DNOW 0x40000000 -#define MM_ACCEL_X86_MMXEXT 0x20000000 -#define MM_ACCEL_X86_SSE 0x10000000 -#define MM_ACCEL_X86_SSE2 0x08000000 -/* powerpc accelerations */ -#define MM_ACCEL_PPC_ALTIVEC 0x04000000 -/* x86 compat defines */ -#define MM_MMX MM_ACCEL_X86_MMX -#define MM_3DNOW MM_ACCEL_X86_3DNOW -#define MM_MMXEXT MM_ACCEL_X86_MMXEXT -#define MM_SSE MM_ACCEL_X86_SSE -#define MM_SSE2 MM_ACCEL_X86_SSE2 - -uint32_t xine_mm_accel (void); - -#ifdef USE_MMX - -typedef union { - int64_t q; /* Quadword (64-bit) value */ - uint64_t uq; /* Unsigned Quadword */ - int d[2]; /* 2 Doubleword (32-bit) values */ - unsigned int ud[2]; /* 2 Unsigned Doubleword */ - short w[4]; /* 4 Word (16-bit) values */ - unsigned short uw[4]; /* 4 Unsigned Word */ - char b[8]; /* 8 Byte (8-bit) values */ - unsigned char ub[8]; /* 8 Unsigned Byte */ - float s[2]; /* Single-precision (32-bit) value */ -} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */ - - - -#define mmx_i2r(op,imm,reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "i" (imm) ) - -#define mmx_m2r(op,mem,reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "m" (mem)) - -#define mmx_r2m(op,reg,mem) \ - __asm__ __volatile__ (#op " %%" #reg ", %0" \ - : "=m" (mem) \ - : /* nothing */ ) - -#define mmx_r2r(op,regs,regd) \ - __asm__ __volatile__ (#op " %" #regs ", %" #regd) - - -#define emms() __asm__ __volatile__ ("emms") - -#define movd_m2r(var,reg) mmx_m2r (movd, var, reg) -#define movd_r2m(reg,var) mmx_r2m (movd, reg, var) -#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd) - -#define movq_m2r(var,reg) mmx_m2r (movq, var, reg) -#define movq_r2m(reg,var) mmx_r2m (movq, reg, var) -#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd) - -#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg) -#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd) -#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg) -#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd) - -#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg) -#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd) - -#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg) -#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd) -#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg) -#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd) -#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg) -#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd) - -#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg) -#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd) -#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg) -#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd) - -#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg) -#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd) -#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg) -#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd) - -#define pand_m2r(var,reg) mmx_m2r (pand, var, reg) -#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd) - -#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg) -#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd) - -#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg) -#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd) -#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg) -#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd) -#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg) -#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd) - -#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg) -#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd) -#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg) -#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd) -#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg) -#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd) - -#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg) -#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd) - -#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg) -#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd) - -#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg) -#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd) - -#define por_m2r(var,reg) mmx_m2r (por, var, reg) -#define por_r2r(regs,regd) mmx_r2r (por, regs, regd) - -#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg) -#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg) -#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd) -#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg) -#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg) -#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd) -#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg) -#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg) -#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd) - -#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg) -#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg) -#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd) -#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg) -#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg) -#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd) - -#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg) -#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg) -#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd) -#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg) -#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg) -#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd) -#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg) -#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg) -#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd) - -#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg) -#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd) -#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg) -#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd) -#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg) -#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd) - -#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg) -#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd) -#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg) -#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd) - -#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg) -#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd) -#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg) -#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd) - -#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg) -#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd) -#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg) -#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd) -#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg) -#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd) - -#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg) -#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd) -#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg) -#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd) -#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg) -#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd) - -#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg) -#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd) - - -/* 3DNOW extensions */ - -#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg) -#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd) - - -/* AMD MMX extensions - also available in intel SSE */ - - -#define mmx_m2ri(op,mem,reg,imm) \ - __asm__ __volatile__ (#op " %1, %0, %%" #reg \ - : /* nothing */ \ - : "X" (mem), "X" (imm)) -#define mmx_r2ri(op,regs,regd,imm) \ - __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ - : /* nothing */ \ - : "X" (imm) ) - -#define mmx_fetch(mem,hint) \ - __asm__ __volatile__ ("prefetch" #hint " %0" \ - : /* nothing */ \ - : "X" (mem)) - - -#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg) - -#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var) - -#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg) -#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd) -#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg) -#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd) - -#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm) - -#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm) - -#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg) -#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd) - -#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg) -#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd) - -#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg) -#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd) - -#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg) -#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd) - -#define pmovmskb(mmreg,reg) \ - __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg) - -#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg) -#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd) - -#define prefetcht0(mem) mmx_fetch (mem, t0) -#define prefetcht1(mem) mmx_fetch (mem, t1) -#define prefetcht2(mem) mmx_fetch (mem, t2) -#define prefetchnta(mem) mmx_fetch (mem, nta) - -#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg) -#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd) - -#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm) -#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm) - -#define sfence() __asm__ __volatile__ ("sfence\n\t") - -typedef union { - float sf[4]; /* Single-precision (32-bit) value */ -} ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */ - - -#define sse_i2r(op, imm, reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "X" (imm) ) - -#define sse_m2r(op, mem, reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "X" (mem)) - -#define sse_r2m(op, reg, mem) \ - __asm__ __volatile__ (#op " %%" #reg ", %0" \ - : "=X" (mem) \ - : /* nothing */ ) - -#define sse_r2r(op, regs, regd) \ - __asm__ __volatile__ (#op " %" #regs ", %" #regd) - -#define sse_r2ri(op, regs, regd, imm) \ - __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ - : /* nothing */ \ - : "X" (imm) ) - -#define sse_m2ri(op, mem, reg, subop) \ - __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \ - : /* nothing */ \ - : "X" (mem)) - - -#define movaps_m2r(var, reg) sse_m2r(movaps, var, reg) -#define movaps_r2m(reg, var) sse_r2m(movaps, reg, var) -#define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd) - -#define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var) - -#define movups_m2r(var, reg) sse_m2r(movups, var, reg) -#define movups_r2m(reg, var) sse_r2m(movups, reg, var) -#define movups_r2r(regs, regd) sse_r2r(movups, regs, regd) - -#define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd) - -#define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd) - -#define movhps_m2r(var, reg) sse_m2r(movhps, var, reg) -#define movhps_r2m(reg, var) sse_r2m(movhps, reg, var) - -#define movlps_m2r(var, reg) sse_m2r(movlps, var, reg) -#define movlps_r2m(reg, var) sse_r2m(movlps, reg, var) - -#define movss_m2r(var, reg) sse_m2r(movss, var, reg) -#define movss_r2m(reg, var) sse_r2m(movss, reg, var) -#define movss_r2r(regs, regd) sse_r2r(movss, regs, regd) - -#define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index) -#define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index) - -#define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg) -#define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg) - -#define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg) -#define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg) - -#define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg) -#define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg) - -#define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg) -#define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg) - -#define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) -#define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) - -#define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) -#define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) - -#define movmskps(xmmreg, reg) \ - __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg) - -#define addps_m2r(var, reg) sse_m2r(addps, var, reg) -#define addps_r2r(regs, regd) sse_r2r(addps, regs, regd) - -#define addss_m2r(var, reg) sse_m2r(addss, var, reg) -#define addss_r2r(regs, regd) sse_r2r(addss, regs, regd) - -#define subps_m2r(var, reg) sse_m2r(subps, var, reg) -#define subps_r2r(regs, regd) sse_r2r(subps, regs, regd) - -#define subss_m2r(var, reg) sse_m2r(subss, var, reg) -#define subss_r2r(regs, regd) sse_r2r(subss, regs, regd) - -#define mulps_m2r(var, reg) sse_m2r(mulps, var, reg) -#define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd) - -#define mulss_m2r(var, reg) sse_m2r(mulss, var, reg) -#define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd) - -#define divps_m2r(var, reg) sse_m2r(divps, var, reg) -#define divps_r2r(regs, regd) sse_r2r(divps, regs, regd) - -#define divss_m2r(var, reg) sse_m2r(divss, var, reg) -#define divss_r2r(regs, regd) sse_r2r(divss, regs, regd) - -#define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg) -#define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd) - -#define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg) -#define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd) - -#define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg) -#define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd) - -#define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg) -#define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd) - -#define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg) -#define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd) - -#define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg) -#define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd) - -#define andps_m2r(var, reg) sse_m2r(andps, var, reg) -#define andps_r2r(regs, regd) sse_r2r(andps, regs, regd) - -#define andnps_m2r(var, reg) sse_m2r(andnps, var, reg) -#define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd) - -#define orps_m2r(var, reg) sse_m2r(orps, var, reg) -#define orps_r2r(regs, regd) sse_r2r(orps, regs, regd) - -#define xorps_m2r(var, reg) sse_m2r(xorps, var, reg) -#define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd) - -#define maxps_m2r(var, reg) sse_m2r(maxps, var, reg) -#define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd) - -#define maxss_m2r(var, reg) sse_m2r(maxss, var, reg) -#define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd) - -#define minps_m2r(var, reg) sse_m2r(minps, var, reg) -#define minps_r2r(regs, regd) sse_r2r(minps, regs, regd) - -#define minss_m2r(var, reg) sse_m2r(minss, var, reg) -#define minss_r2r(regs, regd) sse_r2r(minss, regs, regd) - -#define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op) -#define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op) - -#define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0) -#define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0) - -#define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1) -#define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1) - -#define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2) -#define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2) - -#define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3) -#define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3) - -#define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4) -#define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4) - -#define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5) -#define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5) - -#define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6) -#define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6) - -#define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7) -#define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7) - -#define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op) -#define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op) - -#define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0) -#define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0) - -#define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1) -#define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1) - -#define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2) -#define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2) - -#define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3) -#define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3) - -#define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4) -#define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4) - -#define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5) -#define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5) - -#define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6) -#define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6) - -#define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7) -#define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7) - -#define comiss_m2r(var, reg) sse_m2r(comiss, var, reg) -#define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd) - -#define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg) -#define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd) - -#define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg) -#define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd) - -#define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg) -#define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd) - -#define fxrstor(mem) \ - __asm__ __volatile__ ("fxrstor %0" \ - : /* nothing */ \ - : "X" (mem)) - -#define fxsave(mem) \ - __asm__ __volatile__ ("fxsave %0" \ - : /* nothing */ \ - : "X" (mem)) - -#define stmxcsr(mem) \ - __asm__ __volatile__ ("stmxcsr %0" \ - : /* nothing */ \ - : "X" (mem)) - -#define ldmxcsr(mem) \ - __asm__ __volatile__ ("ldmxcsr %0" \ - : /* nothing */ \ - : "X" (mem)) -#endif /* USE_MMX */ - - - - /* Optimized/fast memcpy */ - -/* - TODO : fix dll linkage problem for xine_fast_memcpy on win32 - - xine_fast_memcpy dll linkage is screwy here. - declaring as dllimport seems to fix the problem - but causes compiler warning with libxineutils -*/ -#ifdef _MSC_VER -__declspec( dllimport ) extern void *(* xine_fast_memcpy)(void *to, const void *from, size_t len); -#else -extern void *(* xine_fast_memcpy)(void *to, const void *from, size_t len); -#endif - -#ifdef HAVE_XINE_INTERNAL_H -/* Benchmark available memcpy methods */ -void xine_probe_fast_memcpy(xine_t *xine); -#endif - - -/* - * Debug stuff - */ -/* - * profiling (unworkable in non DEBUG isn't defined) - */ -void xine_profiler_init (void); -int xine_profiler_allocate_slot (char *label); -void xine_profiler_start_count (int id); -void xine_profiler_stop_count (int id); -void xine_profiler_print_results (void); - -/* - * Allocate and clean memory size_t 'size', then return the pointer - * to the allocated memory. - */ -#if !defined(__GNUC__) || __GNUC__ < 3 -void *xine_xmalloc(size_t size); -#else -void *xine_xmalloc(size_t size) __attribute__ ((__malloc__)); -#endif - -/* - * Same as above, but memory is aligned to 'alignement'. - * **base is used to return pointer to un-aligned memory, use - * this to free the mem chunk - */ -void *xine_xmalloc_aligned(size_t alignment, size_t size, void **base); - -/* - * Get user home directory. - */ -const char *xine_get_homedir(void); - -/* - * Clean a string (remove spaces and '=' at the begin, - * and '\n', '\r' and spaces at the end. - */ -char *xine_chomp (char *str); - -/* - * A thread-safe usecond sleep - */ -void xine_usec_sleep(unsigned usec); - - - /* - * Some string functions - */ - - -void xine_strdupa(char *dest, char *src); -#define xine_strdupa(d, s) do { \ - (d) = NULL; \ - if((s) != NULL) { \ - (d) = (char *) alloca(strlen((s)) + 1); \ - strcpy((d), (s)); \ - } \ - } while(0) - -/* Shamefully copied from glibc 2.2.3 */ -#ifdef HAVE_STRPBRK -#define xine_strpbrk strpbrk -#else -static inline const char *_private_strpbrk(const char *s, const char *accept) { - - while(*s != '\0') { - const char *a = accept; - while(*a != '\0') - if(*a++ == *s) - return s; - ++s; - } - - return NULL; -} -#define xine_strpbrk _private_strpbrk -#endif - -#if defined HAVE_STRSEP && !defined(_MSC_VER) -#define xine_strsep strsep -#else -static inline char *_private_strsep(char **stringp, const char *delim) { - char *begin, *end; - - begin = *stringp; - if(begin == NULL) - return NULL; - - if(delim[0] == '\0' || delim[1] == '\0') { - char ch = delim[0]; - - if(ch == '\0') - end = NULL; - else { - if(*begin == ch) - end = begin; - else if(*begin == '\0') - end = NULL; - else - end = strchr(begin + 1, ch); - } - } - else - end = xine_strpbrk(begin, delim); - - if(end) { - *end++ = '\0'; - *stringp = end; - } - else - *stringp = NULL; - - return begin; -} -#define xine_strsep _private_strsep -#endif - - -#ifdef HAVE_SETENV -#define xine_setenv setenv -#else -static inline void _private_setenv(const char *name, const char *val, int _xx) { - int len = strlen(name) + strlen(val) + 2; - char env[len]; - - sprintf(env, "%s%c%s", name, '=', val); - putenv(env); -} -#define xine_setenv _private_setenv -#endif - -/* - * Color Conversion Utility Functions - * The following data structures and functions facilitate the conversion - * of RGB images to packed YUV (YUY2) images. There are also functions to - * convert from YUV9 -> YV12. All of the meaty details are written in - * color.c. - */ - -typedef struct yuv_planes_s { - - unsigned char *y; - unsigned char *u; - unsigned char *v; - unsigned int row_width; /* frame width */ - unsigned int row_count; /* frame height */ - -} yuv_planes_t; - -void init_yuv_conversion(void); -void init_yuv_planes(yuv_planes_t *yuv_planes, int width, int height); -void free_yuv_planes(yuv_planes_t *yuv_planes); - -extern void (*yuv444_to_yuy2) - (yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int pitch); -extern void (*yuv9_to_yv12) - (unsigned char *y_src, int y_src_pitch, unsigned char *y_dest, int y_dest_pitch, - unsigned char *u_src, int u_src_pitch, unsigned char *u_dest, int u_dest_pitch, - unsigned char *v_src, int v_src_pitch, unsigned char *v_dest, int v_dest_pitch, - int width, int height); -extern void (*yuv411_to_yv12) - (unsigned char *y_src, int y_src_pitch, unsigned char *y_dest, int y_dest_pitch, - unsigned char *u_src, int u_src_pitch, unsigned char *u_dest, int u_dest_pitch, - unsigned char *v_src, int v_src_pitch, unsigned char *v_dest, int v_dest_pitch, - int width, int height); -extern void (*yv12_to_yuy2) - (unsigned char *y_src, int y_src_pitch, - unsigned char *u_src, int u_src_pitch, - unsigned char *v_src, int v_src_pitch, - unsigned char *yuy2_map, int yuy2_pitch, - int width, int height, int progressive); -extern void (*yuy2_to_yv12) - (unsigned char *yuy2_map, int yuy2_pitch, - unsigned char *y_dst, int y_dst_pitch, - unsigned char *u_dst, int u_dst_pitch, - unsigned char *v_dst, int v_dst_pitch, - int width, int height); - -#define SCALEFACTOR 65536 -#define CENTERSAMPLE 128 - -#define COMPUTE_Y(r, g, b) \ - (unsigned char) \ - ((y_r_table[r] + y_g_table[g] + y_b_table[b]) / SCALEFACTOR) -#define COMPUTE_U(r, g, b) \ - (unsigned char) \ - ((u_r_table[r] + u_g_table[g] + u_b_table[b]) / SCALEFACTOR + CENTERSAMPLE) -#define COMPUTE_V(r, g, b) \ - (unsigned char) \ - ((v_r_table[r] + v_g_table[g] + v_b_table[b]) / SCALEFACTOR + CENTERSAMPLE) - -#define UNPACK_BGR15(packed_pixel, r, g, b) \ - b = (packed_pixel & 0x7C00) >> 7; \ - g = (packed_pixel & 0x03E0) >> 2; \ - r = (packed_pixel & 0x001F) << 3; - -#define UNPACK_BGR16(packed_pixel, r, g, b) \ - b = (packed_pixel & 0xF800) >> 8; \ - g = (packed_pixel & 0x07E0) >> 3; \ - r = (packed_pixel & 0x001F) << 3; - -#define UNPACK_RGB15(packed_pixel, r, g, b) \ - r = (packed_pixel & 0x7C00) >> 7; \ - g = (packed_pixel & 0x03E0) >> 2; \ - b = (packed_pixel & 0x001F) << 3; - -#define UNPACK_RGB16(packed_pixel, r, g, b) \ - r = (packed_pixel & 0xF800) >> 8; \ - g = (packed_pixel & 0x07E0) >> 3; \ - b = (packed_pixel & 0x001F) << 3; - -extern int y_r_table[256]; -extern int y_g_table[256]; -extern int y_b_table[256]; - -extern int u_r_table[256]; -extern int u_g_table[256]; -extern int u_b_table[256]; - -extern int v_r_table[256]; -extern int v_g_table[256]; -extern int v_b_table[256]; - -/* frame copying functions */ -extern void yv12_to_yv12 - (unsigned char *y_src, int y_src_pitch, unsigned char *y_dst, int y_dst_pitch, - unsigned char *u_src, int u_src_pitch, unsigned char *u_dst, int u_dst_pitch, - unsigned char *v_src, int v_src_pitch, unsigned char *v_dst, int v_dst_pitch, - int width, int height); -extern void yuy2_to_yuy2 - (unsigned char *src, int src_pitch, - unsigned char *dst, int dst_pitch, - int width, int height); - -/* print a hexdump of the given data */ -void xine_hexdump (const char *buf, int length); - -/* - * Optimization macros for conditions - * Taken from the FIASCO L4 microkernel sources - */ -#if !defined(__GNUC__) || __GNUC__ < 3 -# define EXPECT_TRUE(x) (x) -# define EXPECT_FALSE(x) (x) -#else -# define EXPECT_TRUE(x) __builtin_expect((x),1) -# define EXPECT_FALSE(x) __builtin_expect((x),0) -#endif - -#ifdef NDEBUG -#define _x_assert(exp) \ - do { \ - if (!(exp)) \ - fprintf(stderr, "assert: %s:%d: %s: Assertion `%s' failed.\n", \ - __FILE__, __LINE__, __XINE_FUNCTION__, #exp); \ - } while(0) -#else -#define _x_assert(exp) \ - do { \ - if (!(exp)) { \ - fprintf(stderr, "assert: %s:%d: %s: Assertion `%s' failed.\n", \ - __FILE__, __LINE__, __XINE_FUNCTION__, #exp); \ - abort(); \ - } \ - } while(0) -#endif - -#define _x_abort() \ - do { \ - fprintf(stderr, "abort: %s:%d: %s: Aborting.\n", \ - __FILE__, __LINE__, __XINE_FUNCTION__); \ - abort(); \ - } while(0) - - -/****** logging with xine **********************************/ - -#ifndef LOG_MODULE - #define LOG_MODULE __FILE__ -#endif /* LOG_MODULE */ - -#define LOG_MODULE_STRING printf("%s: ", LOG_MODULE ); - -#ifdef LOG_VERBOSE - #define LONG_LOG_MODULE_STRING \ - printf("%s: (%s:%d) ", LOG_MODULE, __XINE_FUNCTION__, __LINE__ ); -#else - #define LONG_LOG_MODULE_STRING LOG_MODULE_STRING -#endif /* LOG_VERBOSE */ - -#ifdef LOG - #ifdef __GNUC__ - #define lprintf(fmt, args...) \ - do { \ - LONG_LOG_MODULE_STRING \ - printf(fmt, ##args); \ - } while(0) - #else /* __GNUC__ */ - #ifdef _MSC_VER - #define lprintf(fmtargs) \ - do { \ - LONG_LOG_MODULE_STRING \ - printf("%s", fmtargs); \ - } while(0) - #else /* _MSC_VER */ - #define lprintf(fmt, ...) \ - do { \ - LONG_LOG_MODULE_STRING \ - printf(__VA_ARGS__); \ - } while(0) - #endif /* _MSC_VER */ - #endif /* __GNUC__ */ -#else /* LOG */ - #ifdef __GNUC__ - #define lprintf(fmt, args...) do {} while(0) - #else - #ifdef _MSC_VER - #define lprintf - #else - #define lprintf(...) do {} while(0) - #endif /* _MSC_VER */ - #endif /* __GNUC__ */ -#endif /* LOG */ - -#ifdef __GNUC__ - #define llprintf(cat, fmt, args...) \ - do{ \ - if(cat){ \ - LONG_LOG_MODULE_STRING \ - printf( fmt, ##args ); \ - } \ - }while(0) -#else -#ifdef _MSC_VER - #define llprintf(cat, fmtargs) \ - do{ \ - if(cat){ \ - LONG_LOG_MODULE_STRING \ - printf( "%s", fmtargs ); \ - } \ - }while(0) -#else - #define llprintf(cat, ...) \ - do{ \ - if(cat){ \ - LONG_LOG_MODULE_STRING \ - printf( __VA_ARGS__ ); \ - } \ - }while(0) -#endif /* _MSC_VER */ -#endif /* __GNUC__ */ - -#ifdef __GNUC__ - #define xprintf(xine, verbose, fmt, args...) \ - do { \ - if((xine) && (xine)->verbosity >= verbose){ \ - xine_log(xine, XINE_LOG_TRACE, fmt, ##args); \ - } \ - } while(0) -#else -#ifdef _MSC_VER - #define xprintf(xine, verbose, fmtargs) \ - do { \ - if((xine) && (xine)->verbosity >= verbose){ \ - xine_log(xine, XINE_LOG_TRACE, fmtargs); \ - } \ - } while(0) -#else - #define xprintf(xine, verbose, ...) \ - do { \ - if((xine) && (xine)->verbosity >= verbose){ \ - xine_log(xine, XINE_LOG_TRACE, __VA_ARGS__); \ - } \ - } while(0) -#endif /* _MSC_VER */ -#endif /* __GNUC__ */ - -/* time measuring macros for profiling tasks */ - -#ifdef DEBUG -# define XINE_PROFILE(function) \ - do { \ - struct timeval current_time; \ - double dtime; \ - gettimeofday(¤t_time, NULL); \ - dtime = -(current_time.tv_sec + (current_time.tv_usec / 1000000.0)); \ - function; \ - gettimeofday(¤t_time, NULL); \ - dtime += current_time.tv_sec + (current_time.tv_usec / 1000000.0); \ - printf("%s: (%s:%d) took %lf seconds\n", \ - LOG_MODULE, __XINE_FUNCTION__, __LINE__, dtime); \ - } while(0) -# define XINE_PROFILE_ACCUMULATE(function) \ - do { \ - struct timeval current_time; \ - static double dtime = 0; \ - gettimeofday(¤t_time, NULL); \ - dtime -= current_time.tv_sec + (current_time.tv_usec / 1000000.0); \ - function; \ - gettimeofday(¤t_time, NULL); \ - dtime += current_time.tv_sec + (current_time.tv_usec / 1000000.0); \ - printf("%s: (%s:%d) took %lf seconds\n", \ - LOG_MODULE, __XINE_FUNCTION__, __LINE__, dtime); \ - } while(0) -#else -# define XINE_PROFILE(function) function -# define XINE_PROFILE_ACCUMULATE(function) function -#endif /* LOG */ - - -/******** double chained lists with builtin iterator *******/ - -typedef struct xine_node_s { - - struct xine_node_s *next, *prev; - - void *content; - - int priority; - -} xine_node_t; - - -typedef struct { - - xine_node_t *first, *last, *cur; - -} xine_list_t; - - - -xine_list_t *xine_list_new (void); - - -/** - * dispose the whole list. - * note: disposes _only_ the list structure, content must be free()d elsewhere - */ -void xine_list_free(xine_list_t *l); - - -/** - * returns: Boolean - */ -int xine_list_is_empty (xine_list_t *l); - -/** - * return content of first entry in list. - */ -void *xine_list_first_content (xine_list_t *l); - -/** - * return next content in list. - */ -void *xine_list_next_content (xine_list_t *l); - -/** - * Return last content of list. - */ -void *xine_list_last_content (xine_list_t *l); - -/** - * Return previous content of list. - */ -void *xine_list_prev_content (xine_list_t *l); - -/** - * Append content to list, sorted by decreasing priority. - */ -void xine_list_append_priority_content (xine_list_t *l, void *content, int priority); - -/** - * Append content to list. - */ -void xine_list_append_content (xine_list_t *l, void *content); - -/** - * Insert content in list. - */ -void xine_list_insert_content (xine_list_t *l, void *content); - -/** - * Remove current content in list. - * note: removes only the list entry; content must be free()d elsewhere. - */ -void xine_list_delete_current (xine_list_t *l); - -#ifndef HAVE_BASENAME -/* - * get base name - */ -char *basename (char const *name); -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tests/Makefile b/src/tests/Makefile deleted file mode 100644 index 65099fb..0000000 --- a/src/tests/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -include ../../config.mak - -TARGET = dan charlie pango pixbuf dissolve luma - -CFLAGS += -I.. $(RDYNAMIC) - -LDFLAGS += -L../modules -LDFLAGS += -L../framework -lmlt - -all: $(TARGET) - -hello: hello.o - $(CC) hello.o -o $@ -L../framework -L../modules -lmlt - -pango: pango.o - $(CC) pango.o -o $@ $(LDFLAGS) - -pixbuf: pixbuf.o - $(CC) pixbuf.o -o $@ $(LDFLAGS) - -dissolve: dissolve.o - $(CC) dissolve.o -o $@ $(LDFLAGS) - -luma: luma.o - $(CC) luma.o -o $@ $(LDFLAGS) - -dan: dan.o - $(CC) dan.o -o $@ $(LDFLAGS) - -charlie: charlie.o io.o - $(CC) charlie.o io.o -o $@ $(LDFLAGS) - -clean: - rm -f dan.o io.o charlie.o dan charlie - -depend: dan.c charlie.c io.c - $(CC) -MM $(CFLAGS) $^ 1>.depend - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/tests/charlie.c b/src/tests/charlie.c deleted file mode 100644 index 7130b1d..0000000 --- a/src/tests/charlie.c +++ /dev/null @@ -1,193 +0,0 @@ -#include -#include -#include - -#include - -#include "io.h" - -mlt_producer create_producer( char *file ) -{ - mlt_producer result = NULL; - - // 1st Line preferences - if ( strstr( file, ".inigo" ) ) - { - char *args[ 2 ] = { file, NULL }; - result = mlt_factory_producer( "inigo", args ); - } - else if ( strstr( file, ".mpg" ) ) - result = mlt_factory_producer( "mcmpeg", file ); - else if ( strstr( file, ".mpeg" ) ) - result = mlt_factory_producer( "mcmpeg", file ); - else if ( strstr( file, ".dat" ) ) - result = mlt_factory_producer( "mcmpeg", file ); - else if ( strstr( file, ".dv" ) ) - result = mlt_factory_producer( "mcdv", file ); - else if ( strstr( file, ".dif" ) ) - result = mlt_factory_producer( "mcdv", file ); - else if ( strstr( file, ".jpg" ) ) - result = mlt_factory_producer( "pixbuf", file ); - else if ( strstr( file, ".JPG" ) ) - result = mlt_factory_producer( "pixbuf", file ); - else if ( strstr( file, ".jpeg" ) ) - result = mlt_factory_producer( "pixbuf", file ); - else if ( strstr( file, ".png" ) ) - result = mlt_factory_producer( "pixbuf", file ); - - // 2nd Line fallbacks - if ( result == NULL && strstr( file, ".dv" ) ) - result = mlt_factory_producer( "libdv", file ); - else if ( result == NULL && strstr( file, ".dif" ) ) - result = mlt_factory_producer( "libdv", file ); - - return result; -} - -void transport_action( mlt_producer producer, char *value ) -{ - mlt_properties properties = mlt_producer_properties( producer ); - - switch( value[ 0 ] ) - { - case 'q': - mlt_properties_set_int( properties, "done", 1 ); - break; - case '0': - mlt_producer_set_speed( producer, 1 ); - mlt_producer_seek( producer, 0 ); - break; - case '1': - mlt_producer_set_speed( producer, -5 ); - break; - case '2': - mlt_producer_set_speed( producer, -2.5 ); - break; - case '3': - mlt_producer_set_speed( producer, -1 ); - break; - case '4': - mlt_producer_set_speed( producer, -0.5 ); - break; - case '5': - mlt_producer_set_speed( producer, 0 ); - break; - case '6': - mlt_producer_set_speed( producer, 0.5 ); - break; - case '7': - mlt_producer_set_speed( producer, 1 ); - break; - case '8': - mlt_producer_set_speed( producer, 2.5 ); - break; - case '9': - mlt_producer_set_speed( producer, 5 ); - break; - } -} - -mlt_consumer create_consumer( char *id, mlt_producer producer ) -{ - char *arg = strchr( id, ':' ); - if ( arg != NULL ) - *arg ++ = '\0'; - mlt_consumer consumer = mlt_factory_consumer( id, arg ); - if ( consumer != NULL ) - { - mlt_properties properties = mlt_consumer_properties( consumer ); - mlt_properties_set_data( properties, "transport_callback", transport_action, 0, NULL, NULL ); - mlt_properties_set_data( properties, "transport_producer", producer, 0, NULL, NULL ); - } - return consumer; -} - -void track_service( mlt_field field, void *service, mlt_destructor destructor ) -{ - mlt_properties properties = mlt_field_properties( field ); - int registered = mlt_properties_get_int( properties, "registered" ); - char *key = mlt_properties_get( properties, "registered" ); - mlt_properties_set_data( properties, key, service, 0, destructor, NULL ); - mlt_properties_set_int( properties, "registered", ++ registered ); -} - -void set_properties( mlt_service service, char *namevalue ) -{ - mlt_properties properties = mlt_service_properties( service ); - mlt_properties_parse( properties, namevalue ); -} - -void transport( mlt_producer producer ) -{ - mlt_properties properties = mlt_producer_properties( producer ); - - term_init( ); - fprintf( stderr, "Press 'q' to continue\n" ); - while( mlt_properties_get_int( properties, "done" ) == 0 ) - { - int value = term_read( ); - if ( value != -1 ) - transport_action( producer, ( char * )&value ); - } -} - -int main( int argc, char **argv ) -{ - int i; - mlt_service service = NULL; - mlt_consumer consumer = NULL; - mlt_producer producer = NULL; - mlt_playlist playlist = NULL; - - // Construct the factory - mlt_factory_init( getenv( "MLT_REPOSITORY" ) ); - - // Set up containers - playlist = mlt_playlist_init( ); - - // Parse the arguments - for ( i = 1; i < argc; i ++ ) - { - if ( !strcmp( argv[ i ], "-consumer" ) ) - { - consumer = create_consumer( argv[ ++ i ], mlt_playlist_producer( playlist ) ); - if ( consumer != NULL ) - service = mlt_consumer_service( consumer ); - } - else if ( !strstr( argv[ i ], "=" ) ) - { - if ( producer != NULL ) - mlt_playlist_append( playlist, producer ); - producer = create_producer( argv[ i ] ); - if ( producer != NULL ) - service = mlt_producer_service( producer ); - } - else - { - set_properties( service, argv[ i ] ); - } - } - - // If we have no consumer, default to sdl - if ( consumer == NULL ) - consumer = create_consumer( "sdl", mlt_playlist_producer( playlist ) ); - - // Connect producer to playlist - if ( producer != NULL ) - mlt_playlist_append( playlist, producer ); - - // Connect consumer to playlist - mlt_consumer_connect( consumer, mlt_playlist_service( playlist ) ); - - // Transport functionality - transport( mlt_playlist_producer( playlist ) ); - - // Close the services - mlt_consumer_close( consumer ); - mlt_playlist_close( playlist ); - - // Close the factory - mlt_factory_close( ); - - return 0; -} diff --git a/src/tests/clock16ntsc.pgm b/src/tests/clock16ntsc.pgm deleted file mode 100644 index 61e64ad3fb834f1c08414c1d8419182318a6ac0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 691217 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 diff --git a/src/tests/clock16pal.pgm b/src/tests/clock16pal.pgm deleted file mode 100644 index 4d7b0fcd8031f6eabc877d2e2c86e0e287e52f1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 829457 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

fu_-$0n!ENO*?N-4XIY^F!tvJ9Y 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

_UU)Gmc>C3|E&C#$-5a49hvDxSOQsl>n!) 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

  • Am0tf^8Q5vEcc@|H06d+*de zVald(*q$R@UpTyM&gV7Oq%(TAp^_U>@)^3_5Zpd%blouXIgPPPqd25{Njk?7me5jd zm&V(LYL0#~dh4y@Gg@sm(rJx+UPCW7#AZYGItu?j3a>WkwGC1|-;SQ1S-D}Io^MW@ z&;IhpDCG0uU*ZMF^v&>mp1O%|IG}t!U?bo)74rlgt~l%y^gkwY9AT0}y2=4t4s@9# zL~~^H9BD-dVLFmqjTBmg_8QcSDEONwTCstcjliW1z1r~HhMmr~+Yl~pydaPp&w;0B z;Kda2?Zy+t?Z%@5UH69+`P{ysBKSguY6z#jQFOzxHefj56ZBf(2^vuxlV8Ovjwr|R ze7xj9RyiUqM~LR2);Z!mM_SQ=nU17ZL!vdfbq&^QPzxKV*jR>$4RmEgZZ`6$4QFjb z?l$nn4dvalvAO}Co@u+`znUVueV+MlxqepV^EZR?`RBw9^n(#M9QT4Z96yb?gT8}s z9J@;$M;ghI$8uoH9IWQZ=s8N!F)o$pfJ{d+t0B=Ef^`kjYfvwu;BTTVTQ)Vp%7)Zz zm9rz#HhLTEk&=gp26+RAh?7a~#O4 zDxBj;BRLXS4s4l2tvT3r4$gB#FLY=`hif`g^?`jff~h;f9IarEUNE#7jFB7i@48d8 zgTu(@bPZwdjxcXa*k4bmu^jzr4z4TgUv!v#;pk*@jMqpfHby_4WA~7>n@C(Y7;fvR zc5u}4nfgX0B%gU@hbfK_XE)jjoyyzg5_gh>&Xv)zRwIqp;JgO)B1(wZz*aWm%tjiu z;i)>;ZQMaDZk!4)ZaAlBQ*Qi-Jw4yVoSv_5)A>65)f8<$AAPx}H~!Vr&zI%OXFzZe z@2GJ3eBeI=h67&Wz)sMg5}lww9_TodNREhA4xQz|mpLfS!K`ycdk&fCP@9fet0B-D z=d)Ua^%{xA2D-8lWj4aphIe`*DkbIqzA)hJ1 z0jzLzFR4sf2QVD)37T8t&?^qtaqJ;=9D)-xD>-6TIS9+4dS`{z9C4mQB03~zXocy3 zwTAFo;|qdp-Yn8@aLNtQWS&5_k}q!k^b+z6)c1XHwv z>3YF9w-NhIx9Ic?%je@#+-?jjpLGH{rXft*5r!y^v@M~eCzP&o46`ZB?>W-7g}Jgh zcRDXy_Hs+-6s|6{tV@&6I=!LGXVDklO2H9#!;wbWtx4#7nuAa1{xUj;)=1!L!N6L*`*wu|2rFKKy4qo|k%4frHu=#8*aeU*`62(ER zaX9%L={O{k1AJd4-g2bY98sQQg1~c(7kLgwbmY()(O!dD*r3Ell9dhl>nM=f5UCAr zZ6m^MyeN?yqSNy;;OUvO8&3ku8;`f?{20*=c6#HHKJxj9w-JKl%_;I(V>pl{4(kMs zDvrGg#qkn(f_5DTv&aFQphc1+-g4-dIcUv6uXB{1V?qMY5h*&v%NjDR!LMrwyhhNQ zD3sX1RyI(xA$%PLG8;+MhO@Tex()H&1}--id>DQ&1zz1SUQB`QMv~iSO4k|ryk4?= zmI=E~a6H`R^FzQ2NB5G-{UL?}UE;VKy@S3BRUCInUsZ7(hklVmDmmn<96^>NRCCbl z9K7d9DLMetAa~mOYgMTkYV>fc?jj^B4yy1vb9N{e?x7*Ku?=9^KHQ#)vYzkw# z!Ze;k+7`NfVSm{?TIr13I*(vFhq{e8xzU&1pxeQ|@>whFVvU`kBh0Eew2mWpLhCF? zh_}lt?oxUVJE8m08nIp@Ol)XZHejQ;5X&5anuA{F5P6Pd3mul|h}IgS zb&V*m5h^y)n2o$@L+du&(=#PEP7aqF=;;}@8&CC+&)%W^q>x~&(OZ0O@K3|wEpO=Ohj(|JpAjRRegq-70FLK054z1-NmpQU% zj?!~XU_FOSbclY#Z3JUF!Qr%m!|MgES~cg}85e!CH_H&W!Y>h`lfJrnj>vn7?#a_c#Tl8F`DVjuWjhuMwqLMIz1=M=Wx9-iuoLGI8rK( zl#b)&nb0XRI+eN8YmGEsgMJZ(dJ}~e8`;c8xZ2>?HaNH8ot~-1jayMy_oFoVjM$B9 zhm+6Wx->MOkNC1SpQmr;zoP=@v&wMjPtca)nEXj;KD&;?IY57mm3I6hheC2FRyp*R zgIeZ@(;TThhd^}bwMH7R!HEsx=o}(8QkV^?+JH{auVGKmjN1rX+#ux!_Fl>}(2FTb zy8$e3WX$Jp1?O{jf_`fo&~G6H2Y18q2Kfz#X*jSY4)i@0TX9U5Dh}6i*srRH9LMwN zBnP_6p|u?NGDo=PNZ~o6MMrY2!F!DroYx2x8~DlwW;Qghqe#_8A8sS?s}xIa#N2Lh zb^|;;ckiZ*WIo5;KtIUbK>vH98xE=BAl5j%mQd+9(n=1s{a+eYg#BaYHIMu=i5T)eZB-6vS?TU#76_ z;DjXkyyejIc{y_fy@WL!i*-vJQpMrjaS&@9ddHDga_B5asX4Y!wag*V9Q}EYnQ%V$ z*$BpUf+<%vuvRdx7wp4r1fQNWbc12}JZn~peD>SHzVn$g(1II|o)kxF$C0)t9BxyX zzblMs3)5wD?sN_j8)Gq@WA>1wa-%Q15!ViC*Ejmf=P+ZJ%5bDn9Nb>g>X*T?5UGu@wGH6(?79u&r4;YIN#GZwRy-S4XvjKhUjj zz2l(QI2gwvS>#ABIj~g@+;T9>98VHw=qJcCG_N@lc@A52^y4++ z#74loC`*?7b2hV)PHm{&2D!KqBsZ+p4W-?fzaf~<%<{(U_l$f#|3cglKBTyTHVwzm z1o@0CagcY=gyNvrIC#eae5>+fAfaF`3hue)~wquqz;C68Q2;}psHlHsLH-sxfRyfe_yb;4ebcAOT ziesT-jU$8OP)H8(Do2pz$e=m+bqqNiU_P-ioK`ShFBt1KQpk;`xH zJiL4!PD7ZoBTUy4rg0q7o>246x4tPHmgY#=6&7vb=z0x0n^(Vd?#I>PawCo17#sPV zLvW-wcIg#|*4d?U9HW-dF`A>_jLzpZxP=Y+O%zsaWHlS`(nh%2094(bI=4YDZYWOA zx1gtI?8Ow;ZdkVN8u0e{DyAL0qK|z3=D*|=9DF_>^f{&Bu<|*H;$YS|vN;Y|a%fgL z^p=BK=7`Z8{5prwb4Wx-z`BOeYec+>LW>P@WkYE;G)o)dY6EZ^-r<>Z8!wTkXG(57 zkDi{NO?12Qq})EUdgGCd`J6#;81JaCD;xnQ=(S{ugE~QL);IzkhhUKdmK?*g9Mn52 zBF&M&b4XrXQEQD9UW0xUg%%qjD;t>E$e}iXyN%>-gM2H6k{i~0DfaCK@?y$yA5hs1 zGoLqz(;MB}DUtd7pHcZ7^bH~Uk_u)x?t@=bac($J#WDFOxZ?2cpznxw96^g5u;fUw z%E4F;YMCQgbMWgNrRSIs>p4{G8i~9{jMxY;8`$e8In+iPx4|`odr)^9gxs*Z!Clgv zo~?YID8GG{>y5a44ia`Ng9OJi_J%{>5iUxtIJj3;fR^xNFQJ1LIbg|=W|afC9Mm#L zwC3Q~Ib@z=7MIVX;x$6W2Hpzx*$bv|8@gt27~P=m%kJ2Au>X9{)ez?E2>Wdb`{)U^ z-+bq23j68`@wTwvZ0FgwqqrZgi({iLp=orr-(;B7MSP|{WZNH00CRgUDABTjSV z^c=X2Br6=gguObvj7RMo5U`c*aIx`u_F^NC*hptK zBGrayZNtCY_;}pih9fsVLY$ueUbeb{+6^q9-^VR)XqKO6yo<@_^)lr1uYv@}!|V<8 z1L1}PU*aI&Q~3#b2YsjVjw6ZV$R#;KEJyeD2~s z^US*qZgGQrE5*6nSTIR;_iU|hpr_|!cQE34d(G|hoNYq%2B)9X<#U*@4!1!!gDJYfRJR-P?ci9- zXWl>u+;9jx!gPuwpX2DiCk$;0N2M$5+QPVO9!0T%XR}V!vHf#I-E(847SjpAU|I0TMk_m2fFa%7Yo z0hS|tnS<9HqIC|D=O|xX3HBQNizwWiD74t1RyIP+hHhyiMs0+-4gd6FM<#&DFk)jFDK?Uu4c*d4gxZj-Z2)dVxwxT`8`SN_2hrP&4TpZ|kx2p@{b=br`KaQrlx;$YS|fR<3;IPypiz2zu1M}XxJXpZQ04w>f&@EZKW z2KOe)vSm}lS2l)XHpFTJSlbZXJhN_tek+BP8}@rC`09rBVv5Lan6IXo%Ny{!DZJho zem*B@2$vx*sVp(_`P=}*u}FM^rWMEOI>+I@sv>h7c_c@2%MrNDQG1SU@E1`fOg4&avqn zCpS{dy1ci~8oe=mZD|8m8{ihw zT|hdsZUZdlai9@G2v}+tf$MI+3 z2|7}8=vO&d%MrZH!D|l5I!Ea_;C$XxBfZ0f~v;nJ)oNhyTw?WGd@#;n% zyCKQv8Dk=!|0DAaG;TQVC6+ieisLTj9Y=uUkS=m$mK*_=gI(r`*Bp{{4#0DWvUyr| zu@Snmft!tdYD4NaCI`3;ZgC?H?}xgqTa zWp-m2dSf*5IaNcLyCY1kIP$lIsd~a;G=-_ULbomKBb#Hy##l{fk$OHoZ90d_x|DW< zUq(uy>+a*DMfvH zCgcXWx^ZJdyK!}BJ|BJgntV>1&y3<=^LYr41C<=gRgPfG5%JE7L~}^iIV{f+>os_> z5wo(9)NEu@8^GE|klO%G&ne}`v%=H!pCoo8RXfP*x_tS3&^Vu>SYs(CW z{hErs#NjB8*Q8V&pyTjQ(6X0Rgo_-Q+=!4H_UeZ9Vv6u~!+JF(CZFFu#C&GIP)Q~@9*8p>5jPy1;$YS|_*Yes zJC2A&4oq^ST;&M29NaR8M01GOIj%!dcijCxEL!~wrMW_v#+c=$d8``_)Nh$80 z3A=&bZeYtB=DR7gC#dv>na^Km^LdLt@);EzE0A|omL)YD)Dj2ro(iWpfIANURTY`z zh*;#nBuCIHM;^NIjgx{8#?){SO9hYP!a8|cg(VQR(k za!u&b&>Y$qQBsJFaI>L*9Yyy(isp?J#BD6pyA6JE!&^l9F(o&c)ALQj(=%>2uFadz z@Y^Y4IiIbURD}6_z(&#~4(B};MsaX&s(5Q0faCD<8E_n6K1WLq{VE4(IkGKt2sH=i zIg~G=BoQ0oW+U0s2BtRTZ=|Gj8!xe^=ND9`XX3q-FuOtAZak48pTCV%Ix>>dSk}BGUoG9 zs(dyD^e+&>@pB`eABNviA#R}W7aETHh&O_%)8qjw83^pjJ6(%MrWGA<-Q8I!DS*aI{*%G`(PMx4}1qDdk4k zcin`o%iIpGKKb0Q;m|6MQD_N=*%Rh%3S+uLSvKbv8*9=zhujF3&jEI$&wPfzP8qd) z4l#Ce!x5wGLY&>2gdRpl3%y2uv60klq){6&Ya3y1L-1CLPHx;BD4(wnuyt3Dg?vU{ zP)U~0(>4_uyNweV4*CTB=}5&9n9q>o5HE7{AUQHw4qkIi6le}$okJov*rPKiHt3ZN z>SdHLvynz^$k#TY)AK8X?lxYGJUu^0o}Q@}Q>1p|Nzv`bVf&>Z$UN7S1r@nR#?Y~V{9In_o|x8W~taBrn>r)ToL6!OIs zvE4{``#f`;5zkx0Z>I>>HzM*G{X*peBcE4BHH7#I#}eTU2i*}8OB{gWa8J++X~iLV zRVBu8 -#include -#include -#include - - - -int main( int argc, char **argv ) -{ - mlt_properties p = mlt_properties_parse_yaml( argv[1] ); - mlt_properties q = mlt_properties_new(); - mlt_properties_set_data( q, "metadata", p, 0, ( mlt_destructor )mlt_properties_close, ( mlt_serialiser )mlt_properties_serialise_yaml ); - printf( "%s", mlt_properties_get( q, "metadata" ) ); - mlt_properties_close( q ); - - mlt_repository repo = mlt_factory_init( NULL ); - mlt_properties metadata = mlt_repository_metadata( repo, producer_type, "avformat" ); - if ( metadata ) - { - char *s = mlt_properties_serialise_yaml( metadata ); - printf( "%s", s ); - free( s ); - } - mlt_factory_close(); - return 0; -} diff --git a/src/tests/dissolve.c b/src/tests/dissolve.c deleted file mode 100644 index d9ce2d7..0000000 --- a/src/tests/dissolve.c +++ /dev/null @@ -1,71 +0,0 @@ - -#include - -#include - -int main( int argc, char **argv ) -{ - char temp[ 132 ]; - char *file1 = NULL; - char *file2 = NULL; - - mlt_factory_init( "../modules" ); - - if ( argc < 3 ) - { - fprintf( stderr, "usage: dissolve file1.mpeg file2.mpeg\n" ); - return 1; - } - else - { - file1 = argv[ 1 ]; - file2 = argv[ 2 ]; - } - - // Start the consumer... - mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" ); - - // Create the producer(s) - mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 ); - mlt_producer dv2 = mlt_factory_producer( "mcmpeg", file2 ); - - mlt_playlist playlist1 = mlt_playlist_init(); - mlt_playlist_append_io( playlist1, dv1, 0.0, 5.0 ); - - mlt_playlist playlist2 = mlt_playlist_init(); - mlt_playlist_blank( playlist2, 2.9 ); - mlt_playlist_append( playlist2, dv2 ); - - // Register producers(s) with a multitrack object - mlt_multitrack multitrack = mlt_multitrack_init( ); - mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist1 ), 0 ); - mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist2 ), 1 ); - - // Define a transition - mlt_transition transition = mlt_factory_transition( "luma", NULL ); - mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 ); - mlt_transition_set_in_and_out( transition, 3.0, 5.0 ); - - // Buy a tractor and connect it to the filter - mlt_tractor tractor = mlt_tractor_init( ); - mlt_tractor_connect( tractor, mlt_transition_service( transition ) ); - - // Connect the tractor to the consumer - mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) ); - - // Do stuff until we're told otherwise... - fprintf( stderr, "Press return to continue\n" ); - fgets( temp, 132, stdin ); - - // Close everything... - mlt_consumer_close( consumer ); - mlt_tractor_close( tractor ); - mlt_transition_close( transition ); - mlt_multitrack_close( multitrack ); - mlt_playlist_close( playlist1 ); - mlt_playlist_close( playlist2 ); - mlt_producer_close( dv1 ); - mlt_producer_close( dv2 ); - - return 0; -} diff --git a/src/tests/hello.c b/src/tests/hello.c deleted file mode 100644 index 4914304..0000000 --- a/src/tests/hello.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include - -mlt_producer create_playlist( int argc, char **argv ) -{ - // We're creating a playlist here - mlt_playlist playlist = mlt_playlist_init( ); - - // We need the playlist properties to ensure clean up - mlt_properties properties = mlt_playlist_properties( playlist ); - - // Loop through each of the arguments - int i = 0; - for ( i = 1; i < argc; i ++ ) - { - // Definie the unique key - char key[ 256 ]; - - // Create the producer - mlt_producer producer = mlt_factory_producer( NULL, argv[ i ] ); - - // Add it to the playlist - mlt_playlist_append( playlist, producer ); - - // Create a unique key for this producer - sprintf( key, "producer%d", i ); - - // Now we need to ensure the producers are destroyed - mlt_properties_set_data( properties, key, producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); - } - - // Return the playlist as a producer - return mlt_playlist_producer( playlist ); -} - -mlt_producer create_tracks( int argc, char **argv ) -{ - // Create the field - mlt_field field = mlt_field_init( ); - - // Obtain the multitrack - mlt_multitrack multitrack = mlt_field_multitrack( field ); - - // Obtain the tractor - mlt_tractor tractor = mlt_field_tractor( field ); - - // Obtain a composite transition - mlt_transition transition = mlt_factory_transition( "composite", "10%,10%:15%x15%" ); - - // Create track 0 - mlt_producer track0 = create_playlist( argc, argv ); - - // Get the length of track0 - mlt_position length = mlt_producer_get_playtime( track0 ); - - // Create the watermark track - mlt_producer track1 = mlt_factory_producer( "fezzik", "pango:" ); - - // Get the properties of track1 - mlt_properties properties = mlt_producer_properties( track1 ); - - // Set the properties - mlt_properties_set( properties, "text", "Hello\nWorld" ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", length - 1 ); - mlt_properties_set_position( properties, "length", length ); - - // Now set the properties on the transition - properties = mlt_transition_properties( transition ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", length - 1 ); - - // Add our tracks to the multitrack - mlt_multitrack_connect( multitrack, track0, 0 ); - mlt_multitrack_connect( multitrack, track1, 1 ); - - // Now plant the transition - mlt_field_plant_transition( field, transition, 0, 1 ); - - // Now set the properties on the transition - properties = mlt_tractor_properties( tractor ); - - // Ensure clean up and set properties correctly - mlt_properties_set_data( properties, "multitrack", multitrack, 0, ( mlt_destructor )mlt_multitrack_close, NULL ); - mlt_properties_set_data( properties, "field", field, 0, ( mlt_destructor )mlt_field_close, NULL ); - mlt_properties_set_data( properties, "track0", track0, 0, ( mlt_destructor )mlt_producer_close, NULL ); - mlt_properties_set_data( properties, "track1", track1, 0, ( mlt_destructor )mlt_producer_close, NULL ); - mlt_properties_set_data( properties, "transition", transition, 0, ( mlt_destructor )mlt_transition_close, NULL ); - mlt_properties_set_position( properties, "length", length ); - mlt_properties_set_position( properties, "out", length - 1 ); - - // Return the tractor - return mlt_tractor_producer( tractor ); -} - -int main( int argc, char **argv ) -{ - // Initialise the factory - if ( mlt_factory_init( NULL ) == 0 ) - { - // Create the default consumer - mlt_consumer hello = mlt_factory_consumer( NULL, NULL ); - - // Create a producer using the default normalising selecter - mlt_producer world = create_tracks( argc, argv ); - - // Connect the producer to the consumer - mlt_consumer_connect( hello, mlt_producer_service( world ) ); - - // Start the consumer - mlt_consumer_start( hello ); - - // Wait for the consumer to terminate - while( !mlt_consumer_is_stopped( hello ) ) - sleep( 1 ); - - // Close the consumer - mlt_consumer_close( hello ); - - // Close the producer - mlt_producer_close( world ); - - // Close the factory - mlt_factory_close( ); - } - else - { - // Report an error during initialisation - fprintf( stderr, "Unable to locate factory modules\n" ); - } - - // End of program - return 0; -} - diff --git a/src/tests/io.c b/src/tests/io.c deleted file mode 100644 index 431003d..0000000 --- a/src/tests/io.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * io.c -- dv1394d client demo input/output - * Copyright (C) 2002-2003 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* System header files */ -#include -#include -#include -#include -#include -#include - -/* Application header files */ -#include "io.h" - -char *chomp( char *input ) -{ - if ( input != NULL ) - { - int length = strlen( input ); - if ( length && input[ length - 1 ] == '\n' ) - input[ length - 1 ] = '\0'; - if ( length > 1 && input[ length - 2 ] == '\r' ) - input[ length - 2 ] = '\0'; - } - return input; -} - -char *trim( char *input ) -{ - if ( input != NULL ) - { - int length = strlen( input ); - int first = 0; - while( first < length && isspace( input[ first ] ) ) - first ++; - memmove( input, input + first, length - first + 1 ); - length = length - first; - while ( length > 0 && isspace( input[ length - 1 ] ) ) - input[ -- length ] = '\0'; - } - return input; -} - -char *strip_quotes( char *input ) -{ - if ( input != NULL ) - { - char *ptr = strrchr( input, '\"' ); - if ( ptr != NULL ) - *ptr = '\0'; - if ( input[ 0 ] == '\"' ) - strcpy( input, input + 1 ); - } - return input; -} - -char *get_string( char *output, int maxlength, char *use ) -{ - char *value = NULL; - strcpy( output, use ); - if ( trim( chomp( fgets( output, maxlength, stdin ) ) ) != NULL ) - { - if ( !strcmp( output, "" ) ) - strcpy( output, use ); - value = output; - } - return value; -} - -int *get_int( int *output, int use ) -{ - int *value = NULL; - char temp[ 132 ]; - *output = use; - if ( trim( chomp( fgets( temp, 132, stdin ) ) ) != NULL ) - { - if ( strcmp( temp, "" ) ) - *output = atoi( temp ); - value = output; - } - return value; -} - -/** This stores the previous settings -*/ - -static struct termios oldtty; -static int mode = 0; - -/** This is called automatically on application exit to restore the - previous tty settings. -*/ - -void term_exit(void) -{ - if ( mode == 1 ) - { - tcsetattr( 0, TCSANOW, &oldtty ); - mode = 0; - } -} - -/** Init terminal so that we can grab keys without blocking. -*/ - -void term_init( ) -{ - struct termios tty; - - tcgetattr( 0, &tty ); - oldtty = tty; - - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); - tty.c_oflag |= OPOST; - tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); - tty.c_cflag &= ~(CSIZE|PARENB); - tty.c_cflag |= CS8; - tty.c_cc[ VMIN ] = 1; - tty.c_cc[ VTIME ] = 0; - - tcsetattr( 0, TCSANOW, &tty ); - - mode = 1; - - atexit( term_exit ); -} - -/** Check for a keypress without blocking infinitely. - Returns: ASCII value of keypress or -1 if no keypress detected. -*/ - -int term_read( ) -{ - int n = 1; - unsigned char ch; - struct timeval tv; - fd_set rfds; - - FD_ZERO( &rfds ); - FD_SET( 0, &rfds ); - tv.tv_sec = 0; - tv.tv_usec = 250; - n = select( 1, &rfds, NULL, NULL, &tv ); - if (n > 0) - { - n = read( 0, &ch, 1 ); - tcflush( 0, TCIFLUSH ); - if (n == 1) - return ch; - return n; - } - return -1; -} - -char get_keypress( ) -{ - char value = '\0'; - int pressed = 0; - - fflush( stdout ); - - term_init( ); - while ( ( pressed = term_read( ) ) == -1 ) ; - term_exit( ); - - value = (char)pressed; - - return value; -} - -void wait_for_any_key( char *message ) -{ - if ( message == NULL ) - printf( "Press any key to continue: " ); - else - printf( "%s", message ); - - get_keypress( ); - - printf( "\n\n" ); -} - -void beep( ) -{ - printf( "%c", 7 ); - fflush( stdout ); -} diff --git a/src/tests/io.h b/src/tests/io.h deleted file mode 100644 index f97e69e..0000000 --- a/src/tests/io.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * io.h -- dv1394d client demo input/output - * Copyright (C) 2002-2003 Ushodaya Enterprises Limited - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _DEMO_IO_H_ -#define _DEMO_IO_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -extern char *chomp( char * ); -extern char *trim( char * ); -extern char *strip_quotes( char * ); -extern char *get_string( char *, int, char * ); -extern int *get_int( int *, int ); -extern void term_init( ); -extern int term_read( ); -extern void term_exit( ); -extern char get_keypress( ); -extern void wait_for_any_key( char * ); -extern void beep( ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tests/luma.c b/src/tests/luma.c deleted file mode 100644 index dabb878..0000000 --- a/src/tests/luma.c +++ /dev/null @@ -1,75 +0,0 @@ - -#include - -#include - -int main( int argc, char **argv ) -{ - char temp[ 132 ]; - char *file1 = NULL; - char *file2 = NULL; - char *wipe = NULL; - - mlt_factory_init( "../modules" ); - - if ( argc < 4 ) - { - fprintf( stderr, "usage: luma file1.mpeg file2.mpeg wipe.pgm\n" ); - return 1; - } - else - { - file1 = argv[ 1 ]; - file2 = argv[ 2 ]; - wipe = argv[ 3 ]; - } - - // Start the consumer... - mlt_consumer consumer = mlt_factory_consumer( "bluefish", "NTSC" ); - - // Create the producer(s) - mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 ); - mlt_producer dv2 = mlt_factory_producer( "mcmpeg", file2 ); - - mlt_playlist playlist1 = mlt_playlist_init(); - mlt_playlist_append_io( playlist1, dv1, 0.0, 5.0 ); - - mlt_playlist playlist2 = mlt_playlist_init(); - mlt_playlist_blank( playlist2, 2.9 ); - mlt_playlist_append( playlist2, dv2 ); - - // Register producers(s) with a multitrack object - mlt_multitrack multitrack = mlt_multitrack_init( ); - mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist1 ), 0 ); - mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist2 ), 1 ); - - // Define a transition - mlt_transition transition = mlt_factory_transition( "luma", wipe ); - mlt_properties_set( mlt_transition_properties( transition ), "filename", wipe ); - mlt_properties_set_double( mlt_transition_properties( transition ), "softness", 0.1 ); - mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 ); - mlt_transition_set_in_and_out( transition, 3.0, 5.0 ); - - // Buy a tractor and connect it to the filter - mlt_tractor tractor = mlt_tractor_init( ); - mlt_tractor_connect( tractor, mlt_transition_service( transition ) ); - - // Connect the tractor to the consumer - mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) ); - - // Do stuff until we're told otherwise... - fprintf( stderr, "Press return to continue\n" ); - fgets( temp, 132, stdin ); - - // Close everything... - mlt_consumer_close( consumer ); - mlt_tractor_close( tractor ); - mlt_transition_close( transition ); - mlt_multitrack_close( multitrack ); - mlt_playlist_close( playlist1 ); - mlt_playlist_close( playlist2 ); - mlt_producer_close( dv1 ); - mlt_producer_close( dv2 ); - - return 0; -} diff --git a/src/tests/pango.c b/src/tests/pango.c deleted file mode 100644 index fb5e19a..0000000 --- a/src/tests/pango.c +++ /dev/null @@ -1,77 +0,0 @@ - -#include - -#include - -int main( int argc, char **argv ) -{ - char temp[ 132 ]; - char *file1 = NULL; - char *text = NULL; - - mlt_factory_init( "../modules" ); - - if ( argc < 3 ) - { - fprintf( stderr, "usage: pango file.mpeg text_to_display\n" ); - return 1; - } - else - { - file1 = argv[ 1 ]; - text = argv[ 2 ]; - } - - // Start the consumer... - mlt_consumer consumer = mlt_factory_consumer( "bluefish", "NTSC" ); - - // Create the producer(s) - mlt_playlist pl1 = mlt_playlist_init(); - mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 ); - mlt_playlist_append( pl1, dv1 ); - - mlt_playlist pl2 = mlt_playlist_init(); - mlt_producer title = mlt_factory_producer( "pango", NULL ); //"Mutton Lettuce Tomato" ); - mlt_playlist_append( pl2, title ); - mlt_properties_set( mlt_producer_properties( title ), "font", "Sans Bold 36" ); - mlt_properties_set( mlt_producer_properties( title ), "text", text ); - mlt_properties_set_int( mlt_producer_properties( title ), "bgcolor", 0x0000007f ); - mlt_properties_set_int( mlt_producer_properties( title ), "pad", 8 ); - mlt_properties_set_int( mlt_producer_properties( title ), "align", 1 ); - mlt_properties_set_int( mlt_producer_properties( title ), "x", 200 ); - mlt_properties_set_int( mlt_producer_properties( title ), "y", 40 ); - mlt_properties_set_double( mlt_producer_properties( title ), "mix", 0.8 ); - - // Register producers(s) with a multitrack object - mlt_multitrack multitrack = mlt_multitrack_init( ); - mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl1 ), 0 ); - mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl2 ), 1 ); - - // Define a transition - mlt_transition transition = mlt_factory_transition( "composite", NULL ); - mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 ); - mlt_transition_set_in_and_out( transition, 0.0, 9999.0 ); - - // Buy a tractor and connect it to the filter - mlt_tractor tractor = mlt_tractor_init( ); - mlt_tractor_connect( tractor, mlt_transition_service( transition ) ); - - // Connect the tractor to the consumer - mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) ); - - // Do stuff until we're told otherwise... - fprintf( stderr, "Press return to continue\n" ); - fgets( temp, 132, stdin ); - - // Close everything... - mlt_consumer_close( consumer ); - mlt_tractor_close( tractor ); - mlt_transition_close( transition ); - mlt_multitrack_close( multitrack ); - mlt_playlist_close( pl1 ); - mlt_playlist_close( pl2 ); - mlt_producer_close( dv1 ); - mlt_producer_close( title ); - - return 0; -} diff --git a/src/tests/pixbuf.c b/src/tests/pixbuf.c deleted file mode 100644 index fd0f0b6..0000000 --- a/src/tests/pixbuf.c +++ /dev/null @@ -1,72 +0,0 @@ - -#include - -#include - -int main( int argc, char **argv ) -{ - char temp[ 132 ]; - char *file1 = NULL; - char *file2 = NULL; - - mlt_factory_init( "../modules" ); - - if ( argc < 3 ) - { - fprintf( stderr, "usage: pixbuf file.mpeg file.{png,jpg,etc}\n" ); - return 1; - } - else - { - file1 = argv[ 1 ]; - file2 = argv[ 2 ]; - } - - // Start the consumer... - mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" ); - - // Create the producer(s) - mlt_playlist pl1 = mlt_playlist_init(); - mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 ); - mlt_playlist_append( pl1, dv1 ); - - mlt_playlist pl2 = mlt_playlist_init(); - mlt_producer overlay = mlt_factory_producer( "pixbuf", file2 ); - mlt_playlist_append( pl2, overlay ); - mlt_properties_set_int( mlt_producer_properties( overlay ), "x", 600 ); - mlt_properties_set_int( mlt_producer_properties( overlay ), "y", 460 ); - mlt_properties_set_double( mlt_producer_properties( overlay ), "mix", 0.8 ); - - // Register producers(s) with a multitrack object - mlt_multitrack multitrack = mlt_multitrack_init( ); - mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl1 ), 0 ); - mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl2 ), 1 ); - - // Define a transition - mlt_transition transition = mlt_factory_transition( "composite", NULL ); - mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 ); - mlt_transition_set_in_and_out( transition, 0.0, 9999.0 ); - - // Buy a tractor and connect it to the filter - mlt_tractor tractor = mlt_tractor_init( ); - mlt_tractor_connect( tractor, mlt_transition_service( transition ) ); - - // Connect the tractor to the consumer - mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) ); - - // Do stuff until we're told otherwise... - fprintf( stderr, "Press return to continue\n" ); - fgets( temp, 132, stdin ); - - // Close everything... - mlt_consumer_close( consumer ); - mlt_tractor_close( tractor ); - mlt_transition_close( transition ); - mlt_multitrack_close( multitrack ); - mlt_playlist_close( pl1 ); - mlt_playlist_close( pl2 ); - mlt_producer_close( dv1 ); - mlt_producer_close( overlay ); - - return 0; -} diff --git a/src/tests/setenv b/src/tests/setenv deleted file mode 100644 index 44cee49..0000000 --- a/src/tests/setenv +++ /dev/null @@ -1,7 +0,0 @@ -export MLT_REPOSITORY=`pwd`/../modules - -export LD_LIBRARY_PATH=`pwd`/../framework:\ -`pwd`/../modules/bluefish:\ -`pwd`/../../../bluefish/lib:\ -`pwd`/../../../mpeg_sdk_demo/bin:\ -`pwd`/../../../dv_sdk diff --git a/src/tests/test.png b/src/tests/test.png deleted file mode 100644 index b3fca64519876231ae9a060fc194a0ae48244fd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 1352 zc-jF-1-JT%P)Q2Ue;Z@vP-uW*q~F{#Qkvx3{iucMMBURf(ro( z64WDz%3wsI1WiZ?IwmqfE=>#|LBSY)C;}3QD2(82BPa;o3Yo5hZNR#99qZa2f1I_H ztzGq(@2_*d%lmxq_4@>AL{Ystz*E3%(8@tLfC8W$@PYO#i2cA(x63(@PM;VBR0zBZ zsDLq@BESzc0Gr${XE4` z1|ntJ0SGg&TT#7n-^VOm1LP#zVloOEUoK*PO)iZ~?3fIKZ+`3pz?LmDX}oDv8-aU) zg>j&wdadZGpWHfwAkV6w>%po_8W!8RaAkmwZr!a5X4uFyCr$Q5SsnWjit2q9*fZMd z9E-%}x?(0zFayy1bCC8MVV<6D1t1cIGrt5mcsjs$=YoX7S~4|NZkO}C?5JM08kjs9 zFcj7}?&(9Ruwb_tC@nHlV3Wzp&@Gb$l-iBdRA*89h+Zx?15rA=BZ+GM_Ia94Nx-DU z(X0%KbuZZY^sTXc{HBAN>MR7%+aKlCO;@>aMekmAo1O=n2FE>pM54M?)+~wIN386A z!@<`ZO3BHLyL%FV1ezl@Qc-H=;5*}ad`cE~jWtnOW@f!=XG>i%7PB-03LpgRJkrgK zm8~@Hzs_%eh2nF2kNN2eMq|GY&|??@B#T+_$(pf@D>UNoi*oREFSDj)W6PES@O6cG zzQISAKSH)eVoO3yTQ2rfx8)jxL$RwUH8HWo#NqD)3BJ?ZZddsf3AC#Ki)PvwS7_vV zPlQ>kTG{mZ3g)eCC{RK3XAoU0l3r}8U_Op9YZb^ z?EobOdXH}F3^OpOpR~&#;idQ5Is3;g0LqGtY+F%+HA@-+eW)sv4_+%Ctr4^j0XYY7 zvscfk`zD&Hz9%ETYG6=f>HAk{KCgF|3B^V}tSceIBt}3_pAVuXtq6#5WJmQffO&tm z3NmN96{A5=qhxd9Y#-eLJ>Zcj9P${1up%f)^|VT~g#0ouC4e0HKI z1xwRFEb)1o{1R{k=;`PVvwm+E02wC1j`|YH9k<(7IHFO%^%|`mg83iL;5+;<%SgDg_rhe<@N zjeW(caw9`Q-F)B%2Tu0h0Ud9@ed)`Ro)sFm@%;ckPgB@Yz03nV1IVX- z3Q~}3pt8)2#Vk?#s1;cf6pb= zFFs*IeR9kQEtgscSoCgtywFof2zc1-a<(K6j;NZUx5y5_3^1j_LjBx4${i-c5sh7k z{d{z&n{Z@QSSK*Y?Q)(RK9RIc71cWmv@b#AgWfOAMnO12IuO9Oz-+h6c{ADMXzx-P zSOlyB%F|JXKpPSh