Ejemplo n.º 1
0
/* Starts the process whose arguments are given in the null-terminated array
 * 'argv' and waits for it to exit.  On success returns 0 and stores the
 * process exit value (suitable for passing to process_status_msg()) in
 * '*status'.  On failure, returns a positive errno value and stores 0 in
 * '*status'.
 *
 * If 'stdout_log' is nonnull, then the subprocess's output to stdout (up to a
 * limit of PROCESS_MAX_CAPTURE bytes) is captured in a memory buffer, which
 * when this function returns 0 is stored as a null-terminated string in
 * '*stdout_log'.  The caller is responsible for freeing '*stdout_log' (by
 * passing it to free()).  When this function returns an error, '*stdout_log'
 * is set to NULL.
 *
 * If 'stderr_log' is nonnull, then it is treated like 'stdout_log' except
 * that it captures the subprocess's output to stderr. */
int
process_run_capture(char **argv, char **stdout_log, char **stderr_log,
                    int *status)
{
    struct stream s_stdout, s_stderr;
    sigset_t oldsigs;
    pid_t pid;
    int error;

    COVERAGE_INC(process_run_capture);
    if (stdout_log) {
        *stdout_log = NULL;
    }
    if (stderr_log) {
        *stderr_log = NULL;
    }
    *status = 0;
    error = process_prestart(argv);
    if (error) {
        return error;
    }

    error = stream_open(&s_stdout);
    if (error) {
        return error;
    }

    error = stream_open(&s_stderr);
    if (error) {
        stream_close(&s_stdout);
        return error;
    }

    block_sigchld(&oldsigs);
    pid = fork();
    if (pid < 0) {
        int error = errno;

        unblock_sigchld(&oldsigs);
        VLOG_WARN("fork failed: %s", strerror(error));

        stream_close(&s_stdout);
        stream_close(&s_stderr);
        *status = 0;
        return error;
    } else if (pid) {
        /* Running in parent process. */
        struct process *p;

        p = process_register(argv[0], pid);
        unblock_sigchld(&oldsigs);

        close(s_stdout.fds[1]);
        close(s_stderr.fds[1]);
        while (!process_exited(p)) {
            stream_read(&s_stdout);
            stream_read(&s_stderr);

            stream_wait(&s_stdout);
            stream_wait(&s_stderr);
            process_wait(p);
            poll_block();
        }
        stream_read(&s_stdout);
        stream_read(&s_stderr);

        if (stdout_log) {
            *stdout_log = ds_steal_cstr(&s_stdout.log);
        }
        if (stderr_log) {
            *stderr_log = ds_steal_cstr(&s_stderr.log);
        }

        stream_close(&s_stdout);
        stream_close(&s_stderr);

        *status = process_status(p);
        process_destroy(p);
        return 0;
    } else {
        /* Running in child process. */
        int max_fds;
        int i;

        fatal_signal_fork();
        unblock_sigchld(&oldsigs);

        dup2(get_null_fd(), 0);
        dup2(s_stdout.fds[1], 1);
        dup2(s_stderr.fds[1], 2);

        max_fds = get_max_fds();
        for (i = 3; i < max_fds; i++) {
            close(i);
        }

        execvp(argv[0], argv);
        fprintf(stderr, "execvp(\"%s\") failed: %s\n",
                argv[0], strerror(errno));
        exit(EXIT_FAILURE);
    }
}
Ejemplo n.º 2
0
static demuxer_t* demux_open_y4m(demuxer_t* demuxer){
    y4m_priv_t* priv = demuxer->priv;
    y4m_ratio_t ratio;
    sh_video_t* sh=new_sh_video(demuxer,0);
    int err;

    priv->framenum = 0;
    priv->si = malloc(sizeof(y4m_stream_info_t));

    if (priv->is_older)
    {
	char buf[4];
	int frame_rate_code;

	stream_skip(demuxer->stream, 8); /* YUV4MPEG */
	stream_skip(demuxer->stream, 1); /* space */
	stream_read(demuxer->stream, (char *)&buf[0], 3);
	buf[3] = 0;
	sh->disp_w = atoi(buf);
	stream_skip(demuxer->stream, 1); /* space */
	stream_read(demuxer->stream, (char *)&buf[0], 3);
	buf[3] = 0;
	sh->disp_h = atoi(buf);
	stream_skip(demuxer->stream, 1); /* space */
	stream_read(demuxer->stream, (char *)&buf[0], 1);
	buf[1] = 0;
	frame_rate_code = atoi(buf);
	stream_skip(demuxer->stream, 1); /* new-line */
	
	if (!sh->fps)
	{
	    /* values from xawtv */
	    switch(frame_rate_code)
	    {
		case 1:
		    sh->fps = 23.976f;
		    break;
		case 2:
		    sh->fps = 24.0f;
		    break;
		case 3:
		    sh->fps = 25.0f;
		    break;
		case 4:
		    sh->fps = 29.97f;
		    break;
		case 5:
		    sh->fps = 30.0f;
		    break;
		case 6:
		    sh->fps = 50.0f;
		    break;
		case 7:
		    sh->fps = 59.94f;
		    break;
		case 8:
		    sh->fps = 60.0f;
		    break;
		default:
		    sh->fps = 25.0f;
	    }
	}
	sh->frametime = 1.0f/sh->fps;
    }
    else
    {
	y4m_init_stream_info(priv->si);
	if ((err=y4m_read_stream_header(demuxer->stream, priv->si)) != Y4M_OK) 
	    mp_msg(MSGT_DEMUXER, MSGL_FATAL, "error parsing YUV4MPEG header: %s\n", y4m_strerr(err));
	
	if(!sh->fps) {
    	    ratio = y4m_si_get_framerate(priv->si);
    	    if (ratio.d != 0)
        	sh->fps=(float)ratio.n/(float)ratio.d;
    	    else
        	sh->fps=15.0f;
	}
	sh->frametime=1.0f/sh->fps;
	
	ratio = y4m_si_get_sampleaspect(priv->si);

	sh->disp_w = y4m_si_get_width(priv->si);
	sh->disp_h = y4m_si_get_height(priv->si);

	if (ratio.d != 0 && ratio.n != 0)
	    sh->aspect = (float)(sh->disp_w*ratio.n)/(float)(sh->disp_h*ratio.d);

    	demuxer->seekable = 0;
    }

    sh->format = mmioFOURCC('Y', 'V', '1', '2');

    sh->bih=malloc(sizeof(BITMAPINFOHEADER));
    memset(sh->bih,0,sizeof(BITMAPINFOHEADER));
    sh->bih->biSize=40;
    sh->bih->biWidth = sh->disp_w;
    sh->bih->biHeight = sh->disp_h;
    sh->bih->biPlanes=3;
    sh->bih->biBitCount=12;
    sh->bih->biCompression=sh->format;
    sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight*3/2; /* YV12 */

    demuxer->video->sh=sh;
    sh->ds=demuxer->video;
    demuxer->video->id=0;
		

    mp_msg(MSGT_DEMUX, MSGL_INFO, "YUV4MPEG2 Video stream %d size: display: %dx%d, codec: %ux%u\n",
            demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth,
            sh->bih->biHeight);

    return demuxer;
}
Ejemplo n.º 3
0
tbool rpch_in_connect_http(rdpRpch* rpch)
{
	rdpTls* tls_in = rpch->tls_in;
	rdpSettings* settings = rpch->settings;
	rdpRpchHTTP* http_in = rpch->http_in;
	NTLMSSP* http_in_ntlmssp = http_in->ntht;

	STREAM* ntlmssp_stream;
	STREAM* http_stream;

	int decoded_ntht_length;
	int encoded_ntht_length = 0;
	int bytes;

	uint8* decoded_ntht_data;
	uint8* encoded_ntht_data = NULL;

	char* ntlm_text;

	LLOGLN(10, ("rpch_in_connect_http:"));

	ntlmssp_stream = stream_new(0xFFFF);
	http_stream = stream_new(0xFFFF);

	ntlmssp_set_username(http_in_ntlmssp, settings->tsg_username);
	ntlmssp_set_password(http_in_ntlmssp, settings->tsg_password);
	ntlmssp_set_domain(http_in_ntlmssp, settings->tsg_domain);
	ntlmssp_set_workstation(http_in_ntlmssp, "WORKSTATION"); /* TODO insert proper w.name */

	LLOGLN(10, ("rpch_in_connect_http: tsg_username %s tsg_password %s tsg_domain %s",
			settings->tsg_username, settings->tsg_password, settings->tsg_domain));

	ntlmssp_send(http_in_ntlmssp, ntlmssp_stream);

	decoded_ntht_length = (int) (ntlmssp_stream->p - ntlmssp_stream->data);
	decoded_ntht_data = (uint8*) xmalloc(decoded_ntht_length);

	ntlmssp_stream->p = ntlmssp_stream->data;
	stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length);

	stream_clear(ntlmssp_stream);
	ntlmssp_stream->p = ntlmssp_stream->data;

	crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length);

	stream_write(http_stream, "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 54);
	stream_write(http_stream, "Accept: application/rpc\n", 24);
	stream_write(http_stream, "Cache-Control: no-cache\n", 24);
	stream_write(http_stream, "Connection: Keep-Alive\n", 23);
	stream_write(http_stream, "Content-Length: 0\n", 18);
	stream_write(http_stream, "User-Agent: MSRPC\n", 18);
	stream_write(http_stream, "Host: ", 6);
	stream_write(http_stream, settings->tsg_server, strlen(settings->tsg_server));
	stream_write(http_stream, "\n", 1);
	stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110);
	stream_write(http_stream, "Authorization: NTLM ", 20);
	stream_write(http_stream, encoded_ntht_data, encoded_ntht_length);
	stream_write(http_stream, "\n\n", 2);

	LLOGLN(10, ("rpch_in_connect_http: sending\n%s", http_stream->data));

	DEBUG_RPCH("\nSend:\n%s\n", http_stream->data);

	bytes = (int) (http_stream->p - http_stream->data);
	tls_write(tls_in, http_stream->data, bytes);
	stream_clear(http_stream);
	http_stream->p = http_stream->data;

	xfree(decoded_ntht_data);

	encoded_ntht_length = -1;
	xfree(encoded_ntht_data);
	encoded_ntht_data = NULL;
	http_in->contentLength = 0;

	LLOGLN(10, ("rpch_in_connect_http: 1"));

	stream_free(http_stream);
	http_stream = read_http(tls_in, NULL, true);

	if (http_stream == NULL)
	{
		LLOGLN(0, ("rpch_in_connect_http: error http_stream is nil"));
		return false;
	}

	ntlm_text = strstr((char*)(http_stream->data), "NTLM ");
	if (ntlm_text != NULL)
	{
		encoded_ntht_data = (uint8*)(ntlm_text + 5);
		encoded_ntht_length = 0;
		while (encoded_ntht_data[encoded_ntht_length] != '\r' &&
				encoded_ntht_data[encoded_ntht_length] != '\n')
		{
			encoded_ntht_length++;
		}
	}

	LLOGLN(0, ("rpch_in_connect_http: encoded_ntht_length %d encoded_ntht_data %s",
			encoded_ntht_length, encoded_ntht_data));


	if (encoded_ntht_length  < 1) /* No NTLM data was found */
	{
		LLOGLN(0, ("rpch_in_connect_http: error encoded_ntht_length < 1"));
		return false;
	}

	http_stream->p = http_stream->data;

	crypto_base64_decode(encoded_ntht_data, encoded_ntht_length,
			&decoded_ntht_data, &decoded_ntht_length);

	stream_write(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length);
	ntlmssp_stream->p = ntlmssp_stream->data;

	xfree(decoded_ntht_data);

	ntlmssp_recv(http_in_ntlmssp, ntlmssp_stream);
	stream_clear(ntlmssp_stream);
	ntlmssp_stream->p = ntlmssp_stream->data;

	ntlmssp_send(http_in_ntlmssp, ntlmssp_stream);

	decoded_ntht_length = (int) (ntlmssp_stream->p - ntlmssp_stream->data);
	decoded_ntht_data = (uint8*) xmalloc(decoded_ntht_length);
	ntlmssp_stream->p = ntlmssp_stream->data;
	stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length);

	stream_clear(ntlmssp_stream);
	ntlmssp_stream->p = ntlmssp_stream->data;

	crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length);

	stream_write(http_stream, "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 54);
	stream_write(http_stream, "Accept: application/rpc\n", 24);
	stream_write(http_stream, "Cache-Control: no-cache\n", 24);
	stream_write(http_stream, "Connection: Keep-Alive\n", 23);
	stream_write(http_stream, "Content-Length: 1073741824\n", 27);
	stream_write(http_stream, "User-Agent: MSRPC\n", 18);
	stream_write(http_stream, "Host: ", 6);
	stream_write(http_stream, settings->tsg_server, strlen(settings->tsg_server));
	stream_write(http_stream, "\n", 1);
	stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110);
	stream_write(http_stream, "Authorization: NTLM ", 20);
	stream_write(http_stream, encoded_ntht_data, encoded_ntht_length);
	stream_write(http_stream, "\n\n", 2);

	http_in->contentLength = 1073741824;
	http_in->remContentLength = 1073741824;

	DEBUG_RPCH("\nSend:\n%s\n", http_stream->data);

	tls_write(tls_in, http_stream->data, http_stream->p - http_stream->data);

	stream_clear(http_stream);
	http_stream->p = http_stream->data;

	xfree(decoded_ntht_data);
	xfree(encoded_ntht_data);
	/* At this point IN connection is ready to send CONN/B1 and start with sending data */

	http_in->state = RPCH_HTTP_SENDING;

	LLOGLN(10, ("rpch_in_connect_http: out"));

	return true;
}
static int vivo_check_file(demuxer_t* demuxer){
    int i=0;
    int len;
    int c;
    unsigned char buf[2048+256];
    vivo_priv_t* priv;
    int orig_pos = stream_tell(demuxer->stream);

    mp_msg(MSGT_DEMUX,MSGL_V,"Checking for VIVO\n");

    c=stream_read_char(demuxer->stream);
    if(c==-256) return 0;
    len=0;
    while((c=stream_read_char(demuxer->stream))>=0x80){
	len+=0x80*(c-0x80);
	if(len>1024) return 0;
    }
    len+=c;
    mp_msg(MSGT_DEMUX,MSGL_V,"header block 1 size: %d\n",len);
    //stream_skip(demuxer->stream,len);

    priv=malloc(sizeof(vivo_priv_t));
    memset(priv,0,sizeof(vivo_priv_t));
    demuxer->priv=priv;

#if 0
    vivo_parse_text_header(demuxer, len);
    if (priv->supported == 0)
	return 0;
#else
    /* this is enought for check (for now) */
    stream_read(demuxer->stream,buf,len);
    buf[len]=0;
//    printf("VIVO header: '%s'\n",buf);

    // parse header:
    i=0;
    while(i<len && buf[i]==0x0D && buf[i+1]==0x0A) i+=2; // skip empty lines
    if(strncmp(buf+i,"Version:Vivo/",13)) return 0; // bad version/type!
#endif

#if 0
    c=stream_read_char(demuxer->stream);
    if(c) return 0;
    len2=0;
    while((c=stream_read_char(demuxer->stream))>=0x80){
	len2+=0x80*(c-0x80);
	if(len+len2>2048) return 0;
    }
    len2+=c;
    mp_msg(MSGT_DEMUX,MSGL_V,"header block 2 size: %d\n",len2);
    stream_skip(demuxer->stream,len2);
//    stream_read(demuxer->stream,buf+len,len2);
#endif

//    c=stream_read_char(demuxer->stream);
//    printf("first packet: %02X\n",c);

    stream_seek(demuxer->stream, orig_pos);

return DEMUXER_TYPE_VIVO;
}
static void vivo_parse_text_header(demuxer_t *demux, int header_len)
{
    vivo_priv_t* priv = demux->priv;
    char *buf;
    int i;
    char *token;
    char *opt, *param;
    int parser_in_audio_block = 0;

    if (!demux->priv)
    {
	priv = malloc(sizeof(vivo_priv_t));
	memset(priv, 0, sizeof(vivo_priv_t));
	demux->priv = priv;
	priv->supported = 0;
    }

    buf = malloc(header_len);
    opt = malloc(header_len);
    param = malloc(header_len);
    stream_read(demux->stream, buf, header_len);
    i=0;
    while(i<header_len && buf[i]==0x0D && buf[i+1]==0x0A) i+=2; // skip empty lines

    token = strtok(buf, (char *)&("\x0d\x0a"));
    while (token && (header_len>2))
    {
	header_len -= strlen(token)+2;
	if (sscanf(token, "%[^:]:%[^\n]", opt, param) != 2)
	{
	    mp_msg(MSGT_DEMUX, MSGL_V, "viv_text_header_parser: bad line: '%s' at ~%#"PRIx64"\n",
		token, (int64_t)stream_tell(demux->stream));
	    break;
	}
	mp_dbg(MSGT_DEMUX, MSGL_DBG3, "token: '%s' (%zu bytes/%d bytes left)\n",
	    token, strlen(token), header_len);
	mp_dbg(MSGT_DEMUX, MSGL_DBG3, "token => o: '%s', p: '%s'\n",
	    opt, param);

	/* checking versions: only v1 or v2 is suitable (or known?:) */
	if (!strcmp(opt, "Version"))
	{
	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "Version: %s\n", param);
	    if (!strncmp(param, "Vivo/1", 6) || !strncmp(param, "Vivo/2", 6))
	    {
		priv->supported = 1;
		/* save major version for fourcc */
		priv->version = param[5];
	    }
	}

	/* video specific */
	if (!strcmp(opt, "FPS"))
	{
	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "FPS: %f\n", atof(param));
	    priv->fps = atof(param);
	}
	if (!strcmp(opt, "Width"))
	{
	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "Width: %d\n", atoi(param));
	    priv->width = atoi(param);
	}
	if (!strcmp(opt, "Height"))
	{
	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "Height: %d\n", atoi(param));
	    priv->height = atoi(param);
	}
	if (!strcmp(opt, "DisplayWidth"))
	{
	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "Display Width: %d\n", atoi(param));
	    priv->disp_width = atoi(param);
	}
	if (!strcmp(opt, "DisplayHeight"))
	{
	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "Display Height: %d\n", atoi(param));
	    priv->disp_height = atoi(param);
	}

	/* audio specific */
	if (!strcmp(opt, "RecordType"))
	{
	    /* no audio recordblock by Vivo/1.00, 3 and 4 by Vivo/2.00 */
	    if ((atoi(param) == 3) || (atoi(param) == 4))
		parser_in_audio_block = 1;
	    else
		parser_in_audio_block = 0;
	}
	if (!strcmp(opt, "NominalBitrate"))
	{
	    priv->audio_bitrate = atoi(param);
	    if (priv->audio_bitrate == 2000)
		priv->audio_codec = VIVO_AUDIO_SIREN;
	    if (priv->audio_bitrate == 800)
		priv->audio_codec = VIVO_AUDIO_G723;
	}
	if (!strcmp(opt, "SamplingFrequency"))
	{
	    priv->audio_samplerate = atoi(param);
	    if (priv->audio_samplerate == 16000)
		priv->audio_codec = VIVO_AUDIO_SIREN;
	    if (priv->audio_samplerate == 8000)
		priv->audio_codec = VIVO_AUDIO_G723;
	}
	if (!strcmp(opt, "Length") && (parser_in_audio_block == 1))
	{
	    priv->audio_bytesperblock = atoi(param); /* 24 or 40 kbps */
	    if (priv->audio_bytesperblock == 40)
		priv->audio_codec = VIVO_AUDIO_SIREN;
	    if (priv->audio_bytesperblock == 24)
		priv->audio_codec = VIVO_AUDIO_G723;
	}

	/* only for displaying some informations about movie*/
	if (!strcmp(opt, "Title"))
	{
	    demux_info_add(demux, "title", param);
	    priv->title = strdup(param);
	}
	if (!strcmp(opt, "Author"))
	{
	    demux_info_add(demux, "author", param);
	    priv->author = strdup(param);
	}
	if (!strcmp(opt, "Copyright"))
	{
	    demux_info_add(demux, "copyright", param);
	    priv->copyright = strdup(param);
	}
	if (!strcmp(opt, "Producer"))
	{
	    demux_info_add(demux, "encoder", param);
	    priv->producer = strdup(param);
	}

	/* get next token */
	token = strtok(NULL, (char *)&("\x0d\x0a"));
    }

    free(buf);
    free(opt);
    free(param);
}
Ejemplo n.º 6
0
static int d64_image_writefile(imgtool_image *img, const char *fname, imgtool_stream *sourcef, const ResolvedOption *options_)
{
	d64_image *image=(d64_image*)img;
	int fsize, pos, i, b, freespace;
	int track, sector;
	D64_ENTRY *entry;

	fsize=stream_size(sourcef)+1;

	img_freespace(img, &freespace);

	if ((entry=d64_image_findfile(image, (const unsigned char *)fname))!=NULL ) {
		/* overriding */
		if ((freespace + GET_UWORD(entry->blocks))*254<fsize) 
			return IMGTOOLERR_NOSPACE;
		track=entry->track;
		sector=entry->sector;
		
		while (track!=0) {
			image->free_sector(image, track, sector);
			pos = image->get_offset(track, sector);
			track=image->data[pos];
			sector=image->data[pos+1];
		}
	} else {
		if (freespace*254<fsize) return IMGTOOLERR_NOSPACE;
		/* search free entry */
		entry=d64_get_free_entry(image);
	}

	entry->type=FILE_TYPE_PRG|0x80;
	memset(entry->name, 0xa0, sizeof(entry->name));
	memcpy(entry->name, fname, strlen(fname));

	image->alloc_sector(image, &track, &sector);
	entry->track=track; 
	entry->sector=sector;
	pos = image->get_offset(track, sector);

	for (i = 0, b=0; i + 254 < fsize; i += 254, b++)
	{
		if (stream_read(sourcef, image->data+pos+2, 254)!=254)
			return IMGTOOLERR_READERROR;
		
		image->alloc_sector(image, &track, &sector);
		image->data[pos]=track; 
		image->data[pos+1]=sector;
		pos = image->get_offset (track, sector);
	}
	b++;
	image->data[pos]=0;
	image->data[pos+1]=fsize-i;
	if (fsize-i-1>0) {
		if (stream_read(sourcef, image->data+pos+2, fsize-i-1)!=fsize-i-1)
			return IMGTOOLERR_READERROR;
	}
	image->data[pos+2+fsize-i]=0;
	
	SET_UWORD(entry->blocks, b);
	image->modified=1;

	return 0;
}
Ejemplo n.º 7
0
// 0 = EOF or no stream found
// 1 = successfully read a packet
static int demux_pva_fill_buffer (demuxer_t * demux, demux_stream_t *ds)
{
	uint8_t done=0;
	demux_packet_t * dp;
	pva_priv_t * priv=demux->priv;
	pva_payload_t current_payload;

	while(!done)
	{
		if(!pva_get_payload(demux,&current_payload)) return 0;
		switch(current_payload.type)
		{
			case VIDEOSTREAM:
				if(demux->video->id==-1) demux->video->id=0;
				if(!current_payload.is_packet_start && priv->last_video_pts==-1)
				{
					/* We should only be here at the beginning of a stream, when we have
					 * not yet encountered a valid Video PTS, or after a seek.
					 * So, skip these starting packets in order not to deliver the
					 * player a bogus PTS.
					 */
					done=0;
				}
				else
				{
					/*
					 * In every other condition, we are delivering the payload. Set this
					 * so that the following code knows whether to skip it or read it.
					 */
					done=1;
				}
				if(demux->video->id!=0) done=0;
				if(current_payload.is_packet_start)
				{
					priv->last_video_pts=current_payload.pts;
					//mp_msg(MSGT_DEMUXER,MSGL_DBG2,"demux_pva: Video PTS=%llu , delivered %f\n",current_payload.pts,priv->last_video_pts);
				}
				if(done)
				{
					dp=new_demux_packet(current_payload.size);
					dp->pts=priv->last_video_pts;
					stream_read(demux->stream,dp->buffer,current_payload.size);
					ds_add_packet(demux->video,dp);
				}
				else
				{
					//printf("Skipping %u video bytes\n",current_payload.size);
					stream_skip(demux->stream,current_payload.size);
				}
				break;
			case MAINAUDIOSTREAM:
				if(demux->audio->id==-1) demux->audio->id=0;
				if(!current_payload.is_packet_start && priv->last_audio_pts==-1)
				{
					/* Same as above for invalid video PTS, just for audio. */
					done=0;
				}
				else
				{
					done=1;
				}
				if(current_payload.is_packet_start)
				{
					priv->last_audio_pts=current_payload.pts;
				}
				if(demux->audio->id!=0) done=0;
				if(done)
				{
					dp=new_demux_packet(current_payload.size);
					dp->pts=priv->last_audio_pts;
					if(current_payload.offset != stream_tell(demux->stream))
						stream_seek(demux->stream,current_payload.offset);
					stream_read(demux->stream,dp->buffer,current_payload.size);
					ds_add_packet(demux->audio,dp);
				}
				else
				{
					stream_skip(demux->stream,current_payload.size);
				}
				break;
		}
	}
	return 1;
}
Ejemplo n.º 8
0
/*
	imgtool_chd_read - interface for reading from a hard disk image
*/
static UINT32 imgtool_chd_read(chd_interface_file *file, UINT64 offset, UINT32 count, void *buffer)
{
	stream_seek((imgtool_stream *)file, offset, SEEK_SET);
	return stream_read((imgtool_stream *)file, buffer, count);
}
Ejemplo n.º 9
0
static demuxer_t* demux_open_fli(demuxer_t* demuxer){
  sh_video_t *sh_video = NULL;
  fli_frames_t *frames = malloc(sizeof(fli_frames_t));
  int frame_number;
  int speed;
  unsigned int frame_size;
  int magic_number;
  unsigned char * header;

  // go back to the beginning
  stream_reset(demuxer->stream);
  stream_seek(demuxer->stream, 0);

  header = calloc(1, sizeof(BITMAPINFOHEADER) + 128);
  stream_read(demuxer->stream, header + sizeof(BITMAPINFOHEADER), 128);
  stream_seek(demuxer->stream, 0);

  demuxer->movi_start = 128;
  demuxer->movi_end = stream_read_dword_le(demuxer->stream);

  magic_number = stream_read_word_le(demuxer->stream);

  if ((magic_number != 0xAF11) && (magic_number != 0xAF12))
  {
    mp_msg(MSGT_DEMUX, MSGL_ERR, "Bad/unknown magic number (%04x)\n",
	magic_number);
    free(header);
    free(frames);
    return NULL;
  }

  // fetch the number of frames
  frames->num_frames = stream_read_word_le(demuxer->stream);
  frames->current_frame = 0;

  // allocate enough entries for the indices
  //   audit: num_frames is 16bit so it is safe against overflow
  frames->filepos = malloc(frames->num_frames * sizeof(off_t));
  frames->frame_size = malloc(frames->num_frames * sizeof(int));

  // create a new video stream header
  sh_video = new_sh_video(demuxer, 0);

  // make sure the demuxer knows about the new video stream header
  // (even though new_sh_video() ought to take care of it)
  demuxer->video->sh = sh_video;

  // make sure that the video demuxer stream header knows about its
  // parent video demuxer stream (this is getting wacky), or else
  // video_read_properties() will choke
  sh_video->ds = demuxer->video;

  // custom fourcc for internal MPlayer use
  sh_video->format = mmioFOURCC('F', 'L', 'I', 'C');

  sh_video->disp_w = stream_read_word_le(demuxer->stream);
  sh_video->disp_h = stream_read_word_le(demuxer->stream);

  // pass extradata to codec
  sh_video->bih = (BITMAPINFOHEADER*)header;
  sh_video->bih->biSize = sizeof(BITMAPINFOHEADER) + 128;
  sh_video->bih->biWidth = sh_video->disp_w;
  sh_video->bih->biHeight = sh_video->disp_h;

  // skip the video depth and flags
  stream_skip(demuxer->stream, 4);

  // get the speed
  speed = stream_read_word_le(demuxer->stream);
  if (speed == 0)
    speed = 1;
  if (magic_number == 0xAF11)
    speed *= 1000/70;
  sh_video->fps = 1000 / speed;
  sh_video->frametime = 1/sh_video->fps;

  // build the frame index
  stream_seek(demuxer->stream, demuxer->movi_start);
  frame_number = 0;
  while ((!stream_eof(demuxer->stream)) && (frame_number < frames->num_frames))
  {
    frames->filepos[frame_number] = stream_tell(demuxer->stream);
    frame_size = stream_read_dword_le(demuxer->stream);
    magic_number = stream_read_word_le(demuxer->stream);
    stream_skip(demuxer->stream, frame_size - 6);

    // if this chunk has the right magic number, index it
    if ((magic_number == 0xF1FA) || (magic_number == 0xF5FA))
    {
      frames->frame_size[frame_number] = frame_size;
      frame_number++;
    }
  }

  // save the actual number of frames indexed
  frames->num_frames = frame_number;

  demuxer->priv = frames;

  return demuxer;
}
Ejemplo n.º 10
0
static int msx_dsk_image_init(const imgtool_module *mod, imgtool_stream *f, imgtool_image **outimg)
	{
	DSK_IMAGE *image;
	int size, disks, correct, format;
	UINT8 header;

	size = stream_size (f);
	if (size < (360*1024) )
		return IMGTOOLERR_MODULENOTFOUND;

	disks = 1;

	correct = 0;

	if (!strcmp(mod->name, "msx_img"))
	{
		format = FORMAT_IMG;
		if (1 != stream_read (f, &header, 1) )
			return IMGTOOLERR_READERROR;

		if ( (size == (720*1024+1) ) && (header == 2) )
			{
			correct = 1;
			size--;
			}
		if ( (size == (360*1024+1) ) && (header == 1) )
			{
			correct = 1;
			size--;
			}
	}
	else if (!strcmp(mod->name, "msx_msx"))
	{
		format = FORMAT_MSX;
		if (size == (720*1024) )
			correct = 1;
	}
	else if (!strcmp(mod->name, "msx_ddi"))
	{
		format = FORMAT_DDI;
		if (size == (720*1024+0x1200) )
			{
			size -= 0x1200;
			correct = 1;
			}
	}
	else if (!strcmp(mod->name, "msx_mul"))
	{
		format = FORMAT_MULTI;
		if ( (size > 720*1024) && !(size % (720*1024) ) )
			{
			disks = size / (720*1024);
			correct = 1;
			size = 720*1024;
			}
	}
	else
	{
		assert(0);
		return IMGTOOLERR_UNEXPECTED;
	}

	if (!correct) return IMGTOOLERR_MODULENOTFOUND;

	image = (DSK_IMAGE*)malloc (sizeof (DSK_IMAGE) );
	if (!image) return IMGTOOLERR_OUTOFMEMORY;

	*outimg = (imgtool_image*)image;

	memset(image, 0, sizeof(DSK_IMAGE));
	image->base.module = mod;
	image->file_handle = f;
	image->size = size;
	image->format = format;
	image->file_name = NULL;
	image->disks = disks;

	return 0;
	}
