Chapter 9. ML Processing

The ML library is concerned with two types of interfaces:

Both types of interfaces share common control, buffer, and queueing mechanisms. These mechanisms are first described in the context of a complete program example. Subsequently, the individual functions are presented.

This chapter contains the following sections:

ML Program Structure

ML programs are composed of the following structure. Each of the functions are described later in this chapter (except where noted).

// Get list of available media devices:
mlGetCapabilities( systemId, &capabilities );

// Search the devices to find the desired jack, path, or transcoder to open (see Chapter 7):
mlGetCapabilities( deviceId, &capabilities );

// Query the jack, path or transcoder to discover allowable open options and parameters (see Chapter 7):
mlGetCapabilities( objectId, &capabilities );

// Query for individual parameter characteristics (see Chapter 7):
mlPvGetCapabilities( deviceId, paramId, &capabilities );

// Free memory associated with any of the above get-capabilities (see Chapter 7):
mlFreeCapabilities( capabilities );

// Open a logical connection to the desired object:
mlOpen( objectId, options, &openid );

// Get and set any necessary immediate controls:
mlGetControls( openId, controls );
mlSetControls( openId, controls );

// Send any synchronous controls:
mlSendControls( openId, controls );

// Send buffers to device: 
mlSendBuffers( opendId, buffers );

// Prepare for asynchronous processing by getting wait handle:
mlGetWaitHandle( openId, &waitHandle );

// Start the path or transcoder transfer:
mlBeginTransfer( openId );

// Perform synchronous transcoder work (if applicable):
mlXcodeWork( openId );

// Check on the status of the queue:
mlGetSendMessageCount( openId, &sendMsgCount );
mlGetReceiveMessageCount( openId, &receiveMsgCount );

// Process return messages:
mlReceiveMessage( openId, &status, &replyMsg );

// Find specific returned parameters:
mlPvFind( replyMsg, param );

//Repeat mlSendControls, mlSendBuffers, mlXcodeWork, etc. as required, then
// stop the transfer:
mlEndTransfer( openId );

// Close the logical connection:
mlClose( openId );

// Other useful functions:
mlGetVersion( &major, &minor );
mlGetSystemUST( systemId, &UST );
statusName = mlStatusName( status );
msgName = mlMessageName( messageType );

MLstatus Return Value


Note: All ML API functions return an MLstatus value. This provides a consistent error-checking interface. (However, certain convenience functions do not adhere to this standard.)


ML_STATUS_ACCESS_DENIED
 

The requested open access conflicts with a previous access already established or the requested parameter cannot be modified during the current operation mode.

ML_STATUS_DEVICE_UNAVAILABLE
 

The requested device has become unavailable, possibly by being powered down or removed from the system.

ML_STATUS_INSUFFICIENT_RESOURCES
 

Not all the resources required to complete the operation are available.

ML_STATUS_INTERNAL_ERROR
 

An operation was aborted due to a system or device I/O error.

ML_STATUS_INVALID_ARGUMENT
 

One of the arguments in the function call is invalid.

ML_STATUS_INVALID_CONFIGURATION
 

Because control messages may be incomplete, and individual set or send controls may be valid, there exists a point in time where the processing of buffers must be accomplished using those aggregate controls. If the combination of controls is invalid, the processing is aborted and the ML_STATUS_INVALID_CONFIGURATION error (for mlSetControls) or the event (for mlSendControls) is returned.

ML_STATUS_INVALID_ID
 

One of the arguments representing an ID is invalid.

ML_STATUS_INVALID_PARAMETER
 

The specified parameter (param field) is invalid for the requested operation.

ML_STATUS_INVALID_VALUE
 

The value of a parameter is invalid.

ML_STATUS_NO_ERROR
 

The operation succeeded without error.

ML_STATUS_NO_OPERATION
 

The function resulted in no operation.

ML_STATUS_OUT_OF_MEMORY
 

The operation was aborted due to lack of memory resources.

ML_STATUS_RECEIVE_QUEUE_EMPTY
 

The receive queue was empty when an mlReceiveMessage function was processed.

ML_STATUS_RECEIVE_QUEUE_OVERFLOW
 

