/*****************************************************************************
 * matroska.c:
 *****************************************************************************
 * Copyright (C) 2005 Mike Matsnev
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
 *****************************************************************************/

#include <stdlib.h>
#include <string.h>
#include "common/osdep.h"
#include "matroska.h"

#define	CLSIZE	  1048576
#define	CHECK(x)  do { if ((x) < 0) return -1; } while (0)

struct mk_Context {
  struct mk_Context *next, **prev, *parent;
  struct mk_Writer  *owner;
  unsigned	    id;

  void		    *data;
  unsigned	    d_cur, d_max;
};

typedef struct mk_Context mk_Context;

struct mk_Writer {
  FILE		      *fp;

  unsigned	      duration_ptr;

  mk_Context	      *root, *cluster, *frame;
  mk_Context	      *freelist;
  mk_Context	      *actlist;

  int64_t	      def_duration;
  int64_t	      timescale;
  int64_t	      cluster_tc_scaled;
  int64_t	      frame_tc, prev_frame_tc_scaled, max_frame_tc;

  char		      wrote_header, in_frame, keyframe;
};

static mk_Context *mk_createContext(mk_Writer *w, mk_Context *parent, unsigned id) {
  mk_Context  *c;

  if (w->freelist) {
    c = w->freelist;
    w->freelist = w->freelist->next;
  } else {
    c = malloc(sizeof(*c));
    memset(c, 0, sizeof(*c));
  }

  if (c == NULL)
    return NULL;

  c->parent = parent;
  c->owner = w;
  c->id = id;

  if (c->owner->actlist)
    c->owner->actlist->prev = &c->next;
  c->next = c->owner->actlist;
  c->prev = &c->owner->actlist;
  c->owner->actlist = c;

  return c;
}

static int	  mk_appendContextData(mk_Context *c, const void *data, unsigned size) {
  unsigned  ns = c->d_cur + size;

  if (ns > c->d_max) {
    void      *dp;
    unsigned  dn = c->d_max ? c->d_max << 1 : 16;
    while (ns > dn)
      dn <<= 1;

    dp = realloc(c->data, dn);
    if (dp == NULL)
      return -1;

    c->data = dp;
    c->d_max = dn;
  }

  memcpy((char*)c->data + c->d_cur, data, size);

  c->d_cur = ns;

  return 0;
}

static int	  mk_writeID(mk_Context *c, unsigned id) {
  unsigned char	  c_id[4] = { id >> 24, id >> 16, id >> 8, id };

  if (c_id[0])
    return mk_appendContextData(c, c_id, 4);
  if (c_id[1])
    return mk_appendContextData(c, c_id+1, 3);
  if (c_id[2])
    return mk_appendContextData(c, c_id+2, 2);
  return mk_appendContextData(c, c_id+3, 1);
}

static int	  mk_writeSize(mk_Context *c, unsigned size) {
  unsigned char	  c_size[5] = { 0x08, size >> 24, size >> 16, size >> 8, size };

  if (size < 0x7f) {
    c_size[4] |= 0x80;
    return mk_appendContextData(c, c_size+4, 1);
  }
  if (size < 0x3fff) {
    c_size[3] |= 0x40;
    return mk_appendContextData(c, c_size+3, 2);
  }
  if (size < 0x1fffff) {
    c_size[2] |= 0x20;
    return mk_appendContextData(c, c_size+2, 3);
  }
  if (size < 0x0fffffff) {
    c_size[1] |= 0x10;
    return mk_appendContextData(c, c_size+1, 4);
  }
  return mk_appendContextData(c, c_size, 5);
}

static int	  mk_flushContextID(mk_Context *c) {
  unsigned char	ff = 0xff;

  if (c->id == 0)
    return 0;

  CHECK(mk_writeID(c->parent, c->id));
  CHECK(mk_appendContextData(c->parent, &ff, 1));

  c->id = 0;

  return 0;
}

static int	  mk_flushContextData(mk_Context *c) {
  if (c->d_cur == 0)
    return 0;

  if (c->parent)
    CHECK(mk_appendContextData(c->parent, c->data, c->d_cur));
  else
    if (fwrite(c->data, c->d_cur, 1, c->owner->fp) != 1)
      return -1;

  c->d_cur = 0;

  return 0;
}

