History

avcodec/itut35: always check the provider code and country code together

ITU-T T.35 provider codes are attributed by national bodies and it's possible to have collisions across countries. This is why the country code must always be checked as well. Use if statements rather than nested switches which would be unreadable.

Maryla Ustarroz-Calonge committed 1 year ago

Commit a3ec70b1 parent 088ace34 files · +52 −78Browse files

Showing the changes to libavcodec (4 of 4 files). Show all

Unified · Split

4 files
  1. libavcodec/av1dec.c +12 −20
  2. libavcodec/h2645_sei.c +9 −27
  3. libavcodec/itut35.h +16 −5
  4. libavcodec/libdav1d.c +15 −26
libavcodec/av1dec.c+12−20
@@ -965,13 +965,13 @@ static int export_itut_t35(AVCodecContext *avctx, AVFrame *frame, · 964 unmodified lines
965{965{
966 GetByteContext gb;966 GetByteContext gb;
967 AV1DecContext *s = avctx->priv_data;967 AV1DecContext *s = avctx->priv_data;
968 int ret, provider_code;968 int ret, provider_code, country_code;
969 969
970 bytestream2_init(&gb, itut_t35->payload, itut_t35->payload_size);970 bytestream2_init(&gb, itut_t35->payload, itut_t35->payload_size);
971 971
972 provider_code = bytestream2_get_be16(&gb);972 provider_code = bytestream2_get_be16(&gb);
973 switch (provider_code) {973 country_code = itut_t35->itu_t_t35_country_code ;
974 case ITU_T_T35_PROVIDER_CODE_ATSC: {974 if (country_code == ITU_T_T35_COUNTRY_CODE_US && provider_code == ITU_T_T35_PROVIDER_CODE_ATSC) {
975 uint32_t user_identifier = bytestream2_get_be32(&gb);975 uint32_t user_identifier = bytestream2_get_be32(&gb);
976 switch (user_identifier) {976 switch (user_identifier) {
977 case MKBETAG('G', 'A', '9', '4'): { // closed captions977 case MKBETAG('G', 'A', '9', '4'): { // closed captions
@@ -997,16 +997,13 @@ FF_ENABLE_DEPRECATION_WARNINGS · 19 unmodified lines
997 default: // ignore unsupported identifiers997 default: // ignore unsupported identifiers
998 break;998 break;
999 }999 }
1000 break;1000 } else if (country_code == ITU_T_T35_COUNTRY_CODE_US && provider_code == ITU_T_T35_PROVIDER_CODE_SMTPE) {
1001 }
1002 case ITU_T_T35_PROVIDER_CODE_SMTPE: {
1003 AVDynamicHDRPlus *hdrplus;1001 AVDynamicHDRPlus *hdrplus;
1004 int provider_oriented_code = bytestream2_get_be16(&gb);1002 int provider_oriented_code = bytestream2_get_be16(&gb);
1005 int application_identifier = bytestream2_get_byte(&gb);1003 int application_identifier = bytestream2_get_byte(&gb);
1006 1004
1007 if (itut_t35->itu_t_t35_country_code != ITU_T_T35_COUNTRY_CODE_US ||1005 if (provider_oriented_code != 1 || application_identifier != 4)
1008 provider_oriented_code != 1 || application_identifier != 4)1006 return 0; // ignore
1009 break;
1010 1007
1011 hdrplus = av_dynamic_hdr_plus_create_side_data(frame);1008 hdrplus = av_dynamic_hdr_plus_create_side_data(frame);
1012 if (!hdrplus)1009 if (!hdrplus)
@@ -1016,28 +1013,23 @@ FF_ENABLE_DEPRECATION_WARNINGS · 3 unmodified lines
1016 bytestream2_get_bytes_left(&gb));1013 bytestream2_get_bytes_left(&gb));
1017 if (ret < 0)1014 if (ret < 0)
1018 return ret;1015 return ret;
1019 break;1016 } else if (country_code == ITU_T_T35_COUNTRY_CODE_US && provider_code == ITU_T_T35_PROVIDER_CODE_DOLBY) {
1020 }
1021 case ITU_T_T35_PROVIDER_CODE_DOLBY: {
1022 int provider_oriented_code = bytestream2_get_be32(&gb);1017 int provider_oriented_code = bytestream2_get_be32(&gb);
1023 if (itut_t35->itu_t_t35_country_code != ITU_T_T35_COUNTRY_CODE_US ||1018 if (provider_oriented_code != 0x800)
1024 provider_oriented_code != 0x800)1019 return 0; // ignore
1025 break;
1026 1020
1027 ret = ff_dovi_rpu_parse(&s->dovi, gb.buffer, gb.buffer_end - gb.buffer,1021 ret = ff_dovi_rpu_parse(&s->dovi, gb.buffer, gb.buffer_end - gb.buffer,
1028 avctx->err_recognition);1022 avctx->err_recognition);
1029 if (ret < 0) {1023 if (ret < 0) {
1030 av_log(avctx, AV_LOG_WARNING, "Error parsing DOVI OBU.\n");1024 av_log(avctx, AV_LOG_WARNING, "Error parsing DOVI OBU.\n");
1031 break; // ignore1025 return 0; // ignore
1032 }1026 }
1033 1027
1034 ret = ff_dovi_attach_side_data(&s->dovi, frame);1028 ret = ff_dovi_attach_side_data(&s->dovi, frame);
1035 if (ret < 0)1029 if (ret < 0)
1036 return ret;1030 return ret;
1037 break;1031 } else {
1038 }1032 // ignore unsupported provider codes
1039 default: // ignore unsupported provider codes
1040 break;
1041 }1033 }
1042 1034
1043 return 0;1035 return 0;
libavcodec/h2645_sei.c+9−27
@@ -158,20 +158,10 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb, · 157 unmodified lines
158 bytestream2_skipu(gb, 1); // itu_t_t35_country_code_extension_byte158 bytestream2_skipu(gb, 1); // itu_t_t35_country_code_extension_byte
159 }159 }
160 160
161 if (country_code != ITU_T_T35_COUNTRY_CODE_US &&
162 country_code != ITU_T_T35_COUNTRY_CODE_UK &&
163 country_code != ITU_T_T35_COUNTRY_CODE_CN) {
164 av_log(logctx, AV_LOG_VERBOSE,
165 "Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n",
166 country_code);
167 return 0;
168 }
169
170 /* itu_t_t35_payload_byte follows */161 /* itu_t_t35_payload_byte follows */
171 provider_code = bytestream2_get_be16u(gb);162 provider_code = bytestream2_get_be16u(gb);
172 163
173 switch (provider_code) {164 if (country_code == ITU_T_T35_COUNTRY_CODE_US && provider_code == ITU_T_T35_PROVIDER_CODE_ATSC) {
174 case ITU_T_T35_PROVIDER_CODE_ATSC: {
175 uint32_t user_identifier;165 uint32_t user_identifier;
176 166
177 if (bytestream2_get_bytes_left(gb) < 4)167 if (bytestream2_get_bytes_left(gb) < 4)
@@ -189,9 +179,7 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb, · 11 unmodified lines
189 user_identifier);179 user_identifier);
190 break;180 break;
191 }181 }
192 break;182 } else if (country_code == ITU_T_T35_COUNTRY_CODE_UK && provider_code == ITU_T_T35_PROVIDER_CODE_LCEVC) {
193 }
194 case ITU_T_T35_PROVIDER_CODE_LCEVC: {
195 if (bytestream2_get_bytes_left(gb) < 2)183 if (bytestream2_get_bytes_left(gb) < 2)
196 return AVERROR_INVALIDDATA;184 return AVERROR_INVALIDDATA;
197 185
@@ -199,7 +187,7 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb, · 1 unmodified line
199 return decode_registered_user_data_lcevc(&h->lcevc, gb);187 return decode_registered_user_data_lcevc(&h->lcevc, gb);
200 }188 }
201#if CONFIG_HEVC_SEI189#if CONFIG_HEVC_SEI
202 case ITU_T_T35_PROVIDER_CODE_CUVA: {190 else if (country_code == ITU_T_T35_COUNTRY_CODE_CN && provider_code == ITU_T_T35_PROVIDER_CODE_CUVA) {
203 const uint16_t cuva_provider_oriented_code = 0x0005;191 const uint16_t cuva_provider_oriented_code = 0x0005;
204 uint16_t provider_oriented_code;192 uint16_t provider_oriented_code;
205 193
@@ -213,9 +201,7 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb, · 7 unmodified lines
213 if (provider_oriented_code == cuva_provider_oriented_code) {201 if (provider_oriented_code == cuva_provider_oriented_code) {
214 return decode_registered_user_data_dynamic_hdr_vivid(&h->dynamic_hdr_vivid, gb);202 return decode_registered_user_data_dynamic_hdr_vivid(&h->dynamic_hdr_vivid, gb);
215 }203 }
216 break;204 } else if(country_code == ITU_T_T35_COUNTRY_CODE_US && provider_code == ITU_T_T35_PROVIDER_CODE_SMTPE) {
217 }
218 case ITU_T_T35_PROVIDER_CODE_SMTPE: {
219 // A/341 Amendment - 2094-40205 // A/341 Amendment - 2094-40
220 const uint16_t smpte2094_40_provider_oriented_code = 0x0001;206 const uint16_t smpte2094_40_provider_oriented_code = 0x0001;
221 const uint8_t smpte2094_40_application_identifier = 0x04;207 const uint8_t smpte2094_40_application_identifier = 0x04;
@@ -234,9 +220,7 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb, · 12 unmodified lines
234 application_identifier == smpte2094_40_application_identifier) {220 application_identifier == smpte2094_40_application_identifier) {
235 return decode_registered_user_data_dynamic_hdr_plus(&h->dynamic_hdr_plus, gb);221 return decode_registered_user_data_dynamic_hdr_plus(&h->dynamic_hdr_plus, gb);
236 }222 }
237 break;223 } else if (country_code == ITU_T_T35_COUNTRY_CODE_US && provider_code == ITU_T_T35_PROVIDER_CODE_AOM) {
238 }
239 case 0x5890: { // aom_provider_code
240 const uint16_t aom_grain_provider_oriented_code = 0x0001;224 const uint16_t aom_grain_provider_oriented_code = 0x0001;
241 uint16_t provider_oriented_code;225 uint16_t provider_oriented_code;
242 226
@@ -252,15 +236,13 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb, · 9 unmodified lines
252 gb->buffer,236 gb->buffer,
253 bytestream2_get_bytes_left(gb));237 bytestream2_get_bytes_left(gb));
254 }238 }
255 break;
256 }239 }
257 unsupported_provider_code:
258#endif240#endif
259 default:241 else {
242 unsupported_provider_code:
260 av_log(logctx, AV_LOG_VERBOSE,243 av_log(logctx, AV_LOG_VERBOSE,
261 "Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n",244 "Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d, provider_code = %d)\n",
262 provider_code);245 country_code, provider_code);
263 break;
264 }246 }
265 247
266 return 0;248 return 0;
libavcodec/itut35.h+16−5
@@ -23,10 +23,21 @@ · 22 unmodified lines
23#define ITU_T_T35_COUNTRY_CODE_UK 0xB423#define ITU_T_T35_COUNTRY_CODE_UK 0xB4
24#define ITU_T_T35_COUNTRY_CODE_US 0xB524#define ITU_T_T35_COUNTRY_CODE_US 0xB5
25 25
26#define ITU_T_T35_PROVIDER_CODE_ATSC 0x3126// The Terminal Provider Code (or "Manufacturer Code") identifies the
27#define ITU_T_T35_PROVIDER_CODE_CUVA 0x0427// manufacturer within a country. An Assignment Authority appointed by the
28#define ITU_T_T35_PROVIDER_CODE_DOLBY 0x3B28// national body assigns this code nationally. The manufacturer code is always
29#define ITU_T_T35_PROVIDER_CODE_LCEVC 0x5029// used in conjunction with a country code.
30#define ITU_T_T35_PROVIDER_CODE_SMTPE 0x3C30// - CN providers
31#define ITU_T_T35_PROVIDER_CODE_CUVA 0x0004
32// - UK providers
33// V-Nova should be 0x5000 according to UK Register of Manufacturer Codes
34// https://www.cix.co.uk/~bpechey/H221/h221code.htm
35// but FFmpeg has been using 0x0050
36#define ITU_T_T35_PROVIDER_CODE_LCEVC 0x0050
37// - US providers
38#define ITU_T_T35_PROVIDER_CODE_ATSC 0x0031
39#define ITU_T_T35_PROVIDER_CODE_DOLBY 0x003B
40#define ITU_T_T35_PROVIDER_CODE_AOM 0x5890
41#define ITU_T_T35_PROVIDER_CODE_SMTPE 0x003C
31 42
32#endif /* AVCODEC_ITUT35_H */43#endif /* AVCODEC_ITUT35_H */
libavcodec/libdav1d.c+15−26
@@ -390,14 +390,14 @@ static int parse_itut_t35_metadata(Libdav1dContext *dav1d, Dav1dPicture *p, · 389 unmodified lines
390 const Dav1dITUTT35 *itut_t35, AVCodecContext *c,390 const Dav1dITUTT35 *itut_t35, AVCodecContext *c,
391 AVFrame *frame) {391 AVFrame *frame) {
392 GetByteContext gb;392 GetByteContext gb;
393 int provider_code;393 int provider_code, country_code;
394 int res;394 int res;
395 395
396 bytestream2_init(&gb, itut_t35->payload, itut_t35->payload_size);396 bytestream2_init(&gb, itut_t35->payload, itut_t35->payload_size);
397 397
398 provider_code = bytestream2_get_be16(&gb);398 provider_code = bytestream2_get_be16(&gb);
399 switch (provider_code) {399 country_code = itut_t35->country_code;
400 case ITU_T_T35_PROVIDER_CODE_ATSC: {400 if (country_code == ITU_T_T35_COUNTRY_CODE_US && provider_code == ITU_T_T35_PROVIDER_CODE_ATSC) {
401 uint32_t user_identifier = bytestream2_get_be32(&gb);401 uint32_t user_identifier = bytestream2_get_be32(&gb);
402 switch (user_identifier) {402 switch (user_identifier) {
403 case MKBETAG('G', 'A', '9', '4'): { // closed captions403 case MKBETAG('G', 'A', '9', '4'): { // closed captions
@@ -407,7 +407,7 @@ static int parse_itut_t35_metadata(Libdav1dContext *dav1d, Dav1dPicture *p, · 3 unmodified lines
407 if (res < 0)407 if (res < 0)
408 return res;408 return res;
409 if (!res)409 if (!res)
410 break;410 return 0; // no cc found, ignore
411 411
412 res = ff_frame_new_side_data_from_buf(c, frame, AV_FRAME_DATA_A53_CC, &buf);412 res = ff_frame_new_side_data_from_buf(c, frame, AV_FRAME_DATA_A53_CC, &buf);
413 if (res < 0)413 if (res < 0)
@@ -423,51 +423,40 @@ FF_ENABLE_DEPRECATION_WARNINGS · 9 unmodified lines
423 default: // ignore unsupported identifiers423 default: // ignore unsupported identifiers
424 break;424 break;
425 }425 }
426 break;426 } else if (country_code == ITU_T_T35_COUNTRY_CODE_US && provider_code == ITU_T_T35_PROVIDER_CODE_SMTPE) {
427 }
428 case ITU_T_T35_PROVIDER_CODE_SMTPE: {
429 AVDynamicHDRPlus *hdrplus;427 AVDynamicHDRPlus *hdrplus;
430 int provider_oriented_code = bytestream2_get_be16(&gb);428 int provider_oriented_code = bytestream2_get_be16(&gb);
431 int application_identifier = bytestream2_get_byte(&gb);429 int application_identifier = bytestream2_get_byte(&gb);
432 430
433 if (itut_t35->country_code != ITU_T_T35_COUNTRY_CODE_US ||431 if (provider_oriented_code != 1 || application_identifier != 4)
434 provider_oriented_code != 1 || application_identifier != 4)432 return 0; // ignore
435 break;
436 433
437 hdrplus = av_dynamic_hdr_plus_create_side_data(frame);434 hdrplus = av_dynamic_hdr_plus_create_side_data(frame);
438 if (!hdrplus) {435 if (!hdrplus)
439 res = AVERROR(ENOMEM);436 return AVERROR(ENOMEM);
440 return res;
441 }
442 437
443 res = av_dynamic_hdr_plus_from_t35(hdrplus, gb.buffer,438 res = av_dynamic_hdr_plus_from_t35(hdrplus, gb.buffer,
444 bytestream2_get_bytes_left(&gb));439 bytestream2_get_bytes_left(&gb));
445 if (res < 0)440 if (res < 0)
446 return res;441 return res;
447 break;442 } else if (country_code == ITU_T_T35_COUNTRY_CODE_US && provider_code == ITU_T_T35_PROVIDER_CODE_DOLBY) {
448 }
449 case ITU_T_T35_PROVIDER_CODE_DOLBY: {
450 int provider_oriented_code = bytestream2_get_be32(&gb);443 int provider_oriented_code = bytestream2_get_be32(&gb);
451 if (itut_t35->country_code != ITU_T_T35_COUNTRY_CODE_US ||444 if (provider_oriented_code != 0x800)
452 provider_oriented_code != 0x800)445 return 0; // ignore
453 break;
454 446
455 res = ff_dovi_rpu_parse(&dav1d->dovi, gb.buffer, gb.buffer_end - gb.buffer,447 res = ff_dovi_rpu_parse(&dav1d->dovi, gb.buffer, gb.buffer_end - gb.buffer,
456 c->err_recognition);448 c->err_recognition);
457 if (res < 0) {449 if (res < 0) {
458 av_log(c, AV_LOG_WARNING, "Error parsing DOVI OBU.\n");450 av_log(c, AV_LOG_WARNING, "Error parsing DOVI OBU.\n");
459 break; // ignore451 return 0; // ignore
460 }452 }
461 453
462 res = ff_dovi_attach_side_data(&dav1d->dovi, frame);454 res = ff_dovi_attach_side_data(&dav1d->dovi, frame);
463 if (res < 0)455 if (res < 0)
464 return res;456 return res;
465 break;457 } else {
458 // ignore unsupported provider codes
466 }459 }
467 default: // ignore unsupported provider codes
468 break;
469 }
470
471 return 0;460 return 0;
472}461}
473 462

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t