123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- /*
- * DV input/output over IEEE 1394 on OHCI chips
- * Copyright (C)2001 Daniel Maas <dmaas@dcine.com>
- * receive, proc_fs by Dan Dennedy <dan@dennedy.org>
- *
- * based on:
- * video1394.h - driver for OHCI 1394 boards
- * Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
- * Peter Schlaile <udbz@rz.uni-karlsruhe.de>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg 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.
- *
- * FFmpeg 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 FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #ifndef AVDEVICE_DV1394_H
- #define AVDEVICE_DV1394_H
- #define DV1394_DEFAULT_CHANNEL 63
- #define DV1394_DEFAULT_CARD 0
- #define DV1394_RING_FRAMES 20
- #define DV1394_WIDTH 720
- #define DV1394_NTSC_HEIGHT 480
- #define DV1394_PAL_HEIGHT 576
- /* This is the public user-space interface. Try not to break it. */
- #define DV1394_API_VERSION 0x20011127
- /* ********************
- ** **
- ** DV1394 API **
- ** **
- ********************
- There are two methods of operating the DV1394 DV output device.
- 1)
- The simplest is an interface based on write(): simply write
- full DV frames of data to the device, and they will be transmitted
- as quickly as possible. The FD may be set for non-blocking I/O,
- in which case you can use select() or poll() to wait for output
- buffer space.
- To set the DV output parameters (e.g. whether you want NTSC or PAL
- video), use the DV1394_INIT ioctl, passing in the parameters you
- want in a struct dv1394_init.
- Example 1:
- To play a raw .DV file: cat foo.DV > /dev/dv1394
- (cat will use write() internally)
- Example 2:
- static struct dv1394_init init = {
- 0x63, (broadcast channel)
- 4, (four-frame ringbuffer)
- DV1394_NTSC, (send NTSC video)
- 0, 0 (default empty packet rate)
- }
- ioctl(fd, DV1394_INIT, &init);
- while(1) {
- read( <a raw DV file>, buf, DV1394_NTSC_FRAME_SIZE );
- write( <the dv1394 FD>, buf, DV1394_NTSC_FRAME_SIZE );
- }
- 2)
- For more control over buffering, and to avoid unnecessary copies
- of the DV data, you can use the more sophisticated the mmap() interface.
- First, call the DV1394_INIT ioctl to specify your parameters,
- including the number of frames in the ringbuffer. Then, calling mmap()
- on the dv1394 device will give you direct access to the ringbuffer
- from which the DV card reads your frame data.
- The ringbuffer is simply one large, contiguous region of memory
- containing two or more frames of packed DV data. Each frame of DV data
- is 120000 bytes (NTSC) or 144000 bytes (PAL).
- Fill one or more frames in the ringbuffer, then use the DV1394_SUBMIT_FRAMES
- ioctl to begin I/O. You can use either the DV1394_WAIT_FRAMES ioctl
- or select()/poll() to wait until the frames are transmitted. Next, you'll
- need to call the DV1394_GET_STATUS ioctl to determine which ringbuffer
- frames are clear (ready to be filled with new DV data). Finally, use
- DV1394_SUBMIT_FRAMES again to send the new data to the DV output.
- Example: here is what a four-frame ringbuffer might look like
- during DV transmission:
- frame 0 frame 1 frame 2 frame 3
- *--------------------------------------*
- | CLEAR | DV data | DV data | CLEAR |
- *--------------------------------------*
- <ACTIVE>
- transmission goes in this direction --->>>
- The DV hardware is currently transmitting the data in frame 1.
- Once frame 1 is finished, it will automatically transmit frame 2.
- (if frame 2 finishes before frame 3 is submitted, the device
- will continue to transmit frame 2, and will increase the dropped_frames
- counter each time it repeats the transmission).
- If you called DV1394_GET_STATUS at this instant, you would
- receive the following values:
- n_frames = 4
- active_frame = 1
- first_clear_frame = 3
- n_clear_frames = 2
- At this point, you should write new DV data into frame 3 and optionally
- frame 0. Then call DV1394_SUBMIT_FRAMES to inform the device that
- it may transmit the new frames.
- ERROR HANDLING
- An error (buffer underflow/overflow or a break in the DV stream due
- to a 1394 bus reset) can be detected by checking the dropped_frames
- field of struct dv1394_status (obtained through the
- DV1394_GET_STATUS ioctl).
- The best way to recover from such an error is to re-initialize
- dv1394, either by using the DV1394_INIT ioctl call, or closing the
- file descriptor and opening it again. (note that you must unmap all
- ringbuffer mappings when closing the file descriptor, or else
- dv1394 will still be considered 'in use').
- MAIN LOOP
- For maximum efficiency and robustness against bus errors, you are
- advised to model the main loop of your application after the
- following pseudo-code example:
- (checks of system call return values omitted for brevity; always
- check return values in your code!)
- while( frames left ) {
- struct pollfd *pfd = ...;
- pfd->fd = dv1394_fd;
- pfd->revents = 0;
- pfd->events = POLLOUT | POLLIN; (OUT for transmit, IN for receive)
- (add other sources of I/O here)
- poll(pfd, 1, -1); (or select(); add a timeout if you want)
- if(pfd->revents) {
- struct dv1394_status status;
- ioctl(dv1394_fd, DV1394_GET_STATUS, &status);
- if(status.dropped_frames > 0) {
- reset_dv1394();
- } else {
- int i;
- for(i = 0; i < status.n_clear_frames; i++) {
- copy_DV_frame();
- }
- }
- }
- }
- where copy_DV_frame() reads or writes on the dv1394 file descriptor
- (read/write mode) or copies data to/from the mmap ringbuffer and
- then calls ioctl(DV1394_SUBMIT_FRAMES) to notify dv1394 that new
- frames are availble (mmap mode).
- reset_dv1394() is called in the event of a buffer
- underflow/overflow or a halt in the DV stream (e.g. due to a 1394
- bus reset). To guarantee recovery from the error, this function
- should close the dv1394 file descriptor (and munmap() all
- ringbuffer mappings, if you are using them), then re-open the
- dv1394 device (and re-map the ringbuffer).
- */
- /* maximum number of frames in the ringbuffer */
- #define DV1394_MAX_FRAMES 32
- /* number of *full* isochronous packets per DV frame */
- #define DV1394_NTSC_PACKETS_PER_FRAME 250
- #define DV1394_PAL_PACKETS_PER_FRAME 300
- /* size of one frame's worth of DV data, in bytes */
- #define DV1394_NTSC_FRAME_SIZE (480 * DV1394_NTSC_PACKETS_PER_FRAME)
- #define DV1394_PAL_FRAME_SIZE (480 * DV1394_PAL_PACKETS_PER_FRAME)
- /* ioctl() commands */
- enum {
- /* I don't like using 0 as a valid ioctl() */
- DV1394_INVALID = 0,
- /* get the driver ready to transmit video.
- pass a struct dv1394_init* as the parameter (see below),
- or NULL to get default parameters */
- DV1394_INIT,
- /* stop transmitting video and free the ringbuffer */
- DV1394_SHUTDOWN,
- /* submit N new frames to be transmitted, where
- the index of the first new frame is first_clear_buffer,
- and the index of the last new frame is
- (first_clear_buffer + N) % n_frames */
- DV1394_SUBMIT_FRAMES,
- /* block until N buffers are clear (pass N as the parameter)
- Because we re-transmit the last frame on underrun, there
- will at most be n_frames - 1 clear frames at any time */
- DV1394_WAIT_FRAMES,
- /* capture new frames that have been received, where
- the index of the first new frame is first_clear_buffer,
- and the index of the last new frame is
- (first_clear_buffer + N) % n_frames */
- DV1394_RECEIVE_FRAMES,
- DV1394_START_RECEIVE,
- /* pass a struct dv1394_status* as the parameter (see below) */
- DV1394_GET_STATUS,
- };
- enum pal_or_ntsc {
- DV1394_NTSC = 0,
- DV1394_PAL
- };
- /* this is the argument to DV1394_INIT */
- struct dv1394_init {
- /* DV1394_API_VERSION */
- unsigned int api_version;
- /* isochronous transmission channel to use */
- unsigned int channel;
- /* number of frames in the ringbuffer. Must be at least 2
- and at most DV1394_MAX_FRAMES. */
- unsigned int n_frames;
- /* send/receive PAL or NTSC video format */
- enum pal_or_ntsc format;
- /* the following are used only for transmission */
- /* set these to zero unless you want a
- non-default empty packet rate (see below) */
- unsigned long cip_n;
- unsigned long cip_d;
- /* set this to zero unless you want a
- non-default SYT cycle offset (default = 3 cycles) */
- unsigned int syt_offset;
- };
- /* NOTE: you may only allocate the DV frame ringbuffer once each time
- you open the dv1394 device. DV1394_INIT will fail if you call it a
- second time with different 'n_frames' or 'format' arguments (which
- would imply a different size for the ringbuffer). If you need a
- different buffer size, simply close and re-open the device, then
- initialize it with your new settings. */
- /* Q: What are cip_n and cip_d? */
- /*
- A: DV video streams do not utilize 100% of the potential bandwidth offered
- by IEEE 1394 (FireWire). To achieve the correct rate of data transmission,
- DV devices must periodically insert empty packets into the 1394 data stream.
- Typically there is one empty packet per 14-16 data-carrying packets.
- Some DV devices will accept a wide range of empty packet rates, while others
- require a precise rate. If the dv1394 driver produces empty packets at
- a rate that your device does not accept, you may see ugly patterns on the
- DV output, or even no output at all.
- The default empty packet insertion rate seems to work for many people; if
- your DV output is stable, you can simply ignore this discussion. However,
- we have exposed the empty packet rate as a parameter to support devices that
- do not work with the default rate.
- The decision to insert an empty packet is made with a numerator/denominator
- algorithm. Empty packets are produced at an average rate of CIP_N / CIP_D.
- You can alter the empty packet rate by passing non-zero values for cip_n
- and cip_d to the INIT ioctl.
- */
- struct dv1394_status {
- /* this embedded init struct returns the current dv1394
- parameters in use */
- struct dv1394_init init;
- /* the ringbuffer frame that is currently being
- displayed. (-1 if the device is not transmitting anything) */
- int active_frame;
- /* index of the first buffer (ahead of active_frame) that
- is ready to be filled with data */
- unsigned int first_clear_frame;
- /* how many buffers, including first_clear_buffer, are
- ready to be filled with data */
- unsigned int n_clear_frames;
- /* how many times the DV stream has underflowed, overflowed,
- or otherwise encountered an error, since the previous call
- to DV1394_GET_STATUS */
- unsigned int dropped_frames;
- /* N.B. The dropped_frames counter is only a lower bound on the actual
- number of dropped frames, with the special case that if dropped_frames
- is zero, then it is guaranteed that NO frames have been dropped
- since the last call to DV1394_GET_STATUS.
- */
- };
- #endif /* AVDEVICE_DV1394_H */
|