FFmpeg
rtpenc_jpeg.c
Go to the documentation of this file.
1 /*
2  * RTP JPEG-compressed video Packetizer, RFC 2435
3  * Copyright (c) 2012 Samuel Pitoiset
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 "libavcodec/bytestream.h"
23 #include "libavcodec/mjpeg.h"
24 #include "libavcodec/jpegtables.h"
25 #include "libavutil/intreadwrite.h"
26 #include "rtpenc.h"
27 
28 void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size)
29 {
30  RTPMuxContext *s = s1->priv_data;
31  const uint8_t *qtables[4] = { NULL };
32  int nb_qtables = 0;
33  uint8_t type = 2; /* initialized non-0/1 value for RTP/JPEG type check*/
34  uint8_t w, h;
35  uint8_t *p;
36  int off = 0; /* fragment offset of the current JPEG frame */
37  int len;
38  int i;
39  int default_huffman_tables = 0;
40 
41  s->buf_ptr = s->buf;
42  s->timestamp = s->cur_timestamp;
43 
44  /* convert video pixel dimensions from pixels to blocks */
45  w = AV_CEIL_RSHIFT(s1->streams[0]->codecpar->width, 3);
46  h = AV_CEIL_RSHIFT(s1->streams[0]->codecpar->height, 3);
47 
48  /* preparse the header for getting some info */
49  for (i = 0; i < size; i++) {
50  if (buf[i] != 0xff)
51  continue;
52 
53  if (buf[i + 1] == DQT) {
54  int tables, j;
55  if (buf[i + 4] & 0xF0)
57  "Only 8-bit precision is supported.\n");
58 
59  /* a quantization table is 64 bytes long */
60  tables = AV_RB16(&buf[i + 2]) / 65;
61  if (i + 5 + tables * 65 > size) {
62  av_log(s1, AV_LOG_ERROR, "Too short JPEG header. Aborted!\n");
63  return;
64  }
65  if (nb_qtables + tables > 4) {
66  av_log(s1, AV_LOG_ERROR, "Invalid number of quantisation tables\n");
67  return;
68  }
69 
70  for (j = 0; j < tables; j++)
71  qtables[nb_qtables + j] = buf + i + 5 + j * 65;
72  nb_qtables += tables;
73  } else if (buf[i + 1] == SOF0) {
74  if (buf[i + 14] != 17 || buf[i + 17] != 17) {
76  "Only 1x1 chroma blocks are supported. Aborted!\n");
77  return;
78  }
79 
80  /*
81  * Find out the sampling factor in SOF0.
82  * In SOF0, hsample/vsample is inserted in form of (2<<4) | (type ? 2 : 1).
83  * First 4-bit is hsample while Last 4-bit is vsample.
84  */
85 
86  /* Luma channel sampling factor in 4:2:2 chroma subsampling are 2x1 */
87  if (buf[i + 11] == 33) {
88  type = 0;
89  /* Luma channel sampling factor in 4:2:0 chroma subsampling are 2x2 */
90  } else if (buf[i + 11] == 34) {
91  type = 1;
92  } else {
93  av_log(s1, AV_LOG_ERROR, "Unsupported pixel format\n");
94  return;
95  }
96  } else if (buf[i + 1] == DHT) {
97  int dht_size = AV_RB16(&buf[i + 2]);
98  default_huffman_tables |= 1 << 4;
99  i += 3;
100  dht_size -= 2;
101  if (i + dht_size >= size)
102  continue;
103  while (dht_size > 0)
104  switch (buf[i + 1]) {
105  case 0x00:
106  if ( dht_size >= 29
107  && !memcmp(buf + i + 2, ff_mjpeg_bits_dc_luminance + 1, 16)
108  && !memcmp(buf + i + 18, ff_mjpeg_val_dc, 12)) {
109  default_huffman_tables |= 1;
110  i += 29;
111  dht_size -= 29;
112  } else {
113  i += dht_size;
114  dht_size = 0;
115  }
116  break;
117  case 0x01:
118  if ( dht_size >= 29
119  && !memcmp(buf + i + 2, ff_mjpeg_bits_dc_chrominance + 1, 16)
120  && !memcmp(buf + i + 18, ff_mjpeg_val_dc, 12)) {
121  default_huffman_tables |= 1 << 1;
122  i += 29;
123  dht_size -= 29;
124  } else {
125  i += dht_size;
126  dht_size = 0;
127  }
128  break;
129  case 0x10:
130  if ( dht_size >= 179
131  && !memcmp(buf + i + 2, ff_mjpeg_bits_ac_luminance + 1, 16)
132  && !memcmp(buf + i + 18, ff_mjpeg_val_ac_luminance, 162)) {
133  default_huffman_tables |= 1 << 2;
134  i += 179;
135  dht_size -= 179;
136  } else {
137  i += dht_size;
138  dht_size = 0;
139  }
140  break;
141  case 0x11:
142  if ( dht_size >= 179
143  && !memcmp(buf + i + 2, ff_mjpeg_bits_ac_chrominance + 1, 16)
144  && !memcmp(buf + i + 18, ff_mjpeg_val_ac_chrominance, 162)) {
145  default_huffman_tables |= 1 << 3;
146  i += 179;
147  dht_size -= 179;
148  } else {
149  i += dht_size;
150  dht_size = 0;
151  }
152  break;
153  default:
154  i += dht_size;
155  dht_size = 0;
156  continue;
157  }
158  } else if (buf[i + 1] == SOS) {
159  /* SOS is last marker in the header */
160  i += AV_RB16(&buf[i + 2]) + 2;
161  if (i > size) {
163  "Insufficient data. Aborted!\n");
164  return;
165  }
166  break;
167  }
168  }
169 
170  /* Check validity of RTP/JPEG type */
171  if (type != 0 && type != 1) {
173  "Invalid RTP/JPEG type\n");
174  return;
175  }
176 
177  if (default_huffman_tables && default_huffman_tables != 31) {
179  "RFC 2435 requires standard Huffman tables for jpeg\n");
180  return;
181  }
182  if (nb_qtables && nb_qtables != 2)
184  "RFC 2435 suggests two quantization tables, %d provided\n",
185  nb_qtables);
186 
187  /* skip JPEG header */
188  buf += i;
189  size -= i;
190 
191  for (i = size - 2; i >= 0; i--) {
192  if (buf[i] == 0xff && buf[i + 1] == EOI) {
193  /* Remove the EOI marker */
194  size = i;
195  break;
196  }
197  }
198 
199  p = s->buf_ptr;
200  while (size > 0) {
201  int hdr_size = 8;
202 
203  if (off == 0 && nb_qtables)
204  hdr_size += 4 + 64 * nb_qtables;
205 
206  /* payload max in one packet */
207  len = FFMIN(size, s->max_payload_size - hdr_size);
208 
209  /* set main header */
210  bytestream_put_byte(&p, 0);
211  bytestream_put_be24(&p, off);
212  bytestream_put_byte(&p, type);
213  bytestream_put_byte(&p, 255);
214  bytestream_put_byte(&p, w);
215  bytestream_put_byte(&p, h);
216 
217  if (off == 0 && nb_qtables) {
218  /* set quantization tables header */
219  bytestream_put_byte(&p, 0);
220  bytestream_put_byte(&p, 0);
221  bytestream_put_be16(&p, 64 * nb_qtables);
222 
223  for (i = 0; i < nb_qtables; i++)
224  bytestream_put_buffer(&p, qtables[i], 64);
225  }
226 
227  /* copy payload data */
228  memcpy(p, buf, len);
229 
230  /* marker bit is last packet in frame */
231  ff_rtp_send_data(s1, s->buf, len + hdr_size, size == len);
232 
233  buf += len;
234  size -= len;
235  off += len;
236  p = s->buf;
237  }
238 }
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
jpegtables.h
mjpeg.h
SOS
@ SOS
Definition: mjpeg.h:72
SOF0
@ SOF0
Definition: mjpeg.h:39
w
uint8_t w
Definition: llviddspenc.c:38
ff_mjpeg_val_dc
const uint8_t ff_mjpeg_val_dc[]
Definition: jpegtabs.h:34
ff_rtp_send_data
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
Definition: rtpenc.c:335
ff_mjpeg_bits_ac_chrominance
const uint8_t ff_mjpeg_bits_ac_chrominance[]
Definition: jpegtabs.h:66
tables
Writing a table generator This documentation is preliminary Parts of the API are not good and should be changed Basic concepts A table generator consists of two *_tablegen c and *_tablegen h The h file will provide the variable declarations and initialization code for the tables
Definition: tablegen.txt:10
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:51
s1
#define s1
Definition: regdef.h:38
AVFormatContext
Format I/O context.
Definition: avformat.h:1115
NULL
#define NULL
Definition: coverity.c:32
ff_rtp_send_jpeg
void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size)
Definition: rtpenc_jpeg.c:28
RTPMuxContext
Definition: rtpenc.h:27
ff_mjpeg_val_ac_chrominance
const uint8_t ff_mjpeg_val_ac_chrominance[]
Definition: jpegtabs.h:69
ff_mjpeg_val_ac_luminance
const uint8_t ff_mjpeg_val_ac_luminance[]
Definition: jpegtabs.h:42
ff_mjpeg_bits_ac_luminance
const uint8_t ff_mjpeg_bits_ac_luminance[]
Definition: jpegtabs.h:40
size
int size
Definition: twinvq_data.h:10344
DQT
@ DQT
Definition: mjpeg.h:73
bytestream_put_buffer
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:372
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
EOI
@ EOI
Definition: mjpeg.h:71
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
len
int len
Definition: vorbis_enc_data.h:426
rtpenc.h
DHT
@ DHT
Definition: mjpeg.h:56
ff_mjpeg_bits_dc_chrominance
const uint8_t ff_mjpeg_bits_dc_chrominance[]
Definition: jpegtabs.h:37
ff_mjpeg_bits_dc_luminance
const FF_VISIBILITY_PUSH_HIDDEN uint8_t ff_mjpeg_bits_dc_luminance[]
Definition: jpegtabs.h:32
bytestream.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2038
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98