@@ -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
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 ();
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
0 commit comments