Recent

Author Topic: The move procedure in the loop is not working properly  (Read 3351 times)

RedCat

  • New Member
  • *
  • Posts: 28
Re: The move procedure in the loop is not working properly
« Reply #15 on: April 25, 2020, 02:16:55 pm »
Here is the frame information, for now I’m hiding a simple bmp image:
Code: Pascal  [Select][+][-]
  1. Input # 0, bmp_pipe, from 'c: /test.bmp':
  2.    Duration: N / A, bitrate: N / A
  3.      Stream # 0: 0: Video: bmp, bgr24, 128x128, 25 tbr, 25 tbn, 25 tbc
  4.  
I also do not quite understand the logic of this expression (the code is not my copy-paste), but I repeat on Delphi it worked:
Code: Pascal  [Select][+][-]
  1.  for i: = 0 to vp.bmp.Height - 1 do
  2.        CopyMemory (vp.bmp.ScanLine [i], pointer (integer (dataIN) + SizeX * 4 * i), SizeX * 4);
  3.  

I understand that so
Code: Pascal  [Select][+][-]
  1. vp.bmp.ScanLine [i]
is an array of pixels (row), but this expression:
Code: Pascal  [Select][+][-]
  1. pointer (integer (dataIN) + SizeX * 4 * i)
  I don’t understand at all
« Last Edit: April 25, 2020, 02:18:47 pm by RedCat »

Handoko

  • Hero Member
  • *****
  • Posts: 5515
  • My goal: build my own game engine using Lazarus
Re: The move procedure in the loop is not working properly
« Reply #16 on: April 25, 2020, 02:57:40 pm »
I remember I ever had similar problem long time ago. Simply copying the image's data didn't work. Just as marcov said, I later solved it by setting the target's pixel format and dimension, then problem solved. Have tried what marcov suggestion?

If you want to show us the code, please show the whole code. Showing only one or two lines usually is not very useful. Create a new folder, copy and paste all the necessary files except: the binary (exe file), *.bak, lib and backup folders. Compress the folder and send the zip file here.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6325
  • Compiler Developer
Re: The move procedure in the loop is not working properly
« Reply #17 on: April 25, 2020, 02:59:46 pm »
I understand that so
Code: Pascal  [Select][+][-]
  1. vp.bmp.ScanLine [i]
is an array of pixels (row), but this expression:
Code: Pascal  [Select][+][-]
  1. pointer (integer (dataIN) + SizeX * 4 * i)
  I don’t understand at all

SizeX is the number of pixels in a row. SizeX * 4 is the number of bytes in a row. SizeX * 4 * i is the i-th row. So for your original move you should use PByte(dataOut)[SizeX * 4 * y] for the destination otherwise you're just moving along the first line in the destination buffer with PByte(dataOut)[y].

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12657
  • FPC developer.
Re: The move procedure in the loop is not working properly
« Reply #18 on: April 25, 2020, 03:02:23 pm »
Your pixel type is bgr24. This isn't the same as what I expect from the Delphi code. (since that multiplies #pixels in the X direction by 4, not 24/8=3).

So either your stream is different, or some layer is different and doesn't perform the 3->4 conversion.

And my earlier remark still stands, make sure that both bitmaps are of the same pixeltype (po24bit probably or po32bit if whatever reader library converts it to 32-bit).

There is no escape, you need to find out what the actual formats are of the in and out bitmaps in both Delphi and lazarus. Maybe then we get somewhere and know if there is a difference.
« Last Edit: April 25, 2020, 03:21:30 pm by marcov »

RedCat

  • New Member
  • *
  • Posts: 28
