static inline bool ep_process_sampler_dep(struct effect_parser *ep, struct ep_func *func) { struct ep_sampler *val = ep_getsampler_strref(ep, &ep->cfp.cur_token->str); if (val) da_push_back(func->sampler_deps, &val->name); return val != NULL; }
void gs_texcoord2v(const struct vec2 *v, int unit) { graphics_t graphics = thread_graphics; if (!validvertsize(graphics, graphics->texverts[unit].num, "gs_texcoord")) return; da_push_back(graphics->texverts[unit], v); }
void obs_encoder_add_output(struct obs_encoder *encoder, struct obs_output *output) { if (!encoder) return; pthread_mutex_lock(&encoder->outputs_mutex); da_push_back(encoder->outputs, &output); pthread_mutex_unlock(&encoder->outputs_mutex); }
void gs_matrix_push(void) { graphics_t graphics = thread_graphics; struct matrix3 mat, *top_mat = top_matrix(graphics); memcpy(&mat, top_mat, sizeof(struct matrix3)); da_push_back(graphics->matrix_stack, &mat); graphics->cur_matrix++; }
static void ep_parse_technique(struct effect_parser *ep) { struct ep_technique ept; ep_technique_init(&ept); if (cf_next_name(&ep->cfp, &ept.name, "name", ";") != PARSE_SUCCESS) goto error; if (cf_next_token_should_be(&ep->cfp, "{", ";", NULL) != PARSE_SUCCESS) goto error; if (!cf_next_valid_token(&ep->cfp)) goto error; while (!cf_token_is(&ep->cfp, "}")) { struct ep_pass pass; ep_pass_init(&pass); switch (ep_parse_pass(ep, &pass)) { case PARSE_UNEXPECTED_CONTINUE: ep_pass_free(&pass); if (!cf_go_to_token(&ep->cfp, "}", NULL)) goto error; continue; case PARSE_EOF: ep_pass_free(&pass); goto error; } da_push_back(ept.passes, &pass); if (!cf_next_valid_token(&ep->cfp)) goto error; } /* pass the current token (which is '}') if we reached here */ cf_next_token(&ep->cfp); da_push_back(ep->techniques, &ept); return; error: cf_next_token(&ep->cfp); ep_technique_free(&ept); }
void obs_add_module_path(const char *bin, const char *data) { struct obs_module_path omp; if (!obs || !bin || !data) return; omp.bin = bstrdup(bin); omp.data = bstrdup(data); da_push_back(obs->module_paths, &omp); }
void build_font_path_info(FT_Face face, FT_Long idx, const char *path) { FT_UInt num_names = FT_Get_Sfnt_Name_Count(face); DARRAY(char*) family_names; da_init(family_names); da_push_back(family_names, &face->family_name); for (FT_UInt i = 0; i < num_names; i++) { FT_SfntName name; char *family; FT_Error ret = FT_Get_Sfnt_Name(face, i, &name); if (ret != 0 || name.name_id != TT_NAME_ID_FONT_FAMILY) continue; family = sfnt_name_to_utf8(&name); if (!family) continue; for (size_t i = 0; i < family_names.num; i++) { if (astrcmpi(family_names.array[i], family) == 0) { bfree(family); family = NULL; break; } } if (family) da_push_back(family_names, &family); } for (size_t i = 0; i < family_names.num; i++) { add_font_path(face, idx, family_names.array[i], face->style_name, path); /* first item isn't our allocation */ if (i > 0) bfree(family_names.array[i]); } da_free(family_names); }
void obs_context_data_setname(struct obs_context_data *context, const char *name) { pthread_mutex_lock(&context->rename_cache_mutex); if (context->name) da_push_back(context->rename_cache, &context->name); context->name = dup_name(name); pthread_mutex_unlock(&context->rename_cache_mutex); }
static inline void gl_add_sampler(struct gs_shader *shader, struct shader_sampler *sampler) { samplerstate_t new_sampler; struct gs_sampler_info info; shader_sampler_convert(sampler, &info); new_sampler = device_create_samplerstate(shader->device, &info); da_push_back(shader->samplers, &new_sampler); }
audio_line_t audio_output_createline(audio_t audio) { struct audio_line *line = bmalloc(sizeof(struct audio_line)); memset(line, 0, sizeof(struct audio_line)); line->alive = true; pthread_mutex_lock(&audio->line_mutex); da_push_back(audio->lines, &line); pthread_mutex_unlock(&audio->line_mutex); return line; }
static void push_audio_tree(obs_source_t *parent, obs_source_t *source, void *p) { struct obs_core_audio *audio = p; if (da_find(audio->render_order, &source, 0) == DARRAY_INVALID) { obs_source_addref(source); da_push_back(audio->render_order, &source); } UNUSED_PARAMETER(parent); }
void obs_display_add_draw_callback(obs_display_t display, void (*draw)(void *param, uint32_t cx, uint32_t cy), void *param) { if (!display) return; struct draw_callback data = {draw, param}; pthread_mutex_lock(&display->draw_callbacks_mutex); da_push_back(display->draw_callbacks, &data); pthread_mutex_unlock(&display->draw_callbacks_mutex); }
static inline int ep_parse_func_param(struct effect_parser *ep, struct ep_func *func, struct ep_var *var) { int code; if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; code = ep_check_for_keyword(ep, "uniform", &var->uniform); if (code == PARSE_EOF) return PARSE_EOF; code = cf_get_name(&ep->cfp, &var->type, "type", ")"); if (code != PARSE_SUCCESS) return code; code = cf_next_name(&ep->cfp, &var->name, "name", ")"); if (code != PARSE_SUCCESS) return code; if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; if (cf_token_is(&ep->cfp, ":")) { code = cf_next_name(&ep->cfp, &var->mapping, "mapping specifier", ")"); if (code != PARSE_SUCCESS) return code; if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; } if (ep_getstruct(ep, var->type) != NULL) da_push_back(func->struct_deps, &var->type); else if (ep_getsampler(ep, var->type) != NULL) da_push_back(func->sampler_deps, &var->type); return PARSE_SUCCESS; }
static int ep_parse_sampler_state_item(struct effect_parser *ep, struct ep_sampler *eps) { int ret; char *state = NULL; struct dstr value = {0}; ret = cf_next_name(&ep->cfp, &state, "state name", ";"); if (ret != PARSE_SUCCESS) goto fail; ret = cf_next_token_should_be(&ep->cfp, "=", ";", NULL); if (ret != PARSE_SUCCESS) goto fail; for (;;) { const char *cur_str; if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; cur_str = ep->cfp.cur_token->str.array; if (*cur_str == ';') break; dstr_ncat(&value, cur_str, ep->cfp.cur_token->str.len); } if (value.len) { da_push_back(eps->states, &state); da_push_back(eps->values, &value.array); } return ret; fail: bfree(state); dstr_free(&value); return ret; }
bool cf_preprocess(struct cf_preprocessor *pp, struct cf_lexer *lex, struct error_data *ed) { struct cf_token *token = cf_lexer_gettokens(lex); if (!token) return false; pp->ed = ed; pp->lex = lex; cf_preprocess_tokens(pp, false, &token); da_push_back(pp->tokens, token); return !lex->unexpected_eof; }
static void add_font_path(FT_Face face, FT_Long idx, const char *family_in, const char *style_in, const char *path) { struct dstr face_and_style = {0}; struct font_path_info info; if (!family_in || !path) return; dstr_copy(&face_and_style, family_in); if (face->style_name) { struct dstr style = {0}; dstr_copy(&style, style_in); dstr_replace(&style, "Bold", ""); dstr_replace(&style, "Italic", ""); dstr_replace(&style, " ", " "); dstr_depad(&style); if (!dstr_is_empty(&style)) { dstr_cat(&face_and_style, " "); dstr_cat_dstr(&face_and_style, &style); } dstr_free(&style); } info.face_and_style = face_and_style.array; info.full_len = face_and_style.len; info.face_len = strlen(family_in); info.is_bitmap = !!(face->face_flags & FT_FACE_FLAG_FIXED_SIZES); info.bold = !!(face->style_flags & FT_STYLE_FLAG_BOLD); info.italic = !!(face->style_flags & FT_STYLE_FLAG_ITALIC); info.index = idx; info.path = bstrdup(path); create_bitmap_sizes(&info, face); da_push_back(font_list, &info); /*blog(LOG_DEBUG, "name: %s\n\tstyle: %s\n\tpath: %s\n", family_in, style_in, path);*/ }
void obs_source_output_video(obs_source_t source, const struct source_frame *frame) { struct source_frame *output = cache_video(source, frame); pthread_mutex_lock(&source->filter_mutex); output = filter_async_video(source, output); pthread_mutex_unlock(&source->filter_mutex); if (output) { pthread_mutex_lock(&source->video_mutex); da_push_back(source->video_frames, &output); pthread_mutex_unlock(&source->video_mutex); } }
bool obs_add_source(obs_source_t source) { struct calldata params = {0}; pthread_mutex_lock(&obs->data.sources_mutex); da_push_back(obs->data.sources, &source); obs_source_addref(source); pthread_mutex_unlock(&obs->data.sources_mutex); calldata_setptr(¶ms, "source", source); signal_handler_signal(obs->signals, "source-add", ¶ms); calldata_free(¶ms); return true; }
static void cf_preprocess_define(struct cf_preprocessor *pp, struct cf_token **p_cur_token) { struct cf_token *cur_token = *p_cur_token; struct cf_def def; if (pp->ignore_state) { go_to_newline(p_cur_token); return; } cf_def_init(&def); next_token(&cur_token, true); if (cur_token->type != CFTOKEN_NAME) { cf_adderror_expecting(pp, cur_token, "identifier"); go_to_newline(&cur_token); goto exit; } append_space(pp, &def.tokens.da, NULL); cf_token_copy(&def.name, cur_token); if (!next_token(&cur_token, true)) goto complete; /* process macro */ if (*cur_token->str.array == '(') { if (!cf_preprocess_macro_params(pp, &def, &cur_token)) goto error; } while (cur_token->type != CFTOKEN_NEWLINE && cur_token->type != CFTOKEN_NONE) cf_def_addtoken(&def, cur_token++); complete: append_end_token(&def.tokens.da); append_space(pp, &def.tokens.da, NULL); da_push_back(pp->defines, &def); goto exit; error: cf_def_free(&def); exit: *p_cur_token = cur_token; }
static void scene_video_render(void *data, gs_effect_t *effect) { DARRAY(struct obs_scene_item*) remove_items; struct obs_scene *scene = data; struct obs_scene_item *item; da_init(remove_items); video_lock(scene); item = scene->first_item; gs_blend_state_push(); gs_reset_blend_state(); while (item) { if (obs_source_removed(item->source)) { struct obs_scene_item *del_item = item; item = item->next; remove_without_release(del_item); da_push_back(remove_items, &del_item); continue; } if (source_size_changed(item)) update_item_transform(item); if (item->user_visible) { gs_matrix_push(); gs_matrix_mul(&item->draw_transform); obs_source_video_render(item->source); gs_matrix_pop(); } item = item->next; } gs_blend_state_pop(); video_unlock(scene); for (size_t i = 0; i < remove_items.num; i++) obs_sceneitem_release(remove_items.array[i]); da_free(remove_items); UNUSED_PARAMETER(effect); }
static inline void netif_saddr_data_push_back(struct netif_saddr_data *sd, const char *ip, const char *adapter) { struct netif_saddr_item item; struct dstr full_name = {0}; char *ip_dup = bstrdup(ip); if (adapter && *adapter) dstr_printf(&full_name, "[%s] %s", adapter, ip); else dstr_copy(&full_name, ip); item.name = full_name.array; item.addr = ip_dup; da_push_back(sd->addrs, &item); }
static void cf_include_file(struct cf_preprocessor *pp, const struct cf_token *file_token) { struct cf_lexer new_lex; struct dstr str_file; FILE *file; char *file_data; struct cf_token *tokens; size_t i; dstr_init(&str_file); dstr_copy_strref(&str_file, &file_token->str); dstr_mid(&str_file, &str_file, 1, str_file.len-2); /* if dependency already exists, run preprocessor on it */ for (i = 0; i < pp->dependencies.num; i++) { struct cf_lexer *dep = pp->dependencies.array+i; if (strcmp(dep->file, str_file.array) == 0) { tokens = cf_lexer_gettokens(dep); cf_preprocess_tokens(pp, false, &tokens); goto exit; } } file = os_fopen(str_file.array, "rb"); if (!file) { cf_adderror(pp, file_token, "Could not open file '$1'", file_token->str.array, NULL, NULL); goto exit; } os_fread_utf8(file, &file_data); fclose(file); cf_lexer_init(&new_lex); cf_lexer_lex(&new_lex, file_data, str_file.array); tokens = cf_lexer_gettokens(&new_lex); cf_preprocess_tokens(pp, false, &tokens); bfree(file_data); da_push_back(pp->dependencies, &new_lex); exit: dstr_free(&str_file); }
static inline bool gl_process_attrib(struct gs_shader *shader, struct gl_parser_attrib *pa) { struct shader_attrib attrib = {0}; get_attrib_type(pa->mapping, &attrib.type, &attrib.index); attrib.attrib = glGetAttribLocation(shader->program, pa->name.array); if (!gl_success("glGetAttribLocation")) return false; /* If the attribute is not found, it's usually just an output */ if (attrib.attrib == -1) return true; da_push_back(shader->attribs, &attrib); return true; }
static bool do_http_request(struct update_info *info, const char *url, long *response_code) { CURLcode code; uint8_t null_terminator = 0; da_resize(info->file_data, 0); curl_easy_setopt(info->curl, CURLOPT_URL, url); curl_easy_setopt(info->curl, CURLOPT_HTTPHEADER, info->header); curl_easy_setopt(info->curl, CURLOPT_ERRORBUFFER, info->error); curl_easy_setopt(info->curl, CURLOPT_WRITEFUNCTION, http_write); curl_easy_setopt(info->curl, CURLOPT_WRITEDATA, info); curl_easy_setopt(info->curl, CURLOPT_FAILONERROR, true); if (!info->remote_url) { // We only care about headers from the main package file curl_easy_setopt(info->curl, CURLOPT_HEADERFUNCTION, http_header); curl_easy_setopt(info->curl, CURLOPT_HEADERDATA, info); } // A lot of servers don't yet support ALPN curl_easy_setopt(info->curl, CURLOPT_SSL_ENABLE_ALPN, 0); code = curl_easy_perform(info->curl); if (code != CURLE_OK) { warn("Remote update of URL \"%s\" failed: %s", url, info->error); return false; } if (curl_easy_getinfo(info->curl, CURLINFO_RESPONSE_CODE, response_code) != CURLE_OK) return false; if (*response_code >= 400) { warn("Remote update of URL \"%s\" failed: HTTP/%ld", url, response_code); return false; } da_push_back(info->file_data, &null_terminator); return true; }
static void sp_parse_function(struct shader_parser *sp, char *type, char *name) { struct shader_func func; shader_func_init(&func, type, name); if (!sp_parse_func_params(sp, &func)) goto error; if (!cf_next_valid_token(&sp->cfp)) goto error; /* if function is mapped to something, for example COLOR */ if (cf_token_is(&sp->cfp, ":")) { char *mapping = NULL; int errorcode = cf_next_name(&sp->cfp, &mapping, "mapping", "{"); if (errorcode != PARSE_SUCCESS) goto error; func.mapping = mapping; if (!cf_next_valid_token(&sp->cfp)) goto error; } if (!cf_token_is(&sp->cfp, "{")) { cf_adderror_expecting(&sp->cfp, "{"); goto error; } func.start = sp->cfp.cur_token; if (!cf_pass_pair(&sp->cfp, '{', '}')) goto error; /* it is established that the current token is '}' if we reach this */ cf_next_token(&sp->cfp); func.end = sp->cfp.cur_token; da_push_back(sp->funcs, &func); return; error: shader_func_free(&func); }
void proc_handler_add(proc_handler_t *handler, const char *decl_string, proc_handler_proc_t proc, void *data) { if (!handler) return; struct proc_info pi; memset(&pi, 0, sizeof(struct proc_info)); if (!parse_decl_string(&pi.func, decl_string)) { blog(LOG_ERROR, "Function declaration invalid: %s", decl_string); return; } pi.callback = proc; pi.data = data; da_push_back(handler->procs, &pi); }
void cf_preprocessor_add_def(struct cf_preprocessor *pp, struct cf_def *def) { struct cf_def *existing = cf_preprocess_get_def(pp, &def->name.str); if (existing) { struct dstr name; dstr_init_strref(&name, &def->name.str); cf_addwarning(pp, &def->name, "Token $1 already defined", name.array, NULL, NULL); cf_addwarning(pp, &existing->name, "Previous definition of $1 is here", name.array, NULL, NULL); cf_def_free(existing); memcpy(existing, def, sizeof(struct cf_def)); } else { da_push_back(pp->defines, &def); } }
static bool graphics_init(struct graphics_subsystem *graphics) { struct matrix3 top_mat; matrix3_identity(&top_mat); da_push_back(graphics->matrix_stack, &top_mat); graphics->exports.device_entercontext(graphics->device); if (!graphics_init_immediate_vb(graphics)) return false; if (!graphics_init_sprite_vb(graphics)) return false; if (pthread_mutex_init(&graphics->mutex, NULL) != 0) return false; graphics->exports.device_leavecontext(graphics->device); return true; }
bool cf_lexer_lex(struct cf_lexer *lex, const char *str, const char *file) { struct cf_token token; struct cf_token *last_token = NULL; cf_lexer_free(lex); if (!str || !*str) return false; if (file) lex->file = bstrdup(file); lexer_start(&lex->base_lexer, str); cf_token_clear(&token); lex->reformatted = bmalloc(strlen(str) + 1); lex->reformatted[0] = 0; lex->write_offset = lex->reformatted; while (cf_lexer_nexttoken(lex, &token)) { if (last_token && is_space_or_tab(*last_token->str.array) && is_space_or_tab(*token.str.array)) { cf_token_add(last_token, &token); continue; } token.lex = lex; last_token = da_push_back_new(lex->tokens); memcpy(last_token, &token, sizeof(struct cf_token)); } cf_token_clear(&token); token.str.array = lex->write_offset; token.unmerged_str.array = lex->base_lexer.offset; token.lex = lex; da_push_back(lex->tokens, &token); return !lex->unexpected_eof; }
void obs_source_output_audio(obs_source_t source, const struct source_audio *audio) { uint32_t flags = obs_source_get_output_flags(source); size_t blocksize = audio_output_blocksize(obs->audio.audio); struct filtered_audio *output; process_audio(source, audio); pthread_mutex_lock(&source->filter_mutex); output = filter_async_audio(source, &source->audio_data); if (output) { pthread_mutex_lock(&source->audio_mutex); /* wait for video to start before outputting any audio so we * have a base for sync */ if (!source->timing_set && (flags & SOURCE_ASYNC_VIDEO) != 0) { struct audiobuf newbuf; size_t audio_size = blocksize * output->frames; newbuf.data = bmalloc(audio_size); newbuf.frames = output->frames; newbuf.timestamp = output->timestamp; memcpy(newbuf.data, output->data, audio_size); da_push_back(source->audio_wait_buffer, &newbuf); } else { struct audio_data data; data.data = output->data; data.frames = output->frames; data.timestamp = output->timestamp; source_output_audio_line(source, &data); } pthread_mutex_unlock(&source->audio_mutex); } pthread_mutex_unlock(&source->filter_mutex); }