/src/ffmpeg/libavcodec/bsf/hapqa_extract.c
Line | Count | Source (jump to first uncovered line) |
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 | | /** |
23 | | * @file |
24 | | * HAPQA extract bitstream filter |
25 | | * extract one of the two textures of the HAQA |
26 | | */ |
27 | | |
28 | | #include "bsf.h" |
29 | | #include "bsf_internal.h" |
30 | | #include "bytestream.h" |
31 | | #include "hap.h" |
32 | | |
33 | | #include "libavutil/opt.h" |
34 | | |
35 | | typedef struct HapqaExtractContext { |
36 | | const AVClass *class; |
37 | | int texture;/* index of the texture to keep (0 for rgb or 1 for alpha) */ |
38 | | } HapqaExtractContext; |
39 | | |
40 | 4.20k | static int check_texture(HapqaExtractContext *ctx, int section_type) { |
41 | 4.20k | if (((ctx->texture == 0)&&((section_type & 0x0F) == 0x0F)) || /* HapQ texture and rgb extract */ |
42 | 4.20k | ((ctx->texture == 1)&&((section_type & 0x0F) == 0x01))) /* HapAlphaOnly texture and alpha extract */ |
43 | 1.43k | { |
44 | 1.43k | return 1; /* the texture is the one to keep */ |
45 | 2.77k | } else { |
46 | 2.77k | return 0; |
47 | 2.77k | } |
48 | 4.20k | } |
49 | | |
50 | | static int hapqa_extract(AVBSFContext *bsf, AVPacket *pkt) |
51 | 10.1k | { |
52 | 10.1k | HapqaExtractContext *ctx = bsf->priv_data; |
53 | 10.1k | GetByteContext gbc; |
54 | 10.1k | int section_size; |
55 | 10.1k | enum HapSectionType section_type; |
56 | 10.1k | int start_section_size; |
57 | 10.1k | int target_packet_size = 0; |
58 | 10.1k | int ret = 0; |
59 | | |
60 | 10.1k | ret = ff_bsf_get_packet_ref(bsf, pkt); |
61 | 10.1k | if (ret < 0) |
62 | 1.72k | return ret; |
63 | | |
64 | 8.44k | bytestream2_init(&gbc, pkt->data, pkt->size); |
65 | 8.44k | ret = ff_hap_parse_section_header(&gbc, §ion_size, §ion_type); |
66 | 8.44k | if (ret != 0) |
67 | 4.02k | goto fail; |
68 | | |
69 | 4.42k | if ((section_type & 0x0F) != 0x0D) { |
70 | 580 | av_log(bsf, AV_LOG_ERROR, "Invalid section type for HAPQA %#04x.\n", section_type & 0x0F); |
71 | 580 | ret = AVERROR_INVALIDDATA; |
72 | 580 | goto fail; |
73 | 580 | } |
74 | | |
75 | 3.84k | start_section_size = 4; |
76 | | |
77 | 3.84k | bytestream2_seek(&gbc, start_section_size, SEEK_SET);/* go to start of the first texture */ |
78 | | |
79 | 3.84k | ret = ff_hap_parse_section_header(&gbc, §ion_size, §ion_type); |
80 | 3.84k | if (ret != 0) |
81 | 1.08k | goto fail; |
82 | | |
83 | 2.75k | target_packet_size = section_size + 4; |
84 | | |
85 | 2.75k | if (check_texture(ctx, section_type) == 0) { /* the texture is not the one to keep */ |
86 | 2.11k | start_section_size += 4 + section_size; |
87 | 2.11k | bytestream2_seek(&gbc, start_section_size, SEEK_SET);/* go to start of the second texture */ |
88 | 2.11k | ret = ff_hap_parse_section_header(&gbc, §ion_size, §ion_type); |
89 | 2.11k | if (ret != 0) |
90 | 664 | goto fail; |
91 | | |
92 | 1.45k | target_packet_size = section_size + 4; |
93 | | |
94 | 1.45k | if (check_texture(ctx, section_type) == 0){ /* the second texture is not the one to keep */ |
95 | 656 | av_log(bsf, AV_LOG_ERROR, "No valid texture found.\n"); |
96 | 656 | ret = AVERROR_INVALIDDATA; |
97 | 656 | goto fail; |
98 | 656 | } |
99 | 1.45k | } |
100 | | |
101 | 1.43k | pkt->data += start_section_size; |
102 | 1.43k | pkt->size = target_packet_size; |
103 | | |
104 | 8.44k | fail: |
105 | 8.44k | if (ret < 0) |
106 | 7.01k | av_packet_unref(pkt); |
107 | 8.44k | return ret; |
108 | 1.43k | } |
109 | | |
110 | | static const enum AVCodecID codec_ids[] = { |
111 | | AV_CODEC_ID_HAP, AV_CODEC_ID_NONE, |
112 | | }; |
113 | | |
114 | | #define OFFSET(x) offsetof(HapqaExtractContext, x) |
115 | | #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_BSF_PARAM) |
116 | | static const AVOption options[] = { |
117 | | { "texture", "texture to keep", OFFSET(texture), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, .unit = "texture" }, |
118 | | { "color", "keep HapQ texture", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, .unit = "texture" }, |
119 | | { "alpha", "keep HapAlphaOnly texture", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, .unit = "texture" }, |
120 | | { NULL }, |
121 | | }; |
122 | | |
123 | | static const AVClass hapqa_extract_class = { |
124 | | .class_name = "hapqa_extract_bsf", |
125 | | .item_name = av_default_item_name, |
126 | | .option = options, |
127 | | .version = LIBAVUTIL_VERSION_INT, |
128 | | }; |
129 | | |
130 | | const FFBitStreamFilter ff_hapqa_extract_bsf = { |
131 | | .p.name = "hapqa_extract", |
132 | | .p.codec_ids = codec_ids, |
133 | | .p.priv_class = &hapqa_extract_class, |
134 | | .priv_data_size = sizeof(HapqaExtractContext), |
135 | | .filter = hapqa_extract, |
136 | | }; |