#include "ka_block.h"
#include "ka_codecs.h"
#include "ka_scodec.h"
#include "ka_vcodec.h"

#include <stdlib.h>

#define MAX_VIDEO_TYPES 0x42

static const char* vcodec_names[MAX_VIDEO_TYPES] =
{
  "3ivx MPEG-4"
, "Planar RGB"
, "ASV Video v1"
, "ASV Video v2"
, "ATI VCR v1"
, "ATI VCR v2"
, "Cinepak"
, "Microsoft Video v1, CRAM"
, "Creative YUV"
, "ISO-MPEG4/OpenDivx"
, "DivX v5"
, "Duck Truemotion v1"
, "Sony Digital Video (DV)"
, "FLC/FLI"
, "Raw Greyscale"
, "H263"
, "Advanced Video Coding (H264)"
, "HuffYUV"
, "Raw Planar I420"
, "Image"
, "Indeo Video v3.1"
, "Indeo Video v3.2"
, "Indeo Video v4.1"
, "Indeo Video v5.0"
, "JPEG"
, "Motion JPEG A"
, "Motion JPEG B"
, "MPEG 1/2"
, "Microsoft MPEG-4 v1"
, "Microsoft MPEG-4 v2"
, "Microsoft MPEG-4 v3"
, "Microsoft RLE"
, "Windows Screen Video"
, "MSZH Video"
, "Motion Pixels"
, "Radius Studio"
, "Apple Quicktime Animation (RLE)"
, "Raw RGB"
, "Apple Quicktime (RPZA)"
, "Real Video v1"
, "Real Video v2"
, "Real Video v3"
, "Real Video v4"
, "Cinepak for Sega"
, "Apple Quicktime Graphics (SMC)"
, "Sorenson Video v1"
, "Sorenson Video v3"
, "TechSmith Screen Capture Codec"
, "ClearVideo"
, "VIVO"
, "On2 VP3"
, "On2 VP4"
, "On2 VP5"
, "On2 VP6"
, "Windows Media Video v7"
, "Windows Media Video v8"
, "Windows Media Video v9"
, "XviD"
, "Wing Commander IV Video Codec"
, "Raw YUV2"
, "Raw YVU9 Planar Data"
, "Raw Planar YV12"
, "ZyGo Video"
, "ZLIB Video"
, "HEVC, H265"
, "VC1"
};

static const kav_vcodec_t* vcodecs[MAX_VIDEO_TYPES] =
{
  NULL // "3ivx MPEG-4"
, NULL // "Planar RGB"
, NULL // "ASV Video v1"
, NULL // "ASV Video v2"
, NULL // "ATI VCR v1"
, NULL // "ATI VCR v2"
, &kav_vcodec_cvid // "Cinepak"
, NULL // "Microsoft Video v1, CRAM"
, NULL // "Creative YUV"
, NULL // "ISO-MPEG4/OpenDivx"
, NULL // "DivX v5"
, NULL // "Duck Truemotion v1"
, NULL // "Sony Digital Video (DV)"
, NULL // "FLC/FLI"
, NULL // "Raw Greyscale"
, NULL // "H263"
, NULL // "Advanced Video Coding (H264)"
, NULL // "HuffYUV"
, NULL // "Raw Planar I420"
, NULL // "Image"
, NULL // "Indeo Video v3.1"
, NULL // "Indeo Video v3.2"
, NULL // "Indeo Video v4.1"
, NULL // "Indeo Video v5.0"
, NULL // "JPEG"
, NULL // "Motion JPEG A"
, NULL // "Motion JPEG B"
, &kav_vcodec_mpeg // "MPEG 1/2"
, NULL // "Microsoft MPEG-4 v1"
, NULL // "Microsoft MPEG-4 v2"
, NULL // "Microsoft MPEG-4 v3"
, NULL // "Microsoft RLE"
, NULL // "Windows Screen Video"
, NULL // "MSZH Video"
, NULL // "Motion Pixels"
, NULL // "Radius Studio"
, NULL // "Apple Quicktime Animation (RLE)"
, NULL // "Raw RGB"
, NULL // "Apple Quicktime (RPZA)"
, NULL // "Real Video v1"
, NULL // "Real Video v2"
, NULL // "Real Video v3"
, NULL // "Real Video v4"
, NULL // "Cinepak for Sega"
, NULL // "Apple Quicktime Graphics (SMC)"
, NULL // "Sorenson Video v1"
, NULL // "Sorenson Video v3"
, NULL // "TechSmith Screen Capture Codec"
, NULL // "ClearVideo"
, NULL // "VIVO"
, NULL // "On2 VP3"
, NULL // "On2 VP4"
, NULL // "On2 VP5"
, NULL // "On2 VP6"
, NULL // "Windows Media Video v7"
, NULL // "Windows Media Video v8"
, NULL // "Windows Media Video v9"
, NULL // "XviD"
, NULL // "Wing Commander IV Video Codec"
, NULL // "Raw YUV2"
, NULL // "Raw YVU9 Planar Data"
, NULL // "Raw Planar YV12"
, NULL // "ZyGo Video"
, NULL // "ZLIB Video"
};

