/*
 * rotate_demo.h
 *
 * ============================================================================
 * Copyright (c) Texas Instruments Inc 2005
 *
 * Use of this software is controlled by the terms and conditions found in the
 * license agreement under which this software has been supplied or provided.
 * ============================================================================
 */

#ifndef _ROTATE_DEMO_H
#define _ROTATE_DEMO_H

/* Standard Linux headers */
#include <stdio.h>
#include <pthread.h>

/* Enables or disables debug output */
#ifdef __DEBUG
#define DBG(fmt, args...) fprintf(stderr, "Rotate_demo Debug: " fmt, ## args)
#else
#define DBG(fmt, args...)
#endif

#define ERR(fmt, args...) fprintf(stderr, "Rotate_demo Error: " fmt, ## args)

/* Function error codes */
#define SUCCESS         0
#define FAILURE         -1

/* Thread error codes */
#define THREAD_SUCCESS  (void *) 0
#define THREAD_FAILURE  (void *) -1

/* The codec engine to use in this application */
#define ENGINE_NAME     "rotate_engine"

/* Device parameters */
#define V4L2_DEVICE     "/dev/video0"
#define OSD_DEVICE      "/dev/fb/0"
#define ATTR_DEVICE     "/dev/fb/2"
#define FBVID_DEVICE    "/dev/fb/3"

/* True of false enumeration */
#define TRUE            1
#define FALSE           0

/* Scaling factors for the video standards */
#define NOSTD           0
#define PALSTD          12
#define NTSCSTD         10

/* Number of microseconds to pause if the demo is 'paused' */
#define PAUSE           100

/* Screen dimensions */
#define SCREEN_BPP               16
#define D1_WIDTH                 720
#define D1_HEIGHT                yScale(480)
#define D1_LINE_WIDTH            D1_WIDTH * SCREEN_BPP / 8
#define D1_FRAME_SIZE            D1_LINE_WIDTH * D1_HEIGHT

/* Global data structure */
typedef struct GlobalData {
    int              quit;                /* Global quit flag */
    int              play;                /* Whether to play or pause */
    int              frames;              /* Video frame counter */
    int              videoBytesEncoded;   /* Video bytes encoded counter */
    int              yFactor;             /* Vertical scaling (PAL vs. NTSC) */
    pthread_mutex_t  mutex;               /* Mutex to protect the global data */
} GlobalData;

/* Global data */
extern GlobalData gbl;

/* Functions to protect the global data */
static inline int gblGetQuit(void)
{
    int quit;

    pthread_mutex_lock(&gbl.mutex);
    quit = gbl.quit;
    pthread_mutex_unlock(&gbl.mutex);

    return quit;
}

static inline void gblSetQuit(void)
{
    pthread_mutex_lock(&gbl.mutex);
    gbl.quit = TRUE;
    pthread_mutex_unlock(&gbl.mutex);
}

static inline int gblGetPlay(void)
{
    int play;

    pthread_mutex_lock(&gbl.mutex);
    play = gbl.play;
    pthread_mutex_unlock(&gbl.mutex);

    return play;
}

static inline void gblSetPlay(int play)
{
    pthread_mutex_lock(&gbl.mutex);
    gbl.play = play;
    pthread_mutex_unlock(&gbl.mutex);
}

static inline int gblGetAndResetFrames(void)
{
    int frames;

    pthread_mutex_lock(&gbl.mutex);
    frames = gbl.frames;
    gbl.frames = 0;
    pthread_mutex_unlock(&gbl.mutex);

    return frames;
}

static inline void gblIncFrames(void)
{
    pthread_mutex_lock(&gbl.mutex);
    gbl.frames++;
    pthread_mutex_unlock(&gbl.mutex);
}

static inline int gblGetYFactor(void)
{
    int yFactor;

    pthread_mutex_lock(&gbl.mutex);
    yFactor = gbl.yFactor;
    pthread_mutex_unlock(&gbl.mutex);

    return yFactor;
}

static inline void gblSetYFactor(int yFactor)
{
    pthread_mutex_lock(&gbl.mutex);
    gbl.yFactor = yFactor;
    pthread_mutex_unlock(&gbl.mutex);
}

/* Scale vertically depending on video standard */
#define yScale(x) (((x) * gblGetYFactor()) / 10)

/* Cleans up cleanly after a failure */
#define cleanup(x)                                  \
    status = (x);                                   \
    gblSetQuit();                                   \
    goto cleanup

/* Breaks a processing loop for a clean exit */
#define breakLoop(x)                                \
    status = (x);                                   \
    gblSetQuit();                                   \
    break

#endif /* _ROTATE_DEMO_H */
