#ifndef _LIBMP4_H_
#define _LIBMP4_H_
#include <inttypes.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef MP4_API_EXPORTS
# ifdef _WIN32
# define MP4_API __declspec(dllexport)
# else
# define MP4_API __attribute__((visibility("default")))
# endif
#else
# define MP4_API
#endif
#define MP4_META_KEY_FRIENDLY_NAME "com.apple.quicktime.artist"
#define MP4_UDTA_KEY_FRIENDLY_NAME "\251ART"
#define MP4_META_KEY_TITLE "com.apple.quicktime.title"
#define MP4_UDTA_KEY_TITLE "\251nam"
#define MP4_META_KEY_COMMENT "com.apple.quicktime.comment"
#define MP4_UDTA_KEY_COMMENT "\251cmt"
#define MP4_META_KEY_COPYRIGHT "com.apple.quicktime.copyright"
#define MP4_UDTA_KEY_COPYRIGHT "\251cpy"
#define MP4_META_KEY_MEDIA_DATE "com.apple.quicktime.creationdate"
#define MP4_UDTA_KEY_MEDIA_DATE "\251day"
#define MP4_META_KEY_LOCATION "com.apple.quicktime.location.ISO6709"
#define MP4_UDTA_KEY_LOCATION "\251xyz"
#define MP4_META_KEY_MAKER "com.apple.quicktime.make"
#define MP4_UDTA_KEY_MAKER "\251mak"
#define MP4_META_KEY_MODEL "com.apple.quicktime.model"
#define MP4_UDTA_KEY_MODEL "\251mod"
#define MP4_META_KEY_SOFTWARE_VERSION "com.apple.quicktime.software"
#define MP4_UDTA_KEY_SOFTWARE_VERSION "\251swr"
enum mp4_track_type {
MP4_TRACK_TYPE_UNKNOWN = 0,
MP4_TRACK_TYPE_VIDEO,
MP4_TRACK_TYPE_AUDIO,
MP4_TRACK_TYPE_HINT,
MP4_TRACK_TYPE_METADATA,
MP4_TRACK_TYPE_TEXT,
MP4_TRACK_TYPE_CHAPTERS,
};
enum mp4_video_codec {
MP4_VIDEO_CODEC_UNKNOWN = 0,
MP4_VIDEO_CODEC_AVC,
MP4_VIDEO_CODEC_HEVC,
};
enum mp4_audio_codec {
MP4_AUDIO_CODEC_UNKNOWN = 0,
MP4_AUDIO_CODEC_AAC_LC,
};
enum mp4_metadata_cover_type {
MP4_METADATA_COVER_TYPE_UNKNOWN = 0,
MP4_METADATA_COVER_TYPE_JPEG,
MP4_METADATA_COVER_TYPE_PNG,
MP4_METADATA_COVER_TYPE_BMP,
};
enum mp4_seek_method {
MP4_SEEK_METHOD_PREVIOUS = 0,
MP4_SEEK_METHOD_PREVIOUS_SYNC,
MP4_SEEK_METHOD_NEXT_SYNC,
MP4_SEEK_METHOD_NEAREST_SYNC,
};
struct mp4_media_info {
uint64_t duration;
uint64_t creation_time;
uint64_t modification_time;
uint32_t track_count;
};
struct mp4_track_info {
uint32_t id;
const char *name;
int enabled;
int in_movie;
int in_preview;
enum mp4_track_type type;
uint32_t timescale;
uint64_t duration;
uint64_t creation_time;
uint64_t modification_time;
uint32_t sample_count;
uint32_t sample_max_size;
const uint64_t *sample_offsets;
const uint32_t *sample_sizes;
enum mp4_video_codec video_codec;
uint32_t video_width;
uint32_t video_height;
enum mp4_audio_codec audio_codec;
uint32_t audio_channel_count;
uint32_t audio_sample_size;
float audio_sample_rate;
const char *content_encoding;
const char *mime_format;
int has_metadata;
const char *metadata_content_encoding;
const char *metadata_mime_format;
};
struct mp4_hvcc_info {
uint8_t general_profile_space;
uint8_t general_tier_flag;
uint8_t general_profile_idc;
uint32_t general_profile_compatibility_flags;
uint64_t general_constraints_indicator_flags;
uint8_t general_level_idc;
uint16_t min_spatial_segmentation_idc;
uint8_t parallelism_type;
uint8_t chroma_format;
uint8_t bit_depth_luma;
uint8_t bit_depth_chroma;
uint16_t avg_framerate;
uint8_t constant_framerate;
uint8_t num_temporal_layers;
uint8_t temporal_id_nested;
uint8_t length_size;
};
struct mp4_video_decoder_config {
enum mp4_video_codec codec;
union {
struct {
union {
uint8_t *sps;
const uint8_t *c_sps;
};
size_t sps_size;
union {
uint8_t *pps;
const uint8_t *c_pps;
};
size_t pps_size;
} avc;
struct {
struct mp4_hvcc_info hvcc_info;
union {
uint8_t *vps;
const uint8_t *c_vps;
};
size_t vps_size;
union {
uint8_t *sps;
const uint8_t *c_sps;
};
size_t sps_size;
union {
uint8_t *pps;
const uint8_t *c_pps;
};
size_t pps_size;
} hevc;
};
uint32_t width;
uint32_t height;
};
struct mp4_track_sample {
uint32_t size;
uint32_t metadata_size;
int silent;
int sync;
uint64_t dts;
uint64_t next_dts;
uint64_t prev_sync_dts;
uint64_t next_sync_dts;
};
struct mp4_mux_track_params {
enum mp4_track_type type;
const char *name;
int enabled;
int in_movie;
int in_preview;
uint32_t timescale;
uint64_t creation_time;
uint64_t modification_time;
};
struct mp4_mux_sample {
const uint8_t *buffer;
size_t len;
int sync;
int64_t dts;
};
struct mp4_mux_scattered_sample {
const uint8_t *const *buffers;
const size_t *len;
int nbuffers;
int sync;
int64_t dts;
};
struct mp4_demux;
MP4_API int mp4_demux_open(const char *filename, struct mp4_demux **ret_obj);
MP4_API int mp4_demux_close(struct mp4_demux *demux);
MP4_API int mp4_demux_get_media_info(struct mp4_demux *demux,
struct mp4_media_info *media_info);
MP4_API int mp4_demux_get_track_count(struct mp4_demux *demux);
MP4_API int mp4_demux_get_track_info(struct mp4_demux *demux,
unsigned int track_idx,
struct mp4_track_info *track_info);
MP4_API int
mp4_demux_get_track_video_decoder_config(struct mp4_demux *demux,
unsigned int track_id,
struct mp4_video_decoder_config *vdc);
MP4_API int
mp4_demux_get_track_audio_specific_config(struct mp4_demux *demux,
unsigned int track_id,
uint8_t **audio_specific_config,
unsigned int *asc_size);
MP4_API int mp4_demux_get_track_sample(struct mp4_demux *demux,
unsigned int track_id,
int advance,
uint8_t *sample_buffer,
unsigned int sample_buffer_size,
uint8_t *metadata_buffer,
unsigned int metadata_buffer_size,
struct mp4_track_sample *track_sample);
MP4_API int mp4_demux_get_track_prev_sample_time(struct mp4_demux *demux,
unsigned int track_id,
uint64_t *sample_time);
MP4_API int mp4_demux_get_track_next_sample_time(struct mp4_demux *demux,
unsigned int track_id,
uint64_t *sample_time);
MP4_API int mp4_demux_get_track_prev_sample_time_before(struct mp4_demux *demux,
unsigned int track_id,
uint64_t time,
int sync,
uint64_t *sample_time);
MP4_API int mp4_demux_get_track_next_sample_time_after(struct mp4_demux *demux,
unsigned int track_id,
uint64_t time,
int sync,
uint64_t *sample_time);
MP4_API int mp4_demux_seek(struct mp4_demux *demux,
uint64_t time_offset,
enum mp4_seek_method method);
MP4_API int mp4_demux_seek_to_track_prev_sample(struct mp4_demux *demux,
unsigned int track_id);
MP4_API int mp4_demux_seek_to_track_next_sample(struct mp4_demux *demux,
unsigned int track_id);
MP4_API int mp4_demux_get_chapters(struct mp4_demux *demux,
unsigned int *chapters_count,
uint64_t **chapters_time,
char ***chapters_name);
MP4_API int mp4_demux_get_metadata_strings(struct mp4_demux *demux,
unsigned int *count,
char ***keys,
char ***values);
MP4_API int mp4_demux_get_track_metadata_strings(struct mp4_demux *demux,
unsigned int track_id,
unsigned int *count,
char ***keys,
char ***values);
MP4_API int
mp4_demux_get_metadata_cover(struct mp4_demux *demux,
uint8_t *cover_buffer,
unsigned int cover_buffer_size,
unsigned int *cover_size,
enum mp4_metadata_cover_type *cover_type);
struct mp4_mux;
MP4_API int mp4_mux_open(const char *filename,
uint32_t timescale,
uint64_t creation_time,
uint64_t modification_time,
struct mp4_mux **ret_obj);
MP4_API int mp4_mux_open2(const char *filename,
uint32_t timescale,
uint64_t creation_time,
uint64_t modification_time,
uint32_t table_size_mbytes,
struct mp4_mux **ret_obj);
MP4_API int mp4_mux_sync(struct mp4_mux *mux);
MP4_API int mp4_mux_close(struct mp4_mux *mux);
MP4_API int mp4_mux_add_track(struct mp4_mux *mux,
const struct mp4_mux_track_params *params);
MP4_API int mp4_mux_add_ref_to_track(struct mp4_mux *mux,
uint32_t track_id,
uint32_t ref_track_id);
MP4_API int
mp4_mux_track_set_video_decoder_config(struct mp4_mux *mux,
int track_id,
struct mp4_video_decoder_config *vdc);
MP4_API int mp4_mux_track_set_audio_specific_config(struct mp4_mux *mux,
int track_id,
const uint8_t *asc,
size_t asc_size,
uint32_t channel_count,
uint32_t sample_size,
float sample_rate);
MP4_API int mp4_mux_track_set_metadata_mime_type(struct mp4_mux *mux,
int track_id,
const char *content_encoding,
const char *mime_type);
MP4_API int mp4_mux_add_file_metadata(struct mp4_mux *mux,
const char *key,
const char *value);
MP4_API int mp4_mux_add_track_metadata(struct mp4_mux *mux,
uint32_t track_id,
const char *key,
const char *value);
MP4_API int mp4_mux_set_file_cover(struct mp4_mux *mux,
enum mp4_metadata_cover_type cover_type,
const uint8_t *cover,
size_t cover_size);
MP4_API int mp4_mux_track_add_sample(struct mp4_mux *mux,
int track_id,
const struct mp4_mux_sample *sample);
MP4_API int mp4_mux_track_add_scattered_sample(
struct mp4_mux *mux,
int track_id,
const struct mp4_mux_scattered_sample *sample);
MP4_API void mp4_mux_dump(struct mp4_mux *mux);
MP4_API int mp4_generate_avc_decoder_config(const uint8_t *sps,
unsigned int sps_size,
const uint8_t *pps,
unsigned int pps_size,
uint8_t *avcc,
unsigned int *avcc_size);
MP4_API const char *mp4_track_type_str(enum mp4_track_type type);
MP4_API const char *mp4_video_codec_str(enum mp4_video_codec codec);
MP4_API const char *mp4_audio_codec_str(enum mp4_audio_codec codec);
MP4_API const char *
mp4_metadata_cover_type_str(enum mp4_metadata_cover_type type);
static inline uint64_t mp4_usec_to_sample_time(uint64_t time,
uint32_t timescale)
{
return (time * timescale + 500000) / 1000000;
}
static inline uint64_t mp4_sample_time_to_usec(uint64_t time,
uint32_t timescale)
{
if (timescale == 0)
return 0;
return (time * 1000000 + timescale / 2) / timescale;
}
static inline uint64_t mp4_convert_timescale(uint64_t time,
uint32_t src_timescale,
uint32_t dest_timescale)
{
if (src_timescale == dest_timescale)
return time;
return (time * dest_timescale + src_timescale / 2) / src_timescale;
}
#ifdef __cplusplus
}
#endif
#endif