You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
KasmVNC/common/rfb/mp4.h

198 lines
7.8 KiB
C

#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
#define chk_err if (err != BUF_OK) { printf("Error buf: %s %s(...) %s:%d\n", buf_error_to_str(err), __func__, __FILE__, __LINE__); return err; }
#define chk_err_continue if (err != BUF_OK) { printf("Error buf: %s %s(...) %s:%d\n", buf_error_to_str(err), __func__, __FILE__, __LINE__); continue; }
enum BufError {
BUF_OK = 0,
BUF_ENDOFBUF_ERROR,
BUF_MALLOC_ERROR,
BUF_INCORRECT
};
char* buf_error_to_str(const enum BufError err);
struct BitBuf {
char *buf;
uint32_t size;
uint32_t offset;
};
enum BufError put_skip(struct BitBuf *ptr, const uint32_t count);
enum BufError put_to_offset(struct BitBuf *ptr, const uint32_t offset, const uint8_t* data, const uint32_t size);
enum BufError put(struct BitBuf *ptr, const uint8_t* data, const uint32_t size);
enum BufError put_u8_to_offset(struct BitBuf *ptr, const uint32_t offset, const uint8_t val);
enum BufError put_u8(struct BitBuf *ptr, uint8_t val);
enum BufError put_u16_be_to_offset(struct BitBuf *ptr, const uint32_t offset, const uint16_t val);
enum BufError put_u16_be(struct BitBuf *ptr, const uint16_t val);
enum BufError put_u16_le_to_offset(struct BitBuf *ptr, const uint32_t offset, const uint16_t val);
enum BufError put_u16_le(struct BitBuf *ptr, const uint16_t val);
enum BufError put_u32_be_to_offset(struct BitBuf *ptr, const uint32_t offset, const uint32_t val);
enum BufError put_u32_be(struct BitBuf *ptr, const uint32_t val);
enum BufError put_i32_be(struct BitBuf *ptr, const int32_t val);
enum BufError put_u64_be_to_offset(struct BitBuf *ptr, const uint32_t offset, const uint64_t val);
enum BufError put_u64_be(struct BitBuf *ptr, const uint64_t val);
enum BufError put_u32_le_to_offset(struct BitBuf *ptr, const uint32_t offset, const uint32_t val);
enum BufError put_u32_le(struct BitBuf *ptr, const uint32_t val);
enum BufError put_str4_to_offset(struct BitBuf *ptr, const uint32_t offset, const char str[4]);
enum BufError put_str4(struct BitBuf *ptr, const char str[4]);
enum BufError put_counted_str_to_offset(struct BitBuf *ptr, const uint32_t offset, const char *str, const uint32_t len);
enum BufError put_counted_str(struct BitBuf *ptr, const char *str, const uint32_t len);
struct MoovInfo {
uint8_t profile_idc;
uint8_t level_idc;
uint8_t *sps;
uint16_t sps_length;
uint8_t *pps;
uint16_t pps_length;
uint16_t width;
uint16_t height;
uint32_t horizontal_resolution;
uint32_t vertical_resolution;
uint32_t creation_time;
uint32_t timescale;
};
enum BufError write_header(struct BitBuf *ptr, struct MoovInfo *moov_info);
extern uint32_t pos_sequence_number;
extern uint32_t pos_base_data_offset;
extern uint32_t pos_base_media_decode_time;
struct SampleInfo {
uint32_t duration;
uint32_t decode_time;
uint32_t composition_time;
uint32_t composition_offset;
uint32_t size;
uint32_t flags;
};
enum BufError write_mdat(struct BitBuf *ptr, const uint8_t* data, const uint32_t origlen, const uint32_t len);
enum BufError write_moof(struct BitBuf *ptr,
const uint32_t sequence_number,
const uint64_t base_data_offset,
const uint64_t base_media_decode_time,
const uint32_t default_sample_duration,
const struct SampleInfo *samples_info, const uint32_t samples_info_len);
enum NalUnitType { // Table 7-1 NAL unit type codes
NalUnitType_Unspecified = 0, // Unspecified
NalUnitType_CodedSliceNonIdr = 1, // Coded slice of a non-IDR picture
NalUnitType_CodedSliceDataPartitionA = 2, // Coded slice data partition A
NalUnitType_CodedSliceDataPartitionB = 3, // Coded slice data partition B
NalUnitType_CodedSliceDataPartitionC = 4, // Coded slice data partition C
NalUnitType_CodedSliceIdr = 5, // Coded slice of an IDR picture
NalUnitType_SEI = 6, // Supplemental enhancement information (SEI)
NalUnitType_SPS = 7, // Sequence parameter set
NalUnitType_PPS = 8, // Picture parameter set
NalUnitType_AUD = 9, // Access unit delimiter
NalUnitType_EndOfSequence = 10, // End of sequence
NalUnitType_EndOfStream = 11, // End of stream
NalUnitType_Filler = 12, // Filler data
NalUnitType_SpsExt = 13, // Sequence parameter set extension
// 14..18 // Reserved
NalUnitType_CodedSliceAux = 19, // Coded slice of an auxiliary coded picture without partitioning
// 20..23 // Reserved
// 24..31 // Unspecified
};
struct NAL {
char *data;
uint64_t data_size;
uint32_t picture_order_count;
// NAL header
bool forbidden_zero_bit;
uint8_t ref_idc;
uint8_t unit_type_value;
enum NalUnitType unit_type;
};
static inline const char* nal_type_to_str(const enum NalUnitType nal_type) {
switch (nal_type) {
case NalUnitType_Unspecified: return "Unspecified";
case NalUnitType_CodedSliceNonIdr: return "CodedSliceNonIdr";
case NalUnitType_CodedSliceDataPartitionA: return "CodedSliceDataPartitionA";
case NalUnitType_CodedSliceDataPartitionB: return "CodedSliceDataPartitionB";
case NalUnitType_CodedSliceDataPartitionC: return "CodedSliceDataPartitionC";
case NalUnitType_CodedSliceIdr: return "CodedSliceIdr";
case NalUnitType_SEI: return "SEI";
case NalUnitType_SPS: return "SPS";
case NalUnitType_PPS: return "PPS";
case NalUnitType_AUD: return "AUD";
case NalUnitType_EndOfSequence: return "EndOfSequence";
case NalUnitType_EndOfStream: return "EndOfStream";
case NalUnitType_Filler: return "Filler";
case NalUnitType_SpsExt: return "SpsExt";
case NalUnitType_CodedSliceAux: return "CodedSliceAux";
default: return "Unknown";
}
}
static inline void nal_parse_header(struct NAL *nal, const char first_byte) {
nal->forbidden_zero_bit = ((first_byte & 0x80) >> 7) == 1;
nal->ref_idc = (first_byte & 0x60) >> 5;
nal->unit_type = (enum NalUnitType) ((first_byte & 0x1f) >> 0);
}
static inline bool nal_chk4(const uint8_t *buf, const uint32_t offset) {
if (buf[offset] == 0x00 && buf[offset+1] == 0x00 && buf[offset+2] == 0x01) { return true; }
if (buf[offset] == 0x00 && buf[offset+1] == 0x00 && buf[offset+2] == 0x00 && buf[offset+3] == 0x01) { return true; }
return false;
}
static inline bool nal_chk3(const uint8_t *buf, const uint32_t offset) {
if (buf[offset] == 0x00 && buf[offset+1] == 0x00 && buf[offset+2] == 0x01) { return true; }
return false;
}
extern uint32_t default_sample_size;
struct Mp4State {
bool header_sent;
uint32_t sequence_number;
uint64_t base_data_offset;
uint64_t base_media_decode_time;
uint32_t default_sample_duration;
uint32_t nals_count;
};
struct Mp4Context {
char buf_sps[128];
uint16_t buf_sps_len;
char buf_pps[128];
uint16_t buf_pps_len;
uint16_t w, h, framerate;
struct BitBuf buf_header;
struct BitBuf buf_moof;
struct BitBuf buf_mdat;
};
enum BufError set_slice(struct Mp4Context *ctx, const uint8_t* nal_data, const uint32_t origlen, const uint32_t nal_len, const enum NalUnitType unit_type);
void set_sps(struct Mp4Context *ctx, const uint8_t* nal_data, const uint32_t nal_len);
void set_pps(struct Mp4Context *ctx, const uint8_t* nal_data, const uint32_t nal_len);
enum BufError get_header(struct Mp4Context *ctx, struct BitBuf *ptr);
enum BufError set_mp4_state(struct Mp4Context *ctx, struct Mp4State *state);
enum BufError get_moof(struct Mp4Context *ctx, struct BitBuf *ptr);
enum BufError get_mdat(struct Mp4Context *ctx, struct BitBuf *ptr);
#ifdef __cplusplus
} // extern C
#endif