Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 2006.11.12;
Скачать: [xml.tar.bz2];

Вниз

Нужен совет по созданию компонента с потоком.   Найти похожие ветки 

 
DVM ©   (2006-03-20 11:05) [0]

Пишу компонент. Невизуальный. Для простоты изложения положим, что у него должны присутствовать два события:
OnError и OnNewBitmap.
Компонент при старте создает дополнительный поток, который получает откуда-то (с вебсервера) изображения. Если поток получил новую картинку - должно возникать OnNewBitmap, если при получении произошла ошибка OnError.
И в том и в другом случае из потока надо передавать параметры (код ошибки или сам битмап), поэтому Synchronize тут не подходит.
Я решил сделать так:
1) Компонент создает скрытое окно и ждет получения сообщений от потока.
2) Поток при возникновении нужной ситуации посылает сообщение скрытому окну компонента.
3) Я планирую использовать WM_COPYDATA для передачи картинки из дополнительного потока в основной и далее в обработчик события.

Правильно ли я спланировал путь решения задачи? Или есть ли более простые пути и если да, то какие?


 
Reindeer Moss Eater ©   (2006-03-20 11:16) [1]

3) Я планирую использовать WM_COPYDATA

Зачем так серьёзно?
Все же происходит в рамках одного процесса.
Достаточно указателя на начало битмапа и его длину в wParam и lParam.


 
DVM ©   (2006-03-20 11:27) [2]


> Зачем так серьёзно?

А если пока я буду работать с битмапом в обработчике OnNewBitmap поток его (битмап) изменит? Не хотелось бы тормозить поток блокировкой битмапа.
А так просто я отправлю копию битмапа и все.
Правда опасаюсь, что с WM_COPYDATA может получиться медленно. Битмапов будет передаваться много.


 
Reindeer Moss Eater ©   (2006-03-20 11:29) [3]

А если пока я буду работать с битмапом в обработчике OnNewBitmap поток его (битмап) изменит?

А с какого он его изменит?
Не генери событие в компоненте пока не получишь весь битмап с сервера.
Точнее не посылай мессадж в окно компонента пока не качнул весь битмап.
А после того как его выкачал, зачем потоку что-то делать с картинкой?


 
DVM ©   (2006-03-20 11:33) [4]


> А после того как его выкачал, зачем потоку что-то делать
> с картинкой?

Он начинает качать следующую и класть ее на место старой. И так далее. Поэтому я опасаюсь, что я пошлю сообщение с указателем на начало битмапа, и пока сообщение дойдет и обработчик им займется, поток, получив новую картинку, просто заменит данные битмапа.


 
Reindeer Moss Eater ©   (2006-03-20 11:34) [5]

Он начинает качать следующую и класть ее на место старой.

На какое такое "место"?
В тот же файл-что ли? Или в тот же кусок памяти?
И нафига?


 
DVM ©   (2006-03-20 11:42) [6]


> На какое такое "место"?
> В тот же файл-что ли? Или в тот же кусок памяти?
> И нафига?

При старте потока он создает новый битмап FCamBitmap := TBitmap.Create;
Поток получает данные JPEG в специальный буфер, потом как накопится полный кадр, кадр декодируется в Bitmap с пом. Intel Jpeg Library и декодированные данные помещаются в этот битмап.

Поток получает видео в формате MotionJPEG.


function LoadBmpFromJpegInMemory   (bitmap: TBitmap;  Mem: Pointer; MemSize: integer;
                             const set_pixel_format: boolean;
                             const scale: TIJLScale = ijlFullSize): boolean;

var
 iWidth, iHeight, iNChannels: Integer;
 iDIBChannels: integer;
 iStatus: integer;
 jcprops: TJPEG_CORE_PROPERTIES;
 DIB: TDIBSection;
