I've run into a strange problem that I've been able to slap a band-aid over, but can't find the underlying issue.
Our application encodes H.264 mainline video and G.711 audio simultaneously. I have a codec server image with both algorithms configured. I have real time threads that handle the capture and encoding, and non-real time threads to handle the file I/O. There are ping pong buffers that the r/t threads fill with encoded data and the non-r/t threads read from to flush to disk. The video ping pong buffer is fifteen buffers deep. The audio ping pong buffer is 120 buffers deep. The video thread runs at a higher priority than the audio thread.
If I'm just recording video, everything is fine. If I switch on the audio stream as well, sometimes everything is fine. Other times, the fifteen video buffers will get processed once correctly, then the second go-round one of them will have their bufs[] fields cleared to 0 during the VIDENC_process() call. To illustrate, I added code that checks the values of the outgoing XDM_BufDesc before and after the call to VIDENC_process(), and this is what I found:
On startup, my fifteen video buffer locations from Memory_contigAlloc():
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x190928 has buffer at:0x45132000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x190a28 has buffer at:0x45187000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x190b28 has buffer at:0x451dc000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x190c28 has buffer at:0x45231000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x190d28 has buffer at:0x45286000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x190e28 has buffer at:0x452db000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x190f28 has buffer at:0x45330000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x191028 has buffer at:0x45385000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x191128 has buffer at:0x453da000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x191228 has buffer at:0x4542f000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x191328 has buffer at:0x45484000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x191428 has buffer at:0x454d9000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x191528 has buffer at:0x4552e000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x191628 has buffer at:0x45583000
ATEMEH264::Encoder: InternalOpen: 563: allocating ATEMEBufferDescription:0x191728 has buffer at:0x455d8000
From the beginning of the capture run:
ATEMEH264::Encoder: CaptureCallback: 763: appending 38570 bytes from 0x45187000
ATEMEH264::Encoder: CaptureCallback: 763: appending 899 bytes from 0x451dc000
ATEMEH264::Encoder: CaptureCallback: 763: appending 6319 bytes from 0x45231000
ATEMEH264::Encoder: CaptureCallback: 763: appending 3326 bytes from 0x45286000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2922 bytes from 0x452db000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2662 bytes from 0x45330000 <-- next round, this buffer gets clobbered
ATEMEH264::Encoder: CaptureCallback: 763: appending 2620 bytes from 0x45385000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2421 bytes from 0x453da000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2612 bytes from 0x4542f000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2603 bytes from 0x45484000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2404 bytes from 0x454d9000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2464 bytes from 0x4552e000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2787 bytes from 0x45583000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2430 bytes from 0x455d8000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2714 bytes from 0x45132000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2649 bytes from 0x45187000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2446 bytes from 0x451dc000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2729 bytes from 0x45231000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2746 bytes from 0x45286000
ATEMEH264::Encoder: CaptureCallback: 763: appending 2417 bytes from 0x452db000
ceapp.c:441: outDesc.bufs[0] is 0!
outDescOriginal:
numBufs:2
,bufs:00190f30
bufs[0]:45330000 size:345600
bufs[1]:45384600 size:384
outDesc:
numBufs:2
,bufs:00190f30
bufs[0]:00000000 size:345600
bufs[1]:00000000 size:384
As you can see, only the bufs[] entries get cleared; the other fields are untouched. Again, this happens somewhere inside the VIDENC_process() call.
If I restore the bufs[] entries to their original values, the program continues on merrily without the problem recurring. No video data appears lost; all frames are accounted. So, there's my band-aid. The fact that this is happening at all, though, really bothers me.
It seems as though something inside VIDENC_process merely blew away the buffer pointers for some reason, even though they're still valid and still hold the correct encoded data. I want to know what is clearing those fields and why, and whether or not I have a larger issue in play of which I'm not aware. Again, this only happens when I'm recording both audio and video, and if it's going to happen it always happens on the second time through those fifteen video buffers.
Here is my server image info:
Data Sheet for the DSP server image
Server DSP image name xavsc_ateme_server_16.x64P Server Algorithms
Codec name (alias) xavsc_ateme Codec type video encoder, xDM 0.90 (ti.sdo.ce.video.IVIDENC) Package ti.sdo.ce.examples.codecs.xavsc_16 Module XAVSC_ATEME Codec package location at server build time /home/rtalbot/dvsdk_2_00_00_18/codec_engine_2_21/examples/ Package version [ ] RPC protocol version 3
Thread attributes
Priority
2
Stack Size
8192 bytes
Group ID number 0 (auto-assigned value)
Codec name (alias) g711enc Codec type speech encoder, xDM 1.00 (ti.sdo.ce.speech1.ISPHENC1) Package ti.sdo.ce.examples.codecs.g711 Module G711ENC Codec package location at server build time /home/rtalbot/dvsdk_2_00_00_18/codec_engine_2_21/examples/ Package version [ 1,0,0,1226392131011 ] RPC protocol version 0
Thread attributes
Priority
4
Stack Size
default for the alg (512 bytes) + 8192 bytes padding
Group ID number 1 (auto-assigned value)
Server DMA (DMAN3)
config
MAXGROUPS 0x00000014 heapInternal L1DSRAM heapExternal DDR2 scratchAllocFxn undefined scratchFreeFxn undefined idma3Internal true cpu false useExternalRM false numQdmaChannels 0x00000004 qdmaPaRamBase 0x01C04000 maxPaRamEntries 0x00000080 maxQdmaChannels 0x00000008 maxTCs 0x00000008 paRamBaseIndex 0x00000050 numPaRamEntries 0x00000030 nullPaRamIndex 0x00000000 qdmaChannels [ 0, 1, 2, 3 ] tccAllocationMaskH 0xFF80E000 tccAllocationMaskL 0x00000000 qdmaQueueMap [ 1, 1, 1, 1, 1, 1, 1, 1 ] queueTCMap [ 0, 1, 2, 3, 4, 5, 6, 7 ] queuePri [ 3, 7, 0, 0, 0, 0, 0, 0 ] numTccGroup [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] numPaRamGroup [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] debug false trace false ipcKeyBase 0x4E414D44 allowUnshared true Algorithm memory
allocation (DSKT2)
config
DEFAULTSEG IRAM DARAM0 L1DSRAM DARAM1 L1DSRAM DARAM2 L1DSRAM SARAM0 L1DSRAM SARAM1 L1DSRAM SARAM2 L1DSRAM ESDATA DDRALGHEAP IPROG L1DSRAM EPROG DDRALGHEAP DSKT2_HEAP DDR2 ALLOW_EXTERNAL_SCRATCH true DARAM_SCRATCH_SIZES [ 1024, 1024, 0, 0, 0, 0, 0, 0 ] SARAM_SCRATCH_SIZES [ 1024, 1024, 0, 0, 0, 0, 0, 0 ] debug false cacheWritebackInvalidateFxn BCACHE_wbInv trace false DSP memory map
Name ERAM3 Base 0x8FA20000 Len 0x00010000 Description ERAM3
Name DDR2 Base 0x8FA30000 Len 0x003C0000 Description DDR2: off-chip memory for code and data
Name ERAM2 Base 0x8FA10000 Len 0x00010000 Description ERAM2
Name ERAM1 Base 0x8FA00000 Len 0x00010000 Description ERAM1
Name RESET_VECTOR Base 0x8FF00000 Len 0x00000080 Description RESET_VECTOR: off-chip memory for the reset vector table
Name DDRALGHEAP Base 0x8B800000 Len 0x04200000 Description DDRALGHEAP: off-chip memory for dynamic algmem allocation
Name DSPLINKMEM Base 0x8FE00000 Len 0x00100000 Description DSPLINK: off-chip memory for DSPLINK code and data Misc settings
Server thread priority 1 Server thread stack size 16384 bytes autoGenScratchSizeArrays false Configured DSP clock speed 566 MHz (set in the GBL.CLKOUT TCF field; may or may not match the actual DSP clock speed) Configuration example Add the following code to your Arm-side application configuration file (.cfg) to create an Engine from this server:
var Engine = xdc.useModule('ti.sdo.ce.Engine');(note: if the server was built with "Configuro", replace the shown package name with the actual server package name)
var myEngine = Engine.createFromServer(
"xavsc_ateme_server_16", // Engine name (as referred to in the C app)
"xavsc_ateme_server_16.x64P", // path to server exe, relative to its package dir
"xavsc_ateme_server_16" // full server package name
);
And my loadmodules.sh:
insmod cmemk.ko phys_start=0x87800000 phys_end=0x8A000000 pools=1x3600000,5x829440,2x1244160,15x345984,1x40960,2x8192,128x128
insmod dsplinkk.ko
rm -f /dev/dsplink
mknod /dev/dsplink c `awk "\\$2==\"dsplink\" {print \\$1}" /proc/devices` 0
I'm using CodecEngine 2.21 with a 2.6.28-davinci based Linux kernel, Angstrom toolchain, gcc-4.3.3. Hardware is a custom DM6446 board.
I can post any code or more details that might be useful.
Any help is appreciated... working with CodecEngine has been a really strange ride...
Thanks,
Ryan