blob: de0ac81a57f143d60f76a59e5a75ea1a7242d9a5 [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
8#include "C2VDAAdaptor.h"
9#include "bitstream_buffer.h"
10#include "native_pixmap_handle.h"
Johny Lin7c4cb522017-06-26 16:10:24 +080011#include "v4l2_device.h"
Johny Lin48690172017-08-04 11:11:50 +080012#include "v4l2_slice_video_decode_accelerator.h"
Johny Lin7c4cb522017-06-26 16:10:24 +080013#include "videodev2.h"
Johny Lin48690172017-08-04 11:11:50 +080014
15#include <system/graphics.h>
16#include <utils/Log.h>
17
18namespace android {
19
Johny Lina891f0e2017-12-19 10:25:27 +080020C2VDAAdaptor::C2VDAAdaptor() : mNumOutputBuffers(0u) {}
Johny Lin48690172017-08-04 11:11:50 +080021
22C2VDAAdaptor::~C2VDAAdaptor() {
23 if (mVDA) {
24 destroy();
25 }
26}
27
28VideoDecodeAcceleratorAdaptor::Result C2VDAAdaptor::initialize(
Johny Lina891f0e2017-12-19 10:25:27 +080029 media::VideoCodecProfile profile, bool secureMode,
30 VideoDecodeAcceleratorAdaptor::Client* client) {
Hirokazu Hondace275062017-10-30 11:34:57 +090031 // TODO: use secureMode here, or ignore?
Johny Lin48690172017-08-04 11:11:50 +080032 if (mVDA) {
33 ALOGE("Re-initialize() is not allowed");
34 return ILLEGAL_STATE;
35 }
36
37 media::VideoDecodeAccelerator::Config config;
38 config.profile = profile;
39 config.output_mode = media::VideoDecodeAccelerator::Config::OutputMode::IMPORT;
40
41 // TODO(johnylin): may need to implement factory to create VDA if there are multiple VDA
42 // implementations in the future.
43 scoped_refptr<media::V4L2Device> device = new media::V4L2Device();
44 std::unique_ptr<media::VideoDecodeAccelerator> vda(
45 new media::V4L2SliceVideoDecodeAccelerator(device));
46 if (!vda->Initialize(config, this)) {
47 ALOGE("Failed to initialize VDA");
48 return PLATFORM_FAILURE;
49 }
50
51 mVDA = std::move(vda);
52 mClient = client;
53
54 return SUCCESS;
55}
56
57void C2VDAAdaptor::decode(int32_t bitstreamId, int ashmemFd, off_t offset, uint32_t bytesUsed) {
58 CHECK(mVDA);
Johny Lina891f0e2017-12-19 10:25:27 +080059 mVDA->Decode(media::BitstreamBuffer(bitstreamId, base::SharedMemoryHandle(ashmemFd, true),
60 bytesUsed, offset));
Johny Lin48690172017-08-04 11:11:50 +080061}
62
63void C2VDAAdaptor::assignPictureBuffers(uint32_t numOutputBuffers) {
64 CHECK(mVDA);
65 std::vector<media::PictureBuffer> buffers;
66 for (uint32_t id = 0; id < numOutputBuffers; ++id) {
Johny Lina891f0e2017-12-19 10:25:27 +080067 buffers.push_back(media::PictureBuffer(static_cast<int32_t>(id), mPictureSize));
Johny Lin48690172017-08-04 11:11:50 +080068 }
69 mVDA->AssignPictureBuffers(buffers);
70 mNumOutputBuffers = numOutputBuffers;
71}
72
73void C2VDAAdaptor::importBufferForPicture(int32_t pictureBufferId, int dmabufFd,
74 const std::vector<VideoFramePlane>& planes) {
75 CHECK(mVDA);
76 CHECK_LT(pictureBufferId, static_cast<int32_t>(mNumOutputBuffers));
77
78 media::NativePixmapHandle handle;
79 handle.fds.emplace_back(base::FileDescriptor(dmabufFd, true));
80 for (const auto& plane : planes) {
81 handle.planes.emplace_back(plane.stride, plane.offset, 0, 0);
82 }
83 mVDA->ImportBufferForPicture(pictureBufferId, handle);
84}
85
86void C2VDAAdaptor::reusePictureBuffer(int32_t pictureBufferId) {
87 CHECK(mVDA);
88 CHECK_LT(pictureBufferId, static_cast<int32_t>(mNumOutputBuffers));
89
90 mVDA->ReusePictureBuffer(pictureBufferId);
91}
92
93void C2VDAAdaptor::flush() {
94 CHECK(mVDA);
95 mVDA->Flush();
96}
97
98void C2VDAAdaptor::reset() {
99 CHECK(mVDA);
100 mVDA->Reset();
101}
102
103void C2VDAAdaptor::destroy() {
104 mVDA.reset(nullptr);
105 mNumOutputBuffers = 0u;
106 mPictureSize = media::Size();
107}
108
Johny Lin7c4cb522017-06-26 16:10:24 +0800109//static
110media::VideoDecodeAccelerator::SupportedProfiles C2VDAAdaptor::GetSupportedProfiles(
111 uint32_t inputFormatFourcc) {
112 media::VideoDecodeAccelerator::SupportedProfiles supportedProfiles;
113 auto allProfiles = media::V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles();
114 bool isSliceBased = (inputFormatFourcc == V4L2_PIX_FMT_H264_SLICE) ||
115 (inputFormatFourcc == V4L2_PIX_FMT_VP8_FRAME) ||
116 (inputFormatFourcc == V4L2_PIX_FMT_VP9_FRAME);
117 for (const auto& profile : allProfiles) {
Johny Lina891f0e2017-12-19 10:25:27 +0800118 if (inputFormatFourcc ==
119 media::V4L2Device::VideoCodecProfileToV4L2PixFmt(profile.profile, isSliceBased)) {
Johny Lin7c4cb522017-06-26 16:10:24 +0800120 supportedProfiles.push_back(profile);
121 }
122 }
123 return supportedProfiles;
124}
Johny Lin48690172017-08-04 11:11:50 +0800125
126void C2VDAAdaptor::ProvidePictureBuffers(uint32_t requested_num_of_buffers,
127 media::VideoPixelFormat output_format,
128 const media::Size& dimensions) {
129 uint32_t pixelFormat;
130 switch (output_format) {
Johny Lina891f0e2017-12-19 10:25:27 +0800131 case media::PIXEL_FORMAT_I420:
132 case media::PIXEL_FORMAT_YV12:
133 case media::PIXEL_FORMAT_NV12:
134 case media::PIXEL_FORMAT_NV21:
135 // HAL_PIXEL_FORMAT_YCbCr_420_888 is the flexible pixel format in Android
136 // which handles all 420 formats, with both orderings of chroma (CbCr and
137 // CrCb) as well as planar and semi-planar layouts.
138 pixelFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
139 break;
140 case media::PIXEL_FORMAT_ARGB:
141 pixelFormat = HAL_PIXEL_FORMAT_BGRA_8888;
142 break;
143 default:
144 ALOGE("Format not supported: %d", output_format);
145 mClient->notifyError(PLATFORM_FAILURE);
146 return;
Johny Lin48690172017-08-04 11:11:50 +0800147 }
148
149 mClient->providePictureBuffers(pixelFormat, requested_num_of_buffers, dimensions);
150 mPictureSize = dimensions;
151}
152
153void C2VDAAdaptor::DismissPictureBuffer(int32_t picture_buffer_id) {
154 mClient->dismissPictureBuffer(picture_buffer_id);
155}
156
157void C2VDAAdaptor::PictureReady(const media::Picture& picture) {
Johny Lina891f0e2017-12-19 10:25:27 +0800158 mClient->pictureReady(picture.picture_buffer_id(), picture.bitstream_buffer_id(),
Johny Lin48690172017-08-04 11:11:50 +0800159 picture.visible_rect());
160}
161
162void C2VDAAdaptor::NotifyEndOfBitstreamBuffer(int32_t bitstream_buffer_id) {
163 mClient->notifyEndOfBitstreamBuffer(bitstream_buffer_id);
164}
165
166void C2VDAAdaptor::NotifyFlushDone() {
167 mClient->notifyFlushDone();
168}
169
170void C2VDAAdaptor::NotifyResetDone() {
171 mClient->notifyResetDone();
172}
173
174static VideoDecodeAcceleratorAdaptor::Result convertErrorCode(
175 media::VideoDecodeAccelerator::Error error) {
176 switch (error) {
Johny Lina891f0e2017-12-19 10:25:27 +0800177 case media::VideoDecodeAccelerator::ILLEGAL_STATE:
178 return VideoDecodeAcceleratorAdaptor::ILLEGAL_STATE;
179 case media::VideoDecodeAccelerator::INVALID_ARGUMENT:
180 return VideoDecodeAcceleratorAdaptor::INVALID_ARGUMENT;
181 case media::VideoDecodeAccelerator::UNREADABLE_INPUT:
182 return VideoDecodeAcceleratorAdaptor::UNREADABLE_INPUT;
183 case media::VideoDecodeAccelerator::PLATFORM_FAILURE:
184 return VideoDecodeAcceleratorAdaptor::PLATFORM_FAILURE;
185 default:
186 ALOGE("Unknown error code: %d", static_cast<int>(error));
187 return VideoDecodeAcceleratorAdaptor::PLATFORM_FAILURE;
Johny Lin48690172017-08-04 11:11:50 +0800188 }
189}
190
191void C2VDAAdaptor::NotifyError(media::VideoDecodeAccelerator::Error error) {
192 mClient->notifyError(convertErrorCode(error));
193}
194
195} // namespace android