annotate ffmpeg/libavformat/rtpdec_jpeg.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * RTP JPEG-compressed Video Depacketizer, RFC 2435
yading@11 3 * Copyright (c) 2012 Samuel Pitoiset
yading@11 4 *
yading@11 5 * This file is part of FFmpeg.
yading@11 6 *
yading@11 7 * FFmpeg is free software; you can redistribute it and/or
yading@11 8 * modify it under the terms of the GNU Lesser General Public
yading@11 9 * License as published by the Free Software Foundation; either
yading@11 10 * version 2.1 of the License, or (at your option) any later version.
yading@11 11 *
yading@11 12 * FFmpeg is distributed in the hope that it will be useful,
yading@11 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 15 * Lesser General Public License for more details.
yading@11 16 *
yading@11 17 * You should have received a copy of the GNU Lesser General Public
yading@11 18 * License along with FFmpeg; if not, write to the Free Software
yading@11 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 20 */
yading@11 21
yading@11 22 #include "avformat.h"
yading@11 23 #include "rtpdec.h"
yading@11 24 #include "rtpdec_formats.h"
yading@11 25 #include "libavutil/intreadwrite.h"
yading@11 26 #include "libavcodec/mjpeg.h"
yading@11 27 #include "libavcodec/bytestream.h"
yading@11 28
yading@11 29 /**
yading@11 30 * RTP/JPEG specific private data.
yading@11 31 */
yading@11 32 struct PayloadContext {
yading@11 33 AVIOContext *frame; ///< current frame buffer
yading@11 34 uint32_t timestamp; ///< current frame timestamp
yading@11 35 int hdr_size; ///< size of the current frame header
yading@11 36 uint8_t qtables[128][128];
yading@11 37 uint8_t qtables_len[128];
yading@11 38 };
yading@11 39
yading@11 40 static const uint8_t default_quantizers[128] = {
yading@11 41 /* luma table */
yading@11 42 16, 11, 12, 14, 12, 10, 16, 14,
yading@11 43 13, 14, 18, 17, 16, 19, 24, 40,
yading@11 44 26, 24, 22, 22, 24, 49, 35, 37,
yading@11 45 29, 40, 58, 51, 61, 60, 57, 51,
yading@11 46 56, 55, 64, 72, 92, 78, 64, 68,
yading@11 47 87, 69, 55, 56, 80, 109, 81, 87,
yading@11 48 95, 98, 103, 104, 103, 62, 77, 113,
yading@11 49 121, 112, 100, 120, 92, 101, 103, 99,
yading@11 50
yading@11 51 /* chroma table */
yading@11 52 17, 18, 18, 24, 21, 24, 47, 26,
yading@11 53 26, 47, 99, 66, 56, 66, 99, 99,
yading@11 54 99, 99, 99, 99, 99, 99, 99, 99,
yading@11 55 99, 99, 99, 99, 99, 99, 99, 99,
yading@11 56 99, 99, 99, 99, 99, 99, 99, 99,
yading@11 57 99, 99, 99, 99, 99, 99, 99, 99,
yading@11 58 99, 99, 99, 99, 99, 99, 99, 99,
yading@11 59 99, 99, 99, 99, 99, 99, 99, 99
yading@11 60 };
yading@11 61
yading@11 62 static PayloadContext *jpeg_new_context(void)
yading@11 63 {
yading@11 64 return av_mallocz(sizeof(PayloadContext));
yading@11 65 }
yading@11 66
yading@11 67 static inline void free_frame_if_needed(PayloadContext *jpeg)
yading@11 68 {
yading@11 69 if (jpeg->frame) {
yading@11 70 uint8_t *p;
yading@11 71 avio_close_dyn_buf(jpeg->frame, &p);
yading@11 72 av_free(p);
yading@11 73 jpeg->frame = NULL;
yading@11 74 }
yading@11 75 }
yading@11 76
yading@11 77 static void jpeg_free_context(PayloadContext *jpeg)
yading@11 78 {
yading@11 79 free_frame_if_needed(jpeg);
yading@11 80 av_free(jpeg);
yading@11 81 }
yading@11 82
yading@11 83 static int jpeg_create_huffman_table(PutByteContext *p, int table_class,
yading@11 84 int table_id, const uint8_t *bits_table,
yading@11 85 const uint8_t *value_table)
yading@11 86 {
yading@11 87 int i, n = 0;
yading@11 88
yading@11 89 bytestream2_put_byte(p, table_class << 4 | table_id);
yading@11 90
yading@11 91 for (i = 1; i <= 16; i++) {
yading@11 92 n += bits_table[i];
yading@11 93 bytestream2_put_byte(p, bits_table[i]);
yading@11 94 }
yading@11 95
yading@11 96 for (i = 0; i < n; i++) {
yading@11 97 bytestream2_put_byte(p, value_table[i]);
yading@11 98 }
yading@11 99 return n + 17;
yading@11 100 }
yading@11 101
yading@11 102 static void jpeg_put_marker(PutByteContext *pbc, int code)
yading@11 103 {
yading@11 104 bytestream2_put_byte(pbc, 0xff);
yading@11 105 bytestream2_put_byte(pbc, code);
yading@11 106 }
yading@11 107
yading@11 108 static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w,
yading@11 109 uint32_t h, const uint8_t *qtable, int nb_qtable)
yading@11 110 {
yading@11 111 PutByteContext pbc;
yading@11 112 uint8_t *dht_size_ptr;
yading@11 113 int dht_size, i;
yading@11 114
yading@11 115 bytestream2_init_writer(&pbc, buf, size);
yading@11 116
yading@11 117 /* Convert from blocks to pixels. */
yading@11 118 w <<= 3;
yading@11 119 h <<= 3;
yading@11 120
yading@11 121 /* SOI */
yading@11 122 jpeg_put_marker(&pbc, SOI);
yading@11 123
yading@11 124 /* JFIF header */
yading@11 125 jpeg_put_marker(&pbc, APP0);
yading@11 126 bytestream2_put_be16(&pbc, 16);
yading@11 127 bytestream2_put_buffer(&pbc, "JFIF", 5);
yading@11 128 bytestream2_put_be16(&pbc, 0x0201);
yading@11 129 bytestream2_put_byte(&pbc, 0);
yading@11 130 bytestream2_put_be16(&pbc, 1);
yading@11 131 bytestream2_put_be16(&pbc, 1);
yading@11 132 bytestream2_put_byte(&pbc, 0);
yading@11 133 bytestream2_put_byte(&pbc, 0);
yading@11 134
yading@11 135 /* DQT */
yading@11 136 jpeg_put_marker(&pbc, DQT);
yading@11 137 bytestream2_put_be16(&pbc, 2 + nb_qtable * (1 + 64));
yading@11 138
yading@11 139 for (i = 0; i < nb_qtable; i++) {
yading@11 140 bytestream2_put_byte(&pbc, i);
yading@11 141
yading@11 142 /* Each table is an array of 64 values given in zig-zag
yading@11 143 * order, identical to the format used in a JFIF DQT
yading@11 144 * marker segment. */
yading@11 145 bytestream2_put_buffer(&pbc, qtable + 64 * i, 64);
yading@11 146 }
yading@11 147
yading@11 148 /* DHT */
yading@11 149 jpeg_put_marker(&pbc, DHT);
yading@11 150 dht_size_ptr = pbc.buffer;
yading@11 151 bytestream2_put_be16(&pbc, 0);
yading@11 152
yading@11 153 dht_size = 2;
yading@11 154 dht_size += jpeg_create_huffman_table(&pbc, 0, 0,avpriv_mjpeg_bits_dc_luminance,
yading@11 155 avpriv_mjpeg_val_dc);
yading@11 156 dht_size += jpeg_create_huffman_table(&pbc, 0, 1, avpriv_mjpeg_bits_dc_chrominance,
yading@11 157 avpriv_mjpeg_val_dc);
yading@11 158 dht_size += jpeg_create_huffman_table(&pbc, 1, 0, avpriv_mjpeg_bits_ac_luminance,
yading@11 159 avpriv_mjpeg_val_ac_luminance);
yading@11 160 dht_size += jpeg_create_huffman_table(&pbc, 1, 1, avpriv_mjpeg_bits_ac_chrominance,
yading@11 161 avpriv_mjpeg_val_ac_chrominance);
yading@11 162 AV_WB16(dht_size_ptr, dht_size);
yading@11 163
yading@11 164 /* SOF0 */
yading@11 165 jpeg_put_marker(&pbc, SOF0);
yading@11 166 bytestream2_put_be16(&pbc, 17); /* size */
yading@11 167 bytestream2_put_byte(&pbc, 8); /* bits per component */
yading@11 168 bytestream2_put_be16(&pbc, h);
yading@11 169 bytestream2_put_be16(&pbc, w);
yading@11 170 bytestream2_put_byte(&pbc, 3); /* number of components */
yading@11 171 bytestream2_put_byte(&pbc, 1); /* component number */
yading@11 172 bytestream2_put_byte(&pbc, (2 << 4) | (type ? 2 : 1)); /* hsample/vsample */
yading@11 173 bytestream2_put_byte(&pbc, 0); /* matrix number */
yading@11 174 bytestream2_put_byte(&pbc, 2); /* component number */
yading@11 175 bytestream2_put_byte(&pbc, 1 << 4 | 1); /* hsample/vsample */
yading@11 176 bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); /* matrix number */
yading@11 177 bytestream2_put_byte(&pbc, 3); /* component number */
yading@11 178 bytestream2_put_byte(&pbc, 1 << 4 | 1); /* hsample/vsample */
yading@11 179 bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); /* matrix number */
yading@11 180
yading@11 181 /* SOS */
yading@11 182 jpeg_put_marker(&pbc, SOS);
yading@11 183 bytestream2_put_be16(&pbc, 12);
yading@11 184 bytestream2_put_byte(&pbc, 3);
yading@11 185 bytestream2_put_byte(&pbc, 1);
yading@11 186 bytestream2_put_byte(&pbc, 0);
yading@11 187 bytestream2_put_byte(&pbc, 2);
yading@11 188 bytestream2_put_byte(&pbc, 17);
yading@11 189 bytestream2_put_byte(&pbc, 3);
yading@11 190 bytestream2_put_byte(&pbc, 17);
yading@11 191 bytestream2_put_byte(&pbc, 0);
yading@11 192 bytestream2_put_byte(&pbc, 63);
yading@11 193 bytestream2_put_byte(&pbc, 0);
yading@11 194
yading@11 195 /* Return the length in bytes of the JPEG header. */
yading@11 196 return bytestream2_tell_p(&pbc);
yading@11 197 }
yading@11 198
yading@11 199 static void create_default_qtables(uint8_t *qtables, uint8_t q)
yading@11 200 {
yading@11 201 int factor = q;
yading@11 202 int i;
yading@11 203
yading@11 204 factor = av_clip(q, 1, 99);
yading@11 205
yading@11 206 if (q < 50)
yading@11 207 q = 5000 / factor;
yading@11 208 else
yading@11 209 q = 200 - factor * 2;
yading@11 210
yading@11 211 for (i = 0; i < 128; i++) {
yading@11 212 int val = (default_quantizers[i] * q + 50) / 100;
yading@11 213
yading@11 214 /* Limit the quantizers to 1 <= q <= 255. */
yading@11 215 val = av_clip(val, 1, 255);
yading@11 216 qtables[i] = val;
yading@11 217 }
yading@11 218 }
yading@11 219
yading@11 220 static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg,
yading@11 221 AVStream *st, AVPacket *pkt, uint32_t *timestamp,
yading@11 222 const uint8_t *buf, int len, uint16_t seq,
yading@11 223 int flags)
yading@11 224 {
yading@11 225 uint8_t type, q, width, height;
yading@11 226 const uint8_t *qtables = NULL;
yading@11 227 uint16_t qtable_len;
yading@11 228 uint32_t off;
yading@11 229 int ret;
yading@11 230
yading@11 231 if (len < 8) {
yading@11 232 av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n");
yading@11 233 return AVERROR_INVALIDDATA;
yading@11 234 }
yading@11 235
yading@11 236 /* Parse the main JPEG header. */
yading@11 237 off = AV_RB24(buf + 1); /* fragment byte offset */
yading@11 238 type = AV_RB8(buf + 4); /* id of jpeg decoder params */
yading@11 239 q = AV_RB8(buf + 5); /* quantization factor (or table id) */
yading@11 240 width = AV_RB8(buf + 6); /* frame width in 8 pixel blocks */
yading@11 241 height = AV_RB8(buf + 7); /* frame height in 8 pixel blocks */
yading@11 242 buf += 8;
yading@11 243 len -= 8;
yading@11 244
yading@11 245 /* Parse the restart marker header. */
yading@11 246 if (type > 63) {
yading@11 247 av_log(ctx, AV_LOG_ERROR,
yading@11 248 "Unimplemented RTP/JPEG restart marker header.\n");
yading@11 249 return AVERROR_PATCHWELCOME;
yading@11 250 }
yading@11 251 if (type > 1) {
yading@11 252 av_log(ctx, AV_LOG_ERROR, "Unimplemented RTP/JPEG type %d\n", type);
yading@11 253 return AVERROR_PATCHWELCOME;
yading@11 254 }
yading@11 255
yading@11 256 /* Parse the quantization table header. */
yading@11 257 if (off == 0) {
yading@11 258 /* Start of JPEG data packet. */
yading@11 259 uint8_t new_qtables[128];
yading@11 260 uint8_t hdr[1024];
yading@11 261
yading@11 262 if (q > 127) {
yading@11 263 uint8_t precision;
yading@11 264 if (len < 4) {
yading@11 265 av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n");
yading@11 266 return AVERROR_INVALIDDATA;
yading@11 267 }
yading@11 268
yading@11 269 /* The first byte is reserved for future use. */
yading@11 270 precision = AV_RB8(buf + 1); /* size of coefficients */
yading@11 271 qtable_len = AV_RB16(buf + 2); /* length in bytes */
yading@11 272 buf += 4;
yading@11 273 len -= 4;
yading@11 274
yading@11 275 if (precision)
yading@11 276 av_log(ctx, AV_LOG_WARNING, "Only 8-bit precision is supported.\n");
yading@11 277
yading@11 278 if (qtable_len > 0) {
yading@11 279 if (len < qtable_len) {
yading@11 280 av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n");
yading@11 281 return AVERROR_INVALIDDATA;
yading@11 282 }
yading@11 283 qtables = buf;
yading@11 284 buf += qtable_len;
yading@11 285 len -= qtable_len;
yading@11 286 if (q < 255) {
yading@11 287 if (jpeg->qtables_len[q - 128] &&
yading@11 288 (jpeg->qtables_len[q - 128] != qtable_len ||
yading@11 289 memcmp(qtables, &jpeg->qtables[q - 128][0], qtable_len))) {
yading@11 290 av_log(ctx, AV_LOG_WARNING,
yading@11 291 "Quantization tables for q=%d changed\n", q);
yading@11 292 } else if (!jpeg->qtables_len[q - 128] && qtable_len <= 128) {
yading@11 293 memcpy(&jpeg->qtables[q - 128][0], qtables,
yading@11 294 qtable_len);
yading@11 295 jpeg->qtables_len[q - 128] = qtable_len;
yading@11 296 }
yading@11 297 }
yading@11 298 } else {
yading@11 299 if (q == 255) {
yading@11 300 av_log(ctx, AV_LOG_ERROR,
yading@11 301 "Invalid RTP/JPEG packet. Quantization tables not found.\n");
yading@11 302 return AVERROR_INVALIDDATA;
yading@11 303 }
yading@11 304 if (!jpeg->qtables_len[q - 128]) {
yading@11 305 av_log(ctx, AV_LOG_ERROR,
yading@11 306 "No quantization tables known for q=%d yet.\n", q);
yading@11 307 return AVERROR_INVALIDDATA;
yading@11 308 }
yading@11 309 qtables = &jpeg->qtables[q - 128][0];
yading@11 310 qtable_len = jpeg->qtables_len[q - 128];
yading@11 311 }
yading@11 312 } else { /* q <= 127 */
yading@11 313 if (q == 0 || q > 99) {
yading@11 314 av_log(ctx, AV_LOG_ERROR, "Reserved q value %d\n", q);
yading@11 315 return AVERROR_INVALIDDATA;
yading@11 316 }
yading@11 317 create_default_qtables(new_qtables, q);
yading@11 318 qtables = new_qtables;
yading@11 319 qtable_len = sizeof(new_qtables);
yading@11 320 }
yading@11 321
yading@11 322 /* Skip the current frame in case of the end packet
yading@11 323 * has been lost somewhere. */
yading@11 324 free_frame_if_needed(jpeg);
yading@11 325
yading@11 326 if ((ret = avio_open_dyn_buf(&jpeg->frame)) < 0)
yading@11 327 return ret;
yading@11 328 jpeg->timestamp = *timestamp;
yading@11 329
yading@11 330 /* Generate a frame and scan headers that can be prepended to the
yading@11 331 * RTP/JPEG data payload to produce a JPEG compressed image in
yading@11 332 * interchange format. */
yading@11 333 jpeg->hdr_size = jpeg_create_header(hdr, sizeof(hdr), type, width,
yading@11 334 height, qtables,
yading@11 335 qtable_len / 64);
yading@11 336
yading@11 337 /* Copy JPEG header to frame buffer. */
yading@11 338 avio_write(jpeg->frame, hdr, jpeg->hdr_size);
yading@11 339 }
yading@11 340
yading@11 341 if (!jpeg->frame) {
yading@11 342 av_log(ctx, AV_LOG_ERROR,
yading@11 343 "Received packet without a start chunk; dropping frame.\n");
yading@11 344 return AVERROR(EAGAIN);
yading@11 345 }
yading@11 346
yading@11 347 if (jpeg->timestamp != *timestamp) {
yading@11 348 /* Skip the current frame if timestamp is incorrect.
yading@11 349 * A start packet has been lost somewhere. */
yading@11 350 free_frame_if_needed(jpeg);
yading@11 351 av_log(ctx, AV_LOG_ERROR, "RTP timestamps don't match.\n");
yading@11 352 return AVERROR_INVALIDDATA;
yading@11 353 }
yading@11 354
yading@11 355 if (off != avio_tell(jpeg->frame) - jpeg->hdr_size) {
yading@11 356 av_log(ctx, AV_LOG_ERROR,
yading@11 357 "Missing packets; dropping frame.\n");
yading@11 358 return AVERROR(EAGAIN);
yading@11 359 }
yading@11 360
yading@11 361 /* Copy data to frame buffer. */
yading@11 362 avio_write(jpeg->frame, buf, len);
yading@11 363
yading@11 364 if (flags & RTP_FLAG_MARKER) {
yading@11 365 /* End of JPEG data packet. */
yading@11 366 uint8_t buf[2] = { 0xff, EOI };
yading@11 367
yading@11 368 /* Put EOI marker. */
yading@11 369 avio_write(jpeg->frame, buf, sizeof(buf));
yading@11 370
yading@11 371 /* Prepare the JPEG packet. */
yading@11 372 if ((ret = ff_rtp_finalize_packet(pkt, &jpeg->frame, st->index)) < 0) {
yading@11 373 av_log(ctx, AV_LOG_ERROR,
yading@11 374 "Error occurred when getting frame buffer.\n");
yading@11 375 return ret;
yading@11 376 }
yading@11 377
yading@11 378 return 0;
yading@11 379 }
yading@11 380
yading@11 381 return AVERROR(EAGAIN);
yading@11 382 }
yading@11 383
yading@11 384 RTPDynamicProtocolHandler ff_jpeg_dynamic_handler = {
yading@11 385 .enc_name = "JPEG",
yading@11 386 .codec_type = AVMEDIA_TYPE_VIDEO,
yading@11 387 .codec_id = AV_CODEC_ID_MJPEG,
yading@11 388 .alloc = jpeg_new_context,
yading@11 389 .free = jpeg_free_context,
yading@11 390 .parse_packet = jpeg_parse_packet,
yading@11 391 .static_payload_id = 26,
yading@11 392 };