XIRef<Packet> AVDeMuxer::Get() { XIRef<Packet> pkt; if( _bsfc && (_deMuxPkt.stream_index == _videoStreamIndex) ) { pkt = _pf->Get( (size_t)_filterPkt.size + DEFAULT_PADDING ); pkt->SetDataSize( _filterPkt.size ); memcpy( pkt->Map(), _filterPkt.data, _filterPkt.size ); } else { pkt = _pf->Get( (size_t)_deMuxPkt.size + DEFAULT_PADDING ); pkt->SetDataSize( _deMuxPkt.size ); memcpy( pkt->Map(), _deMuxPkt.data, _deMuxPkt.size ); } if( IsKey() ) pkt->SetKey( true ); return pkt; }
XIRef<Packet> ExportOverlay::Process( XIRef<Packet> input, int64_t clockTime ) { cairo_surface_t* surface = NULL; cairo_t* cr = NULL; try { surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, _width, _height ); cr = cairo_create( surface ); uint8_t* cairoSrc = cairo_image_surface_get_data( surface ); int cairoSrcWidth = cairo_image_surface_get_width( surface ); int cairoSrcHeight = cairo_image_surface_get_height( surface ); if( cairo_image_surface_get_stride( surface ) != (cairoSrcWidth * 4) ) X_THROW(("Unexpected cairo stride!")); cairo_set_source_rgba( cr, 0.0, 0.0, 0.0, 1.0 ); cairo_rectangle( cr, 0.0, 0.0, cairoSrcWidth, cairoSrcHeight ); cairo_fill( cr ); memcpy( cairoSrc, input->Map(), input->GetDataSize() ); PangoLayout* layout = pango_cairo_create_layout( cr ); pango_layout_set_text( layout, _decodedMsg.c_str(), -1 ); PangoFontDescription* desc = pango_font_description_from_string( "Helvetica 22" ); pango_layout_set_font_description( layout, desc ); pango_font_description_free( desc ); PangoRectangle logicalRect; pango_layout_get_pixel_extents( layout, NULL, &logicalRect ); uint16_t y = (_vAlign==V_ALIGN_TOP) ? 14 : _height - 52; uint16_t timeX = 0; uint16_t msgX = 0; uint16_t bgX = 0; uint16_t bgWidth = 0; _GetXPositions( timeX, msgX, logicalRect.width, bgX, bgWidth ); cairo_set_source_rgba( cr, 0.5, 0.5, 0.5, 0.50 ); cairo_rectangle( cr, bgX, y, bgWidth, 32 ); cairo_fill( cr ); cairo_set_source_rgba( cr, 1.0, 1.0, 1.0, 1.0 ); if( !_decodedMsg.empty() ) _DrawMessage( cr, layout, msgX, y ); if( _withTime ) _DrawTime( cr, timeX, y, clockTime ); g_object_unref( layout ); // copy from our watermark surface to our output surface... cairo_set_source_surface( cr, _wmSurface, _logoX, _logoY ); cairo_rectangle( cr, _logoX, _logoY, _logoWidth, _logoHeight ); cairo_clip( cr ); cairo_paint_with_alpha( cr, 0.70 ); // Copy data out of our cairo surface into our output packet... size_t outputSize = (cairoSrcWidth * 4) * cairoSrcHeight; XIRef<Packet> dest = new Packet( outputSize ); memcpy( dest->Map(), cairoSrc, outputSize ); dest->SetDataSize( outputSize ); cairo_destroy( cr ); cairo_surface_destroy( surface ); return dest; } catch(...) { if( cr ) cairo_destroy( cr ); if( surface ) cairo_surface_destroy( surface ); throw; } }