From 146aa1230f104fda249596ab1cfd14a7335b43cf Mon Sep 17 00:00:00 2001 From: SeokYeon Hwang Date: Fri, 5 Sep 2014 19:09:05 +0900 Subject: [PATCH] brillcodec: clean-up decode video data handling logic Change-Id: I90a341c9e306797c3c44570a8cdee72ab4e4e559 Signed-off-by: SeokYeon Hwang --- tizen/src/hw/pci/maru_brillcodec.c | 198 +++++++++--------------------- tizen/src/hw/pci/maru_brillcodec_plugin.h | 38 +++++- tizen/src/hw/pci/maru_brillcodec_vaapi.c | 56 +++------ tizen/src/hw/pci/maru_dxva2_plugin.c | 34 ++--- 4 files changed, 123 insertions(+), 203 deletions(-) diff --git a/tizen/src/hw/pci/maru_brillcodec.c b/tizen/src/hw/pci/maru_brillcodec.c index 6c58830..aa3daa1 100644 --- a/tizen/src/hw/pci/maru_brillcodec.c +++ b/tizen/src/hw/pci/maru_brillcodec.c @@ -72,18 +72,6 @@ enum codec_type { CODEC_TYPE_ENCODE, }; -struct video_data { - int32_t width; - int32_t height; - int32_t fps_n; - int32_t fps_d; - int32_t par_n; - int32_t par_d; - int32_t pix_fmt; - int32_t bpp; - int32_t ticks_per_frame; -}; - struct audio_data { int32_t channels; int32_t sample_rate; @@ -160,27 +148,58 @@ static DataHandler default_data_handler = { .release = default_release, }; +static void default_get_picture(void *dst, void *src, enum AVPixelFormat pix_fmt) +{ + AVFrame *frame = (AVFrame *)src; + int pict_size = avpicture_get_size(pix_fmt, frame->width, frame->height); + if (pict_size < 0) { + // cannot enter here... + ERR("Invalid picture size\n"); + return; + } + avpicture_layout((AVPicture *)frame, pix_fmt, + frame->width, frame->height, dst, pict_size); +} + // default video decode data handler -static void copy_picture(void *dst, void *opaque, size_t size) +// FIXME: ignore "size" now... +static void copy_picture(void *dst, void *opaque, size_t dummy) { + size_t size = sizeof(int32_t), offset = 0; DataContainer *dc = (DataContainer *)opaque; + CodecContext *context = (CodecContext *)dc->avctx->opaque; + + if (dc->picture_buffer_offset) { + // FIXME: if video data is exist... + *((int32_t *)dst) = dc->len; + offset += size; + *((int32_t *)(dst + offset)) = dc->got_picture; + offset += size; + + struct video_data *data = (struct video_data *)(dst + offset); + fill_video_data(dc->avctx, data); - if (dc->len_data_buffer) { - memcpy(dst, dc->data_buffer, dc->len_data_buffer); + if (context->is_hwaccel) { + data->pix_fmt = context->state->hwaccel_plugin->output_pix_fmt; + } } + if (dc->frame) { - avpicture_layout((AVPicture *)dc->frame, dc->pix_fmt, dc->frame->width, dc->frame->height, - dst + dc->picture_buffer_offset, size - dc->picture_buffer_offset); // FIXME + // FIXME: if picture is exist... + if (context->is_hwaccel) { + context->state->hwaccel_plugin->get_picture(dst + dc->picture_buffer_offset, dc->frame); + } else { + default_get_picture(dst + dc->picture_buffer_offset, dc->frame, dc->avctx->pix_fmt); + } } } static void release(void *opaque) { DataContainer *dc = (DataContainer *)opaque; - g_free(dc->data_buffer); g_free(dc); } -static DataHandler default_video_decode_data_handler = { +static DataHandler video_decode_data_handler = { .get_data = copy_picture, .release = release, }; @@ -515,22 +534,6 @@ static void serialize_video_data(const struct video_data *video, avctx->sample_aspect_ratio.den, avctx->bits_per_coded_sample); } -static void deserialize_video_data (const AVCodecContext *avctx, - struct video_data *video) -{ - memset(video, 0x00, sizeof(struct video_data)); - - video->width = avctx->width; - video->height = avctx->height; - video->fps_n = avctx->time_base.num; - video->fps_d = avctx->time_base.den; - video->pix_fmt = avctx->pix_fmt; - video->par_n = avctx->sample_aspect_ratio.num; - video->par_d = avctx->sample_aspect_ratio.den; - video->bpp = avctx->bits_per_coded_sample; - video->ticks_per_frame = avctx->ticks_per_frame; -} - static void serialize_audio_data (const struct audio_data *audio, AVCodecContext *avctx) { @@ -967,9 +970,9 @@ static uint8_t *resample_audio_buffer(AVCodecContext * avctx, AVFrame *samples, return resampled_audio; } -static int parse_and_decode_video(AVCodecContext *avctx, AVFrame *picture, +static uint32_t parse_and_decode_video(AVCodecContext *avctx, AVFrame *picture, AVCodecParserContext *pctx, int ctx_id, - AVPacket *packet, int *got_picture, + AVPacket *packet, uint32_t *got_picture, int idx, int64_t in_offset) { uint8_t *parser_outbuf = NULL; @@ -1015,7 +1018,7 @@ static int parse_and_decode_video(AVCodecContext *avctx, AVFrame *picture, TRACE("not using parser %s\n", avctx->codec->name); } - len = avcodec_decode_video2(avctx, picture, got_picture, packet); + len = avcodec_decode_video2(avctx, picture, (int *)got_picture, packet); TRACE("decode_video. len %d, got_picture %d\n", len, *got_picture); if (!pctx) { @@ -1242,13 +1245,11 @@ static bool codec_decode_video2(MaruBrillCodecState *s, int ctx_id, void *data_b AVCodecParserContext *pctx = NULL; AVPacket avpkt; - int got_picture = 0, len = -1; + uint32_t got_picture = 0, len = -1; uint8_t *inbuf = NULL; int inbuf_size = 0, idx = 0, size = 0; int64_t in_offset = 0; DeviceMemEntry *elem = NULL; - uint8_t *tempbuf = NULL; - int tempbuf_size = 0; TRACE("enter: %s\n", __func__); @@ -1293,59 +1294,20 @@ static bool codec_decode_video2(MaruBrillCodecState *s, int ctx_id, void *data_b &avpkt, &got_picture, idx, in_offset); } - tempbuf_size = sizeof(len) + sizeof(got_picture) + sizeof(struct video_data); - - tempbuf = g_malloc(tempbuf_size); - if (!tempbuf) { - ERR("failed to allocate decoded video buffer\n"); - // FIXME: how to handle this case? - } else { - struct video_data video; - - memcpy(tempbuf, &len, sizeof(len)); - size = sizeof(len); - memcpy(tempbuf + size, &got_picture, sizeof(got_picture)); - size += sizeof(got_picture); - if (avctx) { - deserialize_video_data(avctx, &video); - memcpy(tempbuf + size, &video, sizeof(struct video_data)); - } - } - - TRACE("decoded image. len: %d got_picture: %d pix_fmt: %d width: %d, height: %d\n", - len, got_picture, avctx->pix_fmt, avctx->width, avctx->height); - - int pict_size = 0; - bool ret = true; - DataContainer *dc = g_malloc0(sizeof(DataContainer)); - dc->data_buffer = tempbuf; - dc->len_data_buffer = tempbuf_size; dc->picture_buffer_offset = OFFSET_PICTURE_BUFFER; - - if (got_picture) { - pict_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); - - if ((pict_size) < 0) { - ERR("picture size: %d\n", pict_size); - ret = false; - } else { - TRACE("picture size: %d\n", pict_size); - - dc->frame = picture; - dc->pix_fmt = avctx->pix_fmt; - } + dc->len = len; + dc->got_picture = got_picture; + dc->avctx = avctx; + if(got_picture) { + dc->frame = picture; } - if (CONTEXT(s, ctx_id)->is_hwaccel) { - brillcodec_push_write_queue(s, dc, dc->picture_buffer_offset + pict_size, ctx_id, s->hwaccel_plugin->video_decode_data_handler); - } else { - brillcodec_push_write_queue(s, dc, dc->picture_buffer_offset + pict_size, ctx_id, &default_video_decode_data_handler); - } + brillcodec_push_write_queue(s, dc, 0, ctx_id, &video_decode_data_handler); TRACE("leave: %s\n", __func__); - return ret; + return true; } static bool codec_decode_video(MaruBrillCodecState *s, int ctx_id, void *data_buf) @@ -1355,13 +1317,11 @@ static bool codec_decode_video(MaruBrillCodecState *s, int ctx_id, void *data_bu AVCodecParserContext *pctx = NULL; AVPacket avpkt; - int got_picture = 0, len = -1; + uint32_t got_picture = 0, len = -1; uint8_t *inbuf = NULL; int inbuf_size = 0, idx = 0, size = 0; int64_t in_offset = 0; DeviceMemEntry *elem = NULL; - uint8_t *tempbuf = NULL; - int tempbuf_size = 0; TRACE("enter: %s\n", __func__); @@ -1406,26 +1366,13 @@ static bool codec_decode_video(MaruBrillCodecState *s, int ctx_id, void *data_bu &avpkt, &got_picture, idx, in_offset); } - tempbuf_size = sizeof(len) + sizeof(got_picture) + sizeof(struct video_data); - - tempbuf = g_malloc(tempbuf_size); - if (!tempbuf) { - ERR("failed to allocate decoded audio buffer\n"); - tempbuf_size = 0; - } else { - struct video_data video; - - memcpy(tempbuf, &len, sizeof(len)); - size = sizeof(len); - memcpy(tempbuf + size, &got_picture, sizeof(got_picture)); - size += sizeof(got_picture); - if (avctx) { - deserialize_video_data(avctx, &video); - memcpy(tempbuf + size, &video, sizeof(struct video_data)); - } - } + DataContainer *dc = g_malloc0(sizeof(DataContainer)); + dc->picture_buffer_offset = OFFSET_PICTURE_BUFFER; + dc->len = len; + dc->got_picture = got_picture; + dc->avctx = avctx; - brillcodec_push_write_queue(s, tempbuf, tempbuf_size, ctx_id, NULL); + brillcodec_push_write_queue(s, dc, 0, ctx_id, &video_decode_data_handler); TRACE("leave: %s\n", __func__); @@ -1437,7 +1384,6 @@ static bool codec_picture_copy (MaruBrillCodecState *s, int ctx_id, void *elem) { AVCodecContext *avctx = NULL; AVFrame *frame = NULL; - int pict_size = 0; bool ret = true; TRACE("enter: %s\n", __func__); @@ -1446,37 +1392,13 @@ static bool codec_picture_copy (MaruBrillCodecState *s, int ctx_id, void *elem) avctx = CONTEXT(s, ctx_id)->avctx; frame = CONTEXT(s, ctx_id)->frame; - if (!avctx) { - ERR("picture_copy. %d of AVCodecContext is NULL.\n", ctx_id); - ret = false; - } else if (!avctx->codec) { - ERR("picture_copy. %d of AVCodec is NULL.\n", ctx_id); - ret = false; - } else if (!frame) { - ERR("picture_copy. %d of AVFrame is NULL.\n", ctx_id); - ret = false; - } else { - TRACE("decoded image. pix_fmt: %d width: %d, height: %d\n", - avctx->pix_fmt, avctx->width, avctx->height); - pict_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); - if ((pict_size) < 0) { - ERR("picture size: %d\n", pict_size); - ret = false; - } else { - TRACE("picture size: %d\n", pict_size); + DataContainer *dc = g_malloc0(sizeof(DataContainer)); - DataContainer *dc = g_malloc0(sizeof(DataContainer)); - dc->frame = frame; - dc->pix_fmt = avctx->pix_fmt; + dc->frame = frame; + dc->avctx = avctx; - if (CONTEXT(s, ctx_id)->is_hwaccel) { - brillcodec_push_write_queue(s, dc, pict_size, ctx_id, s->hwaccel_plugin->video_decode_data_handler); - } else { - brillcodec_push_write_queue(s, dc, pict_size, ctx_id, &default_video_decode_data_handler); - } - } - } + brillcodec_push_write_queue(s, dc, 0, ctx_id, &video_decode_data_handler); TRACE("leave: %s\n", __func__); diff --git a/tizen/src/hw/pci/maru_brillcodec_plugin.h b/tizen/src/hw/pci/maru_brillcodec_plugin.h index dc6c2cd..889a328 100644 --- a/tizen/src/hw/pci/maru_brillcodec_plugin.h +++ b/tizen/src/hw/pci/maru_brillcodec_plugin.h @@ -36,12 +36,11 @@ #define OFFSET_PICTURE_BUFFER (0x100) typedef struct DataContainer { - void *data_buffer; - size_t len_data_buffer; size_t picture_buffer_offset; - + uint32_t len; + uint32_t got_picture; + AVCodecContext *avctx; AVFrame *frame; - enum AVPixelFormat pix_fmt; } DataContainer; typedef struct DataHandler { @@ -51,10 +50,39 @@ typedef struct DataHandler { typedef struct CodecPlugin { enum PixelFormat pix_fmt; + enum PixelFormat output_pix_fmt; bool (*setup)(AVCodecContext *, int , int); int (*get_buffer)(struct AVCodecContext *, AVFrame *); void (*release_buffer)(struct AVCodecContext *, AVFrame *); - DataHandler *video_decode_data_handler; + void (*get_picture)(void *dst, void *src); } CodecPlugin; +struct video_data { + int32_t width; + int32_t height; + int32_t fps_n; + int32_t fps_d; + int32_t par_n; + int32_t par_d; + int32_t pix_fmt; + int32_t bpp; + int32_t ticks_per_frame; +}; + +static inline void fill_video_data(const AVCodecContext *avctx, + struct video_data *video) +{ + memset(video, 0x00, sizeof(struct video_data)); + + video->width = avctx->width; + video->height = avctx->height; + video->fps_n = avctx->time_base.num; + video->fps_d = avctx->time_base.den; + video->pix_fmt = avctx->pix_fmt; + video->par_n = avctx->sample_aspect_ratio.num; + video->par_d = avctx->sample_aspect_ratio.den; + video->bpp = avctx->bits_per_coded_sample; + video->ticks_per_frame = avctx->ticks_per_frame; +} + #endif //__MARU_BRILLCODEC_PLUGIN_H__ diff --git a/tizen/src/hw/pci/maru_brillcodec_vaapi.c b/tizen/src/hw/pci/maru_brillcodec_vaapi.c index 704607a..b34afa0 100644 --- a/tizen/src/hw/pci/maru_brillcodec_vaapi.c +++ b/tizen/src/hw/pci/maru_brillcodec_vaapi.c @@ -43,7 +43,7 @@ #include "maru_brillcodec_plugin.h" -#define SURFACE_COUNT 20 +#define SURFACE_COUNT 4 #define PROFILE VAProfileH264High #ifndef VA_SURFACE_ATTRIB_SETTABLE @@ -206,9 +206,10 @@ static void copy_yv12(uint8_t *dst[3], src[1], src_pitch[1], width / 2, height / 2); } -static int extract(AVFrame *src, void* dst, size_t size) +static void extract(void* dst, void *src) { - VASurfaceID surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + AVFrame *frame = (AVFrame *)src; + VASurfaceID surface_id = (VASurfaceID)(uintptr_t)frame->data[3]; #if VA_CHECK_VERSION(0,31,0) if (vaSyncSurface(va_display, surface_id)) @@ -216,24 +217,24 @@ static int extract(AVFrame *src, void* dst, size_t size) #error #endif { - return -1; + return; } if (va_ctx->is_supports_derive) { if (vaDeriveImage(va_display, surface_id, &va_ctx->image) != VA_STATUS_SUCCESS) { - return -1; + return; } } else { if (vaGetImage(va_display, surface_id, - 0, 0, src->width, src->height, + 0, 0, frame->width, frame->height, va_ctx->image.image_id)) { - return -1; + return; } } void *p_base; if (vaMapBuffer(va_display, va_ctx->image.buf, &p_base)) { - return -1; + return; } const uint32_t fourcc = va_ctx->image.format.fourcc; @@ -248,18 +249,19 @@ static int extract(AVFrame *src, void* dst, size_t size) pitch[i] = va_ctx->image.pitches[i]; } uint8_t *data[4]; - av_image_fill_pointers(data, PIX_FMT_YUV420P, src->height, dst, (const int *)pitch); - copy_yv12(data, plane, pitch, src->width, src->height); + av_image_fill_pointers(data, PIX_FMT_YUV420P, frame->height, dst, (const int *)pitch); + copy_yv12(data, plane, pitch, frame->width, frame->height); #else // for performance testing... U, V plane order is reversed - memcpy(dst, p_base + va_ctx->image.offsets[0], size); + size_t pict_size = avpicture_get_size(PIX_FMT_YUV420P, frame->width, frame->height); + memcpy(dst, p_base + va_ctx->image.offsets[0], pict_size); #endif } else { - return -1; + return; } if (vaUnmapBuffer(va_display, va_ctx->image.buf)) { - return -1; + return; } if (va_ctx->is_supports_derive) @@ -268,7 +270,7 @@ static int extract(AVFrame *src, void* dst, size_t size) va_ctx->image.image_id = VA_INVALID_ID; } - return 0; + return; } static int get_surface(AVCodecContext *p_context, @@ -303,33 +305,11 @@ static void release_surface(AVCodecContext *p_context, *((bool *)frame->opaque) = false; } -static void vaapi_extract(void *dst, void *opaque, size_t size) -{ - DataContainer *dc = (DataContainer *)opaque; - if (dc->len_data_buffer) { - memcpy(dst, dc->data_buffer, dc->len_data_buffer); - } - if (dc->frame) { - extract(dc->frame, dst + dc->picture_buffer_offset, size - dc->picture_buffer_offset); - } -} - -static void release(void *opaque) -{ - DataContainer *dc = (DataContainer *)opaque; - g_free(dc->data_buffer); - g_free(dc); -} - -static DataHandler vaapi_video_decode_data_handler = { - .get_data = vaapi_extract, - .release = release, -}; - CodecPlugin vaapi_plugin = { .pix_fmt = PIX_FMT_VAAPI_VLD, + .output_pix_fmt = PIX_FMT_YUV420P, .setup = setup, .get_buffer = get_surface, .release_buffer = release_surface, - .video_decode_data_handler = &vaapi_video_decode_data_handler, + .get_picture = extract, }; diff --git a/tizen/src/hw/pci/maru_dxva2_plugin.c b/tizen/src/hw/pci/maru_dxva2_plugin.c index 4cc938a..3fdbd6a 100644 --- a/tizen/src/hw/pci/maru_dxva2_plugin.c +++ b/tizen/src/hw/pci/maru_dxva2_plugin.c @@ -922,9 +922,10 @@ static void dxva_release_surface(AVCodecContext *dec_ctx, AVFrame *frame) surface->is_occupied = false; } -static int extract(AVFrame *src, void *dst, size_t size) +static void extract(void *dst, void *src) { - LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)src->data[3]; + AVFrame *frame = (AVFrame *)src; + LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)frame->data[3]; /* */ assert(dxva_ctx->output == MAKEFOURCC('Y','V','1','2')); @@ -933,7 +934,7 @@ static int extract(AVFrame *src, void *dst, size_t size) D3DLOCKED_RECT lock; if (FAILED(IDirect3DSurface9_LockRect(d3d, &lock, NULL, D3DLOCK_READONLY))) { ERR("Failed to lock surface\n"); - return -1; + return; } if (dxva_ctx->render_fmt == MAKEFOURCC('Y','V','1','2') || @@ -961,8 +962,8 @@ static int extract(AVFrame *src, void *dst, size_t size) } uint8_t *data[4]; - av_image_fill_pointers(data, PIX_FMT_YUV420P, src->height, dst, (const int *)pitch); - copy_yv12(data, pitch, plane, pitch, src->width, src->height); + av_image_fill_pointers(data, PIX_FMT_YUV420P, frame->height, dst, (const int *)pitch); + copy_yv12(data, pitch, plane, pitch, frame->width, frame->height); } else if (dxva_ctx->render_fmt == MAKEFOURCC('N','V','1','2')) { uint8_t *plane[2] = { lock.pBits, @@ -975,35 +976,24 @@ static int extract(AVFrame *src, void *dst, size_t size) uint8_t *data[4]; int linesizes[4]; - av_image_fill_linesizes(linesizes, AV_PIX_FMT_YUV420P, src->width); - av_image_fill_pointers(data, PIX_FMT_YUV420P, src->height, dst, linesizes); - copy_nv12(data, linesizes, plane, pitch, src->width, src->height); + av_image_fill_linesizes(linesizes, AV_PIX_FMT_YUV420P, frame->width); + av_image_fill_pointers(data, PIX_FMT_YUV420P, frame->height, dst, linesizes); + copy_nv12(data, linesizes, plane, pitch, frame->width, frame->height); } else { ERR("Not supported format.(%x)\n", dxva_ctx->render_fmt); IDirect3DSurface9_UnlockRect(d3d); - return -1; + return; } /* */ IDirect3DSurface9_UnlockRect(d3d); - return 0; -} - -static void dxva_extract(void *dst, void *src, size_t size) { - extract((AVFrame *)src, dst, size); } -static void dxva_release(void *buf) {} - -static DataHandler dxva_video_decode_data_handler = { - .get_data = dxva_extract, - .release = dxva_release, -}; - CodecPlugin dxva_plugin = { .pix_fmt = PIX_FMT_DXVA2_VLD, + .output_pix_fmt = PIX_FMT_YUV420P, .setup = dxva_setup, .get_buffer = dxva_get_surface, .release_buffer = dxva_release_surface, - .video_decode_data_handler = &dxva_video_decode_data_handler, + .get_picture = extract, }; -- 2.7.4