#2. FFmpeg data.

#2.1. Reading frame data.
There is no way to check if av_read_frame returns a valid frame by using the frame data exclusively.
Testing AVPacket->buf, AVPacket->data, AVPacket->buf.data will not yield NULL resulst.
Testing AVPacket->buf->size or AVPacket->size will also return data values similar to valid frames.

The following example show av_read_frame() called three times:
- Valid frame:
Is Buffer empty = 0, buffer size should be = 481 , 
avcodec_decode_video2() rez = 0,
Packet size = 417, duration = 1024,
data = !\^Z\M-I

- Invalid frame:
Is Buffer empty = 0, buffer size should be = 882 ,
avcodec_decode_video2() rez = 1,
Packet size = 818, duration = 3750,
data =

- Invalid frame:
Is Buffer empty = 0, buffer size should be = 75 ,
avcodec_decode_video2() rez = 1,
Packet size = 11, duration = 3750,
data =

The only valid way is to use avcodec_decode_video2(). Decoding video will set a flag to 1 if the decoding couldn't be done because the frame was not valid.

#2.2. Decoding frame data.
- Decoding video from a read packet will fail several times because the frame isn't fully assembled.

- Decoding video from a read packet will succeed when the frame is fully assembled.

- Logging the read packet (.data) will show no data when the frame is incomplete.
Is Buffer empty = 0, buffer size should be = 75 ,readFrame rez = 1,
Packet size = 11, duration = 3750,
data =

- Logging the read packet (.data) will show data when the frame is complete.
Is Buffer empty = 0, buffer size should be = 451 ,readFrame rez = 0,
Packet size = 387, duration = 1024,
data = !\^Z\M-J\^B


- Decoding audio from a read packet will always succeed.



#3. FFmpeg & multi-channel audio.

#2. How FFmpeg acquires stream data.
#2.1. A session context (AVFormatContext) is created.
#2.1.1. The session context is created by allocating it with: avformat_alloc_contex()
#2.1.2. The created session context is setup with given options using: av_dict_free(options);
#2.2. The created and setup session context is used to open a stream using: avformat_open_input(_,_,_,_)
#2.3. Data is read from the context using: av_read_frame(_,_)
#2.4. Read data is immediately saved into a AVPacket.
The AVPacket contains two types of encoded data: audio and video frames.


#3.1. General Audio.
Audio data can be stored in a two FFmpeg structs: AVPacket or AVFrame.
AVPacket is more general and less convenient.

Audio data is stored along side video data in a given FFmpeg struct. The data is encoded and requires decoding. Decoding is done for both audio and video with different methods.
The input for decoding will be the AVPacket and the output will be a AVFrame struct.

One AVPacket has exactly one video frame (stored in AVFrame).
One AVPacket can have at least one or more audio frame data (stored in one or more AVFrames).
One AVFrame can't have more than one video or audio frame data.

The video frame is accessed by decoding data from the AVPacket.
The audio frames are accessed by decoding data from AVPacket multiple times while decrementing AVPackt->size resulting in one or more AVFrames.

#3.2. Audio Data Conversion
FFmpeg doesn't explain clearly where and how it's audio is stored. After all steps are done
to access the raw audio additional steps need to be taken with care to convert the data 
into proper audio samples which will be used for consumption.

One example for this is the keyword used to describe interleaved audio data. It's called non-planar.
Non-planar and planar audio formats are explained in #3.2. FFmpeg Audio Formats. The important thing to note is that this doesn't define how the stored data should be stored further. 

FFmpeg doesn't further communicate some audio know-how.

#3.2. FFmpeg Audio Formats
The examples below explain how data is managed in the mentioned audio formats.
The non-planar format has interleaved audio channel data.
c1 c2 c1 c2 c1 c2 c1 c2 ... next sample sequence (s)
The planar format has non-interleaved audio channel data.
c1 c1 c1 c1 ... c2 c2 c2 c2 ... next sample sequence (s)

#3.4. Audio storage.
How audio is stored is explained by the AVFrame->format property.
This property is a AVSampleFormat.
At the end of some AVSampleFormat enum types is a letter P. This  stands for planar (non-interleaved).
When the P at the end is missing then the audio is  non-planar (interleaved).

#3.4.1. Planar audio.
AVFrame->data[i] will contain the data of channel (assuming 0 is first channel).
#3.4.2. Non-planar audio.
AVFrame->data[0] will containt data for all channels in interleaved manner.
#3.4.3. More than 8 channel audio.
AVFrame->extended_data will contain all other channel data because AVFrame->data can only hold 8 channels.


#4. Performance

FFmpeg was built to be used with UDP. TCP can be used as a hacky solution. The reasons are explained below:
Source: https://github.com/ZoneMinder/zoneminder/issues/323
Setting the buffer size makes packed drops and misses worse:
av_dict_set(&_sessionOptions, "buffer_size", "2000000", 0);
Using no buffer works much better with less packed drops:
av_dict_set(&_sessionOptions, "fflags", "nobuffer", 0);