Ejemplo n.º 11
0
static int msx_dsk_image_readfile(imgtool_image *img, const char *fname, imgtool_stream *destf)
	{
	DSK_IMAGE *image=(DSK_IMAGE*)img;
	UINT8	buf[0x1200];
	int 	i, offset, n1, n2, disks = 0;

	/*  check file name */
	switch (image->format)
		{
		case FORMAT_IMG:
		case FORMAT_DDI:
		case FORMAT_MSX:
			if (strcmpi (fname, "msx.dsk") )
				return IMGTOOLERR_MODULENOTFOUND;
			break;
		case FORMAT_MULTI:
			if (strncmpi (fname, "msx-", 4) )
				return IMGTOOLERR_MODULENOTFOUND;
			offset = 4; disks = 0;
			while ( (fname[offset] >= '0') || (fname[offset] <= '9') )
				disks = disks * 10 + (fname[offset++] - '0');

			if (mame_stricmp (fname + offset, ".dsk") )
				return IMGTOOLERR_MODULENOTFOUND;

			if ( (disks < 1) || (disks > image->disks) )
				return IMGTOOLERR_MODULENOTFOUND;

			break;
		}

	/* copy the file */
	switch (image->format)
		{
		case FORMAT_MSX:
			i = 80; n1 = 0; n2 = 80;
			while (i--)
				{
				stream_seek (image->file_handle, n1++ * 0x1200, SEEK_SET);
				if (0x1200 != stream_read (image->file_handle, buf, 0x1200) )
					return IMGTOOLERR_READERROR;

				if (0x1200 != stream_write (destf, buf, 0x1200) )
					return IMGTOOLERR_WRITEERROR;

				stream_seek (image->file_handle, n2++ * 0x1200, SEEK_SET);
				if (0x1200 != stream_read (image->file_handle, buf, 0x1200) )
					return IMGTOOLERR_READERROR;

				if (0x1200 != stream_write (destf, buf, 0x1200) )
					return IMGTOOLERR_WRITEERROR;
				}

			return 0;
		case FORMAT_IMG:
			offset = 1; i = (image->size / 0x1200);
			break;
		case FORMAT_DDI:
			offset = 0x1200; i = 160;
			break;
		case FORMAT_MULTI:	/* multi disk */
			i = 160; offset = 720*1024 * (disks - 1);
			break;
		default:
			return IMGTOOLERR_UNEXPECTED;
		}

	stream_seek (image->file_handle, offset, SEEK_SET);

	while (i--)
		{
		if (0x1200 != stream_read (image->file_handle, buf, 0x1200) )
			return IMGTOOLERR_READERROR;

		if (0x1200 != stream_write (destf, buf, 0x1200) )
			return IMGTOOLERR_WRITEERROR;
		}

	return 0;
	}
