--- a/wp/wp-includes/ID3/module.audio-video.asf.php Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-includes/ID3/module.audio-video.asf.php Fri Sep 05 18:40:08 2025 +0200
@@ -20,6 +20,24 @@
class getid3_asf extends getid3_handler
{
+ protected static $ASFIndexParametersObjectIndexSpecifiersIndexTypes = array(
+ 1 => 'Nearest Past Data Packet',
+ 2 => 'Nearest Past Media Object',
+ 3 => 'Nearest Past Cleanpoint'
+ );
+
+ protected static $ASFMediaObjectIndexParametersObjectIndexSpecifiersIndexTypes = array(
+ 1 => 'Nearest Past Data Packet',
+ 2 => 'Nearest Past Media Object',
+ 3 => 'Nearest Past Cleanpoint',
+ 0xFF => 'Frame Number Offset'
+ );
+
+ protected static $ASFTimecodeIndexParametersObjectIndexSpecifiersIndexTypes = array(
+ 2 => 'Nearest Past Media Object',
+ 3 => 'Nearest Past Cleanpoint'
+ );
+
/**
* @param getID3 $getid3
*/
@@ -175,7 +193,7 @@
$info['playtime_seconds'] = ($thisfile_asf_filepropertiesobject['play_duration'] / 10000000) - ($thisfile_asf_filepropertiesobject['preroll'] / 1000);
//$info['bitrate'] = $thisfile_asf_filepropertiesobject['max_bitrate'];
- $info['bitrate'] = ((isset($thisfile_asf_filepropertiesobject['filesize']) ? $thisfile_asf_filepropertiesobject['filesize'] : $info['filesize']) * 8) / $info['playtime_seconds'];
+ $info['bitrate'] = getid3_lib::SafeDiv($thisfile_asf_filepropertiesobject['filesize'] * 8, $info['playtime_seconds']);
}
break;
@@ -317,6 +335,7 @@
// shortcut
$thisfile_asf['codec_list_object'] = array();
+ /** @var mixed[] $thisfile_asf_codeclistobject */
$thisfile_asf_codeclistobject = &$thisfile_asf['codec_list_object'];
$thisfile_asf_codeclistobject['offset'] = $NextObjectOffset + $offset;
@@ -332,6 +351,9 @@
break;
}
$thisfile_asf_codeclistobject['codec_entries_count'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
+ if ($thisfile_asf_codeclistobject['codec_entries_count'] > 0) {
+ $thisfile_asf_codeclistobject['codec_entries'] = array();
+ }
$offset += 4;
for ($CodecEntryCounter = 0; $CodecEntryCounter < $thisfile_asf_codeclistobject['codec_entries_count']; $CodecEntryCounter++) {
// shortcut
@@ -528,7 +550,7 @@
$offset += 16;
$thisfile_asf_markerobject['reserved_guid'] = $this->BytestringToGUID($thisfile_asf_markerobject['reserved']);
if ($thisfile_asf_markerobject['reserved'] != $this->GUIDtoBytestring('4CFEDB20-75F6-11CF-9C0F-00A0C90349CB')) {
- $this->warning('marker_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_markerobject['reserved_1']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {4CFEDB20-75F6-11CF-9C0F-00A0C90349CB}');
+ $this->warning('marker_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_markerobject['reserved']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {4CFEDB20-75F6-11CF-9C0F-00A0C90349CB}');
break;
}
$thisfile_asf_markerobject['markers_count'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
@@ -648,7 +670,7 @@
break;
default:
- $this->warning('error_correction_object.error_correction_type GUID {'.$this->BytestringToGUID($thisfile_asf_errorcorrectionobject['reserved']).'} does not match expected "GETID3_ASF_No_Error_Correction" GUID {'.$this->BytestringToGUID(GETID3_ASF_No_Error_Correction).'} or "GETID3_ASF_Audio_Spread" GUID {'.$this->BytestringToGUID(GETID3_ASF_Audio_Spread).'}');
+ $this->warning('error_correction_object.error_correction_type GUID {'.$this->BytestringToGUID($thisfile_asf_errorcorrectionobject['error_correction_type']).'} does not match expected "GETID3_ASF_No_Error_Correction" GUID {'.$this->BytestringToGUID(GETID3_ASF_No_Error_Correction).'} or "GETID3_ASF_Audio_Spread" GUID {'.$this->BytestringToGUID(GETID3_ASF_Audio_Spread).'}');
//return false;
break;
}
@@ -1044,7 +1066,7 @@
break;
}
- if (!empty($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'])) {
+ if (!empty($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'])) { // @phpstan-ignore-line
foreach ($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'] as $dummy => $dataarray) {
if (isset($dataarray['flags']['stream_number']) && ($dataarray['flags']['stream_number'] == $streamnumber)) {
$thisfile_asf_audiomedia_currentstream['bitrate'] = $dataarray['bitrate'];
@@ -1130,7 +1152,7 @@
$videomediaoffset += 4;
$thisfile_asf_videomedia_currentstream['format_data']['codec_data'] = substr($streamdata['type_specific_data'], $videomediaoffset);
- if (!empty($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'])) {
+ if (!empty($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'])) { // @phpstan-ignore-line
foreach ($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'] as $dummy => $dataarray) {
if (isset($dataarray['flags']['stream_number']) && ($dataarray['flags']['stream_number'] == $streamnumber)) {
$thisfile_asf_videomedia_currentstream['bitrate'] = $dataarray['bitrate'];
@@ -1442,7 +1464,7 @@
}
}
}
- $info['bitrate'] = (isset($thisfile_audio['bitrate']) ? $thisfile_audio['bitrate'] : 0) + (isset($thisfile_video['bitrate']) ? $thisfile_video['bitrate'] : 0);
+ $info['bitrate'] = 0 + (isset($thisfile_audio['bitrate']) ? $thisfile_audio['bitrate'] : 0) + (isset($thisfile_video['bitrate']) ? $thisfile_video['bitrate'] : 0);
if ((!isset($info['playtime_seconds']) || ($info['playtime_seconds'] <= 0)) && ($info['bitrate'] > 0)) {
$info['playtime_seconds'] = ($info['filesize'] - $info['avdataoffset']) / ($info['bitrate'] / 8);
@@ -1577,8 +1599,9 @@
'GETID3_ASF_Audio_Media' => 'F8699E40-5B4D-11CF-A8FD-00805F5C442B',
'GETID3_ASF_Media_Object_Index_Object' => 'FEB103F8-12AD-4C64-840F-2A1D2F7AD48C',
'GETID3_ASF_Alt_Extended_Content_Encryption_Obj' => 'FF889EF1-ADEE-40DA-9E71-98704BB928CE',
- 'GETID3_ASF_Index_Placeholder_Object' => 'D9AADE20-7C17-4F9C-BC28-8555DD98E2A2', // http://cpan.uwinnipeg.ca/htdocs/Audio-WMA/Audio/WMA.pm.html
- 'GETID3_ASF_Compatibility_Object' => '26F18B5D-4584-47EC-9F5F-0E651F0452C9', // http://cpan.uwinnipeg.ca/htdocs/Audio-WMA/Audio/WMA.pm.html
+ 'GETID3_ASF_Index_Placeholder_Object' => 'D9AADE20-7C17-4F9C-BC28-8555DD98E2A2', // https://metacpan.org/dist/Audio-WMA/source/WMA.pm
+ 'GETID3_ASF_Compatibility_Object' => '26F18B5D-4584-47EC-9F5F-0E651F0452C9', // https://metacpan.org/dist/Audio-WMA/source/WMA.pm
+ 'GETID3_ASF_Media_Object_Index_Parameters_Object'=> '6B203BAD-3F11-48E4-ACA8-D7613DE2CFA7',
);
return $GUIDarray;
}
@@ -1741,7 +1764,7 @@
* @return array
*/
public function HeaderExtensionObjectDataParse(&$asf_header_extension_object_data, &$unhandled_sections) {
- // http://msdn.microsoft.com/en-us/library/bb643323.aspx
+ // https://web.archive.org/web/20140419205228/http://msdn.microsoft.com/en-us/library/bb643323.aspx
$offset = 0;
$objectOffset = 0;
@@ -1805,8 +1828,8 @@
$thisObject['stream_language_id_index'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$offset += 2;
- $thisObject['average_time_per_frame'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 4));
- $offset += 4;
+ $thisObject['average_time_per_frame'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 8));
+ $offset += 8;
$thisObject['stream_name_count'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$offset += 2;
@@ -1823,7 +1846,7 @@
$streamName['stream_name_length'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$offset += 2;
- $streamName['stream_name'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, $streamName['stream_name_length']));
+ $streamName['stream_name'] = substr($asf_header_extension_object_data, $offset, $streamName['stream_name_length']);
$offset += $streamName['stream_name_length'];
$thisObject['stream_names'][$i] = $streamName;
@@ -1845,7 +1868,7 @@
$payloadExtensionSystem['extension_system_info_length'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 4));
$offset += 4;
- $payloadExtensionSystem['extension_system_info_length'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, $payloadExtensionSystem['extension_system_info_length']));
+ $payloadExtensionSystem['extension_system_info'] = substr($asf_header_extension_object_data, $offset, $payloadExtensionSystem['extension_system_info_length']);
$offset += $payloadExtensionSystem['extension_system_info_length'];
$thisObject['payload_extension_systems'][$i] = $payloadExtensionSystem;
@@ -1853,6 +1876,40 @@
break;
+ case GETID3_ASF_Advanced_Mutual_Exclusion_Object:
+ $thisObject['exclusion_type'] = substr($asf_header_extension_object_data, $offset, 16);
+ $offset += 16;
+ $thisObject['exclusion_type_text'] = $this->BytestringToGUID($thisObject['exclusion_type']);
+
+ $thisObject['stream_numbers_count'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+
+ for ($i = 0; $i < $thisObject['stream_numbers_count']; $i++) {
+ $thisObject['stream_numbers'][$i] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+ }
+
+ break;
+
+ case GETID3_ASF_Stream_Prioritization_Object:
+ $thisObject['priority_records_count'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+
+ for ($i = 0; $i < $thisObject['priority_records_count']; $i++) {
+ $priorityRecord = array();
+
+ $priorityRecord['stream_number'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+
+ $priorityRecord['flags_raw'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+ $priorityRecord['flags']['mandatory'] = (bool) $priorityRecord['flags_raw'] & 0x00000001;
+
+ $thisObject['priority_records'][$i] = $priorityRecord;
+ }
+
+ break;
+
case GETID3_ASF_Padding_Object:
// padding, skip it
break;
@@ -1970,6 +2027,103 @@
}
break;
+ case GETID3_ASF_Index_Parameters_Object:
+ $thisObject['index_entry_time_interval'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 4));
+ $offset += 4;
+
+ $thisObject['index_specifiers_count'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+
+ for ($i = 0; $i < $thisObject['index_specifiers_count']; $i++) {
+ $indexSpecifier = array();
+
+ $indexSpecifier['stream_number'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+
+ $indexSpecifier['index_type'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+ $indexSpecifier['index_type_text'] = isset(static::$ASFIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']])
+ ? static::$ASFIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']]
+ : 'invalid'
+ ;
+
+ $thisObject['index_specifiers'][$i] = $indexSpecifier;
+ }
+
+ break;
+
+ case GETID3_ASF_Media_Object_Index_Parameters_Object:
+ $thisObject['index_entry_count_interval'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 4));
+ $offset += 4;
+
+ $thisObject['index_specifiers_count'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+
+ for ($i = 0; $i < $thisObject['index_specifiers_count']; $i++) {
+ $indexSpecifier = array();
+
+ $indexSpecifier['stream_number'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+
+ $indexSpecifier['index_type'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+ $indexSpecifier['index_type_text'] = isset(static::$ASFMediaObjectIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']])
+ ? static::$ASFMediaObjectIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']]
+ : 'invalid'
+ ;
+
+ $thisObject['index_specifiers'][$i] = $indexSpecifier;
+ }
+
+ break;
+
+ case GETID3_ASF_Timecode_Index_Parameters_Object:
+ // 4.11 Timecode Index Parameters Object (mandatory only if TIMECODE index is present in file, 0 or 1)
+ // Field name Field type Size (bits)
+ // Object ID GUID 128 // GUID for the Timecode Index Parameters Object - ASF_Timecode_Index_Parameters_Object
+ // Object Size QWORD 64 // Specifies the size, in bytes, of the Timecode Index Parameters Object. Valid values are at least 34 bytes.
+ // Index Entry Count Interval DWORD 32 // This value is ignored for the Timecode Index Parameters Object.
+ // Index Specifiers Count WORD 16 // Specifies the number of entries in the Index Specifiers list. Valid values are 1 and greater.
+ // Index Specifiers array of: varies //
+ // * Stream Number WORD 16 // Specifies the stream number that the Index Specifiers refer to. Valid values are between 1 and 127.
+ // * Index Type WORD 16 // Specifies the type of index. Values are defined as follows (1 is not a valid value):
+ // 2 = Nearest Past Media Object - indexes point to the closest data packet containing an entire video frame or the first fragment of a video frame
+ // 3 = Nearest Past Cleanpoint - indexes point to the closest data packet containing an entire video frame (or first fragment of a video frame) that is a key frame.
+ // Nearest Past Media Object is the most common value
+
+ $thisObject['index_entry_count_interval'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 4));
+ $offset += 4;
+
+ $thisObject['index_specifiers_count'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+
+ for ($i = 0; $i < $thisObject['index_specifiers_count']; $i++) {
+ $indexSpecifier = array();
+
+ $indexSpecifier['stream_number'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+
+ $indexSpecifier['index_type'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
+ $offset += 2;
+ $indexSpecifier['index_type_text'] = isset(static::$ASFTimecodeIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']])
+ ? static::$ASFTimecodeIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']]
+ : 'invalid'
+ ;
+
+ $thisObject['index_specifiers'][$i] = $indexSpecifier;
+ }
+
+ break;
+
+ case GETID3_ASF_Compatibility_Object:
+ $thisObject['profile'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 1));
+ $offset += 1;
+
+ $thisObject['mode'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 1));
+ $offset += 1;
+
+ break;
+
default:
$unhandled_sections++;
if ($this->GUIDname($thisObject['guid_text'])) {