| @@ -1279,6 +1279,62 @@ static int flv_update_video_color_info(AVFormatContext *s, AVStream *st) · 1278 unmodified lines |
| 1279 | return 0; | 1279 | return 0; |
| 1280 | } | 1280 | } |
| 1281 | | 1281 | |
| | 1282 | static int flv_parse_mod_ex_data(AVFormatContext *s, int *pkt_type, int *size, int64_t *dts) |
| | 1283 | { |
| | 1284 | int ex_type, ret; |
| | 1285 | uint8_t *ex_data; |
| | 1286 | |
| | 1287 | int ex_size = (uint8_t)avio_r8(s->pb) + 1; |
| | 1288 | *size -= 1; |
| | 1289 | |
| | 1290 | if (ex_size == 256) { |
| | 1291 | ex_size = (uint16_t)avio_rb16(s->pb) + 1; |
| | 1292 | *size -= 2; |
| | 1293 | } |
| | 1294 | |
| | 1295 | if (ex_size >= *size) { |
| | 1296 | av_log(s, AV_LOG_WARNING, "ModEx size larger than remaining data!\n"); |
| | 1297 | return AVERROR(EINVAL); |
| | 1298 | } |
| | 1299 | |
| | 1300 | ex_data = av_malloc(ex_size); |
| | 1301 | if (!ex_data) |
| | 1302 | return AVERROR(ENOMEM); |
| | 1303 | |
| | 1304 | ret = avio_read(s->pb, ex_data, ex_size); |
| | 1305 | if (ret < 0) { |
| | 1306 | av_free(ex_data); |
| | 1307 | return ret; |
| | 1308 | } |
| | 1309 | *size -= ex_size; |
| | 1310 | |
| | 1311 | ex_type = (uint8_t)avio_r8(s->pb); |
| | 1312 | *size -= 1; |
| | 1313 | |
| | 1314 | *pkt_type = ex_type & 0x0f; |
| | 1315 | ex_type &= 0xf0; |
| | 1316 | |
| | 1317 | if (ex_type == PacketModExTypeTimestampOffsetNano) { |
| | 1318 | uint32_t nano_offset; |
| | 1319 | |
| | 1320 | if (ex_size != 3) { |
| | 1321 | av_log(s, AV_LOG_WARNING, "Invalid ModEx size for Type TimestampOffsetNano!\n"); |
| | 1322 | nano_offset = 0; |
| | 1323 | } else { |
| | 1324 | nano_offset = (ex_data[0] << 16) | (ex_data[1] << 8) | ex_data[2]; |
| | 1325 | } |
| | 1326 | |
| | 1327 | // this is not likely to ever add anything, but right now timestamps are with ms precision |
| | 1328 | *dts += nano_offset / 1000000; |
| | 1329 | } else { |
| | 1330 | av_log(s, AV_LOG_INFO, "Unknown ModEx type: %d", ex_type); |
| | 1331 | } |
| | 1332 | |
| | 1333 | av_free(ex_data); |
| | 1334 | |
| | 1335 | return 0; |
| | 1336 | } |
| | 1337 | |
| 1282 | static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) | 1338 | static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) |
| 1283 | { | 1339 | { |
| 1284 | FLVContext *flv = s->priv_data; | 1340 | FLVContext *flv = s->priv_data; |
| @@ -1347,6 +1403,12 @@ retry: · 62 unmodified lines |
| 1347 | enhanced_flv = 1; | 1403 | enhanced_flv = 1; |
| 1348 | pkt_type = flags & ~FLV_AUDIO_CODECID_MASK; | 1404 | pkt_type = flags & ~FLV_AUDIO_CODECID_MASK; |
| 1349 | | 1405 | |
| | 1406 | while (pkt_type == PacketTypeModEx) { |
| | 1407 | ret = flv_parse_mod_ex_data(s, &pkt_type, &size, &dts); |
| | 1408 | if (ret < 0) |
| | 1409 | goto leave; |
| | 1410 | } |
| | 1411 | |
| 1350 | if (pkt_type == AudioPacketTypeMultitrack) { | 1412 | if (pkt_type == AudioPacketTypeMultitrack) { |
| 1351 | uint8_t types = avio_r8(s->pb); | 1413 | uint8_t types = avio_r8(s->pb); |
| 1352 | multitrack_type = types & 0xF0; | 1414 | multitrack_type = types & 0xF0; |
| @@ -1376,6 +1438,12 @@ retry: · 23 unmodified lines |
| 1376 | pkt_type = enhanced_flv ? codec_id : 0; | 1438 | pkt_type = enhanced_flv ? codec_id : 0; |
| 1377 | size--; | 1439 | size--; |
| 1378 | | 1440 | |
| | 1441 | while (pkt_type == PacketTypeModEx) { |
| | 1442 | ret = flv_parse_mod_ex_data(s, &pkt_type, &size, &dts); |
| | 1443 | if (ret < 0) |
| | 1444 | goto leave; |
| | 1445 | } |
| | 1446 | |
| 1379 | if (pkt_type == PacketTypeMultitrack) { | 1447 | if (pkt_type == PacketTypeMultitrack) { |
| 1380 | uint8_t types = avio_r8(s->pb); | 1448 | uint8_t types = avio_r8(s->pb); |
| 1381 | multitrack_type = types & 0xF0; | 1449 | multitrack_type = types & 0xF0; |