begin
 Result := False;
 if not Assigned (bitmap) then Exit;
 if Mem = nil then Exit;

 case bitmap.PixelFormat of
   pf8Bit: iDIBchannels := 1;
   pf24Bit: iDIBchannels := 3;
 else
   iDIBchannels := 0;
 end;
 if (iDIBChannels = 0) and (not set_pixel_format) then Exit;

 // Initialise the JPEG library
 FillChar (jcprops, SizeOf (jcprops), 0);  // Just to be sure...
 iStatus := ijlInit (@jcprops);
 if iStatus = IJL_OK then
 try

   jcprops.JPGBytes := Mem;
   jcprops.JPGSizeBytes := MemSize;
   iStatus := ijlRead (@jcprops, IJL_JBUFF_READPARAMS);
   if iStatus = IJL_OK then
     begin
     iWidth := jcprops.JPGWidth;
     iHeight := jcprops.JPGHeight;
     case scale of
       ijlHalf: begin
                iWidth := (iWidth + 1) div 2;
                iHeight := (iHeight + 1) div 2;
                end;
       ijlQuarter: begin
                iWidth := (iWidth + 3) div 4;
                iHeight := (iHeight + 3) div 4;
                end;
       ijlEighth: begin
                iWidth := (iWidth + 7) div 8;
                iHeight := (iHeight + 7) div 8;
                end;
     end;
     iNChannels := jcprops.JPGChannels;
     if (iNChannels = 1) or (iNChannels = 3) then
       begin
       bitmap.Height := 0;
       bitmap.Width := 0;
       if set_pixel_format then
         begin
         iDIBChannels := iNChannels;
         if iDIBChannels = 1
           then bitmap.PixelFormat := pf8Bit
           else bitmap.PixelFormat := pf24Bit;
         end;
       bitmap.Width := iWidth;
       bitmap.Height := iHeight;
       FillChar (DIB, SizeOf (DIB), 0);
       iStatus := GetObject (bitmap.Handle, SizeOf (DIB), @DIB);
       if iStatus <> 0 then
         begin
         jcprops.DIBWidth := iWidth;
         jcprops.DIBHeight := -iHeight;
         jcprops.DIBChannels := iDIBChannels;
         if iDIBchannels = 3
           then jcprops.DIBColor := IJL_BGR
           else jcprops.DIBColor := IJL_G;
         jcprops.DIBPadBytes := ((((iWidth*iDIBChannels)+3) div 4)*4)-(iWidth*iDIBChannels);
         jcprops.DIBBytes := PByte (DIB.dsBm.bmBits);

         case scale of
           ijlHalf: iStatus := ijlRead (@jcprops, IJL_JBUFF_READONEHALF);
           ijlQuarter: iStatus := ijlRead (@jcprops, IJL_JBUFF_READONEQUARTER);
           ijlEighth: iStatus := ijlRead (@jcprops, IJL_JBUFF_READONEEIGHTH);
         else
           iStatus := ijlRead (@jcprops, IJL_JBUFF_READWHOLEIMAGE);
         end;

         if iStatus >= 0 then
           begin
           //bitmap.Modified := True;
           Result := True;
           end;
         end;
       end;
     end;
 finally
   ijlFree (@jcprops);
 end;

end;


 
Reindeer Moss Eater ©   (2006-03-20 11:47) [7]

Ну и в чем такая острая необходимость качать данные в один и тот же битмап?


 
DVM ©   (2006-03-20 11:53) [8]


> Ну и в чем такая острая необходимость качать данные в один
> и тот же битмап?

А как по другому? При получении нового кадра создавать каждый раз в потоке новый битмап и отсылать указатель на него с сообщением, а в обработчике после всех необходимых манипуляций освобождать? Я правильно понял?


 
Reindeer Moss Eater ©   (2006-03-20 12:07) [9]

Зачем тебе вообще битмап в потоке?
Он качает данные с веб сервера.
В итоге либо файл на диске, либо кусок байтов в памяти.
Закачав очередной кадр, оповести свой компонент о файле или блоек памяти и качай другой кадр в другой файл или в другой буфер.
Вот и все.


 
DVM ©   (2006-03-20 12:13) [10]


> Зачем тебе вообще битмап в потоке?

Ну потому как декодирование тоже в доп потоке происходит, хотя это можно оттуда и вынести в основной поток. И даже лучше вынести.

А вообще спасибо большое. Заклинило меня что-то на этом одном битмапе и отсюда все сложности.

Спасибо еще раз за советы.



Страницы: 1 вся ветка

Форум: "Компоненты";
Текущий архив: 2006.11.12;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.055 c
2-1161806369
Kolan
2006-10-25 23:59
2006.11.12
Ошибка "CommandText does not return a result set".


15-1161983461
unknown
2006-10-28 01:11
2006.11.12
Clawfinger


2-1161869692
MishaLuk
2006-10-26 17:34
2006.11.12
вызов внешней программы из Delphi


2-1161837836
Sergdead
2006-10-26 08:43
2006.11.12
Access


2-1162122043
~Aid~
2006-10-29 14:40
2006.11.12
размер





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский