001/* ----------------------------------------------------------------------------
002 * This file was automatically generated by SWIG (http://www.swig.org).
003 * Version 4.0.2
004 *
005 * Do not make changes to this file unless you know what you are doing--modify
006 * the SWIG interface file instead.
007 * ----------------------------------------------------------------------------- */
008
009package com.avpkit.core;
010import com.avpkit.ferry.*;
011/**
012 * A file (or network data source) that contains one or more {IStream}<br>
013 * objects of<br>
014 * audio and video data.<br>
015 * <p><br>
016 * Typical usage for reading looks like this:<br>
017 * <pre><br>
018 * IContainer container = IContainer.make();<br>
019 * <br>
020 * if (container.open("myfile.flv", IContainer.Type.READ, null) &lt;0)<br>
021 * &nbsp;&nbsp;throw new RuntimeException("failed to open");<br>
022 * <br>
023 * int numStreams = container.getNumStreams();<br>
024 * for(i = 0; i &lt; numStreams; i++) {<br>
025 * &nbsp;&nbsp;IStream stream = container.getStream(i);<br>
026 * &nbsp;&nbsp;...query IStream for stream information...<br>
027 * }<br>
028 * <br>
029 * IPacket packet = IPacket.make();<br>
030 * while(container.readNextPacket(packet) &gt;= 0)<br>
031 * {<br>
032 *   &nbsp;&nbsp;... Do something with the packet...<br>
033 * }<br>
034 * container.close();<br>
035 * </pre><br>
036 * <p><br>
037 * Typical usage for writing looks like this (makes an FLV file<br>
038 * with one audio track encoded as mp3 data):<br>
039 * </p><br>
040 * <pre><br>
041 * IContainer container = IContainer.make();<br>
042 * <br>
043 * if (container.open("myfile.flv", IContainer.Type.WRITE, null) &lt;0)<br>
044 * &nbsp;&nbsp;throw new RuntimeException("failed to open");<br>
045 * <br>
046 * IStream stream = container.addNewStream(0);<br>
047 * <br>
048 * IStreamCoder coder = stream.getStreamCoder();<br>
049 * <br>
050 * coder.setCodec(ICodec.ID.AV_CODEC_ID_MP3);<br>
051 * coder.setSampleRate(22050);<br>
052 * coder.setChannels(2);<br>
053 * coder.setBitRate(64000);<br>
054 * <br>
055 * if (coder.open()&lt;0) throw new RuntimeException("could not open coder");<br>
056 * <br>
057 * if (container.writeHeader() &lt; 0) throw new RuntimeException();<br>
058 * <br>
059 * IPacket packet = IPacket.make();<br>
060 * <br>
061 * while( ... have more data to process ... ) {<br>
062 * &nbsp;&nbsp;... Use the coder to encode audio data into packets<br>
063 * &nbsp;&nbsp;then assuming it generated an IPacket for you...<br>
064 * &nbsp;&nbsp;if (container.writePacket(packet)&lt;0)<br>
065 * &nbsp;&nbsp;&nbsp;&nbsp;throw new RuntimeException("could not write packet");<br>
066 * }<br>
067 * <br>
068 * if (container.writeTrailer() &lt;0) throw new RuntimeException();<br>
069 * <br>
070 * container.close();<br>
071 * </pre> 
072 */
073public class IContainer extends RefCounted implements com.avpkit.core.IConfigurable {
074  // JNIHelper.swg: Start generated code
075  // >>>>>>>>>>>>>>>>>>>>>>>>>>>
076  /**
077   * This method is only here to use some references and remove
078   * a Eclipse compiler warning.
079   */
080  @SuppressWarnings("unused")
081  private void noop()
082  {
083    IBuffer.make(null, 1);
084  }
085   
086  private volatile long swigCPtr;
087
088  /**
089   * Internal Only.
090   */
091  protected IContainer(long cPtr, boolean cMemoryOwn) {
092    super(AVPKitJNI.IContainer_SWIGUpcast(cPtr), cMemoryOwn);
093    swigCPtr = cPtr;
094  }
095  
096  /**
097   * Internal Only.
098   */
099  protected IContainer(long cPtr, boolean cMemoryOwn,
100      java.util.concurrent.atomic.AtomicLong ref)
101  {
102    super(AVPKitJNI.IContainer_SWIGUpcast(cPtr),
103     cMemoryOwn, ref);
104    swigCPtr = cPtr;
105  }
106    
107  /**
108   * Internal Only.  Not part of public API.
109   *
110   * Get the raw value of the native object that obj is proxying for.
111   *   
112   * @param obj The java proxy object for a native object.
113   * @return The raw pointer obj is proxying for.
114   */
115  public static long getCPtr(IContainer obj) {
116    if (obj == null) return 0;
117    return obj.getMyCPtr();
118  }
119
120  /**
121   * Internal Only.  Not part of public API.
122   *
123   * Get the raw value of the native object that we're proxying for.
124   *   
125   * @return The raw pointer we're proxying for.
126   */  
127  public long getMyCPtr() {
128    if (swigCPtr == 0) throw new IllegalStateException("underlying native object already deleted");
129    return swigCPtr;
130  }
131  
132  /**
133   * Create a new IContainer object that is actually referring to the
134   * exact same underlying native object.
135   *
136   * @return the new Java object.
137   */
138  @Override
139  public IContainer copyReference() {
140    if (swigCPtr == 0)
141      return null;
142    else
143      return new IContainer(swigCPtr, swigCMemOwn, getJavaRefCount());
144  }
145
146  /**
147   * Compares two values, returning true if the underlying objects in native code are the same object.
148   *
149   * That means you can have two different Java objects, but when you do a comparison, you'll find out
150   * they are the EXACT same object.
151   *
152   * @return True if the underlying native object is the same.  False otherwise.
153   */
154  public boolean equals(Object obj) {
155    boolean equal = false;
156    if (obj instanceof IContainer)
157      equal = (((IContainer)obj).swigCPtr == this.swigCPtr);
158    return equal;
159  }
160  
161  /**
162   * Get a hashable value for this object.
163   *
164   * @return the hashable value.
165   */
166  public int hashCode() {
167     return (int)swigCPtr;
168  }
169  
170  // <<<<<<<<<<<<<<<<<<<<<<<<<<<
171  // JNIHelper.swg: End generated code
172  
173
174  /**
175   * info about this container.  We only print information that can be
176   * determined without reading data from the container.
177   * @return a string representation of this object
178   */
179   
180  @Override
181  public String toString()
182  {
183    StringBuilder result = new StringBuilder();
184    
185    result.append(this.getClass().getName()+"@"+hashCode()+"[");
186    result.append("url:"+getURL()+";");
187    result.append("type:"+getType()+";");
188    result.append("format:"+getContainerFormat()+";");
189    result.append("]");
190    return result.toString();
191  }
192
193  /**
194   * Open this container and make it ready for reading or writing.
195   * Reading or writing ability is determined by
196   * what the {@link com.avpkit.core.io.IURLProtocolHandler}
197   * passed in supports.
198   * @see #open(String, IContainer.Type, IContainerFormat)
199   */  
200  public int open(
201    com.avpkit.core.io.IURLProtocolHandler handler,
202    IContainer.Type type, IContainerFormat format)
203  {
204    return open(com.avpkit.core.io.AVPKitIO.map(handler), type, format); 
205  }
206
207  /**
208   * Open this container and make it ready for writing.
209   * @see #open(String, IContainer.Type, IContainerFormat)
210   */  
211  public int open(
212    java.io.OutputStream output,
213    IContainerFormat format)
214  {
215    return open(com.avpkit.core.io.AVPKitIO.map(output),
216     IContainer.Type.WRITE, format); 
217  }
218
219  /**
220   * Open this container and make it ready for reading.
221   * @see #open(String, IContainer.Type, IContainerFormat)
222   */  
223  public int open(
224    java.io.InputStream input,
225    IContainerFormat format)
226  {
227    return open(com.avpkit.core.io.AVPKitIO.map(input),
228     IContainer.Type.READ, format); 
229  }
230
231  /**
232   * Open this container and make it ready for writing.
233   * @see #open(String, IContainer.Type, IContainerFormat)
234   */  
235  public int open(
236    java.io.DataOutput output,
237    IContainerFormat format)
238  {
239    return open(com.avpkit.core.io.AVPKitIO.map(output),
240     IContainer.Type.WRITE, format); 
241  }
242
243  /**
244   * Open this container and make it ready for writing.
245   * @see #open(String, IContainer.Type, IContainerFormat)
246   */  
247  public int open(
248    java.io.DataOutputStream output,
249    IContainerFormat format)
250  {
251    return open(com.avpkit.core.io.AVPKitIO.map(
252        (java.io.OutputStream)output),
253     IContainer.Type.WRITE, format); 
254  }
255
256  /**
257   * Open this container and make it ready for reading.
258   * @see #open(String, IContainer.Type, IContainerFormat)
259   */  
260  public int open(
261    java.io.DataInput input,
262    IContainerFormat format)
263  {
264    return open(com.avpkit.core.io.AVPKitIO.map(input),
265     IContainer.Type.READ, format); 
266  }
267
268  /**
269   * Open this container and make it ready for reading.
270   * @see #open(String, IContainer.Type, IContainerFormat)
271   */  
272  public int open(
273    java.io.DataInputStream input,
274    IContainerFormat format)
275  {
276    return open(com.avpkit.core.io.AVPKitIO.map(
277        (java.io.InputStream)input),
278     IContainer.Type.READ, format); 
279  }
280
281  /**
282   * Open this container and make it ready for reading or writing.
283   * @see #open(String, IContainer.Type, IContainerFormat)
284   */  
285  public int open(
286    java.io.RandomAccessFile file,
287    IContainer.Type type,
288    IContainerFormat format)
289  {
290    return open(com.avpkit.core.io.AVPKitIO.map(file),
291     type, format); 
292  }
293
294  /**
295   * Open this container and make it ready for writing.
296   * @see #open(String, IContainer.Type, IContainerFormat)
297   */  
298  public int open(
299    java.nio.channels.WritableByteChannel output,
300    IContainerFormat format)
301  {
302    return open(com.avpkit.core.io.AVPKitIO.map(output),
303     IContainer.Type.WRITE, format); 
304  }
305
306  /**
307   * Open this container and make it ready for reading.
308   * @see #open(String, IContainer.Type, IContainerFormat)
309   */  
310  public int open(
311    java.nio.channels.ReadableByteChannel input,
312    IContainerFormat format)
313  {
314    return open(com.avpkit.core.io.AVPKitIO.map(input),
315     IContainer.Type.READ, format); 
316  }
317
318  /**
319   * Open this container and make it ready for reading or writing.
320   * @see #open(String, IContainer.Type, IContainerFormat)
321   */  
322  public int open(
323    java.nio.channels.ByteChannel channel,
324    IContainer.Type type,
325    IContainerFormat format)
326  {
327    return open(com.avpkit.core.io.AVPKitIO.map(channel),
328     type, format); 
329  }
330
331
332/**
333 * Open this container and make it ready for reading or writing, optionally 
334 * reading as far into the container as necessary to find all streams.
335 * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
336 */
337  public int open(com.avpkit.core.io.IURLProtocolHandler handler,
338    IContainer.Type type, IContainerFormat format,
339    boolean streamsCanBeAddedDynamically,
340    boolean queryStreamMetaData)
341  {
342    return open(com.avpkit.core.io.AVPKitIO.map(handler), type, format,
343      streamsCanBeAddedDynamically,
344      queryStreamMetaData); 
345  }
346
347  /**
348   * Open this container and make it ready for writing.
349   * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
350   */  
351  public int open(
352    java.io.OutputStream output,
353    IContainerFormat format,
354    boolean streamsCanBeAddedDynamically,
355    boolean queryStreamMetaData)
356  {
357    return open(com.avpkit.core.io.AVPKitIO.map(output),
358     IContainer.Type.WRITE, format, streamsCanBeAddedDynamically, queryStreamMetaData); 
359  }
360
361  /**
362   * Open this container and make it ready for reading.
363   * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
364   */  
365  public int open(
366    java.io.InputStream input,
367    IContainerFormat format,
368    boolean streamsCanBeAddedDynamically,
369    boolean queryStreamMetaData)
370  {
371    return open(com.avpkit.core.io.AVPKitIO.map(input),
372     IContainer.Type.READ, format, streamsCanBeAddedDynamically, queryStreamMetaData); 
373  }
374
375  /**
376   * Open this container and make it ready for writing.
377   * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
378   */  
379  public int open(
380    java.io.DataOutput output,
381    IContainerFormat format,
382    boolean streamsCanBeAddedDynamically,
383    boolean queryStreamMetaData)
384  {
385    return open(com.avpkit.core.io.AVPKitIO.map(output),
386     IContainer.Type.WRITE, format, streamsCanBeAddedDynamically, queryStreamMetaData); 
387  }
388
389  /**
390   * Open this container and make it ready for writing.
391   * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
392   */  
393  public int open(
394    java.io.DataOutputStream output,
395    IContainerFormat format,
396    boolean streamsCanBeAddedDynamically,
397    boolean queryStreamMetaData)
398  {
399    return open(com.avpkit.core.io.AVPKitIO.map(
400        (java.io.OutputStream)output),
401     IContainer.Type.WRITE, format, streamsCanBeAddedDynamically, queryStreamMetaData); 
402  }
403
404  /**
405   * Open this container and make it ready for reading.
406   * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
407   */  
408  public int open(
409    java.io.DataInput input,
410    IContainerFormat format,
411    boolean streamsCanBeAddedDynamically,
412    boolean queryStreamMetaData)
413  {
414    return open(com.avpkit.core.io.AVPKitIO.map(input),
415     IContainer.Type.READ, format, streamsCanBeAddedDynamically, queryStreamMetaData); 
416  }
417
418  /**
419   * Open this container and make it ready for reading.
420   * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
421   */  
422  public int open(
423    java.io.DataInputStream input,
424    IContainerFormat format,
425    boolean streamsCanBeAddedDynamically,
426    boolean queryStreamMetaData)
427  {
428    return open(com.avpkit.core.io.AVPKitIO.map(
429        (java.io.InputStream)input),
430     IContainer.Type.READ, format, streamsCanBeAddedDynamically, queryStreamMetaData); 
431  }
432  
433  /**
434   * Open this container and make it ready for reading or writing.
435   * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
436   */  
437  public int open(
438    java.io.RandomAccessFile file,
439    IContainer.Type type,
440    IContainerFormat format,
441    boolean streamsCanBeAddedDynamically,
442    boolean queryStreamMetaData)
443  {
444    return open(com.avpkit.core.io.AVPKitIO.map(file),
445     type, format, streamsCanBeAddedDynamically, queryStreamMetaData); 
446  }
447
448  /**
449   * Open this container and make it ready for writing.
450   * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
451   */  
452  public int open(
453    java.nio.channels.WritableByteChannel output,
454    IContainerFormat format,
455    boolean streamsCanBeAddedDynamically,
456    boolean queryStreamMetaData)
457  {
458    return open(com.avpkit.core.io.AVPKitIO.map(output),
459     IContainer.Type.WRITE, format, streamsCanBeAddedDynamically, queryStreamMetaData); 
460  }
461
462  /**
463   * Open this container and make it ready for reading.
464   * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
465   */  
466  public int open(
467    java.nio.channels.ReadableByteChannel input,
468    IContainerFormat format,
469    boolean streamsCanBeAddedDynamically,
470    boolean queryStreamMetaData)
471  {
472    return open(com.avpkit.core.io.AVPKitIO.map(input),
473     IContainer.Type.READ, format, streamsCanBeAddedDynamically, queryStreamMetaData); 
474  }
475
476  /**
477   * Open this container and make it ready for reading or writing.
478   * @see #open(String, IContainer.Type, IContainerFormat, boolean, boolean) 
479   */  
480  public int open(
481    java.nio.channels.ByteChannel channel,
482    IContainer.Type type,
483    IContainerFormat format,
484    boolean streamsCanBeAddedDynamically,
485    boolean queryStreamMetaData)
486  {
487    return open(com.avpkit.core.io.AVPKitIO.map(channel),
488     type, format, streamsCanBeAddedDynamically, queryStreamMetaData); 
489  }
490
491  public int setCustomURLHandlerFactory(
492    com.avpkit.core.io.IURLProtocolHandlerFactory factory)
493  {
494    return com.avpkit.core.io.FfmpegIO.registerProtocolHandlerFactory(swigCPtr, this, factory);
495  }
496
497  /**
498   * Gets the SDP data as a Java string.
499   * <p>
500   * This method only supports SDP files up to 4K in size.
501   * If you have a larger SDP file, use the
502   * {@link #createSDPData(com.avpkit.ferry.IBuffer)} method and pass in your
503   * own {@link com.avpkit.ferry.IBuffer} object.
504   * </p> 
505   * @return A {@link String} representing the data.
506   * @see #createSDPData(IBuffer)
507   */
508  public String createSDPData()
509  {
510    IBuffer buffer = IBuffer.make(null, 4096);
511    int len = this.createSDPData(buffer);
512    if (len > 1)
513    {
514      byte [] stringBuf = new byte[len-1];
515      buffer.get(0, stringBuf, 0, stringBuf.length);
516      return new String(stringBuf);
517    }
518    return null;
519  }
520  /**
521   * {@inheritDoc}
522   */
523  public java.util.Collection<String> getPropertyNames()
524  {
525    java.util.Collection<String> retval = new java.util.LinkedList<String>();
526    int numProperties = this.getNumProperties();
527    for(int i = 0; i < numProperties; i++)
528    {
529      IProperty property = this.getPropertyMetaData(i);
530      String name = property.getName();
531      retval.add(name);
532    }
533    return retval;
534  }
535
536  
537
538  /**
539   * Set the buffer length AVPKit will suggest to FFMPEG for reading inputs.<br>
540   * <br>
541   * If called when a IContainer is open, the call is ignored and -1 is returned.<br>
542   * <br>
543   * @param size The suggested buffer size.<br>
544   * @return size on success; &lt;0 on error.
545   */
546  public int setInputBufferLength(int size) {
547    return AVPKitJNI.IContainer_setInputBufferLength(swigCPtr, this, size);
548  }
549
550  /**
551   * Return the input buffer length.<br>
552   * <br>
553   * @return The input buffer length AVPKit's told FFMPEG to assume.<br>
554   *   0 means FFMPEG should choose it's own<br>
555   *   size (and it'll probably be 32768).
556   */
557  public int getInputBufferLength() {
558    return AVPKitJNI.IContainer_getInputBufferLength(swigCPtr, this);
559  }
560
561  /**
562   * Is this container opened?<br>
563   * @return true if opened; false if not.
564   */
565  public boolean isOpened() {
566    return AVPKitJNI.IContainer_isOpened(swigCPtr, this);
567  }
568
569  /**
570   * Has a header been successfully written?<br>
571   * @return true if yes, false if no.
572   */
573  public boolean isHeaderWritten() {
574    return AVPKitJNI.IContainer_isHeaderWritten(swigCPtr, this);
575  }
576
577  /**
578   * Open this container and make it ready for reading or writing.<br>
579   * <p><br>
580   * The caller must call {#close()} when done, but if not, the<br>
581   * {IContainer} will eventually close<br>
582   * them later but warn to the logging system.<br>
583   * </p><br>
584   * <p><br>
585   * This just forwards to {#open(String, Type, IContainerFormat, boolean, boolean)}<br>
586   * passing false for aStreamsCanBeAddedDynamically, and true for aLookForAllStreams.<br>
587   * </p><p>If the current thread is interrupted while this blocking method<br>
588   * is running the method will return with a negative value.<br>
589   * To check if the method exited because of an interruption<br>
590   * pass the return value to {IError#make(int)} and then<br>
591   * check {IError#getType()} to see if it is<br>
592   * {IError.Type#ERROR_INTERRUPTED}.  <br>
593   * </p><br>
594   * <br>
595   * @param url The resource to open; The format of this string is any<br>
596   *   url that FFMPEG supports (including additional protocols if added<br>
597   *   through the core.io library).<br>
598   * @param type The type of this container.<br>
599   * @param pContainerFormat A pointer to a ContainerFormat object specifying<br>
600   *   the format of this container, or 0 (NULL) if you want us to guess.<br>
601   * <br>
602   * @return &gt;= 0 on success; &lt; 0 on error.
603   */
604  public int open(String url, IContainer.Type type, IContainerFormat pContainerFormat) {
605    return AVPKitJNI.IContainer_open__SWIG_0(swigCPtr, this, url, type.swigValue(), IContainerFormat.getCPtr(pContainerFormat), pContainerFormat);
606  }
607
608  /**
609   * Open this container and make it ready for reading or writing, optionally<br>
610   * reading as far into the container as necessary to find all streams.<br>
611   * <p>The caller must call {#close()} when done, but if not, the<br>
612   * {IContainer} will eventually close<br>
613   * them later but warn to the logging system.<br>
614   * </p><p>If the current thread is interrupted while this blocking method<br>
615   * is running the method will return with a negative value.<br>
616   * To check if the method exited because of an interruption<br>
617   * pass the return value to {IError#make(int)} and then<br>
618   * check {IError#getType()} to see if it is<br>
619   * {IError.Type#ERROR_INTERRUPTED}.  <br>
620   * </p><br>
621   * <br>
622   * @param url The resource to open; The format of this string is any<br>
623   *   url that FFMPEG supports (including additional protocols if added<br>
624   *   through the core.io library).<br>
625   * @param type The type of this container.<br>
626   * @param pContainerFormat A pointer to a ContainerFormat object specifying<br>
627   *   the format of this container, or 0 (NULL) if you want us to guess.<br>
628   * @param aStreamsCanBeAddedDynamically If true, open() will expect that new<br>
629   *   streams can be added at any time, even after the format header has been read.<br>
630   * @param aQueryStreamMetaData If true, open() will call {#queryStreamMetaData()}<br>
631   *   on this container, which will potentially block until it has ready<br>
632   *   enough data to find all streams in a container.  If false, it will only<br>
633   *   block to read a minimal header for this container format.<br>
634   * <br>
635   * @return &gt;= 0 on success; &lt; 0 on error.
636   */
637  public int open(String url, IContainer.Type type, IContainerFormat pContainerFormat, boolean aStreamsCanBeAddedDynamically, boolean aQueryStreamMetaData) {
638    return AVPKitJNI.IContainer_open__SWIG_1(swigCPtr, this, url, type.swigValue(), IContainerFormat.getCPtr(pContainerFormat), pContainerFormat, aStreamsCanBeAddedDynamically, aQueryStreamMetaData);
639  }
640
641  /**
642   * Gets the current level of standards compliance.<br>
643   * @return The level of standards compliance.<br>
644   * @see CodecStandardsCompliance<br>
645   * @since 5.7
646   */
647  public IStreamCoder.CodecStandardsCompliance getStandardsCompliance() {
648    return IStreamCoder.CodecStandardsCompliance.swigToEnum(AVPKitJNI.IContainer_getStandardsCompliance(swigCPtr, this));
649  }
650
651  /**
652   * Set the level of standards compliance.  Only paid attention to<br>
653   * before the code is opened.<br>
654   * <br>
655   * @param compliance The desired compliance level to set<br>
656   * @return 0 on success; non-zero on failure<br>
657   * @see CodecStandardsCompliance<br>
658   * @since 5.7
659   */
660  public int setStandardsCompliance(IStreamCoder.CodecStandardsCompliance compliance) {
661    return AVPKitJNI.IContainer_setStandardsCompliance(swigCPtr, this, compliance.swigValue());
662  }
663
664  /**
665   * Returns the IContainerFormat object being used for this IContainer,<br>
666   * or null if the {IContainer} doesn't yet know.<br>
667   * <br>
668   * @return the IContainerFormat object, or null.
669   */
670  public IContainerFormat getContainerFormat() {
671    long cPtr = AVPKitJNI.IContainer_getContainerFormat(swigCPtr, this);
672    return (cPtr == 0) ? null : new IContainerFormat(cPtr, false);
673  }
674
675  /**
676   * Close the container.  open() must have been called first, or<br>
677   * else an error is returned.<p>If the current thread is interrupted while this blocking method<br>
678   * is running the method will return with a negative value.<br>
679   * To check if the method exited because of an interruption<br>
680   * pass the return value to {IError#make(int)} and then<br>
681   * check {IError#getType()} to see if it is<br>
682   * {IError.Type#ERROR_INTERRUPTED}.  <br>
683   * </p><br>
684   * <p><br>
685   * If this method exits because of an interruption,<br>
686   * all resources will be closed anyway.<br>
687   * </p><br>
688   * <br>
689   * @return &gt;= 0 on success; &lt; 0 on error.
690   */
691  public int close(boolean dangling) {
692    return AVPKitJNI.IContainer_close__SWIG_0(swigCPtr, this, dangling);
693  }
694
695  /**
696   * Close the container.  open() must have been called first, or<br>
697   * else an error is returned.<p>If the current thread is interrupted while this blocking method<br>
698   * is running the method will return with a negative value.<br>
699   * To check if the method exited because of an interruption<br>
700   * pass the return value to {IError#make(int)} and then<br>
701   * check {IError#getType()} to see if it is<br>
702   * {IError.Type#ERROR_INTERRUPTED}.  <br>
703   * </p><br>
704   * <p><br>
705   * If this method exits because of an interruption,<br>
706   * all resources will be closed anyway.<br>
707   * </p><br>
708   * <br>
709   * @return &gt;= 0 on success; &lt; 0 on error.
710   */
711  public int close() {
712    return AVPKitJNI.IContainer_close__SWIG_1(swigCPtr, this);
713  }
714
715  /**
716   * Find out the type of this container.<br>
717   * <br>
718   * @return The Type of this container.  <br>
719   * {IContainer.Type#READ} if not yet opened.
720   */
721  public IContainer.Type getType() {
722    return IContainer.Type.swigToEnum(AVPKitJNI.IContainer_getType(swigCPtr, this));
723  }
724
725  /**
726   * The number of streams in this container.<br>
727   * <p>If opened in {IContainer.Type#READ} mode, this will query the stream and find out<br>
728   * how many streams are in it.</p><p>If opened in<br>
729   * {IContainer.Type#WRITE} mode, this will return the number of streams<br>
730   * the caller has added to date.</p><p>If the current thread is interrupted while this blocking method<br>
731   * is running the method will return with a negative value.<br>
732   * To check if the method exited because of an interruption<br>
733   * pass the return value to {IError#make(int)} and then<br>
734   * check {IError#getType()} to see if it is<br>
735   * {IError.Type#ERROR_INTERRUPTED}.  <br>
736   * </p> <br>
737   * <br>
738   * @return The number of streams in this container.
739   */
740  public int getNumStreams() {
741    return AVPKitJNI.IContainer_getNumStreams(swigCPtr, this);
742  }
743
744  /**
745   * Get the stream at the given position.<br>
746   * <br>
747   * @param streamIndex the index of this stream in the container<br>
748   * @return The stream at that position in the container, or null if none there.
749   */
750  public IStream getStream(int streamIndex) {
751    long cPtr = AVPKitJNI.IContainer_getStream(swigCPtr, this, streamIndex);
752    return (cPtr == 0) ? null : new IStream(cPtr, false);
753  }
754
755  /**
756   * @deprecated Use {#addNewStream(ICodec.ID)} instead.<br>
757   * <br>
758   * Creates a new stream in this container and returns it.<br>
759   * <br>
760   * @param id A format-dependent id for this stream.<br>
761   * <br>
762   * @return A new stream.
763   */
764  @Deprecated public IStream addNewStream(int id) {
765    long cPtr = AVPKitJNI.IContainer_addNewStream__SWIG_0(swigCPtr, this, id);
766    return (cPtr == 0) ? null : new IStream(cPtr, false);
767  }
768
769  /**
770   * Adds a header, if needed, for this container.<br>
771   * <p><br>
772   * Call this AFTER you've added all streams you want to add,<br>
773   * opened all IStreamCoders for those streams (with proper<br>
774   * configuration) and<br>
775   * before you write the first frame.  If you attempt to write<br>
776   * a header but haven't opened all codecs, this method will log<br>
777   * a warning, and your output file will likely be corrupt.<br>
778   * </p><p>If the current thread is interrupted while this blocking method<br>
779   * is running the method will return with a negative value.<br>
780   * To check if the method exited because of an interruption<br>
781   * pass the return value to {IError#make(int)} and then<br>
782   * check {IError#getType()} to see if it is<br>
783   * {IError.Type#ERROR_INTERRUPTED}.  <br>
784   * </p><br>
785   * <br>
786   * @return 0 if successful.  &lt; 0 if not.  Always -1 if this is<br>
787   *           a READ container.
788   */
789  public int writeHeader() {
790    return AVPKitJNI.IContainer_writeHeader(swigCPtr, this);
791  }
792
793  /**
794   * Adds a trailer, if needed, for this container.<br>
795   * <br>
796   * Call this AFTER you've written all data you're going to write<br>
797   * to this container but BEFORE you call<br>
798   * {IStreamCoder#close()} on your {IStreamCoder}<br>
799   * objects.<br>
800   * <p><br>
801   * You must call {#writeHeader()} before you call<br>
802   * this (and if you don't, the {IContainer}<br>
803   * will warn loudly and not<br>
804   * actually write the trailer).<br>
805   * </p><br>
806   * <p><br>
807   * If you have closed any of the {IStreamCoder} objects<br>
808   * that were open when you called<br>
809   * {#writeHeader()}, then this method will fail.<br>
810   * </p><p>If the current thread is interrupted while this blocking method<br>
811   * is running the method will return with a negative value.<br>
812   * To check if the method exited because of an interruption<br>
813   * pass the return value to {IError#make(int)} and then<br>
814   * check {IError#getType()} to see if it is<br>
815   * {IError.Type#ERROR_INTERRUPTED}.  <br>
816   * </p><br>
817   * <br>
818   * @return 0 if successful.  &lt; 0 if not.  Always &lt;0 if this is<br>
819   *           a READ container.
820   */
821  public int writeTrailer() {
822    return AVPKitJNI.IContainer_writeTrailer(swigCPtr, this);
823  }
824
825  /**
826   * Reads the next packet into the IPacket.  This method will<br>
827   * release any buffers currently held by this packet and allocate<br>
828   * new ones.<br>
829   * <p>If the current thread is interrupted while this blocking method<br>
830   * is running the method will return with a negative value.<br>
831   * To check if the method exited because of an interruption<br>
832   * pass the return value to {IError#make(int)} and then<br>
833   * check {IError#getType()} to see if it is<br>
834   * {IError.Type#ERROR_INTERRUPTED}.  <br>
835   * </p><br>
836   * <br>
837   * @param packet [In/Out] The packet the IContainer will read into.<br>
838   * <br>
839   * @return 0 if successful, or &lt;0 if not.
840   */
841  public int readNextPacket(IPacket packet) {
842    return AVPKitJNI.IContainer_readNextPacket(swigCPtr, this, IPacket.getCPtr(packet), packet);
843  }
844
845  /**
846   * Writes the contents of the packet to the container.<br>
847   * <p>If the current thread is interrupted while this blocking method<br>
848   * is running the method will return with a negative value.<br>
849   * To check if the method exited because of an interruption<br>
850   * pass the return value to {IError#make(int)} and then<br>
851   * check {IError#getType()} to see if it is<br>
852   * {IError.Type#ERROR_INTERRUPTED}.  <br>
853   * </p><br>
854   * <br>
855   * @param packet [In] The packet to write out.<br>
856   * @param forceInterleave [In] If true, then this {IContainer} will<br>
857   *   make sure all packets<br>
858   *   are interleaved by DTS (even across streams in a container). <br>
859   *   If false, the {IContainer} won't,<br>
860   *   and it's up to the caller to interleave if necessary.<br>
861   * <br>
862   * @return # of bytes written if successful, or &lt;0 if not.
863   */
864  public int writePacket(IPacket packet, boolean forceInterleave) {
865    return AVPKitJNI.IContainer_writePacket__SWIG_0(swigCPtr, this, IPacket.getCPtr(packet), packet, forceInterleave);
866  }
867
868  /**
869   * Writes the contents of the packet to the container, but make sure the<br>
870   * packets are interleaved.<br>
871   * <p><br>
872   * This means the {IContainer} may have to queue up packets from one<br>
873   * stream while waiting for packets from another.<br>
874   * </p><p>If the current thread is interrupted while this blocking method<br>
875   * is running the method will return with a negative value.<br>
876   * To check if the method exited because of an interruption<br>
877   * pass the return value to {IError#make(int)} and then<br>
878   * check {IError#getType()} to see if it is<br>
879   * {IError.Type#ERROR_INTERRUPTED}.  <br>
880   * </p><br>
881   * @param packet [In] The packet to write out.<br>
882   * <br>
883   * @return # of bytes written if successful, or &lt;0 if not.
884   */
885  public int writePacket(IPacket packet) {
886    return AVPKitJNI.IContainer_writePacket__SWIG_1(swigCPtr, this, IPacket.getCPtr(packet), packet);
887  }
888
889  /**
890   * Create a new container object.<br>
891   * <br>
892   * @return a new container, or null on error.
893   */
894  public static IContainer make() {
895    long cPtr = AVPKitJNI.IContainer_make__SWIG_0();
896    return (cPtr == 0) ? null : new IContainer(cPtr, false);
897  }
898
899  /**
900   * Attempts to read all the meta data in this stream, potentially by reading ahead<br>
901   * and decoding packets.<br>
902   * <p><br>
903   * Any packets this method reads ahead will be cached and correctly returned when you<br>
904   * read packets, but this method can be non-blocking potentially until end of container<br>
905   * to get all meta data.  Take care when you call it.<br>
906   * </p><p>After this method is called, other meta data methods like {#getDuration()} should<br>
907   * work.</p> <p>If the current thread is interrupted while this blocking method<br>
908   * is running the method will return with a negative value.<br>
909   * To check if the method exited because of an interruption<br>
910   * pass the return value to {IError#make(int)} and then<br>
911   * check {IError#getType()} to see if it is<br>
912   * {IError.Type#ERROR_INTERRUPTED}.  <br>
913   * </p><br>
914   * <br>
915   * @return &gt;= 0 on success; &lt;0 on failure.
916   */
917  public int queryStreamMetaData() {
918    return AVPKitJNI.IContainer_queryStreamMetaData(swigCPtr, this);
919  }
920
921  /**
922   * Seeks to the key frame at (or the first one after) the given timestamp.  This method will<br>
923   * always fail for any IContainer that is not seekable (e.g. is streamed).  When successful<br>
924   * the next call to {#readNextPacket(IPacket)} will get the next keyframe from the<br>
925   * sought for stream.<p>If the current thread is interrupted while this blocking method<br>
926   * is running the method will return with a negative value.<br>
927   * To check if the method exited because of an interruption<br>
928   * pass the return value to {IError#make(int)} and then<br>
929   * check {IError#getType()} to see if it is<br>
930   * {IError.Type#ERROR_INTERRUPTED}.  <br>
931   * </p><br>
932   * <p><br>
933   * <strong>WARNING:</strong>: This method will be deprecated<br>
934   * in a future AVPKit release and replaced with the new<br>
935   * API {#seekKeyFrame(int, long, long, long, int)}.<br>
936   * </p><br>
937   * <br>
938   * @param streamIndex The stream to search for the keyframe in; must be a<br>
939   *   stream the IContainer has either queried<br>
940   *   meta-data about or already ready a packet for.<br>
941   * @param timestamp The timestamp, in the timebase of the stream you're looking in (not necessarily Microseconds).<br>
942   * @param flags Flags to pass to com.avpkit.core.io.IURLProtocolHandler's seek method.<br>
943   * <br>
944   * @return &gt;= 0 on success; &lt;0 on failure.
945   */
946  public int seekKeyFrame(int streamIndex, long timestamp, int flags) {
947    return AVPKitJNI.IContainer_seekKeyFrame__SWIG_0(swigCPtr, this, streamIndex, timestamp, flags);
948  }
949
950  /**
951   * Gets the duration, if known, of this container.<br>
952   * <br>
953   * This will only work for non-streamable containers where IContainer <br>
954   * can calculate the container size.<br>
955   * <br>
956   * @return The duration, or {Global#NO_PTS} if not known.
957   */
958  public long getDuration() {
959    return AVPKitJNI.IContainer_getDuration(swigCPtr, this);
960  }
961
962  /**
963   * Get the starting timestamp in microseconds of the first packet of the earliest stream in this container.<br>
964   * <p><br>
965   * This will only return value values either either (a) for non-streamable<br>
966   * containers where IContainer can calculate the container size or<br>
967   * (b) after IContainer has actually read the<br>
968   * first packet from a streamable source.<br>
969   * </p><br>
970   * <br>
971   * @return The starting timestamp in microseconds, or {Global#NO_PTS} if not known.
972   */
973  public long getStartTime() {
974    return AVPKitJNI.IContainer_getStartTime(swigCPtr, this);
975  }
976
977  /**
978   * Get the file size in bytes of this container.<br>
979   * <br>
980   * This will only return a valid value if the container is non-streamed and supports seek.<br>
981   * <br>
982   * @return The file size in bytes, or &lt;0 on error.
983   */
984  public long getFileSize() {
985    return AVPKitJNI.IContainer_getFileSize(swigCPtr, this);
986  }
987
988  /**
989   * Get the calculated overall bit rate of this file.<br>
990   * <p><br>
991   * This will only return a valid value if the container is non-streamed and supports seek.<br>
992   * </p><br>
993   * @return The overall bit rate in bytes per second, or &lt;0 on error.
994   */
995  public int getBitRate() {
996    return AVPKitJNI.IContainer_getBitRate(swigCPtr, this);
997  }
998
999  /**
1000   * Returns the total number of settable properties on this object<br>
1001   * <br>
1002   * @return total number of options (not including constant definitions)
1003   */
1004  public int getNumProperties() {
1005    return AVPKitJNI.IContainer_getNumProperties(swigCPtr, this);
1006  }
1007
1008  /**
1009   * Returns the name of the numbered property.<br>
1010   * <br>
1011   * @param propertyNo The property number in the options list.<br>
1012   * <br>
1013   * @return an IProperty value for this properties meta-data
1014   */
1015  public IProperty getPropertyMetaData(int propertyNo) {
1016    long cPtr = AVPKitJNI.IContainer_getPropertyMetaData__SWIG_0(swigCPtr, this, propertyNo);
1017    return (cPtr == 0) ? null : new IProperty(cPtr, false);
1018  }
1019
1020  /**
1021   * Returns the name of the numbered property.<br>
1022   * <br>
1023   * @param name  The property name.<br>
1024   * <br>
1025   * @return an IProperty value for this properties meta-data
1026   */
1027  public IProperty getPropertyMetaData(String name) {
1028    long cPtr = AVPKitJNI.IContainer_getPropertyMetaData__SWIG_1(swigCPtr, this, name);
1029    return (cPtr == 0) ? null : new IProperty(cPtr, false);
1030  }
1031
1032  /**
1033   * Sets a property on this Object.<br>
1034   * <br>
1035   * All AVOptions supported by the underlying AVClass are supported.<br>
1036   * <br>
1037   * @param name The property name.  For example "b" for bit-rate.<br>
1038   * @param value The value of the property. <br>
1039   * <br>
1040   * @return &gt;= 0 if the property was successfully set; &lt;0 on error
1041   */
1042  public int setProperty(String name, String value) {
1043    return AVPKitJNI.IContainer_setProperty__SWIG_0(swigCPtr, this, name, value);
1044  }
1045
1046  /**
1047   * Looks up the property 'name' and sets the<br>
1048   * value of the property to 'value'.<br>
1049   * <br>
1050   * @param name name of option<br>
1051   * @param value Value of option<br>
1052   * <br>
1053   * @return &gt;= 0 on success; &lt;0 on error.
1054   */
1055  public int setProperty(String name, double value) {
1056    return AVPKitJNI.IContainer_setProperty__SWIG_1(swigCPtr, this, name, value);
1057  }
1058
1059  /**
1060   * Looks up the property 'name' and sets the<br>
1061   * value of the property to 'value'.<br>
1062   * <br>
1063   * @param name name of option<br>
1064   * @param value Value of option<br>
1065   * <br>
1066   * @return &gt;= 0 on success; &lt;0 on error.
1067   */
1068  public int setProperty(String name, long value) {
1069    return AVPKitJNI.IContainer_setProperty__SWIG_2(swigCPtr, this, name, value);
1070  }
1071
1072  /**
1073   * Looks up the property 'name' and sets the<br>
1074   * value of the property to 'value'.<br>
1075   * <br>
1076   * @param name name of option<br>
1077   * @param value Value of option<br>
1078   * <br>
1079   * @return &gt;= 0 on success; &lt;0 on error.
1080   */
1081  public int setProperty(String name, boolean value) {
1082    return AVPKitJNI.IContainer_setProperty__SWIG_3(swigCPtr, this, name, value);
1083  }
1084
1085  /**
1086   * Looks up the property 'name' and sets the<br>
1087   * value of the property to 'value'.<br>
1088   * <br>
1089   * @param name name of option<br>
1090   * @param value Value of option<br>
1091   * <br>
1092   * @return &gt;= 0 on success; &lt;0 on error.
1093   */
1094  public int setProperty(String name, IRational value) {
1095    return AVPKitJNI.IContainer_setProperty__SWIG_4(swigCPtr, this, name, IRational.getCPtr(value), value);
1096  }
1097
1098  /**
1099   * Gets a property on this Object.<br>
1100   * <br>
1101   * <p><br>
1102   * Note for C++ callers; you must free the returned array with<br>
1103   * delete[] in order to avoid a memory leak.  If you call<br>
1104   * from Java or any other language, you don't need to worry<br>
1105   * about this.<br>
1106   * </p><br>
1107   * <br>
1108   * @param name property name<br>
1109   * <br>
1110   * @return an string copy of the option value, or null if the option doesn't exist.
1111   */
1112  public String getPropertyAsString(String name) {
1113    return AVPKitJNI.IContainer_getPropertyAsString(swigCPtr, this, name);
1114  }
1115
1116  /**
1117   * Gets the value of this property, and returns as a double;<br>
1118   * <br>
1119   * @param name name of option<br>
1120   * <br>
1121   * @return double value of property, or 0 on error.
1122   */
1123  public double getPropertyAsDouble(String name) {
1124    return AVPKitJNI.IContainer_getPropertyAsDouble(swigCPtr, this, name);
1125  }
1126
1127  /**
1128   * Gets the value of this property, and returns as an long;<br>
1129   * <br>
1130   * @param name name of option<br>
1131   * <br>
1132   * @return long value of property, or 0 on error.
1133   */
1134  public long getPropertyAsLong(String name) {
1135    return AVPKitJNI.IContainer_getPropertyAsLong(swigCPtr, this, name);
1136  }
1137
1138  /**
1139   * Gets the value of this property, and returns as an IRational;<br>
1140   * <br>
1141   * @param name name of option<br>
1142   * <br>
1143   * @return long value of property, or 0 on error.
1144   */
1145  public IRational getPropertyAsRational(String name) {
1146    long cPtr = AVPKitJNI.IContainer_getPropertyAsRational(swigCPtr, this, name);
1147    return (cPtr == 0) ? null : new IRational(cPtr, false);
1148  }
1149
1150  /**
1151   * Gets the value of this property, and returns as a boolean<br>
1152   * <br>
1153   * @param name name of option<br>
1154   * <br>
1155   * @return boolean value of property, or false on error.
1156   */
1157  public boolean getPropertyAsBoolean(String name) {
1158    return AVPKitJNI.IContainer_getPropertyAsBoolean(swigCPtr, this, name);
1159  }
1160
1161  /**
1162   * Get the flags associated with this object.<br>
1163   * <br>
1164   * @return The (compacted) value of all flags set.
1165   */
1166  public int getFlags() {
1167    return AVPKitJNI.IContainer_getFlags(swigCPtr, this);
1168  }
1169
1170  /**
1171   * Set the flags to use with this object.  All values<br>
1172   * must be ORed (|) together.<br>
1173   * <br>
1174   * @see Flags<br>
1175   * <br>
1176   * @param newFlags The new set flags for this codec.
1177   */
1178  public void setFlags(int newFlags) {
1179    AVPKitJNI.IContainer_setFlags(swigCPtr, this, newFlags);
1180  }
1181
1182  /**
1183   * Get the setting for the specified flag<br>
1184   * <br>
1185   * @param flag The flag you want to find the setting for<br>
1186   * <br>
1187   * @return 0 for false; non-zero for true
1188   */
1189  public boolean getFlag(IContainer.Flags flag) {
1190    return AVPKitJNI.IContainer_getFlag(swigCPtr, this, flag.swigValue());
1191  }
1192
1193  /**
1194   * Set the flag.<br>
1195   * <br>
1196   * @param flag The flag to set<br>
1197   * @param value The value to set it to (true or false)
1198   */
1199  public void setFlag(IContainer.Flags flag, boolean value) {
1200    AVPKitJNI.IContainer_setFlag(swigCPtr, this, flag.swigValue(), value);
1201  }
1202
1203  /**
1204   * Get the URL the IContainer was opened with.<br>
1205   * May return null if unknown.<br>
1206   * @return the URL opened, or null.
1207   */
1208  public String getURL() {
1209    return AVPKitJNI.IContainer_getURL(swigCPtr, this);
1210  }
1211
1212  /**
1213   * Flush all packets to output.<br>
1214   * <p><br>
1215   * Will only work on {IContainer.Type#WRITE} containers.<br>
1216   * </p><p>If the current thread is interrupted while this blocking method<br>
1217   * is running the method will return with a negative value.<br>
1218   * To check if the method exited because of an interruption<br>
1219   * pass the return value to {IError#make(int)} and then<br>
1220   * check {IError#getType()} to see if it is<br>
1221   * {IError.Type#ERROR_INTERRUPTED}.  <br>
1222   * </p><br>
1223   * <br>
1224   * @return &gt;= 0 on success; &lt;0 on error
1225   */
1226  public int flushPackets() {
1227    return AVPKitJNI.IContainer_flushPackets(swigCPtr, this);
1228  }
1229
1230  /**
1231   * Get the number of times {IContainer#readNextPacket(IPacket)}<br>
1232   * will retry a read if it gets a {IError.Type#ERROR_AGAIN}<br>
1233   * value back.<br>
1234   * <br>
1235   * Defaults to 1 times.  &lt;0 means it will keep retrying indefinitely.<br>
1236   * <br>
1237   * @return the read retry count
1238   */
1239  public int getReadRetryCount() {
1240    return AVPKitJNI.IContainer_getReadRetryCount(swigCPtr, this);
1241  }
1242
1243  /**
1244   * Sets the read retry count.<br>
1245   * <br>
1246   * @see #getReadRetryCount()<br>
1247   * <br>
1248   * @param count The read retry count.  &lt;0 means keep trying.
1249   */
1250  public void setReadRetryCount(int count) {
1251    AVPKitJNI.IContainer_setReadRetryCount(swigCPtr, this, count);
1252  }
1253
1254  /**
1255   * Can streams be added dynamically to this container?<br>
1256   * <br>
1257   * @return true if streams can be added dynamically
1258   */
1259  public boolean canStreamsBeAddedDynamically() {
1260    return AVPKitJNI.IContainer_canStreamsBeAddedDynamically(swigCPtr, this);
1261  }
1262
1263  /**
1264   * Get the {IMetaData} for this object,<br>
1265   * or null if none.<br>
1266   * <p><br>
1267   * If the {IContainer} or {IStream} object<br>
1268   * that this {IMetaData} came from was opened<br>
1269   * for reading, then changes via {IMetaData#setValue(String, String)}<br>
1270   * will have no effect on the underlying media.<br>
1271   * </p><br>
1272   * <p><br>
1273   * If the {IContainer} or {IStream} object<br>
1274   * that this {IMetaData} came from was opened<br>
1275   * for writing, then changes via {IMetaData#setValue(String, String)}<br>
1276   * will have no effect after {IContainer#writeHeader()}<br>
1277   * is called.<br>
1278   * </p><br>
1279   * @return the {IMetaData}.
1280   */
1281  public IMetaData getMetaData() {
1282    long cPtr = AVPKitJNI.IContainer_getMetaData(swigCPtr, this);
1283    return (cPtr == 0) ? null : new IMetaData(cPtr, false);
1284  }
1285
1286  /**
1287   * Set the {IMetaData} on this object, overriding<br>
1288   * any previous meta data.  You should call this<br>
1289   * method on writable containers and<br>
1290   * before you call {IContainer#writeHeader}, as<br>
1291   * it probably won't do anything after that.<br>
1292   * <br>
1293   * @see #getMetaData()
1294   */
1295  public void setMetaData(IMetaData data) {
1296    AVPKitJNI.IContainer_setMetaData(swigCPtr, this, IMetaData.getCPtr(data), data);
1297  }
1298
1299  /**
1300   * Fills the given buffer with a null-terminated ASCII<br>
1301   * set of bytes representing SDP data that<br>
1302   * is suitable for use with an RTSP-based system.<br>
1303   * <p><br>
1304   * This method only works if AVPKit is linking<br>
1305   * against a version of FFmpeg that supports RTSP.<br>
1306   * </p><br>
1307   * @param buffer the {com.avpkit.ferry.IBuffer}<br>
1308   * object to fill with data.<br>
1309   * @return the number of bytes written, including the<br>
1310   * terminating 0 byte, or &lt; 0 on error.
1311   */
1312  public int createSDPData(IBuffer buffer) {
1313    return AVPKitJNI.IContainer_createSDPData(swigCPtr, this, IBuffer.getCPtr(buffer), buffer);
1314  }
1315
1316  /**
1317   * Forces the {IContainer} to assume all audio streams are<br>
1318   * encoded with the given audio codec when demuxing.<br>
1319   * @param id The codec id<br>
1320   * @return &lt; 0 on error (e.g. not an audio codec); &gt;= 0 on success.<br>
1321   * @since 3.3
1322   */
1323  public int setForcedAudioCodec(ICodec.ID id) {
1324    return AVPKitJNI.IContainer_setForcedAudioCodec(swigCPtr, this, id.swigValue());
1325  }
1326
1327  /**
1328   * Forces the {IContainer} to assume all video streams are<br>
1329   * encoded with the given video codec when demuxing.<br>
1330   * @param id The codec id<br>
1331   * @return &lt; 0 on error (e.g. not an video codec); &gt;= 0 on success.<br>
1332   * @since 3.3
1333   */
1334  public int setForcedVideoCodec(ICodec.ID id) {
1335    return AVPKitJNI.IContainer_setForcedVideoCodec(swigCPtr, this, id.swigValue());
1336  }
1337
1338  /**
1339   * Forces the {IContainer} to assume all subtitle streams are<br>
1340   * encoded with the given subtitle codec when demuxing.<br>
1341   * @param id The codec id<br>
1342   * @return &lt; 0 on error (e.g. not an subtitle codec); &gt;= 0 on success.<br>
1343   * @since 3.3
1344   */
1345  public int setForcedSubtitleCodec(ICodec.ID id) {
1346    return AVPKitJNI.IContainer_setForcedSubtitleCodec(swigCPtr, this, id.swigValue());
1347  }
1348
1349  /**
1350   * EXPERIMENTAL - Seeks to timestamp in the container.<br>
1351   * <p><br>
1352   * Seeking will be done so that the point from which all active streams<br>
1353   * can be presented successfully will be closest to<br>
1354   * <code>targetTimeStamp</code> and within <code><br>
1355   * minTimeStamp/maxTimeStamp</code>.<br>
1356   * </p><br>
1357   * <p><br>
1358   * If flags contain {#SEEK_FLAG_BYTE}, then all time stamps are in bytes and<br>
1359   * are the file position (this may not be supported by all demuxers).<br>
1360   * If flags contain {#SEEK_FLAG_FRAME}, then all time stamps are in frames<br>
1361   * in the stream with <code>streamIndex</code> (this may not be supported by all demuxers).<br>
1362   * Otherwise all time stamps are in units of the stream selected by stream_index<br>
1363   * or if stream_index is -1, in microseconds.<br>
1364   * If flags contain {#SEEK_FLAG_ANY}, then non-keyframes are treated as<br>
1365   * keyframes (this may not be supported by all demuxers).<br>
1366   * If flags contain {#SEEK_FLAG_BACKWARDS}, then we will attempt to<br>
1367   * search backwards in the container (this may not be supported by all<br>
1368   * demuxers and file protocols).<br>
1369   * </p><br>
1370   * <p><br>
1371   * This is part of the new seek API which is still under construction.<br>
1372   *       It may change in future AVPKit versions.<br>
1373   * </p><br>
1374   * @param streamIndex index of the stream which is used as time base reference<br>
1375   * @param minTimeStamp smallest acceptable time stamp.<br>
1376   * @param targetTimeStamp target time stamp.<br>
1377   * @param maxTimeStamp largest acceptable time stamp.<br>
1378   * @param flags A bitmask of the <code>SEEK_FLAG_*</code> flags, or 0 to turn<br>
1379   *   all flags off.<br>
1380   * @return &gt;=0 on success, error code otherwise<br>
1381   * @since 3.4
1382   */
1383  public int seekKeyFrame(int streamIndex, long minTimeStamp, long targetTimeStamp, long maxTimeStamp, int flags) {
1384    return AVPKitJNI.IContainer_seekKeyFrame__SWIG_1(swigCPtr, this, streamIndex, minTimeStamp, targetTimeStamp, maxTimeStamp, flags);
1385  }
1386
1387  /**
1388   * @deprecated use {#setProperty} instead.<br>
1389   * <br>
1390   * If the container has not already been opened, sets the AVFormatContext.preload property<br>
1391   * which can be useful in some circumstances such as when dealing with mpeg formats.<br>
1392   * <br>
1393   * @param preload amount to preload<br>
1394   * @return &gt;= 0 on success, error code otherwise<br>
1395   * @since 4.0
1396   */
1397  @Deprecated public int setPreload(int preload) {
1398    return AVPKitJNI.IContainer_setPreload(swigCPtr, this, preload);
1399  }
1400
1401  /**
1402   * @deprecated use {#getPropertyAsLong} instead.<br>
1403   * The amount container will attemtp to preload.<br>
1404   * <br>
1405   * @return The amount to preload, error code otherwise.
1406   */
1407  @Deprecated public int getPreload() {
1408    return AVPKitJNI.IContainer_getPreload(swigCPtr, this);
1409  }
1410
1411  /**
1412   * Sets the max delay for the AVFormatContext.max_delay property.<br>
1413   * <br>
1414   * @param maxdelay maximum delay for container<br>
1415   * @return &gt;= 0 on success, error code otherwise<br>
1416   * @since 4.0
1417   */
1418  public int setMaxDelay(int maxdelay) {
1419    return AVPKitJNI.IContainer_setMaxDelay(swigCPtr, this, maxdelay);
1420  }
1421
1422  /**
1423   * Gets the AVFormatContext.max_delay property if possible.<br>
1424   * @return The max delay, error code otherwise.<br>
1425   * @since 4.0
1426   */
1427  public int getMaxDelay() {
1428    return AVPKitJNI.IContainer_getMaxDelay(swigCPtr, this);
1429  }
1430
1431  /**
1432   * Add a new stream that will use the given codec.<br>
1433   * <br>
1434   * @param id The id for the codec used to insert packets.  If you are adding an arbitrary data stream, use {ICodec.ID#AV_CODEC_ID_NONE}, otherwise<br>
1435   *   use the ID of the code type you plan to use.<br>
1436   * <br>
1437   * @return An {IStream} for the new stream on success, or null on failure.<br>
1438   * @since 5.0
1439   */
1440  public IStream addNewStream(ICodec.ID id) {
1441    long cPtr = AVPKitJNI.IContainer_addNewStream__SWIG_1(swigCPtr, this, id.swigValue());
1442    return (cPtr == 0) ? null : new IStream(cPtr, false);
1443  }
1444
1445  /**
1446   * Add a new stream that will use the given codec.<br>
1447   * <br>
1448   * @param codec The codec that will be used to insert packets.<br>
1449   * <br>
1450   * @return An {IStream} for the new stream on success, or null on failure.<br>
1451   * @since 5.0
1452   */
1453  public IStream addNewStream(ICodec codec) {
1454    long cPtr = AVPKitJNI.IContainer_addNewStream__SWIG_2(swigCPtr, this, ICodec.getCPtr(codec), codec);
1455    return (cPtr == 0) ? null : new IStream(cPtr, false);
1456  }
1457
1458  /**
1459   * Add a new stream that will use the given StreamCoder.  The StreamCoder passed in MUST contain the {IStreamCoder#getExtraData} that<br>
1460   * was used to encode the packet.<br>
1461   * <br>
1462   * @param coder The {IStreamCoder} that contains the meta-information needed for decoding the packets that will be muexed into this stream.<br>
1463   * @return An {IStream} for the new stream on success, or null on failure.<br>
1464   * @since 5.0
1465   */
1466  public IStream addNewStream(IStreamCoder coder) {
1467    long cPtr = AVPKitJNI.IContainer_addNewStream__SWIG_3(swigCPtr, this, IStreamCoder.getCPtr(coder), coder);
1468    return (cPtr == 0) ? null : new IStream(cPtr, false);
1469  }
1470
1471  /**
1472   * {
1473   */
1474  public int setProperty(IMetaData valuesToSet, IMetaData valuesNotFound) {
1475    return AVPKitJNI.IContainer_setProperty__SWIG_5(swigCPtr, this, IMetaData.getCPtr(valuesToSet), valuesToSet, IMetaData.getCPtr(valuesNotFound), valuesNotFound);
1476  }
1477
1478  /**
1479   * Get the {IContainerFormat} that is used by this {IContainer}.<br>
1480   * <br>
1481   * @return The format, or null if none is set yet.<br>
1482   * @since 5.0
1483   */
1484  public IContainerFormat getFormat() {
1485    long cPtr = AVPKitJNI.IContainer_getFormat(swigCPtr, this);
1486    return (cPtr == 0) ? null : new IContainerFormat(cPtr, false);
1487  }
1488
1489  /**
1490   * Set the {IContainerFormat} to use with this {IContainer}.  If called when the<br>
1491   * {IContainer} is opened, or if previously called with a non-null value,<br>
1492   * an error is returned and no action is taken.<br>
1493   * @param format The format to use<br>
1494   * return 0 on success; &lt;0 on failure<br>
1495   * @since 5.0
1496   */
1497  public int setFormat(IContainerFormat format) {
1498    return AVPKitJNI.IContainer_setFormat(swigCPtr, this, IContainerFormat.getCPtr(format), format);
1499  }
1500
1501  /**
1502   * Create a new {IContainer} and call {#setFormat(IContainerFormat)} on it immediately.<br>
1503   * @param format The format to pass to {#setFormat(IContainerFormat)}<br>
1504   * @return An {IContainer} on success, or null on failure.<br>
1505   * @since 5.0
1506   */
1507  public static IContainer make(IContainerFormat format) {
1508    long cPtr = AVPKitJNI.IContainer_make__SWIG_1(IContainerFormat.getCPtr(format), format);
1509    return (cPtr == 0) ? null : new IContainer(cPtr, false);
1510  }
1511
1512  /**
1513   * Open this container and make it ready for reading or writing, optionally<br>
1514   * reading as far into the container as necessary to find all streams.<br>
1515   * <p>The caller must call {#close()} when done, but if not, the<br>
1516   * {IContainer} will eventually close<br>
1517   * them later but warn to the logging system.<br>
1518   * </p><p>If the current thread is interrupted while this blocking method<br>
1519   * is running the method will return with a negative value.<br>
1520   * To check if the method exited because of an interruption<br>
1521   * pass the return value to {IError#make(int)} and then<br>
1522   * check {IError#getType()} to see if it is<br>
1523   * {IError.Type#ERROR_INTERRUPTED}.<br>
1524   * </p><br>
1525   * <br>
1526   * @param url The resource to open; The format of this string is any<br>
1527   *   url that FFMPEG supports (including additional protocols if added<br>
1528   *   through the core.io library).<br>
1529   * @param type The type of this container.<br>
1530   * @param containerFormat A pointer to a ContainerFormat object specifying<br>
1531   *   the format of this container, or 0 (NULL) if you want us to guess.<br>
1532   * @param streamsCanBeAddedDynamically If true, open() will expect that new<br>
1533   *   streams can be added at any time, even after the format header has been read.<br>
1534   * @param queryStreamMetaData If true, open() will call {#queryStreamMetaData()}<br>
1535   *   on this container, which will potentially block until it has ready<br>
1536   *   enough data to find all streams in a container.  If false, it will only<br>
1537   *   block to read a minimal header for this container format.<br>
1538   * @param options If not null, a set of key-value pairs that will be set on the container immediately<br>
1539   *   the format is determined.  Some options cannot be set (especially for input containers) until the<br>
1540   *   system has a chance to parse what data is in the file.<br>
1541   * @param optionsNotSet If not null, on return this {IMetaData} object will be cleared out, and<br>
1542   *   replace with any key/value pairs that were in <code>options</code> but could not be set on this<br>
1543   *   {IContainer}.<br>
1544   * <br>
1545   * @return &gt;= 0 on success; &lt; 0 on error.<br>
1546   * @since 5.0
1547   */
1548  public int open(String url, IContainer.Type type, IContainerFormat containerFormat, boolean streamsCanBeAddedDynamically, boolean queryStreamMetaData, IMetaData options, IMetaData optionsNotSet) {
1549    return AVPKitJNI.IContainer_open__SWIG_2(swigCPtr, this, url, type.swigValue(), IContainerFormat.getCPtr(containerFormat), containerFormat, streamsCanBeAddedDynamically, queryStreamMetaData, IMetaData.getCPtr(options), options, IMetaData.getCPtr(optionsNotSet), optionsNotSet);
1550  }
1551
1552  /**
1553   * The different types of Containers AVPKit supports.  A container<br>
1554   * may only be opened in a uni-directional mode.
1555   */
1556  public enum Type {
1557    READ,
1558    WRITE;
1559
1560    public final int swigValue() {
1561      return swigValue;
1562    }
1563
1564    public static Type swigToEnum(int swigValue) {
1565      Type[] swigValues = Type.class.getEnumConstants();
1566      if (swigValue < swigValues.length && swigValue >= 0 && swigValues[swigValue].swigValue == swigValue)
1567        return swigValues[swigValue];
1568      for (Type swigEnum : swigValues)
1569        if (swigEnum.swigValue == swigValue)
1570          return swigEnum;
1571      throw new IllegalArgumentException("No enum " + Type.class + " with value " + swigValue);
1572    }
1573
1574    @SuppressWarnings("unused")
1575    private Type() {
1576      this.swigValue = SwigNext.next++;
1577    }
1578
1579    @SuppressWarnings("unused")
1580    private Type(int swigValue) {
1581      this.swigValue = swigValue;
1582      SwigNext.next = swigValue+1;
1583    }
1584
1585    @SuppressWarnings("unused")
1586    private Type(Type swigEnum) {
1587      this.swigValue = swigEnum.swigValue;
1588      SwigNext.next = this.swigValue+1;
1589    }
1590
1591    private final int swigValue;
1592
1593    private static class SwigNext {
1594      private static int next = 0;
1595    }
1596  }
1597
1598  public enum Flags {
1599    FLAG_GENPTS(AVPKitJNI.IContainer_FLAG_GENPTS_get()),
1600    FLAG_IGNIDX(AVPKitJNI.IContainer_FLAG_IGNIDX_get()),
1601    FLAG_NONBLOCK(AVPKitJNI.IContainer_FLAG_NONBLOCK_get()),
1602    FLAG_IGNDTS(AVPKitJNI.IContainer_FLAG_IGNDTS_get()),
1603    FLAG_NOFILLIN(AVPKitJNI.IContainer_FLAG_NOFILLIN_get()),
1604    FLAG_NOPARSE(AVPKitJNI.IContainer_FLAG_NOPARSE_get()),
1605    FLAG_NOBUFFER(AVPKitJNI.IContainer_FLAG_NOBUFFER_get()),
1606    FLAG_CUSTOM_IO(AVPKitJNI.IContainer_FLAG_CUSTOM_IO_get()),
1607    FLAG_DISCARD_CORRUPT(AVPKitJNI.IContainer_FLAG_DISCARD_CORRUPT_get()),
1608    FLAG_FLUSH_PACKETS(AVPKitJNI.IContainer_FLAG_FLUSH_PACKETS_get()),
1609    FLAG_BITEXACT(AVPKitJNI.IContainer_FLAG_BITEXACT_get()),
1610    FLAG_MP4A_LATM(AVPKitJNI.IContainer_FLAG_MP4A_LATM_get()),
1611    FLAG_SORT_DTS(AVPKitJNI.IContainer_FLAG_SORT_DTS_get()),
1612    FLAG_PRIV_OPT(AVPKitJNI.IContainer_FLAG_PRIV_OPT_get()),
1613    FLAG_KEEP_SIDE_DATA(AVPKitJNI.IContainer_FLAG_KEEP_SIDE_DATA_get()),
1614    FLAG_FAST_SEEK(AVPKitJNI.IContainer_FLAG_FAST_SEEK_get()),
1615    FLAG_SHORTEST(AVPKitJNI.IContainer_FLAG_SHORTEST_get()),
1616    FLAG_AUTO_BSF(AVPKitJNI.IContainer_FLAG_AUTO_BSF_get());
1617
1618    public final int swigValue() {
1619      return swigValue;
1620    }
1621
1622    public static Flags swigToEnum(int swigValue) {
1623      Flags[] swigValues = Flags.class.getEnumConstants();
1624      if (swigValue < swigValues.length && swigValue >= 0 && swigValues[swigValue].swigValue == swigValue)
1625        return swigValues[swigValue];
1626      for (Flags swigEnum : swigValues)
1627        if (swigEnum.swigValue == swigValue)
1628          return swigEnum;
1629      throw new IllegalArgumentException("No enum " + Flags.class + " with value " + swigValue);
1630    }
1631
1632    @SuppressWarnings("unused")
1633    private Flags() {
1634      this.swigValue = SwigNext.next++;
1635    }
1636
1637    @SuppressWarnings("unused")
1638    private Flags(int swigValue) {
1639      this.swigValue = swigValue;
1640      SwigNext.next = swigValue+1;
1641    }
1642
1643    @SuppressWarnings("unused")
1644    private Flags(Flags swigEnum) {
1645      this.swigValue = swigEnum.swigValue;
1646      SwigNext.next = this.swigValue+1;
1647    }
1648
1649    private final int swigValue;
1650
1651    private static class SwigNext {
1652      private static int next = 0;
1653    }
1654  }
1655
1656  /**
1657   *  Flag; Seek backwards 
1658   */
1659  public final static int SEEK_FLAG_BACKWARDS = AVPKitJNI.IContainer_SEEK_FLAG_BACKWARDS_get();
1660  /**
1661   *  Flag; Use bytes instead of time stamps for seeking 
1662   */
1663  public final static int SEEK_FLAG_BYTE = AVPKitJNI.IContainer_SEEK_FLAG_BYTE_get();
1664  /**
1665   *  Flag; Seek to any frame, even non-keyframes 
1666   */
1667  public final static int SEEK_FLAG_ANY = AVPKitJNI.IContainer_SEEK_FLAG_ANY_get();
1668  /**
1669   *  Flag; Seek based on frame number instead of time stamps 
1670   */
1671  public final static int SEEK_FLAG_FRAME = AVPKitJNI.IContainer_SEEK_FLAG_FRAME_get();
1672}