您的位置:首页 > 其它

如何读一个H264文件,将数据转换到DM8127或DM8168的Bitstream_BufList

2014-11-11 10:57 851 查看
 问题如下:

Receiving encoded stream from network via RTSPClient and decode those stream. I just know copy the encoded stream from the network intoBitstream_Buf->addr and I don't know how to initialize (fill up) all fields of Bitstream_Buf before put
them to the decoder by calling the function IpcBitsOutLink_putFullVideoBitStreamBufs. 

 

 

Bitstream_BufList定义如下:

 

/*******************************************************************************
*                                                                             *
*  Copyright (c) 2011 Texas Instruments Incorporated - http://www.ti.com/     *
*                        ALL RIGHTS RESERVED                                  *
*                                                                             *
******************************************************************************/

/**
\ingroup LINK_API
\defgroup VIDBITSTREAM Video Bitstream data structure definition

This file defines the data structure representing an encoded video frame's
bitstream object

@{
*/

/**
\file vidbitstream.h
\brief Definition of encoded video bitstream data structures
*/

#ifndef _VIDBITSTREAM_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define _VIDBITSTREAM_H_

/**
* @brief  Buffer alignment needed for IVA-HD codecs
*/

#ifdef TI_8107_BUILD
#define  IVACODEC_VDMA_BUFFER_ALIGNMENT                                    (128)
#else
#define  IVACODEC_VDMA_BUFFER_ALIGNMENT                                    (32)
#endif
/**
* @def    VIDBITSTREAM_MAX_BITSTREAM_BUFS
* @brief  Maximum number of bitstream buf in a Bitstream_BufList @sa Bitstream_BufList
*/
#define VIDBITSTREAM_MAX_BITSTREAM_BUFS  (64)

/**
\brief Bit stream buffer
*/
typedef struct Bitstream_Buf {
UInt32 reserved[2];
/**< First two 32 bit entries are reserved to allow use as Que element */
void *addr;
/**< Buffer Pointer */
UInt32 bufSize;
/**< Size of the buffer */
UInt32 fillLength;
/**< Filled lengh from start offset */
UInt32 startOffset;
/**< Start offset */
UInt32 mvDataOffset;
/**< Actual offset to mv data bistream in buffer, in bytes */
UInt32 mvDataFilledSize;
/**< Actual size of mv data bistream in buffer, in bytes */
UInt32 channelNum;
/**< Channel number */
UInt32 codingType;
/**< Coding type */
void *appData;
/**< Additional application parameter per buffer */

UInt32 timeStamp;
/**< Original Capture time stamp */

UInt32 temporalId;
/**< SVC TemporalId */

UInt32 upperTimeStamp;
/**< Original Capture time stamp:Upper 32 bit value*/
UInt32 lowerTimeStamp;
/**< Original Capture time stamp: Lower 32 bit value*/
UInt32 encodeTimeStamp;
/**< Encode complete time stamp */

UInt32 isKeyFrame;
/**< Flag indicating whether is currentFrame is key frame */
UInt32 allocPoolID;
/**< Pool frame from which buf was originally alloced */
UInt32 phyAddr;
/**< Physical address of the buffer */
UInt32 frameWidth;
/**< Width of the encoded frame */
UInt32 frameHeight;
/**< Height of the encoded frame */
UInt32 doNotDisplay;
/**< Flag indicating frame should not be displayed
*   This is useful when display should start from a
*   particular frame.
*   This is temporary until Avsync suuports seek functionality*/
UInt32 bottomFieldBitBufSize;
/**< Size of the bottom field Bitstream. Filled by field Merged
interlaced encoders     */
} Bitstream_Buf;

/**
*  \brief Bit stream Buffer List used to exchange multiple Bitstream Buffers
*         between links
*/
typedef struct
{
Bitstream_Buf       *bufs[VIDBITSTREAM_MAX_BITSTREAM_BUFS];
/**< Array of Bitstream_Buf pointers that are to given or received from the
codec. */

UInt32              numBufs;
/**< Number of frames that are given or received from the codec
i.e number of valid pointers in the array containing Bitstream_Buf
pointers. */

void                *appData;
/**< Additional application parameter per buffer list */

} Bitstream_BufList;

#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _VIDBITSTREAM_H_*/

/** @}*/


 

dm8127下有个例子:

 

Void *MultiCh_ipcBitsMain(Void *prm)

