/* 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 "psmuxcommon.h"
#include "psmuxstream.h"
#include "psmux.h"

static guint8 psmux_stream_pes_header_length (PsMuxStream * stream);
static void psmux_stream_write_pes_header (PsMuxStream * stream, guint8 * data);
static void psmux_stream_find_pts_dts_within (PsMuxStream * stream, guint bound,
    gint64 * pts, gint64 * dts);

/**
 * psmux_stream_new:
 * @pid: a PID
 * @stream_type: the stream type
 *
 * Create a new stream with type = @stream_type, assign stream id accordingly
 *
 * Returns: a new #PsMuxStream.
 */
PsMuxStream *
psmux_stream_new (PsMux * mux, PsMuxStreamType stream_type)
{
  PsMuxStream *stream = g_slice_new0 (PsMuxStream);
  PsMuxStreamIdInfo *info = &(mux->id_info);

  stream->stream_type = stream_type;
  stream->is_audio_stream = FALSE;
  stream->is_video_stream = FALSE;
  stream->stream_id = 0;
  stream->max_buffer_size = 0;

  switch (stream_type) {
      /* MPEG AUDIO */
    case PSMUX_ST_AUDIO_MPEG1:
    case PSMUX_ST_AUDIO_MPEG2:
      stream->max_buffer_size = 2484;   /* ISO/IEC 13818 2.5.2.4 */
    case PSMUX_ST_AUDIO_AAC:
      if (info->id_mpga > PSMUX_STREAM_ID_MPGA_MAX)
        break;
      stream->stream_id = info->id_mpga++;
      stream->stream_id_ext = 0;
      stream->is_audio_stream = TRUE;
      break;
      /* MPEG VIDEO */
    case PSMUX_ST_VIDEO_MPEG1:
    case PSMUX_ST_VIDEO_MPEG2:
    case PSMUX_ST_VIDEO_MPEG4:
    case PSMUX_ST_VIDEO_H264:
      if (info->id_mpgv > PSMUX_STREAM_ID_MPGV_MAX)
        break;
      stream->stream_id = info->id_mpgv++;
      stream->stream_id_ext = 0;
      stream->is_video_stream = TRUE;
      break;
      /* AC3 / A52 */
    case PSMUX_ST_PS_AUDIO_AC3:
      if (info->id_ac3 > PSMUX_STREAM_ID_AC3_MAX)
        break;
      stream->stream_id = PSMUX_PRIVATE_STREAM_1;
      stream->stream_id_ext = info->id_ac3++;
      stream->is_audio_stream = TRUE;
      /* AC3 requires data alignment */
      stream->pi.flags |= PSMUX_PACKET_FLAG_PES_DATA_ALIGN;
      break;
      /* TODO: SPU missing */
#if 0
    case spu:
      if (info->id_spu > PSMUX_STREAM_ID_SPU_MAX)
        break;
      return info->id_spu++;
#endif
      /* DTS */
    case PSMUX_ST_PS_AUDIO_DTS:
      if (info->id_dts > PSMUX_STREAM_ID_DTS_MAX)
        break;
      stream->stream_id = PSMUX_PRIVATE_STREAM_1;
      stream->stream_id_ext = info->id_dts++;
      stream->is_audio_stream = TRUE;
      break;
      /* LPCM */
    case PSMUX_ST_PS_AUDIO_LPCM:
      if (info->id_lpcm > PSMUX_STREAM_ID_LPCM_MAX)
        break;
      stream->stream_id = PSMUX_PRIVATE_STREAM_1;
      stream->stream_id_ext = info->id_lpcm++;
      stream->is_audio_stream = TRUE;
      break;
    case PSMUX_ST_VIDEO_DIRAC:
      if (info->id_dirac > PSMUX_STREAM_ID_DIRAC_MAX)
        break;
      stream->stream_id = PSMUX_EXTENDED_STREAM;
      stream->stream_id_ext = info->id_dirac++;
      stream->is_video_stream = TRUE;
      break;
    default:
      g_critical ("Stream type 0x%0x not yet implemented", stream_type);
      break;
  }

  if (stream->stream_id == 0) {
    g_critical ("Number of elementary streams of type %04x exceeds maximum",
        stream->stream_type);
    g_slice_free (PsMuxStream, stream);
    return NULL;
  }

  /* XXX: Are private streams also using stream_id_ext? */
  if (stream->stream_id == PSMUX_EXTENDED_STREAM)
    stream->pi.flags |= PSMUX_PACKET_FLAG_PES_EXT_STREAMID;

  /* Are these useful at all? */
  if (stream->stream_id == PSMUX_PROGRAM_STREAM_MAP ||
      stream->stream_id == PSMUX_PADDING_STREAM ||
      stream->stream_id == PSMUX_PRIVATE_STREAM_2 ||
      stream->stream_id == PSMUX_ECM ||
      stream->stream_id == PSMUX_EMM ||
      stream->stream_id == PSMUX_PROGRAM_STREAM_DIRECTORY ||
      stream->stream_id == PSMUX_DSMCC_STREAM ||
      stream->stream_id == PSMUX_ITU_T_H222_1_TYPE_E)
    stream->pi.flags &= ~PSMUX_PACKET_FLAG_PES_FULL_HEADER;
  else
    stream->pi.flags |= PSMUX_PACKET_FLAG_PES_FULL_HEADER;

  stream->buffers = NULL;
  stream->bytes_avail = 0;
  stream->cur_buffer = NULL;
  stream->cur_buffer_consumed = 0;

  stream->cur_pes_payload_size = 0;

  stream->pts = -1;
  stream->dts = -1;
  stream->last_pts = -1;

  /* These fields are set by gstreamer */
  stream->audio_sampling = 0;
  stream->audio_channels = 0;
  stream->audio_bitrate = 0;

  if (stream->max_buffer_size == 0) {
    /* XXX: VLC'S VALUE. Better default? */
    if (stream->is_video_stream)
      stream->max_buffer_size = 400 * 1024;
    else if (stream->is_audio_stream)
      stream->max_buffer_size = 4 * 1024;
    else
      g_assert_not_reached ();
  }

  return stream;
}

/**
 * psmux_stream_free:
 * @stream: a #PsMuxStream
 *
 * Free the resources of @stream.
 */
void
psmux_stream_free (PsMuxStream * stream)
{
  g_return_if_fail (stream != NULL);

  if (psmux_stream_bytes_in_buffer (stream)) {
    g_warning ("Freeing stream with data not yet processed");
  }
  g_slice_free (PsMuxStream, stream);
}

/* Advance the current packet stream position by len bytes.
 * Mustn't consume more than available in the current packet */
static void
psmux_stream_consume (PsMuxStream * stream, guint len)
{
  g_assert (stream->cur_buffer != NULL);
  g_assert (len <= stream->cur_buffer->map.size - stream->cur_buffer_consumed);

  stream->cur_buffer_consumed += len;
  stream->bytes_avail -= len;

  if (stream->cur_buffer_consumed == 0)
    return;

  if (stream->cur_buffer->pts != -1)
    stream->last_pts = stream->cur_buffer->pts;

  if (stream->cur_buffer_consumed == stream->cur_buffer->map.size) {
    /* Current packet is completed, move along */
    stream->buffers = g_list_delete_link (stream->buffers, stream->buffers);

    gst_buffer_unmap (stream->cur_buffer->buf, &stream->cur_buffer->map);
    gst_buffer_unref (stream->cur_buffer->buf);
    g_slice_free (PsMuxStreamBuffer, stream->cur_buffer);
    stream->cur_buffer = NULL;
  }
}


/**
 * psmux_stream_bytes_in_buffer:
 * @stream: a #PsMuxStream
 *
 * Calculate how much bytes are in the buffer.
 *
 * Returns: The number of bytes in the buffer.
 */
gint
psmux_stream_bytes_in_buffer (PsMuxStream * stream)
{
  g_return_val_if_fail (stream != NULL, 0);

  return stream->bytes_avail;
}

/**
 * psmux_stream_get_data:
 * @stream: a #PsMuxStream
 * @buf: a buffer to hold the result
 * @len: the length of @buf
 *
 * Write a PES packet to @buf, up to @len bytes
 *
 * Returns: number of bytes having been written, 0 if error
 */
