/// <summary>
        /// Reads the next frame from this track. If it contains no more frames to read, null is returned.
        /// </summary>
        /// <returns>the next frame or null if there are no more frames to read</returns>
        public Frame readNextFrame()
        {
            Frame frame = null;

            if (hasMoreFrames())
            {
                frame = frames[currentFrame];

                long diff = frame.getOffset() - inStream.getOffset();
                if (diff > 0)
                {
                    inStream.skipBytes(diff);
                }
                else if (diff < 0)
                {
                    if (inStream.hasRandomAccess())
                    {
                        inStream.seek(frame.getOffset());
                    }
                    else
                    {
                        Logger.LogServe(string.Format("MP4 API: readNextFrame failed: frame {0:N0} already skipped, offset:{1:N0}, stream:{2:N0}", currentFrame, frame.getOffset(), inStream.getOffset()));
                        throw new IOException("frame already skipped and no random access");
                    }
                }

                var b = new byte[(int)frame.getSize()];
                try
                {
                    inStream.read(b, 0, b.Length);
                }
                catch (Exception)
                {
                    Logger.LogServe(string.Format("MP4 API: readNextFrame failed: tried to read {0:N0} bytes at {1:N0}", frame.getSize(), inStream.getOffset()));
                    throw;
                }
                frame.setData(b);
                currentFrame++;
            }
            return(frame);
        }