Educating the world

Our blog has over 10,000 readers a month

Compiling the Quantel’s quentin.idl

May 11th, 2012

In order to drive the Quantel Broadcast system you need to compile the CORBA Interface Definition Language (IDL) file into a language of your choice. There are many CORBA IDL compilers out there: JacORB (Java), OmniORB (Python), TOA (C++), IIOP.NET (.NET) and there’s a more complete list on the Object Management Group’s web site.

Quantel’s IDL is known as Quentin.idl and may be obtained from your account manager, or the 24 hour support desk if you can’t wait! It contains the API interface’s for talking to:

  • ZonePortal - main driver module, metadata, searching, space allocation, copying media, organising running orders, registering listeners.
  • ThumbnailListener - generate thumbnails from video media.
  • StateChangeListener - receive callback notifications on status changes.
  • Server - control of playout and ingest storage servers.
  • Port - object representing a video port.
  • PortListener - callbacks relating to Port status changes.

This article just covers compiling the IDL into your language of choice: coding fun comes later! Due to the amount of IDL implementations there are this will have to be a cut down guide limited to the languages I deal with. I’ll start with JacORB for Java. I might do Python if there’s time.

Ok, so let’s get started. I’m assuming you’ve obtained a copy of Quentin.idl and you have the Java JDK installed. Next we need a copy of JacORB.

  1. Go to the JacORB web site’s download page.
  2. At the time of writing this article the latest version was 3.0rc1.
  3. We are not interested in compiling JacORB from source so download the Binary version.
  4. Use 7-zip to uncompress it, so now we have a folder called d:\blog\jacorb-3.0rc1.
  5. Place the Quentin.idl in the top level folder d:\blog.
  6. There isn’t an installer as such because the package assumes that you have downloaded the source code and are compiling from scratch. So to avoid downloading and installing all sorts of supplementary requirements we are just going to frig the file we need to make it work.
  7. Edit D:\blog\jacorb-3.0rc1\bin\idl.bat and change the classpath:

    -classpath “D:/blog/jacorb-3.0rc1/lib/idl.jar;%CLASSPATH%”

  8. Almost there! Now we need to open a command window and go to the d:\blog folder where the Quentin.idl file lives.
  9. Type:

    jacorb-3.0rc1\bin\idl.bat -all -genEnhanced -d src -i2jpackage Quentin:com.quantel.quentin Quentin.idl

  10. This will compile the IDL into the target language, creating a folder called src in the current directory which contains all the com.quantel.quentin package source code.
  11. Now we have the source, we can compile.
  12. The Java compiler, is frankly a pain in a arse, so if anyone knows a better way of doing this then please leave a comment.

    dir /s/b src\**.java > src.txt
    mkdir bin
    javac -d bin -cp “jacorb-3.0rc1\lib\jacorb.jar” -sourcepath src -g @src.txt

  13. Finally we need to package all that compiled code into a Java Archive (Jar) for easier access.

    jar -cf quentin.jar -C bin .

  14. This will produce a file called quentin.jar in your current folder (d:\blog).

That’s it! We will use the quentin.jar in combination with the jacorb.jar to create our application to drive the Quantel Broadcast system.

Next lesson - obtaining the IOR and connecting to the ZonePortal.

Mastering the Quantel IDL

May 9th, 2012

Quantel is a technology company based in Newbury (England) that describes itself as:

Quantel develops innovative, world-leading content creation systems for broadcast, post and DI. We are driven by a passion to create the most powerful and efficient tools for the digital age. Quantel technology means business; our systems combine industry-leading performance with total scalability to enable productive workflows for post production, graphics, digital intermediate and news/sports production.

The main product for the Broadcasting division is the Broadcasting Server system which consists of sQ Editors (glossy front end editing station), ISA Managers (the brains) and sQ Servers (storage).

