Add an helper function and a compatibility layer for exporting information through coded_frame.
The compression data is exported to the decoded frame, offering a direct correspondece between the packet and the frame properties. Signed-off-by: Vittorio Giovara <[email protected]> --- doc/APIchanges | 5 +++++ libavcodec/avcodec.h | 6 ++++++ libavcodec/internal.h | 5 +++++ libavcodec/utils.c | 33 +++++++++++++++++++++++++++++++++ libavcodec/version.h | 4 ++-- libavformat/dump.c | 24 ++++++++++++++++++++++++ libavutil/frame.h | 7 +++++++ libavutil/metadata.h | 20 ++++++++++++++++++++ libavutil/version.h | 2 +- 9 files changed, 103 insertions(+), 3 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 5215d75..591c8c7 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,11 @@ libavutil: 2014-08-09 API changes, most recent first: +2015-xx-xx - xxxxxx - lavc 56.24, lavu 54.14 - avcodec.h, avutil.h, metadata.h + Add AV_PKT_DATA_STATISTICS and AV_FRAME_DATA_STATISTICS to carry compression + statistic in the form of an AVStats structure from the packet to the + correspoding decoded frame. + 2015-xx-xx - xxxxxxx - lavu 54.13.0 - metadata.h Move AVAudioServiceType from lavc to lavu. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 2c702bc..e5705ef 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -915,6 +915,12 @@ enum AVPacketSideDataType { * to enum AVAudioServiceType. */ AV_PKT_DATA_AUDIO_SERVICE_TYPE, + + /** + * This side data should be associated with a video stream and corresponds + * to statistical data, as described in AVStats. + */ + AV_PKT_DATA_STATISTICS, }; typedef struct AVPacketSideData { diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 634400f..c9e2c66 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -219,6 +219,11 @@ int ff_side_data_update_matrix_encoding(AVFrame *frame, enum AVMatrixEncoding matrix_encoding); /** + * Allocate and initialize an AV_PKT_DATA_STATISTICS side data. + */ +int ff_packet_default_stats(AVPacket *pkt); + +/** * Select the (possibly hardware accelerated) pixel format. * This is a wrapper around AVCodecContext.get_format() and should be used * instead of calling get_format() directly. diff --git a/libavcodec/utils.c b/libavcodec/utils.c index c9ae19b..4b99a05 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -34,6 +34,7 @@ #include "libavutil/frame.h" #include "libavutil/internal.h" #include "libavutil/mathematics.h" +#include "libavutil/metadata.h" #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" #include "libavutil/samplefmt.h" @@ -177,6 +178,23 @@ int ff_side_data_update_matrix_encoding(AVFrame *frame, return 0; } +int ff_packet_default_stats(AVPacket *pkt) +{ + int i; + AVStats *stats = + (AVStats *)av_packet_new_side_data(pkt, AV_PKT_DATA_STATISTICS, + sizeof(AVStats)); + if (!stats) + return AVERROR(ENOMEM); + + stats->pict_type = AV_PICTURE_TYPE_I; + stats->quality = 0; + for (i = 0; i < AV_NUM_DATA_POINTERS; i++) + stats->error[i] = 0; + + return 0; +} + #if HAVE_SIMD_ALIGN_16 # define STRIDE_ALIGN 16 #else @@ -570,6 +588,7 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX }, { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D }, { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, + { AV_PKT_DATA_STATISTICS, AV_FRAME_DATA_STATISTICS }, }; frame->color_primaries = avctx->color_primaries; @@ -1509,6 +1528,8 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); if (!ret) { + AVStats *stats; + if (!*got_packet_ptr) avpkt->size = 0; else if (!(avctx->codec->capabilities & CODEC_CAP_DELAY)) @@ -1520,6 +1541,18 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, avpkt->data = avpkt->buf->data; } + stats = (AVStats *)av_packet_get_side_data(avpkt, + AV_PKT_DATA_STATISTICS, + NULL); + if (stats) { + int i; + avctx->coded_frame->key_frame = avpkt->flags & AV_PKT_FLAG_KEY; + avctx->coded_frame->pict_type = stats->pict_type; + avctx->coded_frame->quality = stats->quality; + for (i = 0; i < AV_NUM_DATA_POINTERS; i++) + avctx->coded_frame->error[i] = stats->error[i]; + } + avctx->frame_number++; } diff --git a/libavcodec/version.h b/libavcodec/version.h index 76020d3..c478ca3 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 23 -#define LIBAVCODEC_VERSION_MICRO 1 +#define LIBAVCODEC_VERSION_MINOR 24 +#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavformat/dump.c b/libavformat/dump.c index 3248e56..ade1e35 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -25,6 +25,7 @@ #include "libavutil/display.h" #include "libavutil/intreadwrite.h" #include "libavutil/log.h" +#include "libavutil/metadata.h" #include "libavutil/mathematics.h" #include "libavutil/replaygain.h" #include "libavutil/stereo3d.h" @@ -318,6 +319,25 @@ static void dump_audioservicetype(void *ctx, AVPacketSideData *sd) } } +static void dump_compstats(void *ctx, AVPacketSideData *sd) +{ + AVStats *stats = (AVStats *)sd->data; + + if (sd->size < sizeof(*stats)) { + av_log(ctx, AV_LOG_INFO, "invalid data"); + return; + } + + av_log(ctx, AV_LOG_INFO, "%c picture type", + av_get_picture_type_char(stats->pict_type)); + + if (stats->quality > 0) + av_log(ctx, AV_LOG_INFO, " (%d quality)", stats->quality); + if (stats->error[0] || stats->error[1] || stats->error[2]) + av_log(ctx, AV_LOG_INFO, " [%"PRIu64" %"PRIu64" %"PRIu64"]", + stats->error[0], stats->error[1], stats->error[2]); +} + static void dump_sidedata(void *ctx, AVStream *st, const char *indent) { int i; @@ -359,6 +379,10 @@ 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_STATISTICS: + av_log(ctx, AV_LOG_INFO, "compression statistics: "); + dump_compstats(ctx, &sd); + break; default: av_log(ctx, AV_LOG_WARNING, "unknown side data type %d (%d bytes)", sd.type, sd.size); diff --git a/libavutil/frame.h b/libavutil/frame.h index ab4079d..8c5caeb 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -93,6 +93,13 @@ enum AVFrameSideDataType { * enum AVAudioServiceType defined in metadata.h. */ AV_FRAME_DATA_AUDIO_SERVICE_TYPE, + + /** + * This side data should be associated with a video stream and corresponds + * to statistical compression data from the packet, described in the form + * of an AVStats structure defined in metadata.h. + */ + AV_FRAME_DATA_STATISTICS, }; enum AVActiveFormatDescription { diff --git a/libavutil/metadata.h b/libavutil/metadata.h index 937581e..5329248 100644 --- a/libavutil/metadata.h +++ b/libavutil/metadata.h @@ -21,6 +21,9 @@ #include <stdint.h> +#include "avutil.h" +#include "frame.h" + enum AVAudioServiceType { AV_AUDIO_SERVICE_TYPE_MAIN = 0, AV_AUDIO_SERVICE_TYPE_EFFECTS = 1, @@ -34,4 +37,21 @@ enum AVAudioServiceType { AV_AUDIO_SERVICE_TYPE_NB , ///< Not part of ABI }; +typedef struct AVStats { + /** + * Picture type of the frame contained in the packet. + */ + enum AVPictureType pict_type; + + /** + * Quality after compression, between 1 (good) and FF_LAMBDA_MAX (bad). + */ + int quality; + + /** + * Compression error for each data pointer. + */ + uint64_t error[AV_NUM_DATA_POINTERS]; +} AVStats; + #endif /* AVUTIL_METADATA_H */ diff --git a/libavutil/version.h b/libavutil/version.h index 378f7b7..c3342cd 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 54 -#define LIBAVUTIL_VERSION_MINOR 13 +#define LIBAVUTIL_VERSION_MINOR 14 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ -- 1.9.5 (Apple Git-50.3) _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