guint
psmux_stream_get_data (PsMuxStream * stream, guint8 * buf, guint len)
{
  guint8 pes_hdr_length;
  guint w;

  g_return_val_if_fail (stream != NULL, FALSE);
  g_return_val_if_fail (buf != NULL, FALSE);
  g_return_val_if_fail (len >= PSMUX_PES_MAX_HDR_LEN, FALSE);

  stream->cur_pes_payload_size =
      MIN (psmux_stream_bytes_in_buffer (stream), len - PSMUX_PES_MAX_HDR_LEN);
  /* Note that we cannot make a better estimation of the header length for the
   * time being; because the header length is dependent on whether we can find a
   * timestamp in the upcomming buffers, which in turn depends on
   * cur_pes_payload_size, which is exactly what we want to decide.
   */

  psmux_stream_find_pts_dts_within (stream, stream->cur_pes_payload_size,
      &stream->pts, &stream->dts);

  /* clear pts/dts flag */
  stream->pi.flags &= ~(PSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS |
      PSMUX_PACKET_FLAG_PES_WRITE_PTS);
  /* update pts/dts flag */
  if (stream->pts != -1 && stream->dts != -1)
    stream->pi.flags |= PSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS;
  else {
    if (stream->pts != -1)
      stream->pi.flags |= PSMUX_PACKET_FLAG_PES_WRITE_PTS;
  }

  pes_hdr_length = psmux_stream_pes_header_length (stream);

  /* write pes header */
  GST_LOG ("Writing PES header of length %u and payload %d",
      pes_hdr_length, stream->cur_pes_payload_size);
  psmux_stream_write_pes_header (stream, buf);

  buf += pes_hdr_length;
  w = stream->cur_pes_payload_size;     /* number of bytes of payload to write */

  while (w > 0) {
    guint32 avail;
    guint8 *cur;

    if (stream->cur_buffer == NULL) {
      /* Start next packet */
      if (stream->buffers == NULL)
        return FALSE;
      stream->cur_buffer = (PsMuxStreamBuffer *) (stream->buffers->data);
      stream->cur_buffer_consumed = 0;
    }

    /* Take as much as we can from the current buffer */
    avail = stream->cur_buffer->map.size - stream->cur_buffer_consumed;
    cur = stream->cur_buffer->map.data + stream->cur_buffer_consumed;
    if (avail < w) {
      memcpy (buf, cur, avail);
      psmux_stream_consume (stream, avail);

      buf += avail;
      w -= avail;
    } else {
      memcpy (buf, cur, w);
      psmux_stream_consume (stream, w);

      w = 0;
    }
  }

  return pes_hdr_length + stream->cur_pes_payload_size;
}

static guint8
psmux_stream_pes_header_length (PsMuxStream * stream)
{
  guint8 packet_len;

  /* Calculate the length of the header for this stream */

  /* start_code prefix + stream_id + pes_packet_length = 6 bytes */
  packet_len = 6;

  if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_FULL_HEADER) {
    /* For a PES 'full header' we have at least 3 more bytes, 
     * and then more based on flags */
    packet_len += 3;
    if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS) {
      packet_len += 10;
    } else if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_WRITE_PTS) {
      packet_len += 5;
    }
    if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_EXT_STREAMID) {
      /* Need basic extension flags (1 byte), plus 2 more bytes for the 
       * length + extended stream id */
      packet_len += 3;
    }
  }

  return packet_len;
}

/* Find a PTS/DTS to write into the pes header within the next bound bytes
 * of the data */
static void
psmux_stream_find_pts_dts_within (PsMuxStream * stream, guint bound,
    gint64 * pts, gint64 * dts)
{
  /* 1. When there are at least one buffer then output the first buffer with
   * pts/dts
   * 2. If the bound is too small to include even one buffer, output the pts/dts
   * of that buffer.
   */
  GList *cur;

  *pts = -1;
  *dts = -1;

  for (cur = g_list_first (stream->buffers); cur != NULL;
      cur = g_list_next (cur)) {
    PsMuxStreamBuffer *curbuf = cur->data;

    /* FIXME: This isn't quite correct - if the 'bound' is within this
     * buffer, we don't know if the timestamp is before or after the split
     * so we shouldn't return it */
    if (bound <= curbuf->map.size) {
      *pts = curbuf->pts;
      *dts = curbuf->dts;
      return;
    }

    /* Have we found a buffer with pts/dts set? */
    if (curbuf->pts != -1 || curbuf->dts != -1) {
      *pts = curbuf->pts;
      *dts = curbuf->dts;
      return;
    }

    bound -= curbuf->map.size;
  }
}

