diff options
author | deva <deva> | 2005-03-24 12:14:44 +0000 |
---|---|---|
committer | deva <deva> | 2005-03-24 12:14:44 +0000 |
commit | 9466b3042bc7314915a15f499bd0b087f569654d (patch) | |
tree | 29c41f6ba46b9b92d91b92578720e1beee44fc9d /src/decoder.cc | |
parent | b5a6a93dcc7a83f5c4f8fd1894e303ae58804e0b (diff) |
Initial revision
Diffstat (limited to 'src/decoder.cc')
-rw-r--r-- | src/decoder.cc | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/decoder.cc b/src/decoder.cc new file mode 100644 index 0000000..2171b1a --- /dev/null +++ b/src/decoder.cc @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * RTVideoRec Realtime video recoder and encoder for Linux + * + * Copyright (C) 2004 Bent Bisballe + * Copyright (C) 2004 B. Stultiens + * Copyright (C) 2004 Koen Otter and Glenn van der Meyden + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <config.h> + +#include "decoder.h" + +Decoder::Decoder(char *device, + int channel, + sem_t *gencode_sem, + sem_t *gplayer_sem, + Queue<DVFrame> *gencode_queue, + Queue<FFFrame> *gplayer_queue, + pthread_mutex_t *gmutex, + volatile int *grunning) +{ + encode_sem = gencode_sem; + player_sem = gplayer_sem; + encode_queue = gencode_queue; + player_queue = gplayer_queue; + mutex = gmutex; + running = grunning; + + AVFormatContext *ifc; + AVFormatParameters dvpars; + AVInputFormat *iformat; + AVCodec *dec_codec; + + memset(&dvpars, 0, sizeof(dvpars)); + + if(!(iformat = av_find_input_format("dv1394"))) { + fprintf(stderr, "Failed to get input format dv1394\n"); + exit(1); + } + + dvpars.device = device; /* "/dev/dv1394"; */ + dvpars.channel = channel; + dvpars.standard = "pal"; + + if(av_open_input_file(&ifc, "", iformat, 0, &dvpars) < 0) { + fprintf(stderr, "Device is in use\n"); + fc = NULL; return; + } + if(av_find_stream_info(ifc) < 0) { + fprintf (stderr, "Could not find enough parameters\n"); + fc = NULL; return; + } + + dump_format(ifc, 1, "", 0); + + if(!(dec_codec = avcodec_find_decoder(ifc->streams[0]->codec.codec_id))) { + printf("Unsupported codec for input stream \n"); + fc = NULL; return; + } + + if(avcodec_open(&ifc->streams[0]->codec, dec_codec) < 0) { + printf("Error while opening codec for input stream\n"); + fc = NULL; return; + } + + fc = ifc; +} + +Decoder::~Decoder() +{ + avcodec_close(&fc->streams[0]->codec); + av_close_input_file(fc); +} + +void Decoder::decode() +{ + if(fc == NULL) { + printf("Decoder not initialized.\n"); + return; + } + + while(*running) { + AVPacket pkt; + uint8_t *ptr; + int len; + SDL_Event user_event; + + av_read_packet(fc, &pkt); + len = pkt.size; + ptr = pkt.data; + /* NOTE: we only decode video, we only need the data from stream_index 0 */ + /* (stream 0: video, stream 1: audio) */ + + while(pkt.stream_index == 0 && len > 0) { + int ret; + int got_picture; + // buf_t *buf = buf_alloc(); + FFFrame *fff = new FFFrame(); + DVFrame *dvf = new DVFrame(); + dvf->type = DVF_VIDEO; + + memcpy(dvf->frame, ptr, len); + + // fprintf(stderr, "DVBufferSize: [%d]bytes\n", len); + ret = avcodec_decode_video(&fc->streams[0]->codec, + fff->frame, &got_picture, ptr, len); + + if(ret < 0) { + fprintf(stderr, "Error while decoding stream\n"); + exit(1); + } + + len -= ret; + ptr += ret; + + pthread_mutex_lock(mutex); + encode_queue->push(dvf); + player_queue->push(fff); + pthread_mutex_unlock(mutex); + + sem_post(encode_sem); + + user_event.type = SDL_USEREVENT; + user_event.user.code = 0; + user_event.user.data1 = NULL; + user_event.user.data2 = NULL; + SDL_PushEvent(&user_event); + } + + /* // For later use, when audio must be implemented + while(pkt.stream_index == 1 && len > 0) { + DVFrame *dvf = new DVFrame(); + dvf->type = DVF_AUDIO; + + memcpy(dvf->frame, ptr, sizeof(dvf->frame)); + + ptr += sizeof(dvf->frame); + len -= sizeof(dvf->frame); + + pthread_mutex_lock(mutex); + encode_queue->push(dvf); + pthread_mutex_unlock(mutex); + + sem_post(encode_sem); + } + */ + av_free_packet(&pkt); + } + + /* Kick the others so they wake up with empty queues */ + sem_post(encode_sem); + pthread_exit(NULL); +} + +void Decoder::run() { + decode(); +} |