2001-07-22 17:18:56 +03:00
|
|
|
/*
|
|
|
|
* The simplest mpeg encoder (well, it was the simplest!)
|
2009-01-19 17:46:40 +02:00
|
|
|
* Copyright (c) 2000,2001 Fabrice Bellard
|
2004-01-10 18:04:55 +02:00
|
|
|
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
2001-07-22 17:18:56 +03:00
|
|
|
*
|
2007-07-05 13:37:29 +03:00
|
|
|
* 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
|
|
|
|
*
|
2006-10-07 18:30:46 +03:00
|
|
|
* This file is part of FFmpeg.
|
|
|
|
*
|
|
|
|
* FFmpeg is free software; you can redistribute it and/or
|
2002-05-26 01:45:33 +03:00
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
2006-10-07 18:30:46 +03:00
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2001-07-22 17:18:56 +03:00
|
|
|
*
|
2006-10-07 18:30:46 +03:00
|
|
|
* FFmpeg is distributed in the hope that it will be useful,
|
2001-07-22 17:18:56 +03:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2002-05-26 01:45:33 +03:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2001-07-22 17:18:56 +03:00
|
|
|
*
|
2002-05-26 01:45:33 +03:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2006-10-07 18:30:46 +03:00
|
|
|
* License along with FFmpeg; if not, write to the Free Software
|
2006-01-13 00:43:26 +02:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2001-07-22 17:18:56 +03:00
|
|
|
*/
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2003-03-06 13:32:04 +02:00
|
|
|
/**
|
2010-04-20 17:45:34 +03:00
|
|
|
* @file
|
2003-03-06 13:32:04 +02:00
|
|
|
* The simplest mpeg encoder (well, it was the simplest!).
|
2005-12-17 20:14:38 +02:00
|
|
|
*/
|
|
|
|
|
2013-02-01 12:31:59 +03:00
|
|
|
#include "libavutil/attributes.h"
|
2012-11-21 23:34:46 +03:00
|
|
|
#include "libavutil/avassert.h"
|
2011-02-07 15:37:08 +02:00
|
|
|
#include "libavutil/imgutils.h"
|
2013-11-05 10:16:31 +03:00
|
|
|
#include "libavutil/internal.h"
|
2014-07-16 17:42:42 +03:00
|
|
|
#include "libavutil/motion_vector.h"
|
2020-03-10 12:45:55 +02:00
|
|
|
#include "libavutil/video_enc_params.h"
|
|
|
|
|
2001-07-22 17:18:56 +03:00
|
|
|
#include "avcodec.h"
|
2014-01-14 12:33:47 +03:00
|
|
|
#include "blockdsp.h"
|
2013-02-07 15:09:35 +03:00
|
|
|
#include "h264chroma.h"
|
2014-01-24 13:55:16 +03:00
|
|
|
#include "idctdsp.h"
|
2010-05-18 22:16:40 +03:00
|
|
|
#include "internal.h"
|
2012-10-11 02:16:05 +03:00
|
|
|
#include "mathops.h"
|
2015-06-10 15:29:04 +02:00
|
|
|
#include "mpeg_er.h"
|
2014-02-28 15:40:54 +03:00
|
|
|
#include "mpegutils.h"
|
2001-07-22 17:18:56 +03:00
|
|
|
#include "mpegvideo.h"
|
2015-05-29 20:44:03 +02:00
|
|
|
#include "mpegvideodata.h"
|
2007-05-19 01:42:49 +03:00
|
|
|
#include "mjpegenc.h"
|
2007-05-10 16:11:36 +03:00
|
|
|
#include "msmpeg4.h"
|
2014-01-08 16:00:10 +03:00
|
|
|
#include "qpeldsp.h"
|
2011-03-22 23:36:57 +02:00
|
|
|
#include "thread.h"
|
2015-05-29 20:44:01 +02:00
|
|
|
#include "wmv2.h"
|
2004-05-18 20:09:46 +03:00
|
|
|
#include <limits.h>
|
2001-07-22 17:18:56 +03:00
|
|
|
|
2013-12-03 09:52:33 +03:00
|
|
|
static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
|
|
|
|
int16_t *block, int n, int qscale)
|
|
|
|
{
|
|
|
|
int i, level, nCoeffs;
|
|
|
|
const uint16_t *quant_matrix;
|
|
|
|
|
|
|
|
nCoeffs= s->block_last_index[n];
|
|
|
|
|
2014-01-04 05:03:02 +03:00
|
|
|
block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
|
2016-04-27 19:45:23 +02:00
|
|
|
/* XXX: only MPEG-1 */
|
2013-12-03 09:52:33 +03:00
|
|
|
quant_matrix = s->intra_matrix;
|
|
|
|
for(i=1;i<=nCoeffs;i++) {
|
|
|
|
int j= s->intra_scantable.permutated[i];
|
|
|
|
level = block[j];
|
|
|
|
if (level) {
|
|
|
|
if (level < 0) {
|
|
|
|
level = -level;
|
|
|
|
level = (int)(level * qscale * quant_matrix[j]) >> 3;
|
|
|
|
level = (level - 1) | 1;
|
|
|
|
level = -level;
|
|
|
|
} else {
|
|
|
|
level = (int)(level * qscale * quant_matrix[j]) >> 3;
|
|
|
|
level = (level - 1) | 1;
|
|
|
|
}
|
|
|
|
block[j] = level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
|
|
|
|
int16_t *block, int n, int qscale)
|
|
|
|
{
|
|
|
|
int i, level, nCoeffs;
|
|
|
|
const uint16_t *quant_matrix;
|
|
|
|
|
|
|
|
nCoeffs= s->block_last_index[n];
|
|
|
|
|
|
|
|
quant_matrix = s->inter_matrix;
|
|
|
|
for(i=0; i<=nCoeffs; i++) {
|
|
|
|
int j= s->intra_scantable.permutated[i];
|
|
|
|
level = block[j];
|
|
|
|
if (level) {
|
|
|
|
if (level < 0) {
|
|
|
|
level = -level;
|
|
|
|
level = (((level << 1) + 1) * qscale *
|
|
|
|
((int) (quant_matrix[j]))) >> 4;
|
|
|
|
level = (level - 1) | 1;
|
|
|
|
level = -level;
|
|
|
|
} else {
|
|
|
|
level = (((level << 1) + 1) * qscale *
|
|
|
|
((int) (quant_matrix[j]))) >> 4;
|
|
|
|
level = (level - 1) | 1;
|
|
|
|
}
|
|
|
|
block[j] = level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
|
|
|
|
int16_t *block, int n, int qscale)
|
|
|
|
{
|
|
|
|
int i, level, nCoeffs;
|
|
|
|
const uint16_t *quant_matrix;
|
|
|
|
|
2015-09-18 00:37:28 +02:00
|
|
|
if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
|
|
|
|
else qscale <<= 1;
|
2015-09-17 23:47:06 +02:00
|
|
|
|
2013-12-03 09:52:33 +03:00
|
|
|
if(s->alternate_scan) nCoeffs= 63;
|
|
|
|
else nCoeffs= s->block_last_index[n];
|
|
|
|
|
2014-01-04 05:03:02 +03:00
|
|
|
block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
|
2013-12-03 09:52:33 +03:00
|
|
|
quant_matrix = s->intra_matrix;
|
|
|
|
for(i=1;i<=nCoeffs;i++) {
|
|
|
|
int j= s->intra_scantable.permutated[i];
|
|
|
|
level = block[j];
|
|
|
|
if (level) {
|
|
|
|
if (level < 0) {
|
|
|
|
level = -level;
|
2015-09-17 23:47:06 +02:00
|
|
|
level = (int)(level * qscale * quant_matrix[j]) >> 4;
|
2013-12-03 09:52:33 +03:00
|
|
|
level = -level;
|
|
|
|
} else {
|
2015-09-17 23:47:06 +02:00
|
|
|
level = (int)(level * qscale * quant_matrix[j]) >> 4;
|
2013-12-03 09:52:33 +03:00
|
|
|
}
|
|
|
|
block[j] = level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
|
|
|
|
int16_t *block, int n, int qscale)
|
|
|
|
{
|
|
|
|
int i, level, nCoeffs;
|
|
|
|
const uint16_t *quant_matrix;
|
|
|
|
int sum=-1;
|
|
|
|
|
2015-09-18 00:37:28 +02:00
|
|
|
if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
|
|
|
|
else qscale <<= 1;
|
2015-09-17 23:47:06 +02:00
|
|
|
|
2013-12-03 09:52:33 +03:00
|
|
|
if(s->alternate_scan) nCoeffs= 63;
|
|
|
|
else nCoeffs= s->block_last_index[n];
|
|
|
|
|
2014-01-04 05:03:02 +03:00
|
|
|
block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
|
|
|
|
sum += block[0];
|
2013-12-03 09:52:33 +03:00
|
|
|
quant_matrix = s->intra_matrix;
|
|
|
|
for(i=1;i<=nCoeffs;i++) {
|
|
|
|
int j= s->intra_scantable.permutated[i];
|
|
|
|
level = block[j];
|
|
|
|
if (level) {
|
|
|
|
if (level < 0) {
|
|
|
|
level = -level;
|
2015-09-17 23:47:06 +02:00
|
|
|
level = (int)(level * qscale * quant_matrix[j]) >> 4;
|
2013-12-03 09:52:33 +03:00
|
|
|
level = -level;
|
|
|
|
} else {
|
2015-09-17 23:47:06 +02:00
|
|
|
level = (int)(level * qscale * quant_matrix[j]) >> 4;
|
2013-12-03 09:52:33 +03:00
|
|
|
}
|
|
|
|
block[j] = level;
|
|
|
|
sum+=level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
block[63]^=sum&1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
|
|
|
|
int16_t *block, int n, int qscale)
|
|
|
|
{
|
|
|
|
int i, level, nCoeffs;
|
|
|
|
const uint16_t *quant_matrix;
|
|
|
|
int sum=-1;
|
|
|
|
|
2015-09-18 00:37:28 +02:00
|
|
|
if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
|
|
|
|
else qscale <<= 1;
|
2015-09-17 23:47:06 +02:00
|
|
|
|
2013-12-03 09:52:33 +03:00
|
|
|
if(s->alternate_scan) nCoeffs= 63;
|
|
|
|
else nCoeffs= s->block_last_index[n];
|
|
|
|
|
|
|
|
quant_matrix = s->inter_matrix;
|
|
|
|
for(i=0; i<=nCoeffs; i++) {
|
|
|
|
int j= s->intra_scantable.permutated[i];
|
|
|
|
level = block[j];
|
|
|
|
if (level) {
|
|
|
|
if (level < 0) {
|
|
|
|
level = -level;
|
|
|
|
level = (((level << 1) + 1) * qscale *
|
2015-09-17 23:47:06 +02:00
|
|
|
((int) (quant_matrix[j]))) >> 5;
|
2013-12-03 09:52:33 +03:00
|
|
|
level = -level;
|
|
|
|
} else {
|
|
|
|
level = (((level << 1) + 1) * qscale *
|
2015-09-17 23:47:06 +02:00
|
|
|
((int) (quant_matrix[j]))) >> 5;
|
2013-12-03 09:52:33 +03:00
|
|
|
}
|
|
|
|
block[j] = level;
|
|
|
|
sum+=level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
block[63]^=sum&1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dct_unquantize_h263_intra_c(MpegEncContext *s,
|
|
|
|
int16_t *block, int n, int qscale)
|
|
|
|
{
|
|
|
|
int i, level, qmul, qadd;
|
|
|
|
int nCoeffs;
|
|
|
|
|
2014-01-04 05:03:02 +03:00
|
|
|
av_assert2(s->block_last_index[n]>=0 || s->h263_aic);
|
2013-12-03 09:52:33 +03:00
|
|
|
|
|
|
|
qmul = qscale << 1;
|
|
|
|
|
|
|
|
if (!s->h263_aic) {
|
2014-01-04 05:03:02 +03:00
|
|
|
block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
|
2013-12-03 09:52:33 +03:00
|
|
|
qadd = (qscale - 1) | 1;
|
|
|
|
}else{
|
|
|
|
qadd = 0;
|
|
|
|
}
|
|
|
|
if(s->ac_pred)
|
|
|
|
nCoeffs=63;
|
|
|
|
else
|
2017-06-20 00:37:40 +02:00
|
|
|
nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
|
2013-12-03 09:52:33 +03:00
|
|
|
|
|
|
|
for(i=1; i<=nCoeffs; i++) {
|
|
|
|
level = block[i];
|
|
|
|
if (level) {
|
|
|
|
if (level < 0) {
|
|
|
|
level = level * qmul - qadd;
|
|
|
|
} else {
|
|
|
|
level = level * qmul + qadd;
|
|
|
|
}
|
|
|
|
block[i] = level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dct_unquantize_h263_inter_c(MpegEncContext *s,
|
|
|
|
int16_t *block, int n, int qscale)
|
|
|
|
{
|
|
|
|
int i, level, qmul, qadd;
|
|
|
|
int nCoeffs;
|
|
|
|
|
2014-01-04 05:03:02 +03:00
|
|
|
av_assert2(s->block_last_index[n]>=0);
|
2013-12-03 09:52:33 +03:00
|
|
|
|
|
|
|
qadd = (qscale - 1) | 1;
|
|
|
|
qmul = qscale << 1;
|
|
|
|
|
|
|
|
nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
|
|
|
|
|
|
|
|
for(i=0; i<=nCoeffs; i++) {
|
|
|
|
level = block[i];
|
|
|
|
if (level) {
|
|
|
|
if (level < 0) {
|
|
|
|
level = level * qmul - qadd;
|
|
|
|
} else {
|
|
|
|
level = level * qmul + qadd;
|
|
|
|
}
|
|
|
|
block[i] = level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-02 22:42:07 +03:00
|
|
|
|
2014-05-02 18:12:26 +03:00
|
|
|
static void gray16(uint8_t *dst, const uint8_t *src, ptrdiff_t linesize, int h)
|
2014-05-02 16:57:59 +03:00
|
|
|
{
|
|
|
|
while(h--)
|
|
|
|
memset(dst + h*linesize, 128, 16);
|
|
|
|
}
|
|
|
|
|
2014-05-02 18:12:26 +03:00
|
|
|
static void gray8(uint8_t *dst, const uint8_t *src, ptrdiff_t linesize, int h)
|
2014-05-02 16:57:59 +03:00
|
|
|
{
|
|
|
|
while(h--)
|
|
|
|
memset(dst + h*linesize, 128, 8);
|
|
|
|
}
|
|
|
|
|
2002-10-04 23:59:29 +03:00
|
|
|
/* init common dct for both encoder and decoder */
|
2014-08-08 18:11:20 +03:00
|
|
|
static av_cold int dct_init(MpegEncContext *s)
|
2001-07-22 17:18:56 +03:00
|
|
|
{
|
2014-01-14 12:33:47 +03:00
|
|
|
ff_blockdsp_init(&s->bdsp, s->avctx);
|
2013-02-07 15:09:35 +03:00
|
|
|
ff_h264chroma_init(&s->h264chroma, 8); //for lowres
|
2013-03-10 23:55:07 +03:00
|
|
|
ff_hpeldsp_init(&s->hdsp, s->avctx->flags);
|
2014-01-24 12:41:12 +03:00
|
|
|
ff_mpegvideodsp_init(&s->mdsp);
|
2012-12-26 02:24:21 +03:00
|
|
|
ff_videodsp_init(&s->vdsp, s->avctx->bits_per_raw_sample);
|
2011-07-25 17:51:36 +03:00
|
|
|
|
2014-05-02 16:57:59 +03:00
|
|
|
if (s->avctx->debug & FF_DEBUG_NOMC) {
|
|
|
|
int i;
|
|
|
|
for (i=0; i<4; i++) {
|
|
|
|
s->hdsp.avg_pixels_tab[0][i] = gray16;
|
|
|
|
s->hdsp.put_pixels_tab[0][i] = gray16;
|
|
|
|
s->hdsp.put_no_rnd_pixels_tab[0][i] = gray16;
|
|
|
|
|
|
|
|
s->hdsp.avg_pixels_tab[1][i] = gray8;
|
|
|
|
s->hdsp.put_pixels_tab[1][i] = gray8;
|
|
|
|
s->hdsp.put_no_rnd_pixels_tab[1][i] = gray8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-12-14 04:57:00 +02:00
|
|
|
s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;
|
|
|
|
s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c;
|
|
|
|
s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c;
|
|
|
|
s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c;
|
|
|
|
s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c;
|
2015-06-29 21:59:37 +02:00
|
|
|
if (s->avctx->flags & AV_CODEC_FLAG_BITEXACT)
|
2006-04-28 20:03:52 +03:00
|
|
|
s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;
|
2003-12-14 04:57:00 +02:00
|
|
|
s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;
|
2003-03-03 16:54:00 +02:00
|
|
|
|
2014-05-17 07:21:10 +03:00
|
|
|
if (HAVE_INTRINSICS_NEON)
|
2014-08-10 18:25:12 +03:00
|
|
|
ff_mpv_common_init_neon(s);
|
2014-05-17 07:21:10 +03:00
|
|
|
|
2013-08-20 19:25:04 +03:00
|
|
|
if (ARCH_ALPHA)
|
2014-08-15 21:00:34 +03:00
|
|
|
ff_mpv_common_init_axp(s);
|
2013-08-20 19:25:04 +03:00
|
|
|
if (ARCH_ARM)
|
2014-08-10 18:25:12 +03:00
|
|
|
ff_mpv_common_init_arm(s);
|
2013-08-20 19:25:04 +03:00
|
|
|
if (ARCH_PPC)
|
2014-08-10 18:25:12 +03:00
|
|
|
ff_mpv_common_init_ppc(s);
|
2013-08-20 19:25:04 +03:00
|
|
|
if (ARCH_X86)
|
2014-08-10 18:25:12 +03:00
|
|
|
ff_mpv_common_init_x86(s);
|
2015-06-29 17:27:12 +02:00
|
|
|
if (ARCH_MIPS)
|
|
|
|
ff_mpv_common_init_mips(s);
|
2002-10-06 18:27:01 +03:00
|
|
|
|
2014-08-08 18:11:20 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
av_cold void ff_mpv_idct_init(MpegEncContext *s)
|
|
|
|
{
|
2018-05-28 21:19:08 +02:00
|
|
|
if (s->codec_id == AV_CODEC_ID_MPEG4)
|
|
|
|
s->idsp.mpeg4_studio_profile = s->studio_profile;
|
2014-08-08 18:11:20 +03:00
|
|
|
ff_idctdsp_init(&s->idsp, s->avctx);
|
|
|
|
|
2002-09-30 01:44:22 +03:00
|
|
|
/* load & permutate scantables
|
2011-11-30 23:55:45 +03:00
|
|
|
* note: only wmv uses different ones
|
|
|
|
*/
|
|
|
|
if (s->alternate_scan) {
|
2014-01-24 13:55:16 +03:00
|
|
|
ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
|
|
|
|
ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
|
2011-11-30 23:55:45 +03:00
|
|
|
} else {
|
2014-01-24 13:55:16 +03:00
|
|
|
ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
|
|
|
|
ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
|
2003-12-30 18:07:57 +02:00
|
|
|
}
|
2014-01-24 13:55:16 +03:00
|
|
|
ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
|
|
|
|
ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
|
2002-10-04 23:59:29 +03:00
|
|
|
}
|
|
|
|
|
2020-03-10 15:14:14 +02:00
|
|
|
static int alloc_picture(MpegEncContext *s, Picture *pic)
|
2015-05-31 15:49:54 +02:00
|
|
|
{
|
2020-03-10 15:14:14 +02:00
|
|
|
return ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, 0, 0,
|
2015-05-31 15:49:54 +02:00
|
|
|
s->chroma_x_shift, s->chroma_y_shift, s->out_format,
|
2015-06-08 21:30:05 +02:00
|
|
|
s->mb_stride, s->mb_width, s->mb_height, s->b8_stride,
|
2015-05-31 15:49:54 +02:00
|
|
|
&s->linesize, &s->uvlinesize);
|
|
|
|
}
|
|
|
|
|
2013-02-03 15:13:00 +03:00
|
|
|
static int init_duplicate_context(MpegEncContext *s)
|
2011-11-30 23:55:45 +03:00
|
|
|
{
|
2010-07-01 14:51:01 +03:00
|
|
|
int y_size = s->b8_stride * (2 * s->mb_height + 1);
|
|
|
|
int c_size = s->mb_stride * (s->mb_height + 1);
|
|
|
|
int yc_size = y_size + 2 * c_size;
|
2004-02-13 19:54:10 +02:00
|
|
|
int i;
|
|
|
|
|
2014-01-03 22:20:12 +03:00
|
|
|
if (s->mb_height & 1)
|
|
|
|
yc_size += 2*s->b8_stride + 2*s->mb_stride;
|
|
|
|
|
2004-02-13 19:54:10 +02:00
|
|
|
if (s->encoding) {
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->me.map, ME_MAP_SIZE) ||
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->me.score_map, ME_MAP_SIZE))
|
|
|
|
return AVERROR(ENOMEM);
|
|
|
|
|
2015-09-13 23:45:24 +02:00
|
|
|
if (s->noise_reduction) {
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_error_sum, 2))
|
|
|
|
return AVERROR(ENOMEM);
|
2004-02-13 19:54:10 +02:00
|
|
|
}
|
2005-12-17 20:14:38 +02:00
|
|
|
}
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->blocks, 2))
|
|
|
|
return AVERROR(ENOMEM);
|
2011-11-30 23:55:45 +03:00
|
|
|
s->block = s->blocks[0];
|
2004-02-13 19:54:10 +02:00
|
|
|
|
2011-11-30 23:55:45 +03:00
|
|
|
for (i = 0; i < 12; i++) {
|
2009-02-22 11:02:06 +02:00
|
|
|
s->pblocks[i] = &s->block[i];
|
2004-02-13 19:54:10 +02:00
|
|
|
}
|
2017-12-29 17:42:14 +02:00
|
|
|
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!(s->block32 = av_mallocz(sizeof(*s->block32))) ||
|
|
|
|
!(s->dpcm_macroblock = av_mallocz(sizeof(*s->dpcm_macroblock))))
|
|
|
|
return AVERROR(ENOMEM);
|
2018-08-19 03:31:42 +02:00
|
|
|
s->dpcm_direction = 0;
|
2017-12-29 17:42:14 +02:00
|
|
|
|
2015-05-22 20:50:10 +02:00
|
|
|
if (s->avctx->codec_tag == AV_RL32("VCR2")) {
|
|
|
|
// exchange uv
|
2015-05-29 14:03:07 +02:00
|
|
|
FFSWAP(void *, s->pblocks[4], s->pblocks[5]);
|
2015-05-22 20:50:10 +02:00
|
|
|
}
|
2010-07-01 14:51:01 +03:00
|
|
|
|
2010-07-02 18:00:21 +03:00
|
|
|
if (s->out_format == FMT_H263) {
|
|
|
|
/* ac values */
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->ac_val_base, yc_size))
|
|
|
|
return AVERROR(ENOMEM);
|
2010-07-01 14:51:01 +03:00
|
|
|
s->ac_val[0] = s->ac_val_base + s->b8_stride + 1;
|
|
|
|
s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1;
|
|
|
|
s->ac_val[2] = s->ac_val[1] + c_size;
|
|
|
|
}
|
|
|
|
|
2004-02-13 19:54:10 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-12-25 15:17:10 +02:00
|
|
|
/**
|
|
|
|
* Initialize an MpegEncContext's thread contexts. Presumes that
|
|
|
|
* slice_context_count is already set and that all the fields
|
|
|
|
* that are freed/reset in free_duplicate_context() are NULL.
|
|
|
|
*/
|
|
|
|
static int init_duplicate_contexts(MpegEncContext *s)
|
|
|
|
{
|
|
|
|
int nb_slices = s->slice_context_count, ret;
|
|
|
|
|
|
|
|
/* We initialize the copies before the original so that
|
|
|
|
* fields allocated in init_duplicate_context are NULL after
|
|
|
|
* copying. This prevents double-frees upon allocation error. */
|
|
|
|
for (int i = 1; i < nb_slices; i++) {
|
|
|
|
s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));
|
|
|
|
if (!s->thread_context[i])
|
|
|
|
return AVERROR(ENOMEM);
|
|
|
|
if ((ret = init_duplicate_context(s->thread_context[i])) < 0)
|
|
|
|
return ret;
|
|
|
|
s->thread_context[i]->start_mb_y =
|
|
|
|
(s->mb_height * (i ) + nb_slices / 2) / nb_slices;
|
|
|
|
s->thread_context[i]->end_mb_y =
|
|
|
|
(s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
|
|
|
|
}
|
|
|
|
s->start_mb_y = 0;
|
|
|
|
s->end_mb_y = nb_slices > 1 ? (s->mb_height + nb_slices / 2) / nb_slices
|
|
|
|
: s->mb_height;
|
|
|
|
return init_duplicate_context(s);
|
|
|
|
}
|
|
|
|
|
2011-11-30 23:55:45 +03:00
|
|
|
static void free_duplicate_context(MpegEncContext *s)
|
|
|
|
{
|
2014-08-14 23:31:24 +03:00
|
|
|
if (!s)
|
2011-11-30 23:55:45 +03:00
|
|
|
return;
|
2004-02-13 19:54:10 +02:00
|
|
|
|
2015-05-31 15:49:52 +02:00
|
|
|
av_freep(&s->sc.edge_emu_buffer);
|
2004-02-13 19:54:10 +02:00
|
|
|
av_freep(&s->me.scratchpad);
|
2011-11-30 23:55:45 +03:00
|
|
|
s->me.temp =
|
2015-05-31 15:49:52 +02:00
|
|
|
s->sc.rd_scratchpad =
|
|
|
|
s->sc.b_scratchpad =
|
|
|
|
s->sc.obmc_scratchpad = NULL;
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2004-02-13 19:54:10 +02:00
|
|
|
av_freep(&s->dct_error_sum);
|
|
|
|
av_freep(&s->me.map);
|
|
|
|
av_freep(&s->me.score_map);
|
|
|
|
av_freep(&s->blocks);
|
2017-12-29 17:42:14 +02:00
|
|
|
av_freep(&s->block32);
|
2018-08-19 03:31:42 +02:00
|
|
|
av_freep(&s->dpcm_macroblock);
|
2010-07-01 14:51:01 +03:00
|
|
|
av_freep(&s->ac_val_base);
|
2011-11-30 23:55:45 +03:00
|
|
|
s->block = NULL;
|
2004-02-13 19:54:10 +02:00
|
|
|
}
|
|
|
|
|
2020-12-25 15:57:38 +02:00
|
|
|
static void free_duplicate_contexts(MpegEncContext *s)
|
|
|
|
{
|
|
|
|
for (int i = 1; i < s->slice_context_count; i++) {
|
|
|
|
free_duplicate_context(s->thread_context[i]);
|
|
|
|
av_freep(&s->thread_context[i]);
|
|
|
|
}
|
|
|
|
free_duplicate_context(s);
|
|
|
|
}
|
|
|
|
|
2011-11-30 23:55:45 +03:00
|
|
|
static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
|
|
|
|
{
|
|
|
|
#define COPY(a) bak->a = src->a
|
2015-05-31 15:49:52 +02:00
|
|
|
COPY(sc.edge_emu_buffer);
|
2004-02-13 19:54:10 +02:00
|
|
|
COPY(me.scratchpad);
|
2008-12-02 12:43:08 +02:00
|
|
|
COPY(me.temp);
|
2015-05-31 15:49:52 +02:00
|
|
|
COPY(sc.rd_scratchpad);
|
|
|
|
COPY(sc.b_scratchpad);
|
|
|
|
COPY(sc.obmc_scratchpad);
|
2004-02-13 19:54:10 +02:00
|
|
|
COPY(me.map);
|
|
|
|
COPY(me.score_map);
|
|
|
|
COPY(blocks);
|
|
|
|
COPY(block);
|
2017-12-29 17:42:14 +02:00
|
|
|
COPY(block32);
|
2018-08-19 03:31:42 +02:00
|
|
|
COPY(dpcm_macroblock);
|
|
|
|
COPY(dpcm_direction);
|
2004-02-13 19:54:10 +02:00
|
|
|
COPY(start_mb_y);
|
|
|
|
COPY(end_mb_y);
|
|
|
|
COPY(me.map_generation);
|
|
|
|
COPY(pb);
|
|
|
|
COPY(dct_error_sum);
|
2004-02-17 20:57:50 +02:00
|
|
|
COPY(dct_count[0]);
|
|
|
|
COPY(dct_count[1]);
|
2010-07-01 14:51:01 +03:00
|
|
|
COPY(ac_val_base);
|
|
|
|
COPY(ac_val[0]);
|
|
|
|
COPY(ac_val[1]);
|
|
|
|
COPY(ac_val[2]);
|
2004-02-13 19:54:10 +02:00
|
|
|
#undef COPY
|
|
|
|
}
|
|
|
|
|
2012-11-26 00:42:07 +03:00
|
|
|
int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src)
|
2011-11-30 23:55:45 +03:00
|
|
|
{
|
2004-02-13 19:54:10 +02:00
|
|
|
MpegEncContext bak;
|
2012-11-26 00:42:07 +03:00
|
|
|
int i, ret;
|
2011-11-30 23:55:45 +03:00
|
|
|
// FIXME copy only needed parts
|
2004-02-13 19:54:10 +02:00
|
|
|
backup_duplicate_context(&bak, dst);
|
|
|
|
memcpy(dst, src, sizeof(MpegEncContext));
|
|
|
|
backup_duplicate_context(dst, &bak);
|
2011-11-30 23:55:45 +03:00
|
|
|
for (i = 0; i < 12; i++) {
|
2009-02-22 11:02:06 +02:00
|
|
|
dst->pblocks[i] = &dst->block[i];
|
2004-02-23 22:56:56 +02:00
|
|
|
}
|
2015-05-22 20:50:10 +02:00
|
|
|
if (dst->avctx->codec_tag == AV_RL32("VCR2")) {
|
|
|
|
// exchange uv
|
2015-05-29 14:03:07 +02:00
|
|
|
FFSWAP(void *, dst->pblocks[4], dst->pblocks[5]);
|
2015-05-22 20:50:10 +02:00
|
|
|
}
|
2015-05-31 15:49:52 +02:00
|
|
|
if (!dst->sc.edge_emu_buffer &&
|
2015-05-31 15:49:53 +02:00
|
|
|
(ret = ff_mpeg_framesize_alloc(dst->avctx, &dst->me,
|
|
|
|
&dst->sc, dst->linesize)) < 0) {
|
2012-11-26 00:42:07 +03:00
|
|
|
av_log(dst->avctx, AV_LOG_ERROR, "failed to allocate context "
|
|
|
|
"scratch buffers.\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
return 0;
|
2004-02-13 19:54:10 +02:00
|
|
|
}
|
|
|
|
|
2011-11-30 23:55:45 +03:00
|
|
|
int ff_mpeg_update_thread_context(AVCodecContext *dst,
|
|
|
|
const AVCodecContext *src)
|
2011-03-22 23:36:57 +02:00
|
|
|
{
|
2012-11-21 23:34:46 +03:00
|
|
|
int i, ret;
|
2011-03-22 23:36:57 +02:00
|
|
|
MpegEncContext *s = dst->priv_data, *s1 = src->priv_data;
|
|
|
|
|
2012-01-30 00:37:37 +03:00
|
|
|
if (dst == src)
|
2011-11-30 23:55:45 +03:00
|
|
|
return 0;
|
2011-03-22 23:36:57 +02:00
|
|
|
|
2012-11-18 04:56:29 +03:00
|
|
|
av_assert0(s != s1);
|
|
|
|
|
2011-11-30 23:55:45 +03:00
|
|
|
// FIXME can parameters change on I-frames?
|
|
|
|
// in that case dst may need a reinit
|
|
|
|
if (!s->context_initialized) {
|
2014-11-04 16:37:00 +02:00
|
|
|
int err;
|
2011-03-22 23:36:57 +02:00
|
|
|
memcpy(s, s1, sizeof(MpegEncContext));
|
|
|
|
|
|
|
|
s->avctx = dst;
|
|
|
|
s->bitstream_buffer = NULL;
|
|
|
|
s->bitstream_buffer_size = s->allocated_bitstream_buffer_size = 0;
|
|
|
|
|
2012-01-30 00:37:37 +03:00
|
|
|
if (s1->context_initialized){
|
2013-03-12 05:20:18 +03:00
|
|
|
// s->picture_range_start += MAX_PICTURE_COUNT;
|
|
|
|
// s->picture_range_end += MAX_PICTURE_COUNT;
|
2014-08-15 03:08:59 +03:00
|
|
|
ff_mpv_idct_init(s);
|
2014-11-11 22:20:50 +02:00
|
|
|
if((err = ff_mpv_common_init(s)) < 0){
|
2013-01-18 00:45:12 +03:00
|
|
|
memset(s, 0, sizeof(MpegEncContext));
|
|
|
|
s->avctx = dst;
|
2014-11-11 22:20:50 +02:00
|
|
|
return err;
|
2013-01-18 00:45:12 +03:00
|
|
|
}
|
2012-01-30 00:37:37 +03:00
|
|
|
}
|
2011-03-22 23:36:57 +02:00
|
|
|
}
|
|
|
|
|
2012-09-18 16:48:14 +03:00
|
|
|
if (s->height != s1->height || s->width != s1->width || s->context_reinit) {
|
|
|
|
s->height = s1->height;
|
|
|
|
s->width = s1->width;
|
2014-08-15 21:00:34 +03:00
|
|
|
if ((ret = ff_mpv_common_frame_size_change(s)) < 0)
|
2013-03-12 05:20:18 +03:00
|
|
|
return ret;
|
2012-09-18 16:48:14 +03:00
|
|
|
}
|
|
|
|
|
2011-03-22 23:36:57 +02:00
|
|
|
s->avctx->coded_height = s1->avctx->coded_height;
|
|
|
|
s->avctx->coded_width = s1->avctx->coded_width;
|
|
|
|
s->avctx->width = s1->avctx->width;
|
|
|
|
s->avctx->height = s1->avctx->height;
|
|
|
|
|
2018-12-13 06:57:35 +02:00
|
|
|
s->quarter_sample = s1->quarter_sample;
|
|
|
|
|
2011-03-22 23:36:57 +02:00
|
|
|
s->coded_picture_number = s1->coded_picture_number;
|
|
|
|
s->picture_number = s1->picture_number;
|
|
|
|
|
2012-11-18 04:56:29 +03:00
|
|
|
av_assert0(!s->picture || s->picture != s1->picture);
|
2013-03-26 23:54:36 +03:00
|
|
|
if(s->picture)
|
2012-11-21 23:34:46 +03:00
|
|
|
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->picture[i]);
|
2015-07-14 00:07:53 +02:00
|
|
|
if (s1->picture && s1->picture[i].f->buf[0] &&
|
2015-04-27 23:09:20 +02:00
|
|
|
(ret = ff_mpeg_ref_picture(s->avctx, &s->picture[i], &s1->picture[i])) < 0)
|
2012-11-21 23:34:46 +03:00
|
|
|
return ret;
|
2013-01-15 06:58:22 +03:00
|
|
|
}
|
2012-10-03 22:41:52 +03:00
|
|
|
|
2012-11-21 23:34:46 +03:00
|
|
|
#define UPDATE_PICTURE(pic)\
|
|
|
|
do {\
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->pic);\
|
2014-04-29 15:50:46 +03:00
|
|
|
if (s1->pic.f && s1->pic.f->buf[0])\
|
2015-04-27 23:09:20 +02:00
|
|
|
ret = ff_mpeg_ref_picture(s->avctx, &s->pic, &s1->pic);\
|
2012-11-21 23:34:46 +03:00
|
|
|
else\
|
2015-06-08 14:00:49 +02:00
|
|
|
ret = ff_update_picture_tables(&s->pic, &s1->pic);\
|
2012-11-21 23:34:46 +03:00
|
|
|
if (ret < 0)\
|
|
|
|
return ret;\
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
UPDATE_PICTURE(current_picture);
|
|
|
|
UPDATE_PICTURE(last_picture);
|
|
|
|
UPDATE_PICTURE(next_picture);
|
2012-10-03 22:41:52 +03:00
|
|
|
|
2014-12-09 18:47:53 +02:00
|
|
|
#define REBASE_PICTURE(pic, new_ctx, old_ctx) \
|
|
|
|
((pic && pic >= old_ctx->picture && \
|
|
|
|
pic < old_ctx->picture + MAX_PICTURE_COUNT) ? \
|
|
|
|
&new_ctx->picture[pic - old_ctx->picture] : NULL)
|
|
|
|
|
2011-12-05 19:40:28 +03:00
|
|
|
s->last_picture_ptr = REBASE_PICTURE(s1->last_picture_ptr, s, s1);
|
|
|
|
s->current_picture_ptr = REBASE_PICTURE(s1->current_picture_ptr, s, s1);
|
|
|
|
s->next_picture_ptr = REBASE_PICTURE(s1->next_picture_ptr, s, s1);
|
2011-03-22 23:36:57 +02:00
|
|
|
|
2011-12-05 19:40:28 +03:00
|
|
|
// Error/bug resilience
|
2011-03-22 23:36:57 +02:00
|
|
|
s->next_p_frame_damaged = s1->next_p_frame_damaged;
|
|
|
|
s->workaround_bugs = s1->workaround_bugs;
|
2011-11-10 15:51:38 +03:00
|
|
|
s->padding_bug_score = s1->padding_bug_score;
|
2011-03-22 23:36:57 +02:00
|
|
|
|
2016-04-27 19:45:23 +02:00
|
|
|
// MPEG-4 timing info
|
2013-11-26 13:23:16 +03:00
|
|
|
memcpy(&s->last_time_base, &s1->last_time_base,
|
2013-11-26 13:23:16 +03:00
|
|
|
(char *) &s1->pb_field_time + sizeof(s1->pb_field_time) -
|
2013-11-26 13:23:16 +03:00
|
|
|
(char *) &s1->last_time_base);
|
2011-12-05 19:40:28 +03:00
|
|
|
|
|
|
|
// B-frame info
|
|
|
|
s->max_b_frames = s1->max_b_frames;
|
|
|
|
s->low_delay = s1->low_delay;
|
2012-12-07 12:25:27 +03:00
|
|
|
s->droppable = s1->droppable;
|
2011-12-05 19:40:28 +03:00
|
|
|
|
|
|
|
// DivX handling (doesn't work)
|
|
|
|
s->divx_packed = s1->divx_packed;
|
|
|
|
|
|
|
|
if (s1->bitstream_buffer) {
|
|
|
|
if (s1->bitstream_buffer_size +
|
2015-07-27 22:53:16 +02:00
|
|
|
AV_INPUT_BUFFER_PADDING_SIZE > s->allocated_bitstream_buffer_size) {
|
2011-12-05 19:40:28 +03:00
|
|
|
av_fast_malloc(&s->bitstream_buffer,
|
|
|
|
&s->allocated_bitstream_buffer_size,
|
|
|
|
s1->allocated_bitstream_buffer_size);
|
2015-05-29 00:33:18 +02:00
|
|
|
if (!s->bitstream_buffer) {
|
|
|
|
s->bitstream_buffer_size = 0;
|
2015-05-28 17:25:57 +02:00
|
|
|
return AVERROR(ENOMEM);
|
2015-05-29 00:33:18 +02:00
|
|
|
}
|
2015-05-28 17:25:57 +02:00
|
|
|
}
|
|
|
|
s->bitstream_buffer_size = s1->bitstream_buffer_size;
|
2011-12-05 19:40:28 +03:00
|
|
|
memcpy(s->bitstream_buffer, s1->bitstream_buffer,
|
|
|
|
s1->bitstream_buffer_size);
|
|
|
|
memset(s->bitstream_buffer + s->bitstream_buffer_size, 0,
|
2015-06-29 23:48:34 +02:00
|
|
|
AV_INPUT_BUFFER_PADDING_SIZE);
|
2011-03-22 23:36:57 +02:00
|
|
|
}
|
|
|
|
|
2016-04-27 19:45:23 +02:00
|
|
|
// linesize-dependent scratch buffer allocation
|
2015-05-31 15:49:52 +02:00
|
|
|
if (!s->sc.edge_emu_buffer)
|
2012-11-26 00:42:07 +03:00
|
|
|
if (s1->linesize) {
|
2015-05-31 15:49:53 +02:00
|
|
|
if (ff_mpeg_framesize_alloc(s->avctx, &s->me,
|
|
|
|
&s->sc, s1->linesize) < 0) {
|
2012-11-26 00:42:07 +03:00
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "Failed to allocate context "
|
|
|
|
"scratch buffers.\n");
|
|
|
|
return AVERROR(ENOMEM);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "Context scratch buffers could not "
|
|
|
|
"be allocated due to unknown size.\n");
|
|
|
|
}
|
|
|
|
|
2016-04-27 19:45:23 +02:00
|
|
|
// MPEG-2/interlacing info
|
2011-12-05 19:40:28 +03:00
|
|
|
memcpy(&s->progressive_sequence, &s1->progressive_sequence,
|
|
|
|
(char *) &s1->rtp_mode - (char *) &s1->progressive_sequence);
|
2011-03-22 23:36:57 +02:00
|
|
|
|
2011-12-05 19:40:28 +03:00
|
|
|
if (!s1->first_field) {
|
|
|
|
s->last_pict_type = s1->pict_type;
|
|
|
|
if (s1->current_picture_ptr)
|
2014-03-31 20:46:29 +03:00
|
|
|
s->last_lambda_for[s1->pict_type] = s1->current_picture_ptr->f->quality;
|
2011-03-22 23:36:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-03-16 18:11:29 +02:00
|
|
|
/**
|
2011-12-07 15:03:53 +03:00
|
|
|
* Set the given MpegEncContext to common defaults
|
2011-12-05 19:40:28 +03:00
|
|
|
* (same for encoding and decoding).
|
2011-12-07 15:03:53 +03:00
|
|
|
* The changed fields will not depend upon the
|
2011-12-05 19:40:28 +03:00
|
|
|
* prior state of the MpegEncContext.
|
2004-03-16 18:11:29 +02:00
|
|
|
*/
|
2014-08-10 18:25:12 +03:00
|
|
|
void ff_mpv_common_defaults(MpegEncContext *s)
|
2011-12-05 19:40:28 +03:00
|
|
|
{
|
|
|
|
s->y_dc_scale_table =
|
|
|
|
s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
|
|
|
|
s->chroma_qscale_table = ff_default_chroma_qscale_table;
|
|
|
|
s->progressive_frame = 1;
|
|
|
|
s->progressive_sequence = 1;
|
|
|
|
s->picture_structure = PICT_FRAME;
|
|
|
|
|
|
|
|
s->coded_picture_number = 0;
|
|
|
|
s->picture_number = 0;
|
2004-03-16 19:27:03 +02:00
|
|
|
|
2011-12-05 19:40:28 +03:00
|
|
|
s->f_code = 1;
|
|
|
|
s->b_code = 1;
|
2011-03-22 23:36:57 +02:00
|
|
|
|
2012-01-01 22:24:24 +03:00
|
|
|
s->slice_context_count = 1;
|
2004-03-16 18:11:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-12-09 04:23:32 +02:00
|
|
|
* Initialize the given MpegEncContext for decoding.
|
2011-12-05 19:40:28 +03:00
|
|
|
* the changed fields will not depend upon
|
|
|
|
* the prior state of the MpegEncContext.
|
2004-03-16 18:11:29 +02:00
|
|
|
*/
|
2020-12-09 04:23:32 +02:00
|
|
|
void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx)
|
2011-12-05 19:40:28 +03:00
|
|
|
{
|
2014-08-10 18:25:12 +03:00
|
|
|
ff_mpv_common_defaults(s);
|
2004-03-16 18:11:29 +02:00
|
|
|
|
2014-09-05 17:57:57 +03:00
|
|
|
s->avctx = avctx;
|
|
|
|
s->width = avctx->coded_width;
|
|
|
|
s->height = avctx->coded_height;
|
|
|
|
s->codec_id = avctx->codec->id;
|
|
|
|
s->workaround_bugs = avctx->workaround_bugs;
|
|
|
|
|
2014-09-05 18:14:50 +03:00
|
|
|
/* convert fourcc to upper case */
|
|
|
|
s->codec_tag = avpriv_toupper4(avctx->codec_tag);
|
2014-09-05 17:57:57 +03:00
|
|
|
}
|
|
|
|
|
2012-09-05 17:34:05 +03:00
|
|
|
/**
|
|
|
|
* Initialize and allocates MpegEncContext fields dependent on the resolution.
|
|
|
|
*/
|
|
|
|
static int init_context_frame(MpegEncContext *s)
|
|
|
|
{
|
|
|
|
int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y;
|
|
|
|
|
|
|
|
s->mb_width = (s->width + 15) / 16;
|
|
|
|
s->mb_stride = s->mb_width + 1;
|
|
|
|
s->b8_stride = s->mb_width * 2 + 1;
|
|
|
|
mb_array_size = s->mb_height * s->mb_stride;
|
|
|
|
mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
|
|
|
|
|
2014-04-27 16:20:45 +03:00
|
|
|
/* set default edge pos, will be overridden
|
2012-09-05 17:34:05 +03:00
|
|
|
* 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->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;
|
|
|
|
|
2014-01-03 22:20:12 +03:00
|
|
|
if (s->mb_height & 1)
|
|
|
|
yc_size += 2*s->b8_stride + 2*s->mb_stride;
|
|
|
|
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_index2xy, s->mb_num + 1))
|
|
|
|
return AVERROR(ENOMEM);
|
2012-09-05 17:34:05 +03:00
|
|
|
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;
|
|
|
|
|
2012-09-19 15:53:53 +03:00
|
|
|
s->mb_index2xy[s->mb_height * s->mb_width] = (s->mb_height - 1) * s->mb_stride + s->mb_width; // FIXME really needed?
|
2012-09-05 17:34:05 +03:00
|
|
|
|
|
|
|
if (s->encoding) {
|
|
|
|
/* Allocate MV tables */
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->p_mv_table_base, mv_table_size) ||
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->b_forw_mv_table_base, mv_table_size) ||
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->b_back_mv_table_base, mv_table_size) ||
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_forw_mv_table_base, mv_table_size) ||
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_back_mv_table_base, mv_table_size) ||
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->b_direct_mv_table_base, mv_table_size))
|
|
|
|
return AVERROR(ENOMEM);
|
2012-09-05 17:34:05 +03:00
|
|
|
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;
|
2012-09-19 15:53:53 +03:00
|
|
|
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;
|
2012-09-05 17:34:05 +03:00
|
|
|
s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1;
|
|
|
|
|
|
|
|
/* Allocate MB type table */
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_type, mb_array_size) ||
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->lambda_table, mb_array_size) ||
|
|
|
|
!FF_ALLOC_TYPED_ARRAY (s->cplx_tab, mb_array_size) ||
|
|
|
|
!FF_ALLOC_TYPED_ARRAY (s->bits_tab, mb_array_size))
|
|
|
|
return AVERROR(ENOMEM);
|
2012-09-05 17:34:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (s->codec_id == AV_CODEC_ID_MPEG4 ||
|
2015-06-29 21:59:37 +02:00
|
|
|
(s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
|
2012-09-05 17:34:05 +03:00
|
|
|
/* 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++) {
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_mv_table_base[i][j][k], mv_table_size))
|
|
|
|
return AVERROR(ENOMEM);
|
2012-09-05 17:34:05 +03:00
|
|
|
s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] +
|
|
|
|
s->mb_stride + 1;
|
|
|
|
}
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_select_table [i][j], mv_table_size * 2) ||
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->p_field_mv_table_base[i][j], mv_table_size))
|
|
|
|
return AVERROR(ENOMEM);
|
2012-09-19 15:53:53 +03:00
|
|
|
s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + s->mb_stride + 1;
|
2012-09-05 17:34:05 +03:00
|
|
|
}
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->p_field_select_table[i], mv_table_size * 2))
|
|
|
|
return AVERROR(ENOMEM);
|
2012-09-05 17:34:05 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (s->out_format == FMT_H263) {
|
2020-06-02 17:42:30 +02:00
|
|
|
/* cbp values, cbp, ac_pred, pred_dir */
|
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->coded_block_base, y_size + (s->mb_height&1)*2*s->b8_stride) ||
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->cbp_table, mb_array_size) ||
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->pred_dir_table, mb_array_size))
|
|
|
|
return AVERROR(ENOMEM);
|
2012-09-05 17:34:05 +03:00
|
|
|
s->coded_block = s->coded_block_base + s->b8_stride + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s->h263_pred || s->h263_plus || !s->encoding) {
|
|
|
|
/* dc values */
|
2016-03-29 00:07:47 +02:00
|
|
|
// MN: we need these for error resilience of intra-frames
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->dc_val_base, yc_size))
|
|
|
|
return AVERROR(ENOMEM);
|
2012-09-05 17:34:05 +03:00
|
|
|
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;
|
|
|
|
for (i = 0; i < yc_size; i++)
|
|
|
|
s->dc_val_base[i] = 1024;
|
|
|
|
}
|
|
|
|
|
2020-06-02 17:42:30 +02:00
|
|
|
/* which mb is an intra block, init macroblock skip table */
|
2020-12-27 22:16:08 +02:00
|
|
|
if (!FF_ALLOC_TYPED_ARRAY(s->mbintra_table, mb_array_size) ||
|
2020-06-02 17:42:30 +02:00
|
|
|
// Note the + 1 is for a quicker MPEG-4 slice_end detection
|
|
|
|
!FF_ALLOCZ_TYPED_ARRAY(s->mbskip_table, mb_array_size + 2))
|
|
|
|
return AVERROR(ENOMEM);
|
2012-09-05 17:34:05 +03:00
|
|
|
memset(s->mbintra_table, 1, mb_array_size);
|
|
|
|
|
2015-06-10 15:29:04 +02:00
|
|
|
return ff_mpeg_er_init(s);
|
2012-09-05 17:34:05 +03:00
|
|
|
}
|
|
|
|
|
2015-07-09 22:16:15 +02:00
|
|
|
static void clear_context(MpegEncContext *s)
|
|
|
|
{
|
|
|
|
int i, j, k;
|
|
|
|
|
|
|
|
memset(&s->next_picture, 0, sizeof(s->next_picture));
|
|
|
|
memset(&s->last_picture, 0, sizeof(s->last_picture));
|
|
|
|
memset(&s->current_picture, 0, sizeof(s->current_picture));
|
|
|
|
memset(&s->new_picture, 0, sizeof(s->new_picture));
|
|
|
|
|
|
|
|
memset(s->thread_context, 0, sizeof(s->thread_context));
|
|
|
|
|
|
|
|
s->me.map = NULL;
|
|
|
|
s->me.score_map = NULL;
|
|
|
|
s->dct_error_sum = NULL;
|
|
|
|
s->block = NULL;
|
|
|
|
s->blocks = NULL;
|
2017-12-29 17:42:14 +02:00
|
|
|
s->block32 = NULL;
|
2015-07-09 22:16:15 +02:00
|
|
|
memset(s->pblocks, 0, sizeof(s->pblocks));
|
2018-08-19 03:31:42 +02:00
|
|
|
s->dpcm_direction = 0;
|
|
|
|
s->dpcm_macroblock = NULL;
|
2015-07-09 22:16:15 +02:00
|
|
|
s->ac_val_base = NULL;
|
|
|
|
s->ac_val[0] =
|
|
|
|
s->ac_val[1] =
|
|
|
|
s->ac_val[2] =NULL;
|
|
|
|
s->sc.edge_emu_buffer = NULL;
|
|
|
|
s->me.scratchpad = NULL;
|
|
|
|
s->me.temp =
|
|
|
|
s->sc.rd_scratchpad =
|
|
|
|
s->sc.b_scratchpad =
|
|
|
|
s->sc.obmc_scratchpad = NULL;
|
|
|
|
|
2016-06-10 15:38:26 +02:00
|
|
|
|
2015-07-09 22:16:15 +02:00
|
|
|
s->bitstream_buffer = NULL;
|
|
|
|
s->allocated_bitstream_buffer_size = 0;
|
|
|
|
s->picture = NULL;
|
|
|
|
s->mb_type = NULL;
|
|
|
|
s->p_mv_table_base = NULL;
|
|
|
|
s->b_forw_mv_table_base = NULL;
|
|
|
|
s->b_back_mv_table_base = NULL;
|
|
|
|
s->b_bidir_forw_mv_table_base = NULL;
|
|
|
|
s->b_bidir_back_mv_table_base = NULL;
|
|
|
|
s->b_direct_mv_table_base = NULL;
|
|
|
|
s->p_mv_table = NULL;
|
|
|
|
s->b_forw_mv_table = NULL;
|
|
|
|
s->b_back_mv_table = NULL;
|
|
|
|
s->b_bidir_forw_mv_table = NULL;
|
|
|
|
s->b_bidir_back_mv_table = NULL;
|
|
|
|
s->b_direct_mv_table = NULL;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
for (j = 0; j < 2; j++) {
|
|
|
|
for (k = 0; k < 2; k++) {
|
|
|
|
s->b_field_mv_table_base[i][j][k] = NULL;
|
|
|
|
s->b_field_mv_table[i][j][k] = NULL;
|
|
|
|
}
|
|
|
|
s->b_field_select_table[i][j] = NULL;
|
|
|
|
s->p_field_mv_table_base[i][j] = NULL;
|
|
|
|
s->p_field_mv_table[i][j] = NULL;
|
|
|
|
}
|
|
|
|
s->p_field_select_table[i] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
s->dc_val_base = NULL;
|
|
|
|
s->coded_block_base = NULL;
|
|
|
|
s->mbintra_table = NULL;
|
|
|
|
s->cbp_table = NULL;
|
|
|
|
s->pred_dir_table = NULL;
|
|
|
|
|
|
|
|
s->mbskip_table = NULL;
|
|
|
|
|
|
|
|
s->er.error_status_table = NULL;
|
|
|
|
s->er.er_temp_buffer = NULL;
|
|
|
|
s->mb_index2xy = NULL;
|
|
|
|
s->lambda_table = NULL;
|
|
|
|
|
|
|
|
s->cplx_tab = NULL;
|
|
|
|
s->bits_tab = NULL;
|
|
|
|
}
|
|
|
|
|
2005-12-17 20:14:38 +02:00
|
|
|
/**
|
2004-03-16 18:11:29 +02:00
|
|
|
* init common structure for both encoder and decoder.
|
|
|
|
* this assumes that some variables like width/height are already set
|
|
|
|
*/
|
2014-08-10 18:25:12 +03:00
|
|
|
av_cold int ff_mpv_common_init(MpegEncContext *s)
|
2002-10-04 23:59:29 +03:00
|
|
|
{
|
2017-11-06 23:39:16 +02:00
|
|
|
int i, ret;
|
2012-01-01 22:24:24 +03:00
|
|
|
int nb_slices = (HAVE_THREADS &&
|
|
|
|
s->avctx->active_thread_type & FF_THREAD_SLICE) ?
|
|
|
|
s->avctx->thread_count : 1;
|
|
|
|
|
2015-07-09 22:16:15 +02:00
|
|
|
clear_context(s);
|
|
|
|
|
2012-01-01 22:24:24 +03:00
|
|
|
if (s->encoding && s->avctx->slices)
|
|
|
|
nb_slices = s->avctx->slices;
|
2002-10-04 23:59:29 +03:00
|
|
|
|
2012-08-05 12:11:04 +03:00
|
|
|
if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
|
2009-04-08 23:48:44 +03:00
|
|
|
s->mb_height = (s->height + 31) / 32 * 2;
|
2013-03-07 18:35:57 +03:00
|
|
|
else
|
2009-04-13 06:35:32 +03:00
|
|
|
s->mb_height = (s->height + 15) / 16;
|
2006-01-28 02:57:59 +02:00
|
|
|
|
2012-10-06 13:10:34 +03:00
|
|
|
if (s->avctx->pix_fmt == AV_PIX_FMT_NONE) {
|
2011-12-05 19:40:28 +03:00
|
|
|
av_log(s->avctx, AV_LOG_ERROR,
|
2012-10-06 13:10:34 +03:00
|
|
|
"decoding to AV_PIX_FMT_NONE is not supported.\n");
|
2020-05-08 00:57:58 +02:00
|
|
|
return AVERROR(EINVAL);
|
2009-02-19 10:39:47 +02:00
|
|
|
}
|
|
|
|
|
2012-01-01 22:24:24 +03:00
|
|
|
if (nb_slices > MAX_THREADS || (nb_slices > s->mb_height && s->mb_height)) {
|
|
|
|
int max_slices;
|
|
|
|
if (s->mb_height)
|
|
|
|
max_slices = FFMIN(MAX_THREADS, s->mb_height);
|
|
|
|
else
|
|
|
|
max_slices = MAX_THREADS;
|
|
|
|
av_log(s->avctx, AV_LOG_WARNING, "too many threads/slices (%d),"
|
|
|
|
" reducing to %d\n", nb_slices, max_slices);
|
|
|
|
nb_slices = max_slices;
|
2004-04-30 01:12:29 +03:00
|
|
|
}
|
|
|
|
|
2011-12-05 19:40:28 +03:00
|
|
|
if ((s->width || s->height) &&
|
|
|
|
av_image_check_size(s->width, s->height, 0, s->avctx))
|
2020-05-08 00:57:58 +02:00
|
|
|
return AVERROR(EINVAL);
|
2005-01-12 02:16:25 +02:00
|
|
|
|
2014-08-08 18:11:20 +03:00
|
|
|
dct_init(s);
|
2002-11-11 11:40:17 +02:00
|
|
|
|
2012-11-14 13:22:40 +03:00
|
|
|
/* set chroma shifts */
|
2017-11-06 23:39:16 +02:00
|
|
|
ret = av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
|
|
|
|
&s->chroma_x_shift,
|
|
|
|
&s->chroma_y_shift);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
2003-09-11 02:40:55 +03:00
|
|
|
|
2020-06-02 17:42:30 +02:00
|
|
|
if (!FF_ALLOCZ_TYPED_ARRAY(s->picture, MAX_PICTURE_COUNT))
|
|
|
|
return AVERROR(ENOMEM);
|
2012-11-21 23:34:46 +03:00
|
|
|
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
|
2014-03-31 20:46:29 +03:00
|
|
|
s->picture[i].f = av_frame_alloc();
|
|
|
|
if (!s->picture[i].f)
|
Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
This mostly reverts commit 4b2863ff01b1fe93d9a518523c9098d17a9d8c6f.
Said commit removed the freeing code from ff_mpv_common_init(),
ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and
instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use
ff_mpv_common_init(). This introduced several bugs:
a) Several decoders using ff_mpv_common_init() in their init function were
forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as
VC-1/WMV3.
b) ff_mpv_common_init() is not only called from the init function of
codecs, it is also called from AVCodec.decode functions. If an error
happens after an allocation has succeeded, it can lead to memleaks;
furthermore, it is now possible for the MpegEncContext to be marked as
initialized even when ff_mpv_common_init() returns an error and this can
lead to segfaults because decoders that call ff_mpv_common_init() when
decoding a frame can mistakenly think that the MpegEncContext has been
properly initialized. This can e.g. happen with H.261 or MPEG-4.
c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't
be called from any init function) can lead to segfaults because the
check for whether it needs to allocate consists of checking whether the
first of the buffers allocated there has been allocated. This part has
already been fixed in 76cea1d2ce3f23e8131c8664086a1daf873ed694.
d) ff_mpv_common_frame_size_change() can also not be reached from any
AVCodec.init function; yet the changes can e.g. lead to segfaults with
decoders using ff_h263_decode_frame() upon allocation failure, because
the MpegEncContext will upon return be flagged as both initialized and
not in need of reinitialization (granted, the fact that
ff_h263_decode_frame() clears context_reinit before the context has been
reinited is a bug in itself). With the earlier version, the context
would be cleaned upon failure and it would be attempted to initialize
the context again in the next call to ff_h263_decode_frame().
While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP,
keeping the current approach would entail adding cleanup code to several
other places because of b). Therefore ff_mpv_common_init() is again made
to clean up after itself; the changes to the wmv2 decoder and the SVQ1
encoder have not been reverted: The former fixed a memleak, the latter
allowed to remove cleanup code.
Fixes: double free
Fixes: ff_free_picture_tables.mp4
Fixes: ff_mpeg_update_thread_context.mp4
Fixes: decode_colskip.mp4
Fixes: memset.mp4
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-12-24 15:36:22 +02:00
|
|
|
goto fail_nomem;
|
2009-06-09 13:06:25 +03:00
|
|
|
}
|
2020-06-02 17:42:30 +02:00
|
|
|
|
2020-06-02 17:36:54 +02:00
|
|
|
if (!(s->next_picture.f = av_frame_alloc()) ||
|
|
|
|
!(s->last_picture.f = av_frame_alloc()) ||
|
|
|
|
!(s->current_picture.f = av_frame_alloc()) ||
|
|
|
|
!(s->new_picture.f = av_frame_alloc()))
|
Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
This mostly reverts commit 4b2863ff01b1fe93d9a518523c9098d17a9d8c6f.
Said commit removed the freeing code from ff_mpv_common_init(),
ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and
instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use
ff_mpv_common_init(). This introduced several bugs:
a) Several decoders using ff_mpv_common_init() in their init function were
forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as
VC-1/WMV3.
b) ff_mpv_common_init() is not only called from the init function of
codecs, it is also called from AVCodec.decode functions. If an error
happens after an allocation has succeeded, it can lead to memleaks;
furthermore, it is now possible for the MpegEncContext to be marked as
initialized even when ff_mpv_common_init() returns an error and this can
lead to segfaults because decoders that call ff_mpv_common_init() when
decoding a frame can mistakenly think that the MpegEncContext has been
properly initialized. This can e.g. happen with H.261 or MPEG-4.
c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't
be called from any init function) can lead to segfaults because the
check for whether it needs to allocate consists of checking whether the
first of the buffers allocated there has been allocated. This part has
already been fixed in 76cea1d2ce3f23e8131c8664086a1daf873ed694.
d) ff_mpv_common_frame_size_change() can also not be reached from any
AVCodec.init function; yet the changes can e.g. lead to segfaults with
decoders using ff_h263_decode_frame() upon allocation failure, because
the MpegEncContext will upon return be flagged as both initialized and
not in need of reinitialization (granted, the fact that
ff_h263_decode_frame() clears context_reinit before the context has been
reinited is a bug in itself). With the earlier version, the context
would be cleaned upon failure and it would be attempted to initialize
the context again in the next call to ff_h263_decode_frame().
While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP,
keeping the current approach would entail adding cleanup code to several
other places because of b). Therefore ff_mpv_common_init() is again made
to clean up after itself; the changes to the wmv2 decoder and the SVQ1
encoder have not been reverted: The former fixed a memleak, the latter
allowed to remove cleanup code.
Fixes: double free
Fixes: ff_free_picture_tables.mp4
Fixes: ff_mpeg_update_thread_context.mp4
Fixes: decode_colskip.mp4
Fixes: memset.mp4
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-12-24 15:36:22 +02:00
|
|
|
goto fail_nomem;
|
2003-10-21 22:55:31 +03:00
|
|
|
|
2020-05-08 00:57:58 +02:00
|
|
|
if ((ret = init_context_frame(s)))
|
Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
This mostly reverts commit 4b2863ff01b1fe93d9a518523c9098d17a9d8c6f.
Said commit removed the freeing code from ff_mpv_common_init(),
ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and
instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use
ff_mpv_common_init(). This introduced several bugs:
a) Several decoders using ff_mpv_common_init() in their init function were
forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as
VC-1/WMV3.
b) ff_mpv_common_init() is not only called from the init function of
codecs, it is also called from AVCodec.decode functions. If an error
happens after an allocation has succeeded, it can lead to memleaks;
furthermore, it is now possible for the MpegEncContext to be marked as
initialized even when ff_mpv_common_init() returns an error and this can
lead to segfaults because decoders that call ff_mpv_common_init() when
decoding a frame can mistakenly think that the MpegEncContext has been
properly initialized. This can e.g. happen with H.261 or MPEG-4.
c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't
be called from any init function) can lead to segfaults because the
check for whether it needs to allocate consists of checking whether the
first of the buffers allocated there has been allocated. This part has
already been fixed in 76cea1d2ce3f23e8131c8664086a1daf873ed694.
d) ff_mpv_common_frame_size_change() can also not be reached from any
AVCodec.init function; yet the changes can e.g. lead to segfaults with
decoders using ff_h263_decode_frame() upon allocation failure, because
the MpegEncContext will upon return be flagged as both initialized and
not in need of reinitialization (granted, the fact that
ff_h263_decode_frame() clears context_reinit before the context has been
reinited is a bug in itself). With the earlier version, the context
would be cleaned upon failure and it would be attempted to initialize
the context again in the next call to ff_h263_decode_frame().
While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP,
keeping the current approach would entail adding cleanup code to several
other places because of b). Therefore ff_mpv_common_init() is again made
to clean up after itself; the changes to the wmv2 decoder and the SVQ1
encoder have not been reverted: The former fixed a memleak, the latter
allowed to remove cleanup code.
Fixes: double free
Fixes: ff_free_picture_tables.mp4
Fixes: ff_mpeg_update_thread_context.mp4
Fixes: decode_colskip.mp4
Fixes: memset.mp4
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-12-24 15:36:22 +02:00
|
|
|
goto fail;
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2016-11-01 14:42:27 +02:00
|
|
|
s->parse_context.state = -1;
|
2002-11-08 20:35:39 +02:00
|
|
|
|
2016-11-01 14:42:27 +02:00
|
|
|
s->context_initialized = 1;
|
|
|
|
memset(s->thread_context, 0, sizeof(s->thread_context));
|
|
|
|
s->thread_context[0] = s;
|
2020-12-25 15:17:10 +02:00
|
|
|
s->slice_context_count = nb_slices;
|
2007-09-05 19:18:15 +03:00
|
|
|
|
2012-01-03 04:25:56 +03:00
|
|
|
// if (s->width && s->height) {
|
2020-12-25 15:17:10 +02:00
|
|
|
ret = init_duplicate_contexts(s);
|
|
|
|
if (ret < 0)
|
|
|
|
goto fail;
|
2012-01-03 04:25:56 +03:00
|
|
|
// }
|
2004-02-13 19:54:10 +02:00
|
|
|
|
2001-07-22 17:18:56 +03:00
|
|
|
return 0;
|
Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
This mostly reverts commit 4b2863ff01b1fe93d9a518523c9098d17a9d8c6f.
Said commit removed the freeing code from ff_mpv_common_init(),
ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and
instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use
ff_mpv_common_init(). This introduced several bugs:
a) Several decoders using ff_mpv_common_init() in their init function were
forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as
VC-1/WMV3.
b) ff_mpv_common_init() is not only called from the init function of
codecs, it is also called from AVCodec.decode functions. If an error
happens after an allocation has succeeded, it can lead to memleaks;
furthermore, it is now possible for the MpegEncContext to be marked as
initialized even when ff_mpv_common_init() returns an error and this can
lead to segfaults because decoders that call ff_mpv_common_init() when
decoding a frame can mistakenly think that the MpegEncContext has been
properly initialized. This can e.g. happen with H.261 or MPEG-4.
c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't
be called from any init function) can lead to segfaults because the
check for whether it needs to allocate consists of checking whether the
first of the buffers allocated there has been allocated. This part has
already been fixed in 76cea1d2ce3f23e8131c8664086a1daf873ed694.
d) ff_mpv_common_frame_size_change() can also not be reached from any
AVCodec.init function; yet the changes can e.g. lead to segfaults with
decoders using ff_h263_decode_frame() upon allocation failure, because
the MpegEncContext will upon return be flagged as both initialized and
not in need of reinitialization (granted, the fact that
ff_h263_decode_frame() clears context_reinit before the context has been
reinited is a bug in itself). With the earlier version, the context
would be cleaned upon failure and it would be attempted to initialize
the context again in the next call to ff_h263_decode_frame().
While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP,
keeping the current approach would entail adding cleanup code to several
other places because of b). Therefore ff_mpv_common_init() is again made
to clean up after itself; the changes to the wmv2 decoder and the SVQ1
encoder have not been reverted: The former fixed a memleak, the latter
allowed to remove cleanup code.
Fixes: double free
Fixes: ff_free_picture_tables.mp4
Fixes: ff_mpeg_update_thread_context.mp4
Fixes: decode_colskip.mp4
Fixes: memset.mp4
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-12-24 15:36:22 +02:00
|
|
|
fail_nomem:
|
|
|
|
ret = AVERROR(ENOMEM);
|
|
|
|
fail:
|
|
|
|
ff_mpv_common_end(s);
|
|
|
|
return ret;
|
2001-07-22 17:18:56 +03:00
|
|
|
}
|
|
|
|
|
2012-09-05 17:34:05 +03:00
|
|
|
/**
|
2020-12-25 15:57:38 +02:00
|
|
|
* Frees and resets MpegEncContext fields depending on the resolution
|
|
|
|
* as well as the slice thread contexts.
|
2012-09-05 17:34:05 +03:00
|
|
|
* Is used during resolution changes to avoid a full reinitialization of the
|
|
|
|
* codec.
|
|
|
|
*/
|
2014-09-07 13:51:08 +03:00
|
|
|
static void free_context_frame(MpegEncContext *s)
|
2001-07-22 17:18:56 +03:00
|
|
|
{
|
2003-12-30 18:07:57 +02:00
|
|
|
int i, j, k;
|
2001-07-22 17:18:56 +03:00
|
|
|
|
2020-12-25 15:57:38 +02:00
|
|
|
free_duplicate_contexts(s);
|
|
|
|
|
2002-05-19 02:03:29 +03:00
|
|
|
av_freep(&s->mb_type);
|
2003-04-10 16:18:38 +03:00
|
|
|
av_freep(&s->p_mv_table_base);
|
|
|
|
av_freep(&s->b_forw_mv_table_base);
|
|
|
|
av_freep(&s->b_back_mv_table_base);
|
|
|
|
av_freep(&s->b_bidir_forw_mv_table_base);
|
|
|
|
av_freep(&s->b_bidir_back_mv_table_base);
|
|
|
|
av_freep(&s->b_direct_mv_table_base);
|
2011-12-05 19:40:28 +03:00
|
|
|
s->p_mv_table = NULL;
|
|
|
|
s->b_forw_mv_table = NULL;
|
|
|
|
s->b_back_mv_table = NULL;
|
|
|
|
s->b_bidir_forw_mv_table = NULL;
|
|
|
|
s->b_bidir_back_mv_table = NULL;
|
|
|
|
s->b_direct_mv_table = NULL;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
for (j = 0; j < 2; j++) {
|
|
|
|
for (k = 0; k < 2; k++) {
|
2003-12-30 18:07:57 +02:00
|
|
|
av_freep(&s->b_field_mv_table_base[i][j][k]);
|
2011-12-05 19:40:28 +03:00
|
|
|
s->b_field_mv_table[i][j][k] = NULL;
|
2003-12-30 18:07:57 +02:00
|
|
|
}
|
|
|
|
av_freep(&s->b_field_select_table[i][j]);
|
|
|
|
av_freep(&s->p_field_mv_table_base[i][j]);
|
2011-12-05 19:40:28 +03:00
|
|
|
s->p_field_mv_table[i][j] = NULL;
|
2003-12-30 18:07:57 +02:00
|
|
|
}
|
|
|
|
av_freep(&s->p_field_select_table[i]);
|
|
|
|
}
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2004-04-16 04:01:45 +03:00
|
|
|
av_freep(&s->dc_val_base);
|
|
|
|
av_freep(&s->coded_block_base);
|
2002-05-19 02:03:29 +03:00
|
|
|
av_freep(&s->mbintra_table);
|
2002-06-02 15:20:39 +03:00
|
|
|
av_freep(&s->cbp_table);
|
|
|
|
av_freep(&s->pred_dir_table);
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2002-05-19 02:03:29 +03:00
|
|
|
av_freep(&s->mbskip_table);
|
2005-01-12 02:16:25 +02:00
|
|
|
|
2013-02-02 22:42:07 +03:00
|
|
|
av_freep(&s->er.error_status_table);
|
|
|
|
av_freep(&s->er.er_temp_buffer);
|
2003-04-10 16:18:38 +03:00
|
|
|
av_freep(&s->mb_index2xy);
|
2003-10-07 14:32:40 +03:00
|
|
|
av_freep(&s->lambda_table);
|
2012-09-19 15:53:53 +03:00
|
|
|
|
2012-09-05 17:34:05 +03:00
|
|
|
av_freep(&s->cplx_tab);
|
|
|
|
av_freep(&s->bits_tab);
|
|
|
|
|
|
|
|
s->linesize = s->uvlinesize = 0;
|
|
|
|
}
|
|
|
|
|
2014-08-10 18:25:12 +03:00
|
|
|
int ff_mpv_common_frame_size_change(MpegEncContext *s)
|
2012-09-05 21:40:12 +03:00
|
|
|
{
|
|
|
|
int i, err = 0;
|
|
|
|
|
2014-09-07 14:00:47 +03:00
|
|
|
if (!s->context_initialized)
|
|
|
|
return AVERROR(EINVAL);
|
|
|
|
|
2014-09-07 13:51:08 +03:00
|
|
|
free_context_frame(s);
|
2012-09-05 21:40:12 +03:00
|
|
|
|
|
|
|
if (s->picture)
|
2012-11-21 23:34:46 +03:00
|
|
|
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
|
2012-09-05 21:40:12 +03:00
|
|
|
s->picture[i].needs_realloc = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
s->last_picture_ptr =
|
|
|
|
s->next_picture_ptr =
|
|
|
|
s->current_picture_ptr = NULL;
|
|
|
|
|
|
|
|
// init
|
|
|
|
if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
|
|
|
|
s->mb_height = (s->height + 31) / 32 * 2;
|
2013-03-07 18:35:57 +03:00
|
|
|
else
|
2012-09-05 21:40:12 +03:00
|
|
|
s->mb_height = (s->height + 15) / 16;
|
|
|
|
|
|
|
|
if ((s->width || s->height) &&
|
2014-09-07 15:14:52 +03:00
|
|
|
(err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0)
|
Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
This mostly reverts commit 4b2863ff01b1fe93d9a518523c9098d17a9d8c6f.
Said commit removed the freeing code from ff_mpv_common_init(),
ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and
instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use
ff_mpv_common_init(). This introduced several bugs:
a) Several decoders using ff_mpv_common_init() in their init function were
forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as
VC-1/WMV3.
b) ff_mpv_common_init() is not only called from the init function of
codecs, it is also called from AVCodec.decode functions. If an error
happens after an allocation has succeeded, it can lead to memleaks;
furthermore, it is now possible for the MpegEncContext to be marked as
initialized even when ff_mpv_common_init() returns an error and this can
lead to segfaults because decoders that call ff_mpv_common_init() when
decoding a frame can mistakenly think that the MpegEncContext has been
properly initialized. This can e.g. happen with H.261 or MPEG-4.
c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't
be called from any init function) can lead to segfaults because the
check for whether it needs to allocate consists of checking whether the
first of the buffers allocated there has been allocated. This part has
already been fixed in 76cea1d2ce3f23e8131c8664086a1daf873ed694.
d) ff_mpv_common_frame_size_change() can also not be reached from any
AVCodec.init function; yet the changes can e.g. lead to segfaults with
decoders using ff_h263_decode_frame() upon allocation failure, because
the MpegEncContext will upon return be flagged as both initialized and
not in need of reinitialization (granted, the fact that
ff_h263_decode_frame() clears context_reinit before the context has been
reinited is a bug in itself). With the earlier version, the context
would be cleaned upon failure and it would be attempted to initialize
the context again in the next call to ff_h263_decode_frame().
While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP,
keeping the current approach would entail adding cleanup code to several
other places because of b). Therefore ff_mpv_common_init() is again made
to clean up after itself; the changes to the wmv2 decoder and the SVQ1
encoder have not been reverted: The former fixed a memleak, the latter
allowed to remove cleanup code.
Fixes: double free
Fixes: ff_free_picture_tables.mp4
Fixes: ff_mpeg_update_thread_context.mp4
Fixes: decode_colskip.mp4
Fixes: memset.mp4
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-12-24 15:36:22 +02:00
|
|
|
goto fail;
|
2012-09-05 21:40:12 +03:00
|
|
|
|
2021-03-22 16:22:35 +02:00
|
|
|
/* set chroma shifts */
|
|
|
|
err = av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
|
|
|
|
&s->chroma_x_shift,
|
|
|
|
&s->chroma_y_shift);
|
|
|
|
if (err < 0)
|
Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
This mostly reverts commit 4b2863ff01b1fe93d9a518523c9098d17a9d8c6f.
Said commit removed the freeing code from ff_mpv_common_init(),
ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and
instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use
ff_mpv_common_init(). This introduced several bugs:
a) Several decoders using ff_mpv_common_init() in their init function were
forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as
VC-1/WMV3.
b) ff_mpv_common_init() is not only called from the init function of
codecs, it is also called from AVCodec.decode functions. If an error
happens after an allocation has succeeded, it can lead to memleaks;
furthermore, it is now possible for the MpegEncContext to be marked as
initialized even when ff_mpv_common_init() returns an error and this can
lead to segfaults because decoders that call ff_mpv_common_init() when
decoding a frame can mistakenly think that the MpegEncContext has been
properly initialized. This can e.g. happen with H.261 or MPEG-4.
c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't
be called from any init function) can lead to segfaults because the
check for whether it needs to allocate consists of checking whether the
first of the buffers allocated there has been allocated. This part has
already been fixed in 76cea1d2ce3f23e8131c8664086a1daf873ed694.
d) ff_mpv_common_frame_size_change() can also not be reached from any
AVCodec.init function; yet the changes can e.g. lead to segfaults with
decoders using ff_h263_decode_frame() upon allocation failure, because
the MpegEncContext will upon return be flagged as both initialized and
not in need of reinitialization (granted, the fact that
ff_h263_decode_frame() clears context_reinit before the context has been
reinited is a bug in itself). With the earlier version, the context
would be cleaned upon failure and it would be attempted to initialize
the context again in the next call to ff_h263_decode_frame().
While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP,
keeping the current approach would entail adding cleanup code to several
other places because of b). Therefore ff_mpv_common_init() is again made
to clean up after itself; the changes to the wmv2 decoder and the SVQ1
encoder have not been reverted: The former fixed a memleak, the latter
allowed to remove cleanup code.
Fixes: double free
Fixes: ff_free_picture_tables.mp4
Fixes: ff_mpeg_update_thread_context.mp4
Fixes: decode_colskip.mp4
Fixes: memset.mp4
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-12-24 15:36:22 +02:00
|
|
|
goto fail;
|
2021-03-22 16:22:35 +02:00
|
|
|
|
2012-09-05 21:40:12 +03:00
|
|
|
if ((err = init_context_frame(s)))
|
Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
This mostly reverts commit 4b2863ff01b1fe93d9a518523c9098d17a9d8c6f.
Said commit removed the freeing code from ff_mpv_common_init(),
ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and
instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use
ff_mpv_common_init(). This introduced several bugs:
a) Several decoders using ff_mpv_common_init() in their init function were
forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as
VC-1/WMV3.
b) ff_mpv_common_init() is not only called from the init function of
codecs, it is also called from AVCodec.decode functions. If an error
happens after an allocation has succeeded, it can lead to memleaks;
furthermore, it is now possible for the MpegEncContext to be marked as
initialized even when ff_mpv_common_init() returns an error and this can
lead to segfaults because decoders that call ff_mpv_common_init() when
decoding a frame can mistakenly think that the MpegEncContext has been
properly initialized. This can e.g. happen with H.261 or MPEG-4.
c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't
be called from any init function) can lead to segfaults because the
check for whether it needs to allocate consists of checking whether the
first of the buffers allocated there has been allocated. This part has
already been fixed in 76cea1d2ce3f23e8131c8664086a1daf873ed694.
d) ff_mpv_common_frame_size_change() can also not be reached from any
AVCodec.init function; yet the changes can e.g. lead to segfaults with
decoders using ff_h263_decode_frame() upon allocation failure, because
the MpegEncContext will upon return be flagged as both initialized and
not in need of reinitialization (granted, the fact that
ff_h263_decode_frame() clears context_reinit before the context has been
reinited is a bug in itself). With the earlier version, the context
would be cleaned upon failure and it would be attempted to initialize
the context again in the next call to ff_h263_decode_frame().
While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP,
keeping the current approach would entail adding cleanup code to several
other places because of b). Therefore ff_mpv_common_init() is again made
to clean up after itself; the changes to the wmv2 decoder and the SVQ1
encoder have not been reverted: The former fixed a memleak, the latter
allowed to remove cleanup code.
Fixes: double free
Fixes: ff_free_picture_tables.mp4
Fixes: ff_mpeg_update_thread_context.mp4
Fixes: decode_colskip.mp4
Fixes: memset.mp4
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-12-24 15:36:22 +02:00
|
|
|
goto fail;
|
2012-09-05 21:40:12 +03:00
|
|
|
|
2015-06-06 21:25:04 +02:00
|
|
|
memset(s->thread_context, 0, sizeof(s->thread_context));
|
2012-09-05 21:40:12 +03:00
|
|
|
s->thread_context[0] = s;
|
|
|
|
|
|
|
|
if (s->width && s->height) {
|
2020-12-25 15:17:10 +02:00
|
|
|
err = init_duplicate_contexts(s);
|
|
|
|
if (err < 0)
|
|
|
|
goto fail;
|
2012-09-05 21:40:12 +03:00
|
|
|
}
|
2021-04-05 02:05:58 +02:00
|
|
|
s->context_reinit = 0;
|
2012-09-05 21:40:12 +03:00
|
|
|
|
|
|
|
return 0;
|
Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
This mostly reverts commit 4b2863ff01b1fe93d9a518523c9098d17a9d8c6f.
Said commit removed the freeing code from ff_mpv_common_init(),
ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and
instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use
ff_mpv_common_init(). This introduced several bugs:
a) Several decoders using ff_mpv_common_init() in their init function were
forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as
VC-1/WMV3.
b) ff_mpv_common_init() is not only called from the init function of
codecs, it is also called from AVCodec.decode functions. If an error
happens after an allocation has succeeded, it can lead to memleaks;
furthermore, it is now possible for the MpegEncContext to be marked as
initialized even when ff_mpv_common_init() returns an error and this can
lead to segfaults because decoders that call ff_mpv_common_init() when
decoding a frame can mistakenly think that the MpegEncContext has been
properly initialized. This can e.g. happen with H.261 or MPEG-4.
c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't
be called from any init function) can lead to segfaults because the
check for whether it needs to allocate consists of checking whether the
first of the buffers allocated there has been allocated. This part has
already been fixed in 76cea1d2ce3f23e8131c8664086a1daf873ed694.
d) ff_mpv_common_frame_size_change() can also not be reached from any
AVCodec.init function; yet the changes can e.g. lead to segfaults with
decoders using ff_h263_decode_frame() upon allocation failure, because
the MpegEncContext will upon return be flagged as both initialized and
not in need of reinitialization (granted, the fact that
ff_h263_decode_frame() clears context_reinit before the context has been
reinited is a bug in itself). With the earlier version, the context
would be cleaned upon failure and it would be attempted to initialize
the context again in the next call to ff_h263_decode_frame().
While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP,
keeping the current approach would entail adding cleanup code to several
other places because of b). Therefore ff_mpv_common_init() is again made
to clean up after itself; the changes to the wmv2 decoder and the SVQ1
encoder have not been reverted: The former fixed a memleak, the latter
allowed to remove cleanup code.
Fixes: double free
Fixes: ff_free_picture_tables.mp4
Fixes: ff_mpeg_update_thread_context.mp4
Fixes: decode_colskip.mp4
Fixes: memset.mp4
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-12-24 15:36:22 +02:00
|
|
|
fail:
|
2021-04-05 02:05:58 +02:00
|
|
|
free_context_frame(s);
|
|
|
|
s->context_reinit = 1;
|
Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
This mostly reverts commit 4b2863ff01b1fe93d9a518523c9098d17a9d8c6f.
Said commit removed the freeing code from ff_mpv_common_init(),
ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and
instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use
ff_mpv_common_init(). This introduced several bugs:
a) Several decoders using ff_mpv_common_init() in their init function were
forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as
VC-1/WMV3.
b) ff_mpv_common_init() is not only called from the init function of
codecs, it is also called from AVCodec.decode functions. If an error
happens after an allocation has succeeded, it can lead to memleaks;
furthermore, it is now possible for the MpegEncContext to be marked as
initialized even when ff_mpv_common_init() returns an error and this can
lead to segfaults because decoders that call ff_mpv_common_init() when
decoding a frame can mistakenly think that the MpegEncContext has been
properly initialized. This can e.g. happen with H.261 or MPEG-4.
c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't
be called from any init function) can lead to segfaults because the
check for whether it needs to allocate consists of checking whether the
first of the buffers allocated there has been allocated. This part has
already been fixed in 76cea1d2ce3f23e8131c8664086a1daf873ed694.
d) ff_mpv_common_frame_size_change() can also not be reached from any
AVCodec.init function; yet the changes can e.g. lead to segfaults with
decoders using ff_h263_decode_frame() upon allocation failure, because
the MpegEncContext will upon return be flagged as both initialized and
not in need of reinitialization (granted, the fact that
ff_h263_decode_frame() clears context_reinit before the context has been
reinited is a bug in itself). With the earlier version, the context
would be cleaned upon failure and it would be attempted to initialize
the context again in the next call to ff_h263_decode_frame().
While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP,
keeping the current approach would entail adding cleanup code to several
other places because of b). Therefore ff_mpv_common_init() is again made
to clean up after itself; the changes to the wmv2 decoder and the SVQ1
encoder have not been reverted: The former fixed a memleak, the latter
allowed to remove cleanup code.
Fixes: double free
Fixes: ff_free_picture_tables.mp4
Fixes: ff_mpeg_update_thread_context.mp4
Fixes: decode_colskip.mp4
Fixes: memset.mp4
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-12-24 15:36:22 +02:00
|
|
|
return err;
|
2012-09-05 21:40:12 +03:00
|
|
|
}
|
|
|
|
|
2012-09-05 17:34:05 +03:00
|
|
|
/* init common structure for both encoder and decoder */
|
2014-08-10 18:25:12 +03:00
|
|
|
void ff_mpv_common_end(MpegEncContext *s)
|
2012-09-05 17:34:05 +03:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2015-07-13 19:18:08 +02:00
|
|
|
if (!s)
|
2020-06-13 01:47:13 +02:00
|
|
|
return;
|
2015-07-13 19:18:08 +02:00
|
|
|
|
2020-12-25 15:57:38 +02:00
|
|
|
free_context_frame(s);
|
|
|
|
if (s->slice_context_count > 1)
|
2012-09-05 17:34:05 +03:00
|
|
|
s->slice_context_count = 1;
|
|
|
|
|
|
|
|
av_freep(&s->parse_context.buffer);
|
|
|
|
s->parse_context.buffer_size = 0;
|
|
|
|
|
|
|
|
av_freep(&s->bitstream_buffer);
|
|
|
|
s->allocated_bitstream_buffer_size = 0;
|
|
|
|
|
2020-06-03 15:53:11 +02:00
|
|
|
if (!s->avctx)
|
|
|
|
return;
|
|
|
|
|
2012-11-21 23:34:46 +03:00
|
|
|
if (s->picture) {
|
|
|
|
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
|
2013-11-30 13:50:09 +03:00
|
|
|
ff_free_picture_tables(&s->picture[i]);
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->picture[i]);
|
2014-03-31 20:46:29 +03:00
|
|
|
av_frame_free(&s->picture[i].f);
|
2003-10-25 22:30:14 +03:00
|
|
|
}
|
2001-07-22 17:18:56 +03:00
|
|
|
}
|
2003-10-21 22:55:31 +03:00
|
|
|
av_freep(&s->picture);
|
2013-11-30 13:50:09 +03:00
|
|
|
ff_free_picture_tables(&s->last_picture);
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->last_picture);
|
2014-03-31 20:46:29 +03:00
|
|
|
av_frame_free(&s->last_picture.f);
|
2013-11-30 13:50:09 +03:00
|
|
|
ff_free_picture_tables(&s->current_picture);
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->current_picture);
|
2014-03-31 20:46:29 +03:00
|
|
|
av_frame_free(&s->current_picture.f);
|
2013-11-30 13:50:09 +03:00
|
|
|
ff_free_picture_tables(&s->next_picture);
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->next_picture);
|
2014-03-31 20:46:29 +03:00
|
|
|
av_frame_free(&s->next_picture.f);
|
|
|
|
ff_free_picture_tables(&s->new_picture);
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->new_picture);
|
2014-03-31 20:46:29 +03:00
|
|
|
av_frame_free(&s->new_picture.f);
|
2012-09-19 15:53:53 +03:00
|
|
|
|
2011-12-05 19:40:28 +03:00
|
|
|
s->context_initialized = 0;
|
2021-04-05 02:05:58 +02:00
|
|
|
s->context_reinit = 0;
|
2011-12-05 19:40:28 +03:00
|
|
|
s->last_picture_ptr =
|
|
|
|
s->next_picture_ptr =
|
|
|
|
s->current_picture_ptr = NULL;
|
|
|
|
s->linesize = s->uvlinesize = 0;
|
2001-07-22 17:18:56 +03:00
|
|
|
}
|
|
|
|
|
2011-04-18 01:47:35 +03:00
|
|
|
|
2014-05-02 16:57:59 +03:00
|
|
|
static void gray_frame(AVFrame *frame)
|
|
|
|
{
|
|
|
|
int i, h_chroma_shift, v_chroma_shift;
|
|
|
|
|
|
|
|
av_pix_fmt_get_chroma_sub_sample(frame->format, &h_chroma_shift, &v_chroma_shift);
|
|
|
|
|
|
|
|
for(i=0; i<frame->height; i++)
|
|
|
|
memset(frame->data[0] + frame->linesize[0]*i, 0x80, frame->width);
|
2016-01-27 17:19:38 +02:00
|
|
|
for(i=0; i<AV_CEIL_RSHIFT(frame->height, v_chroma_shift); i++) {
|
2014-05-02 16:57:59 +03:00
|
|
|
memset(frame->data[1] + frame->linesize[1]*i,
|
2016-01-27 17:19:38 +02:00
|
|
|
0x80, AV_CEIL_RSHIFT(frame->width, h_chroma_shift));
|
2014-05-02 16:57:59 +03:00
|
|
|
memset(frame->data[2] + frame->linesize[2]*i,
|
2016-01-27 17:19:38 +02:00
|
|
|
0x80, AV_CEIL_RSHIFT(frame->width, h_chroma_shift));
|
2014-05-02 16:57:59 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-30 18:58:49 +02:00
|
|
|
/**
|
2013-12-03 09:48:09 +03:00
|
|
|
* generic function called after decoding
|
|
|
|
* the header and before a frame is decoded.
|
2003-10-30 18:58:49 +02:00
|
|
|
*/
|
2014-08-10 18:25:12 +03:00
|
|
|
int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx)
|
2001-07-22 17:18:56 +03:00
|
|
|
{
|
2012-11-21 23:34:46 +03:00
|
|
|
int i, ret;
|
2009-05-15 05:01:53 +03:00
|
|
|
Picture *pic;
|
2005-04-24 20:21:11 +03:00
|
|
|
s->mb_skipped = 0;
|
2003-04-04 17:42:28 +03:00
|
|
|
|
2012-03-24 02:20:05 +03:00
|
|
|
if (!ff_thread_can_start_frame(avctx)) {
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Attempt to start a frame outside SETUP state\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-12-25 20:58:01 +03:00
|
|
|
/* mark & release old frames */
|
2013-03-07 18:37:45 +03:00
|
|
|
if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&
|
|
|
|
s->last_picture_ptr != s->next_picture_ptr &&
|
2014-03-31 20:46:29 +03:00
|
|
|
s->last_picture_ptr->f->buf[0]) {
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, s->last_picture_ptr);
|
2013-03-07 18:37:45 +03:00
|
|
|
}
|
2011-12-25 20:58:01 +03:00
|
|
|
|
2013-03-07 18:37:45 +03:00
|
|
|
/* release forgotten pictures */
|
2016-04-27 19:45:23 +02:00
|
|
|
/* if (MPEG-124 / H.263) */
|
2013-12-03 09:48:09 +03:00
|
|
|
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
|
|
|
|
if (&s->picture[i] != s->last_picture_ptr &&
|
|
|
|
&s->picture[i] != s->next_picture_ptr &&
|
|
|
|
s->picture[i].reference && !s->picture[i].needs_realloc) {
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->picture[i]);
|
2002-10-27 02:02:23 +02:00
|
|
|
}
|
2013-03-07 18:37:45 +03:00
|
|
|
}
|
2009-11-30 23:22:01 +02:00
|
|
|
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->current_picture);
|
2016-06-05 01:46:18 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->last_picture);
|
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->next_picture);
|
2013-05-19 15:49:55 +03:00
|
|
|
|
2015-06-08 14:00:50 +02:00
|
|
|
/* release non reference frames */
|
|
|
|
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
|
|
|
|
if (!s->picture[i].reference)
|
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->picture[i]);
|
|
|
|
}
|
2003-05-06 23:43:37 +03:00
|
|
|
|
2014-08-14 23:31:24 +03:00
|
|
|
if (s->current_picture_ptr && !s->current_picture_ptr->f->buf[0]) {
|
2016-03-29 00:07:47 +02:00
|
|
|
// we already have an unused image
|
2013-12-03 09:48:09 +03:00
|
|
|
// (maybe it was set before reading the header)
|
|
|
|
pic = s->current_picture_ptr;
|
|
|
|
} else {
|
2015-04-27 23:09:21 +02:00
|
|
|
i = ff_find_unused_picture(s->avctx, s->picture, 0);
|
2013-12-03 09:48:09 +03:00
|
|
|
if (i < 0) {
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
|
|
|
|
return i;
|
2003-10-30 18:58:49 +02:00
|
|
|
}
|
2013-12-03 09:48:09 +03:00
|
|
|
pic = &s->picture[i];
|
|
|
|
}
|
2003-10-30 18:58:49 +02:00
|
|
|
|
2013-12-03 09:48:09 +03:00
|
|
|
pic->reference = 0;
|
|
|
|
if (!s->droppable) {
|
|
|
|
if (s->pict_type != AV_PICTURE_TYPE_B)
|
|
|
|
pic->reference = 3;
|
|
|
|
}
|
2003-03-16 22:22:22 +02:00
|
|
|
|
2014-03-31 20:46:29 +03:00
|
|
|
pic->f->coded_picture_number = s->coded_picture_number++;
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2020-03-10 15:14:14 +02:00
|
|
|
if (alloc_picture(s, pic) < 0)
|
2013-12-03 09:48:09 +03:00
|
|
|
return -1;
|
2002-07-14 21:37:35 +03:00
|
|
|
|
2013-12-03 09:48:09 +03:00
|
|
|
s->current_picture_ptr = pic;
|
|
|
|
// FIXME use only the vars from current_pic
|
2014-03-31 20:46:29 +03:00
|
|
|
s->current_picture_ptr->f->top_field_first = s->top_field_first;
|
2013-12-03 09:48:09 +03:00
|
|
|
if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO ||
|
|
|
|
s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
|
|
|
|
if (s->picture_structure != PICT_FRAME)
|
2014-03-31 20:46:29 +03:00
|
|
|
s->current_picture_ptr->f->top_field_first =
|
2013-12-03 09:48:09 +03:00
|
|
|
(s->picture_structure == PICT_TOP_FIELD) == s->first_field;
|
2002-12-04 12:04:03 +02:00
|
|
|
}
|
2014-03-31 20:46:29 +03:00
|
|
|
s->current_picture_ptr->f->interlaced_frame = !s->progressive_frame &&
|
2013-12-03 09:48:09 +03:00
|
|
|
!s->progressive_sequence;
|
|
|
|
s->current_picture_ptr->field_picture = s->picture_structure != PICT_FRAME;
|
2002-08-04 19:05:05 +03:00
|
|
|
|
2014-03-31 20:46:29 +03:00
|
|
|
s->current_picture_ptr->f->pict_type = s->pict_type;
|
2015-06-29 21:59:37 +02:00
|
|
|
// if (s->avctx->flags && AV_CODEC_FLAG_QSCALE)
|
2011-12-25 20:58:01 +03:00
|
|
|
// s->current_picture_ptr->quality = s->new_picture_ptr->quality;
|
2014-03-31 20:46:29 +03:00
|
|
|
s->current_picture_ptr->f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
|
2003-04-07 00:03:24 +03:00
|
|
|
|
2015-04-27 23:09:20 +02:00
|
|
|
if ((ret = ff_mpeg_ref_picture(s->avctx, &s->current_picture,
|
2012-11-21 23:34:46 +03:00
|
|
|
s->current_picture_ptr)) < 0)
|
|
|
|
return ret;
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2013-03-07 18:35:57 +03:00
|
|
|
if (s->pict_type != AV_PICTURE_TYPE_B) {
|
2011-12-25 20:58:01 +03:00
|
|
|
s->last_picture_ptr = s->next_picture_ptr;
|
2012-12-07 12:25:27 +03:00
|
|
|
if (!s->droppable)
|
2011-12-25 20:58:01 +03:00
|
|
|
s->next_picture_ptr = s->current_picture_ptr;
|
2001-07-22 17:18:56 +03:00
|
|
|
}
|
2015-03-16 10:57:36 +02:00
|
|
|
ff_dlog(s->avctx, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n",
|
2012-08-21 13:41:40 +03:00
|
|
|
s->last_picture_ptr, s->next_picture_ptr,s->current_picture_ptr,
|
2014-03-31 20:46:29 +03:00
|
|
|
s->last_picture_ptr ? s->last_picture_ptr->f->data[0] : NULL,
|
|
|
|
s->next_picture_ptr ? s->next_picture_ptr->f->data[0] : NULL,
|
|
|
|
s->current_picture_ptr ? s->current_picture_ptr->f->data[0] : NULL,
|
2012-12-07 12:25:27 +03:00
|
|
|
s->pict_type, s->droppable);
|
2011-12-25 20:58:01 +03:00
|
|
|
|
2014-08-14 23:31:24 +03:00
|
|
|
if ((!s->last_picture_ptr || !s->last_picture_ptr->f->buf[0]) &&
|
2017-09-30 05:22:57 +02:00
|
|
|
(s->pict_type != AV_PICTURE_TYPE_I)) {
|
2013-03-07 18:37:45 +03:00
|
|
|
int h_chroma_shift, v_chroma_shift;
|
|
|
|
av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
|
|
|
|
&h_chroma_shift, &v_chroma_shift);
|
2014-04-09 15:36:47 +03:00
|
|
|
if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture_ptr && s->next_picture_ptr->f->buf[0])
|
2013-08-30 15:20:59 +03:00
|
|
|
av_log(avctx, AV_LOG_DEBUG,
|
2013-08-30 02:45:11 +03:00
|
|
|
"allocating dummy last picture for B frame\n");
|
|
|
|
else if (s->pict_type != AV_PICTURE_TYPE_I)
|
2013-03-07 18:37:45 +03:00
|
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
|
|
"warning: first frame is no keyframe\n");
|
|
|
|
|
|
|
|
/* Allocate a dummy frame */
|
2015-04-27 23:09:21 +02:00
|
|
|
i = ff_find_unused_picture(s->avctx, s->picture, 0);
|
2013-03-07 18:37:45 +03:00
|
|
|
if (i < 0) {
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
|
|
|
|
return i;
|
2009-11-30 23:22:01 +02:00
|
|
|
}
|
2013-03-07 18:37:45 +03:00
|
|
|
s->last_picture_ptr = &s->picture[i];
|
2013-11-28 12:54:35 +03:00
|
|
|
|
|
|
|
s->last_picture_ptr->reference = 3;
|
2014-04-09 15:36:47 +03:00
|
|
|
s->last_picture_ptr->f->key_frame = 0;
|
|
|
|
s->last_picture_ptr->f->pict_type = AV_PICTURE_TYPE_P;
|
2013-11-28 12:54:35 +03:00
|
|
|
|
2020-03-10 15:14:14 +02:00
|
|
|
if (alloc_picture(s, s->last_picture_ptr) < 0) {
|
2013-03-07 18:37:45 +03:00
|
|
|
s->last_picture_ptr = NULL;
|
|
|
|
return -1;
|
2009-11-30 23:22:01 +02:00
|
|
|
}
|
2011-10-18 15:56:59 +03:00
|
|
|
|
2017-10-22 04:40:03 +02:00
|
|
|
if (!avctx->hwaccel) {
|
2013-03-13 15:08:04 +03:00
|
|
|
for(i=0; i<avctx->height; i++)
|
2014-04-09 15:36:47 +03:00
|
|
|
memset(s->last_picture_ptr->f->data[0] + s->last_picture_ptr->f->linesize[0]*i,
|
2014-02-25 13:47:28 +03:00
|
|
|
0x80, avctx->width);
|
2015-05-09 16:20:12 +02:00
|
|
|
if (s->last_picture_ptr->f->data[2]) {
|
2016-01-27 17:19:38 +02:00
|
|
|
for(i=0; i<AV_CEIL_RSHIFT(avctx->height, v_chroma_shift); i++) {
|
2015-05-09 16:20:12 +02:00
|
|
|
memset(s->last_picture_ptr->f->data[1] + s->last_picture_ptr->f->linesize[1]*i,
|
2016-01-27 17:19:38 +02:00
|
|
|
0x80, AV_CEIL_RSHIFT(avctx->width, h_chroma_shift));
|
2015-05-09 16:20:12 +02:00
|
|
|
memset(s->last_picture_ptr->f->data[2] + s->last_picture_ptr->f->linesize[2]*i,
|
2016-01-27 17:19:38 +02:00
|
|
|
0x80, AV_CEIL_RSHIFT(avctx->width, h_chroma_shift));
|
2015-05-09 16:20:12 +02:00
|
|
|
}
|
2014-02-25 13:47:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if(s->codec_id == AV_CODEC_ID_FLV1 || s->codec_id == AV_CODEC_ID_H263){
|
|
|
|
for(i=0; i<avctx->height; i++)
|
2014-04-09 15:36:47 +03:00
|
|
|
memset(s->last_picture_ptr->f->data[0] + s->last_picture_ptr->f->linesize[0]*i, 16, avctx->width);
|
2014-02-25 13:47:28 +03:00
|
|
|
}
|
2014-02-25 13:47:27 +03:00
|
|
|
}
|
2013-03-13 15:08:04 +03:00
|
|
|
|
2013-03-07 18:37:45 +03:00
|
|
|
ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 0);
|
|
|
|
ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1);
|
|
|
|
}
|
2014-08-14 23:31:24 +03:00
|
|
|
if ((!s->next_picture_ptr || !s->next_picture_ptr->f->buf[0]) &&
|
2013-03-07 18:37:45 +03:00
|
|
|
s->pict_type == AV_PICTURE_TYPE_B) {
|
|
|
|
/* Allocate a dummy frame */
|
2015-04-27 23:09:21 +02:00
|
|
|
i = ff_find_unused_picture(s->avctx, s->picture, 0);
|
2013-03-07 18:37:45 +03:00
|
|
|
if (i < 0) {
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
|
|
|
|
return i;
|
2012-11-21 23:34:46 +03:00
|
|
|
}
|
2013-03-07 18:37:45 +03:00
|
|
|
s->next_picture_ptr = &s->picture[i];
|
2013-11-28 12:54:35 +03:00
|
|
|
|
|
|
|
s->next_picture_ptr->reference = 3;
|
2014-04-09 15:36:47 +03:00
|
|
|
s->next_picture_ptr->f->key_frame = 0;
|
|
|
|
s->next_picture_ptr->f->pict_type = AV_PICTURE_TYPE_P;
|
2013-11-28 12:54:35 +03:00
|
|
|
|
2020-03-10 15:14:14 +02:00
|
|
|
if (alloc_picture(s, s->next_picture_ptr) < 0) {
|
2013-03-07 18:37:45 +03:00
|
|
|
s->next_picture_ptr = NULL;
|
|
|
|
return -1;
|
2009-11-30 23:22:01 +02:00
|
|
|
}
|
2013-03-07 18:37:45 +03:00
|
|
|
ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 0);
|
|
|
|
ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 1);
|
|
|
|
}
|
2009-11-30 23:22:01 +02:00
|
|
|
|
2013-03-12 05:20:18 +03:00
|
|
|
#if 0 // BUFREF-FIXME
|
2014-04-09 15:36:47 +03:00
|
|
|
memset(s->last_picture.f->data, 0, sizeof(s->last_picture.f->data));
|
|
|
|
memset(s->next_picture.f->data, 0, sizeof(s->next_picture.f->data));
|
2013-03-12 05:20:18 +03:00
|
|
|
#endif
|
2013-03-07 18:37:45 +03:00
|
|
|
if (s->last_picture_ptr) {
|
2014-03-31 20:46:29 +03:00
|
|
|
if (s->last_picture_ptr->f->buf[0] &&
|
2015-04-27 23:09:20 +02:00
|
|
|
(ret = ff_mpeg_ref_picture(s->avctx, &s->last_picture,
|
2013-03-07 18:37:45 +03:00
|
|
|
s->last_picture_ptr)) < 0)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
if (s->next_picture_ptr) {
|
2014-03-31 20:46:29 +03:00
|
|
|
if (s->next_picture_ptr->f->buf[0] &&
|
2015-04-27 23:09:20 +02:00
|
|
|
(ret = ff_mpeg_ref_picture(s->avctx, &s->next_picture,
|
2013-03-07 18:37:45 +03:00
|
|
|
s->next_picture_ptr)) < 0)
|
|
|
|
return ret;
|
|
|
|
}
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2013-07-26 22:46:47 +03:00
|
|
|
av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
|
2014-04-09 15:36:47 +03:00
|
|
|
s->last_picture_ptr->f->buf[0]));
|
2012-01-10 17:08:20 +03:00
|
|
|
|
2013-03-07 18:35:57 +03:00
|
|
|
if (s->picture_structure!= PICT_FRAME) {
|
2003-03-16 22:22:22 +02:00
|
|
|
int i;
|
2011-12-25 20:58:01 +03:00
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
if (s->picture_structure == PICT_BOTTOM_FIELD) {
|
2014-03-31 20:46:29 +03:00
|
|
|
s->current_picture.f->data[i] +=
|
|
|
|
s->current_picture.f->linesize[i];
|
2005-12-17 20:14:38 +02:00
|
|
|
}
|
2014-03-31 20:46:29 +03:00
|
|
|
s->current_picture.f->linesize[i] *= 2;
|
|
|
|
s->last_picture.f->linesize[i] *= 2;
|
|
|
|
s->next_picture.f->linesize[i] *= 2;
|
2003-03-16 22:22:22 +02:00
|
|
|
}
|
|
|
|
}
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2011-12-25 20:58:01 +03:00
|
|
|
/* set dequantizer, we can't do it during init as
|
2016-04-27 19:45:23 +02:00
|
|
|
* it might change for MPEG-4 and we can't do it in the header
|
|
|
|
* decode as init is not called for MPEG-4 there yet */
|
2012-08-05 12:11:04 +03:00
|
|
|
if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
|
2003-12-14 04:57:00 +02:00
|
|
|
s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;
|
|
|
|
s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;
|
2011-12-25 20:58:01 +03:00
|
|
|
} else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
|
2003-12-14 04:57:00 +02:00
|
|
|
s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
|
|
|
|
s->dct_unquantize_inter = s->dct_unquantize_h263_inter;
|
2011-12-25 20:58:01 +03:00
|
|
|
} else {
|
2003-12-14 04:57:00 +02:00
|
|
|
s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;
|
|
|
|
s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;
|
|
|
|
}
|
2002-10-27 02:02:23 +02:00
|
|
|
|
2014-05-02 16:57:59 +03:00
|
|
|
if (s->avctx->debug & FF_DEBUG_NOMC) {
|
|
|
|
gray_frame(s->current_picture_ptr->f);
|
|
|
|
}
|
|
|
|
|
2002-10-27 02:02:23 +02:00
|
|
|
return 0;
|
2001-07-22 17:18:56 +03:00
|
|
|
}
|
2001-07-31 02:26:26 +03:00
|
|
|
|
2013-11-30 13:34:37 +03:00
|
|
|
/* called after a frame has been decoded. */
|
2014-08-10 18:25:12 +03:00
|
|
|
void ff_mpv_frame_end(MpegEncContext *s)
|
2001-07-22 17:18:56 +03:00
|
|
|
{
|
2002-01-15 07:02:26 +02:00
|
|
|
emms_c();
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2013-03-07 18:35:57 +03:00
|
|
|
if (s->current_picture.reference)
|
2012-11-21 23:34:46 +03:00
|
|
|
ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
|
2001-07-22 17:18:56 +03:00
|
|
|
}
|
|
|
|
|
2013-03-12 13:23:07 +03:00
|
|
|
void ff_print_debug_info(MpegEncContext *s, Picture *p, AVFrame *pict)
|
2013-02-19 04:46:05 +03:00
|
|
|
{
|
2014-03-28 00:14:26 +03:00
|
|
|
ff_print_debug_info2(s->avctx, pict, s->mbskip_table, p->mb_type,
|
|
|
|
p->qscale_table, p->motion_val, &s->low_delay,
|
2013-03-12 05:20:18 +03:00
|
|
|
s->mb_width, s->mb_height, s->mb_stride, s->quarter_sample);
|
2013-02-19 04:46:05 +03:00
|
|
|
}
|
|
|
|
|
2013-03-15 16:33:24 +03:00
|
|
|
int ff_mpv_export_qp_table(MpegEncContext *s, AVFrame *f, Picture *p, int qp_type)
|
|
|
|
{
|
2020-03-10 12:45:55 +02:00
|
|
|
AVVideoEncParams *par;
|
|
|
|
int mult = (qp_type == FF_QSCALE_TYPE_MPEG1) ? 2 : 1;
|
|
|
|
unsigned int nb_mb = p->alloc_mb_height * p->alloc_mb_width;
|
|
|
|
unsigned int x, y;
|
|
|
|
|
|
|
|
if (!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
par = av_video_enc_params_create_side_data(f, AV_VIDEO_ENC_PARAMS_MPEG2, nb_mb);
|
|
|
|
if (!par)
|
2013-03-15 16:33:24 +03:00
|
|
|
return AVERROR(ENOMEM);
|
2020-03-10 12:45:55 +02:00
|
|
|
|
|
|
|
for (y = 0; y < p->alloc_mb_height; y++)
|
|
|
|
for (x = 0; x < p->alloc_mb_width; x++) {
|
|
|
|
const unsigned int block_idx = y * p->alloc_mb_width + x;
|
|
|
|
const unsigned int mb_xy = y * p->alloc_mb_stride + x;
|
|
|
|
AVVideoBlockParams *b = av_video_enc_params_block(par, block_idx);
|
|
|
|
|
|
|
|
b->src_x = x * 16;
|
|
|
|
b->src_y = y * 16;
|
|
|
|
b->w = 16;
|
|
|
|
b->h = 16;
|
|
|
|
|
|
|
|
b->delta_qp = p->qscale_table[mb_xy] * mult;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2013-03-15 16:33:24 +03:00
|
|
|
}
|
|
|
|
|
2012-05-25 13:35:42 +03:00
|
|
|
static inline int hpel_motion_lowres(MpegEncContext *s,
|
|
|
|
uint8_t *dest, uint8_t *src,
|
|
|
|
int field_based, int field_select,
|
|
|
|
int src_x, int src_y,
|
2013-09-28 03:13:59 +03:00
|
|
|
int width, int height, ptrdiff_t stride,
|
2012-05-25 13:35:42 +03:00
|
|
|
int h_edge_pos, int v_edge_pos,
|
|
|
|
int w, int h, h264_chroma_mc_func *pix_op,
|
|
|
|
int motion_x, int motion_y)
|
|
|
|
{
|
|
|
|
const int lowres = s->avctx->lowres;
|
2013-05-29 20:41:55 +03:00
|
|
|
const int op_index = FFMIN(lowres, 3);
|
2012-05-25 13:35:42 +03:00
|
|
|
const int s_mask = (2 << lowres) - 1;
|
|
|
|
int emu = 0;
|
|
|
|
int sx, sy;
|
|
|
|
|
|
|
|
if (s->quarter_sample) {
|
|
|
|
motion_x /= 2;
|
|
|
|
motion_y /= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
sx = motion_x & s_mask;
|
|
|
|
sy = motion_y & s_mask;
|
|
|
|
src_x += motion_x >> lowres + 1;
|
|
|
|
src_y += motion_y >> lowres + 1;
|
|
|
|
|
|
|
|
src += src_y * stride + src_x;
|
|
|
|
|
|
|
|
if ((unsigned)src_x > FFMAX( h_edge_pos - (!!sx) - w, 0) ||
|
|
|
|
(unsigned)src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
|
2015-06-08 20:58:13 +02:00
|
|
|
s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src,
|
2013-11-15 15:56:05 +03:00
|
|
|
s->linesize, s->linesize,
|
|
|
|
w + 1, (h + 1) << field_based,
|
|
|
|
src_x, src_y << field_based,
|
|
|
|
h_edge_pos, v_edge_pos);
|
2015-06-08 20:58:13 +02:00
|
|
|
src = s->sc.edge_emu_buffer;
|
2012-05-25 13:35:42 +03:00
|
|
|
emu = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sx = (sx << 2) >> lowres;
|
|
|
|
sy = (sy << 2) >> lowres;
|
|
|
|
if (field_select)
|
|
|
|
src += s->linesize;
|
|
|
|
pix_op[op_index](dest, src, stride, h, sx, sy);
|
|
|
|
return emu;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* apply one mpeg motion vector to the three components */
|
|
|
|
static av_always_inline void mpeg_motion_lowres(MpegEncContext *s,
|
|
|
|
uint8_t *dest_y,
|
|
|
|
uint8_t *dest_cb,
|
|
|
|
uint8_t *dest_cr,
|
|
|
|
int field_based,
|
|
|
|
int bottom_field,
|
|
|
|
int field_select,
|
|
|
|
uint8_t **ref_picture,
|
|
|
|
h264_chroma_mc_func *pix_op,
|
|
|
|
int motion_x, int motion_y,
|
|
|
|
int h, int mb_y)
|
|
|
|
{
|
|
|
|
uint8_t *ptr_y, *ptr_cb, *ptr_cr;
|
2013-09-28 03:13:59 +03:00
|
|
|
int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, sx, sy, uvsx, uvsy;
|
|
|
|
ptrdiff_t uvlinesize, linesize;
|
2012-05-25 13:35:42 +03:00
|
|
|
const int lowres = s->avctx->lowres;
|
2013-05-29 20:55:27 +03:00
|
|
|
const int op_index = FFMIN(lowres-1+s->chroma_x_shift, 3);
|
2012-05-25 13:35:42 +03:00
|
|
|
const int block_s = 8>>lowres;
|
|
|
|
const int s_mask = (2 << lowres) - 1;
|
|
|
|
const int h_edge_pos = s->h_edge_pos >> lowres;
|
|
|
|
const int v_edge_pos = s->v_edge_pos >> lowres;
|
2014-04-09 15:36:47 +03:00
|
|
|
linesize = s->current_picture.f->linesize[0] << field_based;
|
|
|
|
uvlinesize = s->current_picture.f->linesize[1] << field_based;
|
2012-05-25 13:35:42 +03:00
|
|
|
|
|
|
|
// FIXME obviously not perfect but qpel will not work in lowres anyway
|
|
|
|
if (s->quarter_sample) {
|
|
|
|
motion_x /= 2;
|
|
|
|
motion_y /= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(field_based){
|
|
|
|
motion_y += (bottom_field - field_select)*((1 << lowres)-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
sx = motion_x & s_mask;
|
|
|
|
sy = motion_y & s_mask;
|
|
|
|
src_x = s->mb_x * 2 * block_s + (motion_x >> lowres + 1);
|
|
|
|
src_y = (mb_y * 2 * block_s >> field_based) + (motion_y >> lowres + 1);
|
|
|
|
|
|
|
|
if (s->out_format == FMT_H263) {
|
|
|
|
uvsx = ((motion_x >> 1) & s_mask) | (sx & 1);
|
|
|
|
uvsy = ((motion_y >> 1) & s_mask) | (sy & 1);
|
|
|
|
uvsrc_x = src_x >> 1;
|
|
|
|
uvsrc_y = src_y >> 1;
|
|
|
|
} else if (s->out_format == FMT_H261) {
|
|
|
|
// even chroma mv's are full pel in H261
|
|
|
|
mx = motion_x / 4;
|
|
|
|
my = motion_y / 4;
|
|
|
|
uvsx = (2 * mx) & s_mask;
|
|
|
|
uvsy = (2 * my) & s_mask;
|
|
|
|
uvsrc_x = s->mb_x * block_s + (mx >> lowres);
|
|
|
|
uvsrc_y = mb_y * block_s + (my >> lowres);
|
|
|
|
} else {
|
|
|
|
if(s->chroma_y_shift){
|
|
|
|
mx = motion_x / 2;
|
|
|
|
my = motion_y / 2;
|
|
|
|
uvsx = mx & s_mask;
|
|
|
|
uvsy = my & s_mask;
|
|
|
|
uvsrc_x = s->mb_x * block_s + (mx >> lowres + 1);
|
|
|
|
uvsrc_y = (mb_y * block_s >> field_based) + (my >> lowres + 1);
|
|
|
|
} else {
|
|
|
|
if(s->chroma_x_shift){
|
|
|
|
//Chroma422
|
|
|
|
mx = motion_x / 2;
|
|
|
|
uvsx = mx & s_mask;
|
|
|
|
uvsy = motion_y & s_mask;
|
|
|
|
uvsrc_y = src_y;
|
|
|
|
uvsrc_x = s->mb_x*block_s + (mx >> (lowres+1));
|
|
|
|
} else {
|
|
|
|
//Chroma444
|
|
|
|
uvsx = motion_x & s_mask;
|
|
|
|
uvsy = motion_y & s_mask;
|
|
|
|
uvsrc_x = src_x;
|
|
|
|
uvsrc_y = src_y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ptr_y = ref_picture[0] + src_y * linesize + src_x;
|
|
|
|
ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
|
|
|
|
ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
|
|
|
|
|
2013-05-08 02:18:56 +03:00
|
|
|
if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s, 0) || uvsrc_y<0 ||
|
2012-05-25 13:35:42 +03:00
|
|
|
(unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
|
2015-06-08 20:58:13 +02:00
|
|
|
s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y,
|
2013-11-15 15:56:05 +03:00
|
|
|
linesize >> field_based, linesize >> field_based,
|
|
|
|
17, 17 + field_based,
|
2012-05-25 13:35:42 +03:00
|
|
|
src_x, src_y << field_based, h_edge_pos,
|
|
|
|
v_edge_pos);
|
2015-06-08 20:58:13 +02:00
|
|
|
ptr_y = s->sc.edge_emu_buffer;
|
2015-07-27 21:14:31 +02:00
|
|
|
if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
|
2015-06-08 20:58:13 +02:00
|
|
|
uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize;
|
2016-11-12 13:31:34 +02:00
|
|
|
uint8_t *vbuf =ubuf + 10 * s->uvlinesize;
|
2016-11-12 13:31:35 +02:00
|
|
|
if (s->workaround_bugs & FF_BUG_IEDGE)
|
|
|
|
vbuf -= s->uvlinesize;
|
2014-06-13 02:45:23 +03:00
|
|
|
s->vdsp.emulated_edge_mc(ubuf, ptr_cb,
|
2013-11-15 15:56:05 +03:00
|
|
|
uvlinesize >> field_based, uvlinesize >> field_based,
|
|
|
|
9, 9 + field_based,
|
2012-05-25 13:35:42 +03:00
|
|
|
uvsrc_x, uvsrc_y << field_based,
|
|
|
|
h_edge_pos >> 1, v_edge_pos >> 1);
|
2014-06-13 02:45:23 +03:00
|
|
|
s->vdsp.emulated_edge_mc(vbuf, ptr_cr,
|
2013-11-15 15:56:05 +03:00
|
|
|
uvlinesize >> field_based,uvlinesize >> field_based,
|
|
|
|
9, 9 + field_based,
|
2012-05-25 13:35:42 +03:00
|
|
|
uvsrc_x, uvsrc_y << field_based,
|
|
|
|
h_edge_pos >> 1, v_edge_pos >> 1);
|
2014-06-13 02:45:23 +03:00
|
|
|
ptr_cb = ubuf;
|
|
|
|
ptr_cr = vbuf;
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-09 15:36:47 +03:00
|
|
|
// FIXME use this for field pix too instead of the obnoxious hack which changes picture.f->data
|
2012-05-25 13:35:42 +03:00
|
|
|
if (bottom_field) {
|
|
|
|
dest_y += s->linesize;
|
|
|
|
dest_cb += s->uvlinesize;
|
|
|
|
dest_cr += s->uvlinesize;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (field_select) {
|
|
|
|
ptr_y += s->linesize;
|
|
|
|
ptr_cb += s->uvlinesize;
|
|
|
|
ptr_cr += s->uvlinesize;
|
|
|
|
}
|
|
|
|
|
|
|
|
sx = (sx << 2) >> lowres;
|
|
|
|
sy = (sy << 2) >> lowres;
|
|
|
|
pix_op[lowres - 1](dest_y, ptr_y, linesize, h, sx, sy);
|
|
|
|
|
2015-07-27 21:14:31 +02:00
|
|
|
if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
|
2013-05-08 02:17:45 +03:00
|
|
|
int hc = s->chroma_y_shift ? (h+1-bottom_field)>>1 : h;
|
2012-05-25 13:35:42 +03:00
|
|
|
uvsx = (uvsx << 2) >> lowres;
|
|
|
|
uvsy = (uvsy << 2) >> lowres;
|
2013-05-08 02:17:45 +03:00
|
|
|
if (hc) {
|
|
|
|
pix_op[op_index](dest_cb, ptr_cb, uvlinesize, hc, uvsx, uvsy);
|
|
|
|
pix_op[op_index](dest_cr, ptr_cr, uvlinesize, hc, uvsx, uvsy);
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// FIXME h261 lowres loop filter
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void chroma_4mv_motion_lowres(MpegEncContext *s,
|
|
|
|
uint8_t *dest_cb, uint8_t *dest_cr,
|
|
|
|
uint8_t **ref_picture,
|
|
|
|
h264_chroma_mc_func * pix_op,
|
|
|
|
int mx, int my)
|
|
|
|
{
|
|
|
|
const int lowres = s->avctx->lowres;
|
2013-05-29 20:55:27 +03:00
|
|
|
const int op_index = FFMIN(lowres, 3);
|
2012-05-25 13:35:42 +03:00
|
|
|
const int block_s = 8 >> lowres;
|
|
|
|
const int s_mask = (2 << lowres) - 1;
|
|
|
|
const int h_edge_pos = s->h_edge_pos >> lowres + 1;
|
|
|
|
const int v_edge_pos = s->v_edge_pos >> lowres + 1;
|
2013-09-28 03:13:59 +03:00
|
|
|
int emu = 0, src_x, src_y, sx, sy;
|
|
|
|
ptrdiff_t offset;
|
2012-05-25 13:35:42 +03:00
|
|
|
uint8_t *ptr;
|
|
|
|
|
|
|
|
if (s->quarter_sample) {
|
|
|
|
mx /= 2;
|
|
|
|
my /= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* In case of 8X8, we construct a single chroma motion vector
|
|
|
|
with a special rounding */
|
|
|
|
mx = ff_h263_round_chroma(mx);
|
|
|
|
my = ff_h263_round_chroma(my);
|
|
|
|
|
|
|
|
sx = mx & s_mask;
|
|
|
|
sy = my & s_mask;
|
|
|
|
src_x = s->mb_x * block_s + (mx >> lowres + 1);
|
|
|
|
src_y = s->mb_y * block_s + (my >> lowres + 1);
|
|
|
|
|
|
|
|
offset = src_y * s->uvlinesize + src_x;
|
|
|
|
ptr = ref_picture[1] + offset;
|
2013-09-24 18:14:21 +03:00
|
|
|
if ((unsigned) src_x > FFMAX(h_edge_pos - (!!sx) - block_s, 0) ||
|
|
|
|
(unsigned) src_y > FFMAX(v_edge_pos - (!!sy) - block_s, 0)) {
|
2015-06-08 20:58:13 +02:00
|
|
|
s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
|
2013-11-15 15:56:05 +03:00
|
|
|
s->uvlinesize, s->uvlinesize,
|
|
|
|
9, 9,
|
|
|
|
src_x, src_y, h_edge_pos, v_edge_pos);
|
2015-06-08 20:58:13 +02:00
|
|
|
ptr = s->sc.edge_emu_buffer;
|
2013-09-24 18:14:21 +03:00
|
|
|
emu = 1;
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
|
|
|
sx = (sx << 2) >> lowres;
|
|
|
|
sy = (sy << 2) >> lowres;
|
|
|
|
pix_op[op_index](dest_cb, ptr, s->uvlinesize, block_s, sx, sy);
|
|
|
|
|
|
|
|
ptr = ref_picture[2] + offset;
|
|
|
|
if (emu) {
|
2015-06-08 20:58:13 +02:00
|
|
|
s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
|
2013-11-15 15:56:05 +03:00
|
|
|
s->uvlinesize, s->uvlinesize,
|
|
|
|
9, 9,
|
|
|
|
src_x, src_y, h_edge_pos, v_edge_pos);
|
2015-06-08 20:58:13 +02:00
|
|
|
ptr = s->sc.edge_emu_buffer;
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
|
|
|
pix_op[op_index](dest_cr, ptr, s->uvlinesize, block_s, sx, sy);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* motion compensation of a single macroblock
|
|
|
|
* @param s context
|
|
|
|
* @param dest_y luma destination pointer
|
|
|
|
* @param dest_cb chroma cb/u destination pointer
|
|
|
|
* @param dest_cr chroma cr/v destination pointer
|
|
|
|
* @param dir direction (0->forward, 1->backward)
|
|
|
|
* @param ref_picture array[3] of pointers to the 3 planes of the reference picture
|
|
|
|
* @param pix_op halfpel motion compensation function (average or put normally)
|
|
|
|
* the motion vectors are taken from s->mv and the MV type from s->mv_type
|
|
|
|
*/
|
|
|
|
static inline void MPV_motion_lowres(MpegEncContext *s,
|
|
|
|
uint8_t *dest_y, uint8_t *dest_cb,
|
|
|
|
uint8_t *dest_cr,
|
|
|
|
int dir, uint8_t **ref_picture,
|
|
|
|
h264_chroma_mc_func *pix_op)
|
|
|
|
{
|
|
|
|
int mx, my;
|
|
|
|
int mb_x, mb_y, i;
|
|
|
|
const int lowres = s->avctx->lowres;
|
|
|
|
const int block_s = 8 >>lowres;
|
|
|
|
|
|
|
|
mb_x = s->mb_x;
|
|
|
|
mb_y = s->mb_y;
|
|
|
|
|
|
|
|
switch (s->mv_type) {
|
|
|
|
case MV_TYPE_16X16:
|
|
|
|
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
|
|
|
|
0, 0, 0,
|
|
|
|
ref_picture, pix_op,
|
|
|
|
s->mv[dir][0][0], s->mv[dir][0][1],
|
|
|
|
2 * block_s, mb_y);
|
|
|
|
break;
|
|
|
|
case MV_TYPE_8X8:
|
|
|
|
mx = 0;
|
|
|
|
my = 0;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
hpel_motion_lowres(s, dest_y + ((i & 1) + (i >> 1) *
|
|
|
|
s->linesize) * block_s,
|
|
|
|
ref_picture[0], 0, 0,
|
|
|
|
(2 * mb_x + (i & 1)) * block_s,
|
|
|
|
(2 * mb_y + (i >> 1)) * block_s,
|
|
|
|
s->width, s->height, s->linesize,
|
|
|
|
s->h_edge_pos >> lowres, s->v_edge_pos >> lowres,
|
|
|
|
block_s, block_s, pix_op,
|
|
|
|
s->mv[dir][i][0], s->mv[dir][i][1]);
|
|
|
|
|
|
|
|
mx += s->mv[dir][i][0];
|
|
|
|
my += s->mv[dir][i][1];
|
|
|
|
}
|
|
|
|
|
2015-07-27 21:14:31 +02:00
|
|
|
if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
|
2012-05-25 13:35:42 +03:00
|
|
|
chroma_4mv_motion_lowres(s, dest_cb, dest_cr, ref_picture,
|
|
|
|
pix_op, mx, my);
|
|
|
|
break;
|
|
|
|
case MV_TYPE_FIELD:
|
|
|
|
if (s->picture_structure == PICT_FRAME) {
|
|
|
|
/* top field */
|
|
|
|
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
|
|
|
|
1, 0, s->field_select[dir][0],
|
|
|
|
ref_picture, pix_op,
|
|
|
|
s->mv[dir][0][0], s->mv[dir][0][1],
|
|
|
|
block_s, mb_y);
|
|
|
|
/* bottom field */
|
|
|
|
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
|
|
|
|
1, 1, s->field_select[dir][1],
|
|
|
|
ref_picture, pix_op,
|
|
|
|
s->mv[dir][1][0], s->mv[dir][1][1],
|
|
|
|
block_s, mb_y);
|
|
|
|
} else {
|
|
|
|
if (s->picture_structure != s->field_select[dir][0] + 1 &&
|
|
|
|
s->pict_type != AV_PICTURE_TYPE_B && !s->first_field) {
|
2014-04-09 15:36:47 +03:00
|
|
|
ref_picture = s->current_picture_ptr->f->data;
|
2012-05-25 13:35:42 +03:00
|
|
|
|
|
|
|
}
|
|
|
|
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
|
|
|
|
0, 0, s->field_select[dir][0],
|
|
|
|
ref_picture, pix_op,
|
|
|
|
s->mv[dir][0][0],
|
|
|
|
s->mv[dir][0][1], 2 * block_s, mb_y >> 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MV_TYPE_16X8:
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
uint8_t **ref2picture;
|
|
|
|
|
|
|
|
if (s->picture_structure == s->field_select[dir][i] + 1 ||
|
|
|
|
s->pict_type == AV_PICTURE_TYPE_B || s->first_field) {
|
|
|
|
ref2picture = ref_picture;
|
|
|
|
} else {
|
2014-04-09 15:36:47 +03:00
|
|
|
ref2picture = s->current_picture_ptr->f->data;
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
|
|
|
|
0, 0, s->field_select[dir][i],
|
|
|
|
ref2picture, pix_op,
|
|
|
|
s->mv[dir][i][0], s->mv[dir][i][1] +
|
|
|
|
2 * block_s * i, block_s, mb_y >> 1);
|
|
|
|
|
|
|
|
dest_y += 2 * block_s * s->linesize;
|
|
|
|
dest_cb += (2 * block_s >> s->chroma_y_shift) * s->uvlinesize;
|
|
|
|
dest_cr += (2 * block_s >> s->chroma_y_shift) * s->uvlinesize;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MV_TYPE_DMV:
|
|
|
|
if (s->picture_structure == PICT_FRAME) {
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
int j;
|
|
|
|
for (j = 0; j < 2; j++) {
|
|
|
|
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
|
|
|
|
1, j, j ^ i,
|
|
|
|
ref_picture, pix_op,
|
|
|
|
s->mv[dir][2 * i + j][0],
|
|
|
|
s->mv[dir][2 * i + j][1],
|
|
|
|
block_s, mb_y);
|
|
|
|
}
|
2013-02-07 15:09:35 +03:00
|
|
|
pix_op = s->h264chroma.avg_h264_chroma_pixels_tab;
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
|
|
|
|
0, 0, s->picture_structure != i + 1,
|
|
|
|
ref_picture, pix_op,
|
|
|
|
s->mv[dir][2 * i][0],s->mv[dir][2 * i][1],
|
|
|
|
2 * block_s, mb_y >> 1);
|
|
|
|
|
|
|
|
// after put we make avg of the same block
|
2013-02-07 15:09:35 +03:00
|
|
|
pix_op = s->h264chroma.avg_h264_chroma_pixels_tab;
|
2012-05-25 13:35:42 +03:00
|
|
|
|
|
|
|
// opposite parity is always in the same
|
|
|
|
// frame if this is second field
|
|
|
|
if (!s->first_field) {
|
2014-04-09 15:36:47 +03:00
|
|
|
ref_picture = s->current_picture_ptr->f->data;
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2012-08-06 17:40:22 +03:00
|
|
|
av_assert2(0);
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-22 23:36:57 +02:00
|
|
|
/**
|
|
|
|
* find the lowest MB row referenced in the MVs
|
|
|
|
*/
|
2015-06-08 14:00:52 +02:00
|
|
|
static int lowest_referenced_row(MpegEncContext *s, int dir)
|
2011-03-22 23:36:57 +02:00
|
|
|
{
|
|
|
|
int my_max = INT_MIN, my_min = INT_MAX, qpel_shift = !s->quarter_sample;
|
|
|
|
int my, off, i, mvs;
|
|
|
|
|
2012-10-12 23:38:54 +03:00
|
|
|
if (s->picture_structure != PICT_FRAME || s->mcsel)
|
|
|
|
goto unhandled;
|
2011-03-22 23:36:57 +02:00
|
|
|
|
|
|
|
switch (s->mv_type) {
|
|
|
|
case MV_TYPE_16X16:
|
|
|
|
mvs = 1;
|
|
|
|
break;
|
|
|
|
case MV_TYPE_16X8:
|
|
|
|
mvs = 2;
|
|
|
|
break;
|
|
|
|
case MV_TYPE_8X8:
|
|
|
|
mvs = 4;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto unhandled;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < mvs; i++) {
|
2015-03-11 18:59:59 +02:00
|
|
|
my = s->mv[dir][i][1];
|
2011-03-22 23:36:57 +02:00
|
|
|
my_max = FFMAX(my_max, my);
|
|
|
|
my_min = FFMIN(my_min, my);
|
|
|
|
}
|
|
|
|
|
2015-03-11 18:59:59 +02:00
|
|
|
off = ((FFMAX(-my_min, my_max)<<qpel_shift) + 63) >> 6;
|
2011-03-22 23:36:57 +02:00
|
|
|
|
2015-06-06 12:55:20 +02:00
|
|
|
return av_clip(s->mb_y + off, 0, s->mb_height - 1);
|
2011-03-22 23:36:57 +02:00
|
|
|
unhandled:
|
|
|
|
return s->mb_height-1;
|
|
|
|
}
|
|
|
|
|
2007-07-03 12:55:56 +03:00
|
|
|
/* put block[] to dest[] */
|
|
|
|
static inline void put_dct(MpegEncContext *s,
|
2013-01-20 03:02:29 +03:00
|
|
|
int16_t *block, int i, uint8_t *dest, int line_size, int qscale)
|
2004-09-26 02:18:58 +03:00
|
|
|
{
|
2007-07-03 12:55:56 +03:00
|
|
|
s->dct_unquantize_intra(s, block, i, qscale);
|
2014-01-24 13:55:16 +03:00
|
|
|
s->idsp.idct_put(dest, line_size, block);
|
2007-07-03 12:55:56 +03:00
|
|
|
}
|
2004-09-26 14:05:35 +03:00
|
|
|
|
2007-07-03 12:55:56 +03:00
|
|
|
/* add block[] to dest[] */
|
|
|
|
static inline void add_dct(MpegEncContext *s,
|
2013-01-20 03:02:29 +03:00
|
|
|
int16_t *block, int i, uint8_t *dest, int line_size)
|
2007-07-03 12:55:56 +03:00
|
|
|
{
|
|
|
|
if (s->block_last_index[i] >= 0) {
|
2014-01-24 13:55:16 +03:00
|
|
|
s->idsp.idct_add(dest, line_size, block);
|
2007-07-03 12:55:56 +03:00
|
|
|
}
|
|
|
|
}
|
2002-04-27 16:12:57 +03:00
|
|
|
|
2005-12-17 20:14:38 +02:00
|
|
|
static inline void add_dequant_dct(MpegEncContext *s,
|
2013-01-20 03:02:29 +03:00
|
|
|
int16_t *block, int i, uint8_t *dest, int line_size, int qscale)
|
2002-06-06 02:43:56 +03:00
|
|
|
{
|
2001-07-22 17:18:56 +03:00
|
|
|
if (s->block_last_index[i] >= 0) {
|
2003-12-14 04:57:00 +02:00
|
|
|
s->dct_unquantize_inter(s, block, i, qscale);
|
2002-04-17 07:32:12 +03:00
|
|
|
|
2014-01-24 13:55:16 +03:00
|
|
|
s->idsp.idct_add(dest, line_size, block);
|
2001-07-22 17:18:56 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-02 15:20:39 +03:00
|
|
|
/**
|
2011-12-07 15:03:53 +03:00
|
|
|
* Clean dc, ac, coded_block for the current non-intra MB.
|
2002-06-02 15:20:39 +03:00
|
|
|
*/
|
|
|
|
void ff_clean_intra_table_entries(MpegEncContext *s)
|
|
|
|
{
|
2004-04-16 04:01:45 +03:00
|
|
|
int wrap = s->b8_stride;
|
2002-06-02 15:20:39 +03:00
|
|
|
int xy = s->block_index[0];
|
2005-12-17 20:14:38 +02:00
|
|
|
|
|
|
|
s->dc_val[0][xy ] =
|
|
|
|
s->dc_val[0][xy + 1 ] =
|
2002-06-02 15:20:39 +03:00
|
|
|
s->dc_val[0][xy + wrap] =
|
|
|
|
s->dc_val[0][xy + 1 + wrap] = 1024;
|
|
|
|
/* ac pred */
|
2003-02-11 18:35:48 +02:00
|
|
|
memset(s->ac_val[0][xy ], 0, 32 * sizeof(int16_t));
|
|
|
|
memset(s->ac_val[0][xy + wrap], 0, 32 * sizeof(int16_t));
|
2002-06-02 15:20:39 +03:00
|
|
|
if (s->msmpeg4_version>=3) {
|
|
|
|
s->coded_block[xy ] =
|
|
|
|
s->coded_block[xy + 1 ] =
|
|
|
|
s->coded_block[xy + wrap] =
|
|
|
|
s->coded_block[xy + 1 + wrap] = 0;
|
|
|
|
}
|
|
|
|
/* chroma */
|
2004-04-16 04:01:45 +03:00
|
|
|
wrap = s->mb_stride;
|
|
|
|
xy = s->mb_x + s->mb_y * wrap;
|
2002-06-02 15:20:39 +03:00
|
|
|
s->dc_val[1][xy] =
|
|
|
|
s->dc_val[2][xy] = 1024;
|
|
|
|
/* ac pred */
|
2003-02-11 18:35:48 +02:00
|
|
|
memset(s->ac_val[1][xy], 0, 16 * sizeof(int16_t));
|
|
|
|
memset(s->ac_val[2][xy], 0, 16 * sizeof(int16_t));
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2004-04-16 04:01:45 +03:00
|
|
|
s->mbintra_table[xy]= 0;
|
2002-06-02 15:20:39 +03:00
|
|
|
}
|
|
|
|
|
2001-07-22 17:18:56 +03:00
|
|
|
/* generic function called after a macroblock has been parsed by the
|
|
|
|
decoder or after it has been encoded by the encoder.
|
|
|
|
|
|
|
|
Important variables used:
|
|
|
|
s->mb_intra : true if intra macroblock
|
|
|
|
s->mv_dir : motion vector direction
|
|
|
|
s->mv_type : motion vector type
|
|
|
|
s->mv : motion vector
|
|
|
|
s->interlaced_dct : true if interlaced dct used (mpeg2)
|
|
|
|
*/
|
2008-04-10 22:09:39 +03:00
|
|
|
static av_always_inline
|
2017-06-18 20:15:05 +02:00
|
|
|
void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64],
|
2012-05-25 13:35:42 +03:00
|
|
|
int lowres_flag, int is_mpeg12)
|
2001-07-22 17:18:56 +03:00
|
|
|
{
|
2003-04-10 16:18:38 +03:00
|
|
|
const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
|
2013-11-05 10:16:31 +03:00
|
|
|
|
2013-12-14 22:29:15 +03:00
|
|
|
if (CONFIG_XVMC &&
|
|
|
|
s->avctx->hwaccel && s->avctx->hwaccel->decode_mb) {
|
|
|
|
s->avctx->hwaccel->decode_mb(s);//xvmc uses pblocks
|
2003-07-26 04:28:49 +03:00
|
|
|
return;
|
|
|
|
}
|
2001-07-22 17:18:56 +03:00
|
|
|
|
2004-02-25 20:29:17 +02:00
|
|
|
if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
|
2012-11-21 23:34:46 +03:00
|
|
|
/* print DCT coefficients */
|
2004-02-25 20:29:17 +02:00
|
|
|
int i,j;
|
2011-02-24 00:38:52 +02:00
|
|
|
av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y);
|
|
|
|
for(i=0; i<6; i++){
|
|
|
|
for(j=0; j<64; j++){
|
2014-01-24 13:55:16 +03:00
|
|
|
av_log(s->avctx, AV_LOG_DEBUG, "%5d",
|
|
|
|
block[i][s->idsp.idct_permutation[j]]);
|
2011-02-24 00:38:52 +02:00
|
|
|
}
|
|
|
|
av_log(s->avctx, AV_LOG_DEBUG, "\n");
|
|
|
|
}
|
2004-02-25 20:29:17 +02:00
|
|
|
}
|
|
|
|
|
2012-11-21 23:34:46 +03:00
|
|
|
s->current_picture.qscale_table[mb_xy] = s->qscale;
|
2001-10-17 02:10:38 +03:00
|
|
|
|
2001-07-22 17:18:56 +03:00
|
|
|
/* update DC predictors for P macroblocks */
|
|
|
|
if (!s->mb_intra) {
|
2008-04-21 11:30:54 +03:00
|
|
|
if (!is_mpeg12 && (s->h263_pred || s->h263_aic)) {
|
2002-06-06 02:43:56 +03:00
|
|
|
if(s->mbintra_table[mb_xy])
|
2002-06-02 15:20:39 +03:00
|
|
|
ff_clean_intra_table_entries(s);
|
2001-07-22 17:18:56 +03:00
|
|
|
} else {
|
2002-06-02 15:20:39 +03:00
|
|
|
s->last_dc[0] =
|
|
|
|
s->last_dc[1] =
|
2001-07-22 17:18:56 +03:00
|
|
|
s->last_dc[2] = 128 << s->intra_dc_precision;
|
|
|
|
}
|
|
|
|
}
|
2008-04-21 11:30:54 +03:00
|
|
|
else if (!is_mpeg12 && (s->h263_pred || s->h263_aic))
|
2002-06-06 02:43:56 +03:00
|
|
|
s->mbintra_table[mb_xy]=1;
|
2002-01-10 02:53:21 +02:00
|
|
|
|
2016-01-28 17:08:10 +02:00
|
|
|
if ((s->avctx->flags & AV_CODEC_FLAG_PSNR) || s->frame_skip_threshold || s->frame_skip_factor ||
|
2015-04-27 20:13:25 +02:00
|
|
|
!(s->encoding && (s->intra_only || s->pict_type == AV_PICTURE_TYPE_B) &&
|
|
|
|
s->avctx->mb_decision != FF_MB_DECISION_RD)) { // FIXME precalc
|
2003-02-11 18:35:48 +02:00
|
|
|
uint8_t *dest_y, *dest_cb, *dest_cr;
|
2002-06-06 02:43:56 +03:00
|
|
|
int dct_linesize, dct_offset;
|
2002-09-11 15:39:53 +03:00
|
|
|
op_pixels_func (*op_pix)[4];
|
|
|
|
qpel_mc_func (*op_qpix)[16];
|
2014-03-31 20:46:29 +03:00
|
|
|
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];
|
2012-05-25 13:35:42 +03:00
|
|
|
const int readable= s->pict_type != AV_PICTURE_TYPE_B || s->encoding || s->avctx->draw_horiz_band || lowres_flag;
|
|
|
|
const int block_size= lowres_flag ? 8>>s->avctx->lowres : 8;
|
2001-07-24 23:43:41 +03:00
|
|
|
|
2002-12-04 12:04:03 +02:00
|
|
|
/* avoid copy if macroblock skipped in last frame too */
|
|
|
|
/* skip only during decoding as we might trash the buffers during encoding a bit */
|
|
|
|
if(!s->encoding){
|
2003-02-11 18:35:48 +02:00
|
|
|
uint8_t *mbskip_ptr = &s->mbskip_table[mb_xy];
|
2002-12-04 12:04:03 +02:00
|
|
|
|
2005-04-24 20:21:11 +03:00
|
|
|
if (s->mb_skipped) {
|
|
|
|
s->mb_skipped= 0;
|
2012-08-06 17:40:22 +03:00
|
|
|
av_assert2(s->pict_type!=AV_PICTURE_TYPE_I);
|
2011-12-18 23:41:42 +03:00
|
|
|
*mbskip_ptr = 1;
|
2012-11-21 23:34:46 +03:00
|
|
|
} else if(!s->current_picture.reference) {
|
2011-12-18 23:41:42 +03:00
|
|
|
*mbskip_ptr = 1;
|
2003-01-20 22:37:24 +02:00
|
|
|
} else{
|
2001-07-24 23:43:41 +03:00
|
|
|
*mbskip_ptr = 0; /* not skipped */
|
|
|
|
}
|
2002-10-02 20:07:39 +03:00
|
|
|
}
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2004-06-11 10:59:12 +03:00
|
|
|
dct_linesize = linesize << s->interlaced_dct;
|
2012-01-07 21:07:42 +03:00
|
|
|
dct_offset = s->interlaced_dct ? linesize : linesize * block_size;
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2003-11-27 15:38:00 +02:00
|
|
|
if(readable){
|
|
|
|
dest_y= s->dest[0];
|
|
|
|
dest_cb= s->dest[1];
|
|
|
|
dest_cr= s->dest[2];
|
|
|
|
}else{
|
2015-05-31 15:49:52 +02:00
|
|
|
dest_y = s->sc.b_scratchpad;
|
|
|
|
dest_cb= s->sc.b_scratchpad+16*linesize;
|
|
|
|
dest_cr= s->sc.b_scratchpad+32*linesize;
|
2003-11-27 15:38:00 +02:00
|
|
|
}
|
2004-09-26 02:18:58 +03:00
|
|
|
|
2001-07-22 17:18:56 +03:00
|
|
|
if (!s->mb_intra) {
|
|
|
|
/* motion handling */
|
2005-04-24 14:13:49 +03:00
|
|
|
/* decoding or more than one mb_type (MC was already done otherwise) */
|
2003-07-29 05:09:12 +03:00
|
|
|
if(!s->encoding){
|
2011-03-22 23:36:57 +02:00
|
|
|
|
2011-10-09 22:38:35 +03:00
|
|
|
if(HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) {
|
2011-03-22 23:36:57 +02:00
|
|
|
if (s->mv_dir & MV_DIR_FORWARD) {
|
2012-11-21 23:34:46 +03:00
|
|
|
ff_thread_await_progress(&s->last_picture_ptr->tf,
|
2015-06-08 14:00:52 +02:00
|
|
|
lowest_referenced_row(s, 0),
|
2012-02-28 00:02:45 +03:00
|
|
|
0);
|
2011-03-22 23:36:57 +02:00
|
|
|
}
|
|
|
|
if (s->mv_dir & MV_DIR_BACKWARD) {
|
2012-11-21 23:34:46 +03:00
|
|
|
ff_thread_await_progress(&s->next_picture_ptr->tf,
|
2015-06-08 14:00:52 +02:00
|
|
|
lowest_referenced_row(s, 1),
|
2012-02-28 00:02:45 +03:00
|
|
|
0);
|
2011-03-22 23:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-25 13:35:42 +03:00
|
|
|
if(lowres_flag){
|
2013-02-07 15:09:35 +03:00
|
|
|
h264_chroma_mc_func *op_pix = s->h264chroma.put_h264_chroma_pixels_tab;
|
2012-05-25 13:35:42 +03:00
|
|
|
|
|
|
|
if (s->mv_dir & MV_DIR_FORWARD) {
|
2014-04-09 15:36:47 +03:00
|
|
|
MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f->data, op_pix);
|
2013-02-07 15:09:35 +03:00
|
|
|
op_pix = s->h264chroma.avg_h264_chroma_pixels_tab;
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
|
|
|
if (s->mv_dir & MV_DIR_BACKWARD) {
|
2014-04-09 15:36:47 +03:00
|
|
|
MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f->data, op_pix);
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
2004-09-26 02:18:58 +03:00
|
|
|
}else{
|
2013-11-03 03:07:07 +03:00
|
|
|
op_qpix = s->me.qpel_put;
|
2012-05-25 13:35:42 +03:00
|
|
|
if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
|
2013-03-10 23:55:07 +03:00
|
|
|
op_pix = s->hdsp.put_pixels_tab;
|
2012-05-25 13:35:42 +03:00
|
|
|
}else{
|
2013-03-10 23:55:07 +03:00
|
|
|
op_pix = s->hdsp.put_no_rnd_pixels_tab;
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
|
|
|
if (s->mv_dir & MV_DIR_FORWARD) {
|
2014-08-15 21:00:34 +03:00
|
|
|
ff_mpv_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f->data, op_pix, op_qpix);
|
2013-03-10 23:55:07 +03:00
|
|
|
op_pix = s->hdsp.avg_pixels_tab;
|
2012-05-25 13:35:42 +03:00
|
|
|
op_qpix= s->me.qpel_avg;
|
|
|
|
}
|
|
|
|
if (s->mv_dir & MV_DIR_BACKWARD) {
|
2014-08-15 21:00:34 +03:00
|
|
|
ff_mpv_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f->data, op_pix, op_qpix);
|
2012-05-25 13:35:42 +03:00
|
|
|
}
|
2002-04-17 07:32:12 +03:00
|
|
|
}
|
2001-07-22 17:18:56 +03:00
|
|
|
}
|
|
|
|
|
2002-06-06 02:43:56 +03:00
|
|
|
/* skip dequant / idct if we are really late ;) */
|
2005-07-15 00:39:36 +03:00
|
|
|
if(s->avctx->skip_idct){
|
2011-04-28 02:40:44 +03:00
|
|
|
if( (s->avctx->skip_idct >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B)
|
|
|
|
||(s->avctx->skip_idct >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I)
|
2005-07-15 00:39:36 +03:00
|
|
|
|| s->avctx->skip_idct >= AVDISCARD_ALL)
|
|
|
|
goto skip_idct;
|
|
|
|
}
|
2002-06-06 02:43:56 +03:00
|
|
|
|
2001-07-22 17:18:56 +03:00
|
|
|
/* add dct residue */
|
2012-08-05 12:11:04 +03:00
|
|
|
if(s->encoding || !( s->msmpeg4_version || s->codec_id==AV_CODEC_ID_MPEG1VIDEO || s->codec_id==AV_CODEC_ID_MPEG2VIDEO
|
|
|
|
|| (s->codec_id==AV_CODEC_ID_MPEG4 && !s->mpeg_quant))){
|
2004-09-26 02:18:58 +03:00
|
|
|
add_dequant_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale);
|
2012-05-25 13:35:42 +03:00
|
|
|
add_dequant_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale);
|
2004-09-26 02:18:58 +03:00
|
|
|
add_dequant_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale);
|
2012-05-25 13:35:42 +03:00
|
|
|
add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale);
|
2002-06-06 02:43:56 +03:00
|
|
|
|
2015-06-29 21:59:37 +02:00
|
|
|
if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
|
2006-05-16 18:19:54 +03:00
|
|
|
if (s->chroma_y_shift){
|
|
|
|
add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale);
|
|
|
|
add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale);
|
|
|
|
}else{
|
|
|
|
dct_linesize >>= 1;
|
|
|
|
dct_offset >>=1;
|
|
|
|
add_dequant_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale);
|
|
|
|
add_dequant_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale);
|
|
|
|
add_dequant_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale);
|
|
|
|
add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale);
|
|
|
|
}
|
2002-06-09 16:35:56 +03:00
|
|
|
}
|
2012-08-05 12:11:04 +03:00
|
|
|
} else if(is_mpeg12 || (s->codec_id != AV_CODEC_ID_WMV2)){
|
2004-09-26 02:18:58 +03:00
|
|
|
add_dct(s, block[0], 0, dest_y , dct_linesize);
|
2012-05-25 13:35:42 +03:00
|
|
|
add_dct(s, block[1], 1, dest_y + block_size, dct_linesize);
|
2004-09-26 02:18:58 +03:00
|
|
|
add_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize);
|
2012-05-25 13:35:42 +03:00
|
|
|
add_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize);
|
2001-07-22 17:18:56 +03:00
|
|
|
|
2015-06-29 21:59:37 +02:00
|
|
|
if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
|
2004-06-11 10:59:12 +03:00
|
|
|
if(s->chroma_y_shift){//Chroma420
|
|
|
|
add_dct(s, block[4], 4, dest_cb, uvlinesize);
|
|
|
|
add_dct(s, block[5], 5, dest_cr, uvlinesize);
|
|
|
|
}else{
|
|
|
|
//chroma422
|
|
|
|
dct_linesize = uvlinesize << s->interlaced_dct;
|
2012-05-25 13:35:42 +03:00
|
|
|
dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size;
|
2004-06-11 10:59:12 +03:00
|
|
|
|
|
|
|
add_dct(s, block[4], 4, dest_cb, dct_linesize);
|
|
|
|
add_dct(s, block[5], 5, dest_cr, dct_linesize);
|
|
|
|
add_dct(s, block[6], 6, dest_cb+dct_offset, dct_linesize);
|
|
|
|
add_dct(s, block[7], 7, dest_cr+dct_offset, dct_linesize);
|
|
|
|
if(!s->chroma_x_shift){//Chroma444
|
2012-05-25 13:35:42 +03:00
|
|
|
add_dct(s, block[8], 8, dest_cb+block_size, dct_linesize);
|
|
|
|
add_dct(s, block[9], 9, dest_cr+block_size, dct_linesize);
|
|
|
|
add_dct(s, block[10], 10, dest_cb+block_size+dct_offset, dct_linesize);
|
|
|
|
add_dct(s, block[11], 11, dest_cr+block_size+dct_offset, dct_linesize);
|
2004-06-11 10:59:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}//fi gray
|
|
|
|
}
|
2009-12-30 04:08:25 +02:00
|
|
|
else if (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) {
|
2002-12-28 01:51:46 +02:00
|
|
|
ff_wmv2_add_mb(s, block, dest_y, dest_cb, dest_cr);
|
2002-06-06 02:43:56 +03:00
|
|
|
}
|
2001-07-22 17:18:56 +03:00
|
|
|
} else {
|
2017-12-29 17:42:14 +02:00
|
|
|
/* Only MPEG-4 Simple Studio Profile is supported in > 8-bit mode.
|
|
|
|
TODO: Integrate 10-bit properly into mpegvideo.c so that ER works properly */
|
|
|
|
if (s->avctx->bits_per_raw_sample > 8){
|
|
|
|
const int act_block_size = block_size * 2;
|
2018-08-19 03:31:42 +02:00
|
|
|
|
|
|
|
if(s->dpcm_direction == 0) {
|
|
|
|
s->idsp.idct_put(dest_y, dct_linesize, (int16_t*)(*s->block32)[0]);
|
|
|
|
s->idsp.idct_put(dest_y + act_block_size, dct_linesize, (int16_t*)(*s->block32)[1]);
|
|
|
|
s->idsp.idct_put(dest_y + dct_offset, dct_linesize, (int16_t*)(*s->block32)[2]);
|
|
|
|
s->idsp.idct_put(dest_y + dct_offset + act_block_size, dct_linesize, (int16_t*)(*s->block32)[3]);
|
|
|
|
|
|
|
|
dct_linesize = uvlinesize << s->interlaced_dct;
|
|
|
|
dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size;
|
|
|
|
|
|
|
|
s->idsp.idct_put(dest_cb, dct_linesize, (int16_t*)(*s->block32)[4]);
|
|
|
|
s->idsp.idct_put(dest_cr, dct_linesize, (int16_t*)(*s->block32)[5]);
|
|
|
|
s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, (int16_t*)(*s->block32)[6]);
|
|
|
|
s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, (int16_t*)(*s->block32)[7]);
|
|
|
|
if(!s->chroma_x_shift){//Chroma444
|
|
|
|
s->idsp.idct_put(dest_cb + act_block_size, dct_linesize, (int16_t*)(*s->block32)[8]);
|
|
|
|
s->idsp.idct_put(dest_cr + act_block_size, dct_linesize, (int16_t*)(*s->block32)[9]);
|
|
|
|
s->idsp.idct_put(dest_cb + act_block_size + dct_offset, dct_linesize, (int16_t*)(*s->block32)[10]);
|
|
|
|
s->idsp.idct_put(dest_cr + act_block_size + dct_offset, dct_linesize, (int16_t*)(*s->block32)[11]);
|
|
|
|
}
|
|
|
|
} else if(s->dpcm_direction == 1) {
|
|
|
|
int i, w, h;
|
|
|
|
uint16_t *dest_pcm[3] = {(uint16_t*)dest_y, (uint16_t*)dest_cb, (uint16_t*)dest_cr};
|
|
|
|
int linesize[3] = {dct_linesize, uvlinesize, uvlinesize};
|
|
|
|
for(i = 0; i < 3; i++) {
|
|
|
|
int idx = 0;
|
|
|
|
int vsub = i ? s->chroma_y_shift : 0;
|
|
|
|
int hsub = i ? s->chroma_x_shift : 0;
|
|
|
|
for(h = 0; h < (16 >> vsub); h++){
|
|
|
|
for(w = 0; w < (16 >> hsub); w++)
|
|
|
|
dest_pcm[i][w] = (*s->dpcm_macroblock)[i][idx++];
|
|
|
|
dest_pcm[i] += linesize[i] / 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if(s->dpcm_direction == -1) {
|
|
|
|
int i, w, h;
|
|
|
|
uint16_t *dest_pcm[3] = {(uint16_t*)dest_y, (uint16_t*)dest_cb, (uint16_t*)dest_cr};
|
|
|
|
int linesize[3] = {dct_linesize, uvlinesize, uvlinesize};
|
|
|
|
for(i = 0; i < 3; i++) {
|
|
|
|
int idx = 0;
|
|
|
|
int vsub = i ? s->chroma_y_shift : 0;
|
|
|
|
int hsub = i ? s->chroma_x_shift : 0;
|
|
|
|
dest_pcm[i] += (linesize[i] / 2) * ((16 >> vsub) - 1);
|
|
|
|
for(h = (16 >> vsub)-1; h >= 1; h--){
|
|
|
|
for(w = (16 >> hsub)-1; w >= 1; w--)
|
|
|
|
dest_pcm[i][w] = (*s->dpcm_macroblock)[i][idx++];
|
|
|
|
dest_pcm[i] -= linesize[i] / 2;
|
|
|
|
}
|
|
|
|
}
|
2017-12-29 17:42:14 +02:00
|
|
|
}
|
|
|
|
}
|
2001-07-22 17:18:56 +03:00
|
|
|
/* dct only in intra block */
|
2017-12-29 17:42:14 +02:00
|
|
|
else if(s->encoding || !(s->codec_id==AV_CODEC_ID_MPEG1VIDEO || s->codec_id==AV_CODEC_ID_MPEG2VIDEO)){
|
2004-09-26 02:18:58 +03:00
|
|
|
put_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale);
|
|
|
|
put_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale);
|
|
|
|
put_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale);
|
|
|
|
put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale);
|
2002-09-30 19:14:14 +03:00
|
|
|
|
2015-06-29 21:59:37 +02:00
|
|
|
if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
|
2006-05-16 18:19:54 +03:00
|
|
|
if(s->chroma_y_shift){
|
|
|
|
put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale);
|
|
|
|
put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale);
|
|
|
|
}else{
|
|
|
|
dct_offset >>=1;
|
|
|
|
dct_linesize >>=1;
|
|
|
|
put_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale);
|
|
|
|
put_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale);
|
|
|
|
put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale);
|
2007-07-03 12:55:56 +03:00
|
|
|
put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale);
|
2002-12-31 19:23:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}else{
|
2014-01-24 13:55:16 +03:00
|
|
|
s->idsp.idct_put(dest_y, dct_linesize, block[0]);
|
|
|
|
s->idsp.idct_put(dest_y + block_size, dct_linesize, block[1]);
|
|
|
|
s->idsp.idct_put(dest_y + dct_offset, dct_linesize, block[2]);
|
|
|
|
s->idsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]);
|
2004-01-02 21:22:00 +02:00
|
|
|
|
2015-06-29 21:59:37 +02:00
|
|
|
if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
|
2007-07-03 12:55:56 +03:00
|
|
|
if(s->chroma_y_shift){
|
2014-01-24 13:55:16 +03:00
|
|
|
s->idsp.idct_put(dest_cb, uvlinesize, block[4]);
|
|
|
|
s->idsp.idct_put(dest_cr, uvlinesize, block[5]);
|
2007-07-03 12:55:56 +03:00
|
|
|
}else{
|
2004-01-02 21:22:00 +02:00
|
|
|
|
2007-07-03 12:55:56 +03:00
|
|
|
dct_linesize = uvlinesize << s->interlaced_dct;
|
2013-11-03 03:07:07 +03:00
|
|
|
dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size;
|
2003-01-01 00:58:41 +02:00
|
|
|
|
2014-01-24 13:55:16 +03:00
|
|
|
s->idsp.idct_put(dest_cb, dct_linesize, block[4]);
|
|
|
|
s->idsp.idct_put(dest_cr, dct_linesize, block[5]);
|
|
|
|
s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]);
|
|
|
|
s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]);
|
2007-07-03 12:55:56 +03:00
|
|
|
if(!s->chroma_x_shift){//Chroma444
|
2014-07-01 15:38:57 +03:00
|
|
|
s->idsp.idct_put(dest_cb + block_size, dct_linesize, block[8]);
|
|
|
|
s->idsp.idct_put(dest_cr + block_size, dct_linesize, block[9]);
|
|
|
|
s->idsp.idct_put(dest_cb + block_size + dct_offset, dct_linesize, block[10]);
|
|
|
|
s->idsp.idct_put(dest_cr + block_size + dct_offset, dct_linesize, block[11]);
|
2007-07-03 12:55:56 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}//gray
|
2003-01-01 00:58:41 +02:00
|
|
|
}
|
2002-12-31 19:23:56 +02:00
|
|
|
}
|
2007-07-03 12:55:56 +03:00
|
|
|
skip_idct:
|
|
|
|
if(!readable){
|
2013-03-10 23:55:07 +03:00
|
|
|
s->hdsp.put_pixels_tab[0][0](s->dest[0], dest_y , linesize,16);
|
2015-07-27 21:14:31 +02:00
|
|
|
if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
|
2015-05-09 12:02:47 +02:00
|
|
|
s->hdsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[1], dest_cb, uvlinesize,16 >> s->chroma_y_shift);
|
|
|
|
s->hdsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[2], dest_cr, uvlinesize,16 >> s->chroma_y_shift);
|
2015-05-09 01:36:53 +02:00
|
|
|
}
|
2003-09-24 22:45:57 +03:00
|
|
|
}
|
2002-12-31 19:23:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-18 20:15:05 +02:00
|
|
|
void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64])
|
2014-08-10 18:25:12 +03:00
|
|
|
{
|
2009-01-14 01:44:16 +02:00
|
|
|
#if !CONFIG_SMALL
|
2008-04-21 11:30:54 +03:00
|
|
|
if(s->out_format == FMT_MPEG1) {
|
2017-06-18 20:15:05 +02:00
|
|
|
if(s->avctx->lowres) mpv_reconstruct_mb_internal(s, block, 1, 1);
|
|
|
|
else mpv_reconstruct_mb_internal(s, block, 0, 1);
|
2008-04-21 11:30:54 +03:00
|
|
|
} else
|
|
|
|
#endif
|
2017-06-18 20:15:05 +02:00
|
|
|
if(s->avctx->lowres) mpv_reconstruct_mb_internal(s, block, 1, 0);
|
|
|
|
else mpv_reconstruct_mb_internal(s, block, 0, 0);
|
2004-02-02 05:52:58 +02:00
|
|
|
}
|
|
|
|
|
2013-02-03 16:26:34 +03:00
|
|
|
void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
|
|
|
|
{
|
2014-04-09 15:36:47 +03:00
|
|
|
ff_draw_horiz_band(s->avctx, s->current_picture_ptr->f,
|
|
|
|
s->last_picture_ptr ? s->last_picture_ptr->f : NULL, y, h, s->picture_structure,
|
2014-01-29 16:14:46 +03:00
|
|
|
s->first_field, s->low_delay);
|
2013-02-03 16:26:34 +03:00
|
|
|
}
|
|
|
|
|
2007-07-03 12:55:56 +03:00
|
|
|
void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
|
2014-03-31 20:46:29 +03:00
|
|
|
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];
|
2017-12-29 17:42:14 +02:00
|
|
|
const int width_of_mb = (4 + (s->avctx->bits_per_raw_sample > 8)) - s->avctx->lowres;
|
|
|
|
const int height_of_mb = 4 - s->avctx->lowres;
|
2004-02-02 05:52:58 +02:00
|
|
|
|
2007-07-03 12:55:56 +03:00
|
|
|
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;
|
|
|
|
s->block_index[2]= s->b8_stride*(s->mb_y*2 + 1) - 2 + s->mb_x*2;
|
|
|
|
s->block_index[3]= s->b8_stride*(s->mb_y*2 + 1) - 1 + s->mb_x*2;
|
|
|
|
s->block_index[4]= s->mb_stride*(s->mb_y + 1) + s->b8_stride*s->mb_height*2 + s->mb_x - 1;
|
|
|
|
s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x - 1;
|
|
|
|
//block_index is not used by mpeg2, so it is not affected by chroma_format
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2017-12-29 17:42:14 +02:00
|
|
|
s->dest[0] = s->current_picture.f->data[0] + (int)((s->mb_x - 1U) << width_of_mb);
|
|
|
|
s->dest[1] = s->current_picture.f->data[1] + (int)((s->mb_x - 1U) << (width_of_mb - s->chroma_x_shift));
|
|
|
|
s->dest[2] = s->current_picture.f->data[2] + (int)((s->mb_x - 1U) << (width_of_mb - s->chroma_x_shift));
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2011-04-28 02:40:44 +03:00
|
|
|
if(!(s->pict_type==AV_PICTURE_TYPE_B && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME))
|
2007-07-03 12:55:56 +03:00
|
|
|
{
|
2009-11-30 21:14:00 +02:00
|
|
|
if(s->picture_structure==PICT_FRAME){
|
2017-12-29 17:42:14 +02:00
|
|
|
s->dest[0] += s->mb_y * linesize << height_of_mb;
|
|
|
|
s->dest[1] += s->mb_y * uvlinesize << (height_of_mb - s->chroma_y_shift);
|
|
|
|
s->dest[2] += s->mb_y * uvlinesize << (height_of_mb - s->chroma_y_shift);
|
2009-11-30 21:14:00 +02:00
|
|
|
}else{
|
2017-12-29 17:42:14 +02:00
|
|
|
s->dest[0] += (s->mb_y>>1) * linesize << height_of_mb;
|
|
|
|
s->dest[1] += (s->mb_y>>1) * uvlinesize << (height_of_mb - s->chroma_y_shift);
|
|
|
|
s->dest[2] += (s->mb_y>>1) * uvlinesize << (height_of_mb - s->chroma_y_shift);
|
2012-08-06 17:40:22 +03:00
|
|
|
av_assert1((s->mb_y&1) == (s->picture_structure == PICT_BOTTOM_FIELD));
|
2009-11-30 21:14:00 +02:00
|
|
|
}
|
2004-02-02 05:52:58 +02:00
|
|
|
}
|
|
|
|
}
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2007-07-03 12:55:56 +03:00
|
|
|
void ff_mpeg_flush(AVCodecContext *avctx){
|
|
|
|
int i;
|
|
|
|
MpegEncContext *s = avctx->priv_data;
|
2004-02-02 05:52:58 +02:00
|
|
|
|
2014-08-14 23:31:24 +03:00
|
|
|
if (!s || !s->picture)
|
2007-07-03 12:55:56 +03:00
|
|
|
return;
|
2004-02-02 05:52:58 +02:00
|
|
|
|
2012-11-21 23:34:46 +03:00
|
|
|
for (i = 0; i < MAX_PICTURE_COUNT; i++)
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->picture[i]);
|
2007-07-03 12:55:56 +03:00
|
|
|
s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL;
|
2005-12-17 20:14:38 +02:00
|
|
|
|
2015-04-27 23:09:19 +02:00
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->current_picture);
|
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->last_picture);
|
|
|
|
ff_mpeg_unref_picture(s->avctx, &s->next_picture);
|
2013-04-20 12:33:56 +03:00
|
|
|
|
2007-07-03 12:55:56 +03:00
|
|
|
s->mb_x= s->mb_y= 0;
|
2011-10-24 02:04:14 +03:00
|
|
|
s->closed_gop= 0;
|
2002-10-23 18:11:07 +03:00
|
|
|
|
2007-07-03 12:55:56 +03:00
|
|
|
s->parse_context.state= -1;
|
|
|
|
s->parse_context.frame_start_found= 0;
|
|
|
|
s->parse_context.overread= 0;
|
|
|
|
s->parse_context.overread_index= 0;
|
|
|
|
s->parse_context.index= 0;
|
|
|
|
s->parse_context.last_index= 0;
|
|
|
|
s->bitstream_buffer_size=0;
|
|
|
|
s->pp_time=0;
|
2001-07-22 17:18:56 +03:00
|
|
|
}
|
|
|
|
|
2007-07-10 00:07:24 +03:00
|
|
|
/**
|
|
|
|
* set qscale and update qscale dependent variables.
|
|
|
|
*/
|
|
|
|
void ff_set_qscale(MpegEncContext * s, int qscale)
|
|
|
|
{
|
|
|
|
if (qscale < 1)
|
|
|
|
qscale = 1;
|
|
|
|
else if (qscale > 31)
|
|
|
|
qscale = 31;
|
|
|
|
|
|
|
|
s->qscale = qscale;
|
|
|
|
s->chroma_qscale= s->chroma_qscale_table[qscale];
|
|
|
|
|
|
|
|
s->y_dc_scale= s->y_dc_scale_table[ qscale ];
|
|
|
|
s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ];
|
|
|
|
}
|
2011-03-22 23:36:57 +02:00
|
|
|
|
2014-08-10 18:25:12 +03:00
|
|
|
void ff_mpv_report_decode_progress(MpegEncContext *s)
|
2011-03-22 23:36:57 +02:00
|
|
|
{
|
2013-02-02 22:42:07 +03:00
|
|
|
if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->er.error_occurred)
|
2012-11-21 23:34:46 +03:00
|
|
|
ff_thread_report_progress(&s->current_picture_ptr->tf, s->mb_y, 0);
|
2011-03-22 23:36:57 +02:00
|
|
|
}
|