static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ) { encoder_sys_t *p_sys = p_enc->p_sys; ogg_packet oggpacket; block_t *p_block; od_img img; if( !p_pict ) return NULL; const int i_width = p_sys->di.pic_width; const int i_height = p_sys->di.pic_height; /* Sanity check */ if( p_pict->p[0].i_pitch < i_width || p_pict->p[0].i_lines < i_height ) { msg_Err( p_enc, "frame is smaller than encoding size" "(%ix%i->%ix%i) -> dropping frame", p_pict->p[0].i_pitch, p_pict->p[0].i_lines, i_width, i_height ); return NULL; } /* Daala is a one-frame-in, one-frame-out system. Submit a frame * for compression and pull out the packet. */ img.nplanes = p_sys->di.nplanes; img.width = i_width; img.height = i_height; for( int i = 0; i < img.nplanes; i++ ) { img.planes[i].data = p_pict->p[i].p_pixels; img.planes[i].xdec = p_sys->di.plane_info[i].xdec; img.planes[i].ydec = p_sys->di.plane_info[i].ydec; img.planes[i].xstride = 1; img.planes[i].ystride = p_pict->p[i].i_pitch; } if( daala_encode_img_in( p_sys->dcx, &img, 0 ) < 0 ) { msg_Warn( p_enc, "failed encoding a frame" ); return NULL; } daala_encode_packet_out( p_sys->dcx, 0, &oggpacket ); /* Ogg packet to block */ p_block = block_Alloc( oggpacket.bytes ); memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes ); p_block->i_dts = p_block->i_pts = p_pict->date; if( daala_packet_iskeyframe( oggpacket.packet, oggpacket.bytes ) ) p_block->i_flags |= BLOCK_FLAG_TYPE_I; return p_block; }
int daala_encode(struct videnc_state *ves, bool update, const struct vidframe *frame) { int r, err = 0; daala_image img; unsigned i; (void)update; /* XXX: how to force a KEY-frame? */ if (!ves || !frame || frame->fmt != VID_FMT_YUV420P) return EINVAL; ++ves->stats.n_frame; if (!ves->enc || !vidsz_cmp(&ves->size, &frame->size)) { err = open_encoder(ves, &frame->size); if (err) return err; ves->size = frame->size; } img.planes[0].data = frame->data[0]; img.planes[0].xdec = 0; img.planes[0].ydec = 0; img.planes[0].xstride = 1; img.planes[0].ystride = frame->linesize[0]; img.planes[1].data = frame->data[1]; img.planes[1].xdec = 1; img.planes[1].ydec = 1; img.planes[1].xstride = 1; img.planes[1].ystride = frame->linesize[1]; img.planes[2].data = frame->data[2]; img.planes[2].xdec = 1; img.planes[2].ydec = 1; img.planes[2].xstride = 1; img.planes[2].ystride = frame->linesize[2]; for (i=0; i<3; i++) img.planes[i].bitdepth = 8; img.nplanes = 3; img.width = frame->size.w; img.height = frame->size.h; r = daala_encode_img_in(ves->enc, &img, 0); if (r != 0) { warning("daala: encoder: encode_img_in failed (ret = %d)\n", r); return EPROTO; } for (;;) { daala_packet dp; r = daala_encode_packet_out(ves->enc, 0, &dp); if (r < 0) { warning("daala: encoder: packet_out ret=%d\n", r); break; } else if (r == 0) { break; } err = send_packet(ves, dp.b_o_s, dp.packet, dp.bytes); if (err) break; } return 0; }