diff options
author | Konstantin Andreyev <kandreyev@bcsii.com> | 2004-03-05 22:10:50 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2004-03-05 22:10:50 +0000 |
commit | 615b92fd8eb1a67acfa1799f5ba3f50cd8aac688 (patch) | |
tree | cef6a20687972e372edcf73a8e2111b1611fc1d1 | |
parent | 542993b06e5c9b3010da72be7e390006eb01a50e (diff) | |
download | ffmpeg-615b92fd8eb1a67acfa1799f5ba3f50cd8aac688.tar.gz |
asf patch by (Konstantin Andreyev <kandreyev at bcsii dot com>)
1. Corrected packet sent time. (Packet sent time => previous packet sent
time)
2. Corrected payload playing time. (Payload playing time => packet sent
time)
3. Used different format for packets with one payload and multi payloads.
Originally committed as revision 2851 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavformat/asf-enc.c | 374 | ||||
-rw-r--r-- | libavformat/asf.c | 3 | ||||
-rw-r--r-- | libavformat/asf.h | 72 | ||||
-rw-r--r-- | tests/libav.regression.ref | 4 |
4 files changed, 373 insertions, 80 deletions
diff --git a/libavformat/asf-enc.c b/libavformat/asf-enc.c index 9df604bf8c..cd8f803b91 100644 --- a/libavformat/asf-enc.c +++ b/libavformat/asf-enc.c @@ -24,6 +24,167 @@ #include <assert.h> #ifdef CONFIG_ENCODERS + +#define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2 +#define ASF_PACKET_ERROR_CORRECTION_FLAGS (\ + ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT | \ + ASF_PACKET_ERROR_CORRECTION_DATA_SIZE\ + ) + +#if (ASF_PACKET_ERROR_CORRECTION_FLAGS != 0) +# define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 1 +#else +# define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 0 +#endif + +#define ASF_PPI_PROPERTY_FLAGS (\ + ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE | \ + ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD | \ + ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE | \ + ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE \ + ) + +#define ASF_PPI_LENGTH_TYPE_FLAGS 0 + +#define ASF_PAYLOAD_FLAGS ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD + +#if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE)) +# define ASF_PPI_SEQUENCE_FIELD_SIZE 1 +#endif +#if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE)) +# define ASF_PPI_SEQUENCE_FIELD_SIZE 2 +#endif +#if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE)) +# define ASF_PPI_SEQUENCE_FIELD_SIZE 4 +#endif +#ifndef ASF_PPI_SEQUENCE_FIELD_SIZE +# define ASF_PPI_SEQUENCE_FIELD_SIZE 0 +#endif + + +#if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE)) +# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 1 +#endif +#if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE)) +# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 2 +#endif +#if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE)) +# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 4 +#endif +#ifndef ASF_PPI_PACKET_LENGTH_FIELD_SIZE +# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 0 +#endif + +#if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE)) +# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 1 +#endif +#if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE)) +# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 2 +#endif +#if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE)) +# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 4 +#endif +#ifndef ASF_PPI_PADDING_LENGTH_FIELD_SIZE +# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 0 +#endif + +#if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 1 +#endif +#if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 2 +#endif +#if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 4 +#endif +#ifndef ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE +# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 0 +#endif + +#if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 1 +#endif +#if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 2 +#endif +#if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 4 +#endif +#ifndef ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE +# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 0 +#endif + +#if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 1 +#endif +#if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 2 +#endif +#if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 4 +#endif +#ifndef ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE +# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 0 +#endif + +#if (ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_BYTE == (ASF_PAYLOAD_FLAGS & ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_LENGTH_FIELD_SIZE 1 +#endif +#if (ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD == (ASF_PAYLOAD_FLAGS & ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE)) +# define ASF_PAYLOAD_LENGTH_FIELD_SIZE 2 +#endif +#ifndef ASF_PAYLOAD_LENGTH_FIELD_SIZE +# define ASF_PAYLOAD_LENGTH_FIELD_SIZE 0 +#endif + +#define PACKET_HEADER_MIN_SIZE (\ + ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE + \ + ASF_PACKET_ERROR_CORRECTION_DATA_SIZE + \ + 1 + /*Length Type Flags*/ \ + 1 + /*Property Flags*/ \ + ASF_PPI_PACKET_LENGTH_FIELD_SIZE + \ + ASF_PPI_SEQUENCE_FIELD_SIZE + \ + ASF_PPI_PADDING_LENGTH_FIELD_SIZE + \ + 4 + /*Send Time Field*/ \ + 2 /*Duration Field*/ \ + ) + + +// Replicated Data shall be at least 8 bytes long. +#define ASF_PAYLOAD_REPLICATED_DATA_LENGTH 0x08 + +#define PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD (\ + 1 + /*Stream Number*/ \ + ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \ + ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \ + ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \ + ASF_PAYLOAD_REPLICATED_DATA_LENGTH \ + ) + +#define PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS (\ + 1 + /*Stream Number*/ \ + ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \ + ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \ + ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \ + ASF_PAYLOAD_REPLICATED_DATA_LENGTH + \ + ASF_PAYLOAD_LENGTH_FIELD_SIZE \ + ) + +#define SINGLE_PAYLOAD_DATA_LENGTH (\ + PACKET_SIZE - \ + PACKET_HEADER_MIN_SIZE - \ + PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD \ + ) + +#define MULTI_PAYLOAD_CONSTANT (\ + PACKET_SIZE - \ + PACKET_HEADER_MIN_SIZE - \ + 1 - /*Payload Flags*/ \ + 2*PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS \ + ) + +static int preroll_time = 2000; + static void put_guid(ByteIOContext *s, const GUID *g) { int i; @@ -90,10 +251,10 @@ static void put_chunk(AVFormatContext *s, int type, int payload_length, int flag length = payload_length + 8; put_le16(pb, type); - put_le16(pb, length); - put_le32(pb, asf->seqno); + put_le16(pb, length); //size + put_le32(pb, asf->seqno);//sequence number put_le16(pb, flags); /* unknown bytes */ - put_le16(pb, length); + put_le16(pb, length); //size_confirm asf->seqno++; } @@ -320,10 +481,10 @@ static int asf_write_header(AVFormatContext *s) put_flush_packet(&s->pb); - asf->packet_nb_frames = 0; + asf->packet_nb_payloads = 0; + asf->prev_packet_sent_time = 0; asf->packet_timestamp_start = -1; asf->packet_timestamp_end = -1; - asf->packet_size_left = asf->packet_size - PACKET_HEADER_SIZE; init_put_byte(&asf->pb, asf->packet_buf, asf->packet_size, 1, NULL, NULL, NULL, NULL); @@ -339,125 +500,192 @@ static int asf_write_stream_header(AVFormatContext *s) return asf_write_header(s); } -/* write a fixed size packet */ -static int put_packet(AVFormatContext *s, - unsigned int timestamp, unsigned int duration, - int nb_frames, int padsize) +static int put_payload_parsing_info( + AVFormatContext *s, + unsigned int sendtime, + unsigned int duration, + int nb_payloads, + int padsize + ) { ASFContext *asf = s->priv_data; ByteIOContext *pb = &s->pb; - int flags; - - if (asf->is_streamed) { - put_chunk(s, 0x4424, asf->packet_size, 0); + int ppi_size, i; + unsigned char *start_ppi_ptr = pb->buf_ptr; + + int iLengthTypeFlags = ASF_PPI_LENGTH_TYPE_FLAGS; + + put_byte(pb, ASF_PACKET_ERROR_CORRECTION_FLAGS); + for (i = 0; i < ASF_PACKET_ERROR_CORRECTION_DATA_SIZE; i++){ + put_byte(pb, 0x0); } - put_byte(pb, 0x82); - put_le16(pb, 0); + if (asf->multi_payloads_present) + iLengthTypeFlags |= ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT; - flags = 0x01; /* nb segments present */ if (padsize > 0) { if (padsize < 256) - flags |= 0x08; + iLengthTypeFlags |= ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE; else - flags |= 0x10; + iLengthTypeFlags |= ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD; } - put_byte(pb, flags); /* flags */ - put_byte(pb, 0x5d); - if (flags & 0x10) + put_byte(pb, iLengthTypeFlags); + + put_byte(pb, ASF_PPI_PROPERTY_FLAGS); + + if (iLengthTypeFlags & ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD) put_le16(pb, padsize - 2); - if (flags & 0x08) + if (iLengthTypeFlags & ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE) put_byte(pb, padsize - 1); - put_le32(pb, timestamp); + + put_le32(pb, sendtime); put_le16(pb, duration); - put_byte(pb, nb_frames | 0x80); + if (asf->multi_payloads_present) + put_byte(pb, nb_payloads | ASF_PAYLOAD_FLAGS); + + ppi_size = pb->buf_ptr - start_ppi_ptr; - return PACKET_HEADER_SIZE + ((flags & 0x18) >> 3); + return ppi_size; } static void flush_packet(AVFormatContext *s) { ASFContext *asf = s->priv_data; - int hdr_size, ptr; + int packet_hdr_size, packet_filled_size; + + if (asf->is_streamed) { + put_chunk(s, 0x4424, asf->packet_size, 0); + } - hdr_size = put_packet(s, asf->packet_timestamp_start, - asf->packet_timestamp_end - asf->packet_timestamp_start, - asf->packet_nb_frames, asf->packet_size_left); + packet_hdr_size = put_payload_parsing_info( + s, + asf->packet_timestamp_start, + asf->packet_timestamp_end - asf->packet_timestamp_start, + asf->packet_nb_payloads, + asf->packet_size_left + ); - /* Clear out the padding bytes */ - ptr = asf->packet_size - hdr_size - asf->packet_size_left; - memset(asf->packet_buf + ptr, 0, asf->packet_size_left); + packet_filled_size = PACKET_SIZE - packet_hdr_size - asf->packet_size_left; + memset(asf->packet_buf + packet_filled_size, 0, asf->packet_size_left); - put_buffer(&s->pb, asf->packet_buf, asf->packet_size - hdr_size); + put_buffer(&s->pb, asf->packet_buf, asf->packet_size - packet_hdr_size); put_flush_packet(&s->pb); asf->nb_packets++; - asf->packet_nb_frames = 0; + asf->packet_nb_payloads = 0; + asf->prev_packet_sent_time = asf->packet_timestamp_start; asf->packet_timestamp_start = -1; asf->packet_timestamp_end = -1; - asf->packet_size_left = asf->packet_size - PACKET_HEADER_SIZE; init_put_byte(&asf->pb, asf->packet_buf, asf->packet_size, 1, NULL, NULL, NULL, NULL); } -static void put_frame_header(AVFormatContext *s, ASFStream *stream, int timestamp, - int payload_size, int frag_offset, int frag_len) +static void put_payload_header( + AVFormatContext *s, + ASFStream *stream, + int presentation_time, + int m_obj_size, + int m_obj_offset, + int payload_len + ) { ASFContext *asf = s->priv_data; ByteIOContext *pb = &asf->pb; int val; - + val = stream->num; - if (s->streams[val - 1]->codec.coded_frame->key_frame /* && frag_offset == 0 */) - val |= 0x80; + if (s->streams[val - 1]->codec.coded_frame->key_frame) + val |= ASF_PL_FLAG_KEY_FRAME; put_byte(pb, val); - put_byte(pb, stream->seq); - put_le32(pb, frag_offset); /* fragment offset */ - put_byte(pb, 0x08); /* flags */ - put_le32(pb, payload_size); - put_le32(pb, timestamp); - put_le16(pb, frag_len); + + put_byte(pb, stream->seq); //Media object number + put_le32(pb, m_obj_offset); //Offset Into Media Object + + // Replicated Data shall be at least 8 bytes long. + // The first 4 bytes of data shall contain the + // Size of the Media Object that the payload belongs to. + // The next 4 bytes of data shall contain the + // Presentation Time for the media object that the payload belongs to. + put_byte(pb, ASF_PAYLOAD_REPLICATED_DATA_LENGTH); + + put_le32(pb, m_obj_size); //Replicated Data - Media Object Size + put_le32(pb, presentation_time);//Replicated Data - Presentation Time + + if (asf->multi_payloads_present){ + put_le16(pb, payload_len); //payload length + } } - -/* Output a frame. We suppose that payload_size <= PACKET_SIZE. - - It is there that you understand that the ASF format is really - crap. They have misread the MPEG Systems spec ! - */ -static void put_frame(AVFormatContext *s, ASFStream *stream, int timestamp, - const uint8_t *buf, int payload_size) +static void put_frame( + AVFormatContext *s, + ASFStream *stream, + int timestamp, + const uint8_t *buf, + int m_obj_size + ) { ASFContext *asf = s->priv_data; - int frag_pos, frag_len, frag_len1; + int m_obj_offset, payload_len, frag_len1; + + m_obj_offset = 0; + while (m_obj_offset < m_obj_size) { + payload_len = m_obj_size - m_obj_offset; + if (asf->packet_timestamp_start == -1) { + asf->multi_payloads_present = (payload_len < MULTI_PAYLOAD_CONSTANT); + + if (asf->multi_payloads_present){ + asf->packet_size_left = PACKET_SIZE; //For debug + asf->packet_size_left = PACKET_SIZE - PACKET_HEADER_MIN_SIZE - 1; + frag_len1 = MULTI_PAYLOAD_CONSTANT - 1; + } + else { + asf->packet_size_left = PACKET_SIZE - PACKET_HEADER_MIN_SIZE; + frag_len1 = SINGLE_PAYLOAD_DATA_LENGTH; + } + if (asf->prev_packet_sent_time > timestamp) + asf->packet_timestamp_start = asf->prev_packet_sent_time; + else + asf->packet_timestamp_start = timestamp; + } + else { + // multi payloads + frag_len1 = asf->packet_size_left - PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS; - frag_pos = 0; - while (frag_pos < payload_size) { - frag_len = payload_size - frag_pos; - frag_len1 = asf->packet_size_left - FRAME_HEADER_SIZE; + if (asf->prev_packet_sent_time > timestamp) + asf->packet_timestamp_start = asf->prev_packet_sent_time; + else if (asf->packet_timestamp_start >= timestamp) + asf->packet_timestamp_start = timestamp; + } if (frag_len1 > 0) { - if (frag_len > frag_len1) - frag_len = frag_len1; - put_frame_header(s, stream, timestamp+1, payload_size, frag_pos, frag_len); - put_buffer(&asf->pb, buf, frag_len); - asf->packet_size_left -= (frag_len + FRAME_HEADER_SIZE); + if (payload_len > frag_len1) + payload_len = frag_len1; + else if (payload_len == (frag_len1 - 1)) + payload_len = frag_len1 - 2; //additional byte need to put padding length + + put_payload_header(s, stream, timestamp+preroll_time, m_obj_size, m_obj_offset, payload_len); + put_buffer(&asf->pb, buf, payload_len); + + if (asf->multi_payloads_present) + asf->packet_size_left -= (payload_len + PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS); + else + asf->packet_size_left -= (payload_len + PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD); asf->packet_timestamp_end = timestamp; - if (asf->packet_timestamp_start == -1) - asf->packet_timestamp_start = timestamp; - asf->packet_nb_frames++; + + asf->packet_nb_payloads++; } else { - frag_len = 0; + payload_len = 0; } - frag_pos += frag_len; - buf += frag_len; - /* output the frame if filled */ - if (asf->packet_size_left <= FRAME_HEADER_SIZE) + m_obj_offset += payload_len; + buf += payload_len; + + if (!asf->multi_payloads_present) + flush_packet(s); + else if (asf->packet_size_left <= (PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS + 1)) flush_packet(s); } stream->seq++; } - static int asf_write_packet(AVFormatContext *s, int stream_index, const uint8_t *buf, int size, int64_t timestamp) { diff --git a/libavformat/asf.c b/libavformat/asf.c index ab80eb4d36..19542e5a0c 100644 --- a/libavformat/asf.c +++ b/libavformat/asf.c @@ -24,6 +24,9 @@ #undef NDEBUG #include <assert.h> +#define FRAME_HEADER_SIZE 17 +// Fix Me! FRAME_HEADER_SIZE may be different. + static const GUID index_guid = { 0x33000890, 0xe5b1, 0x11cf, { 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb }, }; diff --git a/libavformat/asf.h b/libavformat/asf.h index c0090af783..f66c25b9dc 100644 --- a/libavformat/asf.h +++ b/libavformat/asf.h @@ -16,12 +16,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define PACKET_SIZE 3200 -#define PACKET_HEADER_SIZE 12 -#define FRAME_HEADER_SIZE 17 typedef struct { int num; - int seq; + unsigned char seq; /* use for reading */ AVPacket pkt; int frag_offset; @@ -74,8 +72,8 @@ typedef struct { typedef struct { - int seqno; - int packet_size; + uint32_t seqno; + unsigned int packet_size; int is_streamed; int asfid2avid[128]; /* conversion table from asf ID 2 AVStream ID */ ASFStream streams[128]; /* it's max number and it's not that big */ @@ -83,9 +81,12 @@ typedef struct { int64_t nb_packets; int64_t duration; /* in 100ns units */ /* packet filling */ + unsigned char multi_payloads_present; int packet_size_left; + int prev_packet_sent_time; int packet_timestamp_start; int packet_timestamp_end; + unsigned int packet_nb_payloads; int packet_nb_frames; uint8_t packet_buf[PACKET_SIZE]; ByteIOContext pb; @@ -179,3 +180,64 @@ static const GUID extended_content_header = { static const GUID my_guid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, }; + +#define ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT 0x80 //1000 0000 + + +// ASF data packet structure +// ========================= +// +// +// ----------------------------------- +// | Error Correction Data | Optional +// ----------------------------------- +// | Payload Parsing Information (PPI) | +// ----------------------------------- +// | Payload Data | +// ----------------------------------- +// | Padding Data | +// ----------------------------------- + + +// PPI_FLAG - Payload parsing information flags +#define ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT 1 + +#define ASF_PPI_FLAG_SEQUENCE_FIELD_IS_BYTE 0x02 //0000 0010 +#define ASF_PPI_FLAG_SEQUENCE_FIELD_IS_WORD 0x04 //0000 0100 +#define ASF_PPI_FLAG_SEQUENCE_FIELD_IS_DWORD 0x06 //0000 0110 +#define ASF_PPI_MASK_SEQUENCE_FIELD_SIZE 0x06 //0000 0110 + +#define ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE 0x08 //0000 1000 +#define ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD 0x10 //0001 0000 +#define ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_DWORD 0x18 //0001 1000 +#define ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE 0x18 //0001 1000 + +#define ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_BYTE 0x20 //0010 0000 +#define ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_WORD 0x40 //0100 0000 +#define ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_DWORD 0x60 //0110 0000 +#define ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE 0x60 //0110 0000 + +// PL_FLAG - Payload flags +#define ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE 0x01 //0000 0001 +#define ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_WORD 0x02 //0000 0010 +#define ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_DWORD 0x03 //0000 0011 +#define ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE 0x03 //0000 0011 + +#define ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_BYTE 0x04 //0000 0100 +#define ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_WORD 0x08 //0000 1000 +#define ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD 0x0c //0000 1100 +#define ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE 0x0c //0000 1100 + +#define ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE 0x10 //0001 0000 +#define ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_WORD 0x20 //0010 0000 +#define ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_DWORD 0x30 //0011 0000 +#define ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE 0x30 //0011 0000 + +#define ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE 0x40 //0100 0000 +#define ASF_PL_MASK_STREAM_NUMBER_LENGTH_FIELD_SIZE 0xc0 //1100 0000 + +#define ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_BYTE 0x40 //0100 0000 +#define ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD 0x80 //1000 0000 +#define ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE 0xc0 //1100 0000 + +#define ASF_PL_FLAG_KEY_FRAME 0x80 //1000 0000 diff --git a/tests/libav.regression.ref b/tests/libav.regression.ref index f581f5cd85..cafa929333 100644 --- a/tests/libav.regression.ref +++ b/tests/libav.regression.ref @@ -1,8 +1,8 @@ ffmpeg regression test 3dc28f3e65addfcf907624805e92c34e *./data/b-libav.avi ./data/b-libav.avi CRC=a08a5739 -f34176ef4f8577c93d51d7c403c8776d *./data/b-libav.asf -./data/b-libav.asf CRC=d9682c23 +b096c8d8a022d69457fac6fcd6d008a1 *./data/b-libav.asf +./data/b-libav.asf CRC=525fdb22 59c71a1bef09beb4a4e6f203967d12de *./data/b-libav.rm a2ac19d68574d38e84138e0b06e609c2 *./data/b-libav.mpg ./data/b-libav.mpg CRC=b67a9677 |