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 uint32_t MAX_SIZE = 3150000; // 3MB
23 constexpr uint32_t MAX_WIDTH = 8000;
24 constexpr uint32_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 return MSERR_OK;
58 }
59
GetInputPortConfig()60 std::shared_ptr<ProcessorConfig> ProcessorVdecImpl::GetInputPortConfig()
61 {
62 CHECK_AND_RETURN_RET(width_ > 0 && width_ < MAX_WIDTH, nullptr);
63 CHECK_AND_RETURN_RET(height_ > 0 && height_ < MAX_HEIGHT, nullptr);
64
65 GstCaps *caps = nullptr;
66 switch (codecName_) {
67 case CODEC_MIMIE_TYPE_VIDEO_MPEG2:
68 caps = gst_caps_new_simple("video/mpeg",
69 "width", G_TYPE_INT, width_, "height", G_TYPE_INT, height_,
70 "mpegversion", G_TYPE_INT, 2, "systemstream", G_TYPE_BOOLEAN, FALSE, nullptr);
71 break;
72 case CODEC_MIMIE_TYPE_VIDEO_MPEG4:
73 caps = gst_caps_new_simple("video/mpeg",
74 "width", G_TYPE_INT, width_, "height", G_TYPE_INT, height_,
75 "mpegversion", G_TYPE_INT, 4, "systemstream", G_TYPE_BOOLEAN, FALSE, nullptr);
76 break;
77 case CODEC_MIMIE_TYPE_VIDEO_H263:
78 caps = gst_caps_new_simple("video/x-h263",
79 "width", G_TYPE_INT, width_, "height", G_TYPE_INT, height_,
80 "variant", G_TYPE_STRING, "itu", nullptr);
81 break;
82 case CODEC_MIMIE_TYPE_VIDEO_AVC:
83 caps = gst_caps_new_simple("video/x-h264",
84 "width", G_TYPE_INT, width_, "height", G_TYPE_INT, height_,
85 "framerate", GST_TYPE_FRACTION, frameRate_, 1,
86 "alignment", G_TYPE_STRING, "nal", "stream-format", G_TYPE_STRING, "byte-stream",
87 "systemstream", G_TYPE_BOOLEAN, FALSE, nullptr);
88 break;
89 case CODEC_MIMIE_TYPE_VIDEO_HEVC:
90 caps = gst_caps_new_simple("video/x-h265",
91 "width", G_TYPE_INT, width_, "height", G_TYPE_INT, height_,
92 "alignment", G_TYPE_STRING, "nal", "stream-format", G_TYPE_STRING, "byte-stream",
93 "systemstream", G_TYPE_BOOLEAN, FALSE, nullptr);
94 break;
95 default:
96 break;
97 }
98 CHECK_AND_RETURN_RET_LOG(caps != nullptr, nullptr, "Unsupported format");
99
100 auto config = std::make_shared<ProcessorConfig>(caps, false);
101 if (config == nullptr) {
102 gst_caps_unref(caps);
103 return nullptr;
104 }
105
106 config->needCodecData_ = (codecName_ == CODEC_MIMIE_TYPE_VIDEO_AVC && isSoftWare_) ? true : false;
107 if (maxInputSize_ > 0) {
108 config->bufferSize_ = (maxInputSize_ > MAX_SIZE) ? MAX_SIZE : static_cast<uint32_t>(maxInputSize_);
109 } else {
110 config->bufferSize_ = CompressedBufSize(width_, height_, false, codecName_);
111 }
112
113 return config;
114 }
115
GetOutputPortConfig()116 std::shared_ptr<ProcessorConfig> ProcessorVdecImpl::GetOutputPortConfig()
117 {
118 CHECK_AND_RETURN_RET(width_ > 0 && width_ < MAX_WIDTH, nullptr);
119 CHECK_AND_RETURN_RET(height_ > 0 && height_ < MAX_HEIGHT, nullptr);
120
121 GstCaps *caps = gst_caps_new_simple("video/x-raw",
122 "format", G_TYPE_STRING, gstPixelFormat_.c_str(), nullptr);
123 CHECK_AND_RETURN_RET_LOG(caps != nullptr, nullptr, "No memory");
124
125 auto config = std::make_shared<ProcessorConfig>(caps, false);
126 if (config == nullptr) {
127 MEDIA_LOGE("No memory");
128 gst_caps_unref(caps);
129 return nullptr;
130 }
131
132 constexpr uint32_t alignment = 16;
133 config->bufferSize_ = PixelBufferSize(static_cast<VideoPixelFormat>(pixelFormat_),
134 static_cast<uint32_t>(width_), static_cast<uint32_t>(height_), alignment);
135
136 return config;
137 }
138 } // namespace Media
139 } // namespace OHOS
140