Mercurial > libavcodec.hg
annotate wmv2enc.c @ 7744:7477cbdacb20 libavcodec
Fix lossless jpeg encoder to comply to spec and store full redundant
residuals, Note this does not change RGB32 as we need to check this
against some decoder that supports it.
author | michael |
---|---|
date | Sat, 30 Aug 2008 20:39:12 +0000 |
parents | e943e1409077 |
children | 04423b2f6e0b |
rev | line source |
---|---|
5939 | 1 /* |
2 * Copyright (c) 2002 The FFmpeg Project. | |
3 * | |
4 * This file is part of FFmpeg. | |
5 * | |
6 * FFmpeg is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2.1 of the License, or (at your option) any later version. | |
10 * | |
11 * FFmpeg is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with FFmpeg; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 */ | |
20 | |
21 #include "avcodec.h" | |
22 #include "dsputil.h" | |
23 #include "mpegvideo.h" | |
24 #include "msmpeg4.h" | |
25 #include "msmpeg4data.h" | |
26 #include "wmv2.h" | |
27 | |
28 | |
29 static int encode_ext_header(Wmv2Context *w){ | |
30 MpegEncContext * const s= &w->s; | |
31 PutBitContext pb; | |
32 int code; | |
33 | |
34 init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size); | |
35 | |
36 put_bits(&pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29 | |
37 put_bits(&pb, 11, FFMIN(s->bit_rate/1024, 2047)); | |
38 | |
39 put_bits(&pb, 1, w->mspel_bit=1); | |
40 put_bits(&pb, 1, s->loop_filter); | |
41 put_bits(&pb, 1, w->abt_flag=1); | |
42 put_bits(&pb, 1, w->j_type_bit=1); | |
43 put_bits(&pb, 1, w->top_left_mv_flag=0); | |
44 put_bits(&pb, 1, w->per_mb_rl_bit=1); | |
45 put_bits(&pb, 3, code=1); | |
46 | |
47 flush_put_bits(&pb); | |
48 | |
49 s->slice_height = s->mb_height / code; | |
50 | |
51 return 0; | |
52 } | |
53 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6481
diff
changeset
|
54 static av_cold int wmv2_encode_init(AVCodecContext *avctx){ |
5939 | 55 Wmv2Context * const w= avctx->priv_data; |
56 | |
57 if(MPV_encode_init(avctx) < 0) | |
58 return -1; | |
59 | |
60 ff_wmv2_common_init(w); | |
61 | |
62 avctx->extradata_size= 4; | |
63 avctx->extradata= av_mallocz(avctx->extradata_size + 10); | |
64 encode_ext_header(w); | |
65 | |
66 return 0; | |
67 } | |
68 | |
69 #if 0 /* unused, remove? */ | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6481
diff
changeset
|
70 static av_cold int wmv2_encode_end(AVCodecContext *avctx){ |
5939 | 71 |
72 if(MPV_encode_end(avctx) < 0) | |
73 return -1; | |
74 | |
75 avctx->extradata_size= 0; | |
76 av_freep(&avctx->extradata); | |
77 | |
78 return 0; | |
79 } | |
80 #endif | |
81 | |
82 int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number) | |
83 { | |
84 Wmv2Context * const w= (Wmv2Context*)s; | |
85 | |
86 put_bits(&s->pb, 1, s->pict_type - 1); | |
6481 | 87 if(s->pict_type == FF_I_TYPE){ |
5939 | 88 put_bits(&s->pb, 7, 0); |
89 } | |
90 put_bits(&s->pb, 5, s->qscale); | |
91 | |
92 s->dc_table_index = 1; | |
93 s->mv_table_index = 1; /* only if P frame */ | |
94 // s->use_skip_mb_code = 1; /* only if P frame */ | |
95 s->per_mb_rl_table = 0; | |
96 s->mspel= 0; | |
97 w->per_mb_abt=0; | |
98 w->abt_type=0; | |
99 w->j_type=0; | |
100 | |
101 assert(s->flipflop_rounding); | |
102 | |
6481 | 103 if (s->pict_type == FF_I_TYPE) { |
5939 | 104 assert(s->no_rounding==1); |
105 if(w->j_type_bit) put_bits(&s->pb, 1, w->j_type); | |
106 | |
107 if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); | |
108 | |
109 if(!s->per_mb_rl_table){ | |
110 ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index); | |
111 ff_msmpeg4_code012(&s->pb, s->rl_table_index); | |
112 } | |
113 | |
114 put_bits(&s->pb, 1, s->dc_table_index); | |
115 | |
116 s->inter_intra_pred= 0; | |
117 }else{ | |
118 int cbp_index; | |
119 | |
120 put_bits(&s->pb, 2, SKIP_TYPE_NONE); | |
121 | |
122 ff_msmpeg4_code012(&s->pb, cbp_index=0); | |
123 if(s->qscale <= 10){ | |
124 int map[3]= {0,2,1}; | |
125 w->cbp_table_index= map[cbp_index]; | |
126 }else if(s->qscale <= 20){ | |
127 int map[3]= {1,0,2}; | |
128 w->cbp_table_index= map[cbp_index]; | |
129 }else{ | |
130 int map[3]= {2,1,0}; | |
131 w->cbp_table_index= map[cbp_index]; | |
132 } | |
133 | |
134 if(w->mspel_bit) put_bits(&s->pb, 1, s->mspel); | |
135 | |
136 if(w->abt_flag){ | |
137 put_bits(&s->pb, 1, w->per_mb_abt^1); | |
138 if(!w->per_mb_abt){ | |
139 ff_msmpeg4_code012(&s->pb, w->abt_type); | |
140 } | |
141 } | |
142 | |
143 if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); | |
144 | |
145 if(!s->per_mb_rl_table){ | |
146 ff_msmpeg4_code012(&s->pb, s->rl_table_index); | |
147 s->rl_chroma_table_index = s->rl_table_index; | |
148 } | |
149 put_bits(&s->pb, 1, s->dc_table_index); | |
150 put_bits(&s->pb, 1, s->mv_table_index); | |
151 | |
152 s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); | |
153 } | |
154 s->esc3_level_length= 0; | |
155 s->esc3_run_length= 0; | |
156 | |
157 return 0; | |
158 } | |
159 | |
160 /* Nearly identical to wmv1 but that is just because we do not use the | |
161 * useless M$ crap features. It is duplicated here in case someone wants | |
162 * to add support for these crap features. */ | |
163 void ff_wmv2_encode_mb(MpegEncContext * s, | |
164 DCTELEM block[6][64], | |
165 int motion_x, int motion_y) | |
166 { | |
167 Wmv2Context * const w= (Wmv2Context*)s; | |
168 int cbp, coded_cbp, i; | |
169 int pred_x, pred_y; | |
170 uint8_t *coded_block; | |
171 | |
172 ff_msmpeg4_handle_slices(s); | |
173 | |
174 if (!s->mb_intra) { | |
175 /* compute cbp */ | |
176 cbp = 0; | |
177 for (i = 0; i < 6; i++) { | |
178 if (s->block_last_index[i] >= 0) | |
179 cbp |= 1 << (5 - i); | |
180 } | |
181 | |
182 put_bits(&s->pb, | |
183 wmv2_inter_table[w->cbp_table_index][cbp + 64][1], | |
184 wmv2_inter_table[w->cbp_table_index][cbp + 64][0]); | |
185 | |
186 /* motion vector */ | |
187 h263_pred_motion(s, 0, 0, &pred_x, &pred_y); | |
188 ff_msmpeg4_encode_motion(s, motion_x - pred_x, | |
189 motion_y - pred_y); | |
190 } else { | |
191 /* compute cbp */ | |
192 cbp = 0; | |
193 coded_cbp = 0; | |
194 for (i = 0; i < 6; i++) { | |
195 int val, pred; | |
196 val = (s->block_last_index[i] >= 1); | |
197 cbp |= val << (5 - i); | |
198 if (i < 4) { | |
199 /* predict value for close blocks only for luma */ | |
200 pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block); | |
201 *coded_block = val; | |
202 val = val ^ pred; | |
203 } | |
204 coded_cbp |= val << (5 - i); | |
205 } | |
206 #if 0 | |
207 if (coded_cbp) | |
208 printf("cbp=%x %x\n", cbp, coded_cbp); | |
209 #endif | |
210 | |
6481 | 211 if (s->pict_type == FF_I_TYPE) { |
5939 | 212 put_bits(&s->pb, |
213 ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); | |
214 } else { | |
215 put_bits(&s->pb, | |
216 wmv2_inter_table[w->cbp_table_index][cbp][1], | |
217 wmv2_inter_table[w->cbp_table_index][cbp][0]); | |
218 } | |
219 put_bits(&s->pb, 1, 0); /* no AC prediction yet */ | |
220 if(s->inter_intra_pred){ | |
221 s->h263_aic_dir=0; | |
222 put_bits(&s->pb, table_inter_intra[s->h263_aic_dir][1], table_inter_intra[s->h263_aic_dir][0]); | |
223 } | |
224 } | |
225 | |
226 for (i = 0; i < 6; i++) { | |
227 ff_msmpeg4_encode_block(s, block[i], i); | |
228 } | |
229 } | |
230 | |
231 AVCodec wmv2_encoder = { | |
232 "wmv2", | |
233 CODEC_TYPE_VIDEO, | |
234 CODEC_ID_WMV2, | |
235 sizeof(Wmv2Context), | |
236 wmv2_encode_init, | |
237 MPV_encode_picture, | |
238 MPV_encode_end, | |
6788 | 239 .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6788
diff
changeset
|
240 .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 8"), |
5939 | 241 }; |