Assembly 从汇编中的BMP文件制作视频

Assembly 从汇编中的BMP文件制作视频,assembly,video-capture,x86-16,bmp,Assembly,Video Capture,X86 16,Bmp,我在DosBox(8086)中完成了一个关于school on assembly 16位的项目,我制作了一个程序,从中获取了一个截图(BMP格式),它工作得非常完美。我想从这些图片中制作一个视频。 我想知道我应该使用哪种视频格式(我想要最简单的),如果有人能告诉我如何制作视频文件,我会很完美 我如何制作屏幕截图: ;--------------------------MakeScreenshot-------------------------- ; Description: Saving t

我在DosBox(8086)中完成了一个关于school on assembly 16位的项目,我制作了一个程序,从中获取了一个截图(BMP格式),它工作得非常完美。我想从这些图片中制作一个视频。 我想知道我应该使用哪种视频格式(我想要最简单的),如果有人能告诉我如何制作视频文件,我会很完美

我如何制作屏幕截图:

;--------------------------MakeScreenshot--------------------------
; Description:  Saving the screen posion in a file(in the log directory)
; Return:       Nothing.
;------------------------------------------------------------------
proc MakeScreenshot
    pusha
    mov bp, sp
    sub sp, 2
    push offset MkScrnshotLog1
    call AddToLog

    @MakeScreenshot@lineCounter         equ [word ptr bp - 2]
    ; creating the file
        push offset MkScrnshotLog3
        call AddToLog
        ; finding the last var in the arr
            push offset ScreenShotPath
            push 1000
            push 0
            call find

            cmp [index], -1 
            jne @MakeScreenshot@cont6
            call PError

    @MakeScreenshot@cont6:
        mov bl, [index]
        xor bh, bh
        add bx, offset ScreenShotPath
        sub bx, 6
        mov di, bx

    ; get the time
        ; CH = hour (0-23)
        ; CL = minutes (0-59)
        ; DH = seconds (0-59)
        mov ah, 2ch
        int 21h
        cmp dx, [SecAndMin]
        jnae @MakeScreenshot@cont
            inc [byte ptr di + 1]
            jmp @MakeScreenshot@SameSec

    @MakeScreenshot@cont:
        mov [SecAndMin], dx
        mov dl, dh
        xor dh, dh
        mov ax, dx
        cmp ax, 10
        jae @MakeScreenshot@Div4
            mov [byte ptr di], '0'
            inc di
            add al, '0'
            mov [byte ptr di], al
            sub di, 4
            jmp @MakeScreenshot@file

    @MakeScreenshot@Div4:
    ; Divide the number to digits in the stack
        xor si, si                  ; Si counts the number of digits
        mov bl, 10
    @MakeScreenshot@dig5:
        div bl                      ; Divide ax by 10
        mov cl, ah
        xor ch, ch
        push cx                     ; Save the digit in the stack
        xor ah, ah
        inc si
        cmp ax, 0
        jne @MakeScreenshot@dig5

        mov cx, si
        mov si, di
    @MakeScreenshot@Sec:
        pop ax
        xor ah, ah
        add al, '0'
        mov [si], al
        inc si
        loop @MakeScreenshot@Sec

        sub di, 3

    @MakeScreenshot@file:
        ; get the time
        ; CH = hour (0-23)
        ; CL = minutes (0-59)
        ; DH = seconds (0-59)
        mov ah, 2ch
        int 21h
        xor ch, ch
        mov ax, cx
        cmp ax, 10
        jae @MakeScreenshot@Div5
            inc di
            mov [byte ptr di], '0'
            inc di
            add al, '0'
            mov [byte ptr di], al
            inc di
            jmp @MakeScreenshot@creat

    @MakeScreenshot@Div5:
    ; Divide the number to digits in the stack
        xor si, si                  ; Si counts the number of digits
        mov bl, 10
    @MakeScreenshot@dig6:
        div bl                      ; Divide ax by 10
        mov cl, ah
        xor ch, ch
        push cx                     ; Save the digit in the stack
        xor ah, ah
        inc si
        cmp ax, 0
        jne @MakeScreenshot@dig6

        mov cx, si
        inc di
        mov si, di
    @MakeScreenshot@Min:
        pop ax
        xor ah, ah
        add al, '0'
        mov [byte ptr si], al
        inc si
        loop @MakeScreenshot@Min

@MakeScreenshot@SameSec:    
    cmp dx, [SecAndMin]
        jnae @MakeScreenshot@creat
            inc [byte ptr di + 1]
            jmp @MakeScreenshot@SameSec
