/* MPEG-PS muxer plugin for GStreamer
 * Copyright 2008 Lin YANG <oxcsnicho@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/*
 * Unless otherwise indicated, Source Code is licensed under MIT license.
 * See further explanation attached in License Statement (distributed in the file
 * LICENSE).
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>
#include <gst/gst.h>

#include "mpegpsmux.h"
#include "psmuxcommon.h"
#include "psmuxstream.h"
#include "psmux.h"
#include "crc.h"

static gboolean psmux_packet_out (PsMux * mux);
static gboolean psmux_write_pack_header (PsMux * mux);
static gboolean psmux_write_system_header (PsMux * mux);
static gboolean psmux_write_program_stream_map (PsMux * mux);

/**
 * psmux_new:
 *
 * Create a new muxer session.
 *
 * Returns: A new #PsMux object.
 */
PsMux *
psmux_new (void)
{
  PsMux *mux;

  mux = g_slice_new0 (PsMux);

  mux->pts = -1;                /* uninitialized values */
  mux->pack_hdr_pts = -1;
  mux->sys_hdr_pts = -1;
  mux->psm_pts = -1;

  mux->bit_pts = 0;

  mux->pes_max_payload = PSMUX_PES_MAX_PAYLOAD;
  mux->bit_rate = 400 * 1024;   /* XXX: better default values? */
  mux->rate_bound = 2 * 1024;   /* 2* bit_rate / (8*50). XXX: any better default? */

  mux->pack_hdr_freq = PSMUX_PACK_HDR_FREQ;
  mux->sys_hdr_freq = PSMUX_SYS_HDR_FREQ;
  mux->psm_freq = PSMUX_PSM_FREQ;

  psmux_stream_id_info_init (&mux->id_info);

  return mux;
}

/**
 * psmux_set_write_func:
 * @mux: a #PsMux
 * @func: a user callback function
 * @user_data: user data passed to @func
 *
 * Set the callback function and user data to be called when @mux has output to
 * produce. @user_data will be passed as user data in @func.
 */
void
psmux_set_write_func (PsMux * mux, PsMuxWriteFunc func, void *user_data)
{
  g_return_if_fail (mux != NULL);

  mux->write_func = func;
  mux->write_func_data = user_data;
}

gboolean
psmux_write_end_code (PsMux * mux)
{
  guint8 end_code[4] = { 0, 0, 1, PSMUX_PROGRAM_END };
  return mux->write_func (end_code, 4, mux->write_func_data);
}


/**
 * psmux_free:
 * @mux: a #PsMux
 *
 * Free all resources associated with @mux. After calling this function @mux can
 * not be used anymore.
 */
void
psmux_free (PsMux * mux)
{
  GList *cur;

  g_return_if_fail (mux != NULL);

  /* Free all streams */
  for (cur = g_list_first (mux->streams); cur != NULL; cur = g_list_next (cur)) {
    PsMuxStream *stream = (PsMuxStream *) cur->data;

    psmux_stream_free (stream);
  }
  g_list_free (mux->streams);

  if (mux->sys_header != NULL)
    gst_buffer_unref (mux->sys_header);

  if (mux->psm != NULL)
    gst_buffer_unref (mux->psm);

  g_slice_free (PsMux, mux);
}

/**
 * psmux_create_stream:
 * @mux: a #PsMux
 * @stream_type: a #PsMuxStreamType
 *
 * Create a new stream of @stream_type in the muxer session @mux.
 *
 * Returns: a new #PsMuxStream.
 */
PsMuxStream *
psmux_create_stream (PsMux * mux, PsMuxStreamType stream_type)
{
  PsMuxStream *stream;
//  guint16 new_pid;

  g_return_val_if_fail (mux != NULL, NULL);

#if 0
  if (pid == PSMUX_PID_AUTO) {
    new_pid = psmux_get_new_pid (mux);
  } else {
    new_pid = pid & 0x1FFF;
  }

  /* Ensure we're not creating a PID collision */
  if (psmux_find_stream (mux, new_pid))
    return NULL;
#endif

  stream = psmux_stream_new (mux, stream_type);

  mux->streams = g_list_prepend (mux->streams, stream);
  if (stream->stream_id_ext) {
    if (!mux->nb_private_streams)
      mux->nb_streams++;
    mux->nb_private_streams++;
  } else
    mux->nb_streams++;

  if (stream->is_video_stream) {
    mux->video_bound++;
    if (mux->video_bound > 32)
      g_critical ("Number of video es exceeds upper limit");
  } else if (stream->is_audio_stream) {
    mux->audio_bound++;
    if (mux->audio_bound > 64)
      g_critical ("Number of audio es exceeds upper limit");
  }

  return stream;
}

static gboolean
psmux_packet_out (PsMux * mux)
{
  gboolean res;
  if (G_UNLIKELY (mux->write_func == NULL))
    return TRUE;

  res = mux->write_func (mux->packet_buf, mux->packet_bytes_written,
      mux->write_func_data);

  if (res) {
    mux->bit_size += mux->packet_bytes_written;
  }
  mux->packet_bytes_written = 0;
  return res;
}

