📄 timeshift.c
字号:
} WriteBlockToFile( p_access, p_block ); block_Release( p_block ); /* Read from file to fill up the fifo */ while( p_sys->p_fifo->i_size < TIMESHIFT_FIFO_MIN && !p_access->b_die ) { p_block = ReadBlockFromFile( p_access ); if( !p_block ) break; block_FifoPut( p_sys->p_fifo, p_block ); } } msg_Dbg( p_access, "timeshift: EOF" ); /* Send dummy packet to avoid deadlock in TShiftBlock */ for( i = 0; i < 2; i++ ) { block_t *p_dummy = block_New( p_access, 128 ); p_dummy->i_flags |= BLOCK_FLAG_DISCONTINUITY; memset( p_dummy->p_buffer, 0, p_dummy->i_buffer ); block_FifoPut( p_sys->p_fifo, p_dummy ); }}/***************************************************************************** * NextFileWrite: *****************************************************************************/static void NextFileWrite( access_t *p_access ){ access_sys_t *p_sys = p_access->p_sys; ts_entry_t *p_next; if( !p_sys->p_write_list ) { p_sys->i_write_size = 0; return; } p_next = p_sys->p_write_list->p_next; /* Put written file in read list */ if( p_sys->i_write_size < p_sys->i_file_size ) ftruncate( fileno( p_sys->p_write_list->file ), p_sys->i_write_size ); fseek( p_sys->p_write_list->file, 0, SEEK_SET ); *p_sys->pp_read_last = p_sys->p_write_list; p_sys->pp_read_last = &p_sys->p_write_list->p_next; p_sys->p_write_list->p_next = 0; /* Switch to next file to write */ p_sys->p_write_list = p_next; if( !p_sys->p_write_list ) p_sys->pp_write_last = &p_sys->p_write_list; p_sys->i_write_size = 0;}/***************************************************************************** * NextFileRead: *****************************************************************************/static void NextFileRead( access_t *p_access ){ access_sys_t *p_sys = p_access->p_sys; ts_entry_t *p_next; if( !p_sys->p_read_list ) return; p_next = p_sys->p_read_list->p_next; /* Put read file in write list */ fseek( p_sys->p_read_list->file, 0, SEEK_SET ); *p_sys->pp_write_last = p_sys->p_read_list; p_sys->pp_write_last = &p_sys->p_read_list->p_next; p_sys->p_read_list->p_next = 0; /* Switch to next file to read */ p_sys->p_read_list = p_next; if( !p_sys->p_read_list ) p_sys->pp_read_last = &p_sys->p_read_list;}/***************************************************************************** * WriteBlockToFile: *****************************************************************************/static int WriteBlockToFile( access_t *p_access, block_t *p_block ){ access_sys_t *p_sys = p_access->p_sys; int i_write, i_buffer; if( p_sys->i_write_size == p_sys->i_file_size ) NextFileWrite( p_access ); /* Open new file if necessary */ if( !p_sys->p_write_list ) { FILE *file; sprintf( p_sys->psz_filename, "%s%i.dat", p_sys->psz_filename_base, p_sys->i_files ); file = utf8_fopen( p_sys->psz_filename, "w+b" ); if( !file && p_sys->i_files < 2 ) { /* We just can't work with less than 2 buffer files */ msg_Err( p_access, "cannot open temporary file '%s' (%s)", p_sys->psz_filename, strerror(errno) ); return VLC_EGENERIC; } else if( !file ) return VLC_EGENERIC; p_sys->p_write_list = malloc( sizeof(ts_entry_t) ); p_sys->p_write_list->p_next = 0; p_sys->p_write_list->file = file; p_sys->pp_write_last = &p_sys->p_write_list->p_next; p_sys->i_files++; } /* Write to file */ i_buffer = __MIN( p_block->i_buffer, p_sys->i_file_size - p_sys->i_write_size ); i_write = fwrite( p_block->p_buffer, 1, i_buffer, p_sys->p_write_list->file ); if( i_write > 0 ) p_sys->i_write_size += i_write; //p_access->info.i_size += i_write; //p_access->info.i_update |= INPUT_UPDATE_SIZE; if( i_write < i_buffer ) { /* Looks like we're short of space */ if( !p_sys->p_write_list->p_next ) { msg_Warn( p_access, "no more space, overwritting old data" ); NextFileRead( p_access ); NextFileRead( p_access ); } /* Make sure we switch to next file in write list */ p_sys->i_write_size = p_sys->i_file_size; } p_block->p_buffer += i_write; p_block->i_buffer -= i_write; /* Check if we have some data left */ if( p_block->i_buffer ) return WriteBlockToFile( p_access, p_block ); return VLC_SUCCESS;}/***************************************************************************** * ReadBlockFromFile: *****************************************************************************/static block_t *ReadBlockFromFile( access_t *p_access ){ access_sys_t *p_sys = p_access->p_sys; block_t *p_block; if( !p_sys->p_read_list && p_sys->p_write_list ) { /* Force switching to next write file, that should * give us something to read */ NextFileWrite( p_access ); } if( !p_sys->p_read_list ) return 0; p_block = block_New( p_access, 4096 ); p_block->i_buffer = fread( p_block->p_buffer, 1, 4096, p_sys->p_read_list->file ); if( p_block->i_buffer == 0 ) NextFileRead( p_access ); //p_access->info.i_size -= p_block->i_buffer; //p_access->info.i_update |= INPUT_UPDATE_SIZE; return p_block;}/***************************************************************************** * Seek: seek to a specific location in a file *****************************************************************************/static int Seek( access_t *p_access, int64_t i_pos ){ //access_sys_t *p_sys = p_access->p_sys; return VLC_SUCCESS;}/***************************************************************************** * *****************************************************************************/static int Control( access_t *p_access, int i_query, va_list args ){ access_t *p_src = p_access->p_source; vlc_bool_t *pb_bool; int *pi_int; int64_t *pi_64; switch( i_query ) { case ACCESS_CAN_SEEK: case ACCESS_CAN_FASTSEEK: pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* ); *pb_bool = VLC_TRUE; break; case ACCESS_CAN_CONTROL_PACE: /* Not really true */ case ACCESS_CAN_PAUSE: pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* ); *pb_bool = VLC_TRUE; break; case ACCESS_GET_MTU: pi_int = (int*)va_arg( args, int * ); *pi_int = 0; break; case ACCESS_GET_PTS_DELAY: pi_64 = (int64_t*)va_arg( args, int64_t * ); return access2_Control( p_src, ACCESS_GET_PTS_DELAY, pi_64 ); case ACCESS_SET_PAUSE_STATE: return VLC_SUCCESS; case ACCESS_GET_TITLE_INFO: case ACCESS_SET_TITLE: case ACCESS_SET_SEEKPOINT: case ACCESS_GET_META: return VLC_EGENERIC; case ACCESS_SET_PRIVATE_ID_STATE: case ACCESS_GET_PRIVATE_ID_STATE: case ACCESS_SET_PRIVATE_ID_CA: return access2_vaControl( p_src, i_query, args ); default: msg_Warn( p_access, "unimplemented query in control" ); return VLC_EGENERIC; } return VLC_SUCCESS;}/***************************************************************************** * GetTmpFilePath: *****************************************************************************/#ifdef WIN32#define getpid() GetCurrentProcessId()#endifstatic char *GetTmpFilePath( access_t *p_access ){ char *psz_dir = var_GetString( p_access, "timeshift-dir" ); char *psz_filename_base; if( ( psz_dir != NULL ) && ( psz_dir[0] == '\0' ) ) { free( psz_dir ); psz_dir = NULL; } if( psz_dir == NULL ) {#ifdef WIN32 char psz_local_dir[MAX_PATH]; int i_size; i_size = GetTempPath( MAX_PATH, psz_local_dir ); if( i_size <= 0 || i_size > MAX_PATH ) { if( !getcwd( psz_local_dir, MAX_PATH ) ) strcpy( psz_local_dir, "C:" ); } psz_dir = FromLocaleDup( psz_local_dir ); /* remove last \\ if any */ if( psz_dir[strlen(psz_dir)-1] == '\\' ) psz_dir[strlen(psz_dir)-1] = '\0';#else psz_dir = strdup( "/tmp" );#endif } asprintf( &psz_filename_base, "%s/vlc-timeshift-%d-%d-", psz_dir, getpid(), p_access->i_object_id ); free( psz_dir ); return psz_filename_base;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -