static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx, const struct vpx_internal_error_info *error) { if (error->error_code) set_error_detail(ctx, error->has_detail ? error->detail : NULL); return error->error_code; }
static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, va_list args) { vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *); // Only support this function in serial decode. if (ctx->frame_parallel_decode) { set_error_detail(ctx, "Not supported in frame parallel decode"); return VPX_CODEC_INCAPABLE; } if (data) { vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data; YV12_BUFFER_CONFIG sd; VPxWorker *const worker = ctx->frame_workers; FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1; image2yuvconfig(&frame->img, &sd); return vp9_set_reference_dec(&frame_worker_data->pbi->common, (VP9_REFFRAME)frame->frame_type, &sd); } else { return VPX_CODEC_INVALID_PARAM; } }
static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, const uint8_t *data, unsigned int data_sz, void *user_priv, long deadline) { const uint8_t *data_start = data; const uint8_t * const data_end = data + data_sz; vpx_codec_err_t res; uint32_t frame_sizes[8]; int frame_count; if (data == NULL && data_sz == 0) { ctx->flushed = 1; return VPX_CODEC_OK; } // Reset flushed when receiving a valid frame. ctx->flushed = 0; // Initialize the decoder workers on the first frame. if (ctx->frame_workers == NULL) { const vpx_codec_err_t res = init_decoder(ctx); if (res != VPX_CODEC_OK) return res; } res = vp9_parse_superframe_index(data, data_sz, frame_sizes, &frame_count, ctx->decrypt_cb, ctx->decrypt_state); if (res != VPX_CODEC_OK) return res; if (ctx->frame_parallel_decode) { // Decode in frame parallel mode. When decoding in this mode, the frame // passed to the decoder must be either a normal frame or a superframe with // superframe index so the decoder could get each frame's start position // in the superframe. if (frame_count > 0) { int i; for (i = 0; i < frame_count; ++i) { const uint8_t *data_start_copy = data_start; const uint32_t frame_size = frame_sizes[i]; if (data_start < data || frame_size > (uint32_t) (data_end - data_start)) { set_error_detail(ctx, "Invalid frame size in index"); return VPX_CODEC_CORRUPT_FRAME; } if (ctx->available_threads == 0) { // No more threads for decoding. Wait until the next output worker // finishes decoding. Then copy the decoded frame into cache. if (ctx->num_cache_frames < FRAME_CACHE_SIZE) { wait_worker_and_cache_frame(ctx); } else { // TODO(hkuang): Add unit test to test this path. set_error_detail(ctx, "Frame output cache is full."); return VPX_CODEC_ERROR; } } res = decode_one(ctx, &data_start_copy, frame_size, user_priv, deadline); if (res != VPX_CODEC_OK) return res; data_start += frame_size; } } else { if (ctx->available_threads == 0) { // No more threads for decoding. Wait until the next output worker // finishes decoding. Then copy the decoded frame into cache. if (ctx->num_cache_frames < FRAME_CACHE_SIZE) { wait_worker_and_cache_frame(ctx); } else { // TODO(hkuang): Add unit test to test this path. set_error_detail(ctx, "Frame output cache is full."); return VPX_CODEC_ERROR; } } res = decode_one(ctx, &data, data_sz, user_priv, deadline); if (res != VPX_CODEC_OK) return res; } } else { // Decode in serial mode. if (frame_count > 0) { int i; for (i = 0; i < frame_count; ++i) { const uint8_t *data_start_copy = data_start; const uint32_t frame_size = frame_sizes[i]; vpx_codec_err_t res; if (data_start < data || frame_size > (uint32_t) (data_end - data_start)) { set_error_detail(ctx, "Invalid frame size in index"); return VPX_CODEC_CORRUPT_FRAME; } res = decode_one(ctx, &data_start_copy, frame_size, user_priv, deadline); if (res != VPX_CODEC_OK) return res; data_start += frame_size; } } else { while (data_start < data_end) { const uint32_t frame_size = (uint32_t) (data_end - data_start); const vpx_codec_err_t res = decode_one(ctx, &data_start, frame_size, user_priv, deadline); if (res != VPX_CODEC_OK) return res; // Account for suboptimal termination by the encoder. while (data_start < data_end) { const uint8_t marker = read_marker(ctx->decrypt_cb, ctx->decrypt_state, data_start); if (marker) break; ++data_start; } } } } return res; }
static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx, const uint8_t **data, unsigned int data_sz, void *user_priv, int64_t deadline) { const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); (void)deadline; // Determine the stream parameters. Note that we rely on peek_si to // validate that we have a buffer that does not wrap around the top // of the heap. if (!ctx->si.h) { int is_intra_only = 0; const vpx_codec_err_t res = decoder_peek_si_internal(*data, data_sz, &ctx->si, &is_intra_only, ctx->decrypt_cb, ctx->decrypt_state); if (res != VPX_CODEC_OK) return res; if (!ctx->si.is_kf && !is_intra_only) return VPX_CODEC_ERROR; } if (!ctx->frame_parallel_decode) { VPxWorker *const worker = ctx->frame_workers; FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1; frame_worker_data->data = *data; frame_worker_data->data_size = data_sz; frame_worker_data->user_priv = user_priv; frame_worker_data->received_frame = 1; // Set these even if already initialized. The caller may have changed the // decrypt config between frames. frame_worker_data->pbi->decrypt_cb = ctx->decrypt_cb; frame_worker_data->pbi->decrypt_state = ctx->decrypt_state; worker->had_error = 0; winterface->execute(worker); // Update data pointer after decode. *data = frame_worker_data->data_end; if (worker->had_error) return update_error_state(ctx, &frame_worker_data->pbi->common.error); check_resync(ctx, frame_worker_data->pbi); } else { VPxWorker *const worker = &ctx->frame_workers[ctx->next_submit_worker_id]; FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1; // Copy context from last worker thread to next worker thread. if (ctx->next_submit_worker_id != ctx->last_submit_worker_id) vp9_frameworker_copy_context( &ctx->frame_workers[ctx->next_submit_worker_id], &ctx->frame_workers[ctx->last_submit_worker_id]); frame_worker_data->pbi->ready_for_new_data = 0; // Copy the compressed data into worker's internal buffer. // TODO(hkuang): Will all the workers allocate the same size // as the size of the first intra frame be better? This will // avoid too many deallocate and allocate. if (frame_worker_data->scratch_buffer_size < data_sz) { frame_worker_data->scratch_buffer = (uint8_t *)vpx_realloc(frame_worker_data->scratch_buffer, data_sz); if (frame_worker_data->scratch_buffer == NULL) { set_error_detail(ctx, "Failed to reallocate scratch buffer"); return VPX_CODEC_MEM_ERROR; } frame_worker_data->scratch_buffer_size = data_sz; } frame_worker_data->data_size = data_sz; memcpy(frame_worker_data->scratch_buffer, *data, data_sz); frame_worker_data->frame_decoded = 0; frame_worker_data->frame_context_ready = 0; frame_worker_data->received_frame = 1; frame_worker_data->data = frame_worker_data->scratch_buffer; frame_worker_data->user_priv = user_priv; if (ctx->next_submit_worker_id != ctx->last_submit_worker_id) ctx->last_submit_worker_id = (ctx->last_submit_worker_id + 1) % ctx->num_frame_workers; ctx->next_submit_worker_id = (ctx->next_submit_worker_id + 1) % ctx->num_frame_workers; --ctx->available_threads; worker->had_error = 0; winterface->launch(worker); } return VPX_CODEC_OK; }
static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) { int i; const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); ctx->last_show_frame = -1; ctx->next_submit_worker_id = 0; ctx->last_submit_worker_id = 0; ctx->next_output_worker_id = 0; ctx->frame_cache_read = 0; ctx->frame_cache_write = 0; ctx->num_cache_frames = 0; ctx->need_resync = 1; ctx->num_frame_workers = (ctx->frame_parallel_decode == 1) ? ctx->cfg.threads: 1; if (ctx->num_frame_workers > MAX_DECODE_THREADS) ctx->num_frame_workers = MAX_DECODE_THREADS; ctx->available_threads = ctx->num_frame_workers; ctx->flushed = 0; ctx->buffer_pool = (BufferPool *)vpx_calloc(1, sizeof(BufferPool)); if (ctx->buffer_pool == NULL) return VPX_CODEC_MEM_ERROR; #if CONFIG_MULTITHREAD if (pthread_mutex_init(&ctx->buffer_pool->pool_mutex, NULL)) { set_error_detail(ctx, "Failed to allocate buffer pool mutex"); return VPX_CODEC_MEM_ERROR; } #endif ctx->frame_workers = (VPxWorker *) vpx_malloc(ctx->num_frame_workers * sizeof(*ctx->frame_workers)); if (ctx->frame_workers == NULL) { set_error_detail(ctx, "Failed to allocate frame_workers"); return VPX_CODEC_MEM_ERROR; } for (i = 0; i < ctx->num_frame_workers; ++i) { VPxWorker *const worker = &ctx->frame_workers[i]; FrameWorkerData *frame_worker_data = NULL; winterface->init(worker); worker->data1 = vpx_memalign(32, sizeof(FrameWorkerData)); if (worker->data1 == NULL) { set_error_detail(ctx, "Failed to allocate frame_worker_data"); return VPX_CODEC_MEM_ERROR; } frame_worker_data = (FrameWorkerData *)worker->data1; frame_worker_data->pbi = vp9_decoder_create(ctx->buffer_pool); if (frame_worker_data->pbi == NULL) { set_error_detail(ctx, "Failed to allocate frame_worker_data"); return VPX_CODEC_MEM_ERROR; } frame_worker_data->pbi->frame_worker_owner = worker; frame_worker_data->worker_id = i; frame_worker_data->scratch_buffer = NULL; frame_worker_data->scratch_buffer_size = 0; frame_worker_data->frame_context_ready = 0; frame_worker_data->received_frame = 0; #if CONFIG_MULTITHREAD if (pthread_mutex_init(&frame_worker_data->stats_mutex, NULL)) { set_error_detail(ctx, "Failed to allocate frame_worker_data mutex"); return VPX_CODEC_MEM_ERROR; } if (pthread_cond_init(&frame_worker_data->stats_cond, NULL)) { set_error_detail(ctx, "Failed to allocate frame_worker_data cond"); return VPX_CODEC_MEM_ERROR; } #endif // If decoding in serial mode, FrameWorker thread could create tile worker // thread or loopfilter thread. frame_worker_data->pbi->max_threads = (ctx->frame_parallel_decode == 0) ? ctx->cfg.threads : 0; frame_worker_data->pbi->inv_tile_order = ctx->invert_tile_order; frame_worker_data->pbi->frame_parallel_decode = ctx->frame_parallel_decode; frame_worker_data->pbi->common.frame_parallel_decode = ctx->frame_parallel_decode; worker->hook = (VPxWorkerHook)frame_worker_hook; if (!winterface->reset(worker)) { set_error_detail(ctx, "Frame Worker thread creation failed"); return VPX_CODEC_MEM_ERROR; } } // If postprocessing was enabled by the application and a // configuration has not been provided, default it. if (!ctx->postproc_cfg_set && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) set_default_ppflags(&ctx->postproc_cfg); init_buffer_callbacks(ctx); return VPX_CODEC_OK; }
static int run_command(struct Parser *parser, const char *cmd, const char *argline) { union Argument args[MAX_ARGS]; struct TableEnt *ent = NULL; int err = 0; ID id = SI_BADID; if (strcmp(cmd, "OpenPlugin") == 0) { err = parse_args("s", argline, args, MAX_ARGS); if (err) return -1; printf(PROMPT"%s: [%s]\n", cmd, args[0].str); err = SiOpenPlugin(args[0].str); if (err == SI_FAIL) { set_error_message(SiGetErrorNo()); set_errno(PSR_ERR_PLUGINNOTFOUND); return -1; } } else if (strcmp(cmd, "RenderScene") == 0) { err = parse_args("s", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } printf(PROMPT"%s: [%s]\n", cmd, args[0].str); err = SiRenderScene(EntGetID(ent)); if (err == SI_FAIL) { set_errno(PSR_ERR_FAILRENDER); return -1; } } else if (strcmp(cmd, "SaveFrameBuffer") == 0) { err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); err = SiSaveFrameBuffer(EntGetID(ent), args[1].str); if (err == SI_FAIL) { set_errno(PSR_ERR_FAILRENDER); return -1; } } else if (strcmp(cmd, "RunProcedure") == 0) { err = parse_args("s", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } printf(PROMPT"%s: [%s]\n", cmd, args[0].str); err = SiRunProcedure(EntGetID(ent)); if (err == SI_FAIL) { set_errno(PSR_ERR_FAILRENDER); return -1; } } else if (strcmp(cmd, "NewTurbulence") == 0) { err = parse_args("s", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: [%s]\n", cmd, args[0].str); id = SiNewTurbulence(); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewObjectInstance") == 0) { err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } ent = TblLookup(parser->table, args[1].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); id = SiNewObjectInstance(EntGetID(ent)); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewFrameBuffer") == 0) { err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); id = SiNewFrameBuffer(args[1].str); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewProcedure") == 0) { err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); id = SiNewProcedure(args[1].str); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewRenderer") == 0) { err = parse_args("s", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: [%s]\n", cmd, args[0].str); id = SiNewRenderer(); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewTexture") == 0) { err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); id = SiNewTexture(args[1].str); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewCamera") == 0) { err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: %s: %s\n", cmd, args[0].str, args[1].str); id = SiNewCamera(args[1].str); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewShader") == 0) { err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); id = SiNewShader(args[1].str); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewVolume") == 0) { err = parse_args("s", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: [%s]\n", cmd, args[0].str); id = SiNewVolume(); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewCurve") == 0) { err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); id = SiNewCurve(args[1].str); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewLight") == 0) { err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); id = SiNewLight(args[1].str); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "NewMesh") == 0) { err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; if (TblLookup(parser->table, args[0].str)) { set_errno(PSR_ERR_NAMEEXISTS); return -1; } printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); id = SiNewMesh(args[1].str); if (id == SI_BADID) { set_errno(PSR_ERR_FAILNEW); /* TODO better error message */ #if 0 set_error_detail(SiGetErrorMessage(SiGetErrorNo())); append_error_detail(": "); append_error_detail(args[1].str); #endif return -1; } TblAdd(parser->table, args[0].str, id); } else if (strcmp(cmd, "AssignShader") == 0) { ID obj_id, shader_id; err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } obj_id = EntGetID(ent); ent = TblLookup(parser->table, args[1].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } shader_id = EntGetID(ent); printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); err = SiAssignShader(obj_id, shader_id); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else if (strcmp(cmd, "AssignTexture") == 0) { ID shader_id, tex_id; err = parse_args("sss", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } shader_id = EntGetID(ent); ent = TblLookup(parser->table, args[2].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } tex_id = EntGetID(ent); printf(PROMPT"%s: [%s] [%s] [%s]\n", cmd, args[0].str, args[1].str, args[2].str); err = SiAssignTexture(shader_id, args[1].str, tex_id); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else if (strcmp(cmd, "AssignCamera") == 0) { ID renderer_id, camera_id; err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } renderer_id = EntGetID(ent); ent = TblLookup(parser->table, args[1].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } camera_id = EntGetID(ent); printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); err = SiAssignCamera(renderer_id, camera_id); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else if (strcmp(cmd, "AssignFrameBuffer") == 0) { ID renderer_id, framebuffer_id; err = parse_args("ss", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } renderer_id = EntGetID(ent); ent = TblLookup(parser->table, args[1].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } framebuffer_id = EntGetID(ent); printf(PROMPT"%s: [%s] [%s]\n", cmd, args[0].str, args[1].str); err = SiAssignFrameBuffer(renderer_id, framebuffer_id); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else if (strcmp(cmd, "AssignTurbulence") == 0) { ID id, turbulence_id; err = parse_args("sss", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } id = EntGetID(ent); ent = TblLookup(parser->table, args[2].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } turbulence_id = EntGetID(ent); printf(PROMPT"%s: [%s] [%s] [%s]\n", cmd, args[0].str, args[1].str, args[2].str); err = SiAssignTurbulence(id, args[1].str, turbulence_id); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else if (strcmp(cmd, "AssignVolume") == 0) { ID id, volume_id; err = parse_args("sss", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } id = EntGetID(ent); ent = TblLookup(parser->table, args[2].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } volume_id = EntGetID(ent); printf(PROMPT"%s: [%s] [%s] [%s]\n", cmd, args[0].str, args[1].str, args[2].str); err = SiAssignVolume(id, args[1].str, volume_id); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else if (strcmp(cmd, "SetProperty1") == 0) { err = parse_args("ssf", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } printf(PROMPT"%s: [%s] [%s] [%g]\n", cmd, args[0].str, args[1].str, args[2].dbl); err = SiSetProperty1(EntGetID(ent), args[1].str, args[2].dbl); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else if (strcmp(cmd, "SetProperty2") == 0) { err = parse_args("ssff", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } printf(PROMPT"%s: [%s] [%s] [%g] [%g]\n", cmd, args[0].str, args[1].str, args[2].dbl, args[3].dbl); err = SiSetProperty2(EntGetID(ent), args[1].str, args[2].dbl, args[3].dbl); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else if (strcmp(cmd, "SetProperty3") == 0) { err = parse_args("ssfff", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } printf(PROMPT"%s: [%s] [%s] [%g] [%g] [%g]\n", cmd, args[0].str, args[1].str, args[2].dbl, args[3].dbl, args[4].dbl); /* TODO check set property error */ err = SiSetProperty3(EntGetID(ent), args[1].str, args[2].dbl, args[3].dbl, args[4].dbl); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else if (strcmp(cmd, "SetProperty4") == 0) { err = parse_args("ssffff", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } printf(PROMPT"%s: [%s] [%s] [%g] [%g] [%g] [%g]\n", cmd, args[0].str, args[1].str, args[2].dbl, args[3].dbl, args[4].dbl, args[5].dbl); err = SiSetProperty4(EntGetID(ent), args[1].str, args[2].dbl, args[3].dbl, args[4].dbl, args[5].dbl); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else if (strcmp(cmd, "ShowPropertyList") == 0) { err = parse_args("s", argline, args, MAX_ARGS); if (err) return -1; printf(PROMPT"%s: [%s]\n", cmd, args[0].str); { const char **prop_types = NULL; const char **prop_names = NULL; const char *type_name = args[0].str; int nprops = 0; int err = 0; int i = 0; err = SiGetPropertyList(type_name, &prop_types, &prop_names, &nprops); if (err) { printf("# No property is available for %s\n", type_name); printf("# Make sure the type name is correct.\n"); printf("# If you requested properties for a plugin,\n"); printf("# make sure it is opened before calling this command.\n"); return -1; } printf("# %s Properties\n", type_name); for (i = 0; i < nprops; i++) { printf("# %15.15s : %-20.20s\n", prop_types[i], prop_names[i]); } } } /* TODO TEST SetSampleProperty3 */ else if (strcmp(cmd, "SetSampleProperty3") == 0) { err = parse_args("ssffff", argline, args, MAX_ARGS); if (err) return -1; ent = TblLookup(parser->table, args[0].str); if (ent == NULL) { set_errno(PSR_ERR_NAMENOTFOUND); return -1; } printf(PROMPT"%s: [%s] [%s] [%g] [%g] [%g] [%g]\n", cmd, args[0].str, args[1].str, args[2].dbl, args[3].dbl, args[4].dbl, args[5].dbl); /* TODO check set property error */ err = SiSetSampleProperty3(EntGetID(ent), args[1].str, args[2].dbl, args[3].dbl, args[4].dbl, args[5].dbl); if (err) { set_errno(PSR_ERR_FAILSETPROP); return -1; } } else { set_errno(PSR_ERR_UNKNOWNCMD); return -1; } return 0; }