]> git.sesse.net Git - mlt/commitdiff
Merge branch 'master' of github.com:mltframework/mlt
authorDan Dennedy <dan@dennedy.org>
Mon, 18 Jun 2012 16:30:05 +0000 (09:30 -0700)
committerDan Dennedy <dan@dennedy.org>
Mon, 18 Jun 2012 16:30:05 +0000 (09:30 -0700)
35 files changed:
ChangeLog
Doxyfile
NEWS
configure
docs/melt.1
src/framework/mlt_cache.c
src/framework/mlt_cache.h
src/framework/mlt_version.h
src/mlt++/configure
src/modules/avformat/configure
src/modules/avformat/producer_avformat.c
src/modules/avformat/producer_avformat.yml
src/modules/decklink/Makefile
src/modules/decklink/common.cpp [new file with mode: 0644]
src/modules/decklink/common.h [new file with mode: 0644]
src/modules/decklink/consumer_decklink.cpp
src/modules/decklink/darwin/DeckLinkAPI.h [new file with mode: 0755]
src/modules/decklink/darwin/DeckLinkAPIDispatch.cpp [new file with mode: 0755]
src/modules/decklink/linux/DeckLinkAPI.h [moved from src/modules/decklink/DeckLinkAPI.h with 100% similarity]
src/modules/decklink/linux/DeckLinkAPIDispatch.cpp [moved from src/modules/decklink/DeckLinkAPIDispatch.cpp with 100% similarity]
src/modules/decklink/linux/LinuxCOM.h [moved from src/modules/decklink/LinuxCOM.h with 100% similarity]
src/modules/decklink/producer_decklink.cpp
src/modules/decklink/win/DeckLinkAPI_h.h [moved from src/modules/decklink/DeckLinkAPI_h.h with 100% similarity]
src/modules/decklink/win/DeckLinkAPI_i.cpp [moved from src/modules/decklink/DeckLinkAPI_i.cpp with 100% similarity]
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
src/modules/jackrack/filter_jackrack.c
src/modules/kdenlive/filter_freeze.c
src/modules/qimage/configure
src/modules/rtaudio/consumer_rtaudio.cpp
src/modules/swfdec/Makefile
src/modules/videostab/stab/estimate.c

index afcd625736b7143236f048410ec32f63254d00c2..7a3c06f35b6be104e7d7e4648dfbe1c1ef55e515 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,477 @@
+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
+
+  * NEWS: add release notes for v0.8.0
+
+  * src/modules/avformat/producer_avformat.c: fix image format regression in
+  avformat caching
+
+  * src/modules/avformat/producer_avformat.c: remove unused alpha_cache member
+
+  * src/modules/avformat/producer_avformat.c: fix video_delay when using
+  new_seek (AVCHD)
+
+  * src/modules/avformat/producer_avformat.c: fix a/v sync after recent change
+  for faster AVCHD seeking
+
+2012-05-31  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/gtk2/scale_line_22_yuv_mmx.S: fix regression in build on 32-bit
+  linux gcc 4.6.1
+
+2012-06-01  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/avformat/producer_avformat.c: fix image format regression in
+  avformat caching
+
+  * src/modules/avformat/producer_avformat.c: remove unused alpha_cache member
+
+  * src/modules/avformat/producer_avformat.c: fix video_delay when using
+  new_seek (AVCHD)
+
+  * src/modules/avformat/producer_avformat.c: fix a/v sync after recent change
+  for faster AVCHD seeking
+
+2012-05-31  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/gtk2/scale_line_22_yuv_mmx.S: fix regression in build on 32-bit
+  linux gcc 4.6.1
+
+2012-05-31  Jean-Baptiste Mardelle <jb@kdenlive.org>
+
+  * src/modules/kdenlive/filter_freeze.c: Fix indentation
+
+2012-05-30  eddrog <eddrog@users.sourceforge.net>
+
+  * src/modules/jackrack/filter_jackrack.c: fix initialize status to zero
+
+2012-05-29  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/avformat/producer_avformat.c: convert avformat producer to use
+  the new mlt_cache_put_frame
+
+  * src/modules/decklink/producer_decklink.cpp: fix decklink producer dropping
+  frames after few hours  mlt_cache_put() was not scalable when using position
+  as a key into the cache. Its reliance upon mlt_properties for
+  reference-counting cache items caused its hash tabe to grow too large after a
+  few hundred thousand frames. This version uses the new mlt_cache_put_frame,
+  which is simpler and more scalable by only using the cache arrays and copying
+  data.
+
+  * 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-22  Jean-Baptiste Mardelle <jb@kdenlive.org>
+
+  * src/modules/kdenlive/filter_freeze.c: Fix filter freeze problem with clip
+  cuts
+
+2012-05-22  eddrog <eddrog@users.sourceforge.net>
+
+  * src/modules/jackrack/filter_jackrack.c: fix unique name problem in
+  filter_jackrack when several filter instances are loaded within one process
+  on evaluating the jack status JackNameNotUnique
+
+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
+
+  * src/modules/plus/interp.h: remove remap functions and document
+  interpolation parameters in English
+
+2012-04-07  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/core/producer_colour.c: fix color:black
+
+  * src/modules/core/transition_luma.c: fix regression due to alpha channels of
+  A and B swapped
+
+  * src/modules/core/producer_colour.c: fix the alpha channel to be opaque on
+  empty string
+
+  * src/modules/plus/transition_affine.c,
+  src/modules/qimage/qimage_wrapper.cpp: fix regressions during refactorization
+
+2012-04-02  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/jackrack/filter_jackrack.c: fix jack-stopped event with some
+  JACK clients  It appears that JackTransportStopped is not received in
+  JackSyncCallback unless the client that calls jack_transport_stop() also
+  calls jack_transport_locate().
+
+  * src/framework/mlt_property.c: fix build for OS X
+
+2012-03-31  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/xml/producer_xml.c: add support for parsing time(code) values
+  to xml producer
+
+  * 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-04-01  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/avformat/producer_avformat.c: make speed of editing AVCHD
+  tolerable  This only works for FFmpeg v0.9.1 or newer but not yet for libav.
+  This uses the image scaling interpolation mode as a hint to perform less
+  (nearest) or more (bilinear or bicubic) diligent seeking. Since most editors
+  are using the SDL consumer with rescale=nearest, this makes scrubbing and
+  cuts/transitions faster. Then, upon encoding, since the avformat consumer
+  uses bilinear by default, it will use the slower, more accurate seeking to
+  ensure the integrity of cuts with an in point. This change has some quirks:
+  frame-stepping backwards sometimes does not update the image, and sometimes a
+  big jump forward shows artifacts.
+
+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-17  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/gtk2/configure: add gdk-pixbuf-2.0 dependency to pango producer
+
+  * src/framework/configure: fix build on OS X 10.6
+
+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
+
+  * src/modules/avformat/producer_avformat.c: fix segfault on failure to decode
+  with multi-threaded decoding  self->got_picture was somewhat redundant with
+  self->av_frame, but not synchronized and not ever really reset. So, just
+  remove that state and use the state of self->av_frame and local got_picture.
+
+2012-03-12  Maksym Veremeyenko <verem@m1stereo.tv>
+
+  * src/modules/avformat/producer_avformat.c: fix playing audio with 0 channels
+
+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.
+
+  * src/modules/qimage/producer_qimage.c: refactor load_filenames in qimage
+
+  * src/modules/gtk2/producer_pixbuf.c: refactor load_filenames in pixbuf
+
+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/modules/plus/transition_affine.c: rename this to transition and affine
+
+  * src/modules/core/transition_composite.c: rename this to self in composite
+  transition
+
+  * src/modules/core/filter_resize.c: rename this to frame and filter
+
+  * src/modules/core/filter_rescale.c: rename this to frame and filter
+
+  * src/modules/core/filter_obscure.c: rename this to filter
+
+  * src/modules/core/filter_crop.c: rename this to frame and filter
+
+  * 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()
+
+  * src/modules/gtk2/producer_pixbuf.c: fix regression in pixbuf setting
+  _real_width and _height for loader
+
+  * src/modules/qimage/qimage_wrapper.cpp: factorize out exif reorientation in
+  qimage producer
+
+  * src/modules/qimage/qimage_wrapper.cpp: remove the cache property from
+  qimage  This is removed in the course of refactorizing to make the code more
+  maintainable for improvements. If you really need to cache an entire image
+  sequence in memory use a ramdisk.
+
+2012-02-29  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/qimage/kdenlivetitle_wrapper.cpp: fix QObject::connect of type
+  QTextCursor errors
+
+2012-02-28  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/gtk2/producer_pixbuf.c: fix regressions caused by refactoring
+  and format conversion
+
+  * src/modules/gtk2/producer_pixbuf.c: convert to and cache requested format
+  in pixbuf  Original idea for patch came from Maksym Veremeyenko.
+
+2012-02-27  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/gtk2/producer_pixbuf.c: split refresh_image() into
+  refresh_pixbuf() and refresh_image()
+
+  * src/modules/core/transition_composite.yml,
+  src/modules/gtk2/producer_pixbuf.yml: couple of small service metadata fixes
+
+2012-02-26  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/gtk2/producer_pixbuf.c: factorize out exif reorientation
+
+  * src/modules/gtk2/producer_pixbuf.c: remove the cache property from pixbuf 
+  This is removed in the course of refactorizing to make the code more
+  maintainable for improvements. If you really need to cache an entire image
+  sequence in memory use a ramdisk.
+
+2012-02-28  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/core/loader.dict: change priority of producers for swf files
+  (3494517)
+
+2012-02-26  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/sdl/consumer_sdl_audio.c: the audio also stutters on Linux when
+  paused
+
+2012-02-25  j-b-m <jb@kdenlive.org>
+
+  * src/modules/avformat/consumer_avformat.c: fix some audio codecs not
+  detected with newer libavcodec
+
+2012-02-22  Dan Dennedy <dan@dennedy.org>
+
+  * src/mlt++/MltProfile.cpp: fix Mlt::Profile::set_frame_rate setting
+  incorrect fields
+
+  * src/modules/avformat/consumer_avformat.c: fix segfault on stop in avformat
+  consumer
+
+  * src/modules/avformat/producer_avformat.c: add meta.media.codec.width and
+  .height
+
+  * 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.
+
+  * src/modules/core/composite_line_yuv_sse2_simple.c: fix asm compilation on
+  some versions of gcc
+
+2012-02-20  Maksym Veremeyenko <verem@m1stereo.tv>
+
+  * src/modules/decklink/producer_decklink.cpp: allow start decklink producer
+  from pause
+
+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
+
+  * src/modules/avformat/producer_avformat.c: fix avformat build on older
+  versions (YUVA444P is new)
+
+2012-02-17  Maksym Veremeyenko <verem@m1stereo.tv>
+
+  * src/modules/avformat/producer_avformat.c: alpha extracting from planar
+  formats
+
+2012-02-16  Maksym Veremeyenko <verem@m1stereo.tv>
+
+  * src/framework/mlt_frame.c: clone alpha on whan cloning image
+
+2012-02-19  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/sdl/consumer_sdl_audio.c: prevent audio from stuttering when
+  paused on Windows
+
+  * src/modules/sdl/consumer_sdl_audio.c: rename this to self
+
+  * configure, src/framework/mlt_version.h: set interim version 0.7.9
+
+2012-02-16  Dan Dennedy <dan@dennedy.org>
+
+  * src/modules/core/transition_luma.c: refactor dissolve_yuv() to use
+  composite_line_yuv()
+
+  * 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/transition_composite.c: fix rounding causes by -ffast-math
+
+  * 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>
 
+  * ChangeLog: update ChangeLog for v0.7.8
+
   * Doxyfile, configure, docs/melt.1, src/framework/mlt_version.h,
   src/melt/melt.c: set version to 0.7.8
 
index 37e14b50800bbd0a30fc5cb3dab0e1cfb1df20e5..4f59abd83e81f1ef42621dbcc5be230b31ff6cb0 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME = mlt
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER = 0.7.8
+PROJECT_NUMBER = 0.8.0
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 
diff --git a/NEWS b/NEWS
index c3fe86a69073b3a2fe6bee59b26127a17e45e970..250af2534f2a78c950de64e9cc507597bbff9f44 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,21 @@
 MLT Release Notes
 -----------------
 
+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.
index 89307f346b9c671a8e39d714786f79d5b97c69a9..7523ac7d937fd9e50259f1e0ef2da959f77e87f2 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-export version=0.7.9
+export version=0.8.1
 export soversion=5
 
 show_help()
@@ -27,6 +27,8 @@ General build options:
   --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:
 
@@ -69,6 +71,7 @@ build_config()
 
                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" ]
@@ -84,13 +87,11 @@ build_config()
 
                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"
@@ -100,7 +101,6 @@ build_config()
                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"
@@ -109,7 +109,6 @@ build_config()
                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"
@@ -118,7 +117,6 @@ build_config()
                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"
@@ -193,33 +191,15 @@ export gpl=false
 export gpl3=false
 export arch=
 export cpu=
-export targetos=
-
-# Determine OS
-targetos=$(uname -s)
-# Chose appropriate suffix for libraries
-case $targetos in
-       Darwin)
-       LIBSUF=".dylib"
-       ;;
-       Linux|FreeBSD|NetBSD)
-       LIBSUF=".so"
-       ;;
-       MINGW32_NT-*)
-       targetos="MinGW"
-       LIBSUF=".dll"
-       ;;
-       *)
-       LIBSUF=".so"
-       ;;
-esac
-export LIBSUF
+export targetos=$(uname -s)
+export targetarch=
+export amd64=false
 
 # Iterate through arguments
 for i in "$@"
 do
        case $i in
-               --help )                        help=1 ;;
+               --help )                help=1 ;;
                --prefix=* )            prefix="${i#--prefix=}" ;;
                --libdir=* )            libdir="${i#--libdir=}" ;;
                --datadir=* )           datadir="${i#--datadir=}" ;;
@@ -231,11 +211,40 @@ do
                --disable-sse2 )        sse2=false ;;
                --enable-gpl )          gpl=true ;;
                --enable-gpl3 )         gpl3=true ;;
-               --arch=* )                      arch="${i#--arch=}" ;;
-               --cpu=* )                       cpu="${i#--cpu=}" ;;
+               --arch=* )              arch="${i#--arch=}" ;;
+               --cpu=* )               cpu="${i#--cpu=}" ;;
+               --target-os=* )         targetos="${i#--target-os=}" ;;
+               --target-arch=* )       targetarch="${i#--target-arch=}" ;;
        esac
 done
 
+# 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-*|MinGW|mingw)
+       targetos="MinGW"
+       LIBSUF=".dll"
+       ;;
+       *)
+       LIBSUF=".so"
+       ;;
+esac
+export LIBSUF
+
+# 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
index 44ab153554db16302ff031880c0d80813372c5ec..9c0366c195e63e7075b8b364aca1ef1bb81060e5 100644 (file)
@@ -1,5 +1,5 @@
 .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.38.4.
-.TH MELT "1" "February 2012" "melt 0.7.8" "User Commands"
+.TH MELT "1" "June 2012" "melt 0.8.0" "User Commands"
 .SH NAME
 melt \- author, play, and encode multitrack audio/video compositions
 .SH SYNOPSIS
index 250ea4156994203b1c4c4fbf7ea6df176ce00bce..7938f79e2d18a48008f0219af803d2dc3689235b 100644 (file)
@@ -1,9 +1,9 @@
 /**
- * \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
@@ -25,6 +25,7 @@
 #include "mlt_log.h"
 #include "mlt_properties.h"
 #include "mlt_cache.h"
+#include "mlt_frame.h"
 
 #include <stdlib.h>
 #include <pthread.h>
@@ -336,6 +337,11 @@ static void** shuffle_get_hit( mlt_cache cache, void *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
@@ -451,3 +457,137 @@ mlt_cache_item mlt_cache_get( mlt_cache cache, void *object )
        
        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_get_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_get_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_get_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;
+       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;
+}
index fb0cca6a048c9e60f1a1e7c68facb6cb38089288..cd26522cdfbccf8df58a2089383757374a16349b 100644 (file)
@@ -3,7 +3,7 @@
  * \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
@@ -36,5 +36,7 @@ extern void mlt_cache_close( mlt_cache cache );
 extern void mlt_cache_purge( mlt_cache cache, void *object );
 extern void mlt_cache_put( mlt_cache cache, void *object, void* data, int size, mlt_destructor destructor );
 extern mlt_cache_item mlt_cache_get( mlt_cache cache, void *object );
+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
index b275c941c7d916af040b66082f8b506490661330..7cf3af25238315fb52dc0f53ad1559cdc57576d1 100644 (file)
@@ -28,8 +28,8 @@
 #define STRINGIZE(s)            STRINGIZE2(s)
 
 #define LIBMLT_VERSION_MAJOR    0
-#define LIBMLT_VERSION_MINOR    7
-#define LIBMLT_VERSION_REVISION 9
+#define LIBMLT_VERSION_MINOR    8
+#define LIBMLT_VERSION_REVISION 1
 #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)
 
index 98e470af90d2fa6d59949a27e307de51bb58fd0e..0a4d37a187b657ca7bb63420b693f3a7d7b7bb81 100755 (executable)
@@ -18,6 +18,6 @@ case $targetos in
        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
index 5e3a7a245da00950d4e7c9e5c1d047025b998260..c64cec83092b11f6e72b94567d95b6fc58f60b7b 100755 (executable)
@@ -3,8 +3,8 @@
 # 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="0.9.2"
+libav_ver="0.8.2"
 micro_version=$(echo $version | cut -d . -f 3)
 odd_version=$(($micro_version % 2))
 [ "$odd_version" -eq "1" ] && ffmpeg_ver="HEAD" && libav_ver="HEAD"
index 8983ebd6587817936ca24d69a89cc9b77a0bc893..fc21d02c0b9ec94e96728f0f08d97f9bd59361c7 100644 (file)
@@ -96,7 +96,7 @@ struct producer_avformat_s
        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;
@@ -114,7 +114,6 @@ struct producer_avformat_s
        unsigned int invalid_pts_counter;
        double resample_factor;
        mlt_cache image_cache;
-       mlt_cache alpha_cache;
        int colorspace;
        pthread_mutex_t video_mutex;
        pthread_mutex_t audio_mutex;
@@ -893,7 +892,7 @@ static int producer_open( producer_avformat self, mlt_profile profile, const cha
                        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 )
@@ -1017,7 +1016,7 @@ static void reopen_video( producer_avformat self, mlt_producer producer )
 }
 
 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, int use_pts )
 {
        mlt_producer producer = self->parent;
        int paused = 0;
@@ -1039,75 +1038,61 @@ static int seek_video( producer_avformat self, mlt_position position,
                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->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 ) )
+               // find initial PTS
+               if ( self->last_position == POSITION_INITIAL )
                {
-                       if ( use_new_seek && self->last_position == POSITION_INITIAL )
-                       {
-                               // find first key frame
-                               int ret = 0;
-                               int toscan = 100;
-                               AVPacket pkt;
+                       int ret = 0;
+                       int toscan = 100;
+                       AVPacket pkt;
 
-                               while ( ret >= 0 && toscan-- > 0 )
+                       while ( ret >= 0 && toscan-- > 0 )
+                       {
+                               ret = av_read_frame( context, &pkt );
+                               if ( ret >= 0 && pkt.stream_index == self->video_index )
                                {
-                                       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;
+                                       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 = use_pts? pkt.pts : pkt.dts;
+                                       if ( self->first_pts != AV_NOPTS_VALUE )
                                                toscan = 0;
-                                       }
-                                       av_free_packet( &pkt );
                                }
-                               // Rewind
-                               av_seek_frame( context, -1, 0, AVSEEK_FLAG_BACKWARD );
+                               av_free_packet( &pkt );
                        }
+                       av_seek_frame( context, -1, 0, AVSEEK_FLAG_BACKWARD );
+               }
 
+               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 >= 12 || self->last_position < 0 ) )
+               {
                        // 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( stream->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( stream->time_base ) != 0 )
+                               timestamp -= 2 / av_q2d( stream->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 || use_pts || 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
                        {
@@ -1121,12 +1106,6 @@ static int seek_video( producer_avformat self, mlt_position position,
                        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;
@@ -1421,14 +1400,23 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        if ( ! self->image_cache && ! mlt_properties_get_int( properties, "noimagecache" ) )
        {
                self->image_cache = mlt_cache_init();
-               self->alpha_cache = mlt_cache_init();
        }
        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, mlt_frame_get_position( frame ) );
                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;
@@ -1437,33 +1425,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                        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 );
-                       }
                        got_picture = 1;
-
-                       // check for alpha
-                       item = mlt_cache_get( self->alpha_cache, (void*) position );
-                       original = mlt_cache_item_data( item, &size );
-                       if ( original )
-                       {
-                               alpha = mlt_pool_alloc( size );
-                               memcpy( alpha, original, size );
-                               mlt_cache_item_close( item );
-                       }
-
                        goto exit_get_image;
                }
        }
@@ -1472,9 +1434,6 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        // 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" ) /
                mlt_properties_get_double( properties, "meta.media.frame_rate_den" );
@@ -1492,20 +1451,20 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                                  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" );
+       int use_pts = self->seekable &&
+               codec_context->codec_id == CODEC_ID_H264 && codec_context->has_b_frames;
+       if ( mlt_properties_get( properties, "use_pts" ) )
+               use_pts = mlt_properties_get_int( properties, "use_pts" );
        double delay = mlt_properties_get_double( properties, "video_delay" );
 
        // Seek if necessary
        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)
-               && ( !use_new_seek || ( interp && strcmp( interp, "nearest" ) ) )
+               && ( !use_pts || ( interp && strcmp( interp, "nearest" ) ) )
 #endif
                && codec_context->has_b_frames;
-       int paused = seek_video( self, position, req_position, preseek, use_new_seek, &ignore );
+       int paused = seek_video( self, position, req_position, preseek, use_pts );
 
        // Seek might have reopened the file
        context = self->video_format;
@@ -1520,9 +1479,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 
        // Duplicate the last image if necessary
        if ( self->av_frame && self->av_frame->linesize[0]
-                && ( paused
-                         || self->current_position == req_position
-                         || ( !use_new_seek && self->current_position > req_position ) ) )
+                && ( paused || self->current_position >= req_position ) )
        {
                // Duplicate it
                if ( ( image_size = allocate_buffer( frame, codec_context, buffer, format, width, height ) ) )
@@ -1591,50 +1548,42 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                        if ( ret >= 0 && pkt.stream_index == self->video_index && pkt.size > 0 )
                        {
                                // Determine time code of the packet
-                               if ( use_new_seek )
+                               if ( pkt.pts == AV_NOPTS_VALUE )
                                {
-                                       int64_t pts = pkt.pts;
-                                       if ( self->first_pts > 0 )
-                                               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++;
+                                       if ( self->invalid_pts_counter > 20 )
                                        {
-                                               self->invalid_pts_counter = 0;
+                                               mlt_log_warning( MLT_PRODUCER_SERVICE(producer), "PTS invalid; using DTS instead\n" );
+                                               mlt_properties_set_int( properties, "use_pts", 0 );
+                                               use_pts = 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 );
                                }
                                else
                                {
-                                       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!" );
-                                       }
+                                       self->invalid_pts_counter = 0;
+                               }
+                               int64_t pts = ( use_pts && pkt.pts != AV_NOPTS_VALUE )? pkt.pts : pkt.dts;
+                               if ( pts != AV_NOPTS_VALUE )
+                               {
+                                       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.5 );
+                                       if ( int_position == self->last_position )
+                                               int_position = self->last_position + 1;
+                               }
+                               mlt_log_debug( MLT_PRODUCER_SERVICE(producer),
+                                       "V 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 );
+
+                               // Make a dumb assumption on streams that contain wild timestamps
+                               if ( abs( req_position - int_position ) > 999 )
+                               {
+                                       int_position = req_position;
+                                       mlt_log_warning( MLT_PRODUCER_SERVICE(producer), " WILD TIMESTAMP!\n" );
                                }
                                self->last_position = int_position;
 
@@ -1651,7 +1600,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                                                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))
@@ -1673,32 +1622,14 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 
                                if ( got_picture )
                                {
-                                       if ( use_new_seek )
-                                       {
-                                               // Determine time code of the packet
-                                               int64_t pts = self->av_frame->reordered_opaque;
-                                               if ( self->first_pts > 0 )
-                                                       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 );
-                                       }
-                                       // Handle ignore
+                                       if ( use_pts )
+                                               // Get position of reordered frame
+                                               int_position = self->av_frame->reordered_opaque;
+
                                        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 );
                        }
@@ -1765,19 +1696,14 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                }
        }
 
+       // 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 );
-               if ( alpha )
-               {
-                       int alpha_size = (*width) * (*height);
-                       image = mlt_pool_alloc( alpha_size );
-                       memcpy( image, alpha, alpha_size );
-                       mlt_cache_put( self->alpha_cache, (void*) position, image, alpha_size, 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
@@ -1837,10 +1763,6 @@ exit_get_image:
        mlt_properties_set_int( properties, "meta.media.progressive", mlt_properties_get_int( frame_properties, "progressive" ) );
        mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
 
-       // set alpha
-       if ( alpha )
-               mlt_frame_set_alpha( frame, alpha, (*width) * (*height), mlt_pool_release );
-
        return !got_picture;
 }
 
@@ -2120,7 +2042,7 @@ static void producer_set_up_video( producer_avformat self, mlt_frame frame )
        }
 }
 
-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;
 
@@ -2132,11 +2054,6 @@ static int seek_audio( producer_avformat self, mlt_position position, double tim
                        // 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;
@@ -2257,11 +2174,18 @@ static int decode_audio( producer_avformat self, int *ignore, AVPacket pkt, int
        // 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 != 0 )
+                       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 )
                {
@@ -2270,7 +2194,7 @@ static int decode_audio( producer_avformat self, int *ignore, AVPacket pkt, int
                                *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 );
                }
        }
 
@@ -2301,7 +2225,7 @@ static int producer_get_audio( mlt_frame frame, void **buffer, mlt_audio_format
        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;
@@ -2769,8 +2693,6 @@ static void producer_avformat_close( producer_avformat self )
 #endif
        if ( self->image_cache )
                mlt_cache_close( self->image_cache );
-       if ( self->alpha_cache )
-               mlt_cache_close( self->alpha_cache );
 
        // Cleanup the mutexes
        pthread_mutex_destroy( &self->audio_mutex );
index 459a590074abd917d1bab96f025c862e46d9205d..c2a56133fc56a949bac08cf7f2f40fd61a0baea6 100644 (file)
@@ -2,7 +2,7 @@ schema_version: 0.1
 type: producer
 identifier: avformat
 title: FFmpeg Reader
-version: 1
+version: 2
 copyright: Copyright (C) 2003-2011 Ushodaya Enterprises Limited
 license: LGPL
 language: en
@@ -119,11 +119,13 @@ parameters:
     default: 0
     widget: checkbox
 
-  - identifier: new_seek
-    title: Use new seeking
+  - identifier: use_pts
+    title: Use video PTS
     description: >
-      When this is not provided (recommended), it is enabled only for H.264 in
-      MPEG-2 Transport Streams.
+      Try to use video PTS instead of DTS for seeking and A/V synchronization.
+      This is only enabled by default for H.264 with B pictures.
+      It is recommended to not use this, in general, but it might be helpful
+      to explicity enable or disable it for some videos.
     type: integer
     minimum: 0
     maximum: 1
index b04ff393b60d9d0e1856913e86a9800e65f32698..3695d5fa6b61bd9e157fe9d36381f94c069bc3aa 100755 (executable)
@@ -7,13 +7,21 @@ include ../../../config.mak
 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)
diff --git a/src/modules/decklink/common.cpp b/src/modules/decklink/common.cpp
new file mode 100644 (file)
index 0000000..83f5e53
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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
+
diff --git a/src/modules/decklink/common.h b/src/modules/decklink/common.h
new file mode 100644 (file)
index 0000000..3b48b9c
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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
index 8260321bc7fd37ea0dcbe6cd0a1b1718e2dd5def..ee9ce7a8396b721517ce4acdc47e66178c336037 100644 (file)
 #include <sys/time.h>
 #include <limits.h>
 #include <pthread.h>
-#ifdef WIN32
-#include <objbase.h>
-#include "DeckLinkAPI_h.h"
-#else
-#include "DeckLinkAPI.h"
-typedef const char* BSTR;
-#endif
-
-#define SAFE_RELEASE(V) if (V) { V->Release(); V = NULL; }
+#include "common.h"
 
 static const unsigned PREROLL_MINIMUM = 3;
 
@@ -70,7 +62,7 @@ private:
                IDeckLinkDisplayModeIterator* iter = NULL;
                IDeckLinkDisplayMode* mode = NULL;
                IDeckLinkDisplayMode* result = 0;
-               
+
                if ( m_deckLinkOutput->GetDisplayModeIterator( &iter ) == S_OK )
                {
                        while ( !result && iter->Next( &mode ) == S_OK )
@@ -81,7 +73,7 @@ private:
                                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 )
                                         && ( m_height == profile->height || ( m_height == 486 && profile->height == 480 ) ) )
@@ -91,10 +83,10 @@ private:
                        }
                        SAFE_RELEASE( iter );
                }
-               
+
                return result;
        }
-       
+
 public:
        mlt_consumer getConsumer()
                { return &m_consumer; }
@@ -105,6 +97,7 @@ public:
                m_deckLinkKeyer = NULL;
                m_deckLinkOutput = NULL;
                m_deckLink = NULL;
+               m_decklinkFrame = NULL;
        }
 
        ~DeckLinkConsumer()
@@ -114,7 +107,7 @@ public:
                SAFE_RELEASE( m_deckLinkOutput );
                SAFE_RELEASE( m_deckLink );
        }
-       
+
        bool open( unsigned card = 0 )
        {
                unsigned i = 0;
@@ -134,7 +127,7 @@ public:
                }
 #else
                IDeckLinkIterator* deckLinkIterator = CreateDeckLinkIteratorInstance();
-               
+
                if ( !deckLinkIterator )
                {
                        mlt_log_error( getConsumer(), "The DeckLink drivers not installed.\n" );
@@ -164,7 +157,7 @@ public:
                        SAFE_RELEASE( m_deckLink );
                        return false;
                }
-               
+
                // Get the keyer interface
                IDeckLinkAttributes *deckLinkAttributes = 0;
                if ( m_deckLink->QueryInterface( IID_IDeckLinkAttributes, (void**) &deckLinkAttributes ) == S_OK )
@@ -189,7 +182,7 @@ public:
 
                // Provide this class as a delegate to the audio and video output interfaces
                m_deckLinkOutput->SetScheduledFrameCompletionCallback( this );
-               
+
                return true;
        }
 
@@ -232,7 +225,7 @@ public:
                        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" ) ) )
                {
@@ -281,7 +274,7 @@ public:
 
                return true;
        }
-       
+
        bool stop()
        {
                mlt_properties properties = MLT_CONSUMER_PROPERTIES( getConsumer() );
@@ -357,7 +350,7 @@ public:
                        stop();
                        return false;
                }
-               
+
                // Make the first line black for field order correction.
                if ( S_OK == frame->GetBytes( (void**) &buffer ) && buffer )
                {
@@ -476,7 +469,7 @@ public:
 
                return result;
        }
-       
+
        // *** DeckLink API implementation of IDeckLinkVideoOutputCallback IDeckLinkAudioOutputCallback *** //
 
        // IUnknown needs only a dummy implementation
@@ -486,9 +479,9 @@ public:
                { return 1; }
        virtual ULONG STDMETHODCALLTYPE Release()
                { return 1; }
-       
+
        /************************* DeckLink API Delegate Methods *****************************/
-       
+
        virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted( IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult completed )
        {
                if( !m_reprio )
@@ -570,7 +563,7 @@ public:
        {
                return mlt_consumer_is_stopped( getConsumer() ) ? S_FALSE : S_OK;
        }
-       
+
 
        void ScheduleNextFrame( bool preroll )
        {
@@ -678,16 +671,18 @@ static void on_property_changed( void*, mlt_properties properties, const char *n
        {
                if ( decklink->QueryInterface( IID_IDeckLinkOutput, (void**) &decklinkOutput ) == S_OK )
                {
-                       char *name = NULL;
-                       if ( decklink->GetModelName( (BSTR*) &name ) == 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 );
+                               mlt_properties_set( properties, key, name_cstr );
                                free( key );
-                               free( name );
+                               freeDLString( name );
+                               freeCString( name_cstr );
                        }
                        SAFE_RELEASE( decklinkOutput );
                }
diff --git a/src/modules/decklink/darwin/DeckLinkAPI.h b/src/modules/decklink/darwin/DeckLinkAPI.h
new file mode 100755 (executable)
index 0000000..17eb6da
--- /dev/null
@@ -0,0 +1,1162 @@
+/* -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__
diff --git a/src/modules/decklink/darwin/DeckLinkAPIDispatch.cpp b/src/modules/decklink/darwin/DeckLinkAPIDispatch.cpp
new file mode 100755 (executable)
index 0000000..368351a
--- /dev/null
@@ -0,0 +1,131 @@
+/* -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();
+}
+
index ca4b2478aeb7406d43b65c2a288c520907aa2396..6a8492be057f82af50ee784afae04d17506855a0 100644 (file)
 #include <unistd.h>
 #include <limits.h>
 #include <sys/time.h>
-#ifdef WIN32
-#include <objbase.h>
-#include "DeckLinkAPI_h.h"
-#else
-#include "DeckLinkAPI.h"
-typedef const char* BSTR;
-#endif
-
-#define SAFE_RELEASE(V) if (V) { V->Release(); V = NULL; }
+#include "common.h"
 
 class DeckLinkProducer
        : public IDeckLinkInputCallback
@@ -95,6 +87,7 @@ public:
 
        DeckLinkProducer()
        {
+               m_producer = NULL;
                m_decklink = NULL;
                m_decklinkInput = NULL;
        }
@@ -250,6 +243,8 @@ public:
                pthread_mutex_unlock( &m_mutex );
 
                m_decklinkInput->StopStreams();
+               m_decklinkInput->DisableVideoInput();
+               m_decklinkInput->DisableAudioInput();
 
                // Cleanup queue
                pthread_mutex_lock( &m_mutex );
@@ -260,12 +255,11 @@ public:
 
        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 )
@@ -290,13 +284,7 @@ public:
                        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 );
@@ -317,8 +305,10 @@ public:
 
                        // 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
@@ -437,15 +427,16 @@ public:
                        IDeckLinkTimecode* timecode = 0;
                        if ( video->GetTimecode( bmdTimecodeVITC, &timecode ) == S_OK && timecode )
                        {
-                               const char* timecodeString = 0;
+                               DLString timecodeString = 0;
 
-                               if ( timecode->GetString( (BSTR*) &timecodeString ) == S_OK )
+                               if ( timecode->GetString( &timecodeString ) == S_OK )
                                {
-                                       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 );
+                               freeDLString( timecodeString );
                                SAFE_RELEASE( timecode );
                        }
                }
@@ -606,7 +597,6 @@ static int get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
                *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
@@ -655,16 +645,18 @@ static void on_property_changed( void*, mlt_properties properties, const char *n
        {
                if ( decklink->QueryInterface( IID_IDeckLinkInput, (void**) &decklinkInput ) == S_OK )
                {
-                       char *name = NULL;
-                       if ( decklink->GetModelName( (BSTR*) &name ) == 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 );
+                               mlt_properties_set( properties, key, name_cstr );
                                free( key );
-                               free( name );
+                               freeDLString( name );
+                               freeCString( name_cstr );
                        }
                        SAFE_RELEASE( decklinkInput );
                }
index b286dbe46b4d2d4a4d147806c97a874c9b2e1d86..acf161c27acd19ec60047325338a0b562a35d1f2 100644 (file)
@@ -11,14 +11,14 @@ OBJS = factory.o
 
 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
@@ -35,8 +35,8 @@ endif
 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
index 06ca6a61dee3349b4bbd88a812179cf3075b0a81..60f8dd7845eb332ba609e3822d64628e0c676426 100755 (executable)
@@ -1,15 +1,31 @@
 #!/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 gdk-pixbuf-2.0 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" ]
@@ -33,6 +49,8 @@ then
        [ "$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
index c929f52682d2202896aa316d6515a3a886e98df9..6f4a3a56793bc00f19cb619e107df8e8029a9c11 100644 (file)
@@ -19,7 +19,9 @@
  */
        .file   "scale_line_22_yuv_mmx.S"
        .version        "01.01"
+#if !defined(__MINGW32__) && !defined(__CYGWIN__)
        .section .note.GNU-stack,"",%progbits
+#endif
 
 .extern printf
 
@@ -31,7 +33,7 @@ MSG: .ascii "scale_line_22_yuv_mmx: %d %d\n"
        .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:
index 5932a47852f10727f2526c9579d86e91db70d674..0d1fee44535cd695eb7d4558f032778dead7cc3b 100644 (file)
@@ -27,11 +27,11 @@ ifdef GPL
 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
index 22f57615b27bf800ddc9fc9e957e09063c5f8f6c..fee51cb955d365192649f52aa523897e19b825b5 100755 (executable)
@@ -1,7 +1,15 @@
 #!/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=$?
@@ -23,6 +31,14 @@ then
                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" ]
index 8b850cbe0904ea73bac5c944f4e6cc0284e11482..c15d31e82db81f7d892a2a3d98adf0505215a767 100644 (file)
@@ -431,12 +431,20 @@ mlt_filter filter_jackrack_init( mlt_profile profile, mlt_service_type type, con
        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 ) );
index c040604d3173b1494ecf52cbad81d00c6ff62cee..9c0b489893602f09232af071bddad40c2710436d 100755 (executable)
@@ -37,7 +37,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
        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;
@@ -55,13 +55,8 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                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);
-
-                       // If requested freeze frame is out of the cutted producer, get parent
-                       if ( pos < mlt_producer_get_in( producer ) || pos > mlt_producer_get_out( producer ) )
-                       {
-                               producer = mlt_producer_cut_parent( producer );
-                       }
+                       // get parent producer
+                       mlt_producer producer = mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) );
                        mlt_producer_seek( producer, pos );
 
                        // Get the frame
