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
rtpdec_ac3.c
Go to the documentation of this file.
1
/*
2
* RTP parser for AC3 payload format (RFC 4184)
3
* Copyright (c) 2015 Gilles Chanteperdrix <gch@xenomai.org>
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
#include "
avformat.h
"
23
#include "
avio_internal.h
"
24
#include "
rtpdec_formats.h
"
25
26
#define RTP_AC3_PAYLOAD_HEADER_SIZE 2
27
28
struct
PayloadContext
{
29
unsigned
nr_frames
;
30
unsigned
last_frame
;
31
uint32_t
timestamp
;
32
AVIOContext
*
fragment
;
33
};
34
35
static
void
ac3_close_context
(
PayloadContext
*
data
)
36
{
37
ffio_free_dyn_buf
(&data->
fragment
);
38
}
39
40
static
int
ac3_handle_packet
(
AVFormatContext
*ctx,
PayloadContext
*
data
,
41
AVStream
*st,
AVPacket
*
pkt
, uint32_t *timestamp,
42
const
uint8_t
*
buf
,
int
len
, uint16_t seq,
43
int
flags
)
44
{
45
unsigned
frame_type;
46
unsigned
nr_frames;
47
int
err;
48
49
if
(len <
RTP_AC3_PAYLOAD_HEADER_SIZE
+ 1) {
50
av_log
(ctx,
AV_LOG_ERROR
,
"Invalid %d bytes packet\n"
, len);
51
return
AVERROR_INVALIDDATA
;
52
}
53
54
frame_type = buf[0] & 0x3;
55
nr_frames = buf[1];
56
buf +=
RTP_AC3_PAYLOAD_HEADER_SIZE
;
57
len -=
RTP_AC3_PAYLOAD_HEADER_SIZE
;
58
59
switch
(frame_type) {
60
case
0:
/* One or more complete frames */
61
if
(!nr_frames) {
62
av_log
(ctx,
AV_LOG_ERROR
,
"Invalid AC3 packet data\n"
);
63
return
AVERROR_INVALIDDATA
;
64
}
65
if
(
av_new_packet
(pkt, len)) {
66
av_log
(ctx,
AV_LOG_ERROR
,
"Out of memory.\n"
);
67
return
AVERROR
(ENOMEM);
68
}
69
70
pkt->
stream_index
= st->
index
;
71
memcpy(pkt->
data
, buf, len);
72
return
0;
73
74
case
1:
75
case
2:
/* First fragment */
76
ffio_free_dyn_buf
(&data->
fragment
);
77
78
data->
last_frame
= 1;
79
data->
nr_frames
= nr_frames;
80
err =
avio_open_dyn_buf
(&data->
fragment
);
81
if
(err < 0)
82
return
err;
83
84
avio_write
(data->
fragment
, buf, len);
85
data->
timestamp
= *timestamp;
86
return
AVERROR
(EAGAIN);
87
88
case
3:
/* Fragment other than first */
89
if
(!data->
fragment
) {
90
av_log
(ctx,
AV_LOG_WARNING
,
91
"Received packet without a start fragment; dropping.\n"
);
92
return
AVERROR
(EAGAIN);
93
}
94
if
(nr_frames != data->
nr_frames
||
95
data->
timestamp
!= *timestamp) {
96
ffio_free_dyn_buf
(&data->
fragment
);
97
av_log
(ctx,
AV_LOG_ERROR
,
"Invalid packet received\n"
);
98
return
AVERROR_INVALIDDATA
;
99
}
100
101
avio_write
(data->
fragment
, buf, len);
102
data->
last_frame
++;
103
}
104
105
if
(!(flags &
RTP_FLAG_MARKER
))
106
return
AVERROR
(EAGAIN);
107
108
if
(data->
last_frame
!= data->
nr_frames
) {
109
ffio_free_dyn_buf
(&data->
fragment
);
110
av_log
(ctx,
AV_LOG_ERROR
,
"Missed %d packets\n"
,
111
data->
nr_frames
- data->
last_frame
);
112
return
AVERROR_INVALIDDATA
;
113
}
114
115
err =
ff_rtp_finalize_packet
(pkt, &data->
fragment
, st->
index
);
116
if
(err < 0) {
117
av_log
(ctx,
AV_LOG_ERROR
,
118
"Error occurred when getting fragment buffer.\n"
);
119
return
err;
120
}
121
122
return
0;
123
}
124
125
RTPDynamicProtocolHandler
ff_ac3_dynamic_handler
= {
126
.
enc_name
=
"ac3"
,
127
.codec_type =
AVMEDIA_TYPE_AUDIO
,
128
.codec_id =
AV_CODEC_ID_AC3
,
129
.need_parsing =
AVSTREAM_PARSE_FULL
,
130
.priv_data_size =
sizeof
(
PayloadContext
),
131
.close =
ac3_close_context
,
132
.
parse_packet
=
ac3_handle_packet
,
133
};
Generated on Sun Mar 8 2015 02:35:12 for FFmpeg by
1.8.2