1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "processor_vdec_impl.h"
17 #include "media_errors.h"
18 #include "media_log.h"
19
20 namespace {
21 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ProcessorVdecImpl"};
22 constexpr int32_t MAX_SIZE = 3150000; // 3MB
23 constexpr int32_t MAX_WIDTH = 8000;
24 constexpr int32_t MAX_HEIGHT = 5000;
25 }
26
27 namespace OHOS {
28 namespace Media {
ProcessorVdecImpl()29 ProcessorVdecImpl::ProcessorVdecImpl()
30 {
31 }
32
~ProcessorVdecImpl()33 ProcessorVdecImpl::~ProcessorVdecImpl()
34 {
35 }
36
ProcessMandatory(const Format & format)37 int32_t ProcessorVdecImpl::ProcessMandatory(const Format &format)
38 {
39 CHECK_AND_RETURN_RET(format.GetIntValue("width", width_) == true, MSERR_INVALID_VAL);
40 CHECK_AND_RETURN_RET(format.GetIntValue("height", height_) == true, MSERR_INVALID_VAL);
41 CHECK_AND_RETURN_RET(format.GetIntValue("pixel_format", pixelFormat_) == true, MSERR_INVALID_VAL);
42 CHECK_AND_RETURN_RET(format.GetIntValue("frame_rate", frameRate_) == true, MSERR_INVALID_VAL);
43 MEDIA_LOGD("width:%{public}d, height:%{public}d, pixel:%{public}d, frameRate:%{public}d",
44 width_, height_, pixelFormat_, frameRate_);
45
46 gstPixelFormat_ = PixelFormatToGst(static_cast<VideoPixelFormat>(pixelFormat_));
47
48 return MSERR_OK;
49 }
50
ProcessOptional(const Format & format)51 int32_t ProcessorVdecImpl::ProcessOptional(const Format &format)
52 {
53 if (format.GetValueType(std::string_view("max_input_size")) == FORMAT_TYPE_INT32) {
54 (void)format.GetIntValue("max_input_size", maxInputSize_);
55 }
56
57 if (format.GetValueType(std::string_view("rotation_angle")) == FORMAT_TYPE_INT32) {
58 (void)format.GetIntValue("rotation_angle", videoRotation_);
59 if (videoRotation_ != VIDEO_ROTATION_0 && videoRotation_ != VIDEO_ROTATION_90 &&
60 videoRotation_ != VIDEO_ROTATION_180 && videoRotation_ != VIDEO_ROTATION_270) {
61 MEDIA_LOGE("The rotation angle can only be {0, 90, 180, 270}, current val is %{public}d", videoRotation_);
62 return MSERR_UNSUPPORT_VID_PARAMS;
63 }
64 }
65
66 return MSERR_OK;
67 }
68
GetInputPortConfig()69 std::shared_ptr<ProcessorConfig> ProcessorVdecImpl::GetInputPortConfig()
70 {
71 CHECK_AND_RETURN_RET(width_ > 0 && width_ < MAX_WIDTH, nullptr);
72 CHECK_AND_RETURN_RET(height_ > 0 && height_ < MAX_HEIGHT, nullptr);
73
74 GstCaps *caps = nullptr;
75 switch (codecName_) {
76 case CODEC_MIME_TYPE_VIDEO_MPEG2:
77 caps = gst_caps_new_simple("video/mpeg",
78 "width", G_TYPE_INT, width_, "height", G_TYPE_INT, height_,
79 "mpegversion", G_TYPE_INT, 2, "systemstream", G_TYPE_BOOLEAN, FALSE, nullptr);
80 break;
81 case CODEC_MIME_TYPE_VIDEO_MPEG4:
82 caps = gst_caps_new_simple("video/mpeg",
83 "width", G_TYPE_INT, width_, "height", G_TYPE_INT, height_,
84 "mpegversion", G_TYPE_INT, 4, "systemstream", G_TYPE_BOOLEAN, FALSE, nullptr);
85 break;
86 case CODEC_MIME_TYPE_VIDEO_H263:
87 caps = gst_caps_new_simple("video/x-h263",
88 "width", G_TYPE_INT, width_, "height", G_TYPE_INT, height_,
89 "variant", G_TYPE_STRING, "itu", nullptr);
90 break;
91 case CODEC_MIME_TYPE_VIDEO_AVC:
92 caps = gst_caps_new_simple("video/x-h264",
93 "width", G_TYPE_INT, width_, "height", G_TYPE_INT, height_,
94 "framerate", GST_TYPE_FRACTION, frameRate_, 1,
95 "alignment", G_TYPE_STRING, "nal", "stream-format", G_TYPE_STRING, "byte-stream",
96 "systemstream", G_TYPE_BOOLEAN, FALSE, nullptr);
97 break;
98 case CODEC_MIME_TYPE_VIDEO_HEVC:
99 caps = gst_caps_new_simple("video/x-h265",
100 "width", G_TYPE_INT, width_, "height", G_TYPE_INT, height_,
101 "alignment", G_TYPE_STRING, "nal", "stream-format", G_TYPE_STRING, "byte-stream",
102 "systemstream", G_TYPE_BOOLEAN, FALSE, nullptr);
103 break;
104 default:
105 break;
106 }
107 CHECK_AND_RETURN_RET_LOG(caps != nullptr, nullptr, "Unsupported format");
108
109 auto config = std::make_shared<ProcessorConfig>(caps, false);
110 config->needCodecData_ = (codecName_ == CODEC_MIME_TYPE_VIDEO_AVC && isSoftWare_);
111 if (maxInputSize_ > 0) {
112 config->bufferSize_ = (maxInputSize_ > MAX_SIZE) ? MAX_SIZE : maxInputSize_;
113 } else {
114 // Memory is aligned to 16 bytes
115 constexpr uint32_t alignment = 16;
116 config->bufferSize_ = PixelBufferSize(static_cast<VideoPixelFormat>(pixelFormat_), width_, height_, alignment);
117 }
118
119 return config;
120 }
121
GetOutputPortConfig()122 std::shared_ptr<ProcessorConfig> ProcessorVdecImpl::GetOutputPortConfig()
123 {
124 CHECK_AND_RETURN_RET(width_ > 0 && width_ < MAX_WIDTH, nullptr);
125 CHECK_AND_RETURN_RET(height_ > 0 && height_ < MAX_HEIGHT, nullptr);
126
127 GstCaps *caps = gst_caps_new_simple("video/x-raw",
128 "format", G_TYPE_STRING, gstPixelFormat_.c_str(), nullptr);
129 CHECK_AND_RETURN_RET_LOG(caps != nullptr, nullptr, "No memory");
130
131 auto config = std::make_shared<ProcessorConfig>(caps, false);
132 // Memory is aligned to 16 bytes
133 constexpr uint32_t alignment = 16;
134 config->bufferSize_ = PixelBufferSize(static_cast<VideoPixelFormat>(pixelFormat_),
135 static_cast<uint32_t>(width_), static_cast<uint32_t>(height_), alignment);
136
137 config->videoRotation_ = static_cast<uint32_t>(videoRotation_);
138
139 return config;
140 }
141 } // namespace Media
142 } // namespace OHOS
143