early-access version 1680

This commit is contained in:
pineappleEA
2021-05-13 11:45:27 +02:00
parent 1434d96e7d
commit 66ed389c6f
311 changed files with 6452 additions and 2597 deletions
+2 -1
View File
@@ -536,6 +536,7 @@ OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o
OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o
OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o
OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o
OBJS-$(CONFIG_PGX_DECODER) += pgxdec.o
OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o
OBJS-$(CONFIG_PIXLET_DECODER) += pixlet.o
OBJS-$(CONFIG_PJS_DECODER) += textdec.o ass.o
@@ -910,7 +911,7 @@ OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o
OBJS-$(CONFIG_HEVC_NVDEC_HWACCEL) += nvdec_hevc.o
OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec_h2645.o
OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o h265_profile_level.o
OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o
OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o h265_profile_level.o
OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o
OBJS-$(CONFIG_MJPEG_VAAPI_HWACCEL) += vaapi_mjpeg.o
OBJS-$(CONFIG_MPEG1_NVDEC_HWACCEL) += nvdec_mpeg12.o
+7 -2
View File
@@ -97,8 +97,13 @@ get_next:
avctx->audio_service_type = s->service_type;
}
if (avctx->codec_id != AV_CODEC_ID_EAC3)
avctx->bit_rate = s->bit_rate;
/* Calculate the average bit rate */
s->frame_number++;
if (avctx->codec_id != AV_CODEC_ID_EAC3) {
avctx->bit_rate =
(s->last_bit_rate * (s->frame_number -1) + s->bit_rate)/s->frame_number;
s->last_bit_rate = avctx->bit_rate;
}
}
return i;
+2
View File
@@ -55,6 +55,8 @@ typedef struct AACAC3ParseContext {
uint64_t state;
int need_next_header;
int frame_number;
int last_bit_rate;
enum AVCodecID codec_id;
} AACAC3ParseContext;
+8 -12
View File
@@ -941,15 +941,14 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s)
static av_cold int alloc_buffers(AVCodecContext *avctx, AACEncContext *s)
{
int ch;
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->buffer.samples, s->channels, 3 * 1024 * sizeof(s->buffer.samples[0]), alloc_fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->cpe, s->chan_map[0], sizeof(ChannelElement), alloc_fail);
if (!FF_ALLOCZ_TYPED_ARRAY(s->buffer.samples, s->channels * 3 * 1024) ||
!FF_ALLOCZ_TYPED_ARRAY(s->cpe, s->chan_map[0]))
return AVERROR(ENOMEM);
for(ch = 0; ch < s->channels; ch++)
s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch;
return 0;
alloc_fail:
return AVERROR(ENOMEM);
}
static av_cold void aac_encode_init_tables(void)
@@ -1078,13 +1077,13 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
s->options.mid_side = 0;
if ((ret = dsp_init(avctx, s)) < 0)
goto fail;
return ret;
if ((ret = alloc_buffers(avctx, s)) < 0)
goto fail;
return ret;
if ((ret = put_audio_specific_config(avctx)))
goto fail;
return ret;
sizes[0] = ff_aac_swb_size_1024[s->samplerate_index];
sizes[1] = ff_aac_swb_size_128[s->samplerate_index];
@@ -1094,7 +1093,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
grouping[i] = s->chan_map[i + 1] == TYPE_CPE;
if ((ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths,
s->chan_map[0], grouping)) < 0)
goto fail;
return ret;
s->psypp = ff_psy_preprocess_init(avctx);
ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON);
s->random_state = 0x1f2e3d4c;
@@ -1114,9 +1113,6 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
ff_af_queue_init(avctx, &s->afq);
return 0;
fail:
aac_encode_end(avctx);
return ret;
}
#define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
@@ -1159,7 +1155,7 @@ AVCodec ff_aac_encoder = {
.close = aac_encode_end,
.defaults = aac_encode_defaults,
.supported_samplerates = mpeg4audio_sample_rates,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
+37 -56
View File
@@ -2322,60 +2322,46 @@ static av_cold void set_bandwidth(AC3EncodeContext *s)
static av_cold int allocate_buffers(AC3EncodeContext *s)
{
AVCodecContext *avctx = s->avctx;
int blk, ch;
int channels = s->channels + 1; /* includes coupling channel */
int channel_blocks = channels * s->num_blocks;
int total_coefs = AC3_MAX_COEFS * channel_blocks;
if (s->allocate_sample_buffers(s))
goto alloc_fail;
return AVERROR(ENOMEM);
if (!FF_ALLOC_TYPED_ARRAY(s->bap_buffer, total_coefs) ||
!FF_ALLOC_TYPED_ARRAY(s->bap1_buffer, total_coefs) ||
!FF_ALLOCZ_TYPED_ARRAY(s->mdct_coef_buffer, total_coefs) ||
!FF_ALLOC_TYPED_ARRAY(s->exp_buffer, total_coefs) ||
!FF_ALLOC_TYPED_ARRAY(s->grouped_exp_buffer, channel_blocks * 128) ||
!FF_ALLOC_TYPED_ARRAY(s->psd_buffer, total_coefs) ||
!FF_ALLOC_TYPED_ARRAY(s->band_psd_buffer, channel_blocks * 64) ||
!FF_ALLOC_TYPED_ARRAY(s->mask_buffer, channel_blocks * 64) ||
!FF_ALLOC_TYPED_ARRAY(s->qmant_buffer, total_coefs))
return AVERROR(ENOMEM);
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->bap_buffer, total_coefs,
sizeof(*s->bap_buffer), alloc_fail);
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->bap1_buffer, total_coefs,
sizeof(*s->bap1_buffer), alloc_fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->mdct_coef_buffer, total_coefs,
sizeof(*s->mdct_coef_buffer), alloc_fail);
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->exp_buffer, total_coefs,
sizeof(*s->exp_buffer), alloc_fail);
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->grouped_exp_buffer, channel_blocks, 128 *
sizeof(*s->grouped_exp_buffer), alloc_fail);
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->psd_buffer, total_coefs,
sizeof(*s->psd_buffer), alloc_fail);
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->band_psd_buffer, channel_blocks, 64 *
sizeof(*s->band_psd_buffer), alloc_fail);
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->mask_buffer, channel_blocks, 64 *
sizeof(*s->mask_buffer), alloc_fail);
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->qmant_buffer, total_coefs,
sizeof(*s->qmant_buffer), alloc_fail);
if (s->cpl_enabled) {
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->cpl_coord_exp_buffer, channel_blocks, 16 *
sizeof(*s->cpl_coord_exp_buffer), alloc_fail);
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->cpl_coord_mant_buffer, channel_blocks, 16 *
sizeof(*s->cpl_coord_mant_buffer), alloc_fail);
if (!FF_ALLOC_TYPED_ARRAY(s->cpl_coord_exp_buffer, channel_blocks * 16) ||
!FF_ALLOC_TYPED_ARRAY(s->cpl_coord_mant_buffer, channel_blocks * 16))
return AVERROR(ENOMEM);
}
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->mdct_coef, channels, sizeof(*block->mdct_coef),
alloc_fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->exp, channels, sizeof(*block->exp),
alloc_fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->grouped_exp, channels, sizeof(*block->grouped_exp),
alloc_fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->psd, channels, sizeof(*block->psd),
alloc_fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->band_psd, channels, sizeof(*block->band_psd),
alloc_fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->mask, channels, sizeof(*block->mask),
alloc_fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->qmant, channels, sizeof(*block->qmant),
alloc_fail);
if (!FF_ALLOCZ_TYPED_ARRAY(block->mdct_coef, channels) ||
!FF_ALLOCZ_TYPED_ARRAY(block->exp, channels) ||
!FF_ALLOCZ_TYPED_ARRAY(block->grouped_exp, channels) ||
!FF_ALLOCZ_TYPED_ARRAY(block->psd, channels) ||
!FF_ALLOCZ_TYPED_ARRAY(block->band_psd, channels) ||
!FF_ALLOCZ_TYPED_ARRAY(block->mask, channels) ||
!FF_ALLOCZ_TYPED_ARRAY(block->qmant, channels))
return AVERROR(ENOMEM);
if (s->cpl_enabled) {
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->cpl_coord_exp, channels, sizeof(*block->cpl_coord_exp),
alloc_fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->cpl_coord_mant, channels, sizeof(*block->cpl_coord_mant),
alloc_fail);
if (!FF_ALLOCZ_TYPED_ARRAY(block->cpl_coord_exp, channels) ||
!FF_ALLOCZ_TYPED_ARRAY(block->cpl_coord_mant, channels))
return AVERROR(ENOMEM);
}
for (ch = 0; ch < channels; ch++) {
@@ -2397,28 +2383,26 @@ static av_cold int allocate_buffers(AC3EncodeContext *s)
}
if (!s->fixed_point) {
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->fixed_coef_buffer, total_coefs,
sizeof(*s->fixed_coef_buffer), alloc_fail);
if (!FF_ALLOCZ_TYPED_ARRAY(s->fixed_coef_buffer, total_coefs))
return AVERROR(ENOMEM);
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->fixed_coef, channels,
sizeof(*block->fixed_coef), alloc_fail);
if (!FF_ALLOCZ_TYPED_ARRAY(block->fixed_coef, channels))
return AVERROR(ENOMEM);
for (ch = 0; ch < channels; ch++)
block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (s->num_blocks * ch + blk)];
}
} else {
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->fixed_coef, channels,
sizeof(*block->fixed_coef), alloc_fail);
if (!FF_ALLOCZ_TYPED_ARRAY(block->fixed_coef, channels))
return AVERROR(ENOMEM);
for (ch = 0; ch < channels; ch++)
block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch];
}
}
return 0;
alloc_fail:
return AVERROR(ENOMEM);
}
@@ -2433,7 +2417,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
ret = validate_options(s);
if (ret)
goto init_fail;
return ret;
avctx->frame_size = AC3_BLOCK_SIZE * s->num_blocks;
avctx->initial_padding = AC3_BLOCK_SIZE;
@@ -2476,11 +2460,11 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
ret = s->mdct_init(s);
if (ret)
goto init_fail;
return ret;
ret = allocate_buffers(s);
if (ret)
goto init_fail;
return ret;
ff_audiodsp_init(&s->adsp);
ff_me_cmp_init(&s->mecc, avctx);
@@ -2489,7 +2473,4 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
dprint_options(s);
return 0;
init_fail:
ff_ac3_encode_close(avctx);
return ret;
}
+1
View File
@@ -155,6 +155,7 @@ AVCodec ff_ac3_fixed_encoder = {
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE },
.priv_class = &ac3enc_class,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.supported_samplerates = ff_ac3_sample_rate_tab,
.channel_layouts = ff_ac3_channel_layouts,
.defaults = ac3_defaults,
+8 -11
View File
@@ -41,19 +41,16 @@ int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s)
{
int ch;
FF_ALLOC_OR_GOTO(s->avctx, s->windowed_samples, AC3_WINDOW_SIZE *
sizeof(*s->windowed_samples), alloc_fail);
FF_ALLOC_ARRAY_OR_GOTO(s->avctx, s->planar_samples, s->channels, sizeof(*s->planar_samples),
alloc_fail);
for (ch = 0; ch < s->channels; ch++) {
FF_ALLOCZ_OR_GOTO(s->avctx, s->planar_samples[ch],
(AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples),
alloc_fail);
}
if (!FF_ALLOC_TYPED_ARRAY(s->windowed_samples, AC3_WINDOW_SIZE) ||
!FF_ALLOC_TYPED_ARRAY(s->planar_samples, s->channels))
return AVERROR(ENOMEM);
for (ch = 0; ch < s->channels; ch++) {
if (!(s->planar_samples[ch] = av_mallocz((AC3_FRAME_SIZE + AC3_BLOCK_SIZE) *
sizeof(**s->planar_samples))))
return AVERROR(ENOMEM);
}
return 0;
alloc_fail:
return AVERROR(ENOMEM);
}
+12 -5
View File
@@ -162,11 +162,18 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
}
break;
case AV_CODEC_ID_ADPCM_IMA_APM:
if (avctx->extradata && avctx->extradata_size >= 16) {
c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 0), 18);
c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 4), 0, 88);
c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 8), 18);
c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 12), 0, 88);
if (avctx->extradata) {
if (avctx->extradata_size >= 28) {
c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 16), 18);
c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 20), 0, 88);
c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 4), 18);
c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 8), 0, 88);
} else if (avctx->extradata_size >= 16) {
c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 0), 18);
c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 4), 0, 88);
c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 8), 18);
c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 12), 0, 88);
}
}
break;
case AV_CODEC_ID_ADPCM_IMA_WS:
+16 -24
View File
@@ -58,14 +58,11 @@ typedef struct ADPCMEncodeContext {
#define FREEZE_INTERVAL 128
static av_cold int adpcm_encode_close(AVCodecContext *avctx);
static av_cold int adpcm_encode_init(AVCodecContext *avctx)
{
ADPCMEncodeContext *s = avctx->priv_data;
uint8_t *extradata;
int i;
int ret = AVERROR(ENOMEM);
if (avctx->channels > 2) {
av_log(avctx, AV_LOG_ERROR, "only stereo or mono is supported\n");
@@ -89,14 +86,11 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx)
if (avctx->trellis) {
int frontier = 1 << avctx->trellis;
int max_paths = frontier * FREEZE_INTERVAL;
FF_ALLOC_OR_GOTO(avctx, s->paths,
max_paths * sizeof(*s->paths), error);
FF_ALLOC_OR_GOTO(avctx, s->node_buf,
2 * frontier * sizeof(*s->node_buf), error);
FF_ALLOC_OR_GOTO(avctx, s->nodep_buf,
2 * frontier * sizeof(*s->nodep_buf), error);
FF_ALLOC_OR_GOTO(avctx, s->trellis_hash,
65536 * sizeof(*s->trellis_hash), error);
if (!FF_ALLOC_TYPED_ARRAY(s->paths, max_paths) ||
!FF_ALLOC_TYPED_ARRAY(s->node_buf, 2 * frontier) ||
!FF_ALLOC_TYPED_ARRAY(s->nodep_buf, 2 * frontier) ||
!FF_ALLOC_TYPED_ARRAY(s->trellis_hash, 65536))
return AVERROR(ENOMEM);
}
avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id);
@@ -123,7 +117,7 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx)
avctx->bits_per_coded_sample = 4;
avctx->block_align = BLKSIZE;
if (!(avctx->extradata = av_malloc(32 + AV_INPUT_BUFFER_PADDING_SIZE)))
goto error;
return AVERROR(ENOMEM);
avctx->extradata_size = 32;
extradata = avctx->extradata;
bytestream_put_le16(&extradata, avctx->frame_size);
@@ -143,8 +137,7 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx)
avctx->sample_rate != 44100) {
av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, "
"22050 or 44100\n");
ret = AVERROR(EINVAL);
goto error;
return AVERROR(EINVAL);
}
avctx->frame_size = 512 * (avctx->sample_rate / 11025);
break;
@@ -153,13 +146,10 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx)
avctx->block_align = BLKSIZE;
break;
default:
ret = AVERROR(EINVAL);
goto error;
return AVERROR(EINVAL);
}
return 0;
error:
return ret;
}
static av_cold int adpcm_encode_close(AVCodecContext *avctx)
@@ -523,7 +513,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
/* stereo: 4 bytes (8 samples) for left, 4 bytes for right */
if (avctx->trellis > 0) {
FF_ALLOC_ARRAY_OR_GOTO(avctx, buf, avctx->channels, blocks * 8, error);
if (!FF_ALLOC_TYPED_ARRAY(buf, avctx->channels * blocks * 8))
return AVERROR(ENOMEM);
for (ch = 0; ch < avctx->channels; ch++) {
adpcm_compress_trellis(avctx, &samples_p[ch][1],
buf + ch * blocks * 8, &c->status[ch],
@@ -618,7 +609,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
}
if (avctx->trellis > 0) {
FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error);
if (!(buf = av_malloc(2 * n)))
return AVERROR(ENOMEM);
adpcm_compress_trellis(avctx, samples + avctx->channels, buf,
&c->status[0], n, avctx->channels);
if (avctx->channels == 2)
@@ -666,7 +658,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
if (avctx->trellis > 0) {
n = avctx->block_align - 7 * avctx->channels;
FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error);
if (!(buf = av_malloc(2 * n)))
return AVERROR(ENOMEM);
if (avctx->channels == 1) {
adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n,
avctx->channels);
@@ -693,7 +686,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
case AV_CODEC_ID_ADPCM_YAMAHA:
n = frame->nb_samples / 2;
if (avctx->trellis > 0) {
FF_ALLOC_OR_GOTO(avctx, buf, 2 * n * 2, error);
if (!(buf = av_malloc(2 * n * 2)))
return AVERROR(ENOMEM);
n *= 2;
if (avctx->channels == 1) {
adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n,
@@ -724,8 +718,6 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
avpkt->size = pkt_size;
*got_packet_ptr = 1;
return 0;
error:
return AVERROR(ENOMEM);
}
static const enum AVSampleFormat sample_fmts[] = {
+8 -9
View File
@@ -489,6 +489,7 @@ static int allocate_buffers(ALACContext *alac)
{
int ch;
unsigned buf_size = alac->max_samples_per_frame * sizeof(int32_t);
unsigned extra_buf_size = buf_size + AV_INPUT_BUFFER_PADDING_SIZE;
for (ch = 0; ch < 2; ch++) {
alac->predict_error_buffer[ch] = NULL;
@@ -497,22 +498,19 @@ static int allocate_buffers(ALACContext *alac)
}
for (ch = 0; ch < FFMIN(alac->channels, 2); ch++) {
FF_ALLOC_OR_GOTO(alac->avctx, alac->predict_error_buffer[ch],
buf_size, buf_alloc_fail);
if (!(alac->predict_error_buffer[ch] = av_malloc(buf_size)))
return AVERROR(ENOMEM);
alac->direct_output = alac->sample_size > 16;
if (!alac->direct_output) {
FF_ALLOC_OR_GOTO(alac->avctx, alac->output_samples_buffer[ch],
buf_size + AV_INPUT_BUFFER_PADDING_SIZE, buf_alloc_fail);
if (!(alac->output_samples_buffer[ch] = av_malloc(extra_buf_size)))
return AVERROR(ENOMEM);
}
FF_ALLOC_OR_GOTO(alac->avctx, alac->extra_bits_buffer[ch],
buf_size + AV_INPUT_BUFFER_PADDING_SIZE, buf_alloc_fail);
if (!(alac->extra_bits_buffer[ch] = av_malloc(extra_buf_size)))
return AVERROR(ENOMEM);
}
return 0;
buf_alloc_fail:
alac_decode_close(alac->avctx);
return AVERROR(ENOMEM);
}
static int alac_set_info(ALACContext *alac)
@@ -625,5 +623,6 @@ AVCodec ff_alac_decoder = {
.close = alac_decode_close,
.decode = alac_decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.priv_class = &alac_class
};
+4 -3
View File
@@ -238,6 +238,7 @@ extern AVCodec ff_pgm_encoder;
extern AVCodec ff_pgm_decoder;
extern AVCodec ff_pgmyuv_encoder;
extern AVCodec ff_pgmyuv_decoder;
extern AVCodec ff_pgx_decoder;
extern AVCodec ff_pictor_decoder;
extern AVCodec ff_pixlet_decoder;
extern AVCodec ff_png_encoder;
@@ -679,9 +680,7 @@ extern AVCodec ff_xsub_decoder;
/* external libraries */
extern AVCodec ff_aac_at_encoder;
extern AVCodec ff_aac_at_decoder;
extern AVCodec ff_aac_mf_encoder;
extern AVCodec ff_ac3_at_decoder;
extern AVCodec ff_ac3_mf_encoder;
extern AVCodec ff_adpcm_ima_qt_at_decoder;
extern AVCodec ff_alac_at_encoder;
extern AVCodec ff_alac_at_decoder;
@@ -693,7 +692,6 @@ extern AVCodec ff_ilbc_at_decoder;
extern AVCodec ff_mp1_at_decoder;
extern AVCodec ff_mp2_at_decoder;
extern AVCodec ff_mp3_at_decoder;
extern AVCodec ff_mp3_mf_encoder;
extern AVCodec ff_pcm_alaw_at_encoder;
extern AVCodec ff_pcm_alaw_at_decoder;
extern AVCodec ff_pcm_mulaw_at_encoder;
@@ -757,6 +755,8 @@ extern AVCodec ff_idf_decoder;
/* external libraries, that shouldn't be used by default if one of the
* above is available */
extern AVCodec ff_aac_mf_encoder;
extern AVCodec ff_ac3_mf_encoder;
extern AVCodec ff_h263_v4l2m2m_encoder;
extern AVCodec ff_libaom_av1_decoder;
extern AVCodec ff_libopenh264_encoder;
@@ -789,6 +789,7 @@ extern AVCodec ff_mjpeg_cuvid_decoder;
extern AVCodec ff_mjpeg_qsv_encoder;
extern AVCodec ff_mjpeg_qsv_decoder;
extern AVCodec ff_mjpeg_vaapi_encoder;
extern AVCodec ff_mp3_mf_encoder;
extern AVCodec ff_mpeg1_cuvid_decoder;
extern AVCodec ff_mpeg2_cuvid_decoder;
extern AVCodec ff_mpeg2_qsv_encoder;
+17 -26
View File
@@ -33,6 +33,7 @@
#include "libavutil/time.h"
#include "amfenc.h"
#include "encode.h"
#include "internal.h"
#if CONFIG_D3D11VA
@@ -588,17 +589,27 @@ static void amf_release_buffer_with_frame_ref(AMFBuffer *frame_ref_storage_buffe
frame_ref_storage_buffer->pVtbl->Release(frame_ref_storage_buffer);
}
int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
{
AmfContext *ctx = avctx->priv_data;
AMFSurface *surface;
AMF_RESULT res;
int ret;
AMF_RESULT res_query;
AMFData *data = NULL;
AVFrame *frame = ctx->delayed_frame;
int block_and_wait;
if (!ctx->encoder)
return AVERROR(EINVAL);
if (!frame) { // submit drain
if (!frame->buf[0]) {
ret = ff_encode_get_frame(avctx, frame);
if (ret < 0 && ret != AVERROR_EOF)
return ret;
}
if (!frame->buf[0]) { // submit drain
if (!ctx->eof) { // submit drain one time only
if (ctx->delayed_surface != NULL) {
ctx->delayed_drain = 1; // input queue is full: resubmit Drain() in ff_amf_receive_packet
@@ -613,15 +624,10 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "Drain() failed with error %d\n", res);
}
}
} else{
return AVERROR_EOF;
}
} else { // submit frame
} else if (!ctx->delayed_surface) { // submit frame
int hw_surface = 0;
if (ctx->delayed_surface != NULL) {
return AVERROR(EAGAIN); // should not happen when called from ffmpeg, other clients may resubmit
}
// prepare surface from frame
switch (frame->format) {
#if CONFIG_D3D11VA
@@ -693,38 +699,23 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
break;
}
// submit surface
res = ctx->encoder->pVtbl->SubmitInput(ctx->encoder, (AMFData*)surface);
if (res == AMF_INPUT_FULL) { // handle full queue
//store surface for later submission
ctx->delayed_surface = surface;
if (surface->pVtbl->GetMemoryType(surface) == AMF_MEMORY_DX11) {
av_frame_ref(ctx->delayed_frame, frame);
}
} else {
int64_t pts = frame->pts;
surface->pVtbl->Release(surface);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "SubmitInput() failed with error %d\n", res);
if ((ret = timestamp_queue_enqueue(avctx, frame->pts)) < 0) {
av_frame_unref(frame);
if ((ret = timestamp_queue_enqueue(avctx, pts)) < 0) {
return ret;
}
}
}
return 0;
}
int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
{
int ret;
AMF_RESULT res;
AMF_RESULT res_query;
AmfContext *ctx = avctx->priv_data;
AMFData *data = NULL;
int block_and_wait;
if (!ctx->encoder)
return AVERROR(EINVAL);
do {
block_and_wait = 0;
-2
View File
@@ -129,8 +129,6 @@ int ff_amf_encode_close(AVCodecContext *avctx);
/**
* Ecoding one frame - common function for all AMF encoders
*/
int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame);
int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
/**
-1
View File
@@ -383,7 +383,6 @@ AVCodec ff_h264_amf_encoder = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.init = amf_encode_init_h264,
.send_frame = ff_amf_send_frame,
.receive_packet = ff_amf_receive_packet,
.close = ff_amf_encode_close,
.priv_data_size = sizeof(AmfContext),
+1 -2
View File
@@ -69,7 +69,7 @@ static const AVOption options[] = {
{ "gop", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_GOP_ALIGNED }, 0, 0, VE, "hdrmode" },
{ "idr", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_IDR_ALIGNED }, 0, 0, VE, "hdrmode" },
{ "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 60 }, 0, INT_MAX, VE },
{ "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, VE },
{ "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
@@ -313,7 +313,6 @@ AVCodec ff_hevc_amf_encoder = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_HEVC,
.init = amf_encode_init_hevc,
.send_frame = ff_amf_send_frame,
.receive_packet = ff_amf_receive_packet,
.close = ff_amf_encode_close,
.priv_data_size = sizeof(AmfContext),
+3 -6
View File
@@ -262,9 +262,8 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
for (i = 0; i < APE_FILTER_LEVELS; i++) {
if (!ape_filter_orders[s->fset][i])
break;
FF_ALLOC_OR_GOTO(avctx, s->filterbuf[i],
(ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4,
filter_alloc_fail);
if (!(s->filterbuf[i] = av_malloc((ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4)))
return AVERROR(ENOMEM);
}
if (s->fileversion < 3860) {
@@ -300,9 +299,6 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
return 0;
filter_alloc_fail:
ape_decode_close(avctx);
return AVERROR(ENOMEM);
}
/**
@@ -1638,6 +1634,7 @@ AVCodec ff_ape_decoder = {
.decode = ape_decode_frame,
.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.flush = ape_flush,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
AV_SAMPLE_FMT_S16P,
+1 -1
View File
@@ -483,7 +483,7 @@ static int ffat_decode(AVCodecContext *avctx, void *data,
if (avctx->codec_id == AV_CODEC_ID_AAC) {
if (!at->extradata_size) {
uint8_t *side_data;
int side_data_size = 0;
int side_data_size;
side_data = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA,
&side_data_size);
+6 -6
View File
@@ -34,8 +34,8 @@ static void av1_frame_merge_flush(AVBSFContext *bsf)
{
AV1FMergeContext *ctx = bsf->priv_data;
ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[0]);
ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[1]);
ff_cbs_fragment_reset(&ctx->frag[0]);
ff_cbs_fragment_reset(&ctx->frag[1]);
av_packet_unref(ctx->in);
av_packet_unref(ctx->pkt);
}
@@ -93,7 +93,7 @@ eof:
ctx->idx = !ctx->idx;
} else {
for (i = 0; i < frag->nb_units; i++) {
err = ff_cbs_insert_unit_content(ctx->cbc, tu, -1, frag->units[i].type,
err = ff_cbs_insert_unit_content(tu, -1, frag->units[i].type,
frag->units[i].content, frag->units[i].content_ref);
if (err < 0)
goto fail;
@@ -108,7 +108,7 @@ eof:
else
av_packet_unref(in);
ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[ctx->idx]);
ff_cbs_fragment_reset(&ctx->frag[ctx->idx]);
fail:
if (err < 0 && err != AVERROR(EAGAIN))
@@ -133,8 +133,8 @@ static void av1_frame_merge_close(AVBSFContext *bsf)
{
AV1FMergeContext *ctx = bsf->priv_data;
ff_cbs_fragment_free(ctx->cbc, &ctx->frag[0]);
ff_cbs_fragment_free(ctx->cbc, &ctx->frag[1]);
ff_cbs_fragment_free(&ctx->frag[0]);
ff_cbs_fragment_free(&ctx->frag[1]);
av_packet_free(&ctx->in);
av_packet_free(&ctx->pkt);
ff_cbs_close(&ctx->cbc);
+5 -5
View File
@@ -172,7 +172,7 @@ static int av1_frame_split_filter(AVBSFContext *ctx, AVPacket *out)
if (s->cur_frame == s->nb_frames) {
av_packet_unref(s->buffer_pkt);
ff_cbs_fragment_reset(s->cbc, td);
ff_cbs_fragment_reset(td);
}
return 0;
@@ -187,7 +187,7 @@ fail:
av_packet_unref(out);
av_packet_unref(s->buffer_pkt);
}
ff_cbs_fragment_reset(s->cbc, td);
ff_cbs_fragment_reset(td);
return ret;
}
@@ -224,7 +224,7 @@ static int av1_frame_split_init(AVBSFContext *ctx)
if (ret < 0)
av_log(ctx, AV_LOG_WARNING, "Failed to parse extradata.\n");
ff_cbs_fragment_reset(s->cbc, td);
ff_cbs_fragment_reset(td);
return 0;
}
@@ -234,7 +234,7 @@ static void av1_frame_split_flush(AVBSFContext *ctx)
AV1FSplitContext *s = ctx->priv_data;
av_packet_unref(s->buffer_pkt);
ff_cbs_fragment_reset(s->cbc, &s->temporal_unit);
ff_cbs_fragment_reset(&s->temporal_unit);
}
static void av1_frame_split_close(AVBSFContext *ctx)
@@ -242,7 +242,7 @@ static void av1_frame_split_close(AVBSFContext *ctx)
AV1FSplitContext *s = ctx->priv_data;
av_packet_free(&s->buffer_pkt);
ff_cbs_fragment_free(s->cbc, &s->temporal_unit);
ff_cbs_fragment_free(&s->temporal_unit);
ff_cbs_close(&s->cbc);
}
+7 -7
View File
@@ -151,7 +151,7 @@ static int av1_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
return AVERROR(ENOMEM);
memcpy(side_data, frag->data, frag->data_size);
ff_cbs_fragment_reset(ctx->cbc, frag);
ff_cbs_fragment_reset(frag);
return 0;
}
@@ -195,13 +195,13 @@ static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
// If a Temporal Delimiter is present, it must be the first OBU.
if (frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) {
if (ctx->td == REMOVE)
ff_cbs_delete_unit(ctx->cbc, frag, 0);
ff_cbs_delete_unit(frag, 0);
} else if (ctx->td == INSERT) {
td = (AV1RawOBU) {
.header.obu_type = AV1_OBU_TEMPORAL_DELIMITER,
};
err = ff_cbs_insert_unit_content(ctx->cbc, frag, 0, AV1_OBU_TEMPORAL_DELIMITER,
err = ff_cbs_insert_unit_content(frag, 0, AV1_OBU_TEMPORAL_DELIMITER,
&td, NULL);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to insert Temporal Delimiter.\n");
@@ -212,7 +212,7 @@ static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
if (ctx->delete_padding) {
for (i = frag->nb_units - 1; i >= 0; i--) {
if (frag->units[i].type == AV1_OBU_PADDING)
ff_cbs_delete_unit(ctx->cbc, frag, i);
ff_cbs_delete_unit(frag, i);
}
}
@@ -224,7 +224,7 @@ static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
err = 0;
fail:
ff_cbs_fragment_reset(ctx->cbc, frag);
ff_cbs_fragment_reset(frag);
if (err < 0)
av_packet_unref(pkt);
@@ -268,7 +268,7 @@ static int av1_metadata_init(AVBSFContext *bsf)
err = 0;
fail:
ff_cbs_fragment_reset(ctx->cbc, frag);
ff_cbs_fragment_reset(frag);
return err;
}
@@ -276,7 +276,7 @@ static void av1_metadata_close(AVBSFContext *bsf)
{
AV1MetadataContext *ctx = bsf->priv_data;
ff_cbs_fragment_free(ctx->cbc, &ctx->access_unit);
ff_cbs_fragment_free(&ctx->access_unit);
ff_cbs_close(&ctx->cbc);
}
+3 -3
View File
@@ -78,7 +78,7 @@ static int av1_parser_parse(AVCodecParserContext *ctx,
av_log(avctx, AV_LOG_WARNING, "Failed to parse extradata.\n");
}
ff_cbs_fragment_reset(s->cbc, td);
ff_cbs_fragment_reset(td);
}
ret = ff_cbs_read(s->cbc, td, data, size);
@@ -191,7 +191,7 @@ static int av1_parser_parse(AVCodecParserContext *ctx,
avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
end:
ff_cbs_fragment_reset(s->cbc, td);
ff_cbs_fragment_reset(td);
s->cbc->log_ctx = NULL;
@@ -225,7 +225,7 @@ static void av1_parser_close(AVCodecParserContext *ctx)
{
AV1ParseContext *s = ctx->priv_data;
ff_cbs_fragment_free(s->cbc, &s->temporal_unit);
ff_cbs_fragment_free(&s->temporal_unit);
ff_cbs_close(&s->cbc);
}
+1 -2
View File
@@ -91,8 +91,7 @@ static av_cold int end(AVCodecContext *avctx)
{
AVRnContext *a = avctx->priv_data;
avcodec_close(a->mjpeg_avctx);
av_freep(&a->mjpeg_avctx);
avcodec_free_context(&a->mjpeg_avctx);
return 0;
}
+8 -6
View File
@@ -285,7 +285,6 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
vlc->bits = nb_bits;
if (flags & INIT_VLC_USE_NEW_STATIC) {
av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf));
buf = localbuf;
localvlc = *vlc_arg;
vlc = &localvlc;
vlc->table_size = 0;
@@ -293,11 +292,13 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
vlc->table = NULL;
vlc->table_allocated = 0;
vlc->table_size = 0;
}
if (nb_codes + 1 > FF_ARRAY_ELEMS(localbuf)) {
buf = av_malloc_array((nb_codes + 1), sizeof(VLCcode));
if (!buf)
return AVERROR(ENOMEM);
}
} else
buf = localbuf;
av_assert0(symbols_size <= 2 || !symbols);
@@ -309,7 +310,7 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
continue; \
if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \
av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\
if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
if (buf != localbuf) \
av_free(buf); \
return AVERROR(EINVAL); \
} \
@@ -317,7 +318,7 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
if (buf[j].code >= (1LL<<buf[j].bits)) { \
av_log(NULL, AV_LOG_ERROR, "Invalid code %"PRIx32" for %d in " \
"init_vlc\n", buf[j].code, i); \
if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
if (buf != localbuf) \
av_free(buf); \
return AVERROR(EINVAL); \
} \
@@ -346,7 +347,8 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
av_assert0(ret >= 0);
*vlc_arg = *vlc;
} else {
av_free(buf);
if (buf != localbuf)
av_free(buf);
if (ret < 0) {
av_freep(&vlc->table);
return ret;
+14
View File
@@ -96,6 +96,7 @@ const AVBitStreamFilter *av_bsf_get_by_name(const char *name)
return NULL;
}
#if FF_API_CHILD_CLASS_NEXT
const AVClass *ff_bsf_child_class_next(const AVClass *prev)
{
const AVBitStreamFilter *f = NULL;
@@ -115,3 +116,16 @@ const AVClass *ff_bsf_child_class_next(const AVClass *prev)
}
return NULL;
}
#endif
const AVClass *ff_bsf_child_class_iterate(void **opaque)
{
const AVBitStreamFilter *f;
/* find next filter with priv options */
while ((f = av_bsf_iterate(opaque))) {
if (f->priv_class)
return f->priv_class;
}
return NULL;
}
+3
View File
@@ -79,7 +79,10 @@ static const AVClass bsf_class = {
.item_name = bsf_to_name,
.version = LIBAVUTIL_VERSION_INT,
.child_next = bsf_child_next,
#if FF_API_CHILD_CLASS_NEXT
.child_class_next = ff_bsf_child_class_next,
#endif
.child_class_iterate = ff_bsf_child_class_iterate,
.category = AV_CLASS_CATEGORY_BITSTREAM_FILTER,
};
+4
View File
@@ -42,6 +42,10 @@ int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt);
*/
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt);
#if FF_API_CHILD_CLASS_NEXT
const AVClass *ff_bsf_child_class_next(const AVClass *prev);
#endif
const AVClass *ff_bsf_child_class_iterate(void **opaque);
#endif /* AVCODEC_BSF_INTERNAL_H */
+19 -29
View File
@@ -127,8 +127,7 @@ void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
av_freep(ctx_ptr);
}
static void cbs_unit_uninit(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit)
static void cbs_unit_uninit(CodedBitstreamUnit *unit)
{
av_buffer_unref(&unit->content_ref);
unit->content = NULL;
@@ -139,13 +138,12 @@ static void cbs_unit_uninit(CodedBitstreamContext *ctx,
unit->data_bit_padding = 0;
}
void ff_cbs_fragment_reset(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag)
void ff_cbs_fragment_reset(CodedBitstreamFragment *frag)
{
int i;
for (i = 0; i < frag->nb_units; i++)
cbs_unit_uninit(ctx, &frag->units[i]);
cbs_unit_uninit(&frag->units[i]);
frag->nb_units = 0;
av_buffer_unref(&frag->data_ref);
@@ -154,10 +152,9 @@ void ff_cbs_fragment_reset(CodedBitstreamContext *ctx,
frag->data_bit_padding = 0;
}
void ff_cbs_fragment_free(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag)
void ff_cbs_fragment_free(CodedBitstreamFragment *frag)
{
ff_cbs_fragment_reset(ctx, frag);
ff_cbs_fragment_reset(frag);
av_freep(&frag->units);
frag->nb_units_allocated = 0;
@@ -200,8 +197,7 @@ static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
return 0;
}
static int cbs_fill_fragment_data(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
static int cbs_fill_fragment_data(CodedBitstreamFragment *frag,
const uint8_t *data, size_t size)
{
av_assert0(!frag->data && !frag->data_ref);
@@ -227,7 +223,7 @@ int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
{
int err;
err = cbs_fill_fragment_data(ctx, frag, par->extradata,
err = cbs_fill_fragment_data(frag, par->extradata,
par->extradata_size);
if (err < 0)
return err;
@@ -254,7 +250,7 @@ int ff_cbs_read_packet(CodedBitstreamContext *ctx,
frag->data_size = pkt->size;
} else {
err = cbs_fill_fragment_data(ctx, frag, pkt->data, pkt->size);
err = cbs_fill_fragment_data(frag, pkt->data, pkt->size);
if (err < 0)
return err;
}
@@ -272,7 +268,7 @@ int ff_cbs_read(CodedBitstreamContext *ctx,
{
int err;
err = cbs_fill_fragment_data(ctx, frag, data, size);
err = cbs_fill_fragment_data(frag, data, size);
if (err < 0)
return err;
@@ -328,7 +324,7 @@ static int cbs_write_unit_data(CodedBitstreamContext *ctx,
flush_put_bits(&pbc);
ret = ff_cbs_alloc_unit_data(ctx, unit, put_bits_count(&pbc) / 8);
ret = ff_cbs_alloc_unit_data(unit, put_bits_count(&pbc) / 8);
if (ret < 0)
return ret;
@@ -641,8 +637,7 @@ int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc,
}
int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit,
int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit,
size_t size,
void (*free)(void *opaque, uint8_t *data))
{
@@ -662,8 +657,7 @@ int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
return 0;
}
int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit,
int ff_cbs_alloc_unit_data(CodedBitstreamUnit *unit,
size_t size)
{
av_assert0(!unit->data && !unit->data_ref);
@@ -680,8 +674,7 @@ int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx,
return 0;
}
static int cbs_insert_unit(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
static int cbs_insert_unit(CodedBitstreamFragment *frag,
int position)
{
CodedBitstreamUnit *units;
@@ -719,8 +712,7 @@ static int cbs_insert_unit(CodedBitstreamContext *ctx,
return 0;
}
int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag,
int position,
CodedBitstreamUnitType type,
void *content,
@@ -742,7 +734,7 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
content_ref = NULL;
}
err = cbs_insert_unit(ctx, frag, position);
err = cbs_insert_unit(frag, position);
if (err < 0) {
av_buffer_unref(&content_ref);
return err;
@@ -756,8 +748,7 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
return 0;
}
int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
int ff_cbs_insert_unit_data(CodedBitstreamFragment *frag,
int position,
CodedBitstreamUnitType type,
uint8_t *data, size_t data_size,
@@ -781,7 +772,7 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
return AVERROR(ENOMEM);
}
err = cbs_insert_unit(ctx, frag, position);
err = cbs_insert_unit(frag, position);
if (err < 0) {
av_buffer_unref(&data_ref);
return err;
@@ -796,14 +787,13 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
return 0;
}
void ff_cbs_delete_unit(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
void ff_cbs_delete_unit(CodedBitstreamFragment *frag,
int position)
{
av_assert0(0 <= position && position < frag->nb_units
&& "Unit to be deleted not in fragment.");
cbs_unit_uninit(ctx, &frag->units[position]);
cbs_unit_uninit(&frag->units[position]);
--frag->nb_units;
+7 -14
View File
@@ -330,23 +330,20 @@ int ff_cbs_write_packet(CodedBitstreamContext *ctx,
* Free the units contained in a fragment as well as the fragment's
* own data buffer, but not the units array itself.
*/
void ff_cbs_fragment_reset(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag);
void ff_cbs_fragment_reset(CodedBitstreamFragment *frag);
/**
* Free the units array of a fragment in addition to what
* ff_cbs_fragment_reset does.
*/
void ff_cbs_fragment_free(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag);
void ff_cbs_fragment_free(CodedBitstreamFragment *frag);
/**
* Allocate a new internal content buffer of the given size in the unit.
*
* The content will be zeroed.
*/
int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit,
int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit,
size_t size,
void (*free)(void *opaque, uint8_t *content));
@@ -355,8 +352,7 @@ int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
*
* The data buffer will have input padding.
*/
int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit,
int ff_cbs_alloc_unit_data(CodedBitstreamUnit *unit,
size_t size);
/**
@@ -365,8 +361,7 @@ int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx,
* The content structure continues to be owned by the caller if
* content_buf is not supplied.
*/
int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag,
int position,
CodedBitstreamUnitType type,
void *content,
@@ -379,8 +374,7 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
* av_malloc() and will on success become owned by the unit after this
* call or freed on error.
*/
int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
int ff_cbs_insert_unit_data(CodedBitstreamFragment *frag,
int position,
CodedBitstreamUnitType type,
uint8_t *data, size_t data_size,
@@ -391,8 +385,7 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
*
* Requires position to be >= 0 and < frag->nb_units.
*/
void ff_cbs_delete_unit(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
void ff_cbs_delete_unit(CodedBitstreamFragment *frag,
int position);
+7 -12
View File
@@ -120,16 +120,11 @@ static int cbs_av1_write_uvlc(CodedBitstreamContext *ctx, PutBitContext *pbc,
if (ctx->trace_enable)
position = put_bits_count(pbc);
if (value == 0) {
zeroes = 0;
put_bits(pbc, 1, 1);
} else {
zeroes = av_log2(value + 1);
v = value - (1U << zeroes) + 1;
put_bits(pbc, zeroes, 0);
put_bits(pbc, 1, 1);
put_bits(pbc, zeroes, v);
}
zeroes = av_log2(value + 1);
v = value - (1U << zeroes) + 1;
put_bits(pbc, zeroes, 0);
put_bits(pbc, 1, 1);
put_bits(pbc, zeroes, v);
if (ctx->trace_enable) {
char bits[65];
@@ -799,7 +794,7 @@ static int cbs_av1_split_fragment(CodedBitstreamContext *ctx,
goto fail;
}
err = ff_cbs_insert_unit_data(ctx, frag, -1, header.obu_type,
err = ff_cbs_insert_unit_data(frag, -1, header.obu_type,
data, obu_length, frag->data_ref);
if (err < 0)
goto fail;
@@ -892,7 +887,7 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx,
GetBitContext gbc;
int err, start_pos, end_pos;
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*obu),
err = ff_cbs_alloc_unit_content(unit, sizeof(*obu),
&cbs_av1_free_obu);
if (err < 0)
return err;
+2 -4
View File
@@ -472,8 +472,7 @@ typedef struct CodedBitstreamH264Context {
* On success, the payload will be owned by a unit in access_unit;
* on failure, the content of the payload will be freed.
*/
int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx,
CodedBitstreamFragment *access_unit,
int ff_cbs_h264_add_sei_message(CodedBitstreamFragment *access_unit,
H264RawSEIPayload *payload);
/**
@@ -485,8 +484,7 @@ int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx,
* Requires nal_unit to be a unit in access_unit and position to be >= 0
* and < the payload count of the SEI nal_unit.
*/
void ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx,
CodedBitstreamFragment *access_unit,
void ff_cbs_h264_delete_sei_message(CodedBitstreamFragment *access_unit,
CodedBitstreamUnit *nal_unit,
int position);
+19 -21
View File
@@ -591,7 +591,7 @@ static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx,
ref = (nal->data == nal->raw_data) ? frag->data_ref
: packet->rbsp.rbsp_buffer_ref;
err = ff_cbs_insert_unit_data(ctx, frag, -1, nal->type,
err = ff_cbs_insert_unit_data(frag, -1, nal->type,
(uint8_t*)nal->data, size, ref);
if (err < 0)
return err;
@@ -807,7 +807,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
{
H264RawSPS *sps;
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*sps), NULL);
err = ff_cbs_alloc_unit_content(unit, sizeof(*sps), NULL);
if (err < 0)
return err;
sps = unit->content;
@@ -824,7 +824,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
case H264_NAL_SPS_EXT:
{
err = ff_cbs_alloc_unit_content(ctx, unit,
err = ff_cbs_alloc_unit_content(unit,
sizeof(H264RawSPSExtension),
NULL);
if (err < 0)
@@ -840,7 +840,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
{
H264RawPPS *pps;
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*pps),
err = ff_cbs_alloc_unit_content(unit, sizeof(*pps),
&cbs_h264_free_pps);
if (err < 0)
return err;
@@ -863,7 +863,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
H264RawSlice *slice;
int pos, len;
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice),
err = ff_cbs_alloc_unit_content(unit, sizeof(*slice),
&cbs_h264_free_slice);
if (err < 0)
return err;
@@ -890,7 +890,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
case H264_NAL_AUD:
{
err = ff_cbs_alloc_unit_content(ctx, unit,
err = ff_cbs_alloc_unit_content(unit,
sizeof(H264RawAUD), NULL);
if (err < 0)
return err;
@@ -903,7 +903,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
case H264_NAL_SEI:
{
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(H264RawSEI),
err = ff_cbs_alloc_unit_content(unit, sizeof(H264RawSEI),
&cbs_h264_free_sei);
if (err < 0)
return err;
@@ -916,7 +916,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
case H264_NAL_FILLER_DATA:
{
err = ff_cbs_alloc_unit_content(ctx, unit,
err = ff_cbs_alloc_unit_content(unit,
sizeof(H264RawFiller), NULL);
if (err < 0)
return err;
@@ -930,7 +930,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
case H264_NAL_END_SEQUENCE:
case H264_NAL_END_STREAM:
{
err = ff_cbs_alloc_unit_content(ctx, unit,
err = ff_cbs_alloc_unit_content(unit,
sizeof(H264RawNALUnitHeader),
NULL);
if (err < 0)
@@ -966,7 +966,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
{
H265RawVPS *vps;
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*vps),
err = ff_cbs_alloc_unit_content(unit, sizeof(*vps),
&cbs_h265_free_vps);
if (err < 0)
return err;
@@ -985,7 +985,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
{
H265RawSPS *sps;
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*sps),
err = ff_cbs_alloc_unit_content(unit, sizeof(*sps),
&cbs_h265_free_sps);
if (err < 0)
return err;
@@ -1005,7 +1005,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
{
H265RawPPS *pps;
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*pps),
err = ff_cbs_alloc_unit_content(unit, sizeof(*pps),
&cbs_h265_free_pps);
if (err < 0)
return err;
@@ -1041,7 +1041,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
H265RawSlice *slice;
int pos, len;
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice),
err = ff_cbs_alloc_unit_content(unit, sizeof(*slice),
&cbs_h265_free_slice);
if (err < 0)
return err;
@@ -1068,7 +1068,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
case HEVC_NAL_AUD:
{
err = ff_cbs_alloc_unit_content(ctx, unit,
err = ff_cbs_alloc_unit_content(unit,
sizeof(H265RawAUD), NULL);
if (err < 0)
return err;
@@ -1082,7 +1082,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
case HEVC_NAL_SEI_PREFIX:
case HEVC_NAL_SEI_SUFFIX:
{
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(H265RawSEI),
err = ff_cbs_alloc_unit_content(unit, sizeof(H265RawSEI),
&cbs_h265_free_sei);
if (err < 0)
@@ -1531,8 +1531,7 @@ const CodedBitstreamType ff_cbs_type_h265 = {
.close = &cbs_h265_close,
};
int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx,
CodedBitstreamFragment *au,
int ff_cbs_h264_add_sei_message(CodedBitstreamFragment *au,
H264RawSEIPayload *payload)
{
H264RawSEI *sei = NULL;
@@ -1577,7 +1576,7 @@ int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx,
break;
}
err = ff_cbs_insert_unit_content(ctx, au, i, H264_NAL_SEI,
err = ff_cbs_insert_unit_content(au, i, H264_NAL_SEI,
sei, sei_ref);
av_buffer_unref(&sei_ref);
if (err < 0)
@@ -1593,8 +1592,7 @@ fail:
return err;
}
void ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx,
CodedBitstreamFragment *au,
void ff_cbs_h264_delete_sei_message(CodedBitstreamFragment *au,
CodedBitstreamUnit *nal,
int position)
{
@@ -1612,7 +1610,7 @@ void ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx,
break;
}
ff_cbs_delete_unit(ctx, au, i);
ff_cbs_delete_unit(au, i);
} else {
cbs_h264_free_sei_payload(&sei->payload[position]);
+5 -5
View File
@@ -226,7 +226,7 @@ static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx,
data_ref = frag->data_ref;
}
err = ff_cbs_insert_unit_data(ctx, frag, unit, marker,
err = ff_cbs_insert_unit_data(frag, unit, marker,
data, data_size, data_ref);
if (err < 0)
return err;
@@ -252,7 +252,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx,
if (unit->type >= JPEG_MARKER_SOF0 &&
unit->type <= JPEG_MARKER_SOF3) {
err = ff_cbs_alloc_unit_content(ctx, unit,
err = ff_cbs_alloc_unit_content(unit,
sizeof(JPEGRawFrameHeader),
NULL);
if (err < 0)
@@ -264,7 +264,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx,
} else if (unit->type >= JPEG_MARKER_APPN &&
unit->type <= JPEG_MARKER_APPN + 15) {
err = ff_cbs_alloc_unit_content(ctx, unit,
err = ff_cbs_alloc_unit_content(unit,
sizeof(JPEGRawApplicationData),
&cbs_jpeg_free_application_data);
if (err < 0)
@@ -278,7 +278,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx,
JPEGRawScan *scan;
int pos;
err = ff_cbs_alloc_unit_content(ctx, unit,
err = ff_cbs_alloc_unit_content(unit,
sizeof(JPEGRawScan),
&cbs_jpeg_free_scan);
if (err < 0)
@@ -304,7 +304,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx,
#define SEGMENT(marker, type, func, free) \
case JPEG_MARKER_ ## marker: \
{ \
err = ff_cbs_alloc_unit_content(ctx, unit, \
err = ff_cbs_alloc_unit_content(unit, \
sizeof(type), free); \
if (err < 0) \
return err; \
+3 -3
View File
@@ -207,7 +207,7 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
final = 1;
}
err = ff_cbs_insert_unit_data(ctx, frag, i, unit_type, (uint8_t*)start,
err = ff_cbs_insert_unit_data(frag, i, unit_type, (uint8_t*)start,
unit_size, frag->data_ref);
if (err < 0)
return err;
@@ -235,7 +235,7 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx,
MPEG2RawSlice *slice;
int pos, len;
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice),
err = ff_cbs_alloc_unit_content(unit, sizeof(*slice),
&cbs_mpeg2_free_slice);
if (err < 0)
return err;
@@ -265,7 +265,7 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx,
case start_code: \
{ \
type *header; \
err = ff_cbs_alloc_unit_content(ctx, unit, \
err = ff_cbs_alloc_unit_content(unit, \
sizeof(*header), free_func); \
if (err < 0) \
return err; \
+3 -3
View File
@@ -451,7 +451,7 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx,
return AVERROR_INVALIDDATA;
}
err = ff_cbs_insert_unit_data(ctx, frag, -1, 0,
err = ff_cbs_insert_unit_data(frag, -1, 0,
frag->data + pos,
sfi.frame_sizes[i],
frag->data_ref);
@@ -469,7 +469,7 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx,
return 0;
} else {
err = ff_cbs_insert_unit_data(ctx, frag, -1, 0,
err = ff_cbs_insert_unit_data(frag, -1, 0,
frag->data, frag->data_size,
frag->data_ref);
if (err < 0)
@@ -497,7 +497,7 @@ static int cbs_vp9_read_unit(CodedBitstreamContext *ctx,
if (err < 0)
return err;
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*frame),
err = ff_cbs_alloc_unit_content(unit, sizeof(*frame),
&cbs_vp9_free_frame);
if (err < 0)
return err;
+203 -91
View File
@@ -32,10 +32,6 @@
static const AVRational ms_tb = {1, 1000};
/*
* TODO list
* 1) handle font and color completely
*/
enum cc_mode {
CCMODE_POPON,
CCMODE_PAINTON,
@@ -173,6 +169,18 @@ static const char *charset_overrides[4][128] =
},
};
static const unsigned char bg_attribs[8] = // Color
{
CCCOL_WHITE,
CCCOL_GREEN,
CCCOL_BLUE,
CCCOL_CYAN,
CCCOL_RED,
CCCOL_YELLOW,
CCCOL_MAGENTA,
CCCOL_BLACK,
};
static const unsigned char pac2_attribs[32][3] = // Color, font, ident
{
{ CCCOL_WHITE, CCFONT_REGULAR, 0 }, // 0x40 || 0x60
@@ -215,6 +223,7 @@ struct Screen {
uint8_t characters[SCREEN_ROWS+1][SCREEN_COLUMNS+1];
uint8_t charsets[SCREEN_ROWS+1][SCREEN_COLUMNS+1];
uint8_t colors[SCREEN_ROWS+1][SCREEN_COLUMNS+1];
uint8_t bgs[SCREEN_ROWS+1][SCREEN_COLUMNS+1];
uint8_t fonts[SCREEN_ROWS+1][SCREEN_COLUMNS+1];
/*
* Bitmask of used rows; if a bit is not set, the
@@ -228,39 +237,37 @@ struct Screen {
typedef struct CCaptionSubContext {
AVClass *class;
int real_time;
int data_field;
struct Screen screen[2];
int active_screen;
uint8_t cursor_row;
uint8_t cursor_column;
uint8_t cursor_color;
uint8_t bg_color;
uint8_t cursor_font;
uint8_t cursor_charset;
AVBPrint buffer;
AVBPrint buffer[2];
int buffer_index;
int buffer_changed;
int rollup;
enum cc_mode mode;
int64_t start_time;
/* visible screen time */
int64_t startv_time;
int64_t end_time;
int64_t buffer_time[2];
int screen_touched;
int64_t last_real_time;
char prev_cmd[2];
/* buffer to store pkt data */
uint8_t *pktbuf;
int pktbuf_size;
uint8_t prev_cmd[2];
int readorder;
} CCaptionSubContext;
static av_cold int init_decoder(AVCodecContext *avctx)
{
int ret;
CCaptionSubContext *ctx = avctx->priv_data;
av_bprint_init(&ctx->buffer, 0, AV_BPRINT_SIZE_UNLIMITED);
av_bprint_init(&ctx->buffer[0], 0, AV_BPRINT_SIZE_UNLIMITED);
av_bprint_init(&ctx->buffer[1], 0, AV_BPRINT_SIZE_UNLIMITED);
/* taking by default roll up to 2 */
ctx->mode = CCMODE_ROLLUP;
ctx->bg_color = CCCOL_BLACK;
ctx->rollup = 2;
ctx->cursor_row = 10;
ret = ff_ass_subtitle_header(avctx, "Monospace",
@@ -282,9 +289,8 @@ static av_cold int init_decoder(AVCodecContext *avctx)
static av_cold int close_decoder(AVCodecContext *avctx)
{
CCaptionSubContext *ctx = avctx->priv_data;
av_bprint_finalize(&ctx->buffer, NULL);
av_freep(&ctx->pktbuf);
ctx->pktbuf_size = 0;
av_bprint_finalize(&ctx->buffer[0], NULL);
av_bprint_finalize(&ctx->buffer[1], NULL);
return 0;
}
@@ -301,6 +307,7 @@ static void flush_decoder(AVCodecContext *avctx)
ctx->cursor_column = 0;
ctx->cursor_font = 0;
ctx->cursor_color = 0;
ctx->bg_color = CCCOL_BLACK;
ctx->cursor_charset = 0;
ctx->active_screen = 0;
ctx->last_real_time = 0;
@@ -308,7 +315,8 @@ static void flush_decoder(AVCodecContext *avctx)
ctx->buffer_changed = 0;
if (!(avctx->flags2 & AV_CODEC_FLAG2_RO_FLUSH_NOOP))
ctx->readorder = 0;
av_bprint_clear(&ctx->buffer);
av_bprint_clear(&ctx->buffer[0]);
av_bprint_clear(&ctx->buffer[1]);
}
/**
@@ -319,11 +327,15 @@ static void write_char(CCaptionSubContext *ctx, struct Screen *screen, char ch)
uint8_t col = ctx->cursor_column;
char *row = screen->characters[ctx->cursor_row];
char *font = screen->fonts[ctx->cursor_row];
char *color = screen->colors[ctx->cursor_row];
char *bg = screen->bgs[ctx->cursor_row];
char *charset = screen->charsets[ctx->cursor_row];
if (col < SCREEN_COLUMNS) {
row[col] = ch;
font[col] = ctx->cursor_font;
color[col] = ctx->cursor_color;
bg[col] = ctx->bg_color;
charset[col] = ctx->cursor_charset;
ctx->cursor_charset = CCSET_BASIC_AMERICAN;
if (ch) ctx->cursor_column++;
@@ -347,11 +359,13 @@ static void write_char(CCaptionSubContext *ctx, struct Screen *screen, char ch)
* If the second byte doesn't pass parity, it returns INVALIDDATA
* user can ignore the whole pair and pass the other pair.
*/
static int validate_cc_data_pair(uint8_t *cc_data_pair)
static int validate_cc_data_pair(const uint8_t *cc_data_pair, uint8_t *hi)
{
uint8_t cc_valid = (*cc_data_pair & 4) >>2;
uint8_t cc_type = *cc_data_pair & 3;
*hi = cc_data_pair[1];
if (!cc_valid)
return AVERROR_INVALIDDATA;
@@ -361,7 +375,7 @@ static int validate_cc_data_pair(uint8_t *cc_data_pair)
return AVERROR_INVALIDDATA;
}
if (!av_parity(cc_data_pair[1])) {
cc_data_pair[1]=0x7F;
*hi = 0x7F;
}
}
@@ -374,10 +388,6 @@ static int validate_cc_data_pair(uint8_t *cc_data_pair)
if (cc_type == 3 || cc_type == 2)
return AVERROR_PATCHWELCOME;
/* remove parity bit */
cc_data_pair[1] &= 0x7F;
cc_data_pair[2] &= 0x7F;
return 0;
}
@@ -423,6 +433,7 @@ static void roll_up(CCaptionSubContext *ctx)
memcpy(screen->characters[i_row], screen->characters[i_row+1], SCREEN_COLUMNS);
memcpy(screen->colors[i_row], screen->colors[i_row+1], SCREEN_COLUMNS);
memcpy(screen->bgs[i_row], screen->bgs[i_row+1], SCREEN_COLUMNS);
memcpy(screen->fonts[i_row], screen->fonts[i_row+1], SCREEN_COLUMNS);
memcpy(screen->charsets[i_row], screen->charsets[i_row+1], SCREEN_COLUMNS);
if (CHECK_FLAG(screen->row_used, i_row + 1))
@@ -437,7 +448,11 @@ static int capture_screen(CCaptionSubContext *ctx)
int i, j, tab = 0;
struct Screen *screen = ctx->screen + ctx->active_screen;
enum cc_font prev_font = CCFONT_REGULAR;
av_bprint_clear(&ctx->buffer);
enum cc_color_code prev_color = CCCOL_WHITE;
enum cc_color_code prev_bg_color = CCCOL_BLACK;
const int bidx = ctx->buffer_index;
av_bprint_clear(&ctx->buffer[bidx]);
for (i = 0; screen->row_used && i < SCREEN_ROWS; i++)
{
@@ -457,6 +472,8 @@ static int capture_screen(CCaptionSubContext *ctx)
if (CHECK_FLAG(screen->row_used, i)) {
const char *row = screen->characters[i];
const char *font = screen->fonts[i];
const char *bg = screen->bgs[i];
const char *color = screen->colors[i];
const char *charset = screen->charsets[i];
const char *override;
int x, y, seen_char = 0;
@@ -468,10 +485,10 @@ static int capture_screen(CCaptionSubContext *ctx)
x = ASS_DEFAULT_PLAYRESX * (0.1 + 0.0250 * j);
y = ASS_DEFAULT_PLAYRESY * (0.1 + 0.0533 * i);
av_bprintf(&ctx->buffer, "{\\an7}{\\pos(%d,%d)}", x, y);
av_bprintf(&ctx->buffer[bidx], "{\\an7}{\\pos(%d,%d)}", x, y);
for (; j < SCREEN_COLUMNS; j++) {
const char *e_tag = "", *s_tag = "";
const char *e_tag = "", *s_tag = "", *c_tag = "", *b_tag = "";
if (row[j] == 0)
break;
@@ -500,38 +517,99 @@ static int capture_screen(CCaptionSubContext *ctx)
break;
}
}
if (prev_color != color[j]) {
switch (color[j]) {
case CCCOL_WHITE:
c_tag = "{\\c&HFFFFFF&}";
break;
case CCCOL_GREEN:
c_tag = "{\\c&H00FF00&}";
break;
case CCCOL_BLUE:
c_tag = "{\\c&HFF0000&}";
break;
case CCCOL_CYAN:
c_tag = "{\\c&HFFFF00&}";
break;
case CCCOL_RED:
c_tag = "{\\c&H0000FF&}";
break;
case CCCOL_YELLOW:
c_tag = "{\\c&H00FFFF&}";
break;
case CCCOL_MAGENTA:
c_tag = "{\\c&HFF00FF&}";
break;
}
}
if (prev_bg_color != bg[j]) {
switch (bg[j]) {
case CCCOL_WHITE:
b_tag = "{\\3c&HFFFFFF&}";
break;
case CCCOL_GREEN:
b_tag = "{\\3c&H00FF00&}";
break;
case CCCOL_BLUE:
b_tag = "{\\3c&HFF0000&}";
break;
case CCCOL_CYAN:
b_tag = "{\\3c&HFFFF00&}";
break;
case CCCOL_RED:
b_tag = "{\\3c&H0000FF&}";
break;
case CCCOL_YELLOW:
b_tag = "{\\3c&H00FFFF&}";
break;
case CCCOL_MAGENTA:
b_tag = "{\\3c&HFF00FF&}";
break;
case CCCOL_BLACK:
b_tag = "{\\3c&H000000&}";
break;
}
}
prev_font = font[j];
prev_color = color[j];
prev_bg_color = bg[j];
override = charset_overrides[(int)charset[j]][(int)row[j]];
if (override) {
av_bprintf(&ctx->buffer, "%s%s%s", e_tag, s_tag, override);
av_bprintf(&ctx->buffer[bidx], "%s%s%s%s%s", e_tag, s_tag, c_tag, b_tag, override);
seen_char = 1;
} else if (row[j] == ' ' && !seen_char) {
av_bprintf(&ctx->buffer, "%s%s\\h", e_tag, s_tag);
av_bprintf(&ctx->buffer[bidx], "%s%s%s%s\\h", e_tag, s_tag, c_tag, b_tag);
} else {
av_bprintf(&ctx->buffer, "%s%s%c", e_tag, s_tag, row[j]);
av_bprintf(&ctx->buffer[bidx], "%s%s%s%s%c", e_tag, s_tag, c_tag, b_tag, row[j]);
seen_char = 1;
}
}
av_bprintf(&ctx->buffer, "\\N");
av_bprintf(&ctx->buffer[bidx], "\\N");
}
}
if (!av_bprint_is_complete(&ctx->buffer))
if (!av_bprint_is_complete(&ctx->buffer[bidx]))
return AVERROR(ENOMEM);
if (screen->row_used && ctx->buffer.len >= 2) {
ctx->buffer.len -= 2;
ctx->buffer.str[ctx->buffer.len] = 0;
if (screen->row_used && ctx->buffer[bidx].len >= 2) {
ctx->buffer[bidx].len -= 2;
ctx->buffer[bidx].str[ctx->buffer[bidx].len] = 0;
}
ctx->buffer_changed = 1;
return 0;
}
static int reap_screen(CCaptionSubContext *ctx, int64_t pts)
static void update_time(CCaptionSubContext *ctx, int64_t pts)
{
ctx->start_time = ctx->startv_time;
ctx->startv_time = pts;
ctx->end_time = pts;
return capture_screen(ctx);
ctx->buffer_time[0] = ctx->buffer_time[1];
ctx->buffer_time[1] = pts;
}
static void handle_bgattr(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo)
{
const int i = (lo & 0xf) >> 1;
ctx->bg_color = bg_attribs[i];
}
static void handle_textattr(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo)
@@ -576,49 +654,55 @@ static void handle_pac(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo)
}
}
/**
* @param pts it is required to set end time
*/
static void handle_edm(CCaptionSubContext *ctx, int64_t pts)
static int handle_edm(CCaptionSubContext *ctx)
{
struct Screen *screen = ctx->screen + ctx->active_screen;
int ret;
// In buffered mode, keep writing to screen until it is wiped.
// Before wiping the display, capture contents to emit subtitle.
if (!ctx->real_time)
reap_screen(ctx, pts);
ret = capture_screen(ctx);
screen->row_used = 0;
ctx->bg_color = CCCOL_BLACK;
// In realtime mode, emit an empty caption so the last one doesn't
// stay on the screen.
if (ctx->real_time)
reap_screen(ctx, pts);
ret = capture_screen(ctx);
return ret;
}
static void handle_eoc(CCaptionSubContext *ctx, int64_t pts)
static int handle_eoc(CCaptionSubContext *ctx)
{
// In buffered mode, we wait til the *next* EOC and
// reap what was already on the screen since the last EOC.
if (!ctx->real_time)
handle_edm(ctx,pts);
int ret;
ctx->active_screen = !ctx->active_screen;
// In buffered mode, we wait til the *next* EOC and
// capture what was already on the screen since the last EOC.
if (!ctx->real_time)
ret = handle_edm(ctx);
ctx->cursor_column = 0;
// In realtime mode, we display the buffered contents (after
// flipping the buffer to active above) as soon as EOC arrives.
if (ctx->real_time)
reap_screen(ctx, pts);
ret = capture_screen(ctx);
return ret;
}
static void handle_delete_end_of_row(CCaptionSubContext *ctx, char hi, char lo)
static void handle_delete_end_of_row(CCaptionSubContext *ctx)
{
struct Screen *screen = get_writing_screen(ctx);
write_char(ctx, screen, 0);
}
static void handle_char(CCaptionSubContext *ctx, char hi, char lo, int64_t pts)
static void handle_char(CCaptionSubContext *ctx, char hi, char lo)
{
struct Screen *screen = get_writing_screen(ctx);
@@ -658,11 +742,12 @@ static void handle_char(CCaptionSubContext *ctx, char hi, char lo, int64_t pts)
ff_dlog(ctx, "(%c)\n", hi);
}
static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint8_t lo)
static int process_cc608(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo)
{
int ret = 0;
if (hi == ctx->prev_cmd[0] && lo == ctx->prev_cmd[1]) {
/* ignore redundant command */
return;
return 0;
}
/* set prev command */
@@ -675,6 +760,8 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint
} else if ( ( hi == 0x11 && lo >= 0x20 && lo <= 0x2f ) ||
( hi == 0x17 && lo >= 0x2e && lo <= 0x2f) ) {
handle_textattr(ctx, hi, lo);
} else if ((hi == 0x10 && lo >= 0x20 && lo <= 0x2f)) {
handle_bgattr(ctx, hi, lo);
} else if (hi == 0x14 || hi == 0x15 || hi == 0x1c) {
switch (lo) {
case 0x20:
@@ -682,7 +769,7 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint
ctx->mode = CCMODE_POPON;
break;
case 0x24:
handle_delete_end_of_row(ctx, hi, lo);
handle_delete_end_of_row(ctx);
break;
case 0x25:
case 0x26:
@@ -700,13 +787,13 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint
break;
case 0x2c:
/* erase display memory */
handle_edm(ctx, pts);
handle_edm(ctx);
break;
case 0x2d:
/* carriage return */
ff_dlog(ctx, "carriage return\n");
if (!ctx->real_time)
reap_screen(ctx, pts);
ret = capture_screen(ctx);
roll_up(ctx);
ctx->cursor_column = 0;
break;
@@ -722,7 +809,7 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint
case 0x2f:
/* end of caption */
ff_dlog(ctx, "handle_eoc\n");
handle_eoc(ctx, pts);
ret = handle_eoc(ctx);
break;
default:
ff_dlog(ctx, "Unknown command 0x%hhx 0x%hhx\n", hi, lo);
@@ -730,73 +817,93 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint
}
} else if (hi >= 0x11 && hi <= 0x13) {
/* Special characters */
handle_char(ctx, hi, lo, pts);
handle_char(ctx, hi, lo);
} else if (hi >= 0x20) {
/* Standard characters (always in pairs) */
handle_char(ctx, hi, lo, pts);
handle_char(ctx, hi, lo);
ctx->prev_cmd[0] = ctx->prev_cmd[1] = 0;
} else if (hi == 0x17 && lo >= 0x21 && lo <= 0x23) {
int i;
/* Tab offsets (spacing) */
for (i = 0; i < lo - 0x20; i++) {
handle_char(ctx, ' ', 0, pts);
handle_char(ctx, ' ', 0);
}
} else {
/* Ignoring all other non data code */
ff_dlog(ctx, "Unknown command 0x%hhx 0x%hhx\n", hi, lo);
}
return ret;
}
static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt)
{
CCaptionSubContext *ctx = avctx->priv_data;
AVSubtitle *sub = data;
const int64_t start_time = sub->pts;
uint8_t *bptr = NULL;
int64_t in_time = sub->pts;
int64_t start_time;
int64_t end_time;
int bidx = ctx->buffer_index;
const uint8_t *bptr = avpkt->data;
int len = avpkt->size;
int ret = 0;
int i;
av_fast_padded_malloc(&ctx->pktbuf, &ctx->pktbuf_size, len);
if (!ctx->pktbuf) {
av_log(ctx, AV_LOG_WARNING, "Insufficient Memory of %d truncated to %d\n", len, ctx->pktbuf_size);
return AVERROR(ENOMEM);
}
memcpy(ctx->pktbuf, avpkt->data, len);
bptr = ctx->pktbuf;
for (i = 0; i < len; i += 3) {
uint8_t hi, cc_type = bptr[i] & 1;
for (i = 0; i < len; i += 3) {
uint8_t cc_type = *(bptr + i) & 3;
if (validate_cc_data_pair(bptr + i))
if (ctx->data_field < 0)
ctx->data_field = cc_type;
if (validate_cc_data_pair(bptr + i, &hi))
continue;
/* ignoring data field 1 */
if(cc_type == 1)
if (cc_type != ctx->data_field)
continue;
else
process_cc608(ctx, start_time, *(bptr + i + 1) & 0x7f, *(bptr + i + 2) & 0x7f);
ret = process_cc608(ctx, hi & 0x7f, bptr[i + 2] & 0x7f);
if (ret < 0)
return ret;
if (!ctx->buffer_changed)
continue;
ctx->buffer_changed = 0;
if (*ctx->buffer.str || ctx->real_time)
{
ff_dlog(ctx, "cdp writing data (%s)\n",ctx->buffer.str);
ret = ff_ass_add_rect(sub, ctx->buffer.str, ctx->readorder++, 0, NULL, NULL);
if (ret < 0)
return ret;
sub->pts = ctx->start_time;
if (!ctx->real_time && ctx->mode == CCMODE_POPON)
ctx->buffer_index = bidx = !ctx->buffer_index;
update_time(ctx, in_time);
if (ctx->buffer[bidx].str[0] || ctx->real_time) {
ff_dlog(ctx, "cdp writing data (%s)\n", ctx->buffer[bidx].str);
start_time = ctx->buffer_time[0];
sub->pts = start_time;
end_time = ctx->buffer_time[1];
if (!ctx->real_time)
sub->end_display_time = av_rescale_q(ctx->end_time - ctx->start_time,
sub->end_display_time = av_rescale_q(end_time - start_time,
AV_TIME_BASE_Q, ms_tb);
else
sub->end_display_time = -1;
ctx->buffer_changed = 0;
ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL);
if (ret < 0)
return ret;
ctx->last_real_time = sub->pts;
ctx->screen_touched = 0;
}
}
if (!bptr && !ctx->real_time && ctx->buffer[!ctx->buffer_index].str[0]) {
bidx = !ctx->buffer_index;
ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL);
if (ret < 0)
return ret;
sub->pts = ctx->buffer_time[1];
sub->end_display_time = av_rescale_q(ctx->buffer_time[1] - ctx->buffer_time[0],
AV_TIME_BASE_Q, ms_tb);
if (sub->end_display_time == 0)
sub->end_display_time = ctx->buffer[bidx].len * 20;
}
if (ctx->real_time && ctx->screen_touched &&
sub->pts > ctx->last_real_time + av_rescale_q(200, ms_tb, AV_TIME_BASE_Q)) {
ctx->last_real_time = sub->pts;
@@ -805,7 +912,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
capture_screen(ctx);
ctx->buffer_changed = 0;
ret = ff_ass_add_rect(sub, ctx->buffer.str, ctx->readorder++, 0, NULL, NULL);
ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL);
if (ret < 0)
return ret;
sub->end_display_time = -1;
@@ -819,6 +926,10 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
{ "real_time", "emit subtitle events as they are decoded for real-time display", OFFSET(real_time), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, SD },
{ "data_field", "select data field", OFFSET(data_field), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, SD, "data_field" },
{ "auto", "pick first one that appears", 0, AV_OPT_TYPE_CONST, { .i64 =-1 }, 0, 0, SD, "data_field" },
{ "first", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, SD, "data_field" },
{ "second", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, SD, "data_field" },
{NULL}
};
@@ -840,4 +951,5 @@ AVCodec ff_ccaption_decoder = {
.flush = flush_decoder,
.decode = decode,
.priv_class = &ccaption_dec_class,
.capabilities = AV_CODEC_CAP_DELAY,
};
+21 -11
View File
@@ -41,15 +41,25 @@
#define ALPHA_COMPAND_GAIN 9400
enum CFHDParam {
SampleType = 1,
SampleIndexTable = 2,
BitstreamMarker = 4,
TransformType = 10,
ChannelCount = 12,
SubbandCount = 14,
ImageWidth = 20,
ImageHeight = 21,
LowpassWidth = 27,
LowpassHeight = 28,
LowpassPrecision = 35,
HighpassWidth = 41,
HighpassHeight = 42,
SubbandNumber = 48,
Quantization = 53,
BandHeader = 55,
ChannelNumber = 62,
SampleFlags = 68,
EncodedFormat = 84,
BitsPerComponent = 101,
ChannelWidth = 104,
ChannelHeight = 105,
@@ -479,7 +489,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
s->prescale_shift[1] = (data >> 3) & 0x7;
s->prescale_shift[2] = (data >> 6) & 0x7;
av_log(avctx, AV_LOG_DEBUG, "Prescale shift (VC-5): %x\n", data);
} else if (tag == 27) {
} else if (tag == LowpassWidth) {
av_log(avctx, AV_LOG_DEBUG, "Lowpass width %"PRIu16"\n", data);
if (data < 3 || data > s->plane[s->channel_num].band[0][0].a_width) {
av_log(avctx, AV_LOG_ERROR, "Invalid lowpass width\n");
@@ -488,7 +498,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
}
s->plane[s->channel_num].band[0][0].width = data;
s->plane[s->channel_num].band[0][0].stride = data;
} else if (tag == 28) {
} else if (tag == LowpassHeight) {
av_log(avctx, AV_LOG_DEBUG, "Lowpass height %"PRIu16"\n", data);
if (data < 3 || data > s->plane[s->channel_num].band[0][0].a_height) {
av_log(avctx, AV_LOG_ERROR, "Invalid lowpass height\n");
@@ -496,9 +506,9 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
break;
}
s->plane[s->channel_num].band[0][0].height = data;
} else if (tag == 1)
} else if (tag == SampleType)
av_log(avctx, AV_LOG_DEBUG, "Sample type? %"PRIu16"\n", data);
else if (tag == 10) {
else if (tag == TransformType) {
if (data != 0) {
avpriv_report_missing_feature(avctx, "Transform type of %"PRIu16, data);
ret = AVERROR_PATCHWELCOME;
@@ -515,7 +525,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
avpriv_report_missing_feature(avctx, "Skip frame");
ret = AVERROR_PATCHWELCOME;
break;
} else if (tag == 2) {
} else if (tag == SampleIndexTable) {
av_log(avctx, AV_LOG_DEBUG, "tag=2 header - skipping %i tag/value pairs\n", data);
if (data > bytestream2_get_bytes_left(&gb) / 4) {
av_log(avctx, AV_LOG_ERROR, "too many tag/value pairs (%d)\n", data);
@@ -527,7 +537,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
uint16_t val2 = bytestream2_get_be16(&gb);
av_log(avctx, AV_LOG_DEBUG, "Tag/Value = %x %x\n", tag2, val2);
}
} else if (tag == 41) {
} else if (tag == HighpassWidth) {
av_log(avctx, AV_LOG_DEBUG, "Highpass width %i channel %i level %i subband %i\n", data, s->channel_num, s->level, s->subband_num);
if (data < 3) {
av_log(avctx, AV_LOG_ERROR, "Invalid highpass width\n");
@@ -536,7 +546,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
}
s->plane[s->channel_num].band[s->level][s->subband_num].width = data;
s->plane[s->channel_num].band[s->level][s->subband_num].stride = FFALIGN(data, 8);
} else if (tag == 42) {
} else if (tag == HighpassHeight) {
av_log(avctx, AV_LOG_DEBUG, "Highpass height %i\n", data);
if (data < 3) {
av_log(avctx, AV_LOG_ERROR, "Invalid highpass height\n");
@@ -576,7 +586,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
break;
}
s->bpc = data;
} else if (tag == 84) {
} else if (tag == EncodedFormat) {
av_log(avctx, AV_LOG_DEBUG, "Sample format? %i\n", data);
if (data == 1) {
s->coded_format = AV_PIX_FMT_YUV422P10;
@@ -612,7 +622,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
av_log(avctx, AV_LOG_DEBUG, "Unknown tag %i data %x\n", tag, data);
/* Some kind of end of header tag */
if (tag == 4 && data == 0x1a4a && s->coded_width && s->coded_height &&
if (tag == BitstreamMarker && data == 0x1a4a && s->coded_width && s->coded_height &&
s->coded_format != AV_PIX_FMT_NONE) {
if (s->a_width != s->coded_width || s->a_height != s->coded_height ||
s->a_format != s->coded_format) {
@@ -645,7 +655,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
coeff_data = s->plane[s->channel_num].subband[s->subband_num_actual];
/* Lowpass coefficients */
if (tag == 4 && data == 0xf0f && s->a_width && s->a_height) {
if (tag == BitstreamMarker && data == 0xf0f && s->a_width && s->a_height) {
int lowpass_height = s->plane[s->channel_num].band[0][0].height;
int lowpass_width = s->plane[s->channel_num].band[0][0].width;
int lowpass_a_height = s->plane[s->channel_num].band[0][0].a_height;
@@ -685,7 +695,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
av_log(avctx, AV_LOG_DEBUG, "Lowpass coefficients %d\n", lowpass_width * lowpass_height);
}
if (tag == 55 && s->subband_num_actual != 255 && s->a_width && s->a_height) {
if (tag == BandHeader && s->subband_num_actual != 255 && s->a_width && s->a_height) {
int highpass_height = s->plane[s->channel_num].band[s->level][s->subband_num].height;
int highpass_width = s->plane[s->channel_num].band[s->level][s->subband_num].width;
int highpass_a_width = s->plane[s->channel_num].band[s->level][s->subband_num].a_width;
+3 -7
View File
@@ -282,14 +282,10 @@ typedef struct AVCodec {
int (*decode)(struct AVCodecContext *, void *outdata, int *outdata_size, struct AVPacket *avpkt);
int (*close)(struct AVCodecContext *);
/**
* Encode API with decoupled packet/frame dataflow. The API is the
* same as the avcodec_ prefixed APIs (avcodec_send_frame() etc.), except
* that:
* - never called if the codec is closed or the wrong type,
* - if AV_CODEC_CAP_DELAY is not set, drain frames are never sent,
* - only one drain frame is ever passed down,
* Encode API with decoupled frame/packet dataflow. This function is called
* to get one output packet. It should call ff_encode_get_frame() to obtain
* input data.
*/
int (*send_frame)(struct AVCodecContext *avctx, const struct AVFrame *frame);
int (*receive_packet)(struct AVCodecContext *avctx, struct AVPacket *avpkt);
/**
+8 -1
View File
@@ -1405,6 +1405,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("AVS2-P2/IEEE1857.4"),
.props = AV_CODEC_PROP_LOSSY,
},
{
.id = AV_CODEC_ID_PGX,
.type = AVMEDIA_TYPE_VIDEO,
.name = "pgx",
.long_name = NULL_IF_CONFIG_SMALL("PGX (JPEG2000 Test Format)"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
},
{
.id = AV_CODEC_ID_Y41P,
.type = AVMEDIA_TYPE_VIDEO,
@@ -2897,7 +2904,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
.type = AVMEDIA_TYPE_AUDIO,
.name = "tak",
.long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
.props = AV_CODEC_PROP_LOSSLESS,
},
{
.id = AV_CODEC_ID_METASOUND,
+1
View File
@@ -241,6 +241,7 @@ enum AVCodecID {
AV_CODEC_ID_SCREENPRESSO,
AV_CODEC_ID_RSCC,
AV_CODEC_ID_AVS2,
AV_CODEC_ID_PGX,
AV_CODEC_ID_Y41P = 0x8000,
AV_CODEC_ID_AVRP,
+1 -1
View File
@@ -66,7 +66,7 @@ typedef struct FramePool {
static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt)
{
int size = 0, ret;
int size, ret;
const uint8_t *data;
uint32_t flags;
int64_t val;
+22 -43
View File
@@ -207,15 +207,11 @@ static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx)
int i, j, level, run;
int max_level = 1 << (ctx->bit_depth + 2);
FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->orig_vlc_codes,
max_level, 4 * sizeof(*ctx->orig_vlc_codes), fail);
FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->orig_vlc_bits,
max_level, 4 * sizeof(*ctx->orig_vlc_bits), fail);
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_codes,
63 * 2, fail);
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_bits,
63, fail);
if (!FF_ALLOCZ_TYPED_ARRAY(ctx->orig_vlc_codes, max_level * 4) ||
!FF_ALLOCZ_TYPED_ARRAY(ctx->orig_vlc_bits, max_level * 4) ||
!(ctx->run_codes = av_mallocz(63 * 2)) ||
!(ctx->run_bits = av_mallocz(63)))
return AVERROR(ENOMEM);
ctx->vlc_codes = ctx->orig_vlc_codes + max_level * 2;
ctx->vlc_bits = ctx->orig_vlc_bits + max_level * 2;
for (level = -max_level; level < max_level; level++) {
@@ -259,8 +255,6 @@ static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx)
ctx->run_bits[run] = ctx->cid_table->run_bits[i];
}
return 0;
fail:
return AVERROR(ENOMEM);
}
static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
@@ -271,16 +265,11 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
const uint8_t *luma_weight_table = ctx->cid_table->luma_weight;
const uint8_t *chroma_weight_table = ctx->cid_table->chroma_weight;
FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l,
(ctx->m.avctx->qmax + 1), 64 * sizeof(int), fail);
FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c,
(ctx->m.avctx->qmax + 1), 64 * sizeof(int), fail);
FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l16,
(ctx->m.avctx->qmax + 1), 64 * 2 * sizeof(uint16_t),
fail);
FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c16,
(ctx->m.avctx->qmax + 1), 64 * 2 * sizeof(uint16_t),
fail);
if (!FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l, ctx->m.avctx->qmax + 1) ||
!FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c, ctx->m.avctx->qmax + 1) ||
!FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l16, ctx->m.avctx->qmax + 1) ||
!FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c16, ctx->m.avctx->qmax + 1))
return AVERROR(ENOMEM);
if (ctx->bit_depth == 8) {
for (i = 1; i < 64; i++) {
@@ -339,27 +328,23 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
ctx->m.q_intra_matrix = ctx->qmatrix_l;
return 0;
fail:
return AVERROR(ENOMEM);
}
static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx)
{
FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_rc, (ctx->m.avctx->qmax + 1),
ctx->m.mb_num * sizeof(RCEntry), fail);
if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_rc, (ctx->m.avctx->qmax + 1) * ctx->m.mb_num))
return AVERROR(ENOMEM);
if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) {
FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_cmp,
ctx->m.mb_num, sizeof(RCCMPEntry), fail);
FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_cmp_tmp,
ctx->m.mb_num, sizeof(RCCMPEntry), fail);
if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp, ctx->m.mb_num) ||
!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp_tmp, ctx->m.mb_num))
return AVERROR(ENOMEM);
}
ctx->frame_bits = (ctx->coding_unit_size -
ctx->data_offset - 4 - ctx->min_padding) * 8;
ctx->qscale = 1;
ctx->lambda = 2 << LAMBDA_FRAC_BITS; // qscale 2
return 0;
fail:
return AVERROR(ENOMEM);
}
static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
@@ -510,15 +495,11 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
if ((ret = dnxhd_init_rc(ctx)) < 0)
return ret;
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_size,
ctx->m.mb_height * sizeof(uint32_t), fail);
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_offs,
ctx->m.mb_height * sizeof(uint32_t), fail);
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_bits,
ctx->m.mb_num * sizeof(uint16_t), fail);
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale,
ctx->m.mb_num * sizeof(uint8_t), fail);
if (!FF_ALLOCZ_TYPED_ARRAY(ctx->slice_size, ctx->m.mb_height) ||
!FF_ALLOCZ_TYPED_ARRAY(ctx->slice_offs, ctx->m.mb_height) ||
!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_bits, ctx->m.mb_num) ||
!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_qscale, ctx->m.mb_num))
return AVERROR(ENOMEM);
#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
avctx->coded_frame->key_frame = 1;
@@ -543,14 +524,12 @@ FF_ENABLE_DEPRECATION_WARNINGS
for (i = 1; i < avctx->thread_count; i++) {
ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext));
if (!ctx->thread[i])
goto fail;
return AVERROR(ENOMEM);
memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext));
}
}
return 0;
fail: // for FF_ALLOCZ_OR_GOTO
return AVERROR(ENOMEM);
}
static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf)
+1 -17
View File
@@ -35,20 +35,12 @@
/* parser definition */
typedef struct DVBSubParseContext {
uint8_t *packet_buf;
int packet_start;
int packet_index;
int in_packet;
uint8_t packet_buf[PARSE_BUF_SIZE];
} DVBSubParseContext;
static av_cold int dvbsub_parse_init(AVCodecParserContext *s)
{
DVBSubParseContext *pc = s->priv_data;
pc->packet_buf = av_malloc(PARSE_BUF_SIZE);
return 0;
}
static int dvbsub_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
@@ -173,16 +165,8 @@ static int dvbsub_parse(AVCodecParserContext *s,
return buf_size;
}
static av_cold void dvbsub_parse_close(AVCodecParserContext *s)
{
DVBSubParseContext *pc = s->priv_data;
av_freep(&pc->packet_buf);
}
AVCodecParser ff_dvbsub_parser = {
.codec_ids = { AV_CODEC_ID_DVB_SUBTITLE },
.priv_data_size = sizeof(DVBSubParseContext),
.parser_init = dvbsub_parse_init,
.parser_parse = dvbsub_parse,
.parser_close = dvbsub_parse_close,
};
+64 -63
View File
@@ -710,8 +710,8 @@ static void compute_default_clut(DVBSubContext *ctx, uint8_t *clut, AVSubtitleRe
}
count = FFMAX(i - 1, 1);
for (i--; i>=0; i--) {
int v = i*255/count;
for (i--; i >= 0; i--) {
int v = i * 255 / count;
AV_WN32(clut + 4*list_inv[i], RGBA(v/2,v,v/2,v));
}
}
@@ -737,7 +737,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou
}
/* Not touching AVSubtitles again*/
if(sub->num_rects) {
if (sub->num_rects) {
avpriv_request_sample(ctx, "Different Version of Segment asked Twice");
return AVERROR_PATCHWELCOME;
}
@@ -747,7 +747,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou
sub->num_rects++;
}
if(ctx->compute_edt == 0) {
if (ctx->compute_edt == 0) {
sub->end_display_time = ctx->time_out * 1000;
*got_output = 1;
} else if (ctx->prev_start != AV_NOPTS_VALUE) {
@@ -813,7 +813,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou
ret = AVERROR(ENOMEM);
goto fail;
}
memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));
memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(*clut_table));
rect->data[0] = av_malloc(region->buf_size);
if (!rect->data[0]) {
@@ -851,7 +851,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
return 0;
fail:
if (sub->rects) {
for(i=0; i<sub->num_rects; i++) {
for (i=0; i < sub->num_rects; i++) {
rect = sub->rects[i];
if (rect) {
av_freep(&rect->data[0]);
@@ -1073,11 +1073,11 @@ static int dvbsub_parse_clut_segment(AVCodecContext *avctx,
clut = get_clut(ctx, clut_id);
if (!clut) {
clut = av_malloc(sizeof(DVBSubCLUT));
clut = av_malloc(sizeof(*clut));
if (!clut)
return AVERROR(ENOMEM);
memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
memcpy(clut, &default_clut, sizeof(*clut));
clut->id = clut_id;
clut->version = -1;
@@ -1088,53 +1088,53 @@ static int dvbsub_parse_clut_segment(AVCodecContext *avctx,
if (clut->version != version) {
clut->version = version;
clut->version = version;
while (buf + 4 < buf_end) {
entry_id = *buf++;
while (buf + 4 < buf_end) {
entry_id = *buf++;
depth = (*buf) & 0xe0;
depth = (*buf) & 0xe0;
if (depth == 0) {
av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
if (depth == 0) {
av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
}
full_range = (*buf++) & 1;
if (full_range) {
y = *buf++;
cr = *buf++;
cb = *buf++;
alpha = *buf++;
} else {
y = buf[0] & 0xfc;
cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
cb = (buf[1] << 2) & 0xf0;
alpha = (buf[1] << 6) & 0xc0;
buf += 2;
}
if (y == 0)
alpha = 0xff;
YUV_TO_RGB1_CCIR(cb, cr);
YUV_TO_RGB2_CCIR(r, g, b, y);
ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
ff_dlog(avctx, "More than one bit level marked: %x\n", depth);
if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL)
return AVERROR_INVALIDDATA;
}
if (depth & 0x80 && entry_id < 4)
clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
else if (depth & 0x40 && entry_id < 16)
clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
else if (depth & 0x20)
clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
}
full_range = (*buf++) & 1;
if (full_range) {
y = *buf++;
cr = *buf++;
cb = *buf++;
alpha = *buf++;
} else {
y = buf[0] & 0xfc;
cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
cb = (buf[1] << 2) & 0xf0;
alpha = (buf[1] << 6) & 0xc0;
buf += 2;
}
if (y == 0)
alpha = 0xff;
YUV_TO_RGB1_CCIR(cb, cr);
YUV_TO_RGB2_CCIR(r, g, b, y);
ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
ff_dlog(avctx, "More than one bit level marked: %x\n", depth);
if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL)
return AVERROR_INVALIDDATA;
}
if (depth & 0x80 && entry_id < 4)
clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
else if (depth & 0x40 && entry_id < 16)
clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
else if (depth & 0x20)
clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
}
}
return 0;
@@ -1163,7 +1163,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx,
region = get_region(ctx, region_id);
if (!region) {
region = av_mallocz(sizeof(DVBSubRegion));
region = av_mallocz(sizeof(*region));
if (!region)
return AVERROR(ENOMEM);
@@ -1210,7 +1210,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx,
}
region->depth = 1 << (((*buf++) >> 2) & 7);
if(region->depth<2 || region->depth>8){
if (region->depth < 2 || region->depth > 8) {
av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
region->depth= 4;
}
@@ -1244,7 +1244,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx,
object = get_object(ctx, object_id);
if (!object) {
object = av_mallocz(sizeof(DVBSubObject));
object = av_mallocz(sizeof(*object));
if (!object)
return AVERROR(ENOMEM);
@@ -1255,7 +1255,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx,
object->type = (*buf) >> 6;
display = av_mallocz(sizeof(DVBSubObjectDisplay));
display = av_mallocz(sizeof(*display));
if (!display)
return AVERROR(ENOMEM);
@@ -1318,7 +1318,7 @@ static int dvbsub_parse_page_segment(AVCodecContext *avctx,
ff_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
if(ctx->compute_edt == 1)
if (ctx->compute_edt == 1)
save_subtitle_set(avctx, sub, got_output);
if (page_state == 1 || page_state == 2) {
@@ -1352,7 +1352,7 @@ static int dvbsub_parse_page_segment(AVCodecContext *avctx,
}
if (!display) {
display = av_mallocz(sizeof(DVBSubRegionDisplay));
display = av_mallocz(sizeof(*display));
if (!display)
return AVERROR(ENOMEM);
}
@@ -1601,7 +1601,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
{
DVBSubContext *ctx = avctx->priv_data;
if(ctx->compute_edt == 0)
if (ctx->compute_edt == 0)
save_subtitle_set(avctx, sub, got_output);
#ifdef DEBUG
save_display_set(ctx);
@@ -1717,12 +1717,12 @@ static int dvbsub_decode(AVCodecContext *avctx,
}
end:
if(ret < 0) {
if (ret < 0) {
*got_sub_ptr = 0;
avsubtitle_free(sub);
return ret;
} else {
if(ctx->compute_edt == 1 )
if (ctx->compute_edt == 1)
FFSWAP(int64_t, ctx->prev_start, sub->pts);
}
@@ -1730,10 +1730,11 @@ end:
}
#define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
#define OFFSET(x) offsetof(DVBSubContext, x)
static const AVOption options[] = {
{"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DS},
{"compute_clut", "compute clut when not available(-1) or always(1) or never(0)", offsetof(DVBSubContext, compute_clut), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, DS},
{"dvb_substream", "", offsetof(DVBSubContext, substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS},
{"compute_edt", "compute end of time using pts or timeout", OFFSET(compute_edt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DS},
{"compute_clut", "compute clut when not available(-1) or always(1) or never(0)", OFFSET(compute_clut), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, DS},
{"dvb_substream", "", OFFSET(substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS},
{NULL}
};
static const AVClass dvbsubdec_class = {
-6
View File
@@ -32,11 +32,6 @@ typedef struct DVDSubParseContext {
int packet_index;
} DVDSubParseContext;
static av_cold int dvdsub_parse_init(AVCodecParserContext *s)
{
return 0;
}
static int dvdsub_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
@@ -92,7 +87,6 @@ static av_cold void dvdsub_parse_close(AVCodecParserContext *s)
AVCodecParser ff_dvdsub_parser = {
.codec_ids = { AV_CODEC_ID_DVD_SUBTITLE },
.priv_data_size = sizeof(DVDSubParseContext),
.parser_init = dvdsub_parse_init,
.parser_parse = dvdsub_parse,
.parser_close = dvdsub_parse_close,
};
+327 -329
View File
@@ -26,61 +26,43 @@
#include "libavutil/samplefmt.h"
#include "avcodec.h"
#include "encode.h"
#include "frame_thread_encoder.h"
#include "internal.h"
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
{
if (avpkt->size < 0) {
av_log(avctx, AV_LOG_ERROR, "Invalid negative user packet size %d\n", avpkt->size);
return AVERROR(EINVAL);
}
if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
av_log(avctx, AV_LOG_ERROR, "Invalid minimum required packet size %"PRId64" (max allowed is %d)\n",
size, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE);
return AVERROR(EINVAL);
}
av_assert0(!avpkt->data);
if (avctx && 2*min_size < size) { // FIXME The factor needs to be finetuned
av_assert0(!avpkt->data || avpkt->data != avctx->internal->byte_buffer);
if (!avpkt->data || avpkt->size < size) {
av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size);
avpkt->data = avctx->internal->byte_buffer;
avpkt->size = avctx->internal->byte_buffer_size;
}
av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size);
avpkt->data = avctx->internal->byte_buffer;
avpkt->size = size;
}
if (avpkt->data) {
AVBufferRef *buf = avpkt->buf;
if (avpkt->size < size) {
av_log(avctx, AV_LOG_ERROR, "User packet is too small (%d < %"PRId64")\n", avpkt->size, size);
return AVERROR(EINVAL);
}
av_init_packet(avpkt);
avpkt->buf = buf;
avpkt->size = size;
return 0;
} else {
if (!avpkt->data) {
int ret = av_new_packet(avpkt, size);
if (ret < 0)
av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %"PRId64"\n", size);
return ret;
}
return 0;
}
/**
* Pad last frame with silence.
*/
static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src)
static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src)
{
AVFrame *frame = NULL;
int ret;
if (!(frame = av_frame_alloc()))
return AVERROR(ENOMEM);
frame->format = src->format;
frame->channel_layout = src->channel_layout;
frame->channels = src->channels;
@@ -101,246 +83,10 @@ static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src)
s->channels, s->sample_fmt)) < 0)
goto fail;
*dst = frame;
return 0;
fail:
av_frame_free(&frame);
return ret;
}
int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
AVPacket *avpkt,
const AVFrame *frame,
int *got_packet_ptr)
{
AVFrame *extended_frame = NULL;
AVFrame *padded_frame = NULL;
int ret;
AVPacket user_pkt = *avpkt;
int needs_realloc = !user_pkt.data;
*got_packet_ptr = 0;
if (!avctx->codec->encode2) {
av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n");
return AVERROR(ENOSYS);
}
if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) {
av_packet_unref(avpkt);
return 0;
}
/* ensure that extended_data is properly set */
if (frame && !frame->extended_data) {
if (av_sample_fmt_is_planar(avctx->sample_fmt) &&
avctx->channels > AV_NUM_DATA_POINTERS) {
av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, "
"with more than %d channels, but extended_data is not set.\n",
AV_NUM_DATA_POINTERS);
return AVERROR(EINVAL);
}
av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n");
extended_frame = av_frame_alloc();
if (!extended_frame)
return AVERROR(ENOMEM);
memcpy(extended_frame, frame, sizeof(AVFrame));
extended_frame->extended_data = extended_frame->data;
frame = extended_frame;
}
/* extract audio service type metadata */
if (frame) {
AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_AUDIO_SERVICE_TYPE);
if (sd && sd->size >= sizeof(enum AVAudioServiceType))
avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data;
}
/* check for valid frame size */
if (frame) {
if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) {
if (frame->nb_samples > avctx->frame_size) {
av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n");
ret = AVERROR(EINVAL);
goto end;
}
} else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) {
/* if we already got an undersized frame, that must have been the last */
if (avctx->internal->last_audio_frame) {
av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame (avcodec_encode_audio2)\n", avctx->frame_size);
ret = AVERROR(EINVAL);
goto end;
}
if (frame->nb_samples < avctx->frame_size) {
ret = pad_last_frame(avctx, &padded_frame, frame);
if (ret < 0)
goto end;
frame = padded_frame;
avctx->internal->last_audio_frame = 1;
}
if (frame->nb_samples != avctx->frame_size) {
av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d) (avcodec_encode_audio2)\n", frame->nb_samples, avctx->frame_size);
ret = AVERROR(EINVAL);
goto end;
}
}
}
av_assert0(avctx->codec->encode2);
ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);
if (!ret) {
if (*got_packet_ptr) {
if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
if (avpkt->pts == AV_NOPTS_VALUE)
avpkt->pts = frame->pts;
if (!avpkt->duration)
avpkt->duration = ff_samples_to_time_base(avctx,
frame->nb_samples);
}
avpkt->dts = avpkt->pts;
} else {
avpkt->size = 0;
}
}
if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) {
needs_realloc = 0;
if (user_pkt.data) {
if (user_pkt.size >= avpkt->size) {
memcpy(user_pkt.data, avpkt->data, avpkt->size);
} else {
av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size);
avpkt->size = user_pkt.size;
ret = -1;
}
avpkt->buf = user_pkt.buf;
avpkt->data = user_pkt.data;
} else if (!avpkt->buf) {
ret = av_packet_make_refcounted(avpkt);
if (ret < 0)
goto end;
}
}
if (!ret) {
if (needs_realloc && avpkt->data) {
ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE);
if (ret >= 0)
avpkt->data = avpkt->buf->data;
}
if (frame)
avctx->frame_number++;
}
if (ret < 0 || !*got_packet_ptr) {
av_packet_unref(avpkt);
goto end;
}
/* NOTE: if we add any audio encoders which output non-keyframe packets,
* this needs to be moved to the encoders, but for now we can do it
* here to simplify things */
avpkt->flags |= AV_PKT_FLAG_KEY;
end:
av_frame_free(&padded_frame);
av_free(extended_frame);
return ret;
}
int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx,
AVPacket *avpkt,
const AVFrame *frame,
int *got_packet_ptr)
{
int ret;
AVPacket user_pkt = *avpkt;
int needs_realloc = !user_pkt.data;
*got_packet_ptr = 0;
if (!avctx->codec->encode2) {
av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n");
return AVERROR(ENOSYS);
}
if ((avctx->flags&AV_CODEC_FLAG_PASS1) && avctx->stats_out)
avctx->stats_out[0] = '\0';
if (!frame &&
!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY ||
(avctx->internal->frame_thread_encoder && avctx->active_thread_type & FF_THREAD_FRAME))) {
av_packet_unref(avpkt);
return 0;
}
if (av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx))
return AVERROR(EINVAL);
if (frame && frame->format == AV_PIX_FMT_NONE)
av_log(avctx, AV_LOG_WARNING, "AVFrame.format is not set\n");
if (frame && (frame->width == 0 || frame->height == 0))
av_log(avctx, AV_LOG_WARNING, "AVFrame.width or height is not set\n");
av_assert0(avctx->codec->encode2);
if (CONFIG_FRAME_THREAD_ENCODER &&
avctx->internal->frame_thread_encoder && (avctx->active_thread_type & FF_THREAD_FRAME))
ret = ff_thread_video_encode_frame(avctx, avpkt, frame, got_packet_ptr);
else {
ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);
if (*got_packet_ptr && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY))
avpkt->pts = avpkt->dts = frame->pts;
}
av_assert0(ret <= 0);
emms_c();
if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) {
needs_realloc = 0;
if (user_pkt.data) {
if (user_pkt.size >= avpkt->size) {
memcpy(user_pkt.data, avpkt->data, avpkt->size);
} else {
av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size);
avpkt->size = user_pkt.size;
ret = -1;
}
avpkt->buf = user_pkt.buf;
avpkt->data = user_pkt.data;
} else if (!avpkt->buf) {
ret = av_packet_make_refcounted(avpkt);
if (ret < 0)
return ret;
}
}
if (!ret) {
if (!*got_packet_ptr)
avpkt->size = 0;
if (needs_realloc && avpkt->data) {
ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE);
if (ret >= 0)
avpkt->data = avpkt->buf->data;
}
if (frame)
avctx->frame_number++;
}
if (ret < 0 || !*got_packet_ptr)
av_packet_unref(avpkt);
av_frame_unref(frame);
return ret;
}
@@ -358,101 +104,353 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
return ret;
}
static int do_encode(AVCodecContext *avctx, const AVFrame *frame, int *got_packet)
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
{
AVCodecInternal *avci = avctx->internal;
if (avci->draining)
return AVERROR_EOF;
if (!avci->buffer_frame->buf[0])
return AVERROR(EAGAIN);
av_frame_move_ref(frame, avci->buffer_frame);
return 0;
}
static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt)
{
AVCodecInternal *avci = avctx->internal;
EncodeSimpleContext *es = &avci->es;
AVFrame *frame = es->in_frame;
int got_packet;
int ret;
*got_packet = 0;
av_packet_unref(avctx->internal->buffer_pkt);
avctx->internal->buffer_pkt_valid = 0;
if (avci->draining_done)
return AVERROR_EOF;
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
ret = avcodec_encode_video2(avctx, avctx->internal->buffer_pkt,
frame, got_packet);
} else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
ret = avcodec_encode_audio2(avctx, avctx->internal->buffer_pkt,
frame, got_packet);
} else {
ret = AVERROR(EINVAL);
if (!frame->buf[0] && !avci->draining) {
av_frame_unref(frame);
ret = ff_encode_get_frame(avctx, frame);
if (ret < 0 && ret != AVERROR_EOF)
return ret;
}
if (ret >= 0 && *got_packet) {
if (!frame->buf[0]) {
if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY ||
(avci->frame_thread_encoder && avctx->active_thread_type & FF_THREAD_FRAME)))
return AVERROR_EOF;
// Flushing is signaled with a NULL frame
frame = NULL;
}
got_packet = 0;
av_assert0(avctx->codec->encode2);
if (CONFIG_FRAME_THREAD_ENCODER &&
avci->frame_thread_encoder && (avctx->active_thread_type & FF_THREAD_FRAME))
ret = ff_thread_video_encode_frame(avctx, avpkt, frame, &got_packet);
else {
ret = avctx->codec->encode2(avctx, avpkt, frame, &got_packet);
if (avctx->codec->type == AVMEDIA_TYPE_VIDEO && !ret && got_packet &&
!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY))
avpkt->pts = avpkt->dts = frame->pts;
}
av_assert0(ret <= 0);
emms_c();
if (!ret && got_packet) {
if (avpkt->data) {
ret = av_packet_make_refcounted(avpkt);
if (ret < 0)
goto end;
}
if (frame && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
if (avpkt->pts == AV_NOPTS_VALUE)
avpkt->pts = frame->pts;
if (!avpkt->duration)
avpkt->duration = ff_samples_to_time_base(avctx,
frame->nb_samples);
}
}
if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
/* NOTE: if we add any audio encoders which output non-keyframe packets,
* this needs to be moved to the encoders, but for now we can do it
* here to simplify things */
avpkt->flags |= AV_PKT_FLAG_KEY;
avpkt->dts = avpkt->pts;
}
}
if (avci->draining && !got_packet)
avci->draining_done = 1;
end:
if (ret < 0 || !got_packet)
av_packet_unref(avpkt);
if (frame) {
if (!ret)
avctx->frame_number++;
av_frame_unref(frame);
}
if (got_packet)
// Encoders must always return ref-counted buffers.
// Side-data only packets have no data and can be not ref-counted.
av_assert0(!avctx->internal->buffer_pkt->data || avctx->internal->buffer_pkt->buf);
avctx->internal->buffer_pkt_valid = 1;
ret = 0;
} else {
av_packet_unref(avctx->internal->buffer_pkt);
}
av_assert0(!avpkt->data || avpkt->buf);
return ret;
}
int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame)
static int encode_simple_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
{
if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec))
return AVERROR(EINVAL);
int ret;
if (avctx->internal->draining)
return AVERROR_EOF;
if (!frame) {
avctx->internal->draining = 1;
if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY))
return 0;
while (!avpkt->data && !avpkt->side_data) {
ret = encode_simple_internal(avctx, avpkt);
if (ret < 0)
return ret;
}
if (avctx->codec->send_frame)
return avctx->codec->send_frame(avctx, frame);
// Emulation via old API. Do it here instead of avcodec_receive_packet, because:
// 1. if the AVFrame is not refcounted, the copying will be much more
// expensive than copying the packet data
// 2. assume few users use non-refcounted AVPackets, so usually no copy is
// needed
if (avctx->internal->buffer_pkt_valid)
return AVERROR(EAGAIN);
return do_encode(avctx, frame, &(int){0});
return 0;
}
int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
static int encode_receive_packet_internal(AVCodecContext *avctx, AVPacket *avpkt)
{
av_packet_unref(avpkt);
AVCodecInternal *avci = avctx->internal;
int ret;
if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec))
return AVERROR(EINVAL);
if (avci->draining_done)
return AVERROR_EOF;
av_assert0(!avpkt->data && !avpkt->side_data);
if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) {
if ((avctx->flags & AV_CODEC_FLAG_PASS1) && avctx->stats_out)
avctx->stats_out[0] = '\0';
if (av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx))
return AVERROR(EINVAL);
}
if (avctx->codec->receive_packet) {
int ret;
if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY))
return AVERROR_EOF;
ret = avctx->codec->receive_packet(avctx, avpkt);
if (!ret)
// Encoders must always return ref-counted buffers.
// Side-data only packets have no data and can be not ref-counted.
av_assert0(!avpkt->data || avpkt->buf);
return ret;
} else
ret = encode_simple_receive_packet(avctx, avpkt);
if (ret == AVERROR_EOF)
avci->draining_done = 1;
return ret;
}
static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src)
{
AVCodecInternal *avci = avctx->internal;
AVFrame *dst = avci->buffer_frame;
int ret;
if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
/* extract audio service type metadata */
AVFrameSideData *sd = av_frame_get_side_data(src, AV_FRAME_DATA_AUDIO_SERVICE_TYPE);
if (sd && sd->size >= sizeof(enum AVAudioServiceType))
avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data;
/* check for valid frame size */
if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) {
if (src->nb_samples > avctx->frame_size) {
av_log(avctx, AV_LOG_ERROR, "more samples than frame size\n");
return AVERROR(EINVAL);
}
} else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) {
/* if we already got an undersized frame, that must have been the last */
if (avctx->internal->last_audio_frame) {
av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame\n", avctx->frame_size);
return AVERROR(EINVAL);
}
if (src->nb_samples < avctx->frame_size) {
ret = pad_last_frame(avctx, dst, src);
if (ret < 0)
return ret;
avctx->internal->last_audio_frame = 1;
} else if (src->nb_samples > avctx->frame_size) {
av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d)\n", src->nb_samples, avctx->frame_size);
return AVERROR(EINVAL);
}
}
}
// Emulation via old API.
if (!avctx->internal->buffer_pkt_valid) {
int got_packet;
int ret;
if (!avctx->internal->draining)
return AVERROR(EAGAIN);
ret = do_encode(avctx, NULL, &got_packet);
if (!dst->data[0]) {
ret = av_frame_ref(dst, src);
if (ret < 0)
return ret;
if (ret >= 0 && !got_packet)
return AVERROR_EOF;
return ret;
}
av_packet_move_ref(avpkt, avctx->internal->buffer_pkt);
avctx->internal->buffer_pkt_valid = 0;
return 0;
}
int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame)
{
AVCodecInternal *avci = avctx->internal;
int ret;
if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec))
return AVERROR(EINVAL);
if (avci->draining)
return AVERROR_EOF;
if (avci->buffer_frame->data[0])
return AVERROR(EAGAIN);
if (!frame) {
avci->draining = 1;
} else {
ret = encode_send_frame_internal(avctx, frame);
if (ret < 0)
return ret;
}
if (!avci->buffer_pkt->data && !avci->buffer_pkt->side_data) {
ret = encode_receive_packet_internal(avctx, avci->buffer_pkt);
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
return ret;
}
return 0;
}
int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
{
AVCodecInternal *avci = avctx->internal;
int ret;
av_packet_unref(avpkt);
if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec))
return AVERROR(EINVAL);
if (avci->buffer_pkt->data || avci->buffer_pkt->side_data) {
av_packet_move_ref(avpkt, avci->buffer_pkt);
} else {
ret = encode_receive_packet_internal(avctx, avpkt);
if (ret < 0)
return ret;
}
return 0;
}
static int compat_encode(AVCodecContext *avctx, AVPacket *avpkt,
int *got_packet, const AVFrame *frame)
{
AVCodecInternal *avci = avctx->internal;
AVPacket user_pkt;
int ret;
*got_packet = 0;
if (frame && avctx->codec->type == AVMEDIA_TYPE_VIDEO) {
if (frame->format == AV_PIX_FMT_NONE)
av_log(avctx, AV_LOG_WARNING, "AVFrame.format is not set\n");
if (frame->width == 0 || frame->height == 0)
av_log(avctx, AV_LOG_WARNING, "AVFrame.width or height is not set\n");
}
ret = avcodec_send_frame(avctx, frame);
if (ret == AVERROR_EOF)
ret = 0;
else if (ret == AVERROR(EAGAIN)) {
/* we fully drain all the output in each encode call, so this should not
* ever happen */
return AVERROR_BUG;
} else if (ret < 0)
return ret;
av_packet_move_ref(&user_pkt, avpkt);
while (ret >= 0) {
ret = avcodec_receive_packet(avctx, avpkt);
if (ret < 0) {
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
ret = 0;
goto finish;
}
if (avpkt != avci->compat_encode_packet) {
if (avpkt->data && user_pkt.data) {
if (user_pkt.size >= avpkt->size) {
memcpy(user_pkt.data, avpkt->data, avpkt->size);
av_buffer_unref(&avpkt->buf);
avpkt->buf = user_pkt.buf;
avpkt->data = user_pkt.data;
av_init_packet(&user_pkt);
} else {
av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size);
av_packet_unref(avpkt);
ret = AVERROR(EINVAL);
goto finish;
}
}
*got_packet = 1;
avpkt = avci->compat_encode_packet;
} else {
if (!avci->compat_decode_warned) {
av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_encode_* "
"API cannot return all the packets for this encoder. "
"Some packets will be dropped. Update your code to the "
"new encoding API to fix this.\n");
avci->compat_decode_warned = 1;
av_packet_unref(avpkt);
}
}
if (avci->draining)
break;
}
finish:
if (ret < 0)
av_packet_unref(&user_pkt);
return ret;
}
int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
AVPacket *avpkt,
const AVFrame *frame,
int *got_packet_ptr)
{
int ret = compat_encode(avctx, avpkt, got_packet_ptr, frame);
if (ret < 0)
av_packet_unref(avpkt);
return ret;
}
int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx,
AVPacket *avpkt,
const AVFrame *frame,
int *got_packet_ptr)
{
int ret = compat_encode(avctx, avpkt, got_packet_ptr, frame);
if (ret < 0)
av_packet_unref(avpkt);
return ret;
}
+39
View File
@@ -0,0 +1,39 @@
/*
* generic encoding-related code
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_ENCODE_H
#define AVCODEC_ENCODE_H
#include "libavutil/frame.h"
#include "avcodec.h"
/**
* Called by encoders to get the next frame for encoding.
*
* @param frame An empty frame to be filled with data.
* @return 0 if a new reference has been successfully written to frame
* AVERROR(EAGAIN) if no data is currently available
* AVERROR_EOF if end of stream has been reached, so no more data
* will be available
*/
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame);
#endif /* AVCODEC_ENCODE_H */
+4 -4
View File
@@ -125,7 +125,7 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt)
}
if (ctx->mode == REMOVE ? j < ctx->nb_types
: j >= ctx->nb_types)
ff_cbs_delete_unit(ctx->cbc, frag, i);
ff_cbs_delete_unit(frag, i);
}
if (frag->nb_units == 0) {
@@ -143,7 +143,7 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt)
fail:
if (err < 0)
av_packet_unref(pkt);
ff_cbs_fragment_reset(ctx->cbc, frag);
ff_cbs_fragment_reset(frag);
return err;
}
@@ -199,7 +199,7 @@ static int filter_units_init(AVBSFContext *bsf)
av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
}
ff_cbs_fragment_reset(ctx->cbc, frag);
ff_cbs_fragment_reset(frag);
}
return err;
@@ -211,7 +211,7 @@ static void filter_units_close(AVBSFContext *bsf)
av_freep(&ctx->type_list);
ff_cbs_fragment_free(ctx->cbc, &ctx->fragment);
ff_cbs_fragment_free(&ctx->fragment);
ff_cbs_close(&ctx->cbc);
}
+1
View File
@@ -686,5 +686,6 @@ AVCodec ff_h261_decoder = {
.close = h261_decode_end,
.decode = h261_decode_frame,
.capabilities = AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.max_lowres = 3,
};
+2 -2
View File
@@ -770,7 +770,7 @@ AVCodec ff_h263_decoder = {
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.flush = ff_mpeg_flush,
.max_lowres = 3,
.pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
@@ -788,7 +788,7 @@ AVCodec ff_h263p_decoder = {
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.flush = ff_mpeg_flush,
.max_lowres = 3,
.pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
+25 -22
View File
@@ -49,7 +49,8 @@ enum {
typedef struct H264MetadataContext {
const AVClass *class;
CodedBitstreamContext *cbc;
CodedBitstreamContext *input;
CodedBitstreamContext *output;
CodedBitstreamFragment access_unit;
int done_first_au;
@@ -289,7 +290,7 @@ static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
if (!side_data_size)
return 0;
err = ff_cbs_read(ctx->cbc, au, side_data, side_data_size);
err = ff_cbs_read(ctx->input, au, side_data, side_data_size);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n");
return err;
@@ -303,7 +304,7 @@ static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
}
}
err = ff_cbs_write_fragment_data(ctx->cbc, au);
err = ff_cbs_write_fragment_data(ctx->output, au);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n");
return err;
@@ -314,7 +315,7 @@ static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
return AVERROR(ENOMEM);
memcpy(side_data, au->data, au->data_size);
ff_cbs_fragment_reset(ctx->cbc, au);
ff_cbs_fragment_reset(au);
return 0;
}
@@ -334,7 +335,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
if (err < 0)
goto fail;
err = ff_cbs_read_packet(ctx->cbc, au, pkt);
err = ff_cbs_read_packet(ctx->input, au, pkt);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
goto fail;
@@ -349,7 +350,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
// If an AUD is present, it must be the first NAL unit.
if (au->units[0].type == H264_NAL_AUD) {
if (ctx->aud == REMOVE)
ff_cbs_delete_unit(ctx->cbc, au, 0);
ff_cbs_delete_unit(au, 0);
} else {
if (ctx->aud == INSERT) {
static const int primary_pic_type_table[] = {
@@ -390,7 +391,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
.primary_pic_type = j,
};
err = ff_cbs_insert_unit_content(ctx->cbc, au,
err = ff_cbs_insert_unit_content(au,
0, H264_NAL_AUD, &aud, NULL);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n");
@@ -448,7 +449,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
udu->data_length = len + 1;
memcpy(udu->data, ctx->sei_user_data + i + 1, len + 1);
err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload);
err = ff_cbs_h264_add_sei_message(au, &payload);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
"message to access unit.\n");
@@ -467,7 +468,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
if (ctx->delete_filler) {
for (i = au->nb_units - 1; i >= 0; i--) {
if (au->units[i].type == H264_NAL_FILLER_DATA) {
ff_cbs_delete_unit(ctx->cbc, au, i);
ff_cbs_delete_unit(au, i);
continue;
}
@@ -478,8 +479,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
for (j = sei->payload_count - 1; j >= 0; j--) {
if (sei->payload[j].payload_type ==
H264_SEI_TYPE_FILLER_PAYLOAD)
ff_cbs_h264_delete_sei_message(ctx->cbc, au,
&au->units[i], j);
ff_cbs_h264_delete_sei_message(au, &au->units[i], j);
}
}
}
@@ -503,8 +503,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
if (ctx->display_orientation == REMOVE ||
ctx->display_orientation == INSERT) {
ff_cbs_h264_delete_sei_message(ctx->cbc, au,
&au->units[i], j);
ff_cbs_h264_delete_sei_message(au, &au->units[i], j);
continue;
}
@@ -595,7 +594,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
if (write) {
disp->display_orientation_repetition_period = 1;
err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload);
err = ff_cbs_h264_add_sei_message(au, &payload);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to add display orientation "
"SEI message to access unit.\n");
@@ -604,7 +603,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
}
}
err = ff_cbs_write_packet(ctx->cbc, pkt, au);
err = ff_cbs_write_packet(ctx->output, pkt, au);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
goto fail;
@@ -614,7 +613,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
err = 0;
fail:
ff_cbs_fragment_reset(ctx->cbc, au);
ff_cbs_fragment_reset(au);
if (err < 0)
av_packet_unref(pkt);
@@ -628,12 +627,15 @@ static int h264_metadata_init(AVBSFContext *bsf)
CodedBitstreamFragment *au = &ctx->access_unit;
int err, i;
err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_H264, bsf);
err = ff_cbs_init(&ctx->input, AV_CODEC_ID_H264, bsf);
if (err < 0)
return err;
err = ff_cbs_init(&ctx->output, AV_CODEC_ID_H264, bsf);
if (err < 0)
return err;
if (bsf->par_in->extradata) {
err = ff_cbs_read_extradata(ctx->cbc, au, bsf->par_in);
err = ff_cbs_read_extradata(ctx->input, au, bsf->par_in);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
goto fail;
@@ -647,7 +649,7 @@ static int h264_metadata_init(AVBSFContext *bsf)
}
}
err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, au);
err = ff_cbs_write_extradata(ctx->output, bsf->par_out, au);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
goto fail;
@@ -656,7 +658,7 @@ static int h264_metadata_init(AVBSFContext *bsf)
err = 0;
fail:
ff_cbs_fragment_reset(ctx->cbc, au);
ff_cbs_fragment_reset(au);
return err;
}
@@ -664,8 +666,9 @@ static void h264_metadata_close(AVBSFContext *bsf)
{
H264MetadataContext *ctx = bsf->priv_data;
ff_cbs_fragment_free(ctx->cbc, &ctx->access_unit);
ff_cbs_close(&ctx->cbc);
ff_cbs_fragment_free(&ctx->access_unit);
ff_cbs_close(&ctx->input);
ff_cbs_close(&ctx->output);
}
#define OFFSET(x) offsetof(H264MetadataContext, x)
+4 -4
View File
@@ -95,7 +95,7 @@ static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *pkt)
if (!au_has_sps) {
av_log(bsf, AV_LOG_VERBOSE, "Deleting redundant PPS "
"at %"PRId64".\n", pkt->pts);
ff_cbs_delete_unit(ctx->input, au, i);
ff_cbs_delete_unit(au, i);
i--;
continue;
}
@@ -113,7 +113,7 @@ static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *pkt)
err = 0;
fail:
ff_cbs_fragment_reset(ctx->output, au);
ff_cbs_fragment_reset(au);
if (err < 0)
av_packet_unref(pkt);
@@ -161,7 +161,7 @@ static int h264_redundant_pps_init(AVBSFContext *bsf)
err = 0;
fail:
ff_cbs_fragment_reset(ctx->output, au);
ff_cbs_fragment_reset(au);
return err;
}
@@ -175,7 +175,7 @@ static void h264_redundant_pps_close(AVBSFContext *bsf)
{
H264RedundantPPSContext *ctx = bsf->priv_data;
ff_cbs_fragment_free(ctx->input, &ctx->access_unit);
ff_cbs_fragment_free(&ctx->access_unit);
ff_cbs_close(&ctx->input);
ff_cbs_close(&ctx->output);
}
+16 -3
View File
@@ -52,6 +52,10 @@ void ff_h264_sei_uninit(H264SEIContext *h)
h->afd.present = 0;
av_buffer_unref(&h->a53_caption.buf_ref);
for (int i = 0; i < h->unregistered.nb_buf_ref; i++)
av_buffer_unref(&h->unregistered.buf_ref[i]);
h->unregistered.nb_buf_ref = 0;
av_freep(&h->unregistered.buf_ref);
}
int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps,
@@ -260,25 +264,34 @@ static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext *
{
uint8_t *user_data;
int e, build, i;
AVBufferRef *buf_ref, **tmp;
if (size < 16 || size >= INT_MAX - 1)
return AVERROR_INVALIDDATA;
user_data = av_malloc(size + 1);
if (!user_data)
tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref));
if (!tmp)
return AVERROR(ENOMEM);
h->buf_ref = tmp;
buf_ref = av_buffer_alloc(size + 1);
if (!buf_ref)
return AVERROR(ENOMEM);
user_data = buf_ref->data;
for (i = 0; i < size; i++)
user_data[i] = get_bits(gb, 8);
user_data[i] = 0;
buf_ref->size = size;
h->buf_ref[h->nb_buf_ref++] = buf_ref;
e = sscanf(user_data + 16, "x264 - core %d", &build);
if (e == 1 && build > 0)
h->x264_build = build;
if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16))
h->x264_build = 67;
av_free(user_data);
return 0;
}
+2
View File
@@ -126,6 +126,8 @@ typedef struct H264SEIA53Caption {
typedef struct H264SEIUnregistered {
int x264_build;
AVBufferRef **buf_ref;
int nb_buf_ref;
} H264SEIUnregistered;
typedef struct H264SEIRecoveryPoint {
+48 -51
View File
@@ -1125,9 +1125,10 @@ static int h264_export_frame_props(H264Context *h)
{
const SPS *sps = h->ps.sps;
H264Picture *cur = h->cur_pic_ptr;
AVFrame *out = cur->f;
cur->f->interlaced_frame = 0;
cur->f->repeat_pict = 0;
out->interlaced_frame = 0;
out->repeat_pict = 0;
/* Signal interlacing information externally. */
/* Prioritize picture timing SEI information over used
@@ -1150,59 +1151,59 @@ static int h264_export_frame_props(H264Context *h)
break;
case H264_SEI_PIC_STRUCT_TOP_FIELD:
case H264_SEI_PIC_STRUCT_BOTTOM_FIELD:
cur->f->interlaced_frame = 1;
out->interlaced_frame = 1;
break;
case H264_SEI_PIC_STRUCT_TOP_BOTTOM:
case H264_SEI_PIC_STRUCT_BOTTOM_TOP:
if (FIELD_OR_MBAFF_PICTURE(h))
cur->f->interlaced_frame = 1;
out->interlaced_frame = 1;
else
// try to flag soft telecine progressive
cur->f->interlaced_frame = h->prev_interlaced_frame;
out->interlaced_frame = h->prev_interlaced_frame;
break;
case H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
case H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
/* Signal the possibility of telecined film externally
* (pic_struct 5,6). From these hints, let the applications
* decide if they apply deinterlacing. */
cur->f->repeat_pict = 1;
out->repeat_pict = 1;
break;
case H264_SEI_PIC_STRUCT_FRAME_DOUBLING:
cur->f->repeat_pict = 2;
out->repeat_pict = 2;
break;
case H264_SEI_PIC_STRUCT_FRAME_TRIPLING:
cur->f->repeat_pict = 4;
out->repeat_pict = 4;
break;
}
if ((pt->ct_type & 3) &&
pt->pic_struct <= H264_SEI_PIC_STRUCT_BOTTOM_TOP)
cur->f->interlaced_frame = (pt->ct_type & (1 << 1)) != 0;
out->interlaced_frame = (pt->ct_type & (1 << 1)) != 0;
} else {
/* Derive interlacing flag from used decoding process. */
cur->f->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);
out->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);
}
h->prev_interlaced_frame = cur->f->interlaced_frame;
h->prev_interlaced_frame = out->interlaced_frame;
if (cur->field_poc[0] != cur->field_poc[1]) {
/* Derive top_field_first from field pocs. */
cur->f->top_field_first = cur->field_poc[0] < cur->field_poc[1];
out->top_field_first = cur->field_poc[0] < cur->field_poc[1];
} else {
if (sps->pic_struct_present_flag && h->sei.picture_timing.present) {
/* Use picture timing SEI information. Even if it is a
* information of a past frame, better than nothing. */
if (h->sei.picture_timing.pic_struct == H264_SEI_PIC_STRUCT_TOP_BOTTOM ||
h->sei.picture_timing.pic_struct == H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
cur->f->top_field_first = 1;
out->top_field_first = 1;
else
cur->f->top_field_first = 0;
} else if (cur->f->interlaced_frame) {
out->top_field_first = 0;
} else if (out->interlaced_frame) {
/* Default to top field first when pic_struct_present_flag
* is not set but interlaced frame detected */
cur->f->top_field_first = 1;
out->top_field_first = 1;
} else {
/* Most likely progressive */
cur->f->top_field_first = 0;
out->top_field_first = 0;
}
}
@@ -1211,7 +1212,7 @@ static int h264_export_frame_props(H264Context *h)
h->sei.frame_packing.content_interpretation_type > 0 &&
h->sei.frame_packing.content_interpretation_type < 3) {
H264SEIFramePacking *fp = &h->sei.frame_packing;
AVStereo3D *stereo = av_stereo3d_create_side_data(cur->f);
AVStereo3D *stereo = av_stereo3d_create_side_data(out);
if (stereo) {
switch (fp->arrangement_type) {
case H264_SEI_FPA_TYPE_CHECKERBOARD:
@@ -1258,7 +1259,7 @@ static int h264_export_frame_props(H264Context *h)
h->sei.display_orientation.vflip)) {
H264SEIDisplayOrientation *o = &h->sei.display_orientation;
double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16);
AVFrameSideData *rotation = av_frame_new_side_data(cur->f,
AVFrameSideData *rotation = av_frame_new_side_data(out,
AV_FRAME_DATA_DISPLAYMATRIX,
sizeof(int32_t) * 9);
if (rotation) {
@@ -1269,7 +1270,7 @@ static int h264_export_frame_props(H264Context *h)
}
if (h->sei.afd.present) {
AVFrameSideData *sd = av_frame_new_side_data(cur->f, AV_FRAME_DATA_AFD,
AVFrameSideData *sd = av_frame_new_side_data(out, AV_FRAME_DATA_AFD,
sizeof(uint8_t));
if (sd) {
@@ -1281,7 +1282,7 @@ static int h264_export_frame_props(H264Context *h)
if (h->sei.a53_caption.buf_ref) {
H264SEIA53Caption *a53 = &h->sei.a53_caption;
AVFrameSideData *sd = av_frame_new_side_data_from_buf(cur->f, AV_FRAME_DATA_A53_CC, a53->buf_ref);
AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, AV_FRAME_DATA_A53_CC, a53->buf_ref);
if (!sd)
av_buffer_unref(&a53->buf_ref);
a53->buf_ref = NULL;
@@ -1289,11 +1290,25 @@ static int h264_export_frame_props(H264Context *h)
h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
}
if (h->sei.picture_timing.timecode_cnt > 0) {
uint32_t tc = 0;
uint32_t *tc_sd;
for (int i = 0; i < h->sei.unregistered.nb_buf_ref; i++) {
H264SEIUnregistered *unreg = &h->sei.unregistered;
AVFrameSideData *tcside = av_frame_new_side_data(cur->f,
if (unreg->buf_ref[i]) {
AVFrameSideData *sd = av_frame_new_side_data_from_buf(out,
AV_FRAME_DATA_SEI_UNREGISTERED,
unreg->buf_ref[i]);
if (!sd)
av_buffer_unref(&unreg->buf_ref[i]);
unreg->buf_ref[i] = NULL;
}
}
h->sei.unregistered.nb_buf_ref = 0;
if (h->sei.picture_timing.timecode_cnt > 0) {
uint32_t *tc_sd;
char tcbuf[AV_TIMECODE_STR_SIZE];
AVFrameSideData *tcside = av_frame_new_side_data(out,
AV_FRAME_DATA_S12M_TIMECODE,
sizeof(uint32_t)*4);
if (!tcside)
@@ -1303,33 +1318,15 @@ static int h264_export_frame_props(H264Context *h)
tc_sd[0] = h->sei.picture_timing.timecode_cnt;
for (int i = 0; i < tc_sd[0]; i++) {
uint32_t frames;
int drop = h->sei.picture_timing.timecode[i].dropframe;
int hh = h->sei.picture_timing.timecode[i].hours;
int mm = h->sei.picture_timing.timecode[i].minutes;
int ss = h->sei.picture_timing.timecode[i].seconds;
int ff = h->sei.picture_timing.timecode[i].frame;
/* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS.
See SMPTE ST 12-1:2014 Sec 12.1 for more info. */
if (av_cmp_q(h->avctx->framerate, (AVRational) {30, 1}) == 1) {
frames = h->sei.picture_timing.timecode[i].frame / 2;
if (h->sei.picture_timing.timecode[i].frame % 2 == 1) {
if (av_cmp_q(h->avctx->framerate, (AVRational) {50, 1}) == 0)
tc |= (1 << 7);
else
tc |= (1 << 23);
}
} else {
frames = h->sei.picture_timing.timecode[i].frame;
}
tc |= h->sei.picture_timing.timecode[i].dropframe << 30;
tc |= (frames / 10) << 28;
tc |= (frames % 10) << 24;
tc |= (h->sei.picture_timing.timecode[i].seconds / 10) << 20;
tc |= (h->sei.picture_timing.timecode[i].seconds % 10) << 16;
tc |= (h->sei.picture_timing.timecode[i].minutes / 10) << 12;
tc |= (h->sei.picture_timing.timecode[i].minutes % 10) << 8;
tc |= (h->sei.picture_timing.timecode[i].hours / 10) << 4;
tc |= (h->sei.picture_timing.timecode[i].hours % 10);
tc_sd[i + 1] = tc;
tc_sd[i + 1] = av_timecode_get_smpte(h->avctx->framerate, drop, hh, mm, ss, ff);
av_timecode_make_smpte_tc_string(tcbuf, tc_sd[i + 1], 0);
av_dict_set(&out->metadata, "timecode", tcbuf, 0);
}
h->sei.picture_timing.timecode_cnt = 0;
}
+27 -53
View File
@@ -182,40 +182,27 @@ int ff_h264_alloc_tables(H264Context *h)
{
const int big_mb_num = h->mb_stride * (h->mb_height + 1);
const int row_mb_num = 2*h->mb_stride*FFMAX(h->nb_slice_ctx, 1);
const int st_size = big_mb_num + h->mb_stride;
int x, y;
FF_ALLOCZ_ARRAY_OR_GOTO(h->avctx, h->intra4x4_pred_mode,
row_mb_num, 8 * sizeof(uint8_t), fail)
if (!FF_ALLOCZ_TYPED_ARRAY(h->intra4x4_pred_mode, row_mb_num * 8) ||
!FF_ALLOCZ_TYPED_ARRAY(h->non_zero_count, big_mb_num) ||
!FF_ALLOCZ_TYPED_ARRAY(h->slice_table_base, st_size) ||
!FF_ALLOCZ_TYPED_ARRAY(h->cbp_table, big_mb_num) ||
!FF_ALLOCZ_TYPED_ARRAY(h->chroma_pred_mode_table, big_mb_num) ||
!FF_ALLOCZ_TYPED_ARRAY(h->mvd_table[0], row_mb_num * 8) ||
!FF_ALLOCZ_TYPED_ARRAY(h->mvd_table[1], row_mb_num * 8) ||
!FF_ALLOCZ_TYPED_ARRAY(h->direct_table, big_mb_num * 4) ||
!FF_ALLOCZ_TYPED_ARRAY(h->list_counts, big_mb_num) ||
!FF_ALLOCZ_TYPED_ARRAY(h->mb2b_xy, big_mb_num) ||
!FF_ALLOCZ_TYPED_ARRAY(h->mb2br_xy, big_mb_num))
return AVERROR(ENOMEM);
h->slice_ctx[0].intra4x4_pred_mode = h->intra4x4_pred_mode;
FF_ALLOCZ_OR_GOTO(h->avctx, h->non_zero_count,
big_mb_num * 48 * sizeof(uint8_t), fail)
FF_ALLOCZ_OR_GOTO(h->avctx, h->slice_table_base,
(big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base), fail)
FF_ALLOCZ_OR_GOTO(h->avctx, h->cbp_table,
big_mb_num * sizeof(uint16_t), fail)
FF_ALLOCZ_OR_GOTO(h->avctx, h->chroma_pred_mode_table,
big_mb_num * sizeof(uint8_t), fail)
FF_ALLOCZ_ARRAY_OR_GOTO(h->avctx, h->mvd_table[0],
row_mb_num, 16 * sizeof(uint8_t), fail);
FF_ALLOCZ_ARRAY_OR_GOTO(h->avctx, h->mvd_table[1],
row_mb_num, 16 * sizeof(uint8_t), fail);
h->slice_ctx[0].mvd_table[0] = h->mvd_table[0];
h->slice_ctx[0].mvd_table[1] = h->mvd_table[1];
FF_ALLOCZ_OR_GOTO(h->avctx, h->direct_table,
4 * big_mb_num * sizeof(uint8_t), fail);
FF_ALLOCZ_OR_GOTO(h->avctx, h->list_counts,
big_mb_num * sizeof(uint8_t), fail)
memset(h->slice_table_base, -1,
(big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base));
st_size * sizeof(*h->slice_table_base));
h->slice_table = h->slice_table_base + h->mb_stride * 2 + 1;
FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2b_xy,
big_mb_num * sizeof(uint32_t), fail);
FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2br_xy,
big_mb_num * sizeof(uint32_t), fail);
for (y = 0; y < h->mb_height; y++)
for (x = 0; x < h->mb_width; x++) {
const int mb_xy = x + y * h->mb_stride;
@@ -226,9 +213,6 @@ int ff_h264_alloc_tables(H264Context *h)
}
return 0;
fail:
return AVERROR(ENOMEM);
}
/**
@@ -253,8 +237,8 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl)
if (sl != h->slice_ctx) {
memset(er, 0, sizeof(*er));
} else
if (CONFIG_ERROR_RESILIENCE) {
} else if (CONFIG_ERROR_RESILIENCE) {
const int er_size = h->mb_height * h->mb_stride * (4*sizeof(int) + 1);
/* init ER */
er->avctx = h->avctx;
@@ -269,8 +253,11 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl)
er->b8_stride = h->mb_width * 2 + 1;
// error resilience code looks cleaner with this
FF_ALLOCZ_OR_GOTO(h->avctx, er->mb_index2xy,
(h->mb_num + 1) * sizeof(int), fail);
if (!FF_ALLOCZ_TYPED_ARRAY(er->mb_index2xy, h->mb_num + 1) ||
!FF_ALLOCZ_TYPED_ARRAY(er->error_status_table, mb_array_size) ||
!FF_ALLOCZ_TYPED_ARRAY(er->er_temp_buffer, er_size) ||
!FF_ALLOCZ_TYPED_ARRAY(sl->dc_val_base, yc_size))
return AVERROR(ENOMEM); // ff_h264_free_tables will clean up for us
for (y = 0; y < h->mb_height; y++)
for (x = 0; x < h->mb_width; x++)
@@ -278,15 +265,6 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl)
er->mb_index2xy[h->mb_height * h->mb_width] = (h->mb_height - 1) *
h->mb_stride + h->mb_width;
FF_ALLOCZ_OR_GOTO(h->avctx, er->error_status_table,
mb_array_size * sizeof(uint8_t), fail);
FF_ALLOC_OR_GOTO(h->avctx, er->er_temp_buffer,
h->mb_height * h->mb_stride * (4*sizeof(int) + 1), fail);
FF_ALLOCZ_OR_GOTO(h->avctx, sl->dc_val_base,
yc_size * sizeof(int16_t), fail);
er->dc_val[0] = sl->dc_val_base + h->mb_width * 2 + 2;
er->dc_val[1] = sl->dc_val_base + y_size + h->mb_stride + 1;
er->dc_val[2] = er->dc_val[1] + c_size;
@@ -295,9 +273,6 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl)
}
return 0;
fail:
return AVERROR(ENOMEM); // ff_h264_free_tables will clean up for us
}
static int h264_init_context(AVCodecContext *avctx, H264Context *h)
@@ -872,7 +847,7 @@ fail:
return ret;
}
static int is_extra(const uint8_t *buf, int buf_size)
static int is_avcc_extradata(const uint8_t *buf, int buf_size)
{
int cnt= buf[5]&0x1f;
const uint8_t *p= buf+6;
@@ -999,16 +974,15 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data,
if (buf_size == 0)
return send_next_delayed_frame(h, pict, got_frame, 0);
if (h->is_avc && av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) {
if (av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) {
int side_size;
uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (is_extra(side, side_size))
ff_h264_decode_extradata(side, side_size,
&h->ps, &h->is_avc, &h->nal_length_size,
avctx->err_recognition, avctx);
ff_h264_decode_extradata(side, side_size,
&h->ps, &h->is_avc, &h->nal_length_size,
avctx->err_recognition, avctx);
}
if (h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC) {
if (is_extra(buf, buf_size))
if (is_avcc_extradata(buf, buf_size))
return ff_h264_decode_extradata(buf, buf_size,
&h->ps, &h->is_avc, &h->nal_length_size,
avctx->err_recognition, avctx);
+20 -16
View File
@@ -40,7 +40,8 @@ enum {
typedef struct H265MetadataContext {
const AVClass *class;
CodedBitstreamContext *cbc;
CodedBitstreamContext *input;
CodedBitstreamContext *output;
CodedBitstreamFragment access_unit;
H265RawAUD aud_nal;
@@ -350,7 +351,7 @@ static int h265_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
if (!side_data_size)
return 0;
err = ff_cbs_read(ctx->cbc, au, side_data, side_data_size);
err = ff_cbs_read(ctx->input, au, side_data, side_data_size);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n");
return err;
@@ -372,7 +373,7 @@ static int h265_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
}
}
err = ff_cbs_write_fragment_data(ctx->cbc, au);
err = ff_cbs_write_fragment_data(ctx->output, au);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n");
return err;
@@ -383,7 +384,7 @@ static int h265_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
return AVERROR(ENOMEM);
memcpy(side_data, au->data, au->data_size);
ff_cbs_fragment_reset(ctx->cbc, au);
ff_cbs_fragment_reset(au);
return 0;
}
@@ -402,7 +403,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
if (err < 0)
goto fail;
err = ff_cbs_read_packet(ctx->cbc, au, pkt);
err = ff_cbs_read_packet(ctx->input, au, pkt);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
goto fail;
@@ -417,7 +418,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
// If an AUD is present, it must be the first NAL unit.
if (au->units[0].type == HEVC_NAL_AUD) {
if (ctx->aud == REMOVE)
ff_cbs_delete_unit(ctx->cbc, au, 0);
ff_cbs_delete_unit(au, 0);
} else {
if (ctx->aud == INSERT) {
H265RawAUD *aud = &ctx->aud_nal;
@@ -449,8 +450,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
};
aud->pic_type = pic_type;
err = ff_cbs_insert_unit_content(ctx->cbc, au,
0, HEVC_NAL_AUD, aud, NULL);
err = ff_cbs_insert_unit_content(au, 0, HEVC_NAL_AUD, aud, NULL);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n");
goto fail;
@@ -474,7 +474,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
}
}
err = ff_cbs_write_packet(ctx->cbc, pkt, au);
err = ff_cbs_write_packet(ctx->output, pkt, au);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
goto fail;
@@ -482,7 +482,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
err = 0;
fail:
ff_cbs_fragment_reset(ctx->cbc, au);
ff_cbs_fragment_reset(au);
if (err < 0)
av_packet_unref(pkt);
@@ -496,12 +496,15 @@ static int h265_metadata_init(AVBSFContext *bsf)
CodedBitstreamFragment *au = &ctx->access_unit;
int err, i;
err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_HEVC, bsf);
err = ff_cbs_init(&ctx->input, AV_CODEC_ID_HEVC, bsf);
if (err < 0)
return err;
err = ff_cbs_init(&ctx->output, AV_CODEC_ID_HEVC, bsf);
if (err < 0)
return err;
if (bsf->par_in->extradata) {
err = ff_cbs_read_extradata(ctx->cbc, au, bsf->par_in);
err = ff_cbs_read_extradata(ctx->input, au, bsf->par_in);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
goto fail;
@@ -523,7 +526,7 @@ static int h265_metadata_init(AVBSFContext *bsf)
}
}
err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, au);
err = ff_cbs_write_extradata(ctx->output, bsf->par_out, au);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
goto fail;
@@ -532,7 +535,7 @@ static int h265_metadata_init(AVBSFContext *bsf)
err = 0;
fail:
ff_cbs_fragment_reset(ctx->cbc, au);
ff_cbs_fragment_reset(au);
return err;
}
@@ -540,8 +543,9 @@ static void h265_metadata_close(AVBSFContext *bsf)
{
H265MetadataContext *ctx = bsf->priv_data;
ff_cbs_fragment_free(ctx->cbc, &ctx->access_unit);
ff_cbs_close(&ctx->cbc);
ff_cbs_fragment_free(&ctx->access_unit);
ff_cbs_close(&ctx->input);
ff_cbs_close(&ctx->output);
}
#define OFFSET(x) offsetof(H265MetadataContext, x)
+8 -6
View File
@@ -86,18 +86,18 @@ static const float intensity_ratio_table[] =
{
2.0, 1.85714, 1.71429, 1.57143, 1.42857, 1.28571, 1.14286, 1.0,
0.857143, 0.714286, 0.571429, 0.428571, 0.285714, 0.142857, 0.0, 0.0,
0, 1.87066e-08, 2.49253e-08, 3.32113e-08, 4.42518e-08, 5.89626e-08, 7.85637e-08, 1.04681e-07,
};
static const float scale_conversion_table[] =
{
0, 0, 1.87066e-08, 2.49253e-08, 3.32113e-08, 4.42518e-08, 5.89626e-08, 7.85637e-08, 1.04681e-07,
1.3948e-07, 1.85848e-07, 2.4763e-07, 3.2995e-07, 4.39636e-07, 5.85785e-07, 7.80519e-07, 1.03999e-06,
1.38572e-06, 1.84637e-06, 2.46017e-06, 3.27801e-06, 4.36772e-06, 5.8197e-06, 7.75435e-06, 1.03321e-05,
1.37669e-05, 1.83435e-05, 2.44414e-05, 3.25665e-05, 4.33927e-05, 5.78179e-05, 7.70384e-05, 0.000102648,
0.000136772, 0.00018224, 0.000242822, 0.000323544, 0.000431101, 0.000574413, 0.000765366, 0.0010198,
0.00135881, 0.00181053, 0.0024124, 0.00321437, 0.00428293, 0.00570671, 0.00760381, 0.0101316,
0.0134996, 0.0179873, 0.0239669, 0.0319343, 0.0425503, 0.0566954, 0.0755428, 0.100656,
0.134117, 0.178702, 0.238108, 0.317263, 0.422731, 0.563261, 0.750507, 0.0,
};
static const float scale_conversion_table[] =
{
0.134117, 0.178702, 0.238108, 0.317263, 0.422731, 0.563261, 0.750507,
1.0, 1.33243, 1.77538, 2.36557, 3.15196, 4.19978, 5.59592, 7.45618,
9.93486, 13.2375, 17.6381, 23.5016, 31.3143, 41.7242, 55.5947, 74.0762,
98.7015, 131.513, 175.232, 233.485, 311.103, 414.524, 552.326, 735.937,
@@ -108,6 +108,8 @@ static const float scale_conversion_table[] =
9.55285e+06, 1.27285e+07, 1.69599e+07, 2.25979e+07, 3.01102e+07, 4.01198e+07, 5.3457e+07, 0,
};
static const int scale_conv_bias = 64;
static const float dequantizer_scaling_table[] =
{
1.58838e-07, 2.11641e-07, 2.81998e-07, 3.75743e-07, 5.00652e-07, 6.67085e-07, 8.88846e-07, 1.18433e-06,
+3 -2
View File
@@ -267,7 +267,7 @@ static void apply_intensity_stereo(HCAContext *s, ChannelContext *ch1, ChannelCo
int index, unsigned band_count, unsigned base_band_count,
unsigned stereo_band_count)
{
float ratio_l = intensity_ratio_table[ch1->intensity[index]];
float ratio_l = intensity_ratio_table[ch2->intensity[index]];
float ratio_r = ratio_l - 2.0f;
float *c1 = &ch1->imdct_in[base_band_count];
float *c2 = &ch2->imdct_in[base_band_count];
@@ -291,7 +291,8 @@ static void reconstruct_hfr(HCAContext *s, ChannelContext *ch,
for (int i = 0, k = start_band, l = start_band - 1; i < hfr_group_count; i++){
for (int j = 0; j < bands_per_hfr_group && k < total_band_count && l >= 0; j++, k++, l--){
ch->imdct_in[k] = scale_conversion_table[ (ch->hfr_scale[i] - ch->scale_factors[l]) & 63 ] * ch->imdct_in[l];
ch->imdct_in[k] = scale_conversion_table[ scale_conv_bias +
av_clip_intp2(ch->hfr_scale[i] - ch->scale_factors[l], 6) ] * ch->imdct_in[l];
}
}
+82
View File
@@ -213,6 +213,32 @@ static int decode_registered_user_data_closed_caption(HEVCSEIA53Caption *s, GetB
return 0;
}
static int decode_nal_sei_user_data_unregistered(HEVCSEIUnregistered *s, GetBitContext *gb,
int size)
{
AVBufferRef *buf_ref, **tmp;
if (size < 16 || size >= INT_MAX - 1)
return AVERROR_INVALIDDATA;
tmp = av_realloc_array(s->buf_ref, s->nb_buf_ref + 1, sizeof(*s->buf_ref));
if (!tmp)
return AVERROR(ENOMEM);
s->buf_ref = tmp;
buf_ref = av_buffer_alloc(size + 1);
if (!buf_ref)
return AVERROR(ENOMEM);
for (int i = 0; i < size; i++)
buf_ref->data[i] = get_bits(gb, 8);
buf_ref->data[size] = 0;
buf_ref->size = size;
s->buf_ref[s->nb_buf_ref++] = buf_ref;
return 0;
}
static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCSEI *s, GetBitContext *gb,
int size)
{
@@ -280,6 +306,53 @@ static int decode_nal_sei_alternative_transfer(HEVCSEIAlternativeTransfer *s, Ge
return 0;
}
static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb)
{
s->num_clock_ts = get_bits(gb, 2);
for (int i = 0; i < s->num_clock_ts; i++) {
s->clock_timestamp_flag[i] = get_bits(gb, 1);
if (s->clock_timestamp_flag[i]) {
s->units_field_based_flag[i] = get_bits(gb, 1);
s->counting_type[i] = get_bits(gb, 5);
s->full_timestamp_flag[i] = get_bits(gb, 1);
s->discontinuity_flag[i] = get_bits(gb, 1);
s->cnt_dropped_flag[i] = get_bits(gb, 1);
s->n_frames[i] = get_bits(gb, 9);
if (s->full_timestamp_flag[i]) {
s->seconds_value[i] = av_clip(get_bits(gb, 6), 0, 59);
s->minutes_value[i] = av_clip(get_bits(gb, 6), 0, 59);
s->hours_value[i] = av_clip(get_bits(gb, 5), 0, 23);
} else {
s->seconds_flag[i] = get_bits(gb, 1);
if (s->seconds_flag[i]) {
s->seconds_value[i] = av_clip(get_bits(gb, 6), 0, 59);
s->minutes_flag[i] = get_bits(gb, 1);
if (s->minutes_flag[i]) {
s->minutes_value[i] = av_clip(get_bits(gb, 6), 0, 59);
s->hours_flag[i] = get_bits(gb, 1);
if (s->hours_flag[i]) {
s->hours_value[i] = av_clip(get_bits(gb, 5), 0, 23);
}
}
}
}
s->time_offset_length[i] = get_bits(gb, 5);
if (s->time_offset_length[i] > 0) {
s->time_offset_value[i] = get_bits(gb, s->time_offset_length[i]);
}
}
}
s->present = 1;
return 0;
}
static int decode_nal_sei_prefix(GetBitContext *gb, void *logctx, HEVCSEI *s,
const HEVCParamSets *ps, int type, int size)
{
@@ -300,8 +373,12 @@ static int decode_nal_sei_prefix(GetBitContext *gb, void *logctx, HEVCSEI *s,
return decode_nal_sei_active_parameter_sets(s, gb, logctx);
case HEVC_SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35:
return decode_nal_sei_user_data_registered_itu_t_t35(s, gb, size);
case HEVC_SEI_TYPE_USER_DATA_UNREGISTERED:
return decode_nal_sei_user_data_unregistered(&s->unregistered, gb, size);
case HEVC_SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS:
return decode_nal_sei_alternative_transfer(&s->alternative_transfer, gb);
case HEVC_SEI_TYPE_TIME_CODE:
return decode_nal_sei_timecode(&s->timecode, gb);
default:
av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
skip_bits_long(gb, 8 * size);
@@ -371,4 +448,9 @@ int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s,
void ff_hevc_reset_sei(HEVCSEI *s)
{
av_buffer_unref(&s->a53_caption.buf_ref);
for (int i = 0; i < s->unregistered.nb_buf_ref; i++)
av_buffer_unref(&s->unregistered.buf_ref[i]);
s->unregistered.nb_buf_ref = 0;
av_freep(&s->unregistered.buf_ref);
}
+27
View File
@@ -91,6 +91,11 @@ typedef struct HEVCSEIA53Caption {
AVBufferRef *buf_ref;
} HEVCSEIA53Caption;
typedef struct HEVCSEIUnregistered {
AVBufferRef **buf_ref;
int nb_buf_ref;
} HEVCSEIUnregistered;
typedef struct HEVCSEIMasteringDisplay {
int present;
uint16_t display_primaries[3][2];
@@ -110,16 +115,38 @@ typedef struct HEVCSEIAlternativeTransfer {
int preferred_transfer_characteristics;
} HEVCSEIAlternativeTransfer;
typedef struct HEVCSEITimeCode {
int present;
uint8_t num_clock_ts;
uint8_t clock_timestamp_flag[3];
uint8_t units_field_based_flag[3];
uint8_t counting_type[3];
uint8_t full_timestamp_flag[3];
uint8_t discontinuity_flag[3];
uint8_t cnt_dropped_flag[3];
uint16_t n_frames[3];
uint8_t seconds_value[3];
uint8_t minutes_value[3];
uint8_t hours_value[3];
uint8_t seconds_flag[3];
uint8_t minutes_flag[3];
uint8_t hours_flag[3];
uint8_t time_offset_length[3];
int32_t time_offset_value[3];
} HEVCSEITimeCode;
typedef struct HEVCSEI {
HEVCSEIPictureHash picture_hash;
HEVCSEIFramePacking frame_packing;
HEVCSEIDisplayOrientation display_orientation;
HEVCSEIPictureTiming picture_timing;
HEVCSEIA53Caption a53_caption;
HEVCSEIUnregistered unregistered;
HEVCSEIMasteringDisplay mastering_display;
HEVCSEIContentLight content_light;
int active_seq_parameter_set_id;
HEVCSEIAlternativeTransfer alternative_transfer;
HEVCSEITimeCode timecode;
} HEVCSEI;
struct HEVCParamSets;
+56
View File
@@ -32,6 +32,7 @@
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/stereo3d.h"
#include "libavutil/timecode.h"
#include "bswapdsp.h"
#include "bytestream.h"
@@ -348,6 +349,15 @@ static void export_stream_params(HEVCContext *s, const HEVCSPS *sps)
avctx->colorspace = AVCOL_SPC_UNSPECIFIED;
}
avctx->chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED;
if (sps->chroma_format_idc == 1) {
if (sps->vui.chroma_loc_info_present_flag) {
if (sps->vui.chroma_sample_loc_type_top_field <= 5)
avctx->chroma_sample_location = sps->vui.chroma_sample_loc_type_top_field + 1;
} else
avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
}
if (vps->vps_timing_info_present_flag) {
num = vps->vps_num_units_in_tick;
den = vps->vps_time_scale;
@@ -414,6 +424,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
*fmt++ = AV_PIX_FMT_VIDEOTOOLBOX;
#endif
#if CONFIG_HEVC_VDPAU_HWACCEL
*fmt++ = AV_PIX_FMT_VDPAU;
#endif
#if CONFIG_HEVC_NVDEC_HWACCEL
*fmt++ = AV_PIX_FMT_CUDA;
#endif
@@ -435,6 +448,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
case AV_PIX_FMT_YUV420P12:
case AV_PIX_FMT_YUV444P10:
case AV_PIX_FMT_YUV444P12:
#if CONFIG_HEVC_VDPAU_HWACCEL
*fmt++ = AV_PIX_FMT_VDPAU;
#endif
#if CONFIG_HEVC_NVDEC_HWACCEL
*fmt++ = AV_PIX_FMT_CUDA;
#endif
@@ -2794,6 +2810,46 @@ static int set_side_data(HEVCContext *s)
s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
}
for (int i = 0; i < s->sei.unregistered.nb_buf_ref; i++) {
HEVCSEIUnregistered *unreg = &s->sei.unregistered;
if (unreg->buf_ref[i]) {
AVFrameSideData *sd = av_frame_new_side_data_from_buf(out,
AV_FRAME_DATA_SEI_UNREGISTERED,
unreg->buf_ref[i]);
if (!sd)
av_buffer_unref(&unreg->buf_ref[i]);
unreg->buf_ref[i] = NULL;
}
}
s->sei.unregistered.nb_buf_ref = 0;
if (s->sei.timecode.present) {
uint32_t *tc_sd;
char tcbuf[AV_TIMECODE_STR_SIZE];
AVFrameSideData *tcside = av_frame_new_side_data(out, AV_FRAME_DATA_S12M_TIMECODE,
sizeof(uint32_t) * 4);
if (!tcside)
return AVERROR(ENOMEM);
tc_sd = (uint32_t*)tcside->data;
tc_sd[0] = s->sei.timecode.num_clock_ts;
for (int i = 0; i < tc_sd[0]; i++) {
int drop = s->sei.timecode.cnt_dropped_flag[i];
int hh = s->sei.timecode.hours_value[i];
int mm = s->sei.timecode.minutes_value[i];
int ss = s->sei.timecode.seconds_value[i];
int ff = s->sei.timecode.n_frames[i];
tc_sd[i + 1] = av_timecode_get_smpte(s->avctx->framerate, drop, hh, mm, ss, ff);
av_timecode_make_smpte_tc_string(tcbuf, tc_sd[i + 1], 0);
av_dict_set(&out->metadata, "timecode", tcbuf, 0);
}
s->sei.timecode.num_clock_ts = 0;
}
return 0;
}
+6 -9
View File
@@ -171,12 +171,10 @@ av_cold struct FFIIRFilterCoeffs *ff_iir_filter_init_coeffs(void *avc,
if (order <= 0 || order > MAXORDER || cutoff_ratio >= 1.0)
return NULL;
FF_ALLOCZ_OR_GOTO(avc, c, sizeof(FFIIRFilterCoeffs),
init_fail);
FF_ALLOC_OR_GOTO(avc, c->cx, sizeof(c->cx[0]) * ((order >> 1) + 1),
init_fail);
FF_ALLOC_OR_GOTO(avc, c->cy, sizeof(c->cy[0]) * order,
init_fail);
if (!(c = av_mallocz(sizeof(*c))) ||
!(c->cx = av_malloc (sizeof(c->cx[0]) * ((order >> 1) + 1))) ||
!(c->cy = av_malloc (sizeof(c->cy[0]) * order)))
goto free;
c->order = order;
switch (filt_type) {
@@ -190,13 +188,12 @@ av_cold struct FFIIRFilterCoeffs *ff_iir_filter_init_coeffs(void *avc,
break;
default:
av_log(avc, AV_LOG_ERROR, "filter type is not currently implemented\n");
goto init_fail;
goto free;
}
if (!ret)
return c;
init_fail:
free:
ff_iir_filter_free_coeffsp(&c);
return NULL;
}
+22 -2
View File
@@ -110,9 +110,12 @@
typedef struct DecodeSimpleContext {
AVPacket *in_pkt;
AVFrame *out_frame;
} DecodeSimpleContext;
typedef struct EncodeSimpleContext {
AVFrame *in_frame;
} EncodeSimpleContext;
typedef struct AVCodecInternal {
/**
* Whether the parent AVCodecContext is a copy of the context which had
@@ -151,6 +154,8 @@ typedef struct AVCodecInternal {
void *frame_thread_encoder;
EncodeSimpleContext es;
/**
* Number of audio samples to skip at the start of the next decoded frame
*/
@@ -170,7 +175,6 @@ typedef struct AVCodecInternal {
* buffers for using new encode/decode API through legacy API
*/
AVPacket *buffer_pkt;
int buffer_pkt_valid; // encoding: packet without data can be valid
AVFrame *buffer_frame;
int draining_done;
int compat_decode_warned;
@@ -181,6 +185,7 @@ typedef struct AVCodecInternal {
* of the packet (that should be submitted in the next decode call */
size_t compat_decode_partial_size;
AVFrame *compat_decode_frame;
AVPacket *compat_encode_packet;
int showed_multi_packet_warning;
@@ -373,6 +378,21 @@ AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx);
int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len,
void **data, size_t *sei_size);
/**
* Check AVFrame for S12M timecode side data and allocate and fill TC SEI message with timecode info
*
* @param frame Raw frame to get S12M timecode side data from
* @param prefix_len Number of bytes to allocate before SEI message
* @param data Pointer to a variable to store allocated memory
* Upon return the variable will hold NULL on error or if frame has no S12M timecode info.
* Otherwise it will point to prefix_len uninitialized bytes followed by
* *sei_size SEI message
* @param sei_size Pointer to a variable to store generated SEI message length
* @return Zero on success, negative error code on failure
*/
int ff_alloc_timecode_sei(const AVFrame *frame, size_t prefix_len,
void **data, size_t *sei_size);
/**
* Get an estimated video bitrate based on frame size, frame rate and coded
* bits per pixel.
-3
View File
@@ -509,9 +509,6 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp,
// update precincts size: 2^n value
reslevel->log2_prec_width = codsty->log2_prec_widths[reslevelno];
reslevel->log2_prec_height = codsty->log2_prec_heights[reslevelno];
if (!reslevel->log2_prec_width || !reslevel->log2_prec_height) {
return AVERROR_INVALIDDATA;
}
/* Number of bands for each resolution level */
if (reslevelno == 0)
+1
View File
@@ -144,6 +144,7 @@ typedef struct Jpeg2000CodingStyle {
uint8_t prog_order; // progression order
uint8_t log2_prec_widths[JPEG2000_MAX_RESLEVELS]; // precincts size according resolution levels
uint8_t log2_prec_heights[JPEG2000_MAX_RESLEVELS]; // TODO: initialize prec_size array with 0?
uint8_t init;
} Jpeg2000CodingStyle;
typedef struct Jpeg2000QuantStyle {
+44 -21
View File
@@ -269,6 +269,8 @@ static int get_siz(Jpeg2000DecoderContext *s)
const enum AVPixelFormat *possible_fmts = NULL;
int possible_fmts_nb = 0;
int ret;
int o_dimx, o_dimy; //original image dimensions.
int dimx, dimy;
if (bytestream2_get_bytes_left(&s->g) < 36) {
av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n");
@@ -286,10 +288,6 @@ static int get_siz(Jpeg2000DecoderContext *s)
s->tile_offset_y = bytestream2_get_be32u(&s->g); // YT0Siz
ncomponents = bytestream2_get_be16u(&s->g); // CSiz
if (s->image_offset_x || s->image_offset_y) {
avpriv_request_sample(s->avctx, "Support for image offsets");
return AVERROR_PATCHWELCOME;
}
if (av_image_check_size2(s->width, s->height, s->avctx->max_pixels, AV_PIX_FMT_NONE, 0, s->avctx)) {
avpriv_request_sample(s->avctx, "Large Dimensions");
return AVERROR_PATCHWELCOME;
@@ -371,11 +369,18 @@ static int get_siz(Jpeg2000DecoderContext *s)
}
/* compute image size with reduction factor */
ret = ff_set_dimensions(s->avctx,
ff_jpeg2000_ceildivpow2(s->width - s->image_offset_x,
s->reduction_factor),
ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
s->reduction_factor));
o_dimx = ff_jpeg2000_ceildivpow2(s->width - s->image_offset_x,
s->reduction_factor);
o_dimy = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
s->reduction_factor);
dimx = ff_jpeg2000_ceildiv(o_dimx, s->cdx[0]);
dimy = ff_jpeg2000_ceildiv(o_dimy, s->cdy[0]);
for (i = 1; i < s->ncomponents; i++) {
dimx = FFMAX(dimx, ff_jpeg2000_ceildiv(o_dimx, s->cdx[i]));
dimy = FFMAX(dimy, ff_jpeg2000_ceildiv(o_dimy, s->cdy[i]));
}
ret = ff_set_dimensions(s->avctx, dimx, dimy);
if (ret < 0)
return ret;
@@ -427,6 +432,18 @@ static int get_siz(Jpeg2000DecoderContext *s)
s->cdef[3] = 3;
i = 0;
}
} else if (ncomponents == 3 && s->precision == 8 &&
s->cdx[0] == s->cdx[1] && s->cdx[0] == s->cdx[2] &&
s->cdy[0] == s->cdy[1] && s->cdy[0] == s->cdy[2]) {
s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
i = 0;
} else if (ncomponents == 2 && s->precision == 8 &&
s->cdx[0] == s->cdx[1] && s->cdy[0] == s->cdy[1]) {
s->avctx->pix_fmt = AV_PIX_FMT_YA8;
i = 0;
} else if (ncomponents == 1 && s->precision == 8) {
s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
i = 0;
}
}
@@ -558,7 +575,7 @@ static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
if ((ret = get_cox(s, &tmp)) < 0)
return ret;
tmp.init = 1;
for (compno = 0; compno < s->ncomponents; compno++)
if (!(properties[compno] & HAD_COC))
memcpy(c + compno, &tmp, sizeof(tmp));
@@ -596,6 +613,7 @@ static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
return ret;
properties[compno] |= HAD_COC;
c->init = 1;
return 0;
}
@@ -969,12 +987,11 @@ static int init_tile(Jpeg2000DecoderContext *s, int tileno)
comp->coord_o[0][1] = tile->coord[0][1];
comp->coord_o[1][0] = tile->coord[1][0];
comp->coord_o[1][1] = tile->coord[1][1];
if (compno) {
comp->coord_o[0][0] /= s->cdx[compno];
comp->coord_o[0][1] /= s->cdx[compno];
comp->coord_o[1][0] /= s->cdy[compno];
comp->coord_o[1][1] /= s->cdy[compno];
}
comp->coord_o[0][0] = ff_jpeg2000_ceildiv(comp->coord_o[0][0], s->cdx[compno]);
comp->coord_o[0][1] = ff_jpeg2000_ceildiv(comp->coord_o[0][1], s->cdx[compno]);
comp->coord_o[1][0] = ff_jpeg2000_ceildiv(comp->coord_o[1][0], s->cdy[compno]);
comp->coord_o[1][1] = ff_jpeg2000_ceildiv(comp->coord_o[1][1], s->cdy[compno]);
comp->coord[0][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], s->reduction_factor);
comp->coord[0][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][1], s->reduction_factor);
@@ -983,7 +1000,8 @@ static int init_tile(Jpeg2000DecoderContext *s, int tileno)
if (!comp->roi_shift)
comp->roi_shift = s->roi_shift[compno];
if (!codsty->init)
return AVERROR_INVALIDDATA;
if (ret = ff_jpeg2000_init_component(comp, codsty, qntsty,
s->cbps[compno], s->cdx[compno],
s->cdy[compno], s->avctx))
@@ -1927,18 +1945,23 @@ static inline void tile_codeblocks(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile
float *datap = comp->f_data; \
int32_t *i_datap = comp->i_data; \
int cbps = s->cbps[compno]; \
int w = tile->comp[compno].coord[0][1] - s->image_offset_x; \
int w = tile->comp[compno].coord[0][1] - \
ff_jpeg2000_ceildiv(s->image_offset_x, s->cdx[compno]); \
int h = tile->comp[compno].coord[1][1] - \
ff_jpeg2000_ceildiv(s->image_offset_y, s->cdy[compno]); \
int plane = 0; \
\
if (planar) \
plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1); \
\
y = tile->comp[compno].coord[1][0] - s->image_offset_y / s->cdy[compno]; \
y = tile->comp[compno].coord[1][0] - \
ff_jpeg2000_ceildiv(s->image_offset_y, s->cdy[compno]); \
line = (PIXEL *)picture->data[plane] + y * (picture->linesize[plane] / sizeof(PIXEL));\
for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y++) { \
for (; y < h; y++) { \
PIXEL *dst; \
\
x = tile->comp[compno].coord[0][0] - s->image_offset_x / s->cdx[compno]; \
x = tile->comp[compno].coord[0][0] - \
ff_jpeg2000_ceildiv(s->image_offset_x, s->cdx[compno]); \
dst = line + x * pixelsize + compno*!planar; \
\
if (codsty->transform == FF_DWT97) { \
+55
View File
@@ -96,6 +96,16 @@ typedef struct AOMEncoderContext {
int enable_restoration;
int usage;
int tune;
int enable_rect_partitions;
int enable_1to4_partitions;
int enable_ab_partitions;
int enable_angle_delta;
int enable_cfl_intra;
int enable_paeth_intra;
int enable_smooth_intra;
int enable_intra_edge_filter;
int enable_palette;
int enable_filter_intra;
} AOMContext;
static const char *const ctlidstr[] = {
@@ -135,6 +145,18 @@ static const char *const ctlidstr[] = {
#endif
[AV1E_SET_ENABLE_CDEF] = "AV1E_SET_ENABLE_CDEF",
[AOME_SET_TUNING] = "AOME_SET_TUNING",
#if AOM_ENCODER_ABI_VERSION >= 22
[AV1E_SET_ENABLE_1TO4_PARTITIONS] = "AV1E_SET_ENABLE_1TO4_PARTITIONS",
[AV1E_SET_ENABLE_AB_PARTITIONS] = "AV1E_SET_ENABLE_AB_PARTITIONS",
[AV1E_SET_ENABLE_RECT_PARTITIONS] = "AV1E_SET_ENABLE_RECT_PARTITIONS",
[AV1E_SET_ENABLE_ANGLE_DELTA] = "AV1E_SET_ENABLE_ANGLE_DELTA",
[AV1E_SET_ENABLE_CFL_INTRA] = "AV1E_SET_ENABLE_CFL_INTRA",
[AV1E_SET_ENABLE_FILTER_INTRA] = "AV1E_SET_ENABLE_FILTER_INTRA",
[AV1E_SET_ENABLE_INTRA_EDGE_FILTER] = "AV1E_SET_ENABLE_INTRA_EDGE_FILTER",
[AV1E_SET_ENABLE_PAETH_INTRA] = "AV1E_SET_ENABLE_PAETH_INTRA",
[AV1E_SET_ENABLE_SMOOTH_INTRA] = "AV1E_SET_ENABLE_SMOOTH_INTRA",
[AV1E_SET_ENABLE_PALETTE] = "AV1E_SET_ENABLE_PALETTE",
#endif
};
static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
@@ -698,6 +720,28 @@ static av_cold int aom_init(AVCodecContext *avctx,
codecctl_int(avctx, AV1E_SET_ENABLE_CDEF, ctx->enable_cdef);
if (ctx->enable_restoration >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_RESTORATION, ctx->enable_restoration);
#if AOM_ENCODER_ABI_VERSION >= 22
if (ctx->enable_rect_partitions >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_RECT_PARTITIONS, ctx->enable_rect_partitions);
if (ctx->enable_1to4_partitions >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_1TO4_PARTITIONS, ctx->enable_1to4_partitions);
if (ctx->enable_ab_partitions >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_AB_PARTITIONS, ctx->enable_ab_partitions);
if (ctx->enable_angle_delta >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_ANGLE_DELTA, ctx->enable_angle_delta);
if (ctx->enable_cfl_intra >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_CFL_INTRA, ctx->enable_cfl_intra);
if (ctx->enable_filter_intra >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_FILTER_INTRA, ctx->enable_filter_intra);
if (ctx->enable_intra_edge_filter >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_INTRA_EDGE_FILTER, ctx->enable_intra_edge_filter);
if (ctx->enable_paeth_intra >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_PAETH_INTRA, ctx->enable_paeth_intra);
if (ctx->enable_smooth_intra >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_SMOOTH_INTRA, ctx->enable_smooth_intra);
if (ctx->enable_palette >= 0)
codecctl_int(avctx, AV1E_SET_ENABLE_PALETTE, ctx->enable_palette);
#endif
codecctl_int(avctx, AOME_SET_STATIC_THRESHOLD, ctx->static_thresh);
if (ctx->crf >= 0)
@@ -1107,6 +1151,17 @@ static const AVOption options[] = {
{ "tune", "The metric that the encoder tunes for. Automatically chosen by the encoder by default", OFFSET(tune), AV_OPT_TYPE_INT, {.i64 = -1}, -1, AOM_TUNE_SSIM, VE, "tune"},
{ "psnr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_PSNR}, 0, 0, VE, "tune"},
{ "ssim", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_SSIM}, 0, 0, VE, "tune"},
FF_AV1_PROFILE_OPTS
{ "enable-rect-partitions", "Enable rectangular partitions", OFFSET(enable_rect_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
{ "enable-1to4-partitions", "Enable 1:4/4:1 partitions", OFFSET(enable_1to4_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
{ "enable-ab-partitions", "Enable ab shape partitions", OFFSET(enable_ab_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
{ "enable-angle-delta", "Enable angle delta intra prediction", OFFSET(enable_angle_delta), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
{ "enable-cfl-intra", "Enable chroma predicted from luma intra prediction", OFFSET(enable_cfl_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
{ "enable-filter-intra", "Enable filter intra predictor", OFFSET(enable_filter_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
{ "enable-intra-edge-filter", "Enable intra edge filter", OFFSET(enable_intra_edge_filter), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
{ "enable-smooth-intra", "Enable smooth intra prediction mode", OFFSET(enable_smooth_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
{ "enable-paeth-intra", "Enable paeth predictor in intra prediction", OFFSET(enable_paeth_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
{ "enable-palette", "Enable palette prediction mode", OFFSET(enable_palette), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
{ NULL },
};
+33 -18
View File
@@ -30,12 +30,15 @@
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "avcodec.h"
#include "encode.h"
#include "internal.h"
typedef struct librav1eContext {
const AVClass *class;
RaContext *ctx;
AVFrame *frame;
RaFrame *rframe;
AVBSFContext *bsf;
uint8_t *pass_data;
@@ -165,7 +168,12 @@ static av_cold int librav1e_encode_close(AVCodecContext *avctx)
rav1e_context_unref(ctx->ctx);
ctx->ctx = NULL;
}
if (ctx->rframe) {
rav1e_frame_unref(ctx->rframe);
ctx->rframe = NULL;
}
av_frame_free(&ctx->frame);
av_bsf_free(&ctx->bsf);
av_freep(&ctx->pass_data);
@@ -180,6 +188,10 @@ static av_cold int librav1e_encode_init(AVCodecContext *avctx)
int rret;
int ret = 0;
ctx->frame = av_frame_alloc();
if (!ctx->frame)
return AVERROR(ENOMEM);
cfg = rav1e_config_default();
if (!cfg) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate rav1e config.\n");
@@ -416,18 +428,27 @@ end:
return ret;
}
static int librav1e_send_frame(AVCodecContext *avctx, const AVFrame *frame)
static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
{
librav1eContext *ctx = avctx->priv_data;
RaFrame *rframe = NULL;
RaFrame *rframe = ctx->rframe;
RaPacket *rpkt = NULL;
int ret;
if (frame) {
if (!rframe) {
AVFrame *frame = ctx->frame;
ret = ff_encode_get_frame(avctx, frame);
if (ret < 0 && ret != AVERROR_EOF)
return ret;
if (frame->buf[0]) {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
rframe = rav1e_frame_new(ctx->ctx);
if (!rframe) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate new rav1e frame.\n");
av_frame_unref(frame);
return AVERROR(ENOMEM);
}
@@ -438,17 +459,23 @@ static int librav1e_send_frame(AVCodecContext *avctx, const AVFrame *frame)
(frame->height >> shift) * frame->linesize[i],
frame->linesize[i], bytes);
}
av_frame_unref(frame);
}
}
ret = rav1e_send_frame(ctx->ctx, rframe);
if (rframe)
if (ret == RA_ENCODER_STATUS_ENOUGH_DATA) {
ctx->rframe = rframe; /* Queue is full. Store the RaFrame to retry next call */
} else {
rav1e_frame_unref(rframe); /* No need to unref if flushing. */
ctx->rframe = NULL;
}
switch (ret) {
case RA_ENCODER_STATUS_SUCCESS:
break;
case RA_ENCODER_STATUS_ENOUGH_DATA:
return AVERROR(EAGAIN);
break;
case RA_ENCODER_STATUS_FAILURE:
av_log(avctx, AV_LOG_ERROR, "Could not send frame: %s\n", rav1e_status_to_str(ret));
return AVERROR_EXTERNAL;
@@ -457,15 +484,6 @@ static int librav1e_send_frame(AVCodecContext *avctx, const AVFrame *frame)
return AVERROR_UNKNOWN;
}
return 0;
}
static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
{
librav1eContext *ctx = avctx->priv_data;
RaPacket *rpkt = NULL;
int ret;
retry:
if (avctx->flags & AV_CODEC_FLAG_PASS1) {
@@ -490,9 +508,7 @@ retry:
}
return AVERROR_EOF;
case RA_ENCODER_STATUS_ENCODED:
if (avctx->internal->draining)
goto retry;
return AVERROR(EAGAIN);
goto retry;
case RA_ENCODER_STATUS_NEED_MORE_DATA:
if (avctx->internal->draining) {
av_log(avctx, AV_LOG_ERROR, "Unexpected error when receiving packet after EOF.\n");
@@ -592,7 +608,6 @@ AVCodec ff_librav1e_encoder = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_AV1,
.init = librav1e_encode_init,
.send_frame = librav1e_send_frame,
.receive_packet = librav1e_receive_packet,
.close = librav1e_encode_close,
.priv_data_size = sizeof(librav1eContext),
+1 -1
View File
@@ -220,7 +220,7 @@ static int vpx_decode(AVCodecContext *avctx,
struct vpx_image *img, *img_alpha;
int ret;
uint8_t *side_data = NULL;
int side_data_size = 0;
int side_data_size;
ret = decode_frame(avctx, &ctx->decoder, avpkt->data, avpkt->size);
if (ret)
+2 -2
View File
@@ -310,8 +310,8 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
if (!cpb_props)
return AVERROR(ENOMEM);
cpb_props->buffer_size = ctx->params->rc.vbvBufferSize * 1000;
cpb_props->max_bitrate = ctx->params->rc.vbvMaxBitrate * 1000;
cpb_props->avg_bitrate = ctx->params->rc.bitrate * 1000;
cpb_props->max_bitrate = ctx->params->rc.vbvMaxBitrate * 1000LL;
cpb_props->avg_bitrate = ctx->params->rc.bitrate * 1000LL;
if (!(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER))
ctx->params->bRepeatHeaders = 1;
+36 -22
View File
@@ -22,6 +22,7 @@
#define _WIN32_WINNT 0x0602
#endif
#include "encode.h"
#include "mf_utils.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
@@ -30,6 +31,7 @@
typedef struct MFContext {
AVClass *av_class;
AVFrame *frame;
int is_video, is_audio;
GUID main_subtype;
IMFTransform *mft;
@@ -398,26 +400,6 @@ static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample)
return 0;
}
static int mf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
{
MFContext *c = avctx->priv_data;
int ret;
IMFSample *sample = NULL;
if (frame) {
sample = mf_avframe_to_sample(avctx, frame);
if (!sample)
return AVERROR(ENOMEM);
if (c->is_video && c->codec_api) {
if (frame->pict_type == AV_PICTURE_TYPE_I || !c->sample_sent)
ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoForceKeyFrame, FF_VAL_VT_UI4(1));
}
}
ret = mf_send_sample(avctx, sample);
if (sample)
IMFSample_Release(sample);
return ret;
}
static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample)
{
MFContext *c = avctx->priv_data;
@@ -500,9 +482,36 @@ static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample)
static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
{
IMFSample *sample;
MFContext *c = avctx->priv_data;
IMFSample *sample = NULL;
int ret;
if (!c->frame->buf[0]) {
ret = ff_encode_get_frame(avctx, c->frame);
if (ret < 0 && ret != AVERROR_EOF)
return ret;
}
if (c->frame->buf[0]) {
sample = mf_avframe_to_sample(avctx, c->frame);
if (!sample) {
av_frame_unref(c->frame);
return AVERROR(ENOMEM);
}
if (c->is_video && c->codec_api) {
if (c->frame->pict_type == AV_PICTURE_TYPE_I || !c->sample_sent)
ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoForceKeyFrame, FF_VAL_VT_UI4(1));
}
}
ret = mf_send_sample(avctx, sample);
if (sample)
IMFSample_Release(sample);
if (ret != AVERROR(EAGAIN))
av_frame_unref(c->frame);
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
return ret;
ret = mf_receive_sample(avctx, &sample);
if (ret < 0)
return ret;
@@ -1034,6 +1043,10 @@ static int mf_init(AVCodecContext *avctx)
const CLSID *subtype = ff_codec_to_mf_subtype(avctx->codec_id);
int use_hw = 0;
c->frame = av_frame_alloc();
if (!c->frame)
return AVERROR(ENOMEM);
c->is_audio = avctx->codec_type == AVMEDIA_TYPE_AUDIO;
c->is_video = !c->is_audio;
c->reorder_delay = AV_NOPTS_VALUE;
@@ -1122,6 +1135,8 @@ static int mf_close(AVCodecContext *avctx)
ff_free_mf(&c->mft);
av_frame_free(&c->frame);
av_freep(&avctx->extradata);
avctx->extradata_size = 0;
@@ -1146,7 +1161,6 @@ static int mf_close(AVCodecContext *avctx)
.priv_data_size = sizeof(MFContext), \
.init = mf_init, \
.close = mf_close, \
.send_frame = mf_send_frame, \
.receive_packet = mf_receive_packet, \
EXTRA \
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID, \
+12 -14
View File
@@ -531,7 +531,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx)
av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d. Supported "
"sample rates are 44100, 88200, 176400, 48000, "
"96000, and 192000.\n", avctx->sample_rate);
return -1;
return AVERROR(EINVAL);
}
ctx->coded_sample_rate[1] = -1 & 0xf;
@@ -564,7 +564,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx)
default:
av_log(avctx, AV_LOG_ERROR, "Sample format not supported. "
"Only 16- and 24-bit samples are supported.\n");
return -1;
return AVERROR(EINVAL);
}
ctx->coded_sample_fmt[1] = -1 & 0xf;
@@ -638,7 +638,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx)
ctx->channel_arrangement = 12; break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported channel arrangement\n");
return -1;
return AVERROR(EINVAL);
}
ctx->flags = FLAGS_DVDA;
ctx->channel_occupancy = ff_mlp_ch_info[ctx->channel_arrangement].channel_occupancy;
@@ -666,7 +666,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx)
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported channel arrangement\n");
return -1;
return AVERROR(EINVAL);
}
ctx->flags = 0;
ctx->channel_occupancy = 0;
@@ -1190,7 +1190,7 @@ static unsigned int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf,
int total_length;
if (buf_size < 4)
return -1;
return AVERROR(EINVAL);
/* Frame header will be written at the end. */
buf += 4;
@@ -1198,7 +1198,7 @@ static unsigned int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf,
if (restart_frame) {
if (buf_size < 28)
return -1;
return AVERROR(EINVAL);
write_major_sync(ctx, buf, buf_size);
buf += 28;
buf_size -= 28;
@@ -1820,7 +1820,8 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel)
if (!filter_state_buffer[i]) {
av_log(ctx->avctx, AV_LOG_ERROR,
"Not enough memory for applying filters.\n");
return -1;
ret = AVERROR(ENOMEM);
goto free_and_return;
}
}
@@ -1848,7 +1849,7 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel)
residual = sample - (accum & mask);
if (residual < SAMPLE_MIN(24) || residual > SAMPLE_MAX(24)) {
ret = -1;
ret = AVERROR_INVALIDDATA;
goto free_and_return;
}
@@ -2226,9 +2227,6 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
if ((ret = ff_alloc_packet2(avctx, avpkt, 87500 * avctx->channels, 0)) < 0)
return ret;
if (!frame)
return 1;
/* add current frame to queue */
if ((ret = ff_af_queue_add(&ctx->afq, frame)) < 0)
return ret;
@@ -2267,7 +2265,7 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
if (ctx->frame_size[ctx->frame_index] > MAX_BLOCKSIZE) {
av_log(avctx, AV_LOG_ERROR, "Invalid frame size (%d > %d)\n",
ctx->frame_size[ctx->frame_index], MAX_BLOCKSIZE);
return -1;
return AVERROR_INVALIDDATA;
}
restart_frame = !ctx->frame_index;
@@ -2389,7 +2387,7 @@ AVCodec ff_mlp_encoder = {
.init = mlp_encode_init,
.encode2 = mlp_encode_frame,
.close = mlp_encode_close,
.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL,
.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL,
.sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE},
.supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0},
.channel_layouts = ff_mlp_channel_layouts,
@@ -2405,7 +2403,7 @@ AVCodec ff_truehd_encoder = {
.init = mlp_encode_init,
.encode2 = mlp_encode_frame,
.close = mlp_encode_close,
.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL,
.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL,
.sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE},
.supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0},
.channel_layouts = (const uint64_t[]) {AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1_BACK, 0},
+50 -38
View File
@@ -57,8 +57,7 @@ typedef struct Mpeg1Context {
AVPanScan pan_scan; /* some temporary storage for the panscan */
AVStereo3D stereo3d;
int has_stereo3d;
uint8_t *a53_caption;
int a53_caption_size;
AVBufferRef *a53_buf_ref;
uint8_t afd;
int has_afd;
int slice_count;
@@ -1635,13 +1634,13 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
return AVERROR(ENOMEM);
memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan));
if (s1->a53_caption) {
AVFrameSideData *sd = av_frame_new_side_data(
if (s1->a53_buf_ref) {
AVFrameSideData *sd = av_frame_new_side_data_from_buf(
s->current_picture_ptr->f, AV_FRAME_DATA_A53_CC,
s1->a53_caption_size);
if (sd)
memcpy(sd->data, s1->a53_caption, s1->a53_caption_size);
av_freep(&s1->a53_caption);
s1->a53_buf_ref);
if (!sd)
av_buffer_unref(&s1->a53_buf_ref);
s1->a53_buf_ref = NULL;
}
if (s1->has_stereo3d) {
@@ -2242,14 +2241,18 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
/* extract A53 Part 4 CC data */
int cc_count = p[5] & 0x1f;
if (cc_count > 0 && buf_size >= 7 + cc_count * 3) {
av_freep(&s1->a53_caption);
s1->a53_caption_size = cc_count * 3;
s1->a53_caption = av_malloc(s1->a53_caption_size);
if (!s1->a53_caption) {
s1->a53_caption_size = 0;
} else {
memcpy(s1->a53_caption, p + 7, s1->a53_caption_size);
}
int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0;
const uint64_t new_size = (old_size + cc_count
* UINT64_C(3));
int ret;
if (new_size > INT_MAX)
return AVERROR(EINVAL);
ret = av_buffer_realloc(&s1->a53_buf_ref, new_size);
if (ret >= 0)
memcpy(s1->a53_buf_ref->data + old_size, p + 7, cc_count * UINT64_C(3));
avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
}
return 1;
@@ -2258,19 +2261,23 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
/* extract SCTE-20 CC data */
GetBitContext gb;
int cc_count = 0;
int i;
int i, ret;
init_get_bits(&gb, p + 2, buf_size - 2);
cc_count = get_bits(&gb, 5);
if (cc_count > 0) {
av_freep(&s1->a53_caption);
s1->a53_caption_size = cc_count * 3;
s1->a53_caption = av_mallocz(s1->a53_caption_size);
if (!s1->a53_caption) {
s1->a53_caption_size = 0;
} else {
int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0;
const uint64_t new_size = (old_size + cc_count
* UINT64_C(3));
if (new_size > INT_MAX)
return AVERROR(EINVAL);
ret = av_buffer_realloc(&s1->a53_buf_ref, new_size);
if (ret >= 0) {
uint8_t field, cc1, cc2;
uint8_t *cap = s1->a53_caption;
uint8_t *cap = s1->a53_buf_ref->data;
memset(s1->a53_buf_ref->data + old_size, 0, cc_count * 3);
for (i = 0; i < cc_count && get_bits_left(&gb) >= 26; i++) {
skip_bits(&gb, 2); // priority
field = get_bits(&gb, 2);
@@ -2322,21 +2329,23 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
* on the even field. There also exist DVDs in the wild that encode an odd field count and the
* caption_extra_field_added/caption_odd_field_first bits change per packet to allow that. */
int cc_count = 0;
int i;
int i, ret;
// There is a caption count field in the data, but it is often
// incorrect. So count the number of captions present.
for (i = 5; i + 6 <= buf_size && ((p[i] & 0xfe) == 0xfe); i += 6)
cc_count++;
// Transform the DVD format into A53 Part 4 format
if (cc_count > 0) {
av_freep(&s1->a53_caption);
s1->a53_caption_size = cc_count * 6;
s1->a53_caption = av_malloc(s1->a53_caption_size);
if (!s1->a53_caption) {
s1->a53_caption_size = 0;
} else {
int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0;
const uint64_t new_size = (old_size + cc_count
* UINT64_C(6));
if (new_size > INT_MAX)
return AVERROR(EINVAL);
ret = av_buffer_realloc(&s1->a53_buf_ref, new_size);
if (ret >= 0) {
uint8_t field1 = !!(p[4] & 0x80);
uint8_t *cap = s1->a53_caption;
uint8_t *cap = s1->a53_buf_ref->data;
p += 5;
for (i = 0; i < cc_count; i++) {
cap[0] = (p[0] == 0xff && field1) ? 0xfc : 0xfd;
@@ -2846,6 +2855,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, void *data,
s2->current_picture_ptr = NULL;
if (s2->timecode_frame_start != -1 && *got_output) {
char tcbuf[AV_TIMECODE_STR_SIZE];
AVFrameSideData *tcside = av_frame_new_side_data(picture,
AV_FRAME_DATA_GOP_TIMECODE,
sizeof(int64_t));
@@ -2853,6 +2863,9 @@ static int mpeg_decode_frame(AVCodecContext *avctx, void *data,
return AVERROR(ENOMEM);
memcpy(tcside->data, &s2->timecode_frame_start, sizeof(int64_t));
av_timecode_make_mpeg_tc_string(tcbuf, s2->timecode_frame_start);
av_dict_set(&picture->metadata, "timecode", tcbuf, 0);
s2->timecode_frame_start = -1;
}
}
@@ -2873,9 +2886,8 @@ static av_cold int mpeg_decode_end(AVCodecContext *avctx)
{
Mpeg1Context *s = avctx->priv_data;
if (s->mpeg_enc_ctx_allocated)
ff_mpv_common_end(&s->mpeg_enc_ctx);
av_freep(&s->a53_caption);
ff_mpv_common_end(&s->mpeg_enc_ctx);
av_buffer_unref(&s->a53_buf_ref);
return 0;
}
@@ -2891,7 +2903,7 @@ AVCodec ff_mpeg1video_decoder = {
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SLICE_THREADS,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.flush = flush,
.max_lowres = 3,
.update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context),
@@ -2924,7 +2936,7 @@ AVCodec ff_mpeg2video_decoder = {
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SLICE_THREADS,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.flush = flush,
.max_lowres = 3,
.profiles = NULL_IF_CONFIG_SMALL(ff_mpeg2_video_profiles),
@@ -2968,7 +2980,7 @@ AVCodec ff_mpegvideo_decoder = {
.close = mpeg_decode_end,
.decode = mpeg_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.flush = flush,
.max_lowres = 3,
};
+4 -4
View File
@@ -137,7 +137,7 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
se->vertical_size_extension << 12 | sh->vertical_size_value,
};
err = ff_cbs_insert_unit_content(ctx->cbc, frag, se_pos + 1,
err = ff_cbs_insert_unit_content(frag, se_pos + 1,
MPEG2_START_EXTENSION,
&ctx->sequence_display_extension,
NULL);
@@ -200,7 +200,7 @@ static int mpeg2_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
err = 0;
fail:
ff_cbs_fragment_reset(ctx->cbc, frag);
ff_cbs_fragment_reset(frag);
if (err < 0)
av_packet_unref(pkt);
@@ -252,7 +252,7 @@ static int mpeg2_metadata_init(AVBSFContext *bsf)
err = 0;
fail:
ff_cbs_fragment_reset(ctx->cbc, frag);
ff_cbs_fragment_reset(frag);
return err;
}
@@ -260,7 +260,7 @@ static void mpeg2_metadata_close(AVBSFContext *bsf)
{
MPEG2MetadataContext *ctx = bsf->priv_data;
ff_cbs_fragment_free(ctx->cbc, &ctx->fragment);
ff_cbs_fragment_free(&ctx->fragment);
ff_cbs_close(&ctx->cbc);
}
+2 -1
View File
@@ -3603,7 +3603,8 @@ AVCodec ff_mpeg4_decoder = {
AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_FRAME_THREADS,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM |
FF_CODEC_CAP_ALLOCATE_PROGRESS,
FF_CODEC_CAP_ALLOCATE_PROGRESS |
FF_CODEC_CAP_INIT_CLEANUP,
.flush = ff_mpeg_flush,
.max_lowres = 3,
.pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
+3 -8
View File
@@ -78,20 +78,15 @@ int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,
// at uvlinesize. It supports only YUV420 so 24x24 is enough
// linesize * interlaced * MBsize
// we also use this buffer for encoding in encode_mb_internal() needig an additional 32 lines
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, sc->edge_emu_buffer, alloc_size, EMU_EDGE_HEIGHT,
fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, me->scratchpad, alloc_size, 4 * 16 * 2,
fail)
if (!FF_ALLOCZ_TYPED_ARRAY(sc->edge_emu_buffer, alloc_size * EMU_EDGE_HEIGHT) ||
!FF_ALLOCZ_TYPED_ARRAY(me->scratchpad, alloc_size * 4 * 16 * 2))
return AVERROR(ENOMEM);
me->temp = me->scratchpad;
sc->rd_scratchpad = me->scratchpad;
sc->b_scratchpad = me->scratchpad;
sc->obmc_scratchpad = me->scratchpad + 16;
return 0;
fail:
av_freep(&sc->edge_emu_buffer);
return AVERROR(ENOMEM);
}
/**
+68 -86
View File
@@ -372,25 +372,27 @@ static int init_duplicate_context(MpegEncContext *s)
s->sc.obmc_scratchpad = NULL;
if (s->encoding) {
FF_ALLOCZ_OR_GOTO(s->avctx, s->me.map,
ME_MAP_SIZE * sizeof(uint32_t), fail)
FF_ALLOCZ_OR_GOTO(s->avctx, s->me.score_map,
ME_MAP_SIZE * sizeof(uint32_t), fail)
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);
if (s->noise_reduction) {
FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_error_sum,
2 * 64 * sizeof(int), fail)
if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_error_sum, 2))
return AVERROR(ENOMEM);
}
}
FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64 * 12 * 2 * sizeof(int16_t), fail)
if (!FF_ALLOCZ_TYPED_ARRAY(s->blocks, 2))
return AVERROR(ENOMEM);
s->block = s->blocks[0];
for (i = 0; i < 12; i++) {
s->pblocks[i] = &s->block[i];
}
FF_ALLOCZ_OR_GOTO(s->avctx, s->block32, sizeof(*s->block32), fail)
if (!(s->block32 = av_mallocz(sizeof(*s->block32))) ||
!(s->dpcm_macroblock = av_mallocz(sizeof(*s->dpcm_macroblock))))
return AVERROR(ENOMEM);
s->dpcm_direction = 0;
FF_ALLOCZ_OR_GOTO(s->avctx, s->dpcm_macroblock, sizeof(*s->dpcm_macroblock), fail)
if (s->avctx->codec_tag == AV_RL32("VCR2")) {
// exchange uv
@@ -399,16 +401,14 @@ static int init_duplicate_context(MpegEncContext *s)
if (s->out_format == FMT_H263) {
/* ac values */
FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_val_base,
yc_size * sizeof(int16_t) * 16, fail);
if (!FF_ALLOCZ_TYPED_ARRAY(s->ac_val_base, yc_size))
return AVERROR(ENOMEM);
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;
}
return 0;
fail:
return AVERROR(ENOMEM); // free() through ff_mpv_common_end()
}
static void free_duplicate_context(MpegEncContext *s)
@@ -715,8 +715,8 @@ static int init_context_frame(MpegEncContext *s)
if (s->mb_height & 1)
yc_size += 2*s->b8_stride + 2*s->mb_stride;
FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int),
fail); // error resilience code looks cleaner with this
if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_index2xy, s->mb_num + 1))
return AVERROR(ENOMEM);
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;
@@ -725,12 +725,13 @@ static int init_context_frame(MpegEncContext *s)
if (s->encoding) {
/* Allocate MV tables */
FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail)
FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail)
FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail)
FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail)
FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail)
FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail)
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);
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;
@@ -739,15 +740,11 @@ static int init_context_frame(MpegEncContext *s)
s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1;
/* Allocate MB type table */
FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type, mb_array_size * sizeof(uint16_t), fail) // needed for encoding
FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail)
FF_ALLOC_OR_GOTO(s->avctx, s->cplx_tab,
mb_array_size * sizeof(float), fail);
FF_ALLOC_OR_GOTO(s->avctx, s->bits_tab,
mb_array_size * sizeof(float), fail);
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);
}
if (s->codec_id == AV_CODEC_ID_MPEG4 ||
@@ -757,34 +754,34 @@ static int init_context_frame(MpegEncContext *s)
int j, k;
for (j = 0; j < 2; j++) {
for (k = 0; k < 2; k++) {
FF_ALLOCZ_OR_GOTO(s->avctx,
s->b_field_mv_table_base[i][j][k],
mv_table_size * 2 * sizeof(int16_t),
fail);
if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_mv_table_base[i][j][k], mv_table_size))
return AVERROR(ENOMEM);
s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] +
s->mb_stride + 1;
}
FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], mb_array_size * 2 * sizeof(uint8_t), fail)
FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], mv_table_size * 2 * sizeof(int16_t), fail)
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);
s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + s->mb_stride + 1;
}
FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], mb_array_size * 2 * sizeof(uint8_t), fail)
if (!FF_ALLOCZ_TYPED_ARRAY(s->p_field_select_table[i], mv_table_size * 2))
return AVERROR(ENOMEM);
}
}
if (s->out_format == FMT_H263) {
/* cbp values */
FF_ALLOCZ_OR_GOTO(s->avctx, s->coded_block_base, y_size + (s->mb_height&1)*2*s->b8_stride, fail);
/* 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);
s->coded_block = s->coded_block_base + s->b8_stride + 1;
/* cbp, ac_pred, pred_dir */
FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table , mb_array_size * sizeof(uint8_t), fail);
FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, mb_array_size * sizeof(uint8_t), fail);
}
if (s->h263_pred || s->h263_plus || !s->encoding) {
/* dc values */
// MN: we need these for error resilience of intra-frames
FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, yc_size * sizeof(int16_t), fail);
if (!FF_ALLOCZ_TYPED_ARRAY(s->dc_val_base, yc_size))
return AVERROR(ENOMEM);
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;
@@ -792,17 +789,14 @@ static int init_context_frame(MpegEncContext *s)
s->dc_val_base[i] = 1024;
}
/* which mb is an intra block */
FF_ALLOCZ_OR_GOTO(s->avctx, s->mbintra_table, mb_array_size, fail);
/* which mb is an intra block, init macroblock skip table */
if (!FF_ALLOCZ_TYPED_ARRAY(s->mbintra_table, mb_array_size) ||
// 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);
memset(s->mbintra_table, 1, mb_array_size);
/* init macroblock skip table */
FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size + 2, fail);
// Note the + 1 is for a quicker MPEG-4 slice_end detection
return ff_mpeg_er_init(s);
fail:
return AVERROR(ENOMEM);
}
static void clear_context(MpegEncContext *s)
@@ -934,28 +928,22 @@ av_cold int ff_mpv_common_init(MpegEncContext *s)
if (ret)
return ret;
FF_ALLOCZ_OR_GOTO(s->avctx, s->picture,
MAX_PICTURE_COUNT * sizeof(Picture), fail_nomem);
if (!FF_ALLOCZ_TYPED_ARRAY(s->picture, MAX_PICTURE_COUNT))
return AVERROR(ENOMEM);
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
s->picture[i].f = av_frame_alloc();
if (!s->picture[i].f)
goto fail_nomem;
return AVERROR(ENOMEM);
}
s->next_picture.f = av_frame_alloc();
if (!s->next_picture.f)
goto fail_nomem;
s->last_picture.f = av_frame_alloc();
if (!s->last_picture.f)
goto fail_nomem;
s->current_picture.f = av_frame_alloc();
if (!s->current_picture.f)
goto fail_nomem;
s->new_picture.f = av_frame_alloc();
if (!s->new_picture.f)
goto fail_nomem;
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()))
return AVERROR(ENOMEM);
if ((ret = init_context_frame(s)))
goto fail_nomem;
return AVERROR(ENOMEM);
s->parse_context.state = -1;
@@ -969,10 +957,10 @@ av_cold int ff_mpv_common_init(MpegEncContext *s)
if (i) {
s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));
if (!s->thread_context[i])
goto fail_nomem;
return AVERROR(ENOMEM);
}
if ((ret = init_duplicate_context(s->thread_context[i])) < 0)
goto fail;
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 =
@@ -980,7 +968,7 @@ av_cold int ff_mpv_common_init(MpegEncContext *s)
}
} else {
if ((ret = init_duplicate_context(s)) < 0)
goto fail;
return ret;
s->start_mb_y = 0;
s->end_mb_y = s->mb_height;
}
@@ -988,11 +976,6 @@ av_cold int ff_mpv_common_init(MpegEncContext *s)
// }
return 0;
fail_nomem:
ret = AVERROR(ENOMEM);
fail:
ff_mpv_common_end(s);
return ret;
}
/**
@@ -1085,10 +1068,10 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)
if ((s->width || s->height) &&
(err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0)
goto fail;
return err;
if ((err = init_context_frame(s)))
goto fail;
return err;
memset(s->thread_context, 0, sizeof(s->thread_context));
s->thread_context[0] = s;
@@ -1100,12 +1083,11 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)
if (i) {
s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));
if (!s->thread_context[i]) {
err = AVERROR(ENOMEM);
goto fail;
return AVERROR(ENOMEM);
}
}
if ((err = init_duplicate_context(s->thread_context[i])) < 0)
goto fail;
return err;
s->thread_context[i]->start_mb_y =
(s->mb_height * (i) + nb_slices / 2) / nb_slices;
s->thread_context[i]->end_mb_y =
@@ -1114,7 +1096,7 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)
} else {
err = init_duplicate_context(s);
if (err < 0)
goto fail;
return err;
s->start_mb_y = 0;
s->end_mb_y = s->mb_height;
}
@@ -1122,9 +1104,6 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)
}
return 0;
fail:
ff_mpv_common_end(s);
return err;
}
/* init common structure for both encoder and decoder */
@@ -1133,7 +1112,7 @@ void ff_mpv_common_end(MpegEncContext *s)
int i;
if (!s)
return ;
return;
if (s->slice_context_count > 1) {
for (i = 0; i < s->slice_context_count; i++) {
@@ -1151,6 +1130,9 @@ void ff_mpv_common_end(MpegEncContext *s)
av_freep(&s->bitstream_buffer);
s->allocated_bitstream_buffer_size = 0;
if (!s->avctx)
return;
if (s->picture) {
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
ff_free_picture_tables(&s->picture[i]);
+15 -19
View File
@@ -925,27 +925,25 @@ FF_ENABLE_DEPRECATION_WARNINGS
ff_qpeldsp_init(&s->qdsp);
if (s->msmpeg4_version) {
FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats,
2 * 2 * (MAX_LEVEL + 1) *
(MAX_RUN + 1) * 2 * sizeof(int), fail);
int ac_stats_size = 2 * 2 * (MAX_LEVEL + 1) * (MAX_RUN + 1) * 2 * sizeof(int);
if (!(s->ac_stats = av_mallocz(ac_stats_size)))
return AVERROR(ENOMEM);
}
FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail);
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix, 64 * 32 * sizeof(int), fail);
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix, 64 * 32 * sizeof(int), fail);
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix, 64 * 32 * sizeof(int), fail);
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail);
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail);
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail);
FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture,
MAX_PICTURE_COUNT * sizeof(Picture *), fail);
FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture,
MAX_PICTURE_COUNT * sizeof(Picture *), fail);
if (!(s->avctx->stats_out = av_mallocz(256)) ||
!FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix, 32) ||
!FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix, 32) ||
!FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix, 32) ||
!FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix16, 32) ||
!FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32) ||
!FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix16, 32) ||
!FF_ALLOCZ_TYPED_ARRAY(s->input_picture, MAX_PICTURE_COUNT) ||
!FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_PICTURE_COUNT))
return AVERROR(ENOMEM);
if (s->noise_reduction) {
FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset,
2 * 64 * sizeof(uint16_t), fail);
if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
return AVERROR(ENOMEM);
}
ff_dct_encode_init(s);
@@ -1060,8 +1058,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
cpb_props->buffer_size = avctx->rc_buffer_size;
return 0;
fail:
return AVERROR_UNKNOWN;
}
av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
+4 -4
View File
@@ -888,7 +888,7 @@ AVCodec ff_msmpeg4v1_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
@@ -906,7 +906,7 @@ AVCodec ff_msmpeg4v2_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
@@ -924,7 +924,7 @@ AVCodec ff_msmpeg4v3_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
@@ -942,7 +942,7 @@ AVCodec ff_wmv1_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
-10
View File
@@ -143,7 +143,6 @@ static int decode_tag(AVCodecContext *avctx, void *data,
{
AVFrame *frame = data;
const uint8_t *buf = avpkt->data;
const uint8_t *side=av_packet_get_side_data(avpkt, 'F', NULL);
int buf_size = avpkt->size;
NellyMoserDecodeContext *s = avctx->priv_data;
int blocks, i, ret;
@@ -160,15 +159,6 @@ static int decode_tag(AVCodecContext *avctx, void *data,
av_log(avctx, AV_LOG_WARNING, "Leftover bytes: %d.\n",
buf_size % NELLY_BLOCK_LEN);
}
/* Normal numbers of blocks for sample rates:
* 8000 Hz - 1
* 11025 Hz - 2
* 16000 Hz - 3
* 22050 Hz - 4
* 44100 Hz - 8
*/
if(side && blocks>1 && avctx->sample_rate%11025==0 && (1<<((side[0]>>2)&3)) == blocks)
avctx->sample_rate= 11025*(blocks/2);
/* get output buffer */
frame->nb_samples = NELLY_SAMPLES * blocks;
+136 -61
View File
@@ -22,6 +22,7 @@
#include "config.h"
#include "nvenc.h"
#include "hevc_sei.h"
#include "libavutil/hwcontext_cuda.h"
#include "libavutil/hwcontext.h"
@@ -30,6 +31,7 @@
#include "libavutil/avassert.h"
#include "libavutil/mem.h"
#include "libavutil/pixdesc.h"
#include "encode.h"
#include "internal.h"
#include "packet_internal.h"
@@ -40,6 +42,12 @@
rc == NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ || \
rc == NV_ENC_PARAMS_RC_CBR_HQ)
#ifdef NVENC_HAVE_NEW_PRESETS
#define IS_SDK10_PRESET(p) ((p) >= PRESET_P1 && (p) <= PRESET_P7)
#else
#define IS_SDK10_PRESET(p) 0
#endif
const enum AVPixelFormat ff_nvenc_pix_fmts[] = {
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NV12,
@@ -143,8 +151,14 @@ static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err,
static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level)
{
#if NVENCAPI_CHECK_VERSION(9, 2)
#if NVENCAPI_CHECK_VERSION(10, 1)
const char *minver = "(unknown)";
#elif NVENCAPI_CHECK_VERSION(10, 0)
# if defined(_WIN32) || defined(__CYGWIN__)
const char *minver = "450.51";
# else
const char *minver = "445.87";
# endif
#elif NVENCAPI_CHECK_VERSION(9, 1)
# if defined(_WIN32) || defined(__CYGWIN__)
const char *minver = "436.15";
@@ -648,6 +662,15 @@ static void nvenc_map_preset(NvencContext *ctx)
PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY),
PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS),
PRESET(LOSSLESS_HP, NVENC_LOSSLESS),
#ifdef NVENC_HAVE_NEW_PRESETS
PRESET(P1),
PRESET(P2),
PRESET(P3),
PRESET(P4),
PRESET(P5),
PRESET(P6),
PRESET(P7),
#endif
};
GUIDTuple *t = &presets[ctx->preset];
@@ -857,6 +880,12 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx)
if (avctx->rc_max_rate > 0)
ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate;
#ifdef NVENC_HAVE_MULTIPASS
ctx->encode_config.rcParams.multiPass = ctx->multipass;
if (ctx->encode_config.rcParams.multiPass != NV_ENC_MULTI_PASS_DISABLED)
ctx->flags |= NVENC_TWO_PASSES;
#endif
if (ctx->rc < 0) {
if (ctx->flags & NVENC_ONE_PASS)
ctx->twopass = 0;
@@ -891,6 +920,11 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx)
ctx->rc &= ~RC_MODE_DEPRECATED;
}
#ifdef NVENC_HAVE_LDKFS
if (ctx->ldkfs)
ctx->encode_config.rcParams.lowDelayKeyFrameScale = ctx->ldkfs;
#endif
if (ctx->flags & NVENC_LOSSLESS) {
set_lossless(avctx);
} else if (ctx->rc >= 0) {
@@ -1200,10 +1234,27 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
preset_config.version = NV_ENC_PRESET_CONFIG_VER;
preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder,
ctx->init_encode_params.encodeGUID,
ctx->init_encode_params.presetGUID,
&preset_config);
if (IS_SDK10_PRESET(ctx->preset)) {
#ifdef NVENC_HAVE_NEW_PRESETS
ctx->init_encode_params.tuningInfo = ctx->tuning_info;
nv_status = p_nvenc->nvEncGetEncodePresetConfigEx(ctx->nvencoder,
ctx->init_encode_params.encodeGUID,
ctx->init_encode_params.presetGUID,
ctx->init_encode_params.tuningInfo,
&preset_config);
#endif
} else {
#ifdef NVENC_HAVE_NEW_PRESETS
// Turn off tuning info parameter if older presets are on
ctx->init_encode_params.tuningInfo = 0;
#endif
nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder,
ctx->init_encode_params.encodeGUID,
ctx->init_encode_params.presetGUID,
&preset_config);
}
if (nv_status != NV_ENC_SUCCESS)
return nvenc_print_error(avctx, nv_status, "Cannot get the preset configuration");
@@ -1226,6 +1277,17 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
ctx->init_encode_params.enableEncodeAsync = 0;
ctx->init_encode_params.enablePTD = 1;
#ifdef NVENC_HAVE_NEW_PRESETS
/* If lookahead isn't set from CLI, use value from preset.
* P6 & P7 presets may enable lookahead for better quality.
* */
if (ctx->rc_lookahead == 0 && ctx->encode_config.rcParams.enableLookahead)
ctx->rc_lookahead = ctx->encode_config.rcParams.lookaheadDepth;
if (ctx->init_encode_params.tuningInfo == NV_ENC_TUNING_INFO_LOSSLESS)
ctx->flags |= NVENC_LOSSLESS;
#endif
if (ctx->weighted_pred == 1)
ctx->init_encode_params.enableWeightedPrediction = 1;
@@ -1509,6 +1571,8 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx)
av_freep(&ctx->surfaces);
ctx->nb_surfaces = 0;
av_frame_free(&ctx->frame);
if (ctx->nvencoder) {
p_nvenc->nvEncDestroyEncoder(ctx->nvencoder);
@@ -1562,6 +1626,10 @@ av_cold int ff_nvenc_encode_init(AVCodecContext *avctx)
ctx->data_pix_fmt = avctx->pix_fmt;
}
ctx->frame = av_frame_alloc();
if (!ctx->frame)
return AVERROR(ENOMEM);
if ((ret = nvenc_load_libraries(avctx)) < 0)
return ret;
@@ -1776,7 +1844,8 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame,
static void nvenc_codec_specific_pic_params(AVCodecContext *avctx,
NV_ENC_PIC_PARAMS *params,
NV_ENC_SEI_PAYLOAD *sei_data)
NV_ENC_SEI_PAYLOAD *sei_data,
int sei_count)
{
NvencContext *ctx = avctx->priv_data;
@@ -1786,9 +1855,9 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx,
ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;
params->codecPicParams.h264PicParams.sliceModeData =
ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
if (sei_data) {
if (sei_count > 0) {
params->codecPicParams.h264PicParams.seiPayloadArray = sei_data;
params->codecPicParams.h264PicParams.seiPayloadArrayCnt = 1;
params->codecPicParams.h264PicParams.seiPayloadArrayCnt = sei_count;
}
break;
@@ -1797,9 +1866,9 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx,
ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;
params->codecPicParams.hevcPicParams.sliceModeData =
ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
if (sei_data) {
if (sei_count > 0) {
params->codecPicParams.hevcPicParams.seiPayloadArray = sei_data;
params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = 1;
params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = sei_count;
}
break;
@@ -1879,9 +1948,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur
goto error;
}
res = pkt->data ?
ff_alloc_packet2(avctx, pkt, lock_params.bitstreamSizeInBytes, lock_params.bitstreamSizeInBytes) :
av_new_packet(pkt, lock_params.bitstreamSizeInBytes);
res = av_new_packet(pkt, lock_params.bitstreamSizeInBytes);
if (res < 0) {
p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);
@@ -2067,13 +2134,14 @@ static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame)
}
}
int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
{
NVENCSTATUS nv_status;
NvencSurface *tmp_out_surf, *in_surf;
int res, res2;
NV_ENC_SEI_PAYLOAD *sei_data = NULL;
size_t sei_size;
NV_ENC_SEI_PAYLOAD sei_data[8];
int sei_count = 0;
int i;
NvencContext *ctx = avctx->priv_data;
NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
@@ -2085,15 +2153,7 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder)
return AVERROR(EINVAL);
if (ctx->encoder_flushing) {
if (avctx->internal->draining)
return AVERROR_EOF;
ctx->encoder_flushing = 0;
av_fifo_reset(ctx->timestamp_list);
}
if (frame) {
if (frame && frame->buf[0]) {
in_surf = get_free_frame(ctx);
if (!in_surf)
return AVERROR(EAGAIN);
@@ -2139,21 +2199,40 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
pic_params.inputTimeStamp = frame->pts;
if (ctx->a53_cc && av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC)) {
if (ff_alloc_a53_sei(frame, sizeof(NV_ENC_SEI_PAYLOAD), (void**)&sei_data, &sei_size) < 0) {
void *a53_data = NULL;
size_t a53_size = 0;
if (ff_alloc_a53_sei(frame, 0, (void**)&a53_data, &a53_size) < 0) {
av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
}
if (sei_data) {
sei_data->payloadSize = (uint32_t)sei_size;
sei_data->payloadType = 4;
sei_data->payload = (uint8_t*)(sei_data + 1);
if (a53_data) {
sei_data[sei_count].payloadSize = (uint32_t)a53_size;
sei_data[sei_count].payloadType = 4;
sei_data[sei_count].payload = (uint8_t*)a53_data;
sei_count ++;
}
}
nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data);
if (ctx->s12m_tc && av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) {
void *tc_data = NULL;
size_t tc_size = 0;
if (ff_alloc_timecode_sei(frame, 0, (void**)&tc_data, &tc_size) < 0) {
av_log(ctx, AV_LOG_ERROR, "Not enough memory for timecode sei, skipping\n");
}
if (tc_data) {
sei_data[sei_count].payloadSize = (uint32_t)tc_size;
sei_data[sei_count].payloadType = HEVC_SEI_TYPE_TIME_CODE;
sei_data[sei_count].payload = (uint8_t*)tc_data;
sei_count ++;
}
}
nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data, sei_count);
} else {
pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
ctx->encoder_flushing = 1;
}
res = nvenc_push_context(avctx);
@@ -2161,7 +2240,9 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
return res;
nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
av_free(sei_data);
for ( i = 0; i < sei_count; i++)
av_freep(&sei_data[i].payload);
res = nvenc_pop_context(avctx);
if (res < 0)
@@ -2171,7 +2252,7 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
nv_status != NV_ENC_ERR_NEED_MORE_INPUT)
return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
if (frame) {
if (frame && frame->buf[0]) {
av_fifo_generic_write(ctx->output_surface_queue, &in_surf, sizeof(in_surf), NULL);
timestamp_queue_enqueue(ctx->timestamp_list, frame->pts);
}
@@ -2194,10 +2275,25 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
NvencContext *ctx = avctx->priv_data;
AVFrame *frame = ctx->frame;
if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder)
return AVERROR(EINVAL);
if (output_ready(avctx, ctx->encoder_flushing)) {
if (!frame->buf[0]) {
res = ff_encode_get_frame(avctx, frame);
if (res < 0 && res != AVERROR_EOF)
return res;
}
res = nvenc_send_frame(avctx, frame);
if (res < 0) {
if (res != AVERROR(EAGAIN))
return res;
} else
av_frame_unref(frame);
if (output_ready(avctx, avctx->internal->draining)) {
av_fifo_generic_read(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
res = nvenc_push_context(avctx);
@@ -2214,7 +2310,7 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
return res;
av_fifo_generic_write(ctx->unused_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
} else if (ctx->encoder_flushing) {
} else if (avctx->internal->draining) {
return AVERROR_EOF;
} else {
return AVERROR(EAGAIN);
@@ -2223,31 +2319,10 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
return 0;
}
int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *frame, int *got_packet)
{
NvencContext *ctx = avctx->priv_data;
int res;
if (!ctx->encoder_flushing) {
res = ff_nvenc_send_frame(avctx, frame);
if (res < 0)
return res;
}
res = ff_nvenc_receive_packet(avctx, pkt);
if (res == AVERROR(EAGAIN) || res == AVERROR_EOF) {
*got_packet = 0;
} else if (res < 0) {
return res;
} else {
*got_packet = 1;
}
return 0;
}
av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx)
{
ff_nvenc_send_frame(avctx, NULL);
NvencContext *ctx = avctx->priv_data;
nvenc_send_frame(avctx, NULL);
av_fifo_reset(ctx->timestamp_list);
}
+23 -7
View File
@@ -62,6 +62,14 @@ typedef void ID3D11Device;
#define NVENC_HAVE_GETLASTERRORSTRING
#endif
// SDK 10.0 compile time feature checks
#if NVENCAPI_CHECK_VERSION(10, 0)
#define NVENC_HAVE_NEW_PRESETS
#define NVENC_HAVE_MULTIPASS
#define NVENC_HAVE_LDKFS
#define NVENC_HAVE_H264_LVL6
#endif
typedef struct NvencSurface
{
NV_ENC_INPUT_PTR input_surface;
@@ -98,6 +106,15 @@ enum {
PRESET_LOW_LATENCY_HP,
PRESET_LOSSLESS_DEFAULT, // lossless presets must be the last ones
PRESET_LOSSLESS_HP,
#ifdef NVENC_HAVE_NEW_PRESETS
PRESET_P1,
PRESET_P2,
PRESET_P3,
PRESET_P4,
PRESET_P5,
PRESET_P6,
PRESET_P7,
#endif
};
enum {
@@ -138,6 +155,8 @@ typedef struct NvencContext
CUstream cu_stream;
ID3D11Device *d3d11_device;
AVFrame *frame;
int nb_surfaces;
NvencSurface *surfaces;
@@ -146,8 +165,6 @@ typedef struct NvencContext
AVFifoBuffer *output_surface_ready_queue;
AVFifoBuffer *timestamp_list;
int encoder_flushing;
struct {
void *ptr;
int ptr_index;
@@ -196,20 +213,19 @@ typedef struct NvencContext
int coder;
int b_ref_mode;
int a53_cc;
int s12m_tc;
int dpb_size;
int tuning_info;
int multipass;
int ldkfs;
} NvencContext;
int ff_nvenc_encode_init(AVCodecContext *avctx);
int ff_nvenc_encode_close(AVCodecContext *avctx);
int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame);
int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *frame, int *got_packet);
void ff_nvenc_encode_flush(AVCodecContext *avctx);
extern const enum AVPixelFormat ff_nvenc_pix_fmts[];
+41 -7
View File
@@ -26,7 +26,11 @@
#define OFFSET(x) offsetof(NvencContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
#ifdef NVENC_HAVE_NEW_PRESETS
{ "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_P4 }, PRESET_DEFAULT, PRESET_P7, VE, "preset" },
#else
{ "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" },
#endif
{ "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_DEFAULT }, 0, 0, VE, "preset" },
{ "slow", "hq 2 passes", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_SLOW }, 0, 0, VE, "preset" },
{ "medium", "hq 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_MEDIUM }, 0, 0, VE, "preset" },
@@ -39,12 +43,30 @@ static const AVOption options[] = {
{ "llhp", "low latency hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HP }, 0, 0, VE, "preset" },
{ "lossless", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_DEFAULT }, 0, 0, VE, "preset" },
{ "losslesshp", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_HP }, 0, 0, VE, "preset" },
#ifdef NVENC_HAVE_NEW_PRESETS
{ "p1", "fastest (lowest quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P1 }, 0, 0, VE, "preset" },
{ "p2", "faster (lower quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P2 }, 0, 0, VE, "preset" },
{ "p3", "fast (low quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P3 }, 0, 0, VE, "preset" },
{ "p4", "medium (default)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P4 }, 0, 0, VE, "preset" },
{ "p5", "slow (good quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P5 }, 0, 0, VE, "preset" },
{ "p6", "slower (better quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P6 }, 0, 0, VE, "preset" },
{ "p7", "slowest (best quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P7 }, 0, 0, VE, "preset" },
{ "tune", "Set the encoding tuning info", OFFSET(tuning_info), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, NV_ENC_TUNING_INFO_HIGH_QUALITY, NV_ENC_TUNING_INFO_LOSSLESS, VE, "tune" },
{ "hq", "High quality", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, 0, 0, VE, "tune" },
{ "ll", "Low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOW_LATENCY }, 0, 0, VE, "tune" },
{ "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, "tune" },
{ "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, "tune" },
#endif
{ "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_H264_PROFILE_MAIN }, NV_ENC_H264_PROFILE_BASELINE, NV_ENC_H264_PROFILE_HIGH_444P, VE, "profile" },
{ "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_BASELINE }, 0, 0, VE, "profile" },
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_MAIN }, 0, 0, VE, "profile" },
{ "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_HIGH }, 0, 0, VE, "profile" },
{ "high444p", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_HIGH_444P }, 0, 0, VE, "profile" },
{ "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_H264_51, VE, "level" },
#ifdef NVENC_HAVE_H264_LVL6
{ "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_H264_62, VE, "level" },
#else
{ "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_H264_52, VE, "level" },
#endif
{ "auto", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, 0, 0, VE, "level" },
{ "1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_1 }, 0, 0, VE, "level" },
{ "1.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_1 }, 0, 0, VE, "level" },
@@ -68,6 +90,12 @@ static const AVOption options[] = {
{ "5", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_5 }, 0, 0, VE, "level" },
{ "5.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_5 }, 0, 0, VE, "level" },
{ "5.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_51 }, 0, 0, VE, "level" },
{ "5.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_52 }, 0, 0, VE, "level" },
#ifdef NVENC_HAVE_H264_LVL6
{ "6.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_60 }, 0, 0, VE, "level" },
{ "6.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_61 }, 0, 0, VE, "level" },
{ "6.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_62 }, 0, 0, VE, "level" },
#endif
{ "rc", "Override the preset rate-control", OFFSET(rc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "rc" },
{ "constqp", "Constant QP mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CONSTQP }, 0, 0, VE, "rc" },
{ "vbr", "Variable bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_VBR }, 0, 0, VE, "rc" },
@@ -142,6 +170,18 @@ static const AVOption options[] = {
{ "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
{ "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)",
OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
#ifdef NVENC_HAVE_MULTIPASS
{ "multipass", "Set the multipass encoding", OFFSET(multipass), AV_OPT_TYPE_INT, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, NV_ENC_MULTI_PASS_DISABLED, NV_ENC_TWO_PASS_FULL_RESOLUTION, VE, "multipass" },
{ "disabled", "Single Pass", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, 0, 0, VE, "multipass" },
{ "qres", "Two Pass encoding is enabled where first Pass is quarter resolution",
0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_QUARTER_RESOLUTION }, 0, 0, VE, "multipass" },
{ "fullres", "Two Pass encoding is enabled where first Pass is full resolution",
0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_FULL_RESOLUTION }, 0, 0, VE, "multipass" },
#endif
#ifdef NVENC_HAVE_LDKFS
{ "ldkfs", "Low delay key frame scale; Specifies the Scene Change frame size increase allowed in case of single frame VBV and CBR",
OFFSET(ldkfs), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UCHAR_MAX, VE },
#endif
{ NULL }
};
@@ -180,9 +220,7 @@ AVCodec ff_nvenc_encoder = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.init = nvenc_old_init,
.send_frame = ff_nvenc_send_frame,
.receive_packet = ff_nvenc_receive_packet,
.encode2 = ff_nvenc_encode_frame,
.close = ff_nvenc_encode_close,
.flush = ff_nvenc_encode_flush,
.priv_data_size = sizeof(NvencContext),
@@ -212,9 +250,7 @@ AVCodec ff_nvenc_h264_encoder = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.init = nvenc_old_init,
.send_frame = ff_nvenc_send_frame,
.receive_packet = ff_nvenc_receive_packet,
.encode2 = ff_nvenc_encode_frame,
.close = ff_nvenc_encode_close,
.flush = ff_nvenc_encode_flush,
.priv_data_size = sizeof(NvencContext),
@@ -244,9 +280,7 @@ AVCodec ff_h264_nvenc_encoder = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.init = ff_nvenc_encode_init,
.send_frame = ff_nvenc_send_frame,
.receive_packet = ff_nvenc_receive_packet,
.encode2 = ff_nvenc_encode_frame,
.close = ff_nvenc_encode_close,
.flush = ff_nvenc_encode_flush,
.priv_data_size = sizeof(NvencContext),
+32 -4
View File
@@ -26,7 +26,11 @@
#define OFFSET(x) offsetof(NvencContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
#ifdef NVENC_HAVE_NEW_PRESETS
{ "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_P4 }, PRESET_DEFAULT, PRESET_P7, VE, "preset" },
#else
{ "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" },
#endif
{ "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_DEFAULT }, 0, 0, VE, "preset" },
{ "slow", "hq 2 passes", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_SLOW }, 0, 0, VE, "preset" },
{ "medium", "hq 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_MEDIUM }, 0, 0, VE, "preset" },
@@ -39,6 +43,20 @@ static const AVOption options[] = {
{ "llhp", "low latency hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HP }, 0, 0, VE, "preset" },
{ "lossless", "lossless", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_DEFAULT }, 0, 0, VE, "preset" },
{ "losslesshp", "lossless hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_HP }, 0, 0, VE, "preset" },
#ifdef NVENC_HAVE_NEW_PRESETS
{ "p1", "fastest (lowest quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P1 }, 0, 0, VE, "preset" },
{ "p2", "faster (lower quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P2 }, 0, 0, VE, "preset" },
{ "p3", "fast (low quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P3 }, 0, 0, VE, "preset" },
{ "p4", "medium (default)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P4 }, 0, 0, VE, "preset" },
{ "p5", "slow (good quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P5 }, 0, 0, VE, "preset" },
{ "p6", "slower (better quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P6 }, 0, 0, VE, "preset" },
{ "p7", "slowest (best quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P7 }, 0, 0, VE, "preset" },
{ "tune", "Set the encoding tuning info", OFFSET(tuning_info), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, NV_ENC_TUNING_INFO_HIGH_QUALITY, NV_ENC_TUNING_INFO_LOSSLESS, VE, "tune" },
{ "hq", "High quality", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, 0, 0, VE, "tune" },
{ "ll", "Low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOW_LATENCY }, 0, 0, VE, "tune" },
{ "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, "tune" },
{ "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, "tune" },
#endif
{ "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, NV_ENC_HEVC_PROFILE_MAIN, FF_PROFILE_HEVC_REXT, VE, "profile" },
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" },
{ "main10", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN_10 }, 0, 0, VE, "profile" },
@@ -129,8 +147,22 @@ static const AVOption options[] = {
{ "each", "", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "b_ref_mode" },
{ "middle", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, "b_ref_mode" },
#endif
{ "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
{ "s12m_tc", "Use timecode (if available)", OFFSET(s12m_tc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
{ "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)",
OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
#ifdef NVENC_HAVE_MULTIPASS
{ "multipass", "Set the multipass encoding", OFFSET(multipass), AV_OPT_TYPE_INT, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, NV_ENC_MULTI_PASS_DISABLED, NV_ENC_TWO_PASS_FULL_RESOLUTION, VE, "multipass" },
{ "disabled", "Single Pass", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, 0, 0, VE, "multipass" },
{ "qres", "Two Pass encoding is enabled where first Pass is quarter resolution",
0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_QUARTER_RESOLUTION }, 0, 0, VE, "multipass" },
{ "fullres", "Two Pass encoding is enabled where first Pass is full resolution",
0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_FULL_RESOLUTION }, 0, 0, VE, "multipass" },
#endif
#ifdef NVENC_HAVE_LDKFS
{ "ldkfs", "Low delay key frame scale; Specifies the Scene Change frame size increase allowed in case of single frame VBV and CBR",
OFFSET(ldkfs), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UCHAR_MAX, VE },
#endif
{ NULL }
};
@@ -168,9 +200,7 @@ AVCodec ff_nvenc_hevc_encoder = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_HEVC,
.init = nvenc_old_init,
.send_frame = ff_nvenc_send_frame,
.receive_packet = ff_nvenc_receive_packet,
.encode2 = ff_nvenc_encode_frame,
.close = ff_nvenc_encode_close,
.priv_data_size = sizeof(NvencContext),
.priv_class = &nvenc_hevc_class,
@@ -198,9 +228,7 @@ AVCodec ff_hevc_nvenc_encoder = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_HEVC,
.init = ff_nvenc_encode_init,
.send_frame = ff_nvenc_send_frame,
.receive_packet = ff_nvenc_receive_packet,
.encode2 = ff_nvenc_encode_frame,
.close = ff_nvenc_encode_close,
.flush = ff_nvenc_encode_flush,
.priv_data_size = sizeof(NvencContext),
+15
View File
@@ -53,6 +53,7 @@ static void *codec_child_next(void *obj, void *prev)
return NULL;
}
#if FF_API_CHILD_CLASS_NEXT
static const AVClass *codec_child_class_next(const AVClass *prev)
{
void *iter = NULL;
@@ -69,6 +70,17 @@ static const AVClass *codec_child_class_next(const AVClass *prev)
return c->priv_class;
return NULL;
}
#endif
static const AVClass *codec_child_class_iterate(void **iter)
{
const AVCodec *c;
/* find next codec with priv options */
while (c = av_codec_iterate(iter))
if (c->priv_class)
return c->priv_class;
return NULL;
}
static AVClassCategory get_category(void *ptr)
{
@@ -84,7 +96,10 @@ static const AVClass av_codec_context_class = {
.version = LIBAVUTIL_VERSION_INT,
.log_level_offset_offset = offsetof(AVCodecContext, log_level_offset),
.child_next = codec_child_next,
#if FF_API_CHILD_CLASS_NEXT
.child_class_next = codec_child_class_next,
#endif
.child_class_iterate = codec_child_class_iterate,
.category = AV_CLASS_CATEGORY_ENCODER,
.get_category = get_category,
};
+2 -1
View File
@@ -580,7 +580,8 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
*
* @param pkt packet
* @param type desired side information type
* @param size pointer for side information size to store (optional)
* @param size If supplied, *size will be set to the size of the side data
* or to zero if the desired side data is not present.
* @return pointer to data if present or NULL otherwise
*/
uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type,
+168
View File
@@ -0,0 +1,168 @@
/*
* PGX image format
* Copyright (c) 2020 Gautam Ramakrishnan
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avcodec.h"
#include "internal.h"
#include "bytestream.h"
#include "libavutil/imgutils.h"
static int pgx_get_number(AVCodecContext *avctx, GetByteContext *g, int *number) {
int ret = AVERROR_INVALIDDATA;
char digit;
*number = 0;
while (1) {
uint64_t temp;
if (!bytestream2_get_bytes_left(g))
return AVERROR_INVALIDDATA;
digit = bytestream2_get_byte(g);
if (digit == ' ' || digit == 0xA || digit == 0xD)
break;
else if (digit < '0' || digit > '9')
return AVERROR_INVALIDDATA;
temp = (uint64_t)10 * (*number) + (digit - '0');
if (temp > INT_MAX)
return AVERROR_INVALIDDATA;
*number = temp;
ret = 0;
}
return ret;
}
static int pgx_decode_header(AVCodecContext *avctx, GetByteContext *g,
int *depth, int *width, int *height,
int *sign)
{
int byte;
if (bytestream2_get_bytes_left(g) < 6) {
return AVERROR_INVALIDDATA;
}
bytestream2_skip(g, 6);
// Is the component signed?
byte = bytestream2_peek_byte(g);
if (byte == '+') {
*sign = 0;
bytestream2_skip(g, 1);
} else if (byte == '-') {
*sign = 1;
bytestream2_skip(g, 1);
} else if (byte == 0)
goto error;
byte = bytestream2_peek_byte(g);
if (byte == ' ')
bytestream2_skip(g, 1);
else if (byte == 0)
goto error;
if (pgx_get_number(avctx, g, depth))
goto error;
if (pgx_get_number(avctx, g, width))
goto error;
if (pgx_get_number(avctx, g, height))
goto error;
if (bytestream2_peek_byte(g) == 0xA)
bytestream2_skip(g, 1);
return 0;
error:
av_log(avctx, AV_LOG_ERROR, "Error in decoding header.\n");
return AVERROR_INVALIDDATA;
}
#define WRITE_FRAME(D, PIXEL, suffix) \
static inline void write_frame_ ##D(AVPacket *avpkt, AVFrame *frame, GetByteContext *g, \
int width, int height, int sign, int depth) \
{ \
int i, j; \
for (i = 0; i < height; i++) { \
PIXEL *line = (PIXEL*)frame->data[0] + i*frame->linesize[0]/sizeof(PIXEL); \
for (j = 0; j < width; j++) { \
int val; \
if (sign) \
val = (PIXEL)bytestream2_get_ ##suffix(g) + (1 << (depth - 1)); \
else \
val = bytestream2_get_ ##suffix(g); \
val <<= (D - depth); \
*(line + j) = val; \
} \
} \
} \
WRITE_FRAME(8, int8_t, byte)
WRITE_FRAME(16, int16_t, be16)
static int pgx_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame, AVPacket *avpkt)
{
AVFrame *p = data;
int ret;
int bpp;
int width, height, depth;
int sign = 0;
GetByteContext g;
bytestream2_init(&g, avpkt->data, avpkt->size);
if ((ret = pgx_decode_header(avctx, &g, &depth, &width, &height, &sign)) < 0)
return ret;
if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
return ret;
if (depth <= 8) {
avctx->pix_fmt = AV_PIX_FMT_GRAY8;
bpp = 8;
} else if (depth <= 16) {
avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
bpp = 16;
} else {
av_log(avctx, AV_LOG_ERROR, "Maximum depth of 16 bits supported.\n");
return AVERROR_PATCHWELCOME;
}
if (bytestream2_get_bytes_left(&g) < width * height * (bpp >> 3))
return AVERROR_INVALIDDATA;
if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
return ret;
p->pict_type = AV_PICTURE_TYPE_I;
p->key_frame = 1;
avctx->bits_per_raw_sample = depth;
if (bpp == 8)
write_frame_8(avpkt, p, &g, width, height, sign, depth);
else if (bpp == 16)
write_frame_16(avpkt, p, &g, width, height, sign, depth);
*got_frame = 1;
return 0;
}
AVCodec ff_pgx_decoder = {
.name = "pgx",
.long_name = NULL_IF_CONFIG_SMALL("PGX (JPEG2000 Test Format)"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_PGX,
.decode = pgx_decode_frame,
.capabilities = AV_CODEC_CAP_DR1,
};
+5
View File
@@ -51,6 +51,11 @@
FF_AVCTX_PROFILE_OPTION("main", NULL, VIDEO, FF_PROFILE_MPEG2_MAIN)\
FF_AVCTX_PROFILE_OPTION("simple", NULL, VIDEO, FF_PROFILE_MPEG2_SIMPLE)\
#define FF_AV1_PROFILE_OPTS \
FF_AVCTX_PROFILE_OPTION("main", NULL, VIDEO, FF_PROFILE_AV1_MAIN)\
FF_AVCTX_PROFILE_OPTION("high", NULL, VIDEO, FF_PROFILE_AV1_HIGH)\
FF_AVCTX_PROFILE_OPTION("professional", NULL, VIDEO, FF_PROFILE_AV1_PROFESSIONAL)\
extern const AVProfile ff_aac_profiles[];
extern const AVProfile ff_dca_profiles[];
extern const AVProfile ff_dnxhd_profiles[];
+1 -1
View File
@@ -246,7 +246,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src,
{
int err = 0;
if (dst != src && (for_user || !(src->codec_descriptor->props & AV_CODEC_PROP_INTRA_ONLY))) {
if (dst != src && (for_user || src->codec->update_thread_context)) {
dst->time_base = src->time_base;
dst->framerate = src->framerate;
dst->width = src->width;
+2
View File
@@ -21,6 +21,8 @@
#ifndef AVCODEC_QSV_INTERNAL_H
#define AVCODEC_QSV_INTERNAL_H
#include "config.h"
#if CONFIG_VAAPI
#define AVCODEC_QSV_LINUX_SESSION_HANDLE
#endif //CONFIG_VAAPI
+5 -6
View File
@@ -735,6 +735,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (q->adaptive_b >= 0)
q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
#endif
}
if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC) {
if (q->extbrc >= 0)
q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
#if QSV_VERSION_ATLEAST(1, 9)
if (avctx->qmin >= 0 && avctx->qmax >= 0 && avctx->qmin > avctx->qmax) {
@@ -750,12 +755,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
q->extco2.MaxQPP = q->extco2.MaxQPB = q->extco2.MaxQPI;
}
#endif
}
if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC) {
if (q->extbrc >= 0)
q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
q->extco2.Header.BufferSz = sizeof(q->extco2);
+2
View File
@@ -263,6 +263,8 @@ static const AVCodecDefault qsv_enc_defaults[] = {
// same as the x264 default
{ "g", "248" },
{ "bf", "8" },
{ "qmin", "-1" },
{ "qmax", "-1" },
{ "trellis", "-1" },
{ "flags", "+cgop" },
#if FF_API_PRIVATE_OPT
+2
View File
@@ -801,6 +801,7 @@ AVCodec ff_rv10_decoder = {
.close = rv10_decode_end,
.decode = rv10_decode_frame,
.capabilities = AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
@@ -818,6 +819,7 @@ AVCodec ff_rv20_decoder = {
.close = rv10_decode_end,
.decode = rv10_decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.flush = ff_mpeg_flush,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
+1 -2
View File
@@ -600,13 +600,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
/* decode huffman trees from extradata */
if(avctx->extradata_size < 16){
av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n");
decode_end(avctx);
return AVERROR(EINVAL);
}
ret = decode_header_trees(c);
if (ret < 0) {
decode_end(avctx);
return ret;
}
@@ -840,6 +838,7 @@ AVCodec ff_smacker_decoder = {
.close = decode_end,
.decode = decode_frame,
.capabilities = AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
AVCodec ff_smackaud_decoder = {
+2 -4
View File
@@ -79,14 +79,12 @@ static av_cold int smvjpeg_decode_end(AVCodecContext *avctx)
{
SMVJpegDecodeContext *s = avctx->priv_data;
MJpegDecodeContext *jpg = &s->jpg;
int ret;
jpg->picture_ptr = NULL;
av_frame_free(&s->picture[0]);
av_frame_free(&s->picture[1]);
ret = avcodec_close(s->avctx);
av_freep(&s->avctx);
return ret;
avcodec_free_context(&s->avctx);
return 0;
}
static av_cold int smvjpeg_decode_init(AVCodecContext *avctx)
+12 -14
View File
@@ -487,28 +487,27 @@ av_cold int ff_snow_common_init(AVCodecContext *avctx){
width= s->avctx->width;
height= s->avctx->height;
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->spatial_idwt_buffer, width, height * sizeof(IDWTELEM), fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->spatial_dwt_buffer, width, height * sizeof(DWTELEM), fail); //FIXME this does not belong here
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->temp_dwt_buffer, width, sizeof(DWTELEM), fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->temp_idwt_buffer, width, sizeof(IDWTELEM), fail);
FF_ALLOC_ARRAY_OR_GOTO(avctx, s->run_buffer, ((width + 1) >> 1), ((height + 1) >> 1) * sizeof(*s->run_buffer), fail);
if (!FF_ALLOCZ_TYPED_ARRAY(s->spatial_idwt_buffer, width * height) ||
!FF_ALLOCZ_TYPED_ARRAY(s->spatial_dwt_buffer, width * height) || //FIXME this does not belong here
!FF_ALLOCZ_TYPED_ARRAY(s->temp_dwt_buffer, width) ||
!FF_ALLOCZ_TYPED_ARRAY(s->temp_idwt_buffer, width) ||
!FF_ALLOCZ_TYPED_ARRAY(s->run_buffer, ((width + 1) >> 1) * ((height + 1) >> 1)))
return AVERROR(ENOMEM);
for(i=0; i<MAX_REF_FRAMES; i++) {
for(j=0; j<MAX_REF_FRAMES; j++)
ff_scale_mv_ref[i][j] = 256*(i+1)/(j+1);
s->last_picture[i] = av_frame_alloc();
if (!s->last_picture[i])
goto fail;
return AVERROR(ENOMEM);
}
s->mconly_picture = av_frame_alloc();
s->current_picture = av_frame_alloc();
if (!s->mconly_picture || !s->current_picture)
goto fail;
return AVERROR(ENOMEM);
return 0;
fail:
return AVERROR(ENOMEM);
}
int ff_snow_common_init_after_header(AVCodecContext *avctx) {
@@ -520,9 +519,10 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) {
if ((ret = ff_get_buffer(s->avctx, s->mconly_picture,
AV_GET_BUFFER_FLAG_REF)) < 0)
return ret;
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->scratchbuf, FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256), 7*MB_SIZE, fail);
emu_buf_size = FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256) * (2 * MB_SIZE + HTAPS_MAX - 1);
FF_ALLOC_OR_GOTO(avctx, s->emu_edge_buffer, emu_buf_size, fail);
if (!FF_ALLOCZ_TYPED_ARRAY(s->scratchbuf, FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256) * 7 * MB_SIZE) ||
!FF_ALLOCZ_TYPED_ARRAY(s->emu_edge_buffer, emu_buf_size))
return AVERROR(ENOMEM);
}
if(s->mconly_picture->format != avctx->pix_fmt) {
@@ -571,7 +571,7 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) {
av_freep(&b->x_coeff);
b->x_coeff=av_mallocz_array(((b->width+1) * b->height+1), sizeof(x_and_coeff));
if (!b->x_coeff)
goto fail;
return AVERROR(ENOMEM);
}
w= (w+1)>>1;
h= (h+1)>>1;
@@ -579,8 +579,6 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) {
}
return 0;
fail:
return AVERROR(ENOMEM);
}
#define USE_HALFPEL_PLANE 0
+3 -3
View File
@@ -458,8 +458,8 @@ static void predictor_init_state(int *k, int *state, int order)
for (j = 0, p = i+1; p < order; j++,p++)
{
int tmp = x + shift_down(k[j] * state[p], LATTICE_SHIFT);
state[p] += shift_down(k[j]*x, LATTICE_SHIFT);
int tmp = x + shift_down(k[j] * (unsigned)state[p], LATTICE_SHIFT);
state[p] += shift_down(k[j]* (unsigned)x, LATTICE_SHIFT);
x = tmp;
}
}
@@ -467,7 +467,7 @@ static void predictor_init_state(int *k, int *state, int order)
static int predictor_calc_error(int *k, int *state, int order, int error)
{
int i, x = error - shift_down(k[order-1] * state[order-1], LATTICE_SHIFT);
int i, x = error - shift_down(k[order-1] * (unsigned)state[order-1], LATTICE_SHIFT);
#if 1
int *k_ptr = &(k[order-2]),
+1 -1
View File
@@ -447,7 +447,7 @@ static int speedhq_decode_frame(AVCodecContext *avctx,
}
frame->key_frame = 1;
if (second_field_offset == 4) {
if (second_field_offset == 4 || second_field_offset == (buf_size-4)) {
/*
* Overlapping first and second fields is used to signal
* encoding only a single field. In this case, "height"
+1 -3
View File
@@ -529,7 +529,6 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
s->current_picture = av_frame_alloc();
s->last_picture = av_frame_alloc();
if (!s->current_picture || !s->last_picture) {
svq1_encode_end(avctx);
return AVERROR(ENOMEM);
}
@@ -546,7 +545,6 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
s->m.avctx = avctx;
if ((ret = ff_mpv_common_init(&s->m)) < 0) {
svq1_encode_end(avctx);
return ret;
}
@@ -564,7 +562,6 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
if (!s->m.me.temp || !s->m.me.scratchpad || !s->m.me.map ||
!s->m.me.score_map || !s->mb_type || !s->dummy) {
svq1_encode_end(avctx);
return AVERROR(ENOMEM);
}
@@ -692,6 +689,7 @@ AVCodec ff_svq1_encoder = {
.init = svq1_encode_init,
.encode2 = svq1_encode_frame,
.close = svq1_encode_end,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
AV_PIX_FMT_NONE },
};
-1
View File
@@ -167,7 +167,6 @@ static void test_copy(const AVCodec *c1, const AVCodec *c2)
avcodec_copy_context(ctx2, ctx1);
test_copy_print_codec(ctx1);
test_copy_print_codec(ctx2);
avcodec_close(ctx1);
}
avcodec_free_context(&ctx1);
avcodec_free_context(&ctx2);

Some files were not shown because too many files have changed in this diff Show More