Simplify buffer ioctls a bit

Define a type for the plane array used in the multi-planar API, and
merge the single and multi-planar functions back together.
diff --git a/src/ioctl/qbuf.rs b/src/ioctl/qbuf.rs
index a892e75..ede53b9 100644
--- a/src/ioctl/qbuf.rs
+++ b/src/ioctl/qbuf.rs
@@ -6,6 +6,17 @@
 use std::mem;
 use std::os::unix::io::AsRawFd;
 
+/// A memory area we can pass to ioctls in order to get/set plane information
+/// with the multi-planar API.
+type PlaneData = [bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize];
+
+/// For simple initialization of `PlaneData`.
+impl Default for bindings::v4l2_plane {
+    fn default() -> Self {
+        unsafe { mem::zeroed() }
+    }
+}
+
 bitflags! {
     /// Flags corresponding to the `flags` field of `struct v4l2_buffer`.
     /// TODO split into two types, one for the user -> kernel and another for
@@ -32,7 +43,7 @@
     fn fill_mplane_v4l2_buffer(
         self,
         v4l2_buf: &mut bindings::v4l2_buffer,
-        v4l2_planes: &mut [bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize],
+        v4l2_planes: &mut PlaneData,
     ) -> Result<()>;
 }
 
@@ -76,7 +87,7 @@
     fn fill_mplane_v4l2_buffer(
         self,
         v4l2_buf: &mut bindings::v4l2_buffer,
-        v4l2_planes: &mut [bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize],
+        v4l2_planes: &mut PlaneData,
     ) -> Result<()> {
         if self.planes.len() == 0 {
             return Err(Error::NotEnoughPlanes);
@@ -108,7 +119,7 @@
     /// retrieve the plane data.
     fn from_v4l2_buffer(
         v4l2_buf: &bindings::v4l2_buffer,
-        v4l2_planes: Option<&[bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize]>,
+        v4l2_planes: Option<&PlaneData>,
     ) -> Result<Self>;
 }
 
@@ -116,7 +127,7 @@
 impl DQBuf for () {
     fn from_v4l2_buffer(
         _v4l2_buf: &bindings::v4l2_buffer,
-        _v4l2_planes: Option<&[bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize]>,
+        _v4l2_planes: Option<&PlaneData>,
     ) -> Result<Self> {
         Ok(())
     }
@@ -127,7 +138,7 @@
 impl DQBuf for u32 {
     fn from_v4l2_buffer(
         v4l2_buf: &bindings::v4l2_buffer,
-        _v4l2_planes: Option<&[bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize]>,
+        _v4l2_planes: Option<&PlaneData>,
     ) -> Result<Self> {
         Ok(v4l2_buf.index)
     }
@@ -148,7 +159,7 @@
 impl<H: PlaneHandle> DQBuf for QueryBuffer<H> {
     fn from_v4l2_buffer(
         v4l2_buf: &bindings::v4l2_buffer,
-        v4l2_planes: Option<&[bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize]>,
+        v4l2_planes: Option<&PlaneData>,
     ) -> Result<Self> {
         let planes = match v4l2_planes {
             None => vec![QueryBufPlane {
@@ -195,16 +206,10 @@
     pub planes: Vec<DQBufPlane<H>>,
 }
 
-impl Default for bindings::v4l2_plane {
-    fn default() -> Self {
-        unsafe { mem::zeroed() }
-    }
-}
-
 impl<H: PlaneHandle> DQBuf for DQBuffer<H> {
     fn from_v4l2_buffer(
         v4l2_buf: &bindings::v4l2_buffer,
-        v4l2_planes: Option<&[bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize]>,
+        v4l2_planes: Option<&PlaneData>,
     ) -> Result<Self> {
         let planes = match v4l2_planes {
             None => vec![DQBufPlane {
@@ -254,21 +259,6 @@
     }
 }
 
-fn qbuf_mp<T: QBuf, F: AsRawFd>(
-    fd: &F,
-    v4l2_buf: &mut bindings::v4l2_buffer,
-    buf_data: T,
-) -> Result<()> {
-    let mut plane_data: [bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize] =
-        Default::default();
-    v4l2_buf.m.planes = plane_data.as_mut_ptr();
-    buf_data.fill_mplane_v4l2_buffer(v4l2_buf, &mut plane_data)?;
-
-    unsafe { ioctl::vidioc_qbuf(fd.as_raw_fd(), v4l2_buf) }?;
-
-    Ok(())
-}
-
 /// Safe wrapper around the `VIDIOC_QBUF` ioctl.
 pub fn qbuf<T: QBuf, F: AsRawFd>(
     fd: &F,
@@ -283,23 +273,17 @@
     };
 
     if is_multi_planar(queue) {
-        return qbuf_mp(fd, &mut v4l2_buf, buf_data);
+        let mut plane_data: PlaneData = Default::default();
+        v4l2_buf.m.planes = plane_data.as_mut_ptr();
+
+        buf_data.fill_mplane_v4l2_buffer(&mut v4l2_buf, &mut plane_data)?;
+        unsafe { ioctl::vidioc_qbuf(fd.as_raw_fd(), &mut v4l2_buf) }?;
+        Ok(())
+    } else {
+        buf_data.fill_splane_v4l2_buffer(&mut v4l2_buf)?;
+        unsafe { ioctl::vidioc_qbuf(fd.as_raw_fd(), &mut v4l2_buf) }?;
+        Ok(())
     }
-
-    buf_data.fill_splane_v4l2_buffer(&mut v4l2_buf)?;
-    unsafe { ioctl::vidioc_qbuf(fd.as_raw_fd(), &mut v4l2_buf) }?;
-    Ok(())
-}
-
-fn dqbuf_mp<T: DQBuf, F: AsRawFd>(fd: &F, v4l2_buf: &mut bindings::v4l2_buffer) -> Result<T> {
-    let mut plane_data: [bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize] =
-        Default::default();
-    v4l2_buf.m.planes = plane_data.as_mut_ptr();
-    v4l2_buf.length = plane_data.len() as u32;
-
-    unsafe { ioctl::vidioc_dqbuf(fd.as_raw_fd(), v4l2_buf) }?;
-
-    Ok(T::from_v4l2_buffer(v4l2_buf, Some(&plane_data))?)
 }
 
 /// Safe wrapper around the `VIDIOC_DQBUF` ioctl.
@@ -308,24 +292,18 @@
         type_: queue as u32,
         ..unsafe { mem::zeroed() }
     };
+
     if is_multi_planar(queue) {
-        return dqbuf_mp(fd, &mut v4l2_buf);
+        let mut plane_data: PlaneData = Default::default();
+        v4l2_buf.m.planes = plane_data.as_mut_ptr();
+        v4l2_buf.length = plane_data.len() as u32;
+
+        unsafe { ioctl::vidioc_dqbuf(fd.as_raw_fd(), &mut v4l2_buf) }?;
+        Ok(T::from_v4l2_buffer(&v4l2_buf, Some(&plane_data))?)
+    } else {
+        unsafe { ioctl::vidioc_dqbuf(fd.as_raw_fd(), &mut v4l2_buf) }?;
+        Ok(T::from_v4l2_buffer(&v4l2_buf, None)?)
     }
-
-    unsafe { ioctl::vidioc_dqbuf(fd.as_raw_fd(), &mut v4l2_buf) }?;
-
-    Ok(T::from_v4l2_buffer(&v4l2_buf, None)?)
-}
-
-fn querybuf_mp<T: DQBuf, F: AsRawFd>(fd: &F, v4l2_buf: &mut bindings::v4l2_buffer) -> Result<T> {
-    let mut plane_data: [bindings::v4l2_plane; bindings::VIDEO_MAX_PLANES as usize] =
-        Default::default();
-    v4l2_buf.m.planes = plane_data.as_mut_ptr();
-    v4l2_buf.length = plane_data.len() as u32;
-
-    unsafe { ioctl::vidioc_querybuf(fd.as_raw_fd(), v4l2_buf) }?;
-
-    Ok(T::from_v4l2_buffer(v4l2_buf, Some(&plane_data))?)
 }
 
 /// Safe wrapper around the `VIDIOC_QUERYBUF` ioctl.
@@ -335,11 +313,16 @@
         type_: queue as u32,
         ..unsafe { mem::zeroed() }
     };
+
     if is_multi_planar(queue) {
-        return querybuf_mp(fd, &mut v4l2_buf);
+        let mut plane_data: PlaneData = Default::default();
+        v4l2_buf.m.planes = plane_data.as_mut_ptr();
+        v4l2_buf.length = plane_data.len() as u32;
+
+        unsafe { ioctl::vidioc_querybuf(fd.as_raw_fd(), &mut v4l2_buf) }?;
+        Ok(T::from_v4l2_buffer(&v4l2_buf, Some(&plane_data))?)
+    } else {
+        unsafe { ioctl::vidioc_querybuf(fd.as_raw_fd(), &mut v4l2_buf) }?;
+        Ok(T::from_v4l2_buffer(&v4l2_buf, None)?)
     }
-
-    unsafe { ioctl::vidioc_querybuf(fd.as_raw_fd(), &mut v4l2_buf) }?;
-
-    Ok(T::from_v4l2_buffer(&v4l2_buf, None)?)
 }