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

Reply via email to