FFmpeg FU-A packet description
+-+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| | FU indicator |
< == >+-+ +
+-+ | F | NRI | Type |
+-+
+-+
+-+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| | FU header |
< == >+-+ +
+-+ | S | E | R | Type |
+-+
-
/ / return 0 on packet, no more left, 1 on packet, 1 on partial packet
Static int h364_handle_packet (AVFormatContext * ctx, PayloadContext * data
AVStream * st, AVPacket * pkt, uint32_t * timestamp
Const uint8_t * buf, int len, uint16_t seq
Int flags)
{
Uint8_t nal
Uint8_t type
Int result = 0
If (! len) {
Av_log (ctx, AV_LOG_ERROR, "Empty H.264 RTP packet\ n")
Return AVERROR_INVALIDDATA
}
Nal = buf [0]; / / the first byte is FU indicator
Type = nal & 0x1f / take the next five bytes
/ * Simplify the case (these are all the NAL types used internally by
* the H.264 codec). , /
If (type > = 1 & & type data, start_sequence, sizeof (start_sequence))
Memcpy (pkt- > data + sizeof (start_sequence), buf, len)
COUNT_NAL_TYPE (data, nal)
Break
Case 24: / / STAP-A (one packet, multiple nals)
/ / consume the STAP-A NAL
Buf++
Len--
Result = ff_h364_handle_aggregated_packet (ctx, data, pkt, buf, len, 0
NAL_COUNTERS, NAL_MASK)
Break
Case 25: / / STAP-B
Case 26: / / MTAP-16
Case 27: / / MTAP-24
Case 29: / / FU-B
Avpriv_report_missing_feature (ctx, "RTP H.264 NAL unit type d", type)
Result = AVERROR_PATCHWELCOME
Break
Case 28: / / FU-A (fragmented nal)
Result = h364_handle_packet_fu_a (ctx, data, pkt, buf, len
NAL_COUNTERS, NAL_MASK)
Break
Case 30: / / undefined
Case 31: / / undefined
Default:
Av_log (ctx, AV_LOG_ERROR, "Undefined type (% d)\ n", type)
Result = AVERROR_INVALIDDATA
Break
}
Pkt- > stream_index = st- > index
Return result
}
Static int h364_handle_packet_fu_a (AVFormatContext * ctx, PayloadContext * data, AVPacket * pkt
Const uint8_t * buf, int len
Int * nal_counters, int nal_mask)
{
Uint8_t fu_indicator, fu_header, start_bit, nal_type, nal
If (len
< 3) { av_log(ctx, AV_LOG_ERROR, "Too short data for FU-A H.264 RTP packet\n"); return AVERROR_INVALIDDATA; } fu_indicator = buf[0]; fu_header = buf[1]; start_bit = fu_header >> 7
Nal_type = fu_header & 0x1f
Nal = fu_indicator & 0xe0 | nal_type
/ / skip the fu_indicator and fu_header
Buf + = 2
Len-= 2
If (start_bit & & nal_counters)
Nal_ counters [nal _ type & nal_mask] + +
Return ff_h364_handle_frag_packet (pkt, buf, len, start_bit, & nal, 1)
}
FU identifier
0... .... = F bit: No bit errors or other syntax violations
.10. .... = Nal_ref_idc (NRI): 2
... 1 1100 = Type: Fragmentation unit A (FU-A) (28)
FU Header
1... .... = Start bit: the first packet of FU-A picture
.0.. .... = End bit: Not the last packet of FU-A picture
.. 0. .... = Forbidden bit: 0
... 0 0001 = Nal_unit_type: Coded slice of a non-IDR picture (1)