winapi - Bitmap Support In C++ -
below snippet i've taken msdn example chops video stream in small thumbnails @ selected intervals:
//------------------------------------------------------------------- // createbitmaps // // creates array of thumbnails video file. // // prt: direct2d render target. used create bitmaps. // count: number of thumbnails create. // psprites: array of sprite objects hold bitmaps. // // note: caller allocates sprite objects. //------------------------------------------------------------------- hresult thumbnailgenerator::createbitmaps( id2d1rendertarget *prt, dword count, sprite psprites[] ) { hresult hr = s_ok; bool bcanseek = 0; longlong hnsduration = 0; longlong hnsrangestart = 0; longlong hnsrangeend = 0; longlong hnsincrement = 0; hr = canseek(&bcanseek); if (failed(hr)) { return hr; } if (bcanseek) { hr = getduration(&hnsduration); if (failed(hr)) { return hr; } hnsrangestart = 0; hnsrangeend = hnsduration; // have file duration , we'll take bitmaps // several positions in file. occasionally, first frame // in video black, don't start @ time 0. hnsincrement = (hnsrangeend - hnsrangestart) / (count + 1); } // generate bitmaps , invalidate button controls // redrawn. (dword = 0; < count; i++) { longlong hpos = hnsincrement * (i + 1); hr = createbitmap( prt, hpos, &psprites[i] ); } return hr; } // /// private methods // //------------------------------------------------------------------- // createbitmap // // creates 1 video thumbnail. // // prt: direct2d render target. used create bitmap. // hnspos: seek position. // psprite: sprite object hold bitmap. //------------------------------------------------------------------- hresult thumbnailgenerator::createbitmap( id2d1rendertarget *prt, longlong& hnspos, sprite *psprite ) { hresult hr = s_ok; dword dwflags = 0; byte *pbitmapdata = null; // bitmap data dword cbbitmapdata = 0; // size of data, in bytes longlong hnstimestamp = 0; bool bcanseek = false; // can source seek? dword cskipped = 0; // number of skipped frames imfmediabuffer *pbuffer = 0; imfsample *psample = null; id2d1bitmap *pbitmap = null; hr = canseek(&bcanseek); if (failed(hr)) { return hr; } if (bcanseek && (hnspos > 0)) { propvariant var; propvariantinit(&var); var.vt = vt_i8; var.hval.quadpart = hnspos; hr = m_preader->setcurrentposition(guid_null, var); if (failed(hr)) { goto done; } } // pulls video frames source reader. // note: seeking might inaccurate, depending on container // format , how file indexed. therefore, first // frame might earlier desired time. // if so, skip max_frames_to_skip frames. while (1) { imfsample *psampletmp = null; hr = m_preader->readsample( (dword)mf_source_reader_first_video_stream, 0, null, &dwflags, null, &psampletmp ); if (failed(hr)) { goto done; } if (dwflags & mf_source_readerf_endofstream) { break; } if (dwflags & mf_source_readerf_currentmediatypechanged) { // type change. new format. hr = getvideoformat(&m_format); if (failed(hr)) { goto done; } } if (psampletmp == null) { continue; } // got sample. hold onto it. saferelease(&psample); psample = psampletmp; psample->addref(); if (succeeded( psample->getsampletime(&hnstimestamp) )) { // keep going until frame within tolerance of // desired seek position, or until skip max_frames_to_skip frames. // during process, might reach end of file, // cache last sample got (psample). if ( (cskipped < max_frames_to_skip) && (hnstimestamp + seek_tolerance < hnspos) ) { saferelease(&psampletmp); ++cskipped; continue; } } saferelease(&psampletmp); hnspos = hnstimestamp; break; } if (psample) { uint32 pitch = 4 * m_format.imagewidthpels; // bitmap data sample, , use create // direct2d bitmap object. use direct2d bitmap // initialize sprite. hr = psample->converttocontiguousbuffer(&pbuffer); if (failed(hr)) { goto done; } hr = pbuffer->lock(&pbitmapdata, null, &cbbitmapdata); if (failed(hr)) { goto done; } assert(cbbitmapdata == (pitch * m_format.imageheightpels)); hr = prt->createbitmap( d2d1::sizeu(m_format.imagewidthpels, m_format.imageheightpels), pbitmapdata, pitch, d2d1::bitmapproperties( // format = rgb32 d2d1::pixelformat(dxgi_format_b8g8r8a8_unorm, d2d1_alpha_mode_ignore) ), &pbitmap ); if (failed(hr)) { goto done; } psprite->setbitmap(pbitmap, m_format); } else { hr = mf_e_end_of_stream; } done: if (pbitmapdata) { pbuffer->unlock(); } saferelease(&pbuffer); saferelease(&psample); saferelease(&pbitmap); return hr; }
instead of bitmaps being placed inside sprite objects (passed in array), want method return array of bitmaps. msdn suggests bitmap class exist c++ though can't seem include reference class. want compile class dll , use in c# project can pass uri movie , have chopped , returned bitmap frames these methods. can take care of logic myself, need know how make code handle , return bitmap[]
of frames createbitmaps()
method.
using windows api, can create bitmap. so, instead of doing:
psprite->setbitmap(pbitmap, m_format);
you should pass pointer bitmap object parameter createbitmap function , use in function:
*pbitmap = new bitmap(int width, int height, int stride, pixelformat format, byte *scan0);
in above, replace *scan0 pointer bitmap data in bytes (which believe in code pbitmap) , rest of information regarding height, width, pixelformat etc, m_format variable.
this should work you.
note: please include gdi+ headers bitmap class part of it.
hope helps.
p.s. if averse using gdi+ classes, can try bitmap object msdn offers part of windows gdi. though personally, feel offers lot less functionality , takes longer code.
Comments
Post a Comment