2 mediastreamer2 library - modular sound and video processing and streaming
3 Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "mediastreamer2/msvideo.h"
22 static void yuv_buf_init(YuvBuf *buf, int w, int h, uint8_t *ptr){
29 buf->planes[1]=buf->planes[0]+ysize;
30 buf->planes[2]=buf->planes[1]+usize;
34 buf->strides[2]=buf->strides[1];
38 int yuv_buf_init_from_mblk(YuvBuf *buf, mblk_t *m){
39 int size=m->b_wptr-m->b_rptr;
41 if (size==(MS_VIDEO_SIZE_QCIF_W*MS_VIDEO_SIZE_QCIF_H*3)/2){
42 w=MS_VIDEO_SIZE_QCIF_W;
43 h=MS_VIDEO_SIZE_QCIF_H;
44 }else if (size==(MS_VIDEO_SIZE_CIF_W*MS_VIDEO_SIZE_CIF_H*3)/2){
45 w=MS_VIDEO_SIZE_CIF_W;
46 h=MS_VIDEO_SIZE_CIF_H;
47 }else if (size==(MS_VIDEO_SIZE_QVGA_W*MS_VIDEO_SIZE_QVGA_H*3)/2){
48 w=MS_VIDEO_SIZE_QVGA_W;
49 h=MS_VIDEO_SIZE_QVGA_H;
50 }else if (size==(MS_VIDEO_SIZE_VGA_W*MS_VIDEO_SIZE_VGA_H*3)/2){
51 w=MS_VIDEO_SIZE_VGA_W;
52 h=MS_VIDEO_SIZE_VGA_H;
53 }else if (size==(MS_VIDEO_SIZE_4CIF_W*MS_VIDEO_SIZE_4CIF_H*3)/2){
54 w=MS_VIDEO_SIZE_4CIF_W;
55 h=MS_VIDEO_SIZE_4CIF_H;
56 }else if (size==(MS_VIDEO_SIZE_SVGA_W*MS_VIDEO_SIZE_SVGA_H*3)/2){
57 w=MS_VIDEO_SIZE_SVGA_W;
58 h=MS_VIDEO_SIZE_SVGA_H;
59 }else if (size==(MS_VIDEO_SIZE_SQCIF_W*MS_VIDEO_SIZE_SQCIF_H*3)/2){
60 w=MS_VIDEO_SIZE_SQCIF_W;
61 h=MS_VIDEO_SIZE_SQCIF_H;
62 }else if (size==(MS_VIDEO_SIZE_QQVGA_W*MS_VIDEO_SIZE_QQVGA_H*3)/2){
63 w=MS_VIDEO_SIZE_QQVGA_W;
64 h=MS_VIDEO_SIZE_QQVGA_H;
65 }else if (size==(MS_VIDEO_SIZE_NS1_W*MS_VIDEO_SIZE_NS1_H*3)/2){
66 w=MS_VIDEO_SIZE_NS1_W;
67 h=MS_VIDEO_SIZE_NS1_H;
68 }else if (size==(MS_VIDEO_SIZE_QSIF_W*MS_VIDEO_SIZE_QSIF_H*3)/2){
69 w=MS_VIDEO_SIZE_QSIF_W;
70 h=MS_VIDEO_SIZE_QSIF_H;
71 }else if (size==(MS_VIDEO_SIZE_SIF_W*MS_VIDEO_SIZE_SIF_H*3)/2){
72 w=MS_VIDEO_SIZE_SIF_W;
73 h=MS_VIDEO_SIZE_SIF_H;
74 }else if (size==(MS_VIDEO_SIZE_4SIF_W*MS_VIDEO_SIZE_4SIF_H*3)/2){
75 w=MS_VIDEO_SIZE_4SIF_W;
76 h=MS_VIDEO_SIZE_4SIF_H;
77 }else if (size==(MS_VIDEO_SIZE_288P_W*MS_VIDEO_SIZE_288P_H*3)/2){
78 w=MS_VIDEO_SIZE_288P_W;
79 h=MS_VIDEO_SIZE_288P_H;
80 }else if (size==(MS_VIDEO_SIZE_448P_W*MS_VIDEO_SIZE_448P_H*3)/2){
81 w=MS_VIDEO_SIZE_448P_W;
82 h=MS_VIDEO_SIZE_448P_H;
83 }else if (size==(MS_VIDEO_SIZE_576P_W*MS_VIDEO_SIZE_576P_H*3)/2){
84 w=MS_VIDEO_SIZE_576P_W;
85 h=MS_VIDEO_SIZE_576P_H;
86 }else if (size==(MS_VIDEO_SIZE_720P_W*MS_VIDEO_SIZE_720P_H*3)/2){
87 w=MS_VIDEO_SIZE_720P_W;
88 h=MS_VIDEO_SIZE_720P_H;
89 }else if (size==(MS_VIDEO_SIZE_1080P_W*MS_VIDEO_SIZE_1080P_H*3)/2){
90 w=MS_VIDEO_SIZE_1080P_W;
91 h=MS_VIDEO_SIZE_1080P_H;
92 }else if (size==(MS_VIDEO_SIZE_SDTV_W*MS_VIDEO_SIZE_SDTV_H*3)/2){
93 w=MS_VIDEO_SIZE_SDTV_W;
94 h=MS_VIDEO_SIZE_SDTV_H;
95 }else if (size==(MS_VIDEO_SIZE_HDTVP_W*MS_VIDEO_SIZE_HDTVP_H*3)/2){
96 w=MS_VIDEO_SIZE_HDTVP_W;
97 h=MS_VIDEO_SIZE_HDTVP_H;
98 }else if (size==(MS_VIDEO_SIZE_XGA_W*MS_VIDEO_SIZE_XGA_H*3)/2){
99 w=MS_VIDEO_SIZE_XGA_W;
100 h=MS_VIDEO_SIZE_XGA_H;
101 }else if (size==(MS_VIDEO_SIZE_WXGA_W*MS_VIDEO_SIZE_WXGA_H*3)/2){
102 w=MS_VIDEO_SIZE_WXGA_W;
103 h=MS_VIDEO_SIZE_WXGA_H;
104 }else if (size==(160*112*3)/2){/*format used by econf*/
107 }else if (size==(320*200*3)/2){/*format used by gTalk */
111 ms_error("Unsupported image size: size=%i (bug somewhere !)",size);
114 yuv_buf_init(buf,w,h,m->b_rptr);
118 void yuv_buf_init_from_mblk_with_size(YuvBuf *buf, mblk_t *m, int w, int h){
119 yuv_buf_init(buf,w,h,m->b_rptr);
122 mblk_t * yuv_buf_alloc(YuvBuf *buf, int w, int h){
124 mblk_t *msg=allocb(size,0);
125 yuv_buf_init(buf,w,h,msg->b_wptr);
130 static void plane_copy(const uint8_t *src_plane, int src_stride,
131 uint8_t *dst_plane, int dst_stride, MSVideoSize roi){
133 for(i=0;i<roi.height;++i){
134 memcpy(dst_plane,src_plane,roi.width);
135 src_plane+=src_stride;
136 dst_plane+=dst_stride;
140 void yuv_buf_copy(uint8_t *src_planes[], const int src_strides[],
141 uint8_t *dst_planes[], const int dst_strides[3], MSVideoSize roi){
142 plane_copy(src_planes[0],src_strides[0],dst_planes[0],dst_strides[0],roi);
143 roi.width=roi.width/2;
144 roi.height=roi.height/2;
145 plane_copy(src_planes[1],src_strides[1],dst_planes[1],dst_strides[1],roi);
146 plane_copy(src_planes[2],src_strides[2],dst_planes[2],dst_strides[2],roi);
149 static void plane_mirror(uint8_t *p, int linesize, int w, int h){
162 /*in place mirroring*/
163 void yuv_buf_mirror(YuvBuf *buf){
164 plane_mirror(buf->planes[0],buf->strides[0],buf->w,buf->h);
165 plane_mirror(buf->planes[1],buf->strides[1],buf->w/2,buf->h/2);
166 plane_mirror(buf->planes[2],buf->strides[2],buf->w/2,buf->h/2);
170 #define MAKEFOURCC(a,b,c,d) ((d)<<24 | (c)<<16 | (b)<<8 | (a))
173 MSPixFmt ms_fourcc_to_pix_fmt(uint32_t fourcc){
176 case MAKEFOURCC('I','4','2','0'):
179 case MAKEFOURCC('Y','U','Y','2'):
182 case MAKEFOURCC('Y','U','Y','V'):
185 case MAKEFOURCC('U','Y','V','Y'):
188 case 0: /*BI_RGB on windows*/
192 ret=MS_PIX_FMT_UNKNOWN;
197 void rgb24_revert(uint8_t *buf, int w, int h, int linesize){
200 uint8_t *end=buf+((h-1)*linesize);
215 void rgb24_copy_revert(uint8_t *dstbuf, int dstlsz,
216 const uint8_t *srcbuf, int srclsz, MSVideoSize roi){
221 pdst=dstbuf+(dstlsz*(roi.height-1));
222 for(i=0;i<roi.height;++i){
223 for(j=0;j<roi.width*3;++j){
224 pdst[(roi.width*3)-1-j]=psrc[j];
231 static MSVideoSize _ordered_vsizes[]={
232 {MS_VIDEO_SIZE_QCIF_W,MS_VIDEO_SIZE_QCIF_H},
233 {MS_VIDEO_SIZE_QVGA_W,MS_VIDEO_SIZE_QVGA_H},
234 {MS_VIDEO_SIZE_CIF_W,MS_VIDEO_SIZE_CIF_H},
235 {MS_VIDEO_SIZE_VGA_W,MS_VIDEO_SIZE_VGA_H},
236 {MS_VIDEO_SIZE_4CIF_W,MS_VIDEO_SIZE_4CIF_H},
237 {MS_VIDEO_SIZE_720P_W,MS_VIDEO_SIZE_720P_H},
241 MSVideoSize ms_video_size_get_just_lower_than(MSVideoSize vs){
246 for(p=_ordered_vsizes;p->width!=0;++p){
247 if (ms_video_size_greater_than(vs,*p) && !ms_video_size_equal(vs,*p)){