From 80c9fd28a6f926850b39df310e1736d45317ac5c Mon Sep 17 00:00:00 2001 From: Brant Thomsen Date: Wed, 6 Dec 2017 16:24:00 -0700 Subject: Added EXTENDED_SEQUENCE_NUMBERS option Added support for extended sequence numbers, which is a non-standard way to increase the number of bits (from 8 to 12) for sequence numbers in AVTP frames. This is useful for Wi-Fi with retries, which can drop large numbers of sequential frames. To enable this feature, uncomment the EXTENDED_SEQUENCE_NUMBERS define. The feature is currently disabled. --- lib/avtp_pipeline/avtp/openavb_avtp.c | 84 +++++++++++++++++----- lib/avtp_pipeline/avtp/openavb_avtp.h | 11 +++ lib/avtp_pipeline/include/openavb_map_pub.h | 2 +- .../map_aaf_audio/openavb_map_aaf_audio.c | 2 +- 4 files changed, 80 insertions(+), 19 deletions(-) diff --git a/lib/avtp_pipeline/avtp/openavb_avtp.c b/lib/avtp_pipeline/avtp/openavb_avtp.c index cfea6adc..a753dff0 100644 --- a/lib/avtp_pipeline/avtp/openavb_avtp.c +++ b/lib/avtp_pipeline/avtp/openavb_avtp.c @@ -322,12 +322,23 @@ static openavbRC fillAvtpHdr(avtp_stream_t *pStream, U8 *pFill) // - 1 bit tv (timestamp valid) = 1 // TODO: set mr correctly *pFill++ = 0x81; +#ifdef EXTENDED_SEQUENCE_NUMBERS + // - 8 bits sequence num = increments with each frame + *pFill++ = (pStream->avtp_sequence_num & 0x00FF); + // - 4 bits upper bits of sequence num = increments every 256 frames + // - 1 bit using extended seq numbers = 1 + // - 2 bits reserved = 0 + // - 1 bit tu (timestamp uncertain) = 1 when no PTP sync + // TODO: set tu correctly + *pFill++ = (U8) ((pStream->avtp_sequence_num & 0x0F00) >> 4) | 0x08; +#else // - 8 bits sequence num = increments with each frame *pFill++ = pStream->avtp_sequence_num; - // - 7 bits reserved = 0; + // - 7 bits reserved = 0 // - 1 bit tu (timestamp uncertain) = 1 when no PTP sync // TODO: set tu correctly *pFill++ = 0; +#endif // - 8 bytes stream_id memcpy(pFill, (U8 *)&pStream->streamIDnet, 8); break; @@ -424,7 +435,11 @@ openavbRC openavbAvtpTx(void *pv, bool bSend, bool txBlockingInIntf) } // Increment the sequence number now that we are sure this is a good packet. +#ifdef EXTENDED_SEQUENCE_NUMBERS + pStream->avtp_sequence_num = ((pStream->avtp_sequence_num + 1) & 0x0FFF); +#else pStream->avtp_sequence_num++; +#endif // Mirror the frame. int i; @@ -544,8 +559,13 @@ static void x_avtpRxFrame(avtp_stream_t *pStream, U8 *pFrame, U32 frameLen) { AVB_TRACE_ENTRY(AVB_TRACE_AVTP_DETAIL); IF_LOG_INTERVAL(4096) AVB_LOGF_DEBUG("pFrame=%p, len=%u", pFrame, frameLen); - U8 subtype, flags, flags2, rxSeq, nLost, avtpVersion; + U8 subtype, flags, flags2, avtpVersion; U8 *pRead = pFrame; +#ifdef EXTENDED_SEQUENCE_NUMBERS + U16 rxSeq, nLost; +#else + U8 rxSeq, nLost; +#endif // AVTP Header // @@ -561,23 +581,53 @@ static void x_avtpRxFrame(avtp_stream_t *pStream, U8 *pFrame, U32 frameLen) rxSeq = *pRead++; - if (pStream->nLost == -1) { - // first frame received, don't check for mismatch - pStream->nLost = 0; - } - else if (pStream->avtp_sequence_num != rxSeq) { - nLost = (rxSeq - pStream->avtp_sequence_num) - + (rxSeq < pStream->avtp_sequence_num ? 256 : 0); - AVB_LOGF_INFO("AVTP sequence mismatch: expected: %3u,\tgot: %3u,\tlost %3d", - pStream->avtp_sequence_num, rxSeq, nLost); - pStream->nLost += nLost; - - // Notify the map that frames were lost. - if (pStream->pMapCB->map_rx_lost_cb) { - pStream->pMapCB->map_rx_lost_cb(pStream->pMediaQ, nLost); +#ifdef EXTENDED_SEQUENCE_NUMBERS + if ((*pRead & 0x08) != 0) { + // Get the upper 4 bits of the sequence number. + rxSeq |= (((U16) (*pRead & 0xF0)) << 4); + + if (pStream->nLost == -1) { + // first frame received, don't check for mismatch + pStream->nLost = 0; + } + else if (pStream->avtp_sequence_num != rxSeq) { + nLost = (rxSeq - pStream->avtp_sequence_num) + + (rxSeq < pStream->avtp_sequence_num ? 0x1000 : 0); + AVB_LOGF_INFO("AVTP sequence mismatch: expected: %4u,\tgot: %4u,\tlost %4d", + pStream->avtp_sequence_num, rxSeq, nLost); + pStream->nLost += nLost; + + // Notify the map that frames were lost. + if (pStream->pMapCB->map_rx_lost_cb) { + pStream->pMapCB->map_rx_lost_cb(pStream->pMediaQ, nLost); + } + } + pStream->avtp_sequence_num = ((rxSeq + 1) & 0x0FFF); + } else +#endif + { + if (pStream->nLost == -1) { + // first frame received, don't check for mismatch + pStream->nLost = 0; + } + else if (pStream->avtp_sequence_num != rxSeq) { + nLost = (rxSeq - pStream->avtp_sequence_num) + + (rxSeq < pStream->avtp_sequence_num ? 0x100 : 0); + AVB_LOGF_INFO("AVTP sequence mismatch: expected: %3u,\tgot: %3u,\tlost %3d", + pStream->avtp_sequence_num, rxSeq, nLost); + pStream->nLost += nLost; + + // Notify the map that frames were lost. + if (pStream->pMapCB->map_rx_lost_cb) { + pStream->pMapCB->map_rx_lost_cb(pStream->pMediaQ, nLost); + } } +#ifdef EXTENDED_SEQUENCE_NUMBERS + pStream->avtp_sequence_num = ((rxSeq + 1) & 0x00FF); +#else + pStream->avtp_sequence_num = rxSeq + 1; +#endif } - pStream->avtp_sequence_num = rxSeq + 1; pStream->bytes += frameLen; diff --git a/lib/avtp_pipeline/avtp/openavb_avtp.h b/lib/avtp_pipeline/avtp/openavb_avtp.h index 71139271..eb163373 100644 --- a/lib/avtp_pipeline/avtp/openavb_avtp.h +++ b/lib/avtp_pipeline/avtp/openavb_avtp.h @@ -83,6 +83,13 @@ typedef struct { } avtp_state_t; +/* If EXTENDED_SEQUENCE_NUMBERS is defined, uses the 4 most significant bits of the reserved space + * immediately following the sequence_num value to allow for larger sequence numbers. + * The bit following those 4 bits is also set to indicate that + * extended sequence numbers are in use. + */ +//#define EXTENDED_SEQUENCE_NUMBERS + /* Info associated with an AVTP stream (RX or TX). * * The void* handle that is returned to the client @@ -117,7 +124,11 @@ typedef struct // Max frame size U16 frameLen; // AVTP sequence number +#ifdef EXTENDED_SEQUENCE_NUMBERS + U16 avtp_sequence_num; +#else U8 avtp_sequence_num; +#endif // Paused state of the stream bool bPause; // Encapsulation-specific state information diff --git a/lib/avtp_pipeline/include/openavb_map_pub.h b/lib/avtp_pipeline/include/openavb_map_pub.h index 8e4abeea..feb8a9e5 100755 --- a/lib/avtp_pipeline/include/openavb_map_pub.h +++ b/lib/avtp_pipeline/include/openavb_map_pub.h @@ -141,7 +141,7 @@ typedef bool (*openavb_map_rx_cb_t)(media_q_t *pMediaQ, U8 *pData, U32 datalen); * \param pMediaQ A pointer to the media queue for this stream * \param numLost The number of sequence numbers missing (i.e. number of lost packets) */ -typedef bool (*openavb_map_rx_lost_cb_t)(media_q_t *pMediaQ, U8 numLost); +typedef bool (*openavb_map_rx_lost_cb_t)(media_q_t *pMediaQ, U16 numLost); /** This callback will be called when the stream is closing. * diff --git a/lib/avtp_pipeline/map_aaf_audio/openavb_map_aaf_audio.c b/lib/avtp_pipeline/map_aaf_audio/openavb_map_aaf_audio.c index e3a5906a..12636619 100755 --- a/lib/avtp_pipeline/map_aaf_audio/openavb_map_aaf_audio.c +++ b/lib/avtp_pipeline/map_aaf_audio/openavb_map_aaf_audio.c @@ -1063,7 +1063,7 @@ bool openavbMapAVTPAudioRxCB(media_q_t *pMediaQ, U8 *pData, U32 dataLen) } // This callback occurs when running as a listener and data is not available. -bool openavbMapAVTPAudioRxLostCB(media_q_t *pMediaQ, U8 numLost) +bool openavbMapAVTPAudioRxLostCB(media_q_t *pMediaQ, U16 numLost) { AVB_TRACE_ENTRY(AVB_TRACE_MAP_DETAIL); -- cgit v1.2.1