Mercurial > libavcodec.hg
annotate sgienc.c @ 8991:ca768cb2bfb6 libavcodec
Use last decoded SPS as current SPS in order to parse picture timing SEI
correctly. This works around an apparent H.264 standard deficiency.
Patch by Ivan Schreter, schreter gmx net
author | cehoyos |
---|---|
date | Fri, 20 Feb 2009 16:20:01 +0000 |
parents | e943e1409077 |
children | 777deb3dc12b |
rev | line source |
---|---|
4790 | 1 /* |
2 * SGI image encoder | |
3 * Todd Kirby <doubleshot@pacbell.net> | |
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 #include "avcodec.h" | |
23 #include "bytestream.h" | |
24 #include "sgi.h" | |
25 #include "rle.h" | |
26 | |
27 #define SGI_SINGLE_CHAN 2 | |
28 #define SGI_MULTI_CHAN 3 | |
29 | |
30 typedef struct SgiContext { | |
31 AVFrame picture; | |
32 } SgiContext; | |
33 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
4790
diff
changeset
|
34 static av_cold int encode_init(AVCodecContext *avctx){ |
4790 | 35 SgiContext *s = avctx->priv_data; |
36 | |
37 avcodec_get_frame_defaults(&s->picture); | |
38 avctx->coded_frame = &s->picture; | |
39 | |
40 return 0; | |
41 } | |
42 | |
43 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, | |
44 int buf_size, void *data) { | |
45 SgiContext *s = avctx->priv_data; | |
46 AVFrame * const p = &s->picture; | |
47 uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf; | |
48 int x, y, z, length, tablesize; | |
49 unsigned int width, height, depth, dimension; | |
50 unsigned char *orig_buf = buf, *end_buf = buf + buf_size; | |
51 | |
52 *p = *(AVFrame*)data; | |
53 p->pict_type = FF_I_TYPE; | |
54 p->key_frame = 1; | |
55 | |
56 width = avctx->width; | |
57 height = avctx->height; | |
58 | |
59 switch (avctx->pix_fmt) { | |
60 case PIX_FMT_GRAY8: | |
61 dimension = SGI_SINGLE_CHAN; | |
62 depth = SGI_GRAYSCALE; | |
63 break; | |
64 case PIX_FMT_RGB24: | |
65 dimension = SGI_MULTI_CHAN; | |
66 depth = SGI_RGB; | |
67 break; | |
68 case PIX_FMT_RGBA: | |
69 dimension = SGI_MULTI_CHAN; | |
70 depth = SGI_RGBA; | |
71 break; | |
72 default: | |
73 return AVERROR_INVALIDDATA; | |
74 } | |
75 | |
76 tablesize = depth * height * 4; | |
77 length = tablesize * 2 + SGI_HEADER_SIZE; | |
78 | |
79 if (buf_size < length) { | |
80 av_log(avctx, AV_LOG_ERROR, "buf_size too small(need %d, got %d)\n", length, buf_size); | |
81 return -1; | |
82 } | |
83 | |
84 /* Encode header. */ | |
85 bytestream_put_be16(&buf, SGI_MAGIC); | |
86 bytestream_put_byte(&buf, 1); /* RLE */ | |
87 bytestream_put_byte(&buf, 1); /* bytes_per_channel */ | |
88 bytestream_put_be16(&buf, dimension); | |
89 bytestream_put_be16(&buf, width); | |
90 bytestream_put_be16(&buf, height); | |
91 bytestream_put_be16(&buf, depth); | |
92 | |
93 /* The rest are constant in this implementation. */ | |
94 bytestream_put_be32(&buf, 0L); /* pixmin */ | |
95 bytestream_put_be32(&buf, 255L); /* pixmax */ | |
96 bytestream_put_be32(&buf, 0L); /* dummy */ | |
97 | |
98 /* name */ | |
99 memset(buf, 0, SGI_HEADER_SIZE); | |
100 buf += 80; | |
101 | |
102 /* colormap */ | |
103 bytestream_put_be32(&buf, 0L); | |
104 | |
105 /* The rest of the 512 byte header is unused. */ | |
106 buf += 404; | |
107 offsettab = buf; | |
108 | |
109 /* Skip RLE offset table. */ | |
110 buf += tablesize; | |
111 lengthtab = buf; | |
112 | |
113 /* Skip RLE length table. */ | |
114 buf += tablesize; | |
115 | |
116 /* Make an intermediate consecutive buffer. */ | |
117 if ((encode_buf = av_malloc(width)) == NULL) | |
118 return -1; | |
119 | |
120 for (z = 0; z < depth; z++) { | |
121 in_buf = p->data[0] + p->linesize[0] * (height - 1) + z; | |
122 | |
123 for (y = 0; y < height; y++) { | |
124 bytestream_put_be32(&offsettab, buf - orig_buf); | |
125 | |
126 for (x = 0; x < width; x++) | |
127 encode_buf[x] = in_buf[depth * x]; | |
128 | |
129 if((length = ff_rle_encode(buf, end_buf - buf - 1, encode_buf, 1, width, 0, 0, 0x80, 0)) < 1) { | |
130 av_free(encode_buf); | |
131 return -1; | |
132 } | |
133 | |
134 buf += length; | |
135 bytestream_put_byte(&buf, 0); | |
136 bytestream_put_be32(&lengthtab, length + 1); | |
137 in_buf -= p->linesize[0]; | |
138 } | |
139 } | |
140 | |
141 av_free(encode_buf); | |
142 /* total length */ | |
143 return buf - orig_buf; | |
144 } | |
145 | |
146 AVCodec sgi_encoder = { | |
147 "sgi", | |
148 CODEC_TYPE_VIDEO, | |
149 CODEC_ID_SGI, | |
150 sizeof(SgiContext), | |
151 encode_init, | |
152 encode_frame, | |
153 NULL, | |
6788 | 154 .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_NONE}, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6788
diff
changeset
|
155 .long_name= NULL_IF_CONFIG_SMALL("SGI image"), |
4790 | 156 }; |
157 |