FFmpeg
rtpenc_h263_rfc2190.c
Go to the documentation of this file.
1 /*
2  * RTP packetization for H.263 video
3  * Copyright (c) 2012 Martin Storsjo
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 "rtpenc.h"
24 #include "libavcodec/put_bits.h"
25 #include "libavcodec/get_bits.h"
26 
27 struct H263Info {
28  int src;
29  int i;
30  int u;
31  int s;
32  int a;
33  int pb;
34  int tr;
35 };
36 
37 struct H263State {
38  int gobn;
39  int mba;
40  int hmv1, vmv1, hmv2, vmv2;
41  int quant;
42 };
43 
44 static void send_mode_a(AVFormatContext *s1, const struct H263Info *info,
45  const uint8_t *buf, int len, int ebits, int m)
46 {
47  RTPMuxContext *s = s1->priv_data;
48  PutBitContext pb;
49 
50  init_put_bits(&pb, s->buf, 32);
51  put_bits(&pb, 1, 0); /* F - 0, mode A */
52  put_bits(&pb, 1, 0); /* P - 0, normal I/P */
53  put_bits(&pb, 3, 0); /* SBIT - 0 bits */
54  put_bits(&pb, 3, ebits); /* EBIT */
55  put_bits(&pb, 3, info->src); /* SRC - source format */
56  put_bits(&pb, 1, info->i); /* I - inter/intra */
57  put_bits(&pb, 1, info->u); /* U - unrestricted motion vector */
58  put_bits(&pb, 1, info->s); /* S - syntax-baesd arithmetic coding */
59  put_bits(&pb, 1, info->a); /* A - advanced prediction */
60  put_bits(&pb, 4, 0); /* R - reserved */
61  put_bits(&pb, 2, 0); /* DBQ - 0 */
62  put_bits(&pb, 3, 0); /* TRB - 0 */
63  put_bits(&pb, 8, info->tr); /* TR */
64  flush_put_bits(&pb);
65  memcpy(s->buf + 4, buf, len);
66 
67  ff_rtp_send_data(s1, s->buf, len + 4, m);
68 }
69 
70 static void send_mode_b(AVFormatContext *s1, const struct H263Info *info,
71  const struct H263State *state, const uint8_t *buf,
72  int len, int sbits, int ebits, int m)
73 {
74  RTPMuxContext *s = s1->priv_data;
75  PutBitContext pb;
76 
77  init_put_bits(&pb, s->buf, 64);
78  put_bits(&pb, 1, 1); /* F - 1, mode B */
79  put_bits(&pb, 1, 0); /* P - 0, mode B */
80  put_bits(&pb, 3, sbits); /* SBIT - 0 bits */
81  put_bits(&pb, 3, ebits); /* EBIT - 0 bits */
82  put_bits(&pb, 3, info->src); /* SRC - source format */
83  put_bits(&pb, 5, state->quant); /* QUANT - quantizer for the first MB */
84  put_bits(&pb, 5, state->gobn); /* GOBN - GOB number */
85  put_bits(&pb, 9, state->mba); /* MBA - MB address */
86  put_bits(&pb, 2, 0); /* R - reserved */
87  put_bits(&pb, 1, info->i); /* I - inter/intra */
88  put_bits(&pb, 1, info->u); /* U - unrestricted motion vector */
89  put_bits(&pb, 1, info->s); /* S - syntax-baesd arithmetic coding */
90  put_bits(&pb, 1, info->a); /* A - advanced prediction */
91  put_bits(&pb, 7, state->hmv1); /* HVM1 - horizontal motion vector 1 */
92  put_bits(&pb, 7, state->vmv1); /* VMV1 - vertical motion vector 1 */
93  put_bits(&pb, 7, state->hmv2); /* HVM2 - horizontal motion vector 2 */
94  put_bits(&pb, 7, state->vmv2); /* VMV2 - vertical motion vector 2 */
95  flush_put_bits(&pb);
96  memcpy(s->buf + 8, buf, len);
97 
98  ff_rtp_send_data(s1, s->buf, len + 8, m);
99 }
100 
102  const uint8_t *mb_info, int mb_info_size)
103 {
104  RTPMuxContext *s = s1->priv_data;
105  int len, sbits = 0, ebits = 0;
106  GetBitContext gb;
107  struct H263Info info = { 0 };
108  struct H263State state = { 0 };
109  int mb_info_pos = 0, mb_info_count = mb_info_size / 12;
110  const uint8_t *buf_base = buf;
111 
112  s->timestamp = s->cur_timestamp;
113 
114  init_get_bits(&gb, buf, size*8);
115  if (get_bits(&gb, 22) == 0x20) { /* Picture Start Code */
116  info.tr = get_bits(&gb, 8);
117  skip_bits(&gb, 2); /* PTYPE start, H.261 disambiguation */
118  skip_bits(&gb, 3); /* Split screen, document camera, freeze picture release */
119  info.src = get_bits(&gb, 3);
120  info.i = get_bits(&gb, 1);
121  info.u = get_bits(&gb, 1);
122  info.s = get_bits(&gb, 1);
123  info.a = get_bits(&gb, 1);
124  info.pb = get_bits(&gb, 1);
125  }
126 
127  while (size > 0) {
128  struct H263State packet_start_state = state;
129  len = FFMIN(s->max_payload_size - 8, size);
130 
131  /* Look for a better place to split the frame into packets. */
132  if (len < size) {
134  buf + len);
135  len = end - buf;
136  if (len == s->max_payload_size - 8) {
137  /* Skip mb info prior to the start of the current ptr */
138  while (mb_info_pos < mb_info_count) {
139  uint32_t pos = AV_RL32(&mb_info[12*mb_info_pos])/8;
140  if (pos >= buf - buf_base)
141  break;
142  mb_info_pos++;
143  }
144  /* Find the first mb info past the end pointer */
145  while (mb_info_pos + 1 < mb_info_count) {
146  uint32_t pos = AV_RL32(&mb_info[12*(mb_info_pos + 1)])/8;
147  if (pos >= end - buf_base)
148  break;
149  mb_info_pos++;
150  }
151  if (mb_info_pos < mb_info_count) {
152  const uint8_t *ptr = &mb_info[12*mb_info_pos];
153  /* get position in bits in the input packet at which the next info block should be used */
154  uint32_t bit_pos = AV_RL32(ptr);
155  /* get position in bytes */
156  uint32_t pos_next_mb_info = (bit_pos + 7)/8;
157  /* check if data from the next MB info block should be used */
158  if (pos_next_mb_info <= end - buf_base) {
159  state.quant = ptr[4];
160  state.gobn = ptr[5];
161  state.mba = AV_RL16(&ptr[6]);
162  state.hmv1 = (int8_t) ptr[8];
163  state.vmv1 = (int8_t) ptr[9];
164  state.hmv2 = (int8_t) ptr[10];
165  state.vmv2 = (int8_t) ptr[11];
166  ebits = 8 * pos_next_mb_info - bit_pos;
167  len = pos_next_mb_info - (buf - buf_base);
168  mb_info_pos++;
169  }
170  } else {
171  av_log(s1, AV_LOG_ERROR, "Unable to split H.263 packet, "
172  "use -mb_info %d or -ps 1.\n",
173  s->max_payload_size - 8);
174  }
175  }
176  }
177 
178  if (size > 2 && !buf[0] && !buf[1])
179  send_mode_a(s1, &info, buf, len, ebits, len == size);
180  else
181  send_mode_b(s1, &info, &packet_start_state, buf, len, sbits,
182  ebits, len == size);
183 
184  if (ebits) {
185  sbits = 8 - ebits;
186  len--;
187  } else {
188  sbits = 0;
189  }
190  buf += len;
191  size -= len;
192  ebits = 0;
193  }
194 }
H263Info::pb
int pb
Definition: rtpenc_h263_rfc2190.c:33
init_put_bits
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:57
state
static struct @321 state
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:218
H263Info::a
int a
Definition: rtpenc_h263_rfc2190.c:32
send_mode_a
static void send_mode_a(AVFormatContext *s1, const struct H263Info *info, const uint8_t *buf, int len, int ebits, int m)
Definition: rtpenc_h263_rfc2190.c:44
ff_rtp_send_data
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
Definition: rtpenc.c:332
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:659
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:467
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
GetBitContext
Definition: get_bits.h:61
send_mode_b
static void send_mode_b(AVFormatContext *s1, const struct H263Info *info, const struct H263State *state, const uint8_t *buf, int len, int sbits, int ebits, int m)
Definition: rtpenc_h263_rfc2190.c:70
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
H263State::vmv1
int vmv1
Definition: rtpenc_h263_rfc2190.c:40
s
#define s(width, name)
Definition: cbs_vp9.c:257
s1
#define s1
Definition: regdef.h:38
info
MIPS optimizations info
Definition: mips.txt:2
get_bits.h
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
PutBitContext
Definition: put_bits.h:44
AVFormatContext
Format I/O context.
Definition: avformat.h:1232
H263Info::src
int src
Definition: rtpenc_h263_rfc2190.c:28
H263State::hmv1
int hmv1
Definition: rtpenc_h263_rfc2190.c:40
H263State::quant
int quant
Definition: rtpenc_h263_rfc2190.c:41
RTPMuxContext
Definition: rtpenc.h:27
H263State::mba
int mba
Definition: rtpenc_h263_rfc2190.c:39
H263State::gobn
int gobn
Definition: rtpenc_h263_rfc2190.c:38
H263Info::tr
int tr
Definition: rtpenc_h263_rfc2190.c:34
size
int size
Definition: twinvq_data.h:10344
H263Info::i
int i
Definition: rtpenc_h263_rfc2190.c:29
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
H263State::hmv2
int hmv2
Definition: rtpenc_h263_rfc2190.c:40
H263Info
Definition: rtpenc_h263_rfc2190.c:27
H263Info::s
int s
Definition: rtpenc_h263_rfc2190.c:31
uint8_t
uint8_t
Definition: audio_convert.c:194
len
int len
Definition: vorbis_enc_data.h:452
rtpenc.h
H263Info::u
int u
Definition: rtpenc_h263_rfc2190.c:30
pos
unsigned int pos
Definition: spdifenc.c:412
avformat.h
ff_h263_find_resync_marker_reverse
const uint8_t * ff_h263_find_resync_marker_reverse(const uint8_t *av_restrict start, const uint8_t *av_restrict end)
Definition: rtpenc_h263.c:26
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
ff_rtp_send_h263_rfc2190
void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size, const uint8_t *mb_info, int mb_info_size)
Definition: rtpenc_h263_rfc2190.c:101
H263State
Definition: rtpenc_h263_rfc2190.c:37
H263State::vmv2
int vmv2
Definition: rtpenc_h263_rfc2190.c:40
flush_put_bits
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:110
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
put_bits.h
mb_info
Definition: cinepakenc.c:87