/*! * COPYRIGHT (C) 2020 Emeric Grange - All Rights Reserved * * This file is part of MiniVideo. * * MiniVideo is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MiniVideo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MiniVideo. If not, see . * * \author Emeric Grange * \date 2012 */ #ifndef BITSTREAM_H #define BITSTREAM_H /* ************************************************************************** */ // minivideo headers #include #include "minivideo_typedef.h" #include /* ************************************************************************** */ /*! * \struct Bitstream_t * \brief Bitstream structure. * \todo Massive cleanup of this API, need to address the bit/byte ambiguity of the variable names and function arguments. * * The "Bitstream_t" structure and associated APU is used to map a file to a * bitstream data buffer that can be read bit by bit instead of byte by byte. * That capability is requiered to extract compressed data that aren't aligned * with bytes boundaries. * * Data can be read from 1 to 64 unaligned bits from a file. These data are * bufferized by slices of size defined by the "BITSTREAM_BUFFER_SIZE" variable. * * Size and offset of the bitstream are stored using int64_t. This structure * should be able to handle files up to 1073741824 GiB if "Large File Support" * is enabled during compilation with -D_LARGEFILE64_SOURCE. Overwise only files * of 2 GiB will work. * * During a bitstream initialization, a MediaStream_t structure can be used. It * allows the bitstream to easily move the current bitstream offset from the end * of a frame directly to the start of the next frame one. */ typedef struct Bitstream_t { FILE *bitstream_file; //!< File pointer int64_t bitstream_size; //!< Bitstream size (in byte) int64_t bitstream_offset; //!< Current offset into the bitstream (in byte) uint32_t buffer_size_saved; //!< Data buffer size (in byte) uint8_t *buffer; //!< Current data buffer uint32_t buffer_size; //!< Current data buffer size (in byte) uint32_t buffer_offset; //!< Current offset into the buffer (in bit) uint32_t buffer_discarded_bytes; //!< Current number of byte(s) removed during NAL Unit read ahead } Bitstream_t; /* ************************************************************************** */ struct MediaFile_t; Bitstream_t *init_bitstream0(MediaFile_t *media, int64_t bitstream_offset, uint32_t buffer_size); Bitstream_t *init_bitstream(MediaFile_t *media); void free_bitstream(Bitstream_t **bitstr_ptr); int buffer_feed_manual(Bitstream_t *bitstr, int64_t bitstream_offset, int64_t size); int buffer_feed_dynamic(Bitstream_t *bitstr, int64_t new_bitstream_offset); int read_chunk(Bitstream_t* bitstr, uint8_t* chunk, const uint32_t size); // Bits operations uint32_t read_bit(Bitstream_t *bitstr); uint32_t read_bits(Bitstream_t *bitstr, const unsigned int n); uint64_t read_bits_64(Bitstream_t *bitstr, const unsigned int n); uint32_t next_bit(Bitstream_t *bitstr); uint32_t next_bits(Bitstream_t *bitstr, const unsigned int n); uint32_t read_byte_aligned(Bitstream_t *bitstr); uint32_t next_byte_aligned(Bitstream_t *bitstr); // Move into the bitstream int skip_bits(Bitstream_t *bitstr, const unsigned int n); int rewind_bits(Bitstream_t *bitstr, const unsigned int n); int bitstream_goto_offset(Bitstream_t *bitstr, const int64_t n); // Various operations int64_t bitstream_get_full_size(Bitstream_t *bitstr); int64_t bitstream_get_absolute_byte_offset(Bitstream_t *bitstr); int64_t bitstream_get_absolute_bit_offset(Bitstream_t *bitstr); /* ************************************************************************** */ #endif // BITSTREAM_H