static int demux_ty_fill_buffer( demuxer_t *demux, demux_stream_t *dsds )
{
   int              invalidType = 0;
   int              errorHeader = 0;
   int              recordsDecoded = 0;

   int              readSize;

   int              numberRecs;
   unsigned char    *recPtr;
   int              offset;

   int              counter;

   int              aid;

   TiVoInfo         *tivo = demux->priv;
   unsigned char    *chunk = tivo->chunk;

   if ( demux->stream->type == STREAMTYPE_DVD )
      return 0;

   mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty processing\n" );

   if( demux->stream->eof ) return 0;

   // ======================================================================
   // If we haven't figured out the size of the stream, let's do so
   // ======================================================================
   if ( demux->stream->type == STREAMTYPE_VSTREAM )
   {
      // The vstream code figures out the exact size of the stream
      demux->movi_start = 0;
      demux->movi_end = demux->stream->end_pos;
      tivo->size = demux->stream->end_pos;
   }
   else
   {
      // If its a local file, try to find the Part Headers, so we can
      // calculate the ACTUAL stream size
      // If we can't find it, go off with the file size and hope the
      // extract program did the "right thing"
      if ( tivo->readHeader == 0 )
      {
         loff_t filePos;
         tivo->readHeader = 1;

         filePos = demux->filepos;
         stream_seek( demux->stream, 0 );

         readSize = stream_read( demux->stream, chunk, CHUNKSIZE );

         if ( memcmp( chunk, TMF_SIG, sizeof( TMF_SIG ) ) == 0 )
         {
            mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Detected a tmf\n" );
            tivo->tmf = 1;
            ty_tmf_filetoparts( demux, tivo );
            readSize = tmf_load_chunk( demux, tivo, chunk, 0 );
         }

         if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID )
         {
               loff_t numberParts;

               readSize = 0;

               if ( tivo->tmf != 1 )
               {
                  loff_t offset;

                  numberParts = demux->stream->end_pos / TIVO_PART_LENGTH;
                  offset = numberParts * TIVO_PART_LENGTH;

                  mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty/ty+Number Parts %"PRId64"\n",
                    (int64_t)numberParts );

                  if ( offset + CHUNKSIZE < demux->stream->end_pos )
                  {
                     stream_seek( demux->stream, offset );
                     readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
                  }
               }
               else
               {
                  numberParts = tivo->tmf_totalparts;
                  offset = numberParts * TIVO_PART_LENGTH;
                  readSize = tmf_load_chunk( demux, tivo, chunk,
                     numberParts * ( TIVO_PART_LENGTH - CHUNKSIZE ) /
                     CHUNKSIZE );
               }

               if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID )
               {
                     int size = AV_RB24(chunk + 12);
                     size -= 4;
                     size *= CHUNKSIZE;
                     tivo->size = numberParts * TIVO_PART_LENGTH;
                     tivo->size += size;
                     mp_msg( MSGT_DEMUX, MSGL_DBG3,
                        "ty:Header Calc Stream Size %"PRId64"\n", tivo->size );
               }
         }

         if ( demux->stream->start_pos > 0 )
            filePos = demux->stream->start_pos;
         stream_seek( demux->stream, filePos );
         demux->filepos = stream_tell( demux->stream );
         tivo->whichChunk = filePos / CHUNKSIZE;
      }
      demux->movi_start = 0;
      demux->movi_end = tivo->size;
   }

   // ======================================================================
   // Give a clue as to where we are in the stream
   // ======================================================================
   mp_msg( MSGT_DEMUX, MSGL_DBG3,
      "ty:ty header size %"PRIx64"\n", (int64_t)tivo->size );
   mp_msg( MSGT_DEMUX, MSGL_DBG3,
      "ty:ty which Chunk %d\n", tivo->whichChunk );
   mp_msg( MSGT_DEMUX, MSGL_DBG3,
      "ty:file end_pos   %"PRIx64"\n", (int64_t)demux->stream->end_pos );
   mp_msg( MSGT_DEMUX, MSGL_DBG3,
      "\nty:wanted current offset %"PRIx64"\n", (int64_t)stream_tell( demux->stream ) );

   if ( tivo->size > 0 && stream_tell( demux->stream ) > tivo->size )
   {
         demux->stream->eof = 1;
         return 0;
   }

   do {
   if ( tivo->tmf != 1 )
   {
      // Make sure we are on a 128k boundary
      if ( demux->filepos % CHUNKSIZE != 0 )
      {
         int whichChunk = demux->filepos / CHUNKSIZE;
         if ( demux->filepos % CHUNKSIZE > CHUNKSIZE / 2 )
            whichChunk++;
         stream_seek( demux->stream, whichChunk * CHUNKSIZE );
      }

      demux->filepos = stream_tell( demux->stream );
      tivo->whichChunk = demux->filepos / CHUNKSIZE;
      readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
      if ( readSize != CHUNKSIZE )
         return 0;
   }
   else
   {
      readSize = tmf_load_chunk( demux, tivo, chunk, tivo->whichChunk );
      if ( readSize != CHUNKSIZE )
         return 0;
      tivo->whichChunk++;
   }
   if (AV_RB32(chunk) == TIVO_PES_FILEID)
      mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Skipping PART Header\n" );
   } while (AV_RB32(chunk) == TIVO_PES_FILEID);

   mp_msg( MSGT_DEMUX, MSGL_DBG3,
      "\nty:actual current offset %"PRIx64"\n", stream_tell( demux->stream ) -
      CHUNKSIZE );


   // Let's make a Video Demux Stream for MPlayer
   aid = 0x0;
   if( !demux->v_streams[ aid ] ) new_sh_video( demux, aid );
   if( demux->video->id == -1 ) demux->video->id = aid;
   if( demux->video->id == aid )
   {
      demux_stream_t *ds = demux->video;
      if( !ds->sh ) ds->sh = demux->v_streams[ aid ];
   }

   // ======================================================================
   // Finally, we get to actually parse the chunk
   // ======================================================================
   mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty parsing a chunk\n" );
   numberRecs = chunk[ 0 ];
   recPtr = &chunk[ 4 ];
   offset = numberRecs * 16 + 4;
   for ( counter = 0 ; counter < numberRecs ; counter++ )
   {
      int size = AV_RB24(recPtr) >> 4;
      int type = recPtr[ 3 ];
      int nybbleType = recPtr[ 2 ] & 0x0f;
      recordsDecoded++;

      mp_msg( MSGT_DEMUX, MSGL_DBG3,
         "ty:Record Type %x/%x %d\n", nybbleType, type, size );

      // ================================================================
      // Video Parsing
      // ================================================================
      if ( type == 0xe0 )
      {
         if ( size > 0 && size + offset <= CHUNKSIZE )
         {
            int esOffset1 = demux_ty_FindESHeader( VIDEO_NAL, &chunk[ offset ],
               size);
            if ( esOffset1 != -1 )
               tivo->lastVideoPTS = get_ty_pts(
                  &chunk[ offset + esOffset1 + 9 ] );

            // Do NOT Pass the PES Header onto the MPEG2 Decode
            if( nybbleType != 0x06 )
               demux_ty_CopyToDemuxPacket( demux->video,
                  &chunk[ offset ], size, demux->filepos + offset,
                  tivo->lastVideoPTS );
            offset += size;
         }
         else
            errorHeader++;
      }
      // ================================================================
      // Audio Parsing
      // ================================================================
      else if ( type == 0xc0 )
      {
         if ( size > 0 && size + offset <= CHUNKSIZE )
         {
            if( demux->audio->id == -1 )
            {
               if ( nybbleType == 0x02 )
                  continue;    // DTiVo inconclusive, wait for more
               else if ( nybbleType == 0x09 )
               {
                  mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Setting AC-3 Audio\n" );
                  aid = 0x80;  // AC-3
               }
               else
               {
                  mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Setting MPEG Audio\n" );
                  aid = 0x0;   // MPEG Audio
               }

               demux->audio->id = aid;
               if( !demux->a_streams[ aid ] ) new_sh_audio( demux, aid, NULL );
               if( demux->audio->id == aid )
               {
                  demux_stream_t *ds = demux->audio;
                  if( !ds->sh ) {
                    sh_audio_t* sh_a;
                    ds->sh = demux->a_streams[ aid ];
                    sh_a = (sh_audio_t*)ds->sh;
                    switch(aid & 0xE0){  // 1110 0000 b  (high 3 bit: type  low 5: id)
                      case 0x00: sh_a->format=0x50;break; // mpeg
                      case 0xA0: sh_a->format=0x10001;break;  // dvd pcm
                      case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts
                                  else sh_a->format=0x2000;break; // ac3
                    }
                 }
               }
            }

            aid = demux->audio->id;


            // SA DTiVo Audio Data, no PES
            // ================================================
            if ( nybbleType == 0x02 || nybbleType == 0x04 )
            {
               if ( nybbleType == 0x02 && tivo->tivoType == 2 )
                  demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size );
               else
               {

                  mp_msg( MSGT_DEMUX, MSGL_DBG3,
                     "ty:Adding Audio Packet Size %d\n", size );
                  demux_ty_CopyToDemuxPacket( demux->audio,
                     &chunk[ offset ], size, ( demux->filepos + offset ),
                     tivo->lastAudioPTS );
               }
            }

            // 3 - MPEG Audio with PES Header, either SA or DTiVo
            // 9 - DTiVo AC3 Audio Data with PES Header
            // ================================================
            if ( nybbleType == 0x03 || nybbleType == 0x09 )
            {
               int esOffset1, esOffset2;
               if ( nybbleType == 0x03 )
               esOffset1 = demux_ty_FindESHeader( AUDIO_NAL, &chunk[ offset ],
                  size);

               // SA PES Header, No Audio Data
               // ================================================
               if ( nybbleType == 0x03 && esOffset1 == 0 && size == 16 )
               {
                  tivo->tivoType = 1;
                  tivo->lastAudioPTS = get_ty_pts( &chunk[ offset +
                     SERIES2_PTS_OFFSET ] );
               }
               else
               // DTiVo Audio with PES Header
               // ================================================
               {
                  tivo->tivoType = 2;

                  demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size );
                  demux_ty_FindESPacket( nybbleType == 9 ? AC3_NAL : AUDIO_NAL,
                     tivo->lastAudio, tivo->lastAudioEnd, &esOffset1,
                     &esOffset2 );

                  if ( esOffset1 != -1 && esOffset2 != -1 )
                  {
                     int packetSize = esOffset2 - esOffset1;
                     int headerSize;
                     int ptsOffset;

                     if ( IsValidAudioPacket( packetSize, &ptsOffset,
                           &headerSize ) )
                     {
                        mp_msg( MSGT_DEMUX, MSGL_DBG3,
                           "ty:Adding DTiVo Audio Packet Size %d\n",
                           packetSize );

                        tivo->lastAudioPTS = get_ty_pts(
                           &tivo->lastAudio[ esOffset1 + ptsOffset ] );

                        if (nybbleType == 9) headerSize = 0;
                        demux_ty_CopyToDemuxPacket
                        (
                           demux->audio,
                           &tivo->lastAudio[ esOffset1 + headerSize ],
                           packetSize - headerSize,
                           demux->filepos + offset,
                           tivo->lastAudioPTS
                        );

                     }

                     // Collapse the Audio Buffer
                     tivo->lastAudioEnd -= esOffset2;
                     memmove( &tivo->lastAudio[ 0 ],
                        &tivo->lastAudio[ esOffset2 ],
                        tivo->lastAudioEnd );
                  }
               }
            }

            offset += size;
         }
         else
            errorHeader++;
      }
      // ================================================================
      // 1 = Closed Caption
      // 2 = Extended Data Services
      // ================================================================
      else if ( type == 0x01 || type == 0x02 )
      {
                        unsigned char lastXDS[ 16 ];
         int b = AV_RB24(recPtr) >> 4;
         b &= 0x7f7f;

         mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:%s %04x\n", type == 1 ? "CC" : "XDS", b);

         lastXDS[ 0x00 ] = 0x00;
         lastXDS[ 0x01 ] = 0x00;
         lastXDS[ 0x02 ] = 0x01;
         lastXDS[ 0x03 ] = 0xb2;
         lastXDS[ 0x04 ] = 'T';
         lastXDS[ 0x05 ] = 'Y';
         lastXDS[ 0x06 ] = type;
         lastXDS[ 0x07 ] = b >> 8;
         lastXDS[ 0x08 ] = b;
         if ( subcc_enabled )
            demux_ty_CopyToDemuxPacket( demux->video, lastXDS, 0x09,
               demux->filepos + offset, tivo->lastVideoPTS );
      }
      // ================================================================
      // Unknown
      // ================================================================
      else
      {
         if ( size > 0 && size + offset <= CHUNKSIZE )
Ejemplo n.º 13
0
// vsfshell_input_thread is used to process the events
// 		from the sender of the stream_rx
vsf_err_t vsfshell_input_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
	struct vsfshell_t *shell = (struct vsfshell_t *)pt->user_data;
	struct vsfsm_pt_t *output_pt = &shell->output_pt;
	char *cmd = (char *)shell->tbuffer.buffer.buffer;
	struct vsf_buffer_t buffer;
	
	vsfsm_pt_begin(pt);
	vsfsm_pt_wfe(pt, VSFSHELL_EVT_STREAMTX_ONCONN);
	vsfshell_printf(output_pt,
					"vsfshell 0.1 beta by SimonQian" VSFSHELL_LINEEND);
	vsfshell_printf(output_pt, VSFSHELL_PROMPT);
	shell->prompted = true;
	while (1)
	{
		vsfsm_pt_wfe(pt, VSFSHELL_EVT_STREAMRX_ONIN);
		do
		{
			buffer.buffer = (uint8_t *)&shell->ch;
			buffer.size = 1;
			buffer.size = stream_read(shell->stream_rx, &buffer);
			if (0 == buffer.size)
			{
				break;
			}
			
			if (shell->echo)
			{
				if ('\r' == shell->ch)
				{
					vsfshell_printf(output_pt, VSFSHELL_LINEEND);
				}
				else if ('\b' == shell->ch)
				{
					if (shell->tbuffer.position)
					{
						vsfshell_printf(output_pt, "\b \b");
						shell->tbuffer.position--;
					}
					continue;
				}
				else if (//!((shell->ch >= ' ') && (shell->ch <= '~')) ||
					(shell->tbuffer.position >= shell->tbuffer.buffer.size - 1))
				{
					continue;
				}
				else
				{
					vsfshell_printf(output_pt, "%c", shell->ch);
				}
			}
			
			if ('\r' == shell->ch)
			{
				if (shell->tbuffer.position > 0)
				{
					// create new handler thread
					cmd[shell->tbuffer.position] = '\0';
					if (vsfshell_new_handler_thread(shell, cmd))
					{
						vsfshell_printf(output_pt,
							"Fail to execute : %s" VSFSHELL_LINEEND, cmd);
						vsfshell_printf(output_pt, VSFSHELL_PROMPT);
					}
					shell->tbuffer.position = 0;
				}
				else
				{
					vsfshell_printf(output_pt, VSFSHELL_PROMPT);
				}
				shell->prompted = true;
				break;
			}
			else if (shell->ch != '\n')
			{
				cmd[shell->tbuffer.position++] = shell->ch;
			}
		} while (buffer.size > 0);
	}
	vsfsm_pt_end(pt);
	return VSFERR_NOT_READY;
}
Ejemplo n.º 14
0
int serial_read(dev_file_t *f, byte *data, dword size) {
  return stream_read(f, data, size);
}
Ejemplo n.º 15
0
static demuxer_t* demux_open_rawdv(demuxer_t* demuxer)
{
   unsigned char dv_frame[DV_PAL_FRAME_SIZE];
   sh_video_t *sh_video = NULL;
   rawdv_frames_t *frames = malloc(sizeof(rawdv_frames_t));
   dv_decoder_t *dv_decoder=NULL;

   mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() end_pos %"PRId64"\n",(int64_t)demuxer->stream->end_pos);

   // go back to the beginning
   stream_reset(demuxer->stream);
   stream_seek(demuxer->stream, 0);

   //get the first frame
   stream_read(demuxer->stream, dv_frame, DV_PAL_FRAME_SIZE);

   //read params from this frame
   dv_decoder=dv_decoder_new(TRUE,TRUE,FALSE);
   dv_decoder->quality=DV_QUALITY_BEST;

   if (dv_parse_header(dv_decoder, dv_frame) == -1)
	   return NULL;

   // create a new video stream header
   sh_video = new_sh_video(demuxer, 0);
   if (!sh_video)
	   return NULL;

   // make sure the demuxer knows about the new video stream header
   // (even though new_sh_video() ought to take care of it)
   demuxer->seekable = 1;
   demuxer->video->sh = sh_video;

   // make sure that the video demuxer stream header knows about its
   // parent video demuxer stream (this is getting wacky), or else
   // video_read_properties() will choke
   sh_video->ds = demuxer->video;

   // custom fourcc for internal MPlayer use
//   sh_video->format = mmioFOURCC('R', 'A', 'D', 'V');
   sh_video->format = mmioFOURCC('D', 'V', 'S', 'D');

   sh_video->disp_w = dv_decoder->width;
   sh_video->disp_h = dv_decoder->height;
   mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() frame_size: %d w: %d h: %d dif_seq: %d system: %d\n",dv_decoder->frame_size,dv_decoder->width, dv_decoder->height,dv_decoder->num_dif_seqs,dv_decoder->system);

   sh_video->fps= (dv_decoder->system==e_dv_system_525_60?29.97:25);
   sh_video->frametime = 1.0/sh_video->fps;

  // emulate BITMAPINFOHEADER for win32 decoders:
  sh_video->bih=malloc(sizeof(BITMAPINFOHEADER));
  memset(sh_video->bih,0,sizeof(BITMAPINFOHEADER));
  sh_video->bih->biSize=40;
  sh_video->bih->biWidth = dv_decoder->width;
  sh_video->bih->biHeight = dv_decoder->height;
  sh_video->bih->biPlanes=1;
  sh_video->bih->biBitCount=24;
  sh_video->bih->biCompression=sh_video->format; // "DVSD"
  sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3;


   frames->current_filepos=0;
   frames->current_frame=0;
   frames->frame_size=dv_decoder->frame_size;
   frames->frame_number=demuxer->stream->end_pos/frames->frame_size;

   mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() seek to %qu, size: %d, dv_dec->frame_size: %d\n",frames->current_filepos,frames->frame_size, dv_decoder->frame_size);
    if (dv_decoder->audio != NULL && demuxer->audio->id>=-1){
       sh_audio_t *sh_audio =  new_sh_audio(demuxer, 0);
	    demuxer->audio->sh = sh_audio;
	    sh_audio->ds = demuxer->audio;
       mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() chan: %d samplerate: %d\n",dv_decoder->audio->num_channels,dv_decoder->audio->frequency );
       // custom fourcc for internal MPlayer use
       sh_audio->format = mmioFOURCC('R', 'A', 'D', 'V');

	sh_audio->wf = malloc(sizeof(WAVEFORMATEX));
	memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX));
	sh_audio->wf->wFormatTag = sh_audio->format;
	sh_audio->wf->nChannels = dv_decoder->audio->num_channels;
	sh_audio->wf->wBitsPerSample = 16;
	sh_audio->wf->nSamplesPerSec = dv_decoder->audio->frequency;
	// info about the input stream:
	sh_audio->wf->nAvgBytesPerSec = sh_video->fps*dv_decoder->frame_size;
	sh_audio->wf->nBlockAlign = dv_decoder->frame_size;

