#include <inttypes.h>
+#include "libavutil/bswap.h"
#include "libavutil/adler32.h"
#include "libavutil/display.h"
#include "libavutil/imgutils.h"
#include "libavutil/timestamp.h"
#include "libavutil/timecode.h"
#include "libavutil/mastering_display_metadata.h"
+#include "libavutil/video_enc_params.h"
#include "avfilter.h"
#include "internal.h"
av_log(ctx, AV_LOG_INFO, "spherical information: ");
if (sd->size < sizeof(*spherical)) {
- av_log(ctx, AV_LOG_ERROR, "invalid data");
+ av_log(ctx, AV_LOG_ERROR, "invalid data\n");
return;
}
else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE)
av_log(ctx, AV_LOG_INFO, "tiled equirectangular ");
else {
- av_log(ctx, AV_LOG_WARNING, "unknown");
+ av_log(ctx, AV_LOG_WARNING, "unknown\n");
return;
}
av_log(ctx, AV_LOG_INFO, "stereoscopic information: ");
if (sd->size < sizeof(*stereo)) {
- av_log(ctx, AV_LOG_ERROR, "invalid data");
+ av_log(ctx, AV_LOG_ERROR, "invalid data\n");
return;
}
roi = (const AVRegionOfInterest *)sd->data;
roi_size = roi->self_size;
if (!roi_size || sd->size % roi_size != 0) {
- av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.");
+ av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
return;
}
nb_rois = sd->size / roi_size;
av_log(ctx, AV_LOG_INFO, "mastering display: ");
if (sd->size < sizeof(*mastering_display)) {
- av_log(ctx, AV_LOG_ERROR, "invalid data");
+ av_log(ctx, AV_LOG_ERROR, "invalid data\n");
return;
}
metadata->MaxCLL, metadata->MaxFALL);
}
+static void dump_video_enc_params(AVFilterContext *ctx, AVFrameSideData *sd)
+{
+ AVVideoEncParams *par = (AVVideoEncParams*)sd->data;
+ int plane, acdc;
+
+ av_log(ctx, AV_LOG_INFO, "video encoding parameters: type %d; ", par->type);
+ if (par->qp)
+ av_log(ctx, AV_LOG_INFO, "qp=%d; ", par->qp);
+ for (plane = 0; plane < FF_ARRAY_ELEMS(par->delta_qp); plane++)
+ for (acdc = 0; acdc < FF_ARRAY_ELEMS(par->delta_qp[plane]); acdc++) {
+ int delta_qp = par->delta_qp[plane][acdc];
+ if (delta_qp)
+ av_log(ctx, AV_LOG_INFO, "delta_qp[%d][%d]=%d; ",
+ plane, acdc, delta_qp);
+ }
+ if (par->nb_blocks)
+ av_log(ctx, AV_LOG_INFO, "%u blocks; ", par->nb_blocks);
+}
+
+static void dump_sei_unregistered_metadata(AVFilterContext *ctx, AVFrameSideData *sd)
+{
+ const int uuid_size = 16;
+ uint8_t *user_data = sd->data;
+ int i;
+
+ if (sd->size < uuid_size) {
+ av_log(ctx, AV_LOG_ERROR, "invalid data(%d < UUID(%d-bytes))\n", sd->size, uuid_size);
+ return;
+ }
+
+ av_log(ctx, AV_LOG_INFO, "User Data Unregistered:\n");
+ av_log(ctx, AV_LOG_INFO, "UUID=");
+ for (i = 0; i < uuid_size; i++) {
+ av_log(ctx, AV_LOG_INFO, "%02x", user_data[i]);
+ if (i == 3 || i == 5 || i == 7 || i == 9)
+ av_log(ctx, AV_LOG_INFO, "-");
+ }
+ av_log(ctx, AV_LOG_INFO, "\n");
+
+ av_log(ctx, AV_LOG_INFO, "User Data=");
+ for (; i < sd->size; i++) {
+ av_log(ctx, AV_LOG_INFO, "%02x", user_data[i]);
+ }
+ av_log(ctx, AV_LOG_INFO, "\n");
+}
+
static void dump_color_property(AVFilterContext *ctx, AVFrame *frame)
{
const char *color_range_str = av_color_range_name(frame->color_range);
av_log(ctx, AV_LOG_INFO, "\n");
}
-static void update_sample_stats(const uint8_t *src, int len, int64_t *sum, int64_t *sum2)
+static void update_sample_stats_8(const uint8_t *src, int len, int64_t *sum, int64_t *sum2)
{
int i;
}
}
+static void update_sample_stats_16(int be, const uint8_t *src, int len, int64_t *sum, int64_t *sum2)
+{
+ const uint16_t *src1 = (const uint16_t *)src;
+ int i;
+
+ for (i = 0; i < len / 2; i++) {
+ if ((HAVE_BIGENDIAN && !be) || (!HAVE_BIGENDIAN && be)) {
+ *sum += av_bswap16(src1[i]);
+ *sum2 += (uint32_t)av_bswap16(src1[i]) * (uint32_t)av_bswap16(src1[i]);
+ } else {
+ *sum += src1[i];
+ *sum2 += (uint32_t)src1[i] * (uint32_t)src1[i];
+ }
+ }
+}
+
+static void update_sample_stats(int depth, int be, const uint8_t *src, int len, int64_t *sum, int64_t *sum2)
+{
+ if (depth <= 8)
+ update_sample_stats_8(src, len, sum, sum2);
+ else
+ update_sample_stats_16(be, src, len, sum, sum2);
+}
+
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
AVFilterContext *ctx = inlink->dst;
uint32_t plane_checksum[4] = {0}, checksum = 0;
int64_t sum[4] = {0}, sum2[4] = {0};
int32_t pixelcount[4] = {0};
+ int bitdepth = desc->comp[0].depth;
+ int be = desc->flags & AV_PIX_FMT_FLAG_BE;
int i, plane, vsub = desc->log2_chroma_h;
for (plane = 0; plane < 4 && s->calculate_checksums && frame->data[plane] && frame->linesize[plane]; plane++) {
uint8_t *data = frame->data[plane];
int h = plane == 1 || plane == 2 ? AV_CEIL_RSHIFT(inlink->h, vsub) : inlink->h;
int linesize = av_image_get_linesize(frame->format, frame->width, plane);
+ int width = linesize >> (bitdepth > 8);
if (linesize < 0)
return linesize;
plane_checksum[plane] = av_adler32_update(plane_checksum[plane], data, linesize);
checksum = av_adler32_update(checksum, data, linesize);
- update_sample_stats(data, linesize, sum+plane, sum2+plane);
- pixelcount[plane] += linesize;
+ update_sample_stats(bitdepth, be, data, linesize, sum+plane, sum2+plane);
+ pixelcount[plane] += width;
data += frame->linesize[plane];
}
}
break;
case AV_FRAME_DATA_S12M_TIMECODE: {
uint32_t *tc = (uint32_t*)sd->data;
- for (int j = 1; j <= tc[0]; j++) {
+ int m = FFMIN(tc[0],3);
+ if (sd->size != 16) {
+ av_log(ctx, AV_LOG_ERROR, "invalid data\n");
+ break;
+ }
+ for (int j = 1; j <= m; j++) {
char tcbuf[AV_TIMECODE_STR_SIZE];
av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0);
- av_log(ctx, AV_LOG_INFO, "timecode - %s%s", tcbuf, j != tc[0] ? ", " : "");
+ av_log(ctx, AV_LOG_INFO, "timecode - %s%s", tcbuf, j != m ? ", " : "");
}
break;
}
case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL:
dump_content_light_metadata(ctx, sd);
break;
+ case AV_FRAME_DATA_GOP_TIMECODE: {
+ char tcbuf[AV_TIMECODE_STR_SIZE];
+ av_timecode_make_mpeg_tc_string(tcbuf, *(int64_t *)(sd->data));
+ av_log(ctx, AV_LOG_INFO, "GOP timecode - %s", tcbuf);
+ break;
+ }
+ case AV_FRAME_DATA_VIDEO_ENC_PARAMS:
+ dump_video_enc_params(ctx, sd);
+ break;
+ case AV_FRAME_DATA_SEI_UNREGISTERED:
+ dump_sei_unregistered_metadata(ctx, sd);
+ break;
default:
- av_log(ctx, AV_LOG_WARNING, "unknown side data type %d (%d bytes)",
+ av_log(ctx, AV_LOG_WARNING, "unknown side data type %d (%d bytes)\n",
sd->type, sd->size);
break;
}