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.

135 lines
4.3KB

  1. /*
  2. * HAPQA extract bitstream filter
  3. * Copyright (c) 2017 Jokyo Images
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg 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. * FFmpeg 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 FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * @file
  23. * HAPQA extract bitstream filter
  24. * extract one of the two textures of the HAQA
  25. */
  26. #include "avcodec.h"
  27. #include "bsf.h"
  28. #include "bytestream.h"
  29. #include "hap.h"
  30. typedef struct HapqaExtractContext {
  31. const AVClass *class;
  32. int texture;/* index of the texture to keep (0 for rgb or 1 for alpha) */
  33. } HapqaExtractContext;
  34. static int check_texture(HapqaExtractContext *ctx, int section_type) {
  35. if (((ctx->texture == 0)&&((section_type & 0x0F) == 0x0F)) || /* HapQ texture and rgb extract */
  36. ((ctx->texture == 1)&&((section_type & 0x0F) == 0x01))) /* HapAlphaOnly texture and alpha extract */
  37. {
  38. return 1; /* the texture is the one to keep */
  39. } else {
  40. return 0;
  41. }
  42. }
  43. static int hapqa_extract(AVBSFContext *bsf, AVPacket *pkt)
  44. {
  45. HapqaExtractContext *ctx = bsf->priv_data;
  46. GetByteContext gbc;
  47. int section_size;
  48. enum HapSectionType section_type;
  49. int start_section_size;
  50. int target_packet_size = 0;
  51. int ret = 0;
  52. ret = ff_bsf_get_packet_ref(bsf, pkt);
  53. if (ret < 0)
  54. return ret;
  55. bytestream2_init(&gbc, pkt->data, pkt->size);
  56. ret = ff_hap_parse_section_header(&gbc, &section_size, &section_type);
  57. if (ret != 0)
  58. goto fail;
  59. if ((section_type & 0x0F) != 0x0D) {
  60. av_log(bsf, AV_LOG_ERROR, "Invalid section type for HAPQA %#04x.\n", section_type & 0x0F);
  61. ret = AVERROR_INVALIDDATA;
  62. goto fail;
  63. }
  64. start_section_size = 4;
  65. bytestream2_seek(&gbc, start_section_size, SEEK_SET);/* go to start of the first texture */
  66. ret = ff_hap_parse_section_header(&gbc, &section_size, &section_type);
  67. if (ret != 0)
  68. goto fail;
  69. target_packet_size = section_size + 4;
  70. if (check_texture(ctx, section_type) == 0) { /* the texture is not the one to keep */
  71. start_section_size += 4 + section_size;
  72. bytestream2_seek(&gbc, start_section_size, SEEK_SET);/* go to start of the second texture */
  73. ret = ff_hap_parse_section_header(&gbc, &section_size, &section_type);
  74. if (ret != 0)
  75. goto fail;
  76. target_packet_size = section_size + 4;
  77. if (check_texture(ctx, section_type) == 0){ /* the second texture is not the one to keep */
  78. av_log(bsf, AV_LOG_ERROR, "No valid texture found.\n");
  79. ret = AVERROR_INVALIDDATA;
  80. goto fail;
  81. }
  82. }
  83. pkt->data += start_section_size;
  84. pkt->size = target_packet_size;
  85. fail:
  86. if (ret < 0)
  87. av_packet_unref(pkt);
  88. return ret;
  89. }
  90. static const enum AVCodecID codec_ids[] = {
  91. AV_CODEC_ID_HAP, AV_CODEC_ID_NONE,
  92. };
  93. #define OFFSET(x) offsetof(HapqaExtractContext, x)
  94. #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_BSF_PARAM)
  95. static const AVOption options[] = {
  96. { "texture", "texture to keep", OFFSET(texture), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, "texture" },
  97. { "color", "keep HapQ texture", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "texture" },
  98. { "alpha", "keep HapAlphaOnly texture", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "texture" },
  99. { NULL },
  100. };
  101. static const AVClass hapqa_extract_class = {
  102. .class_name = "hapqa_extract_bsf",
  103. .item_name = av_default_item_name,
  104. .option = options,
  105. .version = LIBAVUTIL_VERSION_INT,
  106. };
  107. const AVBitStreamFilter ff_hapqa_extract_bsf = {
  108. .name = "hapqa_extract",
  109. .filter = hapqa_extract,
  110. .priv_data_size = sizeof(HapqaExtractContext),
  111. .priv_class = &hapqa_extract_class,
  112. .codec_ids = codec_ids,
  113. };