static int	  mk_closeContext(mk_Context *c, unsigned *off) {
  if (c->id) {
    CHECK(mk_writeID(c->parent, c->id));
    CHECK(mk_writeSize(c->parent, c->d_cur));
  }

  if (c->parent && off != NULL)
    *off += c->parent->d_cur;

  CHECK(mk_flushContextData(c));

  if (c->next)
    c->next->prev = c->prev;
  *(c->prev) = c->next;
  c->next = c->owner->freelist;
  c->owner->freelist = c;

  return 0;
}

static void	  mk_destroyContexts(mk_Writer *w) {
  mk_Context  *cur, *next;

  for (cur = w->freelist; cur; cur = next) {
    next = cur->next;
    free(cur->data);
    free(cur);
  }

  for (cur = w->actlist; cur; cur = next) {
    next = cur->next;
    free(cur->data);
    free(cur);
  }

  w->freelist = w->actlist = w->root = NULL;
}

static int	  mk_writeStr(mk_Context *c, unsigned id, const char *str) {
  size_t  len = strlen(str);

  CHECK(mk_writeID(c, id));
  CHECK(mk_writeSize(c, len));
  CHECK(mk_appendContextData(c, str, len));
  return 0;
}

static int	  mk_writeBin(mk_Context *c, unsigned id, const void *data, unsigned size) {
  CHECK(mk_writeID(c, id));
  CHECK(mk_writeSize(c, size));
  CHECK(mk_appendContextData(c, data, size));
  return 0;
}

static int	  mk_writeUInt(mk_Context *c, unsigned id, int64_t ui) {
  unsigned char	  c_ui[8] = { ui >> 56, ui >> 48, ui >> 40, ui >> 32, ui >> 24, ui >> 16, ui >> 8, ui };
  unsigned	  i = 0;

  CHECK(mk_writeID(c, id));
  while (i < 7 && c_ui[i] == 0)
    ++i;
  CHECK(mk_writeSize(c, 8 - i));
  CHECK(mk_appendContextData(c, c_ui+i, 8 - i));
  return 0;
}

static int  	  mk_writeSInt(mk_Context *c, unsigned id, int64_t si) {
  unsigned char	  c_si[8] = { si >> 56, si >> 48, si >> 40, si >> 32, si >> 24, si >> 16, si >> 8, si };
  unsigned	  i = 0;

  CHECK(mk_writeID(c, id));
  if (si < 0)
    while (i < 7 && c_si[i] == 0xff && c_si[i+1] & 0x80)
      ++i;
  else
    while (i < 7 && c_si[i] == 0 && !(c_si[i+1] & 0x80))
      ++i;
  CHECK(mk_writeSize(c, 8 - i));
  CHECK(mk_appendContextData(c, c_si+i, 8 - i));
  return 0;
}

static int	  mk_writeFloatRaw(mk_Context *c, float f) {
  union {
    float f;
    unsigned u;
  } u;
  unsigned char	c_f[4];

  u.f = f;
  c_f[0] = u.u >> 24;
  c_f[1] = u.u >> 16;
  c_f[2] = u.u >> 8;
  c_f[3] = u.u;

  return mk_appendContextData(c, c_f, 4);
}

static int	  mk_writeFloat(mk_Context *c, unsigned id, float f) {
  CHECK(mk_writeID(c, id));
  CHECK(mk_writeSize(c, 4));
  CHECK(mk_writeFloatRaw(c, f));
  return 0;
}

static unsigned	  mk_ebmlSizeSize(unsigned s) {
  if (s < 0x7f)
    return 1;
  if (s < 0x3fff)
    return 2;
  if (s < 0x1fffff)
    return 3;
  if (s < 0x0fffffff)
    return 4;
  return 5;
}

static unsigned	  mk_ebmlSIntSize(int64_t si) {
  unsigned char	  c_si[8] = { si >> 56, si >> 48, si >> 40, si >> 32, si >> 24, si >> 16, si >> 8, si };
  unsigned	  i = 0;

  if (si < 0)
    while (i < 7 && c_si[i] == 0xff && c_si[i+1] & 0x80)
      ++i;
  else
    while (i < 7 && c_si[i] == 0 && !(c_si[i+1] & 0x80))
      ++i;

  return 8 - i;
}