@MakeScreenshot@creat:
    push offset ScreenShotPath
    push offset ScreenShotHandle
    call CreateFile

    ; write the header
        push offset MkScrnshotLog3
        call AddToLog

        mov ah, 40h
        mov bx, [ScreenShotHandle]  ; file handle
        mov cx, 54                  ; number of bytes to write
        mov dx, offset Fileheader   ; pointer to write buffer (the header is the same and we take a picture omly after the main page so i will not be empty)
        int 21h 
        jnc @MakeScreenshot@Cont20
            mov ah, 59h
            mov bx, 0
            int 21h
            push ax
            call PrintFileError
        @MakeScreenshot@Cont20:

    ; write the pallete
        push offset ScreenShotPalette
        call SavePalette
        push offset MkScrnshotLog4
        call AddToLog
        mov cx, 256
        mov bx, offset ScreenShotPalette
        xor di, di
        @MakeScreenshot@copyPal:
            ; Note: The palette of BMP files are BGR and not RGB so it has to be upsidedown.

            ; Copy last/first color (blue)
                mov al, [bx + 2]    ; Get the last color of the palette to the first color (blue).
                shl al, 2           ; The BMP palette is larger. ThereFore multyplayer by 4 in order ro corp it to the right size.
                mov [byte ptr ScreenShotPalette2 + di], al
                inc di

            ; Do the same on the second color (green)
                mov al, [bx + 1] 
                shl al, 2
                mov [byte ptr ScreenShotPalette2 + di], al
                inc di

            ; Do the same on the first/last color (red)
                mov al, [bx]
                shl al, 2
                mov [byte ptr ScreenShotPalette2 + di], al
                inc di

            ; enter an empty byte
                mov [byte ptr ScreenShotPalette2 + di], 0
                inc di

            add bx, 3               
            loop @MakeScreenshot@copyPal            ; It has to be 256 time becuase there are 256 colors im the palette.    

        mov ah, 40h
        mov bx, [ScreenShotHandle]          ; file handle
        mov cx, 256 * 4                     ; number of bytes to write
        mov dx, offset ScreenShotPalette2   ; pointer to write buffer 
        int 21h 
        jnc @MakeScreenshot@Cont2
            mov ah, 59h
            mov bx, 0
            int 21h
            push ax
            call PrintFileError

        @MakeScreenshot@Cont2:
        ; Copy the image
            push offset MkScrnshotLog5
            call AddToLog
            ; Declare the address of the video memory
                mov ax, 0A000h          ; The video memory is stored on A000:0000
                mov es, ax

            ; Copy
                mov cx, 200             ; 200 lines 
                mov @MakeScreenshot@lineCounter, 0      ; Reset the line counter
            @MakeScreenshot@copyImage:
                push cx                 ; Saves the cx for the big loop

                ; Copy one line
                    ; Declare where to copy from
                        mov di, offset ScreenshotLine

                    ; Declare where start to copy
                        mov si, @MakeScreenshot@lineCounter
                        mov ax, 320     ; We start to write a line on A000:lineNumber*320
                        mul si          ; Saves on dx:ax
                        mov si, ax      ; The max outcome fits into one word
                        ; Note: si now point where to write if the pic was not upside down

                        ; Make it 
                        mov ax, 63680   ; Ax = ((320 * 200) - 1) - 320 which is the start of the last line of the video memory 
                        sub ax, si      ; Ax now poit to the start of the oppesite line 
                        mov si, ax

                    mov cx, 320
                @MakeScreenshot@copyLine:
                    ; Copy from the stored line into the video memory
                        mov al, [es:si]
                        mov [ds:di], al ; Copy one byte from the stored line to the vide memory
                        inc si
                        inc di
                    loop @MakeScreenshot@copyLine

                ; copy the line to the file
                    mov ah, 40h
                    mov bx, [ScreenShotHandle]          ; file handle
                    mov cx, 320                         ; number of bytes to write
                    mov dx, offset ScreenshotLine       ; pointer to write buffer 
                    int 21h 
                    jnc @AddToLog@Cont3
                        mov ah, 59h
                        mov bx, 0
                        int 21h
                        push ax
                        call PrintFileError
                    @AddToLog@Cont3:
                inc @MakeScreenshot@lineCounter
                pop cx                  ; Return the value to cx
                loop @MakeScreenshot@copyImage

    ; close the file
        push [ScreenShotHandle]
        call closeFile

    add sp, 2                       ; Delete local var

    popa
    ret
endp MakeScreenshot

最简单的?未压缩的rgb。。。将是大的,你将不得不告诉玩家的格式,所以它不会是“点击播放”。嗯。。。我认为FFmpeg可能支持一些简单的未压缩视频格式。如果您使用其中一个并将其放入mkv容器或类似容器中,它可能只在普通视频播放器中播放。@Jester我知道它会很大,但视频会很短,帧速率低,分辨率为320*200,所以不会那么差。@flikhamud45一些用户推荐,这是一种支持良好的未压缩视频流。不过,要获得正确的颜色空间可能很棘手。让我再研究一下。如果你使用未压缩的AVI,位图格式与BMP几乎相同,因此这可能是最简单的解决方案。如果使用未压缩的AVI,位图格式与BMP几乎相同,因此这可能是最简单的解决方案。最简单?未压缩的rgb。。。将是大的,你将不得不告诉玩家的格式,所以它不会是“点击播放”。嗯。。。我认为FFmpeg可能支持一些简单的未压缩视频格式。如果您使用其中一个并将其放入mkv容器或类似容器中,它可能只在普通视频播放器中播放。@Jester我知道它会很大,但视频会很短,帧速率低,分辨率为320*200,所以不会那么差。@flikhamud45一些用户推荐,这是一种支持良好的未压缩视频流。不过,要获得正确的颜色空间可能很棘手。让我再研究一下。如果你使用未压缩的AVI,位图格式与BMP几乎相同,因此这可能是最简单的解决方案。如果使用未压缩的AVI,位图格式与BMP几乎相同,因此这可能是迄今为止最简单的解决方案。