.depend
*~
*.cxx
+docs/html/*
+releases/*
+patches/*
+src/modules/lumas/NTSC/*.pgm
+src/modules/lumas/PAL/*.pgm
+src/swig/csharp/src_swig/*
+src/swig/perl/blib/*
Dan Dennedy <dan@dennedy.org>
MLT module authors and maintainers:
-
Charles Yates <charles.yates@pandora.be>
Dan Dennedy <dan@dennedy.org>
Stephane Fillod (effectv)
Marco Gittler <g.marco@freenet.de> (frei0r, oldfilm, qimage/kdenlivetitle)
Jean-Baptiste Mardelle <jb@ader.ch> (kdenlive, qimage)
Zachary Drew (motion_est)
+Maksym Veremeyenko <verem@m1stereo.tv>
+2013-01-20 Dan Dennedy <dan@dennedy.org>
+
+ * Doxyfile, configure, docs/melt.1, src/framework/mlt_version.h,
+ src/melt/melt.c: Set version to 0.8.8.
+
+2012-12-31 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/consumer_avformat.c,
+ src/modules/avformat/producer_avformat.c: Fix build against FFmepg 0.5 and
+ 0.6.
+
+2012-12-26 Niv Sardi <xaiki@evilgiggle.com>
+
+ * src/modules/gtk2/producer_pixbuf.c, src/modules/gtk2/producer_pixbuf.yml:
+ pixbuf producer: loop option to loop sequence selectively
+
+2012-12-22 Dan Dennedy <dan@dennedy.org>
+
+ * src/framework/mlt_consumer.c, src/framework/mlt_frame.c,
+ src/framework/mlt_types.h, src/modules/avformat/consumer_avformat.c,
+ src/modules/avformat/producer_avformat.c,
+ src/modules/core/filter_audiochannels.c,
+ src/modules/core/filter_audioconvert.c,
+ src/modules/core/filter_channelcopy.c, src/modules/core/filter_mono.c: Add
+ mlt_audio_u8 (sourceforce-182). It should support planar libavutil
+ AV_SAMPLE_FMT_U8P, but it is untested due to lacking a sample.
+
+2012-12-12 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/producer_avformat.c,
+ src/modules/resample/filter_resample.c: Fix possible divide by zero
+ exceptions.
+
+2012-11-27 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/factory.c, src/modules/avformat/filter_avresample.c,
+ src/modules/avformat/producer_avformat.c: Fix decoding audio with planar
+ formats.
+
+ * src/modules/decklink/consumer_decklink.cpp,
+ src/modules/decklink/producer_decklink.cpp: Fix mlt_profile to DeckLink
+ DisplayMode matching.
+
+2012-11-17 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/producer_qimage.c:
+ Fix crash on invalid image sequence.
+
+ * configure, src/framework/mlt_version.h: set to interim version 0.8.7
+
+ * src/modules/qimage/kdenlivetitle_wrapper.cpp,
+ src/modules/videostab/stab/klt/error.c: Remove exit()s that cause unexpected
+ app failures. An app can register a mlt_log callback, trap errors, and do
+ something more graceful than abort as perhaps some of these are not really as
+ fatal as they claim to be (a different patch can change the levels as
+ needed).
+
+2012-11-14 Dan Dennedy <dan@dennedy.org>
+
+ * Doxyfile, NEWS, configure, docs/melt.1, src/framework/mlt_version.h: Set
+ version to 0.8.6
+
+2012-11-13 Dan Dennedy <dan@dennedy.org>
+
+ * Doxyfile, configure, docs/melt.1, src/framework/mlt_version.h,
+ src/modules/avformat/configure: Set version to 0.8.4
+
+2012-11-11 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/core/factory.c, src/modules/normalize/Makefile,
+ src/modules/normalize/factory.c, src/modules/normalize/filter_audiolevel.c,
+ src/modules/normalize/filter_audiolevel.yml: Add audiolevel filter.
+
+ * src/modules/avformat/producer_avformat.c,
+ src/modules/avformat/producer_avformat.yml, src/modules/core/filter_resize.c:
+ More fixes for force_full_luma (kdenlive-2799). This change lets the image
+ converter downstream of the avformat producer perform utilize the range
+ as-needed. Then, when the rescale filter sees that the force_full_range is
+ set on the frame but has not yet been applied, forces a conversion to RGB to
+ enforce it. In addition, the recently added force_full_luma property on the
+ avformat producer is removed because it is redundant with AVOption
+ color_range=2.
+
+ * presets/consumer/avformat/Sony-PSP,
+ presets/consumer/avformat/atsc_1080i_50/DNxHD,
+ presets/consumer/avformat/atsc_1080i_5994/DNxHD,
+ presets/consumer/avformat/atsc_1080p_2398/DNxHD,
+ presets/consumer/avformat/atsc_1080p_24/DNxHD,
+ presets/consumer/avformat/atsc_1080p_25/DNxHD,
+ presets/consumer/avformat/atsc_1080p_2997/DNxHD,
+ presets/consumer/avformat/atsc_1080p_30/DNxHD,
+ presets/consumer/avformat/atsc_1080p_50/DNxHD,
+ presets/consumer/avformat/atsc_1080p_5994/DNxHD,
+ presets/consumer/avformat/atsc_1080p_60/DNxHD,
+ presets/consumer/avformat/atsc_720p_2398/DNxHD,
+ presets/consumer/avformat/atsc_720p_50/DNxHD,
+ presets/consumer/avformat/atsc_720p_5994/DNxHD,
+ presets/consumer/avformat/atsc_720p_60/DNxHD,
+ presets/consumer/avformat/dv_ntsc/D10, presets/consumer/avformat/dv_ntsc/DV,
+ presets/consumer/avformat/dv_ntsc/DVCPRO50,
+ presets/consumer/avformat/dv_ntsc_wide/D10,
+ presets/consumer/avformat/dv_ntsc_wide/DV,
+ presets/consumer/avformat/dv_ntsc_wide/DVCPRO50,
+ presets/consumer/avformat/dv_pal/D10, presets/consumer/avformat/dv_pal/DV,
+ presets/consumer/avformat/dv_pal/DVCPRO50,
+ presets/consumer/avformat/dv_pal_wide/D10,
+ presets/consumer/avformat/dv_pal_wide/DV,
+ presets/consumer/avformat/dv_pal_wide/DVCPRO50,
+ presets/consumer/avformat/hdv_1080_25p/HDV,
+ presets/consumer/avformat/hdv_1080_30p/HDV,
+ presets/consumer/avformat/hdv_1080_50i/HDV,
+ presets/consumer/avformat/hdv_1080_60i/HDV,
+ presets/consumer/avformat/hdv_720_25p/HDV,
+ presets/consumer/avformat/hdv_720_30p/HDV,
+ presets/consumer/avformat/hdv_720_50p/HDV,
+ presets/consumer/avformat/hdv_720_60p/HDV,
+ presets/consumer/avformat/lossless/FFV1,
+ presets/consumer/avformat/lossless/H.264,
+ presets/consumer/avformat/lossless/MPEG-4: Add more descriptions to encoding
+ presets.
+
+2012-11-05 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/qimage/producer_qimage.c,
+ src/modules/qimage/producer_qimage.yml: qimage: let begin property be passed
+ as a query string parameter
+
+ * src/modules/gtk2/producer_pixbuf.c, src/modules/gtk2/producer_pixbuf.yml:
+ pixbuf: support alt. query syntax begin:value for melt
+
+2012-11-04 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/gtk2/producer_pixbuf.c, src/modules/gtk2/producer_pixbuf.yml:
+ pixbuf: let begin property be passed as a query string parameter
+
+2012-10-23 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/producer_avformat.c,
+ src/modules/avformat/producer_avformat.yml: Fix force_full_luma
+ (kdenlive-2799).
+
+2012-10-19 Dan Dennedy <dan@dennedy.org>
+
+ * src/framework/mlt_geometry.c, src/modules/videostab/filter_videostab.c,
+ src/modules/videostab/filter_videostab2.c: Let vector property of
+ videostab(2) be read directly as mlt_geometry.
+
+2012-10-19 Jean-Baptiste Mardelle <jb@kdenlive.org>
+
+ * src/modules/qimage/Makefile, src/modules/qimage/configure,
+ src/modules/qimage/producer_qimage.c, src/modules/qimage/qimage_wrapper.cpp,
+ src/modules/qimage/qimage_wrapper.h: Fix loading of extra image formats using
+ Kdelibs (xcf, ...)
+
+2012-10-09 Dan Dennedy <dan@dennedy.org>
+
+ * src/swig/Makefile, src/swig/csharp/build, src/swig/java/build,
+ src/swig/lua/build, src/swig/perl/Makefile.PL, src/swig/perl/build,
+ src/swig/php/build, src/swig/python/build, src/swig/ruby/build,
+ src/swig/tcl/build: Build the SWIG bindings with the CXXFLAGS (3554425)
+ Based on patch by Cristian Morales Vega
+
+ * src/modules/core/producer_colour.c, src/modules/core/producer_noise.c,
+ src/modules/frei0r/producer_frei0r.c: fix aspect ratio of generators when set
+ via consumer property
+
+2012-09-23 Dan Dennedy <dan@dennedy.org>
+
+ * presets/consumer/avformat/MJPEG, presets/consumer/avformat/lossless/FFV1,
+ presets/consumer/avformat/lossless/MJPEG: indicate in some presets codecs
+ which do not support multithread
+
+2012-09-16 Dan Dennedy <dan@dennedy.org>
+
+ * src/framework/Makefile, src/framework/configure,
+ src/framework/mlt_property.h: cleanup sys/param.h include on FreeBSD
+ Assisted by Albert Villa who says it is safe to assume sys/param.h is
+ available, which is needed for FreeBSD version check on whether to include
+ xlocale.h in mlt_property.h.
+
+2012-09-13 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/sdl/consumer_sdl_audio.c,
+ src/modules/sdl/consumer_sdl_preview.c: sdl_audio and sdl_preview also do not
+ care about field order Also, have sdl_preview pass top_field_first to its
+ children.
+
+ * src/framework/mlt_consumer.h, src/modules/core/filter_fieldorder.c,
+ src/modules/sdl/consumer_sdl.c: add ability to ignore field order as used by
+ sdl consumer
+
+2012-09-09 Dan Dennedy <dan@dennedy.org>
+
+ * src/mlt++/MltProfile.cpp, src/mlt++/MltProfile.h: add
+ Mlt::Profile::colorspace()
+
+2012-09-08 Dan Dennedy <dan@dennedy.org>
+
+ * configure, src/framework/configure, src/modules/avformat/configure,
+ src/modules/frei0r/configure: allow env CC to override hard-coded gcc in
+ configure scripts patch by Alberto Villa
+
+ * src/modules/avformat/producer_avformat.c,
+ src/modules/gtk2/producer_pango.c, src/modules/gtk2/producer_pixbuf.c,
+ src/modules/qimage/producer_qimage.c, src/modules/qimage/qimage_wrapper.cpp,
+ src/modules/swfdec/producer_swfdec.c, src/modules/vorbis/producer_vorbis.c:
+ change producers to use mlt_frame_original_position()
+
+ * src/framework/mlt_frame.c, src/framework/mlt_frame.h: add
+ mlt_frame_original_position()
+
+2012-09-03 Dan Dennedy <dan@dennedy.org>
+
+ * src/mlt++/MltService.cpp, src/mlt++/MltService.h: add
+ Mlt::Service::set_profile()
+
+ * src/framework/mlt_service.c, src/framework/mlt_service.h: add
+ mlt_service_set_profile()
+
+ * src/mlt++/MltProfile.cpp, src/mlt++/MltProfile.h: add
+ Mlt::Profile::is_explicit()
+
+2012-08-31 Dan Dennedy <dan@dennedy.org>
+
+ * src/swig/mlt.i, src/swig/ruby/playlist.rb: extend Ruby API with
+ PlaylistNextListner and show how to use it
+
+ * src/framework/mlt_playlist.c, src/framework/mlt_playlist.h: add
+ playlist-next event to mlt_playlist
+
+2012-08-30 Dan Dennedy <dan@dennedy.org>
+
+ * configure, src/framework/mlt_version.h: set interim version to 0.8.3
+
+2012-08-28 Dan Dennedy <dan@dennedy.org>
+
+ * ChangeLog, presets/consumer/avformat/MPEG-4 ASP,
+ presets/consumer/avformat/MPEG-4-ASP, presets/consumer/avformat/webm: add
+ acodec to webm preset and rename MPEG-4 ASP preset
+
+ * Doxyfile, configure, docs/melt.1, src/framework/mlt_version.h: set version
+ to 0.8.2
+
+2012-08-26 Dan Dennedy <dan@dennedy.org>
+
+ * presets/consumer/avformat/stills/BMP, presets/consumer/avformat/stills/DPX,
+ presets/consumer/avformat/stills/JPEG, presets/consumer/avformat/stills/PNG,
+ presets/consumer/avformat/stills/PPM, presets/consumer/avformat/stills/TGA,
+ presets/consumer/avformat/stills/TIFF: add meta.preset.extension to image
+ sequence presets
+
+ * presets/consumer/avformat/AAC, presets/consumer/avformat/Flash,
+ presets/consumer/avformat/MJPEG, presets/consumer/avformat/MP3,
+ presets/consumer/avformat/MPEG-2, presets/consumer/avformat/MPEG-4,
+ presets/consumer/avformat/MPEG-4 ASP, presets/consumer/avformat/Sony-PSP,
+ presets/consumer/avformat/Vorbis, presets/consumer/avformat/WAV,
+ presets/consumer/avformat/XDCAM-HD422,
+ presets/consumer/avformat/atsc_1080i_50/DNxHD,
+ presets/consumer/avformat/atsc_1080i_5994/DNxHD,
+ presets/consumer/avformat/atsc_1080p_2398/DNxHD,
+ presets/consumer/avformat/atsc_1080p_24/DNxHD,
+ presets/consumer/avformat/atsc_1080p_25/DNxHD,
+ presets/consumer/avformat/atsc_1080p_2997/DNxHD,
+ presets/consumer/avformat/atsc_1080p_30/DNxHD,
+ presets/consumer/avformat/atsc_1080p_50/DNxHD,
+ presets/consumer/avformat/atsc_1080p_5994/DNxHD,
+ presets/consumer/avformat/atsc_1080p_60/DNxHD,
+ presets/consumer/avformat/atsc_720p_2398/DNxHD,
+ presets/consumer/avformat/atsc_720p_50/DNxHD,
+ presets/consumer/avformat/atsc_720p_5994/DNxHD,
+ presets/consumer/avformat/atsc_720p_60/DNxHD,
+ presets/consumer/avformat/dv_ntsc/D10, presets/consumer/avformat/dv_ntsc/DVD,
+ presets/consumer/avformat/dv_ntsc_wide/D10,
+ presets/consumer/avformat/dv_ntsc_wide/DVD,
+ presets/consumer/avformat/dv_pal/D10, presets/consumer/avformat/dv_pal/DVD,
+ presets/consumer/avformat/dv_pal_wide/D10,
+ presets/consumer/avformat/dv_pal_wide/DVD,
+ presets/consumer/avformat/hdv_1080_25p/HDV,
+ presets/consumer/avformat/hdv_1080_30p/HDV,
+ presets/consumer/avformat/hdv_1080_50i/HDV,
+ presets/consumer/avformat/hdv_1080_60i/HDV,
+ presets/consumer/avformat/hdv_720_25p/HDV,
+ presets/consumer/avformat/hdv_720_30p/HDV,
+ presets/consumer/avformat/hdv_720_50p/HDV,
+ presets/consumer/avformat/hdv_720_60p/HDV,
+ presets/consumer/avformat/lossless/FFV1,
+ presets/consumer/avformat/lossless/H.264,
+ presets/consumer/avformat/lossless/HuffYUV,
+ presets/consumer/avformat/lossless/MJPEG,
+ presets/consumer/avformat/lossless/MPEG-2,
+ presets/consumer/avformat/lossless/MPEG-4,
+ presets/consumer/avformat/lossless/ProRes, presets/consumer/avformat/webm,
+ presets/consumer/avformat/x264-medium,
+ presets/consumer/avformat/x264-medium-baseline,
+ presets/consumer/avformat/x264-medium-main,
+ presets/consumer/avformat/x264-medium-pass1: add preset metadata such as
+ alternate name, filename extension, note.
+
+ * presets/consumer/avformat/Sony-PSP, presets/consumer/avformat/webm,
+ presets/consumer/avformat/x264-medium-baseline,
+ presets/consumer/avformat/x264-medium-main: change profile to vprofile in
+ presets
+
+ * presets/consumer/avformat/Vorbis,
+ presets/consumer/avformat/lossless/ProRes: add vorbis and prores encode
+ presets
+
+2012-08-25 Dan Dennedy <dan@dennedy.org>
+
+ * presets/consumer/avformat/AAC, presets/consumer/avformat/Flash,
+ presets/consumer/avformat/MJPEG, presets/consumer/avformat/MP3,
+ presets/consumer/avformat/MPEG-2, presets/consumer/avformat/MPEG-4,
+ presets/consumer/avformat/MPEG-4 ASP, presets/consumer/avformat/WAV,
+ presets/consumer/avformat/hdv_1080_25p/HDV,
+ presets/consumer/avformat/hdv_1080_30p/HDV,
+ presets/consumer/avformat/hdv_1080_50i/HDV,
+ presets/consumer/avformat/hdv_1080_60i/HDV,
+ presets/consumer/avformat/hdv_720_25p/HDV,
+ presets/consumer/avformat/hdv_720_30p/HDV,
+ presets/consumer/avformat/hdv_720_50p/HDV,
+ presets/consumer/avformat/hdv_720_60p/HDV,
+ presets/consumer/avformat/lossless/FFV1,
+ presets/consumer/avformat/lossless/H.264,
+ presets/consumer/avformat/lossless/HuffYUV,
+ presets/consumer/avformat/lossless/MJPEG,
+ presets/consumer/avformat/lossless/MPEG-2,
+ presets/consumer/avformat/lossless/MPEG-4,
+ presets/consumer/avformat/stills/BMP, presets/consumer/avformat/stills/DPX,
+ presets/consumer/avformat/stills/JPEG, presets/consumer/avformat/stills/PNG,
+ presets/consumer/avformat/stills/PPM, presets/consumer/avformat/stills/TGA,
+ presets/consumer/avformat/stills/TIFF,
+ presets/consumer/avformat/x264-medium-pass1: add a bunch of new encoding
+ presets
+
+2012-08-24 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/producer_avformat.c,
+ src/modules/avformat/producer_avformat.yml: the recent A/V sync overhaul
+ needed some additional work
+
+2012-08-11 Dan Dennedy <dan@dennedy.org>
+
+ * src/melt/io.c, src/melt/melt.c: fix melt progress display on Windows
+
+2012-08-01 Mikko Rapeli <mikko.rapeli@iki.fi>
+
+ * src/modules/videostab/filter_videostab.c,
+ src/modules/videostab/filter_videostab2.c: videostab/filter_videostab*.c:
+ check return value from mlt_filter_new() Fixes Coverity CID 709365 and
+ 709366: Dereference null return value (NULL_RETURNS) Function
+ "mlt_filter_new" returns null (checked 50 out of 52 times). [show details]
+ Assigning: "parent" = null return value from "mlt_filter_new". 201
+ mlt_filter parent = mlt_filter_new(); Dereferencing a null pointer
+ "parent". 202 parent->child = self;
+
+ * src/modules/videostab/filter_videostab.c,
+ src/modules/videostab/filter_videostab2.c: videostab/filter_videostab*.c:
+ check for null Fixes Coverity CID 709404: Dereference before null check
+ (REVERSE_INULL) Dereferencing pointer "g". [show details] 85 if (
+ !mlt_geometry_parse( g, vectors, length, -1, -1 ) ) ... Dereferencing "g"
+ before a null check. 104 if ( g ) mlt_geometry_close( g );
+
+2012-08-04 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/producer_avformat.c,
+ src/modules/avformat/producer_avformat.yml: add image cache size property to
+ avformat producer
+
+2012-08-03 Marco Gittler <g.marco@freenet.de>
+
+ * src/modules/oldfilm/filter_lines.c, src/modules/oldfilm/filter_lines.yml:
+ fix width output of filter in xml
+
+2012-07-25 Mikko Rapeli <mikko.rapeli@iki.fi>
+
+ * src/framework/mlt_field.c, src/framework/mlt_frame.c,
+ src/framework/mlt_multitrack.c, src/framework/mlt_playlist.c,
+ src/framework/mlt_properties.c, src/framework/mlt_repository.c,
+ src/framework/mlt_service.c, src/framework/mlt_tractor.c,
+ src/modules/core/filter_audioconvert.c, src/modules/core/filter_crop.c,
+ src/modules/core/filter_imageconvert.c, src/modules/core/filter_panner.c,
+ src/modules/core/filter_resize.c, src/modules/core/producer_ppm.c,
+ src/modules/core/transition_composite.c, src/modules/core/transition_mix.c,
+ src/modules/dv/producer_libdv.c, src/modules/gtk2/producer_pango.c,
+ src/modules/gtk2/producer_pixbuf.c, src/modules/kino/producer_kino.c,
+ src/modules/linsys/consumer_SDIstream.c,
+ src/modules/normalize/filter_volume.c,
+ src/modules/qimage/producer_kdenlivetitle.c,
+ src/modules/qimage/producer_qimage.c, src/modules/rtaudio/RtAudio.cpp,
+ src/modules/sdl/consumer_sdl.c, src/modules/sdl/consumer_sdl_audio.c,
+ src/modules/sdl/consumer_sdl_preview.c, src/modules/sdl/consumer_sdl_still.c,
+ src/modules/xml/consumer_xml.c, src/modules/xml/producer_xml.c: Fix calloc()
+ parameter ordering First parameter to calloc() is the count and second the
+ amount of bytes for each item. Likely this has no run time effect since the
+ resulting buffer size is the same.
+
+2012-07-23 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/qimage_wrapper.cpp:
+ fix crash when switching image formats with alpha This happens when
+ switching from image format with distinct alpha channel (yuv422) to one with
+ embedded alpha channel (rgb24a). Reported-by: j-b-m
+
+2012-07-22 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/videostab/stabilize.c, src/modules/videostab/stabilize.h:
+ remove unused function (coverity-709390)
+
+ * src/mlt++/MltService.cpp, src/mlt++/MltService.h: add
+ Service::get_profile() returns mlt_profile
+
+ * src/framework/mlt_consumer.c, src/framework/mlt_consumer.h: fix memory leak
+ (coverity-709375)
+
+2012-07-20 Dan Dennedy <dan@dennedy.org>
+
+ * AUTHORS, src/modules/core/Makefile,
+ src/modules/core/composite_line_yuv_sse2_simple.c,
+ src/modules/core/transition_composite.c: improve compatibility to compile
+ composite sse2 (macports-35243)
+
+2012-07-12 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/core/producer_loader.c, src/modules/xml/producer_xml.c: accept
+ file:// prefix on MLT XML file
+
+2012-06-23 Dan Dennedy <dan@dennedy.org>
+
+ * src/framework/mlt_playlist.c, src/framework/mlt_playlist.h,
+ src/mlt++/MltPlaylist.cpp, src/mlt++/MltPlaylist.h,
+ src/modules/core/producer_melt.c, src/modules/xml/producer_xml.c: add support
+ for time string to playlist blanks
+
+ * src/modules/jackrack/consumer_jack.c,
+ src/modules/jackrack/consumer_jack.yml,
+ src/modules/rtaudio/consumer_rtaudio.cpp,
+ src/modules/rtaudio/consumer_rtaudio.yml,
+ src/modules/sdl/consumer_sdl_audio.c, src/modules/sdl/consumer_sdl_audio.yml:
+ add support for audio scrubbing to audio-only consumers
+
+2012-06-19 Dan Dennedy <dan@dennedy.org>
+
+ * src/framework/mlt_producer.c, src/framework/mlt_producer.h,
+ src/mlt++/MltProducer.cpp, src/mlt++/MltProducer.h: add
+ mlt_producer_seek_time and mlt_producer_frame_time
+
+ * src/mlt++/MltFilteredConsumer.cpp, src/mlt++/MltFilteredConsumer.h,
+ src/mlt++/MltFilteredProducer.cpp, src/mlt++/MltFilteredProducer.h,
+ src/mlt++/MltPushConsumer.cpp, src/mlt++/MltPushConsumer.h: add const-ness to
+ some strings in specialized service classes
+
+2012-06-18 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/rotoscoping/filter_rotoscoping.c,
+ src/modules/vmfx/filter_shape.c, src/modules/xine/vf_yadif_template.h,
+ src/modules/xine/yadif.c: fix clang errors
+
+2012-06-16 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/producer_avformat.c,
+ src/modules/avformat/producer_avformat.yml: overhaul a/v sync and seeking in
+ avformat producer The new_seek property changed to use_pts. This
+ consolidates old seek and new seek code, improves a/v sync for more files,
+ and improves seek performance for AVCHD in general (including libav).
+
+2012-06-04 Dan Dennedy <dan@dennedy.org>
+
+ * NEWS, configure, src/framework/mlt_version.h: set interim version to 0.8.1
+
+2012-06-01 Dan Dennedy <dan@dennedy.org>
+
+ * Doxyfile, configure, docs/melt.1, src/framework/mlt_version.h,
+ src/modules/avformat/configure: set version to 0.8.0
+
+2012-05-29 Dan Dennedy <dan@dennedy.org>
+
+ * src/framework/mlt_cache.c, src/framework/mlt_cache.h: add
+ mlt_cache_put_frame and mlt_cache_get_frame
+
+ * src/modules/gtk2/Makefile, src/modules/gtk2/configure,
+ src/modules/gtk2/scale_line_22_yuv_mmx.S, src/modules/jackrack/Makefile,
+ src/modules/jackrack/configure: fix cross-compiling gtk2 and jackrack modules
+ for windows
+
+2012-05-26 Dan Dennedy <dan@dennedy.org>
+
+ * configure, src/mlt++/configure, src/modules/qimage/configure,
+ src/modules/swfdec/Makefile, src/modules/videostab/stab/estimate.c: add
+ configure options and fixes for cross-compiling
+
+2012-05-19 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/decklink/DeckLinkAPI.h,
+ src/modules/decklink/DeckLinkAPIDispatch.cpp,
+ src/modules/decklink/DeckLinkAPI_h.h, src/modules/decklink/DeckLinkAPI_i.cpp,
+ src/modules/decklink/LinuxCOM.h, src/modules/decklink/Makefile,
+ src/modules/decklink/common.cpp, src/modules/decklink/common.h,
+ src/modules/decklink/consumer_decklink.cpp,
+ src/modules/decklink/darwin/DeckLinkAPI.h,
+ .../decklink/darwin/DeckLinkAPIDispatch.cpp,
+ src/modules/decklink/linux/DeckLinkAPI.h,
+ src/modules/decklink/linux/DeckLinkAPIDispatch.cpp,
+ src/modules/decklink/linux/LinuxCOM.h,
+ src/modules/decklink/producer_decklink.cpp,
+ src/modules/decklink/win/DeckLinkAPI_h.h,
+ src/modules/decklink/win/DeckLinkAPI_i.cpp: fix decklink build for OS X
+
+2012-04-18 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/decklink/consumer_decklink.cpp,
+ src/modules/decklink/producer_decklink.cpp: fix decklink build on Windows
+
+2012-04-11 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/plus/filter_affine.c, src/modules/plus/interp.h,
+ src/modules/plus/transition_affine.c: fix distortion handling alpha channel
+ in affine transition Reported-by: j-b-m
+
+2012-04-10 Dan Dennedy <dan@dennedy.org>
+
+ * demo/mlt_ticker, src/modules/plus/filter_affine.c: fix background alpha
+ channel of affine filter broke when black producer was changed to opaque
+ like other colors
+
+2012-04-07 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/plus/transition_affine.c,
+ src/modules/qimage/qimage_wrapper.cpp: fix regressions during refactorization
+
+2012-03-31 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/xml/consumer_xml.c, src/modules/xml/consumer_xml.yml: add
+ time_format property to xml consumer Now you can save the in, out, and
+ length properties as timecode or clock values. Default unit it still in frame
+ count.
+
+ * src/framework/mlt_producer.c, src/framework/mlt_producer.h,
+ src/mlt++/MltProducer.cpp, src/mlt++/MltProducer.h: add
+ mlt_producer_get_length_time() More functions that return time strings will
+ be added later.
+
+ * configure, src/framework/mlt_properties.c, src/framework/mlt_properties.h,
+ src/framework/mlt_property.c, src/framework/mlt_property.h,
+ src/framework/mlt_types.h, src/mlt++/MltProperties.cpp,
+ src/mlt++/MltProperties.h: add support for timecode and clock time strings to
+ the framework
+
+2012-03-27 Dan Dennedy <dan@dennedy.org>
+
+ * GPLv3, configure, src/modules/qimage/Makefile,
+ src/modules/qimage/configure, src/modules/qimage/factory.c: require configure
+ --enable-gpl3 for GPLv3 services (currently only vqm)
+
+2012-03-25 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/producer_qimage.c:
+ fix resource leak regression in image producers
+
+2012-03-19 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/decklink/consumer_decklink.cpp,
+ src/modules/decklink/producer_decklink.cpp: enumerate DeckLink devices when
+ list_devices property is set
+
+2012-03-19 Maksym Veremeyenko <verem@m1stereo.tv>
+
+ * src/modules/decklink/consumer_decklink.cpp,
+ src/modules/decklink/producer_decklink.cpp: Initialize all decklink interface
+ pointers and reset them upon release. Also, add a couple of missing
+ releases.
+
+2012-03-18 Brian Matherly <pez4brian@yahoo.com>
+
+ * src/modules/avformat/consumer_avformat.c,
+ src/modules/avformat/producer_avformat.c: Fix incorrect precompiler
+ conditionals for libav/ffmpeg versions. Needed to support ffmpeg 0.9 and
+ 0.10 releases.
+
+2012-03-14 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/decklink/consumer_decklink.cpp,
+ src/modules/decklink/consumer_decklink.yml,
+ src/modules/decklink/producer_decklink.cpp,
+ src/modules/decklink/producer_decklink.yml: enumerate available devices in
+ decklink module
+
+2012-03-11 Brian Matherly <pez4brian@yahoo.com>
+
+ * src/modules/gtk2/producer_pixbuf.yml,
+ src/modules/qimage/producer_qimage.yml: Fix broken pixbuf and qimage producer
+ metadata.
+
+2012-03-07 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/gtk2/producer_pango.c, src/modules/gtk2/producer_pixbuf.c,
+ src/modules/qimage/producer_qimage.c: indicate image producers seekable
+
+2012-03-06 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/gtk2/producer_pixbuf.yml,
+ src/modules/qimage/producer_qimage.yml: update service metadata for pixbuf
+ and qimage
+
+2012-03-05 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/producer_qimage.c:
+ allow %u in image sequence pattern containing begin value
+
+ * src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/producer_qimage.c:
+ add image sequences where scanf format contains begin value For example, if
+ an image sequence begins with the file foo1234.png, you can use the resource
+ string "foo%1234d.png" to load it.
+
+2012-03-04 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/decklink/producer_decklink.cpp,
+ src/modules/qimage/qimage_wrapper.cpp: remove a couple more remnants of
+ legacy real_width and _height
+
+ * src/modules/avformat/producer_avformat.c, src/modules/dv/producer_libdv.c:
+ remove deprecated source_fps property
+
+ * src/framework/mlt_tractor.c, src/modules/avformat/producer_avformat.c,
+ src/modules/core/consumer_multi.c, src/modules/core/filter_crop.c,
+ src/modules/core/filter_rescale.c, src/modules/core/filter_resize.c,
+ src/modules/core/producer_colour.c, src/modules/core/producer_consumer.c,
+ src/modules/core/producer_loader.c, src/modules/core/transition_composite.c,
+ src/modules/dv/producer_libdv.c, src/modules/gtk2/producer_pango.c,
+ src/modules/gtk2/producer_pixbuf.c,
+ src/modules/kdenlive/producer_framebuffer.c,
+ src/modules/plus/transition_affine.c, src/modules/sdl/producer_sdl_image.c,
+ src/modules/swfdec/producer_swfdec.c,
+ src/modules/videostab/filter_videostab2.c, src/modules/vmfx/producer_pgm.c:
+ replace legacy real_width and _height with meta.media.width and .height This
+ takes advantage of mlt_producer copying all meta properties from producer to
+ frame so we do not have to remember to do it everywhere it is needed.
+
+2012-02-29 Dan Dennedy <dan@dennedy.org>
+
+ * src/framework/mlt_consumer.c, src/framework/mlt_frame.c,
+ src/framework/mlt_profile.c, src/framework/mlt_tractor.c,
+ src/framework/mlt_transition.c, src/modules/core/filter_crop.c,
+ src/modules/core/filter_watermark.c, src/modules/kdenlive/filter_freeze.c,
+ src/modules/kdenlive/producer_framebuffer.c,
+ src/modules/oldfilm/filter_dust.c, src/modules/plus/filter_affine.c,
+ src/modules/plus/transition_affine.c: remove consumer_aspect_ratio property -
+ use profile instead
+
+ * src/framework/mlt_tractor.c, src/modules/core/filter_watermark.c,
+ src/modules/core/transition_composite.c,
+ src/modules/kdenlive/filter_freeze.c: remove output_ratio property - use
+ profile instead
+
+ * src/modules/core/filter_crop.c, src/modules/core/filter_obscure.c,
+ src/modules/core/filter_rescale.c, src/modules/core/filter_resize.c,
+ src/modules/core/filter_watermark.c, src/modules/core/transition_composite.c,
+ src/modules/plus/filter_affine.c, src/modules/plus/transition_affine.c:
+ remove usage of normalised_width and _height properties from services
+
+ * src/framework/mlt_frame.c, src/framework/mlt_tractor.c: remove
+ normalised_width and _height properties from framework
+
+2012-03-04 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/qimage_wrapper.cpp:
+ fix regression with adding image conversion to image producers
+
+2012-03-02 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/qimage/producer_qimage.c,
+ src/modules/qimage/qimage_wrapper.cpp, src/modules/qimage/qimage_wrapper.h:
+ convert to and cache requested format in qimage
+
+2012-03-01 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/qimage/producer_qimage.c,
+ src/modules/qimage/qimage_wrapper.cpp, src/modules/qimage/qimage_wrapper.h:
+ split refresh_qimage() into refresh_qiamge() and refresh_image()
+
+2012-02-27 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/core/transition_composite.yml,
+ src/modules/gtk2/producer_pixbuf.yml: couple of small service metadata fixes
+
+2012-02-22 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/decklink/producer_decklink.cpp,
+ src/modules/decklink/producer_decklink.yml: fix regression when using
+ producer 'consumer' with decklink This feature now requires one to set the
+ preview property on this producer to support special preview mode when the
+ speed is 0.
+
+2012-02-20 Dan Dennedy <dan@dennedy.org>
+
+ * src/framework/mlt_frame.c, src/modules/avformat/filter_avcolour_space.c,
+ src/modules/core/filter_crop.c, src/modules/core/filter_resize.c,
+ src/modules/core/transition_region.c: let mlt_frame_set_alpha clear the
+ get_alpha_mask function pointer
+
+2012-02-19 Dan Dennedy <dan@dennedy.org>
+
+ * configure, src/framework/mlt_version.h: set interim version 0.7.9
+
+2012-02-16 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/core/transition_composite.c,
+ src/modules/core/transition_composite.h: make composite_line_yuv() available
+ to other services
+
+2012-02-16 Maksym Veremeyenko <verem@m1stereo.tv>
+
+ * src/modules/core/composite_line_yuv_sse2_simple.c,
+ src/modules/core/transition_composite.c: use sse2 instruction for line
+ compositing
+
+2012-02-13 Dan Dennedy <dan@dennedy.org>
+
+ * Doxyfile, configure, docs/melt.1, src/framework/mlt_version.h,
+ src/melt/melt.c: set version to 0.7.8
+
+2012-02-12 Dan Dennedy <dan@dennedy.org>
+
+ * Makefile, src/modules/core/loader.dict,
+ src/modules/sdl/producer_sdl_image.yml: deprecate sdl_image
+
+ * src/mlt++/MltFrame.cpp, src/mlt++/MltFrame.h: make Frame::get_position()
+ retrun type consistent
+
+2012-02-12 Simon A. Eugster <simon.eu@gmail.com>
+
+ * src/mlt++/MltFrame.cpp, src/mlt++/MltFrame.h: Add get_position to
+ Mlt::Frame
+
+2012-02-08 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/qimage/factory.c, src/modules/qimage/transition_vqm.cpp,
+ src/modules/qimage/transition_vqm.yml: add rendering to vqm and yaml service
+ metadata
+
+2012-02-06 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/qimage/Makefile, src/modules/qimage/factory.c,
+ src/modules/qimage/transition_vqm.cpp: add vqm transition
+
+2012-02-05 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/consumer_avformat.c,
+ src/modules/avformat/filter_avcolour_space.c,
+ src/modules/avformat/producer_avformat.c: fix color problem with libav
+ (3483629)
+
+2012-02-04 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/consumer_avformat.c,
+ src/modules/avformat/producer_avformat.c: fix AVOption processing on ffmpeg
+ 0.8
+
+2012-01-30 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/consumer_avformat.c,
+ src/modules/avformat/producer_avformat.c: fix AVOption processing on libav
+ 0.7.3 Patch for consumer by j-b-m and extended to producer by me.
+
+2012-01-28 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/consumer_avformat.c,
+ src/modules/avformat/filter_avresample.c,
+ src/modules/avformat/producer_avformat.c: fix SAMPLE_FMT support for v0.6 and
+ less of libav/ffmpeg
+
+ * src/modules/avformat/filter_avresample.c,
+ src/modules/avformat/producer_avformat.c: convert all SAMPLE_FMT_16 to
+ AV_SAMPLE_FMT_16
+
+2012-01-25 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/core/filter_audiochannels.c,
+ src/modules/core/filter_channelcopy.c, src/modules/core/filter_mono.c: add
+ s32le and f32le format to core audio filters
+
+ * src/framework/mlt_types.h, src/modules/core/filter_audioconvert.c: add
+ support for converting between all audio sample formats
+
+2012-01-21 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/consumer_avformat.c, src/modules/avformat/factory.c,
+ src/modules/avformat/producer_avformat.c: remove global avformat mutex and
+ add a local one to the producer for open/close coherency
+
+ * src/framework/mlt_producer.h, src/framework/mlt_service.h: update doc on
+ service-change and producer-changed events
+
+2012-01-17 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/gtk2/producer_pango.yml, src/modules/gtk2/producer_pixbuf.yml:
+ document force_aspect_ratio on pango and pixbuf producers
+
+2012-01-15 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/consumer_avformat.c,
+ src/modules/avformat/producer_avformat.c: enable codec- and format-specific
+ options for v0.7 releases of ffmpeg (but not libav, which uses v53 of
+ libavformat and libavcodec in its 0.7 releases)
+
+2012-01-14 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/consumer_avformat.c, src/modules/avformat/factory.c,
+ src/modules/avformat/producer_avformat.c: drop deprecated APIs of
+ libavformat/codec v53
+
+2012-01-02 gmarco <g.marco@freenet.de>
+
+ * src/modules/videostab/filter_videostab.c,
+ src/modules/videostab/stab/resample.c, src/modules/videostab/stab/resample.h,
+ src/modules/videostab/stab/utils.c, src/modules/videostab/stab/utils.h: do
+ not use lanc_kernels as global var. moved to filter struct
+
+2011-12-16 gmarco <g.marco@freenet.de>
+
+ * src/modules/videostab/filter_videostab2.c,
+ src/modules/videostab/stabilize.c, src/modules/videostab/stabilize.h,
+ src/modules/videostab/transform_image.c,
+ src/modules/videostab/transform_image.h: use calloc insteadt of malloc/memset
+ use struct for instance data small cleanup use PIX(n) dont use instable
+ yuv420 use stabilize on grayimage (converted from yuv422)
+
+2011-11-21 Marco Gittler <g.marco@freenet.de>
+
+ * src/modules/videostab/stabilize.c, src/modules/videostab/transform_image.c:
+ sse2 updates
+
+2011-12-21 Dan Dennedy <dan@dennedy.org>
+
+ * configure, src/mlt++/configure: add configure support for GNU Hurd Patches
+ provided by Patrick Matthäi.
+
+ * src/modules/rtaudio/RtAudio.cpp, src/modules/rtaudio/configure: only build
+ rtaudio for Linux, Windows, or OS X
+
+ * src/framework/Makefile, src/framework/configure,
+ src/framework/mlt_property.h: add support for xlocale.h on FreeBSD with
+ assistance from Gleb Smirnoff
+
+2011-12-16 gmarco <g.marco@freenet.de>
+
+ * src/modules/videostab/filter_videostab2.c,
+ src/modules/videostab/stabilize.c, src/modules/videostab/stabilize.h,
+ src/modules/videostab/transform_image.c,
+ src/modules/videostab/transform_image.h: use calloc insteadt of malloc/memset
+ use struct for instance data small cleanup use PIX(n) dont use instable
+ yuv420 use stabilize on grayimage (converted from yuv422)
+
+2011-11-21 Marco Gittler <g.marco@freenet.de>
+
+ * src/modules/videostab/stabilize.c, src/modules/videostab/transform_image.c:
+ sse2 updates
+
+2011-12-10 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/core/producer_colour.c, src/modules/core/producer_noise.c,
+ src/modules/dv/producer_libdv.c, src/modules/frei0r/producer_frei0r.c,
+ src/modules/gtk2/producer_pango.c, src/modules/gtk2/producer_pixbuf.c,
+ src/modules/qimage/producer_qimage.c, src/modules/sdl/producer_sdl_image.c:
+ add mlt_image_none support to producers
+
+ * src/framework/mlt_consumer.c, src/framework/mlt_consumer.h: add consumer
+ properties mlt_image_format and mlt_audio_format
+
+2011-12-09 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/core/filter_fieldorder.c,
+ src/modules/core/filter_fieldorder.yml: add meta.swap_fields to the
+ fieldorder filter
+
+2011-12-08 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/core/Makefile, src/modules/core/factory.c,
+ src/modules/core/filter_fieldorder.c, src/modules/core/filter_fieldorder.yml,
+ src/modules/core/filter_resize.c, src/modules/core/filter_resize.yml,
+ src/modules/core/loader.ini: refactor field order correction into new filter
+
+2011-12-05 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/rtaudio/RtAudio.cpp, src/modules/rtaudio/RtAudio.h,
+ src/modules/rtaudio/consumer_rtaudio.cpp: improve selecting rtaudio device by
+ name
+
+2011-11-28 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/rtaudio/Makefile, src/modules/rtaudio/RtAudio.cpp,
+ src/modules/rtaudio/RtAudio.h, src/modules/rtaudio/RtError.h,
+ src/modules/rtaudio/consumer_rtaudio.cpp: add rtaudio consumer
+
+2011-11-27 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/avformat/producer_avformat.c, src/modules/avformat/vdpau.c: fix
+ VDPAU state issues Patch by Christophe Thommeret
+
+2011-11-04 Dan Dennedy <dan@dennedy.org>
+
+ * src/framework/mlt_factory.c, src/modules/frei0r/factory.c,
+ src/modules/jackrack/plugin_mgr.c: fix frei0r and ladspa loading for
+ relocatable builds
+
+2011-11-19 Dan Dennedy <dan@dennedy.org>
+
+ * src/melt/melt.c, src/modules/core/consumer_multi.c: change property
+ 'consumer' to 'mlt_service' consistent with xml
+
+ * src/framework/mlt_frame.c, src/framework/mlt_frame.h,
+ src/modules/core/consumer_multi.c: enhance mlt_frame_clone with a
+ deep/shallow parameter
+
+2011-11-10 Dan Dennedy <dan@dennedy.org>
+
+ * src/framework/mlt_frame.c, src/framework/mlt_frame.h: add mlt_frame_clone()
+
+2011-11-05 Dan Dennedy <dan@dennedy.org>
+
+ * src/modules/core/Makefile, src/modules/core/consumer_multi.c,
+ src/modules/core/consumer_multi.yml, src/modules/core/factory.c: add multi
+ consumer (non-functional)
+
+2011-11-12 Dan Dennedy <dan@dennedy.org>
+
+ * profiles/sdi_486i_5994, profiles/sdi_486p_2398,
+ src/modules/linsys/consumer_SDIstream.c, src/modules/linsys/sdi_generator.c,
+ src/modules/linsys/sdi_generator.h: improve support for 486 line NTSC in
+ linsys sdi consumer
+
+2011-11-03 Dan Dennedy <dan@dennedy.org>
+
+ * configure, src/framework/mlt_version.h: set interim version 0.7.7
+
+ * src/modules/avformat/vdpau.c, src/modules/videostab/stab/estimate.c: build
+ fixes for FreeBSD patches by Alberto Villa
+
2011-10-31 Dan Dennedy <dan@dennedy.org>
* Doxyfile, configure, docs/melt.1, src/framework/mlt_version.h: set version
to 0.7.6
- * NEWS: add release notes for v0.7.6
-
2011-10-30 Dan Dennedy <dan@dennedy.org>
* src/modules/videostab/filter_videostab.c,
adjust in and out properties as needed because we cannot yet use negative
values to mean "from end."
- * src/modules/jackrack/plugin_mgr.c: reduce log level of some LADSPA-related
- exceptions
-
-2011-09-21 Marco Gittler <g.marco@freenet.de>
-
- * src/modules/videostab/filter_videostab2.yml: updated desc
-
2011-09-20 Marco Gittler <g.marco@freenet.de>
- * src/modules/videostab/filter_videostab2.yml: added description
-
* src/modules/videostab/filter_videostab2.c,
src/modules/videostab/transform_image.c,
src/modules/videostab/transform_image.h: set transform properties from mlt
- * src/modules/videostab/filter_videostab2.c: read filter params correct, set
- interpol type
-
2011-09-19 Marco Gittler <g.marco@freenet.de>
* src/modules/videostab/filter_videostab2.c,
src/modules/videostab/transform_image.c: use interpolation settings
- * src/modules/videostab/stabilize.c: log format error on draw*
-
- * src/modules/videostab/filter_videostab2.yml: added yml for videostab2
-
2011-09-11 Marco Gittler <g.marco@freenet.de>
* src/modules/videostab/stabilize.c, src/modules/videostab/transform_image.c:
src/modules/videostab/transform_image.h: avoid unreadable code like
(*format==mlt_image_rgb24?0:1) use mlt_types and names for it
- * src/modules/videostab/filter_videostab2.c: remove log since no parent/type
- yet
-
- * src/modules/videostab/filter_videostab2.c: removed unsued code (point 4 )
-
- * src/modules/videostab/filter_videostab2.c: removed printf from mlt filter
- code (point 9)
-
- * src/modules/videostab/filter_videostab2.c: use mlt_pool_release instead of
- mlt_properties_close (point 8)
-
- * src/modules/videostab/filter_videostab2.c: do not call stabilize_init()
- anymore (point 7) thx to Dan D.
-
- * src/modules/videostab/Makefile: fix makefile to respect global FLAGS (point
- 2)
-
-2011-09-02 Marco Gittler <g.marco@freenet.de>
-
- * src/modules/videostab/filter_videostab2.c: framesize 3/2 * w * h seems to
- bee too small for yuv420 (segfault in filter)
-
2011-08-19 Marco Gittler <g.marco@freenet.de>
* src/modules/videostab/Makefile, src/modules/videostab/factory.c,
2011-10-30 Dan Dennedy <dan@dennedy.org>
- * src/modules/gtk2/producer_pango.yml: remove invalid metadata item for pango
-
* src/modules/core/producer_consumer.c,
src/modules/core/producer_consumer.yml: add autoprofile property to consumer
producer
- * src/modules/decklink/producer_decklink.cpp: log profile info when profile
- not compatible with decklink mode
-
- * src/modules/avformat/producer_avformat.c: fix crash cleaning packet queues
- that were not created
-
- * src/framework/mlt_log.c: change default log level to WARN
-
-2011-10-29 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Let video_delay work with
- new_seek (AVCHD).
-
- * src/modules/avformat/producer_avformat.c: Renove start_time from avformat
- producer core object.
-
2011-10-16 Brian Matherly <pez4brian@yahoo.com>
* demo/mlt_voiceover, demo/pango.mlt, src/modules/core/data_fx.properties,
src/modules/gtk2/producer_pango.yml, src/tests/pango.c: Add "family" and
"style" properties to pango producer. Deprecate "font" property.
-2011-10-14 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Improve a/v sync and fix possible
- inf loop w/ audio_index=all Sometimes it would ignore the next packet that
- falls on the current frame time - ignore was too agressive. And with
- audio_index=all, it is faulty to predict interleaving level of streams
- sometimes causing continual backward seeks.
-
2011-10-11 Brian Matherly <pez4brian@yahoo.com>
* src/modules/decklink/producer_decklink.yml, src/modules/sox/filter_sox.yml:
src/modules/gtk2/producer_pango.yml: Add outline to pango and dynamic text
services. Add pad and align to dynamic text.
-2011-10-08 Brian Matherly <pez4brian@yahoo.com>
-
- * src/modules/gtk2/filter_dynamictext.c: dynamic text fixes: buffer overflows
- an support adjacent keywords.
-
-2011-10-09 Dan Dennedy <dan@dennedy.org>
-
- * src/melt/melt.c: Add -progress2 option to get progress with newlines.
- Makes easier to get progress updates in some scripts.
-
-2011-10-08 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix regression on audio devices.
-
-2011-10-05 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Improve previous fix (efebb3) to
- prevent infinite loop.
-
- * src/modules/avformat/producer_avformat.c: Prevent closing alreadu closed
- AVCoddecContexts. Patch supplied by Mikko Rapeli.
-
-2011-10-03 j-b-m <jb@kdenlive.org>
-
- * src/modules/kdenlive/producer_framebuffer.c: Fix framebuffer producer in
- property (3417991)
-
2011-10-02 Brian Matherly <pez4brian@yahoo.com>
* README, docs/TODO, docs/policies.txt, docs/services.txt: Remove docs/TODO,
src/modules/xml/mlt-xml.dtd, src/modules/xml/producer_xml.c: Add consumer
element to xml producer.
-2011-09-30 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sox/filter_sox.c: Fix segfault in sox with no effect.
-
-2011-09-29 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix race on stream index
- (kdenlive-2296)
-
- * src/modules/avformat/producer_avformat.c: Fix crash when codec not yet
- opened (or just closed?)
-
- * src/modules/avformat/producer_avformat.c: Fix some unprotected calls to
- av_close_input_file.
-
-2011-09-28 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/producer_decklink.cpp: Add re-open capability to
- decklink producer. This causes the producer to automatically close itself
- when it reaches the "end" as defined by an out or length property. Then, the
- same producer can be re-opened if reused elsewhere in a playlist or another
- instance of the decklink producer can use the same card. This requires that
- the decklink producer be permitted to play out to its duration.
-
-2011-09-27 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix multi-threaded encoding on
- libavcodec older than v53.
-
-2011-09-26 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_profile.c: Fix regression loading profile. Also, prefer
- mlt_environment(MLT_DATA) over $datadir to make indirection possible with
- MLT_DATA environment variable and to be consistent with mlt_profile_list().
-
- * src/framework/mlt_profile.c: Fix regression loading profile. Also, prefer
- mlt_environment(MLT_DATA) over $datadir to make indirection possible with
- MLT_DATA environment variable and to be consistent with mlt_profile_list().
-
2011-09-25 Brian Matherly <pez4brian@yahoo.com>
* src/modules/gtk2/filter_dynamictext.yml, src/modules/gtk2/producer_pango.c,
* src/modules/frei0r/factory.c, src/modules/jackrack/plugin_mgr.c: Load
frei0r and ladspa plugins relative to exe on win32
- * src/modules/videostab/stab/estimate.c: Fix videostab build on win32
-
* src/framework/Makefile, src/framework/mlt_factory.c,
src/framework/mlt_profile.c: Fix build on win32
- * src/modules/avformat/consumer_avformat.c: Add parenthesis to fix warning.
-
* src/framework/mlt_profile.c, src/framework/mlt_properties.c,
src/framework/mlt_repository.c: Fix and cleanup profile and preset dirs.
* src/framework/mlt_profile.c, src/framework/mlt_repository.c: Make profiles
relative to MLT_DATA instead of $prefix/share/mlt
-2011-07-22 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_factory.c: Make modules and data relative to executable
- for win32 and osx. Requires RELOCATABLE to be defined for osx.
-
2011-09-25 Dan Dennedy <dan@dennedy.org>
* src/modules/decklink/consumer_decklink.cpp,
src/modules/decklink/producer_decklink.cpp: Fix building decklink on win32
-2011-09-24 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/producer_decklink.cpp: Fix executing stop when not
- started (and vice versa).
-
-2011-09-23 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/linsys/consumer_SDIstream.c: Fix audio_index=all with linsys
- SDI consumer.
-
- * src/modules/core/filter_audiochannels.c: Fix uninitialized var in
- audiochannels filter.
-
-2011-09-22 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl_audio.c: Fix intermittent crash when closing
- sdl_audio.
-
-2011-09-22 Marco Gittler <g.marco@freenet.de>
-
- * src/modules/videostab/stab/estimate.c: fix to compile an MAC (point 1)
-
-2011-09-21 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_geometry.c: Serialize geometry with %g instead of my own
- macros.
-
2011-09-20 Dan Dennedy <dan@dennedy.org>
- * presets/consumer/avformat/Sony-PSP: Add Sony PlayStation Portable encode
- preset
-
* presets/consumer/avformat/XDCAM-HD422,
presets/consumer/avformat/atsc_1080i_50/DNxHD,
presets/consumer/avformat/atsc_1080i_5994/DNxHD,
src/modules/gtk2/filter_dynamictext.c,
src/modules/gtk2/filter_dynamictext.yml: Add filter_dynamictext.
-2011-09-15 Till Theato <root@ttill.de>
-
- * src/modules/kdenlive/filter_freeze.c: Freeze filter: Fix alpha handling.
-
- * src/modules/kdenlive/filter_freeze.c: Freeze filter: Stop using 'this'.
-
- * src/modules/kdenlive/producer_framebuffer.c: Framebuffer producer: Fix
- alpha handling (Kdenlive-2311).
-
-2011-09-14 Till Theato <root@ttill.de>
-
- * src/modules/kdenlive/producer_framebuffer.c: Producer framebuffer: Stop
- using 'this'.
-
-2011-09-14 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_factory.c: Always Load the system locales.
-
2011-09-11 Dan Dennedy <dan@dennedy.org>
* src/modules/sox/Makefile, src/modules/sox/factory.c,
Document normalise and analysis for sox. This change separates the general
sox metadata from effect instance metadata.
- * src/modules/sox/filter_sox.c: Add analysis effect to sox filter. This
- analyzes the audio to determine a normalized gain level. The result is
- suitable for XML serialization.
-
-2011-09-10 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sox/filter_sox.c: Only compute rms if normalise.
-
- * src/modules/sox/filter_sox.c: Only compute rms if normalise.
-
- * src/modules/sox/filter_sox.c: Remove some old cruft in sox.
-
- * src/framework/mlt_property.c: Fix race conditions in mlt_property.
-
-2011-09-10 j-b-m <jb@kdenlive.org>
-
- * src/framework/mlt_geometry.c: Skip empty keyframes when parsing geometry.
-
2011-09-09 Dan Dennedy <dan@dennedy.org>
* src/modules/core/Makefile, src/modules/core/factory.c,
presets/consumer/avformat/atsc_720p_60/DNxHD: Add a bunch of DNxHD encode
presets.
- * src/modules/core/transition_composite.c: Fix composite_copy_region on
- locale using comma for decimal.
-
-2011-09-08 j-b-m <jb@kdenlive.org>
-
- * src/framework/mlt_property.c: Fix locale corruption. setlocale returns a
- pointer that is no longer valid after the intermediate call to setlocale.
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Fix Kdenlive title module
- breaking locale.
-
-2011-09-06 Dan Dennedy <dan@dennedy.org>
-
- * presets/consumer/avformat/XDCAM-HD422: Add XDCAM HD encode preset.
-
- * src/framework/mlt_multitrack.c: Fix many tracks with avformat producer at
- same time (kdenlive-2286).
-
- * presets/consumer/avformat/XDCAM-HD422: Fix many tracks with avformat
- producer at same time (kdenlive-2286).
-
-2011-09-05 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Add support for writing timecode
- from vitc metadata.
-
2011-09-04 Dan Dennedy <dan@dennedy.org>
* src/modules/melt/producer_melt.c, src/modules/xml/producer_xml.c: Change
* src/framework/mlt_cache.c, src/framework/mlt_cache.h: Add
mlt_cache_get_size()
- * src/modules/melt/producer_melt.c: Fix melt crash on many avformat producers
- active.
-
- * src/framework/mlt_cache.c: Fix setting the size of a cache up to 200.
-
2011-09-03 Dan Dennedy <dan@dennedy.org>
* src/modules/decklink/producer_decklink.cpp,
* src/modules/sox/factory.c, src/modules/sox/filter_sox.c: Use the sox
version in metadata and serialization.
- * src/modules/frei0r/factory.c: Serialize the frei0r version.
-
* src/modules/xml/consumer_xml.c, src/modules/xml/mlt-xml.dtd: Add MLT
version to serialized XML.
* src/modules/frei0r/factory.c, .../motion_est/filter_autotrack_rectangle.c:
Convert some printfs to fprintf(stderr) or mlt_log.
-2011-08-29 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix crash at end of second pass.
-
-2011-08-28 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/producer_decklink.cpp: Copy VITC to frame meta
- property. Can be burned in with data_show filter. Perhaps this can be stored
- on the producer property using key frames for discontinuities. Then, it can
- be retrieved and supplied to some new filter that would put the
- meta.attr.vitc.markup property on frames.
-
-2011-08-22 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sox/factory.c: Fix bad comparison on metadata for 'sox' (not
- sox.*)
-
- * src/modules/frei0r/factory.c: Initialize stat buffer.
-
2011-08-16 Dan Dennedy <dan@dennedy.org>
- * src/modules/xml/consumer_xml.yml: Document serializing xml to property.
-
* src/modules/xml/consumer_xml.c, src/modules/xml/consumer_xml.yml: Add
no_meta property to xml consumer. Applications that use the consumer for its
project file might want to reduce xml bloat by setting this.
- * src/modules/xml/consumer_xml.yml: Document some xml consumer properties.
-
* src/modules/jackrack/consumer_jack.c,
src/modules/jackrack/filter_jackrack.c, src/modules/jackrack/process.c: Fix
segfault on concurrent calls to jack_activate().
2011-08-13 Dan Dennedy <dan@dennedy.org>
- * src/framework/mlt_geometry.c: Serialize geometry with integer or float
- representation.
-
- * src/modules/avformat/filter_avcolour_space.c: Check swscale context before
- using it. Old patch suggested by j-b-m on Feb 9, 2011.
-
- * src/modules/videostab/filter_videostab.c: More cleanup.
-
- * src/modules/videostab/Makefile: Fix make install.
-
* src/framework/mlt_filter.c, src/framework/mlt_filter.h,
src/mlt++/MltFilter.cpp, src/mlt++/MltFilter.h: Add mlt_filter_get_length2.
-2011-08-12 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/videostab/filter_videostab.c: Some cleanup - reformating,
- consolidation
-
- * src/modules/videostab/filter_videostab.c: Stop using 'this'
-
- * src/modules/videostab/filter_videostab.c: Remove global variables.
-
- * src/modules/videostab/stab/estimate.c: Fix compile error on MAXFLOAT.
-
- * src/modules/videostab/filter_videostab.c: Fix for GPL license.
-
2011-08-12 Marco Gittler <g.marco@freenet.de>
* src/modules/videostab/factory.c,
src/modules/videostab/filter_videostab.yml: added yml metadata
- * src/modules/videostab/filter_videostab.c: removed comments
-
- * src/modules/videostab/filter_videostab.c: some cleanup, loading from
- deshake file works now (if correct) for my sample (45 frames) the filter will
- do 2 runs, first with 37 , second with 45 frames. so the resut will look like
- not working. correct length deshake file will work.
-
2011-08-11 Marco Gittler <g.marco@freenet.de>
- * src/modules/videostab/filter_videostab.c: some vars are now local instead
- of global. storing pos_h now works, but loading pos_h from file does not
- produce the same result.
-
* src/modules/videostab/factory.c, src/modules/videostab/filter_videostab.c:
compile fix
src/modules/videostab/stab/vector.h: first version of video stabilization
from http://vstab.sourceforge.net/
-2011-08-09 Till Theato <root@ttill.de>
-
- * src/modules/jackrack/factory.c: Fix regression with ladspa metadata.
-
-2011-08-06 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/jackrack/consumer_jack.c: Use JACK to lookup default ports.
-
2011-08-03 Dan Dennedy <dan@dennedy.org>
* src/modules/jackrack/Makefile, src/modules/jackrack/configure,
* src/modules/jackrack/Makefile, src/modules/jackrack/consumer_jack.yml: Add
service metadata for jack consumer.
- * src/modules/jackrack/consumer_jack.c: Add volume property to jack consumer.
-
- * src/modules/jackrack/filter_jackrack.c: Fail gracefully when unable to
- connect to JACK.
-
* src/modules/jackrack/Makefile, src/modules/jackrack/consumer_jack.c,
src/modules/jackrack/factory.c: Add audio-only JACK consumer. Fires
consumer-frame-show for video frames.
-2011-08-01 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix regression in multiple audio
- tracks. Regresssion introduced with audiochannels normalization filter.
-
-2011-07-28 Maksym Veremeyenko <verem@m1stereo.tv>
-
- * src/modules/decklink/consumer_decklink.cpp: Make scheduling priority of
- decklink lib thread adjustable. Uses existing mlt_consumer priority
- property, but also responds to special "max" and "min" values.
-
-2011-07-26 Brian Matherly <pez4brian@yahoo.com>
-
- * src/modules/core/transition_composite.yml: Mark composite transition
- metadata properties that are deprecated as such.
-
- * src/melt/melt.c: Filter service metadata from being displayed if it is
- tagged as "Hidden".
-
2011-07-24 Brian Matherly <pez4brian@yahoo.com>
* Makefile, src/modules/avformat/consumer_avformat.yml,
loader producer. Add yml validation rule to Makefile. All yml files pass
validation against metaschema.yaml.
-2011-07-24 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.yml: Document the redirect property.
-
- * src/modules/avformat/consumer_avformat.c: Remove mlt protocol, use
- ByteIOContext if <v53 libavformat.
-
-2011-07-11 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Add support for custom
- AVIOContext. New versions of ffmpeg drop ability to register a protocol.
-
2011-07-22 Dan Dennedy <dan@dennedy.org>
- * src/swig/Makefile: Add empty uninstall target to swig Makefile.
-
* src/modules/core/filter_mirror.yml, src/modules/core/filter_mono.yml,
src/modules/core/filter_obscure.yml, src/modules/core/filter_region.yml,
src/modules/core/transition_luma.yml, src/modules/core/transition_mix.yml,
src/modules/xml/consumer_xml.yml: Cleanup Brian's service metadata
contribution.
- * src/modules/decklink/consumer_decklink.cpp: Touchup spacing in decklink
- consumer.
-
-2011-07-22 Maksym Veremeyenko <verem@m1stereo.tv>
-
- * src/modules/decklink/consumer_decklink.cpp: Log when decklink audio buffer
- level changes. Very useful to understand when unexpected behavior happens.
-
- * src/modules/decklink/consumer_decklink.cpp: Prevent decklink audio buffer
- overflow. Flush audio buffer if it more then preroll configured length.
-
- * src/modules/decklink/consumer_decklink.cpp: Notify dropped frame in
- decklink. i.e. status *bmdOutputFrameDropped*
-
- * src/modules/decklink/consumer_decklink.cpp: Avoid float rounding error when
- calculating audio timestamp.
-
-2011-07-22 Dan Dennedy <dan@dennedy.org>
-
* src/modules/avformat/consumer_avformat.c, src/modules/avformat/factory.c,
src/modules/avformat/producer_avformat.c: Make ffmpeg v53-specific code more
readable and searchable.
- * src/modules/avformat/consumer_avformat.c: Fix codec-specific defaults for
- libavcodec v53 (3370720).
-
- * src/modules/avformat/consumer_avformat.c: Refactor to pass AVCodec into
- add_audio/video_stream.
-
* configure, src/framework/mlt_version.h: set interim version 0.7.5
* src/framework/mlt_property.c, src/framework/mlt_property.h: Fix build on
Debian kfreebsd.
-2011-07-21 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_consumer.h: Document the priority property.
-
-2011-07-22 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/consumer_decklink.cpp: Touchup spacing in decklink
- consumer.
-
-2011-07-22 Maksym Veremeyenko <verem@m1stereo.tv>
-
- * src/modules/decklink/consumer_decklink.cpp: Log when decklink audio buffer
- level changes. Very useful to understand when unexpected behavior happens.
-
- * src/modules/decklink/consumer_decklink.cpp: Prevent decklink audio buffer
- overflow. Flush audio buffer if it more then preroll configured length.
-
- * src/modules/decklink/consumer_decklink.cpp: Notify dropped frame in
- decklink. i.e. status *bmdOutputFrameDropped*
-
- * src/modules/decklink/consumer_decklink.cpp: Avoid float rounding error when
- calculating audio timestamp.
-
-2011-07-22 Dan Dennedy <dan@dennedy.org>
-
* src/modules/avformat/consumer_avformat.c, src/modules/avformat/factory.c,
src/modules/avformat/producer_avformat.c: Make ffmpeg v53-specific code more
readable and searchable.
- * src/modules/avformat/consumer_avformat.c: Fix codec-specific defaults for
- libavcodec v53 (3370720).
-
- * src/modules/avformat/consumer_avformat.c: Refactor to pass AVCodec into
- add_audio/video_stream.
-
* configure, src/framework/mlt_version.h: set interim version 0.7.5
* src/framework/mlt_property.c, src/framework/mlt_property.h: Fix build on
Debian kfreebsd.
-2011-07-21 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_consumer.h: Document the priority property.
-
2011-07-19 Brian Matherly <pez4brian@yahoo.com>
* src/modules/core/filter_mirror.yml, src/modules/core/filter_mono.yml,
2011-07-16 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog for v0.7.4
-
* Doxyfile, configure, docs/melt.1, docs/melt.txt,
src/framework/mlt_version.h: Set version to 0.7.4
- * NEWS: Add release notes for v0.7.4
-
* src/modules/jackrack/factory.c, src/modules/jackrack/plugin_desc.c,
src/modules/jackrack/plugin_desc.h: Properly represent LADSPA plugin author.
-2011-07-14 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Cleanup fprintf left in last
- commmit
-
- * src/modules/avformat/producer_avformat.c: Fix audio glitch on seek
- (3362840).
-
-2011-07-13 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/xml/producer_xml.c: Load XML with LC_NUMERIC without changing
- global locale. Uses mlt_properties_set_lcnumeric() instead of setlocale().
- This is only known to work on Linux.
-
- * src/framework/mlt_properties.c: Use correct constant for
- mlt_properties_set_lcnumeric().
-
-2011-07-12 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix regression seeking to in
- point on seekable.
-
2011-07-11 Dan Dennedy <dan@dennedy.org>
* src/framework/mlt_properties.c, src/framework/mlt_property.c,
* presets/consumer/avformat/webm, presets/consumer/avformat/webm-pass1,
presets/consumer/avformat/webm-pass2: Fix webm preset.
- * src/framework/mlt_properties.c: Ensure serialized yaml is LC_NUMERIC=C.
- This is needed to ensure consistency. The metadata is read as string data and
- converted to numbers on demand. This is why loading defaults to C locale -
- since they were authored with that in mind. However, some plugins dynamically
- generate metadata and may set values with int or double. Therefore, we need
- to make it all output consistently, and for now that means C.
-
- * src/framework/mlt_property.c: Protect locale hack with a mutex to ensure
- consistency.
-
* src/framework/mlt_consumer.c, src/framework/mlt_consumer.h,
src/modules/sdl/consumer_sdl_preview.c: Make maximum consecutive-dropped
frames configurable. Defaults to old value of 5 that seems more preferable
for video editing.
- * src/framework/mlt_playlist.c: Fix playlist corruption with long blanks
- (kdenlive-2219).
-
- * src/modules/gtk2/producer_pango.c: Add a workaround in pango for old
- kdenlive countdowns.
-
2011-07-09 Dan Dennedy <dan@dennedy.org>
* src/modules/feeds/NTSC/data_fx.properties,
mlt_property_get_string_l. Locale-specific variants of key properties
functions.
- * src/modules/core/filter_obscure.c: Let obscure accept / as a coordinate
- delimiter.
-
- * src/modules/frei0r/factory.c: Make frei0r version metadata support locale.
- Patch by j-b-m
-
2011-07-07 Dan Dennedy <dan@dennedy.org>
* src/modules/core/filter_data_show.yml, src/modules/core/filter_gamma.yml,
2011-07-04 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/configure: Cleanup display of recommended versions.
-
- * presets/consumer/avformat/x264-medium-pass1: Skip audio output with first
- pass.
-
- * presets/consumer/avformat/x264-medium-pass1: Add new FFmpeg fastfirstpass
- option.
-
- * src/modules/avformat/consumer_avformat.c: Suppress confusing message when
- vpre does not exist.
-
* presets/consumer/avformat/x264-medium-baseline,
presets/consumer/avformat/x264-medium-main: Fix profile-based x264 presets
for FFmpeg v0.8+.
- * src/modules/avformat/consumer_avformat.c: Fix crash in consumer on FFmpeg
- v0.8 and later.
-
- * src/modules/avformat/configure: Revert removal of --avformat-ldextra.
-
- * src/modules/avformat/factory.c: Fix metadata for avformat
- demuxer/device-specific options.
-
* presets/consumer/avformat/x264-medium,
presets/consumer/avformat/x264-medium-baseline,
presets/consumer/avformat/x264-medium-main,
src/modules/avformat/producer_avformat.yml, src/modules/melt/producer_melt.c:
Support standard query syntax on avformat URL.
- * reconfigure: Add convenient reconfigure script.
-
-2011-07-03 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Change some verbose messages with
- new_seek to debug.
-
- * src/modules/avformat/producer_avformat.c: Fix file descriptor leak in
- reopen_video().
-
- * src/modules/avformat/producer_avformat.c: Fix race condition by adding
- take_lock to producer_open().
-
- * src/framework/mlt_consumer.c: Add check for null frame.
-
- * src/modules/dv/producer_libdv.c: Make libdv sample aspect ratio consistent
- with profiles. Patch by: Maksym Veremeyenko
-
2011-07-02 Dan Dennedy <dan@dennedy.org>
* src/modules/decklink/DeckLinkAPI_h.h,
src/modules/decklink/configure, src/modules/decklink/consumer_decklink.cpp,
src/modules/decklink/producer_decklink.cpp: Add Windows support for DeckLink.
-2011-06-26 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl.c: Make it easier to embed sdl in Windows
- applications.
-
-2011-06-25 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_consumer.c: Add handling for heavy frame-dropping with
- real_time>1.
-
- * src/framework/mlt_consumer.c: Improve reliability of real_time=1
- frame-dropping.
-
- * src/framework/mlt_consumer.c: Simplify and comment real_time=1
- frame-dropping.
-
-2011-06-24 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Use int64_t for req_position and
- int_position.
-
2011-06-22 Dan Dennedy <dan@dennedy.org>
* presets/consumer/avformat/dv_ntsc/DV,
presets/consumer/avformat/dv_pal_wide/DVCPRO50: Add DV and DVCPRO50 encode
presets.
-2011-06-21 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Make sure avformat consumer
- closes all mlt_frames.
-
- * src/modules/avformat/producer_avformat.c: Fix regression on avdevice. When
- using non-integer profile frame rate, supplying frame_rate on URL, and not
- supplying frame_rate_base on URL.
-
- * src/modules/core/producer_consumer.c: Fix xml producer overwriting explicit
- profile.
-
2011-06-17 Dan Dennedy <dan@dennedy.org>
* src/framework/Makefile, src/framework/mlt_types.h, src/melt/Makefile,
src/modules/avformat/Makefile, src/modules/gtk2/Makefile,
src/modules/sdl/Makefile, src/win32/fnmatch.c: Cleanup Win32 build.
- * src/framework/mlt_repository.c: Win32 compile fix.
-
2011-06-15 Dan Dennedy <dan@dennedy.org>
* src/framework/mlt_transition.c, src/modules/core/transition_composite.c:
Fix regression in field rendering luma transition. Due to refactoring
composite and luma into mlt_transition_get_progress_delta().
- * src/modules/avformat/producer_avformat.c: Fix int64_t to int overflow
- problem.
-
-2011-06-14 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/producer_decklink.cpp: Support decklink video input
- format detection. This makes it work with auto-producer. After calling
- mlt_profile_from_producer(), you must close the decklink producer and re-open
- it with the updated profile. Also, this adds support for top_field_first and
- colorspace indication.
-
2011-06-13 Dan Dennedy <dan@dennedy.org>
- * src/modules/decklink/producer_decklink.cpp: Fix waiting for frame in
- decklink producer.
-
- * profiles/sdi_486i_5994: Fix aspect ratio of sdi_486i_5994.
-
* src/modules/avformat/producer_avformat.c,
src/modules/avformat/producer_avformat.yml: Add video_delay to avformat
producer.
2011-06-11 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/producer_avformat.c: Provide A/V sync for non-seekable
- sources.
-
- * src/melt/melt.c: Fix melt -silent with pipe input.
-
* src/modules/decklink/producer_decklink.cpp,
src/modules/decklink/producer_decklink.yml: Add prefill property to decklink
producer.
- * src/modules/avformat/producer_avformat.c: Fix bug in avformat URL parsing.
- Especially reproducible on file: URLs.
-
- * src/modules/avformat/producer_avformat.c: Fix sync of multiple audio
- streams with audio_index=all.
-
-2011-06-10 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix infinite loop with
- audio_index=all on sample provided by BCE.
-
- * src/modules/decklink/consumer_decklink.cpp: Rework decklink consumer to use
- timestamped audio packet. Patches supplied by Maksym Veremeyenko.
-
-2011-06-08 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Disable new_seek on h264/ts from
- non-seekable source (udp, pipe).
-
-2011-06-07 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/gtk2/producer_pango.c: Fix pango producer from loading with
- empty string arg.
-
2011-06-06 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/consumer_avformat.c: Temporary fix for new crash when
- closing codec.
-
- * src/modules/avformat/consumer_avformat.c: Fix setting codec-specific
- options for avcodec v53.
-
- * src/modules/avformat/factory.c: Fix crash generating avformat metadata.
-
* src/framework/mlt_consumer.c, src/modules/avformat/consumer_avformat.yml:
Change consumer 'profile' property to 'mlt_profile' libavcodec uses the
profile property for aac and libx264.
2011-06-05 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/producer_avformat.c: Drop usage of av_demuxer_open()
- in avformat v53. It is causing problems and need more stability after the
- raft of changes.
-
- * src/modules/avformat/producer_avformat.c: Fix regressions on libavformat
- v53 and failing on invalid file.
-
* src/modules/avformat/consumer_avformat.yml,
- src/modules/avformat/producer_avformat.yml: Change URI to URL in avformat
- yaml.
-
- * src/modules/avformat/producer_avformat.c: Fix compilation error on
- libavformat v53.
-
- * src/melt/melt.c, src/modules/avformat/consumer_avformat.c: Send melt -query
- and -help to stdout. Nice for use with pager or grep, awk, etc.
-
- * src/melt/melt.c: Do not open terminal on stdin if not a tty.
-
- * src/melt/melt.c: Have melt detect 'pipe:' and disable reading stdin on
- terminal.
-
- * src/modules/avformat/producer_avformat.c: Fix setting default streams on
- non-seekable streams.
-
- * src/modules/avformat/producer_avformat.c: Fix setting demuxer private
- options libavformat for v53+.
-
- * src/modules/avformat/producer_avformat.c: Tidy code dealing with
- AVFormatParameters.
-
- * src/modules/avformat/producer_avformat.c: Refactor common code around
- producer_open into producer_open.
-
- * src/modules/avformat/producer_avformat.c: minor cleanup in return handling
- in parse_url
-
-2011-06-04 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Use a single AVFormatContext for
- non-seekable sources. This provides better support for reading from network
- streams such as rtsp, rtmp, udp, and hopefully pipe.
-
- * src/modules/avformat/producer_avformat.c: Refactor avformat get_image()
- into new seek_video().
-
- * src/modules/avformat/producer_avformat.c: refactor avformat producer_open
-
- * src/modules/avformat/producer_avformat.c: cleanup producer_avformat_init
-
- * src/modules/decklink/consumer_decklink.cpp: Default decklink consumer to
- onefield deinterlace method.
+ src/modules/avformat/producer_avformat.yml: Change URI to URL in avformat
+ yaml.
- * src/modules/decklink/consumer_decklink.cpp: Fix decklink keyer playout
- speed (3311056).
+ * src/melt/melt.c, src/modules/avformat/consumer_avformat.c: Send melt -query
+ and -help to stdout. Nice for use with pager or grep, awk, etc.
2011-06-03 Dan Dennedy <dan@dennedy.org>
src/modules/decklink/consumer_decklink.yml: Enable external keyer on decklink
consumer. Patch supplied by Maksym Veremeyenko.
-2011-06-02 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/producer_decklink.cpp: Fix deadlock on no signal in
- decklink producer.
-
- * src/modules/decklink/consumer_decklink.cpp: Fix crash in decklink with
- keyer and interlaced clips (3310104).
-
- * src/modules/decklink/Makefile: Install consumer_decklink.yml.
-
-2011-05-31 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/producer_decklink.cpp: Let decklink run forever. Also
- fix setting resource property.
-
2011-05-30 Dan Dennedy <dan@dennedy.org>
- * src/modules/decklink/consumer_decklink.cpp: Fix decklink choppy playback
- (3308341). This would occur after several pause and play cycles.
-
- * src/modules/rotoscoping/filter_rotoscoping.yml: Make rotoscoping filter
- metadata valid yaml.
-
* src/modules/linsys/Makefile, src/modules/linsys/consumer_sdi.yml,
src/modules/linsys/factory.c: Add service metadata to linsys module (WIP).
src/modules/dv/factory.c, src/modules/dv/producer_libdv.yml: Add service
metdata for dv module (WIP).
- * src/swig/ruby/metadata.rb: Add ruby script to generate wiki text files.
-
* src/modules/core/Makefile, src/modules/core/factory.c,
src/modules/core/filter_audiowave.yml,
src/modules/core/filter_brightness.yml,
2011-05-28 Dan Dennedy <dan@dennedy.org>
- * src/modules/decklink/producer_decklink.cpp: Report dropped frames.
-
- * src/modules/decklink/producer_decklink.cpp: Fix memory leak in decklink
- producer.
-
* src/swig/python/getimage.py, src/swig/python/waveforms.py: Convert Python
examples to new frame method.
- * src/swig/python/build: Fix python binding for OS X
-
- * src/swig/mlt.i: Add mlt.Frame.get_image for Python.
-
- * src/melt/melt.c: Refactor melt to mlt_profile_from_producer.
-
* src/framework/mlt_profile.c, src/framework/mlt_profile.h,
src/mlt++/MltProfile.cpp, src/mlt++/MltProfile.h: Add
mlt_profile_from_producer(). This new function contains the auto-profile
feature. Plus setters for Mlt::Profile.
-2011-05-26 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_cache.c: Do not immediately destroy all cache items on
- purge. This is behaving badly with the addition of mlt_service_cache_purge
- in the avformat producer because there were frames in consumer buffers
- holding references to cache items calling mlt_cache_item_close on
- destruction.
-
-2011-05-25 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_consumer.c: Prevent multiple starts on mlt_consumer.
-
2011-05-22 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/producer_avformat.c: Fix full closure of avformat on
- explicit close. JBM wrote: Creating a video4linux producer like (simplified
- code): producer = new Mlt::Producer(*profile, "video4linux2:/dev/video0");
- consumer->connect(*producer); consumer->start(); It works fine. But when I
- want to stop the capture, there is no way to stop the video4linux producer.
- Deleting the producer and the consumer still leaves the video4linux device
- open. After a few hours of struggling, I figured out that some stuff was
- kept in the cache. Adding : mlt_service_cache_purge(
- MLT_PRODUCER_SERVICE(parent) ); to producer_close (as already done for the
- qimage producer for example) fixes the issue.
-
- * src/modules/avformat/producer_avformat.c: Fix regression in
- protocol/avdevice handling.
-
* src/modules/jackrack/Makefile, src/modules/jackrack/blacklist.txt,
src/modules/jackrack/plugin_mgr.c, src/modules/jackrack/plugin_mgr.h: Add
blacklist for ladspa filters. Initially includes dssi-vst since that is
unstable on AV Linux 5.
- * configure: Fix segfault in yadif with gcc 4.6 -O1 or -O2.
-
2011-05-17 Dan Dennedy <dan@dennedy.org>
- * src/modules/jackrack/jack_rack.c: Do not destroy shared plugin_mgr when
- closing instance.
-
* src/modules/jackrack/factory.c, src/modules/jackrack/jack_rack.c: Let all
instances of ladspa share single plugin_mgr.
-2011-05-16 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_resize.c: Fix regression getting consumer
- aspect_ratio.
-
- * src/modules/feeds/PAL/data_fx.properties: Fix background color on default
- PAL data_show.
-
- * src/modules/core/transition_composite.c: Fix manual deinterlace on B in
- composite.
-
2011-05-15 Dan Dennedy <dan@dennedy.org>
* docs/melt.1, src/melt/melt.c: Document -jack option.
- * docs/melt.1: Add -query preset to man page.
-
- * src/modules/jackrack/filter_jackrack.c: Change a log item to debug.
-
* src/melt/melt.c, src/modules/jackrack/filter_jackrack.c,
src/modules/jackrack/process.c: Add first draft of JACK transport sync.
- * src/framework/mlt_consumer.c: Improve frame-dropping for real_time=1. Uses
- thresholds relative to fps and buffer levels. Properly drops more frames to
- keep audio continuous. Does not drop first several frames to prevent chopping
- playback.
-
- * src/modules/sdl/consumer_sdl_preview.c: Add audio_off and frequency to
- properties passed to sdl consumer.
-
- * src/framework/mlt_producer.c: Fix dox error.
-
2011-05-14 Dan Dennedy <dan@dennedy.org>
- * src/modules/jackrack/factory.c: Fix big slowdown enumerating all metadata
- for ladspa plugins.
-
* configure, src/mlt++/configure: Fix build on Debian GNU/kFreeBSD.
2011-05-12 Dan Dennedy <dan@dennedy.org>
future support for property animation (automation), which JACK Rack lacks.
However, it does still support loading and processing JACK Rack files.
- * src/modules/sox/factory.c: Simplify sox metadata generator.
-
-2011-05-09 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/configure: Allow decklink to build on OS X.
-
- * src/modules/sdl/consumer_sdl_preview.c: sdl_preview should default to
- real_time=1
-
- * src/framework/mlt_consumer.c: Revert change to max consecutive dropped
- frames. At least until a better heuristic is determined.
-
2011-05-08 Dan Dennedy <dan@dennedy.org>
- * src/modules/sox/factory.c: Add version check for SOX_EFF_INTERNAL.
-
* src/modules/sox/Makefile, src/modules/sox/factory.c,
src/modules/sox/filter_sox.c, src/modules/sox/filter_sox.yml: Add support for
sox.effect variants. The legacy forms of 'sox:"effect options"' and 'sox
metadata for both the generic 'sox' filter and all of the new 'sox.effect'
ones including their usage help!
- * src/modules/avformat/Makefile: Install consumer_avformat.yml
-
* src/modules/avformat/filter_avresample.c, src/modules/core/loader.ini: Fix
inadvertent reording of resample filters. And add debug log to avresample.
2011-05-06 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/producer_avformat.c: Pad the last audio frame with
- silence. Instead of returning fewer samples than requested.
-
- * src/framework/mlt_frame.h: Document the frame audio and image properties.
-
* src/framework/mlt_tractor.c, src/modules/avformat/producer_avformat.c,
src/modules/dv/producer_libdv.c, src/modules/vorbis/producer_vorbis.c: Make
the frame audio properties consistent.
- * src/modules/avformat/producer_avformat.c: Fix avformat producer to use new
- mlt audio formats.
-
- * src/modules/core/filter_audioconvert.c: Add conversion routines for new
- audio formats. These only doing conversion _from_ the new types
- mlt_audio_s32le and mlt_audio_f32le. There are no plans at the moment for
- conversion into them, but it is certainly not out of the question.
-
* src/framework/mlt_frame.c, src/framework/mlt_types.h: Add mlt_audio_s32le
and mlt_audio_f32le audio formats.
a new filter to be more manageable. Eventually, we can add options on what to
do when adding/removing channels.
-2011-05-05 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix channel count for resizing
- decoded audio buffer when not resampling.
-
- * src/modules/avformat/producer_avformat.c: Fix regressions in audio
- decoding.
-
- * src/modules/avformat/producer_avformat.c: Cleanup compile warnings.
-
- * src/modules/avformat/producer_avformat.c: Simplify audio pointer and sample
- size code.
-
-2011-05-01 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: WIP to get >16-bit multi-channel
- audio working. Seems close, but something is wrong.
-
-2011-05-04 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Copy cached image if writable
- copy requested.
-
2011-05-03 Dan Dennedy <dan@dennedy.org>
* configure, src/framework/mlt_transition.c: Ensure transition B frames get
2011-05-01 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog for v0.7.2
-
* Doxyfile, configure, docs/melt.1, src/framework/mlt_version.h: Set version
to 0.7.2
- * NEWS: Add release notes for v0.7.2.
-
* src/modules/avformat/filter_avresample.c,
src/modules/resample/filter_resample.c: Finish work to normalize channel
count. Also, refactor the audio resamplers to use mlt_audio_format_size()
src/modules/core/producer_noise.c, src/modules/core/producer_ppm.c: Refactor
to mlt_frame_set_audio().
- * src/melt/melt.c: Let 'Q' stop melt as well.
-
* src/modules/feeds/NTSC/data_fx.properties,
src/modules/feeds/PAL/data_fx.properties: Fix alpha on color of some
data-feed properties.
- * src/modules/avformat/factory.c: Free temp string.
-
* src/modules/avformat/consumer_avformat.c, src/modules/avformat/factory.c,
src/modules/avformat/producer_avformat.c: Add support for new codec- and
muxer-specific AVOptions.
-2011-04-30 Dan Dennedy <dan@dennedy.org>
-
- * setenv: DYLD_LIBRARY_PATH not needed for me on OS X.
-
- * src/modules/avformat/producer_avformat.c: Fix sample rate and channel count
- from avformat producer. If unable to resample or the decoder does not give
- the requested channel count, then we should return the actual values so
- downstream components can do the correct thing if they can. A good example of
- this is 6 channel AAC when the consumer requests 2 channels. Unlike the AC-3
- decoder, the AAC decoder can not downmix. So, we were returning audio pcm
- containing 6 channels but with a channel count of 2.
-
-2011-04-29 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Try to duplicate last image if
- decoding fails.
-
2011-04-22 Dan Dennedy <dan@dennedy.org>
- * src/framework/mlt_consumer.c: Fix intermitent crash in mlt_consumer
- consumer_read_ahead_thread.
-
- * src/modules/avformat/producer_avformat.c: Use new
- av_get_bits_per_sample_fmt() in avformat producer.
-
* src/modules/avformat/consumer_avformat.c,
src/modules/avformat/producer_avformat.c: Use new avio functions in avformat
module.
2011-04-21 Dan Dennedy <dan@dennedy.org>
- * src/modules/sdl/consumer_sdl_audio.c: Fix deadlock in sdl_audio appearing
- in kdenlive.
-
- * src/modules/core/producer_ppm.c: Fix compile warns in producer_ppm.c.
-
* src/modules/avformat/filter_avcolour_space.c,
src/modules/avformat/producer_avformat.c: Fix regression initializing
coefficients.
- * src/modules/avformat/producer_avformat.c: Use newer
- av_get_sample_fmt_name() if available.
-
* src/modules/avformat/consumer_avformat.c,
src/modules/avformat/filter_avcolour_space.c,
src/modules/avformat/filter_swscale.c,
src/modules/avformat/producer_avformat.c: Fix avformat build with libavcodec
v53.
- * src/modules/avformat/configure: Fix detect swscale on libavcodec major
- version bump.
-
-2011-04-18 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/producer_colour.c: Fix corruption in color producer
- (3288984)
-
-2011-04-12 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/consumer_decklink.cpp: Fix decklink consumer on
- devices without keyer.
-
2011-04-09 Dan Dennedy <dan@dennedy.org>
* src/framework/mlt_profile.c, src/mlt++/MltProfile.cpp,
src/mlt++/MltProfile.h, src/swig/mlt.i: Add Mlt::Profile.list().
- * src/framework/mlt_profile.c: Fix mlt_profile_list when MLT_PROFILES_PATH
- not set.
-
-2011-04-08 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/kdenlive/filter_freeze.c: Fix deadlock in freeze filter.
- Reported by Andrew Wason.
-
2011-04-07 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/consumer_avformat.yml, src/modules/avformat/factory.c,
src/modules/avformat/producer_avformat.yml: Add avformat consumer metadata.
Improve avformat producer metadata. Significantly extend each with AVOptions.
-2011-04-06 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/transition_region.c: Better fix to the region regression
- (3277867). This one works with bug report test case, timecode overlay in
- Kdenlive Render, and Region transition in Kdenlive.
-
- * src/modules/core/transition_composite.c: Fix regression on region
- transition (3277867).
-
2011-04-04 Dan Dennedy <dan@dennedy.org>
* demo/README, demo/demo.ini, demo/mlt_pango_keyframes,
demo/pango_keyframes.mpl: Add mlt_pango_keyframes demo.
- * src/modules/gtk2/producer_pango.c: Make pango file on invalid file
- (3272537).
-
2011-04-03 Dan Dennedy <dan@dennedy.org>
* docs/melt.1, docs/melt.txt, src/melt/melt.c: Add -query formats and codecs
* src/framework/mlt_profile.c, src/framework/mlt_profile.h: Add
mlt_profile_list().
- * src/modules/decklink/consumer_decklink.yml: Add parameter descriptions.
-
-2011-04-02 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/consumer_decklink.cpp: Add keyer support to decklink
- consumer.
-
2011-03-31 Dan Dennedy <dan@dennedy.org>
* src/modules/decklink/consumer_decklink.yml,
2011-03-27 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/consumer_avformat.c: Fail gracefully on unsupported
- codec (3251438).
-
* configure, src/modules/core/transition_composite.c: Fix regression in
region filter (3251260).
- * ChangeLog: Update ChangeLog for v0.7.0.
-
* Doxyfile, configure, src/framework/mlt_version.h: Set version to 0.7.0
- * NEWS: Add release notes for v0.7.0.
-
- * src/modules/melt/producer_melt.c: Fix segfault on missing melt argument
- (3249982).
-
- * src/modules/avformat/producer_avformat.c: Fix a segfault in avformat with
- parallel consumer.
-
- * src/modules/core/transition_composite.c: Fix composite using wrong B frame
- scaling. This could happen when the caller of mlt_frame_get_image supplied 0
- for width and height. For example, Kdenlive's GL output with the sdl_audio
- consumer with real_time > 1 and paused.
-
- * docs/melt.1: Fix segfaul on missing melt argument (3249982).
-
- * src/modules/sdl/consumer_sdl_audio.c: Fix some crashing in sdl_audio.
-
- * src/modules/sdl/consumer_sdl_audio.c: Also increase audio_buffer default in
- sdl_audio.
-
- * src/modules/avformat/configure: Disable VDPAU by default. Require new
- --avformat-vdpau to enable it.
-
* src/modules/avformat/consumer_avformat.c, src/modules/sox/filter_sox.c,
src/modules/xml/producer_xml.c: Use mlt_properties_get_value where possible.
src/modules/linsys/configure: Enable linsys by default on Linux. Disable
linsys and decklink by default on OS X and Windows.
- * src/modules/configure: Display all configure options with --help.
- Regardless of --enable-gpl setting.
-
- * src/modules/avformat/producer_avformat.c: Redo locking in avformat
- producer. This significantly improves concurrency. The service locks added
- during parallel consumer development also introduced a concurrency
- performance regression even for the single-threaded consumer. The result was
- much audio discontinuity due to audio output buffer underruns. As a result,
- the recent bug fix to re-open the video demuxer upon seeking to the first
- frame had to be rewritten.
-
2011-03-23 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/vdpau.c: Fix vdpau crashes when failed to init.
-
- * src/modules/avformat/vdpau.c: Fix unchecked vdpau pointer.
-
- * src/modules/sdl/consumer_sdl_preview.c: Default sdl_preview prefill to 1.
- Since buffer and prefill were recently passed from sdl_preview onto sdl,
- sdl's default buffer level changed to the base service default of 25. That
- change increases the latency of transport controls. Changing the prefill to 1
- resolves that while still allowing the rendering thread a chance to do some
- anticipatory work.
-
- * src/modules/decklink/consumer_decklink.cpp: Fix a comment in decklink
- consumer.
-
* src/framework/mlt_consumer.c, src/modules/decklink/consumer_decklink.cpp:
Fix a couple null pointer bugs.
-2011-03-22 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/consumer_decklink.cpp: Improve frame-dropping in
- decklink.
-
2011-03-20 Dan Dennedy <dan@dennedy.org>
* src/modules/jackrack/filter_jackrack.c, src/modules/jackrack/plugin.h,
* profiles/atsc_1080p_50, profiles/atsc_1080p_5994, profiles/atsc_1080p_60:
Add high frame rate 1080p profiles.
-2011-03-17 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix regression on seeking to
- first frame with audio_index set.
-
-2011-03-14 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Add force_length and
- adjust_length properties. The reporter on kdenlive bug 2003 reports another
- user on IRC had the same problem with clips being too long. Change the
- default length adjustment to be more safe and add new properties to affect
- the heuristic for other applications that might want a different behavior.
- adjust_length applies a plus/minus operand to the detected length.
- force_length provides a brute force length override.
-
- * src/modules/avformat/producer_avformat.c: Fix some incorrect frame rates in
- avformat (kdenlive-1616).
-
- * src/modules/frei0r/factory.c: Support frei0r transitions that use
- f0r_update2().
-
- * configure: Fix amd64 detection on FreeBSD. Patch from Alberto Villa.
-
-2011-03-13 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_crop.c: Add boolean use_profile property to crop
- filter. This lets one express crop amounts in pixels relative to profile
- resolution instead of in terms of source resolution.
-
- * src/modules/frei0r/blacklist.txt: We do not yet support
- f0r_param_position_t.
-
-2011-03-12 Ertan Deniz <ertanden@gmail.com>
-
- * src/framework/mlt_factory.c: Set global variables to NULL in
- mlt_factory_close to enable mlt_factory to be initialized and closed
- multiple times.
-
-2011-03-12 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Prefer opening codec by name
- instead of by ID. This fixes a bug with actually using libxvid instead of
- mpeg4 because both share the same CODEC_ID_MPEG4. This is similar to the
- recent problem with ac3 selection in new versions of ffmpeg that have 2 ac3
- encoders.
-
2011-03-09 Dan Dennedy <dan@dennedy.org>
* src/modules/frei0r/filter_frei0r.c, src/modules/frei0r/frei0r_helper.c,
mlt_transition_get_position. frei0r's time parameter is seconds, but we were
passing frame count.
- * src/modules/core/transition_region.c: Fix region transition with more than
- 2 tracks.
-
* src/modules/core/transition_region.c, src/modules/plus/transition_affine.c:
Refactor to mlt_transition_get_position()
src/mlt++/MltTransition.cpp, src/mlt++/MltTransition.h: Add
mlt_transition_get_position()
- * src/modules/core/transition_luma.c: Remove obsolete unique position on
- frame.
-
- * src/framework/mlt_transition.c: Use the producer when always active.
-
* src/modules/core/filter_luma.c, src/modules/core/filter_watermark.c,
src/modules/dgraft/filter_telecide.c, src/modules/kdenlive/filter_freeze.c,
.../motion_est/filter_autotrack_rectangle.c,
2011-03-08 Dan Dennedy <dan@dennedy.org>
- * src/modules/core/filter_obscure.c: Refactor to mlt_filter_get_progress().
-
* src/framework/mlt_filter.c, src/framework/mlt_transition.c: Use the
producer when filter/transition always active.
src/mlt++/MltFilter.cpp, src/mlt++/MltFilter.h: Add
mlt_filter_get_progress().
- * src/modules/plus/transition_affine.c: Refactor to
- mlt_transition_get_length().
-
2011-03-10 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/consumer_avformat.c: Fix regression on AC-3 fix. The
- recent AC-3 fix broke automatic codec selection based on format. So, we
- choose codec by name only for ac3 now.
-
- * src/modules/swfdec/configure: Fix typo in swfdec configure script.
-
* src/modules/swfdec/Makefile, src/modules/swfdec/configure: Add build
support for swfdec 0.7. And prioritize newer versions over older ones.
- * src/modules/resample/filter_resample.c: Increase resample buffer size. For
- example, trying to resample 6 channels of 48 KHz would fail.
-
- * src/modules/resample/filter_resample.c: Remove unnecessary audio conversion
- to float.
-
- * src/modules/avformat/producer_avformat.c: Fix audio resample with
- audio_index=all. This still only works with channels <= 2. Streams with
- channels > 2 are resampled downstream with the resample filter. However, that
- only works when said stream has the highest sample rate.
-
-2011-03-07 Till Theato <root@ttill.de>
-
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: use new API
- functions to prevent some possible issues.
-
-2011-03-07 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_audioconvert.c: Fix regression in audioconvert.
-
2011-03-06 Dan Dennedy <dan@dennedy.org>
* src/modules/core/transition_composite.c,
src/mlt++/MltTransition.cpp, src/mlt++/MltTransition.h: Add
mlt_transition_get_length().
- * src/modules/frei0r/filter_frei0r.c: Refactor to use mlt_frame_get_length().
-
- * src/modules/normalize/filter_volume.c: Remove unused variable.
-
* src/framework/mlt_filter.c, src/framework/mlt_filter.h,
src/mlt++/MltFilter.cpp, src/mlt++/MltFilter.h: Add mlt_filter_get_length().
- * src/framework/mlt_playlist.c: Refactor to use mlt_producer_get_playtime().
-
* src/modules/core/filter_audioconvert.c, src/modules/core/filter_mono.c,
src/modules/core/producer_consumer.c: Refactor to mlt_audio_format_size().
* src/modules/core/producer_noise.c, src/modules/normalize/filter_volume.c:
Remove unused variables.
- * src/modules/avformat/filter_avcolour_space.c: Define out this unused code.
-
* src/modules/avformat/filter_swscale.c,
src/modules/avformat/producer_avformat.c, src/modules/core/filter_crop.c,
src/modules/core/filter_resize.c, src/modules/core/producer_colour.c,
src/mlt++/MltFrame.cpp, src/mlt++/MltFrame.h: Add mlt_frame_set_image and
mlt_frame_set_alpha.
- * src/framework/mlt_properties.c: Fix spelling error in doxygen.
-
- * src/framework/mlt_consumer.c: Fix thread cleanup on parallel consumer stop.
- This was appearing often as a segfault at the end of melt with the avformat
- consumer.
-
* src/modules/gtk2/producer_pango.c, src/modules/gtk2/producer_pixbuf.c:
Alias bicubic for hyper in pango and pixbuf.
* : Add gpl flag file to rotoscoping filter.
- * src/modules/avformat/consumer_avformat.c: Fix AC-3 encoding
- (kdenlive-2010). FFmpeg now has separate encoders that take float versus
- fixed samples.
-
-2011-03-05 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/gtk2/filter_rescale.c: Make 'bicubic' an alias for highest
- quality in gtk scaler.
-
- * src/modules/qimage/qimage_wrapper.cpp: Fix handling monochrome in qimage.
-
-2011-03-03 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/transition_luma.c: Fix string comparison and requested
- luma size.
-
- * src/modules/core/filter_resize.c: Prevent attempt to pad to a smaller size.
-
- * src/modules/core/transition_luma.c: Fix luma semantics when both reverse
- and invert. Previously, when not using a wipe (dissolve), invert would make
- the transition have no effect. Now, it works and does the same thing as
- reverse. Also, when using a wipe, reverse had no effect when invert was set,
- and the desired effect could not be achieved. Now, it works as expected.
-
- * demo/demo: Set a profile for the demo script.
-
- * demo/consumers.ini: Drop MainConcept and BlueFish444 from the demo
- consumers.
-
- * src/framework/mlt_properties.c: Improve mlt_properties_close() in debugger.
-
2011-03-02 Dan Dennedy <dan@dennedy.org>
- * src/modules/kdenlive/filter_wave.c: Rewrite wave filter to be
- parallel-safe. It does this by using mlt_frame_unique_properties(). Also, it
- fixes a problem not properly processing a source image.
-
- * src/modules/normalize/filter_volume.c: Refactor volume to use
- mlt_frame_unique_properties().
-
* src/framework/mlt_frame.c, src/framework/mlt_frame.h: Add
mlt_frame_unique_properties().
src/modules/avformat/producer_avformat.c, src/modules/avformat/vdpau.c:
Rename 'this' in avformat module.
- * src/modules/frei0r/not_thread_safe.txt: Mark more frei0r filters not
- thread-safe.
-
-2011-03-01 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/kdenlive/producer_framebuffer.c: Fix deadlock regression in
- framebuffer producer.
-
- * src/modules/frei0r/not_thread_safe.txt: Flag some frei0r filters as not
- thread-safe.
-
- * src/modules/sdl/consumer_sdl.c: Fix deadlock in sdl_preview. This would
- occur when trying to play from a paused state at the end of the project.
-
2011-03-01 Till Theato <root@ttill.de>
* src/modules/rotoscoping/filter_rotoscoping.c,
2011-02-28 Dan Dennedy <dan@dennedy.org>
- * src/modules/core/transition_luma.c: Fix integrity of luma transition when
- parallel.
-
- * src/modules/avformat/producer_avformat.c: Workaround incorrect duration on
- some clips (kdenlive-2003).
-
- * src/modules/avformat/producer_avformat.c: Fix regression in determination
- of seekable.
-
* src/framework/mlt_consumer.c, src/framework/mlt_deque.c,
src/framework/mlt_events.c, src/framework/mlt_factory.c,
src/framework/mlt_field.c, src/framework/mlt_filter.c,
self in the framework. This makes doxygen output better match the headers,
and it improves life within a code-parsing IDE like Qt Creator.
- * demo/demo.ini: Fixup demo.ini
-
- * src/framework/mlt_geometry.c: Rename self to g in mlt_geometry.
-
- * src/modules/avformat/producer_avformat.c: Fix compiler error on older
- version of libavutil.
-
2011-02-27 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/consumer_avformat.c: Fix mlt_consumer_position when
- encoding audio only.
-
* src/modules/avformat/consumer_avformat.c,
src/modules/avformat/producer_avformat.c: Add support for FFmpeg AVMetadata
API.
- * src/modules/avformat/producer_avformat.c: Fix compiler warning on
- av_get_pix_fmt().
-
- * src/modules/avformat/producer_avformat.c: Rewrite seekable check in
- avformat. Now, alsa input works: melt -profile dv_pal alsa:default
- video4linux with alsa: melt -profile quarter_15 video4linux2:/dev/video1 \
- -track alsa:default -transition mix And files over HTTP can handle seeking.
-
-2011-02-27 Till Theato <root@ttill.de>
-
- * src/modules/rotoscoping/filter_rotoscoping.c: rotoscoping: Add parameters
- feather and feather_passes. Feathering is done by bluring the map containing
- the masked area.
-
-2011-02-26 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/frei0r/blacklist.txt: Remove frei0r.facedetect from black list.
-
- * src/modules/frei0r/not_thread_safe.txt: Mark frei0r.cluster as not
- thread-safe.
-
- * src/modules/frei0r/factory.c: Fix small memory leak each a frei0r plugin is
- instantiated.
-
-2011-02-25 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Add support for pix_fmt on
- avformat resource URL. For example,
- libdc1394:/dev/raw1394?frame_rate:15\&pix_fmt:yuv422 makes a Firewire digital
- camera (not DV camcorder) on Linux work.
-
- * src/modules/avformat/producer_avformat.c: Add support for avdevice video
- channel selection. For example, video4linux2:/dev/video0?channel=2 sets the
- input to S-
-
- * setenv: fix setenv
-
-2011-02-24 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_transition.c: Support forever transitions (in and out not
- supplied).
-
- * src/modules/core/filter_rescale.c: Add 'factor' property to scale filters.
- Under certain conditions it can be desirable to manually change the
- resolution. Caution: one can still not use this in a completely generic way
- with this change. For example, in a realtime playout situation, one can
- attach swscale with factor=0.25, followed by frei0r.cluster, followed by
- swscale again with no properties. The first swscale will downscale the image
- for the heavy cluster filter. The last swscale will upscale it to make the
- rest of the project components happy.
-
2011-02-20 Dan Dennedy <dan@dennedy.org>
* src/modules/frei0r/Makefile, src/modules/frei0r/factory.c,
src/modules/frei0r/frei0r_helper.c, src/modules/frei0r/not_thread_safe.txt:
- Mark some frei0r plugins as not thread safe.
-
-2011-02-20 Till Theato <root@ttill.de>
-
- * src/modules/rotoscoping/filter_rotoscoping.c: rotoscoping: number of points
- can now change from keyframe to keyframe. Result may be unexpected though.
- Additionally some cleanup
-
- * src/modules/rotoscoping/filter_rotoscoping.c: rotoscoping: rename mode
- "matte" to "luma" Additionally prevent serialization of internal parameters
-
-2011-02-19 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix video4linux in avformat
- producer. melt video4linux2:/dev/video0
-
- * docs/install.txt, docs/mlt-xml.txt, docs/services.txt, setenv: Remove info
- about mainconcept and bluefish services.
-
- * src/framework/mlt_producer.c, src/framework/mlt_producer.h,
- src/modules/core/producer_consumer.c, src/modules/core/producer_hold.c,
- src/modules/core/producer_noise.c, src/modules/frei0r/factory.c,
- src/modules/motion_est/producer_slowmotion.c: Add profile parameter to
- mlt_producer_new.
-
- * src/framework/mlt_service.c: Check pointer passed to mlt_service_profile.
-
- * src/modules/core/producer_colour.c: Fix aspect ratio of color producer.
-
- * configure: Add --enable-debug option.
-
-2011-02-19 j-b-m <jb@kdenlive.org>
-
- * src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/qimage_wrapper.cpp:
- Store exif orientation. Patch attached internally stores the exif
- orientation so that it can be accessible to the framework and apps using it.
- Useful it in Kdenlive to correctly rotate images when creating proxy images.
-
-2011-02-19 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/motion_est/Makefile: Fix lib suffix on motion_est.
-
-2011-02-16 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl_audio.c: Disable purging consumer on seek in
- sdl_audio. Due to misbehaving on parallel-consumer.
-
-2011-02-16 Till Theato <root@ttill.de>
-
- * src/modules/rotoscoping/filter_rotoscoping.c: rotoscoping: Use
- "property-changed" event to find out when to parse the spline
-
-2011-02-13 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl.c: Playout remaining frames in sdl at
- end-of-stream.
-
- * src/framework/mlt_consumer.c, src/framework/mlt_consumer.h,
- src/modules/sdl/consumer_sdl_preview.c: Fix deadlocks in sdl_preview with
- parallel-consumer.
-
-2011-02-08 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/transition_composite.c: Fix image skew bug in composite
- (kdenlive-1923).
-
- * src/modules/core/transition_luma.c: Fix deinterlace when luma is inverted
- (kdenlive-1953).
-
-2011-02-07 j-b-m <jb@kdenlive.org>
-
- * src/modules/plus/transition_affine.c: Make offset in affine transition
- keyframable.
-
-2011-02-05 Till Theato <root@ttill.de>
-
- * src/modules/rotoscoping/filter_rotoscoping.c: rotoscoping: fix mode alpha
- not working with image format rgb24a
-
-2011-02-03 Till Theato <root@ttill.de>
-
- * src/modules/rotoscoping/filter_rotoscoping.c: rotoscoping: prevent possible
- crash
-
-2011-01-31 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/producer_consumer.c: Copy the alpha channel in
- producer_consumer.
-
-2011-01-30 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Improve efficiency of memory copy
- in avformat consumer. Patch from Paul Flinders <paul@flinders.org>.
-
- * src/modules/avformat/producer_avformat.c: Be pessimistic about the duration
- (kdenlive-1962). Some clip formats give a slightly longer duration estimate,
- and MLT does not handle that well especially in some non-interactive use
- cases like transcoding and automated processing.
-
-2011-01-27 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/gtk2/Makefile: Link pango producer with libiconv on Mac OS X.
-
-2011-01-27 Till Theato <root@ttill.de>
-
- * src/modules/rotoscoping/Makefile, src/modules/rotoscoping/factory.c,
- src/modules/rotoscoping/filter_rotoscoping.c,
- src/modules/rotoscoping/filter_rotoscoping.yml: Rotoscoping: Set default mode
- to alpha and add YAML filter description
-
-2011-01-26 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Do not round up the duration
- (kdenlive-1962).
-
- * src/modules/avformat/producer_avformat.c: Fix pausing on vdpau with
- noimagecache. Also uses AVFrame we already have instead of local AVPicture.
-
- * src/modules/avformat/producer_avformat.c: Make seeking to first frame more
- reliable.
-
-2011-01-25 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl.c: Increase default SDL audio buffer to
- prevent crackling.
-
- * src/framework/mlt_consumer.c: Make worker thread handle tracking more
- portable.
+ Mark some frei0r plugins as not thread safe.
-2011-01-25 Till Theato <root@ttill.de>
+2011-02-19 Dan Dennedy <dan@dennedy.org>
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: another small
- cleanup
+ * docs/install.txt, docs/mlt-xml.txt, docs/services.txt, setenv: Remove info
+ about mainconcept and bluefish services.
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: cleanup
+ * src/framework/mlt_producer.c, src/framework/mlt_producer.h,
+ src/modules/core/producer_consumer.c, src/modules/core/producer_hold.c,
+ src/modules/core/producer_noise.c, src/modules/frei0r/factory.c,
+ src/modules/motion_est/producer_slowmotion.c: Add profile parameter to
+ mlt_producer_new.
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: Mode matte
- should also work in yuv420p (untested since forcing a conversion from yuv422
- does not work)
+2011-02-19 j-b-m <jb@kdenlive.org>
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: only the mode
- rgb requires a specific colorspace
+ * src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/qimage_wrapper.cpp:
+ Store exif orientation. Patch attached internally stores the exif
+ orientation so that it can be accessible to the framework and apps using it.
+ Useful it in Kdenlive to correctly rotate images when creating proxy images.
-2011-01-24 Till Theato <root@ttill.de>
+2011-02-13 Dan Dennedy <dan@dennedy.org>
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: Save the the
- json object so we do not have to parse the parameter at every processing but
- only when it changed
+ * src/framework/mlt_consumer.c, src/framework/mlt_consumer.h,
+ src/modules/sdl/consumer_sdl_preview.c: Fix deadlocks in sdl_preview with
+ parallel-consumer.
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: use mlt_pool
+2011-01-27 Till Theato <root@ttill.de>
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: rename "mask"
- mode to "matte"
+ * src/modules/rotoscoping/Makefile, src/modules/rotoscoping/factory.c,
+ src/modules/rotoscoping/filter_rotoscoping.c,
+ src/modules/rotoscoping/filter_rotoscoping.yml: Rotoscoping: Set default mode
+ to alpha and add YAML filter description
2010-11-23 Dan Dennedy <dan@dennedy.org>
- * src/modules/plus/filter_affine.c: Reduce service lock contention in affine
- filter.
-
* src/modules/frei0r/filter_frei0r.c, src/modules/frei0r/frei0r_helper.c,
src/modules/frei0r/frei0r_helper.h, src/modules/frei0r/producer_frei0r.c,
src/modules/frei0r/transition_frei0r.c: Reduce service lock contention in
frei0r module.
-2010-11-04 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_consumer.c: Fix race condition on frame pointer in
- parallel consumer.
-
-2010-10-17 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_consumer.c: Fix multiple workers getting the same frame.
-
2010-10-04 Dan Dennedy <dan@dennedy.org>
* src/framework/mlt_consumer.c, src/framework/mlt_consumer.h,
then it may be better to not use realtime mode and permit audio
discontinuity.
- * src/framework/mlt_types.h: Add a MLT_FRAME() cast. And white-space align
- the casts.
-
* src/framework/mlt_deque.c, src/framework/mlt_deque.h: Add mlt_deque_peek()
with index.
-2010-06-15 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_consumer.c: Remove audio processing from the worker
- threads. This has a bad interaction with the avformat producer, which
- contains a buffer of unused decoded samples. This shifts audio processing to
- the main consumer thread, which is often light anyways. I recommend to set
- the threads property to 2 or more on the avformat consumer to offload video
- encoding to separate threads from the audio processing and encoding.
-
- * src/modules/xine/filter_deinterlace.c: Make YADIF reentrant.
-
- * src/framework/mlt_consumer.c: Fix regression frames out-of-order.
-
- * src/framework/mlt_consumer.c: Fix compiler warning on this enum.
-
2010-06-14 Dan Dennedy <dan@dennedy.org>
- * src/framework/mlt_consumer.c: Change this log message back to debug level.
-
* src/framework/mlt_consumer.c, src/framework/mlt_frame.c,
src/framework/mlt_tractor.c, src/modules/core/filter_imageconvert.c,
src/modules/sdl/consumer_sdl.c: Fix image format consistency and conversion.
tractor service locking. This completely inhibited parallelism, but removing
it also exposes more race conditions that require resolution.
- * src/framework/mlt_consumer.c: Add work queue to the parallel consumer.
- This removes get_frame calls from the worker threads. The get_frame call must
- take a service lock and that creates contention between the threads.
-
- * src/modules/xine/filter_deinterlace.c: Add service locks around yadif
- context.
-
-2010-04-15 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_consumer.c: Change this log message to debug level.
-
2010-03-04 Dan Dennedy <dan@dennedy.org>
* .../motion_est/filter_autotrack_rectangle.c,
src/modules/qimage/producer_qimage.c, src/modules/sox/filter_sox.c,
src/modules/vorbis/producer_vorbis.c: Add service locks for parallelism.
- * src/modules/sdl/consumer_sdl_preview.c: Pass real_time, buffer, and prefill
- properties onto normal sdl consumer.
-
- * src/modules/sdl/consumer_sdl.c: Log dropped frames at info log level.
-
* src/modules/avformat/filter_avresample.c,
src/modules/avformat/filter_swscale.c,
src/modules/avformat/producer_avformat.c,
RGB filters and transitions from frei0r and burningtv are still not safe
enough.
- * src/framework/mlt_tractor.c: Set the proper size of "image" where known.
-
* src/framework/mlt_consumer.c, src/framework/mlt_consumer.h: Add parallelism
to mlt_consumer. To use set real_time greater than 1 for frame-dropping or
less than -1 for no frame-dropping. It works better with a liberal buffer
2011-01-23 Dan Dennedy <dan@dennedy.org>
- * src/modules/qimage/producer_qimage.c: Fix build outside MinGW.
-
- * src/modules/jackrack/configure: Fix getting LADSPA include dir from
- listplugins.
-
* configure, src/framework/mlt_version.h: Move to an interim version number.
2011-01-17 Dan Dennedy <dan@dennedy.org>
- * src/examples/Makefile: Make this example use the mlt++ pkg-config. This
- more accurately demonstrates how to build a C++ app against mlt++.
-
* src/modules/sdl/consumer_sdl.c, src/modules/sdl/consumer_sdl_still.c: SDL
tweaks for Windows discovered when embedded.
2010-12-31 Dan Dennedy <dan@dennedy.org>
- * src/modules/swfdec/Makefile: Fix swfdec build on MinGW.
-
* src/modules/xml/consumer_xml.c, src/modules/xml/producer_xml.c: Cleanup
libxml changes for MinGW.
2010-12-30 Dan Dennedy <dan@dennedy.org>
- * src/modules/sox/configure: Fix sox build on MinGW.
-
- * src/modules/frei0r/factory.c: Fix frei0r build on MinGW.
-
* src/modules/xml/consumer_xml.c, src/modules/xml/producer_xml.c: Fix libxml2
build on MinGW.
* src/melt/Makefile, src/melt/io.c, src/melt/melt.c,
src/modules/sdl/consumer_sdl.c: Fix SDL and keyboard input on Win32.
-2010-12-05 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/Makefile: Fix build of mingw branch on Linux. Fixing this
- here prior to merging into master.
-
2010-12-03 Dan Dennedy <dan@dennedy.org>
* configure, src/framework/Makefile, src/melt/Makefile, src/melt/io.c,
2011-01-23 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog for v0.6.2.
-
* Doxyfile, configure, docs/melt.1, src/framework/mlt_version.h: Set version
to 0.6.2.
- * NEWS: Add v0.6.2 release notes.
-
-2011-01-22 Till Theato <root@ttill.de>
-
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: add parameter
- alpha_operation with possible values: clear, max, min, add, sub
-
- * src/modules/rotoscoping/filter_rotoscoping.c: Fix not every point
- calculated for the spline was used
-
-2011-01-21 Till Theato <root@ttill.de>
-
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: - Rename
- parameter polygon to spline - Add parameter precision setting the maximum
- distance between two points when calculating the spline - some cleanup
-
-2011-01-20 Till Theato <root@ttill.de>
-
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: Use cubic Bezier
- spline instead of simple polygon to define masks
-
-2011-01-16 j-b-m <jb@kdenlive.org>
-
- * src/modules/plus/transition_affine.c: Add always_active property to affine
- transition.
-
2011-01-16 Till Theato <root@ttill.de>
- * src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: Add parameter
- invert
-
* src/modules/rotoscoping/Makefile, src/modules/rotoscoping/cJSON.c,
src/modules/rotoscoping/cJSON.h,
src/modules/rotoscoping/filter_rotoscoping.c: Rotoscoping: Add support for
2011-01-15 Till Theato <root@ttill.de>
- * src/modules/rotoscoping/filter_rotoscoping.c: rotoscoping filter: add modes
- - rgb (everything but polygon black, default) - alpha (polygon alpha value =
- 255, the rest = 0) - mask (polygon white, the rest black)
-
* src/modules/rotoscoping/Makefile, src/modules/rotoscoping/factory.c,
src/modules/rotoscoping/filter_rotoscoping.c: Add rotoscoping filter (WIP):
It hides everything not in the polygon defined by the vertices given through
2011-01-11 Dan Dennedy <dan@dennedy.org>
- * src/modules/plus/transition_affine.c: fix compiler warning
-
* configure, src/mlt++/configure, src/modules/avformat/configure,
src/modules/kino/endian_types.h, src/modules/kino/riff.cc,
src/modules/qimage/configure, src/modules/sox/configure: Enable build on
* src/modules/kino/Makefile, src/modules/qimage/Makefile: Use CXX rather than
CC for linking C++ (3090682)
- * src/swig/python/build: Fix underlinking python binding (3082761). Link the
- python binding library to MLT and Python needed on some systems like
- OpenSUSE. Patch by Cristian Morales Vega
-
* src/modules/sdl/consumer_sdl_audio.c,
src/modules/sdl/consumer_sdl_preview.c: Fix undefined bahavior in SDL module
(3066195). The standard says the post-increment can have effect at any point
the behavior of "this->refresh_count = this->refresh_count ++" is undefined.
Patch by Cristian Morales Vega
- * src/modules/plus/filter_affine.c: Add use_normalised to affine filter.
-
- * src/modules/plus/transition_affine.c: Fix some regressions in affine.
- Crashing on null rescale.interp and still some incorrect handling of sample
- aspect ratios.
-
2011-01-10 Dan Dennedy <dan@dennedy.org>
* src/modules/plus/interp.h, src/modules/plus/transition_affine.c: Add
2011-01-10 Dan Dennedy <dan@dennedy.org>
- * src/modules/linsys/20-linsys.rules: Remove NAME= from linsys udev rules.
-
* configure, src/framework/mlt_version.h: Move to an interim version.
2011-01-01 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: update ChangeLog for v0.6.0
-
- * NEWS: Add v0.6.0 release notes.
-
* Doxyfile, configure, docs/melt.1, src/framework/mlt_version.h: set version
to 0.6.0
- * src/modules/avformat/configure: Set recommended FFmpeg version to 0.6.1.
-
- * src/melt/melt.c: Update year in copyright notice.
-
- * src/modules/core/transition_composite.c: Default to progressive rendering
- in composite. Field-based rendering is not sensitive to whether the
- composite has motion and therefore produces ugly results for static things by
- default. Field-based rendering can be explicitly requested on an animated
- composite by setting the progressive property to 0.
-
- * src/modules/feeds/NTSC/etv.properties: Scale the animation durations in
- NTSC etv data feed.
-
* src/modules/feeds/NTSC/etv.properties,
src/modules/feeds/PAL/etv.properties: Make etv data feeds same and scalable
between NTSC and PAL.
- * src/melt/melt.c: Treat profile set by environment variable as explicit.
-
* demo/mlt_attributes, src/modules/feeds/NTSC/data_fx.properties,
src/modules/feeds/NTSC/etv.properties: Make feeds consistent between NTSC and
PAL. Fix mlt_attributes demo.
- * src/melt/melt.c: Fix melt crashing due to many things depending on
- consumer_aspect_ratio.
-
- * src/modules/core/consumer_null.c: Fix segfault stopping unstarted null
- consumer.
-
- * src/modules/avformat/consumer_avformat.c: Increase video encoder output
- buffer size.
-
* demo/README, demo/mlt_slideshow, demo/mlt_slideshow_black: Convert
"Scotland" in demos to "photos"
* demo/svg.mlt, src/modules/xml/producer_xml.c: Fix parsing mixed XML
documents and svg.mlt example.
-2010-12-29 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix an infinite loop encoding a
- video with vorbis audio (kdenlive-1871).
-
2010-12-27 Dan Dennedy <dan@dennedy.org>
* src/mlt++/MltProducer.cpp, src/mlt++/MltProducer.h: Revert
Producer::set_speed and add Producer::pause. The new Producer::pause
contains the wait for consumer-sdl-paused.
-2010-12-23 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/swfdec/producer_swfdec.c: Prevent concurrent access to swfdec
- context.
-
- * src/modules/swfdec/producer_swfdec.c: Add meta.media properties to swfdec.
-
2010-12-22 Dan Dennedy <dan@dennedy.org>
- * src/modules/plus/transition_affine.c: Fix shearing bug in affine transition
- & filter.
-
* src/framework/mlt_frame.c, src/framework/mlt_frame.h: Add
mlt_frame_write_ppm to visualize debugging.
-2010-12-21 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/decklink/Makefile: Fix build of decklink on some non-Linux
- systems (BSD).
-
2010-12-19 Dan Dennedy <dan@dennedy.org>
* src/modules/sdl/consumer_sdl.c, src/modules/sdl/consumer_sdl_preview.c:
2010-12-16 Dan Dennedy <dan@dennedy.org>
- * src/modules/decklink/consumer_decklink.cpp: Fix cleaning up decklink when
- stopped.
-
- * src/mlt++/MltProducer.cpp: Fix regression in Producer::set_speed when
- consumer stopped. This was causing a deadlock in Kdenlive and any app that
- calls set_speed when the consumer is stopped.
-
- * src/modules/sdl/consumer_sdl_still.c: Fix race-induced intermittent crash
- in sdl_still (kdenlive-1762).
-
* src/framework/Makefile, src/framework/mlt.h, src/framework/mlt_version.c,
src/framework/mlt_version.h, src/swig/mlt.i: Add mlt_version API.
Contributed by Jonathan Thomas.
2010-12-15 Dan Dennedy <dan@dennedy.org>
- * src/mlt++/MltProducer.cpp: Fix regression on return value of
- Producer::set_speed.
-
* src/mlt++/MltProducer.cpp, src/modules/sdl/consumer_sdl_preview.c:
Synchronize Producer.set_speed(0) with sdl_preview. This also helps prevent
deadlock while waiting for consumer-sdl-paused event. Not 100% yet, but 100%
variable to use within the handler - once it has support for event listeners
that is.
- * src/modules/sdl/consumer_sdl_preview.c: Prevent a possible deadlock when
- pausing.
-
-2010-12-12 j-b-m <jb@kdenlive.org>
-
- * src/modules/kdenlive/filter_freeze.c: Prevent always fetching the "frozen"
- frame. Instead of using cache, which causes flicker in previews.
-
-2010-12-12 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl_preview.c: Fix crash when connecting the
- sdl_preview to a new producer. This occurs when you do not first stop the
- consumer.
-
-2010-12-11 Dan Dennedy <dan@dennedy.org>
-
- * src/melt/melt.c: Make melt handle failure to start consumer.
-
- * src/modules/decklink/consumer_decklink.cpp: Fix tearing in decklink. Also:
- Adds a "preroll" property, which takes number of video frames. Prevent it
- from deadlocking on a few dropped video frames in succession. Signal failure
- to start when the profile is not compatible.
-
2010-12-09 Dan Dennedy <dan@dennedy.org>
* src/mlt++/MltProperties.cpp, src/mlt++/MltProperties.h: Added
Mlt::Properties::wait_for(string).
- * src/swig/mlt.i: Fix memory leak in swig on Properties::setup_wait_for.
-
- * src/modules/linsys/consumer_SDIstream.c: Remove exit() from Linsys sdi
- consumer. Replace it with a consumer-fatal-error event.
-
* src/framework/mlt_log.c, src/melt/melt.c,
src/modules/avformat/consumer_avformat.c: Add consumer-fatal-error event to
avformat consumer. This addresses Kdenlive bug 1894. When the avformat
src/framework/mlt_types.h, src/melt/melt.c, src/mlt++/MltConsumer.cpp,
src/mlt++/MltConsumer.h: Add mlt_consumer_position (Mlt::Consumer::position).
- * src/modules/sdl/consumer_sdl_preview.c: A minor refactoring.
-
- * src/modules/sdl/consumer_sdl_preview.c: Add a consumer-sdl-paused event.
-
- * src/modules/sdl/consumer_sdl_preview.c: Refactor end-of-stream and speed
- change.
-
2010-11-30 Dan Dennedy <dan@dennedy.org>
- * src/modules/core/loader.dict: Load .xml file as MLT XML.
-
* demo/mlt_swf_variables, demo/txtField.swf: Add example of using SWF with
variables.
- * src/modules/lumas/configure: Make --luma-compress imply --luma-8bit.
- Otherwise, we get unloadable 16-bit PNG.
-
-2010-11-29 Dan Dennedy <dan@dennedy.org>
-
- * src/swig/python/codecs.py: Add example of how to list of codecs.
-
- * src/modules/avformat/consumer_avformat.c: Make the formats and codecs
- available through properties.
-
- * src/modules/avformat/producer_avformat.c: Fix reading uncompressed video
- (bug 3121436).
-
- * src/modules/avformat/vdpau.c: Make VDPAU decoding a tad more resilient.
-
-2010-11-26 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/swfdec/producer_swfdec.c: Add support for swfdec variables.
- The new 'variables' property takes a URL-encoded string, e.g.
- variables="title=Hello World&subtitle=swfdec variables".
-
-2010-11-23 Dan Dennedy <dan@dennedy.org>
-
- * src/melt/melt.c: Fix AVCHD detected as double frame rate. The heuristic is
- based upon fact that there is really no such thing as 50 or 59.94 _frames_
- per second interlaced.
-
-2010-11-20 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/linsys/20-linsys.rules: Add suggested udev rules for Linsys
- cards.
-
-2010-11-19 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/plus/transition_affine.c: Fix affine on non-square pixels
- (kdenlive-1880).
-
-2010-11-17 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/swfdec/producer_swfdec.c: Refactor image conversion in swfdec.
-
- * src/modules/frei0r/frei0r_helper.c: Add support for
- F0R_COLOR_MODEL_BGRA8888
-
-2010-11-17 Till Theato <root@ttill.de>
-
- * src/modules/gtk2/producer_pango.c: Fix crash in pango on very long strings.
- Fix frame width and height get -1 when using producer pango with long
- strings (large text files).
-
-2010-11-14 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl.c: Fix the size argument handling.
-
-2010-11-09 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Add locks around
- avcodec_open/_close for thread protection.
-
- * src/modules/avformat/producer_avformat.c: Fix regression on 1920x1088
- clips.
-
2010-11-07 Dan Dennedy <dan@dennedy.org>
- * src/modules/swfdec/configure: Add configure script to detect optional
- swfdec dependency.
-
- * src/modules/swfdec/Makefile: Support build on swfdec 0.8 as well.
-
* src/modules/core/loader.dict, src/modules/swfdec/Makefile,
src/modules/swfdec/producer_swfdec.c: Add swfdec producer. No audio or
variables/parameters yet.
src/modules/decklink/consumer_decklink.cpp: Add Blackmagic Design DeckLink
consumer.
-2010-10-27 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/plus/transition_affine.c: Another apsect ratio fix in affine.
-
- * src/modules/plus/transition_affine.c: Fix aspect- and size-related issues
- in affine.
-
-2010-10-21 Dan Dennedy <dan@dennedy.org>
-
- * src/melt/melt.c: Fix edit points when using auto-profile.
-
- * src/modules/avformat/producer_avformat.c: Fix frame rate detection when the
- muxer rate is 0/0.
-
2010-10-20 Dan Dennedy <dan@dennedy.org>
* src/framework/mlt_tokeniser.c, src/modules/frei0r/frei0r_helper.c: Add
support for frei0r string parameter.
- * src/modules/avformat/filter_avcolour_space.c: Disable colorspace
- normalization - not working yet.
-
-2010-10-18 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_property.c: Fkx crash converting string property with
- null value.
-
2010-10-17 j-b-m <jb@kdenlive.org>
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
2010-10-13 Dan Dennedy <dan@dennedy.org>
- * src/modules/xml/consumer_xml.c: Do not serialize profile when consumer
- profile is null.
-
- * src/modules/avformat/producer_avformat.c: Fix regression using codec frame
- rate.
-
- * src/modules/xml/consumer_xml.c: Add null pointer checks around profile in
- consumer xml.
-
* src/melt/melt.c, src/modules/avformat/producer_avformat.c: Add colorspace
to auto-profile.
src/modules/avformat/producer_avformat.c: Fix version support for
AVCodec:colorspace.
- * src/modules/avformat/configure: Add --avformat-no-vdpau configure option.
-
- * src/modules/core/filter_data_show.c: Add math header for lrint().
-
- * src/modules/core/filter_data_show.c: Add #frame# variable substitution in
- data_show filter.
-
- * src/modules/core/filter_data_show.c: Fix timecode conversion with
- non-integral framerate.
-
-2010-10-10 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/producer_consumer.c: Fix consumer producer not updating
- frames in Kdenlive.
-
-2010-10-09 Dan Dennedy <dan@dennedy.org>
-
- * src/melt/melt.c: Handle consumer properties that alter the profile.
-
- * src/modules/core/producer_loader.c: Check for colorspace change on profile.
-
2010-10-07 Dan Dennedy <dan@dennedy.org>
* src/melt/melt.c, src/modules/core/producer_consumer.c,
* src/framework/mlt_profile.c, src/framework/mlt_profile.h: Add
mlt_profile_clone().
-2010-09-26 Dan Dennedy <dan@dennedy.org>
-
- * src/melt/melt.c: Use denominators as the litmus test for generating
- profile. This allows converting all producers to meta.media.width and
- meta.media.height while not attempting to auto-profile the image producers,
- which can potentially hold extremely large images and do not contain any
- inherent frame rate. This also protects from potential divide by zero errors.
-
- * src/melt/melt.c: Factor out usage help from main() processing.
-
- * src/melt/melt.c: Factor out processing -consumer option.
-
-2010-09-19 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix some framerate-related issues
- on playback. Usage of stream->avg_frame_rate and seting aspect_ratio on
- fallback.
-
- * src/melt/melt.c: Fix crash on invalid and audio only clips.
-
- * src/modules/avformat/producer_avformat.c: Improve some media attributes
- detection. These are for the new meta.media properties: square pixel
- fallback, use new avg_frame_rate, converting 1088 to 1080.
-
2010-08-28 Dan Dennedy <dan@dennedy.org>
* src/melt/melt.c, src/modules/melt/producer_melt.c: Add an automatic profile
explicitly choosing a profile different than the composition one should use
the consumer producer. This just makes melt smarter and more automatic.
- * src/modules/avformat/producer_avformat.c: Add immutable meta.media-prefixed
- properties. I am deprecating real_width, real_height, and source_fps in
- favor of new properties prefixed by "meta.media." These are different than
- the "meta.media.N.stream" and "meta.media.N.codec" properties because they
- represent the selected tracks as well as some interpretation of the raw
- AVFormat and AVCodec attributes in addition to reflecting "force_" overrides.
- There is still many changes to make throughout to full remove real_width and
- real_height. This change just adds what melt's new auto-profile feature needs
- for most use cases.
-
- * src/modules/core/producer_consumer.c: Do not let consumer producer alter
- the profile when validating input.
-
* src/modules/xml/consumer_xml.c, src/modules/xml/mlt-xml.dtd,
src/modules/xml/producer_xml.c: Add (de)serialization of profile to XML. In
addition to the 'profile' element, one can also set the 'profile' attribute
building without swscale. Fix compiling new colorspace stuff against FFmpeg
<= v0.5. FFmpeg libs are increasing; only support contemporary header layout.
-2010-10-04 j-b-m <jb@kdenlive.org>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Fix
- TextColor+Outline+Typewriter=wrong color in titler (kdenlive-1829).
-
2010-09-28 Dan Dennedy <dan@dennedy.org>
* src/modules/sdl/consumer_sdl.c, src/modules/sdl/consumer_sdl_audio.c,
Fix race conditions in SDL (kdenlive-1711). Contributed patch by 'jem' -
thanks!
-2010-09-28 j-b-m <jb@kdenlive.org>
-
- * src/modules/sdl/consumer_sdl_still.c: Fix crash in SDL with new kdenlive
- audio VU meter. Below, a patch that fixes a crash in the SDL still consumer,
- the bug was triggered by the recent audio monitor feature of Kdenlive.
- Basically, it just sets test_audio to 1 on the SDL still consumer frames.
-
2010-09-26 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/filter_avcolour_space.c,
profile) on frames. Also, allow affirmatively setting luma to _not_ full
range (force_full_luma=0).
- * src/modules/kdenlive/producer_framebuffer.c: Fix indentation in
- producer_framebuffer.c.
-
- * src/framework/mlt.h: Add mlt_cache.h to set of all mlt headers.
-
- * src/framework/mlt_frame.h: Document new colorspace and force_full_luma
- frame properties.
-
- * src/framework/mlt_tractor.c: Tractor needs to pass along new frame
- properties.
-
- * src/modules/dv/producer_libdv.c: Set libdv producer to Rec 601 colorspace.
-
* profiles/atsc_1080i_50, profiles/atsc_1080i_5994, profiles/atsc_1080i_60,
profiles/atsc_1080p_2398, profiles/atsc_1080p_24, profiles/atsc_1080p_25,
profiles/atsc_1080p_2997, profiles/atsc_1080p_30, profiles/atsc_720p_2398,
profiles/svcd_ntsc_wide, profiles/svcd_pal, profiles/svcd_pal_wide,
profiles/vcd_ntsc, profiles/vcd_pal: Add colorspace to all profile presets.
- * src/framework/mlt_profile.c: Parse colorspace profile property and add
- hardcoded default.
-
* src/modules/avformat/filter_avcolour_space.c,
src/modules/avformat/producer_avformat.c: Rename variables and properties
around luma range for clarity. Frame property "force_full_luma" controls
2010-09-13 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/filter_avcolour_space.c: Add conversion to profile
- colorspace.
-
- * src/modules/avformat/producer_avformat.c: Expand colorspace support to
- explicit 601.
-
- * src/modules/avformat/consumer_avformat.c: Set colorspace in codec context.
-
- * src/framework/mlt_consumer.c: Map profile colorspace to consumer property.
-
- * src/modules/avformat/producer_avformat.c: Remove hardcoded luma scaling and
- passing skip_luma_scale to frame. Luma scaling does not work and passing
- skip_luma_scale can be done by setting set.skip_luma_scale on the producer.
-
* src/modules/avformat/filter_avcolour_space.c,
src/modules/avformat/producer_avformat.c: Rename yuv_std to colorspace.
2010-08-24 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/producer_avformat.c: Require skip_luma_scale
- explicitly <> 0.
-
* src/framework/mlt_profile.h, src/modules/avformat/filter_avcolour_space.c,
src/modules/avformat/producer_avformat.c: Add input YUV colorspace (601 vs
709) handling. Still need to work on the output side including normalization
non-scaling luma between YCbCr and RGB conversions as well as support for ITU
Rec. 709 luma conversion for HD formats.
-2010-09-21 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_crop.c: Test the function pointer to be safe.
-
- * src/modules/core/filter_crop.c: Remove an extra debug log message.
-
- * src/modules/core/filter_crop.c: Fix crop making image black in a multitrack
- (kdenlive-1814).
-
-2010-09-20 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_resize.c: Fix field order correction on cached
- image. When the avformat producer is using image caching, the field order is
- top-field-first, and the consumer is paused then the field order correction
- was applied to the cached image. As a result, when repeating the image due to
- being paused, the active image would scroll down the frame. This fixes it by
- copying to a new image instead of reusing the cached image.
-
-2010-09-19 Dan Dennedy <dan@dennedy.org>
-
- * configure: Bump to interim version.
-
-2010-09-19 j-b-m <jb@kdenlive.org>
-
- * src/modules/avformat/producer_avformat.c: Improve fps detection in avformat
- producer. I noticed MLT sometimes gives wrong fps info (I can send some demo
- clips if required), for example it gives a 1000.0 fps on some mp4 clips. In
- december 2009, FFMpeg introduced avg_frame_rate that gives better results
- than r_frame_rate which is currently used in producer_avformat. Patch below
- makes use of this new field when available which gives better results (my
- mpeg4 clip now shows a 22.691 fps instead of 1000.
-
2010-09-13 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog for v0.5.10.
-
* Doxyfile, configure, docs/melt.1, src/framework/mlt.h: Set version to
0.5.10.
- * src/melt/melt.c: Update year in copyright notice.
-
- * NEWS: Update release notes for v0.5.10
-
- * src/modules/core/filter_crop.c: Fix bug with crop always asking for RGB
- even when not cropping!
-
- * src/modules/xine/yadif.c: Only build SSE2 version of YADIF on x86-64
- (2984003).
-
2010-09-12 Dan Dennedy <dan@dennedy.org>
* configure, src/modules/core/producer_loader.c: Enable filter avcolor_space
on OS X. It works now!
- * src/modules/xine/deinterlace.c: Use linearblend as the C fallback to xine
- deinterlacers.
-
- * ChangeLog: Update ChangeLog for v0.5.8.
-
* Doxyfile, NEWS, configure, docs/melt.1, src/framework/mlt.h: Set version to
0.5.8.
- * NEWS: Add v0.5.8 release notes.
-
* src/modules/avformat/filter_avcolour_space.c,
src/modules/core/filter_imageconvert.c: Enhance image conversion logging.
- * src/modules/qimage/Makefile: Use linearblend as the C fallback to xine
- deinterlacers.
-
- * src/modules/avformat/producer_avformat.c: Validate that swscale supports
- the resolution in avformat producer.
-
- * src/modules/core/filter_crop.c: Fix bugs with odd width YUV processing. By
- preferring to crop on RGB and output an even width in case it eventually
- needs to be converted to YUV, which is usually the case.
-
-2010-09-11 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_crop.c: Fix sometimes tight crop causes a green
- line at bottom.
-
- * src/modules/core/filter_imageconvert.c: Fix a stride and chroma-alignment
- bug in imageconvert rgb->yuv. Reported by Marco Gittler.
-
2010-09-10 Dan Dennedy <dan@dennedy.org>
* src/modules/core/filter_crop.c, src/modules/core/filter_resize.c: Validate
mlt_frame_get_alpha() that returns a size and mlt_frame_set_alpha()
encapsulates handling of the alpha channel.
- * src/modules/core/filter_imageconvert.c: Set the alpha channel size more
- reliably in imageconvert.
-
- * src/framework/mlt_frame.c: Base alpha channel on width and height. Removes
- scaled_width and scaled_height properties, which were typically redundant
- with width and height, but less available. Besides, width and height better
- reflect the image attributes to help keep the image and alpha channel in
- sync.
-
- * src/modules/xine/filter_deinterlace.c: Fix a segfault if one tries to use
- deinterlace explicitly.
-
-2010-09-09 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix returning last bit of audio
- samples from avformat. Bug reported by Kevin MacPhail.
-
-2010-09-09 Marco Gittler <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: parent the svgrenderer, to
- destruct on exit
-
-2010-09-08 Marco Gittler <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: load inline images
-
-2010-09-08 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/filter_swscale.c: Refix alpha channel scaling memory
- leak (3060324).
-
2010-09-07 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/consumer_avformat.c,
src/modules/core/filter_imageconvert.c: Apply alpha on frame to rgba image
(kdenlive-1786).
- * src/modules/xine/filter_deinterlace.c: Fix a regression in the yadif
- deinterlace filter. Now that it properly checks if the previous frame
- progressive after getting its image, when progressive, it was returning the
- previous frame's image for the current frame!
-
-2010-09-04 Till Theato <root@ttill.de>
-
- * src/modules/plus/filter_affine.c: Fix filter affine stopping to work at
- frame 15000. Additionally fix problems with in point > 0 (Kdenlive-1782).
-
-2010-09-03 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix field order on avformat
- cached images. Also, provide a field order override that is consistent with
- other overrides (force_).
-
- * src/modules/sox/filter_sox.c: Fix channel alignment in sox filter. This
- pointer swapping is somehow breaking the stereo imaging even though I can not
- see why now. Anyways, it no longer support multiple effects, so it does not
- matter.
-
-2010-09-02 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sox/filter_sox.c: Fix sox effect parameters.
-
- * src/modules/avformat/producer_avformat.c: Automatically crop 8 bottom lines
- of 1088 source.
-
-2010-09-01 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/normalize/filter_volume.c: Accept negative dB values for volume
- filter.
-
-2010-08-31 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/normalize/filter_volume.c: Fix integrity of volume filter when
- applying multiple instances.
-
-2010-08-30 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_luma.c: Fix positioning bugs in filter luma.
- Discovered while working on slideshow animation in Kdenlive.
-
-2010-08-29 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl_still.c: Fix segfault in SDL observed in
- Kdenlive. Triggered by reloading a clip.
-
- * src/modules/avformat/filter_swscale.c: Fix regression on scaling alpha
- channel. Regression introduced with usage of sws_getCachedContext not too
- long ago.
-
-2010-08-28 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix audio decoding when AVPacket
- has >1 frame. This was most obvious on FLAC.
-
- * src/modules/jackrack/filter_jackrack.c: Fix jackrack filter not working
- without rack file.
-
-2010-08-23 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/filter_avcolour_space.c: Fix regression in
- avcolorspace filter.
-
2010-08-22 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/consumer_avformat.c,
src/modules/avformat/filter_swscale.c,
src/modules/avformat/producer_avformat.c: Use caching for swscale contexts.
- * src/modules/avformat/configure: Fix detecting VDPAU on dash-based systems.
- The script was using 'echo -e' which is not POSIX-compliant. The
- recommendation is to use printf with string containing escape sequences.
-
2010-08-21 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/consumer_avformat.c,
FFmpeg builds that use runtime CPU detection. This should make things faster
and it seems to be same quality as C routines.
- * demo/mlt_slideshow2: Minor fix to mlt_slideshow2.
-
* demo/mlt_slideshow2, src/modules/core/filter_luma.c: Enhance luma filter to
work with animated filters. Previously, in a slideshow the luma filter would
apply the dissolve or wipe repeatedly over a slide. For example, with a slide
video with the audio waveform. Currently, it only works on producers that
also provide video.
- * src/framework/mlt_frame.c: Improve audio waveform resault reliability.
- This scales the audio sample rate up to meet the requested image resolution,
- 16 KHz at a time.
-
- * src/framework/mlt_frame.c: Fix potential segfault in
- mlt_frame_get_waveform. Also, reduce sample rate for better performance.
-
- * src/framework/mlt_frame.c: Improve audio waveform quality. This averages
- over the pcm samples in each image column by adding a shade of gray. It also
- draws a solid white base line for each channel.
-
2010-08-18 Dan Dennedy <dan@dennedy.org>
* src/framework/mlt_frame.c, src/swig/mlt.i, src/swig/python/waveforms.py:
stacked. Also, add a Python binding to this call to return 8-bit grayscale
image as a Python string. Finally, add a Python example.
-2010-08-17 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_panner.c: Convert panner to use range [0, 1].
- Instead of [-1, 1]. This works better with Kdenlive.
-
2010-08-16 Dan Dennedy <dan@dennedy.org>
* src/modules/core/Makefile, src/modules/core/factory.c,
front/rear fade and ganging (balance front and rear together or fade left and
right together).
- * src/modules/core/transition_mix.c: Fix ramping the mix level in mix
- transition. Without ramping the same mix level is applied across the samples
- in the frame. The result is a stair-stepping effect. With ramping, the mix
- levels are actually values _between_ frames and the mix factor gradually
- changes from one level to the next across all of the samples in the frame.
-
2010-08-15 Dan Dennedy <dan@dennedy.org>
- * src/modules/core/filter_channelcopy.c: Only do channelcopy/swap if there is
- valid work.
-
* src/modules/core/factory.c, src/modules/core/filter_channelcopy.c: Add
filter channelswap. It is a permutation of channelcopy that can be used from
channelcopy as well by setting swap=1.
2010-08-14 Dan Dennedy <dan@dennedy.org>
- * src/modules/core/filter_imageconvert.c: Make it easier to switch between
- scaled and unscaled native colorspace converters.
-
* src/modules/avformat/consumer_avformat.c,
src/modules/avformat/filter_avcolour_space.c,
src/modules/avformat/filter_swscale.c,
2010-08-08 Dan Dennedy <dan@dennedy.org>
- * src/modules/sdl/consumer_sdl_still.c: Change SDL still consumer to use
- RGBA. Since frei0r filters are popular and use rgba, and also because
- Kdenlive scopes request rgba, this will reduce the number of conversions.
-
* src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/qimage_wrapper.cpp:
Make libexif include compatible with more systems/versions.
- * src/modules/avformat/producer_avformat.c: Fix image cache hit updating
- position state (kdenlive-1714).
-
- * src/modules/xine/filter_deinterlace.c: Optimize some deinterlace filter
- logic. Prevents YADIF from fetching current frame image if previous frame
- image is signalled progressive. Also, tells mlt_service to stop decorating
- frame with previous and next frames when producer is determined to be
- progressive or deinterlace is not requested.
-
2010-08-07 Dan Dennedy <dan@dennedy.org>
* src/modules/core/transition_luma.c, src/modules/frei0r/transition_frei0r.c,
src/modules/plus/transition_affine.c: Fix scaling method on B frames of some
transitions.
-2010-08-05 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_tractor.c: Fix tractor to set conversion functions on
- frames it generates.
-
2010-08-04 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/consumer_avformat.c, src/modules/dv/consumer_libdv.c,
src/modules/sdl/consumer_sdl_still.c: Move firing consumer-frame-show to
after done with image.
- * src/modules/gtk2/producer_pixbuf.c: Initialize processed var and skip if
- NULL.
-
2010-07-29 j-b-m <jb@kdenlive.org>
* src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/qimage_wrapper.cpp:
src/modules/qimage/qimage_wrapper.cpp new file:
src/modules/qimage/readexif.h
-2010-07-22 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/frei0r/frei0r_helper.c: Fix memory corruption on any frei0r
- plugin with color param.
-
- * src/modules/frei0r/factory.c: Recognize new FREI0R_PATH env var.
- FREI0R_PATH was introduced in v1.2 of the frei0r specification.
- MLT_FREI0R_PLUGIN_PATH still accepted for backwards compatibility.
-
2010-07-20 j-b-m <jb@kdenlive.org>
* src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/qimage_wrapper.cpp:
Fix exif rotation angle modified: src/modules/gtk2/producer_pixbuf.c
modified: src/modules/qimage/qimage_wrapper.cpp
- * src/modules/gtk2/producer_pixbuf.c: Support exif rotation with pixbuf
- producer modified: src/modules/gtk2/producer_pixbuf.c
-
- * src/modules/qimage/qimage_wrapper.cpp: Add support for auto rotation for
- images with exif data The meta.attr.rotation property must be set to the exif
- data to get the auto rotate effect. Only supported by qimage producer, not
- with pixbuf currently... modified: src/modules/qimage/qimage_wrapper.cpp
-
-2010-07-19 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix infinite loop on some audio
- decode errors (kdenlive-1690).
-
2010-07-14 Dan Dennedy <dan@dennedy.org>
* configure, src/modules/avformat/producer_avformat.c: Fix crash when
2010-06-20 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog for v0.5.6.
-
* Doxyfile, configure, docs/melt.1, src/framework/mlt.h: Set version to
0.5.6.
- * NEWS: Add v0.5.6 release notes.
-
* src/modules/avformat/Makefile, src/modules/avformat/configure,
src/modules/avformat/factory.c: Fixup local ffmpeg build. Set PIC compiler
flag, make libavdevice optional, and set recommended version to 0.6 branch.
-2010-06-19 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/plus/filter_affine.c: Fix the relative position of affine
- filter.
-
-2010-06-18 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/plus/interp.h: Fix affine interpolation reading outside image.
- This created image garbage along some edges.
-
- * src/modules/plus/transition_affine.c: Fix max affine geometry size wrt
- aspect.
-
-2010-06-17 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Revoke special handling for
- vorbis. It is no longer needed for Ogg and messes up WebM output.
-
2010-06-15 Dan Dennedy <dan@dennedy.org>
- * src/modules/linsys/consumer_SDIstream.c: Fix sdi sample count to be
- recomputed on each iteration.
-
- * src/modules/linsys/consumer_SDIstream.c: Provide sensible defaults for HD
- SDI. Also, now blanking may also be set to 0 or 1 to be consistent with
- other boolean MLT properties.
-
* src/modules/jackrack/filter_jackrack.c, src/modules/jackrack/plugin_desc.h:
Fix a few compiler warnings in jackrack.
-2010-06-09 Dan Dennedy <dan@dennedy.org>
-
- * .gitignore: Tell git to ignore swig-generated .cxx files.
-
-2010-06-07 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/plus/interp.h: Use rint instead of roundf to suppress compiler
- warnings.
-
- * src/modules/plus/transition_affine.c: Cleanup affine and fix a glitch that
- may appear.
-
- * src/modules/plus/transition_affine.c: Fix the repeat/mirror cycle to be
- relative to start of transition. Before, it was relative to start of
- timeline, and this meant geometry animations would start at unpredictable
- locations.
-
- * src/modules/core/filter_obscure.c: Fix infinite loop when obscure blocking
- <1. Patch from Till Theato.
-
-2010-06-03 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/kdenlive/filter_boxblur.c: Make bloxblur faster and simpler.
- It no longer does YUV-RGB-YUV conversion; just operates in RGB.
-
- * src/melt/melt.c: Fix superficial cpu usage with melt progress option (used
- by Kdenlive).
-
2010-06-02 Dan Dennedy <dan@dennedy.org>
* src/modules/plus/filter_affine.c, src/modules/plus/interp.h,
src/modules/plus/transition_affine.c: Revise affine to use interpolation and
sub-pixel positioning.
-2010-05-31 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/Makefile: Fix build on BSD with VDPAU (Alberto Villa).
-
-2010-05-30 j-b-m <jb@kdenlive.org>
-
- * src/modules/qimage/configure: Fix compilation (Qt Xml linking)
-
-2010-05-28 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix compilation warning
- undeclared av_get_pix_fmt().
-
- * src/modules/frei0r/factory.c: Fix a memory leak registering frei0r
- services.
-
-2010-05-20 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl_osx.h: Fix build on non-OSX due to missing
- parameter name.
-
2010-05-18 Dan Dennedy <dan@dennedy.org>
* src/modules/sdl/consumer_sdl_osx.h, src/modules/sdl/consumer_sdl_osx.m: Fix
src/modules/sdl/consumer_sdl_still.c: Fix leaking OS X Cocoa objects in SDL
consumers.
-2010-05-16 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Enable flushing the encoder
- buffers. This improves reliability of encoding especially multithreaded x264
- (remove ugly hack).
-
- * src/modules/avformat/consumer_avformat.c: Fix deprecated function and
- remove unused variable.
-
- * src/modules/avformat/consumer_avformat.c: Multitrack audio encoding
- continued. This version changes the configuration and remapping. The number
- of channels per output audio track is set using "channels.<N>" properties on
- the avformat consumer, where <N> is a 0-based numeric representing the output
- track. At this time, all tracks must share all other attributes such as
- sample rate, codec, and bitrate. As for the remapping, this attempts to
- reuse the meta.map.audio... properties set on the producers as used with the
- sdi consumer. One exception: to skip or silence channels at the beginning
- tracks or in the middle, you must add additional map properties to the end of
- the list to simulate these "gaps."
-
-2010-05-12 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Add multitrack audio encoding.
- This is a check point for the first working version. Changes are forthcoming.
-
2010-05-07 Marco Gittler <g.marco@freenet.de>
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
2010-05-02 Dan Dennedy <dan@dennedy.org>
- * src/swig/perl/Makefile.PL: Remove hardcoded 32-bit arch in Perl binding
- (2995474).
-
* src/swig/csharp/build, src/swig/java/build, src/swig/lua/build,
src/swig/perl/Makefile.PL, src/swig/perl/build, src/swig/php/build,
src/swig/python/build, src/swig/ruby/build, src/swig/tcl/build: Fix missing
2010-04-25 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/producer_avformat.c: Fix white artifacts in image
- (2972137) Also applies to Kdenlive bug 1509.
-
* configure, src/modules/core/filter_resize.c: Fix bad stride in yuv422 due
to non-even width requests.
2010-04-19 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog for v0.5.4.
-
* Doxyfile, configure, docs/melt.1, src/framework/mlt.h: Set version to
0.5.4.
- * NEWS: Add v0.5.4 release notes.
-
* src/framework/mlt_frame.c, src/modules/avformat/producer_avformat.c:
Improve error handling on video decode failure (kdenlive-1553).
version of libswcale. Some early revisions of 0.7.1 would cause garbage on
last column of image with non-even width.
-2010-04-17 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/producer_colour.c: Fix color producer not setting
- real_wdith and _height.
-
-2010-04-15 Dan Dennedy <dan@dennedy.org>
-
- * configure: --disable-mmx, --disable-sse should also disable sse2.
-
2010-04-08 Dan Dennedy <dan@dennedy.org>
* src/swig/configure, src/swig/csharp/build, src/swig/csharp/play.cs,
number of audio channels, audio sampling rate, audio sample size. It does
_not_ set the clock source or the number of buffers for audio and video.
-2010-04-06 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/producer_consumer.c: Bugfix memory leak with producer
- consumer (2976110). Also kdenlive bug 1197.
-
- * src/modules/xine/filter_deinterlace.c: Better signal previous/next frames
- not needed.
-
2010-03-10 Dan Dennedy <dan@dennedy.org>
- * NEWS: Fix version number in release notes :(
-
- * ChangeLog: Update ChangeLog for v0.5.2.
-
* Doxyfile, configure, docs/melt.1, src/framework/mlt.h: Set version to
0.5.2.
- * NEWS: Add v0.5.2 release notes.
-
* src/modules/linsys/consumer_SDIstream.c,
src/modules/linsys/sdi_generator.c, src/modules/linsys/sdi_generator.h:
Improve performance of sdi consumer (patch from BCE). consumer_SDIstream.c -
* src/mlt++/Makefile, src/mlt++/MltFilteredProducer.cpp,
src/mlt++/MltFilteredProducer.h: Fix MltFilteredProducer not building.
-2010-03-02 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl_preview.c: Fix regressions playing all frames
- at end (kdenlive-1207).
-
- * src/modules/core/producer_loader.c: Fix recent regression on failure to
- load file.
-
2010-02-28 Dan Dennedy <dan@dennedy.org>
- * src/modules/core/loader.ini: Make swscale the preferred rescale filter.
- Should be safe now since the default compile-time max resolution for
- libswscale was increased to 5120 for non-ppc systems as of May, 2009. Also,
- because I added the initialization and range tests.
-
* src/modules/avformat/filter_avcolour_space.c,
src/modules/avformat/filter_swscale.c, src/modules/core/producer_loader.c:
Add resolution as init arg to libswscale filters.
* src/framework/mlt_frame.c, src/modules/effectv/filter_burn.c: Fix a couple
of compile warnings.
-2010-02-27 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix crash on reading uncompressed
- (rawvideo).
-
- * src/modules/core/filter_rescale.c: Report scaling method in debug logging.
-
- * src/modules/avformat/consumer_avformat.c: Fix offset to alpha component on
- OS X.
-
2010-02-25 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/filter_avcolour_space.c,
src/modules/core/producer_loader.c: Make FFmpeg the primary image converter
if available. Except on OS X.
- * src/modules/avformat/factory.c: Fix avcolor_space alias.
-
- * src/modules/effectv/filter_burn.c: Fix endianness of the palette in
- burningtv.
-
- * src/modules/sdl/consumer_sdl_preview.c: Fix playing all frames at end of
- project (kdenlive-1207).
-
2010-02-24 Dan Dennedy <dan@dennedy.org>
* src/modules/xine/Makefile, src/modules/xine/yadif.c: Fix build on
2010-02-15 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog for 0.5.0 release.
-
* Doxyfile, configure, docs/melt.1, src/framework/mlt.h: Set version to
0.5.0.
* NEWS, src/modules/avformat/configure: Add v0.5.0 release notes.
-2010-02-14 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_frame.c: Fix mlt_sample_calculator returning negative
- result.
-
- * src/framework/mlt_cache.c: Simplify some of the cache locking and less
- flip-flop.
-
- * src/modules/avformat/producer_avformat.c: Add a reference to avformat
- producer on the frame when cache miss. Also adds some additional checks on
- null pointers.
-
2010-02-11 Dan Dennedy <dan@dennedy.org>
* src/modules/linsys/consumer_SDIstream.c,
* src/modules/linsys/Makefile, src/modules/linsys/configure: Add
--linsys-with-jpeg configure option.
- * src/modules/linsys/factory.c: Change linssys_sdi consumer to just "sdi"
-
2010-02-10 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/producer_avformat.c: Make avformat producer less
- chatty in verbose mode.
-
* profiles/atsc_1080i_50, profiles/atsc_1080i_5994, profiles/atsc_1080i_60,
profiles/atsc_1080p_2398, profiles/atsc_1080p_24, profiles/atsc_1080p_25,
profiles/atsc_1080p_2997, profiles/atsc_1080p_30, profiles/atsc_720p_2398,
profiles/sdi_486i_5994, src/framework/mlt_profile.c: Revise Hz->fps in
profiles and add more ATSC profiles.
- * src/modules/avformat/vdpau.c: Look for libvdpau.so in /usr/lib64 as well.
-
-2010-02-08 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/xml/producer_xml.c: Add support for unspecified out points in
- XML.
-
- * src/framework/mlt_playlist.c: Add support for only negative out in
- mlt_pplaylist_append_io.
-
- * src/framework/mlt_producer.c: Add support for negative out in
- mlt_producer_set_in_and_out.
-
- * src/framework/mlt_playlist.c: Change -1 handling for in/out points to be
- any negative value.
-
- * src/modules/vorbis/producer_vorbis.c: Fix short forward seeking in vorbis
- producer.
-
- * src/modules/avformat/producer_avformat.c: Fix audio muxing when
- downsampling >2 channels. A side effect of this bug was a big memory
- consumption. This occurs mostly commonly when using 5.1 audio sources such as
- AVCHD or DVD and encoding to 44.1 KHz.
-
-2010-02-07 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_resize.c: Safer to use the image from get_image and
- to compute the size.
-
- * src/modules/avformat/producer_avformat.c: Fix crash in filter resize with
- cached images (kdenlive-1330). Also properly sets the top_field_first flag
- on frames with cached image. Also adds the noimagecache property for
- troubleshooting.
-
2010-02-04 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/consumer_avformat.c: Sometimes x264 is crashing on
- single or first pass with multithreading.
-
- * src/modules/core/producer_consumer.c: Fix progressive property on frames in
- the consumer producer. This also adds deinterlace_method and rescale
- (method) properties to the producer so it can set those on its embedded
- consumer.
-
* src/modules/sdl/consumer_sdl.c, src/modules/sdl/consumer_sdl_audio.c,
src/modules/sdl/consumer_sdl_preview.c: Default SDL to use the onefield
deinterlace filter. The previous default in the deinterlace filter was
src/framework/mlt_service.h: Hide need_previous_next property from
serialization.
- * src/modules/avformat/producer_avformat.c: Fix setting resolution and format
- in avformat image caching.
-
2010-02-02 Dan Dennedy <dan@dennedy.org>
- * configure: Add SSE2_FLAGS and --disable-sse2 to configure. This is
- required for YADIF assembler.
-
* src/framework/mlt_filter.h, src/framework/mlt_frame.h,
src/framework/mlt_service.c, src/framework/mlt_service.h: Add fetching
previous and next frames in producers. This is only enabled when the
ANY filters applied to them, which is important for YADIF and telecide
filters, which process before all other filters.
- * src/framework/mlt_multitrack.c: Prefer the API over setting property.
-
- * src/modules/avformat/producer_avformat.c: Fix force_progressive=0 on
- avformat producer.
-
- * src/modules/avformat/producer_avformat.c: Add image caching to avformat
- producer. This not only helps with very short seeking around a point
- especially on AVCHD but also will help immensely with YADIF.
-
-2010-01-28 Dan Dennedy <dan@dennedy.org>
-
- * Doxyfile: Sort members in doxygen docs.
-
-2010-01-26 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix segfault when using
- audio_index=all on file with no audio.
-
-2010-01-23 j-b-m <jb@kdenlive.org>
-
- * src/modules/oldfilm/filter_vignette.c: Fix vignette filter position
- modified: src/modules/oldfilm/filter_vignette.c
-
-2010-01-22 j-b-m <jb@kdenlive.org>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Round corners in titles for
- rectangle borders (Patch from Till Theato) modified:
- src/modules/qimage/kdenlivetitle_wrapper.cpp
-
- * .../motion_est/filter_autotrack_rectangle.c: Fix typo in autotrack filter
- modified: src/modules/motion_est/filter_autotrack_rectangle.c
-
2010-01-21 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/producer_avformat.c, src/modules/avformat/vdpau.c: Let
2010-01-19 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/consumer_avformat.c: Make realtime (streaming)
- avformat consumer less bursty. Patch from PrimeTel PLC -
- http://www.prime-tel.com
-
* src/modules/avformat/configure, src/modules/avformat/factory.c,
src/modules/avformat/producer_avformat.c: Add support for libavdevice
(v4l/v4l2). Thanks to hints from Volodymyr M. Lisivka.
src/modules/qimage/producer_qimage.c: Return and handle errors on failure to
produce image (kdenlive-1312).
- * src/modules/core/filter_resize.c: Fix incorrect comment about yuv422 only
- in resize filter.
-
-2010-01-18 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix muxing when encoding with
- x264 and B frames (2928953).
-
- * src/modules/avformat/consumer_avformat.c: Remove deprecation warnings on
- guess_format.
-
2010-01-16 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/consumer_avformat.c: Only report video encode error
- when truly error result.
-
- * src/modules/avformat/consumer_avformat.c: Add apre, fpre, and vpre
- properties to avformat consumer. These read ffmpeg preset files, which is
- really handy for x264 encoding on the command line. They require the full
- path to the file unlike the ffmpeg utility. apre is for audio, vpre is for
- video, and fpre is for the format/muxer.
-
- * src/framework/mlt_frame.c: Refactor mlt_sample_calculator to reuse
- mlt_sample_calculator_to_now.
-
* Doxyfile, src/framework/mlt_frame.c, src/framework/mlt_frame.h,
src/framework/mlt_service.h: Add mlt_frame doxygen docs.
-2010-01-13 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix detection of aspect ratio of
- DV in AVI.
-
-2010-01-12 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix A/V sync after seeking on
- some files (2892086).
-
-2010-01-12 j-b-m <jb@kdenlive.org>
-
- * src/modules/kdenlive/filter_freeze.c: Fix memleak in freeze filter -
- Kdenlive issue 1379 modified: src/modules/kdenlive/filter_freeze.c
-
2010-01-10 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/producer_avformat.c,
src/modules/xine/filter_deinterlace.c: Fix setting progressive property on
repeated frames (kdenlive-1335).
-2010-01-09 gmarco <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: round outline pen
-
-2009-12-23 Marco Gittler <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: outline text possible (with
- use of font-outline/font-outline-color)
-
2010-01-06 Marco Gittler <g.marco@freenet.de>
* src/modules/oldfilm/filter_oldfilm.c,
src/modules/oldfilm/filter_oldfilm.yml: user array with 100 values yml file
updated
- * src/modules/oldfilm/filter_oldfilm.c: unevendevelop effect
-
-2009-12-21 j-b-m <jb@kdenlive.org>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Fix crash when opening a
- kdenlive document with titles modified:
- src/modules/qimage/kdenlivetitle_wrapper.cpp
-
-2009-12-17 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/linsys/consumer_SDIstream.c: Add force_channels to sdi consumer
- for troubleshooting.
-
- * src/modules/avformat/producer_avformat.c: Fix crash at end of some files
- with audio_index=all.
-
2009-12-16 Dan Dennedy <dan@dennedy.org>
- * src/modules/sdl/consumer_sdl_still.c: This lock makes kdenlive start more
- reliably in the debugger.
-
* src/framework/mlt_service.c, src/framework/mlt_service.h,
src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/producer_qimage.c: Add
mlt_service_cache_purge and remove purge in mlt_service_close. The avformat
mlt_service_close can not purge the cache because frames may be closed after
the producer.
- * src/modules/avformat/producer_avformat.c: Redo avformat producer locking -
- less off-and-on.
-
2009-12-14 Dan Dennedy <dan@dennedy.org>
* configure, src/framework/mlt.h: Bump to unreleased version.
2009-12-13 Dan Dennedy <dan@dennedy.org>
- * src/modules/sdl/consumer_sdl.c: Fix for when actual channels does not match
- requested. This typically only happens when using audio_index=all on the
- avformat producer. This also adds a audio_offset property to the sdl consumer
- to help with testing audio_index. It takes a numeric value in units of
- channels over which to skip.
-
- * src/modules/avformat/vdpau.c: Do not compile vdpau_close() until it can be
- used.
-
* src/modules/avformat/factory.c, src/modules/avformat/producer_avformat.c:
Add producer variant avformat-novalidate. The purpose of this is to increase
the speed of loading playlists with known good files. Use with care. This
tested thus far by modifying the output of consumer xml to change mlt_service
from "avformat" to "avformat-novalidate".
- * src/modules/avformat/producer_avformat.c: Fix audio_index=all when stream
- not stereo.
-
- * src/modules/avformat/vdpau.c: Fix segfault in vdpau_init when x11_display
- not set.
-
- * src/modules/avformat/producer_avformat.c: Some B.C.E. sample files need
- more audio streams.
-
- * src/modules/avformat/producer_avformat.c: Fix regression with addition of
- mlt_cache. This change would cause the producer to not fully initialize on
- the first call to get_frame.
-
2009-12-12 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/producer_avformat.c, src/modules/avformat/vdpau.c: Add
to about 10 - 15 clips using VDPAU in the project at the moment until the
avformat producer is changed to use mlt_cache.
- * src/melt/melt.c: SDL must not close X11 while VDPAU is still using it.
-
* src/framework/mlt_consumer.c, src/modules/sdl/consumer_sdl.c,
src/modules/sdl/consumer_sdl_preview.c, src/modules/sdl/consumer_sdl_still.c:
Make the SDL consumer cooperate with VDPAU. This moves the SDL_Quit calls
X11 Display pointer to the mlt_environment and the global SDL mutex to the
consumer class.
-2009-12-10 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_crop.c: Add center_bias property to crop filter.
-
2009-12-08 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog for 0.4.10 release.
-
* Doxyfile, NEWS, configure, docs/melt.1, src/framework/mlt.h: Set version to
0.4.10 and update release notes.
- * src/modules/core/filter_audioconvert.c: Fix audioconvert setting frame
- audio on no conversion. This was causing the existing audio to be released
- and then telling mlt_properties to release the audio again with the old
- pointer (double free).
-
* configure, src/framework/mlt.h, src/modules/avformat/producer_avformat.c:
Fix underlinking libm by removing math function.
2009-12-07 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog for 0.4.8 release.
-
* Doxyfile, configure, docs/melt.1, src/framework/mlt.h: Set version to
0.4.8.
- * NEWS: Add v0.4.8 release notes.
-
* src/modules/core/loader.ini, src/modules/core/producer_loader.c: Fix some
cases image and audio formats not converting (kdenlive-1259).
- * src/modules/core/transition_composite.c: Fix crash in
- composite-on-composite (kdenlive-1315).
-
-2009-12-06 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix crash in x264 on second pass
- of multi-threaded encoding.
-
- * src/modules/avformat/consumer_avformat.c: Disable multi-threaded audio
- encoding (not useful).
-
- * src/modules/avformat/consumer_avformat.c: Fix encoding PCM on some recent
- FFmpeg change (kdenlive 1282). Also includes a little cleanup and extra
- buffer overwrite protection.
-
- * src/modules/avformat/consumer_avformat.c: Fix regression causing writing
- beyond end of buffer (kdenlive 1282). Anything with a PCM output is still
- crashing including DV and WAV.
-
-2009-12-05 Dan Dennedy <dan@dennedy.org>
-
- * src/swig/ruby/build: Fix build (CFLAGS) of Ruby binding.
-
-2009-12-02 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix audio buffer overflow on
- large resampling (2902193).
-
- * src/modules/avformat/producer_avformat.c: Fix regression converting mono to
- stereo.
-
- * src/modules/core/filter_crop.c: Add center property to crop to
- automatically fill frame.
-
-2009-12-01 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_crop.c: Fix distorting aspect ratio of images with
- crop. Unfortunately, this has the side effect of breaking the crop extents
- of existing projects when crop was applied to an image or image sequence.
- However, those projects were using a distorting version of crop and would
- need to be revised anyways.
-
- * src/modules/core/filter_crop.c: Add support for cropping RGB(A).
-
- * src/modules/core/filter_resize.c: Only correct field order if the source is
- interlaced.
-
-2009-11-29 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_crop.c: Re-Fix bounds checking of crop filter
- (kdenlive-1148).
-
- * src/modules/avformat/producer_avformat.c: Add force_fps property to
- avformat producer.
-
- * src/modules/frei0r/factory.c: Fix locating plugins in $HOME/.frei0r-1/lib
- (2897195).
-
- * src/modules/avformat/producer_avformat.c: Fix pointer of V plane for
- yuv420p.
-
- * src/modules/avformat/producer_avformat.c: Fix crash in avformat producer on
- unusable file.
-
- * src/modules/oldfilm/filter_vignette.yml: Fix validation and consistency
- errors in vignette YAML.
-
2009-11-29 Marco Gittler <g.marco@freenet.de>
* src/modules/oldfilm/filter_vignette.c,
src/modules/oldfilm/filter_vignette.yml: use float for vignette effect fixed
also bug in wrong y center
-2009-11-29 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/oldfilm/filter_vignette.yml: Fix broken vignette YAML.
-
-2009-11-29 Marco Gittler <g.marco@freenet.de>
-
* src/modules/oldfilm/filter_vignette.c,
src/modules/oldfilm/filter_vignette.yml: use extra paramters for vignette
settings
-2009-11-21 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Add support for new libavcodec
- decode functions.
-
- * src/modules/avformat/producer_avformat.c: Fix seek on some AVCHD causing
- infinite loop. This detects when libavformat starts to consistently report
- invalid PTS and then will disable Ivan's new_seek code. In the example file I
- have this only happens when seeking backwards, which typically implies an
- interactive use case (except when using framebuffer with speed < 0). Then, it
- should still use the new_seek when simply apply an in point to allow for a
- clean, accurate cut.
-
-2009-11-20 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix regression in audio only
- output.
-
- * src/modules/avformat/producer_avformat.c: Fix dropping samples on math
- error (kdenlive 1219).
-
-2009-11-14 j-b-m <jb@kdenlive.org>
-
- * src/modules/frei0r/filter_frei0r.c: Fix frei0r helper filter position (used
- for keyframes)
-
-2009-11-13 j-b-m <jb@kdenlive.org>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Fix typewriter start param
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Add an offset start param to
- typewriter effect
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Get ready for typewriter
- effect in titles
-
-2009-11-05 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/frei0r/factory.c: Some frei0r filters need to be initialized
- before getting param info.
-
- * src/modules/frei0r/factory.c: Some frei0r filters need to be initialized
- before getting param info.
-
-2009-11-04 j-b-m <jb@kdenlive.org>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Fix images hidden
- (kdenlive-1247) Get ready for title effects (blur, shadow)
-
-2009-10-26 Dan Dennedy <dan@dennedy.org>
-
- * .../motion_est/filter_autotrack_rectangle.c: Fix autotrack_rectangle with
- negative origin (kdenlive 766).
-
- * src/framework/mlt_frame.c: These get/set position calls are unnecessary.
-
-2009-10-19 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix short output when video
- shorter than audio (kdenlive 1207).
-
-2009-10-13 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix audio distortion due to
- supplying incorrect decode buffer size.
-
- * src/modules/avformat/producer_avformat.c: Add dynamically resizing audio
- buffer.
-
-2009-10-12 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix regression on video-only
- files (kdenlive-1206).
-
-2009-10-13 j-b-m <jb@kdenlive.org>
-
- * src/modules/kdenlive/filter_freeze.c: Fix freeze effect issues with
- transitions (kdenlive 1192) modified: src/modules/kdenlive/filter_freeze.c
-
-2009-10-11 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_crop.c: Fix bounds checking of crop filter
- (kdenlive-1148).
-
- * src/modules/avformat/producer_avformat.c: Fix regression with mono audio
- (kdenlive-1204).
-
2009-10-10 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/producer_avformat.c: Add codec.frame_rate and drop the
- profile/level meta properties.
-
- * profiles/svcd_pal_wide: Fix the display aspect ratio of SVCD Widescreen
- PAL.
-
* configure, src/framework/mlt.h: Bump the version to 0.4.7.
- * src/modules/linsys/consumer_SDIstream.c: Add audio channel mapping. This
- uses meta properties on the producer: meta.map.audio.<N>.channels=<integer>
- meta.map.audio.<N>.start=<integer> where 8 > N >= 0. The consumer loops over
- N, consumes meta...channels and outputs them from channel meta...start. The
- channel index starts at 0. For example, if the first audio track of the clip
- is stereo English and the second audio track is stereo French, then this will
- swap them: $ melt someclip audio_index=all meta.map.audio.0.channels=2
- meta.map.audio.0.start=2 meta.map.audio.1.channels=2 meta.map.audio.1.start=0
- -consumer linsys_sdi. However, the last pair of meta properties in this
- example are actually optional. The algorithm outputs the remaining channels
- at the start channel you specify. But since getting an unspecified property
- yields 0, the last meta properties is unnecessary as well.
-
- * src/modules/linsys/sdi_generator.c: Add MAX_AUDIO_STREAMS constant.
-
- * src/modules/avformat/producer_avformat.c: Improve this log message.
-
- * src/framework/mlt_tractor.c: Fix the tractor not passing meta properties to
- its new frame.
-
* src/modules/linsys/consumer_SDIstream.c,
src/modules/linsys/sdi_generator.c: Convert some printfs to mlt_log.
* src/modules/linsys/consumer_SDIstream.c,
src/modules/linsys/sdi_generator.c: Cleanup unused parameters.
- * src/modules/linsys/sdi_generator.c: Cleanup compiler warnings.
-
* src/modules/linsys/consumer_SDIstream.c,
src/modules/linsys/sdi_generator.c: Add support for >2 audio channels to
Linsys SDI consumer. This does not yet have any remapping support.
-2009-10-06 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Add support for audio_index=all.
-
-2009-09-22 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Convert audio structures to
- arrays. Also collect info about audio channels and streams.
-
-2009-09-21 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Factor out audio seeking and
- decoding from the get_audio callback.
-
-2009-09-18 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Factor out video codec
- initialization.
-
- * src/modules/avformat/producer_avformat.c: Factor out audio codec setup from
- audio index handling.
-
- * src/modules/avformat/producer_avformat.c: Reduce usage of properties for
- state.
-
2009-10-07 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update changelog for 0.4.6 release.
-
* AUTHORS, Doxyfile, NEWS, configure, docs/melt.1, src/framework/mlt.h: Set
version to 0.4.6 and update release notes.
configure option --avformat-svn-version. Also update recommended version to
Sept 15, 2009 and other cleanup.
-2009-10-05 j-b-m <jb@kdenlive.org>
-
- * src/modules/kdenlive/producer_framebuffer.c: Framebuffer producer should
- obey to the force_aspect_ratio value modified:
- src/modules/kdenlive/producer_framebuffer.c
-
2009-10-04 j-b-m <jb@kdenlive.org>
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.cpp modified:
src/modules/qimage/producer_kdenlivetitle.c
-2009-09-26 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Improve exception handling in
- consumer_avformat.
-
-2009-09-26 Marco Gittler <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: locale fix for decial numbers
-
-2009-09-26 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Improve exception handling in
- consumer_avformat.
-
-2009-09-24 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Wait for and close AVCodec
- threads at end. Except when using x264 because it may crash at the end of
- the second pass when using multiple threads. Also, cleanup another dual pass
- log file that new versions of x264 creates.
-
- * src/modules/avformat/consumer_avformat.c: Fix crash in logging warning
- (2865906).
-
-2009-09-22 Dan Dennedy <dan@dennedy.org>
-
- * src/swig/mlt.i: Fix swig building with some Python versions and possibly
- more.
-
2009-09-20 Dan Dennedy <dan@dennedy.org>
* src/mlt++/MltField.cpp, src/mlt++/MltField.h, src/mlt++/MltProducer.cpp,
2009-09-19 Dan Dennedy <dan@dennedy.org>
- * src/mlt++/MltProperties.cpp, src/mlt++/MltProperties.h: Add Properties
- constructor from opaque pointer.
-
-2009-09-15 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix crash when audio encode does
- not yield frame (2859643).
-
- * src/modules/avformat/consumer_avformat.c: Convert consumer_avformat message
- to mlt_log API.
-
-2009-09-15 j-b-m <jb@kdenlive.org>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Fix compatibility with older
- Kdenlive titles: Kdenlive bug 1137 modified:
- src/modules/qimage/kdenlivetitle_wrapper.cpp
-
-2009-09-15 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Remove the old location of the
- first_pts calculation.
-
- * src/modules/avformat/producer_avformat.c: Fix concurrency instability.
- (not related to new_seek)
-
-2009-09-13 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Relocate setting first_pts and
- fix ffmpeg concurrency.
-
-2009-09-09 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Restore seeking to one second
- before target. Since Ivan Schreter's FFmpeg mpegts new-seek patches were
- disabled, this is temporarily required for H.264 MPEG2-TS.
-
-2009-09-05 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Patch from Ivan Schreter to fix
- seeking on AVCHD. This is intended to improve seeking in general, but it not
- ready for all formats. It can be explicitly enabled by setting the new_seek
- property to 1. I added code to enable it by default for H.264 in MPEG-2
- Transport Stream, but one can disable it by setting new_seek to 0.
+ * src/mlt++/MltProperties.cpp, src/mlt++/MltProperties.h: Add Properties
+ constructor from opaque pointer.
2009-09-15 Dan Dennedy <dan@dennedy.org>
- * src/mlt++/MltFrame.cpp: Remove construction of unused properties object.
-
* src/swig/Makefile, src/swig/java/build, src/swig/lua/build,
src/swig/perl/build, src/swig/php/build, src/swig/python/build,
src/swig/ruby/build, src/swig/tcl/build: Fix distclean make target under swig
existing loader filter, which uses the name by which it is invoked to toggle
the behaviour of whether to attach normalizing filters.
-2009-09-12 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/kdenlive/producer_framebuffer.c: Fix framebuffer producer
- preventing image conversion and crop.
-
- * src/modules/qimage/configure: Fix kde_libdir detection for qimage (patch
- 2151852). Patch from Roberto Castagnola <roberto.castagnola@gmail.com>. In
- particular, Gentoo users have needed this.
-
2009-09-10 Dan Dennedy <dan@dennedy.org>
* Makefile, src/swig/Makefile, src/swig/configure: Improve swig build with
help from Michael Forney.
-2009-09-09 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/transition_composite.c: Restore performance
- characteristics of recent composite fix.
-
- * src/modules/core/transition_composite.c: Fix composite regression with no
- luma.
-
- * src/modules/core/transition_composite.c: Fix abruptness when using a luma
- with softness in composite.
-
- * src/modules/sdl/consumer_sdl_audio.c: Fix big memory leak when scrubbing.
-
-2009-09-10 j-b-m <jb@kdenlive.org>
-
- * src/modules/kdenlive/producer_framebuffer.c: Fix memleaks modified:
- src/modules/kdenlive/producer_framebuffer.c
-
-2009-09-09 j-b-m <jb@kdenlive.org>
-
- * src/modules/kdenlive/producer_framebuffer.c: Fix framebuffer flicker
- modified: src/modules/kdenlive/producer_framebuffer.c
-
-2009-09-08 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl_audio.c: Cleanup pthread mutexes and
- conditions.
-
- * src/modules/core/filter_rescale.c: Fix core scaler regression.
-
-2009-09-05 Dan Dennedy <dan@dennedy.org>
-
- * src/swig/configure: Patch from Michael Forney to fix swig configure. If
- configure is run with --swig-languages="lang1 lang2", it complains because it
- is compared to "all" without any quotes.
-
-2009-09-03 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/xml/consumer_xml.c: Fix making paths relative (kdenlive-1111).
-
-2009-09-01 j-b-m <jb@kdenlive.org>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Don't crash when running
- kdenlivetitle module from a console, instead print error message and exit
- modified: src/modules/qimage/kdenlivetitle_wrapper.cpp
-
-2009-08-31 j-b-m <jb@kdenlive.org>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Fix flicker frame appearing
- at 0 position, small optimisations modified:
- src/modules/qimage/kdenlivetitle_wrapper.cpp
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Fix flicker frame appearing
- at 0 position, small optimisations modified:
- src/modules/qimage/kdenlivetitle_wrapper.cpp
-
-2009-08-29 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_pool.c: The padding is no longer necessary with the gcc
- aligned attribute.
-
- * src/framework/mlt_pool.c: Chris Rudorff (ppc contributor) strongly suggests
- 16 byte alignment and padding for all arch.
-
- * src/modules/kdenlive/producer_framebuffer.c: Apply JBM's fix to framebuffer
- regression on big image convert refactoring.
-
- * src/framework/mlt_pool.c: Apply mem alignment and corruption patches from
- Christoph Rudorff while debugging ppc.
-
-2009-08-29 gmarco <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: removed warning
-
2009-08-26 Dan Dennedy <dan@dennedy.org>
- * src/modules/sdl/consumer_sdl_audio.c: Convert audio-only SDL consumer to
- new audio API.
-
- * src/modules/sdl/consumer_sdl_audio.c: Cleanup indentation
-
* src/modules/sdl/Makefile, src/modules/sdl/consumer_sdl_audio.c,
src/modules/sdl/factory.c: Add audio-only SDL consumer (for Kdenlive on OS
X).
- * src/modules/sdl/consumer_sdl_audio.c: Convert audio-only SDL consumer to
- new audio API.
-
- * src/modules/sdl/consumer_sdl_audio.c: Cleanup indentation
-
* src/modules/sdl/Makefile, src/modules/sdl/consumer_sdl_audio.c,
src/modules/sdl/factory.c: Add audio-only SDL consumer (for Kdenlive on OS
X).
src/modules/linsys/consumer_SDIstream.c, src/modules/linsys/factory.c,
src/modules/linsys/sdi_generator.c: Add Linsys SDI consumer from B.C.E.
-2009-08-18 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Fix a/v sync on files with
- incorrect codec frame rate, but correct muxer rate.
-
-2009-08-16 j-b-m <jb@kdenlive.org>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Titler: add support for
- background property modified: src/modules/qimage/kdenlivetitle_wrapper.cpp
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Titler: add support for
- background property modified: src/modules/qimage/kdenlivetitle_wrapper.cpp
-
-2009-08-07 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_frame.c: Fix a/v synch drift with some unhandled
- framerates (kdenlive-1034). Previously only special handling provided for
- 32000, 44100, and 48000 sample rates on the strange NTSC frame rate. Patch
- provided by Mike Adkins makes it generic including 24000/1001. Thanks!
-
2009-08-03 Dan Dennedy <dan@dennedy.org>
* src/framework/Makefile, src/framework/mlt_consumer.c,
2009-08-02 j-b-m <jb@kdenlive.org>
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Fix start / endviewport
- movement, do not respect aspect ratio when resizing modified:
- kdenlivetitle_wrapper.cpp
-
* src/modules/qimage/configure, src/modules/qimage/kdenlivetitle_wrapper.cpp:
Add support for svg items in titles modified: configure modified:
kdenlivetitle_wrapper.cpp
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Dont's set Graphicscene
- parent to avoid warning message, fix display of images modified:
- kdenlivetitle_wrapper.cpp
-
- * src/modules/qimage/kdenlivetitle_wrapper.h: remove unused var modified:
- kdenlivetitle_wrapper.h
-
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.h,
src/modules/qimage/producer_kdenlivetitle.c: Fix errors in caching + mem
qimage producer modified: kdenlivetitle_wrapper.cpp modified:
kdenlivetitle_wrapper.h modified: producer_kdenlivetitle.c
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: Cache image if there is no
- animation modified: kdenlivetitle_wrapper.cpp
-
2009-07-31 j-b-m <jb@kdenlive.org>
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
add myself in copyright modified: kdenlivetitle_wrapper.cpp modified:
kdenlivetitle_wrapper.h modified: producer_kdenlivetitle.c
-2009-07-31 Marco Gittler <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: kdenlivetitle_wrapper.cpp: qt
- 4.4 fix for scale
-
-2009-07-31 j-b-m <jb@kdenlive.org>
-
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.h: don't use cache, just normal
properties to store scene modified: kdenlivetitle_wrapper.cpp modified:
producers in one instance of Kdenlive modified: kdenlivetitle_wrapper.cpp
modified: kdenlivetitle_wrapper.h modified: producer_kdenlivetitle.c
-2009-07-27 gmarco <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: kdenlivetitle_wrapper.cpp:
- fixed merge conflict
-
2009-07-27 j-b-m <jb@kdenlive.org>
- * src/modules/qimage/producer_kdenlivetitle.c: debug -- modified:
- producer_kdenlivetitle.c
-
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.h,
src/modules/qimage/producer_kdenlivetitle.c: Cleanup + fix crashes when used
src/modules/qimage/kdenlivetitle_wrapper.h: Cleanup & fix crash modified:
kdenlivetitle_wrapper.cpp modified: kdenlivetitle_wrapper.h
-2009-07-26 Dan Dennedy <dan@dennedy.org>
-
- * src/framework/mlt_playlist.c: Fix handling of length parameter in
- mlt_playlist_remove_region. This fixes kdenlive bug 1030. The calls to
- mlt_playlist_split() inside this function appear to have forgotten that it
- splits _after_ the specified position.
-
-2009-07-26 j-b-m <jb@kdenlive.org>
-
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.h: Cleanup & fix crash modified:
kdenlivetitle_wrapper.cpp modified: kdenlivetitle_wrapper.h
-2009-07-25 j-b-m <jb@kdenlive.org>
-
- * src/framework/mlt_playlist.c: Fix bug preventing removal of one frame
- region modified: mlt_playlist.c
-
- * src/framework/mlt_playlist.c: Fix bug preventing deletion of one frame
- region modified: mlt_playlist.c
-
2009-07-24 j-b-m <jb@kdenlive.org>
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.cpp modified:
src/modules/qimage/producer_kdenlivetitle.c
- * src/modules/qimage/producer_kdenlivetitle.c: Remove debug output
-
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.h,
src/modules/qimage/producer_kdenlivetitle.c: Fix crash + position in time
src/modules/qimage/kdenlivetitle_wrapper.h modified:
src/modules/qimage/producer_kdenlivetitle.c
-2009-07-24 Marco Gittler <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: kdenlivetitle_wrapper.cpp:
- use changed format of title-xml
-
- * src/modules/qimage/qimage_wrapper.cpp: qimage_wrapper: removed unused line
-
-2009-07-24 j-b-m <jb@kdenlive.org>
-
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.h,
src/modules/qimage/producer_kdenlivetitle.c: Add feature to dynamically
2009-07-24 Marco Gittler <g.marco@freenet.de>
- * src/modules/qimage/factory.c: qimage/factory.c: readded deleted qimage
- producer
-
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.h,
src/modules/qimage/producer_kdenlivetitle.c: kdenlivetitle: reindent code /
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.h: reindent c++
- * src/modules/qimage/producer_kdenlivetitle.c: reindent code
-
* src/modules/qimage/factory.c, src/modules/qimage/qimage_wrapper.cpp:
readded deleted qimage producer in factory
-2009-07-20 Marco Gittler <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: clean image before painting
-
-2009-07-19 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl_still.c: Fix image refresh in sdl_still
- consmuer.
-
- * src/melt/melt.c: Avoid redefining _GNU_SOURCE.
-
2009-07-19 Marco Gittler <g.marco@freenet.de>
* src/modules/qimage/configure, src/modules/qimage/producer_kdenlivetitle.c:
kdenlivetitle: added QtXml during configure, add rescource to producer
-2009-07-18 gmarco <g.marco@freenet.de>
-
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: use start/end from kdenlive
- titlefiles
-
2009-07-18 Marco Gittler <g.marco@freenet.de>
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
2009-07-14 Dan Dennedy <dan@dennedy.org>
- * src/melt/melt.c: Add missing include for basename().
-
* src/modules/avformat/Makefile, src/modules/avformat/configure,
src/modules/core/Makefile, src/modules/dgraft/Makefile,
src/modules/dv/Makefile, src/modules/effectv/Makefile,
2009-07-14 Marco Gittler <g.marco@freenet.de>
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: don't block under
- qt-application (kdenlive)
-
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/producer_kdenlivetitle.c: cleanup
src/modules/qimage/kdenlivetitle_wrapper.h,
src/modules/qimage/producer_kdenlivetitle.c: test alpha channel
-2009-07-13 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/Makefile: Fix underlinking avformat on some systems
- (bug 2821055).
-
- * src/modules/sox/filter_sox.c: Apply sox 14.3 compatibility patch from Fathi
- Boudra.
-
2009-07-11 Marco Gittler <g.marco@freenet.de>
* src/modules/core/loader.dict, src/modules/qimage/kdenlivetitle_wrapper.cpp,
2009-07-10 Marco Gittler <g.marco@freenet.de>
- * src/modules/qimage/kdenlivetitle_wrapper.cpp: kdenlivetitle_wrapper: fixed
- typo, not seen in Mac OS (QtXml also needed
-
* src/modules/qimage/kdenlivetitle_wrapper.cpp,
src/modules/qimage/kdenlivetitle_wrapper.h,
src/modules/qimage/producer_kdenlivetitle.c: kdenlivetitle_wrapper: load
function and contains the various conversion routines. The loader producer
automatically attaches this filter to the producer it creates.
- * src/framework/mlt_profile.c: Slightly improve auto-setting
- MLT_NORMALISATION.
-
2009-06-30 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog for 0.4.4 release.
-
* Doxyfile, NEWS, configure, docs/melt.1, src/framework/mlt.h: Set to v0.4.4
and update release notes.
- * src/modules/sdl/consumer_sdl.c: Log failure to open audio.
-
-2009-06-29 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl_preview.c: Fix crash with invalid video_driver
- property.
-
- * src/modules/gtk2/Makefile: Link gtk2 module against libiconv on FreeBSD.
-
-2009-06-26 Dan Dennedy <dan@dennedy.org>
-
- * src/swig/configure: Fix conditional swig build and remove --enable-swig.
-
2009-06-23 Dan Dennedy <dan@dennedy.org>
* src/swig/configure, src/swig/lua/build, src/swig/lua/play.lua: Add SWIG Lua
* src/melt/Makefile, src/melt/configure, src/melt/melt.c: Add configure
option --rename-melt.
- * src/modules/avformat/producer_avformat.c: Fix crash in avformat producer on
- audio overrun. Fixes Kdenlive bug 754 and possibly others due to unchecked
- bounds writing to an audio buffer.
-
* src/modules/frei0r/Makefile, src/modules/frei0r/blacklist.txt,
src/modules/frei0r/factory.c: Add blacklist to frei0r module. This is for
Kdenlive bugs 913 and 917. It is populated with only facedetect for now.
- * src/framework/mlt_factory.c: Initialize the environment before the module
- repo. This lets module factory functions get info from mlt_environment().
-
2009-06-21 Dan Dennedy <dan@dennedy.org>
* src/modules/avformat/Makefile.orig, src/modules/avformat/Makefile.rej:
src/modules/avformat/consumer_avformat.c: Fix avformat consumer crashing on
pcm_s16le.
-2009-06-19 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/gtk2/Makefile: Fix underlink libm gtk2 module (floor).
-
- * src/modules/avformat/producer_avformat.c: Fix regression in 8bit audio
- handling. Regression occurred with migration to FFmpeg
- av_audio_resample_init(). This also drops usage of non-public audio convert;
- instead, relying upon new resample to do the same task. audioconvert.h is
- still used, however, to get the sample format description.
-
-2009-06-18 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sox/Makefile: Fix underlinking libm for sdl module. Patch from
- Debian.
-
- * docs/melt.1: Fix manpage whatis entry. Patch from Debian.
-
- * src/modules/kdenlive/producer_framebuffer.c: Fix framebuffer producer to be
- thread-safe.
-
2009-06-16 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/consumer_avformat.c: Migrate to FFmpeg
- avformat_alloc_context().
-
* src/modules/avformat/filter_avresample.c,
src/modules/avformat/producer_avformat.c: Migrate to FFmpeg
av_audio_resample_init.
src/modules/avformat/producer_avformat.c: Fix (kdenlive-824) >2 channels not
downmixed.
- * src/modules/jackrack/Makefile: Fix underlinking jackrack plugin.
-
2009-06-15 Dan Dennedy <dan@dennedy.org>
- * src/modules/kdenlive/producer_framebuffer.c: Fix big memory leak in
- framebuffer producer. This fix is for kdenlive bug 898. This was due to
- allocating a frame in get_frame that might not get closed by a skipped call
- to get_image. This skipping can happen when using realtime mode (frame
- dropping).
-
* configure, profiles/Makefile, src/framework/Makefile, src/melt/Makefile,
src/modules/avformat/Makefile, src/modules/core/Makefile,
src/modules/feeds/Makefile, src/modules/lumas/Makefile,
src/modules/oldfilm/Makefile, src/modules/xml/Makefile: Add datadir and
mandir options to configure.
- * src/modules/qimage/configure: Fix building qimage when QtGui does not
- include QtCore.
-
- * src/modules/gtk2/pixops.c: Fix compilation of gtk2 module.
-
* src/modules/kino/avi.cc, src/modules/kino/filehandler.cc,
src/modules/kino/kino_wrapper.cc: Apply patch from Debian to fix compilation
of kino module.
- * src/modules/gtk2/have_mmx.S: Apply patch from Debian to update have_mmx.
-
- * Makefile: Distributors do not like us to run ldconfig.
-
- * configure: Link with --no-undefined flag.
-
-2009-06-13 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/consumer_avformat.c: Fix encoding to Ogg Theora with
- Vorbis. This applies to Kdenlive bug 465. After fixing the huge memory leak,
- there was an audio sync problem, and the fix for that might help other
- formats as well (fix was to initialize the audio codec time base). This also
- increases the size of the audio encoding buffer to fix flac encoding.
-
2009-06-10 Dan Dennedy <dan@dennedy.org>
* docs/melt.1, docs/policies.txt, src/melt/melt.c: Add man page for melt.
Not yet installed.
-2009-06-07 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/transition_composite.c: Add invert boolean property to
- composite transition.
-
-2009-05-29 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/avformat/producer_avformat.c: Workaround video streams with
- wild timestamps (kdenlive-854)
-
2009-06-03 Dan Dennedy <dan@dennedy.org>
- * src/modules/avformat/producer_avformat.c: Add support for RGBA formats such
- as QT Anim.
-
* configure, src/framework/mlt.h: Set to interim version 0.4.3
- * src/modules/core/filter_rescale.c: Improve alpha scaling conditional logic.
-
2009-05-30 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update Changelog for 0.4.2 release.
-
* Doxyfile, NEWS, configure, src/framework/mlt.h: Bump versions and update
release notes.
src/modules/oldfilm/filter_vignette.yml: Fix YAML validation errors and
spelling of Vignette.
-2009-05-28 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_crop.c: Improve performance of crop filter.
-
-2009-05-27 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/core/filter_rescale.c: Bugfix (kdenlive-791) crash when using
- crop filter. The alpha channel was not getting scaled by gtkrescale (and
- possibly others). I moved the core alpha scaling to a fallback position for
- scalers that do not handle alpha channel.
-
- * src/framework/mlt_log.c: Change default log level to panic. Some testing
- against FFmpeg v0.5 shows logging is still verbose with warnings enabled, but
- panic is better?
-
- * src/framework/mlt_log.c: Change default log level to warning or worse.
-
- * src/mlt++/configure: Fix typo in mlt++ CXXFLAGS.
-
2009-05-26 Dan Dennedy <dan@dennedy.org>
* src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/qimage_wrapper.cpp,
Change the ttl default value for image sequences. When using printf-style
image sequences only, the default ttl is now 1.
-2009-05-21 Dan Dennedy <dan@dennedy.org>
-
- * src/modules/sdl/consumer_sdl.c: Bugfix sdl consumer not using
- profile.progressive
-
2009-05-20 Dan Dennedy <dan@dennedy.org>
* configure, src/framework/mlt.h: Bump to an interim version.
- * src/modules/motion_est/Makefile: Link motionest against libm.
-
- * src/mlt++/config.h: Fix license in comment header.
-
2009-05-17 Dan Dennedy <dan@dennedy.org>
- * ChangeLog: Update ChangeLog
-
* Makefile, NEWS: Add v0.4.0 release notes.
* Doxyfile, configure, src/framework/mlt.h: Bump version to 0.4.0
2009-05-13 Dan Dennedy <dan@dennedy.org>
- * src/mlt++/configure: Bump soversion for mlt++ due to removal of classes.
-
* profiles/atsc_1080i_50, profiles/atsc_1080i_60, profiles/atsc_1080p_2398,
profiles/atsc_1080p_24, profiles/atsc_1080p_25, profiles/atsc_1080p_2997,
profiles/atsc_1080p_30, profiles/atsc_720p_30, profiles/dv_ntsc,
profiles/square_pal_wide, profiles/svcd_ntsc_wide, profiles/svcd_pal_wide:
Make profile descriptions more user friendly.
- * src/modules/avformat/producer_avformat.c: Improve reliability of video
- playback. After the v0.5 release of FFmpeg, a change was introduced that
- prevented reliable playback of some files, namely HDV. This fixes it by
- introducing a seek upon opening the file. Also, this change provides simple
- fallback support for when invalid DTS is returned by libavformat.
-
2009-05-11 Dan Dennedy <dan@dennedy.org>
* src/modules/gtk2/have_mmx.S, src/modules/gtk2/scale_line_22_yuv_mmx.S:
Apply patch from Orcan Ogetbil that adds .note.GNU-stack section.
- * setenv: Add libmlt++ to the ld path.
-
- * src/mlt++/configure: Make libmlt++ PIC.
-
2009-05-09 Dan Dennedy <dan@dennedy.org>
- * configure: Fix build on Mac OS X.
-
* ChangeLog, Makefile: Change dist make target to use git-archive.
* src/swig/configure, src/swig/java/Play.java, src/swig/java/build,
src/swig/ruby/play.rb, src/swig/ruby/thumbs.rb, src/swig/tcl/build,
src/swig/tcl/play.tcl: Fixup the swig bindings.
- * src/modules/xine/xineutils.h: Fix compilation warning in xineutils.h.
-
* configure, src/examples/Makefile, src/framework/Makefile,
src/framework/mlt_geometry.c, src/framework/mlt_producer.c,
src/mlt++/Makefile, src/mlt++/configure, src/modules/avformat/Makefile,
src/valerie/valerie_util.c, src/valerie/valerie_util.h: Remove files that no
longer belong.
-2009-05-07 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/configure: Update avformat configure script to deal
- with ffmpeg changes to swscale.
-
- * src/modules/sdl/consumer_sdl_still.c: Prevent potential divide-by-zero
- errors in sdl_still consumer.
-
- * src/modules/avformat/ffmpeg.patch: Remove ffmpeg.patch - no longer
- necessary.
-
- * Makefile: Fix uninstall of pkg-config files.
-
-2009-05-05 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: Improve seek performance with
- dnxhd and huffyuv codecs.
-
2009-05-03 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* configure, src/albino/Makefile, src/humperdink/Makefile,
mlt is not possible, because of the wrong linking of -lmlt while using
LDFLAGS=-L/usr/local/lib this patch fixes the issue using pkg-config"
-2009-04-30 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: improve
- audio synchronization after seek (including in point)
-
2009-04-18 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/resample/Makefile, src/modules/vorbis/Makefile: Apply patch
2009-04-16 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/jackrack/plugin_mgr.c: Add /usr/lib64 libdir to default LADSPA
- plugin path.
-
* configure, src/framework/mlt.h, src/modules/kino/configure: Use pkg-config
instead of lqt-config.
2009-04-15 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * Doxyfile: Update version in Doxygen.
-
* mlt++/ChangeLog, mlt++/Makefile: Add ChangeLog and remove svn log from dist
make target.
- * ChangeLog: update changelog
-
- * src/modules/avformat/configure: Fix build for --avformat-svn to use FFmpeg
- v0.5 and HEAD build to not use --enable-swscale.
-
* ChangeLog, Makefile: Update ChangeLog and remove svn log from the make
install target.
* NEWS, configure, src/framework/mlt.h, src/modules/avformat/configure: bump
to version 0.3.8
-2009-04-13 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/fezzik.ini: fezzik.ini: workaround scaling resolution
- limitation with swscale filter by making it the lowest priority
-
- * src/modules/kdenlive/producer_framebuffer.c: producer_framebuffer.c:
- interpret negative speed as reverse
-
2009-04-10 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/test/play.cpp, mlt++/test/server.cpp: cleanup some warnings
mlt++/src/MltTractor.cpp, mlt++/src/MltTransition.cpp: Fix up warnings about
explicit base initializers in copy constructors
- * mlt++/configure: Add more warnings
-
- * mlt++/.gitignore: Add a .gitignore file
-
-2009-04-09 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- building on some older versions.
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat: bugfix
- (kdenlive-677) to make interlaced coding automatic if profile is not
- progressive and coding not explicit by ildct and ilme properties.
-
2009-04-07 Ray Lehtiniemi <rayl@mail.com>
- * src/modules/kdenlive/filter_boxblur.c: Fix a 64-bit segfault in kdenlive
- To reproduce: - create a new project - create a color clip - add clip to
- timeline - set an in point on the clip - add the box blur effect The
- segfault happens because we take the negative of an unsigned integer. This
- works out to a signed 32 bit value on a 64 bit platform, which causes the rgb
- array bounds to be exceeded.
-
* src/framework/mlt_consumer.c, src/miracle/miracle_connection.c,
src/modules/kino/riff.cc: Fix up a few ignored return values
- * src/framework/mlt_pool.c: Fix warning: pointer of type ‘void *’ used in
- arithmetic
-
* src/modules/avformat/consumer_avformat.c,
src/modules/core/filter_watermark.c, src/modules/core/transition_composite.c,
src/modules/core/transition_region.c, src/modules/westley/producer_westley.c:
src/valerie/valerie_response.c, src/valerie/valerie_response.h: Constness
changes
- * .gitignore: Add a .gitignore file
-
-2009-04-05 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/westley/producer_westley.c: producer_westley.c: Don't prepend
- westley document root to empty properties
-
-2009-04-03 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_crop.c: filter_crop.c: bugfix chroma alignment
-
-2009-04-02 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * mlt++/swig/ruby/thumbs.rb: thumbs.rb: fix setting size property for
- avformat consumer
-
-2009-03-17 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/frei0r/factory.c: frei0r/factory.c: add /usr/lib64 to the
- default frei0r plugin path
-
-2009-03-15 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_composite.c: transition_composite.c: allow
- removing of luma file by passing an empty name
-
-2009-03-14 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_composite.c: transition_composite.c: make luma
- and luma_invert properties mutable
-
2009-03-10 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: add
- backwards compatibility macro for PIX_FMT_YUYV422
-
* src/modules/avformat/consumer_avformat.c,
src/modules/avformat/filter_avcolour_space.c,
src/modules/avformat/filter_avdeinterlace.c,
src/modules/avformat/filter_swscale.c: avformat: fix compilation due to
recent PIX_FMT changes in libavutil v50.
-2009-03-08 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kdenlive/producer_framebuffer.c: producer_framebuffer.c: Fix
- producer out position
-
-2009-03-06 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_log.h: mlt_log.h: add convenience macros
-
2009-03-03 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/kino/riff.cc: kino/riff.cc: suppress compiler warning
-
* src/modules/frei0r/factory.c, src/modules/frei0r/producer_frei0r.c:
frei0r/factory.c, producer_frei0r.c: suppress compiler warnings
- * src/framework/mlt_property.c: mlt_property.c: suppress compiler warning
-
-2009-02-24 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/producer_colour.c: producer_colour.c: improve previous
- patch
-
- * src/modules/core/producer_colour.c: producer_colour.c: bugfix reading color
- value after westley has prepended the document path to the resource property
-
2009-02-23 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/sdl/consumer_sdl.c, src/modules/sdl/consumer_sdl_preview.c,
* src/modules/vmfx/filter_chroma.c, src/modules/vmfx/filter_chroma_hold.c:
filter_chroma.c: update to use new property-based color value
- * src/modules/vmfx/filter_chroma_hold.c: filter_chroma_hold.c: update to use
- new property-based color value
-
- * src/modules/core/producer_colour.c: producer_colour.c: update to use new
- property-based color parsing.
-
- * src/framework/mlt_property.c: mlt_property.c: interpret hex int as unsigned
-
- * src/modules/frei0r/frei0r_helper.c: frei0r_helper.c: cleanup color parser
- to use new code in mlt_property.c
-
- * src/framework/mlt_property.c: mlt_property.c: added parsing for color
- values beginning with #
-
2009-02-20 blendamedt <blendamedt@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/frei0r/producer_frei0r.c: modules/frei0r: added missing
- producer_frei0r.c -This line, and those below, will be ignored-- A
- producer_frei0r.c
-
* src/modules/frei0r/Makefile, src/modules/frei0r/factory.c,
src/modules/frei0r/frei0r_helper.c: added frei0r producers (patch from jb)
thx to jb
2009-02-14 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/plus/filter_affine.c: filter_affine.c: remove silly default
- rotate animation for new kdenlive pan and zoom effect (kdenlive-565)
-
* src/modules/core/Makefile, src/modules/core/factory.c,
src/modules/core/filter_crop.c, src/modules/fezzik.ini: filter_crop.c: add
cropping filter (kdenlive-509)
- * configure: configure: relax optimization level slightly to improve debugger
- backtraces in bug reports
-
- * src/modules/plus/transition_affine.c: transition_affine.c: bugfix chroma
- alignment
-
-2009-02-13 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_brightness.c: filter_brightness.c: fix the
- wonkiness by filtering chroma as well.
-
2009-02-12 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* profiles/cif_15, profiles/qcif_15, profiles/quarter_15: profiles/*_15: add
some 15fps profiles
- * src/modules/qimage/configure: qimage/configure: let qimage first attempt to
- use Qt4 through pkg-config (canonical) without having to specify directories
- or QTDIR
-
- * src/modules/sox/configure: sox/configure: give pkg-config priority over
- libst-config
-
2009-02-10 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/qimage/configure: qimage/configure: fix build on OS X
-
- * src/modules/avformat/filter_avdeinterlace.c: filter_avdeinterlace.c: bugfix
- (kdenlive-672) deinterlace only works on left half of image
-
* src/modules/qimage/producer_qimage.c,
src/modules/qimage/qimage_wrapper.cpp, src/modules/qimage/qimage_wrapper.h:
producer_qimage.c, qimage_wrapper.{h,cpp}: enhance qimage producer to use the
new mlt_cache (kdenlive-575)
- * src/modules/gtk2/producer_pixbuf.c: producer_pixbuf.c: enhance pixbuf
- producer to use new mlt_cache (kdenlive-575)
-
* src/modules/avformat/consumer_avformat.c,
src/modules/avformat/producer_avformat.c,
src/modules/vorbis/producer_vorbis.c: producer_vorbis.c, producer_avformat.c,
mlt_factory.[hc], mlt.h: add mlt_cache and related service functions
(kdenlive-575)
- * Doxyfile: Doxyfile: set tab width to 4 spaces
-
- * src/framework/mlt_properties.c: mlt_properties.c: update doxygen comments
- for some out params
-
- * src/framework/mlt_property.c: mlt_property.c: update a doxygen comment to
- label param as out
-
2009-02-04 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/debian/changelog, mlt++/debian/control, mlt++/debian/copyright,
* configure, src/framework/mlt.h, src/modules/avformat/configure: bump to
version 0.3.6
- * NEWS: NEWS: add release notes for 0.3.6
-
-2009-02-01 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/frei0r/factory.c: frei0r/factory.c: add more default locations
- for locating plugins including one for MacPorts
-
-2009-01-30 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/inigo/inigo.c: inigo.c: make usage fit in 80 columns
-
-2009-01-29 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/filter_swscale.c: filter_swscale.c: Fix compilation
- (typo introduced in rev. 1330)
-
2009-01-29 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/fezzik/producer_fezzik.c: producer_fezzik.c: do not use the
- swscale filter on images wider than 2048 loaded by the sdl_image producer.
-
* src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/producer_qimage.c,
src/modules/sdl/producer_sdl_image.c: producer_pixbuf.c, producer_qimage.c,
producer_sdl_image.c: bugfix (kdenlive-575) large memory consumption loading
many pictures.
- * src/modules/avformat/filter_swscale.c: filter_swscale.c: throw assert if
- creation of swscale context fails.
-
- * src/modules/avformat/factory.c: avformat/factory.c: set ffmpeg logging to
- the same level as MLT's
-
-2009-01-27 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/gtk2/producer_pixbuf.c: producer_pixbuf.c: bugfix
- (kdenlive-575) memory leak
-
- * src/modules/gtk2/producer_pixbuf.c: producer_pixbuf.c: bugfix
- (kdenlive-575) memory leak
-
2009-01-26 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/swig/configure, mlt++/swig/php/build, mlt++/swig/php/play.php:
swig/configure, swig/php/*: add php bindings
-2009-01-24 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: add version
- check to use AVCodec->long_name
-
-2009-01-23 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl.c: consumer_sdl.c: bugfix segfault on
- unchecked pointer
-
- * src/modules/inigo/producer_inigo.c: producer_inigo.c: bugfix segfault on
- unchecked pointer
-
2009-01-21 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * docs/inigo.txt: inigo.txt: update usage info
-
- * docs/policies.txt: policies.txt: add instruction to update version in
- mlt.h\!
-
* src/framework/mlt.h, src/framework/mlt_consumer.c,
src/framework/mlt_consumer.h, src/framework/mlt_deque.c,
src/framework/mlt_deque.h, src/framework/mlt_events.c,
Update copyrights to 2009. Add cross references from files to data structures
in doxygen.
-2009-01-14 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/inigo/inigo.c: inigo/inigo.c: add -debug and -verbose options to turn
- on additional logging.
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: set consumer
- buffer prefill to 1 by default.
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: bugfix
- (kdenlive-450) bad timestamps in MPEG-2 Transport Stream and possibly quite a
- few other formats.
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: add support
- for an=1, vn=1, acodec=none, and vcodec=none options (kdenlive-533)
-
2009-01-13 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * docs/policies.txt: docs/policies.txt: Add policy about not using stdout,
- messages, and recommending the new log API.
-
* src/framework/Makefile, src/framework/mlt.h, src/framework/mlt_consumer.c,
src/framework/mlt_events.c, src/framework/mlt_log.c, src/framework/mlt_log.h,
src/framework/mlt_pool.c, src/framework/mlt_producer.c,
mlt_producer.c, mlt_pool.c, mlt_events.c, mlt_consumer.c, mlt.h, Makefile:
add logging system based on FFmpeg's.
- * configure: configure: separate -march (suitable on x86) and -mcpu (suitable
- on ppc, arm, and sparc)
-
2009-01-08 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * Doxyfile: Doxyfile: strip the path to the source files
-
- * src/modules/core/producer_consumer.c: producer_consumer.c: bugfix setting
- in point
-
* src/framework/mlt_frame.h, src/framework/mlt_multitrack.c,
src/framework/mlt_multitrack.h, src/framework/mlt_playlist.h,
src/framework/mlt_service.h, src/framework/mlt_tractor.c,
support special constructor argument values to list available demuxers and
decoders: f-list[[,]acodec-list][[,]vcodec-list]
- * src/inigo/inigo.c: inigo/inigo.c: fix the usage help within 80 characters
- wide.
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: report list
- of muxers when f=list and codecs when acodec=list or vcodec=list.
-
- * src/framework/mlt_repository.c: mlt_repository.c: report reason when dlopen
- fails.
-
2009-01-05 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_consumer.c, src/framework/mlt_consumer.h,
mlt_filter.[ch], mlt_transition.[ch], mlt_consumer.[ch]: improve doxygen for
filter, transition, and consumer
-2009-01-02 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/configure: avformat/configure: add -lbz2 automatically
- for --avformat-svn
-
2008-12-31 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* configure, src/modules/avformat/producer_avformat.c: producer_avformat.c:
fix build on older versions of ffmpeg; whitespace cleanup by eclipse.
-2008-12-30 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * Doxyfile: Doxyfile: bump version
-
2008-12-29 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* NEWS, configure: NEWS, configure: set version to 0.3.4 and add release
notes
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: further
- analysis and testing reveals the DV encoder does not need the special aspect
- ratio overrides. It expects a generic input. Only the DV decoder produces the
- special, proper aspect ratios for which MLT is not yet prepared.
-
2008-12-28 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/swig/java/build, mlt++/swig/python/build, mlt++/swig/python/play.py,
__stack_chk_fail_local. swig/python/play.py: fix syntax error reported by
Jonathon Thomas.
-2008-12-28 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sox/filter_sox.c: filter_sox.c: fix crash when trying to create
- a sox filter with wrong name
-
-2008-12-28 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/configure: avformat/configure: update the recommended
- ffmpeg revision
-
* src/modules/avformat/producer_avformat.c,
src/modules/core/filter_rescale.c, src/modules/core/producer_consumer.c,
src/modules/dv/producer_libdv.c: filter_rescale.c, producer_avformat.c,
producer_libdv.c, producer_consumer.c: coerce a deinterlace when scaling an
- interlaced source.
-
-2008-12-27 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * mlt-config-template: mlt-config-template: send deprecation warning to
- stderr to prevent breaking legacy scripts and makefiles
-
- * mlt++/swig/configure: swig/configure: use pkg-config mlt-framework instead
- of deprecated mlt-config.
-
- * src/modules/core/filter_luma.c: filter_luma.c: prevent the first
- application of the nested luma transition from being applied to a test card
- image. This makes slideshows start without a transition at the beginning,
- which is nicer and more expected.
-
- * src/modules/core/transition_luma.c: transition_luma.c: bugfix
- (kdenlive-496) floating point exception when a slideshow using filter luma is
- added to a multitrack.
+ interlaced source.
2008-12-26 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/westley/producer_westley.c: producer_westley.c: silence
- compilation warning on uninitialized variable.
-
* src/modules/avformat/consumer_avformat.c,
src/modules/avformat/producer_avformat.c: producer_avformat.c,
consumer_avformat.c: use av_set_string3 where available (gets rid of
deprecation warning).
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: bugfix
- rendering to widescreen PAL DV.
-
2008-12-22 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/vorbis/producer_vorbis.c: producer_vorbis.c: add meta.media.
- properties.
-
- * src/modules/dv/producer_libdv.c: producer_libdv.c: add meta.media.
- properties.
-
- * src/modules/avformat/Makefile: avformat/Makefile: suppress error on
- uninstall target
-
* src/modules/avformat/Makefile, src/modules/avformat/configure,
src/modules/avformat/factory.c: avformat/configure, avformat/Makfile,
avformat/factory.c: Add a --avformat-no-filters configure option to
filename for a no-codecs build to libmltffmpeg.so to prevent a clash with a
no-filters module (libmltavformat.so).
-2008-12-21 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: add a bunch
- of metadata about the media under the properties key prefix "meta.media."
-
-2008-12-21 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/producer_sdl_image.c: producer_sdl_image.c: Fix crash when
- attempting to play a folder without images
-
2008-12-20 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sdl/consumer_sdl.c: consumer_sdl.c: let it work without
- filter_avcolour_space
-
- * src/modules/core/producer_consumer.c: producer_consumer.c: use parent
- profile if none specified; accept real_time properties from parent producer.
-
- * src/modules/core/producer_consumer.c: producer_consumer.c: set our length
- from the length of the nested producer so we can terminate at the end of
- rendering.
-
- * src/framework/mlt_properties.c: mlt_properties.c: fix some documentation
-
* src/modules/core/Makefile, src/modules/core/factory.c,
src/modules/core/producer_consumer.c: core/Makefile, core/factory.c,
core/producer_consumer.c: add new producer_consumer that will consume from an
encapsulated producer under a different profile that the parent producer
(kdenlive-323).
- * src/modules/core/transition_region.c: transition_region.c: bugfix
- regression with in built circle region
-
- * src/modules/avformat/filter_swscale.c: avformat/filter_swscale.c: add
- support for scaling the alpha channel (needs further testing)
-
* src/modules/avformat/Makefile, src/modules/avformat/factory.c,
src/modules/avformat/filter_swscale.c, src/modules/fezzik.ini:
avformat/Makefile, avformat/factory.c, avformat/filter_swscale.c: add new
image scaler using FFmpeg libswcale. fezzik.ini: add swscale at higher
priority than gtk2/rescale.
-2008-12-19 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/fezzik.dict: fezzik.dict: let qimage be a producer for svg
-
2008-12-18 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/Makefile, src/modules/avformat/configure,
people who want to make a version entirely without including FFmpeg's codecs,
which present patent royalty licensing issues.
- * src/modules/avformat/configure: avformat/configure: checkout
- (--avformat-svn) or recommend (--help) a specific FFmpeg revision if this is
- a release version of MLT (last field of version is even).
-
- * configure: configure: --disable-mmx implies --disable-sse
-
* src/modules/avformat/Makefile, src/modules/avformat/factory.c,
src/modules/avformat/filter_avdeinterlace.c: avformat/Makefile,
avformat/factory.c, avformat/filter_avdeinterlace.c: Fix and enable the
avdeinterlace filter for a non-MMX configuration.
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: add support
- for AVOptions as properties.
-
2008-12-16 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_events.c, src/framework/mlt_field.c,
mlt_playlist.h, mlt_field.h, mlt_playlist.c, mlt_tractor.c, mlt_events.c: add
doxygen docs for events, field, and playlist.
-2008-12-14 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- (kdenlive-432) segfault when reusing previous AVFrame (paused or idling on
- last frame) but the previos AVFrame was invalid (not got_picture before
- erroring out).
-
2008-12-12 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/motion_est/filter_motion_est.c: motion_est/filter_motion_est.c:
- the sse compilation flag logic was inverted
-
* src/modules/gtk2/Makefile, src/modules/gtk2/pixops.c: gtk2/pixops.c,
gtk2/Makefile: prevent MMX on all x86_64, not just OS X
- * configure: configure: add make flag and define for ARCH_X86_64 for all OSes
-
- * configure: configure: fix mmx/sse detection on OS X and add detection of
- x86_64 to define ARCH_X86_64
-
* src/modules/xine/Makefile, src/modules/xine/configure,
src/modules/xine/deinterlace.c, src/modules/xine/xineutils.h: xine/Makefile,
xine/xineutils.h, xine/deinterlace.c: respect mmx compilation flag instead of
using own detection xine/configure: remove, no longer necessary
- * src/modules/motion_est/filter_motion_est.c: filtedr_motion_est.c: respect
- new --disable-sse configure flag and whitespace cleanup
-
* src/modules/gtk2/Makefile, src/modules/gtk2/configure,
src/modules/gtk2/pixops.c: gtk2/Makefile, gtk2/configure, gtk2/pixops.c:
disable MMX parts on OS X - does not build
- * src/modules/kino/configure: kino/configure: automatically disable on OS X -
- does not build due to missing headers
-
- * configure: configure: add --disable-sse and add mmx/sse detection for OS X
-
2008-12-04 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/README: README: update instructions to use pkg-config instead of
- mlt-config
-
* mlt++/swig/java/build, mlt++/swig/perl/Makefile.PL,
mlt++/swig/python/build, mlt++/swig/ruby/build, mlt++/swig/tcl/build,
mlt++/test/Makefile: test/Makefile, swig/*/build: replace more mlt-config
with pkg-config
- * profiles/atsc_1080i_50: profiles/atsc_1080i_50: added new profile for
- square pixel 1080i at a PAL-like rate
-
- * Doxyfile: Doxyfile: add doxygen config file
-
- * src/valerie/valerie_status.h: valerie_status.h: take stdio.h header from
- system include path
-
- * docs/install.txt: docs/install.txt: fix license info on humperdink and
- valerie
-
- * configure: configure: bump the version
-
* src/framework/mlt_consumer.c, src/framework/mlt_consumer.h,
src/framework/mlt_deque.c, src/framework/mlt_deque.h,
src/framework/mlt_events.c, src/framework/mlt_events.h,
producer_sdl_image.c: bugfix (kdenlive-422) not validating input file for
image producers.
- * src/modules/inigo/producer_inigo.c: producer_inigo.c: display a warning
- when failed to load a file.
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: clean up the
- dual pass log at the end of the second pass.
-
2008-11-25 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix r1242
- segfault due to improper audio decoder memory allocation. Also fix logical
- bug with resampling on channels > 2
-
* src/modules/avformat/audioconvert.h,
src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
(kdenlive-297) audio distortion with audio formats other than signed 16-bit.
-2008-11-24 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/fezzik.dict: fezzik.dict: added support for .tif equivalent to
- .tiff
-
-2008-11-17 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/albino/albino.c: albino.c: fix playout with SDL on Mac OS X
-
- * src/modules/sox/filter_sox.c: filter_sox.c: bugfix (2263114) build on sox
- 14.2.0.
-
-2008-11-13 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kdenlive/filter_freeze.c: filter_freeze.c: fix detection of
- current frame position in a playlist
-
-2008-11-13 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- (kdenlive-347) segfault when resolution is not known until after first frame
- is decoded. Also, bugfix segfault when video_index or audio_index are -1
- (invalid).
-
-2008-11-13 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kdenlive/filter_freeze.c: filter_freeze.c: update frozen frame
- if freeze position is changed on the fly
-
2008-11-13 blendamedt <blendamedt@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/oldfilm/filter_vignette.c,
* NEWS, configure: configure, NEWS: bump to version 0.3.2 and update release
notes
-2008-11-09 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/plus/filter_affine.c: filter_affine.c: bugfix (kdenlive-235)
- rendering when used inside a multitrack.
-
2008-11-08 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * profiles/hdv_720_50p: profiles/hdv_720_50p: fix frame rate in description
-
* profiles/atsc_1080p_2398, profiles/atsc_1080p_24, profiles/atsc_1080p_25,
profiles/atsc_1080p_2997, profiles/atsc_1080p_30, profiles/hdv_1080_25p,
profiles/hdv_1080_30p, profiles/hdv_720_50p, profiles/hdv_720_60p:
profiles/hdv_*, profiles/atsc_*: added more HD progressive mode profiles
- * src/modules/oldfilm/filter_dust.yml: filter_dust.yml: apply description fix
- patch from Mads Dydensborg.
-
- * src/modules/kdenlive/producer_framebuffer.c: producer_framebuffer.c: bugfix
- segfault in construction with null argument.
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- detection of aspect ratio for DV AVI (applies to raw and quicktime files as
- well).
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: rework the
- aspect ratio detection to try to fetch it from the codec and/or the stream in
- newer versions of ffmpeg. This fixes aspect handling for raw DV but still not
- yet for DV AVIs without the vprp chunk.
-
-2008-11-07 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/frei0r/factory.c: frei0r/factory.c: fix build on BSD
-
- * src/modules/core/transition_mix.c: transition_mix.c: prevent serializing
- previous_mix and reset previous_mix on seeking.
-
- * src/modules/normalize/filter_volume.c: filter_volume.c: prevent serializing
- previous_gain and reset previous_gain on seeking.
-
-2008-11-06 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * docs/services.txt: services.txt: minor corrections to documentation for
- producer_avformat
-
- * mlt++/src/Makefile: src/Makefile: suppress warning on ldconfig failure
-
2008-11-05 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/kdenlive/Makefile, src/modules/kdenlive/factory.c,
src/modules/oldfilm/filter_vignette.yml: oldfilm/filter_vignette*: filter is
now usable with keyframes
- * src/modules/frei0r/factory.c: frei0r/factory.c: set min/max values in
- metadata to defined min/max from frei0r.h
-
- * src/modules/frei0r/frei0r_helper.c: frei0r/frei0r_helper.c: frei0r double
- and bool params are now useable with keyframes (mlt_geometry)
-
- * src/modules/frei0r/factory.c: frei0r/factory.c: yml files can be used now
- for critical plugins
-
-2008-10-30 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * profiles/Makefile: profiles/Makefile: fix removal of turd (*~) files on
- install.
-
- * docs/TODO: docs/TODO: refer to wiki page
-
- * Makefile: Makefile: suppress warning on ldconfig failure.
-
2008-10-29 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/albino/albino.c, src/inigo/inigo.c: albino.c, inigo.c: disable realtime
scheduling (kdenlive-180).
-2008-10-27 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: Fix crash /
- corruption when changing audio or video index
-
-2008-10-27 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: optimize
- slightly the stream index bugfix and update the video informational
- properties on the producer when the video index changes.
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- regression with audio_index and video_index in last release when I added the
- feature to close file on init with re-open on first use. Also, added some
- exception handling around index values.
-
- * src/modules/vmfx/filter_mono.c: filter_mono.c: cleanup code to made it more
- consistent between cases (use_alpha).
-
- * src/modules/vmfx/filter_mono.c: filter_mono.c: bugfix (kdenlive-234)
- threshold filter inverting image and add invert property to revert to old
- behavior.
-
2008-10-25 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/configure: configure: apply patch from Alberto Villa to fix build on
- FreeBSD
-
* configure, src/modules/kino/endian_types.h, src/modules/kino/riff.cc,
src/modules/sox/configure: configure, kino/enadian_types.h, kino/riff.c,
sox/configure: apply patch from Alberto Villa to fix build on FreeBSD and to
fix a sh expression bug in sox/configure.
-2008-10-24 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kdenlive/producer_framebuffer.c: producer_framebuffer.c:
- improve delimiter parsing to allow '?' in filename argument
-
- * mlt-config-template: mlt-config-template: add deprecation warning
-
- * src/modules/sox/filter_sox.c: filter_sox.c: bugfix recent build regression
- on older versions of sox
-
2008-10-23 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/inigo/inigo.c: inigo.c: improve the usage help and add -silent and
- -progress options
-
- * src/modules/inigo/producer_inigo.c: producer_inigo.c: bugfix (2164436)
- processing unknown command line options causes infinite loop
-
* src/inigo/Makefile, src/inigo/inigo.c: inigo.c: added -version option
- * src/modules/sox/filter_sox.c: filter_sox.c: bugfix (2040035) segfault with
- libsox 14.1.0
-
- * configure: configure: -O3 is the maximum optimization level, not -O4
-
-2008-10-21 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: fix
- deprecated warning on av_set_string
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: fix build on
- older libavformat versions
-
-2008-10-20 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix Ogg
- Vorbis files and possibly others that report invalid pts on some packets
-
- * mlt++/configure: configure: convert to use pkg-config; mlt-config is
- deprecated
-
- * src/modules/xine/configure: xine/configure: disable module on ppc64
-
- * src/modules/xine/configure: xine/configure: disable module on ppc64
-
-2008-10-08 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: Fix crash
- introduced by FFmpeg revision 15367 (check that muxer and encoder have same
- aspect ratio)
-
-2008-10-02 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- reading file over http.
-
2008-09-22 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/gtk2/producer_pixbuf.c, src/modules/qimage/qimage_wrapper.cpp:
producer_pixbuf.c, qimage_wrapper.c: Add "force_reload" option to force image
reloading in the image producers
-2008-09-12 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: bugfix
- (2106941) compilation against recent ffmpeg changes
-
-2008-09-07 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kino/filehandler.cc: modules/kino/filehandler.cc: compilation
- fix
-
2008-08-26 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/sox/configure, src/modules/sox/filter_sox.c: sox/configure,
2008-08-06 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/AUTHORS: update mlt++ AUTHORS
-
- * mlt++/Makefile: fix make dist target
-
- * configure: bump versions for 0.3.0 release
-
- * mlt++/configure: bump versions for 0.3.0 release
-
- * Makefile: improve make dist target
-
- * mlt++/Makefile: improve make dist target
-
- * AUTHORS: add AUTHORS file
-
- * NEWS: Add release notes file
-
* mlt++/swig/java/Play.java, mlt++/swig/java/Play.sh, mlt++/swig/java/build:
swig/java: fixup the java bindings build script and example (bug 1523941)
- * demo/mlt_news: demo/mlt_news: small typo
-
-2008-08-05 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kdenlive/producer_framebuffer.c:
- kdenlive/producer_framebuffer.c: keep resource file in producer and use '?'
- instead of ':' to separate filename from speed, because it caused some
- problems with other MLT functions
-
-2008-08-03 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_playlist.c: framework/mlt_playlist.c: check length before
- inserting blank, which fixes one frame blanks that were sometimes inserted
- where not needed.
-
-2008-07-31 blendamedt <blendamedt@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/frei0r/factory.c: frei0r/factory.c: use float values for
- "double vars" in frei0r
-
-2008-07-28 blendamedt <blendamedt@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/frei0r/configure: frei0r/configure: removed unneeded newlines
-
-2008-07-27 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kdenlive/producer_framebuffer.c: producer_framebuffer.c: Fix
- aspect ratio with slowmotion producer
-
-2008-07-24 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/qimage/configure: qimage/configure: Fix Qt3 detection and
- compilation
-
2008-07-22 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/qimage/producer_qimage.c,
qimage module: add mutex, fix caching and use alpha only if necessary (mostly
borrowed from producer_pixbuf)
-2008-07-14 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/qimage/configure: qimage/configure: Fix Qt4 detection
-
-2008-07-13 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: bugfix
- recent regression with setting aspect ratio. Now it takes it from the profile
- by default using the quotient properties for best accuracy. Now, one can also
- override the aspect ratio using the same property name as the ffmpeg command
- line utility ("aspect") for even greater symmetry.
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- segfault when fail to open or read file in init.
-
2008-07-10 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/qimage/configure, src/modules/qimage/producer_qimage.c,
qimage module: add support for Qt4 (you can force compile against Qt3 with
--force-qt3)
-2008-07-09 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/vorbis/producer_vorbis.c: producer_vorbis.c: bugfix regression
- with introduction of mlt_profile causing length of vorbis producer to always
- yield zero.
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- regression playing audio-only files.
-
2008-07-01 blendamedt <blendamedt@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/oldfilm/filter_vignette.c,
service closure truly thread-safe. As it was, reference count increment and
decrement operations were not atomic and not protected comprehensively.
- * src/framework/mlt_consumer.c: mlt_consumer.c: added ability to set priority
- of the read-ahead thread through a new "priority" property. This only works
- if you have permission; fails to execute properly otherwise - not sure how to
- make it fail over gracefully. Do not set this property if you do not have
- permission.
-
2008-06-26 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/src/MltProducer.cpp, mlt++/src/MltProducer.h, mlt++/swig/mltpp.i:
MltProducer.{h,cpp}, mltpp.i: remove Producer::get_frame that is unncessary
and introduced a memory leak.
-2008-06-25 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_field.c: mlt_field.c: correctly reconnect transitions
- after a service disconnect
-
- * src/framework/mlt_service.c: mlt_service.c: fix bad identification for some
- services (eg. transitions)
-
-2008-06-25 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- segfault up the call stack when no image could be decoded for a frame by
- producing the "test card" image.
-
-2008-06-24 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * mlt++/src/MltPlaylist.cpp: MltPlaylist.cpp: return null on clip_info method
- if mlt_playlist_get_clip_info fails.
-
- * src/framework/mlt_playlist.c: mlt_playlist.c: return error on
- mlt_playlist_get_clip_info if producer is null.
-
-2008-06-23 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/fezzik/producer_fezzik.c: producer_fezzik.c: let other services
- prevent Fezzik from attaching filters by passing the "fezzik_normalised"
- property.
-
- * src/framework/mlt_repository.c: mlt_repository.c: bugfix memory leak on
- getting directory list of MLT_REPOSITORY.
-
-2008-06-22 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_consumer.c: mlt_consumer.c: make the realtime
- frame-dropping heuristic based on actual frame rate instead of 25fps
-
-2008-06-17 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- segfault in unprotected libavcodec call that is clearly marked not thread
- safe!
-
-2008-06-15 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_composite.c: transition_composite.c: slightly
- more accurate positioning when using crop panning and horizontal position is
- adjusted to align chroma channels.
-
-2008-06-10 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: close the
- file at the end of object creation, then re-open the file on-demand. This
- presented a file descriptor limit issue when loading very large playlists.
-
-2008-06-08 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * mlt++/src/MltPlaylist.cpp: MltPlaylist.cpp: prevent strdup from crashing on
- a null pointer.
-
- * src/framework/mlt_playlist.c: mlt_playlist.c: remove some unncessary and
- inefficient accounting code.
-
-2008-06-06 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_composite.c: transition_composite.c: add repeat
- processing to crop property.
-
- * src/modules/core/transition_composite.c: transition_composite.c: add
- animatable geometry "pan" property. This suppresses implicit scaling of the
- b-frame and makes the compositing rectangle crop. Then, it uses the x and y
- geometry information to pan the b-frame within the composite rectangle. For
- example, a negative x pans the image to the left and that portion of the b
- frame left of the composite rectangle is cropped. w and h of the pan geometry
- is not implemented at this time, but the plan is to implement scaling of the
- b-frame. In the end, this can provide a Ken Burns effect for still images - a
- much requested feature.
-
-2008-06-04 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: remove
- multi-threaded audio decoding option. It does not provide any advantage at
- this time and just wastes resources.
-
- * src/framework/mlt_playlist.c: mlt_playlist.c: added an "autoclose" property
- for sequential processing of very large playlists. If set, it automatically
- closes previous producers to reduce resources (file handles and threads if
- using producer_avformat with threads).
-
2008-06-01 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/gtk2/producer_pango.c: producer_pango.c: make the size property
- an absolute height in pixels for greater compositing and quality control.
-
* src/modules/core/filter_resize.c, src/modules/core/transition_composite.c:
filter_resize,c, filter_composite.c: bugfix redundant rounding.
- * src/modules/core/filter_watermark.c: filter_watermark.c: bugfix propogation
- of output_ratio as a double - was causing incorrect calculations in
- transition_composite.c with non-square-pixel watermark sources.
-
- * src/framework/mlt_properties.c: mlt_properties.c: make arithmetic processor
- use floating point instead of integer so that '/' is meaningful. I am not
- totally certain of the consequences of this change because I am not aware of
- where the feature is used. However, I am using it to specify the aspect ratio
- of certain things like bitmap graphics that were not designed for square
- pixels. And being able to specify a fraction allows for accurate detection of
- equivalent aspect ratios between different sources, particularly compositing.
-
- * src/framework/mlt_profile.c: mlt_profile.c: make fallback default sample
- aspect ratio the same as the revised profile's sample aspect ratio
-
-2008-05-25 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/gtk2/producer_pixbuf.c: producer_pixbuf.c: apply the in point
- to the position in the image sequence
-
2008-05-15 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/avformat/configure: avformat/configure: fix compilation against
- shared ffmpeg for a headers configuration that has appeared.
-
* profiles/dv_ntsc, profiles/dv_ntsc_wide, profiles/dv_pal,
profiles/dv_pal_wide, src/modules/avformat/consumer_avformat.c,
src/modules/avformat/producer_avformat.c: profiles/dv_*, consumer_avformat.c,
other ITU-R 601-based video sources such as MPEG-2 for DVD Video and
broadcast.
-2008-05-12 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_luma.c: Correctly update the luma file if the
- resource was modified
-
2008-05-12 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/configure, src/modules/avformat/consumer_avformat.c:
2008-05-09 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/core/filter_resize.c: filter_resize.c: fix field order
- correction
-
- * src/modules/xine/configure: xine/configure: relax restrictions to let
- OSX/Intel use xine deinterlace
-
* src/framework/mlt_field.c, src/framework/mlt_field.h: mlt_field.[hc]: added
mlt_field_disconnect_service
src/modules/dgraft/filter_telecide.c: modules/dgraft: added module for ports
of Donald Graft's GPL filters.
- * src/modules/sox/configure: sox/configure: make inclusion of libsfx dynamic
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- reporting of top_field_first on frame.
-
* src/modules/avformat/Makefile, src/modules/avformat/configure:
avformat/Makefile, configure: fix --avformat-swscale and the removal of the
ffmpeg 'lib' make target.
- * src/modules/core/filter_data_show.c: filter_data_show.c: bugfix
- interpreting timecode, due to invalid fps on mlt_profiles API changes
-
2008-04-23 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/src/MltProducer.cpp, mlt++/src/MltProducer.h, mlt++/swig/mltpp.i:
2008-04-12 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/test/server.cpp: test/server.cpp: bugfix (1940389) compilation on gcc
- 4.3
-
- * src/modules/lumas/create_lumas: lumas/create_lumas: bugfix (1940387)
- bash-ism in script
-
* configure, src/modules/motion_est/configure: configure,
motion_est/configure: remove module-specific crud from top-level configure
script, and enable motion_est now by default.
src/modules/kino/kino_wrapper.cc: kino/kino_wrapper.cc, kino/filehandler.cc,
kino/avi.cc: bugfix (1936991) compilation with gcc 4.3.
-2008-04-11 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/gtk2/producer_pixbuf.c: producer_pixbuf.c: bugfix image
- sequences
-
2008-03-22 blendamedt <blendamedt@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/frei0r/frei0r_helper.c, src/modules/frei0r/transition_frei0r.c:
frei0r/{frei0r_helper,transition_frei0r}.c: fixed wrong scaling and memory
leak
-2008-03-18 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/configure: avformat/configure: improve chances of
- successful linking with -svn and -static options
-
2008-03-07 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/kino/riff.cc: kino/riff.c: fix failure to dlopen due to symbol
- signature mismatch on make_fourcc
-
* src/modules/frei0r/configure, src/modules/frei0r/factory.c:
frei0r/configure: use CFLAGS so I can tell the test where to find frei0r.h
frei0r/factory.c: add metadata_schema value to metadata
- * src/framework/mlt_repository.c: mlt_repository.c: clear up warning due to
- const return from getenv_locale()
-
2008-03-06 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/framework/mlt_repository.c: mlt_repository.c: fix to previous string
- const fix in mlt_repository_languages
-
- * src/framework/mlt_repository.c: mlt_repository.[hc]: fix modifying const
- string in mlt_repository_languages
-
* src/framework/mlt_repository.c, src/framework/mlt_repository.h:
mlt_repository.[hc]: add mlt_repository_languages helper function for
localizing metadata
-2008-03-05 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/valerie/Makefile: src/valerie/Makefile: fix overwriting libmlt.0.dylib
- on libvalerie install on OS X
-
- * src/modules/sox/configure: sox/configure: add OS X and Debian (future?)
- pkg-config support to sox configuration
-
2008-03-04 blendamedt <blendamedt@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/frei0r/factory.c: src/modules/frei0r/factory.c: load metadata
- on request (thx for patch from Dan Dennedy) added "tags" metadata with type
- "Video" for frei0r plugins
-
- * src/modules/frei0r/factory.c: modules/frei0r/factory.c: also register
- transitions, added "tags" to metadata
-
- * src/modules/oldfilm/filter_vignette.c: oldfilm/filter_vignette.c: speedup
-
* src/modules/oldfilm/fdust.svg, src/modules/oldfilm/filter_dust.yml,
src/modules/oldfilm/filter_grain.yml, src/modules/oldfilm/filter_lines.yml,
src/modules/oldfilm/filter_oldfilm.yml,
metaschema.yaml, producer_avformat.yml: reset schema_version to 0.1 since we
have not release anything yet with schema let alone metadata
- * src/modules/frei0r/factory.c: frei0r/factory.c: apply destructors and
- serialiser to metadata mlt_properties
-
- * src/inigo/inigo.c: inigo.c: fix querying on specific filter or transition
-
-2008-03-03 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_resize.c: filter_rescale.c: if input width or
- height are zero, infer them from the profile
-
2008-02-28 blendamedt <blendamedt@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/frei0r/configure: test not only if header frei0r.h exists, also
- use an item
-
* src/modules/frei0r/Makefile, src/modules/frei0r/configure,
src/modules/frei0r/factory.c, src/modules/frei0r/filter_frei0r.c,
src/modules/frei0r/frei0r_helper.c, src/modules/frei0r/frei0r_helper.h,
MltRepository.{h,cpp}: update to latest mlt_repository.h change -
finalization of callback declarations and metadata handling
- * src/modules/avformat/configure: avformat/Makefile: compilation fix for
- latest FFmpeg update
-
2008-02-26 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/inigo/inigo.c: inigo.c: add -query option to inigo for service and
- metadata lookup.
-
* src/modules/avformat/Makefile, src/modules/avformat/factory.c,
src/modules/avformat/producer_avformat.yml: avformat/factory.c,
producer_avformat.yml, avformat/Makefile: add metadata for producer:avformat.
2008-02-24 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sox/Makefile: sox/Makefile: helpful note for Ubuntu (and
- Debian?)
-
* src/modules/avformat/Makefile, src/modules/avformat/configure:
avformat/configure, avformat/Makefile: add libavdevice for newer versions of
ffmpeg when using --avformat-svn or --avformat-static
- * src/framework/mlt_repository.c: mlt_repository.c: throw warning on failure
- to load module
-
2008-02-16 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/swig/python/build: swig/python/build: add -fPIC
-
* mlt++/src/MltRepository.cpp, mlt++/src/MltRepository.h, mlt++/swig/mltpp.i:
MltRepository.{h,cpp}, swig/mltpp.i: added consumers, filters, producers,
transitions, register_metadata, and metadata methods to Repository class
mlt_repository_filters, mlt_repository_producers, mlt_repository_transitions,
mlt_repository_register_metadata, and mlt_repository_metadata
-2008-02-13 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/configure: avformat/configure: use pkg-config with
- --avformat-shared
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: - Convert to
- ffmpeg and AVOptions exclusively. This makes ALL AVOptions as seen from
- \'ffmpeg -h\' available to MLT. Instead of ffmpeg\'s \'-option value\' use
- inigo\'s property syntax \'option=value\" - Add dual pass encoding. - Use
- multi-threading even with non-threaded codecs by separating producer and
- consumer threads. - Whitespace cleanup.
-
- * src/framework/mlt_consumer.c: mlt_consumer.c: let consumers use read-ahead
- processing thread without frame dropping with real_time=-1
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: cleanup
- whitespace
-
-2008-02-12 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * mlt++/Makefile: do not make tests automatically
-
2008-02-11 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/consumer_avformat.c,
producer_avformat.c: add FFmpeg multi-thread support via "threads" property
or MLT_AVFORMAT_THREADS environment variable
-2008-02-08 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/dv/producer_libdv.c: producer_libdv.c: fix test for framerate
- matching profile
-
2008-02-07 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/configure, mlt++/src/Makefile: configure: add soversion variable
interface version (soversion) mlt.h: add version info to header so apps can
have build time adaptations
- * mlt++/swig/ruby/thumbs.rb: thumbs.rb: fix error on Playlist.append due to
- args not int
-
* mlt++/src/Makefile, mlt++/src/Mlt.h, mlt++/src/MltFactory.cpp,
mlt++/src/MltFactory.h, mlt++/src/MltRepository.cpp,
mlt++/src/MltRepository.h, mlt++/swig/mltpp.i: Mlt.h, MltFactory.{h,cpp},
2008-02-04 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/COPYING: add COPYING to disclose license
-
- * src/framework/config.h: remove config.h
-
* Makefile, setenv, src/framework/Makefile, src/framework/mlt_consumer.c,
src/framework/mlt_factory.c, src/framework/mlt_filter.c,
src/framework/mlt_frame.c, src/framework/mlt_multitrack.c,
Since nearly every file was touched, remove superfluous headers and prepare
for coming mlt_repository change.
-2008-01-20 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: bugfix
- (kdenlive-28) a/v sync on non-whole frame rate.
-
-2008-01-11 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: do not free
- AVPacket if av_read_frame fails.
-
2008-01-08 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/oldfilm/Makefile, src/modules/oldfilm/configure,
src/modules/oldfilm/filter_oldfilm.h: src/modules/oldfilm/*: add oldfilm
module contributed by Marco Gittler
- * docs/services.txt: minor typo fix
-
- * src/framework/mlt_playlist.c: mlt_playlist.c: fix some blank-handling bugs
- in mlt_playlist_insert_at()
-
-2007-12-18 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/fezzik.dict: fezzik.dict: prioritize avformat over vorbis
- module for .ogg, at least until better track type detection is in place.
-
-2007-12-12 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: make
- compilation fix on url_fclose version sensitive to support older ffmpeg
-
-2007-12-08 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * .../motion_est/filter_autotrack_rectangle.c: Autotrack rectangle can now be
- defined using geometry="x,y:wxh" instead of having to pass it in the filter
- name
-
2007-12-08 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/configure, src/modules/sox/configure: sox/configure:
producer_westley.c: remove statefulness of frame rate through framework and
modules, and allow consumer properties to override profile settings.
- * src/modules/sdl/producer_sdl_image.c: producer_sdl_image.c: fix compilation
- warning with respect to const pointer
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: fix pointer
- passed to url_fclose()
-
- * src/modules/kino/riff.h: kino/riff.h: fix compiler warnings on missing
- const for char*
-
2007-11-09 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/sox/Makefile, src/modules/sox/configure,
gtk2/producer_pango.c, gtk2/pixops.c, miracle_server.c, miracle_unit.c:
cleanup a whole bunch of compiler warnings
- * src/modules/jackrack/configure: jackrack/configure: add detection for
- ladspa and disable if not detected
-
- * src/modules/core/filter_luma.c: filter_luma.c: bugfix testing b_frame's
- dimensions
-
- * src/modules/core/filter_resize.c: filter_resize.c: bugfix overriding
- top_field_first property
-
* src/modules/motion_est/filter_motion_est.c,
src/modules/motion_est/filter_vismv.c: filter_vismv.c: bugfix pointer to
array of motion vectors
- * src/modules/avformat/configure: avformat/configure: fix detect shared
- install of libavformat due to link to versioned .so.
-
2007-10-13 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_factory.c, src/framework/mlt_profile.c: mlt_profile.c,
* setenv, src/framework/mlt_profile.c: mlt_profle.c: add support for
MLT_PROFILES_DIR environment variable
- * src/modules/sdl/consumer_sdl.c: consumer_sdl.c: fix specifying window size
- on constructor arg
-
* src/modules/effectv/utils.c, src/modules/effectv/utils.h: effectv/utils.*:
fix compilation on OS X
-2007-08-04 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl_still.c: consumer_sdl_still.c: bugfix segfault
-
-2007-08-03 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl_still.c: consumer_sdl_still.c: bugfix
- initialisation of window dimensions due to recent profiles addition
-
2007-07-30 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* configure, docs/policies.txt: configure: fix broken variables in pkg-config
files policies.txt: add bug reporting procedure
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: align some
- defaults with ffmpeg for more reliable output
-
2007-07-29 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_consumer.c, src/framework/mlt_profile.c: mlt_profile.c:
2007-07-20 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * profiles/Makefile: profiles/Makefile: cleanup profiles dir on (un)install
-
* profiles/atsc_1080i_60, profiles/atsc_720p_30, profiles/atsc_wide_1080i,
profiles/atsc_wide_720p: profiles/atsc_*: rename and change descriptions
* profiles/hdv_720_50p, profiles/hdv_720_60i, profiles/hdv_720_ntsc,
profiles/hdv_720_pal:
- * src/framework/mlt_profile.c: mlt_profile.c: revise substrings for legacy
- setting of MLT_NORMALISATION
-
* profiles/atsc_wide_1080i, profiles/atsc_wide_720p, profiles/cif_ntsc,
profiles/cif_pal, profiles/cvd_ntsc, profiles/cvd_pal, profiles/dv_ntsc,
profiles/dv_ntsc_wide, profiles/dv_pal, profiles/dv_pal_wide,
src/modules/avformat/producer_avformat.c: consumer_avformat.c: save disabled,
experimental flushing code
-2007-07-07 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/qimage/configure: Fix build based on patch from Ryan Hodge
-
-2007-07-01 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/fezzik.dict, src/modules/qimage/Makefile,
- src/modules/qimage/configure, src/modules/qimage/producer_qimage.c,
- src/modules/qimage/qimage_wrapper.cpp, src/modules/qimage/qimage_wrapper.h:
- Add support for psd, xcf and exr images (KDE libraries needed for these
- formats). Make pcx and tiff images load correctly
-
- * src/modules/gtk2/producer_pixbuf.c: Fix for rgba images (based on the code
- from qimage_producer)
-
- * src/modules/kdenlive/producer_framebuffer.c: Fix get image for formats
- different from yuv422
-
-2007-07-01 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: improve
- frame accuracy
-
-2007-06-30 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kdenlive/producer_framebuffer.c: Better fix for aspect_ratio
- problem in framebuffer producer
-
- * src/modules/kdenlive/producer_framebuffer.c: Fix aspect ratio for
- slowmotion / freeze effect
+2007-07-01 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/kdenlive/configure: Fix typo which prevented wave filter to be
- available
+ * src/modules/fezzik.dict, src/modules/qimage/Makefile,
+ src/modules/qimage/configure, src/modules/qimage/producer_qimage.c,
+ src/modules/qimage/qimage_wrapper.cpp, src/modules/qimage/qimage_wrapper.h:
+ Add support for psd, xcf and exr images (KDE libraries needed for these
+ formats). Make pcx and tiff images load correctly
2007-06-29 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * demo/circle.png: demo/circle.png: fix broken image
-
- * demo/watermark1.png: watermark1.png: fix broken image
-
* demo/mlt_title_over_gfx, demo/mlt_titleshadow_watermark,
demo/mlt_voiceover: demo/mlt_title_over_gfx, demo/mlt_titleshadow_watermark,
demo/mlt_voiceover: fix broken demos due to recent hidden track handling
change in mlt_transition.c
-2007-06-28 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: consumer_avformat.c: bugfix
- initial buffer size to prevent high quantization at beginning
-
-2007-06-26 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix audio
- sync with some codecs and revert unnecessary precautions that introduce
- inefficiency
-
2007-06-12 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/Makefile: added dist make targets
-
- * Makefile: added dist make targets
-
* mlt++/Makefile, mlt++/src/Makefile, mlt++/test/Makefile: added uninstall
make targets
src/modules/effectv/utils.c, src/modules/effectv/utils.h: added effectv
module with BurningTV filter provided by Stephane Fillod
- * src/framework/mlt_frame.c: mlt_frame.c: let image conversions accept NULL
- for the alpha parameter
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: bugfix
- segfault when paused after seeking but no picture available to duplicate
-
* docs/westley.txt, src/modules/fezzik.dict: fezzik.dict: prioritize avformat
higher than libdv for better quality
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: make better
- test for existence for avcodec_decode_audio2
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: fix setting
- int property as double
-
- * src/modules/avformat/producer_avformat.c: producer_avformat.c: - remove
- seeking immediately after opening file improves compatibility (in particular,
- ogg theora) - use non-deprecated avcodec_decode_audio2 if available - changes
- to adhere to warnings on ffmpeg decode api docs ought to improve stability
- and compatibility
-
- * src/modules/avformat/consumer_avformat.c: added support for ilme=1 and
- ildct=1 properties to consumer_avformat
-
2007-06-09 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/avformat/configure: --avformat-swscale with --avformat-svn is
- only permitted with --enable-gpl
-
* src/modules/avformat/Makefile, src/modules/avformat/configure: change
--avformat-svn configure option to do a static build of ffmpeg libs only and
statically link to mlt module. Also, make --avformat-svn aware of
--avformat-swscale and --enable-gpl
-2007-06-04 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_rescale.c: bugfix core/filter_rescale segfault on
- scaling alpha that was already to correct scale (e.g. mlt_bouncy_ball)
-
-2007-06-01 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_rescale.c: bugfix segfault in core/filter_rescale
- scaling alpha already scaled in gtk2/filter_rescale
-
- * src/framework/mlt_tractor.c: bugfix tractor not propogating resize_alpha
- frame property
-
- * src/framework/mlt_transition.c: bugfix transition processing hidden track
-
-2007-05-31 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kdenlive/producer_framebuffer.c: Fix framebuffer crash & clip
- duration error
-
2007-05-25 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/dv/consumer_libdv.c: per jb's suggestion, enable
- terminate_on_pause by default
-
* demo/README, demo/mlt_attributes, demo/mlt_intro, demo/mlt_jcut,
demo/mlt_lcut, docs/inigo.txt: fix some demos broken by old changes
-2007-05-24 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_data_show.c: fix dynamic attribute value parsing
- and memory management in data_show
-
2007-05-23 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_factory.c, src/framework/mlt_producer.c,
src/modules/fezzik.ini: the framework may not depend upon specific
modules--data_feed/show in this case
- * src/modules/core/filter_rescale.c: Only scale the alpha when also scaling
- the image.
-
2007-04-10 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/kdenlive/filter_wave.c: compilation fix
-
- * src/modules/avformat/configure: fix compilation without swscale
-
* ChangeLog, docs/policies.txt, src/modules/core/Makefile,
src/modules/core/configure, src/modules/core/factory.c,
src/modules/core/filter_boxblur.c, src/modules/core/filter_boxblur.h,
Cleanup copyrights and attributions, and move Jean-Baptiste's services to a
new kdenlive module.
-2007-03-31 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/producer_framebuffer.c: Fixed crash in slowmotion producer
-
-
2007-03-31 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* ChangeLog, src/modules/sox/filter_sox.c: add sox 13.0.0 support
-2007-03-31 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/producer_framebuffer.c: Fix slowmotion producer (no more
- variable speed, but at least it works now).
-
2007-03-30 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
* ChangeLog, src/modules/core/filter_boxblur.c,
* demo/README, demo/consumers.ini: change default dv1394 device file
- * configure: remove bashisms
-
-2007-03-02 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl_preview.c: Allow user to choose video driver
- and output display
-
2007-02-19 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/core/filter_boxblur.c, src/modules/core/filter_boxblur.h,
src/modules/core/filter_boxblur.h, src/modules/core/filter_wave.c,
src/modules/core/filter_wave.h: Add blur and wave filters from Leny Grisel
-2007-02-01 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl_preview.c: Allow user to set alsa device
-
-2007-01-23 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_data_show.c: Allow display of metadata and timecode
-
-
-2007-01-22 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: Write metadata if there is any
-
-2007-01-19 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_frame.c: Fix my terribly broken YUV to RGB conversion
-
-2007-01-13 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl_preview.c: Allow changing volume in
- sdl_preview consumer
-
-2007-01-02 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: Change default value for
- libavformat's qscale, preventing some crashes
-
2006-12-31 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/producer_avformat.c,
producers, using basic structure like:
meta.attr.metadata_name.markup=metadata_value
- * src/modules/vorbis/producer_vorbis.c: Vorbis should set correct values in
- frame for audio channels and frequency.
-
2006-12-08 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* ChangeLog, configure, src/framework/mlt_consumer.h,
configure run with bash since it uses bash-specific features. Also, patches
headers to comments for pedantic compilation.
-2006-11-20 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/producer_framebuffer.c: remove debug msg
-
2006-11-18 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/core/producer_framebuffer.c,
src/modules/core/producer_framebuffer.h: New framebuffer producer. Provides
slowmotion, reverse playing and stroboscope effect
-2006-11-05 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/fezzik.dict: Kdenlive project files are now westley compatible
-
- * src/modules/core/transition_luma.c: Luma get_image produces yuv only, so
- announce it. Fix problem when requesting rgb image of a luma transition.
-
-2006-10-26 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_rescale.c: Fix rescaling of rgb images when not
- using gtk2
-
-2006-10-16 j-b-m <j-b-m@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_obscure.c: Position for the effect was not
- calculated right if the clip was in the middle of a playlist
-
-2006-10-06 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: + General improved media support
-
-2006-10-03 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: + Correction to previous patch -
- fixes pause behaviour with rawvideo
-
- * src/modules/avformat/producer_avformat.c: + Corrections for uncompressed
- video sources
-
2006-09-28 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * ChangeLog: Following Dan's example. Applied an amd64 compilation patch to
- motion_est module and patch to correctly initialize audio frequency and
- channels.
-
* src/modules/avformat/producer_avformat.c, src/modules/dv/producer_libdv.c:
Patch supplied by Jean-Baptiste.
2006-08-14 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/vmfx/filter_mono.h: + Header file for mono filter
-
* src/modules/vmfx/Makefile, src/modules/vmfx/configure,
src/modules/vmfx/factory.c, src/modules/vmfx/filter_mono.c: + A mono filter
for mask generation (not v. useful)
* src/modules/vmfx/filter_chroma.c, src/modules/vmfx/filter_chroma_hold.c: +
Correction to uneven chroma samples
- * src/modules/qimage/qimage_wrapper.cpp: + Image caching for the qimage
- producer
-
- * src/modules/gtk2/producer_pixbuf.c: + Image caching for the gtk2 pixbuf
- producer
-
-2006-08-09 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * ChangeLog: *** empty log message ***
-
- * src/modules/westley/producer_westley.c: enhance producer_westley to parse
- Kino 0.9.1 SMIL (clock) time values.
-
- * ChangeLog: *** empty log message ***
-
- * src/modules/avformat/configure: convert --avformat-cvs to svn and rename
- option as --avformat-svn (--avformat-cvs is an undocumented alias).
-
-2006-05-27 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * configure: bump version
-
-2006-05-24 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/qimage/producer_qimage.c: apply patch from Jean-Baptiste
- <jb@ader.ch> to add rgb24a support to producer_qimage
-
2006-05-22 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/core/transition_composite.c: apply patch from Jean Baptiste
- <jb@ader.ch> to fix fill-type rescaling when aspect ratio is equal to
- normalised ratio
-
* src/framework/mlt_frame.c, src/framework/mlt_frame.h,
src/modules/gtk2/producer_pixbuf.c: apply patch from Jean Baptiste to add
rgb24a support to producer_pixbuf
-2006-05-20 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/qimage/configure: let QTDIR also define location of qt include
- dir
-
- * src/modules/kino/filehandler.cc: fix compilation on latest version of
- libquicktime (0.9.8)
-
-2006-05-04 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/filter_avcolour_space.c: + Big endian patch courtesy
- of Goncalo Carvalho (glslang at gmail dot com) - specifically, corrects
- colour space conversions on the Intel Mac
-
-2006-04-20 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_resize.c: + Field order control reworked
- (meta.top_field_first has priority over source)
-
-2006-04-12 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_resize.c: + Top field first correction (original
- approach would not have worked [mea culpa], and this is only a partial
- solution since the consumers have no say in field order)
-
- * src/modules/qimage/qimage_wrapper.cpp: + Fix for byte order as spotted by
- Goncalo Carvhalo (many thanks :-))
-
- * src/modules/core/filter_resize.c: + Meta override for field order
- misreporting/errors in encoders
-
2006-03-29 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/qimage/Makefile, src/modules/qimage/configure,
src/modules/qimage/qimage_wrapper.cpp, src/modules/qimage/qimage_wrapper.h: +
QImage module added - default is still GTK2 when available
- * src/modules/gtk2/producer_pixbuf.c: + Bug Fix: Removes a memory leak on
- last alpha channel
-
* src/framework/mlt_frame.c, src/framework/mlt_frame.h: + Preparation for a
QT image loader (to allow optional and functionally equivalent qt or gtk2
usage for image loading)
2006-03-28 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/gtk2/producer_pixbuf.c: + Usage of mlt_properties_dir_list
-
* src/framework/mlt_properties.c, src/framework/mlt_properties.h: + Adds a
utility function for listing files in a directory (aids with cross platform
support)
-2006-03-20 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * mlt++/src/MltFactory.h: + Fix for swig parsing
-
2006-03-02 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* docs/services.txt, src/framework/mlt_manager.h, src/modules/core/Makefile,
src/modules/core/filter_mono.c, src/modules/core/filter_mono.h: added mono
audio filter
- * src/modules/kino/Makefile: libquicktime prefers pkg-config now and latest
- lqt-config is broken with respect to --cflags
-
- * configure: log configuration history to config.log
-
2006-02-23 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/src/Makefile: + Install of config.h for linux and os/x usage
-
- * mlt++/src/config.h: + Added the config.h for win32
-
* mlt++/mlt++.sln, mlt++/mlt++.vcproj, mlt++/src/Mlt.h,
mlt++/src/MltConsumer.h, mlt++/src/MltDeque.h, mlt++/src/MltEvent.h,
mlt++/src/MltFactory.cpp, mlt++/src/MltFactory.h, mlt++/src/MltField.h,
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
- * src/modules/vmfx/filter_shape.c: + Activates the mixdown in the combine to
- allow audio sync'd with wipe (smooth ramping not implemented yet)
-
- * src/modules/core/transition_mix.c: + Alternative mixing mechanism
- introduced (specify a property of combine=1 on the mix transition to
- activate)
-
* src/framework/mlt_frame.c, src/framework/mlt_frame.h: + Alternative between
track mixing mechanism (using a low pass filter)
* docs/dvcp.txt, docs/inigo.txt: minor fixes
- * src/miracle/miracle_commands.c: add proper response to uadd command
-
2006-01-08 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/Makefile: fix compilation error
-
- * src/modules/dv/producer_libdv.c: Make libdv producer return some image even
- if unable to handle specific image type request.
-
- * Makefile: dist-clean target is more familiar - alias it
-
* src/modules/feeds/NTSC/data_fx.properties,
src/modules/feeds/NTSC/obscure.properties: fix comment/docu typo
* mlt++/Makefile, mlt++/configure: + Correction to a typo
- * src/modules/avformat/Makefile: + Uses libdir in private build of ffmpeg too
-
-
- * src/modules/avformat/configure: + 64 bit fix for ffmpeg built externally
- (should switch to pkg-config here)
-
- * mlt++/swig/perl/Makefile.PL: + Perl compilation patch submitted by Torsten
- Spindler
-
* mlt++/configure, mlt++/src/Makefile: + Added a --libdir switch to the
configure and build and fixed test case compilation
- * configure: - Removed a diagnostic
-
* Makefile, configure, src/framework/Makefile, src/miracle/Makefile,
src/valerie/Makefile: + Added a --libdir switch to the configure and build
-2005-11-22 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * mlt++/configure: + Allow LDFLAGS to be inherited from the environment
-
-2005-11-21 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * mlt++/src/Makefile: + Creates the lib directory on an install
-
-2005-11-17 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_composite.c: + Correction to alpha mask
- generation
-
2005-11-10 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/Makefile, mlt++/src/Makefile: + DESTDIR patch from Anthony Green
src/modules/avformat/producer_avformat.c: Allows aac output, corrects ntsc
sample collection, and picks up known info streams
-2005-10-28 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/motion_est/filter_crop_detect.c: Correct bug introduced by
- revision 1.3
-
- * src/modules/motion_est/filter_motion_est.c: x86 doesn't play well with ppc
-
- * src/modules/motion_est/Makefile: Fix shared lib flags in Makefile for
- Darwin
-
2005-10-25 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/motion_est/configure: + Enabled Zach's new slowmotion producer
-
* src/modules/core/consumer_null.c,
.../motion_est/filter_autotrack_rectangle.c, src/modules/sdl/consumer_sdl.c:
src/modules/core/consumer_null.c src/modules/sdl/consumer_sdl.c + Terminate
2005-10-24 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/motion_est/README: Added a producer slowmotion example.
-
* src/modules/motion_est/Makefile, src/modules/motion_est/factory.c,
src/modules/motion_est/filter_motion_est.c,
src/modules/motion_est/filter_motion_est.h,
slow motion producer. It provides basic slow motion through frame repeats and
a more advanced interpolation.
-2005-10-15 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/vmfx/filter_shape.c: + Correction for non-zero in point on the
- associated cut
-
-2005-10-14 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/gtk2/producer_pango.c: + Moved ~ to LF hack to pango processing
-
-
- * src/modules/sdl/consumer_sdl_still.c: + Rounding errors corrected for last
- gasp scaling
-
-2005-10-13 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl.c: + Deadlock resolution
-
2005-10-10 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_frame.c, src/framework/mlt_tractor.c,
src/modules/core/transition_luma.c: + Added an option to override alignment
and transparent borders for compositing
-2005-10-07 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/vmfx/filter_shape.c: + Corrections, optimisations and a hack
- for loading lumas from the mlt luma collection
-
2005-10-03 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/sdl/configure, src/modules/sdl/factory.c: + Correction for
uninstalled sdl image lib
- * configure: + OS/X Tiger patch
-
* mlt++/src/MltProperties.cpp, mlt++/src/MltProperties.h: OS/X gcc/g++ 4.x
fix
mlt++/src/MltProperties.h, mlt++/test/Makefile: + Whoops - had forgotten
these OS/X patches...
- * src/modules/sdl/producer_sdl_image.c: + Surface conversion
-
- * src/modules/sdl/producer_sdl_image.h: + Added producer_sdl_image as an
- alternative image and image sequence producer
-
* src/modules/fezzik.dict, src/modules/sdl/Makefile,
src/modules/sdl/configure, src/modules/sdl/factory.c,
src/modules/sdl/producer_sdl_image.c: + Added producer_sdl_image as an
alternative image and image sequence producer
-2005-10-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_composite.c: + Clean ups and corrections
-
-2005-09-29 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * mlt++/src/MltPushConsumer.cpp: + Oops - fix for memory leak
-
- * src/modules/avformat/filter_avcolour_space.c: + Extracts alpha from rgb24a
- images
-
2005-09-28 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/src/Makefile, mlt++/src/Mlt.h, mlt++/src/MltPushConsumer.cpp,
src/modules/feeds/PAL/etv.properties + Temporary work around to keep
composites correct
-2005-09-27 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: + Correction and a minor
- optimisation
-
- * src/modules/gtk2/producer_pixbuf.c: + Changed incorrect global variable to
- static
-
- * src/modules/avformat/consumer_avformat.c:
- src/modules/avformat/consumer_avformat.c + User specified pixel format
- property (pix_fmt) + Corrections to aspect ratio + Alpha channel added to
- RGBA32 conversions - Removed an historical/erroneous attempt to hack aspect
- ratio
-
2005-09-23 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/westley/producer_westley.c: + Indicator for missing media
- replacement in case pango doesn't exist
-
- * src/modules/plus/filter_charcoal.c: + Bounds checking on chroma samples
-
* src/modules/avformat/filter_avcolour_space.c,
src/modules/avformat/filter_avdeinterlace.c,
src/modules/avformat/producer_avformat.c: filter_avcolour_space.c +
producer_avformat.c + Corrections for uneven width + Corrections for state
propogation of top field first and interlaced state
- * src/modules/xine/filter_deinterlace.c: + Correction for cases where the
- interlaced state is determined after the image is rendered
-
2005-09-15 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_frame.c, src/framework/mlt_frame.h,
src/modules/sdl/consumer_sdl_still.c + Application provided preview support
added
-2005-09-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/plus/filter_invert.c: + Small mod to allow better use of invert
- as a gui item selector (alpha property)
-
2005-09-01 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/sdl/consumer_sdl.c, src/modules/sdl/consumer_sdl_still.c:
2005-08-29 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/inigo/inigo.c: + Keyboard handling events on Darwin
-
* src/modules/lumas/Makefile, src/modules/sdl/consumer_sdl.c: lumas/Makefile
+ Correction for non-gui app build on darwin lumas/luma.c + Handle sdl
events sdl/consumer_sdl.c + Audio on Darwin
src/modules/sdl/consumer_sdl_preview.c src/modules/sdl/consumer_sdl_still.c +
Corrections to preview mode switching
- * src/modules/sdl/consumer_sdl_preview.c:
- src/modules/sdl/consumer_sdl_preview.c + Temporary rollback for linux
-
* configure, src/modules/avformat/Makefile, src/modules/avformat/configure,
src/modules/sdl/consumer_sdl.c, src/modules/sdl/consumer_sdl_preview.c,
src/modules/sdl/consumer_sdl_still.c: configure + Correction to ldflags for
src/modules/sdl/consumer_sdl_still.c + Moved initialisation of sdl components
to the start/stop methods (Darwin requirement)
- * src/modules/motion_est/configure: + Correction to the disabled case (should
- be disable-motion_est and plugins should not be registered)
-
2005-08-28 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/vmfx/Makefile, src/modules/vmfx/configure,
alternative wipe mechanism + New producer (pgm) which provides basic
functionality for portable grey maps
- * src/modules/core/transition_composite.c: + SMP fix - geometry modifications
- need explicit locking
-
-2005-08-22 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_properties.h: + Replaced this with self in new pass
- functions for C++ compilation
-
2005-08-21 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_properties.c, src/framework/mlt_properties.h,
2005-08-19 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/framework/mlt_tractor.c: + Attempt to ensure that the aspect ratio of
- the background is the reported ar of the output frame
-
- * src/modules/core/transition_composite.c: + Yet another aspect ratio
- correction for the filter transition (not 100% correct yet...) + Correction
- for aspect_ratio == 0 case (should honour consumer)
-
- * src/modules/avformat/consumer_avformat.c: + Correction for aspect ratio
-
* src/modules/gtk2/producer_pango.c, src/modules/gtk2/producer_pixbuf.c:
producer_pango.c producer_pixbuf.c + More efficient use of pixbuf objects and
sequences/mlt pango lists
2005-08-15 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/westley/consumer_westley.c: Fix build errors caused by the
- (hypothetical) conversion of mlt_position from an int to a float, preserving
- original behavior.
-
* src/framework/mlt_frame.c, src/framework/mlt_playlist.c,
src/framework/mlt_playlist.h, src/framework/mlt_producer.c,
src/framework/mlt_property.c, src/framework/mlt_types.h: Fix build errors
Fix build errors caused by the (hypothetical) conversion of mlt_position from
an int to a float, preserving original behavior.
-2005-08-07 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/motion_est/filter_vismv.c: Misc changes. May remove this file
- completely soon.
-
- * src/modules/motion_est/filter_motion_est.c: This is a significant rewrite.
- -Cleared up as many conceptualy sticky points as possible. -Removed chroma
- comparison code pending a better rewrite. -Added show_residual=1 and
- show_reconstruction=1 debug modes. See README. -Renamed many variables and
- functions. -Revamped geometry handling. -Lots more I'm forgeting.
-
- * src/modules/motion_est/README: Added some more examples.
-
- * src/inigo/inigo.c: Prevent a frame from being skipped when inigo is first
- paused.
-
- * src/modules/motion_est/filter_crop_detect.c: Corrected geometry handling.
- Removed redundant arrow drawing code. Modified thresholding.
-
2005-08-04 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/Makefile, src/modules/avformat/configure: ffmpeg split
function, enabled by default; the results seem very good. Removed some unused
development code.
-2005-07-28 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kino/Makefile: + Allow header dependency checks
-
- * src/modules/avformat/configure: + Added an additional help message (for
- ffmpeg suffix)
-
- * Makefile: + Force dependency checks on header files
-
-2005-07-27 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_types.h: Do not break ABI to workaround a problem in
- swig.
-
-2005-07-27 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kino/producer_kino.c: + Stores the resource correctly (to allow
- serialisation via westley)
-
-2005-07-26 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_types.h: Add names to enums to make newer versions of
- swig (noticed on 1.3.24) happy.
-
2005-07-26 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/core/filter_watermark.c: + Correction to long outstanding
- oddity regarding composite.out - not needed in many cases now
-
* mlt++/swig/Makefile, mlt++/swig/configure, mlt++/swig/perl/Makefile.PL,
mlt++/swig/python/build, mlt++/swig/tcl/build: + Cleaned up swig build so it
doesn't require an mlt++ install first - Temporarily disabled java
2005-07-25 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/kino/riff.cc: + Minor correction for entry length being less
- than the data length
-
* src/modules/kino/avi.cc, src/modules/kino/avi.h, src/modules/kino/riff.cc,
src/modules/kino/riff.h: + fixes for opendml dv avi
-2005-07-23 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl.c: - Removed 'resize' property logic and
- width/height confusion
-
- * src/modules/core/filter_resize.c: + Correction for rounding errors
-
2005-07-21 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/dv/producer_libdv.c: - Removed unused aspect ratio property
-
- * src/modules/avformat/producer_avformat.c: + Hide internal properties via
- the _ convention
-
* src/framework/mlt_playlist.c, src/framework/mlt_service.c: - Remove
warnings
-2005-07-21 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/motion_est/filter_motion_est.c: autotrack_rectangle and
- motion_est now convert pixel units to macroblock (whole) units the same way.
-
- * .../motion_est/filter_autotrack_rectangle.c: Fixed several accuracy issues.
- Cleaned up code. Corrected pause behavior.
-
-2005-07-20 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * .../motion_est/filter_autotrack_rectangle.c: use shared arrow drawing code.
- improve tracking accuracy.
-
2005-07-20 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_filter.c, src/framework/mlt_service.c: mlt_filter.c
2005-07-19 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/gtk2/producer_pango.c: producer_pango.c + Correction of
- oversight - allow serialisation of mpl usage
-
* src/modules/avformat/consumer_avformat.c,
src/modules/avformat/producer_avformat.c: consumer_avformat.c
producer_avformat.c + Sync with current ffmpeg CVS - PLEASE UPDATE FFMPEG
2005-07-18 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/gtk2/producer_pango.c: + Mutex protection (temporary work
- around of SMP systems) + Corrected aspect ratio (should be 1, not 0)
-
- * src/modules/core/producer_colour.c: + Accepts modifiable colour property
- (via resource) + Hides non-public properties
-
- * src/modules/fezzik.dict: + Added convenience lookup for MLT Pango List
- files
-
- * src/modules/core/filter_mirror.c: + Alpha handling in silly filter :-)
-
- * src/modules/core/transition_composite.c: + Inherits deinterlace method from
- the consumer + Sanity check on scaled size for compositing
-
* src/modules/gtk2/producer_pango.c, src/modules/gtk2/producer_pixbuf.c:
producer_pango.c + Added cloning + Added the very silly .mpl (MLT Pango List)
format [details to follow] + Corrected invalid content producer_pixbuf.c +
Corrected invalid content
- * src/modules/gtk2/producer_pixbuf.c: + Bug fixes to test card handling +
- Alpha channel cloning + Minor tidy up
-
2005-07-16 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_frame.c, src/framework/mlt_playlist.c,
clean up to follow) src/modules/dv/producer_libdv.c + Frame stored width and
height are no longer assumed to be 'safe' here (investigating)
-2005-07-13 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_repository.c: mlt_repository.c + VERY temporary hack to
- avoid global symbol clashes (RTLD_GLOBAL needed by kino/libquicktime only so
- far)
-
-2005-07-12 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kino/filehandler.cc: filehandler.cc + FOURCC for DVCPRO
- quicktime
-
- * src/modules/vorbis/producer_vorbis.c: producer_vorbis.c + Oops - the frame
- position is relative to the in point (the internal position is absolute)
-
- * src/modules/vorbis/producer_vorbis.c: producer_vorbis.c + Fix for non-zero
- in point
-
2005-07-10 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/sdl/consumer_sdl_preview.c,
src/modules/sdl/consumer_sdl_still.c: consumer_sdl_preview.c
consumer_sdl_still.c + Fixes a deadlock condition
- * src/modules/kino/filehandler.cc: src/modules/kino/filehandler.cc + Added
- missing fourccs to allow compilation
-
* src/framework/mlt_frame.c, src/framework/mlt_frame.h,
src/framework/mlt_repository.c, src/modules/kino/filehandler.cc,
src/modules/kino/filehandler.h: framework/mlt_frame.c framework/mlt_frame.h +
2005-07-09 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/motion_est/configure: Mention that motion est is disabled by
- default during ./configure.
-
* configure, src/modules/motion_est/configure: Prevent motion estimation
components from building unless requested.
src/modules/motion_est/filter_vismv.c, src/modules/motion_est/sad_sse.h:
Initial import of the motion estimation filter.
-2005-07-07 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c:
- src/modules/avformat/consumer_avformat.c + Correction for mpeg encoding -
- Removal of erroneous frame rate checks
-
2005-07-05 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/westley/producer_westley.c:
- src/modules/westley/producer_westley.c - Rollback on erroneous checkin
- (functionality covered correctly in playlist)
-
* src/framework/mlt_frame.c, src/framework/mlt_playlist.c,
src/modules/core/transition_composite.c, src/modules/core/transition_luma.c,
src/modules/fezzik.dict, src/modules/gtk2/producer_pixbuf.c,
frame rendering notification event test/server.cpp + Added an example frame
rendering callback that removes all shotcut related fx
- * src/modules/sdl/consumer_sdl.c: src/modules/sdl/consumer_sdl.c + (Re)Added
- audio volume control
-
- * src/framework/mlt_tractor.c: src/framework/mlt_tractor.c + Added support
- for pango usage on audio only fx cuts (sigh...)
-
- * src/framework/mlt_tractor.c: src/framework/mlt_tractor.c + Slight
- modification to allow pango use in fx cuts
-
2005-06-26 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/core/filter_transition.c, src/modules/core/filter_transition.h:
example of how to hide a track on reception swig/ruby/thumbs.rb + Changed
generator to run, rather than sleep and poll
- * src/modules/core/transition_composite.c: + Cleaned up compositing and alpha
- usage (all frames always have an alpha mask) + Provided an alternative
- rendering mechanism ('or' which takes a and b alpha into account) + Provided
- a and b alpha mask overides ('alpha_a' and 'alpha_b')
-
2005-06-24 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_geometry.c, src/framework/mlt_tractor.c,
to avoid rounding errors?) src/framework/mlt_tractor.c + corrections for
fx_cuts (allows animated fx)
-2005-06-23 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/fezzik.dict: + BGa's request for additional westley extensions
-
2005-06-22 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_frame.h, src/framework/mlt_tractor.c,
src/modules/sdl/consumer_sdl_preview.c src/modules/sdl/consumer_sdl_still.c +
Takes consumer profile into account
-2005-06-05 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/configure: Quick temporary fix for mlt config in non-standard
- paths (relates to mlt++)
-
2005-06-04 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_consumer.c, src/framework/mlt_tractor.c,
src/modules/core/filter_resize.c, src/modules/xine/filter_deinterlace.c:
Sanity checks for normalising filters
-2005-06-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/fezzik.dict: libdv/avformat switching
-
-2005-06-01 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/filter_avcolour_space.c: Sanity checks
-
- * src/modules/gtk2/producer_pixbuf.c: Fallback to testcard
-
2005-05-28 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/avformat/consumer_avformat.c: NTSC fix
-
- * src/modules/fezzik.dict: Added bmp support
-
* src/framework/mlt_consumer.c, src/framework/mlt_factory.c,
src/framework/mlt_producer.c: Frame rate properites and factory
initialisation
-2005-05-27 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: audio out fix
-
2005-05-24 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/kino/filehandler.cc, src/modules/kino/filehandler.h: DVCPRO fix
-2005-05-23 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/consumer_avformat.c: jpeg and mjpeg fixes
-
-2005-05-11 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/jackrack/filter_ladspa.c: bugfix segfault on closre when filter
- never invoked
-
2005-05-09 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/Makefile, src/modules/avformat/configure,
src/modules/westley/configure, src/modules/xine/configure: Bourne shell
compliance
- * configure: Bourne shell compliance
-
* src/modules/avformat/Makefile, src/modules/avformat/configure: Corrections
to --avformat-cvs option
src/modules/avformat/producer_avformat.c: FFMPEG revisions to match current
CVS (part 1)
-2005-05-04 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/kino/Makefile: fix compilation
-
2005-04-22 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* docs/services.txt, src/modules/configure, src/modules/jackrack/Makefile,
src/modules/jackrack/ui.h: cleanup and reduce code in jackrack support code
and add new jack-less filter_ladspa.
-2005-04-19 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/dv/producer_libdv.c: Fix for file identification and dv
-
2005-04-15 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/kino/avi.h: Minor correction
-
* src/modules/kino/Makefile, src/modules/kino/avi.cc, src/modules/kino/avi.h,
src/modules/kino/configure, src/modules/kino/endian_types.h,
src/modules/kino/error.cc, src/modules/kino/error.h,
* src/modules/dv/producer_libdv.c, src/modules/fezzik.dict: Preparation for
kino support
-2005-04-14 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/dv/Makefile: corrected pkg-config libdv usage
-
2005-04-14 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/sdl/Makefile, src/modules/sdl/consumer_sdl_still.c: Build
fixes.
- * src/modules/sdl/consumer_sdl.c: An unfinished attempt at porting the SDL
- consumer to OS X. What remains is a bug in libSDL where the SDL screen object
- becomes a NULL pointer when it shouldn't. This also affects 'ffplay' and the
- SDL test program 'threadwin -threaded' I think.
-
- * src/modules/sdl/consumer_sdl_osx_hack.h: A hack to inform Cocoa that is
- should be multithreaded by spinning of a dummy thread.
-
* configure, src/albino/albino.c, src/inigo/inigo.c, src/miracle/miracle.c:
OS X uses -DDARWIN in
/System/Library/Frameworks/CoreFoundation.framework/Headers/CFBase.h; This in
combination with #include <Foundation/Foundation.h> caused compilation errors
while porting consumer_sdl to OS X.
-2005-04-13 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * COPYING: License update
-
- * src/modules/sox/Makefile, src/modules/sox/configure: Disable sox when
- unavailable
-
- * src/modules/jackrack/configure: Disable jackrack when unavailable
-
- * src/modules/dv/configure, src/modules/vorbis/configure: Disable libdv when
- unavailable
-
- * src/modules/resample/configure: Disable libsamplerate when unavailable
-
- * src/modules/sdl/configure: Disable sdl when unavailable
-
- * src/modules/vorbis/configure: Disable vorbis when unavailable
-
- * configure: Automatic disabling off mmx on a OS/X; mmx detection on Linux;
- other platforms probably broken
+2005-04-13 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/xine/configure: Disable xine when mmx not available
+ * src/modules/sox/Makefile, src/modules/sox/configure: Disable sox when
+ unavailable
- * src/modules/westley/configure: Conditional compilation of westley/libxml2
- components
+ * src/modules/dv/configure, src/modules/vorbis/configure: Disable libdv when
+ unavailable
* src/modules/gtk2/Makefile, src/modules/gtk2/configure,
src/modules/gtk2/factory.c: Conditional compilation of gtk2 components
-2005-04-12 dezeroex <dezeroex@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_geometry.c: Minor but confusing comment fix.
-
2005-04-12 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* configure, setenv, src/albino/Makefile, src/albino/albino.c,
src/modules/xine/configure, src/tests/Makefile, src/valerie/Makefile,
src/valerie/valerie_socket.c: OS/X Patch from Torsten Spindler
- * mlt++/CUSTOMISING: Minor doc updates
-
* src/framework/mlt_factory.c, src/framework/mlt_factory.h,
src/framework/mlt_repository.c, src/framework/mlt_repository.h: More const
usage
* src/miracle/miracle_unit.c, src/modules/avformat/consumer_avformat.c: Minor
mods to playout via avformat and miracle unit generation on an xfer
- * src/modules/westley/producer_westley.c: Reinstatement of entity handling
- and removal of libxml2 warning for non-existent file
-
2005-02-18 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_frame.c, src/modules/core/producer_colour.c,
src/modules/plus/transition_affine.c: Minor corrections with alpha and
affines
-2005-02-13 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/miracle/miracle_unit.c: Smoother unit load
-
2005-02-12 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/src/MltService.cpp: Minor correction
-
* src/framework/mlt_producer.c, src/framework/mlt_tractor.c,
src/modules/core/producer_colour.c, src/modules/core/transition_composite.c,
src/modules/feeds/PAL/etv.properties, src/modules/gtk2/producer_pango.c,
2005-02-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/plus/transition_affine.c: affine silliness
-
* src/framework/mlt_consumer.c, src/framework/mlt_consumer.h,
src/framework/mlt_frame.c, src/framework/mlt_tractor.c,
src/modules/sdl/consumer_sdl.c, src/modules/sdl/consumer_sdl_preview.c,
2005-02-01 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/feeds/PAL/border.properties: fill for borders
-
- * src/modules/gtk2/Makefile: conditional mmx compilation
-
- * src/modules/core/transition_composite.c: int handling on the frame image
- stack
-
* src/framework/mlt_deque.c, src/framework/mlt_deque.h,
src/framework/mlt_frame.c, src/framework/mlt_frame.h: 64 bit fix and deque
int holding
2005-01-31 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sdl/consumer_sdl_preview.c: Refresh count instead of flag
-
- * src/modules/sdl/consumer_sdl_preview.c: Mutex locking for refresh handling
-
- * src/modules/core/filter_rescale.c: Warning removal
-
- * src/modules/resample/filter_resample.c: Workaround for test card audio (may
- need to review)
-
- * src/modules/inigo/producer_inigo.c: Empty track definition fix
-
* src/modules/sdl/consumer_sdl_preview.c,
src/modules/sdl/consumer_sdl_still.c: Consumer reworked
- * src/modules/plus/transition_affine.c: Pointless improvement on a bad filter
- :-)
-
- * src/modules/gtk2/producer_pango.c: Memory leak fix
-
- * src/modules/westley/consumer_westley.c: titles and global feeds
-
* src/modules/feeds/PAL/border.properties,
src/modules/feeds/PAL/data_fx.properties: Minor corrections
- * src/modules/core/filter_data_show.c: Global/local data show distinction
-
- * src/modules/core/Makefile: Removed superflous mmx compilation
-
- * src/framework/mlt_tractor.c: Global data feed handling
-
* src/framework/mlt_filter.c, src/framework/mlt_service.c: Wild card filter
tracks
- * src/framework/mlt_events.c: Memory leak fix
-
- * src/framework/mlt_consumer.c: Small correction to deinterlacing
-
2005-01-25 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/feeds/PAL/border.properties,
src/framework/mlt_transition.h: Transitions reworked (always_active
capabilities); remaining audio handling switched to stacks
- * demo/mlt_news: Correction for audio mix
-
2005-01-19 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/framework/mlt_consumer.c: consumer close fix
-
* src/modules/feeds/PAL/etv.properties, src/modules/gtk2/producer_pango.c:
iconv fixes
src/modules/feeds/PAL/etv.properties: Minor modifications to compositing
options and etv fx
- * src/modules/gtk2/producer_pango.c: Added a weight property
-
2005-01-14 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/src/MltProperties.cpp, mlt++/src/MltProperties.h: Const string usage
in properties
- * demo/mlt_attributes: Correction for ETV specific filters
-
- * src/modules/feeds/PAL/etv.properties: Seperation for ETV specific filters
-
- * docs/testing.txt: Test case clean up
-
* demo/demo, demo/mlt_watermark, src/framework/mlt_producer.c,
src/framework/mlt_properties.c, src/framework/mlt_properties.h,
src/framework/mlt_property.c, src/framework/mlt_property.h,
src/modules/feeds/PAL/obscure.properties, src/modules/fezzik.ini,
src/modules/gtk2/producer_pango.c: Sundry minor fixes and optimisations
-2005-01-08 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_geometry.c: Corrections to geometry next key and
- serialise
-
2005-01-03 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/src/MltGeometry.cpp, mlt++/src/MltGeometry.h: Next/Prev key
* src/miracle/miracle_server.c, src/miracle/miracle_server.h: Fetch unit from
miracle server
-2005-01-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_playlist.c: Correction to clip_start at end of playlist
-
2004-12-31 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* demo/demo.ini, src/framework/mlt_producer.c,
src/framework/mlt_properties.c, src/framework/mlt_property.c,
src/framework/mlt_transition.c: Corrections after valgrinding
- * mlt++/src/MltGeometry.h: Update for geometry
-
* demo/demo.ini, demo/mlt_attributes, demo/mlt_news, demo/mlt_slideshow,
demo/mlt_slideshow_black, demo/mlt_squeeze, demo/mlt_ticker,
demo/mlt_watermark: Corrections and minor fixes to use new geometry spec;
* src/modules/feeds/NTSC/obscure.properties,
src/modules/feeds/PAL/data_fx.properties: Feeds updates
- * src/framework/mlt_producer.c: Extension to mini fezzik for obscures on cuts
-
-
- * src/framework/mlt_tractor.c: Option to hold feed processing on a track
-
- * src/framework/mlt_playlist.c: Fix for join length correction
-
- * src/framework/mlt_frame.c: Resize fix for chroma offsets
-
* src/framework/mlt_geometry.c, src/framework/mlt_geometry.h: Improved
geometry
-2004-12-28 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/jackrack/filter_jackrack.c: bootstrap earlier with fixed number
- of channels, better initial synchronisation phase, reduced internal buffer
- size
-
- * src/modules/jackrack/filter_jackrack.c: even better close handling?
-
- * src/modules/jackrack/filter_jackrack.c: fixup includes
-
- * src/modules/jackrack/filter_jackrack.c: ensure disconnected from jack
- before releasing any resources
-
2004-12-27 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* docs/services.txt, src/modules/jackrack/filter_jackrack.c: add
* mlt++/src/Makefile, mlt++/src/Mlt.h, mlt++/src/MltGeometry.cpp,
mlt++/src/MltGeometry.h, mlt++/swig/mltpp.i: Geometry
- * src/modules/core/transition_composite.c: Luma generation and use
-
* src/modules/core/transition_composite.c,
src/modules/core/transition_luma.c, src/modules/lumas/Makefile,
src/modules/lumas/create_lumas, src/modules/lumas/luma.c: Luma generation and
src/modules/data_fx.properties, src/modules/xine/deinterlace.c: Framework
inclusion of geometry
-2004-12-21 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/data_fx.properties: Correction to obscure data_show config
-
- * src/modules/data_fx.properties: Correction to obscure data_show config
-
2004-12-20 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_playlist.c, src/modules/core/transition_composite.c,
2004-12-14 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/framework/mlt_consumer.c: Mutex protection on put frame close
-
* src/framework/mlt_producer.c, src/framework/mlt_service.c: Mutex locking in
the get frame
2004-12-01 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/core/filter_data_feed.c: ignore attr which are active, but have
- no value
-
- * src/modules/data_fx.properties: Minor mods for ETV data filters
-
* src/framework/mlt_consumer.c, src/framework/mlt_consumer.h,
src/framework/mlt_factory.c, src/framework/mlt_field.c,
src/framework/mlt_filter.c, src/framework/mlt_filter.h,
2004-11-25 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/swig/Makefile: Install makefile for swig
-
* mlt++/src/Makefile, mlt++/src/Mlt.h, mlt++/src/MltDeque.cpp,
mlt++/src/MltDeque.h, mlt++/src/MltFactory.cpp, mlt++/src/MltFactory.h,
mlt++/src/MltProducer.cpp, mlt++/src/MltProducer.h,
mlt++/src/MltService.h, mlt++/test/Makefile: More playlist modifications;
service locking
- * src/modules/sdl/consumer_sdl_still.c: Consumer sdl preview correction -
- attach colour space conversion on start
-
* src/framework/mlt_playlist.c, src/framework/mlt_playlist.h,
src/framework/mlt_producer.c, src/framework/mlt_service.c,
src/framework/mlt_service.h: More playlist modifications; service locking;
2004-11-17 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/framework/mlt_producer.c: Extendible blank producers
-
* mlt++/src/MltProperties.cpp, mlt++/src/MltProperties.h,
mlt++/src/MltTractor.cpp, mlt++/src/MltTractor.h: Ref count and event firing
method on properties; locate_cut on tractor
mlt++/src/MltTractor.cpp, mlt++/src/MltTractor.h: Simplified playlist and
track access
- * src/modules/sdl/consumer_sdl_still.c: Increased delay for polling
-
* src/framework/mlt_playlist.c, src/framework/mlt_playlist.h: Simplified
playlist access
* mlt++/src/MltProducer.cpp, mlt++/src/MltProducer.h: Added cut related
methods
- * src/framework/mlt_multitrack.c: Behavioural change - tracks with hide
- properties now affect length (might be problematic)
-
-2004-11-03 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_producer.c: Correction for direct playback of a cut
-
2004-11-01 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/gtk2/consumer_gtk2.c, src/modules/gtk2/producer_pixbuf.c,
2004-10-27 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/plus/filter_charcoal.c: Minor optimisation
-
* mlt++/configure, mlt++/swig/configure, mlt++/swig/ruby/build,
mlt++/swig/ruby/miracle.rb: Config changes
2004-10-24 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sdl/consumer_sdl_preview.c: Oops - need to parse the size in
- the preview
-
* mlt-config-template, src/framework/configure, src/miracle/configure,
src/modules/gtk2/Makefile, src/modules/gtk2/configure,
src/modules/gtk2/consumer_gtk2.c, src/modules/gtk2/consumer_gtk2.h,
2004-10-21 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sdl/consumer_sdl_still.c: SDL Preview second checkin
-
* src/framework/mlt_consumer.c, src/inigo/inigo.c,
src/modules/sdl/consumer_sdl.c, src/modules/sdl/consumer_sdl_preview.c,
src/modules/sdl/consumer_sdl_still.c: SDL Preview second checkin
src/miracle/miracle_server.h: Convenience functionality for properties load
and miracle_server_id function
- * src/miracle/miracle_server.c: Server shutdown state oops
-
- * mlt++/src/MltMiracle.cpp: Server shutdown state
-
- * src/miracle/miracle_server.c: Server shutdown state
-
-2004-10-15 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/valerie/consumer_valerie.c: Error property for valerie returned
-
-
2004-10-14 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/src/MltConsumer.cpp, mlt++/src/MltConsumer.h, mlt++/test/play.cpp:
* src/modules/westley/consumer_westley.c, src/valerie/valerie_remote.c:
buffer fix and tractor handling
- * mlt++/HOWTO: Doc updates
-
* src/miracle/miracle_connection.c, src/miracle/miracle_local.c,
src/miracle/miracle_server.c, src/miracle/miracle_unit_commands.c,
src/miracle/miracle_unit_commands.h, src/modules/valerie/consumer_valerie.c,
src/modules/westley/producer_westley.c: Fix for deep westleys and filter
in/out points
- * src/framework/mlt_consumer.c: Oops - fix for consumer progressive
-
* docs/services.txt, src/framework/mlt_consumer.c, src/framework/mlt_frame.c,
src/framework/mlt_playlist.c, src/framework/mlt_properties.c,
src/framework/mlt_tractor.c, src/inigo/inigo.c,
* src/modules/avformat/configure, src/modules/avformat/producer_avformat.c:
Fix for current cvs
-2004-10-09 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_playlist.c: Mix on Mix and length corrections
-
2004-10-08 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/src/MltProducer.cpp, mlt++/src/MltProducer.h: Same and following clip
* docs/framework.txt, docs/inigo.txt, docs/install.txt: Some documentation
updates - more to follow
- * src/framework/mlt_producer.c: Removed fezzik usage from cloning
-
2004-10-07 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_filter.c, src/framework/mlt_producer.c,
src/modules/westley/producer_westley.c: Cloning optimisations and
introduction of the service parser
-2004-10-04 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/inigo/producer_inigo.c: Allow filter attachment to clip
-
2004-10-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_factory.c, src/framework/mlt_service.c,
* mlt++/README, mlt++/src/MltPlaylist.cpp, mlt++/src/MltPlaylist.h: Playlist
repeat clip functionality
- * src/inigo/inigo.c: Clean up - added new usage options
-
* src/framework/mlt_playlist.c, src/framework/mlt_playlist.h,
src/modules/inigo/producer_inigo.c, src/modules/westley/consumer_westley.c,
src/modules/westley/producer_westley.c: Splits, joins and repeats
2004-09-25 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/westley/consumer_westley.c: Fix for serialising multiple
- overlapping mixes
-
- * src/framework/mlt_playlist.c: Whoops - mix fix
-
* src/framework/mlt_playlist.c, src/framework/mlt_playlist.h,
src/modules/westley/consumer_westley.c,
src/modules/westley/producer_westley.c: Corrects cuts with filters
src/modules/westley/producer_westley.c: Finalisation of first phase of cut
handling (unmanaged)
- * src/framework/mlt_transition.c: Transitions ignore test frames
-
2004-09-24 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_multitrack.c, src/framework/mlt_playlist.c,
src/modules/westley/producer_westley.c: Cut management part 2 - corrects
playlist split/join and a little bit of mix
- * src/framework/mlt_properties.c: ...gah...
-
* mlt++/src/MltProducer.cpp, mlt++/src/MltProducer.h, mlt++/swig/mltpp.i: Cut
management part 1
src/framework/mlt_service.c, src/modules/westley/consumer_westley.c,
src/modules/westley/producer_westley.c: Cut management part 1
- * src/modules/westley/consumer_westley.c: fix for in/out during serialisation
-
-
2004-09-23 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/framework/mlt_tractor.c: Alpha from the tractor fix
-
* mlt++/src/MltService.cpp, mlt++/swig/mltpp.i: get_frame and ruby listen fix
* mlt++/configure, mlt++/src/MltMiracle.cpp: Server shutdown
- * src/framework/mlt_properties.c: Whoops
-
* src/framework/mlt_factory.c, src/framework/mlt_properties.c,
src/miracle/miracle.c, src/miracle/miracle_local.c,
src/miracle/miracle_server.c, src/miracle/miracle_server.h,
mlt++/src/MltMiracle.h, mlt++/src/MltResponse.cpp, mlt++/src/MltResponse.h,
mlt++/swig/mltpp.i: Added the response object
- * src/valerie/valerie_response.h: Obtain stdio definitions
-
* mlt++/HOWTO, mlt++/src/Makefile, mlt++/src/Mlt.h, mlt++/src/MltMiracle.cpp,
mlt++/src/MltMiracle.h, mlt++/swig/mltpp.i, mlt++/swig/ruby/miracle.rb,
mlt++/test/Makefile, mlt++/test/play.cpp, mlt++/test/server.cpp: Adding
* Makefile, src/humperdink/Makefile, src/modules/dv/producer_libdv.c: Build
fix and temporary libdv compatability
- * src/framework/mlt_frame.c: aspect ratio fix for test card
-
- * src/framework/mlt_tractor.c: Aspect ratio fix
-
- * src/modules/sdl/consumer_sdl.c: Aspect ratio modifications
-
- * src/miracle/Makefile: Customising the miracle server part 1
-
2004-09-17 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_service.c, src/framework/mlt_service.h,
* src/framework/mlt_frame.c, src/modules/core/transition_luma.c: Work arounds
for scaling related issues
-2004-09-13 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: position fixing
-
2004-09-09 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sdl/consumer_sdl.c: Ugly temporary hack for aspect ratio
-
* src/framework/mlt_playlist.c, src/inigo/inigo.c,
src/modules/inigo/producer_inigo.c: Fixes for removed tracks before/after mix
2004-09-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sdl/consumer_sdl.c: Fix occassional sdl core dumps
-
* mlt++/src/Makefile, mlt++/src/Mlt.h, mlt++/src/MltEvent.cpp,
mlt++/src/MltEvent.h, mlt++/src/MltProperties.cpp, mlt++/src/MltProperties.h,
mlt++/swig/mltpp.i, mlt++/swig/ruby/play.rb, mlt++/test/play.cpp: Event
src/framework/mlt_frame.h, src/modules/westley/consumer_westley.c,
src/valerie/Makefile: Minor make/configure mods and mlt_frame_waveform mod
-2004-08-30 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_frame.c: properly deal with evaluation of magnitude of 2s
- complement for waveform generation
-
- * src/framework/mlt_frame.c: new, faster waveform generator that emphasizes
- gain as opposed to shape
-
2004-08-29 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/framework/mlt_frame.c: bugfix in waveform method
-
* src/framework/mlt_frame.c, src/framework/mlt_frame.h: add waveform method
to frame
2004-08-23 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * mlt++/swig/perl/play.pl: Added play.pl
-
* mlt++/src/Makefile, mlt++/swig/mltpp.i: Workaround for perl
2004-08-21 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/core/filter_rescale.c, src/modules/gtk2/factory.c: Colour space
conversion with gdkpixbuf scaling
- * src/modules/avformat/producer_avformat.c: Another attempted mjpeg work
- around
-
- * src/framework/mlt_consumer.c: Prefil consumer property
-
2004-08-18 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/src/MltFrame.cpp, mlt++/src/MltFrame.h, mlt++/src/MltProducer.cpp,
mlt++/src/MltFilteredProducer.h, mlt++/src/MltService.cpp,
mlt++/src/MltService.h, mlt++/swig/mltpp.i: Filtered producers and consumers
- * src/framework/mlt_service.c: NULL accpectance for connect/disconnect
-
- * mlt++/test/play.cpp: oops
-
2004-08-16 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt++/swig/configure, mlt++/swig/java/Play.java, mlt++/swig/java/Play.sh,
mlt++/src/MltTransition.cpp, mlt++/src/MltTransition.h, mlt++/test/Makefile,
mlt++/test/play.cpp: Initial revision
-2004-08-12 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: gop/b frame fix, http/pipe
- handling and logging off
-
2004-08-10 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/Makefile, src/modules/avformat/configure,
src/modules/avformat/factory.c, src/modules/avformat/filter_avcolour_space.c,
src/modules/avformat/filter_avcolour_space.h: Colour space filter
-2004-08-08 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: Rudimentary rgb24 support
-
- * src/modules/avformat/producer_avformat.c: optimisations
-
-2004-08-07 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_region.c: Flexible and animated shapes
-
2004-08-05 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/configure, src/modules/avformat/producer_avformat.c:
* src/modules/dv/consumer_libdv.c, src/modules/dv/producer_libdv.c,
src/modules/dv/producer_libdv.h: Fix for current libdv
- * src/modules/avformat/producer_avformat.c: Pipe workaround
-
2004-08-03 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/core/filter_watermark.c, src/modules/core/transition_region.c:
Mutable shapes on regions
-2004-08-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/plus/filter_affine.c: Small modifications to allow seeking
-
- * src/modules/sdl/consumer_sdl.c: Rectangle added to properties
-
2004-07-31 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/plus/filter_invert.c: Minor fix to invert
-
* src/modules/core/filter_watermark.c,
src/modules/core/transition_composite.c: Mutable watermark producer and small
optimisation
2004-07-26 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sox/Makefile: link to mad
-
* src/modules/core/filter_luma.c, src/modules/core/filter_mirror.c,
src/modules/core/transition_composite.c,
src/modules/core/transition_region.c: Mutable properties
2004-07-23 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/core/transition_composite.c: Allows runtime modifications to
- region fx
-
* src/modules/core/filter_region.c, src/modules/core/transition_composite.c,
src/modules/core/transition_region.c: Allows runtime modifications to region
fx
-2004-07-22 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: Pipe support for audio or video
- only
-
2004-07-15 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_consumer.c, src/framework/mlt_factory.c,
src/modules/plus/filter_sepia.h, src/modules/plus/transition_affine.c: affine
with alpha and a broken sepia
-2004-06-19 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/plus/transition_affine.c: Affine silliness
-
2004-06-14 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* configure, src/modules/configure, src/modules/core/configure,
src/modules/plus/filter_charcoal.h, src/modules/plus/filter_invert.c,
src/modules/plus/filter_invert.h: More silliness :-)
-2004-06-09 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * configure: version bump
-
- * src/modules/avformat/configure: ffmpeg fixed date for cvs checkout
-
- * src/modules/avformat/ffmpeg.patch: ffmpeg patch for mandrake build
-
- * src/modules/avformat/producer_avformat.c: Temporary work around for missing
- aspect ratio
-
- * src/framework/mlt_properties.c: Rudimentary arithmetic property assignment
-
2004-06-07 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_consumer.c, src/modules/core/producer_colour.c,
src/modules/core/producer_noise.c, src/modules/fezzik.ini,
src/modules/gtk2/producer_pixbuf.c, src/tests/charlie.c: Minor tweaks
-2004-05-30 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: slightly better seeking in drop
- frame cases
-
- * src/modules/sdl/consumer_sdl.c: real_time=0 fix
-
- * src/modules/avformat/consumer_avformat.c: Update to latest ffmpeg cvs
-
2004-05-25 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/Makefile, src/modules/avformat/configure: Yet another
src/modules/avformat/producer_avformat.c: fix for avformat seek < gop; fix
for avformat consumer qscale; additional avformat consumer properties
-2004-05-08 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/avformat/producer_avformat.c: Removed unecessary locks in
- avformat
-
-2004-05-07 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl.c: audio off
-
-2004-05-06 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl.c: aspect ratio and locking
-
-2004-05-06 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * docs/services.txt: a clarification
-
- * src/modules/core/filter_resize.c: set output frame aspect to consumer
- sample aspect, not display aspect.
-
- * src/modules/sdl/consumer_sdl.c: fix aspect handling when rescale != none
-
-2004-05-05 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl.c: last sdl fix for now (sigh)
-
- * src/modules/sdl/consumer_sdl.c: yet another sdl tweak (sigh)
-
-2004-05-04 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl.c: last sdl fix for now (sigh)
-
2004-05-03 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/consumer_avformat.c, src/modules/fezzik.ini,
src/modules/sdl/consumer_sdl.c, src/modules/vorbis/producer_vorbis.c: minor
clean ups; added a null consumer for easier valgrind testing
-2004-05-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_consumer.c: audio/video processing swap
-
-2004-05-02 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sox/filter_sox.c: fix st.h include
-
-2004-05-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_frame.c: test card handling
-
2004-05-01 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_consumer.c, src/framework/mlt_frame.c,
2004-04-19 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * configure: version shunt
-
* README, configure, docs/install.txt, docs/services.txt,
src/modules/avformat/Makefile, src/modules/avformat/configure,
src/modules/avformat/consumer_avformat.c, src/modules/avformat/factory.c,
* configure, docs/services.txt, setenv: GPL checking (provisional
implementation), mc scaling docs
- * src/framework/mlt.h: added tokeniser to mlt header
-
* src/modules/configure, src/modules/core/Makefile,
src/modules/core/configure, src/modules/core/factory.c,
src/modules/core/filter_rescale.c, src/modules/core/filter_rescale.h,
2004-04-17 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sox/Makefile: whoops - missed some libs
-
- * src/albino/Makefile: albino Makefile cleanup
-
* src/modules/dv/Makefile, src/modules/normalize/Makefile,
src/modules/sox/Makefile: Makefile cleanup in modules
2004-04-16 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sox/filter_sox.c: add more comments
-
* src/modules/core/Makefile, src/modules/core/configure,
src/modules/core/factory.c, src/modules/core/filter_volume.c,
src/modules/core/filter_volume.h, src/modules/normalize/Makefile,
2004-04-15 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/fezzik/producer_fezzik.c: Change defaults to LGPL deinterlace
- and resample
-
* src/modules/avformat/Makefile, src/modules/avformat/configure,
src/modules/avformat/factory.c, src/modules/avformat/filter_avdeinterlace.c,
src/modules/avformat/filter_avdeinterlace.h,
src/modules/avformat/consumer_avformat.c: Makefile error handling and
consumer avformat cleanup
- * docs/install.txt: Installation docs update
-
2004-04-13 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/producer_avformat.c, src/modules/core/filter_resize.c,
2004-04-07 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/framework/mlt_frame.c: test card and aspect ratio woes continued
-
* src/framework/mlt_consumer.c, src/framework/mlt_frame.c,
src/framework/mlt_properties.c: aspect ratio and test card woes
src/modules/gtk2/filter_rescale.c, src/modules/sdl/consumer_sdl.c: hold
modifications and test card env var
-2004-04-02 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * demo/demo: remove setenv call
-
2004-04-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sdl/consumer_sdl.c: added setenv_mc
-
* setenv_mc, src/modules/sdl/consumer_sdl.c: added setenv_mc
* demo/demo.ini, demo/mlt_squeeze, demo/mlt_squeeze_box, docs/framework.txt,
docs/services.txt, src/modules/core/transition_composite.c: minor mods
-2004-03-30 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * docs/services.txt: fix something that got disordered
-
- * src/modules/westley/producer_westley.c: qualitfy paths of known properties
- that take a filename with server virtual root
-
2004-03-30 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* docs/services.txt, src/albino/Makefile, src/framework/Makefile,
2004-03-29 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/valerie/valerie.c: insert fix
-
* README, src/framework/configure, src/framework/mlt.h,
src/framework/mlt_consumer.c, src/framework/mlt_factory.c,
src/framework/mlt_pool.c, src/modules/avformat/Makefile,
docs/services.txt, docs/testing.txt, docs/valerie.txt, docs/westley.txt: Doc
formating
-2004-03-26 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/miracle/configure: make install part 2 - building configs
-
2004-03-26 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* demo/entity.westley, demo/new.westley, docs/westley.txt,
src/miracle/configure, src/valerie/configure: make install part 2 - building
configs
- * src/modules/fezzik/Makefile: make install fix
-
2004-03-26 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* demo/entity.westley, docs/westley.txt,
src/modules/westley/producer_westley.c: reorganized consumer_westley. added
branch tracking and other bugfixes to producer_westley.
-2004-03-25 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_tractor.c: tractor fix
-
2004-03-24 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* demo/mlt_fade_black, demo/mlt_push, src/modules/westley/consumer_westley.c,
* demo/mlt_fade_black, demo/mlt_title_over_gfx,
demo/mlt_titleshadow_watermark: couple of fixes to hidden tracks
- * src/framework/mlt_multitrack.c: ignore length of hidden tracks
-
* demo/consumers.ini, demo/luma1.pgm, demo/mlt_clock_in_and_out,
demo/mlt_fade_black, demo/mlt_my_name_is, demo/mlt_news, demo/mlt_squeeze,
demo/mlt_title_over_gfx, demo/mlt_voiceover: demo mods for reversed tracks
2004-03-23 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * docs/install.txt: minor typos
-
* README, demo/consumers.ini, docs/framework.txt, docs/install.txt,
docs/services.txt, docs/westley.txt, src/albino/albino.c,
src/humperdink/client.c, src/modules/gtk2/producer_pango.c,
* src/framework/mlt_frame.c, src/miracle/miracle_commands.c,
src/miracle/miracle_unit_commands.c: root corrections to miracle
- * src/valerie/valerie.c: quick valerie fix
-
- * docs/install.txt: Added install.txt
-
-2004-03-22 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/westley/producer_westley.c: null pointer check in end_playlist
-
-2004-03-22 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
* src/modules/avformat/producer_avformat.c,
src/modules/core/producer_colour.c, src/modules/dv/consumer_libdv.c,
src/modules/fezzik/Makefile, src/modules/fezzik/configure,
2004-03-22 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/westley/producer_westley.c: touchup on the producer in/out
- applied to parent entry
-
* demo/circle.svg, demo/demo.kino, demo/new.westley, demo/svg.westley,
src/framework/mlt_filter.c, src/framework/mlt_playlist.c,
src/modules/fezzik.dict, src/modules/fezzik/producer_fezzik.c,
* docs/services.txt, src/modules/avformat/producer_avformat.c: revert
avformat pts offset change and note bug in docs
- * src/modules/inigo/producer_inigo.c: fix brokenness
-
2004-03-18 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* docs/framework.txt, docs/westley.txt, src/framework/config.h,
filter_resample to reproduce channels when producer does not create as many
as consumer requested.
- * src/modules/core/filter_volume.c: bugfix segfault in audio normaliser as
- well as logical bug in smoothing.
-
* docs/services.txt, src/modules/avformat/producer_avformat.c,
src/modules/fezzik/producer_fezzik.c, src/modules/inigo/producer_inigo.c:
fezzik now accepts service:resource and strips \'avformat:\' before fallback
* demo/README, demo/consumers.ini, demo/demo, demo/mlt_clock_in_and_out,
demo/mlt_voiceover: notes for the demo
- * demo/demo.ini: bring into sync with changes
-
- * src/modules/sdl/consumer_sdl.c: default progressive off
-
* demo/circle.png, demo/circle.svg, demo/consumers.ini, demo/luma1.pgm,
demo/mlt_bouncy_ball, demo/mlt_composite_transition,
demo/mlt_fade_in_and_out, demo/mlt_obscure, demo/mlt_title_over_gfx,
demo/mlt_titleshadow_watermark, demo/mlt_voiceover: some demo updates
- * src/modules/core/transition_luma.c: fix distortion in smoothness
-
- * src/modules/core/filter_gamma.c: fix broken gamma
-
- * src/modules/core/transition_luma.c: fix field rendering
-
- * src/modules/core/transition_composite.c: bugfixes with field rendering
-
- * src/modules/dv/producer_libdv.c: fix aspect
-
2004-03-12 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* demo/consumers.ini, demo/demo, src/framework/mlt_consumer.c,
src/framework/mlt_property.h, src/modules/sdl/consumer_sdl.c: more small
optimisations
- * demo/demo: demo framework added
-
* demo/demo, demo/demo.ini, demo/luma1.pgm, demo/mlt_all,
demo/mlt_audio_stuff, demo/mlt_avantika_title, demo/mlt_bouncy,
demo/mlt_bouncy_ball, demo/mlt_clock_in_and_out,
2004-03-04 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/core/transition_luma.c: reorg transition_luma to support
- producer
-
* src/modules/Makefile, src/modules/core/Makefile,
src/modules/core/configure, src/modules/core/factory.c,
src/modules/core/filter_deinterlace.c, src/modules/core/filter_deinterlace.h,
2004-03-03 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/core/filter_deinterlace.c: optimise deinterlace path
-
- * src/modules/core/producer_colour.c: producer_colour
-
* src/framework/mlt_frame.c, src/framework/mlt_frame.h,
src/modules/core/Makefile, src/modules/core/configure,
src/modules/core/factory.c, src/modules/core/producer_colour.c,
src/modules/core/producer_colour.h: producer_colour
- * src/framework/mlt_frame.c: more accurate and scaled rgb to yuv conversion
-
2004-03-03 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_multitrack.c, src/framework/mlt_pool.c,
src/modules/westley/producer_westley.c: some bugfixes, filter_shape producer,
pixbuf takes svg xml, fezzik can take a service name
-2004-03-02 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl.c: More SDL fixes
-
-2004-03-01 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/sdl/consumer_sdl.c: yet more sdl hacks
-
2004-03-01 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/avformat/producer_avformat.c, src/modules/dv/producer_libdv.c,
2004-03-01 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/sdl/consumer_sdl.c: Minor sdl hack
-
* src/framework/mlt_consumer.c, src/framework/mlt_factory.c,
src/framework/mlt_factory.h, src/framework/mlt_frame.c,
src/framework/mlt_producer.c, src/modules/gtk2/filter_rescale.c,
src/modules/dv/producer_libdv.c, src/modules/gtk2/producer_pango.c,
src/modules/gtk2/producer_pixbuf.c: unique ids
-2004-02-27 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/gtk2/scale_line_22_yuv_mmx.S: bugfix mmx scaling with
- performance loss :-(
-
2004-02-27 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_frame.c, src/modules/core/filter_resize.c,
src/modules/gtk2/scale_line_22_yuv_mmx.S: mmx version of non-nearest, 2x2
rescaling
-2004-02-26 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_composite.c: composite alignment fix
-
2004-02-26 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/modules/gtk2/Makefile, src/modules/gtk2/pixops.c,
2004-02-25 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/core/transition_composite.c: composite key frames
-
* docs/TODO, src/framework/mlt_consumer.c, src/framework/mlt_frame.c,
src/framework/mlt_frame.h, src/modules/avformat/producer_avformat.c,
src/modules/core/filter_deinterlace.c, src/modules/core/filter_obscure.c,
src/modules/core/transition_luma.c, src/modules/sdl/consumer_sdl.c: service
stack, various fixes
-2004-02-24 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_composite.c: field rendering fix and disable
- scaling height when normalising pixel aspect when output pixel aspect < 1
-
2004-02-24 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* docs/services.txt, src/framework/mlt_frame.c, src/framework/mlt_producer.h,
src/modules/vorbis/producer_vorbis.c, src/tests/Makefile,
src/valerie/Makefile: Memory pooling part 2 and other optimisations
-2004-02-19 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/transition_luma.c: more dissolve optimisation
-
- * src/modules/core/transition_luma.c: optimise dissolve case
-
2004-02-19 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
* docs/services.txt, src/framework/Makefile, src/framework/mlt_factory.c,
2004-02-18 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/framework/mlt_consumer.c: create consumer_progressive property on frame
-
-
- * src/modules/sdl/consumer_sdl.c: default progressive on
-
- * src/modules/westley/consumer_westley.c: consumer_westley now only puts
- in/out as element attributes and not property elements
-
* src/modules/core/filter_deinterlace.c,
src/modules/core/transition_composite.c, src/modules/core/transition_luma.c:
split getting of b_frame image and composite
* docs/TODO, src/miracle/miracle_local.c: add TODO
-2004-02-11 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_producer.c: test card handling
-
- * src/miracle/miracle_local.c: optional segv handling
-
2004-02-11 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/miracle/miracle_local.c: change segv handler to use log facility
-
- * src/valerie/valerie_notifier.c: cleanup
-
* src/framework/mlt_frame.c, src/framework/mlt_playlist.c,
src/miracle/miracle_local.c, src/valerie/valerie_notifier.c: segv handler,
playlist_move bugfix, resize_yuv422 optimisation
2004-02-11 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/miracle/miracle_unit.c: first of a few local tests
-
- * src/miracle/miracle_commands.c: first of a few local tests
-
* docs/testing-20040110.txt, src/framework/mlt_frame.c,
src/miracle/miracle_unit.c, src/miracle/miracle_unit_commands.c,
src/modules/dv/consumer_libdv.c, src/valerie/valerie_notifier.c,
* src/framework/mlt_filter.c, src/framework/mlt_frame.c: filter fixes
-2004-02-09 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/core/filter_volume.c: remove spurious return in get_audio
-
-2004-02-09 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
* src/miracle/miracle_unit.c, src/modules/dv/consumer_libdv.c: brought by a
resizable bunny
- * src/modules/dv/consumer_libdv.c: brought by a bunny
-
* docs/services.txt, src/modules/gtk2/producer_pango.c: pango colour handling
src/modules/gtk2/producer_pango.c, src/modules/gtk2/producer_pixbuf.c:
pixbuf, composite and fezzik mirrors
-2004-02-07 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/modules/westley/producer_westley.c: support in/out on entry and track
-
2004-02-07 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/gtk2/producer_pango.c: pango producer rework
-
* src/modules/avformat/producer_avformat.c, src/modules/sdl/consumer_sdl.c,
src/modules/westley/producer_westley.c: Minor corrections, rescale=nearest
for sdl
2004-02-07 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/gtk2/filter_rescale.c: rescale aspect handling redux
-
* src/modules/avformat/producer_avformat.c,
src/modules/gtk2/filter_rescale.c, src/modules/gtk2/producer_pango.c,
src/modules/gtk2/producer_pixbuf.c: fixup and disable rescale changes
2004-02-05 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/resample/filter_resample.c: resample fix
-
* docs/services.txt, setenv, src/framework/mlt_frame.c,
src/framework/mlt_multitrack.c, src/framework/mlt_producer.c,
src/framework/mlt_transition.c, src/miracle/miracle_unit.c,
2004-02-04 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/gtk2/pixops.c: final rescale improvement and some optimisation
-
- * src/modules/gtk2/pixops.c: near final rescale improvements?
-
- * src/modules/gtk2/pixops.c: interim rescale improvements
-
- * src/modules/gtk2/pixops.c: interim rescale improvements
-
* src/modules/gtk2/pixops.c, src/modules/gtk2/pixops.h: interim rescale
improvements
src/framework/mlt_types.h: added deque, api design for manager, minor affine
tweaks, experimental destructor work
-2004-01-31 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * docs/services.txt: doc updates
-
- * src/modules/core/filter_volume.c: configurable window size on volume
- normalisation, also set default of max_gain to 20dB
-
-2004-01-30 lilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
-
- * src/framework/mlt_frame.c: updated affine
-
2004-01-30 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* src/framework/mlt_frame.c, src/modules/avformat/producer_avformat.c,
2004-01-28 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
- * src/modules/core/filter_volume.c: comment some diagnostics
-
* docs/services.txt, src/modules/core/filter_volume.c: doc updates; property
changes, and tweaks for volume filter normalisation
src/modules/westley/consumer_westley.c,
src/modules/westley/producer_westley.c: updated westley
- * src/tests/dan.c: test cvs
-
2004-01-22 ddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
* mlt/src/modules/westley/consumer_westley.c,
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 0.7.6
+PROJECT_NUMBER = 0.8.8
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, 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
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
install -d "$(DESTDIR)$(prefix)/bin"
install -d "$(DESTDIR)$(prefix)/include"
install -d "$(DESTDIR)$(libdir)"
- install -d "$(DESTDIR)$(libdir)/mlt"
+ install -d "$(DESTDIR)$(moduledir)"
+ifeq ($(extra_versioning), true)
+ ln -s "$(moduledir)" "$(DESTDIR)$(unversionedmoduledir)"
+endif
install -d "$(DESTDIR)$(libdir)/pkgconfig"
- install -d "$(DESTDIR)$(prefix)/share/mlt"
+ install -d "$(DESTDIR)$(mltdatadir)"
+ifeq ($(extra_versioning), true)
+ ln -s "$(mltdatadir)" "$(DESTDIR)$(unversionedmltdatadir)"
+endif
install -c -m 644 *.pc "$(DESTDIR)$(libdir)/pkgconfig"
list='$(SUBDIRS)'; \
for subdir in $$list; do \
$(MAKE) DESTDIR=$(DESTDIR) -C $$subdir $@ || exit 1; \
done
- cp -R presets "$(DESTDIR)$(prefix)/share/mlt"
+ cp -R presets "$(DESTDIR)$(mltdatadir)"
uninstall:
rm -f "$(DESTDIR)$(bindir)"/mlt-config
$(MAKE) DESTDIR=$(DESTDIR) -C $$subdir $@ || exit 1; \
done
rm -rf "$(DESTDIR)$(prefix)/include/mlt"
+ rm -rf "$(DESTDIR)$(mltdatadir)"
+ifeq ($(compat_dirs), true)
rm -rf "$(DESTDIR)$(prefix)/share/mlt"
+endif
dist:
git archive --format=tar --prefix=mlt-$(version)/ v$(version) | gzip >mlt-$(version).tar.gz
validate-yml:
- for file in `find ./ -type f -name \*.yml`; do \
+ for file in `find src/modules -type f -name \*.yml`; do \
echo "validate: $$file"; \
- kwalify -f src/framework/metaschema.yaml $$file; \
+ kwalify -f src/framework/metaschema.yaml $$file || exit 1; \
done
MLT Release Notes
-----------------
+Version 0.8.8 - January 20, 2013
+
+This is purely a bugfix release. See the ChangeLog or git log.
+
+
+Version 0.8.6 - November 14, 2012
+
+This is a re-issue of the 0.8.4 release with a fix for a performance
+regression on videos that use full-range colorspaces such as yuv420p.
+
+Version 0.8.4 - November 13, 2012
+
+This is a bugfix and minor enhancement release.
+
+* Added playlist-next event and PlaylistNextListener to Ruby binding
+* FFmpeg 1.0 and libAV master compatibility
+* Improvements to motion_est filter to generate keyframes for apps
+* Added audiolevel (measurement) filter
+
+
+Version 0.8.2 - August 28, 2012
+
+This is a bugfix and minor enhancement release.
+
+* Overhaul of A/V sync with libavformat-based inputs.
+* Fix a major memory leak introduced in previous release.
+* Fixes to problems revealed by Coverity Scan static analysis.
+* Improved encoding presets.
+* melt can now be built without SDL with define MELT_NOSDL, which is handy
+ for running it as a child process on Windows and OS X.
+* melt can now be signaled to quit, which also makes it more useful as a
+ child process.
+
+Special thanks to Mikko Rapeli who provided many of the Coverity fixes.
+
+
+Version 0.8.0 - June 1, 2012
+
+The minor version is increased due to the addition of time properties!
+The soname version increased in the process because some mlt_property
+functions changed; however, very few if any apps actually directly use
+mlt_property preferring to use mlt_properties instead. In addition:
+
+* improve seek speed on AVCHD when using FFmpeg v0.9.1+ (NOT Libav!)
+* composite and dissolve speed improvements on x86-64
+* improve performance of caching in image producers
+* add device enumeration to decklink producer and consumer
+
+Special thanks go to contributors Maksym Veremeyenko and Ed Rogalsky.
+
+
+Version 0.7.8 - February 13, 2012
+
+This is a bugfix and minor enhancement release.
+
+* Improved support for v53 of libavcodec/libavformat
+* Added "multi" consumer - multiple, simultanous outputs
+* Added framerate adaption to "consumer" producer and "multi" consumer
+* Can now use YADIF deinterlacer with decklink producer
+* Added "rtaudio" consumer for native audio support on multiple platforms
+* Added ability to request image format closest to source (mlt_image_none)
+* Added more audio formats
+* Added vqm (video quality measurement) transition
+
+
Version 0.7.6 - October 31, 2011
This is a bugfix and minor enhancement release.
#!/bin/sh
-export version=0.7.7
-export soversion=4
+export version=0.8.8
+export soversion=5
show_help()
{
General build options:
- --prefix=directory - install prefix for path (default: $prefix)
- --libdir=directory - lib directory (default: $prefix/lib)
- --datadir=directory - data directory (default: $prefix/share)
- --mandir=directory - man documentation directory (default: $prefix/share/man)
- --enable-gpl - Enable GPL components
- --enable-debug - Compile without optimizations support (default: off)
- --disable-debug - Compile without debug support (default: on)
- --disable-mmx - Compile without MMX support (default: on)
- --disable-sse - Compile without SSE support (default: on)
- --disable-sse2 - Compile without SSE2 support (default: on)
- --arch='arch' - Compile for a specific architecture (default: none)
- --cpu='cpu' - Compile for a specific CPU (default: none)
+ --prefix=directory - install prefix for path (default: $prefix)
+ --libdir=directory - lib directory (default: $prefix/lib)
+ --datadir=directory - data directory (default: $prefix/share)
+ --mandir=directory - man documentation directory (default: $prefix/share/man)
+ --rename-melt - Give melt executable a different name (it will not be versioned)
+ --enable-extra-versioning - Version melt and the data and modules directories
+ --enable-gpl - Enable GPLv2 components
+ --enable-gpl3 - Enable GPLv3 components
+ --enable-debug - Compile without optimizations support (default: off)
+ --disable-debug - Compile without debug support (default: on)
+ --disable-mmx - Compile without MMX support (default: on)
+ --disable-sse - Compile without SSE support (default: on)
+ --disable-sse2 - Compile without SSE2 support (default: on)
+ --arch='arch' - Compile for a specific architecture (default: none)
+ --cpu='cpu' - Compile for a specific CPU (default: none)
+ --target-os='os' - Cross-compile to a specific OS (default: $(uname -s))
+ --target-arch='arch' - Cross-compile to a specific CPU architecture
Module disable options:
echo "bindir=$prefix/bin"
echo "datadir=$datadir"
echo "mandir=$mandir"
+ echo "extra_versioning=$extra_versioning"
+ echo "melt_noversion=$melt_noversion"
echo "targetos=$targetos"
[ "$mmx" = "true" ] &&
echo "LARGE_FILE=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE"
+ [ "$amd64" = "true" ] && echo "ARCH_X86_64=1" && echo "CFLAGS+=-DARCH_X86_64"
[ "$arch" != "" ] && echo "TARGETARCH=-march=$arch"
[ "$cpu" != "" ] && echo "TARGETCPU=-mcpu=$cpu"
if [ "$optimisations" = "true" ]
case $targetos in
Darwin)
- sysctl -a hw | grep "x86_64: 1" > /dev/null && echo "ARCH_X86_64=1" && echo "CFLAGS+=-DARCH_X86_64"
echo "CFLAGS+=-fPIC -D__DARWIN__ `sdl-config --cflags`"
echo "SHFLAGS=-dynamiclib"
echo "LDFLAGS+=`sdl-config --libs`"
;;
Linux|GNU/kFreeBSD|GNU)
- [ "$(uname -m)" = "x86_64" ] && echo "ARCH_X86_64=1" && echo "CFLAGS+=-DARCH_X86_64"
[ "$optimisations" = "true" ] &&
echo "OPTIMISATIONS+=-ffast-math"
echo "CFLAGS+=-fPIC -pthread"
echo "LDFLAGS+=-Wl,--no-undefined -Wl,--as-needed"
;;
FreeBSD)
- [ "$(uname -m)" = "amd64" -o "$(uname -m)" = "x86_64" ] && echo "ARCH_X86_64=1" && echo "CFLAGS+=-DARCH_X86_64"
[ "$optimisations" = "true" ] &&
echo "OPTIMISATIONS+=-ffast-math"
echo "CFLAGS+=-fPIC -pthread"
echo "LDFLAGS+=-Wl,--no-undefined -Wl,--as-needed"
;;
NetBSD)
- [ "$(uname -m)" = "amd64" ] && echo "ARCH_X86_64=1" && echo "CFLAGS+=-DARCH_X86_64"
[ "$optimisations" = "true" ] &&
echo "OPTIMISATIONS+=-ffast-math"
- echo "CFLAGS+=-pthread"
+ echo "CFLAGS+=-fPIC -pthread"
echo "SHFLAGS=-shared"
echo "RDYNAMIC=-rdynamic"
echo "LDFLAGS+=-Wl,--no-undefined -Wl,--as-needed"
;;
MinGW)
- [ "$(uname -m)" = "x86_64" ] && echo "ARCH_X86_64=1" && echo "CFLAGS+=-DARCH_X86_64"
[ "$optimisations" = "true" ] &&
echo "OPTIMISATIONS+=-ffast-math"
echo "SHFLAGS=-shared"
;;
esac
echo "LIBSUF=$LIBSUF"
+ echo "moduledir=${moduledir}"
+ echo "mltdatadir=${mltdatadir}"
+ echo "unversionedmoduledir=${unversionedmoduledir}"
+ echo "unversionedmltdatadir=${unversionedmltdatadir}"
+ echo "meltname=${meltname}"
) > config.mak
echo "#!/bin/sh" > mlt-config
echo version=$version
echo cflags=`grep ^framework packages.dat | cut -f 2`
echo libs=`grep ^framework packages.dat | cut -f 3`
+ echo moduledir=${moduledir}
+ echo mltdatadir=${mltdatadir}
+ echo meltbin=${prefix}/bin/${meltname}
) >> mlt-framework.pc
cat mlt-framework.pc.in >>mlt-framework.pc
export sse=true
export sse2=true
export gpl=false
+export gpl3=false
export arch=
export cpu=
-export targetos=
+export targetos=$(uname -s)
+export targetarch=
+export amd64=false
+export extra_versioning=false
+export melt_noversion=false
+
+# Define the compiler used in tests (gcc is not installed everywhere)
+: ${CC:=gcc}
+
+# Iterate through arguments
+for i in "$@"
+do
+ case $i in
+ --help ) help=1 ;;
+ --prefix=* ) prefix="${i#--prefix=}" ;;
+ --libdir=* ) libdir="${i#--libdir=}" ;;
+ --datadir=* ) datadir="${i#--datadir=}" ;;
+ --mandir=* ) mandir="${i#--mandir=}" ;;
+ --rename-melt=* ) meltname="${i#--rename-melt=}"; melt_noversion=true ;;
+ --enable-extra-versioning ) extra_versioning=true ;;
+ --enable-debug ) optimisations=false ;;
+ --disable-debug ) debug=false ;;
+ --disable-mmx ) mmx=false; sse=false; sse2=false ;;
+ --disable-sse ) sse=false; sse2=false ;;
+ --disable-sse2 ) sse2=false ;;
+ --enable-gpl ) gpl=true ;;
+ --enable-gpl3 ) gpl3=true ;;
+ --arch=* ) arch="${i#--arch=}" ;;
+ --cpu=* ) cpu="${i#--cpu=}" ;;
+ --target-os=* ) targetos="${i#--target-os=}" ;;
+ --target-arch=* ) targetarch="${i#--target-arch=}" ;;
+ esac
+done
+
+if [ -z "${meltname}" ]
+then
+ if [ "$extra_versioning" = "false" ]
+ then
+ meltname=melt
+ else
+ meltname=melt${soversion}
+ fi
+fi
-# Determine OS
-targetos=$(uname -s)
# Chose appropriate suffix for libraries
case $targetos in
Darwin)
LIBSUF=".dylib"
+ if [ "$targetarch" = "" ]
+ then
+ sysctl -a hw | grep "x86_64: 1" > /dev/null
+ [ "$?" = "0" ] && targetarch="amd64"
+ fi
;;
Linux|FreeBSD|NetBSD)
LIBSUF=".so"
;;
- MINGW32_NT-*)
+ MINGW32_NT-*|MinGW|mingw)
targetos="MinGW"
LIBSUF=".dll"
;;
esac
export LIBSUF
-# Iterate through arguments
-for i in "$@"
-do
- case $i in
- --help ) help=1 ;;
- --prefix=* ) prefix="${i#--prefix=}" ;;
- --libdir=* ) libdir="${i#--libdir=}" ;;
- --datadir=* ) datadir="${i#--datadir=}" ;;
- --mandir=* ) mandir="${i#--mandir=}" ;;
- --enable-debug ) optimisations=false ;;
- --disable-debug ) debug=false ;;
- --disable-mmx ) mmx=false; sse=false; sse2=false ;;
- --disable-sse ) sse=false; sse2=false ;;
- --disable-sse2 ) sse2=false ;;
- --enable-gpl ) gpl=true ;;
- --arch=* ) arch="${i#--arch=}" ;;
- --cpu=* ) cpu="${i#--cpu=}" ;;
- esac
-done
+# Determine if we are compiling for 64-bit Intel architecture
+[ "$targetarch" = "" ] && targetarch=$(uname -m)
+[ "$targetarch" = "amd64" -o "$targetarch" = "x86_64" ] && amd64=true
# Determine the libdir if it's not specified in the args
[ "$libdir" = "" ] && libdir=$prefix/lib
[ "$datadir" = "" ] && datadir=$prefix/share
[ "$mandir" = "" ] && mandir=$prefix/share/man
+export unversionedmoduledir=${libdir}/mlt
+export unversionedmltdatadir=${datadir}/mlt
+if [ "$extra_versioning" = "false" ]
+then
+export moduledir=${libdir}/mlt
+export mltdatadir=${datadir}/mlt
+else
+export moduledir=${libdir}/mlt-${soversion}
+export mltdatadir=${datadir}/mlt-${soversion}
+fi
+
# Double check MMX (Darwin, Linux and FreeBSD supported, may end up disabling MMX on other platforms incorrectly)
if [ "$mmx" = "true" ]
then
[ $help = 0 ] && echo "Configuring `basename $i`:"
olddir=`pwd`
cd src/$i
- ./configure "$@"
+ CC="$CC" ./configure "$@"
[ $? != 0 ] && exit 1
cd $olddir
fi
# Build the pkg-config files
build_pkgconfig
-# Report GPL Usage
-[ $help != 1 ] &&
-( [ "$gpl" = "false" ] &&
-echo "GPL Components are disabled" ||
-echo "GPL License Used" )
+# Report license Usage
+if [ $help != 1 ]
+then
+ if [ "$gpl" = "false" ]
+ then
+ echo "LGPLv2.1 license used; GPL components disabled"
+ elif [ "$gpl3" = "false" ]
+ then
+ echo "GPLv2 license used; GPLv3 components disabled"
+ else
+ echo "GPLv3 license used"
+ fi
+fi
melt \
clip1.dv out=299 \
-track \
-colour:black out=299 \
+colour:0 out=299 \
-track \
"+The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog..txt" \
out=299 \
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
-.TH MELT "1" "July 2011" "MLT melt 0.7.6" "User Commands"
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4.
+.TH MELT "1" "January 2013" "melt 0.8.8" "User Commands"
.SH NAME
melt \- author, play, and encode multitrack audio/video compositions
.SH SYNOPSIS
.PP
For more help: <http://www.mltframework.org/>
.SH COPYRIGHT
-Copyright \(co 2002-2011 Ushodaya Enterprises Limited
+Copyright \(co 2002\-2012 Ushodaya Enterprises Limited
<http://www.mltframework.org/>
.br
This is free software; see the source for copying conditions. There is NO
<entry producer="producer0" in="0" out="2999"/>
<blank length="1000"/>
<entry producer="producer0" in="3000" out="6999"/>
+ </playlist>
<playlist id="playlist1">
<blank length="3000"/>
<entry producer="producer1" in="0" out="999"/>
<entry producer="producer0" in="0" out="2999"/>
<blank length="1000"/>
<entry producer="producer0" in="3000" out="6999"/>
+ </playlist>
<playlist id="playlist1">
<blank length="3000"/>
<entry producer="producer1" in="0" out="999"/>
--- /dev/null
+f=mp4
+acodec=aac
+ab=256k
+vn=1
+video_off=1
+meta.preset.extension=m4a
+meta.preset.note=audio only
--- /dev/null
+f=flv
+
+acodec=libmp3lame
+ab=128k
+ar=44100
+
+vcodec=flv
+minrate=0
+vb=1M
+progressive=1
+
+meta.preset.extension=flv
+meta.preset.note=This is the old Sorenson H.263-based codec. Most people use H.264 with Flash now.
--- /dev/null
+f=avi
+vcodec=mjpeg
+qscale=4
+acodec=libmp3lame
+ab=256k
+threads=1
+
+meta.preset.extension=avi
--- /dev/null
+f=mp3
+acodec=mp3
+ab=256k
+vn=1
+video_off=1
+
+meta.preset.extension=mp3
+meta.preset.note=audio only
--- /dev/null
+f=mpeg
+
+acodec=mp2
+ab=256k
+ar=48000
+
+vcodec=mpeg2video
+minrate=0
+vb=8M
+trellis=1
+bf=2
+b_strategy=1
+mbd=rd
+cmp=satd
+subcmp=satd
+
+meta.preset.extension=mpg
+meta.preset.note=a general purpose MPEG-2 preset
--- /dev/null
+f=mp4
+
+acodec=libmp3lame
+ab=128k
+ar=44100
+
+vcodec=mpeg4
+minrate=0
+vb=2M
+mbd=rd
+trellis=1
+flags=+mv4+aic
+cmp=satd
+subcmp=satd
+progressive=1
+
+meta.preset.extension=mp4
+meta.preset.note=Part 2 Simple Profile
--- /dev/null
+f=mp4
+
+acodec=libmp3lame
+ab=128k
+ar=44100
+
+vcodec=mpeg4
+minrate=0
+vb=2M
+mbd=rd
+trellis=1
+cmp=satd
+subcmp=satd
+
+bf=2
+flags=+mv4+aic+qpel
+
+meta.preset.extension=mp4
+meta.preset.note=Part 2 Advanced Simple Profile
threads=0
vpre=medium
preset=medium
-profile=main
+vprofile=main
flags2=-dct8x8
vb=1M
refs=1
bf=1
x264opts=ref=1:bframes=1
+meta.preset.extension=mp4
+meta.preset.note=for Sony PlayStation Portable
--- /dev/null
+f=ogg
+acodec=vorbis
+ab=256k
+vn=1
+video_off=1
+
+meta.preset.name=Ogg Vorbis
+meta.preset.extension=ogg
+meta.preset.note=audio only
--- /dev/null
+f=wav
+acodec=pcm_s16le
+vn=1
+video_off=1
+
+meta.preset.extension=wav
+meta.preset.note=audio only
vtag=xd5c
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=use with mxf or mov
vb=185M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=220M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=175M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=175M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=185M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=220M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=220M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=185M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=220M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=220M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=90M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=175M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=220M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
vb=220M
threads=2
acodec=pcm_s16le
+
+meta.preset.extension=mov
+meta.preset.note=A lightly compressed intermediate codec developed by Avid also known as SMPTE VC-3
acodec=pcm_s16le
+
+meta.preset.extension=mxf
+meta.preset.note=Intra-frame only, 50 Mb/s MPEG-2 also known as Sony IMX or SMPTE 365M
vcodec=dvvideo
acodec=pcm_s16le
+meta.preset.note=The popular standard definition camcorder digital video format
pix_fmt=yuv422p
vcodec=dvvideo
acodec=pcm_s16le
+
+meta.preset.note=Double the amount of chroma as normal DV
me_range=63
trellis=1
+
+meta.preset.extension=vob
+meta.preset.note=Process the output with a DVD authoring tool such as dvdauthor.
acodec=pcm_s16le
+
+meta.preset.extension=mxf
+meta.preset.note=Intra-frame only, 50 Mb/s MPEG-2 also known as Sony IMX or SMPTE 365M
pix_fmt=yuv411p
vcodec=dvvideo
acodec=pcm_s16le
+
+meta.preset.note=The popular standard definition camcorder digital video format
pix_fmt=yuv422p
vcodec=dvvideo
acodec=pcm_s16le
+
+meta.preset.note=Double the amount of chroma as normal DV
me_range=63
trellis=1
+
+meta.preset.extension=vob
+meta.preset.note=Process the output with a DVD authoring tool such as dvdauthor.
acodec=pcm_s16le
+meta.preset.extension=mxf
+meta.preset.note=Intra-frame only, 50 Mb/s MPEG-2 also known as Sony IMX or SMPTE 365M
pix_fmt=yuv420p
vcodec=dvvideo
acodec=pcm_s16le
+
+meta.preset.note=The popular standard definition camcorder digital video format
pix_fmt=yuv422p
vcodec=dvvideo
acodec=pcm_s16le
+
+meta.preset.note=Double the amount of chroma as normal DV
g=15
me_range=63
trellis=1
+
+meta.preset.extension=vob
+meta.preset.note=Process the output with a DVD authoring tool such as dvdauthor.
acodec=pcm_s16le
+meta.preset.extension=mxf
+meta.preset.note=Intra-frame only, 50 Mb/s MPEG-2 also known as Sony IMX or SMPTE 365M
pix_fmt=yuv420p
vcodec=dvvideo
acodec=pcm_s16le
+
+meta.preset.note=The popular standard definition camcorder digital video format
pix_fmt=yuv422p
vcodec=dvvideo
acodec=pcm_s16le
+
+meta.preset.note=Double the amount of chroma as normal DV
me_range=63
trellis=1
+
+meta.preset.extension=vob
+meta.preset.note=Process the output with a DVD authoring tool such as dvdauthor.
--- /dev/null
+f=mpegts
+
+acodec=mp2
+ab=384k
+ar=48000
+ac=2
+
+vcodec=mpeg2video
+vb=25M
+g=15
+trellis=1
+bf=2
+b_strategy=1
+mbd=rd
+cmp=satd
+subcmp=satd
+
+meta.preset.extension=m2t
+meta.preset.note=HD MPEG-2 camcorder format
--- /dev/null
+f=mpegts
+
+acodec=mp2
+ab=384k
+ar=48000
+ac=2
+
+vcodec=mpeg2video
+vb=25M
+g=15
+trellis=1
+bf=2
+b_strategy=1
+mbd=rd
+cmp=satd
+subcmp=satd
+
+meta.preset.extension=m2t
+meta.preset.note=HD MPEG-2 camcorder format
--- /dev/null
+f=mpegts
+
+acodec=mp2
+ab=384k
+ar=48000
+ac=2
+
+vcodec=mpeg2video
+vb=25M
+g=15
+trellis=1
+bf=2
+b_strategy=1
+mbd=rd
+cmp=satd
+subcmp=satd
+
+meta.preset.extension=m2t
+meta.preset.note=HD MPEG-2 camcorder format
--- /dev/null
+f=mpegts
+
+acodec=mp2
+ab=384k
+ar=48000
+ac=2
+
+vcodec=mpeg2video
+vb=25M
+g=15
+trellis=1
+bf=2
+b_strategy=1
+mbd=rd
+cmp=satd
+subcmp=satd
+
+meta.preset.extension=m2t
+meta.preset.note=HD MPEG-2 camcorder format
--- /dev/null
+f=mpegts
+
+acodec=mp2
+ab=384k
+ar=48000
+ac=2
+
+vcodec=mpeg2video
+vb=25M
+g=15
+trellis=1
+bf=2
+b_strategy=1
+mbd=rd
+cmp=satd
+subcmp=satd
+
+meta.preset.extension=m2t
+meta.preset.note=HD MPEG-2 camcorder format
--- /dev/null
+f=mpegts
+
+acodec=mp2
+ab=384k
+ar=48000
+ac=2
+
+vcodec=mpeg2video
+vb=25M
+g=15
+trellis=1
+bf=2
+b_strategy=1
+mbd=rd
+cmp=satd
+subcmp=satd
+
+meta.preset.extension=m2t
+meta.preset.note=HD MPEG-2 camcorder format
--- /dev/null
+f=mpegts
+
+acodec=mp2
+ab=384k
+ar=48000
+ac=2
+
+vcodec=mpeg2video
+vb=25M
+g=15
+trellis=1
+bf=2
+b_strategy=1
+mbd=rd
+cmp=satd
+subcmp=satd
+
+meta.preset.extension=m2t
+meta.preset.note=HD MPEG-2 camcorder format
--- /dev/null
+f=mpegts
+
+acodec=mp2
+ab=384k
+ar=48000
+ac=2
+
+vcodec=mpeg2video
+vb=25M
+g=15
+trellis=1
+bf=2
+b_strategy=1
+mbd=rd
+cmp=satd
+subcmp=satd
+
+meta.preset.extension=m2t
+meta.preset.note=HD MPEG-2 camcorder format
--- /dev/null
+f=mkv
+acodec=flac
+vcodec=ffv1
+threads=1
+
+meta.preset.extension=mkv
+meta.preset.note=FFmpeg video codec 1 with FLAC audio in Matroska container
--- /dev/null
+f=mp4
+acodec=aac
+ab=384k
+vcodec=libx264
+intra=1
+vb=0
+g=0
+bf=0
+preset=medium
+qscale=1
+qp=0
+coder=ac
+
+meta.preset.extension=mp4
+meta.preset.note=Intra-frame only, lossless compressed MPEG-4 AVC with AAC audio
--- /dev/null
+f=mkv
+acodec=flac
+vcodec=huffyuv
+
+meta.preset.extension=mkv
+meta.preset.note=with FLAC audio in Matroska container
--- /dev/null
+progressive=1
+f=avi
+acodec=pcm_s16le
+vcodec=mjpeg
+qscale=1
+threads=1
+
+meta.preset.extension=avi
+meta.preset.note=not lossless, but still high quality
--- /dev/null
+f=mpeg
+acodec=ac3
+ab=512k
+vcodec=mpeg2video
+intra=1
+vb=0
+g=0
+bf=0
+qscale=1
+
+meta.preset.extension=mpg
+meta.preset.note=a little lossy, but intra-frame only with AC-3 audio
--- /dev/null
+f=avi
+acodec=pcm_s16le
+vcodec=mpeg4
+qscale=1
+intra=1
+g=0
+vb=0
+bf=0
+
+meta.preset.extension=avi
+meta.preset.note=somewhat lossy, intra-frame only MPEG-4, with uncompressed audio
--- /dev/null
+f=mov
+acodec=pcm_s16le
+vcodec=prores
+vb=0
+g=0
+bf=0
+threads=1
+vprofile=2
+
+meta.preset.extension=mov
+meta.preset.note=Designed by Apple in California. Set vprofile=1 for LT or =3 for HQ.
--- /dev/null
+progressive=1
+f=image2
+vcodec=bmp
+an=1
+audio_off=1
+
+meta.preset.extension=bmp
--- /dev/null
+progressive=1
+f=image2
+vcodec=dpx
+an=1
+audio_off=1
+
+meta.preset.extension=dpx
--- /dev/null
+progressive=1
+f=image2
+vcodec=mjpeg
+qscale=1
+an=1
+audio_off=1
+
+meta.preset.extension=jpg
--- /dev/null
+progressive=1
+f=image2
+vcodec=png
+an=1
+audio_off=1
+
+meta.preset.extension=png
--- /dev/null
+progressive=1
+f=image2
+vcodec=ppm
+an=1
+audio_off=1
+
+meta.preset.extension=ppm
--- /dev/null
+progressive=1
+f=image2
+vcodec=targa
+an=1
+audio_off=1
+
+meta.preset.extension=tga
--- /dev/null
+progressive=1
+f=image2
+vcodec=tiff
+an=1
+audio_off=1
+
+meta.preset.extension=tif
f=webm
+
+acodec=vorbis
ab=128k
vcodec=libvpx
rc_lookahead=16
quality=good
speed=0
-profile=0
+vprofile=0
qmax=51
qmin=11
slices=4
arnr_max_frames=7
arnr_strength=5
arnr_type=3
+
+meta.preset.name=WebM
+meta.preset.extension=webm
+meta.preset.note=VP8 video with Ogg Vorbis audio in Matroska container: "Don't be evil"
+f=mp4
+
+acodec=aac
+ab=256k
+
vcodec=libx264
threads=0
vpre=medium
preset=medium
+
+meta.preset.extension=mp4
+meta.preset.name=H.264 High Profile
+f=mp4
+
+acodec=aac
+ab=256k
+
vcodec=libx264
threads=0
vpre=medium
preset=medium
-profile=baseline
+vprofile=baseline
coder=0
bf=0
flags2=-wpred-dct8x8
wpredp=0
+
+meta.preset.extension=mp4
+meta.preset.name=H.264 Baseline Profile
+f=mp4
+
+acodec=aac
+ab=256k
+
vcodec=libx264
threads=0
vpre=medium
preset=medium
-profile=main
+vprofile=main
flags2=-dct8x8
+
+meta.preset.extension=mp4
+meta.preset.name=H.264 Main Profile
+f=mp4
+
vcodec=libx264
threads=0
vpre=medium
flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip
pass=1
an=1
+audio_off=1
+
+meta.preset.hidden=1
clean:
install: all uninstall
- install -d "$(DESTDIR)$(datadir)/mlt/profiles"
- install -m 644 * "$(DESTDIR)$(datadir)/mlt/profiles"
- rm -f "$(DESTDIR)$(datadir)/mlt/profiles/"*~
- rm -f "$(DESTDIR)$(datadir)/mlt/profiles/Makefile"
+ install -d "$(DESTDIR)$(mltdatadir)/profiles"
+ install -m 644 * "$(DESTDIR)$(mltdatadir)/profiles"
+ rm -f "$(DESTDIR)$(mltdatadir)/profiles/"*~
+ rm -f "$(DESTDIR)$(mltdatadir)/profiles/Makefile"
uninstall:
- rm -rf "$(DESTDIR)$(datadir)/mlt/profiles"
+ rm -rf "$(DESTDIR)$(mltdatadir)/profiles"
TARGET = $(NAME).$(version)
SONAME = $(NAME).$(soversion)
SHFLAGS += -Wl,-soname,$(SONAME)
- ifeq ($(targetos), FreeBSD)
- ifdef HAVE_SYS_PARAM_H
- CFLAGS += -DHAVE_SYS_PARAM_H
- endif
- endif
+endif
+
+ifeq ($(targetos), Linux)
+SHFLAGS += -Wl,--version-script=mlt.vers
endif
OBJS = mlt_frame.o \
SRCS += ../win32/win32.c
endif
-CFLAGS += $(RDYNAMIC) -DPREFIX="\"$(prefix)\"" -DLIBDIR="\"$(libdir)\"" -DMLTDATADIR="\"$(datadir)\""
+CFLAGS += $(RDYNAMIC) -DPREFIX_DATA="\"$(mltdatadir)\"" -DPREFIX_LIB="\"$(moduledir)\""
LDFLAGS += $(LIBDL) -lpthread
fi
install -d "$(DESTDIR)$(prefix)/include/mlt/framework"
install -m 644 $(INCS) "$(DESTDIR)$(prefix)/include/mlt/framework"
- install -d "$(DESTDIR)$(datadir)/mlt"
- install -m 644 metaschema.yaml "$(DESTDIR)$(datadir)/mlt/"
+ install -d "$(DESTDIR)$(mltdatadir)"
+ install -m 644 metaschema.yaml "$(DESTDIR)$(mltdatadir)"
uninstall:
rm -f "$(DESTDIR)$(libdir)/$(TARGET)"
rm -f "$(DESTDIR)$(libdir)/$(NAME)" ; \
fi
rm -rf "$(DESTDIR)$(prefix)/include/mlt/framework"
- rm -f "$(DESTDIR)$(datadir)/mlt/metaschema.yaml"
+ rm -f "$(DESTDIR)$(mltdatadir)/metaschema.yaml"
ifneq ($(wildcard .depend),)
include .depend
#!/bin/sh
echo "framework -I$prefix/include -I$prefix/include/mlt -D_REENTRANT -L$libdir -lmlt" >> ../../packages.dat
-echo -n > config.mak
-if [ "$(uname -s)" = "FreeBSD" ]
-then
- printf "#include <sys/param.h>\n int main(){ return 0;}" | gcc -c -x c - >/dev/null 2>&1
- [ "$?" -eq 0 ] && echo "HAVE_SYS_PARAM_H=1" >> config.mak
-fi
-exit 0
+echo > config.mak
--- /dev/null
+MLT_0.8.8 {
+ global:
+ default_callback;
+ mlt_audio_format_name;
+ mlt_audio_format_size;
+ mlt_cache_close;
+ mlt_cache_get;
+ mlt_cache_get_frame;
+ mlt_cache_get_size;
+ mlt_cache_init;
+ mlt_cache_item_close;
+ mlt_cache_item_data;
+ mlt_cache_purge;
+ mlt_cache_put;
+ mlt_cache_put_frame;
+ mlt_cache_set_size;
+ mlt_consumer_close;
+ mlt_consumer_connect;
+ mlt_consumer_get_frame;
+ mlt_consumer_init;
+ mlt_consumer_is_stopped;
+ mlt_consumer_new;
+ mlt_consumer_position;
+ mlt_consumer_properties;
+ mlt_consumer_purge;
+ mlt_consumer_put_frame;
+ mlt_consumer_rt_frame;
+ mlt_consumer_service;
+ mlt_consumer_start;
+ mlt_consumer_stop;
+ mlt_consumer_stopped;
+ mlt_deque_close;
+ mlt_deque_count;
+ mlt_deque_init;
+ mlt_deque_insert;
+ mlt_deque_peek;
+ mlt_deque_peek_back;
+ mlt_deque_peek_back_double;
+ mlt_deque_peek_back_int;
+ mlt_deque_peek_front;
+ mlt_deque_peek_front_double;
+ mlt_deque_peek_front_int;
+ mlt_deque_pop_back;
+ mlt_deque_pop_back_double;
+ mlt_deque_pop_back_int;
+ mlt_deque_pop_front;
+ mlt_deque_pop_front_double;
+ mlt_deque_pop_front_int;
+ mlt_deque_push_back;
+ mlt_deque_push_back_double;
+ mlt_deque_push_back_int;
+ mlt_deque_push_front;
+ mlt_deque_push_front_double;
+ mlt_deque_push_front_int;
+ mlt_environment;
+ mlt_environment_set;
+ mlt_event_block;
+ mlt_event_close;
+ mlt_event_inc_ref;
+ mlt_events_block;
+ mlt_events_close_wait_for;
+ mlt_events_disconnect;
+ mlt_events_fire;
+ mlt_events_init;
+ mlt_events_listen;
+ mlt_events_register;
+ mlt_events_setup_wait_for;
+ mlt_events_unblock;
+ mlt_events_wait_for;
+ mlt_event_unblock;
+ mlt_factory_close;
+ mlt_factory_consumer;
+ mlt_factory_directory;
+ mlt_factory_event_object;
+ mlt_factory_filter;
+ mlt_factory_init;
+ mlt_factory_producer;
+ mlt_factory_register_for_clean_up;
+ mlt_factory_transition;
+ mlt_field_close;
+ mlt_field_disconnect_service;
+ mlt_field_init;
+ mlt_field_multitrack;
+ mlt_field_new;
+ mlt_field_plant_filter;
+ mlt_field_plant_transition;
+ mlt_field_properties;
+ mlt_field_service;
+ mlt_field_tractor;
+ mlt_filter_close;
+ mlt_filter_connect;
+ mlt_filter_get_in;
+ mlt_filter_get_length;
+ mlt_filter_get_length2;
+ mlt_filter_get_out;
+ mlt_filter_get_position;
+ mlt_filter_get_progress;
+ mlt_filter_get_track;
+ mlt_filter_init;
+ mlt_filter_new;
+ mlt_filter_process;
+ mlt_filter_properties;
+ mlt_filter_service;
+ mlt_filter_set_in_and_out;
+ mlt_frame_clone;
+ mlt_frame_close;
+ mlt_frame_get_alpha_mask;
+ mlt_frame_get_aspect_ratio;
+ mlt_frame_get_audio;
+ mlt_frame_get_image;
+ mlt_frame_get_original_producer;
+ mlt_frame_get_position;
+ mlt_frame_get_waveform;
+ mlt_frame_init;
+ mlt_frame_is_test_audio;
+ mlt_frame_is_test_card;
+ mlt_frame_original_position;
+ mlt_frame_pop_audio;
+ mlt_frame_pop_frame;
+ mlt_frame_pop_get_image;
+ mlt_frame_pop_service;
+ mlt_frame_pop_service_int;
+ mlt_frame_properties;
+ mlt_frame_push_audio;
+ mlt_frame_push_frame;
+ mlt_frame_push_get_image;
+ mlt_frame_push_service;
+ mlt_frame_push_service_int;
+ mlt_frame_replace_image;
+ mlt_frame_service_stack;
+ mlt_frame_set_alpha;
+ mlt_frame_set_aspect_ratio;
+ mlt_frame_set_audio;
+ mlt_frame_set_image;
+ mlt_frame_set_position;
+ mlt_frame_unique_properties;
+ mlt_frame_write_ppm;
+ mlt_geometry_close;
+ mlt_geometry_fetch;
+ mlt_geometry_get_length;
+ mlt_geometry_init;
+ mlt_geometry_insert;
+ mlt_geometry_interpolate;
+ mlt_geometry_next_key;
+ mlt_geometry_parse;
+ mlt_geometry_parse_item;
+ mlt_geometry_prev_key;
+ mlt_geometry_refresh;
+ mlt_geometry_remove;
+ mlt_geometry_serialise;
+ mlt_geometry_serialise_cut;
+ mlt_geometry_set_length;
+ mlt_global_properties;
+ mlt_image_format_name;
+ mlt_image_format_size;
+ mlt_log;
+ mlt_log_get_level;
+ mlt_log_set_callback;
+ mlt_log_set_level;
+ mlt_multitrack_clip;
+ mlt_multitrack_close;
+ mlt_multitrack_connect;
+ mlt_multitrack_count;
+ mlt_multitrack_init;
+ mlt_multitrack_producer;
+ mlt_multitrack_properties;
+ mlt_multitrack_refresh;
+ mlt_multitrack_service;
+ mlt_multitrack_track;
+ mlt_parser_close;
+ mlt_parser_new;
+ mlt_parser_properties;
+ mlt_parser_start;
+ mlt_playlist_append;
+ mlt_playlist_append_io;
+ mlt_playlist_blank;
+ mlt_playlist_blanks_from;
+ mlt_playlist_blank_time;
+ mlt_playlist_clear;
+ mlt_playlist_clip;
+ mlt_playlist_clip_is_mix;
+ mlt_playlist_clip_length;
+ mlt_playlist_clip_start;
+ mlt_playlist_close;
+ mlt_playlist_consolidate_blanks;
+ mlt_playlist_count;
+ mlt_playlist_current;
+ mlt_playlist_current_clip;
+ mlt_playlist_get_clip;
+ mlt_playlist_get_clip_at;
+ mlt_playlist_get_clip_index_at;
+ mlt_playlist_get_clip_info;
+ mlt_playlist_init;
+ mlt_playlist_insert;
+ mlt_playlist_insert_at;
+ mlt_playlist_insert_blank;
+ mlt_playlist_is_blank;
+ mlt_playlist_is_blank_at;
+ mlt_playlist_join;
+ mlt_playlist_mix;
+ mlt_playlist_mix_add;
+ mlt_playlist_move;
+ mlt_playlist_move_region;
+ mlt_playlist_new;
+ mlt_playlist_pad_blanks;
+ mlt_playlist_producer;
+ mlt_playlist_properties;
+ mlt_playlist_remove;
+ mlt_playlist_remove_region;
+ mlt_playlist_repeat_clip;
+ mlt_playlist_replace_with_blank;
+ mlt_playlist_resize_clip;
+ mlt_playlist_service;
+ mlt_playlist_split;
+ mlt_playlist_split_at;
+ mlt_pool_alloc;
+ mlt_pool_close;
+ mlt_pool_init;
+ mlt_pool_purge;
+ mlt_pool_realloc;
+ mlt_pool_release;
+ mlt_producer_attach;
+ mlt_producer_clear;
+ mlt_producer_close;
+ mlt_producer_cut;
+ mlt_producer_cut_parent;
+ mlt_producer_detach;
+ mlt_producer_filter;
+ mlt_producer_frame;
+ mlt_producer_frame_time;
+ mlt_producer_get_fps;
+ mlt_producer_get_in;
+ mlt_producer_get_length;
+ mlt_producer_get_length_time;
+ mlt_producer_get_out;
+ mlt_producer_get_playtime;
+ mlt_producer_get_speed;
+ mlt_producer_init;
+ mlt_producer_is_blank;
+ mlt_producer_is_cut;
+ mlt_producer_is_mix;
+ mlt_producer_new;
+ mlt_producer_optimise;
+ mlt_producer_position;
+ mlt_producer_prepare_next;
+ mlt_producer_properties;
+ mlt_producer_seek;
+ mlt_producer_seek_time;
+ mlt_producer_service;
+ mlt_producer_set_in_and_out;
+ mlt_producer_set_speed;
+ mlt_profile_clone;
+ mlt_profile_close;
+ mlt_profile_dar;
+ mlt_profile_fps;
+ mlt_profile_from_producer;
+ mlt_profile_init;
+ mlt_profile_list;
+ mlt_profile_load_file;
+ mlt_profile_load_properties;
+ mlt_profile_load_string;
+ mlt_profile_sar;
+ mlt_properties_close;
+ mlt_properties_count;
+ mlt_properties_debug;
+ mlt_properties_dec_ref;
+ mlt_properties_dir_list;
+ mlt_properties_dump;
+ mlt_properties_get;
+ mlt_properties_get_data;
+ mlt_properties_get_data_at;
+ mlt_properties_get_double;
+ mlt_properties_get_int;
+ mlt_properties_get_int64;
+ mlt_properties_get_lcnumeric;
+ mlt_properties_get_name;
+ mlt_properties_get_position;
+ mlt_properties_get_time;
+ mlt_properties_get_value;
+ mlt_properties_inc_ref;
+ mlt_properties_inherit;
+ mlt_properties_init;
+ mlt_properties_is_sequence;
+ mlt_properties_load;
+ mlt_properties_lock;
+ mlt_properties_mirror;
+ mlt_properties_new;
+ mlt_properties_parse;
+ mlt_properties_parse_yaml;
+ mlt_properties_pass;
+ mlt_properties_pass_list;
+ mlt_properties_pass_property;
+ mlt_properties_preset;
+ mlt_properties_ref_count;
+ mlt_properties_rename;
+ mlt_properties_save;
+ mlt_properties_serialise_yaml;
+ mlt_properties_set;
+ mlt_properties_set_data;
+ mlt_properties_set_double;
+ mlt_properties_set_int;
+ mlt_properties_set_int64;
+ mlt_properties_set_lcnumeric;
+ mlt_properties_set_or_default;
+ mlt_properties_set_position;
+ mlt_properties_unlock;
+ mlt_property_close;
+ mlt_property_get_data;
+ mlt_property_get_double;
+ mlt_property_get_int;
+ mlt_property_get_int64;
+ mlt_property_get_position;
+ mlt_property_get_string;
+ mlt_property_get_string_l;
+ mlt_property_get_time;
+ mlt_property_init;
+ mlt_property_pass;
+ mlt_property_set_data;
+ mlt_property_set_double;
+ mlt_property_set_int;
+ mlt_property_set_int64;
+ mlt_property_set_position;
+ mlt_property_set_string;
+ mlt_repository_close;
+ mlt_repository_consumers;
+ mlt_repository_create;
+ mlt_repository_filters;
+ mlt_repository_init;
+ mlt_repository_languages;
+ mlt_repository_metadata;
+ mlt_repository_presets;
+ mlt_repository_producers;
+ mlt_repository_register;
+ mlt_repository_register_metadata;
+ mlt_repository_transitions;
+ mlt_sample_calculator;
+ mlt_sample_calculator_to_now;
+ mlt_sdl_mutex;
+ mlt_service_apply_filters;
+ mlt_service_attach;
+ mlt_service_cache_get;
+ mlt_service_cache_get_size;
+ mlt_service_cache_purge;
+ mlt_service_cache_put;
+ mlt_service_cache_set_size;
+ mlt_service_close;
+ mlt_service_connect_producer;
+ mlt_service_consumer;
+ mlt_service_detach;
+ mlt_service_filter;
+ mlt_service_get_frame;
+ mlt_service_get_producer;
+ mlt_service_identify;
+ mlt_service_init;
+ mlt_service_lock;
+ mlt_service_producer;
+ mlt_service_profile;
+ mlt_service_properties;
+ mlt_service_set_profile;
+ mlt_service_unlock;
+ mlt_tokeniser_close;
+ mlt_tokeniser_count;
+ mlt_tokeniser_get_input;
+ mlt_tokeniser_get_string;
+ mlt_tokeniser_init;
+ mlt_tokeniser_parse_new;
+ mlt_tractor_close;
+ mlt_tractor_connect;
+ mlt_tractor_field;
+ mlt_tractor_get_track;
+ mlt_tractor_init;
+ mlt_tractor_multitrack;
+ mlt_tractor_new;
+ mlt_tractor_producer;
+ mlt_tractor_properties;
+ mlt_tractor_refresh;
+ mlt_tractor_service;
+ mlt_tractor_set_track;
+ mlt_transition_close;
+ mlt_transition_connect;
+ mlt_transition_get_a_track;
+ mlt_transition_get_b_track;
+ mlt_transition_get_in;
+ mlt_transition_get_length;
+ mlt_transition_get_out;
+ mlt_transition_get_position;
+ mlt_transition_get_progress;
+ mlt_transition_get_progress_delta;
+ mlt_transition_init;
+ mlt_transition_new;
+ mlt_transition_process;
+ mlt_transition_properties;
+ mlt_transition_service;
+ mlt_transition_set_in_and_out;
+ mlt_version_get_int;
+ mlt_version_get_major;
+ mlt_version_get_minor;
+ mlt_version_get_revision;
+ mlt_version_get_string;
+ mlt_vlog;
+
+ local: *;
+};
+
+MLT_0.9.0 {
+ global:
+ "mlt_service_filter_count";
+} MLT_0.8.8;
/**
- * \file mlt_profile.c
+ * \file mlt_cache.c
* \brief least recently used cache
* \see mlt_profile_s
*
- * Copyright (C) 2007-2009 Ushodaya Enterprises Limited
+ * Copyright (C) 2007-2012 Ushodaya Enterprises Limited
* \author Dan Dennedy <dan@dennedy.org>
*
* This library is free software; you can redistribute it and/or
#include "mlt_log.h"
#include "mlt_properties.h"
#include "mlt_cache.h"
+#include "mlt_frame.h"
#include <stdlib.h>
#include <pthread.h>
#define MAX_CACHE_SIZE (200)
/** the default number of data objects to cache per line */
-#define DEFAULT_CACHE_SIZE (10)
+#define DEFAULT_CACHE_SIZE (4)
/** \brief Cache item class
*
{
int count; /**< the number of items currently in the cache */
int size; /**< the maximum number of items permitted in the cache <= \p MAX_CACHE_SIZE */
+ int is_frames; /**< indicates if this cache is used to cache frames */
void* *current; /**< pointer to the current array of pointers */
void* A[ MAX_CACHE_SIZE ];
void* B[ MAX_CACHE_SIZE ];
{
char key[19];
+ if ( cache->is_frames )
+ {
+ // Frame caches are easy - just close the object as mlt_frame.
+ mlt_frame_close( object );
+ return;
+ }
+
// Fetch the cache item from the active list by its owner's address
sprintf( key, "%p", object );
mlt_cache_item item = mlt_properties_get_data( cache->active, key, NULL );
void mlt_cache_purge( mlt_cache cache, void *object )
{
+ if (!cache) return;
pthread_mutex_lock( &cache->mutex );
if ( cache && object )
{
}
/** Put a chunk of data in the cache.
+ *
+ * This function and mlt_cache_get() are not scalable with a large volume
+ * of unique \p object paramter values. Therefore, it does not make sense
+ * to use it for a frame/image cache using the frame position for \p object.
+ * Instead, use mlt_cache_put_frame() for that.
*
* \public \memberof mlt_cache_s
* \param cache a cache object
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 );
+ 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;
return result;
}
+
+/** Shuffle the cache entries between the two arrays and return the frame for a position.
+ *
+ * \private \memberof mlt_cache_s
+ * \param cache a cache object
+ * \param position the position of the frame that you want
+ * \return a frame if there was a hit or NULL for a miss
+ */
+
+static mlt_frame* shuffle_get_frame( mlt_cache cache, mlt_position position )
+{
+ int i = cache->count;
+ int j = cache->count - 1;
+ mlt_frame *hit = NULL;
+ mlt_frame *alt = (mlt_frame*) ( 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 )
+ {
+ mlt_frame *o = (mlt_frame*) &cache->current[ i ];
+ if ( mlt_frame_original_position( *o ) == position )
+ 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-- )
+ {
+ mlt_frame *o = (mlt_frame*) &cache->current[ i ];
+
+ if ( !hit && mlt_frame_original_position( *o ) == position )
+ {
+ 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 frame in the cache.
+ *
+ * Unlike mlt_cache_put() this version is more suitable for caching frames
+ * and their data - like images. However, this version does not use reference
+ * counting and garbage collection. Rather, frames are cloned with deep copy
+ * to avoid those things.
+ *
+ * \public \memberof mlt_cache_s
+ * \param cache a cache object
+ * \param frame the frame to cache
+ * \see mlt_frame_get_frame
+ */
+
+void mlt_cache_put_frame( mlt_cache cache, mlt_frame frame )
+{
+ pthread_mutex_lock( &cache->mutex );
+ mlt_frame *hit = shuffle_get_frame( cache, mlt_frame_original_position( frame ) );
+ mlt_frame *alt = (mlt_frame*) ( cache->current == cache->A ? cache->B : cache->A );
+
+ // add the frame to the cache
+ if ( hit )
+ {
+ // release the old data
+ mlt_frame_close( *hit );
+ // 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
+ mlt_frame_close( cache->current[0] );
+
+ // The MRU end gets the new item
+ hit = &alt[ cache->count - 1 ];
+ }
+ *hit = mlt_frame_clone( frame, 1 );
+ mlt_log( NULL, MLT_LOG_DEBUG, "%s: put %d = %p\n", __FUNCTION__, cache->count - 1, frame );
+
+ // swap the current array
+ cache->current = (void**) alt;
+ cache->is_frames = 1;
+ pthread_mutex_unlock( &cache->mutex );
+}
+
+/** Get a frame from the cache.
+ *
+ * You must call mlt_frame_close() on the frame you receive from this.
+ *
+ * \public \memberof mlt_cache_s
+ * \param cache a cache object
+ * \param position the position of the frame that you want
+ * \return a frame if found or NULL if not found or has been flushed from the cache
+ * \see mlt_frame_put_frame
+ */
+
+mlt_frame mlt_cache_get_frame( mlt_cache cache, mlt_position position )
+{
+ mlt_frame result = NULL;
+ pthread_mutex_lock( &cache->mutex );
+ mlt_frame *hit = shuffle_get_frame( cache, position );
+ mlt_frame *alt = (mlt_frame*) ( 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 ];
+
+ result = mlt_frame_clone( *hit, 1 );
+ mlt_log( NULL, MLT_LOG_DEBUG, "%s: get %d = %p\n", __FUNCTION__, cache->count - 1, *hit );
+
+ // swap the current array
+ cache->current = (void**) alt;
+ }
+ pthread_mutex_unlock( &cache->mutex );
+
+ return result;
+}
* \brief least recently used cache
* \see mlt_cache_s
*
- * Copyright (C) 2007-2009 Ushodaya Enterprises Limited
+ * Copyright (C) 2007-2012 Ushodaya Enterprises Limited
* \author Dan Dennedy <dan@dennedy.org>
*
* This library is free software; you can redistribute it and/or
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 );
+extern void mlt_cache_put_frame( mlt_cache cache, mlt_frame frame );
+extern mlt_frame mlt_cache_get_frame( mlt_cache cache, mlt_position position );
#endif
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-thread-started", NULL );
+ mlt_events_register( properties, "consumer-thread-stopped", NULL );
mlt_events_register( properties, "consumer-stopped", NULL );
mlt_events_listen( properties, self, "consumer-frame-show", ( mlt_listener )on_consumer_frame_show );
free( profile->description );
memcpy( profile, new_profile, sizeof( struct mlt_profile_s ) );
profile->description = strdup( new_profile->description );
- mlt_profile_close( new_profile );
}
else
{
// Apply to properties
apply_profile_properties( self, profile, properties );
+ mlt_profile_close( new_profile );
}
}
else if ( !strcmp( name, "frame_rate_num" ) )
{
mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
- profile->sample_aspect_num = mlt_properties_get_int( properties, "sample_aspect_num" );
if ( profile )
+ {
+ profile->sample_aspect_num = mlt_properties_get_int( properties, "sample_aspect_num" );
mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );
+ }
}
else if ( !strcmp( name, "sample_aspect_den" ) )
{
mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
- profile->sample_aspect_den = mlt_properties_get_int( properties, "sample_aspect_den" );
if ( profile )
+ {
+ profile->sample_aspect_den = mlt_properties_get_int( properties, "sample_aspect_den" );
mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );
+ }
}
else if ( !strcmp( name, "display_aspect_num" ) )
{
* \private \memberof mlt_consumer_s
* \param listener a function pointer that will be invoked
* \param owner the events object that will be passed to \p listener
- * \param self 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
+ * \param self a service that will be passed to \p listener
+ * \param args an array of pointers - the first entry is passed as a frame to \p listener
*/
static void mlt_consumer_frame_show( mlt_listener listener, mlt_properties owner, mlt_service self, void **args )
* \private \memberof mlt_consumer_s
* \param listener a function pointer that will be invoked
* \param owner the events object that will be passed to \p listener
- * \param self 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
+ * \param self a service that will be passed to \p listener
+ * \param args an array of pointers - the first entry is passed as a frame to \p listener
*/
static void mlt_consumer_frame_render( mlt_listener listener, mlt_properties owner, mlt_service self, void **args )
mlt_consumer self = malloc( sizeof( struct mlt_consumer_s ) );
// Initialise it
- if ( self != NULL )
- mlt_consumer_init( self, NULL, profile );
-
- // Return it
- return self;
+ if ( self != NULL && mlt_consumer_init( self, NULL, profile ) == 0 )
+ {
+ // Return it
+ return self;
+ }
+ else
+ {
+ free(self);
+ return NULL;
+ }
}
/** Get the parent service object.
char *test_card = mlt_properties_get( properties, "test_card" );
// Just to make sure nothing is hanging around...
+ pthread_mutex_lock( &self->put_mutex );
self->put = NULL;
self->put_active = 1;
+ pthread_mutex_unlock( &self->put_mutex );
// Deal with it now.
if ( test_card != NULL )
mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL );
}
+ // The profile could have changed between a stop and a restart.
+ apply_profile_properties( self, mlt_service_profile( MLT_CONSUMER_SERVICE(self) ), properties );
+
// 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" );
+ int frame_rate_num = mlt_properties_get_int( properties, "frame_rate_num" );
+ int frame_rate_den = mlt_properties_get_int( properties, "frame_rate_den" );
+ int frame_duration = 0;
+
+ if ( frame_rate_num && frame_rate_den )
+ {
+ frame_duration = 1000000 / frame_rate_num * frame_rate_den;
+ }
+
mlt_properties_set_int( properties, "frame_duration", frame_duration );
// Check and run an ante command
self->format = mlt_image_yuv420p;
else if ( !strcmp( format, "none" ) )
self->format = mlt_image_none;
+ else if ( !strcmp( format, "glsl" ) )
+ self->format = mlt_image_glsl_texture;
else
self->format = mlt_image_yuv422;
}
if ( test_card != NULL )
mlt_properties_set_data( frame_properties, "test_card_producer", test_card, 0, NULL, NULL );
- // Attach the rescale property
+ // Pass along the interpolation and deinterlace options
+ // TODO: get rid of consumer_deinterlace and use profile.progressive
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" ) );
mlt_properties_set_int( frame_properties, "consumer_tff", mlt_properties_get_int( properties, "top_field_first" ) );
afmt = mlt_audio_float;
else if ( !strcmp( format, "f32le" ) )
afmt = mlt_audio_f32le;
+ else if ( !strcmp( format, "u8" ) )
+ afmt = mlt_audio_u8;
}
int counter = 0;
double fps = mlt_properties_get_double( properties, "fps" );
if ( preview_off && preview_format != 0 )
self->format = preview_format;
+ mlt_events_fire( properties, "consumer-thread-started", NULL );
+
// Get the first frame
frame = mlt_consumer_get_frame( self );
// Remove the last frame
mlt_frame_close( frame );
+ mlt_events_fire( properties, "consumer-thread-stopped", NULL );
return NULL;
}
if ( preview_off && preview_format != 0 )
format = preview_format;
+ mlt_events_fire( properties, "consumer-thread-started", NULL );
+
// Continue to read ahead
while ( self->ahead )
{
pthread_cond_broadcast( &self->done_cond );
pthread_mutex_unlock( &self->done_mutex );
}
+ mlt_events_fire( properties, "consumer-thread-stopped" );
return NULL;
}
// We're running now
self->ahead = 1;
+ self->threads = thread;
// These keep track of the accelleration of frame dropping or recovery.
self->consecutive_dropped = 0;
pthread_join( *thread, NULL );
// Deallocate the array of threads
- if ( thread )
- free( thread );
+ if ( self->threads )
+ free( self->threads );
// Indicate that worker threads no longer running
self->started = 0;
void mlt_consumer_purge( mlt_consumer self )
{
- if ( self->ahead )
+ if ( self && self->ahead )
{
- pthread_mutex_lock( &self->queue_mutex );
+ if ( self->ahead && self->real_time )
+ pthread_mutex_lock( &self->queue_mutex );
while ( mlt_deque_count( self->queue ) )
mlt_frame_close( mlt_deque_pop_back( self->queue ) );
- pthread_cond_broadcast( &self->queue_cond );
- pthread_mutex_unlock( &self->queue_mutex );
+ if ( self->ahead && self->real_time ) {
+ pthread_cond_broadcast( &self->queue_cond );
+ pthread_mutex_unlock( &self->queue_mutex );
+ }
}
}
}
else // real_time == 0
{
+ if ( !self->ahead )
+ {
+ self->ahead = 1;
+ mlt_events_fire( properties, "consumer-thread-started", NULL );
+ }
// Get the frame in non real time
frame = mlt_consumer_get_frame( self );
int mlt_consumer_is_stopped( mlt_consumer self )
{
// Check if the consumer is stopped
- if ( self->is_stopped != NULL )
+ if ( self && self->is_stopped )
return self->is_stopped( self );
return 0;
* \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
+ * \event \em consumer-frame-show Subclass implementations fire this immediately after showing a frame
+ * or when a frame should be shown (if audio-only consumer).
+ * \event \em consumer-frame-render The base class fires this immediately before rendering a frame.
+ * \event \em consumer-thread-started The base class fires when beginning execution of a rendering thread.
+ * \event \em consumer-thread-stopped The base class fires when a rendering thread has ended.
+ * \event \em consumer-stopped This is fired when the subclass implementation calls mlt_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 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
* \properties \em priority the OS scheduling priority for the render threads when real_time is not 0.
- * \properties \em top_field_first when not progressive, whether interlace field order is top-field-first, defaults to 0
+ * \properties \em top_field_first when not progressive, whether interlace field order is top-field-first, defaults to 0.
+ * Set this to -1 if the consumer does not care about the field order.
* \properties \em mlt_image_format the image format to request in rendering threads, defaults to yuv422
* \properties \em mlt_audio_format the audio format to request in rendering threads, defaults to S16
*/
int consecutive_rendered;
int process_head;
int started;
+ pthread_t *threads; /**< \private used to deallocate all threads */
};
#define MLT_CONSUMER_SERVICE( consumer ) ( &( consumer )->parent )
mlt_deque mlt_deque_init( )
{
- mlt_deque self = malloc( sizeof( struct mlt_deque_s ) );
- if ( self != NULL )
- {
- self->list = NULL;
- self->size = 0;
- self->count = 0;
- }
+ mlt_deque self = calloc( 1, sizeof( struct mlt_deque_s ) );
return self;
}
int mlt_deque_count( mlt_deque self )
{
- return self->count;
+ if ( self )
+ return self->count;
+ else
+ return 0;
}
/** Allocate space on the deque.
mlt_events events = mlt_events_fetch( self );
if ( events == NULL )
{
- events = malloc( sizeof( struct mlt_events_struct ) );
+ events = calloc( 1, sizeof( struct mlt_events_struct ) );
events->list = mlt_properties_new( );
mlt_events_store( self, events );
}
typedef struct
{
- int done;
pthread_cond_t cond;
pthread_mutex_t mutex;
}
static void mlt_events_listen_for( mlt_properties self, condition_pair *pair )
{
pthread_mutex_lock( &pair->mutex );
- if ( pair->done == 0 )
- {
- pthread_cond_signal( &pair->cond );
- pthread_mutex_unlock( &pair->mutex );
- }
+ pthread_cond_signal( &pair->cond );
+ pthread_mutex_unlock( &pair->mutex );
}
/** Prepare to wait for an event.
mlt_event mlt_events_setup_wait_for( mlt_properties self, 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 );
{
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 );
+ free( pair );
}
}
#define PREFIX_LIB "/lib/mlt"
/** the default subdirectory of the install prefix for holding module (plugin) data */
#define PREFIX_DATA "/share/mlt"
-#else
-/** 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 MLTDATADIR "/mlt"
#endif
/** holds the full path to the modules directory - initialized and retained for the entire session */
mlt_field mlt_field_init( )
{
// Initialise the field
- mlt_field self = calloc( sizeof( struct mlt_field_s ), 1 );
+ mlt_field self = calloc( 1, sizeof( struct mlt_field_s ) );
// Initialise it
if ( self != NULL )
mlt_field mlt_field_new( mlt_multitrack multitrack, mlt_tractor tractor )
{
// Initialise the field
- mlt_field self = calloc( sizeof( struct mlt_field_s ), 1 );
+ mlt_field self = calloc( 1, sizeof( struct mlt_field_s ) );
// Initialise it
if ( self != NULL )
mlt_filter mlt_filter_new( )
{
mlt_filter self = calloc( 1, sizeof( struct mlt_filter_s ) );
- if ( self != NULL )
- mlt_filter_init( self, NULL );
- return self;
+ if ( self != NULL && mlt_filter_init( self, NULL ) == 0 )
+ {
+ return self;
+ }
+ else
+ {
+ free(self);
+ return NULL;
+ }
}
/** Get the service class interface.
char name[20];
// Make the properties key from unique id
- strcpy( name, "pos." );
- strcat( name, unique_id );
+ snprintf( name, 20, "pos.%s", unique_id );
+ name[20 - 1] = '\0';
return mlt_properties_get_position( MLT_FRAME_PROPERTIES( frame ), name ) - in;
}
char name[20];
// Make the properties key from unique id
- strcpy( name, "pos." );
- strcat( name, unique_id );
+ snprintf( name, 20, "pos.%s", unique_id );
+ name[20 -1] = '\0';
// Save the position on the frame
mlt_properties_set_position( MLT_FRAME_PROPERTIES( frame ), name, position );
mlt_frame mlt_frame_init( mlt_service service )
{
// Allocate a frame
- mlt_frame self = calloc( sizeof( struct mlt_frame_s ), 1 );
+ mlt_frame self = calloc( 1, sizeof( struct mlt_frame_s ) );
if ( self != NULL )
{
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 );
}
/** Get the time position of this frame.
+ *
+ * This position is not necessarily the position as the original
+ * producer knows it. It could be the position that the playlist,
+ * multitrack, or tractor producer set.
*
* \public \memberof mlt_frame_s
* \param self a frame
* \return the position
+ * \see mlt_frame_original_position
*/
mlt_position mlt_frame_get_position( mlt_frame self )
return pos < 0 ? 0 : pos;
}
+/** Get the original time position of this frame.
+ *
+ * This is the position that the original producer set on the frame.
+ *
+ * \public \memberof mlt_frame_s
+ * \param self a frame
+ * \return the position
+ */
+
+mlt_position mlt_frame_original_position( mlt_frame self )
+{
+ int pos = mlt_properties_get_position( MLT_FRAME_PROPERTIES( self ), "original_position" );
+ return pos < 0 ? 0 : pos;
+}
+
/** Set the time position of this frame.
*
* \public \memberof mlt_frame_s
int mlt_frame_set_position( mlt_frame self, mlt_position value )
{
+ // Only set the original_position the first time.
+ if ( ! mlt_properties_get( MLT_FRAME_PROPERTIES( self ), "original_position" ) )
+ mlt_properties_set_position( MLT_FRAME_PROPERTIES( self ), "original_position", value );
return mlt_properties_set_position( MLT_FRAME_PROPERTIES( self ), "_position", value );
}
int mlt_frame_set_alpha( mlt_frame self, uint8_t *alpha, int size, mlt_destructor destroy )
{
+ self->get_alpha_mask = NULL;
return mlt_properties_set_data( MLT_FRAME_PROPERTIES( self ), "alpha", alpha, size, destroy, NULL );
}
case mlt_image_yuv422: return "yuv422";
case mlt_image_yuv420p: return "yuv420p";
case mlt_image_opengl: return "opengl";
+ case mlt_image_glsl: return "glsl";
+ case mlt_image_glsl_texture: return "glsl_texture";
}
return "invalid";
}
height += 1;
switch ( format )
{
- case mlt_image_none:
- if ( bpp ) *bpp = 0;
- return 0;
case mlt_image_rgb24:
if ( bpp ) *bpp = 3;
return width * height * 3;
case mlt_image_yuv420p:
if ( bpp ) *bpp = 3 / 2;
return width * height * 3 / 2;
+ default:
+ if ( bpp ) *bpp = 0;
+ return 0;
}
return 0;
}
if ( test_frame )
{
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 );
switch( *format )
{
- case mlt_image_none:
- size = 0;
- *buffer = NULL;
- break;
case mlt_image_rgb24:
size *= 3;
size += *width * 3;
if ( *buffer )
memset( *buffer, 255, size );
break;
+ default:
+ size = 0;
+ *buffer = NULL;
+ break;
}
mlt_properties_set_data( properties, "image", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL );
case mlt_audio_s32le: return "s32le";
case mlt_audio_float: return "float";
case mlt_audio_f32le: return "f32le";
+ case mlt_audio_u8: return "u8";
}
return "invalid";
}
case mlt_audio_s32: return samples * channels * sizeof( int32_t );
case mlt_audio_f32le:
case mlt_audio_float: return samples * channels * sizeof( float );
+ case mlt_audio_u8: return samples * channels;
}
return 0;
}
// Make an 8-bit buffer large enough to hold rendering
int size = w * h;
+ if ( size <= 0 )
+ return NULL;
unsigned char *bitmap = ( unsigned char* )mlt_pool_alloc( size );
if ( bitmap != NULL )
memset( bitmap, 0, size );
+ else
+ return NULL;
mlt_properties_set_data( properties, "waveform", bitmap, size, ( mlt_destructor )mlt_pool_release, NULL );
// Render vertical lines
void mlt_frame_write_ppm( mlt_frame frame )
{
- int width;
- int height;
+ int width = 0;
+ int height = 0;
mlt_image_format format = mlt_image_rgb24;
uint8_t *image;
int size;
mlt_properties_inherit( new_props, properties );
+
+ // Carry over some special data properties for the multi consumer.
+ mlt_properties_set_data( new_props, "_producer",
+ mlt_frame_get_original_producer( self ), 0, NULL, NULL );
+ mlt_properties_set_data( new_props, "movit.convert",
+ mlt_properties_get_data( properties, "movit.convert", NULL), 0, NULL, NULL );
+
if ( is_deep )
{
data = mlt_properties_get_data( properties, "audio", &size );
copy = mlt_pool_alloc( size );
memcpy( copy, data, size );
mlt_properties_set_data( new_props, "image", copy, size, mlt_pool_release, NULL );
+
+ data = mlt_properties_get_data( properties, "alpha", &size );
+ if ( data )
+ {
+ if ( ! size )
+ size = mlt_properties_get_int( properties, "width" ) *
+ mlt_properties_get_int( properties, "height" );
+ copy = mlt_pool_alloc( size );
+ memcpy( copy, data, size );
+ mlt_properties_set_data( new_props, "alpha", copy, size, mlt_pool_release, NULL );
+ };
}
}
else
mlt_properties_set_data( new_props, "audio", data, size, NULL, NULL );
data = mlt_properties_get_data( properties, "image", &size );
mlt_properties_set_data( new_props, "image", data, size, NULL, NULL );
+ data = mlt_properties_get_data( properties, "alpha", &size );
+ mlt_properties_set_data( new_props, "alpha", data, size, NULL, NULL );
}
return new_frame;
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 mlt_position mlt_frame_original_position( mlt_frame self );
extern int mlt_frame_set_position( mlt_frame self, mlt_position value );
extern int mlt_frame_set_image( mlt_frame self, uint8_t *image, int size, mlt_destructor destroy );
extern int mlt_frame_set_alpha( mlt_frame self, uint8_t *alpha, int size, mlt_destructor destroy );
free( g->data );
g->data = ret;
}
- return ret;
+ return strdup( ret );
}
// Close the geometry
mlt_multitrack mlt_multitrack_init( )
{
// Allocate the multitrack object
- mlt_multitrack self = calloc( sizeof( struct mlt_multitrack_s ), 1 );
+ mlt_multitrack self = calloc( 1, sizeof( struct mlt_multitrack_s ) );
if ( self != NULL )
{
mlt_position position = 0;
int i = 0;
int j = 0;
- mlt_position *map = malloc( 1000 * sizeof( mlt_position ) );
+ mlt_position *map = calloc( 1000, sizeof( mlt_position ) );
int count = 0;
for ( i = 0; i < self->count; i ++ )
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index );
static int mlt_playlist_unmix( mlt_playlist self, int clip );
static int mlt_playlist_resize_mix( mlt_playlist self, int clip, int in, int out );
+static void mlt_playlist_next( mlt_listener listener, mlt_properties owner, mlt_service self, void **args );
/** Construct a playlist.
*
mlt_playlist mlt_playlist_init( )
{
- mlt_playlist self = calloc( sizeof( struct mlt_playlist_s ), 1 );
+ mlt_playlist self = calloc( 1, sizeof( struct mlt_playlist_s ) );
if ( self != NULL )
{
mlt_producer producer = &self->parent;
// Construct the producer
- mlt_producer_init( producer, self );
+ if ( mlt_producer_init( producer, self ) != 0 ) goto error1;
// Override the producer get_frame
producer->get_frame = producer_get_frame;
producer->close_object = self;
// Initialise blank
- mlt_producer_init( &self->blank, NULL );
+ if ( mlt_producer_init( &self->blank, NULL ) != 0 ) goto error1;
mlt_properties_set( MLT_PRODUCER_PROPERTIES( &self->blank ), "mlt_service", "blank" );
mlt_properties_set( MLT_PRODUCER_PROPERTIES( &self->blank ), "resource", "blank" );
mlt_properties_set_position( MLT_PLAYLIST_PROPERTIES( self ), "length", 0 );
self->size = 10;
- self->list = malloc( self->size * sizeof( playlist_entry * ) );
+ self->list = calloc( self->size, sizeof( playlist_entry * ) );
+ if ( self->list == NULL ) goto error2;
+
+ mlt_events_register( MLT_PLAYLIST_PROPERTIES( self ), "playlist-next", (mlt_transmitter) mlt_playlist_next );
}
return self;
+error2:
+ free( self->list );
+error1:
+ free( self );
+ return NULL;
+}
+
+/** Construct a playlist with a profile.
+ *
+ * Sets the resource property to "<playlist>".
+ * Set the mlt_type to property to "mlt_producer".
+ * \public \memberof mlt_playlist_s
+ * \param profile the profile to use with the profile
+ * \return a new playlist
+ */
+
+mlt_playlist mlt_playlist_new( mlt_profile profile )
+{
+ mlt_playlist self = mlt_playlist_init();
+ if ( self )
+ mlt_properties_set_data( MLT_PLAYLIST_PROPERTIES( self ), "_profile", profile, 0, NULL, NULL );
+ return self;
}
/** Get the producer associated to this playlist.
}
// Create the entry
- self->list[ self->count ] = calloc( sizeof( playlist_entry ), 1 );
+ self->list[ self->count ] = calloc( 1, sizeof( playlist_entry ) );
if ( self->list[ self->count ] != NULL )
{
self->list[ self->count ]->producer = producer;
return producer;
}
+/** The transmitter for the producer-next event
+ *
+ * Invokes the listener.
+ *
+ * \private \memberof mlt_playlist_s
+ * \param listener a function pointer that will be invoked
+ * \param owner the events object that will be passed to \p listener
+ * \param self a service that will be passed to \p listener
+ * \param args an array of pointers.
+ */
+
+static void mlt_playlist_next( mlt_listener listener, mlt_properties owner, mlt_service self, void **args )
+{
+ if ( listener )
+ listener( owner, self, args[ 0 ] );
+}
+
+
/** Seek in the virtual playlist.
*
* This gets the producer at the current position and seeks on the producer
producer = &self->blank;
}
+ // Determine if we have moved to the next entry in the playlist.
+ if ( original == total - 2 )
+ mlt_events_fire( properties, "playlist-next", i, NULL );
+
return MLT_PRODUCER_SERVICE( producer );
}
*
* \public \memberof mlt_playlist_s
* \param self a playlist
- * \param length the ending time of the blank entry, not its duration
+ * \param out the ending time of the blank entry, not its duration
* \return true if there was an error
*/
-int mlt_playlist_blank( mlt_playlist self, mlt_position length )
+int mlt_playlist_blank( mlt_playlist self, mlt_position out )
{
// Append to the virtual list
- if (length >= 0)
- return mlt_playlist_virtual_append( self, &self->blank, 0, length );
+ if ( out >= 0 )
+ return mlt_playlist_virtual_append( self, &self->blank, 0, out );
+ else
+ return 1;
+}
+
+/** Append a blank item to the playlist with duration as a time string.
+ *
+ * \public \memberof mlt_playlist_s
+ * \param self a playlist
+ * \param length the duration of the blank entry as a time string
+ * \return true if there was an error
+ */
+
+int mlt_playlist_blank_time( mlt_playlist self, const char* length )
+{
+ if ( self && length )
+ {
+ mlt_properties properties = MLT_PLAYLIST_PROPERTIES( self );
+ mlt_properties_set( properties , "_blank_time", length );
+ mlt_position duration = mlt_properties_get_position( properties, "_blank_time" );
+ return mlt_playlist_blank( self, duration - 1 );
+ }
else
return 1;
}
// Get the clip info
mlt_playlist_get_clip_info( self, &where_info, where );
- // Make sure the clip to be removed is valid and correct if necessary
- if ( where < 0 )
- where = 0;
- if ( where >= self->count )
- where = self->count - 1;
-
// Reorganise the list
for ( i = where + 1; i < self->count; i ++ )
self->list[ i - 1 ] = self->list[ i ];
if ( error == 0 )
{
int i = clip;
- mlt_playlist new_clip = mlt_playlist_init( );
+ mlt_playlist new_clip = mlt_playlist_new( mlt_service_profile( MLT_PLAYLIST_SERVICE(self) ) );
mlt_events_block( MLT_PLAYLIST_PROPERTIES( self ), self );
if ( clip + count >= self->count )
count = self->count - clip - 1;
* 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
+ * \event \em playlist-next The playlist fires this when it moves to the next item in the list.
+ * The listener receives one argument that is the index of the entry that just completed.
*/
struct mlt_playlist_s
#define MLT_PLAYLIST_PROPERTIES( playlist ) MLT_SERVICE_PROPERTIES( MLT_PLAYLIST_SERVICE( playlist ) )
extern mlt_playlist mlt_playlist_init( );
+extern mlt_playlist mlt_playlist_new( mlt_profile profile );
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_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 int mlt_playlist_blank( mlt_playlist self, mlt_position out );
+extern int mlt_playlist_blank_time( mlt_playlist self, const char *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 );
mlt_properties_set_data( MLT_PRODUCER_PROPERTIES( self ), "_profile", profile, 0, NULL, NULL );
mlt_properties_set_double( MLT_PRODUCER_PROPERTIES( self ), "aspect_ratio", mlt_profile_sar( profile ) );
}
+ else
+ {
+ free( self );
+ return NULL;
+ }
}
return self;
}
* \param position set the "play head" position of the producer
* \return false
* \todo Document how the properties affect behavior.
+ * \see mlt_producer_seek_time
*/
int mlt_producer_seek( mlt_producer self, mlt_position position )
mlt_producer_set_speed( self, 0 );
position = mlt_producer_get_playtime( self ) - 1;
}
- else if ( use_points && !strcmp( eof, "loop" ) && position >= mlt_producer_get_playtime( self ) )
+ else if ( use_points && eof && !strcmp( eof, "loop" ) && position >= mlt_producer_get_playtime( self ) )
{
position = (int)position % (int)mlt_producer_get_playtime( self );
}
return 0;
}
+/** Seek to a specified time string.
+ *
+ * \public \memberof mlt_producer_s
+ * \param self a producer
+ * \param time set the "play head" position of the producer to the time string
+ * \return false
+ * \see mlt_producer_seek
+ */
+
+int mlt_producer_seek_time( mlt_producer self, const char* time )
+{
+ mlt_properties_set( MLT_PRODUCER_PROPERTIES(self), "_seek_time", time );
+ mlt_position position = mlt_properties_get_position( MLT_PRODUCER_PROPERTIES(self), "_seek_time" );
+ return mlt_producer_seek( self, position );
+}
+
/** Get the current position (relative to in point).
*
* \public \memberof mlt_producer_s
return mlt_properties_get_position( MLT_PRODUCER_PROPERTIES( self ), "_frame" );
}
+/** Get the current position (relative to start of producer) as a time string.
+ *
+ * \public \memberof mlt_producer_s
+ * \param self a producer
+ * \param format the time value format
+ * \return the position of the "play head" regardless of the in point
+ */
+
+char* mlt_producer_frame_time( mlt_producer self, mlt_time_format format )
+{
+ return mlt_properties_get_time( MLT_PRODUCER_PROPERTIES( self ), "_frame", format );
+}
+
/** Set the playing speed.
*
* \public \memberof mlt_producer_s
return mlt_properties_get_position( MLT_PRODUCER_PROPERTIES( self ), "length" );
}
+/** Get the total, unedited length of the producer as a time string.
+ *
+ * The value returned by a live streaming producer is unknown.
+ *
+ * \public \memberof mlt_producer_s
+ * \param self a producer
+ * \param format the time value format
+ * \return the duration of the producer regardless of in and out points
+ */
+
+char* mlt_producer_get_length_time( mlt_producer self, mlt_time_format format )
+{
+ return mlt_properties_get_time( MLT_PRODUCER_PROPERTIES( self ), "length", format );
+}
+
/** Prepare for next frame.
*
* Advance the play out position. If the speed is less than zero, it will
* service network - that could be through synthesis or reading a stream.
*
* \extends mlt_service
- * \event \em producer-changed
+ * \event \em producer-changed either service-changed was fired or the timing of the 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
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 int mlt_producer_seek_time( mlt_producer self, const char* time );
extern mlt_position mlt_producer_position( mlt_producer self );
extern mlt_position mlt_producer_frame( mlt_producer self );
+char* mlt_producer_frame_time( mlt_producer self, mlt_time_format );
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 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 char* mlt_producer_get_length_time( mlt_producer self, mlt_time_format );
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 );
mlt_profile mlt_profile_load_string( const char *string )
{
mlt_properties properties = mlt_properties_new();
+ mlt_profile profile = NULL;
+
if ( properties )
{
const char *p = string;
p = strchr( p, '\n' );
if ( p ) p++;
}
+ profile = mlt_profile_load_properties( properties );
+ mlt_properties_close( properties );
}
- return mlt_profile_load_properties( properties );
+ return profile;
}
/** Get the video frame rate as a floating point value.
{
mlt_frame fr = NULL;
uint8_t *buffer;
- mlt_image_format fmt = mlt_image_yuv422;
+ mlt_image_format fmt = mlt_image_none;
mlt_properties p;
int w = profile->width;
int h = profile->height;
if ( ! mlt_service_get_frame( MLT_PRODUCER_SERVICE(producer), &fr, 0 ) && fr )
{
- mlt_properties_set_double( MLT_FRAME_PROPERTIES( fr ), "consumer_aspect_ratio", mlt_profile_sar( profile ) );
if ( ! mlt_frame_get_image( fr, &buffer, &fmt, &w, &h, 0 ) )
{
// Some source properties are not exposed until after the first get_image call.
self->child = child;
// Allocate the local structure
- self->local = calloc( sizeof( property_list ), 1 );
+ self->local = calloc( 1, sizeof( property_list ) );
// Increment the ref count
( ( property_list * )self->local )->ref_count = 1;
mlt_properties mlt_properties_new( )
{
// Construct a standalone properties object
- mlt_properties self = calloc( sizeof( struct mlt_properties_s ), 1 );
+ mlt_properties self = calloc( 1, sizeof( struct mlt_properties_s ) );
// Initialise self
mlt_properties_init( self, NULL );
// Read each string from the file
while( fgets( temp, 1024, file ) )
{
- // Chomp the string
- temp[ strlen( temp ) - 1 ] = '\0';
+ // Chomp the new line character from the string
+ int x = strlen( temp ) - 1;
+ if ( temp[x] == '\n' || temp[x] == '\r' )
+ temp[x] = '\0';
// Check if the line starts with a .
if ( temp[ 0 ] == '.' )
static inline mlt_property mlt_properties_find( mlt_properties self, const char *name )
{
+ if ( !name ) return NULL;
property_list *list = self->local;
mlt_property value = NULL;
int key = generate_hash( name );
mlt_properties_pass_property( self, that, ptr );
ptr += count + 1;
- ptr += strspn( ptr, delim );
+ if ( !done )
+ ptr += strspn( ptr, delim );
}
free( props );
int mlt_properties_get_int( mlt_properties self, const char *name )
{
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ property_list *list = self->local;
mlt_property value = mlt_properties_find( self, name );
- return value == NULL ? 0 : mlt_property_get_int( value );
+ return value == NULL ? 0 : mlt_property_get_int( value, fps, list->locale );
}
/** Set a property to an integer value.
double mlt_properties_get_double( mlt_properties self, const char *name )
{
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
mlt_property value = mlt_properties_find( self, name );
property_list *list = self->local;
- return value == NULL ? 0 : mlt_property_get_double_l( value, list->locale );
+ return value == NULL ? 0 : mlt_property_get_double( value, fps, list->locale );
}
/** Set a property to a floating point value.
mlt_position mlt_properties_get_position( mlt_properties self, const char *name )
{
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ property_list *list = self->local;
mlt_property value = mlt_properties_find( self, name );
- return value == NULL ? 0 : mlt_property_get_position( value );
+ return value == NULL ? 0 : mlt_property_get_position( value, fps, list->locale );
}
/** Set a property to a position value.
{
mlt_deque stack;
unsigned int level;
- unsigned int index;
+ int index;
+ mlt_deque index_stack;
char block;
char *block_name;
unsigned int block_indent;
int error = 0;
char *ptr = strchr( name, ':' );
unsigned int indent = ltrim( &name );
- mlt_properties properties = mlt_deque_peek_front( context->stack );
+ mlt_properties properties = mlt_deque_peek_back( 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 );
+ {
+ mlt_deque_pop_back( context->stack );
+ context->index = mlt_deque_pop_back_int( context->index_stack );
+ }
+ properties = mlt_deque_peek_back( context->stack );
context->level = indent;
}
mlt_properties_set_lcnumeric( child, mlt_properties_get_lcnumeric( properties ) );
mlt_properties_set_data( properties, name, child, 0,
( mlt_destructor )mlt_properties_close, NULL );
- mlt_deque_push_front( context->stack, child );
+ mlt_deque_push_back( context->stack, child );
+ mlt_deque_push_back_int( context->index_stack, context->index );
context->index = 0;
free( name_ );
return error;
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 );
+ mlt_deque_push_back( context->stack, child );
+ mlt_deque_push_back_int( context->index_stack, context->index );
name ++;
context->level += ltrim( &name ) + 1;
// Parser context
yaml_parser context = calloc( 1, sizeof( struct yaml_parser_context ) );
context->stack = mlt_deque_init();
- mlt_deque_push_front( context->stack, self );
+ context->index_stack = mlt_deque_init();
+ mlt_deque_push_back( context->stack, self );
+ mlt_deque_push_back_int( context->index_stack, 0 );
// Read each string from the file
while( fgets( temp, 1024, file ) )
// Close the file
fclose( file );
mlt_deque_close( context->stack );
+ mlt_deque_close( context->index_stack );
if ( context->block_name )
free( context->block_name );
free( context );
strbuf_printf( output, " " );
}
+static void strbuf_escape( strbuf output, const char *value, char c )
+{
+ char *v = strdup( value );
+ char *s = v;
+ char *found = strchr( s, c );
+
+ while ( found )
+ {
+ *found = '\0';
+ strbuf_printf( output, "%s\\%c", s, c );
+ s = found + 1;
+ found = strchr( s, c );
+ }
+ strbuf_printf( output, "%s", s );
+ free( v );
+}
+
/** Convert a line string into a YAML block literal.
*
* \private \memberof strbuf_s
}
indent_yaml( output, indent );
strbuf_printf( output, "%s\n", sol );
+ free( v );
}
/** Recursively serialize a properties list into a string buffer as YAML Tiny.
strbuf_printf( output, "|\n" );
output_yaml_block_literal( output, value, indent + strlen( list->name[ i ] ) + strlen( "|" ) );
}
+ else if ( strchr( value, ':' ) || strchr( value, '[' ) )
+ {
+ strbuf_printf( output, "\"" );
+ strbuf_escape( output, value, '"' );
+ strbuf_printf( output, "\"\n", value );
+ }
else
{
strbuf_printf( output, "%s\n", value );
strbuf_printf( output, "%s: |\n", list->name[ i ] );
output_yaml_block_literal( output, value, indent + strlen( list->name[ i ] ) + strlen( ": " ) );
}
+ else if ( strchr( value, ':' ) || strchr( value, '[' ) )
+ {
+ strbuf_printf( output, "%s: \"", list->name[ i ] );
+ strbuf_escape( output, value, '"' );
+ strbuf_printf( output, "\"\n" );
+ }
else
{
strbuf_printf( output, "%s: %s\n", list->name[ i ], value );
if ( self )
pthread_mutex_unlock( &( ( property_list* )( self->local ) )->mutex );
}
+
+/** Get a time string associated to the name.
+ *
+ * Do not free the returned string. It's lifetime is controlled by the property.
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to get
+ * \param format the time format that you want
+ * \return the property's time value or NULL if \p name does not exist or there is no profile
+ */
+
+char *mlt_properties_get_time( mlt_properties self, const char* name, mlt_time_format format )
+{
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ if ( profile )
+ {
+ double fps = mlt_profile_fps( profile );
+ mlt_property value = mlt_properties_find( self, name );
+ property_list *list = self->local;
+ return value == NULL ? NULL : mlt_property_get_time( value, format, fps, list->locale );
+ }
+ return NULL;
+}
extern char *mlt_properties_serialise_yaml( mlt_properties self );
extern void mlt_properties_lock( mlt_properties self );
extern void mlt_properties_unlock( mlt_properties self );
+extern char *mlt_properties_get_time( mlt_properties, const char* name, mlt_time_format );
#endif
return 0;
}
-/** Convert a base 10 or base 16 string to an integer.
+/** Parse a SMIL clock value.
+ *
+ * \private \memberof mlt_property_s
+ * \param s the string to parse
+ * \param fps frames per second
+ * \param locale the locale to use for parsing a real number value
+ * \return position in frames
+ */
+
+static int time_clock_to_frames( const char *s, double fps, locale_t locale )
+{
+ char *pos, *copy = strdup( s );
+ int hours = 0, minutes = 0;
+ double seconds;
+
+ s = copy;
+ pos = strrchr( s, ':' );
+ if ( pos ) {
+#if defined(__GLIBC__) || defined(__DARWIN__)
+ if ( locale )
+ seconds = strtod_l( pos + 1, NULL, locale );
+ else
+#endif
+ seconds = strtod( pos + 1, NULL );
+ *pos = 0;
+ pos = strrchr( s, ':' );
+ if ( pos ) {
+ minutes = atoi( pos + 1 );
+ *pos = 0;
+ hours = atoi( s );
+ }
+ else {
+ minutes = atoi( s );
+ }
+ }
+ else {
+#if defined(__GLIBC__) || defined(__DARWIN__)
+ if ( locale )
+ seconds = strtod_l( s, NULL, locale );
+ else
+#endif
+ seconds = strtod( s, NULL );
+ }
+ free( copy );
+
+ return fps * ( (hours * 3600) + (minutes * 60) + seconds ) + 0.5;
+}
+
+/** Parse a SMPTE timecode string.
+ *
+ * \private \memberof mlt_property_s
+ * \param s the string to parse
+ * \param fps frames per second
+ * \return position in frames
+ */
+
+static int time_code_to_frames( const char *s, double fps )
+{
+ char *pos, *copy = strdup( s );
+ int hours = 0, minutes = 0, seconds = 0, frames;
+
+ s = copy;
+ pos = strrchr( s, ';' );
+ if ( !pos )
+ pos = strrchr( s, ':' );
+ if ( pos ) {
+ frames = atoi( pos + 1 );
+ *pos = 0;
+ pos = strrchr( s, ':' );
+ if ( pos ) {
+ seconds = atoi( pos + 1 );
+ *pos = 0;
+ pos = strrchr( s, ':' );
+ if ( pos ) {
+ minutes = atoi( pos + 1 );
+ *pos = 0;
+ hours = atoi( s );
+ }
+ else {
+ minutes = atoi( s );
+ }
+ }
+ else {
+ seconds = atoi( s );
+ }
+ }
+ else {
+ frames = atoi( s );
+ }
+ free( copy );
+
+ return frames + ( fps * ( (hours * 3600) + (minutes * 60) + seconds ) + 0.5 );
+}
+
+/** Convert a 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.
* right to obtain RGB without alpha in order to make it do a logical instead
* of arithmetic shift.
*
+ * If the string contains a colon it is interpreted as a time value. If it also
+ * contains a period or comma character, the string is parsed as a clock value:
+ * HH:MM:SS. Otherwise, the time value is parsed as a SMPTE timecode: HH:MM:SS:FF.
* \private \memberof mlt_property_s
* \param value a string to convert
+ * \param fps frames per second, used when converting from time value
+ * \param locale the locale to use when converting from time clock value
* \return the resultant integer
*/
-static inline int mlt_property_atoi( const char *value )
+static int mlt_property_atoi( const char *value, double fps, locale_t locale )
{
- if ( value == NULL )
- return 0;
// Parse a hex color value as #RRGGBB or #AARRGGBB.
if ( value[0] == '#' )
{
{
return strtoul( value + 2, NULL, 16 );
}
+ else if ( fps > 0 && strchr( value, ':' ) )
+ {
+ if ( strchr( value, '.' ) || strchr( value, ',' ) )
+ return time_clock_to_frames( value, fps, locale );
+ else
+ return time_code_to_frames( value, fps );
+ }
else
{
return strtol( value, NULL, 10 );
*
* \public \memberof mlt_property_s
* \param self a property
+ * \param fps frames per second, used when converting from time value
+ * \param locale the locale to use when converting from time clock value
* \return an integer value
*/
-int mlt_property_get_int( mlt_property self )
+int mlt_property_get_int( mlt_property self, double fps, locale_t locale )
{
if ( self->types & mlt_prop_int )
return self->prop_int;
else if ( self->types & mlt_prop_int64 )
return ( int )self->prop_int64;
else if ( ( self->types & mlt_prop_string ) && self->prop_string )
- return mlt_property_atoi( self->prop_string );
+ return mlt_property_atoi( self->prop_string, fps, locale );
return 0;
}
-/** Get the property as a floating point.
+/** Convert a string to a floating point number.
*
- * \public \memberof mlt_property_s
- * \param self a property
- * \return a floating point value
+ * If the string contains a colon it is interpreted as a time value. If it also
+ * contains a period or comma character, the string is parsed as a clock value:
+ * HH:MM:SS. Otherwise, the time value is parsed as a SMPTE timecode: HH:MM:SS:FF.
+ * \private \memberof mlt_property_s
+ * \param value the string to convert
+ * \param fps frames per second, used when converting from time value
+ * \param locale the locale to use when converting from time clock value
+ * \return the resultant real number
*/
-
-double mlt_property_get_double( mlt_property self )
+static double mlt_property_atof( const char *value, double fps, locale_t locale )
{
- if ( self->types & mlt_prop_double )
- return self->prop_double;
- else if ( self->types & mlt_prop_int )
- return ( double )self->prop_int;
- else if ( self->types & mlt_prop_position )
- return ( double )self->prop_position;
- else if ( self->types & mlt_prop_int64 )
- return ( double )self->prop_int64;
- else if ( ( self->types & mlt_prop_string ) && self->prop_string )
- return atof( self->prop_string );
- return 0;
+ if ( fps > 0 && strchr( value, ':' ) )
+ {
+ if ( strchr( value, '.' ) || strchr( value, ',' ) )
+ return time_clock_to_frames( value, fps, locale );
+ else
+ return time_code_to_frames( value, fps );
+ }
+ else
+ {
+#if defined(__GLIBC__) || defined(__DARWIN__)
+ if ( locale )
+ return strtod_l( value, NULL, locale );
+#endif
+ return strtod( value, NULL );
+ }
}
-/** Get the property (with locale) as a floating point.
+/** Get the property as a floating point.
*
* \public \memberof mlt_property_s
* \param self a property
+ * \param fps frames per second, used when converting from time value
* \param locale the locale to use for this conversion
* \return a floating point value
*/
-double mlt_property_get_double_l( mlt_property self, locale_t locale )
+double mlt_property_get_double( mlt_property self, double fps, locale_t locale )
{
if ( self->types & mlt_prop_double )
return self->prop_double;
return ( double )self->prop_position;
else if ( self->types & mlt_prop_int64 )
return ( double )self->prop_int64;
-#if defined(__GLIBC__) || defined(__DARWIN__)
- else if ( locale && ( self->types & mlt_prop_string ) && self->prop_string )
- return strtod_l( self->prop_string, NULL, locale );
-#endif
else if ( ( self->types & mlt_prop_string ) && self->prop_string )
- return strtod( self->prop_string, NULL );
+ return mlt_property_atof( self->prop_string, fps, locale );
return 0;
}
* A position is an offset time in terms of frame units.
* \public \memberof mlt_property_s
* \param self a property
+ * \param fps frames per second, used when converting from time value
+ * \param locale the locale to use when converting from time clock value
* \return the position in frames
*/
-mlt_position mlt_property_get_position( mlt_property self )
+mlt_position mlt_property_get_position( mlt_property self, double fps, locale_t locale )
{
if ( self->types & mlt_prop_position )
return self->prop_position;
else if ( self->types & mlt_prop_int64 )
return ( mlt_position )self->prop_int64;
else if ( ( self->types & mlt_prop_string ) && self->prop_string )
- return ( mlt_position )atol( self->prop_string );
+ return ( mlt_position )mlt_property_atoi( self->prop_string, fps, locale );
return 0;
}
}
pthread_mutex_unlock( &self->mutex );
}
+
+/** Convert frame count to a SMPTE timecode string.
+ *
+ * \private \memberof mlt_property_s
+ * \param frames a frame count
+ * \param fps frames per second
+ * \param[out] s the string to write into - must have enough space to hold largest time string
+ */
+
+static void time_smpte_from_frames( int frames, double fps, char *s )
+{
+ int hours, mins, secs;
+ char frame_sep = ':';
+
+ if ( fps == 30000.0/1001.0 )
+ {
+ fps = 30.0;
+ int i, max_frames = frames;
+ for ( i = 1800; i <= max_frames; i += 1800 )
+ {
+ if ( i % 18000 )
+ {
+ max_frames += 2;
+ frames += 2;
+ }
+ }
+ frame_sep = ';';
+ }
+ hours = frames / ( fps * 3600 );
+ frames -= hours * ( fps * 3600 );
+ mins = frames / ( fps * 60 );
+ frames -= mins * ( fps * 60 );
+ secs = frames / fps;
+ frames -= secs * fps;
+
+ sprintf( s, "%02d:%02d:%02d%c%02d", hours, mins, secs, frame_sep, frames );
+}
+
+/** Convert frame count to a SMIL clock value string.
+ *
+ * \private \memberof mlt_property_s
+ * \param frames a frame count
+ * \param fps frames per second
+ * \param[out] s the string to write into - must have enough space to hold largest time string
+ */
+
+static void time_clock_from_frames( int frames, double fps, char *s )
+{
+ int hours, mins;
+ double secs;
+
+ hours = frames / ( fps * 3600 );
+ frames -= hours * ( fps * 3600 );
+ mins = frames / ( fps * 60 );
+ frames -= mins * ( fps * 60 );
+ secs = (double) frames / fps;
+
+ sprintf( s, "%02d:%02d:%06.3f", hours, mins, secs );
+}
+
+/** Get the property as a time string.
+ *
+ * The time value can be either a SMPTE timecode or SMIL clock value.
+ * The caller is not responsible for deallocating the returned string!
+ * The string is deallocated when the property is closed.
+ * \public \memberof mlt_property_s
+ * \param self a property
+ * \param format the time format that you want
+ * \param fps frames per second
+ * \param locale the locale to use for this conversion
+ * \return a string representation of the property or NULL if failed
+ */
+
+char *mlt_property_get_time( mlt_property self, mlt_time_format format, double fps, locale_t locale )
+{
+ char *orig_localename = NULL;
+ const char *localename = "";
+
+ // Optimization for mlt_time_frames
+ if ( format == mlt_time_frames )
+ return mlt_property_get_string_l( self, locale );
+
+ // Remove existing string
+ if ( self->prop_string )
+ mlt_property_set_int( self, mlt_property_get_int( self, fps, locale ) );
+
+ // Use the specified locale
+ if ( locale )
+ {
+ // TODO: when glibc gets sprintf_l, start using it! For now, hack on setlocale.
+ // Save the current locale
+#if defined(__DARWIN__)
+ localename = querylocale( LC_NUMERIC, locale );
+#elif defined(__GLIBC__)
+ localename = locale->__names[ LC_NUMERIC ];
+#else
+ // TODO: not yet sure what to do on other platforms
+#endif
+ // Protect damaging the global locale from a temporary locale on another thread.
+ pthread_mutex_lock( &self->mutex );
+
+ // Get the current locale
+ orig_localename = strdup( setlocale( LC_NUMERIC, NULL ) );
+
+ // Set the new locale
+ setlocale( LC_NUMERIC, localename );
+ }
+ else
+ {
+ // Make sure we have a lock before accessing self->types
+ pthread_mutex_lock( &self->mutex );
+ }
+
+ // Convert number to string
+ if ( self->types & mlt_prop_int )
+ {
+ self->types |= mlt_prop_string;
+ self->prop_string = malloc( 32 );
+ if ( format == mlt_time_clock )
+ time_clock_from_frames( self->prop_int, fps, self->prop_string );
+ else
+ time_smpte_from_frames( self->prop_int, fps, self->prop_string );
+ }
+ else if ( self->types & mlt_prop_position )
+ {
+ self->types |= mlt_prop_string;
+ self->prop_string = malloc( 32 );
+ if ( format == mlt_time_clock )
+ time_clock_from_frames( (int) self->prop_position, fps, self->prop_string );
+ else
+ time_smpte_from_frames( (int) self->prop_position, fps, self->prop_string );
+ }
+ else if ( self->types & mlt_prop_double )
+ {
+ self->types |= mlt_prop_string;
+ self->prop_string = malloc( 32 );
+ if ( format == mlt_time_clock )
+ time_clock_from_frames( self->prop_double, fps, self->prop_string );
+ else
+ time_smpte_from_frames( self->prop_double, fps, self->prop_string );
+ }
+ else if ( self->types & mlt_prop_int64 )
+ {
+ self->types |= mlt_prop_string;
+ self->prop_string = malloc( 32 );
+ if ( format == mlt_time_clock )
+ time_clock_from_frames( (int) self->prop_int64, fps, self->prop_string );
+ else
+ time_smpte_from_frames( (int) self->prop_int64, fps, self->prop_string );
+ }
+
+ // Restore the current locale
+ if ( locale )
+ {
+ setlocale( LC_NUMERIC, orig_localename );
+ free( orig_localename );
+ pthread_mutex_unlock( &self->mutex );
+ }
+ else
+ {
+ // Make sure we have a lock before accessing self->types
+ pthread_mutex_unlock( &self->mutex );
+ }
+
+ // Return the string (may be NULL)
+ return self->prop_string;
+}
#include "mlt_types.h"
-#ifdef HAVE_SYS_PARAM_H
+#if defined(__FreeBSD__)
+/* This header has existed since 1994 and defines __FreeBSD_version below. */
#include <sys/param.h>
#endif
-#if defined(__GLIBC__) || defined(__DARWIN__) || (__FreeBSD_version >= 1000002)
+#if defined(__GLIBC__) || defined(__DARWIN__) || (__FreeBSD_version >= 900506)
#include <xlocale.h>
#else
typedef void* locale_t;
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 double mlt_property_get_double_l( mlt_property self, locale_t );
-extern mlt_position mlt_property_get_position( mlt_property self );
+extern int mlt_property_get_int( mlt_property self, double fps, locale_t );
+extern double mlt_property_get_double( mlt_property self, double fps, locale_t );
+extern mlt_position mlt_property_get_position( mlt_property self, double fps, locale_t );
extern int64_t mlt_property_get_int64( mlt_property self );
extern char *mlt_property_get_string( mlt_property self );
extern char *mlt_property_get_string_l( mlt_property self, locale_t );
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 self, mlt_property that );
+extern char *mlt_property_get_time( mlt_property self, mlt_time_format, double fps, locale_t );
#endif
return NULL;
// Construct the repository
- mlt_repository self = calloc( sizeof( struct mlt_repository_s ), 1 );
+ mlt_repository self = calloc( 1, sizeof( struct mlt_repository_s ));
mlt_properties_init( &self->parent, self );
self->consumers = mlt_properties_new();
self->filters = mlt_properties_new();
self->child = child;
// Generate local space
- self->local = calloc( sizeof( mlt_service_base ), 1 );
+ self->local = calloc( 1, sizeof( mlt_service_base ) );
// Associate the methods
self->get_frame = service_get_frame;
/** Disconnect a service from its consumer.
*
- * \public \memberof mlt_service_s
+ * \private \memberof mlt_service_s
* \param self a service
*/
mlt_events_fire( MLT_SERVICE_PROPERTIES( self ), "service-changed", NULL );
}
+/** The property-changed event handler.
+ *
+ * \private \memberof mlt_service_s
+ * \param owner ignored
+ * \param self the service on which the "property-changed" event is fired
+ * \param name the name of the property that changed
+ */
+
+static void mlt_service_filter_property_changed( mlt_service owner, mlt_service self, char *name )
+{
+ mlt_events_fire( MLT_SERVICE_PROPERTIES( self ), "property-changed", name, NULL );
+}
+
/** Attach a filter.
*
* \public \memberof mlt_service_s
mlt_events_fire( properties, "service-changed", NULL );
mlt_events_fire( props, "service-changed", NULL );
mlt_events_listen( props, self, "service-changed", ( mlt_listener )mlt_service_filter_changed );
- mlt_events_listen( props, self, "property-changed", ( mlt_listener )mlt_service_filter_changed );
+ mlt_events_listen( props, self, "property-changed", ( mlt_listener )mlt_service_filter_property_changed );
}
else
{
return error;
}
-/** Retrieve a filter.
+/** Get the number of filters attached.
+ *
+ * \public \memberof mlt_service_s
+ * \param self a service
+ * \return the number of attached filters or -1 if there was an error
+ */
+
+int mlt_service_filter_count( mlt_service self )
+{
+ int result = -1;
+ if ( self )
+ {
+ mlt_service_base *base = self->local;
+ result = base->filter_count;
+ }
+ return result;
+}
+
+/** Retrieve an attached filter.
*
* \public \memberof mlt_service_s
* \param self a service
return self? mlt_properties_get_data( MLT_SERVICE_PROPERTIES( self ), "_profile", NULL ) : NULL;
}
+/** Set the profile for a service.
+ *
+ * \public \memberof mlt_service_s
+ * \param self a service
+ * \param profile the profile to set onto the service
+ */
+
+void mlt_service_set_profile( mlt_service self, mlt_profile profile )
+{
+ mlt_properties_set_data( MLT_SERVICE_PROPERTIES( self ), "_profile", profile, 0, NULL, NULL );
+}
+
/** Destroy a service.
*
* \public \memberof mlt_service_s
* 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 service-changed a filter was attached or detached or a transition was connected or disconnected
* \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
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 int mlt_service_filter_count( mlt_service self );
extern mlt_filter mlt_service_filter( mlt_service self, int index );
extern mlt_profile mlt_service_profile( mlt_service self );
+extern void mlt_service_set_profile( mlt_service self, mlt_profile profile );
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 );
mlt_tractor mlt_tractor_init( )
{
- mlt_tractor self = calloc( sizeof( struct mlt_tractor_s ), 1 );
+ mlt_tractor self = calloc( 1, sizeof( struct mlt_tractor_s ) );
if ( self != NULL )
{
mlt_producer producer = &self->parent;
mlt_tractor mlt_tractor_new( )
{
- mlt_tractor self = calloc( sizeof( struct mlt_tractor_s ), 1 );
+ mlt_tractor self = calloc( 1, sizeof( struct mlt_tractor_s ) );
if ( self != NULL )
{
mlt_producer producer = &self->parent;
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_properties_set_int( frame_properties, "consumer_tff", mlt_properties_get_int( properties, "consumer_tff" ) );
mlt_frame_get_image( frame, buffer, format, width, height, writable );
mlt_frame_set_image( self, *buffer, 0, 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 )
{
+ // 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( );
+
// Used to garbage collect all frames
char label[ 30 ];
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;
}
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_pass_list( frame_properties, video_properties, "meta.media.width, meta.media.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 );
static int get_image_a( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
+ mlt_transition self = mlt_frame_pop_service( a_frame );
mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame );
// All transitions get scaling
mlt_properties_set( a_props, "rescale.interp", "nearest" );
// Ensure sane aspect ratio
- 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_frame_get_aspect_ratio( a_frame ) == 0.0 )
+ mlt_frame_set_aspect_ratio( a_frame, mlt_profile_sar( mlt_service_profile( MLT_TRANSITION_SERVICE(self) ) ) );
return mlt_frame_get_image( a_frame, image, format, width, height, writable );
}
static int get_image_b( mlt_frame b_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
+ mlt_transition self = mlt_frame_pop_service( b_frame );
mlt_frame a_frame = mlt_frame_pop_frame( b_frame );
mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame );
mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame );
}
// Ensure sane 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" ) );
+ if ( mlt_frame_get_aspect_ratio( b_frame ) == 0.0 )
+ mlt_frame_set_aspect_ratio( b_frame, mlt_profile_sar( mlt_service_profile( MLT_TRANSITION_SERVICE(self) ) ) );
mlt_properties_pass_list( b_props, a_props,
- "consumer_deinterlace, deinterlace_method, consumer_aspect_ratio, consumer_tff" );
+ "consumer_deinterlace, deinterlace_method, consumer_tff" );
return mlt_frame_get_image( b_frame, image, format, width, height, writable );
}
if ( !( a_hide & type ) && !( b_hide & type ) )
{
// Add hooks for pre-processing frames
+ mlt_frame_push_service( a_frame_ptr, self );
mlt_frame_push_get_image( a_frame_ptr, get_image_a );
mlt_frame_push_frame( b_frame_ptr, a_frame_ptr );
+ mlt_frame_push_service( b_frame_ptr, self );
mlt_frame_push_get_image( b_frame_ptr, get_image_b );
// Process the transition
* \file mlt_types.h
* \brief Provides forward definitions of all public types
*
- * Copyright (C) 2003-2009 Ushodaya Enterprises Limited
+ * Copyright (C) 2003-2012 Ushodaya Enterprises Limited
* \author Charles Yates <charles.yates@pandora.be>
*
* This library is free software; you can redistribute it and/or
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_opengl, /**< (deprecated) suitable for OpenGL texture */
+ mlt_image_glsl, /**< for opengl module internal use only */
+ mlt_image_glsl_texture /**< an OpenGL texture name */
}
mlt_image_format;
mlt_audio_s16 = 1, /**< signed 16-bit interleaved PCM */
mlt_audio_s32, /**< signed 32-bit non-interleaved PCM */
mlt_audio_float, /**< 32-bit non-interleaved floating point */
- mlt_audio_s32le, /**< signed 32-bit interleaved PCM, may only used by producers */
- mlt_audio_f32le /**< 32-bit interleaved floating point, may only be used by producers */
+ mlt_audio_s32le, /**< signed 32-bit interleaved PCM */
+ mlt_audio_f32le, /**< 32-bit interleaved floating point */
+ mlt_audio_u8 /**< unsigned 8-bit interleaved PCM */
}
mlt_audio_format;
+/** The time string formats */
+
+typedef enum
+{
+ mlt_time_frames = 0, /**< frame count */
+ mlt_time_clock, /**< SMIL clock-value as [[hh:]mm:]ss[.fraction] */
+ mlt_time_smpte /**< SMPTE timecode as [[[hh:]mm:]ss:]frames */
+}
+mlt_time_format;
+
/** The relative time qualifiers */
typedef enum
* \file mlt_version.h
* \brief contains version information
*
- * Copyright (C) 2010 Ushodaya Enterprises Limited
+ * Copyright (C) 2010-2013 Ushodaya Enterprises Limited
* \author Jonathan Thomas <Jonathan.Oomph@gmail.com>
*
* This library is free software; you can redistribute it and/or
#define STRINGIZE(s) STRINGIZE2(s)
#define LIBMLT_VERSION_MAJOR 0
-#define LIBMLT_VERSION_MINOR 7
-#define LIBMLT_VERSION_REVISION 7
+#define LIBMLT_VERSION_MINOR 8
+#define LIBMLT_VERSION_REVISION 8
#define LIBMLT_VERSION_INT ((LIBMLT_VERSION_MAJOR<<16)+(LIBMLT_VERSION_MINOR<<8)+LIBMLT_VERSION_REVISION)
#define LIBMLT_VERSION STRINGIZE(LIBMLT_VERSION_MAJOR.LIBMLT_VERSION_MINOR.LIBMLT_VERSION_REVISION)
include ../../config.mak
-include config.mak
OBJS = melt.o \
io.o
SRCS := $(OBJS:.o=.c)
ifeq ($(targetos), MinGW)
+ifeq (, $(findstring MELT_NOSDL, $(CFLAGS)))
CFLAGS += `sdl-config --cflags`
LDFLAGS += `sdl-config --libs`
+endif
bindir = $(prefix)
endif
-all: $(TARGET)
+all: $(meltname)
-$(TARGET): $(OBJS)
+$(meltname): $(OBJS)
$(CC) -o $@ $(OBJS) $(LDFLAGS)
depend: $(SRCS)
rm -f .depend
clean:
- rm -f $(OBJS) $(TARGET)
+ rm -f $(OBJS) $(meltname)
install: all
install -d "$(DESTDIR)$(bindir)"
- install -c -m 755 $(TARGET) "$(DESTDIR)$(bindir)"
+ install -c -m 755 $(meltname) "$(DESTDIR)$(bindir)"
+ifeq ($(extra_versioning), true)
+ifeq ($(melt_noversion), false)
+ ln -s $(meltname) "$(DESTDIR)$(bindir)/melt"
+endif
+endif
uninstall:
- rm -f "$(DESTDIR)$(bindir)/$(TARGET)"
+ rm -f "$(DESTDIR)$(bindir)/$(meltname)"
+ifeq ($(extra_versioning), true)
+ifeq ($(melt_noversion), false)
+ rm -f "$(DESTDIR)$(bindir)/melt"
+endif
+endif
ifneq ($(wildcard .depend),)
include .depend
+++ /dev/null
-#!/bin/sh
-
-if [ "$help" = "1" ]
-then
- cat << EOF
-Melt options:
-
- --rename-melt=name - Give melt executable a different name.
-
-EOF
-
-else
- target=melt
- for i in "$@"
- do
- case $i in
- --rename-melt=* ) target="${i#--rename-melt=}" ;;
- esac
- done
- echo "TARGET=$target" > config.mak
-fi
return n;
}
#else
- struct timespec tm = { 0, 40000 };
+ struct timespec tm = { 0, 40000000 };
nanosleep( &tm, NULL );
#endif
return -1;
/*
* melt.c -- MLT command line utility
- * Copyright (C) 2002-2011 Ushodaya Enterprises Limited
+ * Copyright (C) 2002-2013 Ushodaya Enterprises Limited
* Authors: Charles Yates <charles.yates@pandora.be>
* Dan Dennedy <dan@dennedy.org>
*
#include <libgen.h>
#include <limits.h>
#include <unistd.h>
+#include <signal.h>
#include <framework/mlt.h>
-#if defined(__DARWIN__) || defined(WIN32)
+#if (defined(__DARWIN__) || defined(WIN32)) && !defined(MELT_NOSDL)
#include <SDL.h>
#endif
#include "io.h"
+static mlt_producer melt = NULL;
+
+static void stop_handler(int signum)
+{
+ if ( melt )
+ {
+ mlt_properties properties = MLT_PRODUCER_PROPERTIES( melt );
+ mlt_properties_set_int( properties, "done", 1 );
+ }
+}
+
+static void abnormal_exit_handler(int signum)
+{
+ // The process is going down hard. Restore the terminal first.
+ term_exit();
+ // Reset the default handler so the core gets dumped.
+ signal( signum, SIG_DFL );
+ raise( signum );
+}
+
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 jack = mlt_properties_get_data( MLT_CONSUMER_PROPERTIES( consumer ), "jack_filter", NULL );
- mlt_position position = mlt_producer_position( producer );
+ mlt_position position = producer? mlt_producer_position( producer ) : 0;
mlt_properties_set_int( properties, "stats_off", 1 );
{
int i;
int multi = 0;
+ int qglsl = 0;
+
+ for ( i = 1; i < argc; i ++ ) {
+ // See if we need multi consumer.
+ multi += !strcmp( argv[i], "-consumer" );
+ // Seee if we need the qglsl variant of multi consumer.
+ if ( !strncmp( argv[i], "glsl.", 5 ) || !strncmp( argv[i], "movit.", 6 ) )
+ qglsl = 1;
+ }
+ // Disable qglsl if xgl is being used!
+ for ( i = 1; qglsl && i < argc; i ++ )
+ if ( !strcmp( argv[i], "xgl" ) )
+ qglsl = 0;
- for ( i = 1; i < argc; i ++ )
- multi += !strcmp( argv[ i ], "-consumer" );
-
- if ( multi > 1 )
+ if ( multi > 1 || qglsl )
{
// If there is more than one -consumer use the 'multi' consumer.
int k = 0;
if ( *consumer )
mlt_consumer_close( *consumer );
- *consumer = create_consumer( profile, "multi" );
+ *consumer = create_consumer( profile, ( qglsl? "qglsl" : "multi" ) );
mlt_properties properties = MLT_CONSUMER_PROPERTIES( *consumer );
for ( i = 1; i < argc; i ++ )
{
}
}
-#if defined(__DARWIN__) || defined(WIN32)
+#if (defined(__DARWIN__) || defined(WIN32)) && !defined(MELT_NOSDL)
static void event_handling( 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 };
+ struct timespec tm = { 0, 40000000 };
int total_length = mlt_producer_get_length( producer );
int last_position = 0;
transport_action( producer, string );
}
-#if defined(__DARWIN__) || defined(WIN32)
+#if (defined(__DARWIN__) || defined(WIN32)) && !defined(MELT_NOSDL)
event_handling( producer, consumer );
#endif
{
fprintf( stderr, "Current Position: %10d\r", (int)mlt_consumer_position( consumer ) );
}
+ fflush( stderr );
}
if ( silent || progress )
{
int i;
mlt_consumer consumer = NULL;
- mlt_producer melt = NULL;
FILE *store = NULL;
char *name = NULL;
mlt_profile profile = NULL;
int is_silent = 0;
mlt_profile backup_profile;
+ // Handle abnormal exit situations.
+ signal( SIGSEGV, abnormal_exit_handler );
+ signal( SIGILL, abnormal_exit_handler );
+ signal( SIGABRT, abnormal_exit_handler );
+
// Construct the factory
mlt_repository repo = mlt_factory_init( NULL );
-#ifdef WIN32
+#if defined(WIN32) && !defined(MELT_NOSDL)
is_silent = 1;
#endif
}
else if ( !strcmp( argv[ i ], "-version" ) || !strcmp( argv[ i ], "--version" ) )
{
- fprintf( stdout, "MLT %s " VERSION "\n"
- "Copyright (C) 2002-2011 Ushodaya Enterprises Limited\n"
+ fprintf( stdout, "%s " VERSION "\n"
+ "Copyright (C) 2002-2013 Ushodaya Enterprises Limited\n"
"<http://www.mltframework.org/>\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",
mlt_log_set_level( MLT_LOG_DEBUG );
}
}
- if ( !is_silent && !isatty( STDIN_FILENO ) )
+ if ( !is_silent && !isatty( STDIN_FILENO ) && !is_progress )
is_progress = 1;
// Create profile if not set explicitly
mlt_events_listen( properties, consumer, "consumer-fatal-error", ( mlt_listener )on_fatal_error );
if ( mlt_consumer_start( consumer ) == 0 )
{
+ // Try to exit gracefully upon these signals
+ signal( SIGINT, stop_handler );
+ signal( SIGTERM, stop_handler );
+#ifndef WIN32
+ signal( SIGHUP, stop_handler );
+ signal( SIGPIPE, stop_handler );
+#endif
+
// Transport functionality
transport( melt, consumer );
// Disconnect producer from consumer to prevent ref cycles from closing services
if ( consumer )
+ {
mlt_consumer_connect( consumer, NULL );
+ mlt_events_fire( MLT_CONSUMER_PROPERTIES(consumer), "consumer-cleanup", NULL);
+ }
// Close the producer
if ( melt != NULL )
LIBFLAGS += -Wl,-soname,$(SONAME)
endif
-CXXFLAGS += -I.. $(RDYNAMIC) -DVERSION=\"$(version)\"
+CXXFLAGS += -I.. $(RDYNAMIC) -DVERSION=\"$(version)\" -fvisibility=hidden
LDFLAGS += -L../framework -lmlt
+ifeq ($(targetos), Linux)
+LDFLAGS += -Wl,--version-script=mlt++.vers
+endif
OBJS = MltConsumer.o \
MltDeque.o \
return mlt_deque_peek_front( deque );
}
+void *Deque::peek( int index )
+{
+ return mlt_deque_peek( deque, index );
+}
+
void *pop_front( );
void *peek_back( );
void *peek_front( );
+ void *peek( int index );
};
}
#include "MltFilteredConsumer.h"
using namespace Mlt;
-FilteredConsumer::FilteredConsumer( Profile& profile, char *id, char *arg ) :
+FilteredConsumer::FilteredConsumer( Profile& profile, const char *id, const char *arg ) :
Consumer( profile, id, arg )
{
// Create a reference to the first service
private:
Service *first;
public:
- FilteredConsumer( Profile& profile, char *id, char *arg = NULL );
+ FilteredConsumer( Profile& profile, const char *id, const char *arg = NULL );
FilteredConsumer( Consumer &consumer );
virtual ~FilteredConsumer( );
int connect( Service &service );
*/
#include "MltFilteredProducer.h"
+#include "MltProfile.h"
using namespace Mlt;
-FilteredProducer::FilteredProducer( Profile& profile, char *id, char *arg ) :
+FilteredProducer::FilteredProducer( Profile& profile, const char *id, const char *arg ) :
Producer( profile, id, arg )
{
// Create a reference to the last service
Service *consumer = it->consumer( );
if ( consumer->is_valid( ) )
consumer->connect_producer( *producer );
- Producer dummy( *profile(), "colour" );
+ Profile p( get_profile() );
+ Producer dummy( p, "colour" );
dummy.connect_producer( *it );
if ( last->get_service( ) == it->get_service( ) )
{
private:
Service *last;
public:
- FilteredProducer( Profile& profile, char *id, char *arg = NULL );
+ FilteredProducer( Profile& profile, const char *id, const char *arg = NULL );
virtual ~FilteredProducer( );
int attach( Filter &filter );
int detach( Filter &filter );
return mlt_frame_unique_properties( get_frame(), service.get_service() );
}
+int Frame::get_position( )
+{
+ return mlt_frame_get_position( get_frame() );
+}
+
int Frame::set_image( uint8_t *image, int size, mlt_destructor destroy )
{
return mlt_frame_set_image( get_frame(), image, size, destroy );
void *get_audio( mlt_audio_format &format, int &frequency, int &channels, int &samples );
unsigned char *get_waveform( int w, int h );
Producer *get_original_producer( );
+ int get_position( );
mlt_properties get_unique_properties( Service &service );
int set_image( uint8_t *image, int size, mlt_destructor destroy );
int set_alpha( uint8_t *alpha, int size, mlt_destructor destroy );
#include <stdlib.h>
#include "MltPlaylist.h"
#include "MltTransition.h"
+#include "MltProfile.h"
using namespace Mlt;
ClipInfo::ClipInfo( ) :
instance = mlt_playlist_init( );
}
+Playlist::Playlist( Profile& profile ) :
+ instance( NULL )
+{
+ instance = mlt_playlist_new( profile.get_profile() );
+}
+
Playlist::Playlist( Service &producer ) :
instance( NULL )
{
return mlt_playlist_append_io( get_playlist( ), producer.get_producer( ), in, out );
}
-int Playlist::blank( int length )
+int Playlist::blank( int out )
+{
+ return mlt_playlist_blank( get_playlist( ), out );
+}
+
+int Playlist::blank( const char *length )
{
- return mlt_playlist_blank( get_playlist( ), length );
+ return mlt_playlist_blank_time( get_playlist( ), length );
}
int Playlist::clip( mlt_whence whence, int index )
class Service;
class Playlist;
class Transition;
+ class Profile;
class MLTPP_DECLSPEC ClipInfo
{
mlt_playlist instance;
public:
Playlist( );
+ Playlist( Profile& profile );
Playlist( Service &playlist );
Playlist( Playlist &playlist );
Playlist( mlt_playlist playlist );
int count( );
int clear( );
int append( Producer &producer, int in = -1, int out = -1 );
- int blank( int length );
+ int blank( int out );
+ int blank( const char *length );
int clip( mlt_whence whence, int index );
int current_clip( );
Producer *current( );
return mlt_producer_seek( get_producer( ), position );
}
+int Producer::seek( const char *time )
+{
+ return mlt_producer_seek_time( get_producer( ), time );
+}
+
int Producer::position( )
{
return mlt_producer_position( get_producer( ) );
return mlt_producer_frame( get_producer( ) );
}
+char* Producer::frame_time( mlt_time_format format )
+{
+ return mlt_producer_frame_time( get_producer(), format );
+}
+
int Producer::set_speed( double speed )
{
return mlt_producer_set_speed( get_producer( ), speed );
return mlt_producer_get_length( get_producer( ) );
}
+char* Producer::get_length_time( mlt_time_format format )
+{
+ return mlt_producer_get_length_time( get_producer( ), format );
+}
+
int Producer::get_playtime( )
{
return mlt_producer_get_playtime( get_producer( ) );
mlt_producer get_parent( );
mlt_service get_service( );
int seek( int position );
+ int seek( const char* time );
int position( );
int frame( );
+ char* frame_time( mlt_time_format = mlt_time_smpte );
int set_speed( double speed );
int pause( );
double get_speed( );
int get_in( );
int get_out( );
int get_length( );
+ char* get_length_time( mlt_time_format = mlt_time_smpte );
int get_playtime( );
Producer *cut( int in = 0, int out = -1 );
bool is_cut( );
return mlt_profile_dar( instance );
}
+int Profile::is_explicit() const
+{
+ return instance->is_explicit;
+}
+
+int Profile::colorspace() const
+{
+ return instance->colorspace;
+}
+
Properties* Profile::list()
{
return new Properties( mlt_profile_list() );
void Profile::set_frame_rate( int numerator, int denominator )
{
- instance->sample_aspect_num = numerator;
- instance->sample_aspect_den = denominator;
+ instance->frame_rate_num = numerator;
+ instance->frame_rate_den = denominator;
}
void Profile::set_explicit( int boolean )
int display_aspect_num() const;
int display_aspect_den() const;
double dar() const;
+ int is_explicit() const;
+ int colorspace() const;
static Properties* list();
void from_producer( Producer &producer );
void set_width( int width );
{
return mlt_properties_get_lcnumeric( get_properties() );
}
+
+char *Properties::get_time( const char *name, mlt_time_format format )
+{
+ return mlt_properties_get_time( get_properties(), name, format );
+}
int preset( const char *name );
int set_lcnumeric( const char *locale );
const char *get_lcnumeric( );
+ char *get_time( const char *name, mlt_time_format = mlt_time_smpte );
};
}
delete filter;
}
-PushConsumer::PushConsumer( Profile& profile, char *id , char *service ) :
+PushConsumer::PushConsumer( Profile& profile, const char *id , const char *service ) :
Consumer( profile, id, service ),
m_private( new PushPrivate( ) )
{
private:
PushPrivate *m_private;
public:
- PushConsumer( Profile& profile, char *id , char *service = NULL );
+ PushConsumer( Profile& profile, const char *id , const char *service = NULL );
virtual ~PushConsumer( );
void set_render( int width, int height, double aspect_ratio );
virtual int connect( Service &service );
return new Profile( mlt_service_profile( get_service() ) );
}
+mlt_profile Service::get_profile()
+{
+ return mlt_service_profile( get_service() );
+}
+
Frame *Service::get_frame( int index )
{
mlt_frame frame = NULL;
return mlt_service_detach( get_service( ), filter.get_filter( ) );
}
+int Service::filter_count()
+{
+ return mlt_service_filter_count( get_service() );
+}
+
Filter *Service::filter( int index )
{
mlt_filter result = mlt_service_filter( get_service( ), index );
return result == NULL ? NULL : new Filter( result );
}
+void Service::set_profile( Profile &profile )
+{
+ mlt_service_set_profile( get_service( ), profile.get_profile( ) );
+}
Service *consumer( );
Service *producer( );
Profile *profile( );
+ mlt_profile get_profile( );
Frame *get_frame( int index = 0 );
mlt_service_type type( );
int attach( Filter &filter );
int detach( Filter &filter );
+ int filter_count( );
Filter *filter( int index );
+ void set_profile( Profile &profile );
};
}
#define MLTPP_DECLSPEC __declspec( dllimport )
#endif
#else
- #define MLTPP_DECLSPEC
+ #if __GNUC__ >= 4
+ #define MLTPP_DECLSPEC __attribute__ ((visibility ("default")))
+ #else
+ #define MLTPP_DECLSPEC
+ #endif
#endif
#endif
MinGW)
echo LIBSUF=.dll
echo "CXXFLAGS+=-Wall $WARNINGS -DPIC"
- echo "LIBFLAGS=-enable-auto-import -shared"
+ echo "LIBFLAGS=-Wl,-enable-auto-import -shared"
;;
esac >> config.mak
--- /dev/null
+MLTPP_0.8.8 {
+ global:
+ extern "C++" {
+ "Mlt::ClipInfo::~ClipInfo()";
+ "Mlt::ClipInfo::ClipInfo()";
+ "Mlt::ClipInfo::ClipInfo(mlt_playlist_clip_info*)";
+ "Mlt::ClipInfo::update(mlt_playlist_clip_info*)";
+ "typeinfo for Mlt::Consumer";
+ "typeinfo name for Mlt::Consumer";
+ "vtable for Mlt::Consumer";
+ "Mlt::Consumer::connect(Mlt::Service&)";
+ "Mlt::Consumer::~Consumer()";
+ "Mlt::Consumer::Consumer()";
+ "Mlt::Consumer::Consumer(Mlt::Consumer&)";
+ "Mlt::Consumer::Consumer(mlt_consumer_s*)";
+ "Mlt::Consumer::Consumer(Mlt::Profile&)";
+ "Mlt::Consumer::Consumer(Mlt::Profile&, char const*, char const*)";
+ "Mlt::Consumer::Consumer(Mlt::Service&)";
+ "Mlt::Consumer::get_consumer()";
+ "Mlt::Consumer::get_service()";
+ "Mlt::Consumer::is_stopped()";
+ "Mlt::Consumer::position()";
+ "Mlt::Consumer::purge()";
+ "Mlt::Consumer::run()";
+ "Mlt::Consumer::start()";
+ "Mlt::Consumer::stop()";
+ "Mlt::Deque::count()";
+ "Mlt::Deque::~Deque()";
+ "Mlt::Deque::Deque()";
+ "Mlt::Deque::peek_back()";
+ "Mlt::Deque::peek_front()";
+ "Mlt::Deque::pop_back()";
+ "Mlt::Deque::pop_front()";
+ "Mlt::Deque::push_back(void*)";
+ "Mlt::Deque::push_front(void*)";
+ "Mlt::Event::block()";
+ "Mlt::Event::~Event()";
+ "Mlt::Event::Event(Mlt::Event&)";
+ "Mlt::Event::Event(mlt_event_struct*)";
+ "Mlt::Event::get_event()";
+ "Mlt::Event::is_valid()";
+ "Mlt::Event::unblock()";
+ "Mlt::Factory::close()";
+ "Mlt::Factory::consumer(Mlt::Profile&, char*, char*)";
+ "Mlt::Factory::event_object()";
+ "Mlt::Factory::filter(Mlt::Profile&, char*, char*)";
+ "Mlt::Factory::init(char const*)";
+ "Mlt::Factory::producer(Mlt::Profile&, char*, char*)";
+ "Mlt::Factory::transition(Mlt::Profile&, char*, char*)";
+ "typeinfo for Mlt::Field";
+ "typeinfo name for Mlt::Field";
+ "vtable for Mlt::Field";
+ "Mlt::Field::disconnect_service(Mlt::Service&)";
+ "Mlt::Field::~Field()";
+ "Mlt::Field::Field(Mlt::Field&)";
+ "Mlt::Field::Field(mlt_field_s*)";
+ "Mlt::Field::get_field()";
+ "Mlt::Field::get_service()";
+ "Mlt::Field::plant_filter(Mlt::Filter&, int)";
+ "Mlt::Field::plant_transition(Mlt::Transition&, int, int)";
+ "typeinfo for Mlt::FilteredConsumer";
+ "typeinfo name for Mlt::FilteredConsumer";
+ "vtable for Mlt::FilteredConsumer";
+ "Mlt::FilteredConsumer::attach(Mlt::Filter&)";
+ "Mlt::FilteredConsumer::connect(Mlt::Service&)";
+ "Mlt::FilteredConsumer::detach(Mlt::Filter&)";
+ "Mlt::FilteredConsumer::~FilteredConsumer()";
+ "Mlt::FilteredConsumer::FilteredConsumer(Mlt::Consumer&)";
+ "Mlt::FilteredConsumer::FilteredConsumer(Mlt::Profile&, char const*, char const*)";
+ "Mlt::FilteredConsumer::last(Mlt::Filter&)";
+ "typeinfo for Mlt::FilteredProducer";
+ "typeinfo name for Mlt::FilteredProducer";
+ "vtable for Mlt::FilteredProducer";
+ "Mlt::FilteredProducer::attach(Mlt::Filter&)";
+ "Mlt::FilteredProducer::detach(Mlt::Filter&)";
+ "Mlt::FilteredProducer::~FilteredProducer()";
+ "Mlt::FilteredProducer::FilteredProducer(Mlt::Profile&, char const*, char const*)";
+ "typeinfo for Mlt::Filter";
+ "typeinfo name for Mlt::Filter";
+ "vtable for Mlt::Filter";
+ "Mlt::Filter::connect(Mlt::Service&, int)";
+ "Mlt::Filter::~Filter()";
+ "Mlt::Filter::Filter(Mlt::Filter&)";
+ "Mlt::Filter::Filter(mlt_filter_s*)";
+ "Mlt::Filter::Filter(Mlt::Profile&, char const*, char const*)";
+ "Mlt::Filter::Filter(Mlt::Service&)";
+ "Mlt::Filter::get_filter()";
+ "Mlt::Filter::get_in()";
+ "Mlt::Filter::get_length()";
+ "Mlt::Filter::get_length2(Mlt::Frame&)";
+ "Mlt::Filter::get_out()";
+ "Mlt::Filter::get_position(Mlt::Frame&)";
+ "Mlt::Filter::get_progress(Mlt::Frame&)";
+ "Mlt::Filter::get_service()";
+ "Mlt::Filter::get_track()";
+ "Mlt::Filter::set_in_and_out(int, int)";
+ "typeinfo for Mlt::Frame";
+ "typeinfo name for Mlt::Frame";
+ "vtable for Mlt::Frame";
+ "Mlt::Frame::fetch_image(mlt_image_format, int, int, int)";
+ "Mlt::Frame::~Frame()";
+ "Mlt::Frame::Frame(Mlt::Frame&)";
+ "Mlt::Frame::Frame(mlt_frame_s*)";
+ "Mlt::Frame::get_audio(mlt_audio_format&, int&, int&, int&)";
+ "Mlt::Frame::get_frame()";
+ "Mlt::Frame::get_image(mlt_image_format&, int&, int&, int)";
+ "Mlt::Frame::get_original_producer()";
+ "Mlt::Frame::get_position()";
+ "Mlt::Frame::get_properties()";
+ "Mlt::Frame::get_unique_properties(Mlt::Service&)";
+ "Mlt::Frame::get_waveform(int, int)";
+ "Mlt::Frame::set_alpha(unsigned char*, int, void (*)(void*))";
+ "Mlt::Frame::set_image(unsigned char*, int, void (*)(void*))";
+ "Mlt::Geometry::fetch(Mlt::GeometryItem*, float)";
+ "Mlt::Geometry::fetch(Mlt::GeometryItem&, float)";
+ "Mlt::Geometry::~Geometry()";
+ "Mlt::Geometry::Geometry(char*, int, int, int)";
+ "Mlt::Geometry::insert(Mlt::GeometryItem*)";
+ "Mlt::Geometry::insert(Mlt::GeometryItem&)";
+ "Mlt::Geometry::interpolate()";
+ "Mlt::Geometry::next_key(Mlt::GeometryItem*, int)";
+ "Mlt::Geometry::next_key(Mlt::GeometryItem&, int)";
+ "Mlt::Geometry::parse(char*, int, int, int)";
+ "Mlt::Geometry::prev_key(Mlt::GeometryItem*, int)";
+ "Mlt::Geometry::prev_key(Mlt::GeometryItem&, int)";
+ "Mlt::Geometry::remove(int)";
+ "Mlt::Geometry::serialise()";
+ "Mlt::Geometry::serialise(int, int)";
+ "typeinfo for Mlt::Multitrack";
+ "typeinfo name for Mlt::Multitrack";
+ "vtable for Mlt::Multitrack";
+ "Mlt::Multitrack::clip(mlt_whence, int)";
+ "Mlt::Multitrack::connect(Mlt::Producer&, int)";
+ "Mlt::Multitrack::count()";
+ "Mlt::Multitrack::get_multitrack()";
+ "Mlt::Multitrack::get_producer()";
+ "Mlt::Multitrack::~Multitrack()";
+ "Mlt::Multitrack::Multitrack(Mlt::Multitrack&)";
+ "Mlt::Multitrack::Multitrack(mlt_multitrack_s*)";
+ "Mlt::Multitrack::Multitrack(Mlt::Service&)";
+ "Mlt::Multitrack::refresh()";
+ "Mlt::Multitrack::track(int)";
+ "typeinfo for Mlt::Parser";
+ "typeinfo name for Mlt::Parser";
+ "vtable for Mlt::Parser";
+ "Mlt::Parser::get_properties()";
+ "Mlt::Parser::on_end_filter(Mlt::Filter*)";
+ "Mlt::Parser::on_end_multitrack(Mlt::Multitrack*)";
+ "Mlt::Parser::on_end_playlist(Mlt::Playlist*)";
+ "Mlt::Parser::on_end_producer(Mlt::Producer*)";
+ "Mlt::Parser::on_end_track()";
+ "Mlt::Parser::on_end_tractor(Mlt::Tractor*)";
+ "Mlt::Parser::on_end_transition(Mlt::Transition*)";
+ "Mlt::Parser::on_invalid(Mlt::Service*)";
+ "Mlt::Parser::on_start_filter(Mlt::Filter*)";
+ "Mlt::Parser::on_start_multitrack(Mlt::Multitrack*)";
+ "Mlt::Parser::on_start_playlist(Mlt::Playlist*)";
+ "Mlt::Parser::on_start_producer(Mlt::Producer*)";
+ "Mlt::Parser::on_start_track()";
+ "Mlt::Parser::on_start_tractor(Mlt::Tractor*)";
+ "Mlt::Parser::on_start_transition(Mlt::Transition*)";
+ "Mlt::Parser::on_unknown(Mlt::Service*)";
+ "Mlt::Parser::~Parser()";
+ "Mlt::Parser::Parser()";
+ "Mlt::Parser::start(Mlt::Service&)";
+ "typeinfo for Mlt::Playlist";
+ "typeinfo name for Mlt::Playlist";
+ "vtable for Mlt::Playlist";
+ "Mlt::Playlist::append(Mlt::Producer&, int, int)";
+ "Mlt::Playlist::blank(char const*)";
+ "Mlt::Playlist::blank(int)";
+ "Mlt::Playlist::blanks_from(int, int)";
+ "Mlt::Playlist::clear()";
+ "Mlt::Playlist::clip_info(int, Mlt::ClipInfo*)";
+ "Mlt::Playlist::clip_length(int)";
+ "Mlt::Playlist::clip(mlt_whence, int)";
+ "Mlt::Playlist::clip_start(int)";
+ "Mlt::Playlist::consolidate_blanks(int)";
+ "Mlt::Playlist::count()";
+ "Mlt::Playlist::current()";
+ "Mlt::Playlist::current_clip()";
+ "Mlt::Playlist::delete_clip_info(Mlt::ClipInfo*)";
+ "Mlt::Playlist::get_clip_at(int)";
+ "Mlt::Playlist::get_clip_index_at(int)";
+ "Mlt::Playlist::get_clip(int)";
+ "Mlt::Playlist::get_playlist()";
+ "Mlt::Playlist::get_producer()";
+ "Mlt::Playlist::insert_at(int, Mlt::Producer*, int)";
+ "Mlt::Playlist::insert_at(int, Mlt::Producer&, int)";
+ "Mlt::Playlist::insert_blank(int, int)";
+ "Mlt::Playlist::insert(Mlt::Producer&, int, int, int)";
+ "Mlt::Playlist::is_blank_at(int)";
+ "Mlt::Playlist::is_blank(int)";
+ "Mlt::Playlist::is_mix(int)";
+ "Mlt::Playlist::join(int, int, int)";
+ "Mlt::Playlist::mix_add(int, Mlt::Transition*)";
+ "Mlt::Playlist::mix(int, int, Mlt::Transition*)";
+ "Mlt::Playlist::move(int, int)";
+ "Mlt::Playlist::move_region(int, int, int)";
+ "Mlt::Playlist::pad_blanks(int, int, int)";
+ "Mlt::Playlist::~Playlist()";
+ "Mlt::Playlist::Playlist()";
+ "Mlt::Playlist::Playlist(Mlt::Playlist&)";
+ "Mlt::Playlist::Playlist(mlt_playlist_s*)";
+ "Mlt::Playlist::Playlist(Mlt::Profile&)";
+ "Mlt::Playlist::Playlist(Mlt::Service&)";
+ "Mlt::Playlist::remove(int)";
+ "Mlt::Playlist::remove_region(int, int)";
+ "Mlt::Playlist::repeat(int, int)";
+ "Mlt::Playlist::replace_with_blank(int)";
+ "Mlt::Playlist::resize_clip(int, int, int)";
+ "Mlt::Playlist::split_at(int, bool)";
+ "Mlt::Playlist::split(int, int)";
+ "typeinfo for Mlt::Producer";
+ "typeinfo name for Mlt::Producer";
+ "vtable for Mlt::Producer";
+ "Mlt::Producer::clear()";
+ "Mlt::Producer::cut(int, int)";
+ "Mlt::Producer::frame()";
+ "Mlt::Producer::frame_time(mlt_time_format)";
+ "Mlt::Producer::get_fps()";
+ "Mlt::Producer::get_in()";
+ "Mlt::Producer::get_length()";
+ "Mlt::Producer::get_length_time(mlt_time_format)";
+ "Mlt::Producer::get_out()";
+ "Mlt::Producer::get_parent()";
+ "Mlt::Producer::get_playtime()";
+ "Mlt::Producer::get_producer()";
+ "Mlt::Producer::get_service()";
+ "Mlt::Producer::get_speed()";
+ "Mlt::Producer::is_blank()";
+ "Mlt::Producer::is_cut()";
+ "Mlt::Producer::optimise()";
+ "Mlt::Producer::parent()";
+ "Mlt::Producer::pause()";
+ "Mlt::Producer::position()";
+ "Mlt::Producer::~Producer()";
+ "Mlt::Producer::Producer()";
+ "Mlt::Producer::Producer(Mlt::Producer*)";
+ "Mlt::Producer::Producer(Mlt::Producer&)";
+ "Mlt::Producer::Producer(mlt_producer_s*)";
+ "Mlt::Producer::Producer(Mlt::Profile&, char const*, char const*)";
+ "Mlt::Producer::Producer(Mlt::Service&)";
+ "Mlt::Producer::runs_into(Mlt::Producer&)";
+ "Mlt::Producer::same_clip(Mlt::Producer&)";
+ "Mlt::Producer::seek(char const*)";
+ "Mlt::Producer::seek(int)";
+ "Mlt::Producer::set_in_and_out(int, int)";
+ "Mlt::Producer::set_speed(double)";
+ "Mlt::Profile::colorspace() const";
+ "Mlt::Profile::dar() const";
+ "Mlt::Profile::description() const";
+ "Mlt::Profile::display_aspect_den() const";
+ "Mlt::Profile::display_aspect_num() const";
+ "Mlt::Profile::fps() const";
+ "Mlt::Profile::frame_rate_den() const";
+ "Mlt::Profile::frame_rate_num() const";
+ "Mlt::Profile::from_producer(Mlt::Producer&)";
+ "Mlt::Profile::get_profile() const";
+ "Mlt::Profile::height() const";
+ "Mlt::Profile::is_explicit() const";
+ "Mlt::Profile::list()";
+ "Mlt::Profile::~Profile()";
+ "Mlt::Profile::Profile()";
+ "Mlt::Profile::Profile(char const*)";
+ "Mlt::Profile::Profile(mlt_profile_s*)";
+ "Mlt::Profile::Profile(Mlt::Properties&)";
+ "Mlt::Profile::progressive() const";
+ "Mlt::Profile::sample_aspect_den() const";
+ "Mlt::Profile::sample_aspect_num() const";
+ "Mlt::Profile::sar() const";
+ "Mlt::Profile::set_colorspace(int)";
+ "Mlt::Profile::set_explicit(int)";
+ "Mlt::Profile::set_frame_rate(int, int)";
+ "Mlt::Profile::set_height(int)";
+ "Mlt::Profile::set_progressive(int)";
+ "Mlt::Profile::set_sample_aspect(int, int)";
+ "Mlt::Profile::set_width(int)";
+ "Mlt::Profile::width() const";
+ "typeinfo for Mlt::Properties";
+ "typeinfo name for Mlt::Properties";
+ "vtable for Mlt::Properties";
+ "Mlt::Properties::block(void*)";
+ "Mlt::Properties::count()";
+ "Mlt::Properties::debug(char const*, _IO_FILE*)";
+ "Mlt::Properties::dec_ref()";
+ "Mlt::Properties::delete_event(Mlt::Event*)";
+ "Mlt::Properties::dump(_IO_FILE*)";
+ "Mlt::Properties::fire_event(char const*)";
+ "Mlt::Properties::get(char const*)";
+ "Mlt::Properties::get_data(char const*)";
+ "Mlt::Properties::get_data(char const*, int&)";
+ "Mlt::Properties::get_data(int, int&)";
+ "Mlt::Properties::get_double(char const*)";
+ "Mlt::Properties::get(int)";
+ "Mlt::Properties::get_int64(char const*)";
+ "Mlt::Properties::get_int(char const*)";
+ "Mlt::Properties::get_lcnumeric()";
+ "Mlt::Properties::get_name(int)";
+ "Mlt::Properties::get_properties()";
+ "Mlt::Properties::get_time(char const*, mlt_time_format)";
+ "Mlt::Properties::inc_ref()";
+ "Mlt::Properties::inherit(Mlt::Properties&)";
+ "Mlt::Properties::is_sequence()";
+ "Mlt::Properties::is_valid()";
+ "Mlt::Properties::listen(char const*, void*, void (*)(void*, ...))";
+ "Mlt::Properties::load(char const*)";
+ "Mlt::Properties::lock()";
+ "Mlt::Properties::mirror(Mlt::Properties&)";
+ "Mlt::Properties::parse(char const*)";
+ "Mlt::Properties::parse_yaml(char const*)";
+ "Mlt::Properties::pass_list(Mlt::Properties&, char const*)";
+ "Mlt::Properties::pass_property(Mlt::Properties&, char const*)";
+ "Mlt::Properties::pass_values(Mlt::Properties&, char const*)";
+ "Mlt::Properties::preset(char const*)";
+ "Mlt::Properties::~Properties()";
+ "Mlt::Properties::Properties()";
+ "Mlt::Properties::Properties(bool)";
+ "Mlt::Properties::Properties(char const*)";
+ "Mlt::Properties::Properties(Mlt::Properties&)";
+ "Mlt::Properties::Properties(mlt_properties_s*)";
+ "Mlt::Properties::Properties(void*)";
+ "Mlt::Properties::ref_count()";
+ "Mlt::Properties::rename(char const*, char const*)";
+ "Mlt::Properties::save(char const*)";
+ "Mlt::Properties::serialise_yaml()";
+ "Mlt::Properties::set(char const*, char const*)";
+ "Mlt::Properties::set(char const*, double)";
+ "Mlt::Properties::set(char const*, int)";
+ "Mlt::Properties::set(char const*, long)";
+ "Mlt::Properties::set(char const*, void*, int, void (*)(void*), char* (*)(void*, int))";
+ "Mlt::Properties::set_lcnumeric(char const*)";
+ "Mlt::Properties::setup_wait_for(char const*)";
+ "Mlt::Properties::unblock(void*)";
+ "Mlt::Properties::unlock()";
+ "Mlt::Properties::wait_for(char const*)";
+ "Mlt::Properties::wait_for(Mlt::Event*, bool)";
+ "typeinfo for Mlt::PushConsumer";
+ "typeinfo name for Mlt::PushConsumer";
+ "vtable for Mlt::PushConsumer";
+ "Mlt::PushConsumer::connect(Mlt::Service&)";
+ "Mlt::PushConsumer::construct(int)";
+ "Mlt::PushConsumer::drain()";
+ "Mlt::PushConsumer::~PushConsumer()";
+ "Mlt::PushConsumer::PushConsumer(Mlt::Profile&, char const*, char const*)";
+ "Mlt::PushConsumer::push(Mlt::Frame*)";
+ "Mlt::PushConsumer::push(Mlt::Frame&)";
+ "Mlt::PushConsumer::set_render(int, int, double)";
+ "Mlt::Repository::consumers() const";
+ "Mlt::Repository::create(Mlt::Profile&, mlt_service_type, char const*, void*)";
+ "Mlt::Repository::filters() const";
+ "Mlt::Repository::languages() const";
+ "Mlt::Repository::metadata(mlt_service_type, char const*) const";
+ "Mlt::Repository::presets()";
+ "Mlt::Repository::producers() const";
+ "Mlt::Repository::register_metadata(mlt_service_type, char const*, mlt_properties_s* (*)(mlt_service_type, char const*, void*), void*)";
+ "Mlt::Repository::register_service(mlt_service_type, char const*, void* (*)(mlt_profile_s*, mlt_service_type, char const*, void const*))";
+ "Mlt::Repository::~Repository()";
+ "Mlt::Repository::Repository(char const*)";
+ "Mlt::Repository::Repository(mlt_repository_s*)";
+ "Mlt::Repository::transitions() const";
+ "typeinfo for Mlt::Service";
+ "typeinfo name for Mlt::Service";
+ "vtable for Mlt::Service";
+ "Mlt::Service::attach(Mlt::Filter&)";
+ "Mlt::Service::connect_producer(Mlt::Service&, int)";
+ "Mlt::Service::consumer()";
+ "Mlt::Service::detach(Mlt::Filter&)";
+ "Mlt::Service::filter(int)";
+ "Mlt::Service::get_frame(int)";
+ "Mlt::Service::get_profile()";
+ "Mlt::Service::get_properties()";
+ "Mlt::Service::get_service()";
+ "Mlt::Service::lock()";
+ "Mlt::Service::producer()";
+ "Mlt::Service::profile()";
+ "Mlt::Service::~Service()";
+ "Mlt::Service::Service()";
+ "Mlt::Service::Service(Mlt::Service&)";
+ "Mlt::Service::Service(mlt_service_s*)";
+ "Mlt::Service::set_profile(Mlt::Profile&)";
+ "Mlt::Service::type()";
+ "Mlt::Service::unlock()";
+ "Mlt::Tokeniser::count()";
+ "Mlt::Tokeniser::get(int)";
+ "Mlt::Tokeniser::input()";
+ "Mlt::Tokeniser::parse(char*, char*)";
+ "Mlt::Tokeniser::~Tokeniser()";
+ "Mlt::Tokeniser::Tokeniser(char*, char*)";
+ "typeinfo for Mlt::Tractor";
+ "typeinfo name for Mlt::Tractor";
+ "vtable for Mlt::Tractor";
+ "Mlt::Tractor::connect(Mlt::Producer&)";
+ "Mlt::Tractor::count()";
+ "Mlt::Tractor::field()";
+ "Mlt::Tractor::get_producer()";
+ "Mlt::Tractor::get_tractor()";
+ "Mlt::Tractor::locate_cut(Mlt::Producer*, int&, int&)";
+ "Mlt::Tractor::multitrack()";
+ "Mlt::Tractor::plant_filter(Mlt::Filter*, int)";
+ "Mlt::Tractor::plant_filter(Mlt::Filter&, int)";
+ "Mlt::Tractor::plant_transition(Mlt::Transition*, int, int)";
+ "Mlt::Tractor::plant_transition(Mlt::Transition&, int, int)";
+ "Mlt::Tractor::refresh()";
+ "Mlt::Tractor::set_track(Mlt::Producer&, int)";
+ "Mlt::Tractor::track(int)";
+ "Mlt::Tractor::~Tractor()";
+ "Mlt::Tractor::Tractor()";
+ "Mlt::Tractor::Tractor(Mlt::Profile&, char*, char*)";
+ "Mlt::Tractor::Tractor(Mlt::Service&)";
+ "Mlt::Tractor::Tractor(Mlt::Tractor&)";
+ "Mlt::Tractor::Tractor(mlt_tractor_s*)";
+ "typeinfo for Mlt::Transition";
+ "typeinfo name for Mlt::Transition";
+ "vtable for Mlt::Transition";
+ "Mlt::Transition::connect(Mlt::Producer&, int, int)";
+ "Mlt::Transition::get_a_track()";
+ "Mlt::Transition::get_b_track()";
+ "Mlt::Transition::get_in()";
+ "Mlt::Transition::get_length()";
+ "Mlt::Transition::get_out()";
+ "Mlt::Transition::get_position(Mlt::Frame&)";
+ "Mlt::Transition::get_progress_delta(Mlt::Frame&)";
+ "Mlt::Transition::get_progress(Mlt::Frame&)";
+ "Mlt::Transition::get_service()";
+ "Mlt::Transition::get_transition()";
+ "Mlt::Transition::set_in_and_out(int, int)";
+ "Mlt::Transition::~Transition()";
+ "Mlt::Transition::Transition(Mlt::Profile&, char const*, char const*)";
+ "Mlt::Transition::Transition(Mlt::Service&)";
+ "Mlt::Transition::Transition(Mlt::Transition&)";
+ "Mlt::Transition::Transition(mlt_transition_s*)";
+ };
+
+ local: *;
+};
+
+MLTPP_0.9.0 {
+ global:
+ extern "C++" {
+ "Mlt::Deque::peek(int)";
+ "Mlt::Service::filter_count()";
+ };
+} MLTPP_0.8.8;
done
uninstall:
- rm -rf "$(DESTDIR)$(libdir)/mlt"
+ rm -rf "$(DESTDIR)$(moduledir)"
rm -f $(OBJS) ../libmltffmpeg$(LIBSUF) ../libmltavformat$(LIBSUF)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/avformat"
- install -m 644 producer_avformat.yml "$(DESTDIR)$(datadir)/mlt/avformat"
- install -m 644 consumer_avformat.yml "$(DESTDIR)$(datadir)/mlt/avformat"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/avformat"
+ install -m 644 producer_avformat.yml "$(DESTDIR)$(mltdatadir)/avformat"
+ install -m 644 consumer_avformat.yml "$(DESTDIR)$(mltdatadir)/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)$(datadir)/mlt/avformat"
+ rm "$(DESTDIR)$(moduledir)/libmltavformat$(LIBSUF)" 2> /dev/null || true
+ rm "$(DESTDIR)$(moduledir)/libmltffmpeg$(LIBSUF)" 2> /dev/null || true
+ rm -rf "$(DESTDIR)$(mltdatadir)/avformat"
ifneq ($(wildcard .depend),)
include .depend
# 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.
-ffmpeg_ver="0.8"
-libav_ver="0.7"
+ffmpeg_ver="1.0"
+libav_ver="0.8.4"
micro_version=$(echo $version | cut -d . -f 3)
odd_version=$(($micro_version % 2))
[ "$odd_version" -eq "1" ] && ffmpeg_ver="HEAD" && libav_ver="HEAD"
echo > config.mak
export static_ffmpeg=
- export shared_ffmpeg=$(pkg-config --variable=prefix libavformat)
+ export shared_ffmpeg=
export extra_libs=
export avformat_suffix=
export swscale=
esac
done
+ : ${shared_ffmpeg:=$(pkg-config --variable=prefix libavformat${avformat_suffix})}
+
if [ "$static_ffmpeg" != "" ]
then
if [ -d "$static_ffmpeg" ]
if [ "$vdpau" = "true" ]
then
- printf "#include <libavcodec/vdpau.h>\n int main(){ VdpBitstreamBuffer test; test.struct_version; return 0;}" | gcc -I"$static_ffmpeg" $CFLAGS -c -x c - >/dev/null 2>&1
+ printf "#include <libavcodec/vdpau.h>\n int main(){ VdpBitstreamBuffer test; test.struct_version; return 0;}" | $CC -I"$static_ffmpeg" $CFLAGS -c -x c - >/dev/null 2>&1
[ "$x11" = "0" -a "$?" = "0" ] && echo "VDPAU=1" >> config.mak
fi
else
echo "CFLAGS+=-DAVDATADIR=\\\"share/ffmpeg/\\\"" >> config.mak
;;
*)
- echo "CFLAGS+=-DAVDATADIR=\\\"${shared_ffmpeg}/share/ffmpeg/\\\"" >> config.mak
+ echo "CFLAGS+=-DAVDATADIR=\\\"${shared_ffmpeg}/share/ffmpeg${avformat_suffix}/\\\"" >> config.mak
;;
esac
- echo "CFLAGS+=$(pkg-config --cflags libavformat)" >> config.mak
- echo "LDFLAGS+=$(pkg-config --libs-only-L libavformat)" >> config.mak
+ echo "CFLAGS+=$(pkg-config --cflags libavformat${avformat_suffix})" >> config.mak
+ echo "LDFLAGS+=$(pkg-config --libs-only-L libavformat${avformat_suffix})" >> config.mak
if [ "$devices" = "true" ]
then
- echo "CFLAGS+=$(pkg-config --cflags libavdevice)" >> config.mak
- echo "LDFLAGS+=$(pkg-config --libs-only-L libavdevice)" >> config.mak
+ echo "CFLAGS+=$(pkg-config --cflags libavdevice${avformat_suffix})" >> config.mak
+ echo "LDFLAGS+=$(pkg-config --libs-only-L libavdevice${avformat_suffix})" >> config.mak
fi
- avcodec_version=$(pkg-config --modversion libavcodec)
+ avcodec_version=$(pkg-config --modversion libavcodec${avformat_suffix})
if [ "$swscale" != "" ] || [ $(echo $avcodec_version | cut -d. -f1) -gt 52 ] || ( [ $(echo $avcodec_version | cut -d. -f1) -ge 52 ] && [ $(echo $avcodec_version | cut -d. -f2) -ge 21 ] )
then
- echo "CFLAGS+=$(pkg-config --cflags libswscale)" >> config.mak
- echo "LDFLAGS+=$(pkg-config --libs-only-L libswscale)" >> config.mak
+ echo "CFLAGS+=$(pkg-config --cflags libswscale${avformat_suffix})" >> config.mak
+ echo "LDFLAGS+=$(pkg-config --libs-only-L libswscale${avformat_suffix})" >> config.mak
echo "SWSCALE=1" >> config.mak
fi
if [ "$vdpau" = "true" ]
then
- printf "#include <libavcodec/vdpau.h>\n int main(){ VdpBitstreamBuffer test; test.struct_version; return 0;}" | gcc -I"$(pkg-config --cflags libavformat)" -I"$shared_ffmpeg/include" $CFLAGS -c -x c - >/dev/null 2>&1
+ printf "#include <libavcodec/vdpau.h>\n int main(){ VdpBitstreamBuffer test; test.struct_version; return 0;}" | $CC $(pkg-config --cflags libavformat${avformat_suffix}) -I"$shared_ffmpeg/include" $CFLAGS -c -x c - >/dev/null 2>&1
[ "$x11" = "0" -a "$?" = "0" ] && echo "VDPAU=1" >> config.mak
fi
else
/*
* consumer_avformat.c -- an encoder based on avformat
- * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Copyright (C) 2003-2012 Ushodaya Enterprises Limited
* Author: Charles Yates <charles.yates@pandora.be>
+ * Author: Dan Dennedy <dan@dennedy.org>
* Much code borrowed from ffmpeg.c: Copyright (c) 2000-2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
#if LIBAVUTIL_VERSION_INT >= ((50<<16)+(8<<8)+0)
#include <libavutil/pixdesc.h>
#endif
+#include <libavutil/mathematics.h>
+
+#if LIBAVUTIL_VERSION_INT >= ((50<<16)+(38<<8)+0)
+# include <libavutil/samplefmt.h>
+#else
+# define AV_SAMPLE_FMT_NONE SAMPLE_FMT_NONE
+# define AV_SAMPLE_FMT_U8 SAMPLE_FMT_U8
+# define AV_SAMPLE_FMT_S16 SAMPLE_FMT_S16
+# define AV_SAMPLE_FMT_S32 SAMPLE_FMT_S32
+# define AV_SAMPLE_FMT_FLT SAMPLE_FMT_FLT
+#endif
#if LIBAVUTIL_VERSION_INT < (50<<16)
#define PIX_FMT_RGB32 PIX_FMT_RGBA32
#define AUDIO_BUFFER_SIZE (1024 * 42)
#define VIDEO_BUFFER_SIZE (2048 * 1024)
-void avformat_lock( );
-void avformat_unlock( );
-
//
// This structure should be extended and made globally available in mlt
//
typedef struct
{
- int16_t *buffer;
+ uint8_t *buffer;
int size;
int used;
double time;
return fifo;
}
-// sample_fifo_clear and check are temporarily aborted (not working as intended)
-
-void sample_fifo_clear( sample_fifo fifo, double time )
-{
- int words = ( float )( time - fifo->time ) * fifo->frequency * fifo->channels;
- if ( ( int )( ( float )time * 100 ) < ( int )( ( float )fifo->time * 100 ) && fifo->used > words && words > 0 )
- {
- memmove( fifo->buffer, &fifo->buffer[ words ], ( fifo->used - words ) * sizeof( int16_t ) );
- fifo->used -= words;
- fifo->time = time;
- }
- else if ( ( int )( ( float )time * 100 ) != ( int )( ( float )fifo->time * 100 ) )
- {
- fifo->used = 0;
- fifo->time = time;
- }
-}
-
-void sample_fifo_check( sample_fifo fifo, double time )
-{
- if ( fifo->used == 0 )
- {
- if ( ( int )( ( float )time * 100 ) < ( int )( ( float )fifo->time * 100 ) )
- fifo->time = time;
- }
-}
-
-void sample_fifo_append( sample_fifo fifo, int16_t *samples, int count )
+// count is the number of samples multiplied by the number of bytes per sample
+void sample_fifo_append( sample_fifo fifo, uint8_t *samples, int count )
{
if ( ( fifo->size - fifo->used ) < count )
{
fifo->size += count * 5;
- fifo->buffer = realloc( fifo->buffer, fifo->size * sizeof( int16_t ) );
+ fifo->buffer = realloc( fifo->buffer, fifo->size );
}
- memcpy( &fifo->buffer[ fifo->used ], samples, count * sizeof( int16_t ) );
+ memcpy( &fifo->buffer[ fifo->used ], samples, count );
fifo->used += count;
}
return fifo->used;
}
-int sample_fifo_fetch( sample_fifo fifo, int16_t *samples, int count )
+int sample_fifo_fetch( sample_fifo fifo, uint8_t *samples, int count )
{
if ( count > fifo->used )
count = fifo->used;
- memcpy( samples, fifo->buffer, count * sizeof( int16_t ) );
+ memcpy( samples, fifo->buffer, count );
fifo->used -= count;
- memmove( fifo->buffer, &fifo->buffer[ count ], fifo->used * sizeof( int16_t ) );
+ memmove( fifo->buffer, &fifo->buffer[ count ], fifo->used );
fifo->time += ( double )count / fifo->channels / fifo->frequency;
snprintf( key, sizeof(key), "%d", mlt_properties_count( formats ) );
mlt_properties_set( formats, key, format->name );
}
- fprintf( stdout, "%s", mlt_properties_serialise_yaml( doc ) );
+ s = mlt_properties_serialise_yaml( doc );
+ fprintf( stdout, "%s", s );
+ free( s );
mlt_properties_close( doc );
error = 1;
}
mlt_properties_set_data( properties, "acodec", codecs, 0, (mlt_destructor) mlt_properties_close, NULL );
mlt_properties_set_data( doc, "audio_codecs", codecs, 0, NULL, NULL );
while ( ( codec = av_codec_next( codec ) ) )
+#if (defined(FFUDIV) && LIBAVCODEC_VERSION_INT >= ((54<<16)+(56<<8)+100)) || (LIBAVCODEC_VERSION_INT >= ((54<<16)+(27<<8)+0))
+ if ( codec->encode2 && codec->type == CODEC_TYPE_AUDIO )
+#elif LIBAVCODEC_VERSION_INT >= ((54<<16)+(0<<8)+0)
+ if ( ( codec->encode || codec->encode2 ) && codec->type == CODEC_TYPE_AUDIO )
+#else
if ( codec->encode && codec->type == CODEC_TYPE_AUDIO )
+#endif
{
snprintf( key, sizeof(key), "%d", mlt_properties_count( codecs ) );
mlt_properties_set( codecs, key, codec->name );
}
- fprintf( stdout, "%s", mlt_properties_serialise_yaml( doc ) );
+ s = mlt_properties_serialise_yaml( doc );
+ fprintf( stdout, "%s", s );
+ free( s );
mlt_properties_close( doc );
error = 1;
}
mlt_properties_set_data( properties, "vcodec", codecs, 0, (mlt_destructor) mlt_properties_close, NULL );
mlt_properties_set_data( doc, "video_codecs", codecs, 0, NULL, NULL );
while ( ( codec = av_codec_next( codec ) ) )
+#if (defined(FFUDIV) && LIBAVCODEC_VERSION_INT >= ((54<<16)+(56<<8)+100)) || (LIBAVCODEC_VERSION_INT >= ((54<<16)+(27<<8)+0))
+ if ( codec->encode2 && codec->type == CODEC_TYPE_VIDEO )
+#elif LIBAVCODEC_VERSION_INT >= ((54<<16)+(0<<8)+0)
+ if ( (codec->encode || codec->encode2) && codec->type == CODEC_TYPE_VIDEO )
+#else
if ( codec->encode && codec->type == CODEC_TYPE_VIDEO )
+#endif
{
snprintf( key, sizeof(key), "%d", mlt_properties_count( codecs ) );
mlt_properties_set( codecs, key, codec->name );
}
- fprintf( stdout, "%s", mlt_properties_serialise_yaml( doc ) );
+ s = mlt_properties_serialise_yaml( doc );
+ fprintf( stdout, "%s", s );
+ free( s );
mlt_properties_close( doc );
error = 1;
}
profile->height = height;
}
+ 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 );
+ 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 * height / width, 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, "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 ) );
+ }
+ }
+
// Handle the ffmpeg command line "-r" property for frame rate
if ( mlt_properties_get( properties, "r" ) )
{
// 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, consumer );
+
+ // Set the running state
+ mlt_properties_set_int( properties, "running", 1 );
}
return error;
}
{
// Get the properties
mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
+ pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL );
// Check that we're running
- if ( mlt_properties_get_int( properties, "running" ) )
+ if ( thread )
{
- // 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 );
+
+ mlt_properties_set_data( properties, "thread", NULL, 0, NULL, NULL );
}
return 0;
{
int i;
int count = mlt_properties_count( properties );
+#if LIBAVUTIL_VERSION_INT < ((51<<16)+(12<<8)+0)
int alloc = 1;
+#endif
for ( i = 0; i < count; i++ )
{
const char *opt_name = mlt_properties_get_name( properties, i );
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(10<<8)+0)
+ const AVOption *opt = av_opt_find( obj, opt_name, NULL, flags, flags );
+#else
const AVOption *opt = av_find_opt( obj, opt_name, NULL, flags, flags );
+#endif
// If option not found, see if it was prefixed with a or v (-vb)
if ( !opt && (
( opt_name[0] == 'v' && ( flags & AV_OPT_FLAG_VIDEO_PARAM ) ) ||
( opt_name[0] == 'a' && ( flags & AV_OPT_FLAG_AUDIO_PARAM ) ) ) )
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(10<<8)+0)
+ opt = av_opt_find( obj, ++opt_name, NULL, flags, flags );
+#else
opt = av_find_opt( obj, ++opt_name, NULL, flags, flags );
+#endif
// Apply option if found
if ( opt )
-#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(7<<8)+0)
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(12<<8)+0)
+ av_opt_set( obj, opt_name, mlt_properties_get_value( properties, i), 0 );
+#elif LIBAVCODEC_VERSION_INT >= ((52<<16)+(7<<8)+0)
av_set_string3( obj, opt_name, mlt_properties_get_value( properties, i), alloc, NULL );
#elif LIBAVCODEC_VERSION_INT >= ((51<<16)+(59<<8)+0)
av_set_string2( obj, opt_name, mlt_properties_get_value( properties, i), alloc );
}
}
+static int get_mlt_audio_format( int av_sample_fmt )
+{
+ switch ( av_sample_fmt )
+ {
+ case AV_SAMPLE_FMT_U8:
+ return mlt_audio_u8;
+ case AV_SAMPLE_FMT_S32:
+ return mlt_audio_s32le;
+ case AV_SAMPLE_FMT_FLT:
+ return mlt_audio_f32le;
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ case AV_SAMPLE_FMT_U8P:
+ return mlt_audio_u8;
+ case AV_SAMPLE_FMT_S32P:
+ return mlt_audio_s32le;
+ case AV_SAMPLE_FMT_FLTP:
+ return mlt_audio_f32le;
+#endif
+ default:
+ return mlt_audio_s16;
+ }
+}
+
+static int pick_sample_fmt( mlt_properties properties, AVCodec *codec )
+{
+ int sample_fmt = AV_SAMPLE_FMT_S16;
+ const char *format = mlt_properties_get( properties, "mlt_audio_format" );
+ const int *p = codec->sample_fmts;
+
+ // get default av_sample_fmt from mlt_audio_format
+ if ( format )
+ {
+ if ( !strcmp( format, "s32le" ) )
+ sample_fmt = AV_SAMPLE_FMT_S32;
+ else if ( !strcmp( format, "f32le" ) )
+ sample_fmt = AV_SAMPLE_FMT_FLT;
+ else if ( !strcmp( format, "u8" ) )
+ sample_fmt = AV_SAMPLE_FMT_U8;
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ else if ( !strcmp( format, "s32" ) )
+ sample_fmt = AV_SAMPLE_FMT_S32P;
+ else if ( !strcmp( format, "float" ) )
+ sample_fmt = AV_SAMPLE_FMT_FLTP;
+#endif
+ }
+ // check if codec supports our mlt_audio_format
+ for ( ; *p != -1; p++ )
+ {
+ if ( *p == sample_fmt )
+ return sample_fmt;
+ }
+ // no match - pick first one we support
+ for ( p = codec->sample_fmts; *p != -1; p++ )
+ {
+ switch (*p)
+ {
+ case AV_SAMPLE_FMT_U8:
+ case AV_SAMPLE_FMT_S16:
+ case AV_SAMPLE_FMT_S32:
+ case AV_SAMPLE_FMT_FLT:
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ case AV_SAMPLE_FMT_U8P:
+ case AV_SAMPLE_FMT_S16P:
+ case AV_SAMPLE_FMT_S32P:
+ case AV_SAMPLE_FMT_FLTP:
+#endif
+ return *p;
+ default:
+ break;
+ }
+ }
+ mlt_log_error( properties, "audio codec sample_fmt not compatible" );
+
+ return AV_SAMPLE_FMT_NONE;
+}
+
+static uint8_t* interleaved_to_planar( int samples, int channels, uint8_t* audio, int bytes_per_sample )
+{
+ int size = samples * channels * bytes_per_sample;
+ uint8_t *buffer = mlt_pool_alloc( AUDIO_ENCODE_BUFFER_SIZE );
+ uint8_t *p = buffer;
+ int c;
+
+ memset( buffer, 0, AUDIO_ENCODE_BUFFER_SIZE );
+ for ( c = 0; c < channels; c++ )
+ {
+ uint8_t *q = audio + c * bytes_per_sample;
+ int i = samples + 1;
+ while ( --i )
+ {
+ memcpy( p, q, bytes_per_sample );
+ p += bytes_per_sample;
+ q += channels * bytes_per_sample;
+ }
+ }
+ return buffer;
+}
+
/** Add an audio output stream
*/
mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
// Create a new stream
+#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(10<<8)+0)
+ AVStream *st = avformat_new_stream( oc, codec );
+#else
AVStream *st = av_new_stream( oc, oc->nb_streams );
+#endif
// If created, then initialise from properties
if ( st != NULL )
c->codec_id = codec->id;
c->codec_type = CODEC_TYPE_AUDIO;
- c->sample_fmt = SAMPLE_FMT_S16;
+ c->sample_fmt = pick_sample_fmt( properties, codec );
#if 0 // disabled until some audio codecs are multi-threaded
// Setup multi-threading
if ( audio_qscale > QSCALE_NONE )
{
c->flags |= CODEC_FLAG_QSCALE;
- c->global_quality = st->quality = FF_QP2LAMBDA * audio_qscale;
+ c->global_quality = FF_QP2LAMBDA * audio_qscale;
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+ st->quality = c->global_quality;
+#endif
}
// Set parameters controlled by MLT
if ( mlt_properties_get( properties, "alang" ) != NULL )
#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(43<<8)+0)
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(8<<8)+0)
+ av_dict_set( &oc->metadata, "language", mlt_properties_get( properties, "alang" ), 0 );
+#else
av_metadata_set2( &oc->metadata, "language", mlt_properties_get( properties, "alang" ), 0 );
+#endif
#else
strncpy( st->language, mlt_properties_get( properties, "alang" ), sizeof( st->language ) );
else
codec = avcodec_find_encoder( c->codec_id );
-#if LIBAVCODEC_VERSION_MAJOR >= 53
+#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(122<<8)+0)
// Process properties as AVOptions on the AVCodec
if ( codec && codec->priv_class )
{
}
#endif
- avformat_lock();
-
// Continue if codec found and we can open it
- if ( codec != NULL && avcodec_open( c, codec ) >= 0 )
+#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
+ if ( codec && avcodec_open2( c, codec, NULL ) >= 0 )
+#else
+ if ( codec && avcodec_open( c, codec ) >= 0 )
+#endif
{
// ugly hack for PCM codecs (will be removed ASAP with new PCM
// support to compute the input frame size in samples
else
{
mlt_log_warning( NULL, "%s: Unable to encode audio - disabling audio output.\n", __FILE__ );
+ audio_input_frame_size = 0;
}
-
- avformat_unlock();
return audio_input_frame_size;
}
static void close_audio( AVFormatContext *oc, AVStream *st )
{
if ( st && st->codec )
- {
- avformat_lock();
avcodec_close( st->codec );
- avformat_unlock();
- }
}
/** Add a video output stream
mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
// Create a new stream
+#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(10<<8)+0)
+ AVStream *st = avformat_new_stream( oc, codec );
+#else
AVStream *st = av_new_stream( oc, oc->nb_streams );
+#endif
if ( st != NULL )
{
{
// "-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( consumer ) );
- 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 ) );
- }
+ c->sample_aspect_ratio = av_d2q( ar * c->height / c->width, 255 );
}
else
{
if ( mlt_properties_get_double( properties, "qscale" ) > 0 )
{
c->flags |= CODEC_FLAG_QSCALE;
- st->quality = FF_QP2LAMBDA * mlt_properties_get_double( properties, "qscale" );
+ c->global_quality = FF_QP2LAMBDA * mlt_properties_get_double( properties, "qscale" );
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+ st->quality = c->global_quality;
+#endif
}
// Allow the user to override the video fourcc
mlt_log_fatal( MLT_CONSUMER_SERVICE( consumer ), "Could not allocate log buffer\n" );
else
{
- size = fread( logbuffer, 1, size, f );
- fclose( f );
- logbuffer[size] = '\0';
- c->stats_in = logbuffer;
+ if ( size >= 0 )
+ {
+ size = fread( logbuffer, 1, size, f );
+ logbuffer[size] = '\0';
+ c->stats_in = logbuffer;
+ }
}
+ fclose( f );
}
}
}
else
codec = avcodec_find_encoder( video_enc->codec_id );
-#if LIBAVCODEC_VERSION_MAJOR >= 53
+#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(122<<8)+0)
// Process properties as AVOptions on the AVCodec
if ( codec && codec->priv_class )
{
video_enc->pix_fmt = codec->pix_fmts[ 0 ];
}
- // Open the codec safely
- avformat_lock();
- int result = codec != NULL && avcodec_open( video_enc, codec ) >= 0;
- avformat_unlock();
+#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
+ int result = codec && avcodec_open2( video_enc, codec, NULL ) >= 0;
+#else
+ int result = codec && avcodec_open( video_enc, codec ) >= 0;
+#endif
return result;
}
{
if ( st && st->codec )
{
- avformat_lock();
av_freep( &st->codec->stats_in );
avcodec_close(st->codec);
- avformat_unlock();
}
}
listener( owner, service, (uint8_t*) args[0], (int) args[1] );
}
-
/** The main thread - the argument is simply the consumer.
*/
int img_height = height;
// Get default audio properties
- mlt_audio_format aud_fmt = mlt_audio_s16;
int channels = mlt_properties_get_int( properties, "channels" );
int total_channels = channels;
int frequency = mlt_properties_get_int( properties, "frequency" );
- int16_t *pcm = NULL;
+ void *pcm = NULL;
int samples = 0;
// AVFormat audio buffer and frame size
mlt_image_format img_fmt = mlt_image_yuv422;
// For receiving audio samples back from the fifo
- int16_t *audio_buf_1 = av_malloc( AUDIO_ENCODE_BUFFER_SIZE );
- int16_t *audio_buf_2 = NULL;
+ uint8_t *audio_buf_1 = av_malloc( AUDIO_ENCODE_BUFFER_SIZE );
+ uint8_t *audio_buf_2 = NULL;
int count = 0;
// Allocate the context
acodec = mlt_properties_get( properties, "_acodec" );
audio_codec = avcodec_find_encoder_by_name( acodec );
}
+ else if ( !strcmp( acodec, "aac" ) )
+ {
+ mlt_properties_set( properties, "astrict", "experimental" );
+ }
}
else
{
markup[0] = '\0';
if ( !strstr( key, ".stream." ) )
#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(43<<8)+0)
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(8<<8)+0)
+ av_dict_set( &oc->metadata, key, mlt_properties_get_value( properties, i ), 0 );
+#else
av_metadata_set2( &oc->metadata, key, mlt_properties_get_value( properties, i ), 0 );
+#endif
#else
av_metadata_set( &oc->metadata, key, mlt_properties_get_value( properties, i ) );
#endif
frame = mlt_consumer_rt_frame( consumer );
// Set the timecode from the MLT metadata if available.
- const char *timecode = mlt_properties_get( MLT_FRAME_PROPERTIES(frame), "meta.attr.vitc.markup" );
- if ( timecode && strcmp( timecode, "" ) )
- {
- mlt_properties_set( properties, "timecode", timecode );
- if ( strchr( timecode, ';' ) )
- mlt_properties_set_int( properties, "drop_frame_timecode", 1 );
- }
+ if ( frame )
+ {
+ const char *timecode = mlt_properties_get( MLT_FRAME_PROPERTIES(frame), "meta.attr.vitc.markup" );
+ if ( timecode && strcmp( timecode, "" ) )
+ {
+ mlt_properties_set( properties, "timecode", timecode );
+ if ( strchr( timecode, ';' ) )
+ mlt_properties_set_int( properties, "drop_frame_timecode", 1 );
+ }
+ }
// Add audio and video streams
if ( video_codec_id != CODEC_ID_NONE )
}
mlt_properties_set_int( properties, "channels", total_channels );
+ // Audio format is determined when adding the audio stream
+ mlt_audio_format aud_fmt = mlt_audio_none;
+ if ( audio_st[0] )
+ aud_fmt = get_mlt_audio_format( audio_st[0]->codec->sample_fmt );
+ int sample_bytes = mlt_audio_format_size( aud_fmt, 1, 1 );
+ sample_bytes = sample_bytes ? sample_bytes : 1; // prevent divide by zero
+
// Set the parameters (even though we have none...)
- if ( av_set_parameters(oc, NULL) >= 0 )
+#if LIBAVFORMAT_VERSION_INT < ((53<<16)+(2<<8)+0)
+ if ( av_set_parameters(oc, NULL) >= 0 )
+#endif
{
+#if LIBAVFORMAT_VERSION_MAJOR >= 53
+ if ( mlt_properties_get( properties, "muxpreload" ) && ! mlt_properties_get( properties, "preload" ) )
+ mlt_properties_set_double( properties, "preload", mlt_properties_get_double( properties, "muxpreload" ) );
+#else
oc->preload = ( int )( mlt_properties_get_double( properties, "muxpreload" ) * AV_TIME_BASE );
+#endif
oc->max_delay= ( int )( mlt_properties_get_double( properties, "muxdelay" ) * AV_TIME_BASE );
// Process properties as AVOptions
{
mlt_properties p = mlt_properties_load( fpre );
apply_properties( oc, p, AV_OPT_FLAG_ENCODING_PARAM );
-#if LIBAVFORMAT_VERSION_MAJOR >= 53
+#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(110<<8)+0)
if ( oc->oformat && oc->oformat->priv_class && oc->priv_data )
apply_properties( oc->priv_data, p, AV_OPT_FLAG_ENCODING_PARAM );
#endif
mlt_properties_close( p );
}
apply_properties( oc, properties, AV_OPT_FLAG_ENCODING_PARAM );
-#if LIBAVFORMAT_VERSION_MAJOR >= 53
+#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(110<<8)+0)
if ( oc->oformat && oc->oformat->priv_class && oc->priv_data )
apply_properties( oc->priv_data, properties, AV_OPT_FLAG_ENCODING_PARAM );
#endif
audio_input_frame_size = open_audio( properties, oc, audio_st[i], audio_outbuf_size,
acodec? acodec : NULL );
if ( !audio_input_frame_size )
+ {
+ // Remove the audio stream from the output context
+ int j;
+ for ( j = 0; j < oc->nb_streams; j++ )
+ {
+ if ( oc->streams[j] == audio_st[i] )
+ av_freep( &oc->streams[j] );
+ }
+ --oc->nb_streams;
audio_st[i] = NULL;
+ }
}
// Setup custom I/O if redirecting
#endif
{
mlt_log_error( MLT_CONSUMER_SERVICE( consumer ), "Could not open '%s'\n", filename );
- mlt_properties_set_int( properties, "running", 0 );
+ mlt_events_fire( properties, "consumer-fatal-error", NULL );
+ goto on_fatal_error;
}
}
// Write the stream header.
if ( mlt_properties_get_int( properties, "running" ) )
+#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(2<<8)+0)
+ avformat_write_header( oc, NULL );
+#else
av_write_header( oc );
+#endif
}
+#if LIBAVFORMAT_VERSION_INT < ((53<<16)+(2<<8)+0)
else
{
mlt_log_error( MLT_CONSUMER_SERVICE( consumer ), "Invalid output format parameters\n" );
- mlt_properties_set_int( properties, "running", 0 );
+ mlt_events_fire( properties, "consumer-fatal-error", NULL );
+ goto on_fatal_error;
}
+#endif
// Allocate picture
if ( video_st )
// Last check - need at least one stream
if ( !audio_st[0] && !video_st )
- mlt_properties_set_int( properties, "running", 0 );
+ {
+ mlt_events_fire( properties, "consumer-fatal-error", NULL );
+ goto on_fatal_error;
+ }
// Get the starting time (can ignore the times above)
gettimeofday( &ante, NULL );
{
samples = mlt_sample_calculator( fps, frequency, count ++ );
channels = total_channels;
- mlt_frame_get_audio( frame, (void**) &pcm, &aud_fmt, &frequency, &channels, &samples );
+ mlt_frame_get_audio( frame, &pcm, &aud_fmt, &frequency, &channels, &samples );
// Save the audio channel remap properties for later
mlt_properties_pass( frame_meta_properties, frame_properties, "meta.map.audio." );
fifo = sample_fifo_init( frequency, channels );
mlt_properties_set_data( properties, "sample_fifo", fifo, 0, ( mlt_destructor )sample_fifo_close, NULL );
}
+ if ( pcm )
+ {
+ // Silence if not normal forward speed
+ if ( mlt_properties_get_double( frame_properties, "_speed" ) != 1.0 )
+ memset( pcm, 0, samples * channels * sample_bytes );
- // Silence if not normal forward speed
- 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;
-
+ // Append the samples
+ sample_fifo_append( fifo, pcm, samples * channels * sample_bytes );
+ total_time += ( samples * 1000000 ) / frequency;
+ }
if ( !video_st )
mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
}
if ( !video_st || ( video_st && audio_st[0] && audio_pts < video_pts ) )
{
// Write audio
- if ( ( video_st && terminated ) || ( channels * audio_input_frame_size ) < sample_fifo_used( fifo ) )
+ if ( ( video_st && terminated ) || ( channels * audio_input_frame_size ) < sample_fifo_used( fifo ) / sample_bytes )
{
int j = 0; // channel offset into interleaved source buffer
- int n = FFMIN( FFMIN( channels * audio_input_frame_size, sample_fifo_used( fifo ) ), AUDIO_ENCODE_BUFFER_SIZE );
+ int n = FFMIN( FFMIN( channels * audio_input_frame_size, sample_fifo_used( fifo ) / sample_bytes ), AUDIO_ENCODE_BUFFER_SIZE );
// Get the audio samples
if ( n > 0 )
{
- sample_fifo_fetch( fifo, audio_buf_1, n );
+ sample_fifo_fetch( fifo, audio_buf_1, n * sample_bytes );
}
else if ( audio_codec_id == CODEC_ID_VORBIS && terminated )
{
// Optimized for single track and no channel remap
if ( !audio_st[1] && !mlt_properties_count( frame_meta_properties ) )
{
- pkt.size = avcodec_encode_audio( codec, audio_outbuf, audio_outbuf_size, audio_buf_1 );
+ void* p = audio_buf_1;
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ if ( codec->sample_fmt == AV_SAMPLE_FMT_FLTP )
+ p = interleaved_to_planar( samples, channels, p, sizeof( float ) );
+ else if ( codec->sample_fmt == AV_SAMPLE_FMT_S16P )
+ p = interleaved_to_planar( samples, channels, p, sizeof( int16_t ) );
+ else if ( codec->sample_fmt == AV_SAMPLE_FMT_S32P )
+ p = interleaved_to_planar( samples, channels, p, sizeof( int32_t ) );
+ else if ( codec->sample_fmt == AV_SAMPLE_FMT_U8P )
+ p = interleaved_to_planar( samples, channels, p, sizeof( uint8_t ) );
+#endif
+ pkt.size = avcodec_encode_audio( codec, audio_outbuf, audio_outbuf_size, p );
+
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ if ( p != audio_buf_1 )
+ mlt_pool_release( p );
+#endif
}
else
{
// Interleave the audio buffer with the # channels for this stream/mapping.
for ( k = 0; k < map_channels; k++, j++, source_offset++, dest_offset++ )
{
- int16_t *src = audio_buf_1 + source_offset;
- int16_t *dest = audio_buf_2 + dest_offset;
+ void *src = audio_buf_1 + source_offset * sample_bytes;
+ void *dest = audio_buf_2 + dest_offset * sample_bytes;
int s = samples + 1;
while ( --s ) {
- *dest = *src;
- dest += current_channels;
- src += channels;
+ memcpy( dest, src, sample_bytes );
+ dest += current_channels * sample_bytes;
+ src += channels * sample_bytes;
}
}
}
dest_offset += current_channels;
}
}
- pkt.size = avcodec_encode_audio( codec, audio_outbuf, audio_outbuf_size, audio_buf_2 );
+ pkt.size = avcodec_encode_audio( codec, audio_outbuf, audio_outbuf_size, (short*) audio_buf_2 );
}
// Write the compressed frame in the media file
// Do the colour space conversion
#ifdef SWSCALE
- int flags = SWS_BILINEAR;
+ int flags = SWS_BICUBIC;
#ifdef USE_MMX
flags |= SWS_CPU_CAPS_MMX;
#endif
AVPacket pkt;
av_init_packet(&pkt);
+ // Set frame interlace hints
+ c->coded_frame->interlaced_frame = !mlt_properties_get_int( frame_properties, "progressive" );
+ c->coded_frame->top_field_first = mlt_properties_get_int( frame_properties, "top_field_first" );
+#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(61<<8)+100)
+ if ( mlt_properties_get_int( frame_properties, "progressive" ) )
+ c->field_order = AV_FIELD_PROGRESSIVE;
+ else
+ c->field_order = (mlt_properties_get_int( frame_properties, "top_field_first" )) ? AV_FIELD_TT : AV_FIELD_BB;
+#endif
pkt.flags |= PKT_FLAG_KEY;
pkt.stream_index= video_st->index;
pkt.data= (uint8_t *)output;
else
{
// Set the quality
- output->quality = video_st->quality;
+ output->quality = c->global_quality;
// Set frame interlace hints
output->interlaced_frame = !mlt_properties_get_int( frame_properties, "progressive" );
long passed = time_difference( &ante );
if ( fifo != NULL )
{
- long pending = ( ( ( long )sample_fifo_used( fifo ) * 1000 ) / frequency ) * 1000;
+ long pending = ( ( ( long )sample_fifo_used( fifo ) / sample_bytes * 1000 ) / frequency ) * 1000;
passed -= pending;
}
if ( passed < total_time )
av_init_packet( &pkt );
pkt.size = 0;
- if ( /*( c->capabilities & CODEC_CAP_SMALL_LAST_FRAME ) &&*/
- ( channels * audio_input_frame_size < sample_fifo_used( fifo ) ) )
+ if ( fifo &&
+ ( channels * audio_input_frame_size < sample_fifo_used( fifo ) / sample_bytes ) )
{
- sample_fifo_fetch( fifo, audio_buf_1, channels * audio_input_frame_size );
- pkt.size = avcodec_encode_audio( c, audio_outbuf, audio_outbuf_size, audio_buf_1 );
+ sample_fifo_fetch( fifo, audio_buf_1, channels * audio_input_frame_size * sample_bytes );
+ void* p = audio_buf_1;
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ if ( c->sample_fmt == AV_SAMPLE_FMT_FLTP )
+ p = interleaved_to_planar( audio_input_frame_size, channels, p, sizeof( float ) );
+ else if ( c->sample_fmt == AV_SAMPLE_FMT_S16P )
+ p = interleaved_to_planar( audio_input_frame_size, channels, p, sizeof( int16_t ) );
+ else if ( c->sample_fmt == AV_SAMPLE_FMT_S32P )
+ p = interleaved_to_planar( audio_input_frame_size, channels, p, sizeof( int32_t ) );
+ else if ( c->sample_fmt == AV_SAMPLE_FMT_U8P )
+ p = interleaved_to_planar( audio_input_frame_size, channels, p, sizeof( uint8_t ) );
+#endif
+ pkt.size = avcodec_encode_audio( c, audio_outbuf, audio_outbuf_size, p );
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ if ( p != audio_buf_1 )
+ mlt_pool_release( p );
+#endif
}
if ( pkt.size <= 0 )
pkt.size = avcodec_encode_audio( c, audio_outbuf, audio_outbuf_size, NULL );
on_fatal_error:
// Write the trailer, if any
- av_write_trailer( oc );
+ if ( frames )
+ av_write_trailer( oc );
// close each codec
if ( video_st )
av_freep( &oc->streams[i] );
// Close the output file
- if ( !( fmt->flags & AVFMT_NOFILE ) )
+ if ( !( fmt->flags & AVFMT_NOFILE ) &&
+ !mlt_properties_get_int( properties, "redirect" ) )
{
#if LIBAVFORMAT_VERSION_MAJOR >= 53
- if ( !mlt_properties_get_int( properties, "redirect" ) )
- avio_close( oc->pb );
+ if ( oc->pb ) avio_close( oc->pb );
#elif LIBAVFORMAT_VERSION_MAJOR >= 52
- url_fclose( oc->pb );
+ if ( oc->pb ) url_fclose( oc->pb );
#else
url_fclose( &oc->pb );
#endif
av_free( oc );
// Just in case we terminated on pause
- mlt_properties_set_int( properties, "running", 0 );
-
mlt_consumer_stopped( consumer );
mlt_properties_close( frame_meta_properties );
/*
* factory.c -- the factory method interfaces
- * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Copyright (C) 2003-2012 Ushodaya Enterprises Limited
* Author: Charles Yates <charles.yates@pandora.be>
*
* This library is free software; you can redistribute it and/or
#include <libavcodec/opt.h>
#endif
+#if LIBAVUTIL_VERSION_INT < ((51<<16)+(12<<8)+0)
+#define AV_OPT_TYPE_FLAGS FF_OPT_TYPE_FLAGS
+#define AV_OPT_TYPE_INT FF_OPT_TYPE_INT
+#define AV_OPT_TYPE_INT64 FF_OPT_TYPE_INT64
+#define AV_OPT_TYPE_DOUBLE FF_OPT_TYPE_DOUBLE
+#define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT
+#define AV_OPT_TYPE_STRING FF_OPT_TYPE_STRING
+#define AV_OPT_TYPE_RATIONAL FF_OPT_TYPE_RATIONAL
+#define AV_OPT_TYPE_BINARY FF_OPT_TYPE_BINARY
+#define AV_OPT_TYPE_CONST FF_OPT_TYPE_CONST
+#endif
+
// 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 )
+static int avformat_lockmgr(void **mutex, enum AVLockOp op)
{
- return mlt_pool_alloc( size );
-}
+ pthread_mutex_t** pmutex = (pthread_mutex_t**) mutex;
-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
+ switch (op)
+ {
+ case AV_LOCK_CREATE:
+ *pmutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
+ pthread_mutex_init(*pmutex, NULL);
+ break;
+ case AV_LOCK_OBTAIN:
+ pthread_mutex_lock(*pmutex);
+ break;
+ case AV_LOCK_RELEASE:
+ pthread_mutex_unlock(*pmutex);
+ break;
+ case AV_LOCK_DESTROY:
+ pthread_mutex_destroy(*pmutex);
+ free(*pmutex);
+ break;
+ }
- // 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 );
+ return 0;
}
static void avformat_init( )
if ( avformat_initialised == 0 )
{
avformat_initialised = 1;
- pthread_mutex_init( &avformat_mutex, NULL );
+ av_lockmgr_register( &avformat_lockmgr );
av_register_all( );
#ifdef AVDEVICE
avdevice_register_all();
#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(13<<8))
avformat_network_init();
#endif
- mlt_factory_register_for_clean_up( NULL, avformat_destroy );
av_log_set_level( mlt_log_get_level() );
}
}
return filter_avcolour_space_init( arg );
if ( !strcmp( id, "avdeinterlace" ) )
return filter_avdeinterlace_init( arg );
+#if LIBAVCODEC_VERSION_INT < ((54<<16)+(26<<8)+0)
if ( !strcmp( id, "avresample" ) )
return filter_avresample_init( arg );
+#endif
#ifdef SWSCALE
if ( !strcmp( id, "swscale" ) )
return filter_swscale_init( profile, arg );
const AVOption *opt = NULL;
// For each AVOption on the AVClass object
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(12<<8)+0)
+ while ( ( opt = av_opt_next( object, opt ) ) )
+#else
while ( ( opt = av_next_option( object, opt ) ) )
+#endif
{
// If matches flags and not a binary option (not supported by Mlt)
- if ( !( opt->flags & req_flags ) || ( opt->type == FF_OPT_TYPE_BINARY ) )
+ if ( !( opt->flags & req_flags ) || ( opt->type == AV_OPT_TYPE_BINARY ) )
continue;
// Ignore constants (keyword values)
- if ( !unit && opt->type == FF_OPT_TYPE_CONST )
+ if ( !unit && opt->type == AV_OPT_TYPE_CONST )
continue;
// When processing a groups of options (unit)...
// ...ignore non-constants
- else if ( unit && opt->type != FF_OPT_TYPE_CONST )
+ else if ( unit && opt->type != AV_OPT_TYPE_CONST )
continue;
// ...ignore constants not in this group
- else if ( unit && opt->type == FF_OPT_TYPE_CONST && strcmp( unit, opt->unit ) )
+ else if ( unit && opt->type == AV_OPT_TYPE_CONST && strcmp( unit, opt->unit ) )
continue;
// ..add constants to the 'values' sequence
- else if ( unit && opt->type == FF_OPT_TYPE_CONST )
+ else if ( unit && opt->type == AV_OPT_TYPE_CONST )
{
char key[20];
snprintf( key, 20, "%d", mlt_properties_count( params ) );
switch ( opt->type )
{
- case FF_OPT_TYPE_FLAGS:
+ case AV_OPT_TYPE_FLAGS:
mlt_properties_set( p, "type", "string" );
mlt_properties_set( p, "format", "flags" );
break;
- case FF_OPT_TYPE_INT:
+ case AV_OPT_TYPE_INT:
if ( !opt->unit )
{
mlt_properties_set( p, "type", "integer" );
mlt_properties_set( p, "format", "integer or keyword" );
}
break;
- case FF_OPT_TYPE_INT64:
+ case AV_OPT_TYPE_INT64:
mlt_properties_set( p, "type", "integer" );
mlt_properties_set( p, "format", "64-bit" );
if ( opt->min != INT64_MIN )
mlt_properties_set_int64( p, "default", (int64_t) opt->default_val.dbl );
#endif
break;
- case FF_OPT_TYPE_FLOAT:
+ case AV_OPT_TYPE_FLOAT:
mlt_properties_set( p, "type", "float" );
if ( opt->min != FLT_MIN && opt->min != -340282346638528859811704183484516925440.0 )
mlt_properties_set_double( p, "minimum", opt->min );
mlt_properties_set_double( p, "default", opt->default_val.dbl );
#endif
break;
- case FF_OPT_TYPE_DOUBLE:
+ case AV_OPT_TYPE_DOUBLE:
mlt_properties_set( p, "type", "float" );
mlt_properties_set( p, "format", "double" );
if ( opt->min != DBL_MIN )
mlt_properties_set_double( p, "default", opt->default_val.dbl );
#endif
break;
- case FF_OPT_TYPE_STRING:
+ case AV_OPT_TYPE_STRING:
mlt_properties_set( p, "type", "string" );
#if LIBAVUTIL_VERSION_MAJOR > 50
mlt_properties_set( p, "default", opt->default_val.str );
#endif
break;
- case FF_OPT_TYPE_RATIONAL:
+ case AV_OPT_TYPE_RATIONAL:
mlt_properties_set( p, "type", "string" );
mlt_properties_set( p, "format", "numerator:denominator" );
break;
- case FF_OPT_TYPE_CONST:
+ case AV_OPT_TYPE_CONST:
default:
mlt_properties_set( p, "type", "integer" );
mlt_properties_set( p, "format", "constant" );
break;
}
// If the option belongs to a group (unit) and is not a constant (keyword value)
- if ( opt->unit && opt->type != FF_OPT_TYPE_CONST )
+ if ( opt->unit && opt->type != AV_OPT_TYPE_CONST )
{
// Create a 'values' sequence.
mlt_properties values = mlt_properties_new();
// Annotate the yaml properties with AVOptions.
mlt_properties params = (mlt_properties) mlt_properties_get_data( result, "parameters", NULL );
AVFormatContext *avformat = avformat_alloc_context();
+#if LIBAVCODEC_VERSION_INT > ((53<<16)+(8<<8)+0)
+ AVCodecContext *avcodec = avcodec_alloc_context3( NULL );
+#else
AVCodecContext *avcodec = avcodec_alloc_context();
+#endif
int flags = ( type == consumer_type )? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
add_parameters( params, avformat, flags, NULL, NULL );
MLT_REGISTER( filter_type, "avcolour_space", create_service );
MLT_REGISTER( filter_type, "avcolor_space", create_service );
MLT_REGISTER( filter_type, "avdeinterlace", create_service );
+#if LIBAVCODEC_VERSION_INT < ((54<<16)+(26<<8)+0)
MLT_REGISTER( filter_type, "avresample", create_service );
+#endif
#ifdef SWSCALE
MLT_REGISTER( filter_type, "swscale", create_service );
#endif
case mlt_image_yuv420p:
value = PIX_FMT_YUV420P;
break;
- case mlt_image_none:
- mlt_log_error( NULL, "[filter avcolor_space] Invalid format\n" );
+ default:
+ mlt_log_error( NULL, "[filter avcolor_space] Invalid format %s\n",
+ mlt_image_format_name( format ) );
break;
}
AVPicture input;
AVPicture output;
#ifdef SWSCALE
- int flags = SWS_BILINEAR | SWS_ACCURATE_RND;
+ int flags = SWS_BICUBIC | SWS_ACCURATE_RND;
if ( out_fmt == PIX_FMT_YUYV422 )
flags |= SWS_FULL_CHR_H_INP;
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 );
+ int size = FFMAX( avpicture_get_size( out_fmt, width, height ),
+ mlt_image_format_size( output_format, width, height, NULL ) );
uint8_t *output = mlt_pool_alloc( size );
if ( *format == mlt_image_rgb24a || *format == mlt_image_opengl )
while ( --n > 0 );
}
mlt_frame_set_alpha( frame, alpha, len, mlt_pool_release );
- frame->get_alpha_mask = NULL;
}
}
if ( mlt_properties_get_int( properties, "colorspace" ) <= 0 )
mlt_properties_set_int( properties, "colorspace", mlt_service_profile( MLT_FILTER_SERVICE(filter) )->colorspace );
- frame->convert_image = convert_image;
-
+ if ( !frame->convert_image )
+ frame->convert_image = convert_image;
+
// Not working yet - see comment for get_image() above.
// mlt_frame_push_service( frame, mlt_service_profile( MLT_FILTER_SERVICE( filter ) ) );
// mlt_frame_push_get_image( frame, get_image );
#include "mmx.h"
#else
#define MAX_NEG_CROP 1024
-extern uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP];
+static uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0,};
#endif
#ifdef USE_MMX
mlt_filter filter_avdeinterlace_init( void *arg )
{
+#ifndef USE_MMX
+ if ( ff_cropTbl[MAX_NEG_CROP + 1] == 0 )
+ {
+ int i;
+ for(i=0;i<256;i++) ff_cropTbl[i + MAX_NEG_CROP] = i;
+ for(i=0;i<MAX_NEG_CROP;i++) {
+ ff_cropTbl[i] = 0;
+ ff_cropTbl[i + MAX_NEG_CROP + 256] = 255;
+ }
+ }
+#endif
mlt_filter filter = mlt_filter_new( );
if ( filter != NULL )
filter->process = deinterlace_process;
// ffmpeg Header files
#include <libavformat/avformat.h>
+#if LIBAVUTIL_VERSION_INT >= ((50<<16)+(38<<8)+0)
+# include <libavutil/samplefmt.h>
+#else
+# define AV_SAMPLE_FMT_S16 SAMPLE_FMT_S16
+#endif
+
+#if LIBAVCODEC_VERSION_INT < ((54<<16)+(26<<8)+0)
/** Get the audio.
*/
// Create the resampler
#if (LIBAVCODEC_VERSION_INT >= ((52<<16)+(15<<8)+0))
resample = av_audio_resample_init( *channels, *channels, output_rate, *frequency,
- SAMPLE_FMT_S16, SAMPLE_FMT_S16, 16, 10, 0, 0.8 );
+ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16, 16, 10, 0, 0.8 );
#else
resample = audio_resample_init( *channels, *channels, output_rate, *frequency );
#endif
return filter;
}
+
+#endif // LIBAVCODEC_VERSION_INT < ((54<<16)+(26<<8)+0)
case mlt_image_yuv420p:
value = PIX_FMT_YUV420P;
break;
- case mlt_image_none:
+ default:
fprintf( stderr, "Invalid format...\n" );
break;
}
/*
* producer_avformat.c -- avformat producer
- * Copyright (C) 2003-2009 Ushodaya Enterprises Limited
+ * Copyright (C) 2003-2012 Ushodaya Enterprises Limited
* Author: Charles Yates <charles.yates@pandora.be>
* Author: Dan Dennedy <dan@dennedy.org>
* Much code borrowed from ffmpeg.c: Copyright (c) 2000-2003 Fabrice Bellard
#ifdef SWSCALE
# include <libswscale/swscale.h>
#endif
-#if LIBAVCODEC_VERSION_MAJOR >= 53
-#include <libavutil/samplefmt.h>
-#elif (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0))
+
+#if LIBAVUTIL_VERSION_INT >= ((50<<16)+(38<<8)+0)
+# include <libavutil/samplefmt.h>
+#else
+# define AV_SAMPLE_FMT_U8 SAMPLE_FMT_U8
+# define AV_SAMPLE_FMT_S16 SAMPLE_FMT_S16
+# define AV_SAMPLE_FMT_S32 SAMPLE_FMT_S32
+# define AV_SAMPLE_FMT_FLT SAMPLE_FMT_FLT
+# if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0))
const char *avcodec_get_sample_fmt_name(int sample_fmt);
+# endif
#endif
+
#ifdef VDPAU
# include <libavcodec/vdpau.h>
#endif
#if (LIBAVUTIL_VERSION_INT > ((50<<16)+(7<<8)+0))
# include <libavutil/pixdesc.h>
#endif
+#if (LIBAVUTIL_VERSION_INT >= ((51<<16)+(8<<8)+0))
+# include <libavutil/dict.h>
+#endif
// System header files
#include <stdlib.h>
#define POSITION_INITIAL (-2)
#define POSITION_INVALID (-1)
-#define MAX_AUDIO_STREAMS (10)
+#define MAX_AUDIO_STREAMS (32)
#define MAX_VDPAU_SURFACES (10)
-void avformat_lock( );
-void avformat_unlock( );
-
struct producer_avformat_s
{
mlt_producer parent;
AVCodecContext *audio_codec[ MAX_AUDIO_STREAMS ];
AVCodecContext *video_codec;
AVFrame *av_frame;
+ AVPacket pkt;
ReSampleContext *audio_resample[ MAX_AUDIO_STREAMS ];
mlt_position audio_expected;
mlt_position video_expected;
int audio_index;
int video_index;
- int first_pts;
+ int64_t first_pts;
int64_t last_position;
int seekable;
int64_t current_position;
mlt_position nonseek_position;
- int got_picture;
int top_field_first;
uint8_t *audio_buffer[ MAX_AUDIO_STREAMS ];
size_t audio_buffer_size[ MAX_AUDIO_STREAMS ];
int max_channel;
int max_frequency;
unsigned int invalid_pts_counter;
+ unsigned int invalid_dts_counter;
double resample_factor;
mlt_cache image_cache;
int colorspace;
+ int full_luma;
pthread_mutex_t video_mutex;
pthread_mutex_t audio_mutex;
mlt_deque apackets;
mlt_deque vpackets;
pthread_mutex_t packets_mutex;
+ pthread_mutex_t open_mutex;
+ int is_mutex_init;
+ AVRational video_time_base;
#ifdef VDPAU
struct
{
static void apply_properties( void *obj, mlt_properties properties, int flags );
static int video_codec_init( producer_avformat self, int index, mlt_properties properties );
static void get_audio_streams_info( producer_avformat self );
+static mlt_audio_format pick_audio_format( int sample_fmt );
#ifdef VDPAU
#include "vdpau.c"
// Clean up
mlt_producer_close( producer );
producer = NULL;
+ producer_avformat_close( self );
}
else if ( self->seekable )
{
// Close the file to release resources for large playlists - reopen later as needed
- avformat_lock();
+#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(17<<8)+0)
+ if ( self->audio_format )
+ avformat_close_input( &self->audio_format );
+ if ( self->video_format )
+ avformat_close_input( &self->video_format );
+#else
if ( self->audio_format )
av_close_input_file( self->audio_format );
- self->audio_format = NULL;
if ( self->video_format )
av_close_input_file( self->video_format );
+#endif
+ self->audio_format = NULL;
self->video_format = NULL;
- avformat_unlock();
}
}
if ( producer )
return skip;
}
+static int first_video_index( producer_avformat self )
+{
+ AVFormatContext *context = self->video_format? self->video_format : self->audio_format;
+ int i = -1; // not found
+
+ if ( context ) {
+ for ( i = 0; i < context->nb_streams; i++ ) {
+ if ( context->streams[i]->codec &&
+ context->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO )
+ break;
+ }
+ if ( i == context->nb_streams )
+ i = -1;
+ }
+ return i;
+}
+
/** Find the default streams.
*/
{
int i;
char key[200];
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(8<<8)+0)
+ AVDictionaryEntry *tag = NULL;
+#else
AVMetadataTag *tag = NULL;
+#endif
AVFormatContext *context = self->video_format;
mlt_properties meta_media = MLT_PRODUCER_PROPERTIES( self->parent );
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.width", i );
+ mlt_properties_set_int( meta_media, key, codec_context->width );
+ snprintf( key, sizeof(key), "meta.media.%d.codec.height", i );
+ mlt_properties_set_int( meta_media, key, codec_context->height );
snprintf( key, sizeof(key), "meta.media.%d.codec.frame_rate", i );
mlt_properties_set_double( meta_media, key, (double) codec_context->time_base.den /
( codec_context->time_base.num == 0 ? 1 : codec_context->time_base.num ) );
snprintf( key, sizeof(key), "meta.media.%d.codec.pix_fmt", i );
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(3<<8)+0)
+ mlt_properties_set( meta_media, key, av_get_pix_fmt_name( codec_context->pix_fmt ) );
+#else
mlt_properties_set( meta_media, key, avcodec_get_pix_fmt_name( codec_context->pix_fmt ) );
+#endif
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 ) );
#if LIBAVCODEC_VERSION_INT > ((52<<16)+(28<<8)+0)
#endif
break;
case CODEC_TYPE_AUDIO:
+ if ( !codec_context->channels )
+ break;
// Use first audio stream
- if ( self->audio_index < 0 )
+ if ( self->audio_index < 0 && pick_audio_format( codec_context->sample_fmt ) != mlt_audio_none )
self->audio_index = i;
+
mlt_properties_set( meta_media, key, "audio" );
-#if LIBAVCODEC_VERSION_MAJOR >= 53
+#if LIBAVUTIL_VERSION_INT >= ((50<<16)+(38<<8)+0)
snprintf( key, sizeof(key), "meta.media.%d.codec.sample_fmt", i );
mlt_properties_set( meta_media, key, av_get_sample_fmt_name( codec_context->sample_fmt ) );
#elif (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0))
// Read Metadata
#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(31<<8)+0)
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(8<<8)+0)
+ while ( ( tag = av_dict_get( stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX ) ) )
+#else
while ( ( tag = av_metadata_get( stream->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX ) ) )
+#endif
{
if ( tag->value && strcmp( tag->value, "" ) && strcmp( tag->value, "und" ) )
{
#endif
}
#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(31<<8)+0)
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(8<<8)+0)
+ while ( ( tag = av_dict_get( context->metadata, "", tag, AV_DICT_IGNORE_SUFFIX ) ) )
+#else
while ( ( tag = av_metadata_get( context->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX ) ) )
+#endif
{
if ( tag->value && strcmp( tag->value, "" ) && strcmp( tag->value, "und" ) )
{
return aspect_ratio;
}
+#if LIBAVFORMAT_VERSION_INT > ((53<<16)+(6<<8)+0)
+static char* parse_url( mlt_profile profile, const char* URL, AVInputFormat **format, AVDictionary **params )
+#else
static char* parse_url( mlt_profile profile, const char* URL, AVInputFormat **format, AVFormatParameters *params )
+#endif
{
if ( !URL ) return NULL;
- const char *result = URL;
+ char *result = NULL;
char *protocol = strdup( URL );
char *url = strchr( protocol, ':' );
if ( *format )
{
+#if LIBAVFORMAT_VERSION_INT > ((53<<16)+(6<<8)+0)
+ // support for legacy width and height parameters
+ char *width = NULL;
+ char *height = NULL;
+#else
// These are required by video4linux2 (defaults)
params->width = profile->width;
params->height = profile->height;
params->time_base = (AVRational){ profile->frame_rate_den, profile->frame_rate_num };
params->channels = 2;
params->sample_rate = 48000;
+#endif
// Parse out params
url = strchr( url, '?' );
char *t = strchr( value, '&' );
if ( t )
t[0] = 0;
+#if LIBAVFORMAT_VERSION_INT > ((53<<16)+(6<<8)+0)
+ // translate old parameters to new av_dict names
+ if ( !strcmp( name, "frame_rate" ) )
+ av_dict_set( params, "framerate", value, 0 );
+ else if ( !strcmp( name, "pix_fmt" ) )
+ av_dict_set( params, "pixel_format", value, 0 );
+ else if ( !strcmp( name, "width" ) )
+ width = strdup( value );
+ else if ( !strcmp( name, "height" ) )
+ height = strdup( value );
+ else
+ // generic demux/device option support
+ av_dict_set( params, name, value, 0 );
+#else
if ( !strcmp( name, "frame_rate" ) )
params->time_base.den = atoi( value );
else if ( !strcmp( name, "frame_rate_base" ) )
params->height = atoi( value );
else if ( !strcmp( name, "standard" ) )
params->standard = strdup( value );
+#endif
}
free( name );
url = strchr( url, '&' );
}
+#if LIBAVFORMAT_VERSION_INT > ((53<<16)+(6<<8)+0)
+ // continued support for legacy width and height parameters
+ if ( width && height )
+ {
+ char *s = malloc( strlen( width ) + strlen( height ) + 2 );
+ strcpy( s, width );
+ strcat( s, "x");
+ strcat( s, height );
+ av_dict_set( params, "video_size", s, 0 );
+ free( s );
+ }
+ if ( width ) free( width );
+ if ( height ) free ( height );
+#endif
}
+ result = strdup( result );
+ }
+ else
+ {
+ result = strdup( URL );
}
- result = strdup( result );
free( protocol );
return result;
}
self->seekable = av_seek_frame( format, -1, format->start_time, AVSEEK_FLAG_BACKWARD ) >= 0;
mlt_properties_set_int( properties, "seekable", self->seekable );
self->dummy_context = format;
+#if LIBAVFORMAT_VERSION_INT > ((53<<16)+(6<<8)+0)
+ self->video_format = NULL;
+ avformat_open_input( &self->video_format, filename, NULL, NULL );
+ avformat_find_stream_info( self->video_format, NULL );
+#else
av_open_input_file( &self->video_format, filename, NULL, 0, NULL );
+ av_find_stream_info( self->video_format );
+#endif
format = self->video_format;
- av_find_stream_info( format );
}
// Fetch the width, height and aspect ratio
if ( ret >= 0 && pkt.stream_index == self->video_index && pkt.size > 0 )
{
get_aspect_ratio( properties, format->streams[ self->video_index ], codec_context, &pkt );
+ av_free_packet(&pkt);
break;
}
+ if ( ret >= 0 )
+ av_free_packet(&pkt);
}
}
else
// Lock the service
if ( take_lock )
{
- pthread_mutex_init( &self->audio_mutex, NULL );
- pthread_mutex_init( &self->video_mutex, NULL );
- pthread_mutex_init( &self->packets_mutex, NULL );
+ if ( !self->is_mutex_init )
+ {
+ pthread_mutex_init( &self->audio_mutex, NULL );
+ pthread_mutex_init( &self->video_mutex, NULL );
+ pthread_mutex_init( &self->packets_mutex, NULL );
+ pthread_mutex_init( &self->open_mutex, NULL );
+ self->is_mutex_init = 1;
+ }
pthread_mutex_lock( &self->audio_mutex );
pthread_mutex_lock( &self->video_mutex );
}
// Parse URL
AVInputFormat *format = NULL;
+#if LIBAVFORMAT_VERSION_INT > ((53<<16)+(6<<8)+0)
+ AVDictionary *params = NULL;
+#else
AVFormatParameters params;
memset( ¶ms, 0, sizeof(params) );
+#endif
char *filename = parse_url( profile, URL, &format, ¶ms );
// Now attempt to open the file or device with filename
+#if LIBAVFORMAT_VERSION_INT > ((53<<16)+(6<<8)+0)
+ error = avformat_open_input( &self->video_format, filename, format, ¶ms ) < 0;
+ if ( error )
+ // If the URL is a network stream URL, then we probably need to open with full URL
+ error = avformat_open_input( &self->video_format, URL, format, ¶ms ) < 0;
+#else
error = av_open_input_file( &self->video_format, filename, format, 0, ¶ms ) < 0;
if ( error )
// If the URL is a network stream URL, then we probably need to open with full URL
error = av_open_input_file( &self->video_format, URL, format, 0, ¶ms ) < 0;
+#endif
// Set MLT properties onto video AVFormatContext
if ( !error && self->video_format )
{
apply_properties( self->video_format, properties, AV_OPT_FLAG_DECODING_PARAM );
-#if LIBAVFORMAT_VERSION_MAJOR >= 53
+#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(110<<8)+0)
if ( self->video_format->iformat && self->video_format->iformat->priv_class && self->video_format->priv_data )
apply_properties( self->video_format->priv_data, properties, AV_OPT_FLAG_DECODING_PARAM );
#endif
}
+#if LIBAVFORMAT_VERSION_INT > ((53<<16)+(6<<8)+0)
+ av_dict_free( ¶ms );
+#else
// Cleanup AVFormatParameters
if ( params.standard )
free( (void*) params.standard );
+#endif
// If successful, then try to get additional info
if ( !error && self->video_format )
{
// Get the stream info
+#if LIBAVFORMAT_VERSION_INT > ((53<<16)+(6<<8)+0)
+ error = avformat_find_stream_info( self->video_format, NULL ) < 0;
+#else
error = av_find_stream_info( self->video_format ) < 0;
+#endif
// Continue if no error
if ( !error && self->video_format )
error = get_basic_info( self, profile, filename );
// Initialize position info
- self->first_pts = -1;
+ self->first_pts = AV_NOPTS_VALUE;
self->last_position = POSITION_INITIAL;
if ( !self->audio_format )
if ( self->seekable )
{
// And open again for our audio context
- av_open_input_file( &self->audio_format, filename, NULL, 0, NULL );
+#if LIBAVFORMAT_VERSION_INT > ((53<<16)+(6<<8)+0)
+ avformat_open_input( &self->audio_format, filename, NULL, NULL );
apply_properties( self->audio_format, properties, AV_OPT_FLAG_DECODING_PARAM );
-#if LIBAVFORMAT_VERSION_MAJOR >= 53
if ( self->audio_format->iformat && self->audio_format->iformat->priv_class && self->audio_format->priv_data )
apply_properties( self->audio_format->priv_data, properties, AV_OPT_FLAG_DECODING_PARAM );
+ avformat_find_stream_info( self->audio_format, NULL );
+#else
+ av_open_input_file( &self->audio_format, filename, NULL, 0, NULL );
+ apply_properties( self->audio_format, properties, AV_OPT_FLAG_DECODING_PARAM );
+#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(110<<8)+0)
+ if ( self->audio_format->iformat && self->audio_format->iformat->priv_class && self->audio_format->priv_data )
+ apply_properties( self->audio_format->priv_data, properties, AV_OPT_FLAG_DECODING_PARAM );
#endif
av_find_stream_info( self->audio_format );
+#endif
}
else
{
if ( self->dummy_context )
{
- avformat_lock();
+ pthread_mutex_lock( &self->open_mutex );
+#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(17<<8)+0)
+ avformat_close_input( &self->dummy_context );
+#else
av_close_input_file( self->dummy_context );
- avformat_unlock();
+#endif
self->dummy_context = NULL;
+ pthread_mutex_unlock( &self->open_mutex );
}
// Unlock the service
mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) );
pthread_mutex_lock( &self->audio_mutex );
+ pthread_mutex_lock( &self->open_mutex );
- avformat_lock();
if ( self->video_codec )
avcodec_close( self->video_codec );
self->video_codec = NULL;
+#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(17<<8)+0)
+ if ( self->dummy_context )
+ avformat_close_input( &self->dummy_context );
+ if ( self->video_format )
+ avformat_close_input( &self->video_format );
+#else
if ( self->dummy_context )
av_close_input_file( self->dummy_context );
- self->dummy_context = NULL;
if ( self->video_format )
av_close_input_file( self->video_format );
+#endif
+ self->dummy_context = NULL;
self->video_format = NULL;
- avformat_unlock();
+ pthread_mutex_unlock( &self->open_mutex );
int audio_index = self->audio_index;
int video_index = self->video_index;
mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
}
+static int64_t best_pts( producer_avformat self, int64_t pts, int64_t dts )
+{
+ self->invalid_pts_counter += pts == AV_NOPTS_VALUE;
+ self->invalid_dts_counter += dts == AV_NOPTS_VALUE;
+ if ( ( self->invalid_pts_counter <= self->invalid_dts_counter
+ || dts == AV_NOPTS_VALUE ) && pts != AV_NOPTS_VALUE )
+ return pts;
+ else
+ return dts;
+}
+
+static void find_first_pts( producer_avformat self, int video_index )
+{
+ // find initial PTS
+ AVFormatContext *context = self->video_format? self->video_format : self->audio_format;
+ int ret = 0;
+ int toscan = 500;
+ AVPacket pkt;
+
+ while ( ret >= 0 && toscan-- > 0 )
+ {
+ ret = av_read_frame( context, &pkt );
+ if ( ret >= 0 && pkt.stream_index == video_index && ( pkt.flags & PKT_FLAG_KEY ) )
+ {
+ mlt_log_debug( MLT_PRODUCER_SERVICE(self->parent),
+ "first_pts %"PRId64" dts %"PRId64" pts_dts_delta %d\n",
+ pkt.pts, pkt.dts, (int)(pkt.pts - pkt.dts) );
+ self->first_pts = best_pts( self, pkt.pts, pkt.dts );
+ if ( self->first_pts != AV_NOPTS_VALUE )
+ toscan = 0;
+ }
+ av_free_packet( &pkt );
+ }
+ av_seek_frame( context, -1, 0, AVSEEK_FLAG_BACKWARD );
+}
+
static int seek_video( producer_avformat self, mlt_position position,
- int64_t req_position, int must_decode, int use_new_seek, int *ignore )
+ int64_t req_position, int preseek )
{
mlt_producer producer = self->parent;
int paused = 0;
double source_fps = mlt_properties_get_double( properties, "meta.media.frame_rate_num" ) /
mlt_properties_get_double( properties, "meta.media.frame_rate_den" );
+ if ( self->last_position == POSITION_INITIAL )
+ find_first_pts( self, self->video_index );
+
if ( self->av_frame && position + 1 == self->video_expected )
{
// We're paused - use last image
paused = 1;
}
- else if ( !self->seekable && position > self->video_expected && ( position - self->video_expected ) < 250 )
- {
- // Fast forward - seeking is inefficient for small distances - just ignore following frames
- *ignore = ( int )( ( position - self->video_expected ) / mlt_producer_get_fps( producer ) * source_fps );
- codec_context->skip_loop_filter = AVDISCARD_NONREF;
- }
else if ( self->seekable && ( position < self->video_expected || position - self->video_expected >= 12 || self->last_position < 0 ) )
{
- if ( use_new_seek && self->last_position == POSITION_INITIAL )
- {
- // find first key frame
- int ret = 0;
- int toscan = 100;
- AVPacket pkt;
-
- while ( ret >= 0 && toscan-- > 0 )
- {
- ret = av_read_frame( context, &pkt );
- if ( ret >= 0 && ( pkt.flags & PKT_FLAG_KEY ) && pkt.stream_index == self->video_index )
- {
- mlt_log_debug( MLT_PRODUCER_SERVICE(producer), "first_pts %"PRId64" dts %"PRId64" pts_dts_delta %d\n", pkt.pts, pkt.dts, (int)(pkt.pts - pkt.dts) );
- self->first_pts = pkt.pts;
- toscan = 0;
- }
- av_free_packet( &pkt );
- }
- // Rewind
- av_seek_frame( context, -1, 0, AVSEEK_FLAG_BACKWARD );
- }
-
// Calculate the timestamp for the requested frame
- int64_t timestamp;
- if ( use_new_seek )
- {
- timestamp = ( req_position - 0.1 / source_fps ) /
- ( av_q2d( stream->time_base ) * source_fps );
- mlt_log_debug( MLT_PRODUCER_SERVICE(producer), "pos %"PRId64" pts %"PRId64"\n", req_position, timestamp );
- if ( self->first_pts > 0 )
- timestamp += self->first_pts;
- else if ( context->start_time != AV_NOPTS_VALUE )
- timestamp += context->start_time;
- }
- else
- {
- timestamp = ( int64_t )( ( double )req_position / source_fps * AV_TIME_BASE + 0.5 );
- if ( context->start_time != AV_NOPTS_VALUE )
- timestamp += context->start_time;
- }
- if ( must_decode )
- timestamp -= AV_TIME_BASE;
+ int64_t timestamp = req_position / ( av_q2d( self->video_time_base ) * source_fps );
+ if ( req_position <= 0 )
+ timestamp = 0;
+ else if ( self->first_pts != AV_NOPTS_VALUE )
+ timestamp += self->first_pts;
+ else if ( context->start_time != AV_NOPTS_VALUE )
+ timestamp += context->start_time;
+ if ( preseek && av_q2d( self->video_time_base ) != 0 )
+ timestamp -= 2 / av_q2d( self->video_time_base );
if ( timestamp < 0 )
timestamp = 0;
mlt_log_debug( MLT_PRODUCER_SERVICE(producer), "seeking timestamp %"PRId64" position %d expected %d last_pos %"PRId64"\n",
timestamp, position, self->video_expected, self->last_position );
// Seek to the timestamp
- if ( use_new_seek )
+ // NOTE: reopen_video is disabled at this time because it is causing trouble with A/V sync.
+ if ( 1 || req_position > 0 || self->last_position <= 0 )
{
codec_context->skip_loop_filter = AVDISCARD_NONREF;
av_seek_frame( context, self->video_index, timestamp, AVSEEK_FLAG_BACKWARD );
- }
- else if ( req_position > 0 || self->last_position <= 0 )
- {
- av_seek_frame( context, -1, timestamp, AVSEEK_FLAG_BACKWARD );
+
+ // flush any pictures still in decode buffer
+ avcodec_flush_buffers( codec_context );
}
else
{
self->current_position = POSITION_INVALID;
self->last_position = POSITION_INVALID;
av_freep( &self->av_frame );
-
- if ( use_new_seek )
- {
- // flush any pictures still in decode buffer
- avcodec_flush_buffers( codec_context );
- }
}
}
return paused;
AVCodec *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( );
+ pthread_mutex_lock( &self->open_mutex );
+#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
+ if ( codec && avcodec_open2( codec_context, codec, NULL ) >= 0 )
+#else
if ( codec && avcodec_open( codec_context, codec ) >= 0 )
+#endif
{
self->audio_streams++;
self->audio_max_stream = i;
self->max_frequency = codec_context->sample_rate;
avcodec_close( codec_context );
}
- avformat_unlock( );
+ pthread_mutex_unlock( &self->open_mutex );
}
}
mlt_log_verbose( NULL, "[producer avformat] audio: total_streams %d max_stream %d total_channels %d max_channels %d\n",
#endif
}
-static mlt_image_format pick_format( enum PixelFormat pix_fmt )
+static mlt_image_format pick_pix_format( enum PixelFormat pix_fmt )
{
switch ( pix_fmt )
{
}
}
-static void convert_image( AVFrame *frame, uint8_t *buffer, int pix_fmt,
- mlt_image_format *format, int width, int height, int colorspace )
+static mlt_audio_format pick_audio_format( int sample_fmt )
+{
+ switch ( sample_fmt )
+ {
+ // interleaved
+ case AV_SAMPLE_FMT_U8:
+ return mlt_audio_u8;
+ case AV_SAMPLE_FMT_S16:
+ return mlt_audio_s16;
+ case AV_SAMPLE_FMT_S32:
+ return mlt_audio_s32le;
+ case AV_SAMPLE_FMT_FLT:
+ return mlt_audio_f32le;
+ // planar - this producer converts planar to interleaved
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ case AV_SAMPLE_FMT_U8P:
+ return mlt_audio_u8;
+ case AV_SAMPLE_FMT_S16P:
+ return mlt_audio_s16;
+ case AV_SAMPLE_FMT_S32P:
+ return mlt_audio_s32le;
+ case AV_SAMPLE_FMT_FLTP:
+ return mlt_audio_f32le;
+#endif
+ default:
+ return mlt_audio_none;
+ }
+}
+
+static void convert_image( producer_avformat self, AVFrame *frame, uint8_t *buffer, int pix_fmt,
+ mlt_image_format *format, int width, int height, uint8_t **alpha )
{
#ifdef SWSCALE
- int full_range = -1;
- int flags = SWS_BILINEAR | SWS_ACCURATE_RND;
+ int flags = SWS_BICUBIC | SWS_ACCURATE_RND;
#ifdef USE_MMX
flags |= SWS_CPU_CAPS_MMX;
flags |= SWS_CPU_CAPS_MMX2;
#endif
+ // extract alpha from planar formats
+ if ( ( pix_fmt == PIX_FMT_YUVA420P
+#if defined(FFUDIV) && LIBAVUTIL_VERSION_INT >= ((51<<16)+(35<<8)+101)
+ || pix_fmt == PIX_FMT_YUVA444P
+#endif
+ ) &&
+ *format != mlt_image_rgb24a && *format != mlt_image_opengl &&
+ frame->data[3] && frame->linesize[3] )
+ {
+ int i;
+ uint8_t *src, *dst;
+
+ dst = *alpha = mlt_pool_alloc( width * height );
+ src = frame->data[3];
+
+ for ( i = 0; i < height; dst += width, src += frame->linesize[3], i++ )
+ memcpy( dst, src, FFMIN( width, frame->linesize[3] ) );
+ }
+
if ( *format == mlt_image_yuv420p )
{
struct SwsContext *context = sws_getContext( width, height, pix_fmt,
output.linesize[0] = width;
output.linesize[1] = width >> 1;
output.linesize[2] = width >> 1;
- set_luma_transfer( context, colorspace, full_range );
+ set_luma_transfer( context, self->colorspace, -1 );
sws_scale( context, (const uint8_t* const*) frame->data, frame->linesize, 0, height,
output.data, output.linesize);
sws_freeContext( context );
width, height, PIX_FMT_RGB24, flags | SWS_FULL_CHR_H_INT, NULL, NULL, NULL);
AVPicture output;
avpicture_fill( &output, buffer, PIX_FMT_RGB24, width, height );
- set_luma_transfer( context, colorspace, full_range );
+ set_luma_transfer( context, self->colorspace, self->full_luma );
sws_scale( context, (const uint8_t* const*) frame->data, frame->linesize, 0, height,
output.data, output.linesize);
sws_freeContext( context );
width, height, PIX_FMT_RGBA, flags | SWS_FULL_CHR_H_INT, NULL, NULL, NULL);
AVPicture output;
avpicture_fill( &output, buffer, PIX_FMT_RGBA, width, height );
- set_luma_transfer( context, colorspace, full_range );
+ set_luma_transfer( context, self->colorspace, self->full_luma );
sws_scale( context, (const uint8_t* const*) frame->data, frame->linesize, 0, height,
output.data, output.linesize);
sws_freeContext( context );
width, height, PIX_FMT_YUYV422, flags | SWS_FULL_CHR_H_INP, NULL, NULL, NULL);
AVPicture output;
avpicture_fill( &output, buffer, PIX_FMT_YUYV422, width, height );
- set_luma_transfer( context, colorspace, full_range );
+ set_luma_transfer( context, self->colorspace, -1 );
sws_scale( context, (const uint8_t* const*) frame->data, frame->linesize, 0, height,
output.data, output.linesize);
sws_freeContext( context );
avpicture_fill( &output, buffer, PIX_FMT_RGB24, width, height );
img_convert( &output, PIX_FMT_RGB24, (AVPicture *)frame, pix_fmt, width, height );
}
- else if ( format == mlt_image_rgb24a || format == mlt_image_opengl )
+ else if ( *format == mlt_image_rgb24a || *format == mlt_image_opengl )
{
AVPicture output;
avpicture_fill( &output, buffer, PIX_FMT_RGB32, width, height );
if ( codec_context->width == 0 || codec_context->height == 0 )
return size;
+
+ if ( *format == mlt_image_glsl )
+ *format = pick_pix_format( codec_context->pix_fmt );
+
*width = codec_context->width;
*height = codec_context->height;
size = mlt_image_format_size( *format, *width, *height, NULL );
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" );
+ mlt_position position = mlt_frame_original_position( frame );
// Get the producer properties
mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
// Get codec context
AVCodecContext *codec_context = stream->codec;
+ uint8_t *alpha = NULL;
+ int got_picture = 0;
+ int image_size = 0;
+
// Get the image cache
- if ( ! self->image_cache && ! mlt_properties_get_int( properties, "noimagecache" ) )
- self->image_cache = mlt_cache_init();
+ if ( ! self->image_cache )
+ {
+ // if cache size supplied by environment variable
+ int cache_supplied = getenv( "MLT_AVFORMAT_CACHE" ) != NULL;
+ int cache_size = cache_supplied? atoi( getenv( "MLT_AVFORMAT_CACHE" ) ) : 0;
+
+ // cache size supplied via property
+ if ( mlt_properties_get( properties, "cache" ) )
+ {
+ cache_supplied = 1;
+ cache_size = mlt_properties_get_int( properties, "cache" );
+ }
+ if ( mlt_properties_get_int( properties, "noimagecache" ) )
+ cache_size = 0;
+ // create cache if not disabled
+ if ( !cache_supplied || cache_size > 0 )
+ self->image_cache = mlt_cache_init();
+ // set cache size if supplied
+ if ( self->image_cache && cache_supplied )
+ mlt_cache_set_size( self->image_cache, cache_size );
+ }
if ( self->image_cache )
{
- mlt_cache_item item = mlt_cache_get( self->image_cache, (void*) position );
- uint8_t *original = mlt_cache_item_data( item, (int*) format );
+ mlt_frame original = mlt_cache_get_frame( self->image_cache, position );
if ( original )
{
+ mlt_properties orig_props = MLT_FRAME_PROPERTIES( original );
+ int size = 0;
+
+ *buffer = mlt_properties_get_data( orig_props, "alpha", &size );
+ if (*buffer)
+ mlt_frame_set_alpha( frame, *buffer, size, NULL );
+ *buffer = mlt_properties_get_data( orig_props, "image", &size );
+ mlt_frame_set_image( frame, *buffer, size, NULL );
+ mlt_properties_set_data( frame_properties, "avformat.image_cache", original, 0, (mlt_destructor) mlt_frame_close, NULL );
+ *format = mlt_properties_get_int( orig_props, "format" );
+
// Set the resolution
*width = codec_context->width;
*height = codec_context->height;
if ( *height == 1088 && mlt_profile_dar( mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ) ) == 16.0/9.0 )
*height = 1080;
- // Cache hit
- int size = mlt_image_format_size( *format, *width, *height, NULL );
- if ( writable )
- {
- *buffer = mlt_pool_alloc( size );
- mlt_frame_set_image( frame, *buffer, size, mlt_pool_release );
- memcpy( *buffer, original, size );
- mlt_cache_item_close( item );
- }
- else
- {
- *buffer = original;
- mlt_properties_set_data( frame_properties, "avformat.image_cache", item, 0, ( mlt_destructor )mlt_cache_item_close, NULL );
- mlt_frame_set_image( frame, *buffer, size, NULL );
- }
- self->got_picture = 1;
-
+ got_picture = 1;
goto exit_get_image;
}
}
// Cache miss
- int image_size = 0;
-
- // Packet
- AVPacket pkt;
-
- // 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, "meta.media.frame_rate_num" ) /
strcmp( codec_context->codec->name, "mjpeg" ) &&
strcmp( codec_context->codec->name, "rawvideo" ) );
- // Turn on usage of new seek API and PTS for seeking
- int use_new_seek = self->seekable &&
- codec_context->codec_id == CODEC_ID_H264 && !strcmp( context->iformat->name, "mpegts" );
- if ( mlt_properties_get( properties, "new_seek" ) )
- use_new_seek = mlt_properties_get_int( properties, "new_seek" );
double delay = mlt_properties_get_double( properties, "video_delay" );
// Seek if necessary
- int paused = seek_video( self, position, req_position, must_decode, use_new_seek, &ignore );
+ const char *interp = mlt_properties_get( frame_properties, "rescale.interp" );
+ int preseek = must_decode
+#if defined(FFUDIV) && LIBAVFORMAT_VERSION_INT >= ((53<<16)+(24<<8)+2)
+ && ( interp && strcmp( interp, "nearest" ) )
+#endif
+ && codec_context->has_b_frames;
+ int paused = seek_video( self, position, req_position, preseek );
// Seek might have reopened the file
context = self->video_format;
stream = context->streams[ self->video_index ];
codec_context = stream->codec;
-
if ( *format == mlt_image_none ||
codec_context->pix_fmt == PIX_FMT_ARGB ||
codec_context->pix_fmt == PIX_FMT_RGBA ||
codec_context->pix_fmt == PIX_FMT_ABGR ||
codec_context->pix_fmt == PIX_FMT_BGRA )
- *format = pick_format( codec_context->pix_fmt );
+ *format = pick_pix_format( codec_context->pix_fmt );
// Duplicate the last image if necessary
- if ( self->av_frame && self->av_frame->linesize[0] && self->got_picture
- && ( paused
- || self->current_position == req_position
- || ( !use_new_seek && self->current_position > req_position ) ) )
+ if ( self->av_frame && self->av_frame->linesize[0]
+ && ( paused || self->current_position >= req_position ) )
{
// Duplicate it
if ( ( image_size = allocate_buffer( frame, codec_context, buffer, format, width, height ) ) )
picture.linesize[0] = codec_context->width;
picture.linesize[1] = codec_context->width / 2;
picture.linesize[2] = codec_context->width / 2;
- convert_image( (AVFrame*) &picture, *buffer,
- PIX_FMT_YUV420P, format, *width, *height, self->colorspace );
+ convert_image( self, (AVFrame*) &picture, *buffer,
+ PIX_FMT_YUV420P, format, *width, *height, &alpha );
}
else
#endif
- convert_image( self->av_frame, *buffer, codec_context->pix_fmt,
- format, *width, *height, self->colorspace );
+ convert_image( self, self->av_frame, *buffer, codec_context->pix_fmt,
+ format, *width, *height, &alpha );
+ got_picture = 1;
}
- else
- mlt_frame_get_image( frame, buffer, format, width, height, writable );
}
else
{
int ret = 0;
int64_t int_position = 0;
int decode_errors = 0;
- int got_picture = 0;
-
- av_init_packet( &pkt );
// Construct an AVFrame for YUV422 conversion
if ( !self->av_frame )
while( ret >= 0 && !got_picture )
{
// Read a packet
+ if ( self->pkt.stream_index == self->video_index )
+ av_free_packet( &self->pkt );
+ av_init_packet( &self->pkt );
pthread_mutex_lock( &self->packets_mutex );
if ( mlt_deque_count( self->vpackets ) )
{
AVPacket *tmp = (AVPacket*) mlt_deque_pop_front( self->vpackets );
- pkt = *tmp;
+ self->pkt = *tmp;
free( tmp );
}
else
{
- ret = av_read_frame( context, &pkt );
- if ( ret >= 0 && !self->seekable && pkt.stream_index == self->audio_index )
+ ret = av_read_frame( context, &self->pkt );
+ if ( ret >= 0 && !self->seekable && self->pkt.stream_index == self->audio_index )
{
- if ( !av_dup_packet( &pkt ) )
+ if ( !av_dup_packet( &self->pkt ) )
{
AVPacket *tmp = malloc( sizeof(AVPacket) );
- *tmp = pkt;
+ *tmp = self->pkt;
mlt_deque_push_back( self->apackets, tmp );
}
}
pthread_mutex_unlock( &self->packets_mutex );
// We only deal with video from the selected video_index
- if ( ret >= 0 && pkt.stream_index == self->video_index && pkt.size > 0 )
+ if ( ret >= 0 && self->pkt.stream_index == self->video_index && self->pkt.size > 0 )
{
- // Determine time code of the packet
- if ( use_new_seek )
+ int64_t pts = best_pts( self, self->pkt.pts, self->pkt.dts );
+ if ( pts != AV_NOPTS_VALUE )
{
- int64_t pts = pkt.pts;
- if ( self->first_pts > 0 )
+ if ( !self->seekable && self->first_pts == AV_NOPTS_VALUE )
+ self->first_pts = pts;
+ if ( self->first_pts != AV_NOPTS_VALUE )
pts -= self->first_pts;
else if ( context->start_time != AV_NOPTS_VALUE )
pts -= context->start_time;
- int_position = ( int64_t )( ( av_q2d( stream->time_base ) * pts + delay ) * source_fps + 0.1 );
- if ( pkt.pts == AV_NOPTS_VALUE )
- {
- self->invalid_pts_counter++;
- if ( self->invalid_pts_counter > 20 )
- {
- mlt_log_panic( MLT_PRODUCER_SERVICE(producer), "\ainvalid PTS; DISABLING NEW_SEEK!\n" );
- mlt_properties_set_int( properties, "new_seek", 0 );
- int_position = req_position;
- use_new_seek = 0;
- }
- }
- else
- {
- self->invalid_pts_counter = 0;
- }
- mlt_log_debug( MLT_PRODUCER_SERVICE(producer), "pkt.pts %"PRId64" req_pos %"PRId64" cur_pos %"PRId64" pkt_pos %"PRId64"\n",
- pkt.pts, req_position, self->current_position, int_position );
+ int_position = ( int64_t )( ( av_q2d( self->video_time_base ) * pts + delay ) * source_fps + 0.5 );
+ if ( int_position == self->last_position )
+ int_position = self->last_position + 1;
}
- else
+ mlt_log_debug( MLT_PRODUCER_SERVICE(producer),
+ "V pkt.pts %"PRId64" pkt.dts %"PRId64" req_pos %"PRId64" cur_pos %"PRId64" pkt_pos %"PRId64"\n",
+ self->pkt.pts, self->pkt.dts, req_position, self->current_position, int_position );
+
+ // Make a dumb assumption on streams that contain wild timestamps
+ if ( abs( req_position - int_position ) > 999 )
{
- if ( pkt.dts != AV_NOPTS_VALUE )
- {
- int_position = ( int64_t )( ( av_q2d( stream->time_base ) * pkt.dts + delay ) * source_fps + 0.5 );
- if ( context->start_time != AV_NOPTS_VALUE )
- int_position -= ( int64_t )( context->start_time * source_fps / AV_TIME_BASE + 0.5 );
- if ( int_position == self->last_position )
- int_position = self->last_position + 1;
- }
- mlt_log_debug( MLT_PRODUCER_SERVICE(producer), "pkt.dts %"PRId64" req_pos %"PRId64" cur_pos %"PRId64" pkt_pos %"PRId64"\n",
- pkt.dts, req_position, self->current_position, int_position );
- // Make a dumb assumption on streams that contain wild timestamps
- if ( abs( req_position - int_position ) > 999 )
- {
- int_position = req_position;
- mlt_log_debug( MLT_PRODUCER_SERVICE(producer), " WILD TIMESTAMP!" );
- }
+ int_position = req_position;
+ mlt_log_warning( MLT_PRODUCER_SERVICE(producer), " WILD TIMESTAMP!\n" );
}
self->last_position = int_position;
self->vdpau->is_decoded = 0;
}
#endif
- codec_context->reordered_opaque = pkt.pts;
+ codec_context->reordered_opaque = int_position;
if ( int_position >= req_position )
codec_context->skip_loop_filter = AVDISCARD_NONE;
#if (LIBAVCODEC_VERSION_INT >= ((52<<16)+(26<<8)+0))
- ret = avcodec_decode_video2( codec_context, self->av_frame, &got_picture, &pkt );
+ ret = avcodec_decode_video2( codec_context, self->av_frame, &got_picture, &self->pkt );
#else
- ret = avcodec_decode_video( codec_context, self->av_frame, &got_picture, pkt.data, pkt.size );
+ ret = avcodec_decode_video( codec_context, self->av_frame, &got_picture, self->pkt.data, self->pkt.size );
#endif
// Note: decode may fail at the beginning of MPEGfile (B-frames referencing before first I-frame), so allow a few errors.
if ( ret < 0 )
if ( got_picture )
{
- if ( use_new_seek )
+ // Get position of reordered frame
+ int_position = self->av_frame->reordered_opaque;
+#if (LIBAVCODEC_VERSION_INT >= ((52<<16)+(106<<8)+0))
+ pts = best_pts( self, self->av_frame->pkt_pts, self->av_frame->pkt_dts );
+ if ( pts != AV_NOPTS_VALUE )
{
- // Determine time code of the packet
- int64_t pts = self->av_frame->reordered_opaque;
- if ( self->first_pts > 0 )
+ if ( self->first_pts != AV_NOPTS_VALUE )
pts -= self->first_pts;
else if ( context->start_time != AV_NOPTS_VALUE )
pts -= context->start_time;
- int_position = ( int64_t )( av_q2d( stream->time_base) * pts * source_fps + 0.1 );
- mlt_log_debug( MLT_PRODUCER_SERVICE(producer), "got frame %"PRId64", key %d\n", int_position, self->av_frame->key_frame );
+ int_position = ( int64_t )( ( av_q2d( self->video_time_base ) * pts + delay ) * source_fps + 0.5 );
}
- // Handle ignore
+#endif
+
if ( int_position < req_position )
- {
- ignore = 0;
got_picture = 0;
- }
else if ( int_position >= req_position )
- {
- ignore = 0;
codec_context->skip_loop_filter = AVDISCARD_NONE;
- }
- else if ( ignore -- )
- {
- got_picture = 0;
- }
}
- mlt_log_debug( MLT_PRODUCER_SERVICE(producer), " got_pic %d key %d\n", got_picture, pkt.flags & PKT_FLAG_KEY );
+ mlt_log_debug( MLT_PRODUCER_SERVICE(producer), " got_pic %d key %d\n", got_picture, self->pkt.flags & PKT_FLAG_KEY );
}
// Now handle the picture if we have one
VdpStatus status = vdp_surface_get_bits( render->surface, dest_format, planes, pitches );
if ( status == VDP_STATUS_OK )
{
- convert_image( self->av_frame, *buffer, PIX_FMT_YUV420P,
- format, *width, *height, self->colorspace );
+ convert_image( self, self->av_frame, *buffer, PIX_FMT_YUV420P,
+ format, *width, *height, &alpha );
}
else
{
}
else
#endif
- convert_image( self->av_frame, *buffer, codec_context->pix_fmt,
- format, *width, *height, self->colorspace );
+ convert_image( self, self->av_frame, *buffer, codec_context->pix_fmt,
+ format, *width, *height, &alpha );
self->top_field_first |= self->av_frame->top_field_first;
self->current_position = int_position;
- self->got_picture = 1;
}
else
{
got_picture = 0;
}
}
- if ( self->seekable || pkt.stream_index != self->audio_index )
- av_free_packet( &pkt );
+
+ // Free packet data if not video and not live audio packet
+ if ( self->pkt.stream_index != self->video_index &&
+ !( !self->seekable && self->pkt.stream_index == self->audio_index ) )
+ av_free_packet( &self->pkt );
}
}
- if ( self->got_picture && image_size > 0 && self->image_cache )
+ // set alpha
+ if ( alpha )
+ mlt_frame_set_alpha( frame, alpha, (*width) * (*height), mlt_pool_release );
+
+ if ( image_size > 0 && self->image_cache )
{
- // Copy buffer to image cache
- uint8_t *image = mlt_pool_alloc( image_size );
- memcpy( image, *buffer, image_size );
- mlt_cache_put( self->image_cache, (void*) position, image, *format, mlt_pool_release );
+ mlt_properties_set_int( frame_properties, "format", *format );
+ mlt_cache_put_frame( self->image_cache, frame );
}
+
// Try to duplicate last image if there was a decoding failure
- else if ( !image_size && self->av_frame && self->av_frame->linesize[0] )
+ // TODO: with multithread decoding a partial frame decoding resulting
+ // in failure also resets av_frame making test below fail.
+ if ( !image_size && self->av_frame && self->av_frame->linesize[0] )
{
// Duplicate it
if ( ( image_size = allocate_buffer( frame, codec_context, buffer, format, width, height ) ) )
picture.linesize[0] = codec_context->width;
picture.linesize[1] = codec_context->width / 2;
picture.linesize[2] = codec_context->width / 2;
- convert_image( (AVFrame*) &picture, *buffer,
- PIX_FMT_YUV420P, format, *width, *height, self->colorspace );
+ convert_image( self, (AVFrame*) &picture, *buffer,
+ PIX_FMT_YUV420P, format, *width, *height, &alpha );
}
else
#endif
- convert_image( self->av_frame, *buffer, codec_context->pix_fmt,
- format, *width, *height, self->colorspace );
- self->got_picture = 1;
+ convert_image( self, self->av_frame, *buffer, codec_context->pix_fmt,
+ format, *width, *height, &alpha );
+ got_picture = 1;
}
- else
- mlt_frame_get_image( frame, buffer, format, width, height, writable );
}
// Regardless of speed, we expect to get the next frame (cos we ain't too bright)
mlt_properties_set_int( properties, "meta.media.progressive", mlt_properties_get_int( frame_properties, "progressive" ) );
mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
- return !self->got_picture;
+ // If we already have RGB, then the full range processing either happened already
+ // or does not apply (RGB source).
+ if ( *format == mlt_image_rgb24 || *format == mlt_image_rgb24a || *format == mlt_image_opengl )
+ mlt_properties_set( frame_properties, "force_full_luma", NULL );
+
+ return !got_picture;
}
/** Process properties as AVOptions and apply to AV context obj
for ( i = 0; i < count; i++ )
{
const char *opt_name = mlt_properties_get_name( properties, i );
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(10<<8)+0)
+ const AVOption *opt = av_opt_find( obj, opt_name, NULL, flags, flags );
+#else
const AVOption *opt = av_find_opt( obj, opt_name, NULL, flags, flags );
+#endif
if ( opt_name && mlt_properties_get( properties, opt_name ) )
{
if ( opt )
-#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(7<<8)+0)
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(12<<8)+0)
+ av_opt_set( obj, opt_name, mlt_properties_get( properties, opt_name), 0 );
+#elif 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 );
codec_context->thread_count = thread_count;
// If we don't have a codec and we can't initialise it, we can't do much more...
- avformat_lock( );
+ pthread_mutex_lock( &self->open_mutex );
+#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
+ if ( codec && avcodec_open2( codec_context, codec, NULL ) >= 0 )
+#else
if ( codec && avcodec_open( codec_context, codec ) >= 0 )
+#endif
{
// Now store the codec with its destructor
self->video_codec = codec_context;
{
// Remember that we can't use this later
self->video_index = -1;
- avformat_unlock( );
+ pthread_mutex_unlock( &self->open_mutex );
return 0;
}
- avformat_unlock( );
+ pthread_mutex_unlock( &self->open_mutex );
// Process properties as AVOptions
apply_properties( codec_context, properties, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM );
-#if LIBAVCODEC_VERSION_MAJOR >= 53
+#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(122<<8)+0)
if ( codec->priv_class && codec_context->priv_data )
apply_properties( codec_context->priv_data, properties, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM );
#endif
// Reset some image properties
- mlt_properties_set_int( properties, "width", self->video_codec->width );
- mlt_properties_set_int( properties, "height", self->video_codec->height );
+ if ( self->video_codec )
+ {
+ mlt_properties_set_int( properties, "width", self->video_codec->width );
+ mlt_properties_set_int( properties, "height", self->video_codec->height );
+ }
// For DV, we'll just use the saved aspect ratio
if ( codec_context->codec_id != CODEC_ID_DVVIDEO )
get_aspect_ratio( properties, stream, self->video_codec, NULL );
double source_fps = (double) self->video_codec->time_base.den /
( self->video_codec->time_base.num == 0 ? 1 : self->video_codec->time_base.num );
- if ( mlt_properties_get( properties, "force_fps" ) )
- {
- source_fps = mlt_properties_get_double( properties, "force_fps" );
- stream->time_base = av_d2q( source_fps, 1024 );
- mlt_properties_set_int( properties, "meta.media.frame_rate_num", stream->time_base.num );
- mlt_properties_set_int( properties, "meta.media.frame_rate_den", stream->time_base.den );
- }
- else
{
// If the muxer reports a frame rate different than the codec
#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(42<<8)+0)
#endif
mlt_properties_set_int( properties, "meta.media.frame_rate_num", frame_rate.num );
mlt_properties_set_int( properties, "meta.media.frame_rate_den", frame_rate.den );
- source_fps = av_q2d( frame_rate );
}
else
{
mlt_properties_set_int( properties, "meta.media.frame_rate_den", frame_rate.den );
}
}
-
- // source_fps is deprecated in favor of meta.media.frame_rate_num and .frame_rate_den
- 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( self->parent ) );
+ self->video_time_base = stream->time_base;
+ if ( mlt_properties_get( properties, "force_fps" ) )
+ {
+ double source_fps = mlt_properties_get_double( properties, "force_fps" );
+ AVRational fps = av_d2q( source_fps, 1024 );
+ self->video_time_base.num *= mlt_properties_get_int( properties, "meta.media.frame_rate_num" ) * fps.den;
+ self->video_time_base.den *= mlt_properties_get_int( properties, "meta.media.frame_rate_den" ) * fps.num;
+ mlt_properties_set_int( properties, "meta.media.frame_rate_num", fps.num );
+ mlt_properties_set_int( properties, "meta.media.frame_rate_den", fps.den );
+ }
// Set the YUV colorspace from override or detect
self->colorspace = mlt_properties_get_int( properties, "force_colorspace" );
#endif
// Let apps get chosen colorspace
mlt_properties_set_int( properties, "meta.media.colorspace", self->colorspace );
+
+ self->full_luma = -1;
+#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(72<<8)+2)
+ mlt_log_debug( MLT_PRODUCER_SERVICE(self->parent), "color_range %d\n", codec_context->color_range );
+ if ( codec_context->color_range == AVCOL_RANGE_JPEG )
+ self->full_luma = 1;
+#endif
+ if ( mlt_properties_get( properties, "set.force_full_luma" ) )
+ self->full_luma = mlt_properties_get_int( properties, "set.force_full_luma" );
}
return self->video_codec && self->video_index > -1;
}
{
// Reset the video properties if the index changed
self->video_index = index;
- avformat_lock();
+ pthread_mutex_lock( &self->open_mutex );
if ( self->video_codec )
avcodec_close( self->video_codec );
self->video_codec = NULL;
- avformat_unlock();
+ pthread_mutex_unlock( &self->open_mutex );
}
// Get the frame properties
// Set the width and height
mlt_properties_set_int( frame_properties, "width", self->video_codec->width );
mlt_properties_set_int( frame_properties, "height", self->video_codec->height );
- // real_width and real_height are deprecated in favor of meta.media.width and .height
mlt_properties_set_int( properties, "meta.media.width", self->video_codec->width );
mlt_properties_set_int( properties, "meta.media.height", self->video_codec->height );
- mlt_properties_set_int( frame_properties, "real_width", self->video_codec->width );
- mlt_properties_set_int( frame_properties, "real_height", self->video_codec->height );
mlt_properties_set_double( frame_properties, "aspect_ratio", aspect_ratio );
mlt_properties_set_int( frame_properties, "colorspace", self->colorspace );
if ( self->video_codec->height == 1088 && mlt_profile_dar( mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ) ) == 16.0/9.0 )
{
mlt_properties_set_int( properties, "meta.media.height", 1080 );
- mlt_properties_set_int( frame_properties, "real_height", 1080 );
}
// Add our image operation
}
}
-static int seek_audio( producer_avformat self, mlt_position position, double timecode, int *ignore )
+static int seek_audio( producer_avformat self, mlt_position position, double timecode )
{
int paused = 0;
// Seek if necessary
- if ( self->seekable && position != self->audio_expected )
+ if ( self->seekable && ( position != self->audio_expected || self->last_position < 0 ) )
{
+ if ( self->last_position == POSITION_INITIAL )
+ {
+ int video_index = self->video_index;
+ if ( video_index == -1 )
+ video_index = first_video_index( self );
+ if ( video_index >= 0 )
+ find_first_pts( self, video_index );
+ }
+
if ( position + 1 == self->audio_expected )
{
// We're paused - silence required
paused = 1;
}
- else if ( !self->seekable && position > self->audio_expected && ( position - self->audio_expected ) < 250 )
- {
- // Fast forward - seeking is inefficient for small distances - just ignore following frames
- *ignore = position - self->audio_expected;
- }
else if ( position < self->audio_expected || position - self->audio_expected >= 12 )
{
AVFormatContext *context = self->audio_format;
static int sample_bytes( AVCodecContext *context )
{
-#if LIBAVCODEC_VERSION_MAJOR >= 53
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(8<<8)+0)
+ return av_get_bytes_per_sample( context->sample_fmt );
+#elif LIBAVCODEC_VERSION_MAJOR >= 53
return av_get_bits_per_sample_fmt( context->sample_fmt ) / 8;
#else
return av_get_bits_per_sample_format( context->sample_fmt ) / 8;
#endif
}
+static void planar_to_interleaved( uint8_t *dest, uint8_t *src, int samples, int channels, int bytes_per_sample )
+{
+ int s, c;
+ for ( s = 0; s < samples; s++ )
+ {
+ for ( c = 0; c < channels; c++ )
+ {
+ memcpy( dest, src + ( c * samples + s ) * bytes_per_sample, bytes_per_sample );
+ dest += bytes_per_sample;
+ }
+ }
+}
+
static int decode_audio( producer_avformat self, int *ignore, AVPacket pkt, int channels, int samples, double timecode, double fps )
{
// Fetch the audio_format
}
else
{
- // Straight copy to audio buffer
- memcpy( &audio_buffer[ audio_used * codec_context->channels * sizeof_sample ], decode_buffer, data_size );
+ uint8_t *source = decode_buffer;
+ uint8_t *dest = &audio_buffer[ audio_used * codec_context->channels * sizeof_sample ];
+ switch ( codec_context->sample_fmt )
+ {
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ case AV_SAMPLE_FMT_U8P:
+ case AV_SAMPLE_FMT_S16P:
+ case AV_SAMPLE_FMT_S32P:
+ case AV_SAMPLE_FMT_FLTP:
+ planar_to_interleaved( dest, source, convert_samples, codec_context->channels, sizeof_sample );
+ break;
+#endif
+ default:
+ // Straight copy to audio buffer
+ memcpy( dest, decode_buffer, data_size );
+ }
audio_used += convert_samples;
}
// Skip this on non-seekable, audio-only inputs.
if ( pkt.pts >= 0 && ( self->seekable || self->video_format ) && *ignore == 0 && audio_used > samples / 2 )
{
- double current_pts = av_q2d( context->streams[ index ]->time_base ) * pkt.pts;
+ int64_t pts = pkt.pts;
+ if ( self->first_pts != AV_NOPTS_VALUE )
+ pts -= self->first_pts;
+ else if ( context->start_time != AV_NOPTS_VALUE )
+ pts -= context->start_time;
+ double timebase = av_q2d( context->streams[ index ]->time_base );
+ int64_t int_position = ( int64_t )( timebase * pts * fps + 0.5 );
int64_t req_position = ( int64_t )( timecode * fps + 0.5 );
- int64_t int_position = ( int64_t )( current_pts * fps + 0.5 );
- if ( context->start_time != AV_NOPTS_VALUE )
- int_position -= ( int64_t )( fps * context->start_time / AV_TIME_BASE + 0.5 );
+
+ mlt_log_debug( MLT_PRODUCER_SERVICE(self->parent),
+ "A pkt.pts %"PRId64" pkt.dts %"PRId64" req_pos %"PRId64" cur_pos %"PRId64" pkt_pos %"PRId64"\n",
+ pkt.pts, pkt.dts, req_position, self->current_position, int_position );
if ( int_position > 0 )
{
*ignore = req_position - int_position;
else if ( self->audio_index != INT_MAX && int_position > req_position + 2 )
// We are ahead, so seek backwards some more
- seek_audio( self, req_position, timecode - 1.0, ignore );
+ seek_audio( self, req_position, timecode - 1.0 );
}
+ // Cancel the find_first_pts() in seek_audio()
+ if ( self->video_index == -1 && self->last_position == POSITION_INITIAL )
+ self->last_position = int_position;
}
self->audio_used[ index ] = audio_used;
pthread_mutex_lock( &self->audio_mutex );
// Obtain the frame number of this frame
- mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( frame ), "avformat_position" );
+ mlt_position position = mlt_frame_original_position( frame );
// Calculate the real time code
double real_timecode = producer_time_of_frame( self->parent, position );
int ignore[ MAX_AUDIO_STREAMS ] = { 0 };
// Flag for paused (silence)
- int paused = seek_audio( self, position, real_timecode, &ignore[0] );
+ int paused = seek_audio( self, position, real_timecode );
// Initialize ignore for all streams from the seek return value
int i = MAX_AUDIO_STREAMS;
if ( self->audio_index == INT_MAX )
{
index = 0;
- index_max = context->nb_streams;
+ index_max = FFMIN( MAX_AUDIO_STREAMS, context->nb_streams );
*channels = self->total_channels;
*samples = *samples * FFMAX( self->max_frequency, *frequency ) / *frequency;
*frequency = FFMAX( self->max_frequency, *frequency );
}
// Initialize the resamplers and buffers
- for ( ; index < index_max; index++ )
+ for ( ; index < index_max && index < MAX_AUDIO_STREAMS; index++ )
{
// Get codec context
AVCodecContext *codec_context = self->audio_codec[ index ];
if ( codec_context && !self->audio_buffer[ index ] )
{
+#if LIBAVCODEC_VERSION_INT < ((54<<16)+(26<<8)+0)
// Check for resample and create if necessary
if ( codec_context->channels <= 2 )
{
self->audio_resample[ index ] = av_audio_resample_init(
self->audio_index == INT_MAX ? codec_context->channels : *channels,
codec_context->channels, *frequency, codec_context->sample_rate,
- SAMPLE_FMT_S16, codec_context->sample_fmt, 16, 10, 0, 0.8 );
+ AV_SAMPLE_FMT_S16, codec_context->sample_fmt, 16, 10, 0, 0.8 );
#else
self->audio_resample[ index ] = audio_resample_init(
self->audio_index == INT_MAX ? codec_context->channels : *channels,
#endif
}
else
+#endif
{
codec_context->request_channels = self->audio_index == INT_MAX ? codec_context->channels : *channels;
sizeof_sample = sample_bytes( codec_context );
}
// Get the audio if required
- if ( !paused )
+ if ( !paused && *frequency > 0 )
{
int ret = 0;
int got_audio = 0;
{
// Check if there is enough audio for all streams
got_audio = 1;
- for ( index = 0; got_audio && index < context->nb_streams; index++ )
+ for ( index = 0; got_audio && index < index_max; index++ )
if ( ( self->audio_codec[ index ] && self->audio_used[ index ] < *samples ) || ignore[ index ] )
got_audio = 0;
if ( got_audio )
// We only deal with audio from the selected audio index
index = pkt.stream_index;
- if ( ret >= 0 && pkt.data && pkt.size > 0 && ( index == self->audio_index ||
+ if ( index < MAX_AUDIO_STREAMS && ret >= 0 && pkt.data && pkt.size > 0 && ( index == self->audio_index ||
( self->audio_index == INT_MAX && context->streams[ index ]->codec->codec_type == CODEC_TYPE_AUDIO ) ) )
{
int channels2 = ( self->audio_index == INT_MAX || !self->audio_resample[index] ) ?
index = self->audio_index;
*channels = self->audio_codec[ index ]->channels;
*frequency = self->audio_codec[ index ]->sample_rate;
- *format = self->audio_codec[ index ]->sample_fmt == SAMPLE_FMT_S32 ? mlt_audio_s32le
- : self->audio_codec[ index ]->sample_fmt == SAMPLE_FMT_FLT ? mlt_audio_f32le
- : mlt_audio_s16;
+ *format = pick_audio_format( self->audio_codec[ index ]->sample_fmt );
sizeof_sample = sample_bytes( self->audio_codec[ index ] );
}
else if ( self->audio_index == INT_MAX )
{
- // This only works if all audio tracks have the same sample format.
for ( index = 0; index < index_max; index++ )
if ( self->audio_codec[ index ] && !self->audio_resample[ index ] )
{
- *format = self->audio_codec[ index ]->sample_fmt == SAMPLE_FMT_S32 ? mlt_audio_s32le
- : self->audio_codec[ index ]->sample_fmt == SAMPLE_FMT_FLT ? mlt_audio_f32le
- : mlt_audio_s16;
+ // XXX: This only works if all audio tracks have the same sample format.
+ *format = pick_audio_format( self->audio_codec[ index ]->sample_fmt );
sizeof_sample = sample_bytes( self->audio_codec[ index ] );
break;
}
AVCodec *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( );
+ pthread_mutex_lock( &self->open_mutex );
+#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
+ if ( codec && avcodec_open2( codec_context, codec, NULL ) >= 0 )
+#else
if ( codec && avcodec_open( codec_context, codec ) >= 0 )
+#endif
{
// Now store the codec with its destructor
if ( self->audio_codec[ index ] )
// Remember that we can't use self later
self->audio_index = -1;
}
- avformat_unlock( );
+ pthread_mutex_unlock( &self->open_mutex );
// Process properties as AVOptions
apply_properties( codec_context, properties, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM );
-#if LIBAVCODEC_VERSION_MAJOR >= 53
+#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(122<<8)+0)
if ( codec && codec->priv_class && codec_context->priv_data )
apply_properties( codec_context->priv_data, properties, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM );
#endif
index = self->audio_index;
mlt_properties_set_int( properties, "audio_index", index );
}
+ if ( context && index > -1 && index < INT_MAX &&
+ pick_audio_format( context->streams[ index ]->codec->sample_fmt ) == mlt_audio_none )
+ {
+ index = -1;
+ }
// Update the audio properties if the index changed
if ( context && index > -1 && index != self->audio_index )
{
- avformat_lock();
+ pthread_mutex_lock( &self->open_mutex );
if ( self->audio_codec[ self->audio_index ] )
avcodec_close( self->audio_codec[ self->audio_index ] );
self->audio_codec[ self->audio_index ] = NULL;
- avformat_unlock();
+ pthread_mutex_unlock( &self->open_mutex );
}
if ( self->audio_index != -1 )
self->audio_index = index;
else if ( context && index > -1 && audio_codec_init( self, index, properties ) )
{
// Set the frame properties
- if ( index < INT_MAX )
+ if ( index < MAX_AUDIO_STREAMS )
{
- mlt_properties_set_int( frame_properties, "frequency", self->audio_codec[ index ]->sample_rate );
- mlt_properties_set_int( frame_properties, "channels", self->audio_codec[ index ]->channels );
+ mlt_properties_set_int( frame_properties, "audio_frequency", self->audio_codec[ index ]->sample_rate );
+ mlt_properties_set_int( frame_properties, "audio_channels", self->audio_codec[ index ]->channels );
}
}
if ( context && index > -1 )
// Set the position of this producer
mlt_position position = self->seekable ? mlt_producer_frame( producer ) : self->nonseek_position++;
- mlt_properties_set_position( MLT_FRAME_PROPERTIES( *frame ), "avformat_position", position );
+ mlt_properties_set_position( MLT_FRAME_PROPERTIES( *frame ), "original_position", position );
// Calculate the next timecode
mlt_producer_prepare_next( producer );
mlt_log_debug( NULL, "producer_avformat_close\n" );
// Cleanup av contexts
+ av_free_packet( &self->pkt );
av_free( self->av_frame );
- avformat_lock();
+ pthread_mutex_lock( &self->open_mutex );
int i;
for ( i = 0; i < MAX_AUDIO_STREAMS; i++ )
{
avcodec_close( self->video_codec );
self->video_codec = NULL;
// Close the file
+#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(17<<8)+0)
+ if ( self->dummy_context )
+ avformat_close_input( &self->dummy_context );
+ if ( self->seekable && self->audio_format )
+ avformat_close_input( &self->audio_format );
+ if ( self->video_format )
+ avformat_close_input( &self->video_format );
+#else
if ( self->dummy_context )
av_close_input_file( self->dummy_context );
if ( self->seekable && self->audio_format )
av_close_input_file( self->audio_format );
if ( self->video_format )
av_close_input_file( self->video_format );
- avformat_unlock();
+#endif
+ pthread_mutex_unlock( &self->open_mutex );
#ifdef VDPAU
vdpau_producer_close( self );
#endif
mlt_cache_close( self->image_cache );
// Cleanup the mutexes
- pthread_mutex_destroy( &self->audio_mutex );
- pthread_mutex_destroy( &self->video_mutex );
- pthread_mutex_destroy( &self->packets_mutex );
+ if ( self->is_mutex_init )
+ {
+ pthread_mutex_destroy( &self->audio_mutex );
+ pthread_mutex_destroy( &self->video_mutex );
+ pthread_mutex_destroy( &self->packets_mutex );
+ pthread_mutex_destroy( &self->open_mutex );
+ }
// Cleanup the packet queues
AVPacket *pkt;
type: producer
identifier: avformat
title: FFmpeg Reader
-version: 1
+version: 2
copyright: Copyright (C) 2003-2011 Ushodaya Enterprises Limited
license: LGPL
language: en
default: 0
widget: checkbox
- - identifier: new_seek
- title: Use new seeking
- description: >
- When this is not provided (recommended), it is enabled only for H.264 in
- MPEG-2 Transport Streams.
+ - identifier: cache
+ title: Number of images cache
type: integer
- minimum: 0
- maximum: 1
- widget: checkbox
+ description: >
+ By default, this producer caches images to facilitate YADIF deinterlace,
+ which needs previous and next frames. Also, caching helps with frame-
+ stepping within a player. The default number of images cached is supplied
+ by the MLT framework, which is currently 4, but you can override it
+ with this property. You can also disable caching by setting it to 0.
+ If you are using parallel processing with YADIF deinterlacing, then
+ you might need to increase caching to prevent inadvertent backward seeks.
+ One can also set this value globally for all instances of avformat by
+ setting the environment variable MLT_AVFORMAT_CACHE.
- identifier: force_progressive
title: Force progressive
static VdpDecoderDestroy *vdp_decoder_destroy;
static VdpDecoderRender *vdp_decoder_render;
+// TODO: Shouldn't these be protected by a mutex?
static int vdpau_init_done = 0;
+static int vdpau_supported = 1;
/** VDPAUD functions
*/
static int vdpau_init( producer_avformat self )
{
+ if ( !vdpau_supported )
+ return 0;
mlt_log_debug( MLT_PRODUCER_SERVICE(self->parent), "vdpau_init\n" );
int success = 0;
mlt_properties properties = MLT_PRODUCER_PROPERTIES( self->parent );
if ( !vdpau_init_done )
{
int flags = RTLD_NOW;
- object = dlopen( "/usr/lib64/libvdpau.so", flags );
+ object = dlopen( "/usr/lib/libvdpau.so", flags );
+#ifdef ARCH_X86_64
if ( !object )
- object = dlopen( "/usr/lib/libvdpau.so", flags );
+ object = dlopen( "/usr/lib64/libvdpau.so", flags );
+ if ( !object )
+ object = dlopen( "/usr/lib/x86_64-linux-gnu/libvdpau.so.1", flags );
+#elif ARCH_X86
+ if ( !object )
+ object = dlopen( "/usr/lib/i386-linux-gnu/libvdpau.so.1", flags );
+#endif
if ( !object )
object = dlopen( "/usr/local/lib/libvdpau.so", flags );
if ( object )
else
{
mlt_log( MLT_PRODUCER_SERVICE(self->parent), MLT_LOG_WARNING, "%s: failed to dlopen libvdpau.so\n (%s)\n", __FUNCTION__, dlerror() );
+ // Don't try again.
+ vdpau_supported = 0;
return success;
}
}
frame->reordered_opaque = codec_context->reordered_opaque;
if ( frame->reference )
{
- frame->age = self->vdpau->ip_age[0];
self->vdpau->ip_age[0] = self->vdpau->ip_age[1] + 1;
self->vdpau->ip_age[1] = 1;
self->vdpau->b_age++;
}
else
{
- frame->age = self->vdpau->b_age;
self->vdpau->ip_age[0] ++;
self->vdpau->ip_age[1] ++;
self->vdpau->b_age = 1;
--- /dev/null
+CFLAGS += -I../..
+
+LDFLAGS += -L../../framework -lmlt -lm -lpthread
+
+include ../../../config.mak
+
+TARGET = ../libmltavsync$(LIBSUF)
+
+OBJS = factory.o \
+ producer_blipflash.o \
+ consumer_blipflash.o
+
+ASM_OBJS =
+
+SRCS := $(OBJS:.o=.c)
+
+all: $(TARGET)
+
+$(TARGET): $(OBJS) $(ASM_OBJS)
+ $(CC) $(SHFLAGS) -o $@ $(OBJS) $(ASM_OBJS) $(LDFLAGS)
+
+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)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/avsync"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/avsync"
+
+ifneq ($(wildcard .depend),)
+include .depend
+endif
--- /dev/null
+/*
+ * consumer_blipflash.c -- a consumer to measure A/V sync from a blip/flash
+ * source
+ * Copyright (C) 2013 Brian Matherly
+ * Author: Brian Matherly <pez4brian@yahoo.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// mlt Header files
+#include <framework/mlt_consumer.h>
+#include <framework/mlt_frame.h>
+#include <framework/mlt_deque.h>
+
+// System header files
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+// Private constants
+#define SAMPLE_FREQ 48000
+#define FLASH_LUMA_THRESHOLD 150
+#define BLIP_THRESHOLD 0.5
+
+// Private types
+typedef struct
+{
+ int64_t flash_history[2];
+ int flash_history_count;
+ int64_t blip_history[2];
+ int blip_history_count;
+ int blip_in_progress;
+ int samples_since_blip;
+ int blip;
+ int flash;
+ int sample_offset;
+ FILE* out_file;
+ int report_frames;
+} avsync_stats;
+
+// Forward references.
+static int consumer_start( mlt_consumer consumer );
+static int consumer_stop( mlt_consumer consumer );
+static int consumer_is_stopped( mlt_consumer consumer );
+static void *consumer_thread( void *arg );
+static void consumer_close( mlt_consumer consumer );
+
+/** Initialize the consumer.
+*/
+
+mlt_consumer consumer_blipflash_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ // Allocate the consumer
+ mlt_consumer consumer = mlt_consumer_new( profile );
+ mlt_properties consumer_properties = MLT_CONSUMER_PROPERTIES( consumer );
+ avsync_stats* stats = NULL;
+
+ // If memory allocated and initializes without error
+ if ( consumer != NULL )
+ {
+ // Set up start/stop/terminated callbacks
+ consumer->close = consumer_close;
+ consumer->start = consumer_start;
+ consumer->stop = consumer_stop;
+ consumer->is_stopped = consumer_is_stopped;
+
+ stats = mlt_pool_alloc( sizeof( avsync_stats ) );
+ stats->flash_history_count = 0;
+ stats->blip_history_count = 0;
+ stats->blip_in_progress = 0;
+ stats->samples_since_blip = 0;
+ stats->blip = 0;
+ stats->flash = 0;
+ stats->sample_offset = INT_MAX;
+ stats->report_frames = 0;
+ stats->out_file = stdout;
+ if ( arg != NULL )
+ {
+ FILE* out_file = fopen( arg, "w" );
+ if ( out_file != NULL )
+ stats->out_file = out_file;
+ }
+ mlt_properties_set_data( consumer_properties, "_stats", stats, 0, NULL, NULL );
+
+ mlt_properties_set( consumer_properties, "report", "blip" );
+ }
+
+ // Return this
+ return consumer;
+}
+
+/** Start the consumer.
+*/
+
+static int consumer_start( mlt_consumer consumer )
+{
+ // Get the properties
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
+
+ // 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, consumer );
+ }
+ return 0;
+}
+
+/** Stop the consumer.
+*/
+
+static int consumer_stop( mlt_consumer consumer )
+{
+ // Get the properties
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
+
+ // 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
+ if ( thread )
+ pthread_join( *thread, NULL );
+ }
+
+ return 0;
+}
+
+/** Determine if the consumer is stopped.
+*/
+
+static int consumer_is_stopped( mlt_consumer consumer )
+{
+ // Get the properties
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
+ return !mlt_properties_get_int( properties, "_running" );
+}
+
+static void detect_flash( mlt_frame frame, mlt_position pos, double fps, avsync_stats* stats )
+{
+ int width = 0;
+ int height = 0;
+ mlt_image_format format = mlt_image_yuv422;
+ uint8_t* image = NULL;
+ int error = mlt_frame_get_image( frame, &image, &format, &width, &height, 0 );
+
+ if ( !error && format == mlt_image_yuv422 && image != NULL )
+ {
+ int i, j = 0;
+ int y_accumulator = 0;
+
+ // Add up the luma values from 4 samples in 4 different quadrants.
+ for( i = 1; i < 3; i++ )
+ {
+ int x = ( width / 3 ) * i;
+ x = x - x % 2; // Make sure this is a luma sample
+ for( j = 1; j < 3; j++ )
+ {
+ int y = ( height / 3 ) * j;
+ y_accumulator += image[ y * height * 2 + x * 2 ];
+ }
+ }
+ // If the average luma value is > 150, assume it is a flash.
+ stats->flash = ( y_accumulator / 4 ) > FLASH_LUMA_THRESHOLD;
+ }
+
+ if( stats->flash )
+ {
+ stats->flash_history[1] = stats->flash_history[0];
+ stats->flash_history[0] = mlt_sample_calculator_to_now( fps, SAMPLE_FREQ, pos );
+ if( stats->flash_history_count < 2 )
+ {
+ stats->flash_history_count++;
+ }
+ }
+}
+
+static void detect_blip( mlt_frame frame, mlt_position pos, double fps, avsync_stats* stats )
+{
+ int frequency = SAMPLE_FREQ;
+ int channels = 1;
+ int samples = mlt_sample_calculator( fps, frequency, pos );
+ mlt_audio_format format = mlt_audio_float;
+ float* buffer = NULL;
+ int error = mlt_frame_get_audio( frame, (void**) &buffer, &format, &frequency, &channels, &samples );
+
+ if ( !error && format == mlt_audio_float && buffer != NULL )
+ {
+ int i = 0;
+
+ for( i = 0; i < samples; i++ )
+ {
+ if( !stats->blip_in_progress )
+ {
+ if( buffer[i] > BLIP_THRESHOLD || buffer[i] < -BLIP_THRESHOLD )
+ {
+ // This sample must start a blip
+ stats->blip_in_progress = 1;
+ stats->samples_since_blip = 0;
+
+ stats->blip_history[1] = stats->blip_history[0];
+ stats->blip_history[0] = mlt_sample_calculator_to_now( fps, SAMPLE_FREQ, pos );
+ stats->blip_history[0] += i;
+ if( stats->blip_history_count < 2 )
+ {
+ stats->blip_history_count++;
+ }
+ stats->blip = 1;
+ }
+ }
+ else
+ {
+ if( buffer[i] > -BLIP_THRESHOLD && buffer[i] < BLIP_THRESHOLD )
+ {
+ if( ++stats->samples_since_blip > frequency / 1000 )
+ {
+ // One ms of silence means the blip is over
+ stats->blip_in_progress = 0;
+ stats->samples_since_blip = 0;
+ }
+ }
+ else
+ {
+ stats->samples_since_blip = 0;
+ }
+ }
+ }
+ }
+}
+
+static void calculate_sync( avsync_stats* stats )
+{
+ if( stats->blip || stats->flash )
+ {
+ if( stats->flash_history_count > 0 &&
+ stats->blip_history_count > 0 &&
+ stats->blip_history[0] == stats->flash_history[0] )
+ {
+ // The flash and blip occurred at the same time.
+ stats->sample_offset = 0;
+ }
+ if( stats->flash_history_count > 1 &&
+ stats->blip_history_count > 0 &&
+ stats->blip_history[0] <= stats->flash_history[0] &&
+ stats->blip_history[0] >= stats->flash_history[1] )
+ {
+ // The latest blip occurred between two flashes
+ if( stats->flash_history[0] - stats->blip_history[0] >
+ stats->blip_history[0] - stats->flash_history[1] )
+ {
+ // Blip is closer to the previous flash.
+ // F1---B0--------F0
+ // ^----^
+ // Video leads audio (negative number).
+ stats->sample_offset = (int)(stats->flash_history[1] - stats->blip_history[0] );
+ }
+ else
+ {
+ // Blip is closer to the current flash.
+ // F1--------B0---F0
+ // ^----^
+ // Audio leads video (positive number).
+ stats->sample_offset = (int)(stats->flash_history[0] - stats->blip_history[0]);
+ }
+ }
+ else if( stats->blip_history_count > 1 &&
+ stats->flash_history_count > 0 &&
+ stats->flash_history[0] <= stats->blip_history[0] &&
+ stats->flash_history[0] >= stats->blip_history[1] )
+ {
+ // The latest flash occurred between two blips
+ if( stats->blip_history[0] - stats->flash_history[0] >
+ stats->flash_history[0] - stats->blip_history[1] )
+ {
+ // Flash is closer to the previous blip.
+ // B1---F0--------B0
+ // ^----^
+ // Audio leads video (positive number).
+ stats->sample_offset = (int)(stats->flash_history[0] - stats->blip_history[1]);
+ }
+ else
+ {
+ // Flash is closer to the latest blip.
+ // B1--------F0---B0
+ // ^----^
+ // Video leads audio (negative number).
+ stats->sample_offset = (int)(stats->flash_history[0] - stats->blip_history[0] );
+ }
+ }
+ }
+}
+
+static void report_results( avsync_stats* stats, mlt_position pos )
+{
+ if( stats->report_frames || stats->blip )
+ {
+ if( stats->sample_offset == INT_MAX )
+ {
+ fprintf( stats->out_file, "%d\t??\n", pos );
+ }
+ else
+ {
+ // Convert to milliseconds.
+ double ms_offset = (double)stats->sample_offset * 1000.0 / (double)SAMPLE_FREQ;
+ fprintf( stats->out_file, "%d\t%02.02f\n", pos, ms_offset );
+ }
+ }
+ stats->blip = 0;
+ stats->flash = 0;
+}
+
+/** The main thread - the argument is simply the consumer.
+*/
+
+static void *consumer_thread( void *arg )
+{
+ // Map the argument to the object
+ mlt_consumer consumer = arg;
+
+ // Get the properties
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
+
+ // 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( consumer );
+
+ // 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 )
+ {
+ avsync_stats* stats = mlt_properties_get_data( properties, "_stats", NULL );
+ double fps = mlt_properties_get_double( properties, "fps" );
+ mlt_position pos = mlt_frame_get_position( frame );
+
+ if( !strcmp( mlt_properties_get( properties, "report" ), "frame" ) )
+ {
+ stats->report_frames = 1;
+ }
+ else
+ {
+ stats->report_frames = 0;
+ }
+
+ detect_flash( frame, pos, fps, stats );
+ detect_blip( frame, pos, fps, stats );
+ calculate_sync( stats );
+ report_results( stats, pos );
+
+ // 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( consumer );
+
+ return NULL;
+}
+
+/** Close the consumer.
+*/
+
+static void consumer_close( mlt_consumer consumer )
+{
+ mlt_properties consumer_properties = MLT_CONSUMER_PROPERTIES( consumer );
+ avsync_stats* stats = mlt_properties_get_data( consumer_properties, "_stats", NULL );
+
+ // Stop the consumer
+ mlt_consumer_stop( consumer );
+
+ // Close the file
+ if( stats->out_file != stdout )
+ {
+ fclose( stats->out_file );
+ }
+
+ // Clean up memory
+ mlt_pool_release( stats );
+
+ // Close the parent
+ mlt_consumer_close( consumer );
+
+ // Free the memory
+ free( consumer );
+}
--- /dev/null
+schema_version: 0.1
+type: consumer
+identifier: blipflash
+title: Blip Flash
+version: 1
+copyright: Brian Matherly
+creator: Brian Matherly
+license: LGPLv2.1
+language: en
+tags:
+ - Video
+ - Audio
+description: >
+ Calculate the A/V sync for a blip flash source.
+ Sync can be recalculated whenever a blip or a flash is detected.
+parameters:
+ - identifier: argument
+ title: Report File
+ type: string
+ description: >
+ The file to report the results to. If empty, the results will be reported to standard out.
+ required: no
+ widget: filesave
+ - identifier: report
+ title: Report Style
+ type: string
+ description: >
+ When to report sync - every frame or only when blips occur.
+ default: blip
+ values:
+ - blip
+ - frame
+ mutable: yes
+ widget: combo
--- /dev/null
+/*
+ * factory.c -- the factory method interfaces
+ * Copyright (C) 2013 Brian Matherly
+ * Author: Brian Matherly <pez4brian@yahoo.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <framework/mlt.h>
+#include <string.h>
+#include <limits.h>
+
+extern mlt_consumer consumer_blipflash_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_producer producer_blipflash_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+
+static mlt_properties metadata( mlt_service_type type, const char *id, void *data )
+{
+ char file[ PATH_MAX ];
+ snprintf( file, PATH_MAX, "%s/avsync/%s", mlt_environment( "MLT_DATA" ), (char*) data );
+ return mlt_properties_parse_yaml( file );
+}
+
+MLT_REPOSITORY
+{
+ MLT_REGISTER( consumer_type, "blipflash", consumer_blipflash_init );
+ MLT_REGISTER( producer_type, "blipflash", producer_blipflash_init );
+
+ MLT_REGISTER_METADATA( consumer_type, "blipflash", metadata, "consumer_blipflash.yml" );
+ MLT_REGISTER_METADATA( producer_type, "blipflash", metadata, "producer_blipflash.yml" );
+}
--- /dev/null
+/*
+ * producer_blipflash.c -- blip/flash generating producer
+ * Copyright (C) 2013 Brian Matherly
+ * Author: Brian Matherly <pez4brian@yahoo.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <framework/mlt.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/** Fill an audio buffer with 1kHz "blip" samples.
+*/
+
+static void fill_blip( mlt_properties producer_properties, float* buffer, int frequency, int channels, int samples )
+{
+ int new_size = samples * channels * sizeof( float );
+ int old_size = 0;
+ float* blip = mlt_properties_get_data( producer_properties, "_blip", &old_size );
+
+ if( !blip || new_size > old_size )
+ {
+ blip = mlt_pool_alloc( new_size );
+
+ // Fill the blip buffer
+ if ( blip != NULL )
+ {
+ int s = 0;
+ int c = 0;
+
+ for( s = 0; s < samples; s++ )
+ {
+ float f = 1000.0;
+ float t = (float)s/(float)frequency;
+ // Add 90 deg so the blip always starts at 1 for easy detection.
+ float phase = M_PI / 2;
+ float value = sin( 2*M_PI*f*t + phase );
+
+ for( c = 0; c < channels; c++ )
+ {
+ float* sample_ptr = ((float*) blip) + (c * samples) + s;
+ *sample_ptr = value;
+ }
+ }
+ }
+ // Cache the audio blip to save from regenerating it with every blip.
+ mlt_properties_set_data( producer_properties, "_blip", blip, new_size, mlt_pool_release, NULL );
+ };
+
+ memcpy( buffer, blip, new_size );
+}
+
+static int producer_get_audio( mlt_frame frame, int16_t** buffer, mlt_audio_format* format, int* frequency, int* channels, int* samples )
+{
+ mlt_producer producer = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "_producer_blipflash", NULL );
+ mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
+ int size = *samples * *channels * sizeof( float );
+ double fps = mlt_producer_get_fps( producer );
+ int frames = mlt_frame_get_position( frame ) + mlt_properties_get_int( producer_properties, "offset" );
+ int seconds = frames / fps;
+
+ // Correct the returns if necessary
+ *format = mlt_audio_float;
+ *frequency = *frequency <= 0 ? 48000 : *frequency;
+ *channels = *channels <= 0 ? 2 : *channels;
+ *samples = *samples <= 0 ? mlt_sample_calculator( fps, *frequency, frames ) : *samples;
+
+ // Allocate the buffer
+ *buffer = mlt_pool_alloc( size );
+
+ // Determine if this should be a blip or silence.
+ frames = frames % lrint( fps );
+ seconds = seconds % mlt_properties_get_int( producer_properties, "period" );
+ if( seconds == 0 && frames == 0 )
+ {
+ fill_blip( producer_properties, (float*)*buffer, *frequency, *channels, *samples );
+ }
+ else
+ {
+ // Fill silence.
+ memset( *buffer, 0, size );
+ }
+
+ // Set the buffer for destruction
+ mlt_frame_set_audio( frame, *buffer, *format, size, mlt_pool_release );
+
+ return 0;
+}
+
+/** Fill an image buffer with either white (flash) or black as requested.
+*/
+
+static void fill_image( mlt_properties producer_properties, char* color, uint8_t* buffer, mlt_image_format format, int width, int height )
+{
+
+ int new_size = mlt_image_format_size( format, width, height, NULL );
+ int old_size = 0;
+ uint8_t* image = image = mlt_properties_get_data( producer_properties, color, &old_size );
+
+ if( !image || new_size > old_size )
+ {
+ // Need to create a new cached image.
+ image = mlt_pool_alloc( new_size );
+
+ if ( image != NULL )
+ {
+ uint8_t r, g, b;
+ uint8_t* p = image;
+
+ if( !strcmp( color, "_flash" ) )
+ {
+ r = g = b = 255; // White
+ }
+ else
+ {
+ r = g = b = 0; // Black
+ }
+
+ switch( format )
+ {
+ default:
+ case mlt_image_yuv422:
+ {
+ int uneven = width % 2;
+ int count = ( width - uneven ) / 2 + 1;
+ uint8_t y, u, v;
+
+ RGB2YUV_601_SCALED( r, g, b, y, u, v );
+ int i = height + 1;
+ while ( --i )
+ {
+ int j = count;
+ while ( --j )
+ {
+ *p ++ = y;
+ *p ++ = u;
+ *p ++ = y;
+ *p ++ = v;
+ }
+ if ( uneven )
+ {
+ *p ++ = y;
+ *p ++ = u;
+ }
+ }
+ break;
+ }
+ case mlt_image_rgb24:
+ {
+ int i = width * height + 1;
+ while ( --i )
+ {
+ *p ++ = r;
+ *p ++ = g;
+ *p ++ = b;
+ }
+ break;
+ }
+ case mlt_image_rgb24a:
+ {
+ int i = width * height + 1;
+ while ( --i )
+ {
+ *p ++ = r;
+ *p ++ = g;
+ *p ++ = b;
+ *p ++ = 255; // alpha
+ }
+ break;
+ }
+ }
+ // Cache the image to save from regenerating it with every frame.
+ mlt_properties_set_data( producer_properties, color, image, new_size, mlt_pool_release, NULL );
+ }
+ }
+
+ memcpy( buffer, image, new_size );
+}
+
+static int producer_get_image( mlt_frame frame, uint8_t** buffer, mlt_image_format* format, int* width, int* height, int writable )
+{
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+ mlt_producer producer = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "_producer_blipflash", NULL );
+ mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
+ int size = 0;
+ double fps = mlt_producer_get_fps( producer );
+ int frames = mlt_frame_get_position( frame );
+ int seconds = frames / fps;
+
+ mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) );
+
+ // Correct the returns if necessary
+ if( *format != mlt_image_yuv422 && *format != mlt_image_rgb24 && *format != mlt_image_rgb24a )
+ *format = mlt_image_yuv422;
+ if( *width <= 0 )
+ *width = mlt_service_profile( MLT_PRODUCER_SERVICE(producer) )->width;
+ if ( *height <= 0 )
+ *height = mlt_service_profile( MLT_PRODUCER_SERVICE(producer) )->height;
+
+ // Allocate the buffer
+ size = mlt_image_format_size( *format, *width, *height, NULL );
+ *buffer = mlt_pool_alloc( size );
+
+ // Determine if this should be a flash or black.
+ frames = frames % lrint( fps );
+ seconds = seconds % mlt_properties_get_int( producer_properties, "period" );
+ if( seconds == 0 && frames == 0 )
+ {
+ fill_image( producer_properties, "_flash", *buffer, *format, *width, *height );
+ }
+ else
+ {
+ fill_image( producer_properties, "_black", *buffer, *format, *width, *height );
+ }
+
+ mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
+
+ // Create the alpha channel
+ int alpha_size = *width * *height;
+ uint8_t *alpha = mlt_pool_alloc( alpha_size );
+ if ( alpha )
+ memset( alpha, 255, alpha_size );
+
+ // Update the frame
+ mlt_frame_set_image( frame, *buffer, size, mlt_pool_release );
+ mlt_frame_set_alpha( frame, alpha, alpha_size, mlt_pool_release );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_properties, "aspect_ratio" ) );
+ mlt_properties_set_int( properties, "progressive", 1 );
+ mlt_properties_set_int( properties, "meta.media.width", *width );
+ mlt_properties_set_int( properties, "meta.media.height", *height );
+
+ 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
+ mlt_properties frame_properties = MLT_FRAME_PROPERTIES( *frame );
+
+ // Save the producer to be used later
+ mlt_properties_set_data( frame_properties, "_producer_blipflash", producer, 0, NULL, NULL );
+
+ // Update time code on the frame
+ mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
+
+ // Configure callbacks
+ mlt_frame_push_get_image( *frame, producer_get_image );
+ mlt_frame_push_audio( *frame, producer_get_audio );
+ }
+
+ // Calculate the next time code
+ mlt_producer_prepare_next( producer );
+
+ return 0;
+}
+
+static void producer_close( mlt_producer this )
+{
+ this->close = NULL;
+ mlt_producer_close( this );
+ free( this );
+}
+
+/** Initialize.
+*/
+
+mlt_producer producer_blipflash_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ // Create a new producer object
+ mlt_producer producer = mlt_producer_new( profile );
+ mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
+
+ // Initialize the producer
+ if ( producer )
+ {
+ mlt_properties_set_int( producer_properties, "period", 1 );
+ mlt_properties_set_int( producer_properties, "offset", 0 );
+
+ // Callback registration
+ producer->get_frame = producer_get_frame;
+ producer->close = ( mlt_destructor )producer_close;
+ }
+
+ return producer;
+}
--- /dev/null
+schema_version: 0.1
+type: producer
+identifier: blipflash
+title: Blip Flash
+version: 1
+copyright: Brian Matherly
+creator: Brian Matherly
+license: LGPLv2.1
+language: en
+tags:
+ - Audio
+ - Video
+description: >
+ Generate periodic synchronized audio blips and video flashes.
+ Blips are a 1kHz tone and last the duration of the flash frame.
+parameters:
+ - identifier: period
+ title: Flash Period
+ type: integer
+ description: >
+ The period between flashes in seconds.
+ default: 1
+ readonly: no
+ mutable: yes
+ widget: spinner
+ - identifier: offset
+ title: Audio Offset
+ type: integer
+ description: >
+ The number of frames to offset the audio.
+ A positive number results in audio earlier than video.
+ An negative number results in audio later than video.
+ default: 0
+ readonly: no
+ mutable: yes
+ widget: spinner
consumer_multi.o \
consumer_null.o
+ifdef SSE2_FLAGS
+ifdef ARCH_X86_64
+OBJS += composite_line_yuv_sse2_simple.o
+endif
+endif
+
ASM_OBJS =
SRCS := $(OBJS:.o=.c)
rm -f $(OBJS) $(ASM_OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/core"
- install -m 644 data_fx.properties "$(DESTDIR)$(datadir)/mlt/core"
- install -m 644 loader.dict "$(DESTDIR)$(datadir)/mlt/core"
- install -m 644 loader.ini "$(DESTDIR)$(datadir)/mlt/core"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/core"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/core"
+ install -m 644 data_fx.properties "$(DESTDIR)$(mltdatadir)/core"
+ install -m 644 loader.dict "$(DESTDIR)$(mltdatadir)/core"
+ install -m 644 loader.ini "$(DESTDIR)$(mltdatadir)/core"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/core"
ifneq ($(wildcard .depend),)
include .depend
--- /dev/null
+/*
+ * composite_line_yuv_sse2_simple.c
+ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Author: Maksym Veremeyenko <verem@m1stereo.tv>
+ *
+ * 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 <inttypes.h>
+void composite_line_yuv_sse2_simple(uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a, int weight)
+{
+ const static unsigned char const1[] =
+ {
+ 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00
+ };
+
+ __asm__ volatile
+ (
+ "pxor %%xmm0, %%xmm0 \n\t" /* clear zero register */
+ "movdqu (%4), %%xmm9 \n\t" /* load const1 */
+ "movd %0, %%xmm1 \n\t" /* load weight and decompose */
+ "movlhps %%xmm1, %%xmm1 \n\t"
+ "pshuflw $0, %%xmm1, %%xmm1 \n\t"
+ "pshufhw $0, %%xmm1, %%xmm1 \n\t"
+
+ /*
+ xmm1 (weight)
+
+ 00 W 00 W 00 W 00 W 00 W 00 W 00 W 00 W
+ */
+ "loop_start: \n\t"
+ "movq (%1), %%xmm2 \n\t" /* load source alpha */
+ "punpcklbw %%xmm0, %%xmm2 \n\t" /* unpack alpha 8 8-bits alphas to 8 16-bits values */
+
+ /*
+ xmm2 (src alpha)
+ xmm3 (dst alpha)
+
+ 00 A8 00 A7 00 A6 00 A5 00 A4 00 A3 00 A2 00 A1
+ */
+ "pmullw %%xmm1, %%xmm2 \n\t" /* premultiply source alpha */
+ "psrlw $8, %%xmm2 \n\t"
+
+ /*
+ xmm2 (premultiplied)
+
+ 00 A8 00 A7 00 A6 00 A5 00 A4 00 A3 00 A2 00 A1
+ */
+
+
+ /*
+ DSTa = DSTa + (SRCa * (0xFF - DSTa)) >> 8
+ */
+ "movq (%5), %%xmm3 \n\t" /* load dst alpha */
+ "punpcklbw %%xmm0, %%xmm3 \n\t" /* unpack dst 8 8-bits alphas to 8 16-bits values */
+ "movdqa %%xmm9, %%xmm4 \n\t"
+ "psubw %%xmm3, %%xmm4 \n\t"
+ "pmullw %%xmm2, %%xmm4 \n\t"
+ "psrlw $8, %%xmm4 \n\t"
+ "paddw %%xmm4, %%xmm3 \n\t"
+ "packuswb %%xmm0, %%xmm3 \n\t"
+ "movq %%xmm3, (%5) \n\t" /* save dst alpha */
+
+ "movdqu (%2), %%xmm3 \n\t" /* load src */
+ "movdqu (%3), %%xmm4 \n\t" /* load dst */
+ "movdqa %%xmm3, %%xmm5 \n\t" /* dub src */
+ "movdqa %%xmm4, %%xmm6 \n\t" /* dub dst */
+
+ /*
+ xmm3 (src)
+ xmm4 (dst)
+ xmm5 (src)
+ xmm6 (dst)
+
+ U8 V8 U7 V7 U6 V6 U5 V5 U4 V4 U3 V3 U2 V2 U1 V1
+ */
+
+ "punpcklbw %%xmm0, %%xmm5 \n\t" /* unpack src low */
+ "punpcklbw %%xmm0, %%xmm6 \n\t" /* unpack dst low */
+ "punpckhbw %%xmm0, %%xmm3 \n\t" /* unpack src high */
+ "punpckhbw %%xmm0, %%xmm4 \n\t" /* unpack dst high */
+
+ /*
+ xmm5 (src_l)
+ xmm6 (dst_l)
+
+ 00 U4 00 V4 00 U3 00 V3 00 U2 00 V2 00 U1 00 V1
+
+ xmm3 (src_u)
+ xmm4 (dst_u)
+
+ 00 U8 00 V8 00 U7 00 V7 00 U6 00 V6 00 U5 00 V5
+ */
+
+ "movdqa %%xmm2, %%xmm7 \n\t" /* dub alpha */
+ "movdqa %%xmm2, %%xmm8 \n\t" /* dub alpha */
+ "movlhps %%xmm7, %%xmm7 \n\t" /* dub low */
+ "movhlps %%xmm8, %%xmm8 \n\t" /* dub high */
+
+ /*
+ xmm7 (src alpha)
+
+ 00 A4 00 A3 00 A2 00 A1 00 A4 00 A3 00 A2 00 A1
+ xmm8 (src alpha)
+
+ 00 A8 00 A7 00 A6 00 A5 00 A8 00 A7 00 A6 00 A5
+ */
+
+ "pshuflw $0x50, %%xmm7, %%xmm7 \n\t"
+ "pshuflw $0x50, %%xmm8, %%xmm8 \n\t"
+ "pshufhw $0xFA, %%xmm7, %%xmm7 \n\t"
+ "pshufhw $0xFA, %%xmm8, %%xmm8 \n\t"
+
+ /*
+ xmm7 (src alpha lower)
+
+ 00 A4 00 A4 00 A3 00 A3 00 A2 00 A2 00 A1 00 A1
+
+ xmm8 (src alpha upper)
+ 00 A8 00 A8 00 A7 00 A7 00 A6 00 A6 00 A5 00 A5
+ */
+
+
+ /*
+ DST = SRC * ALPHA + DST * (0xFF - ALPHA)
+ SRC * ALPHA + DST * 0xFF - DST * ALPHA
+ (SRC - DST) * ALPHA + DST * 0xFF
+
+ */
+ "psubw %%xmm4, %%xmm3 \n\t" /* src = src - dst */
+ "psubw %%xmm6, %%xmm5 \n\t"
+ "pmullw %%xmm8, %%xmm3 \n\t" /* src = src * alpha */
+ "pmullw %%xmm7, %%xmm5 \n\t"
+ "pmullw %%xmm9, %%xmm4 \n\t" /* dst = dst * 0xFF */
+ "pmullw %%xmm9, %%xmm6 \n\t"
+ "paddw %%xmm3, %%xmm4 \n\t" /* dst = dst + src */
+ "paddw %%xmm5, %%xmm6 \n\t"
+ "psrlw $8, %%xmm4 \n\t" /* dst = dst >> 8 */
+ "psrlw $8, %%xmm6 \n\t"
+// "pminsw %%xmm9, %%xmm4 \n\t" /* clamp values */
+// "pminsw %%xmm9, %%xmm6 \n\t"
+
+ /*
+ xmm6 (dst_l)
+
+ 00 U4 00 V4 00 U3 00 V3 00 U2 00 V2 00 U1 00 V1
+
+ xmm4 (dst_u)
+
+ 00 U8 00 V8 00 U7 00 V7 00 U6 00 V6 00 U5 00 V5
+ */
+ "packuswb %%xmm4, %%xmm6 \n\t"
+
+ /*
+ xmm6 (dst)
+
+ U8 V8 U7 V7 U6 V6 U5 V5 U4 V4 U3 V3 U2 V2 U1 V1
+ */
+ "movdqu %%xmm6, (%3) \n\t" /* store dst */
+
+ /*
+ increment pointers
+ */
+ "add $0x08, %1 \n\t"
+ "add $0x08, %5 \n\t"
+ "add $0x10, %2 \n\t"
+ "add $0x10, %3 \n\t"
+
+ "dec %6 \n\t"
+ "jnz loop_start \n\t"
+
+ :
+ : "r" (weight >> 8), "r" (alpha_b), "r" (src), "r" (dest), "r" (const1) , "r" (alpha_a), "r" (width / 8)
+ //: "xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7","xmm8","xmm9", "memory"
+ );
+};
// The swscale and avcolor_space filters require resolution as arg to test compatibility
if ( strncmp( effect, "swscale", 7 ) == 0 || strncmp( effect, "avcolo", 6 ) == 0 )
- arg = (char*) mlt_properties_get_int( MLT_SERVICE_PROPERTIES( service ), "_real_width" );
+ arg = (char*) mlt_properties_get_int( MLT_SERVICE_PROPERTIES( service ), "meta.media.width" );
- mlt_filter filter = mlt_factory_filter( profile, id, arg );
- if ( filter != NULL )
+ // We cannot use GLSL-based filters here.
+ if ( strncmp( effect, "movit.", 6 ) && strncmp( effect, "glsl.", 5 ) )
{
- mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "_loader", 1 );
- mlt_service_attach( service, filter );
- mlt_filter_close( filter );
- *created = 1;
+ mlt_filter filter = mlt_factory_filter( profile, id, arg );
+ if ( filter != NULL )
+ {
+ mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "_loader", 1 );
+ mlt_service_attach( service, filter );
+ mlt_filter_close( filter );
+ *created = 1;
+ }
}
free( id );
}
// Attach the audio and video format converters
int created = 0;
+ // movit.convert skips setting the frame->convert_image pointer if GLSL cannot be used.
+ mlt_filter filter = mlt_factory_filter( profile, "movit.convert", NULL );
+ if ( filter != NULL )
+ {
+ mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "_loader", 1 );
+ mlt_service_attach( service, filter );
+ mlt_filter_close( filter );
+ created = 1;
+ }
+ // avcolor_space and imageconvert only set frame->convert_image if it has not been set.
create_filter( profile, service, "avcolor_space", &created );
if ( !created )
create_filter( profile, service, "imageconvert", &created );
create_filter( profile, service, "audioconvert", &created );
}
+static void on_frame_show( void *dummy, mlt_properties properties, mlt_frame frame )
+{
+ mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
+}
+
static mlt_consumer generate_consumer( mlt_consumer consumer, mlt_properties props, int index )
{
mlt_profile profile = NULL;
mlt_properties_inherit( nested_props, props );
attach_normalisers( profile, MLT_CONSUMER_SERVICE(nested) );
+
+ // Relay the first available consumer-frame-show event
+ mlt_event event = mlt_properties_get_data( properties, "frame-show-event", NULL );
+ if ( !event )
+ {
+ event = mlt_events_listen( nested_props, properties, "consumer-frame-show", (mlt_listener) on_frame_show );
+ mlt_properties_set_data( properties, "frame-show-event", event, 0, /*mlt_event_close*/ NULL, NULL );
+ }
}
else
{
while ( nested_time <= self_time )
{
// put ideal number of samples into cloned frame
- mlt_frame clone_frame = mlt_frame_clone( frame, 0 );
+ int deeply = index > 1 ? 1 : 0;
+ mlt_frame clone_frame = mlt_frame_clone( frame, deeply );
int nested_samples = mlt_sample_calculator( nested_fps, frequency, nested_pos );
// -10 is an optimization to avoid tiny amounts of leftover samples
nested_samples = nested_samples > current_samples - 10 ? current_samples : nested_samples;
if ( mlt_properties_get_int( MLT_FRAME_PROPERTIES(frame), "_speed" ) == 0 )
foreach_consumer_refresh( consumer );
foreach_consumer_put( consumer, frame );
- mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
}
else
{
{
// Send this termination frame to nested consumers for their cancellation
foreach_consumer_put( consumer, frame );
- mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
}
if ( frame )
mlt_frame_close( frame );
MLT_REGISTER( filter_type, "audiowave", filter_audiowave_init );
MLT_REGISTER( filter_type, "brightness", filter_brightness_init );
MLT_REGISTER( filter_type, "channelcopy", filter_channelcopy_init );
- MLT_REGISTER( filter_type, "channelswap", filter_channelcopy_init );
- MLT_REGISTER( filter_type, "crop", filter_crop_init );
+ MLT_REGISTER( filter_type, "channelswap", 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, "fieldorder", filter_fieldorder_init );
/*
* filter_audiochannels.c -- convert from one audio format to another
- * Copyright (C) 2009 Ushodaya Enterprises Limited
+ * Copyright (C) 2009-2012 Ushodaya Enterprises Limited
* Author: Dan Dennedy <dan@dennedy.org>
*
* This library is free software; you can redistribute it and/or
{
for ( j = 0; j < *channels; j++ )
{
- new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + k ];
+ new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + k ];
+ k = ( k + 1 ) % channels_avail;
+ }
+ }
+ }
+ else if ( *format == mlt_audio_s32le || *format == mlt_audio_f32le )
+ {
+ int32_t *p = (int32_t*) new_buffer;
+ int i, j, k = 0;
+ for ( i = 0; i < *samples; i++ )
+ {
+ for ( j = 0; j < *channels; j++ )
+ {
+ p[ ( i * *channels ) + j ] = ((int32_t*)(*buffer))[ ( i * channels_avail ) + k ];
+ k = ( k + 1 ) % channels_avail;
+ }
+ }
+ }
+ else if ( *format == mlt_audio_u8 )
+ {
+ uint8_t *p = (uint8_t*) new_buffer;
+ int i, j, k = 0;
+ for ( i = 0; i < *samples; i++ )
+ {
+ for ( j = 0; j < *channels; j++ )
+ {
+ p[ ( i * *channels ) + j ] = ((uint8_t*)(*buffer))[ ( i * channels_avail ) + k ];
k = ( k + 1 ) % channels_avail;
}
}
}
else
{
- // non-interleaved
+ // non-interleaved - s32 or float
int size_avail = mlt_audio_format_size( *format, *samples, channels_avail );
int32_t *p = (int32_t*) new_buffer;
int i = *channels / channels_avail;
/*
* filter_audioconvert.c -- convert from one audio format to another
- * Copyright (C) 2009 Ushodaya Enterprises Limited
+ * Copyright (C) 2009-2012 Ushodaya Enterprises Limited
* Author: Dan Dennedy <dan@dennedy.org>
*
* This library is free software; you can redistribute it and/or
error = 0;
break;
}
+ case mlt_audio_s32le:
+ {
+ int32_t *buffer = mlt_pool_alloc( size );
+ int32_t *p = buffer;
+ int16_t *q = (int16_t*) *audio;
+ int i = samples * channels + 1;
+ while ( --i )
+ *p++ = (int32_t) *q++ << 16;
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_f32le:
+ {
+ float *buffer = mlt_pool_alloc( size );
+ float *p = buffer;
+ int16_t *q = (int16_t*) *audio;
+ int i = samples * channels + 1;
+ while ( --i )
+ {
+ float f = (float)( *q++ ) / 32768.0;
+ f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
+ *p++ = f;
+ }
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_u8:
+ {
+ uint8_t *buffer = mlt_pool_alloc( size );
+ uint8_t *p = buffer;
+ int16_t *q = (int16_t*) *audio;
+ int i = samples * channels + 1;
+ while ( --i )
+ *p++ = ( *q++ >> 8 ) + 128;
+ *audio = buffer;
+ error = 0;
+ break;
+ }
default:
break;
}
error = 0;
break;
}
+ case mlt_audio_s32le:
+ {
+ int32_t *buffer = mlt_pool_alloc( size );
+ int32_t *p = buffer;
+ int32_t *q = (int32_t*) *audio;
+ int s, c;
+ for ( s = 0; s < samples; s++ )
+ for ( c = 0; c < channels; c++ )
+ *p++ = *( q + c * samples + s );
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_f32le:
+ {
+ float *buffer = mlt_pool_alloc( size );
+ float *p = buffer;
+ int32_t *q = (int32_t*) *audio;
+ int s, c;
+ for ( s = 0; s < samples; s++ )
+ for ( c = 0; c < channels; c++ )
+ {
+ float f = (float)( *( q + c * samples + s ) ) / 2147483648.0;
+ f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
+ *p++ = f;
+ }
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_u8:
+ {
+ uint8_t *buffer = mlt_pool_alloc( size );
+ uint8_t *p = buffer;
+ int32_t *q = (int32_t*) *audio;
+ int s, c;
+ for ( s = 0; s < samples; s++ )
+ for ( c = 0; c < channels; c++ )
+ *p++ = ( q[c * samples + s] >> 24 ) + 128;
+ *audio = buffer;
+ error = 0;
+ break;
+ }
default:
break;
}
error = 0;
break;
}
+ case mlt_audio_s32le:
+ {
+ int32_t *buffer = mlt_pool_alloc( size );
+ int32_t *p = buffer;
+ float *q = (float*) *audio;
+ int s, c;
+ for ( s = 0; s < samples; s++ )
+ for ( c = 0; c < channels; c++ )
+ {
+ float f = *( q + c * samples + s );
+ f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
+ *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
+ }
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_f32le:
+ {
+ float *buffer = mlt_pool_alloc( size );
+ float *p = buffer;
+ float *q = (float*) *audio;
+ int s, c;
+ for ( s = 0; s < samples; s++ )
+ for ( c = 0; c < channels; c++ )
+ *p++ = *( q + c * samples + s );
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_u8:
+ {
+ uint8_t *buffer = mlt_pool_alloc( size );
+ uint8_t *p = buffer;
+ float *q = (float*) *audio;
+ int s, c;
+ for ( s = 0; s < samples; s++ )
+ for ( c = 0; c < channels; c++ )
+ {
+ float f = *( q + c * samples + s );
+ f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
+ *p++ = ( 127 * f ) + 128;
+ }
+ *audio = buffer;
+ error = 0;
+ break;
+ }
default:
break;
}
error = 0;
break;
}
+ case mlt_audio_f32le:
+ {
+ float *buffer = mlt_pool_alloc( size );
+ float *p = buffer;
+ int32_t *q = (int32_t*) *audio;
+ int i = samples * channels + 1;
+ while ( --i )
+ *p++ = (float)( *q++ ) / 2147483648.0;
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_u8:
+ {
+ uint8_t *buffer = mlt_pool_alloc( size );
+ uint8_t *p = buffer;
+ int32_t *q = (int32_t*) *audio;
+ int i = samples * channels + 1;
+ while ( --i )
+ *p++ = ( *q++ >> 24 ) + 128;
+ *audio = buffer;
+ error = 0;
+ break;
+ }
default:
break;
}
error = 0;
break;
}
+ case mlt_audio_s32le:
+ {
+ int32_t *buffer = mlt_pool_alloc( size );
+ int32_t *p = buffer;
+ float *q = (float*) *audio;
+ int i = samples * channels + 1;
+ while ( --i )
+ {
+ float f = *q++;
+ f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
+ *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
+ }
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_u8:
+ {
+ uint8_t *buffer = mlt_pool_alloc( size );
+ uint8_t *p = buffer;
+ float *q = (float*) *audio;
+ int i = samples * channels + 1;
+ while ( --i )
+ {
+ float f = *q++;
+ f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
+ *p++ = ( 127 * f ) + 128;
+ }
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ case mlt_audio_u8:
+ switch ( requested_format )
+ {
+ case mlt_audio_s32:
+ {
+ int32_t *buffer = mlt_pool_alloc( size );
+ int32_t *p = buffer;
+ int c;
+ for ( c = 0; c < channels; c++ )
+ {
+ uint8_t *q = (uint8_t*) *audio + c;
+ int i = samples + 1;
+ while ( --i )
+ {
+ *p++ = ( (int32_t) *q - 128 ) << 24;
+ q += channels;
+ }
+ }
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_float:
+ {
+ float *buffer = mlt_pool_alloc( size );
+ float *p = buffer;
+ int c;
+ for ( c = 0; c < channels; c++ )
+ {
+ uint8_t *q = (uint8_t*) *audio + c;
+ int i = samples + 1;
+ while ( --i )
+ {
+ *p++ = ( (float) *q - 128 ) / 256.0f;
+ q += channels;
+ }
+ }
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_s16:
+ {
+ int16_t *buffer = mlt_pool_alloc( size );
+ int16_t *p = buffer;
+ uint8_t *q = (uint8_t*) *audio;
+ int i = samples * channels + 1;
+ while ( --i )
+ *p++ = ( (int16_t) *q++ - 128 ) << 8;
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_s32le:
+ {
+ int32_t *buffer = mlt_pool_alloc( size );
+ int32_t *p = buffer;
+ uint8_t *q = (uint8_t*) *audio;
+ int i = samples * channels + 1;
+ while ( --i )
+ *p++ = ( (int32_t) *q++ - 128 ) << 24;
+ *audio = buffer;
+ error = 0;
+ break;
+ }
+ case mlt_audio_f32le:
+ {
+ float *buffer = mlt_pool_alloc( size );
+ float *p = buffer;
+ uint8_t *q = (uint8_t*) *audio;
+ int i = samples * channels + 1;
+ while ( --i )
+ {
+ float f = ( (float) *q++ - 128 ) / 256.0f;
+ f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
+ *p++ = f;
+ }
+ *audio = buffer;
+ error = 0;
+ break;
+ }
default:
break;
}
mlt_filter filter_audioconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
- mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 );
+ mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) );
if ( mlt_filter_init( this, this ) == 0 )
this->process = filter_process;
return this;
/*
* filter_channelcopy.c -- copy one audio channel to another
- * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Copyright (C) 2003-2012 Ushodaya Enterprises Limited
* Author: Dan Dennedy <dan@dennedy.org>
*
* This library is free software; you can redistribute it and/or
if ( from != to)
switch ( *format )
{
+ case mlt_audio_u8:
+ {
+ uint8_t *f = (uint8_t*) *buffer + from;
+ uint8_t *t = (uint8_t*) *buffer + to;
+ uint8_t x;
+ int i;
+
+ if ( swap )
+ for ( i = 0; i < *samples; i++, f += *channels, t += *channels )
+ {
+ x = *t;
+ *t = *f;
+ *f = x;
+ }
+ else
+ for ( i = 0; i < *samples; i++, f += *channels, t += *channels )
+ *t = *f;
+ break;
+ }
case mlt_audio_s16:
{
int16_t *f = (int16_t*) *buffer + from;
}
break;
}
+ case mlt_audio_s32le:
+ case mlt_audio_f32le:
+ {
+ int32_t *f = (int32_t*) *buffer + from;
+ int32_t *t = (int32_t*) *buffer + to;
+ int32_t x;
+ int i;
+
+ if ( swap )
+ for ( i = 0; i < *samples; i++, f += *channels, t += *channels )
+ {
+ x = *t;
+ *t = *f;
+ *f = x;
+ }
+ else
+ for ( i = 0; i < *samples; i++, f += *channels, t += *channels )
+ *t = *f;
+ break;
+ }
case mlt_audio_float:
{
float *f = (float*) *buffer + from * *samples;
/** Do it :-).
*/
-static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
int error = 0;
+ mlt_profile profile = mlt_frame_pop_service( frame );
// Get the properties from the frame
- mlt_properties properties = MLT_FRAME_PROPERTIES( this );
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
// 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" );
+ *width = profile->width;
+ *height = profile->height;
}
int left = mlt_properties_get_int( properties, "crop.left" );
}
// Now get the image
- error = mlt_frame_get_image( this, image, format, width, height, writable );
+ error = mlt_frame_get_image( frame, image, format, width, height, writable );
int owidth = *width - left - right;
int oheight = *height - top - bottom;
int bpp;
// Subsampled YUV is messy and less precise.
- if ( *format == mlt_image_yuv422 && this->convert_image )
+ if ( *format == mlt_image_yuv422 && frame->convert_image )
{
mlt_image_format requested_format = mlt_image_rgb24;
- this->convert_image( this, image, format, requested_format );
+ frame->convert_image( frame, image, format, requested_format );
}
mlt_log_debug( NULL, "[filter crop] %s %dx%d -> %dx%d\n", mlt_image_format_name(*format),
*width, *height, owidth, oheight);
- // 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" ) );
crop( *image, output, bpp, *width, *height, left, right, top, bottom );
// Now update the frame
- mlt_frame_set_image( this, output, size, mlt_pool_release );
+ mlt_frame_set_image( frame, output, size, mlt_pool_release );
*image = output;
}
// We should resize the alpha too
- uint8_t *alpha = mlt_frame_get_alpha_mask( this );
+ uint8_t *alpha = mlt_frame_get_alpha_mask( frame );
int alpha_size = 0;
mlt_properties_get_data( properties, "alpha", &alpha_size );
if ( alpha && alpha_size >= ( *width * *height ) )
if ( newalpha )
{
crop( alpha, newalpha, 1, *width, *height, left, right, top, bottom );
- mlt_frame_set_alpha( this, newalpha, owidth * oheight, mlt_pool_release );
- this->get_alpha_mask = NULL;
+ mlt_frame_set_alpha( frame, newalpha, owidth * oheight, mlt_pool_release );
}
}
*width = owidth;
/** Filter processing.
*/
-static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
{
- if ( mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "active" ) )
+ if ( mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "active" ) )
{
// Push the get_image method on to the stack
+ mlt_frame_push_service( frame, mlt_service_profile( MLT_FILTER_SERVICE( filter ) ) );
mlt_frame_push_get_image( frame, filter_get_image );
}
else
{
- mlt_properties filter_props = MLT_FILTER_PROPERTIES( this );
+ mlt_properties filter_props = MLT_FILTER_PROPERTIES( filter );
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" );
+ int width = mlt_properties_get_int( frame_props, "meta.media.width" );
+ int height = mlt_properties_get_int( frame_props, "meta.media.height" );
int use_profile = mlt_properties_get_int( filter_props, "use_profile" );
- mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) );
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
if ( use_profile )
{
{
double aspect_ratio = mlt_frame_get_aspect_ratio( frame );
if ( aspect_ratio == 0.0 )
- aspect_ratio = mlt_properties_get_double( frame_props, "consumer_aspect_ratio" );
+ aspect_ratio = mlt_profile_sar( profile );
double input_ar = aspect_ratio * width / height;
- double output_ar = mlt_profile_dar( mlt_service_profile( MLT_FILTER_SERVICE(this) ) );
+ double output_ar = mlt_profile_dar( mlt_service_profile( MLT_FILTER_SERVICE(filter) ) );
int bias = mlt_properties_get_int( filter_props, "center_bias" );
if ( input_ar > output_ar )
mlt_properties_set_int( frame_props, "crop.bottom", bottom );
mlt_properties_set_int( frame_props, "crop.original_width", width );
mlt_properties_set_int( frame_props, "crop.original_height", height );
- mlt_properties_set_int( frame_props, "real_width", width - left - right );
- mlt_properties_set_int( frame_props, "real_height", height - top - bottom );
+ mlt_properties_set_int( frame_props, "meta.media.width", width - left - right );
+ mlt_properties_set_int( frame_props, "meta.media.height", height - top - bottom );
}
return frame;
}
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 )
+ mlt_filter filter = calloc( 1, sizeof( struct mlt_filter_s ) );
+ if ( mlt_filter_init( filter, filter ) == 0 )
{
- this->process = filter_process;
+ filter->process = filter_process;
if ( arg )
- mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "active", atoi( arg ) );
+ mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "active", atoi( arg ) );
}
- return this;
+ return filter;
}
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 );
+ {
+ strncpy( temp, profile, sizeof( temp ) );
+ temp[ sizeof( temp ) - 1 ] = '\0';
+ }
// Load the specified profile or use the default
profile_properties = mlt_properties_load( temp );
// 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 );
+ strncat( result, tc, sizeof( result ) - strlen( result ) - 1 );
free( tc );
}
else if ( !strcmp( keywords, "frame" ) )
int pos = mlt_properties_get_int( feed, "position" );
char s[12];
snprintf( s, sizeof(s) - 1, "%d", pos );
+ s[sizeof( s ) - 1] = '\0';
strcat( result, s );
}
else
{
// replace keyword with metadata value
char *metavalue = metadata_value( MLT_FRAME_PROPERTIES( frame ), keywords );
- strcat( result, metavalue ? metavalue : "-" );
+ strncat( result, metavalue ? metavalue : "-", sizeof( result ) - strlen( result ) -1 );
}
keywords = strtok( NULL, "#" );
ct++;
mlt_properties_get_int( properties, "progressive" ) == 0 )
{
// We only work with non-planar formats
- if ( *format == mlt_image_yuv420p )
- {
- *format = mlt_image_yuv422;
- mlt_frame_get_image( frame, image, format, width, height, writable );
- }
+ if ( *format == mlt_image_yuv420p && frame->convert_image )
+ error = frame->convert_image( frame, image, format, mlt_image_yuv422 );
// Make a new image
int bpp;
}
// Correct field order if needed
- if ( mlt_properties_get_int( properties, "top_field_first" ) != tff &&
+ if ( tff != -1 &&
+ mlt_properties_get_int( properties, "top_field_first" ) != tff &&
mlt_properties_get( properties, "progressive" ) &&
mlt_properties_get_int( properties, "progressive" ) == 0 )
{
? mlt_pool_alloc( width * height ) : NULL;
if ( requested_format == mlt_image_rgb24a || requested_format == mlt_image_opengl )
{
+ if ( alpha )
+ mlt_pool_release( alpha );
alpha = mlt_frame_get_alpha_mask( frame );
mlt_properties_get_data( properties, "alpha", &alpha_size );
}
static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
{
- frame->convert_image = convert_image;
+ if ( !frame->convert_image )
+ frame->convert_image = convert_image;
return frame;
}
mlt_filter filter_imageconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
- mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 );
+ mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) );
if ( mlt_filter_init( this, this ) == 0 )
{
this->process = filter_process;
/*
* filter_mono.c -- mix all channels to a mono signal across n channels
- * Copyright (C) 2003-2009 Ushodaya Enterprises Limited
+ * Copyright (C) 2003-2012 Ushodaya Enterprises Limited
* Author: Dan Dennedy <dan@dennedy.org>
*
* This library is free software; you can redistribute it and/or
switch ( *format )
{
+ case mlt_audio_u8:
+ {
+ uint8_t *new_buffer = mlt_pool_alloc( size );
+ for ( i = 0; i < *samples; i++ )
+ {
+ uint8_t mixdown = 0;
+ for ( j = 0; j < *channels; j++ )
+ mixdown += ((uint8_t*) *buffer)[ ( i * *channels ) + j ] / *channels;
+ for ( j = 0; j < channels_out; j++ )
+ new_buffer[ ( i * channels_out ) + j ] = mixdown;
+ }
+ *buffer = new_buffer;
+ break;
+ }
case mlt_audio_s16:
{
int16_t *new_buffer = mlt_pool_alloc( size );
*buffer = new_buffer;
break;
}
+ case mlt_audio_s32le:
+ {
+ int32_t *new_buffer = mlt_pool_alloc( size );
+ for ( i = 0; i < *samples; i++ )
+ {
+ int32_t mixdown = 0;
+ for ( j = 0; j < *channels; j++ )
+ mixdown += ((int32_t*) *buffer)[ ( i * *channels ) + j ] / *channels;
+ for ( j = 0; j < channels_out; j++ )
+ new_buffer[ ( i * channels_out ) + j ] = mixdown;
+ }
+ *buffer = new_buffer;
+ break;
+ }
+ case mlt_audio_f32le:
+ {
+ float *new_buffer = mlt_pool_alloc( size );
+ for ( i = 0; i < *samples; i++ )
+ {
+ float mixdown = 0;
+ for ( j = 0; j < *channels; j++ )
+ mixdown += ((float*) *buffer)[ ( i * *channels ) + j ] / *channels;
+ for ( j = 0; j < channels_out; j++ )
+ new_buffer[ ( i * channels_out ) + j ] = mixdown;
+ }
+ *buffer = new_buffer;
+ break;
+ }
case mlt_audio_s32:
{
int32_t *new_buffer = mlt_pool_alloc( size );
#include <framework/mlt_filter.h>
#include <framework/mlt_frame.h>
+#include <framework/mlt_profile.h>
#include <stdio.h>
#include <stdlib.h>
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 );
+ mlt_filter filter = mlt_frame_pop_service( frame );
// Get the image from the frame
*format = mlt_image_yuv422;
// Get the image from the frame
if ( error == 0 )
{
- if ( this != NULL )
+ if ( filter != 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" );
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
// Structures for geometry
struct geometry_s result;
struct geometry_s end;
// Retrieve the position
- float position = mlt_filter_get_progress( this, frame );
+ float position = mlt_filter_get_progress( filter, frame );
// 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 );
+ geometry_parse( &start, NULL, mlt_properties_get( properties, "start" ), profile->width, profile->height );
+ geometry_parse( &end, &start, mlt_properties_get( properties, "end" ), profile->width, profile->height );
// Do the calculation
geometry_calculate( &result, &start, &end, position, *width, *height );
/** Filter processing.
*/
-static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
{
// Push this on to the service stack
- mlt_frame_push_service( frame, this );
+ mlt_frame_push_service( frame, filter );
// Push the get image call
mlt_frame_push_get_image( frame, filter_get_image );
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_filter filter = mlt_filter_new( );
+ if ( filter != NULL )
{
- mlt_properties properties = MLT_FILTER_PROPERTIES( this );
- this->process = filter_process;
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ filter->process = filter_process;
mlt_properties_set( properties, "start", arg != NULL ? arg : "0%/0%:100%x100%" );
mlt_properties_set( properties, "end", "" );
}
- return this;
+ return filter;
}
mlt_filter filter_panner_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
- mlt_filter filter = calloc( sizeof( struct mlt_filter_s ), 1 );
+ mlt_filter filter = calloc( 1, sizeof( struct mlt_filter_s ) );
if ( filter != NULL && mlt_filter_init( filter, NULL ) == 0 )
{
filter->process = filter_process;
/** Filter processing.
*/
-static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+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 properties of the filter
- mlt_properties properties = MLT_FILTER_PROPERTIES( this );
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+
+ mlt_service_lock( MLT_FILTER_SERVICE( filter ) );
// Get the region transition
mlt_transition transition = mlt_properties_get_data( properties, "_transition", NULL );
if ( transition == NULL )
{
// Create the transition
- mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) );
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
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 );
+ mlt_properties_set_data( MLT_TRANSITION_PROPERTIES( transition ), "_region_filter", filter, 0, NULL, NULL );
}
+ mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
+
// Pass all properties down
- mlt_properties_pass( MLT_TRANSITION_PROPERTIES( transition ), properties, "" );
+ mlt_properties_inherit( MLT_TRANSITION_PROPERTIES( transition ), properties );
+
+ // Make the frame's position relative to this filter's in point
+ mlt_frame_set_position( frame, mlt_filter_get_position( filter, frame ) );
// Process the frame
- return mlt_transition_process( transition, frame, NULL );
+ mlt_transition_process( transition, frame, NULL );
+
+ return mlt_frame_get_image( frame, image, format, width, height, writable );
+}
+
+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.
// Return the filter
return this;
}
-
#include <framework/mlt_filter.h>
#include <framework/mlt_frame.h>
#include <framework/mlt_log.h>
+#include <framework/mlt_profile.h>
#include <stdio.h>
#include <string.h>
* rgb24a -> yuv422
*/
-typedef int ( *image_scaler )( mlt_frame this, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight );
+typedef int ( *image_scaler )( mlt_frame frame, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight );
-static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight )
+static int filter_scale( mlt_frame frame, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight )
{
// Create the output image
uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 );
}
// Now update the frame
- mlt_frame_set_image( this, output, owidth * ( oheight + 1 ) * 2, mlt_pool_release );
+ mlt_frame_set_image( frame, output, owidth * ( oheight + 1 ) * 2, mlt_pool_release );
*image = output;
return 0;
}
-static void scale_alpha( mlt_frame this, int iwidth, int iheight, int owidth, int oheight )
+static void scale_alpha( mlt_frame frame, int iwidth, int iheight, int owidth, int oheight )
{
// Scale the alpha
uint8_t *output = NULL;
- uint8_t *input = mlt_frame_get_alpha_mask( this );
+ uint8_t *input = mlt_frame_get_alpha_mask( frame );
if ( input != NULL )
{
}
// Set it back on the frame
- mlt_frame_set_alpha( this, output, owidth * oheight, mlt_pool_release );
+ mlt_frame_set_alpha( frame, output, owidth * oheight, mlt_pool_release );
}
}
/** Do it :-).
*/
-static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
int error = 0;
// Get the frame properties
- mlt_properties properties = MLT_FRAME_PROPERTIES( this );
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
// Get the filter from the stack
- mlt_filter filter = mlt_frame_pop_service( this );
+ mlt_filter filter = mlt_frame_pop_service( frame );
// Get the filter properties
mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter );
// 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" );
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
+ *width = profile->width;
+ *height = profile->height;
}
// There can be problems with small images - avoid them (by hacking - gah)
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" ) )
+ // If meta.media.width/height exist, we want that as minimum information
+ if ( mlt_properties_get_int( properties, "meta.media.width" ) )
{
- iwidth = mlt_properties_get_int( properties, "real_width" );
- iheight = mlt_properties_get_int( properties, "real_height" );
+ iwidth = mlt_properties_get_int( properties, "meta.media.width" );
+ iheight = mlt_properties_get_int( properties, "meta.media.height" );
}
// Let the producer know what we are actually requested to obtain
*format = mlt_image_yuv422;
// Get the image as requested
- mlt_frame_get_image( this, image, format, &iwidth, &iheight, writable );
+ mlt_frame_get_image( frame, image, format, &iwidth, &iheight, writable );
// Get rescale interpretation again, in case the producer wishes to override scaling
interps = mlt_properties_get( properties, "rescale.interp" );
*format == mlt_image_rgb24a || *format == mlt_image_opengl )
{
// Call the virtual function
- scaler_method( this, image, format, iwidth, iheight, owidth, oheight );
+ scaler_method( frame, image, format, iwidth, iheight, owidth, oheight );
*width = owidth;
*height = oheight;
}
int alpha_size = 0;
mlt_properties_get_data( properties, "alpha", &alpha_size );
if ( alpha_size > 0 && alpha_size != ( owidth * oheight ) && alpha_size != ( owidth * ( oheight + 1 ) ) )
- scale_alpha( this, iwidth, iheight, owidth, oheight );
+ scale_alpha( frame, iwidth, iheight, owidth, oheight );
}
else
{
/** Filter processing.
*/
-static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
{
// Push the filter
- mlt_frame_push_service( frame, this );
+ mlt_frame_push_service( frame, filter );
// Push the get image method
mlt_frame_push_service( frame, filter_get_image );
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( );
+ mlt_filter filter = mlt_filter_new( );
// If successful, then initialise it
- if ( this != NULL )
+ if ( filter != NULL )
{
// Get the properties
- mlt_properties properties = MLT_FILTER_PROPERTIES( this );
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
// Set the process method
- this->process = filter_process;
+ filter->process = filter_process;
// Set the inerpolation
mlt_properties_set( properties, "interpolation", arg == NULL ? "bilinear" : arg );
mlt_properties_set_data( properties, "method", filter_scale, 0, NULL, NULL );
}
- return this;
+ return filter;
}
resizes.
*/
-static uint8_t *frame_resize_image( mlt_frame this, int owidth, int oheight, int bpp )
+static uint8_t *frame_resize_image( mlt_frame frame, int owidth, int oheight, int bpp )
{
// Get properties
- mlt_properties properties = MLT_FRAME_PROPERTIES( this );
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
// 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 );
+ uint8_t *alpha = mlt_frame_get_alpha_mask( frame );
int alpha_size = 0;
mlt_properties_get_data( properties, "alpha", &alpha_size );
resize_image( output, owidth, oheight, input, iwidth, iheight, bpp );
// Now update the frame
- mlt_frame_set_image( this, output, owidth * ( oheight + 1 ) * bpp, mlt_pool_release );
+ mlt_frame_set_image( frame, output, owidth * ( oheight + 1 ) * bpp, mlt_pool_release );
// We should resize the alpha too
if ( alpha && alpha_size >= iwidth * iheight )
{
alpha = resize_alpha( alpha, owidth, oheight, iwidth, iheight, alpha_value );
if ( alpha )
- {
- mlt_frame_set_alpha( this, alpha, owidth * oheight, mlt_pool_release );
- this->get_alpha_mask = NULL;
- }
+ mlt_frame_set_alpha( frame, alpha, owidth * oheight, mlt_pool_release );
}
// Return the output
/** Do it :-).
*/
-static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+static int filter_get_image( mlt_frame frame, 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 );
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
// Pop the top of stack now
- mlt_filter filter = mlt_frame_pop_service( this );
+ mlt_filter filter = mlt_frame_pop_service( frame );
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
// Retrieve the aspect ratio
- double aspect_ratio = mlt_deque_pop_back_double( MLT_FRAME_IMAGE_STACK( this ) );
+ double aspect_ratio = mlt_deque_pop_back_double( MLT_FRAME_IMAGE_STACK( frame ) );
double consumer_aspect = mlt_profile_sar( mlt_service_profile( MLT_FILTER_SERVICE( filter ) ) );
// 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" );
+ *width = profile->width;
+ *height = profile->height;
}
// Assign requested width/height from our subordinate
// Reset the aspect ratio
mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio );
+ // XXX: This is a hack, but it forces the force_full_luma to apply by doing a RGB
+ // conversion because range scaling only occurs on YUV->RGB. And we do it here,
+ // after the deinterlace filter, which only operates in YUV to avoid a YUV->RGB->YUV->?.
+ // Instead, it will go YUV->RGB->?.
+ if ( mlt_properties_get_int( properties, "force_full_luma" ) )
+ *format = mlt_image_rgb24a;
+
// 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 );
+ return mlt_frame_get_image( frame, 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" );
+ int normalised_width = profile->width;
+ int normalised_height = profile->height;
+ int real_width = mlt_properties_get_int( properties, "meta.media.width" );
+ int real_height = mlt_properties_get_int( properties, "meta.media.height" );
if ( real_width == 0 )
real_width = mlt_properties_get_int( properties, "width" );
if ( real_height == 0 )
oheight = rint( scaled_height * oheight / normalised_height );
// Tell frame we have conformed the aspect to the consumer
- mlt_frame_set_aspect_ratio( this, consumer_aspect );
+ mlt_frame_set_aspect_ratio( frame, consumer_aspect );
}
mlt_properties_set_int( properties, "distort", 0 );
// Now get the image
if ( *format == mlt_image_yuv422 )
owidth -= owidth % 2;
- error = mlt_frame_get_image( this, image, format, &owidth, &oheight, writable );
+ error = mlt_frame_get_image( frame, image, format, &owidth, &oheight, writable );
if ( error == 0 && *image )
{
int bpp;
mlt_image_format_size( *format, owidth, oheight, &bpp );
- *image = frame_resize_image( this, *width, *height, bpp );
+ *image = frame_resize_image( frame, *width, *height, bpp );
}
return error;
/** Filter processing.
*/
-static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+static mlt_frame filter_process( mlt_filter filter, 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 );
+ mlt_frame_push_service( frame, filter );
// Push the get_image method on to the stack
mlt_frame_push_get_image( frame, filter_get_image );
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 )
+ mlt_filter filter = calloc( 1, sizeof( struct mlt_filter_s ) );
+ if ( mlt_filter_init( filter, filter ) == 0 )
{
- this->process = filter_process;
+ filter->process = filter_process;
}
- return this;
+ return filter;
}
// Get the a and b frame properties
mlt_properties a_props = MLT_FRAME_PROPERTIES( frame );
mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame );
+ mlt_profile profile = mlt_service_profile( service );
// 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" ) );
+ mlt_frame_set_aspect_ratio( b_frame, mlt_profile_sar( profile ) );
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" ) );
+ mlt_frame_set_aspect_ratio( frame, mlt_profile_sar( profile ) );
if ( mlt_properties_get_int( properties, "distort" ) )
{
-http://*=avformat
+http://*=avformat,webvfx:plain:
+https://*=webvfx:plain:
+plain:http://*=webvfx:plain:
+plain:https://*=webvfx:plain:
<?xml*=xml-string
*.mlt=xml
*.westley=xml
*.inigo=melt_file
*.asf=avformat
*.avi=mcdv,avformat,libdv
-*.bmp=pixbuf,qimage,sdl_image
+*.bmp=pixbuf,qimage
*.dv=mcdv,avformat,libdv
*.dif=mcdv,avformat,libdv
*.exr=qimage
-*.gif=pixbuf,qimage,sdl_image
+*.gif=pixbuf,qimage
*.graphics=xml
+*.htm=webvfx:plain:
+*.html=webvfx:plain:
*.jfx=xml
*.jef=xml
-*.jpg=pixbuf,qimage,sdl_image
-*.jpeg=pixbuf,qimage,sdl_image
+*.jpg=pixbuf,qimage
+*.jpeg=pixbuf,qimage
+*.kdenlivetitle=kdenlivetitle
*.kino=xml
*.mp3=avformat
*.mov=mcdv,avformat,libdv
*.mpeg=mcmpeg,avformat
*.mpl=pango
*.ogg=avformat,vorbis
-*.pcx=pixbuf,qimage,sdl_image
-*.pgm=pgm,pixbuf,qimage,sdl_image
-*.png=pixbuf,qimage,sdl_image
+*.pcx=pixbuf,qimage
+*.pgm=pgm,pixbuf,qimage
+*.png=pixbuf,qimage
*.psd=qimage
+*.qml=webvfx:plain:
*.story=xml
*.svg=pixbuf,qimage
-*.swf=swfdec,avformat
-*.tga=pixbuf,qimage,sdl_image
-*.tif=pixbuf,qimage,sdl_image
-*.tiff=pixbuf,qimage,sdl_image
+*.swf=avformat,swfdec
+*.tga=pixbuf,qimage
+*.tif=pixbuf,qimage
+*.tiff=pixbuf,qimage
*.txt=pango
*.vob=mcmpeg,avformat
*.wav=avformat
*.wmv=avformat
-*.xcf=qimage,sdl_image
+*.xcf=qimage
*.xml=xml
-*.kdenlivetitle=kdenlivetitle
*=avformat
# the second and third are applied as applicable).
# image filters
-crop=crop:1
deinterlace=deinterlace,avdeinterlace
-rescaler=swscale,gtkrescale,rescale
fieldorder=fieldorder
-resizer=resize
+crop=movit.crop,crop:1
+rescaler=movit.resample,swscale,gtkrescale,rescale
+resizer=movit.resize,resize
# audio filters
channels=audiochannels
producer->close = ( mlt_destructor )producer_close;
// Set the default properties
- mlt_properties_set( properties, "resource", colour == NULL ? "0x000000ff" : colour );
+ mlt_properties_set( properties, "resource", ( !colour || !strcmp( colour, "" ) ) ? "0x000000ff" : colour );
mlt_properties_set( properties, "_resource", "" );
mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );
result.g = 0x00;
result.b = 0xff;
}
+ else if ( !strcmp( color, "black" ) )
+ {
+ result.r = 0x00;
+ result.g = 0x00;
+ result.b = 0x00;
+ }
else if ( strcmp( color, "white" ) )
{
result.r = ( color_int >> 24 ) & 0xff;
mlt_frame_set_image( frame, *buffer, size, mlt_pool_release );
mlt_frame_set_alpha( frame, alpha, alpha_size, mlt_pool_release );
mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) );
- mlt_properties_set_int( properties, "real_width", *width );
- mlt_properties_set_int( properties, "real_height", *height );
+ mlt_properties_set_int( properties, "meta.media.width", *width );
+ mlt_properties_set_int( properties, "meta.media.height", *height );
return 0;
// 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_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );
// colour is an alias for resource
if ( mlt_properties_get( producer_props, "colour" ) != NULL )
mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
memcpy( new_buffer, *buffer, size );
*buffer = new_buffer;
+ cx->audio_position = mlt_frame_get_position( nested_frame );
}
else
{
// otherwise return no samples
*samples = 0;
+ *buffer = NULL;
}
- cx->audio_position = mlt_frame_get_position( nested_frame );
return result;
}
// Since we control the seeking, prevent it from seeking on its own
mlt_producer_set_speed( cx->producer, 0 );
+ cx->audio_position = -1;
// We will encapsulate a consumer
cx->consumer = mlt_consumer_new( cx->profile );
// Generate a frame
*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( this ) );
- if ( frame )
+ if ( *frame )
{
// Seek the producer to the correct place
// Calculate our positions
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, "meta.media.width", cx->profile->width );
+ mlt_properties_set_int( frame_props, "meta.media.height", cx->profile->height );
mlt_properties_set_int( frame_props, "progressive", cx->profile->progressive );
}
char *p = strchr( service, ',' );
if ( p != NULL )
*p ++ = '\0';
- producer = mlt_factory_producer( profile, service, file );
+
+ // If the service name has a colon as field delimiter, then treat the
+ // second field as a prefix for the file/url.
+ char *prefix = strchr( service, ':' );
+ if ( prefix )
+ {
+ *prefix ++ = '\0';
+ char* prefix_file = calloc( 1, strlen( file ) + strlen( prefix ) + 1 );
+ strcpy( prefix_file, prefix );
+ strcat( prefix_file, file );
+ producer = mlt_factory_producer( profile, service, prefix_file );
+ free( prefix_file );
+ }
+ else
+ {
+ producer = mlt_factory_producer( profile, service, file );
+ }
service = p;
}
while ( producer == NULL && service != NULL );
p ++;
}
+ // Chop off the query string
+ p = strrchr( lookup, '?' );
+ if ( p )
+ p[0] = '\0';
+
+ // Strip file:// prefix
+ p = lookup;
+ if ( strncmp( lookup, "file://", 7 ) == 0 )
+ p += 7;
+
// 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 )
+ if ( fnmatch( name, p, 0 ) == 0 )
result = create_from( profile, file, mlt_properties_get_value( dictionary, i ) );
}
// The swscale and avcolor_space filters require resolution as arg to test compatibility
if ( strncmp( effect, "swscale", 7 ) == 0 || strncmp( effect, "avcolo", 6 ) == 0 )
- arg = (char*) mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( producer ), "_real_width" );
+ arg = (char*) mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( producer ), "meta.media.width" );
mlt_filter filter = mlt_factory_filter( profile, id, arg );
if ( filter != NULL )
// Attach filters if we have a producer and it isn't already xml'd :-)
if ( producer && strcmp( id, "abnormal" ) &&
+ strncmp( arg, "abnormal:", 9 ) &&
mlt_properties_get( properties, "xml" ) == NULL &&
mlt_properties_get( properties, "_xml" ) == NULL &&
mlt_properties_get( properties, "loader_normalised" ) == NULL )
{
// Always let the image and audio be converted
int created = 0;
+ // movit.convert skips setting the frame->convert_image pointer if GLSL cannot be used.
+ create_filter( profile, producer, "movit.convert", &created );
+ // avcolor_space and imageconvert only set frame->convert_image if it has not been set.
create_filter( profile, producer, "avcolor_space", &created );
if ( !created )
create_filter( profile, producer, "imageconvert", &created );
if ( strcmp( temp, "" ) )
args[ count ++ ] = strdup( temp );
}
+ fclose( input );
}
mlt_producer result = producer_melt_init( profile, type, id, args );
int track = 0;
mlt_producer producer = NULL;
mlt_tractor mix = NULL;
- mlt_playlist playlist = mlt_playlist_init( );
+ mlt_playlist playlist = mlt_playlist_new( profile );
mlt_properties group = mlt_properties_new( );
mlt_tractor tractor = mlt_tractor_new( );
mlt_properties properties = MLT_TRACTOR_PROPERTIES( tractor );
if ( producer != NULL && !mlt_producer_is_cut( producer ) )
mlt_playlist_append( playlist, producer );
producer = NULL;
- mlt_playlist_blank( playlist, atof( argv[ ++ i ] ) );
+ if ( strchr( argv[ i + 1 ], ':' ) )
+ mlt_playlist_blank_time( playlist, argv[ ++ i ] );
+ else
+ // support for legacy where plain int is an out point instead of length
+ mlt_playlist_blank( playlist, atof( argv[ ++ i ] ) );
}
else if ( !strcmp( argv[ i ], "-track" ) ||
!strcmp( argv[ i ], "-null-track" ) ||
{
mlt_multitrack_connect( multitrack, MLT_PLAYLIST_PRODUCER( playlist ), track ++ );
track_service( field, playlist, ( mlt_destructor )mlt_playlist_close );
- playlist = mlt_playlist_init( );
+ playlist = mlt_playlist_new( profile );
}
if ( playlist != NULL )
{
backtrack = 1;
}
- while ( argv[ i ] != NULL && strchr( argv[ i ], '=' ) )
+ while ( argv[ i ] != NULL && strchr( argv[ i ], '=' ) &&
+ ( !strchr( argv[ i ], ':' ) || strchr( argv[ i ], ':' ) > strchr( argv[ i ], '=' ) ) )
{
i ++;
backtrack = 1;
track_service( field, playlist, ( mlt_destructor )mlt_playlist_close );
// We must have a playlist to connect
- if ( !mlt_properties_get_int( MLT_PLAYLIST_PROPERTIES( playlist ), "_melt_first" ) ||
+ if ( playlist && !mlt_properties_get_int( MLT_PLAYLIST_PROPERTIES( playlist ), "_melt_first" ) ||
mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( playlist ) ) > 0 )
mlt_multitrack_connect( multitrack, MLT_PLAYLIST_PRODUCER( playlist ), track );
mlt_properties properties = MLT_FRAME_PROPERTIES( *frame );
// Aspect ratio is whatever it needs to be
- mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( MLT_PRODUCER_PROPERTIES( this ), "aspect_ratio" ) );
+ mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( this ) );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );
// Set producer-specific frame properties
mlt_properties_set_int( properties, "progressive", 1 );
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 );
+ producer_ppm this = calloc( 1, sizeof( struct producer_ppm_s ) );
if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 )
{
mlt_producer producer = &this->parent;
/** Calculate real geometry.
*/
-static void geometry_calculate( mlt_transition this, struct geometry_s *output, double position )
+static void geometry_calculate( mlt_transition self, struct geometry_s *output, double position )
{
- mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( self );
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" );
mlt_geometry_fetch( geometry, &output->item, position );
}
-static mlt_geometry transition_parse_keys( mlt_transition this, int normalised_width, int normalised_height )
+static mlt_geometry transition_parse_keys( mlt_transition self, 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 );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( self );
// Create an empty geometries object
mlt_geometry geometry = mlt_geometry_init( );
// Get the duration
- mlt_position length = mlt_transition_get_length( this );
+ mlt_position length = mlt_transition_get_length( self );
double cycle = mlt_properties_get_double( properties, "cycle" );
// Get the new style geometry string
/** Calculate the position for this frame.
*/
-static int position_calculate( mlt_transition this, mlt_position position )
+static int position_calculate( mlt_transition self, mlt_position position )
{
// Get the in and out position
- mlt_position in = mlt_transition_get_in( this );
+ mlt_position in = mlt_transition_get_in( self );
// Now do the calcs
return position - in;
static inline int calculate_mix( uint16_t *luma, int j, int softness, int weight, int alpha, uint32_t step )
{
- return ( ( luma ? smoothstep( luma[ j ], luma[ j ] + softness, step ) : weight ) * alpha ) >> 8;
+ return ( ( luma ? smoothstep( luma[ j ], luma[ j ] + softness, step ) : weight ) * ( alpha + 1 ) ) >> 8;
}
static inline uint8_t sample_mix( uint8_t dest, uint8_t src, int mix )
/** Composite a source line over a destination line
*/
+#if defined(USE_SSE) && defined(ARCH_X86_64)
+void composite_line_yuv_sse2_simple(uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a, int weight);
+#endif
-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, uint32_t step )
+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, uint32_t step )
{
- register int j;
+ register int j = 0;
register int mix;
- for ( j = 0; j < width; j ++ )
+#if defined(USE_SSE) && defined(ARCH_X86_64)
+ if ( !luma && width > 7 )
+ {
+ composite_line_yuv_sse2_simple(dest, src, width, alpha_b, alpha_a, weight);
+ j = width - width % 8;
+ dest += j * 2;
+ src += j * 2;
+ alpha_a += j;
+ alpha_b += j;
+ }
+#endif
+
+ for ( ; j < width; j ++ )
{
mix = calculate_mix( luma, j, soft, weight, *alpha_b ++, step );
*dest = sample_mix( *dest, *src++, mix );
int stride_src = geometry.sw * bpp;
int stride_dest = width_dest * bpp;
int i_softness = ( 1 << 16 ) * softness;
- int weight = ( ( 1 << 16 ) - 1 ) * geometry.item.mix / 100;
- uint32_t luma_step = ( ( 1 << 16 ) - 1 ) * geometry.item.mix / 100 * ( 1.0 + softness );
+ int weight = ( ( 1 << 16 ) * geometry.item.mix + 50 ) / 100;
+ uint32_t luma_step = ( ( ( 1 << 16 ) - 1 ) * geometry.item.mix + 50 ) / 100 * ( 1.0 + softness );
// Adjust to consumer scale
int x = rint( geometry.item.x * width_dest / geometry.nw );
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;
+ p_dest += x * bpp + y * stride_dest;
// offset pointer into alpha channel based upon cropping
alpha_b += x_src + y_src * stride_src / bpp;
if ( uneven_x != uneven_x_src )
{
p_src += 2;
- width_src -= 2;
alpha_b += 1;
}
}
}
-static uint16_t* get_luma( mlt_transition this, mlt_properties properties, int width, int height )
+static uint16_t* get_luma( mlt_transition self, mlt_properties properties, int width, int height )
{
// The cached luma map information
int luma_width = mlt_properties_get_int( properties, "_luma.width" );
char *factory = mlt_properties_get( properties, "factory" );
// Create the producer
- mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( this ) );
+ mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( self ) );
mlt_producer producer = mlt_factory_producer( profile, factory, resource );
// If we have one
/** 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 )
+static int get_b_frame_image( mlt_transition self, 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 );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( self );
uint8_t resize_alpha = mlt_properties_get_int( b_props, "resize_alpha" );
- double consumer_ar = mlt_profile_sar( mlt_service_profile( MLT_TRANSITION_SERVICE(this) ) );
+ double output_ar = mlt_profile_sar( mlt_service_profile( MLT_TRANSITION_SERVICE(self) ) );
// 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" );
+ int real_width = get_value( b_props, "meta.media.width", "width" );
+ int real_height = get_value( b_props, "meta.media.height", "height" );
double input_ar = mlt_properties_get_double( b_props, "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;
// 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" );
+ int real_width = get_value( b_props, "meta.media.width", "width" );
+ int real_height = get_value( b_props, "meta.media.height", "height" );
double input_ar = mlt_properties_get_double( b_props, "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__,
+// fprintf(stderr, "%s: scaled %dx%d norm %dx%d real %dx%d output_ar %f\n", __FILE__,
// scaled_width, scaled_height, normalised_width, normalised_height, real_width, real_height,
-// background_ar, output_ar);
+// output_ar);
// Now ensure that our images fit in the normalised frame
if ( scaled_width > normalised_width )
return ret && image != NULL;
}
-static void crop_calculate( mlt_transition this, mlt_properties properties, struct geometry_s *result, double position )
+static void crop_calculate( mlt_transition self, mlt_properties properties, struct geometry_s *result, double position )
{
// Initialize panning info
result->x_src = 0;
if ( !crop )
{
crop = mlt_geometry_init();
- mlt_position length = mlt_transition_get_length( this );
+ mlt_position length = mlt_transition_get_length( self );
double cycle = mlt_properties_get_double( properties, "cycle" );
// Allow a geometry repeat cycle
}
}
-static mlt_geometry composite_calculate( mlt_transition this, struct geometry_s *result, mlt_frame a_frame, double position )
+static mlt_geometry composite_calculate( mlt_transition self, struct geometry_s *result, mlt_frame a_frame, double position )
{
// Get the properties from the transition
- mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( self );
// Get the properties from the frame
mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame );
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" );
+ mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( self ) );
+ int normalised_width = profile->width;
+ int normalised_height = profile->height;
char *name = mlt_properties_get( properties, "_unique_id" );
char key[ 256 ];
if ( start == NULL )
{
// Parse the transitions properties
- start = transition_parse_keys( this, normalised_width, normalised_height );
+ start = transition_parse_keys( self, 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
{
- mlt_position length = mlt_transition_get_length( this );
+ mlt_position length = mlt_transition_get_length( self );
double cycle = mlt_properties_get_double( properties, "cycle" );
if ( cycle > 1 )
length = cycle;
}
// Do the calculation
- geometry_calculate( this, result, position );
+ geometry_calculate( self, result, position );
// Assign normalised info
result->nw = normalised_width;
result->halign = alignment_parse( mlt_properties_get( properties, "halign" ) );
result->valign = alignment_parse( mlt_properties_get( properties, "valign" ) );
- crop_calculate( this, properties, result, position );
+ crop_calculate( self, properties, result, position );
return start;
}
-mlt_frame composite_copy_region( mlt_transition this, mlt_frame a_frame, mlt_position frame_position )
+mlt_frame composite_copy_region( mlt_transition self, mlt_frame a_frame, mlt_position frame_position )
{
// Create a frame to return
- mlt_frame b_frame = mlt_frame_init( MLT_TRANSITION_SERVICE( this ) );
+ mlt_frame b_frame = mlt_frame_init( MLT_TRANSITION_SERVICE( self ) );
// Get the properties of the a frame
mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame );
mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame );
// Get the position
- int position = position_calculate( this, frame_position );
+ int position = position_calculate( self, frame_position );
// Get the unique id of the transition
- char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( this ), "_unique_id" );
+ char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( self ), "_unique_id" );
char key[ 256 ];
// Destination image
struct geometry_s result;
// Calculate the region now
- composite_calculate( this, &result, a_frame, position );
+ composite_calculate( self, &result, a_frame, position );
// Need to scale down to actual dimensions
x = rint( result.item.x * width / result.nw );
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 );
+ mlt_transition self = mlt_frame_pop_service( a_frame );
// Get in and out
double position = mlt_deque_pop_back_double( MLT_FRAME_IMAGE_STACK( a_frame ) );
int in = mlt_frame_pop_service_int( a_frame );
// Get the properties from the transition
- mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( self );
// TODO: clean up always_active behaviour
if ( mlt_properties_get_int( properties, "always_active" ) )
struct geometry_s result;
// Calculate the position
- double delta = mlt_transition_get_progress_delta( this, a_frame );
- mlt_position length = mlt_transition_get_length( this );
+ double delta = mlt_transition_get_progress_delta( self, a_frame );
+ mlt_position length = mlt_transition_get_length( self );
// Get the image from the b frame
uint8_t *image_b = NULL;
- int width_b = *width > 0 ? *width : mlt_properties_get_int( a_props, "normalised_width" );
- int height_b = *height > 0 ? *height : mlt_properties_get_int( a_props, "normalised_height" );
+ mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( self ) );
+ int width_b = *width > 0 ? *width : profile->width;
+ int height_b = *height > 0 ? *height : profile->height;
// Vars for alphas
uint8_t *alpha_a = NULL;
// Do the calculation
// NB: Locks needed here since the properties are being modified
int invert = mlt_properties_get_int( properties, "invert" );
- mlt_service_lock( MLT_TRANSITION_SERVICE( this ) );
- composite_calculate( this, &result, invert ? b_frame : a_frame, position );
- mlt_service_unlock( MLT_TRANSITION_SERVICE( this ) );
+ mlt_service_lock( MLT_TRANSITION_SERVICE( self ) );
+ composite_calculate( self, &result, invert ? b_frame : a_frame, position );
+ mlt_service_unlock( MLT_TRANSITION_SERVICE( self ) );
// Manual option to deinterlace
if ( mlt_properties_get_int( properties, "deinterlace" ) )
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 );
+ get_b_frame_image( self, 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 );
}
height_b = mlt_properties_get_int( a_props, "dest_height" );
}
- if ( *image != image_b && ( ( invert ? 0 : image_b ) || get_b_frame_image( this, b_frame, invert ? image : &image_b, &width_b, &height_b, &result ) == 0 ) )
+ if ( *image != image_b && ( ( invert ? 0 : image_b ) || get_b_frame_image( self, b_frame, invert ? image : &image_b, &width_b, &height_b, &result ) == 0 ) )
{
uint8_t *dest = *image;
uint8_t *src = image_b;
int field;
double luma_softness = mlt_properties_get_double( properties, "softness" );
- mlt_service_lock( MLT_TRANSITION_SERVICE( this ) );
- uint16_t *luma_bitmap = get_luma( this, properties, width_b, height_b );
- mlt_service_unlock( MLT_TRANSITION_SERVICE( this ) );
+ mlt_service_lock( MLT_TRANSITION_SERVICE( self ) );
+ uint16_t *luma_bitmap = get_luma( self, properties, width_b, height_b );
+ mlt_service_unlock( MLT_TRANSITION_SERVICE( self ) );
char *operator = mlt_properties_get( properties, "operator" );
alpha_b = alpha_b == NULL ? mlt_frame_get_alpha_mask( b_frame ) : alpha_b;
// 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, invert ? b_frame : a_frame, field_position );
- mlt_service_unlock( MLT_TRANSITION_SERVICE( this ) );
+ mlt_service_lock( MLT_TRANSITION_SERVICE( self ) );
+ composite_calculate( self, &result, invert ? b_frame : a_frame, field_position );
+ mlt_service_unlock( MLT_TRANSITION_SERVICE( self ) );
if ( mlt_properties_get_int( properties, "titles" ) )
{
/** Composition transition processing.
*/
-static mlt_frame composite_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame )
+static mlt_frame composite_process( mlt_transition self, 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 )
+ if ( mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( self ), "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 ) ) );
+ mlt_frame_push_service_int( a_frame, mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( self ), "in" ) );
+ mlt_frame_push_service_int( a_frame, mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( self ), "out" ) );
+ mlt_deque_push_back_double( MLT_FRAME_IMAGE_STACK( a_frame ), position_calculate( self, mlt_frame_get_position( a_frame ) ) );
}
else
{
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_service( a_frame, self );
mlt_frame_push_frame( a_frame, b_frame );
mlt_frame_push_get_image( a_frame, transition_get_image );
return a_frame;
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_transition self = calloc( 1, sizeof( struct mlt_transition_s ) );
+ if ( self != NULL && mlt_transition_init( self, NULL ) == 0 )
{
- mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( self );
- this->process = composite_process;
+ self->process = composite_process;
// Default starting motion and zoom
mlt_properties_set( properties, "start", arg != NULL ? arg : "0/0:100%x100%" );
// Inform apps and framework that this is a video only transition
mlt_properties_set_int( properties, "_transition_type", 1 );
}
- return this;
+ return self;
}
// Courtesy functionality - allows regionalised filtering
extern mlt_frame composite_copy_region( mlt_transition, mlt_frame, mlt_position );
+extern 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, uint32_t step );
#endif
Mix is always a 2 digit percentage, defaults to 100.
type: geometry
- default: "85%/5%:10%x10%"
+ default: "0%/0%:100%x100%"
readonly: no
mutable: yes
- identifier: end
#include <ctype.h>
#include <string.h>
#include <math.h>
+#include "transition_composite.h"
static inline int dissolve_yuv( mlt_frame this, mlt_frame that, float weight, int width, int height )
{
int ret = 0;
+ int i = height + 1;
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 );
+ int mix = weight * ( 1 << 16 );
if ( mlt_properties_get( &this->parent, "distort" ) )
mlt_properties_set( &that->parent, "distort", mlt_properties_get( &this->parent, "distort" ) );
// 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 )
+ while ( --i )
{
- *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;
+ composite_line_yuv( p_dest, p_src, width_src, alpha_src, alpha_dst, mix, NULL, 0, 0 );
+ p_src += width_src << 1;
+ p_dest += width << 1;
+ alpha_src += width_src;
+ alpha_dst += width;
}
return ret;
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 );
+ mlt_transition this = calloc( 1, sizeof( struct mlt_transition_s ) );
if ( this != NULL && mlt_transition_init( this, NULL ) == 0 )
{
this->process = transition_process;
#include <stdlib.h>
#include <string.h>
-static int create_instance( mlt_transition this, char *name, char *value, int count )
+static int create_instance( mlt_transition transition, char *name, char *value, int count )
{
// Return from this function
int error = 0;
*arg ++ = '\0';
// Create the filter
- mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( this ) );
- filter = mlt_factory_filter( profile, type, arg );
+ mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) );
+ if ( type )
+ 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 );
+ // Properties of transition
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
// String to hold the property name
char id[ 256 ];
// Pass all the key properties on the filter down
mlt_properties_pass( MLT_FILTER_PROPERTIES( filter ), properties, key );
+ mlt_properties_pass_list( MLT_FILTER_PROPERTIES( filter ), properties, "in, out, length" );
// Ensure that filter is assigned
mlt_properties_set_data( properties, id, filter, 0, ( mlt_destructor )mlt_filter_close, NULL );
return error;
}
-static uint8_t *filter_get_alpha_mask( mlt_frame this )
+static uint8_t *filter_get_alpha_mask( mlt_frame frame )
{
uint8_t *alpha = NULL;
// Obtain properties of frame
- mlt_properties properties = MLT_FRAME_PROPERTIES( this );
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
// 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" );
+ int region_width = mlt_properties_get_int( properties, "width" );
+ int region_height = mlt_properties_get_int( properties, "height" );
uint8_t *image = NULL;
mlt_image_format format = mlt_image_yuv422;
alpha = mlt_frame_get_alpha_mask( shape_frame );
+ int size = region_width * region_height;
+ uint8_t *alpha_duplicate = mlt_pool_alloc( size );
+
// 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;
+ alpha = alpha_duplicate;
while ( size -- )
{
- *p ++ = ( int )( ( ( *image ++ - 16 ) * 299 ) / 255 );
+ *alpha ++ = ( int )( ( ( *image ++ - 16 ) * 299 ) / 255 );
image ++;
}
- mlt_frame_set_alpha( this, alpha, region_width * region_height, mlt_pool_release );
}
else
{
- mlt_frame_set_alpha( this, alpha, region_width * region_height, NULL );
+ memcpy( alpha_duplicate, alpha, size );
}
+ mlt_frame_set_alpha( frame, alpha_duplicate, region_width * region_height, mlt_pool_release );
- this->get_alpha_mask = NULL;
-
- return alpha;
+ return alpha_duplicate;
}
/** Do it :-).
mlt_frame b_frame = mlt_frame_pop_frame( frame );
// Get the watermark transition object
- mlt_transition this = mlt_frame_pop_service( frame );
+ mlt_transition transition = mlt_frame_pop_service( frame );
// Get the properties of the transition
- mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
+
+ // Get the properties of the a frame
+ mlt_properties a_props = MLT_FRAME_PROPERTIES( frame );
- mlt_service_lock( MLT_TRANSITION_SERVICE( this ) );
+ mlt_service_lock( MLT_TRANSITION_SERVICE( transition ) );
// Get the composite from the transition
mlt_transition composite = mlt_properties_get_data( properties, "composite", NULL );
mlt_filter filter = mlt_properties_get_data( properties, "_filter_0", NULL );
// Get the position
- mlt_position position = mlt_transition_get_position( this, frame );
+ mlt_position position = mlt_transition_get_position( transition, frame );
// 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 ) );
+ mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) );
composite = mlt_factory_transition( profile, "composite", NULL );
// If we have one
char *value = mlt_properties_get_value( properties, i );
// Create an instance
- if ( create_instance( this, name, value, count ) == 0 )
+ if ( create_instance( transition, name, value, count ) == 0 )
count ++;
}
}
}
}
- mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "width", *width );
- mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "height", *height );
+ mlt_properties_set_int( a_props, "width", *width );
+ mlt_properties_set_int( a_props, "height", *height );
// Only continue if we have both filter and composite
if ( composite != NULL )
// Ensure a destructor
char *name = mlt_properties_get( properties, "_unique_id" );
- mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), name, b_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
+ mlt_properties_set_data( a_props, name, b_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
}
+ // Properties of the B frame
+ mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame );
+
// filter_only prevents copying the alpha channel of the shape to the output frame
// by compositing filtered frame over itself
if ( mlt_properties_get_int( properties, "filter_only" ) )
{
+ char *name = mlt_properties_get( properties, "_unique_id" );
frame = composite_copy_region( composite, b_frame, position );
+ mlt_properties_set_data( b_props, name, frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
}
// Make sure the filter is in the correct position
resource = "pixbuf:<svg width='100' height='100'><circle cx='50' cy='50' r='50' fill='black'/></svg>";
// Create the producer
- mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( this ) );
+ mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) );
producer = mlt_factory_producer( profile, factory, resource );
// If we have one
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 );
+ mlt_properties_set_data( b_props, "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;
error = mlt_frame_get_image( frame, image, format, width, height, 0 );
}
- mlt_service_unlock( MLT_TRANSITION_SERVICE( this ) );
+ mlt_service_unlock( MLT_TRANSITION_SERVICE( transition ) );
return error;
}
/** Filter processing.
*/
-static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame )
+static mlt_frame transition_process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame )
{
// Push the transition on to the frame
- mlt_frame_push_service( a_frame, this );
+ mlt_frame_push_service( a_frame, transition );
// Push the b_frame on to the stack
mlt_frame_push_frame( a_frame, b_frame );
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( );
+ mlt_transition transition = mlt_transition_new( );
// Further initialisation
- if ( this != NULL )
+ if ( transition != NULL )
{
// Get the properties from the transition
- mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
// Assign the transition process method
- this->process = transition_process;
+ transition->process = transition_process;
// Default factory
mlt_properties_set( properties, "factory", mlt_environment( "MLT_PRODUCER" ) );
}
// Return the transition
- return this;
+ return transition;
}
TARGET = ../libmltdecklink$(LIBSUF)
OBJS = consumer_decklink.o \
- producer_decklink.o
+ producer_decklink.o \
+ common.o
ifeq ($(targetos), MinGW)
-OBJS += DeckLinkAPI_i.o
+CFLAGS += -Iwin
+OBJS += win/DeckLinkAPI_i.o
LDFLAGS += -lole32
else
-OBJS += DeckLinkAPIDispatch.o
+ifeq ($(targetos), Darwin)
+CFLAGS += -Idarwin
+OBJS += darwin/DeckLinkAPIDispatch.o
+else
+CFLAGS += -Ilinux
+OBJS += linux/DeckLinkAPIDispatch.o
+endif
endif
SRCS := $(OBJS:.o=.cpp)
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/decklink"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/decklink"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/decklink"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/decklink"
uninstall:
- rm "$(DESTDIR)$(libdir)/mlt/libmltdecklink$(LIBSUF)" 2> /dev/null || true
- rm -rf "$(DESTDIR)$(datadir)/mlt/decklink"
+ rm "$(DESTDIR)$(moduledir)/libmltdecklink$(LIBSUF)" 2> /dev/null || true
+ rm -rf "$(DESTDIR)$(mltdatadir)/decklink"
ifneq ($(wildcard .depend),)
include .depend
--- /dev/null
+/*
+ * common.cpp -- Blackmagic Design DeckLink common functions
+ * Copyright (C) 2012 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 consumer library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "common.h"
+#include <stdlib.h>
+
+#ifdef __DARWIN__
+
+char* getCString( DLString aDLString )
+{
+ char* CString = (char*) malloc( 64 );
+ CFStringGetCString( aDLString, CString, 64, kCFStringEncodingMacRoman );
+ return CString;
+}
+
+void freeCString( char* aCString )
+{
+ if ( aCString ) free( aCString );
+}
+
+void freeDLString( DLString aDLString )
+{
+ if ( aDLString ) CFRelease( aDLString );
+}
+
+#elif defined(WIN32)
+
+char* getCString( DLString aDLString )
+{
+ char* CString = NULL;
+ if ( aDLString )
+ {
+ int size = WideCharToMultiByte( CP_UTF8, 0, aDLString, -1, NULL, 0, NULL, NULL );
+ if (size)
+ {
+ CString = new char[ size ];
+ size = WideCharToMultiByte( CP_UTF8, 0, aDLString, -1, CString, size, NULL, NULL );
+ if ( !size )
+ {
+ delete[] CString;
+ CString = NULL;
+ }
+ }
+ }
+ return CString;
+}
+
+void freeCString( char* aCString )
+{
+ delete[] aCString;
+}
+
+void freeDLString( DLString aDLString )
+{
+ if ( aDLString ) free( (void*) aDLString );
+}
+
+#else
+
+char* getCString( DLString aDLString )
+{
+ return aDLString? (char*) aDLString : NULL;
+}
+
+void freeCString( char* aCString )
+{
+}
+
+void freeDLString( DLString aDLString )
+{
+ if ( aDLString ) free( (void*) aDLString );
+}
+
+#endif
+
--- /dev/null
+/*
+ * common.h -- Blackmagic Design DeckLink common functions
+ * Copyright (C) 2012 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 consumer library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DECKLINK_COMMON_H
+#define DECKLINK_COMMON_H
+
+#ifdef WIN32
+# include <objbase.h>
+# include "DeckLinkAPI_h.h"
+ typedef BSTR DLString;
+#else
+# include "DeckLinkAPI.h"
+# ifdef __DARWIN__
+ typedef CFStringRef DLString;
+# else
+ typedef const char* DLString;
+# endif
+#endif
+
+#define SAFE_RELEASE(V) if (V) { V->Release(); V = NULL; }
+
+char* getCString( DLString aDLString );
+void freeCString( char* aCString );
+void freeDLString( DLString aDLString );
+
+#endif // DECKLINK_COMMON_H
#include <sys/time.h>
#include <limits.h>
#include <pthread.h>
-#ifdef WIN32
-#include <objbase.h>
-#include "DeckLinkAPI_h.h"
-#else
-#include "DeckLinkAPI.h"
-#endif
+#include "common.h"
static const unsigned PREROLL_MINIMUM = 3;
IDeckLinkDisplayMode* getDisplayMode()
{
mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( getConsumer() ) );
- IDeckLinkDisplayModeIterator* iter;
- IDeckLinkDisplayMode* mode;
+ IDeckLinkDisplayModeIterator* iter = NULL;
+ IDeckLinkDisplayMode* mode = NULL;
IDeckLinkDisplayMode* result = 0;
-
+
if ( m_deckLinkOutput->GetDisplayModeIterator( &iter ) == S_OK )
{
while ( !result && iter->Next( &mode ) == S_OK )
m_fps = (double) m_timescale / m_duration;
int p = mode->GetFieldDominance() == bmdProgressiveFrame;
mlt_log_verbose( getConsumer(), "BMD mode %dx%d %.3f fps prog %d\n", m_width, m_height, m_fps, p );
-
+
if ( m_width == profile->width && p == profile->progressive
- && m_fps == mlt_profile_fps( profile )
+ && (int) m_fps == (int) mlt_profile_fps( profile )
&& ( m_height == profile->height || ( m_height == 486 && profile->height == 480 ) ) )
result = mode;
+ else
+ SAFE_RELEASE( mode );
}
+ SAFE_RELEASE( iter );
}
-
+
return result;
}
-
+
public:
mlt_consumer getConsumer()
{ return &m_consumer; }
-
+
+ DeckLinkConsumer()
+ {
+ m_displayMode = NULL;
+ m_deckLinkKeyer = NULL;
+ m_deckLinkOutput = NULL;
+ m_deckLink = NULL;
+ m_decklinkFrame = NULL;
+ }
+
~DeckLinkConsumer()
{
- if ( m_deckLinkKeyer )
- m_deckLinkKeyer->Release();
- if ( m_deckLinkOutput )
- m_deckLinkOutput->Release();
- if ( m_deckLink )
- m_deckLink->Release();
+ SAFE_RELEASE( m_displayMode );
+ SAFE_RELEASE( m_deckLinkKeyer );
+ SAFE_RELEASE( m_deckLinkOutput );
+ SAFE_RELEASE( m_deckLink );
}
-
+
bool open( unsigned card = 0 )
{
unsigned i = 0;
}
#else
IDeckLinkIterator* deckLinkIterator = CreateDeckLinkIteratorInstance();
-
+
if ( !deckLinkIterator )
{
mlt_log_error( getConsumer(), "The DeckLink drivers not installed.\n" );
return false;
}
#endif
-
+
// Connect to the Nth DeckLink instance
- do {
- if ( deckLinkIterator->Next( &m_deckLink ) != S_OK )
- {
- mlt_log_error( getConsumer(), "DeckLink card not found\n" );
- deckLinkIterator->Release();
- return false;
- }
- } while ( ++i <= card );
- deckLinkIterator->Release();
-
+ for ( i = 0; deckLinkIterator->Next( &m_deckLink ) == S_OK ; i++)
+ {
+ if( i == card )
+ break;
+ else
+ SAFE_RELEASE( m_deckLink );
+ }
+ SAFE_RELEASE( deckLinkIterator );
+ if ( !m_deckLink )
+ {
+ mlt_log_error( getConsumer(), "DeckLink card not found\n" );
+ return false;
+ }
+
// Obtain the audio/video output interface (IDeckLinkOutput)
if ( m_deckLink->QueryInterface( IID_IDeckLinkOutput, (void**)&m_deckLinkOutput ) != S_OK )
{
mlt_log_error( getConsumer(), "No DeckLink cards support output\n" );
- m_deckLink->Release();
- m_deckLink = 0;
+ SAFE_RELEASE( m_deckLink );
return false;
}
-
+
// Get the keyer interface
IDeckLinkAttributes *deckLinkAttributes = 0;
- m_deckLinkKeyer = 0;
if ( m_deckLink->QueryInterface( IID_IDeckLinkAttributes, (void**) &deckLinkAttributes ) == S_OK )
{
#ifdef WIN32
if ( m_deckLink->QueryInterface( IID_IDeckLinkKeyer, (void**) &m_deckLinkKeyer ) != S_OK )
{
mlt_log_error( getConsumer(), "Failed to get keyer\n" );
- m_deckLinkOutput->Release();
- m_deckLinkOutput = 0;
- m_deckLink->Release();
- m_deckLink = 0;
+ SAFE_RELEASE( m_deckLinkOutput );
+ SAFE_RELEASE( m_deckLink );
return false;
}
}
- deckLinkAttributes->Release();
+ SAFE_RELEASE( deckLinkAttributes );
}
// Provide this class as a delegate to the audio and video output interfaces
m_deckLinkOutput->SetScheduledFrameCompletionCallback( this );
-
+
return true;
}
void* preroll_thread()
{
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( getConsumer() );
+
// preroll frames
- for ( unsigned i = 0; i < m_preroll; i++ )
+ for ( unsigned i = 0; i < m_preroll && mlt_properties_get_int( properties, "running" ); i++ )
ScheduleNextFrame( true );
// start scheduled playback
- m_deckLinkOutput->StartScheduledPlayback( 0, m_timescale, 1.0 );
+ if ( mlt_properties_get_int( properties, "running" ) )
+ m_deckLinkOutput->StartScheduledPlayback( 0, m_timescale, 1.0 );
return 0;
}
mlt_log_error( getConsumer(), "Profile is not compatible with decklink.\n" );
return false;
}
-
+
// Set the keyer
if ( m_deckLinkKeyer && ( m_isKeyer = mlt_properties_get_int( properties, "keyer" ) ) )
{
m_preroll = preroll;
m_reprio = false;
- // Do preroll in thread to ensure asynchronicity of mlt_consumer_start().
- pthread_create( &m_prerollThread, NULL, preroll_thread_proxy, this );
-
// Set the running state
mlt_properties_set_int( properties, "running", 1 );
+ // Do preroll in thread to ensure asynchronicity of mlt_consumer_start().
+ pthread_create( &m_prerollThread, NULL, preroll_thread_proxy, this );
+
return true;
}
-
+
bool stop()
{
mlt_properties properties = MLT_CONSUMER_PROPERTIES( getConsumer() );
// set running state is 0
mlt_properties_set_int( properties, "running", 0 );
- mlt_consumer_stopped( getConsumer() );
+
+ if ( wasRunning )
+ pthread_join( m_prerollThread, NULL );
// Stop the audio and video output streams immediately
if ( m_deckLinkOutput )
}
// release decklink frame
- if ( m_decklinkFrame )
- m_decklinkFrame->Release();
- m_decklinkFrame = NULL;
+ SAFE_RELEASE( m_decklinkFrame );
- if ( wasRunning )
- pthread_join( m_prerollThread, NULL );
+ mlt_consumer_stopped( getConsumer() );
return true;
}
stop();
return false;
}
-
+
// Make the first line black for field order correction.
if ( S_OK == frame->GetBytes( (void**) &buffer ) && buffer )
{
uint8_t* buffer = 0;
int stride = m_width * ( m_isKeyer? 4 : 2 );
- if ( m_decklinkFrame )
- m_decklinkFrame->Release();
+ SAFE_RELEASE( m_decklinkFrame );
if ( createFrame( &m_decklinkFrame ) )
m_decklinkFrame->GetBytes( (void**) &buffer );
return result;
}
-
+
// *** DeckLink API implementation of IDeckLinkVideoOutputCallback IDeckLinkAudioOutputCallback *** //
// IUnknown needs only a dummy implementation
{ return 1; }
virtual ULONG STDMETHODCALLTYPE Release()
{ return 1; }
-
+
/************************* DeckLink API Delegate Methods *****************************/
-
+
virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted( IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult completed )
{
if( !m_reprio )
{
return mlt_consumer_is_stopped( getConsumer() ) ? S_FALSE : S_OK;
}
-
+
void ScheduleNextFrame( bool preroll )
{
extern "C" {
+// Listen for the list_devices property to be set
+static void on_property_changed( void*, mlt_properties properties, const char *name )
+{
+ IDeckLinkIterator* decklinkIterator = NULL;
+ IDeckLink* decklink = NULL;
+ IDeckLinkInput* decklinkOutput = NULL;
+ int i = 0;
+
+ if ( name && !strcmp( name, "list_devices" ) )
+ mlt_event_block( (mlt_event) mlt_properties_get_data( properties, "list-devices-event", NULL ) );
+ else
+ return;
+
+#ifdef WIN32
+ if ( FAILED( CoInitialize( NULL ) ) )
+ return;
+ if ( FAILED( CoCreateInstance( CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**) &decklinkIterator ) ) )
+ return;
+#else
+ if ( !( decklinkIterator = CreateDeckLinkIteratorInstance() ) )
+ return;
+#endif
+ for ( ; decklinkIterator->Next( &decklink ) == S_OK; i++ )
+ {
+ if ( decklink->QueryInterface( IID_IDeckLinkOutput, (void**) &decklinkOutput ) == S_OK )
+ {
+ DLString name = NULL;
+ if ( decklink->GetModelName( &name ) == S_OK )
+ {
+ char *name_cstr = getCString( name );
+ const char *format = "device.%d";
+ char *key = (char*) calloc( 1, strlen( format ) + 1 );
+
+ sprintf( key, format, i );
+ mlt_properties_set( properties, key, name_cstr );
+ free( key );
+ freeDLString( name );
+ freeCString( name_cstr );
+ }
+ SAFE_RELEASE( decklinkOutput );
+ }
+ SAFE_RELEASE( decklink );
+ }
+ SAFE_RELEASE( decklinkIterator );
+ mlt_properties_set_int( properties, "devices", i );
+}
+
/** Initialise the consumer.
*/
if ( decklink->open( arg? atoi(arg) : 0 ) )
{
consumer = decklink->getConsumer();
-
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
+
// Setup callbacks
consumer->close = close;
consumer->start = start;
consumer->stop = stop;
consumer->is_stopped = is_stopped;
- mlt_properties_set( MLT_CONSUMER_PROPERTIES(consumer), "deinterlace_method", "onefield" );
+ mlt_properties_set( properties, "deinterlace_method", "onefield" );
+
+ mlt_event event = mlt_events_listen( properties, properties, "property-changed", (mlt_listener) on_property_changed );
+ mlt_properties_set_data( properties, "list-devices-event", event, 0, NULL, NULL );
}
}
maximum: 1
default: 1
widget: slider
+
+ - identifier: devices
+ title: Number of devices
+ type: integer
+ readonly: yes
+ minimum: 0
+
+ - identifier: device.*
+ title: Device model
+ description: The model name of each device that provides output.
+ type: string
+ readonly: yes
--- /dev/null
+/* -LICENSE-START-
+** Copyright (c) 2011 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* DeckLinkAPI.h */
+
+#ifndef __DeckLink_API_h__
+#define __DeckLink_API_h__
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFPlugInCOM.h>
+#include <stdint.h>
+
+#define BLACKMAGIC_DECKLINK_API_MAGIC 1
+
+// Type Declarations
+
+typedef int64_t BMDTimeValue;
+typedef int64_t BMDTimeScale;
+typedef uint32_t BMDTimecodeBCD;
+typedef uint32_t BMDTimecodeUserBits;
+
+
+// Interface ID Declarations
+
+#define IID_IDeckLinkVideoOutputCallback /* 20AA5225-1958-47CB-820B-80A8D521A6EE */ (REFIID){0x20,0xAA,0x52,0x25,0x19,0x58,0x47,0xCB,0x82,0x0B,0x80,0xA8,0xD5,0x21,0xA6,0xEE}
+#define IID_IDeckLinkInputCallback /* DD04E5EC-7415-42AB-AE4A-E80C4DFC044A */ (REFIID){0xDD,0x04,0xE5,0xEC,0x74,0x15,0x42,0xAB,0xAE,0x4A,0xE8,0x0C,0x4D,0xFC,0x04,0x4A}
+#define IID_IDeckLinkMemoryAllocator /* B36EB6E7-9D29-4AA8-92EF-843B87A289E8 */ (REFIID){0xB3,0x6E,0xB6,0xE7,0x9D,0x29,0x4A,0xA8,0x92,0xEF,0x84,0x3B,0x87,0xA2,0x89,0xE8}
+#define IID_IDeckLinkAudioOutputCallback /* 403C681B-7F46-4A12-B993-2BB127084EE6 */ (REFIID){0x40,0x3C,0x68,0x1B,0x7F,0x46,0x4A,0x12,0xB9,0x93,0x2B,0xB1,0x27,0x08,0x4E,0xE6}
+#define IID_IDeckLinkIterator /* 74E936FC-CC28-4A67-81A0-1E94E52D4E69 */ (REFIID){0x74,0xE9,0x36,0xFC,0xCC,0x28,0x4A,0x67,0x81,0xA0,0x1E,0x94,0xE5,0x2D,0x4E,0x69}
+#define IID_IDeckLinkAPIInformation /* 7BEA3C68-730D-4322-AF34-8A7152B532A4 */ (REFIID){0x7B,0xEA,0x3C,0x68,0x73,0x0D,0x43,0x22,0xAF,0x34,0x8A,0x71,0x52,0xB5,0x32,0xA4}
+#define IID_IDeckLinkDisplayModeIterator /* 9C88499F-F601-4021-B80B-032E4EB41C35 */ (REFIID){0x9C,0x88,0x49,0x9F,0xF6,0x01,0x40,0x21,0xB8,0x0B,0x03,0x2E,0x4E,0xB4,0x1C,0x35}
+#define IID_IDeckLinkDisplayMode /* 3EB2C1AB-0A3D-4523-A3AD-F40D7FB14E78 */ (REFIID){0x3E,0xB2,0xC1,0xAB,0x0A,0x3D,0x45,0x23,0xA3,0xAD,0xF4,0x0D,0x7F,0xB1,0x4E,0x78}
+#define IID_IDeckLink /* 62BFF75D-6569-4E55-8D4D-66AA03829ABC */ (REFIID){0x62,0xBF,0xF7,0x5D,0x65,0x69,0x4E,0x55,0x8D,0x4D,0x66,0xAA,0x03,0x82,0x9A,0xBC}
+#define IID_IDeckLinkOutput /* A3EF0963-0862-44ED-92A9-EE89ABF431C7 */ (REFIID){0xA3,0xEF,0x09,0x63,0x08,0x62,0x44,0xED,0x92,0xA9,0xEE,0x89,0xAB,0xF4,0x31,0xC7}
+#define IID_IDeckLinkInput /* 6D40EF78-28B9-4E21-990D-95BB7750A04F */ (REFIID){0x6D,0x40,0xEF,0x78,0x28,0xB9,0x4E,0x21,0x99,0x0D,0x95,0xBB,0x77,0x50,0xA0,0x4F}
+#define IID_IDeckLinkTimecode /* BC6CFBD3-8317-4325-AC1C-1216391E9340 */ (REFIID){0xBC,0x6C,0xFB,0xD3,0x83,0x17,0x43,0x25,0xAC,0x1C,0x12,0x16,0x39,0x1E,0x93,0x40}
+#define IID_IDeckLinkVideoFrame /* 3F716FE0-F023-4111-BE5D-EF4414C05B17 */ (REFIID){0x3F,0x71,0x6F,0xE0,0xF0,0x23,0x41,0x11,0xBE,0x5D,0xEF,0x44,0x14,0xC0,0x5B,0x17}
+#define IID_IDeckLinkMutableVideoFrame /* 69E2639F-40DA-4E19-B6F2-20ACE815C390 */ (REFIID){0x69,0xE2,0x63,0x9F,0x40,0xDA,0x4E,0x19,0xB6,0xF2,0x20,0xAC,0xE8,0x15,0xC3,0x90}
+#define IID_IDeckLinkVideoFrame3DExtensions /* DA0F7E4A-EDC7-48A8-9CDD-2DB51C729CD7 */ (REFIID){0xDA,0x0F,0x7E,0x4A,0xED,0xC7,0x48,0xA8,0x9C,0xDD,0x2D,0xB5,0x1C,0x72,0x9C,0xD7}
+#define IID_IDeckLinkVideoInputFrame /* 05CFE374-537C-4094-9A57-680525118F44 */ (REFIID){0x05,0xCF,0xE3,0x74,0x53,0x7C,0x40,0x94,0x9A,0x57,0x68,0x05,0x25,0x11,0x8F,0x44}
+#define IID_IDeckLinkVideoFrameAncillary /* 732E723C-D1A4-4E29-9E8E-4A88797A0004 */ (REFIID){0x73,0x2E,0x72,0x3C,0xD1,0xA4,0x4E,0x29,0x9E,0x8E,0x4A,0x88,0x79,0x7A,0x00,0x04}
+#define IID_IDeckLinkAudioInputPacket /* E43D5870-2894-11DE-8C30-0800200C9A66 */ (REFIID){0xE4,0x3D,0x58,0x70,0x28,0x94,0x11,0xDE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66}
+#define IID_IDeckLinkScreenPreviewCallback /* B1D3F49A-85FE-4C5D-95C8-0B5D5DCCD438 */ (REFIID){0xB1,0xD3,0xF4,0x9A,0x85,0xFE,0x4C,0x5D,0x95,0xC8,0x0B,0x5D,0x5D,0xCC,0xD4,0x38}
+#define IID_IDeckLinkCocoaScreenPreviewCallback /* D174152F-8F96-4C07-83A5-DD5F5AF0A2AA */ (REFIID){0xD1,0x74,0x15,0x2F,0x8F,0x96,0x4C,0x07,0x83,0xA5,0xDD,0x5F,0x5A,0xF0,0xA2,0xAA}
+#define IID_IDeckLinkGLScreenPreviewHelper /* 504E2209-CAC7-4C1A-9FB4-C5BB6274D22F */ (REFIID){0x50,0x4E,0x22,0x09,0xCA,0xC7,0x4C,0x1A,0x9F,0xB4,0xC5,0xBB,0x62,0x74,0xD2,0x2F}
+#define IID_IDeckLinkConfiguration /* C679A35B-610C-4D09-B748-1D0478100FC0 */ (REFIID){0xC6,0x79,0xA3,0x5B,0x61,0x0C,0x4D,0x09,0xB7,0x48,0x1D,0x04,0x78,0x10,0x0F,0xC0}
+#define IID_IDeckLinkAttributes /* ABC11843-D966-44CB-96E2-A1CB5D3135C4 */ (REFIID){0xAB,0xC1,0x18,0x43,0xD9,0x66,0x44,0xCB,0x96,0xE2,0xA1,0xCB,0x5D,0x31,0x35,0xC4}
+#define IID_IDeckLinkKeyer /* 89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3 */ (REFIID){0x89,0xAF,0xCA,0xF5,0x65,0xF8,0x42,0x1E,0x98,0xF7,0x96,0xFE,0x5F,0x5B,0xFB,0xA3}
+#define IID_IDeckLinkVideoConversion /* 3BBCB8A2-DA2C-42D9-B5D8-88083644E99A */ (REFIID){0x3B,0xBC,0xB8,0xA2,0xDA,0x2C,0x42,0xD9,0xB5,0xD8,0x88,0x08,0x36,0x44,0xE9,0x9A}
+#define IID_IDeckLinkDeckControlStatusCallback /* E5F693C1-4283-4716-B18F-C1431521955B */ (REFIID){0xE5,0xF6,0x93,0xC1,0x42,0x83,0x47,0x16,0xB1,0x8F,0xC1,0x43,0x15,0x21,0x95,0x5B}
+#define IID_IDeckLinkDeckControl /* 522A9E39-0F3C-4742-94EE-D80DE335DA1D */ (REFIID){0x52,0x2A,0x9E,0x39,0x0F,0x3C,0x47,0x42,0x94,0xEE,0xD8,0x0D,0xE3,0x35,0xDA,0x1D}
+
+
+/* Enum BMDDisplayMode - Video display modes */
+
+typedef uint32_t BMDDisplayMode;
+enum _BMDDisplayMode {
+
+ /* SD Modes */
+
+ bmdModeNTSC = 'ntsc',
+ bmdModeNTSC2398 = 'nt23', // 3:2 pulldown
+ bmdModePAL = 'pal ',
+ bmdModeNTSCp = 'ntsp',
+ bmdModePALp = 'palp',
+
+ /* HD 1080 Modes */
+
+ bmdModeHD1080p2398 = '23ps',
+ bmdModeHD1080p24 = '24ps',
+ bmdModeHD1080p25 = 'Hp25',
+ bmdModeHD1080p2997 = 'Hp29',
+ bmdModeHD1080p30 = 'Hp30',
+ bmdModeHD1080i50 = 'Hi50',
+ bmdModeHD1080i5994 = 'Hi59',
+ bmdModeHD1080i6000 = 'Hi60', // N.B. This _really_ is 60.00 Hz.
+ bmdModeHD1080p50 = 'Hp50',
+ bmdModeHD1080p5994 = 'Hp59',
+ bmdModeHD1080p6000 = 'Hp60', // N.B. This _really_ is 60.00 Hz.
+
+ /* HD 720 Modes */
+
+ bmdModeHD720p50 = 'hp50',
+ bmdModeHD720p5994 = 'hp59',
+ bmdModeHD720p60 = 'hp60',
+
+ /* 2k Modes */
+
+ bmdMode2k2398 = '2k23',
+ bmdMode2k24 = '2k24',
+ bmdMode2k25 = '2k25'
+};
+
+
+/* Enum BMDFieldDominance - Video field dominance */
+
+typedef uint32_t BMDFieldDominance;
+enum _BMDFieldDominance {
+ bmdUnknownFieldDominance = 0,
+ bmdLowerFieldFirst = 'lowr',
+ bmdUpperFieldFirst = 'uppr',
+ bmdProgressiveFrame = 'prog',
+ bmdProgressiveSegmentedFrame = 'psf '
+};
+
+
+/* Enum BMDPixelFormat - Video pixel formats supported for output/input */
+
+typedef uint32_t BMDPixelFormat;
+enum _BMDPixelFormat {
+ bmdFormat8BitYUV = '2vuy',
+ bmdFormat10BitYUV = 'v210',
+ bmdFormat8BitARGB = 32,
+ bmdFormat8BitBGRA = 'BGRA',
+ bmdFormat10BitRGB = 'r210' // Big-endian RGB 10-bit per component with SMPTE video levels (64-960). Packed as 2:10:10:10
+};
+
+
+/* Enum BMDDisplayModeFlags - Flags to describe the characteristics of an IDeckLinkDisplayMode. */
+
+typedef uint32_t BMDDisplayModeFlags;
+enum _BMDDisplayModeFlags {
+ bmdDisplayModeSupports3D = 1 << 0,
+ bmdDisplayModeColorspaceRec601 = 1 << 1,
+ bmdDisplayModeColorspaceRec709 = 1 << 2
+};
+
+
+/* Enum BMDVideoOutputFlags - Flags to control the output of ancillary data along with video. */
+
+typedef uint32_t BMDVideoOutputFlags;
+enum _BMDVideoOutputFlags {
+ bmdVideoOutputFlagDefault = 0,
+ bmdVideoOutputVANC = 1 << 0,
+ bmdVideoOutputVITC = 1 << 1,
+ bmdVideoOutputRP188 = 1 << 2,
+ bmdVideoOutputDualStream3D = 1 << 4
+};
+
+
+/* Enum BMDFrameFlags - Frame flags */
+
+typedef uint32_t BMDFrameFlags;
+enum _BMDFrameFlags {
+ bmdFrameFlagDefault = 0,
+ bmdFrameFlagFlipVertical = 1 << 0,
+
+ /* Flags that are applicable only to instances of IDeckLinkVideoInputFrame */
+
+ bmdFrameHasNoInputSource = 1 << 31
+};
+
+
+/* Enum BMDVideoInputFlags - Flags applicable to video input */
+
+typedef uint32_t BMDVideoInputFlags;
+enum _BMDVideoInputFlags {
+ bmdVideoInputFlagDefault = 0,
+ bmdVideoInputEnableFormatDetection = 1 << 0,
+ bmdVideoInputDualStream3D = 1 << 1
+};
+
+
+/* Enum BMDVideoInputFormatChangedEvents - Bitmask passed to the VideoInputFormatChanged notification to identify the properties of the input signal that have changed */
+
+typedef uint32_t BMDVideoInputFormatChangedEvents;
+enum _BMDVideoInputFormatChangedEvents {
+ bmdVideoInputDisplayModeChanged = 1 << 0,
+ bmdVideoInputFieldDominanceChanged = 1 << 1,
+ bmdVideoInputColorspaceChanged = 1 << 2
+};
+
+
+/* Enum BMDDetectedVideoInputFormatFlags - Flags passed to the VideoInputFormatChanged notification to describe the detected video input signal */
+
+typedef uint32_t BMDDetectedVideoInputFormatFlags;
+enum _BMDDetectedVideoInputFormatFlags {
+ bmdDetectedVideoInputYCbCr422 = 1 << 0,
+ bmdDetectedVideoInputRGB444 = 1 << 1
+};
+
+
+/* Enum BMDOutputFrameCompletionResult - Frame Completion Callback */
+
+typedef uint32_t BMDOutputFrameCompletionResult;
+enum _BMDOutputFrameCompletionResult {
+ bmdOutputFrameCompleted,
+ bmdOutputFrameDisplayedLate,
+ bmdOutputFrameDropped,
+ bmdOutputFrameFlushed
+};
+
+
+/* Enum BMDReferenceStatus - GenLock input status */
+
+typedef uint32_t BMDReferenceStatus;
+enum _BMDReferenceStatus {
+ bmdReferenceNotSupportedByHardware = 1 << 0,
+ bmdReferenceLocked = 1 << 1
+};
+
+
+/* Enum BMDAudioSampleRate - Audio sample rates supported for output/input */
+
+typedef uint32_t BMDAudioSampleRate;
+enum _BMDAudioSampleRate {
+ bmdAudioSampleRate48kHz = 48000
+};
+
+
+/* Enum BMDAudioSampleType - Audio sample sizes supported for output/input */
+
+typedef uint32_t BMDAudioSampleType;
+enum _BMDAudioSampleType {
+ bmdAudioSampleType16bitInteger = 16,
+ bmdAudioSampleType32bitInteger = 32
+};
+
+
+/* Enum BMDAudioOutputStreamType - Audio output stream type */
+
+typedef uint32_t BMDAudioOutputStreamType;
+enum _BMDAudioOutputStreamType {
+ bmdAudioOutputStreamContinuous,
+ bmdAudioOutputStreamContinuousDontResample,
+ bmdAudioOutputStreamTimestamped
+};
+
+
+/* Enum BMDDisplayModeSupport - Output mode supported flags */
+
+typedef uint32_t BMDDisplayModeSupport;
+enum _BMDDisplayModeSupport {
+ bmdDisplayModeNotSupported = 0,
+ bmdDisplayModeSupported,
+ bmdDisplayModeSupportedWithConversion
+};
+
+
+/* Enum BMDTimecodeFormat - Timecode formats for frame metadata */
+
+typedef uint32_t BMDTimecodeFormat;
+enum _BMDTimecodeFormat {
+ bmdTimecodeRP188 = 'rp18',
+ bmdTimecodeRP188Field2 = 'rp12',
+ bmdTimecodeVITC = 'vitc',
+ bmdTimecodeVITCField2 = 'vit2',
+ bmdTimecodeSerial = 'seri'
+};
+
+
+/* Enum BMDTimecodeFlags - Timecode flags */
+
+typedef uint32_t BMDTimecodeFlags;
+enum _BMDTimecodeFlags {
+ bmdTimecodeFlagDefault = 0,
+ bmdTimecodeIsDropFrame = 1 << 0
+};
+
+
+/* Enum BMDVideoConnection - Video connection types */
+
+typedef uint32_t BMDVideoConnection;
+enum _BMDVideoConnection {
+ bmdVideoConnectionSDI = 1 << 0,
+ bmdVideoConnectionHDMI = 1 << 1,
+ bmdVideoConnectionOpticalSDI = 1 << 2,
+ bmdVideoConnectionComponent = 1 << 3,
+ bmdVideoConnectionComposite = 1 << 4,
+ bmdVideoConnectionSVideo = 1 << 5
+};
+
+
+/* Enum BMDAnalogVideoFlags - Analog video display flags */
+
+typedef uint32_t BMDAnalogVideoFlags;
+enum _BMDAnalogVideoFlags {
+ bmdAnalogVideoFlagCompositeSetup75 = 1 << 0,
+ bmdAnalogVideoFlagComponentBetacamLevels = 1 << 1
+};
+
+
+/* Enum BMDAudioConnection - Audio connection types */
+
+typedef uint32_t BMDAudioConnection;
+enum _BMDAudioConnection {
+ bmdAudioConnectionEmbedded = 'embd',
+ bmdAudioConnectionAESEBU = 'aes ',
+ bmdAudioConnectionAnalog = 'anlg'
+};
+
+
+/* Enum BMDAudioOutputAnalogAESSwitch - Audio output Analog/AESEBU switch */
+
+typedef uint32_t BMDAudioOutputAnalogAESSwitch;
+enum _BMDAudioOutputAnalogAESSwitch {
+ bmdAudioOutputSwitchAESEBU = 'aes ',
+ bmdAudioOutputSwitchAnalog = 'anlg'
+};
+
+
+/* Enum BMDVideoOutputConversionMode - Video/audio conversion mode */
+
+typedef uint32_t BMDVideoOutputConversionMode;
+enum _BMDVideoOutputConversionMode {
+ bmdNoVideoOutputConversion = 'none',
+ bmdVideoOutputLetterboxDownconversion = 'ltbx',
+ bmdVideoOutputAnamorphicDownconversion = 'amph',
+ bmdVideoOutputHD720toHD1080Conversion = '720c',
+ bmdVideoOutputHardwareLetterboxDownconversion = 'HWlb',
+ bmdVideoOutputHardwareAnamorphicDownconversion = 'HWam',
+ bmdVideoOutputHardwareCenterCutDownconversion = 'HWcc',
+ bmdVideoOutputHardware720p1080pCrossconversion = 'xcap',
+ bmdVideoOutputHardwareAnamorphic720pUpconversion = 'ua7p',
+ bmdVideoOutputHardwareAnamorphic1080iUpconversion = 'ua1i',
+ bmdVideoOutputHardwareAnamorphic149To720pUpconversion = 'u47p',
+ bmdVideoOutputHardwareAnamorphic149To1080iUpconversion = 'u41i',
+ bmdVideoOutputHardwarePillarbox720pUpconversion = 'up7p',
+ bmdVideoOutputHardwarePillarbox1080iUpconversion = 'up1i'
+};
+
+
+/* Enum BMDVideoInputConversionMode - Video input conversion mode */
+
+typedef uint32_t BMDVideoInputConversionMode;
+enum _BMDVideoInputConversionMode {
+ bmdNoVideoInputConversion = 'none',
+ bmdVideoInputLetterboxDownconversionFromHD1080 = '10lb',
+ bmdVideoInputAnamorphicDownconversionFromHD1080 = '10am',
+ bmdVideoInputLetterboxDownconversionFromHD720 = '72lb',
+ bmdVideoInputAnamorphicDownconversionFromHD720 = '72am',
+ bmdVideoInputLetterboxUpconversion = 'lbup',
+ bmdVideoInputAnamorphicUpconversion = 'amup'
+};
+
+
+/* Enum BMDVideo3DPackingFormat - Video 3D packing format */
+
+typedef uint32_t BMDVideo3DPackingFormat;
+enum _BMDVideo3DPackingFormat {
+ bmdVideo3DPackingSidebySideHalf = 'sbsh',
+ bmdVideo3DPackingLinebyLine = 'lbyl',
+ bmdVideo3DPackingTopAndBottom = 'tabo',
+ bmdVideo3DPackingFramePacking = 'frpk',
+ bmdVideo3DPackingLeftOnly = 'left',
+ bmdVideo3DPackingRightOnly = 'righ'
+};
+
+
+/* Enum BMDIdleVideoOutputOperation - Video output operation when not playing video */
+
+typedef uint32_t BMDIdleVideoOutputOperation;
+enum _BMDIdleVideoOutputOperation {
+ bmdIdleVideoOutputBlack = 'blac',
+ bmdIdleVideoOutputLastFrame = 'lafa'
+};
+
+
+/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */
+
+typedef uint32_t BMDDeckLinkConfigurationID;
+enum _BMDDeckLinkConfigurationID {
+
+ /* Serial port Flags */
+
+ bmdDeckLinkConfigSwapSerialRxTx = 'ssrt',
+
+ /* Video Input/Output Flags */
+
+ bmdDeckLinkConfigUse1080pNotPsF = 'fpro',
+
+ /* Video Input/Output Integers */
+
+ bmdDeckLinkConfigHDMI3DPackingFormat = '3dpf',
+ bmdDeckLinkConfigBypass = 'byps',
+
+ /* Audio Input/Output Flags */
+
+ bmdDeckLinkConfigAnalogAudioConsumerLevels = 'aacl',
+
+ /* Video output flags */
+
+ bmdDeckLinkConfigFieldFlickerRemoval = 'fdfr',
+ bmdDeckLinkConfigHD1080p24ToHD1080i5994Conversion = 'to59',
+ bmdDeckLinkConfig444SDIVideoOutput = '444o',
+ bmdDeckLinkConfig3GBpsVideoOutput = '3gbs',
+ bmdDeckLinkConfigBlackVideoOutputDuringCapture = 'bvoc',
+ bmdDeckLinkConfigLowLatencyVideoOutput = 'llvo',
+
+ /* Video Output Integers */
+
+ bmdDeckLinkConfigVideoOutputConnection = 'vocn',
+ bmdDeckLinkConfigVideoOutputConversionMode = 'vocm',
+ bmdDeckLinkConfigAnalogVideoOutputFlags = 'avof',
+ bmdDeckLinkConfigReferenceInputTimingOffset = 'glot',
+ bmdDeckLinkConfigVideoOutputIdleOperation = 'voio',
+
+ /* Video Output Floats */
+
+ bmdDeckLinkConfigVideoOutputComponentLumaGain = 'oclg',
+ bmdDeckLinkConfigVideoOutputComponentChromaBlueGain = 'occb',
+ bmdDeckLinkConfigVideoOutputComponentChromaRedGain = 'occr',
+ bmdDeckLinkConfigVideoOutputCompositeLumaGain = 'oilg',
+ bmdDeckLinkConfigVideoOutputCompositeChromaGain = 'oicg',
+ bmdDeckLinkConfigVideoOutputSVideoLumaGain = 'oslg',
+ bmdDeckLinkConfigVideoOutputSVideoChromaGain = 'oscg',
+
+ /* Video Input Integers */
+
+ bmdDeckLinkConfigVideoInputConnection = 'vicn',
+ bmdDeckLinkConfigAnalogVideoInputFlags = 'avif',
+ bmdDeckLinkConfigVideoInputConversionMode = 'vicm',
+ bmdDeckLinkConfig32PulldownSequenceInitialTimecodeFrame = 'pdif',
+ bmdDeckLinkConfigVANCSourceLine1Mapping = 'vsl1',
+ bmdDeckLinkConfigVANCSourceLine2Mapping = 'vsl2',
+ bmdDeckLinkConfigVANCSourceLine3Mapping = 'vsl3',
+
+ /* Video Input Floats */
+
+ bmdDeckLinkConfigVideoInputComponentLumaGain = 'iclg',
+ bmdDeckLinkConfigVideoInputComponentChromaBlueGain = 'iccb',
+ bmdDeckLinkConfigVideoInputComponentChromaRedGain = 'iccr',
+ bmdDeckLinkConfigVideoInputCompositeLumaGain = 'iilg',
+ bmdDeckLinkConfigVideoInputCompositeChromaGain = 'iicg',
+ bmdDeckLinkConfigVideoInputSVideoLumaGain = 'islg',
+ bmdDeckLinkConfigVideoInputSVideoChromaGain = 'iscg',
+
+ /* Audio Input Integers */
+
+ bmdDeckLinkConfigAudioInputConnection = 'aicn',
+
+ /* Audio Input Floats */
+
+ bmdDeckLinkConfigAnalogAudioInputScaleChannel1 = 'ais1',
+ bmdDeckLinkConfigAnalogAudioInputScaleChannel2 = 'ais2',
+ bmdDeckLinkConfigAnalogAudioInputScaleChannel3 = 'ais3',
+ bmdDeckLinkConfigAnalogAudioInputScaleChannel4 = 'ais4',
+ bmdDeckLinkConfigDigitalAudioInputScale = 'dais',
+
+ /* Audio Output Integers */
+
+ bmdDeckLinkConfigAudioOutputAESAnalogSwitch = 'aoaa',
+
+ /* Audio Output Floats */
+
+ bmdDeckLinkConfigAnalogAudioOutputScaleChannel1 = 'aos1',
+ bmdDeckLinkConfigAnalogAudioOutputScaleChannel2 = 'aos2',
+ bmdDeckLinkConfigAnalogAudioOutputScaleChannel3 = 'aos3',
+ bmdDeckLinkConfigAnalogAudioOutputScaleChannel4 = 'aos4',
+ bmdDeckLinkConfigDigitalAudioOutputScale = 'daos'
+};
+
+
+/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */
+
+typedef uint32_t BMDDeckLinkAttributeID;
+enum _BMDDeckLinkAttributeID {
+
+ /* Flags */
+
+ BMDDeckLinkSupportsInternalKeying = 'keyi',
+ BMDDeckLinkSupportsExternalKeying = 'keye',
+ BMDDeckLinkSupportsHDKeying = 'keyh',
+ BMDDeckLinkSupportsInputFormatDetection = 'infd',
+ BMDDeckLinkHasReferenceInput = 'hrin',
+ BMDDeckLinkHasSerialPort = 'hspt',
+ BMDDeckLinkHasAnalogVideoOutputGain = 'avog',
+ BMDDeckLinkCanOnlyAdjustOverallVideoOutputGain = 'ovog',
+ BMDDeckLinkHasVideoInputAntiAliasingFilter = 'aafl',
+ BMDDeckLinkHasBypass = 'byps',
+
+ /* Integers */
+
+ BMDDeckLinkMaximumAudioChannels = 'mach',
+ BMDDeckLinkNumberOfSubDevices = 'nsbd',
+ BMDDeckLinkSubDeviceIndex = 'subi',
+ BMDDeckLinkVideoOutputConnections = 'vocn',
+ BMDDeckLinkVideoInputConnections = 'vicn',
+
+ /* Floats */
+
+ BMDDeckLinkVideoInputGainMinimum = 'vigm',
+ BMDDeckLinkVideoInputGainMaximum = 'vigx',
+ BMDDeckLinkVideoOutputGainMinimum = 'vogm',
+ BMDDeckLinkVideoOutputGainMaximum = 'vogx',
+
+ /* Strings */
+
+ BMDDeckLinkSerialPortDeviceName = 'slpn'
+};
+
+
+/* Enum BMDDeckLinkAPIInformationID - DeckLinkAPI information ID */
+
+typedef uint32_t BMDDeckLinkAPIInformationID;
+enum _BMDDeckLinkAPIInformationID {
+ BMDDeckLinkAPIVersion = 'vers'
+};
+
+
+/* Enum BMDDeckControlMode - DeckControl mode */
+
+typedef uint32_t BMDDeckControlMode;
+enum _BMDDeckControlMode {
+ bmdDeckControlNotOpened = 'ntop',
+ bmdDeckControlVTRControlMode = 'vtrc',
+ bmdDeckControlExportMode = 'expm',
+ bmdDeckControlCaptureMode = 'capm'
+};
+
+
+/* Enum BMDDeckControlEvent - DeckControl event */
+
+typedef uint32_t BMDDeckControlEvent;
+enum _BMDDeckControlEvent {
+ bmdDeckControlAbortedEvent = 'abte', // This event is triggered when a capture or edit-to-tape operation is aborted.
+
+ /* Export-To-Tape events */
+
+ bmdDeckControlPrepareForExportEvent = 'pfee', // This event is triggered a few frames before reaching the in-point. IDeckLinkInput::StartScheduledPlayback() should be called at this point.
+ bmdDeckControlExportCompleteEvent = 'exce', // This event is triggered a few frames after reaching the out-point. At this point, it is safe to stop playback.
+
+ /* Capture events */
+
+ bmdDeckControlPrepareForCaptureEvent = 'pfce', // This event is triggered a few frames before reaching the in-point. The serial timecode attached to IDeckLinkVideoInputFrames is now valid.
+ bmdDeckControlCaptureCompleteEvent = 'ccev' // This event is triggered a few frames after reaching the out-point.
+};
+
+
+/* Enum BMDDeckControlVTRControlState - VTR Control state */
+
+typedef uint32_t BMDDeckControlVTRControlState;
+enum _BMDDeckControlVTRControlState {
+ bmdDeckControlNotInVTRControlMode = 'nvcm',
+ bmdDeckControlVTRControlPlaying = 'vtrp',
+ bmdDeckControlVTRControlRecording = 'vtrr',
+ bmdDeckControlVTRControlStill = 'vtra',
+ bmdDeckControlVTRControlSeeking = 'vtrs',
+ bmdDeckControlVTRControlStopped = 'vtro'
+};
+
+
+/* Enum BMDDeckControlStatusFlags - Deck Control status flags */
+
+typedef uint32_t BMDDeckControlStatusFlags;
+enum _BMDDeckControlStatusFlags {
+ bmdDeckControlStatusDeckConnected = 1 << 0,
+ bmdDeckControlStatusRemoteMode = 1 << 1,
+ bmdDeckControlStatusRecordInhibited = 1 << 2,
+ bmdDeckControlStatusCassetteOut = 1 << 3
+};
+
+
+/* Enum BMDDeckControlExportModeOpsFlags - Export mode flags */
+
+typedef uint32_t BMDDeckControlExportModeOpsFlags;
+enum _BMDDeckControlExportModeOpsFlags {
+ bmdDeckControlExportModeInsertVideo = 1 << 0,
+ bmdDeckControlExportModeInsertAudio1 = 1 << 1,
+ bmdDeckControlExportModeInsertAudio2 = 1 << 2,
+ bmdDeckControlExportModeInsertAudio3 = 1 << 3,
+ bmdDeckControlExportModeInsertAudio4 = 1 << 4,
+ bmdDeckControlExportModeInsertAudio5 = 1 << 5,
+ bmdDeckControlExportModeInsertAudio6 = 1 << 6,
+ bmdDeckControlExportModeInsertAudio7 = 1 << 7,
+ bmdDeckControlExportModeInsertAudio8 = 1 << 8,
+ bmdDeckControlExportModeInsertAudio9 = 1 << 9,
+ bmdDeckControlExportModeInsertAudio10 = 1 << 10,
+ bmdDeckControlExportModeInsertAudio11 = 1 << 11,
+ bmdDeckControlExportModeInsertAudio12 = 1 << 12,
+ bmdDeckControlExportModeInsertTimeCode = 1 << 13,
+ bmdDeckControlExportModeInsertAssemble = 1 << 14,
+ bmdDeckControlExportModeInsertPreview = 1 << 15,
+ bmdDeckControlUseManualExport = 1 << 16
+};
+
+
+/* Enum BMDDeckControlError - Deck Control error */
+
+typedef uint32_t BMDDeckControlError;
+enum _BMDDeckControlError {
+ bmdDeckControlNoError = 'noer',
+ bmdDeckControlModeError = 'moer',
+ bmdDeckControlMissedInPointError = 'mier',
+ bmdDeckControlDeckTimeoutError = 'dter',
+ bmdDeckControlCommandFailedError = 'cfer',
+ bmdDeckControlDeviceAlreadyOpenedError = 'dalo',
+ bmdDeckControlFailedToOpenDeviceError = 'fder',
+ bmdDeckControlInLocalModeError = 'lmer',
+ bmdDeckControlEndOfTapeError = 'eter',
+ bmdDeckControlUserAbortError = 'uaer',
+ bmdDeckControlNoTapeInDeckError = 'nter',
+ bmdDeckControlNoVideoFromCardError = 'nvfc',
+ bmdDeckControlNoCommunicationError = 'ncom',
+ bmdDeckControlBufferTooSmallError = 'btsm',
+ bmdDeckControlBadChecksumError = 'chks',
+ bmdDeckControlUnknownError = 'uner'
+};
+
+
+/* Enum BMD3DPreviewFormat - Linked Frame preview format */
+
+typedef uint32_t BMD3DPreviewFormat;
+enum _BMD3DPreviewFormat {
+ bmd3DPreviewFormatDefault = 'defa',
+ bmd3DPreviewFormatLeftOnly = 'left',
+ bmd3DPreviewFormatRightOnly = 'righ',
+ bmd3DPreviewFormatSideBySide = 'side',
+ bmd3DPreviewFormatTopBottom = 'topb'
+};
+
+
+#if defined(__cplusplus)
+
+// Forward Declarations
+
+class IDeckLinkVideoOutputCallback;
+class IDeckLinkInputCallback;
+class IDeckLinkMemoryAllocator;
+class IDeckLinkAudioOutputCallback;
+class IDeckLinkIterator;
+class IDeckLinkAPIInformation;
+class IDeckLinkDisplayModeIterator;
+class IDeckLinkDisplayMode;
+class IDeckLink;
+class IDeckLinkOutput;
+class IDeckLinkInput;
+class IDeckLinkTimecode;
+class IDeckLinkVideoFrame;
+class IDeckLinkMutableVideoFrame;
+class IDeckLinkVideoFrame3DExtensions;
+class IDeckLinkVideoInputFrame;
+class IDeckLinkVideoFrameAncillary;
+class IDeckLinkAudioInputPacket;
+class IDeckLinkScreenPreviewCallback;
+class IDeckLinkCocoaScreenPreviewCallback;
+class IDeckLinkGLScreenPreviewHelper;
+class IDeckLinkConfiguration;
+class IDeckLinkAttributes;
+class IDeckLinkKeyer;
+class IDeckLinkVideoConversion;
+class IDeckLinkDeckControlStatusCallback;
+class IDeckLinkDeckControl;
+
+
+/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */
+
+class IDeckLinkVideoOutputCallback : public IUnknown
+{
+public:
+ virtual HRESULT ScheduledFrameCompleted (/* in */ IDeckLinkVideoFrame *completedFrame, /* in */ BMDOutputFrameCompletionResult result) = 0;
+ virtual HRESULT ScheduledPlaybackHasStopped (void) = 0;
+
+protected:
+ virtual ~IDeckLinkVideoOutputCallback () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkInputCallback - Frame arrival callback. */
+
+class IDeckLinkInputCallback : public IUnknown
+{
+public:
+ virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0;
+ virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame* videoFrame, /* in */ IDeckLinkAudioInputPacket* audioPacket) = 0;
+
+protected:
+ virtual ~IDeckLinkInputCallback () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */
+
+class IDeckLinkMemoryAllocator : public IUnknown
+{
+public:
+ virtual HRESULT AllocateBuffer (/* in */ uint32_t bufferSize, /* out */ void **allocatedBuffer) = 0;
+ virtual HRESULT ReleaseBuffer (/* in */ void *buffer) = 0;
+
+ virtual HRESULT Commit (void) = 0;
+ virtual HRESULT Decommit (void) = 0;
+};
+
+
+/* Interface IDeckLinkAudioOutputCallback - Optional callback to allow audio samples to be pulled as required. */
+
+class IDeckLinkAudioOutputCallback : public IUnknown
+{
+public:
+ virtual HRESULT RenderAudioSamples (/* in */ bool preroll) = 0;
+};
+
+
+/* Interface IDeckLinkIterator - enumerates installed DeckLink hardware */
+
+class IDeckLinkIterator : public IUnknown
+{
+public:
+ virtual HRESULT Next (/* out */ IDeckLink **deckLinkInstance) = 0;
+};
+
+
+/* Interface IDeckLinkAPIInformation - DeckLinkAPI attribute interface */
+
+class IDeckLinkAPIInformation : public IUnknown
+{
+public:
+ virtual HRESULT GetFlag (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ bool *value) = 0;
+ virtual HRESULT GetInt (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ int64_t *value) = 0;
+ virtual HRESULT GetFloat (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ double *value) = 0;
+ virtual HRESULT GetString (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ CFStringRef *value) = 0;
+
+protected:
+ virtual ~IDeckLinkAPIInformation () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */
+
+class IDeckLinkDisplayModeIterator : public IUnknown
+{
+public:
+ virtual HRESULT Next (/* out */ IDeckLinkDisplayMode **deckLinkDisplayMode) = 0;
+
+protected:
+ virtual ~IDeckLinkDisplayModeIterator () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkDisplayMode - represents a display mode */
+
+class IDeckLinkDisplayMode : public IUnknown
+{
+public:
+ virtual HRESULT GetName (/* out */ CFStringRef *name) = 0;
+ virtual BMDDisplayMode GetDisplayMode (void) = 0;
+ virtual long GetWidth (void) = 0;
+ virtual long GetHeight (void) = 0;
+ virtual HRESULT GetFrameRate (/* out */ BMDTimeValue *frameDuration, /* out */ BMDTimeScale *timeScale) = 0;
+ virtual BMDFieldDominance GetFieldDominance (void) = 0;
+ virtual BMDDisplayModeFlags GetFlags (void) = 0;
+
+protected:
+ virtual ~IDeckLinkDisplayMode () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLink - represents a DeckLink device */
+
+class IDeckLink : public IUnknown
+{
+public:
+ virtual HRESULT GetModelName (/* out */ CFStringRef *modelName) = 0;
+};
+
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkOutput : public IUnknown
+{
+public:
+ virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0;
+ virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0;
+
+ virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;
+
+ /* Video Output */
+
+ virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0;
+ virtual HRESULT DisableVideoOutput (void) = 0;
+
+ virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0;
+ virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame **outFrame) = 0;
+ virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0;
+
+ virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame *theFrame) = 0;
+ virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0;
+ virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0;
+ virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0;
+
+ /* Audio Output */
+
+ virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0;
+ virtual HRESULT DisableAudioOutput (void) = 0;
+
+ virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+ virtual HRESULT BeginAudioPreroll (void) = 0;
+ virtual HRESULT EndAudioPreroll (void) = 0;
+ virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+ virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0;
+ virtual HRESULT FlushBufferedAudioSamples (void) = 0;
+
+ virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0;
+
+ /* Output Control */
+
+ virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0;
+ virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0;
+ virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0;
+ virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0;
+ virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus *referenceStatus) = 0;
+
+ /* Hardware Timing */
+
+ virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+ virtual ~IDeckLinkOutput () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkInput : public IUnknown
+{
+public:
+ virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0;
+ virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0;
+
+ virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;
+
+ /* Video Input */
+
+ virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0;
+ virtual HRESULT DisableVideoInput (void) = 0;
+ virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0;
+
+ /* Audio Input */
+
+ virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0;
+ virtual HRESULT DisableAudioInput (void) = 0;
+ virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0;
+
+ /* Input Control */
+
+ virtual HRESULT StartStreams (void) = 0;
+ virtual HRESULT StopStreams (void) = 0;
+ virtual HRESULT PauseStreams (void) = 0;
+ virtual HRESULT FlushStreams (void) = 0;
+ virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback *theCallback) = 0;
+
+ /* Hardware Timing */
+
+ virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+ virtual ~IDeckLinkInput () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkTimecode - Used for video frame timecode representation. */
+
+class IDeckLinkTimecode : public IUnknown
+{
+public:
+ virtual BMDTimecodeBCD GetBCD (void) = 0;
+ virtual HRESULT GetComponents (/* out */ uint8_t *hours, /* out */ uint8_t *minutes, /* out */ uint8_t *seconds, /* out */ uint8_t *frames) = 0;
+ virtual HRESULT GetString (/* out */ CFStringRef *timecode) = 0;
+ virtual BMDTimecodeFlags GetFlags (void) = 0;
+ virtual HRESULT GetTimecodeUserBits (/* out */ BMDTimecodeUserBits *userBits) = 0;
+
+protected:
+ virtual ~IDeckLinkTimecode () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */
+
+class IDeckLinkVideoFrame : public IUnknown
+{
+public:
+ virtual long GetWidth (void) = 0;
+ virtual long GetHeight (void) = 0;
+ virtual long GetRowBytes (void) = 0;
+ virtual BMDPixelFormat GetPixelFormat (void) = 0;
+ virtual BMDFrameFlags GetFlags (void) = 0;
+ virtual HRESULT GetBytes (/* out */ void **buffer) = 0;
+
+ virtual HRESULT GetTimecode (/* in */ BMDTimecodeFormat format, /* out */ IDeckLinkTimecode **timecode) = 0;
+ virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary **ancillary) = 0;
+
+protected:
+ virtual ~IDeckLinkVideoFrame () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */
+
+class IDeckLinkMutableVideoFrame : public IDeckLinkVideoFrame
+{
+public:
+ virtual HRESULT SetFlags (/* in */ BMDFrameFlags newFlags) = 0;
+
+ virtual HRESULT SetTimecode (/* in */ BMDTimecodeFormat format, /* in */ IDeckLinkTimecode *timecode) = 0;
+ virtual HRESULT SetTimecodeFromComponents (/* in */ BMDTimecodeFormat format, /* in */ uint8_t hours, /* in */ uint8_t minutes, /* in */ uint8_t seconds, /* in */ uint8_t frames, /* in */ BMDTimecodeFlags flags) = 0;
+ virtual HRESULT SetAncillaryData (/* in */ IDeckLinkVideoFrameAncillary *ancillary) = 0;
+ virtual HRESULT SetTimecodeUserBits (/* in */ BMDTimecodeFormat format, /* in */ BMDTimecodeUserBits userBits) = 0;
+
+protected:
+ virtual ~IDeckLinkMutableVideoFrame () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoFrame3DExtensions - Optional interface implemented on IDeckLinkVideoFrame to support 3D frames */
+
+class IDeckLinkVideoFrame3DExtensions : public IUnknown
+{
+public:
+ virtual BMDVideo3DPackingFormat Get3DPackingFormat (void) = 0;
+ virtual HRESULT GetFrameForRightEye (/* out */ IDeckLinkVideoFrame* *rightEyeFrame) = 0;
+
+protected:
+ virtual ~IDeckLinkVideoFrame3DExtensions () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
+
+class IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame
+{
+public:
+ virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, /* in */ BMDTimeScale timeScale) = 0;
+ virtual HRESULT GetHardwareReferenceTimestamp (/* in */ BMDTimeScale timeScale, /* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration) = 0;
+
+protected:
+ virtual ~IDeckLinkVideoInputFrame () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoFrameAncillary - Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */
+
+class IDeckLinkVideoFrameAncillary : public IUnknown
+{
+public:
+
+ virtual HRESULT GetBufferForVerticalBlankingLine (/* in */ uint32_t lineNumber, /* out */ void **buffer) = 0;
+ virtual BMDPixelFormat GetPixelFormat (void) = 0;
+ virtual BMDDisplayMode GetDisplayMode (void) = 0;
+
+protected:
+ virtual ~IDeckLinkVideoFrameAncillary () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */
+
+class IDeckLinkAudioInputPacket : public IUnknown
+{
+public:
+ virtual long GetSampleFrameCount (void) = 0;
+ virtual HRESULT GetBytes (/* out */ void **buffer) = 0;
+ virtual HRESULT GetPacketTime (/* out */ BMDTimeValue *packetTime, /* in */ BMDTimeScale timeScale) = 0;
+
+protected:
+ virtual ~IDeckLinkAudioInputPacket () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */
+
+class IDeckLinkScreenPreviewCallback : public IUnknown
+{
+public:
+ virtual HRESULT DrawFrame (/* in */ IDeckLinkVideoFrame *theFrame) = 0;
+
+protected:
+ virtual ~IDeckLinkScreenPreviewCallback () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkCocoaScreenPreviewCallback - Screen preview callback for Cocoa-based applications */
+
+class IDeckLinkCocoaScreenPreviewCallback : public IDeckLinkScreenPreviewCallback
+{
+public:
+
+protected:
+ virtual ~IDeckLinkCocoaScreenPreviewCallback () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */
+
+class IDeckLinkGLScreenPreviewHelper : public IUnknown
+{
+public:
+
+ /* Methods must be called with OpenGL context set */
+
+ virtual HRESULT InitializeGL (void) = 0;
+ virtual HRESULT PaintGL (void) = 0;
+ virtual HRESULT SetFrame (/* in */ IDeckLinkVideoFrame *theFrame) = 0;
+ virtual HRESULT Set3DPreviewFormat (/* in */ BMD3DPreviewFormat previewFormat) = 0;
+
+protected:
+ virtual ~IDeckLinkGLScreenPreviewHelper () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkConfiguration - DeckLink Configuration interface */
+
+class IDeckLinkConfiguration : public IUnknown
+{
+public:
+ virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0;
+ virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0;
+ virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0;
+ virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0;
+ virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0;
+ virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0;
+ virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ CFStringRef value) = 0;
+ virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ CFStringRef *value) = 0;
+ virtual HRESULT WriteConfigurationToPreferences (void) = 0;
+
+protected:
+ virtual ~IDeckLinkConfiguration () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkAttributes - DeckLink Attribute interface */
+
+class IDeckLinkAttributes : public IUnknown
+{
+public:
+ virtual HRESULT GetFlag (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ bool *value) = 0;
+ virtual HRESULT GetInt (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ int64_t *value) = 0;
+ virtual HRESULT GetFloat (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ double *value) = 0;
+ virtual HRESULT GetString (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ CFStringRef *value) = 0;
+
+protected:
+ virtual ~IDeckLinkAttributes () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkKeyer - DeckLink Keyer interface */
+
+class IDeckLinkKeyer : public IUnknown
+{
+public:
+ virtual HRESULT Enable (/* in */ bool isExternal) = 0;
+ virtual HRESULT SetLevel (/* in */ uint8_t level) = 0;
+ virtual HRESULT RampUp (/* in */ uint32_t numberOfFrames) = 0;
+ virtual HRESULT RampDown (/* in */ uint32_t numberOfFrames) = 0;
+ virtual HRESULT Disable (void) = 0;
+
+protected:
+ virtual ~IDeckLinkKeyer () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoConversion - Created with CoCreateInstance(). */
+
+class IDeckLinkVideoConversion : public IUnknown
+{
+public:
+ virtual HRESULT ConvertFrame (/* in */ IDeckLinkVideoFrame* srcFrame, /* in */ IDeckLinkVideoFrame* dstFrame) = 0;
+
+protected:
+ virtual ~IDeckLinkVideoConversion () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkDeckControlStatusCallback - Deck control state change callback. */
+
+class IDeckLinkDeckControlStatusCallback : public IUnknown
+{
+public:
+ virtual HRESULT TimecodeUpdate (/* in */ BMDTimecodeBCD currentTimecode) = 0;
+ virtual HRESULT VTRControlStateChanged (/* in */ BMDDeckControlVTRControlState newState, /* in */ BMDDeckControlError error) = 0;
+ virtual HRESULT DeckControlEventReceived (/* in */ BMDDeckControlEvent event, /* in */ BMDDeckControlError error) = 0;
+ virtual HRESULT DeckControlStatusChanged (/* in */ BMDDeckControlStatusFlags flags, /* in */ uint32_t mask) = 0;
+
+protected:
+ virtual ~IDeckLinkDeckControlStatusCallback () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkDeckControl - Deck Control main interface */
+
+class IDeckLinkDeckControl : public IUnknown
+{
+public:
+ virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT Close (/* in */ bool standbyOn) = 0;
+ virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode *mode, /* out */ BMDDeckControlVTRControlState *vtrControlState, /* out */ BMDDeckControlStatusFlags *flags) = 0;
+ virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0;
+ virtual HRESULT SendCommand (/* in */ uint8_t *inBuffer, /* in */ uint32_t inBufferSize, /* out */ uint8_t *outBuffer, /* out */ uint32_t *outDataSize, /* in */ uint32_t outBufferSize, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT Play (/* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT Stop (/* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT Eject (/* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT StepForward (/* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT StepBack (/* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT GetTimecodeString (/* out */ CFStringRef *currentTimeCode, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode **currentTimecode, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD *currentTimecode, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0;
+ virtual HRESULT GetPreroll (/* out */ uint32_t *prerollSeconds) = 0;
+ virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0;
+ virtual HRESULT GetExportOffset (/* out */ int32_t *exportOffsetFields) = 0;
+ virtual HRESULT GetManualExportOffset (/* out */ int32_t *deckManualExportOffsetFields) = 0;
+ virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0;
+ virtual HRESULT GetCaptureOffset (/* out */ int32_t *captureOffsetFields) = 0;
+ virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT GetDeviceID (/* out */ uint16_t *deviceId, /* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT Abort (void) = 0;
+ virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0;
+ virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback *callback) = 0;
+
+protected:
+ virtual ~IDeckLinkDeckControl () {}; // call Release method to drop reference count
+};
+
+
+/* Functions */
+
+extern "C" {
+
+ IDeckLinkIterator* CreateDeckLinkIteratorInstance (void);
+ IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void);
+ IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void);
+ IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview (void* /* (NSView*) */ parentView);
+ IDeckLinkVideoConversion* CreateVideoConversionInstance (void);
+
+};
+
+
+#endif // defined(__cplusplus)
+#endif // __DeckLink_API_h__
--- /dev/null
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPIDispatch.cpp */
+
+#include "DeckLinkAPI.h"
+#include <pthread.h>
+
+#if BLACKMAGIC_DECKLINK_API_MAGIC != 1
+ #error The DeckLink API version of DeckLinkAPIDispatch.cpp is not the same version as DeckLinkAPI.h
+#endif
+
+#define kDeckLinkAPI_BundlePath "/Library/Application Support/Blackmagic Design/Blackmagic DeckLink/DeckLinkAPI.bundle"
+
+typedef IDeckLinkIterator* (*CreateIteratorFunc)(void);
+typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void);
+typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void);
+typedef IDeckLinkCocoaScreenPreviewCallback* (*CreateCocoaScreenPreviewFunc)(void*);
+typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void);
+
+static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT;
+static CFBundleRef gBundleRef = NULL;
+static CreateIteratorFunc gCreateIteratorFunc = NULL;
+static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL;
+static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL;
+static CreateCocoaScreenPreviewFunc gCreateCocoaPreviewFunc = NULL;
+static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL;
+
+
+void InitDeckLinkAPI (void)
+{
+ CFURLRef bundleURL;
+
+ bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true);
+ if (bundleURL != NULL)
+ {
+ gBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL);
+ if (gBundleRef != NULL)
+ {
+ gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0001"));
+ gCreateAPIInformationFunc = (CreateAPIInformationFunc)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateDeckLinkAPIInformationInstance_0001"));
+ gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper_0001"));
+ gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateCocoaScreenPreview_0001"));
+ gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateVideoConversionInstance_0001"));
+ }
+ CFRelease(bundleURL);
+ }
+}
+
+bool IsDeckLinkAPIPresent (void)
+{
+ // If the DeckLink API bundle was successfully loaded, return this knowledge to the caller
+ if (gBundleRef != NULL)
+ return true;
+
+ return false;
+}
+
+IDeckLinkIterator* CreateDeckLinkIteratorInstance (void)
+{
+ pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+ if (gCreateIteratorFunc == NULL)
+ return NULL;
+
+ return gCreateIteratorFunc();
+}
+
+IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void)
+{
+ pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+ if (gCreateAPIInformationFunc == NULL)
+ return NULL;
+
+ return gCreateAPIInformationFunc();
+}
+
+IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void)
+{
+ pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+ if (gCreateOpenGLPreviewFunc == NULL)
+ return NULL;
+
+ return gCreateOpenGLPreviewFunc();
+}
+
+IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview (void* parentView)
+{
+ pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+ if (gCreateCocoaPreviewFunc == NULL)
+ return NULL;
+
+ return gCreateCocoaPreviewFunc(parentView);
+}
+
+IDeckLinkVideoConversion* CreateVideoConversionInstance (void)
+{
+ pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+ if (gCreateVideoConversionFunc == NULL)
+ return NULL;
+
+ return gCreateVideoConversionFunc();
+}
+
#include <unistd.h>
#include <limits.h>
#include <sys/time.h>
-#ifdef WIN32
-#include <objbase.h>
-#include "DeckLinkAPI_h.h"
-#else
-#include "DeckLinkAPI.h"
-#endif
+#include "common.h"
class DeckLinkProducer
: public IDeckLinkInputCallback
BMDDisplayMode getDisplayMode( mlt_profile profile, int vancLines )
{
- IDeckLinkDisplayModeIterator* iter;
- IDeckLinkDisplayMode* mode;
+ IDeckLinkDisplayModeIterator* iter = NULL;
+ IDeckLinkDisplayMode* mode = NULL;
BMDDisplayMode result = (BMDDisplayMode) bmdDisplayModeNotSupported;
if ( m_decklinkInput->GetDisplayModeIterator( &iter ) == S_OK )
if ( width == profile->width && p == profile->progressive
&& ( height + vancLines == profile->height || ( height == 486 && profile->height == 480 + vancLines ) )
- && fps == mlt_profile_fps( profile ) )
+ && (int) fps == (int) mlt_profile_fps( profile ) )
result = mode->GetDisplayMode();
+ SAFE_RELEASE( mode );
}
+ SAFE_RELEASE( iter );
}
return result;
mlt_producer getProducer() const
{ return m_producer; }
+ DeckLinkProducer()
+ {
+ m_producer = NULL;
+ m_decklink = NULL;
+ m_decklinkInput = NULL;
+ }
+
~DeckLinkProducer()
{
if ( m_queue )
pthread_cond_destroy( &m_condition );
mlt_cache_close( m_cache );
}
- if ( m_decklinkInput )
- m_decklinkInput->Release();
- if ( m_decklink )
- m_decklink->Release();
+ SAFE_RELEASE( m_decklinkInput );
+ SAFE_RELEASE( m_decklink );
}
bool open( unsigned card = 0 )
if ( !decklinkIterator )
throw "The DeckLink drivers are not installed.";
#endif
-
// Connect to the Nth DeckLink instance
- unsigned i = 0;
- do {
- if ( decklinkIterator->Next( &m_decklink ) != S_OK )
- throw "DeckLink card not found.";
- } while ( ++i <= card );
- decklinkIterator->Release();
+ for ( unsigned i = 0; decklinkIterator->Next( &m_decklink ) == S_OK ; i++)
+ {
+ if ( i == card )
+ break;
+ else
+ SAFE_RELEASE( m_decklink );
+ }
+ SAFE_RELEASE( decklinkIterator );
+ if ( !m_decklink )
+ throw "DeckLink card not found.";
// Get the input interface
if ( m_decklink->QueryInterface( IID_IDeckLinkInput, (void**) &m_decklinkInput ) != S_OK )
}
catch ( const char *error )
{
- if ( decklinkIterator )
- decklinkIterator->Release();
+ SAFE_RELEASE( m_decklinkInput );
+ SAFE_RELEASE( m_decklink );
mlt_log_error( getProducer(), "%s\n", error );
return false;
}
{
if ( decklinkAttributes->GetFlag( BMDDeckLinkSupportsInputFormatDetection, &doesDetectFormat ) != S_OK )
doesDetectFormat = false;
- decklinkAttributes->Release();
+ SAFE_RELEASE( decklinkAttributes );
}
mlt_log_verbose( getProducer(), "%s format detection\n", doesDetectFormat ? "supports" : "does not support" );
pthread_mutex_unlock( &m_mutex );
m_decklinkInput->StopStreams();
+ m_decklinkInput->DisableVideoInput();
+ m_decklinkInput->DisableAudioInput();
// Cleanup queue
pthread_mutex_lock( &m_mutex );
mlt_frame getFrame()
{
- mlt_frame frame = NULL;
struct timeval now;
struct timespec tm;
double fps = mlt_producer_get_fps( getProducer() );
mlt_position position = mlt_producer_position( getProducer() );
- mlt_cache_item cached = mlt_cache_get( m_cache, (void*) position );
+ mlt_frame frame = mlt_cache_get_frame( m_cache, position );
// Allow the buffer to fill to the requested initial buffer level.
if ( m_isBuffering )
pthread_mutex_unlock( &m_mutex );
}
- if ( cached )
- {
- // Copy cached frame instead of pulling from queue
- frame = mlt_frame_clone( (mlt_frame) mlt_cache_item_data( cached, NULL ), 0 );
- mlt_cache_item_close( cached );
- }
- else
+ if ( !frame )
{
// Wait if queue is empty
pthread_mutex_lock( &m_mutex );
// add to cache
if ( frame )
- mlt_cache_put( m_cache, (void*) position, mlt_frame_clone( frame, 1 ), 0,
- (mlt_destructor) mlt_frame_close );
+ {
+ mlt_frame_set_position( frame, position );
+ mlt_cache_put_frame( m_cache, frame );
+ }
}
// Set frame timestamp and properties
mlt_properties_set_int( properties, "meta.media.frame_rate_num", profile->frame_rate_num );
mlt_properties_set_int( properties, "meta.media.frame_rate_den", profile->frame_rate_den );
mlt_properties_set_int( properties, "width", profile->width );
- mlt_properties_set_int( properties, "real_width", profile->width );
mlt_properties_set_int( properties, "meta.media.width", profile->width );
mlt_properties_set_int( properties, "height", profile->height );
- mlt_properties_set_int( properties, "real_height", profile->height );
mlt_properties_set_int( properties, "meta.media.height", profile->height );
mlt_properties_set_int( properties, "format", mlt_image_yuv422 );
mlt_properties_set_int( properties, "colorspace", m_colorspace );
IDeckLinkVideoInputFrame* video,
IDeckLinkAudioInputPacket* audio )
{
+ if ( mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "preview" ) &&
+ mlt_producer_get_speed( getProducer() ) == 0.0 && !mlt_deque_count( m_queue ))
+ {
+ pthread_cond_broadcast( &m_condition );
+ return S_OK;
+ }
+
// Create mlt_frame
mlt_frame frame = mlt_frame_init( MLT_PRODUCER_SERVICE( getProducer() ) );
else
mlt_log_debug( getProducer(), "failed capture vanc line %d\n", i );
}
- vanc->Release();
+ SAFE_RELEASE(vanc);
}
}
IDeckLinkTimecode* timecode = 0;
if ( video->GetTimecode( bmdTimecodeVITC, &timecode ) == S_OK && timecode )
{
- const char* timecodeString = 0;
+ DLString timecodeString = 0;
-#ifdef WIN32
- if ( timecode->GetString( (BSTR*) &timecodeString ) == S_OK )
-#else
if ( timecode->GetString( &timecodeString ) == S_OK )
-#endif
{
- mlt_properties_set( MLT_FRAME_PROPERTIES( frame ), "meta.attr.vitc.markup", timecodeString );
- mlt_log_debug( getProducer(), "timecode %s\n", timecodeString );
+ char* s = getCString( timecodeString );
+ mlt_properties_set( MLT_FRAME_PROPERTIES( frame ), "meta.attr.vitc.markup", s );
+ mlt_log_debug( getProducer(), "timecode %s\n", s );
+ freeCString( s );
}
- if ( timecodeString )
- free( (void*) timecodeString );
- timecode->Release();
+ freeDLString( timecodeString );
+ SAFE_RELEASE( timecode );
}
}
else
*frame = mlt_frame_init( MLT_PRODUCER_SERVICE(producer) );
// Calculate the next timecode
- mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
mlt_producer_prepare_next( producer );
// Close DeckLink if at end
extern "C" {
+// Listen for the list_devices property to be set
+static void on_property_changed( void*, mlt_properties properties, const char *name )
+{
+ IDeckLinkIterator* decklinkIterator = NULL;
+ IDeckLink* decklink = NULL;
+ IDeckLinkInput* decklinkInput = NULL;
+ int i = 0;
+
+ if ( name && !strcmp( name, "list_devices" ) )
+ mlt_event_block( (mlt_event) mlt_properties_get_data( properties, "list-devices-event", NULL ) );
+ else
+ return;
+
+#ifdef WIN32
+ if ( FAILED( CoInitialize( NULL ) ) )
+ return;
+ if ( FAILED( CoCreateInstance( CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**) &decklinkIterator ) ) )
+ return;
+#else
+ if ( !( decklinkIterator = CreateDeckLinkIteratorInstance() ) )
+ return;
+#endif
+ for ( ; decklinkIterator->Next( &decklink ) == S_OK; i++ )
+ {
+ if ( decklink->QueryInterface( IID_IDeckLinkInput, (void**) &decklinkInput ) == S_OK )
+ {
+ DLString name = NULL;
+ if ( decklink->GetModelName( &name ) == S_OK )
+ {
+ char *name_cstr = getCString( name );
+ const char *format = "device.%d";
+ char *key = (char*) calloc( 1, strlen( format ) + 1 );
+
+ sprintf( key, format, i );
+ mlt_properties_set( properties, key, name_cstr );
+ free( key );
+ freeDLString( name );
+ freeCString( name_cstr );
+ }
+ SAFE_RELEASE( decklinkInput );
+ }
+ SAFE_RELEASE( decklink );
+ }
+ SAFE_RELEASE( decklinkIterator );
+ mlt_properties_set_int( properties, "devices", i );
+}
+
/** Initialise the producer.
*/
mlt_properties_set_int( properties, "length", INT_MAX );
mlt_properties_set_int( properties, "out", INT_MAX - 1 );
mlt_properties_set( properties, "eof", "loop" );
+
+ mlt_event event = mlt_events_listen( properties, properties, "property-changed", (mlt_listener) on_property_changed );
+ mlt_properties_set_data( properties, "list-devices-event", event, 0, NULL, NULL );
}
}
default: 0
unit: lines
widget: spinner
+
+ - identifier: preview
+ title: Enable preview
+ description: Support preview monitoring when paused (speed = 0).
+ type: integer
+ minimum: 0
+ maximum: 1
+ default: 0
+ widget: checkbox
+
+ - identifier: devices
+ title: Number of devices
+ type: integer
+ readonly: yes
+ minimum: 0
+
+ - identifier: device.*
+ title: Device model
+ description: The model name of each device that accepts input.
+ type: string
+ readonly: yes
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
ifneq ($(wildcard .depend),)
include .depend
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/dv"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/dv"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/dv"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/dv"
ifneq ($(wildcard .depend),)
include .depend
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 );
+ producer_libdv this = calloc( 1, sizeof( struct producer_libdv_s ) );
if ( filename != NULL && this != NULL && mlt_producer_init( &this->parent, this ) == 0 )
{
aspect_ratio = 8 / 9;
}
mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio);
- 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.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" );
+ mlt_properties_set_int( properties, "meta.media.width", 720 );
+ mlt_properties_set_int( properties, "meta.media.height", this->is_pal ? 576 : 480 );
+ mlt_properties_set_int( properties, "meta.media.frame_rate_num", this->is_pal? 25 : 30000 );
+ mlt_properties_set_int( properties, "meta.media.frame_rate_den", this->is_pal? 1 : 1001 );
// Return the decoder
dv_decoder_return( dv_decoder );
// 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 );
mlt_properties_set_int( properties, "colorspace", 601 );
}
// Update timecode on the frame we're creating
- mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
+ if ( *frame != NULL )
+ mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
// Calculate the next timecode
mlt_producer_prepare_next( producer );
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/effectv"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/effectv"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/effectv"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/effectv"
ifneq ($(wildcard .depend),)
include .depend
clean:
install: all
- install -d "$(DESTDIR)$(datadir)/mlt/feeds/PAL"
- install -d "$(DESTDIR)$(datadir)/mlt/feeds/NTSC"
- install -m 644 PAL/*.* "$(DESTDIR)$(datadir)/mlt/feeds/PAL"
- install -m 644 NTSC/*.* "$(DESTDIR)$(datadir)/mlt/feeds/NTSC"
+ install -d "$(DESTDIR)$(mltdatadir)/feeds/PAL"
+ install -d "$(DESTDIR)$(mltdatadir)/feeds/NTSC"
+ install -m 644 PAL/*.* "$(DESTDIR)$(mltdatadir)/feeds/PAL"
+ install -m 644 NTSC/*.* "$(DESTDIR)$(mltdatadir)/feeds/NTSC"
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(prefix)/share/mlt/frei0r"
- install -m 644 blacklist.txt "$(DESTDIR)$(datadir)/mlt/frei0r"
- install -m 644 not_thread_safe.txt "$(DESTDIR)$(datadir)/mlt/frei0r"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/frei0r"
+ install -m 644 blacklist.txt "$(DESTDIR)$(mltdatadir)/frei0r"
+ install -m 644 not_thread_safe.txt "$(DESTDIR)$(mltdatadir)/frei0r"
ifneq ($(wildcard .depend),)
include .depend
if [ "$help" != "1" ]
then
- echo "#include <frei0r.h> int main(){ f0r_plugin_info_t test; test.name;return 0;}"| gcc $CFLAGS -c -x c - >/dev/null 2>&1
+ echo "#include <frei0r.h> int main(){ f0r_plugin_info_t test; test.name;return 0;}"| $CC $(pkg-config --cflags frei0r) $CFLAGS -c -x c - >/dev/null 2>&1
if [ "$?" = "1" ]
then
mlt_properties_set_data ( parameter , string , pnum , 0 , ( mlt_destructor )mlt_properties_close, NULL );
f0r_param_info_t paraminfo;
param_info(¶minfo,j);
- mlt_properties_set ( pnum , "identifier" , paraminfo.name );
+ mlt_properties_set ( pnum , "identifier" , string );
mlt_properties_set ( pnum , "title" , paraminfo.name );
mlt_properties_set ( pnum , "description" , paraminfo.explanation);
if ( paraminfo.type == F0R_PARAM_DOUBLE ){
}
}
check_thread_safe( properties, name );
- mlt_properties_set_data(properties, "_dlclose_handle", handle , sizeof (void*) , NULL , NULL );
+ mlt_properties_set_data(properties, "_dlclose_handle", handle , sizeof ( handle ) , 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);
+ mlt_properties_set_data(properties, "f0r_construct", f0r_construct , sizeof( f0r_construct ),NULL,NULL);
+ mlt_properties_set_data(properties, "f0r_update", f0r_update , sizeof( f0r_update ),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_update2", f0r_update2 , sizeof( f0r_update2 ),NULL,NULL);
+ mlt_properties_set_data(properties, "f0r_destruct", f0r_destruct , sizeof( f0r_destruct ),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);
char* firstname = strtok_r( shortname, ".", &save_firstptr );
#endif
char pluginname[1024]="frei0r.";
- strcat(pluginname,firstname);
+ if ( firstname )
+ strncat( pluginname, firstname, sizeof( pluginname ) - strlen( pluginname ) -1 );
- if ( mlt_properties_get( blacklist, firstname ) )
+ if ( firstname && mlt_properties_get( blacklist, firstname ) )
continue;
void* handle=dlopen(strcat(name, LIBSUF),RTLD_LAZY);
}
if ( neu == 0 ){
inst= f0r_construct(*width,*height);
- mlt_properties_set_data( prop , ctorname , inst, sizeof(void*) , f0r_destruct , NULL );;
+ mlt_properties_set_data( prop , ctorname , inst, sizeof( inst ) , f0r_destruct , NULL );;
}else{
inst=mlt_properties_get_data( prop , ctorname , NULL );
}
for (i=0;i<info.num_params;i++){
f0r_param_info_t pinfo;
f0r_get_param_info(&pinfo,i);
- if (mlt_properties_get( prop , pinfo.name ) !=NULL ){
+ char index[20];
+ snprintf( index, sizeof(index), "%d", i );
+ char *val = mlt_properties_get( prop , index );
+ if ( !val )
+ val = mlt_properties_get( prop , pinfo.name );
+ if ( val ) {
switch (pinfo.type) {
case F0R_PARAM_DOUBLE:
case F0R_PARAM_BOOL:
{
- char *val=mlt_properties_get(prop, pinfo.name );
mlt_geometry geom=mlt_geometry_init();
struct mlt_geometry_item_s item;
mlt_geometry_parse(geom,val,-1,-1,-1);
case F0R_PARAM_COLOR:
{
f0r_param_color_t color;
- parse_color(mlt_properties_get_int(prop , pinfo.name), &color);
+ int int_color = mlt_properties_get(prop, index) ?
+ mlt_properties_get_int(prop, index) : mlt_properties_get_int(prop, pinfo.name);
+ parse_color(int_color, &color);
f0r_set_param_value(inst, &color, i);
break;
}
case F0R_PARAM_STRING:
{
- f0r_param_string val = mlt_properties_get(prop, pinfo.name);
- if (val) f0r_set_param_value(inst, &val, i);
+ f0r_set_param_value(inst, &val, i);
break;
}
}
// 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_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );
// Push the get_image method
mlt_frame_push_get_image( *frame, producer_get_image );
ifdef USE_GTK2
OBJS += consumer_gtk2.o
-CFLAGS += `pkg-config gtk+-2.0 --cflags`
-LDFLAGS += `pkg-config gtk+-2.0 --libs`
+CFLAGS += `pkg-config $(PKGCONFIG_PREFIX) --cflags gtk+-2.0`
+LDFLAGS += `pkg-config $(PKGCONFIG_PREFIX) --libs gtk+-2.0`
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`
+CFLAGS += `pkg-config $(PKGCONFIG_PREFIX) --cflags gdk-pixbuf-2.0`
+LDFLAGS += `pkg-config $(PKGCONFIG_PREFIX) --libs gdk-pixbuf-2.0`
endif
ifdef USE_EXIF
ifdef USE_PANGO
OBJS += producer_pango.o
OBJS += filter_dynamictext.o
-CFLAGS += `pkg-config pangoft2 --cflags`
-LDFLAGS += `pkg-config pangoft2 --libs`
+CFLAGS += `pkg-config $(PKGCONFIG_PREFIX) --cflags pangoft2`
+LDFLAGS += `pkg-config $(PKGCONFIG_PREFIX) --libs pangoft2`
ifeq ($(targetos),Darwin)
LDFLAGS += -liconv
endif
rm -f $(OBJS) $(ASM_OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/gtk2"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/gtk2"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/gtk2"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/gtk2"
ifneq ($(wildcard .depend),)
include .depend
#!/bin/sh
-if [ "$help" != "1" ]
+if [ "$help" = "1" ]
then
+ cat << EOF
+GTK+ options:
- pkg-config gtk+-2.0 2> /dev/null
+ --gtk2-prefix=path - Override the gtk+-2.0 prefix for pkg-config
+
+EOF
+
+else
+ pkgconfig_prefix=
+ for i in "$@"
+ do
+ case $i in
+ --gtk2-prefix=* ) pkgconfig_prefix="${i#--gtk2-prefix=}" ;;
+ esac
+ done
+ [ "$pkgconfig_prefix" != "" ] && pkgconfig_prefix="--define-variable=prefix=\"$pkgconfig_prefix\""
+
+ pkg-config $pkgconfig_prefix gtk+-2.0 2> /dev/null
disable_gtk2=$?
- pkg-config gdk-pixbuf-2.0 2> /dev/null
+ pkg-config $pkgconfig_prefix gdk-pixbuf-2.0 2> /dev/null
disable_pixbuf=$?
- pkg-config pangoft2 2> /dev/null
+ pkg-config $pkgconfig_prefix gdk-pixbuf-2.0 pangoft2 2> /dev/null
disable_pango=$?
if [ "$disable_gtk2" != "0" -a "$disable_pixbuf" != 0 -a "$disable_pango" != "0" ]
[ "$disable_pixbuf" = "0" ] && echo "USE_PIXBUF=1" >> config.mak
[ "$disable_pango" = "0" ] && echo "USE_PANGO=1" >> config.mak
+ [ "$pkgconfig_prefix" != "" ] && echo "PKGCONFIG_PREFIX=$pkgconfig_prefix" >> config.mak
+
pkg-config --exists 'libexif'
if [ $? -eq 0 ]
then
static int get_next_token(char* str, int* pos, char* token, int* is_keyword)
{
int token_pos = 0;
- int str_len = strlen(str);
+ int str_len = strlen( str );
if( (*pos) >= str_len || str[*pos] == '\0' )
{
char tc[12] = "";
if (fps == 0)
{
- strncat( text, "-", MAX_TEXT_LEN - strlen(text) - 1 );
+ strncat( text, "-", MAX_TEXT_LEN - strlen( text ) - 1 );
}
else
{
int hours = minutes / 60;
minutes = minutes % 60;
sprintf(tc, "%.2d:%.2d:%.2d:%.2d", hours, minutes, seconds, frames);
- strncat( text, tc, MAX_TEXT_LEN - strlen(text) - 1 );
+ strncat( text, tc, MAX_TEXT_LEN - strlen( text ) - 1 );
}
}
{
int pos = mlt_frame_get_position( frame );
char s[12];
- snprintf( s, sizeof(s) - 1, "%d", pos );
- strncat( text, s, MAX_TEXT_LEN - strlen(text) - 1 );
+ snprintf( s, sizeof( s ) - 1, "%d", pos );
+ strncat( text, s, MAX_TEXT_LEN - strlen( text ) - 1 );
}
static void get_filedate_str( mlt_filter filter, mlt_frame frame, char* text )
{
- mlt_producer producer = mlt_producer_cut_parent(mlt_frame_get_original_producer( frame ));
- mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES(producer);
+ mlt_producer producer = mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) );
+ mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
char* filename = mlt_properties_get( producer_properties, "resource");
struct stat file_info;
struct tm* time_info = gmtime( &(file_info.st_mtime) );
char date[11] = "";
strftime( date, 11, "%Y/%m/%d", time_info );
- strncat( text, date, MAX_TEXT_LEN - strlen(text) - 1);
+ strncat( text, date, MAX_TEXT_LEN - strlen( text ) - 1);
}
}
+static void get_localfiledate_str( mlt_filter filter, mlt_frame frame, char* text )
+{
+ mlt_producer producer = mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) );
+ mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
+ char* filename = mlt_properties_get( producer_properties, "resource" );
+ struct stat file_info;
+
+ if( !stat( filename, &file_info ) )
+ {
+ struct tm* time_info = localtime( &(file_info.st_mtime) );
+ char date[11] = "";
+ strftime( date, 11, "%Y/%m/%d", time_info );
+ strncat( text, date, MAX_TEXT_LEN - strlen( text ) - 1);
+ }
+}
+
+static void get_resource_str( mlt_filter filter, mlt_frame frame, char* text )
+{
+ mlt_producer producer = mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) );
+ mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
+ strncat( text, mlt_properties_get( producer_properties, "resource" ), MAX_TEXT_LEN - strlen( text ) - 1 );
+}
/** Perform substitution for keywords that are enclosed in "# #".
*/
-
static void substitute_keywords(mlt_filter filter, char* result, char* value, mlt_frame frame)
{
char keyword[MAX_TEXT_LEN] = "";
{
if(!is_keyword)
{
- strncat( result, keyword, MAX_TEXT_LEN - strlen(result) - 1 );
+ strncat( result, keyword, MAX_TEXT_LEN - strlen( result ) - 1 );
}
else if ( !strcmp( keyword, "timecode" ) )
{
- get_timecode_str(filter, frame, result);
+ get_timecode_str( filter, frame, result );
}
else if ( !strcmp( keyword, "frame" ) )
{
- get_frame_str(filter, frame, result);
+ get_frame_str( filter, frame, result );
}
else if ( !strcmp( keyword, "filedate" ) )
{
- get_filedate_str(filter, frame, result);
+ get_filedate_str( filter, frame, result );
+ }
+ else if ( !strcmp( keyword, "localfiledate" ) )
+ {
+ get_localfiledate_str( filter, frame, result );
}
else if ( !strcmp( keyword, "resource" ) )
{
- // special case: replace #resource# with cut parent resource name
- mlt_producer producer = mlt_producer_cut_parent(mlt_frame_get_original_producer( frame ));
- mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES(producer);
- strncat( result, mlt_properties_get( producer_properties, "resource"), MAX_TEXT_LEN - strlen(result) - 1 );
+ get_resource_str( filter, frame, result );
}
else
{
}
}
-static void apply_filter(mlt_filter filter, mlt_frame frame )
+static void setup_producer( mlt_filter filter, mlt_producer producer, mlt_frame frame )
{
mlt_properties my_properties = MLT_FILTER_PROPERTIES( filter );
- mlt_filter watermark = mlt_properties_get_data( my_properties, "_watermark", NULL );
- mlt_properties watermark_properties = MLT_FILTER_PROPERTIES( watermark );
- char* dynamic_text = mlt_properties_get( my_properties, "argument");
+ mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
+ char* dynamic_text = mlt_properties_get( my_properties, "argument" );
// Check for keywords in dynamic text
if ( dynamic_text )
// Apply keyword substitution before passing the text to the filter.
char result[MAX_TEXT_LEN] = "";
substitute_keywords( filter, result, dynamic_text, frame );
- mlt_properties_set( watermark_properties, "producer.markup", (char*) result );
+ mlt_properties_set( producer_properties, "markup", (char*)result );
}
- // Pass the properties to the watermark filter composite transition
- mlt_properties_set( watermark_properties, "composite.geometry", mlt_properties_get( my_properties, "geometry" ) );
- mlt_properties_set( watermark_properties, "composite.halign", mlt_properties_get( my_properties, "halign" ) );
- mlt_properties_set( watermark_properties, "composite.valign", mlt_properties_get( my_properties, "valign" ) );
-
- // Pass the properties to the watermark filter pango producer
- mlt_properties_set( watermark_properties, "producer.family", mlt_properties_get( my_properties, "family" ) );
- mlt_properties_set( watermark_properties, "producer.size", mlt_properties_get( my_properties, "size" ) );
- mlt_properties_set( watermark_properties, "producer.weight", mlt_properties_get( my_properties, "weight" ) );
- mlt_properties_set( watermark_properties, "producer.fgcolour", mlt_properties_get( my_properties, "fgcolour" ) );
- mlt_properties_set( watermark_properties, "producer.bgcolour", mlt_properties_get( my_properties, "bgcolour" ) );
- mlt_properties_set( watermark_properties, "producer.olcolour", mlt_properties_get( my_properties, "olcolour" ) );
- mlt_properties_set( watermark_properties, "producer.pad", mlt_properties_get( my_properties, "pad" ) );
- mlt_properties_set( watermark_properties, "producer.outline", mlt_properties_get( my_properties, "outline" ) );
-
- // Process the filter
- mlt_filter_process( watermark, frame );
+ // Pass the properties to the pango producer
+ mlt_properties_set( producer_properties, "family", mlt_properties_get( my_properties, "family" ) );
+ mlt_properties_set( producer_properties, "size", mlt_properties_get( my_properties, "size" ) );
+ mlt_properties_set( producer_properties, "weight", mlt_properties_get( my_properties, "weight" ) );
+ mlt_properties_set( producer_properties, "fgcolour", mlt_properties_get( my_properties, "fgcolour" ) );
+ mlt_properties_set( producer_properties, "bgcolour", mlt_properties_get( my_properties, "bgcolour" ) );
+ mlt_properties_set( producer_properties, "olcolour", mlt_properties_get( my_properties, "olcolour" ) );
+ mlt_properties_set( producer_properties, "pad", mlt_properties_get( my_properties, "pad" ) );
+ mlt_properties_set( producer_properties, "outline", mlt_properties_get( my_properties, "outline" ) );
+ mlt_properties_set( producer_properties, "align", mlt_properties_get( my_properties, "halign" ) );
}
+static void setup_transition( mlt_filter filter, mlt_transition transition )
+{
+ mlt_properties my_properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_properties transition_properties = MLT_TRANSITION_PROPERTIES( transition );
+
+ mlt_properties_set( transition_properties, "geometry", mlt_properties_get( my_properties, "geometry" ) );
+ mlt_properties_set( transition_properties, "halign", mlt_properties_get( my_properties, "halign" ) );
+ mlt_properties_set( transition_properties, "valign", mlt_properties_get( my_properties, "valign" ) );
+ mlt_properties_set_int( transition_properties, "out", mlt_properties_get_int( my_properties, "_out" ) );
+ mlt_properties_set_int( transition_properties, "refresh", 1 );
+}
+
+
/** 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
+ int error = 0;
mlt_filter filter = mlt_frame_pop_service( frame );
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_producer producer = mlt_properties_get_data( properties, "_producer", NULL );
+ mlt_transition transition = mlt_properties_get_data( properties, "_transition", NULL );
+ mlt_frame text_frame = NULL;
+ mlt_position position = 0;
+ // Configure this filter
mlt_service_lock( MLT_FILTER_SERVICE( filter ) );
+ setup_producer( filter, producer, frame );
+ setup_transition( filter, transition );
+ mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
- apply_filter(filter, frame);
+ // Make sure the producer is in the correct position
+ position = mlt_filter_get_position( filter, frame );
+ mlt_producer_seek( producer, position );
- mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
+ // Get the b frame and process with transition if successful
+ if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &text_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( text_frame );
- // Need to get the image
- return mlt_frame_get_image( frame, image, format, width, height, 1 );
-}
+ // Set the frame and text_frame to be in the same position and have same consumer requirements
+ mlt_frame_set_position( text_frame, position );
+ mlt_frame_set_position( frame, position );
+ mlt_properties_set_int( b_props, "consumer_deinterlace", mlt_properties_get_int( a_props, "consumer_deinterlace" ) );
+ // Apply all filters that are attached to this filter to the b frame
+ mlt_service_apply_filters( MLT_FILTER_SERVICE( filter ), text_frame, 0 );
+
+ // Process the frame
+ mlt_transition_process( transition, frame, text_frame );
+
+ // Get the image
+ *format = mlt_image_yuv422;
+ error = mlt_frame_get_image( frame, image, format, width, height, 1 );
+
+ // Close the b frame
+ mlt_frame_close( text_frame );
+ }
+
+ return error;
+}
/** Filter processing.
*/
-
static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
{
- // Push the filter
+ // Get the properties of the frame
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+
+ // Save the frame out point
+ mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "_out", mlt_properties_get_int( properties, "out" ) );
+
+ // Push the filter on to the stack
mlt_frame_push_service( frame, filter );
- // Register the get image method
+ // Push the get_image on to the stack
mlt_frame_push_get_image( frame, filter_get_image );
- // Return the frame
return frame;
}
/** Constructor for the filter.
*/
-
-mlt_filter filter_dynamictext_init( mlt_profile profile, mlt_service_type type, const char *id, void *arg )
+mlt_filter filter_dynamictext_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
- // Create the filter
- mlt_filter filter = mlt_filter_new( );
- mlt_filter watermark = mlt_factory_filter( profile, "watermark", "pango:" );
+ mlt_filter filter = mlt_filter_new();
+ mlt_transition transition = mlt_factory_transition( profile, "composite", NULL );
+ mlt_producer producer = mlt_factory_producer( profile, mlt_environment( "MLT_PRODUCER" ), "pango:" );
- // Initialise it
- if ( filter && watermark )
+ if ( filter && transition && producer )
{
- // Get the properties
- mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_properties my_properties = MLT_FILTER_PROPERTIES( filter );
+
+ // Register the transition for reuse/destruction
+ mlt_properties_set_data( my_properties, "_transition", transition, 0, ( mlt_destructor )mlt_transition_close, NULL );
- // Store the watermark filter for future use
- mlt_properties_set_data( properties, "_watermark", watermark, 0, ( mlt_destructor )mlt_filter_close, NULL );
+ // Register the producer for reuse/destruction
+ mlt_properties_set_data( my_properties, "_producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL );
+
+ // Ensure that we loop
+ mlt_properties_set( MLT_PRODUCER_PROPERTIES( producer ), "eof", "loop" );
// Assign default values
- mlt_properties_set( properties, "argument", arg ? arg: "#timecode#" );
- mlt_properties_set( properties, "geometry", "0%/0%:100%x100%:100" );
- mlt_properties_set( properties, "family", "Sans" );
- mlt_properties_set( properties, "size", "48" );
- mlt_properties_set( properties, "weight", "400" );
- mlt_properties_set( properties, "fgcolour", "0x000000ff" );
- mlt_properties_set( properties, "bgcolour", "0x00000020" );
- mlt_properties_set( properties, "olcolour", "0x00000000" );
- mlt_properties_set( properties, "pad", "0" );
- mlt_properties_set( properties, "halign", "left" );
- mlt_properties_set( properties, "valign", "top" );
- mlt_properties_set( properties, "outline", "0" );
-
- // Specify the processing method
+ mlt_properties_set( my_properties, "argument", arg ? arg: "#timecode#" );
+ mlt_properties_set( my_properties, "geometry", "0%/0%:100%x100%:100" );
+ mlt_properties_set( my_properties, "family", "Sans" );
+ mlt_properties_set( my_properties, "size", "48" );
+ mlt_properties_set( my_properties, "weight", "400" );
+ mlt_properties_set( my_properties, "fgcolour", "0x000000ff" );
+ mlt_properties_set( my_properties, "bgcolour", "0x00000020" );
+ mlt_properties_set( my_properties, "olcolour", "0x00000000" );
+ mlt_properties_set( my_properties, "pad", "0" );
+ mlt_properties_set( my_properties, "halign", "left" );
+ mlt_properties_set( my_properties, "valign", "top" );
+ mlt_properties_set( my_properties, "outline", "0" );
+
+ mlt_properties_set_int( my_properties, "_filter_private", 1 );
+
filter->process = filter_process;
}
- else // filter or watermark failed for some reason
+ else
{
if( filter )
{
- mlt_filter_close(filter);
+ mlt_filter_close( filter );
}
- if( watermark )
+ if( transition )
{
- mlt_filter_close(watermark);
+ mlt_transition_close( transition );
+ }
+
+ if( producer )
+ {
+ mlt_producer_close( producer );
}
filter = NULL;
}
-
return filter;
}
case mlt_image_rgb24a:
case mlt_image_opengl:
{
- // Create the output image
- uint8_t *output = mlt_pool_alloc( size );
-
if ( strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) )
{
+ // Create the output image
+ uint8_t *output = mlt_pool_alloc( size );
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( *image, GDK_COLORSPACE_RGB,
( *format == mlt_image_rgb24a || *format == mlt_image_opengl ), 8, iwidth, iheight,
iwidth * bpp, NULL, NULL );
mlt_producer producer_pango_init( const char *filename )
{
- producer_pango this = calloc( sizeof( struct producer_pango_s ), 1 );
+ producer_pango this = calloc( 1, sizeof( struct producer_pango_s ) );
if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 )
{
mlt_producer producer = &this->parent;
mlt_properties_set( properties, "style", "normal" );
mlt_properties_set( properties, "encoding", "UTF-8" );
mlt_properties_set_int( properties, "weight", PANGO_WEIGHT_NORMAL );
+ mlt_properties_set_int( properties, "seekable", 1 );
if ( filename == NULL || ( filename && ( !strcmp( filename, "" )
+ || strstr( filename, "<producer>" )
// workaround for old kdenlive countdown generator
|| strstr( filename, "<producer>" ) ) ) )
{
char *markup = copy;
if ( strstr( markup, "/+" ) )
markup = strstr( markup, "/+" ) + 2;
- ( *strrchr( markup, '.' ) ) = '\0';
+ if ( strrchr( markup, '.' ) )
+ ( *strrchr( markup, '.' ) ) = '\0';
while ( strchr( markup, '~' ) )
( *strchr( markup, '~' ) ) = '\n';
mlt_properties_set( properties, "resource", filename );
if ( markup )
{
markup = realloc( markup, size );
- strcat( markup, line );
+ if ( markup )
+ strcat( markup, line );
}
else
{
}
fclose( f );
- if ( markup[ strlen( markup ) - 1 ] == '\n' )
+ if ( markup && markup[ strlen( markup ) - 1 ] == '\n' )
markup[ strlen( markup ) - 1 ] = '\0';
mlt_properties_set( properties, "resource", filename );
- mlt_properties_set( properties, "markup", ( markup == NULL ? "" : markup ) );
+ if ( markup )
+ mlt_properties_set( properties, "markup", markup );
+ else
+ mlt_properties_set( properties, "markup", "" );
free( markup );
}
else
int result = -1;
iconv_t cd = iconv_open( "UTF-8", encoding );
- if ( cd != ( iconv_t )-1 )
+ if ( text && ( cd != ( iconv_t )-1 ) )
{
char *inbuf_p = text;
size_t inbuf_n = strlen( text );
mlt_properties_set( properties, prop_name, "" );
mlt_pool_release( outbuf );
- iconv_close( cd );
result = 0;
}
+ iconv_close( cd );
return result;
}
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 );
+ mlt_geometry_prev_key( key_frames, &item, mlt_frame_original_position( frame ) );
sprintf( temp, "%d", item.frame );
markup = mlt_properties_get( contents, temp );
}
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 ) );
+ mlt_properties_set_int( producer_props, "meta.media.width", gdk_pixbuf_get_width( pixbuf ) );
+ mlt_properties_set_int( producer_props, "meta.media.height", gdk_pixbuf_get_height( pixbuf ) );
// Store the width/height of the pixbuf temporarily
this->width = gdk_pixbuf_get_width( 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" ) );
}
static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
{
producer_pango this = producer->child;
+ // Fetch the producers properties
+ mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
+
// Generate a frame
*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
// 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 );
// Set producer-specific frame properties
mlt_properties_set_int( properties, "progressive", 1 );
- mlt_properties_set_double( properties, "aspect_ratio", 1 );
+ double force_ratio = mlt_properties_get_double( producer_properties, "force_aspect_ratio" );
+ if ( force_ratio > 0.0 )
+ mlt_properties_set_double( properties, "aspect_ratio", force_ratio );
+ else
+ mlt_properties_set_double( properties, "aspect_ratio", 1.0);
// Stack the get image callback
mlt_frame_push_service( *frame, this );
type: integer
description: The last requested scaled image height.
readonly: yes
+
+ - identifier: force_aspect_ratio
+ title: Sample aspect ratio
+ type: float
+ description: Optionally override a (mis)detected aspect ratio
+ mutable: yes
#include <framework/mlt_frame.h>
#include <framework/mlt_cache.h>
#include <framework/mlt_log.h>
+#include <framework/mlt_tokeniser.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "config.h"
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
+#include <ctype.h>
+// this protects concurrent access to gdk_pixbuf
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
typedef struct producer_pixbuf_s *producer_pixbuf;
int pixbuf_idx;
int width;
int height;
- int alpha;
+ uint8_t *alpha;
uint8_t *image;
mlt_cache_item image_cache;
- pthread_mutex_t mutex;
+ mlt_cache_item alpha_cache;
+ mlt_cache_item pixbuf_cache;
+ GdkPixbuf *pixbuf;
+ mlt_image_format format;
};
-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 void load_filenames( producer_pixbuf self, mlt_properties producer_properties );
+static int refresh_pixbuf( producer_pixbuf self, mlt_frame frame );
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 )
+ producer_pixbuf self = calloc( 1, sizeof( struct producer_pixbuf_s ) );
+ if ( self != NULL && mlt_producer_init( &self->parent, self ) == 0 )
{
- mlt_producer producer = &this->parent;
+ mlt_producer producer = &self->parent;
// Get the properties interface
- mlt_properties properties = MLT_PRODUCER_PROPERTIES( &this->parent );
+ mlt_properties properties = MLT_PRODUCER_PROPERTIES( &self->parent );
// Callback registration
producer->get_frame = producer_get_frame;
mlt_properties_set_int( properties, "ttl", 25 );
mlt_properties_set_int( properties, "aspect_ratio", 1 );
mlt_properties_set_int( properties, "progressive", 1 );
+ mlt_properties_set_int( properties, "seekable", 1 );
+ mlt_properties_set_int( properties, "loop", 1 );
// Validate the resource
if ( filename )
- load_filenames( this, properties );
- if ( this->count )
+ load_filenames( self, properties );
+ if ( self->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_properties_set_data( frame_properties, "producer_pixbuf", self, 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 );
+ refresh_pixbuf( self, frame );
+ mlt_cache_item_close( self->pixbuf_cache );
mlt_frame_close( frame );
}
}
- if ( this->width == 0 )
+ if ( self->width == 0 )
{
producer_close( producer );
producer = NULL;
}
return producer;
}
- free( this );
+ free( self );
return NULL;
}
-static void load_filenames( producer_pixbuf this, mlt_properties producer_properties )
+static int load_svg( producer_pixbuf self, mlt_properties properties, const char *filename )
{
- char *filename = mlt_properties_get( producer_properties, "resource" );
- this->filenames = mlt_properties_new( );
+ int result = 0;
// Read xml string
if ( strstr( filename, "<svg" ) )
{
// Write the svg into the temp file
ssize_t remaining_bytes;
- char *xml = filename;
-
+ const 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 );
+ mlt_properties_set( self->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 );
+ mlt_properties_set_data( properties, "__temporary_file__", fullname, 0, ( mlt_destructor )unlink, NULL );
+ result = 1;
}
}
- // Obtain filenames
- else if ( strchr( filename, '%' ) != NULL )
+ return result;
+}
+
+static int load_sequence_sprintf( producer_pixbuf self, mlt_properties properties, const char *filename )
+{
+ int result = 0;
+
+ // Obtain filenames with pattern
+ if ( strchr( filename, '%' ) != NULL )
{
// handle picture sequences
- int i = mlt_properties_get_int( producer_properties, "begin" );
+ int i = mlt_properties_get_int( properties, "begin" );
int gap = 0;
char full[1024];
int keyvalue = 0;
if ( stat( full, &buf ) == 0 )
{
sprintf( key, "%d", keyvalue ++ );
- mlt_properties_set( this->filenames, key, full );
+ mlt_properties_set( self->filenames, key, full );
gap = 0;
}
else
gap ++;
}
}
- if ( mlt_properties_count( this->filenames ) > 0 )
- mlt_properties_set_int( producer_properties, "ttl", 1 );
+ if ( mlt_properties_count( self->filenames ) > 0 )
+ {
+ mlt_properties_set_int( properties, "ttl", 1 );
+ result = 1;
+ }
}
- else if ( strstr( filename, "/.all." ) != NULL )
+ return result;
+}
+
+static int load_sequence_deprecated( producer_pixbuf self, mlt_properties properties, const char *filename )
+{
+ int result = 0;
+ const char *start;
+
+ // This approach is deprecated in favor of the begin querystring parameter.
+ // Obtain filenames with pattern containing a begin value, e.g. foo%1234d.png
+ if ( ( start = strchr( filename, '%' ) ) )
+ {
+ const char *end = ++start;
+ while ( isdigit( *end ) ) end++;
+ if ( end > start && ( end[0] == 'd' || end[0] == 'i' || end[0] == 'u' ) )
+ {
+ int n = end - start;
+ char *s = calloc( 1, n + 1 );
+ strncpy( s, start, n );
+ mlt_properties_set( properties, "begin", s );
+ free( s );
+ s = calloc( 1, strlen( filename ) + 2 );
+ strncpy( s, filename, start - filename );
+ sprintf( s + ( start - filename ), ".%d%s", n, end );
+ result = load_sequence_sprintf( self, properties, s );
+ free( s );
+ }
+ }
+ return result;
+}
+
+static int load_sequence_querystring( producer_pixbuf self, mlt_properties properties, const char *filename )
+{
+ int result = 0;
+
+ // Obtain filenames with pattern and begin value in query string
+ if ( strchr( filename, '%' ) && strchr( filename, '?' ) )
+ {
+ // Split filename into pattern and query string
+ char *s = strdup( filename );
+ char *querystring = strrchr( s, '?' );
+ *querystring++ = '\0';
+ if ( strstr( filename, "begin=" ) )
+ mlt_properties_set( properties, "begin", strstr( querystring, "begin=" ) + 6 );
+ else if ( strstr( filename, "begin:" ) )
+ mlt_properties_set( properties, "begin", strstr( querystring, "begin:" ) + 6 );
+ // Coerce to an int value so serialization does not have any extra query string cruft
+ mlt_properties_set_int( properties, "begin", mlt_properties_get_int( properties, "begin" ) );
+ result = load_sequence_sprintf( self, properties, s );
+ free( s );
+ }
+ return result;
+}
+
+static int load_folder( producer_pixbuf self, mlt_properties properties, const char *filename )
+{
+ int result = 0;
+
+ // Obtain filenames with folder
+ if ( strstr( filename, "/.all." ) != NULL )
{
char wildcard[ 1024 ];
char *dir_name = strdup( filename );
*( strstr( dir_name, "/.all." ) + 1 ) = '\0';
sprintf( wildcard, "*%s", extension );
- mlt_properties_dir_list( this->filenames, dir_name, wildcard, 1 );
+ mlt_properties_dir_list( self->filenames, dir_name, wildcard, 1 );
free( dir_name );
+ result = 1;
}
- else
+ return result;
+}
+
+static void load_filenames( producer_pixbuf self, mlt_properties properties )
+{
+ char *filename = mlt_properties_get( properties, "resource" );
+ self->filenames = mlt_properties_new( );
+
+ if (!load_svg( self, properties, filename ) &&
+ !load_sequence_querystring( self, properties, filename ) &&
+ !load_sequence_sprintf( self, properties, filename ) &&
+ !load_sequence_deprecated( self, properties, filename ) &&
+ !load_folder( self, properties, filename ) )
{
- mlt_properties_set( this->filenames, "0", filename );
+ mlt_properties_set( self->filenames, "0", filename );
}
-
- this->count = mlt_properties_count( this->filenames );
+ self->count = mlt_properties_count( self->filenames );
}
-static void refresh_image( producer_pixbuf this, mlt_frame frame, int width, int height )
+static GdkPixbuf* reorient_with_exif( producer_pixbuf self, int image_idx, GdkPixbuf *pixbuf )
{
- // Obtain properties of frame
- mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+#ifdef USE_EXIF
+ mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( &self->parent );
+ ExifData *d = exif_data_new_from_file( mlt_properties_get_value( self->filenames, image_idx ) );
+ ExifEntry *entry;
+ int exif_orientation = 0;
- // Obtain the producer
- mlt_producer producer = &this->parent;
+ /* get orientation and rotate image accordingly if necessary */
+ if (d)
+ {
+ if ( ( entry = exif_content_get_entry ( d->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION ) ) )
+ exif_orientation = exif_get_short (entry->data, exif_data_get_byte_order (d));
- // Obtain properties of producer
- mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );
+ /* Free the EXIF data */
+ exif_data_unref(d);
+ }
- // 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;
+ // Remember EXIF value, might be useful for someone
+ mlt_properties_set_int( producer_props, "_exif_orientation" , exif_orientation );
- // 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;
+ if ( exif_orientation > 1 )
+ {
+ GdkPixbuf *processed = NULL;
+ GdkPixbufRotation matrix = GDK_PIXBUF_ROTATE_NONE;
+
+ // Rotate image according to exif data
+ switch ( exif_orientation ) {
+ case 2:
+ processed = gdk_pixbuf_flip ( pixbuf, TRUE );
+ break;
+ case 3:
+ matrix = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
+ processed = pixbuf;
+ break;
+ case 4:
+ processed = gdk_pixbuf_flip ( pixbuf, FALSE );
+ break;
+ case 5:
+ matrix = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
+ processed = gdk_pixbuf_flip ( pixbuf, TRUE );
+ break;
+ case 6:
+ matrix = GDK_PIXBUF_ROTATE_CLOCKWISE;
+ processed = pixbuf;
+ break;
+ case 7:
+ matrix = GDK_PIXBUF_ROTATE_CLOCKWISE;
+ processed = gdk_pixbuf_flip ( pixbuf, TRUE );
+ break;
+ case 8:
+ matrix = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
+ processed = pixbuf;
+ break;
+ }
+ if ( processed )
+ {
+ pixbuf = gdk_pixbuf_rotate_simple( processed, matrix );
+ g_object_unref( processed );
+ }
+ }
+#endif
+ return pixbuf;
+}
- // 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 );
+static int refresh_pixbuf( producer_pixbuf self, mlt_frame frame )
+{
+ // Obtain properties of frame and producer
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+ mlt_producer producer = &self->parent;
+ mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );
// Check if user wants us to reload the image
if ( mlt_properties_get_int( producer_props, "force_reload" ) )
{
- pixbuf = NULL;
- this->image = NULL;
+ self->pixbuf = NULL;
+ self->image = NULL;
mlt_properties_set_int( producer_props, "force_reload", 0 );
}
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" );
+ mlt_position position = mlt_frame_original_position( frame );
position += mlt_producer_get_in( producer );
// Image index
- int image_idx = ( int )floor( ( double )position / ttl ) % this->count;
+ int loop = mlt_properties_get_int( producer_props, "loop" );
+ int current_idx;
+ if (loop) {
+ current_idx = ( int )floor( ( double )position / ttl ) % self->count;
+ } else {
+ current_idx = MIN(( double )position / ttl, self->count - 1);
+ }
// 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 );
- }
+ sprintf( image_key, "%d", current_idx );
- 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_int( cached_props, "alpha" );
-
- if ( width != 0 && ( width != this->width || height != this->height ) )
- this->image = NULL;
- }
- }
int disable_exif = mlt_properties_get_int( producer_props, "disable_exif" );
-
- // 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->pixbuf_idx )
- pixbuf = NULL;
- mlt_log_debug( MLT_PRODUCER_SERVICE( producer ), "image %p pixbuf %p idx %d image_idx %d pixbuf_idx %d width %d\n",
- this->image, pixbuf, image_idx, this->image_idx, this->pixbuf_idx, width );
- if ( !pixbuf || mlt_properties_get_int( producer_props, "_disable_exif" ) != disable_exif )
+
+ if ( current_idx != self->pixbuf_idx )
+ self->pixbuf = NULL;
+ if ( !self->pixbuf || mlt_properties_get_int( producer_props, "_disable_exif" ) != disable_exif )
{
- this->image = NULL;
- pixbuf = gdk_pixbuf_new_from_file( mlt_properties_get_value( this->filenames, image_idx ), &error );
+ GError *error = NULL;
- if ( pixbuf )
+ self->image = NULL;
+ pthread_mutex_lock( &g_mutex );
+ self->pixbuf = gdk_pixbuf_new_from_file( mlt_properties_get_value( self->filenames, current_idx ), &error );
+ if ( self->pixbuf )
{
-#ifdef USE_EXIF
// Read the exif value for this file
- if ( disable_exif == 0) {
- ExifData *d = exif_data_new_from_file( mlt_properties_get_value( this->filenames, image_idx ) );
- ExifEntry *entry;
- int exif_orientation = 0;
-
- /* get orientation and rotate image accordingly if necessary */
- if (d) {
- if ( ( entry = exif_content_get_entry ( d->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION ) ) )
- exif_orientation = exif_get_short (entry->data, exif_data_get_byte_order (d));
-
- /* Free the EXIF data */
- exif_data_unref(d);
- }
-
- // Remember EXIF value, might be useful for someone
- mlt_properties_set_int( producer_props, "_exif_orientation" , exif_orientation );
-
- if ( exif_orientation > 1 )
- {
- GdkPixbuf *processed = NULL;
- GdkPixbufRotation matrix = GDK_PIXBUF_ROTATE_NONE;
-
- // Rotate image according to exif data
- switch ( exif_orientation ) {
- case 2:
- processed = gdk_pixbuf_flip ( pixbuf, TRUE );
- break;
- case 3:
- matrix = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
- processed = pixbuf;
- break;
- case 4:
- processed = gdk_pixbuf_flip ( pixbuf, FALSE );
- break;
- case 5:
- matrix = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
- processed = gdk_pixbuf_flip ( pixbuf, TRUE );
- break;
- case 6:
- matrix = GDK_PIXBUF_ROTATE_CLOCKWISE;
- processed = pixbuf;
- break;
- case 7:
- matrix = GDK_PIXBUF_ROTATE_CLOCKWISE;
- processed = gdk_pixbuf_flip ( pixbuf, TRUE );
- break;
- case 8:
- matrix = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
- processed = pixbuf;
- break;
- }
- if ( processed )
- pixbuf = gdk_pixbuf_rotate_simple( processed, matrix );
- }
- }
-#endif
+ if ( !disable_exif )
+ self->pixbuf = reorient_with_exif( self, current_idx, self->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" );
- this->pixbuf_idx = image_idx;
+ mlt_cache_item_close( self->pixbuf_cache );
+ mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.pixbuf", self->pixbuf, 0, ( mlt_destructor )g_object_unref );
+ self->pixbuf_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.pixbuf" );
+ self->pixbuf_idx = current_idx;
+
+ // Store the width/height of the pixbuf temporarily
+ self->width = gdk_pixbuf_get_width( self->pixbuf );
+ self->height = gdk_pixbuf_get_height( self->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_properties_set_int( producer_props, "meta.media.width", self->width );
+ mlt_properties_set_int( producer_props, "meta.media.height", self->height );
mlt_properties_set_int( producer_props, "_disable_exif", disable_exif );
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 );
}
+ pthread_mutex_unlock( &g_mutex );
}
+ // Set width/height of frame
+ mlt_properties_set_int( properties, "width", self->width );
+ mlt_properties_set_int( properties, "height", self->height );
+
+ return current_idx;
+}
+
+static void refresh_image( producer_pixbuf self, mlt_frame frame, mlt_image_format format, int width, int height )
+{
+ // Obtain properties of frame and producer
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+ mlt_producer producer = &self->parent;
+
+ // Get index and pixbuf
+ int current_idx = refresh_pixbuf( self, frame );
+
+ // optimization for subsequent iterations on single picture
+ if ( current_idx != self->image_idx || width != self->width || height != self->height )
+ self->image = NULL;
+ mlt_log_debug( MLT_PRODUCER_SERVICE( producer ), "image %p pixbuf %p idx %d current_idx %d pixbuf_idx %d width %d\n",
+ self->image, self->pixbuf, current_idx, self->image_idx, self->pixbuf_idx, width );
+
// If we have a pixbuf and we need an image
- if ( pixbuf && width > 0 && !this->image )
+ if ( self->pixbuf && ( !self->image || ( format != mlt_image_none && format != self->format ) ) )
{
char *interps = mlt_properties_get( properties, "rescale.interp" );
int interp = GDK_INTERP_BILINEAR;
- if ( strcmp( interps, "nearest" ) == 0 )
+ if ( !interps ) {
+ // Keep bilinear by default
+ }
+ else if ( strcmp( interps, "nearest" ) == 0 )
interp = GDK_INTERP_NEAREST;
else if ( strcmp( interps, "tiles" ) == 0 )
interp = GDK_INTERP_TILES;
interp = GDK_INTERP_HYPER;
// Note - the original pixbuf is already safe and ready for destruction
- pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, interp );
+ pthread_mutex_lock( &g_mutex );
+ GdkPixbuf* pixbuf = gdk_pixbuf_scale_simple( self->pixbuf, width, height, interp );
// Store width and height
- this->width = width;
- this->height = height;
-
+ self->width = width;
+ self->height = height;
+
// Allocate/define image
- this->alpha = gdk_pixbuf_get_has_alpha( pixbuf );
+ int has_alpha = gdk_pixbuf_get_has_alpha( pixbuf );
int src_stride = gdk_pixbuf_get_rowstride( pixbuf );
- int dst_stride = this->width * ( this->alpha ? 4 : 3 );
+ int dst_stride = self->width * ( has_alpha ? 4 : 3 );
int image_size = dst_stride * ( height + 1 );
- this->image = mlt_pool_alloc( image_size );
+ self->image = mlt_pool_alloc( image_size );
+ self->alpha = NULL;
+ self->format = has_alpha ? mlt_image_rgb24a : mlt_image_rgb24;
if ( src_stride != dst_stride )
{
- int y = this->height;
+ int y = self->height;
uint8_t *src = gdk_pixbuf_get_pixels( pixbuf );
- uint8_t *dst = this->image;
+ uint8_t *dst = self->image;
while ( y-- )
{
memcpy( dst, src, dst_stride );
}
else
{
- memcpy( this->image, gdk_pixbuf_get_pixels( pixbuf ), src_stride * height );
+ memcpy( self->image, gdk_pixbuf_get_pixels( pixbuf ), src_stride * height );
}
- if ( !use_cache )
- mlt_cache_item_close( this->image_cache );
- mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image", this->image, image_size, mlt_pool_release );
- this->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image" );
- this->image_idx = image_idx;
+ pthread_mutex_unlock( &g_mutex );
- // Finished with pixbuf now
- g_object_unref( pixbuf );
+ // Convert image to requested format
+ if ( format != mlt_image_none && format != self->format )
+ {
+ uint8_t *buffer = NULL;
- // Ensure we update the cache when we need to
- update_cache = use_cache;
- }
+ // First, set the image so it can be converted when we get it
+ mlt_frame_replace_image( frame, self->image, self->format, width, height );
+ mlt_frame_set_image( frame, self->image, image_size, mlt_pool_release );
+ self->format = format;
- // 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 );
- }
+ // get_image will do the format conversion
+ mlt_frame_get_image( frame, &buffer, &format, &width, &height, 0 );
- // 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" ) );
+ // cache copies of the image and alpha buffers
+ if ( buffer )
+ {
+ image_size = mlt_image_format_size( format, width, height, NULL );
+ self->image = mlt_pool_alloc( image_size );
+ memcpy( self->image, buffer, image_size );
+ }
+ if ( ( buffer = mlt_frame_get_alpha_mask( frame ) ) )
+ {
+ self->alpha = mlt_pool_alloc( width * height );
+ memcpy( self->alpha, buffer, width * 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_frame_set_image( cached, this->image, this->width * ( this->alpha ? 4 : 3 ) * this->height, mlt_pool_release );
- mlt_properties_set_int( cached_props, "alpha", this->alpha );
- mlt_properties_set_data( cache, image_key, cached, 0, ( mlt_destructor )mlt_frame_close, NULL );
+ // Update the cache
+ mlt_cache_item_close( self->image_cache );
+ mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image", self->image, image_size, mlt_pool_release );
+ self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image" );
+ self->image_idx = current_idx;
+ mlt_cache_item_close( self->alpha_cache );
+ self->alpha_cache = NULL;
+ if ( self->alpha )
+ {
+ mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha", self->alpha, width * height, mlt_pool_release );
+ self->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha" );
+ }
+
+ // Finished with pixbuf now
+ g_object_unref( pixbuf );
}
- pthread_mutex_unlock( &g_mutex );
+ // Set width/height of frame
+ mlt_properties_set_int( properties, "width", self->width );
+ mlt_properties_set_int( properties, "height", self->height );
}
static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
{
int error = 0;
- // Obtain properties of frame
+ // Obtain properties of frame and producer
mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+ producer_pixbuf self = mlt_properties_get_data( properties, "producer_pixbuf", NULL );
+ mlt_producer producer = &self->parent;
- // Obtain the producer for this frame
- producer_pixbuf this = mlt_properties_get_data( properties, "producer_pixbuf", NULL );
-
+ // Use the width and height suggested by the rescale filter because we can do our own scaling.
*width = mlt_properties_get_int( properties, "rescale_width" );
*height = mlt_properties_get_int( properties, "rescale_height" );
- mlt_service_lock( MLT_PRODUCER_SERVICE( &this->parent ) );
+ // Restore pixbuf and image
+ mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) );
+ self->pixbuf_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.pixbuf" );
+ self->pixbuf = mlt_cache_item_data( self->pixbuf_cache, NULL );
+ self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image" );
+ self->image = mlt_cache_item_data( self->image_cache, NULL );
+ self->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha" );
+ self->alpha = mlt_cache_item_data( self->alpha_cache, NULL );
// Refresh the image
- refresh_image( this, frame, *width, *height );
+ refresh_image( self, frame, *format, *width, *height );
// Get width and height (may have changed during the refresh)
- *width = this->width;
- *height = this->height;
- *format = this->alpha ? mlt_image_rgb24a : mlt_image_rgb24;
+ *width = self->width;
+ *height = self->height;
+ *format = self->format;
// 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 ( self->image )
{
// Clone the image
- int image_size = this->width * this->height * ( this->alpha ? 4 :3 );
+ int image_size = mlt_image_format_size( self->format, self->width, self->height, NULL );
uint8_t *image_copy = mlt_pool_alloc( image_size );
- memcpy( image_copy, this->image, image_size );
+ memcpy( image_copy, self->image, image_size );
// Now update properties so we free the copy after
mlt_frame_set_image( frame, image_copy, image_size, mlt_pool_release );
// We're going to pass the copy on
*buffer = image_copy;
- mlt_log_debug( MLT_PRODUCER_SERVICE( &this->parent ), "%dx%d (%s)\n",
- this->width, this->height, mlt_image_format_name( *format ) );
+ mlt_log_debug( MLT_PRODUCER_SERVICE( &self->parent ), "%dx%d (%s)\n",
+ self->width, self->height, mlt_image_format_name( *format ) );
+ // Clone the alpha channel
+ if ( self->alpha )
+ {
+ image_copy = mlt_pool_alloc( self->width * self->height );
+ memcpy( image_copy, self->alpha, self->width * self->height );
+ mlt_frame_set_alpha( frame, image_copy, self->width * self->height, mlt_pool_release );
+ }
}
else
{
}
// Release references and locks
- pthread_mutex_unlock( &this->mutex );
- mlt_cache_item_close( this->image_cache );
- mlt_service_unlock( MLT_PRODUCER_SERVICE( &this->parent ) );
+ mlt_cache_item_close( self->pixbuf_cache );
+ mlt_cache_item_close( self->image_cache );
+ mlt_cache_item_close( self->alpha_cache );
+ mlt_service_unlock( MLT_PRODUCER_SERVICE( &self->parent ) );
return error;
}
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;
+ producer_pixbuf self = 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 );
+ if ( self->filenames == NULL && mlt_properties_get( producer_properties, "resource" ) != NULL )
+ load_filenames( self, producer_properties );
// Generate a frame
*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
- if ( *frame != NULL && this->count > 0 )
+ if ( *frame != NULL && self->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 );
+ mlt_properties_set_data( properties, "producer_pixbuf", self, 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 );
+ // Refresh the pixbuf
+ self->pixbuf_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.pixbuf" );
+ self->pixbuf = mlt_cache_item_data( self->pixbuf_cache, NULL );
+ refresh_pixbuf( self, *frame );
+ mlt_cache_item_close( self->pixbuf_cache );
// Set producer-specific frame properties
mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( producer_properties, "progressive" ) );
static void producer_close( mlt_producer parent )
{
- producer_pixbuf this = parent->child;
- pthread_mutex_destroy( &this->mutex );
+ producer_pixbuf self = parent->child;
parent->close = NULL;
mlt_service_cache_purge( MLT_PRODUCER_SERVICE(parent) );
mlt_producer_close( parent );
- mlt_properties_close( this->filenames );
- free( this );
+ mlt_properties_close( self->filenames );
+ free( self );
}
type: producer
identifier: pixbuf
title: GDK-PixBuf
-version: 1
+version: 2
copyright: Ushodaya Enterprises Limited
creator: Dan Dennedy
license: LGPLv2.1
type: string
description: >
The name of a graphics file loadable by a gdk-pixbuf loader.
- See /usr/lib/gdk-pixbuf/loaders.
+ See the output of gdk-pixbuf-query-loaders.
Definitely png, jpeg, tiff, pnm, and xpm will work.
- If "%" in filename, the filename is used with sprintf generate a
+ If "%" in filename, the filename is used with sprintf to generate a
filename from a counter for multi-file/flipbook animation. The file
sequence ends when numeric discontinuity >100.
+ If the file sequence does not begin within the count of 100 you
+ can pass the begin property like a query string parameter, for
+ example: anim-%04d.png?begin=1000.
+
If filename contains "/.all.", suffix with an extension to load all
pictures with matching extension from a directory.
mutable: yes
widget: spinner
- - identifier: real_width
+ - identifier: meta.media.width
title: Real width
type: integer
description: The original, unscaled width of the rendered image.
readonly: yes
- - identifier: real_height
+ - identifier: meta.media.height
title: Real height
type: integer
description: The original, unscaled height of the rendered image.
minimum: 0
maximum: 1
widget: checkbox
+
+ - identifier: force_aspect_ratio
+ title: Sample aspect ratio
+ type: float
+ description: Optionally override a (mis)detected aspect ratio
+ mutable: yes
+
+ - identifier: loop
+ title: Loop sequence of images indefinitively
+ description: when 1 (default) loop sequences of images, when 0, play them only once
+ type: integer
+ default: 1
+ minimum: 0
+ maximum: 1
+ widget: checkbox
*/
.file "scale_line_22_yuv_mmx.S"
.version "01.01"
+#if !defined(__MINGW32__) && !defined(__CYGWIN__)
.section .note.GNU-stack,"",%progbits
+#endif
.extern printf
.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:
plugin_mgr.o \
plugin_settings.o \
process.o \
+ producer_ladspa.o \
filter_jackrack.o \
filter_ladspa.o
OBJS += $(GPL_OBJS)
CFLAGS += -DGPL
CFLAGS += `pkg-config --cflags libxml-2.0`
-CFLAGS += `pkg-config --cflags glib-2.0`
+CFLAGS += `pkg-config $(PKGCONFIG_PREFIX) --cflags glib-2.0`
LDFLAGS += $(LIBDL)
LDFLAGS += `pkg-config --libs libxml-2.0`
-LDFLAGS += `pkg-config --libs glib-2.0`
+LDFLAGS += `pkg-config $(PKGCONFIG_PREFIX) --libs glib-2.0`
LDFLAGS += -lm
YML_FILES = *.yml
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/jackrack"
- install -m 644 $(YML_FILES) "$(DESTDIR)$(datadir)/mlt/jackrack"
- [ -f $(BLACKLIST) ] && install -m 644 $(BLACKLIST) "$(DESTDIR)$(datadir)/mlt/jackrack" || true
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/jackrack"
+ install -m 644 $(YML_FILES) "$(DESTDIR)$(mltdatadir)/jackrack"
+ [ -f $(BLACKLIST) ] && install -m 644 $(BLACKLIST) "$(DESTDIR)$(mltdatadir)/jackrack" || true
uninstall:
- rm "$(DESTDIR)$(libdir)/mlt/libmltjackrack$(LIBSUF)" 2> /dev/null || true
- rm -rf "$(DESTDIR)$(datadir)/mlt/jackrack"
+ rm "$(DESTDIR)$(moduledir)/libmltjackrack$(LIBSUF)" 2> /dev/null || true
+ rm -rf "$(DESTDIR)$(mltdatadir)/jackrack"
ifneq ($(wildcard .depend),)
include .depend
#!/bin/sh
-if [ "$help" != "1" ]
+if [ "$help" = "1" ]
then
+ cat << EOF
+JACK Rack options:
+
+ --gtk2-prefix=path - Override the gtk+-2.0 prefix for pkg-config
+
+EOF
+
+else
pkg-config jack
disable_jack=$?
fi
disable_ladspa=`[ -f "$ladspa_prefix/include/ladspa.h" ] && echo 0 || echo 1`
echo GPL=1 > config.mak
+
+ for i in "$@"
+ do
+ case $i in
+ --gtk2-prefix=* ) pkgconfig_prefix="${i#--gtk2-prefix=}" ;;
+ esac
+ done
+ [ "$pkgconfig_prefix" != "" ] && echo "PKGCONFIG_PREFIX=--define-variable=prefix=\"$pkgconfig_prefix\"" >> config.mak
fi
if [ "$disable_jack" = "1" -o "$disable_xml2" = "1" -o "$disable_ladspa" = "1" ]
char *dest = jack_port_get_buffer( self->ports[i], frames );
jack_ringbuffer_read( self->ringbuffers[i], dest, ring_size < jack_size ? ring_size : jack_size );
+ if ( ring_size < jack_size )
+ memset( dest + ring_size, 0, jack_size - ring_size );
}
return error;
if ( !ports )
ports = jack_get_ports( self->jack, NULL, NULL, JackPortIsPhysical | JackPortIsInput );
if ( ports )
- strcpy( con_name, ports[i] );
+ strncpy( con_name, ports[i], sizeof( con_name ));
else
snprintf( con_name, sizeof( con_name ), "system:playback_%d", i + 1);
+ con_name[ sizeof( con_name ) - 1 ] = '\0';
}
mlt_log_verbose( NULL, "JACK connect %s to %s\n", mlt_name, con_name );
jack_connect( self->jack, mlt_name, con_name );
mlt_audio_format afmt = mlt_audio_float;
// Set the preferred params of the test card signal
+ double speed = mlt_properties_get_double( MLT_FRAME_PROPERTIES(frame), "_speed" );
int channels = mlt_properties_get_int( properties, "channels" );
int frequency = mlt_properties_get_int( properties, "frequency" );
+ int scrub = mlt_properties_get_int( properties, "scrub_audio" );
int samples = mlt_sample_calculator( mlt_properties_get_double( properties, "fps" ), frequency, self->counter++ );
float *buffer;
init_audio = 0;
}
- if ( init_audio == 0 )
+ if ( init_audio == 0 && ( speed == 1.0 || speed == 0.0 ) )
{
int i;
size_t mlt_size = samples * sizeof(float);
float volume = mlt_properties_get_double( properties, "volume" );
+ if ( !scrub && speed == 0.0 )
+ volume = 0.0;
+
if ( volume != 1.0 )
{
float *p = buffer;
int64_t playtime = 0;
struct timespec tm = { 0, 100000 };
// int last_position = -1;
+
+ pthread_mutex_lock( &self->refresh_mutex );
self->refresh_count = 0;
+ pthread_mutex_unlock( &self->refresh_mutex );
// Loop until told not to
while( self->running )
type: integer
minimum: 1
default: 2
+
- identifier: out_1
title: Send L
type: string
+
- identifier: out_2
title: Send R
type: string
+
- identifier: volume
title: Volume
type: float
minimum: 0.0
default: 1.0
+
- identifier: refresh
description: >
Applications should set this to update the video frame when paused.
type: integer
minimum: 0
maximum: 1
+
+ - identifier: audio_off
+ title: Audio off
+ type: integer
+ description: If 1, disable audio output
+ mutable: yes
+ minimum: 0
+ maximum: 1
+ default: 0
+ widget: checkbox
+
+ - identifier: scrub_audio
+ title: Audio scrubbing
+ type: integer
+ description: If enabled, sound is played even when the speed is not normal.
+ mutable: yes
+ minimum: 0
+ maximum: 1
+ default: 0
+ widget: checkbox
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 );
+extern mlt_producer producer_ladspa_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
plugin_mgr_t *g_jackrack_plugin_mgr = NULL;
#endif
static mlt_properties metadata( mlt_service_type type, const char *id, char *data )
{
char file[ PATH_MAX ];
- snprintf( file, PATH_MAX, "%s/jackrack/%s",
+ if( type == filter_type )
+ {
+ snprintf( file, PATH_MAX, "%s/jackrack/%s",
mlt_environment( "MLT_DATA" ), strncmp( id, "ladspa.", 7 ) ? data : "filter_ladspa.yml" );
+ }
+ else
+ {
+ snprintf( file, PATH_MAX, "%s/jackrack/%s",
+ mlt_environment( "MLT_DATA" ), strncmp( id, "ladspa.", 7 ) ? data : "producer_ladspa.yml" );
+ }
mlt_properties result = mlt_properties_parse_yaml( file );
#ifdef GPL
if ( LADSPA_IS_HINT_LOGARITHMIC( hint_descriptor ) )
mlt_properties_set( p, "scale", "log" );
}
- p = mlt_properties_new();
- snprintf( key, sizeof(key), "%d", i );
- mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL );
- mlt_properties_set( p, "identifier", "wetness" );
- mlt_properties_set( p, "title", "Wet/Dry" );
- mlt_properties_set( p, "type", "float" );
- mlt_properties_set_double( p, "default", 1 );
- mlt_properties_set_double( p, "minimum", 0 );
- mlt_properties_set_double( p, "maximum", 1 );
+
+ if( type == filter_type )
+ {
+ p = mlt_properties_new();
+ snprintf( key, sizeof(key), "%d", i );
+ mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL );
+ mlt_properties_set( p, "identifier", "wetness" );
+ mlt_properties_set( p, "title", "Wet/Dry" );
+ mlt_properties_set( p, "type", "float" );
+ mlt_properties_set_double( p, "default", 1 );
+ mlt_properties_set_double( p, "minimum", 0 );
+ mlt_properties_set_double( p, "maximum", 1 );
+ }
}
}
#endif
char *s = malloc( strlen( "ladpsa." ) + 21 );
sprintf( s, "ladspa.%lu", desc->id );
- MLT_REGISTER( filter_type, s, filter_ladspa_init );
- MLT_REGISTER_METADATA( filter_type, s, metadata, NULL );
+
+ if( desc->has_input )
+ {
+ MLT_REGISTER( filter_type, s, filter_ladspa_init );
+ MLT_REGISTER_METADATA( filter_type, s, metadata, NULL );
+ }
+ else
+ {
+ MLT_REGISTER( producer_type, s, producer_ladspa_init );
+ MLT_REGISTER_METADATA( producer_type, s, metadata, NULL );
+ }
+
free( s );
}
mlt_factory_register_for_clean_up( g_jackrack_plugin_mgr, (mlt_destructor) plugin_mgr_destroy );
static void on_jack_start( mlt_properties owner, mlt_properties properties )
{
- fprintf(stderr, "%s\n", __FUNCTION__);
+ mlt_log_verbose( NULL, "%s\n", __FUNCTION__ );
jack_client_t *jack_client = mlt_properties_get_data( properties, "jack_client", NULL );
jack_transport_start( jack_client );
}
static void on_jack_stop( mlt_properties owner, mlt_properties properties )
{
- fprintf(stderr, "%s\n", __FUNCTION__);
+ mlt_log_verbose( NULL, "%s\n", __FUNCTION__ );
jack_client_t *jack_client = mlt_properties_get_data( properties, "jack_client", NULL );
jack_transport_stop( jack_client );
}
static void on_jack_seek( mlt_properties owner, mlt_filter filter, mlt_position *position )
{
mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
-
-
+ mlt_log_verbose( MLT_FILTER_SERVICE(filter), "%s: %d\n", __FUNCTION__, *position );
mlt_properties_set_int( properties, "_sync_guard", 1 );
- mlt_properties_set_position( properties, "_jack_seek", *position );
- return;
-
-
mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
jack_client_t *jack_client = mlt_properties_get_data( properties, "jack_client", NULL );
jack_nframes_t jack_frame = jack_get_sample_rate( jack_client );
jack_frame *= *position / mlt_profile_fps( profile );
-
- fprintf(stderr, "%s: %d\n", __FUNCTION__, *position);
jack_transport_locate( jack_client, jack_frame );
}
sizeof( float *) * channels, mlt_pool_release, NULL );
mlt_properties_set_data( properties, "jack_input_buffers", jack_input_buffers,
sizeof( float *) * channels, mlt_pool_release, NULL );
-
- // Start Jack processing - required before registering ports
- pthread_mutex_lock( &g_activate_mutex );
- jack_activate( jack_client );
- pthread_mutex_unlock( &g_activate_mutex );
// Register Jack ports
for ( i = 0; i < channels; i++ )
}
}
+ // Start Jack processing
+ pthread_mutex_lock( &g_activate_mutex );
+ jack_activate( jack_client );
+ pthread_mutex_unlock( &g_activate_mutex );
+
// Establish connections
for ( i = 0; i < channels; i++ )
{
}
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 );
+ if ( ring_size < jack_size )
+ memset( &jack_output_buffers[i][ring_size], 0, jack_size - ring_size );
// Return audio through in port
jack_input_buffers[i] = jack_port_get_buffer( jack_input_ports[i], frames );
}
}
+ // Often jackd does not send the stopped event through the JackSyncCallback
+ jack_client_t *jack_client = mlt_properties_get_data( properties, "jack_client", NULL );
+ jack_position_t jack_pos;
+ jack_transport_state_t state = jack_transport_query( jack_client, &jack_pos );
+ int transport_state = mlt_properties_get_int( properties, "_transport_state" );
+ if ( state != transport_state )
+ {
+ mlt_properties_set_int( properties, "_transport_state", state );
+ if ( state == JackTransportStopped )
+ jack_sync( state, &jack_pos, filter );
+ }
+
return err;
}
jack_ringbuffer_read( input_buffers[j], (char*)( q + j * *samples ), size );
}
- // Do JACK seeking if requested
+ // help jack_sync() indicate when we are rolling
mlt_position pos = mlt_frame_get_position( frame );
mlt_properties_set_position( filter_properties, "_last_pos", pos );
- if ( pos == mlt_properties_get_position( filter_properties, "_jack_seek" ) )
- {
- jack_client_t *jack_client = mlt_properties_get_data( filter_properties, "jack_client", NULL );
- jack_position_t jack_pos;
- jack_transport_query( jack_client, &jack_pos );
- double fps = mlt_profile_fps( mlt_service_profile( MLT_FILTER_SERVICE(filter) ) );
- jack_nframes_t jack_frame = jack_pos.frame_rate * pos / fps;
- jack_transport_locate( jack_client, jack_frame );
- mlt_properties_set_position( filter_properties, "_jack_seek", -1 );
- }
return 0;
}
mlt_filter this = mlt_filter_new( );
if ( this != NULL )
{
- char name[14];
-
+ char name[16];
+ char *jack_client_name;
+ jack_status_t status = 0;
+
snprintf( name, sizeof( name ), "mlt%d", getpid() );
- jack_client_t *jack_client = jack_client_open( name, JackNullOption, NULL );
+ jack_client_t *jack_client = jack_client_open( name, JackNullOption, &status, NULL );
if ( jack_client )
{
+ if ( status & JackNameNotUnique )
+ {
+ jack_client_name = jack_get_client_name ( jack_client );
+ strcpy( name, jack_client_name );
+ }
+
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 ) );
}
saved_plugin = NULL;
}
-
+
+ if ( !saved_plugin )
+ return;
+
/* initialize plugin parameters */
plugin->enabled = settings_get_enabled (saved_plugin->settings);
plugin->wet_dry_enabled = settings_get_wet_dry_enabled (saved_plugin->settings);
pd->control_port_indicies = NULL;
pd->aux_channels = 0;
pd->aux_are_input = TRUE;
+ pd->has_input = TRUE;
}
static void
if (icount == ocount)
pd->channels = icount;
+ else if( icount == 0 )
+ {
+ pd->channels = ocount;
+ pd->has_input = FALSE;
+ }
else
{ /* deal with auxilliary ports */
unsigned long ** port_indicies;
unsigned long control_port_count;
unsigned long * control_port_indicies;
+
+ gboolean has_input;
};
plugin_desc_t * plugin_desc_new ();
ocount++;
}
- if (icount == 0 || ocount == 0)
+ if (ocount == 0)
return FALSE;
return TRUE;
int err;
/* open the object file */
- dl_handle = dlopen (filename, RTLD_LAZY);
+ dl_handle = dlopen (filename, RTLD_NOW);
if (!dl_handle)
{
mlt_log_info( NULL, "%s: error opening shared object file '%s': %s\n",
}
/* input buffers for first plugin */
- plugin_connect_input_ports (first_enabled, procinfo->jack_input_buffers);
+ if( plugin->desc->has_input )
+ plugin_connect_input_ports (first_enabled, procinfo->jack_input_buffers);
}
void
for (channel = 0; channel < procinfo->channels; channel++)
{
- procinfo->jack_input_buffers[channel] = inputs[channel];
- if (!procinfo->jack_input_buffers[channel])
+ if(get_first_enabled_plugin (procinfo)->desc->has_input)
{
- mlt_log_verbose( NULL, "%s: no jack buffer for input port %ld\n", __FUNCTION__, channel);
- return 1;
+ procinfo->jack_input_buffers[channel] = inputs[channel];
+ if (!procinfo->jack_input_buffers[channel])
+ {
+ mlt_log_verbose( NULL, "%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])
{
--- /dev/null
+/*
+ * producer_ladspa.c -- LADSPA plugin producer
+ * Copyright (C) 2013 Ushodaya Enterprises Limited
+ * Author: Brian Matherly <pez4brian@yahoo.com>
+ *
+ * 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 <framework/mlt_producer.h>
+#include <framework/mlt_frame.h>
+#include <framework/mlt_log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string.h>
+
+#include "jack_rack.h"
+
+#define BUFFER_LEN 10000
+
+/** One-time initialization of jack rack.
+*/
+
+static jack_rack_t* initialise_jack_rack( mlt_properties properties, int channels )
+{
+ jack_rack_t *jackrack = NULL;
+ unsigned long plugin_id = mlt_properties_get_int64( properties, "_pluginid" );
+
+ // Start JackRack
+ if ( plugin_id )
+ {
+ // Create JackRack without Jack client name so that it only uses LADSPA
+ jackrack = jack_rack_new( NULL, channels );
+ mlt_properties_set_data( properties, "_jackrack", jackrack, 0,
+ (mlt_destructor) jack_rack_destroy, NULL );
+
+ // Load one LADSPA plugin by its UniqueID
+ plugin_desc_t *desc = plugin_mgr_get_any_desc( jackrack->plugin_mgr, plugin_id );
+ plugin_t *plugin;
+
+ if ( desc && ( plugin = jack_rack_instantiate_plugin( jackrack, desc ) ) )
+ {
+ LADSPA_Data value;
+ int index, c;
+
+ plugin->enabled = TRUE;
+ plugin->wet_dry_enabled = FALSE;
+ for ( index = 0; index < desc->control_port_count; index++ )
+ {
+ // Apply the control port values
+ char key[20];
+ value = plugin_desc_get_default_control_value( desc, index, sample_rate );
+ snprintf( key, sizeof(key), "%d", index );
+ if ( mlt_properties_get( properties, key ) )
+ value = mlt_properties_get_double( properties, key );
+ for ( c = 0; c < plugin->copies; c++ )
+ plugin->holders[c].control_memory[index] = value;
+ }
+ process_add_plugin( jackrack->procinfo, plugin );
+ }
+ else
+ {
+ mlt_log_error( properties, "failed to load plugin %lu\n", plugin_id );
+ }
+ }
+
+ return jackrack;
+}
+
+static int producer_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+{
+ // Get the producer service
+ mlt_producer producer = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "_producer_ladspa", NULL );
+ mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
+ int size = 0;
+ LADSPA_Data** output_buffers = NULL;
+ int i = 0;
+
+ // Initialize LADSPA if needed
+ jack_rack_t *jackrack = mlt_properties_get_data( producer_properties, "_jackrack", NULL );
+ if ( !jackrack )
+ {
+ sample_rate = *frequency; // global inside jack_rack
+ jackrack = initialise_jack_rack( producer_properties, *channels );
+ }
+
+ if( jackrack )
+ {
+ // Correct the returns if necessary
+ *samples = *samples <= 0 ? 1920 : *samples;
+ *channels = *channels <= 0 ? 2 : *channels;
+ *frequency = *frequency <= 0 ? 48000 : *frequency;
+ *format = mlt_audio_float;
+
+ // Calculate the size of the buffer
+ size = *samples * *channels * sizeof( float );
+
+ // Allocate the buffer
+ *buffer = mlt_pool_alloc( size );
+
+ // Initialize the LADSPA output buffer.
+ output_buffers = mlt_pool_alloc( sizeof( LADSPA_Data* ) * *channels );
+ for ( i = 0; i < *channels; i++ )
+ {
+ output_buffers[i] = (LADSPA_Data*) *buffer + i * *samples;
+ }
+
+ // Do LADSPA processing
+ process_ladspa( jackrack->procinfo, *samples, NULL, output_buffers );
+ mlt_pool_release( output_buffers );
+
+ // Set the buffer for destruction
+ mlt_frame_set_audio( frame, *buffer, *format, size, mlt_pool_release );
+ }
+
+ 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 ) );
+
+ // Check that we created a frame and initialize it
+ if ( *frame != NULL )
+ {
+ // Obtain properties of frame
+ mlt_properties frame_properties = MLT_FRAME_PROPERTIES( *frame );
+
+ // Update timecode on the frame we're creating
+ mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
+
+ // Save the producer to be used in get_audio
+ mlt_properties_set_data( frame_properties, "_producer_ladspa", producer, 0, NULL, NULL );
+
+ // Push the get_audio method
+ mlt_frame_push_audio( *frame, producer_get_audio );
+ }
+
+ // Calculate the next time code
+ mlt_producer_prepare_next( producer );
+
+ return 0;
+}
+
+/** Destructor for the producer.
+*/
+
+static void producer_close( mlt_producer producer )
+{
+ producer->close = NULL;
+ mlt_producer_close( producer );
+ free( producer );
+}
+
+/** Constructor for the producer.
+*/
+
+mlt_producer producer_ladspa_init( mlt_profile profile, mlt_service_type type, const char* id, char* arg )
+{
+ // Create a new producer object
+ mlt_producer producer = mlt_producer_new( profile );
+
+ if ( producer != NULL )
+ {
+ mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
+
+ producer->get_frame = producer_get_frame;
+ producer->close = ( mlt_destructor )producer_close;
+
+ // Save the plugin ID.
+ if ( !strncmp( id, "ladspa.", 7 ) )
+ {
+ mlt_properties_set( properties, "_pluginid", id + 7 );
+ }
+
+ // Make sure the plugin ID is valid.
+ unsigned long plugin_id = mlt_properties_get_int64( properties, "_pluginid" );
+ if( plugin_id < 1000 || plugin_id > 0x00FFFFFF )
+ {
+ producer_close( producer );
+ producer = NULL;
+ }
+ }
+ return producer;
+}
--- /dev/null
+schema_version: 0.1
+type: producer
+identifier: ladspa
+title: LADSPA
+version: 1
+copyright: Copyright (C) 2013 Ushodaya Enterprises Limited
+license: GPLv2
+language: en
+creator: Brian Matherly
+tags:
+ - Audio
+description: Generate audio using LADSPA plugins.
+notes: >
+ Automatically adapts to the number of channels and sampling rate of the consumer.
+
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/kdenlive"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/kdenlive"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/kdenlive"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/kdenlive"
ifneq ($(wildcard .depend),)
include .depend
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 pos = mlt_properties_get_position( properties, "frame" ) + mlt_producer_get_in( mlt_frame_get_original_producer( frame ) );
mlt_position currentpos = mlt_filter_get_position( filter, frame );
int do_freeze = 0;
if ( !freeze_frame || mlt_properties_get_position( properties, "_frame" ) != pos )
{
// freeze_frame has not been fetched yet or is not useful, so fetch it and cache it.
- mlt_producer producer = mlt_frame_get_original_producer(frame);
+ // get parent producer
+ mlt_producer producer = mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) );
mlt_producer_seek( producer, pos );
// Get the frame
mlt_service_get_frame( mlt_producer_service(producer), &freeze_frame, 0 );
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( frame ) );
mlt_properties_set_int( freeze_properties, "progressive", mlt_properties_get_int( props, "progressive" ) );
mlt_properties_set_int( freeze_properties, "consumer_deinterlace", mlt_properties_get_int( props, "consumer_deinterlace" ) || mlt_properties_get_int( properties, "deinterlace" ) );
- mlt_properties_set_double( freeze_properties, "output_ratio", mlt_properties_get_double( props, "output_ratio" ) );
mlt_properties_set_data( properties, "freeze_frame", freeze_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
mlt_properties_set_position( properties, "_frame", pos );
}
uint8_t *first_alpha = mlt_properties_get_data( first_frame_properties, "alpha", NULL );
if ( !first_image )
{
- mlt_properties_set_double( first_frame_properties, "consumer_aspect_ratio", mlt_properties_get_double( frame_properties, "consumer_aspect_ratio" ) );
mlt_properties_set( first_frame_properties, "rescale.interp", mlt_properties_get( frame_properties, "rescale.interp" ) );
int error = mlt_frame_get_image( first_frame, &first_image, format, width, height, writable );
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
- // Construct a new frame
- *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
- if( frame != NULL )
+ if ( frame )
{
+ // Construct a new frame
+ *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
+
// Stack the producer and producer's get image
mlt_frame_push_service( *frame, (void*) index );
mlt_frame_push_service( *frame, producer );
// Give the returned frame temporal identity
mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
- mlt_properties_set_int( frame_properties, "real_width", mlt_properties_get_int( properties, "width" ) );
- mlt_properties_set_int( frame_properties, "real_height", mlt_properties_get_int( properties, "height" ) );
+ mlt_properties_set_int( frame_properties, "meta.media.width", mlt_properties_get_int( properties, "width" ) );
+ mlt_properties_set_int( frame_properties, "meta.media.height", mlt_properties_get_int( properties, "height" ) );
mlt_properties_pass_list( frame_properties, properties, "width, height" );
}
if ( !arg ) return NULL;
mlt_producer producer = NULL;
producer = calloc( 1, sizeof( struct mlt_producer_s ) );
- mlt_producer_init( producer, NULL );
+ if ( !producer )
+ return NULL;
+
+ if ( mlt_producer_init( producer, NULL ) )
+ {
+ free( producer );
+ return NULL;
+ }
// Wrap loader
mlt_producer real_producer;
{
double real_length = ( (double) mlt_producer_get_length( real_producer ) ) / speed;
mlt_properties_set_position( properties, "length", real_length );
+ mlt_properties real_properties = MLT_PRODUCER_PROPERTIES( real_producer );
+ const char* service = mlt_properties_get( real_properties, "mlt_service" );
+ if ( service && !strcmp( service, "avformat" ) )
+ {
+ int n = mlt_properties_count( real_properties );
+ int i;
+ for ( i = 0; i < n; i++ )
+ {
+ if ( strstr( mlt_properties_get_name( real_properties, i ), "stream.frame_rate" ) )
+ {
+ double source_fps = mlt_properties_get_double( real_properties, mlt_properties_get_name( real_properties, i ) );
+ if ( source_fps > mlt_profile_fps( profile ) )
+ {
+ mlt_properties_set_double( real_properties, "force_fps", source_fps * speed );
+ mlt_properties_set_position( real_properties, "length", real_length );
+ mlt_properties_set_position( real_properties, "out", real_length - 1 );
+ speed = 1.0;
+ }
+ break;
+ }
+ }
+ }
}
mlt_properties_set_position( properties, "out", mlt_producer_get_length( producer ) - 1 );
rm -f $(OBJS) $(TARGET) $(CPPOBJS)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
ifneq ($(wildcard .depend),)
include .depend
}
idx1 = new AVISimpleIndex;
memset( idx1, 0, sizeof( AVISimpleIndex ) );
+ memset( dmlh, 0, sizeof( dmlh ) );
+ memset( &mainHdr, 0, sizeof( mainHdr ) );
+ memset( &streamHdr, 0, sizeof( streamHdr ) );
}
isUpdateIdx1 = avi.isUpdateIdx1;
+ odml_list = 0;
+ dmlh_chunk = 0;
+ memset( &streamHdr, 0, sizeof( streamHdr ) );
}
}
AVI1File::AVI1File() : AVIFile()
-{}
+{
+ memset( &dvinfo, 0, sizeof( dvinfo ) );
+}
AVI1File::~AVI1File()
framesWritten( 0 ), filename( "" )
{
/* empty body */
+ timeStamp = 0;
+ everyNthFrame = 0;
+ framesToSkip = 0;
+ maxFileSize = 0;
}
RawHandler::RawHandler() : fd( -1 )
{
extension = ".dv";
+ numBlocks = 0;
}
return false;
if ( read( fd, data, 4 ) < 0 )
return false;
- lseek( fd, 0, SEEK_SET );
+ if ( lseek( fd, 0, SEEK_SET ) < 0 )
+ return false;
numBlocks = ( ( data[ 3 ] & 0x80 ) == 0 ) ? 250 : 300;
filename = s;
return true;
extension = ".avi";
for ( int c = 0; c < 4; c++ )
audioChannels[ c ] = NULL;
+ memset( &dvinfo, 0, sizeof( dvinfo ) );
}
case AVI_DV1_FORMAT:
fail_null( avi = new AVI1File );
- if ( avi->Create( filename.c_str() ) == false )
+ if ( !avi || 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 )
+ if ( !avi || avi->Create( filename.c_str() ) == false )
return false;
//if ( GetOpenDML() )
//avi->Init( videoInfo.isPAL ? AVI_PAL : AVI_NTSC, audioInfo.frequency,
if ( kino_wrapper_open( wrapper, filename ) )
{
- producer_kino this = calloc( sizeof( struct producer_kino_s ), 1 );
+ producer_kino this = calloc( 1, sizeof( struct producer_kino_s ) );
if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 )
{
RIFFDirEntry::RIFFDirEntry()
-{}
+{
+ type = 0;
+ name = 0;
+ length = 0;
+ offset = 0;
+ parent = 0;
+ written = 0;
+}
RIFFDirEntry::RIFFDirEntry ( FOURCC t, FOURCC n, int l, int o, int p ) : type( t ), name( n ), length( l ), offset( o ), parent( p ), written( 0 )
{
FOURCC type;
DWORD length;
- off_t filesize;
+ off_t filesize = 0;
off_t pos;
int container = AddDirectoryEntry( make_fourcc( "FILE" ), make_fourcc( "FILE" ), 0, RIFF_NO_PARENT );
pos = lseek( fd, 0, SEEK_SET );
+ fail_if( pos == -1 );
/* calculate file size from RIFF header instead from physical file. */
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/linsys"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/linsys"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/linsys"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/linsys"
ifneq ($(wildcard .depend),)
include .depend
mlt_consumer consumer_SDIstream_init(mlt_profile profile, mlt_service_type type, const char *id, char *arg) {
// Create the consumer object
- consumer_SDIstream this = calloc(sizeof(struct consumer_SDIstream_s), 1);
+ consumer_SDIstream this = calloc( 1, sizeof(struct consumer_SDIstream_s) );
// If malloc and consumer init ok
if (this != NULL && mlt_consumer_init(&this->parent, this, profile) == 0) {
// Set additional device file defaults
struct stat st;
- int fd = stat(this->device_file_video, &st);
+ int fd = -1;
+ if (this->device_file_video)
+ fd = stat(this->device_file_video, &st);
if (fd == -1) {
if (this->device_file_video)
free(this->device_file_video);
} else {
close(fd);
}
- } else if (strstr(this->device_file_video, "sdivideotx")) {
+ } else if (this->device_file_video &&
+ strstr(this->device_file_video, "sdivideotx")) {
if (this->device_file_audio)
free(this->device_file_audio);
this->device_file_audio = strdup("/dev/sdiaudiotx0");
} else {
this->blanking = mlt_properties_get_int(MLT_CONSUMER_PROPERTIES( consumer ), "blanking");
}
- } else if (strstr(this->device_file_video, "sdivideotx")) {
+ } else if (this->device_file_video && strstr(this->device_file_video, "sdivideotx")) {
this->blanking = 0;
} else {
// set default value without HD board, also with blanking
this->audio_format.sample_rate = 48000;
this->pix_fmt = mlt_image_yuv422;
- if (!sdi_init(this->device_file_video, this->device_file_audio, this->blanking, mlt_service_profile((mlt_service) consumer), &this->audio_format)) {
+ if (this->device_file_video && this->device_file_audio &&
+ !sdi_init(this->device_file_video, this->device_file_audio, this->blanking, mlt_service_profile((mlt_service) consumer), &this->audio_format)) {
mlt_log_fatal( MLT_CONSUMER_SERVICE(consumer), "failed to initialize\n" );
mlt_events_fire( MLT_CONSUMER_PROPERTIES(consumer), "consumer-fatal-error", NULL );
}
}
if (info.blanking) {
- printf("SDI frame size: %li\n", sdi_frame_size);
+ printf("SDI frame size: %"PRIu64"\n", sdi_frame_size);
} else {
- printf("Frame size for active video: %li\n", sdi_frame_size);
+ printf("Frame size for active video: %"PRIu64"\n", sdi_frame_size);
}
/**
// Buffer size
// audio buffer per frame (Bytes) = sample rate / frame rate * ( sample size / 1Byte ) x channels
value = itoa(
- audio_format->sample_rate / (myProfile->frame_rate_num / myProfile->frame_rate_den) * sample_size / 8
- * audio_format->channels);
+ (uint64_t) audio_format->sample_rate / ( (uint64_t) myProfile->frame_rate_num / (uint64_t) myProfile->frame_rate_den) * (uint64_t) sample_size / 8
+ * (uint64_t) audio_format->channels);
setSDIAudioProperties(SETTING_BUFFER_SIZE_AUDIO, value, device_audio);
free(value);
rm -f luma
install: all
- install -d $(DESTDIR)$(datadir)/mlt/lumas/PAL
- install -d $(DESTDIR)$(datadir)/mlt/lumas/NTSC
- install -m 644 PAL/* $(DESTDIR)$(datadir)/mlt/lumas/PAL
- install -m 644 NTSC/* $(DESTDIR)$(datadir)/mlt/lumas/NTSC
+ install -d $(DESTDIR)$(mltdatadir)/lumas/PAL
+ install -d $(DESTDIR)$(mltdatadir)/lumas/NTSC
+ install -m 644 PAL/* $(DESTDIR)$(mltdatadir)/lumas/PAL
+ install -m 644 NTSC/* $(DESTDIR)$(mltdatadir)/lumas/NTSC
else if ( !strcmp( argv[ arg ], "-type" ) )
this.type = atoi( argv[ ++ arg ] );
else if ( !strcmp( argv[ arg ], "-w" ) )
- this.w = atoi( argv[ ++ arg ] );
+ {
+ int tmp = atoi( argv[ ++ arg ] );
+ // TODO: is there an upper bound?
+ if ( tmp )
+ this.w = tmp;
+ else
+ return 1;
+ }
else if ( !strcmp( argv[ arg ], "-h" ) )
- this.h = atoi( argv[ ++ arg ] );
+ {
+ int tmp = atoi( argv[ ++ arg ] );
+ // TODO: is there an upper bound?
+ if ( tmp )
+ this.h = tmp;
+ else return 1;
+ }
else if ( !strcmp( argv[ arg ], "-bands" ) )
- this.bands = atoi( argv[ ++ arg ] );
+ {
+ int tmp = atoi( argv[ ++ arg ] );
+ // TODO: is there an upper bound?
+ if ( tmp >= 0 )
+ this.bands = tmp;
+ else
+ return 1;
+ }
else if ( !strcmp( argv[ arg ], "-rband" ) )
this.rband = atoi( argv[ ++ arg ] );
else if ( !strcmp( argv[ arg ], "-hmirror" ) )
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/motion_est"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/motion_est"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/motion_est"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/motion_est"
test: $(TARGET)
~/mlt-devel/mlt/src/melt/melt -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
{
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, "_serialize" ) == 1 )
+ {
+ // Add the vector change to the list
+ mlt_geometry key_frames = mlt_properties_get_data( filter_properties, "motion_vector_list", NULL );
+ if ( !key_frames )
+ {
+ key_frames = mlt_geometry_init();
+ mlt_properties_set_data( filter_properties, "motion_vector_list", key_frames, 0,
+ (mlt_destructor) mlt_geometry_close, (mlt_serialiser) mlt_geometry_serialise );
+ if ( key_frames )
+ mlt_geometry_set_length( key_frames, mlt_filter_get_length2( filter, frame ) );
+ }
+ if ( key_frames )
+ {
+ struct mlt_geometry_item_s item;
+ item.frame = (int) mlt_frame_get_position( frame );
+ item.key = 1;
+ item.x = boundry.x;
+ item.y = boundry.y;
+ item.w = boundry.w;
+ item.h = boundry.h;
+ item.mix = 0;
+ item.f[0] = item.f[1] = item.f[2] = item.f[3] = 1;
+ item.f[4] = 0;
+ mlt_geometry_insert( key_frames, &item );
+ }
+ }
+
if( mlt_properties_get_int( filter_properties, "obscure" ) == 1 )
{
mlt_filter obscure = mlt_properties_get_data( filter_properties, "_obscure", NULL );
/* modify the frame with the current geometry */
mlt_frame_push_service( frame, this);
mlt_frame_push_get_image( frame, attach_boundry_to_frame );
-
-
+ mlt_properties properties = MLT_FILTER_PROPERTIES( this );
/* apply the motion estimation filter */
- mlt_filter motion_est = mlt_properties_get_data( MLT_FILTER_PROPERTIES(this), "_motion_est", NULL );
+ mlt_filter motion_est = mlt_properties_get_data( properties, "_motion_est", NULL );
+ /* Pass motion_est properties */
+ mlt_properties_pass( MLT_FILTER_PROPERTIES( motion_est ), properties, "motion_est." );
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 );
+ mlt_filter vismv = mlt_properties_get_data( properties, "_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_properties_set_data( properties, "_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 );
+ mlt_filter obscure = mlt_properties_get_data( properties, "_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_properties_set_data( properties, "_obscure", obscure, 0, (mlt_destructor)mlt_filter_close, NULL );
}
mlt_filter_process( obscure, frame );
/* 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 )
+ {
+ char *property = mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "bounding" );
+ if ( property )
+ {
+ mlt_geometry geometry = mlt_geometry_init( );
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE(filter) );
+ if ( geometry )
+ {
+ mlt_geometry_parse( geometry, property, 0, profile->width, profile->height );
+ bounds = calloc( 1, sizeof(*bounds) );
+ mlt_properties_set_data( MLT_FILTER_PROPERTIES(filter), "bounds", bounds, sizeof(*bounds), free, NULL );
+ mlt_geometry_fetch( geometry, bounds, 0 );
+ }
+ }
+ }
+
if( bounds != NULL ) {
// translate pixel units (from bounds) to macroblock units
// make sure whole macroblock stays within bounds
if( c->comparison_average > 10 * c->mb_w * c->mb_h &&
c->comparison_average > c->previous_msad * 2 )
{
- fprintf(stderr, " - SAD: %d <<Shot change>>\n", c->comparison_average);
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_log_verbose( MLT_FILTER_SERVICE(filter), "shot change: %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;
+
+ // Add the shot change to the list
+ mlt_geometry key_frames = mlt_properties_get_data( properties, "shot_change_list", NULL );
+ if ( !key_frames )
+ {
+ key_frames = mlt_geometry_init();
+ mlt_properties_set_data( properties, "shot_change_list", key_frames, 0,
+ (mlt_destructor) mlt_geometry_close, (mlt_serialiser) mlt_geometry_serialise );
+ if ( key_frames )
+ mlt_geometry_set_length( key_frames, mlt_filter_get_length2( filter, frame ) );
+ }
+ if ( key_frames )
+ {
+ struct mlt_geometry_item_s item;
+ item.frame = (int) c->current_frame_position;
+ item.x = c->comparison_average;
+ item.f[0] = 1;
+ item.f[1] = item.f[2] = item.f[3] = item.f[4] = 0;
+ mlt_geometry_insert( key_frames, &item );
+ }
}
else {
c->former_vectors_valid = 1;
static int slowmotion_get_frame( mlt_producer this, mlt_frame_ptr frame, int index )
{
+ if ( !frame )
+ return 1;
// Construct a new frame
*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( this ) );
TARGET = ../libmltnormalize$(LIBSUF)
OBJS = factory.o \
+ filter_audiolevel.o \
filter_volume.o
SRCS := $(OBJS:.o=.c)
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/normalize"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/normalize"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/normalize"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/normalize"
ifneq ($(wildcard .depend),)
include .depend
#include <limits.h>
#include <framework/mlt.h>
+extern mlt_filter filter_audiolevel_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
extern mlt_filter filter_volume_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
static mlt_properties metadata( mlt_service_type type, const char *id, void *data )
MLT_REPOSITORY
{
+ MLT_REGISTER( filter_type, "audiolevel", filter_audiolevel_init );
MLT_REGISTER( filter_type, "volume", filter_volume_init );
+ MLT_REGISTER_METADATA( filter_type, "audiolevel", metadata, "filter_audiolevel.yml" );
MLT_REGISTER_METADATA( filter_type, "volume", metadata, "filter_volume.yml" );
}
--- /dev/null
+/*
+ * filter_audiolevel.c -- get the audio level of each channel
+ * Copyright (C) 2002 Steve Harris
+ * Copyright (C) 2010 Marco Gittler <g.marco@freenet.de>
+ * Copyright (C) 2012 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt_filter.h>
+#include <framework/mlt_frame.h>
+#include <framework/mlt_log.h>
+
+#include <stdlib.h>
+#include <math.h>
+
+#define AMPTODBFS(n) (log10(n) * 20.0)
+
+//----------------------------------------------------------------------------
+// IEC standard dB scaling -- as borrowed from meterbridge (c) Steve Harris
+
+static inline double IEC_Scale(double dB)
+{
+ double fScale = 1.0f;
+
+ if (dB < -70.0f)
+ fScale = 0.0f;
+ else if (dB < -60.0f) // 0.0 .. 2.5
+ fScale = (dB + 70.0f) * 0.0025f;
+ else if (dB < -50.0f) // 2.5 .. 7.5
+ fScale = (dB + 60.0f) * 0.005f + 0.025f;
+ else if (dB < -40.0) // 7.5 .. 15.0
+ fScale = (dB + 50.0f) * 0.0075f + 0.075f;
+ else if (dB < -30.0f) // 15.0 .. 30.0
+ fScale = (dB + 40.0f) * 0.015f + 0.15f;
+ else if (dB < -20.0f) // 30.0 .. 50.0
+ fScale = (dB + 30.0f) * 0.02f + 0.3f;
+ else if (dB < -0.001f || dB > 0.001f) // 50.0 .. 100.0
+ fScale = (dB + 20.0f) * 0.025f + 0.5f;
+
+ return fScale;
+}
+
+static int filter_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+{
+ mlt_filter filter = mlt_frame_pop_audio( frame );
+ int iec_scale = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter), "iec_scale" );
+ *format = mlt_audio_s16;
+ int error = mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+ if ( error || !buffer ) return error;
+
+ int num_channels = *channels;
+ int num_samples = *samples > 200 ? 200 : *samples;
+ int num_oversample = 0;
+ int c, s;
+ char key[ 50 ];
+ int16_t *pcm = (int16_t*) *buffer;
+
+ for ( c = 0; c < *channels; c++ )
+ {
+ long val = 0;
+ double level = 0.0;
+
+ for ( s = 0; s < num_samples; s++ )
+ {
+ int sample = abs( pcm[c + s * num_channels] / 128 );
+ val += sample;
+ if ( sample == 128 )
+ num_oversample++;
+ else
+ num_oversample = 0;
+ // 10 samples @max => show max signal
+ if ( num_oversample > 10 )
+ {
+ level = 1.0;
+ break;
+ }
+ // if 3 samples over max => 1 peak over 0 db (0 dB = 40.0)
+ if ( num_oversample > 3 )
+ level = 41.0/42.0;
+ }
+ // max amplitude = 40/42, 3to10 oversamples=41, more then 10 oversamples=42
+ if ( level == 0.0 )
+ level = val / num_samples * 40.0/42.0 / 127.0;
+ if ( iec_scale )
+ level = IEC_Scale( AMPTODBFS( level ) );
+ sprintf( key, "meta.media.audio_level.%d", c );
+ mlt_properties_set_double( MLT_FRAME_PROPERTIES( frame ), key, level );
+ sprintf( key, "_audio_level.%d", c );
+ mlt_properties_set_double( MLT_FILTER_PROPERTIES( filter ), key, level );
+ mlt_log_debug( MLT_FILTER_SERVICE( filter ), "channel %d level %f\n", c, level );
+ }
+
+ return error;
+}
+
+/** Filter processing.
+*/
+
+static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
+{
+ mlt_frame_push_audio( frame, filter );
+ mlt_frame_push_audio( frame, filter_get_audio );
+ return frame;
+}
+
+/** Constructor for the filter.
+*/
+
+mlt_filter filter_audiolevel_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = mlt_filter_new();
+ if ( filter )
+ {
+ filter->process = filter_process;
+ mlt_properties_set_int( MLT_FILTER_PROPERTIES(filter), "iec_scale", 1 );
+ }
+ return filter;
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: audiolevel
+title: Audio Levels
+version: 1
+copyright: Dan Dennedy, Marco Gittler, and Steve Harris
+creator: Dan Dennedy
+contributor:
+ - Marco Gittler
+ - Steve Harris
+license: GPLv2
+language: en
+description: Compute the audio amplitude.
+notes: >
+ This filter provides the amplitude level as a percentage value in floating point.
+ This does not do any "slowing" of the data by averaging out peaks and
+ troughs of short duration like a VU meter.
+ Applications can also get this data on the frame as meta.media.audio_level.<N>
+ where <N> is the channel number starting with 0.
+tags:
+ - Audio
+parameters:
+ - identifier: iec_scale
+ title: Use IEC 60268-18 Scale
+ type: integer
+ minimum: 0
+ maximum: 1
+ default: 1
+ widget: checkbox
+
+ - identifier: _audio_level.<N>
+ description: >
+ <N> is the channel number starting with 0.
+ This is updated on every frame with audio.
+ readonly: yes
+ type: float
+ minimum: 0
+ maximum: 1
j++;
}
}
- smoothed /= j;
+ if (j) smoothed /= j;
// fprintf( stderr, "smoothed over %d values, result %f\n", j, smoothed );
return smoothed;
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 );
+ mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) );
if ( this != NULL && mlt_filter_init( this, NULL ) == 0 )
{
mlt_properties properties = MLT_FILTER_PROPERTIES( this );
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d $(DESTDIR)$(datadir)/mlt/oldfilm
- install -m 644 *.svg "$(DESTDIR)$(datadir)/mlt/oldfilm"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/oldfilm"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d $(DESTDIR)$(mltdatadir)/oldfilm
+ install -m 644 *.svg "$(DESTDIR)$(mltdatadir)/oldfilm"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/oldfilm"
ifneq ($(wildcard .depend),)
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" );
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_data ( properties , savename , savepic , sizeof(savepic) , mlt_pool_release, NULL );
+ mlt_properties_set_data ( properties , savename1 , savealpha , sizeof(savealpha) , 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 );
int h = *height;
int w = *width;
- if (maxcount==0)
- return 0;
-
int im=rand()%maxcount;
while (im-- ){
int h = *height;
int w = *width;
- int width_line = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "width" );
+ int line_width = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "line_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" ) ;
char buf[256];
char typebuf[256];
- if (!width_line)
+ if ( line_width < 1 )
return 0;
double position = mlt_filter_get_progress( filter, this );
while (num--){
int type=(rand()%3)+1;
int x1=(double)w*rand()/RAND_MAX;
- int dx=rand()%width_line;
+ int dx=rand()%line_width;
int x=0,y=0;
int ystart=rand()%h;
int yend=rand()%h;
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 ), "line_width", 2 );
+ mlt_properties_set_int( 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 ) ;
}
type: filter # consumer, filter, producer, or transition
identifier: lines
title: Scratchlines
-version: 0.2.5
+version: 0.2.6
copyright: Copyright (C) 2008 Marco Gittler
license: GPL
language: en
- need to do some speed improvement.
parameters:
- - identifier: width
+ - identifier: line_width
title: Width of line
type: integer
description: Linewidth in picture
--- /dev/null
+CFLAGS += -I../..
+
+LDFLAGS += -L../../framework -lmlt -lm
+
+include ../../../config.mak
+
+TARGET = ../libmltopengl$(LIBSUF)
+
+OBJS = factory.o
+
+CPPOBJS = fbo_input.o
+CPPOBJS += filter_glsl_manager.o
+CPPOBJS += filter_movit_blur.o
+CPPOBJS += filter_movit_convert.o
+CPPOBJS += filter_movit_crop.o
+CPPOBJS += filter_deconvolution_sharpen.o
+CPPOBJS += filter_movit_diffusion.o
+CPPOBJS += filter_movit_glow.o
+CPPOBJS += filter_lift_gamma_gain.o
+CPPOBJS += filter_movit_mirror.o
+CPPOBJS += filter_movit_opacity.o
+CPPOBJS += filter_movit_rect.o
+CPPOBJS += filter_movit_resample.o
+CPPOBJS += filter_movit_resize.o
+CPPOBJS += filter_movit_saturation.o
+CPPOBJS += filter_movit_vignette.o
+CPPOBJS += filter_white_balance.o
+CPPOBJS += mlt_movit_input.o
+CPPOBJS += transition_movit_mix.o
+CPPOBJS += transition_movit_overlay.o
+
+CXXFLAGS += -Wno-deprecated $(CFLAGS)
+CXXFLAGS += `pkg-config --cflags movit 2> /dev/null`
+
+SHADERDIR = `pkg-config --variable=shaderdir movit`
+CXXFLAGS += -DSHADERDIR=\"$(SHADERDIR)\"
+
+LDFLAGS += -L../../mlt++ -lmlt++
+
+ifeq ($(targetos), MinGW)
+ CXXFLAGS += `pkg-config --cflags glew`
+ LDFLAGS += -lmovit `pkg-config --libs-only-L glew` -lglew32 -lopengl32
+else
+ LDFLAGS += `pkg-config --libs movit 2> /dev/null`
+ifeq ($(targetos), Darwin)
+ CXXFLAGS += -FOpenGL
+ LDFLAGS += -framework OpenGL
+else
+ OBJS += consumer_xgl.o
+ LDFLAGS += -lpthread -lGL -lX11
+endif
+endif
+
+SRCS := $(OBJS:.o=.c) $(CPPOBJS:.o=.cpp)
+
+all: $(TARGET)
+
+$(TARGET): $(OBJS) $(CPPOBJS)
+ $(CXX) $(SHFLAGS) -o $@ $(OBJS) $(CPPOBJS) $(LDFLAGS)
+
+depend: $(SRCS)
+ $(CXX) -MM $(CXXFLAGS) $^ 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"
+ install -d "$(DESTDIR)$(datadir)/mlt/opengl/movit"
+ install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/opengl"
+
+ifneq ($(wildcard .depend),)
+include .depend
+endif
--- /dev/null
+#!/bin/sh
+
+if [ "$help" != "1" ]
+then
+ if ! $(pkg-config movit)
+ then
+ echo "- movit not found: disabling"
+ touch ../disable-opengl
+ exit 0
+ fi
+
+ echo > config.mak
+ case $targetos in
+ Darwin)
+ ;;
+ MinGW)
+ ;;
+ *)
+ ;;
+ esac
+ exit 0
+fi
--- /dev/null
+/*
+ * consumer_xgl.c
+ * Copyright (C) 2012 Christophe Thommeret
+ * Author: Christophe Thommeret <hftom@free.fr>
+ * Based on Nehe's GLX port by Mihael.Vrbanec@stud.uni-karlsruhe.de
+ * http://nehe.gamedev.net/
+ *
+ * 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
+ */
+
+
+#define GL_GLEXT_PROTOTYPES
+
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+#include <GL/glx.h>
+
+#include <X11/keysym.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+#include <pthread.h>
+
+#include <framework/mlt.h>
+
+
+#define STARTWIDTH 1280
+#define STARTHEIGHT 720
+
+
+extern int XInitThreads();
+
+
+
+typedef struct consumer_xgl_s *consumer_xgl;
+
+struct consumer_xgl_s
+{
+ struct mlt_consumer_s parent;
+ mlt_properties properties;
+ mlt_deque queue;
+ pthread_t thread;
+ int joined;
+ int running;
+ int playing;
+ int xgl_started;
+};
+
+
+typedef struct
+{
+ pthread_t thread;
+ int running;
+} thread_video;
+
+
+typedef struct
+{
+ int width;
+ int height;
+ double aspect_ratio;
+ GLuint texture;
+ pthread_mutex_t mutex;
+ int new;
+ mlt_frame mlt_frame_ref;
+} frame_new;
+
+
+typedef struct
+{
+ int width;
+ int height;
+ GLuint fbo;
+ GLuint texture;
+} fbo;
+
+
+typedef struct
+{
+ Display *dpy;
+ int screen;
+ Window win;
+ GLXContext ctx;
+} HiddenContext;
+
+
+typedef struct
+{
+ Display *dpy;
+ int screen;
+ Window win;
+ GLXContext ctx;
+ XSetWindowAttributes attr;
+ int x, y;
+ unsigned int width, height;
+ unsigned int depth;
+} GLWindow;
+
+
+static GLWindow GLWin;
+static HiddenContext hiddenctx;
+
+static frame_new new_frame;
+static fbo fb;
+static thread_video vthread;
+static consumer_xgl xgl;
+static mlt_filter glsl_manager;
+
+
+
+static void* video_thread( void *arg );
+
+static void update()
+{
+ int _width = GLWin.width;
+ int _height = GLWin.height;
+ GLfloat left, right, top, bottom;
+ GLfloat war = (GLfloat)_width/(GLfloat)_height;
+
+ if ( war < new_frame.aspect_ratio ) {
+ left = -1.0;
+ right = 1.0;
+ top = war / new_frame.aspect_ratio;
+ bottom = -war / new_frame.aspect_ratio;
+ }
+ else {
+ top = 1.0;
+ bottom = -1.0;
+ left = -new_frame.aspect_ratio / war;
+ right = new_frame.aspect_ratio / war;
+ }
+
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+ glLoadIdentity();
+
+ glPushMatrix();
+
+ glTranslatef( _width/2, _height/2, 0 );
+ glScalef( _width/2, _height/2, 1.0 );
+
+ glBindTexture( GL_TEXTURE_2D, fb.texture );
+
+ glBegin( GL_QUADS );
+ glTexCoord2f( 0.0f, 0.0f ); glVertex2f( left, top );
+ glTexCoord2f( 0.0f, 1.0f ); glVertex2f( left, bottom );
+ glTexCoord2f( 1.0f, 1.0f ); glVertex2f( right, bottom );
+ glTexCoord2f( 1.0f, 0.0f ); glVertex2f( right, top );
+ glEnd();
+
+ glPopMatrix();
+
+ glXSwapBuffers( GLWin.dpy, GLWin.win );
+
+ if ( !vthread.running ) {
+ pthread_create( &vthread.thread, NULL, video_thread, NULL );
+ vthread.running = 1;
+ }
+}
+
+
+
+static void show_frame()
+{
+ if ( (fb.width != new_frame.width) || (fb.height != new_frame.height) ) {
+ glDeleteFramebuffers( 1, &fb.fbo );
+ glDeleteTextures( 1, &fb.texture );
+ fb.fbo = 0;
+ fb.width = new_frame.width;
+ fb.height = new_frame.height;
+ glGenFramebuffers( 1, &fb.fbo );
+ glGenTextures( 1, &fb.texture );
+ glBindTexture( GL_TEXTURE_2D, fb.texture );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, fb.width, fb.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glBindFramebuffer( GL_FRAMEBUFFER, fb.fbo );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.texture, 0 );
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ }
+
+ glPushAttrib(GL_VIEWPORT_BIT);
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+
+ glBindFramebuffer( GL_FRAMEBUFFER, fb.fbo );
+
+ glViewport( 0, 0, new_frame.width, new_frame.height );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glOrtho( 0.0, new_frame.width, 0.0, new_frame.height, -1.0, 1.0 );
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, new_frame.texture );
+
+ glBegin( GL_QUADS );
+ glTexCoord2f( 0.0f, 0.0f ); glVertex2f( 0.0f, 0.0f );
+ glTexCoord2f( 0.0f, 1.0f ); glVertex2f( 0.0f, new_frame.height );
+ glTexCoord2f( 1.0f, 1.0f ); glVertex2f( new_frame.width, new_frame.height );
+ glTexCoord2f( 1.0f, 0.0f ); glVertex2f( new_frame.width, 0.0f );
+ glEnd();
+
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ mlt_events_fire( MLT_CONSUMER_PROPERTIES(&xgl->parent), "consumer-frame-show", new_frame.mlt_frame_ref, NULL );
+ mlt_frame_close( new_frame.mlt_frame_ref );
+ new_frame.mlt_frame_ref = NULL;
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopAttrib();
+
+ update();
+
+ new_frame.new = 0;
+}
+
+
+
+void* video_thread( void *arg )
+{
+ mlt_frame next = NULL;
+ mlt_consumer consumer = &xgl->parent;
+ mlt_properties consumer_props = MLT_CONSUMER_PROPERTIES( consumer );
+ struct timeval start, end;
+ double duration = 0;
+
+ gettimeofday( &start, NULL );
+
+ while ( vthread.running )
+ {
+ // Get a frame from the attached producer
+ next = mlt_consumer_rt_frame( consumer );
+
+ if ( !mlt_properties_get_int( MLT_FILTER_PROPERTIES( glsl_manager ), "glsl_supported" ) ) {
+ mlt_log_error( MLT_CONSUMER_SERVICE(consumer), "OpenGL Shading Language is not supported on this machine.\n" );
+ xgl->running = 0;
+ break;
+ }
+
+ // Ensure that we have a frame
+ if ( next )
+ {
+ mlt_properties properties = MLT_FRAME_PROPERTIES( next );
+ if ( mlt_properties_get_int( properties, "rendered" ) == 1 )
+ {
+ // Get the image, width and height
+ mlt_image_format vfmt = mlt_image_glsl_texture;
+ int width = 0, height = 0;
+ GLuint *image = 0;
+ int error = mlt_frame_get_image( next, (uint8_t**) &image, &vfmt, &width, &height, 0 );
+ if ( !error && image && width && height && !new_frame.new ) {
+ new_frame.width = width;
+ new_frame.height = height;
+ new_frame.texture = *image;
+ new_frame.mlt_frame_ref = next;
+ new_frame.aspect_ratio = ((double)width / (double)height) * mlt_properties_get_double( properties, "aspect_ratio" );
+ new_frame.new = 1;
+
+ int loop = 200;
+ while ( new_frame.new && --loop )
+ usleep( 500 );
+ }
+ else
+ {
+ mlt_frame_close( next );
+ }
+ new_frame.new = 0;
+
+ gettimeofday( &end, NULL );
+ duration = 1000000.0 / mlt_properties_get_double( consumer_props, "fps" );
+ duration -= ( end.tv_sec * 1000000 + end.tv_usec ) - ( start.tv_sec * 1000000 + start.tv_usec );
+ if ( duration > 0 )
+ usleep( (int)duration );
+ gettimeofday( &start, NULL );
+ }
+ else
+ {
+ mlt_frame_close( next );
+ static int dropped = 0;
+ mlt_log_info( MLT_CONSUMER_SERVICE(consumer), "dropped video frame %d\n", ++dropped );
+ }
+ }
+ else
+ usleep( 1000 );
+ }
+ mlt_consumer_stopped( consumer );
+
+ return NULL;
+}
+
+
+
+static void resizeGLScene()
+{
+ glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx );
+
+ if ( GLWin.height == 0 )
+ GLWin.height = 1;
+ if ( GLWin.width == 0 )
+ GLWin.width = 1;
+ glViewport( 0, 0, GLWin.width, GLWin.height );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glOrtho( 0.0, GLWin.width, 0.0, GLWin.height, -1.0, 1.0 );
+ glMatrixMode( GL_MODELVIEW );
+
+ update();
+}
+
+
+
+static void initGL( void )
+{
+ glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx );
+
+ glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
+ glClearDepth( 1.0f );
+ glDepthFunc( GL_LEQUAL );
+ glEnable( GL_DEPTH_TEST );
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ glEnable( GL_BLEND );
+ glShadeModel( GL_SMOOTH );
+ glEnable( GL_TEXTURE_2D );
+ glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
+
+ typedef int (*GLXSWAPINTERVALSGI) ( int );
+ GLXSWAPINTERVALSGI mglXSwapInterval = (GLXSWAPINTERVALSGI)glXGetProcAddressARB( (const GLubyte*)"glXSwapIntervalSGI" );
+ if ( mglXSwapInterval )
+ mglXSwapInterval( 1 );
+
+ fb.fbo = 0;
+ fb.width = STARTWIDTH;
+ fb.height = STARTHEIGHT;
+ glGenFramebuffers( 1, &fb.fbo );
+ glGenTextures( 1, &fb.texture );
+ glBindTexture( GL_TEXTURE_2D, fb.texture );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, fb.width, fb.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glBindFramebuffer( GL_FRAMEBUFFER, fb.fbo );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.texture, 0 );
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+
+ resizeGLScene();
+}
+
+
+
+static void createGLWindow()
+{
+ const char* title = "OpenGL consumer";
+ int width = STARTWIDTH;
+ int height = STARTHEIGHT;
+
+ int attrListSgl[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8, GLX_DEPTH_SIZE, 16, None };
+
+ int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_DEPTH_SIZE, 16, None };
+
+ XVisualInfo *vi;
+ Colormap cmap;
+ Atom wmDelete;
+ Window winDummy;
+ unsigned int borderDummy;
+
+ GLWin.dpy = XOpenDisplay( 0 );
+ GLWin.screen = DefaultScreen( GLWin.dpy );
+
+ vi = glXChooseVisual( GLWin.dpy, GLWin.screen, attrListDbl );
+ if ( !vi )
+ vi = glXChooseVisual( GLWin.dpy, GLWin.screen, attrListSgl );
+
+ GLWin.ctx = glXCreateContext( GLWin.dpy, vi, 0, GL_TRUE );
+
+ cmap = XCreateColormap( GLWin.dpy, RootWindow( GLWin.dpy, vi->screen ), vi->visual, AllocNone );
+ GLWin.attr.colormap = cmap;
+ GLWin.attr.border_pixel = 0;
+
+ GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
+ GLWin.win = XCreateWindow( GLWin.dpy, RootWindow(GLWin.dpy, vi->screen), 0, 0, width, height,
+ 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr );
+ wmDelete = XInternAtom( GLWin.dpy, "WM_DELETE_WINDOW", True );
+ XSetWMProtocols( GLWin.dpy, GLWin.win, &wmDelete, 1 );
+ XSetStandardProperties( GLWin.dpy, GLWin.win, title, title, None, NULL, 0, NULL );
+ XMapRaised( GLWin.dpy, GLWin.win );
+
+ glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx );
+ XGetGeometry( GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
+ &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth );
+
+ // Verify GLSL works on this machine
+ hiddenctx.ctx = glXCreateContext( GLWin.dpy, vi, GLWin.ctx, GL_TRUE );
+ if ( hiddenctx.ctx ) {
+ hiddenctx.dpy = GLWin.dpy;
+ hiddenctx.screen = GLWin.screen;
+ hiddenctx.win = RootWindow( hiddenctx.dpy, hiddenctx.screen );
+ }
+
+ initGL();
+}
+
+
+
+static void killGLWindow()
+{
+ if ( GLWin.ctx ) {
+ if ( !glXMakeCurrent( GLWin.dpy, None, NULL ) ) {
+ printf("Error releasing drawing context : killGLWindow\n");
+ }
+ glXDestroyContext( GLWin.dpy, GLWin.ctx );
+ GLWin.ctx = NULL;
+ }
+
+ if ( hiddenctx.ctx )
+ glXDestroyContext( hiddenctx.dpy, hiddenctx.ctx );
+
+ XCloseDisplay( GLWin.dpy );
+}
+
+
+
+static void run()
+{
+ XEvent event;
+
+ while ( xgl->running ) {
+ while ( XPending( GLWin.dpy ) > 0 ) {
+ XNextEvent( GLWin.dpy, &event );
+ switch ( event.type ) {
+ case Expose:
+ if ( event.xexpose.count != 0 )
+ break;
+ break;
+ case ConfigureNotify:
+ if ( (event.xconfigure.width != GLWin.width) || (event.xconfigure.height != GLWin.height) ) {
+ GLWin.width = event.xconfigure.width;
+ GLWin.height = event.xconfigure.height;
+ resizeGLScene();
+ }
+ break;
+ case KeyPress:
+ switch ( XLookupKeysym( &event.xkey, 0 ) ) {
+ case XK_Escape:
+ xgl->running = 0;
+ break;
+ default: {
+ mlt_producer producer = mlt_properties_get_data( xgl->properties, "transport_producer", NULL );
+ char keyboard[ 2 ] = " ";
+ void (*callback)( mlt_producer, char * ) = mlt_properties_get_data( xgl->properties, "transport_callback", NULL );
+ if ( callback != NULL && producer != NULL )
+ {
+ keyboard[ 0 ] = ( char )XLookupKeysym( &event.xkey, 0 );
+ callback( producer, keyboard );
+ }
+ break;
+ }
+ }
+ break;
+ case ClientMessage:
+ if ( *XGetAtomName( GLWin.dpy, event.xclient.message_type ) == *"WM_PROTOCOLS" )
+ xgl->running = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ( new_frame.new )
+ show_frame();
+ else
+ usleep( 1000 );
+ }
+}
+
+
+
+void start_xgl( consumer_xgl consumer )
+{
+ xgl = consumer;
+
+ pthread_mutex_init( &new_frame.mutex, NULL );
+ new_frame.aspect_ratio = 16.0 / 9.0;
+ new_frame.new = 0;
+ new_frame.width = STARTWIDTH;
+ new_frame.height = STARTHEIGHT;
+ new_frame.mlt_frame_ref = NULL;
+
+ vthread.running = 0;
+ xgl->xgl_started = 1;
+
+ createGLWindow();
+ run();
+ if ( vthread.running ) {
+ vthread.running = 0;
+ pthread_join( vthread.thread, NULL );
+ }
+ xgl->running = 0;
+}
+
+static void on_consumer_thread_started( mlt_properties owner, HiddenContext* context )
+{
+ // Initialize this thread's OpenGL state
+ glXMakeCurrent( context->dpy, context->win, context->ctx );
+ mlt_events_fire( MLT_FILTER_PROPERTIES(glsl_manager), "init glsl", NULL );
+}
+
+/** 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 * );
+
+
+
+/** This is what will be called by the factory - anything can be passed in
+ via the argument, but keep it simple.
+*/
+
+mlt_consumer consumer_xgl_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ // Create the consumer object
+ consumer_xgl this = calloc( sizeof( struct consumer_xgl_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 );
+
+ // Default scaler
+ mlt_properties_set( this->properties, "rescale", "bilinear" );
+ mlt_properties_set( this->properties, "deinterlace_method", "onefield" );
+
+ // default image format
+ mlt_properties_set( this->properties, "mlt_image_format", "glsl" );
+
+ // Default buffer for low latency
+ mlt_properties_set_int( this->properties, "buffer", 1 );
+
+ // Ensure we don't join on a non-running object
+ this->joined = 1;
+ this->xgl_started = 0;
+
+ // Allow thread to be started/stopped
+ parent->start = consumer_start;
+ parent->stop = consumer_stop;
+ parent->is_stopped = consumer_is_stopped;
+
+ // "init glsl" is required to instantiate glsl filters.
+ glsl_manager = mlt_factory_filter( profile, "glsl.manager", NULL );
+ if ( glsl_manager ) {
+ mlt_events_listen( this->properties, &hiddenctx, "consumer-thread-started", (mlt_listener) on_consumer_thread_started );
+ } else {
+ mlt_consumer_close( parent );
+ parent = NULL;
+ }
+
+ // Return the consumer produced
+ return parent;
+ }
+
+ // malloc or consumer init failed
+ free( this );
+
+ // Indicate failure
+ return NULL;
+}
+
+
+
+int consumer_start( mlt_consumer parent )
+{
+ consumer_xgl this = parent->child;
+
+ if ( !this->running )
+ {
+ consumer_stop( parent );
+
+ this->running = 1;
+ this->joined = 0;
+
+ pthread_create( &this->thread, NULL, consumer_thread, this );
+ }
+
+ return 0;
+}
+
+
+
+int consumer_stop( mlt_consumer parent )
+{
+ // Get the actual object
+ consumer_xgl this = parent->child;
+
+ if ( this->running && this->joined == 0 )
+ {
+ // Kill the thread and clean up
+ this->joined = 1;
+ this->running = 0;
+
+ if ( this->thread )
+ pthread_join( this->thread, NULL );
+ }
+
+ return 0;
+}
+
+
+
+int consumer_is_stopped( mlt_consumer parent )
+{
+ consumer_xgl this = parent->child;
+ return !this->running;
+}
+
+
+
+static void *consumer_thread( void *arg )
+{
+ // Identify the arg
+ consumer_xgl this = arg;
+
+ XInitThreads();
+ start_xgl( this );
+
+ return NULL;
+}
+
+
+
+/** Callback to allow override of the close method.
+*/
+
+static void consumer_close( mlt_consumer parent )
+{
+ // Get the actual object
+ consumer_xgl this = parent->child;
+
+ // Stop the consumer
+ ///mlt_consumer_stop( parent );
+ mlt_filter_close( glsl_manager );
+
+ // Now clean up the rest
+ mlt_consumer_close( parent );
+
+ // Close the queue
+ mlt_deque_close( this->queue );
+
+ if ( this->xgl_started )
+ killGLWindow();
+
+ // Finally clean up this
+ free( this );
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ * factory.c -- the factory method interfaces
+ *
+ * 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 <string.h>
+#include <limits.h>
+#include <framework/mlt.h>
+
+
+
+extern mlt_consumer consumer_xgl_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_glsl_manager_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_blur_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_convert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_crop_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_deconvolution_sharpen_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_diffusion_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_glow_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_lift_gamma_gain_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_mirror_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_opacity_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_rect_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_resample_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_resize_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_saturation_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_movit_vignette_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_white_balance_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_transition transition_movit_mix_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_transition transition_movit_overlay_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+
+static mlt_properties metadata( mlt_service_type type, const char *id, void *data )
+{
+ char file[ PATH_MAX ];
+ snprintf( file, PATH_MAX, "%s/opengl/%s", mlt_environment( "MLT_DATA" ), (char*) data );
+ return mlt_properties_parse_yaml( file );
+}
+
+MLT_REPOSITORY
+{
+#if !defined(__DARWIN__) && !defined(WIN32)
+ MLT_REGISTER( consumer_type, "xgl", consumer_xgl_init );
+#endif
+ MLT_REGISTER( filter_type, "glsl.manager", filter_glsl_manager_init );
+ MLT_REGISTER( filter_type, "movit.blur", filter_movit_blur_init );
+ MLT_REGISTER( filter_type, "movit.convert", filter_movit_convert_init );
+ MLT_REGISTER( filter_type, "movit.crop", filter_movit_crop_init );
+ MLT_REGISTER( filter_type, "movit.diffusion", filter_movit_diffusion_init );
+ MLT_REGISTER( filter_type, "movit.glow", filter_movit_glow_init );
+ MLT_REGISTER( filter_type, "movit.lift_gamma_gain", filter_lift_gamma_gain_init );
+ MLT_REGISTER( filter_type, "movit.mirror", filter_movit_mirror_init );
+ MLT_REGISTER( filter_type, "movit.opacity", filter_movit_opacity_init );
+ MLT_REGISTER( filter_type, "movit.rect", filter_movit_rect_init );
+ MLT_REGISTER( filter_type, "movit.resample", filter_movit_resample_init );
+ MLT_REGISTER( filter_type, "movit.resize", filter_movit_resize_init );
+ MLT_REGISTER( filter_type, "movit.saturation", filter_movit_saturation_init );
+ MLT_REGISTER( filter_type, "movit.sharpen", filter_deconvolution_sharpen_init );
+ MLT_REGISTER( filter_type, "movit.vignette", filter_movit_vignette_init );
+ MLT_REGISTER( filter_type, "movit.white_balance", filter_white_balance_init );
+ MLT_REGISTER( transition_type, "movit.mix", transition_movit_mix_init );
+ MLT_REGISTER( transition_type, "movit.overlay", transition_movit_overlay_init );
+
+ MLT_REGISTER_METADATA( filter_type, "movit.blur", metadata, "filter_movit_blur.yml" );
+ MLT_REGISTER_METADATA( filter_type, "movit.diffusion", metadata, "filter_movit_diffusion.yml" );
+ MLT_REGISTER_METADATA( filter_type, "movit.glow", metadata, "filter_movit_glow.yml" );
+ MLT_REGISTER_METADATA( filter_type, "movit.lift_gamma_gain", metadata, "filter_lift_gamma_gain.yml" );
+ MLT_REGISTER_METADATA( filter_type, "movit.mirror", metadata, "filter_movit_mirror.yml" );
+ MLT_REGISTER_METADATA( filter_type, "movit.opacity", metadata, "filter_movit_opacity.yml" );
+ MLT_REGISTER_METADATA( filter_type, "movit.rect", metadata, "filter_movit_rect.yml" );
+ MLT_REGISTER_METADATA( filter_type, "movit.saturation", metadata, "filter_movit_saturation.yml" );
+ MLT_REGISTER_METADATA( filter_type, "movit.sharpen", metadata, "filter_deconvolution_sharpen.yml" );
+ MLT_REGISTER_METADATA( filter_type, "movit.vignette", metadata, "filter_movit_vignette.yml" );
+ MLT_REGISTER_METADATA( filter_type, "movit.white_balance", metadata, "filter_white_balance.yml" );
+ MLT_REGISTER_METADATA( transition_type, "movit.mix", metadata, "transition_movit_mix.yml" );
+ MLT_REGISTER_METADATA( transition_type, "movit.overlay", metadata, "transition_movit_overlay.yml" );
+}
--- /dev/null
+/*
+ * fbo_input.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 "fbo_input.h"
+#include <movit/util.h>
+
+// comes from unexported effect_util.h
+extern void set_uniform_int(GLuint glsl_program_num, const std::string &prefix, const std::string &key, int value);
+
+FBOInput::FBOInput(unsigned width, unsigned height)
+ : texture_num(0)
+ , needs_mipmaps(false)
+ , width(width)
+ , height(height)
+{
+ register_int("needs_mipmaps", &needs_mipmaps);
+}
+
+void FBOInput::set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num)
+{
+ glActiveTexture(GL_TEXTURE0 + *sampler_num);
+ check_error();
+ glBindTexture(GL_TEXTURE_2D, texture_num);
+ check_error();
+
+ // Bind it to a sampler.
+ set_uniform_int(glsl_program_num, prefix, "tex", *sampler_num);
+ ++*sampler_num;
+}
+
+std::string FBOInput::output_fragment_shader()
+{
+ return read_file("flat_input.frag");
+// return "uniform sampler2D PREFIX(tex); vec4 FUNCNAME(vec2 tc) { return texture2D(PREFIX(tex), tc); }\n";
+}
--- /dev/null
+/*
+ * fbo_input.h
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 FBO_INPUT_H
+#define FBO_INPUT_H
+
+#include <movit/input.h>
+
+class FBOInput : public Input
+{
+public:
+ FBOInput(unsigned width, unsigned height);
+
+ virtual std::string effect_type_id() const { return "FBOInput"; }
+ void finalize() {}
+ bool can_output_linear_gamma() const { return false; }
+ AlphaHandling alpha_handling() const { return OUTPUT_POSTMULTIPLIED_ALPHA; }
+ std::string output_fragment_shader();
+ void set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num);
+ unsigned get_width() const { return width; }
+ unsigned get_height() const { return height; }
+ Colorspace get_color_space() const { return COLORSPACE_sRGB; }
+ GammaCurve get_gamma_curve() const { return GAMMA_sRGB; }
+ void set_texture(GLuint texture) {
+ texture_num = texture;
+ }
+
+private:
+ GLuint texture_num;
+ int needs_mipmaps;
+ unsigned width, height;
+};
+
+#endif // FBO_INPUT_H
--- /dev/null
+/*
+ * filter_deconvolution_sharpen.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/deconvolution_sharpen_effect.h>
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !mlt_frame_is_test_card( frame ) ) {
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( !effect )
+ GlslManager::add_effect( filter, frame, new DeconvolutionSharpenEffect() );
+ if ( effect ) {
+ mlt_properties filter_props = MLT_FILTER_PROPERTIES( filter );
+ bool ok = effect->set_int( "matrix_size", mlt_properties_get_int( filter_props, "matrix_size" ) );
+ ok |= effect->set_float( "circle_radius", mlt_properties_get_double( filter_props, "circle_radius" ) );
+ ok |= effect->set_float( "gaussian_radius", mlt_properties_get_double( filter_props, "gaussian_radius" ) );
+ ok |= effect->set_float( "correlation", mlt_properties_get_double( filter_props, "correlation" ) );
+ ok |= effect->set_float( "noise", mlt_properties_get_double( filter_props, "noise" ) );
+ assert(ok);
+ }
+ }
+ return frame;
+}
+
+extern "C" {
+
+mlt_filter filter_deconvolution_sharpen_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_properties_set_int( properties, "matrix_size", 5 );
+ mlt_properties_set_double( properties, "circle_radius", 2.0 );
+ mlt_properties_set_double( properties, "gaussian_radius", 0.0 );
+ mlt_properties_set_double( properties, "correlation", 0.95 );
+ mlt_properties_set_double( properties, "noise", 0.01 );
+ filter->process = process;
+ }
+ return filter;
+}
+
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.sharpen
+title: Deconvolution Sharpen (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: >
+ Deconvolution Sharpen is a filter that sharpens by way of deconvolution
+ (i.e., trying to reverse the blur kernel, as opposed to just boosting high
+ frequencies), more specifically by FIR Wiener filters. It is the same
+ algorithm as used by the (now largely abandoned) Refocus plug-in for GIMP,
+ and I suspect the same as in Photoshop's “Smart Sharpen” filter.
+ The effect gives generally better results than unsharp masking, but can be very
+ GPU intensive, and requires a fair bit of tweaking to get good results without
+ ringing and/or excessive noise.
+
+parameters:
+ - identifier: matrix_size
+ title: Matrix Size
+ type: integer
+ minimum: 0
+ maximum: 10
+ default: 5
+
+ - identifier: circle_radius
+ title: Circle Radius
+ type: float
+ minimum: 0
+ default: 2
+
+ - identifier: gaussian_radius
+ title: Gaussian Radius
+ type: float
+ minimum: 0
+ default: 0
+
+ - identifier: correlation
+ title: Correlation
+ type: float
+ minimum: 0
+ default: 0.95
+
+ - identifier: noise
+ title: Noise Level
+ type: float
+ minimum: 0
+ default: 0.01
+
--- /dev/null
+/*
+ * filter_glsl_manager.cpp
+ * Copyright (C) 2011-2012 Christophe Thommeret <hftom@free.fr>
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <stdlib.h>
+#include <string>
+#include "glsl_manager.h"
+#include <movit/init.h>
+#include <movit/effect_chain.h>
+#include "mlt_movit_input.h"
+#include "mlt_flip_effect.h"
+#include <mlt++/MltEvent.h>
+#include <mlt++/MltProducer.h>
+
+extern "C" {
+#include <framework/mlt_factory.h>
+}
+
+void deleteManager(GlslManager *p)
+{
+ delete p;
+}
+
+GlslManager::GlslManager()
+ : Mlt::Filter( mlt_filter_new() )
+ , pbo(0)
+{
+ mlt_filter filter = get_filter();
+ if ( filter ) {
+ // Set the mlt_filter child in case we choose to override virtual functions.
+ filter->child = this;
+ mlt_properties_set_data(mlt_global_properties(), "glslManager", this, 0,
+ (mlt_destructor) deleteManager, NULL);
+
+ mlt_events_register( get_properties(), "init glsl", NULL );
+ listen("init glsl", this, (mlt_listener) GlslManager::onInit);
+ }
+}
+
+GlslManager::~GlslManager()
+{
+ mlt_log_debug(get_service(), "%s\n", __FUNCTION__);
+ while (fbo_list.peek_back())
+ delete (glsl_fbo) fbo_list.pop_back();
+ while (texture_list.peek_back())
+ delete (glsl_texture) texture_list.pop_back();
+ delete pbo;
+}
+
+GlslManager* GlslManager::get_instance()
+{
+ return (GlslManager*) mlt_properties_get_data(mlt_global_properties(), "glslManager", 0);
+}
+
+glsl_fbo GlslManager::get_fbo(int width, int height)
+{
+ for (int i = 0; i < fbo_list.count(); ++i) {
+ glsl_fbo fbo = (glsl_fbo) fbo_list.peek(i);
+ if (!fbo->used && (fbo->width == width) && (fbo->height == height)) {
+ fbo->used = 1;
+ return fbo;
+ }
+ }
+ GLuint fb = 0;
+ glGenFramebuffers(1, &fb);
+ if (!fb)
+ return NULL;
+
+ glsl_fbo fbo = new glsl_fbo_s;
+ if (!fbo) {
+ glDeleteFramebuffers(1, &fb);
+ return NULL;
+ }
+ fbo->fbo = fb;
+ fbo->width = width;
+ fbo->height = height;
+ fbo->used = 1;
+ fbo_list.push_back(fbo);
+ return fbo;
+}
+
+void GlslManager::release_fbo(glsl_fbo fbo)
+{
+ fbo->used = 0;
+}
+
+glsl_texture GlslManager::get_texture(int width, int height, GLint internal_format)
+{
+ for (int i = 0; i < texture_list.count(); ++i) {
+ glsl_texture tex = (glsl_texture) texture_list.peek(i);
+ if (!tex->used && (tex->width == width) && (tex->height == height) && (tex->internal_format == internal_format)) {
+ glBindTexture(GL_TEXTURE_2D, tex->texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glBindTexture( GL_TEXTURE_2D, 0);
+ tex->used = 1;
+ return tex;
+ }
+ }
+ GLuint tex = 0;
+ glGenTextures(1, &tex);
+ if (!tex)
+ return NULL;
+
+ glsl_texture gtex = new glsl_texture_s;
+ if (!gtex) {
+ glDeleteTextures(1, &tex);
+ return NULL;
+ }
+ glBindTexture( GL_TEXTURE_2D, tex );
+ glTexImage2D( GL_TEXTURE_2D, 0, internal_format, width, height, 0, internal_format, GL_UNSIGNED_BYTE, NULL );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+
+ gtex->texture = tex;
+ gtex->width = width;
+ gtex->height = height;
+ gtex->internal_format = internal_format;
+ gtex->used = 1;
+ texture_list.push_back(gtex);
+ return gtex;
+}
+
+void GlslManager::release_texture(glsl_texture texture)
+{
+ texture->used = 0;
+}
+
+glsl_pbo GlslManager::get_pbo(int size)
+{
+ if (!pbo) {
+ GLuint pb = 0;
+ glGenBuffers(1, &pb);
+ if (!pb)
+ return NULL;
+
+ pbo = new glsl_pbo_s;
+ if (!pbo) {
+ glDeleteBuffers(1, &pb);
+ return NULL;
+ }
+ pbo->pbo = pb;
+ }
+ if (size > pbo->size) {
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo->pbo);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, size, NULL, GL_STREAM_DRAW);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ pbo->size = size;
+ }
+ return pbo;
+}
+
+void GlslManager::onInit( mlt_properties owner, GlslManager* filter )
+{
+ mlt_log_debug( filter->get_service(), "%s\n", __FUNCTION__ );
+#ifdef WIN32
+ std::string path = std::string(mlt_environment("MLT_APPDIR")).append("\\share\\movit");
+#elif defined(__DARWIN__) && defined(RELOCATABLE)
+ std::string path = std::string(mlt_environment("MLT_APPDIR")).append("/share/movit");
+#else
+ std::string path = std::string(getenv("MLT_MOVIT_PATH") ? getenv("MLT_MOVIT_PATH") : SHADERDIR);
+#endif
+ ::init_movit( path, mlt_log_get_level() == MLT_LOG_DEBUG? MOVIT_DEBUG_ON : MOVIT_DEBUG_OFF );
+ filter->set( "glsl_supported", movit_initialized );
+}
+
+void GlslManager::onServiceChanged( mlt_properties owner, mlt_service aservice )
+{
+ Mlt::Service service( aservice );
+ service.lock();
+ service.set( "movit chain", NULL, 0 );
+ service.set( "movit input", NULL, 0 );
+ // Destroy the effect list.
+ GlslManager::get_instance()->set( service.get( "_unique_id" ), NULL, 0 );
+ service.unlock();
+}
+
+void GlslManager::onPropertyChanged( mlt_properties owner, mlt_service service, const char* property )
+{
+ if ( property && std::string( property ) == "disable" )
+ onServiceChanged( owner, service );
+}
+
+extern "C" {
+
+mlt_filter filter_glsl_manager_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ GlslManager* g = GlslManager::get_instance();
+ if (g)
+ g->inc_ref();
+ else
+ g = new GlslManager();
+ return g->get_filter();
+}
+
+} // extern "C"
+
+Mlt::Properties GlslManager::effect_list( Mlt::Service& service )
+{
+ char *unique_id = service.get( "_unique_id" );
+ mlt_properties properties = (mlt_properties) get_data( unique_id );
+ if ( !properties ) {
+ properties = mlt_properties_new();
+ set( unique_id, properties, 0, (mlt_destructor) mlt_properties_close );
+ }
+ Mlt::Properties p( properties );
+ return p;
+}
+
+static void deleteChain( EffectChain* chain )
+{
+ delete chain;
+}
+
+bool GlslManager::init_chain( mlt_service aservice )
+{
+ bool error = true;
+ Mlt::Service service( aservice );
+ EffectChain* chain = (EffectChain*) service.get_data( "movit chain" );
+ if ( !chain ) {
+ mlt_profile profile = mlt_service_profile( aservice );
+ Input* input = new MltInput( profile->width, profile->height );
+ chain = new EffectChain( profile->display_aspect_num, profile->display_aspect_den );
+ chain->add_input( input );
+ service.set( "movit chain", chain, 0, (mlt_destructor) deleteChain );
+ service.set( "movit input", input, 0 );
+ service.set( "_movit finalized", 0 );
+ service.listen( "service-changed", aservice, (mlt_listener) GlslManager::onServiceChanged );
+ service.listen( "property-changed", aservice, (mlt_listener) GlslManager::onPropertyChanged );
+ error = false;
+ }
+ return error;
+}
+
+EffectChain* GlslManager::get_chain( mlt_service service )
+{
+ return (EffectChain*) mlt_properties_get_data( MLT_SERVICE_PROPERTIES(service), "movit chain", NULL );
+}
+
+MltInput *GlslManager::get_input( mlt_service service )
+{
+ return (MltInput*) mlt_properties_get_data( MLT_SERVICE_PROPERTIES(service), "movit input", NULL );
+}
+
+void GlslManager::reset_finalized( mlt_service service )
+{
+ mlt_properties_set_int( MLT_SERVICE_PROPERTIES(service), "_movit finalized", 0 );
+}
+
+Effect* GlslManager::get_effect( mlt_filter filter, mlt_frame frame )
+{
+ Mlt::Producer producer( mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) ) );
+ char *unique_id = mlt_properties_get( MLT_FILTER_PROPERTIES(filter), "_unique_id" );
+ return (Effect*) GlslManager::get_instance()->effect_list( producer ).get_data( unique_id );
+}
+
+Effect* GlslManager::add_effect( mlt_filter filter, mlt_frame frame, Effect* effect )
+{
+ Mlt::Producer producer( mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) ) );
+ EffectChain* chain = (EffectChain*) producer.get_data( "movit chain" );
+ chain->add_effect( effect );
+ char *unique_id = mlt_properties_get( MLT_FILTER_PROPERTIES(filter), "_unique_id" );
+ GlslManager::get_instance()->effect_list( producer ).set( unique_id, effect, 0 );
+ return effect;
+}
+
+Effect* GlslManager::add_effect( mlt_filter filter, mlt_frame frame, Effect* effect, Effect* input_b )
+{
+ Mlt::Producer producer( mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) ) );
+ EffectChain* chain = (EffectChain*) producer.get_data( "movit chain" );
+ chain->add_effect( effect, chain->last_added_effect(),
+ input_b? input_b : chain->last_added_effect() );
+ char *unique_id = mlt_properties_get( MLT_FILTER_PROPERTIES(filter), "_unique_id" );
+ GlslManager::get_instance()->effect_list( producer ).set( unique_id, effect, 0 );
+ return effect;
+}
+
+void GlslManager::render( mlt_service service, void* chain, GLuint fbo, int width, int height )
+{
+ EffectChain* effect_chain = (EffectChain*) chain;
+ mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
+ if ( !mlt_properties_get_int( properties, "_movit finalized" ) ) {
+ mlt_properties_set_int( properties, "_movit finalized", 1 );
+ effect_chain->add_effect( new Mlt::VerticalFlip() );
+ effect_chain->finalize();
+ }
+ effect_chain->render_to_fbo( fbo, width, height );
+}
+
+void GlslManager::lock_service( mlt_frame frame )
+{
+ Mlt::Producer producer( mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) ) );
+ producer.lock();
+}
+
+void GlslManager::unlock_service( mlt_frame frame )
+{
+ Mlt::Producer producer( mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) ) );
+ producer.unlock();
+}
--- /dev/null
+/*
+ * filter_lift_gamma_gain.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/lift_gamma_gain_effect.h>
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !mlt_frame_is_test_card( frame ) ) {
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( !effect )
+ effect = GlslManager::add_effect( filter, frame, new LiftGammaGainEffect );
+ if ( effect ) {
+ mlt_properties filter_props = MLT_FILTER_PROPERTIES( filter );
+ RGBTriplet triplet(
+ mlt_properties_get_double( filter_props, "lift_r" ),
+ mlt_properties_get_double( filter_props, "lift_g" ),
+ mlt_properties_get_double( filter_props, "lift_b" )
+ );
+ bool ok = effect->set_vec3( "lift", (float*) &triplet );
+ triplet.r = mlt_properties_get_double( filter_props, "gamma_r" );
+ triplet.g = mlt_properties_get_double( filter_props, "gamma_g" );
+ triplet.b = mlt_properties_get_double( filter_props, "gamma_b" );
+ ok |= effect->set_vec3( "gamma", (float*) &triplet );
+ triplet.r = mlt_properties_get_double( filter_props, "gain_r" );
+ triplet.g = mlt_properties_get_double( filter_props, "gain_g" );
+ triplet.b = mlt_properties_get_double( filter_props, "gain_b" );
+ ok |= effect->set_vec3( "gain", (float*) &triplet );
+ assert(ok);
+ }
+ }
+ return frame;
+}
+
+extern "C" {
+
+mlt_filter filter_lift_gamma_gain_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_properties_set_double( properties, "lift_r", 0.0 );
+ mlt_properties_set_double( properties, "lift_g", 0.0 );
+ mlt_properties_set_double( properties, "lift_b", 0.0 );
+ mlt_properties_set_double( properties, "gamma_r", 1.0 );
+ mlt_properties_set_double( properties, "gamma_g", 1.0 );
+ mlt_properties_set_double( properties, "gamma_b", 1.0 );
+ mlt_properties_set_double( properties, "gain_r", 1.0 );
+ mlt_properties_set_double( properties, "gain_g", 1.0 );
+ mlt_properties_set_double( properties, "gain_b", 1.0 );
+ filter->process = process;
+ }
+ return filter;
+}
+
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.lift_gamma_gain
+title: Lift, Gamma, and Gain (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: >
+ A simple lift/gamma/gain effect, used for color grading.
+notes: >
+ Very roughly speaking, lift=shadows, gamma=midtones and gain=highlights,
+ although all parameters affect the entire curve. Mathematically speaking,
+ it is a bit unusual to look at gamma as a color, but it works pretty well
+ in practice.
+ The classic formula is: output = (gain * (x + lift * (1-x)))^(1/gamma).
+ The lift is actually a case where we actually would _not_ want linear light;
+ since black by definition becomes equal to the lift color, we want lift to
+ be pretty close to black, but in linear light that means lift affects the
+ rest of the curve relatively little. Thus, we actually convert to gamma 2.2
+ before lift, and then back again afterwards. (Gain and gamma are,
+ up to constants, commutative with the de-gamma operation.)
+
+parameters:
+ - identifier: lift_r
+ title: Lift Red
+ type: float
+ minimum: 0.0
+ default: 0.0
+
+ - identifier: lift_g
+ title: Lift Green
+ type: float
+ minimum: 0.0
+ default: 0.0
+
+ - identifier: lift_b
+ title: Lift Blue
+ type: float
+ minimum: 0.0
+ default: 0.0
+
+ - identifier: gamma_r
+ title: Gamma Red
+ type: float
+ minimum: 0.0
+ default: 1.0
+
+ - identifier: gamma_g
+ title: Gamma Green
+ type: float
+ minimum: 0.0
+ default: 1.0
+
+ - identifier: gamma_b
+ title: Gamma Blue
+ type: float
+ minimum: 0.0
+ default: 1.0
+
+ - identifier: gain_r
+ title: Gain Red
+ type: float
+ minimum: 0.0
+ default: 1.0
+
+ - identifier: gain_g
+ title: Gain Green
+ type: float
+ minimum: 0.0
+ default: 1.0
+
+ - identifier: gain_b
+ title: Gain Blue
+ type: float
+ minimum: 0.0
+ default: 1.0
--- /dev/null
+/*
+ * filter_movit_blur.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/blur_effect.h>
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !mlt_frame_is_test_card( frame ) ) {
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( !effect )
+ effect = GlslManager::add_effect( filter, frame, new BlurEffect() );
+ if ( effect ) {
+ mlt_properties filter_props = MLT_FILTER_PROPERTIES( filter );
+ bool ok = effect->set_float( "radius", mlt_properties_get_double( filter_props, "radius" ) );
+ assert(ok);
+ }
+ }
+ return frame;
+}
+
+extern "C" {
+
+mlt_filter filter_movit_blur_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_properties_set_double( properties, "radius", 3 );
+ filter->process = process;
+ }
+ return filter;
+}
+
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.blur
+title: Blur (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: >
+ A separable 2D blur implemented by a combination of mipmap filtering
+ and convolution (essentially giving a convolution with a piecewise linear
+ approximation to the true impulse response).
+
+parameters:
+ - identifier: radius
+ title: Radius
+ type: float
+ minimum: 0
+ default: 3
--- /dev/null
+/*
+ * filter_movit_convert.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/effect_chain.h>
+#include <movit/util.h>
+#include "mlt_movit_input.h"
+#include <mlt++/MltProducer.h>
+#include "mlt_flip_effect.h"
+
+static void yuv422_to_yuv422p( uint8_t *yuv422, uint8_t *yuv422p, int width, int height )
+{
+ uint8_t *Y = yuv422p;
+ uint8_t *U = Y + width * height;
+ uint8_t *V = U + width * height / 2;
+ int n = width * height / 2 + 1;
+ while ( --n ) {
+ *Y++ = *yuv422++;
+ *U++ = *yuv422++;
+ *Y++ = *yuv422++;
+ *V++ = *yuv422++;
+ }
+}
+
+static int convert_on_cpu( mlt_frame frame, uint8_t **image, mlt_image_format *format, mlt_image_format output_format )
+{
+ int error = 0;
+ mlt_filter cpu_csc = (mlt_filter) mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "cpu_csc", NULL );
+ if ( cpu_csc ) {
+ int (* save_fp )( mlt_frame self, uint8_t **image, mlt_image_format *input, mlt_image_format output )
+ = frame->convert_image;
+ frame->convert_image = NULL;
+ mlt_filter_process( cpu_csc, frame );
+ error = frame->convert_image( frame, image, format, output_format );
+ frame->convert_image = save_fp;
+ } else {
+ error = 1;
+ }
+ return error;
+}
+
+static void delete_chain( EffectChain* chain )
+{
+ delete chain;
+}
+
+static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, mlt_image_format output_format )
+{
+ // Nothing to do!
+ if ( *format == output_format )
+ return 0;
+
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+
+ mlt_log_debug( NULL, "filter_movit_convert: %s -> %s\n",
+ mlt_image_format_name( *format ), mlt_image_format_name( output_format ) );
+
+ // Use CPU if glsl not initialized or not supported.
+ GlslManager* glsl = GlslManager::get_instance();
+ if ( !glsl || !glsl->get_int("glsl_supported" ) )
+ return convert_on_cpu( frame, image, format, output_format );
+
+ // Do non-GL image conversions on a CPU-based image converter.
+ if ( *format != mlt_image_glsl && output_format != mlt_image_glsl && output_format != mlt_image_glsl_texture )
+ return convert_on_cpu( frame, image, format, output_format );
+
+ int error = 0;
+ int width = mlt_properties_get_int( properties, "width" );
+ int height = mlt_properties_get_int( properties, "height" );
+ int img_size = mlt_image_format_size( *format, width, height, NULL );
+ mlt_producer producer = mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) );
+ mlt_service service = MLT_PRODUCER_SERVICE(producer);
+ GlslManager::get_instance()->lock_service( frame );
+ EffectChain* chain = GlslManager::get_chain( service );
+ MltInput* input = GlslManager::get_input( service );
+
+ if ( !chain || !input ) {
+ GlslManager::get_instance()->unlock_service( frame );
+ return 2;
+ }
+
+ if ( *format != mlt_image_glsl ) {
+ bool finalize_chain = false;
+ if ( output_format == mlt_image_glsl_texture ) {
+ // We might already have a texture from a previous conversion from mlt_image_glsl.
+ glsl_texture texture = (glsl_texture) mlt_properties_get_data( properties, "movit.convert.texture", NULL );
+ // XXX: requires a special property set on the frame by the app for now
+ // because we do not have reliable way to clear the texture property
+ // when a downstream filter has changed image.
+ if ( texture && mlt_properties_get_int( properties, "movit.convert.use_texture") ) {
+ *image = (uint8_t*) &texture->texture;
+ mlt_frame_set_image( frame, *image, 0, NULL );
+ mlt_properties_set_int( properties, "format", output_format );
+ *format = output_format;
+ GlslManager::get_instance()->unlock_service( frame );
+ return error;
+ } else {
+ // Use a separate chain to convert image in RAM to OpenGL texture.
+ // Use cached chain if available and compatible.
+ Mlt::Producer producer( mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) ) );
+ chain = (EffectChain*) producer.get_data( "movit.convert.chain" );
+ input = (MltInput*) producer.get_data( "movit.convert.input" );
+ int w = producer.get_int( "movit.convert.width" );
+ int h = producer.get_int( "movit.convert.height" );
+ mlt_image_format f = (mlt_image_format) producer.get_int( "movit.convert.format" );
+ if ( !chain || width != w || height != h || output_format != f ) {
+ chain = new EffectChain( width, height );
+ input = new MltInput( width, height );
+ chain->add_input( input );
+ chain->add_effect( new Mlt::VerticalFlip() );
+ finalize_chain = true;
+ producer.set( "movit.convert.chain", chain, 0, (mlt_destructor) delete_chain );
+ producer.set( "movit.convert.width", width );
+ producer.set( "movit.convert.height", height );
+ producer.set( "movit.convert.width", output_format );
+ }
+ }
+ }
+ if ( *format == mlt_image_rgb24a || *format == mlt_image_opengl ) {
+ input->useFlatInput( chain, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, width, height );
+ input->set_pixel_data( *image );
+ }
+ else if ( *format == mlt_image_rgb24 ) {
+ input->useFlatInput( chain, FORMAT_RGB, width, height );
+ input->set_pixel_data( *image );
+ }
+ else if ( *format == mlt_image_yuv420p ) {
+ ImageFormat image_format;
+ YCbCrFormat ycbcr_format;
+ if ( 709 == mlt_properties_get_int( properties, "colorspace" ) ) {
+ image_format.color_space = COLORSPACE_REC_709;
+ image_format.gamma_curve = GAMMA_REC_709;
+ ycbcr_format.luma_coefficients = YCBCR_REC_709;
+ } else if ( 576 == mlt_properties_get_int( properties, "height" ) ) {
+ image_format.color_space = COLORSPACE_REC_601_625;
+ image_format.gamma_curve = GAMMA_REC_601;
+ ycbcr_format.luma_coefficients = YCBCR_REC_601;
+ } else {
+ image_format.color_space = COLORSPACE_REC_601_525;
+ image_format.gamma_curve = GAMMA_REC_601;
+ ycbcr_format.luma_coefficients = YCBCR_REC_601;
+ }
+ ycbcr_format.full_range = mlt_properties_get_int( properties, "force_full_luma" );
+ ycbcr_format.chroma_subsampling_x = ycbcr_format.chroma_subsampling_y = 2;
+ // TODO: make new frame properties set by producers
+ ycbcr_format.cb_x_position = ycbcr_format.cr_x_position = 0.0f;
+ ycbcr_format.cb_y_position = ycbcr_format.cr_y_position = 0.5f;
+ input->useYCbCrInput( chain, image_format, ycbcr_format, width, height );
+ input->set_pixel_data( *image );
+ }
+ else if ( *format == mlt_image_yuv422 ) {
+ ImageFormat image_format;
+ YCbCrFormat ycbcr_format;
+ if ( 709 == mlt_properties_get_int( properties, "colorspace" ) ) {
+ image_format.color_space = COLORSPACE_REC_709;
+ image_format.gamma_curve = GAMMA_REC_709;
+ ycbcr_format.luma_coefficients = YCBCR_REC_709;
+ } else if ( 576 == height ) {
+ image_format.color_space = COLORSPACE_REC_601_625;
+ image_format.gamma_curve = GAMMA_REC_601;
+ ycbcr_format.luma_coefficients = YCBCR_REC_601;
+ } else {
+ image_format.color_space = COLORSPACE_REC_601_525;
+ image_format.gamma_curve = GAMMA_REC_601;
+ ycbcr_format.luma_coefficients = YCBCR_REC_601;
+ }
+ ycbcr_format.full_range = mlt_properties_get_int( properties, "force_full_luma" );
+ ycbcr_format.chroma_subsampling_x = 2;
+ ycbcr_format.chroma_subsampling_y = 1;
+ // TODO: make new frame properties set by producers
+ ycbcr_format.cb_x_position = ycbcr_format.cr_x_position = 0.0f;
+ ycbcr_format.cb_y_position = ycbcr_format.cr_y_position = 0.5f;
+ input->useYCbCrInput( chain, image_format, ycbcr_format, width, height );
+
+ // convert chunky to planar
+ uint8_t* planar = (uint8_t*) mlt_pool_alloc( img_size );
+ yuv422_to_yuv422p( *image, planar, width, height );
+ input->set_pixel_data( planar );
+ mlt_frame_set_image( frame, planar, img_size, mlt_pool_release );
+ }
+ // Finalize the separate conversion chain if needed.
+ if ( finalize_chain )
+ chain->finalize();
+ }
+
+ if ( output_format != mlt_image_glsl ) {
+ glsl_fbo fbo = glsl->get_fbo( width, height );
+
+ if ( output_format == mlt_image_glsl_texture ) {
+ glsl_texture texture = glsl->get_texture( width, height, GL_RGBA );
+
+ glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
+ check_error();
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+
+ GlslManager::render( service, chain, fbo->fbo, width, height );
+
+ glFinish();
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+
+ *image = (uint8_t*) &texture->texture;
+ mlt_frame_set_image( frame, *image, 0, NULL );
+ mlt_properties_set_data( properties, "movit.convert.texture", texture, 0,
+ (mlt_destructor) GlslManager::release_texture, NULL );
+ mlt_properties_set_int( properties, "format", output_format );
+ *format = output_format;
+ }
+ else {
+ // Use a PBO to hold the data we read back with glReadPixels()
+ // (Intel/DRI goes into a slow path if we don't read to PBO)
+ GLenum gl_format = ( output_format == mlt_image_rgb24a || output_format == mlt_image_opengl )?
+ GL_RGBA : GL_RGB;
+ img_size = width * height * ( gl_format == GL_RGB? 3 : 4 );
+ glsl_pbo pbo = glsl->get_pbo( img_size );
+ glsl_texture texture = glsl->get_texture( width, height, gl_format );
+
+ if ( fbo && pbo && texture ) {
+ // Set the FBO
+ glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
+ check_error();
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+
+ GlslManager::render( service, chain, fbo->fbo, width, height );
+
+ // Read FBO into PBO
+ glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, pbo->pbo );
+ check_error();
+ glBufferData( GL_PIXEL_PACK_BUFFER_ARB, img_size, NULL, GL_STREAM_READ );
+ check_error();
+ glReadPixels( 0, 0, width, height, gl_format, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0) );
+ check_error();
+
+ // Copy from PBO
+ uint8_t* buf = (uint8_t*) glMapBuffer( GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY );
+ check_error();
+ *image = (uint8_t*) mlt_pool_alloc( img_size );
+ mlt_frame_set_image( frame, *image, img_size, mlt_pool_release );
+ memcpy( *image, buf, img_size );
+
+ if ( output_format == mlt_image_yuv422 || output_format == mlt_image_yuv420p ) {
+ *format = mlt_image_rgb24;
+ error = convert_on_cpu( frame, image, format, output_format );
+ }
+
+ // Release PBO and FBO
+ glUnmapBuffer( GL_PIXEL_PACK_BUFFER_ARB );
+ check_error();
+ glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, 0 );
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ check_error();
+ mlt_properties_set_data( properties, "movit.convert.texture", texture, 0,
+ (mlt_destructor) GlslManager::release_texture, NULL);
+
+ mlt_properties_set_int( properties, "format", output_format );
+ *format = output_format;
+ }
+ else {
+ error = 1;
+ }
+ }
+ if ( fbo ) GlslManager::release_fbo( fbo );
+ }
+ else {
+ mlt_properties_set_int( properties, "format", output_format );
+ *format = output_format;
+ }
+ GlslManager::get_instance()->unlock_service( frame );
+
+ return error;
+}
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ // Set a default colorspace on the frame if not yet set by the producer.
+ // The producer may still change it during get_image.
+ // This way we do not have to modify each producer to set a valid colorspace.
+ mlt_properties properties = MLT_FRAME_PROPERTIES(frame);
+ if ( mlt_properties_get_int( properties, "colorspace" ) <= 0 )
+ mlt_properties_set_int( properties, "colorspace", mlt_service_profile( MLT_FILTER_SERVICE(filter) )->colorspace );
+
+ frame->convert_image = convert_image;
+
+ mlt_filter cpu_csc = (mlt_filter) mlt_properties_get_data( MLT_FILTER_PROPERTIES( filter ), "cpu_csc", NULL );
+ mlt_properties_inc_ref( MLT_FILTER_PROPERTIES(cpu_csc) );
+ mlt_properties_set_data( properties, "cpu_csc", cpu_csc, 0,
+ (mlt_destructor) mlt_filter_close, NULL );
+
+ return frame;
+}
+
+static mlt_filter create_filter( mlt_profile profile, char *effect )
+{
+ mlt_filter filter = NULL;
+ char *id = strdup( effect );
+ char *arg = strchr( id, ':' );
+ if ( arg != NULL )
+ *arg ++ = '\0';
+
+ // The swscale and avcolor_space filters require resolution as arg to test compatibility
+ if ( !strcmp( effect, "avcolor_space" ) )
+ arg = (char*) profile->width;
+
+ filter = mlt_factory_filter( profile, id, arg );
+ if ( filter )
+ mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "_loader", 1 );
+ free( id );
+ return filter;
+}
+
+extern "C" {
+
+mlt_filter filter_movit_convert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) )
+ {
+ mlt_filter cpu_csc = create_filter( profile, "avcolor_space" );
+ if ( !cpu_csc )
+ cpu_csc = create_filter( profile, "imageconvert" );
+ if ( cpu_csc )
+ mlt_properties_set_data( MLT_FILTER_PROPERTIES( filter ), "cpu_csc", cpu_csc, 0,
+ (mlt_destructor) mlt_filter_close, NULL );
+ filter->process = process;
+ }
+ return filter;
+}
+
+}
--- /dev/null
+/*
+ * filter_movit_crop.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/padding_effect.h>
+
+static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+{
+ int error = 0;
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+ mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame );
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
+ mlt_image_format requested_format = *format;
+
+ // Correct width/height if necessary
+ *width = mlt_properties_get_int( properties, "crop.original_width" );
+ *height = mlt_properties_get_int( properties, "crop.original_height" );
+ if ( *width == 0 || *height == 0 )
+ {
+ *width = mlt_properties_get_int( properties, "meta.media.width" );
+ *height = mlt_properties_get_int( properties, "meta.media.height" );
+ }
+ if ( *width == 0 || *height == 0 )
+ {
+ *width = profile->width;
+ *height = profile->height;
+ }
+ mlt_properties_set_int( properties, "rescale_width", *width );
+ mlt_properties_set_int( properties, "rescale_height", *height );
+
+ // Get the image as requested
+// *format = (mlt_image_format) mlt_properties_get_int( MLT_PRODUCER_PROPERTIES(producer), "_movit image_format" );
+ *format = mlt_image_none;
+ error = mlt_frame_get_image( frame, image, format, width, height, writable );
+
+ // Skip processing if requested.
+ if ( requested_format == mlt_image_none )
+ return error;
+
+ if ( !error && *format != mlt_image_glsl && frame->convert_image ) {
+ // Pin the requested format to the first one returned.
+// mlt_properties_set_int( MLT_PRODUCER_PROPERTIES(producer), "_movit image_format", *format );
+ error = frame->convert_image( frame, image, format, mlt_image_glsl );
+ }
+ if ( !error ) {
+ double left = mlt_properties_get_double( properties, "crop.left" );
+ double right = mlt_properties_get_double( properties, "crop.right" );
+ double top = mlt_properties_get_double( properties, "crop.top" );
+ double bottom = mlt_properties_get_double( properties, "crop.bottom" );
+ int owidth = *width - left - right;
+ int oheight = *height - top - bottom;
+ owidth = owidth < 0 ? 0 : owidth;
+ oheight = oheight < 0 ? 0 : oheight;
+
+ mlt_log_debug( MLT_FILTER_SERVICE(filter), "%dx%d -> %dx%d\n", *width, *height, owidth, oheight);
+
+ GlslManager::get_instance()->lock_service( frame );
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( effect ) {
+ bool ok = effect->set_int( "width", owidth );
+ ok |= effect->set_int( "height", oheight );
+ ok |= effect->set_float( "left", -left );
+ ok |= effect->set_float( "top", -top );
+ assert(ok);
+ *width = owidth;
+ *height = oheight;
+ }
+ GlslManager::get_instance()->unlock_service( frame );
+ }
+
+ return error;
+}
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ mlt_producer producer = mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) );
+ if ( !GlslManager::init_chain( MLT_PRODUCER_SERVICE(producer) ) ) {
+ Effect* effect = GlslManager::add_effect( filter, frame, new PaddingEffect );
+ RGBATuple border_color( 0.0f, 0.0f, 0.0f, 1.0f );
+ bool ok = effect->set_vec4( "border_color", (float*) &border_color );
+ assert(ok);
+ }
+ mlt_frame_push_service( frame, filter );
+ mlt_frame_push_get_image( frame, get_image );
+ return frame;
+}
+
+extern "C"
+mlt_filter filter_movit_crop_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ filter->process = process;
+ }
+ return filter;
+}
--- /dev/null
+/*
+ * filter_movit_diffusion.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/diffusion_effect.h>
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !mlt_frame_is_test_card( frame ) ) {
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( !effect )
+ effect = GlslManager::add_effect( filter, frame, new DiffusionEffect() );
+ if ( effect ) {
+ mlt_properties filter_props = MLT_FILTER_PROPERTIES( filter );
+ bool ok = effect->set_float( "radius", mlt_properties_get_double( filter_props, "radius" ) );
+ ok |= effect->set_float( "blurred_mix_amount", mlt_properties_get_double( filter_props, "mix" ) );
+ assert(ok);
+ }
+ }
+ return frame;
+}
+
+extern "C" {
+
+mlt_filter filter_movit_diffusion_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_properties_set_double( properties, "radius", 3.0 );
+ mlt_properties_set_double( properties, "mix", 0.3 );
+ filter->process = process;
+ }
+ return filter;
+}
+
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.diffusion
+title: Diffusion (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: >
+ There are many different effects that go under the name of "diffusion",
+ seemingly all of the inspired by the effect you get when you put a
+ diffusion filter in front of your camera lens. The effect most people
+ want is a general flattening/smoothing of the light, and reduction of
+ fine detail (most notably, blemishes in people's skin), without ruining
+ edges, which a regular blur would do.
+ We do a relatively simple version, sometimes known as "white diffusion",
+ where we first blur the picture, and then overlay it on the original
+ using the original as a matte.
+
+parameters:
+ - identifier: radius
+ title: Blur Radius
+ type: float
+ minimum: 0.0
+ default: 3.0
+
+ - identifier: mix
+ title: Blurriness
+ type: float
+ minimum: 0.0
+ maximum: 1.0
+ default: 0.3
--- /dev/null
+/*
+ * filter_movit_glow.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/glow_effect.h>
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !mlt_frame_is_test_card( frame ) ) {
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( !effect )
+ effect = GlslManager::add_effect( filter, frame, new GlowEffect() );
+ if ( effect ) {
+ mlt_properties filter_props = MLT_FILTER_PROPERTIES( filter );
+ bool ok = effect->set_float( "radius", mlt_properties_get_double( filter_props, "radius" ) );
+ ok |= effect->set_float( "blurred_mix_amount", mlt_properties_get_double( filter_props, "blur_mix" ) );
+ ok |= effect->set_float( "highlight_cutoff", mlt_properties_get_double( filter_props, "highlight_cutoff" ) );
+ assert(ok);
+ }
+ }
+ return frame;
+}
+
+extern "C" {
+
+mlt_filter filter_movit_glow_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_properties_set_double( properties, "radius", 20.0 );
+ mlt_properties_set_double( properties, "blur_mix", 1.0 );
+ mlt_properties_set_double( properties, "highlight_cutoff", 0.2 );
+ filter->process = process;
+ }
+ return filter;
+}
+
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.glow
+title: Glow (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: >
+ Cut out the highlights of the image (everything above a certain threshold),
+ blur them, and overlay them onto the original image.
+
+parameters:
+ - identifier: radius
+ title: Radius
+ type: float
+ minimum: 0.0
+ default: 20.0
+
+ - identifier: blur_mix
+ title: Highlight Blurriness
+ type: float
+ minimum: 0.0
+ maximum: 1.0
+ default: 1.0
+
+ - identifier: highlight_cutoff
+ title: Highlight Cutoff Threshold
+ type: float
+ minimum: 0.0
+ maximum: 1.0
+ default: 0.2
--- /dev/null
+/*
+ * filter_movit_mirror.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/mirror_effect.h>
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !mlt_frame_is_test_card( frame ) ) {
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( !effect )
+ GlslManager::add_effect( filter, frame, new MirrorEffect() );
+ }
+ return frame;
+}
+
+extern "C" {
+
+mlt_filter filter_movit_mirror_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ filter->process = process;
+ }
+ return filter;
+}
+
+}
+
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.mirror
+title: Mirror (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+description: A simple horizontal mirroring.
+tags:
+ - Video
--- /dev/null
+/*
+ * filter_movit_opacity.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/mix_effect.h>
+
+static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+{
+ mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame );
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ GlslManager::get_instance()->lock_service( frame );
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( effect ) {
+ bool ok = effect->set_float( "strength_first", mlt_properties_get_double( properties, "opacity" ) );
+ assert(ok);
+ }
+ GlslManager::get_instance()->unlock_service( frame );
+ *format = mlt_image_glsl;
+ return mlt_frame_get_image( frame, image, format, width, height, writable );
+}
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !mlt_frame_is_test_card( frame ) ) {
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( !effect ) {
+ effect = GlslManager::add_effect( filter, frame, new MixEffect, 0 );
+ assert(effect);
+ bool ok = effect->set_float( "strength_first", 1.0f );
+ ok |= effect->set_float( "strength_second", 0.0f );
+ assert(ok);
+ }
+ }
+ mlt_frame_push_service( frame, filter );
+ mlt_frame_push_get_image( frame, get_image );
+ return frame;
+}
+
+extern "C"
+mlt_filter filter_movit_opacity_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_properties_set( properties, "opacity", arg? arg : "1" );
+ filter->process = process;
+ }
+ return filter;
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.opacity
+title: Opacity (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: Adjust the opacity of an image through the alpha channel.
+notes: >
+ When used in some transitions this will cause this video to be mixed with
+ the other video. If the video this is applied to already has an alpha channel,
+ then this preserves that by multiplying the opacity level with the alpha channel.
+ This filter is especially handy when used in conjunction with movit.overlay.
+
+parameters:
+ - identifier: opacity
+ title: Opacity
+ type: float
+ minimum: 0
+ maximum: 1
+ default: 1
--- /dev/null
+/*
+ * filter_movit_rect.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include "glsl_manager.h"
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ // Drive the resize and resample filters on the b_frame for these composite parameters
+ mlt_properties properties = MLT_FILTER_PROPERTIES(filter);
+ mlt_properties frame_props = MLT_FRAME_PROPERTIES(frame);
+ mlt_properties_set( frame_props, "resize.geometry", mlt_properties_get( properties, "geometry" ) );
+ mlt_properties_set( frame_props, "resize.fill", mlt_properties_get( properties, "fill" ) );
+ mlt_properties_set( frame_props, "resize.halign", mlt_properties_get( properties, "halign" ) );
+ mlt_properties_set( frame_props, "resize.valign", mlt_properties_get( properties, "valign" ) );
+ return frame;
+}
+
+extern "C"
+mlt_filter filter_movit_rect_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ mlt_properties_set( MLT_FILTER_PROPERTIES(filter), "geometry", arg );
+ mlt_properties_set_int( MLT_FILTER_PROPERTIES(filter), "fill", 1 );
+ filter->process = process;
+ }
+ return filter;
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.rect
+title: Position and Size (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: >
+ Change the coordinates and scale to fit within a rectangle.
+
+parameters:
+ - identifier: geometry
+ title: Rectangle
+ type: geometry
+ description: >
+ Keyframable rectangle specification.
+ mutable: yes
+
+ - identifier: fill
+ title: Upscale to Fill
+ description: >
+ Determines whether the image will be scaled up to fill the rectangle
+ or whether the size will be constrained to 100% of the profile
+ resolution.
+ type: integer
+ default: 1
+ minimum: 0
+ maximum: 1
+ mutable: yes
+ widget: checkbox
+
+ - identifier: halign
+ title: Horizontal alignment
+ description: >
+ Set the horizontal alignment within the geometry rectangle.
+ type: string
+ default: left
+ values:
+ - left
+ - center
+ - right
+ mutable: yes
+ widget: combo
+
+ - identifier: valign
+ title: Vertical alignment
+ description: >
+ Set the vertical alignment within the geometry rectangle.
+ type: string
+ default: top
+ values:
+ - top
+ - middle
+ - bottom
+ mutable: yes
+ widget: combo
--- /dev/null
+/*
+ * filter_movit_resample.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/resample_effect.h>
+
+static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+{
+ int error = 0;
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+ mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame );
+ mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
+
+ // Correct width/height if necessary
+ if ( *width == 0 || *height == 0 )
+ {
+ *width = profile->width;
+ *height = profile->height;
+ }
+
+ int iwidth = *width;
+ int iheight = *height;
+ double factor = mlt_properties_get_double( filter_properties, "factor" );
+ factor = factor > 0 ? factor : 1.0;
+ int owidth = *width * factor;
+ int oheight = *height * factor;
+
+ // If meta.media.width/height exist, we want that as minimum information
+ if ( mlt_properties_get_int( properties, "meta.media.width" ) )
+ {
+ iwidth = mlt_properties_get_int( properties, "meta.media.width" );
+ iheight = mlt_properties_get_int( properties, "meta.media.height" );
+ }
+
+ mlt_properties_set_int( properties, "rescale_width", *width );
+ mlt_properties_set_int( properties, "rescale_height", *height );
+
+ // Deinterlace if height is changing to prevent fields mixing on interpolation
+ if ( iheight != oheight )
+ mlt_properties_set_int( properties, "consumer_deinterlace", 1 );
+
+ // Get the image as requested
+ if ( *format != mlt_image_none )
+ *format = mlt_image_glsl;
+ error = mlt_frame_get_image( frame, image, format, &iwidth, &iheight, writable );
+ if ( !error ) {
+ GlslManager::get_instance()->lock_service( frame );
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( effect ) {
+ bool ok = effect->set_int( "width", owidth );
+ ok |= effect->set_int( "height", oheight );
+ assert(ok);
+ *width = owidth;
+ *height = oheight;
+ }
+ GlslManager::get_instance()->unlock_service( frame );
+ }
+
+ return error;
+}
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !GlslManager::get_effect( filter, frame ) )
+ GlslManager::add_effect( filter, frame, new ResampleEffect );
+ mlt_frame_push_service( frame, filter );
+ mlt_frame_push_get_image( frame, get_image );
+ return frame;
+}
+
+extern "C"
+mlt_filter filter_movit_resample_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ filter->process = process;
+ }
+ return filter;
+}
--- /dev/null
+/*
+ * filter_movit_resize.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/init.h>
+#include <movit/padding_effect.h>
+
+static float alignment_parse( char* align )
+{
+ int ret = 0.0f;
+
+ if ( align == NULL );
+ else if ( isdigit( align[ 0 ] ) )
+ ret = atoi( align );
+ else if ( align[ 0 ] == 'c' || align[ 0 ] == 'm' )
+ ret = 1.0f;
+ else if ( align[ 0 ] == 'r' || align[ 0 ] == 'b' )
+ ret = 2.0f;
+
+ return ret;
+}
+
+static struct mlt_geometry_item_s get_geometry( mlt_profile profile, mlt_filter filter, mlt_frame frame )
+{
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+ mlt_properties filter_props = MLT_FILTER_PROPERTIES( filter );
+ struct mlt_geometry_item_s item;
+ mlt_geometry geometry = (mlt_geometry) mlt_properties_get_data( filter_props, "geometry", NULL );
+ char *string = mlt_properties_get( properties, "resize.geometry" );
+ int length = mlt_filter_get_length2( filter, frame );
+
+ if ( !geometry ) {
+ geometry = mlt_geometry_init();
+ mlt_properties_set_data( filter_props, "geometry", geometry, 0,
+ (mlt_destructor) mlt_geometry_close, NULL );
+ mlt_geometry_parse( geometry, string, length, profile->width, profile->height );
+ } else {
+ mlt_geometry_refresh( geometry, string, length, profile->width, profile->height );
+ }
+
+ mlt_geometry_fetch( geometry, &item, mlt_filter_get_position( filter, frame ) );
+
+ if ( !mlt_properties_get_int( properties, "resize.fill" ) ) {
+ int x = mlt_properties_get_int( properties, "meta.media.width" );
+ item.w = item.w > x ? x : item.w;
+ x = mlt_properties_get_int( properties, "meta.media.height" );
+ item.h = item.h > x ? x : item.h;
+ }
+
+ return item;
+}
+
+static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+{
+ int error = 0;
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+ mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame );
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
+
+ // Retrieve the aspect ratio
+ double aspect_ratio = mlt_frame_get_aspect_ratio( frame );
+ double consumer_aspect = mlt_profile_sar( profile );
+
+ // Correct Width/height if necessary
+ if ( *width == 0 || *height == 0 )
+ {
+ *width = profile->width;
+ *height = profile->height;
+ }
+
+ // Assign requested width/height from our subordinate
+ int owidth = *width;
+ int oheight = *height;
+
+ // Use a geometry to compute position and size
+ struct mlt_geometry_item_s geometry_item;
+ geometry_item.x = geometry_item.y = 0.0f;
+ geometry_item.distort = 0;
+ if ( mlt_properties_get( properties, "resize.geometry" ) ) {
+ geometry_item = get_geometry( profile, filter, frame );
+ owidth = lrintf( geometry_item.w );
+ oheight = lrintf( geometry_item.h );
+ }
+
+ // Check for the special case - no aspect ratio means no problem :-)
+ if ( aspect_ratio == 0.0 )
+ aspect_ratio = consumer_aspect;
+
+ // Reset the aspect ratio
+ mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio );
+
+ // Skip processing if requested.
+ char *rescale = mlt_properties_get( properties, "rescale.interp" );
+ if ( *format == mlt_image_none || ( rescale && !strcmp( rescale, "none" ) ) )
+ return mlt_frame_get_image( frame, image, format, width, height, writable );
+
+ if ( mlt_properties_get_int( properties, "distort" ) == 0 &&
+ geometry_item.distort == 0 )
+ {
+ // Normalise the input and out display aspect
+ int normalised_width = profile->width;
+ int normalised_height = profile->height;
+ int real_width = mlt_properties_get_int( properties, "meta.media.width" );
+ int real_height = mlt_properties_get_int( properties, "meta.media.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 = consumer_aspect * owidth / oheight;
+
+ // Optimised for the input_ar > output_ar case (e.g. widescreen on standard)
+ int scaled_width = lrint( ( 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 = lrint( ( output_ar * normalised_height ) / input_ar );
+ }
+
+ // Now calculate the actual image size that we want
+ owidth = lrint( scaled_width * owidth / normalised_width );
+ oheight = lrint( scaled_height * oheight / normalised_height );
+
+ mlt_log_debug( MLT_FILTER_SERVICE(filter),
+ "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);
+
+ // Tell frame we have conformed the aspect to the consumer
+ mlt_frame_set_aspect_ratio( frame, consumer_aspect );
+ }
+
+ mlt_properties_set_int( properties, "distort", 0 );
+
+ // Now get the image
+ *format = mlt_image_glsl;
+ error = mlt_frame_get_image( frame, image, format, &owidth, &oheight, writable );
+
+ // Offset the position according to alignment
+ float w = float( *width - owidth );
+ float h = float( *height - oheight );
+ if ( mlt_properties_get( properties, "resize.geometry" ) ) {
+ // default left if geometry supplied
+ geometry_item.x += w * alignment_parse( mlt_properties_get( properties, "resize.halign" ) ) / 2.0f;
+ geometry_item.y += h * alignment_parse( mlt_properties_get( properties, "resize.valign" ) ) / 2.0f;
+ } else {
+ // default center if no geometry
+ geometry_item.x = w * 0.5f;
+ geometry_item.y = h * 0.5f;
+ }
+
+ if ( !error ) {
+ GlslManager::get_instance()->lock_service( frame );
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( effect ) {
+ bool ok = effect->set_int( "width", *width );
+ ok |= effect->set_int( "height", *height );
+ ok |= effect->set_float( "left", geometry_item.x );
+ ok |= effect->set_float( "top", geometry_item.y );
+ assert(ok);
+ }
+ GlslManager::get_instance()->unlock_service( frame );
+ }
+
+ return error;
+}
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !GlslManager::get_effect( filter, frame ) )
+ GlslManager::add_effect( filter, frame, new PaddingEffect );
+ mlt_frame_push_service( frame, filter );
+ mlt_frame_push_get_image( frame, get_image );
+ return frame;
+}
+
+extern "C"
+mlt_filter filter_movit_resize_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) )
+ {
+ filter->process = process;
+ }
+ return filter;
+}
--- /dev/null
+/*
+ * filter_movit_saturation.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/saturation_effect.h>
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !mlt_frame_is_test_card( frame ) ) {
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( !effect )
+ effect = GlslManager::add_effect( filter, frame, new SaturationEffect() );
+ if ( effect ) {
+ mlt_properties filter_props = MLT_FILTER_PROPERTIES( filter );
+ bool ok = effect->set_float( "saturation", mlt_properties_get_double( filter_props, "saturation" ) );
+ assert(ok);
+ }
+ }
+ return frame;
+}
+
+extern "C" {
+
+mlt_filter filter_movit_saturation_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_properties_set( properties, "saturation", arg? arg : "1.0" );
+ filter->process = process;
+ }
+ return filter;
+}
+
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.saturation
+title: Saturation (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: >
+ A simple desaturation/saturation effect. We use the Rec. 709
+ definition of luminance (in linear light, of course) and linearly
+ interpolate between that (saturation=0) and the original signal
+ (saturation=1). Extrapolating that curve further (ie., saturation > 1)
+ gives us increased saturation if so desired.
+
+parameters:
+ - identifier: saturation
+ title: Saturation
+ type: float
+ minimum: 0
+ default: 1
--- /dev/null
+/*
+ * filter_movit_vignette.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/vignette_effect.h>
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !mlt_frame_is_test_card( frame ) ) {
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( !effect ) {
+ effect = GlslManager::add_effect( filter, frame, new VignetteEffect() );
+ }
+ if ( effect ) {
+ mlt_properties filter_props = MLT_FILTER_PROPERTIES( filter );
+ bool ok = effect->set_float( "radius", mlt_properties_get_double( filter_props, "radius" ) );
+ ok |= effect->set_float( "inner_radius", mlt_properties_get_double( filter_props, "inner_radius" ) );
+ assert(ok);
+ }
+ }
+ return frame;
+}
+
+extern "C" {
+
+mlt_filter filter_movit_vignette_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ filter->process = process;
+ mlt_properties_set_double( MLT_FILTER_PROPERTIES(filter), "radius", 0.3 );
+ mlt_properties_set_double( MLT_FILTER_PROPERTIES(filter), "inner_radius", 0.3 );
+ }
+ return filter;
+}
+
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.vignette
+title: Vignette (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: >
+ A circular vignette, falling off as cos² of the distance from the center
+ (the classic formula for approximating a real lens).
+
+parameters:
+ - identifier: radius
+ title: Outer Radius
+ type: float
+ minimum: 0.0
+ maximum: 1.0
+ default: 0.3
+
+ - identifier: inner_radius
+ title: Inner Radius
+ type: float
+ minimum: 0.0
+ maximum: 1.0
+ default: 0.3
--- /dev/null
+/*
+ * filter_white_balance.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/white_balance_effect.h>
+
+static mlt_frame process( mlt_filter filter, mlt_frame frame )
+{
+ if ( !mlt_frame_is_test_card( frame ) ) {
+ Effect* effect = GlslManager::get_effect( filter, frame );
+ if ( !effect )
+ effect = GlslManager::add_effect( filter, frame, new WhiteBalanceEffect );
+ if ( effect ) {
+ mlt_properties filter_props = MLT_FILTER_PROPERTIES( filter );
+ int color_int = mlt_properties_get_int( filter_props, "neutral_color" );
+ RGBTriplet color(
+ float((color_int >> 24) & 0xff) / 255.0f,
+ float((color_int >> 16) & 0xff) / 255.0f,
+ float((color_int >> 8) & 0xff) / 255.0f
+ );
+ bool ok = effect->set_vec3( "neutral_color", (float*) &color );
+ ok |= effect->set_float( "output_color_temperature", mlt_properties_get_double( filter_props, "color_temperature" ) );
+ assert(ok);
+ }
+ }
+ return frame;
+}
+
+extern "C" {
+
+mlt_filter filter_white_balance_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+
+ if ( glsl && ( filter = mlt_filter_new() ) ) {
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+ mlt_properties_set( properties, "neutral_color", arg? arg : "#7f7f7f" );
+ mlt_properties_set_double( properties, "color_temperature", 6500.0 );
+ filter->process = process;
+ }
+ return filter;
+}
+
+}
--- /dev/null
+schema_version: 0.1
+type: filter
+identifier: movit.white_balance
+title: White Balance (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: Color correction in LMS color space.
+
+parameters:
+ - identifier: neutral_color
+ title: Neutral Color
+ type: string
+ widget: color
+ default: #7f7f7f
+
+ - identifier: color_temperature
+ title: Color Temperature
+ type: float
+ minimum: 1000.0
+ maximum: 15000.0
+ default: 6500.0
+ unit: Kelvin
--- /dev/null
+/*
+ * glsl_manager.h
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 GLSL_MANAGER_H
+#define GLSL_MANAGER_H
+
+#include <GL/glew.h>
+#include <mlt++/MltFilter.h>
+#include <mlt++/MltDeque.h>
+
+#define MAXLISTCOUNT 1024
+typedef struct glsl_list_s *glsl_list;
+struct glsl_list_s
+{
+ void *items[MAXLISTCOUNT];
+ int count;
+
+ int ( *add )( glsl_list, void* );
+ void* ( *at )( glsl_list, int );
+ void* ( *take_at )( glsl_list, int );
+ void* ( *take )( glsl_list, void* );
+};
+
+struct glsl_texture_s
+{
+ int used;
+ GLuint texture;
+ int width;
+ int height;
+ GLint internal_format;
+};
+typedef struct glsl_texture_s *glsl_texture;
+
+struct glsl_fbo_s
+{
+ int used;
+ int width;
+ int height;
+ GLuint fbo;
+};
+typedef struct glsl_fbo_s *glsl_fbo;
+
+struct glsl_pbo_s
+{
+ int size;
+ GLuint pbo;
+};
+typedef struct glsl_pbo_s *glsl_pbo;
+
+class Effect;
+class EffectChain;
+class MltInput;
+
+class GlslManager : public Mlt::Filter
+{
+public:
+ GlslManager();
+ ~GlslManager();
+ static GlslManager* get_instance();
+
+ glsl_fbo get_fbo(int width, int height);
+ static void release_fbo(glsl_fbo);
+ glsl_texture get_texture(int width, int height, GLint internal_format);
+ static void release_texture(glsl_texture);
+ glsl_pbo get_pbo(int size);
+
+ Properties effect_list( Mlt::Service &service );
+ static bool init_chain(mlt_service);
+ static EffectChain* get_chain(mlt_service);
+ static MltInput* get_input(mlt_service);
+ static void reset_finalized(mlt_service);
+ static Effect* get_effect(mlt_filter, mlt_frame);
+ static Effect* add_effect(mlt_filter, mlt_frame, Effect*);
+ static Effect* add_effect(mlt_filter, mlt_frame, Effect*, Effect* input_b);
+ static void render(mlt_service, void *chain, GLuint fbo, int width, int height);
+ static void lock_service(mlt_frame frame);
+ static void unlock_service(mlt_frame frame);
+
+private:
+ static void onInit( mlt_properties owner, GlslManager* filter );
+ static void onServiceChanged( mlt_properties owner, mlt_service service );
+ static void onPropertyChanged( mlt_properties owner, mlt_service service, const char* property );
+ Mlt::Deque fbo_list;
+ Mlt::Deque texture_list;
+ glsl_pbo pbo;
+ EffectChain* current_chain;
+};
+
+#endif // GLSL_MANAGER_H
--- /dev/null
+/*
+ * mlt_flip_effect.h
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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_FLIP_EFFECT_H
+#define MLT_FLIP_EFFECT_H
+
+namespace Mlt
+{
+
+class VerticalFlip : public Effect {
+public:
+ VerticalFlip() {}
+ virtual std::string effect_type_id() const { return "MltVerticalFlip"; }
+ std::string output_fragment_shader() {
+ return "vec4 FUNCNAME(vec2 tc) { tc.y = 1.0 - tc.y; return INPUT(tc); }\n";
+ }
+ virtual bool needs_linear_light() const { return false; }
+ virtual bool needs_srgb_primaries() const { return false; }
+ AlphaHandling alpha_handling() const { return DONT_CARE_ALPHA_TYPE; }
+};
+
+} // namespace Mlt
+
+#endif // MLT_FLIP_EFFECT_H
--- /dev/null
+/*
+ * mlt_movit_input.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 "mlt_movit_input.h"
+#include "fbo_input.h"
+
+MltInput::MltInput(unsigned width, unsigned height)
+ : m_width(width)
+ , m_height(height)
+ , output_linear_gamma(false)
+ , needs_mipmaps(false)
+ , input(0)
+ , isRGB(true)
+{
+ register_int("output_linear_gamma", &output_linear_gamma);
+ register_int("needs_mipmaps", &needs_mipmaps);
+}
+
+MltInput::~MltInput()
+{
+ // XXX: this is crashing when a producer is closed
+ // on Windows when using melt with qglsl.
+// delete input;
+}
+
+std::string MltInput::output_fragment_shader()
+{
+ assert(input);
+ return input->output_fragment_shader();
+}
+
+void MltInput::set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num)
+{
+ assert(input);
+ input->set_gl_state(glsl_program_num, prefix, sampler_num);
+}
+
+Effect::AlphaHandling MltInput::alpha_handling() const
+{
+ assert(input);
+ return input->alpha_handling();
+}
+
+void MltInput::finalize()
+{
+ assert(input);
+ bool ok = input->set_int("output_linear_gamma", output_linear_gamma);
+ ok |= input->set_int("needs_mipmaps", needs_mipmaps);
+ assert(ok);
+ input->finalize();
+}
+
+bool MltInput::can_output_linear_gamma() const
+{
+ assert(input);
+ return input->can_output_linear_gamma();
+}
+
+Colorspace MltInput::get_color_space() const
+{
+ assert(input);
+ return input->get_color_space();
+}
+GammaCurve MltInput::get_gamma_curve() const
+{
+ assert(input);
+ return input->get_gamma_curve();
+}
+
+void MltInput::useFlatInput(EffectChain* chain, MovitPixelFormat pix_fmt, unsigned width, unsigned height)
+{
+ if (!input) {
+ m_width = width;
+ m_height = height;
+ ImageFormat image_format;
+ image_format.color_space = COLORSPACE_sRGB;
+ image_format.gamma_curve = GAMMA_sRGB;
+ input = new FlatInput(image_format, pix_fmt, GL_UNSIGNED_BYTE, width, height);
+ chain->add_output(image_format, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
+ chain->set_dither_bits(8);
+ }
+}
+
+void MltInput::useYCbCrInput(EffectChain* chain, const ImageFormat& image_format, const YCbCrFormat& ycbcr_format, unsigned width, unsigned height)
+{
+ if (!input) {
+ m_width = width;
+ m_height = height;
+ input = new YCbCrInput(image_format, ycbcr_format, width, height);
+ ImageFormat output_format;
+ output_format.color_space = COLORSPACE_sRGB;
+ output_format.gamma_curve = GAMMA_sRGB;
+ chain->add_output(output_format, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
+ chain->set_dither_bits(8);
+ isRGB = false;
+ m_ycbcr_format = ycbcr_format;
+ }
+}
+
+void MltInput::useFBOInput(EffectChain *chain, GLuint texture)
+{
+ if (!input) {
+ FBOInput* fboInput = new FBOInput(m_width, m_height);
+ input = fboInput;
+ fboInput->set_texture(texture);
+ }
+}
+
+void MltInput::set_pixel_data(const unsigned char* data)
+{
+ assert(input);
+ if (isRGB) {
+ FlatInput* flat = (FlatInput*) input;
+ flat->set_pixel_data(data);
+ } else {
+ YCbCrInput* ycbcr = (YCbCrInput*) input;
+ ycbcr->set_pixel_data(0, data);
+ ycbcr->set_pixel_data(1, &data[m_width * m_height]);
+ ycbcr->set_pixel_data(2, &data[m_width * m_height + (m_width / m_ycbcr_format.chroma_subsampling_x * m_height / m_ycbcr_format.chroma_subsampling_y)]);
+ }
+}
--- /dev/null
+/*
+ * mlt_movit_input.h
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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_MOVIT_INPUT_H
+#define MLT_MOVIT_INPUT_H
+
+#include <movit/flat_input.h>
+#include <movit/ycbcr_input.h>
+#include <movit/effect_chain.h>
+
+class MltInput : public Input
+{
+public:
+ MltInput(unsigned width, unsigned height);
+ ~MltInput();
+
+ // Effect overrides
+ std::string effect_type_id() const { return "MltInput"; }
+ Effect::AlphaHandling alpha_handling() const;
+ std::string output_fragment_shader();
+ void set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num);
+
+ // Input ovverrides
+ void finalize();
+ bool can_output_linear_gamma() const;
+ unsigned get_width() const { return m_width; }
+ unsigned get_height() const { return m_height; }
+ Colorspace get_color_space() const;
+ GammaCurve get_gamma_curve() const;
+
+ // Custom methods
+ void useFlatInput(EffectChain* chain, MovitPixelFormat pix_fmt, unsigned width, unsigned height);
+ void useYCbCrInput(EffectChain* chain, const ImageFormat& image_format, const YCbCrFormat& ycbcr_format, unsigned width, unsigned height);
+ void useFBOInput(EffectChain* chain, GLuint texture);
+ void set_pixel_data(const unsigned char* data);
+
+private:
+ unsigned m_width, m_height;
+ int output_linear_gamma, needs_mipmaps;
+ Input *input;
+ bool isRGB;
+ YCbCrFormat m_ycbcr_format;
+};
+
+#endif // MLT_MOVIT_INPUT_H
--- /dev/null
+/*
+ * transition_movit_mix.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/init.h>
+#include <movit/effect_chain.h>
+#include <movit/util.h>
+#include <movit/mix_effect.h>
+#include "mlt_movit_input.h"
+#include "mlt_flip_effect.h"
+
+static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+{
+ int error = 0;
+
+ // Get the b frame from the stack
+ mlt_frame b_frame = (mlt_frame) mlt_frame_pop_frame( a_frame );
+
+ // Get the transition object
+ mlt_transition transition = (mlt_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 movit objects
+ mlt_service service = MLT_TRANSITION_SERVICE( transition );
+ mlt_service_lock( service );
+ EffectChain* chain = GlslManager::get_chain( service );
+ Effect* effect = (Effect*) mlt_properties_get_data( properties, "movit effect", NULL );
+ MltInput* a_input = GlslManager::get_input( service );
+ MltInput* b_input = (MltInput*) mlt_properties_get_data( properties, "movit input B", NULL );
+ mlt_image_format output_format = *format;
+
+ if ( !chain || !a_input ) {
+ mlt_service_unlock( service );
+ return 2;
+ }
+
+ // Get the transition parameters
+ int reverse = mlt_properties_get_int( properties, "reverse" );
+ double mix = mlt_properties_get( properties, "mix" ) ?
+ mlt_properties_get_double( properties, "mix" ) :
+ mlt_transition_get_progress( transition, a_frame );
+ double inverse = 1.0 - mix;
+
+ // Set the movit parameters
+ bool ok = effect->set_float( "strength_first", reverse ? mix : inverse );
+ ok |= effect->set_float( "strength_second", reverse ? inverse : mix );
+ assert( ok );
+
+ // Get the frames' textures
+ GLuint* texture_id[2] = {0, 0};
+ *format = mlt_image_glsl_texture;
+ mlt_frame_get_image( a_frame, (uint8_t**) &texture_id[0], format, width, height, 0 );
+ a_input->useFBOInput( chain, *texture_id[0] );
+ *format = mlt_image_glsl_texture;
+ mlt_frame_get_image( b_frame, (uint8_t**) &texture_id[1], format, width, height, 0 );
+ b_input->useFBOInput( chain, *texture_id[1] );
+
+ // Set resolution to that of the a_frame
+ *width = mlt_properties_get_int( a_props, "width" );
+ *height = mlt_properties_get_int( a_props, "height" );
+
+ // Setup rendering to an FBO
+ GlslManager* glsl = GlslManager::get_instance();
+ glsl_fbo fbo = glsl->get_fbo( *width, *height );
+ if ( output_format == mlt_image_glsl_texture ) {
+ glsl_texture texture = glsl->get_texture( *width, *height, GL_RGBA );
+
+ glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
+ check_error();
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+
+ GlslManager::render( service, chain, fbo->fbo, *width, *height );
+
+ glFinish();
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+
+ *image = (uint8_t*) &texture->texture;
+ mlt_frame_set_image( a_frame, *image, 0, NULL );
+ mlt_properties_set_data( properties, "movit.convert", texture, 0,
+ (mlt_destructor) GlslManager::release_texture, NULL );
+ *format = output_format;
+ }
+ else {
+ // Use a PBO to hold the data we read back with glReadPixels()
+ // (Intel/DRI goes into a slow path if we don't read to PBO)
+ GLenum gl_format = ( output_format == mlt_image_rgb24a || output_format == mlt_image_opengl )?
+ GL_RGBA : GL_RGB;
+ int img_size = *width * *height * ( gl_format == GL_RGB? 3 : 4 );
+ glsl_pbo pbo = glsl->get_pbo( img_size );
+ glsl_texture texture = glsl->get_texture( *width, *height, gl_format );
+
+ if ( fbo && pbo && texture ) {
+ // Set the FBO
+ glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
+ check_error();
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+
+ GlslManager::render( service, chain, fbo->fbo, *width, *height );
+
+ // Read FBO into PBO
+ glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, pbo->pbo );
+ check_error();
+ glBufferData( GL_PIXEL_PACK_BUFFER_ARB, img_size, NULL, GL_STREAM_READ );
+ check_error();
+ glReadPixels( 0, 0, *width, *height, gl_format, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0) );
+ check_error();
+
+ // Copy from PBO
+ uint8_t* buf = (uint8_t*) glMapBuffer( GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY );
+ check_error();
+
+ *format = gl_format == GL_RGBA ? mlt_image_rgb24a : mlt_image_rgb24;
+ *image = (uint8_t*) mlt_pool_alloc( img_size );
+ mlt_frame_set_image( a_frame, *image, img_size, mlt_pool_release );
+ memcpy( *image, buf, img_size );
+
+ // Release PBO and FBO
+ glUnmapBuffer( GL_PIXEL_PACK_BUFFER_ARB );
+ check_error();
+ glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, 0 );
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ check_error();
+ GlslManager::release_texture( texture );
+ }
+ else {
+ error = 1;
+ }
+ }
+ if ( fbo ) GlslManager::release_fbo( fbo );
+ mlt_service_unlock( service );
+
+ return error;
+}
+
+static mlt_frame process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame )
+{
+ mlt_service service = MLT_TRANSITION_SERVICE(transition);
+
+ if ( !GlslManager::init_chain( service ) ) {
+ // Create the Movit effect chain
+ EffectChain* chain = GlslManager::get_chain( service );
+ mlt_profile profile = mlt_service_profile( service );
+ Input* b_input = new MltInput( profile->width, profile->height );
+ ImageFormat output_format;
+ output_format.color_space = COLORSPACE_sRGB;
+ output_format.gamma_curve = GAMMA_sRGB;
+ chain->add_input( b_input );
+ chain->add_output( output_format, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED );
+ chain->set_dither_bits( 8 );
+
+ Effect* effect = chain->add_effect( new MixEffect(),
+ GlslManager::get_input( service ), b_input );
+
+ // Save these new effects on properties for get_image
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES(transition);
+ mlt_properties_set_data( properties, "movit effect", effect, 0, NULL, NULL );
+ mlt_properties_set_data( properties, "movit input B", b_input, 0, NULL, NULL );
+ }
+
+ // 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, get_image );
+
+ return a_frame;
+}
+
+extern "C"
+mlt_transition transition_movit_mix_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_transition transition = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+ if ( glsl && ( transition = mlt_transition_new() ) ) {
+ transition->process = process;
+ mlt_properties_set( MLT_TRANSITION_PROPERTIES( transition ), "mix", arg );
+
+ // Inform apps and framework that this is a video only transition
+ mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "_transition_type", 1 );
+ }
+ return transition;
+}
--- /dev/null
+schema_version: 0.1
+type: transition
+identifier: movit.mix
+title: Dissolve (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: A simple video cross-fade or mixing effect.
+
+parameters:
+ - identifier: argument
+ title: Mix Level
+ description: Performs a dissolve if a mix level is not supplied.
+ type: float
+ minimum: 0
+ maximum: 1
+
+ - identifier: mix
+ title: Mix Level
+ description: Performs a dissolve if a mix level is not supplied.
+ type: float
+ minimum: 0
+ maximum: 1
+
+ - identifier: reverse
+ title: Reverse
+ type: integer
+ mutable: yes
+ description: >
+ Reverse the direction of the transition.
+ default: 0
--- /dev/null
+/*
+ * transition_movit_overlay.cpp
+ * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "glsl_manager.h"
+#include <movit/init.h>
+#include <movit/effect_chain.h>
+#include <movit/util.h>
+#include <movit/overlay_effect.h>
+#include "mlt_movit_input.h"
+#include "mlt_flip_effect.h"
+
+static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+{
+ int error = 0;
+
+ // Get the b frame from the stack
+ mlt_frame b_frame = (mlt_frame) mlt_frame_pop_frame( a_frame );
+
+ // Get the transition object
+ mlt_transition transition = (mlt_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 movit objects
+ mlt_service service = MLT_TRANSITION_SERVICE( transition );
+ mlt_service_lock( service );
+ EffectChain* chain = GlslManager::get_chain( service );
+ MltInput* a_input = GlslManager::get_input( service );
+ MltInput* b_input = (MltInput*) mlt_properties_get_data( properties, "movit input B", NULL );
+ mlt_image_format output_format = *format;
+
+ if ( !chain || !a_input ) {
+ mlt_service_unlock( service );
+ return 2;
+ }
+
+ // Get the frames' textures
+ GLuint* texture_id[2] = {0, 0};
+ *format = mlt_image_glsl_texture;
+ mlt_frame_get_image( a_frame, (uint8_t**) &texture_id[0], format, width, height, 0 );
+ a_input->useFBOInput( chain, *texture_id[0] );
+ *format = mlt_image_glsl_texture;
+ mlt_frame_get_image( b_frame, (uint8_t**) &texture_id[1], format, width, height, 0 );
+ b_input->useFBOInput( chain, *texture_id[1] );
+
+ // Set resolution to that of the a_frame
+ *width = mlt_properties_get_int( a_props, "width" );
+ *height = mlt_properties_get_int( a_props, "height" );
+
+ // Setup rendering to an FBO
+ GlslManager* glsl = GlslManager::get_instance();
+ glsl_fbo fbo = glsl->get_fbo( *width, *height );
+ if ( output_format == mlt_image_glsl_texture ) {
+ glsl_texture texture = glsl->get_texture( *width, *height, GL_RGBA );
+
+ glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
+ check_error();
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+
+ GlslManager::render( service, chain, fbo->fbo, *width, *height );
+
+ glFinish();
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+
+ *image = (uint8_t*) &texture->texture;
+ mlt_frame_set_image( a_frame, *image, 0, NULL );
+ mlt_properties_set_data( properties, "movit.convert", texture, 0,
+ (mlt_destructor) GlslManager::release_texture, NULL );
+ *format = output_format;
+ }
+ else {
+ // Use a PBO to hold the data we read back with glReadPixels()
+ // (Intel/DRI goes into a slow path if we don't read to PBO)
+ GLenum gl_format = ( output_format == mlt_image_rgb24a || output_format == mlt_image_opengl )?
+ GL_RGBA : GL_RGB;
+ int img_size = *width * *height * ( gl_format == GL_RGB? 3 : 4 );
+ glsl_pbo pbo = glsl->get_pbo( img_size );
+ glsl_texture texture = glsl->get_texture( *width, *height, gl_format );
+
+ if ( fbo && pbo && texture ) {
+ // Set the FBO
+ glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
+ check_error();
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+
+ GlslManager::render( service, chain, fbo->fbo, *width, *height );
+
+ // Read FBO into PBO
+ glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, pbo->pbo );
+ check_error();
+ glBufferData( GL_PIXEL_PACK_BUFFER_ARB, img_size, NULL, GL_STREAM_READ );
+ check_error();
+ glReadPixels( 0, 0, *width, *height, gl_format, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0) );
+ check_error();
+
+ // Copy from PBO
+ uint8_t* buf = (uint8_t*) glMapBuffer( GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY );
+ check_error();
+
+ *format = gl_format == GL_RGBA ? mlt_image_rgb24a : mlt_image_rgb24;
+ *image = (uint8_t*) mlt_pool_alloc( img_size );
+ mlt_frame_set_image( a_frame, *image, img_size, mlt_pool_release );
+ memcpy( *image, buf, img_size );
+
+ // Release PBO and FBO
+ glUnmapBuffer( GL_PIXEL_PACK_BUFFER_ARB );
+ check_error();
+ glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, 0 );
+ check_error();
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ check_error();
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ check_error();
+ GlslManager::release_texture( texture );
+ }
+ else {
+ error = 1;
+ }
+ }
+ if ( fbo ) GlslManager::release_fbo( fbo );
+ mlt_service_lock( service );
+
+ return error;
+}
+
+static mlt_frame process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame )
+{
+ mlt_service service = MLT_TRANSITION_SERVICE(transition);
+
+ if ( !GlslManager::init_chain( service ) ) {
+ // Create the Movit effect chain
+ EffectChain* chain = GlslManager::get_chain( service );
+ mlt_profile profile = mlt_service_profile( service );
+ Input* b_input = new MltInput( profile->width, profile->height );
+ ImageFormat output_format;
+ output_format.color_space = COLORSPACE_sRGB;
+ output_format.gamma_curve = GAMMA_sRGB;
+ chain->add_input( b_input );
+ chain->add_output( output_format, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED );
+ chain->set_dither_bits( 8 );
+
+ Effect* effect = chain->add_effect( new OverlayEffect(),
+ GlslManager::get_input( service ), b_input );
+
+ // Save these new input on properties for get_image
+ mlt_properties_set_data( MLT_TRANSITION_PROPERTIES(transition),
+ "movit input B", b_input, 0, NULL, NULL );
+ }
+
+ // 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, get_image );
+
+ return a_frame;
+}
+
+extern "C"
+mlt_transition transition_movit_overlay_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_transition transition = NULL;
+ GlslManager* glsl = GlslManager::get_instance();
+ if ( glsl && ( transition = mlt_transition_new() ) ) {
+ transition->process = process;
+
+ // Inform apps and framework that this is a video only transition
+ mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "_transition_type", 1 );
+ }
+ return transition;
+}
--- /dev/null
+schema_version: 0.1
+type: transition
+identifier: movit.overlay
+title: Dissolve (GLSL)
+version: 1
+copyright: Dan Dennedy
+creator: Steinar H. Gunderson
+license: GPLv2
+language: en
+tags:
+ - Video
+description: >
+ A simple video overlay or alpha-compositing effect using the Porter-Duff over operation.
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/plus"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/plus"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/plus"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/plus"
ifneq ($(wildcard .depend),)
include .depend
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;
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
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, NULL, 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 ( transition )
+ mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "b_alpha", 1 );
}
if ( producer != NULL && transition != NULL )
mlt_properties frame_properties = MLT_FRAME_PROPERTIES( this );
mlt_position in = mlt_filter_get_in( filter );
mlt_position out = mlt_filter_get_out( filter );
- double consumer_ar = mlt_properties_get_double( frame_properties, "consumer_aspect_ratio" );
+ double consumer_ar = mlt_profile_sar( profile );
mlt_transition_set_in_and_out( transition, in, out );
if ( out > 0 ) {
mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( producer ), "length", out - in + 1 );
// 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 );
+ if ( mlt_frame_get_aspect_ratio( this ) == 0 )
+ mlt_frame_set_aspect_ratio( this, consumer_ar );
+ if ( mlt_frame_get_aspect_ratio( a_frame ) == 0 )
+ mlt_frame_set_aspect_ratio( a_frame, consumer_ar );
// Add the affine transition onto the frame stack
mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
mlt_transition_process( transition, a_frame, this );
- if (mlt_properties_get_int( properties, "use_normalised" ))
+ if ( mlt_properties_get_int( properties, "use_normalised" ) )
{
- // Use the normalised width & height from the a_frame
- *width = mlt_properties_get_int( MLT_FRAME_PROPERTIES( a_frame ), "normalised_width" );
- *height = mlt_properties_get_int( MLT_FRAME_PROPERTIES( a_frame ), "normalised_height" );
+ // Use the normalised width & height
+ mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
+ *width = profile->width;
+ *height = profile->height;
}
mlt_frame_get_image( a_frame, image, format, width, height, writable );
if ( this != NULL )
{
this->process = filter_process;
- mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "background", arg ? arg : "colour:black" );
+ mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "background", arg ? arg : "colour:0" );
}
return this;
}
//--------------------------------------------------------
//pointer to an interpolating function
-typedef int (*interpp)(unsigned char*, int, int, float, float, float, unsigned char*);
-
-//************************************
-//REMAP AN IMAGE
-
-//--------------------------------------------------------
-// vhs = vhodna slika velikosti wi x hi
-// izs = izhodna slika velikosti wo x ho
-// map = za vsak pixel izs pove, kje ga vzamemo is vhs
-// bgc = background color
-// interp = kazalec na interpolacijsko funkcijo
-void remap(int wi, int hi, int wo, int ho, unsigned char *vhs, unsigned char *izs, float *map, unsigned char bgc, interpp interp)
-{
- int i,j;
- float x,y;
-
- for (i=0;i<ho;i++)
- for (j=0;j<wo;j++)
- {
- x=map[2*(wo*i+j)];
- y=map[2*(wo*i+j)+1];
- if (x>0)
- interp(vhs,wi,hi,x,y,1.0,&izs[wo*i+j]);
- else
- izs[wo*i+j]=bgc; //background fill
- }
-}
-
-
-//--------------------------------------------------------
-//for four byte (int, 32 bit) values (packed RGB color)
-//little endian !!
-// vhs = vhodna slika velikosti wi x hi
-// izs = izhodna slika velikosti wo x ho
-// map = za vsak pixel izs pove, kje ga vzamemo is vhs
-// bgc = background color
-// interp = kazalec na interpolacijsko funkcijo
-void remap32(int wi, int hi, int wo, int ho, unsigned char *vhs, unsigned char *izs, float *map, uint32_t bgc, interpp interp)
-{
- int i,j;
- float x,y;
-
- for (i=0;i<ho;i++)
- for (j=0;j<wo;j++)
- {
- x=map[2*(wo*i+j)];
- y=map[2*(wo*i+j)+1];
- if (x>0)
- interp(vhs,wi,hi,x,y,1.0,&izs[4*(wo*i+j)]);
- else //background fill
- {
- izs[4*(wo*i+j)]=bgc;
- izs[4*(wo*i+j)+1]=bgc>>8;
- izs[4*(wo*i+j)+2]=bgc>>16;
- izs[4*(wo*i+j)+3]=bgc>>24;
- }
- }
-}
+//parameters:
+// source image
+// source width
+// source height
+// X coordinate
+// Y coordinate
+// opacity
+// destination image
+// flag to overwrite alpha channel
+typedef int (*interpp)(unsigned char*, int, int, float, float, float, unsigned char*, int);
//**************************************
//HERE BEGIN THE INTERPOLATION FUNCTIONS
// x,y tocka, za katero izracuna interpolirano vrednost
// o opacity
// *v interpolirana vrednost
-int interpNNpr_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpNNpr_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
//printf("u=%5.2f v=%5.2f ",x,y);
printf("u=%5.3f v=%5.3f ",x/(w-1),y/(h-1));
// x,y tocka, za katero izracuna interpolirano vrednost
// o opacity
// *v interpolirana vrednost
-int interpNN_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpNN_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
#ifdef TEST_XY_LIMITS
if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
// x,y tocka, za katero izracuna interpolirano vrednost
// o opacity
// *v interpolirana vrednost
-int interpNN_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpNN_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
#ifdef TEST_XY_LIMITS
if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
#endif
- v[3]= sl[(int)rintf(x)*4+(int)rintf(y)*4*w+3];
- float alpha = (float) v[3] / 255.0 * o;
- v[0]= v[0] * (1.0 - alpha) + sl[(int)rintf(x)*4+(int)rintf(y)*4*w] * alpha;
- v[1]= v[1] * (1.0 - alpha) + sl[(int)rintf(x)*4+(int)rintf(y)*4*w+1] * alpha;
- v[2]= v[2] * (1.0 - alpha) + sl[(int)rintf(x)*4+(int)rintf(y)*4*w+2] * alpha;
+ int p = (int) rintf(x) * 4 + (int) rintf(y) * 4 * w;
+ float alpha = (float) sl[p + 3] / 255.0 * o;
+ v[0]= v[0] * (1.0 - alpha) + sl[p] * alpha;
+ v[1]= v[1] * (1.0 - alpha) + sl[p + 1] * alpha;
+ v[2]= v[2] * (1.0 - alpha) + sl[p + 2] * alpha;
+ if (is_alpha) v[3] = sl[p +3];
return 0;
}
// x,y tocka, za katero izracuna interpolirano vrednost
// o opacity
// *v interpolirana vrednost
-int interpBL_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpBL_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int m,n,k,l;
float a,b;
//------------------------------------------------------
//bilinearna interpolacija
//za byte (char) vrednosti v packed color 32 bitnem formatu
-int interpBL_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpBL_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int m,n,k,l,n1,l1,k1;
float a,b;
a=sl[k+3]+(sl[k1+3]-sl[k+3])*(x-(float)m);
b=sl[l+3]+(sl[l1+3]-sl[n1+3])*(x-(float)m);
- v[3]=a+(b-a)*(y-(float)n);
- float alpha = (float) v[3] / 255.0 * o;
+ float alpha = a+(b-a)*(y-(float)n);
+ if (is_alpha) v[3] = alpha;
+ alpha = alpha / 255.0 * o;
a=sl[k]+(sl[k1]-sl[k])*(x-(float)m);
b=sl[l]+(sl[l1]-sl[n1])*(x-(float)m);
// x,y tocka, za katero izracuna interpolirano vrednost
// o opacity
// *v interpolirana vrednost
-int interpBC_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpBC_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int i,j,l,m,n;
float k;
//------------------------------------------------------
//bikubicna interpolacija "smooth"
//za byte (char) vrednosti v packed color 32 bitnem formatu
-int interpBC_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpBC_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int i,j,b,l,m,n;
float k;
p[i]=p[i]+(x-i-m)/j*(p[i]-p[i-1]);
if (p[3]<0.0) p[3]=0.0;
- if (p[3]>256.0) p[3]=255.0;
+ if (p[3]>255.0) p[3]=255.0;
- v[b]= v[b] * (1.0 - alpha) + p[3] * alpha;
- if (b == 3) alpha = v[b] / 255.0 * o;
+ if (b == 3) {
+ alpha = p[3] / 255.0 * o;
+ if (is_alpha) v[3] = p[3];
+ } else {
+ v[b] = v[b] * (1.0 - alpha) + p[3] * alpha;
+ }
}
return 0;
// *v interpolirana vrednost
//!!! ODKOD SUM??? (ze po eni rotaciji v interp_test !!)
//!!! v defish tega suma ni???
-int interpBC2_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpBC2_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int i,k,l,m,n;
float pp,p[4],wx[4],wy[4],xx;
//za byte (char) vrednosti v packed color 32 bitnem formatu
//!!! ODKOD SUM??? (ze po eni rotaciji v interp_test !!)
//!!! v defish tega suma ni???
-int interpBC2_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpBC2_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int b,i,k,l,m,n,u;
float pp,p[4],wx[4],wy[4],xx;
// x,y tocka, za katero izracuna interpolirano vrednost
// o opacity
// *v interpolirana vrednost
-int interpSP4_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpSP4_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int i,j,m,n;
float pp,p[4],wx[4],wy[4],xx;
//------------------------------------------------------
//spline 4x4 interpolacija
//za byte (char) vrednosti v packed color 32 bitnem formatu
-int interpSP4_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpSP4_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int i,j,m,n,b;
float pp,p[4],wx[4],wy[4],xx;
// *v interpolirana vrednost
//!!! PAZI, TOLE NE DELA CISTO PRAV ??? belina se siri
//!!! zaenkrat sem dodal fudge factor...
-int interpSP6_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpSP6_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int i,j,m,n;
float pp,p[6],wx[6],wy[6],xx;
//za byte (char) vrednosti v packed color 32 bitnem formatu
//!!! PAZI, TOLE NE DELA CISTO PRAV ??? belina se siri
//!!! zaenkrat sem dodal fudge factor...
-int interpSP6_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpSP6_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int i,b,j,m,n;
float pp,p[6],wx[6],wy[6],xx;
// x,y tocka, za katero izracuna interpolirano vrednost
// o opacity
// *v interpolirana vrednost
-int interpSC16_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpSC16_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int i,j,m,n;
float pp,p[16],wx[16],wy[16],xx,xxx,x1;
//------------------------------------------------------
//truncated sinc "lanczos" 16x16 interpolacija
//za byte (char) vrednosti v packed color 32 bitnem formatu
-int interpSC16_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v)
+int interpSC16_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
{
int i,j,m,b,n;
float pp,p[16],wx[16],wy[16],xx,xxx,x1;
/** Calculate real geometry.
*/
-static void geometry_calculate( mlt_transition this, const char *store, struct mlt_geometry_item_s *output, float position )
+static void geometry_calculate( mlt_transition transition, const char *store, struct mlt_geometry_item_s *output, float position )
{
- mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
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" );
}
-static mlt_geometry transition_parse_keys( mlt_transition this, const char *name, const char *store, int normalised_width, int normalised_height )
+static mlt_geometry transition_parse_keys( mlt_transition transition, 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 );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
// Try to fetch it first
mlt_geometry geometry = mlt_properties_get_data( properties, store, NULL );
// Determine length and obtain cycle
- mlt_position length = mlt_transition_get_length( this );
+ mlt_position length = mlt_transition_get_length( transition );
double cycle = mlt_properties_get_double( properties, "cycle" );
// Allow a geometry repeat cycle
return geometry;
}
-static mlt_geometry composite_calculate( mlt_transition this, struct mlt_geometry_item_s *result, int nw, int nh, float position )
+static mlt_geometry composite_calculate( mlt_transition transition, 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 );
+ mlt_geometry start = transition_parse_keys( transition, "geometry", "geometries", nw, nh );
// Do the calculation
- geometry_calculate( this, "geometries", result, position );
+ geometry_calculate( transition, "geometries", result, position );
return start;
}
-static inline float composite_calculate_key( mlt_transition this, const char *name, const char *store, int norm, float position )
+static inline float composite_calculate_key( mlt_transition transition, 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 );
+ transition_parse_keys( transition, name, store, norm, 0 );
// Do the calculation
- geometry_calculate( this, store, &result, position );
+ geometry_calculate( transition, store, &result, position );
return result.x;
}
}
affine_t;
-static void affine_init( float this[3][3] )
+static void affine_init( float affine[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;
+ affine[0][0] = 1;
+ affine[0][1] = 0;
+ affine[0][2] = 0;
+ affine[1][0] = 0;
+ affine[1][1] = 1;
+ affine[1][2] = 0;
+ affine[2][0] = 0;
+ affine[2][1] = 0;
+ affine[2][2] = 1;
}
// Multiply two this affine transform with that
-static void affine_multiply( float this[3][3], float that[3][3] )
+static void affine_multiply( float affine[3][3], float matrix[3][3] )
{
float output[3][3];
int i;
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];
+ output[i][j] = affine[i][0] * matrix[j][0] + affine[i][1] * matrix[j][1] + affine[i][2] * matrix[j][2];
+
+ affine[0][0] = output[0][0];
+ affine[0][1] = output[0][1];
+ affine[0][2] = output[0][2];
+ affine[1][0] = output[1][0];
+ affine[1][1] = output[1][1];
+ affine[1][2] = output[1][2];
+ affine[2][0] = output[2][0];
+ affine[2][1] = output[2][1];
+ affine[2][2] = output[2][2];
}
// Rotate by a given angle
-static void affine_rotate_x( float this[3][3], float angle )
+static void affine_rotate_x( float affine[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 );
+ float matrix[3][3];
+ matrix[0][0] = cos( angle * M_PI / 180 );
+ matrix[0][1] = 0 - sin( angle * M_PI / 180 );
+ matrix[0][2] = 0;
+ matrix[1][0] = sin( angle * M_PI / 180 );
+ matrix[1][1] = cos( angle * M_PI / 180 );
+ matrix[1][2] = 0;
+ matrix[2][0] = 0;
+ matrix[2][1] = 0;
+ matrix[2][2] = 1;
+ affine_multiply( affine, matrix );
}
-static void affine_rotate_y( float this[3][3], float angle )
+static void affine_rotate_y( float affine[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 );
+ float matrix[3][3];
+ matrix[0][0] = cos( angle * M_PI / 180 );
+ matrix[0][1] = 0;
+ matrix[0][2] = 0 - sin( angle * M_PI / 180 );
+ matrix[1][0] = 0;
+ matrix[1][1] = 1;
+ matrix[1][2] = 0;
+ matrix[2][0] = sin( angle * M_PI / 180 );
+ matrix[2][1] = 0;
+ matrix[2][2] = cos( angle * M_PI / 180 );
+ affine_multiply( affine, matrix );
}
-static void affine_rotate_z( float this[3][3], float angle )
+static void affine_rotate_z( float affine[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 );
+ float matrix[3][3];
+ matrix[0][0] = 1;
+ matrix[0][1] = 0;
+ matrix[0][2] = 0;
+ matrix[1][0] = 0;
+ matrix[1][1] = cos( angle * M_PI / 180 );
+ matrix[1][2] = sin( angle * M_PI / 180 );
+ matrix[2][0] = 0;
+ matrix[2][1] = - sin( angle * M_PI / 180 );
+ matrix[2][2] = cos( angle * M_PI / 180 );
+ affine_multiply( affine, matrix );
}
-static void affine_scale( float this[3][3], float sx, float sy )
+static void affine_scale( float affine[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 );
+ float matrix[3][3];
+ matrix[0][0] = sx;
+ matrix[0][1] = 0;
+ matrix[0][2] = 0;
+ matrix[1][0] = 0;
+ matrix[1][1] = sy;
+ matrix[1][2] = 0;
+ matrix[2][0] = 0;
+ matrix[2][1] = 0;
+ matrix[2][2] = 1;
+ affine_multiply( affine, matrix );
}
// Shear by a given value
-static void affine_shear( float this[3][3], float shear_x, float shear_y, float shear_z )
+static void affine_shear( float affine[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 );
+ float matrix[3][3];
+ matrix[0][0] = 1;
+ matrix[0][1] = tan( shear_x * M_PI / 180 );
+ matrix[0][2] = 0;
+ matrix[1][0] = tan( shear_y * M_PI / 180 );
+ matrix[1][1] = 1;
+ matrix[1][2] = tan( shear_z * M_PI / 180 );
+ matrix[2][0] = 0;
+ matrix[2][1] = 0;
+ matrix[2][2] = 1;
+ affine_multiply( affine, matrix );
}
-static void affine_offset( float this[3][3], float x, float y )
+static void affine_offset( float affine[3][3], float x, float y )
{
- this[0][2] += x;
- this[1][2] += y;
+ affine[0][2] += x;
+ affine[1][2] += y;
}
// Obtain the mapped x coordinate of the input
-static inline double MapX( float this[3][3], float x, float y )
+static inline double MapX( float affine[3][3], float x, float y )
{
- return this[0][0] * x + this[0][1] * y + this[0][2];
+ return affine[0][0] * x + affine[0][1] * y + affine[0][2];
}
// Obtain the mapped y coordinate of the input
-static inline double MapY( float this[3][3], float x, float y )
+static inline double MapY( float affine[3][3], float x, float y )
{
- return this[1][0] * x + this[1][1] * y + this[1][2];
+ return affine[1][0] * x + affine[1][1] * y + affine[1][2];
}
-static inline double MapZ( float this[3][3], float x, float y )
+static inline double MapZ( float affine[3][3], float x, float y )
{
- return this[2][0] * x + this[2][1] * y + this[2][2];
+ return affine[2][0] * x + affine[2][1] * y + affine[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, float max_width, float max_height )
+static void affine_max_output( float affine[3][3], float *w, float *h, float dz, float max_width, float max_height )
{
- int tlx = MapX( this, -max_width, max_height ) / dz;
- int tly = MapY( this, -max_width, max_height ) / dz;
- int trx = MapX( this, max_width, max_height ) / dz;
- int try = MapY( this, max_width, max_height ) / dz;
- int blx = MapX( this, -max_width, -max_height ) / dz;
- int bly = MapY( this, -max_width, -max_height ) / dz;
- int brx = MapX( this, max_width, -max_height ) / dz;
- int bry = MapY( this, max_width, -max_height ) / dz;
+ int tlx = MapX( affine, -max_width, max_height ) / dz;
+ int tly = MapY( affine, -max_width, max_height ) / dz;
+ int trx = MapX( affine, max_width, max_height ) / dz;
+ int try = MapY( affine, max_width, max_height ) / dz;
+ int blx = MapX( affine, -max_width, -max_height ) / dz;
+ int bly = MapY( affine, -max_width, -max_height ) / dz;
+ int brx = MapX( affine, max_width, -max_height ) / dz;
+ int bry = MapY( affine, max_width, -max_height ) / dz;
int max_x;
int max_y;
#define IN_RANGE( v, r ) ( v >= - r / 2 && v < r / 2 )
-static inline void get_affine( affine_t *affine, mlt_transition this, float position )
+static inline void get_affine( affine_t *affine, mlt_transition transition, float position )
{
- mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
int keyed = mlt_properties_get_int( properties, "keyed" );
if ( keyed == 0 )
}
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 );
- float o_x = composite_calculate_key( this, "ox", "ox_info", 0, position );
- float o_y = composite_calculate_key( this, "oy", "oy_info", 0, position );
+ float rotate_x = composite_calculate_key( transition, "rotate_x", "rotate_x_info", 360, position );
+ float rotate_y = composite_calculate_key( transition, "rotate_y", "rotate_y_info", 360, position );
+ float rotate_z = composite_calculate_key( transition, "rotate_z", "rotate_z_info", 360, position );
+ float shear_x = composite_calculate_key( transition, "shear_x", "shear_x_info", 360, position );
+ float shear_y = composite_calculate_key( transition, "shear_y", "shear_y_info", 360, position );
+ float shear_z = composite_calculate_key( transition, "shear_z", "shear_z_info", 360, position );
+ float o_x = composite_calculate_key( transition, "ox", "ox_info", 0, position );
+ float o_y = composite_calculate_key( transition, "oy", "oy_info", 0, position );
affine_rotate_x( affine->matrix, rotate_x );
affine_rotate_y( affine->matrix, rotate_y );
mlt_frame b_frame = mlt_frame_pop_frame( a_frame );
// Get the transition object
- mlt_transition this = mlt_frame_pop_service( a_frame );
+ mlt_transition transition = mlt_frame_pop_service( a_frame );
// Get the properties of the transition
- mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
// Get the properties of the a frame
mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame );
int b_height;
// Assign the current position
- mlt_position position = mlt_transition_get_position( this, a_frame );
+ mlt_position position = mlt_transition_get_position( transition, a_frame );
int mirror = mlt_properties_get_position( properties, "mirror" );
- int length = mlt_transition_get_length( this );
+ int length = mlt_transition_get_length( transition );
if ( mlt_properties_get_int( properties, "always_active" ) )
{
mlt_properties props = mlt_properties_get_data( b_props, "_producer", 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" );
+ mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) );
+ int normalised_width = profile->width;
+ int normalised_height = profile->height;
- double consumer_ar = mlt_properties_get_double( a_props, "consumer_aspect_ratio" );
+ double consumer_ar = mlt_profile_sar( mlt_service_profile( MLT_TRANSITION_SERVICE(transition) ) );
// Structures for geometry
struct mlt_geometry_item_s result;
mlt_frame_get_image( a_frame, image, format, width, height, 1 );
// Calculate the region now
- mlt_service_lock( MLT_TRANSITION_SERVICE( this ) );
- composite_calculate( this, &result, normalised_width, normalised_height, ( float )position );
- mlt_service_unlock( MLT_TRANSITION_SERVICE( this ) );
+ mlt_service_lock( MLT_TRANSITION_SERVICE( transition ) );
+ composite_calculate( transition, &result, normalised_width, normalised_height, ( float )position );
+ mlt_service_unlock( MLT_TRANSITION_SERVICE( transition ) );
// Fetch the b frame image
result.w = ( result.w * *width / normalised_width );
result.y = ( result.y * *height / normalised_height );
// Request full resolution of b frame image.
- b_width = mlt_properties_get_int( b_props, "real_width" );
- b_height = mlt_properties_get_int( b_props, "real_height" );
+ b_width = mlt_properties_get_int( b_props, "meta.media.width" );
+ b_height = mlt_properties_get_int( b_props, "meta.media.height" );
mlt_properties_set_int( b_props, "rescale_width", b_width );
mlt_properties_set_int( b_props, "rescale_height", b_height );
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" );
+ int b_alpha = mlt_properties_get_int( properties, "b_alpha" );
float geom_scale_x = (float) b_width / result.w;
float geom_scale_y = (float) b_height / result.h;
float cx = result.x + result.w / 2.0;
affine_init( affine.matrix );
// Compute the affine transform
- get_affine( &affine, this, ( float )position );
+ get_affine( &affine, transition, ( float )position );
dz = MapZ( affine.matrix, 0, 0 );
if ( ( int )abs( dz * 1000 ) < 25 )
{
{
scale_x = geom_scale_x * ( scale_x == 0 ? 1 : scale_x );
scale_y = geom_scale_x * ( scale_y == 0 ? 1 : scale_y );
+ scale_y *= b_ar / consumer_ar;
}
else
{
scale_x = geom_scale_y * ( scale_x == 0 ? 1 : scale_x );
scale_y = geom_scale_y * ( scale_y == 0 ? 1 : scale_y );
+ scale_x *= consumer_ar / b_ar;
}
- scale_x *= consumer_ar / b_ar;
}
if ( scale )
{
dx = MapX( affine.matrix, x, y ) / dz + x_offset;
dy = MapY( affine.matrix, x, y ) / dz + y_offset;
if ( dx >= 0 && dx < (b_width - 1) && dy >=0 && dy < (b_height - 1) )
- interp( b_image, b_width, b_height, dx, dy, result.mix/100.0, p );
+ interp( b_image, b_width, b_height, dx, dy, result.mix/100.0, p, b_alpha );
p += 4;
}
}
CFLAGS += -I../..
-LDFLAGS += -L../../framework -lmlt -lpthread -lm
+LDFLAGS += -L../../framework -lmlt -lpthread -lm -L../../mlt++ -lmlt++
include ../../../config.mak
include config.mak
TARGET = ../libmltqimage$(LIBSUF)
OBJS = factory.o producer_qimage.o producer_kdenlivetitle.o
-CPPOBJS = qimage_wrapper.o kdenlivetitle_wrapper.o
+CPPOBJS = qimage_wrapper.o \
+ kdenlivetitle_wrapper.o \
+ consumer_qglsl.o
-CXXFLAGS += $(CFLAGS) $(QTCXXFLAGS) $(EXIFCXXFLAGS) -Wno-deprecated
+ifdef GPL3
+ CPPOBJS += transition_vqm.o
+ CFLAGS += -DGPL3
+endif
+
+CXXFLAGS += $(CFLAGS) $(QTCXXFLAGS) $(EXIFCXXFLAGS) $(KDECXXFLAGS) -Wno-deprecated
-LDFLAGS += $(QTLIBS) $(EXIFLIBS)
+LDFLAGS += $(QTLIBS) $(EXIFLIBS) $(KDELIBS)
-ifdef USE_KDE
+ifdef USE_KDE3
LDFLAGS += -lkio
endif
rm -f $(OBJS) $(TARGET) $(CPPOBJS)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/qimage"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/qimage"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/qimage"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/qimage"
ifneq ($(wildcard .depend),)
include .depend
--kde-includedir - Location of KDE include directory [/usr/include/kde]
--exif-libdir - Location of libexif lib directory [/usr/lib]
--exif-includedir - Location of libexif include directory [/usr/include/libexif]
+ --without-kde - Don't link to KDE libraries
EOF
;;
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/lib"
- fi
- fi
+ qimage_includedir=
+ qimage_libdir=
if [ "$QTDIR" != "" ]
then
export force_qt3=
export qt4_found=
+ export without_kde=
for i in "$@"
do
--exif-libdir=* ) exif_libdir="${i#--exif-libdir=}" ;;
--exif-includedir=* ) exif_includedir="${i#--exif-includedir=}" ;;
--force-qt3 ) force_qt3="true" ;;
+ --without-kde ) without_kde="true" ;;
esac
done
fi
fi
- 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 QtCore QtGui QtXml QtSvg ) >> config.mak
- echo QTLIBS=$(pkg-config --libs QtCore QtGui QtXml QtSvg) >> config.mak
-
- elif [ -d "$qimage_libdir" -a -d "$qimage_includedir" ]
+ if [ -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" ] || [ -f "$qimage_libdir/libQtCore4.a" ] && [ "$force_qt3" = "" ]
then
echo "USE_QT4=1" >> config.mak
if [ -d "$qimage_libdir/QtGui.framework" ]
then
- echo QTCXXFLAGS=$(pkg-config --cflags QtCore QtGui QtXml QtSvg ) >> config.mak
- echo QTLIBS=$(pkg-config --libs QtCore QtGui QtXml QtSvg) >> config.mak
+ echo QTCXXFLAGS=$(pkg-config --cflags QtCore QtGui QtXml QtSvg QtOpenGL) >> config.mak
+ echo QTLIBS=$(pkg-config --libs QtCore QtGui QtXml QtSvg QtOpenGL) >> config.mak
elif [ -f "$qimage_libdir/libQtCore4.a" ]
then
echo QTCXXFLAGS=-I$qimage_includedir >> config.mak
- echo QTLIBS=-enable-auto-import -L$qimage_libdir -lQtCore4 -lQtGui4 -lQtXml4 -lQtSvg4 >> config.mak
+ echo QTLIBS=-Wl,-enable-auto-import -L$qimage_libdir -lQtCore4 -lQtGui4 -lQtXml4 -lQtSvg4 -lQtOpenGL4 >> config.mak
else
echo QTCXXFLAGS=-I$qimage_includedir >> config.mak
- echo QTLIBS=-L$qimage_libdir -lQtCore -lQtGui -lQtXml -lQtSvg >> config.mak
+ echo QTLIBS=-L$qimage_libdir -lQtCore -lQtGui -lQtXml -lQtSvg -lQtOpenGL >> config.mak
fi
- else
- if [ -d "$kde_includedir" ]
- then
- echo "#define USE_KDE" >> config.h
- echo "USE_KDE=1" >> config.mak
+ else
+ if [ "$without_kde" = "" ] && [ -d "$kde_includedir" ]
+ then
+ echo "#define USE_KDE3" >> config.h
+ echo "USE_KDE3=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 -lqt-mt >> config.mak
- else
- echo "qimage: KDE environment not found - disabling extra image formats"
+ else
+ echo "qimage: KDE environment not found or disabled by request - 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
fi
fi
else
- echo "qimage: QT environment not found - disabling"
- touch ../disable-qimage
+ 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 QtCore QtGui QtXml QtSvg QtOpenGL) >> config.mak
+ echo QTLIBS=$(pkg-config --libs QtCore QtGui QtXml QtSvg QtOpenGL) >> config.mak
+ else
+ echo "qimage: QT environment not found - disabling"
+ touch ../disable-qimage
+ fi
+ fi
+
+ if [ "$without_kde" = "" ]
+ then
+ kde4-config
+ if [ $? -eq 0 ] && [ "$qt4_found" != "" ]
+ then
+ # test if we have KDE4, required on some systems to get QImage extra formats (xcf, ...)
+ if [ "$kde_includedir" = "" ]
+ then
+ kde_includedir=`kde4-config --install include`
+ fi
+ if [ "$kde_libdir" = "" ]
+ then
+ kde_libdir=`kde4-config --install lib`
+ fi
+ if [ -d "$kde_includedir" ] && [ -d "$kde_libdir" ]
+ then
+ echo "KDE version 4.x detected, will enable extra image formats"
+ echo "#define USE_KDE4" >> config.h
+ echo "USE_KDE4=1" >> config.mak
+ echo KDECXXFLAGS=-I$kde_includedir >> config.mak
+ # the -L with kde4/devel is for Fedora
+ echo KDELIBS=-L$kde_libdir -L${kde_libdir}/kde4/devel -lkdecore >> config.mak
+ fi
+ fi
fi
+ [ "$gpl3" = "true" ] && echo GPL3=1 >> config.mak
+ exit 0
fi
--- /dev/null
+/*
+ * consumer_qglsl.cpp
+ * Copyright (C) 2012 Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 <framework/mlt.h>
+#include <QtGui/QApplication>
+#include <QtCore/QLocale>
+#include <QtOpenGL/QGLWidget>
+
+static void onThreadStarted(mlt_properties owner, mlt_consumer consumer)
+{
+ mlt_service service = MLT_CONSUMER_SERVICE(consumer);
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES(consumer);
+ mlt_filter filter = (mlt_filter) mlt_properties_get_data(properties, "glslManager", NULL);
+ mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter);
+ QApplication* app = qApp;
+
+ mlt_log_debug(service, "%s\n", __FUNCTION__);
+#ifdef linux
+ if ( getenv("DISPLAY") == 0 ) {
+ mlt_log_error(service, "The qglsl consumer requires a X11 environment.\nPlease either run melt from an X session or use a fake X server like xvfb:\nxvfb-run -a melt (...)\n" );
+ } else
+#endif
+ if (!app) {
+ int argc = 1;
+ char* argv[1];
+ argv[0] = (char*) "MLT qglsl consumer";
+ app = new QApplication(argc, argv);
+ const char *localename = mlt_properties_get_lcnumeric(properties);
+ QLocale::setDefault(QLocale(localename));
+ }
+ QGLWidget* renderContext = new QGLWidget;
+ renderContext->resize(0, 0);
+ renderContext->show();
+ mlt_events_fire(filter_properties, "init glsl", NULL);
+ if (!mlt_properties_get_int(filter_properties, "glsl_supported")) {
+ mlt_log_fatal(service,
+ "OpenGL Shading Language rendering is not supported on this machine.\n" );
+ mlt_events_fire(properties, "consumer-fatal-error", NULL);
+ }
+ else {
+ mlt_properties_set_data(properties, "qglslRenderContext", renderContext, 0, NULL, NULL);
+ }
+}
+
+static void onCleanup(mlt_properties owner, mlt_consumer consumer)
+{
+ QGLWidget* renderContext = (QGLWidget*) mlt_properties_get_data(
+ MLT_CONSUMER_PROPERTIES(consumer), "qglslRenderContext", NULL);
+ if (renderContext)
+ renderContext->makeCurrent();
+ delete renderContext;
+ mlt_properties_set_data(MLT_CONSUMER_PROPERTIES(consumer),
+ "qglslRenderContext", NULL, 0, NULL, NULL);
+}
+
+extern "C" {
+
+mlt_consumer consumer_qglsl_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_consumer consumer = mlt_factory_consumer(profile, "multi", arg);
+ if (consumer) {
+ mlt_filter filter = mlt_factory_filter(profile, "glsl.manager", 0);
+ if (filter) {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES(consumer);
+ mlt_properties_set_data(properties, "glslManager", filter, 0, (mlt_destructor) mlt_filter_close, NULL);
+ mlt_events_register( properties, "consumer-cleanup", NULL );
+ mlt_events_listen(properties, consumer, "consumer-thread-started", (mlt_listener) onThreadStarted);
+ mlt_events_listen(properties, consumer, "consumer-cleanup", (mlt_listener) onCleanup);
+ return consumer;
+ }
+ mlt_consumer_close(consumer);
+ }
+ return NULL;
+}
+
+}
#include <limits.h>
#include <framework/mlt.h>
+extern mlt_consumer consumer_qglsl_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
extern mlt_producer producer_qimage_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
extern mlt_producer producer_kdenlivetitle_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_transition transition_vqm_init( mlt_profile profile, mlt_service_type type, const char *id, void *arg );
static mlt_properties metadata( mlt_service_type type, const char *id, void *data )
{
MLT_REPOSITORY
{
+ MLT_REGISTER( consumer_type, "qglsl", consumer_qglsl_init );
MLT_REGISTER( producer_type, "qimage", producer_qimage_init );
MLT_REGISTER( producer_type, "kdenlivetitle", producer_kdenlivetitle_init );
MLT_REGISTER_METADATA( producer_type, "qimage", metadata, "producer_qimage.yml" );
MLT_REGISTER_METADATA( producer_type, "kdenlivetitle", metadata, "producer_kdenlivetitle.yml" );
+#ifdef GPL3
+ MLT_REGISTER( transition_type, "vqm", transition_vqm_init );
+ MLT_REGISTER_METADATA( transition_type, "vqm", metadata, "transition_vqm.yml" );
+#endif
}
#endif
static QApplication *app = NULL;
+Q_DECLARE_METATYPE(QTextCursor);
class ImageItem: public QGraphicsItem
{
}
QGraphicsTextItem *txt = scene->addText(text, font);
if (txtProperties.namedItem("font-outline").nodeValue().toDouble()>0.0){
- QTextCursor cursor(txt->document());
+ QTextDocument *doc = txt->document();
+ // Make sure some that the text item does not request refresh by itself
+ doc->blockSignals(true);
+ QTextCursor cursor(doc);
cursor.select(QTextCursor::Document);
QTextCharFormat format;
format.setTextOutline(
mlt_properties_set_int( producer_props, "_animated", 1 );
QStringList effetData = QStringList() << "typewriter" << text << txtProperties.namedItem( "typewriter" ).nodeValue();
txt->setData(0, effetData);
+ if ( !txtProperties.namedItem( "textwidth" ).isNull() )
+ txt->setData( 1, txtProperties.namedItem( "textwidth" ).nodeValue() );
}
if ( txtProperties.namedItem( "alignment" ).isNull() == false )
{
mlt_log_panic( MLT_PRODUCER_SERVICE( producer ), "Error, cannot render titles without an X11 environment.\nPlease either run melt from an X session or use a fake X server like xvfb:\nxvfb-run -a melt (...)\n" );
pthread_mutex_unlock( &self->mutex );
- exit(1);
return;
}
#endif
const char *localename = mlt_properties_get_lcnumeric( MLT_SERVICE_PROPERTIES( MLT_PRODUCER_SERVICE( producer ) ) );
QLocale::setDefault( QLocale( localename ) );
}
+ qRegisterMetaType<QTextCursor>( "QTextCursor" );
}
scene = new QGraphicsScene();
scene->setItemIndexMethod( QGraphicsScene::NoIndex );
QTextCharFormat format = cursor.charFormat();
cursor.select(QTextCursor::Document);
QString txt = params.at( 1 ).left( interval );
- // If the string to insert is empty, insert a space so that we don't loose
+ // If the string to insert is empty, insert a space / linebreak so that we don't loose
// formatting infos for the next iterations
- cursor.insertText(txt.isEmpty() ? " " : txt, format);
+ int lines = params.at( 1 ).count( '\n' );
+ QString empty = " ";
+ for (int i = 0; i < lines; i++)
+ empty.append( "\n " );
+ cursor.insertText( txt.isEmpty() ? empty : txt, format );
+ if ( !titem->data( 1 ).isNull() )
+ titem->setTextWidth( titem->data( 1 ).toDouble() );
}
}
}
scene->render( &p1, source, end, Qt::IgnoreAspectRatio );
}
else {
- double percentage = position / anim_out;
+ double percentage = 0;
+ if ( position && anim_out )
+ percentage = position / anim_out;
QPointF topleft = start.topLeft() + ( end.topLeft() - start.topLeft() ) * percentage;
QPointF bottomRight = start.bottomRight() + ( end.bottomRight() - start.bottomRight() ) * percentage;
const QRectF r1( topleft, bottomRight );
int size = 0;
long lSize;
- fseek (f , 0 , SEEK_END);
+ if ( fseek (f , 0 , SEEK_END) < 0 )
+ goto error;
lSize = ftell (f);
+ if ( lSize <= 0 )
+ goto error;
rewind (f);
char *infile = (char*) mlt_pool_alloc(lSize);
- size=fread(infile,1,lSize,f);
- infile[size] = '\0';
+ if ( infile )
+ {
+ size = fread(infile,1,lSize,f);
+ if ( size )
+ {
+ infile[size] = '\0';
+ mlt_properties_set(properties, "_xmldata", infile);
+ }
+ mlt_pool_release( infile );
+ }
+error:
fclose(f);
- mlt_properties_set(properties, "_xmldata", infile);
- mlt_pool_release( infile );
}
}
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 );
/* Allocate the image */
*format = mlt_image_rgb24a;
- mlt_position time = mlt_producer_position( &this->parent ) + mlt_producer_get_in( &this->parent );
if ( mlt_properties_get_int( producer_props, "force_reload" ) ) {
- if (mlt_properties_get_int( producer_props, "force_reload" ) > 1) read_xml(producer_props);
+ if ( mlt_properties_get_int( producer_props, "force_reload" ) > 1 ) read_xml( producer_props );
mlt_properties_set_int( producer_props, "force_reload", 0 );
- drawKdenliveTitle( this, frame, *width, *height, time, 1);
+ drawKdenliveTitle( this, frame, *width, *height, mlt_frame_original_position( frame ), 1);
}
- else drawKdenliveTitle( this, frame, *width, *height, time, 0);
+ else drawKdenliveTitle( this, frame, *width, *height, mlt_frame_original_position( frame ), 0);
// Get width and height (may have changed during the refresh)
*width = mlt_properties_get_int( properties, "width" );
mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
/* Set producer-specific frame properties */
- mlt_profile profile = mlt_service_profile ( MLT_PRODUCER_SERVICE( producer ) ) ;
- mlt_properties_set_int( properties, "progressive", ( profile ) ? profile->progressive : 1 );
- mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) );
+ mlt_properties_pass_list( properties, producer_props, "progressive, aspect_ratio" );
/* Push the get_image method */
mlt_frame_push_get_image( *frame, producer_get_image );
/* fprintf(stderr, ":::::::::::: CREATE TITLE\n"); */
/* Create a new producer object */
- producer_ktitle this = calloc( sizeof( struct producer_ktitle_s ), 1 );
+ producer_ktitle this = calloc( 1, sizeof( struct producer_ktitle_s ) );
if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 )
{
mlt_producer producer = &this->parent;
producer->get_frame = producer_get_frame;
producer->close = ( mlt_destructor )producer_close;
mlt_properties_set( properties, "resource", filename );
- //mlt_properties_set_int( properties, "aspect_ratio", 1 );
+ mlt_properties_set_int( properties, "progressive", 1 );
read_xml(properties);
return producer;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <ctype.h>
-static void load_filenames( producer_qimage this, mlt_properties producer_properties );
+static void load_filenames( producer_qimage self, 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 )
+ producer_qimage self = calloc( 1, sizeof( struct producer_qimage_s ) );
+ if ( self != NULL && mlt_producer_init( &self->parent, self ) == 0 )
{
- mlt_producer producer = &this->parent;
+ mlt_producer producer = &self->parent;
// Get the properties interface
- mlt_properties properties = MLT_PRODUCER_PROPERTIES( &this->parent );
+ mlt_properties properties = MLT_PRODUCER_PROPERTIES( &self->parent );
- // Callback registration
-#ifdef USE_KDE
+ // Initialize KDE image plugins
init_qimage();
-#endif
+
+ // Callback registration
producer->get_frame = producer_get_frame;
producer->close = ( mlt_destructor )producer_close;
mlt_properties_set_int( properties, "ttl", 25 );
mlt_properties_set_int( properties, "aspect_ratio", 1 );
mlt_properties_set_int( properties, "progressive", 1 );
-
+ mlt_properties_set_int( properties, "seekable", 1 );
+
// Validate the resource
if ( filename )
- load_filenames( this, properties );
- if ( this->count )
+ load_filenames( self, properties );
+ if ( self->count )
{
mlt_frame frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
if ( frame )
{
mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
- mlt_properties_set_data( frame_properties, "producer_qimage", this, 0, NULL, NULL );
+ mlt_properties_set_data( frame_properties, "producer_qimage", self, 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 );
+ refresh_qimage( self, frame );
+ mlt_cache_item_close( self->qimage_cache );
mlt_frame_close( frame );
}
}
- if ( this->current_width == 0 )
+ if ( self->current_width == 0 )
{
producer_close( producer );
producer = NULL;
}
- if ( producer )
- pthread_mutex_init( &this->mutex, NULL );
return producer;
}
- free( this );
+ free( self );
return NULL;
}
-static void load_filenames( producer_qimage this, mlt_properties producer_properties )
+static int load_svg( producer_qimage self, mlt_properties properties, const char *filename )
{
- char *filename = mlt_properties_get( producer_properties, "resource" );
- this->filenames = mlt_properties_new( );
+ int result = 0;
// Read xml string
if ( strstr( filename, "<svg" ) )
{
- make_tempfile( this, filename );
+ make_tempfile( self, filename );
+ result = 1;
}
- // Obtain filenames
- else if ( strchr( filename, '%' ) != NULL )
+ return result;
+}
+
+static int load_sequence_sprintf( producer_qimage self, mlt_properties properties, const char *filename )
+{
+ int result = 0;
+
+ // Obtain filenames with pattern
+ if ( strchr( filename, '%' ) != NULL )
{
// handle picture sequences
- int i = mlt_properties_get_int( producer_properties, "begin" );
+ int i = mlt_properties_get_int( properties, "begin" );
int gap = 0;
char full[1024];
int keyvalue = 0;
if ( stat( full, &buf ) == 0 )
{
sprintf( key, "%d", keyvalue ++ );
- mlt_properties_set( this->filenames, key, full );
+ mlt_properties_set( self->filenames, key, full );
gap = 0;
}
else
gap ++;
}
}
- if ( mlt_properties_count( this->filenames ) > 0 )
- mlt_properties_set_int( producer_properties, "ttl", 1 );
+ if ( mlt_properties_count( self->filenames ) > 0 )
+ {
+ mlt_properties_set_int( properties, "ttl", 1 );
+ result = 1;
+ }
}
- else if ( strstr( filename, "/.all." ) != NULL )
+ return result;
+}
+
+static int load_sequence_deprecated( producer_qimage self, mlt_properties properties, const char *filename )
+{
+ int result = 0;
+ const char *start;
+
+ // Obtain filenames with pattern containing a begin value, e.g. foo%1234d.png
+ if ( ( start = strchr( filename, '%' ) ) )
+ {
+ const char *end = ++start;
+ while ( isdigit( *end ) ) end++;
+ if ( end > start && ( end[0] == 'd' || end[0] == 'i' || end[0] == 'u' ) )
+ {
+ int n = end - start;
+ char *s = calloc( 1, n + 1 );
+ strncpy( s, start, n );
+ mlt_properties_set( properties, "begin", s );
+ free( s );
+ s = calloc( 1, strlen( filename ) + 2 );
+ strncpy( s, filename, start - filename );
+ sprintf( s + ( start - filename ), ".%d%s", n, end );
+ result = load_sequence_sprintf( self, properties, s );
+ free( s );
+ }
+ }
+ return result;
+}
+
+static int load_sequence_querystring( producer_qimage self, mlt_properties properties, const char *filename )
+{
+ int result = 0;
+
+ // Obtain filenames with pattern and begin value in query string
+ if ( strchr( filename, '%' ) && strchr( filename, '?' ) )
+ {
+ // Split filename into pattern and query string
+ char *s = strdup( filename );
+ char *querystring = strrchr( s, '?' );
+ *querystring++ = '\0';
+ if ( strstr( filename, "begin=" ) )
+ mlt_properties_set( properties, "begin", strstr( querystring, "begin=" ) + 6 );
+ else if ( strstr( filename, "begin:" ) )
+ mlt_properties_set( properties, "begin", strstr( querystring, "begin:" ) + 6 );
+ // Coerce to an int value so serialization does not have any extra query string cruft
+ mlt_properties_set_int( properties, "begin", mlt_properties_get_int( properties, "begin" ) );
+ result = load_sequence_sprintf( self, properties, s );
+ free( s );
+ }
+ return result;
+}
+
+static int load_folder( producer_qimage self, mlt_properties properties, const char *filename )
+{
+ int result = 0;
+
+ // Obtain filenames within folder
+ if ( strstr( filename, "/.all." ) != NULL )
{
char wildcard[ 1024 ];
char *dir_name = strdup( filename );
*( strstr( dir_name, "/.all." ) + 1 ) = '\0';
sprintf( wildcard, "*%s", extension );
- mlt_properties_dir_list( this->filenames, dir_name, wildcard, 1 );
+ mlt_properties_dir_list( self->filenames, dir_name, wildcard, 1 );
free( dir_name );
+ result = 1;
}
- else
+ return result;
+}
+
+static void load_filenames( producer_qimage self, mlt_properties properties )
+{
+ char *filename = mlt_properties_get( properties, "resource" );
+ self->filenames = mlt_properties_new( );
+
+ if (!load_svg( self, properties, filename ) &&
+ !load_sequence_querystring( self, properties, filename ) &&
+ !load_sequence_sprintf( self, properties, filename ) &&
+ !load_sequence_deprecated( self, properties, filename ) &&
+ !load_folder( self, properties, filename ) )
{
- mlt_properties_set( this->filenames, "0", filename );
+ mlt_properties_set( self->filenames, "0", filename );
}
-
- this->count = mlt_properties_count( this->filenames );
+ self->count = mlt_properties_count( self->filenames );
}
static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
{
int error = 0;
- // Obtain properties of frame
+ // Obtain properties of frame and producer
mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
-
- // Obtain the producer for this frame
- producer_qimage this = mlt_properties_get_data( properties, "producer_qimage", NULL );
+ producer_qimage self = mlt_properties_get_data( properties, "producer_qimage", NULL );
+ mlt_producer producer = &self->parent;
*width = mlt_properties_get_int( properties, "rescale_width" );
*height = mlt_properties_get_int( properties, "rescale_height" );
- mlt_service_lock( MLT_PRODUCER_SERVICE( &this->parent ) );
+ mlt_service_lock( MLT_PRODUCER_SERVICE( &self->parent ) );
// Refresh the image
- refresh_qimage( this, frame, *width, *height );
+ self->qimage_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.qimage" );
+ self->qimage = mlt_cache_item_data( self->qimage_cache, NULL );
+ self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.image" );
+ self->current_image = mlt_cache_item_data( self->image_cache, NULL );
+ self->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.alpha" );
+ self->current_alpha = mlt_cache_item_data( self->alpha_cache, NULL );
+ refresh_image( self, frame, *format, *width, *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" );
- *format = this->has_alpha ? mlt_image_rgb24a : mlt_image_rgb24;
+ *format = self->format;
// 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 )
+ if ( self->current_image )
{
// Clone the image and the alpha
- int image_size = this->current_width * ( this->current_height + 1 ) * ( this->has_alpha ? 4 :3 );
+ int image_size = mlt_image_format_size( self->format, self->current_width, self->current_height, NULL );
uint8_t *image_copy = mlt_pool_alloc( image_size );
- memcpy( image_copy, this->current_image, image_size );
+ memcpy( image_copy, self->current_image, image_size );
// Now update properties so we free the copy after
mlt_frame_set_image( frame, image_copy, image_size, mlt_pool_release );
// We're going to pass the copy on
*buffer = image_copy;
- mlt_log_debug( MLT_PRODUCER_SERVICE( &this->parent ), "%dx%d (%s)\n",
- this->current_width, this->current_height, mlt_image_format_name( *format ) );
+ mlt_log_debug( MLT_PRODUCER_SERVICE( &self->parent ), "%dx%d (%s)\n",
+ self->current_width, self->current_height, mlt_image_format_name( *format ) );
+ // Clone the alpha channel
+ if ( self->current_alpha )
+ {
+ image_copy = mlt_pool_alloc( self->current_width * self->current_height );
+ memcpy( image_copy, self->current_alpha, self->current_width * self->current_height );
+ mlt_frame_set_alpha( frame, image_copy, self->current_width * self->current_height, mlt_pool_release );
+ }
}
else
{
}
// Release references and locks
- pthread_mutex_unlock( &this->mutex );
- mlt_cache_item_close( this->image_cache );
- mlt_service_unlock( MLT_PRODUCER_SERVICE( &this->parent ) );
+ mlt_cache_item_close( self->qimage_cache );
+ mlt_cache_item_close( self->image_cache );
+ mlt_cache_item_close( self->alpha_cache );
+ mlt_service_unlock( MLT_PRODUCER_SERVICE( &self->parent ) );
return error;
}
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;
+ producer_qimage self = 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 );
+ if ( self->filenames == NULL && mlt_properties_get( producer_properties, "resource" ) != NULL )
+ load_filenames( self, producer_properties );
// Generate a frame
*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
- if ( *frame != NULL && this->count > 0 )
+ if ( *frame != NULL && self->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 );
+ mlt_properties_set_data( properties, "producer_qimage", self, 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 );
+ self->qimage_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.qimage" );
+ self->qimage = mlt_cache_item_data( self->qimage_cache, NULL );
+ refresh_qimage( self, *frame );
+ mlt_cache_item_close( self->qimage_cache );
// Set producer-specific frame properties
mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( producer_properties, "progressive" ) );
static void producer_close( mlt_producer parent )
{
- producer_qimage this = parent->child;
- pthread_mutex_destroy( &this->mutex );
+ producer_qimage self = parent->child;
parent->close = NULL;
mlt_service_cache_purge( MLT_PRODUCER_SERVICE(parent) );
mlt_producer_close( parent );
- mlt_properties_close( this->filenames );
- free( this );
+ mlt_properties_close( self->filenames );
+ free( self );
}
type: producer
identifier: qimage
title: Qt QImage
-version: 1
+version: 2
copyright: Visual Media ?
creator: Charles Yates
license: GPLv2
language: en
tags:
- Video
+description: >
+ A still graphics to video generator using Qt QImage
+notes: >
+ QImage 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.
+parameters:
+ - identifier: argument
+ title: File
+ type: string
+ description: >
+ The name of a graphics file loadable by Qt.
+
+ If "%" in filename, the filename is used with sprintf to generate a
+ filename from a counter for multi-file/flipbook animation. The file
+ sequence ends when numeric discontinuity exceeds 100.
+
+ If the file sequence does not begin within the count of 100 you
+ can pass the begin property like a query string parameter, for
+ example: anim-%04d.png?begin=1000.
+
+ If filename contains "/.all.", suffix with an extension to load all
+ pictures with matching extension from a directory.
+
+ If filename contains the string "<svg", then qimage tries to load the
+ filename as inline SVG XML, which is convenient for melt commands.
+ readonly: no
+ required: yes
+ mutable: no
+ widget: fileopen
+
+ - identifier: begin
+ title: Begin
+ type: integer
+ description: When using an image sequence, this sets the starting number.
+ readonly: no
+ minimum: 0
+ mutable: no
+ widget: spinner
+
+ - identifier: ttl
+ title: Time-to-live
+ type: integer
+ description: How long (in frames) to repeat each picture in file sequences.
+ readonly: no
+ default: 25
+ minimum: 0
+ mutable: yes
+ widget: spinner
+
+ - identifier: meta.media.width
+ title: Real width
+ type: integer
+ description: The original, unscaled width of the rendered image.
+ readonly: yes
+
+ - identifier: meta.media.height
+ title: Real height
+ type: integer
+ description: The original, unscaled height of the rendered image.
+ readonly: yes
+
+ - identifier: width
+ title: Width
+ type: integer
+ description: The last requested scaled image width.
+ readonly: yes
+
+ - identifier: height
+ title: Height
+ type: integer
+ description: The last requested scaled image height.
+ readonly: yes
+
+ - identifier: force_reload
+ type: integer
+ description: >
+ Reload the file instead of using its cached image. This property
+ automatically resets itself once it has been set 1 and processed.
+ minimum: 0
+ maximum: 1
+ mutable: yes
+
+ - identifier: disable_exif
+ title: Disable auto-rotation
+ type: integer
+ minimum: 0
+ maximum: 1
+ widget: checkbox
+
+ - identifier: force_aspect_ratio
+ title: Sample aspect ratio
+ type: float
+ description: Optionally override a (mis)detected aspect ratio
+ mutable: yes
+
#include <qimage.h>
#include <qmutex.h>
-#ifdef USE_KDE
+#ifdef USE_KDE3
#include <kinstance.h>
#include <kimageio.h>
#endif
-
#endif
+#ifdef USE_KDE4
+#include <kcomponentdata.h>
+#endif
#ifdef USE_QT4
#include <QtGui/QImage>
#include <QtCore/QSysInfo>
+#include <QtGui/QApplication>
#include <QtCore/QMutex>
#include <QtCore/QtEndian>
#include <QtCore/QTemporaryFile>
+#include <QtCore/QLocale>
#endif
#ifdef USE_EXIF
#endif
#include <cmath>
+#include <unistd.h>
extern "C" {
#include <framework/mlt_pool.h>
#include <framework/mlt_cache.h>
-#ifdef USE_KDE
+#ifdef USE_KDE4
+static KComponentData *instance = 0L;
+#elif USE_KDE3
static KInstance *instance = 0L;
#endif
+static QApplication *app = NULL;
+
static void qimage_delete( void *data )
{
QImage *image = ( QImage * )data;
delete image;
image = NULL;
-#ifdef USE_KDE
+#if defined(USE_KDE3) || defined(USE_KDE4)
if (instance) delete instance;
instance = 0L;
#endif
-}
-static QMutex g_mutex;
+}
-#ifdef USE_KDE
void init_qimage()
{
- if (!instance) {
- instance = new KInstance("qimage_prod");
+#ifdef USE_KDE4
+ if ( !instance ) {
+ instance = new KComponentData( "qimage_prod" );
+ }
+#elif defined(USE_KDE3)
+ if ( !instance ) {
+ instance = new KInstance( "qimage_prod" );
KImageIO::registerFormats();
}
+#endif
+
}
+
+static QImage* reorient_with_exif( producer_qimage self, int image_idx, QImage *qimage )
+{
+#ifdef USE_EXIF
+ mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( &self->parent );
+ ExifData *d = exif_data_new_from_file( mlt_properties_get_value( self->filenames, image_idx ) );
+ ExifEntry *entry;
+ int exif_orientation = 0;
+ /* get orientation and rotate image accordingly if necessary */
+ if (d) {
+ if ( ( entry = exif_content_get_entry ( d->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION ) ) )
+ exif_orientation = exif_get_short (entry->data, exif_data_get_byte_order (d));
+
+ /* Free the EXIF data */
+ exif_data_unref(d);
+ }
+
+ // Remember EXIF value, might be useful for someone
+ mlt_properties_set_int( producer_props, "_exif_orientation" , exif_orientation );
+
+ if ( exif_orientation > 1 )
+ {
+ // Rotate image according to exif data
+ QImage processed;
+ QMatrix matrix;
+
+ switch ( exif_orientation ) {
+ case 2:
+ matrix.scale( -1, 1 );
+ break;
+ case 3:
+ matrix.rotate( 180 );
+ break;
+ case 4:
+ matrix.scale( 1, -1 );
+ break;
+ case 5:
+ matrix.rotate( 270 );
+ matrix.scale( -1, 1 );
+ break;
+ case 6:
+ matrix.rotate( 90 );
+ break;
+ case 7:
+ matrix.rotate( 90 );
+ matrix.scale( -1, 1 );
+ break;
+ case 8:
+ matrix.rotate( 270 );
+ break;
+ }
+ processed = qimage->transformed( matrix );
+ delete qimage;
+ qimage = new QImage( processed );
+ }
#endif
+ return qimage;
+}
-void refresh_qimage( producer_qimage self, mlt_frame frame, int width, int height )
+int refresh_qimage( producer_qimage self, mlt_frame frame )
{
- // Obtain properties of frame
+ // Obtain properties of frame and producer
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<QImage*>( 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<uint8_t*>( mlt_cache_item_data( self->image_cache, NULL ) );
-
// Check if user wants us to reload the image
if ( mlt_properties_get_int( producer_props, "force_reload" ) )
{
- qimage = NULL;
+ self->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" );
+ mlt_position position = mlt_frame_original_position( frame );
position += mlt_producer_get_in( producer );
// Image index
char image_key[ 10 ];
sprintf( image_key, "%d", image_idx );
- g_mutex.lock();
-
- // Check if the frame is already loaded
- if ( use_cache )
+ int disable_exif = mlt_properties_get_int( producer_props, "disable_exif" );
+
+
+ if ( app == NULL )
{
- if ( cache == NULL )
+ if ( qApp )
{
- cache = mlt_properties_new( );
- mlt_properties_set_data( producer_props, "_cache", cache, 0, ( mlt_destructor )mlt_properties_close, NULL );
+ app = qApp;
}
-
- mlt_frame cached = ( mlt_frame )mlt_properties_get_data( cache, image_key, NULL );
-
- if ( cached )
+ else
{
- 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->has_alpha = mlt_properties_get_int( cached_props, "alpha" );
-
- if ( width != 0 && ( width != self->current_width || height != self->current_height ) )
- self->current_image = NULL;
+#ifdef linux
+ if ( getenv("DISPLAY") == 0 )
+ {
+ mlt_log_panic( MLT_PRODUCER_SERVICE( producer ), "Error, cannot render titles without an X11 environment.\nPlease either run melt from an X session or use a fake X server like xvfb:\nxvfb-run -a melt (...)\n" );
+ return -1;
+ }
+#endif
+ int argc = 1;
+ char* argv[1];
+ argv[0] = (char*) "xxx";
+ app = new QApplication( argc, argv );
+ const char *localename = mlt_properties_get_lcnumeric( MLT_SERVICE_PROPERTIES( MLT_PRODUCER_SERVICE( producer ) ) );
+ QLocale::setDefault( QLocale( localename ) );
}
}
- int disable_exif = mlt_properties_get_int( producer_props, "disable_exif" );
-
- // optimization for subsequent iterations on single pictur
- if ( width != 0 && ( image_idx != self->image_idx || width != self->current_width || height != self->current_height ) )
- self->current_image = NULL;
if ( image_idx != self->qimage_idx )
- qimage = NULL;
-
- if ( !qimage || mlt_properties_get_int( producer_props, "_disable_exif" ) != disable_exif)
+ self->qimage = NULL;
+ if ( !self->qimage || mlt_properties_get_int( producer_props, "_disable_exif" ) != disable_exif )
{
self->current_image = NULL;
- qimage = new QImage( mlt_properties_get_value( self->filenames, image_idx ) );
+ QImage *qimage = new QImage( QString::fromUtf8( mlt_properties_get_value( self->filenames, image_idx ) ) );
+ self->qimage = qimage;
if ( !qimage->isNull( ) )
{
-#ifdef USE_EXIF
// Read the exif value for this file
- if ( disable_exif == 0) {
- ExifData *d = exif_data_new_from_file( mlt_properties_get_value( self->filenames, image_idx ) );
- ExifEntry *entry;
- int exif_orientation = 0;
- /* get orientation and rotate image accordingly if necessary */
- if (d) {
- if ( ( entry = exif_content_get_entry ( d->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION ) ) )
- exif_orientation = exif_get_short (entry->data, exif_data_get_byte_order (d));
-
- /* Free the EXIF data */
- exif_data_unref(d);
- }
-
- // Remember EXIF value, might be useful for someone
- mlt_properties_set_int( producer_props, "_exif_orientation" , exif_orientation );
-
- if ( exif_orientation > 1 )
- {
- // Rotate image according to exif data
- QImage processed;
- QMatrix matrix;
-
- switch ( exif_orientation ) {
- case 2:
- matrix.scale( -1, 1 );
- break;
- case 3:
- matrix.rotate( 180 );
- break;
- case 4:
- matrix.scale( 1, -1 );
- break;
- case 5:
- matrix.rotate( 270 );
- matrix.scale( -1, 1 );
- break;
- case 6:
- matrix.rotate( 90 );
- break;
- case 7:
- matrix.rotate( 90 );
- matrix.scale( -1, 1 );
- break;
- case 8:
- matrix.rotate( 270 );
- break;
- }
- processed = qimage->transformed( matrix );
- delete qimage;
- qimage = new QImage( processed );
- }
- }
-#endif
- // Store the width/height of the qimage
- self->current_width = qimage->width( );
- self->current_height = qimage->height( );
+ if ( !disable_exif )
+ qimage = reorient_with_exif( self, image_idx, qimage );
// Register qimage for destruction and reuse
- mlt_cache_item_close( qimage_cache );
+ mlt_cache_item_close( self->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" );
+ self->qimage_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.qimage" );
self->qimage_idx = image_idx;
+ // Store the width/height of the qimage
+ self->current_width = qimage->width( );
+ self->current_height = qimage->height( );
+
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_properties_set_int( producer_props, "meta.media.width", self->current_width );
+ mlt_properties_set_int( producer_props, "meta.media.height", self->current_height );
mlt_properties_set_int( producer_props, "_disable_exif", disable_exif );
mlt_events_unblock( producer_props, NULL );
}
else
{
delete qimage;
- qimage = NULL;
+ self->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 )
+ // Set width/height of frame
+ mlt_properties_set_int( properties, "width", self->current_width );
+ mlt_properties_set_int( properties, "height", self->current_height );
+
+ return image_idx;
+}
+
+void refresh_image( producer_qimage self, mlt_frame frame, mlt_image_format format, int width, int height )
+{
+ // Obtain properties of frame and producer
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+ mlt_producer producer = &self->parent;
+
+ // Get index and qimage
+ int image_idx = refresh_qimage( self, frame );
+
+ // optimization for subsequent iterations on single pictur
+ if ( image_idx != self->image_idx || width != self->current_width || height != self->current_height )
+ self->current_image = NULL;
+
+ // If we have a qimage and need a new scaled image
+ if ( self->qimage && ( !self->current_image || ( format != mlt_image_none && format != self->format ) ) )
{
char *interps = mlt_properties_get( properties, "rescale.interp" );
int interp = 0;
+ QImage *qimage = static_cast<QImage*>( self->qimage );
// QImage has two scaling modes - we'll toggle between them here
- if ( strcmp( interps, "tiles" ) == 0 )
- interp = 1;
- else if ( strcmp( interps, "hyper" ) == 0 )
+ if ( strcmp( interps, "tiles" ) == 0
+ || strcmp( interps, "hyper" ) == 0
+ || strcmp( interps, "bicubic" ) == 0 )
interp = 1;
#ifdef USE_QT4
QImage temp = qimage->convertToFormat( QImage::Format_RGB32 );
delete qimage;
qimage = new QImage( temp );
+ self->qimage = qimage;
}
QImage scaled = interp == 0 ? qimage->scaled( QSize( width, height ) ) :
qimage->scaled( QSize(width, height), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
- self->has_alpha = scaled.hasAlphaChannel();
+ int has_alpha = scaled.hasAlphaChannel();
#endif
#ifdef USE_QT3
self->current_height = height;
// Allocate/define image
- int dst_stride = width * ( self->has_alpha ? 4 : 3 );
+ int dst_stride = width * ( has_alpha ? 4 : 3 );
int image_size = dst_stride * ( height + 1 );
self->current_image = ( uint8_t * )mlt_pool_alloc( image_size );
+ self->current_alpha = NULL;
+ self->format = has_alpha ? mlt_image_rgb24a : mlt_image_rgb24;
// Copy the image
int y = self->current_height + 1;
*dst++ = qRed(*src);
*dst++ = qGreen(*src);
*dst++ = qBlue(*src);
- if ( self->has_alpha ) *dst++ = qAlpha(*src);
+ if ( has_alpha ) *dst++ = qAlpha(*src);
++src;
}
}
+ // Convert image to requested format
+ if ( format != mlt_image_none && format != self->format )
+ {
+ uint8_t *buffer = NULL;
+
+ // First, set the image so it can be converted when we get it
+ mlt_frame_replace_image( frame, self->current_image, self->format, width, height );
+ mlt_frame_set_image( frame, self->current_image, image_size, mlt_pool_release );
+ self->format = format;
+
+ // get_image will do the format conversion
+ mlt_frame_get_image( frame, &buffer, &format, &width, &height, 0 );
+
+ // cache copies of the image and alpha buffers
+ if ( buffer )
+ {
+ image_size = mlt_image_format_size( format, width, height, NULL );
+ self->current_image = (uint8_t*) mlt_pool_alloc( image_size );
+ memcpy( self->current_image, buffer, image_size );
+ }
+ if ( ( buffer = mlt_frame_get_alpha_mask( frame ) ) )
+ {
+ self->current_alpha = (uint8_t*) mlt_pool_alloc( width * height );
+ memcpy( self->current_alpha, buffer, width * height );
+ }
+ }
+
// Update the cache
- if ( !use_cache )
- mlt_cache_item_close( self->image_cache );
+ mlt_cache_item_close( self->image_cache );
mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "qimage.image", self->current_image, image_size, mlt_pool_release );
self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.image" );
self->image_idx = image_idx;
-
- // 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 );
+ self->alpha_cache = NULL;
+ if ( self->current_alpha )
+ {
+ 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" );
+ }
}
// 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 ) * ( self->has_alpha ? 4 : 3 ),
- mlt_pool_release, NULL );
- mlt_properties_set_int( cached_props, "alpha", self->has_alpha );
- mlt_properties_set_data( cache, image_key, cached, 0, ( mlt_destructor )mlt_frame_close, NULL );
- }
- g_mutex.unlock();
}
extern void make_tempfile( producer_qimage self, const char *xml )
int image_idx;
int qimage_idx;
uint8_t *current_image;
- int has_alpha;
+ uint8_t *current_alpha;
int current_width;
int current_height;
mlt_cache_item image_cache;
- pthread_mutex_t mutex;
+ mlt_cache_item alpha_cache;
+ mlt_cache_item qimage_cache;
+ void *qimage;
+ mlt_image_format format;
};
typedef struct producer_qimage_s *producer_qimage;
-extern void refresh_qimage( producer_qimage, mlt_frame, int width, int height );
+extern int refresh_qimage( producer_qimage self, mlt_frame frame );
+extern void refresh_image( producer_qimage, mlt_frame, mlt_image_format, int width, int height );
extern void make_tempfile( producer_qimage, const char *xml );
-
-#ifdef USE_KDE
extern void init_qimage();
-#endif
+
#ifdef __cplusplus
}
--- /dev/null
+/*
+ * transition_vqm.c -- video quality measurement
+ * Copyright (c) 2012 Dan Dennedy <dan@dennedy.org>
+ * Core psnr and ssim routines based on code from
+ * qsnr (C) 2010 E. Oriani, ema <AT> fastwebnet <DOT> it
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <framework/mlt.h>
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+#include <QtGui/QtGui>
+
+static QApplication *app = 0;
+
+static double calc_psnr( const uint8_t *a, const uint8_t *b, int size, int bpp )
+{
+ double mse = 0.0;
+ int n = size + 1;
+
+ while ( --n )
+ {
+ int diff = *a - *b;
+ mse += diff * diff;
+ a += bpp;
+ b += bpp;
+ }
+
+ return 10.0 * log10( 255.0 * 255.0 / ( mse == 0 ? 1e-10 : mse/size ) );
+}
+
+static double calc_ssim( const uint8_t *a, const uint8_t *b, int width, int height, int window_size, int bpp )
+{
+ int windows_x = width / window_size;
+ int windows_y = height / window_size;
+ double avg = 0.0;
+
+ if ( !windows_x || !windows_y )
+ return 0.0;
+
+ // for each window
+ for ( int y = 0; y < windows_y; ++y )
+ for ( int x = 0; x < windows_x; ++x )
+ {
+ int base_offset = x * window_size + y * window_size * width;
+ double ref_acc = 0.0,
+ ref_acc_2 = 0.0,
+ cmp_acc = 0.0,
+ cmp_acc_2 = 0.0,
+ ref_cmp_acc = 0.0;
+
+ // accumulate the pixel values for this window
+ for ( int j = 0; j < window_size; ++j )
+ for ( int i = 0; i < window_size; ++i )
+ {
+ uint8_t c_a = a[bpp * (base_offset + j * width + i)];
+ uint8_t c_b = b[bpp * (base_offset + j * width + i)];
+ ref_acc += c_a;
+ ref_acc_2 += c_a * c_a;
+ cmp_acc += c_b;
+ cmp_acc_2 += c_b * c_b;
+ ref_cmp_acc += c_a * c_b;
+ }
+
+ // compute the SSIM for this window
+ // http://en.wikipedia.org/wiki/SSIM
+ // http://en.wikipedia.org/wiki/Variance
+ // http://en.wikipedia.org/wiki/Covariance
+ double n_samples = window_size * window_size,
+ ref_avg = ref_acc / n_samples,
+ ref_var = ref_acc_2 / n_samples - ref_avg * ref_avg,
+ cmp_avg = cmp_acc / n_samples,
+ cmp_var = cmp_acc_2 / n_samples - cmp_avg * cmp_avg,
+ ref_cmp_cov = ref_cmp_acc / n_samples - ref_avg * cmp_avg,
+ c1 = 6.5025, // (0.01*255.0)^2
+ c2 = 58.5225, // (0.03*255)^2
+ ssim_num = (2.0 * ref_avg * cmp_avg + c1) * (2.0 * ref_cmp_cov + c2),
+ ssim_den = (ref_avg * ref_avg + cmp_avg * cmp_avg + c1) * (ref_var + cmp_var + c2);
+
+ // accumulate the SSIM
+ avg += ssim_num / ssim_den;
+ }
+
+ // return the average SSIM
+ return avg / windows_x / windows_y;
+}
+
+static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+{
+ mlt_frame b_frame = mlt_frame_pop_frame( a_frame );
+ mlt_properties properties = MLT_FRAME_PROPERTIES( a_frame );
+ mlt_transition transition = MLT_TRANSITION( mlt_frame_pop_service( a_frame ) );
+ uint8_t *b_image;
+ int window_size = mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( transition ), "window_size" );
+ double psnr[3], ssim[3];
+
+ *format = mlt_image_yuv422;
+ mlt_frame_get_image( b_frame, &b_image, format, width, height, writable );
+ mlt_frame_get_image( a_frame, image, format, width, height, writable );
+
+ psnr[0] = calc_psnr( *image, b_image, *width * *height, 2 );
+ psnr[1] = calc_psnr( *image + 1, b_image + 1, *width * *height / 2, 4 );
+ psnr[2] = calc_psnr( *image + 3, b_image + 3, *width * *height / 2, 4 );
+ ssim[0] = calc_ssim( *image, b_image, *width, *height, window_size, 2 );
+ ssim[1] = calc_ssim( *image + 1, b_image + 1, *width / 2, *height, window_size, 4 );
+ ssim[2] = calc_ssim( *image + 3, b_image + 3, *width / 2, *height, window_size, 4 );
+ mlt_properties_set_double( properties, "meta.vqm.psnr.y", psnr[0] );
+ mlt_properties_set_double( properties, "meta.vqm.psnr.cb", psnr[1] );
+ mlt_properties_set_double( properties, "meta.vqm.psnr.cr", psnr[2] );
+ mlt_properties_set_double( properties, "meta.vqm.ssim.y", ssim[0] );
+ mlt_properties_set_double( properties, "meta.vqm.ssim.cb", ssim[1] );
+ mlt_properties_set_double( properties, "meta.vqm.ssim.cr", ssim[2] );
+ printf( "%05d %05.2f %05.2f %05.2f %5.3f %5.3f %5.3f\n",
+ mlt_frame_get_position( a_frame ), psnr[0], psnr[1], psnr[2],
+ ssim[0], ssim[1], ssim[2] );
+
+ // copy the B frame to the bottom of the A frame for comparison
+ window_size = mlt_image_format_size( *format, *width, *height, NULL ) / 2;
+ memcpy( *image + window_size, b_image + window_size, window_size );
+
+ if ( !mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( transition ), "render" ) )
+ return 0;
+
+ // get RGBA image for Qt drawing
+ *format = mlt_image_rgb24a;
+ mlt_frame_get_image( a_frame, image, format, width, height, 1 );
+
+ // convert mlt image to qimage
+ QImage img( *width, *height, QImage::Format_ARGB32 );
+ int y = *height + 1;
+ uint8_t *src = *image;
+ while ( --y )
+ {
+ QRgb *dst = (QRgb*) img.scanLine( *height - y );
+ int x = *width + 1;
+ while ( --x )
+ {
+ *dst++ = qRgba( src[0], src[1], src[2], 255 );
+ src += 4;
+ }
+ }
+
+ // create QApplication, if needed
+ if ( !app )
+ {
+ if ( qApp )
+ {
+ app = qApp;
+ }
+ else
+ {
+ int argc = 1;
+ char* argv[] = { strdup( "unknown" ) };
+
+ app = new QApplication( argc, argv );
+ const char *localename = mlt_properties_get_lcnumeric( MLT_TRANSITION_PROPERTIES(transition) );
+ QLocale::setDefault( QLocale( localename ) );
+ free( argv[0] );
+ }
+ }
+
+ // setup Qt drawing
+ QPainter painter;
+ painter.begin( &img );
+ painter.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing );
+
+ // draw some stuff with Qt
+ QPalette palette;
+ QFont font;
+ QString s;
+ font.setBold( true );
+ font.setPointSize( 30 * *height / 1080 );
+ painter.setPen( QColor("black") );
+ painter.drawLine( 0, *height/2 + 1, *width, *height/2 );
+ painter.setPen( QColor("white") );
+ painter.drawLine( 0, *height/2 - 1, *width, *height/2 );
+ painter.setFont( font );
+ s.sprintf( "Frame: %05d\nPSNR: %05.2f (Y) %05.2f (Cb) %05.2f (Cr)\nSSIM: %5.3f (Y) %5.3f (Cb) %5.3f (Cr)",
+ mlt_frame_get_position( a_frame ), psnr[0], psnr[1], psnr[2],
+ ssim[0], ssim[1], ssim[2] );
+ painter.setPen( QColor("black") );
+ painter.drawText( 52, *height * 8 / 10 + 2, *width, *height, 0, s );
+ painter.setPen( QColor("white") );
+ painter.drawText( 50, *height * 8 / 10, *width, *height, 0, s );
+
+ // finish Qt drawing
+ painter.end();
+ window_size = mlt_image_format_size( *format, *width, *height, NULL );
+ uint8_t *dst = (uint8_t *) mlt_pool_alloc( window_size );
+ mlt_properties_set_data( MLT_FRAME_PROPERTIES(a_frame), "image", dst, window_size, mlt_pool_release, NULL );
+ *image = dst;
+
+ // convert qimage to mlt
+ y = *height + 1;
+ while ( --y )
+ {
+ QRgb *src = (QRgb*) img.scanLine( *height - y );
+ int x = *width + 1;
+ while ( --x )
+ {
+ *dst++ = qRed( *src );
+ *dst++ = qGreen( *src );
+ *dst++ = qBlue( *src );
+ *dst++ = qAlpha( *src );
+ src++;
+ }
+ }
+
+ return 0;
+}
+
+static mlt_frame process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame )
+{
+ mlt_frame_push_service( a_frame, transition );
+ mlt_frame_push_frame( a_frame, b_frame );
+ mlt_frame_push_get_image( a_frame, get_image );
+
+ return a_frame;
+}
+
+extern "C" {
+
+mlt_transition transition_vqm_init( mlt_profile profile, mlt_service_type type, const char *id, void *arg )
+{
+ mlt_transition transition = mlt_transition_new();
+
+ if ( transition )
+ {
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
+
+ transition->process = process;
+ mlt_properties_set_int( properties, "_transition_type", 1 ); // video only
+ mlt_properties_set_int( properties, "window_size", 8 );
+ printf( "frame psnr[Y] psnr[Cb] psnr[Cr] ssim[Y] ssim[Cb] ssim[Cr]\n" );
+ }
+
+ return transition;
+}
+
+} // extern "C"
--- /dev/null
+schema_version: 0.1
+type: transition
+identifier: vqm
+title: Video Quality Measurement
+version: 1
+copyright: Dan Dennedy
+creator: Dan Dennedy
+license: GPLv3
+language: en
+description: >
+ This performs the PSNR and SSIM video quality measurements by comparing the
+ B frames to the reference frame A.
+ It outputs the numbers to stdout in space-delimited format for easy
+ by another tool.
+ The bottom half of the B frame is placed below the top half of the A frame
+ for visual comparison.
+tags:
+ - Video
+parameters:
+ - identifier: render
+ title: Render
+ description: >
+ Render a line between top and bottom halves and the values atop the video.
+ type: integer
+ default: 0
+ minimum: 0
+ maximum: 1
+ widget: checkbox
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/resample"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/resample"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/resample"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/resample"
ifneq ($(wildcard .depend),)
include .depend
if ( error ) return error;
// Return now if no work to do
- if ( output_rate != *frequency )
+ if ( output_rate != *frequency && *frequency > 0 && *channels > 0 )
{
mlt_log_debug( MLT_FILTER_SERVICE(filter), "channels %d samples %d frequency %d -> %d\n",
*channels, *samples, *frequency, output_rate );
// Do not convert to float unless we need to change the rate
- if ( *format != mlt_audio_float )
- {
- *format = mlt_audio_float;
- mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
- }
+ if ( *format != mlt_audio_f32le )
+ frame->convert_audio( frame, buffer, format, mlt_audio_f32le );
mlt_service_lock( MLT_FILTER_SERVICE(filter) );
- float *input_buffer = mlt_properties_get_data( filter_properties, "input_buffer", NULL );
- float *output_buffer = mlt_properties_get_data( filter_properties, "output_buffer", NULL );
SRC_DATA data;
- data.data_in = input_buffer;
- data.data_out = output_buffer;
+ data.data_in = *buffer;
+ data.data_out = mlt_properties_get_data( filter_properties, "output_buffer", NULL );
data.src_ratio = ( float ) output_rate / ( float ) *frequency;
data.input_frames = *samples;
data.output_frames = BUFFER_LEN / *channels;
mlt_properties_set_int( filter_properties, "channels", *channels );
}
- // Convert to interleaved
- float *q = (float*) *buffer;
- float *p = input_buffer;
- int s, c;
- for ( s = 0; s < *samples; s++ )
- for ( c = 0; c < *channels; c++ )
- *p++ = *( q + c * *samples + s );
-
// Resample the audio
error = src_process( state, &data );
if ( !error )
{
- int size = data.output_frames_gen * *channels * sizeof(float);
-
- // Resize if necessary
- if ( data.output_frames_gen > *samples )
- {
- *buffer = mlt_pool_realloc( *buffer, size );
- mlt_frame_set_audio( frame, *buffer, *format, size, mlt_pool_release );
- }
-
- // Convert to non-interleaved
- p = (float*) *buffer;
- for ( c = 0; c < *channels; c++ )
- {
- float *q = output_buffer + c;
- int i = data.output_frames_gen + 1;
- while ( --i )
- {
- *p++ = *q;
- q += *channels;
- }
- }
-
// Update output variables
*samples = data.output_frames_gen;
*frequency = output_rate;
-
+ *buffer = data.data_out;
}
else
{
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
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d $(DESTDIR)$(datadir)/mlt/rotoscoping
- install -m 644 filter_rotoscoping.yml "$(DESTDIR)$(datadir)/mlt/rotoscoping"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d $(DESTDIR)$(mltdatadir)/rotoscoping
+ install -m 644 filter_rotoscoping.yml "$(DESTDIR)$(mltdatadir)/rotoscoping"
ifneq ($(wildcard .depend),)
include .depend
/** Returns the index of \param string in \param stringList.
* Useful for assigning string parameters to enums. */
-int stringValue( const char *string, const char **stringList, int max )
+static int stringValue( const char *string, const char **stringList, int max )
{
int i;
for ( i = 0; i < max; i++ )
}
/** Linear interp */
-inline void lerp( const PointF *a, const PointF *b, PointF *result, double t )
+static inline void lerp( const PointF *a, const PointF *b, PointF *result, double t )
{
result->x = a->x + ( b->x - a->x ) * t;
result->y = a->y + ( b->y - a->y ) * t;
/** Linear interp. with t = 0.5
* Speed gain? */
-inline void lerpHalf( const PointF *a, const PointF *b, PointF *result )
+static inline void lerpHalf( const PointF *a, const PointF *b, PointF *result )
{
result->x = ( a->x + b->x ) * .5;
result->y = ( a->y + b->y ) * .5;
}
/** Turns a json array with two children into a point (x, y tuple). */
-void jsonGetPoint( cJSON *json, PointF *point )
+static void jsonGetPoint( cJSON *json, PointF *point )
{
if ( cJSON_GetArraySize( json ) == 2 )
{
* \param points pointer to array of points. Will be allocated and filled with the points in \param array
* \return number of points
*/
-int json2BCurves( cJSON *array, BPointF **points )
+static int json2BCurves( cJSON *array, BPointF **points )
{
int count = cJSON_GetArraySize( array );
cJSON *child = array->child;
}
/** Blurs \param src horizontally. \See funtion blur. */
-void blurHorizontal( uint8_t *src, uint8_t *dst, int width, int height, int radius)
+static void blurHorizontal( uint8_t *src, uint8_t *dst, int width, int height, int radius)
{
int x, y, kx, yOff, total, amount, amountInit;
amountInit = radius * 2 + 1;
}
/** Blurs \param src vertically. \See funtion blur. */
-void blurVertical( uint8_t *src, uint8_t *dst, int width, int height, int radius)
+static void blurVertical( uint8_t *src, uint8_t *dst, int width, int height, int radius)
{
int x, y, ky, total, amount, amountInit;
amountInit = radius * 2 + 1;
* \param radius blur radius
* \param passes blur passes
*/
-void blur( uint8_t *map, int width, int height, int radius, int passes )
+static void blur( uint8_t *map, int width, int height, int radius, int passes )
{
uint8_t *src = mlt_pool_alloc( width * height );
uint8_t *tmp = mlt_pool_alloc( width * height );
* \param map array of integers of the dimension width * height.
* The map entries belonging to the points in the polygon will be set to \param set * 255 the others to !set * 255.
*/
-void fillMap( PointF *vertices, int count, int width, int height, int invert, uint8_t *map )
+static void fillMap( PointF *vertices, int count, int width, int height, int invert, uint8_t *map )
{
int nodes, nodeX[1024], pixelY, i, j, value;
/** Determines the point in the middle of the Bézier curve (t = 0.5) defined by \param p1 and \param p2
* using De Casteljau's algorithm.
*/
-void deCasteljau( BPointF *p1, BPointF *p2, BPointF *mid )
+static void deCasteljau( BPointF *p1, BPointF *p2, BPointF *mid )
{
struct PointF ab, bc, cd;
* \param count Number of calculated points in \param points
* \param size Allocated size of \param points (in elements not in bytes)
*/
-void curvePoints( BPointF p1, BPointF p2, PointF **points, int *count, int *size )
+static void curvePoints( BPointF p1, BPointF p2, PointF **points, int *count, int *size )
{
double errorSqr = SQR( p1.p.x - p2.p.x ) + SQR( p1.p.y - p2.p.y );
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- #install -d "$(DESTDIR)$(datadir)/mlt/rtaudio"
- #install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/rtaudio"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ #install -d "$(DESTDIR)$(mltdatadir)/rtaudio"
+ #install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/rtaudio"
uninstall:
- rm "$(DESTDIR)$(libdir)/mlt/libmltrtaudio$(LIBSUF)" 2> /dev/null || true
- rm -rf "$(DESTDIR)$(datadir)/mlt/rtaudio"
+ rm "$(DESTDIR)$(moduledir)/libmltrtaudio$(LIBSUF)" 2> /dev/null || true
+ rm -rf "$(DESTDIR)$(mltdatadir)/rtaudio"
ifneq ($(wildcard .depend),)
include .depend
getCompiledApi( apis );\r
for ( unsigned int i=0; i<apis.size(); i++ ) {\r
openRtApi( apis[i] );\r
- if ( rtapi_->getDeviceCount() ) break;\r
+ if ( rtapi_ && rtapi_->getDeviceCount() ) break;\r
}\r
\r
if ( rtapi_ ) return;\r
// Allocate necessary internal buffers.\r
unsigned long bufferBytes;\r
bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );\r
- // stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );\r
+ // stream_.userBuffer[mode] = (char *) calloc( 1, bufferBytes );\r
stream_.userBuffer[mode] = (char *) malloc( bufferBytes * sizeof(char) );\r
memset( stream_.userBuffer[mode], 0, bufferBytes * sizeof(char) );\r
if ( stream_.userBuffer[mode] == NULL ) {\r
if ( makeBuffer ) {\r
bufferBytes *= *bufferSize;\r
if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );\r
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );\r
+ stream_.deviceBuffer = (char *) calloc( 1, bufferBytes );\r
if ( stream_.deviceBuffer == NULL ) {\r
errorText_ = "RtApiCore::probeDeviceOpen: error allocating device buffer memory.";\r
goto error;\r
// Allocate necessary internal buffers.\r
unsigned long bufferBytes;\r
bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );\r
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );\r
+ stream_.userBuffer[mode] = (char *) calloc( 1, bufferBytes );\r
if ( stream_.userBuffer[mode] == NULL ) {\r
errorText_ = "RtApiJack::probeDeviceOpen: error allocating user buffer memory.";\r
goto error;\r
if ( makeBuffer ) {\r
bufferBytes *= *bufferSize;\r
if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );\r
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );\r
+ stream_.deviceBuffer = (char *) calloc( 1, bufferBytes );\r
if ( stream_.deviceBuffer == NULL ) {\r
errorText_ = "RtApiJack::probeDeviceOpen: error allocating device buffer memory.";\r
goto error;\r
// Allocate necessary internal buffers\r
unsigned long bufferBytes;\r
bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );\r
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );\r
+ stream_.userBuffer[mode] = (char *) calloc( 1, bufferBytes );\r
if ( stream_.userBuffer[mode] == NULL ) {\r
errorText_ = "RtApiAsio::probeDeviceOpen: error allocating user buffer memory.";\r
goto error;\r
if ( makeBuffer ) {\r
bufferBytes *= *bufferSize;\r
if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );\r
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );\r
+ stream_.deviceBuffer = (char *) calloc( 1, bufferBytes );\r
if ( stream_.deviceBuffer == NULL ) {\r
errorText_ = "RtApiAsio::probeDeviceOpen: error allocating device buffer memory.";\r
goto error;\r
\r
// Allocate necessary internal buffers\r
long bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );\r
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );\r
+ stream_.userBuffer[mode] = (char *) calloc( 1, bufferBytes );\r
if ( stream_.userBuffer[mode] == NULL ) {\r
errorText_ = "RtApiDs::probeDeviceOpen: error allocating user buffer memory.";\r
goto error;\r
if ( makeBuffer ) {\r
bufferBytes *= *bufferSize;\r
if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );\r
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );\r
+ stream_.deviceBuffer = (char *) calloc( 1, bufferBytes );\r
if ( stream_.deviceBuffer == NULL ) {\r
errorText_ = "RtApiDs::probeDeviceOpen: error allocating device buffer memory.";\r
goto error;\r
// Allocate necessary internal buffers.\r
unsigned long bufferBytes;\r
bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );\r
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );\r
+ stream_.userBuffer[mode] = (char *) calloc( 1, bufferBytes );\r
if ( stream_.userBuffer[mode] == NULL ) {\r
errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating user buffer memory.";\r
goto error;\r
if ( makeBuffer ) {\r
bufferBytes *= *bufferSize;\r
if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );\r
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );\r
+ stream_.deviceBuffer = (char *) calloc( 1, bufferBytes );\r
if ( stream_.deviceBuffer == NULL ) {\r
errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating device buffer memory.";\r
goto error;\r
// Allocate necessary internal buffers.\r
unsigned long bufferBytes;\r
bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );\r
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );\r
+ stream_.userBuffer[mode] = (char *) calloc( 1, bufferBytes );\r
if ( stream_.userBuffer[mode] == NULL ) {\r
errorText_ = "RtApiOss::probeDeviceOpen: error allocating user buffer memory.";\r
goto error;\r
if ( makeBuffer ) {\r
bufferBytes *= *bufferSize;\r
if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );\r
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );\r
+ stream_.deviceBuffer = (char *) calloc( 1, bufferBytes );\r
if ( stream_.deviceBuffer == NULL ) {\r
errorText_ = "RtApiOss::probeDeviceOpen: error allocating device buffer memory.";\r
goto error;\r
#ifndef __RTAUDIO_H
#define __RTAUDIO_H
+#include <string.h>
#include <string>
#include <vector>
#include "RtError.h"
// Default constructor.
CallbackInfo()
- :object(0), callback(0), userData(0), apiInfo(0), isRunning(false) {}
+ :object(0), thread(0), callback(0), userData(0), apiInfo(0), isRunning(false) {}
};
// **************************************************************** //
#endif
RtApiStream()
- :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; }
+ :apiHandle(0),
+ mode(OUTPUT),
+ state(STREAM_STOPPED),
+ deviceBuffer(0),
+ userInterleaved(0),
+ sampleRate(0),
+ bufferSize(0),
+ nBuffers(0),
+ streamTime(0)
+ {
+ device[0] = 11111;
+ device[1] = 11111;
+ memset( &channelOffset, 0, sizeof( channelOffset ) );
+ memset( &deviceFormat, 0, sizeof( deviceFormat ) );
+ memset( &deviceInterleaved, 0, sizeof( deviceInterleaved ) );
+ memset( &doByteSwap, 0, sizeof( doByteSwap ) );
+ memset( &doConvertBuffer, 0, sizeof( doConvertBuffer ) );
+ memset( &latency, 0, sizeof( latency ) );
+ memset( &nDeviceChannels, 0, sizeof( nDeviceChannels ) );
+ memset( &nUserChannels, 0, sizeof( nUserChannels ) );
+ memset( &userBuffer, 0, sizeof( userBuffer ) );
+ memset( &userFormat, 0, sizeof( userFormat ) );
+ }
};
typedef signed short Int16;
RtAudioConsumer()
: device_id(-1)
+ , queue(NULL)
, joined(0)
, running(0)
, audio_avail(0)
, playing(0)
, refresh_count(0)
- {}
+ {
+ memset( &consumer, 0, sizeof( consumer ) );
+ }
~RtAudioConsumer()
{
int64_t playtime = 0;
struct timespec tm = { 0, 100000 };
// int last_position = -1;
+
+ pthread_mutex_lock( &refresh_mutex );
refresh_count = 0;
+ pthread_mutex_unlock( &refresh_mutex );
// Loop until told not to
while ( running )
// 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" );
+ int scrub = mlt_properties_get_int( properties, "scrub_audio" );
static int counter = 0;
int samples = mlt_sample_calculator( mlt_properties_get_double( properties, "fps" ), frequency, counter++ );
int16_t *pcm;
pthread_cond_wait( &audio_cond, &audio_mutex );
if ( running )
{
- if ( mlt_properties_get_double( properties, "_speed" ) == 1 )
+ if ( scrub || mlt_properties_get_double( properties, "_speed" ) == 1 )
memcpy( &audio_buffer[ audio_avail ], pcm, bytes );
else
memset( &audio_buffer[ audio_avail ], 0, bytes );
if ( rtaudio && !mlt_consumer_init( rtaudio->getConsumer(), rtaudio, profile ) )
{
// If initialises without error
- if ( rtaudio->open( arg ) )
+ if ( rtaudio->open( arg? arg : getenv( "AUDIODEV" ) ) )
{
// Setup callbacks
consumer = rtaudio->getConsumer();
type: integer
minimum: 0
maximum: 1
+
+ - identifier: scrub_audio
+ title: Audio scrubbing
+ type: integer
+ description: If enabled, sound is played even when the speed is not normal.
+ mutable: yes
+ minimum: 0
+ maximum: 1
+ default: 0
+ widget: checkbox
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/sdl"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/sdl"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/sdl"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/sdl"
ifneq ($(wildcard .depend),)
include .depend
int height;
int playing;
int sdl_flags;
- SDL_Surface *sdl_screen;
SDL_Overlay *sdl_overlay;
SDL_Rect rect;
uint8_t *buffer;
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 );
+ consumer_sdl this = calloc( 1, sizeof( struct consumer_sdl_s ) );
// If no malloc'd and consumer init ok
if ( this != NULL && mlt_consumer_init( &this->parent, this, profile ) == 0 )
// Default scaler (for now we'll use nearest)
mlt_properties_set( this->properties, "rescale", "nearest" );
mlt_properties_set( this->properties, "deinterlace_method", "onefield" );
+ mlt_properties_set_int( this->properties, "top_field_first", -1 );
// Default buffer for low latency
mlt_properties_set_int( this->properties, "buffer", 1 );
SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
SDL_EnableUNICODE( 1 );
}
- else if ( display_off == 0 )
- {
- pthread_mutex_lock( &mlt_sdl_mutex );
- this->sdl_screen = SDL_GetVideoSurface( );
- pthread_mutex_unlock( &mlt_sdl_mutex );
- }
if ( audio_off == 0 )
SDL_InitSubSystem( SDL_INIT_AUDIO );
this->window_height = this->height;
}
- if ( this->sdl_screen == NULL && display_off == 0 )
+ pthread_mutex_lock( &mlt_sdl_mutex );
+ if ( !SDL_GetVideoSurface() && display_off == 0 )
{
if ( mlt_properties_get_int( this->properties, "fullscreen" ) )
{
this->sdl_flags |= SDL_FULLSCREEN;
SDL_ShowCursor( SDL_DISABLE );
}
- pthread_mutex_lock( &mlt_sdl_mutex );
- this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
- pthread_mutex_unlock( &mlt_sdl_mutex );
+ SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
}
+ pthread_mutex_unlock( &mlt_sdl_mutex );
pthread_create( &this->thread, NULL, consumer_thread, this );
}
SDL_Quit( );
pthread_mutex_unlock( &mlt_sdl_mutex );
}
-
- this->sdl_screen = NULL;
}
return 0;
void *pool = mlt_cocoa_autorelease_init();
// Handle events
- if ( this->sdl_screen != NULL )
+ if ( SDL_GetVideoSurface() )
{
SDL_Event event;
this->sdl_overlay = NULL;
}
- if ( this->running && ( this->sdl_screen == NULL || changed ) )
+ if ( this->running && ( !SDL_GetVideoSurface() || changed ) )
{
// Force an overlay recreation
if ( this->sdl_overlay != NULL )
// open SDL window with video overlay, if possible
pthread_mutex_lock( &mlt_sdl_mutex );
- this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, this->bpp, this->sdl_flags );
+ SDL_Surface *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 );
+ screen = SDL_SetVideoMode( this->window_width, this->window_height, this->bpp, this->sdl_flags );
pthread_mutex_unlock( &mlt_sdl_mutex );
- 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 ( screen )
+ {
+ uint32_t color = mlt_properties_get_int( this->properties, "window_background" );
+ SDL_FillRect( screen, NULL, color >> 8 );
+ SDL_Flip( screen );
+ }
}
if ( this->running )
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 );
+ SDL_SetClipRect( SDL_GetVideoSurface(), &this->rect );
}
- if ( this->running && this->sdl_screen != NULL && this->sdl_overlay == NULL )
+ if ( this->running && SDL_GetVideoSurface() && this->sdl_overlay == NULL )
{
- SDL_SetClipRect( this->sdl_screen, &this->rect );
- this->sdl_overlay = SDL_CreateYUVOverlay( width, height, SDL_YUY2_OVERLAY, this->sdl_screen );
+ SDL_SetClipRect( SDL_GetVideoSurface(), &this->rect );
+ this->sdl_overlay = SDL_CreateYUVOverlay( width, height, SDL_YUY2_OVERLAY, SDL_GetVideoSurface() );
}
- if ( this->running && this->sdl_screen != NULL && this->sdl_overlay != NULL )
+ if ( this->running && SDL_GetVideoSurface() && 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_DisplayYUVOverlay( this->sdl_overlay, &SDL_GetVideoSurface()->clip_rect );
}
}
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;
/*
* consumer_sdl_audio.c -- A Simple DirectMedia Layer audio-only consumer
- * Copyright (C) 2009, 2010 Ushodaya Enterprises Limited
+ * Copyright (C) 2009-2012 Ushodaya Enterprises Limited
* Author: Dan Dennedy <dan@dennedy.org>
*
* This library is free software; you can redistribute it and/or
static int consumer_is_stopped( mlt_consumer parent );
static void consumer_close( mlt_consumer parent );
static void *consumer_thread( void * );
-static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer this, char *name );
+static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer self, char *name );
/** 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_audio_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 );
+ consumer_sdl self = calloc( 1, sizeof( struct consumer_sdl_s ) );
// If no malloc'd and consumer init ok
- if ( this != NULL && mlt_consumer_init( &this->parent, this, profile ) == 0 )
+ if ( self != NULL && mlt_consumer_init( &self->parent, self, profile ) == 0 )
{
// Create the queue
- this->queue = mlt_deque_init( );
+ self->queue = mlt_deque_init( );
// Get the parent consumer object
- mlt_consumer parent = &this->parent;
+ mlt_consumer parent = &self->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 );
+ self->properties = MLT_SERVICE_PROPERTIES( service );
// Set the default volume
- mlt_properties_set_double( this->properties, "volume", 1.0 );
+ mlt_properties_set_double( self->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);
+ pthread_mutex_init( &self->audio_mutex, NULL );
+ pthread_cond_init( &self->audio_cond, NULL);
+ pthread_mutex_init( &self->video_mutex, NULL );
+ pthread_cond_init( &self->video_cond, NULL);
// Default scaler (for now we'll use nearest)
- mlt_properties_set( this->properties, "rescale", "nearest" );
- mlt_properties_set( this->properties, "deinterlace_method", "onefield" );
+ mlt_properties_set( self->properties, "rescale", "nearest" );
+ mlt_properties_set( self->properties, "deinterlace_method", "onefield" );
+ mlt_properties_set_int( self->properties, "top_field_first", -1 );
// Default buffer for low latency
- mlt_properties_set_int( this->properties, "buffer", 1 );
+ mlt_properties_set_int( self->properties, "buffer", 1 );
// Default audio buffer
- mlt_properties_set_int( this->properties, "audio_buffer", 2048 );
+ mlt_properties_set_int( self->properties, "audio_buffer", 2048 );
// Ensure we don't join on a non-running object
- this->joined = 1;
+ self->joined = 1;
// Allow thread to be started/stopped
parent->start = consumer_start;
parent->is_stopped = consumer_is_stopped;
// Initialize the refresh handler
- 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 );
+ pthread_cond_init( &self->refresh_cond, NULL );
+ pthread_mutex_init( &self->refresh_mutex, NULL );
+ mlt_events_listen( MLT_CONSUMER_PROPERTIES( parent ), self, "property-changed", ( mlt_listener )consumer_refresh_cb );
// Return the consumer produced
return parent;
}
// malloc or consumer init failed
- free( this );
+ free( self );
// Indicate failure
return NULL;
{
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 + 1;
- pthread_cond_broadcast( &this->refresh_cond );
- pthread_mutex_unlock( &this->refresh_mutex );
+ consumer_sdl self = parent->child;
+ pthread_mutex_lock( &self->refresh_mutex );
+ if ( self->refresh_count < 2 )
+ self->refresh_count = self->refresh_count <= 0 ? 1 : self->refresh_count + 1;
+ pthread_cond_broadcast( &self->refresh_cond );
+ pthread_mutex_unlock( &self->refresh_mutex );
}
}
int consumer_start( mlt_consumer parent )
{
- consumer_sdl this = parent->child;
+ consumer_sdl self = parent->child;
- if ( !this->running )
+ if ( !self->running )
{
consumer_stop( parent );
return -1;
}
- this->running = 1;
- this->joined = 0;
- pthread_create( &this->thread, NULL, consumer_thread, this );
+ self->running = 1;
+ self->joined = 0;
+ pthread_create( &self->thread, NULL, consumer_thread, self );
}
return 0;
int consumer_stop( mlt_consumer parent )
{
// Get the actual object
- consumer_sdl this = parent->child;
+ consumer_sdl self = parent->child;
- if ( this->running && !this->joined )
+ if ( self->running && !self->joined )
{
// Kill the thread and clean up
- this->joined = 1;
- this->running = 0;
+ self->joined = 1;
+ self->running = 0;
// Unlatch the consumer thread
- pthread_mutex_lock( &this->refresh_mutex );
- pthread_cond_broadcast( &this->refresh_cond );
- pthread_mutex_unlock( &this->refresh_mutex );
+ pthread_mutex_lock( &self->refresh_mutex );
+ pthread_cond_broadcast( &self->refresh_cond );
+ pthread_mutex_unlock( &self->refresh_mutex );
// Cleanup the main thread
#ifndef WIN32
- if ( this->thread )
+ if ( self->thread )
#endif
- pthread_join( this->thread, NULL );
+ pthread_join( self->thread, NULL );
// Unlatch the video thread
- pthread_mutex_lock( &this->video_mutex );
- pthread_cond_broadcast( &this->video_cond );
- pthread_mutex_unlock( &this->video_mutex );
+ pthread_mutex_lock( &self->video_mutex );
+ pthread_cond_broadcast( &self->video_cond );
+ pthread_mutex_unlock( &self->video_mutex );
// Unlatch the audio callback
- pthread_mutex_lock( &this->audio_mutex );
- pthread_cond_broadcast( &this->audio_cond );
- pthread_mutex_unlock( &this->audio_mutex );
+ pthread_mutex_lock( &self->audio_mutex );
+ pthread_cond_broadcast( &self->audio_cond );
+ pthread_mutex_unlock( &self->audio_mutex );
SDL_QuitSubSystem( SDL_INIT_AUDIO );
}
int consumer_is_stopped( mlt_consumer parent )
{
- consumer_sdl this = parent->child;
- return !this->running;
+ consumer_sdl self = parent->child;
+ return !self->running;
}
static void sdl_fill_audio( void *udata, uint8_t *stream, int len )
{
- consumer_sdl this = udata;
+ consumer_sdl self = udata;
// Get the volume
- double volume = mlt_properties_get_double( this->properties, "volume" );
+ double volume = mlt_properties_get_double( self->properties, "volume" );
- pthread_mutex_lock( &this->audio_mutex );
+ pthread_mutex_lock( &self->audio_mutex );
// Block until audio received
- while ( this->running && len > this->audio_avail )
- pthread_cond_wait( &this->audio_cond, &this->audio_mutex );
+#ifdef __DARWIN__
+ while ( self->running && len > self->audio_avail )
+ pthread_cond_wait( &self->audio_cond, &self->audio_mutex );
+#endif
- if ( this->audio_avail >= len )
+ if ( self->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 ) );
+ SDL_MixAudio( stream, self->audio_buffer, len, ( int )( ( float )SDL_MIX_MAXVOLUME * volume ) );
else
- memcpy( stream, this->audio_buffer, len );
+ memcpy( stream, self->audio_buffer, len );
// Remove len from the audio available
- this->audio_avail -= len;
+ self->audio_avail -= len;
// Remove the samples
- memmove( this->audio_buffer, this->audio_buffer + len, this->audio_avail );
+ memmove( self->audio_buffer, self->audio_buffer + len, self->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 ) );
+ // Mix the audio
+ SDL_MixAudio( stream, self->audio_buffer, self->audio_avail,
+ ( int )( ( float )SDL_MIX_MAXVOLUME * volume ) );
// No audio left
- this->audio_avail = 0;
+ self->audio_avail = 0;
}
// We're definitely playing now
- this->playing = 1;
+ self->playing = 1;
- pthread_cond_broadcast( &this->audio_cond );
- pthread_mutex_unlock( &this->audio_mutex );
+ pthread_cond_broadcast( &self->audio_cond );
+ pthread_mutex_unlock( &self->audio_mutex );
}
-static int consumer_play_audio( consumer_sdl this, mlt_frame frame, int init_audio, int *duration )
+static int consumer_play_audio( consumer_sdl self, mlt_frame frame, int init_audio, int *duration )
{
// Get the properties of this consumer
- mlt_properties properties = this->properties;
+ mlt_properties properties = self->properties;
mlt_audio_format afmt = mlt_audio_s16;
// 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" );
+ int scrub = mlt_properties_get_int( properties, "scrub_audio" );
static int counter = 0;
- int samples = mlt_sample_calculator( mlt_properties_get_double( this->properties, "fps" ), frequency, counter++ );
+ int samples = mlt_sample_calculator( mlt_properties_get_double( self->properties, "fps" ), frequency, counter++ );
int16_t *pcm;
int bytes;
if ( mlt_properties_get_int( properties, "audio_off" ) )
{
- this->playing = 1;
+ self->playing = 1;
init_audio = 1;
return init_audio;
}
// specify audio format
memset( &request, 0, sizeof( SDL_AudioSpec ) );
- this->playing = 0;
+ self->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;
+ request.userdata = (void *)self;
if ( SDL_OpenAudio( &request, &got ) != 0 )
{
- mlt_log_error( MLT_CONSUMER_SERVICE( this ), "SDL failed to open audio: %s\n", SDL_GetError() );
+ mlt_log_error( MLT_CONSUMER_SERVICE( self ), "SDL failed to open audio: %s\n", SDL_GetError() );
init_audio = 2;
}
else if ( got.size != 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 )
+ pthread_mutex_lock( &self->audio_mutex );
+ while ( self->running && bytes > ( sizeof( self->audio_buffer) - self->audio_avail ) )
+ pthread_cond_wait( &self->audio_cond, &self->audio_mutex );
+ if ( self->running )
{
- if ( mlt_properties_get_double( properties, "_speed" ) == 1 )
- memcpy( &this->audio_buffer[ this->audio_avail ], pcm, bytes );
+ if ( scrub || mlt_properties_get_double( properties, "_speed" ) == 1 )
+ memcpy( &self->audio_buffer[ self->audio_avail ], pcm, bytes );
else
- memset( &this->audio_buffer[ this->audio_avail ], 0, bytes );
- this->audio_avail += bytes;
+ memset( &self->audio_buffer[ self->audio_avail ], 0, bytes );
+ self->audio_avail += bytes;
}
- pthread_cond_broadcast( &this->audio_cond );
- pthread_mutex_unlock( &this->audio_mutex );
+ pthread_cond_broadcast( &self->audio_cond );
+ pthread_mutex_unlock( &self->audio_mutex );
}
else
{
- this->playing = 1;
+ self->playing = 1;
}
return init_audio;
}
-static int consumer_play_video( consumer_sdl this, mlt_frame frame )
+static int consumer_play_video( consumer_sdl self, mlt_frame frame )
{
// Get the properties of this consumer
- mlt_properties properties = this->properties;
- if ( this->running && !mlt_consumer_is_stopped( &this->parent ) )
+ mlt_properties properties = self->properties;
+ if ( self->running && !mlt_consumer_is_stopped( &self->parent ) )
mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
return 0;
static void *video_thread( void *arg )
{
// Identify the arg
- consumer_sdl this = arg;
+ consumer_sdl self = arg;
// Obtain time of thread start
struct timeval now;
double speed = 0;
// Get real time flag
- int real_time = mlt_properties_get_int( this->properties, "real_time" );
+ int real_time = mlt_properties_get_int( self->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 )
+ while ( self->running )
{
// Pop the next frame
- pthread_mutex_lock( &this->video_mutex );
- next = mlt_deque_pop_front( this->queue );
- while ( next == NULL && this->running )
+ pthread_mutex_lock( &self->video_mutex );
+ next = mlt_deque_pop_front( self->queue );
+ while ( next == NULL && self->running )
{
- pthread_cond_wait( &this->video_cond, &this->video_mutex );
- next = mlt_deque_pop_front( this->queue );
+ pthread_cond_wait( &self->video_cond, &self->video_mutex );
+ next = mlt_deque_pop_front( self->queue );
}
- pthread_mutex_unlock( &this->video_mutex );
+ pthread_mutex_unlock( &self->video_mutex );
- if ( !this->running || next == NULL ) break;
+ if ( !self->running || next == NULL ) break;
// Get the properties
properties = MLT_FRAME_PROPERTIES( next );
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 )
+ if ( mlt_properties_get_int( properties, "rendered" ) == 1 && self->running )
{
// Obtain the scheduled playout time
int64_t scheduled = mlt_properties_get_int( properties, "playtime" );
}
// 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 ( !real_time || ( difference > -10000 || speed != 1.0 || mlt_deque_count( self->queue ) < 2 ) )
+ consumer_play_video( self, 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 ) )
+ if ( real_time && ( mlt_deque_count( self->queue ) == 0 && speed == 1.0 ) )
{
gettimeofday( &now, NULL );
start = ( ( int64_t )now.tv_sec * 1000000 + now.tv_usec ) - scheduled + 20000;
if ( next != NULL )
mlt_frame_close( next );
- mlt_consumer_stopped( &this->parent );
+ mlt_consumer_stopped( &self->parent );
return NULL;
}
static void *consumer_thread( void *arg )
{
// Identify the arg
- consumer_sdl this = arg;
+ consumer_sdl self = arg;
// Get the consumer
- mlt_consumer consumer = &this->parent;
+ mlt_consumer consumer = &self->parent;
// Get the properties
mlt_properties consumer_props = MLT_CONSUMER_PROPERTIES( consumer );
int64_t playtime = 0;
struct timespec tm = { 0, 100000 };
// int last_position = -1;
- this->refresh_count = 0;
+
+ pthread_mutex_lock( &self->refresh_mutex );
+ self->refresh_count = 0;
+ pthread_mutex_unlock( &self->refresh_mutex );
// Loop until told not to
- while( this->running )
+ while( self->running )
{
// Get a frame from the attached producer
frame = mlt_consumer_rt_frame( consumer );
mlt_events_unblock( consumer_props, consumer_props );
// Play audio
- init_audio = consumer_play_audio( this, frame, init_audio, &duration );
+ init_audio = consumer_play_audio( self, frame, init_audio, &duration );
// Determine the start time now
- if ( this->playing && init_video )
+ if ( self->playing && init_video )
{
// Create the video thread
- pthread_create( &thread, NULL, video_thread, this );
+ pthread_create( &thread, NULL, video_thread, self );
// 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 && speed != 0 && mlt_deque_count( this->queue ) > 15 )
+ while ( self->running && speed != 0 && mlt_deque_count( self->queue ) > 15 )
nanosleep( &tm, NULL );
// Push this frame to the back of the queue
- if ( this->running && speed )
+ if ( self->running && speed )
{
- 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 );
+ pthread_mutex_lock( &self->video_mutex );
+ mlt_deque_push_back( self->queue, frame );
+ pthread_cond_broadcast( &self->video_cond );
+ pthread_mutex_unlock( &self->video_mutex );
// Calculate the next playtime
playtime += ( duration * 1000 );
}
- else if ( this->running )
+ else if ( self->running )
{
- pthread_mutex_lock( &this->refresh_mutex );
- if ( refresh == 0 && this->refresh_count <= 0 )
+ pthread_mutex_lock( &self->refresh_mutex );
+ if ( ( refresh == 0 && self->refresh_count <= 0 ) || self->refresh_count > 1 )
{
- consumer_play_video( this, frame );
- pthread_cond_wait( &this->refresh_cond, &this->refresh_mutex );
+ consumer_play_video( self, frame );
+ pthread_cond_wait( &self->refresh_cond, &self->refresh_mutex );
}
mlt_frame_close( frame );
- this->refresh_count --;
- pthread_mutex_unlock( &this->refresh_mutex );
+ self->refresh_count --;
+ pthread_mutex_unlock( &self->refresh_mutex );
}
else
{
// 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_mutex_lock( &self->video_mutex );
+ pthread_cond_broadcast( &self->video_cond );
+ pthread_mutex_unlock( &self->video_mutex );
pthread_join( thread, NULL );
}
- while( mlt_deque_count( this->queue ) )
- mlt_frame_close( mlt_deque_pop_back( this->queue ) );
+ while( mlt_deque_count( self->queue ) )
+ mlt_frame_close( mlt_deque_pop_back( self->queue ) );
- this->audio_avail = 0;
+ self->audio_avail = 0;
return NULL;
}
static void consumer_close( mlt_consumer parent )
{
// Get the actual object
- consumer_sdl this = parent->child;
+ consumer_sdl self = parent->child;
// Stop the consumer
mlt_consumer_stop( parent );
mlt_consumer_close( parent );
// Close the queue
- mlt_deque_close( this->queue );
+ mlt_deque_close( self->queue );
// Destroy mutexes
- pthread_mutex_destroy( &this->audio_mutex );
- pthread_cond_destroy( &this->audio_cond );
- pthread_mutex_destroy( &this->video_mutex );
- pthread_cond_destroy( &this->video_cond );
- pthread_mutex_destroy( &this->refresh_mutex );
- pthread_cond_destroy( &this->refresh_cond );
+ pthread_mutex_destroy( &self->audio_mutex );
+ pthread_cond_destroy( &self->audio_cond );
+ pthread_mutex_destroy( &self->video_mutex );
+ pthread_cond_destroy( &self->video_cond );
+ pthread_mutex_destroy( &self->refresh_mutex );
+ pthread_cond_destroy( &self->refresh_cond );
// Finally clean up this
- free( this );
+ free( self );
}
language: en
tags:
- Audio
+description: >
+ Simple DirectMedia Layer audio only output module.
+
+parameters:
+ - identifier: volume
+ title: Volume
+ type: float
+ description: Audio level factor.
+ mutable: yes
+
+ - identifier: audio_off
+ title: Audio off
+ type: integer
+ description: If 1, disable audio output
+ mutable: yes
+ minimum: 0
+ maximum: 1
+ default: 0
+ widget: checkbox
+
+ - identifier: audio_buffer
+ title: Audio buffer
+ type: integer
+ description: Size of the sdl audio buffer.
+ mutable: yes
+ default: 2048
+ minimum: 128
+
+ - identifier: scrub_audio
+ title: Audio scrubbing
+ type: integer
+ description: If enabled, sound is played even when the speed is not normal.
+ mutable: yes
+ minimum: 0
+ maximum: 1
+ default: 0
+ widget: checkbox
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 );
+ consumer_sdl this = calloc( 1, sizeof( struct consumer_sdl_s ) );
if ( this != NULL && mlt_consumer_init( &this->parent, this, profile ) == 0 )
{
// Get the parent consumer object
mlt_properties_set( properties, "rescale", "nearest" );
mlt_properties_set( properties, "deinterlace_method", "onefield" );
mlt_properties_set_int( properties, "prefill", 1 );
+ mlt_properties_set_int( properties, "top_field_first", -1 );
+
parent->close = consumer_close;
parent->start = consumer_start;
parent->stop = consumer_stop;
mlt_properties_pass_list( play, properties,
"deinterlace_method,resize,rescale,width,height,aspect_ratio,display_ratio,preview_off,preview_format,window_background"
- ",volume,real_time,buffer,prefill,audio_off,frequency,drop_max" );
+ ",top_field_first,volume,real_time,buffer,prefill,audio_off,frequency,drop_max" );
mlt_properties_pass_list( still, properties,
- "deinterlace_method,resize,rescale,width,height,aspect_ratio,display_ratio,preview_off,preview_format,window_background" );
+ "deinterlace_method,resize,rescale,width,height,aspect_ratio,display_ratio,preview_off,preview_format,window_background"
+ ",top_field_first");
mlt_properties_pass( play, properties, "play." );
mlt_properties_pass( still, properties, "still." );
mlt_frame frame = NULL;
int last_position = -1;
int eos = 0;
- int eos_threshold = 20 + mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( this->play ), "buffer" );
+ int eos_threshold = 20;
+ if ( this->play )
+ eos_threshold = eos_threshold + mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( this->play ), "buffer" );
// Determine if the application is dealing with the preview
int preview_off = mlt_properties_get_int( properties, "preview_off" );
+ pthread_mutex_lock( &this->refresh_mutex );
this->refresh_count = 0;
+ pthread_mutex_unlock( &this->refresh_mutex );
// Loop until told not to
while( this->running )
this->ignore_change = 0;
mlt_consumer_start( this->play );
}
- mlt_consumer_put_frame( this->play, frame );
+ if ( this->play )
+ mlt_consumer_put_frame( this->play, frame );
}
// Copy the rectangle info from the active consumer
int height;
int playing;
int sdl_flags;
- SDL_Surface *sdl_screen;
SDL_Rect rect;
uint8_t *buffer;
int last_position;
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 );
+ consumer_sdl this = calloc( 1, sizeof( struct consumer_sdl_s ) );
// If no malloc'd and consumer init ok
if ( this != NULL && mlt_consumer_init( &this->parent, this, profile ) == 0 )
SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
SDL_EnableUNICODE( 1 );
}
- else if ( preview_off == 0 )
- {
- pthread_mutex_lock( &mlt_sdl_mutex );
- SDL_Surface *screen = SDL_GetVideoSurface( );
- pthread_mutex_unlock( &mlt_sdl_mutex );
- if ( screen != NULL )
- {
- this->sdl_screen = screen;
- }
- }
- if ( this->sdl_screen == NULL && preview_off == 0 )
- {
- pthread_mutex_lock( &mlt_sdl_mutex );
- this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
- pthread_mutex_unlock( &mlt_sdl_mutex );
- }
+ pthread_mutex_lock( &mlt_sdl_mutex );
+ if ( !SDL_GetVideoSurface() && preview_off == 0 )
+ SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
+ pthread_mutex_unlock( &mlt_sdl_mutex );
pthread_create( &this->thread, NULL, consumer_thread, this );
}
SDL_Quit( );
pthread_mutex_unlock( &mlt_sdl_mutex );
}
-
- this->sdl_screen = NULL;
}
return 0;
sdl_lock_display();
// Handle events
- if ( this->sdl_screen != NULL )
+ if ( SDL_GetVideoSurface() )
{
SDL_Event event;
}
}
- if ( this->sdl_screen == NULL || changed )
+ if ( !SDL_GetVideoSurface() || changed )
{
// open SDL window
pthread_mutex_lock( &mlt_sdl_mutex );
- this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
+ SDL_Surface *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 );
+ screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
- uint32_t color = mlt_properties_get_int( this->properties, "window_background" );
- if ( this->sdl_screen )
+ if ( screen )
{
- SDL_FillRect( this->sdl_screen, NULL, color >> 8 );
+ uint32_t color = mlt_properties_get_int( this->properties, "window_background" );
+ SDL_FillRect( screen, NULL, color >> 8 );
changed = 1;
}
pthread_mutex_unlock( &mlt_sdl_mutex );
pthread_mutex_lock( &mlt_sdl_mutex );
SDL_Surface *screen = SDL_GetVideoSurface( );
- if ( !mlt_consumer_is_stopped( &this->parent ) && screen != NULL && this->sdl_screen != NULL && this->sdl_screen->pixels != NULL )
+ if ( !mlt_consumer_is_stopped( &this->parent ) && screen && screen->pixels )
{
- switch( this->sdl_screen->format->BytesPerPixel )
+ switch( screen->format->BytesPerPixel )
{
case 1:
- display_1( this->sdl_screen, this->rect, image, width, height );
+ display_1( screen, this->rect, image, width, height );
break;
case 2:
- display_2( this->sdl_screen, this->rect, image, width, height );
+ display_2( screen, this->rect, image, width, height );
break;
case 3:
- display_3( this->sdl_screen, this->rect, image, width, height );
+ display_3( screen, this->rect, image, width, height );
break;
case 4:
- display_4( this->sdl_screen, this->rect, image, width, height );
+ display_4( screen, this->rect, image, width, height );
break;
default:
- fprintf( stderr, "Unsupported video depth %d\n", this->sdl_screen->format->BytesPerPixel );
+ fprintf( stderr, "Unsupported video depth %d\n", screen->format->BytesPerPixel );
break;
}
// Flip it into sight
- SDL_Flip( this->sdl_screen );
+ SDL_Flip( screen );
}
pthread_mutex_unlock( &mlt_sdl_mutex );
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 );
+ mlt_properties_set_int( properties, "meta.media.width", surface->w );
+ mlt_properties_set_int( properties, "meta.media.height", surface->h );
}
}
else if ( surface != NULL )
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 );
creator: Charles Yates
license: LGPLv2.1
language: en
+notes: DEPRECATED
tags:
- Video
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/sox"
- install -m 644 filter_sox.yml "$(DESTDIR)$(datadir)/mlt/sox"
- install -m 644 filter_sox_effect.yml "$(DESTDIR)$(datadir)/mlt/sox"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/sox"
+ install -m 644 filter_sox.yml "$(DESTDIR)$(mltdatadir)/sox"
+ install -m 644 filter_sox_effect.yml "$(DESTDIR)$(mltdatadir)/sox"
uninstall:
- rm "$(DESTDIR)$(libdir)/mlt/libmltsox$(LIBSUF)" 2> /dev/null || true
- rm -rf "$(DESTDIR)$(datadir)/mlt/sox"
+ rm "$(DESTDIR)$(moduledir)/libmltsox$(LIBSUF)" 2> /dev/null || true
+ rm -rf "$(DESTDIR)$(mltdatadir)/sox"
ifneq ($(wildcard .depend),)
include .depend
// Tokenise the effect specification
mlt_tokeniser_parse_new( tokeniser, value, " " );
if ( tokeniser->count < 1 )
+ {
+ mlt_tokeniser_close( tokeniser );
return error;
+ }
// Locate the effect
mlt_destructor effect_destructor = mlt_pool_release;
OBJS = producer_swfdec.o
ifeq ($(targetos), MinGW)
-LDFLAGS += -enable-auto-import -lz
+LDFLAGS += -Wl,enable-auto-import -lz
endif
SRCS := $(OBJS:.o=.c)
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/swfdec"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/swfdec"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/swfdec"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/swfdec"
ifneq ($(wildcard .depend),)
include .depend
then
pkg-config swfdec-0.9 2> /dev/null
disable_swfdec=$?
+ echo > config.mak
if [ "$disable_swfdec" = "0" ]
then
echo "CFLAGS += $(pkg-config --cflags swfdec-0.9)" >> config.mak
producer_swfdec swfdec = mlt_frame_pop_service( frame );
mlt_service service = MLT_PRODUCER_SERVICE( &swfdec->parent );
mlt_profile profile = mlt_service_profile( service );
- mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
mlt_service_lock( service );
mlt_frame_set_image( frame, *buffer, *width * ( *height + 1 ) * 4, mlt_pool_release );
// Seek
- mlt_position pos = mlt_properties_get_position( properties, "swfdec.position" );
+ mlt_position pos = mlt_frame_original_position( frame );
if ( pos > swfdec->last_position )
{
gulong msec = 1000UL * ( pos - swfdec->last_position ) * profile->frame_rate_den / profile->frame_rate_num;
mlt_properties_set_int( properties, "test_image", 0 );
mlt_properties_set_int( properties, "width", swfdec->width );
mlt_properties_set_int( properties, "height", swfdec->height );
- mlt_properties_set_int( properties, "real_width", swfdec->width );
- mlt_properties_set_int( properties, "real_height", swfdec->height );
mlt_properties_set_int( properties, "progressive", 1 );
mlt_properties_set_double( properties, "aspect_ratio", 1.0 );
- mlt_properties_set_position( properties, "swfdec.position", mlt_producer_frame( producer ) );
// Push the get_image method on to the stack
mlt_frame_push_service( *frame, swfdec );
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d $(DESTDIR)$(datadir)/mlt/videostab
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/videostab"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d $(DESTDIR)$(mltdatadir)/videostab
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/videostab"
ifneq ($(wildcard .depend),)
// Put the analysis results in a property
mlt_geometry_set_length( g, length );
- mlt_properties_set( MLT_FILTER_PROPERTIES( self->parent ), "vectors", mlt_geometry_serialise( g ) );
- mlt_geometry_close( g );
+ mlt_properties_set_data( MLT_FILTER_PROPERTIES( self->parent ), "vectors", g, 0,
+ (mlt_destructor) mlt_geometry_close, (mlt_serialiser) mlt_geometry_serialise );
}
}
mlt_geometry g = mlt_geometry_init();
// Parse the property as a geometry
- if ( !mlt_geometry_parse( g, vectors, length, -1, -1 ) )
+ if ( g && !mlt_geometry_parse( g, vectors, length, -1, -1 ) )
{
struct mlt_geometry_item_s item;
int i;
if ( self )
{
mlt_filter parent = mlt_filter_new();
+ if ( !parent )
+ {
+ free( self );
+ return NULL;
+ }
parent->child = self;
parent->close = filter_close;
parent->process = filter_process;
mlt_position i;
// Initialize geometry item
- item.key = item.f[0] = item.f[1] = 1;
- item.f[2] = item.f[3] = item.f[4] = 1;
+ item.key = item.f[0] = item.f[1] = item.f[2] = item.f[3] = 1;
+ item.f[4] = 0;
tlist* transform_data =self->stab->transs;
for ( i = 0; i < length; i++ )
// Put the analysis results in a property
mlt_geometry_set_length( g, length );
- mlt_properties_set( MLT_FILTER_PROPERTIES( (mlt_filter) self->parent ), "vectors", mlt_geometry_serialise( g ) );
- mlt_geometry_close( g );
+ mlt_properties_set_data( MLT_FILTER_PROPERTIES( (mlt_filter) self->parent ), "vectors", g, 0,
+ (mlt_destructor) mlt_geometry_close, (mlt_serialiser) mlt_geometry_serialise );
}
}
-
-Transform* deserialize_vectors( char *vectors, mlt_position length )
+// scale zoom implements the factor that the vetcors must be scaled since the vector is calulated for real with, now we need it for (scaled)width
+Transform* deserialize_vectors( char *vectors, mlt_position length ,float scale_zoom )
{
mlt_geometry g = mlt_geometry_init();
Transform* tx=NULL;
// Parse the property as a geometry
- if ( !mlt_geometry_parse( g, vectors, length, -1, -1 ) )
+ if ( g && !mlt_geometry_parse( g, vectors, length, -1, -1 ) )
{
struct mlt_geometry_item_s item;
int i;
{
mlt_geometry_fetch( g, &item, i );
Transform t;
- t.x=item.x;
- t.y=item.y;
+ t.x=scale_zoom*item.x;
+ t.y=scale_zoom*item.y;
t.alpha=item.w;
- t.zoom=item.h;
+ t.zoom=scale_zoom*item.h;
t.extra=0;
tx[i]=t;
}
data->initialized = 2;
int interp = 2;
+ float scale_zoom=1.0;
+ if ( *width != mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "meta.media.width" ) )
+ scale_zoom = (float) *width / (float) mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "meta.media.width" );
if ( strcmp( interps, "nearest" ) == 0 || strcmp( interps, "neighbor" ) == 0 )
interp = 0;
else if ( strcmp( interps, "tiles" ) == 0 || strcmp( interps, "fast_bilinear" ) == 0 )
data->trans->optzoom = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter), "optzoom" );
data->trans->sharpen = mlt_properties_get_double( MLT_FILTER_PROPERTIES(filter), "sharpen" );
- transform_configure(data->trans,w,h,*format ,*image, deserialize_vectors( vectors, length ),length);
+ transform_configure(data->trans,w,h,*format ,*image, deserialize_vectors( vectors, length , scale_zoom ),length);
}
if ( data->initialized == 2 )
mlt_filter filter_videostab2_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
videostab2_data* data= calloc( 1, sizeof(videostab2_data));
- data->stab = calloc( 1, sizeof(StabData) );
- data->trans = calloc( 1, sizeof (TransformData) ) ;
if ( data )
{
+ data->stab = calloc( 1, sizeof(StabData) );
+ if ( !data->stab )
+ {
+ free( data );
+ return NULL;
+ }
+
+ data->trans = calloc( 1, sizeof (TransformData) ) ;
+ if ( !data->trans )
+ {
+ free( data->stab );
+ free( data );
+ return NULL;
+ }
+
mlt_filter parent = mlt_filter_new();
+ if ( !parent )
+ {
+ free( data->trans );
+ free( data->stab );
+ free( data );
+ return NULL;
+ }
parent->child = data;
parent->close = filter_close;
- identifier: maxangle
title: Maxangle
type: float
- description: max anglen to rotate (in rad)
+ description: max angle to rotate (in rad)
readonly: no
required: no
minimum: -1
- maximum: 1000
+ maximum: 3.142
default: -1
mutable: yes
widget: spinner
#include <stdlib.h>
#include <math.h>
#include <string.h>
-#if !defined(__DARWIN__) && !defined(__FreeBSD__)
+#if !defined(__DARWIN__) && !defined(__FreeBSD__) && !defined(WIN32) && !defined(__NetBSD__)
#include <values.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
-
+#include <framework/mlt_log.h>
/*********************************************************************
* KLTError
va_list args;
va_start(args, fmt);
- fprintf(stderr, "KLT Error: ");
- vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
+ mlt_log_error(NULL, "KLT Error: ");
+ mlt_log_error(NULL, fmt, args);
+ mlt_log_error(NULL, "\n");
va_end(args);
- exit(1);
}
KLT_TrackingContext KLTCreateTrackingContext()
{
- KLT_TrackingContext tc;
+ KLT_TrackingContext tc = NULL;
/* Allocate memory */
- tc = (KLT_TrackingContext) malloc(sizeof(KLT_TrackingContextRec));
+ tc = (KLT_TrackingContext) calloc(1, sizeof(KLT_TrackingContextRec));
/* Set values to default values */
tc->mindist = 10;
tc->max_residue = 10.0;
tc->grad_sigma = 1.0;
tc->smooth_sigma_fact = 0.1;
- tc->pyramid_sigma_fact = 0.9;\r
- tc->step_factor = 1.0;\r
+ tc->pyramid_sigma_fact = 0.9;
+ tc->step_factor = 1.0;
tc->nSkippedPixels = 0;
tc->pyramid_last = NULL;
tc->pyramid_last_gradx = NULL;
t = null_transform();
num_trans = index; // amount of transforms we actually have
if (num_trans < 1) {
- printf( "too low contrast! No field remains.\n \
- (no translations are detected in frame %i)", sd->t);
+ printf( "too low contrast! No field remains.\n"
+ "(no translations are detected in frame %i)", sd->t);
+ free(ts);
+ free(fs);
+ free(angles);
return t;
}
#ifdef STABVERBOSE
fclose(f);
#endif
+ free(ts);
+ free(fs);
+ free(angles);
return t;
}
/** draws the field scanning area */
void drawFieldScanArea(StabData* sd, const Field* field, const Transform* t)
{
- if (!sd->pixelformat == mlt_image_yuv420p) {
+ if (sd->pixelformat != mlt_image_yuv420p) {
mlt_log_warning (NULL, "format not usable\n");
return;
}
/** draws the field */
void drawField(StabData* sd, const Field* field, const Transform* t)
{
- if (!sd->pixelformat == mlt_image_yuv420p){
+ if (sd->pixelformat != mlt_image_yuv420p){
mlt_log_warning (NULL, "format not usable\n");
return;
}
/** draws the transform data of this field */
void drawFieldTrans(StabData* sd, const Field* field, const Transform* t)
{
- if (!sd->pixelformat == mlt_image_yuv420p){
+ if (sd->pixelformat != mlt_image_yuv420p){
mlt_log_warning (NULL, "format not usable\n");
return;
}
/*************************************************************************/
-/**
- * stabilize_init: Initialize this instance of the module. See
- * tcmodule-data.h for function details.
- */
-int stabilize_init(StabData* instance)
-{
-
- instance = calloc(1,sizeof(StabData)); // allocation with zero values
- if (!instance) {
- return -1;
- }
- return 0;
-}
-
/*
* stabilize_configure: Configure this instance of the module. See
* tcmodule-data.h for function details.
int x, int y, int sizex, int sizey, unsigned char color);
void addTrans(StabData* sd, Transform sl);
-int stabilize_init(StabData* instance);
int stabilize_configure(StabData* instance);
int stabilize_stop(StabData* instance);
unsigned char* img, int width, int height, unsigned char def,unsigned char N, unsigned char channel)
{
// do a simple linear interpolation at the border
- if (x < 1 || x > width-2 || y < 1 || y > height - 2) {
+ if (x < 1 || x >= width-2 || y < 1 || y >= height - 2) {
interpolateBiLinBorder(rv, x,y,img,width,height,def,N,channel);
} else {
int x_f = myfloor(x);
void interpolateSqr(unsigned char *rv, float x, float y,
unsigned char* img, int width, int height, unsigned char def,unsigned char N, unsigned char channel)
{
- if (x < 0 || x > width-1 || y < 0 || y > height - 1) {
+ if (x < 0 || x >= width-1 || y < 0 || y >= height-1) {
interpolateBiLinBorder(rv, x, y, img, width, height, def,N,channel);
} else {
int x_f = myfloor(x);
unsigned char* img, int width, int height,
unsigned char def,unsigned char N, unsigned char channel)
{
- if (x < 0 || x > width-1 || y < 0 || y > height - 1) {
+ if (x < 0 || x >= width-1 || y < 0 || y >= height - 1) {
interpolateBiLinBorder(rv, x, y, img, width, height, def,N,channel);
} else {
int x_f = myfloor(x);
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/vmfx"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/vmfx"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/vmfx"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/vmfx"
ifneq ($(wildcard .depend),)
include .depend
#include <framework/mlt_producer.h>
#include <framework/mlt_geometry.h>
-inline double smoothstep( const double e1, const double e2, const double a )
+static inline double smoothstep( const double e1, const double e2, const double a )
{
if ( a < e1 ) return 0.0;
if ( a > e2 ) return 1.0;
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 );
+ mlt_properties_set_int( properties, "meta.media.width", width );
+ mlt_properties_set_int( properties, "meta.media.height", height );
}
else
{
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 real_width = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "meta.media.width" );
+ int real_height = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "meta.media.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 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 );
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/vorbis"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/vorbis"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/vorbis"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/vorbis"
ifneq ($(wildcard .depend),)
include .depend
char **ptr = ov_comment(ov, -1)->user_comments;
while(*ptr) {
metadata = vorbis_metadata_from_str (*ptr);
- if (metadata != NULL)
+ if (metadata != NULL) {
mlt_properties_set(properties, metadata->name, metadata->content);
+ if (metadata->name)
+ free(metadata->name);
+ if (metadata->content)
+ free(metadata->content);
+ free(metadata);
+ }
++ptr;
}
static int producer_get_audio( mlt_frame frame, void **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" );
+ mlt_position position = mlt_frame_original_position( frame );
// Get the producer
mlt_producer this = mlt_frame_pop_audio( frame );
// 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" );
+ mlt_properties_pass_list( MLT_FRAME_PROPERTIES(*frame), MLT_PRODUCER_PROPERTIES( this ), "frequency, channels" );
// Calculate the next timecode
mlt_producer_prepare_next( this );
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
ifneq ($(wildcard .depend),)
include .depend
#include <string.h>
#include <stdlib.h>
+#define YADIF_MODE_TEMPORAL_SPATIAL (0)
+#define YADIF_MODE_TEMPORAL (2)
+
static yadif_filter *init_yadif( int width, int height )
{
yadif_filter *yadif = mlt_pool_alloc( sizeof( *yadif ) );
int next_height = *height;
mlt_log_debug( MLT_FILTER_SERVICE(filter), "previous %d current %d next %d\n",
- previous_frame? mlt_frame_get_position(previous_frame) : -1,
- mlt_frame_get_position(frame),
- next_frame? mlt_frame_get_position(next_frame) : -1);
+ previous_frame? mlt_frame_original_position(previous_frame) : -1,
+ mlt_frame_original_position(frame),
+ next_frame? mlt_frame_original_position(next_frame) : -1);
if ( !previous_frame || !next_frame )
return 1;
// Get the preceding frame's image
int error = mlt_frame_get_image( previous_frame, &previous_image, format, &previous_width, &previous_height, 0 );
+ int progressive = mlt_properties_get_int( MLT_FRAME_PROPERTIES( previous_frame ), "progressive" );
// Check that we aren't already progressive
- if ( !error && previous_image && *format == mlt_image_yuv422 &&
- !mlt_properties_get_int( MLT_FRAME_PROPERTIES( previous_frame ), "progressive" ) )
+ if ( !error && previous_image && !progressive )
{
+ // OK, now we know we have work to do and can request the image in our format
+ frame->convert_image( previous_frame, &previous_image, format, mlt_image_yuv422 );
+
// Get the current frame's image
+ *format = mlt_image_yuv422;
error = mlt_frame_get_image( frame, image, format, width, height, 0 );
if ( !error && *image && *format == mlt_image_yuv422 )
/** Do it :-).
*/
-static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
int error = 0;
- mlt_properties properties = MLT_FRAME_PROPERTIES( this );
+ mlt_filter filter = mlt_frame_pop_service( frame );
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
int deinterlace = mlt_properties_get_int( properties, "consumer_deinterlace" );
+ // The progressive var should only represent the frame's original state and not the state
+ // as modified by this filter!
int progressive = mlt_properties_get_int( properties, "progressive" );
-
- // Pop the service off the stack
- mlt_filter filter = mlt_frame_pop_service( this );
+ // At this point - before image was requested - (progressive == 0) cannot be trusted because
+ // some producers (avformat) do not yet know.
- // Get the input image
- if ( deinterlace && !progressive )
+ if ( deinterlace )
{
// Determine deinterlace method
char *method_str = mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "method" );
else if ( strcmp( method_str, "greedy" ) == 0 )
method = DEINTERLACE_GREEDY;
- *format = mlt_image_yuv422;
+ // Some producers like pixbuf want rescale_width & _height, but will not get them if you request
+ // the previous image first. So, on the first iteration, we use linearblend.
+ if ( ( method == DEINTERLACE_YADIF || method == DEINTERLACE_YADIF_NOSPATIAL ) &&
+ !mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter), "_notfirst" ) )
+ {
+ mlt_properties_set_int( MLT_FILTER_PROPERTIES(filter), "_notfirst", 1 );
+ method = DEINTERLACE_LINEARBLEND;
+ error = 1;
+ }
if ( method == DEINTERLACE_YADIF )
{
- int mode = 0;
- error = deinterlace_yadif( this, filter, image, format, width, height, mode );
- progressive = mlt_properties_get_int( properties, "progressive" );
+ error = deinterlace_yadif( frame, filter, image, format, width, height, YADIF_MODE_TEMPORAL_SPATIAL );
}
else if ( method == DEINTERLACE_YADIF_NOSPATIAL )
{
- int mode = 2;
- error = deinterlace_yadif( this, filter, image, format, width, height, mode );
- progressive = mlt_properties_get_int( properties, "progressive" );
+ error = deinterlace_yadif( frame, filter, image, format, width, height, YADIF_MODE_TEMPORAL );
}
if ( error || ( method > DEINTERLACE_NONE && method < DEINTERLACE_YADIF ) )
{
- // Signal that we no longer need previous and next frames
mlt_service service = mlt_properties_get_data( MLT_FILTER_PROPERTIES(filter), "service", NULL );
- mlt_properties_set_int( MLT_SERVICE_PROPERTIES(service), "_need_previous_next", 0 );
-
- if ( error )
- method = DEINTERLACE_ONEFIELD;
-
+
// Get the current frame's image
- error = mlt_frame_get_image( this, image, format, width, height, writable );
+ int error2 = mlt_frame_get_image( frame, image, format, width, height, writable );
progressive = mlt_properties_get_int( properties, "progressive" );
- // Check that we aren't already progressive
- if ( !progressive && !error && *image && *format == mlt_image_yuv422 )
+ if ( error )
+ {
+ method = DEINTERLACE_LINEARBLEND;
+ // If YADIF requested, prev/next cancelled because some previous frames were progressive,
+ // but new frames are interlaced, then turn prev/next frames back on.
+ if ( !progressive )
+ mlt_properties_set_int( MLT_SERVICE_PROPERTIES(service), "_need_previous_next", 1 );
+ }
+ else
{
- // Deinterlace the image using one of the Xine deinterlacers
- int image_size = *width * *height * 2;
- uint8_t *new_image = mlt_pool_alloc( image_size );
+ // Signal that we no longer need previous and next frames
+ mlt_properties_set_int( MLT_SERVICE_PROPERTIES(service), "_need_previous_next", 0 );
+ }
+ error = error2;
+
+ if ( !error && !progressive )
+ {
+ // OK, now we know we have work to do and can request the image in our format
+ error = frame->convert_image( frame, image, format, mlt_image_yuv422 );
- deinterlace_yuv( new_image, image, *width * 2, *height, method );
- mlt_frame_set_image( this, new_image, image_size, mlt_pool_release );
- *image = new_image;
+ // Check that we aren't already progressive
+ if ( !error && *image && *format == mlt_image_yuv422 )
+ {
+ // Deinterlace the image using one of the Xine deinterlacers
+ int image_size = *width * *height * 2;
+ uint8_t *new_image = mlt_pool_alloc( image_size );
+
+ deinterlace_yuv( new_image, image, *width * 2, *height, method );
+ mlt_frame_set_image( frame, new_image, image_size, mlt_pool_release );
+ *image = new_image;
+ }
}
}
else if ( method == DEINTERLACE_NONE )
{
- error = mlt_frame_get_image( this, image, format, width, height, writable );
+ error = mlt_frame_get_image( frame, image, format, width, height, writable );
}
-
+
+ // update progressive flag after having obtained image
+ progressive = mlt_properties_get_int( properties, "progressive" );
+
mlt_log_debug( MLT_FILTER_SERVICE( filter ), "error %d deint %d prog %d fmt %s method %s\n",
error, deinterlace, progressive, mlt_image_format_name( *format ), method_str ? method_str : "yadif" );
-
+
if ( !error )
{
// Make sure that others know the frame is deinterlaced
else
{
// Pass through
- error = mlt_frame_get_image( this, image, format, width, height, writable );
+ error = mlt_frame_get_image( frame, image, format, width, height, writable );
}
if ( !deinterlace || progressive )
/** Deinterlace filter processing - this should be lazy evaluation here...
*/
-static mlt_frame deinterlace_process( mlt_filter this, mlt_frame frame )
+static mlt_frame deinterlace_process( mlt_filter filter, mlt_frame frame )
{
- // Push this on to the service stack
- mlt_frame_push_service( frame, this );
+ // Push filter on to the service stack
+ mlt_frame_push_service( frame, filter );
// Push the get_image method on to the stack
mlt_frame_push_get_image( frame, filter_get_image );
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 )
+ mlt_filter filter = mlt_filter_new( );
+ if ( filter != NULL )
{
- this->process = deinterlace_process;
- mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "method", arg );
- mlt_events_listen( MLT_FILTER_PROPERTIES( this ), this, "service-changed", (mlt_listener) on_service_changed );
+ filter->process = deinterlace_process;
+ mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "method", arg );
+ mlt_events_listen( MLT_FILTER_PROPERTIES( filter ), filter, "service-changed", (mlt_listener) on_service_changed );
}
- return this;
+ return filter;
}
"pmaxub %%xmm3, %%xmm2 \n\t"\\r
/*"pshuflw $9,%%xmm2, %%xmm3 \n\t"*/\\r
/*"pshufhw $9,%%xmm2, %%xmm3 \n\t"*/\\r
- "movdqa %%xmm2, %%xmm3 \n\t" /* correct replacement (here) */\
- "psrldq $2, %%xmm3 \n\t"/* for "pshufw $9,%%mm2, %%mm3" - fix by Fizick */\
+ "movdqa %%xmm2, %%xmm3 \n\t" /* correct replacement (here) */\\r
+ "psrldq $2, %%xmm3 \n\t"/* for "pshufw $9,%%mm2, %%mm3" - fix by Fizick */\\r
"punpcklbw %%xmm7, %%xmm2 \n\t" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */\\r
"punpcklbw %%xmm7, %%xmm3 \n\t" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */\\r
"paddw %%xmm2, %%xmm0 \n\t"\\r
\\r
/* if(yadctx->mode<2) ... */\\r
"movdqa %[tmp3], %%xmm6 \n\t" /* diff */\\r
- "cmp $2, %[mode] \n\t"\\r
+ "cmpl $2, %[mode] \n\t"\\r
"jge 1f \n\t"\\r
LOAD8("(%["prev2"],%[mrefs],2)", %%xmm2) /* prev2[x-2*refs] */\\r
LOAD8("(%["next2"],%[mrefs],2)", %%xmm4) /* next2[x-2*refs] */\\r
\
/* if(p->mode<2) ... */\
"movq %[tmp3], %%mm6 \n\t" /* diff */\
- "cmp $2, %[mode] \n\t"\
+ "cmpl $2, %[mode] \n\t"\
"jge 1f \n\t"\
LOAD4("(%["prev2"],%[mrefs],2)", %%mm2) /* prev2[x-2*refs] */\
LOAD4("(%["next2"],%[mrefs],2)", %%mm4) /* next2[x-2*refs] */\
"packuswb %%mm4, %%mm4 \n\t" /* xxxxVVVV */\
"movd %%mm2, (%%edx,%%eax) \n\t" /* store u */\
"add $4, %%eax \n\t" \
- "cmp %%ecx, %%eax \n\t" \
+ "cmpl %%ecx, %%eax \n\t" \
"movd %%mm4, -4(%%esi,%%eax) \n\t" /* store v */\
"jl xloop%= \n\t"\
: : "D"(srcYUY2), "b"(py), "d"(pu), "S"(pv), "c"(widthdiv2) : "%eax");
"punpckhbw %%mm1, %%mm3 \n\t" /* VYUYVYUY */\
"movntq %%mm0, -16(%%edi,%%eax,4) \n\t" /*store */\
"movntq %%mm3, -8(%%edi,%%eax,4) \n\t" /* store */\
- "cmp %%ecx, %%eax \n\t"\
+ "cmpl %%ecx, %%eax \n\t"\
"jl xloop%= \n\t"\
: : "b"(py), "d"(pu), "S"(pv), "D"(dstYUY2), "c"(widthdiv2) : "%eax");
py += pitch_y;
rm -f $(OBJS) $(TARGET)
install: all
- install -m 755 $(TARGET) "$(DESTDIR)$(libdir)/mlt"
- install -d "$(DESTDIR)$(datadir)/mlt/xml"
- install -m 644 mlt-xml.dtd "$(DESTDIR)$(datadir)/mlt/xml"
- install -m 644 *.yml "$(DESTDIR)$(datadir)/mlt/xml"
+ install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)"
+ install -d "$(DESTDIR)$(mltdatadir)/xml"
+ install -m 644 mlt-xml.dtd "$(DESTDIR)$(mltdatadir)/xml"
+ install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/xml"
ifneq ($(wildcard .depend),)
include .depend
#include <locale.h>
#include <libxml/tree.h>
#include <pthread.h>
+#include <wchar.h>
#define ID_SIZE 128
+#define TIME_PROPERTY "_consumer_xml"
#define _x (const xmlChar*)
#define _s (const char*)
char *root;
char *store;
int no_meta;
+ mlt_profile profile;
+ mlt_time_format time_format;
};
typedef struct serialise_context_s* serialise_context;
static void *consumer_thread( void *arg );
static void serialise_service( serialise_context context, mlt_service service, xmlNode *node );
-typedef enum
+static char* filter_restricted( const char *in )
+{
+ if ( !in ) return NULL;
+ size_t n = strlen( in );
+ char *out = calloc( 1, n + 1 );
+ char *p = out;
+ mbstate_t mbs;
+ memset( &mbs, 0, sizeof(mbs) );
+ while ( *in )
+ {
+ wchar_t w;
+ size_t c = mbrtowc( &w, in, n, &mbs );
+ if ( c <= 0 || c > n ) break;
+ n -= c;
+ in += c;
+ if ( w == 0x9 || w == 0xA || w == 0xD ||
+ ( w >= 0x20 && w <= 0xD7FF ) ||
+ ( w >= 0xE000 && w <= 0xFFFD ) ||
+ ( w >= 0x10000 && w <= 0x10FFFF ) )
+ {
+ mbstate_t ps;
+ memset( &ps, 0, sizeof(ps) );
+ c = wcrtomb( p, w, &ps );
+ if ( c > 0 )
+ p += c;
+ }
+ }
+ return out;
+}
+
+typedef enum
{
xml_existing,
xml_producer,
// 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
+ // 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 )
{
mlt_consumer consumer_xml_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 );
+ mlt_consumer this = calloc( 1, sizeof( struct mlt_consumer_s ) );
// If no malloc'd and consumer init ok
if ( this != NULL && mlt_consumer_init( this, NULL, profile ) == 0 )
{
int i;
xmlNode *p;
-
+
// Enumerate the properties
for ( i = 0; i < mlt_properties_count( properties ); i++ )
{
strcmp( name, "width" ) &&
strcmp( name, "height" ) )
{
- char *value = mlt_properties_get_value( properties, i );
- int rootlen = strlen( context->root );
- if ( rootlen && !strncmp( value, context->root, rootlen ) && value[ rootlen ] == '/' )
- value += rootlen + 1;
- p = xmlNewTextChild( node, NULL, _x("property"), _x(value) );
- xmlNewProp( p, _x("name"), _x(name) );
+ char *value = NULL;
+ if ( !strcmp( name, "length" ) )
+ {
+ char *time = mlt_properties_get_time( properties, name, context->time_format );
+ if ( time )
+ value = strdup( time );
+ }
+ else
+ value = filter_restricted( mlt_properties_get_value( properties, i ) );
+ if ( value )
+ {
+ int rootlen = strlen( context->root );
+ // convert absolute path to relative
+ if ( rootlen && !strncmp( value, context->root, rootlen ) && value[ rootlen ] == '/' )
+ p = xmlNewTextChild( node, NULL, _x("property"), _x(value + rootlen + 1 ) );
+ else
+ p = xmlNewTextChild( node, NULL, _x("property"), _x(value) );
+ xmlNewProp( p, _x("name"), _x(name) );
+ free( value );
+ }
}
}
}
{
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 )
+ char *value = filter_restricted( mlt_properties_get_value( properties, i ) );
+ if ( value )
{
int rootlen = strlen( context->root );
+ // convert absolute path to relative
if ( rootlen && !strncmp( value, context->root, rootlen ) && value[ rootlen ] == '/' )
- value += rootlen + 1;
- p = xmlNewTextChild( node, NULL, _x("property"), _x(value) );
+ p = xmlNewTextChild( node, NULL, _x("property"), _x(value + rootlen + 1) );
+ else
+ p = xmlNewTextChild( node, NULL, _x("property"), _x(value) );
xmlNewProp( p, _x("name"), _x(name) );
+ free( value );
}
}
}
int i;
xmlNode *p;
mlt_filter filter = NULL;
-
+
// Enumerate the filters
for ( i = 0; ( filter = mlt_producer_filter( MLT_PRODUCER( service ), i ) ) != NULL; i ++ )
{
char *id = xml_get_id( context, MLT_FILTER_SERVICE( filter ), xml_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) );
- }
+ if ( mlt_properties_get_position( properties, "in" ) )
+ xmlNewProp( p, _x("in"), _x( mlt_properties_get_time( properties, "in", context->time_format ) ) );
+ if ( mlt_properties_get_position( properties, "out" ) )
+ xmlNewProp( p, _x("out"), _x( mlt_properties_get_time( properties, "out", context->time_format ) ) );
serialise_properties( context, properties, p );
serialise_service_filters( context, MLT_FILTER_SERVICE( filter ), p );
}
{
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 );
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" )) );
+ xmlNewProp( child, _x("in"), _x(mlt_properties_get_time( properties, "in", context->time_format )) );
+ xmlNewProp( child, _x("out"), _x(mlt_properties_get_time( properties, "out", context->time_format )) );
serialise_properties( context, properties, child );
serialise_service_filters( context, service, child );
char *id = xml_get_id( context, parent, xml_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" )) );
+ xmlNewProp( node, _x("in"), _x(mlt_properties_get_time( properties, "in", context->time_format )) );
+ xmlNewProp( node, _x("out"), _x(mlt_properties_get_time( properties, "out", context->time_format )) );
}
}
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
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" )) );
+ xmlNewProp( track, _x("in"), _x( mlt_properties_get_time( properties, "in", context->time_format ) ) );
+ xmlNewProp( track, _x("out"), _x( mlt_properties_get_time( properties, "out", context->time_format ) ) );
serialise_store_properties( context, MLT_PRODUCER_PROPERTIES( producer ), track, context->store );
if ( !context->no_meta )
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" ) ) );
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
}
}
}
-
+
child = xmlNewChild( node, NULL, _x("playlist"), NULL );
// Set the id
// 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" );
+ mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );
+ char *service_s = mlt_properties_get( producer_props, "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) );
+ mlt_properties_set_data( producer_props, "_profile", context->profile, 0, NULL, NULL );
+ mlt_properties_set_position( producer_props, TIME_PROPERTY, info.frame_count );
+ xmlNewProp( entry, _x("length"), _x( mlt_properties_get_time( producer_props, TIME_PROPERTY, context->time_format ) ) );
}
else
{
xmlNode *entry = xmlNewChild( child, NULL, _x("entry"), NULL );
id = xml_get_id( context, MLT_SERVICE( producer ), xml_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) );
+ mlt_properties_set_position( producer_props, TIME_PROPERTY, info.frame_in );
+ xmlNewProp( entry, _x("in"), _x( mlt_properties_get_time( producer_props, TIME_PROPERTY, context->time_format ) ) );
+ mlt_properties_set_position( producer_props, TIME_PROPERTY, info.frame_out );
+ xmlNewProp( entry, _x("out"), _x( mlt_properties_get_time( producer_props, TIME_PROPERTY, context->time_format ) ) );
if ( info.repeat > 1 )
{
sprintf( temp, "%d", info.repeat );
{
xmlNode *child = node;
mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
-
+
if ( context->pass == 0 )
{
// Recurse on connected producer
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" )) );
+ xmlNewProp( child, _x("in"), _x(mlt_properties_get_time( properties, "in", context->time_format )) );
+ xmlNewProp( child, _x("out"), _x(mlt_properties_get_time( properties, "out", context->time_format )) );
// Store application specific properties
serialise_store_properties( context, MLT_SERVICE_PROPERTIES( service ), child, context->store );
{
xmlNode *child = node;
mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
-
+
// Recurse on connected producer
serialise_service( context, mlt_service_producer( service ), node );
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" )) );
+ if ( mlt_properties_get_position( properties, "in" ) )
+ xmlNewProp( child, _x("in"), _x( mlt_properties_get_time( properties, "in", context->time_format ) ) );
+ if ( mlt_properties_get_position( properties, "out" ) )
+ xmlNewProp( child, _x("out"), _x( mlt_properties_get_time( properties, "out", context->time_format ) ) );
serialise_properties( context, properties, child );
serialise_service_filters( context, service, child );
{
xmlNode *child = node;
mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
-
+
// Recurse on connected producer
serialise_service( context, MLT_SERVICE( MLT_TRANSITION( service )->producer ), node );
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" )) );
+ if ( mlt_properties_get_position( properties, "in" ) )
+ xmlNewProp( child, _x("in"), _x( mlt_properties_get_time( properties, "in", context->time_format ) ) );
+ if ( mlt_properties_get_position( properties, "out" ) )
+ xmlNewProp( child, _x("out"), _x( mlt_properties_get_time( properties, "out", context->time_format ) ) );
serialise_properties( context, properties, child );
serialise_service_filters( context, service, child );
{
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 )
{
else if ( strcmp( mlt_type, "mlt_producer" ) == 0 )
{
char *resource = mlt_properties_get( properties, "resource" );
-
+
// Recurse on multitrack's tracks
if ( resource && strcmp( resource, "<multitrack>" ) == 0 )
{
serialise_multitrack( context, service, node );
break;
}
-
+
// Recurse on playlist's clips
else if ( resource && strcmp( resource, "<playlist>" ) == 0 )
{
serialise_playlist( context, service, node );
}
-
+
// Recurse on tractor's producer
else if ( resource && strcmp( resource, "<tractor>" ) == 0 )
{
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 );
}
// Assign the additional 'storage' pattern for properties
context->store = mlt_properties_get( MLT_CONSUMER_PROPERTIES( consumer ), "store" );
context->no_meta = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "no_meta" );
+ const char *time_format = mlt_properties_get( MLT_CONSUMER_PROPERTIES( consumer ), "time_format" );
+ if ( time_format && ( !strcmp( time_format, "smpte" ) || !strcmp( time_format, "SMPTE" )
+ || !strcmp( time_format, "timecode" ) ) )
+ context->time_format = mlt_time_smpte;
+ else if ( time_format && ( !strcmp( time_format, "clock" ) || !strcmp( time_format, "CLOCK" ) ) )
+ context->time_format = mlt_time_clock;
// Assign a title property
if ( mlt_properties_get( properties, "title" ) != NULL )
xmlNewProp( profile_node, _x("frame_rate_den"), _x(tmpstr) );
sprintf( tmpstr, "%d", profile->colorspace );
xmlNewProp( profile_node, _x("colorspace"), _x(tmpstr) );
+ context->profile = profile;
}
// 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" );
mlt_properties_close( context->hide_map );
free( context->root );
free( context );
-
+
return doc;
}
maximum: 1
default: 0
widget: checkbox
+
+ - identifier: time_format
+ title: Time format
+ type: string
+ description: Output time-based values as timecode or clock formats.
+ values:
+ - frames
+ - smpte # or SMPTE
+ - timecode # same as smpte
+ - clock # or CLOCK
+ default: frames
+ widget: dropdown
// when the returned producer is closed).
#include <framework/mlt.h>
+#include <framework/mlt_log.h>
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
mlt_consumer consumer;
int multi_consumer;
int consumer_count;
+ int seekable;
+ mlt_consumer qglsl;
};
typedef struct deserialise_context_s *deserialise_context;
{
mlt_service result = NULL;
- *type = invalid_type;
+ if ( type ) *type = invalid_type;
if ( context->stack_service_size > 0 )
{
result = context->stack_service[ -- context->stack_service_size ];
if ( type != NULL )
*type = context->stack_types[ context->stack_service_size ];
+ // Set the service's profile and locale so mlt_property time-to-position conversions can get fps
+ if ( result )
+ {
+ mlt_properties_set_data( MLT_SERVICE_PROPERTIES( result ), "_profile", context->profile, 0, NULL, NULL );
+ mlt_properties_set_lcnumeric( MLT_SERVICE_PROPERTIES( result ), context->lc_numeric );
+ }
}
return result;
}
break;
default:
result = 0;
- fprintf( stderr, "Producer defined inside something that isn't a container\n" );
+ mlt_log_warning( NULL, "[producer_xml] Producer defined inside something that isn't a container\n" );
break;
};
}
else
{
- fprintf( stderr, "Invalid state for tractor\n" );
+ mlt_log_error( NULL, "[producer_xml] Invalid state for tractor\n" );
}
}
}
else
{
- fprintf( stderr, "Invalid multitrack position\n" );
+ mlt_log_error( NULL, "[producer_xml] Invalid multitrack position\n" );
}
}
mlt_service service = context_pop_service( context, &type );
if ( service == NULL || type != mlt_multitrack_type )
- fprintf( stderr, "End multitrack in the wrong state...\n" );
+ mlt_log_error( NULL, "[producer_xml] 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_playlist playlist = mlt_playlist_new( context->profile );
mlt_service service = MLT_PLAYLIST_SERVICE( playlist );
mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
}
else
{
- fprintf( stderr, "Invalid state of playlist end %d\n", type );
+ mlt_log_error( NULL, "[producer_xml] Invalid state of playlist end %d\n", type );
}
}
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;
if ( !producer && resource )
producer = MLT_SERVICE( mlt_factory_producer( context->profile, NULL, resource ) );
if ( !producer )
- fprintf( stderr, "failed to load producer \"%s\"\n", resource );
+ mlt_log_error( NULL, "[producer_xml] failed to load producer \"%s\"\n", resource );
if ( !producer )
producer = MLT_SERVICE( mlt_factory_producer( context->profile, NULL, "+INVALID.txt" ) );
if ( !producer )
if ( !producer )
{
mlt_service_close( service );
+ free( service );
return;
}
// Track this producer
track_service( context->destructors, producer, (mlt_destructor) mlt_producer_close );
mlt_properties_set_lcnumeric( MLT_SERVICE_PROPERTIES( producer ), context->lc_numeric );
+ context->seekable &= mlt_properties_get_int( MLT_SERVICE_PROPERTIES( producer ), "seekable" );
- // Propogate the properties
+ // Propagate the properties
qualify_property( context, properties, "resource" );
qualify_property( context, properties, "luma" );
qualify_property( context, properties, "luma.resource" );
mlt_position out = -1;
// Get in
- if ( mlt_properties_get( properties, "in" ) != NULL )
+ if ( mlt_properties_get( properties, "in" ) )
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" );
- }
+ else if ( mlt_properties_get( properties, "clipBegin" ) )
+ in = mlt_properties_get_position( properties, "clipBegin" );
// Get out
- if ( mlt_properties_get( properties, "out" ) != NULL )
+ if ( mlt_properties_get( properties, "out" ) )
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" );
- }
+ else if ( mlt_properties_get( properties, "clipEnd" ) )
+ out = mlt_properties_get_position( properties, "clipEnd" );
// Remove in and out
mlt_properties_set( properties, "in", NULL );
mlt_properties_set( properties, "out", NULL );
// Push the producer onto the stack
context_push_service( context, producer, mlt_producer_type );
}
+ }
+ if ( service )
+ {
mlt_service_close( service );
+ free( service );
}
}
// 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 )
{
{
if ( xmlStrcmp( atts[0], _x("length") ) == 0 )
{
- length = atoll( _s(atts[1]) );
+ // Append a blank to the playlist
+ mlt_playlist_blank_time( MLT_PLAYLIST( service ), _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" );
+ mlt_log_error( NULL, "[producer_xml] blank without a playlist - a definite no no\n" );
}
}
{
mlt_producer entry = NULL;
mlt_properties temp = mlt_properties_new( );
+ mlt_properties_set_data( temp, "_profile", context->profile, 0, NULL, NULL );
+ mlt_properties_set_lcnumeric( temp, context->lc_numeric );
for ( ; atts != NULL && *atts != NULL; atts += 2 )
{
}
else
{
- fprintf( stderr, "Entry not part of a playlist...\n" );
+ mlt_log_error( NULL, "[producer_xml] Entry not part of a playlist...\n" );
}
context_push_service( context, parent, parent_type );
if ( entry == NULL && entry_type != mlt_entry_type )
{
- fprintf( stderr, "Invalid state at end of entry\n" );
+ mlt_log_error( NULL, "[producer_xml] Invalid state at end of entry\n" );
}
}
else if ( parent_type == mlt_multitrack_type )
multitrack = MLT_MULTITRACK( parent );
else
- fprintf( stderr, "track contained in an invalid container\n" );
+ mlt_log_error( NULL, "[producer_xml] track contained in an invalid container\n" );
if ( multitrack != NULL )
{
if ( parent != NULL )
context_push_service( context, parent, parent_type );
-
- mlt_service_close( track );
}
else
{
- fprintf( stderr, "Invalid state at end of track\n" );
+ mlt_log_error( NULL, "[producer_xml] Invalid state at end of track\n" );
+ }
+
+ if ( track )
+ {
+ mlt_service_close( track );
+ free( track );
}
}
if ( !filter )
{
- fprintf( stderr, "failed to load filter \"%s\"\n", id );
+ mlt_log_error( NULL, "[producer_xml] failed to load filter \"%s\"\n", id );
if ( parent )
context_push_service( context, parent, parent_type );
mlt_service_close( service );
+ free( service );
return;
}
}
else
{
- fprintf( stderr, "filter closed with invalid parent...\n" );
+ mlt_log_error( NULL, "[producer_xml] 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" );
+ mlt_log_error( NULL, "[producer_xml] Invalid top of stack on filter close\n" );
+ }
+
+ if ( service )
+ {
+ mlt_service_close( service );
+ free(service);
}
}
if ( !effect )
{
- fprintf( stderr, "failed to load transition \"%s\"\n", id );
+ mlt_log_error( NULL, "[producer_xml] failed to load transition \"%s\"\n", id );
if ( parent )
context_push_service( context, parent, parent_type );
mlt_service_close( service );
+ free( service );
return;
}
track_service( context->destructors, effect, (mlt_destructor) mlt_transition_close );
}
else
{
- fprintf( stderr, "Misplaced transition - ignoring\n" );
+ mlt_log_warning( NULL, "[producer_xml] Misplaced transition - ignoring\n" );
}
// Put the parent back on the stack
}
else
{
- fprintf( stderr, "transition closed with invalid parent...\n" );
+ mlt_log_error( NULL, "[producer_xml] 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" );
+ mlt_log_error( NULL, "[producer_xml] Invalid top of stack on transition close\n" );
+ }
+
+ if ( service )
+ {
+ mlt_service_close( service );
+ free( service );
}
}
{
if ( context->pass == 1 )
{
- mlt_consumer consumer = mlt_consumer_new( context->profile );
- mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
+ mlt_properties properties = mlt_properties_new();
mlt_properties_set_lcnumeric( properties, context->lc_numeric );
- context_push_service( context, MLT_CONSUMER_SERVICE(consumer), mlt_dummy_consumer_type );
+ context_push_service( context, (mlt_service) properties, mlt_dummy_consumer_type );
// Set the properties from attributes
for ( ; atts != NULL && *atts != NULL; atts += 2 )
{
// Get the consumer from the stack
enum service_type type;
- mlt_service service = context_pop_service( context, &type );
+ mlt_properties properties = (mlt_properties) context_pop_service( context, &type );
- if ( service && type == mlt_dummy_consumer_type )
+ if ( properties && type == mlt_dummy_consumer_type )
{
- mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
qualify_property( context, properties, "resource" );
qualify_property( context, properties, "target" );
char *resource = trim( mlt_properties_get( properties, "resource" ) );
- if ( context->multi_consumer > 1 )
+ if ( context->multi_consumer > 1 || context->qglsl )
{
// Instantiate the multi consumer
if ( !context->consumer )
{
- context->consumer = mlt_factory_consumer( context->profile, "multi", NULL );
+ if ( context->qglsl )
+ context->consumer = context->qglsl;
+ else
+ context->consumer = mlt_factory_consumer( context->profile, "multi", NULL );
if ( context->consumer )
{
// Track this consumer
}
if ( context->consumer )
{
- // Set this service instance on multi consumer
+ // Set this properties object on multi consumer
char key[20];
snprintf( key, sizeof(key), "%d", context->consumer_count++ );
- mlt_properties_set_data( MLT_CONSUMER_PROPERTIES(context->consumer), key, service, 0,
- (mlt_destructor) mlt_service_close, NULL );
+ mlt_properties_inc_ref( properties );
+ mlt_properties_set_data( MLT_CONSUMER_PROPERTIES(context->consumer), key, properties, 0,
+ (mlt_destructor) mlt_properties_close, NULL );
}
}
else
// Inherit the properties
mlt_properties_inherit( MLT_CONSUMER_PROPERTIES(context->consumer), properties );
}
- // Close the dummy
- mlt_service_close( service );
}
}
+ // Close the dummy
+ if ( properties )
+ mlt_properties_close( properties );
}
}
}
else
{
- fprintf( stderr, "Property without a service '%s'?\n", ( const char * )name );
+ mlt_log_error( NULL, "[producer_xml] Property without a service '%s'?\n", ( const char * )name );
}
}
}
else
{
- fprintf( stderr, "Property without a service '%s'??\n", (const char *)name );
+ mlt_log_error( NULL, "[producer_xml] Property without a service '%s'??\n", (const char *)name );
}
}
struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx;
deserialise_context context = ( deserialise_context )( xmlcontext->_private );
-//printf("on_start_element: %s\n", name );
if ( context->pass == 0 )
{
if ( xmlStrcmp( name, _x("mlt") ) == 0 ||
on_start_profile( context, name, atts );
if ( xmlStrcmp( name, _x("consumer") ) == 0 )
context->multi_consumer++;
+
+ // Check for a service beginning with glsl. or movit.
+ for ( ; atts != NULL && *atts != NULL; atts += 2 ) {
+ if ( !xmlStrncmp( atts[1], _x("glsl."), 5 ) || !xmlStrncmp( atts[1], _x("movit."), 6 ) ) {
+ mlt_properties_set_int( context->params, "qglsl", 1 );
+ break;
+ }
+ }
return;
}
context->branch[ context->depth ] ++;
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 && context->pass == 1 && xmlStrcmp( name, _x("property") ) != 0 )
context_pop_node( context );
else if ( xmlStrcmp( name, _x("multitrack") ) == 0 )
{
struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx;
deserialise_context context = ( deserialise_context )( xmlcontext->_private );
- char *value = calloc( len + 1, 1 );
+ char *value = calloc( 1, len + 1 );
enum service_type type;
mlt_service service = context_pop_service( context, &type );
mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
if ( s != NULL )
{
// Append new text to existing content
- char *new = calloc( strlen( s ) + len + 1, 1 );
+ char *new = calloc( 1, strlen( s ) + len + 1 );
strcat( new, s );
strcat( new, value );
mlt_properties_set( properties, context->property, new );
mlt_properties_set( properties, context->property, value );
}
context->entity_is_replace = 0;
-
+
+ // Check for a service beginning with glsl. or movit.
+ if ( !strncmp( value, "glsl.", 5 ) || !strncmp( value, "movit.", 6 ) )
+ mlt_properties_set_int( context->params, "qglsl", 1 );
+
free( value);
}
return e;
}
+static void on_error( void * ctx, const char * msg, ... )
+{
+ struct _xmlError* err_ptr = xmlCtxtGetLastError( ctx );
+
+ switch( err_ptr->level )
+ {
+ case XML_ERR_WARNING:
+ mlt_log_warning( NULL, "[producer_xml] parse warning: %s\trow: %d\tcol: %d\n",
+ err_ptr->message, err_ptr->line, err_ptr->int2 );
+ break;
+ case XML_ERR_ERROR:
+ mlt_log_error( NULL, "[producer_xml] parse error: %s\trow: %d\tcol: %d\n",
+ err_ptr->message, err_ptr->line, err_ptr->int2 );
+ break;
+ default:
+ case XML_ERR_FATAL:
+ mlt_log_fatal( NULL, "[producer_xml] parse fatal: %s\trow: %d\tcol: %d\n",
+ err_ptr->message, err_ptr->line, err_ptr->int2 );
+ break;
+ }
+}
+
/** Convert a hexadecimal character to its value.
*/
static int tohex( char p )
case ':':
case '=':
- url[ i++ ] = '\0';
- value = &url[ i ];
+#ifdef WIN32
+ if ( url[i] == ':' && url[i + 1] != '/' )
+ {
+#endif
+ url[ i++ ] = '\0';
+ value = &url[ i ];
+#ifdef WIN32
+ }
+#endif
break;
case '&':
mlt_producer producer_xml_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 ) );
+ xmlSAXHandler *sax, *sax_orig;
+ struct deserialise_context_s *context;
mlt_properties properties = NULL;
int i = 0;
struct _xmlParserCtxt *xmlcontext;
int well_formed = 0;
char *filename = NULL;
- int info = strcmp( id, "xml-string" ) ? 0 : 1;
+ int is_filename = strcmp( id, "xml-string" );
+
+ // Strip file:// prefix
+ if ( data && strlen( data ) >= 7 && strncmp( data, "file://", 7 ) == 0 )
+ data += 7;
- if ( data == NULL || !strcmp( data, "" ) || ( info == 0 && !file_exists( data ) ) )
+ if ( data == NULL || !strcmp( data, "" ) || ( is_filename && !file_exists( data ) ) )
return NULL;
context = calloc( 1, sizeof( struct deserialise_context_s ) );
context->destructors = mlt_properties_new();
context->params = mlt_properties_new();
context->profile = profile;
+ context->seekable = 1;
// Decode URL and parse parameters
mlt_properties_set( context->producer_map, "root", "" );
- if ( info == 0 )
+ if ( is_filename )
{
filename = strdup( data );
parse_url( context->params, url_decode( filename, data ) );
// We need to track the number of registered filters
mlt_properties_set_int( context->destructors, "registered", 0 );
- // Setup SAX callbacks
+ // Setup SAX callbacks for first pass
+ sax = calloc( 1, sizeof( xmlSAXHandler ) );
sax->startElement = on_start_element;
+ sax->characters = on_characters;
+ sax->warning = on_error;
+ sax->error = on_error;
+ sax->fatalError = on_error;
// 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 )
+ if ( is_filename )
xmlcontext = xmlCreateFileParserCtxt( filename );
else
xmlcontext = xmlCreateMemoryParserCtxt( data, strlen( data ) );
}
// Parse
+ sax_orig = xmlcontext->sax;
xmlcontext->sax = sax;
xmlcontext->_private = ( void* )context;
xmlParseDocument( xmlcontext );
+ well_formed = xmlcontext->wellFormed;
// Cleanup after parsing
- xmlcontext->sax = NULL;
+ xmlcontext->sax = sax_orig;
xmlcontext->_private = NULL;
+ if ( xmlcontext->myDoc )
+ xmlFreeDoc( xmlcontext->myDoc );
xmlFreeParserCtxt( xmlcontext );
context->stack_node_size = 0;
context->stack_service_size = 0;
+ // Bad xml - clean up and return NULL
+ if ( !well_formed )
+ {
+ mlt_properties_close( context->producer_map );
+ mlt_properties_close( context->destructors );
+ mlt_properties_close( context->params );
+ xmlFreeDoc( context->entity_doc );
+ free( context );
+ free( sax );
+ free( filename );
+ return NULL;
+ }
+
// Setup the second pass
context->pass ++;
- if ( info == 0 )
+ if ( is_filename )
xmlcontext = xmlCreateFileParserCtxt( filename );
else
xmlcontext = xmlCreateMemoryParserCtxt( data, strlen( data ) );
return NULL;
}
- // Setup SAX callbacks
+ // Create the qglsl consumer now, if requested, so that glsl.manager
+ // may exist when trying to load glsl. or movit. services.
+ // The "if requested" part can come from query string qglsl=1 or when
+ // a service beginning with glsl. or movit. appears in the XML.
+ if ( mlt_properties_get_int( context->params, "qglsl" ) )
+ context->qglsl = mlt_factory_consumer( profile, "qglsl", NULL );
+
+ // Setup SAX callbacks for second pass
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;
// Parse
+ sax_orig = xmlcontext->sax;
xmlcontext->sax = sax;
xmlcontext->_private = ( void* )context;
xmlParseDocument( xmlcontext );
xmlFreeDoc( context->entity_doc );
free( sax );
xmlMemoryDump( ); // for debugging
+ xmlcontext->sax = sax_orig;
+ xmlcontext->_private = NULL;
+ if ( xmlcontext->myDoc )
+ xmlFreeDoc( xmlcontext->myDoc );
+ xmlFreeParserCtxt( xmlcontext );
// Get the last producer on the stack
enum service_type type;
if ( getenv( "MLT_XML_DEEP" ) == NULL )
{
// Now assign additional properties
- if ( info == 0 )
+ if ( is_filename && (
+ mlt_service_identify( service ) == tractor_type ||
+ mlt_service_identify( service ) == playlist_type ||
+ mlt_service_identify( service ) == multitrack_type ) )
+ {
+ mlt_properties_set_int( properties, "_original_type",
+ mlt_service_identify( service ) );
+ mlt_properties_set( properties, "_original_resource",
+ mlt_properties_get( properties, "resource" ) );
mlt_properties_set( properties, "resource", data );
+ }
// This tells consumer_xml not to deep copy
mlt_properties_set( properties, "xml", "was here" );
mlt_properties_inc_ref( MLT_CONSUMER_PROPERTIES( context->consumer ) );
mlt_properties_set_data( properties, "consumer", context->consumer, 0,
(mlt_destructor) mlt_consumer_close, NULL );
+
+ mlt_properties_set_int( properties, "seekable", context->seekable );
}
else
{
}
// Clean up
+ if ( context->qglsl && context->consumer != context->qglsl )
+ mlt_consumer_close( context->qglsl );
mlt_properties_close( context->producer_map );
if ( context->params != NULL )
mlt_properties_close( context->params );
for subdir in $$list; do \
if [ -x $$subdir/build -a ! -f .$$subdir -o $@ = clean ] ; \
then echo -n Building $$subdir... ; \
- cd $$subdir && output=`./build $@ 2>&1` ; \
+ cd $$subdir && output=`CXXFLAGS="$(CXXFLAGS)" ./build $@ 2>&1` ; \
if [ $$? -eq 0 ] ; \
then echo OK && touch ../.$$subdir ; \
else echo $$output && exit 1 ; \
swig -c++ -I../../mlt++ -I../.. -csharp -dllimport libmltsharp -outdir src_swig -namespace Mlt mlt.i || exit $?
# Compile the wrapper
- g++ -fPIC -D_GNU_SOURCE -c -rdynamic -pthread -I../.. mlt_wrap.cxx || exit $?
+ g++ -fPIC -D_GNU_SOURCE ${CXXFLAGS} -c -rdynamic -pthread -I../.. mlt_wrap.cxx || exit $?
# Create the module
- g++ -shared mlt_wrap.o -L../../mlt++ -lmlt++ -o libmltsharp.so || exit $?
+ g++ ${CXXFLAGS} -shared mlt_wrap.o -L../../mlt++ -lmlt++ -o libmltsharp.so || exit $?
# Compile the library assembly
mcs -out:mlt-sharp.dll -target:library src_swig/*.cs
swig -c++ -I../../mlt++ -I../.. -java -outdir src_swig/org/mltframework -package org.mltframework mlt.i || exit $?
# Compile the wrapper
- g++ -fPIC -D_GNU_SOURCE -c -rdynamic -pthread -I../.. mlt_wrap.cxx $JAVA_INCLUDE || exit $?
+ g++ -fPIC -D_GNU_SOURCE ${CXXFLAGS} -c -rdynamic -pthread -I../.. mlt_wrap.cxx $JAVA_INCLUDE || exit $?
# Create the module
- g++ -shared mlt_wrap.o -L../../mlt++ -lmlt++ -o libmlt_java.so || exit $?
+ g++ ${CXXFLAGS} -shared mlt_wrap.o -L../../mlt++ -lmlt++ -o libmlt_java.so || exit $?
# Compile the test
javac `find src_swig -name '*.java'` || exit $?
swig -c++ -I../../mlt++ -I../.. -lua mlt.i || exit $?
# Compile the wrapper
- g++ -fPIC -DPIC -D_GNU_SOURCE -c -rdynamic -pthread -I../.. mlt_wrap.cxx || exit $?
+ g++ -fPIC -DPIC -D_GNU_SOURCE ${CXXFLAGS} -c -rdynamic -pthread -I../.. mlt_wrap.cxx || exit $?
# Create the module
- g++ -shared mlt_wrap.o -L../../mlt++ -lmlt++ -o mlt.so || exit $?
+ g++ ${CXXFLAGS} -shared mlt_wrap.o -L../../mlt++ -lmlt++ -o mlt.so || exit $?
else
echo Lua not installed.
exit 1
%include <MltParser.h>
%include <MltFilteredConsumer.h>
+
+
#if defined(SWIGRUBY)
%{
class RubyListener
{
- private:
+ protected:
VALUE callback;
Mlt::Event *event;
public:
- RubyListener( Mlt::Properties &properties, char *id, VALUE callback ) :
+ RubyListener( VALUE callback ) : callback( callback )
+ {}
+
+ RubyListener( Mlt::Properties &properties, char *id, VALUE callback ) :
callback( callback )
{
event = properties.listen( id, this, ( mlt_listener )ruby_listener );
}
- ~RubyListener( )
+ virtual ~RubyListener( )
{
delete event;
}
- void mark( )
+ void mark( )
{
((void (*)(VALUE))(rb_gc_mark))( callback );
}
- void doit( )
+ void doit( )
{
ID method = rb_intern( "call" );
rb_funcall( callback, method, 0 );
o->mark( );
}
+static void on_playlist_next( mlt_properties owner, void *object, int i );
+
+class PlaylistNextListener : RubyListener
+{
+ private:
+ Mlt::Event *event;
+
+ public:
+ PlaylistNextListener( Mlt::Properties *properties, VALUE proc )
+ : RubyListener( proc )
+ {
+ event = properties->listen( "playlist-next", this, ( mlt_listener )on_playlist_next );
+ }
+
+ ~PlaylistNextListener()
+ {
+ delete event;
+ }
+
+ void yield( int i )
+ {
+ ID method = rb_intern( "call" );
+ rb_funcall( callback, method, 1, INT2FIX( i ) );
+ }
+};
+
+static void on_playlist_next( mlt_properties owner, void *object, int i )
+{
+ PlaylistNextListener *o = static_cast< PlaylistNextListener * >( object );
+ o->yield( i );
+}
+
%}
// Ruby wrapper
%rename( Listener ) RubyListener;
%markfunc RubyListener "markRubyListener";
+%markfunc PlaylistNextListener "markRubyListener";
-class RubyListener
+class RubyListener
{
public:
RubyListener( Mlt::Properties &properties, char *id, VALUE callback );
};
-#endif
+class PlaylistNextListener
+{
+ public:
+ PlaylistNextListener( Mlt::Properties *properties, VALUE proc );
+};
+
+#endif // SWIGGRUBY
+
+
#if defined(SWIGPYTHON)
%{
system( "swig -c++ -I../../mlt++ -I../.. -perl5 mlt.i" );
WriteMakefile(
'NAME' => 'mlt',
- 'CC' => '${CXX} -fPIC -I../..',
+ 'CC' => '${CXX} -fPIC ${CXXFLAGS} -I../..',
'OPTIMIZE' => '-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions',
'LIBS' => ['-L../../mlt++ -lmlt++'],
'OBJECT' => 'mlt_wrap.o',
exit 0
fi
-perl Makefile.PL || exit 1
+CXXFLAGS="$CXXFLAGS" perl Makefile.PL || exit 1
make
ln -sf ../mlt.i
swig -c++ -I../../mlt++ -I../.. -php5 -noproxy mlt.i
-g++ -fPIC -DPIC -D_GNU_SOURCE -c -rdynamic -pthread -I../.. `php-config --includes` mlt_wrap.cpp
-g++ -shared mlt_wrap.o -L../../mlt++ -lmlt++ -o mlt.so || exit $?
+g++ -fPIC -DPIC -D_GNU_SOURCE ${CXXFLAGS} -c -rdynamic -pthread -I../.. `php-config --includes` mlt_wrap.cpp
+g++ ${CXXFLAGS} -shared mlt_wrap.o -L../../mlt++ -lmlt++ -o mlt.so || exit $?
swig -c++ -I../../mlt++ -I../.. -python mlt.i || exit $?
# Compile the wrapper
- g++ -fPIC -D_GNU_SOURCE -c -rdynamic -pthread -I../.. -I$PYTHON_INCLUDE mlt_wrap.cxx || exit $?
+ g++ -fPIC -D_GNU_SOURCE ${CXXFLAGS} -c -I../.. -I$PYTHON_INCLUDE mlt_wrap.cxx || exit $?
# Create the module
- g++ -shared mlt_wrap.o -L../../mlt++ -lmlt++ -L../../framework -lmlt $(python-config --ldflags) -o _mlt.so || exit $?
+ g++ ${CXXFLAGS} -shared mlt_wrap.o -L../../mlt++ -lmlt++ -L../../framework -lmlt $(python-config --ldflags) -o _mlt.so || exit $?
else
echo Python not installed.
exit 1
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Import required modules
+import mlt
+import time
+import sys
+import tornado.ioloop
+import tornado.web
+
+# Start the mlt system
+mlt.mlt_log_set_level(40) # verbose
+mlt.Factory.init()
+
+# Establish a pipeline
+profile = mlt.Profile("atsc_1080i_5994")
+profile.set_explicit(1)
+tractor = mlt.Tractor()
+tractor.set("eof", "loop")
+fg_resource = "decklink:0"
+bg_resource = "decklink:1"
+if len(sys.argv) > 2:
+ fg_resource = sys.argv[1]
+ bg_resource = sys.argv[2]
+fg = mlt.Producer(profile, fg_resource)
+bg = mlt.Producer(profile, bg_resource)
+tractor.set_track(bg, 0)
+tractor.set_track(fg, 1)
+composite = mlt.Transition(profile, "composite")
+composite.set("fill", 1)
+tractor.plant_transition(composite)
+
+# Setup the consumer
+consumer = "decklink:2"
+if len(sys.argv) > 3:
+ consumer = sys.argv[3]
+consumer = mlt.Consumer(profile, consumer)
+consumer.connect(tractor)
+consumer.set("real_time", -2)
+consumer.start()
+
+flip_flop = False
+def switch():
+ global composite, flip_flop
+ frame = fg.frame() + 2
+ if flip_flop:
+ s = "0=20%%/0:100%%x80%%; %d=20%%/0:100%%x80%%; %d=0/0:100%%x100%%" % (frame, frame + 30)
+ composite.set("geometry", s)
+ else:
+ s = "0=0/0:100%%x100%%; %d=0/0:100%%x100%%; %d=20%%/0:100%%x80%%" % (frame, frame + 30)
+ composite.set("geometry", s)
+ flip_flop = not flip_flop
+
+
+def output_form(handler):
+ handler.write('<form action="/" method="post"><input type="submit" value="Switch"></form>')
+
+class SwitchHandler(tornado.web.RequestHandler):
+ def get(self):
+ switch()
+
+class MainHandler(tornado.web.RequestHandler):
+ def get(self):
+ output_form(self)
+
+ def post(self):
+ switch()
+ output_form(self)
+
+application = tornado.web.Application([
+ (r"/", MainHandler),
+ (r"/switch", SwitchHandler)
+])
+
+application.listen(8888)
+tornado.ioloop.IOLoop.instance().start()
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# webvfx_generator.py
+# Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
+#
+# 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.
+
+# Import required modules
+import mlt
+import time
+import sys
+import tornado.ioloop
+import tornado.web
+import shutil
+import tempfile
+import os
+import os.path
+
+# Start the mlt system
+mlt.mlt_log_set_level(40) # verbose
+mlt.Factory.init()
+
+# Establish a pipeline
+profile = mlt.Profile("atsc_1080i_5994")
+#profile = mlt.Profile('square_ntsc_wide')
+profile.set_explicit(1)
+tractor = mlt.Tractor()
+tractor.set('eof', 'loop')
+playlist = mlt.Playlist()
+playlist.append(mlt.Producer(profile, 'color:'))
+
+# Setup the consumer
+consumer = 'decklink:0'
+if len(sys.argv) > 1:
+ consumer = sys.argv[1]
+consumer = mlt.Consumer(profile, consumer)
+consumer.connect(playlist)
+#consumer.set("real_time", -2)
+consumer.start()
+
+def switch(resource):
+ global playlist
+ resource = resource
+ playlist.lock()
+ playlist.append(mlt.Producer(profile, str(resource)))
+ playlist.remove(0)
+ playlist.unlock()
+
+state = {}
+state['tempdir'] = None
+
+class MainHandler(tornado.web.RequestHandler):
+ def get(self):
+ resource = self.get_argument('url', None)
+ if resource:
+ global state
+
+ self.write('Playing %s\n' % (resource))
+ switch(resource)
+
+ olddir = state['tempdir']
+ if olddir:
+ shutil.rmtree(olddir, True)
+ state['tempdir'] = None
+
+ else:
+ self.write('''
+<p>POST a bunch of files to / to change the output.</p>
+<p>Or GET / with query string parameter "url" to display something from the network.</p>
+''')
+
+ def post(self):
+ if len(self.request.files) == 0:
+ self.write('POST a bunch of files to / to change the output')
+ else:
+ global state
+ olddir = state['tempdir']
+ resource = None
+ state['tempdir'] = tempfile.mkdtemp()
+ for key, items in self.request.files.iteritems():
+ for item in items:
+ path = os.path.dirname(key)
+ fn = item.filename
+ if path:
+ if not os.path.exists(os.path.join(state['tempdir'], path)):
+ os.makedirs(os.path.join(state['tempdir'], path))
+ fn = os.path.join(path, fn)
+ fn = os.path.join(state['tempdir'], fn)
+ if not path and fn.endswith('.html') or fn.endswith('.qml'):
+ resource = fn
+ with open(fn, 'w') as fo:
+ fo.write(item.body)
+ self.write("Uploaded %s\n" % (fn))
+ if resource:
+ self.write('Playing %s\n' % (resource))
+ switch(resource)
+ if olddir:
+ shutil.rmtree(olddir, True)
+
+application = tornado.web.Application([
+ (r"/", MainHandler),
+])
+
+application.listen(8888)
+try:
+ tornado.ioloop.IOLoop.instance().start()
+except:
+ pass
+
+consumer.stop()
+if state['tempdir']:
+ shutil.rmtree(state['tempdir'], True)
end
system( "ln -sf ../mlt.i" )
system( "swig -c++ -ruby -I../../mlt++ -I../.. mlt.i" )
-$CFLAGS += " -I../.."
+$CFLAGS += " -I../.. " + ENV['CXXFLAGS']
$LDFLAGS += " -L../../mlt++ -lmlt++"
create_makefile('mlt')
system( "make" )
#!/usr/bin/env ruby
+require 'erb'
+require 'yaml'
require 'mlt'
$repo = Mlt::Factory::init
+$optional_params = [
+ 'minimum',
+ 'maximum',
+ 'default',
+ 'unit',
+ 'scale',
+ 'format',
+ 'widget'
+]
+template = %q{%%META:TOPICPARENT{name="Plugins<%= type_title %>s"}%
+<noautolink>
+---+ <%= type_title %>: <%= yml['identifier'] %>
+%%TOC%
+---++ Plugin Information
+title: <%= yml['title'] %> %BR%
+% if yml['tags']
+media types:
+% yml['tags'].each do |x|
+<%= x %>
+% end
+%%BR%
+% end
+description: <%= yml['description'] %> %BR%
+version: <%= yml['version'] %> %BR%
+creator: <%= yml['creator'] %> %BR%
+% yml['contributor'] and yml['contributor'].each do |x|
+contributor: <%= x %> %BR%
+% end
+<%= "license: #{yml['license']} %BR%\n" if yml['license'] %>
+<%= "URL: [[#{yml['url']}]] %BR%\n" if yml['url'] %>
+
+% if yml['notes']
+---++ Notes
+% yml['notes'].each do |x|
+<%= x %>
+% end
+% end
+
+% if yml['bugs']
+---++ Bugs
+% yml['bugs'].each do |x|
+ * <%= x %>
+% end
+% end
+
+% if yml['parameters']
+---++ Parameters
+% yml['parameters'].each do |param|
+---+++ <%= param['identifier'] %>
+<%= "title: #{param['title']} %BR%\n" if param['title'] %>
+<%= "description: #{param['description']} %BR%\n" if param['description'] %>
+type: <%= param['type'] %> %BR%
+readonly: <%= param['readonly'] or 'no' %> %BR%
+required: <%= param['required'] or 'no' %> %BR%
+% $optional_params.each do |key|
+<%= "#{key}: #{param[key]} %BR%\n" if param[key] %>
+% end
+% if param['values']
+values:
+% param['values'].each do |value|
+ * <%= value %>
+% end
+% end
+
+% end
+% end
+</noautolink>
+}
+
+$processor = ERB.new(template, 0, "%<>")
+
+
def output(mlt_type, services, type_title)
index = File.open("Plugins#{type_title}s.txt", 'w')
index.puts '%META:TOPICPARENT{name="Documentation"}%'
+ index.puts '<noautolink>'
index.puts "---+ #{type_title} Plugins"
- (0..(services.count - 1)).each {|i|
- name = services.get_name(i)
+ unsorted = []
+ (0..(services.count - 1)).each do |i|
+ unsorted << services.get_name(i)
+ end
+ unsorted.sort().each do |name|
meta = $repo.metadata(mlt_type, name)
if meta.is_valid
filename = type_title + name.capitalize.gsub('.', '-')
- File.open(filename + '.txt', 'w') do |f|
- f.puts %Q/%META:TOPICPARENT{name="Plugins#{type_title}s"}%/
- f.puts "---+ #{type_title} Plugin"
- f.puts "---++ #{name}"
- f.puts '<verbatim>'
- f.puts meta.serialise_yaml
- f.puts '</verbatim>'
- puts "Wrote file #{filename}.txt"
- index.puts " * [[#{filename}][#{name}]]: #{meta.get('title')}\n"
+ puts "Processing #{filename}"
+ yml = YAML.load(meta.serialise_yaml)
+ if yml
+ File.open(filename + '.txt', 'w') do |f|
+ f.puts $processor.result(binding)
+ end
+ else
+ puts "Failed to write file for #{filename}"
end
+ index.puts " * [[#{filename}][#{name}]]: #{meta.get('title')}\n"
end
- }
+ end
+ index.puts '</noautolink>'
index.close
end
--- /dev/null
+#!/usr/bin/env ruby
+
+# Import required modules
+require 'mlt'
+
+# Create the mlt system
+Mlt::Factory::init
+
+# Establish the mlt profile
+profile = Mlt::Profile.new
+
+# Get and check the argument
+file = ARGV.shift
+raise "Usage: test.rb file1 file2" if file.nil?
+file2 = ARGV.shift
+raise "Usage: test.rb file1 file2" if file2.nil?
+
+pls = Mlt::Playlist.new(profile)
+
+# Create the producer
+producer = Mlt::Factory::producer( profile, file )
+raise "Unable to load #{file}" if !producer.is_valid
+
+producer2 = Mlt::Factory::producer( profile, file2 )
+raise "Unable to load #{file2}" if !producer2.is_valid
+
+pls.append(producer)
+#pls.repeat(0, 2)
+pls.append(producer2)
+
+# Create the consumer
+consumer = Mlt::Consumer.new( profile, "sdl" )
+raise "Unable to open sdl consumer" if !consumer.is_valid
+
+# Turn off the default rescaling
+consumer.set( "rescale", "none" )
+consumer.set("volume", 0.1)
+consumer.set("terminate_on_pause", 1)
+
+Mlt::PlaylistNextListener.new(pls, Proc.new { |i|
+ info = pls.clip_info(i)
+ puts "finished playing #{info.resource}\n"
+})
+
+
+# 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( pls )
+
+# Wait until the user stops the consumer
+consumer.wait_for( event )
+
+# Clean up consumer
+consumer.stop
+
swig -c++ -I../../mlt++ -I../.. -tcl mlt.i || exit 1
# Compile the wrapper
- g++ -fPIC -D_GNU_SOURCE -c -rdynamic -pthread -I../.. mlt_wrap.cxx || exit 1
+ g++ -fPIC -D_GNU_SOURCE ${CXXFLAGS} -c -rdynamic -pthread -I../.. mlt_wrap.cxx || exit 1
# Create the module
- g++ -shared mlt_wrap.o -L../../mlt++ -lmlt++ -o mlt.so || exit 1
+ g++ ${CXXFLAGS} -shared mlt_wrap.o -L../../mlt++ -lmlt++ -o mlt.so || exit 1
else
echo "Unable to locate tclsh."
exit 1