aboutsummaryrefslogtreecommitdiffhomepage
path: root/libvo
diff options
context:
space:
mode:
Diffstat (limited to 'libvo')
-rw-r--r--libvo/jpeg_enc.c485
-rw-r--r--libvo/jpeg_enc.h52
-rw-r--r--libvo/video_out.c6
-rw-r--r--libvo/vo_zr.c837
-rw-r--r--libvo/vo_zr.h29
-rw-r--r--libvo/vo_zr2.c500
6 files changed, 0 insertions, 1909 deletions
diff --git a/libvo/jpeg_enc.c b/libvo/jpeg_enc.c
deleted file mode 100644
index 37b5010250..0000000000
--- a/libvo/jpeg_enc.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * straightforward (to be) optimized JPEG encoder for the YUV422 format
- * based on MJPEG code from FFmpeg
- *
- * For an excellent introduction to the JPEG format, see:
- * http://www.ece.purdue.edu/~bouman/grad-labs/lab8/pdf/lab.pdf
- *
- * Copyright (c) 2002, Rik Snel
- * parts from FFmpeg Copyright (c) 2000-2002 Fabrice Bellard
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "config.h"
-#include "mp_msg.h"
-/* We need this #define because we need ../libavcodec/common.h to #define
- * be2me_32, otherwise the linker will complain that it doesn't exist */
-#define HAVE_AV_CONFIG_H
-#include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
-#include "libavcodec/mpegvideo.h"
-#include "libavcodec/mjpegenc.h"
-
-#include "libmpcodecs/vd_ffmpeg.h"
-#include "jpeg_enc.h"
-
-
-/* Begin excessive code duplication ************************************/
-/* Code coming from mpegvideo.c and mjpeg.c in ../libavcodec ***********/
-
-static const unsigned short aanscales[64] = {
- /* precomputed values scaled up by 14 bits */
- 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
- 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
- 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
- 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
- 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
- 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
- 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
- 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
-};
-
-static void convert_matrix(MpegEncContext *s, int (*qmat)[64],
- uint16_t (*qmat16)[2][64], const uint16_t *quant_matrix,
- int bias, int qmin, int qmax)
-{
- int qscale;
-
- for(qscale=qmin; qscale<=qmax; qscale++){
- int i;
- if (s->dsp.fdct == ff_jpeg_fdct_islow) {
- for (i = 0; i < 64; i++) {
- const int j = s->dsp.idct_permutation[i];
- /* 16 <= qscale * quant_matrix[i] <= 7905
- * 19952 <= aanscales[i] * \
- * qscale * quant_matrix[i] <= 205026
- * (1<<36)/19952 >= (1<<36)/(aanscales[i] * \
- * qscale * quant_matrix[i]) >= (1<<36)/249205025
- * 3444240 >= (1<<36)/(aanscales[i] *
- * qscale * quant_matrix[i]) >= 275 */
- qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT-3))/
- (qscale * quant_matrix[j]));
- }
- } else if (s->dsp.fdct == fdct_ifast) {
- for(i=0;i<64;i++) {
- const int j = s->dsp.idct_permutation[i];
- /* 16 <= qscale * quant_matrix[i] <= 7905 */
- /* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */
- /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */
- /* 3444240 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */
-
- qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 11)) /
- (aanscales[i] * qscale * quant_matrix[j]));
- }
- } else {
- for(i=0;i<64;i++) {
- const int j = s->dsp.idct_permutation[i];
- /* We can safely suppose that 16 <= quant_matrix[i] <= 255
- So 16 <= qscale * quant_matrix[i] <= 7905
- so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905
- so 32768 >= (1<<19) / (qscale * quant_matrix[i]) >= 67
- */
- qmat [qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]));
- qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]);
-
- if(qmat16[qscale][0][i]==0 || qmat16[qscale][0][i]==128*256) qmat16[qscale][0][i]=128*256-1;
- qmat16[qscale][1][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][0][i]);
- }
- }
- }
-}
-
-static inline void encode_dc(MpegEncContext *s, int val,
- uint8_t *huff_size, uint16_t *huff_code)
-{
- int mant, nbits;
-
- if (val == 0) {
- put_bits(&s->pb, huff_size[0], huff_code[0]);
- } else {
- mant = val;
- if (val < 0) {
- val = -val;
- mant--;
- }
-
- /* compute the log (XXX: optimize) */
- nbits = 0;
- while (val != 0) {
- val = val >> 1;
- nbits++;
- }
-
- put_bits(&s->pb, huff_size[nbits], huff_code[nbits]);
-
- put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1));
- }
-}
-
-static void encode_block(MpegEncContext *s, DCTELEM *block, int n)
-{
- int mant, nbits, code, i, j;
- int component, dc, run, last_index, val;
- MJpegContext *m = s->mjpeg_ctx;
- uint8_t *huff_size_ac;
- uint16_t *huff_code_ac;
-
- /* DC coef */
- component = (n <= 3 ? 0 : n - 4 + 1);
- dc = block[0]; /* overflow is impossible */
- val = dc - s->last_dc[component];
- if (n < 4) {
- encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance);
- huff_size_ac = m->huff_size_ac_luminance;
- huff_code_ac = m->huff_code_ac_luminance;
- } else {
- encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
- huff_size_ac = m->huff_size_ac_chrominance;
- huff_code_ac = m->huff_code_ac_chrominance;
- }
- s->last_dc[component] = dc;
-
- /* AC coefs */
-
- run = 0;
- last_index = s->block_last_index[n];
- for(i=1;i<=last_index;i++) {
- j = s->intra_scantable.permutated[i];
- val = block[j];
- if (val == 0) {
- run++;
- } else {
- while (run >= 16) {
- put_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]);
- run -= 16;
- }
- mant = val;
- if (val < 0) {
- val = -val;
- mant--;
- }
-
- /* compute the log (XXX: optimize) */
- nbits = 0;
- while (val != 0) {
- val = val >> 1;
- nbits++;
- }
- code = (run << 4) | nbits;
-
- put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]);
-
- put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1));
- run = 0;
- }
- }
-
- /* output EOB only if not already 64 values */
- if (last_index < 63 || run != 0)
- put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);
-}
-
-static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block, int last_index)
-{
- int i;
- const int maxlevel= s->max_qcoeff;
- const int minlevel= s->min_qcoeff;
-
- for(i=0; i<=last_index; i++){
- const int j = s->intra_scantable.permutated[i];
- int level = block[j];
-
- if (level>maxlevel) level=maxlevel;
- else if(level<minlevel) level=minlevel;
- block[j]= level;
- }
-}
-
-/* End excessive code duplication **************************************/
-
-/* this function is a reproduction of the one in mjpeg, it includes two
- * changes, it allows for black&white encoding (it skips the U and V
- * macroblocks and it outputs the huffman code for 'no change' (dc) and
- * 'all zero' (ac)) and it takes 4 macroblocks (422) instead of 6 (420) */
-static void zr_mjpeg_encode_mb(jpeg_enc_t *j) {
-
- MJpegContext *m = j->s->mjpeg_ctx;
-
- encode_block(j->s, j->s->block[0], 0);
- encode_block(j->s, j->s->block[1], 1);
- if (j->bw) {
- /* U */
- put_bits(&j->s->pb, m->huff_size_dc_chrominance[0],
- m->huff_code_dc_chrominance[0]);
- put_bits(&j->s->pb, m->huff_size_ac_chrominance[0],
- m->huff_code_ac_chrominance[0]);
- /* V */
- put_bits(&j->s->pb, m->huff_size_dc_chrominance[0],
- m->huff_code_dc_chrominance[0]);
- put_bits(&j->s->pb, m->huff_size_ac_chrominance[0],
- m->huff_code_ac_chrominance[0]);
- } else {
- /* we trick encode_block here so that it uses
- * chrominance huffman tables instead of luminance ones
- * (see the effect of second argument of encode_block) */
- encode_block(j->s, j->s->block[2], 4);
- encode_block(j->s, j->s->block[3], 5);
- }
-}
-
-/* this function can take all kinds of YUV colorspaces
- * YV12, YVYU, UYVY. The necesary parameters must be set up by the caller
- * y_ps means "y pixel size", y_rs means "y row size".
- * For YUYV, for example, is u_buf = y_buf + 1, v_buf = y_buf + 3,
- * y_ps = 2, u_ps = 4, v_ps = 4, y_rs = u_rs = v_rs.
- *
- * The actual buffers must be passed with mjpeg_encode_frame, this is
- * to make it possible to call encode on the buffer provided by the
- * codec in draw_frame.
- *
- * The data is straightened out at the moment it is put in DCT
- * blocks, there are therefore no spurious memcopies involved */
-/* Notice that w must be a multiple of 16 and h must be a multiple of 8 */
-/* We produce YUV422 jpegs, the colors must be subsampled horizontally,
- * if the colors are also subsampled vertically, then this function
- * performs cheap upsampling (better solution will be: a DCT that is
- * optimized in the case that every two rows are the same) */
-/* cu = 0 means 'No cheap upsampling'
- * cu = 1 means 'perform cheap upsampling' */
-/* The encoder doesn't know anything about interlacing, the halve height
- * needs to be passed and the double rowstride. Which field gets encoded
- * is decided by what buffers are passed to mjpeg_encode_frame */
-jpeg_enc_t *jpeg_enc_init(int w, int h, int y_psize, int y_rsize,
- int u_psize, int u_rsize, int v_psize, int v_rsize,
- int cu, int q, int b) {
- jpeg_enc_t *j;
- int i = 0;
- mp_msg(MSGT_VO, MSGL_V, "JPEnc init: %dx%d %d %d %d %d %d %d\n",
- w, h, y_psize, y_rsize, u_psize,
- u_rsize, v_psize, v_rsize);
-
- j = av_malloc(sizeof(jpeg_enc_t));
- if (j == NULL) return NULL;
-
- j->s = av_malloc(sizeof(MpegEncContext));
- memset(j->s,0x00,sizeof(MpegEncContext));
- if (j->s == NULL) {
- av_free(j);
- return NULL;
- }
-
- /* info on how to access the pixels */
- j->y_ps = y_psize;
- j->u_ps = u_psize;
- j->v_ps = v_psize;
- j->y_rs = y_rsize;
- j->u_rs = u_rsize;
- j->v_rs = v_rsize;
-
- j->s->width = w;
- j->s->height = h;
- j->s->qscale = q;
-
- j->s->out_format = FMT_MJPEG;
- j->s->intra_only = 1;
- j->s->encoding = 1;
- j->s->pict_type = FF_I_TYPE;
- j->s->y_dc_scale = 8;
- j->s->c_dc_scale = 8;
-
- //FIXME j->s->mjpeg_write_tables = 1;
- j->s->mjpeg_vsample[0] = 1;
- j->s->mjpeg_vsample[1] = 1;
- j->s->mjpeg_vsample[2] = 1;
- j->s->mjpeg_hsample[0] = 2;
- j->s->mjpeg_hsample[1] = 1;
- j->s->mjpeg_hsample[2] = 1;
-
- j->cheap_upsample = cu;
- j->bw = b;
-
- init_avcodec();
-
- if (ff_mjpeg_encode_init(j->s) < 0) {
- av_free(j->s);
- av_free(j);
- return NULL;
- }
-
- /* alloc bogus avctx to keep MPV_common_init from segfaulting */
- j->s->avctx = calloc(sizeof(*j->s->avctx), 1);
- /* Set up to encode mjpeg */
- j->s->avctx->codec_id = CODEC_ID_MJPEG;
-
- /* make MPV_common_init allocate important buffers, like s->block */
- j->s->avctx->thread_count = 1;
-
- if (MPV_common_init(j->s) < 0) {
- av_free(j->s);
- av_free(j);
- return NULL;
- }
-
- /* correct the value for sc->mb_height */
- j->s->mb_height = j->s->height/8;
- j->s->mb_intra = 1;
-
- j->s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0];
- for (i = 1; i < 64; i++)
- j->s->intra_matrix[i] = av_clip_uint8(
- (ff_mpeg1_default_intra_matrix[i]*j->s->qscale) >> 3);
- convert_matrix(j->s, j->s->q_intra_matrix, j->s->q_intra_matrix16,
- j->s->intra_matrix, j->s->intra_quant_bias, 8, 8);
- return j;
-}
-
-int jpeg_enc_frame(jpeg_enc_t *j, unsigned char *y_data,
- unsigned char *u_data, unsigned char *v_data, char *bufr) {
- int i, k, mb_x, mb_y, overflow;
- short int *dest;
- unsigned char *source;
- /* initialize the buffer */
-
- init_put_bits(&j->s->pb, bufr, 1024*256);
-
- ff_mjpeg_encode_picture_header(j->s);
-
- j->s->header_bits = put_bits_count(&j->s->pb);
-
- j->s->last_dc[0] = 128;
- j->s->last_dc[1] = 128;
- j->s->last_dc[2] = 128;
-
- for (mb_y = 0; mb_y < j->s->mb_height; mb_y++) {
- for (mb_x = 0; mb_x < j->s->mb_width; mb_x++) {
- /* conversion 8 to 16 bit and filling of blocks
- * must be mmx optimized */
- /* fill 2 Y macroblocks and one U and one V */
- source = mb_y * 8 * j->y_rs +
- 16 * j->y_ps * mb_x + y_data;
- dest = j->s->block[0];
- for (i = 0; i < 8; i++) {
- for (k = 0; k < 8; k++) {
- dest[k] = source[k*j->y_ps];
- }
- dest += 8;
- source += j->y_rs;
- }
- source = mb_y * 8 * j->y_rs +
- (16*mb_x + 8)*j->y_ps + y_data;
- dest = j->s->block[1];
- for (i = 0; i < 8; i++) {
- for (k = 0; k < 8; k++) {
- dest[k] = source[k*j->y_ps];
- }
- dest += 8;
- source += j->y_rs;
- }
- if (!j->bw && j->cheap_upsample) {
- source = mb_y*4*j->u_rs +
- 8*mb_x*j->u_ps + u_data;
- dest = j->s->block[2];
- for (i = 0; i < 4; i++) {
- for (k = 0; k < 8; k++) {
- dest[k] = source[k*j->u_ps];
- dest[k+8] = source[k*j->u_ps];
- }
- dest += 16;
- source += j->u_rs;
- }
- source = mb_y*4*j->v_rs +
- 8*mb_x*j->v_ps + v_data;
- dest = j->s->block[3];
- for (i = 0; i < 4; i++) {
- for (k = 0; k < 8; k++) {
- dest[k] = source[k*j->v_ps];
- dest[k+8] = source[k*j->v_ps];
- }
- dest += 16;
- source += j->u_rs;
- }
- } else if (!j->bw && !j->cheap_upsample) {
- source = mb_y*8*j->u_rs +
- 8*mb_x*j->u_ps + u_data;
- dest = j->s->block[2];
- for (i = 0; i < 8; i++) {
- for (k = 0; k < 8; k++)
- dest[k] = source[k*j->u_ps];
- dest += 8;
- source += j->u_rs;
- }
- source = mb_y*8*j->v_rs +
- 8*mb_x*j->v_ps + v_data;
- dest = j->s->block[3];
- for (i = 0; i < 8; i++) {
- for (k = 0; k < 8; k++)
- dest[k] = source[k*j->v_ps];
- dest += 8;
- source += j->u_rs;
- }
- }
- emms_c(); /* is this really needed? */
-
- j->s->block_last_index[0] =
- j->s->dct_quantize(j->s, j->s->block[0],
- 0, 8, &overflow);
- if (overflow) clip_coeffs(j->s, j->s->block[0],
- j->s->block_last_index[0]);
- j->s->block_last_index[1] =
- j->s->dct_quantize(j->s, j->s->block[1],
- 1, 8, &overflow);
- if (overflow) clip_coeffs(j->s, j->s->block[1],
- j->s->block_last_index[1]);
-
- if (!j->bw) {
- j->s->block_last_index[4] =
- j->s->dct_quantize(j->s, j->s->block[2],
- 4, 8, &overflow);
- if (overflow) clip_coeffs(j->s, j->s->block[2],
- j->s->block_last_index[2]);
- j->s->block_last_index[5] =
- j->s->dct_quantize(j->s, j->s->block[3],
- 5, 8, &overflow);
- if (overflow) clip_coeffs(j->s, j->s->block[3],
- j->s->block_last_index[3]);
- }
- zr_mjpeg_encode_mb(j);
- }
- }
- emms_c();
- ff_mjpeg_encode_picture_trailer(j->s);
- flush_put_bits(&j->s->pb);
-
- //FIXME
- //if (j->s->mjpeg_write_tables == 1)
- // j->s->mjpeg_write_tables = 0;
-
- return put_bits_ptr(&(j->s->pb)) - j->s->pb.buf;
-}
-
-void jpeg_enc_uninit(jpeg_enc_t *j) {
- ff_mjpeg_encode_close(j->s);
- av_free(j->s);
- av_free(j);
-}
diff --git a/libvo/jpeg_enc.h b/libvo/jpeg_enc.h
deleted file mode 100644
index c3255ad99d..0000000000
--- a/libvo/jpeg_enc.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * straightforward (to be) optimized JPEG encoder for the YUV422 format
- * based on MJPEG code from FFmpeg
- *
- * For an excellent introduction to the JPEG format, see:
- * http://www.ece.purdue.edu/~bouman/grad-labs/lab8/pdf/lab.pdf
- *
- * Copyright (c) 2002, Rik Snel
- * parts from FFmpeg Copyright (c) 2000-2002 Fabrice Bellard
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_JPEG_ENC_H
-#define MPLAYER_JPEG_ENC_H
-
-typedef struct {
- struct MpegEncContext *s;
- int cheap_upsample;
- int bw;
- int y_ps;
- int u_ps;
- int v_ps;
- int y_rs;
- int u_rs;
- int v_rs;
-} jpeg_enc_t;
-
-jpeg_enc_t *jpeg_enc_init(int w, int h, int y_psize, int y_rsize,
- int u_psize, int u_rsize, int v_psize, int v_rsize,
- int cu, int q, int b);
-
-int jpeg_enc_frame(jpeg_enc_t *j, unsigned char *y_data,
- unsigned char *u_data, unsigned char *v_data, char *bufr);
-
-void jpeg_enc_uninit(jpeg_enc_t *j);
-
-#endif /* MPLAYER_JPEG_ENC_H */
diff --git a/libvo/video_out.c b/libvo/video_out.c
index caf916d197..679d111e6f 100644
--- a/libvo/video_out.c
+++ b/libvo/video_out.c
@@ -94,8 +94,6 @@ extern struct vo_driver video_out_tdfxfb;
extern struct vo_driver video_out_s3fb;
extern struct vo_driver video_out_wii;
extern struct vo_driver video_out_null;
-extern struct vo_driver video_out_zr;
-extern struct vo_driver video_out_zr2;
extern struct vo_driver video_out_bl;
extern struct vo_driver video_out_fbdev;
extern struct vo_driver video_out_fbdev2;
@@ -217,10 +215,6 @@ const struct vo_driver *video_out_drivers[] =
#ifdef CONFIG_V4L2_DECODER
&video_out_v4l2,
#endif
-#ifdef CONFIG_ZR
- &video_out_zr,
- &video_out_zr2,
-#endif
#ifdef CONFIG_BL
&video_out_bl,
#endif
diff --git a/libvo/vo_zr.c b/libvo/vo_zr.c
deleted file mode 100644
index 4cb1ed0de6..0000000000
--- a/libvo/vo_zr.c
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- * playback on Zoran cards
- * copyright (C) 2001, 2003 Rik Snel
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <linux/types.h>
-#include <linux/videodev.h>
-#include "config.h"
-#include "videodev_mjpeg.h"
-#include "video_out.h"
-#include "video_out_internal.h"
-#include "mp_msg.h"
-#include "m_option.h"
-#include "fastmemcpy.h"
-#include "jpeg_enc.h"
-#include "vo_zr.h"
-
-static const vo_info_t info =
-{
- "Zoran ZR360[56]7/ZR36060 Driver (DC10(+)/buz/lml33/MatroxRR)",
- "zr",
- "Rik Snel <rsnel@cube.dyndns.org>",
- ""
-};
-
-const LIBVO_EXTERN (zr)
-
-#define ZR_MAX_DEVICES 4
-/* General variables */
-
-typedef struct {
- int width;
- int height;
- int xoff;
- int yoff;
- int set;
-} geo_t;
-
-static int zr_count = 1;
-static int zr_parsing = 0;
-static int framenum;
-
-typedef struct {
- /* commandline args given for this device (and defaults) */
- int vdec, hdec; /* requested decimation 1,2,4 */
- int fd; /* force decimation */
- int xdoff, ydoff; /* offset from upperleft of screen
- * default is 'centered' */
- int quality; /* jpeg quality 1=best, 20=bad */
- geo_t g; /* view window (zrcrop) */
- char *device; /* /dev/video1 */
- int bw; /* if bw == 1, display in black&white */
- int norm; /* PAL/NTSC */
-
- /* buffers + pointers + info */
-
- unsigned char *image;
- int image_width, image_height, size;
- int off_y, off_c, stride; /* for use by 'draw slice/frame' */
-
- unsigned char *buf; /* the jpeg images will be placed here */
- jpeg_enc_t *j;
- unsigned char *y_data, *u_data, *v_data; /* used by the jpeg encoder */
- int y_stride, u_stride, v_stride; /* these point somewhere in image */
-
- /* information for (and about) the zoran card */
-
- int vdes; /* file descriptor of card */
- int frame, synco, queue; /* buffer management */
- struct mjpeg_sync zs; /* state information */
- struct mjpeg_params p;
- struct mjpeg_requestbuffers zrq;
- struct video_capability vc; /* max resolution and so on */
- int fields, stretchy; /* must the *image be interlaced
- or stretched to fit on the screen? */
-} zr_info_t;
-
-static zr_info_t zr_info[ZR_MAX_DEVICES] = {
- {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0,
- 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0,
- 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0,
- 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0,
- 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-
-
-
-
-#define MJPEG_NBUFFERS 2
-#define MJPEG_SIZE 1024*256
-
-
-int zoran_getcap(zr_info_t *zr) {
- char* dev = NULL;
-
- if (zr->device)
- dev = zr->device;
- else {
- struct stat vstat;
- const char *devs[] = {
- "/dev/video",
- "/dev/video0",
- "/dev/v4l/video0",
- "/dev/v4l0",
- "/dev/v4l",
- NULL
- };
- int i = 0;
-
- do
- {
- if ((stat(devs[i], &vstat) == 0) && S_ISCHR(vstat.st_mode))
- {
- dev = devs[i];
- mp_msg(MSGT_VO, MSGL_V, "zr: found video device %s\n", dev);
- break;
- }
- } while (devs[++i] != NULL);
-
- if (!dev)
- {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: unable to find video device\n");
- return 1;
- }
- }
-
- zr->vdes = open(dev, O_RDWR);
-
- if (zr->vdes < 0) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error opening %s: %s\n",
- dev, strerror(errno));
- return 1;
- }
-
- /* before we can ask for the maximum resolution, we must set
- * the correct tv norm */
-
- if (ioctl(zr->vdes, MJPIOC_G_PARAMS, &zr->p) < 0) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: device at %s is probably not a DC10(+)/buz/lml33\n", dev);
- return 1;
- }
-
- if (zr->p.norm != zr->norm && zr->norm != VIDEO_MODE_AUTO) {
- /* attempt to set requested norm */
- zr->p.norm = zr->norm;
- if (ioctl(zr->vdes, MJPIOC_S_PARAMS, &zr->p) < 0) {
- mp_msg(MSGT_VO, MSGL_ERR,
- "zr: unable to change video norm, use another program to change it (XawTV)\n");
- return 1;
- }
- ioctl(zr->vdes, MJPIOC_G_PARAMS, &zr->p);
- if (zr->norm != zr->p.norm) {
- mp_msg(MSGT_VO, MSGL_ERR,
- "zr: unable to change video norm, use another program to change it (XawTV)\n");
- return 1;
- }
- }
-
- if (ioctl(zr->vdes, VIDIOCGCAP, &zr->vc) < 0) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error getting video capabilities from %s\n", dev);
- return 1;
- }
- mp_msg(MSGT_VO, MSGL_V, "zr: MJPEG card reports maxwidth=%d, maxheight=%d\n", zr->vc.maxwidth, zr->vc.maxheight);
-
- return 0;
-}
-
-int init_zoran(zr_info_t *zr, int stretchx, int stretchy) {
- /* center the image, and stretch it as far as possible (try to keep
- * aspect) and check if it fits */
- if (zr->image_width > zr->vc.maxwidth) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: movie to be played is too wide, max width currently %d\n", zr->vc.maxwidth);
- return 1;
- }
-
- if (zr->image_height > zr->vc.maxheight) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: movie to be played is too high, max height currently %d\n", zr->vc.maxheight);
- return 1;
- }
-
- zr->p.decimation = 0;
- zr->p.HorDcm = stretchx;
- zr->p.VerDcm = stretchy;
- zr->p.TmpDcm = 1;
- zr->p.field_per_buff = zr->fields;
- if (zr->xdoff == -1) {
- zr->p.img_x = (zr->vc.maxwidth -
- zr->p.HorDcm*(int)zr->image_width/zr->hdec)/2;
- } else {
- zr->p.img_x = zr->xdoff;
- }
- if (zr->ydoff == -1) {
- zr->p.img_y = (zr->vc.maxheight - zr->p.VerDcm*
- (3-zr->fields)*(int)zr->image_height)/4;
- } else {
- zr->p.img_y = zr->ydoff;
- }
- zr->p.img_width = zr->p.HorDcm*zr->image_width/zr->hdec;
- zr->p.img_height = zr->p.VerDcm*zr->image_height/zr->fields;
- mp_msg(MSGT_VO, MSGL_V, "zr: geometry (after 'scaling'): %dx%d+%d+%d fields=%d, w=%d, h=%d\n", zr->p.img_width, (3-zr->fields)*zr->p.img_height, zr->p.img_x, zr->p.img_y, zr->fields, zr->image_width/zr->hdec, zr->image_height);
-
- if (ioctl(zr->vdes, MJPIOC_S_PARAMS, &zr->p) < 0) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error setting display parameters\n");
- return 1;
- }
-
- zr->zrq.count = MJPEG_NBUFFERS;
- zr->zrq.size = MJPEG_SIZE;
-
- if (ioctl(zr->vdes, MJPIOC_REQBUFS, &zr->zrq)) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error requesting %ld buffers of size %ld\n", zr->zrq.count, zr->zrq.size);
- return 1;
- }
-
- /* the buffer count allocated may be different to the request */
- zr->buf = (unsigned char*)mmap(0, zr->zrq.count*zr->zrq.size,
- PROT_READ|PROT_WRITE, MAP_SHARED, zr->vdes, 0);
-
- if (zr->buf == MAP_FAILED) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error requesting %ld buffers of size %ld\n", zr->zrq.count, zr->zrq.size);
- return 1;
- }
-
- mp_msg(MSGT_VO, MSGL_V, "zr: got %ld buffers of size %ld (wanted %d buffers of size %d)\n", zr->zrq.count, zr->zrq.size, MJPEG_NBUFFERS, MJPEG_SIZE);
- if (zr->zrq.count < MJPEG_NBUFFERS) {
- mp_msg(MSGT_VO, MSGL_V, "zr: got not enough buffers\n");
- return 1;
- }
-
- zr->queue = 0;
- zr->synco = 0;
-
- return 0;
-}
-
-void uninit_zoran(zr_info_t *zr) {
- free(zr->image);
- zr->image=NULL;
- while (zr->queue > zr->synco + 1) {
- if (ioctl(zr->vdes, MJPIOC_SYNC, &zr->zs) < 0)
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error waiting for buffers to become free\n");
- zr->synco++;
- }
- /* stop streaming */
- zr->frame = -1;
- if (ioctl(zr->vdes, MJPIOC_QBUF_PLAY, &zr->frame) < 0)
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error stopping playback of last frame\n");
- if (munmap(zr->buf,zr->zrq.count*zr->zrq.size))
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error unmapping buffer\n");
- close(zr->vdes);
-}
-
-int zr_geometry_sane(geo_t *g, unsigned int width, unsigned int height) {
- if (g->set) {
- if (g->width%2 != 0 || g->height%2 != 0 ||
- g->xoff%2 != 0 || g->yoff%2 != 0) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: arguments in -zrcrop must be multiples of 2\n");
- return 1;
- }
- if (g->width <= 0 || g->height <= 0 ||
- g->xoff < 0 || g->yoff < 0) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: width and height must be positive and offset nonnegative\n");
- return 1;
- }
- if (g->width + g->xoff > width) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: width+xoffset (%d+%d>%d) is too big\n", g->width, g->xoff, width);
- return 1;
- }
- if (g->height + g->yoff > height) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: height+yoffset (%d+%d>%d) is too big\n", g->height, g->yoff, height);
- return 1;
- }
- } else {
- g->width = width;
- g->height = height;
- g->xoff = 0;
- g->yoff = 0;
- g->set = 1;
- }
- return 0;
-}
-
-
-static int config(uint32_t width, uint32_t height, uint32_t d_width,
- uint32_t d_height, uint32_t flags, char *title, uint32_t format)
-{
- int i, tmp, stretchx, stretchy;
- framenum = 0;
- if (format != IMGFMT_YV12 && format != IMGFMT_YUY2) {
- printf("vo_zr called with wrong format");
- return 1;
- }
- for (i = 0; i < zr_count; i++) {
- zr_info_t *zr = &zr_info[i];
- geo_t *g = &zr->g;
-
- zr->stride = 2*width;
- if (zr_geometry_sane(g, width, height)) return 1;
-
- /* we must know the maximum resolution of the device
- * it differs for DC10+ and buz for example */
- zoran_getcap(zr); /*must be called before init_zoran */
- /* make the scaling decision
- * we are capable of stretching the image in the horizontal
- * direction by factors 1, 2 and 4
- * we can stretch the image in the vertical direction by a
- * factor of 1 and 2 AND we must decide about interlacing */
- if (g->width > zr->vc.maxwidth/2 ||
- g->height > zr->vc.maxheight/2) {
- stretchx = 1;
- stretchy = 1;
- zr->fields = 2;
- if (zr->vdec == 2) {
- zr->fields = 1;
- } else if (zr->vdec == 4) {
- zr->fields = 1;
- stretchy = 2;
- }
- stretchx = zr->hdec;
- } else if (g->width > zr->vc.maxwidth/4 ||
- g->height > zr->vc.maxheight/4) {
- stretchx = 2;
- stretchy = 1;
- zr->fields = 1;
- if (zr->vdec == 2) {
- stretchy = 2;
- } else if (zr->vdec == 4) {
- if (!zr->fd) {
- mp_msg(MSGT_VO, MSGL_WARN, "zr: vertical decimation too high, changing to 2 (use -zrfd to keep vdec=4)\n");
- zr->vdec = 2;
- }
- stretchy = 2;
- }
- if (zr->hdec == 2) {
- stretchx = 4;
- } else if (zr->hdec == 4){
- if (!zr->fd) {
- mp_msg(MSGT_VO, MSGL_WARN, "zr: horizontal decimation too high, changing to 2 (use -zrfd to keep hdec=4)\n");
- zr->hdec = 2;
- }
- stretchx = 4;
- }
- } else {
- /* output image is maximally stretched */
- stretchx = 4;
- stretchy = 2;
- zr->fields = 1;
- if (zr->vdec != 1 && !zr->fd) {
- mp_msg(MSGT_VO, MSGL_WARN, "zr: vertical decimation too high, changing to 1 (use -zrfd to keep vdec=%d)\n", zr->vdec);
- zr->vdec = 1;
- }
- if (zr->hdec != 1 && !zr->fd) {
- mp_msg(MSGT_VO, MSGL_WARN, "zr: vertical decimation too high, changing to 1 (use -zrfd to keep hdec=%d)\n", zr->hdec);
- zr->hdec = 1;
- }
- }
- /* It can be that the original frame was too big for display,
- * or that the width of the decimated image (for example) after
- * padding up to a multiple of 16 has become too big. (orig
- * width 720 (exactly right for the Buz) after decimation 360,
- * after padding up to a multiple of 16 368, display 736 -> too
- * large). In these situations we auto(re)crop. */
- tmp = 16*((g->width - 1)/(zr->hdec*16) + 1);
- if (stretchx*tmp > zr->vc.maxwidth) {
- g->xoff += 2*((g->width - zr->hdec*(tmp-16))/4);
- /* g->off must be a multiple of 2 */
- g->width = zr->hdec*(tmp - 16);
- g->set = 0; /* we abuse this field to
- report that g has changed*/
- }
- tmp = 8*zr->fields*((g->height - 1)/(zr->vdec*zr->fields*8)+1);
- if (stretchy*tmp > zr->vc.maxheight) {
- g->yoff += 2*((g->height - zr->vdec*
- (tmp - 8*zr->fields))/4);
- g->height = zr->vdec*(tmp - 8*zr->fields);
- g->set = 0;
- }
- if (!g->set)
- mp_msg(MSGT_VO, MSGL_V, "zr: auto(re)cropping %dx%d+%d+%d to make the image fit on the screen\n", g->width, g->height, g->xoff, g->yoff);
-
- /* the height must be a multiple of fields*8 and the width
- * must be a multiple of 16 */
- /* add some black borders to make it so, and center the image*/
- zr->image_height = zr->fields*8*((g->height/zr->vdec - 1)/
- (zr->fields*8) + 1);
- zr->image_width = (zr->hdec*16)*((g->width - 1)/(zr->hdec*16) + 1);
- zr->off_y = (zr->image_height - g->height/zr->vdec)/2;
- if (zr->off_y%2 != 0) zr->off_y++;
- zr->off_y *= zr->image_width;
- zr->off_c = zr->off_y/4;
- zr->off_y += (zr->image_width - g->width)/2;
- if (zr->off_y%2 != 0) zr->off_y--;
- zr->off_c += (zr->image_width - g->width)/4;
- zr->size = zr->image_width*zr->image_height;
- mp_msg(MSGT_VO, MSGL_V, "zr: input: %dx%d, cropped: %dx%d, output: %dx%d, off_y=%d, off_c=%d\n", width, height, g->width, g->height, zr->image_width, zr->image_height, zr->off_y, zr->off_c);
-
- zr->image = malloc(2*zr->size); /* this buffer allows for YUV422 data,
- * so it is a bit too big for YUV420 */
- if (!zr->image) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: Memory exhausted\n");
- return 1;
- }
- /* and make sure that the borders are _really_ black */
- switch (format) {
- case IMGFMT_YV12:
- memset(zr->image, 0, zr->size);
- memset(zr->image + zr->size, 0x80, zr->size/4);
- memset(zr->image + 3*zr->size/2, 0x80, zr->size/4);
- zr->y_data = zr->image;
- zr->u_data = zr->image + zr->size;
- zr->v_data = zr->image + 3*zr->size/2;
-
- zr->y_stride = zr->image_width;
- zr->u_stride = zr->image_width/2;
- zr->v_stride = zr->image_width/2;
-
- zr->j = jpeg_enc_init(zr->image_width/zr->hdec,
- zr->image_height/zr->fields,
- zr->hdec, zr->y_stride*zr->fields,
- zr->hdec, zr->u_stride*zr->fields,
- zr->hdec, zr->v_stride*zr->fields,
- 1, zr->quality, zr->bw);
- break;
- case IMGFMT_YUY2:
- for (tmp = 0; tmp < 2*zr->size; tmp+=4) {
- zr->image[tmp] = 0;
- zr->image[tmp+1] = 0x80;
- zr->image[tmp+2] = 0;
- zr->image[tmp+3] = 0x80;
- }
-
- zr->y_data = zr->image;
- zr->u_data = zr->image + 1;
- zr->v_data = zr->image + 3;
-
- zr->y_stride = 2*zr->image_width;
- zr->u_stride = 2*zr->image_width;
- zr->v_stride = 2*zr->image_width;
-
- zr->j = jpeg_enc_init(zr->image_width/zr->hdec,
- zr->image_height/zr->fields,
- zr->hdec*2,
- zr->y_stride*zr->fields,
- zr->hdec*4,
- zr->u_stride*zr->fields,
- zr->hdec*4,
- zr->v_stride*zr->fields,
- 0, zr->quality, zr->bw);
- break;
- default:
- mp_msg(MSGT_VO, MSGL_FATAL, "zr: internal inconsistency in vo_zr\n");
- }
-
-
- if (zr->j == NULL) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error initializing the jpeg encoder\n");
- return 1;
- }
-
- if (init_zoran(zr, stretchx, stretchy)) {
- return 1;
- }
-
- }
- return 0;
-}
-
-static void draw_osd(void) {
-}
-
-static void flip_page (void) {
- int i, j, k;
- //FILE *fp;
- //char filename[100];
- /* do we have a free buffer? */
- for (j = 0; j < zr_count; j++) {
- zr_info_t *zr = &zr_info[j];
- /* using MJPEG_NBUFFERS here, using the real number of
- * buffers may give sync issues (real number of buffers
- * is always sufficient) */
- if (zr->queue-zr->synco < MJPEG_NBUFFERS) {
- zr->frame = zr->queue;
- } else {
- if (ioctl(zr->vdes, MJPIOC_SYNC, &zr->zs) < 0)
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error waiting for buffers to become free\n");
- zr->frame = zr->zs.frame;
- zr->synco++;
- }
- k=0;
- for (i = 0; i < zr->fields; i++)
- k+=jpeg_enc_frame(zr->j, zr->y_data + i*zr->y_stride,
- zr->u_data + i*zr->u_stride,
- zr->v_data + i*zr->v_stride,
- zr->buf + zr->frame*zr->zrq.size+k);
- if (k > zr->zrq.size) mp_msg(MSGT_VO, MSGL_WARN, "zr: jpeg image too large for maximum buffer size. Lower the jpeg encoding\nquality or the resolution of the movie.\n");
- }
- /* Warning: Only the first jpeg image contains huffman- and
- * quantisation tables, so don't expect files other than
- * test0001.jpg to be readable */
- /*sprintf(filename, "test%04d.jpg", framenum);
- fp = fopen(filename, "w");
- if (!fp) exit(1);
- fwrite(buf+frame*zrq.size, 1, k, fp);
- fclose(fp);*/
- /*fp = fopen("test1.jpg", "r");
- fread(buf+frame*zrq.size, 1, 2126, fp);
- fclose(fp);*/
-
- for (j = 0; j < zr_count; j++) {
- zr_info_t *zr = &zr_info[j];
- if (ioctl(zr->vdes, MJPIOC_QBUF_PLAY, &zr->frame) < 0)
- mp_msg(MSGT_VO, MSGL_ERR, "zr: error queueing buffer for playback\n");
- zr->queue++;
- }
-
- framenum++;
- return;
-}
-
-static int draw_frame(uint8_t * src[]) {
- int i, j;
- char *source, *dest;
- //printf("draw frame called\n");
- for (j = 0; j < zr_count; j++) {
- zr_info_t *zr = &zr_info[j];
- geo_t *g = &zr->g;
- source = src[0] + 2*g->yoff*zr->vdec*zr->stride + 2*g->xoff;
- dest = zr->image + 2*zr->off_y;
- for (i = 0; i < g->height/zr->vdec; i++) {
- fast_memcpy(dest, source, zr->image_width*2);
- dest += 2*zr->image_width;
- source += zr->vdec*zr->stride;
- }
- }
- return 0;
-}
-
-static int query_format(uint32_t format) {
- if(format==IMGFMT_YV12 || format==IMGFMT_YUY2)
- return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW;
- return 0;
-}
-
-static void uninit(void) {
- int j;
- mp_msg(MSGT_VO, MSGL_V, "zr: uninit called\n");
- for (j = 0; j < zr_count; j++) {
- jpeg_enc_uninit(zr_info[j].j);
- uninit_zoran(&zr_info[j]);
- }
-}
-
-static void check_events(void) {
-}
-
-
-static int draw_slice(uint8_t *srcimg[], int stride[],
- int wf, int hf, int xf, int yf) {
- int i, j, w, h, x, y;
- /* Apply 'geometry', crop unwanted parts */
- uint8_t *dst;
- //printf("before: w=%d, h=%d, x=%d, y=%d, src0=%p, src1=%p, src2=%p\n", w, h, x, y, srcimg[0], srcimg[1], srcimg[2]);
- for (j = 0; j < zr_count; j++) {
- uint8_t *src=srcimg[0];
- uint8_t *src1=srcimg[1];
- uint8_t *src2=srcimg[2];
- zr_info_t *zr = &zr_info[j];
- geo_t *g = &zr->g;
- w = wf; h = hf; x = xf; y = yf;
- if (x < g->xoff) {
- src += g->xoff - x;
- src1 += (g->xoff - x)/2;
- src2 += (g->xoff - x)/2;
- w -= g->xoff - x;
- if (w < 0) break; //return 0;
- x = 0 /*g.xoff*/;
- } else {
- x -= g->xoff;
- }
- if (x + w > g->width) {
- w = g->width - x;
- if (w < 0) break; //return 0;
- }
- if (y < g->yoff) {
- src += (g->yoff - y)*stride[0];
- src1 += ((g->yoff - y)/2)*stride[1];
- src2 += ((g->yoff - y)/2)*stride[2];
- h -= g->yoff - y;
- if (h < 0) break; //return 0;
- y = 0;
- } else {
- y -= g->yoff;
- }
- if (y + h > g->height) {
- h = g->height - y;
- if (h < 0) break; //return 0;
- }
- //printf("after: w=%d, h=%d, x=%d, y=%d, src0=%p, src1=%p, src2=%p\n", w, h, x, y, srcimg[0], srcimg[1], srcimg[2]);
- dst=zr->image + zr->off_y + zr->image_width*(y/zr->vdec)+x;
- // copy Y:
- for (i = 0; i < h; i++) {
- if ((i + x)%zr->vdec == 0) {
- fast_memcpy(dst,src,w);
- dst+=zr->image_width;
- }
- src+=stride[0];
-
- }
- if (!zr->bw) {
- // copy U+V:
- uint8_t *dst1=zr->image + zr->size + zr->off_c+ (y/(zr->vdec*2))*zr->image_width/2+(x/2);
- uint8_t *dst2=zr->image + 3*zr->size/2 + zr->off_c +
- (y/(zr->vdec*2))*
- zr->image_width/2+(x/2);
- for (i = 0; i< h/2; i++) {
- if ((i+x/2)%zr->vdec == 0) {
- fast_memcpy(dst1,src1,w/2);
- fast_memcpy(dst2,src2,w/2);
- dst1+=zr->image_width/2;
- dst2+=zr->image_width/2;
- }
- src1+=stride[1];
- src2+=stride[2];
- }
- }
- }
- return 0;
-}
-
-
-/* copied and adapted from vo_aa_parseoption */
-int
-vo_zr_parseoption(const m_option_t* conf, const char *opt, const char *param){
- /* got an option starting with zr */
- zr_info_t *zr = &zr_info[zr_parsing];
- int i;
- /* do WE need it ?, always */
- if (!strcasecmp(opt, "zrdev")) {
- if (param == NULL) return ERR_MISSING_PARAM;
- //if ((i=getcolor(param))==-1) return ERR_OUT_OF_RANGE;
- //aaopt_osdcolor=i;
- free(zr->device);
- zr->device = malloc(strlen(param)+1);
- strcpy(zr->device, param);
- mp_msg(MSGT_VO, MSGL_V, "zr: using device %s\n", zr->device);
- return 1;
- } else if (!strcasecmp(opt, "zrbw")) {
- if (param != NULL) {
- return ERR_OUT_OF_RANGE;
- }
- zr->bw = 1;
- return 1;
- } else if (!strcasecmp(opt, "zrfd")) {
- if (param != NULL) {
- return ERR_OUT_OF_RANGE;
- }
- zr->fd = 1;
- return 1;
- } else if (!strcasecmp(opt, "zrcrop")){
- geo_t *g = &zr->g;
- if (g->set == 1) {
- zr_parsing++;
- zr_count++;
- zr = &zr_info[zr_parsing];
- g = &zr->g;
- if (zr_count > 4) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: too many simultaneus display devices requested (max. is 4)\n");
- return ERR_OUT_OF_RANGE;
- }
- }
- if (param == NULL) return ERR_MISSING_PARAM;
- if (sscanf(param, "%dx%d+%d+%d", &g->width, &g->height,
- &g->xoff, &g->yoff) != 4) {
- g->xoff = 0; g->yoff = 0;
- if (sscanf(param, "%dx%d", &g->width, &g->height) != 2) {
- mp_msg(MSGT_VO, MSGL_ERR, "zr: argument to -zrcrop must be of the form 352x288+16+0\n");
- return ERR_OUT_OF_RANGE;
- }
- }
- g->set = 1;
- mp_msg(MSGT_VO, MSGL_V, "zr: cropping %s\n", param);
- return 1;
- }else if (!strcasecmp(opt, "zrhdec")) {
- i = atoi(param);
- if (i != 1 && i != 2 && i != 4) return ERR_OUT_OF_RANGE;
- zr->hdec = i;
- return 1;
- }else if (!strcasecmp(opt, "zrvdec")) {
- i = atoi(param);
- if (i != 1 && i != 2 && i != 4) return ERR_OUT_OF_RANGE;
- zr->vdec = i;
- return 1;
- }else if (!strcasecmp(opt, "zrxdoff")) {
- i = atoi(param);
- zr->xdoff = i;
- return 1;
- }else if (!strcasecmp(opt, "zrydoff")) {
- i = atoi(param);
- zr->ydoff = i;
- return 1;
- }else if (!strcasecmp(opt, "zrquality")) {
- i = atoi(param);
- if (i < 1 || i > 20) return ERR_OUT_OF_RANGE;
- zr->quality = i;
- return 1;
- }else if (!strcasecmp(opt, "zrnorm")) {
- if (param == NULL) return ERR_MISSING_PARAM;
- if (!strcasecmp(param, "NTSC")) {
- mp_msg(MSGT_VO, MSGL_V, "zr: Norm set to NTSC\n");
- zr->norm = VIDEO_MODE_NTSC;
- return 1;
- } else if (!strcasecmp(param, "PAL")) {
- mp_msg(MSGT_VO, MSGL_V, "zr: Norm set to PAL\n");
- zr->norm = VIDEO_MODE_PAL;
- return 1;
- } else {
- return ERR_OUT_OF_RANGE;
- }
- }else if (!strcasecmp(opt, "zrhelp")){
- printf("Help for -vo zr: Zoran ZR360[56]7/ZR36060 based MJPEG capture/playback cards\n");
- printf("\n");
- printf("Here are the zr options:\n");
- printf(
- "\n"
- " -zrcrop specify part of the input image that\n"
- " you want to see as an x-style geometry string\n"
- " example: -zrcrop 352x288+16+0\n"
- " -zrvdec vertical decimation 1, 2 or 4\n"
- " -zrhdec horizontal decimation 1, 2 or 4\n"
- " -zrfd decimation is only done if the primitive\n"
- " hardware upscaler can correct for the decimation,\n"
- " this switch allows you to see the effects\n"
- " of too much decimation\n"
- " -zrbw display in black&white (speed increase)\n"
- " -zrxdoff x offset from upper-left of TV screen (default is 'centered')\n"
- " -zrydoff y offset from upper-left of TV screen (default is 'centered')\n"
- " -zrquality jpeg compression quality [BEST] 1 - 20 [VERY BAD]\n"
- " -zrdev playback device (example -zrdev /dev/video1)\n"
- " -zrnorm specify norm PAL/NTSC (default: leave at current setting)\n"
- "\n"
- "Cinerama support: additional occurances of -zrcrop activate cinerama mode,\n"
- "suppose you have a 704x272 movie, two DC10+ cards and two beamers (or tv's),\n"
- "then you would issue the following command:\n\n"
- "mplayer -vo zr -zrcrop 352x272+0+0 -zrdev /dev/video0 -zrcrop 352x272+352+0 \\\n"
- " -zrdev /dev/video1 movie.avi\n\n"
- "Options appearing after the second -zrcrop apply to the second card, it is\n"
- "possible to dispay at a different jpeg quality or at different decimations.\n\n"
- "The parameters -zrxdoff and -zrydoff can be used to align the two images.\n"
- "The maximum number of zoran cards participating in cinerama is 4, so you can\n"
- "build a 2x2 vidiwall. (untested for obvious reasons, the setup wit a buz and\n"
- "a DC10+ (and no beamers) is tested, however)\n"
- );
- exit(0);
-
- }
- return ERR_NOT_AN_OPTION;
-}
-
-void vo_zr_revertoption(const m_option_t* opt,const char* param) {
-
- zr_info_t *zr = &zr_info[1];
- zr_count = 1;
- zr_parsing = 0;
-
- if (!strcasecmp(param, "zrdev")) {
- free(zr->device);
- zr->device=NULL;
- } else if (!strcasecmp(param, "zrbw"))
- zr->bw=0;
- else if (!strcasecmp(param, "zrfd"))
- zr->fd=0;
- else if (!strcasecmp(param, "zrcrop"))
- zr->g.set = zr->g.xoff = zr->g.yoff = 0;
- else if (!strcasecmp(param, "zrhdec"))
- zr->hdec = 1;
- else if (!strcasecmp(param, "zrvdec"))
- zr->vdec = 1;
- else if (!strcasecmp(param, "zrxdoff"))
- zr->xdoff = -1;
- else if (!strcasecmp(param, "zrydoff"))
- zr->ydoff = -1;
- else if (!strcasecmp(param, "zrquality"))
- zr->quality = 2;
- else if (!strcasecmp(param, "zrnorm"))
- zr->norm = VIDEO_MODE_AUTO;
-
-}
-
-static int preinit(const char *arg)
-{
- if(arg)
- {
- printf("vo_zr: Unknown subdevice: %s\n",arg);
- return ENOSYS;
- }
- return 0;
-}
-
-static int control(uint32_t request, void *data)
-{
- switch (request) {
- case VOCTRL_QUERY_FORMAT:
- return query_format(*((uint32_t*)data));
- }
- return VO_NOTIMPL;
-}
diff --git a/libvo/vo_zr.h b/libvo/vo_zr.h
deleted file mode 100644
index ce13f0fb41..0000000000
--- a/libvo/vo_zr.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * playback on Zoran cards
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_VO_ZR_H
-#define MPLAYER_VO_ZR_H
-
-#include "m_option.h"
-
-int vo_zr_parseoption(const m_option_t *conf, const char *opt, const char *param);
-void vo_zr_revertoption(const m_option_t *opt, const char *param);
-
-#endif /* MPLAYER_VO_ZR_H */
diff --git a/libvo/vo_zr2.c b/libvo/vo_zr2.c
deleted file mode 100644
index 57addb03f1..0000000000
--- a/libvo/vo_zr2.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * playback on Zoran cards, based on vo_zr.c
- *
- * copyright (C) 2001-2005 Rik Snel
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <linux/types.h>
-#include <linux/videodev.h>
-#include "config.h"
-#include "videodev_mjpeg.h"
-#include "video_out.h"
-#include "video_out_internal.h"
-#include "mp_msg.h"
-#include "subopt-helper.h"
-#include "fastmemcpy.h"
-
-static const vo_info_t info = {
- "Zoran ZR360[56]7/ZR36060 Driver (DC10(+)/buz/lml33/MatroxRR)",
- "zr2",
- "Rik Snel <rsnel@cube.dyndns.org>",
- ""
-};
-
-const LIBVO_EXTERN(zr2)
-
-typedef struct {
- /* options */
- char *subdevice;
-
- /* information for (and about) the zoran card */
-
- unsigned char *buf; /* the JPEGs will be placed here */
- struct mjpeg_requestbuffers zrq; /* info about this buffer */
-
- int vdes; /* file descriptor of card */
- int playing; /* 0 or 1 */
- int frame, sync, queue; /* buffer management */
- struct mjpeg_sync zs; /* state information */
- struct mjpeg_params zp;
- struct video_capability vc; /* max resolution and so on */
-} vo_zr2_priv_t;
-
-static vo_zr2_priv_t priv;
-
-#define ZR2_MJPEG_NBUFFERS 2
-#define ZR2_MJPEG_SIZE 1024*256
-
-/* some convenient #define's, is this portable enough? */
-#define DBG2(...) mp_msg(MSGT_VO, MSGL_DBG2, "vo_zr2: " __VA_ARGS__)
-#define VERBOSE(...) mp_msg(MSGT_VO, MSGL_V, "vo_zr2: " __VA_ARGS__)
-#define ERROR(...) mp_msg(MSGT_VO, MSGL_ERR, "vo_zr2: " __VA_ARGS__)
-#define WARNING(...) mp_msg(MSGT_VO, MSGL_WARN, "vo_zr2: " __VA_ARGS__)
-
-static void stop_playing(vo_zr2_priv_t *p) {
- if (p->playing) {
- p->frame = -1;
- if (ioctl(p->vdes, MJPIOC_QBUF_PLAY, &p->frame) < 0)
- ERROR("error stopping playback\n");
- p->playing = 0;
- p->sync = 0;
- p->queue = 0;
- p->frame = 0;
- }
-}
-
-static const char *guess_device(const char *suggestion, int inform) {
- struct stat vstat;
- int res;
- static const char * const devs[] = {
- "/dev/video",
- "/dev/video0",
- "/dev/v4l/video0",
- "/dev/v4l0",
- "/dev/v4l",
- NULL
- };
- const char * const *dev = devs;
-
- if (suggestion) {
- if (!*suggestion) {
- ERROR("error: specified device name is empty string\n");
- return NULL;
- }
-
- res = stat(suggestion, &vstat);
- if (res == 0 && S_ISCHR(vstat.st_mode)) {
- if (inform) VERBOSE("using device %s\n", suggestion);
- return suggestion;
- } else {
- if (res != 0) ERROR("%s does not exist\n", suggestion);
- else ERROR("%s is no character device\n", suggestion);
- /* don't try to be smarter than the user, just exit */
- return NULL;
- }
- }
-
- while (*(++dev) != NULL) {
- if (stat(*dev, &vstat) == 0 && S_ISCHR(vstat.st_mode)) {
- VERBOSE("guessed video device %s\n", *dev);
- return *dev;
- }
- dev++;
- }
-
- ERROR("unable to find video device\n");
-
- return NULL;
-}
-
-static int query_format(uint32_t format) {
- if (format==IMGFMT_ZRMJPEGNI ||
- format==IMGFMT_ZRMJPEGIT ||
- format==IMGFMT_ZRMJPEGIB)
- return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW;
- return 0;
-}
-
-static uint32_t draw_image(mp_image_t *mpi) {
- vo_zr2_priv_t *p = &priv;
- int size = (int)mpi->planes[1];
- if (size > (int)p->zrq.size) {
- ERROR("incoming JPEG image (size=%d) doesn't fit in buffer\n",
- size);
- return VO_FALSE;
- }
-
- /* looking for free buffer */
- if (p->queue - p->sync < (int)p->zrq.count) p->frame = p->queue;
- else {
- if (ioctl(p->vdes, MJPIOC_SYNC, &p->zs) < 0) {
- ERROR("error waiting for buffer to become free\n");
- return VO_FALSE;
- }
- p->frame = p->zs.frame;
- p->sync++;
- }
-
- /* copy the jpeg image to the buffer which we acquired */
- fast_memcpy(p->buf + p->zrq.size*p->frame, mpi->planes[0], size);
-
- return VO_TRUE;
-}
-
-static const char *normstring(int norm) {
- switch (norm) {
- case VIDEO_MODE_PAL:
- return "PAL";
- case VIDEO_MODE_NTSC:
- return "NTSC";
- case VIDEO_MODE_SECAM:
- return "SECAM";
- case VIDEO_MODE_AUTO:
- return "auto";
- }
- return "undefined";
-}
-
-static int get_norm(const char *n) {
- if (!strcmp(n, "PAL")) return VIDEO_MODE_PAL;
- if (!strcmp(n, "NTSC")) return VIDEO_MODE_NTSC;
- if (!strcmp(n, "SECAM")) return VIDEO_MODE_SECAM;
- if (!strcmp(n, "auto")) return VIDEO_MODE_AUTO;
- return -1; /* invalid */
-}
-
-static int nc(void *normp) {
- const char **norm = normp;
- if (get_norm(*norm) == -1) {
- ERROR("norm \"%s\" is not supported, choose from PAL, NTSC, SECAM and auto\n", *norm);
- return 0;
- } else return 1;
-}
-
-static int pbc(void *prebufp) {
- int *prebuf = prebufp;
- if (*prebuf) WARNING("prebuffering is not yet supported\n");
- return 1;
-}
-
-static int preinit(const char *arg) {
- vo_zr2_priv_t *p = &priv;
- const char *dev = NULL;
- char *dev_arg = NULL, *norm_arg = NULL;
- int norm = VIDEO_MODE_AUTO, prebuf = 0;
- const opt_t subopts[] = { /* don't want warnings with -Wall... */
- { "dev", OPT_ARG_MSTRZ, &dev_arg, NULL },
- { "prebuf", OPT_ARG_BOOL, &prebuf, pbc },
- { "norm", OPT_ARG_MSTRZ, &norm_arg, nc },
- { NULL, 0, NULL, NULL }
- };
-
- VERBOSE("preinit() called with arg: %s\n", arg);
- memset(p, 0, sizeof(*p)); /* set defaults */
- p->vdes = -1;
-
- if (subopt_parse(arg, subopts)) {
- mp_msg(MSGT_VO, MSGL_FATAL,
- "Allowed suboptions for -vo zr2 are:\n"
- "- dev=DEVICE (default: %s)\n"
- "- norm=PAL|NTSC|SECAM|auto (default: auto)\n"
- "- prebuf/noprebuf (default:"
- " noprebuf)\n"
- "\n"
- "Example: mplayer -vo zr2:dev=/dev/video1:"
- "norm=PAL movie.avi\n\n"
- , guess_device(NULL, 0));
- free(norm_arg);
- free(dev_arg);
- return -1;
- }
-
- /* interpret the strings we got from subopt_parse */
- if (norm_arg) {
- norm = get_norm(norm_arg);
- free(norm_arg);
- }
-
- if (dev_arg) dev = dev_arg;
-
- dev = guess_device(dev, 1);
- if (!dev) {
- free(dev_arg);
- uninit();
- return 1;
- }
-
- p->vdes = open(dev, O_RDWR);
- if (p->vdes < 0) {
- ERROR("error opening %s: %s\n", dev, strerror(errno));
- free(dev_arg);
- uninit();
- return 1;
- }
-
- free(dev_arg);
-
- /* check if we really are dealing with a zoran card */
- if (ioctl(p->vdes, MJPIOC_G_PARAMS, &p->zp) < 0) {
- ERROR("%s probably is not a DC10(+)/buz/lml33\n", dev);
- uninit();
- return 1;
- }
-
- VERBOSE("kernel driver version %d.%d, current norm is %s\n",
- p->zp.major_version, p->zp.minor_version,
- normstring(p->zp.norm));
-
- /* changing the norm in the zoran_params and MJPIOC_S_PARAMS
- * does nothing the last time I tried, so bail out if the norm
- * is not correct */
- if (norm != VIDEO_MODE_AUTO && p->zp.norm != norm) {
- ERROR("mplayer currently can't change the video norm, "
- "change it with (eg.) XawTV and retry.\n");
- uninit();
- return 1;
- }
-
- /* gather useful information */
- if (ioctl(p->vdes, VIDIOCGCAP, &p->vc) < 0) {
- ERROR("error getting video capabilities from %s\n", dev);
- uninit();
- return 1;
- }
-
- VERBOSE("card reports maxwidth=%d, maxheight=%d\n",
- p->vc.maxwidth, p->vc.maxheight);
-
- /* according to the mjpegtools source, some cards return a bogus
- * vc.maxwidth, correct it here. If a new zoran card appears with a
- * maxwidth different 640, 720 or 768 this code may lead to problems */
- if (p->vc.maxwidth != 640 && p->vc.maxwidth != 768) {
- VERBOSE("card probably reported bogus width (%d), "
- "changing to 720\n", p->vc.maxwidth);
- p->vc.maxwidth = 720;
- }
-
- p->zrq.count = ZR2_MJPEG_NBUFFERS;
- p->zrq.size = ZR2_MJPEG_SIZE;
-
- if (ioctl(p->vdes, MJPIOC_REQBUFS, &p->zrq)) {
- ERROR("error requesting %d buffers of size %d\n",
- ZR2_MJPEG_NBUFFERS, ZR2_MJPEG_NBUFFERS);
- uninit();
- return 1;
- }
-
- VERBOSE("got %ld buffers of size %ld (wanted %d buffers of size %d)\n",
- p->zrq.count, p->zrq.size, ZR2_MJPEG_NBUFFERS,
- ZR2_MJPEG_SIZE);
-
- p->buf = (unsigned char*)mmap(0, p->zrq.count*p->zrq.size,
- PROT_READ|PROT_WRITE, MAP_SHARED, p->vdes, 0);
-
- if (p->buf == MAP_FAILED) {
- ERROR("error mapping requested buffers: %s", strerror(errno));
- uninit();
- return 1;
- }
-
- return 0;
-}
-
-static int config(uint32_t width, uint32_t height, uint32_t d_width,
- uint32_t d_height, uint32_t flags, char *title, uint32_t format) {
- int fields = 1, top_first = 1, err = 0;
- int stretchx = 1, stretchy = 1;
- struct mjpeg_params zptmp;
- vo_zr2_priv_t *p = &priv;
- VERBOSE("config() called\n");
-
- /* paranoia check */
- if (!query_format(format)) {
- ERROR("called with wrong format, should be impossible\n");
- return 1;
- }
-
- if ((int)height > p->vc.maxheight) {
- ERROR("input height %d is too large, maxheight=%d\n",
- height, p->vc.maxheight);
- err = 1;
- }
-
- if (format != IMGFMT_ZRMJPEGNI) {
- fields = 2;
- if (format == IMGFMT_ZRMJPEGIB)
- top_first = 0;
- } else if ((int)height > p->vc.maxheight/2) {
- ERROR("input is too high (%d) for non-interlaced playback"
- "max=%d\n", height, p->vc.maxheight);
- err = 1;
- }
-
- if (width%16 != 0) {
- ERROR("input width=%d, must be multiple of 16\n", width);
- err = 1;
- }
-
- if (height%(fields*8) != 0) {
- ERROR("input height=%d, must be multiple of %d\n",
- height, 2*fields);
- err = 1;
- }
-
- /* we assume sample_aspect = 1 */
- if (fields == 1) {
- if (2*d_width <= (uint32_t)p->vc.maxwidth) {
- VERBOSE("stretching x direction to preserve aspect\n");
- d_width *= 2;
- } else VERBOSE("unable to preserve aspect, screen width "
- "too small\n");
- }
-
- if (d_width == width) stretchx = 1;
- else if (d_width == 2*width) stretchx = 2;
-#if 0 /* do minimal stretching for now */
- else if (d_width == 4*width) stretchx = 4;
- else WARNING("d_width must be {1,2,4}*width, using defaults\n");
-
- if (d_height == height) stretchy = 1;
- else if (d_height == 2*height) stretchy = 2;
- else if (d_height == 4*height) stretchy = 4;
- else WARNING("d_height must be {1,2,4}*height, using defaults\n");
-#endif
-
- if (stretchx*width > (uint32_t)p->vc.maxwidth) {
- ERROR("movie to be played is too wide, width=%d>maxwidth=%d\n",
- width*stretchx, p->vc.maxwidth);
- err = 1;
- }
-
- if (stretchy*height > (uint32_t)p->vc.maxheight) {
- ERROR("movie to be played is too heigh, height=%d>maxheight"
- "=%d\n", height*stretchy, p->vc.maxheight);
- err = 1;
- }
-
- if (err == 1) return 1;
-
- /* some video files (eg. concatenated MPEG files), make MPlayer
- * call config() during playback while no parameters have changed.
- * We make configuration changes to a temporary params structure,
- * compare it with the old params structure and only apply the new
- * config if it is different from the old one. */
- memcpy(&zptmp, &p->zp, sizeof(zptmp));
-
- /* translate the configuration to zoran understandable format */
- zptmp.decimation = 0;
- zptmp.HorDcm = stretchx;
- zptmp.VerDcm = stretchy;
- zptmp.TmpDcm = 1;
- zptmp.field_per_buff = fields;
- zptmp.odd_even = top_first;
-
- /* center the image on screen */
- zptmp.img_x = (p->vc.maxwidth - width*stretchx)/2;
- zptmp.img_y = (p->vc.maxheight - height*stretchy*(3-fields))/4;
-
- zptmp.img_width = stretchx*width;
- zptmp.img_height = stretchy*height/fields;
-
- VERBOSE("tv: %dx%d, out: %dx%d+%d+%d, in: %ux%u %s%s%s\n",
- p->vc.maxwidth, p->vc.maxheight,
- zptmp.img_width, 2*zptmp.img_height,
- zptmp.img_x, 2*zptmp.img_y,
- width, height, (fields == 1) ? "non-interlaced" : "",
- (fields == 2 && top_first == 1)
- ? "interlaced top first" : "",
- (fields == 2 && top_first == 0)
- ? "interlaced bottom first" : "");
-
- if (memcmp(&zptmp, &p->zp, sizeof(zptmp))) {
- /* config differs, we must update */
- memcpy(&p->zp, &zptmp, sizeof(zptmp));
- stop_playing(p);
- if (ioctl(p->vdes, MJPIOC_S_PARAMS, &p->zp) < 0) {
- ERROR("error writing display params to card\n");
- return 1;
- }
- VERBOSE("successfully written display parameters to card\n");
- } else VERBOSE("config didn't change, no need to write it to card\n");
-
- return 0;
-}
-
-static int control(uint32_t request, void *data) {
- switch (request) {
- case VOCTRL_QUERY_FORMAT:
- return query_format(*((uint32_t*)data));
- case VOCTRL_DRAW_IMAGE:
- return draw_image(data);
- }
- return VO_NOTIMPL;
-}
-
-static int draw_frame(uint8_t *src[]) {
- return 0;
-}
-
-static int draw_slice(uint8_t *image[], int stride[],
- int w, int h, int x, int y) {
- return 0;
-}
-
-static void draw_osd(void) {
-}
-
-static void flip_page(void) {
- vo_zr2_priv_t *p = &priv;
- /* queueing the buffer for playback */
- /* queueing the first buffer automatically starts playback */
- if (p->playing == 0) p->playing = 1;
- if (ioctl(p->vdes, MJPIOC_QBUF_PLAY, &p->frame) < 0)
- ERROR("error queueing buffer for playback\n");
- else p->queue++;
-}
-
-static void check_events(void) {
-}
-
-static void uninit(void) {
- vo_zr2_priv_t *p = &priv;
- VERBOSE("uninit() called (may be called from preinit() on error)\n");
-
- stop_playing(p);
-
- if (p->buf && munmap(p->buf, p->zrq.size*p->zrq.count))
- ERROR("error munmapping buffer: %s\n", strerror(errno));
-
- if (p->vdes >= 0) close(p->vdes);
- free(p->subdevice);
-}