Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > VSs > VSs__H264__App
diff libavcodec/h264_parser.c @ 2:897f711a7157
rearrange to work with autoconf
| author | Nina Engelhardt <nengel@mailbox.tu-berlin.de> |
|---|---|
| date | Tue, 25 Sep 2012 15:55:33 +0200 |
| parents | |
| children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libavcodec/h264_parser.c Tue Sep 25 15:55:33 2012 +0200 1.3 @@ -0,0 +1,224 @@ 1.4 +/* 1.5 + * H.26L/H.264/AVC/JVT/14496-10/... parser 1.6 + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> 1.7 + * 1.8 + * This file is part of FFmpeg. 1.9 + * 1.10 + * FFmpeg is free software; you can redistribute it and/or 1.11 + * modify it under the terms of the GNU Lesser General Public 1.12 + * License as published by the Free Software Foundation; either 1.13 + * version 2.1 of the License, or (at your option) any later version. 1.14 + * 1.15 + * FFmpeg is distributed in the hope that it will be useful, 1.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.18 + * Lesser General Public License for more details. 1.19 + * 1.20 + * You should have received a copy of the GNU Lesser General Public 1.21 + * License along with FFmpeg; if not, write to the Free Software 1.22 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 1.23 + */ 1.24 + 1.25 +/** 1.26 + * @file 1.27 + * H.264 / AVC / MPEG4 part10 parser. 1.28 + * @author Michael Niedermayer <michaelni@gmx.at> 1.29 + */ 1.30 + 1.31 +#include <unistd.h> 1.32 + 1.33 +#include "golomb.h" 1.34 +#include "libavutil/error.h" 1.35 +#include "h264_types.h" 1.36 + 1.37 +#undef NDEBUG 1.38 +#include <assert.h> 1.39 + 1.40 +#define END_NOT_FOUND (-100) 1.41 + 1.42 +static int ff_h264_find_frame_end(ParserContext *s, const uint8_t *buf, int buf_size) 1.43 +{ 1.44 + int i; 1.45 + uint32_t state; 1.46 + 1.47 + state= s->state; 1.48 + if(state>13) 1.49 + state= 7; 1.50 + 1.51 + for(i=0; i<buf_size; i++){ 1.52 + if(state==7){ 1.53 + /* we check i<buf_size instead of i+3/7 because its simpler 1.54 + * and there should be FF_INPUT_BUFFER_PADDING_SIZE bytes at the end 1.55 + */ 1.56 + while(i<buf_size && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL)) 1.57 + i+=8; 1.58 + 1.59 + for(; i<buf_size; i++){ 1.60 + if(!buf[i]){ 1.61 + state=2; 1.62 + break; 1.63 + } 1.64 + } 1.65 + }else if(state<=2){ 1.66 + if(buf[i]==1) state^= 5; //2->7, 1->4, 0->5 1.67 + else if(buf[i]) state = 7; 1.68 + else state>>=1; //2->1, 1->0, 0->0 1.69 + }else if(state<=5){ 1.70 + int v= buf[i] & 0x1F; 1.71 + if(v==6 || v==7 || v==8 || v==9){ 1.72 + if(s->frame_start_found){ 1.73 + i++; 1.74 + goto found; 1.75 + } 1.76 + }else if(v==1 || v==2 || v==5){ 1.77 + if(s->frame_start_found){ 1.78 + state+=8; 1.79 + continue; 1.80 + }else 1.81 + s->frame_start_found = 1; 1.82 + } 1.83 + state= 7; 1.84 + }else{ 1.85 + if(buf[i] & 0x80) 1.86 + goto found; 1.87 + state= 7; 1.88 + } 1.89 + } 1.90 + s->state= state; 1.91 + return END_NOT_FOUND; 1.92 + 1.93 +found: 1.94 + s->state=7; 1.95 + s->frame_start_found= 0; 1.96 + return i-(state&5); 1.97 +} 1.98 + 1.99 +static int ff_combine_frame(ParserContext *s, GetBitContext *gb, int next, uint8_t **buf, int *buf_size) 1.100 +{ 1.101 + int i; 1.102 + /* Copy overread bytes from last frame into buffer. */ 1.103 + for(i =0; s->overread_cnt>0; s->overread_cnt--, i++){ 1.104 + gb->raw[s->index++]= s->overread[i]; 1.105 + } 1.106 + 1.107 + /* EOF - END_NOT_FOUND means no next frame start is found in current partial read. If buf_size of the partial read is 0 we are at EOF */ 1.108 + if(!*buf_size && next == END_NOT_FOUND){ 1.109 + next= 0; 1.110 + } 1.111 + s->last_index= s->index; 1.112 + 1.113 + /* copy into buffer end return */ 1.114 + if(next == END_NOT_FOUND){ 1.115 + gb->raw = av_fast_realloc(gb->raw, &gb->alloc_size, (*buf_size) + s->index + FF_INPUT_BUFFER_PADDING_SIZE); 1.116 + memcpy(&gb->raw[s->index], *buf, *buf_size); 1.117 + s->index += *buf_size; 1.118 + return -1; 1.119 + } 1.120 + 1.121 + ///end found 1.122 + *buf_size= s->index + next; 1.123 + /* append to buffer */ 1.124 + 1.125 + gb->raw = av_fast_realloc(gb->raw, &gb->alloc_size, next + s->index + FF_INPUT_BUFFER_PADDING_SIZE); 1.126 + memcpy(&gb->raw[s->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); 1.127 + s->index = 0; 1.128 + 1.129 + /* store overread bytes */ 1.130 + for(i=0; next < 0; next++, i++){ 1.131 + s->state = (s->state<<8) | gb->raw[s->last_index + next]; 1.132 + s->overread[i] = gb->raw[s->last_index + next]; 1.133 + s->overread_cnt++; 1.134 + } 1.135 + 1.136 + return 0; 1.137 +} 1.138 + 1.139 +static int h264_parse(ParserContext *s, GetBitContext *gb, 1.140 + uint8_t *buf, int buf_size) 1.141 +{ 1.142 + int next; 1.143 + 1.144 + next= ff_h264_find_frame_end(s, buf, buf_size); 1.145 + 1.146 + if (ff_combine_frame(s, gb, next, &buf, &buf_size) < 0) { 1.147 + gb->buf_size = 0; 1.148 + return buf_size; 1.149 + } 1.150 + 1.151 + if(next<0 && next != END_NOT_FOUND){ 1.152 + assert(s->last_index + next >= 0 ); 1.153 + ff_h264_find_frame_end(s, &gb->raw[s->last_index + next], -next); //update state 1.154 + } 1.155 + 1.156 + gb->buf_size = buf_size; 1.157 + return next; 1.158 +} 1.159 + 1.160 +static int ff_raw_read_partial_packet(ParserContext *pc) 1.161 +{ 1.162 + int len= -1; 1.163 + 1.164 + if (!pc->eof_reached){ 1.165 + len = read( pc->ifile, pc->data, pc->buffer_size); 1.166 +// printf("read task %d\t%d\n", pc->ifile, len); fflush(NULL); 1.167 + if (len < pc->buffer_size) { 1.168 + pc->eof_reached = 1; 1.169 + } 1.170 + } 1.171 + 1.172 + return len; 1.173 +} 1.174 + 1.175 +void av_read_frame_internal(ParserContext *pc, GetBitContext *gb){ 1.176 + int len; 1.177 + uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]={0}; 1.178 + av_fast_malloc(&gb->raw, &gb->alloc_size, 2048+FF_INPUT_BUFFER_PADDING_SIZE); 1.179 + 1.180 + //Parsing is performed before read, since there are ussually leftovers from parsing the previous frame. 1.181 + for(;;) { 1.182 + if (pc->cur_len>0){ 1.183 + len = h264_parse(pc, gb, pc->cur_ptr, pc->cur_len); 1.184 + if (len<0) 1.185 + len =0; 1.186 + //* increment read pointer */ 1.187 + pc->cur_ptr += len; 1.188 + pc->cur_len -= len; 1.189 + 1.190 + if (gb->buf_size) { 1.191 + break; 1.192 + } 1.193 + } 1.194 + 1.195 + //check for ret and not parser->eof_reached as one "read" can contain more than 1 frame 1.196 + pc->size= ff_raw_read_partial_packet(pc); 1.197 + if (pc->size < 0) { 1.198 + pc->final_frame =1; 1.199 + /* return the last frames, if any */ 1.200 + h264_parse(pc, gb, dummy_buf, 0); 1.201 + break; 1.202 + } 1.203 + pc->cur_ptr = pc->data; 1.204 + pc->cur_len = pc->size; 1.205 + } 1.206 + 1.207 + assert(gb->raw!=NULL); 1.208 + 1.209 +} 1.210 + 1.211 +ParserContext *get_parse_context(int ifile){ 1.212 + ParserContext *pc = av_mallocz(sizeof(ParserContext)); 1.213 + pc->buffer_size = 2048; 1.214 + pc->final_frame = 0; 1.215 + pc->cur_len= 0; 1.216 + pc->data = av_mallocz(2048 + FF_INPUT_BUFFER_PADDING_SIZE); 1.217 + pc->size = 2048; 1.218 + pc->eof_reached =0; 1.219 + pc->ifile = ifile; 1.220 + 1.221 + return pc; 1.222 +} 1.223 + 1.224 +void free_parse_context(ParserContext *pc){ 1.225 + av_free(pc->data); 1.226 + av_free(pc); 1.227 +}
