early-access version 1680
This commit is contained in:
Vendored
+2
-1
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Vendored
+8
-12
@@ -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 },
|
||||
|
||||
Vendored
+37
-56
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+12
-5
@@ -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
@@ -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[] = {
|
||||
|
||||
Vendored
+8
-9
@@ -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
@@ -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;
|
||||
|
||||
Vendored
+17
-26
@@ -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;
|
||||
|
||||
Vendored
-2
@@ -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
@@ -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
@@ -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),
|
||||
|
||||
Vendored
+3
-6
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Vendored
+3
@@ -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
@@ -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 */
|
||||
|
||||
Vendored
+19
-29
@@ -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;
|
||||
|
||||
|
||||
Vendored
+7
-14
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
};
|
||||
|
||||
Vendored
+21
-11
@@ -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;
|
||||
|
||||
Vendored
+3
-7
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
Vendored
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
};
|
||||
|
||||
Vendored
+327
-329
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
Vendored
+3
-2
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Vendored
+36
-22
@@ -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, \
|
||||
|
||||
Vendored
+12
-14
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Vendored
+136
-61
@@ -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);
|
||||
}
|
||||
|
||||
Vendored
+23
-7
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
};
|
||||
|
||||
Vendored
+2
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Vendored
+5
-6
@@ -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
@@ -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
|
||||
|
||||
Vendored
+2
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
Vendored
+12
-14
@@ -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
|
||||
|
||||
Vendored
+3
-3
@@ -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
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user