Sisyphus repositório
Última atualização: 1 outubro 2023 | SRPMs: 18631 | Visitas: 37850229
en ru br
ALT Linux repositórios
S:1.1.7-alt16
D:1.0.4-alt0.1
5.0: 1.0.7-alt2
4.1: 1.0.5-alt1
4.0: 1.0.2-alt3.3M40.1
3.0: 0.6.14-alt1.3
+backports:1.0.2-alt2.M30.2

Group :: Vídeo
RPM: transcode

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs e FR  Repocop 

/*
* export_dvraw.c
*
* Copyright (C) Thomas Östreich - 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.
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <libdv/dv.h>
#include "transcode.h"
#include "vid_aux.h"
#include "optstr.h"
#include "ioaux.h"

#define MOD_NAME "export_dvraw.so"
#define MOD_VERSION "v0.4a3 (2006-02-01)"
#define MOD_CODEC "(video) Digital Video | (audio) PCM"

static int verbose_flag=TC_QUIET;
static int capability_flag=TC_CAP_PCM|TC_CAP_RGB|TC_CAP_YUV|TC_CAP_VID|TC_CAP_YUV422;

#define MOD_PRE dvraw
#include "export_def.h"

static int fd;

static int16_t *audio_bufs[4];

static uint8_t *target = NULL;

static dv_encoder_t *encoder = NULL;
static uint8_t *pixels[3], *tmp_buf;

static int frame_size=0, format=0;
static int pass_through=0;

static int chans, rate;
static int dv_yuy2_mode=0;
static int dv_uyvy_mode=0;

static int media_type = 0;

/* Allocate a buffer aligned to the machine's page size, if known. The
* buffer must be freed with buffree() (not free()). */

void *_tc_bufalloc(const char *file, int line, size_t size)
{
#ifdef HAVE_GETPAGESIZE
unsigned long pagesize = getpagesize();
int8_t *base = malloc(size + sizeof(void *) + pagesize);
int8_t *ptr = NULL;
unsigned long offset = 0;

if (base == NULL) {
fprintf(stderr, "[%s:%d] tc_bufalloc(): can't allocate %lu bytes\n",
file, line, (unsigned long)size);
} else {
ptr = base + sizeof(void *);
offset = (unsigned long)ptr % pagesize;

if (offset)
ptr += (pagesize - offset);
((void **)ptr)[-1] = base; /* save the base pointer for freeing */
}
return ptr;
#else /* !HAVE_GETPAGESIZE */
return malloc(size);
#endif
}

/* Free a buffer allocated with tc_bufalloc(). */
void tc_buffree(void *ptr)
{
#ifdef HAVE_GETPAGESIZE
if (ptr)
free(((void **)ptr)[-1]);
#else
free(ptr);
#endif
}

#define tc_bufalloc(size) \
_tc_bufalloc(__FILE__, __LINE__, size)


/* ------------------------------------------------------------
*
* init codec
*
* ------------------------------------------------------------*/

MOD_init
{
int i;
if (param->flag == TC_VIDEO) {
int want_tmp_buf = 0;
target = tc_bufalloc(TC_FRAME_DV_PAL);

if (vob->dv_yuy2_mode) {
tmp_buf = tc_bufalloc(PAL_W*PAL_H*2); //max frame
dv_yuy2_mode = 1;
want_tmp_buf = 1;
}
if (vob->im_v_codec == CODEC_YUV422) {
tmp_buf = tc_bufalloc(PAL_W*PAL_H*2); //max frame
dv_uyvy_mode = 1;
want_tmp_buf = 1;
}
if (!target || (want_tmp_buf && !tmp_buf)) {
fprintf(stderr, "[%s] can't allocate video buffers\n", MOD_NAME);
return(TC_EXPORT_ERROR);
}

encoder = dv_encoder_new(FALSE, FALSE, FALSE);
if (!encoder) {
fprintf(stderr, "[%s] can't allocate video encoder\n", MOD_NAME);
return(TC_EXPORT_ERROR);
}

media_type |= TC_VIDEO;
return(TC_EXPORT_OK);
}

if (param->flag == TC_AUDIO) {
if (!(media_type & TC_VIDEO)) {
return(TC_EXPORT_ERROR);
}
// tmp audio buffer
for (i = 0; i < 4; i++) {
audio_bufs[i] = malloc(DV_AUDIO_MAX_SAMPLES * sizeof(int16_t));
if (!(audio_bufs[i])) {
fprintf(stderr, "[%s] can't allocate audio buffers\n", MOD_NAME);
return(TC_EXPORT_ERROR);
}
}

media_type |= TC_AUDIO;
return(TC_EXPORT_OK);
}

// invalid flag
return(TC_EXPORT_ERROR);
}