//       sh_audio->context=(void*)dv_decoder;
    }
   stream_reset(demuxer->stream);
   stream_seek(demuxer->stream, 0);
   dv_decoder_free(dv_decoder);  //we keep this in the context of both stream headers
   demuxer->priv=frames;
   return demuxer;
}
Ejemplo n.º 16
0
void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
{
	STREAM* s;
	int length;
	BYTE padding;
	UINT32 version;
	int modulus_length;
	int exponent_length;

	s = stream_new(0);
	stream_attach(s, cert->data, cert->length);

	ber_read_sequence_tag(s, &length); /* Certificate (SEQUENCE) */

	ber_read_sequence_tag(s, &length); /* TBSCertificate (SEQUENCE) */

	/* Explicit Contextual Tag [0] */
	ber_read_contextual_tag(s, 0, &length, TRUE);
	ber_read_integer(s, &version); /* version (INTEGER) */
	version++;

	/* serialNumber */
	ber_read_integer(s, NULL); /* CertificateSerialNumber (INTEGER) */

	/* signature */
	ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
	stream_seek(s, length);

	/* issuer */
	ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */
	stream_seek(s, length);

	/* validity */
	ber_read_sequence_tag(s, &length); /* Validity (SEQUENCE) */
	stream_seek(s, length);

	/* subject */
	ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */
	stream_seek(s, length);

	/* subjectPublicKeyInfo */
	ber_read_sequence_tag(s, &length); /* SubjectPublicKeyInfo (SEQUENCE) */

	/* subjectPublicKeyInfo::AlgorithmIdentifier */
	ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
	stream_seek(s, length);

	/* subjectPublicKeyInfo::subjectPublicKey */
	ber_read_bit_string(s, &length, &padding); /* BIT_STRING */

	/* RSAPublicKey (SEQUENCE) */
	ber_read_sequence_tag(s, &length); /* SEQUENCE */

	ber_read_integer_length(s, &modulus_length); /* modulus (INTEGER) */

	/* skip zero padding, if any */
	do
	{
		stream_peek_BYTE(s, padding);

		if (padding == 0)
		{
			stream_seek(s, 1);
			modulus_length--;
		}
	}
	while (padding == 0);

	info->ModulusLength = modulus_length;
	info->Modulus = (BYTE*) malloc(info->ModulusLength);
	stream_read(s, info->Modulus, info->ModulusLength);

	ber_read_integer_length(s, &exponent_length); /* publicExponent (INTEGER) */
	stream_read(s, &info->exponent[4 - exponent_length], exponent_length);
	crypto_reverse(info->Modulus, info->ModulusLength);
	crypto_reverse(info->exponent, 4);

	stream_detach(s);
	stream_free(s);
}
Ejemplo n.º 17
0
uint32 serial_tty_control(SERIAL_TTY* tty, uint32 IoControlCode, STREAM* input, STREAM* output, uint32* abort_io)
{
	int purge_mask;
	uint32 result;
	uint32 modemstate;
	uint8 immediate;
	uint32 ret = STATUS_SUCCESS;
	uint32 length = 0;
	uint32 pos;

	DEBUG_SVC("in");

	stream_seek(output, sizeof(uint32));

	switch (IoControlCode)
	{
		case IOCTL_SERIAL_SET_BAUD_RATE:
			stream_read_uint32(input, tty->baud_rate);
			tty_set_termios(tty);
			DEBUG_SVC("SERIAL_SET_BAUD_RATE %d", tty->baud_rate);
			break;

		case IOCTL_SERIAL_GET_BAUD_RATE:
			length = 4;
			stream_write_uint32(output, tty->baud_rate);
			DEBUG_SVC("SERIAL_GET_BAUD_RATE %d", tty->baud_rate);
			break;

		case IOCTL_SERIAL_SET_QUEUE_SIZE:
			stream_read_uint32(input, tty->queue_in_size);
			stream_read_uint32(input, tty->queue_out_size);
			DEBUG_SVC("SERIAL_SET_QUEUE_SIZE in %d out %d", tty->queue_in_size, tty->queue_out_size);
			break;

		case IOCTL_SERIAL_SET_LINE_CONTROL:
			stream_read_uint8(input, tty->stop_bits);
			stream_read_uint8(input, tty->parity);
			stream_read_uint8(input, tty->word_length);
			tty_set_termios(tty);
			DEBUG_SVC("SERIAL_SET_LINE_CONTROL stop %d parity %d word %d",
				tty->stop_bits, tty->parity, tty->word_length);
			break;

		case IOCTL_SERIAL_GET_LINE_CONTROL:
			DEBUG_SVC("SERIAL_GET_LINE_CONTROL");
			length = 3;
			stream_write_uint8(output, tty->stop_bits);
			stream_write_uint8(output, tty->parity);
			stream_write_uint8(output, tty->word_length);
			break;

		case IOCTL_SERIAL_IMMEDIATE_CHAR:
			DEBUG_SVC("SERIAL_IMMEDIATE_CHAR");
			stream_read_uint8(input, immediate);
			tty_write_data(tty, &immediate, 1);
			break;

		case IOCTL_SERIAL_CONFIG_SIZE:
			DEBUG_SVC("SERIAL_CONFIG_SIZE");
			length = 4;
			stream_write_uint32(output, 0);
			break;

		case IOCTL_SERIAL_GET_CHARS:
			DEBUG_SVC("SERIAL_GET_CHARS");
			length = 6;
			stream_write(output, tty->chars, 6);
			break;

		case IOCTL_SERIAL_SET_CHARS:
			DEBUG_SVC("SERIAL_SET_CHARS");
			stream_read(input, tty->chars, 6);
			tty_set_termios(tty);
			break;

		case IOCTL_SERIAL_GET_HANDFLOW:
			length = 16;
			tty_get_termios(tty);
			stream_write_uint32(output, tty->control);
			stream_write_uint32(output, tty->xonoff);
			stream_write_uint32(output, tty->onlimit);
			stream_write_uint32(output, tty->offlimit);
			DEBUG_SVC("IOCTL_SERIAL_GET_HANDFLOW %X %X %X %X",
				tty->control, tty->xonoff, tty->onlimit, tty->offlimit);
			break;

		case IOCTL_SERIAL_SET_HANDFLOW:
			stream_read_uint32(input, tty->control);
			stream_read_uint32(input, tty->xonoff);
			stream_read_uint32(input, tty->onlimit);
			stream_read_uint32(input, tty->offlimit);
			DEBUG_SVC("IOCTL_SERIAL_SET_HANDFLOW %X %X %X %X",
				tty->control, tty->xonoff, tty->onlimit, tty->offlimit);
			tty_set_termios(tty);
			break;

		case IOCTL_SERIAL_SET_TIMEOUTS:
			stream_read_uint32(input, tty->read_interval_timeout);
			stream_read_uint32(input, tty->read_total_timeout_multiplier);
			stream_read_uint32(input, tty->read_total_timeout_constant);
			stream_read_uint32(input, tty->write_total_timeout_multiplier);
			stream_read_uint32(input, tty->write_total_timeout_constant);

			/* http://www.codeproject.com/KB/system/chaiyasit_t.aspx, see 'ReadIntervalTimeout' section
				http://msdn.microsoft.com/en-us/library/ms885171.aspx */
			if (tty->read_interval_timeout == SERIAL_TIMEOUT_MAX)
			{
				tty->read_interval_timeout = 0;
				tty->read_total_timeout_multiplier = 0;
			}

			DEBUG_SVC("SERIAL_SET_TIMEOUTS read timeout %d %d %d",
				tty->read_interval_timeout,
				tty->read_total_timeout_multiplier,
				tty->read_total_timeout_constant);
			break;

		case IOCTL_SERIAL_GET_TIMEOUTS:
			DEBUG_SVC("SERIAL_GET_TIMEOUTS read timeout %d %d %d",
				tty->read_interval_timeout,
				tty->read_total_timeout_multiplier,
				tty->read_total_timeout_constant);
			length = 20;
			stream_write_uint32(output, tty->read_interval_timeout);
			stream_write_uint32(output, tty->read_total_timeout_multiplier);
			stream_write_uint32(output, tty->read_total_timeout_constant);
			stream_write_uint32(output, tty->write_total_timeout_multiplier);
			stream_write_uint32(output, tty->write_total_timeout_constant);
			break;

		case IOCTL_SERIAL_GET_WAIT_MASK:
			DEBUG_SVC("SERIAL_GET_WAIT_MASK %X", tty->wait_mask);
			length = 4;
			stream_write_uint32(output, tty->wait_mask);
			break;

		case IOCTL_SERIAL_SET_WAIT_MASK:
			stream_read_uint32(input, tty->wait_mask);
			DEBUG_SVC("SERIAL_SET_WAIT_MASK %X", tty->wait_mask);
			break;

		case IOCTL_SERIAL_SET_DTR:
			DEBUG_SVC("SERIAL_SET_DTR");
			ioctl(tty->fd, TIOCMGET, &result);
			result |= TIOCM_DTR;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->dtr = 1;
			break;

		case IOCTL_SERIAL_CLR_DTR:
			DEBUG_SVC("SERIAL_CLR_DTR");
			ioctl(tty->fd, TIOCMGET, &result);
			result &= ~TIOCM_DTR;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->dtr = 0;
			break;

		case IOCTL_SERIAL_SET_RTS:
			DEBUG_SVC("SERIAL_SET_RTS");
			ioctl(tty->fd, TIOCMGET, &result);
			result |= TIOCM_RTS;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->rts = 1;
			break;

		case IOCTL_SERIAL_CLR_RTS:
			DEBUG_SVC("SERIAL_CLR_RTS");
			ioctl(tty->fd, TIOCMGET, &result);
			result &= ~TIOCM_RTS;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->rts = 0;
			break;

		case IOCTL_SERIAL_GET_MODEMSTATUS:
			modemstate = 0;
#ifdef TIOCMGET
			ioctl(tty->fd, TIOCMGET, &result);
			if (result & TIOCM_CTS)
				modemstate |= SERIAL_MS_CTS;
			if (result & TIOCM_DSR)
				modemstate |= SERIAL_MS_DSR;
			if (result & TIOCM_RNG)
				modemstate |= SERIAL_MS_RNG;
			if (result & TIOCM_CAR)
				modemstate |= SERIAL_MS_CAR;
			if (result & TIOCM_DTR)
				modemstate |= SERIAL_MS_DTR;
			if (result & TIOCM_RTS)
				modemstate |= SERIAL_MS_RTS;
#endif
			DEBUG_SVC("SERIAL_GET_MODEMSTATUS %X", modemstate);
			length = 4;
			stream_write_uint32(output, modemstate);
			break;

		case IOCTL_SERIAL_GET_COMMSTATUS:
			length = 18;
			stream_write_uint32(output, 0);	/* Errors */
			stream_write_uint32(output, 0);	/* Hold reasons */

			result = 0;
#ifdef TIOCINQ
			ioctl(tty->fd, TIOCINQ, &result);
#endif
			stream_write_uint32(output, result); /* Amount in in queue */
			if (result)
				DEBUG_SVC("SERIAL_GET_COMMSTATUS in queue %d", result);

			result = 0;
#ifdef TIOCOUTQ
			ioctl(tty->fd, TIOCOUTQ, &result);
#endif
			stream_write_uint32(output, result);	/* Amount in out queue */
			DEBUG_SVC("SERIAL_GET_COMMSTATUS out queue %d", result);

			stream_write_uint8(output, 0); /* EofReceived */
			stream_write_uint8(output, 0); /* WaitForImmediate */
			break;

		case IOCTL_SERIAL_PURGE:
			stream_read_uint32(input, purge_mask);
			DEBUG_SVC("SERIAL_PURGE purge_mask %X", purge_mask);

		/*	See http://msdn.microsoft.com/en-us/library/ms901431.aspx
			PURGE_TXCLEAR 	Clears the output buffer, if the driver has one.
			PURGE_RXCLEAR 	Clears the input buffer, if the driver has one.

			It clearly states to clear the *driver* buffer, not the port buffer
		*/

#ifdef DEBUG_SVC
			if (purge_mask & SERIAL_PURGE_TXCLEAR)
				DEBUG_SVC("Ignoring SERIAL_PURGE_TXCLEAR");
			if (purge_mask & SERIAL_PURGE_RXCLEAR)
				DEBUG_SVC("Ignoring SERIAL_PURGE_RXCLEAR");
#endif

			if (purge_mask & SERIAL_PURGE_TXABORT)
				*abort_io |= SERIAL_ABORT_IO_WRITE;
			if (purge_mask & SERIAL_PURGE_RXABORT)
				*abort_io |= SERIAL_ABORT_IO_READ;
			break;
		case IOCTL_SERIAL_WAIT_ON_MASK:
			DEBUG_SVC("SERIAL_WAIT_ON_MASK %X", tty->wait_mask);
			tty->event_pending = 1;
			length = 4;
			if (serial_tty_get_event(tty, &result))
			{
				DEBUG_SVC("WAIT end  event = %X", result);
				stream_write_uint32(output, result);
				break;
			}
			ret = STATUS_PENDING;
			break;

		case IOCTL_SERIAL_SET_BREAK_ON:
			DEBUG_SVC("SERIAL_SET_BREAK_ON");
			tcsendbreak(tty->fd, 0);
			break;

		case IOCTL_SERIAL_RESET_DEVICE:
			DEBUG_SVC("SERIAL_RESET_DEVICE");
			break;

		case IOCTL_SERIAL_SET_BREAK_OFF:
			DEBUG_SVC("SERIAL_SET_BREAK_OFF");
			break;

		case IOCTL_SERIAL_SET_XOFF:
			DEBUG_SVC("SERIAL_SET_XOFF");
			break;

		case IOCTL_SERIAL_SET_XON:
			DEBUG_SVC("SERIAL_SET_XON");
			tcflow(tty->fd, TCION);
			break;

		default:
			DEBUG_SVC("NOT FOUND IoControlCode SERIAL IOCTL %d", IoControlCode);
			return STATUS_INVALID_PARAMETER;
	}

	/* Write OutputBufferLength */
	pos = stream_get_pos(output);
	stream_set_pos(output, 16);
	stream_write_uint32(output, length);
	stream_set_pos(output, pos);

	return ret;
}
Ejemplo n.º 18
0
/* Zebra client message read function. */
int
zclient_read (struct thread *thread)
{
  int ret;
  int nbytes;
  int sock;
  zebra_size_t length;
  zebra_command_t command;
#undef	zclient
  struct_zclient *zclient;

  /* Get socket to zebra. */
  sock = THREAD_FD (thread);
  zclient = THREAD_ARG (thread);
  zclient->t_read = NULL;

  /* Clear input buffer. */
  stream_reset (zclient->ibuf);

  /* Read zebra header. */
  nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE);

  /* zebra socket is closed. */
  if (nbytes == 0) 
    {
      if (zclient_debug)
       zlog_debug ("zclient connection closed socket [%d].", sock);
      zclient->fail++;
      zclient_stop (zclient);
      zclient_event (ZCLIENT_CONNECT, zclient);
      return -1;
    }

  /* zebra read error. */
  if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE)
    {
      if (zclient_debug)
        zlog_debug ("Can't read all packet (length %d).", nbytes);
      zclient->fail++;
      zclient_stop (zclient);
      zclient_event (ZCLIENT_CONNECT, zclient);
      return -1;
    }

  /* Fetch length and command. */
  length = stream_getw (zclient->ibuf);
  command = stream_getc (zclient->ibuf);

  /* Length check. */
  if (length >= zclient->ibuf->size)
    {
      stream_free (zclient->ibuf);
      zclient->ibuf = stream_new (length + 1);
    }
  length -= ZEBRA_HEADER_SIZE;

  /* Read rest of zebra packet. */
  nbytes = stream_read (zclient->ibuf, sock, length);
 if (nbytes != length)
   {
     if (zclient_debug)
       zlog_debug ("zclient connection closed socket [%d].", sock);
     zclient->fail++;
     zclient_stop (zclient);
     zclient_event (ZCLIENT_CONNECT, zclient);
     return -1;
   }

  if (zclient_debug)
    zlog_debug("zclient 0x%p command 0x%x \n", zclient, command);

  switch (command)
    {
    case ZEBRA_ROUTER_ID_UPDATE:
      if (zclient->router_id_update)
	ret = (*zclient->router_id_update) (command, zclient, length);
      break;
    case ZEBRA_INTERFACE_ADD:
      if (zclient->interface_add)
	ret = (*zclient->interface_add) (command, zclient, length);
      break;
    case ZEBRA_INTERFACE_DELETE:
      if (zclient->interface_delete)
	ret = (*zclient->interface_delete) (command, zclient, length);
      break;
    case ZEBRA_INTERFACE_ADDRESS_ADD:
      if (zclient->interface_address_add)
	ret = (*zclient->interface_address_add) (command, zclient, length);
      break;
    case ZEBRA_INTERFACE_ADDRESS_DELETE:
      if (zclient->interface_address_delete)
	ret = (*zclient->interface_address_delete) (command, zclient, length);
      break;
    case ZEBRA_INTERFACE_UP:
      if (zclient->interface_up)
	ret = (*zclient->interface_up) (command, zclient, length);
      break;
    case ZEBRA_INTERFACE_DOWN:
      if (zclient->interface_down)
	ret = (*zclient->interface_down) (command, zclient, length);
      break;
    case ZEBRA_IPV4_ROUTE_ADD:
      if (zclient->ipv4_route_add)
	ret = (*zclient->ipv4_route_add) (command, zclient, length);
      break;
    case ZEBRA_IPV4_ROUTE_DELETE:
      if (zclient->ipv4_route_delete)
	ret = (*zclient->ipv4_route_delete) (command, zclient, length);
      break;
    case ZEBRA_IPV6_ROUTE_ADD:
      if (zclient->ipv6_route_add)
	ret = (*zclient->ipv6_route_add) (command, zclient, length);
      break;
    case ZEBRA_IPV6_ROUTE_DELETE:
      if (zclient->ipv6_route_delete)
	ret = (*zclient->ipv6_route_delete) (command, zclient, length);
      break;
    default:
      break;
    }

  /* Register read thread. */
  zclient_event (ZCLIENT_READ, zclient);

  return 0;
}
Ejemplo n.º 19
0
static int pva_get_payload(demuxer_t *d, pva_payload_t *payload)
{
	uint8_t flags,pes_head_len;
	uint16_t pack_size;
	off_t pva_payload_start;
	unsigned char buffer[256];
	pva_priv_t * priv;


	if(d==NULL)
	{
		mp_msg(MSGT_DEMUX,MSGL_ERR,"demux_pva: pva_get_payload got passed a NULL pointer!\n");
		return 0;
	}

	priv = (pva_priv_t *)d->priv;
	d->filepos=stream_tell(d->stream);




	if(d->stream->eof)
	{
		mp_msg(MSGT_DEMUX,MSGL_V,"demux_pva: pva_get_payload() detected stream->eof!!!\n");
		return 0;
	}

	//printf("priv->just_synced %s\n",priv->just_synced?"SET":"UNSET");

	if(priv->prebytes_delivered)
		/* The previous call to this fn has delivered the preBytes. Then we are already inside
		 * the payload. Let's just deliver the video along with its right PTS, the one we stored
		 * in the priv structure and was in the PVA header before the PreBytes.
		 */
	{
		//printf("prebytes_delivered=1. Resetting.\n");
		payload->size = priv->video_size_after_prebytes;
		payload->pts = priv->video_pts_after_prebytes;
		payload->is_packet_start = 1;
		payload->offset = stream_tell(d->stream);
		payload->type = VIDEOSTREAM;
		priv->prebytes_delivered = 0;
		return 1;
	}
	if(!priv->just_synced)
	{
		if(stream_read_word(d->stream) != (('A'<<8)|'V'))
		{
			mp_msg(MSGT_DEMUX,MSGL_V,"demux_pva: pva_get_payload() missed a SyncWord at %"PRId64"!! Trying to sync...\n",(int64_t)stream_tell(d->stream));
			if(!pva_sync(d))
			{
				if (!d->stream->eof)
				{
					mp_msg(MSGT_DEMUX,MSGL_ERR,"demux_pva: couldn't sync! (broken file?)");
				}
				return 0;
			}
		}
	}
	if(priv->just_synced)
	{
		payload->type=priv->synced_stream_id;
		priv->just_synced=0;
	}
	else
	{
		payload->type=stream_read_char(d->stream);
		stream_skip(d->stream,2); //counter and reserved
	}
	flags=stream_read_char(d->stream);
	payload->is_packet_start=flags & 0x10;
	pack_size=stream_read_word(d->stream);
	mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_pva::pva_get_payload(): pack_size=%u field read at offset %"PRIu64"\n",pack_size,(int64_t)stream_tell(d->stream)-2);
	pva_payload_start=stream_tell(d->stream);


	/*
	 * The code in the #ifdef directive below is a hack needed to get badly formatted PVA files
	 * such as the ones written by MultiDec played back correctly.
	 * Basically, it works like this: if the PVA packet does not signal a PES header, but the
	 * payload looks like one, let's assume it IS one. It has worked for me up to now.
	 * It can be disabled since it's quite an ugly hack and could potentially break things up
	 * if the PVA audio payload happens to start with 0x000001 even without being a non signalled
	 * PES header start.
	 * Though it's quite unlikely, it potentially could (AFAIK).
	 */
#ifdef DEMUX_PVA_MULTIDEC_HACK
	if(payload->type==MAINAUDIOSTREAM)
	{
		stream_read(d->stream,buffer,3);
		if(buffer[0]==0x00 && buffer[1]==0x00 && buffer[2]==0x01 && !payload->is_packet_start)
		{
			mp_msg(MSGT_DEMUX,MSGL_V,"demux_pva: suspecting non signaled audio PES packet start. Maybe file by MultiDec?\n");
			payload->is_packet_start=1;
		}
		stream_seek(d->stream,stream_tell(d->stream)-3);
	}
#endif


	if(!payload->is_packet_start)
	{
		payload->offset=stream_tell(d->stream);
		payload->size=pack_size;
	}
	else
	{	//here comes the good part...
		switch(payload->type)
		{
			case VIDEOSTREAM:
				payload->pts=(float)(stream_read_dword(d->stream))/90000;
				//printf("Video PTS: %f\n",payload->pts);
				if((flags&0x03)
						&& !priv->prebytes_delivered
						)
				{
					//printf("Delivering prebytes. Setting prebytes_delivered.");
					payload->offset=stream_tell(d->stream);
					payload->size = flags & 0x03;
					priv->video_pts_after_prebytes = payload->pts;
					priv->video_size_after_prebytes = pack_size - 4 - (flags & 0x03);
					payload->pts=priv->last_video_pts;
					payload->is_packet_start=0;
					priv->prebytes_delivered=1;
					return 1;
				}


				//now we are at real beginning of payload.
				payload->offset=stream_tell(d->stream);
				//size is pack_size minus PTS size minus PreBytes size.
				payload->size=pack_size - 4 - (flags & 0x03);
				break;
			case MAINAUDIOSTREAM:
				stream_skip(d->stream,3); //FIXME properly parse PES header.
				//printf("StreamID in audio PES header: 0x%2X\n",stream_read_char(d->stream));
				stream_skip(d->stream,4);

				buffer[255]=stream_read_char(d->stream);
				pes_head_len=stream_read_char(d->stream);
				stream_read(d->stream,buffer,pes_head_len);
				if(!(buffer[255]&0x80)) //PES header does not contain PTS.
				{
					mp_msg(MSGT_DEMUX,MSGL_V,"Audio PES packet does not contain PTS. (pes_head_len=%d)\n",pes_head_len);
					payload->pts=priv->last_audio_pts;
					break;
				}
				else		//PES header DOES contain PTS
				{
					if((buffer[0] & 0xf0)!=0x20) // PTS badly formatted
					{
						mp_msg(MSGT_DEMUX,MSGL_V,"demux_pva: expected audio PTS but badly formatted... (read 0x%02X). Falling back to previous PTS (hack).\n",buffer[0]);
						payload->pts=priv->last_audio_pts;
					//	return 0;
					}
					else
					{
						uint64_t temp_pts;

						temp_pts=0LL;
						temp_pts|=((uint64_t)(buffer[0] & 0x0e) << 29);
						temp_pts|=buffer[1]<<22;
						temp_pts|=(buffer[2] & 0xfe) << 14;
						temp_pts|=buffer[3]<<7;
						temp_pts|=(buffer[4] & 0xfe) >> 1;
						/*
					 	* PTS parsing is hopefully finished.
					 	*/
						payload->pts=(float)temp_pts/90000;
					}
				}
				payload->offset=stream_tell(d->stream);
				payload->size=pack_size-stream_tell(d->stream)+pva_payload_start;
				break;
		}
	}
	return 1;
}
Ejemplo n.º 20
0
void read_avi_header(demuxer_t *demuxer,int index_mode){
sh_audio_t *sh_audio=NULL;
sh_video_t *sh_video=NULL;
int stream_id=-1;
int idxfix_videostream=0;
int idxfix_divx=0;
avi_priv_t* priv=demuxer->priv;
off_t list_end=0;

//---- AVI header:
priv->idx_size=0;
priv->audio_streams=0;
while(1){
  int id=stream_read_dword_le(demuxer->stream);
  unsigned chunksize,size2;
  static int last_fccType=0;
  static int last_fccHandler=0;
  char* hdr=NULL;
  //
  if(stream_eof(demuxer->stream)) break;
  // Imply -forceidx if -saveidx is specified
  if (index_file_save)
    index_mode = 2;
  //
  if(id==mmioFOURCC('L','I','S','T')){
    unsigned len=stream_read_dword_le(demuxer->stream);   // list size
    id=stream_read_dword_le(demuxer->stream);             // list type
    mp_msg(MSGT_HEADER,MSGL_DBG2,"LIST %.4s  len=%u\n",(char *) &id,len);
    if(len >= 4) {
	len -= 4;
	list_end=stream_tell(demuxer->stream)+((len+1)&(~1));
    } else {
	mp_msg(MSGT_HEADER,MSGL_WARN,MSGTR_MPDEMUX_AVIHDR_EmptyList);
	list_end = 0;
    }
    mp_msg(MSGT_HEADER,MSGL_V,"list_end=0x%X\n",(int)list_end);
    if(id==listtypeAVIMOVIE){
      // found MOVI header
      if(!demuxer->movi_start) demuxer->movi_start=stream_tell(demuxer->stream);
      demuxer->movi_end=stream_tell(demuxer->stream)+len;
      mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_FoundMovieAt,(int)demuxer->movi_start,(int)demuxer->movi_end);
      if(demuxer->stream->end_pos>demuxer->movi_end) demuxer->movi_end=demuxer->stream->end_pos;
      if(index_mode==-2 || index_mode==2 || index_mode==0)
        break; // reading from non-seekable source (stdin) or forced index or no index forced
      if(list_end>0) stream_seek(demuxer->stream,list_end); // skip movi
      list_end=0;
    }
    continue;
  }
  size2=stream_read_dword_le(demuxer->stream);
  mp_msg(MSGT_HEADER,MSGL_DBG2,"CHUNK %.4s  len=%u\n",(char *) &id,size2);
  chunksize=(size2+1)&(~1);
  switch(id){

    // Indicates where the subject of the file is archived
    case mmioFOURCC('I','A','R','L'): hdr="Archival Location";break;
    // Lists the artist of the original subject of the file;
    // for example, "Michaelangelo."
    case mmioFOURCC('I','A','R','T'): hdr="Artist";break;
    // Lists the name of the person or organization that commissioned
    // the subject of the file; for example "Pope Julian II."
    case mmioFOURCC('I','C','M','S'): hdr="Commissioned";break;
    // Provides general comments about the file or the subject
    // of the file. If the comment is several sentences long, end each
    // sentence with a period. Do not include new-line characters.
    case mmioFOURCC('I','C','M','T'): hdr="Comments";break;
    // Records the copyright information for the file; for example,
    // "Copyright Encyclopedia International 1991." If there are multiple
    // copyrights, separate them by semicolon followed by a space.
    case mmioFOURCC('I','C','O','P'): hdr="Copyright";break;
    // Describes whether an image has been cropped and, if so, how it
    // was cropped; for example, "lower-right corner."
    case mmioFOURCC('I','C','R','D'): hdr="Creation Date";break;
    // Describes whether an image has been cropped and, if so, how it
    // was cropped; for example, "lower-right corner."
    case mmioFOURCC('I','C','R','P'): hdr="Cropped";break;
    // Specifies the size of the original subject of the file; for
    // example, "8.5 in h, 11 in w."
    case mmioFOURCC('I','D','I','M'): hdr="Dimensions";break;
    // Stores dots per inch setting of the digitizer used to
    // produce the file, such as "300."
    case mmioFOURCC('I','D','P','I'): hdr="Dots Per Inch";break;
    // Stores the of the engineer who worked on the file. If there are
    // multiple engineers, separate the names by a semicolon and a blank;
    // for example, "Smith, John; Adams, Joe."
    case mmioFOURCC('I','E','N','G'): hdr="Engineer";break;
    // Describes the original work, such as "landscape,", "portrait,"
    // "still liefe," etc.
    case mmioFOURCC('I','G','N','R'): hdr="Genre";break;
    // Provides a list of keywords that refer to the file or subject of the
    // file. Separate multiple keywords with a semicolon and a blank;
    // for example, "Seattle, aerial view; scenery."
    case mmioFOURCC('I','K','E','Y'): hdr="Keywords";break;
    // ILGT - Describes the changes in the lightness settings on the digitizer
    // required to produce the file. Note that the format of this information
    // depends on the hardware used.
    case mmioFOURCC('I','L','G','T'): hdr="Lightness";break;
    // IMED - Decribes the original subject of the file, such as
    // "computer image," "drawing," "lithograph," and so on.
    case mmioFOURCC('I','M','E','D'): hdr="Medium";break;
    // INAM - Stores the title of the subject of the file, such as
    // "Seattle from Above."
    case mmioFOURCC('I','N','A','M'): hdr="Title";break;
    // IPLT - Specifies the number of colors requested when digitizing
    // an image, such as "256."
    case mmioFOURCC('I','P','L','T'): hdr="Palette Setting";break;
    // IPRD - Specifies the name of title the file was originally intended
    // for, such as "Encyclopedia of Pacific Northwest Geography."
    case mmioFOURCC('I','P','R','D'): hdr="Product";break;
    // ISBJ - Decsribes the contents of the file, such as
    // "Aerial view of Seattle."
    case mmioFOURCC('I','S','B','J'): hdr="Subject";break;
    // ISFT - Identifies the name of the software packages used to create the
    // file, such as "Microsoft WaveEdit"
    case mmioFOURCC('I','S','F','T'): hdr="Software";break;
    // ISHP - Identifies the change in sharpness for the digitizer
    // required to produce the file (the format depends on the hardware used).
    case mmioFOURCC('I','S','H','P'): hdr="Sharpness";break;
    // ISRC - Identifies the name of the person or organization who
    // suplied the original subject of the file; for example, "Try Research."
    case mmioFOURCC('I','S','R','C'): hdr="Source";break;
    // ISRF - Identifies the original form of the material that was digitized,
    // such as "slide," "paper," "map," and so on. This is not necessarily
    // the same as IMED
    case mmioFOURCC('I','S','R','F'): hdr="Source Form";break;
    // ITCH - Identifies the technician who digitized the subject file;
    // for example, "Smith, John."
    case mmioFOURCC('I','T','C','H'): hdr="Technician";break;
    case mmioFOURCC('I','S','M','P'): hdr="Time Code";break;
    case mmioFOURCC('I','D','I','T'): hdr="Digitization Time";break;

    case ckidAVIMAINHDR:          // read 'avih'
      stream_read(demuxer->stream,(char*) &avih,FFMIN(size2,sizeof(avih)));
      le2me_MainAVIHeader(&avih); // swap to machine endian
      chunksize-=FFMIN(size2,sizeof(avih));
      if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_avih(&avih,MSGL_V); // else print_avih_flags(&avih,MSGL_V);
      break;
    case ckidSTREAMHEADER: {      // read 'strh'
      AVIStreamHeader h;
      stream_read(demuxer->stream,(char*) &h,FFMIN(size2,sizeof(h)));
      le2me_AVIStreamHeader(&h);  // swap to machine endian
      chunksize-=FFMIN(size2,sizeof(h));
      ++stream_id;
      if(h.fccType==streamtypeVIDEO){
        sh_video=new_sh_video(demuxer,stream_id);
        mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "aviheader", stream_id);
        memcpy(&sh_video->video,&h,sizeof(h));
        sh_video->stream_delay = (float)sh_video->video.dwStart * sh_video->video.dwScale/sh_video->video.dwRate;
      } else
      if(h.fccType==streamtypeAUDIO){
        sh_audio=new_sh_audio(demuxer,stream_id);
        mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "aviheader", stream_id);
        memcpy(&sh_audio->audio,&h,sizeof(h));
        sh_audio->stream_delay = (float)sh_audio->audio.dwStart * sh_audio->audio.dwScale/sh_audio->audio.dwRate;
      }
      last_fccType=h.fccType;
      last_fccHandler=h.fccHandler;
      if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_strh(&h,MSGL_V);
      break; }
    case mmioFOURCC('i', 'n', 'd', 'x'): {
      uint32_t i;
      avisuperindex_chunk *s;

      if(!index_mode) break;

      if(chunksize<=24){
        break;
      }
      priv->suidx_size++;
      priv->suidx = realloc_struct(priv->suidx, priv->suidx_size, sizeof (avisuperindex_chunk));
      s = &priv->suidx[priv->suidx_size-1];

      chunksize-=24;
      memcpy(s->fcc, "indx", 4);
      s->dwSize = size2;
      s->wLongsPerEntry = stream_read_word_le(demuxer->stream);
      s->bIndexSubType = stream_read_char(demuxer->stream);
      s->bIndexType = stream_read_char(demuxer->stream);
      s->nEntriesInUse = stream_read_dword_le(demuxer->stream);
      *(uint32_t *)s->dwChunkId = stream_read_dword_le(demuxer->stream);
      stream_read(demuxer->stream, (char *)s->dwReserved, 3*4);
      memset(s->dwReserved, 0, 3*4);

      print_avisuperindex_chunk(s,MSGL_V);

      // Check and fix this useless crap
      if(s->wLongsPerEntry != sizeof (avisuperindex_entry)/4) {
          mp_msg (MSGT_HEADER, MSGL_WARN, "Broken super index chunk size: %u\n",s->wLongsPerEntry);
          s->wLongsPerEntry = sizeof(avisuperindex_entry)/4;
      }
      if( ((chunksize/4)/s->wLongsPerEntry) < s->nEntriesInUse){
        mp_msg (MSGT_HEADER, MSGL_WARN, "Broken super index chunk\n");
        s->nEntriesInUse = (chunksize/4)/s->wLongsPerEntry;
      }

      s->aIndex = calloc(s->nEntriesInUse, sizeof (avisuperindex_entry));
      s->stdidx = calloc(s->nEntriesInUse, sizeof (avistdindex_chunk));

      // now the real index of indices
      for (i=0; i<s->nEntriesInUse; i++) {
	  chunksize-=16;
	  s->aIndex[i].qwOffset = stream_read_qword_le(demuxer->stream);
	  s->aIndex[i].dwSize = stream_read_dword_le(demuxer->stream);
	  s->aIndex[i].dwDuration = stream_read_dword_le(demuxer->stream);
	  mp_msg (MSGT_HEADER, MSGL_V, "ODML (%.4s): [%d] 0x%016"PRIx64" 0x%04x %u\n",
		  (s->dwChunkId), i,
		  (uint64_t)s->aIndex[i].qwOffset, s->aIndex[i].dwSize, s->aIndex[i].dwDuration);
      }

      break; }
    case ckidSTREAMFORMAT: {      // read 'strf'
      if(last_fccType==streamtypeVIDEO){
        sh_video->bih=calloc(FFMAX(chunksize, sizeof(BITMAPINFOHEADER)), 1);
//        sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize);
        mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_FoundBitmapInfoHeader,chunksize,sizeof(BITMAPINFOHEADER));
        stream_read(demuxer->stream,(char*) sh_video->bih,chunksize);
	le2me_BITMAPINFOHEADER(sh_video->bih);  // swap to machine endian
	if (sh_video->bih->biSize > chunksize && sh_video->bih->biSize > sizeof(BITMAPINFOHEADER))
		sh_video->bih->biSize = chunksize;
	// fixup MS-RLE header (seems to be broken for <256 color files)
	if(sh_video->bih->biCompression<=1 && sh_video->bih->biSize==40)
	    sh_video->bih->biSize=chunksize;
        if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih,MSGL_V);
        chunksize=0;
        sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale;
        sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
        sh_video->format = sh_video->bih->biCompression;
