mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
1036 lines
42 KiB
C
1036 lines
42 KiB
C
/*
|
|
* gstav12json.c - AV1 parsed bistream to json
|
|
*
|
|
* Copyright (C) 2023 Collabora
|
|
* Author: Benjamin Gaignard <benjamin.gaignard@collabora.com>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
/**
|
|
* SECTION:element-av12json
|
|
* @title: av12json
|
|
*
|
|
* Convert AV1 bitstream parameters to JSON formated text.
|
|
*
|
|
* ## Example launch line
|
|
* ```
|
|
* gst-launch-1.0 filesrc location=/path/to/av1/file ! parsebin ! av12json ! filesink location=/path/to/json/file
|
|
* ```
|
|
*
|
|
* Since: 1.24
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <gst/base/base.h>
|
|
#include <json-glib/json-glib.h>
|
|
|
|
#include "gstav12json.h"
|
|
|
|
GST_DEBUG_CATEGORY (gst_av1_2_json_debug);
|
|
#define GST_CAT_DEFAULT gst_av1_2_json_debug
|
|
|
|
struct _GstAV12json
|
|
{
|
|
GstElement parent;
|
|
|
|
GstPad *sinkpad, *srcpad;
|
|
GstAV1Parser *parser;
|
|
gboolean use_annex_b;
|
|
|
|
JsonObject *json;
|
|
};
|
|
|
|
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
|
GST_PAD_SINK,
|
|
GST_PAD_ALWAYS,
|
|
GST_STATIC_CAPS ("video/x-av1")
|
|
);
|
|
|
|
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
|
GST_PAD_SRC,
|
|
GST_PAD_ALWAYS,
|
|
GST_STATIC_CAPS ("text/x-json,format=av1"));
|
|
|
|
G_DEFINE_TYPE_WITH_CODE (GstAV12json, gst_av1_2_json,
|
|
GST_TYPE_ELEMENT,
|
|
GST_DEBUG_CATEGORY_INIT (gst_av1_2_json_debug, "av12json", 0,
|
|
"AV1 to json"));
|
|
|
|
static void
|
|
gst_av1_2_json_finalize (GObject * object)
|
|
{
|
|
GstAV12json *self = GST_AV1_2_JSON (object);
|
|
|
|
gst_av1_parser_free (self->parser);
|
|
json_object_unref (self->json);
|
|
}
|
|
|
|
static gchar *
|
|
get_string_from_json_object (JsonObject * object)
|
|
{
|
|
JsonNode *root;
|
|
JsonGenerator *generator;
|
|
gchar *text;
|
|
|
|
/* Make it the root node */
|
|
root = json_node_init_object (json_node_alloc (), object);
|
|
generator = json_generator_new ();
|
|
json_generator_set_indent (generator, 2);
|
|
json_generator_set_indent_char (generator, ' ');
|
|
json_generator_set_pretty (generator, TRUE);
|
|
json_generator_set_root (generator, root);
|
|
text = json_generator_to_data (generator, NULL);
|
|
|
|
/* Release everything */
|
|
g_object_unref (generator);
|
|
json_node_free (root);
|
|
return text;
|
|
}
|
|
|
|
static void
|
|
gst_av1_2_json_sequence_header (GstAV12json * self,
|
|
GstAV1SequenceHeaderOBU * seq_header)
|
|
{
|
|
JsonObject *json = self->json;
|
|
JsonObject *hdr = json_object_new ();
|
|
JsonArray *operating_points;
|
|
JsonObject *color_config;
|
|
guint i;
|
|
|
|
json_object_set_int_member (hdr, "seq profile", seq_header->seq_profile);
|
|
json_object_set_boolean_member (hdr, "still picture",
|
|
seq_header->still_picture);
|
|
json_object_set_int_member (hdr, "reduced still picture header",
|
|
seq_header->reduced_still_picture_header);
|
|
json_object_set_int_member (hdr, "frame width bits minus 1",
|
|
seq_header->frame_width_bits_minus_1);
|
|
json_object_set_int_member (hdr, "frame height bits minus 1",
|
|
seq_header->frame_height_bits_minus_1);
|
|
json_object_set_int_member (hdr, "max frame width minus 1",
|
|
seq_header->max_frame_width_minus_1);
|
|
json_object_set_int_member (hdr, "max frame height minus 1",
|
|
seq_header->max_frame_height_minus_1);
|
|
json_object_set_boolean_member (hdr, "frame id numbers present flag",
|
|
seq_header->frame_id_numbers_present_flag);
|
|
json_object_set_int_member (hdr, "delta frame id length minus 2",
|
|
seq_header->delta_frame_id_length_minus_2);
|
|
json_object_set_int_member (hdr, "additional frame id length minus 1",
|
|
seq_header->additional_frame_id_length_minus_1);
|
|
json_object_set_boolean_member (hdr, "use 128x128 superblock",
|
|
seq_header->use_128x128_superblock);
|
|
json_object_set_boolean_member (hdr, "enable filter intra",
|
|
seq_header->enable_filter_intra);
|
|
json_object_set_boolean_member (hdr, "enable intra edge filter",
|
|
seq_header->enable_intra_edge_filter);
|
|
json_object_set_boolean_member (hdr, "enable interintra compound",
|
|
seq_header->enable_interintra_compound);
|
|
json_object_set_boolean_member (hdr, "enable masked compound",
|
|
seq_header->enable_masked_compound);
|
|
json_object_set_boolean_member (hdr, "enable warped motion",
|
|
seq_header->enable_warped_motion);
|
|
json_object_set_boolean_member (hdr, "enable order hint",
|
|
seq_header->enable_order_hint);
|
|
json_object_set_boolean_member (hdr, "enable dual filter",
|
|
seq_header->enable_dual_filter);
|
|
json_object_set_boolean_member (hdr, "enable jnt comp",
|
|
seq_header->enable_jnt_comp);
|
|
json_object_set_boolean_member (hdr, "enable ref frame mvs",
|
|
seq_header->enable_ref_frame_mvs);
|
|
json_object_set_boolean_member (hdr, "seq choose screen content tools",
|
|
seq_header->seq_choose_screen_content_tools);
|
|
json_object_set_int_member (hdr, "seq force screen content tools",
|
|
seq_header->seq_force_screen_content_tools);
|
|
json_object_set_boolean_member (hdr, "seq choose integer mv",
|
|
seq_header->seq_choose_integer_mv);
|
|
json_object_set_int_member (hdr, "seq force integer mv",
|
|
seq_header->seq_force_integer_mv);
|
|
json_object_set_int_member (hdr, "order hint bits minus 1",
|
|
seq_header->order_hint_bits_minus_1);
|
|
json_object_set_boolean_member (hdr, "enable superres",
|
|
seq_header->enable_superres);
|
|
json_object_set_boolean_member (hdr, "enable cdef", seq_header->enable_cdef);
|
|
json_object_set_boolean_member (hdr, "enable restoration",
|
|
seq_header->enable_restoration);
|
|
json_object_set_int_member (hdr, "film grain params present",
|
|
seq_header->film_grain_params_present);
|
|
json_object_set_int_member (hdr, "operating points cnt minus 1",
|
|
seq_header->operating_points_cnt_minus_1);
|
|
|
|
operating_points = json_array_new ();
|
|
for (i = 0; i < seq_header->operating_points_cnt_minus_1 + 1; i++) {
|
|
JsonObject *operating_point = json_object_new ();
|
|
|
|
json_object_set_int_member (operating_point, "seq level idx",
|
|
seq_header->operating_points[i].seq_level_idx);
|
|
json_object_set_int_member (operating_point, "seq tier",
|
|
seq_header->operating_points[i].seq_tier);
|
|
json_object_set_int_member (operating_point, "idc",
|
|
seq_header->operating_points[i].idc);
|
|
json_object_set_boolean_member (operating_point,
|
|
"decoder model present for this op",
|
|
seq_header->operating_points[i].decoder_model_present_for_this_op);
|
|
json_object_set_int_member (operating_point, "decoder buffer delay",
|
|
seq_header->operating_points[i].decoder_buffer_delay);
|
|
json_object_set_int_member (operating_point, "encoder buffer delay",
|
|
seq_header->operating_points[i].encoder_buffer_delay);
|
|
json_object_set_boolean_member (operating_point, "low delay mode flag",
|
|
seq_header->operating_points[i].low_delay_mode_flag);
|
|
json_object_set_boolean_member (operating_point,
|
|
"initial display delay present for this op",
|
|
seq_header->
|
|
operating_points[i].initial_display_delay_present_for_this_op);
|
|
json_object_set_int_member (operating_point,
|
|
"initial display delay minus 1",
|
|
seq_header->operating_points[i].initial_display_delay_minus_1);
|
|
json_array_add_object_element (operating_points, operating_point);
|
|
}
|
|
json_object_set_array_member (hdr, "operating points", operating_points);
|
|
|
|
json_object_set_boolean_member (hdr, "decoder model info present flag",
|
|
seq_header->decoder_model_info_present_flag);
|
|
if (seq_header->decoder_model_info_present_flag) {
|
|
JsonObject *decoder_model_info = json_object_new ();
|
|
|
|
json_object_set_int_member (decoder_model_info,
|
|
"buffer delay length minus 1",
|
|
seq_header->decoder_model_info.buffer_delay_length_minus_1);
|
|
json_object_set_int_member (decoder_model_info,
|
|
"num units in decoding tick",
|
|
seq_header->decoder_model_info.num_units_in_decoding_tick);
|
|
json_object_set_int_member (decoder_model_info,
|
|
"buffer removal time length minus 1",
|
|
seq_header->decoder_model_info.buffer_removal_time_length_minus_1);
|
|
json_object_set_int_member (decoder_model_info,
|
|
"frame presentation time length minus 1",
|
|
seq_header->decoder_model_info.frame_presentation_time_length_minus_1);
|
|
json_object_set_object_member (hdr, "decoder model info",
|
|
decoder_model_info);
|
|
}
|
|
|
|
json_object_set_int_member (hdr, "initial display delay present flag",
|
|
seq_header->initial_display_delay_present_flag);
|
|
|
|
json_object_set_boolean_member (hdr, "timing info present flag",
|
|
seq_header->timing_info_present_flag);
|
|
if (seq_header->timing_info_present_flag) {
|
|
JsonObject *timing_info = json_object_new ();
|
|
|
|
json_object_set_int_member (timing_info, "num units in display tick",
|
|
seq_header->timing_info.num_units_in_display_tick);
|
|
json_object_set_int_member (timing_info, "time scale",
|
|
seq_header->timing_info.time_scale);
|
|
json_object_set_boolean_member (timing_info, "equal picture interval",
|
|
seq_header->timing_info.equal_picture_interval);
|
|
json_object_set_int_member (timing_info, "num ticks per picture minus 1",
|
|
seq_header->timing_info.num_ticks_per_picture_minus_1);
|
|
json_object_set_object_member (hdr, "timing info", timing_info);
|
|
}
|
|
|
|
color_config = json_object_new ();
|
|
json_object_set_boolean_member (color_config, "high bitdepth",
|
|
seq_header->color_config.high_bitdepth);
|
|
json_object_set_boolean_member (color_config, "twelve bit",
|
|
seq_header->color_config.twelve_bit);
|
|
json_object_set_boolean_member (color_config, "mono chrome",
|
|
seq_header->color_config.mono_chrome);
|
|
json_object_set_boolean_member (color_config,
|
|
"color description present flag",
|
|
seq_header->color_config.color_description_present_flag);
|
|
json_object_set_int_member (color_config, "color primaries",
|
|
seq_header->color_config.color_primaries);
|
|
json_object_set_int_member (color_config, "transfer characteristics",
|
|
seq_header->color_config.transfer_characteristics);
|
|
json_object_set_int_member (color_config, "matrix coefficients",
|
|
seq_header->color_config.matrix_coefficients);
|
|
json_object_set_boolean_member (color_config, "color range",
|
|
seq_header->color_config.color_range);
|
|
json_object_set_int_member (color_config, "subsampling x",
|
|
seq_header->color_config.subsampling_x);
|
|
json_object_set_int_member (color_config, "subsampling y",
|
|
seq_header->color_config.subsampling_y);
|
|
json_object_set_int_member (color_config, "chroma sample position",
|
|
seq_header->color_config.chroma_sample_position);
|
|
json_object_set_boolean_member (color_config, "separate uv delta q",
|
|
seq_header->color_config.separate_uv_delta_q);
|
|
json_object_set_object_member (hdr, "color config", color_config);
|
|
|
|
json_object_set_int_member (hdr, "order hint bits",
|
|
seq_header->order_hint_bits);
|
|
json_object_set_int_member (hdr, "bit depth", seq_header->bit_depth);
|
|
json_object_set_int_member (hdr, "num planes", seq_header->num_planes);
|
|
|
|
json_object_set_object_member (json, "sequence header", hdr);
|
|
}
|
|
|
|
static void
|
|
gst_av1_2_json_frame_header (GstAV12json * self,
|
|
GstAV1FrameHeaderOBU * frame_header)
|
|
{
|
|
JsonObject *json = self->json;
|
|
JsonArray *buffer_removal_time, *ref_order_hint, *ref_frame_idx,
|
|
*loop_filter_level, *loop_filter_ref_deltas, *loop_filter_mode_deltas,
|
|
*feature_enabled, *feature_data, *width_in_sbs_minus_1,
|
|
*height_in_sbs_minus_1, *mi_col_starts, *mi_row_starts,
|
|
*cdef_y_pri_strength, *cdef_y_sec_strength, *cdef_uv_pri_strength,
|
|
*cdef_uv_sec_strength, *frame_restoration_type, *loop_restoration_size,
|
|
*is_global, *is_rot_zoom, *is_translation, *gm_params, *gm_type, *invalid,
|
|
*point_y_value, *point_y_scaling, *point_cb_value, *point_cb_scaling,
|
|
*point_cr_value, *point_cr_scaling, *ar_coeffs_y_plus_128,
|
|
*ar_coeffs_cb_plus_128, *ar_coeffs_cr_plus_128, *order_hints,
|
|
*ref_frame_sign_bias, *lossless_array, *seg_qm_level, *skip_mode_frame;
|
|
JsonObject *hdr = json_object_new ();
|
|
JsonObject *loop_filter_params, *quantization_params, *segmentation_params,
|
|
*tile_info, *cdef_params, *loop_restoration_params, *global_motion_params,
|
|
*film_grain_params;
|
|
guint i, j;
|
|
|
|
json_object_set_boolean_member (hdr, "show existing frame",
|
|
frame_header->show_existing_frame);
|
|
json_object_set_int_member (hdr, "frame to show map idx",
|
|
frame_header->frame_to_show_map_idx);
|
|
json_object_set_int_member (hdr, "frame presentation time",
|
|
frame_header->frame_presentation_time);
|
|
json_object_set_int_member (hdr, "tu presentation delay",
|
|
frame_header->tu_presentation_delay);
|
|
json_object_set_int_member (hdr, "display frame id",
|
|
frame_header->display_frame_id);
|
|
switch (frame_header->frame_type) {
|
|
case GST_AV1_KEY_FRAME:
|
|
json_object_set_string_member (hdr, "frame type", "key frame");
|
|
break;
|
|
case GST_AV1_INTER_FRAME:
|
|
json_object_set_string_member (hdr, "frame type", "inter frame");
|
|
break;
|
|
case GST_AV1_INTRA_ONLY_FRAME:
|
|
json_object_set_string_member (hdr, "frame type", "intra only frame");
|
|
break;
|
|
case GST_AV1_SWITCH_FRAME:
|
|
json_object_set_string_member (hdr, "frame type", "switch frame");
|
|
break;
|
|
}
|
|
json_object_set_boolean_member (hdr, "show frame", frame_header->show_frame);
|
|
json_object_set_boolean_member (hdr, "showable frame",
|
|
frame_header->showable_frame);
|
|
json_object_set_boolean_member (hdr, "error resilient mode",
|
|
frame_header->error_resilient_mode);
|
|
json_object_set_boolean_member (hdr, "disable cdf update",
|
|
frame_header->disable_cdf_update);
|
|
json_object_set_int_member (hdr, "allow screen content tools",
|
|
frame_header->allow_screen_content_tools);
|
|
json_object_set_boolean_member (hdr, "force integer_mv",
|
|
frame_header->force_integer_mv);
|
|
json_object_set_int_member (hdr, "current frame id",
|
|
frame_header->current_frame_id);
|
|
json_object_set_boolean_member (hdr, "frame size override flag",
|
|
frame_header->frame_size_override_flag);
|
|
json_object_set_int_member (hdr, "order hint", frame_header->order_hint);
|
|
json_object_set_int_member (hdr, "primary ref_frame",
|
|
frame_header->primary_ref_frame);
|
|
json_object_set_boolean_member (hdr, "buffer removal time present flag",
|
|
frame_header->buffer_removal_time_present_flag);
|
|
|
|
buffer_removal_time = json_array_new ();
|
|
for (i = 0; i < GST_AV1_MAX_OPERATING_POINTS; i++)
|
|
json_array_add_int_element (buffer_removal_time,
|
|
frame_header->buffer_removal_time[i]);
|
|
json_object_set_array_member (hdr, "buffer removal time",
|
|
buffer_removal_time);
|
|
|
|
json_object_set_int_member (hdr, "refresh frame flags",
|
|
frame_header->refresh_frame_flags);
|
|
|
|
ref_order_hint = json_array_new ();
|
|
for (i = 0; i < GST_AV1_NUM_REF_FRAMES; i++)
|
|
json_array_add_int_element (ref_order_hint,
|
|
frame_header->ref_order_hint[i]);
|
|
json_object_set_array_member (hdr, "ref order hint", ref_order_hint);
|
|
|
|
json_object_set_boolean_member (hdr, "allow intrabc",
|
|
frame_header->allow_intrabc);
|
|
json_object_set_boolean_member (hdr, "frame refs short signaling",
|
|
frame_header->frame_refs_short_signaling);
|
|
json_object_set_int_member (hdr, "last frame idx",
|
|
frame_header->last_frame_idx);
|
|
json_object_set_int_member (hdr, "gold frame idx",
|
|
frame_header->gold_frame_idx);
|
|
|
|
ref_frame_idx = json_array_new ();
|
|
for (i = 0; i < GST_AV1_REFS_PER_FRAME; i++)
|
|
json_array_add_int_element (ref_frame_idx, frame_header->ref_frame_idx[i]);
|
|
json_object_set_array_member (hdr, "ref frame idx", ref_frame_idx);
|
|
|
|
json_object_set_boolean_member (hdr, "allow high precision mv",
|
|
frame_header->allow_high_precision_mv);
|
|
json_object_set_boolean_member (hdr, "is motion mode switchable",
|
|
frame_header->is_motion_mode_switchable);
|
|
json_object_set_boolean_member (hdr, "use ref frame mvs",
|
|
frame_header->use_ref_frame_mvs);
|
|
json_object_set_boolean_member (hdr, "disable frame end update cdf",
|
|
frame_header->disable_frame_end_update_cdf);
|
|
json_object_set_boolean_member (hdr, "allow warped motion",
|
|
frame_header->allow_warped_motion);
|
|
json_object_set_boolean_member (hdr, "reduced tx set",
|
|
frame_header->reduced_tx_set);
|
|
json_object_set_boolean_member (hdr, "render and frame size different",
|
|
frame_header->render_and_frame_size_different);
|
|
json_object_set_boolean_member (hdr, "use superres",
|
|
frame_header->use_superres);
|
|
json_object_set_boolean_member (hdr, "is filter switchable",
|
|
frame_header->is_filter_switchable);
|
|
json_object_set_int_member (hdr, "interpolation filter",
|
|
frame_header->interpolation_filter);
|
|
|
|
loop_filter_params = json_object_new ();
|
|
loop_filter_level = json_array_new ();
|
|
for (i = 0; i < 4; i++)
|
|
json_array_add_int_element (loop_filter_level,
|
|
frame_header->loop_filter_params.loop_filter_level[i]);
|
|
json_object_set_array_member (loop_filter_params, "loop filter level",
|
|
loop_filter_level);
|
|
json_object_set_int_member (loop_filter_params, "loop filter sharpness",
|
|
frame_header->loop_filter_params.loop_filter_sharpness);
|
|
json_object_set_boolean_member (loop_filter_params,
|
|
"loop filter delta enabled",
|
|
frame_header->loop_filter_params.loop_filter_delta_enabled);
|
|
json_object_set_boolean_member (loop_filter_params,
|
|
"loop filter delta update",
|
|
frame_header->loop_filter_params.loop_filter_delta_update);
|
|
|
|
loop_filter_ref_deltas = json_array_new ();
|
|
for (i = 0; i < GST_AV1_TOTAL_REFS_PER_FRAME; i++)
|
|
json_array_add_int_element (loop_filter_ref_deltas,
|
|
frame_header->loop_filter_params.loop_filter_ref_deltas[i]);
|
|
json_object_set_array_member (loop_filter_params, "loop filter ref deltas",
|
|
loop_filter_ref_deltas);
|
|
|
|
loop_filter_mode_deltas = json_array_new ();
|
|
for (i = 0; i < 2; i++)
|
|
json_array_add_int_element (loop_filter_mode_deltas,
|
|
frame_header->loop_filter_params.loop_filter_mode_deltas[i]);
|
|
json_object_set_array_member (loop_filter_params, "loop filter mode deltas",
|
|
loop_filter_mode_deltas);
|
|
json_object_set_boolean_member (loop_filter_params, "delta lf present",
|
|
frame_header->loop_filter_params.delta_lf_present);
|
|
json_object_set_int_member (loop_filter_params, "delta lf res",
|
|
frame_header->loop_filter_params.delta_lf_res);
|
|
json_object_set_int_member (loop_filter_params, "delta lf multi",
|
|
frame_header->loop_filter_params.delta_lf_multi);
|
|
json_object_set_object_member (hdr, "loop filter params", loop_filter_params);
|
|
|
|
quantization_params = json_object_new ();
|
|
json_object_set_int_member (quantization_params, "base q idx",
|
|
frame_header->quantization_params.base_q_idx);
|
|
json_object_set_boolean_member (quantization_params, "diff uv delta",
|
|
frame_header->quantization_params.diff_uv_delta);
|
|
json_object_set_boolean_member (quantization_params, "using qmatrix",
|
|
frame_header->quantization_params.using_qmatrix);
|
|
json_object_set_int_member (quantization_params, "qm y",
|
|
frame_header->quantization_params.qm_y);
|
|
json_object_set_int_member (quantization_params, "qm u",
|
|
frame_header->quantization_params.qm_u);
|
|
json_object_set_int_member (quantization_params, "qm v",
|
|
frame_header->quantization_params.qm_v);
|
|
json_object_set_boolean_member (quantization_params, "delta q present",
|
|
frame_header->quantization_params.delta_q_present);
|
|
json_object_set_int_member (quantization_params, "delta q res",
|
|
frame_header->quantization_params.delta_q_res);
|
|
json_object_set_int_member (quantization_params, "delta q y dc",
|
|
frame_header->quantization_params.delta_q_y_dc);
|
|
json_object_set_int_member (quantization_params, "delta q u dc",
|
|
frame_header->quantization_params.delta_q_u_dc);
|
|
json_object_set_int_member (quantization_params, "delta q u ac",
|
|
frame_header->quantization_params.delta_q_u_ac);
|
|
json_object_set_int_member (quantization_params, "delta q v dc",
|
|
frame_header->quantization_params.delta_q_v_dc);
|
|
json_object_set_int_member (quantization_params, "delta q v ac",
|
|
frame_header->quantization_params.delta_q_v_ac);
|
|
json_object_set_object_member (hdr, "quantization params",
|
|
quantization_params);
|
|
|
|
segmentation_params = json_object_new ();
|
|
json_object_set_boolean_member (segmentation_params, "segmentation enabled",
|
|
frame_header->segmentation_params.segmentation_enabled);
|
|
json_object_set_int_member (segmentation_params, "segmentation update map",
|
|
frame_header->segmentation_params.segmentation_update_map);
|
|
json_object_set_int_member (segmentation_params,
|
|
"segmentation temporal update",
|
|
frame_header->segmentation_params.segmentation_temporal_update);
|
|
json_object_set_int_member (segmentation_params, "segmentation update data",
|
|
frame_header->segmentation_params.segmentation_update_data);
|
|
feature_enabled = json_array_new ();
|
|
feature_data = json_array_new ();
|
|
for (i = 0; i < GST_AV1_MAX_SEGMENTS; i++) {
|
|
for (j = 0; j < GST_AV1_SEG_LVL_MAX; j++) {
|
|
json_array_add_int_element (feature_enabled,
|
|
frame_header->segmentation_params.feature_enabled[i][j]);
|
|
json_array_add_int_element (feature_data,
|
|
frame_header->segmentation_params.feature_data[i][j]);
|
|
}
|
|
}
|
|
json_object_set_array_member (segmentation_params, "feature enabled",
|
|
feature_enabled);
|
|
json_object_set_array_member (segmentation_params, "feature data",
|
|
feature_data);
|
|
json_object_set_int_member (segmentation_params, "seg id pre skip",
|
|
frame_header->segmentation_params.seg_id_pre_skip);
|
|
json_object_set_int_member (segmentation_params, "last active seg id",
|
|
frame_header->segmentation_params.last_active_seg_id);
|
|
json_object_set_object_member (hdr, "segmentation params",
|
|
segmentation_params);
|
|
|
|
tile_info = json_object_new ();
|
|
json_object_set_int_member (tile_info, "uniform tile spacing flag",
|
|
frame_header->tile_info.uniform_tile_spacing_flag);
|
|
json_object_set_int_member (tile_info, "increment tile rows log2",
|
|
frame_header->tile_info.increment_tile_rows_log2);
|
|
width_in_sbs_minus_1 = json_array_new ();
|
|
height_in_sbs_minus_1 = json_array_new ();
|
|
for (i = 0; i < GST_AV1_MAX_TILE_COLS; i++) {
|
|
json_array_add_int_element (width_in_sbs_minus_1,
|
|
frame_header->tile_info.width_in_sbs_minus_1[i]);
|
|
json_array_add_int_element (height_in_sbs_minus_1,
|
|
frame_header->tile_info.height_in_sbs_minus_1[i]);
|
|
}
|
|
json_object_set_array_member (tile_info, "width in sbs minus 1",
|
|
width_in_sbs_minus_1);
|
|
json_object_set_array_member (tile_info, "height in sbs minus 1",
|
|
height_in_sbs_minus_1);
|
|
json_object_set_int_member (tile_info, "tile size bytes minus 1",
|
|
frame_header->tile_info.tile_size_bytes_minus_1);
|
|
json_object_set_int_member (tile_info, "context update tile id",
|
|
frame_header->tile_info.context_update_tile_id);
|
|
mi_col_starts = json_array_new ();
|
|
mi_row_starts = json_array_new ();
|
|
for (i = 0; i < GST_AV1_MAX_TILE_COLS + 1; i++) {
|
|
json_array_add_int_element (mi_col_starts,
|
|
frame_header->tile_info.mi_col_starts[i]);
|
|
json_array_add_int_element (mi_row_starts,
|
|
frame_header->tile_info.mi_row_starts[i]);
|
|
}
|
|
json_object_set_array_member (tile_info, "mi col starts", mi_col_starts);
|
|
json_object_set_array_member (tile_info, "mi row starts", mi_row_starts);
|
|
json_object_set_int_member (tile_info, "tile cols log2",
|
|
frame_header->tile_info.tile_cols_log2);
|
|
json_object_set_int_member (tile_info, "tile cols",
|
|
frame_header->tile_info.tile_cols);
|
|
json_object_set_int_member (tile_info, "tile rows log2",
|
|
frame_header->tile_info.tile_rows_log2);
|
|
json_object_set_int_member (tile_info, "tile rows",
|
|
frame_header->tile_info.tile_rows);
|
|
json_object_set_int_member (tile_info, "tile size bytes",
|
|
frame_header->tile_info.tile_size_bytes);
|
|
json_object_set_object_member (hdr, "tile_info", tile_info);
|
|
|
|
cdef_params = json_object_new ();
|
|
json_object_set_int_member (cdef_params, "cdef damping",
|
|
frame_header->cdef_params.cdef_damping);
|
|
json_object_set_int_member (cdef_params, "cdef bits",
|
|
frame_header->cdef_params.cdef_bits);
|
|
cdef_y_pri_strength = json_array_new ();
|
|
cdef_y_sec_strength = json_array_new ();
|
|
cdef_uv_pri_strength = json_array_new ();
|
|
cdef_uv_sec_strength = json_array_new ();
|
|
for (i = 0; i < GST_AV1_CDEF_MAX; i++) {
|
|
json_array_add_int_element (cdef_y_pri_strength,
|
|
frame_header->cdef_params.cdef_y_pri_strength[i]);
|
|
json_array_add_int_element (cdef_y_sec_strength,
|
|
frame_header->cdef_params.cdef_y_sec_strength[i]);
|
|
json_array_add_int_element (cdef_uv_pri_strength,
|
|
frame_header->cdef_params.cdef_uv_pri_strength[i]);
|
|
json_array_add_int_element (cdef_uv_sec_strength,
|
|
frame_header->cdef_params.cdef_uv_sec_strength[i]);
|
|
}
|
|
json_object_set_array_member (cdef_params, "cdef y pri strength",
|
|
cdef_y_pri_strength);
|
|
json_object_set_array_member (cdef_params, "cdef y sec strength",
|
|
cdef_y_sec_strength);
|
|
json_object_set_array_member (cdef_params, "cdef uv pri_strength",
|
|
cdef_uv_pri_strength);
|
|
json_object_set_array_member (cdef_params, "cdef uv sec_strength",
|
|
cdef_uv_sec_strength);
|
|
json_object_set_object_member (hdr, "cdef params", cdef_params);
|
|
|
|
loop_restoration_params = json_object_new ();
|
|
json_object_set_int_member (loop_restoration_params, "lr unit shift",
|
|
frame_header->loop_restoration_params.lr_unit_shift);
|
|
json_object_set_int_member (loop_restoration_params, "lr uv shift",
|
|
frame_header->loop_restoration_params.lr_uv_shift);
|
|
frame_restoration_type = json_array_new ();
|
|
loop_restoration_size = json_array_new ();
|
|
for (i = 0; i < GST_AV1_MAX_NUM_PLANES; i++) {
|
|
json_array_add_int_element (frame_restoration_type,
|
|
frame_header->loop_restoration_params.frame_restoration_type[i]);
|
|
json_array_add_int_element (loop_restoration_size,
|
|
frame_header->loop_restoration_params.loop_restoration_size[i]);
|
|
}
|
|
json_object_set_array_member (loop_restoration_params,
|
|
"frame restoration type", frame_restoration_type);
|
|
json_object_set_array_member (loop_restoration_params,
|
|
"loop restoration size", loop_restoration_size);
|
|
json_object_set_int_member (loop_restoration_params, "uses lr",
|
|
frame_header->loop_restoration_params.uses_lr);
|
|
json_object_set_object_member (hdr, "loop restoration params",
|
|
loop_restoration_params);
|
|
|
|
json_object_set_boolean_member (hdr, "tx mode select",
|
|
frame_header->tx_mode_select);
|
|
json_object_set_boolean_member (hdr, "skip mode present",
|
|
frame_header->skip_mode_present);
|
|
json_object_set_boolean_member (hdr, "reference select",
|
|
frame_header->reference_select);
|
|
|
|
global_motion_params = json_object_new ();
|
|
is_global = json_array_new ();
|
|
is_rot_zoom = json_array_new ();
|
|
is_translation = json_array_new ();
|
|
gm_params = json_array_new ();
|
|
gm_type = json_array_new ();
|
|
invalid = json_array_new ();
|
|
for (i = 0; i < GST_AV1_NUM_REF_FRAMES; i++) {
|
|
json_array_add_boolean_element (is_global,
|
|
frame_header->global_motion_params.is_global[i]);
|
|
json_array_add_boolean_element (is_rot_zoom,
|
|
frame_header->global_motion_params.is_rot_zoom[i]);
|
|
json_array_add_boolean_element (is_translation,
|
|
frame_header->global_motion_params.is_translation[i]);
|
|
for (j = 0; j < 6; j++)
|
|
json_array_add_int_element (gm_params,
|
|
frame_header->global_motion_params.gm_params[i][j]);
|
|
json_array_add_int_element (gm_type,
|
|
frame_header->global_motion_params.gm_type[i]);
|
|
json_array_add_boolean_element (invalid,
|
|
frame_header->global_motion_params.invalid[i]);
|
|
}
|
|
json_object_set_array_member (global_motion_params, "is global", is_global);
|
|
json_object_set_array_member (global_motion_params, "is rot zoom",
|
|
is_rot_zoom);
|
|
json_object_set_array_member (global_motion_params, "is translation",
|
|
is_translation);
|
|
json_object_set_array_member (global_motion_params, "gm params", gm_params);
|
|
json_object_set_array_member (global_motion_params, "gm type", gm_type);
|
|
json_object_set_array_member (global_motion_params, "invalid", invalid);
|
|
json_object_set_object_member (hdr, "global motion params",
|
|
global_motion_params);
|
|
|
|
film_grain_params = json_object_new ();
|
|
json_object_set_boolean_member (film_grain_params, "apply grain",
|
|
frame_header->film_grain_params.apply_grain);
|
|
json_object_set_int_member (film_grain_params, "grain seed",
|
|
frame_header->film_grain_params.grain_seed);
|
|
json_object_set_boolean_member (film_grain_params, "update grain",
|
|
frame_header->film_grain_params.update_grain);
|
|
json_object_set_int_member (film_grain_params, "film grain params ref idx",
|
|
frame_header->film_grain_params.film_grain_params_ref_idx);
|
|
json_object_set_int_member (film_grain_params, "num y points",
|
|
frame_header->film_grain_params.num_y_points);
|
|
point_y_value = json_array_new ();
|
|
point_y_scaling = json_array_new ();
|
|
for (i = 0; i < GST_AV1_MAX_NUM_Y_POINTS; i++) {
|
|
json_array_add_int_element (point_y_value,
|
|
frame_header->film_grain_params.point_y_value[i]);
|
|
json_array_add_int_element (point_y_scaling,
|
|
frame_header->film_grain_params.point_y_scaling[i]);
|
|
}
|
|
json_object_set_array_member (film_grain_params, "point y value",
|
|
point_y_value);
|
|
json_object_set_array_member (film_grain_params, "point y scaling",
|
|
point_y_scaling);
|
|
json_object_set_int_member (film_grain_params, "chroma scaling from luma",
|
|
frame_header->film_grain_params.chroma_scaling_from_luma);
|
|
json_object_set_int_member (film_grain_params, "num cb points",
|
|
frame_header->film_grain_params.num_cb_points);
|
|
point_cb_value = json_array_new ();
|
|
point_cb_scaling = json_array_new ();
|
|
for (i = 0; i < GST_AV1_MAX_NUM_CB_POINTS; i++) {
|
|
json_array_add_int_element (point_cb_value,
|
|
frame_header->film_grain_params.point_cb_value[i]);
|
|
json_array_add_int_element (point_cb_scaling,
|
|
frame_header->film_grain_params.point_cb_scaling[i]);
|
|
}
|
|
json_object_set_array_member (film_grain_params, "point cb value",
|
|
point_cb_value);
|
|
json_object_set_array_member (film_grain_params, "point cb scaling",
|
|
point_cb_scaling);
|
|
json_object_set_int_member (film_grain_params, "num cr points",
|
|
frame_header->film_grain_params.num_cr_points);
|
|
point_cr_value = json_array_new ();
|
|
point_cr_scaling = json_array_new ();
|
|
for (i = 0; i < GST_AV1_MAX_NUM_CR_POINTS; i++) {
|
|
json_array_add_int_element (point_cr_value,
|
|
frame_header->film_grain_params.point_cr_value[i]);
|
|
json_array_add_int_element (point_cr_scaling,
|
|
frame_header->film_grain_params.point_cr_scaling[i]);
|
|
}
|
|
json_object_set_array_member (film_grain_params, "point cr value",
|
|
point_cr_value);
|
|
json_object_set_array_member (film_grain_params, "point cr scaling",
|
|
point_cr_scaling);
|
|
json_object_set_int_member (film_grain_params, "grain scaling minus 8",
|
|
frame_header->film_grain_params.grain_scaling_minus_8);
|
|
json_object_set_int_member (film_grain_params, "ar coeff lag",
|
|
frame_header->film_grain_params.ar_coeff_lag);
|
|
ar_coeffs_y_plus_128 = json_array_new ();
|
|
ar_coeffs_cb_plus_128 = json_array_new ();
|
|
ar_coeffs_cr_plus_128 = json_array_new ();
|
|
for (i = 0; i < GST_AV1_MAX_NUM_POS_LUMA; i++) {
|
|
json_array_add_int_element (ar_coeffs_y_plus_128,
|
|
frame_header->film_grain_params.ar_coeffs_y_plus_128[i]);
|
|
json_array_add_int_element (ar_coeffs_cb_plus_128,
|
|
frame_header->film_grain_params.ar_coeffs_cb_plus_128[i]);
|
|
json_array_add_int_element (ar_coeffs_cr_plus_128,
|
|
frame_header->film_grain_params.ar_coeffs_cr_plus_128[i]);
|
|
}
|
|
json_object_set_array_member (film_grain_params, "ar coeffs y plus 128",
|
|
ar_coeffs_y_plus_128);
|
|
json_object_set_array_member (film_grain_params, "ar coeffs cb plus 128",
|
|
ar_coeffs_cb_plus_128);
|
|
json_object_set_array_member (film_grain_params, "ar coeffs cr plus 128",
|
|
ar_coeffs_cr_plus_128);
|
|
json_object_set_int_member (film_grain_params, "ar coeff shift minus 6",
|
|
frame_header->film_grain_params.ar_coeff_shift_minus_6);
|
|
json_object_set_int_member (film_grain_params, "grain scale shift",
|
|
frame_header->film_grain_params.grain_scale_shift);
|
|
json_object_set_int_member (film_grain_params, "cb mult",
|
|
frame_header->film_grain_params.cb_mult);
|
|
json_object_set_int_member (film_grain_params, "cb luma mult",
|
|
frame_header->film_grain_params.cb_luma_mult);
|
|
json_object_set_int_member (film_grain_params, "cb offset",
|
|
frame_header->film_grain_params.cb_offset);
|
|
json_object_set_int_member (film_grain_params, "cr mult",
|
|
frame_header->film_grain_params.cr_mult);
|
|
json_object_set_int_member (film_grain_params, "cr luma mult",
|
|
frame_header->film_grain_params.cr_luma_mult);
|
|
json_object_set_int_member (film_grain_params, "cr offset",
|
|
frame_header->film_grain_params.cr_offset);
|
|
json_object_set_boolean_member (film_grain_params, "overlap flag",
|
|
frame_header->film_grain_params.overlap_flag);
|
|
json_object_set_boolean_member (film_grain_params, "clip to restricted range",
|
|
frame_header->film_grain_params.clip_to_restricted_range);
|
|
json_object_set_object_member (hdr, "film grain params", film_grain_params);
|
|
|
|
json_object_set_int_member (hdr, "superres denom",
|
|
frame_header->superres_denom);
|
|
json_object_set_int_member (hdr, "frame is intra",
|
|
frame_header->frame_is_intra);
|
|
|
|
order_hints = json_array_new ();
|
|
ref_frame_sign_bias = json_array_new ();
|
|
for (i = 0; i < GST_AV1_NUM_REF_FRAMES; i++) {
|
|
json_array_add_int_element (order_hints, frame_header->order_hints[i]);
|
|
json_array_add_int_element (ref_frame_sign_bias,
|
|
frame_header->ref_frame_sign_bias[i]);
|
|
}
|
|
json_object_set_array_member (hdr, "order hints", order_hints);
|
|
json_object_set_array_member (hdr, "ref frame sign bias",
|
|
ref_frame_sign_bias);
|
|
|
|
json_object_set_int_member (hdr, "coded lossless",
|
|
frame_header->coded_lossless);
|
|
json_object_set_int_member (hdr, "all lossless", frame_header->all_lossless);
|
|
|
|
lossless_array = json_array_new ();
|
|
for (i = 0; i < GST_AV1_MAX_SEGMENTS; i++)
|
|
json_array_add_int_element (lossless_array,
|
|
frame_header->lossless_array[i]);
|
|
json_object_set_array_member (hdr, "lossless array", lossless_array);
|
|
|
|
seg_qm_level = json_array_new ();
|
|
for (i = 0; i < 3; i++)
|
|
for (j = 0; j < GST_AV1_MAX_SEGMENTS; j++)
|
|
json_array_add_int_element (seg_qm_level,
|
|
frame_header->seg_qm_Level[i][j]);
|
|
json_object_set_array_member (hdr, "seg qm level", seg_qm_level);
|
|
|
|
json_object_set_int_member (hdr, "upscaled width",
|
|
frame_header->upscaled_width);
|
|
json_object_set_int_member (hdr, "frame width", frame_header->frame_width);
|
|
json_object_set_int_member (hdr, "frame height", frame_header->frame_height);
|
|
json_object_set_int_member (hdr, "render width", frame_header->render_width);
|
|
json_object_set_int_member (hdr, "render height",
|
|
frame_header->render_height);
|
|
json_object_set_int_member (hdr, "tx mode", frame_header->tx_mode);
|
|
|
|
skip_mode_frame = json_array_new ();
|
|
json_array_add_int_element (skip_mode_frame,
|
|
frame_header->skip_mode_frame[0]);
|
|
json_array_add_int_element (skip_mode_frame,
|
|
frame_header->skip_mode_frame[1]);
|
|
json_object_set_array_member (hdr, "skip mode frame", skip_mode_frame);
|
|
|
|
json_object_set_object_member (json, "frame header", hdr);
|
|
}
|
|
|
|
static GstAV1ParserResult
|
|
gst_av1_2_json_handle_one_obu (GstAV12json * self, GstAV1OBU * obu)
|
|
{
|
|
GstAV1ParserResult pres = GST_AV1_PARSER_OK;
|
|
GstAV1FrameHeaderOBU frame_header;
|
|
GstAV1FrameOBU frame;
|
|
|
|
switch (obu->obu_type) {
|
|
case GST_AV1_OBU_TEMPORAL_DELIMITER:
|
|
pres = gst_av1_parser_parse_temporal_delimiter_obu (self->parser, obu);
|
|
break;
|
|
|
|
case GST_AV1_OBU_SEQUENCE_HEADER:
|
|
{
|
|
GstAV1SequenceHeaderOBU seq_header;
|
|
|
|
pres = gst_av1_parser_parse_sequence_header_obu (self->parser,
|
|
obu, &seq_header);
|
|
|
|
if (pres == GST_AV1_PARSER_OK)
|
|
gst_av1_2_json_sequence_header (self, &seq_header);
|
|
break;
|
|
}
|
|
|
|
case GST_AV1_OBU_REDUNDANT_FRAME_HEADER:
|
|
case GST_AV1_OBU_FRAME_HEADER:
|
|
pres = gst_av1_parser_parse_frame_header_obu (self->parser, obu,
|
|
&frame_header);
|
|
if (pres == GST_AV1_PARSER_OK)
|
|
gst_av1_2_json_frame_header (self, &frame_header);
|
|
break;
|
|
|
|
case GST_AV1_OBU_FRAME:
|
|
pres = gst_av1_parser_parse_frame_obu (self->parser, obu, &frame);
|
|
|
|
if (pres == GST_AV1_PARSER_OK)
|
|
gst_av1_2_json_frame_header (self, &frame.frame_header);
|
|
break;
|
|
|
|
case GST_AV1_OBU_METADATA:
|
|
{
|
|
GstAV1MetadataOBU metadata;
|
|
|
|
pres = gst_av1_parser_parse_metadata_obu (self->parser, obu, &metadata);
|
|
break;
|
|
}
|
|
|
|
case GST_AV1_OBU_TILE_GROUP:
|
|
{
|
|
GstAV1TileGroupOBU tile_group;
|
|
|
|
pres =
|
|
gst_av1_parser_parse_tile_group_obu (self->parser, obu, &tile_group);
|
|
break;
|
|
}
|
|
|
|
case GST_AV1_OBU_TILE_LIST:
|
|
{
|
|
GstAV1TileListOBU tile_list;
|
|
|
|
pres = gst_av1_parser_parse_tile_list_obu (self->parser, obu, &tile_list);
|
|
break;
|
|
}
|
|
|
|
case GST_AV1_OBU_PADDING:
|
|
break;
|
|
default:
|
|
GST_WARNING_OBJECT (self, "an unrecognized obu type %d", obu->obu_type);
|
|
pres = GST_AV1_PARSER_BITSTREAM_ERROR;
|
|
break;
|
|
}
|
|
|
|
if (obu->obu_type == GST_AV1_OBU_FRAME_HEADER
|
|
|| obu->obu_type == GST_AV1_OBU_FRAME
|
|
|| obu->obu_type == GST_AV1_OBU_REDUNDANT_FRAME_HEADER) {
|
|
GstAV1FrameHeaderOBU *fh = &frame_header;
|
|
|
|
if (obu->obu_type == GST_AV1_OBU_FRAME)
|
|
fh = &frame.frame_header;
|
|
|
|
if (!fh->show_existing_frame || fh->frame_type == GST_AV1_KEY_FRAME)
|
|
pres = gst_av1_parser_reference_frame_update (self->parser, fh);
|
|
}
|
|
|
|
return pres;
|
|
}
|
|
|
|
static GstFlowReturn
|
|
gst_av1_2_json_chain (GstPad * sinkpad, GstObject * object, GstBuffer * in_buf)
|
|
{
|
|
GstAV12json *self = GST_AV1_2_JSON (object);
|
|
JsonObject *json = self->json;
|
|
GstAV1ParserResult pres = GST_AV1_PARSER_OK;
|
|
GstAV1OBU obu;
|
|
GstBuffer *out_buf;
|
|
gchar *json_string;
|
|
guint32 offset = 0, consumed;
|
|
guint length;
|
|
GstMapInfo in_map, out_map;
|
|
GstFlowReturn ret = GST_FLOW_OK;
|
|
|
|
if (!gst_buffer_map (in_buf, &in_map, GST_MAP_READ)) {
|
|
GST_ERROR_OBJECT (self, "Cannot map buffer");
|
|
return GST_FLOW_ERROR;
|
|
}
|
|
|
|
while (offset < in_map.size) {
|
|
pres =
|
|
gst_av1_parser_identify_one_obu (self->parser, in_map.data + offset,
|
|
in_map.size - offset, &obu, &consumed);
|
|
|
|
if (pres != GST_AV1_PARSER_OK) {
|
|
GST_WARNING_OBJECT (self, "Cannot get OBU");
|
|
ret = GST_FLOW_ERROR;
|
|
goto unmap;
|
|
}
|
|
|
|
pres = gst_av1_2_json_handle_one_obu (self, &obu);
|
|
if (pres != GST_AV1_PARSER_OK) {
|
|
GST_WARNING_OBJECT (self, "Cannot parse frame header");
|
|
ret = GST_FLOW_ERROR;
|
|
goto unmap;
|
|
}
|
|
offset += consumed;
|
|
}
|
|
|
|
json_string = get_string_from_json_object (json);
|
|
length = strlen (json_string);
|
|
out_buf = gst_buffer_new_allocate (NULL, length, NULL);
|
|
gst_buffer_map (out_buf, &out_map, GST_MAP_WRITE);
|
|
if (length)
|
|
memcpy (&out_map.data[0], json_string, length);
|
|
gst_buffer_unmap (out_buf, &out_map);
|
|
|
|
g_free (json_string);
|
|
|
|
gst_buffer_copy_into (out_buf, in_buf,
|
|
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
|
|
GST_BUFFER_COPY_METADATA, 0, -1);
|
|
ret = gst_pad_push (self->srcpad, out_buf);
|
|
|
|
unmap:
|
|
switch (pres) {
|
|
case GST_AV1_PARSER_BITSTREAM_ERROR:
|
|
case GST_AV1_PARSER_MISSING_OBU_REFERENCE:
|
|
case GST_AV1_PARSER_NO_MORE_DATA:
|
|
if (self->use_annex_b)
|
|
gst_av1_parser_reset_annex_b (self->parser);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
gst_buffer_unmap (in_buf, &in_map);
|
|
gst_buffer_unref (in_buf);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
gst_av1_2_json_use_annexb (GstAV12json * self, GstCaps * caps)
|
|
{
|
|
if (caps && gst_caps_get_size (caps) > 0) {
|
|
GstStructure *s = gst_caps_get_structure (caps, 0);
|
|
const gchar *str_align = NULL;
|
|
const gchar *str_stream = NULL;
|
|
|
|
str_align = gst_structure_get_string (s, "alignment");
|
|
str_stream = gst_structure_get_string (s, "stream-format");
|
|
|
|
self->use_annex_b = FALSE;
|
|
if (str_stream && g_strcmp0 (str_stream, "annexb") == 0)
|
|
if (str_align && g_strcmp0 (str_align, "tu") == 0) {
|
|
self->use_annex_b = TRUE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
gst_av1_parser_reset (self->parser, self->use_annex_b);
|
|
}
|
|
|
|
|
|
static gboolean
|
|
gst_av1_2_json_set_caps (GstAV12json * self, GstCaps * caps)
|
|
{
|
|
GstCaps *src_caps =
|
|
gst_caps_new_simple ("text/x-json", "format", G_TYPE_STRING, "av1", NULL);
|
|
GstEvent *event;
|
|
|
|
event = gst_event_new_caps (src_caps);
|
|
gst_caps_unref (src_caps);
|
|
|
|
gst_av1_2_json_use_annexb (self, caps);
|
|
|
|
return gst_pad_push_event (self->srcpad, event);
|
|
}
|
|
|
|
static gboolean
|
|
gst_av1_2_json_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|
{
|
|
GstAV12json *self = GST_AV1_2_JSON (parent);
|
|
gboolean res = TRUE;
|
|
|
|
switch (GST_EVENT_TYPE (event)) {
|
|
case GST_EVENT_CAPS:
|
|
{
|
|
GstCaps *caps;
|
|
|
|
gst_event_parse_caps (event, &caps);
|
|
res = gst_av1_2_json_set_caps (self, caps);
|
|
gst_event_unref (event);
|
|
break;
|
|
}
|
|
default:
|
|
res = gst_pad_event_default (pad, parent, event);
|
|
break;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static void
|
|
gst_av1_2_json_class_init (GstAV12jsonClass * klass)
|
|
{
|
|
GObjectClass *gobject_class;
|
|
GstElementClass *gstelement_class;
|
|
|
|
gobject_class = (GObjectClass *) klass;
|
|
gstelement_class = (GstElementClass *) klass;
|
|
|
|
gobject_class->finalize = gst_av1_2_json_finalize;
|
|
|
|
gst_element_class_add_static_pad_template (gstelement_class, &src_factory);
|
|
gst_element_class_add_static_pad_template (gstelement_class, &sink_factory);
|
|
|
|
gst_element_class_set_static_metadata (gstelement_class, "Av12json",
|
|
"Transform",
|
|
"AV1 to json element",
|
|
"Benjamin Gaignard <benjamin.gaignard@collabora.com>");
|
|
}
|
|
|
|
static void
|
|
gst_av1_2_json_init (GstAV12json * self)
|
|
{
|
|
self->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
|
|
gst_pad_set_chain_function (self->sinkpad, gst_av1_2_json_chain);
|
|
gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
|
|
gst_pad_set_event_function (self->sinkpad,
|
|
GST_DEBUG_FUNCPTR (gst_av1_2_json_sink_event));
|
|
|
|
self->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
|
|
gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
|
|
|
|
self->json = json_object_new ();
|
|
|
|
self->parser = gst_av1_parser_new ();
|
|
gst_av1_parser_reset (self->parser, FALSE);
|
|
}
|