RetroArch/cores/libretro-ffmpeg/video_buffer.h

213 lines
5.3 KiB
C
Raw Normal View History

#ifndef __LIBRETRO_SDK_VIDEOBUFFER_H__
#define __LIBRETRO_SDK_VIDEOBUFFER_H__
#include <retro_common_api.h>
#include <boolean.h>
#include <stdint.h>
#ifdef RARCH_INTERNAL
#ifdef HAVE_CONFIG_H
2021-08-18 18:19:48 +00:00
#include "../../config.h"
#endif
#endif
#ifdef HAVE_SSA
#include <ass/ass.h>
#endif
2020-06-30 20:15:49 +00:00
#ifdef __cplusplus
extern "C" {
#endif
#include <libavcodec/version.h>
#include <libavutil/frame.h>
#include <libswscale/swscale.h>
2020-06-30 20:15:49 +00:00
#ifdef __cplusplus
}
#endif
#include <retro_miscellaneous.h>
RETRO_BEGIN_DECLS
/* If libavutil is at least version 55,
* and if libavcodec is at least version 57.80.100,
* enable hardware acceleration */
#define ENABLE_HW_ACCEL ((LIBAVUTIL_VERSION_MAJOR >= 55) && \
(LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 80, 100)))
/**
* video_decoder_context
*
* Context object for the sws worker threads.
*
*/
struct video_decoder_context
{
int64_t pts;
struct SwsContext *sws;
AVFrame *source;
#if ENABLE_HW_ACCEL
AVFrame *hw_source;
#endif
AVFrame *target;
#ifdef HAVE_SSA
ASS_Track *ass_track_active;
#endif
uint8_t *frame_buf;
int index;
};
typedef struct video_decoder_context video_decoder_context_t;
/**
* video_buffer
*
* The video buffer is a ring buffer, that can be used as a
* buffer for many workers while keeping the order.
*
* It is thread safe in a sensem that it is designed to work
* with one work coordinator, that allocates work slots for
* workers threads to work on and later collect the work
* product in the same order, as the slots were allocated.
*
*/
struct video_buffer;
typedef struct video_buffer video_buffer_t;
/**
* video_buffer_create:
* @capacity : Size of the buffer.
* @frame_size : Size of the target frame.
* @width : Width of the target frame.
* @height : Height of the target frame.
*
* Create a video buffer.
*
* Returns: A video buffer.
*/
video_buffer_t *video_buffer_create(size_t capacity, int frame_size, int width, int height);
/**
* video_buffer_destroy:
* @video_buffer : video buffer.
*
* Destroys a video buffer.
*
* Does also free the buffer allocated with video_buffer_create().
* User has to shut down any external worker threads that may have
* a reference to this video buffer.
*
**/
void video_buffer_destroy(video_buffer_t *video_buffer);
/**
* video_buffer_clear:
* @video_buffer : video buffer.
*
* Clears a video buffer.
*
**/
void video_buffer_clear(video_buffer_t *video_buffer);
/**
* video_buffer_get_open_slot:
* @video_buffer : video buffer.
* @context : sws context.
*
* Returns the next open context inside the ring buffer
* and it's index. The status of the slot will be marked as
* 'in progress' until slot is marked as finished with
* video_buffer_finish_slot();
*
**/
void video_buffer_get_open_slot(video_buffer_t *video_buffer, video_decoder_context_t **context);
/**
* video_buffer_return_open_slot:
* @video_buffer : video buffer.
* @context : sws context.
*
* Marks the given sws context that is "in progress" as "open" again.
*
**/
void video_buffer_return_open_slot(video_buffer_t *video_buffer, video_decoder_context_t *context);
/**
* video_buffer_open_slot:
* @video_buffer : video buffer.
* @context : sws context.
*
* Sets the status of the given context from "finished" to "open".
* The slot is then available for producers to claim again with video_buffer_get_open_slot().
**/
void video_buffer_open_slot(video_buffer_t *video_buffer, video_decoder_context_t *context);
/**
* video_buffer_get_finished_slot:
* @video_buffer : video buffer.
* @context : sws context.
*
* Returns a reference for the next context inside
* the ring buffer. User needs to use video_buffer_open_slot()
* to open the slot in the ringbuffer for the next
* work assignment. User is free to re-allocate or
* re-use the context.
*/
void video_buffer_get_finished_slot(video_buffer_t *video_buffer, video_decoder_context_t **context);
/**
* video_buffer_finish_slot:
* @video_buffer : video buffer.
* @context : sws context.
*
* Sets the status of the given context from "in progress" to "finished".
* This is normally done by a producer. User can then retrieve the finished work
* context by calling video_buffer_get_finished_slot().
*/
void video_buffer_finish_slot(video_buffer_t *video_buffer, video_decoder_context_t *context);
/**
* video_buffer_wait_for_open_slot:
* @video_buffer : video buffer.
*
* Blocks until open slot is available.
*
* Returns true if the buffer has a open slot available.
*/
bool video_buffer_wait_for_open_slot(video_buffer_t *video_buffer);
/**
* video_buffer_wait_for_finished_slot:
* @video_buffer : video buffer.
*
* Blocks until finished slot is available.
*
* Returns true if the buffers next slot is finished and a
* context available.
*/
bool video_buffer_wait_for_finished_slot(video_buffer_t *video_buffer);
/**
* bool video_buffer_has_open_slot(video_buffer_t *video_buffer)
:
* @video_buffer : video buffer.
*
* Returns true if the buffer has a open slot available.
*/
bool video_buffer_has_open_slot(video_buffer_t *video_buffer);
/**
* video_buffer_has_finished_slot:
* @video_buffer : video buffer.
*
* Returns true if the buffers next slot is finished and a
* context available.
*/
bool video_buffer_has_finished_slot(video_buffer_t *video_buffer);
RETRO_END_DECLS
#endif