1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 // This file defines the V4L2Device interface which is used by the 6 // V4L2DecodeAccelerator class to delegate/pass the device specific 7 // handling of any of the functionalities. 8 9 #ifndef V4L2_DEVICE_H_ 10 #define V4L2_DEVICE_H_ 11 12 #include <map> 13 #include <stddef.h> 14 #include <stdint.h> 15 16 #include "base/files/scoped_file.h" 17 #include "base/memory/ref_counted.h" 18 #include "size.h" 19 #include "video_codecs.h" 20 #include "video_decode_accelerator.h" 21 #include "video_pixel_format.h" 22 #include "videodev2.h" 23 24 // TODO(posciak): remove this once V4L2 headers are updated. 25 #define V4L2_PIX_FMT_MT21 v4l2_fourcc('M', 'T', '2', '1') 26 #ifndef V4L2_BUF_FLAG_LAST 27 #define V4L2_BUF_FLAG_LAST 0x00100000 28 #endif 29 30 namespace media { 31 32 // Implemented for decoder usage only. 33 class V4L2Device : public base::RefCountedThreadSafe<V4L2Device> { 34 public: 35 V4L2Device(); 36 ~V4L2Device(); 37 38 // Utility format conversion functions 39 static VideoPixelFormat V4L2PixFmtToVideoPixelFormat(uint32_t format); 40 static uint32_t VideoPixelFormatToV4L2PixFmt(VideoPixelFormat format); 41 static uint32_t VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile, 42 bool slice_based); 43 std::vector<VideoCodecProfile> V4L2PixFmtToVideoCodecProfiles( 44 uint32_t pix_fmt, 45 bool is_encoder); 46 47 enum class Type { 48 kDecoder, 49 kEncoder, 50 kImageProcessor, 51 kJpegDecoder, 52 }; 53 54 // Open a V4L2 device of |type| for use with |v4l2_pixfmt|. 55 // Return true on success. 56 // The device will be closed in the destructor. 57 bool Open(Type type, uint32_t v4l2_pixfmt); 58 59 // Parameters and return value are the same as for the standard ioctl() system 60 // call. 61 int Ioctl(int request, void* arg); 62 63 // This method sleeps until either: 64 // - SetDevicePollInterrupt() is called (on another thread), 65 // - |poll_device| is true, and there is new data to be read from the device, 66 // or an event from the device has arrived; in the latter case 67 // |*event_pending| will be set to true. 68 // Returns false on error, true otherwise. 69 // This method should be called from a separate thread. 70 bool Poll(bool poll_device, bool* event_pending); 71 72 // These methods are used to interrupt the thread sleeping on Poll() and force 73 // it to return regardless of device state, which is usually when the client 74 // is no longer interested in what happens with the device (on cleanup, 75 // client state change, etc.). When SetDevicePollInterrupt() is called, Poll() 76 // will return immediately, and any subsequent calls to it will also do so 77 // until ClearDevicePollInterrupt() is called. 78 bool SetDevicePollInterrupt(); 79 bool ClearDevicePollInterrupt(); 80 81 // Wrappers for standard mmap/munmap system calls. 82 void* Mmap(void* addr, 83 unsigned int len, 84 int prot, 85 int flags, 86 unsigned int offset); 87 void Munmap(void* addr, unsigned int len); 88 89 // Return a vector of dmabuf file descriptors, exported for V4L2 buffer with 90 // |index|, assuming the buffer contains |num_planes| V4L2 planes and is of 91 // |type|. Return an empty vector on failure. 92 // The caller is responsible for closing the file descriptors after use. 93 std::vector<base::ScopedFD> GetDmabufsForV4L2Buffer( 94 int index, 95 size_t num_planes, 96 enum v4l2_buf_type type); 97 98 // NOTE: The below methods to query capabilities have a side effect of 99 // closing the previously-open device, if any, and should not be called after 100 // Open(). 101 // TODO(posciak): fix this. 102 103 // Get minimum and maximum resolution for fourcc |pixelformat| and store to 104 // |min_resolution| and |max_resolution|. 105 void GetSupportedResolution(uint32_t pixelformat, 106 Size* min_resolution, 107 Size* max_resolution); 108 109 // Return supported profiles for decoder, including only profiles for given 110 // fourcc |pixelformats|. 111 VideoDecodeAccelerator::SupportedProfiles GetSupportedDecodeProfiles( 112 const size_t num_formats, 113 const uint32_t pixelformats[]); 114 115 private: 116 friend class base::RefCountedThreadSafe<V4L2Device>; 117 118 // Vector of video device node paths and corresponding pixelformats supported 119 // by each device node. 120 using Devices = std::vector<std::pair<std::string, std::vector<uint32_t>>>; 121 122 VideoDecodeAccelerator::SupportedProfiles EnumerateSupportedDecodeProfiles( 123 const size_t num_formats, 124 const uint32_t pixelformats[]); 125 126 std::vector<uint32_t> EnumerateSupportedPixelformats(v4l2_buf_type buf_type); 127 128 // Open device node for |path| as a device of |type|. 129 bool OpenDevicePath(const std::string& path, Type type); 130 131 // Close the currently open device. 132 void CloseDevice(); 133 134 // Enumerate all V4L2 devices on the system for |type| and store the results 135 // under devices_by_type_[type]. 136 void EnumerateDevicesForType(Type type); 137 138 // Return device information for all devices of |type| available in the 139 // system. Enumerates and queries devices on first run and caches the results 140 // for subsequent calls. 141 const Devices& GetDevicesForType(Type type); 142 143 // Return device node path for device of |type| supporting |pixfmt|, or 144 // an empty string if the given combination is not supported by the system. 145 std::string GetDevicePathFor(Type type, uint32_t pixfmt); 146 147 // Stores information for all devices available on the system 148 // for each device Type. 149 std::map<Type, Devices> devices_by_type_; 150 151 // The actual device fd. 152 base::ScopedFD device_fd_; 153 154 // eventfd fd to signal device poll thread when its poll() should be 155 // interrupted. 156 base::ScopedFD device_poll_interrupt_fd_; 157 158 DISALLOW_COPY_AND_ASSIGN(V4L2Device); 159 }; 160 161 } // namespace media 162 163 #endif // V4L2_DEVICE_H_ 164