Skip to content

Commit fbf2715

Browse files
authored
Fix HarmonyOS decoding error and temporarily increased frame wait limit to 16. (#2743)
1 parent 4fe4f97 commit fbf2715

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

src/platform/ohos/NativeDisplayLink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#pragma once
2020
#include <native_vsync/native_vsync.h>
21+
#include <cstdint>
2122
#include <functional>
2223
#include <mutex>
2324
#include "rendering/utils/DisplayLink.h"

src/platform/ohos/OHOSVideoDecoder.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ OHOSVideoDecoder::~OHOSVideoDecoder() {
100100
}
101101
}
102102
if (videoCodec != nullptr) {
103+
releaseOutputBuffer();
103104
OH_VideoDecoder_Flush(videoCodec);
104105
OH_VideoDecoder_Stop(videoCodec);
105106
OH_VideoDecoder_Destroy(videoCodec);
@@ -133,7 +134,6 @@ bool OHOSVideoDecoder::initDecoder(const OH_AVCodecCategory avCodecCategory) {
133134
OH_AVFormat* ohFormat = OH_AVFormat_Create();
134135
OH_AVFormat_SetIntValue(ohFormat, OH_MD_KEY_WIDTH, videoFormat.width);
135136
OH_AVFormat_SetIntValue(ohFormat, OH_MD_KEY_HEIGHT, videoFormat.height);
136-
OH_AVFormat_SetIntValue(ohFormat, OH_MD_KEY_VIDEO_ENABLE_LOW_LATENCY, 1);
137137
OH_AVFormat_SetIntValue(ohFormat, OH_MD_KEY_PIXEL_FORMAT, AV_PIXEL_FORMAT_NV12);
138138
ret = OH_VideoDecoder_Configure(videoCodec, ohFormat);
139139
OH_AVFormat_Destroy(ohFormat);
@@ -194,19 +194,21 @@ DecodingResult OHOSVideoDecoder::onEndOfStream() {
194194
}
195195

196196
DecodingResult OHOSVideoDecoder::onDecodeFrame() {
197+
releaseOutputBuffer();
197198
std::unique_lock<std::mutex> lock(codecUserData->outputMutex);
198199
codecUserData->outputCondition.wait(lock, [this]() {
199-
// In the PAG file, video sequence frame software decoding testing requires sending additional
200-
// data before obtaining the decoded data. If compatibility with user video decoding is desired,
201-
// retesting is necessary.
202-
return codecUserData->outputBufferInfoQueue.size() > 0 ||
203-
pendingFrames.size() <= static_cast<size_t>(videoFormat.maxReorderSize) +
204-
(codecCategory == SOFTWARE ? 1 : 0);
200+
/**
201+
* According to HarmonyOS recommendations, temporarily modify the maximum frame delivery count to 16 to avoid
202+
* freezing issues caused by the lack of decoded data on certain HarmonyOS devices. However, this change will
203+
* result in increased memory usage. Once HarmonyOS are improved, appropriate adjustments will be made here.
204+
*/
205+
return codecUserData->outputBufferInfoQueue.size() > 0 || pendingFrames.size() <= 16;
205206
});
206207
if (codecUserData->outputBufferInfoQueue.size() > 0) {
207208
codecBufferInfo = codecUserData->outputBufferInfoQueue.front();
208209
codecUserData->outputBufferInfoQueue.pop();
209210
lock.unlock();
211+
lastOutputBufferIndex = codecBufferInfo.bufferIndex;
210212
pendingFrames.remove(codecBufferInfo.attr.pts);
211213
if (codecBufferInfo.buffer == nullptr) {
212214
return DecodingResult::Error;
@@ -215,11 +217,6 @@ DecodingResult OHOSVideoDecoder::onDecodeFrame() {
215217
lock.unlock();
216218
return DecodingResult::Success;
217219
}
218-
int ret = OH_VideoDecoder_FreeOutputBuffer(videoCodec, codecBufferInfo.bufferIndex);
219-
if (ret != AV_ERR_OK) {
220-
LOGE("OH_VideoDecoder_FreeOutputBuffer failed, ret:%d", ret);
221-
return DecodingResult::Error;
222-
}
223220
if (codecBufferInfo.attr.flags == AVCODEC_BUFFER_FLAGS_EOS) {
224221
return DecodingResult::EndOfStream;
225222
}
@@ -233,6 +230,7 @@ void OHOSVideoDecoder::onFlush() {
233230
}
234231
codecUserData->clearQueue();
235232
pendingFrames.clear();
233+
lastOutputBufferIndex = -1;
236234
codecBufferInfo = {0, nullptr};
237235
start();
238236
}
@@ -310,4 +308,14 @@ std::shared_ptr<tgfx::ImageBuffer> OHOSVideoDecoder::onRenderFrame() {
310308
return imageBuffer;
311309
}
312310

311+
void OHOSVideoDecoder::releaseOutputBuffer() {
312+
if (lastOutputBufferIndex != -1) {
313+
int ret = OH_VideoDecoder_FreeOutputBuffer(videoCodec, codecBufferInfo.bufferIndex);
314+
if (ret != AV_ERR_OK) {
315+
LOGE("OH_VideoDecoder_FreeOutputBuffer failed, ret:%d", ret);
316+
}
317+
lastOutputBufferIndex = -1;
318+
}
319+
}
320+
313321
} // namespace pag

src/platform/ohos/OHOSVideoDecoder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,11 @@ class OHOSVideoDecoder : public VideoDecoder {
9797
int64_t yBufferSize = 0;
9898
int64_t uvBufferSize = 0;
9999
std::weak_ptr<OHOSVideoDecoder> weakThis;
100+
int lastOutputBufferIndex = -1;
100101

101102
explicit OHOSVideoDecoder(const VideoFormat& format, bool hardware);
102103
bool initDecoder(const OH_AVCodecCategory avCodecCategory);
103104
bool start();
105+
void releaseOutputBuffer();
104106
};
105107
} // namespace pag

0 commit comments

Comments
 (0)