Hello,
I am using H.264 HP encoder for C66x DSP version DEV.100.V.H264HP.E.C66X.01.00.00.00.
For some reason H.264 HP encoder produces wrong H.264 elementary stream that is not playable (we use ffmpeg to play it):ffplay -f h264 output.264avplay version 0.8.4-6:0.8.4-0ubuntu0.12.10.1, Copyright (c) 2003-2012 the Libav developers built on Nov 6 2012 16:51:11 with gcc 4.7.2[h264 @ 0x7fee54000e00] non-existing PPS referenced[h264 @ 0x7fee54000e00] non-existing PPS 0 referenced[h264 @ 0x7fee54000e00] decode_slice_header error[h264 @ 0x7fee54000e00] no frame![h264 @ 0x7fee54000e00] sps_id out of range[h264 @ 0x7fee54000e00] non-existing PPS referenced[h264 @ 0x7fee54000e00] sps_id out of range[h264 @ 0x7fee54000e00] non-existing PPS 0 referenced[h264 @ 0x7fee54000e00] decode_slice_header error[h264 @ 0x7fee54000e00] no frame![h264 @ 0x7fee54000e00] non-existing PPS referenced[h264 @ 0x7fee54000e00] non-existing PPS 0 referenced[h264 @ 0x7fee54000e00] decode_slice_header error[h264 @ 0x7fee54000e00] no frame!
As we see most likely IDR frame is missing.
At the same time demo that goes with H.264 encoder produces correct streams.I created test that shows how we use H.264 encoder. I did totally the same call order to the encoder API (including all not mandatory calls) in my test as in original demo that goes with the encoder. Input parameters are also the same - you can compare demo_params.txt and test_params.txt files that contains copy of the param and dynamic params of test and original demo.
Some details about test:- By default test encodes YUV that consists of all zeros - a green image. This is to speed-up testing because reading input YUV files is slow.- Also you can use "input.yuv" file as an input. Just uncomment "fopen" code in test_task.c- For simplicity test does not use caching- For simplicity test does not have a buffer manager. We just never free allocated input/output buffers. So with time it ends with out of memory error.- For simplicity no IPC. Only one core is used.- Shared Memory Manager implemented using SYS/BIOS Heap- Test outputs encoded stream to "output.264" file
Call order:algNumAllocalgAllocalgInitalgActivatecontrol XDM_GETVERSIONalgDeactivatealgActivatecontrol XDM_GETBUFINFOalgDeactivatealgActivateRMAN_assignResourcesRMAN_activateAllResourcesalgDeactivateloop { algActivate control XDM_SETPARAMS algDeactivate algActivate process algActivate control XDM_GETSTATUS algDeactivate}Results are interesting - frame type changes correctly, starting from IDR frame, but encoder doesn't generate any data:[C66xx_0] main() on CORE=0Initialize RMANStart SYS/BIOStest_taskCreate encoderVersion: DEV.100.V.H264HP.E.C66X.01.00.00.00Configure encoder2 buffersminNumInBufs 3minNumOutBufs 1minInBufSize[0] 101376 0minInBufSize[1] 25344 0minInBufSize[2] 25344 0minOutBufSize[0] 3145728 0Input buffers size (bytes in YUV frame) = 152064Output buffers size = 3145728Configure encoder resourcesEncoder created and configuredAllocating input and output buffersEncoding frameFrame type: -1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: -1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 3 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frame....Also with little different call order encoder is able to generate bytes so I am attaching generated data for you to compare:output.264 - generated by test (with little different call order)airshow_p352x288.264 - generated by original demoLog of test with changed call order:...Encoder created and configuredAllocating input and output buffersEncoding frameFrame type: -1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: -1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 3 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 1 Bytes generated 103Output 103 bytes from 0 bufferAllocating input and output buffersEncoding frameFrame type: 2 Bytes generated 16Output 16 bytes from 0 bufferAllocating input and output buffersEncoding frameFrame type: 2 Bytes generated 14Output 14 bytes from 0 bufferAllocating input and output buffersEncoding frameFrame type: 1 Bytes generated 14Output 14 bytes from 0 bufferAllocating input and output buffersEncoding frameFrame type: 2 Bytes generated 16Output 16 bytes from 0 bufferAllocating input and output buffersEncoding frameAs you see in this case Bytest generated = 0, when Frame type = 3 (IDR) so most likely IDR frame just missing.I can not understand where is the problem because H.264 HP encoder is a black box for me and all the "magic" that generates bytes is in it.
Can you clarify the reason of this strange encoder behaviour?
Regards,
Andrey Lisnevich
Hi Andrey,
We have tried same configuration file you have used in unit test application, with input frames as all 0s. We are not observing any issue everything looks fine.
It looks like with little different call order you were able to encode stream properly, there were no syntax errors with the file you shared. Can we know what is the change between two trials?
Also we have used mplayer version "r31743-4.2.5" we were able to play without any error...
Modified call order with which I managed to get bytes is:
algNumAllocalgAllocalgInitalgActivatecontrol XDM_GETVERSIONalgDeactivatealgActivatecontrol XDM_GETBUFINFOalgDeactivatealgActivateRMAN_assignResourcesRMAN_activateAllResourcesalgDeactivate
algActivateloop { control XDM_SETPARAMS process control XDM_GETSTATUS}
In previous message I attached CCS project of my test. I debugged it and I do not see any problem.
But encoder produces wrong stream (or doesn't produce any). Since I have no source code of encoder I can not debug deeper into encoder and find the reason why is it so.
Can you help me find the reason by running and debugging my very simple test project?
Looks like cache issue are present in the application provided by you.
1) By default on power on Cache is enabled. So to disable cache we need to disable with cache APIs.
2) Assuming that cache is enabled, shared memory sync, allocation APIs are not implemented. Though app is for single core, Codec uses EDMA to update shared buffers, since sync is not implemented, codec will not work.
Just as a work around to make the app working please call "Cache_wbInvAll();" in function "shmmap_sync_test" it will work. we are able to see proper output with work around without any syntax errors.
Rama Mohana Reddy
Thanks Rama,
You are right - by default L1P and L1D caches are enabled. "Cache_wbInvAll();" in function "shmmap_sync_test" solves the issue.
Hi Rama,
This workaround works perfectly but only for core0:
[C66xx_0] main() on CORE=0Initialize RMANStart SYS/BIOStest_taskCreate encoderWARNING: Not supported parent functionsspace=17 pointer=80000180 size=d900space=0 pointer=00800000 size=32000space=17 pointer=8000da80 size=300000space=17 pointer=8030da80 size=a1b80space=17 pointer=803af600 size=a1b80space=17 pointer=80451180 size=32000space=17 pointer=80483180 size=518cspace=0 pointer=00832000 size=1800space=17 pointer=80488380 size=2580space=17 pointer=8048a900 size=10000space=17 pointer=8049a900 size=5e00space=0 pointer=00833800 size=800space=0 pointer=00834000 size=300space=17 pointer=804a0700 size=1300space=17 pointer=804a1a00 size=5000space=0 pointer=00834300 size=2000space=17 pointer=804a6a00 size=500space=17 pointer=804a6f00 size=500space=17 pointer=804a7400 size=500space=17 pointer=804a7900 size=2a80space=17 pointer=804aa380 size=1300shmmap 0 15048 2shmmap 1 176 2shmmap 2 11104 2shmmap 3 760 2shmmap 4 2921240 0shmmap 5 5576 2shmmap 6 960 0shmmap 7 3145728 0Version: DEV.100.V.H264HP.E.C66X.01.00.00.00Configure encoder2 buffersminNumInBufs 3minNumOutBufs 1minInBufSize[0] 101376 0minInBufSize[1] 25344 0minInBufSize[2] 25344 0minOutBufSize[0] 3145728 0Input buffers size (bytes in YUV frame) = 152064Output buffers size = 3145728Configure encoder resourcesEncoder created and configuredAllocating input and output buffersEncoding frameFrame type: -1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: -1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 3 Bytes generated 111Output 111 bytes from 0 bufferAllocating input and output buffersEncoding frameFrame type: 1 Bytes generated 16Output 16 bytes from 0 bufferAllocating input and output buffersEncoding frameFrame type: 2 Bytes generated 14Output 14 bytes from 0 bufferAllocating input and output buffersEncoding frameFrame type: 2 Bytes generated 14Output 14 bytes from 0 bufferAllocating input and output buffersEncoding frameFrame type: 1 Bytes generated 16
When I run it on other cores result is the same:
[C66xx_1] main() on CORE=1Initialize RMANStart SYS/BIOStest_taskCreate encoderWARNING: Not supported parent functionsspace=17 pointer=80000180 size=d900space=0 pointer=00800000 size=32000space=17 pointer=8000da80 size=300000space=17 pointer=8030da80 size=a1b80space=17 pointer=803af600 size=a1b80space=17 pointer=80451180 size=32000space=17 pointer=80483180 size=518cspace=0 pointer=00832000 size=1800space=17 pointer=80488380 size=2580space=17 pointer=8048a900 size=10000space=17 pointer=8049a900 size=5e00space=0 pointer=00833800 size=800space=0 pointer=00834000 size=300space=17 pointer=804a0700 size=1300space=17 pointer=804a1a00 size=5000space=0 pointer=00834300 size=2000space=17 pointer=804a6a00 size=500space=17 pointer=804a6f00 size=500space=17 pointer=804a7400 size=500space=17 pointer=804a7900 size=2a80space=17 pointer=804aa380 size=1300shmmap 0 15048 2shmmap 1 176 2shmmap 2 11104 2shmmap 3 760 2shmmap 4 2921240 0shmmap 5 5576 2shmmap 6 960 0shmmap 7 3145728 0Version: DEV.100.V.H264HP.E.C66X.01.00.00.00Configure encoder2 buffersminNumInBufs 3minNumOutBufs 1minInBufSize[0] 101376 0minInBufSize[1] 25344 0minInBufSize[2] 25344 0minOutBufSize[0] 3145728 0Input buffers size (bytes in YUV frame) = 152064Output buffers size = 3145728Configure encoder resourcesEncoder created and configuredAllocating input and output buffersEncoding frameFrame type: -1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: -1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 3 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 1 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0Allocating input and output buffersEncoding frameFrame type: 2 Bytes generated 0
As you see frame type is correctly changing as before, but encoder generates 0 bytes. To reproduce the issue just run single instance of the same program on core other then core0.
Can you please help to resolve the issue?
Do you have an idea why is it so?
Mutlicore code uses Master,Slave core concept. When CoreID is "zero" codec understands it as master core. So in case of single core we need to assign CoreID in ividmc params as "zero" instead of DNUM value(Only master is present).
We have tried making CoreID zero while running on Core 1 instead of Core 0, it works fine no issues
Regards
Rama
In ividimc.h, part of HP encoder distribution, you can read opposite information:
* @param core_task_ID : Core Task Name,can be master or slave core * * @param coreID : Core number of the active core,given by DNUM
And the same according to documentation: core_task_ID is responsible for core's task identification. It can be set to:
IVIDMC_TASK_MASTER = 0 - The master core task ID.IVIDMC_TASK_SLAVE = 1 - Slave Task ID. This is non specific to any particular task.IVIDMC_TASK_SLAVE_1 = 2 - Specific slave task ID 1.IVIDMC_TASK_SLAVE_2 = 3 - Specific slave task ID 2.
etc.
Documentation says that CoreID is just current core identification number. It should not be mandatory to set CoreID = 0 for master core.
Most likely problem is in H.264 HP encoder implementation.
Can you please confirm this?
The information specified in ividmc.h file is correct. But codec algorithm use "CoreID" parameter to distribute number of rows encoding in multicore scenario. Same will is mapped to in single core also.
Codec uses "core_task_ID" as expected, but slice division logic, sync APIs are called based on coreID where it mandates coreID to start from zero.
I got your point. With coreID = 0 transcoding works on all cores.
But then the description in header file is untrue:
@param coreID : Core number of the active core,given by DNUM
Also documentation never says that coreID should be == 0 for core with master task. I hope you will describe this point more detailed with HP encoder release.
Thanks!
We will mention these points in users guide in upcoming releases for H264 HP encoder.
Best Regards
Can you please also look at another problem: http://e2e.ti.com/support/embedded/multimedia_software_codecs/f/356/t/239791.aspx
It uses almost same test project from this thread. Memory "disappears" when initializing encoder with 176x144 resolution.
Thanks
I havn't found detailed description of coreID in H.264 HP encoder release so I have the question that should help me understand it better:
I want to run multicore encoding on 2 cores: core DNUM=3 master and core DNUM=4 slave. What values should I specify in IVIDMC_t coreID and core_task_ID for each core?
In the drop we provided, we have not updated documentation, it is meant for fixing memory leakage when aspect ratio is changed dynamically. We would like to hear from you whether issue got fixed or not. Once issue is fixed we will do formal release with documentation update.
You can set below values to encode using 2 cores.
DNUM = 3:
coreID = 0; core_task_ID = Master;
DNUM = 4:
coreID = 1; core_task_ID = Slave;
ncores = 2;