Re: [FFmpeg-devel] [PATCH v2 4/5] avformat/chromaprint: Fix writing raw fingerprint
On 16-10-2019 01:21 AM, Gyan wrote: On 16-10-2019 01:11 AM, Andriy Gelman wrote: On Sun, 06. Oct 01:49, Andriy Gelman wrote: From: Andriy Gelman The pointer fp after the call to chromaprint_get_raw_fingerpoint() points to an array of uint32_t whereas the current code assumed just a char stream. Thus when writing the raw fingerprint, the output would be truncated by a factor of 4. This is fixed in the commit. For reference the declaration of the function from chromaprint.h is: int chromaprint_get_raw_fingerprint(ChromaprintContext *ctx, uint32_t **fingerprint, int *size); --- libavformat/chromaprint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/chromaprint.c b/libavformat/chromaprint.c index a4c0b97d99..faa92ca0db 100644 --- a/libavformat/chromaprint.c +++ b/libavformat/chromaprint.c @@ -136,7 +136,7 @@ static int write_trailer(AVFormatContext *s) switch (cpr->fp_format) { case FINGERPRINT_RAW: - avio_write(pb, fp, size); + avio_write(pb, fp, size * 4); //fp points to array of uint32_t break; case FINGERPRINT_COMPRESSED: case FINGERPRINT_BASE64: -- 2.23.0 ping Will check and apply. Pushed as e14f5fd0a6983838b5fe3c6ad1c2ec2f2d8e49df Thanks, Gyan ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/4] avfilter/dnn: get the data type of network output from dnn execution result
so, we can make a filter more general to accept different network models, by adding a data type convertion after getting data from network. After we add dt field into struct DNNData, it becomes the same as DNNInputData, so merge them with one struct: DNNData. Signed-off-by: Guo, Yejun --- libavfilter/dnn/dnn_backend_native.c | 3 ++- libavfilter/dnn/dnn_backend_native_layer_conv2d.c | 1 + libavfilter/dnn/dnn_backend_native_layer_depth2space.c | 1 + libavfilter/dnn/dnn_backend_native_layer_pad.c | 1 + libavfilter/dnn/dnn_backend_tf.c | 5 +++-- libavfilter/dnn_interface.h| 9 ++--- libavfilter/vf_derain.c| 4 ++-- libavfilter/vf_sr.c| 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libavfilter/dnn/dnn_backend_native.c b/libavfilter/dnn/dnn_backend_native.c index ff280b5..add1db4 100644 --- a/libavfilter/dnn/dnn_backend_native.c +++ b/libavfilter/dnn/dnn_backend_native.c @@ -28,7 +28,7 @@ #include "dnn_backend_native_layer_conv2d.h" #include "dnn_backend_native_layers.h" -static DNNReturnType set_input_output_native(void *model, DNNInputData *input, const char *input_name, const char **output_names, uint32_t nb_output) +static DNNReturnType set_input_output_native(void *model, DNNData *input, const char *input_name, const char **output_names, uint32_t nb_output) { ConvolutionalNetwork *network = (ConvolutionalNetwork *)model; DnnOperand *oprd = NULL; @@ -263,6 +263,7 @@ DNNReturnType ff_dnn_execute_model_native(const DNNModel *model, DNNData *output outputs[i].height = oprd->dims[1]; outputs[i].width = oprd->dims[2]; outputs[i].channels = oprd->dims[3]; +outputs[i].dt = oprd->data_type; } return DNN_SUCCESS; diff --git a/libavfilter/dnn/dnn_backend_native_layer_conv2d.c b/libavfilter/dnn/dnn_backend_native_layer_conv2d.c index 6ec0fa7..7b29697 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_conv2d.c +++ b/libavfilter/dnn/dnn_backend_native_layer_conv2d.c @@ -106,6 +106,7 @@ int dnn_execute_layer_conv2d(DnnOperand *operands, const int32_t *input_operand_ output_operand->dims[1] = height - pad_size * 2; output_operand->dims[2] = width - pad_size * 2; output_operand->dims[3] = conv_params->output_num; +output_operand->data_type = operands[input_operand_index].data_type; output_operand->length = calculate_operand_data_length(output_operand); output_operand->data = av_realloc(output_operand->data, output_operand->length); if (!output_operand->data) diff --git a/libavfilter/dnn/dnn_backend_native_layer_depth2space.c b/libavfilter/dnn/dnn_backend_native_layer_depth2space.c index 174676e..7dab19d 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_depth2space.c +++ b/libavfilter/dnn/dnn_backend_native_layer_depth2space.c @@ -69,6 +69,7 @@ int dnn_execute_layer_depth2space(DnnOperand *operands, const int32_t *input_ope output_operand->dims[1] = height * block_size; output_operand->dims[2] = width * block_size; output_operand->dims[3] = new_channels; +output_operand->data_type = operands[input_operand_index].data_type; output_operand->length = calculate_operand_data_length(output_operand); output_operand->data = av_realloc(output_operand->data, output_operand->length); if (!output_operand->data) diff --git a/libavfilter/dnn/dnn_backend_native_layer_pad.c b/libavfilter/dnn/dnn_backend_native_layer_pad.c index 8fa35de..8e5959b 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_pad.c +++ b/libavfilter/dnn/dnn_backend_native_layer_pad.c @@ -105,6 +105,7 @@ int dnn_execute_layer_pad(DnnOperand *operands, const int32_t *input_operand_ind output_operand->dims[1] = new_height; output_operand->dims[2] = new_width; output_operand->dims[3] = new_channel; +output_operand->data_type = operands[input_operand_index].data_type; output_operand->length = calculate_operand_data_length(output_operand); output_operand->data = av_realloc(output_operand->data, output_operand->length); if (!output_operand->data) diff --git a/libavfilter/dnn/dnn_backend_tf.c b/libavfilter/dnn/dnn_backend_tf.c index c8dff51..ed91d05 100644 --- a/libavfilter/dnn/dnn_backend_tf.c +++ b/libavfilter/dnn/dnn_backend_tf.c @@ -83,7 +83,7 @@ static TF_Buffer *read_graph(const char *model_filename) return graph_buf; } -static TF_Tensor *allocate_input_tensor(const DNNInputData *input) +static TF_Tensor *allocate_input_tensor(const DNNData *input) { TF_DataType dt; size_t size; @@ -105,7 +105,7 @@ static TF_Tensor *allocate_input_tensor(const DNNInputData *input) input_dims[1] * input_dims[2] * input_dims[3] * size); } -static DNNReturnType set_input_output_tf(void *model, DNNInputData *input, const char *input_name, const char **output_names,
[FFmpeg-devel] [PATCH 4/4] avfilter: add a generic filter for rgb proccessing with dnn networks
This filter accepts all the dnn networks which do image processing on RGB-based format. Currently, frame with formats rgb24 and bgr24 are supported. Other formats such as gray and YUV can be supported in separated filters. The dnn network can accept RGB data in float32 or uint8 format. And the dnn network can change frame size. Let's take an example with the following python script. This script halves the value of the first channel of the pixel. import tensorflow as tf import numpy as np import scipy.misc in_img = scipy.misc.imread('in.bmp') in_img = in_img.astype(np.float32)/255.0 in_data = in_img[np.newaxis, :] filter_data = np.array([0.5, 0, 0, 0, 1., 0, 0, 0, 1.]).reshape(1,1,3,3).astype(np.float32) filter = tf.Variable(filter_data) x = tf.placeholder(tf.float32, shape=[1, None, None, 3], name='dnn_in') y = tf.nn.conv2d(x, filter, strides=[1, 1, 1, 1], padding='VALID', name='dnn_out') sess=tf.Session() sess.run(tf.global_variables_initializer()) output = sess.run(y, feed_dict={x: in_data}) graph_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def, ['dnn_out']) tf.train.write_graph(graph_def, '.', 'halve_first_channel.pb', as_text=False) output = output * 255.0 output = output.astype(np.uint8) scipy.misc.imsave("out.bmp", np.squeeze(output)) - generate halve_first_channel.pb with the above script - generate halve_first_channel.model with tools/python/convert.py - try with following commands ./ffmpeg -i input.jpg -vf dnn_rgb_processing=model=halve_first_channel.model:input=dnn_in:output=dnn_out:fmt=rgb24:dnn_backend=native -y out.native.png ./ffmpeg -i input.jpg -vf dnn_rgb_processing=model=halve_first_channel.pb:input=dnn_in:output=dnn_out:fmt=rgb24:dnn_backend=tensorflow -y out.tf.png Signed-off-by: Guo, Yejun --- configure | 1 + doc/filters.texi| 46 ++ libavfilter/Makefile| 2 + libavfilter/allfilters.c| 1 + libavfilter/dnn_filter_utils.c | 81 +++ libavfilter/dnn_filter_utils.h | 35 + libavfilter/vf_dnn_rgb_processing.c | 276 7 files changed, 442 insertions(+) create mode 100644 libavfilter/dnn_filter_utils.c create mode 100644 libavfilter/dnn_filter_utils.h create mode 100644 libavfilter/vf_dnn_rgb_processing.c diff --git a/configure b/configure index 8413826..b8619f0 100755 --- a/configure +++ b/configure @@ -3460,6 +3460,7 @@ derain_filter_select="dnn" deshake_filter_select="pixelutils" deshake_opencl_filter_deps="opencl" dilation_opencl_filter_deps="opencl" +dnn_rgb_processing_filter_select="dnn" drawtext_filter_deps="libfreetype" drawtext_filter_suggest="libfontconfig libfribidi" elbg_filter_deps="avcodec" diff --git a/doc/filters.texi b/doc/filters.texi index 6865f0f..21e9aa8 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -8877,6 +8877,52 @@ ffmpeg -i INPUT -f lavfi -i nullsrc=hd720,geq='r=128+80*(sin(sqrt((X-W/2)*(X-W/2 @end example @end itemize +@section dnn_rgb_processing + +Do image processing with deep neural networks for RGB-based format. The format of network +input and output can be RGB or BGR, the data type of each color channel cab be uint8 or float32. +The input format and output format should be same, the data type can be same or different. +The network can change the frame size. + +The filter accepts the following options: + +@table @option +@item dnn_backend +Specify which DNN backend to use for model loading and execution. This option accepts +the following values: + +@table @samp +@item native +Native implementation of DNN loading and execution. + +@item tensorflow +TensorFlow backend. To enable this backend you +need to install the TensorFlow for C library (see +@url{https://www.tensorflow.org/install/install_c}) and configure FFmpeg with +@code{--enable-libtensorflow} +@end table + +Default value is @samp{native}. + +@item model +Set path to model file specifying network architecture and its parameters. +Note that different backends use different file formats. TensorFlow and native +backend can load files for only its format. + +Native model file (.model) can be generated from TensorFlow model file (.pb) by using tools/python/convert.py + +@item input +Set the input name of the dnn network. + +@item output +Set the output name of the dnn network. + +@item fmt +Set the pixel format for the Frame. Allowed values are @code{AV_PIX_FMT_RGB24}, and @code{AV_PIX_FMT_BGR24}. +Default value is @code{AV_PIX_FMT_RGB24}. + +@end table + @section drawbox Draw a colored box on the input image. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 16bb8cd..2f612d7 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -27,6 +27,7 @@ OBJS-$(HAVE_THREADS) += pthread.o # subsystems OBJS-$(CONFIG_QSVVPP)+= qsvvpp.o OBJS-$(CONFIG_SCENE_SAD) += scene_sad.o +OBJS-$(CONFIG_DNN)
[FFmpeg-devel] [PATCH 1/4] dnn: add tf.nn.conv2d support for native model
Unlike other tf.*.conv2d layers, tf.nn.conv2d does not create many nodes (within a scope) in the graph, it just acts like other layers. tf.nn.conv2d only creates one node in the graph, and no internal nodes such as 'kernel' are created. The format of native model file is also changed, a flag named has_bias is added, so change the version number. Signed-off-by: Guo, Yejun --- libavfilter/dnn/dnn_backend_native.c | 2 +- libavfilter/dnn/dnn_backend_native_layer_conv2d.c | 37 +++- libavfilter/dnn/dnn_backend_native_layer_conv2d.h | 1 + tests/dnn/dnn-layer-conv2d-test.c | 2 + tools/python/convert_from_tensorflow.py | 54 --- tools/python/convert_header.py| 4 +- 6 files changed, 82 insertions(+), 18 deletions(-) diff --git a/libavfilter/dnn/dnn_backend_native.c b/libavfilter/dnn/dnn_backend_native.c index 06b010d..ff280b5 100644 --- a/libavfilter/dnn/dnn_backend_native.c +++ b/libavfilter/dnn/dnn_backend_native.c @@ -98,7 +98,7 @@ DNNModel *ff_dnn_load_model_native(const char *model_filename) char header_expected[] = "FFMPEGDNNNATIVE"; char *buf; size_t size; -int version, header_size, major_version_expected = 0; +int version, header_size, major_version_expected = 1; ConvolutionalNetwork *network = NULL; AVIOContext *model_file_context; int file_size, dnn_size, parsed_size; diff --git a/libavfilter/dnn/dnn_backend_native_layer_conv2d.c b/libavfilter/dnn/dnn_backend_native_layer_conv2d.c index 0de8902..6ec0fa7 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_conv2d.c +++ b/libavfilter/dnn/dnn_backend_native_layer_conv2d.c @@ -38,27 +38,41 @@ int dnn_load_layer_conv2d(Layer *layer, AVIOContext *model_file_context, int fil conv_params->input_num = (int32_t)avio_rl32(model_file_context); conv_params->output_num = (int32_t)avio_rl32(model_file_context); conv_params->kernel_size = (int32_t)avio_rl32(model_file_context); +conv_params->has_bias = (int32_t)avio_rl32(model_file_context); +dnn_size += 28; + kernel_size = conv_params->input_num * conv_params->output_num * - conv_params->kernel_size * conv_params->kernel_size; -dnn_size += 24 + (kernel_size + conv_params->output_num << 2); + conv_params->kernel_size * conv_params->kernel_size; +dnn_size += kernel_size * 4; +if (conv_params->has_bias) +dnn_size += conv_params->output_num * 4; + if (dnn_size > file_size || conv_params->input_num <= 0 || conv_params->output_num <= 0 || conv_params->kernel_size <= 0){ av_freep(_params); return 0; } + conv_params->kernel = av_malloc(kernel_size * sizeof(float)); -conv_params->biases = av_malloc(conv_params->output_num * sizeof(float)); -if (!conv_params->kernel || !conv_params->biases){ -av_freep(_params->kernel); -av_freep(_params->biases); +if (!conv_params->kernel) { av_freep(_params); return 0; } -for (int i = 0; i < kernel_size; ++i){ +for (int i = 0; i < kernel_size; ++i) { conv_params->kernel[i] = av_int2float(avio_rl32(model_file_context)); } -for (int i = 0; i < conv_params->output_num; ++i){ -conv_params->biases[i] = av_int2float(avio_rl32(model_file_context)); + +conv_params->biases = NULL; +if (conv_params->has_bias) { +conv_params->biases = av_malloc(conv_params->output_num * sizeof(float)); +if (!conv_params->biases){ +av_freep(_params->kernel); +av_freep(_params); +return 0; +} +for (int i = 0; i < conv_params->output_num; ++i){ +conv_params->biases[i] = av_int2float(avio_rl32(model_file_context)); +} } layer->params = conv_params; @@ -103,7 +117,10 @@ int dnn_execute_layer_conv2d(DnnOperand *operands, const int32_t *input_operand_ for (int y = pad_size; y < height - pad_size; ++y) { for (int x = pad_size; x < width - pad_size; ++x) { for (int n_filter = 0; n_filter < conv_params->output_num; ++n_filter) { -output[n_filter] = conv_params->biases[n_filter]; +if (conv_params->has_bias) +output[n_filter] = conv_params->biases[n_filter]; +else +output[n_filter] = 0.f; for (int ch = 0; ch < conv_params->input_num; ++ch) { for (int kernel_y = 0; kernel_y < conv_params->kernel_size; ++kernel_y) { diff --git a/libavfilter/dnn/dnn_backend_native_layer_conv2d.h b/libavfilter/dnn/dnn_backend_native_layer_conv2d.h index db90b2b..bf87264 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_conv2d.h +++ b/libavfilter/dnn/dnn_backend_native_layer_conv2d.h @@ -31,6 +31,7 @@ typedef struct ConvolutionalParams{ DNNActivationFunc activation; DNNConvPaddingParam padding_method; int32_t dilation; +
[FFmpeg-devel] [PATCH 3/4] avfilter/dnn: add a new interface to query dnn model's input info
to support dnn networks more general, we need to know the input info of the dnn model. background: The data type of dnn model's input could be float32, uint8 or fp16, etc. And the w/h of input image could be fixed or variable. Signed-off-by: Guo, Yejun --- libavfilter/dnn/dnn_backend_native.c | 24 +++- libavfilter/dnn/dnn_backend_tf.c | 32 libavfilter/dnn_interface.h | 3 +++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/libavfilter/dnn/dnn_backend_native.c b/libavfilter/dnn/dnn_backend_native.c index add1db4..94634b3 100644 --- a/libavfilter/dnn/dnn_backend_native.c +++ b/libavfilter/dnn/dnn_backend_native.c @@ -28,6 +28,28 @@ #include "dnn_backend_native_layer_conv2d.h" #include "dnn_backend_native_layers.h" +static DNNReturnType get_input_native(void *model, DNNData *input, const char *input_name) +{ +ConvolutionalNetwork *network = (ConvolutionalNetwork *)model; + +for (int i = 0; i < network->operands_num; ++i) { +DnnOperand *oprd = >operands[i]; +if (strcmp(oprd->name, input_name) == 0) { +if (oprd->type != DOT_INPUT) +return DNN_ERROR; +input->dt = oprd->data_type; +av_assert0(oprd->dims[0] == 1); +input->height = oprd->dims[1]; +input->width = oprd->dims[2]; +input->channels = oprd->dims[3]; +return DNN_SUCCESS; +} +} + +// do not find the input operand +return DNN_ERROR; +} + static DNNReturnType set_input_output_native(void *model, DNNData *input, const char *input_name, const char **output_names, uint32_t nb_output) { ConvolutionalNetwork *network = (ConvolutionalNetwork *)model; @@ -37,7 +59,6 @@ static DNNReturnType set_input_output_native(void *model, DNNData *input, const return DNN_ERROR; /* inputs */ -av_assert0(input->dt == DNN_FLOAT); for (int i = 0; i < network->operands_num; ++i) { oprd = >operands[i]; if (strcmp(oprd->name, input_name) == 0) { @@ -234,6 +255,7 @@ DNNModel *ff_dnn_load_model_native(const char *model_filename) } model->set_input_output = _input_output_native; +model->get_input = _input_native; return model; } diff --git a/libavfilter/dnn/dnn_backend_tf.c b/libavfilter/dnn/dnn_backend_tf.c index ed91d05..a921667 100644 --- a/libavfilter/dnn/dnn_backend_tf.c +++ b/libavfilter/dnn/dnn_backend_tf.c @@ -105,6 +105,37 @@ static TF_Tensor *allocate_input_tensor(const DNNData *input) input_dims[1] * input_dims[2] * input_dims[3] * size); } +static DNNReturnType get_input_tf(void *model, DNNData *input, const char *input_name) +{ +TFModel *tf_model = (TFModel *)model; +TF_Status *status; +int64_t dims[4]; + +TF_Output tf_output; +tf_output.oper = TF_GraphOperationByName(tf_model->graph, input_name); +if (!tf_output.oper) +return DNN_ERROR; + +tf_output.index = 0; +input->dt = TF_OperationOutputType(tf_output); + +status = TF_NewStatus(); +TF_GraphGetTensorShape(tf_model->graph, tf_output, dims, 4, status); +if (TF_GetCode(status) != TF_OK){ +TF_DeleteStatus(status); +return DNN_ERROR; +} +TF_DeleteStatus(status); + +// currently only NHWC is supported +av_assert0(dims[0] == 1); +input->height = dims[1]; +input->width = dims[2]; +input->channels = dims[3]; + +return DNN_SUCCESS; +} + static DNNReturnType set_input_output_tf(void *model, DNNData *input, const char *input_name, const char **output_names, uint32_t nb_output) { TFModel *tf_model = (TFModel *)model; @@ -568,6 +599,7 @@ DNNModel *ff_dnn_load_model_tf(const char *model_filename) model->model = (void *)tf_model; model->set_input_output = _input_output_tf; +model->get_input = _input_tf; return model; } diff --git a/libavfilter/dnn_interface.h b/libavfilter/dnn_interface.h index fdefcb7..b20e5c8 100644 --- a/libavfilter/dnn_interface.h +++ b/libavfilter/dnn_interface.h @@ -43,6 +43,9 @@ typedef struct DNNData{ typedef struct DNNModel{ // Stores model that can be different for different backends. void *model; +// Gets model input information +// Just reuse struct DNNData here, actually the DNNData.data field is not needed. +DNNReturnType (*get_input)(void *model, DNNData *input, const char *input_name); // Sets model input and output. // Should be called at least once before model execution. DNNReturnType (*set_input_output)(void *model, DNNData *input, const char *input_name, const char **output_names, uint32_t nb_output); -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 2/3] fate: Add tests for hevc_mp4annexb bsf
From: Andriy Gelman Test hevc-mp4annexb-pps: Test contains 64 PPS that are signalled in extradata. Different PPS are referenced by the VCL nal units during the mp4 to annexb conversion. Test hevc-mp4annexb-sps: Access units contain PPS that reference different cached SPS nal units. --- tests/fate/hevc.mak | 22 ++ 1 file changed, 22 insertions(+) diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index 4f812b0834..3209d581cd 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -240,6 +240,28 @@ fate-hevc-bsf-mp4toannexb: CMD = md5 -i $(TARGET_PATH)/tests/data/hevc-mp4.mov - fate-hevc-bsf-mp4toannexb: CMP = oneline fate-hevc-bsf-mp4toannexb: REF = 3c9d998a3aa2b9e0fb1c1f434952bf8b +tests/data/hevc-pps-mp4.mov: TAG = GEN +tests/data/hevc-pps-mp4.mov: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data + $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ + -i $(TARGET_SAMPLES)/hevc-conformance/PPS_A_qualcomm_7.bit -c copy -flags +bitexact $(TARGET_PATH)/$@ -y 2>/dev/null + +FATE_HEVC-$(call ALLYES, HEVC_DEMUXER MOV_DEMUXER HEVC_MP4TOANNEXB_BSF MOV_MUXER HEVC_MUXER) += fate-hevc-bsf-mp4toannexb-pps +fate-hevc-bsf-mp4toannexb-pps: tests/data/hevc-pps-mp4.mov +fate-hevc-bsf-mp4toannexb-pps: CMD = md5 -i $(TARGET_PATH)/tests/data/hevc-pps-mp4.mov -c:v copy -fflags +bitexact -f hevc +fate-hevc-bsf-mp4toannexb-pps: CMP = oneline +fate-hevc-bsf-mp4toannexb-pps: REF = 28ad5b4fdcb8c35ba2b1b740c761bae3 + +tests/data/hevc-sps-mp4.mov: TAG = GEN +tests/data/hevc-sps-mp4.mov: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data + $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ + -i $(TARGET_SAMPLES)/hevc-conformance/SLIST_B_Sony_8.bit -c copy -flags +bitexact $(TARGET_PATH)/$@ -y 2>/dev/null + +FATE_HEVC-$(call ALLYES, HEVC_DEMUXER MOV_DEMUXER HEVC_MP4TOANNEXB_BSF MOV_MUXER HEVC_MUXER) += fate-hevc-bsf-mp4toannexb-sps +fate-hevc-bsf-mp4toannexb-sps: tests/data/hevc-sps-mp4.mov +fate-hevc-bsf-mp4toannexb-sps: CMD = md5 -i $(TARGET_PATH)/tests/data/hevc-sps-mp4.mov -c:v copy -fflags +bitexact -f hevc +fate-hevc-bsf-mp4toannexb-sps: CMP = oneline +fate-hevc-bsf-mp4toannexb-sps: REF = 762147b37b393620eb30af7809f34bb2 + fate-hevc-skiploopfilter: CMD = framemd5 -skip_loop_filter nokey -i $(TARGET_SAMPLES)/hevc-conformance/SAO_D_Samsung_5.bit -sws_flags bitexact FATE_HEVC += fate-hevc-skiploopfilter -- 2.23.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 3/3] hevc_mp4toannexb: Parse extradata directly from HVCC format
From: Andriy Gelman Since the original extradata is in HVCC format, there is no need to segment the output extradata into nal units. --- libavcodec/hevc_mp4toannexb_bsf.c | 66 --- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/libavcodec/hevc_mp4toannexb_bsf.c b/libavcodec/hevc_mp4toannexb_bsf.c index 1ca5f13807..938e01171d 100644 --- a/libavcodec/hevc_mp4toannexb_bsf.c +++ b/libavcodec/hevc_mp4toannexb_bsf.c @@ -243,12 +243,17 @@ static int update_paramset(AVBSFContext *ctx, H2645NAL *nal) static int hevc_extradata_to_annexb(AVBSFContext *ctx) { +HEVCBSFContext *s = ctx->priv_data; GetByteContext gb; int length_size, num_arrays, i, j; int ret = 0; uint8_t *new_extradata = NULL; size_t new_extradata_size = 0; +size_t start, end; + +H2645Packet pkt; +memset(, 0, sizeof(H2645Packet)); /* in case goto fail is called before pkt is initialized*/ bytestream2_init(, ctx->par_in->extradata, ctx->par_in->extradata_size); @@ -268,6 +273,7 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx) goto fail; } +start = bytestream2_tell(); for (j = 0; j < cnt; j++) { int nalu_len = bytestream2_get_be16(); @@ -284,6 +290,32 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx) new_extradata_size += 4 + nalu_len; memset(new_extradata + new_extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); } +end = bytestream2_tell(); + +/* split extradata into nalu packets*/ +ret = ff_h2645_packet_split(, ctx->par_in->extradata + start, +end - start, ctx, 1, 2, AV_CODEC_ID_HEVC, 1, 0); +if (ret < 0) +goto fail; + +/* parse the segmented nals*/ +for (j = 0; j < pkt.nb_nals; j++) { +H2645NAL *nal = [j]; + +if (IS_PARAMSET(nal)) { +ret = update_paramset(ctx, nal); +if (ret < 0) +goto fail; +continue; +} + +if (nal->type == HEVC_NAL_SEI_PREFIX || nal->type == HEVC_NAL_SEI_SUFFIX) { +ret = append_sei_annexb(>ps.sei, nal); +if (ret < 0) +goto fail; +} +} +ff_h2645_packet_uninit(); } av_freep(>par_out->extradata); @@ -295,6 +327,7 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx) return length_size; fail: +ff_h2645_packet_uninit(); av_freep(_extradata); return ret; } @@ -302,7 +335,6 @@ fail: static int hevc_mp4toannexb_init(AVBSFContext *ctx) { HEVCBSFContext *s = ctx->priv_data; -H2645Packet pkt; int ret; if (ctx->par_in->extradata_size < MIN_HEVCC_LENGTH || @@ -310,44 +342,14 @@ static int hevc_mp4toannexb_init(AVBSFContext *ctx) AV_RB32(ctx->par_in->extradata) == 1) { av_log(ctx, AV_LOG_VERBOSE, "The input looks like it is Annex B already\n"); -return 0; } else { ret = hevc_extradata_to_annexb(ctx); if (ret < 0) return ret; s->length_size = ret; s->extradata_parsed = 1; - -memset(, 0, sizeof(H2645Packet)); -ret = ff_h2645_packet_split(, ctx->par_out->extradata, ctx->par_out->extradata_size, - ctx, 0, 0, AV_CODEC_ID_HEVC, 1, 0); -if (ret < 0) -goto done; - -for (int i = 0; i < pkt.nb_nals; ++i) { -H2645NAL *nal = [i]; - -/*current segmentation algorithm includes next 0x00 from next nal unit*/ -if (nal->raw_data[nal->raw_size - 1] == 0x00) -nal->raw_size--; - -if (IS_PARAMSET(nal)) { -ret = update_paramset(ctx, nal); -if (ret < 0) -goto done; -continue; -} - -if (nal->type == HEVC_NAL_SEI_PREFIX || nal->type == HEVC_NAL_SEI_SUFFIX) { -ret = append_sei_annexb(>ps.sei, nal); -if (ret < 0) -goto done; -} -} } -done: -ff_h2645_packet_uninit(); -return ret; +return 0; } static void ps_uninit(ParamSets *ps) -- 2.23.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 1/3] hevc_mp4toannexb: Insert correct parameter sets before IRAP
From: Andriy Gelman Fixes #7799 Currently, the mp4toannexb filter always inserts the same extradata at the start of the first IRAP unit. As in ticket #7799, this can lead to decoding errors if modified parameter sets are signalled in-band. Decoding errors/visual artifacts are also present in the following fate-suite/hevc-conformance datasets for hevc->mp4->hevc conversion: -RAP_B_Bossen_1.bit -RPS_C_ericsson_5.bit -SLIST_A_Sony_4.bit -SLIST_B_Sony_8.bit -SLIST_C_Sony_3.bit -SLIST_D_Sony_9.bit -TSKIP_A_MS_2.bit This commit solves these errors by keeping track of VPS/SPS/PPS parameter sets during the conversion. The correct combination is inserted at the start of the first IRAP. SEIs from extradata are inserted before each IRAP. This commit also makes an update to the hevc-bsf-mp4toannexb fate test since the result before this patch contained duplicate parameter sets in-band. --- libavcodec/hevc_mp4toannexb_bsf.c | 503 -- tests/fate/hevc.mak | 2 +- 2 files changed, 472 insertions(+), 33 deletions(-) diff --git a/libavcodec/hevc_mp4toannexb_bsf.c b/libavcodec/hevc_mp4toannexb_bsf.c index 09bce5b34c..1ca5f13807 100644 --- a/libavcodec/hevc_mp4toannexb_bsf.c +++ b/libavcodec/hevc_mp4toannexb_bsf.c @@ -23,19 +23,224 @@ #include "libavutil/intreadwrite.h" #include "libavutil/mem.h" +#include "libavutil/avassert.h" #include "avcodec.h" #include "bsf.h" #include "bytestream.h" #include "hevc.h" +#include "h2645_parse.h" +#include "hevc_ps.h" +#include "golomb.h" #define MIN_HEVCC_LENGTH 23 +#define PROFILE_WITHOUT_IDC_BITS88 +#define IS_IRAP(s) ((s)->type >= 16 && (s)->type <= 23) +#define IS_PARAMSET(s) ((s)->type >= 32 && (s)->type <= 34) + +/*reserved VCLs not included*/ +#define IS_VCL(s) ((s)->type <= 9 || ((s)->type >= 16 && (s)->type <= 21)) +#define HEVC_NAL_HEADER_BITS16 + +/* + * Copies data from input buffer to output buffer. Appends annexb startcode. + * out must be allocated at least out_len + in_len + write_startcode * 4. + */ +#define WRITE_NAL(out, out_len, in, in_len, write_startcode) do {\ +if ((write_startcode)) {\ +AV_WB32((out) + (out_len), 1); \ +(out_len) += 4; \ +} \ +memcpy((out) + (out_len), (in), (in_len)); \ +(out_len) += (in_len); \ +} while (0) + +typedef struct Param { +uint8_t *raw_data; /* raw data to store param set payload*/ +int raw_size; /* size of raw_data*/ +size_t allocated_size;/* allocated size of raw_data*/ +int ref; /* stores the ref of the higher level parameter set*/ +int is_signalled; /* indicates whether this param has already been signalled in the cvs*/ +} Param; + +/* modified version of HEVCParamSets to store bytestream and reference to previous level*/ +typedef struct ParamSets { +Param vps_list[HEVC_MAX_VPS_COUNT]; +Param sps_list[HEVC_MAX_SPS_COUNT]; +Param pps_list[HEVC_MAX_PPS_COUNT]; + +Param sei; /* cached SEIs from extradatat*/ +} ParamSets; typedef struct HEVCBSFContext { uint8_t length_size; int extradata_parsed; +ParamSets ps; /* cached VPS/SPS/PPS parameter sets + SEI from extradata*/ } HEVCBSFContext; +static int update_cached_paramset(AVBSFContext *ctx, Param *cached_param, + H2645NAL *nal, int ref) +{ +int ret; + +if (cached_param->raw_data && cached_param->raw_size == nal->raw_size + 4 && +!memcmp(cached_param->raw_data + 4, nal->raw_data, nal->raw_size)) { +av_log(ctx, AV_LOG_DEBUG, "NAL unit: %d. Copy already exists in parameter set.\n", nal->type); +} else { +if (nal->raw_size + 4 > cached_param->allocated_size) { +ret = av_reallocp(_param->raw_data, nal->raw_size + 4); +if (ret < 0) +return ret; +cached_param->allocated_size = nal->raw_size + 4; +} +cached_param->raw_size = 0; +WRITE_NAL(cached_param->raw_data, cached_param->raw_size, nal->raw_data, nal->raw_size, 1); +cached_param->ref = ref; +cached_param->is_signalled = 0; +av_assert1(cached_param->raw_size == nal->raw_size + 4); +} +return 0; +} + +static int parse_vps(AVBSFContext *ctx, H2645NAL *nal) +{ +int vps_id, ret; + +HEVCBSFContext *s = ctx->priv_data; +ParamSets *ps = >ps; + +GetBitContext *gb = >gb; + +vps_id = get_bits(gb, 4); + +if (get_bits_left(gb) < 0) { +av_log(ctx, AV_LOG_ERROR, "Over-read bitstream in VPS id: %d\n", vps_id); +return AVERROR_INVALIDDATA; +
[FFmpeg-devel] (no subject)
Changes in v6: - Store parameter sets with startcode - Use helper functions to reset index in GetBitContext - Replace get_ue_golomb_long by get_ue_golomb -- Andriy ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v5 1/3] hevc_mp4toannexb: Insert correct parameter sets before IRAP
Andreas, On Thu, 01. Jan 00:00, Andreas Rheinhardt wrote: > Andriy Gelman: > > From: Andriy Gelman > > > > Fixes #7799 > > > > Currently, the mp4toannexb filter always inserts the same extradata at > > the start of the first IRAP unit. As in ticket #7799, this can lead to > > decoding errors if modified parameter sets are signalled in-band. > > > > This commit keeps track of the VPS/SPS/PPS parameter sets during the > > conversion. The correct combination is inserted at the start of the > > first IRAP. SEIs from extradata are inserted before each IRAP. > > > > This commit also makes an update to the hevc-bsf-mp4toannexb fate test > > since the result before this patch contained duplicate parameter sets > > in-band. > > --- > > libavcodec/hevc_mp4toannexb_bsf.c | 488 -- > > tests/fate/hevc.mak | 2 +- > > 2 files changed, 456 insertions(+), 34 deletions(-) > > > > diff --git a/libavcodec/hevc_mp4toannexb_bsf.c > > b/libavcodec/hevc_mp4toannexb_bsf.c > > index 09bce5b34c..90a4d17d25 100644 > > --- a/libavcodec/hevc_mp4toannexb_bsf.c > > +++ b/libavcodec/hevc_mp4toannexb_bsf.c > > @@ -23,19 +23,209 @@ > > > > #include "libavutil/intreadwrite.h" > > #include "libavutil/mem.h" > > +#include "libavutil/avassert.h" > > > > #include "avcodec.h" > > #include "bsf.h" > > #include "bytestream.h" > > #include "hevc.h" > > +#include "h2645_parse.h" > > +#include "hevc_ps.h" > > +#include "golomb.h" > > > > #define MIN_HEVCC_LENGTH 23 > > +#define PROFILE_WITHOUT_IDC_BITS88 > > +#define IS_IRAP(s) ((s)->type >= 16 && (s)->type <= 23) > > +#define IS_PARAMSET(s) ((s)->type >= 32 && (s)->type <= 34) > > + > > +/*reserved VCLs not included*/ > > +#define IS_VCL(s) ((s)->type <= 9 || ((s)->type >= 16 && > > (s)->type <= 21)) > > +#define HEVC_NAL_HEADER_BITS16 > > + > > +/* > > + *Copies data from input buffer to output buffer. Appends annexb startcode. > > + *out must be allocated at least out_len + in_len + 4. > > + */ > > A space between * and the actual comment is both common and IMO more > readable. This goes for all comments. > > > +#define WRITE_NAL(out, out_len, in, in_len) do {\ > > +AV_WB32((out) + (out_len), 1); \ > > +(out_len) += 4; \ > > +memcpy((out) + (out_len), (in), (in_len)); \ > > +(out_len) += (in_len); \ > > +} while (0) > > + > > +typedef struct Param { > > +uint8_t *raw_data; /*raw data to store param set payload*/ > > +int raw_size; /*size of raw_data*/ > > +size_t allocated_size;/*allocated size of raw_data*/ > > +int ref; /*stores the ref of the higher level > > parameter set*/ > > +int is_signalled; /*indicates whether this param has already > > been signalled in the cvs*/ > > +} Param; > > + > > +/*modified version of HEVCParamSets to store bytestream and reference to > > previous level*/ > > +typedef struct ParamSets { > > +Param vps_list[HEVC_MAX_VPS_COUNT]; > > +Param sps_list[HEVC_MAX_SPS_COUNT]; > > +Param pps_list[HEVC_MAX_PPS_COUNT]; > > + > > +Param sei; /*cached SEIs from extradata in annexb format*/ > > +} ParamSets; > > > > typedef struct HEVCBSFContext { > > uint8_t length_size; > > int extradata_parsed; > > +ParamSets ps; /*cached VPS/SPS/PPS parameter sets + SEI from > > extradata*/ > > } HEVCBSFContext; > > > > +static int update_cached_paramset(AVBSFContext *ctx, Param *cached_param, > > + H2645NAL *nal, int ref) > > +{ > > +int ret; > > + > > +if (cached_param->raw_data && cached_param->raw_size == nal->raw_size > > && > > +!memcmp(cached_param->raw_data, nal->raw_data, nal->raw_size)) { > > +av_log(ctx, AV_LOG_DEBUG, "NAL unit: %d. Copy already exists in > > parameter set.\n", nal->type); > > +} else { > > +if (nal->raw_size > cached_param->allocated_size) { > > +ret = av_reallocp(_param->raw_data, nal->raw_size); > > +if (ret < 0) > > +return ret; > > +cached_param->allocated_size = nal->raw_size; > > +} > > +memcpy(cached_param->raw_data, nal->raw_data, nal->raw_size); > > You already include the start code in the SEI. Wouldn't it make sense > to do the same for parameter sets? Copying would then amount to one > big memcpy. The only complication I see is that you would have to add > a parameter to WRITE_NAL that determines whether to write a start code > or not. > > > +cached_param->raw_size = nal->raw_size; > > +cached_param->ref = ref; > > +cached_param->is_signalled = 0; > > +} > > +return 0; > > +} > > + > >
[FFmpeg-devel] [PATCH v2] avformat/matroskaenc: Move track-related fields to mkv_track
Signed-off-by: Andreas Rheinhardt --- Resending because of a merge conflict with version 2 of the memleak patch I just sent. libavformat/matroskaenc.c | 41 ++- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index b924a64b03..39c4171c05 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -96,6 +96,9 @@ typedef struct mkv_track { int has_cue; int sample_rate; int64_t sample_rate_offset; +int64_t last_timestamp; +int64_t duration; +int64_t duration_offset; int64_t codecpriv_offset; int64_t ts_offset; } mkv_track; @@ -155,11 +158,6 @@ typedef struct MatroskaMuxContext { uint32_t chapter_id_offset; int wrote_chapters; -int64_t last_track_timestamp[MAX_TRACKS]; - -int64_t *stream_durations; -int64_t *stream_duration_offsets; - int allow_raw_vfw; } MatroskaMuxContext; @@ -410,8 +408,6 @@ static void mkv_deinit(AVFormatContext *s) av_freep(>attachments); } av_freep(>tracks); -av_freep(>stream_durations); -av_freep(>stream_duration_offsets); } /** @@ -1670,7 +1666,7 @@ static int mkv_write_tags(AVFormatContext *s) tag = start_ebml_master(pb, MATROSKA_ID_SIMPLETAG, 0); put_ebml_string(pb, MATROSKA_ID_TAGNAME, "DURATION"); -mkv->stream_duration_offsets[i] = avio_tell(pb); +mkv->tracks[i].duration_offset = avio_tell(pb); // Reserve space to write duration as a 20-byte string. // 2 (ebml id) + 1 (data size) + 20 (data) @@ -1957,13 +1953,6 @@ static int mkv_write_header(AVFormatContext *s) end_ebml_master_crc32(s->pb, >info_bc, mkv); pb = s->pb; -// initialize stream_duration fields -mkv->stream_durations= av_mallocz(s->nb_streams * sizeof(int64_t)); -mkv->stream_duration_offsets = av_mallocz(s->nb_streams * sizeof(int64_t)); -if (!mkv->stream_durations || !mkv->stream_duration_offsets) { -return AVERROR(ENOMEM); -} - ret = mkv_write_tracks(s); if (ret < 0) return ret; @@ -2096,6 +2085,7 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, { MatroskaMuxContext *mkv = s->priv_data; AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; +mkv_track *track = >tracks[pkt->stream_index]; uint8_t *data = NULL, *side_data = NULL; int offset = 0, size = pkt->size, side_data_size = 0; int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; @@ -2174,10 +2164,9 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, av_free(data); if (blockid == MATROSKA_ID_BLOCK && !keyframe) { -put_ebml_sint(pb, MATROSKA_ID_BLOCKREFERENCE, - mkv->last_track_timestamp[track_number - 1]); +put_ebml_sint(pb, MATROSKA_ID_BLOCKREFERENCE, track->last_timestamp); } -mkv->last_track_timestamp[track_number - 1] = ts - mkv->cluster_pts; +track->last_timestamp = ts - mkv->cluster_pts; if (discard_padding) { put_ebml_sint(pb, MATROSKA_ID_DISCARDPADDING, discard_padding); @@ -2367,6 +2356,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ MatroskaMuxContext *mkv = s->priv_data; AVIOContext *pb = s->pb; AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; +mkv_track *track= >tracks[pkt->stream_index]; int keyframe= !!(pkt->flags & AV_PKT_FLAG_KEY); int duration= pkt->duration; int ret; @@ -2437,9 +2427,7 @@ FF_ENABLE_DEPRECATION_WARNINGS mkv->duration = FFMAX(mkv->duration, ts + duration); -if (mkv->stream_durations) -mkv->stream_durations[pkt->stream_index] = -FFMAX(mkv->stream_durations[pkt->stream_index], ts + duration); +track->duration = FFMAX(track->duration, ts + duration); return 0; } @@ -2613,20 +2601,21 @@ static int mkv_write_trailer(AVFormatContext *s) end_ebml_master_crc32(pb, >tracks_bc, mkv); // update stream durations -if (!mkv->is_live && mkv->stream_durations) { +if (!mkv->is_live) { int i; int64_t curr = avio_tell(mkv->tags_bc); for (i = 0; i < s->nb_streams; ++i) { AVStream *st = s->streams[i]; +mkv_track *track = >tracks[i]; -if (mkv->stream_duration_offsets[i] > 0) { -double duration_sec = mkv->stream_durations[i] * av_q2d(st->time_base); +if (track->duration_offset > 0) { +double duration_sec = track->duration * av_q2d(st->time_base); char duration_string[20] = ""; av_log(s, AV_LOG_DEBUG, "stream %d end duration = %" PRIu64
[FFmpeg-devel] [PATCH v2 2/2] avformat/matroskaenc: Use ffio_free_dyn_buf
instead of replicating its behaviour. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 23 ++- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 3f9bd3445d..b924a64b03 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -391,23 +391,12 @@ static void put_xiph_size(AVIOContext *pb, int size) static void mkv_deinit(AVFormatContext *s) { MatroskaMuxContext *mkv = s->priv_data; -uint8_t* buf; -if (mkv->cluster_bc) { -avio_close_dyn_buf(mkv->cluster_bc, ); -av_free(buf); -} -if (mkv->info_bc) { -avio_close_dyn_buf(mkv->info_bc, ); -av_free(buf); -} -if (mkv->tracks_bc) { -avio_close_dyn_buf(mkv->tracks_bc, ); -av_free(buf); -} -if (mkv->tags_bc) { -avio_close_dyn_buf(mkv->tags_bc, ); -av_free(buf); -} + +ffio_free_dyn_buf(>cluster_bc); +ffio_free_dyn_buf(>info_bc); +ffio_free_dyn_buf(>tracks_bc); +ffio_free_dyn_buf(>tags_bc); + if (mkv->seekhead) { av_freep(>seekhead->entries); av_freep(>seekhead); -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 1/2] avformat/matroskaenc: Fix memleak upon failure
The Matroska muxer up until now leaked memory in two scenarios: 1. If an error happened during writing the trailer, as mkv_write_trailer() returned early without cleaning up. 2. If mkv_write_header() indicated success despite an error in the underlying AVIOContext. In this case avformat_write_header() returned the IO error and according to the API the caller is not allowed to call av_write_trailer(), so that no cleanup happened for the allocations made in mkv_write_header(). This has been fixed by using a dedicated deinit function. Signed-off-by: Andreas Rheinhardt --- I wouldn't be surprised if other muxers also leaked memory in the second scenario. libavformat/matroskaenc.c | 34 -- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 37706e56c7..3f9bd3445d 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -388,7 +388,9 @@ static void put_xiph_size(AVIOContext *pb, int size) /** * Free the members allocated in the mux context. */ -static void mkv_free(MatroskaMuxContext *mkv) { +static void mkv_deinit(AVFormatContext *s) +{ +MatroskaMuxContext *mkv = s->priv_data; uint8_t* buf; if (mkv->cluster_bc) { avio_close_dyn_buf(mkv->cluster_bc, ); @@ -1875,8 +1877,7 @@ static int mkv_write_header(AVFormatContext *s) mkv->tracks = av_mallocz_array(s->nb_streams, sizeof(*mkv->tracks)); if (!mkv->tracks) { -ret = AVERROR(ENOMEM); -goto fail; +return AVERROR(ENOMEM); } ebml_header = start_ebml_master(pb, EBML_ID_HEADER, MAX_EBML_HEADER_SIZE); put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); @@ -1896,12 +1897,12 @@ static int mkv_write_header(AVFormatContext *s) // of every other currently defined level 1 element mkv->seekhead = mkv_start_seekhead(pb, mkv->segment_offset, 10); if (!mkv->seekhead) { -ret = AVERROR(ENOMEM); -goto fail; +return AVERROR(ENOMEM); } ret = mkv_add_seekhead_entry(mkv->seekhead, MATROSKA_ID_INFO, avio_tell(pb)); -if (ret < 0) goto fail; +if (ret < 0) +return ret; ret = start_ebml_master_crc32(pb, >info_bc, mkv, MATROSKA_ID_INFO); if (ret < 0) @@ -1971,38 +1972,36 @@ static int mkv_write_header(AVFormatContext *s) mkv->stream_durations= av_mallocz(s->nb_streams * sizeof(int64_t)); mkv->stream_duration_offsets = av_mallocz(s->nb_streams * sizeof(int64_t)); if (!mkv->stream_durations || !mkv->stream_duration_offsets) { -ret = AVERROR(ENOMEM); -goto fail; +return AVERROR(ENOMEM); } ret = mkv_write_tracks(s); if (ret < 0) -goto fail; +return ret; for (i = 0; i < s->nb_chapters; i++) mkv->chapter_id_offset = FFMAX(mkv->chapter_id_offset, 1LL - s->chapters[i]->id); ret = mkv_write_chapters(s); if (ret < 0) -goto fail; +return ret; if (mkv->mode != MODE_WEBM) { ret = mkv_write_attachments(s); if (ret < 0) -goto fail; +return ret; } ret = mkv_write_tags(s); if (ret < 0) -goto fail; +return ret; if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) mkv_write_seekhead(pb, mkv); mkv->cues = mkv_start_cues(mkv->segment_offset); if (!mkv->cues) { -ret = AVERROR(ENOMEM); -goto fail; +return AVERROR(ENOMEM); } if (s->metadata_header_padding > 0) { @@ -2039,9 +2038,6 @@ static int mkv_write_header(AVFormatContext *s) } return 0; -fail: -mkv_free(mkv); -return ret; } static int mkv_blockgroup_size(int pkt_size) @@ -2664,7 +2660,6 @@ static int mkv_write_trailer(AVFormatContext *s) end_ebml_master(pb, mkv->segment); } -mkv_free(mkv); return 0; } @@ -2811,6 +2806,7 @@ AVOutputFormat ff_matroska_muxer = { .video_codec = CONFIG_LIBX264_ENCODER ? AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4, .init = mkv_init, +.deinit= mkv_deinit, .write_header = mkv_write_header, .write_packet = mkv_write_flush_packet, .write_trailer = mkv_write_trailer, @@ -2845,6 +2841,7 @@ AVOutputFormat ff_webm_muxer = { .video_codec = CONFIG_LIBVPX_VP9_ENCODER? AV_CODEC_ID_VP9 : AV_CODEC_ID_VP8, .subtitle_codec= AV_CODEC_ID_WEBVTT, .init = mkv_init, +.deinit= mkv_deinit, .write_header = mkv_write_header, .write_packet = mkv_write_flush_packet, .write_trailer = mkv_write_trailer, @@ -2873,6 +2870,7 @@ AVOutputFormat ff_matroska_audio_muxer = { AV_CODEC_ID_VORBIS : AV_CODEC_ID_AC3, .video_codec = AV_CODEC_ID_NONE, .init = mkv_init, +.deinit= mkv_deinit, .write_header
Re: [FFmpeg-devel] [PATCH v1 4/4] fate/filter-video: add 10bit test for unsharp filter
On Tue, Oct 15, 2019 at 04:41:36PM +0200, Michael Niedermayer wrote: > On Mon, Oct 14, 2019 at 06:27:07PM +0800, lance.lmw...@gmail.com wrote: > > From: Limin Wang > > > > Signed-off-by: Limin Wang > > --- > > tests/fate/filter-video.mak | 3 ++ > > tests/ref/fate/filter-unsharp-yuv420p10 | 55 + > > 2 files changed, 58 insertions(+) > > create mode 100644 tests/ref/fate/filter-unsharp-yuv420p10 > > fails on mips I'll try to setup a qeum mips system later, however I update a patch for I guess it's caused by yuv420p10le. > > TESTfilter-unsharp-yuv420p10 > --- src/tests/ref/fate/filter-unsharp-yuv420p10 2019-10-15 > 15:35:27.272519847 +0200 > +++ tests/data/fate/filter-unsharp-yuv420p10 2019-10-15 16:39:22.896600653 > +0200 > @@ -3,53 +3,53 @@ > #codec_id 0: rawvideo > #dimensions 0: 352x288 > #sar 0: 0/1 > -0, 0, 0,1, 304128, 0x375a055d > -0, 1, 1,1, 304128, 0x43374234 > -0, 2, 2,1, 304128, 0xba34fded > -0, 3, 3,1, 304128, 0xaab09f3b > -0, 4, 4,1, 304128, 0x1e42b90e > -0, 5, 5,1, 304128, 0x135f1088 > -0, 6, 6,1, 304128, 0x780c001a > -0, 7, 7,1, 304128, 0x10f209fa > -0, 8, 8,1, 304128, 0x54aa698a > -0, 9, 9,1, 304128, 0x72470a4b > -0, 10, 10,1, 304128, 0x7cac80ed > -0, 11, 11,1, 304128, 0x820ffb09 > -0, 12, 12,1, 304128, 0x7386656a > -0, 13, 13,1, 304128, 0x3662c47e > -0, 14, 14,1, 304128, 0x1b07cbce > -0, 15, 15,1, 304128, 0x2577c6d2 > -0, 16, 16,1, 304128, 0xb478c1a6 > -0, 17, 17,1, 304128, 0x27549b49 > -0, 18, 18,1, 304128, 0xd2f628ca > -0, 19, 19,1, 304128, 0x95cc5544 > -0, 20, 20,1, 304128, 0x844a1bda > -0, 21, 21,1, 304128, 0x4bcfc8b2 > -0, 22, 22,1, 304128, 0x403e2302 > -0, 23, 23,1, 304128, 0x275214bf > -0, 24, 24,1, 304128, 0x2f1e8e7b > -0, 25, 25,1, 304128, 0x14d68a42 > -0, 26, 26,1, 304128, 0x2d966e74 > -0, 27, 27,1, 304128, 0x7d2f0bf2 > -0, 28, 28,1, 304128, 0x5744d92e > -0, 29, 29,1, 304128, 0x4c89f858 > -0, 30, 30,1, 304128, 0x9702e22e > -0, 31, 31,1, 304128, 0xea18c80e > -0, 32, 32,1, 304128, 0x5290813c > -0, 33, 33,1, 304128, 0xc8909e8c > -0, 34, 34,1, 304128, 0xf9c985f9 > -0, 35, 35,1, 304128, 0xcdf626f0 > -0, 36, 36,1, 304128, 0xc517d607 > -0, 37, 37,1, 304128, 0xe765923b > -0, 38, 38,1, 304128, 0xf12fa5f6 > -0, 39, 39,1, 304128, 0x04bf7f2b > -0, 40, 40,1, 304128, 0x695762d6 > -0, 41, 41,1, 304128, 0xb1bf1983 > -0, 42, 42,1, 304128, 0x654dc4b2 > -0, 43, 43,1, 304128, 0x161854b6 > -0, 44, 44,1, 304128, 0x3d56b1c1 > -0, 45, 45,1, 304128, 0xa16f54a8 > -0, 46, 46,1, 304128, 0x02fffb2f > -0, 47, 47,1, 304128, 0x04bddde4 > -0, 48, 48,1, 304128, 0xf5687316 > -0, 49, 49,1, 304128, 0x2a9a7dc6 > +0, 0, 0,1, 304128, 0x12f2055d > +0, 1, 1,1, 304128, 0xda454234 > +0, 2, 2,1, 304128, 0x9497fded > +0, 3, 3,1, 304128, 0xe6db9f3b > +0, 4, 4,1, 304128, 0x4214b90e > +0, 5, 5,1, 304128, 0xe09d1088 > +0, 6, 6,1, 304128, 0x5c89001a > +0, 7, 7,1, 304128, 0xe9e809fa > +0, 8, 8,1, 304128, 0xc4ec698a > +0, 9, 9,1, 304128, 0x48610a4b > +0, 10, 10,1, 304128, 0xdd9b80ed > +0, 11, 11,1, 304128, 0x679afb09 > +0, 12, 12,1, 304128, 0xf364656a > +0, 13, 13,1, 304128, 0x5612c47e > +0, 14, 14,1, 304128, 0x2cafcbce > +0, 15, 15,1, 304128, 0x382bc6d2 > +0, 16, 16,1, 304128, 0xcc5cc1a6 > +0, 17, 17,
[FFmpeg-devel] [PATCH v2 4/4] fate/filter-video: add 10bit test for unsharp filter
From: Limin Wang Signed-off-by: Limin Wang --- tests/fate/filter-video.mak | 3 ++ tests/ref/fate/filter-unsharp-yuv420p10 | 55 + 2 files changed, 58 insertions(+) create mode 100644 tests/ref/fate/filter-unsharp-yuv420p10 diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index 0c6ee72432..22582471f4 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -395,6 +395,9 @@ FATE_FILTER_VSYNTH-$(CONFIG_TRIM_FILTER) += $(FATE_TRIM) FATE_FILTER_VSYNTH-$(CONFIG_UNSHARP_FILTER) += fate-filter-unsharp fate-filter-unsharp: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf unsharp=11:11:-1.5:11:11:-1.5 +FATE_FILTER_VSYNTH-$(CONFIG_UNSHARP_FILTER) += fate-filter-unsharp-yuv420p10 +fate-filter-unsharp-yuv420p10: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=pix_fmts=yuv420p10,unsharp=11:11:-1.5:11:11:-1.5 -pix_fmt yuv420p10le -flags +bitexact -sws_flags +accurate_rnd+bitexact + FATE_FILTER_SAMPLES-$(call ALLYES, SMJPEG_DEMUXER MJPEG_DECODER PERMS_FILTER HQDN3D_FILTER) += fate-filter-hqdn3d-sample fate-filter-hqdn3d-sample: tests/data/filtergraphs/hqdn3d fate-filter-hqdn3d-sample: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/hqdn3d -an diff --git a/tests/ref/fate/filter-unsharp-yuv420p10 b/tests/ref/fate/filter-unsharp-yuv420p10 new file mode 100644 index 00..20f82f1fae --- /dev/null +++ b/tests/ref/fate/filter-unsharp-yuv420p10 @@ -0,0 +1,55 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 352x288 +#sar 0: 0/1 +0, 0, 0,1, 304128, 0x375a055d +0, 1, 1,1, 304128, 0x43374234 +0, 2, 2,1, 304128, 0xba34fded +0, 3, 3,1, 304128, 0xaab09f3b +0, 4, 4,1, 304128, 0x1e42b90e +0, 5, 5,1, 304128, 0x135f1088 +0, 6, 6,1, 304128, 0x780c001a +0, 7, 7,1, 304128, 0x10f209fa +0, 8, 8,1, 304128, 0x54aa698a +0, 9, 9,1, 304128, 0x72470a4b +0, 10, 10,1, 304128, 0x7cac80ed +0, 11, 11,1, 304128, 0x820ffb09 +0, 12, 12,1, 304128, 0x7386656a +0, 13, 13,1, 304128, 0x3662c47e +0, 14, 14,1, 304128, 0x1b07cbce +0, 15, 15,1, 304128, 0x2577c6d2 +0, 16, 16,1, 304128, 0xb478c1a6 +0, 17, 17,1, 304128, 0x27549b49 +0, 18, 18,1, 304128, 0xd2f628ca +0, 19, 19,1, 304128, 0x95cc5544 +0, 20, 20,1, 304128, 0x844a1bda +0, 21, 21,1, 304128, 0x4bcfc8b2 +0, 22, 22,1, 304128, 0x403e2302 +0, 23, 23,1, 304128, 0x275214bf +0, 24, 24,1, 304128, 0x2f1e8e7b +0, 25, 25,1, 304128, 0x14d68a42 +0, 26, 26,1, 304128, 0x2d966e74 +0, 27, 27,1, 304128, 0x7d2f0bf2 +0, 28, 28,1, 304128, 0x5744d92e +0, 29, 29,1, 304128, 0x4c89f858 +0, 30, 30,1, 304128, 0x9702e22e +0, 31, 31,1, 304128, 0xea18c80e +0, 32, 32,1, 304128, 0x5290813c +0, 33, 33,1, 304128, 0xc8909e8c +0, 34, 34,1, 304128, 0xf9c985f9 +0, 35, 35,1, 304128, 0xcdf626f0 +0, 36, 36,1, 304128, 0xc517d607 +0, 37, 37,1, 304128, 0xe765923b +0, 38, 38,1, 304128, 0xf12fa5f6 +0, 39, 39,1, 304128, 0x04bf7f2b +0, 40, 40,1, 304128, 0x695762d6 +0, 41, 41,1, 304128, 0xb1bf1983 +0, 42, 42,1, 304128, 0x654dc4b2 +0, 43, 43,1, 304128, 0x161854b6 +0, 44, 44,1, 304128, 0x3d56b1c1 +0, 45, 45,1, 304128, 0xa16f54a8 +0, 46, 46,1, 304128, 0x02fffb2f +0, 47, 47,1, 304128, 0x04bddde4 +0, 48, 48,1, 304128, 0xf5687316 +0, 49, 49,1, 304128, 0x2a9a7dc6 -- 2.21.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 2/2] FATE/dnn: add .gitignore
> -Original Message- > From: ffmpeg-devel [mailto:ffmpeg-devel-boun...@ffmpeg.org] On Behalf Of > Zhao Zhili > Sent: Wednesday, October 16, 2019 12:21 AM > To: ffmpeg-devel@ffmpeg.org > Cc: Zhao Zhili > Subject: [FFmpeg-devel] [PATCH 2/2] FATE/dnn: add .gitignore > > --- > tests/dnn/.gitignore | 4 > 1 file changed, 4 insertions(+) > create mode 100644 tests/dnn/.gitignore > > diff --git a/tests/dnn/.gitignore b/tests/dnn/.gitignore > new file mode 100644 > index 00..5eedaaa56d > --- /dev/null > +++ b/tests/dnn/.gitignore > @@ -0,0 +1,4 @@ > +/dnn-layer-conv2d-test > +/dnn-layer-depth2space-test > +/dnn-layer-maximum-test > +/dnn-layer-pad-test LGTM, thanks. > -- > 2.21.0 > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH V3 3/3] avfilter/dnn: unify the layer load function in native mode
> -Original Message- > From: ffmpeg-devel [mailto:ffmpeg-devel-boun...@ffmpeg.org] On Behalf Of > Pedro Arthur > Sent: Wednesday, October 16, 2019 6:01 AM > To: FFmpeg development discussions and patches > Subject: Re: [FFmpeg-devel] [PATCH V3 3/3] avfilter/dnn: unify the layer load > function in native mode > > Em ter, 15 de out de 2019 às 02:29, Guo, Yejun > escreveu: > > > > > > > > -Original Message- > > > From: Guo, Yejun > > > Sent: Wednesday, October 09, 2019 10:08 PM > > > To: ffmpeg-devel@ffmpeg.org > > > Cc: Guo, Yejun > > > Subject: [PATCH V3 3/3] avfilter/dnn: unify the layer load function in > > native > > > mode > > > > > > Signed-off-by: Guo, Yejun > > > --- > > > libavfilter/dnn/dnn_backend_native.c | 114 > > +++-- > > > libavfilter/dnn/dnn_backend_native.h | 2 +- > > > libavfilter/dnn/dnn_backend_native_layer_conv2d.c | 46 + > > > libavfilter/dnn/dnn_backend_native_layer_conv2d.h | 1 + > > > .../dnn/dnn_backend_native_layer_depth2space.c | 18 > > > .../dnn/dnn_backend_native_layer_depth2space.h | 1 + > > > libavfilter/dnn/dnn_backend_native_layer_maximum.c | 18 > > > libavfilter/dnn/dnn_backend_native_layer_maximum.h | 1 + > > > libavfilter/dnn/dnn_backend_native_layer_pad.c | 23 + > > > libavfilter/dnn/dnn_backend_native_layer_pad.h | 1 + > > > libavfilter/dnn/dnn_backend_native_layers.c| 12 +-- > > > libavfilter/dnn/dnn_backend_native_layers.h| 8 +- > > > 12 files changed, 135 insertions(+), 110 deletions(-) > > > > > this patch set asks for review, thanks. > > > > Patch set LGTM. > Please make sure your source files end in a newline otherwise it can't be > pushed, I've fixed it locally and pushed, thanks! thanks, just know it, will make sure there is a new empty line at the end of file. > > > > > ___ > > ffmpeg-devel mailing list > > ffmpeg-devel@ffmpeg.org > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > To unsubscribe, visit link above, or email > > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] segfault in af_afade.c::activate
On Tue, Oct 15, 2019, at 3:06 PM, Mark Niebur wrote: > This should be fixed already on master? I checked a few hours ago and was > able to repro. Yes. Paul made the commit less than 10 minutes ago. https://git.videolan.org/gitweb.cgi/ffmpeg.git/?p=ffmpeg.git;a=commit;h=29dac2927f5fa0b1f5c6b27a3ed32f2968ea9b00 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avformat/flvenc: Check pts for mpeg4/h264 (which need the value)
Fixes: Ticket8152 Signed-off-by: Michael Niedermayer --- libavformat/flvenc.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index fb1dede7ae..eb52b473b8 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -928,6 +928,12 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) "Packets are not in the proper order with respect to DTS\n"); return AVERROR(EINVAL); } +if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) { +if (pkt->pts == AV_NOPTS_VALUE) { +av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n"); +return AVERROR(EINVAL); +} +} ts = pkt->dts; -- 2.23.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] segfault in af_afade.c::activate
This should be fixed already on master? I checked a few hours ago and was able to repro. On Tue, Oct 15, 2019, 5:03 PM Paul B Mahol wrote: > Should be fixed. > > On 10/16/19, Mark Niebur wrote: > > I'm sorry for not specifying. In the case that data is not ready from > > ctx->inputs[1] after crossfade is over, ff_inlink_consume_frame will > return > > 0 and not set the frame pointer. If ff_outlink_frame_wanted is still 0, > the > > function will fall through to the code filtering the frame, although the > > frame pointer is NULL. This is the affected code in af_afade.c: > > > > 455 if (s->crossfade_is_over) { > > 456 ret = ff_inlink_consume_frame(ctx->inputs[1], ); > > 457 if (ret < 0) { > > 458 return ret; > > 459 } else if (ff_inlink_acknowledge_status(ctx->inputs[1], > , > > )) { > > 460 ff_outlink_set_status(ctx->outputs[0], status, pts); > > 461 return 0; > > 462 } else { > > 463 if (ff_outlink_frame_wanted(ctx->outputs[0]) && !in) { > > 464 ff_inlink_request_frame(ctx->inputs[1]); > > 465 return 0; > > 466 } > > 467 } > > 468 in->pts = s->pts; > > 469 s->pts += av_rescale_q(in->nb_samples, > > 470 (AVRational){ 1, outlink->sample_rate }, > > outlink->time_base); > > 471 return ff_filter_frame(outlink, in); > > 472 } > > > >> On Oct 15, 2019, at 4:29 PM, Paul B Mahol wrote: > >> > >> On 10/15/19, Mark Niebur mailto:mnie...@thuuz.com>> > >> wrote: > >>> I just checked out master and I see the fix you mentioned. This does > not > >>> completely fix acrossfade for me. I also had to apply the following > >>> patch: > >> > >> What this patch fixes? > >> > >>> diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c > >>> index 195fb65..446aa0a 100644 > >>> --- a/libavfilter/af_afade.c > >>> +++ b/libavfilter/af_afade.c > >>> @@ -459,11 +459,11 @@ static int activate(AVFilterContext *ctx) > >>> } else if (ff_inlink_acknowledge_status(ctx->inputs[1], > , > >>> )) { > >>> ff_outlink_set_status(ctx->outputs[0], status, pts); > >>> return 0; > >>> -} else { > >>> -if (ff_outlink_frame_wanted(ctx->outputs[0]) && !in) { > >>> +} else if (!in) { > >>> +if (ff_outlink_frame_wanted(ctx->outputs[0])) { > >>> ff_inlink_request_frame(ctx->inputs[1]); > >>> -return 0; > >>> } > >>> + return 0; > >>> } > >>> in->pts = s->pts; > >>> s->pts += av_rescale_q(in->nb_samples, > >>> > >>> Thanks, > >>> Mark > >>> > On Oct 15, 2019, at 2:26 PM, Paul B Mahol wrote: > > On 10/15/19, Mark Niebur wrote: > > Hello, > > I'm trying to debug an issue I'm seeing where the filter "acrossfade" > > produces a segfault. This seemingly only happens in docker > containers, > > and > > I am seeing it when running a rather large filter chain. I'm trying > to > > get > > to the bottom of it, but it would be really helpful to understand the > > context around how libavfilter fills the filter input fifos. This is > > the > > code where I'm seeing the segfault: > > 449 AVFrame *in = NULL, *out, *cf[2] = { NULL }; > > ... > > 474 if (ff_inlink_queued_samples(ctx->inputs[0]) > > s->nb_samples) { > > 475 // consume some samples - this is not a crossfade overlap > > 486 } else if (ff_inlink_queued_samples(ctx->inputs[1]) >= > > s->nb_samples) { > > 487 if (s->overlap) { > > 488 out = ff_get_audio_buffer(outlink, s->nb_samples); > > 489 if (!out) > > 490 return AVERROR(ENOMEM); > > 491 // NO CHECK IS DONE HERE THAT ENOUGH SAMPLES ARE > > PRESENT > > 491 // In our case, there are 0 samples, so > > ff_inlink_consume_samples returns early and does not set cf[0] > > 492 ret = ff_inlink_consume_samples(ctx->inputs[0], > > s->nb_samples, s->nb_samples, [0]); > > 493 if (ret < 0) { > > 494 av_frame_free(); > > 495 return ret; > > 496 } > > 497 // SEGFAULT HERE > > 498 ret = ff_inlink_consume_samples(ctx->inputs[1], > > s->nb_samples, s->nb_samples, [1]); > > 499 if (ret < 0) { > > 500 av_frame_free(); > > 501 return ret; > > 502 } > > > > How does avfilter add samples to an inlink? Does it just fill it > > randomly > > or will it fill input 0 completely and then move on to input 1, 2, 3? > > Even > > when I fix this segfault by ensuring that > > ff_inlink_queued_samples(ctx->inputs[0]) == s->nb_samples, I will > still > > get > > additional segfaults in the acrossfade code where > >
[FFmpeg-devel] [PATCH 2/2] avcodec/dstdec: Check that AC probabilities are within range
ISO/IEC 14496-3:2005(E): "Each entry of P_one[ ][ ] is in the range of 1 to 128, corresponding to a probability of 1/256 to 128/256 of the next error bit (bit E, See Figure 10.5)..." Fixes: Timeout (42sec ->1sec) Fixes: 18181/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_DST_fuzzer-5736646250594304 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dstdec.c | 4 1 file changed, 4 insertions(+) diff --git a/libavcodec/dstdec.c b/libavcodec/dstdec.c index e0519d2a0b..ae3fe428dd 100644 --- a/libavcodec/dstdec.c +++ b/libavcodec/dstdec.c @@ -162,6 +162,10 @@ static int read_table(GetBitContext *gb, Table *t, const int8_t code_pred_coeff[ c -= (x + 4) / 8; else c += (-x + 3) / 8; +if (!is_signed) { +if (c < offset || c >= offset + (1
[FFmpeg-devel] [PATCH 1/2] avcodec/dstdec: Check read_table() for failure
Fixes: Timeout (too long -> 42sec) Fixes: 18181/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_DST_fuzzer-5736646250594304 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dstdec.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/dstdec.c b/libavcodec/dstdec.c index 48271b10f7..e0519d2a0b 100644 --- a/libavcodec/dstdec.c +++ b/libavcodec/dstdec.c @@ -302,11 +302,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, /* Filter Coef Sets (10.12) */ -read_table(gb, >fsets, fsets_code_pred_coeff, 7, 9, 1, 0); +ret = read_table(gb, >fsets, fsets_code_pred_coeff, 7, 9, 1, 0); +if (ret < 0) +return ret; /* Probability Tables (10.13) */ -read_table(gb, >probs, probs_code_pred_coeff, 6, 7, 0, 1); +ret = read_table(gb, >probs, probs_code_pred_coeff, 6, 7, 0, 1); +if (ret < 0) +return ret; /* Arithmetic Coded Data (10.11) */ -- 2.23.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] segfault in af_afade.c::activate
Should be fixed. On 10/16/19, Mark Niebur wrote: > I'm sorry for not specifying. In the case that data is not ready from > ctx->inputs[1] after crossfade is over, ff_inlink_consume_frame will return > 0 and not set the frame pointer. If ff_outlink_frame_wanted is still 0, the > function will fall through to the code filtering the frame, although the > frame pointer is NULL. This is the affected code in af_afade.c: > > 455 if (s->crossfade_is_over) { > 456 ret = ff_inlink_consume_frame(ctx->inputs[1], ); > 457 if (ret < 0) { > 458 return ret; > 459 } else if (ff_inlink_acknowledge_status(ctx->inputs[1], , > )) { > 460 ff_outlink_set_status(ctx->outputs[0], status, pts); > 461 return 0; > 462 } else { > 463 if (ff_outlink_frame_wanted(ctx->outputs[0]) && !in) { > 464 ff_inlink_request_frame(ctx->inputs[1]); > 465 return 0; > 466 } > 467 } > 468 in->pts = s->pts; > 469 s->pts += av_rescale_q(in->nb_samples, > 470 (AVRational){ 1, outlink->sample_rate }, > outlink->time_base); > 471 return ff_filter_frame(outlink, in); > 472 } > >> On Oct 15, 2019, at 4:29 PM, Paul B Mahol wrote: >> >> On 10/15/19, Mark Niebur mailto:mnie...@thuuz.com>> >> wrote: >>> I just checked out master and I see the fix you mentioned. This does not >>> completely fix acrossfade for me. I also had to apply the following >>> patch: >> >> What this patch fixes? >> >>> diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c >>> index 195fb65..446aa0a 100644 >>> --- a/libavfilter/af_afade.c >>> +++ b/libavfilter/af_afade.c >>> @@ -459,11 +459,11 @@ static int activate(AVFilterContext *ctx) >>> } else if (ff_inlink_acknowledge_status(ctx->inputs[1], , >>> )) { >>> ff_outlink_set_status(ctx->outputs[0], status, pts); >>> return 0; >>> -} else { >>> -if (ff_outlink_frame_wanted(ctx->outputs[0]) && !in) { >>> +} else if (!in) { >>> +if (ff_outlink_frame_wanted(ctx->outputs[0])) { >>> ff_inlink_request_frame(ctx->inputs[1]); >>> -return 0; >>> } >>> + return 0; >>> } >>> in->pts = s->pts; >>> s->pts += av_rescale_q(in->nb_samples, >>> >>> Thanks, >>> Mark >>> On Oct 15, 2019, at 2:26 PM, Paul B Mahol wrote: On 10/15/19, Mark Niebur wrote: > Hello, > I'm trying to debug an issue I'm seeing where the filter "acrossfade" > produces a segfault. This seemingly only happens in docker containers, > and > I am seeing it when running a rather large filter chain. I'm trying to > get > to the bottom of it, but it would be really helpful to understand the > context around how libavfilter fills the filter input fifos. This is > the > code where I'm seeing the segfault: > 449 AVFrame *in = NULL, *out, *cf[2] = { NULL }; > ... > 474 if (ff_inlink_queued_samples(ctx->inputs[0]) > s->nb_samples) { > 475 // consume some samples - this is not a crossfade overlap > 486 } else if (ff_inlink_queued_samples(ctx->inputs[1]) >= > s->nb_samples) { > 487 if (s->overlap) { > 488 out = ff_get_audio_buffer(outlink, s->nb_samples); > 489 if (!out) > 490 return AVERROR(ENOMEM); > 491 // NO CHECK IS DONE HERE THAT ENOUGH SAMPLES ARE > PRESENT > 491 // In our case, there are 0 samples, so > ff_inlink_consume_samples returns early and does not set cf[0] > 492 ret = ff_inlink_consume_samples(ctx->inputs[0], > s->nb_samples, s->nb_samples, [0]); > 493 if (ret < 0) { > 494 av_frame_free(); > 495 return ret; > 496 } > 497 // SEGFAULT HERE > 498 ret = ff_inlink_consume_samples(ctx->inputs[1], > s->nb_samples, s->nb_samples, [1]); > 499 if (ret < 0) { > 500 av_frame_free(); > 501 return ret; > 502 } > > How does avfilter add samples to an inlink? Does it just fill it > randomly > or will it fill input 0 completely and then move on to input 1, 2, 3? > Even > when I fix this segfault by ensuring that > ff_inlink_queued_samples(ctx->inputs[0]) == s->nb_samples, I will still > get > additional segfaults in the acrossfade code where > ff_inlink_consume_samples > returns 0 and does not set the frame pointer. I think this was just reported and fixed very recently. > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email >
Re: [FFmpeg-devel] segfault in af_afade.c::activate
I'm sorry for not specifying. In the case that data is not ready from ctx->inputs[1] after crossfade is over, ff_inlink_consume_frame will return 0 and not set the frame pointer. If ff_outlink_frame_wanted is still 0, the function will fall through to the code filtering the frame, although the frame pointer is NULL. This is the affected code in af_afade.c: 455 if (s->crossfade_is_over) { 456 ret = ff_inlink_consume_frame(ctx->inputs[1], ); 457 if (ret < 0) { 458 return ret; 459 } else if (ff_inlink_acknowledge_status(ctx->inputs[1], , )) { 460 ff_outlink_set_status(ctx->outputs[0], status, pts); 461 return 0; 462 } else { 463 if (ff_outlink_frame_wanted(ctx->outputs[0]) && !in) { 464 ff_inlink_request_frame(ctx->inputs[1]); 465 return 0; 466 } 467 } 468 in->pts = s->pts; 469 s->pts += av_rescale_q(in->nb_samples, 470 (AVRational){ 1, outlink->sample_rate }, outlink->time_base); 471 return ff_filter_frame(outlink, in); 472 } > On Oct 15, 2019, at 4:29 PM, Paul B Mahol wrote: > > On 10/15/19, Mark Niebur mailto:mnie...@thuuz.com>> wrote: >> I just checked out master and I see the fix you mentioned. This does not >> completely fix acrossfade for me. I also had to apply the following patch: > > What this patch fixes? > >> diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c >> index 195fb65..446aa0a 100644 >> --- a/libavfilter/af_afade.c >> +++ b/libavfilter/af_afade.c >> @@ -459,11 +459,11 @@ static int activate(AVFilterContext *ctx) >> } else if (ff_inlink_acknowledge_status(ctx->inputs[1], , >> )) { >> ff_outlink_set_status(ctx->outputs[0], status, pts); >> return 0; >> -} else { >> -if (ff_outlink_frame_wanted(ctx->outputs[0]) && !in) { >> +} else if (!in) { >> +if (ff_outlink_frame_wanted(ctx->outputs[0])) { >> ff_inlink_request_frame(ctx->inputs[1]); >> -return 0; >> } >> + return 0; >> } >> in->pts = s->pts; >> s->pts += av_rescale_q(in->nb_samples, >> >> Thanks, >> Mark >> >>> On Oct 15, 2019, at 2:26 PM, Paul B Mahol wrote: >>> >>> On 10/15/19, Mark Niebur wrote: Hello, I'm trying to debug an issue I'm seeing where the filter "acrossfade" produces a segfault. This seemingly only happens in docker containers, and I am seeing it when running a rather large filter chain. I'm trying to get to the bottom of it, but it would be really helpful to understand the context around how libavfilter fills the filter input fifos. This is the code where I'm seeing the segfault: 449 AVFrame *in = NULL, *out, *cf[2] = { NULL }; ... 474 if (ff_inlink_queued_samples(ctx->inputs[0]) > s->nb_samples) { 475 // consume some samples - this is not a crossfade overlap 486 } else if (ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples) { 487 if (s->overlap) { 488 out = ff_get_audio_buffer(outlink, s->nb_samples); 489 if (!out) 490 return AVERROR(ENOMEM); 491 // NO CHECK IS DONE HERE THAT ENOUGH SAMPLES ARE PRESENT 491 // In our case, there are 0 samples, so ff_inlink_consume_samples returns early and does not set cf[0] 492 ret = ff_inlink_consume_samples(ctx->inputs[0], s->nb_samples, s->nb_samples, [0]); 493 if (ret < 0) { 494 av_frame_free(); 495 return ret; 496 } 497 // SEGFAULT HERE 498 ret = ff_inlink_consume_samples(ctx->inputs[1], s->nb_samples, s->nb_samples, [1]); 499 if (ret < 0) { 500 av_frame_free(); 501 return ret; 502 } How does avfilter add samples to an inlink? Does it just fill it randomly or will it fill input 0 completely and then move on to input 1, 2, 3? Even when I fix this segfault by ensuring that ff_inlink_queued_samples(ctx->inputs[0]) == s->nb_samples, I will still get additional segfaults in the acrossfade code where ff_inlink_consume_samples returns 0 and does not set the frame pointer. >>> >>> I think this was just reported and fixed very recently. >>> ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". >>> ___ >>> ffmpeg-devel mailing list >>> ffmpeg-devel@ffmpeg.org >>>
Re: [FFmpeg-devel] segfault in af_afade.c::activate
On 10/15/19, Mark Niebur wrote: > I just checked out master and I see the fix you mentioned. This does not > completely fix acrossfade for me. I also had to apply the following patch: What this patch fixes? > diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c > index 195fb65..446aa0a 100644 > --- a/libavfilter/af_afade.c > +++ b/libavfilter/af_afade.c > @@ -459,11 +459,11 @@ static int activate(AVFilterContext *ctx) > } else if (ff_inlink_acknowledge_status(ctx->inputs[1], , > )) { > ff_outlink_set_status(ctx->outputs[0], status, pts); > return 0; > -} else { > -if (ff_outlink_frame_wanted(ctx->outputs[0]) && !in) { > +} else if (!in) { > +if (ff_outlink_frame_wanted(ctx->outputs[0])) { > ff_inlink_request_frame(ctx->inputs[1]); > -return 0; > } > + return 0; > } > in->pts = s->pts; > s->pts += av_rescale_q(in->nb_samples, > > Thanks, > Mark > >> On Oct 15, 2019, at 2:26 PM, Paul B Mahol wrote: >> >> On 10/15/19, Mark Niebur wrote: >>> Hello, >>> I'm trying to debug an issue I'm seeing where the filter "acrossfade" >>> produces a segfault. This seemingly only happens in docker containers, >>> and >>> I am seeing it when running a rather large filter chain. I'm trying to >>> get >>> to the bottom of it, but it would be really helpful to understand the >>> context around how libavfilter fills the filter input fifos. This is the >>> code where I'm seeing the segfault: >>> 449 AVFrame *in = NULL, *out, *cf[2] = { NULL }; >>> ... >>> 474 if (ff_inlink_queued_samples(ctx->inputs[0]) > s->nb_samples) { >>> 475 // consume some samples - this is not a crossfade overlap >>> 486 } else if (ff_inlink_queued_samples(ctx->inputs[1]) >= >>> s->nb_samples) { >>> 487 if (s->overlap) { >>> 488 out = ff_get_audio_buffer(outlink, s->nb_samples); >>> 489 if (!out) >>> 490 return AVERROR(ENOMEM); >>> 491 // NO CHECK IS DONE HERE THAT ENOUGH SAMPLES ARE PRESENT >>> 491 // In our case, there are 0 samples, so >>> ff_inlink_consume_samples returns early and does not set cf[0] >>> 492 ret = ff_inlink_consume_samples(ctx->inputs[0], >>> s->nb_samples, s->nb_samples, [0]); >>> 493 if (ret < 0) { >>> 494 av_frame_free(); >>> 495 return ret; >>> 496 } >>> 497 // SEGFAULT HERE >>> 498 ret = ff_inlink_consume_samples(ctx->inputs[1], >>> s->nb_samples, s->nb_samples, [1]); >>> 499 if (ret < 0) { >>> 500 av_frame_free(); >>> 501 return ret; >>> 502 } >>> >>> How does avfilter add samples to an inlink? Does it just fill it >>> randomly >>> or will it fill input 0 completely and then move on to input 1, 2, 3? >>> Even >>> when I fix this segfault by ensuring that >>> ff_inlink_queued_samples(ctx->inputs[0]) == s->nb_samples, I will still >>> get >>> additional segfaults in the acrossfade code where >>> ff_inlink_consume_samples >>> returns 0 and does not set the frame pointer. >> >> I think this was just reported and fixed very recently. >> >>> ___ >>> ffmpeg-devel mailing list >>> ffmpeg-devel@ffmpeg.org >>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >>> >>> To unsubscribe, visit link above, or email >>> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". >> ___ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH V3 3/3] avfilter/dnn: unify the layer load function in native mode
Em ter, 15 de out de 2019 às 02:29, Guo, Yejun escreveu: > > > > -Original Message- > > From: Guo, Yejun > > Sent: Wednesday, October 09, 2019 10:08 PM > > To: ffmpeg-devel@ffmpeg.org > > Cc: Guo, Yejun > > Subject: [PATCH V3 3/3] avfilter/dnn: unify the layer load function in > native > > mode > > > > Signed-off-by: Guo, Yejun > > --- > > libavfilter/dnn/dnn_backend_native.c | 114 > +++-- > > libavfilter/dnn/dnn_backend_native.h | 2 +- > > libavfilter/dnn/dnn_backend_native_layer_conv2d.c | 46 + > > libavfilter/dnn/dnn_backend_native_layer_conv2d.h | 1 + > > .../dnn/dnn_backend_native_layer_depth2space.c | 18 > > .../dnn/dnn_backend_native_layer_depth2space.h | 1 + > > libavfilter/dnn/dnn_backend_native_layer_maximum.c | 18 > > libavfilter/dnn/dnn_backend_native_layer_maximum.h | 1 + > > libavfilter/dnn/dnn_backend_native_layer_pad.c | 23 + > > libavfilter/dnn/dnn_backend_native_layer_pad.h | 1 + > > libavfilter/dnn/dnn_backend_native_layers.c| 12 +-- > > libavfilter/dnn/dnn_backend_native_layers.h| 8 +- > > 12 files changed, 135 insertions(+), 110 deletions(-) > > > this patch set asks for review, thanks. > Patch set LGTM. Please make sure your source files end in a newline otherwise it can't be pushed, I've fixed it locally and pushed, thanks! > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] segfault in af_afade.c::activate
I just checked out master and I see the fix you mentioned. This does not completely fix acrossfade for me. I also had to apply the following patch: diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c index 195fb65..446aa0a 100644 --- a/libavfilter/af_afade.c +++ b/libavfilter/af_afade.c @@ -459,11 +459,11 @@ static int activate(AVFilterContext *ctx) } else if (ff_inlink_acknowledge_status(ctx->inputs[1], , )) { ff_outlink_set_status(ctx->outputs[0], status, pts); return 0; -} else { -if (ff_outlink_frame_wanted(ctx->outputs[0]) && !in) { +} else if (!in) { +if (ff_outlink_frame_wanted(ctx->outputs[0])) { ff_inlink_request_frame(ctx->inputs[1]); -return 0; } + return 0; } in->pts = s->pts; s->pts += av_rescale_q(in->nb_samples, Thanks, Mark > On Oct 15, 2019, at 2:26 PM, Paul B Mahol wrote: > > On 10/15/19, Mark Niebur wrote: >> Hello, >> I'm trying to debug an issue I'm seeing where the filter "acrossfade" >> produces a segfault. This seemingly only happens in docker containers, and >> I am seeing it when running a rather large filter chain. I'm trying to get >> to the bottom of it, but it would be really helpful to understand the >> context around how libavfilter fills the filter input fifos. This is the >> code where I'm seeing the segfault: >> 449 AVFrame *in = NULL, *out, *cf[2] = { NULL }; >> ... >> 474 if (ff_inlink_queued_samples(ctx->inputs[0]) > s->nb_samples) { >> 475 // consume some samples - this is not a crossfade overlap >> 486 } else if (ff_inlink_queued_samples(ctx->inputs[1]) >= >> s->nb_samples) { >> 487 if (s->overlap) { >> 488 out = ff_get_audio_buffer(outlink, s->nb_samples); >> 489 if (!out) >> 490 return AVERROR(ENOMEM); >> 491 // NO CHECK IS DONE HERE THAT ENOUGH SAMPLES ARE PRESENT >> 491 // In our case, there are 0 samples, so >> ff_inlink_consume_samples returns early and does not set cf[0] >> 492 ret = ff_inlink_consume_samples(ctx->inputs[0], >> s->nb_samples, s->nb_samples, [0]); >> 493 if (ret < 0) { >> 494 av_frame_free(); >> 495 return ret; >> 496 } >> 497 // SEGFAULT HERE >> 498 ret = ff_inlink_consume_samples(ctx->inputs[1], >> s->nb_samples, s->nb_samples, [1]); >> 499 if (ret < 0) { >> 500 av_frame_free(); >> 501 return ret; >> 502 } >> >> How does avfilter add samples to an inlink? Does it just fill it randomly >> or will it fill input 0 completely and then move on to input 1, 2, 3? Even >> when I fix this segfault by ensuring that >> ff_inlink_queued_samples(ctx->inputs[0]) == s->nb_samples, I will still get >> additional segfaults in the acrossfade code where ff_inlink_consume_samples >> returns 0 and does not set the frame pointer. > > I think this was just reported and fixed very recently. > >> ___ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] segfault in af_afade.c::activate
Would this be on master or some other branch? > On Oct 15, 2019, at 2:26 PM, Paul B Mahol wrote: > > On 10/15/19, Mark Niebur wrote: >> Hello, >> I'm trying to debug an issue I'm seeing where the filter "acrossfade" >> produces a segfault. This seemingly only happens in docker containers, and >> I am seeing it when running a rather large filter chain. I'm trying to get >> to the bottom of it, but it would be really helpful to understand the >> context around how libavfilter fills the filter input fifos. This is the >> code where I'm seeing the segfault: >> 449 AVFrame *in = NULL, *out, *cf[2] = { NULL }; >> ... >> 474 if (ff_inlink_queued_samples(ctx->inputs[0]) > s->nb_samples) { >> 475 // consume some samples - this is not a crossfade overlap >> 486 } else if (ff_inlink_queued_samples(ctx->inputs[1]) >= >> s->nb_samples) { >> 487 if (s->overlap) { >> 488 out = ff_get_audio_buffer(outlink, s->nb_samples); >> 489 if (!out) >> 490 return AVERROR(ENOMEM); >> 491 // NO CHECK IS DONE HERE THAT ENOUGH SAMPLES ARE PRESENT >> 491 // In our case, there are 0 samples, so >> ff_inlink_consume_samples returns early and does not set cf[0] >> 492 ret = ff_inlink_consume_samples(ctx->inputs[0], >> s->nb_samples, s->nb_samples, [0]); >> 493 if (ret < 0) { >> 494 av_frame_free(); >> 495 return ret; >> 496 } >> 497 // SEGFAULT HERE >> 498 ret = ff_inlink_consume_samples(ctx->inputs[1], >> s->nb_samples, s->nb_samples, [1]); >> 499 if (ret < 0) { >> 500 av_frame_free(); >> 501 return ret; >> 502 } >> >> How does avfilter add samples to an inlink? Does it just fill it randomly >> or will it fill input 0 completely and then move on to input 1, 2, 3? Even >> when I fix this segfault by ensuring that >> ff_inlink_queued_samples(ctx->inputs[0]) == s->nb_samples, I will still get >> additional segfaults in the acrossfade code where ff_inlink_consume_samples >> returns 0 and does not set the frame pointer. > > I think this was just reported and fixed very recently. > >> ___ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 2/6] avcodec/apedec: Check error flag after entropy_decode*
On Sat, Oct 05, 2019 at 11:41:03PM +0200, Michael Niedermayer wrote: > Fixes: > 17886/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_APE_fuzzer-5728165124636672 > > Found-by: continuous fuzzing process > https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg > Signed-off-by: Michael Niedermayer > --- > libavcodec/apedec.c | 4 > 1 file changed, 4 insertions(+) will apply this and the other ape patch the fuzzer found another case that is fixed by it [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Why not whip the teacher when the pupil misbehaves? -- Diogenes of Sinope signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] segfault in af_afade.c::activate
On 10/15/19, Mark Niebur wrote: > Hello, > I'm trying to debug an issue I'm seeing where the filter "acrossfade" > produces a segfault. This seemingly only happens in docker containers, and > I am seeing it when running a rather large filter chain. I'm trying to get > to the bottom of it, but it would be really helpful to understand the > context around how libavfilter fills the filter input fifos. This is the > code where I'm seeing the segfault: > 449 AVFrame *in = NULL, *out, *cf[2] = { NULL }; > ... > 474 if (ff_inlink_queued_samples(ctx->inputs[0]) > s->nb_samples) { > 475 // consume some samples - this is not a crossfade overlap > 486 } else if (ff_inlink_queued_samples(ctx->inputs[1]) >= > s->nb_samples) { > 487 if (s->overlap) { > 488 out = ff_get_audio_buffer(outlink, s->nb_samples); > 489 if (!out) > 490 return AVERROR(ENOMEM); > 491 // NO CHECK IS DONE HERE THAT ENOUGH SAMPLES ARE PRESENT > 491 // In our case, there are 0 samples, so > ff_inlink_consume_samples returns early and does not set cf[0] > 492 ret = ff_inlink_consume_samples(ctx->inputs[0], > s->nb_samples, s->nb_samples, [0]); > 493 if (ret < 0) { > 494 av_frame_free(); > 495 return ret; > 496 } > 497 // SEGFAULT HERE > 498 ret = ff_inlink_consume_samples(ctx->inputs[1], > s->nb_samples, s->nb_samples, [1]); > 499 if (ret < 0) { > 500 av_frame_free(); > 501 return ret; > 502 } > > How does avfilter add samples to an inlink? Does it just fill it randomly > or will it fill input 0 completely and then move on to input 1, 2, 3? Even > when I fix this segfault by ensuring that > ff_inlink_queued_samples(ctx->inputs[0]) == s->nb_samples, I will still get > additional segfaults in the acrossfade code where ff_inlink_consume_samples > returns 0 and does not set the frame pointer. I think this was just reported and fixed very recently. > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] segfault in af_afade.c::activate
Hello, I'm trying to debug an issue I'm seeing where the filter "acrossfade" produces a segfault. This seemingly only happens in docker containers, and I am seeing it when running a rather large filter chain. I'm trying to get to the bottom of it, but it would be really helpful to understand the context around how libavfilter fills the filter input fifos. This is the code where I'm seeing the segfault: 449 AVFrame *in = NULL, *out, *cf[2] = { NULL }; ... 474 if (ff_inlink_queued_samples(ctx->inputs[0]) > s->nb_samples) { 475 // consume some samples - this is not a crossfade overlap 486 } else if (ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples) { 487 if (s->overlap) { 488 out = ff_get_audio_buffer(outlink, s->nb_samples); 489 if (!out) 490 return AVERROR(ENOMEM); 491 // NO CHECK IS DONE HERE THAT ENOUGH SAMPLES ARE PRESENT 491 // In our case, there are 0 samples, so ff_inlink_consume_samples returns early and does not set cf[0] 492 ret = ff_inlink_consume_samples(ctx->inputs[0], s->nb_samples, s->nb_samples, [0]); 493 if (ret < 0) { 494 av_frame_free(); 495 return ret; 496 } 497 // SEGFAULT HERE 498 ret = ff_inlink_consume_samples(ctx->inputs[1], s->nb_samples, s->nb_samples, [1]); 499 if (ret < 0) { 500 av_frame_free(); 501 return ret; 502 } How does avfilter add samples to an inlink? Does it just fill it randomly or will it fill input 0 completely and then move on to input 1, 2, 3? Even when I fix this segfault by ensuring that ff_inlink_queued_samples(ctx->inputs[0]) == s->nb_samples, I will still get additional segfaults in the acrossfade code where ff_inlink_consume_samples returns 0 and does not set the frame pointer. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 4/5] avformat/chromaprint: Fix writing raw fingerprint
On 16-10-2019 01:11 AM, Andriy Gelman wrote: On Sun, 06. Oct 01:49, Andriy Gelman wrote: From: Andriy Gelman The pointer fp after the call to chromaprint_get_raw_fingerpoint() points to an array of uint32_t whereas the current code assumed just a char stream. Thus when writing the raw fingerprint, the output would be truncated by a factor of 4. This is fixed in the commit. For reference the declaration of the function from chromaprint.h is: int chromaprint_get_raw_fingerprint(ChromaprintContext *ctx, uint32_t **fingerprint, int *size); --- libavformat/chromaprint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/chromaprint.c b/libavformat/chromaprint.c index a4c0b97d99..faa92ca0db 100644 --- a/libavformat/chromaprint.c +++ b/libavformat/chromaprint.c @@ -136,7 +136,7 @@ static int write_trailer(AVFormatContext *s) switch (cpr->fp_format) { case FINGERPRINT_RAW: -avio_write(pb, fp, size); +avio_write(pb, fp, size * 4); //fp points to array of uint32_t break; case FINGERPRINT_COMPRESSED: case FINGERPRINT_BASE64: -- 2.23.0 ping Will check and apply. Gyan ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 4/5] avformat/chromaprint: Fix writing raw fingerprint
On Sun, 06. Oct 01:49, Andriy Gelman wrote: > From: Andriy Gelman > > The pointer fp after the call to chromaprint_get_raw_fingerpoint() points to > an array of uint32_t whereas the current code assumed just a char stream. > Thus when writing the raw fingerprint, the output would be truncated by a > factor of 4. This is fixed in the commit. > > For reference the declaration of the function from chromaprint.h is: > int chromaprint_get_raw_fingerprint(ChromaprintContext *ctx, uint32_t > **fingerprint, int *size); > --- > libavformat/chromaprint.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/libavformat/chromaprint.c b/libavformat/chromaprint.c > index a4c0b97d99..faa92ca0db 100644 > --- a/libavformat/chromaprint.c > +++ b/libavformat/chromaprint.c > @@ -136,7 +136,7 @@ static int write_trailer(AVFormatContext *s) > > switch (cpr->fp_format) { > case FINGERPRINT_RAW: > -avio_write(pb, fp, size); > +avio_write(pb, fp, size * 4); //fp points to array of uint32_t > break; > case FINGERPRINT_COMPRESSED: > case FINGERPRINT_BASE64: > -- > 2.23.0 ping To reproduce the error, we can compare the results to fpcalc (chromaprint utility https://acoustid.org/chromaprint) $ ffmpeg -f lavfi -i sine=d=4 -f s16le testsample.raw $ fpcalc -format s16le -raw -plain testsample.raw 558758263,558758263,558758263,558758263,558758263,558758263,558758263,558758263,558758263,558758263,558758263 #with ffmpeg (need to typecast output bytesteam to uint32 to compare) $ ffmpeg -f lavfi -i sine=d=4 -f s16le -f chromaprint -fp_format raw fingerprint.raw $ python3 -c "import numpy; print(numpy.fromfile(\"fingerprint.raw\", dtype=numpy.uint32))" [558758263 558758263] Applying this commit makes the outputs same size -- Andriy ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avcodec/frame_thread_encoder: fix memleak on error
On 10/15/19, James Almer wrote: > On 10/15/2019 2:36 PM, Paul B Mahol wrote: >> Fixes #8281 >> >> Signed-off-by: Paul B Mahol >> --- >> libavcodec/frame_thread_encoder.c | 4 +++- >> 1 file changed, 3 insertions(+), 1 deletion(-) >> >> diff --git a/libavcodec/frame_thread_encoder.c >> b/libavcodec/frame_thread_encoder.c >> index 949bc69f81..ffee242b76 100644 >> --- a/libavcodec/frame_thread_encoder.c >> +++ b/libavcodec/frame_thread_encoder.c >> @@ -116,6 +116,7 @@ end: >> >> int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary >> *options){ >> int i=0; >> +AVCodecContext *thread_avctx = NULL; >> ThreadContext *c; >> >> >> @@ -195,7 +196,7 @@ int ff_frame_thread_encoder_init(AVCodecContext >> *avctx, AVDictionary *options){ >> AVDictionary *tmp = NULL; >> int ret; >> void *tmpv; >> -AVCodecContext *thread_avctx = >> avcodec_alloc_context3(avctx->codec); >> +thread_avctx = avcodec_alloc_context3(avctx->codec); >> if(!thread_avctx) >> goto fail; >> tmpv = thread_avctx->priv_data; >> @@ -236,6 +237,7 @@ fail: >> avctx->thread_count = i; >> av_log(avctx, AV_LOG_ERROR, "ff_frame_thread_encoder_init failed\n"); >> ff_frame_thread_encoder_free(avctx); >> +avcodec_free_context(_avctx); >> return -1; >> } > > I thought about this, but if you look at line 202 where it does > "*thread_avctx = *avctx;", isn't there a risk of double frees with > internal fields when avctx is also freed? Yes, there it is. > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avcodec/frame_thread_encoder: fix memleak on error
On 10/15/2019 2:36 PM, Paul B Mahol wrote: > Fixes #8281 > > Signed-off-by: Paul B Mahol > --- > libavcodec/frame_thread_encoder.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/libavcodec/frame_thread_encoder.c > b/libavcodec/frame_thread_encoder.c > index 949bc69f81..ffee242b76 100644 > --- a/libavcodec/frame_thread_encoder.c > +++ b/libavcodec/frame_thread_encoder.c > @@ -116,6 +116,7 @@ end: > > int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary > *options){ > int i=0; > +AVCodecContext *thread_avctx = NULL; > ThreadContext *c; > > > @@ -195,7 +196,7 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, > AVDictionary *options){ > AVDictionary *tmp = NULL; > int ret; > void *tmpv; > -AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec); > +thread_avctx = avcodec_alloc_context3(avctx->codec); > if(!thread_avctx) > goto fail; > tmpv = thread_avctx->priv_data; > @@ -236,6 +237,7 @@ fail: > avctx->thread_count = i; > av_log(avctx, AV_LOG_ERROR, "ff_frame_thread_encoder_init failed\n"); > ff_frame_thread_encoder_free(avctx); > +avcodec_free_context(_avctx); > return -1; > } I thought about this, but if you look at line 202 where it does "*thread_avctx = *avctx;", isn't there a risk of double frees with internal fields when avctx is also freed? ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avcodec/frame_thread_encoder: fix memleak on error
Fixes #8281 Signed-off-by: Paul B Mahol --- libavcodec/frame_thread_encoder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index 949bc69f81..ffee242b76 100644 --- a/libavcodec/frame_thread_encoder.c +++ b/libavcodec/frame_thread_encoder.c @@ -116,6 +116,7 @@ end: int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ int i=0; +AVCodecContext *thread_avctx = NULL; ThreadContext *c; @@ -195,7 +196,7 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ AVDictionary *tmp = NULL; int ret; void *tmpv; -AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec); +thread_avctx = avcodec_alloc_context3(avctx->codec); if(!thread_avctx) goto fail; tmpv = thread_avctx->priv_data; @@ -236,6 +237,7 @@ fail: avctx->thread_count = i; av_log(avctx, AV_LOG_ERROR, "ff_frame_thread_encoder_init failed\n"); ff_frame_thread_encoder_free(avctx); +avcodec_free_context(_avctx); return -1; } -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avfilter/f_sidedata: fix Wtautological-constant-out-of-range-compare
--- How about add AV_FRAME_DATA_NONE to AVFrameSideDataType? libavfilter/f_sidedata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/f_sidedata.c b/libavfilter/f_sidedata.c index 381da5a052..4210dcac4c 100644 --- a/libavfilter/f_sidedata.c +++ b/libavfilter/f_sidedata.c @@ -39,7 +39,7 @@ typedef struct SideDataContext { const AVClass *class; int mode; -enum AVFrameSideDataType type; +int type; // enum AVFrameSideDataType or -1 for delete side data mode } SideDataContext; #define OFFSET(x) offsetof(SideDataContext, x) -- 2.21.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avfilter/vf_adadenoise: add x86 SIMD
Signed-off-by: Paul B Mahol --- libavfilter/atadenoise.h | 36 +++ libavfilter/vf_atadenoise.c | 16 +-- libavfilter/x86/Makefile | 2 + libavfilter/x86/vf_atadenoise.asm| 150 +++ libavfilter/x86/vf_atadenoise_init.c | 40 +++ 5 files changed, 237 insertions(+), 7 deletions(-) create mode 100644 libavfilter/atadenoise.h create mode 100644 libavfilter/x86/vf_atadenoise.asm create mode 100644 libavfilter/x86/vf_atadenoise_init.c diff --git a/libavfilter/atadenoise.h b/libavfilter/atadenoise.h new file mode 100644 index 00..c1fdc2f64e --- /dev/null +++ b/libavfilter/atadenoise.h @@ -0,0 +1,36 @@ + /* + * Copyright (c) 2019 Paul B Mahol + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_ATADENOISE_H +#define AVFILTER_ATADENOISE_H + +#include +#include + +typedef struct ATADenoiseDSPContext { +void (*filter_row)(const uint8_t *src, uint8_t *dst, + const uint8_t **srcf, + int w, int mid, int size, + int thra, int thrb); +} ATADenoiseDSPContext; + +void ff_atadenoise_init_x86(ATADenoiseDSPContext *dsp, int depth); + +#endif /* AVFILTER_ATADENOISE_H */ diff --git a/libavfilter/vf_atadenoise.c b/libavfilter/vf_atadenoise.c index be7c4e2a34..d85fa79961 100644 --- a/libavfilter/vf_atadenoise.c +++ b/libavfilter/vf_atadenoise.c @@ -33,6 +33,7 @@ #define FF_BUFQUEUE_SIZE 129 #include "bufferqueue.h" +#include "atadenoise.h" #include "formats.h" #include "internal.h" #include "video.h" @@ -57,10 +58,8 @@ typedef struct ATADenoiseContext { int available; int (*filter_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); -void (*filter_row)(const uint8_t *src, uint8_t *dst, - const uint8_t *srcf[SIZE], - int w, int mid, int size, - int thra, int thrb); + +ATADenoiseDSPContext dsp; } ATADenoiseContext; #define OFFSET(x) offsetof(ATADenoiseContext, x) @@ -209,7 +208,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) srcf[i] = data[i] + slice_start * linesize[i]; for (y = slice_start; y < slice_end; y++) { -s->filter_row(src, dst, srcf, w, mid, size, thra, thrb); +s->dsp.filter_row(src, dst, srcf, w, mid, size, thra, thrb); dst += out->linesize[p]; src += in->linesize[p]; @@ -239,9 +238,9 @@ static int config_input(AVFilterLink *inlink) depth = desc->comp[0].depth; s->filter_slice = filter_slice; if (depth == 8) -s->filter_row = filter_row8; +s->dsp.filter_row = filter_row8; else -s->filter_row = filter_row16; +s->dsp.filter_row = filter_row16; s->thra[0] = s->fthra[0] * (1 << depth) - 1; s->thra[1] = s->fthra[1] * (1 << depth) - 1; @@ -250,6 +249,9 @@ static int config_input(AVFilterLink *inlink) s->thrb[1] = s->fthrb[1] * (1 << depth) - 1; s->thrb[2] = s->fthrb[2] * (1 << depth) - 1; +if (ARCH_X86) +ff_atadenoise_init_x86(>dsp, depth); + return 0; } diff --git a/libavfilter/x86/Makefile b/libavfilter/x86/Makefile index 4cd914366a..06f832e36c 100644 --- a/libavfilter/x86/Makefile +++ b/libavfilter/x86/Makefile @@ -2,6 +2,7 @@ OBJS-$(CONFIG_SCENE_SAD) += x86/scene_sad_init.o OBJS-$(CONFIG_AFIR_FILTER) += x86/af_afir_init.o OBJS-$(CONFIG_ANLMDN_FILTER) += x86/af_anlmdn_init.o +OBJS-$(CONFIG_ATADENOISE_FILTER) += x86/vf_atadenoise_init.o OBJS-$(CONFIG_BLEND_FILTER) += x86/vf_blend_init.o OBJS-$(CONFIG_BWDIF_FILTER) += x86/vf_bwdif_init.o OBJS-$(CONFIG_COLORSPACE_FILTER) += x86/colorspacedsp_init.o @@ -39,6 +40,7 @@ X86ASM-OBJS-$(CONFIG_SCENE_SAD) += x86/scene_sad.o X86ASM-OBJS-$(CONFIG_AFIR_FILTER)+= x86/af_afir.o X86ASM-OBJS-$(CONFIG_ANLMDN_FILTER) += x86/af_anlmdn.o +X86ASM-OBJS-$(CONFIG_ATADENOISE_FILTER) += x86/vf_atadenoise.o X86ASM-OBJS-$(CONFIG_BLEND_FILTER) += x86/vf_blend.o X86ASM-OBJS-$(CONFIG_BWDIF_FILTER) += x86/vf_bwdif.o
[FFmpeg-devel] [PATCH 2/2] FATE/dnn: add .gitignore
--- tests/dnn/.gitignore | 4 1 file changed, 4 insertions(+) create mode 100644 tests/dnn/.gitignore diff --git a/tests/dnn/.gitignore b/tests/dnn/.gitignore new file mode 100644 index 00..5eedaaa56d --- /dev/null +++ b/tests/dnn/.gitignore @@ -0,0 +1,4 @@ +/dnn-layer-conv2d-test +/dnn-layer-depth2space-test +/dnn-layer-maximum-test +/dnn-layer-pad-test -- 2.21.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] avcodec/tests: add h265_levels to .gitignore
--- libavcodec/tests/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/tests/.gitignore b/libavcodec/tests/.gitignore index 56ddb2cbeb..a01a700e2d 100644 --- a/libavcodec/tests/.gitignore +++ b/libavcodec/tests/.gitignore @@ -9,6 +9,7 @@ /fft-fixed32 /golomb /h264_levels +/h265_levels /htmlsubtitles /iirfilter /imgconvert -- 2.21.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avformat/latmenc: abort if no extradata is available
On 10/15/2019 12:00 PM, Paul B Mahol wrote: > LGTM > > On 10/15/19, James Almer wrote: >> Fixes ticket #8273. >> >> Signed-off-by: James Almer >> --- >> libavformat/latmenc.c | 3 ++- >> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c >> index db867ebf1a..5ae677f5da 100644 >> --- a/libavformat/latmenc.c >> +++ b/libavformat/latmenc.c >> @@ -176,7 +176,8 @@ static int latm_write_packet(AVFormatContext *s, >> AVPacket *pkt) >> if (ret < 0) >> return ret; >> memcpy(par->extradata, side_data, side_data_size); >> -} >> +} else >> +return AVERROR_INVALIDDATA; >> } >> } Pushed, thanks. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avfilter/vf_adadenoise: add x86 SIMD
On 10/15/2019 12:55 PM, Paul B Mahol wrote: > On 10/15/19, James Almer wrote: >> On 10/15/2019 12:21 PM, Paul B Mahol wrote: >>> +;-- >>> +; void ff_filter_row(const uint8_t *src, uint8_t *dst, >>> +;const uint8_t **srcf, >>> +;int w, int mid, int size, >>> +;int thra, int thrb) >>> +;-- >>> + >>> +INIT_XMM sse4 >>> +cglobal atadenoise_filter_row8, 8,12,13, src, dst, srcf, w, mid, size, >>> thra, thrb, i, j, srcfx, x >> >> You need to sign extend all the int argument. And if you're not using >> thra and thrb, then don't load them and save two gprs. > > Sorry but they are used. You're loading them from memory manually using r6m and r7m after having the prologue code load them to gprs in the cglobal line. Since you don't need them in r6q and r7q, just reuse them for i and j. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avformat/latmenc: abort if no extradata is available
LGTM On 10/15/19, James Almer wrote: > Fixes ticket #8273. > > Signed-off-by: James Almer > --- > libavformat/latmenc.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c > index db867ebf1a..5ae677f5da 100644 > --- a/libavformat/latmenc.c > +++ b/libavformat/latmenc.c > @@ -176,7 +176,8 @@ static int latm_write_packet(AVFormatContext *s, > AVPacket *pkt) > if (ret < 0) > return ret; > memcpy(par->extradata, side_data, side_data_size); > -} > +} else > +return AVERROR_INVALIDDATA; > } > } > > -- > 2.23.0 > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avfilter/vf_adadenoise: add x86 SIMD
On 10/15/19, James Almer wrote: > On 10/15/2019 12:21 PM, Paul B Mahol wrote: >> +;-- >> +; void ff_filter_row(const uint8_t *src, uint8_t *dst, >> +;const uint8_t **srcf, >> +;int w, int mid, int size, >> +;int thra, int thrb) >> +;-- >> + >> +INIT_XMM sse4 >> +cglobal atadenoise_filter_row8, 8,12,13, src, dst, srcf, w, mid, size, >> thra, thrb, i, j, srcfx, x > > You need to sign extend all the int argument. And if you're not using > thra and thrb, then don't load them and save two gprs. Sorry but they are used. > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avfilter/vf_adadenoise: add x86 SIMD
On 10/15/2019 12:21 PM, Paul B Mahol wrote: > +;-- > +; void ff_filter_row(const uint8_t *src, uint8_t *dst, > +;const uint8_t **srcf, > +;int w, int mid, int size, > +;int thra, int thrb) > +;-- > + > +INIT_XMM sse4 > +cglobal atadenoise_filter_row8, 8,12,13, src, dst, srcf, w, mid, size, thra, > thrb, i, j, srcfx, x You need to sign extend all the int argument. And if you're not using thra and thrb, then don't load them and save two gprs. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avfilter/vf_adadenoise: add x86 SIMD
Signed-off-by: Paul B Mahol --- libavfilter/atadenoise.h | 36 +++ libavfilter/vf_atadenoise.c | 16 +-- libavfilter/x86/Makefile | 2 + libavfilter/x86/vf_atadenoise.asm| 147 +++ libavfilter/x86/vf_atadenoise_init.c | 40 5 files changed, 234 insertions(+), 7 deletions(-) create mode 100644 libavfilter/atadenoise.h create mode 100644 libavfilter/x86/vf_atadenoise.asm create mode 100644 libavfilter/x86/vf_atadenoise_init.c diff --git a/libavfilter/atadenoise.h b/libavfilter/atadenoise.h new file mode 100644 index 00..c1fdc2f64e --- /dev/null +++ b/libavfilter/atadenoise.h @@ -0,0 +1,36 @@ + /* + * Copyright (c) 2019 Paul B Mahol + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_ATADENOISE_H +#define AVFILTER_ATADENOISE_H + +#include +#include + +typedef struct ATADenoiseDSPContext { +void (*filter_row)(const uint8_t *src, uint8_t *dst, + const uint8_t **srcf, + int w, int mid, int size, + int thra, int thrb); +} ATADenoiseDSPContext; + +void ff_atadenoise_init_x86(ATADenoiseDSPContext *dsp, int depth); + +#endif /* AVFILTER_ATADENOISE_H */ diff --git a/libavfilter/vf_atadenoise.c b/libavfilter/vf_atadenoise.c index be7c4e2a34..d85fa79961 100644 --- a/libavfilter/vf_atadenoise.c +++ b/libavfilter/vf_atadenoise.c @@ -33,6 +33,7 @@ #define FF_BUFQUEUE_SIZE 129 #include "bufferqueue.h" +#include "atadenoise.h" #include "formats.h" #include "internal.h" #include "video.h" @@ -57,10 +58,8 @@ typedef struct ATADenoiseContext { int available; int (*filter_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); -void (*filter_row)(const uint8_t *src, uint8_t *dst, - const uint8_t *srcf[SIZE], - int w, int mid, int size, - int thra, int thrb); + +ATADenoiseDSPContext dsp; } ATADenoiseContext; #define OFFSET(x) offsetof(ATADenoiseContext, x) @@ -209,7 +208,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) srcf[i] = data[i] + slice_start * linesize[i]; for (y = slice_start; y < slice_end; y++) { -s->filter_row(src, dst, srcf, w, mid, size, thra, thrb); +s->dsp.filter_row(src, dst, srcf, w, mid, size, thra, thrb); dst += out->linesize[p]; src += in->linesize[p]; @@ -239,9 +238,9 @@ static int config_input(AVFilterLink *inlink) depth = desc->comp[0].depth; s->filter_slice = filter_slice; if (depth == 8) -s->filter_row = filter_row8; +s->dsp.filter_row = filter_row8; else -s->filter_row = filter_row16; +s->dsp.filter_row = filter_row16; s->thra[0] = s->fthra[0] * (1 << depth) - 1; s->thra[1] = s->fthra[1] * (1 << depth) - 1; @@ -250,6 +249,9 @@ static int config_input(AVFilterLink *inlink) s->thrb[1] = s->fthrb[1] * (1 << depth) - 1; s->thrb[2] = s->fthrb[2] * (1 << depth) - 1; +if (ARCH_X86) +ff_atadenoise_init_x86(>dsp, depth); + return 0; } diff --git a/libavfilter/x86/Makefile b/libavfilter/x86/Makefile index 4cd914366a..06f832e36c 100644 --- a/libavfilter/x86/Makefile +++ b/libavfilter/x86/Makefile @@ -2,6 +2,7 @@ OBJS-$(CONFIG_SCENE_SAD) += x86/scene_sad_init.o OBJS-$(CONFIG_AFIR_FILTER) += x86/af_afir_init.o OBJS-$(CONFIG_ANLMDN_FILTER) += x86/af_anlmdn_init.o +OBJS-$(CONFIG_ATADENOISE_FILTER) += x86/vf_atadenoise_init.o OBJS-$(CONFIG_BLEND_FILTER) += x86/vf_blend_init.o OBJS-$(CONFIG_BWDIF_FILTER) += x86/vf_bwdif_init.o OBJS-$(CONFIG_COLORSPACE_FILTER) += x86/colorspacedsp_init.o @@ -39,6 +40,7 @@ X86ASM-OBJS-$(CONFIG_SCENE_SAD) += x86/scene_sad.o X86ASM-OBJS-$(CONFIG_AFIR_FILTER)+= x86/af_afir.o X86ASM-OBJS-$(CONFIG_ANLMDN_FILTER) += x86/af_anlmdn.o +X86ASM-OBJS-$(CONFIG_ATADENOISE_FILTER) += x86/vf_atadenoise.o X86ASM-OBJS-$(CONFIG_BLEND_FILTER) += x86/vf_blend.o X86ASM-OBJS-$(CONFIG_BWDIF_FILTER) += x86/vf_bwdif.o
Re: [FFmpeg-devel] [PATCH v5 1/4] lavc/libxavs2: fix parameter setting result determination
On Mon, Oct 14, 2019 at 09:22:42PM +0800, hwren wrote: > Signed-off-by: hwren > --- > libavcodec/libxavs2.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) will apply thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Never trust a computer, one day, it may think you are the virus. -- Compn signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avformat/latmenc: abort if no extradata is available
Fixes ticket #8273. Signed-off-by: James Almer --- libavformat/latmenc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c index db867ebf1a..5ae677f5da 100644 --- a/libavformat/latmenc.c +++ b/libavformat/latmenc.c @@ -176,7 +176,8 @@ static int latm_write_packet(AVFormatContext *s, AVPacket *pkt) if (ret < 0) return ret; memcpy(par->extradata, side_data, side_data_size); -} +} else +return AVERROR_INVALIDDATA; } } -- 2.23.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v1 4/4] fate/filter-video: add 10bit test for unsharp filter
On Mon, Oct 14, 2019 at 06:27:07PM +0800, lance.lmw...@gmail.com wrote: > From: Limin Wang > > Signed-off-by: Limin Wang > --- > tests/fate/filter-video.mak | 3 ++ > tests/ref/fate/filter-unsharp-yuv420p10 | 55 + > 2 files changed, 58 insertions(+) > create mode 100644 tests/ref/fate/filter-unsharp-yuv420p10 fails on mips TESTfilter-unsharp-yuv420p10 --- src/tests/ref/fate/filter-unsharp-yuv420p10 2019-10-15 15:35:27.272519847 +0200 +++ tests/data/fate/filter-unsharp-yuv420p102019-10-15 16:39:22.896600653 +0200 @@ -3,53 +3,53 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0,1, 304128, 0x375a055d -0, 1, 1,1, 304128, 0x43374234 -0, 2, 2,1, 304128, 0xba34fded -0, 3, 3,1, 304128, 0xaab09f3b -0, 4, 4,1, 304128, 0x1e42b90e -0, 5, 5,1, 304128, 0x135f1088 -0, 6, 6,1, 304128, 0x780c001a -0, 7, 7,1, 304128, 0x10f209fa -0, 8, 8,1, 304128, 0x54aa698a -0, 9, 9,1, 304128, 0x72470a4b -0, 10, 10,1, 304128, 0x7cac80ed -0, 11, 11,1, 304128, 0x820ffb09 -0, 12, 12,1, 304128, 0x7386656a -0, 13, 13,1, 304128, 0x3662c47e -0, 14, 14,1, 304128, 0x1b07cbce -0, 15, 15,1, 304128, 0x2577c6d2 -0, 16, 16,1, 304128, 0xb478c1a6 -0, 17, 17,1, 304128, 0x27549b49 -0, 18, 18,1, 304128, 0xd2f628ca -0, 19, 19,1, 304128, 0x95cc5544 -0, 20, 20,1, 304128, 0x844a1bda -0, 21, 21,1, 304128, 0x4bcfc8b2 -0, 22, 22,1, 304128, 0x403e2302 -0, 23, 23,1, 304128, 0x275214bf -0, 24, 24,1, 304128, 0x2f1e8e7b -0, 25, 25,1, 304128, 0x14d68a42 -0, 26, 26,1, 304128, 0x2d966e74 -0, 27, 27,1, 304128, 0x7d2f0bf2 -0, 28, 28,1, 304128, 0x5744d92e -0, 29, 29,1, 304128, 0x4c89f858 -0, 30, 30,1, 304128, 0x9702e22e -0, 31, 31,1, 304128, 0xea18c80e -0, 32, 32,1, 304128, 0x5290813c -0, 33, 33,1, 304128, 0xc8909e8c -0, 34, 34,1, 304128, 0xf9c985f9 -0, 35, 35,1, 304128, 0xcdf626f0 -0, 36, 36,1, 304128, 0xc517d607 -0, 37, 37,1, 304128, 0xe765923b -0, 38, 38,1, 304128, 0xf12fa5f6 -0, 39, 39,1, 304128, 0x04bf7f2b -0, 40, 40,1, 304128, 0x695762d6 -0, 41, 41,1, 304128, 0xb1bf1983 -0, 42, 42,1, 304128, 0x654dc4b2 -0, 43, 43,1, 304128, 0x161854b6 -0, 44, 44,1, 304128, 0x3d56b1c1 -0, 45, 45,1, 304128, 0xa16f54a8 -0, 46, 46,1, 304128, 0x02fffb2f -0, 47, 47,1, 304128, 0x04bddde4 -0, 48, 48,1, 304128, 0xf5687316 -0, 49, 49,1, 304128, 0x2a9a7dc6 +0, 0, 0,1, 304128, 0x12f2055d +0, 1, 1,1, 304128, 0xda454234 +0, 2, 2,1, 304128, 0x9497fded +0, 3, 3,1, 304128, 0xe6db9f3b +0, 4, 4,1, 304128, 0x4214b90e +0, 5, 5,1, 304128, 0xe09d1088 +0, 6, 6,1, 304128, 0x5c89001a +0, 7, 7,1, 304128, 0xe9e809fa +0, 8, 8,1, 304128, 0xc4ec698a +0, 9, 9,1, 304128, 0x48610a4b +0, 10, 10,1, 304128, 0xdd9b80ed +0, 11, 11,1, 304128, 0x679afb09 +0, 12, 12,1, 304128, 0xf364656a +0, 13, 13,1, 304128, 0x5612c47e +0, 14, 14,1, 304128, 0x2cafcbce +0, 15, 15,1, 304128, 0x382bc6d2 +0, 16, 16,1, 304128, 0xcc5cc1a6 +0, 17, 17,1, 304128, 0x73459b49 +0, 18, 18,1, 304128, 0x9bf328ca +0, 19, 19,1, 304128, 0x2d7b5544 +0, 20, 20,1, 304128, 0x56a31bda +0, 21, 21,1, 304128, 0x715bc8b2 +0, 22, 22,1, 304128, 0x0c9f2302 +0, 23, 23,1,
[FFmpeg-devel] [PATCH 3/9] avformat/matroskaenc: Use smaller types
Several members of structures denote offsets inside dynamic buffers and therefore always fit into an int. So it is unnecessary to use an int64_t for them. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 63ad6e47b4..e024c58c84 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -95,11 +95,11 @@ typedef struct mkv_track { int write_dts; int has_cue; int sample_rate; -int64_t sample_rate_offset; +int sample_rate_offset; int64_t last_timestamp; int64_t duration; -int64_t duration_offset; -int64_t codecpriv_offset; +int duration_offset; +int codecpriv_offset; int64_t ts_offset; } mkv_track; @@ -134,7 +134,7 @@ typedef struct MatroskaMuxContext { AVIOContext *cluster_bc; int64_t cluster_pos;///< file offset of the current cluster int64_t cluster_pts; -int64_t duration_offset; +int duration_offset; int64_t duration; mkv_seekhead*seekhead; mkv_cues*cues; -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 8/9] avformat/matroskaenc: Improve cues in case of no-video
The Matroska muxer currently only adds CuePoints in three cases: a) For video keyframes. b) For the first audio frame in a new cluster if in dash-mode. c) For subtitles. This means that ordinary Matroska audio files won't have any cues which impedes seeking. This commit changes this. For every track in a file without video track it is checked and tracked whether a cue entry has already been added for said track for the current cluster. This is used to add a cue entry for each first packet of each track in each cluster. Implements #3149. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c| 21 - tests/ref/fate/aac-autobsf-adtstoasc | 4 ++-- tests/ref/lavf/mka | 4 ++-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 7c9941c567..1a3d337e5b 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2253,6 +2253,10 @@ static void mkv_end_cluster(AVFormatContext *s) MatroskaMuxContext *mkv = s->priv_data; end_ebml_master_crc32(s->pb, >cluster_bc, mkv); +if (!mkv->have_video) { +for (int i = 0; i < s->nb_streams; i++) +mkv->tracks[i].has_cue = 0; +} mkv->cluster_pos = -1; avio_flush(s->pb); } @@ -2365,7 +2369,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, AVPacket *pkt) return 0; } -static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_cue) +static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt) { MatroskaMuxContext *mkv = s->priv_data; AVIOContext *pb; @@ -2410,9 +2414,11 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ if (par->codec_type != AVMEDIA_TYPE_SUBTITLE) { mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); -if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && (par->codec_type == AVMEDIA_TYPE_VIDEO && keyframe || add_cue)) { +if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && keyframe && +(par->codec_type == AVMEDIA_TYPE_VIDEO || !mkv->have_video && !track->has_cue)) { ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, tracknum, ts, mkv->cluster_pos, relative_packet_pos, -1); if (ret < 0) return ret; +track->has_cue = 1; } } else { if (par->codec_id == AV_CODEC_ID_WEBVTT) { @@ -2479,8 +2485,7 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) // on seeing key frames. start_new_cluster = keyframe; } else if (mkv->is_dash && codec_type == AVMEDIA_TYPE_AUDIO && - (mkv->cluster_pos == -1 || -cluster_time > mkv->cluster_time_limit)) { + cluster_time > mkv->cluster_time_limit) { // For DASH audio, we create a Cluster based on cluster_time_limit start_new_cluster = 1; } else if (!mkv->is_dash && @@ -2504,9 +2509,7 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) // check if we have an audio packet cached if (mkv->cur_audio_pkt.size > 0) { -// for DASH audio, a CuePoint has to be added when there is a new cluster. -ret = mkv_write_packet_internal(s, >cur_audio_pkt, -mkv->is_dash ? start_new_cluster : 0); +ret = mkv_write_packet_internal(s, >cur_audio_pkt); av_packet_unref(>cur_audio_pkt); if (ret < 0) { av_log(s, AV_LOG_ERROR, @@ -2521,7 +2524,7 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) if (pkt->size > 0) ret = av_packet_ref(>cur_audio_pkt, pkt); } else -ret = mkv_write_packet_internal(s, pkt, 0); +ret = mkv_write_packet_internal(s, pkt); return ret; } @@ -2550,7 +2553,7 @@ static int mkv_write_trailer(AVFormatContext *s) // check if we have an audio packet cached if (mkv->cur_audio_pkt.size > 0) { -ret = mkv_write_packet_internal(s, >cur_audio_pkt, 0); +ret = mkv_write_packet_internal(s, >cur_audio_pkt); av_packet_unref(>cur_audio_pkt); if (ret < 0) { av_log(s, AV_LOG_ERROR, diff --git a/tests/ref/fate/aac-autobsf-adtstoasc b/tests/ref/fate/aac-autobsf-adtstoasc index 9bf9dfe78f..a94364c213 100644 --- a/tests/ref/fate/aac-autobsf-adtstoasc +++ b/tests/ref/fate/aac-autobsf-adtstoasc @@ -1,5 +1,5 @@ -b09fc2f554712adbf84fe7899eb679d4 *tests/data/fate/aac-autobsf-adtstoasc.matroska -6695 tests/data/fate/aac-autobsf-adtstoasc.matroska +f1bccaa7ab4967e7dc4f5b07c372b040 *tests/data/fate/aac-autobsf-adtstoasc.matroska +6723 tests/data/fate/aac-autobsf-adtstoasc.matroska #extradata 0:2, 0x0030001c #tb 0: 1/1000 #media_type 0: audio diff --git a/tests/ref/lavf/mka b/tests/ref/lavf/mka index a244893cf2..f51f465533 100644 --- a/tests/ref/lavf/mka +++ b/tests/ref/lavf/mka @@ -1,3 +1,3 @@
[FFmpeg-devel] [PATCH 6/9] avformat/matroskaenc: Cosmetics
Contains renaming of variables (e.g. mkv_write_cues() contained variables called tracknum that actually contain the index of a track in s->streams and not the track number (which can differ in case an explicit dash track number is set)). Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 0d21ab055a..9df3f929d7 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -80,7 +80,7 @@ typedef struct mkv_cuepoint { uint64_tpts; int stream_idx; int tracknum; -int64_t cluster_pos;///< file offset of the cluster containing the block +int64_t cluster_pos;///< offset of the cluster containing the block relative to the segment int64_t relative_pos; ///< relative offset from the position of the cluster containing the block int64_t duration; ///< duration of the block according to time base } mkv_cuepoint; @@ -584,11 +584,12 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra for (j = 0; j < num_tracks; j++) tracks[j].has_cue = 0; for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) { -int tracknum = entry[j].stream_idx; -av_assert0(tracknum>=0 && tracknumstreams[tracknum]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) +int idx = entry[j].stream_idx; + +av_assert0(idx >= 0 && idx < num_tracks); +if (tracks[idx].has_cue && s->streams[idx]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) continue; -tracks[tracknum].has_cue = 1; +tracks[idx].has_cue = 1; ctp_nb ++; } @@ -600,11 +601,11 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra for (j = 0; j < num_tracks; j++) tracks[j].has_cue = 0; for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) { -int tracknum = entry[j].stream_idx; +int idx = entry[j].stream_idx; -if (tracks[tracknum].has_cue && s->streams[tracknum]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) +if (tracks[idx].has_cue && s->streams[idx]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) continue; -tracks[tracknum].has_cue = 1; +tracks[idx].has_cue = 1; track_positions = start_ebml_master(dyn_cp, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE); put_ebml_uint(dyn_cp, MATROSKA_ID_CUETRACK , entry[j].tracknum ); put_ebml_uint(dyn_cp, MATROSKA_ID_CUECLUSTERPOSITION , entry[j].cluster_pos); @@ -2102,13 +2103,13 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, mkv_track *track = >tracks[pkt->stream_index]; uint8_t *data = NULL, *side_data = NULL; int offset = 0, size = pkt->size, side_data_size = 0; -int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; +int64_t ts = track->write_dts ? pkt->dts : pkt->pts; uint64_t additional_id = 0; int64_t discard_padding = 0; uint8_t track_number = (mkv->is_dash ? mkv->dash_track_number : (pkt->stream_index + 1)); ebml_master block_group, block_additions, block_more; -ts += mkv->tracks[pkt->stream_index].ts_offset; +ts += track->ts_offset; /* The following string is identical to the one in mkv_write_vtt_blocks * so that only one copy needs to exist in binaries. */ @@ -2364,21 +2365,21 @@ static int mkv_check_new_extra_data(AVFormatContext *s, AVPacket *pkt) static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_cue) { MatroskaMuxContext *mkv = s->priv_data; -AVIOContext *pb = s->pb; +AVIOContext *pb; AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; mkv_track *track= >tracks[pkt->stream_index]; int keyframe= !!(pkt->flags & AV_PKT_FLAG_KEY); int duration= pkt->duration; int ret; -int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; +int64_t ts = track->write_dts ? pkt->dts : pkt->pts; int64_t relative_packet_pos; -int dash_tracknum = mkv->is_dash ? mkv->dash_track_number : pkt->stream_index + 1; +int tracknum = mkv->is_dash ? mkv->dash_track_number : pkt->stream_index + 1; if (ts == AV_NOPTS_VALUE) { av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n"); return AVERROR(EINVAL); } -ts += mkv->tracks[pkt->stream_index].ts_offset; +ts += track->ts_offset; if (mkv->cluster_pos != -1) { int64_t cluster_time = ts - mkv->cluster_pts; @@ -2407,7 +2408,7 @@ static int
[FFmpeg-devel] [PATCH 5/9] avformat/matroskaenc: Use more appropriate function name
mkv_start_new_cluster() actually didn't start a new cluster, but ended the old one instead and emitted a debug message that it had started a new cluster. This has been changed: The debug message has been moved to the place that really starts a new cluster and the function has been renamed to mkv_end_cluster(). Furthermore, without this debug message the function can be used for flushing. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 18 -- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index eb8977ff9c..0d21ab055a 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2244,16 +2244,12 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *p return pkt->duration; } -static void mkv_start_new_cluster(AVFormatContext *s, AVPacket *pkt) +static void mkv_end_cluster(AVFormatContext *s) { MatroskaMuxContext *mkv = s->priv_data; end_ebml_master_crc32(s->pb, >cluster_bc, mkv); mkv->cluster_pos = -1; -av_log(s, AV_LOG_DEBUG, - "Starting new cluster at offset %" PRIu64 " bytes, " - "pts %" PRIu64 ", dts %" PRIu64 "\n", - avio_tell(s->pb), pkt->pts, pkt->dts); avio_flush(s->pb); } @@ -2387,8 +2383,8 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ if (mkv->cluster_pos != -1) { int64_t cluster_time = ts - mkv->cluster_pts; if ((int16_t)cluster_time != cluster_time) { +mkv_end_cluster(s); av_log(s, AV_LOG_WARNING, "Starting new cluster due to timestamp\n"); -mkv_start_new_cluster(s, pkt); } } @@ -2399,6 +2395,10 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ return ret; put_ebml_uint(mkv->cluster_bc, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts)); mkv->cluster_pts = FFMAX(0, ts); +av_log(s, AV_LOG_DEBUG, + "Starting new cluster with timestamp " + "%" PRId64 " at offset %" PRId64 " bytes\n", + mkv->cluster_pts, mkv->cluster_pos); } pb = mkv->cluster_bc; @@ -2491,7 +2491,7 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) } if (mkv->cluster_pos != -1 && start_new_cluster) { -mkv_start_new_cluster(s, pkt); +mkv_end_cluster(s); } if (!mkv->cluster_pos) @@ -2528,12 +2528,10 @@ static int mkv_write_flush_packet(AVFormatContext *s, AVPacket *pkt) if (!pkt) { if (mkv->cluster_pos != -1) { -end_ebml_master_crc32(s->pb, >cluster_bc, mkv); -mkv->cluster_pos = -1; +mkv_end_cluster(s); av_log(s, AV_LOG_DEBUG, "Flushing cluster at offset %" PRIu64 " bytes\n", avio_tell(s->pb)); -avio_flush(s->pb); } return 1; } -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 7/9] avformat/matroskaenc: Add check for using explicit track number
When creating dash streams, the track number is externally prescribed and not derived from the number of streams in the AVFormatContext. Up until now, a track number of zero was allowed, although this is an illegal track number; furthermore, it was not checked whether the number of tracks for a file using an explicit track number was more than one, as such a file would be invalid (it would be impossible to tell to which track a block belongs if different tracks share the same track number). Signed-off-by: Andreas Rheinhardt --- Using 0 as dash_track_number could lead to an access to mkv->last_track_timestamp[-1] (before said field was moved to mkv_track). libavformat/matroskaenc.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 9df3f929d7..7c9941c567 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1858,6 +1858,9 @@ static int mkv_write_header(AVFormatContext *s) } else mkv->mode = MODE_MATROSKAv2; +if (mkv->is_dash && s->nb_streams != 1) +return AVERROR(EINVAL); + if (mkv->mode != MODE_WEBM || av_dict_get(s->metadata, "stereo_mode", NULL, 0) || av_dict_get(s->metadata, "alpha_mode", NULL, 0)) @@ -2773,7 +2776,7 @@ static const AVOption options[] = { { "cluster_size_limit", "Store at most the provided amount of bytes in a cluster. ", OFFSET(cluster_size_limit), AV_OPT_TYPE_INT , { .i64 = -1 }, -1, INT_MAX, FLAGS }, { "cluster_time_limit", "Store at most the provided number of milliseconds in a cluster.", OFFSET(cluster_time_limit), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, FLAGS }, { "dash", "Create a WebM file conforming to WebM DASH specification", OFFSET(is_dash), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, -{ "dash_track_number", "Track number for the DASH stream", OFFSET(dash_track_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 127, FLAGS }, +{ "dash_track_number", "Track number for the DASH stream", OFFSET(dash_track_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 127, FLAGS }, { "live", "Write files assuming it is a live stream.", OFFSET(is_live), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "allow_raw_vfw", "allow RAW VFW mode", OFFSET(allow_raw_vfw), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "write_crc32", "write a CRC32 element inside every Level 1 element", OFFSET(write_crc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 9/9] avformat/matroskaenc: Fix ReferenceBlock timestamp
In order to indicate that the frames in a BlockGroup are not keyframes, one has to add a ReferenceBlock element containing the timestamp of a reference block that has already been written. The timestamp ought to be relative to the timestamp of the block it is attached to. Yet the Matroska muxer used the relative timestamp of the preceding block of the track, i.e. the timestamp of the preceding block relative to the timestamp of the cluster containing said block (that need not be the cluster containing the current block). This has been fixed. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 1a3d337e5b..cb608f3297 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2182,9 +2182,9 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, av_free(data); if (blockid == MATROSKA_ID_BLOCK && !keyframe) { -put_ebml_sint(pb, MATROSKA_ID_BLOCKREFERENCE, track->last_timestamp); +put_ebml_sint(pb, MATROSKA_ID_BLOCKREFERENCE, track->last_timestamp - ts); } -track->last_timestamp = ts - mkv->cluster_pts; +track->last_timestamp = ts; if (discard_padding) { put_ebml_sint(pb, MATROSKA_ID_DISCARDPADDING, discard_padding); -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/9] avformat/matroskaenc: Remove redundant assert
The Matroska muxer groups index entries with the same pts together in order to save a few bytes. Because of Matroska's variable-length length fields, mkv_write_cues() does this by first finding out how many index entries will be grouped together before actually writing them. Currently, it is asserted at both of these stages that the stream index of the list of designated index entries is valid. But the second assert is redundant, because the very same index entries have already been checked. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index e024c58c84..eb8977ff9c 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -601,7 +601,7 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra tracks[j].has_cue = 0; for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) { int tracknum = entry[j].stream_idx; -av_assert0(tracknum>=0 && tracknumstreams[tracknum]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) continue; tracks[tracknum].has_cue = 1; -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/9] avformat/matroskaenc: Move track-related fields to mkv_track
Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 42 ++- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 4b32130a94..63ad6e47b4 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -96,6 +96,9 @@ typedef struct mkv_track { int has_cue; int sample_rate; int64_t sample_rate_offset; +int64_t last_timestamp; +int64_t duration; +int64_t duration_offset; int64_t codecpriv_offset; int64_t ts_offset; } mkv_track; @@ -155,11 +158,6 @@ typedef struct MatroskaMuxContext { uint32_t chapter_id_offset; int wrote_chapters; -int64_t last_track_timestamp[MAX_TRACKS]; - -int64_t *stream_durations; -int64_t *stream_duration_offsets; - int allow_raw_vfw; } MatroskaMuxContext; @@ -419,8 +417,6 @@ static void mkv_free(MatroskaMuxContext *mkv) { av_freep(>attachments); } av_freep(>tracks); -av_freep(>stream_durations); -av_freep(>stream_duration_offsets); } /** @@ -1679,7 +1675,7 @@ static int mkv_write_tags(AVFormatContext *s) tag = start_ebml_master(pb, MATROSKA_ID_SIMPLETAG, 0); put_ebml_string(pb, MATROSKA_ID_TAGNAME, "DURATION"); -mkv->stream_duration_offsets[i] = avio_tell(pb); +mkv->tracks[i].duration_offset = avio_tell(pb); // Reserve space to write duration as a 20-byte string. // 2 (ebml id) + 1 (data size) + 20 (data) @@ -1967,14 +1963,6 @@ static int mkv_write_header(AVFormatContext *s) end_ebml_master_crc32(s->pb, >info_bc, mkv); pb = s->pb; -// initialize stream_duration fields -mkv->stream_durations= av_mallocz(s->nb_streams * sizeof(int64_t)); -mkv->stream_duration_offsets = av_mallocz(s->nb_streams * sizeof(int64_t)); -if (!mkv->stream_durations || !mkv->stream_duration_offsets) { -ret = AVERROR(ENOMEM); -goto fail; -} - ret = mkv_write_tracks(s); if (ret < 0) goto fail; @@ -2111,6 +2099,7 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, { MatroskaMuxContext *mkv = s->priv_data; AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; +mkv_track *track = >tracks[pkt->stream_index]; uint8_t *data = NULL, *side_data = NULL; int offset = 0, size = pkt->size, side_data_size = 0; int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; @@ -2189,10 +2178,9 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, av_free(data); if (blockid == MATROSKA_ID_BLOCK && !keyframe) { -put_ebml_sint(pb, MATROSKA_ID_BLOCKREFERENCE, - mkv->last_track_timestamp[track_number - 1]); +put_ebml_sint(pb, MATROSKA_ID_BLOCKREFERENCE, track->last_timestamp); } -mkv->last_track_timestamp[track_number - 1] = ts - mkv->cluster_pts; +track->last_timestamp = ts - mkv->cluster_pts; if (discard_padding) { put_ebml_sint(pb, MATROSKA_ID_DISCARDPADDING, discard_padding); @@ -2382,6 +2370,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ MatroskaMuxContext *mkv = s->priv_data; AVIOContext *pb = s->pb; AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; +mkv_track *track= >tracks[pkt->stream_index]; int keyframe= !!(pkt->flags & AV_PKT_FLAG_KEY); int duration= pkt->duration; int ret; @@ -2452,9 +2441,7 @@ FF_ENABLE_DEPRECATION_WARNINGS mkv->duration = FFMAX(mkv->duration, ts + duration); -if (mkv->stream_durations) -mkv->stream_durations[pkt->stream_index] = -FFMAX(mkv->stream_durations[pkt->stream_index], ts + duration); +track->duration = FFMAX(track->duration, ts + duration); return 0; } @@ -2629,20 +2616,21 @@ static int mkv_write_trailer(AVFormatContext *s) end_ebml_master_crc32(pb, >tracks_bc, mkv); // update stream durations -if (!mkv->is_live && mkv->stream_durations) { +if (!mkv->is_live) { int i; int64_t curr = avio_tell(mkv->tags_bc); for (i = 0; i < s->nb_streams; ++i) { AVStream *st = s->streams[i]; +mkv_track *track = >tracks[i]; -if (mkv->stream_duration_offsets[i] > 0) { -double duration_sec = mkv->stream_durations[i] * av_q2d(st->time_base); +if (track->duration_offset > 0) { +double duration_sec = track->duration * av_q2d(st->time_base); char duration_string[20] = ""; av_log(s, AV_LOG_DEBUG, "stream %d end duration = %" PRIu64 "\n", i, - mkv->stream_durations[i]); +
[FFmpeg-devel] [PATCH 1/9] avformat/matroskaenc: Fix memleak upon failure
Signed-off-by: Andreas Rheinhardt --- The easiest way to hit this memleak is by supplying an unreasonably low number to reserve_index_space. libavformat/matroskaenc.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 37706e56c7..4b32130a94 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2567,7 +2567,7 @@ static int mkv_write_trailer(AVFormatContext *s) if (ret < 0) { av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret); -return ret; +goto fail; } } @@ -2577,7 +2577,7 @@ static int mkv_write_trailer(AVFormatContext *s) ret = mkv_write_chapters(s); if (ret < 0) -return ret; +goto fail; if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) { @@ -2595,7 +2595,8 @@ static int mkv_write_trailer(AVFormatContext *s) "Insufficient space reserved for cues: %d " "(needed: %" PRId64 ").\n", mkv->reserve_cues_space, cues_end - cuespos); -return AVERROR(EINVAL); +ret = AVERROR(EINVAL); +goto fail; } if (cues_end < cuespos + mkv->reserve_cues_space) @@ -2610,7 +2611,7 @@ static int mkv_write_trailer(AVFormatContext *s) ret = mkv_add_seekhead_entry(mkv->seekhead, MATROSKA_ID_CUES, cuespos); if (ret < 0) -return ret; +goto fail; } mkv_write_seekhead(pb, mkv); @@ -2664,8 +2665,9 @@ static int mkv_write_trailer(AVFormatContext *s) end_ebml_master(pb, mkv->segment); } +fail: mkv_free(mkv); -return 0; +return ret; } static int mkv_query_codec(enum AVCodecID codec_id, int std_compliance) -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v5] avcodec/v210dec: add the frame and slice threading support
On Mon, Oct 14, 2019 at 10:12:45PM +0200, Michael Niedermayer wrote: > On Sun, Oct 13, 2019 at 06:45:16AM +0800, Limin Wang wrote: > > On Sat, Oct 12, 2019 at 11:46:58PM +0200, Michael Niedermayer wrote: > > > On Sat, Oct 12, 2019 at 06:58:21PM +0800, lance.lmw...@gmail.com wrote: > > > > From: Limin Wang > > > > > > > > The multithread is avoid one core cpu is full with other filter like > > > > scale etc. > > > > About the performance, the gain is very small, below is my testing for > > > > performance. > > > > In order to avoid the disk bottleneck, I'll use stream_loop mode for 10 > > > > frame > > > > only. > > > > > > > > ./ffmpeg -y -i ~/Movies/4k_Rec709_ProResHQ.mov -c:v v210 -f rawvideo > > > > -frames 10 > > > > ~/Movies/1.v210 > > > > > > > > master: > > > > ./ffmpeg -threads 1 -s 4096x3072 -stream_loop 100 -i ~/Movies/1.v210 > > > > -benchmark > > > > -f null - > > > > frame= 1010 fps= 42 q=-0.0 Lsize=N/A time=00:00:40.40 bitrate=N/A > > > > speed=1.69x > > > > video:529kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB > > > > muxing > > > > overhead: unknown > > > > bench: utime=10.082s stime=13.784s rtime=23.889s > > > > bench: maxrss=147836928kB > > > > > > > > patch applied: > > > > ./ffmpeg -threads 4 -thread_type frame+slice -s 4096x3072 -stream_loop > > > > 100 -i > > > > ~/Movies/1.v210 -benchmark -f null - > > > > > > > > frame= 1010 fps= 55 q=-0.0 Lsize=N/A time=00:00:40.40 bitrate=N/A > > > > speed=2.22x > > > > video:529kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB > > > > muxing > > > > overhead: unknown > > > > bench: utime=11.407s stime=17.258s rtime=18.279s > > > > bench: maxrss=442884096kB > > > > > > > > Signed-off-by: Limin Wang > > > > --- > > > > libavcodec/v210dec.c | 132 +++ > > > > libavcodec/v210dec.h | 1 + > > > > 2 files changed, 85 insertions(+), 48 deletions(-) > > > > > > > > diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c > > > > index 5a33d8c089..c3ef8051e6 100644 > > > > --- a/libavcodec/v210dec.c > > > > +++ b/libavcodec/v210dec.c > > > > @@ -28,6 +28,7 @@ > > > > #include "libavutil/internal.h" > > > > #include "libavutil/mem.h" > > > > #include "libavutil/intreadwrite.h" > > > > +#include "thread.h" > > > > > > > > #define READ_PIXELS(a, b, c) \ > > > > do { \ > > > > @@ -37,6 +38,12 @@ > > > > *c++ = (val >> 20) & 0x3FF; \ > > > > } while (0) > > > > > > > > +typedef struct ThreadData { > > > > +AVFrame *frame; > > > > +uint8_t *buf; > > > > +int stride; > > > > +} ThreadData; > > > > + > > > > static void v210_planar_unpack_c(const uint32_t *src, uint16_t *y, > > > > uint16_t *u, uint16_t *v, int width) > > > > { > > > > uint32_t val; > > > > @@ -64,21 +71,87 @@ static av_cold int decode_init(AVCodecContext > > > > *avctx) > > > > avctx->pix_fmt = AV_PIX_FMT_YUV422P10; > > > > avctx->bits_per_raw_sample = 10; > > > > > > > > +s->thread_count = av_clip(avctx->thread_count, 1, > > > > avctx->height/4); > > > > s->aligned_input = 0; > > > > ff_v210dec_init(s); > > > > > > > > return 0; > > > > } > > > > > > > > +static int v210_decode_slice(AVCodecContext *avctx, void *arg, int > > > > jobnr, int threadnr) > > > > +{ > > > > +V210DecContext *s = avctx->priv_data; > > > > +int h, w; > > > > +ThreadData *td = arg; > > > > +AVFrame *frame = td->frame; > > > > +int stride = td->stride; > > > > +int slice_h = avctx->height / s->thread_count; > > > > +int slice_m = avctx->height % s->thread_count; > > > > +int slice_start = jobnr * slice_h; > > > > > > this is still not correct > > > the height of a slice is not the same for all slices if the frame height > > > is not divisible by the number of slices > > Yes, so the last slice is processed different by the following code. I have > > tested with > > different thread number to verify the fate-v210 result. > > > > make fate-v210 SAMPLES=../fate-suite thread_type=frame+slice threads=[1-7] > > What the code should do is split the frame evenly not > have many small slices and a really large last one > > a really large last slice would need much longer to be processed making > the work distribution uneven Michael, I have updated the patch to split the frame evenly. Please review it. I have tested with fate with threads from 1-18 to check the result. In addition, I updated the comment message with more performance data. > > thx > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > If you fake or manipulate statistics in a paper in physics you will never > get a job again. > If you fake or manipulate statistics in a paper in medicin you will get > a job for life at the pharma industry. > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org >
[FFmpeg-devel] [PATCH v6] avcodec/v210dec: add the frame and slice threading support
From: Limin Wang Threading is to avoid a core cpu being occupied fully with other filters like scale, regarding performance, if your cpu frequency is very high, the gain is very small, but with more cores and fewer cpu MHz cpus, you will get more improvements. The following is my testing results of performance on two different system: 1, testing result with my old mac pro ./ffmpeg -y -i ./4k_4096_3072.mov -c:v v210 -f rawvideo -frames 10 ./1.v210 ./ffmpeg -threads 1 -s 4096x3072 -stream_loop 100 -i ./1.v210 -benchmark -f null - frame= 1010 fps= 42 q=-0.0 Lsize=N/A time=00:00:40.40 bitrate=N/A speed=1.69x patch applied: ./ffmpeg -threads 4 -thread_type frame+slice -s 4096x3072 -stream_loop 100 -i ./1.v210 -benchmark -f null - frame= 1010 fps= 55 q=-0.0 Lsize=N/A time=00:00:40.40 bitrate=N/A speed=2.22x 2, testing result with x86 server (Intel(R) Xeon(R) CPU E5-2650 v2 @ 2.60GHz): ./ffmpeg -y -i ./4k_3840_2160.ts -c:v v210 -f rawvideo -frames 50 ./2.v210 ./ffmpeg -threads 1 -s 3840x2160 -stream_loop 20 -i ./2.v210 -benchmark -f null - frame= 1050 fps= 80 q=-0.0 Lsize=N/A time=00:00:42.00 bitrate=N/A speed=3.19x patch applied: ./ffmpeg -threads 2 -thread_type frame+slice -s 3840x2160 -stream_loop 20 -i ./2.v210 -benchmark -f null - frame= 1050 fps=111 q=-0.0 Lsize=N/A time=00:00:42.00 bitrate=N/A speed=4.45x ./ffmpeg -threads 4 -thread_type frame+slice -s 3840x2160 -stream_loop 20 -i ./2.v210 -benchmark -f null - frame= 1050 fps=145 q=-0.0 Lsize=N/A time=00:00:42.00 bitrate=N/A speed=5.81x Signed-off-by: Limin Wang --- libavcodec/v210dec.c | 135 --- libavcodec/v210dec.h | 1 + 2 files changed, 88 insertions(+), 48 deletions(-) diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c index 5a33d8c089..91c2fe0d07 100644 --- a/libavcodec/v210dec.c +++ b/libavcodec/v210dec.c @@ -28,6 +28,7 @@ #include "libavutil/internal.h" #include "libavutil/mem.h" #include "libavutil/intreadwrite.h" +#include "thread.h" #define READ_PIXELS(a, b, c) \ do { \ @@ -37,6 +38,12 @@ *c++ = (val >> 20) & 0x3FF; \ } while (0) +typedef struct ThreadData { +AVFrame *frame; +uint8_t *buf; +int stride; +} ThreadData; + static void v210_planar_unpack_c(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width) { uint32_t val; @@ -64,21 +71,90 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUV422P10; avctx->bits_per_raw_sample = 10; +s->thread_count = av_clip(avctx->thread_count, 1, avctx->height/4); s->aligned_input = 0; ff_v210dec_init(s); return 0; } +static int v210_decode_slice(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) +{ +V210DecContext *s = avctx->priv_data; +int h, w; +ThreadData *td = arg; +AVFrame *frame = td->frame; +int stride = td->stride; +int slice_h = avctx->height / s->thread_count; +int slice_m = avctx->height % s->thread_count; +int slice_start; +int slice_end; +uint8_t *psrc; +uint16_t *y, *u, *v; + +slice_start = jobnr * slice_h; +slice_start += FFMIN(jobnr, slice_m); +slice_end = slice_start + slice_h; +if (jobnr < slice_m) +slice_end ++; + +psrc = td->buf + stride * slice_start; +y = (uint16_t*)frame->data[0] + slice_start * frame->linesize[0] / 2; +u = (uint16_t*)frame->data[1] + slice_start * frame->linesize[1] / 2; +v = (uint16_t*)frame->data[2] + slice_start * frame->linesize[2] / 2; +for (h = slice_start; h < slice_end; h++) { +const uint32_t *src = (const uint32_t*)psrc; +uint32_t val; + +w = (avctx->width / 12) * 12; +s->unpack_frame(src, y, u, v, w); + +y += w; +u += w >> 1; +v += w >> 1; +src += (w << 1) / 3; + +if (w < avctx->width - 5) { +READ_PIXELS(u, y, v); +READ_PIXELS(y, u, y); +READ_PIXELS(v, y, u); +READ_PIXELS(y, v, y); +w += 6; +} + +if (w < avctx->width - 1) { +READ_PIXELS(u, y, v); + +val = av_le2ne32(*src++); +*y++ = val & 0x3FF; +if (w < avctx->width - 3) { +*u++ = (val >> 10) & 0x3FF; +*y++ = (val >> 20) & 0x3FF; + +val = av_le2ne32(*src++); +*v++ = val & 0x3FF; +*y++ = (val >> 10) & 0x3FF; +} +} + +psrc += stride; +y += frame->linesize[0] / 2 - avctx->width + (avctx->width & 1); +u += frame->linesize[1] / 2 - avctx->width / 2; +v += frame->linesize[2] / 2 - avctx->width / 2; +} + +return 0; +} + static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { V210DecContext *s = avctx->priv_data; - -int h, w, ret, stride, aligned_input; +
Re: [FFmpeg-devel] [PATCH 1/5] avcodec/binkaudio: Check sample rate
On Mon, Oct 14, 2019 at 10:06:55PM +0200, Michael Niedermayer wrote: > On Sun, Oct 13, 2019 at 10:51:49AM +1100, Peter Ross wrote: > > On Sat, Oct 12, 2019 at 06:53:05PM -0300, James Almer wrote: > > > On 10/12/2019 5:47 PM, Michael Niedermayer wrote: > > > > On Fri, Oct 11, 2019 at 08:51:54PM +1100, Peter Ross wrote: > > > >> On Fri, Oct 11, 2019 at 12:40:07AM +0200, Michael Niedermayer wrote: > > > >>> Fixes: signed integer overflow: 1092624416 * 2 cannot be represented > > > >>> in type 'int' > > > >>> Fixes: > > > >>> 18045/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BINKAUDIO_RDFT_fuzzer-5718519492116480 > > > >>> > > > >>> Found-by: continuous fuzzing process > > > >>> https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg > > > >>> Signed-off-by: Michael Niedermayer > > > >>> --- > > > >>> libavcodec/binkaudio.c | 2 ++ > > > >>> 1 file changed, 2 insertions(+) > > > >>> > > > >>> diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c > > > >>> index 96cf968c66..2384ebf312 100644 > > > >>> --- a/libavcodec/binkaudio.c > > > >>> +++ b/libavcodec/binkaudio.c > > > >>> @@ -95,6 +95,8 @@ static av_cold int decode_init(AVCodecContext > > > >>> *avctx) > > > >>> if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) { > > > >>> // audio is already interleaved for the RDFT format variant > > > >>> avctx->sample_fmt = AV_SAMPLE_FMT_FLT; > > > >>> +if (sample_rate > INT_MAX / avctx->channels) > > > >>> +return AVERROR_INVALIDDATA; > > > >>> sample_rate *= avctx->channels; > > > >>> s->channels = 1; > > > >>> if (!s->version_b) > > > >>> -- > > > >>> 2.23.0 > > > >> > > > >> i think this checl belongs inside the fuzzer test harness, or as a > > > >> general > > > >> purpose codec check. > > > >> > > > >> the bink and smaker demuxers will only ever use BINKAUDIO_RDFT with 1 > > > >> or 2 channels. > > > > > > > > In the case of the overflow channels was 2 > > > > > > > > what check do you suggest to be done in general code ? > > > > A check specific to the fuzzer would fail to prevent this from happening > > > > outside the fuzzer > > > > fair enough, approve patch. > > > > > Judging by the bink demuxer reading 16 bits for sample_rate, I assume > > > binkaudio has a max valid value for it, like 44k or 48k, in which case a > > > check like the one for channels at the beginning of this function would > > > be the proper non general code fix. If not one of those two values, then > > > just <= UINT16_MAX. > > > > the bink demuxer supplied sample_reate is 16-bits wide, smacker is 24-bits. > > the error can never happen when using ffmpeg+libavformat+libavcodec to play > > any > > bink or smacker files, but i guess we need to account for other use cases. > > do you prefer the original patch or a check based on the maximum the current > demuxers can inject (24bits) ? original one is good. -- Peter (A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B) signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v18 1/2] lavc/svt_hevc: add libsvt hevc encoder wrapper
Signed-off-by: Zhengxu Huang Signed-off-by: Hassene Tmar Signed-off-by: Jun Zhao Signed-off-by: Jing Sun --- configure| 4 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/libsvt_hevc.c | 497 +++ libavcodec/version.h | 2 +- 5 files changed, 504 insertions(+), 1 deletion(-) create mode 100644 libavcodec/libsvt_hevc.c diff --git a/configure b/configure index 8413826..7b5e9f9 100755 --- a/configure +++ b/configure @@ -264,6 +264,7 @@ External library support: --enable-libspeexenable Speex de/encoding via libspeex [no] --enable-libsrt enable Haivision SRT protocol via libsrt [no] --enable-libssh enable SFTP protocol via libssh [no] + --enable-libsvthevc enable HEVC encoding via svt [no] --enable-libtensorflow enable TensorFlow as a DNN module backend for DNN based filters like sr [no] --enable-libtesseractenable Tesseract, needed for ocr filter [no] @@ -1793,6 +1794,7 @@ EXTERNAL_LIBRARY_LIST=" libspeex libsrt libssh +libsvthevc libtensorflow libtesseract libtheora @@ -3198,6 +3200,7 @@ libshine_encoder_select="audio_frame_queue" libspeex_decoder_deps="libspeex" libspeex_encoder_deps="libspeex" libspeex_encoder_select="audio_frame_queue" +libsvt_hevc_encoder_deps="libsvthevc" libtheora_encoder_deps="libtheora" libtwolame_encoder_deps="libtwolame" libvo_amrwbenc_encoder_deps="libvo_amrwbenc" @@ -6276,6 +6279,7 @@ enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr enabled libssh&& require_pkg_config libssh libssh libssh/sftp.h sftp_init enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init enabled libsrt&& require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket +enabled libsvthevc&& require_pkg_config libsvthevc SvtHevcEnc EbApi.h EbInitHandle enabled libtensorflow && require libtensorflow tensorflow/c/c_api.h TF_Version -ltensorflow enabled libtesseract && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 37a84a6..334b755 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -994,6 +994,7 @@ OBJS-$(CONFIG_LIBOPUS_ENCODER)+= libopusenc.o libopus.o \ OBJS-$(CONFIG_LIBSHINE_ENCODER) += libshine.o OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o +OBJS-$(CONFIG_LIBSVT_HEVC_ENCODER)+= libsvt_hevc.o OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 41f6801..9415e94 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -708,6 +708,7 @@ extern AVCodec ff_librsvg_decoder; extern AVCodec ff_libshine_encoder; extern AVCodec ff_libspeex_encoder; extern AVCodec ff_libspeex_decoder; +extern AVCodec ff_libsvt_hevc_encoder; extern AVCodec ff_libtheora_encoder; extern AVCodec ff_libtwolame_encoder; extern AVCodec ff_libvo_amrwbenc_encoder; diff --git a/libavcodec/libsvt_hevc.c b/libavcodec/libsvt_hevc.c new file mode 100644 index 000..d2fdaf3 --- /dev/null +++ b/libavcodec/libsvt_hevc.c @@ -0,0 +1,497 @@ +/* +* Scalable Video Technology for HEVC encoder library plugin +* +* Copyright (c) 2019 Intel Corporation +* +* This file is part of FFmpeg. +* +* FFmpeg is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* FFmpeg 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "EbApi.h" + +#include "libavutil/common.h" +#include "libavutil/frame.h" +#include "libavutil/opt.h" + +#include "internal.h" +#include "avcodec.h" + +typedef enum eos_status { +EOS_NOT_REACHED = 0, +EOS_SENT, +EOS_RECEIVED +}EOS_STATUS; + +typedef struct SvtContext { +AVClass *class; + +EB_H265_ENC_CONFIGURATION enc_params; +EB_COMPONENTTYPE *svt_handle; +EB_BUFFERHEADERTYPE in_buf; +uint8_t *in_data; +EOS_STATUS eos_flag; + +// User options. +
[FFmpeg-devel] [PATCH] lavc/qsvenc: Fix bitrate_limit to allow AVC encode in limited bitrate
MFXVideoENCODE_Query calls CheckVideoParamQueryLike in MSDK and will determine whether to set param.mfx.TargetKbps to the allowed minTargetKbps according to the bitrate_limit in extco2 buffer. Thus q->param.ExtParam must be set before MFXVideoENCODE_Query in case minTargetKbps is written to TargetKbps by default. 1080P AVC encoding with option "-bitrate_limit 0 -b:v 100k": Before patch: 902 kbps After patch: 156 kbps Signed-off-by: Linjie Fu --- libavcodec/qsvenc.c | 38 +++--- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index ba85d64..dcff778 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -1052,25 +1052,6 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) if (ret < 0) return ret; -ret = MFXVideoENCODE_Query(q->session, >param, >param); -if (ret == MFX_WRN_PARTIAL_ACCELERATION) { -av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n"); -} else if (ret < 0) { -return ff_qsv_print_error(avctx, ret, - "Error querying encoder params"); -} - -ret = MFXVideoENCODE_QueryIOSurf(q->session, >param, >req); -if (ret < 0) -return ff_qsv_print_error(avctx, ret, - "Error querying (IOSurf) the encoding parameters"); - -if (opaque_alloc) { -ret = qsv_init_opaque_alloc(avctx, q); -if (ret < 0) -return ret; -} - if (avctx->hwaccel_context) { AVQSVContext *qsv = avctx->hwaccel_context; int i, j; @@ -1100,6 +1081,25 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) q->param.NumExtParam = q->nb_extparam_internal; } +ret = MFXVideoENCODE_Query(q->session, >param, >param); +if (ret == MFX_WRN_PARTIAL_ACCELERATION) { +av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n"); +} else if (ret < 0) { +return ff_qsv_print_error(avctx, ret, + "Error querying encoder params"); +} + +ret = MFXVideoENCODE_QueryIOSurf(q->session, >param, >req); +if (ret < 0) +return ff_qsv_print_error(avctx, ret, + "Error querying (IOSurf) the encoding parameters"); + +if (opaque_alloc) { +ret = qsv_init_opaque_alloc(avctx, q); +if (ret < 0) +return ret; +} + ret = MFXVideoENCODE_Init(q->session, >param); if (ret < 0) return ff_qsv_print_error(avctx, ret, -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".