HarmonyOS 6.0 AVCodec Kit Video Decoder Smooth Shutdown: Blank Frame Output in Surface Mode

HarmonyOS 6.0 introduces a smooth shutdown mechanism for AVCodec Kit video decoders: before Stop or Destroy, the decoder outputs a blank black frame to the Surface, eliminating last-frame residue, flicker, and abrupt transitions. Keywords: HarmonyOS 6.0, AVCodec Kit, video decoding.

The technical specification snapshot summarizes the feature at a glance

Parameter Description
Platform HarmonyOS 6.0+
API Level 20 and later
Language C / C++
Core Module AVCodec Kit
Output Mode Effective only in Surface mode
Control Key OH_MD_KEY_VIDEO_DECODER_BLANK_FRAME_ON_SHUTDOWN
Value Type int32_t, 0/1
Default Value 0 (disabled)
Related APIs Configure, SetSurface, Prepare, Start, Stop, Destroy
Core Dependencies native_avcodec_videodecoder.h, native_avcodec_base.h, native_window.h
Star Count Not provided in the source
License Not provided in the source; repost notice indicates CC 4.0 BY-SA

Illustration AI Visual Insight: This image serves as the article’s primary visual anchor. Its main purpose is to highlight that the new AVCodec Kit capability is tied to video shutdown transition quality, typically in media frameworks, display pipelines, or decoder-to-display scenarios, rather than a specific UI interaction screenshot.

The traditional shutdown flow causes hard display pipeline transitions

In the standard flow, the video decoder lifecycle typically includes creation, configuration, preparation, startup, running, stop, and destroy. OH_VideoDecoder_Stop stops decoding and releases input and output buffers, while OH_VideoDecoder_Destroy fully reclaims instance resources.

The real issue is not whether the decoder stops, but what remains on screen after it stops. Once the decoder stops sending frames to the Surface, the display device often keeps the last rendered frame until the system or driver clears the screen. This can cause ghosting, flicker, and even expose stale content during multi-page transitions.

The smooth shutdown mechanism replaces the last frame with a black frame

HarmonyOS 6.0 adds the OH_MD_KEY_VIDEO_DECODER_BLANK_FRAME_ON_SHUTDOWN parameter. When you set its value to 1, the decoder proactively outputs a blank frame, typically black, before Stop or Destroy.

This is not a business-layer workaround that appends a UI frame. Instead, the decoder itself performs a controlled final write to the Surface before shutdown. The benefit is immediate: the last frame no longer lingers, and the display transitions smoothly from “content visible” to “no content.”

// Enable blank frame output during shutdown
OH_AVFormat_SetIntValue(format,
    OH_MD_KEY_VIDEO_DECODER_BLANK_FRAME_ON_SHUTDOWN,
    1); // 1 enables the black blank-frame transition

This configuration inserts a controlled black frame before the decoder shuts down, replacing an otherwise unpredictable residual image.

This feature only has practical value in Surface mode

This capability only works in Surface mode, which means the decoder has already been bound to an OHNativeWindow through OH_VideoDecoder_SetSurface. Only in this mode does the decoder participate directly in on-screen rendering.

If the application uses Buffer mode and passes decoded YUV data to an upper layer for custom processing, the decoder is no longer responsible for pushing a black frame to the display during shutdown. In that case, setting this parameter will not change the visible result.

The system defaults to black because it is the least disruptive color

Black is visually the closest match to “content ended” and “no signal.” It reduces the perception of switching and avoids the abrupt flash that bright colors such as white or blue can create during shutdown.

For player exit flows, ad segment switching, or releasing a Surface in VR scenarios, a black frame acts as both the lowest-interference visual buffer and the most stable engineering default.

#include <multimedia/player_framework/native_avcodec_videodecoder.h>
#include <multimedia/player_framework/native_avcodec_base.h>
#include <multimedia/player_framework/native_avformat.h>
#include <multimedia/player_framework/native_window.h>

OH_AVCodec *CreateDecoder()
{
    // Create an AVC video decoder by MIME type
    return OH_VideoDecoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC);
}

This snippet shows the minimal header set required for decoder initialization and the entry point for instance creation.

The correct integration point is to declare the parameter during Configure

The best time to enable the blank-frame transition is when constructing OH_AVFormat before Configure. In addition to the switch itself, you must also provide complete base information such as width, height, pixel format, frame rate, and bitrate. Otherwise, the decoder cannot enter a runnable state.

