bitstreamfeeder.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  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 <stdio.h>
  26. #include <stdarg.h>
  27. #include <time.h>
  28. #include "vpuapifunc.h"
  29. #include "main_helper.h"
  30. typedef struct {
  31. FeedingMethod method;
  32. Uint8* remainData;
  33. Uint32 remainDataSize;
  34. void* actualFeeder;
  35. Uint32 coreIdx;
  36. Uint32 room;
  37. Uint32 fillingMode;
  38. BOOL eos;
  39. DecHandle decHandle;
  40. EndianMode endian;
  41. BSFeederHook observer;
  42. void* observerArg;
  43. vpu_buffer_t bitBuffer;
  44. int sequenceHeaderSize;
  45. } BitstreamFeeder;
  46. void* BitstreamFeeder_GetActualFeeder(void *feeder)
  47. {
  48. BitstreamFeeder* handle = (BitstreamFeeder*) feeder;
  49. return handle->actualFeeder;
  50. }
  51. static void BitstreamFeeder_DummyObserver(
  52. void* handle,
  53. void* es,
  54. Uint32 size,
  55. void* arg
  56. )
  57. {
  58. UNREFERENCED_PARAMETER(handle);
  59. UNREFERENCED_PARAMETER(es);
  60. UNREFERENCED_PARAMETER(size);
  61. UNREFERENCED_PARAMETER(arg);
  62. }
  63. extern void* BSFeederFixedSize_Create(
  64. const char* path,
  65. CodStd codecId
  66. );
  67. extern BOOL BSFeederFixedSize_Destroy(
  68. void* feeder
  69. );
  70. extern Int32 BSFeederFixedSize_Act(
  71. void* feeder,
  72. BSChunk* chunk
  73. );
  74. extern BOOL BSFeederFixedSize_Rewind(
  75. void* feeder
  76. );
  77. extern void BSFeederFixedSize_SetFeedingSize(
  78. void* feeder,
  79. Uint32 feedingSize
  80. );
  81. extern void* BSFeederFrameSize_Create(
  82. const char* path,
  83. CodStd codec
  84. );
  85. extern BOOL BSFeederFrameSize_Destroy(
  86. void* feeder
  87. );
  88. extern Int32 BSFeederFrameSize_Act(
  89. void* feeder,
  90. BSChunk* packet
  91. );
  92. extern BOOL BSFeederFrameSize_Rewind(
  93. void* feeder
  94. );
  95. extern void* BSFeederSizePlusEs_Create(
  96. const char* path,
  97. CodStd codecId
  98. );
  99. extern BOOL BSFeederSizePlusEs_Destroy(
  100. void* feeder
  101. );
  102. extern Int32 BSFeederSizePlusEs_Act(
  103. void* feeder,
  104. BSChunk* chunk
  105. );
  106. extern BOOL BSFeederSizePlusEs_Rewind(
  107. void* feeder
  108. );
  109. extern Int32 BSFeederFrameSize_GetStandard(
  110. void* feeder
  111. );
  112. extern void* BSFeederBuffer_Create(
  113. const char* path,
  114. CodStd codecId
  115. );
  116. extern BOOL BSFeederBuffer_Destroy(
  117. void* feeder
  118. );
  119. extern Int32 BSFeederBuffer_Act(
  120. void* feeder,
  121. BSChunk* chunk
  122. );
  123. extern BOOL BSFeederBuffer_Rewind(
  124. void* feeder
  125. );
  126. extern void BSFeederBuffer_SetFeedingSize(
  127. void* feeder,
  128. Uint32 feedingSize
  129. );
  130. /**
  131. * Abstract Bitstream Feeader Functions
  132. */
  133. void* BitstreamFeeder_Create(
  134. Uint32 coreIdx,
  135. const char* path,
  136. CodStd codecId,
  137. FeedingMethod method,
  138. EndianMode endian
  139. )
  140. {
  141. /*lint -esym(438, ap) */
  142. BitstreamFeeder* handle = NULL;
  143. void* feeder = NULL;
  144. switch (method) {
  145. case FEEDING_METHOD_FIXED_SIZE:
  146. feeder = BSFeederFixedSize_Create(path, codecId);
  147. break;
  148. case FEEDING_METHOD_FRAME_SIZE:
  149. feeder = BSFeederFrameSize_Create(path, codecId);
  150. break;
  151. case FEEDING_METHOD_SIZE_PLUS_ES:
  152. feeder = BSFeederSizePlusEs_Create(path, codecId);
  153. break;
  154. #ifdef USE_FEEDING_METHOD_BUFFER
  155. case FEEDING_METHOD_BUFFER:
  156. feeder = BSFeederBuffer_Create(path, codecId);
  157. break;
  158. #endif
  159. default:
  160. feeder = NULL;
  161. break;
  162. }
  163. if (feeder != NULL) {
  164. if ((handle=(BitstreamFeeder*)osal_malloc(sizeof(BitstreamFeeder))) == NULL) {
  165. VLOG(ERR, "%s:%d Failed to allocate memory\n", __FUNCTION__, __LINE__);
  166. return NULL;
  167. }
  168. handle->actualFeeder = feeder;
  169. handle->method = method;
  170. handle->remainData = NULL;
  171. handle->remainDataSize = 0;
  172. handle->fillingMode = (method == FEEDING_METHOD_FIXED_SIZE) ? BSF_FILLING_RINGBUFFER : BSF_FILLING_LINEBUFFER;
  173. handle->eos = FALSE;
  174. handle->observer = (BSFeederHook)BitstreamFeeder_DummyObserver;
  175. handle->observerArg = NULL;
  176. handle->endian = endian;
  177. handle->coreIdx = coreIdx;
  178. }
  179. return handle;
  180. /*lint +esym(438, ap) */
  181. }
  182. void BitstreamFeeder_SetFillMode(
  183. BSFeeder feeder,
  184. Uint32 mode
  185. )
  186. {
  187. BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
  188. switch (mode) {
  189. case BSF_FILLING_AUTO:
  190. bsf->fillingMode = (bsf->method == FEEDING_METHOD_FIXED_SIZE) ? BSF_FILLING_RINGBUFFER : BSF_FILLING_LINEBUFFER;
  191. break;
  192. case BSF_FILLING_RINGBUFFER:
  193. case BSF_FILLING_LINEBUFFER:
  194. case BSF_FILLING_RINGBUFFER_WITH_ENDFLAG:
  195. bsf->fillingMode = mode;
  196. break;
  197. default:
  198. VLOG(INFO, "%s Not supported mode %d\n", __FUNCTION__, mode);
  199. break;
  200. }
  201. }
  202. BOOL BitstreamFeeder_SetFeedingSize(
  203. BSFeeder feeder,
  204. Uint32 size
  205. )
  206. {
  207. BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
  208. BOOL ret = FALSE;
  209. if (bsf->method == FEEDING_METHOD_FIXED_SIZE) {
  210. BSFeederFixedSize_SetFeedingSize(bsf->actualFeeder, size);
  211. ret = TRUE;
  212. }
  213. return ret;
  214. }
  215. Uint32 BitstreamFeeder_Act(
  216. BSFeeder feeder,
  217. vpu_buffer_t* bsBuffer,
  218. PhysicalAddress wrPtr,
  219. Uint32 room,
  220. PhysicalAddress* newWrPtr
  221. )
  222. {
  223. BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
  224. Int32 feedingSize = 0;
  225. BSChunk chunk = {0};
  226. EndianMode endian;
  227. if (bsf == NULL) {
  228. VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
  229. return 0;
  230. }
  231. endian = bsf->endian;
  232. if (bsf->remainData == NULL) {
  233. chunk.size = bsBuffer->size;
  234. chunk.data = osal_malloc(chunk.size);
  235. chunk.eos = FALSE;
  236. if (chunk.data == NULL) {
  237. VLOG(ERR, "%s:%d failed to allocate memory\n", __FUNCTION__, __LINE__);
  238. return 0;
  239. }
  240. switch (bsf->method) {
  241. case FEEDING_METHOD_FIXED_SIZE:
  242. feedingSize = BSFeederFixedSize_Act(bsf->actualFeeder, &chunk);
  243. break;
  244. case FEEDING_METHOD_FRAME_SIZE:
  245. feedingSize = BSFeederFrameSize_Act(bsf->actualFeeder, &chunk);
  246. break;
  247. case FEEDING_METHOD_SIZE_PLUS_ES:
  248. feedingSize = BSFeederSizePlusEs_Act(bsf->actualFeeder, &chunk);
  249. break;
  250. #ifdef USE_FEEDING_METHOD_BUFFER
  251. case FEEDING_METHOD_BUFFER:
  252. feedingSize = BSFeederBuffer_Act(bsf->actualFeeder, &chunk);
  253. break;
  254. #endif
  255. default:
  256. VLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
  257. osal_free(chunk.data);
  258. return 0;
  259. }
  260. }
  261. else {
  262. chunk.data = bsf->remainData;
  263. feedingSize = bsf->remainDataSize;
  264. }
  265. bsf->observer((void*)bsf, chunk.data, feedingSize, bsf->observerArg);
  266. if (feedingSize < 0) {
  267. VLOG(ERR, "feeding size is negative value: %d\n", feedingSize);
  268. osal_free(chunk.data);
  269. return 0;
  270. }
  271. if (feedingSize > 0) {
  272. Uint32 rightSize=0, leftSize=feedingSize;
  273. PhysicalAddress base = bsBuffer->phys_addr;
  274. Uint32 size = bsBuffer->size;
  275. if ((Int32)room < feedingSize) {
  276. bsf->remainData = chunk.data;
  277. bsf->remainDataSize = feedingSize;
  278. return 0;
  279. }
  280. if (bsf->fillingMode == BSF_FILLING_RINGBUFFER || bsf->fillingMode == BSF_FILLING_RINGBUFFER_WITH_ENDFLAG) {
  281. if ((wrPtr+feedingSize) >= (base+size)) {
  282. PhysicalAddress endAddr = base+size;
  283. rightSize = endAddr-wrPtr;
  284. leftSize = (wrPtr+feedingSize) - endAddr;
  285. if (rightSize > 0) {
  286. VpuWriteMem(bsf->coreIdx, wrPtr, (unsigned char*)chunk.data, rightSize, (int)endian);
  287. VLOG(TRACE, "<%s:%d> WRPTR: %p SIZE: %x\n", __FUNCTION__, __LINE__, wrPtr, rightSize);
  288. }
  289. wrPtr = base;
  290. }
  291. }
  292. VpuWriteMem(bsf->coreIdx, wrPtr, (unsigned char*)chunk.data+rightSize, leftSize, (int)endian);
  293. *newWrPtr = wrPtr + leftSize;
  294. }
  295. bsf->eos = chunk.eos;
  296. bsf->sequenceHeaderSize = chunk.seqHeaderSize;
  297. osal_free(chunk.data);
  298. bsf->remainData = NULL;
  299. bsf->remainDataSize = 0;
  300. return feedingSize;
  301. }
  302. BOOL BitstreamFeeder_IsEos(
  303. BSFeeder feeder
  304. )
  305. {
  306. BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
  307. if (bsf == NULL) {
  308. VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
  309. return FALSE;
  310. }
  311. return bsf->eos;
  312. }
  313. Uint32 BitstreamFeeder_GetSeqHeaderSize(
  314. BSFeeder feeder
  315. )
  316. {
  317. BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
  318. if (bsf == NULL) {
  319. VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
  320. return FALSE;
  321. }
  322. return bsf->sequenceHeaderSize;
  323. }
  324. Int32 BitstreamFeeder_GetStandard(
  325. BSFeeder feeder
  326. )
  327. {
  328. BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
  329. Int32 standard = -1;
  330. if (bsf == NULL) {
  331. VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
  332. return FALSE;
  333. }
  334. switch (bsf->method) {
  335. case FEEDING_METHOD_FRAME_SIZE:
  336. standard = BSFeederFrameSize_GetStandard(bsf->actualFeeder);
  337. break;
  338. case FEEDING_METHOD_FIXED_SIZE:
  339. case FEEDING_METHOD_SIZE_PLUS_ES:
  340. #ifdef USE_FEEDING_METHOD_BUFFER
  341. case FEEDING_METHOD_BUFFER:
  342. #endif
  343. default:
  344. VLOG(ERR, "%s:%d Invalid return value (%d), method(%d)\n", __FUNCTION__, __LINE__, -1, bsf->method);
  345. break;
  346. }
  347. return standard;
  348. }
  349. void BitstreamFeeder_Stop(
  350. BSFeeder feeder
  351. )
  352. {
  353. BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
  354. if (bsf == NULL) {
  355. VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
  356. return;
  357. }
  358. }
  359. BOOL BitstreamFeeder_Destroy(
  360. BSFeeder feeder
  361. )
  362. {
  363. BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
  364. if (bsf == NULL) {
  365. return FALSE;
  366. }
  367. switch (bsf->method) {
  368. case FEEDING_METHOD_FIXED_SIZE:
  369. BSFeederFixedSize_Destroy(bsf->actualFeeder);
  370. break;
  371. case FEEDING_METHOD_FRAME_SIZE:
  372. BSFeederFrameSize_Destroy(bsf->actualFeeder);
  373. break;
  374. case FEEDING_METHOD_SIZE_PLUS_ES:
  375. BSFeederSizePlusEs_Destroy(bsf->actualFeeder);
  376. break;
  377. #ifdef USE_FEEDING_METHOD_BUFFER
  378. case FEEDING_METHOD_BUFFER:
  379. BSFeederBuffer_Destroy(bsf->actualFeeder);
  380. break;
  381. #endif
  382. default:
  383. VLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
  384. break;
  385. }
  386. if (bsf->remainData) {
  387. osal_free(bsf->remainData);
  388. }
  389. osal_free(bsf);
  390. return TRUE;
  391. }
  392. BOOL BitstreamFeeder_Rewind(
  393. BSFeeder feeder
  394. )
  395. {
  396. BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
  397. BOOL success = FALSE;
  398. if (bsf == NULL) {
  399. VLOG(ERR, "%s:%d handle is NULL\n", __FUNCTION__, __LINE__);
  400. return success;
  401. }
  402. switch (bsf->method) {
  403. case FEEDING_METHOD_FIXED_SIZE:
  404. success = BSFeederFixedSize_Rewind(bsf->actualFeeder);
  405. break;
  406. case FEEDING_METHOD_FRAME_SIZE:
  407. success = BSFeederFrameSize_Rewind(bsf->actualFeeder);
  408. break;
  409. case FEEDING_METHOD_SIZE_PLUS_ES:
  410. success = BSFeederSizePlusEs_Rewind(bsf->actualFeeder);
  411. break;
  412. #ifdef USE_FEEDING_METHOD_BUFFER
  413. case FEEDING_METHOD_BUFFER:
  414. #endif
  415. default:
  416. VLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
  417. break;
  418. }
  419. if (success == TRUE) {
  420. bsf->eos = FALSE;
  421. }
  422. return success;
  423. }
  424. BOOL BitstreamFeeder_SetHook(
  425. BSFeeder feeder,
  426. BSFeederHook hookFunc,
  427. void* hookArg
  428. )
  429. {
  430. BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
  431. if (bsf == NULL) {
  432. VLOG(ERR, "%s:%d handle is NULL\n", __FUNCTION__, __LINE__);
  433. return FALSE;
  434. }
  435. if (hookFunc == NULL) {
  436. bsf->observer = (BSFeederHook)BitstreamFeeder_DummyObserver;
  437. }
  438. else {
  439. bsf->observer = hookFunc;
  440. }
  441. bsf->observerArg = hookArg;
  442. return TRUE;
  443. }