AVPKit
com::avpkit::core::Container Class Reference
Inheritance diagram for com::avpkit::core::Container:
Collaboration diagram for com::avpkit::core::Container:

Public Member Functions

virtual int32_t setInputBufferLength (int32_t size)
 Set the buffer length AVPKit will suggest to FFMPEG for reading inputs. More...
 
virtual int32_t getInputBufferLength ()
 Return the input buffer length. More...
 
virtual bool isOpened ()
 Is this container opened? More...
 
virtual bool isHeaderWritten ()
 Has a header been successfully written? More...
 
virtual int32_t open (const char *url, Type type, IContainerFormat *pContainerFormat)
 Open this container and make it ready for reading or writing. More...
 
virtual int32_t open (const char *url, Type type, IContainerFormat *pContainerFormat, bool, bool)
 Open this container and make it ready for reading or writing, optionally reading as far into the container as necessary to find all streams. More...
 
virtual IStreamCoder::CodecStandardsCompliance getStandardsCompliance ()
 Gets the current level of standards compliance. More...
 
virtual int32_t setStandardsCompliance (IStreamCoder::CodecStandardsCompliance compliance)
 Set the level of standards compliance. More...
 
virtual IContainerFormatgetContainerFormat ()
 Returns the IContainerFormat object being used for this IContainer, or null if the IContainer doesn't yet know. More...
 
virtual Type getType ()
 Find out the type of this container. More...
 
virtual int32_t close ()
 
virtual int32_t close (bool)
 Close the container. More...
 
virtual int32_t getNumStreams ()
 The number of streams in this container. More...
 
virtual StreamgetStream (int32_t position)
 Get the stream at the given position. More...
 
virtual StreamaddNewStream (int32_t id)
 
virtual int32_t readNextPacket (IPacket *packet)
 Reads the next packet into the IPacket. More...
 
virtual int32_t writePacket (IPacket *packet, bool forceInterleave)
 Writes the contents of the packet to the container. More...
 
virtual int32_t writePacket (IPacket *packet)
 Writes the contents of the packet to the container, but make sure the packets are interleaved. More...
 
virtual int32_t writeHeader ()
 Adds a header, if needed, for this container. More...
 
virtual int32_t writeTrailer ()
 Adds a trailer, if needed, for this container. More...
 
AVFormatContext * getFormatContext ()
 
virtual int32_t queryStreamMetaData ()
 Attempts to read all the meta data in this stream, potentially by reading ahead and decoding packets. More...
 
virtual int32_t seekKeyFrame (int streamIndex, int64_t timestamp, int32_t flags)
 
virtual int64_t getDuration ()
 Gets the duration, if known, of this container. More...
 
virtual int64_t getStartTime ()
 Get the starting timestamp in microseconds of the first packet of the earliest stream in this container. More...
 
virtual int64_t getFileSize ()
 Get the file size in bytes of this container. More...
 
virtual int32_t getBitRate ()
 Get the calculated overall bit rate of this file. More...
 
virtual int32_t setPreload (int32_t preload)
 @Deprecated use setProperty instead. More...
 
virtual int32_t getPreload ()
 @Deprecated use getPropertyAsLong instead. More...
 
virtual int32_t setMaxDelay (int32_t maxdelay)
 Sets the max delay for the AVFormatContext.max_delay property. More...
 
virtual int32_t getMaxDelay ()
 Gets the AVFormatContext.max_delay property if possible. More...
 
virtual int32_t getNumProperties ()
 Returns the total number of settable properties on this object. More...
 
virtual IPropertygetPropertyMetaData (int32_t propertyNo)
 Returns the name of the numbered property. More...
 
virtual IPropertygetPropertyMetaData (const char *name)
 Returns the name of the numbered property. More...
 
virtual int32_t setProperty (const char *name, const char *value)
 Sets a property on this Object. More...
 
virtual int32_t setProperty (const char *name, double value)
 Looks up the property 'name' and sets the value of the property to 'value'. More...
 
virtual int32_t setProperty (const char *name, int64_t value)
 Looks up the property 'name' and sets the value of the property to 'value'. More...
 
virtual int32_t setProperty (const char *name, bool value)
 Looks up the property 'name' and sets the value of the property to 'value'. More...
 
virtual int32_t setProperty (const char *name, IRational *value)
 Looks up the property 'name' and sets the value of the property to 'value'. More...
 
virtual char * getPropertyAsString (const char *name)
 Gets a property on this Object. More...
 
virtual double getPropertyAsDouble (const char *name)
 Gets the value of this property, and returns as a double;. More...
 
virtual int64_t getPropertyAsLong (const char *name)
 Gets the value of this property, and returns as an long;. More...
 
virtual IRationalgetPropertyAsRational (const char *name)
 Gets the value of this property, and returns as an IRational;. More...
 
virtual bool getPropertyAsBoolean (const char *name)
 Gets the value of this property, and returns as a boolean. More...
 
virtual int32_t getFlags ()
 Get the flags associated with this object. More...
 
virtual void setFlags (int32_t newFlags)
 Set the flags to use with this object. More...
 
virtual bool getFlag (Flags flag)
 Get the setting for the specified flag. More...
 
virtual void setFlag (Flags flag, bool value)
 Set the flag. More...
 
virtual const char * getURL ()
 Get the URL the IContainer was opened with. More...
 
virtual int32_t flushPackets ()
 Flush all packets to output. More...
 
virtual int32_t getReadRetryCount ()
 Get the number of times IContainer#readNextPacket(IPacket) will retry a read if it gets a IError.Type#ERROR_AGAIN value back. More...
 
virtual void setReadRetryCount (int32_t count)
 Sets the read retry count. More...
 
virtual bool canStreamsBeAddedDynamically ()
 Can streams be added dynamically to this container? More...
 
virtual IMetaDatagetMetaData ()
 Get the IMetaData for this object, or null if none. More...
 
virtual void setMetaData (IMetaData *metaData)
 Set the IMetaData on this object, overriding any previous meta data. More...
 
virtual int32_t createSDPData (com::avpkit::ferry::IBuffer *buffer)
 Fills the given buffer with a null-terminated ASCII set of bytes representing SDP data that is suitable for use with an RTSP-based system. More...
 
virtual int32_t setForcedAudioCodec (ICodec::ID id)
 Forces the IContainer to assume all audio streams are encoded with the given audio codec when demuxing. More...
 
virtual int32_t setForcedVideoCodec (ICodec::ID id)
 Forces the IContainer to assume all video streams are encoded with the given video codec when demuxing. More...
 
virtual int32_t setForcedSubtitleCodec (ICodec::ID id)
 Forces the IContainer to assume all subtitle streams are encoded with the given subtitle codec when demuxing. More...
 
virtual int32_t seekKeyFrame (int32_t streamIndex, int64_t minTimeStamp, int64_t targetTimeStamp, int64_t maxTimeStamp, int32_t flags)
 EXPERIMENTAL - Seeks to timestamp in the container. More...
 
virtual StreamaddNewStream (ICodec::ID id)
 Add a new stream that will use the given codec. More...
 
virtual StreamaddNewStream (ICodec *codec)
 Add a new stream that will use the given codec. More...
 
virtual StreamaddNewStream (IStreamCoder *coder)
 Add a new stream that will use the given StreamCoder. More...
 
virtual ContainerFormatgetFormat ()
 Get the IContainerFormat that is used by this IContainer. More...
 
virtual int32_t setFormat (IContainerFormat *format)
 Set the IContainerFormat to use with this IContainer. More...
 
virtual int32_t setProperty (IMetaData *valuesToSet, IMetaData *valuesNotFound)
 
virtual int32_t open (const char *url, Type type, IContainerFormat *pContainerFormat, bool, bool, IMetaData *, IMetaData *)
 Open this container and make it ready for reading or writing, optionally reading as far into the container as necessary to find all streams. More...
 
int32_t setCustomIOProtocol (io::URLProtocolHandlerFactory *factory)
 
- Public Member Functions inherited from com::avpkit::core::IContainer
virtual int32_t seekKeyFrame (int32_t streamIndex, int64_t timestamp, int32_t flags)=0
 Seeks to the key frame at (or the first one after) the given timestamp. More...
 
- Public Member Functions inherited from com::avpkit::ferry::RefCounted
virtual int32_t acquire ()
 Internal Only. More...
 
virtual int32_t release ()
 Internal Only. More...
 
virtual RefCountedcopyReference ()
 Create a new Java object that refers to the same native object. More...
 
virtual int32_t getCurrentRefCount ()
 Return the current reference count on this object. More...
 
void setJavaAllocator (void *allocator)
 This method is public but not part of the standard API. More...
 
void * getJavaAllocator ()
 This method is public but not part of the standard API. More...
 

Static Public Member Functions

static Containermake (IContainerFormat *format)
 
- Static Public Member Functions inherited from com::avpkit::core::IContainer
static IContainermake ()
 Create a new container object. More...
 
static IContainermake (IContainerFormat *format)
 Create a new IContainer and call setFormat(IContainerFormat) on it immediately. More...
 

Additional Inherited Members

- Public Types inherited from com::avpkit::core::IContainer
enum  Type { READ , WRITE }
 The different types of Containers AVPKit supports. More...
 