The receive queue will not accept the return message if the current message is enqueued on the send queue.

ML_STATUS_SEND_QUEUE_OVERFLOW
 

Too many mlSendControls and/or mlSendBuffers have been issued.

Device States

For audio and video paths and transcoders, the device transitions through well-known states, known as device states. These states are as follows:

ML_DEVICE_STATE_ABORTING
 

The device has terminated message processing, usually by accepting an mlEndTransfer. All messages remaining on the input queue will be flushed to the output queue with the message type indicating that the message was aborted. Values are:

ML_BUFFERS_ABORTED
ML_CONTROLS_ABORTED
ML_QUERY_CONTROLS_ABORTED

ML_DEVICE_STATE_FINISHING
 

The device is terminating the transfer, but will complete processing of the remaining messages in the input queue.

ML_DEVICE_STATE_READY
 

The device is in a quiescent state and can accept messages, but will not process them until it enters the ML_DEVICE_STATE_TRANSFERRING state.

ML_DEVICE_STATE_TRANSFERRING
 

The device has accepted an mlBeginTransfer and is now processing messages.

ML_DEVICE_STATE_WAITING
 

The device is currently waiting for an external event such as the ML_WAIT_FOR_AUDIO_MSC_INT64 predicate control. Messages may still be enqueued, but will not be processed until the wait condition is removed.

Opening a Jack, Path, or Transcoder

In order to communicate with a jack, path, or transcoder, a connection must be opened. A physical device (such as a PCI card) may simultaneously support several such connections. These connections are done by calling mlOpen:

MLstatus mlOpen (const MLint64 objectId, MLpv* options,MLopenid* openid);

where:

  • objectId is the 64-bit unique identifier for the object (jack, path or transcoder) to be opened

  • options specify the initial configuration of the device to be opened

These parameters are described in Table 3-7.

The status return for this function is one of the following:

ML_STATUS_ACCESS_DENIED
 

The requested open access mode is not available.

ML_STATUS_DEVICE_UNAVAILABLE
 

The requested device has gone off-line, possibly by being disconnected.

ML_STATUS_NO_ERROR
 

The call succeeded and the handle of the open instance of the object has been returned in openid.

ML_STATUS_OUT_OF_MEMORY
 

Insufficient memory is available to perform the operation, including the space needed to allocate the queues for messages between the application and the device.

ML_STATUS_INSUFFICIENT_RESOURCES
 

Some other required resource is not available, possibly by being already in use by this or another application.

ML_STATUS_INTERNAL_ERROR
 

An operating system error has occurred.

ML_STATUS_INVALID_ARGUMENT
 

One of the arguments is otherwise invalid.

ML_STATUS_INVALID_ID
 

The argument objectId is invalid.

ML_STATUS_INVALID_PARAMETER
 

One of the parameters in the options list is invalid.

ML_STATUS_INVALID_VALUE
 

One of the parameters in the options list has an invalid value.

Set Controls

Some controls on a logical connection are asynchronous in nature and do not affect an ongoing data transfer. These controls may be set in an out-of-band message using the mlSetControls operation:

MLstatus mlSetControls( MLopenid openid, MLpv* controls );

where:

  • openid is the 64-bit unique identifier returned by the mlOpen function

  • controls is a message containing various parameters as described elsewhere in Chapter 2, “Parameters”

This call blocks until the device has processed the message. To identify an invalid value specification, the device will set the length component of the erroneous MLpv to -1, otherwise the controls array will not be altered in any way and may be reused. The controls message is not enqueued on the send queue but instead is sent directly to the device. The device will attempt to process the message as soon as possible.

Enqueueing entails a copy operation, so the application is free to delete/alter the message array as soon as the call returns. Any error return value indicates the control change has not been enqueued and will thus have no effect.


Note: The mlSetControls call returns as soon as the control array has been processed. This does not mean that buffers have been affected by the parameter change. Rather, it means that the parameters have been validated and sent to the device (that is, in most cases this means that they reside in registers).

The status return is one of the following:

ML_STATUS_INVALID_ID
 

The specified openid is invalid.

ML_STATUS_INVALID_PARAMETER
 

At least one of the parameters in the controls array was not recognized. (The first such offending control will be marked with length -1, remaining controls will be skipped and the entire message will be ignored.)

