1 /*
2 * Copyright (c) 2024-2025 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 #define HST_LOG_TAG "StreamDemuxer"
17
18 #include "stream_demuxer.h"
19
20 #include <algorithm>
21 #include <map>
22 #include <memory>
23
24 #include "avcodec_common.h"
25 #include "avcodec_trace.h"
26 #include "cpp_ext/type_traits_ext.h"
27 #include "buffer/avallocator.h"
28 #include "common/event.h"
29 #include "common/log.h"
30 #include "meta/media_types.h"
31 #include "meta/meta.h"
32 #include "osal/utils/dump_buffer.h"
33 #include "plugin/plugin_buffer.h"
34 #include "plugin/plugin_info.h"
35 #include "plugin/plugin_time.h"
36 #include "source/source.h"
37
38 namespace {
39 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "StreamDemuxer" };
40 }
41
42 namespace OHOS {
43 namespace Media {
44
45 const int32_t TRY_READ_SLEEP_TIME = 10; //ms
46 const int32_t TRY_READ_TIMES = 10;
47 constexpr uint64_t LIVE_CONTENT_LENGTH = 2147483646;
StreamDemuxer()48 StreamDemuxer::StreamDemuxer() : position_(0)
49 {
50 MEDIA_LOG_I("VodStreamDemuxer called");
51 }
52
~StreamDemuxer()53 StreamDemuxer::~StreamDemuxer()
54 {
55 MEDIA_LOG_I("~VodStreamDemuxer called");
56 ResetAllCache();
57 }
58
ReadFrameData(int32_t streamID,uint64_t offset,size_t size,std::shared_ptr<Buffer> & bufferPtr)59 Status StreamDemuxer::ReadFrameData(int32_t streamID, uint64_t offset, size_t size,
60 std::shared_ptr<Buffer>& bufferPtr)
61 {
62 if (IsDash() || GetIsDataSrcNoSeek()) {
63 MEDIA_LOG_D("GetPeekRange read cache, offset: " PUBLIC_LOG_U64 " streamID: " PUBLIC_LOG_D32, offset, streamID);
64 if (cacheDataMap_.find(streamID) != cacheDataMap_.end() && cacheDataMap_[streamID].CheckCacheExist(offset)) {
65 MEDIA_LOG_D("GetPeekRange read cache, offset: " PUBLIC_LOG_U64, offset);
66 auto memory = cacheDataMap_[streamID].GetData()->GetMemory();
67 if (memory != nullptr && memory->GetSize() > 0) {
68 MEDIA_LOG_D("GetPeekRange read cache, Read data from cache data. streamID: " PUBLIC_LOG_D32, streamID);
69 return PullDataWithCache(streamID, offset, size, bufferPtr);
70 }
71 }
72 }
73 return PullData(streamID, offset, size, bufferPtr);
74 }
75
ReadHeaderData(int32_t streamID,uint64_t offset,size_t size,std::shared_ptr<Buffer> & bufferPtr)76 Status StreamDemuxer::ReadHeaderData(int32_t streamID, uint64_t offset, size_t size,
77 std::shared_ptr<Buffer>& bufferPtr)
78 {
79 if (cacheDataMap_.find(streamID) != cacheDataMap_.end() && cacheDataMap_[streamID].CheckCacheExist(offset)) {
80 MEDIA_LOG_D("GetPeekRange read cache, offset: " PUBLIC_LOG_U64, offset);
81 auto memory = cacheDataMap_[streamID].GetData()->GetMemory();
82 if (memory != nullptr && memory->GetSize() > 0) {
83 MEDIA_LOG_D("GetPeekRange read cache, Read data from cache data.");
84 return PullDataWithCache(streamID, offset, size, bufferPtr);
85 }
86 }
87 return PullDataWithoutCache(streamID, offset, size, bufferPtr);
88 }
89
GetPeekRange(int32_t streamID,uint64_t offset,size_t size,std::shared_ptr<Buffer> & bufferPtr)90 Status StreamDemuxer::GetPeekRange(int32_t streamID, uint64_t offset, size_t size, std::shared_ptr<Buffer>& bufferPtr)
91 {
92 FALSE_RETURN_V_MSG_E(!isInterruptNeeded_.load(), Status::ERROR_WRONG_STATE,
93 "GetPeekRange interrupt " PUBLIC_LOG_D32 " " PUBLIC_LOG_U64 " " PUBLIC_LOG_ZU, streamID, offset, size);
94 FALSE_RETURN_V_MSG_E(streamID >= 0, Status::ERROR_INVALID_PARAMETER,
95 "Invalid streamId, id = " PUBLIC_LOG_D32, streamID);
96 if (bufferPtr == nullptr) {
97 MEDIA_LOG_E("GetPeekRange bufferPtr invalid.");
98 return Status::ERROR_INVALID_PARAMETER;
99 }
100 bufferPtr->streamID = streamID;
101 Status ret = Status::OK;
102 if (pluginStateMap_[streamID] == DemuxerState::DEMUXER_STATE_PARSE_FRAME) {
103 ret = ReadFrameData(streamID, offset, size, bufferPtr);
104 } else {
105 ret = ReadHeaderData(streamID, offset, size, bufferPtr);
106 }
107 if (ret != Status::OK) {
108 return ret;
109 }
110 return CheckChangeStreamID(streamID, bufferPtr);
111 }
112
Init(const std::string & uri)113 Status StreamDemuxer::Init(const std::string& uri)
114 {
115 MediaAVCodec::AVCodecTrace trace("StreamDemuxer::Init");
116 MEDIA_LOG_I("StreamDemuxer::Init called");
117 checkRange_ = [](int32_t streamID, uint64_t offset, uint32_t size) {
118 return Status::OK;
119 };
120 peekRange_ = [this](int32_t streamID, uint64_t offset, size_t size, std::shared_ptr<Buffer>& bufferPtr) -> Status {
121 return GetPeekRange(streamID, offset, size, bufferPtr);
122 };
123 getRange_ = peekRange_;
124 uri_ = uri;
125 return Status::OK;
126 }
127
PullDataWithCache(int32_t streamID,uint64_t offset,size_t size,std::shared_ptr<Buffer> & bufferPtr)128 Status StreamDemuxer::PullDataWithCache(int32_t streamID, uint64_t offset, size_t size,
129 std::shared_ptr<Buffer>& bufferPtr)
130 {
131 FALSE_RETURN_V_MSG_E(bufferPtr->GetMemory() != nullptr, Status::ERROR_UNKNOWN, "bufferPtr invalid");
132 auto memory = cacheDataMap_[streamID].GetData()->GetMemory();
133 FALSE_RETURN_V_MSG_E(memory != nullptr, Status::ERROR_UNKNOWN, "memory invalid");
134 MEDIA_LOG_D("PullDataWithCache, Read data from cache data. streamID: " PUBLIC_LOG_D32, streamID);
135 uint64_t offsetInCache = offset - cacheDataMap_[streamID].GetOffset();
136 if (size <= memory->GetSize() - offsetInCache) {
137 MEDIA_LOG_D("Readfromcache. streamID: " PUBLIC_LOG_D32, streamID);
138 bufferPtr->GetMemory()->Write(memory->GetReadOnlyData() + offsetInCache, size, 0);
139 return Status::OK;
140 }
141 bufferPtr->GetMemory()->Write(memory->GetReadOnlyData() + offsetInCache, memory->GetSize() - offsetInCache, 0);
142 uint64_t remainOffset = cacheDataMap_[streamID].GetOffset() + memory->GetSize();
143 uint64_t remainSize = size - (memory->GetSize() - offsetInCache);
144 std::shared_ptr<Buffer> tempBuffer = Buffer::CreateDefaultBuffer(remainSize);
145 if (tempBuffer == nullptr || tempBuffer->GetMemory() == nullptr) {
146 MEDIA_LOG_W("PullDataWithCache, Read data from cache data. only get partial data.");
147 return Status::ERROR_UNKNOWN;
148 }
149 Status ret = PullData(streamID, remainOffset, remainSize, tempBuffer);
150 if (ret == Status::OK) {
151 FALSE_RETURN_V_MSG_E(tempBuffer->GetMemory() != nullptr, Status::ERROR_UNKNOWN, "tempBuffer invalid");
152 bufferPtr->GetMemory()->Write(tempBuffer->GetMemory()->GetReadOnlyData(),
153 tempBuffer->GetMemory()->GetSize(), memory->GetSize() - offsetInCache);
154 if (pluginStateMap_[streamID] == DemuxerState::DEMUXER_STATE_PARSE_FRAME) {
155 MEDIA_LOG_W("PullDataWithCache, not cache begin.");
156 return ret;
157 }
158 std::shared_ptr<Buffer> mergedBuffer = Buffer::CreateDefaultBuffer(
159 tempBuffer->GetMemory()->GetSize() + memory->GetSize());
160 FALSE_RETURN_V_MSG_E(mergedBuffer != nullptr, Status::ERROR_UNKNOWN, "mergedBuffer invalid");
161 FALSE_RETURN_V_MSG_E(mergedBuffer->GetMemory() != nullptr, Status::ERROR_UNKNOWN,
162 "mergedBuffer->GetMemory invalid");
163 mergedBuffer->GetMemory()->Write(memory->GetReadOnlyData(), memory->GetSize(), 0);
164 mergedBuffer->GetMemory()->Write(tempBuffer->GetMemory()->GetReadOnlyData(),
165 tempBuffer->GetMemory()->GetSize(), memory->GetSize());
166 cacheDataMap_[streamID].SetData(mergedBuffer);
167 memory = cacheDataMap_[streamID].GetData()->GetMemory();
168 FALSE_RETURN_V_MSG_E(memory != nullptr, Status::ERROR_UNKNOWN, "memory invalid");
169 MEDIA_LOG_I("PullDataWithCache, offset: " PUBLIC_LOG_U64 ", cache offset: " PUBLIC_LOG_U64
170 ", cache size: " PUBLIC_LOG_ZU, offset, cacheDataMap_[streamID].GetOffset(), memory->GetSize());
171 }
172 FALSE_RETURN_V_MSG_E(ret != Status::END_OF_STREAM, Status::OK, "eos&data return data");
173 return ret;
174 }
175
ProcInnerDash(int32_t streamID,uint64_t offset,std::shared_ptr<Buffer> & bufferPtr)176 Status StreamDemuxer::ProcInnerDash(int32_t streamID, uint64_t offset, std::shared_ptr<Buffer>& bufferPtr)
177 {
178 FALSE_RETURN_V_MSG_E(bufferPtr != nullptr, Status::ERROR_UNKNOWN, "bufferPtr invalid");
179 if (IsDash()) {
180 MEDIA_LOG_D("dash PullDataWithoutCache, cacheDataMap_ exist streamID , merge it.");
181 FALSE_RETURN_V_MSG_E(cacheDataMap_[streamID].GetData() != nullptr, Status::ERROR_UNKNOWN, "getdata invalid");
182 auto cacheMemory = cacheDataMap_[streamID].GetData()->GetMemory();
183 auto bufferMemory = bufferPtr->GetMemory();
184 FALSE_RETURN_V_MSG_E(bufferMemory != nullptr, Status::ERROR_UNKNOWN, "bufferPtr invalid");
185 FALSE_RETURN_V_MSG_E(cacheMemory != nullptr, Status::ERROR_UNKNOWN, "cacheMemory invalid");
186 std::shared_ptr<Buffer> mergedBuffer = Buffer::CreateDefaultBuffer(
187 bufferMemory->GetSize() + cacheMemory->GetSize());
188 FALSE_RETURN_V_MSG_E(mergedBuffer != nullptr, Status::ERROR_UNKNOWN, "mergedBuffer invalid");
189 auto mergeMemory = mergedBuffer->GetMemory();
190 FALSE_RETURN_V_MSG_E(mergeMemory != nullptr, Status::ERROR_UNKNOWN, "mergeMemory invalid");
191 MEDIA_LOG_I("dash PullDataWithoutCache merge before: cache offset: " PUBLIC_LOG_U64
192 ", cache size: " PUBLIC_LOG_ZU, cacheDataMap_[streamID].GetOffset(), cacheMemory->GetSize());
193 mergeMemory->Write(cacheMemory->GetReadOnlyData(), cacheMemory->GetSize(), 0);
194 mergeMemory->Write(bufferMemory->GetReadOnlyData(), bufferMemory->GetSize(), cacheMemory->GetSize());
195 cacheDataMap_[streamID].SetData(mergedBuffer);
196 MEDIA_LOG_I("dash PullDataWithoutCache merge after: " PUBLIC_LOG_U64 ", cache offset: " PUBLIC_LOG_U64,
197 offset, cacheDataMap_[streamID].GetOffset());
198 }
199 return Status::OK;
200 }
201
PullDataWithoutCache(int32_t streamID,uint64_t offset,size_t size,std::shared_ptr<Buffer> & bufferPtr)202 Status StreamDemuxer::PullDataWithoutCache(int32_t streamID, uint64_t offset, size_t size,
203 std::shared_ptr<Buffer>& bufferPtr)
204 {
205 Status ret = PullData(streamID, offset, size, bufferPtr);
206 if (ret != Status::OK) {
207 MEDIA_LOG_E("PullDataWithoutCache, PullData error " PUBLIC_LOG_D32, static_cast<int32_t>(ret));
208 return ret;
209 }
210 if (cacheDataMap_.find(streamID) != cacheDataMap_.end()) {
211 MEDIA_LOG_D("PullDataWithoutCache, cacheDataMap_ exist streamID , do nothing.");
212 ret = ProcInnerDash(streamID, offset, bufferPtr);
213 if (ret != Status::OK) {
214 MEDIA_LOG_E("ProcInnerDash error " PUBLIC_LOG_D32, static_cast<int32_t>(ret));
215 return ret;
216 }
217 } else {
218 CacheData cacheTmp;
219 cacheDataMap_[streamID] = cacheTmp;
220 }
221 if (cacheDataMap_[streamID].GetData() == nullptr || cacheDataMap_[streamID].GetData()->GetMemory() == nullptr) {
222 MEDIA_LOG_D("PullDataWithoutCache, write cache data.");
223 if (bufferPtr->GetMemory() == nullptr) {
224 MEDIA_LOG_W("PullDataWithoutCache, write cache data error. memory is nullptr!");
225 } else {
226 auto buffer = Buffer::CreateDefaultBuffer(bufferPtr->GetMemory()->GetSize());
227 if (buffer != nullptr && buffer->GetMemory() != nullptr) {
228 buffer->GetMemory()->Write(bufferPtr->GetMemory()->GetReadOnlyData(),
229 bufferPtr->GetMemory()->GetSize(), 0);
230 cacheDataMap_[streamID].Init(buffer, offset);
231 MEDIA_LOG_D("PullDataWithoutCache, write cache data success. offset=" PUBLIC_LOG_U64, offset);
232 } else {
233 MEDIA_LOG_W("PullDataWithoutCache, write cache data failed. memory is nullptr!");
234 }
235 }
236 }
237 return ret;
238 }
239
ReadRetry(int32_t streamID,uint64_t offset,size_t size,std::shared_ptr<Plugins::Buffer> & data)240 Status StreamDemuxer::ReadRetry(int32_t streamID, uint64_t offset, size_t size,
241 std::shared_ptr<Plugins::Buffer>& data)
242 {
243 FALSE_RETURN_V_MSG_E(data->GetMemory() != nullptr, Status::ERROR_UNKNOWN, "getmemory invalid");
244 Status err = Status::OK;
245 int32_t retryTimes = 0;
246 while (true && !isInterruptNeeded_.load()) {
247 err = source_->Read(streamID, data, offset, size);
248 if (IsDash() && streamID != data->streamID) {
249 break;
250 }
251 FALSE_RETURN_V_MSG_E(err != Status::ERROR_UNKNOWN, Status::ERROR_UNKNOWN, "error unknown");
252 if (err != Status::END_OF_STREAM && data->GetMemory()->GetSize() == 0) {
253 {
254 std::unique_lock<std::mutex> lock(mutex_);
255 readCond_.wait_for(lock, std::chrono::milliseconds(TRY_READ_SLEEP_TIME),
256 [&] { return isInterruptNeeded_.load(); });
257 }
258 retryTimes++;
259 if (retryTimes > TRY_READ_TIMES || isInterruptNeeded_.load()) {
260 break;
261 }
262 continue;
263 }
264 break;
265 }
266 FALSE_LOG_MSG(!isInterruptNeeded_.load(), "ReadRetry interrupted");
267 return err;
268 }
269
PullData(int32_t streamID,uint64_t offset,size_t size,std::shared_ptr<Plugins::Buffer> & data)270 Status StreamDemuxer::PullData(int32_t streamID, uint64_t offset, size_t size,
271 std::shared_ptr<Plugins::Buffer>& data)
272 {
273 MEDIA_LOG_DD("IN, offset: " PUBLIC_LOG_U64 ", size: " PUBLIC_LOG_ZU
274 ", position: " PUBLIC_LOG_U64, offset, size, position_);
275 if (!source_) {
276 return Status::ERROR_INVALID_OPERATION;
277 }
278 Status err;
279 auto readSize = size;
280 if (source_->IsSeekToTimeSupported() || source_->GetSeekable() == Plugins::Seekable::UNSEEKABLE) {
281 err = ReadRetry(streamID, offset, readSize, data);
282 FALSE_LOG_MSG(err == Status::OK, "hls, plugin read failed.");
283 return err;
284 }
285
286 uint64_t totalSize = 0;
287 if ((source_->GetSize(totalSize) == Status::OK) && (totalSize != 0)) {
288 if (offset >= totalSize) {
289 MEDIA_LOG_D("Offset: " PUBLIC_LOG_U64 " is larger than totalSize: " PUBLIC_LOG_U64, offset, totalSize);
290 return Status::END_OF_STREAM;
291 }
292 if ((offset + readSize) > totalSize) {
293 readSize = totalSize - offset;
294 }
295 if (data->GetMemory() != nullptr) {
296 auto realSize = data->GetMemory()->GetCapacity();
297 readSize = (readSize > realSize) ? realSize : readSize;
298 }
299 MEDIA_LOG_DD("TotalSize_: " PUBLIC_LOG_U64, totalSize);
300 }
301 if (position_ != offset) {
302 err = source_->SeekTo(offset);
303 FALSE_RETURN_V_MSG_E(err == Status::OK, err, "Seek to " PUBLIC_LOG_U64 " fail", offset);
304 position_ = offset;
305 }
306
307 err = ReadRetry(streamID, offset, readSize, data);
308 if (err == Status::OK) {
309 FALSE_RETURN_V_MSG_E(data->GetMemory() != nullptr, Status::ERROR_UNKNOWN, "data->GetMemory invalid");
310 position_ += data->GetMemory()->GetSize();
311 }
312 return err;
313 }
314
ResetCache(int32_t streamID)315 Status StreamDemuxer::ResetCache(int32_t streamID)
316 {
317 if (cacheDataMap_.find(streamID) != cacheDataMap_.end()) {
318 cacheDataMap_[streamID].Reset();
319 cacheDataMap_.erase(streamID);
320 }
321 return Status::OK;
322 }
323
ResetAllCache()324 Status StreamDemuxer::ResetAllCache()
325 {
326 for (auto& iter : cacheDataMap_) {
327 iter.second.Reset();
328 }
329 cacheDataMap_.clear();
330 return Status::OK;
331 }
332
Start()333 Status StreamDemuxer::Start()
334 {
335 return Status::OK;
336 }
337
338
Stop()339 Status StreamDemuxer::Stop()
340 {
341 return Status::OK;
342 }
343
344
Resume()345 Status StreamDemuxer::Resume()
346 {
347 return Status::OK;
348 }
349
350
Pause()351 Status StreamDemuxer::Pause()
352 {
353 return Status::OK;
354 }
355
Flush()356 Status StreamDemuxer::Flush()
357 {
358 return Status::OK;
359 }
360
HandleReadHeader(int32_t streamID,int64_t offset,std::shared_ptr<Buffer> & buffer,size_t expectedLen)361 Status StreamDemuxer::HandleReadHeader(int32_t streamID, int64_t offset, std::shared_ptr<Buffer>& buffer,
362 size_t expectedLen)
363 {
364 MEDIA_LOG_D("Demuxer parse DEMUXER_STATE_PARSE_HEADER, offset: " PUBLIC_LOG_D64
365 ", expectedLen: " PUBLIC_LOG_ZU, offset, expectedLen);
366 if (expectedLen == 0) {
367 return Status::END_OF_STREAM;
368 }
369 Status ret = getRange_(streamID, static_cast<uint64_t>(offset), expectedLen, buffer);
370 if (ret == Status::OK) {
371 DUMP_BUFFER2FILE(DEMUXER_INPUT_PEEK, buffer);
372 return ret;
373 }
374 // Under the current specifications, change buffer->streamID only in the scenario of switching tracks.
375 FALSE_RETURN_V_NOLOG(!IsDash() || buffer == nullptr || buffer->streamID == streamID, Status::END_OF_STREAM);
376
377 if (mediaDataSize_ == LIVE_CONTENT_LENGTH) {
378 return Status::OK;
379 }
380 MEDIA_LOG_W("Demuxer parse DEMUXER_STATE_PARSE_HEADER, getRange_ failed, ret = " PUBLIC_LOG_D32, ret);
381 return ret;
382 }
383
CheckChangeStreamID(int32_t streamID,std::shared_ptr<Buffer> & buffer)384 Status StreamDemuxer::CheckChangeStreamID(int32_t streamID, std::shared_ptr<Buffer>& buffer)
385 {
386 if (IsDash()) {
387 if (buffer != nullptr && buffer->streamID != streamID) {
388 if (GetNewVideoStreamID() == streamID) {
389 SetNewVideoStreamID(buffer->streamID);
390 } else if (GetNewAudioStreamID() == streamID) {
391 SetNewAudioStreamID(buffer->streamID);
392 } else if (GetNewSubtitleStreamID() == streamID) {
393 SetNewSubtitleStreamID(buffer->streamID);
394 } else {}
395 MEDIA_LOG_I("Demuxer parse dash change, oldStreamID = " PUBLIC_LOG_D32
396 ", newStreamID = " PUBLIC_LOG_D32, streamID, buffer->streamID);
397 return Status::END_OF_STREAM;
398 }
399 }
400 return Status::OK;
401 }
402
HandleReadPacket(int32_t streamID,int64_t offset,std::shared_ptr<Buffer> & buffer,size_t expectedLen)403 Status StreamDemuxer::HandleReadPacket(int32_t streamID, int64_t offset, std::shared_ptr<Buffer>& buffer,
404 size_t expectedLen)
405 {
406 MEDIA_LOG_D("Demuxer parse DEMUXER_STATE_PARSE_FRAME");
407 Status ret = getRange_(streamID, static_cast<uint64_t>(offset), expectedLen, buffer);
408 if (ret == Status::OK) {
409 DUMP_BUFFER2LOG("Demuxer GetRange", buffer, offset);
410 DUMP_BUFFER2FILE(DEMUXER_INPUT_GET, buffer);
411 if (buffer != nullptr && buffer->GetMemory() != nullptr &&
412 buffer->GetMemory()->GetSize() == 0) {
413 MEDIA_LOG_I("Demuxer parse DEMUXER_STATE_PARSE_FRAME in pausing(isIgnoreParse),"
414 " Read fail and try again");
415 return Status::ERROR_AGAIN;
416 }
417 return ret;
418 }
419 MEDIA_LOG_W("Demuxer parse DEMUXER_STATE_PARSE_FRAME, getRange_ failed, ret = " PUBLIC_LOG_D32, ret);
420 return ret;
421 }
422
CallbackReadAt(int32_t streamID,int64_t offset,std::shared_ptr<Buffer> & buffer,size_t expectedLen)423 Status StreamDemuxer::CallbackReadAt(int32_t streamID, int64_t offset, std::shared_ptr<Buffer>& buffer,
424 size_t expectedLen)
425 {
426 FALSE_RETURN_V(!isInterruptNeeded_.load(), Status::ERROR_WRONG_STATE);
427 switch (pluginStateMap_[streamID]) {
428 case DemuxerState::DEMUXER_STATE_NULL:
429 return Status::ERROR_WRONG_STATE;
430 case DemuxerState::DEMUXER_STATE_PARSE_HEADER: {
431 auto ret = HandleReadHeader(streamID, offset, buffer, expectedLen);
432 if (ret != Status::OK) {
433 return ret;
434 }
435 break;
436 }
437 case DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME:
438 case DemuxerState::DEMUXER_STATE_PARSE_FRAME: {
439 auto ret = HandleReadPacket(streamID, offset, buffer, expectedLen);
440 if (ret == Status::END_OF_STREAM &&
441 pluginStateMap_[streamID] == DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME) {
442 SetDemuxerState(streamID, DemuxerState::DEMUXER_STATE_PARSE_FRAME);
443 return ret;
444 }
445 if (ret != Status::OK) {
446 return ret;
447 }
448 if (pluginStateMap_[streamID] == DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME) {
449 SetDemuxerState(streamID, DemuxerState::DEMUXER_STATE_PARSE_FRAME);
450 }
451 break;
452 }
453 default:
454 break;
455 }
456 return Status::OK;
457 }
458
SetInterruptState(bool isInterruptNeeded)459 void StreamDemuxer::SetInterruptState(bool isInterruptNeeded)
460 {
461 MEDIA_LOG_I("StreamDemuxer OnInterrupted %{public}d", isInterruptNeeded);
462 {
463 std::unique_lock<std::mutex> lock(mutex_);
464 isInterruptNeeded_ = isInterruptNeeded;
465 readCond_.notify_all();
466 }
467 TypeFinderInterrupt(isInterruptNeeded);
468 }
469 } // namespace Media
470 } // namespace OHOS
471