enum  Flags {
  FLAG_GENPTS =0x0001 , FLAG_IGNIDX =0x0002 , FLAG_NONBLOCK =0x0004 , FLAG_IGNDTS =0x0008 ,
  FLAG_NOFILLIN =0x0010 , FLAG_NOPARSE =0x0020 , FLAG_NOBUFFER =0x0040 , FLAG_CUSTOM_IO =0x0080 ,
  FLAG_DISCARD_CORRUPT =0x0100 , FLAG_FLUSH_PACKETS =0x0200 , FLAG_BITEXACT =0x0400 , FLAG_MP4A_LATM =0x8000 ,
  FLAG_SORT_DTS =0x10000 , FLAG_PRIV_OPT =0x20000 , FLAG_KEEP_SIDE_DATA =0x40000 , FLAG_FAST_SEEK =0x80000 ,
  FLAG_SHORTEST =0x100000 , FLAG_AUTO_BSF =0x200000
}
 
typedef enum com::avpkit::core::IContainer::Type Type
 The different types of Containers AVPKit supports. More...
 
typedef enum com::avpkit::core::IContainer::Flags Flags
 
- Static Public Attributes inherited from com::avpkit::core::IContainer
static const int32_t SEEK_FLAG_BACKWARDS =1
 Flag; Seek backwards.
 
static const int32_t SEEK_FLAG_BYTE =2
 Flag; Use bytes instead of time stamps for seeking.
 
static const int32_t SEEK_FLAG_ANY =4
 Flag; Seek to any frame, even non-keyframes.
 
static const int32_t SEEK_FLAG_FRAME =8
 Flag; Seek based on frame number instead of time stamps.
 
- Protected Member Functions inherited from com::avpkit::ferry::RefCounted
virtual void destroy ()
 This method is called by RefCounted objects when their Ref Count reaches zero and they are about to be destroyed.
 
- Protected Attributes inherited from com::avpkit::ferry::RefCounted
AtomicIntegermRefCount
 This is the internal reference count, represented as an AtomicInteger to make sure it is thread safe.
 
void * mAllocator
 Not part of public API.
 

Detailed Description

Definition at line 40 of file Container.h.

Member Function Documentation

◆ addNewStream() [1/4]

Stream * com::avpkit::core::Container::addNewStream ( ICodec codec)
virtual

Add a new stream that will use the given codec.

Parameters
codecThe codec that will be used to insert packets.
Returns
An IStream for the new stream on success, or null on failure.
Since
5.0

Implements com::avpkit::core::IContainer.

Definition at line 1508 of file Container.cpp.

1509  {
1510  Codec* codec = static_cast<Codec*>(aCodec);
1511  Stream *retval=0;
1512  try
1513  {
1514  const AVCodec* avCodec = codec ? codec->getAVCodec() : 0;
1515 
1516  if (!mFormatContext)
1517  throw std::runtime_error("no format context");
1518 
1519  if (!isOpened())
1520  throw std::runtime_error("attempted to add stream to "
1521  " unopened container");
1522 
1523  if (isHeaderWritten())
1524  throw std::runtime_error("cannot add stream after header is written"
1525  );
1526 
1527  AVStream * stream=0;
1528  stream = avformat_new_stream(mFormatContext, avCodec);
1529 
1530 
1531  if (!stream)
1532  throw std::runtime_error("could not allocate stream");
1533 
1535  Stream::make(this, stream, IStream::OUTBOUND, avCodec)
1536  );
1537  if (!p) throw std::bad_alloc();
1538  if (*p)
1539  {
1540  mStreams.push_back(p);
1541  mNumStreams++;
1542  retval = p->get(); // acquire for caller
1543  }
1544  else
1545  {
1546  delete p;
1547  throw std::bad_alloc();
1548  }
1549  } catch (std::exception & e)
1550  {
1551  VS_LOG_DEBUG("Error: %s", e.what());
1552  VS_REF_RELEASE(retval);
1553  }
1554  return retval;
1555  }
virtual bool isHeaderWritten()
Has a header been successfully written?
Definition: Container.cpp:264
virtual bool isOpened()
Is this container opened?
Definition: Container.cpp:258
This class is only useful from C++.
Definition: RefPointer.h:47
T * get()
Call RefCounted::acquire() on the managed pointer and return it.
Definition: RefPointer.h:206

References com::avpkit::ferry::RefPointer< T >::get().

◆ addNewStream() [2/4]

Stream * com::avpkit::core::Container::addNewStream ( ICodec::ID  id)
virtual

Add a new stream that will use the given codec.

Parameters
idThe id for the codec used to insert packets. If you are adding an arbitrary data stream, use ICodec.ID#AV_CODEC_ID_NONE, otherwise use the ID of the code type you plan to use.
Returns
An IStream for the new stream on success, or null on failure.
Since
5.0

Implements com::avpkit::core::IContainer.

Definition at line 1485 of file Container.cpp.

1486  {
1487  Stream* retval=0;
1488  RefPointer<ICodec> codec;
1489  try
1490  {
1491  codec = ICodec::findEncodingCodec(id);
1492 
1493  if (!codec) {
1494  VS_LOG_ERROR("Could not find encoding codec: %d", id);
1495  throw std::runtime_error("Could not find encoding codec");
1496  }
1497  retval = addNewStream(codec.value());
1498  }
1499  catch (std::exception & e)
1500  {
1501  VS_LOG_DEBUG("Error: %s", e.what());
1502  VS_REF_RELEASE(retval);
1503  }
1504  return retval;
1505  }
virtual Stream * addNewStream(int32_t id)
Definition: Container.cpp:1587
static ICodec * findEncodingCodec(ICodec::ID id, const IPixelFormat::Type=IPixelFormat::NONE)
Find a codec that can be used for encoding or find a HW codec that can be used for encoding.
Definition: ICodec.cpp:38
T * value()
Return the managed pointer without calling RefCounted::acquire() on it.
Definition: RefPointer.h:226

References com::avpkit::ferry::RefPointer< T >::value().

◆ addNewStream() [3/4]

Stream * com::avpkit::core::Container::addNewStream ( int32_t  id)
virtual
Deprecated:
Use addNewStream(ICodec.ID) instead.

Creates a new stream in this container and returns it.

Parameters
idA format-dependent id for this stream.
Returns
A new stream.

Implements com::avpkit::core::IContainer.

Definition at line 1587 of file Container.cpp.

1588  {
1589  Stream *retval=0;
1590  retval = addNewStream((ICodec*)0);
1591  if (retval)
1592  retval->setId(id);
1593  return retval;
1594  }

References com::avpkit::core::Stream::setId().

◆ addNewStream() [4/4]

Stream * com::avpkit::core::Container::addNewStream ( IStreamCoder coder)
virtual

Add a new stream that will use the given StreamCoder.

The StreamCoder passed in MUST contain the IStreamCoder#getExtraData that was used to encode the packet.

Parameters
coderThe IStreamCoder that contains the meta-information needed for decoding the packets that will be muexed into this stream.
Returns
An IStream for the new stream on success, or null on failure.
Since
5.0

Implements com::avpkit::core::IContainer.

Definition at line 1558 of file Container.cpp.

1559  {
1560  Stream *retval=0;
1561  StreamCoder * coder = static_cast<StreamCoder*>(aCoder);
1562  RefPointer<ICodec> codec;
1563  try
1564  {
1565  if (!coder)
1566  throw std::runtime_error("must pass non-null coder");
1567  codec = coder->getCodec();
1568  if (!codec)
1569  throw std::runtime_error("StreamCoder has no attached Codec");
1570 
1571  retval = this->addNewStream(codec.value());
1572  if (retval)
1573  {
1574  if (retval->setStreamCoder(coder) < 0)
1575  throw std::runtime_error("Could not set StreamCoder on stream");
1576  }
1577 
1578  } catch (std::exception & e)
1579  {
1580  VS_LOG_DEBUG("addNewStream Error: %s", e.what());
1581  VS_REF_RELEASE(retval);
1582  }
1583  return retval;
1584  }

References com::avpkit::core::StreamCoder::getCodec(), com::avpkit::core::Stream::setStreamCoder(), and com::avpkit::ferry::RefPointer< T >::value().

◆ canStreamsBeAddedDynamically()

bool com::avpkit::core::Container::canStreamsBeAddedDynamically ( )
virtual

Can streams be added dynamically to this container?

Returns
true if streams can be added dynamically

Implements com::avpkit::core::IContainer.

Definition at line 1379 of file Container.cpp.

1380  {
1381  if (mFormatContext)
1382  return mFormatContext->ctx_flags & AVFMTCTX_NOHEADER;
1383  return false;
1384  }

◆ close()

int32_t com::avpkit::core::Container::close ( bool  dangling)
virtual

Close the container.

open() must have been called first, or else an error is returned.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

If this method exits because of an interruption, all resources will be closed anyway.

Returns
>= 0 on success; < 0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 649 of file Container.cpp.

