virtual HRESULT VideoInputFrameArrived(IDeckLinkVideoInputFrame *in, IDeckLinkAudioInputPacket *audio_in) { RawFrame *out; AudioPacket *audio_out; void *data; uint8_t *bytes; size_t i, spitch, h; if (in != NULL) { if (in->GetFlags( ) & bmdFrameHasNoInputSource) { fprintf(stderr, "DeckLink input: no signal\n"); } else { out = new RawFrame(in->GetWidth(), in->GetHeight(), pf); out->set_field_dominance(dominance); spitch = in->GetRowBytes( ); h = in->GetHeight( ); in->GetBytes(&data); bytes = (uint8_t *) data; for (i = 0; i < h; i++) { memcpy(out->scanline(i), bytes, out->pitch( )); bytes += spitch; } if (out_pipe.can_put( )) { out_pipe.put(out); } else { fprintf(stderr, "DeckLink: dropping input frame on floor\n"); delete out; } } } if (audio_in != NULL && audio_pipe != NULL) { audio_out = new AudioPacket(audio_rate, n_channels, 2, audio_in->GetSampleFrameCount( )); if (audio_in->GetBytes(&data) != S_OK) { throw std::runtime_error( "DeckLink audio input: GetBytes failed" ); } memcpy(audio_out->data( ), data, audio_out->size( )); audio_pipe->put(audio_out); } return S_OK; }
RawFrame *upscale(RawFrame *in) { RawFrame *out = new RawFrame(1920, 1080, RawFrame::CbYCrY8422); uint8_t *scaled_1 = new uint8_t[2*1920]; uint8_t *scaled_2 = new uint8_t[2*1920]; for (int i = 0; i < out->h( ); i++) { int src_scan = i * 4 / 9; uint8_t *scanline_1 = in->scanline(src_scan); uint8_t *scanline_2; if (src_scan + 1 < in->h( )) { scanline_2 = in->scanline(src_scan + 1); } else { scanline_2 = in->scanline(src_scan); } upscale_scanline(scaled_1, scanline_1); upscale_scanline(scaled_2, scanline_2); interpolate_scanline(out->scanline(i), scaled_1, scaled_2, (4 * i) % 9); } return out; }
RawFrame *FreetypeFont::render_string(const char *string) { int x; RawFrame *ret; FT_GlyphSlot slot = face->glyph; FT_Bool use_kerning = FT_HAS_KERNING(face); FT_UInt glyph_index, previous; uint8_t *glyph_scanline; x = 0; previous = 0; /* first compute the size of the resulting image */ const char *scan_ptr = string; while (*scan_ptr != '\0') { glyph_index = FT_Get_Char_Index(face, *scan_ptr); scan_ptr++; if (use_kerning && previous != 0 && glyph_index != 0) { FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); x += delta.x / 64; } FTCHK(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT)); x += slot->advance.x / 64; previous = glyph_index; } /* initialize a raw frame */ ret = new RawFrame(x, _h, RawFrame::BGRAn8); /* second pass: draw it */ scan_ptr = string; int xd = 0; previous = 0; uint8_t *dest_scanline = ret->data( ); for (unsigned int i = 0; i < ret->size( ); i += 4) { dest_scanline[i] = bb; dest_scanline[i+1] = gb; dest_scanline[i+2] = rb; dest_scanline[i+3] = ab; } while (*scan_ptr != '\0') { glyph_index = FT_Get_Char_Index(face, *scan_ptr); scan_ptr++; if (use_kerning && previous != 0 && glyph_index != 0) { FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); xd += delta.x / 64; } FTCHK(FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER)); //int yd = -(slot->bitmap_top); int yd = _baseline - slot->bitmap_top; for (unsigned int y = 0; y < slot->bitmap.rows && yd < _h; y++, yd++) { if (yd >= 0) { glyph_scanline = ((uint8_t *)slot->bitmap.buffer) + slot->bitmap.pitch * y; dest_scanline = ret->scanline(yd) + 4*xd; int xd2 = xd; for (unsigned int x = 0; x < slot->bitmap.width && xd2 < ret->w( ); x++, xd2++) { dest_scanline[0] = (bf * glyph_scanline[x] + bb * (255 - glyph_scanline[x])) / 255; dest_scanline[1] = (gf * glyph_scanline[x] + gb * (255 - glyph_scanline[x])) / 255; dest_scanline[2] = (rf * glyph_scanline[x] + rb * (255 - glyph_scanline[x])) / 255; dest_scanline[3] = (af * glyph_scanline[x] + ab * (255 - glyph_scanline[x])) / 255; dest_scanline += 4; } } } xd += slot->advance.x / 64; previous = glyph_index; } return ret; }