- Timestamp:
- 12/04/07 12:07:26 (1 year ago)
- Files:
-
- trunk/source/org/kolaka/freecast/lang/ArrayUtils.java (added)
- trunk/source/org/kolaka/freecast/ogg/OggPages.java (added)
- trunk/source/org/kolaka/freecast/ogg/OggStreamSource.java (modified) (12 diffs)
- trunk/source/org/kolaka/freecast/ogg/test/Dump.java (modified) (4 diffs)
- trunk/source/org/kolaka/freecast/ogg/test/OggStreamSourceTest.java (modified) (5 diffs)
- trunk/source/org/kolaka/freecast/ogg/test/resources/invalid-stream.ogg (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/source/org/kolaka/freecast/ogg/OggStreamSource.java
r725 r1155 2 2 * FreeCast - streaming over Internet 3 3 * 4 * This code was developped by Alban Peignier (http://people.tryphon.org/~alban/) 4 * This code was developped by Alban Peignier (http://people.tryphon.org/~alban/) 5 5 * and contributors (their names can be found in the CONTRIBUTORS file). 6 6 * … … 39 39 import org.apache.commons.lang.builder.ToStringBuilder; 40 40 import org.apache.commons.logging.LogFactory; 41 import org.kolaka.freecast.lang.ArrayUtils; 41 42 import org.kolaka.freecast.io.ReminderInputStream; 42 43 43 44 /** 44 * 45 * 45 * 46 * 46 47 * @author <a href="mailto:alban.peignier@free.fr">Alban Peignier </a> 47 48 */ … … 65 66 reminderInput)); 66 67 } 67 68 68 69 public String getDescription() { 69 70 return description; … … 77 78 78 79 private final byte[] capturePatternBuffer = new byte[4]; 79 80 80 81 private boolean beginOfStream = true; 81 82 82 83 public OggPage next() throws IOException { 83 84 dataInput.readFully(capturePatternBuffer, 0, 4); 84 85 85 86 if (!Arrays.equals(OggPage.CAPTURE_PATTERN, capturePatternBuffer)) { 86 LogFactory.getLog(getClass()).trace(createHexDump(capturePatternBuffer)); 87 throw createIOException("Missing capture pattern"); 87 LogFactory.getLog(getClass()).warn("invalid ogg stream"); 88 LogFactory.getLog(getClass()).trace(OggPages.createHexDump(capturePatternBuffer)); 89 90 findNextCapturePattern(); 88 91 } 89 92 … … 99 102 try { 100 103 int headerTypeFlag = dataInput.readUnsignedByte(); 101 104 102 105 page.setFirstPage((headerTypeFlag & 0x02) != 0); 103 106 page.setLastPage((headerTypeFlag & 0x04) != 0); … … 114 117 pageSize += dataInput.readUnsignedByte(); 115 118 } 116 119 117 120 LogFactory.getLog(getClass()).trace("payload size: " + pageSize); 118 121 119 122 byte payload[] = new byte[pageSize]; 120 123 dataInput.readFully(payload); … … 126 129 throw e; 127 130 } catch (IOException e) { 128 131 129 132 LogFactory.getLog(getClass()).error("io error while reading " + page); 130 133 lastPages.log(); … … 132 135 if (readData.length > 0) { 133 136 LogFactory.getLog(getClass()).trace("last bytes read"); 134 LogFactory.getLog(getClass()).trace( createHexDump(readData));137 LogFactory.getLog(getClass()).trace(OggPages.createHexDump(readData)); 135 138 } 136 139 throw e; 137 140 } 138 141 139 142 if (beginOfStream) { 140 143 if (!page.isFirstPage()) { … … 143 146 beginOfStream = false; 144 147 } 145 148 146 149 if (page.isLastPage()) { 147 150 beginOfStream = true; 148 151 } 149 152 150 LogFactory.getLog(getClass()).trace("returns " + page); 151 // LogFactory.getLog(getClass()).trace(createHexDump(page.getRawBytes())); 152 153 if (LogFactory.getLog(getClass()).isTraceEnabled()) { 154 LogFactory.getLog(getClass()).trace("returns " + page); 155 156 int capturePatternInPayload = 157 ArrayUtils.indexOf(page.getPayload(), OggPage.CAPTURE_PATTERN); 158 if (capturePatternInPayload > -1) { 159 LogFactory.getLog(getClass()).warn("capture pattern found into payload : 0x" + Integer.toHexString( capturePatternInPayload)); 160 LogFactory.getLog(getClass()).trace(OggPages.createHexDump(page.getPayload())); 161 } 162 } 163 153 164 lastPages.add(page); 154 165 155 166 return page; 156 167 } 168 169 private void findNextCapturePattern() throws IOException { 170 LogFactory.getLog(getClass()).info("try to find next valid Ogg page"); 171 172 final int searchLimit = 10 * 1024; 173 int searchLength = 0; 174 175 int patternIndex = 0; 176 byte[] pattern = OggPage.CAPTURE_PATTERN; 177 178 while (searchLength < searchLimit && patternIndex < pattern.length) { 179 int nextByte = dataInput.readUnsignedByte(); 180 181 if (nextByte == pattern[patternIndex]) { 182 patternIndex++; 183 } else { 184 patternIndex = 0; 185 } 186 searchLength++; 187 } 188 189 if (patternIndex < pattern.length) { 190 throw createIOException("Invalid Ogg stream"); 191 } 192 193 LogFactory.getLog(getClass()).info("next valid Ogg page found after " + searchLength + " bytes"); 194 } 157 195 158 196 /** … … 165 203 } 166 204 167 /**168 * @param buffer TODO169 * @return170 * @throws IOException171 */172 private String createHexDump(byte[] buffer) throws IOException {173 ByteArrayOutputStream output = new ByteArrayOutputStream();174 HexDump.dump(buffer, 0, output, 0);175 String hexdump = output.toString();176 output.close();177 return hexdump;178 }179 180 205 public void close() throws IOException { 181 206 dataInput.close(); 182 207 } 183 208 184 209 private final LastPages lastPages = new LastPages(); 185 210 186 211 class LastPages { 187 212 188 213 private final int remaindedPages = 5; 189 214 private final List pages = new LinkedList(); … … 202 227 LogFactory.getLog(getClass()).trace(page); 203 228 try { 204 LogFactory.getLog(getClass()).trace( createHexDump(page.getRawBytes()));229 LogFactory.getLog(getClass()).trace(OggPages.createHexDump(page)); 205 230 } catch (IOException e) { 206 231 LogFactory.getLog(getClass()).error("can't dump " + page); … … 208 233 } 209 234 } 210 211 212 235 236 237 213 238 } 214 239 trunk/source/org/kolaka/freecast/ogg/test/Dump.java
r405 r1155 2 2 * FreeCast - streaming over Internet 3 3 * 4 * This code was developped by Alban Peignier (http://people.tryphon.org/~alban/) 4 * This code was developped by Alban Peignier (http://people.tryphon.org/~alban/) 5 5 * and contributors (their names can be found in the CONTRIBUTORS file). 6 6 * … … 31 31 32 32 import org.kolaka.freecast.ogg.OggPage; 33 import org.kolaka.freecast.ogg.OggPages; 33 34 import org.kolaka.freecast.ogg.OggSource; 34 35 import org.kolaka.freecast.ogg.OggStreamSource; 35 36 36 37 /** 37 * 38 * 38 * 39 * 39 40 * @author <a href="mailto:alban.peignier@free.fr">Alban Peignier</a> 40 41 */ … … 47 48 Map absolutePositions = new TreeMap(); 48 49 49 for (int i = 0; i < 20; i++) { 50 int pageCount = 0; 51 52 while (true) { 50 53 OggPage page = source.next(); 51 54 52 writer.println("page " + i);55 writer.println("page " + pageCount); 53 56 writer.println("\tfirstpage: " + page.isFirstPage() 54 57 + "\tlastpage: " + page.isLastPage()); … … 68 71 .longValue())); 69 72 } 73 74 writer.println(); 75 writer.println(page); 76 writer.println(OggPages.createHexDump(page)); 77 70 78 absolutePositions.put(streamSerialNumberString, new Long( 71 79 absolutePosition)); 80 pageCount++; 81 writer.flush(); 72 82 } 73 writer.close();83 // writer.close(); 74 84 } 75 85 trunk/source/org/kolaka/freecast/ogg/test/OggStreamSourceTest.java
r884 r1155 2 2 * FreeCast - streaming over Internet 3 3 * 4 * This code was developped by Alban Peignier (http://people.tryphon.org/~alban/) 4 * This code was developped by Alban Peignier (http://people.tryphon.org/~alban/) 5 5 * and contributors (their names can be found in the CONTRIBUTORS file). 6 6 * … … 26 26 import java.io.IOException; 27 27 import java.io.InputStream; 28 import java.io.EOFException; 28 29 29 30 import junit.framework.TestCase; … … 33 34 34 35 /** 35 * 36 * 36 * 37 * 37 38 * @author <a href="mailto:alban.peignier@free.fr">Alban Peignier </a> 38 39 */ 39 40 public class OggStreamSourceTest extends TestCase { 40 41 41 public void testReadFile() throws IOException { 42 InputStream resource = OggTestResources.getResourceAsStream("sample.ogg"); 43 44 OggStreamSource oggSource = new OggStreamSource(resource); 42 public void testValidFile() throws IOException { 43 testStream("sample.ogg", 14); 44 } 45 46 public void testInvalidStream() throws IOException { 47 testStream("invalid-stream.ogg", 60); 48 } 49 50 51 private void testStream(String resourceName, int expectedPageCount) 52 throws IOException 53 { 54 OggStreamSource oggSource = new OggStreamSource(OggTestResources.getResourceAsStream(resourceName)); 45 55 46 56 OggPage firstPage = oggSource.next(); … … 50 60 OggPage page = firstPage; 51 61 while (!page.isLastPage()) { 52 page = oggSource.next(); 62 try { 63 page = oggSource.next(); 64 } catch (EOFException e) { 65 if (pageCount < expectedPageCount) { 66 throw e; 67 } 68 69 break; 70 } 71 53 72 assertFalse("page can't be first", page.isFirstPage()); 54 73 pageCount++; … … 56 75 57 76 oggSource.close(); 58 assertEquals( 14, pageCount);77 assertEquals(expectedPageCount, pageCount); 59 78 } 60 79 80 61 81 }
