/*
 * OggDecoder
 *
 * Copyright (C) 2008 Joern Seger
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <iostream>
#include <string.h>
#include <stdlib.h>

#include "oggDecoder.h"
#include "oggHeader.h"
#include "log.h"

#define min(a,b) (((a)<(b))?(a):(b));

OggDecoder::OggDecoder()
    : oggRingbuffer(71000) // max page size plus 4KB read size
{
  setConfigured();
}

OggDecoder::~OggDecoder()
{
}

void OggDecoder::clear()
{
  /* nothing to be done here */
}

void OggDecoder::getNextPages()
{
  uint8* data(0);
  uint32 length(0);

  while (oggRingbuffer.getNextPage(data, length)) {

    uint32 headerLength = sizeof(OggHeader) + ((OggHeader*)data)->tableSegments;
    uint32 bodyLength = length - headerLength;
    OggPage page(new OggPageInternal(data, headerLength, bodyLength));

    oggPageList.push_back(page);

    data = 0;

    setAvailable();
  }
}

OggDecoder& OggDecoder::operator<<(RawMediaPacket& mediaPacket)
{
  /* insert the raw data into the ring buffer*/
  oggRingbuffer.addData(mediaPacket.getData(), mediaPacket.size());

  /* extract ogg pages */
  getNextPages();

  return(*this);
}

OggDecoder& OggDecoder::operator>>(OggPage& page)
{

  if (isAvailable()) {
    page = oggPageList.front();
    oggPageList.pop_front();
    if (oggPageList.empty())
      setEmpty();
  } else
    logger.error() << "OggDecoder::operator>>: no page available, insert a packet first\n";

  return(*this);
}

uint32 OggDecoder::space()
{
  return(oggRingbuffer.getAvailable());
}
