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.
Unified · Split
| @@ -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 captions | 977 | case MKBETAG('G', 'A', '9', '4'): { // closed captions |
| @@ -997,16 +997,13 @@ FF_ENABLE_DEPRECATION_WARNINGS · 19 unmodified lines | |||
| 997 | default: // ignore unsupported identifiers | 997 | 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; // ignore | 1025 | 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; |
| @@ -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_byte | 158 | 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_SEI | 189 | #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-40 | 205 | // 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 | #endif | 240 | #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; |
| @@ -23,10 +23,21 @@ · 22 unmodified lines | |||
| 23 | #define ITU_T_T35_COUNTRY_CODE_UK 0xB4 | 23 | #define ITU_T_T35_COUNTRY_CODE_UK 0xB4 |
| 24 | #define ITU_T_T35_COUNTRY_CODE_US 0xB5 | 24 | #define ITU_T_T35_COUNTRY_CODE_US 0xB5 |
| 25 | 25 | ||
| 26 | #define ITU_T_T35_PROVIDER_CODE_ATSC 0x31 | 26 | // The Terminal Provider Code (or "Manufacturer Code") identifies the |
| 27 | #define ITU_T_T35_PROVIDER_CODE_CUVA 0x04 | 27 | // manufacturer within a country. An Assignment Authority appointed by the |
| 28 | #define ITU_T_T35_PROVIDER_CODE_DOLBY 0x3B | 28 | // national body assigns this code nationally. The manufacturer code is always |
| 29 | #define ITU_T_T35_PROVIDER_CODE_LCEVC 0x50 | 29 | // used in conjunction with a country code. |
| 30 | #define ITU_T_T35_PROVIDER_CODE_SMTPE 0x3C | 30 | // - 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 */ |
| @@ -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 captions | 403 | 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 identifiers | 423 | 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; // ignore | 451 | 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 | ||