00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avformat.h"
00023 #include "rtpdec.h"
00024 #include "rtpdec_formats.h"
00025 #include "libavutil/intreadwrite.h"
00026 #include "libavcodec/mjpeg.h"
00027 #include "libavcodec/bytestream.h"
00028
00032 struct PayloadContext {
00033 AVIOContext *frame;
00034 uint32_t timestamp;
00035 int hdr_size;
00036 uint8_t qtables[128][128];
00037 uint8_t qtables_len[128];
00038 };
00039
00040 static const uint8_t default_quantizers[128] = {
00041
00042 16, 11, 12, 14, 12, 10, 16, 14,
00043 13, 14, 18, 17, 16, 19, 24, 40,
00044 26, 24, 22, 22, 24, 49, 35, 37,
00045 29, 40, 58, 51, 61, 60, 57, 51,
00046 56, 55, 64, 72, 92, 78, 64, 68,
00047 87, 69, 55, 56, 80, 109, 81, 87,
00048 95, 98, 103, 104, 103, 62, 77, 113,
00049 121, 112, 100, 120, 92, 101, 103, 99,
00050
00051
00052 17, 18, 18, 24, 21, 24, 47, 26,
00053 26, 47, 99, 66, 56, 66, 99, 99,
00054 99, 99, 99, 99, 99, 99, 99, 99,
00055 99, 99, 99, 99, 99, 99, 99, 99,
00056 99, 99, 99, 99, 99, 99, 99, 99,
00057 99, 99, 99, 99, 99, 99, 99, 99,
00058 99, 99, 99, 99, 99, 99, 99, 99,
00059 99, 99, 99, 99, 99, 99, 99, 99
00060 };
00061
00062 static PayloadContext *jpeg_new_context(void)
00063 {
00064 return av_mallocz(sizeof(PayloadContext));
00065 }
00066
00067 static inline void free_frame_if_needed(PayloadContext *jpeg)
00068 {
00069 if (jpeg->frame) {
00070 uint8_t *p;
00071 avio_close_dyn_buf(jpeg->frame, &p);
00072 av_free(p);
00073 jpeg->frame = NULL;
00074 }
00075 }
00076
00077 static void jpeg_free_context(PayloadContext *jpeg)
00078 {
00079 free_frame_if_needed(jpeg);
00080 av_free(jpeg);
00081 }
00082
00083 static int jpeg_create_huffman_table(PutByteContext *p, int table_class,
00084 int table_id, const uint8_t *bits_table,
00085 const uint8_t *value_table)
00086 {
00087 int i, n = 0;
00088
00089 bytestream2_put_byte(p, table_class << 4 | table_id);
00090
00091 for (i = 1; i <= 16; i++) {
00092 n += bits_table[i];
00093 bytestream2_put_byte(p, bits_table[i]);
00094 }
00095
00096 for (i = 0; i < n; i++) {
00097 bytestream2_put_byte(p, value_table[i]);
00098 }
00099 return n + 17;
00100 }
00101
00102 static void jpeg_put_marker(PutByteContext *pbc, int code)
00103 {
00104 bytestream2_put_byte(pbc, 0xff);
00105 bytestream2_put_byte(pbc, code);
00106 }
00107
00108 static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w,
00109 uint32_t h, const uint8_t *qtable, int nb_qtable)
00110 {
00111 PutByteContext pbc;
00112 uint8_t *dht_size_ptr;
00113 int dht_size, i;
00114
00115 bytestream2_init_writer(&pbc, buf, size);
00116
00117
00118 w <<= 3;
00119 h <<= 3;
00120
00121
00122 jpeg_put_marker(&pbc, SOI);
00123
00124
00125 jpeg_put_marker(&pbc, APP0);
00126 bytestream2_put_be16(&pbc, 16);
00127 bytestream2_put_buffer(&pbc, "JFIF", 5);
00128 bytestream2_put_be16(&pbc, 0x0201);
00129 bytestream2_put_byte(&pbc, 0);
00130 bytestream2_put_be16(&pbc, 1);
00131 bytestream2_put_be16(&pbc, 1);
00132 bytestream2_put_byte(&pbc, 0);
00133 bytestream2_put_byte(&pbc, 0);
00134
00135
00136 jpeg_put_marker(&pbc, DQT);
00137 bytestream2_put_be16(&pbc, 2 + nb_qtable * (1 + 64));
00138
00139 for (i = 0; i < nb_qtable; i++) {
00140 bytestream2_put_byte(&pbc, i);
00141
00142
00143
00144
00145 bytestream2_put_buffer(&pbc, qtable + 64 * i, 64);
00146 }
00147
00148
00149 jpeg_put_marker(&pbc, DHT);
00150 dht_size_ptr = pbc.buffer;
00151 bytestream2_put_be16(&pbc, 0);
00152
00153 dht_size = 2;
00154 dht_size += jpeg_create_huffman_table(&pbc, 0, 0,avpriv_mjpeg_bits_dc_luminance,
00155 avpriv_mjpeg_val_dc);
00156 dht_size += jpeg_create_huffman_table(&pbc, 0, 1, avpriv_mjpeg_bits_dc_chrominance,
00157 avpriv_mjpeg_val_dc);
00158 dht_size += jpeg_create_huffman_table(&pbc, 1, 0, avpriv_mjpeg_bits_ac_luminance,
00159 avpriv_mjpeg_val_ac_luminance);
00160 dht_size += jpeg_create_huffman_table(&pbc, 1, 1, avpriv_mjpeg_bits_ac_chrominance,
00161 avpriv_mjpeg_val_ac_chrominance);
00162 AV_WB16(dht_size_ptr, dht_size);
00163
00164
00165 jpeg_put_marker(&pbc, SOF0);
00166 bytestream2_put_be16(&pbc, 17);
00167 bytestream2_put_byte(&pbc, 8);
00168 bytestream2_put_be16(&pbc, h);
00169 bytestream2_put_be16(&pbc, w);
00170 bytestream2_put_byte(&pbc, 3);
00171 bytestream2_put_byte(&pbc, 1);
00172 bytestream2_put_byte(&pbc, (2 << 4) | (type ? 2 : 1));
00173 bytestream2_put_byte(&pbc, 0);
00174 bytestream2_put_byte(&pbc, 2);
00175 bytestream2_put_byte(&pbc, 1 << 4 | 1);
00176 bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0);
00177 bytestream2_put_byte(&pbc, 3);
00178 bytestream2_put_byte(&pbc, 1 << 4 | 1);
00179 bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0);
00180
00181
00182 jpeg_put_marker(&pbc, SOS);
00183 bytestream2_put_be16(&pbc, 12);
00184 bytestream2_put_byte(&pbc, 3);
00185 bytestream2_put_byte(&pbc, 1);
00186 bytestream2_put_byte(&pbc, 0);
00187 bytestream2_put_byte(&pbc, 2);
00188 bytestream2_put_byte(&pbc, 17);
00189 bytestream2_put_byte(&pbc, 3);
00190 bytestream2_put_byte(&pbc, 17);
00191 bytestream2_put_byte(&pbc, 0);
00192 bytestream2_put_byte(&pbc, 63);
00193 bytestream2_put_byte(&pbc, 0);
00194
00195
00196 return bytestream2_tell_p(&pbc);
00197 }
00198
00199 static void create_default_qtables(uint8_t *qtables, uint8_t q)
00200 {
00201 int factor = q;
00202 int i;
00203
00204 factor = av_clip(q, 1, 99);
00205
00206 if (q < 50)
00207 q = 5000 / factor;
00208 else
00209 q = 200 - factor * 2;
00210
00211 for (i = 0; i < 128; i++) {
00212 int val = (default_quantizers[i] * q + 50) / 100;
00213
00214
00215 val = av_clip(val, 1, 255);
00216 qtables[i] = val;
00217 }
00218 }
00219
00220 static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg,
00221 AVStream *st, AVPacket *pkt, uint32_t *timestamp,
00222 const uint8_t *buf, int len, int flags)
00223 {
00224 uint8_t type, q, width, height;
00225 const uint8_t *qtables = NULL;
00226 uint16_t qtable_len;
00227 uint32_t off;
00228 int ret;
00229
00230 if (len < 8) {
00231 av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n");
00232 return AVERROR_INVALIDDATA;
00233 }
00234
00235
00236 off = AV_RB24(buf + 1);
00237 type = AV_RB8(buf + 4);
00238 q = AV_RB8(buf + 5);
00239 width = AV_RB8(buf + 6);
00240 height = AV_RB8(buf + 7);
00241 buf += 8;
00242 len -= 8;
00243
00244
00245 if (type > 63) {
00246 av_log(ctx, AV_LOG_ERROR,
00247 "Unimplemented RTP/JPEG restart marker header.\n");
00248 return AVERROR_PATCHWELCOME;
00249 }
00250 if (type > 1) {
00251 av_log(ctx, AV_LOG_ERROR, "Unimplemented RTP/JPEG type %d\n", type);
00252 return AVERROR_PATCHWELCOME;
00253 }
00254
00255
00256 if (off == 0) {
00257
00258 uint8_t new_qtables[128];
00259 uint8_t hdr[1024];
00260
00261 if (q > 127) {
00262 uint8_t precision;
00263 if (len < 4) {
00264 av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n");
00265 return AVERROR_INVALIDDATA;
00266 }
00267
00268
00269 precision = AV_RB8(buf + 1);
00270 qtable_len = AV_RB16(buf + 2);
00271 buf += 4;
00272 len -= 4;
00273
00274 if (precision)
00275 av_log(ctx, AV_LOG_WARNING, "Only 8-bit precision is supported.\n");
00276
00277 if (qtable_len > 0) {
00278 if (len < qtable_len) {
00279 av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n");
00280 return AVERROR_INVALIDDATA;
00281 }
00282 qtables = buf;
00283 buf += qtable_len;
00284 len -= qtable_len;
00285 if (q < 255) {
00286 if (jpeg->qtables_len[q - 128] &&
00287 (jpeg->qtables_len[q - 128] != qtable_len ||
00288 memcmp(qtables, &jpeg->qtables[q - 128][0], qtable_len))) {
00289 av_log(ctx, AV_LOG_WARNING,
00290 "Quantization tables for q=%d changed\n", q);
00291 } else if (!jpeg->qtables_len[q - 128] && qtable_len <= 128) {
00292 memcpy(&jpeg->qtables[q - 128][0], qtables,
00293 qtable_len);
00294 jpeg->qtables_len[q - 128] = qtable_len;
00295 }
00296 }
00297 } else {
00298 if (q == 255) {
00299 av_log(ctx, AV_LOG_ERROR,
00300 "Invalid RTP/JPEG packet. Quantization tables not found.\n");
00301 return AVERROR_INVALIDDATA;
00302 }
00303 if (!jpeg->qtables_len[q - 128]) {
00304 av_log(ctx, AV_LOG_ERROR,
00305 "No quantization tables known for q=%d yet.\n", q);
00306 return AVERROR_INVALIDDATA;
00307 }
00308 qtables = &jpeg->qtables[q - 128][0];
00309 qtable_len = jpeg->qtables_len[q - 128];
00310 }
00311 } else {
00312 if (q == 0 || q > 99) {
00313 av_log(ctx, AV_LOG_ERROR, "Reserved q value %d\n", q);
00314 return AVERROR_INVALIDDATA;
00315 }
00316 create_default_qtables(new_qtables, q);
00317 qtables = new_qtables;
00318 qtable_len = sizeof(new_qtables);
00319 }
00320
00321
00322
00323 free_frame_if_needed(jpeg);
00324
00325 if ((ret = avio_open_dyn_buf(&jpeg->frame)) < 0)
00326 return ret;
00327 jpeg->timestamp = *timestamp;
00328
00329
00330
00331
00332 jpeg->hdr_size = jpeg_create_header(hdr, sizeof(hdr), type, width,
00333 height, qtables,
00334 qtable_len / 64);
00335
00336
00337 avio_write(jpeg->frame, hdr, jpeg->hdr_size);
00338 }
00339
00340 if (!jpeg->frame) {
00341 av_log(ctx, AV_LOG_ERROR,
00342 "Received packet without a start chunk; dropping frame.\n");
00343 return AVERROR(EAGAIN);
00344 }
00345
00346 if (jpeg->timestamp != *timestamp) {
00347
00348
00349 free_frame_if_needed(jpeg);
00350 av_log(ctx, AV_LOG_ERROR, "RTP timestamps don't match.\n");
00351 return AVERROR_INVALIDDATA;
00352 }
00353
00354 if (off != avio_tell(jpeg->frame) - jpeg->hdr_size) {
00355 av_log(ctx, AV_LOG_ERROR,
00356 "Missing packets; dropping frame.\n");
00357 return AVERROR(EAGAIN);
00358 }
00359
00360
00361 avio_write(jpeg->frame, buf, len);
00362
00363 if (flags & RTP_FLAG_MARKER) {
00364
00365 uint8_t buf[2] = { 0xff, EOI };
00366
00367
00368 avio_write(jpeg->frame, buf, sizeof(buf));
00369
00370
00371 if ((ret = ff_rtp_finalize_packet(pkt, &jpeg->frame, st->index)) < 0) {
00372 av_log(ctx, AV_LOG_ERROR,
00373 "Error occured when getting frame buffer.\n");
00374 return ret;
00375 }
00376
00377 return 0;
00378 }
00379
00380 return AVERROR(EAGAIN);
00381 }
00382
00383 RTPDynamicProtocolHandler ff_jpeg_dynamic_handler = {
00384 .enc_name = "JPEG",
00385 .codec_type = AVMEDIA_TYPE_VIDEO,
00386 .codec_id = AV_CODEC_ID_MJPEG,
00387 .alloc = jpeg_new_context,
00388 .free = jpeg_free_context,
00389 .parse_packet = jpeg_parse_packet,
00390 .static_payload_id = 26,
00391 };