ML_STATUS_INVALID_VALUE
 

At least one of the parameters in the controls array has a value that is invalid. This may be because the parameter value is outside the legal range, or it may be that parameter value is inconsistent. (The entire message will be ignored and the system will attempt to flag the first offending value by setting the length to -1.)

ML_STATUS_NO_ERROR
 

The control values were set successfully.

Get Controls

Control on a logical connection may be queried asynchronously to an ongoing transfer:

MLstatus mlGetControls (MLopenid openid, MLpv* controls);

where:

  • openid is the identifier (returned by mlOpen) of the jack, path, or transcoder whose parameters are to be queried.

  • controls is a message consisting of parameters to be queried. The device will place its reply in the controls array argument (overwriting existing values). Control values that were obtained successfully will have nonnegative lengths. mlGetControls returns the state of the controls at the time the call is made.

If mlGetControls is called before a control has been explicitly set, then generally the returned value is undefined. (Exceptions are noted in the definitions the controls; see Chapter 10, “Synchronization” or ML_UST in mlSynchronization (3dm).)

The status return for this function is one of the following:

ML_STATUS_INVALID_ID
 

The specified open device ID is invalid.

ML_STATUS_INVALID_PARAMETER
 

At least one of the parameters in the controls array was not recognized. (The offending control will be marked with length -1; remaining controls will still be processed.)

ML_STATUS_INVALID_VALUE
 

At least one of the parameters in the controls array has a value that is invalid. (The offending control will be marked with length -1; remaining controls will still be processed.)

ML_STATUS_NO_ERROR
 

The control values were obtained successfully.

Send Controls

Other controls on a logical connection are synchronous in nature and affect the processing of subsequent data buffers. These controls should be set in an in-band message using the mlSendControls operation:

MLstatus mlSendControls( MLopenid openid, MLpv* controls );

where:

The mlSendControls operation sends a message containing a list of control parameters to a previously-opened digital media device. These controls are enqueued on the send queue in sequence with any other messages to that device. Any control changes are thus guaranteed not to have any effect until all previously enqueued messages have been processed.

This call returns as soon as the control change has been enqueued to the device. It does not wait until the control change has actually taken effect.

All the control changes within a single message are considered to occur atomically. If any one control change in the message fails, then the entire message has no effect. A successful return does not guarantee that resources will be available to support the requested control change at the time it is processed by the device.

As each message is processed by the device, a reply message will be enqueued for return to the application. By examining that reply, the application may obtain the result of attempting to process the requested controls.


Note: A device may take an arbitrarily long time to generate a reply (it may, for example, wait for several messages before replying to the first). If an application requires an immediate response, consider using the mlSetControls operation instead.

Enqueueing entails a copy operation, so the application is free to delete/alter the message array as soon as the call returns. Any error return value indicates the control change has not been enqueued and will thus have no effect.

The status return is one of the following:

ML_STATUS_INVALID_ID
 

The specified openid is invalid.

ML_STATUS_INVALID_PARAMETER
 

At least one of the parameters in the controls array was not recognized. (The first such offending control will be marked with length -1, remaining controls will be skipped and the entire message will be ignored.)

ML_STATUS_INVALID_VALUE
 

At least one of the parameters in the controls array has a value that is invalid. This may be because the parameter value is outside the legal range, or it may be that parameter value is inconsistent. (The entire message will be ignored and the system will attempt to flag the first offending value by setting the length to -1.)

ML_STATUS_NO_ERROR
 

The control values were set successfully.

ML_STATUS_RECEIVE_QUEUE_OVERFLOW
 

There is not currently enough space on the receive queue to hold the reply to this message. Read some replies from the receive queue and then try to send again, or specify a larger receive-queue size on open.

ML_STATUS_SEND_QUEUE_OVERFLOW
 

There was not enough space on the path send queue for this latest message. Try again later after the device has had time to catch up, or specify a larger send-queue size on open.

The return event may be one of the following:

ML_CONTROLS_ABORTED
 

The processing of the controls were aborted due to another asynchronous event, such as the mlEndTransfer function was requested.

ML_CONTROLS_COMPLETE
 

