diff options
Diffstat (limited to 'gpr/source/lib/vc5_encoder/vc5_encoder.c')
-rwxr-xr-x | gpr/source/lib/vc5_encoder/vc5_encoder.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/gpr/source/lib/vc5_encoder/vc5_encoder.c b/gpr/source/lib/vc5_encoder/vc5_encoder.c new file mode 100755 index 0000000..c28d904 --- /dev/null +++ b/gpr/source/lib/vc5_encoder/vc5_encoder.c @@ -0,0 +1,164 @@ +/*! @file vc5_encoder.c + * + * @brief Implementation of the top level vc5 encoder data structures and functions. + * + * @version 1.0.0 + * + * (C) Copyright 2018 GoPro Inc (http://gopro.com/). + * + * Licensed under either: + * - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0 + * - MIT license, http://opensource.org/licenses/MIT + * at your option. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "headers.h" + +void vc5_encoder_parameters_set_default(vc5_encoder_parameters* encoding_parameters) +{ + encoding_parameters->enabled_parts = VC5_ENABLED_PARTS; + encoding_parameters->input_width = 4000; + encoding_parameters->input_height = 3000; + encoding_parameters->input_pitch = 4000; + + encoding_parameters->pixel_format = VC5_ENCODER_PIXEL_FORMAT_DEFAULT; + encoding_parameters->quality_setting = VC5_ENCODER_QUALITY_SETTING_DEFAULT; + + encoding_parameters->mem_alloc = malloc; + encoding_parameters->mem_free = free; +} + +CODEC_ERROR vc5_encoder_process(const vc5_encoder_parameters* encoding_parameters, /* vc5 encoding parameters */ + const gpr_buffer* raw_buffer, /* raw input buffer. */ + gpr_buffer* vc5_buffer, + gpr_rgb_buffer* rgb_buffer) /* rgb output buffer. */ +{ + CODEC_ERROR error = CODEC_ERROR_OKAY; + IMAGE image; + ENCODER_PARAMETERS parameters; + + STREAM bitstream_file; + + const int max_vc5_buffer_size = 10000000; + + // Initialize the data structure for passing parameters to the encoder + InitEncoderParameters(¶meters); + + { + QUANT quant_table[VC5_ENCODER_QUALITY_SETTING_COUNT][sizeof(parameters.quant_table) / sizeof(parameters.quant_table[0])] = { + {1, 24, 24, 12, 64, 64, 48, 512, 512, 768}, // CineForm Low + {1, 24, 24, 12, 48, 48, 32, 256, 256, 384}, // CineForm Medium + {1, 24, 24, 12, 32, 32, 24, 128, 128, 192}, // CineForm High + {1, 24, 24, 12, 24, 24, 12, 96, 96, 144}, // CineForm Filmscan-1 + {1, 24, 24, 12, 24, 24, 12, 64, 64, 96}, // CineForm Filmscan-X + {1, 24, 24, 12, 24, 24, 12, 32, 32, 48} // CineForm Filmscan-2 + }; + + if( encoding_parameters->quality_setting < VC5_ENCODER_QUALITY_SETTING_COUNT ) + { + memcpy(parameters.quant_table, quant_table[encoding_parameters->quality_setting], sizeof(parameters.quant_table)); + } + } + + parameters.enabled_parts = encoding_parameters->enabled_parts; + parameters.encoded.format = IMAGE_FORMAT_RAW; + +#if VC5_ENABLED_PART(VC5_PART_LAYERS) + // Test interlaced encoding using one layer per field + parameters.layer_count = 2; + parameters.progressive = 0; + parameters.decompositor = DecomposeFields; +#endif + + parameters.allocator.Alloc = encoding_parameters->mem_alloc; + parameters.allocator.Free = encoding_parameters->mem_free; + + // Check that the enabled parts are correct + error = CheckEnabledParts(¶meters.enabled_parts); + if (error != CODEC_ERROR_OKAY) { + return error; + } + + image.buffer = raw_buffer->buffer; + + image.width = encoding_parameters->input_width; + image.height = encoding_parameters->input_height; + image.pitch = encoding_parameters->input_pitch; + image.size = image.width * image.height * 2; + image.offset = 0; + + switch( encoding_parameters->pixel_format ) + { + case VC5_ENCODER_PIXEL_FORMAT_RGGB_12: + image.format = PIXEL_FORMAT_RAW_RGGB_12; + break; + + case VC5_ENCODER_PIXEL_FORMAT_RGGB_12P: + image.format = PIXEL_FORMAT_RAW_RGGB_12P; + break; + + case VC5_ENCODER_PIXEL_FORMAT_RGGB_14: + image.format = PIXEL_FORMAT_RAW_RGGB_14; + break; + + case VC5_ENCODER_PIXEL_FORMAT_GBRG_12: + image.format = PIXEL_FORMAT_RAW_GBRG_12; + break; + + case VC5_ENCODER_PIXEL_FORMAT_GBRG_12P: + image.format = PIXEL_FORMAT_RAW_GBRG_12P; + break; + + default: + assert(0); + } + + // Set the dimensions and pixel format of the packed input image + { + parameters.input.width = image.width; + parameters.input.height = image.height; + parameters.input.format = image.format; + } + +#if VC5_ENABLED_PART(VC5_PART_LAYERS) + // Test interlaced encoding using one layer per field + parameters.layer_count = 2; + parameters.progressive = 0; + parameters.decompositor = DecomposeFields; +#endif + + vc5_buffer->buffer = encoding_parameters->mem_alloc( max_vc5_buffer_size ); + + // Open a stream to the output file + error = CreateStreamBuffer(&bitstream_file, vc5_buffer->buffer, max_vc5_buffer_size ); + if (error != CODEC_ERROR_OKAY) { + return error; + } + + RGB_IMAGE rgb_image; + InitRGBImage(&rgb_image); + + // Encode the image into the byte stream + error = EncodeImage(&image, &bitstream_file, &rgb_image, ¶meters); + if (error != CODEC_ERROR_OKAY) { + return error; + } + + if( rgb_buffer ) + { + rgb_buffer->buffer = rgb_image.buffer; + rgb_buffer->size = rgb_image.size; + rgb_buffer->width = rgb_image.width; + rgb_buffer->height = rgb_image.height; + } + + vc5_buffer->size = bitstream_file.byte_count; + + return CODEC_ERROR_OKAY; +} |