{

    UInt32 i;

 OSA_DmaCopy1D copy1D;

 Bitstream_BufList fullBitsBufList;

 Bitstream_BufList emptyBitsBufList;

 IpcBitsOutLinkHLOS_BitstreamBufReqInfo ipcReqInfo;

 OSA_printf("Entered IPC Bits Handler function\n");

 gIpcBitsThObj.exitTh   = FALSE;

 gIpcBitsThObj.exitDone = FALSE;

 while(gIpcBitsThObj.exitTh == FALSE)

 {

  OSA_semWait(&gIpcBitsNotifySem,OSA_TIMEOUT_FOREVER);

  IpcBitsInLink_getFullVideoBitStreamBufs(gIpcBitsInHLOSId,&fullBitsBufList);

  ipcReqInfo.numBufs = fullBitsBufList.numBufs;

  for(i = 0;i < ipcReqInfo.numBufs;i++)

  {

   ipcReqInfo.minBufSize[i] = DEC_MIN_BUF_SIZE;

  }

  if(IpcBitsOutLink_getEmptyVideoBitStreamBufs(gIpcBitsOutHLOSId,&emptyBitsBufList,&ipcReqInfo) == IPC_BITSOUT_LINK_S_SUCCESS)

  {

   emptyBitsBufList.numBufs = fullBitsBufList.numBufs;

   for(i = 0;i < fullBitsBufList.numBufs;i++)

   {

    if((Int32)emptyBitsBufList.bufs[i]->addr & 0x80000000)

    {

     goto skip;

    }

    emptyBitsBufList.bufs[i]->channelNum = fullBitsBufList.bufs[i]->channelNum;

    emptyBitsBufList.bufs[i]->fillLength = fullBitsBufList.bufs[i]->fillLength;

    emptyBitsBufList.bufs[i]->timeStamp  = fullBitsBufList.bufs[i]->timeStamp;

    if(gDmaHndl.chId == 0xFF)

    {

     memcpy(emptyBitsBufList.bufs[i]->addr,

         (fullBitsBufList.bufs[i]->addr + fullBitsBufList.bufs[i]->startOffset),

         fullBitsBufList.bufs[i]->fillLength);

    }

    else

    {

     copy1D.srcPhysAddr = (unsigned long)CMEM_getPhys(fullBitsBufList.bufs[i]->addr + fullBitsBufList.bufs[i]->startOffset);

     copy1D.dstPhysAddr = (unsigned long)CMEM_getPhys(emptyBitsBufList.bufs[i]->addr);

     copy1D.size        = fullBitsBufList.bufs[i]->fillLength;

     OSA_dmaCopy1D(&gDmaHndl,©1D,1);

    }

   }

   IpcBitsOutLink_putFullVideoBitStreamBufs(gIpcBitsOutHLOSId,&emptyBitsBufList);

  }

skip:

  IpcBitsInLink_putEmptyVideoBitStreamBufs(gIpcBitsInHLOSId,&fullBitsBufList);

 }

 gIpcBitsThObj.exitDone = TRUE;

 OSA_printf("Exiting IPC Bits Handler function\n");

    return NULL;

}

 

参考这个例子:将h264数据送到videoM3解码时,出现错误;

1)在videoM3解码有问题,错误码为0x2000a00, 通过查找TI的文档,该错误码是一个32位,表示32个错误,此错误码表示第9,11,25位对应为1;

错误如下:

XDM_APPLIEDCONCEALMENT :Applied concealment;

XDM_CORRUPTEDDATA :    Data problem/corruption;

IH264VDEC_ERR_MISSINGSLICE: one or more slices are completely missing in this picture;

 

因为使用的视频是用海康相机录的,使用海康工具将视频文件转换为标准h264文件,然后ultraEdit裁剪到0x00 00 00 01 67 前的数据,解决;

 

2)dm8148,我将h264数据送入videoM3 解码时,出错; if(IpcBitsOutLink_getEmptyVideoBitStreamBufs(IPCBITOUTHOSTTOVIDM3ID,&emptyBitsBufList,&ipcReqInfo) == IPC_BITSOUT_LINK_S_SUCCESS) dm8127 这个地方获取的地址emptyBitsBufList有时有问题,获取的是物理地址了,本来是虚拟地址的; 有人知道原因吗?

 
调试日志:

 [host] ###Bit buff of size from the SR # 1 : 2073600

 [host] IPC_BITSOUT:BitBuffer Alloc.PoolID:0,Size:0x1FA400

 [host] IPCBITSOUTLINK:Translated Addr Virt:0x4189d080 To Phy:0x90000080

从这里看0x4189d080是虚拟地址,而 0x90000080是物理地址;

平时正常跑的时候,获取的地址是0x4189d080,而有时,获取的地址是0x90000080,然后拷贝了数据就出错了。

 

产生原因:

1)可能是由于读264文件时,IPCBitoutlink还未初始化;

