You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

322 lines
9.1 KiB

/*
* H.265 video codec.
* Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
*
* Authors: Dirk Farin <farin@struktur.de>
*
* This file is part of libde265.
*
* libde265 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 3 of
* the License, or (at your option) any later version.
*
* libde265 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 libde265. If not, see <http://www.gnu.org/licenses/>.
*/
#include "libde265/en265.h"
#include "libde265/encoder/encoder-context.h"
LIBDE265_API en265_encoder_context* en265_new_encoder(void)
{
de265_error init_err = de265_init();
if (init_err != DE265_OK) {
return NULL;
}
encoder_context* ectx = new encoder_context();
return (en265_encoder_context*)ectx;
}
LIBDE265_API de265_error en265_free_encoder(en265_encoder_context* e)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
delete ectx;
return de265_free();
}
/*
LIBDE265_API void en265_set_image_release_function(en265_encoder_context* e,
void (*release_func)(en265_encoder_context*,
de265_image*,
void* userdata),
void* alloc_userdata)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
ectx->param_image_allocation_userdata = alloc_userdata;
ectx->release_func = release_func;
}
*/
// ========== encoder parameters ==========
LIBDE265_API de265_error en265_parse_command_line_parameters(en265_encoder_context* e,
int* argc, char** argv)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
//if (!ectx->params_config.parse_command_line_params(argc,argv, &ectx->params, true)) {
int first_idx=1;
if (!ectx->params_config.parse_command_line_params(argc,argv, &first_idx, true)) {
return DE265_ERROR_PARAMETER_PARSING;
}
else {
return DE265_OK;
}
}
LIBDE265_API void en265_show_parameters(en265_encoder_context* e)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
//ectx->params_config.show_params(&ectx->params);
ectx->params_config.print_params();
}
LIBDE265_API const char** en265_list_parameters(en265_encoder_context* e)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
return ectx->params_config.get_parameter_string_table();
}
LIBDE265_API enum en265_parameter_type en265_get_parameter_type(en265_encoder_context* e,
const char* parametername)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
return ectx->params_config.get_parameter_type(parametername);
}
LIBDE265_API de265_error en265_set_parameter_bool(en265_encoder_context* e,
const char* param,int value)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
return ectx->params_config.set_bool(param,value) ? DE265_OK : DE265_ERROR_PARAMETER_PARSING;
}
LIBDE265_API de265_error en265_set_parameter_int(en265_encoder_context* e,
const char* param,int value)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
return ectx->params_config.set_int(param,value) ? DE265_OK : DE265_ERROR_PARAMETER_PARSING;
}
LIBDE265_API de265_error en265_set_parameter_string(en265_encoder_context* e,
const char* param,const char* value)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
return ectx->params_config.set_string(param,value) ? DE265_OK : DE265_ERROR_PARAMETER_PARSING;
}
LIBDE265_API de265_error en265_set_parameter_choice(en265_encoder_context* e,
const char* param,const char* value)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
return ectx->params_config.set_choice(param,value) ? DE265_OK : DE265_ERROR_PARAMETER_PARSING;
}
LIBDE265_API const char** en265_list_parameter_choices(en265_encoder_context* e,
const char* parametername)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
return ectx->params_config.get_parameter_choices_table(parametername);
}
// ========== encoding loop ==========
LIBDE265_API de265_error en265_start_encoder(en265_encoder_context* e, int number_of_threads)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
ectx->start_encoder();
return DE265_OK;
}
LIBDE265_API struct de265_image* en265_allocate_image(en265_encoder_context* e,
int width, int height, de265_chroma chroma,
de265_PTS pts, void* image_userdata)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
de265_image* img = new de265_image;
if (img->alloc_image(width,height,de265_chroma_420, NULL, false,
NULL, /*ectx,*/ pts, image_userdata, true) != DE265_OK) {
delete img;
return NULL;
}
return img;
}
// Request a specification of the image memory layout for an image of the specified dimensions.
LIBDE265_API void en265_get_image_spec(en265_encoder_context* e,
int width, int height, de265_chroma chroma,
struct de265_image_spec* out_spec)
{
out_spec->format = de265_image_format_YUV420P8;
out_spec->width = width;
out_spec->height= height;
out_spec->alignment = 1;
out_spec->crop_left =0;
out_spec->crop_right =0;
out_spec->crop_top =0;
out_spec->crop_bottom=0;
out_spec->visible_width = out_spec->width - out_spec->crop_left - out_spec->crop_right;
out_spec->visible_height = out_spec->height - out_spec->crop_top - out_spec->crop_bottom;
}
// Image memory layout specification for an image returned by en265_allocate_image().
//LIBDE265_API void de265_get_image_spec_from_image(de265_image* img, struct de265_image_spec* spec);
LIBDE265_API de265_error en265_push_image(en265_encoder_context* e,
struct de265_image* img)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
ectx->sop->insert_new_input_image(img);
return DE265_OK;
}
LIBDE265_API de265_error en265_push_eof(en265_encoder_context* e)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
ectx->sop->insert_end_of_stream();
return DE265_OK;
}
LIBDE265_API de265_error en265_block_on_input_queue_length(en265_encoder_context*,
int max_pending_images,
int timeout_ms)
{
// TODO
return DE265_OK;
}
LIBDE265_API de265_error en265_trim_input_queue(en265_encoder_context*, int max_pending_images)
{
// TODO
return DE265_OK;
}
LIBDE265_API int en265_current_input_queue_length(en265_encoder_context*)
{
// TODO
return DE265_OK;
}
LIBDE265_API de265_error en265_encode(en265_encoder_context* e)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
while (ectx->picbuf.have_more_frames_to_encode())
{
de265_error result = ectx->encode_picture_from_input_buffer();
if (result != DE265_OK) return result;
}
return DE265_OK;
}
LIBDE265_API enum en265_encoder_state en265_get_encoder_state(en265_encoder_context* e)
{
// TODO
return EN265_STATE_IDLE;
}
LIBDE265_API struct en265_packet* en265_get_packet(en265_encoder_context* e, int timeout_ms)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
assert(timeout_ms==0); // TODO: blocking not implemented yet
if (ectx->output_packets.size()>0) {
en265_packet* pck = ectx->output_packets.front();
ectx->output_packets.pop_front();
return pck;
}
else {
return NULL;
}
}
LIBDE265_API void en265_free_packet(en265_encoder_context* e, struct en265_packet* pck)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
// Do not delete images here. They are owned by the EncPicBuf.
//delete pck->input_image;
//delete pck->reconstruction;
if (pck->frame_number >= 0) {
ectx->mark_image_is_outputted(pck->frame_number);
ectx->release_input_image(pck->frame_number);
}
delete[] pck->data;
delete pck;
}
LIBDE265_API int en265_number_of_queued_packets(en265_encoder_context* e)
{
assert(e);
encoder_context* ectx = (encoder_context*)e;
return ectx->output_packets.size();
}