![]() |
IEEE 1394 for Linux | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Home |
Introduction
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. A CIP header for DV data is as follows:
SID = Source Node ID 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. 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 algoritm 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 (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 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 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 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
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 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 sort 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; } Where, 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. -
Ability to start the dma program begin 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 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 because 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. Other Interesting References
http://www.adaptec.com/technology/standards/1394formats.html#top
(introduction) http://desktopvideo.miningco.com/compute/desktopvideo/library/weekly/aa032698.htm
(a bit about DV coding and format) http://www.1394ta.org/Technology/Specifications/specifications.htm
(look at the AVC specifications) ftp://ftp.t10.org/t10/drafts/sbp3/sbp3r01.pdf
(look at isochronous sections) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||