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