650  {
651  int32_t retval = -1;
652  mMetaData.reset();
653 
654  if (mFormatContext && mIsOpened)
655  {
656  VS_ASSERT(mNumStreams == mStreams.size(),
657  "unexpected number of streams");
658 
659  if (mNeedTrailerWrite)
660  {
661  if (dangling)
662  // don't actually write the trailer when dangling; we could
663  // block on that, which could occur inside a finalizer thread
664  // or other unexpected thread
665  VS_LOG_ERROR("Disposing of dangling container but could not write trailer");
666  else {
667  VS_LOG_DEBUG("Writing dangling trailer");
668  (void) this->writeTrailer();
669  }
670  mNeedTrailerWrite = false;
671  }
672  mOpenCoders.clear();
673 
674  while(mStreams.size() > 0)
675  {
676  RefPointer<Stream> * stream=mStreams.back();
677 
678  VS_ASSERT(stream && *stream, "no stream?");
679  if (stream && *stream) {
680  (*stream)->containerClosed(this);
681  delete stream;
682  }
683  mStreams.pop_back();
684  }
685  mNumStreams = 0;
686 
687  // we need to remember the avio context
688  AVIOContext* pb = mFormatContext->pb;
689 
690  if (this->getType() == READ)
691  avformat_close_input(&mFormatContext);
692 
693  if (mCustomIOHandler) {
694  retval = mCustomIOHandler->url_close();
695  if (!mFormatContext) {
696  if (pb)
697  av_freep(&pb->buffer);
698  av_free(pb);
699  }
700  } else if (this->getType() != READ)
701  retval = avio_close(pb);
702  else
703  retval = 0;
704 
705  resetContext();
706  mIsOpened = false;
707  mIsMetaDataQueried=false;
708  }
709  AVPKIT_CHECK_INTERRUPT(retval);
710  return retval;
711  }
virtual Type getType()
Find out the type of this container.
Definition: Container.cpp:622
virtual int32_t writeTrailer()
Adds a trailer, if needed, for this container.
Definition: Container.cpp:952

◆ createSDPData()

int32_t com::avpkit::core::Container::createSDPData ( com::avpkit::ferry::IBuffer buffer)
virtual

Fills the given buffer with a null-terminated ASCII set of bytes representing SDP data that is suitable for use with an RTSP-based system.

This method only works if AVPKit is linking against a version of FFmpeg that supports RTSP.

Parameters
bufferthe com.avpkit.ferry.IBuffer object to fill with data.
Returns
the number of bytes written, including the terminating 0 byte, or < 0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 1413 of file Container.cpp.

1414  {
1415  if (!mFormatContext)
1416  return -1;
1417  if (!buffer)
1418  return -1;
1419 
1420  int32_t bufSize = buffer->getBufferSize();
1421  if (bufSize <= 0)
1422  return -1;
1423 
1424  char* bytes = static_cast<char*>(buffer->getBytes(0, bufSize));
1425  if (!bytes)
1426  return -1;
1427 
1428  bytes[0] = 0;
1429  // null terminate the buffer to ensure strlen below doesn't
1430  // overrun
1431  bytes[bufSize-1]=0;
1432  int32_t ret = av_sdp_create(&mFormatContext, 1, bytes, bufSize-1);
1433 
1434  if (ret < 0)
1435  {
1436  VS_LOG_INFO("Could not create SDP file: %d", ret);
1437  return ret;
1438  }
1439  // Otherwise, we have to figure out the length, including the
1440  // terminating null
1441  ret = strlen(bytes)+1;
1442  return ret;
1443  }
virtual void * getBytes(int32_t offset, int32_t length)=0
Returns up to length bytes, starting at offset in the underlying buffer we're managing.
virtual int32_t getBufferSize()=0
Get the current maximum number of bytes that can be safely placed in this buffer.

References com::avpkit::ferry::IBuffer::getBufferSize(), and com::avpkit::ferry::IBuffer::getBytes().

◆ flushPackets()

int32_t com::avpkit::core::Container::flushPackets ( )
virtual

Flush all packets to output.

Will only work on IContainer.Type#WRITE containers.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Returns
>= 0 on success; <0 on error

Implements com::avpkit::core::IContainer.

Definition at line 1299 of file Container.cpp.

1300  {
1301  int32_t retval = -1;
1302  try
1303  {
1304  if (this->getType() != WRITE)
1305  throw std::runtime_error("cannot write packet to read only container");
1306 
1307  if (!mFormatContext)
1308  throw std::runtime_error("no format context allocated");
1309 
1310  // Do the flush
1311  if (!(mFormatContext->oformat->flags & AVFMT_NOFILE)) {
1312  avio_flush(mFormatContext->pb);
1313  }
1314  retval = 0;
1315  }
1316  catch (std::exception & e)
1317  {
1318  VS_LOG_ERROR("Error: %s", e.what());
1319  retval = -1;
1320  }
1321  AVPKIT_CHECK_INTERRUPT(retval);
1322  return retval;
1323  }

◆ getBitRate()

int32_t com::avpkit::core::Container::getBitRate ( )
virtual

Get the calculated overall bit rate of this file.

This will only return a valid value if the container is non-streamed and supports seek.

Returns
The overall bit rate in bytes per second, or <0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 1113 of file Container.cpp.

1114  {
1115  int32_t retval = -1;
1117  if (mFormatContext)
1118  retval = mFormatContext->bit_rate;
1119  return retval;
1120  }
virtual int32_t queryStreamMetaData()
Attempts to read all the meta data in this stream, potentially by reading ahead and decoding packets.
Definition: Container.cpp:999

◆ getContainerFormat()

IContainerFormat * com::avpkit::core::Container::getContainerFormat ( )
virtual

Returns the IContainerFormat object being used for this IContainer, or null if the IContainer doesn't yet know.

Returns
the IContainerFormat object, or null.

Implements com::avpkit::core::IContainer.

Definition at line 405 of file Container.cpp.

406  {
407  ContainerFormat *retval = ContainerFormat::make();
408  if (retval)
409  {
410  if (mFormatContext)
411  {
412  if (mFormatContext->iformat)
413  retval->setInputFormat(mFormatContext->iformat);
414  if (mFormatContext->oformat)
415  retval->setOutputFormat(mFormatContext->oformat);
416  }
417  }
418  return retval;
419  }
static IContainerFormat * make()
Create a new IContainerFormat object.

References com::avpkit::core::ContainerFormat::setInputFormat(), and com::avpkit::core::ContainerFormat::setOutputFormat().

◆ getDuration()

int64_t com::avpkit::core::Container::getDuration ( )
virtual

Gets the duration, if known, of this container.

This will only work for non-streamable containers where IContainer can calculate the container size.

Returns
The duration, or Global#NO_PTS if not known.

Implements com::avpkit::core::IContainer.

Definition at line 1077 of file Container.cpp.

1078  {
1079  int64_t retval = Global::NO_PTS;
1081  if (mFormatContext)
1082  retval = mFormatContext->duration;
1083  return retval;
1084  }
static const int64_t NO_PTS
A value that means no time stamp is set for a given object.
Definition: Global.h:50

◆ getFileSize()

int64_t com::avpkit::core::Container::getFileSize ( )
virtual

Get the file size in bytes of this container.

This will only return a valid value if the container is non-streamed and supports seek.

Returns
The file size in bytes, or <0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 1097 of file Container.cpp.

1098  {
1099  int64_t retval = -1;
1101  if (mFormatContext) {
1102  if (mFormatContext->iformat && mFormatContext->iformat->flags & AVFMT_NOFILE)
1103  retval = 0;
1104  else {
1105  retval = avio_size(mFormatContext->pb);
1106  retval = FFMAX(0, retval);
1107  }
1108  }
1109  return retval;
1110  }

◆ getFlag()

bool com::avpkit::core::Container::getFlag ( Flags  flag)
virtual

Get the setting for the specified flag.

Parameters
flagThe flag you want to find the setting for
Returns
0 for false; non-zero for true

Implements com::avpkit::core::IContainer.

Definition at line 1267 of file Container.cpp.

1268  {
1269  bool result = false;
1270  if (mFormatContext)
1271  result = mFormatContext->flags& flag;
1272  return result;
1273  }

◆ getFlags()

int32_t com::avpkit::core::Container::getFlags ( )
virtual

Get the flags associated with this object.

Returns
The (compacted) value of all flags set.

Implements com::avpkit::core::IContainer.

Definition at line 1248 of file Container.cpp.

1249  {
1250  int32_t flags = (mFormatContext ? mFormatContext->flags : 0);
1251  // remove custom io if set
1252  flags &= ~(AVFMT_FLAG_CUSTOM_IO);
1253  return flags;
1254  }

◆ getFormat()

virtual ContainerFormat* com::avpkit::core::Container::getFormat ( )
inlinevirtual

Get the IContainerFormat that is used by this IContainer.

Returns
The format, or null if none is set yet.
Since
5.0

Implements com::avpkit::core::IContainer.

Definition at line 141 of file Container.h.

141 { return mFormat.get(); };

◆ getInputBufferLength()

int32_t com::avpkit::core::Container::getInputBufferLength ( )
virtual

Return the input buffer length.

