ms: add hidden video header to mblk_t

parent 8ca68be3
......@@ -85,11 +85,6 @@ MS2_PUBLIC void ms_queue_destroy(MSQueue *q);
#define mblk_get_payload_type(m) (((m)->reserved2>>3)&0x7F)
#define mblk_set_precious_flag(m,bit) (m)->reserved2=(m)->reserved2|((bit & 0x1)<<10) /*use to prevent mirroring*/
#define mblk_get_precious_flag(m) (((m)->reserved2)>>10 & 0x1)
#define mblk_set_video_orientation(m,o) do{\
if (o==MS_VIDEO_LANDSCAPE) (m)->reserved2=(m)->reserved2 & ~(1<<11); \
else (m)->reserved2|=(1<<11); \
}while(0)
#define mblk_get_video_orientation(m) (((m)->reserved2 & (1<<11)) ? MS_VIDEO_PORTRAIT : MS_VIDEO_LANDSCAPE)
struct _MSBufferizer{
queue_t q;
......
......@@ -205,6 +205,7 @@ MS2_PUBLIC int ms_yuv_buf_init_from_mblk(MSPicture *buf, mblk_t *m);
MS2_PUBLIC int ms_yuv_buf_init_from_mblk_with_size(MSPicture *buf, mblk_t *m, int w, int h);
MS2_PUBLIC int ms_picture_init_from_mblk_with_size(MSPicture *buf, mblk_t *m, MSPixFmt fmt, int w, int h);
MS2_PUBLIC mblk_t * ms_yuv_buf_alloc(MSPicture *buf, int w, int h);
MS2_PUBLIC mblk_t * ms_yuv_buf_alloc_from_buffer(int w, int h, mblk_t* buffer);
MS2_PUBLIC void ms_yuv_buf_copy(uint8_t *src_planes[], const int src_strides[],
uint8_t *dst_planes[], const int dst_strides[3], MSVideoSize roi);
MS2_PUBLIC void ms_yuv_buf_mirror(YuvBuf *buf);
......
......@@ -60,7 +60,7 @@ public class MediastreamerActivity extends Activity {
Thread msThread;
int cameraId = 0;
String videoCodec = VP8_MIME_TYPE;
String remoteIp = "127.0.0.1";
String remoteIp = "192.168.1.100";//27.0.0.1";
short remotePort = 4000, localPort = 4000;
int bitrate = 256;
......
......@@ -191,7 +191,7 @@ static int v4lv2_do_mmap(V4lState *s){
}
msg=esballoc(start,buf.length,0,NULL);
/* adjust to real size of picture*/
if (s->pix_fmt==MS_RGB24)
if (s->pix_fmt==MS_RGB24
msg->b_wptr+=s->vsize.width*s->vsize.height*3;
else
msg->b_wptr+=(s->vsize.width*s->vsize.height*3)/2;
......@@ -476,7 +476,7 @@ static int v4l_do_mmap(V4lState *s){
buf->b_wptr+=s->vsize.width*s->vsize.height*3;
else
buf->b_wptr+=(s->vsize.width*s->vsize.height*3)/2;
s->frames[i]=buf;
s->frames[i]=ms_yuv_buf_alloc_from_buffer(s->vsize.width, s->vsize.height, buf);
}
s->frame_ind=0;
return 0;
......
......@@ -251,7 +251,7 @@ static int msv4l2_do_mmap(V4l2State *s){
}
msg=esballoc(start,buf.length,0,NULL);
msg->b_wptr+=buf.length;
s->frames[i]=msg;
s->frames[i]=ms_yuv_buf_alloc_from_buffer(s->vsize.width, s->vsize.height, msg);
}
s->frame_max=req.count;
for (i = 0; i < s->frame_max; ++i) {
......@@ -317,8 +317,8 @@ static mblk_t *v4l2_dequeue_ready_buffer(V4l2State *s, int poll_timeout_ms){
/*normally buf.bytesused should contain the right buffer size; however we have found a buggy
driver that puts a random value inside */
if (s->picture_size!=0)
ret->b_wptr=ret->b_rptr+s->picture_size;
else ret->b_wptr=ret->b_rptr+buf.bytesused;
ret->b_cont->b_wptr=ret->b_cont->b_rptr+s->picture_size;
else ret->b_cont->b_wptr=ret->b_cont->b_rptr+buf.bytesused;
}
}
return ret;
......@@ -426,7 +426,7 @@ static void *msv4l2_thread(void *ptr){
mblk_t *m;
m=v4lv2_grab_image(s,50);
if (m){
mblk_t *om=dupb(m);
mblk_t *om=dupmsg(m);
mblk_set_marker_info(om,(s->pix_fmt==MS_MJPEG));
ms_mutex_lock(&s->mutex);
putq(&s->rq,om);
......
......@@ -27,6 +27,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <malloc.h>
#endif
struct _mblk_video_header {
uint16_t w, h;
int pad[3];
};
typedef struct _mblk_video_header mblk_video_header;
static void yuv_buf_init(YuvBuf *buf, int w, int h, uint8_t *ptr){
int ysize,usize;
ysize=w*h;
......@@ -46,106 +52,20 @@ static void yuv_buf_init(YuvBuf *buf, int w, int h, uint8_t *ptr){
int ms_yuv_buf_init_from_mblk(YuvBuf *buf, mblk_t *m){
int size=m->b_wptr-m->b_rptr;
int w,h;
if (size==(MS_VIDEO_SIZE_QCIF_W*MS_VIDEO_SIZE_QCIF_H*3)/2){
w=MS_VIDEO_SIZE_QCIF_W;
h=MS_VIDEO_SIZE_QCIF_H;
}else if (size==(MS_VIDEO_SIZE_CIF_W*MS_VIDEO_SIZE_CIF_H*3)/2){
w=MS_VIDEO_SIZE_CIF_W;
h=MS_VIDEO_SIZE_CIF_H;
}else if (size==(MS_VIDEO_SIZE_QVGA_W*MS_VIDEO_SIZE_QVGA_H*3)/2){
w=MS_VIDEO_SIZE_QVGA_W;
h=MS_VIDEO_SIZE_QVGA_H;
}else if (size==(MS_VIDEO_SIZE_VGA_W*MS_VIDEO_SIZE_VGA_H*3)/2){
w=MS_VIDEO_SIZE_VGA_W;
h=MS_VIDEO_SIZE_VGA_H;
}else if (size==(MS_VIDEO_SIZE_4CIF_W*MS_VIDEO_SIZE_4CIF_H*3)/2){
w=MS_VIDEO_SIZE_4CIF_W;
h=MS_VIDEO_SIZE_4CIF_H;
}else if (size==(MS_VIDEO_SIZE_W4CIF_W*MS_VIDEO_SIZE_W4CIF_H*3)/2){
w=MS_VIDEO_SIZE_W4CIF_W;
h=MS_VIDEO_SIZE_W4CIF_H;
}else if (size==(MS_VIDEO_SIZE_SVGA_W*MS_VIDEO_SIZE_SVGA_H*3)/2){
w=MS_VIDEO_SIZE_SVGA_W;
h=MS_VIDEO_SIZE_SVGA_H;
}else if (size==(MS_VIDEO_SIZE_SQCIF_W*MS_VIDEO_SIZE_SQCIF_H*3)/2){
w=MS_VIDEO_SIZE_SQCIF_W;
h=MS_VIDEO_SIZE_SQCIF_H;
}else if (size==(MS_VIDEO_SIZE_QQVGA_W*MS_VIDEO_SIZE_QQVGA_H*3)/2){
w=MS_VIDEO_SIZE_QQVGA_W;
h=MS_VIDEO_SIZE_QQVGA_H;
}else if (size==(MS_VIDEO_SIZE_NS1_W*MS_VIDEO_SIZE_NS1_H*3)/2){
w=MS_VIDEO_SIZE_NS1_W;
h=MS_VIDEO_SIZE_NS1_H;
}else if (size==(MS_VIDEO_SIZE_QSIF_W*MS_VIDEO_SIZE_QSIF_H*3)/2){
w=MS_VIDEO_SIZE_QSIF_W;
h=MS_VIDEO_SIZE_QSIF_H;
}else if (size==(MS_VIDEO_SIZE_SIF_W*MS_VIDEO_SIZE_SIF_H*3)/2){
w=MS_VIDEO_SIZE_SIF_W;
h=MS_VIDEO_SIZE_SIF_H;
}else if (size==(MS_VIDEO_SIZE_4SIF_W*MS_VIDEO_SIZE_4SIF_H*3)/2){
w=MS_VIDEO_SIZE_4SIF_W;
h=MS_VIDEO_SIZE_4SIF_H;
}else if (size==(MS_VIDEO_SIZE_288P_W*MS_VIDEO_SIZE_288P_H*3)/2){
w=MS_VIDEO_SIZE_288P_W;
h=MS_VIDEO_SIZE_288P_H;
}else if (size==(MS_VIDEO_SIZE_432P_W*MS_VIDEO_SIZE_432P_H*3)/2){
w=MS_VIDEO_SIZE_432P_W;
h=MS_VIDEO_SIZE_432P_H;
}else if (size==(MS_VIDEO_SIZE_448P_W*MS_VIDEO_SIZE_448P_H*3)/2){
w=MS_VIDEO_SIZE_448P_W;
h=MS_VIDEO_SIZE_448P_H;
}else if (size==(MS_VIDEO_SIZE_480P_W*MS_VIDEO_SIZE_480P_H*3)/2){
w=MS_VIDEO_SIZE_480P_W;
h=MS_VIDEO_SIZE_480P_H;
}else if (size==(MS_VIDEO_SIZE_576P_W*MS_VIDEO_SIZE_576P_H*3)/2){
w=MS_VIDEO_SIZE_576P_W;
h=MS_VIDEO_SIZE_576P_H;
}else if (size==(MS_VIDEO_SIZE_720P_W*MS_VIDEO_SIZE_720P_H*3)/2){
w=MS_VIDEO_SIZE_720P_W;
h=MS_VIDEO_SIZE_720P_H;
}else if (size==(MS_VIDEO_SIZE_1080P_W*MS_VIDEO_SIZE_1080P_H*3)/2){
w=MS_VIDEO_SIZE_1080P_W;
h=MS_VIDEO_SIZE_1080P_H;
}else if (size==(MS_VIDEO_SIZE_SDTV_W*MS_VIDEO_SIZE_SDTV_H*3)/2){
w=MS_VIDEO_SIZE_SDTV_W;
h=MS_VIDEO_SIZE_SDTV_H;
}else if (size==(MS_VIDEO_SIZE_HDTVP_W*MS_VIDEO_SIZE_HDTVP_H*3)/2){
w=MS_VIDEO_SIZE_HDTVP_W;
h=MS_VIDEO_SIZE_HDTVP_H;
}else if (size==(MS_VIDEO_SIZE_XGA_W*MS_VIDEO_SIZE_XGA_H*3)/2){
w=MS_VIDEO_SIZE_XGA_W;
h=MS_VIDEO_SIZE_XGA_H;
}else if (size==(MS_VIDEO_SIZE_WXGA_W*MS_VIDEO_SIZE_WXGA_H*3)/2){
w=MS_VIDEO_SIZE_WXGA_W;
h=MS_VIDEO_SIZE_WXGA_H;
}else if (size==(MS_VIDEO_SIZE_WQCIF_W*MS_VIDEO_SIZE_WQCIF_H*3)/2){
w=MS_VIDEO_SIZE_WQCIF_W;
h=MS_VIDEO_SIZE_WQCIF_H;
}else if (size==(MS_VIDEO_SIZE_CVD_W*MS_VIDEO_SIZE_CVD_H*3)/2){
w=MS_VIDEO_SIZE_CVD_W;
h=MS_VIDEO_SIZE_CVD_H;
}else if (size==(160*112*3)/2){/*format used by econf*/
w=160;
h=112;
}else if (size==(320*200*3)/2){/*format used by gTalk */
w=320;
h=200;
}else if (size==(MS_VIDEO_SIZE_IOS_MEDIUM_W*MS_VIDEO_SIZE_IOS_MEDIUM_H*3)/2){/*format used by iPhone in AVCaptureSessionPresetMedium */
w=480;
h=360;
}else {
ms_error("Unsupported image size: size=%i (bug somewhere !)",size);
return -1;
}
if (mblk_get_video_orientation(m)==MS_VIDEO_PORTRAIT){
int tmp=h;
h=w;
w=tmp;
}
yuv_buf_init(buf,w,h,m->b_rptr);
// read header
mblk_video_header* hdr = (mblk_video_header*)m->b_datap->db_base;
w = hdr->w;
h = hdr->h;
if (m->b_cont == NULL)
yuv_buf_init(buf,w,h,m->b_rptr);
else
yuv_buf_init(buf,w,h,m->b_cont->b_rptr);
return 0;
}
int ms_yuv_buf_init_from_mblk_with_size(YuvBuf *buf, mblk_t *m, int w, int h){
yuv_buf_init(buf,w,h,m->b_rptr);
return 0;
......@@ -182,17 +102,36 @@ int ms_picture_init_from_mblk_with_size(MSPicture *buf, mblk_t *m, MSPixFmt fmt,
mblk_t * ms_yuv_buf_alloc(YuvBuf *buf, int w, int h){
int size=(w*h*3)/2;
const int header_size =sizeof(mblk_video_header);
const int padding=16;
mblk_t *msg=allocb(size+padding,0);
mblk_t *msg=allocb(header_size + size+padding,0);
// write width/height in header
mblk_video_header* hdr = (mblk_video_header*)msg->b_wptr;
hdr->w = w;
hdr->h = h;
msg->b_rptr += header_size;
msg->b_wptr += header_size;
yuv_buf_init(buf,w,h,msg->b_wptr);
if (h>w)
mblk_set_video_orientation(msg,MS_VIDEO_PORTRAIT);
else
mblk_set_video_orientation(msg,MS_VIDEO_LANDSCAPE);
msg->b_wptr+=size;
return msg;
}
mblk_t* ms_yuv_buf_alloc_from_buffer(int w, int h, mblk_t* buffer) {
const int header_size =sizeof(mblk_video_header);
mblk_t *msg=allocb(header_size,0);
// write width/height in header
mblk_video_header* hdr = (mblk_video_header*)msg->b_wptr;
hdr->w = w;
hdr->h = h;
msg->b_rptr += header_size;
msg->b_wptr += header_size;
// append real image buffer
msg->b_cont = buffer;
buffer->b_datap->db_ref++;
return msg;
}
static void plane_copy(const uint8_t *src_plane, int src_stride,
uint8_t *dst_plane, int dst_stride, MSVideoSize roi){
int i;
......
......@@ -63,7 +63,10 @@ static mblk_t *jpeg2yuv(uint8_t *jpgbuf, int bufsize, MSVideoSize *reqsize){
av_init_packet(&pkt);
pkt.data=jpgbuf;
pkt.size=bufsize;
if (avcodec_decode_video2(&av_context,&orig,&got_picture,&pkt)<0){
int rrr = avcodec_decode_video2(&av_context,&orig,&got_picture,&pkt);
ms_message("decode return: %d\n", rrr);
if (rrr < 0) {
ms_error("jpeg2yuv: avcodec_decode_video failed");
avcodec_close(&av_context);
return NULL;
......@@ -1666,7 +1669,7 @@ mblk_t *ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){
m=ms_load_generate_yuv(reqsize);
return m;
}
jpgbuf=(uint8_t*)ms_malloc0(statbuf.st_size);
jpgbuf=(uint8_t*)ms_malloc0(statbuf.st_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (jpgbuf==NULL)
{
close(fd);
......@@ -1764,7 +1767,7 @@ void static_image_process(MSFilter *f){
if ((f->ticker->time - d->lasttime>frame_interval) || d->lasttime==0){
ms_mutex_lock(&f->lock);
if (d->pic) {
mblk_t *o=dupb(d->pic);
mblk_t *o=dupmsg(d->pic);
/*prevent mirroring at the output*/
mblk_set_precious_flag(o,1);
ms_queue_put(f->outputs[0],o);
......
......@@ -768,10 +768,12 @@ static void process_frame(MSFilter *f, mblk_t *inm){
int error;
mblk_t *comp_buf=s->comp_buf;
int comp_buf_sz=comp_buf->b_datap->db_lim-comp_buf->b_datap->db_base;
YuvBuf yuv;
ms_yuv_buf_init_from_mblk(&yuv, inm);
/* convert image if necessary */
avcodec_get_frame_defaults(&pict);
avpicture_fill((AVPicture*)&pict,(uint8_t*)inm->b_rptr,c->pix_fmt,c->width,c->height);
avpicture_fill((AVPicture*)&pict,yuv.planes[0],c->pix_fmt,c->width,c->height);
/* timestamp used by ffmpeg, unset here */
pict.pts=AV_NOPTS_VALUE;
......
......@@ -161,6 +161,7 @@ static void enc_process(MSFilter *f) {
EncState *s=(EncState*)f->data;
unsigned int flags = 0;
vpx_codec_err_t err;
YuvBuf yuv;
while((im=ms_queue_get(f->inputs[0]))!=NULL){
vpx_image_t img;
......@@ -168,8 +169,9 @@ static void enc_process(MSFilter *f) {
om = NULL;
flags = 0;
vpx_img_wrap(&img, VPX_IMG_FMT_I420, s->width, s->height, 1, im->b_rptr);
ms_yuv_buf_init_from_mblk(&yuv, im);
vpx_img_wrap(&img, VPX_IMG_FMT_I420, s->width, s->height, 1, yuv.planes[0]);
if (video_starter_need_i_frame (&s->starter,f->ticker->time)){
/*sends an I frame at 2 seconds and 4 seconds after the beginning of the call*/
s->req_vfu=TRUE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment