mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 20:10:14 +01:00
st/omx/tizonia: Add H.264 decoder
v2: Refactor out screen functions to st/omx Example Gstreamer pipeline : gst-launch-1.0 filesrc location=movie.mp4 ! qtdemux ! h264parse ! omxh264dec ! videoconvert ! ximagesink Acked-by: Leo Liu <leo.liu@amd.com> Reviewed-by: Julien Isorce <julien.isorce@gmail.com>
This commit is contained in:
parent
430ccdbcb9
commit
83d4a5d5ae
25 changed files with 2795 additions and 1286 deletions
|
|
@ -487,8 +487,10 @@ gallium_omx = _omx
|
||||||
dep_omx = []
|
dep_omx = []
|
||||||
dep_omx_other = []
|
dep_omx_other = []
|
||||||
if gallium_omx == 'bellagio'
|
if gallium_omx == 'bellagio'
|
||||||
|
pre_args += '-DENABLE_ST_OMX_BELLAGIO'
|
||||||
dep_omx = dependency('libomxil-bellagio')
|
dep_omx = dependency('libomxil-bellagio')
|
||||||
elif gallium_omx == 'tizonia'
|
elif gallium_omx == 'tizonia'
|
||||||
|
pre_args += '-DENABLE_ST_OMX_TIZONIA'
|
||||||
dep_omx = dependency('libtizonia', version : '>= 0.10.0')
|
dep_omx = dependency('libtizonia', version : '>= 0.10.0')
|
||||||
dep_omx_other = [
|
dep_omx_other = [
|
||||||
dependency('libtizplatform'),
|
dependency('libtizplatform'),
|
||||||
|
|
|
||||||
|
|
@ -1 +1,7 @@
|
||||||
C_SOURCES :=
|
C_SOURCES := \
|
||||||
|
vid_dec_common.c \
|
||||||
|
vid_dec_common.h \
|
||||||
|
vid_dec_h264_common.c \
|
||||||
|
vid_dec_h264_common.h \
|
||||||
|
vid_omx_common.c \
|
||||||
|
vid_omx_common.h
|
||||||
|
|
|
||||||
|
|
@ -31,33 +31,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#if defined(HAVE_X11_PLATFORM)
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#else
|
|
||||||
#define XOpenDisplay(x) NULL
|
|
||||||
#define XCloseDisplay(x)
|
|
||||||
#define Display void
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "os/os_thread.h"
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "loader/loader.h"
|
|
||||||
|
|
||||||
#include "entrypoint.h"
|
#include "entrypoint.h"
|
||||||
#include "vid_dec.h"
|
#include "vid_dec.h"
|
||||||
#include "vid_enc.h"
|
#include "vid_enc.h"
|
||||||
|
|
||||||
static mtx_t omx_lock = _MTX_INITIALIZER_NP;
|
|
||||||
static Display *omx_display = NULL;
|
|
||||||
static struct vl_screen *omx_screen = NULL;
|
|
||||||
static unsigned omx_usecount = 0;
|
|
||||||
static const char *omx_render_node = NULL;
|
|
||||||
static int drm_fd;
|
|
||||||
|
|
||||||
int omx_component_library_Setup(stLoaderComponentType **stComponents)
|
int omx_component_library_Setup(stLoaderComponentType **stComponents)
|
||||||
{
|
{
|
||||||
OMX_ERRORTYPE r;
|
OMX_ERRORTYPE r;
|
||||||
|
|
@ -78,66 +55,6 @@ int omx_component_library_Setup(stLoaderComponentType **stComponents)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vl_screen *omx_get_screen(void)
|
|
||||||
{
|
|
||||||
static bool first_time = true;
|
|
||||||
mtx_lock(&omx_lock);
|
|
||||||
|
|
||||||
if (!omx_screen) {
|
|
||||||
if (first_time) {
|
|
||||||
omx_render_node = debug_get_option("OMX_RENDER_NODE", NULL);
|
|
||||||
first_time = false;
|
|
||||||
}
|
|
||||||
if (omx_render_node) {
|
|
||||||
drm_fd = loader_open_device(omx_render_node);
|
|
||||||
if (drm_fd < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
omx_screen = vl_drm_screen_create(drm_fd);
|
|
||||||
if (!omx_screen) {
|
|
||||||
close(drm_fd);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
omx_display = XOpenDisplay(NULL);
|
|
||||||
if (!omx_display)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
omx_screen = vl_dri3_screen_create(omx_display, 0);
|
|
||||||
if (!omx_screen)
|
|
||||||
omx_screen = vl_dri2_screen_create(omx_display, 0);
|
|
||||||
if (!omx_screen) {
|
|
||||||
XCloseDisplay(omx_display);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++omx_usecount;
|
|
||||||
|
|
||||||
mtx_unlock(&omx_lock);
|
|
||||||
return omx_screen;
|
|
||||||
|
|
||||||
error:
|
|
||||||
mtx_unlock(&omx_lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void omx_put_screen(void)
|
|
||||||
{
|
|
||||||
mtx_lock(&omx_lock);
|
|
||||||
if ((--omx_usecount) == 0) {
|
|
||||||
omx_screen->destroy(omx_screen);
|
|
||||||
omx_screen = NULL;
|
|
||||||
|
|
||||||
if (omx_render_node)
|
|
||||||
close(drm_fd);
|
|
||||||
else
|
|
||||||
XCloseDisplay(omx_display);
|
|
||||||
}
|
|
||||||
mtx_unlock(&omx_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
OMX_ERRORTYPE omx_workaround_Destructor(OMX_COMPONENTTYPE *comp)
|
OMX_ERRORTYPE omx_workaround_Destructor(OMX_COMPONENTTYPE *comp)
|
||||||
{
|
{
|
||||||
omx_base_component_PrivateType* priv = (omx_base_component_PrivateType*)comp->pComponentPrivate;
|
omx_base_component_PrivateType* priv = (omx_base_component_PrivateType*)comp->pComponentPrivate;
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,6 @@
|
||||||
|
|
||||||
PUBLIC extern int omx_component_library_Setup(stLoaderComponentType **stComponents);
|
PUBLIC extern int omx_component_library_Setup(stLoaderComponentType **stComponents);
|
||||||
|
|
||||||
struct vl_screen *omx_get_screen(void);
|
|
||||||
void omx_put_screen(void);
|
|
||||||
|
|
||||||
OMX_ERRORTYPE omx_workaround_Destructor(OMX_COMPONENTTYPE *comp);
|
OMX_ERRORTYPE omx_workaround_Destructor(OMX_COMPONENTTYPE *comp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,8 @@
|
||||||
|
|
||||||
#include "entrypoint.h"
|
#include "entrypoint.h"
|
||||||
#include "vid_dec.h"
|
#include "vid_dec.h"
|
||||||
|
#include "vid_omx_common.h"
|
||||||
|
#include "vid_dec_h264_common.h"
|
||||||
|
|
||||||
static OMX_ERRORTYPE vid_dec_Constructor(OMX_COMPONENTTYPE *comp, OMX_STRING name);
|
static OMX_ERRORTYPE vid_dec_Constructor(OMX_COMPONENTTYPE *comp, OMX_STRING name);
|
||||||
static OMX_ERRORTYPE vid_dec_Destructor(OMX_COMPONENTTYPE *comp);
|
static OMX_ERRORTYPE vid_dec_Destructor(OMX_COMPONENTTYPE *comp);
|
||||||
|
|
@ -420,50 +422,6 @@ static OMX_ERRORTYPE vid_dec_MessageHandler(OMX_COMPONENTTYPE* comp, internalReq
|
||||||
return omx_base_component_MessageHandler(comp, msg);
|
return omx_base_component_MessageHandler(comp, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vid_dec_NeedTarget(vid_dec_PrivateType *priv)
|
|
||||||
{
|
|
||||||
struct pipe_video_buffer templat = {};
|
|
||||||
struct vl_screen *omx_screen;
|
|
||||||
struct pipe_screen *pscreen;
|
|
||||||
|
|
||||||
omx_screen = priv->screen;
|
|
||||||
assert(omx_screen);
|
|
||||||
|
|
||||||
pscreen = omx_screen->pscreen;
|
|
||||||
assert(pscreen);
|
|
||||||
|
|
||||||
if (!priv->target) {
|
|
||||||
memset(&templat, 0, sizeof(templat));
|
|
||||||
|
|
||||||
templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
|
|
||||||
templat.width = priv->codec->width;
|
|
||||||
templat.height = priv->codec->height;
|
|
||||||
templat.buffer_format = pscreen->get_video_param(
|
|
||||||
pscreen,
|
|
||||||
PIPE_VIDEO_PROFILE_UNKNOWN,
|
|
||||||
PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
|
||||||
PIPE_VIDEO_CAP_PREFERED_FORMAT
|
|
||||||
);
|
|
||||||
templat.interlaced = pscreen->get_video_param(
|
|
||||||
pscreen,
|
|
||||||
PIPE_VIDEO_PROFILE_UNKNOWN,
|
|
||||||
PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
|
||||||
PIPE_VIDEO_CAP_PREFERS_INTERLACED
|
|
||||||
);
|
|
||||||
priv->target = priv->pipe->create_video_buffer(priv->pipe, &templat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vid_dec_FreeInputPortPrivate(OMX_BUFFERHEADERTYPE *buf)
|
|
||||||
{
|
|
||||||
struct pipe_video_buffer *vbuf = buf->pInputPortPrivate;
|
|
||||||
if (!vbuf)
|
|
||||||
return;
|
|
||||||
|
|
||||||
vbuf->destroy(vbuf);
|
|
||||||
buf->pInputPortPrivate = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static OMX_ERRORTYPE vid_dec_DecodeBuffer(omx_base_PortType *port, OMX_BUFFERHEADERTYPE *buf)
|
static OMX_ERRORTYPE vid_dec_DecodeBuffer(omx_base_PortType *port, OMX_BUFFERHEADERTYPE *buf)
|
||||||
{
|
{
|
||||||
OMX_COMPONENTTYPE* comp = port->standCompContainer;
|
OMX_COMPONENTTYPE* comp = port->standCompContainer;
|
||||||
|
|
@ -541,104 +499,10 @@ static OMX_ERRORTYPE vid_dec_FreeDecBuffer(omx_base_PortType *port, OMX_U32 idx,
|
||||||
return base_port_FreeBuffer(port, idx, buf);
|
return base_port_FreeBuffer(port, idx, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vid_dec_FillOutput(vid_dec_PrivateType *priv, struct pipe_video_buffer *buf,
|
|
||||||
OMX_BUFFERHEADERTYPE* output)
|
|
||||||
{
|
|
||||||
omx_base_PortType *port = priv->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
|
|
||||||
OMX_VIDEO_PORTDEFINITIONTYPE *def = &port->sPortParam.format.video;
|
|
||||||
|
|
||||||
struct pipe_sampler_view **views;
|
|
||||||
unsigned i, j;
|
|
||||||
unsigned width, height;
|
|
||||||
|
|
||||||
views = buf->get_sampler_view_planes(buf);
|
|
||||||
|
|
||||||
for (i = 0; i < 2 /* NV12 */; i++) {
|
|
||||||
if (!views[i]) continue;
|
|
||||||
width = def->nFrameWidth;
|
|
||||||
height = def->nFrameHeight;
|
|
||||||
vl_video_buffer_adjust_size(&width, &height, i, buf->chroma_format, buf->interlaced);
|
|
||||||
for (j = 0; j < views[i]->texture->array_size; ++j) {
|
|
||||||
struct pipe_box box = {0, 0, j, width, height, 1};
|
|
||||||
struct pipe_transfer *transfer;
|
|
||||||
uint8_t *map, *dst;
|
|
||||||
map = priv->pipe->transfer_map(priv->pipe, views[i]->texture, 0,
|
|
||||||
PIPE_TRANSFER_READ, &box, &transfer);
|
|
||||||
if (!map)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dst = ((uint8_t*)output->pBuffer + output->nOffset) + j * def->nStride +
|
|
||||||
i * def->nFrameWidth * def->nFrameHeight;
|
|
||||||
util_copy_rect(dst,
|
|
||||||
views[i]->texture->format,
|
|
||||||
def->nStride * views[i]->texture->array_size, 0, 0,
|
|
||||||
box.width, box.height, map, transfer->stride, 0, 0);
|
|
||||||
|
|
||||||
pipe_transfer_unmap(priv->pipe, transfer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vid_dec_FrameDecoded(OMX_COMPONENTTYPE *comp, OMX_BUFFERHEADERTYPE* input,
|
static void vid_dec_FrameDecoded(OMX_COMPONENTTYPE *comp, OMX_BUFFERHEADERTYPE* input,
|
||||||
OMX_BUFFERHEADERTYPE* output)
|
OMX_BUFFERHEADERTYPE* output)
|
||||||
{
|
{
|
||||||
vid_dec_PrivateType *priv = comp->pComponentPrivate;
|
vid_dec_PrivateType *priv = comp->pComponentPrivate;
|
||||||
bool eos = !!(input->nFlags & OMX_BUFFERFLAG_EOS);
|
|
||||||
OMX_TICKS timestamp;
|
|
||||||
|
|
||||||
if (!input->pInputPortPrivate) {
|
vid_dec_FrameDecoded_common(priv, input, output);
|
||||||
input->pInputPortPrivate = priv->Flush(priv, ×tamp);
|
|
||||||
if (timestamp != OMX_VID_DEC_TIMESTAMP_INVALID)
|
|
||||||
input->nTimeStamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input->pInputPortPrivate) {
|
|
||||||
if (output->pInputPortPrivate && !priv->disable_tunnel) {
|
|
||||||
struct pipe_video_buffer *tmp, *vbuf, *new_vbuf;
|
|
||||||
|
|
||||||
tmp = output->pOutputPortPrivate;
|
|
||||||
vbuf = input->pInputPortPrivate;
|
|
||||||
if (vbuf->interlaced) {
|
|
||||||
/* re-allocate the progressive buffer */
|
|
||||||
omx_base_video_PortType *port;
|
|
||||||
struct pipe_video_buffer templat = {};
|
|
||||||
struct u_rect src_rect, dst_rect;
|
|
||||||
|
|
||||||
port = (omx_base_video_PortType *)
|
|
||||||
priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
|
|
||||||
memset(&templat, 0, sizeof(templat));
|
|
||||||
templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
|
|
||||||
templat.width = port->sPortParam.format.video.nFrameWidth;
|
|
||||||
templat.height = port->sPortParam.format.video.nFrameHeight;
|
|
||||||
templat.buffer_format = PIPE_FORMAT_NV12;
|
|
||||||
templat.interlaced = false;
|
|
||||||
new_vbuf = priv->pipe->create_video_buffer(priv->pipe, &templat);
|
|
||||||
|
|
||||||
/* convert the interlaced to the progressive */
|
|
||||||
src_rect.x0 = dst_rect.x0 = 0;
|
|
||||||
src_rect.x1 = dst_rect.x1 = templat.width;
|
|
||||||
src_rect.y0 = dst_rect.y0 = 0;
|
|
||||||
src_rect.y1 = dst_rect.y1 = templat.height;
|
|
||||||
|
|
||||||
vl_compositor_yuv_deint_full(&priv->cstate, &priv->compositor,
|
|
||||||
input->pInputPortPrivate, new_vbuf,
|
|
||||||
&src_rect, &dst_rect, VL_COMPOSITOR_WEAVE);
|
|
||||||
|
|
||||||
/* set the progrssive buffer for next round */
|
|
||||||
vbuf->destroy(vbuf);
|
|
||||||
input->pInputPortPrivate = new_vbuf;
|
|
||||||
}
|
|
||||||
output->pOutputPortPrivate = input->pInputPortPrivate;
|
|
||||||
input->pInputPortPrivate = tmp;
|
|
||||||
} else {
|
|
||||||
vid_dec_FillOutput(priv, input->pInputPortPrivate, output);
|
|
||||||
}
|
|
||||||
output->nFilledLen = output->nAllocLen;
|
|
||||||
output->nTimeStamp = input->nTimeStamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eos && input->pInputPortPrivate)
|
|
||||||
vid_dec_FreeInputPortPrivate(input);
|
|
||||||
else
|
|
||||||
input->nFilledLen = 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,17 +38,10 @@
|
||||||
|
|
||||||
#include <OMX_Types.h>
|
#include <OMX_Types.h>
|
||||||
#include <OMX_Component.h>
|
#include <OMX_Component.h>
|
||||||
#include <OMX_Core.h>
|
|
||||||
|
|
||||||
#include <bellagio/st_static_component_loader.h>
|
|
||||||
#include <bellagio/omx_base_filter.h>
|
|
||||||
#include <bellagio/omx_base_video_port.h>
|
|
||||||
|
|
||||||
#include "pipe/p_video_state.h"
|
|
||||||
#include "os/os_thread.h"
|
#include "os/os_thread.h"
|
||||||
#include "util/list.h"
|
|
||||||
|
|
||||||
#include "vl/vl_compositor.h"
|
#include "vid_dec_common.h"
|
||||||
|
|
||||||
#define OMX_VID_DEC_BASE_NAME "OMX.mesa.video_decoder"
|
#define OMX_VID_DEC_BASE_NAME "OMX.mesa.video_decoder"
|
||||||
|
|
||||||
|
|
@ -63,79 +56,8 @@
|
||||||
|
|
||||||
#define OMX_VID_DEC_TIMESTAMP_INVALID ((OMX_TICKS) -1)
|
#define OMX_VID_DEC_TIMESTAMP_INVALID ((OMX_TICKS) -1)
|
||||||
|
|
||||||
struct vl_vlc;
|
|
||||||
|
|
||||||
DERIVEDCLASS(vid_dec_PrivateType, omx_base_filter_PrivateType)
|
|
||||||
#define vid_dec_PrivateType_FIELDS omx_base_filter_PrivateType_FIELDS \
|
|
||||||
enum pipe_video_profile profile; \
|
|
||||||
struct vl_screen *screen; \
|
|
||||||
struct pipe_context *pipe; \
|
|
||||||
struct pipe_video_codec *codec; \
|
|
||||||
void (*Decode)(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left); \
|
|
||||||
void (*EndFrame)(vid_dec_PrivateType *priv); \
|
|
||||||
struct pipe_video_buffer *(*Flush)(vid_dec_PrivateType *priv, OMX_TICKS *timestamp); \
|
|
||||||
struct pipe_video_buffer *target, *shadow; \
|
|
||||||
union { \
|
|
||||||
struct { \
|
|
||||||
uint8_t intra_matrix[64]; \
|
|
||||||
uint8_t non_intra_matrix[64]; \
|
|
||||||
} mpeg12; \
|
|
||||||
struct { \
|
|
||||||
unsigned nal_ref_idc; \
|
|
||||||
bool IdrPicFlag; \
|
|
||||||
unsigned idr_pic_id; \
|
|
||||||
unsigned pic_order_cnt_lsb; \
|
|
||||||
unsigned pic_order_cnt_msb; \
|
|
||||||
unsigned delta_pic_order_cnt_bottom; \
|
|
||||||
unsigned delta_pic_order_cnt[2]; \
|
|
||||||
unsigned prevFrameNumOffset; \
|
|
||||||
struct pipe_h264_sps sps[32]; \
|
|
||||||
struct pipe_h264_pps pps[256]; \
|
|
||||||
struct list_head dpb_list; \
|
|
||||||
unsigned dpb_num; \
|
|
||||||
} h264; \
|
|
||||||
struct { \
|
|
||||||
unsigned temporal_id; \
|
|
||||||
unsigned level_idc; \
|
|
||||||
unsigned pic_width_in_luma_samples; \
|
|
||||||
unsigned pic_height_in_luma_samples; \
|
|
||||||
bool IdrPicFlag; \
|
|
||||||
int slice_prev_poc; \
|
|
||||||
void *ref_pic_set_list; \
|
|
||||||
void *rps; \
|
|
||||||
struct pipe_h265_sps sps[16]; \
|
|
||||||
struct pipe_h265_pps pps[64]; \
|
|
||||||
struct list_head dpb_list; \
|
|
||||||
unsigned dpb_num; \
|
|
||||||
} h265; \
|
|
||||||
} codec_data; \
|
|
||||||
union { \
|
|
||||||
struct pipe_picture_desc base; \
|
|
||||||
struct pipe_mpeg12_picture_desc mpeg12; \
|
|
||||||
struct pipe_h264_picture_desc h264; \
|
|
||||||
struct pipe_h265_picture_desc h265; \
|
|
||||||
} picture; \
|
|
||||||
unsigned num_in_buffers; \
|
|
||||||
OMX_BUFFERHEADERTYPE *in_buffers[2]; \
|
|
||||||
const void *inputs[2]; \
|
|
||||||
unsigned sizes[2]; \
|
|
||||||
OMX_TICKS timestamps[2]; \
|
|
||||||
OMX_TICKS timestamp; \
|
|
||||||
bool first_buf_in_frame; \
|
|
||||||
bool frame_finished; \
|
|
||||||
bool frame_started; \
|
|
||||||
unsigned bytes_left; \
|
|
||||||
const void *slice; \
|
|
||||||
bool disable_tunnel; \
|
|
||||||
struct vl_compositor compositor; \
|
|
||||||
struct vl_compositor_state cstate;
|
|
||||||
ENDCLASS(vid_dec_PrivateType)
|
|
||||||
|
|
||||||
OMX_ERRORTYPE vid_dec_LoaderComponent(stLoaderComponentType *comp);
|
OMX_ERRORTYPE vid_dec_LoaderComponent(stLoaderComponentType *comp);
|
||||||
|
|
||||||
/* used by MPEG12 and H264 implementation */
|
|
||||||
void vid_dec_NeedTarget(vid_dec_PrivateType *priv);
|
|
||||||
|
|
||||||
/* vid_dec_mpeg12.c */
|
/* vid_dec_mpeg12.c */
|
||||||
void vid_dec_mpeg12_Init(vid_dec_PrivateType *priv);
|
void vid_dec_mpeg12_Init(vid_dec_PrivateType *priv);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,51 +39,7 @@
|
||||||
|
|
||||||
#include "entrypoint.h"
|
#include "entrypoint.h"
|
||||||
#include "vid_dec.h"
|
#include "vid_dec.h"
|
||||||
|
#include "vid_dec_h264_common.h"
|
||||||
#define DPB_MAX_SIZE 5
|
|
||||||
|
|
||||||
struct dpb_list {
|
|
||||||
struct list_head list;
|
|
||||||
struct pipe_video_buffer *buffer;
|
|
||||||
OMX_TICKS timestamp;
|
|
||||||
int poc;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t Default_4x4_Intra[16] = {
|
|
||||||
6, 13, 20, 28, 13, 20, 28, 32,
|
|
||||||
20, 28, 32, 37, 28, 32, 37, 42
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t Default_4x4_Inter[16] = {
|
|
||||||
10, 14, 20, 24, 14, 20, 24, 27,
|
|
||||||
20, 24, 27, 30, 24, 27, 30, 34
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t Default_8x8_Intra[64] = {
|
|
||||||
6, 10, 13, 16, 18, 23, 25, 27,
|
|
||||||
10, 11, 16, 18, 23, 25, 27, 29,
|
|
||||||
13, 16, 18, 23, 25, 27, 29, 31,
|
|
||||||
16, 18, 23, 25, 27, 29, 31, 33,
|
|
||||||
18, 23, 25, 27, 29, 31, 33, 36,
|
|
||||||
23, 25, 27, 29, 31, 33, 36, 38,
|
|
||||||
25, 27, 29, 31, 33, 36, 38, 40,
|
|
||||||
27, 29, 31, 33, 36, 38, 40, 42
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t Default_8x8_Inter[64] = {
|
|
||||||
9, 13, 15, 17, 19, 21, 22, 24,
|
|
||||||
13, 13, 17, 19, 21, 22, 24, 25,
|
|
||||||
15, 17, 19, 21, 22, 24, 25, 27,
|
|
||||||
17, 19, 21, 22, 24, 25, 27, 28,
|
|
||||||
19, 21, 22, 24, 25, 27, 28, 30,
|
|
||||||
21, 22, 24, 25, 27, 28, 30, 32,
|
|
||||||
22, 24, 25, 27, 28, 30, 32, 33,
|
|
||||||
24, 25, 27, 28, 30, 32, 33, 35
|
|
||||||
};
|
|
||||||
|
|
||||||
static void vid_dec_h264_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left);
|
|
||||||
static void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv);
|
|
||||||
static struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv, OMX_TICKS *timestamp);
|
|
||||||
|
|
||||||
void vid_dec_h264_Init(vid_dec_PrivateType *priv)
|
void vid_dec_h264_Init(vid_dec_PrivateType *priv)
|
||||||
{
|
{
|
||||||
|
|
@ -97,936 +53,3 @@ void vid_dec_h264_Init(vid_dec_PrivateType *priv)
|
||||||
priv->picture.h264.field_order_cnt[0] = priv->picture.h264.field_order_cnt[1] = INT_MAX;
|
priv->picture.h264.field_order_cnt[0] = priv->picture.h264.field_order_cnt[1] = INT_MAX;
|
||||||
priv->first_buf_in_frame = true;
|
priv->first_buf_in_frame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vid_dec_h264_BeginFrame(vid_dec_PrivateType *priv)
|
|
||||||
{
|
|
||||||
//TODO: sane buffer handling
|
|
||||||
|
|
||||||
if (priv->frame_started)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!priv->codec) {
|
|
||||||
struct pipe_video_codec templat = {};
|
|
||||||
omx_base_video_PortType *port;
|
|
||||||
|
|
||||||
port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
|
|
||||||
templat.profile = priv->profile;
|
|
||||||
templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
|
|
||||||
templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
|
|
||||||
templat.max_references = priv->picture.h264.num_ref_frames;
|
|
||||||
templat.expect_chunked_decode = true;
|
|
||||||
templat.width = port->sPortParam.format.video.nFrameWidth;
|
|
||||||
templat.height = port->sPortParam.format.video.nFrameHeight;
|
|
||||||
templat.level = priv->picture.h264.pps->sps->level_idc;
|
|
||||||
|
|
||||||
priv->codec = priv->pipe->create_video_codec(priv->pipe, &templat);
|
|
||||||
}
|
|
||||||
|
|
||||||
vid_dec_NeedTarget(priv);
|
|
||||||
|
|
||||||
if (priv->first_buf_in_frame)
|
|
||||||
priv->timestamp = priv->timestamps[0];
|
|
||||||
priv->first_buf_in_frame = false;
|
|
||||||
|
|
||||||
priv->picture.h264.num_ref_frames = priv->picture.h264.pps->sps->max_num_ref_frames;
|
|
||||||
|
|
||||||
priv->picture.h264.slice_count = 0;
|
|
||||||
priv->codec->begin_frame(priv->codec, priv->target, &priv->picture.base);
|
|
||||||
priv->frame_started = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv,
|
|
||||||
OMX_TICKS *timestamp)
|
|
||||||
{
|
|
||||||
struct dpb_list *entry, *result = NULL;
|
|
||||||
struct pipe_video_buffer *buf;
|
|
||||||
|
|
||||||
/* search for the lowest poc and break on zeros */
|
|
||||||
LIST_FOR_EACH_ENTRY(entry, &priv->codec_data.h264.dpb_list, list) {
|
|
||||||
|
|
||||||
if (result && entry->poc == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!result || entry->poc < result->poc)
|
|
||||||
result = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
buf = result->buffer;
|
|
||||||
if (timestamp)
|
|
||||||
*timestamp = result->timestamp;
|
|
||||||
|
|
||||||
--priv->codec_data.h264.dpb_num;
|
|
||||||
LIST_DEL(&result->list);
|
|
||||||
FREE(result);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv)
|
|
||||||
{
|
|
||||||
struct dpb_list *entry;
|
|
||||||
struct pipe_video_buffer *tmp;
|
|
||||||
bool top_field_first;
|
|
||||||
OMX_TICKS timestamp;
|
|
||||||
|
|
||||||
if (!priv->frame_started)
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv->codec->end_frame(priv->codec, priv->target, &priv->picture.base);
|
|
||||||
priv->frame_started = false;
|
|
||||||
|
|
||||||
// TODO: implement frame number handling
|
|
||||||
priv->picture.h264.frame_num_list[0] = priv->picture.h264.frame_num;
|
|
||||||
priv->picture.h264.field_order_cnt_list[0][0] = priv->picture.h264.frame_num;
|
|
||||||
priv->picture.h264.field_order_cnt_list[0][1] = priv->picture.h264.frame_num;
|
|
||||||
|
|
||||||
top_field_first = priv->picture.h264.field_order_cnt[0] < priv->picture.h264.field_order_cnt[1];
|
|
||||||
|
|
||||||
if (priv->picture.h264.field_pic_flag && priv->picture.h264.bottom_field_flag != top_field_first)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* add the decoded picture to the dpb list */
|
|
||||||
entry = CALLOC_STRUCT(dpb_list);
|
|
||||||
if (!entry)
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv->first_buf_in_frame = true;
|
|
||||||
entry->buffer = priv->target;
|
|
||||||
entry->timestamp = priv->timestamp;
|
|
||||||
entry->poc = MIN2(priv->picture.h264.field_order_cnt[0], priv->picture.h264.field_order_cnt[1]);
|
|
||||||
LIST_ADDTAIL(&entry->list, &priv->codec_data.h264.dpb_list);
|
|
||||||
++priv->codec_data.h264.dpb_num;
|
|
||||||
priv->target = NULL;
|
|
||||||
priv->picture.h264.field_order_cnt[0] = priv->picture.h264.field_order_cnt[1] = INT_MAX;
|
|
||||||
|
|
||||||
if (priv->codec_data.h264.dpb_num <= DPB_MAX_SIZE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
tmp = priv->in_buffers[0]->pInputPortPrivate;
|
|
||||||
priv->in_buffers[0]->pInputPortPrivate = vid_dec_h264_Flush(priv, ×tamp);
|
|
||||||
priv->in_buffers[0]->nTimeStamp = timestamp;
|
|
||||||
priv->target = tmp;
|
|
||||||
priv->frame_finished = priv->in_buffers[0]->pInputPortPrivate != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vui_parameters(struct vl_rbsp *rbsp)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scaling_list(struct vl_rbsp *rbsp, uint8_t *scalingList, unsigned sizeOfScalingList,
|
|
||||||
const uint8_t *defaultList, const uint8_t *fallbackList)
|
|
||||||
{
|
|
||||||
unsigned lastScale = 8, nextScale = 8;
|
|
||||||
const int *list;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
/* (pic|seq)_scaling_list_present_flag[i] */
|
|
||||||
if (!vl_rbsp_u(rbsp, 1)) {
|
|
||||||
if (fallbackList)
|
|
||||||
memcpy(scalingList, fallbackList, sizeOfScalingList);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
list = (sizeOfScalingList == 16) ? vl_zscan_normal_16 : vl_zscan_normal;
|
|
||||||
for (i = 0; i < sizeOfScalingList; ++i ) {
|
|
||||||
|
|
||||||
if (nextScale != 0) {
|
|
||||||
signed delta_scale = vl_rbsp_se(rbsp);
|
|
||||||
nextScale = (lastScale + delta_scale + 256) % 256;
|
|
||||||
if (i == 0 && nextScale == 0) {
|
|
||||||
memcpy(scalingList, defaultList, sizeOfScalingList);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scalingList[list[i]] = nextScale == 0 ? lastScale : nextScale;
|
|
||||||
lastScale = scalingList[list[i]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_h264_sps *seq_parameter_set_id(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
|
|
||||||
{
|
|
||||||
unsigned id = vl_rbsp_ue(rbsp);
|
|
||||||
if (id >= ARRAY_SIZE(priv->codec_data.h264.sps))
|
|
||||||
return NULL; /* invalid seq_parameter_set_id */
|
|
||||||
|
|
||||||
return &priv->codec_data.h264.sps[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void seq_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
|
|
||||||
{
|
|
||||||
struct pipe_h264_sps *sps;
|
|
||||||
unsigned profile_idc, level_idc;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
/* Sequence parameter set */
|
|
||||||
profile_idc = vl_rbsp_u(rbsp, 8);
|
|
||||||
|
|
||||||
/* constraint_set0_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
/* constraint_set1_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
/* constraint_set2_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
/* constraint_set3_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
/* constraint_set4_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
/* constraint_set5_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
/* reserved_zero_2bits */
|
|
||||||
vl_rbsp_u(rbsp, 2);
|
|
||||||
|
|
||||||
/* level_idc */
|
|
||||||
level_idc = vl_rbsp_u(rbsp, 8);
|
|
||||||
|
|
||||||
sps = seq_parameter_set_id(priv, rbsp);
|
|
||||||
if (!sps)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memset(sps, 0, sizeof(*sps));
|
|
||||||
memset(sps->ScalingList4x4, 16, sizeof(sps->ScalingList4x4));
|
|
||||||
memset(sps->ScalingList8x8, 16, sizeof(sps->ScalingList8x8));
|
|
||||||
|
|
||||||
sps->level_idc = level_idc;
|
|
||||||
|
|
||||||
if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 ||
|
|
||||||
profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118 ||
|
|
||||||
profile_idc == 128 || profile_idc == 138) {
|
|
||||||
|
|
||||||
sps->chroma_format_idc = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (sps->chroma_format_idc == 3)
|
|
||||||
sps->separate_colour_plane_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
sps->bit_depth_luma_minus8 = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
sps->bit_depth_chroma_minus8 = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
/* qpprime_y_zero_transform_bypass_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
sps->seq_scaling_matrix_present_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
if (sps->seq_scaling_matrix_present_flag) {
|
|
||||||
|
|
||||||
scaling_list(rbsp, sps->ScalingList4x4[0], 16, Default_4x4_Intra, Default_4x4_Intra);
|
|
||||||
scaling_list(rbsp, sps->ScalingList4x4[1], 16, Default_4x4_Intra, sps->ScalingList4x4[0]);
|
|
||||||
scaling_list(rbsp, sps->ScalingList4x4[2], 16, Default_4x4_Intra, sps->ScalingList4x4[1]);
|
|
||||||
scaling_list(rbsp, sps->ScalingList4x4[3], 16, Default_4x4_Inter, Default_4x4_Inter);
|
|
||||||
scaling_list(rbsp, sps->ScalingList4x4[4], 16, Default_4x4_Inter, sps->ScalingList4x4[3]);
|
|
||||||
scaling_list(rbsp, sps->ScalingList4x4[5], 16, Default_4x4_Inter, sps->ScalingList4x4[4]);
|
|
||||||
|
|
||||||
scaling_list(rbsp, sps->ScalingList8x8[0], 64, Default_8x8_Intra, Default_8x8_Intra);
|
|
||||||
scaling_list(rbsp, sps->ScalingList8x8[1], 64, Default_8x8_Inter, Default_8x8_Inter);
|
|
||||||
if (sps->chroma_format_idc == 3) {
|
|
||||||
scaling_list(rbsp, sps->ScalingList8x8[2], 64, Default_8x8_Intra, sps->ScalingList8x8[0]);
|
|
||||||
scaling_list(rbsp, sps->ScalingList8x8[3], 64, Default_8x8_Inter, sps->ScalingList8x8[1]);
|
|
||||||
scaling_list(rbsp, sps->ScalingList8x8[4], 64, Default_8x8_Intra, sps->ScalingList8x8[2]);
|
|
||||||
scaling_list(rbsp, sps->ScalingList8x8[5], 64, Default_8x8_Inter, sps->ScalingList8x8[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (profile_idc == 183)
|
|
||||||
sps->chroma_format_idc = 0;
|
|
||||||
else
|
|
||||||
sps->chroma_format_idc = 1;
|
|
||||||
|
|
||||||
sps->log2_max_frame_num_minus4 = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
sps->pic_order_cnt_type = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (sps->pic_order_cnt_type == 0)
|
|
||||||
sps->log2_max_pic_order_cnt_lsb_minus4 = vl_rbsp_ue(rbsp);
|
|
||||||
else if (sps->pic_order_cnt_type == 1) {
|
|
||||||
sps->delta_pic_order_always_zero_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
sps->offset_for_non_ref_pic = vl_rbsp_se(rbsp);
|
|
||||||
|
|
||||||
sps->offset_for_top_to_bottom_field = vl_rbsp_se(rbsp);
|
|
||||||
|
|
||||||
sps->num_ref_frames_in_pic_order_cnt_cycle = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i)
|
|
||||||
sps->offset_for_ref_frame[i] = vl_rbsp_se(rbsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
sps->max_num_ref_frames = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
/* gaps_in_frame_num_value_allowed_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
/* pic_width_in_mbs_minus1 */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
/* pic_height_in_map_units_minus1 */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
sps->frame_mbs_only_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
if (!sps->frame_mbs_only_flag)
|
|
||||||
sps->mb_adaptive_frame_field_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
sps->direct_8x8_inference_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
/* frame_cropping_flag */
|
|
||||||
if (vl_rbsp_u(rbsp, 1)) {
|
|
||||||
/* frame_crop_left_offset */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
/* frame_crop_right_offset */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
/* frame_crop_top_offset */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
/* frame_crop_bottom_offset */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vui_parameters_present_flag */
|
|
||||||
if (vl_rbsp_u(rbsp, 1))
|
|
||||||
vui_parameters(rbsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_h264_pps *pic_parameter_set_id(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
|
|
||||||
{
|
|
||||||
unsigned id = vl_rbsp_ue(rbsp);
|
|
||||||
if (id >= ARRAY_SIZE(priv->codec_data.h264.pps))
|
|
||||||
return NULL; /* invalid pic_parameter_set_id */
|
|
||||||
|
|
||||||
return &priv->codec_data.h264.pps[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void picture_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
|
|
||||||
{
|
|
||||||
struct pipe_h264_sps *sps;
|
|
||||||
struct pipe_h264_pps *pps;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
pps = pic_parameter_set_id(priv, rbsp);
|
|
||||||
if (!pps)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memset(pps, 0, sizeof(*pps));
|
|
||||||
|
|
||||||
sps = pps->sps = seq_parameter_set_id(priv, rbsp);
|
|
||||||
if (!sps)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memcpy(pps->ScalingList4x4, sps->ScalingList4x4, sizeof(pps->ScalingList4x4));
|
|
||||||
memcpy(pps->ScalingList8x8, sps->ScalingList8x8, sizeof(pps->ScalingList8x8));
|
|
||||||
|
|
||||||
pps->entropy_coding_mode_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
pps->bottom_field_pic_order_in_frame_present_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
pps->num_slice_groups_minus1 = vl_rbsp_ue(rbsp);
|
|
||||||
if (pps->num_slice_groups_minus1 > 0) {
|
|
||||||
pps->slice_group_map_type = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (pps->slice_group_map_type == 0) {
|
|
||||||
|
|
||||||
for (i = 0; i <= pps->num_slice_groups_minus1; ++i)
|
|
||||||
/* run_length_minus1[i] */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
} else if (pps->slice_group_map_type == 2) {
|
|
||||||
|
|
||||||
for (i = 0; i <= pps->num_slice_groups_minus1; ++i) {
|
|
||||||
/* top_left[i] */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
/* bottom_right[i] */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5) {
|
|
||||||
|
|
||||||
/* slice_group_change_direction_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
pps->slice_group_change_rate_minus1 = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
} else if (pps->slice_group_map_type == 6) {
|
|
||||||
|
|
||||||
unsigned pic_size_in_map_units_minus1;
|
|
||||||
|
|
||||||
pic_size_in_map_units_minus1 = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
for (i = 0; i <= pic_size_in_map_units_minus1; ++i)
|
|
||||||
/* slice_group_id[i] */
|
|
||||||
vl_rbsp_u(rbsp, log2(pps->num_slice_groups_minus1 + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pps->num_ref_idx_l0_default_active_minus1 = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
pps->num_ref_idx_l1_default_active_minus1 = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
pps->weighted_pred_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
pps->weighted_bipred_idc = vl_rbsp_u(rbsp, 2);
|
|
||||||
|
|
||||||
pps->pic_init_qp_minus26 = vl_rbsp_se(rbsp);
|
|
||||||
|
|
||||||
/* pic_init_qs_minus26 */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
|
|
||||||
pps->chroma_qp_index_offset = vl_rbsp_se(rbsp);
|
|
||||||
|
|
||||||
pps->deblocking_filter_control_present_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
pps->constrained_intra_pred_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
pps->redundant_pic_cnt_present_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
if (vl_rbsp_more_data(rbsp)) {
|
|
||||||
pps->transform_8x8_mode_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
/* pic_scaling_matrix_present_flag */
|
|
||||||
if (vl_rbsp_u(rbsp, 1)) {
|
|
||||||
|
|
||||||
scaling_list(rbsp, pps->ScalingList4x4[0], 16, Default_4x4_Intra,
|
|
||||||
sps->seq_scaling_matrix_present_flag ? NULL : Default_4x4_Intra);
|
|
||||||
scaling_list(rbsp, pps->ScalingList4x4[1], 16, Default_4x4_Intra, pps->ScalingList4x4[0]);
|
|
||||||
scaling_list(rbsp, pps->ScalingList4x4[2], 16, Default_4x4_Intra, pps->ScalingList4x4[1]);
|
|
||||||
scaling_list(rbsp, pps->ScalingList4x4[3], 16, Default_4x4_Inter,
|
|
||||||
sps->seq_scaling_matrix_present_flag ? NULL : Default_4x4_Inter);
|
|
||||||
scaling_list(rbsp, pps->ScalingList4x4[4], 16, Default_4x4_Inter, pps->ScalingList4x4[3]);
|
|
||||||
scaling_list(rbsp, pps->ScalingList4x4[5], 16, Default_4x4_Inter, pps->ScalingList4x4[4]);
|
|
||||||
|
|
||||||
if (pps->transform_8x8_mode_flag) {
|
|
||||||
scaling_list(rbsp, pps->ScalingList8x8[0], 64, Default_8x8_Intra,
|
|
||||||
sps->seq_scaling_matrix_present_flag ? NULL : Default_8x8_Intra);
|
|
||||||
scaling_list(rbsp, pps->ScalingList8x8[1], 64, Default_8x8_Inter,
|
|
||||||
sps->seq_scaling_matrix_present_flag ? NULL : Default_8x8_Inter);
|
|
||||||
if (sps->chroma_format_idc == 3) {
|
|
||||||
scaling_list(rbsp, pps->ScalingList8x8[2], 64, Default_8x8_Intra, pps->ScalingList8x8[0]);
|
|
||||||
scaling_list(rbsp, pps->ScalingList8x8[3], 64, Default_8x8_Inter, pps->ScalingList8x8[1]);
|
|
||||||
scaling_list(rbsp, pps->ScalingList8x8[4], 64, Default_8x8_Intra, pps->ScalingList8x8[2]);
|
|
||||||
scaling_list(rbsp, pps->ScalingList8x8[5], 64, Default_8x8_Inter, pps->ScalingList8x8[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pps->second_chroma_qp_index_offset = vl_rbsp_se(rbsp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ref_pic_list_mvc_modification(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ref_pic_list_modification(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
|
|
||||||
enum pipe_h264_slice_type slice_type)
|
|
||||||
{
|
|
||||||
unsigned modification_of_pic_nums_idc;
|
|
||||||
|
|
||||||
if (slice_type != 2 && slice_type != 4) {
|
|
||||||
/* ref_pic_list_modification_flag_l0 */
|
|
||||||
if (vl_rbsp_u(rbsp, 1)) {
|
|
||||||
do {
|
|
||||||
modification_of_pic_nums_idc = vl_rbsp_ue(rbsp);
|
|
||||||
if (modification_of_pic_nums_idc == 0 ||
|
|
||||||
modification_of_pic_nums_idc == 1)
|
|
||||||
/* abs_diff_pic_num_minus1 */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
else if (modification_of_pic_nums_idc == 2)
|
|
||||||
/* long_term_pic_num */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
} while (modification_of_pic_nums_idc != 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slice_type == 1) {
|
|
||||||
/* ref_pic_list_modification_flag_l1 */
|
|
||||||
if (vl_rbsp_u(rbsp, 1)) {
|
|
||||||
do {
|
|
||||||
modification_of_pic_nums_idc = vl_rbsp_ue(rbsp);
|
|
||||||
if (modification_of_pic_nums_idc == 0 ||
|
|
||||||
modification_of_pic_nums_idc == 1)
|
|
||||||
/* abs_diff_pic_num_minus1 */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
else if (modification_of_pic_nums_idc == 2)
|
|
||||||
/* long_term_pic_num */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
} while (modification_of_pic_nums_idc != 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pred_weight_table(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
|
|
||||||
struct pipe_h264_sps *sps, enum pipe_h264_slice_type slice_type)
|
|
||||||
{
|
|
||||||
unsigned ChromaArrayType = sps->separate_colour_plane_flag ? 0 : sps->chroma_format_idc;
|
|
||||||
unsigned i, j;
|
|
||||||
|
|
||||||
/* luma_log2_weight_denom */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (ChromaArrayType != 0)
|
|
||||||
/* chroma_log2_weight_denom */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
for (i = 0; i <= priv->picture.h264.num_ref_idx_l0_active_minus1; ++i) {
|
|
||||||
/* luma_weight_l0_flag */
|
|
||||||
if (vl_rbsp_u(rbsp, 1)) {
|
|
||||||
/* luma_weight_l0[i] */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
/* luma_offset_l0[i] */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
}
|
|
||||||
if (ChromaArrayType != 0) {
|
|
||||||
/* chroma_weight_l0_flag */
|
|
||||||
if (vl_rbsp_u(rbsp, 1)) {
|
|
||||||
for (j = 0; j < 2; ++j) {
|
|
||||||
/* chroma_weight_l0[i][j] */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
/* chroma_offset_l0[i][j] */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slice_type == 1) {
|
|
||||||
for (i = 0; i <= priv->picture.h264.num_ref_idx_l1_active_minus1; ++i) {
|
|
||||||
/* luma_weight_l1_flag */
|
|
||||||
if (vl_rbsp_u(rbsp, 1)) {
|
|
||||||
/* luma_weight_l1[i] */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
/* luma_offset_l1[i] */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
}
|
|
||||||
if (ChromaArrayType != 0) {
|
|
||||||
/* chroma_weight_l1_flag */
|
|
||||||
if (vl_rbsp_u(rbsp, 1)) {
|
|
||||||
for (j = 0; j < 2; ++j) {
|
|
||||||
/* chroma_weight_l1[i][j] */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
/* chroma_offset_l1[i][j] */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dec_ref_pic_marking(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
|
|
||||||
bool IdrPicFlag)
|
|
||||||
{
|
|
||||||
unsigned memory_management_control_operation;
|
|
||||||
|
|
||||||
if (IdrPicFlag) {
|
|
||||||
/* no_output_of_prior_pics_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
/* long_term_reference_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
} else {
|
|
||||||
/* adaptive_ref_pic_marking_mode_flag */
|
|
||||||
if (vl_rbsp_u(rbsp, 1)) {
|
|
||||||
do {
|
|
||||||
memory_management_control_operation = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (memory_management_control_operation == 1 ||
|
|
||||||
memory_management_control_operation == 3)
|
|
||||||
/* difference_of_pic_nums_minus1 */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (memory_management_control_operation == 2)
|
|
||||||
/* long_term_pic_num */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (memory_management_control_operation == 3 ||
|
|
||||||
memory_management_control_operation == 6)
|
|
||||||
/* long_term_frame_idx */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (memory_management_control_operation == 4)
|
|
||||||
/* max_long_term_frame_idx_plus1 */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
} while (memory_management_control_operation != 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void slice_header(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
|
|
||||||
unsigned nal_ref_idc, unsigned nal_unit_type)
|
|
||||||
{
|
|
||||||
enum pipe_h264_slice_type slice_type;
|
|
||||||
struct pipe_h264_pps *pps;
|
|
||||||
struct pipe_h264_sps *sps;
|
|
||||||
unsigned frame_num, prevFrameNum;
|
|
||||||
bool IdrPicFlag = nal_unit_type == 5;
|
|
||||||
|
|
||||||
if (IdrPicFlag != priv->codec_data.h264.IdrPicFlag)
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
priv->codec_data.h264.IdrPicFlag = IdrPicFlag;
|
|
||||||
|
|
||||||
/* first_mb_in_slice */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
slice_type = vl_rbsp_ue(rbsp) % 5;
|
|
||||||
|
|
||||||
pps = pic_parameter_set_id(priv, rbsp);
|
|
||||||
if (!pps)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sps = pps->sps;
|
|
||||||
if (!sps)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pps != priv->picture.h264.pps)
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
priv->picture.h264.pps = pps;
|
|
||||||
|
|
||||||
if (sps->separate_colour_plane_flag == 1 )
|
|
||||||
/* colour_plane_id */
|
|
||||||
vl_rbsp_u(rbsp, 2);
|
|
||||||
|
|
||||||
frame_num = vl_rbsp_u(rbsp, sps->log2_max_frame_num_minus4 + 4);
|
|
||||||
|
|
||||||
if (frame_num != priv->picture.h264.frame_num)
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
prevFrameNum = priv->picture.h264.frame_num;
|
|
||||||
priv->picture.h264.frame_num = frame_num;
|
|
||||||
|
|
||||||
priv->picture.h264.field_pic_flag = 0;
|
|
||||||
priv->picture.h264.bottom_field_flag = 0;
|
|
||||||
|
|
||||||
if (!sps->frame_mbs_only_flag) {
|
|
||||||
unsigned field_pic_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
if (!field_pic_flag && field_pic_flag != priv->picture.h264.field_pic_flag)
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
priv->picture.h264.field_pic_flag = field_pic_flag;
|
|
||||||
|
|
||||||
if (priv->picture.h264.field_pic_flag) {
|
|
||||||
unsigned bottom_field_flag = vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
if (bottom_field_flag != priv->picture.h264.bottom_field_flag)
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
priv->picture.h264.bottom_field_flag = bottom_field_flag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IdrPicFlag) {
|
|
||||||
unsigned idr_pic_id = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (idr_pic_id != priv->codec_data.h264.idr_pic_id)
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
priv->codec_data.h264.idr_pic_id = idr_pic_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sps->pic_order_cnt_type == 0) {
|
|
||||||
unsigned log2_max_pic_order_cnt_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
|
|
||||||
unsigned max_pic_order_cnt_lsb = 1 << log2_max_pic_order_cnt_lsb;
|
|
||||||
int pic_order_cnt_lsb = vl_rbsp_u(rbsp, log2_max_pic_order_cnt_lsb);
|
|
||||||
int pic_order_cnt_msb;
|
|
||||||
|
|
||||||
if (pic_order_cnt_lsb != priv->codec_data.h264.pic_order_cnt_lsb)
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
if (IdrPicFlag) {
|
|
||||||
priv->codec_data.h264.pic_order_cnt_msb = 0;
|
|
||||||
priv->codec_data.h264.pic_order_cnt_lsb = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((pic_order_cnt_lsb < priv->codec_data.h264.pic_order_cnt_lsb) &&
|
|
||||||
(priv->codec_data.h264.pic_order_cnt_lsb - pic_order_cnt_lsb) >= (max_pic_order_cnt_lsb / 2))
|
|
||||||
pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb + max_pic_order_cnt_lsb;
|
|
||||||
|
|
||||||
else if ((pic_order_cnt_lsb > priv->codec_data.h264.pic_order_cnt_lsb) &&
|
|
||||||
(pic_order_cnt_lsb - priv->codec_data.h264.pic_order_cnt_lsb) > (max_pic_order_cnt_lsb / 2))
|
|
||||||
pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb - max_pic_order_cnt_lsb;
|
|
||||||
|
|
||||||
else
|
|
||||||
pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb;
|
|
||||||
|
|
||||||
priv->codec_data.h264.pic_order_cnt_msb = pic_order_cnt_msb;
|
|
||||||
priv->codec_data.h264.pic_order_cnt_lsb = pic_order_cnt_lsb;
|
|
||||||
|
|
||||||
if (pps->bottom_field_pic_order_in_frame_present_flag && !priv->picture.h264.field_pic_flag) {
|
|
||||||
unsigned delta_pic_order_cnt_bottom = vl_rbsp_se(rbsp);
|
|
||||||
|
|
||||||
if (delta_pic_order_cnt_bottom != priv->codec_data.h264.delta_pic_order_cnt_bottom)
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
priv->codec_data.h264.delta_pic_order_cnt_bottom = delta_pic_order_cnt_bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!priv->picture.h264.field_pic_flag) {
|
|
||||||
priv->picture.h264.field_order_cnt[0] = pic_order_cnt_msb + pic_order_cnt_lsb;
|
|
||||||
priv->picture.h264.field_order_cnt[1] = priv->picture.h264.field_order_cnt [0] +
|
|
||||||
priv->codec_data.h264.delta_pic_order_cnt_bottom;
|
|
||||||
} else if (!priv->picture.h264.bottom_field_flag)
|
|
||||||
priv->picture.h264.field_order_cnt[0] = pic_order_cnt_msb + pic_order_cnt_lsb;
|
|
||||||
else
|
|
||||||
priv->picture.h264.field_order_cnt[1] = pic_order_cnt_msb + pic_order_cnt_lsb;
|
|
||||||
|
|
||||||
} else if (sps->pic_order_cnt_type == 1) {
|
|
||||||
unsigned MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
|
|
||||||
unsigned FrameNumOffset, absFrameNum, expectedPicOrderCnt;
|
|
||||||
|
|
||||||
if (!sps->delta_pic_order_always_zero_flag) {
|
|
||||||
unsigned delta_pic_order_cnt[2];
|
|
||||||
|
|
||||||
delta_pic_order_cnt[0] = vl_rbsp_se(rbsp);
|
|
||||||
|
|
||||||
if (delta_pic_order_cnt[0] != priv->codec_data.h264.delta_pic_order_cnt[0])
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
priv->codec_data.h264.delta_pic_order_cnt[0] = delta_pic_order_cnt[0];
|
|
||||||
|
|
||||||
if (pps->bottom_field_pic_order_in_frame_present_flag && !priv->picture.h264.field_pic_flag) {
|
|
||||||
delta_pic_order_cnt[1] = vl_rbsp_se(rbsp);
|
|
||||||
|
|
||||||
if (delta_pic_order_cnt[1] != priv->codec_data.h264.delta_pic_order_cnt[1])
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
priv->codec_data.h264.delta_pic_order_cnt[1] = delta_pic_order_cnt[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IdrPicFlag)
|
|
||||||
FrameNumOffset = 0;
|
|
||||||
else if (prevFrameNum > frame_num)
|
|
||||||
FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset + MaxFrameNum;
|
|
||||||
else
|
|
||||||
FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset;
|
|
||||||
|
|
||||||
priv->codec_data.h264.prevFrameNumOffset = FrameNumOffset;
|
|
||||||
|
|
||||||
if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
|
|
||||||
absFrameNum = FrameNumOffset + frame_num;
|
|
||||||
else
|
|
||||||
absFrameNum = 0;
|
|
||||||
|
|
||||||
if (nal_ref_idc == 0 && absFrameNum > 0)
|
|
||||||
absFrameNum = absFrameNum - 1;
|
|
||||||
|
|
||||||
if (absFrameNum > 0) {
|
|
||||||
unsigned picOrderCntCycleCnt = (absFrameNum - 1) / sps->num_ref_frames_in_pic_order_cnt_cycle;
|
|
||||||
unsigned frameNumInPicOrderCntCycle = (absFrameNum - 1) % sps->num_ref_frames_in_pic_order_cnt_cycle;
|
|
||||||
signed ExpectedDeltaPerPicOrderCntCycle = 0;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i)
|
|
||||||
ExpectedDeltaPerPicOrderCntCycle += sps->offset_for_ref_frame[i];
|
|
||||||
|
|
||||||
expectedPicOrderCnt = picOrderCntCycleCnt * ExpectedDeltaPerPicOrderCntCycle;
|
|
||||||
for (i = 0; i <= frameNumInPicOrderCntCycle; ++i)
|
|
||||||
expectedPicOrderCnt += sps->offset_for_ref_frame[i];
|
|
||||||
|
|
||||||
} else
|
|
||||||
expectedPicOrderCnt = 0;
|
|
||||||
|
|
||||||
if (nal_ref_idc == 0)
|
|
||||||
expectedPicOrderCnt += sps->offset_for_non_ref_pic;
|
|
||||||
|
|
||||||
if (!priv->picture.h264.field_pic_flag) {
|
|
||||||
priv->picture.h264.field_order_cnt[0] = expectedPicOrderCnt + priv->codec_data.h264.delta_pic_order_cnt[0];
|
|
||||||
priv->picture.h264.field_order_cnt[1] = priv->picture.h264.field_order_cnt[0] +
|
|
||||||
sps->offset_for_top_to_bottom_field + priv->codec_data.h264.delta_pic_order_cnt[1];
|
|
||||||
|
|
||||||
} else if (!priv->picture.h264.bottom_field_flag)
|
|
||||||
priv->picture.h264.field_order_cnt[0] = expectedPicOrderCnt + priv->codec_data.h264.delta_pic_order_cnt[0];
|
|
||||||
else
|
|
||||||
priv->picture.h264.field_order_cnt[1] = expectedPicOrderCnt + sps->offset_for_top_to_bottom_field +
|
|
||||||
priv->codec_data.h264.delta_pic_order_cnt[0];
|
|
||||||
|
|
||||||
} else if (sps->pic_order_cnt_type == 2) {
|
|
||||||
unsigned MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
|
|
||||||
unsigned FrameNumOffset, tempPicOrderCnt;
|
|
||||||
|
|
||||||
if (IdrPicFlag)
|
|
||||||
FrameNumOffset = 0;
|
|
||||||
else if (prevFrameNum > frame_num)
|
|
||||||
FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset + MaxFrameNum;
|
|
||||||
else
|
|
||||||
FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset;
|
|
||||||
|
|
||||||
priv->codec_data.h264.prevFrameNumOffset = FrameNumOffset;
|
|
||||||
|
|
||||||
if (IdrPicFlag)
|
|
||||||
tempPicOrderCnt = 0;
|
|
||||||
else if (nal_ref_idc == 0)
|
|
||||||
tempPicOrderCnt = 2 * (FrameNumOffset + frame_num) - 1;
|
|
||||||
else
|
|
||||||
tempPicOrderCnt = 2 * (FrameNumOffset + frame_num);
|
|
||||||
|
|
||||||
if (!priv->picture.h264.field_pic_flag) {
|
|
||||||
priv->picture.h264.field_order_cnt[0] = tempPicOrderCnt;
|
|
||||||
priv->picture.h264.field_order_cnt[1] = tempPicOrderCnt;
|
|
||||||
|
|
||||||
} else if (!priv->picture.h264.bottom_field_flag)
|
|
||||||
priv->picture.h264.field_order_cnt[0] = tempPicOrderCnt;
|
|
||||||
else
|
|
||||||
priv->picture.h264.field_order_cnt[1] = tempPicOrderCnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pps->redundant_pic_cnt_present_flag)
|
|
||||||
/* redundant_pic_cnt */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (slice_type == PIPE_H264_SLICE_TYPE_B)
|
|
||||||
/* direct_spatial_mv_pred_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
priv->picture.h264.num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_default_active_minus1;
|
|
||||||
priv->picture.h264.num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_default_active_minus1;
|
|
||||||
|
|
||||||
if (slice_type == PIPE_H264_SLICE_TYPE_P ||
|
|
||||||
slice_type == PIPE_H264_SLICE_TYPE_SP ||
|
|
||||||
slice_type == PIPE_H264_SLICE_TYPE_B) {
|
|
||||||
|
|
||||||
/* num_ref_idx_active_override_flag */
|
|
||||||
if (vl_rbsp_u(rbsp, 1)) {
|
|
||||||
priv->picture.h264.num_ref_idx_l0_active_minus1 = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (slice_type == PIPE_H264_SLICE_TYPE_B)
|
|
||||||
priv->picture.h264.num_ref_idx_l1_active_minus1 = vl_rbsp_ue(rbsp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nal_unit_type == 20 || nal_unit_type == 21)
|
|
||||||
ref_pic_list_mvc_modification(priv, rbsp);
|
|
||||||
else
|
|
||||||
ref_pic_list_modification(priv, rbsp, slice_type);
|
|
||||||
|
|
||||||
if ((pps->weighted_pred_flag && (slice_type == PIPE_H264_SLICE_TYPE_P || slice_type == PIPE_H264_SLICE_TYPE_SP)) ||
|
|
||||||
(pps->weighted_bipred_idc == 1 && slice_type == PIPE_H264_SLICE_TYPE_B))
|
|
||||||
pred_weight_table(priv, rbsp, sps, slice_type);
|
|
||||||
|
|
||||||
if (nal_ref_idc != 0)
|
|
||||||
dec_ref_pic_marking(priv, rbsp, IdrPicFlag);
|
|
||||||
|
|
||||||
if (pps->entropy_coding_mode_flag && slice_type != PIPE_H264_SLICE_TYPE_I && slice_type != PIPE_H264_SLICE_TYPE_SI)
|
|
||||||
/* cabac_init_idc */
|
|
||||||
vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
/* slice_qp_delta */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
|
|
||||||
if (slice_type == PIPE_H264_SLICE_TYPE_SP || slice_type == PIPE_H264_SLICE_TYPE_SI) {
|
|
||||||
if (slice_type == PIPE_H264_SLICE_TYPE_SP)
|
|
||||||
/* sp_for_switch_flag */
|
|
||||||
vl_rbsp_u(rbsp, 1);
|
|
||||||
|
|
||||||
/*slice_qs_delta */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pps->deblocking_filter_control_present_flag) {
|
|
||||||
unsigned disable_deblocking_filter_idc = vl_rbsp_ue(rbsp);
|
|
||||||
|
|
||||||
if (disable_deblocking_filter_idc != 1) {
|
|
||||||
/* slice_alpha_c0_offset_div2 */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
|
|
||||||
/* slice_beta_offset_div2 */
|
|
||||||
vl_rbsp_se(rbsp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pps->num_slice_groups_minus1 > 0 && pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5)
|
|
||||||
/* slice_group_change_cycle */
|
|
||||||
vl_rbsp_u(rbsp, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vid_dec_h264_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left)
|
|
||||||
{
|
|
||||||
unsigned nal_ref_idc, nal_unit_type;
|
|
||||||
|
|
||||||
if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (vl_vlc_peekbits(vlc, 24) != 0x000001) {
|
|
||||||
vl_vlc_eatbits(vlc, 8);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->slice) {
|
|
||||||
unsigned bytes = priv->bytes_left - (vl_vlc_bits_left(vlc) / 8);
|
|
||||||
++priv->picture.h264.slice_count;
|
|
||||||
priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
|
|
||||||
1, &priv->slice, &bytes);
|
|
||||||
priv->slice = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
vl_vlc_eatbits(vlc, 24);
|
|
||||||
|
|
||||||
/* forbidden_zero_bit */
|
|
||||||
vl_vlc_eatbits(vlc, 1);
|
|
||||||
|
|
||||||
nal_ref_idc = vl_vlc_get_uimsbf(vlc, 2);
|
|
||||||
|
|
||||||
if (nal_ref_idc != priv->codec_data.h264.nal_ref_idc &&
|
|
||||||
(nal_ref_idc * priv->codec_data.h264.nal_ref_idc) == 0)
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
priv->codec_data.h264.nal_ref_idc = nal_ref_idc;
|
|
||||||
|
|
||||||
nal_unit_type = vl_vlc_get_uimsbf(vlc, 5);
|
|
||||||
|
|
||||||
if (nal_unit_type != 1 && nal_unit_type != 5)
|
|
||||||
vid_dec_h264_EndFrame(priv);
|
|
||||||
|
|
||||||
if (nal_unit_type == 7) {
|
|
||||||
struct vl_rbsp rbsp;
|
|
||||||
vl_rbsp_init(&rbsp, vlc, ~0);
|
|
||||||
seq_parameter_set(priv, &rbsp);
|
|
||||||
|
|
||||||
} else if (nal_unit_type == 8) {
|
|
||||||
struct vl_rbsp rbsp;
|
|
||||||
vl_rbsp_init(&rbsp, vlc, ~0);
|
|
||||||
picture_parameter_set(priv, &rbsp);
|
|
||||||
|
|
||||||
} else if (nal_unit_type == 1 || nal_unit_type == 5) {
|
|
||||||
/* Coded slice of a non-IDR or IDR picture */
|
|
||||||
unsigned bits = vl_vlc_valid_bits(vlc);
|
|
||||||
unsigned bytes = bits / 8 + 4;
|
|
||||||
struct vl_rbsp rbsp;
|
|
||||||
uint8_t buf[8];
|
|
||||||
const void *ptr = buf;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
buf[0] = 0x0;
|
|
||||||
buf[1] = 0x0;
|
|
||||||
buf[2] = 0x1;
|
|
||||||
buf[3] = (nal_ref_idc << 5) | nal_unit_type;
|
|
||||||
for (i = 4; i < bytes; ++i)
|
|
||||||
buf[i] = vl_vlc_peekbits(vlc, bits) >> ((bytes - i - 1) * 8);
|
|
||||||
|
|
||||||
priv->bytes_left = (vl_vlc_bits_left(vlc) - bits) / 8;
|
|
||||||
priv->slice = vlc->data;
|
|
||||||
|
|
||||||
vl_rbsp_init(&rbsp, vlc, 128);
|
|
||||||
slice_header(priv, &rbsp, nal_ref_idc, nal_unit_type);
|
|
||||||
|
|
||||||
vid_dec_h264_BeginFrame(priv);
|
|
||||||
|
|
||||||
++priv->picture.h264.slice_count;
|
|
||||||
priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
|
|
||||||
1, &ptr, &bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* resync to byte boundary */
|
|
||||||
vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
|
|
||||||
#include "entrypoint.h"
|
#include "entrypoint.h"
|
||||||
#include "vid_enc.h"
|
#include "vid_enc.h"
|
||||||
|
#include "vid_omx_common.h"
|
||||||
|
|
||||||
struct encode_task {
|
struct encode_task {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,14 @@
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
|
|
||||||
if gallium_omx == 'bellagio'
|
|
||||||
files_omx = files(
|
files_omx = files(
|
||||||
|
'vid_dec_common.c',
|
||||||
|
'vid_dec_h264_common.c',
|
||||||
|
'vid_omx_common.c'
|
||||||
|
)
|
||||||
|
|
||||||
|
if gallium_omx == 'bellagio'
|
||||||
|
files_omx += files(
|
||||||
'bellagio/entrypoint.c',
|
'bellagio/entrypoint.c',
|
||||||
'bellagio/vid_dec.c',
|
'bellagio/vid_dec.c',
|
||||||
'bellagio/vid_dec_mpeg12.c',
|
'bellagio/vid_dec_mpeg12.c',
|
||||||
|
|
@ -28,8 +34,11 @@ files_omx = files(
|
||||||
'bellagio/vid_enc.c'
|
'bellagio/vid_enc.c'
|
||||||
)
|
)
|
||||||
elif gallium_omx == 'tizonia'
|
elif gallium_omx == 'tizonia'
|
||||||
files_omx = files(
|
files_omx += files(
|
||||||
'tizonia/entrypoint.c',
|
'tizonia/entrypoint.c',
|
||||||
|
'tizonia/h264d.c',
|
||||||
|
'tizonia/h264dprc.c',
|
||||||
|
'tizonia/h264dinport.c'
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
C_SOURCES := \
|
C_SOURCES := \
|
||||||
entrypoint.c \
|
entrypoint.c \
|
||||||
entrypoint.h
|
entrypoint.h \
|
||||||
|
h264d.c \
|
||||||
|
h264d.h \
|
||||||
|
h264dprc.c \
|
||||||
|
h264dprc.h \
|
||||||
|
h264dinport.c \
|
||||||
|
h264dinport.h \
|
||||||
|
h264dinport_decls.h \
|
||||||
|
names.h
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,53 @@
|
||||||
#include <tizplatform.h>
|
#include <tizplatform.h>
|
||||||
#include <tizkernel.h>
|
#include <tizkernel.h>
|
||||||
#include <tizscheduler.h>
|
#include <tizscheduler.h>
|
||||||
|
#include <tizport.h>
|
||||||
|
#include <tizport_decls.h>
|
||||||
|
#include <tizvideoport.h>
|
||||||
|
#include <tizvideoport_decls.h>
|
||||||
|
|
||||||
|
#include "vid_dec_h264_common.h"
|
||||||
#include "entrypoint.h"
|
#include "entrypoint.h"
|
||||||
|
#include "h264d.h"
|
||||||
|
#include "h264dprc.h"
|
||||||
|
#include "h264dinport.h"
|
||||||
|
#include "names.h"
|
||||||
|
|
||||||
OMX_ERRORTYPE OMX_ComponentInit (OMX_HANDLETYPE ap_hdl)
|
OMX_ERRORTYPE OMX_ComponentInit (OMX_HANDLETYPE ap_hdl)
|
||||||
{
|
{
|
||||||
|
tiz_role_factory_t h264d_role;
|
||||||
|
const tiz_role_factory_t * rf_list[] = {&h264d_role};
|
||||||
|
tiz_type_factory_t h264dprc_type;
|
||||||
|
tiz_type_factory_t h264d_inport_type;
|
||||||
|
const tiz_type_factory_t * tf_list[] = {&h264dprc_type, &h264d_inport_type};
|
||||||
|
|
||||||
|
/* Settings for roles */
|
||||||
|
strcpy ((OMX_STRING) h264d_role.role, OMX_VID_DEC_AVC_ROLE);
|
||||||
|
h264d_role.pf_cport = instantiate_h264d_config_port;
|
||||||
|
h264d_role.pf_port[0] = instantiate_h264d_input_port;
|
||||||
|
h264d_role.pf_port[1] = instantiate_h264d_output_port;
|
||||||
|
h264d_role.nports = 2;
|
||||||
|
h264d_role.pf_proc = instantiate_h264d_processor;
|
||||||
|
|
||||||
|
/* Settings for classes */
|
||||||
|
strcpy ((OMX_STRING) h264dprc_type.class_name, "h264dprc_class");
|
||||||
|
h264dprc_type.pf_class_init = h264d_prc_class_init;
|
||||||
|
strcpy ((OMX_STRING) h264dprc_type.object_name, "h264dprc");
|
||||||
|
h264dprc_type.pf_object_init = h264d_prc_init;
|
||||||
|
|
||||||
|
strcpy ((OMX_STRING) h264d_inport_type.class_name, "h264dinport_class");
|
||||||
|
h264d_inport_type.pf_class_init = h264d_inport_class_init;
|
||||||
|
strcpy ((OMX_STRING) h264d_inport_type.object_name, "h264dinport");
|
||||||
|
h264d_inport_type.pf_object_init = h264d_inport_init;
|
||||||
|
|
||||||
|
/* Initialize the component infrastructure */
|
||||||
|
tiz_comp_init (ap_hdl, OMX_VID_COMP_NAME);
|
||||||
|
|
||||||
|
/* Classes need to be registered first */
|
||||||
|
tiz_comp_register_types (ap_hdl, tf_list, 2);
|
||||||
|
|
||||||
|
/* Register the component roles */
|
||||||
|
tiz_comp_register_roles (ap_hdl, rf_list, 1);
|
||||||
|
|
||||||
return OMX_ErrorNone;
|
return OMX_ErrorNone;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
176
src/gallium/state_trackers/omx/tizonia/h264d.c
Normal file
176
src/gallium/state_trackers/omx/tizonia/h264d.c
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <tizport_decls.h>
|
||||||
|
|
||||||
|
#include "vid_dec_h264_common.h"
|
||||||
|
|
||||||
|
#include "h264dprc.h"
|
||||||
|
#include "h264d.h"
|
||||||
|
#include "names.h"
|
||||||
|
|
||||||
|
static OMX_VERSIONTYPE h264_decoder_version = {{0, 0, 0, 1}};
|
||||||
|
|
||||||
|
OMX_PTR instantiate_h264d_input_port(OMX_HANDLETYPE ap_hdl)
|
||||||
|
{
|
||||||
|
OMX_VIDEO_PORTDEFINITIONTYPE portdef;
|
||||||
|
OMX_VIDEO_PARAM_AVCTYPE avctype;
|
||||||
|
OMX_VIDEO_CODINGTYPE encodings[] = {
|
||||||
|
OMX_VIDEO_CodingAVC,
|
||||||
|
OMX_VIDEO_CodingMax
|
||||||
|
};
|
||||||
|
OMX_COLOR_FORMATTYPE formats[] = {
|
||||||
|
OMX_COLOR_FormatUnused,
|
||||||
|
OMX_COLOR_FormatMax
|
||||||
|
};
|
||||||
|
tiz_port_options_t avc_port_opts = {
|
||||||
|
OMX_PortDomainVideo,
|
||||||
|
OMX_DirInput,
|
||||||
|
OMX_VID_DEC_AVC_INPUT_PORT_MIN_BUF_COUNT,
|
||||||
|
OMX_VID_DEC_AVC_PORT_MIN_INPUT_BUF_SIZE,
|
||||||
|
OMX_VID_DEC_AVC_PORT_NONCONTIGUOUS,
|
||||||
|
OMX_VID_DEC_AVC_PORT_ALIGNMENT,
|
||||||
|
OMX_VID_DEC_AVC_PORT_SUPPLIERPREF,
|
||||||
|
{OMX_VID_DEC_AVC_INPUT_PORT_INDEX, NULL, NULL, NULL},
|
||||||
|
1 /* slave port */
|
||||||
|
};
|
||||||
|
OMX_VIDEO_AVCLEVELTYPE levels[] = {
|
||||||
|
OMX_VIDEO_AVCLevel1,
|
||||||
|
OMX_VIDEO_AVCLevel1b,
|
||||||
|
OMX_VIDEO_AVCLevel11,
|
||||||
|
OMX_VIDEO_AVCLevel12,
|
||||||
|
OMX_VIDEO_AVCLevel13,
|
||||||
|
OMX_VIDEO_AVCLevel2,
|
||||||
|
OMX_VIDEO_AVCLevel21,
|
||||||
|
OMX_VIDEO_AVCLevel22,
|
||||||
|
OMX_VIDEO_AVCLevel3,
|
||||||
|
OMX_VIDEO_AVCLevel31,
|
||||||
|
OMX_VIDEO_AVCLevel32,
|
||||||
|
OMX_VIDEO_AVCLevel4,
|
||||||
|
OMX_VIDEO_AVCLevel41,
|
||||||
|
OMX_VIDEO_AVCLevel42,
|
||||||
|
OMX_VIDEO_AVCLevel5,
|
||||||
|
OMX_VIDEO_AVCLevel51,
|
||||||
|
OMX_VIDEO_AVCLevelMax
|
||||||
|
};
|
||||||
|
|
||||||
|
portdef.pNativeRender = NULL;
|
||||||
|
portdef.nFrameWidth = OMX_VID_DEC_AVC_DEFAULT_FRAME_WIDTH;
|
||||||
|
portdef.nFrameHeight = OMX_VID_DEC_AVC_DEFAULT_FRAME_HEIGHT;
|
||||||
|
portdef.nStride = 0;
|
||||||
|
portdef.nSliceHeight = 0;
|
||||||
|
portdef.nBitrate = 64000;
|
||||||
|
portdef.xFramerate = OMX_VID_DEC_AVC_DEFAULT_FRAME_RATE;
|
||||||
|
portdef.bFlagErrorConcealment = OMX_FALSE;
|
||||||
|
portdef.eCompressionFormat = OMX_VIDEO_CodingAVC;
|
||||||
|
portdef.eColorFormat = OMX_COLOR_FormatUnused;
|
||||||
|
portdef.pNativeWindow = NULL;
|
||||||
|
|
||||||
|
avctype.nSize = sizeof (OMX_VIDEO_PARAM_AVCTYPE);
|
||||||
|
avctype.nVersion.nVersion = OMX_VERSION;
|
||||||
|
avctype.nPortIndex = OMX_VID_DEC_AVC_INPUT_PORT_INDEX;
|
||||||
|
avctype.eProfile = OMX_VIDEO_AVCProfileHigh;
|
||||||
|
/* Encoder related, decide if need to initialise these */
|
||||||
|
avctype.nSliceHeaderSpacing = 0;
|
||||||
|
avctype.nPFrames = 0;
|
||||||
|
avctype.nBFrames = 0;
|
||||||
|
avctype.bUseHadamard = OMX_FALSE;
|
||||||
|
avctype.nRefFrames = 1;
|
||||||
|
avctype.nRefIdx10ActiveMinus1 = 1;
|
||||||
|
avctype.nRefIdx11ActiveMinus1 = 0;
|
||||||
|
avctype.bEnableUEP = OMX_FALSE;
|
||||||
|
avctype.bEnableFMO = OMX_FALSE;
|
||||||
|
avctype.bEnableASO = OMX_FALSE;
|
||||||
|
avctype.bEnableRS = OMX_FALSE;
|
||||||
|
avctype.eLevel = OMX_VIDEO_AVCLevel51;
|
||||||
|
avctype.nAllowedPictureTypes = 2;
|
||||||
|
avctype.bFrameMBsOnly = OMX_FALSE;
|
||||||
|
avctype.bMBAFF = OMX_FALSE;
|
||||||
|
avctype.bEntropyCodingCABAC = OMX_FALSE;
|
||||||
|
avctype.bWeightedPPrediction = OMX_FALSE;
|
||||||
|
avctype.nWeightedBipredicitonMode = 0;
|
||||||
|
avctype.bconstIpred = OMX_FALSE;
|
||||||
|
avctype.bDirect8x8Inference = OMX_FALSE;
|
||||||
|
avctype.bDirectSpatialTemporal = OMX_FALSE;
|
||||||
|
avctype.nCabacInitIdc = 0;
|
||||||
|
avctype.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
|
||||||
|
|
||||||
|
return factory_new (tiz_get_type(ap_hdl, "h264dinport"),
|
||||||
|
&avc_port_opts, &portdef,
|
||||||
|
&encodings, &formats, &avctype, &levels,
|
||||||
|
NULL /* OMX_VIDEO_PARAM_BITRATETYPE */,
|
||||||
|
NULL /* OMX_VIDEO_PARAM_QUANTIZATIONTYPE */);
|
||||||
|
}
|
||||||
|
|
||||||
|
OMX_PTR instantiate_h264d_output_port(OMX_HANDLETYPE ap_hdl)
|
||||||
|
{
|
||||||
|
OMX_VIDEO_PORTDEFINITIONTYPE portdef;
|
||||||
|
OMX_VIDEO_CODINGTYPE encodings[] = {
|
||||||
|
OMX_VIDEO_CodingUnused,
|
||||||
|
OMX_VIDEO_CodingMax
|
||||||
|
};
|
||||||
|
OMX_COLOR_FORMATTYPE formats[] = {
|
||||||
|
OMX_COLOR_FormatYUV420SemiPlanar,
|
||||||
|
OMX_COLOR_FormatMax
|
||||||
|
};
|
||||||
|
tiz_port_options_t rawvideo_port_opts = {
|
||||||
|
OMX_PortDomainVideo,
|
||||||
|
OMX_DirOutput,
|
||||||
|
OMX_VID_DEC_AVC_OUTPUT_PORT_MIN_BUF_COUNT,
|
||||||
|
OMX_VID_DEC_AVC_PORT_MIN_OUTPUT_BUF_SIZE,
|
||||||
|
OMX_VID_DEC_AVC_PORT_NONCONTIGUOUS,
|
||||||
|
OMX_VID_DEC_AVC_PORT_ALIGNMENT,
|
||||||
|
OMX_VID_DEC_AVC_PORT_SUPPLIERPREF,
|
||||||
|
{OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX, NULL, NULL, NULL},
|
||||||
|
0 /* Master port */
|
||||||
|
};
|
||||||
|
|
||||||
|
portdef.pNativeRender = NULL;
|
||||||
|
portdef.nFrameWidth = OMX_VID_DEC_AVC_DEFAULT_FRAME_WIDTH;
|
||||||
|
portdef.nFrameHeight = OMX_VID_DEC_AVC_DEFAULT_FRAME_HEIGHT;
|
||||||
|
portdef.nStride = 0;
|
||||||
|
portdef.nSliceHeight = 0;
|
||||||
|
portdef.nBitrate = 64000;
|
||||||
|
portdef.xFramerate = OMX_VID_DEC_AVC_DEFAULT_FRAME_RATE;
|
||||||
|
portdef.bFlagErrorConcealment = OMX_FALSE;
|
||||||
|
portdef.eCompressionFormat = OMX_VIDEO_CodingUnused;
|
||||||
|
portdef.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
|
||||||
|
portdef.pNativeWindow = NULL;
|
||||||
|
|
||||||
|
return factory_new(tiz_get_type(ap_hdl, "tizvideoport"),
|
||||||
|
&rawvideo_port_opts, &portdef,
|
||||||
|
&encodings, &formats);
|
||||||
|
}
|
||||||
|
|
||||||
|
OMX_PTR instantiate_h264d_config_port(OMX_HANDLETYPE ap_hdl)
|
||||||
|
{
|
||||||
|
return factory_new(tiz_get_type(ap_hdl, "tizconfigport"),
|
||||||
|
NULL, /* this port does not take options */
|
||||||
|
OMX_VID_COMP_NAME, h264_decoder_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
OMX_PTR instantiate_h264d_processor(OMX_HANDLETYPE ap_hdl)
|
||||||
|
{
|
||||||
|
return factory_new(tiz_get_type(ap_hdl, "h264dprc"));
|
||||||
|
}
|
||||||
40
src/gallium/state_trackers/omx/tizonia/h264d.h
Normal file
40
src/gallium/state_trackers/omx/tizonia/h264d.h
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef H264D_H
|
||||||
|
#define H264D_H
|
||||||
|
|
||||||
|
#include <OMX_Core.h>
|
||||||
|
#include <OMX_Types.h>
|
||||||
|
#include <OMX_Video.h>
|
||||||
|
|
||||||
|
OMX_PTR instantiate_h264d_config_port(OMX_HANDLETYPE ap_hdl);
|
||||||
|
OMX_PTR instantiate_h264d_input_port(OMX_HANDLETYPE ap_hdl);
|
||||||
|
OMX_PTR instantiate_h264d_output_port(OMX_HANDLETYPE ap_hdl);
|
||||||
|
OMX_PTR instantiate_h264d_processor(OMX_HANDLETYPE ap_hdl);
|
||||||
|
|
||||||
|
#endif /* H264D_H */
|
||||||
147
src/gallium/state_trackers/omx/tizonia/h264dinport.c
Normal file
147
src/gallium/state_trackers/omx/tizonia/h264dinport.c
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include <tizplatform.h>
|
||||||
|
#include <tizkernel.h>
|
||||||
|
|
||||||
|
#include "vl/vl_winsys.h"
|
||||||
|
|
||||||
|
#include "h264d.h"
|
||||||
|
#include "h264dinport.h"
|
||||||
|
#include "h264dinport_decls.h"
|
||||||
|
#include "vid_dec_common.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* h264dinport class
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void * h264d_inport_ctor(void * ap_obj, va_list * app)
|
||||||
|
{
|
||||||
|
return super_ctor(typeOf(ap_obj, "h264dinport"), ap_obj, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void * h264d_inport_dtor(void * ap_obj)
|
||||||
|
{
|
||||||
|
return super_dtor(typeOf(ap_obj, "h264dinport"), ap_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* from tiz_api
|
||||||
|
*/
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_inport_SetParameter(const void * ap_obj, OMX_HANDLETYPE ap_hdl,
|
||||||
|
OMX_INDEXTYPE a_index, OMX_PTR ap_struct)
|
||||||
|
{
|
||||||
|
OMX_ERRORTYPE err = OMX_ErrorNone;
|
||||||
|
|
||||||
|
assert(ap_obj);
|
||||||
|
assert(ap_hdl);
|
||||||
|
assert(ap_struct);
|
||||||
|
|
||||||
|
if (a_index == OMX_IndexParamPortDefinition) {
|
||||||
|
vid_dec_PrivateType * p_prc = tiz_get_prc(ap_hdl);
|
||||||
|
OMX_VIDEO_PORTDEFINITIONTYPE * p_def = &(p_prc->out_port_def_.format.video);
|
||||||
|
OMX_PARAM_PORTDEFINITIONTYPE * i_def = (OMX_PARAM_PORTDEFINITIONTYPE *) ap_struct;
|
||||||
|
|
||||||
|
/* Make changes only if there is a resolution change */
|
||||||
|
if ((p_def->nFrameWidth == i_def->format.video.nFrameWidth) &&
|
||||||
|
(p_def->nFrameHeight == i_def->format.video.nFrameHeight) &&
|
||||||
|
(p_def->eCompressionFormat == i_def->format.video.eCompressionFormat))
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* Set some default values if not set */
|
||||||
|
if (i_def->format.video.nStride == 0)
|
||||||
|
i_def->format.video.nStride = i_def->format.video.nFrameWidth;
|
||||||
|
if (i_def->format.video.nSliceHeight == 0)
|
||||||
|
i_def->format.video.nSliceHeight = i_def->format.video.nFrameHeight;
|
||||||
|
|
||||||
|
err = super_SetParameter(typeOf (ap_obj, "h264dinport"), ap_obj,
|
||||||
|
ap_hdl, a_index, ap_struct);
|
||||||
|
if (err == OMX_ErrorNone) {
|
||||||
|
tiz_port_t * p_obj = (tiz_port_t *) ap_obj;
|
||||||
|
|
||||||
|
/* Set desired buffer size that will be used when allocating input buffers */
|
||||||
|
p_obj->portdef_.nBufferSize = i_def->format.video.nFrameWidth * i_def->format.video.nFrameHeight * 512 / (16*16);
|
||||||
|
|
||||||
|
/* Get a locally copy of port def. Useful for the early return above */
|
||||||
|
tiz_check_omx(tiz_api_GetParameter(tiz_get_krn(handleOf(p_prc)), handleOf(p_prc),
|
||||||
|
OMX_IndexParamPortDefinition, &(p_prc->out_port_def_)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* h264dinport_class
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void * h264d_inport_class_ctor(void * ap_obj, va_list * app)
|
||||||
|
{
|
||||||
|
/* NOTE: Class methods might be added in the future. None for now. */
|
||||||
|
return super_ctor (typeOf (ap_obj, "h264dinport_class"), ap_obj, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initialization
|
||||||
|
*/
|
||||||
|
|
||||||
|
void * h264d_inport_class_init(void * ap_tos, void * ap_hdl)
|
||||||
|
{
|
||||||
|
void * tizavcport = tiz_get_type(ap_hdl, "tizavcport");
|
||||||
|
void * h264dinport_class
|
||||||
|
= factory_new(classOf(tizavcport), "h264dinport_class",
|
||||||
|
classOf(tizavcport), sizeof(h264d_inport_class_t),
|
||||||
|
ap_tos, ap_hdl, ctor, h264d_inport_class_ctor, 0);
|
||||||
|
return h264dinport_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * h264d_inport_init(void * ap_tos, void * ap_hdl)
|
||||||
|
{
|
||||||
|
void * tizavcport = tiz_get_type (ap_hdl, "tizavcport");
|
||||||
|
void * h264dinport_class = tiz_get_type (ap_hdl, "h264dinport_class");
|
||||||
|
void * h264dinport = factory_new
|
||||||
|
/* TIZ_CLASS_COMMENT: class type, class name, parent, size */
|
||||||
|
(h264dinport_class, "h264dinport", tizavcport,
|
||||||
|
sizeof (h264d_inport_t),
|
||||||
|
/* TIZ_CLASS_COMMENT: class constructor */
|
||||||
|
ap_tos, ap_hdl,
|
||||||
|
/* TIZ_CLASS_COMMENT: class constructor */
|
||||||
|
ctor, h264d_inport_ctor,
|
||||||
|
/* TIZ_CLASS_COMMENT: class destructor */
|
||||||
|
dtor, h264d_inport_dtor,
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
tiz_api_SetParameter, h264d_inport_SetParameter,
|
||||||
|
/* TIZ_CLASS_COMMENT: stop value*/
|
||||||
|
0);
|
||||||
|
|
||||||
|
return h264dinport;
|
||||||
|
}
|
||||||
31
src/gallium/state_trackers/omx/tizonia/h264dinport.h
Normal file
31
src/gallium/state_trackers/omx/tizonia/h264dinport.h
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef H264DINPORT_H
|
||||||
|
#define H264DINPORT_H
|
||||||
|
|
||||||
|
void * h264d_inport_class_init(void * ap_tos, void * ap_hdl);
|
||||||
|
void * h264d_inport_init(void * ap_tos, void * ap_hdl);
|
||||||
|
|
||||||
|
#endif /* H264DINPORT_H */
|
||||||
48
src/gallium/state_trackers/omx/tizonia/h264dinport_decls.h
Normal file
48
src/gallium/state_trackers/omx/tizonia/h264dinport_decls.h
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef H264DINPORT_DECLS_H
|
||||||
|
#define H264DINPORT_DECLS_H
|
||||||
|
|
||||||
|
#include <OMX_TizoniaExt.h>
|
||||||
|
#include <OMX_Types.h>
|
||||||
|
|
||||||
|
#include <tizavcport_decls.h>
|
||||||
|
|
||||||
|
typedef struct h264d_inport h264d_inport_t;
|
||||||
|
struct h264d_inport
|
||||||
|
{
|
||||||
|
/* Object */
|
||||||
|
const tiz_avcport_t _;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct h264d_inport_class h264d_inport_class_t;
|
||||||
|
struct h264d_inport_class
|
||||||
|
{
|
||||||
|
/* Class */
|
||||||
|
const tiz_avcport_class_t _;
|
||||||
|
/* NOTE: Class methods might be added in the future */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* H264DINPORT_DECLS_H */
|
||||||
519
src/gallium/state_trackers/omx/tizonia/h264dprc.c
Normal file
519
src/gallium/state_trackers/omx/tizonia/h264dprc.c
Normal file
|
|
@ -0,0 +1,519 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <tizplatform.h>
|
||||||
|
#include <tizkernel.h>
|
||||||
|
#include <tizutils.h>
|
||||||
|
|
||||||
|
#include "entrypoint.h"
|
||||||
|
#include "h264d.h"
|
||||||
|
#include "h264dprc.h"
|
||||||
|
#include "vid_omx_common.h"
|
||||||
|
#include "vid_dec_common.h"
|
||||||
|
#include "vid_dec_h264_common.h"
|
||||||
|
|
||||||
|
#include "vl/vl_video_buffer.h"
|
||||||
|
#include "vl/vl_compositor.h"
|
||||||
|
#include "util/u_surface.h"
|
||||||
|
|
||||||
|
unsigned dec_frame_delta;
|
||||||
|
|
||||||
|
static void release_input_headers(vid_dec_PrivateType* priv) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < priv->num_in_buffers; i++) {
|
||||||
|
assert(!priv->in_port_disabled_);
|
||||||
|
if (priv->in_buffers[i]->pInputPortPrivate) {
|
||||||
|
vid_dec_FreeInputPortPrivate(priv->in_buffers[i]);
|
||||||
|
}
|
||||||
|
(void) tiz_krn_release_buffer (tiz_get_krn (handleOf (priv)),
|
||||||
|
OMX_VID_DEC_AVC_INPUT_PORT_INDEX,
|
||||||
|
priv->in_buffers[i]);
|
||||||
|
priv->in_buffers[i] = NULL;
|
||||||
|
}
|
||||||
|
priv->p_inhdr_ = NULL;
|
||||||
|
priv->num_in_buffers = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void release_output_header(vid_dec_PrivateType* priv) {
|
||||||
|
if (priv->p_outhdr_) {
|
||||||
|
assert(!priv->out_port_disabled_);
|
||||||
|
(void) tiz_krn_release_buffer (tiz_get_krn (handleOf (priv)),
|
||||||
|
OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX,
|
||||||
|
priv->p_outhdr_);
|
||||||
|
priv->p_outhdr_ = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_release_all_headers(vid_dec_PrivateType* priv)
|
||||||
|
{
|
||||||
|
assert(priv);
|
||||||
|
release_input_headers(priv);
|
||||||
|
release_output_header(priv);
|
||||||
|
|
||||||
|
return OMX_ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void h264d_buffer_emptied(vid_dec_PrivateType* priv, OMX_BUFFERHEADERTYPE * p_hdr)
|
||||||
|
{
|
||||||
|
assert(priv);
|
||||||
|
assert(priv->in_buffers[0] == p_hdr);
|
||||||
|
|
||||||
|
if (!priv->out_port_disabled_) {
|
||||||
|
assert (p_hdr->nFilledLen == 0);
|
||||||
|
p_hdr->nOffset = 0;
|
||||||
|
|
||||||
|
if ((p_hdr->nFlags & OMX_BUFFERFLAG_EOS) != 0) {
|
||||||
|
priv->eos_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) tiz_krn_release_buffer (tiz_get_krn (handleOf (priv)), 0, p_hdr);
|
||||||
|
priv->p_inhdr_ = NULL;
|
||||||
|
priv->in_buffers[0] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void h264d_buffer_filled(vid_dec_PrivateType* priv, OMX_BUFFERHEADERTYPE * p_hdr)
|
||||||
|
{
|
||||||
|
assert(priv);
|
||||||
|
assert(p_hdr);
|
||||||
|
assert(priv->p_outhdr_ == p_hdr);
|
||||||
|
|
||||||
|
if (!priv->in_port_disabled_) {
|
||||||
|
p_hdr->nOffset = 0;
|
||||||
|
|
||||||
|
if (priv->eos_) {
|
||||||
|
/* EOS has been received and all the input data has been consumed
|
||||||
|
* already, so its time to propagate the EOS flag */
|
||||||
|
priv->p_outhdr_->nFlags |= OMX_BUFFERFLAG_EOS;
|
||||||
|
priv->eos_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) tiz_krn_release_buffer(tiz_get_krn (handleOf (priv)),
|
||||||
|
OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX,
|
||||||
|
p_hdr);
|
||||||
|
priv->p_outhdr_ = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool h264d_shift_buffers_left(vid_dec_PrivateType* priv) {
|
||||||
|
if (--priv->num_in_buffers) {
|
||||||
|
priv->in_buffers[0] = priv->in_buffers[1];
|
||||||
|
priv->sizes[0] = priv->sizes[1] - dec_frame_delta;
|
||||||
|
priv->inputs[0] = priv->inputs[1] + dec_frame_delta;
|
||||||
|
priv->timestamps[0] = priv->timestamps[1];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_BUFFERHEADERTYPE * get_input_buffer(vid_dec_PrivateType* priv) {
|
||||||
|
assert(priv);
|
||||||
|
|
||||||
|
if (priv->in_port_disabled_) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->num_in_buffers > 1) {
|
||||||
|
/* The input buffer wasn't cleared last time. */
|
||||||
|
h264d_buffer_emptied(priv, priv->in_buffers[0]);
|
||||||
|
if (priv->in_buffers[0]) {
|
||||||
|
/* Failed to release buffer */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
h264d_shift_buffers_left(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode_frame expects new buffers each time */
|
||||||
|
assert(priv->p_inhdr_ || priv->first_buf_in_frame);
|
||||||
|
tiz_krn_claim_buffer(tiz_get_krn (handleOf (priv)),
|
||||||
|
OMX_VID_DEC_AVC_INPUT_PORT_INDEX, 0,
|
||||||
|
&priv->p_inhdr_);
|
||||||
|
return priv->p_inhdr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_BUFFERHEADERTYPE * get_output_buffer(vid_dec_PrivateType* priv) {
|
||||||
|
assert (priv);
|
||||||
|
|
||||||
|
if (priv->out_port_disabled_) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!priv->p_outhdr_) {
|
||||||
|
tiz_krn_claim_buffer(tiz_get_krn (handleOf (priv)),
|
||||||
|
OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX, 0,
|
||||||
|
&priv->p_outhdr_);
|
||||||
|
}
|
||||||
|
return priv->p_outhdr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset_stream_parameters(vid_dec_PrivateType* apriv)
|
||||||
|
{
|
||||||
|
assert(apriv);
|
||||||
|
TIZ_INIT_OMX_PORT_STRUCT(apriv->out_port_def_,
|
||||||
|
OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX);
|
||||||
|
|
||||||
|
tiz_api_GetParameter (tiz_get_krn (handleOf (apriv)), handleOf (apriv),
|
||||||
|
OMX_IndexParamPortDefinition, &(apriv->out_port_def_));
|
||||||
|
|
||||||
|
apriv->p_inhdr_ = 0;
|
||||||
|
apriv->num_in_buffers = 0;
|
||||||
|
apriv->first_buf_in_frame = true;
|
||||||
|
apriv->eos_ = false;
|
||||||
|
apriv->frame_finished = false;
|
||||||
|
apriv->frame_started = false;
|
||||||
|
apriv->picture.h264.field_order_cnt[0] = apriv->picture.h264.field_order_cnt[1] = INT_MAX;
|
||||||
|
apriv->slice = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replacement for bellagio's omx_base_filter_BufferMgmtFunction */
|
||||||
|
static void h264d_manage_buffers(vid_dec_PrivateType* priv) {
|
||||||
|
bool next_is_eos = priv->num_in_buffers == 2 ? !!(priv->in_buffers[1]->nFlags & OMX_BUFFERFLAG_EOS) : false;
|
||||||
|
vid_dec_FrameDecoded_common(priv, priv->in_buffers[0], priv->p_outhdr_);
|
||||||
|
|
||||||
|
priv->p_outhdr_->nTimeStamp = priv->in_buffers[0]->nTimeStamp;
|
||||||
|
|
||||||
|
/* Realase output buffer if filled or eos
|
||||||
|
Keep if two input buffers are being decoded */
|
||||||
|
if ((!next_is_eos) && ((priv->p_outhdr_->nFilledLen > 0) || priv->eos_)) {
|
||||||
|
h264d_buffer_filled(priv, priv->p_outhdr_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release input buffer if possible */
|
||||||
|
if (priv->in_buffers[0]->nFilledLen == 0) {
|
||||||
|
h264d_buffer_emptied(priv, priv->in_buffers[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE decode_frame(vid_dec_PrivateType*priv,
|
||||||
|
OMX_BUFFERHEADERTYPE *in_buf)
|
||||||
|
{
|
||||||
|
unsigned i = priv->num_in_buffers++;
|
||||||
|
priv->in_buffers[i] = in_buf;
|
||||||
|
priv->sizes[i] = in_buf->nFilledLen;
|
||||||
|
priv->inputs[i] = in_buf->pBuffer;
|
||||||
|
priv->timestamps[i] = in_buf->nTimeStamp;
|
||||||
|
|
||||||
|
while (priv->num_in_buffers > (!!(in_buf->nFlags & OMX_BUFFERFLAG_EOS) ? 0 : 1)) {
|
||||||
|
priv->eos_ = !!(priv->in_buffers[0]->nFlags & OMX_BUFFERFLAG_EOS);
|
||||||
|
unsigned min_bits_left = priv->eos_ ? 32 : MAX2(in_buf->nFilledLen * 8, 32);
|
||||||
|
struct vl_vlc vlc;
|
||||||
|
|
||||||
|
vl_vlc_init(&vlc, priv->num_in_buffers, priv->inputs, priv->sizes);
|
||||||
|
|
||||||
|
if (priv->slice)
|
||||||
|
priv->bytes_left = vl_vlc_bits_left(&vlc) / 8;
|
||||||
|
|
||||||
|
while (vl_vlc_bits_left (&vlc) > min_bits_left) {
|
||||||
|
vid_dec_h264_Decode(priv, &vlc, min_bits_left);
|
||||||
|
vl_vlc_fillbits(&vlc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->slice) {
|
||||||
|
unsigned bytes = priv->bytes_left - vl_vlc_bits_left(&vlc) / 8;
|
||||||
|
|
||||||
|
priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
|
||||||
|
1, &priv->slice, &bytes);
|
||||||
|
|
||||||
|
if (priv->num_in_buffers)
|
||||||
|
priv->slice = priv->inputs[1];
|
||||||
|
else
|
||||||
|
priv->slice = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->eos_ && priv->frame_started)
|
||||||
|
vid_dec_h264_EndFrame(priv);
|
||||||
|
|
||||||
|
if (priv->frame_finished) {
|
||||||
|
priv->frame_finished = false;
|
||||||
|
h264d_manage_buffers(priv);
|
||||||
|
} else if (priv->eos_) {
|
||||||
|
vid_dec_FreeInputPortPrivate(priv->in_buffers[0]);
|
||||||
|
h264d_manage_buffers(priv);
|
||||||
|
} else {
|
||||||
|
priv->in_buffers[0]->nFilledLen = 0;
|
||||||
|
h264d_buffer_emptied(priv, priv->in_buffers[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->out_port_disabled_) {
|
||||||
|
/* In case out port is disabled, h264d_buffer_emptied will fail to release input port.
|
||||||
|
* We need to wait before shifting the buffers in that case and check in
|
||||||
|
* get_input_buffer when out port is enabled to release and shift the buffers.
|
||||||
|
* Infinite looping occurs if buffer is not released */
|
||||||
|
if (priv->num_in_buffers == 2) {
|
||||||
|
/* Set the delta value for use in get_input_buffer before exiting */
|
||||||
|
dec_frame_delta = MIN2((min_bits_left - vl_vlc_bits_left(&vlc)) / 8, priv->sizes[1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
h264d_shift_buffers_left(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OMX_ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* h264dprc
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void * h264d_prc_ctor(void *ap_obj, va_list * app)
|
||||||
|
{
|
||||||
|
vid_dec_PrivateType*priv = super_ctor(typeOf (ap_obj, "h264dprc"), ap_obj, app);
|
||||||
|
assert(priv);
|
||||||
|
priv->p_inhdr_ = 0;
|
||||||
|
priv->p_outhdr_ = 0;
|
||||||
|
priv->first_buf_in_frame = true;
|
||||||
|
priv->eos_ = false;
|
||||||
|
priv->in_port_disabled_ = false;
|
||||||
|
priv->out_port_disabled_ = false;
|
||||||
|
priv->picture.base.profile = PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH;
|
||||||
|
priv->profile = PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH;
|
||||||
|
reset_stream_parameters(priv);
|
||||||
|
|
||||||
|
return priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void * h264d_prc_dtor(void *ap_obj)
|
||||||
|
{
|
||||||
|
return super_dtor(typeOf(ap_obj, "h264dprc"), ap_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_prc_allocate_resources(void *ap_obj, OMX_U32 a_pid)
|
||||||
|
{
|
||||||
|
vid_dec_PrivateType*priv = ap_obj;
|
||||||
|
struct pipe_screen *screen;
|
||||||
|
|
||||||
|
assert (priv);
|
||||||
|
|
||||||
|
priv->screen = omx_get_screen();
|
||||||
|
if (!priv->screen)
|
||||||
|
return OMX_ErrorInsufficientResources;
|
||||||
|
|
||||||
|
screen = priv->screen->pscreen;
|
||||||
|
priv->pipe = screen->context_create(screen, priv->screen, 0);
|
||||||
|
if (!priv->pipe)
|
||||||
|
return OMX_ErrorInsufficientResources;
|
||||||
|
|
||||||
|
if (!vl_compositor_init(&priv->compositor, priv->pipe)) {
|
||||||
|
priv->pipe->destroy(priv->pipe);
|
||||||
|
priv->pipe = NULL;
|
||||||
|
return OMX_ErrorInsufficientResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vl_compositor_init_state(&priv->cstate, priv->pipe)) {
|
||||||
|
vl_compositor_cleanup(&priv->compositor);
|
||||||
|
priv->pipe->destroy(priv->pipe);
|
||||||
|
priv->pipe = NULL;
|
||||||
|
return OMX_ErrorInsufficientResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIST_INITHEAD(&priv->codec_data.h264.dpb_list);
|
||||||
|
|
||||||
|
return OMX_ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_prc_deallocate_resources(void *ap_obj)
|
||||||
|
{
|
||||||
|
vid_dec_PrivateType*priv = ap_obj;
|
||||||
|
assert(priv);
|
||||||
|
|
||||||
|
if (priv->pipe) {
|
||||||
|
vl_compositor_cleanup_state(&priv->cstate);
|
||||||
|
vl_compositor_cleanup(&priv->compositor);
|
||||||
|
priv->pipe->destroy(priv->pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->screen)
|
||||||
|
omx_put_screen();
|
||||||
|
|
||||||
|
return OMX_ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_prc_prepare_to_transfer(void *ap_obj, OMX_U32 a_pid)
|
||||||
|
{
|
||||||
|
vid_dec_PrivateType*priv = ap_obj;
|
||||||
|
assert(priv);
|
||||||
|
|
||||||
|
TIZ_INIT_OMX_PORT_STRUCT(priv->out_port_def_,
|
||||||
|
OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX);
|
||||||
|
tiz_check_omx(
|
||||||
|
tiz_api_GetParameter(tiz_get_krn(handleOf(priv)), handleOf(priv),
|
||||||
|
OMX_IndexParamPortDefinition, &(priv->out_port_def_)));
|
||||||
|
|
||||||
|
priv->first_buf_in_frame = true;
|
||||||
|
priv->eos_ = false;
|
||||||
|
return OMX_ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_prc_transfer_and_process(void *ap_obj, OMX_U32 a_pid)
|
||||||
|
{
|
||||||
|
return OMX_ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_prc_stop_and_return(void *ap_obj)
|
||||||
|
{
|
||||||
|
vid_dec_PrivateType*priv = (vid_dec_PrivateType*) ap_obj;
|
||||||
|
return h264d_release_all_headers (priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_prc_buffers_ready(const void *ap_obj)
|
||||||
|
{
|
||||||
|
vid_dec_PrivateType*priv = (vid_dec_PrivateType*) ap_obj;
|
||||||
|
OMX_BUFFERHEADERTYPE *in_buf = NULL;
|
||||||
|
OMX_BUFFERHEADERTYPE *out_buf = NULL;
|
||||||
|
|
||||||
|
assert(priv);
|
||||||
|
|
||||||
|
/* Set parameters if start of stream */
|
||||||
|
if (!priv->eos_ && priv->first_buf_in_frame && (in_buf = get_input_buffer(priv))) {
|
||||||
|
decode_frame(priv, in_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't get input buffer if output buffer not found */
|
||||||
|
while (!priv->eos_ && (out_buf = get_output_buffer(priv)) && (in_buf = get_input_buffer(priv))) {
|
||||||
|
if (!priv->out_port_disabled_) {
|
||||||
|
decode_frame(priv, in_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OMX_ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_prc_port_flush(const void *ap_obj, OMX_U32 a_pid)
|
||||||
|
{
|
||||||
|
vid_dec_PrivateType*priv = (vid_dec_PrivateType*) ap_obj;
|
||||||
|
if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_INPUT_PORT_INDEX == a_pid) {
|
||||||
|
release_input_headers(priv);
|
||||||
|
reset_stream_parameters(priv);
|
||||||
|
}
|
||||||
|
if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX == a_pid) {
|
||||||
|
release_output_header(priv);
|
||||||
|
}
|
||||||
|
return OMX_ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_prc_port_disable(const void *ap_obj, OMX_U32 a_pid)
|
||||||
|
{
|
||||||
|
vid_dec_PrivateType*priv = (vid_dec_PrivateType*) ap_obj;
|
||||||
|
assert(priv);
|
||||||
|
if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_INPUT_PORT_INDEX == a_pid) {
|
||||||
|
/* Release all buffers */
|
||||||
|
h264d_release_all_headers(priv);
|
||||||
|
reset_stream_parameters(priv);
|
||||||
|
priv->in_port_disabled_ = true;
|
||||||
|
}
|
||||||
|
if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX == a_pid) {
|
||||||
|
release_output_header(priv);
|
||||||
|
priv->out_port_disabled_ = true;
|
||||||
|
}
|
||||||
|
return OMX_ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OMX_ERRORTYPE h264d_prc_port_enable(const void *ap_obj, OMX_U32 a_pid)
|
||||||
|
{
|
||||||
|
vid_dec_PrivateType* priv = (vid_dec_PrivateType*) ap_obj;
|
||||||
|
assert(priv);
|
||||||
|
if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_INPUT_PORT_INDEX == a_pid) {
|
||||||
|
if (priv->in_port_disabled_) {
|
||||||
|
reset_stream_parameters(priv);
|
||||||
|
priv->in_port_disabled_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX == a_pid) {
|
||||||
|
priv->out_port_disabled_ = false;
|
||||||
|
}
|
||||||
|
return OMX_ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* h264d_prc_class
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void * h264d_prc_class_ctor(void *ap_obj, va_list * app)
|
||||||
|
{
|
||||||
|
/* NOTE: Class methods might be added in the future. None for now. */
|
||||||
|
return super_ctor(typeOf(ap_obj, "h264dprc_class"), ap_obj, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initialization
|
||||||
|
*/
|
||||||
|
|
||||||
|
void * h264d_prc_class_init(void * ap_tos, void * ap_hdl)
|
||||||
|
{
|
||||||
|
void * tizprc = tiz_get_type(ap_hdl, "tizprc");
|
||||||
|
void * h264dprc_class = factory_new
|
||||||
|
/* TIZ_CLASS_COMMENT: class type, class name, parent, size */
|
||||||
|
(classOf(tizprc), "h264dprc_class", classOf(tizprc),
|
||||||
|
sizeof(h264d_prc_class_t),
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
ap_tos, ap_hdl,
|
||||||
|
/* TIZ_CLASS_COMMENT: class constructor */
|
||||||
|
ctor, h264d_prc_class_ctor,
|
||||||
|
/* TIZ_CLASS_COMMENT: stop value*/
|
||||||
|
0);
|
||||||
|
return h264dprc_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * h264d_prc_init(void * ap_tos, void * ap_hdl)
|
||||||
|
{
|
||||||
|
void * tizprc = tiz_get_type(ap_hdl, "tizprc");
|
||||||
|
void * h264dprc_class = tiz_get_type(ap_hdl, "h264dprc_class");
|
||||||
|
TIZ_LOG_CLASS (h264dprc_class);
|
||||||
|
void * h264dprc = factory_new
|
||||||
|
/* TIZ_CLASS_COMMENT: class type, class name, parent, size */
|
||||||
|
(h264dprc_class, "h264dprc", tizprc, sizeof(vid_dec_PrivateType),
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
ap_tos, ap_hdl,
|
||||||
|
/* TIZ_CLASS_COMMENT: class constructor */
|
||||||
|
ctor, h264d_prc_ctor,
|
||||||
|
/* TIZ_CLASS_COMMENT: class destructor */
|
||||||
|
dtor, h264d_prc_dtor,
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
tiz_srv_allocate_resources, h264d_prc_allocate_resources,
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
tiz_srv_deallocate_resources, h264d_prc_deallocate_resources,
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
tiz_srv_prepare_to_transfer, h264d_prc_prepare_to_transfer,
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
tiz_srv_transfer_and_process, h264d_prc_transfer_and_process,
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
tiz_srv_stop_and_return, h264d_prc_stop_and_return,
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
tiz_prc_buffers_ready, h264d_prc_buffers_ready,
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
tiz_prc_port_flush, h264d_prc_port_flush,
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
tiz_prc_port_disable, h264d_prc_port_disable,
|
||||||
|
/* TIZ_CLASS_COMMENT: */
|
||||||
|
tiz_prc_port_enable, h264d_prc_port_enable,
|
||||||
|
/* TIZ_CLASS_COMMENT: stop value*/
|
||||||
|
0);
|
||||||
|
|
||||||
|
return h264dprc;
|
||||||
|
}
|
||||||
31
src/gallium/state_trackers/omx/tizonia/h264dprc.h
Normal file
31
src/gallium/state_trackers/omx/tizonia/h264dprc.h
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef H264DPRC_H
|
||||||
|
#define H264DPRC_H
|
||||||
|
|
||||||
|
void * h264d_prc_class_init(void * ap_tos, void * ap_hdl);
|
||||||
|
void * h264d_prc_init(void * ap_tos, void * ap_hdl);
|
||||||
|
|
||||||
|
#endif /* H264DPRC_H */
|
||||||
30
src/gallium/state_trackers/omx/tizonia/names.h
Normal file
30
src/gallium/state_trackers/omx/tizonia/names.h
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef OMX_TIZ_NAMES_H
|
||||||
|
#define OMX_TIZ_NAMES_H
|
||||||
|
|
||||||
|
#define OMX_VID_COMP_NAME "OMX.mesa.video.all"
|
||||||
|
|
||||||
|
#endif
|
||||||
117
src/gallium/state_trackers/omx/vid_dec_common.c
Normal file
117
src/gallium/state_trackers/omx/vid_dec_common.c
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if ENABLE_ST_OMX_TIZONIA
|
||||||
|
#include <tizkernel.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "util/u_memory.h"
|
||||||
|
#include "vl/vl_winsys.h"
|
||||||
|
#include "vl/vl_video_buffer.h"
|
||||||
|
#include "util/u_surface.h"
|
||||||
|
|
||||||
|
#include "vid_dec_common.h"
|
||||||
|
#include "vid_dec_h264_common.h"
|
||||||
|
|
||||||
|
void vid_dec_NeedTarget(vid_dec_PrivateType *priv)
|
||||||
|
{
|
||||||
|
struct pipe_video_buffer templat = {};
|
||||||
|
struct vl_screen *omx_screen;
|
||||||
|
struct pipe_screen *pscreen;
|
||||||
|
|
||||||
|
omx_screen = priv->screen;
|
||||||
|
assert(omx_screen);
|
||||||
|
|
||||||
|
pscreen = omx_screen->pscreen;
|
||||||
|
assert(pscreen);
|
||||||
|
|
||||||
|
if (!priv->target) {
|
||||||
|
memset(&templat, 0, sizeof(templat));
|
||||||
|
|
||||||
|
templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
|
||||||
|
templat.width = priv->codec->width;
|
||||||
|
templat.height = priv->codec->height;
|
||||||
|
templat.buffer_format = pscreen->get_video_param(
|
||||||
|
pscreen,
|
||||||
|
PIPE_VIDEO_PROFILE_UNKNOWN,
|
||||||
|
PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
||||||
|
PIPE_VIDEO_CAP_PREFERED_FORMAT
|
||||||
|
);
|
||||||
|
templat.interlaced = pscreen->get_video_param(
|
||||||
|
pscreen,
|
||||||
|
PIPE_VIDEO_PROFILE_UNKNOWN,
|
||||||
|
PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
||||||
|
PIPE_VIDEO_CAP_PREFERS_INTERLACED
|
||||||
|
);
|
||||||
|
|
||||||
|
priv->target = priv->pipe->create_video_buffer(priv->pipe, &templat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_dec_FillOutput(vid_dec_PrivateType *priv, struct pipe_video_buffer *buf,
|
||||||
|
OMX_BUFFERHEADERTYPE* output)
|
||||||
|
{
|
||||||
|
#if ENABLE_ST_OMX_TIZONIA
|
||||||
|
tiz_port_t *out_port = tiz_krn_get_port(tiz_get_krn(handleOf(priv)),
|
||||||
|
OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX);
|
||||||
|
OMX_VIDEO_PORTDEFINITIONTYPE *def = &out_port->portdef_.format.video;
|
||||||
|
#else
|
||||||
|
omx_base_PortType *port = priv->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
|
||||||
|
OMX_VIDEO_PORTDEFINITIONTYPE *def = &port->sPortParam.format.video;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct pipe_sampler_view **views;
|
||||||
|
unsigned i, j;
|
||||||
|
unsigned width, height;
|
||||||
|
|
||||||
|
views = buf->get_sampler_view_planes(buf);
|
||||||
|
|
||||||
|
for (i = 0; i < 2 /* NV12 */; i++) {
|
||||||
|
if (!views[i]) continue;
|
||||||
|
width = def->nFrameWidth;
|
||||||
|
height = def->nFrameHeight;
|
||||||
|
vl_video_buffer_adjust_size(&width, &height, i, buf->chroma_format, buf->interlaced);
|
||||||
|
for (j = 0; j < views[i]->texture->array_size; ++j) {
|
||||||
|
struct pipe_box box = {0, 0, j, width, height, 1};
|
||||||
|
struct pipe_transfer *transfer;
|
||||||
|
uint8_t *map, *dst;
|
||||||
|
map = priv->pipe->transfer_map(priv->pipe, views[i]->texture, 0,
|
||||||
|
PIPE_TRANSFER_READ, &box, &transfer);
|
||||||
|
if (!map)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dst = ((uint8_t*)output->pBuffer + output->nOffset) + j * def->nStride +
|
||||||
|
i * def->nFrameWidth * def->nFrameHeight;
|
||||||
|
util_copy_rect(dst,
|
||||||
|
views[i]->texture->format,
|
||||||
|
def->nStride * views[i]->texture->array_size, 0, 0,
|
||||||
|
box.width, box.height, map, transfer->stride, 0, 0);
|
||||||
|
|
||||||
|
pipe_transfer_unmap(priv->pipe, transfer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
194
src/gallium/state_trackers/omx/vid_dec_common.h
Normal file
194
src/gallium/state_trackers/omx/vid_dec_common.h
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef VID_DEC_COMMON_H
|
||||||
|
#define VID_DEC_COMMON_H
|
||||||
|
|
||||||
|
#include "util/list.h"
|
||||||
|
|
||||||
|
#include "vl/vl_compositor.h"
|
||||||
|
#include "vl/vl_rbsp.h"
|
||||||
|
#include "vl/vl_zscan.h"
|
||||||
|
|
||||||
|
#include <OMX_Core.h>
|
||||||
|
#include <OMX_Types.h>
|
||||||
|
|
||||||
|
#if ENABLE_ST_OMX_BELLAGIO
|
||||||
|
|
||||||
|
#include <bellagio/st_static_component_loader.h>
|
||||||
|
#include <bellagio/omx_base_filter.h>
|
||||||
|
#include <bellagio/omx_base_video_port.h>
|
||||||
|
|
||||||
|
DERIVEDCLASS(vid_dec_PrivateType, omx_base_filter_PrivateType)
|
||||||
|
#define vid_dec_PrivateType_FIELDS omx_base_filter_PrivateType_FIELDS \
|
||||||
|
enum pipe_video_profile profile; \
|
||||||
|
struct vl_screen *screen; \
|
||||||
|
struct pipe_context *pipe; \
|
||||||
|
struct pipe_video_codec *codec; \
|
||||||
|
void (*Decode)(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left); \
|
||||||
|
void (*EndFrame)(vid_dec_PrivateType *priv); \
|
||||||
|
struct pipe_video_buffer *(*Flush)(vid_dec_PrivateType *priv, OMX_TICKS *timestamp); \
|
||||||
|
struct pipe_video_buffer *target, *shadow; \
|
||||||
|
union { \
|
||||||
|
struct { \
|
||||||
|
uint8_t intra_matrix[64]; \
|
||||||
|
uint8_t non_intra_matrix[64]; \
|
||||||
|
} mpeg12; \
|
||||||
|
struct { \
|
||||||
|
unsigned nal_ref_idc; \
|
||||||
|
bool IdrPicFlag; \
|
||||||
|
unsigned idr_pic_id; \
|
||||||
|
unsigned pic_order_cnt_lsb; \
|
||||||
|
unsigned pic_order_cnt_msb; \
|
||||||
|
unsigned delta_pic_order_cnt_bottom; \
|
||||||
|
unsigned delta_pic_order_cnt[2]; \
|
||||||
|
unsigned prevFrameNumOffset; \
|
||||||
|
struct pipe_h264_sps sps[32]; \
|
||||||
|
struct pipe_h264_pps pps[256]; \
|
||||||
|
struct list_head dpb_list; \
|
||||||
|
unsigned dpb_num; \
|
||||||
|
} h264; \
|
||||||
|
struct { \
|
||||||
|
unsigned temporal_id; \
|
||||||
|
unsigned level_idc; \
|
||||||
|
unsigned pic_width_in_luma_samples; \
|
||||||
|
unsigned pic_height_in_luma_samples; \
|
||||||
|
bool IdrPicFlag; \
|
||||||
|
int slice_prev_poc; \
|
||||||
|
void *ref_pic_set_list; \
|
||||||
|
void *rps; \
|
||||||
|
struct pipe_h265_sps sps[16]; \
|
||||||
|
struct pipe_h265_pps pps[64]; \
|
||||||
|
struct list_head dpb_list; \
|
||||||
|
unsigned dpb_num; \
|
||||||
|
} h265; \
|
||||||
|
} codec_data; \
|
||||||
|
union { \
|
||||||
|
struct pipe_picture_desc base; \
|
||||||
|
struct pipe_mpeg12_picture_desc mpeg12; \
|
||||||
|
struct pipe_h264_picture_desc h264; \
|
||||||
|
struct pipe_h265_picture_desc h265; \
|
||||||
|
} picture; \
|
||||||
|
unsigned num_in_buffers; \
|
||||||
|
OMX_BUFFERHEADERTYPE *in_buffers[2]; \
|
||||||
|
const void *inputs[2]; \
|
||||||
|
unsigned sizes[2]; \
|
||||||
|
OMX_TICKS timestamps[2]; \
|
||||||
|
OMX_TICKS timestamp; \
|
||||||
|
bool first_buf_in_frame; \
|
||||||
|
bool frame_finished; \
|
||||||
|
bool frame_started; \
|
||||||
|
unsigned bytes_left; \
|
||||||
|
const void *slice; \
|
||||||
|
bool disable_tunnel; \
|
||||||
|
struct vl_compositor compositor; \
|
||||||
|
struct vl_compositor_state cstate;
|
||||||
|
ENDCLASS(vid_dec_PrivateType)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <tizprc_decls.h>
|
||||||
|
#include <tizport_decls.h>
|
||||||
|
|
||||||
|
#include "util/list.h"
|
||||||
|
|
||||||
|
#include "pipe/p_video_state.h"
|
||||||
|
|
||||||
|
typedef struct h264d_prc_class h264d_prc_class_t;
|
||||||
|
struct h264d_prc_class
|
||||||
|
{
|
||||||
|
/* Class */
|
||||||
|
const tiz_prc_class_t _;
|
||||||
|
/* NOTE: Class methods might be added in the future */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct h264d_stream_info h264d_stream_info_t;
|
||||||
|
struct h264d_stream_info
|
||||||
|
{
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct h264d_prc vid_dec_PrivateType;
|
||||||
|
struct h264d_prc
|
||||||
|
{
|
||||||
|
/* Object */
|
||||||
|
const tiz_prc_t _;
|
||||||
|
OMX_BUFFERHEADERTYPE *in_buffers[2];
|
||||||
|
OMX_BUFFERHEADERTYPE *p_inhdr_;
|
||||||
|
OMX_BUFFERHEADERTYPE *p_outhdr_;
|
||||||
|
OMX_PARAM_PORTDEFINITIONTYPE out_port_def_;
|
||||||
|
const void *inputs[2];
|
||||||
|
unsigned sizes[2];
|
||||||
|
OMX_TICKS timestamps[2];
|
||||||
|
OMX_TICKS timestamp;
|
||||||
|
bool eos_;
|
||||||
|
bool in_port_disabled_;
|
||||||
|
bool out_port_disabled_;
|
||||||
|
struct vl_screen *screen;
|
||||||
|
struct pipe_context *pipe;
|
||||||
|
struct pipe_video_codec *codec;
|
||||||
|
struct pipe_video_buffer *target;
|
||||||
|
enum pipe_video_profile profile;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned nal_ref_idc;
|
||||||
|
bool IdrPicFlag;
|
||||||
|
unsigned idr_pic_id;
|
||||||
|
unsigned pic_order_cnt_lsb;
|
||||||
|
unsigned pic_order_cnt_msb;
|
||||||
|
unsigned delta_pic_order_cnt_bottom;
|
||||||
|
unsigned delta_pic_order_cnt[2];
|
||||||
|
unsigned prevFrameNumOffset;
|
||||||
|
struct pipe_h264_sps sps[32];
|
||||||
|
struct pipe_h264_pps pps[256];
|
||||||
|
struct list_head dpb_list;
|
||||||
|
unsigned dpb_num;
|
||||||
|
} h264;
|
||||||
|
} codec_data;
|
||||||
|
union {
|
||||||
|
struct pipe_picture_desc base;
|
||||||
|
struct pipe_h264_picture_desc h264;
|
||||||
|
} picture;
|
||||||
|
h264d_stream_info_t stream_info;
|
||||||
|
unsigned num_in_buffers;
|
||||||
|
bool first_buf_in_frame;
|
||||||
|
bool frame_finished;
|
||||||
|
bool frame_started;
|
||||||
|
unsigned bytes_left;
|
||||||
|
const void *slice;
|
||||||
|
bool disable_tunnel;
|
||||||
|
struct vl_compositor compositor;
|
||||||
|
struct vl_compositor_state cstate;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void vid_dec_NeedTarget(vid_dec_PrivateType* priv);
|
||||||
|
void vid_dec_FillOutput(vid_dec_PrivateType* priv, struct pipe_video_buffer* buf,
|
||||||
|
OMX_BUFFERHEADERTYPE* output);
|
||||||
|
#endif
|
||||||
1138
src/gallium/state_trackers/omx/vid_dec_h264_common.c
Normal file
1138
src/gallium/state_trackers/omx/vid_dec_h264_common.c
Normal file
File diff suppressed because it is too large
Load diff
99
src/gallium/state_trackers/omx/vid_dec_h264_common.h
Normal file
99
src/gallium/state_trackers/omx/vid_dec_h264_common.h
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef VID_DEC_H264_COMMON_H
|
||||||
|
#define VID_DEC_H264_COMMON_H
|
||||||
|
|
||||||
|
#include "vid_dec_common.h"
|
||||||
|
|
||||||
|
#define OMX_VID_DEC_AVC_DEFAULT_FRAME_WIDTH 176
|
||||||
|
#define OMX_VID_DEC_AVC_DEFAULT_FRAME_HEIGHT 144
|
||||||
|
#define OMX_VID_DEC_AVC_DEFAULT_FRAME_RATE 15<<16
|
||||||
|
#define OMX_VID_DEC_AVC_ROLE "video_decoder.avc"
|
||||||
|
/* With libtizonia, port indexes must start at index 0 */
|
||||||
|
#define OMX_VID_DEC_AVC_INPUT_PORT_INDEX 0
|
||||||
|
#define OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX 1
|
||||||
|
#define OMX_VID_DEC_AVC_INPUT_PORT_MIN_BUF_COUNT 8
|
||||||
|
#define OMX_VID_DEC_AVC_OUTPUT_PORT_MIN_BUF_COUNT 4
|
||||||
|
/* 38016 = (width * height) + ((width * height)/2) */
|
||||||
|
#define OMX_VID_DEC_AVC_PORT_MIN_INPUT_BUF_SIZE 38016
|
||||||
|
#define OMX_VID_DEC_AVC_PORT_MIN_OUTPUT_BUF_SIZE 345600
|
||||||
|
#define OMX_VID_DEC_AVC_PORT_NONCONTIGUOUS OMX_FALSE
|
||||||
|
#define OMX_VID_DEC_AVC_PORT_ALIGNMENT 0
|
||||||
|
#define OMX_VID_DEC_AVC_PORT_SUPPLIERPREF OMX_BufferSupplyInput
|
||||||
|
#define OMX_VID_DEC_AVC_TIMESTAMP_INVALID ((OMX_TICKS) -1)
|
||||||
|
|
||||||
|
#define DPB_MAX_SIZE 5
|
||||||
|
|
||||||
|
struct dpb_list {
|
||||||
|
struct list_head list;
|
||||||
|
struct pipe_video_buffer *buffer;
|
||||||
|
OMX_TICKS timestamp;
|
||||||
|
int poc;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t Default_4x4_Intra[16] = {
|
||||||
|
6, 13, 20, 28, 13, 20, 28, 32,
|
||||||
|
20, 28, 32, 37, 28, 32, 37, 42
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t Default_4x4_Inter[16] = {
|
||||||
|
10, 14, 20, 24, 14, 20, 24, 27,
|
||||||
|
20, 24, 27, 30, 24, 27, 30, 34
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t Default_8x8_Intra[64] = {
|
||||||
|
6, 10, 13, 16, 18, 23, 25, 27,
|
||||||
|
10, 11, 16, 18, 23, 25, 27, 29,
|
||||||
|
13, 16, 18, 23, 25, 27, 29, 31,
|
||||||
|
16, 18, 23, 25, 27, 29, 31, 33,
|
||||||
|
18, 23, 25, 27, 29, 31, 33, 36,
|
||||||
|
23, 25, 27, 29, 31, 33, 36, 38,
|
||||||
|
25, 27, 29, 31, 33, 36, 38, 40,
|
||||||
|
27, 29, 31, 33, 36, 38, 40, 42
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t Default_8x8_Inter[64] = {
|
||||||
|
9, 13, 15, 17, 19, 21, 22, 24,
|
||||||
|
13, 13, 17, 19, 21, 22, 24, 25,
|
||||||
|
15, 17, 19, 21, 22, 24, 25, 27,
|
||||||
|
17, 19, 21, 22, 24, 25, 27, 28,
|
||||||
|
19, 21, 22, 24, 25, 27, 28, 30,
|
||||||
|
21, 22, 24, 25, 27, 28, 30, 32,
|
||||||
|
22, 24, 25, 27, 28, 30, 32, 33,
|
||||||
|
24, 25, 27, 28, 30, 32, 33, 35
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv,
|
||||||
|
OMX_TICKS *timestamp);
|
||||||
|
void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv);
|
||||||
|
void vid_dec_h264_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left);
|
||||||
|
void vid_dec_FreeInputPortPrivate(OMX_BUFFERHEADERTYPE *buf);
|
||||||
|
void vid_dec_FrameDecoded_common(vid_dec_PrivateType*priv, OMX_BUFFERHEADERTYPE* input,
|
||||||
|
OMX_BUFFERHEADERTYPE* output);
|
||||||
|
|
||||||
|
#endif
|
||||||
111
src/gallium/state_trackers/omx/vid_omx_common.c
Normal file
111
src/gallium/state_trackers/omx/vid_omx_common.c
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_X11_PLATFORM)
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#else
|
||||||
|
#define XOpenDisplay(x) NULL
|
||||||
|
#define XCloseDisplay(x)
|
||||||
|
#define Display void
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "os/os_thread.h"
|
||||||
|
#include "util/u_memory.h"
|
||||||
|
#include "loader/loader.h"
|
||||||
|
|
||||||
|
#include "vid_omx_common.h"
|
||||||
|
|
||||||
|
static mtx_t omx_lock = _MTX_INITIALIZER_NP;
|
||||||
|
static Display *omx_display = NULL;
|
||||||
|
static struct vl_screen *omx_screen = NULL;
|
||||||
|
static unsigned omx_usecount = 0;
|
||||||
|
static const char *omx_render_node = NULL;
|
||||||
|
static int drm_fd;
|
||||||
|
|
||||||
|
struct vl_screen *omx_get_screen(void)
|
||||||
|
{
|
||||||
|
static bool first_time = true;
|
||||||
|
mtx_lock(&omx_lock);
|
||||||
|
|
||||||
|
if (!omx_screen) {
|
||||||
|
if (first_time) {
|
||||||
|
omx_render_node = debug_get_option("OMX_RENDER_NODE", NULL);
|
||||||
|
first_time = false;
|
||||||
|
}
|
||||||
|
if (omx_render_node) {
|
||||||
|
drm_fd = loader_open_device(omx_render_node);
|
||||||
|
if (drm_fd < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
omx_screen = vl_drm_screen_create(drm_fd);
|
||||||
|
if (!omx_screen) {
|
||||||
|
close(drm_fd);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
omx_display = XOpenDisplay(NULL);
|
||||||
|
if (!omx_display)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
omx_screen = vl_dri3_screen_create(omx_display, 0);
|
||||||
|
if (!omx_screen)
|
||||||
|
omx_screen = vl_dri2_screen_create(omx_display, 0);
|
||||||
|
if (!omx_screen) {
|
||||||
|
XCloseDisplay(omx_display);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++omx_usecount;
|
||||||
|
|
||||||
|
mtx_unlock(&omx_lock);
|
||||||
|
return omx_screen;
|
||||||
|
|
||||||
|
error:
|
||||||
|
mtx_unlock(&omx_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void omx_put_screen(void)
|
||||||
|
{
|
||||||
|
mtx_lock(&omx_lock);
|
||||||
|
if ((--omx_usecount) == 0) {
|
||||||
|
omx_screen->destroy(omx_screen);
|
||||||
|
omx_screen = NULL;
|
||||||
|
|
||||||
|
if (omx_render_node)
|
||||||
|
close(drm_fd);
|
||||||
|
else
|
||||||
|
XCloseDisplay(omx_display);
|
||||||
|
}
|
||||||
|
mtx_unlock(&omx_lock);
|
||||||
|
}
|
||||||
36
src/gallium/state_trackers/omx/vid_omx_common.h
Normal file
36
src/gallium/state_trackers/omx/vid_omx_common.h
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef VID_OMX_COMMON_H
|
||||||
|
#define VID_OMX_COMMON_H
|
||||||
|
|
||||||
|
#include "vl/vl_winsys.h"
|
||||||
|
|
||||||
|
struct vl_screen *omx_get_screen(void);
|
||||||
|
void omx_put_screen(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Reference in a new issue