Пример #1
0
static int demux_rtp_control(struct demuxer *demuxer, int cmd, void *arg)
{
    Nemesi_DemuxerStreamData * ndsd = demuxer->priv;
    rtsp_ctrl * ctl = ndsd->rtsp;
    sdp_attr * r_attr = NULL;
    sdp_range r = {0, 0};
    double time = ndsd->time[NEMESI_SESSION_VIDEO] ?
                  ndsd->time[NEMESI_SESSION_VIDEO] :
                  ndsd->time[NEMESI_SESSION_AUDIO];

    if (!ctl->rtsp_queue)
        return DEMUXER_CTRL_DONTKNOW;

    r_attr = sdp_get_attr(ctl->rtsp_queue->info->attr_list, "range");
    if (r_attr)
        r = sdp_parse_range(r_attr->value);

    switch (cmd) {
        case DEMUXER_CTRL_GET_TIME_LENGTH:
            if (r.end == 0)
                return DEMUXER_CTRL_DONTKNOW;

            *((double *)arg) = ((double)r.end) - ((double)r.begin);
            return DEMUXER_CTRL_OK;

        case DEMUXER_CTRL_GET_PERCENT_POS:
            if (r.end == 0)
                return DEMUXER_CTRL_DONTKNOW;

            *((int *)arg) = (int)( time * 100 / (r.end - r.begin) );
            return DEMUXER_CTRL_OK;
        default:
           return DEMUXER_CTRL_DONTKNOW;
    }
}
Пример #2
0
/*
 * Configure PnP Information results
 */
static int
config_pnp(prop_dictionary_t dict, sdp_data_t *rec)
{
	sdp_data_t value;
	uintmax_t v;
	uint16_t attr;
	int vendor, product, source;

	vendor = -1;
	product = -1;
	source = -1;

	while (sdp_get_attr(rec, &attr, &value)) {
		switch (attr) {
		case 0x0201:	/* Vendor ID */
			if (sdp_get_uint(&value, &v)
			    && v <= UINT16_MAX)
				vendor = (int)v;

			break;

		case 0x0202:	/* Product ID */
			if (sdp_get_uint(&value, &v)
			    && v <= UINT16_MAX)
				product = (int)v;

			break;

		case 0x0205:	/* Vendor ID Source */
			if (sdp_get_uint(&value, &v)
			    && v <= UINT16_MAX)
				source = (int)v;

			break;

		default:
			break;
		}
	}

	if (vendor == -1 || product == -1)
		return ENOATTR;

	if (source != 0x0002)	/* "USB Implementers Forum" */
		return ENOATTR;

	if (!prop_dictionary_set_uint16(dict, BTDEVvendor, (uint16_t)vendor))
		return errno;

	if (!prop_dictionary_set_uint16(dict, BTDEVproduct, (uint16_t)product))
		return errno;

	return 0;
}
Пример #3
0
static void demux_seek_rtp(demuxer_t *demuxer, float rel_seek_secs,
                           float audio_delay, int flags)
{
    Nemesi_DemuxerStreamData * ndsd = demuxer->priv;
    rtsp_ctrl * ctl = ndsd->rtsp;
    sdp_attr * r_attr = NULL;
    sdp_range r = {0, 0};
    double time = ndsd->time[NEMESI_SESSION_VIDEO] ?
                  ndsd->time[NEMESI_SESSION_VIDEO] :
                  ndsd->time[NEMESI_SESSION_AUDIO];

    if (!ctl->rtsp_queue)
        return;

    r_attr = sdp_get_attr(ctl->rtsp_queue->info->attr_list, "range");
    if (r_attr)
        r = sdp_parse_range(r_attr->value);

    //flags & 1 -> absolute seek
    //flags & 2 -> percent seek
    if (flags == 0) {
        time += rel_seek_secs;
        if (time < r.begin)
            time = r.begin;
        else if (time > r.end)
            time = r.end;
        ndsd->seek = time;

        mp_msg(MSGT_DEMUX,MSGL_WARN,"libNemesi SEEK %f on %f - %f)\n",
           time, r.begin, r.end);

        if (!rtsp_seek(ctl, time, 0)) {
            RTSP_Error err = rtsp_wait(ctl);
            if (err.got_error) {
                mp_msg(MSGT_DEMUX, MSGL_ERR,
                       "Error Performing Seek: %s\n",
                       err.message.reply_str);
                demuxer->stream->eof = 1;
            }
            else
                mp_msg(MSGT_DEMUX, MSGL_INFO, "Seek, performed\n");
        }
        else {
            mp_msg(MSGT_DEMUX, MSGL_ERR, "Unable to pause stream to perform seek\n");
            demuxer->stream->eof = 1;
        }
    }
    else
        mp_msg(MSGT_DEMUX, MSGL_ERR, "Unsupported seek type\n");
}
Пример #4
0
ATF_TC_BODY(check_sdp_get_attr, tc)
{
	uint8_t data[] = {
		0x09, 0x00, 0x00,	// uint16	0x0000
		0x35, 0x05,		// seq8(5)
		0x19, 0x00, 0x00,	//   uuid16	0x0000
		0x08, 0x00,		//   uint8	0x00
		0x08, 0x00,		// uint8	0x00
		0x09, 0x00, 0x01,	// uint16	0x0001
		0x19, 0x12, 0x34,	// uuid16	0x1234
	};
	sdp_data_t test = { data, data + sizeof(data) };
	sdp_data_t value;
	uint16_t attr;

	/*
	 * sdp_get_attr expects a UINT16 followed by any data item
	 * and advances test if successful
	 */
	ATF_REQUIRE(sdp_get_attr(&test, &attr, &value));
	ATF_CHECK_EQ(attr, 0x0000);
	ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_SEQ8);
	ATF_CHECK_EQ(sdp_data_size(&value), 7);

	ATF_REQUIRE_EQ(sdp_get_attr(&test, &attr, &value), false);
	ATF_REQUIRE(sdp_get_data(&test, &value));
	ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UINT8);
	ATF_CHECK_EQ(sdp_data_size(&value), 2);

	ATF_REQUIRE(sdp_get_attr(&test, &attr, &value));
	ATF_CHECK_EQ(attr, 0x0001);
	ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UUID16);
	ATF_CHECK_EQ(sdp_data_size(&value), 3);

	ATF_CHECK_EQ(test.next, test.end);
}
Пример #5
0
/*
 * Configure HF results
 */
