00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "parser.h"
00029 #include "h264_parser.h"
00030
00031 #include <assert.h>
00032
00033
00034 int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size)
00035 {
00036 int i;
00037 uint32_t state;
00038 ParseContext *pc = &(h->s.parse_context);
00039
00040
00041 state= pc->state;
00042 if(state>13)
00043 state= 7;
00044
00045 for(i=0; i<buf_size; i++){
00046 if(state==7){
00047 for(; i<buf_size; i++){
00048 if(!buf[i]){
00049 state=2;
00050 break;
00051 }
00052 }
00053 }else if(state<=2){
00054 if(buf[i]==1) state^= 5;
00055 else if(buf[i]) state = 7;
00056 else state>>=1;
00057 }else if(state<=5){
00058 int v= buf[i] & 0x1F;
00059 if(v==7 || v==8 || v==9){
00060 if(pc->frame_start_found){
00061 i++;
00062 found:
00063 pc->state=7;
00064 pc->frame_start_found= 0;
00065 return i-(state&5);
00066 }
00067 }else if(v==1 || v==2 || v==5){
00068 if(pc->frame_start_found){
00069 state+=8;
00070 continue;
00071 }else
00072 pc->frame_start_found = 1;
00073 }
00074 state= 7;
00075 }else{
00076 if(buf[i] & 0x80)
00077 goto found;
00078 state= 7;
00079 }
00080 }
00081 pc->state= state;
00082 return END_NOT_FOUND;
00083 }
00084
00085 static int h264_parse(AVCodecParserContext *s,
00086 AVCodecContext *avctx,
00087 const uint8_t **poutbuf, int *poutbuf_size,
00088 const uint8_t *buf, int buf_size)
00089 {
00090 H264Context *h = s->priv_data;
00091 ParseContext *pc = &h->s.parse_context;
00092 int next;
00093
00094 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
00095 next= buf_size;
00096 }else{
00097 next= ff_h264_find_frame_end(h, buf, buf_size);
00098
00099 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
00100 *poutbuf = NULL;
00101 *poutbuf_size = 0;
00102 return buf_size;
00103 }
00104
00105 if(next<0 && next != END_NOT_FOUND){
00106 assert(pc->last_index + next >= 0 );
00107 ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next);
00108 }
00109 }
00110
00111 *poutbuf = buf;
00112 *poutbuf_size = buf_size;
00113 return next;
00114 }
00115
00116 static int h264_split(AVCodecContext *avctx,
00117 const uint8_t *buf, int buf_size)
00118 {
00119 int i;
00120 uint32_t state = -1;
00121 int has_sps= 0;
00122
00123 for(i=0; i<=buf_size; i++){
00124 if((state&0xFFFFFF1F) == 0x107)
00125 has_sps=1;
00126
00127
00128 if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){
00129 if(has_sps){
00130 while(i>4 && buf[i-5]==0) i--;
00131 return i-4;
00132 }
00133 }
00134 if (i<buf_size)
00135 state= (state<<8) | buf[i];
00136 }
00137 return 0;
00138 }
00139
00140
00141 AVCodecParser h264_parser = {
00142 { CODEC_ID_H264 },
00143 sizeof(H264Context),
00144 NULL,
00145 h264_parse,
00146 ff_parse_close,
00147 h264_split,
00148 };