blob: feffb79e1a77466a9f9e72a13112b2b922784954 [file] [log] [blame]
#ifndef _AVI_CAPTURE_H_
#define _AVI_CAPTURE_H_
#include "video/avi_segment.h"
#include "avi_capture_timings.h"
/* Hardcoded stats output config */
#define AVI_CAPTURE_THUMB_STATS_WIDTH 64
#define AVI_CAPTURE_THUMB_STATS_HEIGHT 48
#define AVI_CAPTURE_STATS_WIDTH (AVI_CAPTURE_THUMB_STATS_WIDTH * 6)
#define AVI_CAPTURE_STATS_HEIGHT (AVI_CAPTURE_THUMB_STATS_HEIGHT + 1)
/* Size of a stat buffer (in bytes) */
#define AVI_CAPTURE_STATS_FRAMESIZE (AVI_CAPTURE_STATS_WIDTH * \
AVI_CAPTURE_STATS_HEIGHT * \
4)
struct avi_capture_crop {
unsigned x;
unsigned y;
unsigned width;
unsigned height;
};
struct avi_capture_context;
typedef void (*avi_capture_frame_cback)(struct avi_capture_context *ctx,
struct avi_dma_buffer *frame,
enum avi_field field);
struct avi_capture_context {
/* Callback when a frame is done capturing */
avi_capture_frame_cback done;
/* Callback for the configuration of the next frame */
avi_capture_frame_cback next;
/* Ditto for the stats frame. Those functions are *always* called after
* the equivalent video callbacks above. This means that these stats
* always match the last frame passed to done() or next(). */
avi_capture_frame_cback stats_done;
avi_capture_frame_cback stats_next;
/* Private client data. */
void *priv;
/* These members need to be correctly initialized before the first call
* to avi_capture_get_measures */
union avi_cam_interface interface;
int interlaced;
enum avi_colorspace capture_cspace;
/* If set to NULL we use a builtin measure-to-timings conversion routine
* that should work for standard-compliant 656 streams at
* least. Unfortunately many sensors use non-standard timings and need
* adjustment, for those we need custom code (usually in the BSP). */
avi_capture_get_timings measure_to_timings;
struct device *dev;
struct avi_capture_timings timings_top;
struct avi_capture_timings timings_bot;
struct avi_capture_crop crop;
atomic_t timings_valid;
wait_queue_head_t waitq;
/* We have two segments: one containing the camera and one containing
* the DMA out. We need that in order to use either IRQ
* independently. */
struct avi_segment *cam_segment;
struct avi_segment *dma_segment;
struct avi_segment *stats_segment;
struct avi_node *stats_fifo;
struct avi_node *cam_node;
/* We need a rotation of two buffers: at any given moment while
* streaming one will be receiving the frame while the next one will be
* configured for receiving the next frame. */
struct avi_dma_buffer buffers[2];
struct avi_dma_buffer *configured_buffer;
struct avi_dma_buffer *capture_buffer;
/* Ditto for stats */
struct avi_dma_buffer stats[2];
struct avi_dma_buffer *configured_stats;
struct avi_dma_buffer *capture_stats;
atomic_t streaming;
/* Give up while waiting for a frame for more than timeout_jiffies
* jiffies. The frame is returned in the done() callback with status set
* to AVI_BUFFER_TIMEOUT. If 0 the timeout is ignored. */
struct timer_list timer;
unsigned long timeout_jiffies;
struct timeval last_frame;
struct timeval last_captured_frame;
struct timeval last_stats_frame;
struct timeval last_captured_stats_frame;
spinlock_t lock;
};
/* Allocate the resources needed for the capture. If stats is true and caps
* contains an ISP we also allocate the resources for capturing the stat
* buffers. */
extern int avi_capture_init(struct avi_capture_context *ctx,
struct device *dev,
int major,
unsigned long caps,
int enable_stats);
extern void avi_capture_destroy(struct avi_capture_context *ctx);
/* Configure the capture interface and get the video timings. This has to be
* called after any change to the input stream timings or the capture
* configuration in ctx.
*
* This call will block for a few frames' worth of time. */
extern int avi_capture_prepare(struct avi_capture_context *ctx);
/* After a call to avi_capture_get_measures this function can be used to get the
* resolution of the video. */
extern void avi_capture_resolution(const struct avi_capture_context *ctx,
unsigned *width,
unsigned *height);
extern int avi_capture_set_crop(struct avi_capture_context *ctx,
struct avi_capture_crop *crop);
extern int avi_capture_try_format(const struct avi_capture_context *ctx,
struct avi_segment_format *fmt);
extern int avi_capture_set_format(struct avi_capture_context *ctx,
struct avi_segment_format *fmt);
extern int avi_capture_streamon (struct avi_capture_context *ctx);
extern int avi_capture_streamoff(struct avi_capture_context *ctx);
/* Resume capture after suspend to ram */
extern int avi_capture_resume(struct avi_capture_context *ctx);
extern void avi_capture_configure_interface(struct avi_capture_context *ctx);
extern int avi_capture_prepare_timings(struct avi_capture_context *ctx,
unsigned width, unsigned height);
struct avi_multicapt {
struct avi_capture_context *ctx;
dma_addr_t fb_offset_addr;
};
#endif /* _AVI_CAPTURE_H_ */