提交 d142d540 编写于 作者: Z Zhang Rui

ijksdl/vout: Lazily allocate frame buffer in opaque_obtain_managed_frame_buffer

For refererenced frame management, we use buffer allocated by decoder
上级 1afbb144
...@@ -48,32 +48,55 @@ typedef struct SDL_VoutOverlay_Opaque { ...@@ -48,32 +48,55 @@ typedef struct SDL_VoutOverlay_Opaque {
/* Always assume a linesize alignment of 1 here */ /* Always assume a linesize alignment of 1 here */
// TODO: 9 alignment to speed up memcpy when display // TODO: 9 alignment to speed up memcpy when display
static AVFrame *alloc_avframe(SDL_VoutOverlay_Opaque* opaque, enum AVPixelFormat format, int width, int height) static AVFrame *opaque_setup_frame(SDL_VoutOverlay_Opaque* opaque, enum AVPixelFormat format, int width, int height)
{ {
int frame_bytes = avpicture_get_size(format, width, height); AVFrame *managed_frame = av_frame_alloc();
AVBufferRef *frame_buffer_ref = av_buffer_alloc(frame_bytes); if (!managed_frame) {
if (!frame_buffer_ref)
return NULL;
AVFrame *frame = av_frame_alloc();
if (!frame) {
av_buffer_unref(&frame_buffer_ref);
return NULL; return NULL;
} }
AVFrame *linked_frame = av_frame_alloc(); AVFrame *linked_frame = av_frame_alloc();
if (!frame) { if (!linked_frame) {
av_frame_free(&frame); av_frame_free(&managed_frame);
av_buffer_unref(&frame_buffer_ref);
return NULL; return NULL;
} }
AVPicture *pic = (AVPicture *) frame; /*-
avcodec_get_frame_defaults(frame); * Lazily allocate frame buffer in opaque_obtain_managed_frame_buffer
avpicture_fill(pic, frame_buffer_ref->data, format, width, height); *
* For refererenced frame management, we use buffer allocated by decoder
*
int frame_bytes = avpicture_get_size(format, width, height);
AVBufferRef *frame_buffer_ref = av_buffer_alloc(frame_bytes);
if (!frame_buffer_ref)
return NULL;
opaque->frame_buffer = frame_buffer_ref; opaque->frame_buffer = frame_buffer_ref;
*/
avcodec_get_frame_defaults(managed_frame);
avcodec_get_frame_defaults(linked_frame);
AVPicture *pic = (AVPicture *) managed_frame;
avpicture_fill(pic, NULL, format, width, height);
opaque->managed_frame = managed_frame;
opaque->linked_frame = linked_frame; opaque->linked_frame = linked_frame;
return frame; return managed_frame;
}
static AVFrame *opaque_obtain_managed_frame_buffer(SDL_VoutOverlay_Opaque* opaque)
{
if (opaque->frame_buffer != NULL)
return opaque->managed_frame;
AVFrame *managed_frame = opaque->managed_frame;
int frame_bytes = avpicture_get_size(managed_frame->format, managed_frame->width, managed_frame->height);
AVBufferRef *frame_buffer_ref = av_buffer_alloc(frame_bytes);
if (!frame_buffer_ref)
return NULL;
AVPicture *pic = (AVPicture *) managed_frame;
avpicture_fill(pic, frame_buffer_ref->data, managed_frame->format, managed_frame->width, managed_frame->height);
opaque->frame_buffer = frame_buffer_ref;
return opaque->managed_frame;
} }
static void overlay_free_l(SDL_VoutOverlay *overlay) static void overlay_free_l(SDL_VoutOverlay *overlay)
...@@ -195,7 +218,7 @@ SDL_VoutOverlay *SDL_VoutFFmpeg_CreateOverlay(int width, int height, Uint32 form ...@@ -195,7 +218,7 @@ SDL_VoutOverlay *SDL_VoutFFmpeg_CreateOverlay(int width, int height, Uint32 form
goto fail; goto fail;
} }
opaque->managed_frame = alloc_avframe(opaque, ff_format, buf_width, buf_height); opaque->managed_frame = opaque_setup_frame(opaque, ff_format, buf_width, buf_height);
if (!opaque->managed_frame) { if (!opaque->managed_frame) {
ALOGE("overlay->opaque->frame allocation failed\n"); ALOGE("overlay->opaque->frame allocation failed\n");
goto fail; goto fail;
...@@ -221,12 +244,7 @@ int SDL_VoutFFmpeg_ConvertFrame( ...@@ -221,12 +244,7 @@ int SDL_VoutFFmpeg_ConvertFrame(
assert(overlay); assert(overlay);
assert(p_sws_ctx); assert(p_sws_ctx);
SDL_VoutOverlay_Opaque *opaque = overlay->opaque; SDL_VoutOverlay_Opaque *opaque = overlay->opaque;
AVPicture dest_pic = { { 0 } }; AVPicture swscale_dst_pic = { { 0 } };
for (int i = 0; i < overlay->planes; ++i) {
dest_pic.data[i] = overlay->pixels[i];
dest_pic.linesize[i] = overlay->pitches[i];
}
av_frame_unref(opaque->linked_frame); av_frame_unref(opaque->linked_frame);
...@@ -241,34 +259,19 @@ int SDL_VoutFFmpeg_ConvertFrame( ...@@ -241,34 +259,19 @@ int SDL_VoutFFmpeg_ConvertFrame(
if (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUVJ420P) { if (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUVJ420P) {
// ALOGE("direct draw frame"); // ALOGE("direct draw frame");
use_linked_frame = 1; use_linked_frame = 1;
av_frame_ref(opaque->linked_frame, frame); dst_format = frame->format;
overlay_fill(overlay, opaque->linked_frame, opaque->planes);
} else { } else {
// ALOGE("copy draw frame"); // ALOGE("copy draw frame");
overlay_fill(overlay, opaque->managed_frame, opaque->planes);
dest_pic.data[1] = overlay->pixels[1];
dest_pic.data[2] = overlay->pixels[2];
dst_format = AV_PIX_FMT_YUV420P; dst_format = AV_PIX_FMT_YUV420P;
} }
if (need_swap_uv) {
if (use_linked_frame) {
FFSWAP(Uint8*, overlay->pixels[1], overlay->pixels[2]);
} else {
FFSWAP(Uint8*, dest_pic.data[1], dest_pic.data[2]);
}
}
break; break;
case SDL_FCC_RV32: case SDL_FCC_RV32:
overlay_fill(overlay, opaque->managed_frame, opaque->planes);
dst_format = AV_PIX_FMT_0BGR32; dst_format = AV_PIX_FMT_0BGR32;
break; break;
case SDL_FCC_RV24: case SDL_FCC_RV24:
overlay_fill(overlay, opaque->managed_frame, opaque->planes);
dst_format = AV_PIX_FMT_RGB24; dst_format = AV_PIX_FMT_RGB24;
break; break;
case SDL_FCC_RV16: case SDL_FCC_RV16:
overlay_fill(overlay, opaque->managed_frame, opaque->planes);
dst_format = AV_PIX_FMT_RGB565; dst_format = AV_PIX_FMT_RGB565;
break; break;
default: default:
...@@ -277,10 +280,42 @@ int SDL_VoutFFmpeg_ConvertFrame( ...@@ -277,10 +280,42 @@ int SDL_VoutFFmpeg_ConvertFrame(
return -1; return -1;
} }
// setup frame
if (use_linked_frame) {
// linked frame
av_frame_ref(opaque->linked_frame, frame);
overlay_fill(overlay, opaque->linked_frame, opaque->planes);
if (need_swap_uv)
FFSWAP(Uint8*, overlay->pixels[1], overlay->pixels[2]);
} else {
// managed frame
AVFrame* managed_frame = opaque_obtain_managed_frame_buffer(opaque);
if (!managed_frame) {
ALOGE("OOM in opaque_obtain_managed_frame_buffer");
return -1;
}
// setup frame managed
for (int i = 0; i < overlay->planes; ++i) {
swscale_dst_pic.data[i] = overlay->pixels[i];
swscale_dst_pic.linesize[i] = overlay->pitches[i];
}
overlay_fill(overlay, opaque->managed_frame, opaque->planes);
if (need_swap_uv)
FFSWAP(Uint8*, swscale_dst_pic.data[1], swscale_dst_pic.data[2]);
}
// swscale / direct draw
if (use_linked_frame) { if (use_linked_frame) {
// do nothing // do nothing
} else if (ijk_image_convert(frame->width, frame->height, } else if (ijk_image_convert(frame->width, frame->height,
dst_format, dest_pic.data, dest_pic.linesize, dst_format, swscale_dst_pic.data, swscale_dst_pic.linesize,
frame->format, (const uint8_t**) frame->data, frame->linesize)) { frame->format, (const uint8_t**) frame->data, frame->linesize)) {
*p_sws_ctx = sws_getCachedContext(*p_sws_ctx, *p_sws_ctx = sws_getCachedContext(*p_sws_ctx,
frame->width, frame->height, frame->format, frame->width, frame->height, frame->width, frame->height, frame->format, frame->width, frame->height,
...@@ -291,7 +326,7 @@ int SDL_VoutFFmpeg_ConvertFrame( ...@@ -291,7 +326,7 @@ int SDL_VoutFFmpeg_ConvertFrame(
} }
sws_scale(*p_sws_ctx, (const uint8_t**) frame->data, frame->linesize, sws_scale(*p_sws_ctx, (const uint8_t**) frame->data, frame->linesize,
0, frame->height, dest_pic.data, dest_pic.linesize); 0, frame->height, swscale_dst_pic.data, swscale_dst_pic.linesize);
if (!opaque->no_neon_warned) { if (!opaque->no_neon_warned) {
opaque->no_neon_warned = 1; opaque->no_neon_warned = 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册