Libav 0.7.1
|
00001 /* 00002 * VC-1 and WMV3 parser 00003 * Copyright (c) 2006-2007 Konstantin Shishkov 00004 * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer 00005 * 00006 * This file is part of Libav. 00007 * 00008 * Libav is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * Libav is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with Libav; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00028 #include "parser.h" 00029 #include "vc1.h" 00030 #include "get_bits.h" 00031 00032 typedef struct { 00033 ParseContext pc; 00034 VC1Context v; 00035 } VC1ParseContext; 00036 00037 static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx, 00038 const uint8_t *buf, int buf_size) 00039 { 00040 VC1ParseContext *vpc = s->priv_data; 00041 GetBitContext gb; 00042 const uint8_t *start, *end, *next; 00043 uint8_t *buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); 00044 00045 vpc->v.s.avctx = avctx; 00046 vpc->v.parse_only = 1; 00047 next = buf; 00048 00049 for(start = buf, end = buf + buf_size; next < end; start = next){ 00050 int buf2_size, size; 00051 00052 next = find_next_marker(start + 4, end); 00053 size = next - start - 4; 00054 buf2_size = vc1_unescape_buffer(start + 4, size, buf2); 00055 init_get_bits(&gb, buf2, buf2_size * 8); 00056 if(size <= 0) continue; 00057 switch(AV_RB32(start)){ 00058 case VC1_CODE_SEQHDR: 00059 vc1_decode_sequence_header(avctx, &vpc->v, &gb); 00060 break; 00061 case VC1_CODE_ENTRYPOINT: 00062 vc1_decode_entry_point(avctx, &vpc->v, &gb); 00063 break; 00064 case VC1_CODE_FRAME: 00065 if(vpc->v.profile < PROFILE_ADVANCED) 00066 vc1_parse_frame_header (&vpc->v, &gb); 00067 else 00068 vc1_parse_frame_header_adv(&vpc->v, &gb); 00069 00070 /* keep AV_PICTURE_TYPE_BI internal to VC1 */ 00071 if (vpc->v.s.pict_type == AV_PICTURE_TYPE_BI) 00072 s->pict_type = AV_PICTURE_TYPE_B; 00073 else 00074 s->pict_type = vpc->v.s.pict_type; 00075 00076 break; 00077 } 00078 } 00079 00080 av_free(buf2); 00081 } 00082 00087 static int vc1_find_frame_end(ParseContext *pc, const uint8_t *buf, 00088 int buf_size) { 00089 int pic_found, i; 00090 uint32_t state; 00091 00092 pic_found= pc->frame_start_found; 00093 state= pc->state; 00094 00095 i=0; 00096 if(!pic_found){ 00097 for(i=0; i<buf_size; i++){ 00098 state= (state<<8) | buf[i]; 00099 if(state == VC1_CODE_FRAME || state == VC1_CODE_FIELD){ 00100 i++; 00101 pic_found=1; 00102 break; 00103 } 00104 } 00105 } 00106 00107 if(pic_found){ 00108 /* EOF considered as end of frame */ 00109 if (buf_size == 0) 00110 return 0; 00111 for(; i<buf_size; i++){ 00112 state= (state<<8) | buf[i]; 00113 if(IS_MARKER(state) && state != VC1_CODE_FIELD && state != VC1_CODE_SLICE){ 00114 pc->frame_start_found=0; 00115 pc->state=-1; 00116 return i-3; 00117 } 00118 } 00119 } 00120 pc->frame_start_found= pic_found; 00121 pc->state= state; 00122 return END_NOT_FOUND; 00123 } 00124 00125 static int vc1_parse(AVCodecParserContext *s, 00126 AVCodecContext *avctx, 00127 const uint8_t **poutbuf, int *poutbuf_size, 00128 const uint8_t *buf, int buf_size) 00129 { 00130 VC1ParseContext *vpc = s->priv_data; 00131 int next; 00132 00133 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ 00134 next= buf_size; 00135 }else{ 00136 next= vc1_find_frame_end(&vpc->pc, buf, buf_size); 00137 00138 if (ff_combine_frame(&vpc->pc, next, &buf, &buf_size) < 0) { 00139 *poutbuf = NULL; 00140 *poutbuf_size = 0; 00141 return buf_size; 00142 } 00143 } 00144 00145 vc1_extract_headers(s, avctx, buf, buf_size); 00146 00147 *poutbuf = buf; 00148 *poutbuf_size = buf_size; 00149 return next; 00150 } 00151 00152 static int vc1_split(AVCodecContext *avctx, 00153 const uint8_t *buf, int buf_size) 00154 { 00155 int i; 00156 uint32_t state= -1; 00157 int charged=0; 00158 00159 for(i=0; i<buf_size; i++){ 00160 state= (state<<8) | buf[i]; 00161 if(IS_MARKER(state)){ 00162 if(state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT){ 00163 charged=1; 00164 }else if(charged){ 00165 return i-3; 00166 } 00167 } 00168 } 00169 return 0; 00170 } 00171 00172 AVCodecParser ff_vc1_parser = { 00173 { CODEC_ID_VC1 }, 00174 sizeof(VC1ParseContext), 00175 NULL, 00176 vc1_parse, 00177 ff_parse1_close, 00178 vc1_split, 00179 };