*/
/**
- * @file h264.c
+ * @file libavcodec/h264.c
* H.264 / AVC / MPEG4 part10 codec.
* @author Michael Niedermayer <michaelni@gmx.at>
*/
+#include "internal.h"
#include "dsputil.h"
#include "avcodec.h"
#include "mpegvideo.h"
#include "h264data.h"
#include "h264_parser.h"
#include "golomb.h"
+#include "mathops.h"
#include "rectangle.h"
#include "vdpau_internal.h"
#include "cabac.h"
-#ifdef ARCH_X86
+#if ARCH_X86
#include "x86/h264_i386.h"
#endif
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
};
-static const int left_block_options[4][8]={
+static const uint8_t left_block_options[4][8]={
{0,1,2,3,7,10,8,11},
{2,2,3,3,8,11,8,11},
{0,0,1,1,7,10,7,10},
const int mb_xy= h->mb_xy;
int topleft_xy, top_xy, topright_xy, left_xy[2];
int topleft_type, top_type, topright_type, left_type[2];
- const int * left_block;
+ const uint8_t * left_block;
int topleft_partition= -1;
int i;
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;
printf("%2X ", src[i]);
#endif
-#ifdef HAVE_FAST_UNALIGNED
-# ifdef HAVE_FAST_64BIT
+#if HAVE_FAST_UNALIGNED
+# 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;
qpix_op[luma_xy](dest_y + delta, src_y + delta, h->mb_linesize);
}
- if(ENABLE_GRAY && s->flags&CODEC_FLAG_GRAY) return;
+ if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return;
if(MB_FIELD){
// chroma offset when predicting from a field of opposite parity
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(avctx->codec_id == CODEC_ID_SVQ3)
- avctx->pix_fmt= PIX_FMT_YUVJ420P;
- else if(avctx->codec_id == CODEC_ID_H264_VDPAU)
+ if(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
avctx->pix_fmt= PIX_FMT_VDPAU_H264;
else
- avctx->pix_fmt= PIX_FMT_YUV420P;
+ 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();
h->thread_context[0] = h;
h->outputed_poc = INT_MIN;
h->prev_poc_msb= 1<<16;
+ 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(!MB_MBAFF){
*(uint64_t*)(h->top_borders[0][s->mb_x]+ 0)= *(uint64_t*)(src_y + 15*linesize);
*(uint64_t*)(h->top_borders[0][s->mb_x]+ 8)= *(uint64_t*)(src_y +8+15*linesize);
- if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+ if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
*(uint64_t*)(h->top_borders[0][s->mb_x]+16)= *(uint64_t*)(src_cb+7*uvlinesize);
*(uint64_t*)(h->top_borders[0][s->mb_x]+24)= *(uint64_t*)(src_cr+7*uvlinesize);
}
}else{
if(!MB_MBAFF){
h->left_border[0]= h->top_borders[0][s->mb_x][15];
- if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+ if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
h->left_border[34 ]= h->top_borders[0][s->mb_x][16+7 ];
h->left_border[34+18]= h->top_borders[0][s->mb_x][16+8+7];
}
*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+0)= *(uint64_t*)(src_y + 16*linesize);
*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+8)= *(uint64_t*)(src_y +8+16*linesize);
- if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+ if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
h->left_border[uvoffset+34 ]= h->top_borders[top_idx][s->mb_x][16+7];
h->left_border[uvoffset+34+18]= h->top_borders[top_idx][s->mb_x][24+7];
for(i=1; i<9 - skiplast; i++){
}
}
- if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+ if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
if(deblock_left){
for(i = !deblock_top; i<8; i++){
XCHG(h->left_border[uvoffset+34 +i*step], src_cb[i*uvlinesize], temp8, xchg);
int i;
int *block_offset = &h->block_offset[0];
const int transform_bypass = !simple && (s->qscale == 0 && h->sps.transform_bypass);
- const int is_h264 = simple || s->codec_id == CODEC_ID_H264;
+ /* is_h264 should always be true if SVQ3 is disabled. */
+ const int is_h264 = !CONFIG_SVQ3_DECODER || simple || s->codec_id == CODEC_ID_H264;
void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
void (*idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride);
if(h->deblocking_filter)
xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 1, simple);
- if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+ if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
h->hpc.pred8x8[ h->chroma_pred_mode ](dest_cb, uvlinesize);
h->hpc.pred8x8[ h->chroma_pred_mode ](dest_cr, uvlinesize);
}
}
}
- if((simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)) && (h->cbp&0x30)){
+ if((simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) && (h->cbp&0x30)){
uint8_t *dest[2] = {dest_cb, dest_cr};
if(transform_bypass){
if(IS_INTRA(mb_type) && h->sps.profile_idc==244 && (h->chroma_pred_mode==VERT_PRED8x8 || h->chroma_pred_mode==HOR_PRED8x8)){
MpegEncContext * const s = &h->s;
const int mb_xy= h->mb_xy;
const int mb_type= s->current_picture.mb_type[mb_xy];
- int is_complex = ENABLE_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || s->qscale == 0;
-
- if(ENABLE_H264_ENCODER && !s->decode)
- return;
+ int is_complex = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || s->qscale == 0;
if (is_complex)
hl_decode_mb_complex(h);
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;
}
}
}
chroma_def = 1<<h->chroma_log2_weight_denom;
for(list=0; list<2; list++){
+ h->luma_weight_flag[list] = 0;
+ h->chroma_weight_flag[list] = 0;
for(i=0; i<h->ref_count[list]; i++){
int luma_weight_flag, chroma_weight_flag;
h->luma_weight[list][i]= get_se_golomb(&s->gb);
h->luma_offset[list][i]= get_se_golomb(&s->gb);
if( h->luma_weight[list][i] != luma_def
- || h->luma_offset[list][i] != 0)
+ || h->luma_offset[list][i] != 0) {
h->use_weight= 1;
+ h->luma_weight_flag[list]= 1;
+ }
}else{
h->luma_weight[list][i]= luma_def;
h->luma_offset[list][i]= 0;
h->chroma_weight[list][i][j]= get_se_golomb(&s->gb);
h->chroma_offset[list][i][j]= get_se_golomb(&s->gb);
if( h->chroma_weight[list][i][j] != chroma_def
- || h->chroma_offset[list][i][j] != 0)
+ || h->chroma_offset[list][i][j] != 0) {
h->use_weight_chroma= 1;
+ h->chroma_weight_flag[list]= 1;
+ }
}
}else{
int j;
static void implicit_weight_table(H264Context *h){
MpegEncContext * const s = &h->s;
- int ref0, ref1;
+ int ref0, ref1, i;
int cur_poc = s->current_picture_ptr->poc;
+ for (i = 0; i < 2; i++) {
+ h->luma_weight_flag[i] = 0;
+ h->chroma_weight_flag[i] = 0;
+ }
+
if( h->ref_count[0] == 1 && h->ref_count[1] == 1
&& h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2*cur_poc){
h->use_weight= 0;
if(h->s.current_picture_ptr)
h->s.current_picture_ptr->reference= 0;
h->s.first_field= 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 *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);
}
}
if(s->dsp.h264_idct8_add == ff_h264_idct8_add_c){
- memcpy(h->zigzag_scan8x8, zigzag_scan8x8, 64*sizeof(uint8_t));
+ memcpy(h->zigzag_scan8x8, ff_zigzag_direct, 64*sizeof(uint8_t));
memcpy(h->zigzag_scan8x8_cavlc, zigzag_scan8x8_cavlc, 64*sizeof(uint8_t));
memcpy(h->field_scan8x8, field_scan8x8, 64*sizeof(uint8_t));
memcpy(h->field_scan8x8_cavlc, field_scan8x8_cavlc, 64*sizeof(uint8_t));
}else{
for(i=0; i<64; i++){
#define T(x) (x>>3) | ((x&7)<<3)
- h->zigzag_scan8x8[i] = T(zigzag_scan8x8[i]);
+ h->zigzag_scan8x8[i] = T(ff_zigzag_direct[i]);
h->zigzag_scan8x8_cavlc[i] = T(zigzag_scan8x8_cavlc[i]);
h->field_scan8x8[i] = T(field_scan8x8[i]);
h->field_scan8x8_cavlc[i] = T(field_scan8x8_cavlc[i]);
}
if(h->sps.transform_bypass){ //FIXME same ugly
h->zigzag_scan_q0 = zigzag_scan;
- h->zigzag_scan8x8_q0 = zigzag_scan8x8;
+ h->zigzag_scan8x8_q0 = ff_zigzag_direct;
h->zigzag_scan8x8_cavlc_q0 = zigzag_scan8x8_cavlc;
h->field_scan_q0 = field_scan;
h->field_scan8x8_q0 = field_scan8x8;
}
}
+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];
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};
+ 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,
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;
pred_weight_table(h);
else if(h->pps.weighted_bipred_idc==2 && h->slice_type_nos== FF_B_TYPE)
implicit_weight_table(h);
- else
+ else {
h->use_weight = 0;
+ for (i = 0; i < 2; i++) {
+ h->luma_weight_flag[i] = 0;
+ h->chroma_weight_flag[i] = 0;
+ }
+ }
if(h->nal_ref_idc)
decode_ref_pic_marking(h0, &s->gb);
//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;
}
uint8_t *last_coeff_ctx_base;
uint8_t *abs_level_m1_ctx_base;
-#ifndef ARCH_X86
+#if !ARCH_X86
#define CABAC_ON_STACK
#endif
#ifdef CABAC_ON_STACK
index[coeff_count++] = last;\
}
const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD];
-#if defined(ARCH_X86) && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS)
+#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS)
coeff_count= decode_significance_8x8_x86(CC, significant_coeff_ctx_base, index, sig_off);
} else {
coeff_count= decode_significance_x86(CC, max_coeff, significant_coeff_ctx_base, index);
}
-#ifndef CONFIG_SMALL
+#if !CONFIG_SMALL
static void decode_cabac_residual_dc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) {
decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 1);
}
#endif
static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) {
-#ifdef CONFIG_SMALL
+#if CONFIG_SMALL
decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, cat == 0 || cat == 3);
#else
if( cat == 0 || cat == 3 ) decode_cabac_residual_dc(h, block, cat, n, scantable, qmul, max_coeff);
}
-static void av_always_inline filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int dir) {
+static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int dir) {
MpegEncContext * const s = &h->s;
int edge;
const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy;
const int mb_type = s->current_picture.mb_type[mb_xy];
const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
int first_vertical_edge_done = 0;
- int dir;
+ av_unused int dir;
//for sufficiently low qp, filtering wouldn't do anything
//this is a conservative estimate: could also check beta_offset and more accurate chroma_qp
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;
}
}
filter_mb_mbaff_edgecv( h, &img_cr[0], uvlinesize, bS, rqp );
}
-#ifdef CONFIG_SMALL
+#if CONFIG_SMALL
for( dir = 0; dir < 2; dir++ )
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, dir ? 0 : first_vertical_edge_done, dir);
#else
s->mb_skip_run= -1;
h->is_complex = FRAME_MBAFF || s->picture_structure != PICT_FRAME || s->codec_id != CODEC_ID_H264 ||
- (ENABLE_GRAY && (s->flags&CODEC_FLAG_GRAY)) || (ENABLE_H264_ENCODER && s->encoding);
+ (CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
if( h->pps.cabac ) {
int i;
static int decode_picture_timing(H264Context *h){
MpegEncContext * const s = &h->s;
if(h->sps.nal_hrd_parameters_present_flag || h->sps.vcl_hrd_parameters_present_flag){
- skip_bits(&s->gb, h->sps.cpb_removal_delay_length); /* cpb_removal_delay */
- skip_bits(&s->gb, h->sps.dpb_output_delay_length); /* dpb_output_delay */
+ h->sei_cpb_removal_delay = get_bits(&s->gb, h->sps.cpb_removal_delay_length);
+ h->sei_dpb_output_delay = get_bits(&s->gb, h->sps.dpb_output_delay_length);
}
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);
return 0;
}
-static int decode_sei(H264Context *h){
+static int decode_recovery_point(H264Context *h){
+ MpegEncContext * const s = &h->s;
+
+ h->sei_recovery_frame_cnt = get_ue_golomb(&s->gb);
+ skip_bits(&s->gb, 4); /* 1b exact_match_flag, 1b broken_link_flag, 2b changing_slice_group_idc */
+
+ return 0;
+}
+
+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){
}while(get_bits(&s->gb, 8) == 255);
switch(type){
- case 1: // Picture timing SEI
+ case SEI_TYPE_PIC_TIMING: // Picture timing SEI
if(decode_picture_timing(h) < 0)
return -1;
break;
- case 5:
+ case SEI_TYPE_USER_DATA_UNREGISTERED:
if(decode_unregistered_user_data(h, size) < 0)
return -1;
break;
+ case SEI_TYPE_RECOVERY_POINT:
+ 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);
}
get_ue_golomb(&s->gb); /* cpb_size_value_minus1 */
get_bits1(&s->gb); /* cbr_flag */
}
- get_bits(&s->gb, 5); /* initial_cpb_removal_delay_length_minus1 */
+ sps->initial_cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
sps->cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
sps->dpb_output_delay_length = get_bits(&s->gb, 5) + 1;
sps->time_offset_length = get_bits(&s->gb, 5);
+ sps->cpb_cnt = cpb_count;
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 */
}
const uint8_t *jvt_list, const uint8_t *fallback_list){
MpegEncContext * const s = &h->s;
int i, last = 8, next = 8;
- const uint8_t *scan = size == 16 ? zigzag_scan : zigzag_scan8x8;
+ const uint8_t *scan = size == 16 ? zigzag_scan : ff_zigzag_direct;
if(!get_bits1(&s->gb)) /* matrix not written, we use the predicted one */
memcpy(factors, fallback_list, size*sizeof(uint8_t));
else
}
}
-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;
if(sps->profile_idc >= 100){ //high profile
sps->chroma_format_idc= get_ue_golomb_31(&s->gb);
if(sps->chroma_format_idc == 3)
- get_bits1(&s->gb); //residual_color_transform_flag
- get_ue_golomb(&s->gb); //bit_depth_luma_minus8
- get_ue_golomb(&s->gb); //bit_depth_chroma_minus8
+ sps->residual_color_transform_flag = get_bits1(&s->gb);
+ sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8;
+ sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8;
sps->transform_bypass = get_bits1(&s->gb);
decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8);
}else{
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
);
}
+
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(avctx->codec_id == CODEC_ID_H264_VDPAU)
+ if (s->avctx->hwaccel)
+ return;
+ if(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
return;
if(context_count == 1) {
decode_slice(avctx, &h);
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++)
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)){
- av_log(h->s.avctx, AV_LOG_ERROR, "AVC: Consumed only %d bytes instead of %d\n", consumed, nalsize);
- consumed= nalsize;
+ 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);
}
buf_index += consumed;
if((err = decode_slice_header(hx, h)))
break;
- s->current_picture_ptr->key_frame|= (hx->nal_unit_type == NAL_IDR_SLICE);
+ 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);
if(hx->redundant_pic_count==0 && hx->s.hurry_up < 5
&& (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc)
&& (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(ENABLE_H264_VDPAU_DECODER && avctx->codec_id == CODEC_ID_H264_VDPAU){
+ 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_h264_add_data_chunk(h, start_code, sizeof(start_code));
- ff_VDPAU_h264_add_data_chunk(h, &buf[buf_index - consumed], consumed );
+ ff_vdpau_add_data_chunk(s, start_code, sizeof(start_code));
+ ff_vdpau_add_data_chunk(s, &buf[buf_index - consumed], consumed );
}else
context_count++;
}
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;
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(!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 (ENABLE_H264_VDPAU_DECODER && avctx->codec_id == CODEC_ID_H264_VDPAU)
- ff_VDPAU_h264_picture_complete(h);
-
- /*
- * 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 (avctx->codec_id != CODEC_ID_H264_VDPAU && !FIELD_PICTURE)
- ff_er_frame_end(s);
-
- MPV_frame_end(s);
+ field_end(h);
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.
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]);
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,
};
-#ifdef CONFIG_H264_VDPAU_DECODER
+#if CONFIG_H264_VDPAU_DECODER
AVCodec h264_vdpau_decoder = {
"h264_vdpau",
CODEC_TYPE_VIDEO,
- CODEC_ID_H264_VDPAU,
+ CODEC_ID_H264,
sizeof(H264Context),
decode_init,
NULL,
};
#endif
+#if CONFIG_SVQ3_DECODER
#include "svq3.c"
+#endif