#include "libavutil/imgutils.h"
#include "internal.h"
+#include "cabac.h"
+#include "cabac_functions.h"
#include "dsputil.h"
#include "avcodec.h"
#include "mpegvideo.h"
#include "vdpau_internal.h"
#include "libavutil/avassert.h"
-#include "cabac.h"
-
//#undef NDEBUG
#include <assert.h>
};
/**
- * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks.
+ * Check if the top & left blocks are available if needed and
+ * change the dc mode so it only uses the available blocks.
*/
int ff_h264_check_intra4x4_pred_mode(H264Context *h){
MpegEncContext * const s = &h->s;
} //FIXME cleanup like ff_h264_check_intra_pred_mode
/**
- * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks.
+ * Check if the top & left blocks are available if needed and
+ * change the dc mode so it only uses the available blocks.
*/
-int ff_h264_check_intra_pred_mode(H264Context *h, int mode){
+int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma){
MpegEncContext * const s = &h->s;
static const int8_t top [7]= {LEFT_DC_PRED8x8, 1,-1,-1};
static const int8_t left[7]= { TOP_DC_PRED8x8,-1, 2,-1,DC_128_PRED8x8};
if((h->left_samples_available&0x8080) != 0x8080){
mode= left[ mode ];
- if(h->left_samples_available&0x8080){ //mad cow disease mode, aka MBAFF + constrained_intra_pred
+ if(is_chroma && (h->left_samples_available&0x8080)){ //mad cow disease mode, aka MBAFF + constrained_intra_pred
mode= ALZHEIMER_DC_L0T_PRED8x8 + (!(h->left_samples_available&0x8000)) + 2*(mode == DC_128_PRED8x8);
}
if(mode<0){
h->dequant_coeff_pps= -1;
s->unrestricted_mv=1;
- dsputil_init(&s->dsp, s->avctx); // needed so that idct permutation is known early
+ ff_dsputil_init(&s->dsp, s->avctx); // needed so that idct permutation is known early
memset(h->pps.scaling_matrix4, 16, 6*16*sizeof(uint8_t));
memset(h->pps.scaling_matrix8, 16, 2*64*sizeof(uint8_t));
MpegEncContext * const s = &h->s;
int i;
- MPV_decode_defaults(s);
+ ff_MPV_decode_defaults(s);
s->avctx = avctx;
common_init(h);
MpegEncContext * const s = &h->s;
int i;
const int pixel_shift = h->pixel_shift;
- int thread_count = (s->avctx->active_thread_type & FF_THREAD_SLICE) ? s->avctx->thread_count : 1;
- if(MPV_frame_start(s, s->avctx) < 0)
+ if(ff_MPV_frame_start(s, s->avctx) < 0)
return -1;
ff_er_frame_start(s);
/*
- * MPV_frame_start uses pict_type to derive key_frame.
+ * ff_MPV_frame_start uses pict_type to derive key_frame.
* This is incorrect for H.264; IDR markings must be used.
* Zero here; IDR markings per slice in frame or fields are ORed in later.
* See decode_nal_units().
/* can't be in alloc_tables because linesize isn't known there.
* FIXME: redo bipred weight to not require extra buffer? */
- for(i = 0; i < thread_count; i++)
+ for(i = 0; i < s->slice_context_count; i++)
if(h->thread_context[i] && !h->thread_context[i]->s.obmc_scratchpad)
h->thread_context[i]->s.obmc_scratchpad = av_malloc(16*6*s->linesize);
// We mark the current picture as non-reference after allocating it, so
// that if we break out due to an error it can be released automatically
- // in the next MPV_frame_start().
+ // in the next ff_MPV_frame_start().
// SVQ3 as well as most other codecs have only last/next/current and thus
// get released even with set reference, besides SVQ3 and others do not
// mark frames as reference later "naturally".
h->next_outputed_poc = INT_MIN;
}
} else {
- h->next_outputed_poc = out->poc;
+ if (out_idx == 0 && pics > 1 && h->delayed_pic[0]->f.key_frame) {
+ h->next_outputed_poc = INT_MIN;
+ } else {
+ h->next_outputed_poc = out->poc;
+ }
}
h->mmco_reset = 0;
}else{
idct_dc_add(ptr, h->mb + (i*16+p*256 << pixel_shift), linesize);
else
idct_add (ptr, h->mb + (i*16+p*256 << pixel_shift), linesize);
- }else
+ } else if (CONFIG_SVQ3_DECODER)
ff_svq3_add_idct_c(ptr, h->mb + i*16+p*256, linesize, qscale, 0);
}
}
dctcoef_set(h->mb+(p*256 << pixel_shift), pixel_shift, dc_mapping[i], dctcoef_get(h->mb_luma_dc[p], pixel_shift, i));
}
}
- }else
+ } else if (CONFIG_SVQ3_DECODER)
ff_svq3_luma_dc_dequant_idct_c(h->mb+p*256, h->mb_luma_dc[p], qscale);
}
}
}
}
}
- }else{
+ } else if (CONFIG_SVQ3_DECODER) {
for(i=0; i<16; i++){
if(h->non_zero_count_cache[ scan8[i+p*16] ] || h->mb[i*16+p*256]){ //FIXME benchmark weird rule, & below
uint8_t * const ptr= dest_y + block_offset[i];
h->h264dsp.h264_idct_add8(dest, block_offset,
h->mb, uvlinesize,
h->non_zero_count_cache);
- }else{
+ } else if (CONFIG_SVQ3_DECODER) {
h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 16*16*1, h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][h->chroma_qp[0]][0]);
h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 16*16*2, h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][h->chroma_qp[1]][0]);
for(j=1; j<3; j++){
static void hl_decode_mb_simple_ ## bits(H264Context *h){ \
hl_decode_mb_internal(h, 1, sh); \
}
-hl_decode_mb_simple(0, 8);
-hl_decode_mb_simple(1, 16);
+hl_decode_mb_simple(0, 8)
+hl_decode_mb_simple(1, 16)
/**
* Process a macroblock; this handles edge cases, such as interlacing.
if (!FIELD_PICTURE)
ff_er_frame_end(s);
- MPV_frame_end(s);
+ ff_MPV_frame_end(s);
h->current_slice=0;
}
/**
- * computes profile from profile_idc and constraint_set?_flags
+ * Compute profile from profile_idc and constraint_set?_flags.
*
* @param sps SPS
*
}
/**
- * decodes a slice header.
- * This will also call MPV_common_init() and frame_start() as needed.
+ * Decode a slice header.
+ * This will also call ff_MPV_common_init() and frame_start() as needed.
*
* @param h h264context
* @param h0 h264 master context (differs from 'h' when doing sliced based parallel decoding)
}
free_tables(h, 0);
flush_dpb(s->avctx);
- MPV_common_end(s);
+ ff_MPV_common_end(s);
}
if (!s->context_initialized) {
if (h != h0) {
s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt);
- if (MPV_common_init(s) < 0) {
- av_log(h->s.avctx, AV_LOG_ERROR, "MPV_common_init() failed.\n");
+ if (ff_MPV_common_init(s) < 0) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "ff_MPV_common_init() failed.\n");
return -1;
}
s->first_field = 0;
return -1;
}
} else {
- for(i = 1; i < s->avctx->thread_count; i++) {
+ for(i = 1; i < s->slice_context_count; i++) {
H264Context *c;
c = h->thread_context[i] = av_malloc(sizeof(H264Context));
memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext));
clone_tables(c, h, i);
}
- for(i = 0; i < s->avctx->thread_count; i++)
+ for(i = 0; i < s->slice_context_count; i++)
if (context_init(h->thread_context[i]) < 0) {
av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n");
return -1;
static int decode_slice(struct AVCodecContext *avctx, void *arg){
H264Context *h = *(void**)arg;
MpegEncContext * const s = &h->s;
- const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F;
+ const int part_mask= s->partitioned_frame ? (ER_AC_END|ER_AC_ERROR) : 0x7F;
int lf_x_start = s->mb_x;
s->mb_skip_run= -1;
eos = get_cabac_terminate( &h->cabac );
if((s->workaround_bugs & FF_BUG_TRUNCATED) && h->cabac.bytestream > h->cabac.bytestream_end + 2){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask);
if (s->mb_x >= lf_x_start) loop_filter(h, lf_x_start, s->mb_x + 1);
return 0;
}
if( ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%td)\n", s->mb_x, s->mb_y, h->cabac.bytestream_end - h->cabac.bytestream);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
return -1;
}
if( eos || s->mb_y >= s->mb_height ) {
tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask);
if (s->mb_x > lf_x_start) loop_filter(h, lf_x_start, s->mb_x);
return 0;
}
if(ret<0){
av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
return -1;
}
tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
if(get_bits_count(&s->gb) == s->gb.size_in_bits ) {
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask);
return 0;
}else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
return -1;
}
if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->mb_skip_run<=0){
tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
if(get_bits_count(&s->gb) == s->gb.size_in_bits ){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask);
if (s->mb_x > lf_x_start) loop_filter(h, lf_x_start, s->mb_x);
return 0;
}else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
return -1;
}
} else {
for(i = 1; i < context_count; i++) {
hx = h->thread_context[i];
- hx->s.error_recognition = avctx->error_recognition;
+ hx->s.err_recognition = avctx->err_recognition;
hx->s.error_count = 0;
}
- avctx->execute(avctx, (void *)decode_slice,
+ avctx->execute(avctx, decode_slice,
h->thread_context, NULL, context_count, sizeof(void*));
/* pull back stuff from slices to master context */
int nals_needed=0; ///< number of NALs that need decoding before the next frame thread starts
int nal_index;
- h->max_contexts = (HAVE_THREADS && (s->avctx->active_thread_type&FF_THREAD_SLICE)) ? avctx->thread_count : 1;
+ h->max_contexts = s->slice_context_count;
if(!(s->flags2 & CODEC_FLAG2_CHUNKS)){
h->current_slice = 0;
if (!s->first_field)
int consumed;
int dst_length;
int bit_length;
- const uint8_t *ptr;
+ uint8_t *ptr;
int i, nalsize = 0;
int err;
if(buf_index >= next_avc) {
- if(buf_index >= buf_size) break;
+ if (buf_index >= buf_size - h->nal_length_size) break;
nalsize = 0;
for(i = 0; i < h->nal_length_size; i++)
nalsize = (nalsize << 8) | buf[buf_index++];
}
if (h->is_avc && (nalsize != consumed) && nalsize){
+ // set trailing bits in the last partial byte to zero
+ if (bit_length & 7)
+ ptr[bit_length >> 3] = ptr[bit_length >> 3] & (0xff << 8 - (bit_length & 7));
av_log(h->s.avctx, AV_LOG_DEBUG, "AVC: Consumed only %d bytes instead of %d\n", consumed, nalsize);
}
ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma, h->sps.chroma_format_idc);
ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma, h->sps.chroma_format_idc);
s->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16;
- dsputil_init(&s->dsp, s->avctx);
+ ff_dsputil_init(&s->dsp, s->avctx);
} else {
av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", h->sps.bit_depth_luma);
return -1;
}
/**
- * returns the number of bytes consumed for building the current frame
+ * Return the number of bytes consumed for building the current frame.
*/
static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size){
if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...)
H264Context *h = avctx->priv_data;
MpegEncContext *s = &h->s;
AVFrame *pict = data;
- int buf_index;
+ int buf_index = 0;
s->flags= avctx->flags;
s->flags2= avctx->flags2;
*pict= *(AVFrame*)out;
}
- return 0;
+ return buf_index;
}
buf_index=decode_nal_units(h, buf, buf_size);
}
#endif
-#ifdef TEST
-#undef printf
-#undef random
-#define COUNT 8000
-#define SIZE (COUNT*40)
-int main(void){
- int i;
- uint8_t temp[SIZE];
- PutBitContext pb;
- GetBitContext gb;
-// int int_temp[10000];
- DSPContext dsp;
- AVCodecContext avctx;
-
- dsputil_init(&dsp, &avctx);
-
- init_put_bits(&pb, temp, SIZE);
- printf("testing unsigned exp golomb\n");
- for(i=0; i<COUNT; i++){
- START_TIMER
- set_ue_golomb(&pb, i);
- STOP_TIMER("set_ue_golomb");
- }
- flush_put_bits(&pb);
-
- init_get_bits(&gb, temp, 8*SIZE);
- for(i=0; i<COUNT; i++){
- int j, s;
-
- s= show_bits(&gb, 24);
-
- START_TIMER
- j= get_ue_golomb(&gb);
- if(j != i){
- printf("mismatch! at %d (%d should be %d) bits:%6X\n", i, j, i, s);
-// return -1;
- }
- STOP_TIMER("get_ue_golomb");
- }
-
-
- init_put_bits(&pb, temp, SIZE);
- printf("testing signed exp golomb\n");
- for(i=0; i<COUNT; i++){
- START_TIMER
- set_se_golomb(&pb, i - COUNT/2);
- STOP_TIMER("set_se_golomb");
- }
- flush_put_bits(&pb);
-
- init_get_bits(&gb, temp, 8*SIZE);
- for(i=0; i<COUNT; i++){
- int j, s;
-
- s= show_bits(&gb, 24);
-
- START_TIMER
- j= get_se_golomb(&gb);
- if(j != i - COUNT/2){
- printf("mismatch! at %d (%d should be %d) bits:%6X\n", i, j, i, s);
-// return -1;
- }
- STOP_TIMER("get_se_golomb");
- }
-
- printf("Testing RBSP\n");
-
-
- return 0;
-}
-#endif /* TEST */
-
-
av_cold void ff_h264_free_context(H264Context *h)
{
int i;
ff_h264_free_context(h);
- MPV_common_end(s);
+ ff_MPV_common_end(s);
// memset(h, 0, sizeof(H264Context));