ffmpeg / libavformat / rtpdec_svq3.c @ b9f9e59a
History | View | Annotate | Download (4.04 KB)
1 |
/*
|
---|---|
2 |
* Sorenson-3 (SVQ3/SV3V) payload for RTP
|
3 |
* Copyright (c) 2010 Ronald S. Bultje
|
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 RTP support for the SV3V (SVQ3) payload
|
25 |
* (http://wiki.multimedia.cx/index.php?title=Sorenson_Video_3#Packetization)
|
26 |
* @author Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
27 |
*/
|
28 |
|
29 |
#include <string.h> |
30 |
#include "libavutil/intreadwrite.h" |
31 |
#include "rtp.h" |
32 |
#include "rtpdec.h" |
33 |
#include "rtpdec_formats.h" |
34 |
|
35 |
struct PayloadContext {
|
36 |
ByteIOContext *pktbuf; |
37 |
int64_t timestamp; |
38 |
int is_keyframe;
|
39 |
}; |
40 |
|
41 |
/** return 0 on packet, <0 on partial packet or error... */
|
42 |
static int svq3_parse_packet (AVFormatContext *s, PayloadContext *sv, |
43 |
AVStream *st, AVPacket *pkt, |
44 |
uint32_t *timestamp, |
45 |
const uint8_t *buf, int len, int flags) |
46 |
{ |
47 |
int config_packet, start_packet, end_packet;
|
48 |
|
49 |
if (len < 2) |
50 |
return AVERROR_INVALIDDATA;
|
51 |
|
52 |
config_packet = buf[0] & 0x40; |
53 |
start_packet = buf[0] & 0x20; |
54 |
end_packet = buf[0] & 0x10; |
55 |
buf += 2; // ignore buf[1] |
56 |
len -= 2;
|
57 |
|
58 |
if (config_packet) {
|
59 |
|
60 |
av_freep(&st->codec->extradata); |
61 |
st->codec->extradata_size = 0;
|
62 |
|
63 |
if (len < 2 || !(st->codec->extradata = |
64 |
av_malloc(len + 8 + FF_INPUT_BUFFER_PADDING_SIZE)))
|
65 |
return AVERROR_INVALIDDATA;
|
66 |
|
67 |
st->codec->extradata_size = len + 8;
|
68 |
memcpy(st->codec->extradata, "SEQH", 4); |
69 |
AV_WB32(st->codec->extradata + 4, len);
|
70 |
memcpy(st->codec->extradata + 8, buf, len);
|
71 |
|
72 |
/* We set codec_id to CODEC_ID_NONE initially to
|
73 |
* delay decoder initialization since extradata is
|
74 |
* carried within the RTP stream, not SDP. Here,
|
75 |
* by setting codec_id to CODEC_ID_SVQ3, we are signalling
|
76 |
* to the decoder that it is OK to initialize. */
|
77 |
st->codec->codec_id = CODEC_ID_SVQ3; |
78 |
|
79 |
return AVERROR(EAGAIN);
|
80 |
} |
81 |
|
82 |
if (start_packet) {
|
83 |
int res;
|
84 |
|
85 |
if (sv->pktbuf) {
|
86 |
uint8_t *tmp; |
87 |
url_close_dyn_buf(sv->pktbuf, &tmp); |
88 |
av_free(tmp); |
89 |
} |
90 |
if ((res = url_open_dyn_buf(&sv->pktbuf)) < 0) |
91 |
return res;
|
92 |
sv->timestamp = *timestamp; |
93 |
sv->is_keyframe = flags & RTP_FLAG_KEY; |
94 |
} |
95 |
|
96 |
if (!sv->pktbuf)
|
97 |
return AVERROR_INVALIDDATA;
|
98 |
|
99 |
put_buffer(sv->pktbuf, buf, len); |
100 |
|
101 |
if (end_packet) {
|
102 |
av_init_packet(pkt); |
103 |
pkt->stream_index = st->index; |
104 |
*timestamp = sv->timestamp; |
105 |
pkt->flags = sv->is_keyframe ? AV_PKT_FLAG_KEY : 0;
|
106 |
pkt->size = url_close_dyn_buf(sv->pktbuf, &pkt->data); |
107 |
pkt->destruct = av_destruct_packet; |
108 |
sv->pktbuf = NULL;
|
109 |
return 0; |
110 |
} |
111 |
|
112 |
return AVERROR(EAGAIN);
|
113 |
} |
114 |
|
115 |
static PayloadContext *svq3_extradata_new(void) |
116 |
{ |
117 |
return av_mallocz(sizeof(PayloadContext)); |
118 |
} |
119 |
|
120 |
static void svq3_extradata_free(PayloadContext *sv) |
121 |
{ |
122 |
if (sv->pktbuf) {
|
123 |
uint8_t *buf; |
124 |
url_close_dyn_buf(sv->pktbuf, &buf); |
125 |
av_free(buf); |
126 |
} |
127 |
av_free(sv); |
128 |
} |
129 |
|
130 |
RTPDynamicProtocolHandler ff_svq3_dynamic_handler = { |
131 |
"X-SV3V-ES",
|
132 |
AVMEDIA_TYPE_VIDEO, |
133 |
CODEC_ID_NONE, // see if (config_packet) above
|
134 |
NULL, // parse sdp line |
135 |
svq3_extradata_new, |
136 |
svq3_extradata_free, |
137 |
svq3_parse_packet, |
138 |
}; |