blob: f15eb717427b14040a1883177df26f02bf975c8d [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"
11#include "v4l2_slice_video_decode_accelerator.h"
12
13#include <system/graphics.h>
14#include <utils/Log.h>
15
16namespace android {
17
18C2VDAAdaptor::C2VDAAdaptor() : mNumOutputBuffers(0u) {
19}
20
21C2VDAAdaptor::~C2VDAAdaptor() {
22 if (mVDA) {
23 destroy();
24 }
25}
26
27VideoDecodeAcceleratorAdaptor::Result C2VDAAdaptor::initialize(
28 media::VideoCodecProfile profile, VideoDecodeAcceleratorAdaptor::Client* client) {
29 if (mVDA) {
30 ALOGE("Re-initialize() is not allowed");
31 return ILLEGAL_STATE;
32 }
33
34 media::VideoDecodeAccelerator::Config config;
35 config.profile = profile;
36 config.output_mode = media::VideoDecodeAccelerator::Config::OutputMode::IMPORT;
37
38 // TODO(johnylin): may need to implement factory to create VDA if there are multiple VDA
39 // implementations in the future.
40 scoped_refptr<media::V4L2Device> device = new media::V4L2Device();
41 std::unique_ptr<media::VideoDecodeAccelerator> vda(
42 new media::V4L2SliceVideoDecodeAccelerator(device));
43 if (!vda->Initialize(config, this)) {
44 ALOGE("Failed to initialize VDA");
45 return PLATFORM_FAILURE;
46 }
47
48 mVDA = std::move(vda);
49 mClient = client;
50
51 return SUCCESS;
52}
53
54void C2VDAAdaptor::decode(int32_t bitstreamId, int ashmemFd, off_t offset, uint32_t bytesUsed) {
55 CHECK(mVDA);
56 mVDA->Decode(media::BitstreamBuffer(
57 bitstreamId, base::SharedMemoryHandle(ashmemFd, true), bytesUsed, offset));
58}
59
60void C2VDAAdaptor::assignPictureBuffers(uint32_t numOutputBuffers) {
61 CHECK(mVDA);
62 std::vector<media::PictureBuffer> buffers;
63 for (uint32_t id = 0; id < numOutputBuffers; ++id) {
64 buffers.push_back(
65 media::PictureBuffer(static_cast<int32_t>(id), mPictureSize));
66 }
67 mVDA->AssignPictureBuffers(buffers);
68 mNumOutputBuffers = numOutputBuffers;
69}
70
71void C2VDAAdaptor::importBufferForPicture(int32_t pictureBufferId, int dmabufFd,
72 const std::vector<VideoFramePlane>& planes) {
73 CHECK(mVDA);
74 CHECK_LT(pictureBufferId, static_cast<int32_t>(mNumOutputBuffers));
75
76 media::NativePixmapHandle handle;
77 handle.fds.emplace_back(base::FileDescriptor(dmabufFd, true));
78 for (const auto& plane : planes) {
79 handle.planes.emplace_back(plane.stride, plane.offset, 0, 0);
80 }
81 mVDA->ImportBufferForPicture(pictureBufferId, handle);
82}
83
84void C2VDAAdaptor::reusePictureBuffer(int32_t pictureBufferId) {
85 CHECK(mVDA);
86 CHECK_LT(pictureBufferId, static_cast<int32_t>(mNumOutputBuffers));
87
88 mVDA->ReusePictureBuffer(pictureBufferId);
89}
90
91void C2VDAAdaptor::flush() {
92 CHECK(mVDA);
93 mVDA->Flush();
94}
95
96void C2VDAAdaptor::reset() {
97 CHECK(mVDA);
98 mVDA->Reset();
99}
100
101void C2VDAAdaptor::destroy() {
102 mVDA.reset(nullptr);
103 mNumOutputBuffers = 0u;
104 mPictureSize = media::Size();
105}
106
107
108void C2VDAAdaptor::ProvidePictureBuffers(uint32_t requested_num_of_buffers,
109 media::VideoPixelFormat output_format,
110 const media::Size& dimensions) {
111 uint32_t pixelFormat;
112 switch (output_format) {
113 case media::PIXEL_FORMAT_I420:
114 case media::PIXEL_FORMAT_YV12:
115 case media::PIXEL_FORMAT_NV12:
116 case media::PIXEL_FORMAT_NV21:
117 // HAL_PIXEL_FORMAT_YCbCr_420_888 is the flexible pixel format in Android
118 // which handles all 420 formats, with both orderings of chroma (CbCr and
119 // CrCb) as well as planar and semi-planar layouts.
120 pixelFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
121 break;
122 case media::PIXEL_FORMAT_ARGB:
123 pixelFormat = HAL_PIXEL_FORMAT_BGRA_8888;
124 break;
125 default:
126 ALOGE("Format not supported: %d", output_format);
127 mClient->notifyError(PLATFORM_FAILURE);
128 return;
129 }
130
131 mClient->providePictureBuffers(pixelFormat, requested_num_of_buffers, dimensions);
132 mPictureSize = dimensions;
133}
134
135void C2VDAAdaptor::DismissPictureBuffer(int32_t picture_buffer_id) {
136 mClient->dismissPictureBuffer(picture_buffer_id);
137}
138
139void C2VDAAdaptor::PictureReady(const media::Picture& picture) {
140 mClient->pictureReady(picture.picture_buffer_id(),
141 picture.bitstream_buffer_id(),
142 picture.visible_rect());
143}
144
145void C2VDAAdaptor::NotifyEndOfBitstreamBuffer(int32_t bitstream_buffer_id) {
146 mClient->notifyEndOfBitstreamBuffer(bitstream_buffer_id);
147}
148
149void C2VDAAdaptor::NotifyFlushDone() {
150 mClient->notifyFlushDone();
151}
152
153void C2VDAAdaptor::NotifyResetDone() {
154 mClient->notifyResetDone();
155}
156
157static VideoDecodeAcceleratorAdaptor::Result convertErrorCode(
158 media::VideoDecodeAccelerator::Error error) {
159 switch (error) {
160 case media::VideoDecodeAccelerator::ILLEGAL_STATE:
161 return VideoDecodeAcceleratorAdaptor::ILLEGAL_STATE;
162 case media::VideoDecodeAccelerator::INVALID_ARGUMENT:
163 return VideoDecodeAcceleratorAdaptor::INVALID_ARGUMENT;
164 case media::VideoDecodeAccelerator::UNREADABLE_INPUT:
165 return VideoDecodeAcceleratorAdaptor::UNREADABLE_INPUT;
166 case media::VideoDecodeAccelerator::PLATFORM_FAILURE:
167 return VideoDecodeAcceleratorAdaptor::PLATFORM_FAILURE;
168 default:
169 ALOGE("Unknown error code: %d", error);
170 return VideoDecodeAcceleratorAdaptor::PLATFORM_FAILURE;
171 }
172}
173
174void C2VDAAdaptor::NotifyError(media::VideoDecodeAccelerator::Error error) {
175 mClient->notifyError(convertErrorCode(error));
176}
177
178} // namespace android
179