diff options
Diffstat (limited to 'libavcodec/mpegvideo.c')
-rw-r--r-- | libavcodec/mpegvideo.c | 375 |
1 files changed, 167 insertions, 208 deletions
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index d1c42331c2..0383992975 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -5,20 +5,20 @@ * * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -420,12 +420,12 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base) // edge emu needs blocksize + filter length - 1 // (= 17x17 for halfpel / 21x21 for h264) FF_ALLOCZ_OR_GOTO(s->avctx, s->edge_emu_buffer, - (s->width + 64) * 2 * 21 * 2, fail); // (width + edge + align)*interlaced*MBsize*tolerance + (s->width + 95) * 2 * 21 * 4, fail); // (width + edge + align)*interlaced*MBsize*tolerance // FIXME should be linesize instead of s->width * 2 // but that is not known before get_buffer() FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad, - (s->width + 64) * 4 * 16 * 2 * sizeof(uint8_t), fail) + (s->width + 95) * 4 * 16 * 2 * sizeof(uint8_t), fail) s->me.temp = s->me.scratchpad; s->rd_scratchpad = s->me.scratchpad; s->b_scratchpad = s->me.scratchpad; @@ -529,7 +529,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, { MpegEncContext *s = dst->priv_data, *s1 = src->priv_data; - if (dst == src || !s1->context_initialized) + if (dst == src) return 0; // FIXME can parameters change on I-frames? @@ -538,12 +538,14 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, memcpy(s, s1, sizeof(MpegEncContext)); s->avctx = dst; - s->picture_range_start += MAX_PICTURE_COUNT; - s->picture_range_end += MAX_PICTURE_COUNT; s->bitstream_buffer = NULL; s->bitstream_buffer_size = s->allocated_bitstream_buffer_size = 0; - ff_MPV_common_init(s); + if (s1->context_initialized){ + s->picture_range_start += MAX_PICTURE_COUNT; + s->picture_range_end += MAX_PICTURE_COUNT; + ff_MPV_common_init(s); + } } s->avctx->coded_height = s1->avctx->coded_height; @@ -566,6 +568,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, // Error/bug resilience s->next_p_frame_damaged = s1->next_p_frame_damaged; s->workaround_bugs = s1->workaround_bugs; + s->padding_bug_score = s1->padding_bug_score; // MPEG4 timing info memcpy(&s->time_increment_bits, &s1->time_increment_bits, @@ -694,110 +697,83 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) s->flags = s->avctx->flags; s->flags2 = s->avctx->flags2; - if (s->width && s->height) { - s->mb_width = (s->width + 15) / 16; - s->mb_stride = s->mb_width + 1; - s->b8_stride = s->mb_width * 2 + 1; - s->b4_stride = s->mb_width * 4 + 1; - mb_array_size = s->mb_height * s->mb_stride; - mv_table_size = (s->mb_height + 2) * s->mb_stride + 1; + s->mb_width = (s->width + 15) / 16; + s->mb_stride = s->mb_width + 1; + s->b8_stride = s->mb_width * 2 + 1; + s->b4_stride = s->mb_width * 4 + 1; + mb_array_size = s->mb_height * s->mb_stride; + mv_table_size = (s->mb_height + 2) * s->mb_stride + 1; /* set chroma shifts */ avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift); - /* set default edge pos, will be overriden - * in decode_header if needed */ - s->h_edge_pos = s->mb_width * 16; - s->v_edge_pos = s->mb_height * 16; + /* set default edge pos, will be overriden in decode_header if needed */ + s->h_edge_pos = s->mb_width * 16; + s->v_edge_pos = s->mb_height * 16; - s->mb_num = s->mb_width * s->mb_height; + s->mb_num = s->mb_width * s->mb_height; - s->block_wrap[0] = - s->block_wrap[1] = - s->block_wrap[2] = - s->block_wrap[3] = s->b8_stride; - s->block_wrap[4] = - s->block_wrap[5] = s->mb_stride; + s->block_wrap[0] = + s->block_wrap[1] = + s->block_wrap[2] = + s->block_wrap[3] = s->b8_stride; + s->block_wrap[4] = + s->block_wrap[5] = s->mb_stride; - y_size = s->b8_stride * (2 * s->mb_height + 1); - c_size = s->mb_stride * (s->mb_height + 1); - yc_size = y_size + 2 * c_size; + y_size = s->b8_stride * (2 * s->mb_height + 1); + c_size = s->mb_stride * (s->mb_height + 1); + yc_size = y_size + 2 * c_size; - /* convert fourcc to upper case */ - s->codec_tag = avpriv_toupper4(s->avctx->codec_tag); + /* convert fourcc to upper case */ + s->codec_tag = avpriv_toupper4(s->avctx->codec_tag); + s->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag); - s->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag); + s->avctx->coded_frame = &s->current_picture.f; - s->avctx->coded_frame = &s->current_picture.f; + FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int), fail); // error ressilience code looks cleaner with this + for (y = 0; y < s->mb_height; y++) + for (x = 0; x < s->mb_width; x++) + s->mb_index2xy[x + y * s->mb_width] = x + y * s->mb_stride; - FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int), - fail); // error ressilience code looks cleaner with this - for (y = 0; y < s->mb_height; y++) - for (x = 0; x < s->mb_width; x++) - s->mb_index2xy[x + y * s->mb_width] = x + y * s->mb_stride; + s->mb_index2xy[s->mb_height * s->mb_width] = (s->mb_height - 1) * s->mb_stride + s->mb_width; // FIXME really needed? - s->mb_index2xy[s->mb_height * s->mb_width] = - (s->mb_height - 1) * s->mb_stride + s->mb_width; // FIXME really needed? + if (s->encoding) { + /* Allocate MV tables */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + s->p_mv_table = s->p_mv_table_base + s->mb_stride + 1; + s->b_forw_mv_table = s->b_forw_mv_table_base + s->mb_stride + 1; + s->b_back_mv_table = s->b_back_mv_table_base + s->mb_stride + 1; + s->b_bidir_forw_mv_table= s->b_bidir_forw_mv_table_base + s->mb_stride + 1; + s->b_bidir_back_mv_table= s->b_bidir_back_mv_table_base + s->mb_stride + 1; + s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1; + + if(s->msmpeg4_version){ + FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats, 2*2*(MAX_LEVEL+1)*(MAX_RUN+1)*2*sizeof(int), fail); + } + FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail); - if (s->encoding) { - /* Allocate MV tables */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - s->p_mv_table = s->p_mv_table_base + - s->mb_stride + 1; - s->b_forw_mv_table = s->b_forw_mv_table_base + - s->mb_stride + 1; - s->b_back_mv_table = s->b_back_mv_table_base + - s->mb_stride + 1; - s->b_bidir_forw_mv_table = s->b_bidir_forw_mv_table_base + - s->mb_stride + 1; - s->b_bidir_back_mv_table = s->b_bidir_back_mv_table_base + - s->mb_stride + 1; - s->b_direct_mv_table = s->b_direct_mv_table_base + - s->mb_stride + 1; - - if (s->msmpeg4_version) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats, - 2 * 2 * (MAX_LEVEL + 1) * - (MAX_RUN + 1) * 2 * sizeof(int), fail); - } - FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail); - - /* Allocate MB type table */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type, mb_array_size * - sizeof(uint16_t), fail); // needed for encoding - - FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * - sizeof(int), fail); - - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix, - 64 * 32 * sizeof(int), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix, - 64 * 32 * sizeof(int), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16, - 64 * 32 * 2 * sizeof(uint16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16, - 64 * 32 * 2 * sizeof(uint16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, - MAX_PICTURE_COUNT * sizeof(Picture *), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, - MAX_PICTURE_COUNT * sizeof(Picture *), fail); - - if (s->avctx->noise_reduction) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, - 2 * 64 * sizeof(uint16_t), fail); - } + /* Allocate MB type table */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type , mb_array_size * sizeof(uint16_t), fail) //needed for encoding + + FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail) + + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix , 64*32 * sizeof(int), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix , 64*32 * sizeof(int), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix , 64*32 * sizeof(int), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16 , 64*32*2 * sizeof(uint16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix16, 64*32*2 * sizeof(uint16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16 , 64*32*2 * sizeof(uint16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail) + + if(s->avctx->noise_reduction){ + FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, 2 * 64 * sizeof(uint16_t), fail) } } @@ -808,36 +784,22 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) avcodec_get_frame_defaults(&s->picture[i].f); } - if (s->width && s->height) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table, - mb_array_size * sizeof(uint8_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table, mb_array_size*sizeof(uint8_t), fail) - if (s->codec_id == CODEC_ID_MPEG4 || - (s->flags & CODEC_FLAG_INTERLACED_ME)) { + if(s->codec_id==CODEC_ID_MPEG4 || (s->flags & CODEC_FLAG_INTERLACED_ME)){ /* interlaced direct mode decoding tables */ for (i = 0; i < 2; i++) { int j, k; for (j = 0; j < 2; j++) { for (k = 0; k < 2; k++) { - FF_ALLOCZ_OR_GOTO(s->avctx, - s->b_field_mv_table_base[i][j][k], - mv_table_size * 2 * sizeof(int16_t), - fail); - s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] + - s->mb_stride + 1; + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_mv_table_base[i][j][k], mv_table_size * 2 * sizeof(int16_t), fail) + s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] + s->mb_stride + 1; } - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], - mb_array_size * 2 * sizeof(uint8_t), - fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], - mv_table_size * 2 * sizeof(int16_t), - fail); - s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] - + s->mb_stride + 1; + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], mb_array_size * 2 * sizeof(uint8_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], mv_table_size * 2 * sizeof(int16_t), fail) + s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + s->mb_stride + 1; } - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], - mb_array_size * 2 * sizeof(uint8_t), - fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], mb_array_size * 2 * sizeof(uint8_t), fail) } } if (s->out_format == FMT_H263) { @@ -846,17 +808,14 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) s->coded_block = s->coded_block_base + s->b8_stride + 1; /* cbp, ac_pred, pred_dir */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table, - mb_array_size * sizeof(uint8_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, - mb_array_size * sizeof(uint8_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table , mb_array_size * sizeof(uint8_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, mb_array_size * sizeof(uint8_t), fail); } if (s->h263_pred || s->h263_plus || !s->encoding) { /* dc values */ // MN: we need these for error resilience of intra-frames - FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, - yc_size * sizeof(int16_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, yc_size * sizeof(int16_t), fail); s->dc_val[0] = s->dc_val_base + s->b8_stride + 1; s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1; s->dc_val[2] = s->dc_val[1] + c_size; @@ -873,21 +832,11 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) // Note the + 1 is for a quicker mpeg4 slice_end detection 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 * 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; + s->context_initialized = 1; + s->thread_context[0] = s; - if (s->width && s->height) { +// if (s->width && s->height) { if (nb_slices > 1) { for (i = 1; i < nb_slices; i++) { s->thread_context[i] = av_malloc(sizeof(MpegEncContext)); @@ -909,7 +858,7 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) s->end_mb_y = s->mb_height; } s->slice_context_count = nb_slices; - } +// } return 0; fail: @@ -976,6 +925,10 @@ void ff_MPV_common_end(MpegEncContext *s) av_freep(&s->error_status_table); av_freep(&s->mb_index2xy); av_freep(&s->lambda_table); + if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix); + if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16); + s->q_chroma_intra_matrix= NULL; + s->q_chroma_intra_matrix16= NULL; av_freep(&s->q_intra_matrix); av_freep(&s->q_inter_matrix); av_freep(&s->q_intra_matrix16); @@ -1130,7 +1083,21 @@ int ff_find_unused_picture(MpegEncContext *s, int shared) } } - return AVERROR_INVALIDDATA; + av_log(s->avctx, AV_LOG_FATAL, + "Internal error, picture buffer overflow\n"); + /* We could return -1, but the codec would crash trying to draw into a + * non-existing frame anyway. This is safer than waiting for a random crash. + * Also the return of this is never useful, an encoder must only allocate + * as much as allowed in the specification. This has no relationship to how + * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large + * enough for such valid streams). + * Plus, a decoder has to check stream validity and remove frames if too + * many reference frames are around. Waiting for "OOM" is not correct at + * all. Similarly, missing reference frames have to be replaced by + * interpolated/MC frames, anything else is a bug in the codec ... + */ + abort(); + return -1; } static void update_noise_reduction(MpegEncContext *s) @@ -1167,6 +1134,11 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) assert(s->last_picture_ptr == NULL || s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3); + if (!ff_thread_can_start_frame(avctx)) { + av_log(avctx, AV_LOG_ERROR, "Attempt to start a frame outside SETUP state\n"); + return -1; + } + /* mark & release old frames */ if (s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3) { if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr && @@ -1203,6 +1175,8 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) pic = s->current_picture_ptr; } else { i = ff_find_unused_picture(s, 0); + if (i < 0) + return i; pic = &s->picture[i]; } @@ -1266,11 +1240,20 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) /* Allocate a dummy frame */ i = ff_find_unused_picture(s, 0); + if (i < 0) + return i; s->last_picture_ptr = &s->picture[i]; + s->last_picture_ptr->f.key_frame = 0; if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) { s->last_picture_ptr = NULL; return -1; } + + if(s->codec_id == CODEC_ID_FLV1 || s->codec_id == CODEC_ID_H263){ + for(i=0; i<avctx->height; i++) + memset(s->last_picture_ptr->f.data[0] + s->last_picture_ptr->f.linesize[0]*i, 16, avctx->width); + } + ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 0); ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 1); s->last_picture_ptr->f.reference = 3; @@ -1280,7 +1263,10 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->pict_type == AV_PICTURE_TYPE_B) { /* Allocate a dummy frame */ i = ff_find_unused_picture(s, 0); + if (i < 0) + return i; s->next_picture_ptr = &s->picture[i]; + s->next_picture_ptr->f.key_frame = 0; if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) { s->next_picture_ptr = NULL; return -1; @@ -1356,7 +1342,7 @@ void ff_MPV_frame_end(MpegEncContext *s) // just to make sure that all data is rendered. if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) { ff_xvmc_field_end(s); - } else if ((s->error_count || s->encoding) && + } else if((s->error_count || s->encoding || !(s->avctx->codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND)) && !s->avctx->hwaccel && !(s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) && s->unrestricted_mv && @@ -1365,15 +1351,15 @@ void ff_MPV_frame_end(MpegEncContext *s) !(s->flags & CODEC_FLAG_EMU_EDGE)) { int hshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_w; int vshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_h; - s->dsp.draw_edges(s->current_picture.f.data[0], s->linesize, + s->dsp.draw_edges(s->current_picture.f.data[0], s->current_picture.f.linesize[0], s->h_edge_pos, s->v_edge_pos, EDGE_WIDTH, EDGE_WIDTH, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(s->current_picture.f.data[1], s->uvlinesize, + s->dsp.draw_edges(s->current_picture.f.data[1], s->current_picture.f.linesize[1], s->h_edge_pos >> hshift, s->v_edge_pos >> vshift, EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(s->current_picture.f.data[2], s->uvlinesize, + s->dsp.draw_edges(s->current_picture.f.data[2], s->current_picture.f.linesize[2], s->h_edge_pos >> hshift, s->v_edge_pos >> vshift, EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, EDGE_TOP | EDGE_BOTTOM); @@ -1446,7 +1432,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, buf += sx + sy * stride; ex -= sx; f = ((ey - sy) << 16) / ex; - for (x = 0; x = ex; x++) { + for(x= 0; x <= ex; x++){ y = (x * f) >> 16; fr = (x * f) & 0xFFFF; buf[y * stride + x] += (color * (0x10000 - fr)) >> 16; @@ -1460,12 +1446,12 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, buf += sx + sy * stride; ey -= sy; if (ey) - f = ((ex - sx) << 16) / ey; + f = ((ex - sx) << 16) / ey; else f = 0; - for (y = 0; y = ey; y++) { - x = (y * f) >> 16; - fr = (y * f) & 0xFFFF; + 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; } @@ -1518,27 +1504,8 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) if (s->avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) { int x,y; - av_log(s->avctx,AV_LOG_DEBUG,"New frame, type: "); - switch (pict->pict_type) { - case AV_PICTURE_TYPE_I: - av_log(s->avctx,AV_LOG_DEBUG,"I\n"); - break; - case AV_PICTURE_TYPE_P: - av_log(s->avctx,AV_LOG_DEBUG,"P\n"); - break; - case AV_PICTURE_TYPE_B: - av_log(s->avctx,AV_LOG_DEBUG,"B\n"); - break; - case AV_PICTURE_TYPE_S: - av_log(s->avctx,AV_LOG_DEBUG,"S\n"); - break; - case AV_PICTURE_TYPE_SI: - av_log(s->avctx,AV_LOG_DEBUG,"SI\n"); - break; - case AV_PICTURE_TYPE_SP: - av_log(s->avctx,AV_LOG_DEBUG,"SP\n"); - break; - } + av_log(s->avctx, AV_LOG_DEBUG, "New frame, type: %c\n", + av_get_picture_type_char(pict->pict_type)); for (y = 0; y < s->mb_height; y++) { for (x = 0; x < s->mb_width; x++) { if (s->avctx->debug & FF_DEBUG_SKIP) { @@ -1622,12 +1589,14 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); for (i = 0; i < 3; i++) { - memcpy(s->visualization_buffer[i], pict->data[i], - (i == 0) ? pict->linesize[i] * height: - pict->linesize[i] * height >> v_chroma_shift); + size_t size= (i == 0) ? pict->linesize[i] * height: + pict->linesize[i] * height >> v_chroma_shift; + s->visualization_buffer[i]= av_realloc(s->visualization_buffer[i], size); + memcpy(s->visualization_buffer[i], pict->data[i], size); pict->data[i] = s->visualization_buffer[i]; } pict->type = FF_BUFFER_TYPE_COPY; + pict->opaque= NULL; ptr = pict->data[0]; block_height = 16 >> v_chroma_shift; @@ -1705,11 +1674,11 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) height, s->linesize, 100); } } else { - int sx = mb_x * 16 + 8; - int sy = mb_y * 16 + 8; - int xy = (mb_x + mb_y * mv_stride) << mv_sample_log2; - int mx = pict->motion_val[direction][xy][0] >> shift + sx; - int my = pict->motion_val[direction][xy][1] >> shift + sy; + int sx= mb_x * 16 + 8; + int sy= mb_y * 16 + 8; + int xy= (mb_x + mb_y * mv_stride) << mv_sample_log2; + int mx= (pict->motion_val[direction][xy][0]>>shift) + sx; + int my= (pict->motion_val[direction][xy][1]>>shift) + sy; draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100); } } @@ -1969,8 +1938,8 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], qpel_mc_func (*op_qpix)[16]; const int linesize = s->current_picture.f.linesize[0]; //not s->linesize as this would be wrong for field pics const int uvlinesize = s->current_picture.f.linesize[1]; - const int readable= s->pict_type != AV_PICTURE_TYPE_B || s->encoding || s->avctx->draw_horiz_band; - const int block_size = 8; + const int readable= s->pict_type != AV_PICTURE_TYPE_B || s->encoding || s->avctx->draw_horiz_band || s->avctx->lowres; + const int block_size= 8 >> s->avctx->lowres; /* avoid copy if macroblock skipped in last frame too */ /* skip only during decoding as we might trash the buffers during encoding a bit */ @@ -2047,9 +2016,9 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], if(s->encoding || !( s->msmpeg4_version || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO || (s->codec_id==CODEC_ID_MPEG4 && !s->mpeg_quant))){ add_dequant_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); - add_dequant_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); + add_dequant_dct(s, block[1], 1, dest_y + 8 , dct_linesize, s->qscale); add_dequant_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); - add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); + add_dequant_dct(s, block[3], 3, dest_y + dct_offset + 8 , dct_linesize, s->qscale); if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if (s->chroma_y_shift){ @@ -2066,9 +2035,9 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], } } 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[1], 1, dest_y + 8 , dct_linesize); add_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize); - add_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize); + add_dct(s, block[3], 3, dest_y + dct_offset + 8 , dct_linesize); if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if(s->chroma_y_shift){//Chroma420 @@ -2077,7 +2046,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], }else{ //chroma422 dct_linesize = uvlinesize << s->interlaced_dct; - dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize * 8; + dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*8; add_dct(s, block[4], 4, dest_cb, dct_linesize); add_dct(s, block[5], 5, dest_cr, dct_linesize); @@ -2118,9 +2087,9 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], } }else{ s->dsp.idct_put(dest_y , dct_linesize, block[0]); - s->dsp.idct_put(dest_y + block_size, dct_linesize, block[1]); + s->dsp.idct_put(dest_y + 8 , dct_linesize, block[1]); s->dsp.idct_put(dest_y + dct_offset , dct_linesize, block[2]); - s->dsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]); + s->dsp.idct_put(dest_y + dct_offset + 8 , dct_linesize, block[3]); if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if(s->chroma_y_shift){ @@ -2129,7 +2098,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], }else{ dct_linesize = uvlinesize << s->interlaced_dct; - dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize * 8; + dct_offset = s->interlaced_dct? uvlinesize : uvlinesize*8; s->dsp.idct_put(dest_cb, dct_linesize, block[4]); s->dsp.idct_put(dest_cr, dct_linesize, block[5]); @@ -2235,7 +2204,7 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename const int linesize = s->current_picture.f.linesize[0]; //not s->linesize as this would be wrong for field pics const int uvlinesize = s->current_picture.f.linesize[1]; - const int mb_size= 4; + const int mb_size= 4 - s->avctx->lowres; s->block_index[0]= s->b8_stride*(s->mb_y*2 ) - 2 + s->mb_x*2; s->block_index[1]= s->b8_stride*(s->mb_y*2 ) - 1 + s->mb_x*2; @@ -2280,6 +2249,7 @@ void ff_mpeg_flush(AVCodecContext *avctx){ s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL; s->mb_x= s->mb_y= 0; + s->closed_gop= 0; s->parse_context.state= -1; s->parse_context.frame_start_found= 0; @@ -2299,10 +2269,7 @@ static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s, nCoeffs= s->block_last_index[n]; - if (n < 4) - block[0] = block[0] * s->y_dc_scale; - else - block[0] = block[0] * s->c_dc_scale; + block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale; /* XXX: only mpeg1 */ quant_matrix = s->intra_matrix; for(i=1;i<=nCoeffs;i++) { @@ -2361,10 +2328,7 @@ static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s, if(s->alternate_scan) nCoeffs= 63; else nCoeffs= s->block_last_index[n]; - if (n < 4) - block[0] = block[0] * s->y_dc_scale; - else - block[0] = block[0] * s->c_dc_scale; + block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale; quant_matrix = s->intra_matrix; for(i=1;i<=nCoeffs;i++) { int j= s->intra_scantable.permutated[i]; @@ -2392,10 +2356,8 @@ static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s, if(s->alternate_scan) nCoeffs= 63; else nCoeffs= s->block_last_index[n]; - if (n < 4) - block[0] = block[0] * s->y_dc_scale; - else - block[0] = block[0] * s->c_dc_scale; + block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale; + sum += block[0]; quant_matrix = s->intra_matrix; for(i=1;i<=nCoeffs;i++) { int j= s->intra_scantable.permutated[i]; @@ -2457,10 +2419,7 @@ static void dct_unquantize_h263_intra_c(MpegEncContext *s, qmul = qscale << 1; if (!s->h263_aic) { - if (n < 4) - block[0] = block[0] * s->y_dc_scale; - else - block[0] = block[0] * s->c_dc_scale; + block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale; qadd = (qscale - 1) | 1; }else{ qadd = 0; |