1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
6 * Moonlight List (moonlight-list@lists.ximian.com)
8 * Copyright 2007 Novell, Inc. (http://www.novell.com)
10 * See the LICENSE file included with the distribution for details.
20 wchar_to_utf8 (void* unicode
, guint32 length
)
28 result
= g_utf16_to_utf8 ((const gunichar2
*) unicode
, length
, NULL
, NULL
, &err
);
30 ASF_LOG ("Could not convert to utf8from utf16: %s\n", err
->message
);
39 asf_header_validate (const asf_header
* header
, ASFParser
* parser
)
41 // SPEC: This field shall be set to ASF_Header_Object
42 if (!asf_guid_validate (&header
->id
, &asf_guids_header
, parser
)) {
46 // SPEC: valid values are at least 30 bytes
47 if (header
->size
< 30) {
48 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 30, got %" G_GUINT64_FORMAT
").", header
->size
));
52 // SPEC: This field must be set to the value 0x02. If the this value is different when read, the application should fail to source the content.
53 if (header
->reserved2
!= 0x02) {
54 parser
->AddError (g_strdup_printf ("Invalid reserved2 value (expected 0x02, got: %x).", header
->reserved2
));
62 asf_file_properties_validate (const asf_file_properties
* obj
, ASFParser
* parser
)
64 // SPEC: This field shall be set to ASF_File_Properties_Object
65 if (!asf_guid_validate (&obj
->id
, &asf_guids_file_properties
, parser
)) {
69 // SPEC: Valid values are at least 104 bytes
70 if (obj
->size
< 104) {
71 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 104, got %" G_GUINT64_FORMAT
").", obj
->size
));
75 // SPEC: the values for the Minimum Data Packet Size and Maximum Data Packet Size
76 // fields shall be set to the same value, and this value should be set to the packet size,
77 // even when the Broadcast Flag in the Flags field is set to 1.
78 if (obj
->min_packet_size
!= obj
->max_packet_size
) {
79 // This is not logical at all, but it's what the spec says.
80 // besides, our code depends on it (it makes a few minor things easier).
81 parser
->AddError (g_strdup_printf ("The min packet size (%d) is different from the max packet size (%d).", obj
->min_packet_size
, obj
->max_packet_size
));
85 if (obj
->size
> parser
->header
->size
) {
86 parser
->AddError (g_strdup_printf ("The size of the file property object (%" G_GUINT64_FORMAT
") is bigger than the sizeof the entire header itself (%" G_GUINT64_FORMAT
").", obj
->size
, parser
->header
->size
));
94 asf_stream_properties_validate (const asf_stream_properties
* obj
, ASFParser
* parser
)
96 if (!(asf_guid_validate (&obj
->id
, &asf_guids_stream_properties
, parser
))) {
100 if (obj
->size
< 78) {
101 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 78, got %" G_GUINT64_FORMAT
").", obj
->size
));
109 asf_header_extension_validate (const asf_header_extension
* obj
, ASFParser
* parser
)
111 if (!(asf_guid_validate (&obj
->id
, &asf_guids_header_extension
, parser
))) {
115 if (obj
->size
< 46) {
116 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 46, got %" G_GUINT64_FORMAT
").", obj
->size
));
120 if (obj
->data_size
< 24 && obj
->data_size
> 1) {
121 parser
->AddError (g_strdup_printf ("Invalid data_size (expected >= 24 or 0, got %u).", obj
->data_size
));
123 } else if (obj
->data_size
!= 0 && obj
->data_size
+ 46 != obj
->size
) {
124 parser
->AddError (g_strdup_printf ("Invalid data_size (expected size - 46, got %" G_GUINT64_FORMAT
" - 46 = %u).", obj
->size
, obj
->data_size
));
128 if (obj
->data_size
== 0)
131 guint64 max_size
= obj
->size
;
134 guint64 accum_length
= 0;
135 void *data
= obj
->get_data ();
136 asf_object
*header_obj
;
139 if (size
+ 24 /* minimum object size */ > max_size
) {
140 parser
->AddError (g_strdup_printf ("Invalid header extension size."));
144 header_obj
= (asf_object
*) (((char *) data
) + accum_length
);
145 length
= header_obj
->size
;
147 parser
->AddError (g_strdup_printf ("Invalid header length is zero"));
150 accum_length
+= length
;
152 if (size
> max_size
) {
153 parser
->AddError (g_strdup_printf ("Invalid header extension object."));
157 if (!asf_object_validate_exact (header_obj
, parser
))
160 } while (size
< max_size
);
165 bool asf_codec_list_validate (const asf_codec_list
* obj
, ASFParser
* parser
)
167 if (!(asf_guid_validate (&obj
->id
, &asf_guids_codec_list
, parser
))) {
171 if (obj
->size
< 44) {
172 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 44, got %" G_GUINT64_FORMAT
").", obj
->size
));
175 // TODO: More verifications?
179 bool asf_script_command_validate (const asf_script_command
* obj
, ASFParser
* parser
)
181 if (!(asf_guid_validate (&obj
->id
, &asf_guids_script_command
, parser
))) {
185 if (obj
->size
< 44) {
186 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 44, got %" G_GUINT64_FORMAT
").", obj
->size
));
189 // TODO: More verifications?
193 bool asf_marker_validate (const asf_marker
* obj
, ASFParser
* parser
)
195 if (!(asf_guid_validate (&obj
->id
, &asf_guids_marker
, parser
))) {
199 if (obj
->size
< 48) {
200 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 48, got %" G_GUINT64_FORMAT
").", obj
->size
));
203 // TODO: More verifications?
207 bool asf_bitrate_mutual_exclusion_validate (const asf_bitrate_mutual_exclusion
* obj
, ASFParser
* parser
)
209 if (!(asf_guid_validate (&obj
->id
, &asf_guids_bitrate_mutual_exclusion
, parser
))) {
213 if (obj
->size
< 42) {
214 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 42, got %" G_GUINT64_FORMAT
").", obj
->size
));
217 // TODO: More verifications?
221 bool asf_error_correction_validate (const asf_error_correction
* obj
, ASFParser
* parser
)
223 if (!(asf_guid_validate (&obj
->id
, &asf_guids_error_correction
, parser
))) {
227 if (obj
->size
< 44) {
228 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 44, got %" G_GUINT64_FORMAT
").", obj
->size
));
231 // TODO: More verifications?
235 bool asf_content_description_validate (const asf_content_description
* obj
, ASFParser
* parser
)
237 if (!(asf_guid_validate (&obj
->id
, &asf_guids_content_description
, parser
))) {
241 if (obj
->size
< 34) {
242 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 34, got %" G_GUINT64_FORMAT
").", obj
->size
));
245 // TODO: More verifications?
249 bool asf_extended_content_description_validate (const asf_extended_content_description
* obj
, ASFParser
* parser
)
251 if (!(asf_guid_validate (&obj
->id
, &asf_guids_extended_content_description
, parser
))) {
255 if (obj
->size
< 26) {
256 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 26, got %" G_GUINT64_FORMAT
").", obj
->size
));
259 // TODO: More verifications?
263 bool asf_stream_bitrate_properties_validate (const asf_stream_bitrate_properties
* obj
, ASFParser
* parser
)
265 if (!(asf_guid_validate (&obj
->id
, &asf_guids_stream_bitrate_properties
, parser
))) {
269 if (obj
->size
< 26) {
270 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 26, got %" G_GUINT64_FORMAT
").", obj
->size
));
273 // TODO: More verifications?
277 bool asf_data_validate (const asf_data
* obj
, ASFParser
* parser
)
279 if (!(asf_guid_validate (&obj
->id
, &asf_guids_data
, parser
))) {
283 if (obj
->size
< 50) {
284 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 50, got %" G_GUINT64_FORMAT
").", obj
->size
));
288 if (!(asf_guid_compare (&obj
->file_id
, &parser
->GetFileProperties ()->file_id
))) {
289 parser
->AddError ("Data file id and header's file properties file id don't match.");
293 // TODO: More verifications?
298 asf_error_correction_data::FillInAll (ASFContext
*context
)
300 IMediaSource
*source
= context
->source
;
305 if (!source
->ReadAll (&data
, 1)) {
306 ASF_LOG_ERROR ("asf_error_correction_data::FillInAll (): Error while reading 'data'.\n");
307 return MEDIA_READ_ERROR
;
310 if (!is_error_correction_present ())
311 return MEDIA_SUCCESS
;
313 if (!source
->ReadAll (&first
, 1)) {
314 ASF_LOG_ERROR ("asf_error_correction_data::FillInAll (): Error while reading 'first'.\n");
315 return MEDIA_READ_ERROR
;
318 if (!source
->ReadAll (&second
, 1)) {
319 ASF_LOG_ERROR ("asf_error_correction_data::FillInAll (): Error while reading 'second'.\n");
320 return MEDIA_READ_ERROR
;
323 return MEDIA_SUCCESS
;
327 asf_error_correction_data_dump (asf_error_correction_data
* obj
)
329 char* tostring
= obj
->tostring ();
330 ASF_DUMP ("ASF_ERROR_CORRECTION_DATA\n");
331 ASF_DUMP ("\tdata = 0x%X\n", (asf_dword
) obj
->data
);
332 ASF_DUMP ("\tdata = 0b%s\n", tostring
); g_free (tostring
);
333 ASF_DUMP ("\t\tis_error_correction_present: %d\n", obj
->is_error_correction_present ());
334 ASF_DUMP ("\t\tis_opaque_data_present: %d\n", obj
->is_opaque_data_present ());
335 ASF_DUMP ("\t\tdata_length: %d\n", obj
->get_data_length ());
336 ASF_DUMP ("\t\tlength_type: %d\n", obj
->get_error_correction_length_type ());
337 ASF_DUMP ("\tfirst = %X\n", (asf_dword
) obj
->first
);
339 ASF_DUMP ("\tsecond = %X\n", (asf_dword
) obj
->second
);
343 asf_payload_parsing_information::FillInAll (ASFContext
*context
)
345 ASFParser
*parser
= context
->parser
;
346 IMediaSource
*source
= context
->source
;
347 // There's no guarantee that these fields will be written to by Read ()
355 if (!source
->ReadAll (&length_type_flags
, 1)) {
356 ASF_LOG_ERROR ("asf_payload_parsing_information::FillInAll (): Error while reading 'length_type_flags'.\n");
357 return MEDIA_READ_ERROR
;
360 if (!source
->ReadAll (&property_flags
, 1)) {
361 ASF_LOG_ERROR ("asf_payload_parsing_information::FillInAll (): Error while reading 'property_flags'.\n");
362 return MEDIA_READ_ERROR
;
365 if (get_packet_length_type () == 0) {
366 packet_length
= parser
->GetPacketSize ();
368 if (!ASFParser::ReadEncoded (source
, get_packet_length_type (), &packet_length
)) {
369 ASF_LOG_ERROR ("asf_payload_parsing_information::FillInAll (): Error while reading 'packet_length'.\n");
370 return MEDIA_READ_ERROR
;
374 if (!ASFParser::ReadEncoded (source
, get_sequence_type (), &sequence
)) {
375 ASF_LOG_ERROR ("asf_payload_parsing_information::FillInAll (): Error while reading 'sequence'.\n");
376 return MEDIA_READ_ERROR
;
379 if (!ASFParser::ReadEncoded (source
, get_padding_length_type (), &padding_length
)) {
380 ASF_LOG_ERROR ("asf_payload_parsing_information::FillInAll (): Error while reading 'padding_length'.\n");
381 return MEDIA_READ_ERROR
;
384 if (!source
->ReadAll (&send_time
, 4)) {
385 ASF_LOG_ERROR ("asf_payload_parsing_information::FillInAll (): Error while reading 'send_time'.\n");
386 return MEDIA_READ_ERROR
;
389 if (!source
->ReadAll (&duration
, 2)) {
390 ASF_LOG_ERROR ("asf_payload_parsing_information::FillInAll (): Error while reading 'duration'.\n");
391 return MEDIA_READ_ERROR
;
394 return MEDIA_SUCCESS
;
397 void asf_payload_parsing_information_dump (asf_payload_parsing_information
* obj
)
399 ASF_DUMP ("ASF_PAYLOAD_PARSING_INFORMATION\n");
400 ASF_DUMP ("\tlength_type_flags = %X\n", (asf_dword
) obj
->length_type_flags
);
401 ASF_DUMP ("\t\tmultiple_payloads_present = %d\n", obj
->is_multiple_payloads_present ());
402 ASF_DUMP ("\t\tsequence_type = %d\n", obj
->get_sequence_type ());
403 ASF_DUMP ("\t\tpadding_length_type = %d\n", obj
->get_padding_length_type ());
404 ASF_DUMP ("\t\tpacket_length_type = %d\n", obj
->get_packet_length_type ());
405 ASF_DUMP ("\tproperty_flags = %X\n", (asf_dword
) obj
->property_flags
);
406 ASF_DUMP ("\t\treplicated_data_length_type = %d\n", obj
->get_replicated_data_length_type ());
407 ASF_DUMP ("\t\toffset_into_media_object_length_type = %d\n", obj
->get_offset_into_media_object_length_type ());
408 ASF_DUMP ("\t\tmedia_object_number_length_type = %d\n", obj
->get_media_object_number_length_type ());
409 ASF_DUMP ("\t\tstream_number_length_type = %d\n", obj
->get_stream_number_length_type ());
410 ASF_DUMP ("\tpacket_length = %u\n", (asf_dword
) obj
->packet_length
);
411 ASF_DUMP ("\tsequence = %u\n", (asf_dword
) obj
->sequence
);
412 ASF_DUMP ("\tpadding_length = %u\n", (asf_dword
) obj
->padding_length
);
413 ASF_DUMP ("\tsend_time = %u\n", (asf_dword
) obj
->send_time
);
414 ASF_DUMP ("\tduration = %u\n", (asf_dword
) obj
->duration
);
418 asf_single_payload::Clone ()
420 asf_single_payload
*result
= new asf_single_payload ();
422 result
->stream_id
= stream_id
;
423 result
->is_key_frame
= is_key_frame
;
424 result
->media_object_number
= media_object_number
;
425 result
->offset_into_media_object
= offset_into_media_object
;
426 result
->replicated_data_length
= replicated_data_length
;
427 if (replicated_data
!= NULL
) {
428 result
->replicated_data
= (asf_byte
*) g_malloc (replicated_data_length
);
429 memcpy (result
->replicated_data
, replicated_data
, replicated_data_length
);
431 result
->payload_data_length
= payload_data_length
;
432 if (payload_data
!= NULL
) {
433 result
->payload_data
= (asf_byte
*) g_malloc (payload_data_length
);
434 memcpy (result
->payload_data
, payload_data
, payload_data_length
);
436 result
->presentation_time
= presentation_time
;
442 asf_single_payload::FillInAll (ASFContext
*context
, asf_error_correction_data
* ecd
, asf_payload_parsing_information ppi
, asf_multiple_payloads
* mp
)
444 ASFParser
*parser
= context
->parser
;
445 IMediaSource
*source
= context
->source
;
447 if (!source
->ReadAll (&stream_id
, 1)) {
448 ASF_LOG_ERROR ("asf_single_payload::FillInAll (): Error while reading 'stream_id'.\n");
449 return MEDIA_READ_ERROR
;
452 is_key_frame
= stream_id
& 0x80;
453 stream_id
= stream_id
& 0x7F;
455 if (!parser
->IsValidStream (stream_id
)) {
456 ASF_LOG_ERROR ("asf_single_payload::FillInAll: Invalid stream number (%d).", (int) stream_id
);
457 return MEDIA_INVALID_DATA
;
460 media_object_number
= 0;
461 offset_into_media_object
= 0;
462 replicated_data_length
= 0;
463 replicated_data
= NULL
;
464 payload_data_length
= 0;
466 presentation_time
= 0;
468 ASF_LOG ("asf_single_payload::FillInAll (%p, %p, [Length type flags: %i, property flags: %i (mon:%i,oimo:%i,rpl:%i,sl:%i]). Stream: %i\n", context
, ecd
, ppi
.length_type_flags
, ppi
.property_flags
, ppi
.get_offset_into_media_object_length_type (), ppi
.get_media_object_number_length_type (), ppi
.get_replicated_data_length_type (), ppi
.get_stream_number_length_type (), stream_id
);
470 if (!ASFParser::ReadEncoded (source
, ppi
.get_media_object_number_length_type (), &media_object_number
)) {
471 ASF_LOG_ERROR ("asf_single_payload::FillInAll (): Error while reading 'media_object_number'.\n");
472 return MEDIA_READ_ERROR
;
475 if (!ASFParser::ReadEncoded (source
, ppi
.get_offset_into_media_object_length_type (), &offset_into_media_object
)) {
476 ASF_LOG_ERROR ("asf_single_payload::FillInAll (): Error while reading 'offset_into_media_object'.\n");
477 return MEDIA_READ_ERROR
;
480 if (!ASFParser::ReadEncoded (source
, ppi
.get_replicated_data_length_type (), &replicated_data_length
)) {
481 ASF_LOG_ERROR ("asf_single_payload::FillInAll (): Error while reading 'replicated_data_length'.\n");
482 return MEDIA_READ_ERROR
;
485 if (replicated_data_length
>= 2 && replicated_data_length
< 7) {
486 parser
->AddError (g_strdup_printf ("Invalid replicated data length: %d", replicated_data_length
));
487 return MEDIA_INVALID_DATA
;
490 if (replicated_data_length
> parser
->file_properties
->max_packet_size
) {
491 parser
->AddError ("Data corruption in payload.");
492 return MEDIA_INVALID_DATA
;
495 replicated_data
= (asf_byte
*) parser
->MallocVerified (replicated_data_length
);
496 if (replicated_data
== NULL
) {
497 return MEDIA_OUT_OF_MEMORY
;
500 if (!source
->ReadAll (replicated_data
, replicated_data_length
)) {
501 ASF_LOG_ERROR ("asf_single_payload::FillInAll (): Error while reading 'replicated_data'.\n");
502 return MEDIA_READ_ERROR
;
505 if (replicated_data_length
== 1) {
506 presentation_time
= offset_into_media_object
;
507 } else if (replicated_data_length
>= 8) {
508 presentation_time
= *(((asf_dword
*) replicated_data
) + 1);
512 if (!ASFParser::ReadEncoded (source
, mp
->get_payload_length_type (), &payload_data_length
)) {
513 ASF_LOG_ERROR ("asf_single_payload::FillInAll (): Error while reading 'payload_data_length'.\n");
514 return MEDIA_READ_ERROR
;
517 if (payload_data_length
== 0) {
518 parser
->AddError ("Warning: Invalid payload data length: can't be 0.");
523 // The number of bytes in this array can be calculated from the overall Packet Length field,
524 // and is equal to the Packet Length
525 payload_length
= ppi
.packet_length
;
526 // minus the packet header length,
527 payload_length
-= ppi
.get_struct_size ();
528 payload_length
-= ecd
->get_struct_size (),
529 // minus the payload header length (including Replicated Data),
530 payload_length
-= 1; // stream_number
531 payload_length
-= ASF_DECODE_PACKED_SIZE (ppi
.get_media_object_number_length_type ());
532 payload_length
-= ASF_DECODE_PACKED_SIZE (ppi
.get_offset_into_media_object_length_type ());
533 payload_length
-= ASF_DECODE_PACKED_SIZE (ppi
.get_replicated_data_length_type ());
534 payload_length
-= replicated_data_length
;
535 // minus the Padding Length.
536 payload_length
-= ppi
.padding_length
;
537 ASF_LOG ("payload_length: %d. packet_length: %d, ppi.get_struct_size: %d, replicated_data_length: %d, padding_length: %d, ecd.get_struct_size: %d\n",
538 payload_length
, ppi
.packet_length
, ppi
.get_struct_size (), replicated_data_length
, ppi
.padding_length
, ecd
->get_struct_size ());
540 if (payload_length
< 0) {
541 parser
->AddError (g_strdup_printf ("Invalid payload length: %d", payload_length
));
542 return MEDIA_INVALID_DATA
;
545 payload_data_length
= (asf_dword
) payload_length
;
548 if (payload_data_length
> 0) {
549 if (payload_data_length
>= parser
->file_properties
->max_packet_size
) {
550 parser
->AddError ("Data corruption in payload.");
551 return MEDIA_INVALID_DATA
;
554 payload_data
= (asf_byte
*) parser
->MallocVerified (payload_data_length
);
555 if (payload_data
== NULL
) {
556 return MEDIA_OUT_OF_MEMORY
;
559 if (!source
->ReadAll (payload_data
, payload_data_length
)) {
560 ASF_LOG_ERROR ("asf_single_payload::FillInAll (): Error while reading 'payload_data'.\n");
561 return MEDIA_READ_ERROR
;
566 return MEDIA_SUCCESS
;
569 asf_single_payload::~asf_single_payload ()
571 g_free (replicated_data
);
572 replicated_data
= NULL
;
574 g_free (payload_data
);
579 asf_single_payload_dump (asf_single_payload
* obj
)
581 ASF_DUMP ("ASF_SINGLE_PAYLOAD\n");
582 ASF_DUMP ("\tstream_number = %u\n", (asf_dword
) obj
->stream_id
);
583 ASF_DUMP ("\tis_key_frame = %s\n", obj
->is_key_frame
? "true" : "false");
584 ASF_DUMP ("\tmedia_object_number = %u\n", (asf_dword
) obj
->media_object_number
);
585 ASF_DUMP ("\toffset_into_media_object = %u\n", (asf_dword
) obj
->offset_into_media_object
);
586 ASF_DUMP ("\treplicated_data_length = %u\n", (asf_dword
) obj
->replicated_data_length
);
587 ASF_DUMP ("\treplicated_data = %s\n", obj
->replicated_data
? "non-null" : "null");
588 ASF_DUMP ("\tpayload_data_length = %u\n", (asf_dword
) obj
->payload_data_length
);
589 ASF_DUMP ("\tpayload_data = %s\n", obj
->payload_data
? "non-null" : "null");
590 ASF_DUMP ("\tget_presentation_time = %" G_GINT64_FORMAT
"\n", obj
->get_presentation_time ());
594 asf_multiple_payloads::ResizeList (ASFParser
* parser
, int requested_size
)
596 if (requested_size
<= payloads_size
)
599 asf_single_payload
** new_list
;
601 new_list
= (asf_single_payload
**) parser
->MallocVerified ((requested_size
+ 1) * sizeof (asf_single_payload
*));
603 if (new_list
== NULL
) {
607 if (payloads
!= NULL
) {
608 memcpy (new_list
, payloads
, sizeof (asf_single_payload
*) * payloads_size
);
613 payloads_size
= requested_size
;
619 asf_multiple_payloads::CountCompressedPayloads (ASFParser
* parser
, asf_single_payload
* payload
)
621 asf_byte
* data
= payload
->payload_data
;
622 asf_dword length
= payload
->payload_data_length
;
628 parser
->AddError ("Compressed payload is corrupted.");
634 size
= *(data
+ offset
);
635 offset
+= (size
+ 1);
636 if (offset
> length
|| size
== 0) {
637 parser
->AddError ("Compressed payloads are corrupted.");
639 } else if (offset
== length
) {
648 asf_multiple_payloads::ReadCompressedPayload (ASFParser
* parser
, asf_single_payload
* first
, int count
, int start_index
)
650 asf_byte
* data
= first
->payload_data
;
653 asf_single_payload
* payload
= NULL
;
655 for (int i
= 0; i
< count
; i
++) {
656 size
= *(data
+ offset
);
659 payload
= new asf_single_payload ();
660 payloads
[start_index
+ i
] = payload
;
662 payload
->stream_id
= first
->stream_id
;
663 payload
->is_key_frame
= first
->is_key_frame
;
664 payload
->media_object_number
= first
->media_object_number
+ i
;
665 payload
->offset_into_media_object
= 0;
666 payload
->replicated_data_length
= 0;
667 payload
->replicated_data
= NULL
;
668 payload
->presentation_time
= first
->presentation_time
+ i
* first
->get_presentation_time_delta ();
669 payload
->payload_data_length
= size
;
670 payload
->payload_data
= (asf_byte
*) parser
->Malloc (size
);
671 if (payload
->payload_data
== NULL
) {
672 return MEDIA_OUT_OF_MEMORY
;
674 memcpy (payload
->payload_data
, data
+ offset
, size
);
678 return MEDIA_SUCCESS
;
682 asf_multiple_payloads::FillInAll (ASFContext
*context
, asf_error_correction_data
* ecd
, asf_payload_parsing_information ppi
)
684 ASFParser
*parser
= context
->parser
;
685 IMediaSource
*source
= context
->source
;
689 if (ppi
.is_multiple_payloads_present ()) {
690 if (!source
->ReadAll (&payload_flags
, 1)) {
691 ASF_LOG_ERROR ("asf_multiple_payload::FillInAll (): Error while reading 'payload_flags'.\n");
692 return MEDIA_READ_ERROR
;
695 count
= payload_flags
& 0x3F; // number of payloads is encoded in a byte, no need to check for extreme values.
698 parser
->AddError (g_strdup_printf ("Invalid number of payloads: %d", count
));
699 return MEDIA_INVALID_DATA
;
702 if (!ResizeList (parser
, count
)) {
703 return MEDIA_OUT_OF_MEMORY
;
706 ASF_LOG ("asf_multiple_payloads::FillInAll (): Reading %d payloads...\n", count
);
708 int current_index
= 0;
709 for (int i
= 0; i
< count
; i
++) {
710 payloads
[current_index
] = new asf_single_payload ();
712 result
= payloads
[current_index
]->FillInAll (context
, ecd
, ppi
, this);
713 if (!MEDIA_SUCCEEDED (result
)) {
714 delete payloads
[current_index
];
715 payloads
[current_index
] = NULL
;
719 if (payloads
[current_index
]->is_compressed ()) {
720 asf_single_payload
* first
= payloads
[current_index
];
721 int number
= CountCompressedPayloads (parser
, first
);
723 return MEDIA_INVALID_DATA
;
725 if (!ResizeList (parser
, number
+ payloads_size
)) {
726 return MEDIA_OUT_OF_MEMORY
;
728 result
= ReadCompressedPayload (parser
, first
, number
, current_index
);
729 if (!MEDIA_SUCCEEDED (result
)) {
735 ASF_DUMP ("-Payload #%d:\n", current_index
+ 1);
736 asf_single_payload_dump (payloads
[current_index
]);
741 ASF_LOG ("asf_multiple_payloads::FillInAll (%p, %p, ?): A single payload\n", context
, ecd
);
743 asf_single_payload
* payload
= new asf_single_payload ();
744 result
= payload
->FillInAll (context
, ecd
, ppi
, NULL
);
745 if (!MEDIA_SUCCEEDED (result
)) {
750 if (payload
->is_compressed ()) {
753 counter
= CountCompressedPayloads (parser
, payload
);
755 return MEDIA_INVALID_DATA
;
758 if (!ResizeList (parser
, counter
)) {
759 return MEDIA_OUT_OF_MEMORY
;
762 result
= ReadCompressedPayload (parser
, payload
, counter
, 0);
763 if (!MEDIA_SUCCEEDED (result
)) {
770 payloads
= (asf_single_payload
**) parser
->MallocVerified (sizeof (asf_single_payload
*) * 2);
771 if (payloads
== NULL
) {
772 return MEDIA_OUT_OF_MEMORY
;
774 payloads
[0] = payload
;
776 payload_flags
= 1; // 1 payload
779 return MEDIA_SUCCESS
;
782 void asf_multiple_payloads_dump (asf_multiple_payloads
* obj
)
784 ASF_DUMP ("ASF_MULTIPLE_PAYLOADS\n");
785 ASF_DUMP ("\tpayload_flags = %u\n", (asf_dword
) obj
->payload_flags
);
786 ASF_DUMP ("\t\tnumber of payloads = %d\n", obj
->get_number_of_payloads ());
787 ASF_DUMP ("\t\tpayload_length_type = %d\n", obj
->get_payload_length_type ());
791 while (obj
->payloads
[i
] != NULL
) {
792 ASF_DUMP ("\tpayload #%d:\n", i
+ 1);
793 asf_single_payload_dump (obj
->payloads
[i
++]);
796 ASF_DUMP ("\t<no payloads here>\n");
800 asf_script_command_entry
**
801 asf_script_command::get_commands (ASFParser
* parser
, char*** command_types
)
803 //printf ("asf_script_command::get_commands ().\n");
804 int size_left
= size
;
805 int size_requested
= 0;
808 asf_script_command_entry
** result
= NULL
;
809 asf_script_command_entry
* next
= NULL
;
811 if (size
== sizeof (asf_script_command
)) {
812 //printf ("asf_script_command::get_commands (), size = %d\n", size);
816 size_left
-= sizeof (asf_script_command
);
818 size_requested
= sizeof (char*) * (command_count
+ 1);
819 if (size_requested
> size_left
) {
820 parser
->AddError ("Data corruption in script command.");
824 result
= (asf_script_command_entry
**) parser
->MallocVerified (size_requested
);
828 size_requested
= sizeof (char*) * (command_type_count
+ 1);
829 if (size_requested
> size_left
) {
830 parser
->AddError ("Data corruption in script command.");
834 types
= (char**) parser
->MallocVerified (size_requested
);
838 if (command_types
!= NULL
)
839 *command_types
= types
;
841 // Walk past by the command type table.
842 start
= (sizeof (asf_script_command
) + (char*) this);
843 for (int i
= 0; i
< command_type_count
; i
++) {
844 asf_word length
= * (asf_word
*) start
;
847 size_requested
= sizeof (asf_word
) + sizeof (guint16
) * length
;
848 if (size_requested
> size_left
) {
849 parser
->AddError ("Data corruption in script command.");
852 size_left
-= size_requested
;
855 types
[i
] = wchar_to_utf8 (start
+ sizeof (asf_word
), length
);
856 start
+= size_requested
;
859 // Fill in the commands table
860 next
= (asf_script_command_entry
*) start
;
861 for (int i
= 0; i
< command_count
; i
++) {
864 char* tmp
= (char*) next
;
865 tmp
+= sizeof (asf_script_command_entry
);
866 tmp
+= (next
->name_length
* sizeof (guint16
));
868 size_requested
= sizeof (asf_script_command_entry
) + next
->name_length
* sizeof (guint16
);
869 if (size_requested
> size_left
) {
870 parser
->AddError ("Data corruption in script command.");
873 size_left
-= size_requested
;
875 next
= (asf_script_command_entry
*) tmp
;
878 //printf ("asf_script_command::read_commands (): success, read %d commands and %d types.\n", command_count, command_type_count);
882 //printf ("asf_script_command::read_commands (): failure.\n");
885 for (int i
= 0; types
[i
]; i
++)
890 if (command_types
!= NULL
)
891 *command_types
= NULL
;
897 void asf_marker_entry_dump (const asf_marker_entry
* obj
)
900 asf_marker_entry
* o
= (asf_marker_entry
*) obj
;
901 ASF_DUMP ("\tASF_MARKER_ENTRY\n");
902 ASF_DUMP ("\t\toffset = %" G_GUINT64_FORMAT
"\n", obj
->offset
);
903 ASF_DUMP ("\t\tpts = %" G_GUINT64_FORMAT
"\n", obj
->pts
);
904 ASF_DUMP ("\t\tentry_length = %d\n", (asf_dword
) obj
->entry_length
);
905 ASF_DUMP ("\t\tsend_time = %d\n", obj
->send_time
);
906 ASF_DUMP ("\t\tflags = %d\n", obj
->flags
);
907 ASF_DUMP ("\t\tmarker_description_length = %d\n", o
->marker_description_length
);
908 ASF_DUMP ("\t\tmarker_description = %s\n", o
->get_marker_description ());
912 void asf_marker_dump (const asf_marker
* obj
)
914 asf_marker
* o
= (asf_marker
*) obj
;
916 ASF_DUMP ("ASF_MARKER\n");
917 ASF_DUMP ("\tid = %s\n", asf_guid_tostring (&obj
->id
));
918 ASF_DUMP ("\tsize = %" G_GUINT64_FORMAT
"\n", obj
->size
);
919 ASF_DUMP ("\treserved = %s\n", asf_guid_tostring (&obj
->reserved
));
920 ASF_DUMP ("\tmarker_count = %u\n", (asf_dword
) obj
->marker_count
);
921 ASF_DUMP ("\treserved2 = %u\n", (asf_dword
) obj
->reserved2
);
922 ASF_DUMP ("\tname_length = %u\n", (asf_dword
) obj
->name_length
);
923 ASF_DUMP ("\tname = %s\n", o
->get_name ());
925 for (guint32 i
= 0; i
< obj
->marker_count
; i
++) {
926 asf_marker_entry_dump (o
->get_entry (i
));
930 void asf_script_command_dump (ASFParser
* parser
, const asf_script_command
* obj
)
933 asf_script_command
* o
= (asf_script_command
*) obj
;
936 ASF_DUMP ("ASF_SCRIPT_COMMAND\n");
937 ASF_DUMP ("\tid = %s\n", asf_guid_tostring (&obj
->id
));
938 ASF_DUMP ("\tsize = %" G_GUINT64_FORMAT
"\n", obj
->size
);
939 ASF_DUMP ("\treserved = %s\n", asf_guid_tostring (&obj
->reserved
));
940 ASF_DUMP ("\tcommand_count = %u\n", (asf_dword
) obj
->command_count
);
941 ASF_DUMP ("\tcommand_type_count = %u\n", (asf_dword
) obj
->command_type_count
);
943 char** command_types
= NULL
;
944 asf_script_command_entry
** entries
= NULL
;
946 entries
= o
->get_commands (parser
, &command_types
);
948 for (i
= 0; i
< obj
->command_type_count
; i
++) {
949 ASF_DUMP ("\tASF_SCRIPT_COMMAND_TYPE #%d\n", i
);
950 ASF_DUMP ("\t\tname = %s\n", command_types
[i
]);
953 for (i
= 0; i
< obj
->command_count
; i
++) {
954 ASF_DUMP ("\tASF_SCRIPT_COMMAND #%u\n", i
);
955 asf_script_command_entry
* entry
= entries
[i
];
956 ASF_DUMP ("\t\tpts = %u\n", entry
->pts
);
957 ASF_DUMP ("\t\ttype_index = %d\n", (asf_dword
) entry
->type_index
);
958 ASF_DUMP ("\t\tname_length = %d\n", (asf_dword
) entry
->name_length
);
959 ASF_DUMP ("\t\tname = %s\n", entry
->get_name ());
964 void asf_header_extension_dump (const asf_header_extension
* obj
)
966 ASF_DUMP ("ASF_HEADER_EXTENSION\n");
967 ASF_DUMP ("\tid = %s\n", asf_guid_tostring (&obj
->id
));
968 ASF_DUMP ("\tsize = %" G_GUINT64_FORMAT
"\n", obj
->size
);
969 ASF_DUMP ("\treserved1 = %s\n", asf_guid_tostring (&obj
->reserved1
));
970 ASF_DUMP ("\treserved2 = %u\n", (asf_dword
) obj
->reserved2
);
971 ASF_DUMP ("\tdata_size = %u\n", (asf_dword
) obj
->data_size
);
973 asf_dword count
= obj
->get_object_count ();
974 asf_object
** objects
= obj
->get_objects ();
976 for (asf_dword i
= 0; i
< count
; i
++) {
977 ASF_DUMP ("\n\textended object #%d:\n", i
);
978 asf_object_dump_exact (objects
[i
]);
984 bool asf_extended_stream_properties_validate (const asf_extended_stream_properties
* obj
, ASFParser
* parser
)
986 if (!(asf_guid_validate (&obj
->id
, &asf_guids_extended_stream_properties
, parser
))) {
990 if (obj
->size
< 88) {
991 parser
->AddError (g_strdup_printf ("Invalid size (expected >= 112, got %" G_GUINT64_FORMAT
").", obj
->size
));
995 if (obj
->data_bitrate
== 0) {
996 parser
->AddError (g_strdup_printf ("Invalid bitrate (expected != 0)."));
1000 if (obj
->initial_buffer_fullness
> obj
->buffer_size
) {
1001 parser
->AddError (g_strdup_printf ("Invalid initial buffer fullness (expected <= buffer size (%i), got %i).", obj
->buffer_size
, obj
->initial_buffer_fullness
));
1005 if (obj
->alternate_initial_buffer_fullness
> obj
->alternate_buffer_size
) {
1006 parser
->AddError (g_strdup_printf ("Invalid alternate initial buffer fullness (expected <= alternate buffer size (%i), got %i).", obj
->alternate_buffer_size
, obj
->alternate_initial_buffer_fullness
));
1010 if (obj
->stream_id
== 0 || obj
->stream_id
> 127) {
1011 parser
->AddError (g_strdup_printf ("Invalid stream number, must be 0 < stream number <= 127, got %i.", obj
->stream_id
));
1015 guint64 max_size
= obj
->size
;
1016 guint64 stream_names_length
= 0; // accumulated length of stream names
1017 guint64 payload_ex_sys_length
= 0; // accumulated length of payload extension systems
1018 guint64 size
= 88; // size of all the fixed fields
1020 for (gint32 i
= 0; i
< obj
->stream_name_count
; i
++) {
1021 if (size
+ 4 > max_size
) { // 4 = minimum size of stream name
1022 parser
->AddError (g_strdup_printf ("Invalid stream name count."));
1025 gint16 length
= 4 + *(gint16
*) (((char *) obj
) + 88 + stream_names_length
+ 2 /* offset into length */);
1027 stream_names_length
+= length
;
1028 if (size
> max_size
) {
1029 parser
->AddError (g_strdup_printf ("Invalid stream name."));
1034 for (gint32 i
= 0; i
< obj
->payload_extension_system_count
; i
++) {
1035 if (size
+ 22 > max_size
) { // 22 = minimum size of payload extension system
1036 parser
->AddError (g_strdup_printf ("Invalid payload extension system count."));
1039 guint32 length
= 22 + *(guint32
*) (((char *) obj
) + 88 + stream_names_length
+ payload_ex_sys_length
+ 18 /* offset into length */);
1040 if (length
> max_size
) { // Sanity check length before doing algorithm with it to avoid overflows.
1041 parser
->AddError (g_strdup_printf ("Invalid payload extension system."));
1045 payload_ex_sys_length
+= length
;
1046 if (size
> max_size
) {
1047 parser
->AddError (g_strdup_printf ("Invalid payload extension system."));
1055 void asf_extended_stream_properties_dump (const asf_extended_stream_properties
* obj
)
1058 ASF_DUMP ("ASF_EXTENDED_STREAM_PROPERTIES\n");
1059 ASF_DUMP ("\tid = %s\n", asf_guid_tostring (&obj
->id
));
1060 ASF_DUMP ("\tsize = %" G_GUINT64_FORMAT
"\n", obj
->size
);
1061 ASF_DUMP ("\tstart_time = %" G_GUINT64_FORMAT
"\n", obj
->start_time
);
1062 ASF_DUMP ("\tend_time = %" G_GUINT64_FORMAT
"\n", obj
->end_time
);
1063 ASF_DUMP ("\tdata_bitrate = %u\n", (asf_dword
) obj
->data_bitrate
);
1064 ASF_DUMP ("\tbuffer_size = %u\n", (asf_dword
) obj
->buffer_size
);
1065 ASF_DUMP ("\tinitial_buffer_fullness = %u\n", (asf_dword
) obj
->initial_buffer_fullness
);
1066 ASF_DUMP ("\talternate_data_bitrate = %u\n", (asf_dword
) obj
->alternate_data_bitrate
);
1067 ASF_DUMP ("\talternate_buffer_size = %u\n", (asf_dword
) obj
->alternate_buffer_size
);
1068 ASF_DUMP ("\talternate_initial_buffer_fullness = %u\n", (asf_dword
) obj
->alternate_initial_buffer_fullness
);
1069 ASF_DUMP ("\tmaximum_object_size = %u\n", (asf_dword
) obj
->maximum_object_size
);
1070 ASF_DUMP ("\tflags = %u\n", (asf_dword
) obj
->flags
);
1071 ASF_DUMP ("\tstream_id = %u\n", (asf_dword
) obj
->stream_id
);
1072 ASF_DUMP ("\tstream_language_id_index = %u\n", (asf_dword
) obj
->stream_language_id_index
);
1073 ASF_DUMP ("\taverage_time_per_frame = %" G_GUINT64_FORMAT
"\n", obj
->average_time_per_frame
);
1074 ASF_DUMP ("\tstream_name_count = %u\n", (asf_dword
) obj
->stream_name_count
);
1075 ASF_DUMP ("\tpayload_extension_system_count = %u\n", (asf_dword
) obj
->payload_extension_system_count
);
1077 asf_extended_stream_name
**names
= obj
->get_stream_names ();
1078 ASF_DUMP ("\tstream_names: %p\n", names
);
1079 if (names
!= NULL
) {
1080 for (int i
= 0; names
[i
] != NULL
; i
++)
1081 asf_extended_stream_name_dump (names
[i
]);
1085 asf_payload_extension_system
**systems
= obj
->get_payload_extension_systems ();
1086 ASF_DUMP ("\tpayload_extension_systems: %p\n", systems
);
1087 if (systems
!= NULL
) {
1088 for (int i
= 0; systems
[i
] != NULL
; i
++)
1089 asf_payload_extension_system_dump (systems
[i
]);
1093 const asf_stream_properties
*asp
= obj
->get_stream_properties ();
1094 ASF_DUMP ("\tasf_stream_properties = %p\n", asp
);
1096 asf_stream_properties_dump (asp
);
1100 void asf_extended_stream_name_dump (const asf_extended_stream_name
* obj
)
1102 ASF_DUMP ("ASF_EXTENDED_STREAM_NAME\n");
1103 ASF_DUMP ("\tlanguage_id_index = %i\n", (int) obj
->language_id_index
);
1104 ASF_DUMP ("\tstream_name_length = %i\n", (int) obj
->stream_name_length
);
1105 ASF_DUMP ("\tstream_name = %s\n", obj
->get_stream_name ());
1108 void asf_payload_extension_system_dump (const asf_payload_extension_system
* obj
)
1110 ASF_DUMP ("ASF_PAYLOAD_EXTENSION_SYSTEM\n");
1111 ASF_DUMP ("\textension_system_id = %s\n", asf_guid_tostring (&obj
->extension_system_id
));
1112 ASF_DUMP ("\textension_data_size = %i\n", (int) obj
->extension_data_size
);