2 * MJPEG A dump header bitstream filter
3 * Copyright (c) 2006 Baptiste Coudurier
5 * This file is part of Libav.
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * MJPEG A dump header bitstream filter
25 * modifies bitstream to be decoded by quicktime
29 #include "bytestream.h"
33 static int mjpega_dump_header(AVBitStreamFilterContext
*bsfc
, AVCodecContext
*avctx
, const char *args
,
34 uint8_t **poutbuf
, int *poutbuf_size
,
35 const uint8_t *buf
, int buf_size
, int keyframe
)
38 unsigned dqt
= 0, dht
= 0, sof0
= 0;
41 if (avctx
->codec_id
!= AV_CODEC_ID_MJPEG
) {
42 av_log(avctx
, AV_LOG_ERROR
, "mjpega bitstream filter only applies to mjpeg codec\n");
47 *poutbuf
= av_malloc(buf_size
+ 44 + FF_INPUT_BUFFER_PADDING_SIZE
);
49 bytestream_put_byte(&poutbufp
, 0xff);
50 bytestream_put_byte(&poutbufp
, SOI
);
51 bytestream_put_byte(&poutbufp
, 0xff);
52 bytestream_put_byte(&poutbufp
, APP1
);
53 bytestream_put_be16(&poutbufp
, 42); /* size */
54 bytestream_put_be32(&poutbufp
, 0);
55 bytestream_put_buffer(&poutbufp
, "mjpg", 4);
56 bytestream_put_be32(&poutbufp
, buf_size
+ 44); /* field size */
57 bytestream_put_be32(&poutbufp
, buf_size
+ 44); /* pad field size */
58 bytestream_put_be32(&poutbufp
, 0); /* next ptr */
60 for (i
= 0; i
< buf_size
- 1; i
++) {
63 case DQT
: dqt
= i
+ 46; break;
64 case DHT
: dht
= i
+ 46; break;
65 case SOF0
: sof0
= i
+ 46; break;
67 bytestream_put_be32(&poutbufp
, dqt
); /* quant off */
68 bytestream_put_be32(&poutbufp
, dht
); /* huff off */
69 bytestream_put_be32(&poutbufp
, sof0
); /* image off */
70 bytestream_put_be32(&poutbufp
, i
+ 46); /* scan off */
71 bytestream_put_be32(&poutbufp
, i
+ 46 + AV_RB16(buf
+ i
+ 2)); /* data off */
72 bytestream_put_buffer(&poutbufp
, buf
+ 2, buf_size
- 2); /* skip already written SOI */
73 *poutbuf_size
= poutbufp
- *poutbuf
;
76 if (i
+ 8 < buf_size
&& AV_RL32(buf
+ i
+ 8) == AV_RL32("mjpg")) {
77 av_log(avctx
, AV_LOG_ERROR
, "bitstream already formatted\n");
78 memcpy(*poutbuf
, buf
, buf_size
);
79 *poutbuf_size
= buf_size
;
86 av_log(avctx
, AV_LOG_ERROR
, "could not find SOS marker in bitstream\n");
90 AVBitStreamFilter ff_mjpega_dump_header_bsf
= {