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/DRA725: decoder can get width and height from the h.264 head

Part Number: DRA725


Tool/software: Linux

Hi,

    the decoder read width and height  from the h.264 head, how to config the decoder  on the viddec3test.c example.  

   

   Regards,

   Cesar

  • Hi Cesar,
    This question is answered here.
    e2e.ti.com/.../636061

    Ram
  • Hi Ram,

    i read the doc,
    1. Decoder_Create
    2. Control call (XDM_SETPARAMS) to configure decoder in parse
    header mode
    3. Process call to decoder which shall decode SPS+PPS
    4. Control call (XDM_GETBUFINFO) to understand buffer
    requirements
    5. Allocate buffers of size exactly needed to decode this particular bit
    stream
    6. Control call (XDM_SETPARAMS) to configure decoder in normal
    mode (dynamicParams->decodeHeader = XDM_DECODE_AU)
    7. Process calls to decode frames

    but i only know modify the HEAD config :
    decoder->dynParams->decodeHeader = XDM_PARSE_HEADER;

    I don't know what to do next, can you offer the sample code.
    thanks.

    Regards,
    Cesar
  • Hi Cesar,

    viddec3test's decoder_open() function does all of these except XDM_PARSE_HEADER support. You can have a look.

  • Hi Ram,
    1. Decoder_Create

      it config pdecParams,  how fill in  pdecParams.

       pdecParams->maxWidth = width;
       pdecParams->maxHeight = height;


    decoder->codec = VIDDEC3_create(decoder->engine, "ivahd_h264dec", (VIDDEC3_Params*)decoder->h264params);


    Regards,

    Cesar

  • You need to set maxWidth and maxHeight to maximum supported. You can set these to 1920 and 1080 respectively

    pdecParams->maxWidth = 1920;
    pdecParams->maxHeight = 1080;
  • Hi Ram,

     modify decoder_open  :

    pdecParams->maxWidth = 1920;

    pdecParams->maxHeight = 1080;

    decoder->dynParams->decodeHeader  = XDM_PARSE_HEADER;

    execut :

    ./h264dectest_frame -s 32:1920x1080 test1.264 -frame frame1.txt -W 720 -H 480

    the error:

    Regards,

    Cesar

  • Hi Cesar,
    I didn't get your requirement. In the application here you are still using -W and -H option to set the width and height.
    Application needs to set maxWidth and maxHeight and create the decoder instance. Then to know the actual width and height, PARSE_HEADER needs to be set.

    Please give more details or share your modified h264dectest
  • Hi Ram,

    the h264dectest_frame.c 

    /*
     * Copyright (C) 2012 Texas Instruments
     * Author: Rob Clark <rob.clark@linaro.org>
     *
     * This program is free software; you can redistribute it and/or modify it
     * under the terms of the GNU General Public License version 2 as published by
     * the Free Software Foundation.
     *
     * This program is distributed in the hope that it will be useful, but WITHOUT
     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     * more details.
     *
     * You should have received a copy of the GNU General Public License along with
     * this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <libdce.h>
    #include <xf86drm.h>
    #include <omap_drm.h>
    #include <omap_drmif.h>
    
    #include <pthread.h>
    
    #include "util.h"
    
    #include <ti/sdo/codecs/h264vdec/ih264vdec.h>
    
    /* Used for mpeg4 esds data copy */
    int first_in_buff = 0;
    
    
    /* Padding for width as per Codec Requirement (for h264) */
    #define PADX  32
    /* Padding for height as per Codec requirement (for h264)*/
    #define PADY  24
    
    
    /* omap drm device handle */
    struct omap_device *dev = NULL;
    
    struct decoder {
    	struct display *disp;
    	struct buffer *framebuf;
    	Engine_Handle engine;
    	VIDDEC3_Handle codec;
    	IH264VDEC_Params *h264params;
    	VIDDEC3_DynamicParams *dynParams;
    	VIDDEC3_Status *status;
    	XDM2_BufDesc *inBufs;
    	XDM2_BufDesc *outBufs;
    	VIDDEC3_InArgs *inArgs;
    	VIDDEC3_OutArgs *outArgs;
    	char *input;
    	struct omap_bo *input_bo;
    	int input_sz, uv_offset;
    	int padded_width;
    	int padded_height;
    	int num_outBuf;
    	FILE* inFile;
        FILE* frameLen;
    	size_t *outBuf_fd;
    	suseconds_t tdisp;
    	struct buffer *lastOutBuf;
    	int need_out_buf;
    };
    
    /* When true, do not actually call VIDDEC3_process. For benchmarking. */
    static int no_process = 0;
    static int inloop = 0;
    
    /* When true, loop at end of playback. */
    static int loop = 0;
    
    static void
    usage(char *name)
    {
    
    	MSG("Usage: %s [OPTIONS] INFILE -frame frame.txt -W width -H height\n", name);
        MSG("Example: %s -s 4:800x480 test.h264 -frame frame.txt -W 1280 -H 720 \n", name);
    	MSG("Test of h264 decoder.");
    	MSG("");
    	MSG("vc1dectest options:");
    	MSG("\t-h, --help: Print this help and exit.");
    	MSG("\t--loop\tRestart playback at end of stream.");
    	MSG("\t--inloop\tRestart playback at end of stream along with decoder reinitialization.");
    	MSG("\t--no-process\tDo not actually call VIDDEC3_process method. For benchmarking.");
    	MSG("");
    	disp_usage();
    }
    
    static void
    decoder_close(struct decoder *decoder)
    {
    
    	MSG("Closing decoder %p\n", decoder);
    	if(!decoder) return;
    	/* free output buffers allocated by display */
    	if(inloop < 2 && decoder->disp) disp_free_buffers(decoder->disp,decoder->num_outBuf);
    
    	if (decoder->status)         dce_free(decoder->status);
    	if (decoder->h264params)         dce_free(decoder->h264params);
    	if (decoder->dynParams)      dce_free(decoder->dynParams);
    	if (decoder->inBufs) {
    		dce_buf_unlock(1, &(decoder->inBufs->descs[0].buf));
    		close(decoder->inBufs->descs[0].buf);
    		dce_free(decoder->inBufs);
    	}
    	if (decoder->outBufs)        dce_free(decoder->outBufs);
    	if (decoder->inArgs)         dce_free(decoder->inArgs);
    	if (decoder->outArgs)        dce_free(decoder->outArgs);
    	if (decoder->codec)          VIDDEC3_delete(decoder->codec);
    	if (decoder->engine)         Engine_close(decoder->engine);
    	if (decoder->input_bo)       omap_bo_del(decoder->input_bo);
    	if (decoder->outBuf_fd)	     free(decoder->outBuf_fd);
    	if(inloop < 2) {
    		if (dev)		             dce_deinit(dev);
    	if (decoder->disp)           disp_close(decoder->disp);
    		if(decoder) free(decoder);
    	}
    }
    
    static struct decoder *
    decoder_open(int argc, char **argv)
    {
    	static struct decoder *decoder = NULL;
    	char *infile = NULL;
    	int i;
    	static int width, height, padded_width, padded_height;
    	Engine_Error ec;
    	XDAS_Int32 err;
    	VIDDEC3_Params* pdecParams;
    
        if(inloop < 2) {
    	decoder = calloc(1, sizeof(*decoder));
    	if (!decoder)
    		return NULL;
    
    	MSG("%p: Opening Display..", decoder);
    	decoder->disp = disp_open(argc, argv);
    	if (!decoder->disp)
    		goto usage;
    
    	/* loop thru args, find input file.. */
    	for (i = 1; i < argc; i++) {
    		int fd;
    		if (!argv[i]) {
    			continue;
    		}
    		fd = open(argv[i], 0);
    		if (fd > 0) {
    			infile = argv[i];
    			decoder->inFile = fopen(argv[i], "rb");
                    if(!decoder->inFile)
                        printf("could not open input stream file\n");
    			argv[i] = NULL;
    			close(fd);
    			break;
    		}
    		break;
    	}
    
    	  for(i = 1; i < argc; i++){
             if(!argv[i])
                   continue;
    
                if(!strcmp(argv[i],"-frame")){
                    decoder->frameLen = fopen(argv[i+1],"r");
                    if(!decoder->frameLen)
                         MSG("could not open framelength file\n");
                    if(decoder->frameLen ){
                        argv[i] = NULL;
                        argv[i+1] = NULL;
                    }
    
                        continue;
                }
                if(!strcmp(argv[i],"-W")){
                    argv[i] = NULL;
                    width = atoi(argv[i+1]);
                    argv[i+1] = NULL;
                    continue;
                }
                if(!strcmp(argv[i], "-H")){
                    argv[i] = NULL;
                    height = atoi(argv[i+1]);
                    argv[i+1] = NULL;
                }
         }
    	if (check_args(argc, argv) || !infile)
    		goto usage;
    	/* calculate output buffer parameters: */
    	width  = ALIGN2 (width, 4);        /* round up to macroblocks */
    	height = ALIGN2 (height, 4);       /* round up to macroblocks */
    
    
        padded_width  = ALIGN2 (width + (2*PADX), 7);
        padded_height = height + 4*PADY;
    
    	decoder->num_outBuf   = MIN(16, 32768 / ((width/16) * (height/16))) + 3;
    	decoder->padded_width = padded_width;
    	decoder->padded_height = padded_height;
    	MSG("%p: padded_width=%d, padded_height=%d, num_buffers=%d",
    			decoder, padded_width, padded_height, decoder->num_outBuf);
    		dce_set_fd(decoder->disp->fd);
    		dev = dce_init();
    		if(dev == NULL) {
    			ERROR("%p: dce init failed", dev);
    			goto fail;
    		}
    		decoder->framebuf = disp_get_fb(decoder->disp);
    		if (! disp_get_vid_buffers(decoder->disp, decoder->num_outBuf,
    				FOURCC_STR("NV12"), decoder->padded_width, decoder->padded_height)) {
    			ERROR("%p: could not allocate buffers", decoder);
    			goto fail;
    		}
    		if(inloop) inloop = 2; /*Don't bother about looping if not asked to*/
        }
    
    	if (!decoder->disp->multiplanar) {
    		decoder->uv_offset = padded_width * padded_height;
    		decoder->outBuf_fd = malloc(sizeof(int)*decoder->num_outBuf);
    		MSG("%p: uv_offset=%d", decoder, decoder->uv_offset);
    	}
    	else{
    		decoder->outBuf_fd = malloc(sizeof(int)*(decoder->num_outBuf*2));
    	}
    
    	decoder->input_sz = width * height;
    	decoder->input_bo = omap_bo_new(decoder->disp->dev,
    			decoder->input_sz, OMAP_BO_WC);
    	decoder->input = omap_bo_map(decoder->input_bo);
    
    	MSG("%p: Opening Engine..", decoder);
    	decoder->engine = Engine_open("ivahd_vidsvr", NULL, &ec);
    	if (!decoder->engine) {
    		ERROR("%p: could not open engine", decoder);
    		goto fail;
    	}
    
    	decoder->h264params = dce_alloc(sizeof(IH264VDEC_Params));
        pdecParams = &(decoder->h264params->viddec3Params);
        pdecParams->size = sizeof(IH264VDEC_Params);
    //    pdecParams->size = sizeof(IVIDDEC3_Params);
    
    	pdecParams->maxWidth         = 1280;
    	pdecParams->maxHeight        = 720;
    	pdecParams->maxFrameRate     = 30000;
    	pdecParams->maxBitRate       = 10000000;
    	pdecParams->dataEndianness   = XDM_BYTE;
    	pdecParams->forceChromaFormat= XDM_YUV_420SP;
    	pdecParams->operatingMode    = IVIDEO_DECODE_ONLY;
    	pdecParams->displayDelay     = IVIDDEC3_DECODE_ORDER;/*no delay*/ //IVIDDEC3_DISPLAY_DELAY_AUTO;
    	pdecParams->displayBufsMode  = IVIDDEC3_DISPLAYBUFS_EMBEDDED;
    	pdecParams->inputDataMode    = IVIDEO_ENTIREFRAME;
    	pdecParams->metadataType[0]  = IVIDEO_METADATAPLANE_NONE;
    	pdecParams->metadataType[1]  = IVIDEO_METADATAPLANE_NONE;
    	pdecParams->metadataType[2]  = IVIDEO_METADATAPLANE_NONE;
    	pdecParams->numInputDataUnits= 1;
    	pdecParams->outputDataMode   = IVIDEO_ENTIREFRAME;
    	pdecParams->numOutputDataUnits = 1;
    	pdecParams->errorInfoMode    = IVIDEO_ERRORINFO_OFF;
    
    
        decoder->h264params->dpbSizeInFrames  = IH264VDEC_DPB_NUMFRAMES_DEFAULT;
        decoder->h264params->pConstantMemory  = NULL;
        decoder->h264params->bitStreamFormat  = IH264VDEC_BYTE_STREAM_FORMAT;
        decoder->h264params->errConcealmentMode = IH264VDEC_APPLY_CONCEALMENT;
        decoder->h264params->temporalDirModePred = IH264VDEC_ENABLE_TEMPORALDIRECT;
        decoder->h264params->svcExtensionFlag = IH264VDEC_DISABLE_SVCEXTENSION;
        decoder->h264params->svcTargetLayerDID = IH264VDEC_TARGET_DID_DEFAULT;
        decoder->h264params->svcTargetLayerTID = IH264VDEC_TARGET_TID_DEFAULT;
        decoder->h264params->svcTargetLayerQID = IH264VDEC_TARGET_QID_DEFAULT;
        decoder->h264params->presetLevelIdc    = IH264VDEC_LEVEL41;
        decoder->h264params->presetProfileIdc    = 0;
        decoder->h264params->detectCabacAlignErr = IH264VDEC_DISABLE_CABACALIGNERR_DETECTION;
        decoder->h264params->detectIPCMAlignErr  = IH264VDEC_DISABLE_IPCMALIGNERR_DETECTION;
        decoder->h264params->debugTraceLevel     = IH264VDEC_DEBUGTRACE_LEVEL0;
        decoder->h264params->lastNFramesToLog = 0;
        decoder->h264params->enableDualOutput = IH264VDEC_DUALOUTPUT_DISABLE;
        decoder->h264params->enableWatermark  = IH264VDEC_WATERMARK_DISABLE;
        decoder->h264params->decodeFrameType  =  IH264VDEC_DECODE_ALL;
        decoder->h264params->processCallLevel = IH264VDEC_FRAMELEVELPROCESSCALL;
        decoder->h264params->processCallLevel = IH264VDEC_FIELDLEVELPROCESSCALL;
    
    
    
    	MSG("maxWidth = %d maxHeight = %d ",decoder->h264params->viddec3Params.maxWidth,decoder->h264params->viddec3Params.maxHeight);
        decoder->codec = VIDDEC3_create(decoder->engine,
                                            "ivahd_h264dec", (VIDDEC3_Params*)decoder->h264params);
    
    	if (!decoder->codec) {
    		ERROR("%p: could not create codec", decoder);
    		goto fail;
    	}
    
    	decoder->dynParams = dce_alloc(sizeof(IVIDDEC3_DynamicParams));
    	decoder->dynParams->size = sizeof(IVIDDEC3_DynamicParams);
    
    	decoder->dynParams->decodeHeader  = XDM_PARSE_HEADER;//XDM_DECODE_AU;
    
    	/*Not Supported: Set default*/
    	decoder->dynParams->displayWidth  = 0;
    	decoder->dynParams->frameSkipMode = IVIDEO_NO_SKIP;
    	decoder->dynParams->newFrameFlag  = XDAS_TRUE;
    	decoder->dynParams->lateAcquireArg  = -1;
    
    
    	decoder->status = dce_alloc(sizeof(IVIDDEC3_Status));
    	decoder->status->size = sizeof(IVIDDEC3_Status);
    
    	err = VIDDEC3_control(decoder->codec, XDM_SETPARAMS,
    			decoder->dynParams, decoder->status);
    	if (err) {
    		ERROR("%p: fail: %d", decoder, err);
    		goto fail;
    	}
    	/* not entirely sure why we need to call this here.. just copying omx.. */
    	err = VIDDEC3_control(decoder->codec, XDM_GETBUFINFO,
    			decoder->dynParams, decoder->status);
    	if (err) {
    		ERROR("%p: fail: %d", decoder, err);
    		goto fail;
    	}
    	printf("decoder->dynParams->displayWidth = %d\n",decoder->dynParams->displayWidth);
    	
    
    	decoder->inBufs = dce_alloc(sizeof(XDM2_BufDesc));
    	decoder->inBufs->numBufs = 1;
    	decoder->inBufs->descs[0].buf =	(XDAS_Int8 *)omap_bo_dmabuf(decoder->input_bo);
    	dce_buf_lock(1, &(decoder->inBufs->descs[0].buf));
    	decoder->inBufs->descs[0].bufSize.bytes = omap_bo_size(decoder->input_bo);
    	decoder->inBufs->descs[0].memType = XDM_MEMTYPE_RAW;
    
    
    	decoder->outBufs = dce_alloc(sizeof(XDM2_BufDesc));
    	decoder->outBufs->numBufs = 2;
    	decoder->outBufs->descs[0].memType = XDM_MEMTYPE_RAW;
    	decoder->outBufs->descs[1].memType = XDM_MEMTYPE_RAW;
    
    	decoder->inArgs = dce_alloc(sizeof(IVIDDEC3_InArgs));
    	decoder->inArgs->size = sizeof(IVIDDEC3_InArgs);
    
    	decoder->outArgs = dce_alloc(sizeof(IVIDDEC3_OutArgs));
    	decoder->outArgs->size = sizeof(IVIDDEC3_OutArgs);
    
    	decoder->need_out_buf = XDAS_TRUE;
    	decoder->tdisp = mark(NULL);
    
    	return decoder;
    
    usage:
    	usage(argv[0]);
    fail:
    	if(inloop) inloop = 1; /*Error case: delete everything*/
    	if (decoder)
    		decoder_close(decoder);
    	return NULL;
    }
    
    
    static int
    decoder_start(struct decoder *decoder)
    {
    	XDM2_BufDesc *inBufs = decoder->inBufs;
    	XDM2_BufDesc *outBufs = decoder->outBufs;
    	VIDDEC3_InArgs *inArgs = decoder->inArgs;
    	VIDDEC3_OutArgs *outArgs = decoder->outArgs;
    	struct buffer *buf;
    	int freeBufCount =0;
    	int i, n,bytes;
    	XDAS_Int32 err;
    	int eof = 0; /* end of file flag */
    
    	buf = disp_get_vid_buffer(decoder->disp);
    	if (!buf) {
    		ERROR("%p: fail: out of buffers", decoder);
    		return -1;
    	}
    
    	fscanf(decoder->frameLen,"%ld",&bytes ); 
    	inBufs->descs[0].bufSize.bytes = bytes;
    	inArgs->numBytes = bytes;
    	n = fread(decoder->input,sizeof(char), bytes, decoder->inFile);
    	printf("%p: push: %d bytes\n", decoder, n);
    
        
    	inArgs->inputID = (XDAS_Int32)buf;		
    	outBufs->descs[0].buf = buf->fd[0];
    	outBufs->descs[1].buf = (buf->multiplanar) ?buf->fd[1]:(XDAS_Int8 *)((outBufs->descs[0].buf));
    	inBufs->numBufs = 1;
    	outBufs->numBufs = 2;
    
    	err = VIDDEC3_process(decoder->codec, inBufs, outBufs, inArgs, outArgs);
    	printf("bytesConsumed %d\n", outArgs->bytesConsumed);
    
    	if (err) {
    		ERROR("%p: process returned error: %d", decoder, err);
    		ERROR("%p: extendedError: %08x", decoder, outArgs->extendedError);		
    	}		
    	err = VIDDEC3_control(decoder->codec, XDM_GETSTATUS,
    				decoder->dynParams, decoder->status);
    	if (err) {
    		ERROR("%p: fail: %d", decoder, err);
    		return -1;
    	}
    	printf("++++++++++++++++++++++++++++++++++++++decoder->status->outputWidth = %d\n",decoder->status->outputWidth);
    	
    	return 0;		
    
    }
    
    
    static int
    decoder_process(struct decoder *decoder)
    {
    	XDM2_BufDesc *inBufs = decoder->inBufs;
    	XDM2_BufDesc *outBufs = decoder->outBufs;
    	VIDDEC3_InArgs *inArgs = decoder->inArgs;
    	VIDDEC3_OutArgs *outArgs = decoder->outArgs;
    	struct buffer *buf;
    	int freeBufCount =0;
    	int i, n,bytes;
    	XDAS_Int32 err;
    	int eof = 0; /* end of file flag */
    
    	if(decoder->need_out_buf == XDAS_TRUE){
    	    buf = disp_get_vid_buffer(decoder->disp);
    	    if (!buf) {
    		   ERROR("%p: fail: out of buffers", decoder);
    		   return -1;
    	  }
          decoder->lastOutBuf = buf;
    	 }
    	else{
    	   buf = decoder->lastOutBuf;
    	}
    
    	for (i = 0; i < 2; i++)
    	{
            n = fscanf(decoder->frameLen,"%ld",&bytes );
        	if (bytes != -1) {
    			inBufs->descs[0].bufSize.bytes = bytes;
    			inArgs->numBytes = bytes;
    			//printf("inBytes %d\n", bytes);
    			n = fread(decoder->input,bytes,sizeof(char), decoder->inFile);
    			DBG("%p: push: %d bytes (%p)", decoder, n, buf);
    
                if( bytes == 0)
                   eof = 1;
    
    		} else {
    			/* end of input.. do we need to flush? */
    			MSG("%p: end of input", decoder);
    
    			/* In loop mode: rewind and retry once. */
    			//if (loop && i == 0)
    			{
                    //fseek(decoder->inFile, 0, SEEK_SET);
    				//MSG("%p: rewound.", decoder);
    				//if(!inloop) continue;
    			}
    
    			eof = 1; /* set the flag for end of file to 1 */
    
    			/* Control call call with XDM_FLUSH command */
    			err = VIDDEC3_control(decoder->codec, XDM_FLUSH,
    					decoder->dynParams, decoder->status);
    			inBufs->numBufs = 0;
    			outBufs->numBufs = 0;
    			inArgs->inputID = 0;
                inArgs->numBytes = 0;
                outArgs->bytesConsumed = 0;
    		}
    		break;
    	}
    	
            /*set the parameters if it is not the end of file */
    	if (!eof) {
    		inArgs->inputID = (XDAS_Int32)buf;
    		
    		outBufs->descs[0].buf = buf->fd[0];
    		outBufs->descs[1].buf = (buf->multiplanar) ?buf->fd[1]:(XDAS_Int8 *)((outBufs->descs[0].buf));
    
    		if(decoder->need_out_buf == XDAS_TRUE){
    		if(buf->multiplanar){
    			decoder->outBuf_fd[0] = buf->fd[0];
    			decoder->outBuf_fd[1] = buf->fd[1];
    			dce_buf_lock(2,decoder->outBuf_fd);
    		}
    		else{
    			decoder->outBuf_fd[0] = buf->fd[0];
    			dce_buf_lock(1,decoder->outBuf_fd);
    			}
    		}
    		decoder->outBufs->descs[0].bufSize.bytes =decoder->padded_width*decoder->padded_height;
    		decoder->outBufs->descs[1].bufSize.bytes = decoder->padded_width* (decoder->padded_height/2);
    
    		inBufs->numBufs = 1;
    		outBufs->numBufs = 2;
    	}
    
    	do {
    		if (no_process) {
    			/* Do not process. This is for benchmarking. We need to "fake"
    			 * the outArgs. */
    			outArgs->outputID[0] = 0;
    			outArgs->freeBufID[0] = 0;
    			if(!eof) {
    			outArgs->outputID[0] = buf;
    			outArgs->freeBufID[0] = buf;
    			}
    			outArgs->outputID[1] = NULL;
    			outArgs->freeBufID[0] = buf;
    			outArgs->freeBufID[1] = NULL;
    			outArgs->outBufsInUseFlag = 0;
    
    		} else {
    			suseconds_t tproc;
    			tproc = mark(NULL);
    			err = VIDDEC3_process(decoder->codec, inBufs, outBufs, inArgs, outArgs);
    			printf("bytesConsumed %d\n", outArgs->bytesConsumed);
    			DBG("%p: processed returned in: %ldus", decoder, (long int)mark(&tproc));
    			if (err) {
    				ERROR("%p: process returned error: %d", decoder, err);
    				ERROR("%p: extendedError: %08x", decoder, outArgs->extendedError);
    				/*if (XDM_ISFATALERROR(outArgs->extendedError)){
    					ERROR("Fatal Error.. Exiting");
    					return -1;
    				}*/
    			}
    		}
    		
    		err = VIDDEC3_control(decoder->codec, XDM_GETSTATUS,
    					decoder->dynParams, decoder->status);
    			if (err) {
    				ERROR("%p: fail: %d", decoder, err);
    				return -1;
    			}
    			printf("++++++++++++++++++++++++++++++++++++++decoder->status->outputWidth = %d\n",decoder->status->outputWidth);
    
    	
    		for (i = 0; outArgs->outputID[i]; i++) {
    			printf("-----------------------------------get the output buffer\n");
    			/* calculate offset to region of interest */
    			XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion);
    			/* get the output buffer and write it to file */
    			buf = (struct buffer *)outArgs->outputID[i];
    			printf("----------------------------------end:-buf->fd[0] = %d\n",buf->fd[0]);
    			if(!no_process)
    			disp_post_vid_buffer(decoder->disp, buf,
    			r->topLeft.x, r->topLeft.y,
    					r->bottomRight.x - r->topLeft.x,
    					r->bottomRight.y - r->topLeft.y);
    		//printf("--x=%d,y=%d--------\n", r->bottomRight.x - r->topLeft.x, r->bottomRight.y - r->topLeft.y);
    		}
    
    
    		for (i = 0; outArgs->freeBufID[i]; i++) {
    			printf("---------------------------------------------------------------------------------------------freeBufID \n");
    			buf = (struct buffer *)outArgs->freeBufID[i];
    			disp_put_vid_buffer(decoder->disp, buf);
    
    			if(buf->multiplanar){
    				decoder->outBuf_fd[freeBufCount++] = buf->fd[0];
    				decoder->outBuf_fd[freeBufCount++] = buf->fd[1];
    			}
    			else{
    				decoder->outBuf_fd[freeBufCount++] = buf->fd[0];
    			}
    		}
    
    		if(freeBufCount)
    		{
    		//if(!eof)
    			dce_buf_unlock(freeBufCount,decoder->outBuf_fd);
    			freeBufCount =0;
    		}
    		if (outArgs->outBufsInUseFlag) {
    			decoder->need_out_buf = XDAS_FALSE;
    		}
           else{
             decoder->need_out_buf = XDAS_TRUE;
           }
    	} while ((err == 0) && eof && !no_process);
    
    
    	//return 0;
    	return (inBufs->numBufs > 0) ? 0 : -1;
    }
    
    void *decode_stream(void *decoderHandle)
    {
    	int ret = 0;
    	struct decoder *decoder = (struct decoder*)decoderHandle;
        int n = 0;
        if(!decoder) goto exit;
    
    	decoder_start(decoder);
    	decoder->dynParams->decodeHeader  = XDM_DECODE_AU;
    	
    	 VIDDEC3_control(decoder->codec, XDM_SETPARAMS,
    				decoder->dynParams, decoder->status);
    
        while((ret = decoder_process(decoder)) == 0);
        if((ret != -1 && ret != 0) && inloop) inloop = 1; /*Assuming Good case. Otherwise logic gets messy*/
        decoder_close(decoder);
    
    exit:
    	return NULL;
    }
    
    int
    main(int argc, char **argv)
    {
    	struct decoder *decoders[8] = {};
    	int i, first = 0, ndecoders = 0;
    
    	for (i = 1; i < argc; i++) {
    		if ( !strcmp(argv[i], "--help")) {
    			usage(argv[0]);
    			exit(0);
    
    		} else if (!strcmp(argv[i], "--loop")) {
    			loop = 1;
    			argv[i] = NULL;
    
    		} else if (!strcmp(argv[i], "--no-process")) {
    			no_process = 1;
    			argv[i] = NULL;
    
    		} else if (!strcmp(argv[i], "--inloop")) {
    			inloop = 1; // this means inloop is detected
    			DBG("detected inloop = %d\n", inloop);
    			loop = 1; //we want rewind as well
    			argv[i] = NULL;
    		} else if (!strcmp(argv[i], "--")) {
    			argv[first] = argv[0];
    			decoders[ndecoders++] = decoder_open(i - first, &argv[first]);
    			first = i;
    		}
    	}
    
    	argv[first] = argv[0];
    	argc = i - first;
    
    	if(ndecoders) decoders[ndecoders++] = decoder_open(argc ,&argv[first]);
    
    	if (ndecoders > 1) {
    		pthread_t threadIds[8];
    
    		for (i = 0; i < ndecoders; i++) {
    			if (decoders[i]) {
    				int ret = pthread_create(&threadIds[i], NULL,
    						&decode_stream, decoders[i]);
    				if (ret != 0)
    					ERROR("%p: creation of pthread, error: %d",
    							decoders[i], ret);
    				}
    			}
    
    		for (i = 0; i < ndecoders; i++) {
    			pthread_join(threadIds[i], NULL);
    		}
    	}
    	else {
    		int itr = 0;
    		do {
    			decoders[0] = decoder_open(argc, &argv[first]);
    			decode_stream(decoders[0]);
    			if (inloop) {
    				MSG("=================Iteration %d complete =============== %d\n", ++itr);
    			}
    		}while(inloop);
    	}
    
    	return 0;
    }
    

    modify:

    1.decoder_open function:

    pdecParams->maxWidth = 1280;
    pdecParams->maxHeight = 720;

    decoder->dynParams->decodeHeader  = XDM_PARSE_HEADER;

    2. i add the ' decoder_parse_head(decoder) ' function in '  decode_stream'

    execute:parse the 727 byte head, and outputWidth = 720;

    but i don't know read  head, how many bytes;

    Regards,

    Cesar

  • Yes, here 727 bytes is the header size(SPS/PPS). In PARSE_HEADER mode, decoder consumes only header bytes.
    REfer Appendix D Notes of h264decoder userGhide.