The controls were processed without error.

ML_CONTROLS_FAILED
 

The processing of the controls failed because the values were not accepted at the time of processing.

Send Buffers

The mlSendBuffers function sends a message containing a list of buffers to a previously-opened digital media device. These buffers are enqueued on the send queue in sequence with any other messages to that device. All the buffers within a single message are considered to apply to the same point in time. For example, a single buffers message could contain image, audio, HANC, and VANC buffers, each specified with its own buffer parameter in the buffers message. The mlSendBuffers operation is as follows:

MLstatus mlSendBuffers( MLopenid openid, MLpv* buffers );

where:

  • openid refers to a previously-opened logical connection as returned from mlOpen

  • buffers is a message containing a list of buffer parameters

As each message is processed by the path, a reply message will be enqueued for return to the application. By examining that reply, the application may obtain the result of attempting to process the buffers.

A successful return value from mlSendBuffers guarantees only that the requested buffers have been enqueued to the device. Any error return value indicates the buffers have not been enqueued and will thus have no effect.

The memory for the buffers is designated by the pointer value, and is always owned by the application. However, after a buffer has been sent, it is on loan to the system and must not be touched by the application. After the buffer has been returned via mlReceiveMessage , then the application is again free to delete and/or modify it.

When sending a buffer to be output, the application must set the buffer length to indicate the number of valid bytes in the buffer. In this case, maxLength is ignored by the device. (It does not matter how much larger the buffer may be because the device will not read past the last valid byte.)

When sending a buffer to be filled (on input) the application must set the buffer maxLength to indicate the maximum number of bytes that may be written by the device to the buffer. As the device processes the buffer, it will write no more than the maxLength bytes and then set the returned length to indicate the last byte written. The maxLength is returned without change. It is acceptable to send the same buffer multiple times.

Enqueueing entails a copy operation, so the application is free to delete/alter the message array as soon as the call returns. Any error return value indicates that the buffer has not been enqueued and will thus have no effect.

The status return is one of the following:

ML_STATUS_INVALID_ID
 

The specified openid is invalid.

ML_STATUS_INVALID_PARAMETER
 

At least one of the parameters in the message was not recognized. (The first such offending control will be marked with length -1, remaining controls will be skipped and the entire message will be ignored.)

ML_STATUS_INVALID_VALUE
 

At least one of the parameters in the message has a value that is invalid. This may be because the parameter value is outside the legal range, or it may be that parameter value is inconsistent. (The entire message will be ignored and the system will attempt to flag the first offending value by setting the length to -1.)

ML_STATUS_NO_ERROR
 

The buffers message was enqueued successfully.

ML_STATUS_RECEIVE_QUEUE_OVERFLOW
 

There is not currently enough space on the receive queue to hold the reply to this message. Read some replies from the receive queue and then try to send again, or specify a larger receive-queue size on open.

ML_STATUS_SEND_QUEUE_OVERFLOW
 

There was not enough space on the path send queue for this latest message. Try again later after the device has had time to catch up, or specify a larger send-queue size on open.

The return event may be one of the following:

ML_BUFFERS_ABORTED
 

The processing of the buffers was aborted due to another asynchronous event, such as the mlEndTransfer function was requested.

ML_BUFFERS_COMPLETE
 

The buffers were processed without error.

ML_BUFFERS_FAILED
 

The processing of the buffers failed because the values were not accepted at the time of processing. This can occur both because parameters in the buffers message were invalid or because the current control settings at the time of processing (due to previous mlSendControls messages), the processing of buffers would be invalid. Because preceding control messages may be incomplete, and each of the individual set or send controls may be valid, there still exists a point in time where the processing of buffers must be accomplished using those aggregate controls. If the combination of controls is invalid, the processing is aborted and the event ML_BUFFERS_FAILED is returned.

Query Controls

To obtain the control values on a logical connection that are synchronous via an in-band message, use the mlQueryControls operation:

MLstatus mlQueryControls( MLopenid openid, MLpv* controls );

