gst_asf_mux_write_data_object (GstAsfMux * asfmux, guint8 ** buf)
{
gst_asf_put_guid (*buf, guids[ASF_DATA_OBJECT_INDEX]);
- GST_WRITE_UINT64_LE (*buf + 16, 0); /* object size - needs updating */
+
+ /* Data object size. This is always >= ASF_DATA_OBJECT_SIZE. The standard
+ * specifically accepts the value 0 in live streams, but WMP is not accepting
+ * this while streaming using WMSP, so we default to minimum size also for
+ * live streams. Otherwise this field must be updated later on when we know
+ * the complete stream size.
+ */
+ GST_WRITE_UINT64_LE (*buf + 16, ASF_DATA_OBJECT_SIZE);
+
gst_asf_put_guid (*buf + 24, asfmux->file_id);
GST_WRITE_UINT64_LE (*buf + 40, 0); /* total data packets */
GST_WRITE_UINT16_LE (*buf + 48, 0x0101); /* reserved */
*buf += ASF_DATA_OBJECT_SIZE;
}
+guint
+gst_asf_mux_find_payload_parsing_info_size (GstAsfMux * asfmux)
+{
+ /* Minimum payload parsing information size is 8 bytes */
+ guint size = 8;
+
+ if (asfmux->prop_packet_size > 65535)
+ size += 4;
+ else
+ size += 2;
+
+ if (asfmux->prop_padding > 65535)
+ size += 4;
+ else
+ size += 2;
+
+ return size;
+}
+
/**
* gst_asf_mux_start_file:
* @asfmux: #GstAsfMux
gboolean has_keyframe;
AsfPayload *payload;
guint32 payload_size;
+ guint offset;
if (asfmux->payloads == NULL)
return GST_FLOW_OK; /* nothing to send is ok */
memset (GST_BUFFER_DATA (buf), 0, asfmux->packet_size);
/* 1 for the multiple payload flags */
- data = GST_BUFFER_DATA (buf) + ASF_PAYLOAD_PARSING_INFO_SIZE + 1;
- size_left = asfmux->packet_size - ASF_PAYLOAD_PARSING_INFO_SIZE - 1;
+ data = GST_BUFFER_DATA (buf) + asfmux->payload_parsing_info_size + 1;
+ size_left = asfmux->packet_size - asfmux->payload_parsing_info_size - 1;
has_keyframe = FALSE;
walk = asfmux->payloads;
(ASF_FIELD_TYPE_DWORD << 3) | /* padding length type */
(ASF_FIELD_TYPE_NONE << 1) | /* sequence type type */
0x1); /* multiple payloads */
+ offset = 1;
/* property flags - according to the spec, this should not change */
- GST_WRITE_UINT8 (data + 1, (ASF_FIELD_TYPE_BYTE << 6) | /* stream number length type */
+ GST_WRITE_UINT8 (data + offset, (ASF_FIELD_TYPE_BYTE << 6) | /* stream number length type */
(ASF_FIELD_TYPE_BYTE << 4) | /* media obj number length type */
(ASF_FIELD_TYPE_DWORD << 2) | /* offset info media object length type */
(ASF_FIELD_TYPE_BYTE)); /* replicated data length type */
+ offset++;
- GST_WRITE_UINT32_LE (data + 2, asfmux->packet_size);
- GST_WRITE_UINT32_LE (data + 6, size_left); /* padding size */
+ /* Due to a limitation in WMP while streaming through WMSP we reduce the
+ * packet & padding size to 16bit if theay are <= 65535 bytes
+ */
+ if (asfmux->packet_size > 65535) {
+ GST_WRITE_UINT32_LE (data + offset, asfmux->packet_size - size_left);
+ offset += 4;
+ } else {
+ *data &= ~(ASF_FIELD_TYPE_MASK << 5);
+ *data |= ASF_FIELD_TYPE_WORD << 5;
+ GST_WRITE_UINT16_LE (data + offset, asfmux->packet_size - size_left);
+ offset += 2;
+ }
+ if (asfmux->prop_padding > 65535) {
+ GST_WRITE_UINT32_LE (data + offset, size_left);
+ offset += 4;
+ } else {
+ *data &= ~(ASF_FIELD_TYPE_MASK << 3);
+ *data |= ASF_FIELD_TYPE_WORD << 3;
+ GST_WRITE_UINT16_LE (data + offset, size_left);
+ offset += 2;
+ }
/* packet send time */
if (GST_CLOCK_TIME_IS_VALID (send_ts)) {
- GST_WRITE_UINT32_LE (data + 10, (send_ts / GST_MSECOND));
+ GST_WRITE_UINT32_LE (data + offset, (send_ts / GST_MSECOND));
GST_BUFFER_TIMESTAMP (buf) = send_ts;
}
+ offset += 4;
/* packet duration */
- GST_WRITE_UINT16_LE (data + 14, 0); /* FIXME send duration needs to be estimated */
+ GST_WRITE_UINT16_LE (data + offset, 0); /* FIXME send duration needs to be estimated */
+ offset += 2;
/* multiple payloads flags */
- GST_WRITE_UINT8 (data + 16, 0x2 << 6 | payloads_count);
+ GST_WRITE_UINT8 (data + offset, 0x2 << 6 | payloads_count);
if (payloads_count == 0) {
GST_WARNING_OBJECT (asfmux, "Sending packet without any payload");
GST_LOG_OBJECT (asfmux, "Payload data size: %" G_GUINT32_FORMAT,
asfmux->payload_data_size);
- while (asfmux->payload_data_size + ASF_PAYLOAD_PARSING_INFO_SIZE >=
+ while (asfmux->payload_data_size + asfmux->payload_parsing_info_size >=
asfmux->packet_size) {
GstFlowReturn ret = gst_asf_mux_flush_payloads (asfmux);
if (ret != GST_FLOW_OK)
case GST_STATE_CHANGE_READY_TO_PAUSED:
/* TODO - check if it is possible to mux 2 files without going
* through here */
+ asfmux->payload_parsing_info_size =
+ gst_asf_mux_find_payload_parsing_info_size (asfmux);
asfmux->packet_size = asfmux->prop_packet_size;
asfmux->preroll = asfmux->prop_preroll;
asfmux->merge_stream_tags = asfmux->prop_merge_stream_tags;