static int AStreamControl(stream_t *s, int cmd, va_list args) { stream_sys_t *sys = s->p_sys; access_t *access = sys->access; static_control_match(CAN_SEEK); static_control_match(CAN_FASTSEEK); static_control_match(CAN_PAUSE); static_control_match(CAN_CONTROL_PACE); static_control_match(GET_SIZE); static_control_match(IS_DIRECTORY); static_control_match(GET_PTS_DELAY); static_control_match(GET_TITLE_INFO); static_control_match(GET_TITLE); static_control_match(GET_SEEKPOINT); static_control_match(GET_META); static_control_match(GET_CONTENT_TYPE); static_control_match(GET_SIGNAL); static_control_match(SET_PAUSE_STATE); static_control_match(SET_TITLE); static_control_match(SET_SEEKPOINT); static_control_match(SET_PRIVATE_ID_STATE); static_control_match(SET_PRIVATE_ID_CA); static_control_match(GET_PRIVATE_ID_STATE); switch (cmd) { case STREAM_SET_TITLE: case STREAM_SET_SEEKPOINT: { int ret = access_vaControl(access, cmd, args); if (ret != VLC_SUCCESS) return ret; if (sys->block != NULL) { block_Release(sys->block); sys->block = NULL; } break; } case STREAM_GET_PRIVATE_BLOCK: { block_t **b = va_arg(args, block_t **); bool *eof = va_arg(args, bool *); if (access->pf_block == NULL) return VLC_EGENERIC; *b = vlc_access_Eof(access) ? NULL : vlc_access_Block(access); *eof = (*b == NULL) && vlc_access_Eof(access); break; } default: return access_vaControl(access, cmd, args); } return VLC_SUCCESS; }
static block_t *Block(access_t *access) { access_t *a = GetAccess(access); if (a == NULL) return NULL; if (likely(a->pf_block != NULL)) return vlc_access_Block(a); if (a->pf_read == NULL) { access->info.b_eof = true; return NULL; } /* Emulate pf_block in case of mixed pf_read and bf_block */ block_t *block = block_Alloc(4096); if (unlikely(block == NULL)) return NULL; ssize_t ret = vlc_access_Read(a, block->p_buffer, block->i_buffer); if (ret >= 0) { block->i_buffer = ret; access->info.i_pos += ret; } else { block_Release(block); block = NULL; } return block; }
/* Block access */ static ssize_t AStreamReadBlock(stream_t *s, void *buf, size_t len) { stream_sys_t *sys = s->p_sys; input_thread_t *input = s->p_input; block_t *block = sys->block; while (block == NULL) { if (vlc_access_Eof(sys->access)) return 0; if (vlc_killed()) return -1; block = vlc_access_Block(sys->access); } if (input != NULL) { uint64_t total; vlc_mutex_lock(&input->p->counters.counters_lock); stats_Update(input->p->counters.p_read_bytes, block->i_buffer, &total); stats_Update(input->p->counters.p_input_bitrate, total, NULL); stats_Update(input->p->counters.p_read_packets, 1, NULL); vlc_mutex_unlock(&input->p->counters.counters_lock); } size_t copy = block->i_buffer < len ? block->i_buffer : len; if (likely(copy > 0) && buf != NULL /* skipping data? */) memcpy(buf, block->p_buffer, copy); block->p_buffer += copy; block->i_buffer -= copy; if (block->i_buffer == 0) { block_Release(block); sys->block = NULL; } else sys->block = block; return copy; }