index d97aad5682b807e471cfc427767cf9b79d5c6c9b..b85606854cbb1a09e68df5d19b10b66a7c75857a 100755 (executable)
@@ -31,8 +31,8 @@ else
                ;;
        esac
 
-       qimage_includedir=/usr/include/qt4
-       qimage_libdir=/usr/lib/qt4
+       qimage_includedir=
+       qimage_libdir=
 
        if [ ! -d "$qimage_libdir" -o ! -d "$qimage_includedir" ]
        then
@@ -95,19 +95,8 @@ else
                fi
        fi
 
-       pkg-config --exists 'QtGui >= 4'
-       if [ $? -eq 0 ] && [ "$force_qt3" = "" ]
+       if [ -d "$qimage_libdir" -a -d "$qimage_includedir" ]
        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" ]
-       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
@@ -130,7 +119,7 @@ else
                        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 >> config.mak
                        else
                                echo QTCXXFLAGS=-I$qimage_includedir >> config.mak
                                echo QTLIBS=-L$qimage_libdir -lQtCore -lQtGui -lQtXml -lQtSvg >> config.mak
@@ -153,8 +142,19 @@ else
                    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 ) >> config.mak
+                       echo QTLIBS=$(pkg-config --libs QtCore QtGui QtXml QtSvg) >> config.mak
+               else
+                       echo "qimage: QT environment not found - disabling"
+                       touch ../disable-qimage
+               fi
        fi
        [ "$gpl3" = "true" ] && echo GPL3=1 >> config.mak
        exit 0
