/*
 * Copyright (c) 2012 Georg Lippitsch <georg.lippitsch@gmx.at>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * libiec61883 interface
 */

#include <sys/poll.h>
#include <libraw1394/raw1394.h>
#include <libavc1394/avc1394.h>
#include <libavc1394/rom1394.h>
#include <libiec61883/iec61883.h>
#include "libavformat/dv.h"
#include "libavformat/mpegts.h"
#include "libavutil/opt.h"
#include "avdevice.h"

#define THREADS HAVE_PTHREADS

#if THREADS
#include <pthread.h>
#endif

#define MOTDCT_SPEC_ID      0x00005068
#define IEC61883_AUTO       0
#define IEC61883_DV         1
#define IEC61883_HDV        2

/**
 * For DV, one packet corresponds exactly to one frame.
 * For HDV, these are MPEG2 transport stream packets.
 * The queue is implemented as linked list.
 */
typedef struct DVPacket {
    uint8_t *buf;                       ///< actual buffer data
    int len;                            ///< size of buffer allocated
    struct DVPacket *next;              ///< next DVPacket
} DVPacket;

struct iec61883_data {
    AVClass *class;
    raw1394handle_t raw1394;            ///< handle for libraw1394
    iec61883_dv_fb_t iec61883_dv;       ///< handle for libiec61883 when used with DV
    iec61883_mpeg2_t iec61883_mpeg2;    ///< handle for libiec61883 when used with HDV

    DVDemuxContext *dv_demux;           ///< generic DV muxing/demuxing context
    MpegTSContext *mpeg_demux;          ///< generic HDV muxing/demuxing context

    DVPacket *queue_first;              ///< first element of packet queue
    DVPacket *queue_last;               ///< last element of packet queue

    char *device_guid;                  ///< to select one of multiple DV devices

    int packets;                        ///< Number of packets queued
    int max_packets;                    ///< Max. number of packets in queue

    int bandwidth;                      ///< returned by libiec61883
    int channel;                        ///< returned by libiec61883
    int input_port;                     ///< returned by libiec61883
    int type;                           ///< Stream type, to distinguish DV/HDV
    int node;                           ///< returned by libiec61883
    int output_port;                    ///< returned by libiec61883
    int thread_loop;                    ///< Condition for thread while-loop
    int receiving;                      ///< True as soon data from device available
    int receive_error;                  ///< Set in receive task in case of error
    int eof;                            ///< True as soon as no more data available

    struct pollfd raw1394_poll;         ///< to poll for new data from libraw1394

    /** Parse function for DV/HDV differs, so this is set before packets arrive */
    int (*parse_queue)(struct iec61883_data *dv, AVPacket *pkt);

#if THREADS
    pthread_t receive_task_thread;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
#endif
};

static int iec61883_callback(unsigned char *data, int length,
                             int complete, void *callback_data)
{
    struct iec61883_data *dv = callback_data;
    DVPacket *packet;
    int ret;

#if THREADS
    pthread_mutex_lock(&dv->mutex);
#endif

    if (dv->packets >= dv->max_packets) {
        av_log(NULL, AV_LOG_ERROR, "DV packet queue overrun, dropping.\n");
        ret = 0;
        goto exit;
    }

    packet = av_mallocz(sizeof(*packet));
    if (!packet) {
        ret = -1;
        goto exit;
    }

    packet->buf = av_malloc(length + AV_INPUT_BUFFER_PADDING_SIZE);
    if (!packet->buf) {
        av_free(packet);
        ret = -1;
        goto exit;
    }
    packet->len = length;

    memcpy(packet->buf, data, length);
    memset(packet->buf + length, 0, AV_INPUT_BUFFER_PADDING_SIZE);

    if (dv->queue_first) {
        dv->queue_last->next = packet;
        dv->queue_last = packet;
    } else {
        dv->queue_first = packet;
        dv->queue_last = packet;
    }
    dv->packets++;

    ret = 0;

exit:
#if THREADS
    pthread_cond_broadcast(&dv->cond);
    pthread_mutex_unlock(&dv->mutex);
#endif
    return ret;
}

