什么叫总胆红素| 什么人容易得小脑萎缩| 女人手心热吃什么药好| as是什么意思| 神经酰胺是什么| 肝裂不宽是什么意思| 鼻子上的痣有什么寓意| 绝技是什么意思| 冠心病吃什么药| 日光浴是什么意思| 辞职是什么意思| 木耳不能和什么食物一起吃| 股骨头坏死什么症状| 月经血量少是什么原因| 肋软骨炎吃什么药最好| 脚上有水泡是什么原因| 草酸是什么| 常喝三七粉有什么好处| 什么一梦| 存款准备金率下调意味着什么| 头发不干就睡觉有什么危害| 葡萄和提子有什么区别| 董监高是什么意思| 情人的定义是什么| 22是什么意思| gd是什么牌子| 乐哉是什么意思| 毛囊炎吃什么药| 七月十三什么星座| 过敏能吃什么| 什么是御姐| 什么深似海| 补气血用什么泡水喝| 家里停电了打什么电话| 蝙蝠为什么倒挂着睡觉| 女人的逼是什么意思| 83年猪是什么命| 农历五月初五是什么节| 热伤风吃什么| 梦见上香是什么意思| lok是什么意思| 白蛋白偏高是什么原因| 北海特产有什么值得带| spv是什么| 胚芽是什么| 油茶是什么| 人为什么会便秘| 嘴唇紫色是什么原因| 桑是什么意思| 马卡龙为什么这么贵| 吃狗肉不能和什么一起吃| 中药龙骨是什么东西| 激光点痣后需要注意什么| 眉毛痒是什么原因| 家里进蝴蝶有什么预兆| b细胞是什么| 雪松香是什么味道| 大臣是什么意思| 女人吃什么| 为什么会有头皮屑| 股骨头坏死什么原因| 禁欲是什么意思| 麦字五行属什么| 人乳头瘤病毒阴性是什么意思| 齐白石擅长画什么| 250为什么是骂人的话| 肚兜是什么| 漂洗什么意思| 脚底起水泡是什么原因| 荻是什么意思| 吃什么才能减肥| 男生为什么会遗精| 练深蹲有什么好处| 女性肛门瘙痒用什么药| 高血糖能吃什么| 不以为意什么意思| 柚子是什么季节| 五月初五是什么星座| 224是什么星座| 妈妈的妈妈叫什么| 石榴石一般什么价位| 老人喝什么牛奶比较好| penguin是什么意思| 什么叫肺纤维化| 头晕目赤是什么意思| 1973年属牛是什么命| 人流是什么意思| 忙什么呢幽默的回答| 隋朝之前是什么朝代| 紫癜吃什么药| 梦见火灾预示什么| 中药学专业学什么| 好色是什么意思| 吃你鲍鱼是什么意思| 义务兵是什么意思| 追什么| 为什么吃了饭就想睡觉| 为什么肾阳虚很难恢复| 婴儿补铁吃什么铁剂| 印迹杂交技术检查什么| 心脑供血不足吃什么药效果最好| 皮肤过敏擦什么药膏好得快| 肠道感染吃什么消炎药| 补肾壮阳吃什么效果好| 男生射精什么感觉| 泡泡尿是什么毛病| 中老年补钙吃什么钙片好| 腰间盘突出吃什么药好| 维生素a中毒是什么症状| 一年一片避孕药叫什么| 吃什么治便秘最有效| 11月17是什么星座| 梦见被警察抓预示什么| 54年属什么| 品牌logo是什么意思| 大麦和小麦有什么区别| 正常白带是什么颜色| 喝什么可以降血压| 移花接木什么意思| 什么是标准预防| 右眼一直跳什么情况| 什么是腺肌症| 吃山竹有什么好处和坏处| 贾乃亮演过什么电视剧| 玉皇大帝姓什么| 作灶什么意思| 疝气手术是什么| 胎毛是什么| 山竹有什么功效和作用| 胃左边疼是什么原因| 白酒优级和一级有什么区别| 痹症是什么病| 牛黄安宫丸什么季节吃| 风热感冒吃什么消炎药| rv是什么品牌| 各什么各什么| 什么是药食同源| 子宫肌瘤吃什么药好| 脑鸣挂什么科| 卵黄囊偏大是什么原因| 手掌发红是什么原因| 真丝姆米是什么意思| 白羊座是什么性格| 骨折什么症状| 心率不齐是什么原因| 高什么远什么| 来姨妈为什么是黑色的血| 铂金是什么材质| 吉祥是什么意思| 蚂蚁代表什么生肖| 春梦是什么意思啊| 天麻加什么治头晕| 盐和醋泡脚有什么好处| 打飞机是什么意思| 三花五罗都是什么鱼| 脚底红润是什么原因| 肾与性功能有什么关系| iris是什么意思啊| 红薯用什么繁殖| 西安有什么特色美食| hcy是什么检查项目| 什么是抗阻运动| 降龙十八掌最后一掌叫什么| 桦树茸泡水喝有什么功效| 骨质疏松症有什么症状| 叶子为什么是绿色的| 什么叫元素| 马眼是什么| 少女怀春是什么意思| 急性子是什么意思| 吃什么补孕酮最快| 三月十九是什么星座| 什么是生命之本| 腹泻吃什么食物好| 独角兽是什么动物| 佛心果是什么东西| 牛瓦沟是什么部位| 粉刺是什么样的图片| 生性多疑是什么意思| 吃什么可以补钾| 俗不可耐是什么意思| 梦见别人流血是什么预兆| 木瓜什么味道| 什么土方治咳嗽最有效| 磷高有什么症状和危害| 总爱睡觉是什么原因| 八年是什么婚| yy是什么| 因果报应是什么意思| 左脸长痣代表什么| 什么方法| 3月16号是什么星座的| 七五年属什么| 打蛔虫吃什么药| 贫嘴是什么意思| 闭关修炼是什么意思| 眼睛酸疼是什么原因| 宫腔内钙化灶是什么意思| saba是什么药| 7月30号是什么星座| 早泄吃什么好| 什么是职业道德| 洗手做羹汤是什么意思| 马蹄铁什么时候发明的| 例假颜色发黑是什么原因| 过去的日子叫什么日| 舌苔发青是什么原因| 官方什么意思| 手发抖是什么原因| 小孩肚子痛挂什么科| gm是什么牌子| 寿者相什么意思| 怀孕前期有什么征兆| 回心转意是什么意思| 干眼症有什么症状| 什么炒菜好吃| 吃什么药头脑立刻清醒| 为什么手机会发烫| 泉州有什么特产| 白带豆腐渣状是什么原因造成的| kms是什么意思| 乳酸脱氢酶高是什么原因| 唇色深的人适合什么颜色的口红| 尿酸高是什么病| 肚子硬是什么原因| 哈西奈德溶液治什么病| 平板电脑是什么| 司令是什么军衔| 掉头发是缺什么维生素| 梦到鳄鱼是什么意思| 叶酸什么时候吃| 莫非的近义词是什么| 验孕棒一深一浅代表什么| 为什么一吃东西就拉肚子| 为什么医院不建议药流| 眼睛屈光不正是什么意思| 春回大地是指什么生肖| 风热感冒吃什么药| 支原体肺炎用什么药| 孤臣是什么意思| 主家是什么意思| 黄色配什么颜色好看| 白色鼻毛是什么原因| 牛肉烧什么菜好吃| 桃子和什么不能一起吃| 存款准备金率下调意味着什么| 桃子吃多了有什么坏处| 来世是什么意思| 疝气是什么病怎样治疗| 酒不醉人人自醉是什么意思| 二甲双胍不能和什么药一起吃| 寒冷性荨麻疹是什么原因引起的| gap是什么牌子的衣服| 残疾证有什么补贴| 山东的简称是什么| 端午是什么时候| 叫什么| 同型半胱氨酸偏高吃什么药| 粉底和气垫的区别是什么| 淘宝预售是什么意思| 半什么半什么| 枫叶是什么颜色| 飞车是什么意思| 脑血管狭窄吃什么药| 百度

