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_mpeg2.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_mpeg2.c')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/import/import_mpeg2.c | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/import/import_mpeg2.c b/debian/transcode/transcode-1.1.7/import/import_mpeg2.c new file mode 100644 index 00000000..6d7c40ea --- /dev/null +++ b/debian/transcode/transcode-1.1.7/import/import_mpeg2.c @@ -0,0 +1,344 @@ +/* + * import_mpeg2.c + * + * Copyright (C) Thomas Oestreich - June 2001 + * + * 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_mpeg2.so" +#define MOD_VERSION "v0.4.0 (2003-10-02)" +#define MOD_CODEC "(video) MPEG2" + +#include "transcode.h" + +static int verbose_flag = TC_QUIET; +static int capability_flag = TC_CAP_RGB | TC_CAP_YUV | TC_CAP_VID; + +#define MOD_PRE mpeg2 +#include "import_def.h" + + +char import_cmd_buf[TC_BUF_MAX]; + +typedef struct tbuf_t { + int off; + int len; + char *d; +} tbuf_t; + +// m2v passthru +static int can_read = 1; +static tbuf_t tbuf; +static int m2v_passthru=0; +static FILE *f; // video fd + + +/* ------------------------------------------------------------ + * + * open stream + * + * ------------------------------------------------------------*/ + +MOD_open +{ + + char requant_buf[256]; + long sret; + + if(param->flag != TC_VIDEO) return(TC_IMPORT_ERROR); + + if(vob->ts_pid1==0) { // no transport stream + + switch(vob->im_v_codec) { + + case CODEC_RGB: + + sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, + "tcextract -x mpeg2 -i \"%s\" -d %d |" + " tcdecode -x mpeg2 -d %d", + vob->video_in_file, vob->verbose, vob->verbose); + if (sret < 0) + return(TC_IMPORT_ERROR); + + break; + + case CODEC_YUV: + + sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, + "tcextract -x mpeg2 -i \"%s\" -d %d |" + " tcdecode -x mpeg2 -d %d -y yuv420p", + vob->video_in_file, vob->verbose, vob->verbose); + if (sret < 0) + return(TC_IMPORT_ERROR); + + break; + + case CODEC_RAW: + case CODEC_RAW_YUV: + + memset(requant_buf, 0, sizeof (requant_buf)); + if (vob->m2v_requant > M2V_REQUANT_FACTOR) { + tc_snprintf (requant_buf, 256, " | tcrequant -d %d -f %f ", + vob->verbose, vob->m2v_requant); + } + m2v_passthru=1; + + sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, + "tcextract -x mpeg2 -i \"%s\" -d %d%s", + vob->video_in_file, vob->verbose, requant_buf); + if (sret < 0) + return(TC_IMPORT_ERROR); + + break; + } + + } else { + + switch(vob->im_v_codec) { + + case CODEC_RGB: + + sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, + "tccat -i \"%s\" -d %d -n 0x%x |" + " tcextract -x mpeg2 -t m2v -d %d |" + " tcdecode -x mpeg2 -d %d", + vob->video_in_file, vob->verbose, vob->ts_pid1, + vob->verbose, vob->verbose); + if (sret < 0) + return(TC_IMPORT_ERROR); + + break; + + case CODEC_YUV: + + sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, + "tccat -i \"%s\" -d %d -n 0x%x |" + " tcextract -x mpeg2 -t m2v -d %d |" + " tcdecode -x mpeg2 -d %d -y yuv420p", + vob->video_in_file, vob->verbose,vob->ts_pid1, + vob->verbose, vob->verbose); + if (sret < 0) + return(TC_IMPORT_ERROR); + + break; + } + } + + // print out + if(verbose_flag) tc_log_info(MOD_NAME, "%s", import_cmd_buf); + + param->fd = NULL; + + // popen + if((param->fd = popen(import_cmd_buf, "r"))== NULL) { + tc_log_perror(MOD_NAME, "popen RGB stream"); + return(TC_IMPORT_ERROR); + } + + // we handle the read; + if (m2v_passthru) { + f = param->fd; + param->fd = NULL; + + tbuf.d = tc_malloc (SIZE_RGB_FRAME); + tbuf.len = SIZE_RGB_FRAME; + tbuf.off = 0; + + if ((tbuf.len = fread(tbuf.d, 1, tbuf.len, f)) < 0) + return(TC_IMPORT_ERROR); + + // find a sync word + while (tbuf.off+4<tbuf.len) { + if (tbuf.d[tbuf.off+0]==0x0 && tbuf.d[tbuf.off+1]==0x0 && + tbuf.d[tbuf.off+2]==0x1 && + (unsigned char)tbuf.d[tbuf.off+3]==0xb3) break; + else tbuf.off++; + } + if (tbuf.off+4>=tbuf.len) { + tc_log_warn(MOD_NAME, "Internal Error. No sync word"); + return (TC_IMPORT_ERROR); + } + + } + + return(TC_IMPORT_OK); +} + +/* ------------------------------------------------------------ + * + * decode stream + * + * ------------------------------------------------------------*/ + +MOD_decode{ + + if(param->flag == TC_VIDEO && m2v_passthru) { + + // --------------------------------------------------- + // This code splits the MPEG2 elementary stream + // into packets. It sets the type of the packet + // as an frame attribute. + // I frames (== Key frames) are not only I frames, + // they also carry the sequence headers in the packet. + // --------------------------------------------------- + + int ID, start_seq, start_pic, pic_type; + + ID = tbuf.d[tbuf.off+3]&0xff; + + switch (ID) { + case 0xb3: // sequence + start_seq = tbuf.off; + + // look for pic header + while (tbuf.off+6<tbuf.len) { + + if (tbuf.d[tbuf.off+0]==0x0 && tbuf.d[tbuf.off+1]==0x0 && + tbuf.d[tbuf.off+2]==0x1 && tbuf.d[tbuf.off+3]==0x0 && + ((tbuf.d[tbuf.off+5]>>3)&0x7)>1 && + ((tbuf.d[tbuf.off+5]>>3)&0x7)<4) { + if (verbose & TC_DEBUG) + tc_log_warn(MOD_NAME, "Completed a sequence + I frame from %d -> %d", + start_seq, tbuf.off); + + param->attributes |= TC_FRAME_IS_KEYFRAME; + param->size = tbuf.off-start_seq; + + // spit frame out + ac_memcpy(param->buffer, tbuf.d+start_seq, param->size); + memmove(tbuf.d, tbuf.d+param->size, tbuf.len-param->size); + tbuf.off = 0; + tbuf.len -= param->size; + + if (verbose & TC_DEBUG) + tc_log_info(MOD_NAME, "%02x %02x %02x %02x", + tbuf.d[0]&0xff, tbuf.d[1]&0xff, + tbuf.d[2]&0xff, tbuf.d[3]&0xff); + return TC_IMPORT_OK; + } + else tbuf.off++; + } + + // not enough data. + if (tbuf.off+6 >= tbuf.len) { + + if (verbose & TC_DEBUG) tc_log_info(MOD_NAME, "Fetching in Sequence"); + memmove (tbuf.d, tbuf.d+start_seq, tbuf.len - start_seq); + tbuf.len -= start_seq; + tbuf.off = 0; + + if (can_read>0) { + can_read = fread (tbuf.d+tbuf.len, SIZE_RGB_FRAME-tbuf.len, 1, f); + tbuf.len += (SIZE_RGB_FRAME-tbuf.len); + } else { + tc_log_info(MOD_NAME, "No 1 Read %d", can_read); + /* XXX: Flush buffers */ + return TC_IMPORT_ERROR; + } + } + break; + + case 0x00: // pic header + + start_pic = tbuf.off; + pic_type = (tbuf.d[start_pic+5] >> 3) & 0x7; + tbuf.off++; + + while (tbuf.off+6<tbuf.len) { + if (tbuf.d[tbuf.off+0]==0x0 && tbuf.d[tbuf.off+1]==0x0 && + tbuf.d[tbuf.off+2]==0x1 && + (unsigned char)tbuf.d[tbuf.off+3]==0xb3) { + if (verbose & TC_DEBUG) + tc_log_info(MOD_NAME, "found a last P or B frame %d -> %d", + start_pic, tbuf.off); + + param->size = tbuf.off - start_pic; + + ac_memcpy(param->buffer, tbuf.d+start_pic, param->size); + memmove(tbuf.d, tbuf.d+param->size, tbuf.len-param->size); + tbuf.off = 0; + tbuf.len -= param->size; + + return TC_IMPORT_OK; + + } else if // P or B frame + (tbuf.d[tbuf.off+0]==0x0 && tbuf.d[tbuf.off+1]==0x0 && + tbuf.d[tbuf.off+2]==0x1 && tbuf.d[tbuf.off+3]==0x0 && + ((tbuf.d[tbuf.off+5]>>3)&0x7)>1 && + ((tbuf.d[tbuf.off+5]>>3)&0x7)<4) { + if (verbose & TC_DEBUG) + tc_log_info(MOD_NAME, "found a P or B frame from %d -> %d", + start_pic, tbuf.off); + + param->size = tbuf.off - start_pic; + + ac_memcpy(param->buffer, tbuf.d+start_pic, param->size); + memmove(tbuf.d, tbuf.d+param->size, tbuf.len-param->size); + tbuf.off = 0; + tbuf.len -= param->size; + + return TC_IMPORT_OK; + + } else tbuf.off++; + + // not enough data. + if (tbuf.off+6 >= tbuf.len) { + + memmove (tbuf.d, tbuf.d+start_pic, tbuf.len - start_pic); + tbuf.len -= start_pic; + tbuf.off = 0; + + if (can_read>0) { + can_read = fread (tbuf.d+tbuf.len, SIZE_RGB_FRAME-tbuf.len, 1, f); + tbuf.len += (SIZE_RGB_FRAME-tbuf.len); + } else { + tc_log_info(MOD_NAME, "No 1 Read %d", can_read); + /* XXX: Flush buffers */ + return TC_IMPORT_ERROR; + } + } + } + break; + default: + // should not get here + tc_log_warn(MOD_NAME, "Default case"); + tbuf.off++; + break; + } + + + } + return(TC_IMPORT_OK); +} + +/* ------------------------------------------------------------ + * + * close stream + * + * ------------------------------------------------------------*/ + +MOD_close +{ + + if(param->fd != NULL) pclose(param->fd); + if(f != NULL) pclose(f); + param->fd = f = NULL; + + return(TC_IMPORT_OK); +} |
