1/*
2 * Copyright (c) 2009, David McPaul
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 *  * Redistributions of source code must retain the above copyright notice,
9 *    this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright notice,
11 *    this list of conditions and the following disclaimer in the documentation
12 *    and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23 * OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "ASFIndex.h"
27
28#include <stdio.h>
29
30
31void
32IndexEntry::Clear()
33{
34	frameNo=0;
35	noPayloads=0;
36	dataSize=0;
37	pts=0;
38	keyFrame=false;
39}
40
41void
42IndexEntry::AddPayload(uint32 pdataSize)
43{
44	noPayloads++;
45	dataSize += pdataSize;
46}
47
48StreamEntry::StreamEntry()
49{
50	lastID = 0;
51	frameCount = 0;
52	maxPTS = 0;
53	duration = 0;
54}
55
56StreamEntry::~StreamEntry()
57{
58	index.clear();
59}
60
61void
62StreamEntry::setDuration(bigtime_t pduration)
63{
64	duration = pduration;
65}
66
67
68IndexEntry
69StreamEntry::GetIndex(uint32 frameNo)
70{
71	IndexEntry indexEntry;
72
73	for (std::vector<IndexEntry>::iterator itr = index.begin(); itr != index.end(); ++itr) {
74		if (itr->frameNo == frameNo) {
75			indexEntry = *itr;
76			break;
77		}
78	}
79	return indexEntry;
80}
81
82bool
83StreamEntry::HasIndex(uint32 frameNo)
84{
85	if (!index.empty()) {
86		for (std::vector<IndexEntry>::iterator itr = index.begin();	itr != index.end();	++itr) {
87 			if (itr->frameNo == frameNo) {
88 				return true;
89			}
90		}
91	}
92
93	return false;
94}
95
96IndexEntry
97StreamEntry::GetIndex(bigtime_t pts)
98{
99	IndexEntry indexEntry;
100
101	for (std::vector<IndexEntry>::iterator itr = index.begin(); itr != index.end(); ++itr) {
102		if (pts <= itr->pts) {
103			indexEntry = *itr;
104			break;
105		}
106	}
107	return indexEntry;
108}
109
110bool
111StreamEntry::HasIndex(bigtime_t pts)
112{
113	if (!index.empty()) {
114		for (std::vector<IndexEntry>::iterator itr = index.begin();	itr != index.end();	++itr) {
115 			if (pts <= itr->pts) {
116 				return true;
117			}
118		}
119	}
120
121	return false;
122}
123
124/*
125	Combine payloads with the same id into a single IndexEntry
126	When isLast flag is set then no more payloads are available (ie add current entry to index)
127
128*/
129void
130StreamEntry::AddPayload(uint32 id, bool keyFrame, bigtime_t pts, uint32 dataSize, bool isLast)
131{
132	if (isLast) {
133		maxPTS = indexEntry.pts;
134		if (frameCount > 0) {
135			index.push_back(indexEntry);
136//			printf("Stream %d added Index %ld PTS %Ld payloads %d\n",streamIndex, indexEntry.frameNo, indexEntry.pts, indexEntry.noPayloads);
137			printf("Stream Index Loaded for Stream %d Max Frame %ld Max PTS %Ld size %ld\n",streamIndex, frameCount-1, maxPTS, index.size());
138		}
139	} else {
140		if (id != lastID) {
141			if (frameCount != 0) {
142				// add indexEntry to Index
143				index.push_back(indexEntry);
144//				printf("Stream %d added Index %ld PTS %Ld payloads %d\n",streamIndex, indexEntry.frameNo, indexEntry.pts, indexEntry.noPayloads);
145			}
146			lastID = id;
147			indexEntry.Clear();
148
149			indexEntry.frameNo = frameCount++;
150			indexEntry.keyFrame = keyFrame;
151			indexEntry.pts = pts;
152			indexEntry.dataSize = dataSize;
153			indexEntry.noPayloads = 1;
154			indexEntry.id = id;
155		} else {
156			indexEntry.AddPayload(dataSize);
157		}
158	}
159}
160