• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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