protected void ReportGetSampleCompleted (MediaStreamSample mediaStreamSample)
{
IntPtr frame;
IntPtr buffer;
uint buflen;
byte [] buf;
// FIXME: wrong/overzealous validations wrt SL2 (see unit tests)
if (closed || media_element == null || demuxer == IntPtr.Zero)
throw new InvalidOperationException ();
// A null value / stream means the end has been reached.
if ((mediaStreamSample == null) || (mediaStreamSample.Stream == null)) {
NativeMethods.imedia_demuxer_report_get_frame_completed (demuxer, IntPtr.Zero);
return;
}
if (mediaStreamSample.MediaStreamDescription.NativeStream == IntPtr.Zero)
throw new InvalidOperationException ();
// TODO:
// Fix this to not copy the data twice and have 3 managed/unmanaged switches.
// The best would probably be to have the pipeline/mediaframe accept an IMediaStream as the
// buffer, this however requires changes in every demuxer/codecs we have.
buflen = (uint) mediaStreamSample.Count;
buf = new byte [buflen];
mediaStreamSample.Stream.Seek (mediaStreamSample.Offset, System.IO.SeekOrigin.Begin);
mediaStreamSample.Stream.Read (buf, 0, (int) buflen);
buffer = Marshal.AllocHGlobal ((int) buflen);
Marshal.Copy (buf, 0, buffer, (int) buflen);
// we pass a hardocded true as keyframe flag here. User code can lie and
// don't set the keyframe flag on any frame at all. Our pipeline doesn't work well
// for this case (seeking in particular, we seek to keyframes, and when
// there are no keyframes...). Since we can't rely on the keyframe
// flag being set at all, just lie the best way for our pipeline.
frame = NativeMethods.media_frame_new (mediaStreamSample.MediaStreamDescription.NativeStream, buffer, buflen, (ulong) mediaStreamSample.Timestamp, true);
NativeMethods.imedia_demuxer_report_get_frame_completed (demuxer, frame);
NativeMethods.event_object_unref (frame);
}