OH_AVCodec *videoDecoder = OH_VideoDecoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC);
OH_AVFormat *format = OH_AVFormat_Create();

OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, 1920);          // Set width
OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, 1080);         // Set height
OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, AV_PIXEL_FORMAT_NV12); // Set pixel format
OH_AVFormat_SetIntValue(format, OH_MD_KEY_FRAME_RATE, 30);       // Set frame rate
OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, 4000000);    // Set bitrate
OH_AVFormat_SetIntValue(format,
    OH_MD_KEY_VIDEO_DECODER_BLANK_FRAME_ON_SHUTDOWN,
    1); // Enable smooth shutdown

OH_AVErrCode ret = OH_VideoDecoder_Configure(videoDecoder, format);

This code assembles the decoder’s core parameters and enables smooth shutdown during the configuration phase.

The Surface binding and startup order must remain explicit

In asynchronous callback mode, the recommended order is: SetSurfaceRegisterCallbackPrepareStart. SetSurface is the prerequisite for this feature to work. Without it, there is no output path for the shutdown black frame.

OHNativeWindow *nativeWindow = /* Obtained from XComponent */ nullptr;

ret = OH_VideoDecoder_SetSurface(videoDecoder, nativeWindow); // Bind the display output window

OH_AVCodecCallback callback = {
    .onError = OnError,
    .onStreamChanged = OnStreamChanged,
    .onNeedInputBuffer = OnNeedInputBuffer,
    .onNewOutputBuffer = OnNewOutputBuffer
};

OH_VideoDecoder_RegisterCallback(videoDecoder, callback, nullptr); // Register callbacks
OH_VideoDecoder_Prepare(videoDecoder); // Pre-allocate resources
OH_VideoDecoder_Start(videoDecoder);   // Start decoding

This code defines the standard startup path for Surface mode and ensures the blank-frame shutdown capability has a valid execution environment.

This mechanism is especially important for scene switching and Surface reuse

Player exit is the most intuitive benefit scenario. Once enabled, users see a natural fade to black after video playback ends instead of a frozen final frame that lingers briefly before disappearing.

Its value becomes even greater during app switching, ad insertion, or when multiple decoders reuse the same Surface. The mechanism provides a system-level cleanup step so the next content source can take over rendering on a clean canvas.

Both Stop and Destroy trigger blank frame output

As long as the switch is enabled, both OH_VideoDecoder_Stop and OH_VideoDecoder_Destroy can trigger the black-frame transition. However, Flush does not trigger it, because Flush handles buffer cleanup rather than display finalization.

OH_AVErrCode ret = OH_VideoDecoder_Stop(videoDecoder); // Output a black frame before stopping
if (ret == AV_ERR_OK) {
    // The final image on the Surface should now be covered by the black frame
}

ret = OH_VideoDecoder_Destroy(videoDecoder); // Fully release resources
videoDecoder = nullptr; // Avoid a dangling pointer

This snippet shows that both Stop and Destroy are part of the smooth shutdown path, but after Destroy you must also handle the instance lifecycle correctly.

Production use still requires attention to threading, versioning, and restart semantics

First, the API requirement is HarmonyOS 6.0 with API Level 20 or later. Earlier versions do not support this capability, so you should add feature checks or version-based branching in production code.

Second, you should not call Destroy directly from a callback thread, because doing so may cause blocking or resource release issues. Third, if you call Start again after Stop, you usually need to re-feed codec-specific data that was already sent previously, such as H.264 SPS/PPS.

FAQ

Q1: Why do I not see any black-frame effect after setting the parameter?
A: The most common reason is that you are not using Surface mode, or you did not call OH_VideoDecoder_SetSurface. This feature does not work in Buffer mode.

Q2: What are the behavioral differences between Flush, Stop, and Destroy?
A: Flush only clears buffers and does not trigger a black frame. Stop halts decoding while keeping some configuration state. Destroy fully releases the instance. When the parameter is enabled, both Stop and Destroy output a blank frame.

Q3: Does this capability introduce noticeable performance overhead?
A: Usually not. It only outputs one additional solid-color frame before shutdown, so the cost is minimal, while the improvement in visual consistency is significant.

AI Readability Summary: This article systematically explains the new smooth shutdown capability for video decoders in HarmonyOS 6.0 AVCodec Kit. It focuses on the blank-frame output mechanism, applicability constraints, configuration method, lifecycle impact, and common scenarios, helping developers resolve last-frame residue, flicker, and Surface reuse issues after Stop or Destroy.