where:

  • openid is the 64-bit unique identifier returned by the mlOpen function.

  • controls is a message containing various parameters as described in “param/value Pairs in an MLpv Message” in Chapter 2.

  • mlQueryControls sends a message containing a list of control parameters to a previously-opened digital media device. These controls are enqueued on the send queue in sequence with any other messages to that device. The control values returned are thus guaranteed to reflect all previously enqueued mlSendControls messages that have been processed.

This call returns as soon as the message has been enqueued to the device. It does not wait until the control value is available.

As each message is processed by the device, a reply message will be enqueued for return to the application. By examining that reply, the application may obtain the result of attempting to process the requested controls.


Note: A device may take an arbitrarily long time to generate a reply (it may, for example, wait for several messages before replying to the first). If an application requires an immediate response, consider using the mlGetControls operation instead.

Enqueueing entails a copy operation, so the application is free to delete/alter the message array as soon as the call returns. Any error return value indicates the control change has not been enqueued and will thus have no effect.

The status return is one of the following:

ML_STATUS_INVALID_ID
 

The specified openid is invalid.

ML_STATUS_INVALID_PARAMETER
 

At least one of the parameters in the controls array was not recognized. (The first such offending control will be marked with length -1, remaining controls will be skipped and the entire message will be ignored.)

ML_STATUS_NO_ERROR
 

The control values were set successfully.

ML_STATUS_RECEIVE_QUEUE_OVERFLOW
 

There is not currently enough space on the receive queue to hold the reply to this message. Read some replies from the receive queue and then try to send again, or specify a larger receive-queue size on open.

ML_STATUS_SEND_QUEUE_OVERFLOW
 

There was not enough space on the path send queue for this latest message. Try again later after the device has had time to catch up, or specify a larger send-queue size on open.

The return event may be one of the following:

ML_QUERY_CONTROLS_ABORTED
 

The processing of the query controls were aborted due to another asynchronous event, such as the mlEndTransfer function was requested.

ML_QUERY_CONTROLS_COMPLETE
 

The query controls were processed without error.

Get Wait Handle

When processing a number of digital media streams asynchronously, there exists a need for the application to know when processing is required on each individual stream. The mlGetSendWaitHandle and mlGetReceiveWaitHandle functions are provided to facilitate this processing:

MLstatus mlGetSendWaitHandle( MLopenid openid, MLwaitable* WaitHandle );
MLstatus mlGetReceiveWaitHandle( MLopenid openid, MLwaitable* WaitHandle );

where:

  • openid is a previously-opened digital media object as returned by a mlOpen call.

  • MLwaitable on IRIX, UNIX, and Linux is a file descriptor for use in select(). On Windows, MLwaitable is a handle that may be used in the win32 functions WaitForSingleObject or WaitForMultipleObjects.

  • WaitHandle is the requested returned wait handle. This function returns an event handle on which an application may wait.

The send queue handle is signaled whenever the device dequeues a message and the message count drops below a preset level (set by the parameter ML_OPEN_SEND_SIGNAL_COUNT specified when the object was opened). Thus, if the send queue is full, an application may wait on this handle for notification that space is available for additional messages.

The receive queue handle is signaled whenever the device enqueues a reply message. Thus, if the receive queue is empty, the application may wait on this handle for notification that additional reply messages are ready.

The returned handles were created when the device was opened and are automatically destroyed when the path is closed.

The status return is one of the following:

ML_STATUS_INVALID_ID
 

The specified open device handle is invalid

ML_STATUS_NO_ERROR
 

The wait handle was obtained successfully

Begin Transfer

mlBeginTransfer starts the actual transferring of buffers to the logical media connection:

MLstatus mlBeginTransfer (MLopen id openid);

where openid is a previously-opened digital media object as returned by an mlOpen call.

This function begins a continuous transfer on the specified path or transcoder. It is not used on a logical connection to a jack. This call advises the device to begin processing buffers and returning messages to the application. As stated earlier, sending a buffer to a device that has not yet begun transfers will cause the send queue to stall until the transfers have started. Typically, applications will open a device, send several buffers, and then call mlBeginTransfer. This call returns as soon as the device has begun processing transfers. It does not block until the first buffer has been processed. It is an error to call this function more than once without an intervening call to mlEndTransfer.


