From: Reinhard N. <rn...@gm...> - 2008-05-15 14:07:42
|
# HG changeset patch # User Reinhard Nißl <rn...@gm...> # Date 1210600570 -7200 # Node ID 43ef34a8682d6b493ab66652653197f6fdceb6b5 # Parent 5a46043419a636ad94bea85a2d50957de35b8804 Provide xine_get_current_frame_data which passes more data via a structure. The new structure xine_current_frame_data_t additionally contains cropping and interlacing information, which both are required for proper conversion of the image. The existing functions have been adopted to use the code of the new function. The changeset should be ABI compatible. diff -r 43ef34a8682d6b493ab66652653197f6fdceb6b5 -r 5a46043419a636ad94bea85a2d50957de35b8804 include/xine.h.in --- a/include/xine.h.in Mon May 12 15:56:10 2008 +0200 +++ b/include/xine.h.in Sun May 11 18:31:42 2008 +0100 @@ -433,6 +433,11 @@ int xine_get_param (xine_stream_t *stre * xine_get_current_frame_alloc() takes care of allocating * a buffer on its own, so image data can be retrieved by * a single call without the need to pause the stream. + * + * xine_get_current_frame_data() passes the parameters of the + * previously mentioned functions plus further information in + * a structure and can work like the _s or _alloc function + * respectively depending on the passed flags. * * all functions return 1 on success, 0 failure. */ @@ -444,12 +449,33 @@ int xine_get_current_frame_s (xine_stre int xine_get_current_frame_s (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, - uint8_t *img, int *size) XINE_PROTECTED; + uint8_t *img, int *img_size) XINE_PROTECTED; int xine_get_current_frame_alloc (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, - uint8_t **img, int *size) XINE_PROTECTED; + uint8_t **img, int *img_size) XINE_PROTECTED; + +typedef struct { + + int width; + int height; + int crop_left; + int crop_right; + int crop_top; + int crop_bottom; + int ratio_code; + int interlaced; + int format; + int img_size; + uint8_t *img; +} xine_current_frame_data_t; + +#define XINE_FRAME_DATA_ALLOCATE_IMG (1<<0) + +int xine_get_current_frame_data (xine_stream_t *stream, + xine_current_frame_data_t *data, + int flags) XINE_PROTECTED; /* xine image formats */ #define XINE_IMGFMT_YV12 (('2'<<24)|('1'<<16)|('V'<<8)|'Y') diff -r 43ef34a8682d6b493ab66652653197f6fdceb6b5 -r 5a46043419a636ad94bea85a2d50957de35b8804 src/xine-engine/xine.c --- a/src/xine-engine/xine.c Mon May 12 15:56:10 2008 +0200 +++ b/src/xine-engine/xine.c Sun May 11 18:31:42 2008 +0100 @@ -1933,9 +1933,9 @@ int xine_get_pos_length (xine_stream_t * return 1; } -static int _x_get_current_frame_impl (xine_stream_t *stream, int *width, int *height, - int *ratio_code, int *format, - uint8_t **img, int *size, int alloc_img) { +static int _x_get_current_frame_data (xine_stream_t *stream, + xine_current_frame_data_t *data, + int flags, int img_size_unknown) { vo_frame_t *frame; size_t required_size; @@ -1944,42 +1944,49 @@ static int _x_get_current_frame_impl (xi frame = stream->video_out->get_last_frame (stream->video_out); stream->xine->port_ticket->release(stream->xine->port_ticket, 0); - if (!frame) + if (!frame) { + data->img_size = 0; return 0; - - *width = frame->width; - *height = frame->height; - - *ratio_code = 10000.0 * frame->ratio; + } + + data->width = frame->width; + data->height = frame->height; + data->crop_left = frame->crop_left; + data->crop_right = frame->crop_right; + data->crop_top = frame->crop_top; + data->crop_bottom = frame->crop_bottom; + + data->ratio_code = 10000.0 * frame->ratio; /* make ratio_code backward compatible */ #define RATIO_LIKE(a, b) ((b) - 1 <= (a) && (a) <= 1 + (b)) - if (RATIO_LIKE(*ratio_code, 10000)) - *ratio_code = XINE_VO_ASPECT_SQUARE; - else if (RATIO_LIKE(*ratio_code, 13333)) - *ratio_code = XINE_VO_ASPECT_4_3; - else if (RATIO_LIKE(*ratio_code, 17778)) - *ratio_code = XINE_VO_ASPECT_ANAMORPHIC; - else if (RATIO_LIKE(*ratio_code, 21100)) - *ratio_code = XINE_VO_ASPECT_DVB; - - *format = frame->format; - - switch (*format) { + if (RATIO_LIKE(data->ratio_code, 10000)) + data->ratio_code = XINE_VO_ASPECT_SQUARE; + else if (RATIO_LIKE(data->ratio_code, 13333)) + data->ratio_code = XINE_VO_ASPECT_4_3; + else if (RATIO_LIKE(data->ratio_code, 17778)) + data->ratio_code = XINE_VO_ASPECT_ANAMORPHIC; + else if (RATIO_LIKE(data->ratio_code, 21100)) + data->ratio_code = XINE_VO_ASPECT_DVB; + + data->format = frame->format; + data->interlaced = frame->progressive_frame ? 0 : (2 - frame->top_field_first); + + switch (frame->format) { case XINE_IMGFMT_YV12: - required_size = *width * *height - + ((*width + 1) / 2) * ((*height + 1) / 2) - + ((*width + 1) / 2) * ((*height + 1) / 2); + required_size = frame->width * frame->height + + ((frame->width + 1) / 2) * ((frame->height + 1) / 2) + + ((frame->width + 1) / 2) * ((frame->height + 1) / 2); break; case XINE_IMGFMT_YUY2: - required_size = *width * *height - + ((*width + 1) / 2) * *height - + ((*width + 1) / 2) * *height; + required_size = frame->width * frame->height + + ((frame->width + 1) / 2) * frame->height + + ((frame->width + 1) / 2) * frame->height; break; default: - if (*img || alloc_img) { + if (data->img || (flags & XINE_FRAME_DATA_ALLOCATE_IMG)) { xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "xine: error, snapshot function not implemented for format 0x%x\n", frame->format); _x_abort (); @@ -1988,38 +1995,36 @@ static int _x_get_current_frame_impl (xi required_size = 0; } - if (alloc_img) { - /* return size if requested */ - if (size) - *size = required_size; + if (flags & XINE_FRAME_DATA_ALLOCATE_IMG) { + /* return allocated buffer size */ + data->img_size = required_size; /* allocate img or fail */ - if (!(*img = calloc(1, required_size))) + if (!(data->img = calloc(1, required_size))) return 0; } else { /* fail if supplied buffer is to small */ - if (*img && size && *size < required_size) { - *size = required_size; + if (data->img && !img_size_unknown && data->img_size < required_size) { + data->img_size = required_size; return 0; } - /* return size if requested */ - if (size) - *size = required_size; + /* return used buffer size */ + data->img_size = required_size; } - if (*img) { + if (data->img) { switch (frame->format) { case XINE_IMGFMT_YV12: yv12_to_yv12( /* Y */ frame->base[0], frame->pitches[0], - *img, frame->width, + data->img, frame->width, /* U */ frame->base[1], frame->pitches[1], - *img+frame->width*frame->height, frame->width/2, + data->img+frame->width*frame->height, frame->width/2, /* V */ frame->base[2], frame->pitches[2], - *img+frame->width*frame->height+frame->width*frame->height/4, frame->width/2, + data->img+frame->width*frame->height+frame->width*frame->height/4, frame->width/2, /* width x height */ frame->width, frame->height); break; @@ -2029,7 +2034,7 @@ static int _x_get_current_frame_impl (xi /* src */ frame->base[0], frame->pitches[0], /* dst */ - *img, frame->width*2, + data->img, frame->width*2, /* width x height */ frame->width, frame->height); break; @@ -2043,23 +2048,67 @@ static int _x_get_current_frame_impl (xi return 1; } +int xine_get_current_frame_data (xine_stream_t *stream, + xine_current_frame_data_t *data, + int flags) { + + return _x_get_current_frame_data(stream, data, flags, 0); +} + int xine_get_current_frame_alloc (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, - uint8_t **img, int *size) { - uint8_t *no_img = NULL; - return _x_get_current_frame_impl(stream, width, height, ratio_code, format, img ? img : &no_img, size, img != NULL); + uint8_t **img, int *img_size) { + + int result; + xine_current_frame_data_t data; + + memset(&data, 0, sizeof (data)); + + result = _x_get_current_frame_data(stream, &data, img ? XINE_FRAME_DATA_ALLOCATE_IMG : 0, 0); + if (width) *width = data.width; + if (height) *height = data.height; + if (ratio_code) *ratio_code = data.ratio_code; + if (format) *format = data.format; + if (img_size) *img_size = data.img_size; + if (img) *img = data.img; + return result; } int xine_get_current_frame_s (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, - uint8_t *img, int *size) { - return (!img || size) && _x_get_current_frame_impl(stream, width, height, ratio_code, format, &img, size, 0); + uint8_t *img, int *img_size) { + int result; + xine_current_frame_data_t data; + + memset(&data, 0, sizeof (data)); + data.img = img; + if (img_size) + data.img_size = *img_size; + + result = _x_get_current_frame_data(stream, &data, 0, 0); + if (width) *width = data.width; + if (height) *height = data.height; + if (ratio_code) *ratio_code = data.ratio_code; + if (format) *format = data.format; + if (img_size) *img_size = data.img_size; + return result; } int xine_get_current_frame (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, uint8_t *img) { - return _x_get_current_frame_impl(stream, width, height, ratio_code, format, &img, NULL, 0); + int result; + xine_current_frame_data_t data; + + memset(&data, 0, sizeof (data)); + data.img = img; + + result = _x_get_current_frame_data(stream, &data, 0, 1); + if (width) *width = data.width; + if (height) *height = data.height; + if (ratio_code) *ratio_code = data.ratio_code; + if (format) *format = data.format; + return result; } int xine_get_video_frame (xine_stream_t *stream, |