Returns
The input buffer length AVPKit's told FFMPEG to assume. 0 means FFMPEG should choose it's own size (and it'll probably be 32768).

Implements com::avpkit::core::IContainer.

Definition at line 252 of file Container.cpp.

253  {
254  return mInputBufferLength;
255  }

◆ getMaxDelay()

int32_t com::avpkit::core::Container::getMaxDelay ( )
virtual

Gets the AVFormatContext.max_delay property if possible.

Returns
The max delay, error code otherwise.
Since
4.0

Implements com::avpkit::core::IContainer.

Definition at line 1153 of file Container.cpp.

1154  {
1155  int32_t retval = -1;
1156  if (mFormatContext)
1157  retval = mFormatContext->max_delay;
1158  return retval;
1159  }

◆ getMetaData()

IMetaData * com::avpkit::core::Container::getMetaData ( )
virtual

Get the IMetaData for this object, or null if none.

If the IContainer or IStream object that this IMetaData came from was opened for reading, then changes via IMetaData#setValue(String, String) will have no effect on the underlying media.

If the IContainer or IStream object that this IMetaData came from was opened for writing, then changes via IMetaData#setValue(String, String) will have no effect after IContainer#writeHeader() is called.

Returns
the IMetaData.

Implements com::avpkit::core::IContainer.

Definition at line 1387 of file Container.cpp.

1388  {
1389  if (!mMetaData && mFormatContext)
1390  {
1391  if (this->getType() == WRITE)
1392  mMetaData = MetaData::make(&mFormatContext->metadata);
1393  else
1394  // make a read-only copy so when libav deletes the
1395  // input version we don't delete our copy
1396  mMetaData = MetaData::make(mFormatContext->metadata);
1397  }
1398  return mMetaData.get();
1399  }
static IMetaData * make()
Create a new IMetaData bag of properties with no values set.
Definition: IMetaData.cpp:36

◆ getNumProperties()

int32_t com::avpkit::core::Container::getNumProperties ( )
virtual

Returns the total number of settable properties on this object.

Returns
total number of options (not including constant definitions)

Implements com::avpkit::core::IContainer.

Definition at line 1162 of file Container.cpp.

1163  {
1164  return Property::getNumProperties(mFormatContext);
1165  }
static int32_t getNumProperties(void *context)
For internal use.
Definition: Property.cpp:114

◆ getNumStreams()

int32_t com::avpkit::core::Container::getNumStreams ( )
virtual

The number of streams in this container.

If opened in IContainer.Type#READ mode, this will query the stream and find out how many streams are in it.

If opened in IContainer.Type#WRITE mode, this will return the number of streams the caller has added to date.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Returns
The number of streams in this container.

Implements com::avpkit::core::IContainer.

Definition at line 629 of file Container.cpp.

630  {
631  int32_t retval = 0;
632  if (mFormatContext)
633  {
634  if (mFormatContext->nb_streams != mNumStreams)
635  setupAllInputStreams();
636  retval = mFormatContext->nb_streams;
637  }
638  AVPKIT_CHECK_INTERRUPT(retval);
639  return retval;
640  }

◆ getPreload()

int32_t com::avpkit::core::Container::getPreload ( )
virtual

@Deprecated use getPropertyAsLong instead.

The amount container will attemtp to preload.

Returns
The amount to preload, error code otherwise.

Implements com::avpkit::core::IContainer.

Definition at line 1130 of file Container.cpp.

1131  {
1132  VS_LOG_WARN("Deprecated and will be removed; does nothing now.");
1133  return -1;
1134  }

◆ getPropertyAsBoolean()

bool com::avpkit::core::Container::getPropertyAsBoolean ( const char *  name)
virtual

Gets the value of this property, and returns as a boolean.

Parameters
namename of option
Returns
boolean value of property, or false on error.

Implements com::avpkit::core::IContainer.

Definition at line 1242 of file Container.cpp.

1243  {
1244  return Property::getPropertyAsBoolean(mFormatContext, aName);
1245  }
static bool getPropertyAsBoolean(void *context, const char *name)
Gets the value of this property, and returns as a boolean.
Definition: Property.cpp:491

◆ getPropertyAsDouble()

double com::avpkit::core::Container::getPropertyAsDouble ( const char *  name)
virtual

Gets the value of this property, and returns as a double;.

Parameters
namename of option
Returns
double value of property, or 0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 1224 of file Container.cpp.

1225  {
1226  return Property::getPropertyAsDouble(mFormatContext, aName);
1227  }
static double getPropertyAsDouble(void *context, const char *name)
Gets the value of this property, and returns as a double;.
Definition: Property.cpp:422

◆ getPropertyAsLong()

int64_t com::avpkit::core::Container::getPropertyAsLong ( const char *  name)
virtual

Gets the value of this property, and returns as an long;.

Parameters
namename of option
Returns
long value of property, or 0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 1230 of file Container.cpp.

1231  {
1232  return Property::getPropertyAsLong(mFormatContext, aName);
1233  }
static int64_t getPropertyAsLong(void *context, const char *name)
Gets the value of this property, and returns as an long;.
Definition: Property.cpp:446

◆ getPropertyAsRational()

IRational * com::avpkit::core::Container::getPropertyAsRational ( const char *  name)
virtual

Gets the value of this property, and returns as an IRational;.

Parameters
namename of option
Returns
long value of property, or 0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 1236 of file Container.cpp.

1237  {
1238  return Property::getPropertyAsRational(mFormatContext, aName);
1239  }
static IRational * getPropertyAsRational(void *context, const char *name)
Gets the value of this property, and returns as an IRational;.
Definition: Property.cpp:467

◆ getPropertyAsString()

char * com::avpkit::core::Container::getPropertyAsString ( const char *  name)
virtual

Gets a property on this Object.

Note for C++ callers; you must free the returned array with delete[] in order to avoid a memory leak. If you call from Java or any other language, you don't need to worry about this.

Parameters
nameproperty name
Returns
an string copy of the option value, or null if the option doesn't exist.

Implements com::avpkit::core::IContainer.

Definition at line 1218 of file Container.cpp.

1219  {
1220  return Property::getPropertyAsString(mFormatContext, aName);
1221  }
static char * getPropertyAsString(void *context, const char *name)
Gets the value of this property, and returns as a new[]ed string.
Definition: Property.cpp:238

◆ getPropertyMetaData() [1/2]

IProperty * com::avpkit::core::Container::getPropertyMetaData ( const char *  name)
virtual

Returns the name of the numbered property.

Parameters
nameThe property name.
Returns
an IProperty value for this properties meta-data

Implements com::avpkit::core::IContainer.

Definition at line 1174 of file Container.cpp.

1175  {
1176  return Property::getPropertyMetaData(mFormatContext, name);
1177  }
static IProperty * getPropertyMetaData(void *context, int32_t propertyNo)
Returns the metadata for the numbered property.
Definition: Property.cpp:133

◆ getPropertyMetaData() [2/2]

IProperty * com::avpkit::core::Container::getPropertyMetaData ( int32_t  propertyNo)
virtual

Returns the name of the numbered property.

Parameters
propertyNoThe property number in the options list.
Returns
an IProperty value for this properties meta-data

Implements com::avpkit::core::IContainer.

Definition at line 1168 of file Container.cpp.

1169  {
1170  return Property::getPropertyMetaData(mFormatContext, propertyNo);
1171  }

◆ getReadRetryCount()

int32_t com::avpkit::core::Container::getReadRetryCount ( )
virtual

Get the number of times IContainer#readNextPacket(IPacket) will retry a read if it gets a IError.Type#ERROR_AGAIN value back.

Defaults to 1 times. <0 means it will keep retrying indefinitely.

Returns
the read retry count

Implements com::avpkit::core::IContainer.

Definition at line 1326 of file Container.cpp.

1327  {
1328  return mReadRetryCount;
1329  }

◆ getStandardsCompliance()

IStreamCoder::CodecStandardsCompliance com::avpkit::core::Container::getStandardsCompliance ( )
virtual

Gets the current level of standards compliance.

Returns
The level of standards compliance.
See also
CodecStandardsCompliance
Since
5.7

Implements com::avpkit::core::IContainer.

Definition at line 387 of file Container.cpp.

388  {
389  return mFormatContext ? (IStreamCoder::CodecStandardsCompliance) mFormatContext->strict_std_compliance : IStreamCoder::COMPLIANCE_NORMAL;
390  }
CodecStandardsCompliance
An enumeration of how strictly Codecs may follow the spec.
Definition: IStreamCoder.h:959
@ COMPLIANCE_NORMAL
Take normal liberties with the spec, including taking the spec out to dinner, and making suggestive c...
Definition: IStreamCoder.h:972

◆ getStartTime()

int64_t com::avpkit::core::Container::getStartTime ( )
virtual

Get the starting timestamp in microseconds of the first packet of the earliest stream in this container.

This will only return value values either either (a) for non-streamable containers where IContainer can calculate the container size or (b) after IContainer has actually read the first packet from a streamable source.

Returns
The starting timestamp in microseconds, or Global#NO_PTS if not known.

Implements com::avpkit::core::IContainer.

Definition at line 1087 of file Container.cpp.

1088  {
1089  int64_t retval = Global::NO_PTS;
1091  if (mFormatContext)
1092  retval = mFormatContext->start_time;
1093  return retval;
1094  }

◆ getStream()

Stream * com::avpkit::core::Container::getStream ( int32_t  streamIndex)
virtual

Get the stream at the given position.

Parameters
streamIndexthe index of this stream in the container
Returns
The stream at that position in the container, or null if none there.

Implements com::avpkit::core::IContainer.

Definition at line 714 of file Container.cpp.

715  {
716  Stream *retval = 0;
717  if (mFormatContext)
718  {
719  if (mFormatContext->nb_streams != mNumStreams)
720  setupAllInputStreams();
721 
722  if (position < mNumStreams)
723  {
724  // will acquire for caller.
725  retval = (*mStreams.at(position)).get();
726  }
727  }
728  return retval;
729  }

◆ getType()

IContainer::Type com::avpkit::core::Container::getType ( )
virtual

Find out the type of this container.

Returns
The Type of this container.
IContainer.Type#READ if not yet opened.

Implements com::avpkit::core::IContainer.

Definition at line 622 of file Container.cpp.

623  {
624  return (!mFormatContext ? READ :
625  (mFormatContext->oformat ? WRITE: READ));
626  }

◆ getURL()

const char * com::avpkit::core::Container::getURL ( )
virtual

Get the URL the IContainer was opened with.

May return null if unknown.

Returns
the URL opened, or null.

Implements com::avpkit::core::IContainer.

Definition at line 1293 of file Container.cpp.

1294  {
1295  return mFormatContext && *mFormatContext->filename ? mFormatContext->filename : 0;
1296  }

◆ isHeaderWritten()

bool com::avpkit::core::Container::isHeaderWritten ( )
virtual

Has a header been successfully written?

Returns
true if yes, false if no.

Implements com::avpkit::core::IContainer.

Definition at line 264 of file Container.cpp.

265  {
266  return (mIsOpened && mNeedTrailerWrite);
267  }

◆ isOpened()

bool com::avpkit::core::Container::isOpened ( )
virtual

Is this container opened?

Returns
true if opened; false if not.

Implements com::avpkit::core::IContainer.

Definition at line 258 of file Container.cpp.

259  {
260  return mIsOpened;
261  }

◆ open() [1/3]

int32_t com::avpkit::core::Container::open ( const char *  url,
Type  type,
IContainerFormat pContainerFormat 
)
virtual

Open this container and make it ready for reading or writing.

The caller must call close() when done, but if not, the IContainer will eventually close them later but warn to the logging system.

This just forwards to open(String, Type, IContainerFormat, boolean, boolean) passing false for aStreamsCanBeAddedDynamically, and true for aLookForAllStreams.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Parameters
urlThe resource to open; The format of this string is any url that FFMPEG supports (including additional protocols if added through the core.io library).
typeThe type of this container.
pContainerFormatA pointer to a ContainerFormat object specifying the format of this container, or 0 (NULL) if you want us to guess.
Returns
>= 0 on success; < 0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 270 of file Container.cpp.

272  {
273  return open(url, type, pContainerFormat, false, true);
274  }
virtual int32_t open(const char *url, Type type, IContainerFormat *pContainerFormat)
Open this container and make it ready for reading or writing.
Definition: Container.cpp:270

◆ open() [2/3]

int32_t com::avpkit::core::Container::open ( const char *  url,
Type  type,
IContainerFormat pContainerFormat,
bool  aStreamsCanBeAddedDynamically,
bool  aQueryStreamMetaData 
)
virtual

Open this container and make it ready for reading or writing, optionally reading as far into the container as necessary to find all streams.

The caller must call close() when done, but if not, the IContainer will eventually close them later but warn to the logging system.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Parameters
urlThe resource to open; The format of this string is any url that FFMPEG supports (including additional protocols if added through the core.io library).
typeThe type of this container.
pContainerFormatA pointer to a ContainerFormat object specifying the format of this container, or 0 (NULL) if you want us to guess.
aStreamsCanBeAddedDynamicallyIf true, open() will expect that new streams can be added at any time, even after the format header has been read.
aQueryStreamMetaDataIf true, open() will call queryStreamMetaData() on this container, which will potentially block until it has ready enough data to find all streams in a container. If false, it will only block to read a minimal header for this container format.
Returns
>= 0 on success; < 0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 277 of file Container.cpp.

281  {
282  return open(url, type, pContainerFormat,
283  aStreamsCanBeAddedDynamically, aLookForAllStreams,
284  NULL, NULL);
285  }

◆ open() [3/3]

int32_t com::avpkit::core::Container::open ( const char *  url,
Type  type,
IContainerFormat containerFormat,
bool  streamsCanBeAddedDynamically,
bool  queryStreamMetaData,
IMetaData options,
IMetaData optionsNotSet 
)
virtual

Open this container and make it ready for reading or writing, optionally reading as far into the container as necessary to find all streams.

The caller must call close() when done, but if not, the IContainer will eventually close them later but warn to the logging system.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Parameters
urlThe resource to open; The format of this string is any url that FFMPEG supports (including additional protocols if added through the core.io library).
typeThe type of this container.
containerFormatA pointer to a ContainerFormat object specifying the format of this container, or 0 (NULL) if you want us to guess.
streamsCanBeAddedDynamicallyIf true, open() will expect that new streams can be added at any time, even after the format header has been read.
queryStreamMetaDataIf true, open() will call queryStreamMetaData() on this container, which will potentially block until it has ready enough data to find all streams in a container. If false, it will only block to read a minimal header for this container format.
optionsIf not null, a set of key-value pairs that will be set on the container immediately the format is determined. Some options cannot be set (especially for input containers) until the system has a chance to parse what data is in the file.
optionsNotSetIf not null, on return this IMetaData object will be cleared out, and replace with any key/value pairs that were in options but could not be set on this IContainer.
Returns
>= 0 on success; < 0 on error.
Since
5.0

Implements com::avpkit::core::IContainer.

Definition at line 287 of file Container.cpp.

293  {
294  AVDictionary *tmp= NULL;
295 
296  int32_t retval = -1;
297 
298  // reset if an open is called before a close.
299  reset();
300  if (!mFormatContext)
301  {
302  // always reset to a new one
303  mFormatContext = avformat_alloc_context();
304  if (!mFormatContext)
305  throw std::bad_alloc();
306  }
307 
308  if (pContainerFormat)
309  setFormat(pContainerFormat);
310 
311  // Set up thread interrupt handling.
312  mFormatContext->interrupt_callback.callback = Global::avioInterruptCB;
313  mFormatContext->interrupt_callback.opaque = this;
314 
315  // Let's check for custom IO
316  mCustomIOHandler = URLProtocolManager::findHandler(
317  url,
318  type == WRITE ? URLProtocolHandler::URL_WRONLY_MODE : URLProtocolHandler::URL_RDONLY_MODE,
319  0);
320  if (mCustomIOHandler) {
321  if (mInputBufferLength <= 0)
322  // default to 4k
323  mInputBufferLength = 4096;
324  // free and realloc the input buffer length
325  uint8_t* buffer = (uint8_t*)av_malloc(mInputBufferLength);
326  if (!buffer)
327  throw std::bad_alloc();
328 
329  // we will allocate ourselves an io context; ownership of buffer passes here.
330  mFormatContext->pb = avio_alloc_context(
331  buffer,
332  mInputBufferLength,
333  type == WRITE ? 1 : 0,
334  mCustomIOHandler,
335  Container_url_read,
336  Container_url_write,
337  mCustomIOHandler->url_seekflags(url,0) == URLProtocolHandler::SK_NOT_SEEKABLE ? NULL : Container_url_seek);//Container_url_seek is necessary for some media (mov format)
338  if (!mFormatContext->pb)
339  av_freep(&buffer);
340  }
341  // set up our options
342  if (aOptions) {
343  MetaData* options = static_cast<MetaData*>(aOptions);
344  if (!options)
345  throw std::runtime_error("um, this shouldn't ever happen");
346  // make a copy of the data returned
347  av_dict_copy(&tmp, options->getDictionary(), 0);
348  }
349  if (url && *url)
350  {
351  if (type == WRITE)
352  {
353  retval = openOutputURL(url,
354  aStreamsCanBeAddedDynamically, &tmp);
355  } else if (type == READ)
356  {
357  retval = openInputURL(url,
358  aStreamsCanBeAddedDynamically, aLookForAllStreams, &tmp);
359  }
360  else
361  {
362  VS_ASSERT(false, "Invalid type for open");
363  retval = -1;
364  }
365  }
366  AVPKIT_CHECK_INTERRUPT(retval);
367  if (aUnsetOptions) {
368  MetaData* unsetOptions = static_cast<MetaData*>(aUnsetOptions);
369  if (!unsetOptions)
370  throw std::runtime_error("a little part of me just died inside");
371  unsetOptions->copy(tmp);
372  }
373  if (tmp)
374  av_dict_free(&tmp);
375  return retval;
376  }
virtual int32_t setFormat(IContainerFormat *format)
Set the IContainerFormat to use with this IContainer.
Definition: Container.cpp:1338
static int avioInterruptCB(void *)
Internal Only.
Definition: Global.cpp:115

References com::avpkit::core::MetaData::copy(), and com::avpkit::core::MetaData::getDictionary().

◆ queryStreamMetaData()

int32_t com::avpkit::core::Container::queryStreamMetaData ( )
virtual

Attempts to read all the meta data in this stream, potentially by reading ahead and decoding packets.

Any packets this method reads ahead will be cached and correctly returned when you read packets, but this method can be non-blocking potentially until end of container to get all meta data. Take care when you call it.

After this method is called, other meta data methods like getDuration() should work.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Returns
>= 0 on success; <0 on failure.

Implements com::avpkit::core::IContainer.

Definition at line 999 of file Container.cpp.

1000  {
1001  int retval = -1;
1002  if (mIsOpened)
1003  {
1004  if (!mIsMetaDataQueried)
1005  {
1006  retval = avformat_find_stream_info(mFormatContext, NULL);
1007  // for shits and giggles, dump the ffmpeg output
1008  //av_dump_format(mFormatContext, 0, (mFormatContext ? mFormatContext->filename :0), 0);
1009  mIsMetaDataQueried = true;
1010  } else {
1011  retval = 0;
1012  }
1013 
1014  if (retval >= 0 && mFormatContext->nb_streams > 0)
1015  {
1016  setupAllInputStreams();
1017  } else {
1018  VS_LOG_WARN("Could not find streams in input container");
1019  }
1020  }
1021  else
1022  {
1023  VS_LOG_WARN("Attempt to queryStreamMetaData but container is not open");
1024  }
1025  AVPKIT_CHECK_INTERRUPT(retval);
1026  return retval;
1027  }

◆ readNextPacket()

int32_t com::avpkit::core::Container::readNextPacket ( IPacket packet)
virtual

Reads the next packet into the IPacket.

This method will release any buffers currently held by this packet and allocate new ones.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Parameters
packet[In/Out] The packet the IContainer will read into.
Returns
0 if successful, or <0 if not.

Implements com::avpkit::core::IContainer.

Definition at line 732 of file Container.cpp.

733  {
734  int32_t retval = -1;
735  Packet* pkt = static_cast<Packet*>(ipkt);
736  if (mFormatContext && pkt)
737  {
738 
739  bool useBsf = false;
740 
741 // pkt->reset();
742  int32_t numReads=0;
743  do
744  {
745  retval = av_read_frame(mFormatContext,
746  mPacket);
747  ++numReads;
748 
749  if (retval == 0) {
750  Stream* stream = this->getStream(mPacket->stream_index);
751  AVBSFContext* bsfContext = stream->getAVBsfContext();
752  VS_REF_RELEASE(stream);
753  if (bsfContext) {
754  useBsf = true;
755  if (retval = av_bsf_send_packet(bsfContext, mPacket) == 0) {
756  retval = av_bsf_receive_packet(bsfContext, mBsfPacket);
757  }
758  }
759  }
760  }
761  while (retval == AVERROR(EAGAIN) &&
762  (mReadRetryCount < 0 || numReads <= mReadRetryCount));
763 
764  if (retval >= 0)
765  if (!useBsf) {
766  pkt->wrapAVPacket(mPacket);
767  } else {
768  pkt->wrapAVPacket(mBsfPacket);
769  }
770  av_packet_unref(mPacket);
771  av_packet_unref(mBsfPacket);
772 
773 // // Get a pointer to the wrapped packet
774 // packet = pkt->getAVPacket();
775  // and dump it's contents
776  VS_LOG_TRACE("read-packet: %lld, %lld, %d, %d, %d, %lld, %lld: %p",
777  pkt->getDts(),
778  pkt->getPts(),
779  pkt->getFlags(),
780  pkt->getStreamIndex(),
781  pkt->getSize(),
782  pkt->getDuration(),
783  pkt->getPosition(),
784  pkt->getAVPacket()->data);
785 
786  // and let's try to set the packet time base if known
787  if (pkt->getStreamIndex() >= 0)
788  {
789  RefPointer<IStream> stream = this->getStream(pkt->getStreamIndex());
790  if (stream)
791  {
792  RefPointer<IRational> streamBase = stream->getTimeBase();
793  if (streamBase)
794  {
795  pkt->setTimeBase(streamBase.value());
796  }
797  }
798  }
799  }
800  AVPKIT_CHECK_INTERRUPT(retval);
801  return retval;
802  }
virtual Stream * getStream(int32_t position)
Get the stream at the given position.
Definition: Container.cpp:714

References com::avpkit::core::Packet::getDts(), com::avpkit::core::Packet::getDuration(), com::avpkit::core::Packet::getFlags(), com::avpkit::core::Packet::getPosition(), com::avpkit::core::Packet::getPts(), com::avpkit::core::Packet::getSize(), com::avpkit::core::Packet::getStreamIndex(), com::avpkit::core::Packet::setTimeBase(), and com::avpkit::ferry::RefPointer< T >::value().

◆ seekKeyFrame()

int32_t com::avpkit::core::Container::seekKeyFrame ( int32_t  streamIndex,
int64_t  minTimeStamp,
int64_t  targetTimeStamp,
int64_t  maxTimeStamp,
int32_t  flags 
)
virtual

EXPERIMENTAL - Seeks to timestamp in the container.

Seeking will be done so that the point from which all active streams can be presented successfully will be closest to targetTimeStamp and within minTimeStamp/maxTimeStamp.

If flags contain SEEK_FLAG_BYTE, then all time stamps are in bytes and are the file position (this may not be supported by all demuxers). If flags contain SEEK_FLAG_FRAME, then all time stamps are in frames in the stream with streamIndex (this may not be supported by all demuxers). Otherwise all time stamps are in units of the stream selected by stream_index or if stream_index is -1, in microseconds. If flags contain SEEK_FLAG_ANY, then non-keyframes are treated as keyframes (this may not be supported by all demuxers). If flags contain SEEK_FLAG_BACKWARDS, then we will attempt to search backwards in the container (this may not be supported by all demuxers and file protocols).

This is part of the new seek API which is still under construction. It may change in future AVPKit versions.

Parameters
streamIndexindex of the stream which is used as time base reference
minTimeStampsmallest acceptable time stamp.
targetTimeStamptarget time stamp.
maxTimeStamplargest acceptable time stamp.
flagsA bitmask of the SEEK_FLAG_* flags, or 0 to turn all flags off.
Returns
>=0 on success, error code otherwise
Since
3.4

Implements com::avpkit::core::IContainer.

Definition at line 1051 of file Container.cpp.

1053  {
1054  int32_t retval = -1;
1055 
1056  if (mIsOpened)
1057  {
1058  if (streamIndex >= (int32_t)mNumStreams)
1059  VS_LOG_WARN("Attempt to seek on streamIndex %d but only %d streams known about in container",
1060  streamIndex, mNumStreams);
1061  else
1062  retval = avformat_seek_file(mFormatContext, streamIndex,
1063  minTimeStamp,
1064  targetTimeStamp,
1065  maxTimeStamp,
1066  flags);
1067  }
1068  else
1069  {
1070  VS_LOG_WARN("Attempt to seekKeyFrame but container is not open");
1071  }
1072  AVPKIT_CHECK_INTERRUPT(retval);
1073  return retval;
1074  }

◆ setFlag()

void com::avpkit::core::Container::setFlag ( Flags  flag,
bool  value 
)
virtual

Set the flag.

Parameters
flagThe flag to set
valueThe value to set it to (true or false)

Implements com::avpkit::core::IContainer.

Definition at line 1276 of file Container.cpp.

1277  {
1278  if (mFormatContext)
1279  {
1280  if (value)
1281  {
1282  mFormatContext->flags |= flag;
1283  }
1284  else
1285  {
1286  mFormatContext->flags &= (~flag);
1287  }
1288  }
1289 
1290  }

◆ setFlags()

void com::avpkit::core::Container::setFlags ( int32_t  newFlags)
virtual

Set the flags to use with this object.

All values must be ORed (|) together.

See also
Flags
Parameters
newFlagsThe new set flags for this codec.

Implements com::avpkit::core::IContainer.

Definition at line 1257 of file Container.cpp.

1258  {
1259  if (mFormatContext) {
1260  mFormatContext->flags = newFlags;
1261  // force custom io
1262  mFormatContext->flags |= AVFMT_FLAG_CUSTOM_IO;
1263  }
1264  }

◆ setForcedAudioCodec()

int32_t com::avpkit::core::Container::setForcedAudioCodec ( ICodec::ID  id)
virtual

Forces the IContainer to assume all audio streams are encoded with the given audio codec when demuxing.

Parameters
idThe codec id
Returns
< 0 on error (e.g. not an audio codec); >= 0 on success.
Since
3.3

Implements com::avpkit::core::IContainer.

Definition at line 1446 of file Container.cpp.

1447  {
1448  int32_t retval=-1;
1449  if (mFormatContext && id != ICodec::AV_CODEC_ID_NONE)
1450  {
1452  if (codec && codec->getType() == ICodec::CODEC_TYPE_AUDIO)
1453  mFormatContext->audio_codec_id = (enum AVCodecID) id;
1454  }
1455  return retval;
1456  }
static ICodec * findDecodingCodec(ICodec::ID id, const IPixelFormat::Type=IPixelFormat::NONE)
Find a codec that can be used for decoding or find a HW codec that can be used for decoding.
Definition: ICodec.cpp:59

◆ setForcedSubtitleCodec()

int32_t com::avpkit::core::Container::setForcedSubtitleCodec ( ICodec::ID  id)
virtual

Forces the IContainer to assume all subtitle streams are encoded with the given subtitle codec when demuxing.

Parameters
idThe codec id
Returns
< 0 on error (e.g. not an subtitle codec); >= 0 on success.
Since
3.3

Implements com::avpkit::core::IContainer.

Definition at line 1472 of file Container.cpp.

1473  {
1474  int32_t retval=-1;
1475  if (mFormatContext && id != ICodec::AV_CODEC_ID_NONE)
1476  {
1478  if (codec && codec->getType() == ICodec::CODEC_TYPE_SUBTITLE)
1479  mFormatContext->subtitle_codec_id = (enum AVCodecID) id;
1480  }
1481  return retval;
1482  }

◆ setForcedVideoCodec()

int32_t com::avpkit::core::Container::setForcedVideoCodec ( ICodec::ID  id)
virtual

Forces the IContainer to assume all video streams are encoded with the given video codec when demuxing.

Parameters
idThe codec id
Returns
< 0 on error (e.g. not an video codec); >= 0 on success.
Since
3.3

Implements com::avpkit::core::IContainer.

Definition at line 1459 of file Container.cpp.

1460  {
1461  int32_t retval=-1;
1462  if (mFormatContext && id != ICodec::AV_CODEC_ID_NONE)
1463  {
1465  if (codec && codec->getType() == ICodec::CODEC_TYPE_VIDEO)
1466  mFormatContext->video_codec_id = (enum AVCodecID) id;
1467  }
1468  return retval;
1469  }

◆ setFormat()

int32_t com::avpkit::core::Container::setFormat ( IContainerFormat format)
virtual

Set the IContainerFormat to use with this IContainer.

If called when the IContainer is opened, or if previously called with a non-null value, an error is returned and no action is taken.

Parameters
formatThe format to use return 0 on success; <0 on failure
Since
5.0

Implements com::avpkit::core::IContainer.

Definition at line 1338 of file Container.cpp.

1339  {
1340  int32_t retval = -1;
1341  ContainerFormat* format = static_cast<ContainerFormat*>(aFormat);
1342  try {
1343  if (!format)
1344  throw std::runtime_error("no format set");
1345 
1346  if (!mFormatContext)
1347  throw std::runtime_error("no underlying AVFormatContext");
1348  if (mFormatContext->iformat || mFormatContext->oformat)
1349  throw std::runtime_error("format already set on this IContainer; cannot be reset");
1350  if (mIsOpened)
1351  throw std::runtime_error("container already opened");
1352 
1353  AVOutputFormat* oformat = format->getOutputFormat();
1354  AVInputFormat* iformat = format->getInputFormat();
1355 
1356  if (!iformat && !oformat)
1357  throw std::runtime_error("no input or output format set");
1358 
1359  // iformat, if set, always wins
1360  if (iformat) {
1361  mFormatContext->iformat = iformat;
1362  mFormatContext->oformat = 0;
1363  } else {
1364  // throw away the old context and use the new to get the correct options set up
1365  resetContext();
1366  mFormatContext = 0;
1367  if (avformat_alloc_output_context2(&mFormatContext, oformat, 0, 0)<0)
1368  throw std::runtime_error("could not allocate output context");
1369  }
1370  mFormat.reset(format, true);
1371  retval = 0;
1372  } catch (std::exception &e)
1373  {
1374  retval = -1;
1375  }
1376  return retval;
1377  }

◆ setInputBufferLength()

int32_t com::avpkit::core::Container::setInputBufferLength ( int32_t  size)
virtual

Set the buffer length AVPKit will suggest to FFMPEG for reading inputs.

If called when a IContainer is open, the call is ignored and -1 is returned.

Parameters
sizeThe suggested buffer size.
Returns
size on success; <0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 236 of file Container.cpp.

237  {
238  int32_t retval = -1;
239  if (mIsOpened)
240  {
241  VS_LOG_WARN("Attempting to set input buffer length while file is opened; ignoring");
242  }
243  else
244  {
245  mInputBufferLength = size;
246  retval = size;
247  }
248  return retval;
249  }

◆ setMaxDelay()

int32_t com::avpkit::core::Container::setMaxDelay ( int32_t  maxdelay)
virtual

Sets the max delay for the AVFormatContext.max_delay property.

Parameters
maxdelaymaximum delay for container
Returns
>= 0 on success, error code otherwise
Since
4.0

Implements com::avpkit::core::IContainer.

Definition at line 1137 of file Container.cpp.

1138  {
1139  int32_t retval = -1;
1140  if (mIsOpened || !mFormatContext)
1141  {
1142  VS_LOG_WARN("Attempting to set max delay while file is opened; ignoring");
1143  }
1144  else
1145  {
1146  mFormatContext->max_delay = maxdelay;
1147  retval = maxdelay;
1148  }
1149  return retval;
1150  }

◆ setMetaData()

void com::avpkit::core::Container::setMetaData ( IMetaData data)
virtual

Set the IMetaData on this object, overriding any previous meta data.

You should call this method on writable containers and before you call IContainer#writeHeader, as it probably won't do anything after that.

See also
getMetaData()

Implements com::avpkit::core::IContainer.

Definition at line 1401 of file Container.cpp.

1402  {
1403  MetaData* data = static_cast<MetaData*>(getMetaData());
1404  if (data) {
1405  data->copy(copy);
1406  // release for the get above
1407  data->release();
1408  }
1409  return;
1410  }
virtual IMetaData * getMetaData()
Get the IMetaData for this object, or null if none.
Definition: Container.cpp:1387

References com::avpkit::core::MetaData::copy(), and com::avpkit::ferry::RefCounted::release().

◆ setPreload()

int32_t com::avpkit::core::Container::setPreload ( int32_t  preload)
virtual

@Deprecated use setProperty instead.

If the container has not already been opened, sets the AVFormatContext.preload property which can be useful in some circumstances such as when dealing with mpeg formats.

Parameters
preloadamount to preload
Returns
>= 0 on success, error code otherwise
Since
4.0

Implements com::avpkit::core::IContainer.

Definition at line 1123 of file Container.cpp.

1124  {
1125  VS_LOG_WARN("Deprecated and will be removed; does nothing now.");
1126  return -1;
1127  }

◆ setProperty() [1/5]

int32_t com::avpkit::core::Container::setProperty ( const char *  name,
bool  value 
)
virtual

Looks up the property 'name' and sets the value of the property to 'value'.

Parameters
namename of option
valueValue of option
Returns
>= 0 on success; <0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 1204 of file Container.cpp.

1205  {
1206  return Property::setProperty(mFormatContext, aName, aValue);
1207  }
static int32_t setProperty(void *context, const char *name, const char *value)
Looks up the property 'name' in 'context' and sets the value of the property to 'value'.
Definition: Property.cpp:201

◆ setProperty() [2/5]

int32_t com::avpkit::core::Container::setProperty ( const char *  name,
const char *  value 
)
virtual

Sets a property on this Object.

All AVOptions supported by the underlying AVClass are supported.

Parameters
nameThe property name. For example "b" for bit-rate.
valueThe value of the property.
Returns
>= 0 if the property was successfully set; <0 on error

Implements com::avpkit::core::IContainer.

Definition at line 1186 of file Container.cpp.

1187  {
1188  return Property::setProperty(mFormatContext, aName, aValue);
1189  }

◆ setProperty() [3/5]

int32_t com::avpkit::core::Container::setProperty ( const char *  name,
double  value 
)
virtual

Looks up the property 'name' and sets the value of the property to 'value'.

Parameters
namename of option
valueValue of option
Returns
>= 0 on success; <0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 1192 of file Container.cpp.

1193  {
1194  return Property::setProperty(mFormatContext, aName, aValue);
1195  }

◆ setProperty() [4/5]

int32_t com::avpkit::core::Container::setProperty ( const char *  name,
int64_t  value 
)
virtual

Looks up the property 'name' and sets the value of the property to 'value'.

Parameters
namename of option
valueValue of option
Returns
>= 0 on success; <0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 1198 of file Container.cpp.

1199  {
1200  return Property::setProperty(mFormatContext, aName, aValue);
1201  }

◆ setProperty() [5/5]

int32_t com::avpkit::core::Container::setProperty ( const char *  name,
IRational value 
)
virtual

Looks up the property 'name' and sets the value of the property to 'value'.

Parameters
namename of option
valueValue of option
Returns
>= 0 on success; <0 on error.

Implements com::avpkit::core::IContainer.

Definition at line 1211 of file Container.cpp.

1212  {
1213  return Property::setProperty(mFormatContext, aName, aValue);
1214  }

◆ setReadRetryCount()

void com::avpkit::core::Container::setReadRetryCount ( int32_t  count)
virtual

Sets the read retry count.

See also
getReadRetryCount()
Parameters
countThe read retry count. <0 means keep trying.

Implements com::avpkit::core::IContainer.

Definition at line 1332 of file Container.cpp.

1333  {
1334  mReadRetryCount = aCount;
1335  }

◆ setStandardsCompliance()

int32_t com::avpkit::core::Container::setStandardsCompliance ( IStreamCoder::CodecStandardsCompliance  compliance)
virtual

Set the level of standards compliance.

Only paid attention to before the code is opened.

Parameters
complianceThe desired compliance level to set
Returns
0 on success; non-zero on failure
See also
CodecStandardsCompliance
Since
5.7

Implements com::avpkit::core::IContainer.

Definition at line 393 of file Container.cpp.

394  {
395  if (mFormatContext)
396  {
397  mFormatContext->strict_std_compliance = compliance;
398  return 0;
399  }
400  return -1;
401  }

◆ writeHeader()

int32_t com::avpkit::core::Container::writeHeader ( )
virtual

Adds a header, if needed, for this container.

Call this AFTER you've added all streams you want to add, opened all IStreamCoders for those streams (with proper configuration) and before you write the first frame. If you attempt to write a header but haven't opened all codecs, this method will log a warning, and your output file will likely be corrupt.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Returns
0 if successful. < 0 if not. Always -1 if this is a READ container.

Implements com::avpkit::core::IContainer.

Definition at line 883 of file Container.cpp.

884  {
885  int32_t retval = -1;
886  try {
887  if (this->getType() != WRITE)
888  throw std::runtime_error("cannot write packet to read only container");
889 
890  if (!mFormatContext)
891  throw std::runtime_error("no format context allocated");
892 
893 #ifdef VS_DEBUG
894  // for shits and giggles, dump the ffmpeg output
895  // dump_format(mFormatContext, 0, (mFormatContext ? mFormatContext->filename :0), 1);
896 #endif // VS_DEBUG
897 
898  // now we're going to walk through and record each open stream coder.
899  // this is needed to catch a potential error on writeTrailer().
900  mOpenCoders.clear();
901  int numStreams = getNumStreams();
902  if (numStreams < 0 &&
903  !(mFormatContext->ctx_flags & AVFMTCTX_NOHEADER))
904  throw std::runtime_error("no streams added to container");
905 
906  if (numStreams == 0)
907  {
909  if (format)
910  {
911  const char *shortName = format->getOutputFormatShortName();
912  if (shortName && !strcmp(shortName, "mp3"))
913  throw std::runtime_error("no streams added to mp3 container");
914  }
915  }
916  for(int i = 0; i < numStreams; i++)
917  {
918  RefPointer<IStream> stream = this->getStream(i);
919  if (stream)
920  {
921  RefPointer<IStreamCoder> coder = stream->getStreamCoder();
922  if (coder)
923  {
924  if (coder->isOpen())
925  // add to our open list
926  mOpenCoders.push_back(coder);
927  else
928  VS_LOG_TRACE("writing Header for container, but at least one codec (%d) is not opened first", i);
929  }
930  }
931  }
932  retval = avformat_write_header(mFormatContext,0);
933  if (retval < 0)
934  throw std::runtime_error("could not write header for container");
935 
936  // force a flush.
937  if (!(mFormatContext->oformat->flags & AVFMT_NOFILE)) {
938  avio_flush(mFormatContext->pb);
939  }
940  // and remember that a writeTrailer is needed
941  mNeedTrailerWrite = true;
942  }
943  catch (std::exception & e)
944  {
945  VS_LOG_ERROR("Error: %s", e.what());
946  retval = -1;
947  }
948  AVPKIT_CHECK_INTERRUPT(retval);
949  return retval;
950  }
virtual int32_t getNumStreams()
The number of streams in this container.
Definition: Container.cpp:629
virtual IContainerFormat * getContainerFormat()
Returns the IContainerFormat object being used for this IContainer, or null if the IContainer doesn't...
Definition: Container.cpp:405

◆ writePacket() [1/2]

int32_t com::avpkit::core::Container::writePacket ( IPacket packet)
virtual

Writes the contents of the packet to the container, but make sure the packets are interleaved.

This means the IContainer may have to queue up packets from one stream while waiting for packets from another.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Parameters
packet[In] The packet to write out.
Returns
# of bytes written if successful, or <0 if not.

Implements com::avpkit::core::IContainer.

Definition at line 804 of file Container.cpp.

805  {
806  return writePacket(ipkt, true);
807  }
virtual int32_t writePacket(IPacket *packet, bool forceInterleave)
Writes the contents of the packet to the container.
Definition: Container.cpp:809

◆ writePacket() [2/2]

int32_t com::avpkit::core::Container::writePacket ( IPacket packet,
bool  forceInterleave 
)
virtual

Writes the contents of the packet to the container.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Parameters
packet[In] The packet to write out.
forceInterleave[In] If true, then this IContainer will make sure all packets are interleaved by DTS (even across streams in a container). If false, the IContainer won't, and it's up to the caller to interleave if necessary.
Returns
# of bytes written if successful, or <0 if not.

Implements com::avpkit::core::IContainer.

Definition at line 809 of file Container.cpp.

810  {
811  int32_t retval = -1;
812  Packet *pkt = static_cast<Packet*>(ipkt);
813  try
814  {
815  if (this->getType() != WRITE)
816  throw std::runtime_error("cannot write packet to read only container");
817 
818  if (!mFormatContext)
819  throw std::logic_error("no format context");
820 
821  if (!pkt)
822  throw std::runtime_error("cannot write missing packet");
823 
824  if (!pkt->isComplete())
825  throw std::runtime_error("cannot write incomplete packet");
826 
827 // if (!pkt->getSize())
828 // throw std::runtime_error("cannot write empty packet");
829 
830  if (!mNeedTrailerWrite)
831  throw std::runtime_error("container has not written header yet");
832 
833  int32_t pktIndex = pkt->getStreamIndex();
834 
835  if ((uint32_t)pktIndex >= mNumStreams)
836  throw std::runtime_error("packet being written to stream that doesn't exist");
837 
838  RefPointer<Stream> *streamPtr = mStreams.at(pktIndex);
839  if (!streamPtr || !*streamPtr)
840  throw std::runtime_error("no stream set up for this packet");
841 
842  Stream* stream = streamPtr->value();
843 
844  // Create a new packet that wraps the input data; this
845  // just copies meta-data
846  RefPointer<Packet> outPacket = Packet::make(pkt, false);
847  // Stamp it with the stream data
848  if (stream->stampOutputPacket(outPacket.value()) <0)
849  throw std::runtime_error("could not stamp output packet");
850 
851  AVPacket *packet = 0;
852  packet = outPacket->getAVPacket();
853  if (!packet || !packet->data)
854  throw std::runtime_error("no data in packet");
855 
856  /*
857  VS_LOG_DEBUG("write-packet: %lld, %lld, %d, %d, %d, %lld, %lld: %p",
858  pkt->getDts(),
859  pkt->getPts(),
860  pkt->getFlags(),
861  pkt->getStreamIndex(),
862  pkt->getSize(),
863  pkt->getDuration(),
864  pkt->getPosition(),
865  packet->data);
866  */
867 
868  if (forceInterleave)
869  retval = av_interleaved_write_frame(mFormatContext, packet);
870  else
871  retval = av_write_frame(mFormatContext, packet);
872  }
873  catch (std::exception & e)
874  {
875  VS_LOG_ERROR("Error: %s", e.what());
876  retval = -1;
877  }
878  AVPKIT_CHECK_INTERRUPT(retval);
879  return retval;
880  }
static IPacket * make()
Allocate a new packet.
Definition: IPacket.cpp:37

References com::avpkit::core::Packet::getStreamIndex(), com::avpkit::core::Packet::isComplete(), com::avpkit::core::Stream::stampOutputPacket(), and com::avpkit::ferry::RefPointer< T >::value().

◆ writeTrailer()

int32_t com::avpkit::core::Container::writeTrailer ( )
virtual

Adds a trailer, if needed, for this container.

Call this AFTER you've written all data you're going to write to this container but BEFORE you call IStreamCoder#close() on your IStreamCoder objects.

You must call writeHeader() before you call this (and if you don't, the IContainer will warn loudly and not actually write the trailer).

If you have closed any of the IStreamCoder objects that were open when you called writeHeader(), then this method will fail.

If the current thread is interrupted while this blocking method is running the method will return with a negative value. To check if the method exited because of an interruption pass the return value to IError#make(int) and then check IError#getType() to see if it is IError.Type#ERROR_INTERRUPTED.

Returns
0 if successful. < 0 if not. Always <0 if this is a READ container.

Implements com::avpkit::core::IContainer.

Definition at line 952 of file Container.cpp.

953  {
954  int32_t retval = -1;
955  try
956  {
957  if (this->getType() != WRITE)
958  throw std::runtime_error("cannot write packet to read only container");
959 
960  if (!mFormatContext)
961  throw std::runtime_error("no format context allocated");
962 
963  if (mNeedTrailerWrite)
964  {
965  while(mOpenCoders.size()>0)
966  {
967  RefPointer<IStreamCoder> coder = mOpenCoders.front();
968  mOpenCoders.pop_front();
969  if (!coder->isOpen())
970  {
971  mOpenCoders.clear();
972  throw std::runtime_error("attempt to write trailer, but at least one used codec already closed");
973  }
974  }
975  retval = av_write_trailer(mFormatContext);
976  if (retval == 0)
977  {
978  if (!(mFormatContext->oformat->flags & AVFMT_NOFILE)) {
979  avio_flush(mFormatContext->pb);
980  }
981  }
982  } else {
983  VS_LOG_WARN("writeTrailer() with no matching call to writeHeader()");
984  }
985  }
986  catch (std::exception & e)
987  {
988  VS_LOG_ERROR("Error: %s", e.what());
989  retval = -1;
990  }
991  // regardless of whether or not the write trailer succeeded, since
992  // an attempt has occurred, we shouldn't call it twice.
993  mNeedTrailerWrite = false;
994  AVPKIT_CHECK_INTERRUPT(retval);
995  return retval;
996  }

The documentation for this class was generated from the following files: