bool ArchiveDataClient::getValues(int key, stdVector<stdString> &names, const epicsTime &start, const epicsTime &end, int count, int how, value_callback callback, void *callback_arg) { xmlrpc_value *name_array, *result, *element; size_t n; name_array = xmlrpc_build_value(&env, "()"); if (log_fault()) return false; for (n=0; n<names.size(); ++n) { element = xmlrpc_build_value(&env, "s", names[n].c_str()); if (log_fault()) return false; xmlrpc_array_append_item(&env, name_array, element); if (log_fault()) return false; xmlrpc_DECREF(element); } xmlrpc_int32 start_sec, start_nano, end_sec, end_nano; epicsTime2pieces(start, start_sec, start_nano); epicsTime2pieces(end, end_sec, end_nano); result = xmlrpc_client_call(&env, (char *)URL, "archiver.values", "(iViiiiii)", (xmlrpc_int32)key, name_array, start_sec, start_nano, end_sec, end_nano, (xmlrpc_int32)count, (xmlrpc_int32)how); if (log_fault()) return false; xmlrpc_DECREF(name_array); size_t channel_count = xmlrpc_array_size(&env, result); xmlrpc_value *channel_result; for (n=0; n<channel_count; ++n) { channel_result = xmlrpc_array_get_item(&env, result, n); if (log_fault()) return false; if (!decode_channel(channel_result, n, callback, callback_arg)) return false; } xmlrpc_DECREF(result); return true; }
yuv_image decode_frame(const xyuv::frame &frame_in) { // Determine the size of each plane. bool has_y = !frame_in.format.channel_blocks[channel::Y].samples.empty(); bool has_u = !frame_in.format.channel_blocks[channel::U].samples.empty(); bool has_v = !frame_in.format.channel_blocks[channel::V].samples.empty(); bool has_a = !frame_in.format.channel_blocks[channel::A].samples.empty(); yuv_image yuva_out = create_yuv_image( frame_in.format.image_w, frame_in.format.image_h, frame_in.format.chroma_siting, has_y, has_u, has_v, has_a ); bool has_negative_line_stride = (frame_in.format.origin == image_origin::LOWER_LEFT); const uint8_t * raw_data = frame_in.data.get(); std::unique_ptr<uint8_t> tmp_buffer; if (needs_reorder(frame_in.format)) { // Todo: If needed optimize this for memory. // At some point we will have allocated 2x frame + 1 plane. tmp_buffer.reset(new uint8_t[frame_in.format.size]); memcpy(tmp_buffer.get(), raw_data, frame_in.format.size); // Use the copy instead. raw_data = tmp_buffer.get(); for (auto & plane : frame_in.format.planes) { reorder_inverse(tmp_buffer.get(), plane); } } if (has_y) decode_channel( raw_data, frame_in.format.channel_blocks[channel::Y], &(yuva_out.y_plane), frame_in.format.planes, frame_in.format.conversion_matrix.y_packed_range, has_negative_line_stride ); if (has_u) decode_channel( raw_data, frame_in.format.channel_blocks[channel::U], &(yuva_out.u_plane), frame_in.format.planes, frame_in.format.conversion_matrix.u_packed_range, has_negative_line_stride ); if (has_v) decode_channel( raw_data, frame_in.format.channel_blocks[channel::V], &(yuva_out.v_plane), frame_in.format.planes, frame_in.format.conversion_matrix.v_packed_range, has_negative_line_stride ); if (has_a) decode_channel( raw_data, frame_in.format.channel_blocks[channel::A], &(yuva_out.a_plane), frame_in.format.planes, std::make_pair<float, float>(0.0f, 1.0f), has_negative_line_stride ); return yuva_out; }