index f425fed0fce9638678850a9abc50976611d75c54..01f5955407bd4573fabedf26b8d797e1b4e02d1a 100644 (file)
@@ -640,7 +640,7 @@ mlt_consumer consumer_rtaudio_init( mlt_profile profile, mlt_service_type type,
        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();
index 32d5d5d4b6fd84713c90632a77bc22dbf29786ad..e6839e73e916ec64869f8412a43222f92c9e1830 100644 (file)
@@ -10,7 +10,7 @@ TARGET = ../libmltswfdec$(LIBSUF)
 OBJS = producer_swfdec.o
 
 ifeq ($(targetos), MinGW)
-LDFLAGS += -enable-auto-import -lz
+LDFLAGS += -Wl,enable-auto-import -lz
 endif
 
 SRCS := $(OBJS:.o=.c)
index 8d39cec6ecd4ce11a80dad116fd4de3c7866970a..1585153597cdb798e72249a6df421cf8c54ee51c 100644 (file)
@@ -18,7 +18,7 @@
 #include <stdlib.h>
 #include <math.h>
 #include <string.h>
-#if !defined(__DARWIN__) && !defined(__FreeBSD__)
+#if !defined(__DARWIN__) && !defined(__FreeBSD__) && !defined(WIN32)
 #include <values.h>
 #endif