mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Add a quality factor packet side data
This is necessary to preserve the quality information currently exported with coded_frame. Add the new side data to every encoder that needs it, and use it in avconv. Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
This commit is contained in:
parent
d6604b29ef
commit
5d3addb937
13
avconv.c
13
avconv.c
@ -274,6 +274,11 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
|||||||
}
|
}
|
||||||
ost->frame_number++;
|
ost->frame_number++;
|
||||||
}
|
}
|
||||||
|
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||||
|
uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_FACTOR,
|
||||||
|
NULL);
|
||||||
|
ost->quality = sd ? *(int *)sd : -1;
|
||||||
|
}
|
||||||
|
|
||||||
while (bsfc) {
|
while (bsfc) {
|
||||||
AVPacket new_pkt = *pkt;
|
AVPacket new_pkt = *pkt;
|
||||||
@ -561,7 +566,8 @@ static void do_video_stats(OutputStream *ost, int frame_size)
|
|||||||
enc = ost->enc_ctx;
|
enc = ost->enc_ctx;
|
||||||
if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
|
if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||||
frame_number = ost->frame_number;
|
frame_number = ost->frame_number;
|
||||||
fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality / (float)FF_QP2LAMBDA);
|
fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number,
|
||||||
|
ost->quality / (float)FF_QP2LAMBDA);
|
||||||
if (enc->flags&CODEC_FLAG_PSNR)
|
if (enc->flags&CODEC_FLAG_PSNR)
|
||||||
fprintf(vstats_file, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0] / (enc->width * enc->height * 255.0 * 255.0)));
|
fprintf(vstats_file, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0] / (enc->width * enc->height * 255.0 * 255.0)));
|
||||||
|
|
||||||
@ -846,8 +852,9 @@ static void print_report(int is_last_report, int64_t timer_start)
|
|||||||
float q = -1;
|
float q = -1;
|
||||||
ost = output_streams[i];
|
ost = output_streams[i];
|
||||||
enc = ost->enc_ctx;
|
enc = ost->enc_ctx;
|
||||||
if (!ost->stream_copy && enc->coded_frame)
|
if (!ost->stream_copy)
|
||||||
q = enc->coded_frame->quality / (float)FF_QP2LAMBDA;
|
q = ost->quality / (float) FF_QP2LAMBDA;
|
||||||
|
|
||||||
if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
|
if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
|
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
|
||||||
}
|
}
|
||||||
|
3
avconv.h
3
avconv.h
@ -362,6 +362,9 @@ typedef struct OutputStream {
|
|||||||
// number of frames/samples sent to the encoder
|
// number of frames/samples sent to the encoder
|
||||||
uint64_t frames_encoded;
|
uint64_t frames_encoded;
|
||||||
uint64_t samples_encoded;
|
uint64_t samples_encoded;
|
||||||
|
|
||||||
|
/* packet quality factor */
|
||||||
|
int quality;
|
||||||
} OutputStream;
|
} OutputStream;
|
||||||
|
|
||||||
typedef struct OutputFile {
|
typedef struct OutputFile {
|
||||||
|
@ -13,6 +13,9 @@ libavutil: 2014-08-09
|
|||||||
|
|
||||||
API changes, most recent first:
|
API changes, most recent first:
|
||||||
|
|
||||||
|
2015-xx-xx - xxxxxxx - lavc 56.33.0 - avcodec.h
|
||||||
|
Add AV_PKT_DATA_QUALITY_FACTOR to export the quality value of an AVPacket.
|
||||||
|
|
||||||
2015-xx-xx - xxxxxxx - lavu 56.15.0
|
2015-xx-xx - xxxxxxx - lavu 56.15.0
|
||||||
Add av_version_info().
|
Add av_version_info().
|
||||||
|
|
||||||
|
@ -930,6 +930,13 @@ enum AVPacketSideDataType {
|
|||||||
* to enum AVAudioServiceType.
|
* to enum AVAudioServiceType.
|
||||||
*/
|
*/
|
||||||
AV_PKT_DATA_AUDIO_SERVICE_TYPE,
|
AV_PKT_DATA_AUDIO_SERVICE_TYPE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This side data contains an integer value representing the quality
|
||||||
|
* factor of the compressed frame. Allowed range is between 1 (good)
|
||||||
|
* and FF_LAMBDA_MAX (bad).
|
||||||
|
*/
|
||||||
|
AV_PKT_DATA_QUALITY_FACTOR,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct AVPacketSideData {
|
typedef struct AVPacketSideData {
|
||||||
|
@ -1036,7 +1036,7 @@ static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
DNXHDEncContext *ctx = avctx->priv_data;
|
DNXHDEncContext *ctx = avctx->priv_data;
|
||||||
int first_field = 1;
|
int first_field = 1;
|
||||||
int offset, i, ret;
|
int offset, i, ret;
|
||||||
uint8_t *buf;
|
uint8_t *buf, *sd;
|
||||||
|
|
||||||
if ((ret = ff_alloc_packet(pkt, ctx->cid_table->frame_size)) < 0) {
|
if ((ret = ff_alloc_packet(pkt, ctx->cid_table->frame_size)) < 0) {
|
||||||
av_log(avctx, AV_LOG_ERROR,
|
av_log(avctx, AV_LOG_ERROR,
|
||||||
@ -1092,6 +1092,11 @@ encode_coding_unit:
|
|||||||
|
|
||||||
avctx->coded_frame->quality = ctx->qscale * FF_QP2LAMBDA;
|
avctx->coded_frame->quality = ctx->qscale * FF_QP2LAMBDA;
|
||||||
|
|
||||||
|
sd = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_FACTOR, sizeof(int));
|
||||||
|
if (!sd)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
*(int *)sd = ctx->qscale * FF_QP2LAMBDA;
|
||||||
|
|
||||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||||
*got_packet = 1;
|
*got_packet = 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -268,8 +268,15 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkt->flags |= AV_PKT_FLAG_KEY*pic_out.b_keyframe;
|
pkt->flags |= AV_PKT_FLAG_KEY*pic_out.b_keyframe;
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
uint8_t *sd = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_FACTOR,
|
||||||
|
sizeof(int));
|
||||||
|
if (!sd)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
*(int *)sd = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
|
||||||
|
|
||||||
ctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
|
ctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
|
||||||
|
}
|
||||||
|
|
||||||
*got_packet = ret;
|
*got_packet = ret;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -119,6 +119,7 @@ static int XAVS_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
xavs_nal_t *nal;
|
xavs_nal_t *nal;
|
||||||
int nnal, i, ret;
|
int nnal, i, ret;
|
||||||
xavs_picture_t pic_out;
|
xavs_picture_t pic_out;
|
||||||
|
uint8_t *sd;
|
||||||
|
|
||||||
x4->pic.img.i_csp = XAVS_CSP_I420;
|
x4->pic.img.i_csp = XAVS_CSP_I420;
|
||||||
x4->pic.img.i_plane = 3;
|
x4->pic.img.i_plane = 3;
|
||||||
@ -193,6 +194,11 @@ static int XAVS_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
|
|
||||||
avctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
|
avctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
|
||||||
|
|
||||||
|
sd = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_FACTOR, sizeof(int));
|
||||||
|
if (!sd)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
*(int *)sd = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
|
||||||
|
|
||||||
x4->out_frame_count++;
|
x4->out_frame_count++;
|
||||||
*got_packet = ret;
|
*got_packet = ret;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -743,6 +743,12 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (xerr > 0) {
|
if (xerr > 0) {
|
||||||
|
uint8_t *sd = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_FACTOR,
|
||||||
|
sizeof(int));
|
||||||
|
if (!sd)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
*(int *)sd = xvid_enc_stats.quant * FF_QP2LAMBDA;
|
||||||
|
|
||||||
*got_packet = 1;
|
*got_packet = 1;
|
||||||
|
|
||||||
avctx->coded_frame->quality = xvid_enc_stats.quant * FF_QP2LAMBDA;
|
avctx->coded_frame->quality = xvid_enc_stats.quant * FF_QP2LAMBDA;
|
||||||
|
@ -1589,6 +1589,7 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
|
|
||||||
/* output? */
|
/* output? */
|
||||||
if (s->new_picture.f->data[0]) {
|
if (s->new_picture.f->data[0]) {
|
||||||
|
uint8_t *sd;
|
||||||
if (!pkt->data &&
|
if (!pkt->data &&
|
||||||
(ret = ff_alloc_packet(pkt, s->mb_width*s->mb_height*MAX_MB_BYTES)) < 0)
|
(ret = ff_alloc_packet(pkt, s->mb_width*s->mb_height*MAX_MB_BYTES)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -1630,6 +1631,12 @@ vbv_retry:
|
|||||||
|
|
||||||
frame_end(s);
|
frame_end(s);
|
||||||
|
|
||||||
|
sd = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_FACTOR,
|
||||||
|
sizeof(int));
|
||||||
|
if (!sd)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
*(int *)sd = s->current_picture.f->quality;
|
||||||
|
|
||||||
if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG)
|
if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG)
|
||||||
ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits);
|
ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits);
|
||||||
|
|
||||||
|
@ -569,6 +569,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
{
|
{
|
||||||
SVQ1EncContext *const s = avctx->priv_data;
|
SVQ1EncContext *const s = avctx->priv_data;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
uint8_t *sd;
|
||||||
|
|
||||||
if (!pkt->data &&
|
if (!pkt->data &&
|
||||||
(ret = av_new_packet(pkt, s->y_block_width * s->y_block_height *
|
(ret = av_new_packet(pkt, s->y_block_width * s->y_block_height *
|
||||||
@ -611,6 +612,11 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
avctx->coded_frame->pict_type = s->pict_type;
|
avctx->coded_frame->pict_type = s->pict_type;
|
||||||
avctx->coded_frame->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
|
avctx->coded_frame->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
|
||||||
|
|
||||||
|
sd = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_FACTOR, sizeof(int));
|
||||||
|
if (!sd)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
*(int *)sd = pict->quality;
|
||||||
|
|
||||||
svq1_write_header(s, s->pict_type);
|
svq1_write_header(s, s->pict_type);
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
if (svq1_encode_plane(s, i,
|
if (svq1_encode_plane(s, i,
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "libavutil/version.h"
|
#include "libavutil/version.h"
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MAJOR 56
|
#define LIBAVCODEC_VERSION_MAJOR 56
|
||||||
#define LIBAVCODEC_VERSION_MINOR 32
|
#define LIBAVCODEC_VERSION_MINOR 33
|
||||||
#define LIBAVCODEC_VERSION_MICRO 0
|
#define LIBAVCODEC_VERSION_MICRO 0
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
|
@ -359,6 +359,9 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
|
|||||||
av_log(ctx, AV_LOG_INFO, "audio service type: ");
|
av_log(ctx, AV_LOG_INFO, "audio service type: ");
|
||||||
dump_audioservicetype(ctx, &sd);
|
dump_audioservicetype(ctx, &sd);
|
||||||
break;
|
break;
|
||||||
|
case AV_PKT_DATA_QUALITY_FACTOR:
|
||||||
|
av_log(ctx, AV_LOG_INFO, "quality factor: %d", *(int *)sd.data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
av_log(ctx, AV_LOG_WARNING,
|
av_log(ctx, AV_LOG_WARNING,
|
||||||
"unknown side data type %d (%d bytes)", sd.type, sd.size);
|
"unknown side data type %d (%d bytes)", sd.type, sd.size);
|
||||||
|
Loading…
Reference in New Issue
Block a user