FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
rtpenc_h264.c
Go to the documentation of this file.
1
/*
2
* RTP packetization for H.264 (RFC3984)
3
* Copyright (c) 2008 Luca Abeni
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* FFmpeg is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
/**
23
* @file
24
* @brief H.264 packetization
25
* @author Luca Abeni <lucabe72@email.it>
26
*/
27
28
#include "
libavutil/intreadwrite.h
"
29
30
#include "
avformat.h
"
31
#include "
avc.h
"
32
#include "
rtpenc.h
"
33
34
static
void
flush_buffered
(
AVFormatContext
*
s1
,
int
last)
35
{
36
RTPMuxContext
*
s
= s1->
priv_data
;
37
if
(s->
buf_ptr
!= s->
buf
) {
38
// If we're only sending one single NAL unit, send it as such, skip
39
// the STAP-A framing
40
if
(s->
buffered_nals
== 1)
41
ff_rtp_send_data
(s1, s->
buf
+ 3, s->
buf_ptr
- s->
buf
- 3, last);
42
else
43
ff_rtp_send_data
(s1, s->
buf
, s->
buf_ptr
- s->
buf
, last);
44
}
45
s->
buf_ptr
= s->
buf
;
46
s->
buffered_nals
= 0;
47
}
48
49
static
void
nal_send
(
AVFormatContext
*
s1
,
const
uint8_t
*
buf
,
int
size
,
int
last)
50
{
51
RTPMuxContext
*
s
= s1->
priv_data
;
52
53
av_log
(s1,
AV_LOG_DEBUG
,
"Sending NAL %x of len %d M=%d\n"
, buf[0] & 0x1F, size, last);
54
if
(
size <= s->
max_payload_size) {
55
int
buffered_size = s->
buf_ptr
- s->
buf
;
56
// Flush buffered NAL units if the current unit doesn't fit
57
if
(buffered_size + 2 + size > s->
max_payload_size
) {
58
flush_buffered
(s1, 0);
59
buffered_size = 0;
60
}
61
// If we aren't using mode 0, and the NAL unit fits including the
62
// framing (2 bytes length, plus 1 byte for the STAP-A marker),
63
// write the unit to the buffer as a STAP-A packet, otherwise flush
64
// and send as single NAL.
65
if
(buffered_size + 3 +
size <= s->
max_payload_size &&
66
!(s->
flags
&
FF_RTP_FLAG_H264_MODE0
)) {
67
if
(buffered_size == 0)
68
*s->
buf_ptr
++ = 24;
69
AV_WB16
(s->
buf_ptr
, size);
70
s->
buf_ptr
+= 2;
71
memcpy(s->
buf_ptr
, buf, size);
72
s->
buf_ptr
+=
size
;
73
s->
buffered_nals
++;
74
}
else
{
75
flush_buffered
(s1, 0);
76
ff_rtp_send_data
(s1, buf, size, last);
77
}
78
}
else
{
79
uint8_t
type
= buf[0] & 0x1F;
80
uint8_t
nri = buf[0] & 0x60;
81
82
flush_buffered
(s1, 0);
83
if
(s->
flags
&
FF_RTP_FLAG_H264_MODE0
) {
84
av_log
(s1,
AV_LOG_ERROR
,
85
"NAL size %d > %d, try -slice-max-size %d\n"
, size,
86
s->
max_payload_size
, s->
max_payload_size
);
87
return
;
88
}
89
av_log
(s1,
AV_LOG_DEBUG
,
"NAL size %d > %d\n"
, size, s->
max_payload_size
);
90
s->
buf
[0] = 28;
/* FU Indicator; Type = 28 ---> FU-A */
91
s->
buf
[0] |= nri;
92
s->
buf
[1] =
type
;
93
s->
buf
[1] |= 1 << 7;
94
buf += 1;
95
size -= 1;
96
while
(size + 2 > s->
max_payload_size
) {
97
memcpy(&s->
buf
[2], buf, s->
max_payload_size
- 2);
98
ff_rtp_send_data
(s1, s->
buf
, s->
max_payload_size
, 0);
99
buf += s->
max_payload_size
- 2;
100
size -= s->
max_payload_size
- 2;
101
s->
buf
[1] &= ~(1 << 7);
102
}
103
s->
buf
[1] |= 1 << 6;
104
memcpy(&s->
buf
[2], buf, size);
105
ff_rtp_send_data
(s1, s->
buf
, size + 2, last);
106
}
107
}
108
109
void
ff_rtp_send_h264
(
AVFormatContext
*
s1
,
const
uint8_t
*buf1,
int
size
)
110
{
111
const
uint8_t
*
r
, *
end
= buf1 +
size
;
112
RTPMuxContext
*
s
= s1->
priv_data
;
113
114
s->
timestamp
= s->
cur_timestamp
;
115
s->
buf_ptr
= s->
buf
;
116
if
(s->
nal_length_size
)
117
r =
ff_avc_mp4_find_startcode
(buf1, end, s->
nal_length_size
) ? buf1 :
end
;
118
else
119
r =
ff_avc_find_startcode
(buf1, end);
120
while
(r < end) {
121
const
uint8_t
*r1;
122
123
if
(s->
nal_length_size
) {
124
r1 =
ff_avc_mp4_find_startcode
(r, end, s->
nal_length_size
);
125
if
(!r1)
126
r1 =
end
;
127
r += s->
nal_length_size
;
128
}
else
{
129
while
(!*(r++));
130
r1 =
ff_avc_find_startcode
(r, end);
131
}
132
nal_send
(s1, r, r1 - r, r1 == end);
133
r = r1;
134
}
135
flush_buffered
(s1, 1);
136
}
Generated on Tue Feb 24 2015 19:21:33 for FFmpeg by
1.8.2