解决办法:使用0x80000000过滤掉,另外当下面条件成立时,emptyBitsBufList的buff数可能为0,所以if语句中应该加一个条件过滤(emptyBitsBufList.numBufs>0)

 if(IpcBitsOutLink_getEmptyVideoBitStreamBufs(IPCBITOUTHOSTTOVIDM3ID,&emptyBitsBufList,&ipcReqInfo) == IPC_BITSOUT_LINK_S_SUCCESS) 

 

 

3)出现decLink_h264.c[333]::INTERNAL ERROR: -1 ALGPROCESS FAILED :STATUS

 [m3video] 1356708:DECLINK::links_m3video/iva_dec/decLink_h264.c:[333]::INTERNAL ERROR:-1

 [m3video] ALGPROCESS FAILED:STATUS

 [m3video] outArgs->viddec3OutArgs.extendedError for channel 0 Error: 0x1021

 [m3video] Sequence called number 11680

 [m3video] 1356804:DECLINK::links_m3video/iva_dec/decLink_h264.c:[333]::INTERNAL ERROR:-1

 [m3video] ALGPROCESS FAILED:STATUS

 [m3video] outArgs->viddec3OutArgs.extendedError for channel 0 Error: 0x1021

 [m3video] Sequence called number 11681

 

 [m3video] 1377791:DECLINK::links_m3video/iva_dec/decLink_h264.c:[333]::INTERNAL ERROR:-1

 [m3video] ALGPROCESS FAILED:STATUS

 [m3video] outArgs->viddec3OutArgs.extendedError for channel 0 Error: 0x401

 

 在dm8168 的demo_decode.c文件中有;

/*----------------------------------------------------------------------------*/

/* Error strings which are mapped to codec errors                             */

/* Please refer User guide for more details on error strings                  */

/*----------------------------------------------------------------------------*/

static sEnumToStringMapping gDecoderErrorStrings[32] =

{

  {(char *)"IH264VDEC_ERR_NOSLICE : 0, \0"},

  {(char *)"IH264VDEC_ERR_SPS : 1,"},

  {(char *)"IH264VDEC_ERR_PPS : 2,\0"},

  {(char *)"IH264VDEC_ERR_SLICEHDR : 3,\0"},

  {(char *)"IH264VDEC_ERR_MBDATA : 4,\0"},

  {(char *)"IH264VDEC_ERR_UNAVAILABLESPS : 5,\0"},

  {(char *)"IH264VDEC_ERR_UNAVAILABLEPPS  : 6,\0"},

  {(char *)"IH264VDEC_ERR_INVALIDPARAM_IGNORE : 7\0"},

  {(char *)"XDM_PARAMSCHANGE : 8,\0"},

  {(char *)"XDM_APPLIEDCONCEALMENT : 9,\0"},

  {(char *)"XDM_INSUFFICIENTDATA : 10,\0"},

  {(char *)"XDM_CORRUPTEDDATA : 11,\0"},

  {(char *)"XDM_CORRUPTEDHEADER : 12,\0"},

  {(char *)"XDM_UNSUPPORTEDINPUT : 13,\0"},

  {(char *)"XDM_UNSUPPORTEDPARAM : 14,\0"},

  {(char *)"XDM_FATALERROR : 15\0"},

  {(char *)"IH264VDEC_ERR_UNSUPPFEATURE : 16,\0"},

  {(char *)"IH264VDEC_ERR_METADATA_BUFOVERFLOW : 17,\0"},

  {(char *)"IH264VDEC_ERR_STREAM_END : 18,\0"},

  {(char *)"IH264VDEC_ERR_NO_FREEBUF : 19,\0"},

  {(char *)"IH264VDEC_ERR_PICSIZECHANGE : 20,\0"},

  {(char *)"IH264VDEC_ERR_UNSUPPRESOLUTION : 21,\0"},

  {(char *)"IH264VDEC_ERR_NUMREF_FRAMES : 22,\0"},

  {(char *)"IH264VDEC_ERR_INVALID_MBOX_MESSAGE : 23,\0"},

  {(char *)"IH264VDEC_ERR_DATA_SYNC : 24,\0"},

  {(char *)"IH264VDEC_ERR_MISSINGSLICE : 25,\0"},

  {(char *)"IH264VDEC_ERR_INPUT_DATASYNC_PARAMS : 26,\0"},

  {(char *)"IH264VDEC_ERR_HDVICP2_IMPROPER_STATE : 27,\0"},

  {(char *)"IH264VDEC_ERR_TEMPORAL_DIRECT_MODE : 28,\0"},

  {(char *)"IH264VDEC_ERR_DISPLAYWIDTH : 29,\0"},

  {(char *)"IH264VDEC_ERR_NOHEADER : 30,\0"},

  {(char *)"IH264VDEC_ERR_GAPSINFRAMENUM : 31, \0"}

};

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