Note: The delay between a call to mlBeginTransfer and the transfer of the first buffer is implementation-dependent. To begin sending data at a particular time, an application should start the transfer early (enqueueing blank buffers) and use the UST/MSC mechanism to synchronize the start of real data.

The status return is one of the following:

ML_STATUS_INVALID_ID
 

The specified open device ID is invalid

ML_STATUS_NO_ERROR
 

The device agreed to begin transfer on the path

ML_STATUS_NO_OPERATION
 

The call had no effect (transfers have already been started)

Transcoder Work

For software-only transcoders opened with the ML_XCODE_MODE_INT32 open option set to ML_XCODE_MODE_SYNCHRONOUS, this function allows an application to control exactly when (and in which thread) the processing for that codec takes place:

MLstatus mlXcodeWork( MLopenid openid );

where openid refers to a previously-opened digital media transcoder.

This function performs one unit of processing for the specified codec. The processing is done in the thread of the calling process and the call does not return until the processing is complete. For most codecs, a unit of work is the processing of a single buffer from the source queue and the writing of a single resulting buffer on the destination queue.


Note: The default behavior for all codecs is for processing to happen automatically as a side effect of enqueueing messages to the device. This function only applies to software codecs and only applies if they are opened with the ML_XCODE_MODE_SYNCHRONOUS open option.


The status return is one of the following:

ML_STATUS_INVALID_ID
 

The specified openid is invalid

ML_STATUS_NO_ERROR
 

The software transcoder performed one unit of work successfully

ML_STATUS_NO_OPERATION
 

There was no work to be done

Get Message Count

During the processing of messages, it is sometimes necessary to inquire about the current capacity (fullness) of the message queues. The following functions provide that capability:

MLstatus mlGetSendMessageCount ( MLopenid openid, MLint32* messageCount);
MLstatus mlGetReceiveMessageCount ( MLopenid openid, MLint32* messageCount );

where:

  • openid is a previously-opened digital media object returned by mlOpen.

  • messageCount is the resulting returned count.

These functions return a count of the number of messages in the send or receive queues of a device:

  • The send queue contains messages queued by the application for processing by the device. A message resides in the send queue from the moment it is enqueued by the application until the device begins processing it.

  • The receive queue holds messages that have been processed and are waiting to be read by the application. A message resides in the receive queue from the moment the device enqueues it until the application dequeues the corresponding reply message. (All messages in the receive queue are counted, regardless of whether or not they were successfully processed.)

The message counts are intended to aid load-balancing in sophisticated applications. They are not a reliable method for predicting UST/MSC pairs.

Some devices can begin processing one or more following messages before the first has been completed. Thus, the sum of the send and receive queue counts may be less than the difference between the number of messages that have enqueued and dequeued by the application. The time lag between a message being removed from the send queue and the time at which it affects data passing though a physical jack is implementation-dependent. The message counts are not a reliable method for timing or synchronizing media streams.

The status return is one of the following:

ML_STATUS_INVALID_ID
 

The specified open device ID is invalid

ML_STATUS_NO_ERROR
 

The message count was obtained successfully

Receive Messsage

To obtain the results of previous digital media requests, use the mlReceiveMessage function:

MLstatus mlReceiveMessage( MLopenid openid, MLint32* messageType, MLpv *reply );

where:

  • openid is a previously-opened digital media object

  • messageType is an integer to be filled in by the device, indicating the type of message received

  • reply is a pointer to the head of the reply message

This function reads the oldest message from the receive queue. The receive queue holds reply messages sent from a digital media device back to an application.

Messages on the receive queue may be the result of the following:

  • Processing a message sent with mlSendControls or mlSendBuffers

  • Generated spontaneously by the device to advise the application of some exceptional event

Each message sent with an mlSendBuffers or mlSendControls generates a single reply message with messageType. This indicates whether or not the message was processed successfully and a pointer to a list of parameters holding the reply.

The contents of the reply array are guaranteed to remain valid until the next call to mlReceiveMessage. It is acceptable for an application to modify the reply and then send it to the same or to another device by calling mlSendControls or mlSendBuffers.

On some devices, triggering of the receive wait handle does not guarantee that a message is waiting on the receive queue. Thus applications must accept a status return of ML_STATUS_RECEIVE_QUEUE_EMPTY from an mlReceiveMessage function.