/* ------------------------------------------------------------
*
* open outputfile
*
* ------------------------------------------------------------*/

MOD_open
{
if (param->flag == TC_VIDEO) {
// video
if ((fd = open(vob->video_out_file, O_RDWR|O_CREAT|O_TRUNC,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH))<0) {
perror("open file");
return(TC_EXPORT_ERROR);
}

switch (vob->im_v_codec) {
case CODEC_RGB:
format = 0;
if (verbose & TC_DEBUG) {
fprintf(stderr, "[%s] raw format is RGB\n", MOD_NAME);
}
break;
case CODEC_YUV:
format = 1;
if (verbose & TC_DEBUG) {
fprintf(stderr, "[%s] raw format is YV12\n", MOD_NAME);
}
break;
case CODEC_YUV422:
format = 1;
if (verbose & TC_DEBUG) {
fprintf(stderr, "[%s] raw format is UYVY\n", MOD_NAME);
}
break;
case CODEC_RAW: /* fallthrough */
case CODEC_RAW_YUV:
format = 1;
pass_through = 1;
break;
default:
fprintf(stderr, "[%s] codec not supported (0x%x)\n",
MOD_NAME, vob->im_v_codec);
return(TC_EXPORT_ERROR);
}

// for reading
frame_size = (vob->ex_v_height==PAL_H) ? TC_FRAME_DV_PAL:TC_FRAME_DV_NTSC;

if (verbose & TC_DEBUG) {
fprintf(stderr, "[%s] encoding to %s DV\n",
MOD_NAME, (vob->ex_v_height==PAL_H) ? "PAL":"NTSC");
}

// Store aspect ratio - ex_asr uses the value 3 for 16x9
encoder->is16x9 = ((vob->ex_asr<0) ? vob->im_asr:vob->ex_asr) == 3;
encoder->isPAL = (vob->ex_v_height==PAL_H);
encoder->vlc_encode_passes = 3;
encoder->static_qno = 0;

if (vob->ex_v_string != NULL) {
if (optstr_get (vob->ex_v_string, "qno", "%d", &encoder->static_qno) == 1) {
fprintf(stderr, "[%s] using quantisation: %d\n",
MOD_NAME, encoder->static_qno);
}
}
encoder->force_dct = DV_DCT_AUTO;

return(TC_EXPORT_OK);
}

if (param->flag == TC_AUDIO) {
int bytealignment;
int bytespersecond;
int bytesperframe;

chans = vob->dm_chan;
//re-sampling only with -J resample possible
rate = vob->a_rate;

bytealignment = (chans==2) ? 4:2;
bytespersecond = rate * bytealignment;
bytesperframe = bytespersecond/(encoder->isPAL ? 25 : 30);

if (verbose & TC_DEBUG) {
fprintf(stderr, "[%s] audio: CH=%d, f=%d, balign=%d, bps=%d, bpf=%d\n",
MOD_NAME, chans, rate, bytealignment, bytespersecond, bytesperframe);
}

return(TC_EXPORT_OK);
}
// invalid flag
return(TC_EXPORT_ERROR);
}

/* ------------------------------------------------------------
*
* encode and export
*
* ------------------------------------------------------------*/