/**
 * psmux_write_stream_packet:
 * @mux: a #PsMux
 * @stream: a #PsMuxStream
 *
 * Write a packet of @stream.
 *
 * Returns: TRUE if the packet could be written.
 */
gboolean
psmux_write_stream_packet (PsMux * mux, PsMuxStream * stream)
{
  gboolean res;

  g_return_val_if_fail (mux != NULL, FALSE);
  g_return_val_if_fail (stream != NULL, FALSE);


  {
    guint64 ts = psmux_stream_get_pts (stream);
    if (ts != -1)
      mux->pts = ts;
  }

  if (mux->pts - mux->pack_hdr_pts > PSMUX_PACK_HDR_INTERVAL
      || mux->pes_cnt % mux->pack_hdr_freq == 0) {
    /* Time to write pack header */
    /* FIXME: currently we write the mux rate of the PREVIOUS pack into the
     * pack header, because of the incapability to calculate the mux_rate
     * before outputing the pack. To calculate the mux_rate for the current
     * pack, we need to put the whole pack into buffer, calculate the
     * mux_rate, and then output the whole trunck.
     */
    if (mux->pts != -1 && mux->pts > mux->bit_pts
        && mux->pts - mux->bit_pts > PSMUX_BITRATE_CALC_INTERVAL) {
      /* XXX: smoothing the rate? */
      mux->bit_rate =
          gst_util_uint64_scale (mux->bit_size, 8 * CLOCKBASE,
          (mux->pts - mux->bit_pts));

      mux->bit_size = 0;
      mux->bit_pts = mux->pts;
    }

    psmux_write_pack_header (mux);
    mux->pack_hdr_pts = mux->pts;
  }

  if (mux->pes_cnt % mux->sys_hdr_freq == 0) {
    /* Time to write system header */
    psmux_write_system_header (mux);
    mux->sys_hdr_pts = mux->pts;
  }

  if (mux->pes_cnt % mux->psm_freq == 0) {
    /* Time to write program stream map (PSM) */
    psmux_write_program_stream_map (mux);
    mux->psm_pts = mux->pts;
  }

  /* Write the packet */
  if (!(mux->packet_bytes_written =
          psmux_stream_get_data (stream, mux->packet_buf,
              mux->pes_max_payload + PSMUX_PES_MAX_HDR_LEN))) {
    return FALSE;
  }

  res = psmux_packet_out (mux);
  if (!res) {
    GST_DEBUG_OBJECT (mux, "packet write false");
    return FALSE;
  }

  mux->pes_cnt += 1;

  return res;
}

static gboolean
psmux_write_pack_header (PsMux * mux)
{
  bits_buffer_t bw;
  guint64 scr = mux->pts;       /* XXX: is this correct? necessary to put any offset? */
  if (mux->pts == -1)
    scr = 0;

  /* pack_start_code */
  bits_initwrite (&bw, 14, mux->packet_buf);
  bits_write (&bw, 24, PSMUX_START_CODE_PREFIX);
  bits_write (&bw, 8, PSMUX_PACK_HEADER);

  /* scr */
  bits_write (&bw, 2, 0x1);
  bits_write (&bw, 3, (scr >> 30) & 0x07);
  bits_write (&bw, 1, 1);
  bits_write (&bw, 15, (scr >> 15) & 0x7fff);
  bits_write (&bw, 1, 1);
  bits_write (&bw, 15, scr & 0x7fff);
  bits_write (&bw, 1, 1);
  bits_write (&bw, 9, 0);       /* system_clock_reference_extension: set to 0 (like what VLC does) */
  bits_write (&bw, 1, 1);

  {
    /* Scale to get the mux_rate, rounding up */
    guint mux_rate =
        gst_util_uint64_scale (mux->bit_rate + 8 * 50 - 1, 1, 8 * 50);
    if (mux_rate > mux->rate_bound / 2)
      mux->rate_bound = mux_rate * 2;
    bits_write (&bw, 22, mux_rate);     /* program_mux_rate */
    bits_write (&bw, 2, 3);
  }

  bits_write (&bw, 5, 0x1f);
  bits_write (&bw, 3, 0);       /* pack_stuffing_length */

  mux->packet_bytes_written = 14;
  return psmux_packet_out (mux);
}

