@@ -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,14 +194,15 @@ DecodingResult OHOSVideoDecoder::onEndOfStream() {
194194}
195195
196196DecodingResult 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 ();
@@ -215,11 +216,6 @@ DecodingResult OHOSVideoDecoder::onDecodeFrame() {
215216 lock.unlock ();
216217 return DecodingResult::Success;
217218 }
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- }
223219 if (codecBufferInfo.attr .flags == AVCODEC_BUFFER_FLAGS_EOS) {
224220 return DecodingResult::EndOfStream;
225221 }
@@ -310,4 +306,14 @@ std::shared_ptr<tgfx::ImageBuffer> OHOSVideoDecoder::onRenderFrame() {
310306 return imageBuffer;
311307}
312308
309+ void OHOSVideoDecoder::releaseOutputBuffer () {
310+ if (codecBufferInfo.buffer ) {
311+ int ret = OH_VideoDecoder_FreeOutputBuffer (videoCodec, codecBufferInfo.bufferIndex );
312+ if (ret != AV_ERR_OK) {
313+ LOGE (" OH_VideoDecoder_FreeOutputBuffer failed, ret:%d" , ret);
314+ }
315+ codecBufferInfo = {0 , nullptr };
316+ }
317+ }
318+
313319} // namespace pag
0 commit comments