Friday, May 14, 2021
    HomeTechnologyDV Transmission over IEEE-1394

    DV Transmission over IEEE-1394

    The blog post explains the detail of DV Transmission over IEEE-1394 including introduction and layers.


    The transmission of DV data over IEEE-1394 involves the packaging and presentation of data within Common Isochronous Packets (CIPs). CIPs are used to package raw DV data and describe the contents and presentation time of the data. A CIP consists of a CIP header and data packet. An empty CIP is a CIP header with no attached data packet and is used for rate control of the DV data.

    Setting the IEEE-1394 isochronous header tag field to 1 indicates that CIP-based data is contained in the isochronous payload.

    - Advertisement -

    A CIP header for DV data is as follows:

    1 0


    SID = Source Node ID

    - Advertisement -

    DBS = Data Block Size (0x78 for DV NTSC)

    FN, QPC, SPH, rsv = 0

    DBC = Data Block Counter, 8-bit counter that is incremented for each packet that has a valid data payload (empty CIPs do not increment this counter)

    FMT = Format (DV = 0)

    FDF = Format Dependent Field (set to 0)

    SYT = Represents the “presentation time” of the data to the camcorder, and should be set to two to three cycles ahead of the current IEEE-1394 isochronous cycle time. This “presentation” time is only set in the first CIP header of a complete DV frame. For all other CIP headers, the SYT is set to 0xffff. The format is identical to the lower 16 bits of the IEEE-1394 isochronous cycle time (upper 4 bits are mod 16, lower 12 bits are mod 3072). These upper 4 bits represent cycle count (8KHz), and the lower 12 bits represent cycle offset (24.576MHz mod 3072).

    The two important points for ensuring proper DV transmission are:

    – Make sure the DV transmission data rate is accurate (through use of EmptyCIPs)

    – Set the SYT field in the CIP header (first in a DV frame) to the proper “presentation time” for the DV data.

    Getting the DV Data Rate Right:

    CIP headers without CIP data payloads (Empty CIPs) must be attached periodically in order to adjust for the difference in data rate between CIP data payload size times 8000 (cycles per second for IEEE-1394) and the true data rate of the DV device. These empty CIPs bring the transmission data rate down to the rate expected by the DV device.

    Empty CIP insertion must be calculated in advance of transmission (when creating the isochronous transmission DMA program). If this Empty CIP insertion rate is not finely adjusted to match data rates expected by the DV device, jitter will occur.

    After initial values for the CIP headers are calculated and inserted, Empty CIPs must be created and the insertion rate described (by the isochronous transmission DMA program). Empty CIPs contain exactly the same data as the next CIP header to be transmitted. Therefore, it is only necessary to describe an algorithm do decide when to insert these Empty CIPs into the data stream.

    Following are some calculations and algorithm for deciding when to insert Empty CIPs into an NTSC DV data stream (PAL actually results in much nicer even numbers):

    DV payload size = 480 bytes

    DV payload size + CIP header = 488 bytes

    DV frame size = 480 x 250 = 120000 bytes

    Frame rate (NTSC) = 29.97 frames/sec

    Raw data rate required for DV = 29.97 x 120000 = 3596400 bytes/second

    IEEE-1394 isoc cycles = 8000/sec

    Average DV payload size for proper data rate should be 3596400 / 8000 = 449.55

    This is less than the 480-byte payloads actually being sent per cycle on the IEEE-1394 bus. (480 x 8000 = 3840000, which is too high a data rate). In order to “bring-down” the data rate to match exactly what the camcorder expects, we must insert Empty CIPs.

    Empty CIP ratio = (3840000 – 3596400) / 3840000 = 2436 / 38400 = around 1 header per 15 packets

    Use a modified I+N/D algorithm to determine when to insert Empty CIP headers. An Empty CIP header should look exactly like the header of the next full CIP.

    Here is some pseudo-code for DV NTSC transmission of full and empty CIPs.

    CIP_I = 488 bytes (full CIP packet)

    CIP_S = 8 bytes (empty CIP header)

    CIP_N = 2436

    CIP_D = 38400

    CIP_Acc = General purpose accumulator

    TotalFullCips = Total number of CIPs contained in data buffers

    CIP_Acc = CIP_N // initialize accumulator

    for (i=0; i<TotalFullCips; i++) { // loop on total number of full CIPs

    CIP_Acc += CIP_N; // increment accumulator by CIP_N

    if (CIP_Acc > CIP_D) {

    Insert CIP_S (8 byte empty CIP header); // create program to send empty CIP

    CIP_Acc -= CIP_D; // decrement accumulator by CIP_D

    } else {

    Insert CIP_I (488 byte full CIP packet); // create program to send full CIP



    Setting the “Presentation Time” (SYT field) for DV Data:

    The SYT field within the Format Dependent Field (FDF) of the CIP header must represent a real-time “presentation time” for the isochronous data being transmitted. This SYT “presentation time” must be calculated in advance of transmission, and must be carefully regulated (must always be a fixed number of cycles ahead of the current IEEE-1394 bus time). DV devices lock onto this SYT field in the DV data stream and use it for determining when to display the DV data received.

    The initial SYT fields may be calculated based on an offset from the starting transmit time (the difference between transmit time and presentation time) and a variation on the I+N/D algorithm. Remember that the SYT field is 16 bits and contains the upper four bits of cycle count (8KHz, mod 16) and lower 12 bits of cycle offset (24.576MHz, mod 3072).

    Following is some pseudo-code for generating the SYT for DV NTSC frames (is inserted into the first CIP header of a full DV frame of data). The SYT for all other CIP headers is 0xffff.

    SYT_I = 0xb34

    SYT_N = 0xb34

    SYT_D = 0x23028

    SYT_OFFSET = 0x2000 // presentation time offset

    SYT_Upper = SYT_OFFSET; // initialize to two cycle offset from transmission start time of zero

    SYT_Lower = 0; // initialize lower portion of SYT to zero

    SYT_Acc = SYT_N; // initialize accumulator

    while (transmitting pa ckets) { // loop, this calculation is done per DV frame (first CIP header)

    SYT_Acc += SYT_N; // increment accumulator by SYT_N

    if (SYT_Acc > SYT_D) {

    SYT_Lower += (SYT_I + 1); // increment SYT field

    SYT_Acc -= SYT_D; // decrement accumulator by SYT_D

    } else {

    SYT_Lower += SYT_I; // increment SYT field


    SYT_Upper += 0xa000; // base increment for upper portion of SYT

    // do base 3072 (0xc00) stuff for SYT lower and upper fields

    // remember, upper 4 bits are mod 16, and lower 12 bits are mod 3072

    if (SYT_Lower >= 0xc00) {

    SYT_Lower -= 0xc00;

    SYT_Upper += 0x1000;


    Full_SYT = SYT_Upper | SYT_Lower; // put two pieces together for full SYT

    Full_SYT &= 0x0000ffff; // it’s only a 16-bit field, and is then inserted into the

    // first CIP header of a dv frame


    Starting DV Transmission and SYT Feedback/Adjustment:

    The previous sections describe how to create CIP headers, calculate when to insert empty CIPs, and calculate the SYT field (“presentation time”) of the CIP header. In addition to the requirement for having an accurate SYT field, there is also a requirement for DV devices that this SYT field be two or three cycles ahead of the current IEEE-1394 cycle time (not more and not less). If the SYT drifts away from this range, the DV picture will break up on the DV device.

    (NOTE: I suspect this is because the DV devices have internal buffers that can only hold a couple of cycles worth of data, and use the SYT field as their presentation time, meaning that this SYT must be two to three cycles ahead of current bus time).

    In order to start the DV stream properly, and continue to maintain a proper SYT offset from current cycle time, there are a couple of requirements necessary:

    – The ability to begin a DV stream at a particular bus cycle time (hardware start-on-cycle capability)

    – The ability to record the actual “transmit” time of an isochronous buffer, for use in SYT “feedback.”

    It is possible to make DV transmission work without both of these requirements, but at least one is necessary (most IEEE-1394 hardware supports both of these capabilities).

    The start-on-cycle capability is needed so the DV stream can begin with the SYT field set to two or three cycles in advance of the current bus cycle time. If the empty CIP insertion rate and SYT calculation algorithms are exact (as they are, above), then SYT “feedback” is not strictly necessary, except in rare cases where isochronous cycles are dropped (resulting in SYT value drift).

    The isochronous “transmit” time capability is necessary so that the software maintaining the DV data stream (the one that updates CIP headers, data, and DMA programs), can use the actual “transmit” time to adjust the next SYT calculations if necessary (in case SYT value drift begins to occur). This feedback mechanism can be used without the start-on-cycle capability, but will usually result in the first few DV frames transmitted being dropped by the camcorder (until the feedback mechanism adjusts the SYT values to be at the proper offset from bus cycle time).

    These start-on-cycle and isochronous “transmit” time capabilities are necessary unless a real-time system is available to create/insert CIP headers and SYT values on-the-fly. Linux (and Windows) do not have these sorts of real-time capabilities, so the above-described pre-creation of CIP headers and SYT values are necessary.

    Following is some basic pseudo-code for the isochronous “transmit” time feedback capability. This feedback could occur once every DV frame transmission (around 30 times a second).

    Offset = NewCalculatedSytField – LastTransmitTimeStamp;

    If (Offset > UpperDriftLimit) {

    NewCalculatedSytField -= CycleAdjustment;

    } else if (Offset < LowerDriftLimit) {

    NewCalculatedSytField += CycleAdjustment;



    Offset = Difference between the previous transmit cycle time saved and the new calculated SYT field.

    NewCalculatedSytField = SYT field calculated using the SYT algorithm described above.

    LastTransmitTimeStamp = Previous transmit time stored by the DMA script program.

    UpperDriftLimit = The upper limit of how much the Offset can drift before noticeable jitter occurs.

    LowerDriftLimit = The lower limit of how much the Offset can drift before noticeable jitter occurs.

    CycleAdjustment = How much the new SYT field should be adjusted. A good value might be 0x1000 (one cycle).

    Putting it All Together:

    Proper transmission of DV data is much more complex than receiving DV data. It also requires more complex DMA programs and buffer handling.

    Hardware DMA program requirements are the following:

    – Ability to attach DMA descriptors describing “varying” sized IEEE-1394 isochronous payloads on the fly (for NTSC transmission, isochronous payloads of 8 and 488 bytes, excluding the isochronous header itself).

    – Ability to continue attaching and removing descriptors on the fly without stopping the DMA program itself.

    – The ability to start the DMA program begins isochronous transmission at a particular bus cycle.

    – Ability to have the DMA program record the actual isochronous transmission time, for use in SYT field feedback.

    OpenHCI hardware has all of these capabilities. TILynx and Pele (Adaptec) based hardware can also support these capabilities (with more sophisticated DMA programs).

    Allocation of Data Buffers:

    Memory buffers must be allocated to hold the CIP headers and CIP data to be transmitted. Enough memory must be allocated to handle the worst-case application and OS latency, as each buffer must be removed from the DMA program after transmission, updated with new CIP headers and data, and re-attached to the DMA program before the DMA program stops (where then DV data transmission would stop).

    For example, in the case of NTSC DV data transmission, each frame of DV data is 120000 bytes. Each CIP header is 8 bytes in length, and each CIP data packet is 480 bytes in length. This results in a 1220000 byte buffer of CIPs representing a frame of DV data. In order to handle, for example, a worst case latency of 1/3 second, we would need to allocate 10 buffers (based on around 30fps) of 1220000 bytes in size. This allows the CIP headers and data buffers to be filled in advance of actual transmission.

    NOTE: The reason that empty CIPs are not included in these allocated buffers is that empty CIPs are exactly the same as the CIP header of the next CIP in memory. Therefore, the DMA program describing the transmission of the empty CIP will just be pointing at the CIP header of the next CIP in memory. So, the CIP header actually get transmitted twice (once for the empty CIP, and once for the next full CIP).

    Typical pseudo DMA program:

    The DMA program will describe how the full CIP data packets and empty CIPs are to be transmitted over the IEEE-1394 bus to the DV device. For example, in the case of DV transmission of NTSC data, a section of a DMA program might look like the following:

    – Start transmission on particular cycle number
    – Transmit 488 bytes (full CIP)
    – Transmit 488 bytes (full CIP)
    . . .

    – Transmit 8 bytes (empty CIP)
    – Transmit 488 bytes (empty CIP)
    (note: finished transmitting full DV frame’s worth of data)
    – Store current cycle time
    – Generate interrupt
    – Branch to next set of DMA descriptors

    Note: The DMA program when transmitting the 8-byte packet is actually pointing to the first 8 bytes of the next full CIP (CIP header), saving the need to actually allocate separate memory for empty CIPs.


    Consider Reading to these articles:

    - Advertisement -
    - Advertisment -

    Most Popular

    Recent Comments