1 /* Copyright 2017 The Chromium OS 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 
6 #ifndef HAL_USB_CACHED_FRAME_H_
7 #define HAL_USB_CACHED_FRAME_H_
8 
9 #include <memory>
10 
11 #include <camera/CameraMetadata.h>
12 
13 #include "arc/image_processor.h"
14 
15 namespace arc {
16 
17 // CachedFrame contains a source FrameBuffer and a cached, converted
18 // FrameBuffer. The incoming frames would be converted to YU12, the default
19 // format of libyuv, to allow convenient processing.
20 class CachedFrame {
21  public:
22   CachedFrame();
23   ~CachedFrame();
24 
25   // SetSource() doesn't take ownership of |frame|. The caller can only release
26   // |frame| after calling UnsetSource(). SetSource() immediately converts
27   // incoming frame into YU12. Return non-zero values if it encounters errors.
28   // If |rotate_degree| is 90 or 270, |frame| will be cropped, rotated by the
29   // specified amount and scaled.
30   // If |rotate_degree| is -1, |frame| will not be cropped, rotated, and scaled.
31   // This function will return an error if |rotate_degree| is not -1, 90, or
32   // 270.
33   int SetSource(const FrameBuffer* frame, int rotate_degree);
34   void UnsetSource();
35 
36   uint8_t* GetSourceBuffer() const;
37   size_t GetSourceDataSize() const;
38   uint32_t GetSourceFourCC() const;
39   uint8_t* GetCachedBuffer() const;
40   uint32_t GetCachedFourCC() const;
41 
42   uint32_t GetWidth() const;
43   uint32_t GetHeight() const;
44 
45   // Calculate the output buffer size when converting to the specified pixel
46   // format. |fourcc| is defined as V4L2_PIX_FMT_* in linux/videodev2.h. Return
47   // 0 on error.
48   size_t GetConvertedSize(int fourcc) const;
49 
50   // Caller should fill everything except |data_size| and |fd| of |out_frame|.
51   // The function will do format conversion and scale to fit |out_frame|
52   // requirement.
53   // If |video_hack| is true, it outputs YU12 when |hal_pixel_format| is YV12
54   // (swapping U/V planes). Caller should fill |fourcc|, |data|, and
55   // Return non-zero error code on failure; return 0 on success.
56   int Convert(const android::CameraMetadata& metadata, FrameBuffer* out_frame,
57               bool video_hack = false);
58 
59  private:
60   int ConvertToYU12();
61   // When we have a landscape mounted camera and the current camera activity is
62   // portrait, the frames shown in the activity would be stretched. Therefore,
63   // we want to simulate a native portrait camera. That's why we want to crop,
64   // rotate |rotate_degree| clockwise and scale the frame. HAL would not change
65   // CameraInfo.orientation. Instead, framework would fake the
66   // CameraInfo.orientation. Framework would then tell HAL how much the frame
67   // needs to rotate clockwise by |rotate_degree|.
68   int CropRotateScale(int rotate_degree);
69 
70   const FrameBuffer* source_frame_;
71   // const V4L2FrameBuffer* source_frame_;
72 
73   // Temporary buffer for cropped and rotated results.
74   std::unique_ptr<uint8_t[]> cropped_buffer_;
75   size_t cropped_buffer_capacity_;
76 
77   // Cache YU12 decoded results.
78   std::unique_ptr<AllocatedFrameBuffer> yu12_frame_;
79 
80   // Temporary buffer for scaled results.
81   std::unique_ptr<AllocatedFrameBuffer> scaled_frame_;
82 };
83 
84 }  // namespace arc
85 
86 #endif  // HAL_USB_CACHED_FRAME_H_
87