//        if(demuxer->video->id==-1) demuxer->video->id=stream_id;
        // IdxFix:
        idxfix_videostream=stream_id;
        switch(sh_video->bih->biCompression){
	case mmioFOURCC('M', 'P', 'G', '4'):
	case mmioFOURCC('m', 'p', 'g', '4'):
	case mmioFOURCC('D', 'I', 'V', '1'):
          idxfix_divx=3; // set index recovery mpeg4 flavour: msmpeg4v1
	  mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_RegeneratingKeyfTableForMPG4V1);
	  break;
        case mmioFOURCC('D', 'I', 'V', '3'):
	case mmioFOURCC('d', 'i', 'v', '3'):
	case mmioFOURCC('D', 'I', 'V', '4'):
        case mmioFOURCC('d', 'i', 'v', '4'):
	case mmioFOURCC('D', 'I', 'V', '5'):
	case mmioFOURCC('d', 'i', 'v', '5'):
	case mmioFOURCC('D', 'I', 'V', '6'):
        case mmioFOURCC('d', 'i', 'v', '6'):
	case mmioFOURCC('M', 'P', '4', '3'):
	case mmioFOURCC('m', 'p', '4', '3'):
	case mmioFOURCC('M', 'P', '4', '2'):
	case mmioFOURCC('m', 'p', '4', '2'):
	case mmioFOURCC('D', 'I', 'V', '2'):
        case mmioFOURCC('A', 'P', '4', '1'):
          idxfix_divx=1; // set index recovery mpeg4 flavour: msmpeg4v3
	  mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_RegeneratingKeyfTableForDIVX3);
	  break;
        case mmioFOURCC('D', 'I', 'V', 'X'):
        case mmioFOURCC('d', 'i', 'v', 'x'):
        case mmioFOURCC('D', 'X', '5', '0'):
        case mmioFOURCC('X', 'V', 'I', 'D'):
        case mmioFOURCC('x', 'v', 'i', 'd'):
        case mmioFOURCC('F', 'M', 'P', '4'):
        case mmioFOURCC('f', 'm', 'p', '4'):
          idxfix_divx=2; // set index recovery mpeg4 flavour: generic mpeg4
	  mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_RegeneratingKeyfTableForMPEG4);
	  break;
        }
      } else
      if(last_fccType==streamtypeAUDIO){
	unsigned wf_size = chunksize<sizeof(WAVEFORMATEX)?sizeof(WAVEFORMATEX):chunksize;
        sh_audio->wf=calloc(wf_size,1);
//        sh_audio->wf=malloc(chunksize); memset(sh_audio->wf,0,chunksize);
        mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_FoundWaveFmt,chunksize,sizeof(WAVEFORMATEX));
        stream_read(demuxer->stream,(char*) sh_audio->wf,chunksize);
	le2me_WAVEFORMATEX(sh_audio->wf);
	if (sh_audio->wf->cbSize != 0 &&
	    wf_size < sizeof(WAVEFORMATEX)+sh_audio->wf->cbSize) {
	    sh_audio->wf=realloc(sh_audio->wf, sizeof(WAVEFORMATEX)+sh_audio->wf->cbSize);
	}
	sh_audio->format=sh_audio->wf->wFormatTag;
	if (sh_audio->format == 1 &&
	    last_fccHandler == mmioFOURCC('A', 'x', 'a', 'n'))
	    sh_audio->format = last_fccHandler;
	sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec;
        chunksize=0;
        if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf,MSGL_V);
	++priv->audio_streams;