static void *iec61883_receive_task(void *opaque)
{
    struct iec61883_data *dv = (struct iec61883_data *)opaque;
    int result;

#if THREADS
    while (dv->thread_loop)
#endif
    {
        while ((result = poll(&dv->raw1394_poll, 1, 200)) < 0) {
            if (!(errno == EAGAIN || errno == EINTR)) {
                av_log(NULL, AV_LOG_ERROR, "Raw1394 poll error occurred.\n");
                dv->receive_error = AVERROR(EIO);
                return NULL;
            }
        }
        if (result > 0 && ((dv->raw1394_poll.revents & POLLIN)
                           || (dv->raw1394_poll.revents & POLLPRI))) {
            dv->receiving = 1;
            raw1394_loop_iterate(dv->raw1394);
        } else if (dv->receiving) {
            av_log(NULL, AV_LOG_ERROR, "No more input data available\n");
#if THREADS
            pthread_mutex_lock(&dv->mutex);
            dv->eof = 1;
            pthread_cond_broadcast(&dv->cond);
            pthread_mutex_unlock(&dv->mutex);
#else
            dv->eof = 1;
#endif
            return NULL;
        }
    }

    return NULL;
}

static int iec61883_parse_queue_dv(struct iec61883_data *dv, AVPacket *pkt)
{
    DVPacket *packet;
    int size;

    size = avpriv_dv_get_packet(dv->dv_demux, pkt);
    if (size > 0)
        return size;

    packet = dv->queue_first;
    if (!packet)
        return -1;

    size = avpriv_dv_produce_packet(dv->dv_demux, pkt,
                                    packet->buf, packet->len, -1);
    dv->queue_first = packet->next;
    if (size < 0)
        av_free(packet->buf);
    av_free(packet);
    dv->packets--;

    if (size < 0)
        return -1;

    if (av_packet_from_data(pkt, pkt->data, pkt->size) < 0) {
        av_freep(&pkt->data);
        av_packet_unref(pkt);
        return -1;
    }

    return size;
}

static int iec61883_parse_queue_hdv(struct iec61883_data *dv, AVPacket *pkt)
{
    DVPacket *packet;
    int size;

    while (dv->queue_first) {
        packet = dv->queue_first;
        size = avpriv_mpegts_parse_packet(dv->mpeg_demux, pkt, packet->buf,
                                          packet->len);
        dv->queue_first = packet->next;
        av_freep(&packet->buf);
        av_freep(&packet);
        dv->packets--;

        if (size > 0)
            return size;
    }

    return -1;
}

