[10/39] firewire-lib: Add transfer delay to synchronized duplex streams
diff mbox

Message ID 1394016507-15761-11-git-send-email-o-takashi@sakamocchi.jp
State Superseded
Delegated to: Takashi Iwai
Headers show

Commit Message

Takashi Sakamoto March 5, 2014, 10:47 a.m. UTC
Currently, in duplex streams with synchronization mode, this module just pass
'presentation timestamp' from in-packets to out-packets. This is enough to
handle actual device but logically the timestamp should include
'transfer delay' and 'processing time'. This means the timestamp in out-packet
should be at future.

To be simple, this commit add only 'transfer delay'.
---
 sound/firewire/amdtp.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

Comments

Clemens Ladisch March 9, 2014, 9:13 p.m. UTC | #1
Takashi Sakamoto wrote:
> Currently, in duplex streams with synchronization mode, this module just pass
> 'presentation timestamp' from in-packets to out-packets. This is enough to
> handle actual device but logically the timestamp should include
> 'transfer delay' and 'processing time'. This means the timestamp in out-packet
> should be at future.
>
> To be simple, this commit add only 'transfer delay'.

> +		*syt += (s->transfer_delay / TICKS_PER_CYCLE) << 12;
> +		*syt += s->transfer_delay % TICKS_PER_CYCLE;
> +		*syt &= CIP_SYT_MASK;

The transfer delay is the offset between the frame in which the packet
is transmitted and the intended presentation time.  This delay was
already added by the device when it sent the input packets, so we
don't need to send it again.

The frame in which the out-packet will be sent is QUEUE_LENGTH
frames later than that of the in-packet, so we need to adjust the
SYT by that amount.  (However, 48 % 16 == 0.)


Regards,
Clemens
Takashi Sakamoto March 10, 2014, 1:43 p.m. UTC | #2
(mar 10 2014 06:13), Clemens Ladisch wrote:
> The transfer delay is the offset between the frame in which the packet
> is transmitted and the intended presentation time.  This delay was
> already added by the device when it sent the input packets, so we
> don't need to send it again.

Exactly. Adding TRANSFER_DELAY for out-packets is needless...

IEC 61883-6 said:
"If a function block receives a CIP, processes it and subsequently 
re-transmits it, then the SYT of the outgoing CIP shall be the sum of 
the incoming SYT and the processing delay."

> The frame in which the out-packet will be sent is QUEUE_LENGTH
> frames later than that of the in-packet, so we need to adjust the
> SYT by that amount.  (However, 48 % 16 == 0.)

So basically we need to add nothing to SYT for out-packet.
This patch should be removed.


Thanks

Takashi Sakamoto
o-takashi@sakamocchi.jp
Clemens Ladisch March 11, 2014, 8:13 a.m. UTC | #3
Takashi Sakamoto wrote:
> (mar 10 2014 06:13), Clemens Ladisch wrote:
>> The frame in which the out-packet will be sent is QUEUE_LENGTH
>> frames later than that of the in-packet, so we need to adjust the
>> SYT by that amount.  (However, 48 % 16 == 0.)
>
> So basically we need to add nothing to SYT for out-packet.

It would be possible to do the QUEUE_LENGTH adjustment in the code and
rely on the compiler to optimize it away, but that would be silly.
OTOH a comment might be useful.


Regards,
Clemens

Patch
diff mbox

diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c
index d3cf7bf..9383392 100644
--- a/sound/firewire/amdtp.c
+++ b/sound/firewire/amdtp.c
@@ -774,6 +774,15 @@  static void packet_sort(struct sort_table *tbl, unsigned int len)
 	} while (i < len);
 }
 
+static inline void add_transfer_delay(struct amdtp_stream *s, unsigned int *syt)
+{
+	if (*syt != CIP_SYT_NO_INFO) {
+		*syt += (s->transfer_delay / TICKS_PER_CYCLE) << 12;
+		*syt += s->transfer_delay % TICKS_PER_CYCLE;
+		*syt &= CIP_SYT_MASK;
+	}
+}
+
 static void out_stream_callback(struct fw_iso_context *context, u32 cycle,
 				size_t header_length, void *header,
 				void *private_data)
@@ -846,6 +855,7 @@  static void in_stream_callback(struct fw_iso_context *context, u32 cycle,
 			    (s->flags & CIP_SYNC_TO_DEVICE) &&
 			    s->sync_slave->callbacked) {
 				syt = be32_to_cpu(buffer[1]) & CIP_SYT_MASK;
+				add_transfer_delay(s, &syt);
 				handle_out_packet(s->sync_slave, syt);
 			}
 			handle_in_packet(s, tbl[i].payload_size / 4, buffer);