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.

196 lines
5.7KB

  1. /*
  2. * HEVC MP4 to Annex B byte stream format filter
  3. * copyright (c) 2015 Anton Khirnov
  4. *
  5. * This file is part of Libav.
  6. *
  7. * Libav is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * Libav is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with Libav; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <string.h>
  22. #include "libavutil/intreadwrite.h"
  23. #include "libavutil/mem.h"
  24. #include "avcodec.h"
  25. #include "bsf.h"
  26. #include "bytestream.h"
  27. #include "hevc.h"
  28. #define MIN_HEVCC_LENGTH 23
  29. typedef struct HEVCBSFContext {
  30. uint8_t length_size;
  31. int extradata_parsed;
  32. } HEVCBSFContext;
  33. static int hevc_extradata_to_annexb(AVBSFContext *ctx)
  34. {
  35. GetByteContext gb;
  36. int length_size, num_arrays, i, j;
  37. int ret = 0;
  38. uint8_t *new_extradata = NULL;
  39. size_t new_extradata_size = 0;;
  40. bytestream2_init(&gb, ctx->par_in->extradata, ctx->par_in->extradata_size);
  41. bytestream2_skip(&gb, 21);
  42. length_size = (bytestream2_get_byte(&gb) & 3) + 1;
  43. num_arrays = bytestream2_get_byte(&gb);
  44. for (i = 0; i < num_arrays; i++) {
  45. int type = bytestream2_get_byte(&gb) & 0x3f;
  46. int cnt = bytestream2_get_be16(&gb);
  47. if (!(type == NAL_VPS || type == NAL_SPS || type == NAL_PPS ||
  48. type == NAL_SEI_PREFIX || type == NAL_SEI_SUFFIX)) {
  49. av_log(ctx, AV_LOG_ERROR, "Invalid NAL unit type in extradata: %d\n",
  50. type);
  51. ret = AVERROR_INVALIDDATA;
  52. goto fail;
  53. }
  54. for (j = 0; j < cnt; j++) {
  55. int nalu_len = bytestream2_get_be16(&gb);
  56. if (4 + AV_INPUT_BUFFER_PADDING_SIZE + nalu_len > SIZE_MAX - new_extradata_size) {
  57. ret = AVERROR_INVALIDDATA;
  58. goto fail;
  59. }
  60. ret = av_reallocp(&new_extradata, new_extradata_size + nalu_len + 4 + AV_INPUT_BUFFER_PADDING_SIZE);
  61. if (ret < 0)
  62. goto fail;
  63. AV_WB32(new_extradata + new_extradata_size, 1); // add the startcode
  64. bytestream2_get_buffer(&gb, new_extradata + new_extradata_size + 4, nalu_len);
  65. new_extradata_size += 4 + nalu_len;
  66. memset(new_extradata + new_extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
  67. }
  68. }
  69. av_freep(&ctx->par_out->extradata);
  70. ctx->par_out->extradata = new_extradata;
  71. ctx->par_out->extradata_size = new_extradata_size;
  72. if (!new_extradata_size)
  73. av_log(ctx, AV_LOG_WARNING, "No parameter sets in the extradata\n");
  74. return length_size;
  75. fail:
  76. av_freep(&new_extradata);
  77. return ret;
  78. }
  79. static int hevc_mp4toannexb_init(AVBSFContext *ctx)
  80. {
  81. HEVCBSFContext *s = ctx->priv_data;
  82. int ret;
  83. if (ctx->par_in->extradata_size < MIN_HEVCC_LENGTH ||
  84. AV_RB24(ctx->par_in->extradata) == 1 ||
  85. AV_RB32(ctx->par_in->extradata) == 1) {
  86. av_log(ctx, AV_LOG_VERBOSE,
  87. "The input looks like it is Annex B already\n");
  88. } else {
  89. ret = hevc_extradata_to_annexb(ctx);
  90. if (ret < 0)
  91. return ret;
  92. s->length_size = ret;
  93. s->extradata_parsed = 1;
  94. }
  95. return 0;
  96. }
  97. static int hevc_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out)
  98. {
  99. HEVCBSFContext *s = ctx->priv_data;
  100. AVPacket *in;
  101. GetByteContext gb;
  102. int got_irap = 0;
  103. int i, ret = 0;
  104. ret = ff_bsf_get_packet(ctx, &in);
  105. if (ret < 0)
  106. return ret;
  107. if (!s->extradata_parsed) {
  108. av_packet_move_ref(out, in);
  109. av_packet_free(&in);
  110. return 0;
  111. }
  112. bytestream2_init(&gb, in->data, in->size);
  113. while (bytestream2_get_bytes_left(&gb)) {
  114. uint32_t nalu_size = 0;
  115. int nalu_type;
  116. int is_irap, add_extradata, extra_size, prev_size;
  117. for (i = 0; i < s->length_size; i++)
  118. nalu_size = (nalu_size << 8) | bytestream2_get_byte(&gb);
  119. nalu_type = (bytestream2_peek_byte(&gb) >> 1) & 0x3f;
  120. /* prepend extradata to IRAP frames */
  121. is_irap = nalu_type >= 16 && nalu_type <= 23;
  122. add_extradata = is_irap && !got_irap;
  123. extra_size = add_extradata * ctx->par_out->extradata_size;
  124. got_irap |= is_irap;
  125. if (SIZE_MAX - nalu_size < 4 ||
  126. SIZE_MAX - 4 - nalu_size < extra_size) {
  127. ret = AVERROR_INVALIDDATA;
  128. goto fail;
  129. }
  130. prev_size = out->size;
  131. ret = av_grow_packet(out, 4 + nalu_size + extra_size);
  132. if (ret < 0)
  133. goto fail;
  134. if (add_extradata)
  135. memcpy(out->data + prev_size, ctx->par_out->extradata, extra_size);
  136. AV_WB32(out->data + prev_size + extra_size, 1);
  137. bytestream2_get_buffer(&gb, out->data + prev_size + 4 + extra_size, nalu_size);
  138. }
  139. ret = av_packet_copy_props(out, in);
  140. if (ret < 0)
  141. goto fail;
  142. fail:
  143. if (ret < 0)
  144. av_packet_unref(out);
  145. av_packet_free(&in);
  146. return ret;
  147. }
  148. static const enum AVCodecID codec_ids[] = {
  149. AV_CODEC_ID_HEVC, AV_CODEC_ID_NONE,
  150. };
  151. const AVBitStreamFilter ff_hevc_mp4toannexb_bsf = {
  152. .name = "hevc_mp4toannexb",
  153. .priv_data_size = sizeof(HEVCBSFContext),
  154. .init = hevc_mp4toannexb_init,
  155. .filter = hevc_mp4toannexb_filter,
  156. .codec_ids = codec_ids,
  157. };