diff --git a/doc/APIchanges b/doc/APIchanges index a7d99524e0..e90e23e321 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,8 +15,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 - lavc 56.51.100 - avcodec.h + Add AV_PKT_DATA_QUALITY_STATS to export the quality value, PSNR, and pict_type + of an AVPacket. 2015-07-16 - xxxxxxxx - lavc 56.49.100 Add av_codec_get_codec_properties(), FF_CODEC_PROPERTY_LOSSLESS diff --git a/ffmpeg.c b/ffmpeg.c index ce9cac7846..751c7d350d 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -669,9 +669,9 @@ 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, + uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, NULL); - ost->quality = sd ? *(int *)sd : -1; + ost->quality = sd ? AV_RL32(sd) : -1; } if (bsfc) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 6cfbea4324..af30ff012d 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1055,11 +1055,16 @@ enum AVPacketSideDataType { 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). + * This side data contains quality related information from the encoder. + * @code + * u32le quality factor of the compressed frame. Allowed range is between 1 (good) and FF_LAMBDA_MAX (bad). + * u8 picture type + * u8 error count + * u16 reserved + * u64le[error count] sum of squared differences between encoder in and output + * @endcode */ - AV_PKT_DATA_QUALITY_FACTOR, + AV_PKT_DATA_QUALITY_STATS, /** * Recommmends skipping the specified number of samples @@ -1126,6 +1131,8 @@ enum AVPacketSideDataType { AV_PKT_DATA_METADATA_UPDATE, }; +#define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED + typedef struct AVPacketSideData { uint8_t *data; int size; diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index aae67c5a00..6ba9c0bc5e 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -602,3 +602,28 @@ void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb) if (pkt->convergence_duration > 0) pkt->convergence_duration = av_rescale_q(pkt->convergence_duration, src_tb, dst_tb); } + +int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type) +{ + uint8_t *side_data; + int side_data_size; + int i; + + side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, &side_data_size); + if (!side_data) { + side_data_size = 4+4+8*error_count; + side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, + side_data_size); + } + + if (!side_data || side_data_size < 4+4+8*error_count) + return AVERROR(ENOMEM); + + AV_WL32(side_data , quality ); + side_data[4] = pict_type; + side_data[5] = error_count; + for (i = 0; iqscale * FF_QP2LAMBDA; + ff_side_data_set_encoder_stats(pkt, ctx->qscale * FF_QP2LAMBDA, NULL, 0, 0); pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; diff --git a/libavcodec/internal.h b/libavcodec/internal.h index f3dafc0cd1..e0b40f1cc4 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -298,4 +298,6 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt); */ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame); +int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type); + #endif /* AVCODEC_INTERNAL_H */ diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 048edbf0e1..3a55b5dafb 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -307,11 +307,7 @@ FF_ENABLE_DEPRECATION_WARNINGS pkt->flags |= AV_PKT_FLAG_KEY*pic_out.b_keyframe; 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; + ff_side_data_set_encoder_stats(pkt, (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA, NULL, 0, 0); #if FF_API_CODED_FRAME FF_DISABLE_DEPRECATION_WARNINGS diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c index a1b48c04d9..9c1c6897d0 100644 --- a/libavcodec/libxavs.c +++ b/libavcodec/libxavs.c @@ -208,10 +208,7 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif - 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; + ff_side_data_set_encoder_stats(pkt, (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA, NULL, 0, 0); x4->out_frame_count++; *got_packet = ret; diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c index 25c2476573..6979346f62 100644 --- a/libavcodec/libxvid.c +++ b/libavcodec/libxvid.c @@ -771,27 +771,28 @@ 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; + int pict_type; *got_packet = 1; + if (xvid_enc_stats.type == XVID_TYPE_PVOP) + pict_type = AV_PICTURE_TYPE_P; + else if (xvid_enc_stats.type == XVID_TYPE_BVOP) + pict_type = AV_PICTURE_TYPE_B; + else if (xvid_enc_stats.type == XVID_TYPE_SVOP) + pict_type = AV_PICTURE_TYPE_S; + else + pict_type = AV_PICTURE_TYPE_I; + #if FF_API_CODED_FRAME FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame->pict_type = pict_type; avctx->coded_frame->quality = xvid_enc_stats.quant * FF_QP2LAMBDA; - if (xvid_enc_stats.type == XVID_TYPE_PVOP) - avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P; - else if (xvid_enc_stats.type == XVID_TYPE_BVOP) - avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B; - else if (xvid_enc_stats.type == XVID_TYPE_SVOP) - avctx->coded_frame->pict_type = AV_PICTURE_TYPE_S; - else - avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; FF_ENABLE_DEPRECATION_WARNINGS #endif + + ff_side_data_set_encoder_stats(pkt, xvid_enc_stats.quant * FF_QP2LAMBDA, NULL, 0, pict_type); + if (xvid_enc_frame.out_flags & XVID_KEYFRAME) { #if FF_API_CODED_FRAME FF_DISABLE_DEPRECATION_WARNINGS diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 0143d9dad8..6939ce5a23 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -1786,11 +1786,7 @@ 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; + ff_side_data_set_encoder_stats(pkt, s->current_picture.f->quality, NULL, 0, s->pict_type); 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 cb3bc451b2..6d5ff01b51 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -618,10 +618,7 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif - sd = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_FACTOR, sizeof(int)); - if (!sd) - return AVERROR(ENOMEM); - *(int *)sd = pict->quality; + ff_side_data_set_encoder_stats(pkt, pict->quality, NULL, 0, s->pict_type); svq1_write_header(s, s->pict_type); for (i = 0; i < 3; i++) diff --git a/libavcodec/version.h b/libavcodec/version.h index c79e2bacd0..399ee56862 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,8 +29,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 56 -#define LIBAVCODEC_VERSION_MINOR 50 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 51 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavformat/dump.c b/libavformat/dump.c index bb7779daf9..acf6bf622e 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -377,8 +377,8 @@ 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); + case AV_PKT_DATA_QUALITY_STATS: + av_log(ctx, AV_LOG_INFO, "quality factor: %d", AV_RL32(sd.data)); break; default: av_log(ctx, AV_LOG_WARNING,