component_enc_reader.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /*
  2. * Copyright (c) 2019, Chips&Media
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  18. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include <string.h>
  26. #include "component.h"
  27. typedef enum {
  28. READER_STATE_OPEN,
  29. READER_STATE_READING,
  30. } EncReaderState;
  31. typedef struct {
  32. EncHandle handle;
  33. Uint32 streamBufCount;
  34. Uint32 streamBufSize;
  35. vpu_buffer_t* bsBuffer;
  36. Uint32 coreIdx;
  37. EndianMode streamEndian;
  38. EncReaderState state;
  39. char bitstreamFileName[MAX_FILE_PATH];
  40. BitstreamReader bsReader;
  41. osal_file_t fp;
  42. BOOL ringBuffer;
  43. BOOL ringBufferWrapEnable;
  44. Int32 productID;
  45. } ReaderContext;
  46. static CNMComponentParamRet GetParameterReader(ComponentImpl* from, ComponentImpl* com, GetParameterCMD commandType, void* data)
  47. {
  48. ReaderContext* ctx = (ReaderContext*)com->context;
  49. BOOL result = TRUE;
  50. ParamEncBitstreamBuffer* bsBuf = NULL;
  51. PortContainer* container;
  52. switch(commandType) {
  53. case GET_PARAM_COM_IS_CONTAINER_CONUSUMED:
  54. container = (PortContainer*)data;
  55. container->consumed = TRUE;
  56. break;
  57. case GET_PARAM_READER_BITSTREAM_BUF:
  58. if (ctx->bsBuffer == NULL) return CNM_COMPONENT_PARAM_NOT_READY;
  59. bsBuf = (ParamEncBitstreamBuffer*)data;
  60. bsBuf->bs = ctx->bsBuffer;
  61. bsBuf->num = ctx->streamBufCount;
  62. break;
  63. default:
  64. return CNM_COMPONENT_PARAM_NOT_FOUND;
  65. }
  66. return (result == TRUE) ? CNM_COMPONENT_PARAM_SUCCESS : CNM_COMPONENT_PARAM_FAILURE;
  67. }
  68. static CNMComponentParamRet SetParameterReader(ComponentImpl* from, ComponentImpl* com, SetParameterCMD commandType, void* data)
  69. {
  70. BOOL result = TRUE;
  71. switch(commandType) {
  72. default:
  73. result = FALSE;
  74. break;
  75. }
  76. return (result == TRUE) ? CNM_COMPONENT_PARAM_SUCCESS : CNM_COMPONENT_PARAM_FAILURE;
  77. }
  78. static BOOL ExecuteReader(ComponentImpl* com, PortContainer* in, PortContainer* out)
  79. {
  80. ReaderContext* ctx = (ReaderContext*)com->context;
  81. PortContainerES* srcData = (PortContainerES*)in;
  82. BOOL success = TRUE;
  83. CNMComponentParamRet ret;
  84. srcData->reuse = FALSE;
  85. #ifdef USE_FEEDING_METHOD_BUFFER
  86. PortContainerExternal *output = (PortContainerExternal*)ComponentPortPeekData(&com->sinkPort);
  87. if (output == NULL) {
  88. srcData->reuse = TRUE;
  89. return TRUE;
  90. }
  91. #endif
  92. switch (ctx->state) {
  93. case READER_STATE_OPEN:
  94. ret = ComponentGetParameter(com, com->srcPort.connectedComponent, GET_PARAM_ENC_HANDLE, &ctx->handle);
  95. if (ComponentParamReturnTest(ret, &success) == FALSE) {
  96. return success;
  97. }
  98. #ifdef USE_FEEDING_METHOD_BUFFER
  99. ctx->bsReader = BitstreamReader_Create(BUFFER_MODE_TYPE_LINEBUFFER, ctx->bitstreamFileName, ctx->streamEndian, &ctx->handle);
  100. if (ctx->bsReader == NULL) {
  101. VLOG(ERR, "%s:%d Failed to BitstreamReader_Create\n", __FUNCTION__, __LINE__);
  102. return FALSE;
  103. }
  104. #else
  105. if ( ctx->bitstreamFileName[0] != 0) {
  106. ctx->bsReader = BitstreamReader_Create(BUFFER_MODE_TYPE_LINEBUFFER, ctx->bitstreamFileName, ctx->streamEndian, &ctx->handle);
  107. if (ctx->bsReader == NULL) {
  108. VLOG(ERR, "%s:%d Failed to BitstreamReader_Create\n", __FUNCTION__, __LINE__);
  109. return FALSE;
  110. }
  111. }
  112. #endif
  113. ctx->state = READER_STATE_READING;
  114. srcData->reuse = TRUE;
  115. break;
  116. case READER_STATE_READING:
  117. if (srcData->size <= 0 && srcData->last == TRUE)
  118. {
  119. while ((output = (PortContainerExternal*)ComponentPortGetData(&com->sinkPort)) != NULL)
  120. {
  121. output->nFlags = 0x1;
  122. output->nFilledLen = 0;
  123. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_FILL_BUFFER_DONE, (void *)output);
  124. }
  125. }
  126. if (srcData->size > 0 ||
  127. (ctx->ringBuffer == TRUE && ctx->ringBufferWrapEnable == FALSE && srcData->last == TRUE) ) {
  128. if ( ctx->ringBuffer == TRUE) {
  129. Uint8* buf = (Uint8*)osal_malloc(srcData->size);
  130. PhysicalAddress rd, paBsBufStart, paBsBufEnd;
  131. Int32 readSize;
  132. Uint32 room;
  133. rd = srcData->rdPtr;
  134. paBsBufStart = srcData->paBsBufStart;
  135. paBsBufEnd = srcData->paBsBufEnd;
  136. readSize = srcData->size;
  137. if (ctx->ringBufferWrapEnable == TRUE ) {
  138. if (ctx->bsReader != 0) {
  139. if ((rd+readSize) > paBsBufEnd) {
  140. room = paBsBufEnd - rd;
  141. vdi_read_memory(ctx->coreIdx, rd, buf, room, ctx->streamEndian);
  142. vdi_read_memory(ctx->coreIdx, paBsBufStart, buf+room, (readSize-room), ctx->streamEndian);
  143. }
  144. else {
  145. vdi_read_memory(ctx->coreIdx, rd, buf, readSize, ctx->streamEndian);
  146. }
  147. }
  148. VPU_EncUpdateBitstreamBuffer(ctx->handle, readSize);
  149. #ifdef USE_FEEDING_METHOD_BUFFER
  150. VLOG(ERR, "%s, %s\r\n", __FUNCTION__, __LINE__);
  151. osal_memcpy(output->pBuffer, buf, readSize);
  152. output->nFilledLen = readSize;
  153. if (srcData->last == TRUE)
  154. {
  155. output->nFlags = 0x01;
  156. }
  157. else {
  158. output->nFlags = 0x10;
  159. }
  160. ComponentPortGetData(&com->sinkPort);
  161. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_FILL_BUFFER_DONE, (void *)output);
  162. #else
  163. if (ctx->fp) {
  164. osal_fwrite(buf, readSize, 1, ctx->fp);
  165. }
  166. #endif
  167. }
  168. else { //ring=1, wrap=0
  169. if (srcData->streamBufFull == TRUE || srcData->last == TRUE) { // read whole data at once and no UpdateBS
  170. if (ctx->bsReader != 0) {
  171. vdi_read_memory(ctx->coreIdx, rd, buf, readSize, ctx->streamEndian);
  172. }
  173. #ifdef USE_FEEDING_METHOD_BUFFER
  174. osal_memcpy(output->pBuffer, buf, readSize);
  175. output->nFilledLen = readSize;
  176. if (srcData->bufferType == RECON_IDX_FLAG_HEADER_ONLY)
  177. {
  178. output->nFlags = 0x80;
  179. }
  180. else if (srcData->last == TRUE)
  181. {
  182. output->nFlags = 0x01;
  183. }
  184. else {
  185. output->nFlags = 0x10;
  186. }
  187. ComponentPortGetData(&com->sinkPort);
  188. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_FILL_BUFFER_DONE, (void *)output);
  189. #else
  190. if (ctx->fp) {
  191. osal_fwrite(buf, readSize, 1, ctx->fp);
  192. }
  193. #endif
  194. }
  195. }
  196. if (srcData->streamBufFull == TRUE) {
  197. if (ctx->ringBufferWrapEnable == FALSE) {
  198. vdi_free_dma_memory(ctx->coreIdx, &srcData->buf, ENC_BS, ctx->handle->instIndex);
  199. osal_memcpy(ctx->bsBuffer, &srcData->newBsBuf, sizeof(*ctx->bsBuffer));
  200. }
  201. srcData->buf.size = 0;
  202. }
  203. osal_free(buf);
  204. }
  205. else { /* line buffer mode */
  206. #ifdef USE_FEEDING_METHOD_BUFFER
  207. if (ctx->bsReader != 0) {
  208. output->nFilledLen = BitstreamReader_Act2(ctx->bsReader, srcData->buf.phys_addr, srcData->buf.size, srcData->size, NULL, output->pBuffer);
  209. if(PRODUCT_ID_NOT_W_SERIES(ctx->productID) && TRUE == srcData->streamBufFull) {
  210. VPU_ClearInterrupt(ctx->coreIdx);
  211. }
  212. }
  213. if (srcData->streamBufFull == TRUE) {
  214. srcData->buf.phys_addr = 0;
  215. }
  216. if (srcData->bufferType == RECON_IDX_FLAG_HEADER_ONLY)
  217. {
  218. output->nFlags = 0x80;
  219. }
  220. else if (srcData->last == TRUE)
  221. {
  222. output->nFlags = 0x01;
  223. }
  224. else {
  225. output->nFlags = 0x10;
  226. }
  227. ComponentPortGetData(&com->sinkPort);
  228. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_FILL_BUFFER_DONE, (void *)output);
  229. #else
  230. Uint8* buf = (Uint8*)osal_malloc(srcData->size);
  231. if (ctx->bsReader != 0) {
  232. //buf = (Uint8*)osal_malloc(srcData->size);
  233. BitstreamReader_Act(ctx->bsReader, srcData->buf.phys_addr, srcData->buf.size, srcData->size, NULL);
  234. if(PRODUCT_ID_NOT_W_SERIES(ctx->productID) && TRUE == srcData->streamBufFull) {
  235. VPU_ClearInterrupt(ctx->coreIdx);
  236. }
  237. }
  238. if (srcData->streamBufFull == TRUE) {
  239. srcData->buf.phys_addr = 0;
  240. }
  241. if (ctx->fp) {
  242. osal_fwrite(buf, srcData->size, 1, ctx->fp);
  243. }
  244. if(buf)
  245. osal_free(buf);
  246. #endif
  247. }
  248. if (TRUE == srcData->streamBufFull) {
  249. srcData->streamBufFull = FALSE;
  250. }
  251. }
  252. srcData->consumed = TRUE;
  253. com->terminate = srcData->last;
  254. break;
  255. default:
  256. success = FALSE;
  257. break;
  258. }
  259. return success;
  260. }
  261. static BOOL PrepareReader(ComponentImpl* com, BOOL* done)
  262. {
  263. ReaderContext* ctx = (ReaderContext*)com->context;
  264. Uint32 i;
  265. vpu_buffer_t* bsBuffer;
  266. Uint32 num = ctx->streamBufCount;
  267. *done = FALSE;
  268. bsBuffer = (vpu_buffer_t*)osal_malloc(num*sizeof(vpu_buffer_t));
  269. for (i = 0; i < num; i++) {
  270. bsBuffer[i].size = ctx->streamBufSize;
  271. if (vdi_allocate_dma_memory(ctx->coreIdx, &bsBuffer[i], ENC_BS, /*ctx->handle->instIndex*/0) < 0) {
  272. VLOG(ERR, "%s:%d fail to allocate bitstream buffer\n", __FUNCTION__, __LINE__);
  273. osal_free(bsBuffer);
  274. return FALSE;
  275. }
  276. }
  277. ctx->bsBuffer = bsBuffer;
  278. ctx->state = READER_STATE_OPEN;
  279. *done = TRUE;
  280. return TRUE;
  281. }
  282. static void ReleaseReader(ComponentImpl* com)
  283. {
  284. ReaderContext* ctx = (ReaderContext*)com->context;
  285. Uint32 i = 0;
  286. if (ctx->bsBuffer != NULL) {
  287. for (i = 0; i < ctx->streamBufCount ; i++) {
  288. if (ctx->bsBuffer[i].size)
  289. vdi_free_dma_memory(ctx->coreIdx, &ctx->bsBuffer[i], ENC_BS, 0);
  290. }
  291. }
  292. }
  293. static BOOL DestroyReader(ComponentImpl* com)
  294. {
  295. ReaderContext* ctx = (ReaderContext*)com->context;
  296. if (ctx->bsBuffer != NULL) osal_free(ctx->bsBuffer);
  297. if (ctx->fp) osal_fclose(ctx->fp);
  298. osal_free(ctx);
  299. return TRUE;
  300. }
  301. static Component CreateReader(ComponentImpl* com, CNMComponentConfig* componentParam)
  302. {
  303. ReaderContext* ctx;
  304. com->context = osal_malloc(sizeof(ReaderContext));
  305. ctx = (ReaderContext*)com->context;
  306. osal_memset((void*)ctx, 0, sizeof(ReaderContext));
  307. strcpy(ctx->bitstreamFileName, componentParam->testEncConfig.bitstreamFileName);
  308. ctx->handle = NULL;
  309. ctx->coreIdx = componentParam->testEncConfig.coreIdx;
  310. ctx->productID = componentParam->testEncConfig.productId;
  311. ctx->streamEndian = (EndianMode)componentParam->testEncConfig.stream_endian;
  312. ctx->streamBufCount = componentParam->encOpenParam.streamBufCount;
  313. ctx->streamBufSize = componentParam->encOpenParam.streamBufSize;
  314. ctx->ringBuffer = componentParam->encOpenParam.ringBufferEnable;
  315. ctx->ringBufferWrapEnable = componentParam->encOpenParam.ringBufferWrapEnable;
  316. return (Component)com;
  317. }
  318. ComponentImpl readerComponentImpl = {
  319. "reader",
  320. NULL,
  321. {0,},
  322. {0,},
  323. sizeof(PortContainer),
  324. 5,
  325. CreateReader,
  326. GetParameterReader,
  327. SetParameterReader,
  328. PrepareReader,
  329. ExecuteReader,
  330. ReleaseReader,
  331. DestroyReader,
  332. };