//        if(demuxer->audio->id==-1) demuxer->audio->id=stream_id;
      }
      break;
    }
    case mmioFOURCC('v', 'p', 'r', 'p'): {
	VideoPropHeader *vprp = malloc(chunksize);
	unsigned int i;
	stream_read(demuxer->stream, (void*)vprp, chunksize);
	le2me_VideoPropHeader(vprp);
	chunksize -= sizeof(*vprp)-sizeof(vprp->FieldInfo);
	chunksize /= sizeof(VIDEO_FIELD_DESC);
	if (vprp->nbFieldPerFrame > chunksize) {
	    vprp->nbFieldPerFrame = chunksize;
	}
	chunksize = 0;
	for (i=0; i<vprp->nbFieldPerFrame; i++) {
		le2me_VIDEO_FIELD_DESC(&vprp->FieldInfo[i]);
	}
	if (sh_video) {
		sh_video->aspect = GET_AVI_ASPECT(vprp->dwFrameAspectRatio);
	}
	if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_vprp(vprp,MSGL_V);
	free(vprp);
	break;
    }
    case mmioFOURCC('d', 'm', 'l', 'h'): {
	// dmlh 00 00 00 04 frms
	unsigned int total_frames = stream_read_dword_le(demuxer->stream);
	mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_FoundAVIV2Header, chunksize, total_frames);
	stream_skip(demuxer->stream, chunksize-4);
	chunksize = 0;
    }
    break;
    case ckidAVINEWINDEX:
    if(demuxer->movi_end>stream_tell(demuxer->stream))
	demuxer->movi_end=stream_tell(demuxer->stream); // fixup movi-end
    if(index_mode && !priv->isodml){
      int i;
      priv->idx_size=size2>>4;
      mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_ReadingIndexBlockChunksForFrames,
        priv->idx_size,avih.dwTotalFrames, (int64_t)stream_tell(demuxer->stream));
      priv->idx=malloc(priv->idx_size<<4);
//      printf("\nindex to %p !!!!! (priv=%p)\n",priv->idx,priv);
      stream_read(demuxer->stream,(char*)priv->idx,priv->idx_size<<4);
      for (i = 0; i < priv->idx_size; i++) {	// swap index to machine endian
	AVIINDEXENTRY *entry=(AVIINDEXENTRY*)priv->idx + i;
	le2me_AVIINDEXENTRY(entry);
	/*
	 * We (ab)use the upper word for bits 32-47 of the offset, so
	 * we'll clear them here.
	 * FIXME: AFAIK no codec uses them, but if one does it will break
	 */
	entry->dwFlags&=0xffff;
      }
      chunksize-=priv->idx_size<<4;
      if( mp_msg_test(MSGT_HEADER,MSGL_DBG2) ) print_index(priv->idx,priv->idx_size,MSGL_DBG2);
    }
    break;
    /* added May 2002 */
    case mmioFOURCC('R','I','F','F'): {
	char riff_type[4];

	mp_msg(MSGT_HEADER, MSGL_V, MSGTR_MPDEMUX_AVIHDR_AdditionalRIFFHdr);
	stream_read(demuxer->stream, riff_type, sizeof riff_type);
	if (strncmp(riff_type, "AVIX", sizeof riff_type))
	    mp_msg(MSGT_HEADER, MSGL_WARN, MSGTR_MPDEMUX_AVIHDR_WarnNotExtendedAVIHdr);
	else {
		/*
		 * We got an extended AVI header, so we need to switch to
		 * ODML to get seeking to work, provided we got indx chunks
		 * in the header (suidx_size > 0).
		 */
		if (priv->suidx_size > 0)
			priv->isodml = 1;
	}
	chunksize = 0;
	list_end = 0; /* a new list will follow */
	break; }
    case ckidAVIPADDING:
	stream_skip(demuxer->stream, chunksize);
	chunksize = 0;
	break;
  }
  if(hdr){
    mp_msg(MSGT_HEADER,MSGL_V,"hdr=%s  size=%u\n",hdr,size2);
    if(size2==3)
      chunksize=1; // empty
    else {
      char buf[256];
      int len=(size2<250)?size2:250;
      stream_read(demuxer->stream,buf,len);
      chunksize-=len;
      buf[len]=0;
      mp_msg(MSGT_HEADER,MSGL_V,"%-10s: %s\n",hdr,buf);
      demux_info_add(demuxer, hdr, buf);
    }
  }
  mp_msg(MSGT_HEADER,MSGL_DBG2,"list_end=0x%"PRIX64"  pos=0x%"PRIX64"  chunksize=0x%"PRIX64"  next=0x%"PRIX64"\n",
      (int64_t)list_end, (int64_t)stream_tell(demuxer->stream),
      (int64_t)chunksize, (int64_t)chunksize+(int64_t)stream_tell(demuxer->stream));
  if(list_end>0 &&
     chunksize+stream_tell(demuxer->stream) == list_end) list_end=0;
  if(list_end>0 && chunksize+stream_tell(demuxer->stream)>list_end){
      mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_BrokenChunk,chunksize,(char *) &id);
      stream_seek(demuxer->stream,list_end);
      list_end=0;
  } else
  if(chunksize>0) stream_skip(demuxer->stream,chunksize); else
  if((int)chunksize<0) mp_msg(MSGT_HEADER,MSGL_WARN,"chunksize=%u  (id=%.4s)\n",chunksize,(char *) &id);

}
Ejemplo n.º 21
0
void *thread_readstream(void *vargs)
{
    struct thread *t = (struct thread *) vargs;

    pthread_cleanup_push(thread_readstream_close, t);

    while (session.state != STATE_DEAD)
    {
        char *msg = NULL;

        if (session.state != STATE_RUN)
        {
            pthread_mutex_lock(&_lock_readstream);

            while (session.state == STATE_TLS_INIT)
                pthread_cond_wait(&_cond_readstream, &_lock_readstream);

            if (session.state == STATE_INIT)
            {
                session.state = STATE_POLL;
                pthread_cond_signal(&_cond_readstream);
            }

            pthread_mutex_unlock(&_lock_readstream);

            msg = stream_read(session.wfs);

            pthread_mutex_lock(&_lock_readstream);

            if (session.state == STATE_POLL)
            {
                session.state = STATE_INIT;
                pthread_cond_signal(&_cond_readstream);
            }

            pthread_mutex_unlock(&_lock_readstream);
        }
        else
        {
            msg = stream_read(session.wfs);
        }

        if (msg == NULL || strlen(msg) <= 0)
        {
            if (session.state != STATE_DEAD)
            {
                status_set(STATUS_OFFLINE);
            }

            break;
        }

        { /* Replace any " with ' */
            for (char *s = msg; *s; ++s)
                if (*s == '"')
                    *s = '\'';
        }

        thread_readstream_post_new_msg(msg);

        session.xmpp.last_query = time(NULL);
    }

    pthread_cleanup_pop(1);
    return thread_close(t);
}
Ejemplo n.º 22
0
int read_asf_header(demuxer_t *demuxer,struct asf_priv* asf) {
    int hdr_len = asf->header.objh.size - sizeof(asf->header);
    int hdr_skip = 0;
    char *hdr = NULL;
    char guid_buffer[16];
    int pos, start = stream_tell(demuxer->stream);
    uint32_t* streams = NULL;
    int audio_streams=0;
    int video_streams=0;
    uint16_t stream_count=0;
    int best_video = -1;
    int best_audio = -1;
    uint64_t data_len;
    ASF_stream_header_t *streamh;
    uint8_t *buffer;
    int audio_pos=0;

    if(hdr_len < 0) {
        mp_msg(MSGT_HEADER, MSGL_FATAL, "Header size is too small.\n");
        return 0;
    }

    if (hdr_len > 1024 * 1024) {
        mp_tmsg(MSGT_HEADER, MSGL_ERR, "FATAL: header size bigger than 1 MB (%d)!\nPlease contact MPlayer authors, and upload/send this file.\n",
                hdr_len);
        hdr_skip = hdr_len - 1024 * 1024;
        hdr_len = 1024 * 1024;
    }
    hdr = malloc(hdr_len);
    if (!hdr) {
        mp_tmsg(MSGT_HEADER, MSGL_FATAL, "Could not allocate %d bytes for header.\n",
                hdr_len);
        return 0;
    }
    stream_read(demuxer->stream, hdr, hdr_len);
    if (hdr_skip)
        stream_skip(demuxer->stream, hdr_skip);
    if (stream_eof(demuxer->stream)) {
        mp_tmsg(MSGT_HEADER, MSGL_FATAL, "EOF while reading ASF header, broken/incomplete file?\n");
        goto err_out;
    }

    if (is_drm(hdr, hdr_len))
        mp_tmsg(MSGT_HEADER, MSGL_FATAL, "This file has been encumbered with DRM encryption, it will not play in MPlayer!\n");

    if ((pos = find_asf_guid(hdr, asf_ext_stream_audio, 0, hdr_len)) >= 0)
    {
        // Special case: found GUID for dvr-ms audio.
        // Now skip back to associated stream header.
        int sh_pos=0;

        sh_pos = find_backwards_asf_guid(hdr, asf_stream_header_guid, pos);

        if (sh_pos > 0) {
            sh_audio_t *sh_audio;

            mp_msg(MSGT_HEADER, MSGL_V, "read_asf_header found dvr-ms audio stream header pos=%d\n", sh_pos);
            // found audio stream header - following code reads header and
            // initializes audio stream.
            audio_pos = pos - 16 - 8;
            streamh = (ASF_stream_header_t *)&hdr[sh_pos];
            le2me_ASF_stream_header_t(streamh);
            audio_pos += 64; //16+16+4+4+4+16+4;
            buffer = &hdr[audio_pos];
            sh_audio=new_sh_audio(demuxer,streamh->stream_no & 0x7F);
            sh_audio->needs_parsing = 1;
            mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Audio stream found, -aid %d\n", "asfheader", streamh->stream_no & 0x7F);
            ++audio_streams;
            if (!asf_init_audio_stream(demuxer, asf, sh_audio, streamh, &audio_pos, &buffer, hdr, hdr_len))
                goto len_err_out;
            if (!get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, asf, 0))
                goto len_err_out;
        }
    }
    // find stream headers
    // only reset pos if we didnt find dvr_ms audio stream
    // if we did find it then we want to avoid reading its header twice
    if (audio_pos == 0)
        pos = 0;

    while ((pos = find_asf_guid(hdr, asf_stream_header_guid, pos, hdr_len)) >= 0)
    {
        streamh = (ASF_stream_header_t *)&hdr[pos];
        pos += sizeof(ASF_stream_header_t);
        if (pos > hdr_len) goto len_err_out;
        le2me_ASF_stream_header_t(streamh);
        mp_msg(MSGT_HEADER, MSGL_V, "stream type: %s\n",
               asf_chunk_type(streamh->type));
        mp_msg(MSGT_HEADER, MSGL_V, "stream concealment: %s\n",
               asf_chunk_type(streamh->concealment));
        mp_msg(MSGT_HEADER, MSGL_V, "type: %d bytes,  stream: %d bytes  ID: %d\n",
               (int)streamh->type_size, (int)streamh->stream_size,
               (int)streamh->stream_no);
        mp_msg(MSGT_HEADER, MSGL_V, "unk1: %lX  unk2: %X\n",
               (unsigned long)streamh->unk1, (unsigned int)streamh->unk2);
        mp_msg(MSGT_HEADER, MSGL_V, "FILEPOS=0x%X\n", pos + start);
        // type-specific data:
        buffer = &hdr[pos];
        pos += streamh->type_size;
        if (pos > hdr_len) goto len_err_out;
        switch(ASF_LOAD_GUID_PREFIX(streamh->type)) {
        case ASF_GUID_PREFIX_audio_stream: {
            sh_audio_t* sh_audio=new_sh_audio(demuxer,streamh->stream_no & 0x7F);
            mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Audio stream found, -aid %d\n", "asfheader", streamh->stream_no & 0x7F);
            ++audio_streams;
            if (!asf_init_audio_stream(demuxer, asf, sh_audio, streamh, &pos, &buffer, hdr, hdr_len))
                goto len_err_out;
            //if(demuxer->audio->id==-1) demuxer->audio->id=streamh.stream_no & 0x7F;
            break;
        }
        case ASF_GUID_PREFIX_video_stream: {
            unsigned int len;
            float asp_ratio;
            sh_video_t* sh_video=new_sh_video(demuxer,streamh->stream_no & 0x7F);
            mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Video stream found, -vid %d\n", "asfheader", streamh->stream_no & 0x7F);
            len=streamh->type_size-(4+4+1+2);
            ++video_streams;
//        sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize);
            sh_video->bih=calloc((len<sizeof(BITMAPINFOHEADER))?sizeof(BITMAPINFOHEADER):len,1);
            memcpy(sh_video->bih,&buffer[4+4+1+2],len);
            le2me_BITMAPINFOHEADER(sh_video->bih);
            if (sh_video->bih->biSize > len && sh_video->bih->biSize > sizeof(BITMAPINFOHEADER))
                sh_video->bih->biSize = len;
            if (sh_video->bih->biCompression == mmioFOURCC('D', 'V', 'R', ' ')) {
                //mp_tmsg(MSGT_DEMUXER, MSGL_WARN, "DVR will probably only work with libavformat, try -demuxer 35 if you have problems\n");
                //sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale;
                //sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
                asf->asf_frame_state=-1;
                asf->asf_frame_start_found=0;
                asf->asf_is_dvr_ms=1;
                asf->dvr_last_vid_pts=0.0;
            } else asf->asf_is_dvr_ms=0;
            if (!get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, asf, 1))
                goto len_err_out;
            if (get_meta(hdr, hdr_len, streamh->stream_no, &asp_ratio)) {
                sh_video->aspect = asp_ratio * sh_video->bih->biWidth /
                                   sh_video->bih->biHeight;
            }
            sh_video->i_bps = asf->bps;

            if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
            //asf_video_id=streamh.stream_no & 0x7F;
            //if(demuxer->video->id==-1) demuxer->video->id=streamh.stream_no & 0x7F;
            break;
        }
        }
        // stream-specific data:
        // stream_read(demuxer->stream,(char*) buffer,streamh.stream_size);
    }

    // find file header
    pos = find_asf_guid(hdr, asf_file_header_guid, 0, hdr_len);
    if (pos >= 0) {
        ASF_file_header_t *fileh = (ASF_file_header_t *)&hdr[pos];
        pos += sizeof(ASF_file_header_t);
        if (pos > hdr_len) goto len_err_out;
        le2me_ASF_file_header_t(fileh);
        mp_msg(MSGT_HEADER, MSGL_V, "ASF: packets: %d  flags: %d  "
               "max_packet_size: %d  min_packet_size: %d  max_bitrate: %d  "
               "preroll: %d\n",
               (int)fileh->num_packets, (int)fileh->flags,
               (int)fileh->min_packet_size, (int)fileh->max_packet_size,
               (int)fileh->max_bitrate, (int)fileh->preroll);
        asf->packetsize=fileh->max_packet_size;
        asf->packet=malloc(asf->packetsize); // !!!
        asf->packetrate=fileh->max_bitrate/8.0/(double)asf->packetsize;
        asf->movielength=(fileh->play_duration-10000*fileh->preroll)/10000000.0;
    }

    // find content header
    pos = find_asf_guid(hdr, asf_content_desc_guid, 0, hdr_len);
    if (pos >= 0) {
        ASF_content_description_t *contenth = (ASF_content_description_t *)&hdr[pos];
        char *string=NULL;
        uint16_t* wstring = NULL;
        uint16_t len;
        pos += sizeof(ASF_content_description_t);
        if (pos > hdr_len) goto len_err_out;
        le2me_ASF_content_description_t(contenth);
        mp_msg(MSGT_HEADER,MSGL_V,"\n");
        // extract the title
        if((len = contenth->title_size) != 0) {
            wstring = (uint16_t*)&hdr[pos];
            pos += len;
            if (pos > hdr_len) goto len_err_out;
            if ((string = get_ucs2str(wstring, len))) {
                mp_msg(MSGT_HEADER,MSGL_V," Title: %s\n", string);
                demux_info_add(demuxer, "title", string);
                free(string);
            }
        }
        // extract the author
        if((len = contenth->author_size) != 0) {
            wstring = (uint16_t*)&hdr[pos];
            pos += len;
            if (pos > hdr_len) goto len_err_out;
            if ((string = get_ucs2str(wstring, len))) {
                mp_msg(MSGT_HEADER,MSGL_V," Author: %s\n", string);
                demux_info_add(demuxer, "author", string);
                free(string);
            }
        }
        // extract the copyright
        if((len = contenth->copyright_size) != 0) {
            wstring = (uint16_t*)&hdr[pos];
            pos += len;
            if (pos > hdr_len) goto len_err_out;
            if ((string = get_ucs2str(wstring, len))) {
                mp_msg(MSGT_HEADER,MSGL_V," Copyright: %s\n", string);
                demux_info_add(demuxer, "copyright", string);
                free(string);
            }
        }
        // extract the comment
        if((len = contenth->comment_size) != 0) {
            wstring = (uint16_t*)&hdr[pos];
            pos += len;
            if (pos > hdr_len) goto len_err_out;
            if ((string = get_ucs2str(wstring, len))) {
                mp_msg(MSGT_HEADER,MSGL_V," Comment: %s\n", string);
                demux_info_add(demuxer, "comments", string);
                free(string);
            }
        }
        // extract the rating
        if((len = contenth->rating_size) != 0) {
            wstring = (uint16_t*)&hdr[pos];
            pos += len;
            if (pos > hdr_len) goto len_err_out;
            if ((string = get_ucs2str(wstring, len))) {
                mp_msg(MSGT_HEADER,MSGL_V," Rating: %s\n", string);
                free(string);
            }
        }
        mp_msg(MSGT_HEADER,MSGL_V,"\n");
    }

    // find content header
    pos = find_asf_guid(hdr, asf_stream_group_guid, 0, hdr_len);
    if (pos >= 0) {
        int max_streams = (hdr_len - pos - 2) / 6;
        uint16_t stream_id, i;
        uint32_t max_bitrate;
        char *ptr = &hdr[pos];
        mp_msg(MSGT_HEADER,MSGL_V,"============ ASF Stream group == START ===\n");
        if(max_streams <= 0) goto len_err_out;
        stream_count = AV_RL16(ptr);
        ptr += sizeof(uint16_t);
        if(stream_count > max_streams) stream_count = max_streams;
        if(stream_count > 0)
            streams = malloc(2*stream_count*sizeof(uint32_t));
        mp_msg(MSGT_HEADER,MSGL_V," stream count=[0x%x][%u]\n", stream_count, stream_count );
        for( i=0 ; i<stream_count ; i++ ) {
            stream_id = AV_RL16(ptr);
            ptr += sizeof(uint16_t);
            memcpy(&max_bitrate, ptr, sizeof(uint32_t));// workaround unaligment bug on sparc
            max_bitrate = le2me_32(max_bitrate);
            ptr += sizeof(uint32_t);
            mp_msg(MSGT_HEADER,MSGL_V,"   stream id=[0x%x][%u]\n", stream_id, stream_id );
            mp_msg(MSGT_HEADER,MSGL_V,"   max bitrate=[0x%x][%u]\n", max_bitrate, max_bitrate );
            streams[2*i] = stream_id;
            streams[2*i+1] = max_bitrate;
        }
        mp_msg(MSGT_HEADER,MSGL_V,"============ ASF Stream group == END ===\n");
    }
    free(hdr);
    hdr = NULL;
    start = stream_tell(demuxer->stream); // start of first data chunk
    stream_read(demuxer->stream, guid_buffer, 16);
    if (memcmp(guid_buffer, asf_data_chunk_guid, 16) != 0) {
        mp_tmsg(MSGT_HEADER, MSGL_FATAL, "No data chunk following header!\n");
        free(streams);
        streams = NULL;
        return 0;
    }
    // read length of chunk
    stream_read(demuxer->stream, (char *)&data_len, sizeof(data_len));
    data_len = le2me_64(data_len);
    demuxer->movi_start = stream_tell(demuxer->stream) + 26;
    demuxer->movi_end = start + data_len;
    mp_msg(MSGT_HEADER, MSGL_V, "Found movie at 0x%X - 0x%X\n",
           (int)demuxer->movi_start, (int)demuxer->movi_end);

    if(streams) {
        // stream selection is done in the network code, it shouldn't be done here
        // as the servers often do not care about what we requested.
#if 0
        uint32_t vr = 0, ar = 0,i;
#ifdef CONFIG_NETWORK
        if( demuxer->stream->streaming_ctrl!=NULL ) {
            if( demuxer->stream->streaming_ctrl->bandwidth!=0 && demuxer->stream->streaming_ctrl->data!=NULL ) {
                best_audio = ((asf_http_streaming_ctrl_t*)demuxer->stream->streaming_ctrl->data)->audio_id;
                best_video = ((asf_http_streaming_ctrl_t*)demuxer->stream->streaming_ctrl->data)->video_id;
            }
        } else
#endif
            for(i = 0; i < stream_count; i++) {
                uint32_t id = streams[2*i];
                uint32_t rate = streams[2*i+1];
                if(demuxer->v_streams[id] && rate > vr) {
                    vr = rate;
                    best_video = id;
                } else if(demuxer->a_streams[id] && rate > ar) {
                    ar = rate;
                    best_audio = id;
                }
            }
#endif
        free(streams);
        streams = NULL;
    }

    mp_msg(MSGT_HEADER,MSGL_V,"ASF: %d audio and %d video streams found\n",audio_streams,video_streams);
    if(!audio_streams) demuxer->audio->id=-2;  // nosound
    else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;
    if(!video_streams) {
        if(!audio_streams) {
            mp_tmsg(MSGT_HEADER,MSGL_ERR,"ASF: no audio or video headers found - broken file?\n");
            return 0;
        }
        demuxer->video->id=-2; // audio-only
    } else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;

