This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/DRA712: omapdrmtest-viddec3test questions

Part Number: DRA712

Tool/software: Linux

HI

i was using omapdrmtest-viddec3test demo  to decode  h264 Video stream transmitted by usb The display interface is wayland.

But something went wrong ,when the decoding ,sometime will appear Segmentation Fault .i was analyze coredump files:

warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./Mirror'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  wl_map_insert_new (map=map@entry=0x32944, flags=flags@entry=0, data=data@entry=0xb251d230) at ../wayland-1.9.0/src/wayland-util.c:198
198     ../wayland-1.9.0/src/wayland-util.c: No such file or directory.
warning: File "/lib/libstdc++.so.6.0.21-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
        add-auto-load-safe-path /lib/libstdc++.so.6.0.21-gdb.py
line to your configuration file "//.gdbinit".
To completely disable this security protection add
        set auto-load safe-path /
line to your configuration file "//.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
        info "(gdb)Auto-loading safe path"
(gdb) bt
#0  wl_map_insert_new (map=map@entry=0x32944, flags=flags@entry=0, data=data@entry=0xb251d230) at ../wayland-1.9.0/src/wayland-util.c:198
#1  0xb6ec3f40 in proxy_create (interface=interface@entry=0xb6ed89a0 <wl_callback_interface>, factory=0x31348, factory=0x31348) at ../wayland-1.9.0/src/wayland-client.c:345
#2  0xb6ec47a8 in create_outgoing_proxy (message=0x0, interface=0xb6ed89a0 <wl_callback_interface>, args=0xac317c78, proxy=0x31348) at ../wayland-1.9.0/src/wayland-client.c:546
#3  wl_proxy_marshal_array_constructor (proxy=proxy@entry=0x31348, opcode=201560, opcode@entry=3, args=args@entry=0xac317c78, interface=0xb6ed89a0 <wl_callback_interface>,
    interface@entry=0xb6d43ceb <wl_viewport_set(wl_viewport*, wl_fixed_t, wl_fixed_t, wl_fixed_t, wl_fixed_t, int32_t, int32_t)+42>) at ../wayland-1.9.0/src/wayland-client.c:593
#4  0xb6ec4934 in wl_proxy_marshal_constructor (proxy=0x31348, opcode=3, interface=0xb6ed89a0 <wl_callback_interface>) at ../wayland-1.9.0/src/wayland-client.c:682
#5  0xb6d43b62 in wl_surface_frame (wl_surface=0x31348) at /home/zhan/dra7xx-evm-03_04_00_03/filesystem/usr/include/wayland-client-protocol.h:1491
#6  0xb6d44412 in post_vid_buffer (disp=0x312d0, buf=0x33348, x=32, y=24, w=1920, h=720) at display-wayland.cpp:299
#7  0xb6d44c48 in disp_post_vid_buffer (disp=0x312d0, buf=0x33348, x=32, y=24, w=1920, h=720) at util.cpp:121
#8  0xb6d438dc in Decoder::RetriveData (this=0xb6d55be4 <_gVideoDecoder>) at decoder.cpp:237
#9  0xb6d437c6 in Decoder::Decode (this=0xb6d55be4 <_gVideoDecoder>, data=0xac514008, len=242) at decoder.cpp:192
#10 0xb6d430bc in DecoderProcess (data=0xac514008, datalen=242) at main.cpp:13
#11 0x000129fc in ECCallback::onMirrorVideoReceived (this=0x2b550, data=0xac514008, length=242) at Mirror.cpp:135
#12 0xb6d9900c in CarbitECSDK::DataService::postLoop(void*) () from /usr/lib/libECSDK.so
#13 0xb6cc3d40 in std::(anonymous namespace)::execute_native_thread_routine (__p=<optimized out>)
    at /home/tcwg-buildslave/workspace/tcwg-make-release/label/tcwg-x86_64-ex40/target/arm-linux-gnueabihf/snapshots/gcc-linaro-5.3-2016.02/libstdc++-v3/src/c++11/thread.cc:84
#14 0xb6f2e4b8 in start_thread (arg=0x0) at pthread_create.c:335
#15 0xb6b4243c in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:89 from /lib/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

from this MSG,I don't  understand what the problem is. Can you give me some advice?

 

Thanks

  • Hi xinyang,
    This looks like customized version of viddec3test.
    What have you modified in viddec3test ?
    What is the SDK version and please share the commitID on omapdrmtest?
    Can you check if the issue is reproduced when you use --fps option ?

    Thanks
    Ramprasad
  • Hi

       Thank you for  your reply !

       Yes .it is customized version of viddec3test .  we are modified the code base on it ,

       viddec3test version is 1.0.0-r19 ,SDK version is dra7xx-evm-03_02_00_03.

      I  did a test, i put the  video stream  stored into a H264 format video file, and then decoded and displayed  (on the wayland )by viddec3test  DEMO.it is no problem . But there is a problem with directly decoding and displaying the data. there is anther  phenomenon ,The higher the FPS value of the transmitted video, the greater the probability of error.

    code:

    #pragma once
    
    #include <fcntl.h>
    #include "decoder.h"
    #include "util.h"
    #include <fcntl.h>
    extern "C" 
    {
    #include <libdce.h>
    #include <xf86drm.h>
    #include <omap_drm.h>
    #include <omap_drmif.h>
    }
    
    
    /* Padding for width as per Codec Requirement (for h264) */
    #define PADX  32
    /* Padding for height as per Codec requirement (for h264)*/
    #define PADY  24
    
    class Decoder 
    {
    public:
    	Decoder();
    	~Decoder();
    
    	bool Open(int imgWidth, int imgHeight, int scrnX, int scrnY, int scrnWidth, int scrnHeight);
    	bool Decode(const void* data, int len);
    	void Flush();
    	void Close();
    
    protected:
    	void RetriveData();
    
    	struct omap_device* m_dev;
    	struct Display* m_disp;
    	Engine_Handle m_engine;
    	VIDDEC3_Handle m_codec;
    	VIDDEC3_DynamicParams* m_dynParams;
    	XDM2_BufDesc* m_inBufs;
    	XDM2_BufDesc* m_outBufs;
    	VIDDEC3_InArgs* m_inArgs;
    	VIDDEC3_OutArgs* m_outArgs;
    	struct omap_bo* m_input_bo;
    	int m_input_sz;
    	int m_padded_width;
    	int m_padded_height;
    	int m_num_outBuf;
    	size_t* m_outBuf_fd;
    };
    
    Decoder::Decoder()
    {
    	m_dev = NULL;
    	m_disp = NULL;
    	m_dynParams = NULL;
    	m_inBufs = NULL;
    	m_outBufs = NULL;
    	m_inArgs = NULL;
    	m_outArgs = NULL;
    	m_input_bo = NULL;
    	m_outBuf_fd = NULL;
    }
    
    Decoder::~Decoder()
    {
    	Close();
    }
    
    void Decoder::Close()
    {
    //	printf("Close Decoder...\n");
    	if(m_dynParams != NULL) { dce_free(m_dynParams); 					m_dynParams = NULL; }
    	if(m_inBufs != NULL)		
    	{
    		dce_buf_unlock(1, (size_t*)&(m_inBufs->descs[0].buf));
    		close((int)m_inBufs->descs[0].buf);
    		dce_free(m_inBufs);
    		m_inBufs = NULL;
    	}
    	if(m_outBufs != NULL)	{ dce_free(m_outBufs); 						m_outBufs = NULL; }
    	if(m_inArgs != NULL)    { dce_free(m_inArgs); 						m_inArgs = NULL; }
    	if(m_outArgs != NULL)   { dce_free(m_outArgs); 						m_outArgs = NULL; }
    	if(m_codec != NULL)     { VIDDEC3_delete(m_codec); 					m_codec = NULL; }
    	if(m_engine != NULL)    { Engine_close(m_engine); 					m_engine = NULL; }
        if(m_input_bo != NULL)  { omap_bo_del(m_input_bo); 					m_input_bo = NULL; }
    	if(m_outBuf_fd != NULL)	{ free(m_outBuf_fd); 						m_outBuf_fd = NULL; }
    	if(m_dev != NULL)	 	{ dce_deinit(m_dev); 						m_dev = NULL; }
    	if(m_disp != NULL)    	
    	{ 
    		disp_free_buffers(m_disp,m_num_outBuf);
    		disp_close(m_disp);
    		free(m_disp);
    		m_disp = NULL;
    	}
    }
    
    bool Decoder::Open(int w, int h, int scrnX, int scrnY, int scrnWidth, int scrnHeight)
    {
    	m_disp = disp_open(scrnX, scrnY, scrnWidth, scrnHeight);
    	if(m_disp == NULL)
    		return false;		
    
    	dce_set_fd(m_disp->fd);
    
    	m_dev = (omap_device*)dce_init();
    	if(m_dev == NULL) 
    		return false;	
    
    	/* calculate output buffer parameters: */
    	w  = ALIGN2 (w, 4);        /* round up to macroblocks */
    	h = ALIGN2 (h, 4);       /* round up to macroblocks */
    
    	m_padded_width  = ALIGN2 (w + (2*PADX), 7);
    	m_padded_height = h + 4*PADY;
    
    	m_num_outBuf   = MIN(16, 32768 / ((w/16) * (h/16))) *2+1;
    	//printf("Num = %d\n",m_num_outBuf);
    
    	if (!disp_get_vid_buffers(m_disp, m_num_outBuf, FOURCC_STR("NV12"), m_padded_width, m_padded_height))
    	{
    		ERROR("could not allocate buffers");
    		return false;
    	}
    
    	m_outBuf_fd = (size_t*)malloc(sizeof(int)*m_num_outBuf);
    	m_input_sz = w * h;
    	m_input_bo = omap_bo_new(m_dev,	m_input_sz, OMAP_BO_WC);
    
    	Engine_Error ec;
    	m_engine = Engine_open(String("ivahd_vidsvr"), NULL, &ec);
    	if (m_engine == NULL) 
    	{
    		ERROR("could not open engine");
    		return false;
    	}
    
    	VIDDEC3_Params* params = (VIDDEC3_Params*)dce_alloc(sizeof(IVIDDEC3_Params));
    	params->size = sizeof(IVIDDEC3_Params);
    	params->maxWidth         = w;
    	params->maxHeight        = h;
    	params->maxFrameRate     = 30000;
    	params->maxBitRate       = 10000000;
    	params->dataEndianness   = XDM_BYTE;
    	params->forceChromaFormat= XDM_YUV_420SP;
    	params->operatingMode    = IVIDEO_DECODE_ONLY;
    	params->displayDelay     = 1;//IVIDDEC3_DISPLAY_DELAY_AUTO;
    	params->displayBufsMode  = IVIDDEC3_DISPLAYBUFS_EMBEDDED;
    	params->inputDataMode    = IVIDEO_ENTIREFRAME;
    	params->metadataType[0]  = IVIDEO_METADATAPLANE_NONE;
    	params->metadataType[1]  = IVIDEO_METADATAPLANE_NONE;
    	params->metadataType[2]  = IVIDEO_METADATAPLANE_NONE;
    	params->numInputDataUnits= 0;
    	params->outputDataMode   = IVIDEO_ENTIREFRAME;
    	params->numOutputDataUnits = 0;
    	params->errorInfoMode    = IVIDEO_ERRORINFO_OFF;
    
    	m_codec = VIDDEC3_create(m_engine, String("ivahd_h264dec"), params);
    	dce_free(params);
    
    	if(m_codec == NULL) 
    	{
    		ERROR("could not create codec");
    		return false;
    	}
    
    	m_dynParams = (IVIDDEC3_DynamicParams*)dce_alloc(sizeof(IVIDDEC3_DynamicParams));
    	m_dynParams->size = sizeof(IVIDDEC3_DynamicParams);
    	m_dynParams->decodeHeader  = XDM_DECODE_AU;
    	/*Not Supported: Set default*/
    	m_dynParams->displayWidth  = 0;
    	m_dynParams->frameSkipMode = IVIDEO_NO_SKIP;
    	m_dynParams->newFrameFlag  = XDAS_TRUE;
    	VIDDEC3_Status* status = (IVIDDEC3_Status*)dce_alloc(sizeof(IVIDDEC3_Status));
    	status->size = sizeof(IVIDDEC3_Status);
    	XDAS_Int32 err = VIDDEC3_control(m_codec, XDM_SETPARAMS, m_dynParams, status);
    	dce_free(status);
    	if (err != 0) 
    	{
    		ERROR("fail to control: %d", err);
    		return false;
    	}
    
    	m_inBufs = (XDM2_BufDesc*)dce_alloc(sizeof(XDM2_BufDesc));
    	m_inBufs->numBufs = 1;
    	m_inBufs->descs[0].buf = (XDAS_Int8 *)omap_bo_dmabuf(m_input_bo);
    	dce_buf_lock(1, (size_t*)&(m_inBufs->descs[0].buf));
    	m_inBufs->descs[0].memType = XDM_MEMTYPE_RAW;
    
    	m_outBufs = (XDM2_BufDesc*)dce_alloc(sizeof(XDM2_BufDesc));
    	m_outBufs->numBufs = 2;
    	m_outBufs->descs[0].memType = XDM_MEMTYPE_RAW;
    	m_outBufs->descs[1].memType = XDM_MEMTYPE_RAW;
    
    	m_inArgs = (IVIDDEC3_InArgs*)dce_alloc(sizeof(IVIDDEC3_InArgs));
    	m_inArgs->size = sizeof(IVIDDEC3_InArgs);
    	m_outArgs = (IVIDDEC3_OutArgs*)dce_alloc(sizeof(IVIDDEC3_OutArgs));
    	m_outArgs->size = sizeof(IVIDDEC3_OutArgs);
    
    	return true;
    }
    
    bool Decoder::Decode(const void* data, int len)
    {
    //	printf("decode...\n");
    	struct Buffer *buf = disp_get_vid_buffer(m_disp);
    
    	if(buf == NULL)
    	{
    		ERROR("Out of buffers.");
    		return false;
    	}
    
    	m_inBufs->descs[0].bufSize.bytes = len;
    	m_inArgs->numBytes = len;
    
    	char* input = (char*)omap_bo_map(m_input_bo);
    	memcpy(input, data, len);	
    
    	m_inArgs->inputID = (XDAS_Int32)buf;
    	m_outBufs->descs[0].buf = (XDAS_Int8*)buf->fd[0];
    	m_outBufs->descs[1].buf = (XDAS_Int8*)((m_outBufs->descs[0].buf));
    
    	m_outBuf_fd[0] = buf->fd[0];
    	dce_buf_lock(1, m_outBuf_fd);
    
    	m_outBufs->descs[0].bufSize.bytes = m_padded_width*m_padded_height;
    	m_outBufs->descs[1].bufSize.bytes = m_padded_width*m_padded_height/2;
    
    	XDAS_Int32 err = VIDDEC3_process(m_codec, m_inBufs, m_outBufs, m_inArgs, m_outArgs);
    
    	RetriveData();
    
    /*	if (err != 0) 
    	{
    		ERROR("process returned error: %d", err);
    		return false;
    	}
    */
    	return true;
    }
    
    void Decoder::Flush()
    {
    //	printf("Flush...\n");
    	VIDDEC3_Status* status = (IVIDDEC3_Status*)dce_alloc(sizeof(IVIDDEC3_Status));
    	status->size = sizeof(IVIDDEC3_Status);
    	VIDDEC3_control(m_codec, XDM_FLUSH, m_dynParams, status);
    	dce_free(status);
    
    	m_inBufs->numBufs = 0;
    	m_outBufs->numBufs = 0;
    	m_inArgs->inputID = 0;
    
    	while(true)
    	{
    		if(VIDDEC3_process(m_codec, m_inBufs, m_outBufs, m_inArgs, m_outArgs) != 0)
    			break;
    
    		RetriveData();	
    	}
    }
    
    void Decoder::RetriveData()
    {
    	struct Buffer* buf;
    	int freeBufCount = 0;
    
    	for (int i = 0; m_outArgs->outputID[i]; i++) 
    	{
    		// calculate offset to region of interest 
    		XDM_Rect *r = &(m_outArgs->displayBufs.bufDesc[0].activeFrameRegion);
    
    		// get the output buffer and render it
    		buf = (struct Buffer *)m_outArgs->outputID[i];
    
    		disp_post_vid_buffer(m_disp, buf, r->topLeft.x, r->topLeft.y, r->bottomRight.x - r->topLeft.x, r->bottomRight.y - r->topLeft.y);
    
    	//	printf("rect = %d %d %d %d\n",r->topLeft.x, r->topLeft.y, r->bottomRight.x - r->topLeft.x, r->bottomRight.y - r->topLeft.y);
    	}
    
    	for (int i = 0; m_outArgs->freeBufID[i]; i++)
    	{
    		buf = (struct Buffer *)m_outArgs->freeBufID[i];
    		disp_put_vid_buffer(m_disp, buf);
    
    		m_outBuf_fd[freeBufCount++] = buf->fd[0];
    	}
    
    	if(freeBufCount != 0)
    		dce_buf_unlock(freeBufCount,m_outBuf_fd);
    }
    
    void main()
    {
    	
    	/*video stream which mobile phone mirror video ransport by usb ,we are do some init usb and connect phone  work before decoderopen*/
    	DecoderOpen(1552,576,0,0,1552,576);
    	/*Transfer mirrored video stream  to callback function */
    	Decode(data, len);
    	
    	
    }
    
    

  • Hi xinyang,
    We haven't seen this issue with default viddec3test. I have observed double free corruption error sometimes with waylandsink backend when --fps option was not used.
    Please revert this patch and give a try.
    git.ti.com/.../6f4fe30726e09f0116b62cf959f0ff15954e4a6b

    Thanks
    Ramprasad