An h264 video decoding trial program is displayed on the Internet, which can be used to test its logical process.
The Code is as follows:
Test_display_h264 ()
{
In_fd = open (h1__input_file, o_rdonly); // video file open
Fstat (in_fd, & S); // get input file size
File_size = S. st_size;
In_addr = (char *) MMAP (0, file_size, prot_read, map_shared, in_fd, 0); // mapping input file to memory
Pp_fd = open (pp_dev_name, o_rdwr); // post processor open, why does it need to be opened?
Fb_fd = open (fb_dev_name, o_rdwr | o_ndelay); // LCD frame buffer open
//////////////////////////////////////// //////
// Frameextractor initialization frame decompression initialization //
//////////////////////////////////////// //////
Pframeexctx = frameextractorinit (framex_in_type_mem, delimiter_h264, sizeof (delimiter_h264), 1 );
File_strm.p_start = file_strm.p_cur = (unsigned char *) in_addr;
File_strm.p_end = (unsigned char *) (in_addr + file_size );
Frameextractorfirst (pframeexctx, & file_strm); // stream File Buffer start and end
//////////////////////////////////////
/// 1. Create new instance ///
/// (Ssbsiph264decodeinit )///
//////////////////////////////////////
Handle = ssbsiph264decodeinit ();
//////////////////////////////
//// 1.1 createfile /////
//////////////////////////////
Hopen = open (mfc_dev_name, o_rdwr | o_ndelay); // open the MFC Device
//////////////////////////////////////// //
// 1.2 mapping the MFC input/output buffer //
//////////////////////////////////////// //
// Mapping shared in/out buffer between application and MFC Device Driver
ADDR = (unsigned char *) MMAP (0, buf_size, prot_read | prot_write, map_shared, hopen, 0 );
Pctx = (_ mfclib_h1__dec *) malloc (sizeof (_ mfclib_h1__dec); // defines decoding CTX
//////////////////////////////////////// /////
/// 2. Obtaining the input buffer ///
/// (Ssbsiph264decodegetinbuf )///
//////////////////////////////////////// /////
Pstrmbuf = ssbsiph264decodegetinbuf (handle, nframeleng );
//////////////////////////////////////// /////////
//// 2.1 (deviceiocontrol )/////
//// Ioctl_mfc_get_strm_buf_addr 0x0080000f /////
//////////////////////////////////////// /////////
Mfc_args.get_buf_addr.in_usr_data = (INT) pctx-> mapped_addr;
R = IOCTL (pctx-> hopen, ioctl_mfc_get_line_buf_addr, & mfc_args );
//////////////////////////////////////// ///////
// 2.2 h264 config stream extraction frame decompression configuration //
//////////////////////////////////////// //////
Nframeleng = extractconfigstreamh264 (pframeexctx, & file_strm, pstrmbuf, input_buffer_size, null );
//////////////////////////////////////// ////////////////////////
/// 3. refreshing the instance with the config stream ///
/// (Ssbsiph264decodeexe )///
//////////////////////////////////////// ////////////////////////
Ssbsiph264decodeexe (handle, nframeleng );
//////////////////////////////////////// /////////
//// 3.1 (deviceiocontrol )/////
//// Ioctl_mfc_h1__dec_init 0x00800005 /////
//////////////////////////////////////// /////////
Mfc_args.dec_init.in_strmsize = lengthbuffill;
R = IOCTL (pctx-> hopen, ioctl_mfc_h1__dec_init, & mfc_args );
/////////////////////////////////////
/// 4. Get stream information ///
/////////////////////////////////////
Ssbsiph264decodegetconfig (handle, hsf-_dec_getconf_streaminfo, & stream_info );
// 4.1 case hsf-_dec_getconf_streaminfo
G_stream_info.width = pctx-> width;
G_stream_info.height = pctx-> height;
G_stream_info.buf_width = pctx-> buf_width;
G_stream_info.buf_height = pctx-> buf_height;
// Set post processor Configuration
// Structure type for IOCTL commands initi_pp_set_params, initi_pp_set_input_buf_start_addr_phy,
// Initiat_pp_set_input_buf_next_start_addr_phy.
Pp_param.src_full_width = stream_info.buf_width;
Pp_param.src_full_height = stream_info.buf_height;
Pp_param.src_start_x = 0;
Pp_param.src_start_y = 0;
Pp_param.src_width = pp_param.src_full_width;
Pp_param.src_height = pp_param.src_full_height;
Pp_param.src_color_space = yc420; // The MFC decode data is in the yuv420 format.
Pp_param.dst_start_x = 0;
Pp_param.dst_start_y = 0;
Pp_param.dst_full_width = fb0_width; // destination width
Pp_param.dst_full_height = fb0_height; // destination height
Pp_param.dst_width = pp_param.dst_full_width;
Pp_param.dst_height = pp_param.dst_full_height;
Pp_param.dst_color_space = fb0_color_space; // rgb565
Pp_param.out_path = dma_oneshot;
IOCTL (pp_fd, cloud_pp_set_params, & pp_param );
// Get LCD frame buffer address
Fb_size = pp_param.dst_full_width * pp_param.dst_full_height * 2; // rgb565
Fb_addr = (char *) MMAP (0, fb_size, prot_read | prot_write, map_shared, fb_fd, 0 );
// Decompress each frame cyclically until the playback is complete.
While (1)
{
//////////////////////////////////
/// 5. Decode ///
/// (Ssbsiph264decodeexe )///
//////////////////////////////////
If (ssbsiph264decodeexe (handle, nframeleng )! = Ssbsip_h1__dec_ret_ OK)
Break;
//////////////////////////////////////// /////////
//// 5.1 (deviceiocontrol )/////
//// Ioctl_mfc_h1__dec_exe 0x00800007 /////
//////////////////////////////////////// /////////
Mfc_args.dec_exe.in_strmsize = lengthbuffill;
R = IOCTL (pctx-> hopen, ioctl_mfc_h1__dec_exe, & mfc_args );
//////////////////////////////////////// //////
/// 6. Obtaining the output buffer ///
/// (Ssbsiph264decodegetoutbuf )///
//////////////////////////////////////// //////
Ssbsiph264decodegetconfig (handle, hsf-_dec_getconf_phyaddr_fram_buf, pyuvbuf );
// 6.1 ioctl_mfc_get_phy_fram_buf_addr 0x00800013
// Obtain the physical address for PP
R = IOCTL (pctx-> hopen, ioctl_mfc_get_phy_fram_buf_addr, & mfc_args );
///////////////////////////////////////
// Next H.264 video stream get next frame //
//////////////////////////////////////
Nframeleng = nextframeh264 (pframeexctx, & file_strm, pstrmbuf, input_buffer_size, null );
If (nframeleng <4) // condition for loop end
Break;
// Post Processing
// Pp_param.srcfrmst MFC output buffer physical address
// Pp_param.dstfrmst LCD frame buffer physical address.
Pp_param.src_buf_addr_phy = pyuvbuf [0]; // MFC output buffer
IOCTL (pp_fd, s3_pp_set_src_buf_addr_phy, & pp_param );
IOCTL (fb_fd, fbioget_fscreeninfo, & LCD _info );
Pp_param.dst_buf_addr_phy = LCD _info.smem_start; // LCD Frame Buffer
IOCTL (pp_fd, maid, & pp_param );
IOCTL (pp_fd, cloud_pp_start); // set the number of PP workers and start PP
}
Ssbsiph264decodedeinit (handle );
Munmap (in_addr, file_size );
Munmap (fb_addr, fb_size );
Close (pp_fd );
Close (fb_fd );
Close (in_fd );
Return 0;
}