00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include <sys/poll.h>
00027 #include <libraw1394/raw1394.h>
00028 #include <libavc1394/avc1394.h>
00029 #include <libavc1394/rom1394.h>
00030 #include <libiec61883/iec61883.h>
00031 #include "libavformat/dv.h"
00032 #include "libavformat/mpegts.h"
00033 #include "libavutil/opt.h"
00034 #include "avdevice.h"
00035
00036 #define THREADS HAVE_PTHREADS
00037
00038 #if THREADS
00039 #include <pthread.h>
00040 #endif
00041
00042 #define MOTDCT_SPEC_ID 0x00005068
00043 #define IEC61883_AUTO 0
00044 #define IEC61883_DV 1
00045 #define IEC61883_HDV 2
00046
00052 typedef struct DVPacket {
00053 uint8_t *buf;
00054 int len;
00055 struct DVPacket *next;
00056 } DVPacket;
00057
00058 struct iec61883_data {
00059 AVClass *class;
00060 raw1394handle_t raw1394;
00061 iec61883_dv_fb_t iec61883_dv;
00062 iec61883_mpeg2_t iec61883_mpeg2;
00063
00064 DVDemuxContext *dv_demux;
00065 MpegTSContext *mpeg_demux;
00066
00067 DVPacket *queue_first;
00068 DVPacket *queue_last;
00069
00070 int packets;
00071 int max_packets;
00072
00073 int bandwidth;
00074 int channel;
00075 int input_port;
00076 int type;
00077 int node;
00078 int output_port;
00079 int thread_loop;
00080 int receiving;
00081 int receive_error;
00082 int eof;
00083
00084 struct pollfd raw1394_poll;
00085
00087 int (*parse_queue)(struct iec61883_data *dv, AVPacket *pkt);
00088
00089 #if THREADS
00090 pthread_t receive_task_thread;
00091 pthread_mutex_t mutex;
00092 pthread_cond_t cond;
00093 #endif
00094 };
00095
00096 static int iec61883_callback(unsigned char *data, int length,
00097 int complete, void *callback_data)
00098 {
00099 struct iec61883_data *dv = callback_data;
00100 DVPacket *packet;
00101 int ret;
00102
00103 #ifdef THREADS
00104 pthread_mutex_lock(&dv->mutex);
00105 #endif
00106
00107 if (dv->packets >= dv->max_packets) {
00108 av_log(NULL, AV_LOG_ERROR, "DV packet queue overrun, dropping.\n");
00109 ret = 0;
00110 goto exit;
00111 }
00112
00113 packet = av_mallocz(sizeof(*packet));
00114 if (!packet) {
00115 ret = -1;
00116 goto exit;
00117 }
00118
00119 packet->buf = av_malloc(length);
00120 if (!packet->buf) {
00121 ret = -1;
00122 goto exit;
00123 }
00124 packet->len = length;
00125
00126 memcpy(packet->buf, data, length);
00127
00128 if (dv->queue_first) {
00129 dv->queue_last->next = packet;
00130 dv->queue_last = packet;
00131 } else {
00132 dv->queue_first = packet;
00133 dv->queue_last = packet;
00134 }
00135 dv->packets++;
00136
00137 ret = 0;
00138
00139 exit:
00140 #ifdef THREADS
00141 pthread_cond_signal(&dv->cond);
00142 pthread_mutex_unlock(&dv->mutex);
00143 #endif
00144 return ret;
00145 }
00146
00147 static void *iec61883_receive_task(void *opaque)
00148 {
00149 struct iec61883_data *dv = (struct iec61883_data *)opaque;
00150 int result;
00151
00152 #ifdef THREADS
00153 while (dv->thread_loop)
00154 #endif
00155 {
00156 while ((result = poll(&dv->raw1394_poll, 1, 200)) < 0) {
00157 if (!(errno == EAGAIN || errno == EINTR)) {
00158 av_log(NULL, AV_LOG_ERROR, "Raw1394 poll error occurred.\n");
00159 dv->receive_error = AVERROR(EIO);
00160 return NULL;
00161 }
00162 }
00163 if (result > 0 && ((dv->raw1394_poll.revents & POLLIN)
00164 || (dv->raw1394_poll.revents & POLLPRI))) {
00165 dv->receiving = 1;
00166 raw1394_loop_iterate(dv->raw1394);
00167 } else if (dv->receiving) {
00168 av_log(NULL, AV_LOG_ERROR, "No more input data available\n");
00169 #ifdef THREADS
00170 pthread_mutex_lock(&dv->mutex);
00171 dv->eof = 1;
00172 pthread_cond_signal(&dv->cond);
00173 pthread_mutex_unlock(&dv->mutex);
00174 #else
00175 dv->eof = 1;
00176 #endif
00177 return NULL;
00178 }
00179 }
00180
00181 return NULL;
00182 }
00183
00184 static int iec61883_parse_queue_dv(struct iec61883_data *dv, AVPacket *pkt)
00185 {
00186 DVPacket *packet;
00187 int size;
00188
00189 size = avpriv_dv_get_packet(dv->dv_demux, pkt);
00190 if (size > 0)
00191 return size;
00192
00193 packet = dv->queue_first;
00194 if (!packet)
00195 return -1;
00196
00197 size = avpriv_dv_produce_packet(dv->dv_demux, pkt,
00198 packet->buf, packet->len, -1);
00199 pkt->destruct = av_destruct_packet;
00200 dv->queue_first = packet->next;
00201 av_free(packet);
00202 dv->packets--;
00203
00204 if (size > 0)
00205 return size;
00206
00207 return -1;
00208 }
00209
00210 static int iec61883_parse_queue_hdv(struct iec61883_data *dv, AVPacket *pkt)
00211 {
00212 DVPacket *packet;
00213 int size;
00214
00215 while (dv->queue_first) {
00216 packet = dv->queue_first;
00217 size = ff_mpegts_parse_packet(dv->mpeg_demux, pkt, packet->buf,
00218 packet->len);
00219 dv->queue_first = packet->next;
00220 av_free(packet->buf);
00221 av_free(packet);
00222 dv->packets--;
00223
00224 if (size > 0)
00225 return size;
00226 }
00227
00228 return -1;
00229 }
00230
00231 static int iec61883_read_header(AVFormatContext *context)
00232 {
00233 struct iec61883_data *dv = context->priv_data;
00234 struct raw1394_portinfo pinf[16];
00235 rom1394_directory rom_dir;
00236 char *endptr;
00237 int inport;
00238 int nb_ports;
00239 int port = -1;
00240 int response;
00241 int i, j = 0;
00242
00243 dv->input_port = -1;
00244 dv->output_port = -1;
00245 dv->channel = -1;
00246
00247 dv->raw1394 = raw1394_new_handle();
00248
00249 if (!dv->raw1394) {
00250 av_log(context, AV_LOG_ERROR, "Failed to open IEEE1394 interface.\n");
00251 return AVERROR(EIO);
00252 }
00253
00254 if ((nb_ports = raw1394_get_port_info(dv->raw1394, pinf, 16)) < 0) {
00255 av_log(context, AV_LOG_ERROR, "Failed to get number of IEEE1394 ports.\n");
00256 goto fail;
00257 }
00258
00259 inport = strtol(context->filename, &endptr, 10);
00260 if (endptr != context->filename && *endptr == '\0') {
00261 av_log(context, AV_LOG_INFO, "Selecting IEEE1394 port: %d\n", inport);
00262 j = inport;
00263 nb_ports = inport + 1;
00264 } else if (strcmp(context->filename, "auto")) {
00265 av_log(context, AV_LOG_ERROR, "Invalid input \"%s\", you should specify "
00266 "\"auto\" for auto-detection, or the port number.\n", context->filename);
00267 goto fail;
00268 }
00269
00270
00271
00272 for (; j < nb_ports && port==-1; ++j) {
00273 if (raw1394_set_port(dv->raw1394, j)) {
00274 av_log(context, AV_LOG_ERROR, "Failed setting IEEE1394 port.\n");
00275 goto fail;
00276 }
00277 for (i=0; i<raw1394_get_nodecount(dv->raw1394); ++i) {
00278 if (rom1394_get_directory(dv->raw1394, i, &rom_dir) < 0)
00279 continue;
00280 if (((rom1394_get_node_type(&rom_dir) == ROM1394_NODE_TYPE_AVC) &&
00281 avc1394_check_subunit_type(dv->raw1394, i, AVC1394_SUBUNIT_TYPE_VCR)) ||
00282 (rom_dir.unit_spec_id == MOTDCT_SPEC_ID)) {
00283 rom1394_free_directory(&rom_dir);
00284 dv->node = i;
00285 port = j;
00286 break;
00287 }
00288 rom1394_free_directory(&rom_dir);
00289 }
00290 }
00291
00292 if (port == -1) {
00293 av_log(context, AV_LOG_ERROR, "No AV/C devices found.\n");
00294 goto fail;
00295 }
00296
00297
00298
00299 if (dv->type == IEC61883_AUTO) {
00300 response = avc1394_transaction(dv->raw1394, dv->node,
00301 AVC1394_CTYPE_STATUS |
00302 AVC1394_SUBUNIT_TYPE_TAPE_RECORDER |
00303 AVC1394_SUBUNIT_ID_0 |
00304 AVC1394_VCR_COMMAND_OUTPUT_SIGNAL_MODE |
00305 0xFF, 2);
00306 response = AVC1394_GET_OPERAND0(response);
00307 dv->type = (response == 0x10 || response == 0x90 || response == 0x1A || response == 0x9A) ?
00308 IEC61883_HDV : IEC61883_DV;
00309 }
00310
00311
00312
00313 dv->channel = iec61883_cmp_connect(dv->raw1394, dv->node, &dv->output_port,
00314 raw1394_get_local_id(dv->raw1394),
00315 &dv->input_port, &dv->bandwidth);
00316
00317 if (dv->channel < 0)
00318 dv->channel = 63;
00319
00320 if (!dv->max_packets)
00321 dv->max_packets = 100;
00322
00323 if (dv->type == IEC61883_HDV) {
00324
00325
00326
00327 avformat_new_stream(context, NULL);
00328
00329 dv->mpeg_demux = ff_mpegts_parse_open(context);
00330 if (!dv->mpeg_demux)
00331 goto fail;
00332
00333 dv->parse_queue = iec61883_parse_queue_hdv;
00334
00335 dv->iec61883_mpeg2 = iec61883_mpeg2_recv_init(dv->raw1394,
00336 (iec61883_mpeg2_recv_t)iec61883_callback,
00337 dv);
00338
00339 dv->max_packets *= 766;
00340 } else {
00341
00342
00343
00344 dv->dv_demux = avpriv_dv_init_demux(context);
00345 if (!dv->dv_demux)
00346 goto fail;
00347
00348 dv->parse_queue = iec61883_parse_queue_dv;
00349
00350 dv->iec61883_dv = iec61883_dv_fb_init(dv->raw1394, iec61883_callback, dv);
00351 }
00352
00353 dv->raw1394_poll.fd = raw1394_get_fd(dv->raw1394);
00354 dv->raw1394_poll.events = POLLIN | POLLERR | POLLHUP | POLLPRI;
00355
00356
00357
00358 if (dv->type == IEC61883_HDV)
00359 iec61883_mpeg2_recv_start(dv->iec61883_mpeg2, dv->channel);
00360 else
00361 iec61883_dv_fb_start(dv->iec61883_dv, dv->channel);
00362
00363 #if THREADS
00364 dv->thread_loop = 1;
00365 pthread_mutex_init(&dv->mutex, NULL);
00366 pthread_cond_init(&dv->cond, NULL);
00367 pthread_create(&dv->receive_task_thread, NULL, iec61883_receive_task, dv);
00368 #endif
00369
00370 return 0;
00371
00372 fail:
00373 raw1394_destroy_handle(dv->raw1394);
00374 return AVERROR(EIO);
00375 }
00376
00377 static int iec61883_read_packet(AVFormatContext *context, AVPacket *pkt)
00378 {
00379 struct iec61883_data *dv = context->priv_data;
00380 int size;
00381
00386 #ifdef THREADS
00387 pthread_mutex_lock(&dv->mutex);
00388 while ((size = dv->parse_queue(dv, pkt)) == -1)
00389 if (!dv->eof)
00390 pthread_cond_wait(&dv->cond, &dv->mutex);
00391 else
00392 break;
00393 pthread_mutex_unlock(&dv->mutex);
00394 #else
00395 int result;
00396 while ((size = dv->parse_queue(dv, pkt)) == -1) {
00397 iec61883_receive_task((void *)dv);
00398 if (dv->receive_error)
00399 return dv->receive_error;
00400 }
00401 #endif
00402
00403 return size;
00404 }
00405
00406 static int iec61883_close(AVFormatContext *context)
00407 {
00408 struct iec61883_data *dv = context->priv_data;
00409
00410 #if THREADS
00411 dv->thread_loop = 0;
00412 pthread_join(dv->receive_task_thread, NULL);
00413 pthread_cond_destroy(&dv->cond);
00414 pthread_mutex_destroy(&dv->mutex);
00415 #endif
00416
00417 if (dv->type == IEC61883_HDV) {
00418 iec61883_mpeg2_recv_stop(dv->iec61883_mpeg2);
00419 iec61883_mpeg2_close(dv->iec61883_mpeg2);
00420 ff_mpegts_parse_close(dv->mpeg_demux);
00421 } else {
00422 iec61883_dv_fb_stop(dv->iec61883_dv);
00423 iec61883_dv_fb_close(dv->iec61883_dv);
00424 }
00425 while (dv->queue_first) {
00426 DVPacket *packet = dv->queue_first;
00427 dv->queue_first = packet->next;
00428 av_free(packet->buf);
00429 av_free(packet);
00430 }
00431
00432 iec61883_cmp_disconnect(dv->raw1394, dv->node, dv->output_port,
00433 raw1394_get_local_id(dv->raw1394),
00434 dv->input_port, dv->channel, dv->bandwidth);
00435
00436 raw1394_destroy_handle(dv->raw1394);
00437
00438 return 0;
00439 }
00440
00441 static const AVOption options[] = {
00442 { "dvtype", "override autodetection of DV/HDV", offsetof(struct iec61883_data, type), AV_OPT_TYPE_INT, {.i64 = IEC61883_AUTO}, IEC61883_AUTO, IEC61883_HDV, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
00443 { "auto", "auto detect DV/HDV", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_AUTO}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
00444 { "dv", "force device being treated as DV device", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_DV}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
00445 { "hdv" , "force device being treated as HDV device", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_HDV}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
00446 { "dvbuffer", "set queue buffer size (in packets)", offsetof(struct iec61883_data, max_packets), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
00447 { NULL },
00448 };
00449
00450 static const AVClass iec61883_class = {
00451 .class_name = "iec61883 indev",
00452 .item_name = av_default_item_name,
00453 .option = options,
00454 .version = LIBAVUTIL_VERSION_INT,
00455 };
00456
00457 AVInputFormat ff_iec61883_demuxer = {
00458 .name = "iec61883",
00459 .long_name = NULL_IF_CONFIG_SMALL("libiec61883 (new DV1394) A/V input device"),
00460 .priv_data_size = sizeof(struct iec61883_data),
00461 .read_header = iec61883_read_header,
00462 .read_packet = iec61883_read_packet,
00463 .read_close = iec61883_close,
00464 .flags = AVFMT_NOFILE,
00465 .priv_class = &iec61883_class,
00466 };