static void
psmux_ensure_system_header (PsMux * mux)
{
  bits_buffer_t bw;
  guint len = 12 + (mux->nb_streams +
      (mux->nb_private_streams > 1 ? mux->nb_private_streams - 1 : 0)) * 3;
  GList *cur;
  gboolean private_hit = FALSE;
  guint8 *data;

  if (mux->sys_header != NULL)
    return;

  data = g_malloc (len);

  bits_initwrite (&bw, len, data);

  /* system_header start code */
  bits_write (&bw, 24, PSMUX_START_CODE_PREFIX);
  bits_write (&bw, 8, PSMUX_SYSTEM_HEADER);

  bits_write (&bw, 16, len - 6);        /* header_length (bytes after this field) */
  bits_write (&bw, 1, 1);       /* marker */
  bits_write (&bw, 22, mux->rate_bound);        /* rate_bound */
  bits_write (&bw, 1, 1);       /* marker */
  bits_write (&bw, 6, mux->audio_bound);        /* audio_bound */
  bits_write (&bw, 1, 0);       /* fixed_flag */
  bits_write (&bw, 1, 0);       /* CSPS_flag */
  bits_write (&bw, 1, 0);       /* system_audio_lock_flag */
  bits_write (&bw, 1, 0);       /* system_video_lock_flag */
  bits_write (&bw, 1, 1);       /* marker */
  bits_write (&bw, 5, mux->video_bound);        /* video_bound */
  bits_write (&bw, 1, 0);       /* packet_rate_restriction_flag */
  bits_write (&bw, 7, 0x7f);    /* reserved_bits */

  for (cur = mux->streams, private_hit = FALSE; cur != NULL; cur = cur->next) {
    PsMuxStream *stream = (PsMuxStream *) cur->data;

    if (private_hit && stream->stream_id == PSMUX_EXTENDED_STREAM)
      continue;

    bits_write (&bw, 8, stream->stream_id);     /* stream_id */
    bits_write (&bw, 2, 0x3);   /* reserved */
    bits_write (&bw, 1, stream->is_video_stream);       /* buffer_bound_scale */
    bits_write (&bw, 13, stream->max_buffer_size / (stream->is_video_stream ? 1024 : 128));     /* buffer_size_bound */

    if (stream->stream_id == PSMUX_EXTENDED_STREAM)
      private_hit = TRUE;
  }

  GST_MEMDUMP ("System Header", data, len);

  mux->sys_header = gst_buffer_new_wrapped (data, len);
}

static gboolean
psmux_write_system_header (PsMux * mux)
{
  GstMapInfo map;

  psmux_ensure_system_header (mux);

  gst_buffer_map (mux->sys_header, &map, GST_MAP_READ);
  memcpy (mux->packet_buf, map.data, map.size);
  mux->packet_bytes_written = map.size;
  gst_buffer_unmap (mux->sys_header, &map);

  return psmux_packet_out (mux);
}

static void
psmux_ensure_program_stream_map (PsMux * mux)
{
  gint psm_size = 16, es_map_size = 0;
  bits_buffer_t bw;
  GList *cur;
  guint16 len;
  guint8 *pos;
  guint8 *data;

  if (mux->psm != NULL)
    return;

  /* pre-write the descriptor loop */
  pos = mux->es_info_buf;
  for (cur = mux->streams; cur != NULL; cur = cur->next) {
    PsMuxStream *stream = (PsMuxStream *) cur->data;
    len = 0;

    *pos++ = stream->stream_type;
    *pos++ = stream->stream_id;

    psmux_stream_get_es_descrs (stream, pos + 2, &len);
    psmux_put16 (&pos, len);

    es_map_size += len + 4;
    pos += len;
#if 0
    if (stream->lang[0] != 0)
      es_map_size += 6;
#endif
  }

  psm_size += es_map_size;

  data = g_malloc (psm_size);

  bits_initwrite (&bw, psm_size, data);

  /* psm start code */
  bits_write (&bw, 24, PSMUX_START_CODE_PREFIX);
  bits_write (&bw, 8, PSMUX_PROGRAM_STREAM_MAP);

  bits_write (&bw, 16, psm_size - 6);   /* psm_length */
  bits_write (&bw, 1, 1);       /* current_next_indicator */
  bits_write (&bw, 2, 0xF);     /* reserved */
  bits_write (&bw, 5, 0x1);     /* psm_version = 1 */
  bits_write (&bw, 7, 0xFF);    /* reserved */
  bits_write (&bw, 1, 1);       /* marker */

  bits_write (&bw, 16, 0);      /* program_stream_info_length */
  /* program_stream_info empty */

  bits_write (&bw, 16, es_map_size);    /* elementary_stream_map_length */

  memcpy (bw.p_data + bw.i_data, mux->es_info_buf, es_map_size);

  /* CRC32 */
  {
    guint32 crc = calc_crc32 (bw.p_data, psm_size - 4);
    guint8 *pos = bw.p_data + psm_size - 4;
    psmux_put32 (&pos, crc);
  }

  GST_MEMDUMP ("Program Stream Map", data, psm_size);

  mux->psm = gst_buffer_new_wrapped (data, psm_size);
}

static gboolean
psmux_write_program_stream_map (PsMux * mux)
{
  GstMapInfo map;

  psmux_ensure_program_stream_map (mux);

  gst_buffer_map (mux->psm, &map, GST_MAP_READ);
  memcpy (mux->packet_buf, map.data, map.size);
  mux->packet_bytes_written = map.size;
  gst_buffer_unmap (mux->psm, &map);

  return psmux_packet_out (mux);
}

GList *
psmux_get_stream_headers (PsMux * mux)
{
  GList *list;

  psmux_ensure_system_header (mux);
  psmux_ensure_program_stream_map (mux);

  list = g_list_append (NULL, gst_buffer_ref (mux->sys_header));
  list = g_list_append (list, gst_buffer_ref (mux->psm));

  return list;
}