One of Quantel’s unique selling points is that the storage system is highly efficient; no 2 frames are stored twice in their patented technology called FrameMagic. A huge advantage of this is when you are versioning, that is producing a version of the film for the UK market and then another version for the Japanese market. All the pictures for both versions of the film are only held once. The bits of film that are unique are held separately and are seamlessly stitched together to produce 2 versions. So the same film versioned for 10 countries’ laws will only occupy the same storage space of one and a little bit’s worth of storage space. This is unlike most of the competitor systems where it will occupy 10 times the space. The advantages don’t stop there! If you want to copy the 10 versions from the edit server to the playout or archive server then The Quantel System manages the copy ensuring that no to frames are copied twice, so copying the 10 versions will be 10 times quicker than an equivalent file based storage system. Cool!

One can use the Quantel Server system to record video, copy it between servers, create new clips from recorded rushes, search for media, add tagging information to rushes (which follow the media around, in and out of edits) and all sorts of other video and audio related functions. Quantel exposes it’s Application Programmer Interface (API) so that anyone can control the Quantel server system. This interface is used by lots of automaters to schedule records, making back ups, housekeeping, etc. The API is written using CORBA which is basically a convenient way of passing objects around a network, it’s similar to RMI (Java only) or COM (Windows only).

This article will join together a series of articles on how to get the most from the Quantel IDL to control the worlds most powerful video editing system.

If you can’t wait and you want to get started straight away then I’m available for consultancy, just drop me a line. No application too small, no language too difficult*.

Set up and using a test system

Development

Note: Now that I’m freelancing full time the articles won’t be “coming soon". I don’t want to give away all my secrets!

* provided there is an IDL compiler available for that language.

Politics doesn't really effect us does it?

May 8th, 2012

Full transcript of the a television advertisement on the BBC for their coverage of politics, with the tag line: Everything is Politics. Making politics make sense..

Politics doesn’t really effect us does it? Oh, apart from the cost of our heating; and the fat content of our food; how often our streets are cleaned; the minimum wage, the maximum wage; cycle lanes, care homes, first homes, Sherlock Holmes, oh and the air we breathe. Yeh, apart from all that!

Hibernate exception - attempted to assign id from null one-to-one property

April 26th, 2012

I wrote this 3 years ago and never really got around to finishing it properly. I’m not doing this kind of work at the moment so there’s no incentive to complete it. I’m posting it now so that it might help others and to fulfil my 4 articles a month target!

This was a tricky one to solve! Tricky because the exception doesn’t happen at the point of error - it happens down the line at the time you try to commit a transaction. This is one of those error messages you just need to know. Here is the top of the exception’s stack trace. Almost all of the rest of the stack trace is inside hibernate and doesn’t give you any kind of clue as to the cause.

org.springframework.orm.hibernate3.HibernateSystemException:
attempted to assign id from null one-to-one property: clip; nested exception is org.hibernate.id.IdentifierGenerationException:
attempted to assign id from null one-to-one property: clip

The error message we are concerned with is:

attempted to assign id from null one-to-one property: clip

Where clip is the name of property. The exception is caused by trying to save a cascading object, without persisting the entity your object is referring to.

In my case I have the classes: Clip and Aaf. A Clip has one Aaf, so I need a one-to-one relationship. My Aaf object contains a blob but unfortunately hibernate doesn’t let you do lazy initialisations on one-to-one relationships, so I’ve had to use a Set even though there is only ever one entry.

The situation is made slightly more complicated by the fact that I’m using a UUID as my primary key. Hibernate doesn’t currently support UUID so I need a custom type along with a custom key generator.

XML

<class name="uk.co.bigsoft.bus.Aaf" table="aafs">
  <id name="id" type="uuid">
    <generator class="foreign">
      <param name="property">clip</param>
    </generator>
  </id>
  :
</class>

The Aaf’s hibernate ("hbm") file above says to use a uuid identifier that is generated from the primary key of the clip property. So if we look at the Aaf class you can see that the clip property has type Clip