static void
psmux_stream_write_pes_header (PsMuxStream * stream, guint8 * data)
{
  guint16 length_to_write;
  guint8 hdr_len = psmux_stream_pes_header_length (stream);

  /* start_code prefix + stream_id + pes_packet_length = 6 bytes */
  data[0] = 0x00;
  data[1] = 0x00;
  data[2] = 0x01;
  data[3] = stream->stream_id;
  data += 4;

  length_to_write = hdr_len - 6 + stream->cur_pes_payload_size;

  psmux_put16 (&data, length_to_write);

  if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_FULL_HEADER) {
    guint8 flags = 0;

    /* Not scrambled, original, not-copyrighted, data_alignment specified by flag */
    flags = 0x81;
    if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_DATA_ALIGN)
      flags |= 0x04;            /* Enable data_alignment_indicator */
    *data++ = flags;

    /* Flags */
    flags = 0;
    if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS)
      flags |= 0xC0;
    else if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_WRITE_PTS)
      flags |= 0x80;
    if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_EXT_STREAMID)
      flags |= 0x01;            /* Enable PES_extension_flag */
    *data++ = flags;

    /* Header length is the total pes length, 
     * minus the 9 bytes of start codes, flags + hdr_len */
    g_return_if_fail (hdr_len >= 9);
    *data++ = (hdr_len - 9);

    if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS) {
      psmux_put_ts (&data, 0x3, stream->pts);
      psmux_put_ts (&data, 0x1, stream->dts);
    } else if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_WRITE_PTS) {
      psmux_put_ts (&data, 0x2, stream->pts);
    }

    if (stream->pi.flags & PSMUX_PACKET_FLAG_PES_EXT_STREAMID) {
      guint8 ext_len;

      flags = 0x0f;             /* preceeding flags all 0 | (reserved bits) | PES_extension_flag_2 */
      *data++ = flags;

      ext_len = 1;              /* Only writing 1 byte into the extended fields */
      *data++ = 0x80 | ext_len; /* marker | PES_extension_field_length */
      *data++ = 0x80 | stream->stream_id_ext;   /* stream_id_extension_flag | extended_stream_id */
    }
  }
}

/**
 * psmux_stream_add_data:
 * @stream: a #PsMuxStream
 * @buffer: (transfer full): buffer with data to add
 * @pts: PTS of access unit in @data
 * @dts: DTS of access unit in @data
 *
 * Submit @len bytes of @data into @stream. @pts and @dts can be set to the
 * timestamp (against a 90Hz clock) of the first access unit in @data. A
 * timestamp of -1 for @pts or @dts means unknown.
 *
 * This function takes ownership of @buffer.
 */
void
psmux_stream_add_data (PsMuxStream * stream, GstBuffer * buffer,
    gint64 pts, gint64 dts, gboolean keyunit)
{
  PsMuxStreamBuffer *packet;

  g_return_if_fail (stream != NULL);

  packet = g_slice_new (PsMuxStreamBuffer);
  packet->buf = buffer;

  if (!gst_buffer_map (packet->buf, &packet->map, GST_MAP_READ)) {
    GST_ERROR ("Failed to map buffer for reading");
    gst_buffer_unref (packet->buf);
    g_slice_free (PsMuxStreamBuffer, packet);
    return;
  }

  packet->keyunit = keyunit;
  packet->pts = pts;
  packet->dts = dts;

  if (stream->bytes_avail == 0)
    stream->last_pts = pts;

  stream->bytes_avail += packet->map.size;
  /* FIXME: perhaps use GstQueueArray instead? */
  stream->buffers = g_list_append (stream->buffers, packet);

}

/**
 * psmux_stream_get_es_descrs:
 * @stream: a #PsMuxStream
 * @buf: a buffer to hold the ES descriptor
 * @len: the length used in @buf
 *
 * Write an Elementary Stream Descriptor for @stream into @buf. the number of
 * bytes consumed in @buf will be updated in @len.
 *
 * @buf and @len must be at least #PSMUX_MIN_ES_DESC_LEN.
 */
