1/* 2 * VC-1 and WMV3 parser 3 * Copyright (c) 2006-2007 Konstantin Shishkov 4 * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer 5 * 6 * This file is part of FFmpeg. 7 * 8 * FFmpeg is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * FFmpeg is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with FFmpeg; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23/** 24 * @file 25 * VC-1 and WMV3 parser 26 */ 27 28#include "libavutil/attributes.h" 29#include "parser.h" 30#include "vc1.h" 31#include "get_bits.h" 32 33/** The maximum number of bytes of a sequence, entry point or 34 * frame header whose values we pay any attention to */ 35#define UNESCAPED_THRESHOLD 37 36 37/** The maximum number of bytes of a sequence, entry point or 38 * frame header which must be valid memory (because they are 39 * used to update the bitstream cache in skip_bits() calls) 40 */ 41#define UNESCAPED_LIMIT 144 42 43typedef enum { 44 NO_MATCH, 45 ONE_ZERO, 46 TWO_ZEROS, 47 ONE 48} VC1ParseSearchState; 49 50typedef struct { 51 ParseContext pc; 52 VC1Context v; 53 uint8_t prev_start_code; 54 size_t bytes_to_skip; 55 uint8_t unesc_buffer[UNESCAPED_LIMIT]; 56 size_t unesc_index; 57 VC1ParseSearchState search_state; 58} VC1ParseContext; 59 60static void vc1_extract_header(AVCodecParserContext *s, AVCodecContext *avctx, 61 const uint8_t *buf, int buf_size) 62{ 63 /* Parse the header we just finished unescaping */ 64 VC1ParseContext *vpc = s->priv_data; 65 GetBitContext gb; 66 int ret; 67 vpc->v.s.avctx = avctx; 68 vpc->v.parse_only = 1; 69 init_get_bits(&gb, buf, buf_size * 8); 70 switch (vpc->prev_start_code) { 71 case VC1_CODE_SEQHDR & 0xFF: 72 ff_vc1_decode_sequence_header(avctx, &vpc->v, &gb); 73 break; 74 case VC1_CODE_ENTRYPOINT & 0xFF: 75 ff_vc1_decode_entry_point(avctx, &vpc->v, &gb); 76 break; 77 case VC1_CODE_FRAME & 0xFF: 78 if(vpc->v.profile < PROFILE_ADVANCED) 79 ret = ff_vc1_parse_frame_header (&vpc->v, &gb); 80 else 81 ret = ff_vc1_parse_frame_header_adv(&vpc->v, &gb); 82 83 if (ret < 0) 84 break; 85 86 /* keep AV_PICTURE_TYPE_BI internal to VC1 */ 87 if (vpc->v.s.pict_type == AV_PICTURE_TYPE_BI) 88 s->pict_type = AV_PICTURE_TYPE_B; 89 else 90 s->pict_type = vpc->v.s.pict_type; 91 92 if (avctx->ticks_per_frame > 1){ 93 // process pulldown flags 94 s->repeat_pict = 1; 95 // Pulldown flags are only valid when 'broadcast' has been set. 96 // So ticks_per_frame will be 2 97 if (vpc->v.rff){ 98 // repeat field 99 s->repeat_pict = 2; 100 }else if (vpc->v.rptfrm){ 101 // repeat frames 102 s->repeat_pict = vpc->v.rptfrm * 2 + 1; 103 } 104 }else{ 105 s->repeat_pict = 0; 106 } 107 108 if (vpc->v.broadcast && vpc->v.interlace && !vpc->v.psf) 109 s->field_order = vpc->v.tff ? AV_FIELD_TT : AV_FIELD_BB; 110 else 111 s->field_order = AV_FIELD_PROGRESSIVE; 112 113 break; 114 } 115} 116 117static int vc1_parse(AVCodecParserContext *s, 118 AVCodecContext *avctx, 119 const uint8_t **poutbuf, int *poutbuf_size, 120 const uint8_t *buf, int buf_size) 121{ 122 /* Here we do the searching for frame boundaries and headers at 123 * the same time. Only a minimal amount at the start of each 124 * header is unescaped. */ 125 VC1ParseContext *vpc = s->priv_data; 126 int pic_found = vpc->pc.frame_start_found; 127 uint8_t *unesc_buffer = vpc->unesc_buffer; 128 size_t unesc_index = vpc->unesc_index; 129 VC1ParseSearchState search_state = vpc->search_state; 130 int next = END_NOT_FOUND; 131 int i = vpc->bytes_to_skip; 132 133 if (pic_found && buf_size == 0) { 134 /* EOF considered as end of frame */ 135 memset(unesc_buffer + unesc_index, 0, UNESCAPED_THRESHOLD - unesc_index); 136 vc1_extract_header(s, avctx, unesc_buffer, unesc_index); 137 next = 0; 138 } 139 while (i < buf_size) { 140 int start_code_found = 0; 141 uint8_t b; 142 while (i < buf_size && unesc_index < UNESCAPED_THRESHOLD) { 143 b = buf[i++]; 144 unesc_buffer[unesc_index++] = b; 145 if (search_state <= ONE_ZERO) 146 search_state = b ? NO_MATCH : search_state + 1; 147 else if (search_state == TWO_ZEROS) { 148 if (b == 1) 149 search_state = ONE; 150 else if (b > 1) { 151 if (b == 3) 152 unesc_index--; // swallow emulation prevention byte 153 search_state = NO_MATCH; 154 } 155 } 156 else { // search_state == ONE 157 // Header unescaping terminates early due to detection of next start code 158 search_state = NO_MATCH; 159 start_code_found = 1; 160 break; 161 } 162 } 163 if ((s->flags & PARSER_FLAG_COMPLETE_FRAMES) && 164 unesc_index >= UNESCAPED_THRESHOLD && 165 vpc->prev_start_code == (VC1_CODE_FRAME & 0xFF)) 166 { 167 // No need to keep scanning the rest of the buffer for 168 // start codes if we know it contains a complete frame and 169 // we've already unescaped all we need of the frame header 170 vc1_extract_header(s, avctx, unesc_buffer, unesc_index); 171 break; 172 } 173 if (unesc_index >= UNESCAPED_THRESHOLD && !start_code_found) { 174 while (i < buf_size) { 175 if (search_state == NO_MATCH) { 176 i += vpc->v.vc1dsp.vc1_find_start_code_candidate(buf + i, buf_size - i); 177 if (i < buf_size) { 178 search_state = ONE_ZERO; 179 } 180 i++; 181 } else { 182 b = buf[i++]; 183 if (search_state == ONE_ZERO) 184 search_state = b ? NO_MATCH : TWO_ZEROS; 185 else if (search_state == TWO_ZEROS) { 186 if (b >= 1) 187 search_state = b == 1 ? ONE : NO_MATCH; 188 } 189 else { // search_state == ONE 190 search_state = NO_MATCH; 191 start_code_found = 1; 192 break; 193 } 194 } 195 } 196 } 197 if (start_code_found) { 198 vc1_extract_header(s, avctx, unesc_buffer, unesc_index); 199 200 vpc->prev_start_code = b; 201 unesc_index = 0; 202 203 if (!(s->flags & PARSER_FLAG_COMPLETE_FRAMES)) { 204 if (!pic_found && (b == (VC1_CODE_FRAME & 0xFF) || b == (VC1_CODE_FIELD & 0xFF))) { 205 pic_found = 1; 206 } 207 else if (pic_found && b != (VC1_CODE_FIELD & 0xFF) && b != (VC1_CODE_SLICE & 0xFF)) { 208 next = i - 4; 209 pic_found = b == (VC1_CODE_FRAME & 0xFF); 210 break; 211 } 212 } 213 } 214 } 215 216 vpc->pc.frame_start_found = pic_found; 217 vpc->unesc_index = unesc_index; 218 vpc->search_state = search_state; 219 220 if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { 221 next = buf_size; 222 } else { 223 if (ff_combine_frame(&vpc->pc, next, &buf, &buf_size) < 0) { 224 vpc->bytes_to_skip = 0; 225 *poutbuf = NULL; 226 *poutbuf_size = 0; 227 return buf_size; 228 } 229 } 230 231 vpc->v.first_pic_header_flag = 1; 232 233 /* If we return with a valid pointer to a combined frame buffer 234 * then on the next call then we'll have been unhelpfully rewound 235 * by up to 4 bytes (depending upon whether the start code 236 * overlapped the input buffer, and if so by how much). We don't 237 * want this: it will either cause spurious second detections of 238 * the start code we've already seen, or cause extra bytes to be 239 * inserted at the start of the unescaped buffer. */ 240 vpc->bytes_to_skip = 4; 241 if (next < 0 && next != END_NOT_FOUND) 242 vpc->bytes_to_skip += next; 243 244 *poutbuf = buf; 245 *poutbuf_size = buf_size; 246 return next; 247} 248 249static int vc1_split(AVCodecContext *avctx, 250 const uint8_t *buf, int buf_size) 251{ 252 int i; 253 uint32_t state= -1; 254 int charged=0; 255 256 for(i=0; i<buf_size; i++){ 257 state= (state<<8) | buf[i]; 258 if(IS_MARKER(state)){ 259 if(state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT){ 260 charged=1; 261 }else if(charged){ 262 return i-3; 263 } 264 } 265 } 266 return 0; 267} 268 269static av_cold int vc1_parse_init(AVCodecParserContext *s) 270{ 271 VC1ParseContext *vpc = s->priv_data; 272 vpc->v.s.slice_context_count = 1; 273 vpc->v.first_pic_header_flag = 1; 274 vpc->prev_start_code = 0; 275 vpc->bytes_to_skip = 0; 276 vpc->unesc_index = 0; 277 vpc->search_state = NO_MATCH; 278 return ff_vc1_init_common(&vpc->v); 279} 280 281AVCodecParser ff_vc1_parser = { 282 .codec_ids = { AV_CODEC_ID_VC1 }, 283 .priv_data_size = sizeof(VC1ParseContext), 284 .parser_init = vc1_parse_init, 285 .parser_parse = vc1_parse, 286 .parser_close = ff_parse_close, 287 .split = vc1_split, 288}; 289