Mercurial > libavcodec.hg
annotate ljpegenc.c @ 11557:53822d92c3f7 libavcodec
Make sure the EC code does not attempt to use inter based concealment if there
is no reference frame available. (this can happen because the EC code will attempt
to use reference frames even for I/IDR frames)
author | michael |
---|---|
date | Tue, 30 Mar 2010 20:46:46 +0000 |
parents | 6eefb31b1bfc |
children | 8a4984c5cacc |
rev | line source |
---|---|
5020 | 1 /* |
5028 | 2 * lossless JPEG encoder |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
7744
diff
changeset
|
3 * Copyright (c) 2000, 2001 Fabrice Bellard |
5020 | 4 * Copyright (c) 2003 Alex Beregszaszi |
5 * Copyright (c) 2003-2004 Michael Niedermayer | |
6 * | |
5214 | 7 * Support for external huffman table, various fixes (AVID workaround), |
8 * aspecting, new decode_frame mechanism and apple mjpeg-b support | |
9 * by Alex Beregszaszi | |
10 * | |
5020 | 11 * This file is part of FFmpeg. |
12 * | |
13 * FFmpeg is free software; you can redistribute it and/or | |
14 * modify it under the terms of the GNU Lesser General Public | |
15 * License as published by the Free Software Foundation; either | |
16 * version 2.1 of the License, or (at your option) any later version. | |
17 * | |
18 * FFmpeg is distributed in the hope that it will be useful, | |
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
21 * Lesser General Public License for more details. | |
22 * | |
23 * You should have received a copy of the GNU Lesser General Public | |
24 * License along with FFmpeg; if not, write to the Free Software | |
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
26 */ | |
27 | |
28 /** | |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8629
diff
changeset
|
29 * @file libavcodec/ljpegenc.c |
5028 | 30 * lossless JPEG encoder. |
5020 | 31 */ |
32 | |
33 #include "avcodec.h" | |
34 #include "dsputil.h" | |
35 #include "mpegvideo.h" | |
36 #include "mjpeg.h" | |
5028 | 37 #include "mjpegenc.h" |
5020 | 38 |
39 | |
40 static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ | |
41 MpegEncContext * const s = avctx->priv_data; | |
42 MJpegContext * const m = s->mjpeg_ctx; | |
43 AVFrame *pict = data; | |
44 const int width= s->width; | |
45 const int height= s->height; | |
46 AVFrame * const p= (AVFrame*)&s->current_picture; | |
47 const int predictor= avctx->prediction_method+1; | |
48 | |
49 init_put_bits(&s->pb, buf, buf_size); | |
50 | |
51 *p = *pict; | |
52 p->pict_type= FF_I_TYPE; | |
53 p->key_frame= 1; | |
54 | |
5029
dbaa06366c3c
add a proper prefix to all mjpeg encoder exported functions
aurel
parents:
5028
diff
changeset
|
55 ff_mjpeg_encode_picture_header(s); |
5020 | 56 |
57 s->header_bits= put_bits_count(&s->pb); | |
58 | |
10668 | 59 if(avctx->pix_fmt == PIX_FMT_BGRA){ |
5020 | 60 int x, y, i; |
61 const int linesize= p->linesize[0]; | |
62 uint16_t (*buffer)[4]= (void *) s->rd_scratchpad; | |
63 int left[3], top[3], topleft[3]; | |
64 | |
65 for(i=0; i<3; i++){ | |
66 buffer[0][i]= 1 << (9 - 1); | |
67 } | |
68 | |
69 for(y = 0; y < height; y++) { | |
70 const int modified_predictor= y ? predictor : 1; | |
71 uint8_t *ptr = p->data[0] + (linesize * y); | |
72 | |
73 if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < width*3*4){ | |
74 av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
75 return -1; | |
76 } | |
77 | |
78 for(i=0; i<3; i++){ | |
79 top[i]= left[i]= topleft[i]= buffer[0][i]; | |
80 } | |
81 for(x = 0; x < width; x++) { | |
82 buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100; | |
83 buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100; | |
84 buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2; | |
85 | |
86 for(i=0;i<3;i++) { | |
87 int pred, diff; | |
88 | |
89 PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); | |
90 | |
91 topleft[i]= top[i]; | |
92 top[i]= buffer[x+1][i]; | |
93 | |
94 left[i]= buffer[x][i]; | |
95 | |
96 diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100; | |
97 | |
98 if(i==0) | |
5029
dbaa06366c3c
add a proper prefix to all mjpeg encoder exported functions
aurel
parents:
5028
diff
changeset
|
99 ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly |
5020 | 100 else |
5029
dbaa06366c3c
add a proper prefix to all mjpeg encoder exported functions
aurel
parents:
5028
diff
changeset
|
101 ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); |
5020 | 102 } |
103 } | |
104 } | |
105 }else{ | |
106 int mb_x, mb_y, i; | |
107 const int mb_width = (width + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0]; | |
108 const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0]; | |
109 | |
110 for(mb_y = 0; mb_y < mb_height; mb_y++) { | |
111 if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < mb_width * 4 * 3 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]){ | |
112 av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
113 return -1; | |
114 } | |
115 for(mb_x = 0; mb_x < mb_width; mb_x++) { | |
116 if(mb_x==0 || mb_y==0){ | |
117 for(i=0;i<3;i++) { | |
118 uint8_t *ptr; | |
119 int x, y, h, v, linesize; | |
120 h = s->mjpeg_hsample[i]; | |
121 v = s->mjpeg_vsample[i]; | |
122 linesize= p->linesize[i]; | |
123 | |
124 for(y=0; y<v; y++){ | |
125 for(x=0; x<h; x++){ | |
126 int pred; | |
127 | |
128 ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap | |
129 if(y==0 && mb_y==0){ | |
130 if(x==0 && mb_x==0){ | |
131 pred= 128; | |
132 }else{ | |
133 pred= ptr[-1]; | |
134 } | |
135 }else{ | |
136 if(x==0 && mb_x==0){ | |
137 pred= ptr[-linesize]; | |
138 }else{ | |
139 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); | |
140 } | |
141 } | |
142 | |
143 if(i==0) | |
7744
7477cbdacb20
Fix lossless jpeg encoder to comply to spec and store full redundant
michael
parents:
7040
diff
changeset
|
144 ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly |
5020 | 145 else |
7744
7477cbdacb20
Fix lossless jpeg encoder to comply to spec and store full redundant
michael
parents:
7040
diff
changeset
|
146 ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); |
5020 | 147 } |
148 } | |
149 } | |
150 }else{ | |
151 for(i=0;i<3;i++) { | |
152 uint8_t *ptr; | |
153 int x, y, h, v, linesize; | |
154 h = s->mjpeg_hsample[i]; | |
155 v = s->mjpeg_vsample[i]; | |
156 linesize= p->linesize[i]; | |
157 | |
158 for(y=0; y<v; y++){ | |
159 for(x=0; x<h; x++){ | |
160 int pred; | |
161 | |
162 ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap | |
163 //printf("%d %d %d %d %8X\n", mb_x, mb_y, x, y, ptr); | |
164 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); | |
165 | |
166 if(i==0) | |
7744
7477cbdacb20
Fix lossless jpeg encoder to comply to spec and store full redundant
michael
parents:
7040
diff
changeset
|
167 ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly |
5020 | 168 else |
7744
7477cbdacb20
Fix lossless jpeg encoder to comply to spec and store full redundant
michael
parents:
7040
diff
changeset
|
169 ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); |
5020 | 170 } |
171 } | |
172 } | |
173 } | |
174 } | |
175 } | |
176 } | |
177 | |
178 emms_c(); | |
179 | |
5029
dbaa06366c3c
add a proper prefix to all mjpeg encoder exported functions
aurel
parents:
5028
diff
changeset
|
180 ff_mjpeg_encode_picture_trailer(s); |
5020 | 181 s->picture_number++; |
182 | |
183 flush_put_bits(&s->pb); | |
9431 | 184 return put_bits_ptr(&s->pb) - s->pb.buf; |
5020 | 185 // return (put_bits_count(&f->pb)+7)/8; |
186 } | |
187 | |
188 | |
5127 | 189 AVCodec ljpeg_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them |
5020 | 190 "ljpeg", |
191 CODEC_TYPE_VIDEO, | |
192 CODEC_ID_LJPEG, | |
193 sizeof(MpegEncContext), | |
194 MPV_encode_init, | |
195 encode_picture_lossless, | |
196 MPV_encode_end, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6717
diff
changeset
|
197 .long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"), |
5020 | 198 }; |