00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "avcodec.h"
00029 #include "bytestream.h"
00030 #include "mjpeg.h"
00031
00032
00033 static int mjpega_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
00034 uint8_t **poutbuf, int *poutbuf_size,
00035 const uint8_t *buf, int buf_size, int keyframe)
00036 {
00037 uint8_t *poutbufp;
00038 unsigned dqt = 0, dht = 0, sof0 = 0;
00039 int i;
00040
00041 if (avctx->codec_id != AV_CODEC_ID_MJPEG) {
00042 av_log(avctx, AV_LOG_ERROR, "mjpega bitstream filter only applies to mjpeg codec\n");
00043 return 0;
00044 }
00045
00046 *poutbuf_size = 0;
00047 *poutbuf = av_malloc(buf_size + 44 + FF_INPUT_BUFFER_PADDING_SIZE);
00048 poutbufp = *poutbuf;
00049 bytestream_put_byte(&poutbufp, 0xff);
00050 bytestream_put_byte(&poutbufp, SOI);
00051 bytestream_put_byte(&poutbufp, 0xff);
00052 bytestream_put_byte(&poutbufp, APP1);
00053 bytestream_put_be16(&poutbufp, 42);
00054 bytestream_put_be32(&poutbufp, 0);
00055 bytestream_put_buffer(&poutbufp, "mjpg", 4);
00056 bytestream_put_be32(&poutbufp, buf_size + 44);
00057 bytestream_put_be32(&poutbufp, buf_size + 44);
00058 bytestream_put_be32(&poutbufp, 0);
00059
00060 for (i = 0; i < buf_size - 1; i++) {
00061 if (buf[i] == 0xff) {
00062 switch (buf[i + 1]) {
00063 case DQT: dqt = i + 46; break;
00064 case DHT: dht = i + 46; break;
00065 case SOF0: sof0 = i + 46; break;
00066 case SOS:
00067 bytestream_put_be32(&poutbufp, dqt);
00068 bytestream_put_be32(&poutbufp, dht);
00069 bytestream_put_be32(&poutbufp, sof0);
00070 bytestream_put_be32(&poutbufp, i + 46);
00071 bytestream_put_be32(&poutbufp, i + 46 + AV_RB16(buf + i + 2));
00072 bytestream_put_buffer(&poutbufp, buf + 2, buf_size - 2);
00073 *poutbuf_size = poutbufp - *poutbuf;
00074 return 1;
00075 case APP1:
00076 if (i + 8 < buf_size && AV_RL32(buf + i + 8) == AV_RL32("mjpg")) {
00077 av_log(avctx, AV_LOG_ERROR, "bitstream already formatted\n");
00078 memcpy(*poutbuf, buf, buf_size);
00079 *poutbuf_size = buf_size;
00080 return 1;
00081 }
00082 }
00083 }
00084 }
00085 av_freep(poutbuf);
00086 av_log(avctx, AV_LOG_ERROR, "could not find SOS marker in bitstream\n");
00087 return 0;
00088 }
00089
00090 AVBitStreamFilter ff_mjpega_dump_header_bsf = {
00091 "mjpegadump",
00092 0,
00093 mjpega_dump_header,
00094 };