File:  [DVB] / libsoftmpeg / src / d_avcodec.c
Revision 1.2: download - view: text, annotated - select for diffs
Wed Mar 17 19:46:53 2004 UTC (20 years, 3 months ago) by hunold
Branches: MAIN
CVS tags: HEAD
- hotfix: return code of avcodec_decode_video() doesn't indicate an error properly, ignore it for now

/*
   (c) Copyright 2004  convergence GmbH

   All rights reserved.

   Written by Michael Hunold <hunold@convergence.de> and
	      Denis Oliver Kropp <dok@directfb.org>

   This library 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 of the License, or (at your option) any later version.

   This library 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 this library; if not, write to the
   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

#include "video.h"

static struct avcodec_data  {
	AVCodec *codec;
	AVCodecContext *codec_ctx;
} priv;

static int flush(struct video_decoder *d)
{
	struct avcodec_data *data = &priv;
	
	avdecoder_flush(data->codec, data->codec_ctx, 1);
	
	return 0;
}

static int decode(struct video_decoder *d, struct video_buffer *buf, struct video_frame *frame, int *ready)
{
	struct avcodec_data *data = &priv;
	AVFrame av_frame;

	avcodec_decode_video(data->codec_ctx, &av_frame, ready, buf->buf, buf->len);

	/* this depends on the decoder used */		
	if (av_frame.pict_type == FF_I_TYPE) {
		frame->is_iframe = 1;
	} else {
		frame->is_iframe = 0;
	}	
#ifdef RATIONAL_H
	frame->aspect_ratio = av_q2d(data->codec_ctx->sample_aspect_ratio);
#else
	frame->aspect_ratio = data->codec_ctx->aspect_ratio;
#endif
	frame->width  = data->codec_ctx->width;
	frame->height = data->codec_ctx->height;
	frame->data[0] = av_frame.data[0];
	frame->data[1] = av_frame.data[1];
	frame->data[2] = av_frame.data[2];
	frame->linesize[0] = av_frame.linesize[0];
	frame->linesize[1] = av_frame.linesize[1];
	frame->linesize[2] = av_frame.linesize[2];

	return 0;
}

static int init(struct video_decoder *d)
{
	struct avcodec_data *data = &priv;

	init_avcodec_stuff();

	data->codec = avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
	if (NULL == data->codec) {
		SOFTMPEG_ERROR("codec not found\n");
		return -1;
	}

	data->codec_ctx = avcodec_alloc_context();
	if (NULL == data->codec_ctx) {
		SOFTMPEG_ERROR("cannot allocate codec context\n");
		/* fixme: release decoder */
		return -1;
	}

	if (avcodec_open(data->codec_ctx, data->codec) < 0) {
		SOFTMPEG_ERROR("could not open codec\n");
		/* fixme: release decoder + contect */
		return -1;
	}

	return 0;
}

struct video_codec avcodec_ops =
{
	.init 	= &init,
	.flush 	= &flush,
	.decode	= &decode,
};

LinuxTV legacy CVS <linuxtv.org/cvs>