End Transfer

To invoke an orderly shutdown of a digital media stream, use the mlEndTransfer function:

mlEndTransfer( openId );

where openid is a previously-opened digital media object.

This function ends a continuous transfer on the specified path or transcoder. This call advises the device to stop processing buffers and aborts any remaining messages on its input queue. This is a blocking call. It does not return until transfers have stopped and any messages remaining on the device input queue have been aborted and flushed to the device output queue. Calling mlEndTransfer on a device that has not begun transfers is legal (it still causes the queue to be flushed). Any messages that are flushed will be marked to indicate they were aborted. Buffer messages are marked ML_BUFFERS_ABORTED; control messages are marked ML_CONTROLS_ABORTED.

The status return is one of the following:

ML_STATUS_INVALID_ID
 

The specified open device handle is invalid

ML_STATUS_NO_ERROR
 

The device agreed to end transfer on the path

Close Processing

After an application is finished with a digital media connection, it should terminate that connection. Use the mlClose function to close a previously opened digital media:

MLstatus mlClose(MLopenid openid);

where openid is the handle of the device to be closed.

When a digital media object is closed, all messages in the message queues of the device are discarded. The device handle openid becomes invalid; any subsequent attempt to use it to refer to the closed object will result in an error.


Note: An mlClose is implied if an application terminates (for any reason) before an mlClose function is called.

mlClose returns ML_STATUS_INVALID_ID if openid is invalid. Otherwise it returns ML_STATUS_NO_ERROR after the device has been closed and associated resources have been freed.

The pipes opened as a side-effect of opening a transcoder are also closed as a side-effect of closing a transcoder. Pipes should not be closed explicitly.

Utility Functions

This section describes the following:

Get Returned Parameters

In returned messages, the application often wants to query specific parameters. The mlPvFind convenience function is provided for this use:

MLpv* mlPvFind( MLpv* msg, MLint64 param );

where:

  • msg is a message for which the parameter being searched is to be found

  • param argument is the parameter that is being searched

Get Version

The following function obtains the version number for the ML library:

MLstatus mlGetVersion( MLint32* majorVersion, MLint32* minorVersion );

where:

  • majorVersion is the first digit in the major version

  • minorVersion is the first digit in the minor version

For example, the 1.0 release will have a major number of 1 and a minor number of 0. Changes in major numbers indicate a potential incompatibility, while changes in minor numbers indicate small backward-compatible enhancements. Within a particular major version, all the minor version numbers will start at 0 and increase monotonically.


Note: This is the version number of the ML core library. The version numbers for device-dependent modules are available in the capabilities list for each physical device.

The status return is one of the following:

ML_STATUS_INVALID_ARGUMENT
 

At least one of the pointers passed in is invalid

ML_STATUS_NO_ERROR
 

The version numbers were obtained successfully

Status Name

Intended mainly as an aid in debugging, the following call converts the integer ML status value into a C string. The converted string is exactly the same as the status enumerated value:

const char *mlStatusName( MLstatus status );

where status is the return code from an ML function.

For example, the value ML_STATUS_NO_ERROR is converted to the string "ML_STATUS_NO_ERROR".

This function returns a valid C string or NULL character if the status value is invalid.

Message Name

Intended mainly as an aid in debugging, the following call converts the integer ML message type into a C string:

const char *mlMessageName( MLint32 messageType );

where messageType is the the message type resulting from a call to mlReceiveMessage.

The converted string is exactly the same as the message enumerated values. For example, the value ML_CONTROLS_FAILED is converted to the string "ML_CONTROLS_FAILED".

This function returns a valid C string, or NULL character if the message value is invalid.

MLpv String Conversion Routines

You can use the following routines to convert parameters and values to strings or to convert strings to parameters and values:

MLstatus  mlPvValueToString(MLint64 objectId, MLpv* pv, char* buffer, MLint32* bufferSize);
MLstatus  mlPvParamToString(MLint64 objectId, MLpv* pv,char* buffer, MLint32* bufferSize);
MLstatus  mlPvToString(MLint64 objectId, MLpv* pv, 	char* buffer, MLint32* bufferSize);
MLstatus  mlPvValueFromString(MLint64 objectId, const char* buffer,MLint32* bufferSize, 
                              MLpv* pv, MLbyte* arrayData, MLint32 arraySize);
