00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <unistd.h>
00023 #include <fcntl.h>
00024 #include <errno.h>
00025 #include <sys/ioctl.h>
00026 #include <sys/mman.h>
00027 #include <sys/poll.h>
00028 #include <sys/time.h>
00029 #include <time.h>
00030
00031 #include "avformat.h"
00032
00033 #undef DV1394_DEBUG
00034
00035 #include "dv1394.h"
00036 #include "dv.h"
00037
00038 struct dv1394_data {
00039 int fd;
00040 int channel;
00041 int format;
00042
00043 uint8_t *ring;
00044 int index;
00045 int avail;
00046 int done;
00047
00048 DVDemuxContext* dv_demux;
00049 };
00050
00051
00052
00053
00054
00055
00056
00057 static int dv1394_reset(struct dv1394_data *dv)
00058 {
00059 struct dv1394_init init;
00060
00061 init.channel = dv->channel;
00062 init.api_version = DV1394_API_VERSION;
00063 init.n_frames = DV1394_RING_FRAMES;
00064 init.format = DV1394_PAL;
00065
00066 if (ioctl(dv->fd, DV1394_INIT, &init) < 0)
00067 return -1;
00068
00069 dv->avail = dv->done = 0;
00070 return 0;
00071 }
00072
00073 static int dv1394_start(struct dv1394_data *dv)
00074 {
00075
00076 if (ioctl(dv->fd, DV1394_START_RECEIVE, 0) < 0) {
00077 av_log(NULL, AV_LOG_ERROR, "Failed to start receiver: %s\n", strerror(errno));
00078 return -1;
00079 }
00080 return 0;
00081 }
00082
00083 static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap)
00084 {
00085 struct dv1394_data *dv = context->priv_data;
00086
00087 dv->dv_demux = dv_init_demux(context);
00088 if (!dv->dv_demux)
00089 goto failed;
00090
00091 if (ap->standard && !strcasecmp(ap->standard, "pal"))
00092 dv->format = DV1394_PAL;
00093 else
00094 dv->format = DV1394_NTSC;
00095
00096 if (ap->channel)
00097 dv->channel = ap->channel;
00098 else
00099 dv->channel = DV1394_DEFAULT_CHANNEL;
00100
00101
00102 dv->fd = open(context->filename, O_RDONLY);
00103 if (dv->fd < 0) {
00104 av_log(context, AV_LOG_ERROR, "Failed to open DV interface: %s\n", strerror(errno));
00105 goto failed;
00106 }
00107
00108 if (dv1394_reset(dv) < 0) {
00109 av_log(context, AV_LOG_ERROR, "Failed to initialize DV interface: %s\n", strerror(errno));
00110 goto failed;
00111 }
00112
00113 dv->ring = mmap(NULL, DV1394_PAL_FRAME_SIZE * DV1394_RING_FRAMES,
00114 PROT_READ, MAP_PRIVATE, dv->fd, 0);
00115 if (dv->ring == MAP_FAILED) {
00116 av_log(context, AV_LOG_ERROR, "Failed to mmap DV ring buffer: %s\n", strerror(errno));
00117 goto failed;
00118 }
00119
00120 if (dv1394_start(dv) < 0)
00121 goto failed;
00122
00123 return 0;
00124
00125 failed:
00126 close(dv->fd);
00127 return AVERROR(EIO);
00128 }
00129
00130 static int dv1394_read_packet(AVFormatContext *context, AVPacket *pkt)
00131 {
00132 struct dv1394_data *dv = context->priv_data;
00133 int size;
00134
00135 size = dv_get_packet(dv->dv_demux, pkt);
00136 if (size > 0)
00137 return size;
00138
00139 if (!dv->avail) {
00140 struct dv1394_status s;
00141 struct pollfd p;
00142
00143 if (dv->done) {
00144
00145 if (ioctl(dv->fd, DV1394_RECEIVE_FRAMES, dv->done) < 0) {
00146
00147
00148
00149
00150 av_log(context, AV_LOG_ERROR, "DV1394: Ring buffer overflow. Reseting ..\n");
00151
00152 dv1394_reset(dv);
00153 dv1394_start(dv);
00154 }
00155 dv->done = 0;
00156 }
00157
00158
00159 restart_poll:
00160 p.fd = dv->fd;
00161 p.events = POLLIN | POLLERR | POLLHUP;
00162 if (poll(&p, 1, -1) < 0) {
00163 if (errno == EAGAIN || errno == EINTR)
00164 goto restart_poll;
00165 av_log(context, AV_LOG_ERROR, "Poll failed: %s\n", strerror(errno));
00166 return AVERROR(EIO);
00167 }
00168
00169 if (ioctl(dv->fd, DV1394_GET_STATUS, &s) < 0) {
00170 av_log(context, AV_LOG_ERROR, "Failed to get status: %s\n", strerror(errno));
00171 return AVERROR(EIO);
00172 }
00173 #ifdef DV1394_DEBUG
00174 av_log(context, AV_LOG_DEBUG, "DV1394: status\n"
00175 "\tactive_frame\t%d\n"
00176 "\tfirst_clear_frame\t%d\n"
00177 "\tn_clear_frames\t%d\n"
00178 "\tdropped_frames\t%d\n",
00179 s.active_frame, s.first_clear_frame,
00180 s.n_clear_frames, s.dropped_frames);
00181 #endif
00182
00183 dv->avail = s.n_clear_frames;
00184 dv->index = s.first_clear_frame;
00185 dv->done = 0;
00186
00187 if (s.dropped_frames) {
00188 av_log(context, AV_LOG_ERROR, "DV1394: Frame drop detected (%d). Reseting ..\n",
00189 s.dropped_frames);
00190
00191 dv1394_reset(dv);
00192 dv1394_start(dv);
00193 }
00194 }
00195
00196 #ifdef DV1394_DEBUG
00197 av_log(context, AV_LOG_DEBUG, "index %d, avail %d, done %d\n", dv->index, dv->avail,
00198 dv->done);
00199 #endif
00200
00201 size = dv_produce_packet(dv->dv_demux, pkt,
00202 dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE),
00203 DV1394_PAL_FRAME_SIZE);
00204 dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
00205 dv->done++; dv->avail--;
00206
00207 return size;
00208 }
00209
00210 static int dv1394_close(AVFormatContext * context)
00211 {
00212 struct dv1394_data *dv = context->priv_data;
00213
00214
00215 if (ioctl(dv->fd, DV1394_SHUTDOWN, 0) < 0)
00216 av_log(context, AV_LOG_ERROR, "Failed to shutdown DV1394: %s\n", strerror(errno));
00217
00218
00219 if (munmap(dv->ring, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES) < 0)
00220 av_log(context, AV_LOG_ERROR, "Failed to munmap DV1394 ring buffer: %s\n", strerror(errno));
00221
00222 close(dv->fd);
00223 av_free(dv->dv_demux);
00224
00225 return 0;
00226 }
00227
00228 AVInputFormat dv1394_demuxer = {
00229 .name = "dv1394",
00230 .long_name = "dv1394 A/V grab",
00231 .priv_data_size = sizeof(struct dv1394_data),
00232 .read_header = dv1394_read_header,
00233 .read_packet = dv1394_read_packet,
00234 .read_close = dv1394_close,
00235 .flags = AVFMT_NOFILE
00236 };