static int iec61883_read_header(AVFormatContext *context)
{
    struct iec61883_data *dv = context->priv_data;
    struct raw1394_portinfo pinf[16];
    rom1394_directory rom_dir;
    char *endptr;
    int inport;
    int nb_ports;
    int port = -1;
    int response;
    int i, j = 0;
    uint64_t guid = 0;

    dv->input_port = -1;
    dv->output_port = -1;
    dv->channel = -1;

    dv->raw1394 = raw1394_new_handle();

    if (!dv->raw1394) {
        av_log(context, AV_LOG_ERROR, "Failed to open IEEE1394 interface.\n");
        return AVERROR(EIO);
    }

    if ((nb_ports = raw1394_get_port_info(dv->raw1394, pinf, 16)) < 0) {
        av_log(context, AV_LOG_ERROR, "Failed to get number of IEEE1394 ports.\n");
        goto fail;
    }

    inport = strtol(context->url, &endptr, 10);
    if (endptr != context->url && *endptr == '\0') {
        av_log(context, AV_LOG_INFO, "Selecting IEEE1394 port: %d\n", inport);
        j = inport;
        nb_ports = inport + 1;
    } else if (strcmp(context->url, "auto")) {
        av_log(context, AV_LOG_ERROR, "Invalid input \"%s\", you should specify "
               "\"auto\" for auto-detection, or the port number.\n", context->url);
        goto fail;
    }

    if (dv->device_guid) {
        if (sscanf(dv->device_guid, "%"SCNu64, &guid) != 1) {
            av_log(context, AV_LOG_INFO, "Invalid dvguid parameter: %s\n",
                   dv->device_guid);
            goto fail;
        }
    }

    for (; j < nb_ports && port==-1; ++j) {
        raw1394_destroy_handle(dv->raw1394);

        if (!(dv->raw1394 = raw1394_new_handle_on_port(j))) {
            av_log(context, AV_LOG_ERROR, "Failed setting IEEE1394 port.\n");
            goto fail;
        }

        for (i=0; i<raw1394_get_nodecount(dv->raw1394); ++i) {

            /* Select device explicitly by GUID */

            if (guid > 1) {
                if (guid == rom1394_get_guid(dv->raw1394, i)) {
                    dv->node = i;
                    port = j;
                    break;
                }
            } else {

                /* Select first AV/C tape recorder player node */

                if (rom1394_get_directory(dv->raw1394, i, &rom_dir) < 0)
                    continue;
                if (((rom1394_get_node_type(&rom_dir) == ROM1394_NODE_TYPE_AVC) &&
                     avc1394_check_subunit_type(dv->raw1394, i, AVC1394_SUBUNIT_TYPE_VCR)) ||
                    (rom_dir.unit_spec_id == MOTDCT_SPEC_ID)) {
                    rom1394_free_directory(&rom_dir);
                    dv->node = i;
                    port = j;
                    break;
                }
                rom1394_free_directory(&rom_dir);
            }
        }
    }

    if (port == -1) {
        av_log(context, AV_LOG_ERROR, "No AV/C devices found.\n");
        goto fail;
    }

    /* Provide bus sanity for multiple connections */

    iec61883_cmp_normalize_output(dv->raw1394, 0xffc0 | dv->node);

    /* Find out if device is DV or HDV */

    if (dv->type == IEC61883_AUTO) {
        response = avc1394_transaction(dv->raw1394, dv->node,
                                       AVC1394_CTYPE_STATUS |
                                       AVC1394_SUBUNIT_TYPE_TAPE_RECORDER |
                                       AVC1394_SUBUNIT_ID_0 |
                                       AVC1394_VCR_COMMAND_OUTPUT_SIGNAL_MODE |
                                       0xFF, 2);
        response = AVC1394_GET_OPERAND0(response);
        dv->type = (response == 0x10 || response == 0x90 || response == 0x1A || response == 0x9A) ?
            IEC61883_HDV : IEC61883_DV;
    }

    /* Connect to device, and do initialization */

    dv->channel = iec61883_cmp_connect(dv->raw1394, dv->node, &dv->output_port,
                                       raw1394_get_local_id(dv->raw1394),
                                       &dv->input_port, &dv->bandwidth);

    if (dv->channel < 0)
        dv->channel = 63;

    if (!dv->max_packets)
        dv->max_packets = 100;

    if (CONFIG_MPEGTS_DEMUXER && dv->type == IEC61883_HDV) {

        /* Init HDV receive */

        avformat_new_stream(context, NULL);

        dv->mpeg_demux = avpriv_mpegts_parse_open(context);
        if (!dv->mpeg_demux)
            goto fail;

        dv->parse_queue = iec61883_parse_queue_hdv;

        dv->iec61883_mpeg2 = iec61883_mpeg2_recv_init(dv->raw1394,
                                                      (iec61883_mpeg2_recv_t)iec61883_callback,
                                                      dv);

        dv->max_packets *= 766;
    } else {

        /* Init DV receive */

        dv->dv_demux = avpriv_dv_init_demux(context);
        if (!dv->dv_demux)
            goto fail;

        dv->parse_queue = iec61883_parse_queue_dv;

        dv->iec61883_dv = iec61883_dv_fb_init(dv->raw1394, iec61883_callback, dv);
    }

    dv->raw1394_poll.fd = raw1394_get_fd(dv->raw1394);
    dv->raw1394_poll.events = POLLIN | POLLERR | POLLHUP | POLLPRI;

    /* Actually start receiving */

    if (dv->type == IEC61883_HDV)
        iec61883_mpeg2_recv_start(dv->iec61883_mpeg2, dv->channel);
    else
        iec61883_dv_fb_start(dv->iec61883_dv, dv->channel);

#if THREADS
    dv->thread_loop = 1;
    if (pthread_mutex_init(&dv->mutex, NULL))
        goto fail;
    if (pthread_cond_init(&dv->cond, NULL))
        goto fail;
    if (pthread_create(&dv->receive_task_thread, NULL, iec61883_receive_task, dv))
        goto fail;
#endif

    return 0;

fail:
    raw1394_destroy_handle(dv->raw1394);
    return AVERROR(EIO);
}

