A311D SOC support 1 channel 4K@60fps VP9,H265,H264 video decoding OR maximum 4 channels of 1080P@25fps video decoding in the codec format: H265,H264,MPEG-1/2/4,VP9,WMV。
The libamldec.so is developed to use the A311D hardware video decoder in a convenient manner.
Quick Start
First Step:To connect the board with LCD monitor via HDMI cable
Second Step:To power on the board and login the shell
Third Step: To edit the script for playback
vi /etc/test/testxhiveai.xml
There are 4 test cases for video decoding and displaying to the screen:
disp_1win, disp_2win, disp_3win, disp_4win: They cover up to 4 channels of video playbacks
Edit the link=”xxxxx” for your own playback linkage
<alias name=”xxxx”/>: the short description for the playback that would be displayed on the screen
Fourth Step: To start the playback
testxhiveai disp_1win //one windows display
testxhiveai disp_2win //two windows display
testxhiveai disp_3win //three windows display
testxhiveai disp_4win //four windows display
Develop the code
The example code is under the git repository: a311d/video_decode/vframes.
Step 1: Initialize the video decoder
#include "amldec.h"
#define ALIGN(x, mask) (((x) + (mask)) & ~(mask))#define ALIGN(x, a)
ALIGN(x, (typeof(x))(a) - 1)
DEC_CONFIG_t dec_conf;AMLDEC_HANDLE_t vdec_handle;
memset(&dec_conf, 0, sizeof(DEC_CONFIG_t));
dec_conf.play_id = <playback channel id: 1, 2, 3, 4 ...>;
dec_conf.format = <DEC_FORMAT_t defined in amldec.h.
the default hardware decoding output is VDEC_FORMAT_NV12>;
dec_conf.src_width = ALIGN(<original video width>, 32);
dec_conf.src_height = ALIGN(<original video height>, 32);
dec_conf.dest_width = <expected output video width>;
dec_conf.dest_height = <expected output video height>;
dec_conf.tbuf = kVdecBuffer_MEM;
dec_conf.opaque = <application private data OR NULL>;
vdec_handle = amlDecInit(&dec_conf);
if (!vdec_handle) {
//success
} else {
//failure
}
Step 2: Start the video decoder
int rc;
rc = amlDecStart(vdec_handle);
if (rc == 0) {
//success
} else {
//failure
}
Step 3: Feed the video ES packages into the video decoder continuously
2 options currently are supported
1) Gstreamer: GstSample *frame
GstFlowReturn status = GST_FLOW_ERROR;
status = amlDecSendData(vdec_handle, sample, DEC_DATA_GST);
if (status != GST_FLOW_OK) {
//failure
} else {
//success
}
2) AMLDEC_DATA_t *frame
AMLDEC_DATA_t *frame;
frame->codec = <DEC_CODEC_t>;
frame->is_key_frame = <1: I frame, 0: P/B frames>;
frame->pts_us = <64-bit pts in us>;
frame->data = <Video ES Package Data Buffer>;
frame->size = <Size of the video buffer>;
status = amlDecSendData(vdec_handle, sample, DEC_DATA_SPEC);
if (status) {
//failure
} else {
//success
}
Note: ffmpeg AVPacket* pkt is not supported right now and planned to be supported in
the future.
Step 4: Start the thread to recieve the decoded picture whenever it is ready
DEC_FRAME_t *frame;
mlDecReceiveFrame(vdec_handle, &frame);
/*
VDEC_FORMAT_NV12:
frame->buf[0]: YYYY...
frame->buf[1]: UV...
VDEC_FORMAT_NV21:
frame->buf[0]: YYYY...
frame->buf[1]: VU...
VDEC_FORMAT_I420:
frame->buf[0]: YYYY...
frame->buf[1]: U...
frame->buf[2]: V...
VDEC_FORMAT_RGB/VDEC_FORMAT_BGR/VDEC_FORMAT_RGBA...
frame->buf[0]
*/
/*Need to release it once you used it up*/
amlDecReleaseFrame(rt->vdec_handle, frame);
Step 5: Stop the video decoder
stop to feed the video data into decoder
amlDecStop(vdec_handle);
Step 6: Release the video decoder
amlDecRelease(vdec_handle);