static int
config_hf(prop_dictionary_t dict, sdp_data_t *rec)
{
	prop_object_t obj;
	sdp_data_t value;
	int32_t channel;
	uint16_t attr;

	channel = -1;

	while (sdp_get_attr(rec, &attr, &value)) {
		switch (attr) {
		case SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST:
			channel = parse_pdl(&value, SDP_UUID_PROTOCOL_RFCOMM);
			break;

		default:
			break;
		}
	}

	if (channel == -1)
		return ENOATTR;

	obj = prop_string_create_cstring_nocopy("btsco");
	if (obj == NULL || !prop_dictionary_set(dict, BTDEVtype, obj))
		return errno;

	prop_object_release(obj);

	obj = prop_bool_create(true);
	if (obj == NULL || !prop_dictionary_set(dict, BTSCOlisten, obj))
		return errno;

	prop_object_release(obj);

	obj = prop_number_create_integer(channel);
	if (obj == NULL || !prop_dictionary_set(dict, BTSCOchannel, obj))
		return errno;

	prop_object_release(obj);

	return 0;
}
Пример #6
0
/*
 * Configure HID results
 */
static int
config_hid(prop_dictionary_t dict, sdp_data_t *rec)
{
	prop_object_t obj;
	int32_t control_psm, interrupt_psm,
		reconnect_initiate, hid_length;
	uint8_t *hid_descriptor;
	sdp_data_t value;
	const char *mode;
	uint16_t attr;

	control_psm = -1;
	interrupt_psm = -1;
	reconnect_initiate = -1;
	hid_descriptor = NULL;
	hid_length = -1;

	while (sdp_get_attr(rec, &attr, &value)) {
		switch (attr) {
		case SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST:
			control_psm = parse_pdl(&value, SDP_UUID_PROTOCOL_L2CAP);
			break;

		case SDP_ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS:
			interrupt_psm = parse_apdl(&value, SDP_UUID_PROTOCOL_L2CAP);
			break;

		case 0x0205: /* HIDReconnectInitiate */
			reconnect_initiate = parse_boolean(&value);
			break;

		case 0x0206: /* HIDDescriptorList */
			if (parse_hid_descriptor(&value)) {
				hid_descriptor = value.next;
				hid_length = value.end - value.next;
			}
			break;

		default:
			break;
		}
	}

	if (control_psm == -1
	    || interrupt_psm == -1
	    || reconnect_initiate == -1
	    || hid_descriptor == NULL
	    || hid_length == -1)
		return ENOATTR;

	obj = prop_string_create_cstring_nocopy("bthidev");
	if (obj == NULL || !prop_dictionary_set(dict, BTDEVtype, obj))
		return errno;

	prop_object_release(obj);

	obj = prop_number_create_integer(control_psm);
	if (obj == NULL || !prop_dictionary_set(dict, BTHIDEVcontrolpsm, obj))
		return errno;

	prop_object_release(obj);

	obj = prop_number_create_integer(interrupt_psm);
	if (obj == NULL || !prop_dictionary_set(dict, BTHIDEVinterruptpsm, obj))
		return errno;

	prop_object_release(obj);

	obj = prop_data_create_data(hid_descriptor, hid_length);
	if (obj == NULL || !prop_dictionary_set(dict, BTHIDEVdescriptor, obj))
		return errno;

	mode = hid_mode(obj);
	prop_object_release(obj);

	obj = prop_string_create_cstring_nocopy(mode);
	if (obj == NULL || !prop_dictionary_set(dict, BTDEVmode, obj))
		return errno;

	prop_object_release(obj);

	if (!reconnect_initiate) {
		obj = prop_bool_create(true);
		if (obj == NULL || !prop_dictionary_set(dict, BTHIDEVreconnect, obj))
			return errno;

		prop_object_release(obj);
	}

	return 0;
}