mk_Writer *mk_createWriter(const char *filename) {
  mk_Writer *w = malloc(sizeof(*w));
  if (w == NULL)
    return NULL;

  memset(w, 0, sizeof(*w));

  w->root = mk_createContext(w, NULL, 0);
  if (w->root == NULL) {
    free(w);
    return NULL;
  }

  w->fp = fopen(filename, "wb");
  if (w->fp == NULL) {
    mk_destroyContexts(w);
    free(w);
    return NULL;
  }

  w->timescale = 1000000;

  return w;
}

int	  mk_writeHeader(mk_Writer *w, const char *writingApp,
			 const char *codecID,
			 const void *codecPrivate, unsigned codecPrivateSize,
			 int64_t default_frame_duration,
			 int64_t timescale,
			 unsigned width, unsigned height,
			 unsigned d_width, unsigned d_height)
{
  mk_Context  *c, *ti, *v;

  if (w->wrote_header)
    return -1;

  w->timescale = timescale;
  w->def_duration = default_frame_duration;

  if ((c = mk_createContext(w, w->root, 0x1a45dfa3)) == NULL) // EBML
    return -1;
  CHECK(mk_writeUInt(c, 0x4286, 1)); // EBMLVersion
  CHECK(mk_writeUInt(c, 0x42f7, 1)); // EBMLReadVersion
  CHECK(mk_writeUInt(c, 0x42f2, 4)); // EBMLMaxIDLength
  CHECK(mk_writeUInt(c, 0x42f3, 8)); // EBMLMaxSizeLength
  CHECK(mk_writeStr(c, 0x4282, "matroska")); // DocType
  CHECK(mk_writeUInt(c, 0x4287, 1)); // DocTypeVersion
  CHECK(mk_writeUInt(c, 0x4285, 1)); // DocTypeReadversion
  CHECK(mk_closeContext(c, 0));

  if ((c = mk_createContext(w, w->root, 0x18538067)) == NULL) // Segment
    return -1;
  CHECK(mk_flushContextID(c));
  CHECK(mk_closeContext(c, 0));

  if ((c = mk_createContext(w, w->root, 0x1549a966)) == NULL) // SegmentInfo
    return -1;
  CHECK(mk_writeStr(c, 0x4d80, "Haali Matroska Writer b0"));
  CHECK(mk_writeStr(c, 0x5741, writingApp));
  CHECK(mk_writeUInt(c, 0x2ad7b1, w->timescale));
  CHECK(mk_writeFloat(c, 0x4489, 0));
  w->duration_ptr = c->d_cur - 4;
  CHECK(mk_closeContext(c, &w->duration_ptr));

  if ((c = mk_createContext(w, w->root, 0x1654ae6b)) == NULL) // tracks
    return -1;
  if ((ti = mk_createContext(w, c, 0xae)) == NULL) // TrackEntry
    return -1;
  CHECK(mk_writeUInt(ti, 0xd7, 1)); // TrackNumber
  CHECK(mk_writeUInt(ti, 0x73c5, 1)); // TrackUID
  CHECK(mk_writeUInt(ti, 0x83, 1)); // TrackType
  CHECK(mk_writeUInt(ti, 0x9c, 0)); // FlagLacing
  CHECK(mk_writeStr(ti, 0x86, codecID)); // CodecID
  if (codecPrivateSize)
    CHECK(mk_writeBin(ti, 0x63a2, codecPrivate, codecPrivateSize)); // CodecPrivate
  if (default_frame_duration)
    CHECK(mk_writeUInt(ti, 0x23e383, default_frame_duration)); // DefaultDuration

  if ((v = mk_createContext(w, ti, 0xe0)) == NULL) // Video
    return -1;
  CHECK(mk_writeUInt(v, 0xb0, width));
  CHECK(mk_writeUInt(v, 0xba, height));
  CHECK(mk_writeUInt(v, 0x54b0, d_width));
  CHECK(mk_writeUInt(v, 0x54ba, d_height));
  CHECK(mk_closeContext(v, 0));

  CHECK(mk_closeContext(ti, 0));

  CHECK(mk_closeContext(c, 0));

  CHECK(mk_flushContextData(w->root));

  w->wrote_header = 1;

  return 0;
}

