如何讀一個H264檔案,將資料轉換到DM8127或DM8168的Bitstream_BufList

smilestone322發表於2014-11-11

 問題如下:

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,&copy1D,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"}
};

 

相關文章