#include "libavutil/md5.h"
#include "libavutil/opt.h"
#include "avcodec.h"
-#include "dsputil.h"
+#include "bswapdsp.h"
#include "get_bits.h"
#include "golomb.h"
#include "internal.h"
enum CodingMode coding_mode;
int porder;
int params[MAX_PARTITIONS];
+ uint32_t udata[FLAC_MAX_BLOCKSIZE];
} RiceContext;
typedef struct FlacSubframe {
struct AVMD5 *md5ctx;
uint8_t *md5_buffer;
unsigned int md5_buffer_size;
- DSPContext dsp;
+ BswapDSPContext bdsp;
FLACDSPContext flac_dsp;
+
+ int flushed;
+ int64_t next_pts;
} FlacEncodeContext;
FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON,
FF_LPC_TYPE_LEVINSON})[level];
- s->options.min_prediction_order = ((int[]){ 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})[level];
- s->options.max_prediction_order = ((int[]){ 3, 4, 4, 6, 8, 8, 8, 8, 12, 12, 12, 32, 32})[level];
+ if (s->options.min_prediction_order < 0)
+ s->options.min_prediction_order = ((int[]){ 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})[level];
+ if (s->options.max_prediction_order < 0)
+ s->options.max_prediction_order = ((int[]){ 3, 4, 4, 6, 8, 8, 8, 8, 12, 12, 12, 32, 32})[level];
if (s->options.prediction_order_method < 0)
s->options.prediction_order_method = ((int[]){ ORDER_METHOD_EST, ORDER_METHOD_EST, ORDER_METHOD_EST,
if (s->options.max_partition_order < 0)
s->options.max_partition_order = ((int[]){ 2, 2, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 8})[level];
- if (s->options.lpc_type == FF_LPC_TYPE_NONE) {
- s->options.min_prediction_order = 0;
- } else if (avctx->min_prediction_order >= 0) {
+#if FF_API_PRIVATE_OPT
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->min_prediction_order >= 0) {
if (s->options.lpc_type == FF_LPC_TYPE_FIXED) {
if (avctx->min_prediction_order > MAX_FIXED_ORDER) {
- av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",
- avctx->min_prediction_order);
- return -1;
+ av_log(avctx, AV_LOG_WARNING,
+ "invalid min prediction order %d, clamped to %d\n",
+ avctx->min_prediction_order, MAX_FIXED_ORDER);
+ avctx->min_prediction_order = MAX_FIXED_ORDER;
}
} else if (avctx->min_prediction_order < MIN_LPC_ORDER ||
avctx->min_prediction_order > MAX_LPC_ORDER) {
}
s->options.min_prediction_order = avctx->min_prediction_order;
}
- if (s->options.lpc_type == FF_LPC_TYPE_NONE) {
- s->options.max_prediction_order = 0;
- } else if (avctx->max_prediction_order >= 0) {
+ if (avctx->max_prediction_order >= 0) {
if (s->options.lpc_type == FF_LPC_TYPE_FIXED) {
if (avctx->max_prediction_order > MAX_FIXED_ORDER) {
- av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",
- avctx->max_prediction_order);
- return -1;
+ av_log(avctx, AV_LOG_WARNING,
+ "invalid max prediction order %d, clamped to %d\n",
+ avctx->max_prediction_order, MAX_FIXED_ORDER);
+ avctx->max_prediction_order = MAX_FIXED_ORDER;
}
} else if (avctx->max_prediction_order < MIN_LPC_ORDER ||
avctx->max_prediction_order > MAX_LPC_ORDER) {
}
s->options.max_prediction_order = avctx->max_prediction_order;
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if (s->options.lpc_type == FF_LPC_TYPE_NONE) {
+ s->options.min_prediction_order = 0;
+ s->options.max_prediction_order = 0;
+ } else if (s->options.lpc_type == FF_LPC_TYPE_FIXED) {
+ if (s->options.min_prediction_order > MAX_FIXED_ORDER) {
+ av_log(avctx, AV_LOG_WARNING,
+ "invalid min prediction order %d, clamped to %d\n",
+ s->options.min_prediction_order, MAX_FIXED_ORDER);
+ s->options.min_prediction_order = MAX_FIXED_ORDER;
+ }
+ if (s->options.max_prediction_order > MAX_FIXED_ORDER) {
+ av_log(avctx, AV_LOG_WARNING,
+ "invalid max prediction order %d, clamped to %d\n",
+ s->options.max_prediction_order, MAX_FIXED_ORDER);
+ s->options.max_prediction_order = MAX_FIXED_ORDER;
+ }
+ }
+
if (s->options.max_prediction_order < s->options.min_prediction_order) {
av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n",
s->options.min_prediction_order, s->options.max_prediction_order);
s->frame_count = 0;
s->min_framesize = s->max_framesize;
-#if FF_API_OLD_ENCODE_AUDIO
- avctx->coded_frame = avcodec_alloc_frame();
- if (!avctx->coded_frame)
- return AVERROR(ENOMEM);
-#endif
-
ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size,
s->options.max_prediction_order, FF_LPC_TYPE_LEVINSON);
- ff_dsputil_init(&s->dsp, avctx);
+ ff_bswapdsp_init(&s->bdsp);
ff_flacdsp_init(&s->flac_dsp, avctx->sample_fmt,
avctx->bits_per_raw_sample);
uint64_t bits[MAX_PARTITION_ORDER+1];
int opt_porder;
RiceContext tmp_rc;
- uint32_t *udata;
- uint64_t sums[MAX_PARTITION_ORDER+1][MAX_PARTITIONS];
+ uint64_t sums[MAX_PARTITION_ORDER + 1][MAX_PARTITIONS] = { { 0 } };
assert(pmin >= 0 && pmin <= MAX_PARTITION_ORDER);
assert(pmax >= 0 && pmax <= MAX_PARTITION_ORDER);
tmp_rc.coding_mode = rc->coding_mode;
- udata = av_malloc(n * sizeof(uint32_t));
for (i = 0; i < n; i++)
- udata[i] = (2*data[i]) ^ (data[i]>>31);
+ rc->udata[i] = (2 * data[i]) ^ (data[i] >> 31);
- calc_sums(pmin, pmax, udata, n, pred_order, sums);
+ calc_sums(pmin, pmax, rc->udata, n, pred_order, sums);
opt_porder = pmin;
bits[pmin] = UINT32_MAX;
}
}
- av_freep(&udata);
return bits[opt_porder];
}
if (s->avctx->bits_per_raw_sample <= 16) {
buf = (const uint8_t *)samples;
#if HAVE_BIGENDIAN
- s->dsp.bswap16_buf((uint16_t *)s->md5_buffer,
- (const uint16_t *)samples, buf_size / 2);
+ s->bdsp.bswap16_buf((uint16_t *) s->md5_buffer,
+ (const uint16_t *) samples, buf_size / 2);
buf = s->md5_buffer;
#endif
} else {
s->max_framesize = s->max_encoded_framesize;
av_md5_final(s->md5ctx, s->md5sum);
write_streaminfo(s, avctx->extradata);
+
+#if FF_API_SIDEDATA_ONLY_PKT
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->side_data_only_packets && !s->flushed) {
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ if (!s->flushed) {
+#endif
+ uint8_t *side_data = av_packet_new_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA,
+ avctx->extradata_size);
+ if (!side_data)
+ return AVERROR(ENOMEM);
+ memcpy(side_data, avctx->extradata, avctx->extradata_size);
+
+ avpkt->pts = s->next_pts;
+
+ *got_packet_ptr = 1;
+ s->flushed = 1;
+ }
+
return 0;
}
frame_bytes = encode_frame(s);
- /* fallback to verbatim mode if the compressed frame is larger than it
+ /* Fall back on verbatim mode if the compressed frame is larger than it
would be if encoded uncompressed. */
if (frame_bytes < 0 || frame_bytes > s->max_framesize) {
s->frame.verbatim_only = 1;
avpkt->pts = frame->pts;
avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
avpkt->size = out_bytes;
+
+ s->next_pts = avpkt->pts + avpkt->duration;
+
*got_packet_ptr = 1;
return 0;
}
}
av_freep(&avctx->extradata);
avctx->extradata_size = 0;
-#if FF_API_OLD_ENCODE_AUDIO
- av_freep(&avctx->coded_frame);
-#endif
return 0;
}
{ "fixed", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LPC_TYPE_FIXED }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
{ "levinson", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LPC_TYPE_LEVINSON }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
{ "cholesky", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LPC_TYPE_CHOLESKY }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
-{ "lpc_passes", "Number of passes to use for Cholesky factorization during LPC analysis", offsetof(FlacEncodeContext, options.lpc_passes), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, FLAGS },
+{ "lpc_passes", "Number of passes to use for Cholesky factorization during LPC analysis", offsetof(FlacEncodeContext, options.lpc_passes), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, FLAGS },
{ "min_partition_order", NULL, offsetof(FlacEncodeContext, options.min_partition_order), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, MAX_PARTITION_ORDER, FLAGS },
{ "max_partition_order", NULL, offsetof(FlacEncodeContext, options.max_partition_order), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, MAX_PARTITION_ORDER, FLAGS },
{ "prediction_order_method", "Search method for selecting prediction order", offsetof(FlacEncodeContext, options.prediction_order_method), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, ORDER_METHOD_LOG, FLAGS, "predm" },
{ "left_side", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FLAC_CHMODE_LEFT_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" },
{ "right_side", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FLAC_CHMODE_RIGHT_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" },
{ "mid_side", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FLAC_CHMODE_MID_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" },
+{ "min_prediction_order", NULL, offsetof(FlacEncodeContext, options.min_prediction_order), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, MAX_LPC_ORDER, FLAGS },
+{ "max_prediction_order", NULL, offsetof(FlacEncodeContext, options.max_prediction_order), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, MAX_LPC_ORDER, FLAGS },
+
{ NULL },
};
AVCodec ff_flac_encoder = {
.name = "flac",
+ .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
.type = AVMEDIA_TYPE_AUDIO,
.id = AV_CODEC_ID_FLAC,
.priv_data_size = sizeof(FlacEncodeContext),
.init = flac_encode_init,
.encode2 = flac_encode_frame,
.close = flac_encode_close,
- .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
+ .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_NONE },
- .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
.priv_class = &flac_encoder_class,
};