diff options
| author | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-09-11 14:38:47 +0900 |
|---|---|---|
| committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-09-11 14:38:47 +0900 |
| commit | 884c8093d63402a1ad0b502244b791e3c6782be3 (patch) | |
| tree | a600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/transcode/transcode-1.1.7/import/import_ffmpeg.c | |
| parent | 14e1aa2006796f147f3f4811fb908a6b01e79253 (diff) | |
| download | extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip | |
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/transcode/transcode-1.1.7/import/import_ffmpeg.c')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/import/import_ffmpeg.c | 772 |
1 files changed, 772 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/import/import_ffmpeg.c b/debian/transcode/transcode-1.1.7/import/import_ffmpeg.c new file mode 100644 index 00000000..3a047a39 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/import/import_ffmpeg.c @@ -0,0 +1,772 @@ +/* + * import_ffmpeg.c + * + * Copyright (C) Moritz Bunkus - October 2002 + * libavformat support and misc updates: + * Copyright (C) Francesco Romani - September 2006 + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode 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 GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define MOD_NAME "import_ffmpeg.so" +#define MOD_VERSION "v0.1.15 (2008-01-28)" +#define MOD_CODEC "(video) ffmpeg: MS MPEG4v1-3/MPEG4/MJPEG" + +#include "transcode.h" +#include "libtc/libtc.h" +#include "filter.h" + +static int verbose_flag = TC_QUIET; +static int capability_flag = TC_CAP_YUV | TC_CAP_RGB | TC_CAP_VID; + +#define MOD_PRE ffmpeg +#include "import_def.h" + +#include "libtc/tcavcodec.h" +#include "aclib/imgconvert.h" +#include "avilib/avilib.h" +#include "magic.h" + +char import_cmd_buf[TC_BUF_MAX]; + +// libavcodec is not thread-safe. We must protect concurrent access to it. +// this is visible (without the mutex of course) with +// transcode .. -x ffmpeg -y ffmpeg -F mpeg4 + +static int done_seek=0; + +struct ffmpeg_codec { + int id; + unsigned int tc_id; + char *name; + char fourCCs[10][5]; +}; + +// fourCC to ID mapping taken from MPlayer's codecs.conf +static struct ffmpeg_codec ffmpeg_codecs[] = { + {CODEC_ID_MSMPEG4V1, TC_CODEC_ERROR, "mp41", + {"MP41", "DIV1", ""}}, + {CODEC_ID_MSMPEG4V2, TC_CODEC_MP42, "mp42", + {"MP42", "DIV2", ""}}, + {CODEC_ID_MSMPEG4V3, TC_CODEC_DIVX3, "msmpeg4", + {"DIV3", "DIV5", "AP41", "MPG3", "MP43", ""}}, + {CODEC_ID_MPEG4, TC_CODEC_DIVX4, "mpeg4", + {"DIVX", "XVID", "MP4S", "M4S2", "MP4V", "UMP4", "DX50", ""}}, + {CODEC_ID_MJPEG, TC_CODEC_MJPEG, "mjpeg", + {"MJPG", "AVRN", "AVDJ", "JPEG", "MJPA", "JFIF", ""}}, + {CODEC_ID_MPEG1VIDEO, TC_CODEC_MPG1, "mpeg1video", + {"MPG1", ""}}, + {CODEC_ID_DVVIDEO, TC_CODEC_DV, "dvvideo", + {"DVSD", ""}}, + {CODEC_ID_WMV1, TC_CODEC_WMV1, "wmv1", + {"WMV1", ""}}, + {CODEC_ID_WMV2, TC_CODEC_WMV2, "wmv2", + {"WMV2", ""}}, + {CODEC_ID_HUFFYUV, TC_CODEC_HUFFYUV, "hfyu", + {"HFYU", ""}}, + {CODEC_ID_H263I, TC_CODEC_H263I, "h263i", + {"I263", ""}}, + {CODEC_ID_H263P, TC_CODEC_H263P, "h263p", + {"H263", "U263", "VIV1", ""}}, + {CODEC_ID_H264, TC_CODEC_H264, "h264", + {"H264", "h264", "X264", "x264", "avc1", ""}}, + {CODEC_ID_RV10, TC_CODEC_RV10, "rv10", + {"RV10", "RV13", ""}}, + {CODEC_ID_SVQ1, TC_CODEC_SVQ1, "svq1", + {"SVQ1", ""}}, + {CODEC_ID_SVQ3, TC_CODEC_SVQ3, "svq3", + {"SVQ3", ""}}, + {CODEC_ID_MPEG2VIDEO, TC_CODEC_MPEG2, "mpeg2video", + {"MPG2", ""}}, + {CODEC_ID_MPEG2VIDEO, TC_CODEC_MPEG, "mpeg2video", + {"MPG2", ""}}, + {CODEC_ID_ASV1, TC_CODEC_ASV1, "asv1", + {"ASV1", ""}}, + {CODEC_ID_ASV2, TC_CODEC_ASV2, "asv2", + {"ASV2", ""}}, + {CODEC_ID_FFV1, TC_CODEC_FFV1, "ffv1", + {"FFV1", ""}}, + {CODEC_ID_RAWVIDEO, TC_CODEC_YUV420P, "raw", + {"I420", "IYUV", ""}}, + {CODEC_ID_RAWVIDEO, TC_CODEC_YUV422P, "raw", + {"Y42B", ""}}, + {0, TC_CODEC_UNKNOWN, NULL, {""}}}; + +#define BUFFER_SIZE SIZE_RGB_FRAME + +static avi_t *avifile = NULL; +static int pass_through = 0; +static uint8_t *buffer = NULL; +static uint8_t *yuv2rgb_buffer = NULL; +static AVCodec *lavc_dec_codec = NULL; +static AVCodecContext *lavc_dec_context = NULL; +static int x_dim = 0, y_dim = 0; +static int pix_fmt, frame_size = 0; +static uint8_t *frame = NULL; +static unsigned long format_flag; +static struct ffmpeg_codec *codec; + +static struct ffmpeg_codec *find_ffmpeg_codec(char *fourCC) { + int i; + struct ffmpeg_codec *cdc; + + cdc = &ffmpeg_codecs[0]; + while (cdc->name != NULL) { + i = 0; + while (cdc->fourCCs[i][0] != 0) { + if (!strcasecmp(cdc->fourCCs[i], fourCC)) + return cdc; + i++; + } + cdc++; + } + + return NULL; +} + +static struct ffmpeg_codec *find_ffmpeg_codec_id(unsigned int transcode_id) { + struct ffmpeg_codec *cdc; + + cdc = &ffmpeg_codecs[0]; + while (cdc->name != NULL) { + if (cdc->tc_id == transcode_id) + return cdc; + cdc++; + } + + return NULL; +} + +inline static int stream_read_char(const uint8_t *d) +{ + return (*d & 0xff); +} + +inline static unsigned int stream_read_dword(const uint8_t *s) +{ + unsigned int y; + y=stream_read_char(s); + y=(y<<8)|stream_read_char(s+1); + y=(y<<8)|stream_read_char(s+2); + y=(y<<8)|stream_read_char(s+3); + return y; +} + +// Determine of the compressed frame is a keyframe for direct copy +static int mpeg4_is_key(const uint8_t *data, long size) +{ + int result = 0; + int i; + + for(i = 0; i < size - 5; i++) + { + if( data[i] == 0x00 && + data[i + 1] == 0x00 && + data[i + 2] == 0x01 && + data[i + 3] == 0xb6) + { + if((data[i + 4] & 0xc0) == 0x0) + return 1; + else + return 0; + } + } + + return result; +} + +static int divx3_is_key(const uint8_t *d) +{ + int32_t c=0; + + c=stream_read_dword(d); + if(c&0x40000000) return(0); + + return(1); +} + + +static void enable_levels_filter(void) +{ + int handle = 0, id = tc_filter_find("levels"); + if (id == 0) { + tc_log_info(MOD_NAME, "input is mjpeg, reducing range from YUVJ420P to YUV420P"); + handle = tc_filter_add("levels", "output=16-240:pre=1"); + if (!handle) { + tc_log_warn(MOD_NAME, "cannot load levels filter"); + } + } +} + +/* ------------------------------------------------------------ + * + * open stream + * + * ------------------------------------------------------------*/ + +MOD_open { + char *fourCC = NULL; + double fps = 0; + int extra_data_size = 0; + long sret; + int ret; + + if (param->flag == TC_VIDEO) { + + format_flag = vob->v_format_flag; + + sret = tc_file_check(vob->video_in_file); /* is a directory? */ + if (sret == 1) + goto do_dv; /* yes, it is */ + else + if (sret == -1) + return TC_IMPORT_ERROR; + + if (format_flag == TC_MAGIC_AVI) { + goto do_avi; + } else if (format_flag==TC_MAGIC_DV_PAL || format_flag==TC_MAGIC_DV_NTSC) { + tc_log_warn(MOD_NAME, "Format 0x%lX DV!!", format_flag); + goto do_dv; + } else { + tc_log_warn(MOD_NAME, "Format 0x%lX not supported", + format_flag); + return(TC_IMPORT_ERROR); + } + tc_log_info(MOD_NAME, "Format 0x%lX", format_flag); + +do_avi: + if(avifile==NULL) { + if(vob->nav_seek_file) { + if(NULL == (avifile = AVI_open_input_indexfile(vob->video_in_file, + 0, vob->nav_seek_file))){ + AVI_print_error("avi open error"); + return(TC_IMPORT_ERROR); + } + } else { + if(NULL == (avifile = AVI_open_input_file(vob->video_in_file,1))){ + AVI_print_error("avi open error"); + return(TC_IMPORT_ERROR); + } + } + } + + // vob->offset contains the last keyframe + if (!done_seek && vob->vob_offset>0) { + AVI_set_video_position(avifile, vob->vob_offset); + done_seek=1; + } + + //important parameter + x_dim = vob->im_v_width; + y_dim = vob->im_v_height; + fps = vob->fps; + + fourCC = AVI_video_compressor(avifile); + + if (strlen(fourCC) == 0) { + tc_log_warn(MOD_NAME, "FOURCC has zero length!? Broken source?"); + + return TC_IMPORT_ERROR; + } + + TC_INIT_LIBAVCODEC; + + codec = find_ffmpeg_codec(fourCC); + if (codec == NULL) { + tc_log_warn(MOD_NAME, "No codec is known for the FOURCC '%s'.", + fourCC); + return TC_IMPORT_ERROR; + } + + lavc_dec_codec = avcodec_find_decoder(codec->id); + if (!lavc_dec_codec) { + tc_log_warn(MOD_NAME, "No codec found for the FOURCC '%s'.", + fourCC); + return TC_IMPORT_ERROR; + } + + // Set these to the expected values so that ffmpeg's decoder can + // properly detect interlaced input. + lavc_dec_context = avcodec_alloc_context(); + if (lavc_dec_context == NULL) { + tc_log_error(MOD_NAME, "Could not allocate enough memory."); + return TC_IMPORT_ERROR; + } + lavc_dec_context->width = x_dim; + lavc_dec_context->height = y_dim; + + if (vob->decolor) lavc_dec_context->flags |= CODEC_FLAG_GRAY; +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) + lavc_dec_context->error_resilience = 2; +#else + lavc_dec_context->error_recognition = 2; +#endif + lavc_dec_context->error_concealment = 3; + lavc_dec_context->workaround_bugs = FF_BUG_AUTODETECT; + lavc_dec_context->codec_tag= (fourCC[0]<<24) | (fourCC[1]<<16) | + (fourCC[2]<<8) | (fourCC[3]); + + // XXX: some codecs need extra data + switch (codec->id) + { + case CODEC_ID_MJPEG: extra_data_size = 28; break; + case CODEC_ID_LJPEG: extra_data_size = 28; break; + case CODEC_ID_HUFFYUV: extra_data_size = 1000; break; + case CODEC_ID_ASV1: extra_data_size = 8; break; + case CODEC_ID_ASV2: extra_data_size = 8; break; + case CODEC_ID_WMV1: extra_data_size = 4; break; + case CODEC_ID_WMV2: extra_data_size = 4; break; + default: extra_data_size = 0; break; + } + + if (extra_data_size) { + lavc_dec_context->extradata = tc_zalloc(extra_data_size); + if (!lavc_dec_context->extradata) { + tc_log_error(MOD_NAME, "can't allocate extra_data"); + return TC_IMPORT_ERROR; + } + lavc_dec_context->extradata_size = extra_data_size; + } + + TC_LOCK_LIBAVCODEC; + ret = avcodec_open(lavc_dec_context, lavc_dec_codec); + TC_UNLOCK_LIBAVCODEC; + if (ret < 0) { + tc_log_warn(MOD_NAME, "Could not initialize the '%s' codec.", + codec->name); + return TC_IMPORT_ERROR; + } + + pix_fmt = vob->im_v_codec; + + frame_size = x_dim * y_dim * 3; + switch (pix_fmt) { + case CODEC_YUV: + frame_size = x_dim*y_dim + 2*UV_PLANE_SIZE(IMG_YUV_DEFAULT,x_dim,y_dim); + + // we adapt the color space + if(codec->id == CODEC_ID_MJPEG) { + enable_levels_filter(); + } + break; + case CODEC_RGB: + frame_size = x_dim * y_dim * 3; + + if (yuv2rgb_buffer == NULL) yuv2rgb_buffer = tc_bufalloc(BUFFER_SIZE); + + if (yuv2rgb_buffer == NULL) { + tc_log_perror(MOD_NAME, "out of memory"); + return TC_IMPORT_ERROR; + } else + memset(yuv2rgb_buffer, 0, BUFFER_SIZE); + break; + case CODEC_RAW: + case CODEC_RAW_YUV: + case CODEC_RAW_RGB: + pass_through = 1; + break; + } + + if (!frame) { + frame = tc_zalloc(frame_size); + if (!frame) { + tc_log_perror(MOD_NAME, "out of memory"); + return TC_IMPORT_ERROR; + } + } + + //---------------------------------------- + // + // setup decoder + // + //---------------------------------------- + + if(buffer == NULL) buffer=tc_bufalloc(frame_size); + + if(buffer == NULL) { + tc_log_perror(MOD_NAME, "out of memory"); + return TC_IMPORT_ERROR; + } + + memset(buffer, 0, frame_size); + + param->fd = NULL; + + return TC_IMPORT_OK; +do_dv: + x_dim = vob->im_v_width; + y_dim = vob->im_v_height; + + { + char yuv_buf[255]; + //char ext_buf[255]; + struct ffmpeg_codec *codec; + + switch (vob->im_v_codec) { + case CODEC_RGB: + tc_snprintf(yuv_buf, sizeof(yuv_buf), "rgb"); + break; + case CODEC_YUV: + tc_snprintf(yuv_buf, sizeof(yuv_buf), "yuv420p"); + break; + } + + codec = find_ffmpeg_codec_id (vob->v_codec_flag); + if (codec == NULL) { + tc_log_warn(MOD_NAME, "No codec is known for the TAG '%lx'.", + vob->v_codec_flag); + return TC_IMPORT_ERROR; + } + + // we adapt the color space + if(codec->id == CODEC_ID_MJPEG) { + enable_levels_filter(); + } + + sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, + "tccat -i \"%s\" -d %d |" + " tcextract -x dv -d %d |" + " tcdecode -x %s -t lavc -y %s -g %dx%d -Q %d -d %d", + vob->video_in_file, vob->verbose, vob->verbose, + codec->name, yuv_buf, x_dim, y_dim, vob->quality, + vob->verbose); + if (sret < 0) + return(TC_IMPORT_ERROR); + } + + // print out + if(verbose_flag) tc_log_info(MOD_NAME, "%s", import_cmd_buf); + + // set to NULL if we handle read + param->fd = NULL; + + // popen + if((param->fd = popen(import_cmd_buf, "r"))== NULL) { + tc_log_perror(MOD_NAME, "popen LAVC stream"); + return(TC_IMPORT_ERROR); + } + + return TC_IMPORT_OK; + + } + + return TC_IMPORT_ERROR; +} + + +/* ------------------------------------------------------------ + * + * decode stream + * + * ------------------------------------------------------------*/ + +MOD_decode { + + /* + * When using directory mode or dvraw etc, we don't enter here + * (transcode-core does the reading) so there is no need to protect this + * stuff by and if() or something. + */ + + int key, len; + long bytes_read = 0; + int got_picture; + uint8_t *src_planes[3]; + uint8_t *dst_planes[3]; + int src_fmt, dst_fmt; + AVFrame picture; + + if (param->flag == TC_VIDEO) { + bytes_read = AVI_read_frame(avifile, (char*)buffer, &key); + + if (bytes_read < 0) return TC_IMPORT_ERROR; + + if (key) param->attributes |= TC_FRAME_IS_KEYFRAME; + + // PASS_THROUGH MODE + + if (pass_through) { + int bkey = 0; + + // check for keyframes + if (codec->id == CODEC_ID_MSMPEG4V3) { + if (divx3_is_key(buffer)) bkey = 1; + } + else if (codec->id == CODEC_ID_MPEG4) { + if (mpeg4_is_key(buffer, bytes_read)) bkey = 1; + } + else if (codec->id == CODEC_ID_MJPEG) { + bkey = 1; + } + + if (bkey) { + param->attributes |= TC_FRAME_IS_KEYFRAME; + } + + if (verbose & TC_DEBUG) + if (key || bkey) + tc_log_info(MOD_NAME, "Keyframe info (AVI | Bitstream) (%d|%d)", + key, bkey); + + param->size = (int) bytes_read; + ac_memcpy(param->buffer, buffer, bytes_read); + + return TC_IMPORT_OK; + } + + if (bytes_read == 0) { + // repeat last frame + ac_memcpy(param->buffer, frame, frame_size); + param->size = frame_size; + return TC_IMPORT_OK; + } + + // ------------ + // decode frame + // ------------ + +retry: + do { + TC_LOCK_LIBAVCODEC; + AVPacket avpkt; + av_init_packet(&avpkt); + avpkt.data = NULL; + avpkt.size = 0; + len = avcodec_decode_video2(lavc_dec_context, &picture, + &got_picture, &avpkt); + TC_UNLOCK_LIBAVCODEC; + + if (len < 0) { + tc_log_warn (MOD_NAME, "frame decoding failed"); + return TC_IMPORT_ERROR; + } + if (!got_picture) { + if (avifile->video_pos == 1) { + + bytes_read = AVI_read_frame(avifile, (char*)buffer, &key); + if (bytes_read < 0) return TC_IMPORT_ERROR; + param->attributes &= ~TC_FRAME_IS_KEYFRAME; + if (key) param->attributes |= TC_FRAME_IS_KEYFRAME; + goto retry; + + } else { + + // repeat last frame + ac_memcpy(param->buffer, frame, frame_size); + param->size = frame_size; + return TC_IMPORT_OK; + } + } + } while (0); + + dst_fmt = (pix_fmt == CODEC_YUV) ?IMG_YUV_DEFAULT :IMG_RGB_DEFAULT; + YUV_INIT_PLANES(dst_planes, param->buffer, dst_fmt, + lavc_dec_context->width, lavc_dec_context->height); + + // Convert avcodec image to our internal YUV or RGB format + switch (lavc_dec_context->pix_fmt) { + case PIX_FMT_YUVJ420P: + case PIX_FMT_YUV420P: + src_fmt = IMG_YUV420P; + YUV_INIT_PLANES(src_planes, frame, src_fmt, + lavc_dec_context->width, lavc_dec_context->height); + + // Remove "dead space" at right edge of planes, if any + if (picture.linesize[0] != lavc_dec_context->width) { + int y; + for (y = 0; y < lavc_dec_context->height; y++) { + ac_memcpy(src_planes[0] + y*lavc_dec_context->width, + picture.data[0] + y*picture.linesize[0], + lavc_dec_context->width); + } + for (y = 0; y < lavc_dec_context->height / 2; y++) { + ac_memcpy(src_planes[1] + y*(lavc_dec_context->width/2), + picture.data[1] + y*picture.linesize[1], + lavc_dec_context->width/2); + ac_memcpy(src_planes[2] + y*(lavc_dec_context->width/2), + picture.data[2] + y*picture.linesize[2], + lavc_dec_context->width/2); + } + } else { + ac_memcpy(src_planes[0], picture.data[0], + lavc_dec_context->width * lavc_dec_context->height); + ac_memcpy(src_planes[1], picture.data[1], + (lavc_dec_context->width/2)*(lavc_dec_context->height/2)); + ac_memcpy(src_planes[2], picture.data[2], + (lavc_dec_context->width/2)*(lavc_dec_context->height/2)); + } + break; + + case PIX_FMT_YUV411P: + src_fmt = IMG_YUV411P; + YUV_INIT_PLANES(src_planes, frame, src_fmt, + lavc_dec_context->width, lavc_dec_context->height); + + if (picture.linesize[0] != lavc_dec_context->width) { + int y; + for (y = 0; y < lavc_dec_context->height; y++) { + ac_memcpy(src_planes[0] + y*lavc_dec_context->width, + picture.data[0] + y*picture.linesize[0], + lavc_dec_context->width); + ac_memcpy(src_planes[1] + y*(lavc_dec_context->width/4), + picture.data[1] + y*picture.linesize[1], + lavc_dec_context->width/4); + ac_memcpy(src_planes[2] + y*(lavc_dec_context->width/4), + picture.data[2] + y*picture.linesize[2], + lavc_dec_context->width/4); + } + } else { + ac_memcpy(src_planes[0], picture.data[0], + lavc_dec_context->width * lavc_dec_context->height); + ac_memcpy(src_planes[1], picture.data[1], + (lavc_dec_context->width/4) * lavc_dec_context->height); + ac_memcpy(src_planes[2], picture.data[2], + (lavc_dec_context->width/4) * lavc_dec_context->height); + } + break; + + case PIX_FMT_YUVJ422P: + case PIX_FMT_YUV422P: + src_fmt = IMG_YUV422P; + YUV_INIT_PLANES(src_planes, frame, src_fmt, + lavc_dec_context->width, lavc_dec_context->height); + + if (picture.linesize[0] != lavc_dec_context->width) { + int y; + for (y = 0; y < lavc_dec_context->height; y++) { + ac_memcpy(src_planes[0] + y*lavc_dec_context->width, + picture.data[0] + y*picture.linesize[0], + lavc_dec_context->width); + ac_memcpy(src_planes[1] + y*(lavc_dec_context->width/2), + picture.data[1] + y*picture.linesize[1], + lavc_dec_context->width/2); + ac_memcpy(src_planes[2] + y*(lavc_dec_context->width/2), + picture.data[2] + y*picture.linesize[2], + lavc_dec_context->width/2); + } + } else { + ac_memcpy(src_planes[0], picture.data[0], + lavc_dec_context->width * lavc_dec_context->height); + ac_memcpy(src_planes[1], picture.data[1], + (lavc_dec_context->width/2) * lavc_dec_context->height); + ac_memcpy(src_planes[2], picture.data[2], + (lavc_dec_context->width/2) * lavc_dec_context->height); + } + break; + + case PIX_FMT_YUVJ444P: + case PIX_FMT_YUV444P: + src_fmt = IMG_YUV444P; + YUV_INIT_PLANES(src_planes, frame, src_fmt, + lavc_dec_context->width, lavc_dec_context->height); + + if (picture.linesize[0] != lavc_dec_context->width) { + int y; + for (y = 0; y < lavc_dec_context->height; y++) { + ac_memcpy(picture.data[0] + y*lavc_dec_context->width, + picture.data[0] + y*picture.linesize[0], + lavc_dec_context->width); + ac_memcpy(picture.data[1] + y*lavc_dec_context->width, + picture.data[1] + y*picture.linesize[1], + lavc_dec_context->width); + ac_memcpy(picture.data[2] + y*lavc_dec_context->width, + picture.data[2] + y*picture.linesize[2], + lavc_dec_context->width); + } + } else { + ac_memcpy(src_planes[0], picture.data[0], + lavc_dec_context->width * lavc_dec_context->height); + ac_memcpy(src_planes[1], picture.data[1], + lavc_dec_context->width * lavc_dec_context->height); + ac_memcpy(src_planes[2], picture.data[2], + lavc_dec_context->width * lavc_dec_context->height); + } + break; + + default: + tc_log_warn(MOD_NAME, "Unsupported decoded frame format: %d", + lavc_dec_context->pix_fmt); + return TC_IMPORT_ERROR; + } + + ac_imgconvert(src_planes, src_fmt, dst_planes, dst_fmt, + lavc_dec_context->width, lavc_dec_context->height); + param->size = frame_size; + + return TC_IMPORT_OK; + } + + return TC_IMPORT_ERROR; +} + +/* ------------------------------------------------------------ + * + * close stream + * + * ------------------------------------------------------------*/ + +MOD_close { + + if (param->flag == TC_VIDEO) { + + if(lavc_dec_context) { + if (!pass_through) + avcodec_flush_buffers(lavc_dec_context); + + avcodec_close(lavc_dec_context); + if (lavc_dec_context->extradata_size) free(lavc_dec_context->extradata); + free(lavc_dec_context); + + lavc_dec_context = NULL; + done_seek=0; + + pass_through = 0; + + } + + if (param->fd) pclose(param->fd); + param->fd = NULL; + + if(avifile!=NULL) { + AVI_close(avifile); + avifile=NULL; + } + + // do not free buffer and yuv2rgb_buffer!! + /* + * because they are static variables and are conditionally allocated + * -- fromani 20051112 + */ + return TC_IMPORT_OK; + } + + return TC_IMPORT_ERROR; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ + |
