av_freep(&h->mb2b_xy);
av_freep(&h->mb2b8_xy);
- for(i = 0; i < h->s.avctx->thread_count; i++) {
+ for(i = 0; i < MAX_THREADS; i++) {
hx = h->thread_context[i];
if(!hx) continue;
av_freep(&hx->top_borders[1]);
memset(h->pps.scaling_matrix8, 16, 2*64*sizeof(uint8_t));
}
+/**
+ * Reset SEI values at the beginning of the frame.
+ *
+ * @param h H.264 context.
+ */
+static void reset_sei(H264Context *h) {
+ h->sei_recovery_frame_cnt = -1;
+ h->sei_dpb_output_delay = 0;
+ h->sei_cpb_removal_delay = -1;
+ h->sei_buffering_period_present = 0;
+}
+
static av_cold int decode_init(AVCodecContext *avctx){
H264Context *h= avctx->priv_data;
MpegEncContext * const s = &h->s;
// set defaults
// s->decode_mb= ff_h263_decode_mb;
s->quarter_sample = 1;
+ if(!avctx->has_b_frames)
s->low_delay= 1;
if(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
h->thread_context[0] = h;
h->outputed_poc = INT_MIN;
h->prev_poc_msb= 1<<16;
- h->sei_recovery_frame_cnt = -1;
- h->sei_dpb_output_delay = 0;
- h->sei_cpb_removal_delay = -1;
- h->sei_buffering_period_present = 0;
- if(avctx->codec_id == CODEC_ID_H264)
+ reset_sei(h);
+ if(avctx->codec_id == CODEC_ID_H264){
+ if(avctx->ticks_per_frame == 1){
+ s->avctx->time_base.den *=2;
+ }
avctx->ticks_per_frame = 2;
+ }
return 0;
}
if(h->s.current_picture_ptr)
h->s.current_picture_ptr->reference= 0;
h->s.first_field= 0;
- h->sei_recovery_frame_cnt = -1;
- h->sei_dpb_output_delay = 0;
- h->sei_cpb_removal_delay = -1;
- h->sei_buffering_period_present = 0;
+ reset_sei(h);
ff_mpeg_flush(avctx);
}
*/
static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
MpegEncContext * const s = &h->s;
- int i, j;
+ int i, av_uninit(j);
int current_ref_assigned=0;
Picture *av_uninit(pic);
av_log(h->s.avctx, AV_LOG_DEBUG, "no mmco here\n");
for(i=0; i<mmco_count; i++){
- int structure, av_uninit(frame_num);
+ int av_uninit(structure), av_uninit(frame_num);
if(s->avctx->debug&FF_DEBUG_MMCO)
av_log(h->s.avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_pic_num, h->mmco[i].long_arg);
return -1;
}
if(!h0->pps_buffers[pps_id]) {
- av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS referenced\n");
+ av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS %u referenced\n", pps_id);
return -1;
}
h->pps= *h0->pps_buffers[pps_id];
if(!h0->sps_buffers[h->pps.sps_id]) {
- av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS referenced\n");
+ av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %u referenced\n", h->pps.sps_id);
return -1;
}
h->sps = *h0->sps_buffers[h->pps.sps_id];
s->avctx->time_base.den *= 2;
av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,
s->avctx->time_base.num, s->avctx->time_base.den, 1<<30);
- }else if(!h->sps.time_scale && !s->avctx->frame_number){
- s->avctx->time_base.den *=2;
- h->sps.time_scale= s->avctx->time_base.den;
}
}
//first coefficient has suffix_length equal to 0 or 1
if(prefix<14){ //FIXME try to build a large unified VLC table for all this
if(suffix_length)
- level_code= (prefix<<suffix_length) + get_bits(gb, suffix_length); //part
+ level_code= (prefix<<1) + get_bits1(gb); //part
else
- level_code= (prefix<<suffix_length); //part
+ level_code= prefix; //part
}else if(prefix==14){
if(suffix_length)
- level_code= (prefix<<suffix_length) + get_bits(gb, suffix_length); //part
+ level_code= (prefix<<1) + get_bits1(gb); //part
else
level_code= prefix + get_bits(gb, 4); //part
}else{
- level_code= (15<<suffix_length) + get_bits(gb, prefix-3); //part
- if(suffix_length==0) level_code+=15; //FIXME doesn't make (much)sense
+ level_code= 30 + get_bits(gb, prefix-3); //part
if(prefix>=16)
level_code += (1<<(prefix-3))-4096;
}
int qp = s->current_picture.qscale_table[mb_xy];
if(qp <= qp_thresh
&& (mb_x == 0 || ((qp + s->current_picture.qscale_table[mb_xy-1] + 1)>>1) <= qp_thresh)
- && (mb_y == 0 || ((qp + s->current_picture.qscale_table[h->top_mb_xy] + 1)>>1) <= qp_thresh)){
+ && (h->top_mb_xy < 0 || ((qp + s->current_picture.qscale_table[h->top_mb_xy] + 1)>>1) <= qp_thresh)){
return;
}
}
if(h->sps.pic_struct_present_flag){
unsigned int i, num_clock_ts;
h->sei_pic_struct = get_bits(&s->gb, 4);
+ h->sei_ct_type = 0;
if (h->sei_pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING)
return -1;
for (i = 0 ; i < num_clock_ts ; i++){
if(get_bits(&s->gb, 1)){ /* clock_timestamp_flag */
unsigned int full_timestamp_flag;
- skip_bits(&s->gb, 2); /* ct_type */
+ h->sei_ct_type |= 1<<get_bits(&s->gb, 2);
skip_bits(&s->gb, 1); /* nuit_field_based_flag */
skip_bits(&s->gb, 5); /* counting_type */
full_timestamp_flag = get_bits(&s->gb, 1);
decode_vui_parameters(h, sps);
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\n",
+ 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",
sps_id, sps->profile_idc, sps->level_idc,
sps->poc_type,
sps->ref_frame_count,
sps->crop_left, sps->crop_right,
sps->crop_top, sps->crop_bottom,
sps->vui_parameters_present_flag ? "VUI" : "",
- ((const char*[]){"Gray","420","422","444"})[sps->chroma_format_idc]
+ ((const char*[]){"Gray","420","422","444"})[sps->chroma_format_idc],
+ sps->timing_info_present_flag ? sps->num_units_in_tick : 0,
+ sps->timing_info_present_flag ? sps->time_scale : 0
);
}
h->current_slice = 0;
if (!s->first_field)
s->current_picture_ptr= NULL;
+ reset_sei(h);
}
for(;;){
if((err = decode_slice_header(hx, h)))
break;
+ if (s->avctx->hwaccel && h->current_slice == 1) {
+ if (s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0)
+ return -1;
+ }
+
s->current_picture_ptr->key_frame |=
(hx->nal_unit_type == NAL_IDR_SLICE) ||
(h->sei_recovery_frame_cnt >= 0);
static int decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
- const uint8_t *buf, int buf_size)
+ AVPacket *avpkt)
{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
H264Context *h = avctx->priv_data;
MpegEncContext *s = &h->s;
AVFrame *pict = data;
h->prev_frame_num_offset= h->frame_num_offset;
h->prev_frame_num= h->frame_num;
+ if (avctx->hwaccel) {
+ if (avctx->hwaccel->end_frame(avctx) < 0)
+ av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n");
+ }
+
if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
ff_vdpau_h264_picture_complete(s);
ff_er_frame_end(s);
MPV_frame_end(s);
- h->sei_recovery_frame_cnt = -1;
- h->sei_dpb_output_delay = 0;
- h->sei_cpb_removal_delay = -1;
- h->sei_buffering_period_present = 0;
if (cur->field_poc[0]==INT_MAX || cur->field_poc[1]==INT_MAX) {
/* Wait for second field. */
/* 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:
- cur->interlaced_frame = 0;
- break;
- case SEI_PIC_STRUCT_TOP_FIELD:
- case SEI_PIC_STRUCT_BOTTOM_FIELD:
- case SEI_PIC_STRUCT_TOP_BOTTOM:
- case SEI_PIC_STRUCT_BOTTOM_TOP:
- cur->interlaced_frame = 1;
- 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)
// From these hints, let the applications decide if they apply deinterlacing.
cur->repeat_pict = 1;
- cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
break;
case SEI_PIC_STRUCT_FRAME_DOUBLING:
// Force progressive here, as doubling interlaced frame is a bad idea.
#endif /* TEST */
-static av_cold int decode_end(AVCodecContext *avctx)
+av_cold void ff_h264_free_context(H264Context *h)
{
- H264Context *h = avctx->priv_data;
- MpegEncContext *s = &h->s;
int i;
av_freep(&h->rbsp_buffer[0]);
for(i = 0; i < MAX_PPS_COUNT; i++)
av_freep(h->pps_buffers + i);
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ H264Context *h = avctx->priv_data;
+ MpegEncContext *s = &h->s;
+
+ ff_h264_free_context(h);
MPV_common_end(s);
/*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY,
.flush= flush_dpb,
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
- .pix_fmts= ff_pixfmt_list_420,
+ .pix_fmts= ff_hwaccel_pixfmt_list_420,
};
#if CONFIG_H264_VDPAU_DECODER