av_freep(&hx->top_borders[1]);
av_freep(&hx->top_borders[0]);
av_freep(&hx->s.obmc_scratchpad);
+ av_freep(&hx->rbsp_buffer[1]);
+ av_freep(&hx->rbsp_buffer[0]);
+ if (i) av_freep(&h->thread_context[i]);
}
}
else
avctx->pix_fmt= avctx->get_format(avctx, avctx->codec->pix_fmts);
avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
+ avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
decode_init_vlc();
* See decode_nal_units().
*/
s->current_picture_ptr->key_frame= 0;
+ s->current_picture_ptr->mmco_reset= 0;
assert(s->linesize && s->uvlinesize);
for(index= 0; index < h->ref_count[list]; index++){
if(!h->ref_list[list][index].data[0]){
av_log(h->s.avctx, AV_LOG_ERROR, "Missing reference picture\n");
- h->ref_list[list][index]= s->current_picture; //FIXME this is not a sensible solution
+ if(h->default_ref_list[list][0].data[0])
+ h->ref_list[list][index]= h->default_ref_list[list][0];
+ else
+ return -1;
}
}
}
h->delayed_pic[i]= NULL;
}
h->outputed_poc= INT_MIN;
+ h->prev_interlaced_frame = 1;
idr(h);
if(h->s.current_picture_ptr)
h->s.current_picture_ptr->reference= 0;
h->poc_msb=
h->frame_num=
s->current_picture_ptr->frame_num= 0;
+ s->current_picture_ptr->mmco_reset=1;
break;
default: assert(0);
}
ff_er_frame_end(s);
MPV_frame_end(s);
+
+ h->current_slice=0;
}
/**
first_mb_in_slice= get_ue_golomb(&s->gb);
- if((s->flags2 & CODEC_FLAG2_CHUNKS) && first_mb_in_slice == 0){
+ if(first_mb_in_slice == 0){ //FIXME better field boundary detection
+ if(h0->current_slice && FIELD_PICTURE){
+ field_end(h);
+ }
+
h0->current_slice = 0;
if (!s0->first_field)
s->current_picture_ptr= NULL;
if (MPV_common_init(s) < 0)
return -1;
s->first_field = 0;
+ h->prev_interlaced_frame = 1;
init_scan_tables(h);
alloc_tables(h);
const int index_a = qp + h->slice_alpha_c0_offset;
const int alpha = (alpha_table+52)[index_a];
const int beta = (beta_table+52)[qp + h->slice_beta_offset];
+ if (alpha ==0 || beta == 0) return;
if( bS[0] < 4 ) {
int8_t tc[4];
const int index_a = qp + h->slice_alpha_c0_offset;
const int alpha = (alpha_table+52)[index_a];
const int beta = (beta_table+52)[qp + h->slice_beta_offset];
+ if (alpha ==0 || beta == 0) return;
if( bS[0] < 4 ) {
int8_t tc[4];
const int index_a = qp + h->slice_alpha_c0_offset;
const int alpha = (alpha_table+52)[index_a];
const int beta = (beta_table+52)[qp + h->slice_beta_offset];
+ if (alpha ==0 || beta == 0) return;
if( bS[0] < 4 ) {
int8_t tc[4];
const int index_a = qp + h->slice_alpha_c0_offset;
const int alpha = (alpha_table+52)[index_a];
const int beta = (beta_table+52)[qp + h->slice_beta_offset];
+ if (alpha ==0 || beta == 0) return;
if( bS[0] < 4 ) {
int8_t tc[4];
skip_bits(&s->gb, h->sps.time_offset_length); /* time_offset */
}
}
+
+ if(s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n", h->sei_ct_type, h->sei_pic_struct);
}
return 0;
}
}
if(get_bits1(&s->gb)){ /* chroma_location_info_present_flag */
- get_ue_golomb(&s->gb); /* chroma_sample_location_type_top_field */
+ s->avctx->chroma_sample_location = get_ue_golomb(&s->gb)+1; /* chroma_sample_location_type_top_field */
get_ue_golomb(&s->gb); /* chroma_sample_location_type_bottom_field */
}
sps->vui_parameters_present_flag= get_bits1(&s->gb);
if( sps->vui_parameters_present_flag )
- decode_vui_parameters(h, sps);
+ if (decode_vui_parameters(h, sps) < 0)
+ goto fail;
if(s->avctx->debug&FF_DEBUG_PICT_INFO){
av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d\n",
int buf_index=0;
H264Context *hx; ///< thread context
int context_count = 0;
+ int next_avc= h->is_avc ? 0 : buf_size;
h->max_contexts = avctx->thread_count;
#if 0
int i, nalsize = 0;
int err;
- if(h->is_avc) {
+ if(buf_index >= next_avc) {
if(buf_index >= buf_size) break;
nalsize = 0;
for(i = 0; i < h->nal_length_size; i++)
nalsize = (nalsize << 8) | buf[buf_index++];
- if(nalsize <= 1 || (nalsize+buf_index > buf_size)){
+ if(nalsize <= 1 || nalsize > buf_size - buf_index){
if(nalsize == 1){
buf_index++;
continue;
break;
}
}
+ next_avc= buf_index + nalsize;
} else {
// start code prefix search
for(; buf_index + 3 < buf_size; buf_index++){
hx = h->thread_context[context_count];
- ptr= ff_h264_decode_nal(hx, buf + buf_index, &dst_length, &consumed, h->is_avc ? nalsize : buf_size - buf_index);
+ ptr= ff_h264_decode_nal(hx, buf + buf_index, &dst_length, &consumed, next_avc - buf_index);
if (ptr==NULL || dst_length < 0){
return -1;
}
av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d at %d/%d length %d\n", hx->nal_unit_type, buf_index, buf_size, dst_length);
}
- if (h->is_avc && (nalsize != consumed)){
+ if (h->is_avc && (nalsize != consumed) && nalsize){
int i, debug_level = AV_LOG_DEBUG;
for (i = consumed; i < nalsize; i++)
if (buf[buf_index+i])
debug_level = AV_LOG_ERROR;
av_log(h->s.avctx, debug_level, "AVC: Consumed only %d bytes instead of %d\n", consumed, nalsize);
- consumed= nalsize;
}
buf_index += consumed;
init_get_bits(&hx->s.gb, ptr, bit_length);
hx->intra_gb_ptr=
hx->inter_gb_ptr= NULL;
+
+ if ((err = decode_slice_header(hx, h)) < 0)
+ break;
+
hx->s.data_partitioning = 1;
- err = decode_slice_header(hx, h);
break;
case NAL_DPB:
init_get_bits(&hx->intra_gb, ptr, bit_length);
//FIXME factorize this with the output code below
out = h->delayed_pic[0];
out_idx = 0;
- for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc && !h->delayed_pic[i]->key_frame); i++)
+ for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame && !h->delayed_pic[i]->mmco_reset; i++)
if(h->delayed_pic[i]->poc < out->poc){
out = h->delayed_pic[i];
out_idx = i;
*data_size = 0;
} else {
+ cur->interlaced_frame = 0;
cur->repeat_pict = 0;
/* Signal interlacing information externally. */
/* Prioritize picture timing SEI information over used decoding process if it exists. */
- if (h->sei_ct_type)
- cur->interlaced_frame = (h->sei_ct_type & (1<<1)) != 0;
- else
- cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
if(h->sps.pic_struct_present_flag){
switch (h->sei_pic_struct)
{
+ case SEI_PIC_STRUCT_FRAME:
+ break;
+ case SEI_PIC_STRUCT_TOP_FIELD:
+ case SEI_PIC_STRUCT_BOTTOM_FIELD:
+ cur->interlaced_frame = 1;
+ break;
+ case SEI_PIC_STRUCT_TOP_BOTTOM:
+ case SEI_PIC_STRUCT_BOTTOM_TOP:
+ if (FIELD_OR_MBAFF_PICTURE)
+ cur->interlaced_frame = 1;
+ else
+ // try to flag soft telecine progressive
+ cur->interlaced_frame = h->prev_interlaced_frame;
+ break;
case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
// Signal the possibility of telecined film externally (pic_struct 5,6)
break;
case SEI_PIC_STRUCT_FRAME_DOUBLING:
// Force progressive here, as doubling interlaced frame is a bad idea.
- cur->interlaced_frame = 0;
cur->repeat_pict = 2;
break;
case SEI_PIC_STRUCT_FRAME_TRIPLING:
- cur->interlaced_frame = 0;
cur->repeat_pict = 4;
break;
}
+
+ if ((h->sei_ct_type & 3) && h->sei_pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP)
+ cur->interlaced_frame = (h->sei_ct_type & (1<<1)) != 0;
}else{
/* Derive interlacing flag from used decoding process. */
cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
}
+ h->prev_interlaced_frame = cur->interlaced_frame;
if (cur->field_poc[0] != cur->field_poc[1]){
/* Derive top_field_first from field pocs. */
out = h->delayed_pic[0];
out_idx = 0;
- for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc && !h->delayed_pic[i]->key_frame); i++)
+ for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame && !h->delayed_pic[i]->mmco_reset; i++)
if(h->delayed_pic[i]->poc < out->poc){
out = h->delayed_pic[i];
out_idx = i;
}
- cross_idr = !h->delayed_pic[0]->poc || !!h->delayed_pic[i] || h->delayed_pic[0]->key_frame;
+ cross_idr = !!h->delayed_pic[i] || h->delayed_pic[0]->key_frame || h->delayed_pic[0]->mmco_reset;
out_of_order = !cross_idr && out->poc < h->outputed_poc;
assert(pict->data[0] || !*data_size);
ff_print_debug_info(s, pict);
//printf("out %d\n", (int)pict->data[0]);
-#if 0 //?
- /* Return the Picture timestamp as the frame number */
- /* we subtract 1 because it is added on utils.c */
- avctx->frame_number = s->picture_number - 1;
-#endif
return get_consumed_bytes(s, buf_index, buf_size);
}
#if 0
{
int i;
- av_freep(&h->rbsp_buffer[0]);
- av_freep(&h->rbsp_buffer[1]);
free_tables(h); //FIXME cleanup init stuff perhaps
for(i = 0; i < MAX_SPS_COUNT; i++)