===================================================================
--- libmpcodecs/ae_pcm.c (revision 26838)
+++ libmpcodecs/ae_pcm.c (working copy)
@@ -14,7 +14,38 @@
#include "libmpdemux/muxer.h"
#include "ae_pcm.h"
+static int ao_pipe = 0;
+static int pipe_only = 0;
+#define WAV_ID_RIFF 0x46464952 /* "RIFF" */
+#define WAV_ID_WAVE 0x45564157 /* "WAVE" */
+#define WAV_ID_FMT 0x20746d66 /* "fmt " */
+#define WAV_ID_DATA 0x61746164 /* "data" */
+#define WAV_ID_PCM 0x0001
+
+struct WaveHeader
+{
+ uint32_t riff;
+ uint32_t file_length;
+ uint32_t wave;
+ uint32_t fmt;
+ uint32_t fmt_length;
+ uint16_t fmt_tag;
+ uint16_t channels;
+ uint32_t sample_rate;
+ uint32_t bytes_per_second;
+ uint16_t block_align;
+ uint16_t bits;
+ uint32_t data;
+ uint32_t data_length;
+};
+
+m_option_t pcmopts_conf[] = {
+ {"pipe", &ao_pipe, CONF_TYPE_INT, 0, 0, 0, NULL},
+ {"pipeonly", &pipe_only, CONF_TYPE_FLAG, 0, 0, 0, NULL},
+ {NULL, NULL, 0, 0, 0, 0, NULL}
+};
+
static int bind_pcm(audio_encoder_t *encoder, muxer_stream_t *mux_a)
{
mux_a->h.dwScale=1;
@@ -39,6 +70,10 @@
static int encode_pcm(audio_encoder_t *encoder, uint8_t *dest, void *src, int nsamples, int max_size)
{
max_size = FFMIN(nsamples, max_size);
+ if (ao_pipe) {
+ max_size = write(ao_pipe, src, max_size);
+ if (pipe_only) return max_size;
+ }
if (encoder->params.channels == 6 || encoder->params.channels == 5) {
max_size -= max_size % (encoder->params.channels * 2);
reorder_channel_copy_nch(src, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
@@ -78,6 +113,26 @@
encoder->encode = encode_pcm;
encoder->close = close_pcm;
+ if (ao_pipe) {
+ struct WaveHeader wavhdr;
+ wavhdr.riff = le2me_32(WAV_ID_RIFF);
+ wavhdr.wave = le2me_32(WAV_ID_WAVE);
+ wavhdr.fmt = le2me_32(WAV_ID_FMT);
+ wavhdr.fmt_length = le2me_32(16);
+ wavhdr.fmt_tag = le2me_16(WAV_ID_PCM);
+ wavhdr.channels = le2me_16(encoder->params.channels);
+ wavhdr.sample_rate = le2me_32(encoder->params.sample_rate);
+ wavhdr.bits = le2me_16(16);
+ wavhdr.block_align = le2me_16(wavhdr.channels * (16 / 8));
+ wavhdr.bytes_per_second = le2me_32(encoder->params.sample_rate * wavhdr.block_align);
+
+ wavhdr.data = le2me_32(WAV_ID_DATA);
+ wavhdr.data_length=le2me_32(0x7ffff000);
+ wavhdr.file_length = wavhdr.data_length + sizeof(wavhdr) - 8;
+
+ write(ao_pipe, &wavhdr, sizeof(wavhdr));
+ mp_msg(MSGT_MENCODER, MSGL_INFO, "Audio data will be piped out through fd %d\n", ao_pipe);
+ }
return 1;
}
Index: libmpcodecs/ve_vfw.c
===================================================================
--- libmpcodecs/ve_vfw.c (revision 26838)
+++ libmpcodecs/ve_vfw.c (working copy)
@@ -33,6 +33,8 @@
static char *vfw_param_codec = NULL;
static char *vfw_param_compdata = NULL;
+extern char *vfw_param_tmpprefix;
+char *vfw_param_tmpprefix = NULL;
static HRESULT CoInitRes = -1;
#include "m_option.h"
@@ -40,6 +42,7 @@
m_option_t vfwopts_conf[]={
{"codec", &vfw_param_codec, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"compdata", &vfw_param_compdata, CONF_TYPE_STRING, 0, 0, 0, NULL},
+ {"tmpprefix", &vfw_param_tmpprefix, CONF_TYPE_STRING, 0, 0, 0, NULL},
{NULL, NULL, 0, 0, 0, 0, NULL}
};
Index: libmpcodecs/ve_raw.c
===================================================================
--- libmpcodecs/ve_raw.c (revision 26838)
+++ libmpcodecs/ve_raw.c (working copy)
@@ -18,6 +18,8 @@
#include "mp_image.h"
#include "vf.h"
+#include "m_option.h"
+#include "libavutil/rational.h"
//===========================================================================//
@@ -26,6 +28,27 @@
};
#define mux_v (vf->priv->mux)
+typedef struct {
+ int format;
+ int width;
+ int height;
+ int interlace;
+ int fps_num;
+ int fps_den;
+ int pixelaspect_num;
+ int pixelaspect_den;
+ int frameCount;
+} YUV_INFO;
+
+static int pipefd;
+
+m_option_t rawvidopts_conf[] =
+{
+ /* Standard things mencoder should be able to treat directly */
+ {"pipe", &pipefd, CONF_TYPE_INT, 0, 0, 0, NULL},
+ {NULL, 0, 0, 0, 0, 0, NULL}
+};
+
static int set_format(struct vf_instance_s *vf, unsigned int fmt) {
mux_v->bih->biCompression = fmt;
@@ -86,6 +109,7 @@
unsigned int flags, unsigned int outfmt)
{
int ret;
+ AVRational pixelaspect = av_div_q((AVRational){d_width, d_height}, (AVRational){width, height});
mux_v->bih->biWidth = width;
mux_v->bih->biHeight = height;
mux_v->aspect = (float)d_width/d_height;
@@ -93,6 +117,23 @@
if (!ret) return 0;
mux_v->bih->biSizeImage = mux_v->bih->biWidth*mux_v->bih->biHeight*mux_v->bih->biBitCount/8;
+
+ if (pipefd) {
+ YUV_INFO yuv_info = {
+ 0,
+ mux_v->bih->biWidth,
+ mux_v->bih->biHeight,
+ 'p',
+ mux_v->h.dwRate,
+ mux_v->h.dwScale,
+ pixelaspect.num, pixelaspect.den,
+ 0
+ };
+ int len = sizeof(yuv_info);
+ write(pipefd, &len, sizeof(len));
+ write(pipefd, &yuv_info, len);
+ }
+
return 1;
}
@@ -122,8 +163,15 @@
}
static int put_image(struct vf_instance_s *vf, mp_image_t *mpi, double pts) {
+ if (pipefd) {
+ char nulldata = 0;
+ mux_v->buffer = &nulldata;
+ muxer_write_chunk(mux_v, 1, 0x10, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
+ write(pipefd, mpi->planes[0], mpi->width*mpi->height*mux_v->bih->biBitCount/8);
+ } else {
mux_v->buffer = mpi->planes[0];
muxer_write_chunk(mux_v, mpi->width*mpi->height*mux_v->bih->biBitCount/8, 0x10, pts, pts);
+ }
return 1;
}
Index: fmt-conversion.h
===================================================================
--- fmt-conversion.h (revision 26838)
+++ fmt-conversion.h (working copy)
@@ -15,7 +15,7 @@
case IMGFMT_BGR16:
return PIX_FMT_BGR565;
case IMGFMT_BGR15:
- return PIX_FMT_BGR555;
+ return PIX_FMT_RGB555;
case IMGFMT_BGR8:
return PIX_FMT_BGR8;
case IMGFMT_BGR4:
@@ -34,7 +34,7 @@
case IMGFMT_RGB16:
return PIX_FMT_RGB565;
case IMGFMT_RGB15:
- return PIX_FMT_RGB555;
+ return PIX_FMT_BGR555;
case IMGFMT_RGB8:
return PIX_FMT_RGB8;
case IMGFMT_RGB4:
Index: libao2/ao_pcm.c
===================================================================
--- libao2/ao_pcm.c (revision 26838)
+++ libao2/ao_pcm.c (working copy)
@@ -30,6 +30,7 @@
static char *ao_outputfilename = NULL;
static int ao_pcm_waveheader = 1;
static int fast = 0;
+static int ao_pipe = 0;
#define WAV_ID_RIFF 0x46464952 /* "RIFF" */
#define WAV_ID_WAVE 0x45564157 /* "WAVE" */
@@ -73,6 +74,7 @@
{"waveheader", OPT_ARG_BOOL, &ao_pcm_waveheader, NULL},
{"file", OPT_ARG_MSTRZ, &ao_outputfilename, NULL},
{"fast", OPT_ARG_BOOL, &fast, NULL},
+ {"pipe", OPT_ARG_INT, &ao_pipe, NULL},
{NULL}
};
// set defaults
@@ -81,7 +83,7 @@
if (subopt_parse(ao_subdevice, subopts) != 0) {
return 0;
}
- if (!ao_outputfilename){
+ if (!ao_outputfilename && !ao_pipe){
ao_outputfilename =
strdup(ao_pcm_waveheader?"audiodump.wav":"audiodump.pcm");
}
@@ -138,7 +140,12 @@
(channels > 1) ? "Stereo" : "Mono", af_fmt2str_short(format));
mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_PCM_HintInfo);
+ if (ao_pipe) {
+ mp_msg(MSGT_AO, MSGL_INFO, "Audio data will be piped out through fd %d\n", ao_pipe);
+ fp = fdopen(ao_pipe, "wb");
+ } else {
fp = fopen(ao_outputfilename, "wb");
+ }
if(fp) {
if(ao_pcm_waveheader){ /* Reserve space for wave header */
fwrite(&wavhdr,sizeof(wavhdr),1,fp);
@@ -154,13 +161,17 @@
// close audio device
static void uninit(int immed){
- if(ao_pcm_waveheader && fseek(fp, 0, SEEK_SET) == 0){ /* Write wave header */
+ if(!ao_pipe && ao_pcm_waveheader && fseek(fp, 0, SEEK_SET) == 0){ /* Write wave header */
wavhdr.file_length = wavhdr.data_length + sizeof(wavhdr) - 8;
wavhdr.file_length = le2me_32(wavhdr.file_length);
wavhdr.data_length = le2me_32(wavhdr.data_length);
fwrite(&wavhdr,sizeof(wavhdr),1,fp);
}
fclose(fp);
+ if (ao_pipe) {
+ close(ao_pipe);
+ ao_pipe = 0;
+ }
if (ao_outputfilename)
free(ao_outputfilename);
ao_outputfilename = NULL;
Index: Makefile
===================================================================
--- Makefile (revision 26838)
+++ Makefile (working copy)
@@ -499,6 +499,7 @@
libao2/ao_mpegpes.c \
libao2/ao_null.c \
libao2/ao_pcm.c \
+ libao2/ao_pipe.c \
$(addprefix libao2/,$(AO_SRCS)) \
libvo/aspect.c \
libvo/geometry.c \
@@ -507,6 +508,7 @@
libvo/vo_mpegpes.c \
libvo/vo_null.c \
libvo/vo_yuv4mpeg.c \
+ libvo/vo_pipe.c \
$(addprefix libvo/,$(VO_SRCS)) \
SRCS_MPLAYER-$(APPLE_IR) += input/appleir.c
Index: cfg-mencoder.h
===================================================================
--- cfg-mencoder.h (revision 26838)
+++ cfg-mencoder.h (working copy)
@@ -19,6 +19,8 @@
extern m_option_t faacopts_conf[];
extern m_option_t vfwopts_conf[];
extern m_option_t xvidencopts_conf[];
+extern m_option_t pcmopts_conf[];
+extern m_option_t rawvidopts_conf[];
extern void x264enc_set_param(const m_option_t* opt, char* arg);
@@ -250,6 +252,7 @@
{"x264encopts", &x264enc_set_param, CONF_TYPE_FUNC_PARAM, CONF_GLOBAL, 0, 0, NULL},
#endif
+ {"rawvidopts", rawvidopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
#ifdef USE_LIBLZO
{"nuvopts", nuvopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
#endif
@@ -257,6 +260,7 @@
#ifdef USE_LIBAVFORMAT
{"lavfopts", lavfopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
#endif
+ {"pcmopts", pcmopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
#include "cfg-common-opts.h"
Index: libvo/video_out.c
===================================================================
--- libvo/video_out.c (revision 26838)
+++ libvo/video_out.c (working copy)
@@ -112,6 +112,7 @@
extern vo_functions_t video_out_quartz;
extern vo_functions_t video_out_pnm;
extern vo_functions_t video_out_md5sum;
+extern vo_functions_t video_out_pipe;
const vo_functions_t* const video_out_drivers[] =
{
@@ -222,6 +223,7 @@
#endif
&video_out_mpegpes,
&video_out_yuv4mpeg,
+ &video_out_pipe,
#ifdef HAVE_PNG
&video_out_png,
#endif
Index: libvo/vo_yuv4mpeg.c
===================================================================
--- libvo/vo_yuv4mpeg.c (revision 26838)
+++ libvo/vo_yuv4mpeg.c (working copy)
@@ -68,6 +68,7 @@
static uint8_t *rgb_line_buffer = NULL;
static char *yuv_filename = NULL;
+static int yuv_pipe = 0;
static int using_format = 0;
static FILE *yuv_out;
@@ -147,7 +148,12 @@
write_bytes = image_width * image_height * 3 / 2;
image = malloc(write_bytes);
+ if (yuv_pipe) {
+ yuv_out = fdopen(yuv_pipe, "wb");
+ mp_msg(MSGT_VO,MSGL_INFO, "Video frames output to pipe %d (0x%X) \n", yuv_pipe, yuv_out);
+ } else {
yuv_out = fopen(yuv_filename, "wb");
+ }
if (!yuv_out || image == 0)
{
mp_msg(MSGT_VO,MSGL_FATAL,
@@ -244,11 +250,16 @@
free(line_state);
}
-static void vo_y4m_write(const void *ptr, const size_t num_bytes)
+static int vo_y4m_write(const void *ptr, const size_t num_bytes)
{
if (fwrite(ptr, 1, num_bytes, yuv_out) != num_bytes)
+ /*
mp_msg(MSGT_VO,MSGL_ERR,
MSGTR_VO_YUV4MPEG_OutFileWriteError);
+ */
+ return -1;
+ else
+ return 0;
}
static int write_last_frame(void)
@@ -297,8 +308,7 @@
}
}
/* Write progressive frame */
- vo_y4m_write(image, write_bytes);
- return VO_TRUE;
+ return !vo_y4m_write(image, write_bytes) ? VO_TRUE : VO_FALSE;
}
static void flip_page (void)
@@ -474,6 +484,10 @@
fclose(yuv_out);
yuv_out = NULL;
+ if (yuv_pipe)
+ close(yuv_pipe);
+ yuv_pipe = 0;
+
if(rgb_buffer)
free(rgb_buffer);
rgb_buffer = NULL;
@@ -502,6 +516,7 @@
{"interlaced", OPT_ARG_BOOL, &il, NULL},
{"interlaced_bf", OPT_ARG_BOOL, &il_bf, NULL},
{"file", OPT_ARG_MSTRZ, &yuv_filename, NULL},
+ {"pipe", OPT_ARG_INT, &yuv_pipe, NULL},
{NULL}
};
Index: mplayer.c
===================================================================
--- mplayer.c (revision 26838)
+++ mplayer.c (working copy)
@@ -93,6 +93,9 @@
char *heartbeat_cmd;
+/* XXX: Fixme. The ugliest solution ever. */
+char *vfw_param_tmpprefix = NULL;
+
#define ROUND(x) ((int)((x)<0 ? (x)-0.5 : (x)+0.5))
#ifdef HAVE_RTC
Index: loader/win32.c
===================================================================
--- loader/win32.c (revision 26838)
+++ loader/win32.c (working copy)
@@ -46,6 +46,7 @@
#include "loader.h"
#include "com.h"
#include "ext.h"
+#include "m_config.h"
#include <stdlib.h>
#include <assert.h>
@@ -64,6 +65,7 @@
#include <dirent.h>
#include <sys/time.h>
#include <sys/timeb.h>
+#include <sys/stat.h>
#ifdef HAVE_KSTAT
#include <kstat.h>
#endif
@@ -92,6 +94,8 @@
char* def_path = WIN32_PATH;
+extern char* vfw_param_tmpprefix;
+
static void do_cpuid(unsigned int ax, unsigned int *regs)
{
__asm__ __volatile__
@@ -3535,14 +3539,26 @@
free(tmp);
return result;
}
- if (strstr(cs1, "vp3"))
+ if (strstr(cs1, "vp3")||strstr(cs1, ".fpf"))
{
int r;
int flg = 0;
- char* tmp=malloc(20 + strlen(cs1));
- strcpy(tmp, "/tmp/");
+ char* tmp;
+
+ if (NULL != vfw_param_tmpprefix)
+ {
+ /* custom file prefix, e.g. '/tmp/mencoder/' */
+ tmp = malloc(strlen(vfw_param_tmpprefix) + strlen(cs1) + 10);
+ strcpy(tmp, vfw_param_tmpprefix);
+ r = strlen(vfw_param_tmpprefix);
+ }
+ else
+ {
+ tmp = malloc(30 + strlen(cs1));
+ strcpy(tmp, "/tmp/");
+ r = 5;
+ }
strcat(tmp, cs1);
- r = 4;
while (tmp[r])
{
if (tmp[r] == ':' || tmp[r] == '\\')
@@ -3553,10 +3569,10 @@
flg |= O_RDONLY;
else if (GENERIC_WRITE & i1)
{
- flg |= O_WRONLY;
+ flg |= O_WRONLY | O_CREAT;
printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg);
}
- r=open(tmp, flg);
+ r=open(tmp, flg, S_IRWXU);
free(tmp);
return r;
}
Hello,
I've created patch for mencoder/mplayer, which enables the user to
decode audio or video output to a pipe. The patch is applied below. It's
basically derived from the MediaCoder project's mplayer patch, and is
rather straightforward. Apply in the svn root with patch -p0
With this patch applied to the latest svn revision (26838), I tried to
transcode video using pipes. This results in a transcoded video stream,
but the horizontal alignment of the result is wrong:
http://bram.name/~brama/pics/output_shifted.png
In this picture, you can see a sharp vertical black line in the left
side. It seems the X-offset of the picture has shifted a bit to the
right, with the rightmost bit of the picture wrapped around.
How can this offset occur? In the past I've experienced similar
problems, which occurred because there was some garbage prepended to
the decoded stream. However, with this patch all data that's written to
it should only be the video data and nothing else.
I'm hoping someone here can shed a light on this problem. Other
solutions which allow me to use mencoder/mplayer to decode both video
and audio streams individually to separate files is welcome too.
I've used these commands to do the transcoding:
mkfifo /tmp/videopipe
export IN=/tmp/input.avi
export OUT=/tmp/output.avi
export WIDTH=480
export HEIGHT=360
# start consumer of video pipe first
mencoder /tmp/videopipe -o "$OUT" -ofps 25 -noaspect -demuxer rawvideo -rawvideo fps=25:w=${WIDTH}:h=${HEIGHT}:format=i420 -nosound -ovc xvid -xvidencopts bitrate=800 &
# demux video stream to named pipe
mencoder -quiet -of rawvideo -ovc raw -rawvidopts pipe=6 -ofps 25 -vf harddup,format=i420 -nosound "$IN" -o NUL 6>/tmp/videopipe
wait # waits for encoder background job to complete
Best regards,
Bram
No comments:
Post a Comment