问题如下:
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"}
};