Skip to content

Commit

Permalink
Merge pull request gopro#4 from gopro/fix_define
Browse files Browse the repository at this point in the history
Fix define
  • Loading branch information
dnewman-gpsw authored Apr 24, 2019
2 parents c9877a4 + f4c3ffb commit 83f405e
Show file tree
Hide file tree
Showing 14 changed files with 2,857 additions and 356 deletions.
35 changes: 25 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
# CMakeLists.txt
cmake_minimum_required (VERSION 3.5.1)
project (gpmf-writer)

set(CMAKE_SUPPRESS_REGENERATION true)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release")

file(GLOB SOURCES *.c *.h "demo/*.c" "demo/*.h")

add_executable(gpmf-writer ${SOURCES})
cmake_minimum_required(VERSION 3.5.1)
project(gpmf-writer)

set(CMAKE_SUPPRESS_REGENERATION true)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release")

file(GLOB HEADERS "*.h")
file(GLOB DEMO_HEADERS "demo/*.h")
file(GLOB LIB_SOURCES "*.c" "demo/GPMF_mp4writer.c" "demo/GPMF_parser.c")
file(GLOB SOURCES ${LIB_SOURCES} "demo/GPMF_demo.c" "demo/GPMF_print.c")

add_executable(GPMF_WRITER_BIN ${SOURCES} ${HEADERS})
set_target_properties(GPMF_WRITER_BIN PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")
add_library(GPMF_WRITER_LIB ${LIB_SOURCES})
set_target_properties(GPMF_WRITER_LIB PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")
set_property(TARGET GPMF_WRITER_LIB PROPERTY SOVERSION 1)

set(PC_LINK_FLAGS "-l${PROJECT_NAME}")
configure_file("${PROJECT_NAME}.pc.in" "${PROJECT_NAME}.pc" @ONLY)

install(FILES ${HEADERS} DESTINATION "include/gpmf-writer")
install(FILES ${DEMO_HEADERS} DESTINATION "include/gpmf-writer/demo")
install(TARGETS GPMF_WRITER_BIN DESTINATION "bin")
install(TARGETS GPMF_WRITER_LIB DESTINATION "lib")
install(FILES "${PROJECT_NAME}.pc" DESTINATION "lib/pkgconfig")
153 changes: 153 additions & 0 deletions GPMF_bitstream.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*! @file GPMF_bitstream.h
*
* @brief GPMF Parser library include
*
* Some GPMF streams may contain compressed data, this is useful for high frequency
* sensor data that is highly correlated like IMU data. The compression is Huffman
* coding of the delta between samples, with addition codewords for runs of zeros,
* and optional quantization. The compression scheme is similar to the Huffman coding
* in JPEG. As it intended for lossless compression (with quantize set to 1) it can
* only comrpess/decompress integer based streams.
*
* @version 1.2.0
*
* (C) Copyright 2017 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#ifndef _GPMF_BITSTREAM_H
#define _GPMF_BITSTREAM_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

typedef struct rlv { // Codebook entries for arbitrary runs
uint16_t size; // Size of code word in bits
uint16_t bits; // Code word bits right justified
uint16_t count; // Run length for zeros
int16_t value; // Value for difference
} RLV;

typedef const struct {
int length; // Number of entries in the code book
RLV entries[39];
} RLVTABLE;

#define BITSTREAM_WORD_TYPE uint16_t // use 16-bit buffer for compression
#define BITSTREAM_WORD_SIZE 16 // use 16-bit buffer for compression
#define BITSTREAM_ERROR_OVERFLOW 1

#define BITMASK(n) _bitmask[n]
#define _BITMASK(n) ((((BITSTREAM_WORD_TYPE )1 << (n))) - 1)

static const BITSTREAM_WORD_TYPE _bitmask[] =
{
_BITMASK(0), _BITMASK(1), _BITMASK(2), _BITMASK(3),
_BITMASK(4), _BITMASK(5), _BITMASK(6), _BITMASK(7),
_BITMASK(8), _BITMASK(9), _BITMASK(10), _BITMASK(11),
_BITMASK(12), _BITMASK(13), _BITMASK(14), _BITMASK(15),
0xFFFF
};



typedef struct bitstream
{
int32_t error; // Error parsing the bitstream
uint8_t *lpCurrentWord; // Pointer to next word in block
int32_t wordsUsed; // Number of words used in the block
int32_t dwBlockLength; // Number of entries in the block
BITSTREAM_WORD_TYPE wBuffer; // Current word bit buffer
BITSTREAM_WORD_TYPE bits_per_src_word; // Bitused in the source word. e.g. 's' = 16-bits
BITSTREAM_WORD_TYPE bitsFree; // Number of bits available in the current word
} BITSTREAM;


static RLVTABLE enchuftable = {
39,
{
{ 1, 0b0, 1, 0 }, // m0
{ 2, 0b10, 1, 1 }, // m1
{ 4, 0b1100, 1, 2 }, // m2
{ 5, 0b11011, 1, 3 }, // m3
{ 5, 0b11101, 1, 4 }, // m4
{ 6, 0b110100, 1, 5 }, // m5
{ 6, 0b110101, 1, 6 }, // m6
{ 6, 0b111110, 1, 7 }, // m7
{ 7, 0b1110000, 1, 8 }, // m8
{ 7, 0b1110011, 1, 9 }, // m9
{ 7, 0b1111000, 1, 10 }, // m10
{ 7, 0b1111001, 1, 11 }, // m11
{ 7, 0b1111011, 1, 12 }, // m12
{ 8, 0b11100100, 1, 13 }, // m13
{ 8, 0b11100101, 1, 14 }, // m14
{ 8, 0b11110100, 1, 15 }, // m15
{ 9, 0b111000101, 1, 16 }, // m16
{ 9, 0b111000110, 1, 17 }, // m17
{ 9, 0b111101010, 1, 18 }, // m18
{ 10, 0b1110001000, 1, 19 }, // m19
{ 10, 0b1110001110, 1, 20 }, // m20
{ 10, 0b1111010110, 1, 21 }, // m21
{ 10, 0b1111111100, 1, 22 }, // m22
{ 11, 0b11100010010, 1, 23 }, // m23
{ 11, 0b11100011111, 1, 24 }, // m24
{ 11, 0b11110101110, 1, 25 }, // m25
{ 12, 0b111000100111, 1, 26 }, // m26
{ 12, 0b111000111101, 1, 27 }, // m27
{ 12, 0b111101011111, 1, 28 }, // m28
{ 13, 0b1110001001101, 1, 29 }, // m29
{ 13, 0b1110001111001, 1, 30 }, // m30
{ 13, 0b1111010111101, 1, 31 }, // m31
{ 14, 0b11100010011000, 1, 32 }, // m32
{ 14, 0b11100011110000, 1, 33 }, // m33
{ 14, 0b11110101111000, 1, 34 }, // m34
{ 14, 0b11110101111001, 1, 35 }, // m35
{ 15, 0b111000100110010, 1, 36 }, // m36
{ 15, 0b111000100110011, 1, 37 }, // m37
{ 15, 0b111000111100011, 1, 38 }, // m38
}
};



static RLVTABLE enczerorunstable = {
4,
{
{ 7, 0b1111110, 16, 0 }, // z16
{ 8, 0b11111110, 32, 0 }, // z32
{ 9, 0b111111111, 64, 0 }, // z64
{ 10,0b1111111101, 128, 0 }, // z128
}
};

#define HUFF_ESC_CODE_ENTRY 0
#define HUFF_END_CODE_ENTRY 1
static RLVTABLE enccontrolcodestable = {
2,
{
{ 16, 0b1110001111000100, 0, 0 }, // escape code for direct data <ESC><data>Continue
{ 16, 0b1110001111000101, 0, 0 }, // end code. Ends each compressed stream
}
};



#ifdef __cplusplus
}
#endif

#endif
12 changes: 9 additions & 3 deletions GPMF_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* @brief GPMF Parser library include
*
* @version 1.1.0
* @version 1.1.1
*
* (C) Copyright 2017 GoPro Inc (http://gopro.com/).
*
Expand Down Expand Up @@ -58,13 +58,16 @@ typedef enum
GPMF_TYPE_SIGNED_64BIT_INT = 'j', //64 bit signed long
GPMF_TYPE_UNSIGNED_64BIT_INT = 'J', //64 bit unsigned long
GPMF_TYPE_DOUBLE = 'd', //64 bit double precision float (IEEE 754)
GPMF_TYPE_STRING_UTF8 = 'u', //UTF-8 formatted text string. As the character storage size varies, the size is in bytes, not UTF characters.
GPMF_TYPE_UTC_DATE_TIME = 'U', //128-bit ASCII Date + UTC Time format yymmddhhmmss.sss - 16 bytes ASCII (years 20xx covered)
GPMF_TYPE_GUID = 'G', //128-bit ID (like UUID)

GPMF_TYPE_COMPLEX = '?', //for sample with complex data structures, base size in bytes. Data is either opaque, or the stream has a TYPE structure field for the sample.
GPMF_TYPE_COMPRESSED = '#', //Huffman compression STRM payloads. 4-CC <type><size><rpt> <data ...> is compressed as 4-CC '#'<new size/rpt> <type><size><rpt> <compressed data ...>

GPMF_TYPE_NEST = 0, // used to nest more GPMF formatted metadata

GPMF_TYPE_ERROR = 0xff // used to report an error
} GPMF_SampleType;


Expand All @@ -75,6 +78,7 @@ typedef enum
#define BYTESWAP64(a) (((a&0xff)<<56)|((a&0xff00)<<40)|((a&0xff0000)<<24)|((a&0xff000000)<<8) | ((a>>56)&0xff)|((a>>40)&0xff00)|((a>>24)&0xff0000)|((a>>8)&0xff000000) )
#define BYTESWAP32(a) (((a&0xff)<<24)|((a&0xff00)<<8)|((a>>8)&0xff00)|((a>>24)&0xff))
#define BYTESWAP16(a) ((((a)>>8)&0xff)|(((a)<<8)&0xff00))
#define BYTESWAP2x16(a) (((a>>8)&0xff)|((a<<8)&0xff00)|((a>>8)&0xff0000)|((a<<8)&0xff000000))
#define NOSWAP8(a) (a)

#define GPMF_SAMPLES(a) (((a>>24) & 0xff)|(((a>>16)&0xff)<<8))
Expand Down Expand Up @@ -107,11 +111,13 @@ typedef enum GPMFKey // TAG in all caps are GoPro preserved (are defined by GoPr
GPMF_KEY_TOTAL_SAMPLES = MAKEID('T','S','M','P'),//TOTL - Total Sample Count including the current payload
GPMF_KEY_TICK = MAKEID('T','I','C','K'),//TICK - Beginning of data timing (arrival) in milliseconds.
GPMF_KEY_TOCK = MAKEID('T','O','C','K'),//TOCK - End of data timing (arrival) in milliseconds.
GPMF_KEY_TIME_STAMP = MAKEID('S','T','M','P'),//STMP - Time stamp at the source in microseconds for the first sample.
GPMF_KEY_TIME_STAMPS = MAKEID('S','T','P','S'),//STPS - Stream of all the timestamps delivered.
GPMF_KEY_TIME_OFFSET = MAKEID('T','I','M','O'),//TIMO - Time offset of the metadata stream that follows (single 4 byte float)
GPMF_KEY_TIME_STAMP = MAKEID('S','T','M','P'),//STMP - Time stamp for the first sample.
GPMF_KEY_TIME_STAMPS = MAKEID('S','T','P','S'),//STPS - Stream of all the timestamps delivered (Generally don't use this. This would be if your sensor has no peroidic times, yet precision is required, or for debugging.)
GPMF_KEY_PREFORMATTED = MAKEID('P','F','R','M'),//PFRM - GPMF data
GPMF_KEY_TEMPERATURE_C = MAKEID('T','M','P','C'),//TMPC - Temperature in Celsius
GPMF_KEY_EMPTY_PAYLOADS = MAKEID('E','M','P','T'),//EMPT - Payloads that are empty since the device start (e.g. BLE disconnect.)
GPMF_KEY_QUANTIZE = MAKEID('Q','U','A','N'),//QUAN - quantize used to enable stream compression - 1 - enable, 2+ enable and quantize by this value
GPMF_KEY_VERSION = MAKEID('V','E','R','S'),//VERS - version of the metadata stream (debugging)
GPMF_KEY_FREESPACE = MAKEID('F','R','E','E'),//FREE - n bytes reserved for more metadata added to an existing stream
GPMF_KEY_REMARK = MAKEID('R','M','R','K'),//RMRK - adding comments to the bitstream (debugging)
Expand Down
Loading

0 comments on commit 83f405e

Please sign in to comment.