/* GStreamer
 * Copyright (C) 2008 Pioneers of the Inevitable <songbird@songbirdnest.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.
 */

#include "dshowvideofakesrc.h"

GST_DEBUG_CATEGORY_EXTERN (dshowvideosink_debug);
#define GST_CAT_DEFAULT dshowvideosink_debug

// {A0A5CF33-BD0C-4158-9A56-3011DEE3AF6B}
const GUID CLSID_VideoFakeSrc = 
{ 0xa0a5cf33, 0xbd0c, 0x4158, { 0x9a, 0x56, 0x30, 0x11, 0xde, 0xe3, 0xaf, 0x6b } };

/* output pin*/
VideoFakeSrcPin::VideoFakeSrcPin (CBaseFilter *pFilter, CCritSec *sec, HRESULT *hres):
  CDynamicOutputPin("VideoFakeSrcPin", pFilter, sec, hres, L"output")
{
}

VideoFakeSrcPin::~VideoFakeSrcPin()
{
}

HRESULT VideoFakeSrcPin::GetMediaType(int iPosition, CMediaType *pMediaType)
{
  GST_DEBUG ("GetMediaType(%d) called", iPosition);
  if(iPosition == 0) {
    *pMediaType = m_MediaType;
    return S_OK;
  }
  
  return VFW_S_NO_MORE_ITEMS;
}

/* This seems to be called to notify us of the actual media type being used,
 * even though SetMediaType isn't called. How bizarre! */
HRESULT VideoFakeSrcPin::CheckMediaType(const CMediaType *pmt)
{
    GST_DEBUG ("CheckMediaType called: %p", pmt);

    /* The video renderer will request a different stride, which we must accept.
     * So, we accept arbitrary strides (and do memcpy() to convert if needed),
     * and require the rest of the media type to match
     */
    if (IsEqualGUID(pmt->majortype,m_MediaType.majortype) &&
        IsEqualGUID(pmt->subtype,m_MediaType.subtype) &&
        IsEqualGUID(pmt->formattype,m_MediaType.formattype) &&
        pmt->cbFormat >= m_MediaType.cbFormat)
    {
      if (IsEqualGUID(pmt->formattype, FORMAT_VideoInfo)) {
        VIDEOINFOHEADER *newvh = (VIDEOINFOHEADER *)pmt->pbFormat;
        VIDEOINFOHEADER *curvh = (VIDEOINFOHEADER *)m_MediaType.pbFormat;

        if ((memcmp ((void *)&newvh->rcSource, (void *)&curvh->rcSource, sizeof (RECT)) == 0) &&
            (memcmp ((void *)&newvh->rcTarget, (void *)&curvh->rcTarget, sizeof (RECT)) == 0) &&
            (newvh->bmiHeader.biCompression == curvh->bmiHeader.biCompression) &&
            (newvh->bmiHeader.biHeight == curvh->bmiHeader.biHeight) &&
            (newvh->bmiHeader.biWidth >= curvh->bmiHeader.biWidth))
        {
          GST_DEBUG ("CheckMediaType has same media type, width %d (%d image)", newvh->bmiHeader.biWidth, curvh->bmiHeader.biWidth);
        
          /* OK, compatible! */
          return S_OK;
        }
        else {
          GST_WARNING ("Looked similar, but aren't...");
        }
      }
      
    }
    GST_WARNING ("Different media types, FAILING!");
    return S_FALSE;
}