static int iec61883_read_packet(AVFormatContext *context, AVPacket *pkt)
{
    struct iec61883_data *dv = context->priv_data;
    int size;

    /**
     * Try to parse frames from queue
     */

#if THREADS
    pthread_mutex_lock(&dv->mutex);
    while ((size = dv->parse_queue(dv, pkt)) == -1)
        if (!dv->eof)
            pthread_cond_wait(&dv->cond, &dv->mutex);
        else
            break;
    pthread_mutex_unlock(&dv->mutex);
#else
    int result;
    while ((size = dv->parse_queue(dv, pkt)) == -1) {
        iec61883_receive_task((void *)dv);
        if (dv->receive_error)
            return dv->receive_error;
    }
#endif

    return size;
}

static int iec61883_close(AVFormatContext *context)
{
    struct iec61883_data *dv = context->priv_data;

#if THREADS
    dv->thread_loop = 0;
    pthread_join(dv->receive_task_thread, NULL);
    pthread_cond_destroy(&dv->cond);
    pthread_mutex_destroy(&dv->mutex);
#endif

    if (CONFIG_MPEGTS_DEMUXER && dv->type == IEC61883_HDV) {
        iec61883_mpeg2_recv_stop(dv->iec61883_mpeg2);
        iec61883_mpeg2_close(dv->iec61883_mpeg2);
        avpriv_mpegts_parse_close(dv->mpeg_demux);
    } else {
        iec61883_dv_fb_stop(dv->iec61883_dv);
        iec61883_dv_fb_close(dv->iec61883_dv);
        av_freep(&dv->dv_demux);
    }
    while (dv->queue_first) {
        DVPacket *packet = dv->queue_first;
        dv->queue_first = packet->next;
        av_freep(&packet->buf);
        av_freep(&packet);
    }

    iec61883_cmp_disconnect(dv->raw1394, dv->node, dv->output_port,
                            raw1394_get_local_id(dv->raw1394),
                            dv->input_port, dv->channel, dv->bandwidth);

    raw1394_destroy_handle(dv->raw1394);

    return 0;
}

static const AVOption options[] = {
    { "dvtype", "override autodetection of DV/HDV", offsetof(struct iec61883_data, type), AV_OPT_TYPE_INT, {.i64 = IEC61883_AUTO}, IEC61883_AUTO, IEC61883_HDV, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
    { "auto",   "auto detect DV/HDV", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_AUTO}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
    { "dv",     "force device being treated as DV device", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_DV},   0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
    { "hdv" ,   "force device being treated as HDV device", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_HDV},  0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
    { "dvbuffer", "set queue buffer size (in packets)", offsetof(struct iec61883_data, max_packets), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
    { "dvguid", "select one of multiple DV devices by its GUID", offsetof(struct iec61883_data, device_guid), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
    { NULL },
};

static const AVClass iec61883_class = {
    .class_name = "iec61883 indev",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
    .category   = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT,
};

AVInputFormat ff_iec61883_demuxer = {
    .name           = "iec61883",
    .long_name      = NULL_IF_CONFIG_SMALL("libiec61883 (new DV1394) A/V input device"),
    .priv_data_size = sizeof(struct iec61883_data),
    .read_header    = iec61883_read_header,
    .read_packet    = iec61883_read_packet,
    .read_close     = iec61883_close,
    .flags          = AVFMT_NOFILE,
    .priv_class     = &iec61883_class,
};
