diff mbox

[FFmpeg-devel,02/10] crc: add av_crc_bits() to compute CRC on block with bit boundary

Message ID 20171220195814.18269-2-aurel@gnuage.org
State New
Headers show

Commit Message

Aurelien Jacobs Dec. 20, 2017, 7:58 p.m. UTC
---
 libavutil/crc.c | 20 ++++++++++++++++++++
 libavutil/crc.h | 12 ++++++++++++
 2 files changed, 32 insertions(+)

Comments

Rostislav Pehlivanov Dec. 21, 2017, 11:39 a.m. UTC | #1
On 20 December 2017 at 19:58, Aurelien Jacobs <aurel@gnuage.org> wrote:

> ---
>  libavutil/crc.c | 20 ++++++++++++++++++++
>  libavutil/crc.h | 12 ++++++++++++
>  2 files changed, 32 insertions(+)
>
> diff --git a/libavutil/crc.c b/libavutil/crc.c
> index 8e44a76ec8..cb26a09a20 100644
> --- a/libavutil/crc.c
> +++ b/libavutil/crc.c
> @@ -413,3 +413,23 @@ uint32_t av_crc(const AVCRC *ctx, uint32_t crc,
>
>      return crc;
>  }
> +
> +uint32_t av_crc_bits(const AVCRC *ctx, uint32_t crc,
> +                     const uint8_t *buffer, size_t length)
> +{
> +    size_t byte_length = length >> 3;
> +    int bit_length = length & 7;
> +
> +    crc = av_crc(ctx, crc, buffer, byte_length);
> +
> +    if (bit_length) {
> +        uint8_t bits = buffer[byte_length];
> +        while (bit_length--) {
> +            int8_t mask = (bits ^ crc);
> +            crc = (crc << 1) ^ (ctx[1] & (mask >> 7));
> +            bits <<= 1;
> +        }
> +    }
> +
> +    return crc;
> +}
> diff --git a/libavutil/crc.h b/libavutil/crc.h
> index e57a1af903..bde31f858a 100644
> --- a/libavutil/crc.h
> +++ b/libavutil/crc.h
> @@ -86,6 +86,7 @@ const AVCRC *av_crc_get_table(AVCRCId crc_id);
>  /**
>   * Calculate the CRC of a block.
>   * @param crc CRC of previous blocks if any or initial value for CRC
> + * @param length number of bytes in the given block
>   * @return CRC updated with the data from the given block
>   *
>   * @see av_crc_init() "le" parameter
> @@ -93,6 +94,17 @@ const AVCRC *av_crc_get_table(AVCRCId crc_id);
>  uint32_t av_crc(const AVCRC *ctx, uint32_t crc,
>                  const uint8_t *buffer, size_t length) av_pure;
>
> +/**
> + * Calculate the CRC of a block with bits boundary.
> + * @param crc CRC of previous blocks if any or initial value for CRC
> + * @param length number of bits in the given block
> + * @return CRC updated with the data from the given block
> + *
> + * @see av_crc_init() "le" parameter
> + */
> +uint32_t av_crc_bits(const AVCRC *ctx, uint32_t crc,
> +                     const uint8_t *buffer, size_t length) av_pure;
> +
>  /**
>   * @}
>   */
> --
> 2.15.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>