HRESULT VideoFakeSrcPin::DecideBufferSize (IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
{
  ALLOCATOR_PROPERTIES properties;
  GST_DEBUG ("Required allocator properties: %d, %d, %d, %d", 
        ppropInputRequest->cbAlign, ppropInputRequest->cbBuffer, 
        ppropInputRequest->cbPrefix, ppropInputRequest->cBuffers);

  ppropInputRequest->cbBuffer = m_SampleSize;
  ppropInputRequest->cBuffers = 1;

  /* First set the buffer descriptions we're interested in */
  HRESULT hres = pAlloc->SetProperties(ppropInputRequest, &properties);
  GST_DEBUG ("Actual Allocator properties: %d, %d, %d, %d", 
        properties.cbAlign, properties.cbBuffer, 
        properties.cbPrefix, properties.cBuffers);

  return S_OK;
}

STDMETHODIMP
VideoFakeSrcPin::Notify(IBaseFilter * pSender, Quality q)
{
  /* Implementing this usefully is not required, but the base class
   * has an assertion here... */
  /* TODO: Map this to GStreamer QOS events? */
  return E_NOTIMPL;
}

STDMETHODIMP VideoFakeSrcPin::SetMediaType (AM_MEDIA_TYPE *pmt)
{
  m_MediaType.Set (*pmt);
  m_SampleSize = m_MediaType.GetSampleSize();

  GST_DEBUG ("SetMediaType called. SampleSize is %d", m_SampleSize);

  return S_OK;
}

/* If the destination buffer is a different shape (strides, etc.) from the source
 * buffer, we have to copy. Do that here, for supported video formats.
 *
 * TODO: When possible (when these things DON'T differ), we should buffer-alloc the
 * final output buffer, and not do this copy */
STDMETHODIMP VideoFakeSrcPin::CopyToDestinationBuffer (byte *srcbuf, byte *dstbuf)
{
  VIDEOINFOHEADER *vh = (VIDEOINFOHEADER *)m_MediaType.pbFormat;
  GST_DEBUG ("Rendering a frame");

  byte *src, *dst;
  int dststride, srcstride, rows;
  guint32 fourcc = vh->bmiHeader.biCompression;

  /* biHeight is always negative; we don't want that. */
  int height = ABS (vh->bmiHeader.biHeight);
  int width = vh->bmiHeader.biWidth;

  /* YUY2 is the preferred layout for DirectShow, so we will probably get this
   * most of the time */
  if ((fourcc == GST_MAKE_FOURCC ('Y', 'U', 'Y', '2')) ||
      (fourcc == GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V')) ||
      (fourcc == GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'))) 
  {
    /* Nice and simple */
    int srcstride = GST_ROUND_UP_4 (vh->rcSource.right * 2);
    int dststride = width * 2;

    for (int i = 0; i < height; i++) {
      memcpy (dstbuf + dststride * i, srcbuf + srcstride * i, srcstride);
    }
  }
  else if (fourcc == GST_MAKE_FOURCC ('Y', 'V', '1', '2')) {
    for (int component = 0; component < 3; component++) {
      // TODO: Get format properly rather than hard-coding it. Use gst_video_* APIs *?
      if (component == 0) {
        srcstride = GST_ROUND_UP_4 (vh->rcSource.right);
        src = srcbuf;
      }
      else {
        srcstride = GST_ROUND_UP_4 ( GST_ROUND_UP_2 (vh->rcSource.right) / 2);
        if (component == 1)
          src = srcbuf + GST_ROUND_UP_4 (vh->rcSource.right) * GST_ROUND_UP_2 (vh->rcSource.bottom);
        else
          src = srcbuf + GST_ROUND_UP_4 (vh->rcSource.right) * GST_ROUND_UP_2 (vh->rcSource.bottom) +
                  srcstride * (GST_ROUND_UP_2 (vh->rcSource.bottom) / 2);
      }

      /* Is there a better way to do this? This is ICK! */
      if (component == 0) {
        dststride = width;
        dst = dstbuf;
        rows = height;
      } else if (component == 1) {
        dststride = width / 2;
        dst = dstbuf + width * height;
        rows = height/2;
      }
      else {
        dststride = width / 2;
        dst = dstbuf + width * height +
                       width/2 * height/2;
        rows = height/2;
      }

      for (int i = 0; i < rows; i++) {
        memcpy (dst + i * dststride, src + i * srcstride, srcstride);
      }
    }
  }

  return S_OK;
}

STDMETHODIMP VideoFakeSrcPin::Disconnect ()
{
  GST_DEBUG_OBJECT (this, "Disconnecting pin");
  HRESULT hr = CDynamicOutputPin::Disconnect();
  GST_DEBUG_OBJECT (this, "Pin disconnected");
  return hr;
}

HRESULT VideoFakeSrcPin::Inactive ()
{
  GST_DEBUG_OBJECT (this, "Pin going inactive");
  HRESULT hr = CDynamicOutputPin::Inactive();
  GST_DEBUG_OBJECT (this, "Pin inactivated");
  return hr;
}

HRESULT VideoFakeSrcPin::BreakConnect ()
{
  GST_DEBUG_OBJECT (this, "Breaking connection");
  HRESULT hr = CDynamicOutputPin::BreakConnect();
  GST_DEBUG_OBJECT (this, "Connection broken");
  return hr;
}

HRESULT VideoFakeSrcPin::CompleteConnect (IPin *pReceivePin)
{
  GST_DEBUG_OBJECT (this, "Completing connection");
  HRESULT hr = CDynamicOutputPin::CompleteConnect(pReceivePin);
  GST_DEBUG_OBJECT (this, "Completed connection: %x", hr);
  return hr;
}

STDMETHODIMP VideoFakeSrcPin::Block(DWORD dwBlockFlags, HANDLE hEvent)
{
  GST_DEBUG_OBJECT (this, "Calling Block()");
  HRESULT hr = CDynamicOutputPin::Block (dwBlockFlags, hEvent);
  GST_DEBUG_OBJECT (this, "Called Block()");
  return hr;
}

/* When moving the video to a different monitor, directshow stops and restarts the playback pipeline.
 * Unfortunately, it doesn't properly block pins or do anything special, so we racily just fail
 * at this point.
 * So, we try multiple times in a loop, hoping that it'll have finished (we get no notifications at all!)
 * at some point.
 */
#define MAX_ATTEMPTS 10

GstFlowReturn VideoFakeSrcPin::PushBuffer(GstBuffer *buffer)
{
  IMediaSample *pSample = NULL;
  byte *data;
  GstMapInfo map;
  int attempts = 0;
  HRESULT hres;
  BYTE *sample_buffer;
  AM_MEDIA_TYPE *mediatype;

  /* FIXME: check return value. */
  gst_buffer_map (buffer, &map, GST_MAP_READ);
  data = map.data;
  StartUsingOutputPin();

  while (attempts < MAX_ATTEMPTS)
  {
    hres = GetDeliveryBuffer(&pSample, NULL, NULL, 0);
    if (SUCCEEDED (hres))
      break;
    attempts++;
    Sleep(100);
  }

  if (FAILED (hres)) 
  {
    StopUsingOutputPin();
    GST_WARNING ("Could not get sample for delivery to sink: %x", hres);
    return GST_FLOW_ERROR;
  }

  pSample->GetPointer(&sample_buffer);
  pSample->GetMediaType(&mediatype);
  if (mediatype)
    SetMediaType (mediatype);

  if(sample_buffer)
  {
    /* Copy to the destination stride. 
     * This is not just a simple memcpy because of the different strides. 
     * TODO: optimise for the same-stride case and avoid the copy entirely. 
     */
    CopyToDestinationBuffer (data, sample_buffer);
  }
  gst_buffer_unmap (buffer, &map);

  pSample->SetDiscontinuity(FALSE); /* Decoded frame; unimportant */
  pSample->SetSyncPoint(TRUE); /* Decoded frame; always a valid syncpoint */
  pSample->SetPreroll(FALSE); /* For non-displayed frames. 
                                 Not used in GStreamer */

  /* Disable synchronising on this sample. We instead let GStreamer handle 
   * this at a higher level, inside BaseSink. */
  pSample->SetTime(NULL, NULL);

  while (attempts < MAX_ATTEMPTS)
  {
    hres = Deliver(pSample);
    if (SUCCEEDED (hres))
      break;
    attempts++;
    Sleep(100);
  }

  pSample->Release();

  StopUsingOutputPin();

  if (SUCCEEDED (hres))
    return GST_FLOW_OK;
  else {
    GST_WARNING_OBJECT (this, "Failed to deliver sample: %x", hres);
    if (hres == VFW_E_NOT_CONNECTED)
      return GST_FLOW_NOT_LINKED;
    else
      return GST_FLOW_ERROR;
  }
}

STDMETHODIMP VideoFakeSrcPin::Flush ()
{
  DeliverBeginFlush();
  DeliverEndFlush();
  return S_OK;
}

VideoFakeSrc::VideoFakeSrc() : CBaseFilter("VideoFakeSrc", NULL, &m_critsec, CLSID_VideoFakeSrc),
	m_evFilterStoppingEvent(TRUE)
{
  HRESULT hr = S_OK;
  m_pOutputPin = new VideoFakeSrcPin ((CSource *)this, &m_critsec, &hr);
}

int VideoFakeSrc::GetPinCount()
{
  return 1;
}

CBasePin *VideoFakeSrc::GetPin(int n)
{
  return (CBasePin *)m_pOutputPin;
}

VideoFakeSrcPin *VideoFakeSrc::GetOutputPin()
{
  return m_pOutputPin;
}

STDMETHODIMP VideoFakeSrc::Stop(void)
{
  GST_DEBUG_OBJECT (this, "Stop()");
  m_evFilterStoppingEvent.Set();

  return CBaseFilter::Stop();
}

STDMETHODIMP VideoFakeSrc::Pause(void)
{
  GST_DEBUG_OBJECT (this, "Pause()");

  m_evFilterStoppingEvent.Reset();

  return CBaseFilter::Pause();
}

STDMETHODIMP VideoFakeSrc::Run(REFERENCE_TIME tStart)
{
  GST_DEBUG_OBJECT (this, "Run()");

  return CBaseFilter::Run(tStart);
}

STDMETHODIMP VideoFakeSrc::JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR pName)
{
  HRESULT hr;

  // The filter is joining the filter graph.
  if(NULL != pGraph)
  {
    IGraphConfig* pGraphConfig = NULL;
    hr = pGraph->QueryInterface(IID_IGraphConfig, (void**)&pGraphConfig);
    if(FAILED(hr))
      return hr;

    hr = CBaseFilter::JoinFilterGraph(pGraph, pName);
    if(FAILED(hr))
    {
      pGraphConfig->Release();
      return hr;
    }

    m_pOutputPin->SetConfigInfo(pGraphConfig, m_evFilterStoppingEvent);
    pGraphConfig->Release();
  }
  else
  {
    hr = CBaseFilter::JoinFilterGraph(pGraph, pName);
    if(FAILED(hr))
      return hr;

    m_pOutputPin->SetConfigInfo(NULL, NULL);
  }

  return S_OK;
}

