blob: 3a960d90db5e20dbdf826725bebbe52a2b5355ca [file] [log] [blame]
Johny Lin48690172017-08-04 11:11:50 +08001// Copyright 2017 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//#define LOG_NDEBUG 0
6#define LOG_TAG "C2VDAAdaptor"
7
Johny Linc6d0b6f2017-12-19 15:47:06 +08008#include <C2VDAAdaptor.h>
9
10#include <bitstream_buffer.h>
11#include <native_pixmap_handle.h>
12#include <v4l2_device.h>
13#include <v4l2_slice_video_decode_accelerator.h>
Johny Lin4059fa22018-02-06 16:00:23 +080014#include <video_pixel_format.h>
Johny Linc6d0b6f2017-12-19 15:47:06 +080015#include <videodev2.h>
Johny Lin48690172017-08-04 11:11:50 +080016
Johny Lin48690172017-08-04 11:11:50 +080017#include <utils/Log.h>
18
19namespace android {
20
Johny Linac6e2702018-01-17 12:11:52 +080021constexpr SupportedPixelFormat kSupportedPixelFormats[] = {
22 // {mCrcb, mSemiplanar, mPixelFormat}
23 {false, true, HalPixelFormat::NV12},
24 {true, false, HalPixelFormat::YV12},
25 // Add more buffer formats when needed
26};
27
Johny Lina891f0e2017-12-19 10:25:27 +080028C2VDAAdaptor::C2VDAAdaptor() : mNumOutputBuffers(0u) {}
Johny Lin48690172017-08-04 11:11:50 +080029
30C2VDAAdaptor::~C2VDAAdaptor() {
31 if (mVDA) {
32 destroy();
33 }
34}
35
36VideoDecodeAcceleratorAdaptor::Result C2VDAAdaptor::initialize(
Johny Lina891f0e2017-12-19 10:25:27 +080037 media::VideoCodecProfile profile, bool secureMode,
38 VideoDecodeAcceleratorAdaptor::Client* client) {
Hirokazu Hondace275062017-10-30 11:34:57 +090039 // TODO: use secureMode here, or ignore?
Johny Lin48690172017-08-04 11:11:50 +080040 if (mVDA) {
41 ALOGE("Re-initialize() is not allowed");
42 return ILLEGAL_STATE;
43 }
44
45 media::VideoDecodeAccelerator::Config config;
46 config.profile = profile;
47 config.output_mode = media::VideoDecodeAccelerator::Config::OutputMode::IMPORT;
48
49 // TODO(johnylin): may need to implement factory to create VDA if there are multiple VDA
50 // implementations in the future.
51 scoped_refptr<media::V4L2Device> device = new media::V4L2Device();
52 std::unique_ptr<media::VideoDecodeAccelerator> vda(
53 new media::V4L2SliceVideoDecodeAccelerator(device));
54 if (!vda->Initialize(config, this)) {
55 ALOGE("Failed to initialize VDA");
56 return PLATFORM_FAILURE;
57 }
58
59 mVDA = std::move(vda);
60 mClient = client;
61
62 return SUCCESS;
63}
64
65void C2VDAAdaptor::decode(int32_t bitstreamId, int ashmemFd, off_t offset, uint32_t bytesUsed) {
66 CHECK(mVDA);
Johny Lina891f0e2017-12-19 10:25:27 +080067 mVDA->Decode(media::BitstreamBuffer(bitstreamId, base::SharedMemoryHandle(ashmemFd, true),
68 bytesUsed, offset));
Johny Lin48690172017-08-04 11:11:50 +080069}
70
71void C2VDAAdaptor::assignPictureBuffers(uint32_t numOutputBuffers) {
72 CHECK(mVDA);
73 std::vector<media::PictureBuffer> buffers;
74 for (uint32_t id = 0; id < numOutputBuffers; ++id) {
Johny Lina891f0e2017-12-19 10:25:27 +080075 buffers.push_back(media::PictureBuffer(static_cast<int32_t>(id), mPictureSize));
Johny Lin48690172017-08-04 11:11:50 +080076 }
77 mVDA->AssignPictureBuffers(buffers);
78 mNumOutputBuffers = numOutputBuffers;
79}
80
Johny Linac6e2702018-01-17 12:11:52 +080081void C2VDAAdaptor::importBufferForPicture(int32_t pictureBufferId, HalPixelFormat format,
82 int dmabufFd,
Johny Lin48690172017-08-04 11:11:50 +080083 const std::vector<VideoFramePlane>& planes) {
84 CHECK(mVDA);
85 CHECK_LT(pictureBufferId, static_cast<int32_t>(mNumOutputBuffers));
86
Johny Lin4059fa22018-02-06 16:00:23 +080087 media::VideoPixelFormat pixelFormat;
88 switch (format) {
89 case HalPixelFormat::YV12:
90 pixelFormat = media::PIXEL_FORMAT_YV12;
91 break;
92 case HalPixelFormat::NV12:
93 pixelFormat = media::PIXEL_FORMAT_NV12;
94 break;
95 default:
96 LOG_ALWAYS_FATAL("Unsupported format: 0x%x", format);
97 return;
98 }
99
Johny Lin48690172017-08-04 11:11:50 +0800100 media::NativePixmapHandle handle;
101 handle.fds.emplace_back(base::FileDescriptor(dmabufFd, true));
102 for (const auto& plane : planes) {
Johny Linac6e2702018-01-17 12:11:52 +0800103 handle.planes.emplace_back(plane.mStride, plane.mOffset, 0, 0);
Johny Lin48690172017-08-04 11:11:50 +0800104 }
Johny Lin4059fa22018-02-06 16:00:23 +0800105 mVDA->ImportBufferForPicture(pictureBufferId, pixelFormat, handle);
Johny Lin48690172017-08-04 11:11:50 +0800106}
107
108void C2VDAAdaptor::reusePictureBuffer(int32_t pictureBufferId) {
109 CHECK(mVDA);
110 CHECK_LT(pictureBufferId, static_cast<int32_t>(mNumOutputBuffers));
111
112 mVDA->ReusePictureBuffer(pictureBufferId);
113}
114
115void C2VDAAdaptor::flush() {
116 CHECK(mVDA);
117 mVDA->Flush();
118}
119
120void C2VDAAdaptor::reset() {
121 CHECK(mVDA);
122 mVDA->Reset();
123}
124
125void C2VDAAdaptor::destroy() {
126 mVDA.reset(nullptr);
127 mNumOutputBuffers = 0u;
128 mPictureSize = media::Size();
129}
130
Johny Lin7c4cb522017-06-26 16:10:24 +0800131//static
132media::VideoDecodeAccelerator::SupportedProfiles C2VDAAdaptor::GetSupportedProfiles(
133 uint32_t inputFormatFourcc) {
134 media::VideoDecodeAccelerator::SupportedProfiles supportedProfiles;
135 auto allProfiles = media::V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles();
136 bool isSliceBased = (inputFormatFourcc == V4L2_PIX_FMT_H264_SLICE) ||
137 (inputFormatFourcc == V4L2_PIX_FMT_VP8_FRAME) ||
138 (inputFormatFourcc == V4L2_PIX_FMT_VP9_FRAME);
139 for (const auto& profile : allProfiles) {
Johny Lina891f0e2017-12-19 10:25:27 +0800140 if (inputFormatFourcc ==
141 media::V4L2Device::VideoCodecProfileToV4L2PixFmt(profile.profile, isSliceBased)) {
Johny Lin7c4cb522017-06-26 16:10:24 +0800142 supportedProfiles.push_back(profile);
143 }
144 }
145 return supportedProfiles;
146}
Johny Lin48690172017-08-04 11:11:50 +0800147
Johny Linac6e2702018-01-17 12:11:52 +0800148//static
149HalPixelFormat C2VDAAdaptor::ResolveBufferFormat(bool crcb, bool semiplanar) {
150 auto value = std::find_if(std::begin(kSupportedPixelFormats), std::end(kSupportedPixelFormats),
151 [crcb, semiplanar](const struct SupportedPixelFormat& f) {
152 return f.mCrcb == crcb && f.mSemiplanar == semiplanar;
153 });
154 LOG_ALWAYS_FATAL_IF(value == std::end(kSupportedPixelFormats),
155 "Unsupported pixel format: (crcb=%d, semiplanar=%d)", crcb, semiplanar);
156 return value->mPixelFormat;
157}
158
Johny Lin48690172017-08-04 11:11:50 +0800159void C2VDAAdaptor::ProvidePictureBuffers(uint32_t requested_num_of_buffers,
160 media::VideoPixelFormat output_format,
161 const media::Size& dimensions) {
Johny Linac6e2702018-01-17 12:11:52 +0800162 // per change ag/3262504, output_format from VDA is no longer used, component side always
163 // allocate graphic buffers for flexible YUV format.
164 (void)output_format;
Johny Lin48690172017-08-04 11:11:50 +0800165
Johny Linac6e2702018-01-17 12:11:52 +0800166 mClient->providePictureBuffers(requested_num_of_buffers, dimensions);
Johny Lin48690172017-08-04 11:11:50 +0800167 mPictureSize = dimensions;
168}
169
170void C2VDAAdaptor::DismissPictureBuffer(int32_t picture_buffer_id) {
171 mClient->dismissPictureBuffer(picture_buffer_id);
172}
173
174void C2VDAAdaptor::PictureReady(const media::Picture& picture) {
Johny Lina891f0e2017-12-19 10:25:27 +0800175 mClient->pictureReady(picture.picture_buffer_id(), picture.bitstream_buffer_id(),
Johny Lin48690172017-08-04 11:11:50 +0800176 picture.visible_rect());
177}
178
179void C2VDAAdaptor::NotifyEndOfBitstreamBuffer(int32_t bitstream_buffer_id) {
180 mClient->notifyEndOfBitstreamBuffer(bitstream_buffer_id);
181}
182
183void C2VDAAdaptor::NotifyFlushDone() {
184 mClient->notifyFlushDone();
185}
186
187void C2VDAAdaptor::NotifyResetDone() {
188 mClient->notifyResetDone();
189}
190
191static VideoDecodeAcceleratorAdaptor::Result convertErrorCode(
192 media::VideoDecodeAccelerator::Error error) {
193 switch (error) {
Johny Lina891f0e2017-12-19 10:25:27 +0800194 case media::VideoDecodeAccelerator::ILLEGAL_STATE:
195 return VideoDecodeAcceleratorAdaptor::ILLEGAL_STATE;
196 case media::VideoDecodeAccelerator::INVALID_ARGUMENT:
197 return VideoDecodeAcceleratorAdaptor::INVALID_ARGUMENT;
198 case media::VideoDecodeAccelerator::UNREADABLE_INPUT:
199 return VideoDecodeAcceleratorAdaptor::UNREADABLE_INPUT;
200 case media::VideoDecodeAccelerator::PLATFORM_FAILURE:
201 return VideoDecodeAcceleratorAdaptor::PLATFORM_FAILURE;
202 default:
203 ALOGE("Unknown error code: %d", static_cast<int>(error));
204 return VideoDecodeAcceleratorAdaptor::PLATFORM_FAILURE;
Johny Lin48690172017-08-04 11:11:50 +0800205 }
206}
207
208void C2VDAAdaptor::NotifyError(media::VideoDecodeAccelerator::Error error) {
209 mClient->notifyError(convertErrorCode(error));
210}
211
212} // namespace android