This article introduces Live555 as RTSP client, s5pv210 do media terminal, hard decode NV12 image sequence.
MPlayer Play YUV Command:
Mplayer-demuxer Rawvideo-rawvideo W=700:H=480/SDCARD/RESOURCE/IMG_700_480.YUV
Coding:
1) or the same as the code superboot, indispensable, u-boot not
2) Be sure to call SSBSIPMFCDECGETINBUF () before calling Ssbsipmfcdecinit () and then fill in the header (Sps/pps/sei) information.
3) Ssbsipmfcdecgetoutbuf () The status returned is only mfc_getoutbuf_display_decoding or Mfc_getoutbuf_display_ Only yviraddr and cviraddr are valid, and if return mfc_getoutbuf_decoding_only need to call Ssbsipmfcdecexe () and Ssbsipmfcdecgetoutbuf () again
4) Yviraddr and Cviraddr point to the data is tiled NV12 format (64x32 tiled), need to be converted into the current format in order to normal reality. This MFC API has already provided csc_tiled_to_linear (), header file Color_space_convertor.h
5) There are several problems in the test procedure: The frame of multi-slice is not supported; the last few frames in buffer are not disposed of directly; if the data frame after the first header is not IDR, it will be warning until the first IDR frame is reached. The previous NON-IDR frames may be decoded incorrectly or dropped frames.
is a function flow
The embedding process for Live555 is as follows:
The key process is shown in the following function:
int H264decoder_c::ssbsipmfcdecode264stream (char* frame,int framelen) {char* imgptr = NULL; int tmp_width=-1; int Tmp_hei Ght =-1; imgptr = Ssbsipmfcusrdecodeaframe (frame,framelen,m_ssbsipmfc_virbuf,m_ssbsipmfc_openhandle,&tmp_width , &tmp_height), if (imgptr!=null) {u_int8_t* src[3]; int linesize[3]; src[0] = (u_int8_t*) imgptr; SRC[1] = src[0] + tmp_width*tmp_height; SRC[2] = src[1] + tmp_width*tmp_height/4; linesize[0] = Tmp_width; LINESIZE[1] = TMP_WIDTH/2; LINESIZE[2] = linesize[1]; Scaleyuvimgtorgb (Tmp_width,tmp_height,src,linesize,tmp_width,tmp_height); Callimgpaint (g_cenptr,tmp_width,tmp_height); free (imgptr);} return Framelen;}
int Ssbsipmfcusropenmfcdecodemodule (char *spspps,int spsppslen,void **openhandle,void **virinbuf) {int i=0; int set_ conf_val; void * PHYINBUF; Ssbsip_mfc_error_code err;//unsigned int buf_type = cache;unsigned int buf_type = CACHE; *openhandle = Ssbsipmfcdecopen (&buf_type); if (!*openhandle) {fprintf (stderr, "error:ssbsipmfcdecopen.\n"); return-1; } printf ("Ssbsipmfcdecopen succeeded.\n"); *virinbuf = Ssbsipmfcdecgetinbuf (*openhandle, &phyinbuf, max_decoder_input_buffer_size); Max_decoder_input_buffer_size is defined in SsbSipMfcApi.h, = 1024*3072 = 3 MiB if (!*virinbuf) {fprintf (std Err, "error:ssbsipmfcdecgetinbuf.\n"); return-1; } printf ("Ssbsipmfcdecgetinbuf succeeded.\n"); #if 1//This might improve performance. To is confirmed set_conf_val = 3; Ssbsipmfcdecsetconfig (Openhandle, Mfc_dec_setconf_extra_buffer_num, &set_conf_val); Set_conf_val = 4; Ssbsipmfcdecsetconfig (Openhandle, Mfc_dec_setconf_diSplay_delay, &set_conf_val); #endif memcpy (*virinbuf,spspps,spsppslen); #if 1 printf ("Header:"); for (i=0;i<spsppslen;i++) printf ("%x", ((uint8_t*) (*VIRINBUF)) [i]); printf ("\ n"); #endif err = Ssbsipmfcdecinit (*openhandle,h264_dec,spsppslen); if (err<0) {fprintf (stderr, "Error:ssbsipmfcdecinit. Code%d\n ", err); printf ("Error:ssbsipmfcdecinit. Code%d\n ", err); return-1; } printf ("Ssbsipmfcdecinit succeeded.\n"); return 0;} void Ssbsipmfcusrshowstatus (Ssbsip_mfc_dec_output_info *oinfo,ssbsip_mfc_dec_outbuf_status status) {printf ("status : "); Switch (status) {case mfc_getoutbuf_decoding_only:printf ("Decoding only\n"); Break Case mfc_getoutbuf_display_decoding:printf ("DISPLAY and decoding\n"); Break Case mfc_getoutbuf_display_only:printf ("DISPLAY only\n"); Break Case mfc_getoutbuf_display_end:printf ("DPB is EMPty\n "); Break default:printf ("Unknown status!\n"); Break } printf ("img_width=%d, img_height=%d\n", oinfo->img_width,oinfo->img_height); printf ("yviraddr=%x, cviraddr=%x\n", oinfo->yviraddr,oinfo->cviraddr); printf ("buf_width=%d, buf_height=%d\n", oinfo->buf_width,oinfo->buf_height); printf ("consumedbyte=%d\n", Oinfo->consumedbyte);} char* ssbsipmfcusrnv12dump (ssbsip_mfc_dec_output_info *oinfo,ssbsip_mfc_dec_outbuf_status status,int *width,int * Height) {static int channel=1; int i=0; if (status==mfc_getoutbuf_display_decoding | | status==mfc_getoutbuf_display_ only) {char *nv12=null; Nv12=malloc ((int) (oinfo->img_width*oinfo->img_height*1.5)); NV12) {fprintf (stderr, "Out of memory.\n");} Converted tiled to linear nv12 format-y planecsc_tiled_to_linear (Nv12,oinfo->yviraddr,oinfo->img_width, Oinfo->img_height);//converted tiled to linear nv12 format-c Planecsc_tiled_to_linear (nv12+oinfo->img_wiDTH*OINFO->IMG_HEIGHT,OINFO->CVIRADDR,OINFO->IMG_WIDTH,OINFO->IMG_HEIGHT/2); SSBSIPMFCUSRNV12TOYV12 (nv12,oinfo->img_width,oinfo->img_height);*width=oinfo->img_width; *height=oinfo->img_height;//fprintf_binary ("Ssbsipmfcyuv.yuv", NV12, (int) (oinfo->img_width*oinfo->img_ height*1.5), "AB");//free (NV12); return NV12;} return NULL;} char* ssbsipmfcusrdecodeaframe (char *framebuf,int framelen,void *virinbuf,void *openhandle,int *width,int *height) { static int cnt=0; void *phyinbuf; Ssbsip_mfc_error_code err; Ssbsip_mfc_dec_output_info Oinfo; Ssbsip_mfc_dec_outbuf_status status;char* imgptr=null; STATUS = mfc_getoutbuf_status_null;//printf ("length:%d\n", Ssbsipmfcusrreadoneframe (&framebuf,framelen)); memcpy (Virinbuf,framebuf,framelen); S5pv210_decode://Take care of Goto, with as less as possible err = Ssbsipmfcdecex E (Openhandle, Framelen); if (err<0) {fprintf (stderr, "Error:ssbsipmfcdecexe. Code%d\n ", err); return-1; } else{//printf ("SSBSIPMFC Decode OK frame%d!! \ n ", cnt++); if (cnt>10000) cnt=0; } memset (&oinfo,0,sizeof (oinfo)); Status = Ssbsipmfcdecgetoutbuf (Openhandle,&oinfo); if (status==mfc_getoutbuf_decoding_only) {printf ("Decode not done redecode\n"); Goto S5pv210_decode; } else if ((status==mfc_getoutbuf_display_decoding) | | | (status==mfc_getoutbuf_display_only)) {static int cnt = 0; if ((cnt++)%2) {if (cnt>1000) cnt = 0; return NULL; }//ssbsipmfcusrshowstatus (&oinfo,status); imgptr = Ssbsipmfcusrnv12dump (&oinfo,status,width, height); return imgptr; } else{printf ("s5pv210 decode unexpected status goto decode again\n"); Goto S5pv210_decode; } return NULL;
At the same time, the call in the function is optimized, only two steps are needed, and the Open->decode is finished.
Reference article:
Android s5pv210 FIMC Driver Analysis-FIMC_REGS.C
http://blog.csdn.net/mirkerson/article/details/8192600
The encoding process of MFC in s5pv210
http://blog.csdn.net/mirkerson/article/details/8953469
s5pv210 MFC sub-decoding
http://bbs.csdn.net/topics/390385062
s5pv210 HDMI Display Implementation
http://blog.csdn.net/liujia2100/article/details/21788667
NV12 Turn RGB
http://www.armbbs.net/forum.php?mod=viewthread&tid=18938
"Success" tiny210 MFC library porting and hard-coded test source under Linux
Http://www.arm9home.net/read.php?tid-28647.html
"This time it's decoding." Tiny210 MFC library porting and hard decoding test source under Linux
Http://www.arm9home.net/read.php?tid-28822.html
TQ210 Linux under nv12t turn RGB display problem
http://www.armbbs.net/forum.php?mod=viewthread&tid=18938
Linux under: live555+s5pv210 MFC module Hard Solution implementation