void
psmux_stream_get_es_descrs (PsMuxStream * stream, guint8 * buf, guint16 * len)
{
  guint8 *pos;

  g_return_if_fail (stream != NULL);

  if (buf == NULL) {
    if (len != NULL)
      *len = 0;
    return;
  }

  /* Based on the stream type, write out any descriptors to go in the 
   * PMT ES_info field */
  pos = buf;

  /* tag (registration_descriptor), length, format_identifier */
  switch (stream->stream_type) {
    case PSMUX_ST_AUDIO_AAC:
      /* FIXME */
      break;
    case PSMUX_ST_VIDEO_MPEG4:
      /* FIXME */
      break;
    case PSMUX_ST_VIDEO_H264:
      *pos++ = 0x05;
      *pos++ = 8;
      *pos++ = 0x48;            /* 'H' */
      *pos++ = 0x44;            /* 'D' */
      *pos++ = 0x4D;            /* 'M' */
      *pos++ = 0x56;            /* 'V' */
      /* FIXME : Not sure about this additional_identification_info */
      *pos++ = 0xFF;
      *pos++ = 0x1B;
      *pos++ = 0x44;
      *pos++ = 0x3F;
      break;
    case PSMUX_ST_VIDEO_DIRAC:
      *pos++ = 0x05;
      *pos++ = 4;
      *pos++ = 0x64;            /* 'd' */
      *pos++ = 0x72;            /* 'r' */
      *pos++ = 0x61;            /* 'a' */
      *pos++ = 0x63;            /* 'c' */
      break;
    case PSMUX_ST_PS_AUDIO_AC3:
    {
      *pos++ = 0x05;
      *pos++ = 4;
      *pos++ = 0x41;            /* 'A' */
      *pos++ = 0x43;            /* 'C' */
      *pos++ = 0x2D;            /* '-' */
      *pos++ = 0x33;            /* '3' */

      /* audio_stream_descriptor () | ATSC A/52-2001 Annex A
       *
       * descriptor_tag       8 uimsbf
       * descriptor_length    8 uimsbf
       * sample_rate_code     3 bslbf
       * bsid                 5 bslbf
       * bit_rate_code        6 bslbf
       * surround_mode        2 bslbf
       * bsmod                3 bslbf
       * num_channels         4 bslbf
       * full_svc             1 bslbf
       * langcod              8 bslbf
       * [...]
       */
      *pos++ = 0x81;
      *pos++ = 0x04;

      /* 3 bits sample_rate_code, 5 bits hardcoded bsid (default ver 8) */
      switch (stream->audio_sampling) {
        case 48000:
          *pos++ = 0x08;
          break;
        case 44100:
          *pos++ = 0x28;
          break;
        case 32000:
          *pos++ = 0x48;
          break;
        default:
          *pos++ = 0xE8;
          break;                /* 48, 44.1 or 32 Khz */
      }

      /* 1 bit bit_rate_limit, 5 bits bit_rate_code, 2 bits suround_mode */
      switch (stream->audio_bitrate) {
        case 32:
          *pos++ = 0x00 << 2;
          break;
        case 40:
          *pos++ = 0x01 << 2;
          break;
        case 48:
          *pos++ = 0x02 << 2;
          break;
        case 56:
          *pos++ = 0x03 << 2;
          break;
        case 64:
          *pos++ = 0x04 << 2;
          break;
        case 80:
          *pos++ = 0x05 << 2;
          break;
        case 96:
          *pos++ = 0x06 << 2;
          break;
        case 112:
          *pos++ = 0x07 << 2;
          break;
        case 128:
          *pos++ = 0x08 << 2;
          break;
        case 160:
          *pos++ = 0x09 << 2;
          break;
        case 192:
          *pos++ = 0x0A << 2;
          break;
        case 224:
          *pos++ = 0x0B << 2;
          break;
        case 256:
          *pos++ = 0x0C << 2;
          break;
        case 320:
          *pos++ = 0x0D << 2;
          break;
        case 384:
          *pos++ = 0x0E << 2;
          break;
        case 448:
          *pos++ = 0x0F << 2;
          break;
        case 512:
          *pos++ = 0x10 << 2;
          break;
        case 576:
          *pos++ = 0x11 << 2;
          break;
        case 640:
          *pos++ = 0x12 << 2;
          break;
        default:
          *pos++ = 0x32 << 2;
          break;                /* 640 Kb/s upper limit */
      }

      /* 3 bits bsmod, 4 bits num_channels, 1 bit full_svc */
      switch (stream->audio_channels) {
        case 1:
          *pos++ = 0x01 << 1;
          break;                /* 1/0 */
        case 2:
          *pos++ = 0x02 << 1;
          break;                /* 2/0 */
        case 3:
          *pos++ = 0x0A << 1;
          break;                /* <= 3 */
        case 4:
          *pos++ = 0x0B << 1;
          break;                /* <= 4 */
        case 5:
          *pos++ = 0x0C << 1;
          break;                /* <= 5 */
        case 6:
        default:
          *pos++ = 0x0D << 1;
          break;                /* <= 6 */
      }

      *pos++ = 0x00;

      break;
    }
    case PSMUX_ST_PS_AUDIO_DTS:
      /* FIXME */
      break;
    case PSMUX_ST_PS_AUDIO_LPCM:
      /* FIXME */
      break;
    default:
      break;
  }

  if (len)
    *len = (pos - buf);
}

/**
 * psmux_stream_get_pts:
 * @stream: a #PsMuxStream
 *
 * Return the PTS of the last buffer that has had bytes written and
 * which _had_ a PTS in @stream.
 *
 * Returns: the PTS of the last buffer in @stream.
 */
guint64
psmux_stream_get_pts (PsMuxStream * stream)
{
  g_return_val_if_fail (stream != NULL, -1);

  return stream->last_pts;
}
