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