LCOV - code coverage report
Current view: top level - libavcodec - put_bits.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 103 138 74.6 %
Date: 2017-12-13 10:57:33 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /*
       2             :  * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public
       8             :  * License as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with FFmpeg; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : /**
      22             :  * @file
      23             :  * bitstream writer API
      24             :  */
      25             : 
      26             : #ifndef AVCODEC_PUT_BITS_H
      27             : #define AVCODEC_PUT_BITS_H
      28             : 
      29             : #include <stdint.h>
      30             : #include <stddef.h>
      31             : 
      32             : #include "libavutil/intreadwrite.h"
      33             : #include "libavutil/avassert.h"
      34             : 
      35             : typedef struct PutBitContext {
      36             :     uint32_t bit_buf;
      37             :     int bit_left;
      38             :     uint8_t *buf, *buf_ptr, *buf_end;
      39             :     int size_in_bits;
      40             : } PutBitContext;
      41             : 
      42             : /**
      43             :  * Initialize the PutBitContext s.
      44             :  *
      45             :  * @param buffer the buffer where to put bits
      46             :  * @param buffer_size the size in bytes of buffer
      47             :  */
      48     9513930 : static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
      49             :                                  int buffer_size)
      50             : {
      51     9513930 :     if (buffer_size < 0) {
      52           0 :         buffer_size = 0;
      53           0 :         buffer      = NULL;
      54             :     }
      55             : 
      56     9513930 :     s->size_in_bits = 8 * buffer_size;
      57     9513930 :     s->buf          = buffer;
      58     9513930 :     s->buf_end      = s->buf + buffer_size;
      59     9513930 :     s->buf_ptr      = s->buf;
      60     9513930 :     s->bit_left     = 32;
      61     9513930 :     s->bit_buf      = 0;
      62     9513930 : }
      63             : 
      64             : /**
      65             :  * Rebase the bit writer onto a reallocated buffer.
      66             :  *
      67             :  * @param buffer the buffer where to put bits
      68             :  * @param buffer_size the size in bytes of buffer,
      69             :  *                    must be larger than the previous size
      70             :  */
      71          25 : static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
      72             :                                    int buffer_size)
      73             : {
      74          25 :     av_assert0(8*buffer_size > s->size_in_bits);
      75             : 
      76          25 :     s->buf_end = buffer + buffer_size;
      77          25 :     s->buf_ptr = buffer + (s->buf_ptr - s->buf);
      78          25 :     s->buf     = buffer;
      79          25 :     s->size_in_bits = 8 * buffer_size;
      80          25 : }
      81             : 
      82             : /**
      83             :  * @return the total number of bits written to the bitstream.
      84             :  */
      85    31952551 : static inline int put_bits_count(PutBitContext *s)
      86             : {
      87    31952551 :     return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
      88             : }
      89             : 
      90             : /**
      91             :  * @return the number of bits available in the bitstream.
      92             :  */
      93   109975419 : static inline int put_bits_left(PutBitContext* s)
      94             : {
      95   109975419 :     return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left;
      96             : }
      97             : 
      98             : /**
      99             :  * Pad the end of the output stream with zeros.
     100             :  */
     101    10673340 : static inline void flush_put_bits(PutBitContext *s)
     102             : {
     103             : #ifndef BITSTREAM_WRITER_LE
     104    10671259 :     if (s->bit_left < 32)
     105    10139819 :         s->bit_buf <<= s->bit_left;
     106             : #endif
     107    42790628 :     while (s->bit_left < 32) {
     108    21443948 :         av_assert0(s->buf_ptr < s->buf_end);
     109             : #ifdef BITSTREAM_WRITER_LE
     110        4304 :         *s->buf_ptr++ = s->bit_buf;
     111        4304 :         s->bit_buf  >>= 8;
     112             : #else
     113    21439644 :         *s->buf_ptr++ = s->bit_buf >> 24;
     114    21439644 :         s->bit_buf  <<= 8;
     115             : #endif
     116    21443948 :         s->bit_left  += 8;
     117             :     }
     118    10673340 :     s->bit_left = 32;
     119    10673340 :     s->bit_buf  = 0;
     120    10673340 : }
     121             : 
     122           0 : static inline void flush_put_bits_le(PutBitContext *s)
     123             : {
     124           0 :     while (s->bit_left < 32) {
     125           0 :         av_assert0(s->buf_ptr < s->buf_end);
     126           0 :         *s->buf_ptr++ = s->bit_buf;
     127           0 :         s->bit_buf  >>= 8;
     128           0 :         s->bit_left  += 8;
     129             :     }
     130           0 :     s->bit_left = 32;
     131           0 :     s->bit_buf  = 0;
     132           0 : }
     133             : 
     134             : #ifdef BITSTREAM_WRITER_LE
     135             : #define avpriv_align_put_bits align_put_bits_unsupported_here
     136             : #define avpriv_put_string ff_put_string_unsupported_here
     137             : #define avpriv_copy_bits avpriv_copy_bits_unsupported_here
     138             : #else
     139             : /**
     140             :  * Pad the bitstream with zeros up to the next byte boundary.
     141             :  */
     142             : void avpriv_align_put_bits(PutBitContext *s);
     143             : 
     144             : /**
     145             :  * Put the string string in the bitstream.
     146             :  *
     147             :  * @param terminate_string 0-terminates the written string if value is 1
     148             :  */
     149             : void avpriv_put_string(PutBitContext *pb, const char *string,
     150             :                        int terminate_string);
     151             : 
     152             : /**
     153             :  * Copy the content of src to the bitstream.
     154             :  *
     155             :  * @param length the number of bits of src to copy
     156             :  */
     157             : void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
     158             : #endif
     159             : 
     160             : /**
     161             :  * Write up to 31 bits into a bitstream.
     162             :  * Use put_bits32 to write 32 bits.
     163             :  */
     164  1867594993 : static inline void put_bits(PutBitContext *s, int n, unsigned int value)
     165             : {
     166             :     unsigned int bit_buf;
     167             :     int bit_left;
     168             : 
     169             :     av_assert2(n <= 31 && value < (1U << n));
     170             : 
     171  1867594993 :     bit_buf  = s->bit_buf;
     172  1867594993 :     bit_left = s->bit_left;
     173             : 
     174             :     /* XXX: optimize */
     175             : #ifdef BITSTREAM_WRITER_LE
     176    10511034 :     bit_buf |= value << (32 - bit_left);
     177    10511034 :     if (n >= bit_left) {
     178     2937968 :         if (3 < s->buf_end - s->buf_ptr) {
     179     2937968 :             AV_WL32(s->buf_ptr, bit_buf);
     180     2937968 :             s->buf_ptr += 4;
     181             :         } else {
     182           0 :             av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
     183             :             av_assert2(0);
     184             :         }
     185     2937968 :         bit_buf     = value >> bit_left;
     186     2937968 :         bit_left   += 32;
     187             :     }
     188    10511034 :     bit_left -= n;
     189             : #else
     190  1857083959 :     if (n < bit_left) {
     191  1565351728 :         bit_buf     = (bit_buf << n) | value;
     192  1565351728 :         bit_left   -= n;
     193             :     } else {
     194   291732231 :         bit_buf   <<= bit_left;
     195   291732231 :         bit_buf    |= value >> (n - bit_left);
     196   291732231 :         if (3 < s->buf_end - s->buf_ptr) {
     197   291732231 :             AV_WB32(s->buf_ptr, bit_buf);
     198   291732231 :             s->buf_ptr += 4;
     199             :         } else {
     200           0 :             av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
     201             :             av_assert2(0);
     202             :         }
     203   291732231 :         bit_left   += 32 - n;
     204   291732231 :         bit_buf     = value;
     205             :     }
     206             : #endif
     207             : 
     208  1867594993 :     s->bit_buf  = bit_buf;
     209  1867594993 :     s->bit_left = bit_left;
     210  1867594993 : }
     211             : 
     212           0 : static inline void put_bits_le(PutBitContext *s, int n, unsigned int value)
     213             : {
     214             :     unsigned int bit_buf;
     215             :     int bit_left;
     216             : 
     217             :     av_assert2(n <= 31 && value < (1U << n));
     218             : 
     219           0 :     bit_buf  = s->bit_buf;
     220           0 :     bit_left = s->bit_left;
     221             : 
     222           0 :     bit_buf |= value << (32 - bit_left);
     223           0 :     if (n >= bit_left) {
     224           0 :         if (3 < s->buf_end - s->buf_ptr) {
     225           0 :             AV_WL32(s->buf_ptr, bit_buf);
     226           0 :             s->buf_ptr += 4;
     227             :         } else {
     228           0 :             av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
     229             :             av_assert2(0);
     230             :         }
     231           0 :         bit_buf     = value >> bit_left;
     232           0 :         bit_left   += 32;
     233             :     }
     234           0 :     bit_left -= n;
     235             : 
     236           0 :     s->bit_buf  = bit_buf;
     237           0 :     s->bit_left = bit_left;
     238           0 : }
     239             : 
     240   174561588 : static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
     241             : {
     242             :     av_assert2(n >= 0 && n <= 31);
     243             : 
     244   174561588 :     put_bits(pb, n, av_mod_uintp2(value, n));
     245   174561588 : }
     246             : 
     247             : /**
     248             :  * Write exactly 32 bits into a bitstream.
     249             :  */
     250     1526937 : static void av_unused put_bits32(PutBitContext *s, uint32_t value)
     251             : {
     252             :     unsigned int bit_buf;
     253             :     int bit_left;
     254             : 
     255     1526937 :     bit_buf  = s->bit_buf;
     256     1526937 :     bit_left = s->bit_left;
     257             : 
     258             : #ifdef BITSTREAM_WRITER_LE
     259          41 :     bit_buf |= value << (32 - bit_left);
     260          41 :     if (3 < s->buf_end - s->buf_ptr) {
     261          41 :         AV_WL32(s->buf_ptr, bit_buf);
     262          41 :         s->buf_ptr += 4;
     263             :     } else {
     264           0 :         av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
     265             :         av_assert2(0);
     266             :     }
     267          41 :     bit_buf     = (uint64_t)value >> bit_left;
     268             : #else
     269     1526896 :     bit_buf     = (uint64_t)bit_buf << bit_left;
     270     1526896 :     bit_buf    |= value >> (32 - bit_left);
     271     1526896 :     if (3 < s->buf_end - s->buf_ptr) {
     272     1526896 :         AV_WB32(s->buf_ptr, bit_buf);
     273     1526896 :         s->buf_ptr += 4;
     274             :     } else {
     275           0 :         av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
     276             :         av_assert2(0);
     277             :     }
     278     1526896 :     bit_buf     = value;
     279             : #endif
     280             : 
     281     1526937 :     s->bit_buf  = bit_buf;
     282     1526937 :     s->bit_left = bit_left;
     283     1526937 : }
     284             : 
     285             : /**
     286             :  * Write up to 64 bits into a bitstream.
     287             :  */
     288        8175 : static inline void put_bits64(PutBitContext *s, int n, uint64_t value)
     289             : {
     290             :     av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n)));
     291             : 
     292        8175 :     if (n < 32)
     293        4079 :         put_bits(s, n, value);
     294        4096 :     else if (n == 32)
     295           0 :         put_bits32(s, value);
     296        4096 :     else if (n < 64) {
     297        4096 :         uint32_t lo = value & 0xffffffff;
     298        4096 :         uint32_t hi = value >> 32;
     299             : #ifdef BITSTREAM_WRITER_LE
     300             :         put_bits32(s, lo);
     301             :         put_bits(s, n - 32, hi);
     302             : #else
     303        4096 :         put_bits(s, n - 32, hi);
     304        4096 :         put_bits32(s, lo);
     305             : #endif
     306             :     } else {
     307           0 :         uint32_t lo = value & 0xffffffff;
     308           0 :         uint32_t hi = value >> 32;
     309             : #ifdef BITSTREAM_WRITER_LE
     310             :         put_bits32(s, lo);
     311             :         put_bits32(s, hi);
     312             : #else
     313           0 :         put_bits32(s, hi);
     314           0 :         put_bits32(s, lo);
     315             : #endif
     316             : 
     317             :     }
     318        8175 : }
     319             : 
     320             : /**
     321             :  * Return the pointer to the byte where the bitstream writer will put
     322             :  * the next bit.
     323             :  */
     324      467291 : static inline uint8_t *put_bits_ptr(PutBitContext *s)
     325             : {
     326      467291 :     return s->buf_ptr;
     327             : }
     328             : 
     329             : /**
     330             :  * Skip the given number of bytes.
     331             :  * PutBitContext must be flushed & aligned to a byte boundary before calling this.
     332             :  */
     333      123436 : static inline void skip_put_bytes(PutBitContext *s, int n)
     334             : {
     335             :     av_assert2((put_bits_count(s) & 7) == 0);
     336             :     av_assert2(s->bit_left == 32);
     337      123436 :     av_assert0(n <= s->buf_end - s->buf_ptr);
     338      123436 :     s->buf_ptr += n;
     339      123436 : }
     340             : 
     341             : /**
     342             :  * Skip the given number of bits.
     343             :  * Must only be used if the actual values in the bitstream do not matter.
     344             :  * If n is 0 the behavior is undefined.
     345             :  */
     346         200 : static inline void skip_put_bits(PutBitContext *s, int n)
     347             : {
     348         200 :     s->bit_left -= n;
     349         200 :     s->buf_ptr  -= 4 * (s->bit_left >> 5);
     350         200 :     s->bit_left &= 31;
     351         200 : }
     352             : 
     353             : /**
     354             :  * Change the end of the buffer.
     355             :  *
     356             :  * @param size the new size in bytes of the buffer where to put bits
     357             :  */
     358        4054 : static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
     359             : {
     360        4054 :     av_assert0(size <= INT_MAX/8 - 32);
     361        4054 :     s->buf_end = s->buf + size;
     362        4054 :     s->size_in_bits = 8*size;
     363        4054 : }
     364             : 
     365             : #endif /* AVCODEC_PUT_BITS_H */

Generated by: LCOV version 1.13