Re: The move procedure in the loop is not working properly
« Reply #19 on: April 25, 2020, 06:24:25 pm »
Here is the whole format conversion code:
Code: Pascal  [Select][+][-]
  1. img_convert_context: = sws_getContext (codec_context ^ .width, codec_context ^ .height, codec_context ^ .pix_fmt, codec_context ^ .width, codec_context ^ .height, AV_PIX_FMT_RGB24, SWS_BILINEAR, nil, nil, nil, nil, nil, nil, nil, nil, nil
  2. pFrameYUV420P: = av_frame_alloc ();
  3. numBytes: = avpicture_get_size (AV_PIX_FMT_RGB24, codec_context ^ .width, codec_context ^ .height);
  4. mybuffer: = av_malloc (numBytes * sizeof (cardinal));
  5. avpicture_fill (PAVPicture (pFrameYUV420P), mybuffer, AV_PIX_FMT_RGB32, codec_context ^ .width, codec_context ^ .height);
  6. if not assigned (pFrameYUV420P) then
  7.  begin
  8.   writeln ('Could not Allocate AVFrame structure');
  9.   exit
  10.  end;
  11. sws_scale (img_convert_context, @ frame ^ .data, @ frame ^ .linesize, 0, codec_context ^ .height, @ pFrameYUV420P ^ .data, @ pFrameYUV420P ^ .linesize);
The input format can be any, but the output will always be AV_PIX_FMT_RGB24. Do not pay attention to the variable name pFrameYUV420P, there is more precisely not the YUV format. when it was implemented in Delphi it was the same principle, the decoded frame using sws_scale turned into AV_PIX_FMT_RGB24 and then rendered in Tbitmap. I understand that you need to somehow shift the bytes, but I myself have never personally used bit operations in either delphi or lazarus. And all ready-made examples with Avcodec use SDL for rendering, so I don’t even have anywhere to see how this can be implemented without SDL
I couldn’t put the attachment, so here the link to it is the source code of the project in zip
http://nfftech.uz/wp-content/uploads/2020/04/On-forum-src.zip
« Last Edit: April 25, 2020, 06:47:56 pm by RedCat »

MarkMLl

  • Hero Member
  • *****
  • Posts: 8534
Re: The move procedure in the loop is not working properly
« Reply #20 on: April 25, 2020, 10:11:25 pm »
Can I ask a silly question please?

I'd always assumed that := shouldn't have whitespace in it: it was, after all, originally a digraph for a left arrow.

Is there any possibility whatsoever that the compiler's reacting badly to this unusual form?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12657
  • FPC developer.
Re: The move procedure in the loop is not working properly
« Reply #21 on: April 25, 2020, 11:16:21 pm »
Weird code that seems to have enormous amounts of trial and error debugging. This doesn't look like Delphi/Lazarus but an enormous amount of trial-and-error work, and maybe simply using a different stream from back then with Delphi, and the program, old and crufty that it is reacting bad to it. I count multiple sets of opengl headers, copy and pasted bmp structures, UGH.

First and for all. You might not want to do these changes by hand since you use opengl for display. Some changes (like RGB swap and topdown) can be handled by OpenGL.

E.g. you might be avoid the whole need for byteswapping by changing this code

Code: [Select]
  if Format = GL_RGBA then
      gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, pData)
    else
      gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pData);

to read GL_BGR and GL_BGRA. I don't know GLU though, I always used opengl directly, and not using mipmaps.

Some streams generate topdown code (first line is top line of the image), some bottom up (first line in memory is last line of image). This code:

Code: [Select]
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0); glVertex3f(-1,-1,0);
    glTexCoord2f(1, 0); glVertex3f(1,-1,0);
    glTexCoord2f(1, 1); glVertex3f(1,1,0);
    glTexCoord2f(0, 1); glVertex3f(-1,1,0);
  glEnd;

probably governs drawing. negating some of the glvertex3f Y (second) coordinates might change the image topdown.

As to the image corruption (it is not just the above problems since I see much more loops than in the original which means something 3-byte vs 4-bite probably, or origin image having different dimensions than the target image (e.g. due to the sws_scale)

So I search for your code line and look at it:

Code: [Select]
     SwapTB(pFrameYUV420P^.data[0],pData,codec_context^.width,codec_context^.height);

This copies from  pFrameYUV420P^.data[0],pData.

Pdata is a rightly sized buffer:
Code: [Select]
          GetMem(pData, codec_context^.width*codec_context^.height*4);

so probably not the problem.

So the problem seems to be the source. I also don't understand how "mybuffer" factors into it. Also its calculation is a bit weird

Code: [Select]
numBytes: = avpicture_get_size (AV_PIX_FMT_RGB24, codec_context ^ .width, codec_context ^ .height);
mybuffer: = av_malloc (numBytes * sizeof (cardinal));

Why the times sizeof(cardinal?), avpicture_get_size knows it is RGB24, so should already multiply with 3?

But then there is suddenly
Code: [Select]
avpicture_fill (PAVPicture (pFrameYUV420P), mybuffer, AV_PIX_FMT_RGB32, codec_context ^ .width, codec_context ^ .height);

where clearly suddenly is spoken about RGB32, IOW 4 bytes per pixel.

And then there swaptb that assumes everything is 4 bytes per pixel. Are you sure that pFrameYUV420P^.data[0] is the right pointer (and not e.g. @mybuffer[0]), and if it is really 32-bit  per pixel ?

Hope I gave you a few pointers to look at.







jamie

  • Hero Member
  • *****
  • Posts: 7544
Re: The move procedure in the loop is not working properly
« Reply #22 on: April 26, 2020, 12:43:52 am »
I have worked with this format before in a different live implementing the old YUV system in software which works basically the same as NTSC "Never the same color twice"
 Look here at the bottom of the page..

https://en.wikipedia.org/wiki/YUV

It explains the format..

 basically you first have the chroma which is a Byte size per pixel black and white image.

 following are two more lines which are smaller because they are stretched out to be use for the chroma.. These are the UV lines and in this format here for every one byte of U manages a 2x2 grid of pixels.

 The UV values normally stay at center point for a gray scale and then +/- to remove the elements of the chroma which gives you color since chroma is made up of RGB anyways..

 Basically you can get a sharp chroma image but reduced color resolution but not pixel res..

 
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018