HarmonyOS 6.0 introduces a smooth shutdown mechanism for AVCodec Kit video decoders: before
StoporDestroy, 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 |
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: SetSurface → RegisterCallback → Prepare → Start. 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.