00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
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 };