typedef struct
{
  uint32_t fourcc;
  uint32_t id;
} four_cc_t;

#define MAX_VIDEO_DB 137

static const four_cc_t video_db[MAX_VIDEO_DB] =
{
  {MKTAG('3', 'I', 'V', '1'), KA_VBLOCK_3IVX}
, {MKTAG('3', 'I', 'V', '2'), KA_VBLOCK_3IVX}
, {MKTAG('8', 'B', 'P', 'S'), KA_VBLOCK_8BPS}
, {MKTAG('A', 'P', '4', '1'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('A', 'S', 'V', '1'), KA_VBLOCK_ASV_V1}
, {MKTAG('A', 'S', 'V', '2'), KA_VBLOCK_ASV_V2}
, {MKTAG('A', 'V', 'D', 'J'), KA_VBLOCK_MJPEG_A}
, {MKTAG('A', 'V', 'R', 'n'), KA_VBLOCK_MJPEG_A}
, {MKTAG('C', 'O', 'L', '1'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('C', 'R', 'A', 'M'), KA_VBLOCK_CRAM}
, {MKTAG('C', 'Y', 'U', 'V'), KA_VBLOCK_CYUV}
, {MKTAG('D', 'I', 'B', ' '), KA_VBLOCK_RGB}
, {MKTAG('D', 'I', 'V', '2'), KA_VBLOCK_MSMPEG4_V2}
, {MKTAG('D', 'I', 'V', '3'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('D', 'I', 'V', '4'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('D', 'I', 'V', '5'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('D', 'I', 'V', '6'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('D', 'I', 'V', 'X'), KA_VBLOCK_DIVX}
, {MKTAG('D', 'U', 'C', 'K'), KA_VBLOCK_DUCK}
, {MKTAG('D', 'V', 'S', 'D'), KA_VBLOCK_DV}
, {MKTAG('D', 'X', '5', '0'), KA_VBLOCK_DIVX_V5}
, {MKTAG('D', 'i', 'v', 'X'), KA_VBLOCK_DIVX}
, {MKTAG('D', 'i', 'v', 'x'), KA_VBLOCK_DIVX}
, {MKTAG('F', 'M', 'P', '4'), KA_VBLOCK_DIVX}
, {MKTAG('G', 'R', 'E', 'Y'), KA_VBLOCK_GREY}
, {MKTAG('H', '2', '6', '3'), KA_VBLOCK_H263}
, {MKTAG('H', 'F', 'Y', 'U'), KA_VBLOCK_HFYU}
, {MKTAG('I', '2', '6', '3'), KA_VBLOCK_VIVO}
, {MKTAG('I', '4', '2', '0'), KA_VBLOCK_I420}
, {MKTAG('I', 'M', 'G', ' '), KA_VBLOCK_IMAGE}
, {MKTAG('I', 'V', '3', '1'), KA_VBLOCK_IV31}
, {MKTAG('I', 'V', '3', '2'), KA_VBLOCK_IV32}
, {MKTAG('I', 'V', '4', '1'), KA_VBLOCK_IV41}
, {MKTAG('I', 'V', '5', '0'), KA_VBLOCK_IV50}
, {MKTAG('I', 'Y', 'U', 'V'), KA_VBLOCK_I420}
, {MKTAG('J', 'F', 'I', 'F'), KA_VBLOCK_JPEG}
, {MKTAG('M', '4', 'S', '2'), KA_VBLOCK_DIVX}
, {MKTAG('M', 'J', 'P', 'G'), KA_VBLOCK_MJPEG_A}
, {MKTAG('M', 'P', '4', '1'), KA_VBLOCK_MSMPEG4_V1}
, {MKTAG('M', 'P', '4', '2'), KA_VBLOCK_MSMPEG4_V2}
, {MKTAG('M', 'P', '4', '3'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('M', 'P', '4', 'S'), KA_VBLOCK_DIVX}
, {MKTAG('M', 'P', 'G', '3'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('M', 'P', 'G', '4'), KA_VBLOCK_MSMPEG4_V1}
, {MKTAG('M', 'S', 'S', '1'), KA_VBLOCK_MSS1}
, {MKTAG('M', 'S', 'V', 'C'), KA_VBLOCK_CRAM}
, {MKTAG('M', 'S', 'Z', 'H'), KA_VBLOCK_MSZH}
, {MKTAG('M', 'V', 'I', '2'), KA_VBLOCK_MVI2}
, {MKTAG('P', 'G', 'V', 'V'), KA_VBLOCK_PGVV}
, {MKTAG('P', 'I', 'M', '1'), KA_VBLOCK_MPEG}
, {MKTAG('R', 'V', '1', '0'), KA_VBLOCK_RV10}
, {MKTAG('R', 'V', '2', '0'), KA_VBLOCK_RV20}
, {MKTAG('R', 'V', '3', '0'), KA_VBLOCK_RV30}
, {MKTAG('R', 'V', '4', '0'), KA_VBLOCK_RV40}
, {MKTAG('S', 'E', 'G', 'A'), KA_VBLOCK_SEGA}
, {MKTAG('S', 'V', 'Q', '1'), KA_VBLOCK_SORENSON_V1}
, {MKTAG('S', 'V', 'Q', '3'), KA_VBLOCK_SORENSON_V3}
, {MKTAG('U', '2', '6', '3'), KA_VBLOCK_H263}
, {MKTAG('U', 'C', 'O', 'D'), KA_VBLOCK_UCOD}
, {MKTAG('V', 'C', 'R', '1'), KA_VBLOCK_ATIVCR_V1}
, {MKTAG('V', 'C', 'R', '2'), KA_VBLOCK_ATIVCR_V2}
, {MKTAG('V', 'I', 'V', 'O'), KA_VBLOCK_VIVO}
, {MKTAG('V', 'P', '3', ' '), KA_VBLOCK_VP3}
, {MKTAG('V', 'P', '3', '0'), KA_VBLOCK_VP3}
, {MKTAG('V', 'P', '3', '1'), KA_VBLOCK_VP3}
, {MKTAG('V', 'P', '4', '0'), KA_VBLOCK_VP4}
, {MKTAG('V', 'P', '5', '0'), KA_VBLOCK_VP5}
, {MKTAG('V', 'P', '6', '0'), KA_VBLOCK_VP6}
, {MKTAG('V', 'P', '6', '1'), KA_VBLOCK_VP6}
, {MKTAG('V', 'P', '6', '2'), KA_VBLOCK_VP6}
, {MKTAG('W', 'H', 'A', 'M'), KA_VBLOCK_CRAM}
, {MKTAG('W', 'M', 'V', '1'), KA_VBLOCK_WMV_V7}
, {MKTAG('W', 'M', 'V', '2'), KA_VBLOCK_WMV_V8}
, {MKTAG('W', 'M', 'V', '3'), KA_VBLOCK_WMV_V9}
, {MKTAG('W', 'M', 'V', 'P'), KA_VBLOCK_WMV_V9}
, {MKTAG('X', 'V', 'I', 'D'), KA_VBLOCK_XVID}
, {MKTAG('X', 'X', 'A', 'N'), KA_VBLOCK_XXAN}
, {MKTAG('X', 'x', 'a', 'n'), KA_VBLOCK_XXAN}
, {MKTAG('Y', 'V', '1', '2'), KA_VBLOCK_YV12}
, {MKTAG('Y', 'V', 'U', '9'), KA_VBLOCK_YUV9}
, {MKTAG('Z', 'L', 'I', 'B'), KA_VBLOCK_ZLIB}
, {MKTAG('Z', 'y', 'G', 'o'), KA_VBLOCK_ZYGO}
, {MKTAG('a', 'v', 'c', '1'), KA_VBLOCK_H264}
, {MKTAG('a', 'z', 'p', 'r'), KA_VBLOCK_RPZA}
, {MKTAG('c', 'r', 'a', 'm'), KA_VBLOCK_CRAM}
, {MKTAG('c', 'v', 'i', 'd'), KA_VBLOCK_CINEPAK}
, {MKTAG('c', 'y', 'u', 'v'), KA_VBLOCK_CYUV}
, {MKTAG('d', 'i', 'v', '2'), KA_VBLOCK_MSMPEG4_V2}
, {MKTAG('d', 'i', 'v', '3'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('d', 'i', 'v', '4'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('d', 'i', 'v', '5'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('d', 'i', 'v', '6'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('d', 'i', 'v', 'x'), KA_VBLOCK_DIVX}
, {MKTAG('d', 'm', 'b', '1'), KA_VBLOCK_MJPEG_A}
, {MKTAG('d', 'v', 'c', 'p'), KA_VBLOCK_DV}
, {MKTAG('d', 'v', 's', 'd'), KA_VBLOCK_DV}
, {MKTAG('h', '2', '6', '3'), KA_VBLOCK_H263}
, {MKTAG('h', '2', '6', '4'), KA_VBLOCK_H264}
, {MKTAG('i', '2', '6', '3'), KA_VBLOCK_VIVO}
, {MKTAG('i', 'v', '3', '1'), KA_VBLOCK_IV31}
, {MKTAG('i', 'v', '3', '2'), KA_VBLOCK_IV32}
, {MKTAG('i', 'v', '4', '1'), KA_VBLOCK_IV41}
, {MKTAG('i', 'v', '5', '0'), KA_VBLOCK_IV50}
, {MKTAG('j', 'p', 'e', 'g'), KA_VBLOCK_JPEG}
, {MKTAG('m', '4', 's', '2'), KA_VBLOCK_DIVX}
, {MKTAG('m', 'j', 'p', 'a'), KA_VBLOCK_MJPEG_A}
, {MKTAG('m', 'j', 'p', 'b'), KA_VBLOCK_MJPEG_B}
, {MKTAG('m', 'p', '4', '1'), KA_VBLOCK_MSMPEG4_V1}
, {MKTAG('m', 'p', '4', '2'), KA_VBLOCK_MSMPEG4_V2}
, {MKTAG('m', 'p', '4', '3'), KA_VBLOCK_MSMPEG4_V3}
, {MKTAG('m', 'p', '4', 'v'), KA_VBLOCK_DIVX}
, {MKTAG('m', 'p', 'e', 'g'), KA_VBLOCK_MPEG}
, {MKTAG('m', 'p', 'g', '1'), KA_VBLOCK_MPEG}
, {MKTAG('m', 'p', 'g', '2'), KA_VBLOCK_MPEG}
, {MKTAG('m', 'p', 'g', '4'), KA_VBLOCK_MSMPEG4_V1}
, {MKTAG('m', 's', 'v', 'c'), KA_VBLOCK_CRAM}
, {MKTAG('m', 'v', 'i', '2'), KA_VBLOCK_MVI2}
, {MKTAG('r', 'a', 'w', ' '), KA_VBLOCK_RGB}
, {MKTAG('r', 'l', 'e', ' '), KA_VBLOCK_QTRLE}
, {MKTAG('r', 'p', 'z', 'a'), KA_VBLOCK_RPZA}
, {MKTAG('s', '2', '6', '3'), KA_VBLOCK_H263}
, {MKTAG('s', 'e', 'g', 'a'), KA_VBLOCK_SEGA}
, {MKTAG('s', 'm', 'c', ' '), KA_VBLOCK_SMC}
, {MKTAG('s', 'v', 'q', '1'), KA_VBLOCK_SORENSON_V1}
, {MKTAG('s', 'v', 'q', '3'), KA_VBLOCK_SORENSON_V3}
, {MKTAG('s', 'v', 'q', 'i'), KA_VBLOCK_SORENSON_V1}
, {MKTAG('t', 's', 'c', 'c'), KA_VBLOCK_TSCC}
, {MKTAG('u', 'c', 'o', 'd'), KA_VBLOCK_UCOD}
, {MKTAG('v', 'i', 'v', '1'), KA_VBLOCK_VIVO}
, {MKTAG('v', 'i', 'v', 'o'), KA_VBLOCK_VIVO}
, {MKTAG('v', 'p', '3', '0'), KA_VBLOCK_VP3}
, {MKTAG('v', 'p', '3', '1'), KA_VBLOCK_VP3}
, {MKTAG('w', 'h', 'a', 'm'), KA_VBLOCK_CRAM}
, {MKTAG('x', 'v', 'i', 'd'), KA_VBLOCK_XVID}
, {MKTAG('x', 'x', 'a', 'n'), KA_VBLOCK_XXAN}
, {MKTAG('y', 'u', 'v', '2'), KA_VBLOCK_YUV2}
, {MKTAG('y', 'v', '1', '2'), KA_VBLOCK_YV12}
};

uint32_t ka_tag_to_video(uint32_t fourcc)
{
  int a = 0, b = MAX_VIDEO_DB/2, c = MAX_VIDEO_DB;

  while (a < b)
  {
    if (fourcc < video_db[b].fourcc)
    {
      c = b;
      b = (a + c)/2;
    }
    else if (fourcc > video_db[b].fourcc)
    {
      a = b;
      b = (a + c)/2;
    }
    else return video_db[b].id;
  }

  if (fourcc == video_db[b].fourcc)
    return video_db[b].id;

  return KA_VBLOCK_UNKNOWN;
}

#define MAX_SUBTITLES_TYPES 0x04

static const char* scodec_names[MAX_SUBTITLES_TYPES] =
{ "DVD Subtitles"
, "DVB Subtitles"
, "TELETEXT"
, "PGS Subtitles"
};

static const kav_scodec_t* scodecs[MAX_SUBTITLES_TYPES] =
{
  &kav_scodec_dvd
, &kav_scodec_dvb
, NULL
, NULL
};

uint32_t ka_tag_to_subtitle(uint32_t fourcc)
{
  fourcc = fourcc; // unused
  return KA_SBLOCK_UNKNOWN;
}

#define MAX_AUDIO_TYPES 0x2C

static const char* acodec_names[MAX_AUDIO_TYPES] =
{
  "Advanced Audio Coding (MPEG-4 AAC)"
, "AC3"
, "ACELP.net"
, "GSM 6.10"
, "Apple Lossless Audio Codec"
, "A-law logarithmic PCM"
, "RealAudio ATRK"
, "RealAudio COOK"
, "Duck DK3 ADPCM (rogue format number)"
, "Duck DK4 ADPCM (rogue format number)"
, "RealAudio DNET"
, "DTS"
, "Free Lossless Audio Codec (FLAC)"
, "Intel Music Coder"
, "Lernout & Hauspie"
, "Signed PCM big endian"
, "Signed PCM little endian"
, "Unsigned PCM big endian"
, "Unsigned PCM little endian"
, "Apple MACE 3:1 Audio"
, "Apple MACE 6:1 Audio"
, "MPEG layer 2/3"
, "MS ADPCM"
, "MS GSM"
, "MS IMA ADPCM"
, "Qualcomm PureVoice"
, "QDesign Audio v1"
, "QDesign Audio v2"
, "QT IMA ADPCM"
, "Real 14.4"
, "Real 28.8"
, "RealAudio SIPRO"
, "mu-law logarithmic PCM"
, "Vivo G.723/Siren Audio Codec"
, "OggVorbis Audio"
, "Voxware Metasound"
, "Windows Media Audio Lossless"
, "Windows Media Audio v1"
, "Windows Media Audio v2"
, "Windows Media Audio v3"
, "Windows Media Audio Voice"
, "TrueHD"
, "Signed PCM big endian DVD"
, "Signed PCM big endian Blu-Ray"
};

#define MAX_AUDIO_DB 69

static four_cc_t audio_db[MAX_AUDIO_DB] =
{
  { MKTAG(0x00,0x20,0x00,0x00), KA_ABLOCK_AC3}
, { MKTAG(0x01,0x00,0x00,0x00), KA_ABLOCK_LPCM_LE}
, { MKTAG(0x01,0x04,0x00,0x00), KA_ABLOCK_IMC}
, { MKTAG(0x01,0x11,0x00,0x00), KA_ABLOCK_LH}
, { MKTAG(0x01,0x20,0x00,0x00), KA_ABLOCK_DTS}
, { MKTAG(0x02,0x00,0x00,0x00), KA_ABLOCK_MSADPCM}
, { MKTAG(0x02,0x11,0x00,0x00), KA_ABLOCK_LH}
, { MKTAG(0x03,0x11,0x00,0x00), KA_ABLOCK_LH}
, { MKTAG(0x04,0x11,0x00,0x00), KA_ABLOCK_LH}
, { MKTAG(0x06,0x00,0x00,0x00), KA_ABLOCK_ALAW}
, { MKTAG(0x07,0x00,0x00,0x00), KA_ABLOCK_ULAW}
, { MKTAG(0x0A,0x00,0x00,0x00), KA_ABLOCK_WMA_VOICE}
, { MKTAG(0x11,0x00,0x00,0x00), KA_ABLOCK_MSIMAADPCM}
, { MKTAG(0x11,0x01,0x00,0x00), KA_ABLOCK_VIVOG723}
, { MKTAG(0x12,0x01,0x00,0x00), KA_ABLOCK_VIVOG723}
, { MKTAG( '.', 'm', 'p', '3'), KA_ABLOCK_MPEG}
, { MKTAG(0x30,0x01,0x00,0x00), KA_ABLOCK_ACELPNET}
, { MKTAG(0x31,0x00,0x00,0x00), KA_ABLOCK_MSGSM}
, { MKTAG(0x32,0x00,0x00,0x00), KA_ABLOCK_MSGSM}
, { MKTAG( '2', '8', '_', '8'), KA_ABLOCK_REAL_28_8}
, { MKTAG( 'A', 'A', 'C', ' '), KA_ABLOCK_AAC}
, { MKTAG( 'M', 'A', 'C', '3'), KA_ABLOCK_MACE3}
, { MKTAG( 'M', 'A', 'C', '6'), KA_ABLOCK_MACE6}
, { MKTAG( 'M', 'P', '3', ' '), KA_ABLOCK_MPEG}
, { MKTAG( 'M', 'P', '4', 'A'), KA_ABLOCK_AAC}
, { MKTAG(0x4F,0x67,0x00,0x00), KA_ABLOCK_VORBIS}
, { MKTAG( 'O', 'g', 'g', 'S'), KA_ABLOCK_VORBIS}
, { MKTAG( 'O', 'g', 'g', 'V'), KA_ABLOCK_VORBIS}
, { MKTAG(0x50,0x00,0x00,0x00), KA_ABLOCK_MPEG}
, { MKTAG(0x50,0x67,0x00,0x00), KA_ABLOCK_VORBIS}
, { MKTAG( 'Q', 'D', 'M', '2'), KA_ABLOCK_QDESIGN_V2}
, { MKTAG( 'Q', 'D', 'M', 'C'), KA_ABLOCK_QDESIGN_V1}
, { MKTAG( 'Q', 'c', 'l', 'p'), KA_ABLOCK_QCLP}
, { MKTAG(0x51,0x67,0x00,0x00), KA_ABLOCK_VORBIS}
, { MKTAG(0x55,0x00,0x00,0x00), KA_ABLOCK_MPEG}
, { MKTAG(0x60,0x01,0x00,0x00), KA_ABLOCK_WMA_V1}
, { MKTAG(0x61,0x00,0x00,0x00), KA_ABLOCK_DK4ADPCM}
, { MKTAG(0x61,0x01,0x00,0x00), KA_ABLOCK_WMA_V2}
, { MKTAG( 'a', 'g', 's', 'm'), KA_ABLOCK_AGSM}
, { MKTAG( 'a', 'l', 'a', 'c'), KA_ABLOCK_ALAC}
, { MKTAG( 'a', 'l', 'a', 'w'), KA_ABLOCK_ALAW}
, { MKTAG( 'a', 't', 'r', 'c'), KA_ABLOCK_ATRAC}
, { MKTAG(0x62,0x00,0x00,0x00), KA_ABLOCK_DK3ADPCM}
, { MKTAG(0x62,0x01,0x00,0x00), KA_ABLOCK_WMA_V3}
, { MKTAG(0x63,0x01,0x00,0x00), KA_ABLOCK_WMA_LOSSLESS}
, { MKTAG( 'c', 'o', 'o', 'k'), KA_ABLOCK_COOK}
, { MKTAG( 'd', 'n', 'e', 't'), KA_ABLOCK_DNET}
, { MKTAG( 'i', 'm', 'a', '4'), KA_ABLOCK_QTIMAADPCM}
, { MKTAG( 'i', 'n', '2', '4'), KA_ABLOCK_LPCM_BE}
, { MKTAG( 'l', 'p', 'c', 'J'), KA_ABLOCK_REAL_14_4}
, { MKTAG( 'm', 'a', 'c', '3'), KA_ABLOCK_MACE3}
, { MKTAG( 'm', 'a', 'c', '6'), KA_ABLOCK_MACE6}
, { MKTAG( 'm', 'p', '4', 'a'), KA_ABLOCK_AAC}
, { MKTAG( 'm', 's',0x00,0x02), KA_ABLOCK_MSADPCM}
, { MKTAG( 'm', 's',0x00,0x11), KA_ABLOCK_MSIMAADPCM}
, { MKTAG( 'm', 's',0x00,0x55), KA_ABLOCK_MPEG}
, { MKTAG( 'm', 's',0x20,0x00), KA_ABLOCK_AC3}
, { MKTAG(0x6F,0x67,0x00,0x00), KA_ABLOCK_VORBIS}
, { MKTAG(0x70,0x67,0x00,0x00), KA_ABLOCK_VORBIS}
, { MKTAG(0x71,0x67,0x00,0x00), KA_ABLOCK_VORBIS}
, { MKTAG( 'r', 'a', 'a', 'c'), KA_ABLOCK_AAC}
, { MKTAG( 'r', 'a', 'c', 'p'), KA_ABLOCK_AAC}
, { MKTAG( 'r', 'a', 'w', ' '), KA_ABLOCK_LPCM_LE}
, { MKTAG( 's', 'i', 'p', 'r'), KA_ABLOCK_SIPRO}
, { MKTAG( 's', 'o', 'w', 't'), KA_ABLOCK_LPCM_LE}
, { MKTAG( 't', 'w', 'o', 's'), KA_ABLOCK_LPCM_BE}
, { MKTAG(0x75,0x00,0x00,0x00), KA_ABLOCK_VOXWARE}
, { MKTAG( 'u', 'l', 'a', 'w'), KA_ABLOCK_ULAW}
, { MKTAG(0xFFu,0x00,0x00,0x00), KA_ABLOCK_AAC}
};

uint32_t ka_tag_to_audio(uint32_t fourcc)
{
  int a = 0, b = MAX_AUDIO_DB/2, c = MAX_AUDIO_DB;

  while (a < b)
  {
    if (fourcc < audio_db[b].fourcc)
    {
      c = b;
      b = (a + c)/2;
    }
    else if (fourcc > audio_db[b].fourcc)
    {
      a = b;
      b = (a + c)/2;
    }
    else return audio_db[b].id;
  }

  if (fourcc == audio_db[b].fourcc)
    return audio_db[b].id;

  return KA_ABLOCK_UNKNOWN;
}

const kav_vcodec_t* ka_block_to_vcodec(uint32_t typ)
{
  int id = (typ >> 16) & 0xff;

  if (id < MAX_VIDEO_TYPES)
    return vcodecs[id];

  return NULL;
}

const kav_scodec_t* ka_block_to_scodec(uint32_t typ)
{
  int id = (typ >> 16) & 0xff;

  if (id < MAX_SUBTITLES_TYPES)
    return scodecs[id];

  return NULL;
}

const char* ka_block_to_name(uint32_t typ)
{
  int id = (typ >> 16) & 0xff;

  switch(typ >> 24)
  {
    case 1:
    {
      if (id < MAX_AUDIO_TYPES)
        return acodec_names[id];

      return "Unkown audio format";
    }
    break;
    case 2:
    {
      if (id < MAX_VIDEO_TYPES)
        return vcodec_names[id];

      return "Unkown video format";
    }
    break;
    case 3:
    {
      if (id < MAX_SUBTITLES_TYPES)
        return scodec_names[id];

      return "Unkown subtitles format";
    }
    break;
  }

  return "None";
}
