/src/ffmpeg/libavcodec/mjpegbdec.c
Line | Count | Source |
1 | | /* |
2 | | * Apple MJPEG-B decoder |
3 | | * Copyright (c) 2002 Alex Beregszaszi |
4 | | * |
5 | | * This file is part of FFmpeg. |
6 | | * |
7 | | * FFmpeg 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. |
11 | | * |
12 | | * FFmpeg 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. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with FFmpeg; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | */ |
21 | | |
22 | | /** |
23 | | * @file |
24 | | * Apple MJPEG-B decoder. |
25 | | */ |
26 | | |
27 | | #include <inttypes.h> |
28 | | |
29 | | #include "avcodec.h" |
30 | | #include "codec_internal.h" |
31 | | #include "mjpeg.h" |
32 | | #include "mjpegdec.h" |
33 | | |
34 | 2.58M | static uint32_t read_offs(AVCodecContext *avctx, GetBitContext *gb, uint32_t size, const char *err_msg){ |
35 | 2.58M | uint32_t offs= get_bits_long(gb, 32); |
36 | 2.58M | if(offs >= size){ |
37 | 194k | av_log(avctx, AV_LOG_WARNING, err_msg, offs, size); |
38 | 194k | return 0; |
39 | 194k | } |
40 | 2.38M | return offs; |
41 | 2.58M | } |
42 | | |
43 | | static int mjpegb_decode_frame(AVCodecContext *avctx, AVFrame *rframe, |
44 | | int *got_frame, AVPacket *avpkt) |
45 | 494k | { |
46 | 494k | const uint8_t *buf = avpkt->data; |
47 | 494k | int buf_size = avpkt->size; |
48 | 494k | MJpegDecodeContext *s = avctx->priv_data; |
49 | 494k | const uint8_t *buf_end, *buf_ptr; |
50 | 494k | GetBitContext hgb; /* for the header */ |
51 | 494k | uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs; |
52 | 494k | uint32_t field_size, sod_offs; |
53 | 494k | int ret; |
54 | | |
55 | 494k | buf_ptr = buf; |
56 | 494k | buf_end = buf + buf_size; |
57 | 494k | s->got_picture = 0; |
58 | 494k | s->adobe_transform = -1; |
59 | 494k | s->buf_size = buf_size; |
60 | | |
61 | 607k | read_header: |
62 | | /* reset on every SOI */ |
63 | 607k | s->restart_interval = 0; |
64 | 607k | s->mjpb_skiptosod = 0; |
65 | | |
66 | 607k | if ((ret = init_get_bits8(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr))) < 0) |
67 | 0 | return ret; |
68 | | |
69 | 607k | skip_bits(&hgb, 32); /* reserved zeros */ |
70 | | |
71 | 607k | if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g')) { |
72 | 122k | av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n"); |
73 | 122k | return AVERROR_INVALIDDATA; |
74 | 122k | } |
75 | | |
76 | 484k | field_size = get_bits_long(&hgb, 32); /* field size */ |
77 | 484k | av_log(avctx, AV_LOG_DEBUG, "field size: 0x%"PRIx32"\n", field_size); |
78 | 484k | skip_bits(&hgb, 32); /* padded field size */ |
79 | 484k | second_field_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "second_field_offs is %d and size is %d\n"); |
80 | 484k | av_log(avctx, AV_LOG_DEBUG, "second field offs: 0x%"PRIx32"\n", |
81 | 484k | second_field_offs); |
82 | | |
83 | 484k | dqt_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dqt is %d and size is %d\n"); |
84 | 484k | av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%"PRIx32"\n", dqt_offs); |
85 | 484k | if (dqt_offs) { |
86 | 370k | bytestream2_init(&s->gB, buf_ptr+dqt_offs, buf_end - (buf_ptr+dqt_offs)); |
87 | 370k | ret = ff_mjpeg_decode_dqt(s); |
88 | 370k | if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) |
89 | 3.40k | return ret; |
90 | 370k | } |
91 | | |
92 | 481k | dht_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dht is %d and size is %d\n"); |
93 | 481k | av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%"PRIx32"\n", dht_offs); |
94 | 481k | if (dht_offs) { |
95 | 4.17k | bytestream2_init(&s->gB, buf_ptr+dht_offs, buf_end - (buf_ptr+dht_offs)); |
96 | 4.17k | ff_mjpeg_decode_dht(s); |
97 | 4.17k | } |
98 | | |
99 | 481k | sof_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n"); |
100 | 481k | av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%"PRIx32"\n", sof_offs); |
101 | 481k | if (sof_offs) { |
102 | 407k | bytestream2_init(&s->gB, buf_ptr+sof_offs, buf_end - (buf_ptr+sof_offs)); |
103 | 407k | if ((ret = ff_mjpeg_decode_sof(s)) < 0) |
104 | 156k | return ret; |
105 | 407k | } |
106 | | |
107 | 325k | sos_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sos is %d and size is %d\n"); |
108 | 325k | av_log(avctx, AV_LOG_DEBUG, "sos offs: 0x%"PRIx32"\n", sos_offs); |
109 | 325k | sod_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n"); |
110 | 325k | av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%"PRIx32"\n", sod_offs); |
111 | 325k | if (sos_offs) { |
112 | 235k | bytestream2_init(&s->gB, buf_ptr+sos_offs, |
113 | 235k | FFMIN(field_size, buf_end - buf_ptr - sos_offs)); |
114 | 235k | s->mjpb_skiptosod = (sod_offs - sos_offs - bytestream2_peek_be16(&s->gB)); |
115 | 235k | if (avctx->skip_frame == AVDISCARD_ALL) { |
116 | 806 | bytestream2_skipu(&s->gB, bytestream2_get_bytes_left(&s->gB)); |
117 | 234k | } else { |
118 | 234k | ret = ff_mjpeg_decode_sos(s); |
119 | 234k | if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) |
120 | 713 | return ret; |
121 | 234k | } |
122 | 235k | } |
123 | | |
124 | 324k | if (s->interlaced) { |
125 | 227k | s->bottom_field ^= 1; |
126 | | /* if not bottom field, do not output image yet */ |
127 | 227k | if (s->bottom_field != s->interlace_polarity && second_field_offs) { |
128 | 112k | buf_ptr = buf + second_field_offs; |
129 | 112k | goto read_header; |
130 | 112k | } |
131 | 227k | } |
132 | | |
133 | | //XXX FIXME factorize, this looks very similar to the EOI code |
134 | | |
135 | 212k | if(!s->got_picture) { |
136 | 73.7k | av_log(avctx, AV_LOG_WARNING, "no picture\n"); |
137 | 73.7k | return buf_size; |
138 | 73.7k | } |
139 | 138k | av_frame_move_ref(rframe, s->picture_ptr); |
140 | 138k | s->got_picture = 0; |
141 | 138k | if (avctx->skip_frame == AVDISCARD_ALL) |
142 | 515 | return buf_size; |
143 | 137k | *got_frame = 1; |
144 | | |
145 | 137k | if (!s->lossless && avctx->debug & FF_DEBUG_QP) { |
146 | 3.60k | av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", |
147 | 3.60k | FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2])); |
148 | 3.60k | } |
149 | | |
150 | 137k | return buf_size; |
151 | 138k | } |
152 | | |
153 | | const FFCodec ff_mjpegb_decoder = { |
154 | | .p.name = "mjpegb", |
155 | | CODEC_LONG_NAME("Apple MJPEG-B"), |
156 | | .p.type = AVMEDIA_TYPE_VIDEO, |
157 | | .p.id = AV_CODEC_ID_MJPEGB, |
158 | | .priv_data_size = sizeof(MJpegDecodeContext), |
159 | | .init = ff_mjpeg_decode_init, |
160 | | .close = ff_mjpeg_decode_end, |
161 | | FF_CODEC_DECODE_CB(mjpegb_decode_frame), |
162 | | .p.capabilities = AV_CODEC_CAP_DR1, |
163 | | .p.max_lowres = 3, |
164 | | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, |
165 | | }; |
166 | | |
167 | | const FFCodec ff_media100_decoder = { |
168 | | .p.name = "media100", |
169 | | CODEC_LONG_NAME("Media 100"), |
170 | | .p.type = AVMEDIA_TYPE_VIDEO, |
171 | | .p.id = AV_CODEC_ID_MEDIA100, |
172 | | .priv_data_size = sizeof(MJpegDecodeContext), |
173 | | .init = ff_mjpeg_decode_init, |
174 | | .close = ff_mjpeg_decode_end, |
175 | | FF_CODEC_DECODE_CB(mjpegb_decode_frame), |
176 | | .p.capabilities = AV_CODEC_CAP_DR1, |
177 | | .p.max_lowres = 3, |
178 | | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, |
179 | | .bsfs = "media100_to_mjpegb", |
180 | | }; |