linuxOS_AP05/buildroot/package/ffmpeg/0008-As-SDL2-support-nv12-directly-send-nv12.patch
2025-06-02 13:59:07 +08:00

167 lines
7.4 KiB
Diff

From 4f6ca8c4228f453d2f3267009792439ad47975ad Mon Sep 17 00:00:00 2001
From: Hertz Wang <wangh@rock-chips.com>
Date: Mon, 10 Jun 2019 16:39:11 +0800
Subject: [PATCH 08/11] As SDL2 support nv12, directly send nv12
Change-Id: I49ce83f65ac8564a60b2add3f6adcb11c4ca5183
Signed-off-by: Hertz Wang <wangh@rock-chips.com>
---
fftools/ffplay.c | 54 ++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 38 insertions(+), 16 deletions(-)
diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index f9717e4..84fd8b0 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -392,6 +392,7 @@ static const struct TextureFormatEntry {
{ AV_PIX_FMT_BGR32, SDL_PIXELFORMAT_ABGR8888 },
{ AV_PIX_FMT_BGR32_1, SDL_PIXELFORMAT_BGRA8888 },
{ AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV },
+ { AV_PIX_FMT_NV12, SDL_PIXELFORMAT_NV12 },
{ AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2 },
{ AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY },
{ AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN },
@@ -912,10 +913,14 @@ static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_B
static void get_avframe_info(AVFrame *frame,
uint8_t *srcSlice[],
- int srcStride[]) {
+ int srcStride[],
+ int *hStride,
+ int *vStride) {
if (frame->format != AV_PIX_FMT_DRM_PRIME) {
memcpy(srcSlice, frame->data, sizeof(frame->data));
memcpy(srcStride, frame->linesize, sizeof(frame->linesize));
+ *hStride = frame->width;
+ *vStride = frame->height;
} else {
AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)frame->data[0];
AVDRMLayerDescriptor *layer = &desc->layers[0];
@@ -924,6 +929,8 @@ static void get_avframe_info(AVFrame *frame,
srcSlice[0] = (uint8_t*)desc->objects[0].ptr;
srcSlice[1] = srcSlice[0] + layer->planes[1].offset;
srcStride[0] = srcStride[1] = layer->planes[0].pitch;
+ *hStride = layer->planes[0].pitch; // always nv12
+ *vStride = layer->planes[1].offset / layer->planes[0].pitch;
}
}
@@ -950,8 +957,13 @@ static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext *
Uint32 sdl_pix_fmt;
SDL_BlendMode sdl_blendmode;
int av_format = get_avframe_format(frame);
- get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode);
- if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0)
+ uint8_t *srcSlice[AV_NUM_DATA_POINTERS] = { NULL };
+ int srcStride[AV_NUM_DATA_POINTERS] = { 0 };
+ int tex_w, tex_h;
+
+ get_avframe_info(frame, srcSlice, srcStride, &tex_w, &tex_h);
+ get_sdl_pix_fmt_and_blendmode(av_format, &sdl_pix_fmt, &sdl_blendmode);
+ if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, tex_w, tex_h, sdl_blendmode, 0) < 0)
return -1;
switch (sdl_pix_fmt) {
case SDL_PIXELFORMAT_UNKNOWN:
@@ -960,14 +972,10 @@ static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext *
frame->width, frame->height, av_format, frame->width, frame->height,
AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
if (*img_convert_ctx != NULL) {
- uint8_t *pixels[4];
- int pitch[4];
+ uint8_t *pixels[4] = { NULL };
+ int pitch[4] = { 0 };
if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) {
- uint8_t *srcSlice[AV_NUM_DATA_POINTERS] = { NULL };
- int srcStride[AV_NUM_DATA_POINTERS] = { 0 };
-
- get_avframe_info(frame, srcSlice, srcStride);
- sws_scale(*img_convert_ctx, (const uint8_t * const *)srcSlice, srcStride,
+ sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
0, frame->height, pixels, pitch);
SDL_UnlockTexture(*tex);
}
@@ -976,6 +984,16 @@ static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext *
ret = -1;
}
break;
+ case SDL_PIXELFORMAT_NV12:
+ {
+ if (srcStride[0] > 0 && srcStride[1] > 0) {
+ ret = SDL_UpdateTexture(*tex, NULL, srcSlice[0], srcStride[0]);
+ } else {
+ av_log(NULL, AV_LOG_ERROR, "TODO: negative linesizes are not supported.\n");
+ return -1;
+ }
+ }
+ break;
case SDL_PIXELFORMAT_IYUV:
if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) {
ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0],
@@ -1021,7 +1039,7 @@ static void video_image_display(VideoState *is)
{
Frame *vp;
Frame *sp = NULL;
- SDL_Rect rect;
+ SDL_Rect rect, src_rect;
vp = frame_queue_peek_last(&is->pictq);
if (is->subtitle_st) {
@@ -1071,6 +1089,10 @@ static void video_image_display(VideoState *is)
calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
+ src_rect.x = 0;
+ src_rect.y = 0;
+ src_rect.w = vp->frame->width;
+ src_rect.h = vp->frame->height;
if (!vp->uploaded) {
if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
return;
@@ -1079,7 +1101,7 @@ static void video_image_display(VideoState *is)
}
set_sdl_yuv_conversion_mode(vp->frame);
- SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
+ SDL_RenderCopyEx(renderer, is->vid_texture, &src_rect, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
set_sdl_yuv_conversion_mode(NULL);
if (sp) {
#if USE_ONEPASS_SUBTITLE_RENDER
@@ -1533,7 +1555,7 @@ static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_by
static void stream_toggle_pause(VideoState *is)
{
if (is->paused) {
- is->frame_timer += av_gettime_relative() / 1000000.0; // make play immediately
+ is->frame_timer = av_gettime_relative() / 1000000.0; // make play immediately
if (is->read_pause_return != AVERROR(ENOSYS)) {
is->vidclk.paused = 0;
}
@@ -2241,14 +2263,14 @@ static int video_thread(void *arg)
frame_rate = av_buffersink_get_frame_rate(filt_out);
}
- if (support_avfilter) {
+ if (filt_in) {
ret = av_buffersrc_add_frame(filt_in, frame);
if (ret < 0)
goto the_end;
}
while (ret >= 0) {
- if (support_avfilter) {
+ if (filt_out) {
is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
@@ -2270,7 +2292,7 @@ static int video_thread(void *arg)
ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
av_frame_unref(frame);
#if CONFIG_AVFILTER
- if (!support_avfilter || is->videoq.serial != is->viddec.pkt_serial)
+ if (!filt_out || is->videoq.serial != is->viddec.pkt_serial)
break;
}
#endif
--
2.7.4