/*
    libMakeMKV - MKV multiplexer library

    Copyright (C) 2007-2013 GuinpinSoft inc <libmkv@makemkv.com>

    This library 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 2.1 of the License, or (at your option) any later version.

    This library 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 this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/
#ifndef LGPL_FFABI_H_INCLUDED
#define LGPL_FFABI_H_INCLUDED

#include <stddef.h>
#include <stdint.h>

#if !defined(_MSC_VER) && !defined(__cdecl)
#define __cdecl
#endif

typedef enum _FFM_CodecID {
    FFM_CODEC_ID_AC3        = 0x15003,
    FFM_CODEC_ID_DTS        = 0x15004,
    FFM_CODEC_ID_FLAC       = 0x1500e,
    FFM_CODEC_ID_MLP        = 0x1501f,
    FFM_CODEC_ID_EAC3       = 0x1502b,
    FFM_CODEC_ID_TRUEHD     = 0x1502f,
    FFM_CODEC_ID_MAX_VALUE
} FFM_CodecID;

#define FFM_INPUT_BUFFER_PADDING_SIZE 16

typedef enum _FFM_AudioFormat {
    FFM_AUDIO_FMT_UNKNOWN,
    FFM_AUDIO_FMT_PCM_U8,
    FFM_AUDIO_FMT_PCM_S16,
    FFM_AUDIO_FMT_PCM_S32,
    FFM_AUDIO_FMT_PCM_FLT,
    FFM_AUDIO_FMT_PCM_DBL,
    FFM_AUDIO_FMT_PCM_U8P,
    FFM_AUDIO_FMT_PCM_S16P,
    FFM_AUDIO_FMT_PCM_S32P,
    FFM_AUDIO_FMT_PCM_FLTP,
    FFM_AUDIO_FMT_PCM_DBLP,
    FFM_AUDIO_FMT_PCM_S24,
    FFM_AUDIO_FMT_MAX_VALUE
} FFM_AudioFormat;

#ifdef _MSC_VER
#define ALIGN_PACKED
#pragma pack(1)
#endif

#ifdef __GNUC__
#define ALIGN_PACKED __attribute((packed))
#endif

typedef struct _FFM_AudioInfo {
    uint32_t    sample_rate;
    uint32_t    channels;
    uint32_t    bits_per_sample;
    uint32_t    frame_size;
    uint64_t    channel_layout;
} ALIGN_PACKED FFM_AudioInfo;


#ifdef _MSC_VER
#pragma pack()
#endif

struct _FFM_AudioDecodeContext;
typedef struct _FFM_AudioDecodeContext FFM_AudioDecodeContext;

struct _FFM_AudioEncodeContext;
typedef struct _FFM_AudioEncodeContext FFM_AudioEncodeContext;

struct _FFM_AudioConvert;
typedef struct _FFM_AudioConvert FFM_AudioConvert;

typedef void  (__cdecl *ffm_log_callback_t)(void* ctx,void* ctx2,int level,char* text);
typedef void* (__cdecl *ffm_memalign_t)(uintptr_t align, uintptr_t size);
typedef void* (__cdecl *ffm_realloc_t)(void *ptr, uintptr_t size);
typedef void  (__cdecl *ffm_free_t)(void *ptr);

#ifdef __cplusplus
extern "C" {
#endif

int __cdecl ffm_init(ffm_log_callback_t log_proc,void* log_context,ffm_memalign_t memalign_proc,ffm_realloc_t realloc_proc,ffm_free_t free_proc);
uint32_t __cdecl ffm_avcodec_version(void);

FFM_AudioDecodeContext* __cdecl ffm_audio_decode_init(void* logctx,FFM_CodecID id,FFM_AudioFormat fmt,const char* argp[],const uint8_t* CodecData,unsigned int CodecDataSize,unsigned int time_base);
int __cdecl ffm_audio_decode_close(FFM_AudioDecodeContext* ctx);
int __cdecl ffm_audio_decode_put_data(FFM_AudioDecodeContext* ctx,const uint8_t* data,unsigned int size,int64_t pts);
unsigned int __cdecl ffm_audio_decode_get_frame(FFM_AudioDecodeContext* ctx,int64_t* pts,const uint8_t* data[]);
int __cdecl ffm_audio_decode_get_info(FFM_AudioDecodeContext* ctx,FFM_AudioInfo* info);

FFM_AudioEncodeContext* __cdecl ffm_audio_encode_init(void* logctx,FFM_CodecID id,FFM_AudioFormat fmt,FFM_AudioInfo* info,const char* argp[],unsigned int time_base);
int __cdecl ffm_audio_encode_close(FFM_AudioEncodeContext* ctx);
int __cdecl ffm_audio_encode_put_frame(FFM_AudioEncodeContext* ctx,const uint8_t* frame_data[],unsigned int frame_size,unsigned int nb_samples,uint64_t pts);
const uint8_t* __cdecl ffm_audio_encode_get_data(FFM_AudioEncodeContext* ctx,unsigned int *size,int64_t *pts);
const uint8_t* __cdecl ffm_audio_encode_get_info(FFM_AudioEncodeContext* ctx,unsigned int *size);

int __cdecl ffm_audio_check_codec_format(FFM_CodecID id,FFM_AudioFormat fmt,int encode);

FFM_AudioConvert* __cdecl ffm_audio_convert_alloc(FFM_AudioFormat out_fmt,FFM_AudioFormat in_fmt,int channels);
void __cdecl ffm_audio_convert_free(FFM_AudioConvert **ac);
void __cdecl ffm_audio_convert(FFM_AudioConvert *ac, uint8_t *data_out[], const uint8_t* data_in[], int nb_samples);

int __cdecl ffm_mlp_read_syncframe(const uint8_t* data,unsigned int size,FFM_AudioInfo* info,uint32_t* bitrate);
uint16_t __cdecl ffm_mlp_checksum16(const uint8_t *buf, unsigned int buf_size);

int __cdecl ffm_mpa_decode_header(uint32_t hdr,FFM_AudioInfo* info,uint32_t* layer,uint32_t* frame_size,uint32_t* bitrate);

#ifdef __cplusplus
};
#endif

#endif // LGPL_FFABI_H_INCLUDED

