📄 stream.c
字号:
var_SetString( p_input, "subsdec-encoding", "UTF-8" ); vlc_object_release( p_input ); } free( psz_encoding ); } } if( i_data % s->i_char_width ) { /* keep i_char_width boundary */ i_data = i_data - ( i_data % s->i_char_width ); msg_Warn( s, "the read is not i_char_width compatible"); } if( i_data == 0 ) break; /* Check if there is an EOL */ if( s->i_char_width == 1 ) { /* UTF-8: 0A <LF> */ psz_eol = memchr( p_data, '\n', i_data ); } else { const uint8_t *p = p_data; const uint8_t *p_last = p + i_data - s->i_char_width; if( s->i_char_width == 2 ) { if( s->b_little_endian == true) { /* UTF-16LE: 0A 00 <LF> */ while( p <= p_last && ( p[0] != 0x0A || p[1] != 0x00 ) ) p += 2; } else { /* UTF-16BE: 00 0A <LF> */ while( p <= p_last && ( p[1] != 0x0A || p[0] != 0x00 ) ) p += 2; } } else if( s->i_char_width == 4 ) { if( s->b_little_endian == true) { /* UTF-32LE: 0A 00 00 00 <LF> */ while( p <= p_last && ( p[0] != 0x0A || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0x00 ) ) p += 4; } else { /* UTF-32BE: 00 00 00 0A <LF> */ while( p <= p_last && ( p[3] != 0x0A || p[2] != 0x00 || p[1] != 0x00 || p[0] != 0x00 ) ) p += 4; } } if( p > p_last ) { psz_eol = NULL; } else { psz_eol = (char *)p + ( s->i_char_width - 1 ); } } if(psz_eol) { i_data = (psz_eol - (char *)p_data) + 1; p_line = realloc( p_line, i_line + i_data + s->i_char_width ); /* add \0 */ if( !p_line ) goto error; i_data = stream_Read( s, &p_line[i_line], i_data ); if( i_data <= 0 ) break; /* Hmmm */ i_line += i_data - s->i_char_width; /* skip \n */; i_read += i_data; /* We have our line */ break; } /* Read data (+1 for easy \0 append) */ p_line = realloc( p_line, i_line + STREAM_PROBE_LINE + s->i_char_width ); if( !p_line ) goto error; i_data = stream_Read( s, &p_line[i_line], STREAM_PROBE_LINE ); if( i_data <= 0 ) break; /* Hmmm */ i_line += i_data; i_read += i_data; } if( i_read > 0 ) { int j; for( j = 0; j < s->i_char_width; j++ ) { p_line[i_line + j] = '\0'; } i_line += s->i_char_width; /* the added \0 */ if( s->i_char_width > 1 ) { size_t i_in = 0, i_out = 0; const char * p_in = NULL; char * p_out = NULL; char * psz_new_line = NULL; /* iconv */ psz_new_line = malloc( i_line ); if( psz_new_line == NULL ) goto error; i_in = i_out = (size_t)i_line; p_in = p_line; p_out = psz_new_line; if( vlc_iconv( s->conv, &p_in, &i_in, &p_out, &i_out ) == (size_t)-1 ) { msg_Err( s, "iconv failed" ); msg_Dbg( s, "original: %d, in %d, out %d", i_line, (int)i_in, (int)i_out ); } free( p_line ); p_line = psz_new_line; i_line = (size_t)i_line - i_out; /* does not include \0 */ } /* Remove trailing LF/CR */ while( i_line >= 2 && ( p_line[i_line-2] == '\r' || p_line[i_line-2] == '\n') ) i_line--; /* Make sure the \0 is there */ p_line[i_line-1] = '\0'; return p_line; }error: /* We failed to read any data, probably EOF */ free( p_line ); if( s->conv != (vlc_iconv_t)(-1) ) vlc_iconv_close( s->conv ); return NULL;}/**************************************************************************** * Access reading/seeking wrappers to handle concatenated streams. ****************************************************************************/static int AReadStream( stream_t *s, void *p_read, unsigned int i_read ){ stream_sys_t *p_sys = s->p_sys; access_t *p_access = p_sys->p_access; input_thread_t *p_input = NULL; int i_read_orig = i_read; int i_total = 0; if( s->p_parent && s->p_parent->p_parent && s->p_parent->p_parent->i_object_type == VLC_OBJECT_INPUT ) p_input = (input_thread_t *)s->p_parent->p_parent; if( !p_sys->i_list ) { i_read = p_access->pf_read( p_access, p_read, i_read ); if( p_access->b_die ) vlc_object_kill( s ); if( p_input ) { vlc_mutex_lock( &p_input->p->counters.counters_lock ); stats_UpdateInteger( s, p_input->p->counters.p_read_bytes, i_read, &i_total ); stats_UpdateFloat( s, p_input->p->counters.p_input_bitrate, (float)i_total, NULL ); stats_UpdateInteger( s, p_input->p->counters.p_read_packets, 1, NULL ); vlc_mutex_unlock( &p_input->p->counters.counters_lock ); } return i_read; } i_read = p_sys->p_list_access->pf_read( p_sys->p_list_access, p_read, i_read ); if( p_access->b_die ) vlc_object_kill( s ); /* If we reached an EOF then switch to the next stream in the list */ if( i_read == 0 && p_sys->i_list_index + 1 < p_sys->i_list ) { char *psz_name = p_sys->list[++p_sys->i_list_index]->psz_path; access_t *p_list_access; msg_Dbg( s, "opening input `%s'", psz_name ); p_list_access = access_New( s, p_access->psz_access, "", psz_name ); if( !p_list_access ) return 0; if( p_sys->p_list_access != p_access ) access_Delete( p_sys->p_list_access ); p_sys->p_list_access = p_list_access; /* We have to read some data */ return AReadStream( s, p_read, i_read_orig ); } /* Update read bytes in input */ if( p_input ) { vlc_mutex_lock( &p_input->p->counters.counters_lock ); stats_UpdateInteger( s, p_input->p->counters.p_read_bytes, i_read, &i_total ); stats_UpdateFloat( s, p_input->p->counters.p_input_bitrate, (float)i_total, NULL ); stats_UpdateInteger( s, p_input->p->counters.p_read_packets, 1, NULL ); vlc_mutex_unlock( &p_input->p->counters.counters_lock ); } return i_read;}static block_t *AReadBlock( stream_t *s, bool *pb_eof ){ stream_sys_t *p_sys = s->p_sys; access_t *p_access = p_sys->p_access; input_thread_t *p_input = NULL; block_t *p_block; bool b_eof; int i_total = 0; if( s->p_parent && s->p_parent->p_parent && s->p_parent->p_parent->i_object_type == VLC_OBJECT_INPUT ) p_input = (input_thread_t *)s->p_parent->p_parent; if( !p_sys->i_list ) { p_block = p_access->pf_block( p_access ); if( p_access->b_die ) vlc_object_kill( s ); if( pb_eof ) *pb_eof = p_access->info.b_eof; if( p_input && p_block && libvlc_stats (p_access) ) { vlc_mutex_lock( &p_input->p->counters.counters_lock ); stats_UpdateInteger( s, p_input->p->counters.p_read_bytes, p_block->i_buffer, &i_total ); stats_UpdateFloat( s, p_input->p->counters.p_input_bitrate, (float)i_total, NULL ); stats_UpdateInteger( s, p_input->p->counters.p_read_packets, 1, NULL ); vlc_mutex_unlock( &p_input->p->counters.counters_lock ); } return p_block; } p_block = p_sys->p_list_access->pf_block( p_sys->p_list_access ); if( p_access->b_die ) vlc_object_kill( s ); b_eof = p_sys->p_list_access->info.b_eof; if( pb_eof ) *pb_eof = b_eof; /* If we reached an EOF then switch to the next stream in the list */ if( !p_block && b_eof && p_sys->i_list_index + 1 < p_sys->i_list ) { char *psz_name = p_sys->list[++p_sys->i_list_index]->psz_path; access_t *p_list_access; msg_Dbg( s, "opening input `%s'", psz_name ); p_list_access = access_New( s, p_access->psz_access, "", psz_name ); if( !p_list_access ) return 0; if( p_sys->p_list_access != p_access ) access_Delete( p_sys->p_list_access ); p_sys->p_list_access = p_list_access; /* We have to read some data */ return AReadBlock( s, pb_eof ); } if( p_block ) { if( p_input ) { vlc_mutex_lock( &p_input->p->counters.counters_lock ); stats_UpdateInteger( s, p_input->p->counters.p_read_bytes, p_block->i_buffer, &i_total ); stats_UpdateFloat( s, p_input->p->counters.p_input_bitrate, (float)i_total, NULL ); stats_UpdateInteger( s, p_input->p->counters.p_read_packets, 1 , NULL); vlc_mutex_unlock( &p_input->p->counters.counters_lock ); } } return p_block;}static int ASeek( stream_t *s, int64_t i_pos ){ stream_sys_t *p_sys = s->p_sys; access_t *p_access = p_sys->p_access; /* Check which stream we need to access */ if( p_sys->i_list ) { int i; char *psz_name; int64_t i_size = 0; access_t *p_list_access = 0; for( i = 0; i < p_sys->i_list - 1; i++ ) { if( i_pos < p_sys->list[i]->i_size + i_size ) break; i_size += p_sys->list[i]->i_size; } psz_name = p_sys->list[i]->psz_path; if( i != p_sys->i_list_index ) msg_Dbg( s, "opening input `%s'", psz_name ); if( i != p_sys->i_list_index && i != 0 ) { p_list_access = access_New( s, p_access->psz_access, "", psz_name ); } else if( i != p_sys->i_list_index ) { p_list_access = p_access; } if( p_list_access ) { if( p_sys->p_list_access != p_access ) access_Delete( p_sys->p_list_access ); p_sys->p_list_access = p_list_access; } p_sys->i_list_index = i; return p_sys->p_list_access->pf_seek( p_sys->p_list_access, i_pos - i_size ); } return p_access->pf_seek( p_access, i_pos );}/** * Try to read "i_read" bytes into a buffer pointed by "p_read". If * "p_read" is NULL then data are skipped instead of read. The return * value is the real numbers of bytes read/skip. If this value is less * than i_read that means that it's the end of the stream. */int stream_Read( stream_t *s, void *p_read, int i_read ){ return s->pf_read( s, p_read, i_read );}/** * Store in pp_peek a pointer to the next "i_peek" bytes in the stream * \return The real numbers of valid bytes, if it's less * or equal to 0, *pp_peek is invalid. * \note pp_peek is a pointer to internal buffer and it will be invalid as * soons as other stream_* functions are called. * \note Due to input limitation, it could be less than i_peek without meaning * the end of the stream (but only when you have i_peek >= * p_input->i_bufsize) */int stream_Peek( stream_t *s, const uint8_t **pp_peek, int i_peek ){ return s->pf_peek( s, pp_peek, i_peek );}/** * Use to control the "stream_t *". Look at #stream_query_e for * possible "i_query" value and format arguments. Return VLC_SUCCESS * if ... succeed ;) and VLC_EGENERIC if failed or unimplemented */int stream_vaControl( stream_t *s, int i_query, va_list args ){ return s->pf_control( s, i_query, args );}/** * Destroy a stream */void stream_Delete( stream_t *s ){ s->pf_destroy( s );}int stream_Control( stream_t *s, int i_query, ... ){ va_list args; int i_result; if ( s == NULL ) return VLC_EGENERIC; va_start( args, i_query ); i_result = s->pf_control( s, i_query, args ); va_end( args ); return i_result;}/** * Read "i_size" bytes and store them in a block_t. * It always read i_size bytes unless you are at the end of the stream * where it return what is available. */block_t *stream_Block( stream_t *s, int i_size ){ if( i_size <= 0 ) return NULL; /* emulate block read */ block_t *p_bk = block_New( s, i_size ); if( p_bk ) { int i_read = stream_Read( s, p_bk->p_buffer, i_size ); if( i_read > 0 ) { p_bk->i_buffer = i_read; return p_bk; } block_Release( p_bk ); } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -