+static uint64_t ns_from_value(uint64_t frequency, uint64_t value)
+{
+ uint64_t ns;
+
+ if (frequency == NSEC_PER_SEC) {
+ ns = value;
+ } else {
+ ns = (uint64_t) ((1e9 * (double) value) / (double) frequency);
+ }
+
+ return ns;
+}
+
+/*
+ * timestamp minus the offset.
+ */
+static
+int64_t get_raw_timestamp(const struct bt_packet *writer_packet,
+ int64_t timestamp)
+{
+ const struct bt_clock_class *writer_clock_class;
+ int64_t sec_offset, cycles_offset, ns;
+ const struct bt_trace *writer_trace;
+ const struct bt_stream *writer_stream;
+ const struct bt_stream_class *writer_stream_class;
+ int ret;
+ uint64_t freq;
+
+ writer_stream = bt_packet_get_stream(writer_packet);
+ BT_ASSERT(writer_stream);
+
+ writer_stream_class = bt_stream_get_class(writer_stream);
+ BT_ASSERT(writer_stream_class);
+
+ writer_trace = bt_stream_class_get_trace(writer_stream_class);
+ BT_ASSERT(writer_trace);
+
+ /* FIXME multi-clock? */
+ writer_clock_class = bt_trace_get_clock_class_by_index(
+ writer_trace, 0);
+ BT_ASSERT(writer_clock_class);
+
+ ret = bt_clock_class_get_offset_s(writer_clock_class, &sec_offset);
+ BT_ASSERT(!ret);
+ ns = sec_offset * NSEC_PER_SEC;
+
+ freq = bt_clock_class_get_frequency(writer_clock_class);
+ BT_ASSERT(freq != -1ULL);
+
+ ret = bt_clock_class_get_offset_cycles(writer_clock_class, &cycles_offset);
+ BT_ASSERT(!ret);
+
+ ns += ns_from_value(freq, cycles_offset);
+
+ bt_object_put_ref(writer_clock_class);
+ bt_object_put_ref(writer_trace);
+ bt_object_put_ref(writer_stream_class);
+ bt_object_put_ref(writer_stream);
+
+ return timestamp - ns;
+}
+