[vlc-devel] [PATCH v2 2/3] Add CineForm plugin v1
Rémi Denis-Courmont
remi at remlab.net
Wed Nov 22 16:46:21 CET 2017
Le tiistaina 21. marraskuuta 2017, 11.41.06 EET Emeric Grange a écrit :
> ---
> modules/codec/cineformsdk/cineform_allocator.c | 76 ++
> modules/codec/cineformsdk/cineform_allocator.h | 38 +
> modules/codec/cineformsdk/cineform_debug.c | 246 +++++
> modules/codec/cineformsdk/cineform_debug.h | 41 +
> modules/codec/cineformsdk/cineform_plugin.c | 1364
> ++++++++++++++++++++++++ modules/codec/cineformsdk/cineform_plugin.h |
> 173 +++
> modules/codec/cineformsdk/cineform_settings.c | 427 ++++++++
> modules/codec/cineformsdk/cineform_settings.h | 94 ++
> 8 files changed, 2459 insertions(+)
> create mode 100755 modules/codec/cineformsdk/cineform_allocator.c
> create mode 100755 modules/codec/cineformsdk/cineform_allocator.h
> create mode 100755 modules/codec/cineformsdk/cineform_debug.c
> create mode 100755 modules/codec/cineformsdk/cineform_debug.h
> create mode 100755 modules/codec/cineformsdk/cineform_plugin.c
> create mode 100755 modules/codec/cineformsdk/cineform_plugin.h
> create mode 100755 modules/codec/cineformsdk/cineform_settings.c
> create mode 100755 modules/codec/cineformsdk/cineform_settings.h
>
> diff --git a/modules/codec/cineformsdk/cineform_allocator.c
> b/modules/codec/cineformsdk/cineform_allocator.c new file mode 100755
> index 0000000000..99a897dd14
> --- /dev/null
> +++ b/modules/codec/cineformsdk/cineform_allocator.c
> @@ -0,0 +1,76 @@
> +/**************************************************************************
> *** + * cineform_allocator.c : CineForm decoder and encoder
> +
> ***************************************************************************
> ** + * Copyright (C) 2017 VLC authors and VideoLAN
> + * $Id$
> + *
> + * Authors: Emeric Grange <egrange at gopro.com>
> + *
> + * This program 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.
> + *
> + * This program 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 "cineform_allocator.h"
> +
> +#include <stdlib.h> // regular memory handling
> +#include <emmintrin.h> // aligned memory handling and SSE intrisics?
Not portable.
> +
> +#ifdef _MSC_VER
> +#include "malloc.h" // _mm_malloc for MSVC
> +#endif
> +
> +void *AlignedAlloc(void *allocator, size_t size, size_t alignment)
> +{
> + (void)allocator; // custom UNUSED macro
> + return _mm_malloc(size, alignment);
Nonexistent symbol. You probably mean aligned_alloc().
> +}
> +
> +void AlignedFree(void *allocator, void *block)
> +{
> + (void)allocator; // custom UNUSED macro
> + _mm_free(block);
Ditto; free().
> +}
> +
> +void UnalignedFree(void *allocator, void *block)
> +{
> + (void)allocator; // custom UNUSED macro
> + free(block);
> +}
> +
> +void *UnalignedAlloc(void *allocator, size_t size)
> +{
> + (void)allocator; // custom UNUSED macro
> + return malloc(size);
> +}
> +
> +void *AllocateBuffer(size_t size)
> +{
> + // Align buffers to a 16 byte boundary for SSE2 instructions
> + const size_t alignment = 16;
Not portable.
> +
> +#ifdef _MSC_VER
> + return _aligned_malloc(size, alignment);
> +#else
> + return _mm_malloc(size, alignment);
> +#endif
Same as above.
> +}
> +
> +void DeallocateBuffer(void *buffer)
> +{
> +#ifdef _MSC_VER
> + _aligned_free(buffer);
> +#else
> + _mm_free(buffer);
> +#endif
> +}
Ditto.
> diff --git a/modules/codec/cineformsdk/cineform_allocator.h
> b/modules/codec/cineformsdk/cineform_allocator.h new file mode 100755
> index 0000000000..e8fd9febed
> --- /dev/null
> +++ b/modules/codec/cineformsdk/cineform_allocator.h
> @@ -0,0 +1,38 @@
> +/**************************************************************************
> *** + * cineform_allocator.h : CineForm decoder and encoder
> +
> ***************************************************************************
> ** + * Copyright (C) 2017 VLC authors and VideoLAN
> + * $Id$
> + *
> + * Authors: Emeric Grange <egrange at gopro.com>
> + *
> + * This program 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.
> + *
> + * This program 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. +
> ***************************************************************************
> **/ +
> +#ifndef CINEFORM_ALLOCATOR_H
> +#define CINEFORM_ALLOCATOR_H
> +
> +#include <stddef.h>
> +
> +void *AlignedAlloc(void *allocator, size_t size, size_t alignment);
> +void AlignedFree(void *allocator, void *block);
> +
> +void UnalignedFree(void *allocator, void *block);
> +void *UnalignedAlloc(void *allocator, size_t size);
> +
> +void *AllocateBuffer(size_t size);
> +void DeallocateBuffer(void *buffer);
> +
> +#endif // CINEFORM_ALLOCATOR_H
> diff --git a/modules/codec/cineformsdk/cineform_debug.c
> b/modules/codec/cineformsdk/cineform_debug.c new file mode 100755
> index 0000000000..ae7ed4f02f
> --- /dev/null
> +++ b/modules/codec/cineformsdk/cineform_debug.c
> @@ -0,0 +1,246 @@
> +/**************************************************************************
> *** + * cineform_debug.c : CineForm decoder and encoder
> +
> ***************************************************************************
> ** + * Copyright (C) 2017 VLC authors and VideoLAN
> + * $Id$
> + *
> + * Authors: Emeric Grange <egrange at gopro.com>
> + *
> + * This program 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.
> + *
> + * This program 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 "cineform_debug.h"
> +
> +#include <stdio.h>
> +
> +char *getFourccStr_le(unsigned fcc, char *fcc_str)
vlc_fourcc_t
> +{
> + // "fcc_str" must be at least 5 characters long
> + if (fcc_str)
> + {
> + fcc_str[0] = (char)((fcc >> 0) & 0xFF);
> + fcc_str[1] = (char)((fcc >> 8) & 0xFF);
> + fcc_str[2] = (char)((fcc >> 16) & 0xFF);
> + fcc_str[3] = (char)((fcc >> 24) & 0xFF);
GetDWLE().
> + fcc_str[4] = '\0';
> + }
> +
> + return fcc_str;
> +}
> +
> +char *getFourccStr_be(unsigned fcc, char *fcc_str)
> +{
> + // "fcc_str" must be at least 5 characters long
> + if (fcc_str)
> + {
> + fcc_str[0] = (char)((fcc >> 24) & 0xFF);
> + fcc_str[1] = (char)((fcc >> 16) & 0xFF);
> + fcc_str[2] = (char)((fcc >> 8) & 0xFF);
> + fcc_str[3] = (char)((fcc >> 0) & 0xFF);
GetDWBE().
> + fcc_str[4] = '\0';
> + }
> +
> + return fcc_str;
> +}
> +
> +void printBuffer(const unsigned char *bufferData, const unsigned
> bufferSize)
size_t
> +{
> + if (bufferData)
> + {
> + printf("BUFFER (raw) datas @ '%p'\n", &bufferData);
> + printf("BUFFER (raw) datas (size : %i)\n", bufferSize);
Please don´t use stdio for debugging.
> +
> + // how many bytes per line
> + unsigned linesize = 48;
> + unsigned datavolumetoprint = 1000000000;
> +
> + // how many bytes to print
> + if (datavolumetoprint <= 0 || datavolumetoprint > bufferSize)
> + {
> + datavolumetoprint = bufferSize;
> + }
> +
> + for (unsigned i = 0; i < datavolumetoprint; i+=linesize)
> + {
> + for (unsigned j = 0; j < linesize; j++)
> + {
> + printf("%02X ", (bufferData[i+j]));
> + }
> + printf("\n");
> + }
> + printf("\n");
> +
> + // Force flush to the terminal?
> + //fflush(stdout);
> + //fflush(stderr);
> + }
> + else
> + {
> + printf("printBuffer() ERROR > empty sampleDatas\n");
> + }
> +}
> +
> +const char *getErrorString(const CFHD_Error error)
> +{
> + switch (error)
> + {
> + case CFHD_ERROR_OKAY:
> + return "OKAY";
> +
> + case CFHD_ERROR_INVALID_ARGUMENT:
> + return "INVALID ARGUMENT";
> + case CFHD_ERROR_OUTOFMEMORY:
> + return "OUT OF MEMORY";
> + case CFHD_ERROR_BADFORMAT:
> + return "BAD FORMAT";
> + case CFHD_ERROR_BADSCALING:
> + return "BAD SCALING";
> + case CFHD_ERROR_BADSAMPLE:
> + return "BAD SAMPLE";
> + case CFHD_ERROR_INTERNAL:
> + return "INTERNAL ERROR";
> + case CFHD_ERROR_METADATA_CLASS:
> + return "METADATA CLASS";
> + case CFHD_ERROR_METADATA_UNDEFINED:
> + return "METADATA UNDEFINED";
> + case CFHD_ERROR_METADATA_END:
> + return "METADATA END";
> + case CFHD_ERROR_UNEXPECTED:
> + return "UNEXPECTED ERROR";
> + case CFHD_ERROR_BAD_RESOLUTION:
> + return "BAD RESOLUTION";
> + case CFHD_ERROR_BAD_PIXEL_SIZE:
> + return "BAD PIXEL SIZE";
> + case CFHD_ERROR_NOT_FINISHED:
> + return "NOT FINISHED";
> + case CFHD_ERROR_ENCODING_NOT_STARTED:
> + return "NOT STARTED";
> + case CFHD_ERROR_METADATA_ATTACHED:
> + return "METADATA ATTACHED";
> + case CFHD_ERROR_BAD_METADATA:
> + return "BAD METADATA";
> + case CFHD_ERROR_THREAD_CREATE_FAILED:
> + return "THREAD CREATE FAILED";
> + case CFHD_ERROR_THREAD_WAIT_FAILED:
> + return "THREAD WAIT FAILED";
> + case CFHD_ERROR_UNKNOWN_TAG:
> + return "UNKNOWN TAG";
> + case CFHD_ERROR_LICENSING:
> + return "LICENSING ERROR";
> +
> + // Error codes returned by the codec library
> + case CFHD_ERROR_CODEC_ERROR:
> + return "CODEC ERROR";
> + case CFHD_ERROR_DECODE_BUFFER_SIZE:
> + return "DECODE BUFFER SIZE ERROR";
> +
> + // Error codes used by the sample code distributed with the codec SDK
> + case CFHD_ERROR_SAMPLE_CODE:
> + return "SAMPLE CODE ERROR";
> + case CFHD_ERROR_FILE_CREATE:
> + return "FILE CREATE ERROR";
> + case CFHD_ERROR_FILE_OPEN:
> + return "FILE OPEN ERROR";
> + case CFHD_ERROR_BADFILE:
> + return "BAD FILE";
> + case CFHD_ERROR_READ_FAILURE:
> + return "READ FAILURE";
> + case CFHD_ERROR_WRITE_FAILURE:
> + return "WRITE FAILURE";
> + case CFHD_ERROR_FILE_SIZE:
> + return "FILE SIZE ERROR";
> + case CFHD_ERROR_END_OF_FILE:
> + return "END OF FILE";
> + case CFHD_ERROR_END_OF_DATABASE:
> + return "END OF DATABASE";
> + case CFHD_ERROR_THREAD:
> + return "THREAD ERROR";
> +
> + default:
> + return "UNKNOW ERROR";
> + }
> +}
> +
> +void printEncodedFormats(const CFHD_EncodedFormat format)
> +{
> + switch (format)
> + {
> + case CFHD_ENCODED_FORMAT_YUV_422:
> + printf("- encodedFormat: CFHD_ENCODED_FORMAT_YUV_422\n");
> + break;
> + case CFHD_ENCODED_FORMAT_RGB_444:
> + printf("- encodedFormat: CFHD_ENCODED_FORMAT_RGB_444\n");
> + break;
> + case CFHD_ENCODED_FORMAT_RGBA_4444:
> + printf("- encodedFormat: CFHD_ENCODED_FORMAT_RGBA_4444\n");
> + break;
> + case CFHD_ENCODED_FORMAT_BAYER:
> + printf("- encodedFormat: CFHD_ENCODED_FORMAT_BAYER\n");
> + break;
> + case CFHD_ENCODED_FORMAT_YUVA_4444:
> + printf("- encodedFormat: CFHD_ENCODED_FORMAT_YUVA_4444\n");
> + break;
> + }
> +}
> +
> +void printEncodingFormats(const unsigned level, const CFHD_EncodedFormat
> format) +{
> + printf("SUPPORTED ENCODING FORMATS\n");
> + if (level & 1)
> + {
> + if (format == CFHD_ENCODED_FORMAT_YUV_422)
> + printf("[X] ");
> + else
> + printf("- ");
> +
> + printf("YUV 4:2:2\n");
> + }
> + if (level & 2)
> + {
> + if (format == CFHD_ENCODED_FORMAT_RGB_444)
> + printf("[X] ");
> + else
> + printf("- ");
> +
> + printf("RGB 4:4:4\n");
> + }
> + if (level & 4)
> + {
> + if (format == CFHD_ENCODED_FORMAT_RGBA_4444)
> + printf("[X] ");
> + else
> + printf("- ");
> +
> + printf("RGBA 4:4:4:4\n");
> + }
> + if (level & 8)
> + {
> + if (format == CFHD_ENCODED_FORMAT_BAYER)
> + printf("[X] ");
> + else
> + printf("- ");
> +
> + printf("RAW bayer\n");
> + }
> + if (level & 16)
> + {
> + if (format == CFHD_ENCODED_FORMAT_YUVA_4444)
> + printf("[X] ");
> + else
> + printf("- ");
> +
> + printf("YUVA 4:4:4:4\n");
> + }
> +}
> diff --git a/modules/codec/cineformsdk/cineform_debug.h
> b/modules/codec/cineformsdk/cineform_debug.h new file mode 100755
> index 0000000000..2a19dacf60
> --- /dev/null
> +++ b/modules/codec/cineformsdk/cineform_debug.h
> @@ -0,0 +1,41 @@
> +/**************************************************************************
> *** + * cineform_debug.h : CineForm decoder and encoder
> +
> ***************************************************************************
> ** + * Copyright (C) 2017 VLC authors and VideoLAN
> + * $Id$
> + *
> + * Authors: Emeric Grange <egrange at gopro.com>
> + *
> + * This program 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.
> + *
> + * This program 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. +
> ***************************************************************************
> **/ +
> +#ifndef CINEFORM_DEBUG_H
> +#define CINEFORM_DEBUG_H
> +
> +#include <stdint.h>
> +#include <string.h>
> +
> +char *getFourccStr_le(unsigned fcc, char *fcc_str);
> +char *getFourccStr_be(unsigned fcc, char *fcc_str);
> +void printBuffer(const unsigned char *bufferData, const unsigned
> bufferSize); +
> +#include <cineformsdk/CFHDError.h>
> +#include <cineformsdk/CFHDTypes.h>
> +
> +const char *getErrorString(const CFHD_Error error);
> +void printEncodedFormats(const CFHD_EncodedFormat format);
> +void printEncodingFormats(const unsigned level, const CFHD_EncodedFormat
> format); +
> +#endif // CINEFORM_DEBUG_H
> diff --git a/modules/codec/cineformsdk/cineform_plugin.c
> b/modules/codec/cineformsdk/cineform_plugin.c new file mode 100755
> index 0000000000..1ef78cbbfa
> --- /dev/null
> +++ b/modules/codec/cineformsdk/cineform_plugin.c
> @@ -0,0 +1,1364 @@
> +/**************************************************************************
> *** + * cineform_plugin.c : CineForm decoder and encoder
> +
> ***************************************************************************
> ** + * Copyright (C) 2017 VLC authors and VideoLAN
> + * $Id$
> + *
> + * Authors: Emeric Grange <egrange at gopro.com>
> + *
> + * This program 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.
> + *
> + * This program 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 "cineform_plugin.h"
> +#include "cineform_allocator.h"
> +#include "cineform_settings.h"
> +#include "cineform_debug.h"
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdint.h>
> +#include <time.h>
> +#include <math.h>
> +
> +/**************************************************************************
> *** + * Module descriptor
> +
> ***************************************************************************
> **/ +
> +vlc_module_begin ()
> +
> + set_category(CAT_INPUT)
> + set_subcategory(SUBCAT_INPUT_VCODEC)
> +
> + // Description
> + set_shortname("CineForm")
> + set_description("CineForm DECODER plugin")
Watch case.
> + set_help("CineForm encoding/decoding plugin for VLC3, using GoPro
> CineForm SDK") +
Abbreviate.
> + set_capability("video decoder", 100)
> + set_callbacks(OpenDecoder, CloseDecoder)
> +
> + // User defined settings
> + set_section("Decoding", NULL)
> + add_bool("cineform-skip-frames", true,
> + SKIP_FRAMES_TEXT, SKIP_FRAMES_LONGTEXT, false)
> + add_string("cineform-output-formats", "AUTO",
> + OUTPUT_FORMATS_TEXT, OUTPUT_FORMATS_LONGTEXT, false)
> + vlc_config_set(VLC_CONFIG_LIST, (sizeof(output_formats) /
> sizeof(char*)) - 1, + output_formats,
> output_formats);
> + add_string("cineform-decoding-resolutions", "FULL RESOLUTION",
> + DECODING_RESOLUTIONS_TEXT, DECODING_RESOLUTIONS_LONGTEXT,
> false) + vlc_config_set(VLC_CONFIG_LIST,
> (sizeof(decoding_resolutions) / sizeof(char*)) - 1, +
> decoding_resolutions, decoding_resolutions); +
> add_string("cineform-decoding-flags", "NONE",
> + DECODING_FLAGS_TEXT, DECODING_FLAGS_LONGTEXT, false)
> + vlc_config_set(VLC_CONFIG_LIST, (sizeof(decoding_flags) /
> sizeof(char*)) - 1, + decoding_flags,
> decoding_flags);
> + add_string("cineform-stereo-select", "DEFAULT",
> + STEREO_SELECT_TEXT, STEREO_SELECT_LONGTEXT, false)
> + vlc_config_set(VLC_CONFIG_LIST, (sizeof(stereo_select) /
> sizeof(char*)) - 1, + stereo_select, stereo_select);
> + add_string("cineform-stereo-type", "DEFAULT",
> + STEREO_TYPE_TEXT, STEREO_TYPE_LONGTEXT, false)
> + vlc_config_set(VLC_CONFIG_LIST, (sizeof(stereo_type) /
> sizeof(char*)) - 1, + stereo_type, stereo_type);
> + add_string("cineform-stereo-flags", "DEFAULT",
> + STEREO_FLAGS_TEXT, STEREO_FLAGS_LONGTEXT, false)
> + vlc_config_set(VLC_CONFIG_LIST, (sizeof(stereo_flags) /
> sizeof(char*)) - 1, + stereo_flags, stereo_flags);
> +
> +#if ENABLE_ENCODER == 1
> + add_submodule()
> +
> + set_capability("encoder", 150)
> + set_description("CineForm ENCODER plugin")
> + set_callbacks(OpenEncoder, CloseEncoder)
> +
> + // User defined settings
> + set_section("Encoding", NULL)
> + add_string("cineform-encoding-format", "YUV 4:2:2",
> + ENCODING_FORMAT_TEXT, ENCODING_FORMAT_LONGTEXT, false)
> + vlc_config_set(VLC_CONFIG_LIST, (sizeof(encoding_format) /
> sizeof(char*)) - 1, + encoding_format,
> encoding_format);
> + add_string("cineform-encoding-quality", "MEDIUM",
> + ENCODING_QUALITY_TEXT, ENCODING_QUALITY_LONGTEXT, false)
> + vlc_config_set(VLC_CONFIG_LIST, (sizeof(encoding_quality) /
> sizeof(char*)) - 1, + encoding_quality,
> encoding_quality);
> + add_string("cineform-encoding-flags", "NONE",
> + ENCODING_FLAGS_TEXT, ENCODING_FLAGS_LONGTEXT, false)
> + vlc_config_set(VLC_CONFIG_LIST, (sizeof(encoding_flags) /
> sizeof(char*)) - 1, + encoding_flags,
> encoding_flags);
> +#endif // ENABLE_ENCODER
> +
> +vlc_module_end ()
> +
> +/**************************************************************************
> *** + * Decoder
> +
> ***************************************************************************
> **/ +
> +/**
> + * @brief Starts and init the CineForm decoder plugin.
> + * @param obj A pointer to a decoder_t structure allocated by VLC.
> + * @return VLC_SUCCESS or an error code.
> + */
> +int OpenDecoder(vlc_object_t *obj)
> +{
> + decoder_t *p_dec = (decoder_t*)obj;
> + decoder_sys_t *p_sys = NULL;
> +
> + // First, check if we have a CineForm video track as input
> + if (p_dec->fmt_in.i_cat == VIDEO_ES && p_dec->fmt_in.i_codec ==
> VLC_CODEC_CINEFORM) + {
> + char fcc[5];
> + msg_Info(p_dec, "CineForm DECODER plugin (OpenDecoder with fourCC
> '%s')", + getFourccStr_le(p_dec->fmt_in.i_codec, fcc));
That´s rather noisy.
> + }
> + else
> + {
> + return VLC_EGENERIC;
> + }
> +
> + // Init decoder_sys_t // Allocate the memory needed to store the
> decoder's private context + if ((p_dec->p_sys = p_sys = (decoder_sys_t
> *)malloc(sizeof(*p_sys))) == NULL)
Useless cast.
Avoid assignment as truth value where possible. Ditto below.
> + {
> + msg_Err(p_dec, "CineForm DECODER plugin (unable to allocate
> internal decoding structure)"); + return VLC_ENOMEM;
> + }
> +
> + // Set VLC output properties
> + p_dec->fmt_out.i_cat = VIDEO_ES;
> +
> + // Register VLC decoding callback
> + p_dec->pf_decode = DecodeVideo;
> +
> + // Init decoder_sys_t content
> + p_sys->SDKversion = 0;
> + p_sys->SAMPLEversion = 0;
> +
> + p_sys->sampleCount = 0;
> + p_sys->sampleDecoded = 0;
> + p_sys->sampleSkipped = 0;
> + p_sys->sampleFailed = 0;
> +
> + p_sys->sourceWidth = 0;
> + p_sys->sourceHeight = 0;
> + p_sys->sourceChannels = 0;
> + p_sys->sourcePixelSize = 0;
> + p_sys->sourcePixelFormat = CFHD_ENCODED_FORMAT_YUV_422;
> +
> + p_sys->directMapping = false;
> +
> + p_sys->internalBuffer = NULL;
> + p_sys->internalBufferWidth = 0;
> + p_sys->internalBufferHeight = 0;
> + p_sys->internalBufferPitch = 0;
> + p_sys->internalBufferSize = 0;
> + p_sys->internalBufferSizeComputed = 0;
> + p_sys->internalBufferPixelFormat = CFHD_PIXEL_FORMAT_UNKNOWN;
> +
> + p_sys->decSizeAuto = false;
> + p_sys->decFormatAuto = false;
> +
> + p_sys->skipFrames = var_InheritBool(p_dec, "cineform-skip-frames");
> + p_sys->decSize = getDecodingResolutions(p_dec);
> + p_sys->decFlags = getDecodingFlags(p_dec);
> + p_sys->decFormat = getOutputFormats(p_dec);
> +
> + p_sys->stereo3Dtype = getStereoType(p_dec);
> + p_sys->stereoFlags = getStereoFlags(p_dec);
> + p_sys->stereoChannelSelection = getStereoSelect(p_dec);
> +
> +#if ENABLE_STATS == 1
> + p_sys->total_fn = 0;
> + p_sys->total_dec = 0;
> + p_sys->total_pic = 0;
> + p_sys->total_conv = 0;
> +#endif
> +
> + // Init allocator
> + if ((p_sys->allocator.vtable = (struct cfhd_allocator_vtable
> *)malloc(sizeof(struct cfhd_allocator_vtable))) == NULL) + {
> + return VLC_ENOMEM;
Leaks. Consider using vlc_obj_alloc(). Ditto below.
> + }
> + p_sys->allocator.vtable->aligned_malloc = AlignedAlloc;
> + p_sys->allocator.vtable->aligned_free = AlignedFree;
> + p_sys->allocator.vtable->unaligned_malloc = UnalignedAlloc;
> + p_sys->allocator.vtable->unaligned_free = UnalignedFree;
> +
> + // Init CineForm HD decoder
> + CFHD_Error errorCode = CFHD_OpenDecoder(&(p_sys->decoderRef),
> &(p_sys->allocator)); + if (errorCode)
> + {
> + msg_Err(p_dec, "CFHD_OpenDecoder(error %i / %s)\n", errorCode,
> getErrorString(errorCode)); + return VLC_EGENERIC;
> + }
> +
> + // Open an interface to the CineForm HD metadata
> + errorCode = CFHD_OpenMetadata(&(p_sys->metadataRef));
> + if (errorCode)
> + {
> + msg_Err(p_dec, "CFHD_OpenMetadata(error %i / %s)\n", errorCode,
> getErrorString(errorCode)); + return VLC_EGENERIC;
> + }
> +
> + return VLC_SUCCESS;
> +}
> +
> +void CloseDecoder(vlc_object_t *obj)
> +{
> + decoder_t *p_dec = (decoder_t*)obj;
> + decoder_sys_t *p_sys = p_dec->p_sys;
> +
> + msg_Info(p_dec, "CineForm DECODER plugin (CloseDecoder)");
Noise.
> +
> +#if ENABLE_STATS == 1
> + printf("CineForm DECODER plugin (stats: %llu samples / %llu decoded /
> %llu skipped / %llu failed)\n", + p_sys->sampleCount,
> p_sys->sampleDecoded, p_sys->sampleSkipped, p_sys->sampleFailed); +
> + if (p_sys->sampleCount > 0)
> + {
> + printf("- mean function time: %.2f ms\n", (double)(p_sys->total_fn)
> / (double)(p_sys->sampleCount)); + printf("- mean decoding time:
> %.2f ms\n", (double)(p_sys->total_dec) / (double)(p_sys->sampleCount)); +
> printf("- mean pic allo time: %.2f ms\n", (double)(p_sys->total_pic) /
> (double)(p_sys->sampleCount)); + printf("- mean pic conv time: %.2f
> ms\n", (double)(p_sys->total_conv) / (double)(p_sys->sampleCount)); + }
> +#endif
> +
> + // Cleanup
> + if (p_sys)
Tautology.
> + {
> + CFHD_CloseDecoder(p_sys->decoderRef);
> + CFHD_CloseMetadata(p_sys->metadataRef);
> +
> + if (p_sys->internalBuffer)
> + {
> + DeallocateBuffer(p_sys->internalBuffer);
> + p_sys->internalBuffer = NULL;
Pointless.
> + }
> +
> + free(p_sys);
> + p_sys = NULL;
Pointless.
> + }
> +}
> +
> +/**
> + * @brief DecodeVideo
> + * @param p_dec
> + * @param p_block
> + * @return picture_t
> + */
> +int DecodeVideo(decoder_t *p_dec, block_t *p_block)
> +{
> + if (p_block == NULL) /* No Drain */
> + return VLCDEC_SUCCESS;
> +
> + picture_t *p_pic = DecodeBlock(p_dec, &p_block);
> + if (p_pic != NULL)
> + decoder_QueueVideo(p_dec, p_pic);
> +
> + return VLCDEC_SUCCESS;
> +}
> +
> +/**
> + * @brief DecodeBlock
> + * @param p_dec
> + * @param pp_block
> + * @return picture_t
> + */
> +picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
> +{
> +#if ENABLE_STATS == 1
> + clock_t timer_fn_start = clock();
> + clock_t timer_fn_end = 0;
> + clock_t timer_pic_start = 0;
> + clock_t timer_pic_end = 0;
> + clock_t timer_dec_start = 0;
> + clock_t timer_dec_end = 0;
> + clock_t timer_conv_start = 0;
> + clock_t timer_conv_end = 0;
> + int64_t diff_fn = 0;
> + int64_t diff_pic = 0;
> + int64_t diff_dec = 0;
> + int64_t diff_conv = 0;
> +#endif
> +
> + if (!pp_block || !*pp_block)
> + return NULL;
> +
> + CFHD_Error errorCode = CFHD_ERROR_OKAY;
> + decoder_sys_t *p_sys = p_dec->p_sys;
> + block_t *p_block = *pp_block;
> + picture_t *p_pic = NULL;
> +
> + // We have a block
> + p_sys->sampleCount++;
> +
> + // Check block flags
> + if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY |
> BLOCK_FLAG_CORRUPTED)) + {
> + msg_Warn(p_dec, "DecodeBlock error (block corrupted?)");
> + goto error;
> + }
> +
> + // Drop late frames instead of slowing down the video output? Activated
> by default. + if (p_sys->skipFrames == true)
> + {
> + mtime_t i_display_date = 0;
> +
> + if (!(p_block->i_flags & BLOCK_FLAG_PREROLL))
> + i_display_date = decoder_GetDisplayDate(p_dec, p_block->i_dts);
> +
> + if (i_display_date > 0 && i_display_date < mdate())
> + {
> +#if ENABLE_STATS
> + msg_Warn(p_dec, "SKIPPING frame %llu (%lli μs too late)",
> + p_sys->sampleCount, mdate() - i_display_date);
> +#endif
> + goto skip;
> + }
> + }
> +
> + // Packet handling
> + cf_packet_t packet;
> + packet.sampleData = p_block->p_buffer;
> + packet.sampleSize = p_block->i_buffer;
> + packet.samplePTS = p_block->i_dts;
> +
> +
> ///////////////////////////////////////////////////////////////////////////
> / +
> + if (p_sys->sampleDecoded == 0 /*|| video_size_changed*/)
> + {
> + if (p_sys->sampleDecoded == 0)
> + {
> + int SDKversion = 0;
> + errorCode = CFHD_GetSampleInfo(p_sys->decoderRef,
> packet.sampleData, packet.sampleSize, +
> CFHD_SAMPLE_SDK_VERSION, &SDKversion, sizeof(SDKversion)); +
> + if (errorCode != CFHD_ERROR_OKAY)
> + {
> + // not critical...
> + msg_Warn(p_dec, "CFHD_GetSampleInfo(error: '%i' / '%s')",
> errorCode, getErrorString(errorCode)); + }
> + if (SDKversion)
> + {
> + msg_Info(p_dec, "CineForm SDK version used = %d.%d.%d",
> (SDKversion >> 16) & 0xFF, (SDKversion >> 8) & 0xFF, (SDKversion) & 0xFF);
Noisy.
> + p_sys->SDKversion = SDKversion;
> + }
> +
> + int SAMPLEversion = 0;
> + errorCode = CFHD_GetSampleInfo(p_sys->decoderRef,
> packet.sampleData, packet.sampleSize, +
> CFHD_SAMPLE_ENCODE_VERSION, &SAMPLEversion, sizeof(SAMPLEversion)); +
> + if (errorCode != CFHD_ERROR_OKAY)
> + {
> + // not critical...
> + msg_Warn(p_dec, "CFHD_GetSampleInfo(error: '%i' / '%s')",
> errorCode, getErrorString(errorCode)); + }
> + if (SAMPLEversion)
> + {
> + msg_Info(p_dec, "CineForm encoder version used = %d.%d.%d",
> (SAMPLEversion >> 16) & 0xFF, (SAMPLEversion >> 8) & 0xFF, (SAMPLEversion)
> & 0xFF); + p_sys->SAMPLEversion = SAMPLEversion;
> + }
> + }
> +
> + // Get various infos from the current sample, choose buffer
> formats, and then initialize the decoder + errorCode =
> prepareDecoding(p_dec, p_sys, &packet);
> +
> +#if ENABLE_STATS == 1
> + printf("ENCODED VIDEO PARAMETERS\n");
> + printf("- surface: %d x %d\n", p_sys->sourceWidth,
> p_sys->sourceHeight); + printf("- visible: %d x %d\n",
> p_sys->sourceVisibleWidth, p_sys->sourceVisibleHeight); + printf("-
> macropixel size: %d byte(s)\n", p_sys->sourcePixelSize); + printf("-
> %d video channel(s)\n", p_sys->sourceChannels); +
> + if (p_dec->fmt_in.video.i_frame_rate_base != 0)
> + printf("- %.3f fps\n", (float)p_dec->fmt_in.video.i_frame_rate
> / (float)p_dec->fmt_in.video.i_frame_rate_base); +
> + printEncodedFormats(p_sys->sourcePixelFormat);
> + printPreferedOutputFormats(p_sys, &packet);
> +#endif // ENABLE_STATS
> +
> + if (errorCode != CFHD_ERROR_OKAY)
> + {
> + msg_Err(p_dec, "getSampleInfos(error: '%i' / '%s')", errorCode,
> getErrorString(errorCode)); + return NULL;
> + }
> +
> + // Allocate a buffer for the decoded frame, if needed
> + if (p_sys->directMapping == false)
Use !.
And I stopped there; a lot of the same issues afterwards.
--
雷米‧德尼-库尔蒙
https://www.remlab.net/
More information about the vlc-devel
mailing list