annotate frwu.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 8a4984c5cacc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10394
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
1 /*
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
2 * Forward Uncompressed
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
3 *
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
4 * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
5 *
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
6 * This file is part of FFmpeg.
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
7 *
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
12 *
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
16 * Lesser General Public License for more details.
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
17 *
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
21 */
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
22
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
23 #include "avcodec.h"
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
24 #include "bytestream.h"
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
25 #include "libavutil/intreadwrite.h"
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
26
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
27 static av_cold int decode_init(AVCodecContext *avctx)
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
28 {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
29 if (avctx->width & 1) {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
30 av_log(avctx, AV_LOG_ERROR, "FRWU needs even width\n");
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
31 return -1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
32 }
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
33 avctx->pix_fmt = PIX_FMT_UYVY422;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
34
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
35 avctx->coded_frame = avcodec_alloc_frame();
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
36
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
37 return 0;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
38 }
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
39
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
40 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
41 AVPacket *avpkt)
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
42 {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
43 int field;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
44 AVFrame *pic = avctx->coded_frame;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
45 const uint8_t *buf = avpkt->data;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
46 const uint8_t *buf_end = buf + avpkt->size;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
47
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
48 if (pic->data[0])
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
49 avctx->release_buffer(avctx, pic);
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
50
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
51 if (avpkt->size < avctx->width * 2 * avctx->height + 4 + 2*8) {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
52 av_log(avctx, AV_LOG_ERROR, "Packet is too small.\n");
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
53 return -1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
54 }
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
55 if (bytestream_get_le32(&buf) != AV_RL32("FRW1")) {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
56 av_log(avctx, AV_LOG_ERROR, "incorrect marker\n");
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
57 return -1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
58 }
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
59
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
60 pic->reference = 0;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
61 if (avctx->get_buffer(avctx, pic) < 0)
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
62 return -1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
63
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
64 pic->pict_type = FF_I_TYPE;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
65 pic->key_frame = 1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
66 pic->interlaced_frame = 1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
67 pic->top_field_first = 1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
68
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
69 for (field = 0; field < 2; field++) {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
70 int i;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
71 int field_h = (avctx->height + !field) >> 1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
72 int field_size, min_field_size = avctx->width * 2 * field_h;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
73 uint8_t *dst = pic->data[0];
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
74 if (buf_end - buf < 8)
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
75 return -1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
76 buf += 4; // flags? 0x80 == bottom field maybe?
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
77 field_size = bytestream_get_le32(&buf);
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
78 if (field_size < min_field_size) {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
79 av_log(avctx, AV_LOG_ERROR, "Field size %i is too small (required %i)\n", field_size, min_field_size);
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
80 return -1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
81 }
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
82 if (buf_end - buf < field_size) {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
83 av_log(avctx, AV_LOG_ERROR, "Packet is too small, need %i, have %i\n", field_size, (int)(buf_end - buf));
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
84 return -1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
85 }
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
86 if (field)
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
87 dst += pic->linesize[0];
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
88 for (i = 0; i < field_h; i++) {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
89 memcpy(dst, buf, avctx->width * 2);
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
90 buf += avctx->width * 2;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
91 dst += pic->linesize[0] << 1;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
92 }
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
93 buf += field_size - min_field_size;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
94 }
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
95
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
96 *data_size = sizeof(AVFrame);
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
97 *(AVFrame*)data = *pic;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
98
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
99 return avpkt->size;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
100 }
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
101
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
102 static av_cold int decode_close(AVCodecContext *avctx)
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
103 {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
104 AVFrame *pic = avctx->coded_frame;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
105 if (pic->data[0])
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
106 avctx->release_buffer(avctx, pic);
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
107 av_freep(&avctx->coded_frame);
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
108
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
109 return 0;
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
110 }
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
111
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
112 AVCodec frwu_decoder = {
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
113 "FRWU",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10394
diff changeset
114 AVMEDIA_TYPE_VIDEO,
10394
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
115 CODEC_ID_FRWU,
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
116 0,
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
117 decode_init,
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
118 NULL,
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
119 decode_close,
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
120 decode_frame,
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
121 CODEC_CAP_DR1,
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
122 .long_name = NULL_IF_CONFIG_SMALL("Forward Uncompressed"),
81cf22a16ab3 Add decoder for "forward uncompressed".
reimar
parents:
diff changeset
123 };