Mercurial > libavcodec.hg
comparison mjpeg.c @ 4252:daaebca81d86 libavcodec
mjpeg a dump header bitstream filter, modifies bitstream to be decoded by quicktime
| author | bcoudurier |
|---|---|
| date | Fri, 01 Dec 2006 14:06:21 +0000 |
| parents | fa816309076b |
| children | 05e932ddaaa9 |
comparison
equal
deleted
inserted
replaced
| 4251:b0d38ef4b547 | 4252:daaebca81d86 |
|---|---|
| 34 #include <assert.h> | 34 #include <assert.h> |
| 35 | 35 |
| 36 #include "avcodec.h" | 36 #include "avcodec.h" |
| 37 #include "dsputil.h" | 37 #include "dsputil.h" |
| 38 #include "mpegvideo.h" | 38 #include "mpegvideo.h" |
| 39 #include "bytestream.h" | |
| 39 | 40 |
| 40 /* use two quantizer tables (one for luminance and one for chrominance) */ | 41 /* use two quantizer tables (one for luminance and one for chrominance) */ |
| 41 /* not yet working */ | 42 /* not yet working */ |
| 42 #undef TWOMATRIXES | 43 #undef TWOMATRIXES |
| 43 | 44 |
| 2501 free_vlc(&s->vlcs[i][j]); | 2502 free_vlc(&s->vlcs[i][j]); |
| 2502 } | 2503 } |
| 2503 return 0; | 2504 return 0; |
| 2504 } | 2505 } |
| 2505 | 2506 |
| 2507 static int mjpega_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, | |
| 2508 uint8_t **poutbuf, int *poutbuf_size, | |
| 2509 const uint8_t *buf, int buf_size, int keyframe) | |
| 2510 { | |
| 2511 uint8_t *poutbufp; | |
| 2512 int i; | |
| 2513 | |
| 2514 if (avctx->codec_id != CODEC_ID_MJPEG) { | |
| 2515 av_log(avctx, AV_LOG_ERROR, "mjpega bitstream filter only applies to mjpeg codec\n"); | |
| 2516 return 0; | |
| 2517 } | |
| 2518 | |
| 2519 *poutbuf_size = 0; | |
| 2520 *poutbuf = av_malloc(buf_size + 44 + FF_INPUT_BUFFER_PADDING_SIZE); | |
| 2521 poutbufp = *poutbuf; | |
| 2522 bytestream_put_byte(&poutbufp, 0xff); | |
| 2523 bytestream_put_byte(&poutbufp, SOI); | |
| 2524 bytestream_put_byte(&poutbufp, 0xff); | |
| 2525 bytestream_put_byte(&poutbufp, APP1); | |
| 2526 bytestream_put_be16(&poutbufp, 42); /* size */ | |
| 2527 bytestream_put_be32(&poutbufp, 0); | |
| 2528 bytestream_put_buffer(&poutbufp, "mjpg", 4); | |
| 2529 bytestream_put_be32(&poutbufp, buf_size + 44); /* field size */ | |
| 2530 bytestream_put_be32(&poutbufp, buf_size + 44); /* pad field size */ | |
| 2531 bytestream_put_be32(&poutbufp, 0); /* next ptr */ | |
| 2532 | |
| 2533 for (i = 0; i < buf_size - 1; i++) { | |
| 2534 if (buf[i] == 0xff) { | |
| 2535 switch (buf[i + 1]) { | |
| 2536 case DQT: /* quant off */ | |
| 2537 case DHT: /* huff off */ | |
| 2538 case SOF0: /* image off */ | |
| 2539 bytestream_put_be32(&poutbufp, i + 46); | |
| 2540 break; | |
| 2541 case SOS: | |
| 2542 bytestream_put_be32(&poutbufp, i + 46); /* scan off */ | |
| 2543 bytestream_put_be32(&poutbufp, i + 46 + BE_16(buf + i + 2)); /* data off */ | |
| 2544 bytestream_put_buffer(&poutbufp, buf + 2, buf_size - 2); /* skip already written SOI */ | |
| 2545 *poutbuf_size = poutbufp - *poutbuf; | |
| 2546 return 1; | |
| 2547 case APP1: | |
| 2548 if (i + 8 < buf_size && LE_32(buf + i + 8) == ff_get_fourcc("mjpg")) { | |
| 2549 av_log(avctx, AV_LOG_ERROR, "bitstream already formatted\n"); | |
| 2550 memcpy(*poutbuf, buf, buf_size); | |
| 2551 *poutbuf_size = buf_size; | |
| 2552 return 1; | |
| 2553 } | |
| 2554 } | |
| 2555 } | |
| 2556 } | |
| 2557 av_freep(poutbuf); | |
| 2558 av_log(avctx, AV_LOG_ERROR, "could not find SOS marker in bitstream\n"); | |
| 2559 return 0; | |
| 2560 } | |
| 2561 | |
| 2506 AVCodec mjpeg_decoder = { | 2562 AVCodec mjpeg_decoder = { |
| 2507 "mjpeg", | 2563 "mjpeg", |
| 2508 CODEC_TYPE_VIDEO, | 2564 CODEC_TYPE_VIDEO, |
| 2509 CODEC_ID_MJPEG, | 2565 CODEC_ID_MJPEG, |
| 2510 sizeof(MJpegDecodeContext), | 2566 sizeof(MJpegDecodeContext), |
| 2560 NULL, | 2616 NULL, |
| 2561 jpeg_parse, | 2617 jpeg_parse, |
| 2562 ff_parse_close, | 2618 ff_parse_close, |
| 2563 }; | 2619 }; |
| 2564 | 2620 |
| 2621 AVBitStreamFilter mjpega_dump_header_bsf = { | |
| 2622 "mjpegadump", | |
| 2623 0, | |
| 2624 mjpega_dump_header, | |
| 2625 }; |