Sorry, I didn't see that sbc does fucked up crc on 7 bits.
In that case could you submit a new version of just the sbc patch which
adds this back in the decoder?
If you can point out another CRC, even a non-multimedia one, which does
calculations on a non-byte aligned (but continuous, without skipping bits)
buffer I'd accept this patch though.
Aurelien Jacobs Dec. 23, 2017, 6 p.m. UTC | #2
On Thu, Dec 21, 2017 at 11:39:02AM +0000, Rostislav Pehlivanov wrote:
> On 20 December 2017 at 19:58, Aurelien Jacobs <aurel@gnuage.org> wrote:
> 
> > ---
> >  libavutil/crc.c | 20 ++++++++++++++++++++
> >  libavutil/crc.h | 12 ++++++++++++
> >  2 files changed, 32 insertions(+)
> >
> > diff --git a/libavutil/crc.c b/libavutil/crc.c
> > index 8e44a76ec8..cb26a09a20 100644
> > --- a/libavutil/crc.c
> > +++ b/libavutil/crc.c
> > @@ -413,3 +413,23 @@ uint32_t av_crc(const AVCRC *ctx, uint32_t crc,
> >
> >      return crc;
> >  }
> > +
> > +uint32_t av_crc_bits(const AVCRC *ctx, uint32_t crc,
> > +                     const uint8_t *buffer, size_t length)
> > +{
> > +    size_t byte_length = length >> 3;
> > +    int bit_length = length & 7;
> > +
> > +    crc = av_crc(ctx, crc, buffer, byte_length);
> > +
> > +    if (bit_length) {
> > +        uint8_t bits = buffer[byte_length];
> > +        while (bit_length--) {
> > +            int8_t mask = (bits ^ crc);
> > +            crc = (crc << 1) ^ (ctx[1] & (mask >> 7));
> > +            bits <<= 1;
> > +        }
> > +    }
> > +
> > +    return crc;
> > +}
> > diff --git a/libavutil/crc.h b/libavutil/crc.h
> > index e57a1af903..bde31f858a 100644
> > --- a/libavutil/crc.h
> > +++ b/libavutil/crc.h
> > @@ -86,6 +86,7 @@ const AVCRC *av_crc_get_table(AVCRCId crc_id);
> >  /**
> >   * Calculate the CRC of a block.
> >   * @param crc CRC of previous blocks if any or initial value for CRC
> > + * @param length number of bytes in the given block
> >   * @return CRC updated with the data from the given block
> >   *
> >   * @see av_crc_init() "le" parameter
> > @@ -93,6 +94,17 @@ const AVCRC *av_crc_get_table(AVCRCId crc_id);
> >  uint32_t av_crc(const AVCRC *ctx, uint32_t crc,
> >                  const uint8_t *buffer, size_t length) av_pure;
> >
> > +/**
> > + * Calculate the CRC of a block with bits boundary.
> > + * @param crc CRC of previous blocks if any or initial value for CRC
> > + * @param length number of bits in the given block
> > + * @return CRC updated with the data from the given block
> > + *
> > + * @see av_crc_init() "le" parameter
> > + */
> > +uint32_t av_crc_bits(const AVCRC *ctx, uint32_t crc,
> > +                     const uint8_t *buffer, size_t length) av_pure;
> > +
> >  /**
> >   * @}
> >   */
> >
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> 
> Sorry, I didn't see that sbc does fucked up crc on 7 bits.

Well, it is not on 7 bits. That actual data length is a multiple of
4 bits.

> In that case could you submit a new version of just the sbc patch which
> adds this back in the decoder?

I moved the function back to sbc, but I keept its usage of av_crc() for
the whole buffer except for the last bits that don't form a full byte.
diff mbox

Patch

diff --git a/libavutil/crc.c b/libavutil/crc.c
index 8e44a76ec8..cb26a09a20 100644
--- a/libavutil/crc.c
+++ b/libavutil/crc.c
@@ -413,3 +413,23 @@  uint32_t av_crc(const AVCRC *ctx, uint32_t crc,
 
     return crc;
 }
+
+uint32_t av_crc_bits(const AVCRC *ctx, uint32_t crc,
+                     const uint8_t *buffer, size_t length)
+{
+    size_t byte_length = length >> 3;
+    int bit_length = length & 7;
+
+    crc = av_crc(ctx, crc, buffer, byte_length);
+
+    if (bit_length) {
+        uint8_t bits = buffer[byte_length];
+        while (bit_length--) {
+            int8_t mask = (bits ^ crc);
+            crc = (crc << 1) ^ (ctx[1] & (mask >> 7));
+            bits <<= 1;
+        }
+    }
+
+    return crc;
+}
diff --git a/libavutil/crc.h b/libavutil/crc.h
index e57a1af903..bde31f858a 100644
--- a/libavutil/crc.h
+++ b/libavutil/crc.h
@@ -86,6 +86,7 @@  const AVCRC *av_crc_get_table(AVCRCId crc_id);
 /**
  * Calculate the CRC of a block.
  * @param crc CRC of previous blocks if any or initial value for CRC
+ * @param length number of bytes in the given block
  * @return CRC updated with the data from the given block
  *
  * @see av_crc_init() "le" parameter
@@ -93,6 +94,17 @@  const AVCRC *av_crc_get_table(AVCRCId crc_id);
 uint32_t av_crc(const AVCRC *ctx, uint32_t crc,
                 const uint8_t *buffer, size_t length) av_pure;
 
+/**
+ * Calculate the CRC of a block with bits boundary.
+ * @param crc CRC of previous blocks if any or initial value for CRC
+ * @param length number of bits in the given block
+ * @return CRC updated with the data from the given block
+ *
+ * @see av_crc_init() "le" parameter
+ */
+uint32_t av_crc_bits(const AVCRC *ctx, uint32_t crc,
+                     const uint8_t *buffer, size_t length) av_pure;
+
 /**
  * @}
  */