rtpdec_h263_rfc2190.c
Go to the documentation of this file.
1 /*
2  * RTP H.263 Depacketizer, RFC 2190
3  * Copyright (c) 2012 Martin Storsjo
4  * Based on the GStreamer H.263 Depayloder:
5  * Copyright 2005 Wim Taymans
6  * Copyright 2007 Edward Hervey
7  * Copyright 2007 Nokia Corporation
8  * Copyright 2007 Collabora Ltd, Philippe Kalaf
9  * Copyright 2010 Mark Nauwelaerts
10  *
11  * This file is part of Libav.
12  *
13  * Libav is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2.1 of the License, or (at your option) any later version.
17  *
18  * Libav is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  * Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with Libav; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26  */
27 
28 #include "avformat.h"
29 #include "rtpdec_formats.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavcodec/get_bits.h"
32 
33 struct PayloadContext {
37  uint32_t timestamp;
38  int newformat;
39 };
40 
42 {
43  return av_mallocz(sizeof(PayloadContext));
44 }
45 
47 {
48  if (!data)
49  return;
50  if (data->buf) {
51  uint8_t *p;
52  avio_close_dyn_buf(data->buf, &p);
53  av_free(p);
54  }
55  av_free(data);
56 }
57 
58 static int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
59 {
60  if (st_index < 0)
61  return 0;
62  ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
63  return 0;
64 }
65 
67  AVStream *st, AVPacket *pkt, uint32_t *timestamp,
68  const uint8_t *buf, int len, uint16_t seq,
69  int flags)
70 {
71  /* Corresponding to header fields in the RFC */
72  int f, p, i, sbit, ebit, src, r;
73  int header_size, ret;
74 
75  if (data->newformat)
76  return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, len,
77  seq, flags);
78 
79  if (data->buf && data->timestamp != *timestamp) {
80  /* Dropping old buffered, unfinished data */
81  uint8_t *p;
82  avio_close_dyn_buf(data->buf, &p);
83  av_free(p);
84  data->buf = NULL;
85  }
86 
87  if (len < 4) {
88  av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet: %d\n", len);
89  return AVERROR_INVALIDDATA;
90  }
91 
92  f = buf[0] & 0x80;
93  p = buf[0] & 0x40;
94  if (!f) {
95  /* Mode A */
96  header_size = 4;
97  i = buf[1] & 0x10;
98  r = ((buf[1] & 0x01) << 3) | ((buf[2] & 0xe0) >> 5);
99  } else if (!p) {
100  /* Mode B */
101  header_size = 8;
102  if (len < header_size) {
103  av_log(ctx, AV_LOG_ERROR,
104  "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
105  len, header_size);
106  return AVERROR_INVALIDDATA;
107  }
108  r = buf[3] & 0x03;
109  i = buf[4] & 0x80;
110  } else {
111  /* Mode C */
112  header_size = 12;
113  if (len < header_size) {
114  av_log(ctx, AV_LOG_ERROR,
115  "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
116  len, header_size);
117  return AVERROR_INVALIDDATA;
118  }
119  r = buf[3] & 0x03;
120  i = buf[4] & 0x80;
121  }
122  sbit = (buf[0] >> 3) & 0x7;
123  ebit = buf[0] & 0x7;
124  src = (buf[1] & 0xe0) >> 5;
125  if (!(buf[0] & 0xf8)) { /* Reserved bits in RFC 2429/4629 are zero */
126  if ((src == 0 || src >= 6) && r) {
127  /* Invalid src for this format, and bits that should be zero
128  * according to RFC 2190 aren't zero. */
129  av_log(ctx, AV_LOG_WARNING,
130  "Interpreting H263 RTP data as RFC 2429/4629 even though "
131  "signalled with a static payload type.\n");
132  data->newformat = 1;
133  return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf,
134  len, seq, flags);
135  }
136  }
137 
138  buf += header_size;
139  len -= header_size;
140 
141  if (!data->buf) {
142  /* Check the picture start code, only start buffering a new frame
143  * if this is correct */
144  if (len > 4 && AV_RB32(buf) >> 10 == 0x20) {
145  ret = avio_open_dyn_buf(&data->buf);
146  if (ret < 0)
147  return ret;
148  data->timestamp = *timestamp;
149  } else {
150  /* Frame not started yet, skipping */
151  return AVERROR(EAGAIN);
152  }
153  }
154 
155  if (data->endbyte_bits || sbit) {
156  if (data->endbyte_bits == sbit) {
157  data->endbyte |= buf[0] & (0xff >> sbit);
158  data->endbyte_bits = 0;
159  buf++;
160  len--;
161  avio_w8(data->buf, data->endbyte);
162  } else {
163  /* Start/end skip bits not matching - missed packets? */
164  GetBitContext gb;
165  init_get_bits(&gb, buf, len*8 - ebit);
166  skip_bits(&gb, sbit);
167  if (data->endbyte_bits) {
168  data->endbyte |= get_bits(&gb, 8 - data->endbyte_bits);
169  avio_w8(data->buf, data->endbyte);
170  }
171  while (get_bits_left(&gb) >= 8)
172  avio_w8(data->buf, get_bits(&gb, 8));
173  data->endbyte_bits = get_bits_left(&gb);
174  if (data->endbyte_bits)
175  data->endbyte = get_bits(&gb, data->endbyte_bits) <<
176  (8 - data->endbyte_bits);
177  ebit = 0;
178  len = 0;
179  }
180  }
181  if (ebit) {
182  if (len > 0)
183  avio_write(data->buf, buf, len - 1);
184  data->endbyte_bits = 8 - ebit;
185  data->endbyte = buf[len - 1] & (0xff << ebit);
186  } else {
187  avio_write(data->buf, buf, len);
188  }
189 
190  if (!(flags & RTP_FLAG_MARKER))
191  return AVERROR(EAGAIN);
192 
193  if (data->endbyte_bits)
194  avio_w8(data->buf, data->endbyte);
195  data->endbyte_bits = 0;
196 
197  ret = ff_rtp_finalize_packet(pkt, &data->buf, st->index);
198  if (ret < 0)
199  return ret;
200  if (!i)
201  pkt->flags |= AV_PKT_FLAG_KEY;
202 
203  return 0;
204 }
205 
208  .codec_id = AV_CODEC_ID_H263,
209  .init = h263_init,
210  .parse_packet = h263_handle_packet,
211  .alloc = h263_new_context,
212  .free = h263_free_context,
213  .static_payload_id = 34,
214 };
static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t *buf, int len, uint16_t seq, int flags)
AVPacket pkt
Definition: rtpdec_qt.c:37
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
Bytestream IO Context.
Definition: avio.h:68
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t *buf, int len, uint16_t seq, int flags)
Definition: rtpdec_h263.c:34
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:988
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:240
static void h263_free_context(PayloadContext *data)
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
RTP/JPEG specific private data.
Definition: rdt.c:83
int index
stream index in AVFormatContext
Definition: avformat.h:644
Sinusoidal phase f
uint8_t * buf
the temporary storage buffer
Definition: rtpdec_asf.c:160
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:976
enum AVMediaType codec_type
Definition: rtpdec.h:121
Format I/O context.
Definition: avformat.h:944
uint8_t
#define AV_RB32
enum AVStreamParseType need_parsing
Definition: avformat.h:811
static PayloadContext * h263_new_context(void)
AVStream ** streams
Definition: avformat.h:992
bitstream reader API header.
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:173
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:557
uint32_t timestamp
current frame timestamp
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
#define RTP_FLAG_MARKER
RTP marker bit was set for this packet.
Definition: rtpdec.h:97
const char * r
Definition: vf_curves.c:94
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
int flags
A combination of AV_PKT_FLAG values.
ret
Definition: avfilter.c:821
AVIOContext * buf
Stream structure.
Definition: avformat.h:643
NULL
Definition: eval.c:55
AVS_Value src
Definition: avisynth_c.h:523
AVIOContext * data
Definition: rtpdec_vp8.c:35
RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:151
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:265
synthesis window for stochastic i
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:379
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
static int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
static int flags
Definition: cpu.c:23
full parsing and repack
Definition: avformat.h:582
Main libavformat public API header.
int ff_rtp_finalize_packet(AVPacket *pkt, AVIOContext **dyn_buf, int stream_idx)
Close the dynamic buffer and make a packet from it.
Definition: rtpdec.c:865
This structure stores compressed data.