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 access_t *GetAccess(access_t *access) { access_sys_t *sys = access->p_sys; access_t *a = sys->access; if (a != NULL) { if (!vlc_access_Eof(a)) return a; vlc_access_Delete(a); sys->access = NULL; } if (sys->next == NULL) { error: access->info.b_eof = true; return NULL; } a = vlc_access_NewMRL(VLC_OBJECT(access), sys->next->mrl); if (a == NULL) goto error; sys->access = a; sys->next = sys->next->next; return a; }
/* Read access */ static ssize_t AStreamReadStream(stream_t *s, void *buf, size_t len) { stream_sys_t *sys = s->p_sys; input_thread_t *input = s->p_input; ssize_t val = 0; do { if (vlc_access_Eof(sys->access)) return 0; if (vlc_killed()) return -1; val = vlc_access_Read(sys->access, buf, len); if (val == 0) return 0; /* EOF */ } while (val < 0); if (input != NULL) { uint64_t total; vlc_mutex_lock(&input->p->counters.counters_lock); stats_Update(input->p->counters.p_read_bytes, val, &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); } return val; }
/* 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; }