DCTELEM *block, int n, int qscale);
static void dct_unquantize_h263_inter_c(MpegEncContext *s,
DCTELEM *block, int n, int qscale);
-static void draw_edges_c(uint8_t *buf, int wrap, int width, int height, int w);
-#ifdef HAVE_XVMC
extern int XVMC_field_start(MpegEncContext*s, AVCodecContext *avctx);
extern void XVMC_field_end(MpegEncContext *s);
extern void XVMC_decode_mb(MpegEncContext *s);
-#endif
-
-void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w)= draw_edges_c;
/* enable all paranoid tests for rounding, overflows, etc... */
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
};
-void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable){
- int i;
- int end;
-
- st->scantable= src_scantable;
+const uint8_t ff_mpeg1_dc_scale_table[128]={
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+};
- for(i=0; i<64; i++){
- int j;
- j = src_scantable[i];
- st->permutated[i] = permutation[j];
-#ifdef ARCH_POWERPC
- st->inverse[j] = i;
-#endif
- }
-
- end=-1;
- for(i=0; i<64; i++){
- int j;
- j = st->permutated[i];
- if(j>end) end=j;
- st->raster_end[i]= end;
- }
-}
const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state){
int i;
MPV_common_init_mmx(s);
#elif defined(ARCH_ALPHA)
MPV_common_init_axp(s);
-#elif defined(HAVE_MLIB)
+#elif defined(CONFIG_MLIB)
MPV_common_init_mlib(s);
#elif defined(HAVE_MMI)
MPV_common_init_mmi(s);
/* It might be nicer if the application would keep track of these
* but it would require an API change. */
memmove(s->prev_pict_types+1, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE-1);
- s->prev_pict_types[0]= s->pict_type;
- if(pic->age < PREV_PICT_TYPES_BUFFER_SIZE && s->prev_pict_types[pic->age] == B_TYPE)
+ s->prev_pict_types[0]= s->dropable ? FF_B_TYPE : s->pict_type;
+ if(pic->age < PREV_PICT_TYPES_BUFFER_SIZE && s->prev_pict_types[pic->age] == FF_B_TYPE)
pic->age= INT_MAX; // Skipped MBs in B-frames are quite rare in MPEG-1/2 and it is a bit tricky to skip them anyway.
return 0;
s->parse_context.state= -1;
if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){
s->visualization_buffer[0] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);
- s->visualization_buffer[1] = av_malloc((s->mb_width*8 + EDGE_WIDTH) * s->mb_height*8 + EDGE_WIDTH);
- s->visualization_buffer[2] = av_malloc((s->mb_width*8 + EDGE_WIDTH) * s->mb_height*8 + EDGE_WIDTH);
+ s->visualization_buffer[1] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);
+ s->visualization_buffer[2] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);
}
s->context_initialized = 1;
s->thread_context[0]= s;
- /* h264 does thread context setup itself, but it needs context[0]
- * to be fully initialized for the error resilience code */
- threads = s->codec_id == CODEC_ID_H264 ? 1 : s->avctx->thread_count;
+ threads = s->avctx->thread_count;
for(i=1; i<threads; i++){
s->thread_context[i]= av_malloc(sizeof(MpegEncContext));
}
}
-void init_vlc_rl(RLTable *rl, int use_static)
+void init_vlc_rl(RLTable *rl)
{
int i, q;
- /* Return if static table is already initialized */
- if(use_static && rl->rl_vlc[0])
- return;
-
- init_vlc(&rl->vlc, 9, rl->n + 1,
- &rl->table_vlc[0][1], 4, 2,
- &rl->table_vlc[0][0], 4, 2, use_static);
-
-
for(q=0; q<32; q++){
int qmul= q*2;
int qadd= (q-1)|1;
qmul=1;
qadd=0;
}
- if(use_static)
- rl->rl_vlc[q]= av_mallocz_static(rl->vlc.table_size*sizeof(RL_VLC_ELEM));
- else
- rl->rl_vlc[q]= av_malloc(rl->vlc.table_size*sizeof(RL_VLC_ELEM));
for(i=0; i<rl->vlc.table_size; i++){
int code= rl->vlc.table[i][0];
int len = rl->vlc.table[i][1];
}
}
-/* draw the edges of width 'w' of an image of size width, height */
-//FIXME check that this is ok for mpeg4 interlaced
-static void draw_edges_c(uint8_t *buf, int wrap, int width, int height, int w)
-{
- uint8_t *ptr, *last_line;
- int i;
-
- last_line = buf + (height - 1) * wrap;
- for(i=0;i<w;i++) {
- /* top and bottom */
- memcpy(buf - (i + 1) * wrap, buf, width);
- memcpy(last_line + (i + 1) * wrap, last_line, width);
- }
- /* left and right */
- ptr = buf;
- for(i=0;i<height;i++) {
- memset(ptr - w, ptr[0], w);
- memset(ptr + width, ptr[width-1], w);
- ptr += wrap;
- }
- /* corners */
- for(i=0;i<w;i++) {
- memset(buf - (i + 1) * wrap - w, buf[0], w); /* top left */
- memset(buf - (i + 1) * wrap + width, buf[width-1], w); /* top right */
- memset(last_line + (i + 1) * wrap - w, last_line[0], w); /* top left */
- memset(last_line + (i + 1) * wrap + width, last_line[width-1], w); /* top right */
- }
-}
-
int ff_find_unused_picture(MpegEncContext *s, int shared){
int i;
assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3);
/* mark&release old frames */
- if (s->pict_type != B_TYPE && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && s->last_picture_ptr->data[0]) {
+ if (s->pict_type != FF_B_TYPE && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && s->last_picture_ptr->data[0]) {
if(s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3){
avctx->release_buffer(avctx, (AVFrame*)s->last_picture_ptr);
}
if(s->current_picture_ptr && s->current_picture_ptr->data[0]==NULL)
- pic= (AVFrame*)s->current_picture_ptr; //we allready have a unused image (maybe it was set before reading the header)
+ pic= (AVFrame*)s->current_picture_ptr; //we already have a unused image (maybe it was set before reading the header)
else{
i= ff_find_unused_picture(s, 0);
pic= (AVFrame*)&s->picture[i];
if (!s->dropable){
if (s->codec_id == CODEC_ID_H264)
pic->reference = s->picture_structure;
- else if (s->pict_type != B_TYPE)
+ else if (s->pict_type != FF_B_TYPE)
pic->reference = 3;
}
s->current_picture_ptr->pict_type= s->pict_type;
// if(s->flags && CODEC_FLAG_QSCALE)
// s->current_picture_ptr->quality= s->new_picture_ptr->quality;
- s->current_picture_ptr->key_frame= s->pict_type == I_TYPE;
+ s->current_picture_ptr->key_frame= s->pict_type == FF_I_TYPE;
copy_picture(&s->current_picture, s->current_picture_ptr);
- if (s->pict_type != B_TYPE) {
+ if (s->pict_type != FF_B_TYPE) {
s->last_picture_ptr= s->next_picture_ptr;
if(!s->dropable)
s->next_picture_ptr= s->current_picture_ptr;
if(s->last_picture_ptr) copy_picture(&s->last_picture, s->last_picture_ptr);
if(s->next_picture_ptr) copy_picture(&s->next_picture, s->next_picture_ptr);
- if(s->pict_type != I_TYPE && (s->last_picture_ptr==NULL || s->last_picture_ptr->data[0]==NULL) && !s->dropable){
+ if(s->pict_type != FF_I_TYPE && (s->last_picture_ptr==NULL || s->last_picture_ptr->data[0]==NULL) && !s->dropable){
av_log(avctx, AV_LOG_ERROR, "warning: first frame is no keyframe\n");
- assert(s->pict_type != B_TYPE); //these should have been dropped if we don't have a reference
+ assert(s->pict_type != FF_B_TYPE); //these should have been dropped if we don't have a reference
goto alloc;
}
- assert(s->pict_type == I_TYPE || (s->last_picture_ptr && s->last_picture_ptr->data[0]));
+ assert(s->pict_type == FF_I_TYPE || (s->last_picture_ptr && s->last_picture_ptr->data[0]));
if(s->picture_structure!=PICT_FRAME && s->out_format != FMT_H264){
int i;
}
s->hurry_up= s->avctx->hurry_up;
- s->error_resilience= avctx->error_resilience;
+ s->error_recognition= avctx->error_recognition;
/* set dequantizer, we can't do it during init as it might change for mpeg4
and we can't do it in the header decode as init is not called for mpeg4 there yet */
}else
#endif
if(s->unrestricted_mv && s->current_picture.reference && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
- draw_edges(s->current_picture.data[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH );
- draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
- draw_edges(s->current_picture.data[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
+ s->dsp.draw_edges(s->current_picture.data[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH );
+ s->dsp.draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
+ s->dsp.draw_edges(s->current_picture.data[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
}
emms_c();
s->last_pict_type = s->pict_type;
s->last_lambda_for[s->pict_type]= s->current_picture_ptr->quality;
- if(s->pict_type!=B_TYPE){
+ if(s->pict_type!=FF_B_TYPE){
s->last_non_b_pict_type= s->pict_type;
}
#if 0
for(y= 0; y <= ey; y++){
x = (y*f)>>16;
fr= (y*f)&0xFFFF;
- buf[y*stride + x ]+= (color*(0x10000-fr))>>16;;
- buf[y*stride + x+1]+= (color* fr )>>16;;
+ buf[y*stride + x ]+= (color*(0x10000-fr))>>16;
+ buf[y*stride + x+1]+= (color* fr )>>16;
}
}
}
int mb_y;
uint8_t *ptr;
int i;
- int h_chroma_shift, v_chroma_shift;
+ int h_chroma_shift, v_chroma_shift, block_height;
const int width = s->avctx->width;
const int height= s->avctx->height;
const int mv_sample_log2= 4 - pict->motion_subsample_log2;
}
pict->type= FF_BUFFER_TYPE_COPY;
ptr= pict->data[0];
+ block_height = 16>>v_chroma_shift;
for(mb_y=0; mb_y<s->mb_height; mb_y++){
int mb_x;
if((s->avctx->debug&FF_DEBUG_VIS_QP) && pict->motion_val){
uint64_t c= (pict->qscale_table[mb_index]*128/31) * 0x0101010101010101ULL;
int y;
- for(y=0; y<8; y++){
- *(uint64_t*)(pict->data[1] + 8*mb_x + (8*mb_y + y)*pict->linesize[1])= c;
- *(uint64_t*)(pict->data[2] + 8*mb_x + (8*mb_y + y)*pict->linesize[2])= c;
+ for(y=0; y<block_height; y++){
+ *(uint64_t*)(pict->data[1] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[1])= c;
+ *(uint64_t*)(pict->data[2] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[2])= c;
}
}
if((s->avctx->debug&FF_DEBUG_VIS_MB_TYPE) && pict->motion_val){
u*= 0x0101010101010101ULL;
v*= 0x0101010101010101ULL;
- for(y=0; y<8; y++){
- *(uint64_t*)(pict->data[1] + 8*mb_x + (8*mb_y + y)*pict->linesize[1])= u;
- *(uint64_t*)(pict->data[2] + 8*mb_x + (8*mb_y + y)*pict->linesize[2])= v;
+ for(y=0; y<block_height; y++){
+ *(uint64_t*)(pict->data[1] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[1])= u;
+ *(uint64_t*)(pict->data[2] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[2])= v;
}
//segmentation
}
}
-/**
- * Copies a rectangular area of samples to a temporary buffer and replicates the boarder samples.
- * @param buf destination buffer
- * @param src source buffer
- * @param linesize number of bytes between 2 vertically adjacent samples in both the source and destination buffers
- * @param block_w width of block
- * @param block_h height of block
- * @param src_x x coordinate of the top left sample of the block in the source buffer
- * @param src_y y coordinate of the top left sample of the block in the source buffer
- * @param w width of the source buffer
- * @param h height of the source buffer
- */
-void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w, int block_h,
- int src_x, int src_y, int w, int h){
- int x, y;
- int start_y, start_x, end_y, end_x;
-
- if(src_y>= h){
- src+= (h-1-src_y)*linesize;
- src_y=h-1;
- }else if(src_y<=-block_h){
- src+= (1-block_h-src_y)*linesize;
- src_y=1-block_h;
- }
- if(src_x>= w){
- src+= (w-1-src_x);
- src_x=w-1;
- }else if(src_x<=-block_w){
- src+= (1-block_w-src_x);
- src_x=1-block_w;
- }
-
- start_y= FFMAX(0, -src_y);
- start_x= FFMAX(0, -src_x);
- end_y= FFMIN(block_h, h-src_y);
- end_x= FFMIN(block_w, w-src_x);
-
- // copy existing part
- for(y=start_y; y<end_y; y++){
- for(x=start_x; x<end_x; x++){
- buf[x + y*linesize]= src[x + y*linesize];
- }
- }
-
- //top
- for(y=0; y<start_y; y++){
- for(x=start_x; x<end_x; x++){
- buf[x + y*linesize]= buf[x + start_y*linesize];
- }
- }
-
- //bottom
- for(y=end_y; y<block_h; y++){
- for(x=start_x; x<end_x; x++){
- buf[x + y*linesize]= buf[x + (end_y-1)*linesize];
- }
- }
-
- for(y=0; y<block_h; y++){
- //left
- for(x=0; x<start_x; x++){
- buf[x + y*linesize]= buf[start_x + y*linesize];
- }
-
- //right
- for(x=end_x; x<block_w; x++){
- buf[x + y*linesize]= buf[end_x - 1 + y*linesize];
- }
- }
-}
-
static inline int hpel_motion_lowres(MpegEncContext *s,
uint8_t *dest, uint8_t *src,
int field_based, int field_select,
linesize = s->current_picture.linesize[0] << field_based;
uvlinesize = s->current_picture.linesize[1] << field_based;
- if(s->quarter_sample){ //FIXME obviously not perfect but qpel wont work in lowres anyway
+ if(s->quarter_sample){ //FIXME obviously not perfect but qpel will not work in lowres anyway
motion_x/=2;
motion_y/=2;
}
ref_picture, pix_op,
s->mv[dir][1][0], s->mv[dir][1][1], block_s);
} else {
- if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != B_TYPE && !s->first_field){
+ if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != FF_B_TYPE && !s->first_field){
ref_picture= s->current_picture_ptr->data;
}
for(i=0; i<2; i++){
uint8_t ** ref2picture;
- if(s->picture_structure == s->field_select[dir][i] + 1 || s->pict_type == B_TYPE || s->first_field){
+ if(s->picture_structure == s->field_select[dir][i] + 1 || s->pict_type == FF_B_TYPE || s->first_field){
ref2picture= ref_picture;
}else{
ref2picture= s->current_picture_ptr->data;
s->mv : motion vector
s->interlaced_dct : true if interlaced dct used (mpeg2)
*/
-static av_always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], int lowres_flag)
+static av_always_inline
+void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
+ int lowres_flag, int is_mpeg12)
{
int mb_x, mb_y;
const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
/* update DC predictors for P macroblocks */
if (!s->mb_intra) {
- if (s->h263_pred || s->h263_aic) {
+ if (!is_mpeg12 && (s->h263_pred || s->h263_aic)) {
if(s->mbintra_table[mb_xy])
ff_clean_intra_table_entries(s);
} else {
s->last_dc[2] = 128 << s->intra_dc_precision;
}
}
- else if (s->h263_pred || s->h263_aic)
+ else if (!is_mpeg12 && (s->h263_pred || s->h263_aic))
s->mbintra_table[mb_xy]=1;
- if ((s->flags&CODEC_FLAG_PSNR) || !(s->encoding && (s->intra_only || s->pict_type==B_TYPE) && s->avctx->mb_decision != FF_MB_DECISION_RD)) { //FIXME precalc
+ if ((s->flags&CODEC_FLAG_PSNR) || !(s->encoding && (s->intra_only || s->pict_type==FF_B_TYPE) && s->avctx->mb_decision != FF_MB_DECISION_RD)) { //FIXME precalc
uint8_t *dest_y, *dest_cb, *dest_cr;
int dct_linesize, dct_offset;
op_pixels_func (*op_pix)[4];
qpel_mc_func (*op_qpix)[16];
const int linesize= s->current_picture.linesize[0]; //not s->linesize as this would be wrong for field pics
const int uvlinesize= s->current_picture.linesize[1];
- const int readable= s->pict_type != B_TYPE || s->encoding || s->avctx->draw_horiz_band || lowres_flag;
+ const int readable= s->pict_type != FF_B_TYPE || s->encoding || s->avctx->draw_horiz_band || lowres_flag;
const int block_size= lowres_flag ? 8>>s->avctx->lowres : 8;
/* avoid copy if macroblock skipped in last frame too */
if (s->mb_skipped) {
s->mb_skipped= 0;
- assert(s->pict_type!=I_TYPE);
+ assert(s->pict_type!=FF_I_TYPE);
(*mbskip_ptr) ++; /* indicate that this time we skipped it */
if(*mbskip_ptr >99) *mbskip_ptr= 99;
}
}else{
op_qpix= s->me.qpel_put;
- if ((!s->no_rounding) || s->pict_type==B_TYPE){
+ if ((!s->no_rounding) || s->pict_type==FF_B_TYPE){
op_pix = s->dsp.put_pixels_tab;
}else{
op_pix = s->dsp.put_no_rnd_pixels_tab;
/* skip dequant / idct if we are really late ;) */
if(s->hurry_up>1) goto skip_idct;
if(s->avctx->skip_idct){
- if( (s->avctx->skip_idct >= AVDISCARD_NONREF && s->pict_type == B_TYPE)
- ||(s->avctx->skip_idct >= AVDISCARD_NONKEY && s->pict_type != I_TYPE)
+ if( (s->avctx->skip_idct >= AVDISCARD_NONREF && s->pict_type == FF_B_TYPE)
+ ||(s->avctx->skip_idct >= AVDISCARD_NONKEY && s->pict_type != FF_I_TYPE)
|| s->avctx->skip_idct >= AVDISCARD_ALL)
goto skip_idct;
}
add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale);
}
}
- } else if(s->codec_id != CODEC_ID_WMV2){
+ } else if(is_mpeg12 || (s->codec_id != CODEC_ID_WMV2)){
add_dct(s, block[0], 0, dest_y , dct_linesize);
add_dct(s, block[1], 1, dest_y + block_size, dct_linesize);
add_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize);
}
void MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){
- if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1);
- else MPV_decode_mb_internal(s, block, 0);
+#ifndef CONFIG_SMALL
+ if(s->out_format == FMT_MPEG1) {
+ if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 1);
+ else MPV_decode_mb_internal(s, block, 0, 1);
+ } else
+#endif
+ if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 0);
+ else MPV_decode_mb_internal(s, block, 0, 0);
}
/**
h= FFMIN(h, s->avctx->height - y);
- if(s->pict_type==B_TYPE || s->low_delay || (s->avctx->slice_flags&SLICE_FLAG_CODED_ORDER))
+ if(s->pict_type==FF_B_TYPE || s->low_delay || (s->avctx->slice_flags&SLICE_FLAG_CODED_ORDER))
src= (AVFrame*)s->current_picture_ptr;
else if(s->last_picture_ptr)
src= (AVFrame*)s->last_picture_ptr;
else
return;
- if(s->pict_type==B_TYPE && s->picture_structure == PICT_FRAME && s->out_format != FMT_H264){
+ if(s->pict_type==FF_B_TYPE && s->picture_structure == PICT_FRAME && s->out_format != FMT_H264){
offset[0]=
offset[1]=
offset[2]=
offset[3]= 0;
}else{
- offset[0]= y * s->linesize;;
+ offset[0]= y * s->linesize;
offset[1]=
offset[2]= (y >> s->chroma_y_shift) * s->uvlinesize;
offset[3]= 0;
s->dest[1] = s->current_picture.data[1] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
s->dest[2] = s->current_picture.data[2] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
- if(!(s->pict_type==B_TYPE && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME))
+ if(!(s->pict_type==FF_B_TYPE && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME))
{
s->dest[0] += s->mb_y * linesize << mb_size;
s->dest[1] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift);