• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 <cinttypes>
17 #include <cstdio>
18 #include <fcntl.h>
19 #include <iostream>
20 #include <malloc.h>
21 #include <string>
22 #include <thread>
23 #include <sys/stat.h>
24 #include <fstream>
25 #include <ctime>
26 #include "native_avbuffer.h"
27 #include "inner_demuxer_sample.h"
28 #include "native_avcodec_base.h"
29 #include "meta/format.h"
30 #include "avcodec_errors.h"
31 #include "avcodec_common.h"
32 #include "native_avformat.h"
33 #include "av_common.h"
34 #include <random>
35 #include "avmuxer.h"
36 #include "media_description.h"
37 
38 using namespace std;
39 using namespace OHOS::MediaAVCodec;
40 using namespace OHOS::Media;
41 namespace OHOS {
42 namespace MediaAVCodec {
InnerDemuxerSample()43 InnerDemuxerSample::InnerDemuxerSample()
44 {
45 }
46 
~InnerDemuxerSample()47 InnerDemuxerSample::~InnerDemuxerSample()
48 {
49     if (fd > 0) {
50         close(fd);
51         fd = 0;
52     }
53 }
54 
CreateBuffer()55 bool InnerDemuxerSample::CreateBuffer()
56 {
57     uint32_t buffersize = 1024 * 1024;
58     std::shared_ptr<AVAllocator> allocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
59     avBuffer = OHOS::Media::AVBuffer::CreateAVBuffer(allocator, buffersize);
60     if (!avBuffer) {
61         return false;
62     }
63     return true;
64 }
InitWithFile(const std::string & path,bool local)65 int32_t InnerDemuxerSample::InitWithFile(const std::string &path, bool local)
66 {
67     if (local) {
68         fd = open(path.c_str(), O_RDONLY);
69         int64_t size = GetFileSize(path);
70         this->avsource_ = AVSourceFactory::CreateWithFD(fd, 0, size);
71     } else {
72         this->avsource_ = AVSourceFactory::CreateWithURI(const_cast<char*>(path.data()));
73     }
74     if (!avsource_) {
75         printf("Source is null\n");
76         return -1;
77     }
78     this->demuxer_ = AVDemuxerFactory::CreateWithSource(avsource_);
79     if (!demuxer_) {
80         printf("AVDemuxerFactory::CreateWithSource is failed\n");
81         return -1;
82     }
83     int32_t ret = this->avsource_->GetSourceFormat(source_format_);
84     if (ret != 0) {
85         printf("GetSourceFormat is failed\n");
86         return ret;
87     }
88     source_format_.GetIntValue(OH_MD_KEY_TRACK_COUNT, trackCount);
89     source_format_.GetLongValue(OH_MD_KEY_DURATION, duration);
90     printf("====>total tracks:%d duration:%" PRId64 "\n", trackCount, duration);
91     int32_t trackType = 0;
92     for (int32_t i = 0; i < trackCount; i++) {
93         ret = this->avsource_->GetTrackFormat(track_format_, i);
94         if (ret != 0) {
95             printf("GetTrackFormat is failed\n");
96             return ret;
97         }
98         track_format_.GetIntValue(OH_MD_KEY_TRACK_TYPE, trackType);
99         if (trackType == MEDIA_TYPE_VID) {
100             videoTrackIdx = i;
101         }
102         if (unSelectTrack != i) {
103             ret = this->demuxer_->SelectTrackByID(i);
104             if (ret != 0) {
105                 printf("SelectTrackByID is failed\n");
106                 return ret;
107             }
108         }
109     }
110     return ret;
111 }
112 
ReadSampleAndSave()113 int32_t InnerDemuxerSample::ReadSampleAndSave()
114 {
115     uint32_t buffersize = 1024 * 1024;
116     std::shared_ptr<AVAllocator> allocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
117     avBuffer = OHOS::Media::AVBuffer::CreateAVBuffer(allocator, buffersize);
118     while (!isAudioEosFlagForSave && !isVideoEosFlagForSave) {
119         CheckLoopForSave();
120     }
121     videoIndexPtsList.sort();
122     audioIndexPtsList.sort();
123     return retForSave;
124 }
125 
CheckLoopForSave()126 void InnerDemuxerSample::CheckLoopForSave()
127 {
128     for (int32_t i = 0; i < trackCount; i++) {
129         retForSave = this->demuxer_->ReadSampleBuffer(i, avBuffer);
130         if (retForSave != 0) {
131             cout << "ReadSampleBuffer fail ret:" << retForSave << endl;
132             isVideoEosFlagForSave = true;
133             isAudioEosFlagForSave = true;
134             break;
135         }
136         if (avBuffer->flag_ == AVCODEC_BUFFER_FLAG_EOS) {
137             if (i == videoTrackIdx) {
138                 isVideoEosFlagForSave = true;
139             } else {
140                 isAudioEosFlagForSave = true;
141             }
142             continue;
143         }
144         if (i == videoTrackIdx) {
145             videoIndexPtsList.push_back(avBuffer->pts_);
146             videoIndexForRead ++;
147             if (videoIndexForRead == 1) {
148                 videoPtsOffset = avBuffer->pts_;
149             }
150         } else {
151             audioIndexPtsList.push_back(avBuffer->pts_);
152             audioIndexForRead ++;
153             if (audioIndexForRead == 1) {
154                 audioPtsOffset = avBuffer->pts_;
155             }
156         }
157     }
158 }
159 
CheckPtsFromIndex()160 int32_t InnerDemuxerSample::CheckPtsFromIndex()
161 {
162     int32_t num = 999;
163     for (int32_t i = 0; i < trackCount; i++) {
164         if (retForPts == num) {
165             break;
166         }
167         indexForPts = 0;
168         CheckLoopForPtsFromIndex(i);
169     }
170     cout << "CheckPtsFromIndex ret:" << retForPts << endl;
171     return retForPts;
172 }
173 
CheckIndexFromPts()174 int32_t InnerDemuxerSample::CheckIndexFromPts()
175 {
176     int32_t num = 999;
177     for (int32_t i = 0; i < trackCount; i++) {
178         if (retForIndex == num) {
179             break;
180         }
181         listIndex = 0;
182         previousValue = 0;
183         CheckLoopForIndexFromPts(i);
184     }
185     cout << "CheckIndexFromPts ret:" << retForIndex << endl;
186     return retForIndex;
187 }
188 
CheckLoopForPtsFromIndex(int32_t trackIndex)189 void InnerDemuxerSample::CheckLoopForPtsFromIndex(int32_t trackIndex)
190 {
191     uint64_t presentationTimeUs = 0;
192     int32_t num = 999;
193     if (trackIndex == videoTrackIdx) {
194         for (const auto &pair : videoIndexPtsList) {
195             retForPts = demuxer_->GetRelativePresentationTimeUsByIndex(trackIndex, indexForPts, presentationTimeUs);
196             if (retForPts != 0) {
197                 cout << "GetRelativePresentationTimeUsByIndex fail ret:" << retForPts << endl;
198                 break;
199             }
200             if (!((pair - videoPtsOffset - 1) <= presentationTimeUs <= (pair - videoPtsOffset + 1))) {
201                 retForPts = num;
202                 break;
203             }
204             indexForPts ++;
205         }
206     } else {
207         for (const auto &pair : audioIndexPtsList) {
208             retForPts = demuxer_->GetRelativePresentationTimeUsByIndex(trackIndex, indexForPts, presentationTimeUs);
209             if (retForPts != 0) {
210                 cout << "GetRelativePresentationTimeUsByIndex fail ret:" << retForPts << endl;
211                 break;
212             }
213             if (!((pair - audioPtsOffset - 1) <= presentationTimeUs <= (pair - audioPtsOffset + 1))) {
214                 retForPts = num;
215                 break;
216             }
217             indexForPts ++;
218         }
219     }
220 }
CheckLoopForIndexFromPts(int32_t trackIndex)221 void InnerDemuxerSample::CheckLoopForIndexFromPts(int32_t trackIndex)
222 {
223     if (trackIndex == videoTrackIdx) {
224         GetIndexByPtsForVideo(trackIndex);
225     } else {
226         GetIndexByPtsForAudio(trackIndex);
227     }
228 }
229 
GetIndexByPtsForVideo(int32_t trackIndex)230 void InnerDemuxerSample::GetIndexByPtsForVideo(int32_t trackIndex)
231 {
232     int division = 2;
233     int value = 1;
234     for (const auto &pair : videoIndexPtsList) {
235         uint64_t tempValue = pair;
236         uint64_t relativePresentationTimeUs = static_cast<uint64_t>(pair - videoPtsOffset);
237         GetIndexFromPtsForVideo(trackIndex, relativePresentationTimeUs, pair, division, value);
238         if (retForIndex != 0) {
239             cout << "video GetIndexByRelativePresentationTimeUs fail ret:" << retForIndex << endl;
240             break;
241         }
242         retForIndex = CheckIndex(indexVideo);
243         if (retForIndex != 0) {
244             break;
245         }
246         previousValue = tempValue;
247         listIndex ++;
248     }
249 }
250 
GetIndexByPtsForAudio(int32_t trackIndex)251 void InnerDemuxerSample::GetIndexByPtsForAudio(int32_t trackIndex)
252 {
253     int division = 2;
254     int value = 1;
255     for (const auto &pair : audioIndexPtsList) {
256         uint64_t tempValue = pair;
257         uint64_t relativePresentationTimeUs = static_cast<uint64_t>(pair - audioPtsOffset);
258         GetIndexFromPtsForAudio(trackIndex, relativePresentationTimeUs, pair, division, value);
259         if (retForIndex != 0) {
260             cout << "audio GetIndexByRelativePresentationTimeUs fail ret:" << retForIndex << endl;
261             break;
262         }
263         retForIndex = CheckIndex(indexAudio);
264         if (retForIndex != 0) {
265             break;
266         }
267 
268         previousValue = tempValue;
269         listIndex ++;
270     }
271 }
272 
GetIndexFromPtsForVideo(int32_t trackIndex,uint64_t relativePresentationTimeUs,int64_t pair,int division,int value)273 void InnerDemuxerSample::GetIndexFromPtsForVideo(int32_t trackIndex,
274     uint64_t relativePresentationTimeUs, int64_t pair, int division, int value)
275 {
276     if (isPtsExist && listIndex != 0) {
277         if (isPtsCloseLeft) {
278             if (division != 0) {
279                 retForIndex = demuxer_->GetIndexByRelativePresentationTimeUs(trackIndex,
280                     relativePresentationTimeUs - ((pair - previousValue) / division + value), indexVideo);
281             }
282         } else if (isPtsCloseCenter) {
283             if (division != 0) {
284                 retForIndex = demuxer_->GetIndexByRelativePresentationTimeUs(trackIndex,
285                     relativePresentationTimeUs - ((pair - previousValue) / division), indexVideo);
286             }
287         } else {
288             if (division != 0) {
289                 retForIndex = demuxer_->GetIndexByRelativePresentationTimeUs(trackIndex,
290                     relativePresentationTimeUs - ((pair - previousValue) / division - value), indexVideo);
291             }
292         }
293     } else {
294         retForIndex = demuxer_->GetIndexByRelativePresentationTimeUs(trackIndex,
295             relativePresentationTimeUs, indexVideo);
296     }
297 }
298 
GetIndexFromPtsForAudio(int32_t trackIndex,uint64_t relativePresentationTimeUs,int64_t pair,int division,int value)299 void InnerDemuxerSample::GetIndexFromPtsForAudio(int32_t trackIndex,
300     uint64_t relativePresentationTimeUs, int64_t pair, int division, int value)
301 {
302     if (isPtsExist && listIndex != 0) {
303         if (isPtsCloseLeft) {
304             if (division != 0) {
305                 retForIndex = demuxer_->GetIndexByRelativePresentationTimeUs(trackIndex,
306                     relativePresentationTimeUs - ((pair - previousValue) / division + value), indexAudio);
307             }
308         } else if (isPtsCloseCenter) {
309             if (division != 0) {
310                 retForIndex = demuxer_->GetIndexByRelativePresentationTimeUs(trackIndex,
311                     relativePresentationTimeUs - ((pair - previousValue) / division), indexAudio);
312             }
313         } else {
314             if (division != 0) {
315                 retForIndex = demuxer_->GetIndexByRelativePresentationTimeUs(trackIndex,
316                     relativePresentationTimeUs - ((pair - previousValue) / division - value), indexAudio);
317             }
318         }
319     } else {
320         retForIndex = demuxer_->GetIndexByRelativePresentationTimeUs(trackIndex,
321             relativePresentationTimeUs, indexAudio);
322     }
323 }
324 
CheckIndex(uint32_t index)325 int32_t InnerDemuxerSample::CheckIndex(uint32_t index)
326 {
327     int32_t num = 999;
328     if (isPtsExist) {
329         if (isPtsCloseLeft && listIndex != 0) {
330             if (index != (listIndex -1)) {
331                 retForIndex = num;
332                 cout << "pts != pair  index:" << index << " listIndex - 1 :"<< (listIndex - 1) << endl;
333             }
334         } else if (isPtsCloseCenter && listIndex != 0) {
335             if (index != listIndex && index != (listIndex - 1)) {
336                 retForIndex = num;
337                 cout << "pts != pair index:" << index << " listIndex - 1 :"<< (listIndex - 1) << endl;
338             }
339         } else {
340             if (index != listIndex) {
341                 retForIndex = num;
342                 cout << "pts != pair  index:" << index << " listIndex:"<< listIndex << endl;
343             }
344         }
345     } else {
346         if (index != listIndex) {
347             retForIndex = num;
348             cout << "pts != pair  index:" << index << " listIndex:"<< listIndex << endl;
349         }
350     }
351     return retForIndex;
352 }
CheckHasTimedMeta()353 int32_t InnerDemuxerSample::CheckHasTimedMeta()
354 {
355     int32_t hasMeta = 0;
356     source_format_.GetIntValue(AVSourceFormat::SOURCE_HAS_TIMEDMETA, hasMeta);
357     return hasMeta;
358 }
359 
CheckTimedMetaFormat(int32_t trackIndex,int32_t srcTrackIndex)360 int32_t InnerDemuxerSample::CheckTimedMetaFormat(int32_t trackIndex, int32_t srcTrackIndex)
361 {
362     int32_t ret = this->avsource_->GetTrackFormat(track_format_, trackIndex);
363     if (ret != 0) {
364         cout << "get track_format_ fail" << endl;
365         return -1;
366     }
367     int32_t trackType = 0;
368     std::string codecMime = "";
369     std::string timedMetadataKey = "";
370     int32_t srcTrackID = -1;
371     std::string TIMED_METADATA_KEY = "com.openharmony.timed_metadata.test";
372     track_format_.GetIntValue(MediaDescriptionKey::MD_KEY_TRACK_TYPE, trackType);
373     if (trackType != MediaType::MEDIA_TYPE_TIMED_METADATA) {
374         cout << "check MD_KEY_TRACK_TYPE fail" << endl;
375         return -1;
376     }
377     track_format_.GetStringValue(MediaDescriptionKey::MD_KEY_CODEC_MIME, codecMime);
378     if (codecMime != "meta/timed-metadata") {
379         cout << "check codecMime fail" << endl;
380         return -1;
381     }
382     track_format_.GetStringValue(MediaDescriptionKey::MD_KEY_TIMED_METADATA_KEY, timedMetadataKey);
383     if (timedMetadataKey != TIMED_METADATA_KEY) {
384         cout << "check MD_KEY_TIMED_METADATA_KEY fail" << endl;
385         return -1;
386     }
387     track_format_.GetIntValue(MediaDescriptionKey::MD_KEY_TIMED_METADATA_SRC_TRACK_ID, srcTrackID);
388     if (srcTrackID != srcTrackIndex) {
389         cout << "check MD_KEY_TIMED_METADATA_SRC_TRACK_ID fail" << endl;
390         return -1;
391     }
392     return 0;
393 }
394 
CheckTimedMeta(int32_t metaTrack)395 int32_t InnerDemuxerSample::CheckTimedMeta(int32_t metaTrack)
396 {
397     uint32_t buffersize = 1024 * 1024;
398     std::shared_ptr<AVAllocator> allocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
399     avBuffer = OHOS::Media::AVBuffer::CreateAVBuffer(allocator, buffersize);
400     uint32_t twoHundredAndTen = 210;
401     while (!isVideoEosFlagForMeta && !isMetaEosFlagForMeta && retForMeta == 0) {
402         CheckLoop(metaTrack);
403     }
404     if (videoIndexForMeta != twoHundredAndTen || metaIndexForMeta != twoHundredAndTen) {
405         retForMeta = -1;
406     }
407     return retForMeta;
408 }
409 
CheckLoop(int32_t metaTrack)410 void InnerDemuxerSample::CheckLoop(int32_t metaTrack)
411 {
412     int32_t compaseSize = 0;
413     int32_t metaSize = 0;
414     for (int32_t i = 0; i < trackCount; i++) {
415         retForMeta = this->demuxer_->ReadSampleBuffer(i, avBuffer);
416         if (retForMeta != 0) {
417             isVideoEosFlagForMeta = true;
418             isMetaEosFlagForMeta = true;
419             break;
420         }
421         if (avBuffer->flag_ == AVCODEC_BUFFER_FLAG_EOS) {
422             if (i == videoTrackIdx) {
423                 isVideoEosFlagForMeta = true;
424             } else if (i == metaTrack) {
425                 isMetaEosFlagForMeta = true;
426             }
427             continue;
428         }
429         if (i == videoTrackIdx) {
430             compaseSize = static_cast<int32_t>(avBuffer->memory_->GetSize());
431             if (metaTrack == 0 && metaSize != compaseSize - 1) {
432                     retForMeta = -1;
433                     break;
434             }
435             videoIndexForMeta ++;
436         } else if (i == metaTrack) {
437             metaSize = static_cast<int32_t>(avBuffer->memory_->GetSize());
438             if (metaTrack != 0 && metaSize != compaseSize - 1) {
439                 retForMeta = -1;
440                 break;
441             }
442             metaIndexForMeta ++;
443         }
444     }
445 }
446 
GetFileSize(const std::string & filePath)447 size_t InnerDemuxerSample::GetFileSize(const std::string& filePath)
448 {
449     size_t fileSize = 0;
450     if (!filePath.empty()) {
451         struct stat fileStatus {};
452         if (stat(filePath.c_str(), &fileStatus) == 0) {
453             fileSize = static_cast<size_t>(fileStatus.st_size);
454         }
455     }
456     return fileSize;
457 }
458 
CheckDemuxer(int32_t & readMax)459 bool InnerDemuxerSample::CheckDemuxer(int32_t &readMax)
460 {
461     for (int32_t i = 0; i < trackCount; i++) {
462         int32_t ret = this->demuxer_->SelectTrackByID(i);
463         if (ret != 0) {
464             printf("SelectTrackByID is failed\n");
465             return false;
466         }
467         ret = this->demuxer_->ReadSampleBuffer(i, avBuffer);
468         if (ret != 0) {
469             cout << "ReadSampleBuffer fail ret:" << ret << endl;
470             isAudioEosFlagForSave = true;
471             return false;
472         }
473         if (avBuffer->flag_ == AVCODEC_BUFFER_FLAG_EOS) {
474             printf("ReadSampleBuffer EOS\n");
475             isAudioEosFlagForSave = true;
476             continue;
477         }
478         if (avBuffer->memory_->GetSize() > readMax) {
479             readMax = avBuffer->memory_->GetSize();
480         }
481     }
482     return true;
483 }
484 
CheckApeSourceData(const std::string & path,int32_t version)485 bool InnerDemuxerSample::CheckApeSourceData(const std::string &path, int32_t version)
486 {
487     fd = open(path.c_str(), O_RDONLY);
488     int64_t size = GetFileSize(path);
489     this->avsource_ = AVSourceFactory::CreateWithFD(fd, 0, size);
490     if (!avsource_) {
491         printf("Source is null\n");
492         return false;
493     }
494     this->demuxer_ = AVDemuxerFactory::CreateWithSource(avsource_);
495     if (!demuxer_) {
496         printf("AVDemuxerFactory::CreateWithSource is failed\n");
497         return false;
498     }
499     int32_t ret = this->avsource_->GetSourceFormat(source_format_);
500     if (ret != 0) {
501         return false;
502     }
503     source_format_.GetIntValue(OH_MD_KEY_TRACK_COUNT, trackCount);
504     uint32_t buffersize = 2048 * 2048;
505     std::shared_ptr<AVAllocator> allocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
506     avBuffer = OHOS::Media::AVBuffer::CreateAVBuffer(allocator, buffersize);
507     int32_t trackType = 0;
508     int32_t readSize = 0;
509     int32_t frame = 0;
510     int32_t sizeMax = 0;
511     ret = this->avsource_->GetTrackFormat(track_format_, 0);
512     if (ret != 0) {
513         return false;
514     }
515     track_format_.GetIntValue(Media::Tag::AUDIO_SAMPLE_PER_FRAME, frame);
516     track_format_.GetIntValue(Media::Tag::AUDIO_MAX_INPUT_SIZE, sizeMax);
517     track_format_.GetIntValue(OH_MD_KEY_TRACK_TYPE, trackType);
518     if (trackType != MEDIA_TYPE_AUD) {
519         return false;
520     }
521     while (!isAudioEosFlagForSave) {
522         if (!CheckDemuxer(readSize)) {
523             return false;
524         }
525     }
526     if (frame != version) {
527         printf("frame not as expected\n");
528         return false;
529     }
530     if (sizeMax != readSize) {
531         printf("sizeMax = %d not as expected\n", sizeMax);
532         return false;
533     }
534     return true;
535 }
536 
CheckCache(std::vector<std::vector<int32_t>> & cacheCheckSteps,int32_t times)537 bool InnerDemuxerSample::CheckCache(std::vector<std::vector<int32_t>> &cacheCheckSteps, int32_t times)
538 {
539     uint32_t memoryUsage = 0;
540     for (auto step : cacheCheckSteps) {
541         demuxer_->GetCurrentCacheSize(step[0], memoryUsage);
542         if (memoryUsage != step[times]) {
543             return false;
544         }
545     }
546     return true;
547 }
ReadVideo(std::vector<std::vector<int32_t>> & cacheCheckSteps)548 bool InnerDemuxerSample::ReadVideo(std::vector<std::vector<int32_t>> &cacheCheckSteps)
549 {
550     int32_t readCount = 0;
551     int32_t ret = 0;
552     int32_t checkVector1 = 1;
553     int32_t checkVector2 = 2;
554     bool isEnd = true;
555     while (isEnd) {
556         if (readCount >= readPos) {
557             isEnd = false;
558             if (!CheckCache(cacheCheckSteps, checkVector1)) {
559                 return false;
560             }
561             ret = demuxer_->ReadSampleBuffer(indexAud, avBuffer);
562             if (ret != 0) {
563                 cout << "ReadSampleBuffer fail ret:" << ret << endl;
564                 return false;
565             }
566             if (!CheckCache(cacheCheckSteps, checkVector2)) {
567                 return false;
568             }
569             break;
570         } else {
571             readCount++;
572             ret = demuxer_->ReadSampleBuffer(indexVid, avBuffer);
573             if (ret != 0) {
574                 cout << "ReadSampleBuffer fail ret:" << ret << endl;
575                 isEnd = false;
576                 return false;
577             }
578         }
579     }
580     return true;
581 }
582 
ReadAudio(std::vector<std::vector<int32_t>> & cacheCheckSteps)583 bool InnerDemuxerSample::ReadAudio(std::vector<std::vector<int32_t>> &cacheCheckSteps)
584 {
585     int32_t readCount = 0;
586     int32_t ret = 0;
587     int32_t checkVector1 = 1;
588     int32_t checkVector2 = 2;
589     bool isEnd = true;
590     while (isEnd) {
591         if (readCount >= readPos) {
592             isEnd = false;
593             if (!CheckCache(cacheCheckSteps, checkVector1)) {
594                 return false;
595             }
596             ret = demuxer_->ReadSampleBuffer(indexVid, avBuffer);
597             if (ret != 0) {
598                 cout << "ReadSampleBuffer fail ret:" << ret << endl;
599                 return false;
600             }
601             if (!CheckCache(cacheCheckSteps, checkVector2)) {
602                 return false;
603             }
604             break;
605         } else {
606             readCount++;
607             ret = demuxer_->ReadSampleBuffer(indexAud, avBuffer);
608             if (ret != 0) {
609                 cout << "ReadSampleBuffer fail ret:" << ret << endl;
610                 isEnd = false;
611                 return false;
612             }
613         }
614     }
615     return true;
616 }
617 }
618 }