Mercurial > libavcodec.hg
comparison vc1.c @ 4462:d47a98f52e25 libavcodec
General approach to parsing chunks in VC-1 AP
author | kostya |
---|---|
date | Fri, 02 Feb 2007 06:45:21 +0000 |
parents | 33f181383a21 |
children | b619aebd8469 |
comparison
equal
deleted
inserted
replaced
4461:c95e0df9841f | 4462:d47a98f52e25 |
---|---|
44 extern const uint16_t ff_msmp4_mb_i_table[64][2]; | 44 extern const uint16_t ff_msmp4_mb_i_table[64][2]; |
45 #define DC_VLC_BITS 9 | 45 #define DC_VLC_BITS 9 |
46 #define AC_VLC_BITS 9 | 46 #define AC_VLC_BITS 9 |
47 static const uint16_t table_mb_intra[64][2]; | 47 static const uint16_t table_mb_intra[64][2]; |
48 | 48 |
49 /** Markers used if VC-1 AP frame data */ | |
50 //@{ | |
51 enum VC1Code{ | |
52 VC1_CODE_RES0 = 0x00000100, | |
53 VC1_CODE_ESCAPE = 0x00000103, | |
54 VC1_CODE_ENDOFSEQ = 0x0000010A, | |
55 VC1_CODE_SLICE, | |
56 VC1_CODE_FIELD, | |
57 VC1_CODE_FRAME, | |
58 VC1_CODE_ENTRYPOINT, | |
59 VC1_CODE_SEQHDR, | |
60 }; | |
61 //@} | |
49 | 62 |
50 /** Available Profiles */ | 63 /** Available Profiles */ |
51 //@{ | 64 //@{ |
52 enum Profile { | 65 enum Profile { |
53 PROFILE_SIMPLE, | 66 PROFILE_SIMPLE, |
4092 vc1_decode_b_blocks(v); | 4105 vc1_decode_b_blocks(v); |
4093 break; | 4106 break; |
4094 } | 4107 } |
4095 } | 4108 } |
4096 | 4109 |
4110 #define IS_MARKER(x) ((((x) & ~0xFF) == VC1_CODE_RES0) && ((x) != VC1_CODE_ESCAPE)) | |
4111 | |
4112 /** Find VC-1 marker in buffer | |
4113 * @return position where next marker starts or end of buffer if no marker found | |
4114 */ | |
4115 static av_always_inline uint8_t* find_next_marker(uint8_t *src, uint8_t *end) | |
4116 { | |
4117 uint32_t mrk = 0xFFFFFFFF; | |
4118 | |
4119 if(end-src < 4) return end; | |
4120 while(src < end){ | |
4121 mrk = (mrk << 8) | *src++; | |
4122 if(IS_MARKER(mrk)) | |
4123 return src-4; | |
4124 } | |
4125 return end; | |
4126 } | |
4127 | |
4128 static av_always_inline int vc1_unescape_buffer(uint8_t *src, int size, uint8_t *dst) | |
4129 { | |
4130 int dsize = 0, i; | |
4131 | |
4132 if(size < 4){ | |
4133 for(dsize = 0; dsize < size; dsize++) *dst++ = *src++; | |
4134 return size; | |
4135 } | |
4136 for(i = 0; i < size; i++, src++) { | |
4137 if(src[0] == 3 && i >= 2 && !src[-1] && !src[-2] && i < size-1 && src[1] < 4) { | |
4138 dst[dsize++] = src[1]; | |
4139 src++; | |
4140 i++; | |
4141 } else | |
4142 dst[dsize++] = *src; | |
4143 } | |
4144 return dsize; | |
4145 } | |
4097 | 4146 |
4098 /** Initialize a VC1/WMV3 decoder | 4147 /** Initialize a VC1/WMV3 decoder |
4099 * @todo TODO: Handle VC-1 IDUs (Transport level?) | 4148 * @todo TODO: Handle VC-1 IDUs (Transport level?) |
4100 * @todo TODO: Decypher remaining bits in extra_data | 4149 * @todo TODO: Decypher remaining bits in extra_data |
4101 */ | 4150 */ |
4143 else if (count < 0) | 4192 else if (count < 0) |
4144 { | 4193 { |
4145 av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count); | 4194 av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count); |
4146 } | 4195 } |
4147 } else { // VC1/WVC1 | 4196 } else { // VC1/WVC1 |
4148 int edata_size = avctx->extradata_size; | 4197 uint8_t *start = avctx->extradata, *end = avctx->extradata + avctx->extradata_size; |
4149 uint8_t *edata = avctx->extradata; | 4198 uint8_t *next; int size, buf2_size; |
4199 uint8_t *buf2 = NULL; | |
4200 int seq_inited = 0, ep_inited = 0; | |
4150 | 4201 |
4151 if(avctx->extradata_size < 16) { | 4202 if(avctx->extradata_size < 16) { |
4152 av_log(avctx, AV_LOG_ERROR, "Extradata size too small: %i\n", edata_size); | 4203 av_log(avctx, AV_LOG_ERROR, "Extradata size too small: %i\n", avctx->extradata_size); |
4153 return -1; | 4204 return -1; |
4154 } | 4205 } |
4155 while(edata_size > 8) { | 4206 |
4156 // test if we've found header | 4207 buf2 = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); |
4157 if(AV_RB32(edata) == 0x0000010F) { | 4208 if(start[0]) start++; // in WVC1 extradata first byte is its size |
4158 edata += 4; | 4209 next = start; |
4159 edata_size -= 4; | 4210 for(; next < end; start = next){ |
4211 next = find_next_marker(start + 4, end); | |
4212 size = next - start - 4; | |
4213 if(size <= 0) continue; | |
4214 buf2_size = vc1_unescape_buffer(start + 4, size, buf2); | |
4215 init_get_bits(&gb, buf2, buf2_size * 8); | |
4216 switch(AV_RB32(start)){ | |
4217 case VC1_CODE_SEQHDR: | |
4218 if(decode_sequence_header(avctx, &gb) < 0){ | |
4219 av_free(buf2); | |
4220 return -1; | |
4221 } | |
4222 seq_inited = 1; | |
4160 break; | 4223 break; |
4161 } | 4224 case VC1_CODE_ENTRYPOINT: |
4162 edata_size--; | 4225 if(decode_entry_point(avctx, &gb) < 0){ |
4163 edata++; | 4226 av_free(buf2); |
4164 } | 4227 return -1; |
4165 | 4228 } |
4166 init_get_bits(&gb, edata, edata_size*8); | 4229 ep_inited = 1; |
4167 | |
4168 if (decode_sequence_header(avctx, &gb) < 0) | |
4169 return -1; | |
4170 | |
4171 while(edata_size > 8) { | |
4172 // test if we've found entry point | |
4173 if(AV_RB32(edata) == 0x0000010E) { | |
4174 edata += 4; | |
4175 edata_size -= 4; | |
4176 break; | 4230 break; |
4177 } | 4231 } |
4178 edata_size--; | 4232 } |
4179 edata++; | 4233 av_free(buf2); |
4180 } | 4234 if(!seq_inited || !ep_inited){ |
4181 | 4235 av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n"); |
4182 init_get_bits(&gb, edata, edata_size*8); | 4236 return -1; |
4183 | 4237 } |
4184 if (decode_entry_point(avctx, &gb) < 0) | |
4185 return -1; | |
4186 } | 4238 } |
4187 avctx->has_b_frames= !!(avctx->max_b_frames); | 4239 avctx->has_b_frames= !!(avctx->max_b_frames); |
4188 s->low_delay = !avctx->has_b_frames; | 4240 s->low_delay = !avctx->has_b_frames; |
4189 | 4241 |
4190 s->mb_width = (avctx->coded_width+15)>>4; | 4242 s->mb_width = (avctx->coded_width+15)>>4; |
4244 if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ | 4296 if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ |
4245 int i= ff_find_unused_picture(s, 0); | 4297 int i= ff_find_unused_picture(s, 0); |
4246 s->current_picture_ptr= &s->picture[i]; | 4298 s->current_picture_ptr= &s->picture[i]; |
4247 } | 4299 } |
4248 | 4300 |
4249 //for advanced profile we need to unescape buffer | 4301 //for advanced profile we may need to parse and unescape data |
4250 if (avctx->codec_id == CODEC_ID_VC1) { | 4302 if (avctx->codec_id == CODEC_ID_VC1) { |
4251 int i, buf_size2; | 4303 int buf_size2 = 0; |
4252 buf2 = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); | 4304 buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); |
4253 buf_size2 = 0; | 4305 |
4254 for(i = 0; i < buf_size; i++) { | 4306 if(IS_MARKER(AV_RB32(buf))){ /* frame starts with marker and needs to be parsed */ |
4255 if(buf[i] == 3 && i >= 2 && !buf[i-1] && !buf[i-2] && i < buf_size-1 && buf[i+1] < 4) { | 4307 uint8_t *dst = buf2, *start, *end, *next; |
4256 buf2[buf_size2++] = buf[i+1]; | 4308 int size; |
4257 i++; | 4309 |
4258 } else | 4310 next = buf; |
4259 buf2[buf_size2++] = buf[i]; | 4311 for(start = buf, end = buf + buf_size; next < end; start = next){ |
4312 next = find_next_marker(start + 4, end); | |
4313 size = next - start - 4; | |
4314 if(size <= 0) continue; | |
4315 switch(AV_RB32(start)){ | |
4316 case VC1_CODE_FRAME: | |
4317 buf_size2 = vc1_unescape_buffer(start + 4, size, buf2); | |
4318 break; | |
4319 case VC1_CODE_ENTRYPOINT: /* it should be before frame data */ | |
4320 buf_size2 = vc1_unescape_buffer(start + 4, size, buf2); | |
4321 init_get_bits(&s->gb, buf2, buf_size2*8); | |
4322 decode_entry_point(avctx, &s->gb); | |
4323 break; | |
4324 case VC1_CODE_SLICE: | |
4325 av_log(avctx, AV_LOG_ERROR, "Sliced decoding is not implemented (yet)\n"); | |
4326 av_free(buf2); | |
4327 return -1; | |
4328 } | |
4329 } | |
4330 }else if(v->interlace && ((buf[0] & 0xC0) == 0xC0)){ /* WVC1 interlaced stores both fields divided by marker */ | |
4331 uint8_t *divider; | |
4332 | |
4333 divider = find_next_marker(buf, buf + buf_size); | |
4334 if((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD){ | |
4335 av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n"); | |
4336 return -1; | |
4337 } | |
4338 | |
4339 buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2); | |
4340 // TODO | |
4341 av_free(buf2);return -1; | |
4342 }else{ | |
4343 buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2); | |
4260 } | 4344 } |
4261 init_get_bits(&s->gb, buf2, buf_size2*8); | 4345 init_get_bits(&s->gb, buf2, buf_size2*8); |
4262 } else | 4346 } else |
4263 init_get_bits(&s->gb, buf, buf_size*8); | 4347 init_get_bits(&s->gb, buf, buf_size*8); |
4264 // do parse frame header | 4348 // do parse frame header |