* @author Michael Niedermayer <michaelni@gmx.at>
*/
+#include "internal.h"
#include "dsputil.h"
#include "avcodec.h"
#include "mpegvideo.h"
static Picture * remove_long(H264Context *h, int i, int ref_mask);
static av_always_inline uint32_t pack16to32(int a, int b){
-#ifdef WORDS_BIGENDIAN
+#if HAVE_BIGENDIAN
return (b&0xFFFF) + (a<<16);
#else
return (a&0xFFFF) + (b<<16);
unsigned int sub_mb_type;
int i8, i4;
+ assert(h->ref_list[1][0].reference&3);
+
#define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)
if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL
}
}
-/**
- * Decodes a network abstraction layer unit.
- * @param consumed is the number of bytes used as input
- * @param length is the length of the array
- * @param dst_length is the number of decoded bytes FIXME here or a decode rbsp tailing?
- * @returns decoded bytes, might be src+1 if no escapes
- */
-static const uint8_t *decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){
+const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){
int i, si, di;
uint8_t *dst;
int bufidx;
# if HAVE_FAST_64BIT
# define RS 7
for(i=0; i+1<length; i+=9){
- if(!((~*(uint64_t*)(src+i) & (*(uint64_t*)(src+i) - 0x0100010001000101ULL)) & 0x8000800080008080ULL))
+ if(!((~*(const uint64_t*)(src+i) & (*(const uint64_t*)(src+i) - 0x0100010001000101ULL)) & 0x8000800080008080ULL))
# else
# define RS 3
for(i=0; i+1<length; i+=5){
- if(!((~*(uint32_t*)(src+i) & (*(uint32_t*)(src+i) - 0x01000101U)) & 0x80008080U))
+ if(!((~*(const uint32_t*)(src+i) & (*(const uint32_t*)(src+i) - 0x01000101U)) & 0x80008080U))
# endif
continue;
if(i>0 && !src[i]) i--;
}
bufidx = h->nal_unit_type == NAL_DPC ? 1 : 0; // use second escape buffer for inter data
- h->rbsp_buffer[bufidx]= av_fast_realloc(h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE);
+ av_fast_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE);
dst= h->rbsp_buffer[bufidx];
if (dst == NULL){
return dst;
}
-/**
- * identifies the exact end of the bitstream
- * @return the length of the trailing, or 0 if damaged
- */
-static int decode_rbsp_trailing(H264Context *h, const uint8_t *src){
+int ff_h264_decode_rbsp_trailing(H264Context *h, const uint8_t *src){
int v= *src;
int r;
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]);
av_freep(&hx->top_borders[0]);
av_freep(&hx->s.obmc_scratchpad);
+ av_freep(&hx->rbsp_buffer[1]);
+ av_freep(&hx->rbsp_buffer[0]);
+ hx->rbsp_buffer_size[0] = 0;
+ hx->rbsp_buffer_size[1] = 0;
+ if (i) av_freep(&h->thread_context[i]);
}
}
const int big_mb_num= s->mb_stride * (s->mb_height+1);
int x,y;
- CHECKED_ALLOCZ(h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t))
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t), fail)
- CHECKED_ALLOCZ(h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t))
- CHECKED_ALLOCZ(h->slice_table_base , (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base))
- CHECKED_ALLOCZ(h->cbp_table, big_mb_num * sizeof(uint16_t))
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t), fail)
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->slice_table_base , (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base), fail)
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->cbp_table, big_mb_num * sizeof(uint16_t), fail)
- CHECKED_ALLOCZ(h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t))
- CHECKED_ALLOCZ(h->mvd_table[0], 32*big_mb_num * sizeof(uint16_t));
- CHECKED_ALLOCZ(h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t));
- CHECKED_ALLOCZ(h->direct_table, 32*big_mb_num * sizeof(uint8_t));
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t), fail)
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[0], 32*big_mb_num * sizeof(uint16_t), fail);
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t), fail);
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->direct_table, 32*big_mb_num * sizeof(uint8_t) , fail);
memset(h->slice_table_base, -1, (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base));
h->slice_table= h->slice_table_base + s->mb_stride*2 + 1;
- CHECKED_ALLOCZ(h->mb2b_xy , big_mb_num * sizeof(uint32_t));
- CHECKED_ALLOCZ(h->mb2b8_xy , big_mb_num * sizeof(uint32_t));
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2b_xy , big_mb_num * sizeof(uint32_t), fail);
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2b8_xy , big_mb_num * sizeof(uint32_t), fail);
for(y=0; y<s->mb_height; y++){
for(x=0; x<s->mb_width; x++){
const int mb_xy= x + y*s->mb_stride;
* Allocate buffers which are not shared amongst multiple threads.
*/
static int context_init(H264Context *h){
- CHECKED_ALLOCZ(h->top_borders[0], h->s.mb_width * (16+8+8) * sizeof(uint8_t))
- CHECKED_ALLOCZ(h->top_borders[1], h->s.mb_width * (16+8+8) * sizeof(uint8_t))
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[0], h->s.mb_width * (16+8+8) * sizeof(uint8_t), fail)
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[1], h->s.mb_width * (16+8+8) * sizeof(uint8_t), fail)
return 0;
fail:
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(avctx->codec_id == CODEC_ID_SVQ3)
- avctx->pix_fmt= PIX_FMT_YUVJ420P;
- else if(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
- avctx->pix_fmt= PIX_FMT_VDPAU_H264;
- else
- avctx->pix_fmt= PIX_FMT_YUV420P;
+ avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
decode_init_vlc();
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;
+ 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;
}
* 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->s.first_field= 0;
- h->sei_recovery_frame_cnt = -1;
- h->sei_dpb_output_delay = 0;
- h->sei_cpb_removal_delay = -1;
+ 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 *pic;
+ Picture *av_uninit(pic);
if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0)
av_log(h->s.avctx, AV_LOG_DEBUG, "no mmco here\n");
for(i=0; i<mmco_count; i++){
- int structure, 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);
h->poc_msb=
h->frame_num=
s->current_picture_ptr->frame_num= 0;
+ s->current_picture_ptr->mmco_reset=1;
break;
default: assert(0);
}
}
}
+static void field_end(H264Context *h){
+ MpegEncContext * const s = &h->s;
+ AVCodecContext * const avctx= s->avctx;
+ s->mb_y= 0;
+
+ s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_H264;
+ s->current_picture_ptr->pict_type= s->pict_type;
+
+ if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
+ ff_vdpau_h264_set_reference_frames(s);
+
+ if(!s->dropable) {
+ execute_ref_pic_marking(h, h->mmco, h->mmco_index);
+ h->prev_poc_msb= h->poc_msb;
+ h->prev_poc_lsb= h->poc_lsb;
+ }
+ 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);
+
+ /*
+ * FIXME: Error handling code does not seem to support interlaced
+ * when slices span multiple rows
+ * The ff_er_add_slice calls don't work right for bottom
+ * fields; they cause massive erroneous error concealing
+ * Error marking covers both fields (top and bottom).
+ * This causes a mismatched s->error_count
+ * and a bad error table. Further, the error count goes to
+ * INT_MAX when called for bottom field, because mb_y is
+ * past end by one (callers fault) and resync_mb_y != 0
+ * causes problems for the first MB line, too.
+ */
+ if (!FIELD_PICTURE)
+ ff_er_frame_end(s);
+
+ MPV_frame_end(s);
+
+ h->current_slice=0;
+}
+
/**
* Replicates H264 "master" context to thread contexts.
*/
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;
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];
if (!s->context_initialized) {
if(h != h0)
return -1; // we cant (re-)initialize context during parallel decoding
+
+ avcodec_set_dimensions(s->avctx, s->width, s->height);
+ s->avctx->sample_aspect_ratio= h->sps.sar;
+ if(!s->avctx->sample_aspect_ratio.den)
+ s->avctx->sample_aspect_ratio.den = 1;
+
+ if(h->sps.timing_info_present_flag){
+ s->avctx->time_base= (AVRational){h->sps.num_units_in_tick, h->sps.time_scale};
+ if(h->x264_build > 0 && h->x264_build < 44)
+ 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);
+ }
+ s->avctx->pix_fmt = s->avctx->get_format(s->avctx, s->avctx->codec->pix_fmts);
+ s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt);
+
if (MPV_common_init(s) < 0)
return -1;
s->first_field = 0;
+ h->prev_interlaced_frame = 1;
init_scan_tables(h);
alloc_tables(h);
for(i = 0; i < s->avctx->thread_count; i++)
if(context_init(h->thread_context[i]) < 0)
return -1;
-
- s->avctx->width = s->width;
- s->avctx->height = s->height;
- s->avctx->sample_aspect_ratio= h->sps.sar;
- if(!s->avctx->sample_aspect_ratio.den)
- s->avctx->sample_aspect_ratio.den = 1;
-
- if(h->sps.timing_info_present_flag){
- s->avctx->time_base= (AVRational){h->sps.num_units_in_tick * 2, h->sps.time_scale};
- if(h->x264_build > 0 && h->x264_build < 44)
- 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);
- }
}
h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num);
while(h->frame_num != h->prev_frame_num &&
h->frame_num != (h->prev_frame_num+1)%(1<<h->sps.log2_max_frame_num)){
av_log(NULL, AV_LOG_DEBUG, "Frame num gap %d %d\n", h->frame_num, h->prev_frame_num);
- frame_start(h);
+ if (frame_start(h) < 0)
+ return -1;
h->prev_frame_num++;
h->prev_frame_num %= 1<<h->sps.log2_max_frame_num;
s->current_picture_ptr->frame_num= h->prev_frame_num;
//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;
}
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];
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;
}
}
ff_init_cabac_states( &h->cabac);
ff_init_cabac_decoder( &h->cabac,
s->gb.buffer + get_bits_count(&s->gb)/8,
- ( s->gb.size_in_bits - get_bits_count(&s->gb) + 7)/8);
+ (get_bits_left(&s->gb) + 7)/8);
/* calculate pre-state */
for( i= 0; i < 460; i++ ) {
int pre;
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);
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;
}
return 0;
}
-static int decode_sei(H264Context *h){
+static int decode_buffering_period(H264Context *h){
+ MpegEncContext * const s = &h->s;
+ unsigned int sps_id;
+ int sched_sel_idx;
+ SPS *sps;
+
+ sps_id = get_ue_golomb_31(&s->gb);
+ if(sps_id > 31 || !h->sps_buffers[sps_id]) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %d referenced in buffering period\n", sps_id);
+ return -1;
+ }
+ sps = h->sps_buffers[sps_id];
+
+ // NOTE: This is really so duplicated in the standard... See H.264, D.1.1
+ if (sps->nal_hrd_parameters_present_flag) {
+ for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) {
+ h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&s->gb, sps->initial_cpb_removal_delay_length);
+ skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
+ }
+ }
+ if (sps->vcl_hrd_parameters_present_flag) {
+ for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) {
+ h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&s->gb, sps->initial_cpb_removal_delay_length);
+ skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
+ }
+ }
+
+ h->sei_buffering_period_present = 1;
+ return 0;
+}
+
+int ff_h264_decode_sei(H264Context *h){
MpegEncContext * const s = &h->s;
while(get_bits_count(&s->gb) + 16 < s->gb.size_in_bits){
if(decode_recovery_point(h) < 0)
return -1;
break;
+ case SEI_BUFFERING_PERIOD:
+ if(decode_buffering_period(h) < 0)
+ return -1;
+ break;
default:
skip_bits(&s->gb, 8*size);
}
}
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 */
}
if(sps->timing_info_present_flag){
sps->num_units_in_tick = get_bits_long(&s->gb, 32);
sps->time_scale = get_bits_long(&s->gb, 32);
+ if(sps->num_units_in_tick-1 > 0x7FFFFFFEU || sps->time_scale-1 > 0x7FFFFFFEU){
+ av_log(h->s.avctx, AV_LOG_ERROR, "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n", sps->time_scale, sps->num_units_in_tick);
+ return -1;
+ }
sps->fixed_frame_rate_flag = get_bits1(&s->gb);
}
}
}
-static inline int decode_seq_parameter_set(H264Context *h){
+int ff_h264_decode_seq_parameter_set(H264Context *h){
MpegEncContext * const s = &h->s;
int profile_idc, level_idc;
unsigned int sps_id;
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\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
);
}
av_free(h->sps_buffers[sps_id]);
h->sps_buffers[sps_id]= sps;
+ h->sps = *sps;
return 0;
fail:
av_free(sps);
pps->chroma_qp_table[t][i] = chroma_qp[av_clip(i + index, 0, 51)];
}
-static inline int decode_picture_parameter_set(H264Context *h, int bit_length){
+int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
MpegEncContext * const s = &h->s;
unsigned int pps_id= get_ue_golomb(&s->gb);
PPS *pps;
H264Context *hx;
int i;
+ if (s->avctx->hwaccel)
+ return;
if(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
return;
if(context_count == 1) {
}
avctx->execute(avctx, (void *)decode_slice,
- (void **)h->thread_context, NULL, context_count, sizeof(void*));
+ h->thread_context, NULL, context_count, sizeof(void*));
/* pull back stuff from slices to master context */
hx = h->thread_context[context_count - 1];
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
h->current_slice = 0;
if (!s->first_field)
s->current_picture_ptr= NULL;
+ reset_sei(h);
}
for(;;){
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= 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;
}
while(ptr[dst_length - 1] == 0 && dst_length > 0)
dst_length--;
- bit_length= !dst_length ? 0 : (8*dst_length - decode_rbsp_trailing(h, ptr + dst_length - 1));
+ bit_length= !dst_length ? 0 : (8*dst_length - ff_h264_decode_rbsp_trailing(h, ptr + dst_length - 1));
if(s->avctx->debug&FF_DEBUG_STARTCODE){
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;
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);
&& (avctx->skip_frame < AVDISCARD_BIDIR || hx->slice_type_nos!=FF_B_TYPE)
&& (avctx->skip_frame < AVDISCARD_NONKEY || hx->slice_type_nos==FF_I_TYPE)
&& avctx->skip_frame < AVDISCARD_ALL){
+ if(avctx->hwaccel) {
+ if (avctx->hwaccel->decode_slice(avctx, &buf[buf_index - consumed], consumed) < 0)
+ return -1;
+ }else
if(CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){
static const uint8_t start_code[] = {0x00, 0x00, 0x01};
ff_vdpau_add_data_chunk(s, start_code, sizeof(start_code));
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);
break;
case NAL_SEI:
init_get_bits(&s->gb, ptr, bit_length);
- decode_sei(h);
+ ff_h264_decode_sei(h);
break;
case NAL_SPS:
init_get_bits(&s->gb, ptr, bit_length);
- decode_seq_parameter_set(h);
+ ff_h264_decode_seq_parameter_set(h);
if(s->flags& CODEC_FLAG_LOW_DELAY)
s->low_delay=1;
case NAL_PPS:
init_get_bits(&s->gb, ptr, bit_length);
- decode_picture_parameter_set(h, bit_length);
+ ff_h264_decode_picture_parameter_set(h, bit_length);
break;
case NAL_AUD:
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;
//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;
if(!(s->flags2 & CODEC_FLAG2_CHUNKS) || (s->mb_y >= s->mb_height && s->mb_height)){
Picture *out = s->current_picture_ptr;
Picture *cur = s->current_picture_ptr;
- int i, pics, cross_idr, out_of_order, out_idx;
-
- s->mb_y= 0;
-
- s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_H264;
- s->current_picture_ptr->pict_type= s->pict_type;
-
- if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
- ff_vdpau_h264_set_reference_frames(s);
-
- if(!s->dropable) {
- execute_ref_pic_marking(h, h->mmco, h->mmco_index);
- h->prev_poc_msb= h->poc_msb;
- h->prev_poc_lsb= h->poc_lsb;
- }
- h->prev_frame_num_offset= h->frame_num_offset;
- h->prev_frame_num= h->frame_num;
-
- if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
- ff_vdpau_h264_picture_complete(s);
+ int i, pics, out_of_order, out_idx;
- /*
- * FIXME: Error handling code does not seem to support interlaced
- * when slices span multiple rows
- * The ff_er_add_slice calls don't work right for bottom
- * fields; they cause massive erroneous error concealing
- * Error marking covers both fields (top and bottom).
- * This causes a mismatched s->error_count
- * and a bad error table. Further, the error count goes to
- * INT_MAX when called for bottom field, because mb_y is
- * past end by one (callers fault) and resync_mb_y != 0
- * causes problems for the first MB line, too.
- */
- if (!FIELD_PICTURE)
- 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;
+ field_end(h);
if (cur->field_poc[0]==INT_MAX || cur->field_poc[1]==INT_MAX) {
/* Wait for second field. */
*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->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:
+ cur->interlaced_frame = 1;
+ break;
case SEI_PIC_STRUCT_TOP_BOTTOM:
case SEI_PIC_STRUCT_BOTTOM_TOP:
- cur->interlaced_frame = 1;
+ 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)
// 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.
- 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;
-
- out_of_order = !cross_idr && out->poc < h->outputed_poc;
+ if(s->avctx->has_b_frames == 0 && (h->delayed_pic[0]->key_frame || h->delayed_pic[0]->mmco_reset))
+ h->outputed_poc= INT_MIN;
+ out_of_order = out->poc < h->outputed_poc;
if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >= h->sps.num_reorder_frames)
{ }
else if((out_of_order && pics-1 == s->avctx->has_b_frames && s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT)
|| (s->low_delay &&
- ((!cross_idr && out->poc > h->outputed_poc + 2)
+ ((h->outputed_poc != INT_MIN && out->poc > h->outputed_poc + 2)
|| cur->pict_type == FF_B_TYPE)))
{
s->low_delay = 0;
if(!out_of_order && pics > s->avctx->has_b_frames){
*data_size = sizeof(AVFrame);
- h->outputed_poc = out->poc;
+ if(out_idx==0 && h->delayed_pic[0] && (h->delayed_pic[0]->key_frame || h->delayed_pic[0]->mmco_reset)) {
+ h->outputed_poc = INT_MIN;
+ } else
+ h->outputed_poc = out->poc;
*pict= *(AVFrame*)out;
}else{
av_log(avctx, AV_LOG_DEBUG, "no picture\n");
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
return -1;
}
- out= decode_nal(&h, nal, &out_length, &consumed, nal_length);
+ out= ff_h264_decode_nal(&h, nal, &out_length, &consumed, nal_length);
STOP_TIMER("NAL")
#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]);
- av_freep(&h->rbsp_buffer[1]);
free_tables(h); //FIXME cleanup init stuff perhaps
for(i = 0; i < MAX_SPS_COUNT; i++)
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_hwaccel_pixfmt_list_420,
};
#if CONFIG_H264_VDPAU_DECODER
CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
.flush= flush_dpb,
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"),
+ .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_H264, PIX_FMT_NONE},
};
#endif