static int mk_closeCluster(mk_Writer *w) {
  if (w->cluster == NULL)
    return 0;
  CHECK(mk_closeContext(w->cluster, 0));
  w->cluster = NULL;
  CHECK(mk_flushContextData(w->root));
  return 0;
}

static int mk_flushFrame(mk_Writer *w) {
  int64_t	delta, ref = 0;
  unsigned	fsize, bgsize;
  unsigned char	c_delta_flags[3];

  if (!w->in_frame)
    return 0;

  delta = w->frame_tc/w->timescale - w->cluster_tc_scaled;
  if (delta > 32767ll || delta < -32768ll)
    CHECK(mk_closeCluster(w));

  if (w->cluster == NULL) {
    w->cluster_tc_scaled = w->frame_tc / w->timescale;
    w->cluster = mk_createContext(w, w->root, 0x1f43b675); // Cluster
    if (w->cluster == NULL)
      return -1;

    CHECK(mk_writeUInt(w->cluster, 0xe7, w->cluster_tc_scaled)); // Timecode

    delta = 0;
  }

  fsize = w->frame ? w->frame->d_cur : 0;
  bgsize = fsize + 4 + mk_ebmlSizeSize(fsize + 4) + 1;
  if (!w->keyframe) {
    ref = w->prev_frame_tc_scaled - w->cluster_tc_scaled - delta;
    bgsize += 1 + 1 + mk_ebmlSIntSize(ref);
  }

  CHECK(mk_writeID(w->cluster, 0xa0)); // BlockGroup
  CHECK(mk_writeSize(w->cluster, bgsize));
  CHECK(mk_writeID(w->cluster, 0xa1)); // Block
  CHECK(mk_writeSize(w->cluster, fsize + 4));
  CHECK(mk_writeSize(w->cluster, 1)); // track number

  c_delta_flags[0] = delta >> 8;
  c_delta_flags[1] = delta;
  c_delta_flags[2] = 0;
  CHECK(mk_appendContextData(w->cluster, c_delta_flags, 3));
  if (w->frame) {
    CHECK(mk_appendContextData(w->cluster, w->frame->data, w->frame->d_cur));
    w->frame->d_cur = 0;
  }
  if (!w->keyframe)
    CHECK(mk_writeSInt(w->cluster, 0xfb, ref)); // ReferenceBlock

  w->in_frame = 0;
  w->prev_frame_tc_scaled = w->cluster_tc_scaled + delta;

  if (w->cluster->d_cur > CLSIZE)
    CHECK(mk_closeCluster(w));

  return 0;
}

int	  mk_startFrame(mk_Writer *w) {
  if (mk_flushFrame(w) < 0)
    return -1;

  w->in_frame = 1;
  w->keyframe = 0;

  return 0;
}

int	  mk_setFrameFlags(mk_Writer *w,int64_t timestamp, int keyframe) {
  if (!w->in_frame)
    return -1;

  w->frame_tc = timestamp;
  w->keyframe = keyframe != 0;

  if (w->max_frame_tc < timestamp)
    w->max_frame_tc = timestamp;

  return 0;
}

int	  mk_addFrameData(mk_Writer *w, const void *data, unsigned size) {
  if (!w->in_frame)
    return -1;

  if (w->frame == NULL)
    if ((w->frame = mk_createContext(w, NULL, 0)) == NULL)
      return -1;

  return mk_appendContextData(w->frame, data, size);
}

int	  mk_close(mk_Writer *w) {
  int	ret = 0;
  if (mk_flushFrame(w) < 0 || mk_closeCluster(w) < 0)
    ret = -1;
  if (w->wrote_header) {
    fseek(w->fp, w->duration_ptr, SEEK_SET);
    if (mk_writeFloatRaw(w->root, (float)((double)(w->max_frame_tc+w->def_duration) / w->timescale)) < 0 ||
	mk_flushContextData(w->root) < 0)
      ret = -1;
  }
  mk_destroyContexts(w);
  fclose(w->fp);
  free(w);
  return ret;
}