MLstatus  mlPvParamFromString(MLint64 objectId, const char* buffer, MLint32* size, MLpv* pv);
MLstatus  mlPvFromString(MLint64 objectId, const char* buffer, MLint32* bufferSize, MLpv* pv,
                         MLbyte* arrayData, MLint32 arraySize);

where:

  • objectID is the 64-bit ID number for the digital media library on which the parameter is interpreted.

  • pv is a pointer to the MLpv for use in the conversion.

  • buffer is a pointer to a buffer to hold the string.

  • bufferSize initially contains the size of the buffer (in bytes). Upon completion, this is overwritten with the actual number of bytes processed.

  • arrayData is a pointer to a buffer to hold any array data resulting from the conversion.

  • arraySize initially contains the size of the array buffer (in bytes).

These routines convert between MLpv message param/value pairs and strings. They are of benefit to applications writing lists of parameters to/from files, but are most commonly used as an aid to debugging.

These routines make use of the parameter capability data to generate and interpret human-readable ASCII strings. (See the mlPvGetCapabilities(3dm) man page.)

mlPvParamToString converts pv->param into a string. The resulting value for bufferSize is the length of the string (excluding the terminating '\0'.

mlPvValueToString converts pv->value into a string. The resulting value for bufferSize is the length of the string (excluding the terminating '\0').

mlPvToString converts the MLpv into a string. It writes the parameter name and value separated by =. The resulting value for bufferSize is the length of the string (excluding the terminating '\0').

mlPvParamFromString interprets a string as a parameter name and writes the result in pv->param. It expects the string was created by mlPvParamToString.

mlPvValueFromString interprets a string as the value of an MLpv and writes the result in pv->value. It expects the string was created by mlPvValueToString . For scalar parameters, the result is returned in the value field of the MLpv structure and the array arguments are not used. For array parameters, additional space is required for the result. In this case, the contents of the array are returned inside the arrayData buffer and arraySize is set to indicate the number of bytes written.

mlPvFromString interprets a string as an MLpv. It expects the string was created by mlPvToString .

The interpretation of a param/value pair depends on the parameter, its value, and the device on which it will be used. Thus, all these functions require both a param/value pair and a 64-bit device identifier. That identifier may be one of the following:

  • A static ID (obtained from a call to mlGetCapabilities )

  • The open ID of a jack, path or transcoder (obtained from a call to mlOpen)

  • The ID of an open pipe (obtained by calling mlXcodeGetOpenPipe)

The status returns are:

ML_STATUS_INVALID_ARGUMENT
 

The arguments could not be interpreted correctly. Perhaps the bufferSize or arraySize is too small to hold the result of the operation.

ML_STATUS_INVALID_ID
 

The specified id is invalid.

ML_STATUS_INVALID_PARAMETER
 

The parameter name is invalid. When converting to a string, the parameter name was not recognized on this device. When converting from a string, the string could not be interpreted as a valid parameter for this device.

ML_STATUS_INVALID_VALUE
 

The parameter value is invalid. When converting to a string, the parameter value was not recognized on this device. When converting from a string, the string could not be interpreted as a valid parameter value for this device.

ML_STATUS_NO_ERROR
 

The conversion was performed successfully.

Example: Printing the Interpretation of a Video Timing Parameter

The following example prints the interpretation of a video timing parameter by a previously-opened video path. The calls could fail if that path did not accept the particular timing value we have chosen here. Because the interpretation is coming from the device, this example will work for device-specific parameters.

char buffer[200]; 
MLpv control;

  control.param = ML_VIDEO_TIMING_INT32;
  control.value = ML_TIMING_1125_1920x1080_5994i;

  mlPvParamToString(someOpenPath, &control, buffer, sizeof(buffer)); 
  printf("control.param is %s\n", buffer); 
  mlPvValueToString(someOpenPath, &control, buffer, sizeof(buffer)); 
  printf("control.value is %s\n", buffer); 
  mlPvToString(someOpenPath, &control, buffer, sizeof(buffer));