Code

public class Aaf
  {
 
  private UUID id ;
  private Clip clip ;
  :

As you can see above id is the record identifier but clip (mentioned in the exception) is the relationship object that is used to set the record identifier. That is id is never explicitly set by us, we set the clip property.

The first example is *wrong*.

Code

Aaf aaf = new Aaf (aafInputStream);
aafs = new HashSet<aaf> ();
aafs.add (aaf);
clip.setAaf (aafs);

I was expecting that saving the Clip would do a cascade save on the Aaf object, but is doesn’t. We need the an intermediate step of persisting the Aaf object first. In order to do this we need to fill in all the details of the Aaf record.

Code

Aaf aaf = new Aaf (aafInputStream) ;
aaf.setClip (clip) ;
aafManager.set (aaf) ;
 
aafs = new HashSet<aaf> () ;
aafs.add (aaf) ;
clip.setAaf (aafs) ;
 
sc = new AafUpdateStatechange () ;
sc.setClipId (isaClip.getId ()) ;
remoteEventQueue.send (sc) ;

XML

<class name="uk.co.bigsoft.dino.bus.Aaf" table="aafs">
 
  <id name="id" type="dinouuid">
    <generator class="foreign">
      <param name="property">clip</param>
    </generator>
  </id>
 
  <many-to-one
    name="clip"
    column="id"
    insert="false"
    update="false"
    unique-key="true"
    class="uk.co.bigsoft.dino.bus.Clip"/>
 
  <property name="content" column="content" type="uk.co.bigsoft.dino.db.types.BlobUserType"/>
        
</class>

We need to persist Aaf object, before saving the clip relationship.

It's simple you can just merge main\LATEST into your private branch...

April 24th, 2012

Everyone keeps saying “It’s simple you can just merge [Clearcase] main\LATEST into your private branch” but I’m pretty sure that almost no one understands what this involves. In fact several people have spoken to me with problems relating to just that. Hence this article!

Let’s take a typical scenario. Create a private branch and check in a couple of new versions. Wait for your feature to get the go-ahead for main\LATEST check in. Merge main latest into your private branch. What will you end up with? Clearcase will check out every single file and directory in your view that has changed (in main) since you created your private view. Clearcase will then merge all those files into your branch; for the most part this will be a trivial merge because the version on your private branch won’t have changed. If your code has been on a branch for a while there may be thousands of files across the VOB that have nothing to do with you that will be merged. Each merge will create merge lines from one branch to the other.

There is a simpler and quicker way which involves a lot less hassle (and scary merge lines):

  1. When you have finished your new feature and checked everything in on to your [private] branch.
  2. Make a note of the private branch’s name.
  3. Go into Clearcase explorer, right click on the view and select “Finish private branch".
  4. Clearcase pops up a merge box so select “Leave my changes on Private branch".
  5. Clearcase will kick off an “Update". If you’re on a dynamic view this will be instant whereas if you’re using a snapshot view then get yourself a coffee.
  6. When the update has finished, go back into Clearcase Explorer and right click on the view name and click “Set up private branch".
  7. The dialogue will pop up asking for a branch name, so enter the branch name you wrote down earlier.
  8. Clearcase will pop up a warning about reusing the branches so click “OK” to say that’s fine.
  9. Clearcase will kick off another update, so if you’re on a snapshot view you can go to the toilet to get rid of that coffee and dynamic view users can move to the next step. The update process will copy the items on your branch into the local view.
  10. You are now on your private branch again only the private branch timestamp has moved forward. All the files that have not been modified by you (i.e. don’t have a version on your branch) will be updated to the latest version. Your view will also contain the files on your branch.
  11. Now if you merge main latest into your private branch only the files that have changed on main latest AND your branch will be merged together.
  12. Now you are free to continue working with the latest code base. If you decide to check in your code (i.e. merge your private branch into main) then all the merges will be trivial.