Mercurial > mplayer.hg
annotate libmpcodecs/vf_lavc.c @ 26625:5b89b42f6d50
Only compile and use libmpeg2 AltiVec code when AltiVec is available. The
AltiVec code needs -maltivec to compile, but then AltiVec instructions
appear in other places of the code causing MPlayer to sigill.
Somehow upstream libmpeg2 manages not to sigill under what appear to be
the same circumstances. Enlightenment welcome.
author | diego |
---|---|
date | Sat, 03 May 2008 15:23:22 +0000 |
parents | 1318e956c092 |
children | 63630c09e237 |
rev | line source |
---|---|
5873 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <inttypes.h> | |
5 | |
17012 | 6 #include "config.h" |
7 #include "mp_msg.h" | |
8 #include "help_mp.h" | |
5873 | 9 |
10 #include "img_format.h" | |
11 #include "mp_image.h" | |
12 #include "vf.h" | |
13 #include "libavcodec/avcodec.h" | |
14 | |
25962 | 15 extern int avcodec_initialized; |
5873 | 16 |
17 struct vf_priv_s { | |
18 unsigned char* outbuf; | |
19 int outbuf_size; | |
7852 | 20 AVCodecContext* context; |
8413 | 21 AVFrame* pic; |
7852 | 22 AVCodec* codec; |
5873 | 23 vo_mpegpes_t pes; |
24 }; | |
25 | |
7852 | 26 #define lavc_venc_context (*vf->priv->context) |
5873 | 27 |
28 //===========================================================================// | |
29 | |
30 static int config(struct vf_instance_s* vf, | |
31 int width, int height, int d_width, int d_height, | |
32 unsigned int flags, unsigned int outfmt){ | |
33 if(vf_next_query_format(vf,IMGFMT_MPEGPES)<=0) return 0; | |
34 | |
35 lavc_venc_context.width = width; | |
36 lavc_venc_context.height = height; | |
6019 | 37 |
15843 | 38 if(!lavc_venc_context.time_base.num || !lavc_venc_context.time_base.den){ |
6019 | 39 // guess FPS: |
40 switch(height){ | |
41 case 240: | |
42 case 480: | |
15307 | 43 lavc_venc_context.time_base= (AVRational){1001,30000}; |
6019 | 44 break; |
45 case 576: | |
46 case 288: | |
47 default: | |
15307 | 48 lavc_venc_context.time_base= (AVRational){1,25}; |
6019 | 49 break; |
50 // lavc_venc_context.frame_rate=vo_fps*FRAME_RATE_BASE; // same as src | |
51 } | |
52 } | |
5873 | 53 |
54 if(vf->priv->outbuf) free(vf->priv->outbuf); | |
55 | |
56 vf->priv->outbuf_size=10000+width*height; // must be enough! | |
57 vf->priv->outbuf = malloc(vf->priv->outbuf_size); | |
58 | |
59 if (avcodec_open(&lavc_venc_context, vf->priv->codec) != 0) { | |
60 mp_msg(MSGT_MENCODER,MSGL_ERR,MSGTR_CantOpenCodec); | |
61 return 0; | |
62 } | |
63 | |
64 if (lavc_venc_context.codec->encode == NULL) { | |
65 mp_msg(MSGT_MENCODER,MSGL_ERR,"avcodec init failed (ctx->codec->encode == NULL)!\n"); | |
66 return 0; | |
67 } | |
68 | |
69 return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_MPEGPES); | |
70 } | |
71 | |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17523
diff
changeset
|
72 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ |
5873 | 73 mp_image_t* dmpi; |
74 int out_size; | |
8413 | 75 AVFrame *pic= vf->priv->pic; |
5873 | 76 |
8339 | 77 pic->data[0]=mpi->planes[0]; |
78 pic->data[1]=mpi->planes[1]; | |
79 pic->data[2]=mpi->planes[2]; | |
80 pic->linesize[0]=mpi->stride[0]; | |
81 pic->linesize[1]=mpi->stride[1]; | |
82 pic->linesize[2]=mpi->stride[2]; | |
5873 | 83 |
84 out_size = avcodec_encode_video(&lavc_venc_context, | |
8339 | 85 vf->priv->outbuf, vf->priv->outbuf_size, pic); |
5873 | 86 |
7368 | 87 if(out_size<=0) return 1; |
5873 | 88 |
89 dmpi=vf_get_image(vf->next,IMGFMT_MPEGPES, | |
90 MP_IMGTYPE_EXPORT, 0, | |
91 mpi->w, mpi->h); | |
92 | |
93 vf->priv->pes.data=vf->priv->outbuf; | |
94 vf->priv->pes.size=out_size; | |
95 vf->priv->pes.id=0x1E0; | |
96 vf->priv->pes.timestamp=-1; // dunno | |
97 | |
7127 | 98 dmpi->planes[0]=(unsigned char*)&vf->priv->pes; |
5873 | 99 |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17523
diff
changeset
|
100 return vf_next_put_image(vf,dmpi, MP_NOPTS_VALUE); |
5873 | 101 } |
102 | |
103 //===========================================================================// | |
104 | |
105 static int query_format(struct vf_instance_s* vf, unsigned int fmt){ | |
106 switch(fmt){ | |
107 case IMGFMT_YV12: | |
108 case IMGFMT_I420: | |
109 case IMGFMT_IYUV: | |
5876 | 110 return (vf_next_query_format(vf,IMGFMT_MPEGPES) & (~(VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_ACCEPT_STRIDE))); |
5873 | 111 } |
112 return 0; | |
113 } | |
114 | |
115 static int open(vf_instance_t *vf, char* args){ | |
6019 | 116 int p_quality=0; |
117 float p_fps=0; | |
118 | |
5873 | 119 vf->config=config; |
120 vf->put_image=put_image; | |
121 vf->query_format=query_format; | |
122 vf->priv=malloc(sizeof(struct vf_priv_s)); | |
123 memset(vf->priv,0,sizeof(struct vf_priv_s)); | |
124 | |
25962 | 125 if (!avcodec_initialized){ |
5873 | 126 avcodec_init(); |
127 avcodec_register_all(); | |
25962 | 128 avcodec_initialized=1; |
5873 | 129 } |
130 | |
131 vf->priv->codec = (AVCodec *)avcodec_find_encoder_by_name("mpeg1video"); | |
132 if (!vf->priv->codec) { | |
133 mp_msg(MSGT_MENCODER,MSGL_ERR,MSGTR_MissingLAVCcodec, "mpeg1video"); | |
134 return 0; | |
135 } | |
7852 | 136 |
137 vf->priv->context=avcodec_alloc_context(); | |
8413 | 138 vf->priv->pic = avcodec_alloc_frame(); |
5873 | 139 |
140 // TODO: parse args -> | |
6019 | 141 if(args) sscanf(args, "%d:%f", &p_quality, &p_fps); |
142 | |
143 if(p_quality<32){ | |
144 // fixed qscale | |
145 lavc_venc_context.flags = CODEC_FLAG_QSCALE; | |
11257
837bca3ae69f
constant qscale was broken due to libavcodec changes, fix taken from ve_lavc.c
ranma
parents:
11000
diff
changeset
|
146 lavc_venc_context.global_quality = |
837bca3ae69f
constant qscale was broken due to libavcodec changes, fix taken from ve_lavc.c
ranma
parents:
11000
diff
changeset
|
147 vf->priv->pic->quality = (int)(FF_QP2LAMBDA * ((p_quality<1) ? 1 : p_quality) + 0.5); |
6019 | 148 } else { |
149 // fixed bitrate (in kbits) | |
150 lavc_venc_context.bit_rate = 1000*p_quality; | |
151 } | |
15307 | 152 lavc_venc_context.time_base.num = 1000*1001; |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17523
diff
changeset
|
153 lavc_venc_context.time_base.den = (p_fps<1.0) ? 1000*1001*25 : (p_fps * lavc_venc_context.time_base.num); |
5873 | 154 lavc_venc_context.gop_size = 0; // I-only |
15349 | 155 lavc_venc_context.pix_fmt= PIX_FMT_YUV420P; |
5873 | 156 |
157 return 1; | |
158 } | |
159 | |
25221 | 160 const vf_info_t vf_info_lavc = { |
5873 | 161 "realtime mpeg1 encoding with libavcodec", |
162 "lavc", | |
163 "A'rpi", | |
164 "", | |
9593
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9577
diff
changeset
|
165 open, |
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9577
diff
changeset
|
166 NULL |
5873 | 167 }; |
168 | |
169 //===========================================================================// |