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