mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-11 18:09:36 +00:00
lavd/xv: free resources on errors
xv_write_header callback leave not freed resources on errors. Signed-off-by: Lukasz Marek <lukasz.m.luki@gmail.com> Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
This commit is contained in:
parent
57bca5a2b6
commit
995f450b44
@ -81,13 +81,28 @@ static int xv_get_tag_from_format(enum AVPixelFormat format)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int xv_write_trailer(AVFormatContext *s)
|
||||||
|
{
|
||||||
|
XVContext *xv = s->priv_data;
|
||||||
|
if (xv->display) {
|
||||||
|
XShmDetach(xv->display, &xv->yuv_shminfo);
|
||||||
|
if (xv->yuv_image)
|
||||||
|
shmdt(xv->yuv_image->data);
|
||||||
|
XFree(xv->yuv_image);
|
||||||
|
if (xv->gc)
|
||||||
|
XFreeGC(xv->display, xv->gc);
|
||||||
|
XCloseDisplay(xv->display);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int xv_write_header(AVFormatContext *s)
|
static int xv_write_header(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
XVContext *xv = s->priv_data;
|
XVContext *xv = s->priv_data;
|
||||||
unsigned int num_adaptors;
|
unsigned int num_adaptors;
|
||||||
XvAdaptorInfo *ai;
|
XvAdaptorInfo *ai;
|
||||||
XvImageFormatValues *fv;
|
XvImageFormatValues *fv;
|
||||||
int num_formats = 0, j, tag;
|
int num_formats = 0, j, tag, ret;
|
||||||
AVCodecContext *encctx = s->streams[0]->codec;
|
AVCodecContext *encctx = s->streams[0]->codec;
|
||||||
|
|
||||||
if ( s->nb_streams > 1
|
if ( s->nb_streams > 1
|
||||||
@ -122,20 +137,26 @@ static int xv_write_header(AVFormatContext *s)
|
|||||||
xv->window_width, xv->window_height,
|
xv->window_width, xv->window_height,
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!xv->window_title) {
|
if (!xv->window_title) {
|
||||||
if (!(xv->window_title = av_strdup(s->filename)))
|
if (!(xv->window_title = av_strdup(s->filename))) {
|
||||||
return AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
XStoreName(xv->display, xv->window, xv->window_title);
|
XStoreName(xv->display, xv->window, xv->window_title);
|
||||||
XMapWindow(xv->display, xv->window);
|
XMapWindow(xv->display, xv->window);
|
||||||
|
|
||||||
if (XvQueryAdaptors(xv->display, DefaultRootWindow(xv->display), &num_adaptors, &ai) != Success)
|
if (XvQueryAdaptors(xv->display, DefaultRootWindow(xv->display), &num_adaptors, &ai) != Success) {
|
||||||
return AVERROR_EXTERNAL;
|
ret = AVERROR_EXTERNAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
xv->xv_port = ai[0].base_id;
|
xv->xv_port = ai[0].base_id;
|
||||||
XvFreeAdaptorInfo(ai);
|
XvFreeAdaptorInfo(ai);
|
||||||
|
|
||||||
fv = XvListImageFormats(xv->display, xv->xv_port, &num_formats);
|
fv = XvListImageFormats(xv->display, xv->xv_port, &num_formats);
|
||||||
if (!fv)
|
if (!fv) {
|
||||||
return AVERROR_EXTERNAL;
|
ret = AVERROR_EXTERNAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
for (j = 0; j < num_formats; j++) {
|
for (j = 0; j < num_formats; j++) {
|
||||||
if (fv[j].id == tag) {
|
if (fv[j].id == tag) {
|
||||||
break;
|
break;
|
||||||
@ -147,7 +168,8 @@ static int xv_write_header(AVFormatContext *s)
|
|||||||
av_log(s, AV_LOG_ERROR,
|
av_log(s, AV_LOG_ERROR,
|
||||||
"Device does not support pixel format %s, aborting\n",
|
"Device does not support pixel format %s, aborting\n",
|
||||||
av_get_pix_fmt_name(encctx->pix_fmt));
|
av_get_pix_fmt_name(encctx->pix_fmt));
|
||||||
return AVERROR(EINVAL);
|
ret = AVERROR(EINVAL);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
xv->gc = XCreateGC(xv->display, xv->window, 0, 0);
|
xv->gc = XCreateGC(xv->display, xv->window, 0, 0);
|
||||||
@ -166,6 +188,9 @@ static int xv_write_header(AVFormatContext *s)
|
|||||||
shmctl(xv->yuv_shminfo.shmid, IPC_RMID, 0);
|
shmctl(xv->yuv_shminfo.shmid, IPC_RMID, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
fail:
|
||||||
|
xv_write_trailer(s);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xv_write_packet(AVFormatContext *s, AVPacket *pkt)
|
static int xv_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||||
@ -195,18 +220,6 @@ static int xv_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xv_write_trailer(AVFormatContext *s)
|
|
||||||
{
|
|
||||||
XVContext *xv = s->priv_data;
|
|
||||||
|
|
||||||
XShmDetach(xv->display, &xv->yuv_shminfo);
|
|
||||||
shmdt(xv->yuv_image->data);
|
|
||||||
XFree(xv->yuv_image);
|
|
||||||
XFreeGC(xv->display, xv->gc);
|
|
||||||
XCloseDisplay(xv->display);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(XVContext, x)
|
#define OFFSET(x) offsetof(XVContext, x)
|
||||||
static const AVOption options[] = {
|
static const AVOption options[] = {
|
||||||
{ "display_name", "set display name", OFFSET(display_name), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
|
{ "display_name", "set display name", OFFSET(display_name), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
|
||||||
|
Loading…
Reference in New Issue
Block a user