aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVittorio Giovara <vittorio.giovara@gmail.com>2015-07-15 18:41:21 +0100
committerVittorio Giovara <vittorio.giovara@gmail.com>2015-07-20 15:06:47 +0100
commit5d3addb937946eca5391e40b5e6308e74ac6f77b (patch)
treee758d6b07dd07480a3b32901ccedc421d45b33c0
parentd6604b29ef544793479d7fb4e05ef6622bb3e534 (diff)
downloadffmpeg-5d3addb937946eca5391e40b5e6308e74ac6f77b.tar.gz
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>
-rw-r--r--avconv.c13
-rw-r--r--avconv.h3
-rw-r--r--doc/APIchanges3
-rw-r--r--libavcodec/avcodec.h7
-rw-r--r--libavcodec/dnxhdenc.c7
-rw-r--r--libavcodec/libx264.c9
-rw-r--r--libavcodec/libxavs.c6
-rw-r--r--libavcodec/libxvid.c6
-rw-r--r--libavcodec/mpegvideo_enc.c7
-rw-r--r--libavcodec/svq1enc.c6
-rw-r--r--libavcodec/version.h2
-rw-r--r--libavformat/dump.c3
12 files changed, 66 insertions, 6 deletions
diff --git a/avconv.c b/avconv.c
index 291c4d4ce3..f083d6fb7c 100644
--- a/avconv.c
+++ b/avconv.c
@@ -274,6 +274,11 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
}
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) {
AVPacket new_pkt = *pkt;
@@ -561,7 +566,8 @@ static void do_video_stats(OutputStream *ost, int frame_size)
enc = ost->enc_ctx;
if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
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)
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;
ost = output_streams[i];
enc = ost->enc_ctx;
- if (!ost->stream_copy && enc->coded_frame)
- q = enc->coded_frame->quality / (float)FF_QP2LAMBDA;
+ if (!ost->stream_copy)
+ q = ost->quality / (float) FF_QP2LAMBDA;
+
if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
}
diff --git a/avconv.h b/avconv.h
index ec57fc8799..187dcdbd28 100644
--- a/avconv.h
+++ b/avconv.h
@@ -362,6 +362,9 @@ typedef struct OutputStream {
// number of frames/samples sent to the encoder
uint64_t frames_encoded;
uint64_t samples_encoded;
+
+ /* packet quality factor */
+ int quality;
} OutputStream;
typedef struct OutputFile {
diff --git a/doc/APIchanges b/doc/APIchanges
index 8d22556169..3303d5f2f7 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,9 @@ libavutil: 2014-08-09
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
Add av_version_info().
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index e8be1968c3..db077e9e67 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -930,6 +930,13 @@ enum AVPacketSideDataType {
* to enum AVAudioServiceType.
*/
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 {
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 5c45fe0b3a..bccf5c8a48 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -1036,7 +1036,7 @@ static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
DNXHDEncContext *ctx = avctx->priv_data;
int first_field = 1;
int offset, i, ret;
- uint8_t *buf;
+ uint8_t *buf, *sd;
if ((ret = ff_alloc_packet(pkt, ctx->cid_table->frame_size)) < 0) {
av_log(avctx, AV_LOG_ERROR,
@@ -1092,6 +1092,11 @@ encode_coding_unit:
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;
*got_packet = 1;
return 0;
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index ace750cc54..a3ffe228c1 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -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;
- 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;
+ }
*got_packet = ret;
return 0;
diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c
index 9b80243612..0cabe63f7f 100644
--- a/libavcodec/libxavs.c
+++ b/libavcodec/libxavs.c
@@ -119,6 +119,7 @@ static int XAVS_frame(AVCodecContext *avctx, AVPacket *pkt,
xavs_nal_t *nal;
int nnal, i, ret;
xavs_picture_t pic_out;
+ uint8_t *sd;
x4->pic.img.i_csp = XAVS_CSP_I420;
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;
+ 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++;
*got_packet = ret;
return 0;
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c
index 5282ea7a19..b440ac2d92 100644
--- a/libavcodec/libxvid.c
+++ b/libavcodec/libxvid.c
@@ -743,6 +743,12 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
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;
avctx->coded_frame->quality = xvid_enc_stats.quant * FF_QP2LAMBDA;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 84e9dc8c58..ceced188a9 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1589,6 +1589,7 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
/* output? */
if (s->new_picture.f->data[0]) {
+ uint8_t *sd;
if (!pkt->data &&
(ret = ff_alloc_packet(pkt, s->mb_width*s->mb_height*MAX_MB_BYTES)) < 0)
return ret;
@@ -1630,6 +1631,12 @@ vbv_retry:
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)
ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits);
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 82e2f74bc4..ebbc54e589 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -569,6 +569,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
{
SVQ1EncContext *const s = avctx->priv_data;
int i, ret;
+ uint8_t *sd;
if (!pkt->data &&
(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->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);
for (i = 0; i < 3; i++)
if (svq1_encode_plane(s, i,
diff --git a/libavcodec/version.h b/libavcodec/version.h
index ca928e8385..a130e8d25c 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 56
-#define LIBAVCODEC_VERSION_MINOR 32
+#define LIBAVCODEC_VERSION_MINOR 33
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
diff --git a/libavformat/dump.c b/libavformat/dump.c
index 22ae586146..878eae8c1d 100644
--- a/libavformat/dump.c
+++ b/libavformat/dump.c
@@ -359,6 +359,9 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
av_log(ctx, AV_LOG_INFO, "audio service type: ");
dump_audioservicetype(ctx, &sd);
break;
+ case AV_PKT_DATA_QUALITY_FACTOR:
+ av_log(ctx, AV_LOG_INFO, "quality factor: %d", *(int *)sd.data);
+ break;
default:
av_log(ctx, AV_LOG_WARNING,
"unknown side data type %d (%d bytes)", sd.type, sd.size);