MOD_encode
{
int i;
time_t now = time(NULL);

if (param->flag == TC_VIDEO) {
if (pass_through) {
tc_memcpy(target, param->buffer, frame_size);
} else {
pixels[0] = param->buffer;

if (encoder->isPAL) {
pixels[2] = param->buffer + PAL_W*PAL_H;
pixels[1] = param->buffer + (PAL_W*PAL_H*5)/4;
} else {
pixels[2] = param->buffer + NTSC_W*NTSC_H;
pixels[1] = param->buffer + (NTSC_W*NTSC_H*5)/4;
}

if (dv_yuy2_mode && !dv_uyvy_mode) {
yv12toyuy2(pixels[0], pixels[1], pixels[2], tmp_buf,
PAL_W, (encoder->isPAL)? PAL_H : NTSC_H);
pixels[0]=tmp_buf;
}

if (dv_uyvy_mode) {
uyvytoyuy2(pixels[0], tmp_buf,
PAL_W, (encoder->isPAL)? PAL_H : NTSC_H);
pixels[0]=tmp_buf;
}

dv_encode_full_frame(encoder, pixels, (format)?e_dv_color_yuv:e_dv_color_rgb, target);

}//no pass-through
#ifdef LIBDV_099
encoder->samples_this_frame = param->size;
#endif
dv_encode_metadata(target, encoder->isPAL, encoder->is16x9, &now, 0);
dv_encode_timecode(target, encoder->isPAL, 0);

if (media_type == TC_VIDEO) { /* only video */
if (p_write(fd, target, frame_size) != frame_size) {
perror("write video frame");
return(TC_EXPORT_ERROR);
}
}
/*
* else (only case: this module used *also* for audio) be lazy
* and wait for writing data after the audio encoding
*/

return(TC_EXPORT_OK);
}

if (param->flag == TC_AUDIO) {
#ifdef WORDS_BIGENDIAN
for (i = 0; i < param->size; i += 2) {
char tmp = param->buffer[i];
param->buffer[i] = param->buffer[i+1];
param->buffer[i+1] = tmp;
}
#endif
// Although dv_encode_full_audio supports 4 channels, the internal
// PCM data (param->buffer) is only carrying 2 channels so only deal
// with 1 or 2 channel audio.
// Work around apparent bug in dv_encode_full_audio when chans == 1
// by putting silence in 2nd channel and calling with chans = 2
if (chans == 1) {
audio_bufs[0] = (int16_t *)param->buffer;
memset(audio_bufs[1], 0, DV_AUDIO_MAX_SAMPLES * 2);
dv_encode_full_audio(encoder, audio_bufs, 2, rate, target);
} else {
// assume 2 channel, demultiplex for libdv API
for (i = 0; i < param->size/4; i++) {
audio_bufs[0][i] = ((int16_t *)param->buffer)[i*2];
audio_bufs[1][i] = ((int16_t *)param->buffer)[i*2+1];
}
dv_encode_full_audio(encoder, audio_bufs, chans, rate, target);
}

/* write raw DV frame. */
if (p_write(fd, target, frame_size) != frame_size) {
perror("write frame");
return(TC_EXPORT_ERROR);
}
return(TC_EXPORT_OK);
}
// invalid flag
return(TC_EXPORT_ERROR);
}

/* ------------------------------------------------------------
*
* stop encoder
*
* ------------------------------------------------------------*/

MOD_stop
{
int i;

if (param->flag == TC_VIDEO) {
dv_encoder_free(encoder);
return(TC_EXPORT_OK);
}

if (param->flag == TC_AUDIO) {
for (i = 0; i < 4; i++) {
free(audio_bufs[i]);
}
return(TC_EXPORT_OK);
}
return(TC_EXPORT_ERROR);
}

/* ------------------------------------------------------------
*
* close outputfiles
*
* ------------------------------------------------------------*/

MOD_close
{
if (param->flag == TC_VIDEO) {
close(fd);
return(TC_EXPORT_OK);
}

if (param->flag == TC_AUDIO) {
return(TC_EXPORT_OK);
}
return(TC_EXPORT_ERROR);
}

 
projeto & código: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
mantenedor atual: Michael Shigorin
mantenedor da tradução: Fernando Martini aka fmartini © 2009