mirror of
https://github.com/mpv-player/mpv
synced 2025-02-20 06:46:55 +00:00
Merge svn changes up to r30876
This commit is contained in:
commit
0269d22d32
@ -7480,6 +7480,48 @@ Larger radius makes for smoother gradients, but also prevents the filter
|
||||
from modifying pixels near detailed regions (default: 16).
|
||||
.RE
|
||||
.
|
||||
.TP
|
||||
.B fixpts[=options]
|
||||
Fixes the presentation timestamps (PTS) of the frames.
|
||||
By default, the PTS passed to the next filter is dropped, but the following
|
||||
options can change that:
|
||||
.RSs
|
||||
.IPs print
|
||||
Print the incoming PTS.
|
||||
.IPs fps=<fps>
|
||||
Specify a frame per second value.
|
||||
.IPs start=<pts>
|
||||
Specify an initial value for the PTS.
|
||||
.IPs autostart=<n>
|
||||
Uses the
|
||||
.IR n th
|
||||
incoming PTS as the initial PTS.
|
||||
All previous pts are kept, so setting a huge value or \-1 keeps the PTS
|
||||
intact.
|
||||
.IPs autofps=<n>
|
||||
Uses the
|
||||
.IR n th
|
||||
incoming PTS after the end of autostart to determine the framerate.
|
||||
.RE
|
||||
.sp 1
|
||||
.RS
|
||||
.I EXAMPLE:
|
||||
.RE
|
||||
.PD 0
|
||||
.RSs
|
||||
.IPs "\-vf fixpts=fps=24000/1001,ass,fixpts"
|
||||
Generates a new sequence of PTS, uses it for ASS subtitles, then drops it.
|
||||
Generating a new sequence is useful when the timestamps are reset during the
|
||||
program; this is frequent on DVDs.
|
||||
Dropping it may be necessary to avoid confusing encoders.
|
||||
.RE
|
||||
.PD 1
|
||||
.sp 1
|
||||
.RS
|
||||
.I NOTE:
|
||||
Using this filter together with any sort of seeking (including -ss and EDLs)
|
||||
may make demons fly out of your nose.
|
||||
.RE
|
||||
.
|
||||
.
|
||||
.SH "GENERAL ENCODING OPTIONS (MENCODER ONLY)"
|
||||
@ -10668,6 +10710,52 @@ SVC encodes.
|
||||
.TP
|
||||
.B (no)aud
|
||||
Write access unit delimeters to the stream (default: disabled).
|
||||
Enable this only if your target container format requires access unit
|
||||
delimiters.
|
||||
.
|
||||
.TP
|
||||
.B overscan=<undef|show|crop>
|
||||
Include VUI overscan information in the stream (default: disabled).
|
||||
See doc/vui.txt in the x264 source code for more information.
|
||||
.
|
||||
.TP
|
||||
.B videoformat=<component|pal|ntsc|secam|mac|undef>
|
||||
Include VUI video format information in the stream (default: disabled).
|
||||
This is a purely informative setting for describing the original source.
|
||||
See doc/vui.txt in the x264 source code for more information.
|
||||
.
|
||||
.TP
|
||||
.B (no)fullrange
|
||||
Include VUI full range information in the stream (default: disabled).
|
||||
Use this option if your source video is not range limited.
|
||||
See doc/vui.txt in the x264 source code for more information.
|
||||
.
|
||||
.TP
|
||||
.B colorprim=<bt709|bt470m|bt470bg|smpte170m|smpte240m|film|undef>
|
||||
Include color primaries information (default: disabled).
|
||||
This can be used for color correction.
|
||||
See doc/vui.txt in the x264 source code for more information.
|
||||
.
|
||||
.TP
|
||||
.B transfer=<bt709|bt470m|bt470bg|linear|log100|log316|smpte170m|smpte240m>
|
||||
Include VUI transfer characteristics information in the stream
|
||||
(default: disabled).
|
||||
This can be used for color correction.
|
||||
See doc/vui.txt in the x264 source code for more information.
|
||||
.
|
||||
.TP
|
||||
.B colormatrix=<bt709|fcc|bt470bg|smpte170m|smpte240m|GBR|YCgCo>
|
||||
Include VUI matrix coefficients in the stream (default: disabled).
|
||||
This can be used for color correction.
|
||||
See doc/vui.txt in the x264 source code for more information.
|
||||
.
|
||||
.TP
|
||||
.B chromaloc=<0-5>
|
||||
Include VUI chroma sample location information in the stream (default:
|
||||
disabled).
|
||||
Use this option to ensure alignment of the chroma and luma planes after
|
||||
color space conversions.
|
||||
See doc/vui.txt in the x264 source code for more information.
|
||||
.
|
||||
.TP
|
||||
.B log=<\-1\-3>
|
||||
|
@ -789,14 +789,8 @@ while seeking through RealMedia streams?
|
||||
What about DVD navigation/menus?
|
||||
</para></question>
|
||||
<answer><para>
|
||||
<application>MPlayer</application> does not support DVD menus due to serious
|
||||
architectural limitations that prevent proper handling of still images and
|
||||
interactive content. If you want to have fancy menus, you will have to use
|
||||
another player like <application>xine</application>,
|
||||
<application>VLC</application> or <application>Ogle</application>.
|
||||
If you want to see DVD navigation in <application>MPlayer</application> you
|
||||
will have to implement it yourself, but be aware that it is a major
|
||||
undertaking.
|
||||
<application>MPlayer</application> should support DVD menus nowadays.
|
||||
Your mileage may vary.
|
||||
</para></answer>
|
||||
</qandaentry>
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -313,6 +313,7 @@ SRCS_COMMON-$(WIN32DLL) += libmpcodecs/ad_acm.c \
|
||||
loader/dshow/DS_VideoDecoder.c \
|
||||
loader/dshow/allocator.c \
|
||||
loader/dshow/cmediasample.c \
|
||||
loader/dshow/graph.c \
|
||||
loader/dshow/guids.c \
|
||||
loader/dshow/inputpin.c \
|
||||
loader/dshow/mediatype.c \
|
||||
@ -425,6 +426,7 @@ SRCS_COMMON = asxparser.c \
|
||||
libmpcodecs/vf_field.c \
|
||||
libmpcodecs/vf_fil.c \
|
||||
libmpcodecs/vf_filmdint.c \
|
||||
libmpcodecs/vf_fixpts.c \
|
||||
libmpcodecs/vf_flip.c \
|
||||
libmpcodecs/vf_format.c \
|
||||
libmpcodecs/vf_framestep.c \
|
||||
|
2
configure
vendored
2
configure
vendored
@ -289,7 +289,7 @@ Codecs:
|
||||
--enable-jpeg enable JPEG input/output support [autodetect]
|
||||
--enable-libcdio enable libcdio support [autodetect]
|
||||
--enable-liblzo enable liblzo support [autodetect]
|
||||
--disable-win32dll disable Win32 DLL support [enabled]
|
||||
--disable-win32dll disable Win32 DLL support [autodetect]
|
||||
--disable-qtx disable QuickTime codecs support [enabled]
|
||||
--disable-xanim disable XAnim codecs support [enabled]
|
||||
--disable-real disable RealPlayer codecs support [enabled]
|
||||
|
@ -3677,6 +3677,13 @@ audiocodec raatrcmac
|
||||
driver realaud
|
||||
dll "atrc.bundle/Contents/MacOS/atrc"
|
||||
|
||||
audiocodec ffadpcmadx
|
||||
info "FFmpeg SEGA CRI adx codec"
|
||||
status working
|
||||
fourcc Sadx ; internal MPlayer FourCC
|
||||
driver ffmpeg
|
||||
dll adpcm_adx
|
||||
|
||||
audiocodec ffadpcmimaamv
|
||||
info "FFmpeg AMV IMA ADPCM audio"
|
||||
status working
|
||||
|
@ -90,7 +90,7 @@ static OSErr (*QTNewGWorldFromPtr)(GWorldPtr *gw,
|
||||
GWorldFlags flags,
|
||||
void *baseAddr,
|
||||
long rowBytes);
|
||||
static OSErr (*NewHandleClear)(Size byteCount);
|
||||
static Handle (*NewHandleClear)(Size byteCount);
|
||||
#endif /* #ifndef CONFIG_QUICKTIME */
|
||||
|
||||
// to set/get/query special features/parameters
|
||||
@ -103,7 +103,7 @@ static int codec_initialized=0;
|
||||
// init driver
|
||||
static int init(sh_video_t *sh){
|
||||
#ifndef CONFIG_QUICKTIME
|
||||
long result = 1;
|
||||
OSErr result = 1;
|
||||
#endif
|
||||
ComponentResult cres;
|
||||
ComponentDescription desc;
|
||||
@ -156,7 +156,7 @@ static int init(sh_video_t *sh){
|
||||
|
||||
result=InitializeQTML(6+16);
|
||||
// result=InitializeQTML(0);
|
||||
mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"InitializeQTML returned %li\n",result);
|
||||
mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"InitializeQTML returned %d\n",result);
|
||||
// result=EnterMovies();
|
||||
// printf("EnterMovies->%d\n",result);
|
||||
#endif /* CONFIG_QUICKTIME */
|
||||
@ -305,7 +305,7 @@ static void uninit(sh_video_t *sh){
|
||||
|
||||
// decode a frame
|
||||
static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
|
||||
long result = 1;
|
||||
OSErr result = 1;
|
||||
int i;
|
||||
mp_image_t* mpi;
|
||||
ComponentResult cres;
|
||||
@ -335,7 +335,7 @@ if(!codec_initialized){
|
||||
0,
|
||||
mpi->planes[0],
|
||||
mpi->stride[0]);
|
||||
mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"NewGWorldFromPtr returned:%ld\n",65536-(result&0xffff));
|
||||
mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"NewGWorldFromPtr returned:%d\n",result);
|
||||
// if (65536-(result&0xFFFF) != 10000)
|
||||
// return NULL;
|
||||
|
||||
@ -406,7 +406,7 @@ if(!codec_initialized){
|
||||
|
||||
++decpar.frameNumber;
|
||||
|
||||
if(cres&0xFFFF){
|
||||
if(cres) {
|
||||
mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageCodecBandDecompress cres=0x%X (-0x%X) %d\n",cres,-cres,cres);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ static OSErr (*QTNewGWorldFromPtr)(GWorldPtr *gw,
|
||||
GWorldFlags flags,
|
||||
void *baseAddr,
|
||||
long rowBytes);
|
||||
static OSErr (*NewHandleClear)(Size byteCount);
|
||||
static Handle (*NewHandleClear)(Size byteCount);
|
||||
static OSErr (*CompressSequenceBegin) (
|
||||
ImageSequence *seqID,
|
||||
PixMapHandle src,
|
||||
|
@ -118,6 +118,7 @@ extern const vf_info_t vf_info_yadif;
|
||||
extern const vf_info_t vf_info_blackframe;
|
||||
extern const vf_info_t vf_info_geq;
|
||||
extern const vf_info_t vf_info_ow;
|
||||
extern const vf_info_t vf_info_fixpts;
|
||||
|
||||
// list of available filters:
|
||||
static const vf_info_t* const filter_list[]={
|
||||
@ -219,6 +220,7 @@ static const vf_info_t* const filter_list[]={
|
||||
&vf_info_yadif,
|
||||
&vf_info_blackframe,
|
||||
&vf_info_ow,
|
||||
&vf_info_fixpts,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
137
libmpcodecs/vf_fixpts.c
Normal file
137
libmpcodecs/vf_fixpts.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* MPlayer 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "mp_msg.h"
|
||||
#include "help_mp.h"
|
||||
|
||||
#include "img_format.h"
|
||||
#include "mp_image.h"
|
||||
#include "vf.h"
|
||||
|
||||
struct vf_priv_s {
|
||||
double current;
|
||||
double step;
|
||||
int autostart;
|
||||
int autostep;
|
||||
unsigned have_step:1;
|
||||
unsigned print:1;
|
||||
};
|
||||
|
||||
static int put_image(vf_instance_t *vf, mp_image_t *src, double pts)
|
||||
{
|
||||
struct vf_priv_s *p = vf->priv;
|
||||
|
||||
if (p->print) {
|
||||
if (pts == MP_NOPTS_VALUE)
|
||||
mp_msg(MSGT_VFILTER, MSGL_INFO, "PTS: undef\n");
|
||||
else
|
||||
mp_msg(MSGT_VFILTER, MSGL_INFO, "PTS: %f\n", pts);
|
||||
}
|
||||
if (pts != MP_NOPTS_VALUE && p->autostart != 0) {
|
||||
p->current = pts;
|
||||
if (p->autostart > 0)
|
||||
p->autostart--;
|
||||
} else if (pts != MP_NOPTS_VALUE && p->autostep > 0) {
|
||||
p->step = pts - p->current;
|
||||
p->current = pts;
|
||||
p->autostep--;
|
||||
p->have_step = 1;
|
||||
} else if (p->have_step) {
|
||||
p->current += p->step;
|
||||
pts = p->current;
|
||||
} else {
|
||||
pts = MP_NOPTS_VALUE;
|
||||
}
|
||||
return vf_next_put_image(vf, src, pts);
|
||||
}
|
||||
|
||||
static void uninit(vf_instance_t *vf)
|
||||
{
|
||||
free(vf->priv);
|
||||
}
|
||||
|
||||
static int parse_args(struct vf_priv_s *p, const char *args)
|
||||
{
|
||||
int pos;
|
||||
double num, denom = 1;
|
||||
int iarg;
|
||||
|
||||
while (*args != 0) {
|
||||
pos = 0;
|
||||
if (sscanf(args, "print%n", &pos) == 0 && pos > 0) {
|
||||
p->print = 1;
|
||||
} else if (sscanf(args, "fps=%lf%n/%lf%n", &num, &pos, &denom, &pos) >=
|
||||
1 && pos > 0) {
|
||||
p->step = denom / num;
|
||||
p->have_step = 1;
|
||||
} else if (sscanf(args, "start=%lf%n", &num, &pos) >= 1 && pos > 0) {
|
||||
p->current = num;
|
||||
} else if (sscanf(args, "autostart=%d%n", &iarg, &pos) == 1 && pos > 0) {
|
||||
p->autostart = iarg;
|
||||
} else if (sscanf(args, "autofps=%d%n", &iarg, &pos) == 1 && pos > 0) {
|
||||
p->autostep = iarg;
|
||||
} else {
|
||||
mp_msg(MSGT_VFILTER, MSGL_FATAL,
|
||||
"fixpts: unknown suboption: %s\n", args);
|
||||
return 0;
|
||||
}
|
||||
args += pos;
|
||||
if (*args == ':')
|
||||
args++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int open(vf_instance_t *vf, char *args)
|
||||
{
|
||||
struct vf_priv_s *p;
|
||||
struct vf_priv_s ptmp = {
|
||||
.current = 0,
|
||||
.step = 0,
|
||||
.autostart = 0,
|
||||
.autostep = 0,
|
||||
.have_step = 0,
|
||||
.print = 0,
|
||||
};
|
||||
|
||||
if (!parse_args(&ptmp, args == NULL ? "" : args))
|
||||
return 0;
|
||||
|
||||
vf->put_image = put_image;
|
||||
vf->uninit = uninit;
|
||||
vf->priv = p = malloc(sizeof(struct vf_priv_s));
|
||||
*p = ptmp;
|
||||
p->current = -p->step;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
vf_info_t vf_info_fixpts = {
|
||||
"Fix presentation timestamps",
|
||||
"fixpts",
|
||||
"Nicolas George",
|
||||
"",
|
||||
&open,
|
||||
NULL
|
||||
};
|
@ -27,6 +27,7 @@
|
||||
|
||||
static const struct mp_AVCodecTag mp_wav_tags[] = {
|
||||
{ CODEC_ID_ADPCM_4XM, MKTAG('4', 'X', 'M', 'A')},
|
||||
{ CODEC_ID_ADPCM_ADX, MKTAG('S', 'a', 'd', 'x')},
|
||||
{ CODEC_ID_ADPCM_EA, MKTAG('A', 'D', 'E', 'A')},
|
||||
{ CODEC_ID_ADPCM_EA_MAXIS_XA, MKTAG('A', 'D', 'X', 'A')},
|
||||
{ CODEC_ID_ADPCM_IMA_WS, MKTAG('A', 'I', 'W', 'S')},
|
||||
|
@ -572,6 +572,7 @@ static int fb_bpp_we_want; // 32: 32 24: 24 16: 16 15: 15
|
||||
static int fb_line_len;
|
||||
static int fb_xres;
|
||||
static int fb_yres;
|
||||
static int fb_page;
|
||||
static void (*draw_alpha_p)(int w, int h, unsigned char *src,
|
||||
unsigned char *srca, int stride,
|
||||
unsigned char *dst, int dstride);
|
||||
@ -804,6 +805,12 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
|
||||
set_bpp(&fb_vinfo, fb_bpp);
|
||||
fb_vinfo.xres_virtual = fb_vinfo.xres;
|
||||
fb_vinfo.yres_virtual = fb_vinfo.yres;
|
||||
fb_page = 0;
|
||||
if (vo_doublebuffering) {
|
||||
fb_vinfo.yres_virtual <<= 1;
|
||||
fb_vinfo.yoffset = 0;
|
||||
fb_page = 1; // start writing into the page we don't display
|
||||
}
|
||||
|
||||
if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) {
|
||||
mp_msg(MSGT_VO, MSGL_V, "Can't set graphics mode: %s\n", strerror(errno));
|
||||
@ -903,6 +910,12 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
|
||||
|
||||
fb_line_len = fb_finfo.line_length;
|
||||
fb_size = fb_finfo.smem_len;
|
||||
if (vo_doublebuffering && fb_size < 2 * fb_yres * fb_line_len)
|
||||
{
|
||||
mp_msg(MSGT_VO, MSGL_WARN, "framebuffer too small for double-buffering, disabling\n");
|
||||
vo_doublebuffering = 0;
|
||||
fb_page = 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDIX
|
||||
if (vidix_name) {
|
||||
@ -963,14 +976,19 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
|
||||
center = frame_buffer +
|
||||
( (out_width - in_width) / 2 ) * fb_pixel_size +
|
||||
( (out_height - in_height) / 2 ) * fb_line_len +
|
||||
x_offset * fb_pixel_size + y_offset * fb_line_len;
|
||||
x_offset * fb_pixel_size + y_offset * fb_line_len +
|
||||
fb_page * fb_yres * fb_line_len;
|
||||
|
||||
mp_msg(MSGT_VO, MSGL_DBG2, "frame_buffer @ %p\n", frame_buffer);
|
||||
mp_msg(MSGT_VO, MSGL_DBG2, "center @ %p\n", center);
|
||||
mp_msg(MSGT_VO, MSGL_V, "pixel per line: %d\n", fb_line_len / fb_pixel_size);
|
||||
|
||||
if (fs || vm)
|
||||
memset(frame_buffer, '\0', fb_line_len * fb_yres);
|
||||
if (fs || vm) {
|
||||
int clear_size = fb_line_len * fb_yres;
|
||||
if (vo_doublebuffering)
|
||||
clear_size <<= 1;
|
||||
memset(frame_buffer, 0, clear_size);
|
||||
}
|
||||
}
|
||||
|
||||
vt_set_textarea(last_row, fb_yres);
|
||||
@ -1027,6 +1045,20 @@ static void check_events(void)
|
||||
|
||||
static void flip_page(void)
|
||||
{
|
||||
int next_page = !fb_page;
|
||||
int page_delta = next_page - fb_page;
|
||||
#ifdef CONFIG_VIDIX
|
||||
if (vidix_name)
|
||||
return;
|
||||
#endif
|
||||
if (!vo_doublebuffering)
|
||||
return;
|
||||
|
||||
fb_vinfo.yoffset = fb_page * fb_yres;
|
||||
ioctl(fb_dev_fd, FBIOPAN_DISPLAY, &fb_vinfo);
|
||||
|
||||
center += page_delta * fb_yres * fb_line_len;
|
||||
fb_page = next_page;
|
||||
}
|
||||
|
||||
static void draw_osd(void)
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "DS_Filter.h"
|
||||
#include "graph.h"
|
||||
#include "loader/drv.h"
|
||||
#include "loader/com.h"
|
||||
#include <stdio.h>
|
||||
@ -125,6 +126,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
|
||||
// char eb[250];
|
||||
const char* em = NULL;
|
||||
MemAllocator* tempAll;
|
||||
FilterGraph* graph;
|
||||
ALLOCATOR_PROPERTIES props,props1;
|
||||
DS_Filter* This = malloc(sizeof(DS_Filter));
|
||||
if (!This)
|
||||
@ -166,6 +168,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
|
||||
ULONG fetched;
|
||||
HRESULT result;
|
||||
unsigned int i;
|
||||
static const uint16_t filter_name[] = { 'F', 'i', 'l', 't', 'e', 'r', 0 };
|
||||
|
||||
This->m_iHandle = LoadLibraryA(dllname);
|
||||
if (!This->m_iHandle)
|
||||
@ -199,6 +202,10 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
|
||||
em = "object does not provide IBaseFilter interface";
|
||||
break;
|
||||
}
|
||||
|
||||
graph = FilterGraphCreate();
|
||||
result = This->m_pFilter->vt->JoinFilterGraph(This->m_pFilter, (IFilterGraph*)graph, filter_name);
|
||||
|
||||
// enumerate pins
|
||||
result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins);
|
||||
if (result || !enum_pins)
|
||||
|
@ -116,7 +116,7 @@ static inline avm_list_t* avm_list_find(avm_list_t* head, void* member)
|
||||
|
||||
static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** ppv)
|
||||
{
|
||||
IMemAllocator* p;
|
||||
IUnknown* p;
|
||||
int result;
|
||||
if (!ppv)
|
||||
return -1;
|
||||
@ -124,9 +124,9 @@ static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** pp
|
||||
if (memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID)))
|
||||
return -1;
|
||||
|
||||
p = (IMemAllocator*) MemAllocatorCreate();
|
||||
result = p->vt->QueryInterface((IUnknown*)p, iid, ppv);
|
||||
p->vt->Release((IUnknown*)p);
|
||||
p = (IUnknown*) MemAllocatorCreate();
|
||||
result = p->vt->QueryInterface(p, iid, ppv);
|
||||
p->vt->Release(p);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
163
loader/dshow/graph.c
Normal file
163
loader/dshow/graph.c
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Implemention of FilterGraph. Based on allocator.c.
|
||||
* Copyright 2010 Steinar H. Gunderson
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* MPlayer 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Modified for use with MPlayer, detailed changelog at
|
||||
* http://svn.mplayerhq.hu/mplayer/trunk/
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "loader/com.h"
|
||||
#include "loader/dshow/graph.h"
|
||||
#include "loader/wine/winerror.h"
|
||||
|
||||
// How many FilterGraph objects exist.
|
||||
// Used for knowing when to register and unregister the class in COM.
|
||||
static int GraphKeeper = 0;
|
||||
|
||||
static long FilterGraph_CreateGraph(GUID* clsid, const GUID* iid, void** ppv)
|
||||
{
|
||||
IUnknown* p;
|
||||
int result;
|
||||
if (!ppv)
|
||||
return -1;
|
||||
*ppv = 0;
|
||||
if (memcmp(clsid, &CLSID_FilterGraph, sizeof(*clsid)))
|
||||
return -1;
|
||||
|
||||
p = (IUnknown*) FilterGraphCreate();
|
||||
result = p->vt->QueryInterface(p, iid, ppv);
|
||||
p->vt->Release(p);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void FilterGraph_Destroy(FilterGraph* This)
|
||||
{
|
||||
Debug printf("FilterGraph_Destroy(%p) called (%d, %d)\n", This, This->refcount, GraphKeeper);
|
||||
#ifdef WIN32_LOADER
|
||||
if (--GraphKeeper == 0)
|
||||
UnregisterComClass(&CLSID_FilterGraph, FilterGraph_CreateGraph);
|
||||
#endif
|
||||
free(This->vt);
|
||||
free(This);
|
||||
}
|
||||
|
||||
HRESULT STDCALL FilterGraph_AddFilter(FilterGraph* This,
|
||||
IBaseFilter* pFilter,
|
||||
unsigned short* pName)
|
||||
{
|
||||
Debug printf("FilterGraph_AddFilter(%p) called\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDCALL FilterGraph_RemoveFilter(FilterGraph* This, IBaseFilter* pFilter)
|
||||
{
|
||||
Debug printf("FilterGraph_RemoveFilter(%p) called\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDCALL FilterGraph_EnumFilters(FilterGraph* This, IEnumFilters** ppEnum)
|
||||
{
|
||||
Debug printf("FilterGraph_EnumFilters(%p) called\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDCALL FilterGraph_FindFilterByName(FilterGraph* This,
|
||||
unsigned short* pName,
|
||||
IBaseFilter** ppFilter)
|
||||
{
|
||||
Debug printf("FilterGraph_FindFilterByName(%p) called\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDCALL FilterGraph_ConnectDirect(FilterGraph* This,
|
||||
IPin* ppinOut,
|
||||
IPin* ppinIn,
|
||||
const AM_MEDIA_TYPE* pmt)
|
||||
{
|
||||
Debug printf("FilterGraph_ConnectDirect(%p) called\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDCALL FilterGraph_Reconnect(FilterGraph* This, IPin* ppin)
|
||||
{
|
||||
Debug printf("FilterGraph_Reconnect(%p) called\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDCALL FilterGraph_Disconnect(FilterGraph* This, IPin* ppin)
|
||||
{
|
||||
Debug printf("FilterGraph_Disconnect(%p) called\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDCALL FilterGraph_SetDefaultSyncSource(FilterGraph* This)
|
||||
{
|
||||
Debug printf("FilterGraph_SetDefaultSyncSource(%p) called\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
IMPLEMENT_IUNKNOWN(FilterGraph)
|
||||
|
||||
FilterGraph* FilterGraphCreate()
|
||||
{
|
||||
FilterGraph* This = calloc(1, sizeof(*This));
|
||||
|
||||
if (!This)
|
||||
return NULL;
|
||||
|
||||
Debug printf("FilterGraphCreate() called -> %p\n", This);
|
||||
|
||||
This->refcount = 1;
|
||||
|
||||
This->vt = calloc(1, sizeof(*This->vt));
|
||||
|
||||
if (!This->vt) {
|
||||
free(This);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
This->vt->QueryInterface = FilterGraph_QueryInterface;
|
||||
This->vt->AddRef = FilterGraph_AddRef;
|
||||
This->vt->Release = FilterGraph_Release;
|
||||
|
||||
This->vt->AddFilter = FilterGraph_AddFilter;
|
||||
This->vt->RemoveFilter = FilterGraph_RemoveFilter;
|
||||
This->vt->EnumFilters = FilterGraph_EnumFilters;
|
||||
This->vt->FindFilterByName = FilterGraph_FindFilterByName;
|
||||
This->vt->ConnectDirect = FilterGraph_ConnectDirect;
|
||||
This->vt->Reconnect = FilterGraph_Reconnect;
|
||||
This->vt->Disconnect = FilterGraph_Disconnect;
|
||||
This->vt->SetDefaultSyncSource = FilterGraph_SetDefaultSyncSource;
|
||||
|
||||
This->interfaces[0] = IID_IUnknown;
|
||||
This->interfaces[1] = IID_IFilterGraph;
|
||||
|
||||
#ifdef WIN32_LOADER
|
||||
if (GraphKeeper++ == 0)
|
||||
RegisterComClass(&CLSID_FilterGraph, FilterGraph_CreateGraph);
|
||||
#endif
|
||||
|
||||
return This;
|
||||
}
|
||||
|
57
loader/dshow/graph.h
Normal file
57
loader/dshow/graph.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef MPLAYER_GRAPH_H
|
||||
#define MPLAYER_GRAPH_H
|
||||
|
||||
/*
|
||||
* Copyright 2010 Steinar H. Gunderson
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* MPlayer 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "interfaces.h"
|
||||
#include "cmediasample.h"
|
||||
|
||||
typedef struct FilterGraph FilterGraph;
|
||||
|
||||
struct FilterGraph {
|
||||
IFilterGraph_vt* vt;
|
||||
DECLARE_IUNKNOWN();
|
||||
GUID interfaces[2];
|
||||
|
||||
HRESULT STDCALL (*AddFilter)(FilterGraph* This,
|
||||
/* [in] */ IBaseFilter* pFilter,
|
||||
/* [string][in] */ unsigned short* pName);
|
||||
HRESULT STDCALL (*RemoveFilter)(FilterGraph* This,
|
||||
/* [in] */ IBaseFilter* pFilter);
|
||||
HRESULT STDCALL (*EnumFilters)(FilterGraph* This,
|
||||
/* [out] */ IEnumFilters** ppEnum);
|
||||
HRESULT STDCALL (*FindFilterByName)(FilterGraph* This,
|
||||
/* [string][in] */ unsigned short* pName,
|
||||
/* [out] */ IBaseFilter** ppFilter);
|
||||
HRESULT STDCALL (*ConnectDirect)(FilterGraph* This,
|
||||
/* [in] */ IPin* ppinOut,
|
||||
/* [in] */ IPin* ppinIn,
|
||||
/* [in] */ const AM_MEDIA_TYPE* pmt);
|
||||
HRESULT STDCALL (*Reconnect)(FilterGraph* This,
|
||||
/* [in] */ IPin* ppin);
|
||||
HRESULT STDCALL (*Disconnect)(FilterGraph* This,
|
||||
/* [in] */ IPin* ppin);
|
||||
HRESULT STDCALL (*SetDefaultSyncSource)(FilterGraph* This);
|
||||
};
|
||||
|
||||
FilterGraph* FilterGraphCreate(void);
|
||||
|
||||
#endif /* MPLAYER_GRAPH_H */
|
@ -11,6 +11,8 @@ const GUID IID_IBaseFilter={0x56a86895, 0x0ad4, 0x11ce,
|
||||
{0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
|
||||
const GUID IID_IEnumPins={0x56a86892, 0x0ad4, 0x11ce,
|
||||
{0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
|
||||
const GUID IID_IFilterGraph={0x56a8689f, 0x0ad4, 0x11ce,
|
||||
{0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
|
||||
const GUID IID_IEnumMediaTypes={0x89c31040, 0x846b, 0x11ce,
|
||||
{0x97, 0xd3, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
|
||||
const GUID IID_IMemInputPin={0x56a8689d, 0x0ad4, 0x11ce,
|
||||
@ -64,6 +66,8 @@ const GUID MEDIASUBTYPE_I420={0x30323449, 0x0000, 0x0010,
|
||||
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||
const GUID MEDIASUBTYPE_IF09={0x39304649, 0x0000, 0x0010,
|
||||
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||
const GUID CLSID_FilterGraph={0xe436ebb3, 0x524f, 0x11ce,
|
||||
{0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
|
||||
const GUID CLSID_MemoryAllocator={0x1e651cc0, 0xb199, 0x11d0,
|
||||
{0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45}};
|
||||
const GUID IID_DivxHidden={0x598eba01, 0xb49a, 0x11d2,
|
||||
|
@ -46,6 +46,7 @@ typedef GUID IID;
|
||||
extern const GUID IID_IBaseFilter;
|
||||
extern const GUID IID_IEnumPins;
|
||||
extern const GUID IID_IEnumMediaTypes;
|
||||
extern const GUID IID_IFilterGraph;
|
||||
extern const GUID IID_IMemInputPin;
|
||||
extern const GUID IID_IMemAllocator;
|
||||
extern const GUID IID_IMediaSample;
|
||||
@ -54,6 +55,7 @@ extern const GUID IID_Iv50Hidden;
|
||||
extern const GUID CLSID_DivxDecompressorCF;
|
||||
extern const GUID IID_IDivxFilterInterface;
|
||||
extern const GUID CLSID_IV50_Decoder;
|
||||
extern const GUID CLSID_FilterGraph;
|
||||
extern const GUID CLSID_MemoryAllocator;
|
||||
extern const GUID MEDIATYPE_Video;
|
||||
// avoid a clash with MinGW-W64 libuuid
|
||||
|
@ -329,4 +329,32 @@ struct IDivxFilterInterface_vt
|
||||
HRESULT STDCALL ( *get_AspectRatio )(IDivxFilterInterface* This, int* x, IDivxFilterInterface* Thisit, int* y);
|
||||
};
|
||||
|
||||
typedef struct IEnumFilters IEnumFilters;
|
||||
|
||||
typedef struct IFilterGraph_vt
|
||||
{
|
||||
INHERIT_IUNKNOWN();
|
||||
|
||||
HRESULT STDCALL ( *AddFilter )(IFilterGraph* This,
|
||||
/* [in] */ IBaseFilter* pFilter,
|
||||
/* [string][in] */ unsigned short* pName);
|
||||
HRESULT STDCALL ( *RemoveFilter )(IFilterGraph* This,
|
||||
/* [in] */ IBaseFilter* pFilter);
|
||||
HRESULT STDCALL ( *EnumFilters )(IFilterGraph* This,
|
||||
/* [out] */ IEnumFilters** ppEnum);
|
||||
HRESULT STDCALL ( *FindFilterByName )(IFilterGraph* This,
|
||||
/* [string][in] */ unsigned short* pName,
|
||||
/* [out] */ IBaseFilter** ppFilter);
|
||||
HRESULT STDCALL ( *ConnectDirect )(IFilterGraph* This,
|
||||
/* [in] */ IPin* ppinOut,
|
||||
/* [in] */ IPin* ppinIn,
|
||||
/* [in] */ const AM_MEDIA_TYPE* pmt);
|
||||
HRESULT STDCALL ( *Reconnect )(IFilterGraph* This,
|
||||
/* [in] */ IPin* ppin);
|
||||
HRESULT STDCALL ( *Disconnect )(IFilterGraph* This,
|
||||
/* [in] */ IPin* ppin);
|
||||
HRESULT STDCALL ( *SetDefaultSyncSource )(IFilterGraph* This);
|
||||
} IFilterGraph_vt;
|
||||
struct IFilterGraph { IFilterGraph_vt *vt; };
|
||||
|
||||
#endif /*MPLAYER_INTERFACES_H */
|
||||
|
@ -12,7 +12,7 @@ typedef unsigned char Boolean;
|
||||
typedef unsigned char Str31[32];
|
||||
typedef int32_t Fixed;
|
||||
|
||||
typedef int32_t OSErr;
|
||||
typedef int16_t OSErr;
|
||||
typedef int OSType;
|
||||
|
||||
typedef int32_t ComponentResult;
|
||||
@ -641,10 +641,10 @@ static inline void dump_ImageDescription(void* xxx){
|
||||
printf("=============== ImageDescription at %p ==================\n",xxx);
|
||||
printf("idSize=0x%X fourcc=0x%08X\n",id->idSize,id->cType);
|
||||
printf("ver=%d rev=%d vendor=0x%08X\n",id->version,id->revisionLevel,id->vendor);
|
||||
printf("tempQ=%d spatQ=%d dim: %d x %d dpi: %d x %d depth: %d\n",
|
||||
printf("tempQ=%d spatQ=%d dim: %d x %d dpi: %.2f x %.2f depth: %d\n",
|
||||
id->temporalQuality,id->spatialQuality,
|
||||
id->width, id->height,
|
||||
id->hRes, id->vRes,
|
||||
id->hRes / 65536.0, id->vRes / 65536.0,
|
||||
id->depth);
|
||||
printf("dataSize=%d frameCount=%d clutID=%d\n",id->dataSize, id->frameCount, id->clutID);
|
||||
printf("name='%.*s'\n",((char*)(&id->name))[0],((char*)(&id->name))+1);
|
||||
|
196
loader/win32.c
196
loader/win32.c
@ -240,6 +240,7 @@ typedef struct th_list_t{
|
||||
//static int heap_counter=0;
|
||||
static tls_t* g_tls=NULL;
|
||||
static th_list* list=NULL;
|
||||
static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#if 0
|
||||
static void test_heap(void)
|
||||
@ -638,6 +639,7 @@ static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
|
||||
printf( "WARNING: CreateThread flags not supported\n");
|
||||
if(dwThreadId)
|
||||
*dwThreadId=(long)pth;
|
||||
pthread_mutex_lock(&list_lock);
|
||||
if(list==NULL)
|
||||
{
|
||||
list=my_mreq(sizeof(th_list), 1);
|
||||
@ -651,11 +653,19 @@ static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
|
||||
list=list->next;
|
||||
}
|
||||
list->thread=pth;
|
||||
pthread_mutex_unlock(&list_lock);
|
||||
dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
|
||||
pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
|
||||
return pth;
|
||||
}
|
||||
|
||||
static DWORD WINAPI expResumeThread(HANDLE hThread)
|
||||
{
|
||||
int ret = 1;
|
||||
dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct mutex_list_t;
|
||||
|
||||
struct mutex_list_t
|
||||
@ -667,14 +677,18 @@ struct mutex_list_t
|
||||
char reset;
|
||||
char name[128];
|
||||
int semaphore;
|
||||
int lock_count;
|
||||
pthread_t owner;
|
||||
struct mutex_list_t* next;
|
||||
struct mutex_list_t* prev;
|
||||
};
|
||||
typedef struct mutex_list_t mutex_list;
|
||||
static mutex_list* mlist=NULL;
|
||||
static pthread_mutex_t mlist_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void destroy_event(void* event)
|
||||
{
|
||||
pthread_mutex_lock(&mlist_lock);
|
||||
mutex_list* pp=mlist;
|
||||
// printf("garbage collector: destroy_event(%x)\n", event);
|
||||
while(pp)
|
||||
@ -696,10 +710,12 @@ void destroy_event(void* event)
|
||||
}
|
||||
printf("0\n");
|
||||
*/
|
||||
pthread_mutex_unlock(&mlist_lock);
|
||||
return;
|
||||
}
|
||||
pp=pp->prev;
|
||||
}
|
||||
pthread_mutex_unlock(&mlist_lock);
|
||||
}
|
||||
|
||||
static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
|
||||
@ -707,6 +723,7 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
|
||||
{
|
||||
pthread_mutex_t *pm;
|
||||
pthread_cond_t *pc;
|
||||
void *ret;
|
||||
/*
|
||||
mutex_list* pp;
|
||||
pp=mlist;
|
||||
@ -717,6 +734,7 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
|
||||
}
|
||||
printf("0\n");
|
||||
*/
|
||||
pthread_mutex_lock(&mlist_lock);
|
||||
if(mlist!=NULL)
|
||||
{
|
||||
mutex_list* pp=mlist;
|
||||
@ -727,6 +745,7 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
|
||||
{
|
||||
dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
|
||||
pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
|
||||
pthread_mutex_unlock(&mlist_lock);
|
||||
return pp->pm;
|
||||
}
|
||||
}while((pp=pp->prev) != NULL);
|
||||
@ -768,7 +787,9 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
|
||||
else
|
||||
dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
|
||||
pSecAttr, bManualReset, bInitialState, mlist);
|
||||
return mlist;
|
||||
ret = mlist;
|
||||
pthread_mutex_unlock(&mlist_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void* WINAPI expSetEvent(void* event)
|
||||
@ -800,8 +821,8 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
|
||||
mutex_list *ml = (mutex_list *)object;
|
||||
// FIXME FIXME FIXME - this value is sometime unititialize !!!
|
||||
int ret = WAIT_FAILED;
|
||||
mutex_list* pp=mlist;
|
||||
th_list* tp=list;
|
||||
mutex_list* pp;
|
||||
th_list* tp;
|
||||
if(object == (void*)0xcfcf9898)
|
||||
{
|
||||
/**
|
||||
@ -818,8 +839,11 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
|
||||
dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
|
||||
|
||||
// See if this is a thread.
|
||||
pthread_mutex_lock(&list_lock);
|
||||
tp=list;
|
||||
while (tp && (tp->thread != object))
|
||||
tp = tp->prev;
|
||||
pthread_mutex_unlock(&list_lock);
|
||||
if (tp) {
|
||||
if (pthread_join(*(pthread_t*)object, NULL) == 0) {
|
||||
return (void*)WAIT_OBJECT_0;
|
||||
@ -832,8 +856,11 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
|
||||
// this object really exists in our list
|
||||
if (!ml)
|
||||
return (void*) ret;
|
||||
pthread_mutex_lock(&mlist_lock);
|
||||
pp=mlist;
|
||||
while (pp && (pp->pm != ml->pm))
|
||||
pp = pp->prev;
|
||||
pthread_mutex_unlock(&mlist_lock);
|
||||
if (!pp) {
|
||||
dbgprintf("WaitForSingleObject: NotFound\n");
|
||||
return (void*)ret;
|
||||
@ -872,7 +899,7 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
|
||||
if (duration == 0) {
|
||||
if(ml->semaphore==0) ret = WAIT_FAILED;
|
||||
else {
|
||||
ml->semaphore++;
|
||||
ml->semaphore--;
|
||||
ret = WAIT_OBJECT_0;
|
||||
}
|
||||
}
|
||||
@ -880,6 +907,25 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
|
||||
if (ml->semaphore==0)
|
||||
pthread_cond_wait(ml->pc,ml->pm);
|
||||
ml->semaphore--;
|
||||
ret = WAIT_OBJECT_0;
|
||||
}
|
||||
break;
|
||||
case 2: /* Mutex */
|
||||
if (duration == 0) {
|
||||
if(ml->lock_count > 0 && ml->owner != pthread_self()) ret = WAIT_FAILED;
|
||||
else {
|
||||
ml->lock_count++;
|
||||
ml->owner = pthread_self();
|
||||
ret = WAIT_OBJECT_0;
|
||||
}
|
||||
}
|
||||
if (duration == -1) {
|
||||
if (ml->lock_count > 0 && ml->owner != pthread_self()) {
|
||||
pthread_cond_wait(ml->pc,ml->pm);
|
||||
}
|
||||
ml->lock_count++;
|
||||
ml->owner = pthread_self();
|
||||
ret = WAIT_OBJECT_0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -917,31 +963,6 @@ static void WINAPI expExitThread(int retcode)
|
||||
dbgprintf("ExitThread(%d)\n", retcode);
|
||||
pthread_exit(&retcode);
|
||||
}
|
||||
|
||||
static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
|
||||
char bInitialOwner, const char *name)
|
||||
{
|
||||
HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name);
|
||||
|
||||
if (name)
|
||||
dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
|
||||
pSecAttr, bInitialOwner, name, mlist);
|
||||
else
|
||||
dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
|
||||
pSecAttr, bInitialOwner, mlist);
|
||||
#ifndef CONFIG_QTX_CODECS
|
||||
/* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
|
||||
waits for ever, else it works ;) */
|
||||
return mlist;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int WINAPI expReleaseMutex(HANDLE hMutex)
|
||||
{
|
||||
dbgprintf("ReleaseMutex(%x) => 1\n", hMutex);
|
||||
/* FIXME:XXX !! not yet implemented */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int pf_set = 0;
|
||||
@ -1801,6 +1822,7 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
|
||||
{
|
||||
pthread_mutex_t *pm;
|
||||
pthread_cond_t *pc;
|
||||
HANDLE ret;
|
||||
/*
|
||||
mutex_list* pp;
|
||||
printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
|
||||
@ -1812,6 +1834,7 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
|
||||
}
|
||||
printf("0\n");
|
||||
*/
|
||||
pthread_mutex_lock(&mlist_lock);
|
||||
if(mlist!=NULL)
|
||||
{
|
||||
mutex_list* pp=mlist;
|
||||
@ -1822,7 +1845,9 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
|
||||
{
|
||||
dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
|
||||
v1, init_count, max_count, name, name, mlist);
|
||||
return (HANDLE)mlist;
|
||||
ret = (HANDLE)mlist;
|
||||
pthread_mutex_unlock(&mlist_lock);
|
||||
return ret;
|
||||
}
|
||||
}while((pp=pp->prev) != NULL);
|
||||
}
|
||||
@ -1861,7 +1886,9 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
|
||||
else
|
||||
dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
|
||||
v1, init_count, max_count, mlist);
|
||||
return (HANDLE)mlist;
|
||||
ret = (HANDLE)mlist;
|
||||
pthread_mutex_unlock(&mlist_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
|
||||
@ -1882,6 +1909,105 @@ static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_cou
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
|
||||
char bInitialOwner, const char *name)
|
||||
{
|
||||
pthread_mutex_t *pm;
|
||||
pthread_cond_t *pc;
|
||||
HANDLE ret;
|
||||
pthread_mutex_lock(&mlist_lock);
|
||||
if(mlist!=NULL)
|
||||
{
|
||||
mutex_list* pp=mlist;
|
||||
if(name!=NULL)
|
||||
do
|
||||
{
|
||||
if((strcmp(pp->name, name)==0) && (pp->type==2))
|
||||
{
|
||||
dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr, bInitialOwner, name, mlist);
|
||||
ret = (HANDLE)mlist;
|
||||
pthread_mutex_unlock(&mlist_lock);
|
||||
return ret;
|
||||
}
|
||||
}while((pp=pp->prev) != NULL);
|
||||
}
|
||||
pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
|
||||
pthread_mutex_init(pm, NULL);
|
||||
pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
|
||||
pthread_cond_init(pc, NULL);
|
||||
if(mlist==NULL)
|
||||
{
|
||||
mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
|
||||
mlist->next=mlist->prev=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
|
||||
mlist->next->prev=mlist;
|
||||
mlist->next->next=NULL;
|
||||
mlist=mlist->next;
|
||||
}
|
||||
mlist->type=2; /* Type Mutex */
|
||||
mlist->pm=pm;
|
||||
mlist->pc=pc;
|
||||
mlist->state=0;
|
||||
mlist->reset=0;
|
||||
mlist->semaphore=0;
|
||||
if (bInitialOwner) {
|
||||
mlist->owner = pthread_self();
|
||||
mlist->lock_count = 1;
|
||||
} else {
|
||||
mlist->owner = (pthread_t)0;
|
||||
mlist->lock_count = 0;
|
||||
}
|
||||
if(name!=NULL)
|
||||
strncpy(mlist->name, name, 64);
|
||||
else
|
||||
mlist->name[0]=0;
|
||||
if(pm==NULL)
|
||||
dbgprintf("ERROR::: CreateMutexA failure\n");
|
||||
if(name)
|
||||
dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
|
||||
pSecAttr, bInitialOwner, name, mlist);
|
||||
else
|
||||
dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
|
||||
pSecAttr, bInitialOwner, mlist);
|
||||
ret = (HANDLE)mlist;
|
||||
pthread_mutex_unlock(&mlist_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int WINAPI expReleaseMutex(HANDLE hMutex)
|
||||
{
|
||||
mutex_list *ml = (mutex_list *)hMutex;
|
||||
|
||||
pthread_mutex_lock(ml->pm);
|
||||
if (--ml->lock_count == 0) pthread_cond_signal(ml->pc);
|
||||
pthread_mutex_unlock(ml->pm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static DWORD WINAPI expSignalObjectAndWait(HANDLE hObjectToSignal,
|
||||
HANDLE hObjectToWaitOn,
|
||||
DWORD dwMilliseconds,
|
||||
WIN_BOOL bAlertable) {
|
||||
mutex_list* mlist = (mutex_list*)hObjectToSignal;
|
||||
|
||||
switch (mlist->type) {
|
||||
case 0: // Event
|
||||
expSetEvent(mlist);
|
||||
break;
|
||||
case 1: // Semaphore
|
||||
expReleaseSemaphore(mlist, 1, NULL);
|
||||
break;
|
||||
case 2: // Mutex
|
||||
expReleaseMutex(mlist);
|
||||
break;
|
||||
default:
|
||||
dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal);
|
||||
}
|
||||
return expWaitForSingleObject(hObjectToWaitOn, dwMilliseconds);
|
||||
}
|
||||
|
||||
static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
|
||||
{
|
||||
@ -5002,6 +5128,7 @@ struct exports exp_kernel32[]=
|
||||
FF(IsBadStringPtrA, -1)
|
||||
FF(DisableThreadLibraryCalls, -1)
|
||||
FF(CreateThread, -1)
|
||||
FF(ResumeThread, -1)
|
||||
FF(CreateEventA, -1)
|
||||
FF(SetEvent, -1)
|
||||
FF(ResetEvent, -1)
|
||||
@ -5009,8 +5136,6 @@ struct exports exp_kernel32[]=
|
||||
#ifdef CONFIG_QTX_CODECS
|
||||
FF(WaitForMultipleObjects, -1)
|
||||
FF(ExitThread, -1)
|
||||
FF(CreateMutexA,-1)
|
||||
FF(ReleaseMutex,-1)
|
||||
#endif
|
||||
FF(GetSystemInfo, -1)
|
||||
FF(GetVersion, 332)
|
||||
@ -5055,6 +5180,9 @@ struct exports exp_kernel32[]=
|
||||
FF(GlobalFree, -1)
|
||||
FF(LoadResource, -1)
|
||||
FF(ReleaseSemaphore, -1)
|
||||
FF(CreateMutexA, -1)
|
||||
FF(ReleaseMutex, -1)
|
||||
FF(SignalObjectAndWait, -1)
|
||||
FF(FindResourceA, -1)
|
||||
FF(LockResource, -1)
|
||||
FF(FreeResource, -1)
|
||||
@ -5662,5 +5790,7 @@ void my_garbagecollection(void)
|
||||
dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);
|
||||
#endif
|
||||
g_tls = NULL;
|
||||
pthread_mutex_lock(&list_lock);
|
||||
list = NULL;
|
||||
pthread_mutex_unlock(&list_lock);
|
||||
}
|
||||
|
129
mencoder.c
129
mencoder.c
@ -375,6 +375,46 @@ static void exit_sighandler(int x){
|
||||
|
||||
static muxer_t* muxer=NULL;
|
||||
|
||||
void add_subtitles(char *filename, float fps, int silent)
|
||||
{
|
||||
sub_data *subd;
|
||||
#ifdef CONFIG_ASS
|
||||
ASS_Track *asst = 0;
|
||||
#endif
|
||||
|
||||
if (!filename) return;
|
||||
|
||||
subd = sub_read_file(filename, fps);
|
||||
#ifdef CONFIG_ASS
|
||||
if (opts.ass_enabled)
|
||||
#ifdef CONFIG_ICONV
|
||||
asst = ass_read_file(ass_library, filename, sub_cp);
|
||||
#else
|
||||
asst = ass_read_file(ass_library, filename, 0);
|
||||
#endif
|
||||
if (opts.ass_enabled && subd && !asst)
|
||||
asst = ass_read_subdata(ass_library, subd, fps);
|
||||
|
||||
if (!asst && !subd && !silent)
|
||||
#else
|
||||
if (!subd && !silent)
|
||||
#endif
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "Cannot load subtitles: %s\n",
|
||||
filename_recode(filename));
|
||||
|
||||
#ifdef CONFIG_ASS
|
||||
if (!asst && !subd) return;
|
||||
ass_track = asst;
|
||||
#else
|
||||
if (!subd) return;
|
||||
#endif
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_FILE_SUB_FILENAME=%s\n",
|
||||
filename_recode(filename));
|
||||
subdata = subd;
|
||||
}
|
||||
|
||||
void print_wave_header(WAVEFORMATEX *h, int verbose_level);
|
||||
|
||||
int main(int argc,char* argv[]){
|
||||
|
||||
stream_t* stream=NULL;
|
||||
@ -535,6 +575,10 @@ play_next_file:
|
||||
m_entry_set_options(mconfig,&filelist[curfile]);
|
||||
filename = filelist[curfile].name;
|
||||
|
||||
#ifdef CONFIG_ASS
|
||||
ass_library = ass_init();
|
||||
#endif
|
||||
|
||||
if(!filename){
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_FATAL, "\nFilename missing.\n\n");
|
||||
mencoder_exit(1,NULL);
|
||||
@ -666,26 +710,6 @@ if(sh_audio && (out_audio_codec || seek_to_sec || !sh_audio->wf || opts.playback
|
||||
}
|
||||
}
|
||||
|
||||
// after reading video params we should load subtitles because
|
||||
// we know fps so now we can adjust subtitles time to ~6 seconds AST
|
||||
// check .sub
|
||||
// current_module="read_subtitles_file";
|
||||
if(sub_name && sub_name[0]){
|
||||
subdata=sub_read_file(sub_name[0], sh_video->fps);
|
||||
if(!subdata) mp_tmsg(MSGT_CPLAYER,MSGL_ERR,"Cannot load subtitles: %s\n",sub_name[0]);
|
||||
} else
|
||||
if(sub_auto && filename) { // auto load sub file ...
|
||||
char **tmp = NULL;
|
||||
int i = 0;
|
||||
char *psub = get_path( "sub/" );
|
||||
tmp = sub_filenames((psub ? psub : ""), filename);
|
||||
free(psub);
|
||||
subdata=sub_read_file(tmp[0], sh_video->fps);
|
||||
while (tmp[i])
|
||||
free(tmp[i++]);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
// set up video encoder:
|
||||
|
||||
if (!curfile) { // curfile is non zero when a second file is opened
|
||||
@ -865,12 +889,77 @@ default: {
|
||||
ve = sh_video->vfilter;
|
||||
} else sh_video->vfilter = ve;
|
||||
// append 'expand' filter, it fixes stride problems and renders osd:
|
||||
#ifdef CONFIG_ASS
|
||||
if (auto_expand && !opts.ass_enabled) { /* we do not want both */
|
||||
#else
|
||||
if (auto_expand) {
|
||||
#endif
|
||||
char* vf_args[] = { "osd", "1", NULL };
|
||||
sh_video->vfilter=vf_open_filter(&opts, sh_video->vfilter,"expand",vf_args);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ASS
|
||||
if(opts.ass_enabled) {
|
||||
int i;
|
||||
int insert = 1;
|
||||
if (opts.vf_settings)
|
||||
for (i = 0; opts.vf_settings[i].name; ++i)
|
||||
if (strcmp(opts.vf_settings[i].name, "ass") == 0) {
|
||||
insert = 0;
|
||||
break;
|
||||
}
|
||||
if (insert) {
|
||||
extern vf_info_t vf_info_ass;
|
||||
vf_info_t* libass_vfs[] = {&vf_info_ass, NULL};
|
||||
char* vf_arg[] = {"auto", "1", NULL};
|
||||
vf_instance_t* vf_ass = vf_open_plugin(&opts,libass_vfs,sh_video->vfilter,"ass",vf_arg);
|
||||
if (vf_ass)
|
||||
sh_video->vfilter=(void*)vf_ass;
|
||||
else
|
||||
mp_msg(MSGT_CPLAYER,MSGL_ERR, "ASS: cannot add video filter\n");
|
||||
}
|
||||
|
||||
if (ass_library) {
|
||||
for (i = 0; i < demuxer->num_attachments; ++i) {
|
||||
demux_attachment_t* att = demuxer->attachments + i;
|
||||
if (use_embedded_fonts &&
|
||||
att->name && att->type && att->data && att->data_size &&
|
||||
(strcmp(att->type, "application/x-truetype-font") == 0 ||
|
||||
strcmp(att->type, "application/x-font") == 0))
|
||||
ass_add_font(ass_library, att->name, att->data, att->data_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
sh_video->vfilter=append_filters(sh_video->vfilter, opts.vf_settings);
|
||||
|
||||
#ifdef CONFIG_ASS
|
||||
if (opts.ass_enabled)
|
||||
((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_INIT_EOSD, ass_library);
|
||||
#endif
|
||||
|
||||
// after reading video params we should load subtitles because
|
||||
// we know fps so now we can adjust subtitles time to ~6 seconds AST
|
||||
// check .sub
|
||||
if(sub_name && sub_name[0]){
|
||||
for (i = 0; sub_name[i] != NULL; ++i)
|
||||
add_subtitles (sub_name[i], sh_video->fps, 0);
|
||||
} else
|
||||
if(sub_auto && filename) { // auto load sub file ...
|
||||
char **tmp = NULL;
|
||||
int i = 0;
|
||||
char *psub = get_path( "sub/" );
|
||||
tmp = sub_filenames((psub ? psub : ""), filename);
|
||||
free(psub);
|
||||
while (tmp[i])
|
||||
{
|
||||
add_subtitles (tmp[i], sh_video->fps, 0);
|
||||
free(tmp[i++]);
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
|
||||
init_best_video_codec(sh_video,video_codec_list,video_fm_list);
|
||||
mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
|
||||
|
@ -1239,7 +1239,7 @@ static void saddf(char *buf, unsigned *pos, int len, const char *format, ...)
|
||||
* \param time time value to convert/append
|
||||
*/
|
||||
static void sadd_hhmmssf(char *buf, unsigned *pos, int len, float time) {
|
||||
long tenths = 10 * time;
|
||||
int64_t tenths = 10 * time;
|
||||
int f1 = tenths % 10;
|
||||
int ss = (tenths / 10) % 60;
|
||||
int mm = (tenths / 600) % 60;
|
||||
|
@ -25,6 +25,11 @@
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#define STREAMTYPE_DUMMY -1 // for placeholders, when the actual reading is handled in the demuxer
|
||||
#define STREAMTYPE_FILE 0 // read from seekable file
|
||||
|
@ -76,10 +76,6 @@
|
||||
#include "network.h"
|
||||
#include "libavutil/common.h"
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#define DEFAULT_FREEDB_SERVER "freedb.freedb.org"
|
||||
#define DEFAULT_CACHE_DIR "/.cddb/"
|
||||
|
||||
|
@ -136,9 +136,7 @@ static int open_f(stream_t *stream,int mode, void* opts, int* file_format) {
|
||||
filename++;
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN__)|| defined(__MINGW32__) || defined(__OS2__)
|
||||
m |= O_BINARY;
|
||||
#endif
|
||||
|
||||
if(!strcmp(filename,"-")){
|
||||
if(mode == STREAM_READ) {
|
||||
|
@ -79,11 +79,7 @@ static int open_live_sdp(stream_t *stream,int mode, void* opts, int* file_format
|
||||
|
||||
if(strncmp("sdp://",filename,6) == 0) {
|
||||
filename += 6;
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__)
|
||||
f = open(filename,O_RDONLY|O_BINARY);
|
||||
#else
|
||||
f = open(filename,O_RDONLY);
|
||||
#endif
|
||||
if(f < 0) {
|
||||
mp_tmsg(MSGT_OPEN,MSGL_ERR,"File not found: '%s'\n",filename);
|
||||
return STREAM_ERROR;
|
||||
|
Loading…
Reference in New Issue
Block a user