大力开展企业文化建设 推进高速公路服务区健康发展


Directory: ../../../ffmpeg/
File: src/libavcodec/bsf/h264_metadata.c
Date: 2025-08-04 00:43:16
Exec Total Coverage
Lines: 57 252 22.6%
Functions: 3 5 60.0%
Branches: 54 238 22.7%

Line Branch Exec Source
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
19 #include "libavutil/avstring.h"
20 #include "libavutil/display.h"
21 #include "libavutil/common.h"
22 #include "libavutil/mem.h"
23 #include "libavutil/opt.h"
24
25 #include "bsf.h"
26 #include "bsf_internal.h"
27 #include "cbs.h"
28 #include "cbs_bsf.h"
29 #include "cbs_h264.h"
30 #include "cbs_sei.h"
31 #include "h264.h"
32 #include "h264_levels.h"
33 #include "h2645data.h"
34 #include "sei.h"
35
36 enum {
37 FLIP_HORIZONTAL = 1,
38 FLIP_VERTICAL = 2,
39 };
40
41 enum {
42 LEVEL_UNSET = -2,
43 LEVEL_AUTO = -1,
44 };
45
46 typedef struct H264MetadataContext {
47 CBSBSFContext common;
48
49 int done_first_au;
50
51 int aud;
52 H264RawAUD aud_nal;
53
54 AVRational sample_aspect_ratio;
55
56 int overscan_appropriate_flag;
57
58 int video_format;
59 int video_full_range_flag;
60 int colour_primaries;
61 int transfer_characteristics;
62 int matrix_coefficients;
63
64 int chroma_sample_loc_type;
65
66 AVRational tick_rate;
67 int fixed_frame_rate_flag;
68 int zero_new_constraint_set_flags;
69
70 int crop_left;
71 int crop_right;
72 int crop_top;
73 int crop_bottom;
74
75 const char *sei_user_data;
76 SEIRawUserDataUnregistered sei_user_data_payload;
77
78 int delete_filler;
79
80 int display_orientation;
81 double rotate;
82 int flip;
83 H264RawSEIDisplayOrientation display_orientation_payload;
84
85 int level;
86 } H264MetadataContext;
87
88
89 static int h264_metadata_insert_aud(AVBSFContext *bsf,
90 CodedBitstreamFragment *au)
91 {
92 H264MetadataContext *ctx = bsf->priv_data;
93 int primary_pic_type_mask = 0xff;
94 int err, i, j;
95
96 static const int primary_pic_type_table[] = {
97 0x084, // 2, 7
98 0x0a5, // 0, 2, 5, 7
99 0x0e7, // 0, 1, 2, 5, 6, 7
100 0x210, // 4, 9
101 0x318, // 3, 4, 8, 9
102 0x294, // 2, 4, 7, 9
103 0x3bd, // 0, 2, 3, 4, 5, 7, 8, 9
104 0x3ff, // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
105 };
106
107 for (i = 0; i < au->nb_units; i++) {
108 if (au->units[i].type == H264_NAL_SLICE ||
109 au->units[i].type == H264_NAL_IDR_SLICE) {
110 H264RawSlice *slice = au->units[i].content;
111 for (j = 0; j < FF_ARRAY_ELEMS(primary_pic_type_table); j++) {
112 if (!(primary_pic_type_table[j] &
113 (1 << slice->header.slice_type)))
114 primary_pic_type_mask &= ~(1 << j);
115 }
116 }
117 }
118 for (j = 0; j < FF_ARRAY_ELEMS(primary_pic_type_table); j++)
119 if (primary_pic_type_mask & (1 << j))
120 break;
121 if (j >= FF_ARRAY_ELEMS(primary_pic_type_table)) {
122 av_log(bsf, AV_LOG_ERROR, "No usable primary_pic_type: "
123 "invalid slice types?\n");
124 return AVERROR_INVALIDDATA;
125 }
126
127 ctx->aud_nal = (H264RawAUD) {
128 .nal_unit_header.nal_unit_type = H264_NAL_AUD,
129 .primary_pic_type = j,
130 };
131
132 err = ff_cbs_insert_unit_content(au, 0, H264_NAL_AUD,
133 &ctx->aud_nal, NULL);
134 if (err < 0) {
135 av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n");
136 return err;
137 }
138
139 return 0;
140 }
141
142 45 static int h264_metadata_update_sps(AVBSFContext *bsf,
143 H264RawSPS *sps)
144 {
145 45 H264MetadataContext *ctx = bsf->priv_data;
146 45 int need_vui = 0;
147 int crop_unit_x, crop_unit_y;
148
149
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (ctx->sample_aspect_ratio.num && ctx->sample_aspect_ratio.den) {
150 int num, den, i;
151
152 av_reduce(&num, &den, ctx->sample_aspect_ratio.num,
153 ctx->sample_aspect_ratio.den, 65535);
154
155 for (i = 1; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) {
156 if (num == ff_h2645_pixel_aspect[i].num &&
157 den == ff_h2645_pixel_aspect[i].den)
158 break;
159 }
160 if (i == FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) {
161 sps->vui.aspect_ratio_idc = 255;
162 sps->vui.sar_width = num;
163 sps->vui.sar_height = den;
164 } else {
165 sps->vui.aspect_ratio_idc = i;
166 }
167 sps->vui.aspect_ratio_info_present_flag = 1;
168 need_vui = 1;
169 }
170
171 #define SET_VUI_FIELD(field) do { \
172 if (ctx->field >= 0) { \
173 sps->vui.field = ctx->field; \
174 need_vui = 1; \
175 } \
176 } while (0)
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 if (ctx->overscan_appropriate_flag >= 0) {
179 SET_VUI_FIELD(overscan_appropriate_flag);
180 sps->vui.overscan_info_present_flag = 1;
181 }
182
183
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 if (ctx->video_format >= 0 ||
184
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 ctx->video_full_range_flag >= 0 ||
185
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 ctx->colour_primaries >= 0 ||
186
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 ctx->transfer_characteristics >= 0 ||
187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 ctx->matrix_coefficients >= 0) {
188
189 SET_VUI_FIELD(video_format);
190
191 SET_VUI_FIELD(video_full_range_flag);
192
193 if (ctx->colour_primaries >= 0 ||
194 ctx->transfer_characteristics >= 0 ||
195 ctx->matrix_coefficients >= 0) {
196
197 SET_VUI_FIELD(colour_primaries);
198 SET_VUI_FIELD(transfer_characteristics);
199 SET_VUI_FIELD(matrix_coefficients);
200
201 sps->vui.colour_description_present_flag = 1;
202 }
203 sps->vui.video_signal_type_present_flag = 1;
204 }
205
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 if (ctx->chroma_sample_loc_type >= 0) {
207 sps->vui.chroma_sample_loc_type_top_field =
208 ctx->chroma_sample_loc_type;
209 sps->vui.chroma_sample_loc_type_bottom_field =
210 ctx->chroma_sample_loc_type;
211 sps->vui.chroma_loc_info_present_flag = 1;
212 need_vui = 1;
213 }
214
215
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (ctx->tick_rate.num && ctx->tick_rate.den) {
216 int num, den;
217
218 av_reduce(&num, &den, ctx->tick_rate.num, ctx->tick_rate.den,
219 UINT32_MAX > INT_MAX ? UINT32_MAX : INT_MAX);
220
221 sps->vui.time_scale = num;
222 sps->vui.num_units_in_tick = den;
223
224 sps->vui.timing_info_present_flag = 1;
225 need_vui = 1;
226 }
227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 SET_VUI_FIELD(fixed_frame_rate_flag);
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 if (ctx->zero_new_constraint_set_flags) {
229 sps->constraint_set4_flag = 0;
230 sps->constraint_set5_flag = 0;
231 }
232
233
2/4
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45 times.
45 if (sps->separate_colour_plane_flag || sps->chroma_format_idc == 0) {
234 crop_unit_x = 1;
235 crop_unit_y = 2 - sps->frame_mbs_only_flag;
236 } else {
237
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 crop_unit_x = 1 + (sps->chroma_format_idc < 3);
238
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 crop_unit_y = (1 + (sps->chroma_format_idc < 2)) *
239 45 (2 - sps->frame_mbs_only_flag);
240 }
241 #define CROP(border, unit) do { \
242 if (ctx->crop_ ## border >= 0) { \
243 if (ctx->crop_ ## border % unit != 0) { \
244 av_log(bsf, AV_LOG_ERROR, "Invalid value for crop_%s: " \
245 "must be a multiple of %d.\n", #border, unit); \
246 return AVERROR(EINVAL); \
247 } \
248 sps->frame_crop_ ## border ## _offset = \
249 ctx->crop_ ## border / unit; \
250 sps->frame_cropping_flag = 1; \
251 } \
252 } while (0)
253
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 CROP(left, crop_unit_x);
254
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 CROP(right, crop_unit_x);
255
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 CROP(top, crop_unit_y);
256
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 CROP(bottom, crop_unit_y);
257 #undef CROP
258
259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 if (ctx->level != LEVEL_UNSET) {
260 int level_idc;
261
262 if (ctx->level == LEVEL_AUTO) {
263 const H264LevelDescriptor *desc;
264 int64_t bit_rate;
265 int width, height, dpb_frames;
266 int framerate;
267
268 if (sps->vui.nal_hrd_parameters_present_flag) {
269 bit_rate = (sps->vui.nal_hrd_parameters.bit_rate_value_minus1[0] + 1) *
270 (INT64_C(1) << (sps->vui.nal_hrd_parameters.bit_rate_scale + 6));
271 } else if (sps->vui.vcl_hrd_parameters_present_flag) {
272 bit_rate = (sps->vui.vcl_hrd_parameters.bit_rate_value_minus1[0] + 1) *
273 (INT64_C(1) << (sps->vui.vcl_hrd_parameters.bit_rate_scale + 6));
274 // Adjust for VCL vs. NAL limits.
275 bit_rate = bit_rate * 6 / 5;
276 } else {
277 bit_rate = 0;
278 }
279
280 // Don't use max_dec_frame_buffering if it is only inferred.
281 dpb_frames = sps->vui.bitstream_restriction_flag ?
282 sps->vui.max_dec_frame_buffering : H264_MAX_DPB_FRAMES;
283
284 width = 16 * (sps->pic_width_in_mbs_minus1 + 1);
285 height = 16 * (sps->pic_height_in_map_units_minus1 + 1) *
286 (2 - sps->frame_mbs_only_flag);
287
288 if (sps->vui.timing_info_present_flag)
289 framerate = sps->vui.time_scale / sps->vui.num_units_in_tick / 2;
290 else
291 framerate = 0;
292
293 desc = ff_h264_guess_level(sps->profile_idc, bit_rate, framerate,
294 width, height, dpb_frames);
295 if (desc) {
296 level_idc = desc->level_idc;
297 } else {
298 av_log(bsf, AV_LOG_WARNING, "Stream does not appear to "
299 "conform to any level: using level 6.2.\n");
300 level_idc = 62;
301 }
302 } else {
303 level_idc = ctx->level;
304 }
305
306 if (level_idc == 9) {
307 if (sps->profile_idc == 66 ||
308 sps->profile_idc == 77 ||
309 sps->profile_idc == 88) {
310 sps->level_idc = 11;
311 sps->constraint_set3_flag = 1;
312 } else {
313 sps->level_idc = 9;
314 }
315 } else {
316 sps->level_idc = level_idc;
317 }
318 }
319
320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 if (need_vui)
321 sps->vui_parameters_present_flag = 1;
322
323 45 return 0;
324 }
325
326 static int h264_metadata_handle_display_orientation(AVBSFContext *bsf,
327 AVPacket *pkt,
328 CodedBitstreamFragment *au,
329 int seek_point)
330 {
331 H264MetadataContext *ctx = bsf->priv_data;
332 SEIRawMessage *message;
333 int err;
334
335 message = NULL;
336 while (ff_cbs_sei_find_message(ctx->common.output, au,
337 SEI_TYPE_DISPLAY_ORIENTATION,
338 &message) == 0) {
339 H264RawSEIDisplayOrientation *disp = message->payload;
340 double angle = disp->anticlockwise_rotation * 180.0 / 65536.0;
341 int32_t *matrix;
342
343 matrix = av_malloc(9 * sizeof(int32_t));
344 if (!matrix)
345 return AVERROR(ENOMEM);
346
347 /* av_display_rotation_set() expects the angle in the clockwise
348 * direction, hence the first minus.
349 * The below code applies the flips after the rotation, yet
350 * the H.2645 specs require flipping to be applied first.
351 * Because of R O(phi) = O(-phi) R (where R is flipping around
352 * an arbitatry axis and O(phi) is the proper rotation by phi)
353 * we can create display matrices as desired by negating
354 * the degree once for every flip applied. */
355 angle = -angle * (1 - 2 * !!disp->hor_flip) * (1 - 2 * !!disp->ver_flip);
356
357 av_display_rotation_set(matrix, angle);
358 av_display_matrix_flip(matrix, disp->hor_flip, disp->ver_flip);
359
360 // If there are multiple display orientation messages in an
361 // access unit, then the last one added to the packet (i.e.
362 // the first one in the access unit) will prevail.
363 err = av_packet_add_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX,
364 (uint8_t*)matrix,
365 9 * sizeof(int32_t));
366 if (err < 0) {
367 av_log(bsf, AV_LOG_ERROR, "Failed to attach extracted "
368 "displaymatrix side data to packet.\n");
369 av_free(matrix);
370 return AVERROR(ENOMEM);
371 }
372 }
373
374 if (ctx->display_orientation == BSF_ELEMENT_REMOVE ||
375 ctx->display_orientation == BSF_ELEMENT_INSERT) {
376 ff_cbs_sei_delete_message_type(ctx->common.output, au,
377 SEI_TYPE_DISPLAY_ORIENTATION);
378 }
379
380 if (ctx->display_orientation == BSF_ELEMENT_INSERT) {
381 H264RawSEIDisplayOrientation *disp =
382 &ctx->display_orientation_payload;
383 uint8_t *data;
384 size_t size;
385 int write = 0;
386
387 data = av_packet_get_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX, &size);
388 if (data && size >= 9 * sizeof(int32_t)) {
389 int32_t matrix[9];
390 double dmatrix[9];
391 int hflip, vflip, i;
392 double scale_x, scale_y, angle;
393
394 memcpy(matrix, data, sizeof(matrix));
395
396 for (i = 0; i < 9; i++)
397 dmatrix[i] = matrix[i] / 65536.0;
398
399 // Extract scale factors.
400 scale_x = hypot(dmatrix[0], dmatrix[3]);
401 scale_y = hypot(dmatrix[1], dmatrix[4]);
402
403 // Select flips to make the main diagonal positive.
404 hflip = dmatrix[0] < 0.0;
405 vflip = dmatrix[4] < 0.0;
406 if (hflip)
407 scale_x = -scale_x;
408 if (vflip)
409 scale_y = -scale_y;
410
411 // Rescale.
412 for (i = 0; i < 9; i += 3) {
413 dmatrix[i] /= scale_x;
414 dmatrix[i + 1] /= scale_y;
415 }
416
417 // Extract rotation.
418 angle = atan2(dmatrix[3], dmatrix[0]);
419
420 if (!(angle >= -M_PI && angle <= M_PI) ||
421 matrix[2] != 0.0 || matrix[5] != 0.0 ||
422 matrix[6] != 0.0 || matrix[7] != 0.0) {
423 av_log(bsf, AV_LOG_WARNING, "Input display matrix is not "
424 "representable in H.264 parameters.\n");
425 } else {
426 disp->hor_flip = hflip;
427 disp->ver_flip = vflip;
428 disp->anticlockwise_rotation =
429 (uint16_t)rint((angle >= 0.0 ? angle
430 : angle + 2 * M_PI) *
431 32768.0 / M_PI);
432 write = 1;
433 }
434 }
435
436 if (seek_point) {
437 if (!isnan(ctx->rotate)) {
438 disp->anticlockwise_rotation =
439 (uint16_t)rint((ctx->rotate >= 0.0 ? ctx->rotate
440 : ctx->rotate + 360.0) *
441 65536.0 / 360.0);
442 write = 1;
443 }
444 if (ctx->flip) {
445 disp->hor_flip = !!(ctx->flip & FLIP_HORIZONTAL);
446 disp->ver_flip = !!(ctx->flip & FLIP_VERTICAL);
447 write = 1;
448 }
449 }
450
451 if (write) {
452 disp->display_orientation_repetition_period = 1;
453
454 err = ff_cbs_sei_add_message(ctx->common.output, au, 1,
455 SEI_TYPE_DISPLAY_ORIENTATION,
456 disp, NULL);
457 if (err < 0) {
458 av_log(bsf, AV_LOG_ERROR, "Failed to add display orientation "
459 "SEI message to access unit.\n");
460 return err;
461 }
462 }
463 }
464
465 return 0;
466 }
467
468 2395 static int h264_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
469 CodedBitstreamFragment *au)
470 {
471 2395 H264MetadataContext *ctx = bsf->priv_data;
472 int err, i, has_sps, seek_point;
473
474
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 2355 times.
2395 if (ctx->aud == BSF_ELEMENT_REMOVE) {
475
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 40 times.
216 for (i = au->nb_units - 1; i >= 0; i--) {
476
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 137 times.
176 if (au->units[i].type == H264_NAL_AUD)
477 39 ff_cbs_delete_unit(au, i);
478 }
479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2355 times.
2355 } else if (ctx->aud == BSF_ELEMENT_INSERT) {
480 if (pkt) {
481 err = h264_metadata_insert_aud(bsf, au);
482 if (err < 0)
483 return err;
484 }
485 }
486
487 2395 has_sps = 0;
488
2/2
✓ Branch 0 taken 6765 times.
✓ Branch 1 taken 2395 times.
9160 for (i = 0; i < au->nb_units; i++) {
489
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 6720 times.
6765 if (au->units[i].type == H264_NAL_SPS) {
490 45 err = h264_metadata_update_sps(bsf, au->units[i].content);
491
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 if (err < 0)
492 return err;
493 45 has_sps = 1;
494 }
495 }
496
497
2/2
✓ Branch 0 taken 2378 times.
✓ Branch 1 taken 17 times.
2395 if (pkt) {
498 // The current packet should be treated as a seek point for metadata
499 // insertion if any of:
500 // - It is the first packet in the stream.
501 // - It contains an SPS, indicating that a sequence might start here.
502 // - It is marked as containing a key frame.
503
4/4
✓ Branch 0 taken 2361 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 2350 times.
✓ Branch 3 taken 11 times.
4728 seek_point = !ctx->done_first_au || has_sps ||
504
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2342 times.
2350 (pkt->flags & AV_PKT_FLAG_KEY);
505 } else {
506 17 seek_point = 0;
507 }
508
509
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2395 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2395 if (ctx->sei_user_data && seek_point) {
510 err = ff_cbs_sei_add_message(ctx->common.output, au, 1,
511 SEI_TYPE_USER_DATA_UNREGISTERED,
512 &ctx->sei_user_data_payload, NULL);
513 if (err < 0) {
514 av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
515 "message to access unit.\n");
516 return err;
517 }
518 }
519
520
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 2355 times.
2395 if (ctx->delete_filler) {
521
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 40 times.
177 for (i = au->nb_units - 1; i >= 0; i--) {
522
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 104 times.
137 if (au->units[i].type == H264_NAL_FILLER_DATA) {
523 33 ff_cbs_delete_unit(au, i);
524 33 continue;
525 }
526 }
527
528 40 ff_cbs_sei_delete_message_type(ctx->common.output, au,
529 SEI_TYPE_FILLER_PAYLOAD);
530 }
531
532
3/4
✓ Branch 0 taken 2378 times.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2378 times.
2395 if (pkt && ctx->display_orientation != BSF_ELEMENT_PASS) {
533 err = h264_metadata_handle_display_orientation(bsf, pkt, au,
534 seek_point);
535 if (err < 0)
536 return err;
537 }
538
539
2/2
✓ Branch 0 taken 2378 times.
✓ Branch 1 taken 17 times.
2395 if (pkt)
540 2378 ctx->done_first_au = 1;
541
542 2395 return 0;
543 }
544
545 static const CBSBSFType h264_metadata_type = {
546 .codec_id = AV_CODEC_ID_H264,
547 .fragment_name = "access unit",
548 .unit_name = "NAL unit",
549 .update_fragment = &h264_metadata_update_fragment,
550 };
551
552 17 static int h264_metadata_init(AVBSFContext *bsf)
553 {
554 17 H264MetadataContext *ctx = bsf->priv_data;
555
556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (ctx->sei_user_data) {
557 SEIRawUserDataUnregistered *udu = &ctx->sei_user_data_payload;
558 int i, j;
559
560 // Parse UUID. It must be a hex string of length 32, possibly
561 // containing '-'s between hex digits (which we ignore).
562 for (i = j = 0; j < 32 && i < 64 && ctx->sei_user_data[i]; i++) {
563 int c, v;
564 c = ctx->sei_user_data[i];
565 if (c == '-') {
566 continue;
567 } else if (av_isxdigit(c)) {
568 c = av_tolower(c);
569 v = (c <= '9' ? c - '0' : c - 'a' + 10);
570 } else {
571 break;
572 }
573 if (j & 1)
574 udu->uuid_iso_iec_11578[j / 2] |= v;
575 else
576 udu->uuid_iso_iec_11578[j / 2] = v << 4;
577 ++j;
578 }
579 if (j == 32 && ctx->sei_user_data[i] == '+') {
580 udu->data = (uint8_t*)ctx->sei_user_data + i + 1;
581 udu->data_length = strlen(udu->data) + 1;
582 } else {
583 av_log(bsf, AV_LOG_ERROR, "Invalid user data: "
584 "must be \"UUID+string\".\n");
585 return AVERROR(EINVAL);
586 }
587 }
588
589 17 return ff_cbs_bsf_generic_init(bsf, &h264_metadata_type);
590 }
591
592 #define OFFSET(x) offsetof(H264MetadataContext, x)
593 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
594 static const AVOption h264_metadata_options[] = {
595 BSF_ELEMENT_OPTIONS_PIR("aud", "Access Unit Delimiter NAL units",
596 aud, FLAGS),
597
598 { "sample_aspect_ratio", "Set sample aspect ratio (table E-1)",
599 OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL,
600 { .dbl = 0.0 }, 0, 65535, FLAGS },
601
602 { "overscan_appropriate_flag", "Set VUI overscan appropriate flag",
603 OFFSET(overscan_appropriate_flag), AV_OPT_TYPE_INT,
604 { .i64 = -1 }, -1, 1, FLAGS },
605
606 { "video_format", "Set video format (table E-2)",
607 OFFSET(video_format), AV_OPT_TYPE_INT,
608 { .i64 = -1 }, -1, 7, FLAGS},
609 { "video_full_range_flag", "Set video full range flag",
610 OFFSET(video_full_range_flag), AV_OPT_TYPE_INT,
611 { .i64 = -1 }, -1, 1, FLAGS },
612 { "colour_primaries", "Set colour primaries (table E-3)",
613 OFFSET(colour_primaries), AV_OPT_TYPE_INT,
614 { .i64 = -1 }, -1, 255, FLAGS },
615 { "transfer_characteristics", "Set transfer characteristics (table E-4)",
616 OFFSET(transfer_characteristics), AV_OPT_TYPE_INT,
617 { .i64 = -1 }, -1, 255, FLAGS },
618 { "matrix_coefficients", "Set matrix coefficients (table E-5)",
619 OFFSET(matrix_coefficients), AV_OPT_TYPE_INT,
620 { .i64 = -1 }, -1, 255, FLAGS },
621
622 { "chroma_sample_loc_type", "Set chroma sample location type (figure E-1)",
623 OFFSET(chroma_sample_loc_type), AV_OPT_TYPE_INT,
624 { .i64 = -1 }, -1, 5, FLAGS },
625
626 { "tick_rate", "Set VUI tick rate (time_scale / num_units_in_tick)",
627 OFFSET(tick_rate), AV_OPT_TYPE_RATIONAL,
628 { .dbl = 0.0 }, 0, UINT_MAX, FLAGS },
629 { "fixed_frame_rate_flag", "Set VUI fixed frame rate flag",
630 OFFSET(fixed_frame_rate_flag), AV_OPT_TYPE_INT,
631 { .i64 = -1 }, -1, 1, FLAGS },
632 { "zero_new_constraint_set_flags", "Set constraint_set4_flag / constraint_set5_flag to zero",
633 OFFSET(zero_new_constraint_set_flags), AV_OPT_TYPE_BOOL,
634 { .i64 = 0 }, 0, 1, FLAGS },
635
636 { "crop_left", "Set left border crop offset",
637 OFFSET(crop_left), AV_OPT_TYPE_INT,
638 { .i64 = -1 }, -1, H264_MAX_WIDTH, FLAGS },
639 { "crop_right", "Set right border crop offset",
640 OFFSET(crop_right), AV_OPT_TYPE_INT,
641 { .i64 = -1 }, -1, H264_MAX_WIDTH, FLAGS },
642 { "crop_top", "Set top border crop offset",
643 OFFSET(crop_top), AV_OPT_TYPE_INT,
644 { .i64 = -1 }, -1, H264_MAX_HEIGHT, FLAGS },
645 { "crop_bottom", "Set bottom border crop offset",
646 OFFSET(crop_bottom), AV_OPT_TYPE_INT,
647 { .i64 = -1 }, -1, H264_MAX_HEIGHT, FLAGS },
648
649 { "sei_user_data", "Insert SEI user data (UUID+string)",
650 OFFSET(sei_user_data), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
651
652 { "delete_filler", "Delete all filler (both NAL and SEI)",
653 OFFSET(delete_filler), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS},
654
655 BSF_ELEMENT_OPTIONS_PIRE("display_orientation",
656 "Display orientation SEI",
657 display_orientation, FLAGS),
658
659 { "rotate", "Set rotation in display orientation SEI (anticlockwise angle in degrees)",
660 OFFSET(rotate), AV_OPT_TYPE_DOUBLE,
661 { .dbl = NAN }, -360.0, +360.0, FLAGS },
662 { "flip", "Set flip in display orientation SEI",
663 OFFSET(flip), AV_OPT_TYPE_FLAGS,
664 { .i64 = 0 }, 0, FLIP_HORIZONTAL | FLIP_VERTICAL, FLAGS, .unit = "flip" },
665 { "horizontal", "Set hor_flip",
666 0, AV_OPT_TYPE_CONST,
667 { .i64 = FLIP_HORIZONTAL }, .flags = FLAGS, .unit = "flip" },
668 { "vertical", "Set ver_flip",
669 0, AV_OPT_TYPE_CONST,
670 { .i64 = FLIP_VERTICAL }, .flags = FLAGS, .unit = "flip" },
671
672 { "level", "Set level (table A-1)",
673 OFFSET(level), AV_OPT_TYPE_INT,
674 { .i64 = LEVEL_UNSET }, LEVEL_UNSET, 0xff, FLAGS, .unit = "level" },
675 { "auto", "Attempt to guess level from stream properties",
676 0, AV_OPT_TYPE_CONST,
677 { .i64 = LEVEL_AUTO }, .flags = FLAGS, .unit = "level" },
678 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
679 { .i64 = value }, .flags = FLAGS, .unit = "level"
680 { LEVEL("1", 10) },
681 { LEVEL("1b", 9) },
682 { LEVEL("1.1", 11) },
683 { LEVEL("1.2", 12) },
684 { LEVEL("1.3", 13) },
685 { LEVEL("2", 20) },
686 { LEVEL("2.1", 21) },
687 { LEVEL("2.2", 22) },
688 { LEVEL("3", 30) },
689 { LEVEL("3.1", 31) },
690 { LEVEL("3.2", 32) },
691 { LEVEL("4", 40) },
692 { LEVEL("4.1", 41) },
693 { LEVEL("4.2", 42) },
694 { LEVEL("5", 50) },
695 { LEVEL("5.1", 51) },
696 { LEVEL("5.2", 52) },
697 { LEVEL("6", 60) },
698 { LEVEL("6.1", 61) },
699 { LEVEL("6.2", 62) },
700 #undef LEVEL
701
702 { NULL }
703 };
704
705 static const AVClass h264_metadata_class = {
706 .class_name = "h264_metadata_bsf",
707 .item_name = av_default_item_name,
708 .option = h264_metadata_options,
709 .version = LIBAVUTIL_VERSION_INT,
710 };
711
712 static const enum AVCodecID h264_metadata_codec_ids[] = {
713 AV_CODEC_ID_H264, AV_CODEC_ID_NONE,
714 };
715
716 const FFBitStreamFilter ff_h264_metadata_bsf = {
717 .p.name = "h264_metadata",
718 .p.codec_ids = h264_metadata_codec_ids,
719 .p.priv_class = &h264_metadata_class,
720 .priv_data_size = sizeof(H264MetadataContext),
721 .init = &h264_metadata_init,
722 .close = &ff_cbs_bsf_generic_close,
723 .filter = &ff_cbs_bsf_generic_filter,
724 };
725

叶公好龙是什么生肖 肾阴虚什么症状 榴莲苦是什么原因 鸡蛋炒什么菜好吃 飞蚊症是什么原因
af是什么意思 喉咙痛有痰吃什么药 么么哒是什么意思 1314代表什么意思 大肠杆菌感染吃什么药
dragon是什么意思 气胸挂什么科 肾小球是什么 鼻子上长痘痘是什么原因 什么的蔷薇
火影忍者大结局是什么 慢性非萎缩性胃炎什么意思 减肥期间吃什么水果 勇往直前是什么意思 乙肝核心抗体阳性是什么意思
审时度势是什么意思hcv8jop9ns3r.cn 什么思而行hcv9jop1ns1r.cn 声带白斑是什么病严重吗96micro.com 集体户口什么意思hcv7jop9ns4r.cn 看甲状腺挂什么科inbungee.com
铁蛋白高是什么原因hcv7jop7ns2r.cn 临床诊断是什么意思hcv9jop3ns0r.cn 什么人不能吃蜂蜜hcv9jop2ns0r.cn ab型血可以给什么血型输血jasonfriends.com 大便有点绿色是什么原因hcv7jop6ns0r.cn
黄芪配升麻有什么作用hcv8jop7ns5r.cn 喉咙痛吃什么药cl108k.com 为什么呀hcv9jop2ns7r.cn 望尘莫及的及是什么意思hcv8jop0ns2r.cn 水晶是什么hcv8jop8ns3r.cn
十月份是什么季节clwhiglsz.com 久之的之是什么意思mmeoe.com 吃什么补维生素b12hcv8jop7ns3r.cn mar什么意思hcv8jop7ns5r.cn 钾离子低的原因是什么hcv8jop7ns7r.cn
百度