You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
276 lines
6.6 KiB
276 lines
6.6 KiB
4 years ago
|
/*
|
||
|
* import_lzo.c
|
||
|
*
|
||
|
* Copyright (C) Thomas Oestreich - October 2002
|
||
|
*
|
||
|
* 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_lzo.so"
|
||
|
#define MOD_VERSION "v0.1.0 (2005-10-16)"
|
||
|
#define MOD_CODEC "(video) LZO"
|
||
|
|
||
|
#include "transcode.h"
|
||
|
#include "magic.h"
|
||
|
#include "libtc/tc_lzo.h"
|
||
|
|
||
|
static int verbose_flag = TC_QUIET;
|
||
|
static int capability_flag = TC_CAP_PCM | TC_CAP_YUV | TC_CAP_RGB |
|
||
|
TC_CAP_AUD | TC_CAP_VID;
|
||
|
|
||
|
#define MOD_PRE lzo
|
||
|
#include "import_def.h"
|
||
|
|
||
|
|
||
|
static avi_t *avifile1=NULL;
|
||
|
static avi_t *avifile2=NULL;
|
||
|
|
||
|
static uint32_t video_codec;
|
||
|
static int audio_codec;
|
||
|
static int aframe_count=0, vframe_count=0;
|
||
|
|
||
|
#define BUFFER_SIZE SIZE_RGB_FRAME<<1
|
||
|
|
||
|
static int r;
|
||
|
static lzo_byte *out;
|
||
|
static lzo_byte *wrkmem;
|
||
|
static lzo_uint out_len;
|
||
|
|
||
|
static int done_seek=0;
|
||
|
|
||
|
/* ------------------------------------------------------------
|
||
|
*
|
||
|
* open stream
|
||
|
*
|
||
|
* ------------------------------------------------------------*/
|
||
|
|
||
|
MOD_open
|
||
|
{
|
||
|
int width=0, height=0;
|
||
|
double fps=0;
|
||
|
char *codec=NULL;
|
||
|
|
||
|
param->fd = NULL;
|
||
|
|
||
|
if(param->flag == TC_AUDIO) return(TC_IMPORT_ERROR);
|
||
|
|
||
|
if(param->flag == TC_VIDEO) {
|
||
|
|
||
|
param->fd = NULL;
|
||
|
|
||
|
if(avifile2==NULL) {
|
||
|
if(vob->nav_seek_file) {
|
||
|
if(NULL == (avifile2 = 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 == (avifile2 = 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(avifile2, vob->vob_offset);
|
||
|
done_seek=1;
|
||
|
}
|
||
|
|
||
|
//read all video parameter from input file
|
||
|
width = AVI_video_width(avifile2);
|
||
|
height = AVI_video_height(avifile2);
|
||
|
|
||
|
fps = AVI_frame_rate(avifile2);
|
||
|
codec = AVI_video_compressor(avifile2);
|
||
|
|
||
|
if (strcmp(codec,"LZO1") == 0) {
|
||
|
video_codec = TC_CODEC_LZO1;
|
||
|
} else if (strcmp(codec,"LZO2") == 0) {
|
||
|
video_codec = TC_CODEC_LZO2;
|
||
|
} else {
|
||
|
tc_log_warn(MOD_NAME, "Unsupported video codec %s", codec);
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|
||
|
|
||
|
tc_log_info(MOD_NAME, "codec=%s, fps=%6.3f, width=%d, height=%d",
|
||
|
codec, fps, width, height);
|
||
|
|
||
|
/*
|
||
|
* Step 1: initialize the LZO library
|
||
|
*/
|
||
|
|
||
|
if (lzo_init() != LZO_E_OK) {
|
||
|
tc_log_warn(MOD_NAME, "lzo_init() failed");
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|
||
|
|
||
|
wrkmem = (lzo_bytep) lzo_malloc(LZO1X_1_MEM_COMPRESS);
|
||
|
out = (lzo_bytep) lzo_malloc(BUFFER_SIZE);
|
||
|
|
||
|
if (wrkmem == NULL || out == NULL) {
|
||
|
tc_log_warn(MOD_NAME, "out of memory");
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|
||
|
|
||
|
return(TC_IMPORT_OK);
|
||
|
}
|
||
|
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* ------------------------------------------------------------
|
||
|
*
|
||
|
* decode stream
|
||
|
*
|
||
|
* ------------------------------------------------------------*/
|
||
|
|
||
|
MOD_decode
|
||
|
{
|
||
|
|
||
|
int key;
|
||
|
lzo_uint size;
|
||
|
long bytes_read=0;
|
||
|
|
||
|
if(param->flag == TC_VIDEO) {
|
||
|
// If we are using tccat, then do nothing here
|
||
|
if (param->fd != NULL) {
|
||
|
return(TC_IMPORT_OK);
|
||
|
}
|
||
|
|
||
|
out_len = AVI_read_frame(avifile2, out, &key);
|
||
|
|
||
|
if(verbose & TC_STATS && key)
|
||
|
tc_log_info(MOD_NAME, "keyframe %d", vframe_count);
|
||
|
|
||
|
if(out_len<=0) {
|
||
|
if(verbose & TC_DEBUG) AVI_print_error("AVI read video frame");
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|
||
|
|
||
|
if (video_codec == TC_CODEC_LZO1) {
|
||
|
r = lzo1x_decompress(out, out_len, param->buffer, &size, wrkmem);
|
||
|
} else {
|
||
|
tc_lzo_header_t *h = (tc_lzo_header_t *)out;
|
||
|
uint8_t *compdata = out + sizeof(*h);
|
||
|
int compsize = out_len - sizeof(*h);
|
||
|
if (h->magic != video_codec) {
|
||
|
tc_log_warn(MOD_NAME, "frame with invalid magic 0x%08X", h->magic);
|
||
|
return (TC_IMPORT_ERROR);
|
||
|
}
|
||
|
if (h->flags & TC_LZO_NOT_COMPRESSIBLE) {
|
||
|
ac_memcpy(param->buffer, compdata, compsize);
|
||
|
size = compsize;
|
||
|
r = LZO_E_OK;
|
||
|
} else {
|
||
|
r = lzo1x_decompress(compdata, compsize, param->buffer, &size, wrkmem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (r == LZO_E_OK) {
|
||
|
if(verbose & TC_DEBUG)
|
||
|
tc_log_info(MOD_NAME, "decompressed %lu bytes into %lu bytes",
|
||
|
(long) out_len, (long) param->size);
|
||
|
} else {
|
||
|
/* this should NEVER happen */
|
||
|
tc_log_warn(MOD_NAME, "internal error - decompression failed: %d", r);
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|
||
|
|
||
|
param->size = size;
|
||
|
//transcode v.0.5.0-pre8 addition
|
||
|
if(key) param->attributes |= TC_FRAME_IS_KEYFRAME;
|
||
|
|
||
|
++vframe_count;
|
||
|
|
||
|
return(TC_IMPORT_OK);
|
||
|
}
|
||
|
|
||
|
if(param->flag == TC_AUDIO) {
|
||
|
|
||
|
switch(audio_codec) {
|
||
|
|
||
|
case CODEC_RAW:
|
||
|
|
||
|
bytes_read = AVI_audio_size(avifile1, aframe_count);
|
||
|
|
||
|
if(bytes_read<=0) {
|
||
|
if(verbose & TC_DEBUG) AVI_print_error("AVI audio read frame");
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|
||
|
|
||
|
if(AVI_read_audio(avifile1, param->buffer, bytes_read) < 0) {
|
||
|
AVI_print_error("AVI audio read frame");
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|
||
|
|
||
|
param->size = bytes_read;
|
||
|
++aframe_count;
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
bytes_read = AVI_read_audio(avifile1, param->buffer, param->size);
|
||
|
|
||
|
if(bytes_read<0) {
|
||
|
if(verbose & TC_DEBUG) AVI_print_error("AVI audio read frame");
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|
||
|
|
||
|
if(bytes_read < param->size) param->size=bytes_read;
|
||
|
}
|
||
|
|
||
|
return(TC_IMPORT_OK);
|
||
|
}
|
||
|
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|
||
|
|
||
|
/* ------------------------------------------------------------
|
||
|
*
|
||
|
* close stream
|
||
|
*
|
||
|
* ------------------------------------------------------------*/
|
||
|
|
||
|
MOD_close
|
||
|
{
|
||
|
|
||
|
if(param->fd != NULL) pclose(param->fd);
|
||
|
|
||
|
if(param->flag == TC_AUDIO) return(TC_IMPORT_ERROR);
|
||
|
|
||
|
if(param->flag == TC_VIDEO) {
|
||
|
|
||
|
lzo_free(wrkmem);
|
||
|
lzo_free(out);
|
||
|
|
||
|
if(avifile2!=NULL) {
|
||
|
AVI_close(avifile2);
|
||
|
avifile2=NULL;
|
||
|
}
|
||
|
done_seek = 0;
|
||
|
return(TC_IMPORT_OK);
|
||
|
}
|
||
|
|
||
|
return(TC_IMPORT_ERROR);
|
||
|
}
|