You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	Update iec61883 to handle multiple devices, and allow
selection of DV device by its GUID
This commit is contained in:
		| @@ -224,6 +224,13 @@ Set maxiumum size of buffer for incoming data, in frames. For DV, this | ||||
| is an exact value. For HDV, it is not frame exact, since HDV does | ||||
| not have a fixed frame size. | ||||
|  | ||||
| @item dvguid | ||||
| Select the capture device by specifying it's GUID. Capturing will only | ||||
| be performed from the specified device and fails if no device with the | ||||
| given GUID is found. This is useful to select the input if multiple | ||||
| devices are connected at the same time. | ||||
| Look at /sys/bus/firewire/devices to find out the GUIDs. | ||||
|  | ||||
| @end table | ||||
|  | ||||
| @subsection Examples | ||||
|   | ||||
| @@ -67,6 +67,8 @@ struct iec61883_data { | ||||
|     DVPacket *queue_first;              ///< first element of packet queue | ||||
|     DVPacket *queue_last;               ///< last element of packet queue | ||||
|  | ||||
|     char *device_guid;                  ///< to select one of multiple DV devices | ||||
|  | ||||
|     int packets;                        ///< Number of packets queued | ||||
|     int max_packets;                    ///< Max. number of packets in queue | ||||
|  | ||||
| @@ -138,7 +140,7 @@ static int iec61883_callback(unsigned char *data, int length, | ||||
|  | ||||
| exit: | ||||
| #ifdef THREADS | ||||
|     pthread_cond_signal(&dv->cond); | ||||
|     pthread_cond_broadcast(&dv->cond); | ||||
|     pthread_mutex_unlock(&dv->mutex); | ||||
| #endif | ||||
|     return ret; | ||||
| @@ -169,7 +171,7 @@ static void *iec61883_receive_task(void *opaque) | ||||
| #ifdef THREADS | ||||
|             pthread_mutex_lock(&dv->mutex); | ||||
|             dv->eof = 1; | ||||
|             pthread_cond_signal(&dv->cond); | ||||
|             pthread_cond_broadcast(&dv->cond); | ||||
|             pthread_mutex_unlock(&dv->mutex); | ||||
| #else | ||||
|             dv->eof = 1; | ||||
| @@ -239,6 +241,7 @@ static int iec61883_read_header(AVFormatContext *context) | ||||
|     int port = -1; | ||||
|     int response; | ||||
|     int i, j = 0; | ||||
|     uint64_t guid = 0; | ||||
|  | ||||
|     dv->input_port = -1; | ||||
|     dv->output_port = -1; | ||||
| @@ -267,25 +270,48 @@ static int iec61883_read_header(AVFormatContext *context) | ||||
|         goto fail; | ||||
|     } | ||||
|  | ||||
|     /* Select first AV/C tape recorder player node */ | ||||
|     if (dv->device_guid) { | ||||
|         if (sscanf(dv->device_guid, "%llx", (long long unsigned int *)&guid) != 1) { | ||||
|             av_log(context, AV_LOG_INFO, "Invalid dvguid parameter: %s\n", | ||||
|                    dv->device_guid); | ||||
|             goto fail; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     for (; j < nb_ports && port==-1; ++j) { | ||||
|         if (raw1394_set_port(dv->raw1394, j)) { | ||||
|         raw1394_destroy_handle(dv->raw1394); | ||||
|  | ||||
|         if (!(dv->raw1394 = raw1394_new_handle_on_port(j))) { | ||||
|             av_log(context, AV_LOG_ERROR, "Failed setting IEEE1394 port.\n"); | ||||
|             goto fail; | ||||
|         } | ||||
|  | ||||
|         for (i=0; i<raw1394_get_nodecount(dv->raw1394); ++i) { | ||||
|             if (rom1394_get_directory(dv->raw1394, i, &rom_dir) < 0) | ||||
|                 continue; | ||||
|             if (((rom1394_get_node_type(&rom_dir) == ROM1394_NODE_TYPE_AVC) && | ||||
|                  avc1394_check_subunit_type(dv->raw1394, i, AVC1394_SUBUNIT_TYPE_VCR)) || | ||||
|                 (rom_dir.unit_spec_id == MOTDCT_SPEC_ID)) { | ||||
|  | ||||
|             /* Select device explicitly by GUID */ | ||||
|  | ||||
|             if (guid > 1) { | ||||
|                 if (guid == rom1394_get_guid(dv->raw1394, i)) { | ||||
|                     dv->node = i; | ||||
|                     port = j; | ||||
|                     break; | ||||
|                 } | ||||
|             } else { | ||||
|  | ||||
|                 /* Select first AV/C tape recorder player node */ | ||||
|  | ||||
|                 if (rom1394_get_directory(dv->raw1394, i, &rom_dir) < 0) | ||||
|                     continue; | ||||
|                 if (((rom1394_get_node_type(&rom_dir) == ROM1394_NODE_TYPE_AVC) && | ||||
|                      avc1394_check_subunit_type(dv->raw1394, i, AVC1394_SUBUNIT_TYPE_VCR)) || | ||||
|                     (rom_dir.unit_spec_id == MOTDCT_SPEC_ID)) { | ||||
|                     rom1394_free_directory(&rom_dir); | ||||
|                     dv->node = i; | ||||
|                     port = j; | ||||
|                     break; | ||||
|                 } | ||||
|                 rom1394_free_directory(&rom_dir); | ||||
|                 dv->node = i; | ||||
|                 port = j; | ||||
|                 break; | ||||
|             } | ||||
|             rom1394_free_directory(&rom_dir); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -294,6 +320,10 @@ static int iec61883_read_header(AVFormatContext *context) | ||||
|         goto fail; | ||||
|     } | ||||
|  | ||||
|     /* Provide bus sanity for multiple connections */ | ||||
|  | ||||
|     iec61883_cmp_normalize_output(dv->raw1394, 0xffc0 | dv->node); | ||||
|  | ||||
|     /* Find out if device is DV or HDV */ | ||||
|  | ||||
|     if (dv->type == IEC61883_AUTO) { | ||||
| @@ -444,6 +474,7 @@ static const AVOption options[] = { | ||||
|     { "dv",     "force device being treated as DV device", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_DV},   0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" }, | ||||
|     { "hdv" ,   "force device being treated as HDV device", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_HDV},  0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" }, | ||||
|     { "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 }, | ||||
|     { "dvguid", "select one of multiple DV devices by its GUID", offsetof(struct iec61883_data, device_guid), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM }, | ||||
|     { NULL }, | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user