static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size)
{
- int i;
+ int i, j;
uint32_t state;
ParseContext *pc = &(h->s.parse_context);
+ int next_avc= h->is_avc ? 0 : buf_size;
+
//printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
// mb_addr= pc->mb_addr - 1;
state= pc->state;
if(state>13)
state= 7;
+ if(h->is_avc && !h->nal_length_size)
+ av_log(h->s.avctx, AV_LOG_ERROR, "AVC-parser: nal length size invalid\n");
+
for(i=0; i<buf_size; i++){
+ if(i >= next_avc) {
+ int nalsize = 0;
+ i = next_avc;
+ for(j = 0; j < h->nal_length_size; j++)
+ nalsize = (nalsize << 8) | buf[i++];
+ if(nalsize <= 0 || nalsize > buf_size - i){
+ av_log(h->s.avctx, AV_LOG_ERROR, "AVC-parser: nal size %d remaining %d\n", nalsize, buf_size - i);
+ return buf_size;
+ }
+ next_avc= i + nalsize;
+ state= 5;
+ }
+
if(state==7){
#if HAVE_FAST_UNALIGNED
/* we check i<buf_size instead of i+3/7 because its simpler
* and there should be FF_INPUT_BUFFER_PADDING_SIZE bytes at the end
*/
# if HAVE_FAST_64BIT
- while(i<buf_size && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL))
+ while(i<next_avc && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL))
i+=8;
# else
- while(i<buf_size && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U))
+ while(i<next_avc && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U))
i+=4;
# endif
#endif
- for(; i<buf_size; i++){
+ for(; i<next_avc; i++){
if(!buf[i]){
state=2;
break;
goto found;
}
}else if(v==1 || v==2 || v==5){
+ state+=8;
+ continue;
+ }
+ state= 7;
+ }else{
+ h->parse_history[h->parse_history_count++]= buf[i];
+ if(h->parse_history_count>3){
+ unsigned int mb, last_mb= h->parse_last_mb;
+ GetBitContext gb;
+
+ init_get_bits(&gb, h->parse_history, 8*h->parse_history_count);
+ h->parse_history_count=0;
+ mb= get_ue_golomb_long(&gb);
+ last_mb= h->parse_last_mb;
+ h->parse_last_mb= mb;
if(pc->frame_start_found){
- state+=8;
- continue;
+ if(mb <= last_mb)
+ goto found;
}else
pc->frame_start_found = 1;
+ state= 7;
}
- state= 7;
- }else{
- if(buf[i] & 0x80)
- goto found;
- state= 7;
}
}
pc->state= state;
+ if(h->is_avc)
+ return next_avc;
return END_NOT_FOUND;
found:
pc->state=7;
pc->frame_start_found= 0;
- return i-(state&5);
+ if(h->is_avc)
+ return next_avc;
+ return i-(state&5) - 3*(state>7);
}
/**
for(;;) {
int src_length, dst_length, consumed;
- buf = ff_find_start_code(buf, buf_end, &state);
+ buf = avpriv_mpv_find_start_code(buf, buf_end, &state);
if(buf >= buf_end)
break;
--buf;
s->key_frame = 1;
/* fall through */
case NAL_SLICE:
- get_ue_golomb(&h->s.gb); // skip first_mb_in_slice
+ get_ue_golomb_long(&h->s.gb); // skip first_mb_in_slice
slice_type = get_ue_golomb_31(&h->s.gb);
s->pict_type = golomb_to_pict_type[slice_type % 5];
if (h->sei_recovery_frame_cnt >= 0) {
buf += consumed;
}
/* didn't find a picture! */
- av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n");
+ av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit with size %d\n", buf_size);
return -1;
}
// Note that estimate_timings_from_pts does exactly this.
if (!avctx->has_b_frames)
h->s.low_delay = 1;
- ff_h264_decode_extradata(h);
+ ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size);
}
}
}
}
+ if(!h->is_avc){
parse_nal_units(s, avctx, buf, buf_size);
if (h->sei_cpb_removal_delay >= 0) {
if (s->flags & PARSER_FLAG_ONCE) {
s->flags &= PARSER_FLAG_COMPLETE_FRAMES;
}
+ }
*poutbuf = buf;
*poutbuf_size = buf_size;
}
AVCodecParser ff_h264_parser = {
- { CODEC_ID_H264 },
- sizeof(H264Context),
- init,
- h264_parse,
- close,
- h264_split,
+ .codec_ids = { CODEC_ID_H264 },
+ .priv_data_size = sizeof(H264Context),
+ .parser_init = init,
+ .parser_parse = h264_parse,
+ .parser_close = close,
+ .split = h264_split,
};