You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

815 lines
22KB

  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * FFmpeg is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * FFmpeg is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with FFmpeg; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include <string.h>
  19. #include "config.h"
  20. #include "libavutil/avassert.h"
  21. #include "libavutil/buffer.h"
  22. #include "libavutil/common.h"
  23. #include "cbs.h"
  24. #include "cbs_internal.h"
  25. static const CodedBitstreamType *cbs_type_table[] = {
  26. #if CONFIG_CBS_AV1
  27. &ff_cbs_type_av1,
  28. #endif
  29. #if CONFIG_CBS_H264
  30. &ff_cbs_type_h264,
  31. #endif
  32. #if CONFIG_CBS_H265
  33. &ff_cbs_type_h265,
  34. #endif
  35. #if CONFIG_CBS_JPEG
  36. &ff_cbs_type_jpeg,
  37. #endif
  38. #if CONFIG_CBS_MPEG2
  39. &ff_cbs_type_mpeg2,
  40. #endif
  41. #if CONFIG_CBS_VP9
  42. &ff_cbs_type_vp9,
  43. #endif
  44. };
  45. const enum AVCodecID ff_cbs_all_codec_ids[] = {
  46. #if CONFIG_CBS_AV1
  47. AV_CODEC_ID_AV1,
  48. #endif
  49. #if CONFIG_CBS_H264
  50. AV_CODEC_ID_H264,
  51. #endif
  52. #if CONFIG_CBS_H265
  53. AV_CODEC_ID_H265,
  54. #endif
  55. #if CONFIG_CBS_JPEG
  56. AV_CODEC_ID_MJPEG,
  57. #endif
  58. #if CONFIG_CBS_MPEG2
  59. AV_CODEC_ID_MPEG2VIDEO,
  60. #endif
  61. #if CONFIG_CBS_VP9
  62. AV_CODEC_ID_VP9,
  63. #endif
  64. AV_CODEC_ID_NONE
  65. };
  66. int ff_cbs_init(CodedBitstreamContext **ctx_ptr,
  67. enum AVCodecID codec_id, void *log_ctx)
  68. {
  69. CodedBitstreamContext *ctx;
  70. const CodedBitstreamType *type;
  71. int i;
  72. type = NULL;
  73. for (i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) {
  74. if (cbs_type_table[i]->codec_id == codec_id) {
  75. type = cbs_type_table[i];
  76. break;
  77. }
  78. }
  79. if (!type)
  80. return AVERROR(EINVAL);
  81. ctx = av_mallocz(sizeof(*ctx));
  82. if (!ctx)
  83. return AVERROR(ENOMEM);
  84. ctx->log_ctx = log_ctx;
  85. ctx->codec = type;
  86. if (type->priv_data_size) {
  87. ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
  88. if (!ctx->priv_data) {
  89. av_freep(&ctx);
  90. return AVERROR(ENOMEM);
  91. }
  92. }
  93. ctx->decompose_unit_types = NULL;
  94. ctx->trace_enable = 0;
  95. ctx->trace_level = AV_LOG_TRACE;
  96. *ctx_ptr = ctx;
  97. return 0;
  98. }
  99. void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
  100. {
  101. CodedBitstreamContext *ctx = *ctx_ptr;
  102. if (!ctx)
  103. return;
  104. if (ctx->codec && ctx->codec->close)
  105. ctx->codec->close(ctx);
  106. av_freep(&ctx->write_buffer);
  107. av_freep(&ctx->priv_data);
  108. av_freep(ctx_ptr);
  109. }
  110. static void cbs_unit_uninit(CodedBitstreamContext *ctx,
  111. CodedBitstreamUnit *unit)
  112. {
  113. av_buffer_unref(&unit->content_ref);
  114. unit->content = NULL;
  115. av_buffer_unref(&unit->data_ref);
  116. unit->data = NULL;
  117. unit->data_size = 0;
  118. unit->data_bit_padding = 0;
  119. }
  120. void ff_cbs_fragment_reset(CodedBitstreamContext *ctx,
  121. CodedBitstreamFragment *frag)
  122. {
  123. int i;
  124. for (i = 0; i < frag->nb_units; i++)
  125. cbs_unit_uninit(ctx, &frag->units[i]);
  126. frag->nb_units = 0;
  127. av_buffer_unref(&frag->data_ref);
  128. frag->data = NULL;
  129. frag->data_size = 0;
  130. frag->data_bit_padding = 0;
  131. }
  132. void ff_cbs_fragment_free(CodedBitstreamContext *ctx,
  133. CodedBitstreamFragment *frag)
  134. {
  135. ff_cbs_fragment_reset(ctx, frag);
  136. av_freep(&frag->units);
  137. frag->nb_units_allocated = 0;
  138. }
  139. static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
  140. CodedBitstreamFragment *frag)
  141. {
  142. int err, i, j;
  143. for (i = 0; i < frag->nb_units; i++) {
  144. CodedBitstreamUnit *unit = &frag->units[i];
  145. if (ctx->decompose_unit_types) {
  146. for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
  147. if (ctx->decompose_unit_types[j] == unit->type)
  148. break;
  149. }
  150. if (j >= ctx->nb_decompose_unit_types)
  151. continue;
  152. }
  153. av_buffer_unref(&unit->content_ref);
  154. unit->content = NULL;
  155. av_assert0(unit->data && unit->data_ref);
  156. err = ctx->codec->read_unit(ctx, unit);
  157. if (err == AVERROR(ENOSYS)) {
  158. av_log(ctx->log_ctx, AV_LOG_VERBOSE,
  159. "Decomposition unimplemented for unit %d "
  160. "(type %"PRIu32").\n", i, unit->type);
  161. } else if (err < 0) {
  162. av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
  163. "(type %"PRIu32").\n", i, unit->type);
  164. return err;
  165. }
  166. }
  167. return 0;
  168. }
  169. static int cbs_fill_fragment_data(CodedBitstreamContext *ctx,
  170. CodedBitstreamFragment *frag,
  171. const uint8_t *data, size_t size)
  172. {
  173. av_assert0(!frag->data && !frag->data_ref);
  174. frag->data_ref =
  175. av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
  176. if (!frag->data_ref)
  177. return AVERROR(ENOMEM);
  178. frag->data = frag->data_ref->data;
  179. frag->data_size = size;
  180. memcpy(frag->data, data, size);
  181. memset(frag->data + size, 0,
  182. AV_INPUT_BUFFER_PADDING_SIZE);
  183. return 0;
  184. }
  185. int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
  186. CodedBitstreamFragment *frag,
  187. const AVCodecParameters *par)
  188. {
  189. int err;
  190. err = cbs_fill_fragment_data(ctx, frag, par->extradata,
  191. par->extradata_size);
  192. if (err < 0)
  193. return err;
  194. err = ctx->codec->split_fragment(ctx, frag, 1);
  195. if (err < 0)
  196. return err;
  197. return cbs_read_fragment_content(ctx, frag);
  198. }
  199. int ff_cbs_read_packet(CodedBitstreamContext *ctx,
  200. CodedBitstreamFragment *frag,
  201. const AVPacket *pkt)
  202. {
  203. int err;
  204. if (pkt->buf) {
  205. frag->data_ref = av_buffer_ref(pkt->buf);
  206. if (!frag->data_ref)
  207. return AVERROR(ENOMEM);
  208. frag->data = pkt->data;
  209. frag->data_size = pkt->size;
  210. } else {
  211. err = cbs_fill_fragment_data(ctx, frag, pkt->data, pkt->size);
  212. if (err < 0)
  213. return err;
  214. }
  215. err = ctx->codec->split_fragment(ctx, frag, 0);
  216. if (err < 0)
  217. return err;
  218. return cbs_read_fragment_content(ctx, frag);
  219. }
  220. int ff_cbs_read(CodedBitstreamContext *ctx,
  221. CodedBitstreamFragment *frag,
  222. const uint8_t *data, size_t size)
  223. {
  224. int err;
  225. err = cbs_fill_fragment_data(ctx, frag, data, size);
  226. if (err < 0)
  227. return err;
  228. err = ctx->codec->split_fragment(ctx, frag, 0);
  229. if (err < 0)
  230. return err;
  231. return cbs_read_fragment_content(ctx, frag);
  232. }
  233. static int cbs_write_unit_data(CodedBitstreamContext *ctx,
  234. CodedBitstreamUnit *unit)
  235. {
  236. PutBitContext pbc;
  237. int ret;
  238. if (!ctx->write_buffer) {
  239. // Initial write buffer size is 1MB.
  240. ctx->write_buffer_size = 1024 * 1024;
  241. reallocate_and_try_again:
  242. ret = av_reallocp(&ctx->write_buffer, ctx->write_buffer_size);
  243. if (ret < 0) {
  244. av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a "
  245. "sufficiently large write buffer (last attempt "
  246. "%"SIZE_SPECIFIER" bytes).\n", ctx->write_buffer_size);
  247. return ret;
  248. }
  249. }
  250. init_put_bits(&pbc, ctx->write_buffer, ctx->write_buffer_size);
  251. ret = ctx->codec->write_unit(ctx, unit, &pbc);
  252. if (ret < 0) {
  253. if (ret == AVERROR(ENOSPC)) {
  254. // Overflow.
  255. if (ctx->write_buffer_size == INT_MAX / 8)
  256. return AVERROR(ENOMEM);
  257. ctx->write_buffer_size = FFMIN(2 * ctx->write_buffer_size, INT_MAX / 8);
  258. goto reallocate_and_try_again;
  259. }
  260. // Write failed for some other reason.
  261. return ret;
  262. }
  263. // Overflow but we didn't notice.
  264. av_assert0(put_bits_count(&pbc) <= 8 * ctx->write_buffer_size);
  265. if (put_bits_count(&pbc) % 8)
  266. unit->data_bit_padding = 8 - put_bits_count(&pbc) % 8;
  267. else
  268. unit->data_bit_padding = 0;
  269. flush_put_bits(&pbc);
  270. ret = ff_cbs_alloc_unit_data(ctx, unit, put_bits_count(&pbc) / 8);
  271. if (ret < 0)
  272. return ret;
  273. memcpy(unit->data, ctx->write_buffer, unit->data_size);
  274. return 0;
  275. }
  276. int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
  277. CodedBitstreamFragment *frag)
  278. {
  279. int err, i;
  280. for (i = 0; i < frag->nb_units; i++) {
  281. CodedBitstreamUnit *unit = &frag->units[i];
  282. if (!unit->content)
  283. continue;
  284. av_buffer_unref(&unit->data_ref);
  285. unit->data = NULL;
  286. err = cbs_write_unit_data(ctx, unit);
  287. if (err < 0) {
  288. av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
  289. "(type %"PRIu32").\n", i, unit->type);
  290. return err;
  291. }
  292. av_assert0(unit->data && unit->data_ref);
  293. }
  294. av_buffer_unref(&frag->data_ref);
  295. frag->data = NULL;
  296. err = ctx->codec->assemble_fragment(ctx, frag);
  297. if (err < 0) {
  298. av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
  299. return err;
  300. }
  301. av_assert0(frag->data && frag->data_ref);
  302. return 0;
  303. }
  304. int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
  305. AVCodecParameters *par,
  306. CodedBitstreamFragment *frag)
  307. {
  308. int err;
  309. err = ff_cbs_write_fragment_data(ctx, frag);
  310. if (err < 0)
  311. return err;
  312. av_freep(&par->extradata);
  313. par->extradata = av_malloc(frag->data_size +
  314. AV_INPUT_BUFFER_PADDING_SIZE);
  315. if (!par->extradata)
  316. return AVERROR(ENOMEM);
  317. memcpy(par->extradata, frag->data, frag->data_size);
  318. memset(par->extradata + frag->data_size, 0,
  319. AV_INPUT_BUFFER_PADDING_SIZE);
  320. par->extradata_size = frag->data_size;
  321. return 0;
  322. }
  323. int ff_cbs_write_packet(CodedBitstreamContext *ctx,
  324. AVPacket *pkt,
  325. CodedBitstreamFragment *frag)
  326. {
  327. AVBufferRef *buf;
  328. int err;
  329. err = ff_cbs_write_fragment_data(ctx, frag);
  330. if (err < 0)
  331. return err;
  332. buf = av_buffer_ref(frag->data_ref);
  333. if (!buf)
  334. return AVERROR(ENOMEM);
  335. av_buffer_unref(&pkt->buf);
  336. pkt->buf = buf;
  337. pkt->data = frag->data;
  338. pkt->size = frag->data_size;
  339. return 0;
  340. }
  341. void ff_cbs_trace_header(CodedBitstreamContext *ctx,
  342. const char *name)
  343. {
  344. if (!ctx->trace_enable)
  345. return;
  346. av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
  347. }
  348. void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
  349. const char *str, const int *subscripts,
  350. const char *bits, int64_t value)
  351. {
  352. char name[256];
  353. size_t name_len, bits_len;
  354. int pad, subs, i, j, k, n;
  355. if (!ctx->trace_enable)
  356. return;
  357. av_assert0(value >= INT_MIN && value <= UINT32_MAX);
  358. subs = subscripts ? subscripts[0] : 0;
  359. n = 0;
  360. for (i = j = 0; str[i];) {
  361. if (str[i] == '[') {
  362. if (n < subs) {
  363. ++n;
  364. k = snprintf(name + j, sizeof(name) - j, "[%d", subscripts[n]);
  365. av_assert0(k > 0 && j + k < sizeof(name));
  366. j += k;
  367. for (++i; str[i] && str[i] != ']'; i++);
  368. av_assert0(str[i] == ']');
  369. } else {
  370. while (str[i] && str[i] != ']')
  371. name[j++] = str[i++];
  372. av_assert0(str[i] == ']');
  373. }
  374. } else {
  375. av_assert0(j + 1 < sizeof(name));
  376. name[j++] = str[i++];
  377. }
  378. }
  379. av_assert0(j + 1 < sizeof(name));
  380. name[j] = 0;
  381. av_assert0(n == subs);
  382. name_len = strlen(name);
  383. bits_len = strlen(bits);
  384. if (name_len + bits_len > 60)
  385. pad = bits_len + 2;
  386. else
  387. pad = 61 - name_len;
  388. av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %"PRId64"\n",
  389. position, name, pad, bits, value);
  390. }
  391. int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
  392. int width, const char *name,
  393. const int *subscripts, uint32_t *write_to,
  394. uint32_t range_min, uint32_t range_max)
  395. {
  396. uint32_t value;
  397. int position;
  398. av_assert0(width > 0 && width <= 32);
  399. if (get_bits_left(gbc) < width) {
  400. av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
  401. "%s: bitstream ended.\n", name);
  402. return AVERROR_INVALIDDATA;
  403. }
  404. if (ctx->trace_enable)
  405. position = get_bits_count(gbc);
  406. value = get_bits_long(gbc, width);
  407. if (ctx->trace_enable) {
  408. char bits[33];
  409. int i;
  410. for (i = 0; i < width; i++)
  411. bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
  412. bits[i] = 0;
  413. ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
  414. bits, value);
  415. }
  416. if (value < range_min || value > range_max) {
  417. av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
  418. "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
  419. name, value, range_min, range_max);
  420. return AVERROR_INVALIDDATA;
  421. }
  422. *write_to = value;
  423. return 0;
  424. }
  425. int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
  426. int width, const char *name,
  427. const int *subscripts, uint32_t value,
  428. uint32_t range_min, uint32_t range_max)
  429. {
  430. av_assert0(width > 0 && width <= 32);
  431. if (value < range_min || value > range_max) {
  432. av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
  433. "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
  434. name, value, range_min, range_max);
  435. return AVERROR_INVALIDDATA;
  436. }
  437. if (put_bits_left(pbc) < width)
  438. return AVERROR(ENOSPC);
  439. if (ctx->trace_enable) {
  440. char bits[33];
  441. int i;
  442. for (i = 0; i < width; i++)
  443. bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
  444. bits[i] = 0;
  445. ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
  446. name, subscripts, bits, value);
  447. }
  448. if (width < 32)
  449. put_bits(pbc, width, value);
  450. else
  451. put_bits32(pbc, value);
  452. return 0;
  453. }
  454. int ff_cbs_read_signed(CodedBitstreamContext *ctx, GetBitContext *gbc,
  455. int width, const char *name,
  456. const int *subscripts, int32_t *write_to,
  457. int32_t range_min, int32_t range_max)
  458. {
  459. int32_t value;
  460. int position;
  461. av_assert0(width > 0 && width <= 32);
  462. if (get_bits_left(gbc) < width) {
  463. av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
  464. "%s: bitstream ended.\n", name);
  465. return AVERROR_INVALIDDATA;
  466. }
  467. if (ctx->trace_enable)
  468. position = get_bits_count(gbc);
  469. value = get_sbits_long(gbc, width);
  470. if (ctx->trace_enable) {
  471. char bits[33];
  472. int i;
  473. for (i = 0; i < width; i++)
  474. bits[i] = value & (1U << (width - i - 1)) ? '1' : '0';
  475. bits[i] = 0;
  476. ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
  477. bits, value);
  478. }
  479. if (value < range_min || value > range_max) {
  480. av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
  481. "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
  482. name, value, range_min, range_max);
  483. return AVERROR_INVALIDDATA;
  484. }
  485. *write_to = value;
  486. return 0;
  487. }
  488. int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc,
  489. int width, const char *name,
  490. const int *subscripts, int32_t value,
  491. int32_t range_min, int32_t range_max)
  492. {
  493. av_assert0(width > 0 && width <= 32);
  494. if (value < range_min || value > range_max) {
  495. av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
  496. "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
  497. name, value, range_min, range_max);
  498. return AVERROR_INVALIDDATA;
  499. }
  500. if (put_bits_left(pbc) < width)
  501. return AVERROR(ENOSPC);
  502. if (ctx->trace_enable) {
  503. char bits[33];
  504. int i;
  505. for (i = 0; i < width; i++)
  506. bits[i] = value & (1U << (width - i - 1)) ? '1' : '0';
  507. bits[i] = 0;
  508. ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
  509. name, subscripts, bits, value);
  510. }
  511. if (width < 32)
  512. put_sbits(pbc, width, value);
  513. else
  514. put_bits32(pbc, value);
  515. return 0;
  516. }
  517. int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
  518. CodedBitstreamUnit *unit,
  519. size_t size,
  520. void (*free)(void *opaque, uint8_t *data))
  521. {
  522. av_assert0(!unit->content && !unit->content_ref);
  523. unit->content = av_mallocz(size);
  524. if (!unit->content)
  525. return AVERROR(ENOMEM);
  526. unit->content_ref = av_buffer_create(unit->content, size,
  527. free, NULL, 0);
  528. if (!unit->content_ref) {
  529. av_freep(&unit->content);
  530. return AVERROR(ENOMEM);
  531. }
  532. return 0;
  533. }
  534. int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx,
  535. CodedBitstreamUnit *unit,
  536. size_t size)
  537. {
  538. av_assert0(!unit->data && !unit->data_ref);
  539. unit->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
  540. if (!unit->data_ref)
  541. return AVERROR(ENOMEM);
  542. unit->data = unit->data_ref->data;
  543. unit->data_size = size;
  544. memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
  545. return 0;
  546. }
  547. static int cbs_insert_unit(CodedBitstreamContext *ctx,
  548. CodedBitstreamFragment *frag,
  549. int position)
  550. {
  551. CodedBitstreamUnit *units;
  552. if (frag->nb_units < frag->nb_units_allocated) {
  553. units = frag->units;
  554. if (position < frag->nb_units)
  555. memmove(units + position + 1, units + position,
  556. (frag->nb_units - position) * sizeof(*units));
  557. } else {
  558. units = av_malloc_array(frag->nb_units*2 + 1, sizeof(*units));
  559. if (!units)
  560. return AVERROR(ENOMEM);
  561. frag->nb_units_allocated = 2*frag->nb_units_allocated + 1;
  562. if (position > 0)
  563. memcpy(units, frag->units, position * sizeof(*units));
  564. if (position < frag->nb_units)
  565. memcpy(units + position + 1, frag->units + position,
  566. (frag->nb_units - position) * sizeof(*units));
  567. }
  568. memset(units + position, 0, sizeof(*units));
  569. if (units != frag->units) {
  570. av_free(frag->units);
  571. frag->units = units;
  572. }
  573. ++frag->nb_units;
  574. return 0;
  575. }
  576. int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
  577. CodedBitstreamFragment *frag,
  578. int position,
  579. CodedBitstreamUnitType type,
  580. void *content,
  581. AVBufferRef *content_buf)
  582. {
  583. CodedBitstreamUnit *unit;
  584. AVBufferRef *content_ref;
  585. int err;
  586. if (position == -1)
  587. position = frag->nb_units;
  588. av_assert0(position >= 0 && position <= frag->nb_units);
  589. if (content_buf) {
  590. content_ref = av_buffer_ref(content_buf);
  591. if (!content_ref)
  592. return AVERROR(ENOMEM);
  593. } else {
  594. content_ref = NULL;
  595. }
  596. err = cbs_insert_unit(ctx, frag, position);
  597. if (err < 0) {
  598. av_buffer_unref(&content_ref);
  599. return err;
  600. }
  601. unit = &frag->units[position];
  602. unit->type = type;
  603. unit->content = content;
  604. unit->content_ref = content_ref;
  605. return 0;
  606. }
  607. int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
  608. CodedBitstreamFragment *frag,
  609. int position,
  610. CodedBitstreamUnitType type,
  611. uint8_t *data, size_t data_size,
  612. AVBufferRef *data_buf)
  613. {
  614. CodedBitstreamUnit *unit;
  615. AVBufferRef *data_ref;
  616. int err;
  617. if (position == -1)
  618. position = frag->nb_units;
  619. av_assert0(position >= 0 && position <= frag->nb_units);
  620. if (data_buf)
  621. data_ref = av_buffer_ref(data_buf);
  622. else
  623. data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
  624. if (!data_ref) {
  625. if (!data_buf)
  626. av_free(data);
  627. return AVERROR(ENOMEM);
  628. }
  629. err = cbs_insert_unit(ctx, frag, position);
  630. if (err < 0) {
  631. av_buffer_unref(&data_ref);
  632. return err;
  633. }
  634. unit = &frag->units[position];
  635. unit->type = type;
  636. unit->data = data;
  637. unit->data_size = data_size;
  638. unit->data_ref = data_ref;
  639. return 0;
  640. }
  641. void ff_cbs_delete_unit(CodedBitstreamContext *ctx,
  642. CodedBitstreamFragment *frag,
  643. int position)
  644. {
  645. av_assert0(0 <= position && position < frag->nb_units
  646. && "Unit to be deleted not in fragment.");
  647. cbs_unit_uninit(ctx, &frag->units[position]);
  648. --frag->nb_units;
  649. if (frag->nb_units > 0)
  650. memmove(frag->units + position,
  651. frag->units + position + 1,
  652. (frag->nb_units - position) * sizeof(*frag->units));
  653. }