#if 0
    if( mp_msg_test(MSGT_HEADER,MSGL_V) ) {
        printf("ASF duration: %d\n",(int)fileh.duration);
        printf("ASF start pts: %d\n",(int)fileh.start_timestamp);
        printf("ASF end pts: %d\n",(int)fileh.end_timestamp);
    }
#endif

    return 1;

len_err_out:
    mp_tmsg(MSGT_HEADER, MSGL_FATAL, "Invalid length in ASF header!\n");
err_out:
    if (hdr) free(hdr);
    if (streams) free(streams);
    return 0;
}
// return value:
//     0 = EOF or no stream found
//     1 = successfully read a packet
static int demux_vivo_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
  demux_stream_t *ds=NULL;
  int c;
  int len=0;
  int seq;
  int prefix=0;
  demux->filepos=stream_tell(demux->stream);

  c=stream_read_char(demux->stream);
  if (c == -256) /* EOF */
    return 0;
//  printf("c=%x,%02X\n",c,c&0xf0);
  if (c == 0x82)
  {
      /* ok, this works, but pts calculating from header is required! */
      /* FIXME: "Calculate PTS from picture header!" */
      prefix = 1;
      c = stream_read_char(demux->stream);
      mp_msg(MSGT_DEMUX, MSGL_V, "packet 0x82(pos=%u) chunk=%x\n",
        (int)stream_tell(demux->stream), c);
  }
  switch(c&0xF0){
  case 0x00: // header - skip it!
  {
      len=stream_read_char(demux->stream);
      if(len>=0x80) len=0x80*(len-0x80)+stream_read_char(demux->stream);
      mp_msg(MSGT_DEMUX, MSGL_V, "vivo extra header: %d bytes\n",len);
#ifdef TEXTPARSE_ALL
{
      int pos;
      /* also try to parse all headers */
      pos = stream_tell(demux->stream);
      vivo_parse_text_header(demux, len);
      stream_seek(demux->stream, pos);
}
#endif
      break;
  }
  case 0x10:  // video packet
      if (prefix == 1)
        len = stream_read_char(demux->stream);
      else
        len=128;
      ds=demux->video;
      break;
  case 0x20:  // video packet
      len=stream_read_char(demux->stream);
      ds=demux->video;
      break;
  case 0x30:  // audio packet
      if (prefix == 1)
        len = stream_read_char(demux->stream);
      else
        len=40;	/* 40kbps */
      ds=demux->audio;
      audio_pos+=len;
      break;
  case 0x40:  // audio packet
      if (prefix == 1)
        len = stream_read_char(demux->stream);
      else
        len=24;	/* 24kbps */
      ds=demux->audio;
      audio_pos+=len;
      break;
  default:
      mp_msg(MSGT_DEMUX,MSGL_WARN,"VIVO - unknown ID found: %02X at pos %"PRIu64" contact author!\n",
        c, (int64_t)stream_tell(demux->stream));
      return 0;
  }

//  printf("chunk=%x, len=%d\n", c, len);

  if(!ds || ds->id<-1){
      if(len) stream_skip(demux->stream,len);
      return 1;
  }

  seq=c&0x0F;

    if(ds->asf_packet){
      if(ds->asf_seq!=seq){
        // closed segment, finalize packet:
        ds_add_packet(ds,ds->asf_packet);
        ds->asf_packet=NULL;
//	printf("packet!\n");
      } else {
        // append data to it!
        demux_packet_t* dp=ds->asf_packet;
        if(dp->len + len + MP_INPUT_BUFFER_PADDING_SIZE < 0)
	    return 0;
        dp->buffer=realloc(dp->buffer,dp->len+len+MP_INPUT_BUFFER_PADDING_SIZE);
        memset(dp->buffer+dp->len+len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
        //memcpy(dp->buffer+dp->len,data,len);
	stream_read(demux->stream,dp->buffer+dp->len,len);
        mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len);
        dp->len+=len;
        // we are ready now.
	if((c&0xF0)==0x20) --ds->asf_seq; // hack!
        return 1;
      }
    }
    // create new packet:
    { demux_packet_t* dp;
      dp=new_demux_packet(len);
      //memcpy(dp->buffer,data,len);
      stream_read(demux->stream,dp->buffer,len);
      dp->pts=audio_rate?((float)audio_pos/(float)audio_rate):0;
//      dp->flags=keyframe;
//      if(ds==demux->video) printf("ASF time: %8d  dur: %5d  \n",time,dur);
      dp->pos=demux->filepos;
      ds->asf_packet=dp;
      ds->asf_seq=seq;
      // we are ready now.
      return 1;
    }

}
Ejemplo n.º 24
0
static imgtoolerr_t macbinary_writefile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, util::option_resolution *opts)
{
	static const UINT32 attrs[] =
	{
		IMGTOOLATTR_TIME_CREATED,
		IMGTOOLATTR_TIME_LASTMODIFIED,
		IMGTOOLATTR_INT_MAC_TYPE,
		IMGTOOLATTR_INT_MAC_CREATOR,
		IMGTOOLATTR_INT_MAC_FINDERFLAGS,
		IMGTOOLATTR_INT_MAC_COORDX,
		IMGTOOLATTR_INT_MAC_COORDY,
		IMGTOOLATTR_INT_MAC_FINDERFOLDER,
		IMGTOOLATTR_INT_MAC_SCRIPTCODE,
		IMGTOOLATTR_INT_MAC_EXTENDEDFLAGS,
		0
	};
	imgtoolerr_t err;
	imgtool_image *image = imgtool_partition_image(partition);
	UINT8 header[128];
	UINT32 datafork_size;
	UINT32 resourcefork_size;
	UINT64 total_size;
	UINT32 creation_time;
	UINT32 lastmodified_time;
	//int version;
	imgtool_attribute attr_values[10];

	UINT32 type_code;
	UINT32 creator_code;
	UINT16 finder_flags;
	UINT16 coord_x;
	UINT16 coord_y;
	UINT16 finder_folder;
	UINT8 script_code = 0;
	UINT8 extended_flags = 0;

	/* read in the header */
	memset(header, 0, sizeof(header));
	stream_read(sourcef, header, sizeof(header));

	/* check magic and zero fill bytes */
	if (header[0] != 0x00)
		return IMGTOOLERR_CORRUPTFILE;
	if (header[74] != 0x00)
		return IMGTOOLERR_CORRUPTFILE;
	if (header[82] != 0x00)
		return IMGTOOLERR_CORRUPTFILE;

	datafork_size = pick_integer_be(header, 83, 4);
	resourcefork_size = pick_integer_be(header, 87, 4);
	total_size = stream_size(sourcef);

	/* size of a MacBinary header is always 128 bytes */
	if (total_size - pad128(datafork_size) - pad128(resourcefork_size) != 128)
		return IMGTOOLERR_CORRUPTFILE;

	/* check filename length byte */
	if ((header[1] <= 0x00) || (header[1] > 0x3F))
		return IMGTOOLERR_CORRUPTFILE;

	/* check the CRC */
	if (pick_integer_be(header, 124, 2) != ccitt_crc16(0, header, 124))
	{
		/* the CRC does not match; this file is MacBinary I */
		//version = 1;
	}
	else if (pick_integer_be(header, 102, 4) != 0x6D42494E)
	{
		/* did not see 'mBIN'; this file is MacBinary II */
		if (header[122] < 0x81)
			return IMGTOOLERR_CORRUPTFILE;
		if (header[123] < 0x81)
			return IMGTOOLERR_CORRUPTFILE;
		//version = 2;
	}
	else
	{
		/* we did see 'mBIN'; this file is MacBinary III */
		if (header[122] < 0x82)
			return IMGTOOLERR_CORRUPTFILE;
		if (header[123] < 0x81)
			return IMGTOOLERR_CORRUPTFILE;
		//version = 3;
	}

	type_code         = pick_integer_be(header, 65, 4);
	creator_code      = pick_integer_be(header, 69, 4);
	finder_flags      = pick_integer_be(header, 73, 1) << 8;
	coord_x           = pick_integer_be(header, 75, 2);
	coord_y           = pick_integer_be(header, 77, 2);
	finder_folder     = pick_integer_be(header, 79, 2);
	creation_time     = pick_integer_be(header, 91, 4);
	lastmodified_time = pick_integer_be(header, 95, 4);

	if (image)
	{
		/* write out both forks */
		err = write_fork(partition, filename, "", sourcef, sizeof(header), datafork_size, opts);
		if (err)
			return err;
		err = write_fork(partition, filename, "RESOURCE_FORK", sourcef, sizeof(header) + pad128(datafork_size), resourcefork_size, opts);
		if (err)
			return err;

		/* set up attributes */
		attr_values[0].t = mac_crack_time(creation_time);
		attr_values[1].t = mac_crack_time(lastmodified_time);
		attr_values[2].i = type_code;
		attr_values[3].i = creator_code;
		attr_values[4].i = finder_flags;
		attr_values[5].i = coord_x;
		attr_values[6].i = coord_y;
		attr_values[7].i = finder_folder;
		attr_values[8].i = script_code;
		attr_values[9].i = extended_flags;

		err = imgtool_partition_put_file_attributes(partition, filename, attrs, attr_values);
		if (err)
			return err;
	}

	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 25
0
static imgtoolerr_t vzdos_writefile(imgtool_partition *partition, int offset, imgtool_stream *sourcef, vzdos_dirent *entry)
{
	imgtoolerr_t ret;
	imgtool_image *img = imgtool_partition_image(partition);
	int index, track, sector, toread, next_track, next_sector;
	vzdos_dirent temp_entry;
	UINT64 filesize = 0, freespace = 0;
	UINT8 buffer[DATA_SIZE + 2];
	char filename[9];

	/* is the image writeable? */
	if (floppy_is_read_only(imgtool_floppy(img)))
		return IMGTOOLERR_READONLY;

	/* check for already existing filename -> overwrite */
	strcpy(filename, entry->fname);
	filename[vzdos_get_fname_len(entry->fname) + 1] = 0x00;
	ret = vzdos_get_dirent_fname(img, filename, &temp_entry);
	if (!ret) {
		/* file already exists, delete it */
		ret = vzdos_diskimage_deletefile(partition, filename);
		if (ret) return ret;
	} else if (ret != IMGTOOLERR_FILENOTFOUND) {
		/* another error occurred, return it */
		return ret;
	}

	ret = (imgtoolerr_t)stream_seek(sourcef, offset, SEEK_SET);
	if (ret) return ret;

	/* check if there is enough space */
	filesize = stream_size(sourcef) - offset;

	ret = vzdos_diskimage_freespace(partition, &freespace);
	if (ret) return ret;

	if (filesize > freespace)
		return IMGTOOLERR_NOSPACE;

	/* get next free track and sector */
	ret = vzdos_free_trackmap(img, &track, &sector);
	if (ret) return ret;

	entry->end_address = entry->start_address + (unsigned int) filesize;
	entry->start_track   = track;
	entry->start_sector  = sector;

	/* search for next free directory entry */
	for (index = 0; index < MAX_DIRENTS; index++) {
		ret = vzdos_get_dirent(img, index, &temp_entry);
		if (ret == IMGTOOLERR_FILENOTFOUND)
			break;
		else if (ret)
			return (ret);
	}

	/* write directory entry to disk */
	ret = vzdos_set_dirent(img, index, *entry);
	if (ret) return ret;

	next_track  = 0;
	next_sector = 0;

	/* write data to disk */
	while (filesize > 0) {
		toread = filesize > DATA_SIZE ? DATA_SIZE : filesize;
		stream_read(sourcef, buffer, toread);

		filesize -= toread;

		/* mark sector as used */
		ret = vzdos_set_trackmap(img, track, sector);
		if (ret) return ret;

		/* get track and sector for next sector */
		if (filesize > 0) {
			ret = vzdos_free_trackmap(img, &next_track, &next_sector);
			if (ret) return ret;
		} else {
			next_track = 0;
			next_sector = 0;
		}
		buffer[DATA_SIZE]     = next_track;
		buffer[DATA_SIZE + 1] = next_sector;

		/* write sector to disk */
		ret = vzdos_write_sector_data(img, track, sector, buffer);
		if (ret) return ret;

		track  = next_track;
		sector = next_sector;
	}

	return IMGTOOLERR_SUCCESS;

}
Ejemplo n.º 26
0
BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, STREAM* s)
{
	UINT16 flags;
	UINT16 length;
	rdpRedirection* redirection = rdp->redirection;

	stream_read_UINT16(s, flags); /* flags (2 bytes) */
	stream_read_UINT16(s, length); /* length (2 bytes) */
	stream_read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */
	stream_read_UINT32(s, redirection->flags); /* redirFlags (4 bytes) */

	DEBUG_REDIR("flags: 0x%04X, length:%d, sessionID:0x%08X", flags, length, redirection->sessionID);

#ifdef WITH_DEBUG_REDIR
	rdp_print_redirection_flags(redirection->flags);
#endif

	if (redirection->flags & LB_TARGET_NET_ADDRESS)
	{
		freerdp_string_read_length32(s, &redirection->targetNetAddress);
		DEBUG_REDIR("targetNetAddress: %s", redirection->targetNetAddress.ascii);
	}

	if (redirection->flags & LB_LOAD_BALANCE_INFO)
	{
		stream_read_UINT32(s, redirection->LoadBalanceInfoLength);
		redirection->LoadBalanceInfo = (BYTE*) malloc(redirection->LoadBalanceInfoLength);
		stream_read(s, redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength);
#ifdef WITH_DEBUG_REDIR
		DEBUG_REDIR("loadBalanceInfo:");
		freerdp_hexdump(redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength);
#endif
	}

	if (redirection->flags & LB_USERNAME)
	{
		freerdp_string_read_length32(s, &redirection->username);
		DEBUG_REDIR("username: %s", redirection->username.ascii);
	}

	if (redirection->flags & LB_DOMAIN)
	{
		freerdp_string_read_length32(s, &redirection->domain);
		DEBUG_REDIR("domain: %s", redirection->domain.ascii);
	}

	if (redirection->flags & LB_PASSWORD)
	{
		/* Note: length (hopefully) includes double zero termination */
		stream_read_UINT32(s, redirection->PasswordCookieLength);
		redirection->PasswordCookie = (BYTE*) malloc(redirection->PasswordCookieLength);
		stream_read(s, redirection->PasswordCookie, redirection->PasswordCookieLength);

#ifdef WITH_DEBUG_REDIR
		DEBUG_REDIR("password_cookie:");
		freerdp_hexdump(redirection->PasswordCookie, redirection->PasswordCookieLength);
#endif
	}

	if (redirection->flags & LB_TARGET_FQDN)
	{
		freerdp_string_read_length32(s, &redirection->targetFQDN);
		DEBUG_REDIR("targetFQDN: %s", redirection->targetFQDN.ascii);
	}

	if (redirection->flags & LB_TARGET_NETBIOS_NAME)
	{
		freerdp_string_read_length32(s, &redirection->targetNetBiosName);
		DEBUG_REDIR("targetNetBiosName: %s", redirection->targetNetBiosName.ascii);
	}

	if (redirection->flags & LB_CLIENT_TSV_URL)
	{
		freerdp_string_read_length32(s, &redirection->tsvUrl);
		DEBUG_REDIR("tsvUrl: %s", redirection->tsvUrl.ascii);
	}

	if (redirection->flags & LB_TARGET_NET_ADDRESSES)
	{
		int i;
		UINT32 count;
		UINT32 targetNetAddressesLength;

		stream_read_UINT32(s, targetNetAddressesLength);

		stream_read_UINT32(s, redirection->targetNetAddressesCount);
		count = redirection->targetNetAddressesCount;

		redirection->targetNetAddresses = (rdpString*) xzalloc(count * sizeof(rdpString));

		for (i = 0; i < (int) count; i++)
		{
			freerdp_string_read_length32(s, &redirection->targetNetAddresses[i]);
			DEBUG_REDIR("targetNetAddresses: %s", (&redirection->targetNetAddresses[i])->ascii);
		}
	}

	stream_seek(s, 8); /* pad (8 bytes) */

	if (redirection->flags & LB_NOREDIRECT)
		return TRUE;
	else
		return rdp_client_redirect(rdp);
}
Ejemplo n.º 27
0
static boolean rdp_server_establish_keys(rdpRdp* rdp, STREAM* s)
{
	uint8 client_random[64]; /* Should be only 32 after successfull decryption, but on failure might take up to 64 bytes. */
	uint8 crypt_client_random[256 + 8];
	uint32 rand_len, key_len;
	uint16 channel_id, length, sec_flags;
	uint8* mod;
	uint8* priv_exp;

	if (rdp->settings->encryption == false)
	{
		/* No RDP Security. */
		return true;
	}

	if (!rdp_read_header(rdp, s, &length, &channel_id))
	{
		freerdp_log(rdp->instance, "rdp_server_establish_keys: invalid RDP header\n");
		return false;
	}
	rdp_read_security_header(s, &sec_flags);
	if ((sec_flags & SEC_EXCHANGE_PKT) == 0)
	{
		freerdp_log(rdp->instance, "rdp_server_establish_keys: missing SEC_EXCHANGE_PKT in security header\n");
		return false;
	}
	stream_read_uint32(s, rand_len);
	key_len = rdp->settings->server_key->modulus.length;
	if (rand_len != key_len + 8)
	{
		freerdp_log(rdp->instance, "rdp_server_establish_keys: invalid encrypted client random length\n");
		return false;
	}
	memset(crypt_client_random, 0, sizeof(crypt_client_random));
	stream_read(s, crypt_client_random, rand_len);
	/* 8 zero bytes of padding */
	stream_seek(s, 8);
	mod = rdp->settings->server_key->modulus.data;
	priv_exp = rdp->settings->server_key->private_exponent.data;
	crypto_rsa_private_decrypt(crypt_client_random, rand_len - 8, key_len, mod, priv_exp, client_random);

	/* now calculate encrypt / decrypt and update keys */
	if (!security_establish_keys(client_random, rdp))
	{
		return false;
	}

	rdp->do_crypt = true;
	if (rdp->settings->salted_checksum)
		rdp->do_secure_checksum = true;

	if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
	{
		uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
		rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
		rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);

		rdp->fips_hmac = crypto_hmac_new();
		return true;
	}

	rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
	rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);

	return true;
}
Ejemplo n.º 28
0
static int lavf_check_file(demuxer_t *demuxer){
    AVProbeData avpd = { 0 };
    lavf_priv_t *priv;
    int probe_data_size = 0;
    int read_size = is_rar_stream?2048:INITIAL_PROBE_SIZE;
    int score;

    if(!demuxer->priv)
        demuxer->priv=calloc(sizeof(lavf_priv_t),1);
    priv= demuxer->priv;

    init_avformat();

    if (opt_format) {
        if (strcmp(opt_format, "help") == 0) {
           list_formats();
           return 0;
        }
        priv->avif= av_find_input_format(opt_format);
        if (!priv->avif) {
            mp_msg(MSGT_DEMUX,MSGL_FATAL,"Unknown lavf format %s\n", opt_format);
            return 0;
        }
        mp_msg(MSGT_DEMUX,MSGL_INFO,"Forced lavf %s demuxer\n", priv->avif->long_name);
        return DEMUXER_TYPE_LAVF;
    }

    avpd.buf = av_mallocz(FFMAX(BIO_BUFFER_SIZE, PROBE_BUF_SIZE) +
                          FF_INPUT_BUFFER_PADDING_SIZE);
    do {
        read_size = stream_read(demuxer->stream, avpd.buf + probe_data_size, read_size);
        if(read_size < 0) {
            av_free(avpd.buf);
            return 0;
        }
        probe_data_size += read_size;
        avpd.filename= demuxer->stream->url;
        if (!avpd.filename) {
            mp_msg(MSGT_DEMUX, MSGL_WARN, "Stream url is not set!\n");
            avpd.filename = "";
        }
        if (!strncmp(avpd.filename, "ffmpeg://", 9))
            avpd.filename += 9;
        avpd.buf_size= probe_data_size;

        score = 0;
        priv->avif= av_probe_input_format2(&avpd, probe_data_size > 0, &score);
        read_size = FFMIN(2*read_size, PROBE_BUF_SIZE - probe_data_size);
    } while ((demuxer->desc->type != DEMUXER_TYPE_LAVF_PREFERRED ||
              probe_data_size < SMALL_MAX_PROBE_SIZE) &&
             score <= AVPROBE_SCORE_MAX / 4 &&
             read_size > 0 && probe_data_size < PROBE_BUF_SIZE);
    av_free(avpd.buf);

    if(!priv->avif){
        mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: no clue about this gibberish!\n");
        return 0;
    }else{
		if(is_rar_stream && !strcmp("matroska,webm", priv->avif->name))
			return 0;
        mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: %s\n", priv->avif->long_name);
	}

    return DEMUXER_TYPE_LAVF;
}
Ejemplo n.º 29
0
boolean rdp_recv_server_redirection_pdu(rdpRdp* rdp, STREAM* s)
{
	uint16 flags;
	uint16 length;
	rdpRedirection* redirection = rdp->redirection;

	stream_read_uint16(s, flags); /* flags (2 bytes) */
	stream_read_uint16(s, length); /* length (2 bytes) */
	stream_read_uint32(s, redirection->sessionID); /* sessionID (4 bytes) */
	stream_read_uint32(s, redirection->flags); /* redirFlags (4 bytes) */

	DEBUG_REDIR("flags: 0x%04X, length:%d, sessionID:0x%08X", flags, length, redirection->sessionID);

#ifdef WITH_DEBUG_REDIR
	rdp_print_redirection_flags(redirection->flags);
#endif

	if (redirection->flags & LB_TARGET_NET_ADDRESS)
	{
		freerdp_string_read_length32(s, &redirection->targetNetAddress, rdp->settings->uniconv);
		DEBUG_REDIR("targetNetAddress: %s", redirection->targetNetAddress.ascii);
	}

	if (redirection->flags & LB_LOAD_BALANCE_INFO)
	{
		uint32 loadBalanceInfoLength;
		stream_read_uint32(s, loadBalanceInfoLength);
		freerdp_blob_alloc(&redirection->loadBalanceInfo, loadBalanceInfoLength);
		stream_read(s, redirection->loadBalanceInfo.data, loadBalanceInfoLength);
#ifdef WITH_DEBUG_REDIR
		DEBUG_REDIR("loadBalanceInfo:");
		freerdp_hexdump(redirection->loadBalanceInfo.data, redirection->loadBalanceInfo.length);
#endif
	}

	if (redirection->flags & LB_USERNAME)
	{
		freerdp_string_read_length32(s, &redirection->username, rdp->settings->uniconv);
		DEBUG_REDIR("username: %s", redirection->username.ascii);
	}

	if (redirection->flags & LB_DOMAIN)
	{
		freerdp_string_read_length32(s, &redirection->domain, rdp->settings->uniconv);
		DEBUG_REDIR("domain: %s", redirection->domain.ascii);
	}

	if (redirection->flags & LB_PASSWORD)
	{
		freerdp_string_read_length32(s, &redirection->password, rdp->settings->uniconv);
		DEBUG_REDIR("password: %s", redirection->password.ascii);
	}

	if (redirection->flags & LB_TARGET_FQDN)
	{
		freerdp_string_read_length32(s, &redirection->targetFQDN, rdp->settings->uniconv);
		DEBUG_REDIR("targetFQDN: %s", redirection->targetFQDN.ascii);
	}

	if (redirection->flags & LB_TARGET_NETBIOS_NAME)
	{
		freerdp_string_read_length32(s, &redirection->targetNetBiosName, rdp->settings->uniconv);
		DEBUG_REDIR("targetNetBiosName: %s", redirection->targetNetBiosName.ascii);
	}

	if (redirection->flags & LB_CLIENT_TSV_URL)
	{
		freerdp_string_read_length32(s, &redirection->tsvUrl, rdp->settings->uniconv);
		DEBUG_REDIR("tsvUrl: %s", redirection->tsvUrl.ascii);
	}

	if (redirection->flags & LB_TARGET_NET_ADDRESSES)
	{
		uint32 count;
		uint32 targetNetAddressesLength;

		stream_read_uint32(s, targetNetAddressesLength);

		stream_read_uint32(s, redirection->targetNetAddressesCount);
		count = redirection->targetNetAddressesCount;

		redirection->targetNetAddresses = (rdpString*) xzalloc(count * sizeof(rdpString));

		while (count > 0)
		{
			freerdp_string_read_length32(s, redirection->targetNetAddresses, rdp->settings->uniconv);
			DEBUG_REDIR("targetNetAddresses: %s", redirection->targetNetAddresses->ascii);
			redirection->targetNetAddresses++;
			count--;
		}
	}

	stream_seek(s, 8); /* pad (8 bytes) */

	if (redirection->flags & LB_NOREDIRECT)
		return True;
	else
		return rdp_client_redirect(rdp);
}
Ejemplo n.º 30
0
static vsf_err_t
vsfip_telnetd_session_tx_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
	struct vsfip_telnetd_session_t *session =
								(struct vsfip_telnetd_session_t *)pt->user_data;
	uint32_t len;
	vsf_err_t err;

	vsfsm_pt_begin(pt);

	session->caller_txpt.sm = pt->sm;
	while (!session->disconnect)
	{
		len = stream_get_data_size(session->stream_tx);
		if (!len && vsfsm_sem_pend(&session->stream_tx_sem, pt->sm))
		{
			vsfsm_pt_wfe(pt, VSFIP_TELNETD_EVT_STREAM_IN);
			if (session->disconnect)
				break;
			continue;
		}

	retry_alloc_buf:
		session->outbuf = VSFIP_TCPBUF_GET(len);
		if (NULL == session->outbuf)
		{
			vsfsm_pt_delay(pt, 5);
			if (session->disconnect)
				break;
			goto retry_alloc_buf;
		}

		session->outbuf->app.size =
					stream_read(session->stream_tx, &session->outbuf->app);
		if (!session->outbuf->app.size)
		{
			vsfip_buffer_release(session->outbuf);
			continue;
		}

		session->caller_txpt.state = 0;
		vsfsm_pt_entry(pt);
		err = vsfip_tcp_send(&session->caller_txpt, evt, session->so,
						session->outbuf, false);
		if (err > 0) return err; else if (err < 0)
		{
			session->disconnect = true;
		}
	}

	// close tcp socket
	session->caller_txpt.state = 0;
	vsfsm_pt_entry(pt);
	err = vsfip_tcp_close(&session->caller_txpt, evt, session->so);
	if (err > 0) return err;

	// close socket no matter if tcp closed OK or not
	vsfip_close(session->so);
	session->connected = false;

	vsfsm_pt_end(pt);
	return VSFERR_NONE;
}