1 /**
2  * Copyright 2021, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "TunerDemux"
18 
19 #include "TunerDvr.h"
20 #include "TunerDemux.h"
21 #include "TunerTimeFilter.h"
22 
23 using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
24 using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
25 using ::android::hardware::tv::tuner::V1_0::DemuxFilterType;
26 using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
27 using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
28 using ::android::hardware::tv::tuner::V1_0::DemuxTlvFilterType;
29 using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
30 using ::android::hardware::tv::tuner::V1_0::DvrType;
31 using ::android::hardware::tv::tuner::V1_0::Result;
32 
33 namespace android {
34 
TunerDemux(sp<IDemux> demux,int id)35 TunerDemux::TunerDemux(sp<IDemux> demux, int id) {
36     mDemux = demux;
37     mDemuxId = id;
38 }
39 
~TunerDemux()40 TunerDemux::~TunerDemux() {
41     mDemux = nullptr;
42 }
43 
setFrontendDataSource(const std::shared_ptr<ITunerFrontend> & frontend)44 Status TunerDemux::setFrontendDataSource(const std::shared_ptr<ITunerFrontend>& frontend) {
45     if (mDemux == nullptr) {
46         ALOGE("IDemux is not initialized");
47         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
48     }
49 
50     int frontendId;
51     frontend->getFrontendId(&frontendId);
52     Result res = mDemux->setFrontendDataSource(frontendId);
53     if (res != Result::SUCCESS) {
54         return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
55     }
56     return Status::ok();
57 }
58 
openFilter(int type,int subType,int bufferSize,const std::shared_ptr<ITunerFilterCallback> & cb,std::shared_ptr<ITunerFilter> * _aidl_return)59 Status TunerDemux::openFilter(
60         int type, int subType, int bufferSize, const std::shared_ptr<ITunerFilterCallback>& cb,
61         std::shared_ptr<ITunerFilter>* _aidl_return) {
62     if (mDemux == nullptr) {
63         ALOGE("IDemux is not initialized.");
64         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
65     }
66 
67     DemuxFilterMainType mainType = static_cast<DemuxFilterMainType>(type);
68     DemuxFilterType filterType {
69         .mainType = mainType,
70     };
71 
72     switch(mainType) {
73         case DemuxFilterMainType::TS:
74             filterType.subType.tsFilterType(static_cast<DemuxTsFilterType>(subType));
75             break;
76         case DemuxFilterMainType::MMTP:
77             filterType.subType.mmtpFilterType(static_cast<DemuxMmtpFilterType>(subType));
78             break;
79         case DemuxFilterMainType::IP:
80             filterType.subType.ipFilterType(static_cast<DemuxIpFilterType>(subType));
81             break;
82         case DemuxFilterMainType::TLV:
83             filterType.subType.tlvFilterType(static_cast<DemuxTlvFilterType>(subType));
84             break;
85         case DemuxFilterMainType::ALP:
86             filterType.subType.alpFilterType(static_cast<DemuxAlpFilterType>(subType));
87             break;
88     }
89     Result status;
90     sp<IFilter> filterSp;
91     sp<IFilterCallback> cbSp = new TunerFilter::FilterCallback(cb);
92     mDemux->openFilter(filterType, bufferSize, cbSp,
93             [&](Result r, const sp<IFilter>& filter) {
94                 filterSp = filter;
95                 status = r;
96             });
97     if (status != Result::SUCCESS) {
98         return Status::fromServiceSpecificError(static_cast<int32_t>(status));
99     }
100 
101     *_aidl_return = ::ndk::SharedRefBase::make<TunerFilter>(filterSp, type, subType);
102     return Status::ok();
103 }
104 
openTimeFilter(shared_ptr<ITunerTimeFilter> * _aidl_return)105 Status TunerDemux::openTimeFilter(shared_ptr<ITunerTimeFilter>* _aidl_return) {
106     if (mDemux == nullptr) {
107         ALOGE("IDemux is not initialized.");
108         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
109     }
110 
111     Result status;
112     sp<ITimeFilter> filterSp;
113     mDemux->openTimeFilter([&](Result r, const sp<ITimeFilter>& filter) {
114         filterSp = filter;
115         status = r;
116     });
117     if (status != Result::SUCCESS) {
118         return Status::fromServiceSpecificError(static_cast<int32_t>(status));
119     }
120 
121     *_aidl_return = ::ndk::SharedRefBase::make<TunerTimeFilter>(filterSp);
122     return Status::ok();
123 }
124 
getAvSyncHwId(const shared_ptr<ITunerFilter> & tunerFilter,int * _aidl_return)125 Status TunerDemux::getAvSyncHwId(const shared_ptr<ITunerFilter>& tunerFilter, int* _aidl_return) {
126     if (mDemux == nullptr) {
127         ALOGE("IDemux is not initialized.");
128         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
129     }
130 
131     uint32_t avSyncHwId;
132     Result res;
133     sp<IFilter> halFilter = static_cast<TunerFilter*>(tunerFilter.get())->getHalFilter();
134     mDemux->getAvSyncHwId(halFilter,
135             [&](Result r, uint32_t id) {
136                 res = r;
137                 avSyncHwId = id;
138             });
139     if (res != Result::SUCCESS) {
140         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
141     }
142 
143     *_aidl_return = (int)avSyncHwId;
144     return Status::ok();
145 }
146 
getAvSyncTime(int avSyncHwId,int64_t * _aidl_return)147 Status TunerDemux::getAvSyncTime(int avSyncHwId, int64_t* _aidl_return) {
148     if (mDemux == nullptr) {
149         ALOGE("IDemux is not initialized.");
150         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
151     }
152 
153     uint64_t time;
154     Result res;
155     mDemux->getAvSyncTime(static_cast<uint32_t>(avSyncHwId),
156             [&](Result r, uint64_t ts) {
157                 res = r;
158                 time = ts;
159             });
160     if (res != Result::SUCCESS) {
161         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
162     }
163 
164     *_aidl_return = (int64_t)time;
165     return Status::ok();
166 }
167 
openDvr(int dvrType,int bufferSize,const shared_ptr<ITunerDvrCallback> & cb,shared_ptr<ITunerDvr> * _aidl_return)168 Status TunerDemux::openDvr(int dvrType, int bufferSize, const shared_ptr<ITunerDvrCallback>& cb,
169         shared_ptr<ITunerDvr>* _aidl_return) {
170     if (mDemux == nullptr) {
171         ALOGE("IDemux is not initialized.");
172         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
173     }
174 
175     Result res;
176     sp<IDvrCallback> callback = new TunerDvr::DvrCallback(cb);
177     sp<IDvr> hidlDvr;
178     mDemux->openDvr(static_cast<DvrType>(dvrType), bufferSize, callback,
179             [&](Result r, const sp<IDvr>& dvr) {
180                 hidlDvr = dvr;
181                 res = r;
182             });
183     if (res != Result::SUCCESS) {
184         *_aidl_return = NULL;
185         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
186     }
187 
188     *_aidl_return = ::ndk::SharedRefBase::make<TunerDvr>(hidlDvr, dvrType);
189     return Status::ok();
190 }
191 
connectCiCam(int ciCamId)192 Status TunerDemux::connectCiCam(int ciCamId) {
193     if (mDemux == nullptr) {
194         ALOGE("IDemux is not initialized.");
195         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
196     }
197 
198     Result res = mDemux->connectCiCam(static_cast<uint32_t>(ciCamId));
199     if (res != Result::SUCCESS) {
200         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
201     }
202     return Status::ok();
203 }
204 
disconnectCiCam()205 Status TunerDemux::disconnectCiCam() {
206     if (mDemux == nullptr) {
207         ALOGE("IDemux is not initialized.");
208         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
209     }
210 
211     Result res = mDemux->disconnectCiCam();
212     if (res != Result::SUCCESS) {
213         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
214     }
215     return Status::ok();
216 }
217 
close()218 Status TunerDemux::close() {
219     if (mDemux == nullptr) {
220         ALOGE("IDemux is not initialized.");
221         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
222     }
223 
224     Result res = mDemux->close();
225     mDemux = NULL;
226 
227     if (res != Result::SUCCESS) {
228         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
229     }
230     return Status::ok();
231 }
232 }  // namespace android
233