Author: rolf
Date: 2007-10-19 15:02:14 -0400 (Fri, 19 Oct 2007)
New Revision: 87842
Modified:
trunk/moon/src/asf/ChangeLog
trunk/moon/src/asf/asf-ffmpeg.cpp
trunk/moon/src/asf/asf-ffmpeg.h
trunk/moon/src/asf/asf-structures.h
trunk/moon/src/asf/asf.cpp
trunk/moon/src/asf/asf.h
Log:
* asf-structures.h, asf.cpp, asf-ffmpeg.cpp, asf.h, asf-ffmpeg.h:
Today's work.
Modified: trunk/moon/src/asf/ChangeLog
===================================================================
--- trunk/moon/src/asf/ChangeLog 2007-10-19 18:17:33 UTC (rev 87841)
+++ trunk/moon/src/asf/ChangeLog 2007-10-19 19:02:14 UTC (rev 87842)
@@ -1,3 +1,8 @@
+2007-10-19 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
+
+ * asf-structures.h, asf.cpp, asf-ffmpeg.cpp, asf.h, asf-ffmpeg.h:
Today's
+ work.
+
2007-10-18 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
* asf-structures.h, asf-generated.cpp, asf.mdp, asf.cpp, asf.mds,
Modified: trunk/moon/src/asf/asf-ffmpeg.cpp
===================================================================
--- trunk/moon/src/asf/asf-ffmpeg.cpp 2007-10-19 18:17:33 UTC (rev 87841)
+++ trunk/moon/src/asf/asf-ffmpeg.cpp 2007-10-19 19:02:14 UTC (rev 87842)
@@ -192,7 +192,39 @@
MoonASFContext *context = (MoonASFContext*) s->priv_data;
FFMPEGParser* parser = context->parser;
FFMPEGPacket* packet = NULL;
+ ASFFrameReader* reader = parser->reader;
+ if (!reader->Advance ())
+ return -1;
+
+ AVPacket* pkt = new AVPacket ();
+
+ av_new_packet (pkt, reader->Size ());
+
+ pkt->pts = reader->Pts ();
+ pkt->dts = 0;
+ pkt->stream_index = parser->ConvertStreamIndex (reader->StreamNumber
());
+ pkt->pos = -1;
+ pkt->size = reader->Size ();
+ reader->Write (pkt->data);
+ if (reader->IsKeyFrame () || s->streams
[pkt->stream_index]->codec->codec_type == CODEC_TYPE_AUDIO) {
+ pkt->flags |= PKT_FLAG_KEY;
+ }
+
+ //AVPacket_dump (pkt, 1);
+
+ *av_packet = *pkt;
+
+ return 0;
+
+ //////////////
+
+#if 0
+
+ MoonASFContext *context = (MoonASFContext*) s->priv_data;
+ FFMPEGParser* parser = context->parser;
+ FFMPEGPacket* packet = NULL;
+
packet = (FFMPEGPacket*) parser->GetCurrentPacket ();
if (packet == NULL) {
@@ -215,6 +247,7 @@
if (!parser->ReadPacket (packet)) {
return -1;
}
+ parser->SetCurrentPacket (packet);
parser->packets_read++;
FFMPEG_LOG ("ffmpeg_asf_read_packet: Created new packet %p with
%i payloads.\n", packet, packet->GetPayloadCount ());
}
@@ -230,16 +263,16 @@
FFMPEG_LOG ("ffmpeg_asf_read_packet: Reading payload #%i/%i with size
%u.\n", current_payload, packet->GetPayloadCount (), payload_size);
- if (false && packet->current_payload == packet->GetPayloadCount ()) {
+ if (packet->current_payload == packet->GetPayloadCount ()) {
int64_t pos = parser->GetPacketOffset (parser->packets_read);
parser->source->Seek (pos, SEEK_SET);
-
+ parser->SetCurrentPacket (NULL);
if (parser->ReadPacket (new FFMPEGPacket ())) {
parser->packets_read++;
asf_single_payload* next_payload;
packet = (FFMPEGPacket*) parser->GetCurrentPacket ();
- next_payload = packet->GetPayload
(++packet->current_payload);
+ next_payload = packet->GetPayload
(packet->current_payload++);
if (next_payload != NULL &&
next_payload->media_object_number ==
payload->media_object_number &&
next_payload->stream_number ==
payload->stream_number) {
@@ -262,7 +295,7 @@
if (payload->is_key_frame || s->streams
[pkt->stream_index]->codec->codec_type == CODEC_TYPE_AUDIO) {
pkt->flags |= PKT_FLAG_KEY;
}
- printf ("pkt: %p, pkt->data: %p, payload_size: %i, next_data_size:
%i\n", pkt, pkt->data, payload_size, next_data_size);
+ //printf ("pkt: %p, pkt->data: %p, payload_size: %i, next_data_size:
%i\n", pkt, pkt->data, payload_size, next_data_size);
memcpy (pkt->data, payload->payload_data, payload_size);
if (next_data_size > 0) {
memcpy (pkt->data + payload_size, next_data, next_data_size);
@@ -270,13 +303,14 @@
}
//AVPacket_dump (pkt, 1);
- if (packet->current_payload == packet->GetPayloadCount ()) {
+ if (false && packet->current_payload == packet->GetPayloadCount ()) {
parser->FreeCurrentPacket ();
}
*av_packet = *pkt;
return 0;
+#endif
}
int ffmpeg_asf_read_close(AVFormatContext *s)
@@ -297,12 +331,10 @@
FFMPEG_LOG ("ffmpeg_asf_read_seek (%p, %i, %lld, %i).\n", s,
stream_index, pts, flags);
+ if (parser->reader->Seek (parser->ConvertFFMpegStreamIndex
(stream_index), pts))
+ return 0;
- printf ("FIXME: Seeking to the first packet. This will normally not be
correct.\n");
- parser->packets_read = 0;
- parser->FreeCurrentPacket ();
-
- return 0;
+ return -1;
}
int64_t ffmpeg_asf_read_pts(AVFormatContext *s, int ffmpeg_stream_index,
int64_t *start_pos, int64_t pos_limit)
@@ -352,29 +384,28 @@
bool is_audio_stream = parser->GetStream (stream_index)->is_audio ();
int64_t result = AV_NOPTS_VALUE;
- ASFPacket* old_packet = parser->GetCurrentPacket ();
- parser->SetCurrentPacket (NULL);
while (packet_offset > pos_limit) {
packet_offset += file_properties->min_packet_size;
packet_index++;
- if (!parser->ReadPacket ()) {
+
+ ASFPacket* packet = new ASFPacket ();
+ if (!parser->ReadPacket (packet)) {
FFMPEG_LOG ("ffmpeg_asf_read_pts: could not read packet
index %lld at position %lld.\n", packet_index, packet_offset);
+ delete packet;
return AV_NOPTS_VALUE;
}
- ASFPacket* packet = parser->GetCurrentPacket ();
-
if (!is_audio_stream && !packet->payloads->is_key_frame
(stream_index))
continue;
*start_pos = packet_offset;
result = packet->payloads->get_presentation_time (stream_index);
+
+ delete packet;
+
break;
}
- parser->FreeCurrentPacket ();
-
- parser->SetCurrentPacket (old_packet);
FFMPEG_LOG ("fmpeg_asf_read_pts: found pts (%lld) of packet index
%lld.\n", pts, packet_index);
@@ -789,4 +820,4 @@
FFMPEG_DUMP ("%sduration = %i\n", tabs, pkt->duration);
FFMPEG_DUMP ("%spos = %lld\n", tabs, pkt->pos);
-}
\ No newline at end of file
+}
Modified: trunk/moon/src/asf/asf-ffmpeg.h
===================================================================
--- trunk/moon/src/asf/asf-ffmpeg.h 2007-10-19 18:17:33 UTC (rev 87841)
+++ trunk/moon/src/asf/asf-ffmpeg.h 2007-10-19 19:02:14 UTC (rev 87842)
@@ -70,11 +70,13 @@
FFMPEGParser (const char* filename) : ASFParser (filename)
{
memset (ffmpeg_stream_indices, -1, 128);
- packets_read = 0;
+ reader = new ASFFrameReader (this);
}
virtual ~FFMPEGParser ()
{
+ delete reader;
+ reader = NULL;
}
void AddStreamIndex (gint32 ffmpeg_stream_index, gint32
asf_stream_index)
@@ -114,7 +116,7 @@
gint32 ffmpeg_stream_indices [128];
- int64_t packets_read;
+ ASFFrameReader* reader;
};
class FFMPEGSource : public ASFSource {
Modified: trunk/moon/src/asf/asf-structures.h
===================================================================
--- trunk/moon/src/asf/asf-structures.h 2007-10-19 18:17:33 UTC (rev 87841)
+++ trunk/moon/src/asf/asf-structures.h 2007-10-19 19:02:14 UTC (rev 87842)
@@ -192,12 +192,12 @@
bool FillInAll (ASFSource* source, asf_error_correction_data* ecd,
asf_payload_parsing_information ppi, asf_multiple_payloads* mp);
- asf_dword get_presentation_time ()
+ gint64 get_presentation_time ()
{
if (replicated_data_length >= 8) {
return * (((asf_dword*) replicated_data) + 1);
}
- return 0;
+ return -1;
}
asf_single_payload ()
@@ -312,6 +312,13 @@
}
return false;
}
+
+ asf_single_payload** steal_payloads ()
+ {
+ asf_single_payload** result = payloads;
+ payloads = NULL;
+ return result;
+ }
};
Modified: trunk/moon/src/asf/asf.cpp
===================================================================
--- trunk/moon/src/asf/asf.cpp 2007-10-19 18:17:33 UTC (rev 87841)
+++ trunk/moon/src/asf/asf.cpp 2007-10-19 19:02:14 UTC (rev 87842)
@@ -23,8 +23,9 @@
ASFParser* parser = new ASFParser (filename);
parser->ReadHeader ();
parser->ReadData ();
- while (parser->ReadPacket ()) {
- ASF_LOG ("One more packet read.\n");
+ ASFPacket* packet;
+ while ((packet = new ASFPacket ()) && parser->ReadPacket (packet)) {
+ delete packet;
}
delete parser;
}
@@ -51,7 +52,6 @@
packet_offset_end = 0;
header_objects = NULL;
last_error = NULL;
- current_packet = NULL;
file_properties = NULL;
memset (stream_properties, 0, sizeof (asf_stream_properties*) * 127);
@@ -74,8 +74,6 @@
g_free (header_objects);
header_objects = NULL;
-
- FreeCurrentPacket ();
}
asf_object*
@@ -113,44 +111,40 @@
}
bool
-ASFParser::ReadPacket ()
+ASFParser::ReadPacket (ASFPacket* packet, gint32 packet_index)
{
- return ASFParser::ReadPacket (new ASFPacket ());
+ ASF_LOG ("ASFParser::ReadPacket (%p, %i).\n", packet, packet_index);
+
+ if (packet_index >= 0) {
+ guint64 position = GetPacketOffset (packet_index);
+
+ if (position == 0 || !source->Seek (position, SEEK_SET))
+ return false;
+ }
+
+ return ASFParser::ReadPacket (packet);
}
bool
-ASFParser::ReadPacket (ASFPacket* next_packet)
+ASFParser::ReadPacket (ASFPacket* packet)
{
- ASF_LOG ("ASFParser::ReadPacket (%p), data: %p\n", next_packet, data);
+ ASF_LOG ("ASFParser::ReadPacket (%p): Reading packet at %lld (index:
%i) of %lld packets.\n", packet, source->Position (), GetPacketIndex
(source->Position ()), data->data_packet_count);
- if (!data && !ReadData ())
- return false;
-
- FreeCurrentPacket ();
-
- ASF_LOG ("ASFParser::ReadPacket (): Reading packet at %lld (index: %i)
of %lld packets.\n", source->Position (), GetPacketIndex (source->Position ()),
data->data_packet_count);
-
asf_error_correction_data ecd;
asf_payload_parsing_information ppi;
- int64_t start_position = source->Position ();
+ //int64_t start_position = source->Position ();
- //printf ("Current position: %llx (%lld)\n", source->Position (),
source->Position ());
-
if (!ecd.FillInAll (source))
return false;
- //asf_error_correction_data_dump (&ecd);
+ asf_error_correction_data_dump (&ecd);
- //printf ("Current position: %llx (%lld)\n", source->Position (),
source->Position ());
-
if (!ppi.FillInAll (source))
return false;
- //asf_payload_parsing_information_dump (&ppi);
+ asf_payload_parsing_information_dump (&ppi);
- //printf ("Current position: %llx (%lld)\n", source->Position (),
source->Position ());
-
asf_multiple_payloads* mp = new asf_multiple_payloads ();
if (ppi.is_multiple_payloads_present ()) {
ASF_LOG ("ASFParser::ReadPacket (), reading multiple
payloads.\n");
@@ -170,13 +164,11 @@
mp->payload_flags = 1; // 1 payload
}
//asf_multiple_payloads_dump (mp);
- next_packet->payloads = mp;
+ packet->payloads = mp;
- if (!source->Skip (ppi.padding_length))
- return false;
+// if (!source->Skip (ppi.padding_length))
+// return false;
- current_packet = next_packet;
-
ASF_LOG ("ASFParser::ReadPacket (): Current position (end of packet):
%llx (%lld), start position was: %llx (%lld), difference: %llx (%lld)\n",
source->Position (), source->Position (),
start_position, start_position,
@@ -254,6 +246,9 @@
ASF_LOG ("ASFParser::ReadHeader (): Header read successfully.\n");
+ if (!ReadData ())
+ return false;
+
return true;
}
@@ -404,7 +399,222 @@
}
}
+/*
+ ASFFrameReader
+*/
+ASFFrameReader::ASFFrameReader (ASFParser* p)
+{
+ parser = p;
+ first = NULL;
+ last = NULL;
+ size = 0;
+ is_key_frame = true;
+ pts = 0;
+ stream_number = 0;
+ payloads = NULL;
+ current_packet_index = CanSeek () ? 0 : -1;
+
+ // Most streams has at least once a media object spanning two payloads.
+ // so we allocate space for two (+ NULL at the end).
+ payloads_size = 2;
+ payloads = (asf_single_payload**) g_malloc0 (sizeof
(asf_single_payload*) * (payloads_size + 1));
+}
+ASFFrameReader::~ASFFrameReader ()
+{
+ parser = NULL;
+
+ RemoveAll ();
+
+ gint32 i = -1;
+ while (payloads [++i] != NULL)
+ delete payloads [i];
+ g_free (payloads); payloads = NULL;
+}
+bool
+ASFFrameReader::Seek (gint32 stream_number, guint64 pts)
+{
+ ASF_LOG ("ASFFrameReader::Seek (%i, %llu).\n", stream_number, pts);
+
+ if (!CanSeek ())
+ return false;
+
+ // Now this is an algorithm that needs some optimization.
+ // We seek from the first frame to the frame AFTER the one we want
(counting the numbers of frames)
+ // then we seek again from the first frame until the number of frames
counted - 1.
+
+ gint32 counter = 0;
+ bool found = true;
+
+ current_packet_index = 0;
+ RemoveAll ();
+
+ while (Advance ()) {
+ if (Pts () > pts) {
+ found = true;
+ break;
+ }
+ counter++;
+ }
+
+ if (!found)
+ return false;
+
+ current_packet_index = 0;
+ RemoveAll ();
+
+ while (counter-- > 0) {
+ if (!Advance ()) {
+ return false;
+ }
+ }
+
+ return true;
+}
+bool
+ASFFrameReader::Advance ()
+{
+ ASF_LOG ("ASFFrameReader::Advance ().\n");
+ // Clear the current list of payloads.
+ int i = -1;
+ while (payloads [++i] != NULL) {
+ delete payloads [i];
+ payloads [i] = NULL;
+ }
+
+ if (first == NULL) {
+ if (!ReadMore ())
+ return false;
+ if (first == NULL)
+ return false;
+ }
+ gint32 payload_count = 1;
+ payloads [0] = first->payload;
+ gint32 media_object_number = payloads [0]->media_object_number;
+ size = payloads [0]->payload_data_length;
+ is_key_frame = payloads [0]->is_key_frame;
+ pts = payloads [0]->get_presentation_time ();
+ stream_number = payloads [0]->stream_number;
+
+ ASF_LOG ("ASFFrameReader::Advance (): frame data: size = %lld, key =
%s, pts = %llu, stream# = %i.\n",
+ size, is_key_frame ? "true" : "false", pts, stream_number);
+
+ bool end = false;
+ ASFFrameReaderData *current = first->next;
+
+ Remove (first);
+
+ while (!end) {
+ // Loop through payloads until we find a payload with the same
stream number.
+ // if the media number is different, no more payloads in the
current frame,
+ // otherwise add the payload to the current frame's payloads
and continue looping.
+ while (current == NULL) {
+ // We went past the end, read another packet to get
more data.
+ current = last; // go back to the last element.
+ if (!ReadMore ()) {
+ end = true; // No more data, we've reached the
end
+ break;
+ } else {
+ if (current == NULL) {
+ // There was no elements before reading
more, our next element is the first one
+ current = first;
+ } else {
+ current = current->next;
+ }
+ }
+ }
+
+ if (end)
+ break;
+
+ if (current->payload->stream_number == stream_number) {
+ if (current->payload->media_object_number ==
media_object_number) {
+ // Add the payload to the current frame's
payloads
+ payload_count++;
+ size += current->payload->payload_data_length;
+ if (payload_count > payloads_size) {
+ gint32 new_size = payload_count + 3;
+ payloads = (asf_single_payload**)
g_realloc (payloads, sizeof (asf_single_payload*) * (new_size + 1));
+ memset (payloads + payloads_size, 0,
sizeof (asf_single_payload*) * (new_size - payloads_size));
+ payloads_size = new_size;
+ }
+ payloads [payload_count - 1] = current->payload;
+
+ // Remove it from the queue
+ ASFFrameReaderData* tmp = current;
+ current = current->prev;
+
+ tmp->payload = NULL;
+ Remove (tmp);
+ delete tmp;
+ } else {
+ // We've found the end of the current frame's
payloads
+ end = true;
+ }
+ }
+
+ if (current != NULL)
+ current = current->next;
+ }
+
+ return true;
+}
+
+bool
+ASFFrameReader::ReadMore ()
+{
+ ASFPacket* packet = new ASFPacket ();
+
+ ASF_LOG ("ASFFrameReader::ReadMore ().\n");
+
+ if (!parser->ReadPacket (packet, current_packet_index)) {
+ ASF_LOG ("ASFFrameReader::ReadMore (): could not read more
packets.\n");
+ delete packet;
+ return false;
+ }
+
+ if (CanSeek ()) {
+ current_packet_index++;
+ }
+
+ asf_single_payload** payloads = packet->payloads->steal_payloads ();
+ int i = -1;
+ while (payloads [++i] != NULL) {
+ // Append the payload at the end of the queue of payloads.
+ ASFFrameReaderData* node = new ASFFrameReaderData (payloads
[i]);
+
+ if (first == NULL) {
+ first = node;
+ last = node;
+ } else {
+ node->prev = last;
+ last->next = node;
+ last = node;
+ }
+ }
+
+ ASF_LOG ("ASFFrameReader::ReadMore (): read %i payloads.\n", i);
+
+ delete packet;
+ return true;
+}
+
+bool
+ASFFrameReader::Write (void* destination)
+{
+ if (payloads == NULL)
+ return false;
+
+ void* start = destination;
+ gint32 i = -1;
+ while (payloads [++i] != NULL) {
+ memcpy (destination, payloads [i]->payload_data, payloads
[i]->payload_data_length);
+ destination = payloads [i]->payload_data_length + (char*)
destination;
+ }
+
+ return true;
+}
+
Modified: trunk/moon/src/asf/asf.h
===================================================================
--- trunk/moon/src/asf/asf.h 2007-10-19 18:17:33 UTC (rev 87841)
+++ trunk/moon/src/asf/asf.h 2007-10-19 19:02:14 UTC (rev 87842)
@@ -142,11 +142,131 @@
return NULL;
}
+ // Gets the pts of the first payload.
+ int64_t GetPts (gint32 stream_number)
+ {
+ if (!payloads)
+ return -1;
+
+ asf_single_payload* first = GetFirstPayload (stream_number);
+ if (!first)
+ return -1;
+
+ return first->get_presentation_time ();
+ }
+
+ asf_single_payload* GetFirstPayload (gint32 stream_number)
+ {
+ if (!payloads)
+ return NULL;
+
+ int index = 0;
+ while (payloads->payloads [index] != NULL) {
+ if (payloads->payloads [index]->stream_number ==
stream_number)
+ return payloads->payloads [index];
+ index++;
+ }
+ return NULL;
+ }
+
asf_multiple_payloads* payloads;
- int64_t index;
+
+ gint32 index; // The index of this packet. -1 if not known.
+ gint64 position; // The position of this packet. -1 if not known.
};
+struct ASFFrameReaderData {
+ asf_single_payload* payload;
+ ASFFrameReaderData* prev;
+ ASFFrameReaderData* next;
+
+ ASFFrameReaderData (asf_single_payload* load)
+ {
+ payload = load;
+ prev = NULL;
+ next = NULL;
+ }
+
+ ~ASFFrameReaderData ()
+ {
+ delete payload;
+ }
+};
+
+class ASFFrameReader {
+public:
+ ASFFrameReader (ASFParser* parser);
+ virtual ~ASFFrameReader ();
+
+ // Can we seek?
+ bool CanSeek () { return true; }
+
+ // Seek to the frame with the provided pts
+ bool Seek (gint32 stream_number, guint64 pts);
+
+ // Advance to the next frame
+ bool Advance ();
+
+ // Write the frame's data to a the destination
+ bool Write (void* destination);
+
+ // Information about the current frame
+ guint64 Size () { return size; }
+ bool IsKeyFrame () { return is_key_frame; }
+ gint64 Pts () { return pts; }
+ gint32 StreamNumber () { return stream_number; }
+
+private:
+ ASFParser* parser;
+
+ gint32 current_packet_index;
+
+ // The queue of payloads we've built.
+ ASFFrameReaderData* first;
+ ASFFrameReaderData* last;
+
+ // A list of the payloads in the current frame
+ asf_single_payload** payloads;
+ gint32 payloads_size;
+
+ // Information about the current frame.
+ guint64 size;
+ bool is_key_frame;
+ gint64 pts;
+ gint32 stream_number;
+
+ // Reads another packet and fills data at the end
+ bool ReadMore ();
+
+ void RemoveAll ()
+ {
+ ASFFrameReaderData* current = first, *next = NULL;
+ while (current = NULL) {
+ next = current->next;
+ delete current;
+ current = next;
+ }
+ first = NULL;
+ last = NULL;
+ }
+
+ void Remove (ASFFrameReaderData* data)
+ {
+ if (data->prev != NULL)
+ data->prev->next = data->next;
+
+ if (data->next != NULL)
+ data->next->prev = data->prev;
+
+ if (data == first)
+ first = data->next;
+
+ if (data == last)
+ last = data->prev;
+ }
+};
+
class ASFParser {
public:
ASFParser (const char* filename);
@@ -154,26 +274,17 @@
bool ReadHeader ();
bool ReadData ();
- bool ReadPacket ();
+ // Reads the packet at the current position.
bool ReadPacket (ASFPacket* packet);
+ // Seeks to the packet index (as long as the packet index >= 0), then
reads it.
+ // If the packet index is < 0, then just read at the current position
+ bool ReadPacket (ASFPacket* packet, gint32 packet_index);
+
asf_object* ReadObject (asf_object* guid);
const char* GetLastError ();
void AddError (const char* err); // Makes a copy of the provided error
string.
void AddError (char* err); // Frees the provided error string.
- ASFSource* source;
-
- asf_header* header;
- int64_t data_offset; // location of data object
- int64_t packet_offset; // location of first packet
- int64_t packet_offset_end; // location of the end of the last packet
- asf_data* data;
- asf_file_properties* file_properties;
-
- asf_stream_properties* stream_properties [127];
-
- ASFPacket* current_packet;
-
// Stream index from 1 to 127
asf_stream_properties* GetStream (gint32 stream_index)
{
@@ -197,8 +308,14 @@
return GetStream (stream_index) != NULL;
}
- int64_t GetPacketOffset (int64_t packet_index)
+ // Returns 0 on failure, otherwise the offset of the packet index.
+ guint64 GetPacketOffset (gint32 packet_index)
{
+ if (packet_index < 0 || packet_index >=
file_properties->data_packet_count) {
+ AddError (g_strdup_printf ("ASFParser::GetPacketOffset
(%i): Invalid packet index (there are %llu packets).", packet_index,
file_properties->data_packet_count));
+ return 0;
+ }
+
return packet_offset + packet_index *
file_properties->min_packet_size;
}
@@ -211,22 +328,28 @@
return (offset - packet_offset) /
file_properties->min_packet_size;
}
- ASFPacket* GetCurrentPacket ()
+ // Returns the packet index where the desired pts is found.
+ // Returns -1 on failure.
+ gint32 GetPacketIndexOfPts (gint32 stream_number, gint64 pts)
{
- return current_packet;
+ int result = 0;
+ ASFPacket* packet = NULL;
+
+ // Read packets until we find the packet which has a pts
+ // greater than the one we're looking for.
+
+ while (ReadPacket (packet, result)) {
+ gint64 current_pts = packet->GetPts (stream_number);
+ if (current_pts < 0) // Can't read pts for some reason.
+ return -1;
+ if (current_pts > pts) // We've found the packet after
the one we're looking for
+ return result - 1; // return the previous one.
+ result++;
+ }
+
+ return -1;
}
- void SetCurrentPacket (ASFPacket* packet)
- {
- current_packet = packet;
- }
-
- void FreeCurrentPacket ()
- {
- delete current_packet;
- current_packet = NULL;
- }
-
asf_header* GetHeader ()
{
return header;
@@ -271,11 +394,22 @@
return NULL;
return header_objects [index];
}
+
+ ASFSource* source;
+ asf_object** header_objects;
+ asf_header* header;
+ asf_data* data;
+ asf_file_properties* file_properties;
-private:
- asf_object** header_objects;
- char* last_error;
+ asf_stream_properties* stream_properties [127];
+
+ guint64 data_offset; // location of data object
+ guint64 packet_offset; // location of the beginning of the first packet
+ guint64 packet_offset_end; // location of the end of the last packet
+
+
+ char* last_error;
};
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches