Recherche avancée

Médias (91)

Autres articles (56)

  • Amélioration de la version de base

    13 septembre 2013

    Jolie sélection multiple
    Le plugin Chosen permet d’améliorer l’ergonomie des champs de sélection multiple. Voir les deux images suivantes pour comparer.
    Il suffit pour cela d’activer le plugin Chosen (Configuration générale du site > Gestion des plugins), puis de configurer le plugin (Les squelettes > Chosen) en activant l’utilisation de Chosen dans le site public et en spécifiant les éléments de formulaires à améliorer, par exemple select[multiple] pour les listes à sélection multiple (...)

  • Emballe médias : à quoi cela sert ?

    4 février 2011, par

    Ce plugin vise à gérer des sites de mise en ligne de documents de tous types.
    Il crée des "médias", à savoir : un "média" est un article au sens SPIP créé automatiquement lors du téléversement d’un document qu’il soit audio, vidéo, image ou textuel ; un seul document ne peut être lié à un article dit "média" ;

  • Menus personnalisés

    14 novembre 2010, par

    MediaSPIP utilise le plugin Menus pour gérer plusieurs menus configurables pour la navigation.
    Cela permet de laisser aux administrateurs de canaux la possibilité de configurer finement ces menus.
    Menus créés à l’initialisation du site
    Par défaut trois menus sont créés automatiquement à l’initialisation du site : Le menu principal ; Identifiant : barrenav ; Ce menu s’insère en général en haut de la page après le bloc d’entête, son identifiant le rend compatible avec les squelettes basés sur Zpip ; (...)

Sur d’autres sites (3511)

  • 'pjsip-apps/Samples' Cannot functionally run vid_streamutil.c sample

    2 décembre 2020, par ShootingKIng

    Issue Description
After building[Build Varient=Debug, Build Config=x64] the latest pjproject-vs14 (retargeted to MSVS 2017, WINSDK=8.1, because my application works at these config) as per the build instruction on trac website. Successfully built pjsua and samples.

    


    I want to use only RTP + FFMPEG APIs (pjmedia) for my application from pjproject.

    


    My config_site.h

    


    #define PJMEDIA_HAS_VIDEO           1
#define PJMEDIA_HAS_FFMPEG          1


    


    FFMPEG (pre build from ffmpeg-N-100121-g052b4c3481-win64-gpl-shared.zip)

    


    But running the example, vid_streamutil.c did not work as expected (? Whats the normal expected behaviour ?).
It says

    


    ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)


    


    To Reproduce
Steps to reproduce the behavior :

    


      

    1. run vid_streamutil.exe with parameter : --codec=H264 --remote=127.0.0.1:5000 --play-file=test.avi --send-only
(test.avi file being a sample file)
    2. 


    


    Expected behavior
Get some RTP packets in wireshark while listening to ports 4000 and 5000 maybe ? I dont know whats the expected behaviour, documentation dosent say anything about this :(

    


    Logs/Screenshots
Couldn't catch anything on Wireshark.
Console log of vid_streamutil.exe is

    


    vid_streamutil.exe --codec=H264 --remote=127.0.0.1:5000 --send-only --play-file=test.avi
10:25:24.757 os_core_win32. !pjlib 2.10 for win32 initialized
 
10:25:24.840     wmme_dev.c  WMME found 12 devices:
10:25:24.858     wmme_dev.c   dev_id 0: Wave mapper  (in=2, out=2)
10:25:24.860     wmme_dev.c   dev_id 1: Headset Microphone (Arctis 7 Ch  (in=2, out=0)
10:25:24.860     wmme_dev.c   dev_id 2: Microphone (AMM Virtual Audio D  (in=2, out=0)
10:25:24.861     wmme_dev.c   dev_id 3: CABLE Output (VB-Audio Virtual   (in=2, out=0)
10:25:24.864     wmme_dev.c   dev_id 4: VoiceMeeter Output (VB-Audio Vo  (in=2, out=0)
10:25:24.864     wmme_dev.c   dev_id 5: Microphone (Realtek Audio)  (in=2, out=0)
10:25:24.865     wmme_dev.c   dev_id 6: Headphones (Arctis 7 Game)  (in=0, out=2)
10:25:24.866     wmme_dev.c   dev_id 7: Speakers / Headphones (Realtek   (in=0, out=2)
10:25:24.867     wmme_dev.c   dev_id 8: VoiceMeeter Input (VB-Audio Voi  (in=0, out=2)
10:25:24.884     wmme_dev.c   dev_id 9: Headset Earphone (Arctis 7 Chat  (in=0, out=2)
10:25:24.885     wmme_dev.c   dev_id 10: Speakers (AMM Virtual Audio Dev  (in=0, out=2)
10:25:24.887     wmme_dev.c   dev_id 11: Speakers (VB-Audio Virtual Cabl  (in=0, out=2)
10:25:24.887     wmme_dev.c  WMME initialized
10:25:24.890          pjlib  select() I/O Queue created (0000016B2C5F9608)
10:25:24.892 colorbar_dev.c  Colorbar video src initialized with 2 device(s):
10:25:24.915 colorbar_dev.c   0: Colorbar generator
10:25:24.935 colorbar_dev.c   1: Colorbar-active
10:25:24.956   avi_player.c  The AVI file has 2 streams.
10:25:24.976   avi_player.c  AVI file player 'test.avi' created with 2 media ports
10:25:24.994 vid_streamutil  Reading video stream 1280x720 H264 @30.00fps
10:25:25.033          rtp.c  pjmedia_rtp_session_init: ses=0000016B2C6793C8, default_pt=97, ssrc=0x294823
10:25:25.053 vstdec0000016B  Decoding channel created 720x480 I420<-H264 22/1(~22)fps
10:25:25.054          rtp.c  pjmedia_rtp_session_init: ses=0000016B2C62DF1C, default_pt=97, ssrc=0x294823
10:25:25.057 vstenc0000016B  Encoding channel created 1280x720 I420->H264 30/1(~30)fps
10:25:25.060 udp0000016B2C6  SO_RCVBUF set to 65536
10:25:25.061 udp0000016B2C6  SO_SNDBUF set to 65536
10:25:25.062   vid_stream.c  Video stream vstrm0000016B2C678508 created
10:25:25.086 vstenc0000016B  Encoder stream started
10:25:25.104 vstdec0000016B  Decoder stream paused
 [VID_STEAMUTIL] Stream is active, dir is send-only, sending to 127.0.0.1:5000
10:25:25.114 vid_streamutil  Sending 1280x720 H264 @30.00fps

Commands:
  q     Quit

Command: 10:25:25.147 ffmpeg_vid_cod !ffmpeg err -22: Invalid argument
10:25:25.222 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.237 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.250 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.251 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.287 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.311 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.316 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.341 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.353 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.369 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.386 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.387 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.411 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.415 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.452 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.469 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.486 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.496 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.506 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.527 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.547 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.568 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.576 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.604 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.606 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.627 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.648 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.668 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.686 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.711 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.731 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.752 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.769 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.778 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.804 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.827 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.833 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.868 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.886 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.895 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.921 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.923 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.943 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:25.963 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:25.983 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.003 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.019 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.038 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.041 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.060 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.081 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.086 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.109 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.130 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.138 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.162 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.183 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.202 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.220 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.228 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.260 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.281 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.312 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.321 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.321 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.322 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.323 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.323 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.324 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.324 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.333 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.353 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.353 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.381 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.401 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.414 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.429 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.449 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.469 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.480 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.510 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.531 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.553 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.571 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.594 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.615 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.636 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.653 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.671 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.678 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.714 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.736 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.754 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.777 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.781 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
10:25:26.816 ffmpeg_vid_cod  ffmpeg err -22: Invalid argument
10:25:26.836 vstenc0000016B  Codec encode_begin() error: Codec internal creation error (PJMEDIA_CODEC_EFAILED)
EOF while reading stdin, will quit now..

Commands:
  q     Quit

^C


    


    Desktop information :

    


      

    • OS, Distribution & Version : MS Windows 10 Home, 1909
    • 


    • PJSIP

        

      • version : 2.10
      • 


      • applied patch(es) : Nothing Extra
      • 


      • configure script params : Default
      • 


      • config_site.h contents : Aforementioned
      • 


      • related third party libraries & versions :
FFMPEG 4.3
      • 


      


    • 


    


    #define LIBAVCODEC_VERSION_MAJOR  58
#define LIBAVCODEC_VERSION_MINOR  91
#define LIBAVCODEC_VERSION_MICRO 100


    


    Additional context
I didnt change the default program that must except adding some printf's when program goes to exit label, without this it will be very difficult to know which part of the program jumped to exit : label. Anyways, here is the full code,

    


    vid_streamutil.c (with printfs)

    


    Any help is appreciated ^^'
Thanks.

    


  • How can i save the preview video in pictureBox1 to a avi/mp4 video file on hard disk using directshow ?

    10 avril 2016, par benny dayag

    The first problem maybe it’s not a problem but for some reason the video preview in the pictureBox1 is working but the frame rate seems not right. I can’t figure how to set/change it. The preview video seems a bit dart to the eyes not flickering but not moving smooth.

    The main problem is how to save the preview in the pictureBox1 or directly the streaming to a video file ? The MediaSubtype i’m getting is h.264

    The video is from the device legato game capture.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using DirectShowLib;
    using DirectShowLib.BDA;
    using DirectShowLib.DES;
    using DirectShowLib.DMO;
    using DirectShowLib.Dvd;
    using DirectShowLib.MultimediaStreaming;
    using DirectShowLib.SBE;
    using System.Runtime.InteropServices;
    using System.Management;
    using System.IO;
    using System.Drawing.Imaging;


    namespace Youtube_Manager
    {

       public partial class Elgato_Video_Capture : Form
       {


           IFileSinkFilter sink;

           IFilterGraph2 graph;
           ICaptureGraphBuilder2 captureGraph;
           System.Drawing.Size videoSize;

           string error = "";
           List devices = new List();
           IMediaControl mediaControl;

           public Elgato_Video_Capture()
           {
               InitializeComponent();



               if (comboBox1.Items.Count == 0)
               {
                   for (int xx = 1; xx <= 8; xx++)
                   {
                       comboBox1.Items.Add(xx);
                   }
               }

               InitDevice();
               timer1.Start();
           }

           IBaseFilter smartTeeFilter;
           IPin outPin;
           IPin inPin;
           private void InitDevice()
           {
               try
               {
                   //Set the video size to use for capture and recording
                   videoSize = new Size(827, 505);//1280, 720);

                   //Initialize filter graph and capture graph
                   graph = (IFilterGraph2)new FilterGraph();
                   captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
                   captureGraph.SetFiltergraph(graph);
                   //Create filter for Elgato
                   Guid elgatoGuid = new Guid("39F50F4C-99E1-464A-B6F9-D605B4FB5918");
                   Type comType = Type.GetTypeFromCLSID(elgatoGuid);
                   IBaseFilter  elgatoFilter = (IBaseFilter)Activator.CreateInstance(comType);
                   graph.AddFilter(elgatoFilter, "Elgato Video Capture Filter");

                   //Create smart tee filter, add to graph, connect Elgato's video out to smart tee in
                   smartTeeFilter = (IBaseFilter)new SmartTee();

                   graph.AddFilter(smartTeeFilter, "Smart Tee");
                   outPin = GetPin(elgatoFilter, "Video");
                   inPin = GetPin(smartTeeFilter, "Input");
                   SetAndGetAllAvailableResolution(outPin);
                   graph.Connect(outPin, inPin);


                   //Create video renderer filter, add it to graph, connect smartTee Preview pin to video renderer's input pin
                   IBaseFilter videoRendererFilter = (IBaseFilter)new VideoRenderer();

                   graph.AddFilter(videoRendererFilter, "Video Renderer");
                   outPin = GetPin(smartTeeFilter, "Preview");

                   inPin = GetPin(videoRendererFilter, "Input");
                   graph.Connect(outPin, inPin);

                  // int hr = graph.Connect(outPin, inPin); ;
                  // DsError.ThrowExceptionForHR(hr);

                   captureGraph.SetOutputFileName(MediaSubType.Avi, @"e:\screenshots\test1.mp4", out smartTeeFilter, out sink);

                   //Render stream from video renderer
                   captureGraph.RenderStream(PinCategory.VideoPort, MediaType.Video, videoRendererFilter, null, null);
                   //Set the video preview to be the videoFeed panel
                   IVideoWindow vw = (IVideoWindow)graph;
                   vw.put_Owner(pictureBox1.Handle);
                   vw.put_MessageDrain(this.Handle);
                   vw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren);
                   vw.SetWindowPosition(0, 0, 827, 505);

                   //Start the preview
                   mediaControl = graph as IMediaControl;
                   mediaControl.Run();
               }
               catch (Exception err)
               {
                   error = err.ToString();
               }
           }

            IPin GetPin(IBaseFilter filter, string pinname)
           {
               IEnumPins epins;
               int hr = filter.EnumPins(out epins);
               checkHR(hr, "Can't enumerate pins");
               IntPtr fetched = Marshal.AllocCoTaskMem(4);
               IPin[] pins = new IPin[1];
               while (epins.Next(1, pins, fetched) == 0)
               {
                   PinInfo pinfo;
                   pins[0].QueryPinInfo(out pinfo);
                   bool found = (pinfo.name == pinname);
                   DsUtils.FreePinInfo(pinfo);
                   if (found)
                       return pins[0];
               }
               checkHR(-1, "Pin not found");
               return null;
           }

           public  void checkHR(int hr, string msg)
           {
               if (hr < 0)
               {
                   MessageBox.Show(msg);
                   DsError.ThrowExceptionForHR(hr);
               }



           }

           public void SetAndGetAllAvailableResolution(IPin VideoOutPin)
           {
               int hr = 0;
               IAMStreamConfig streamConfig = (IAMStreamConfig)VideoOutPin;
               AMMediaType searchmedia;
               AMMediaType CorectvidFormat = new AMMediaType();
               IntPtr ptr;
               int piCount, piSize;
               hr = streamConfig.GetNumberOfCapabilities(out piCount, out piSize);
               ptr = Marshal.AllocCoTaskMem(piSize);
               for (int i = 0; i < piCount; i++)
               {
                   hr = streamConfig.GetStreamCaps(i, out searchmedia, ptr);
                   VideoInfoHeader v = new VideoInfoHeader();

                   Marshal.PtrToStructure(searchmedia.formatPtr, v);
                   if (i == 2)// 4
                   {
                       CorectvidFormat = searchmedia;
                   }
               }
               hr = streamConfig.SetFormat(CorectvidFormat);

               IntPtr pmt = IntPtr.Zero;
               AMMediaType mediaType = new AMMediaType();
               IAMStreamConfig streamConfig1 = (IAMStreamConfig)VideoOutPin;
               hr = streamConfig1.GetFormat(out mediaType);
               BitmapInfoHeader bmpih = new BitmapInfoHeader();
               Marshal.PtrToStructure(mediaType.formatPtr, bmpih);
           }
     }
    }

    I tried to use this line to save the video to a video file but the video file on hard disk is 0 KB so I guess it’s a wrong way to do it.
    I also thought somehow to save each frame(bitmap image) from the pictureBox1 to the hard disk or maybe the memory and use ffmpeg to create/build a video file in real time from each saved frame but I can’t get/save the images(frames) from the pictureBox1 for some reason.

    I tried using DrawToBitmap but all the frames(bitmaps on hard disk saved) are empty size 2.24 KB

    captureGraph.SetOutputFileName(MediaSubType.Avi, @"e:\screenshots\test1.mp4", out smartTeeFilter, out sink);

    This is how I tried to get the frames from the pictureBox1

    public static int counter = 0;
           private void timer1_Tick(object sender, EventArgs e)
           {
               counter++;
               Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);
               pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
               bmp.Save(@"e:\screenshots\" + "screenshot" + counter.ToString("D6") + ".bmp");
               bmp.Dispose();
           }
  • Understanding The Dreamcast GD-ROM Layout

    24 mars 2022, par Multimedia Mike — Sega Dreamcast

    I’m finally completing something I set out to comprehend over a decade ago. I wanted to understand how data is actually laid out on a Sega Dreamcast GD-ROM drive. I’m trying to remember why I even still care. There was something about how I wanted to make sure the contents of a set of Dreamcast demo discs was archived for study.


    Lot of 9 volumes of the Official Sega Dreamcast Magazine

    I eventually figured it out. Read on, if you are interested in the technical details. Or, if you would like to examine the fruits of this effort, check out the Dreamcast demo discs that I took apart and uploaded to the Internet Archive.

    If you care to read some geeky technical details of some of the artifacts on these sampler discs, check out this followup post on Dreamcast Finds.

    Motivation
    Why do I still care about this ? Well, see the original charter of this blog above. It’s mostly about studying multimedia formats, as well as the general operation of games and their non-multimedia data formats. It’s also something that has nagged at me ever since I extracted a bunch of Dreamcast discs years ago and tried to understand why the tracks were arranged the way they were, and how I could systematically split the files out of the filesystem. This turns out not to be as easy as it might sound, even if you can get past the obstacle of getting at the raw data.

    CD/CD-ROM Refresher
    As I laid out in my Grand Unified Theory of Compact Disc, every compact disc can be viewed conceptually as a string of sectors, where each sector is 2352 bytes long. The difference among the various CD types (audio CDs, various CD-ROM types) boils down to the format of contents of the 2352-byte sectors. For an audio CD, every sector’s 2352 bytes represents 1/75 of a second of CD-quality audio samples.

    Meanwhile, there are various sector layouts for different CD-ROM modes, useful for storing computer data. This post is most interested in “mode 1/form 1”, which uses 2048 of the 2352 bytes for data, while using the remaining bytes for error detection and correction codes. A filesystem (usually ISO-9660) is overlaid on these 2048-byte sectors in order to create data structures for organizing strings of sectors into files.

    A CD has between 1 and 99 tracks. A pure CD-ROM will have a single data track. Pure audio CDs tend to have numerous audio tracks, usually 1 per song. Mixed CDs are common. For software, this usually manifests as the first track being data and containing an ISO-9660 filesystem, followed by a series of audio tracks, sometimes for in-game music. For audio CDs, there is occasionally a data track at the end of the disc with some extra media types.

    GD-ROM Refresher
    The Dreamcast used optical discs called GD-ROMs, where the GD stands for “gigadisc”. These discs were designed to hold about 1 gigabyte of data, vs. the usual 650-700MB offered by standard CD solutions, while using the same laser unit as is used for CDs. I’m not sure how it achieved this exactly. I always assumed it was some sort of “double density” sector scheme. According to Wikipedia, the drive read the disc at a slower rate which allowed it to read more data (presumably the “pits” vs. “lands” which comprise the surface of an optical disc). This might be equivalent to my theory.

    The GD-ROM discs cannot be read in a standard optical drive. It is necessary to get custom software onto the Dreamcast which will ask the optical hardware to extract the sectors and exfiltrate them off of the unit somehow. There are numerous methods for this. Alternatively, just find rips that are increasingly plentiful around the internet. However, just because you might be able to find the data for a given disc does not mean that you can easily explore the contents.

    Typical Layout Patterns
    Going back to my study of the GD-ROM track layouts, 2 clear patterns emerge :

    All of the game data is packed into track 3 :


    GD-ROM Layout Type 1

    Track 3 has data, the last track has data, and the tracks in between contain standard CD audio :


    GD-ROM Layout Type 2

    Also, the disc is always, always 100% utilized.

    Track 1 always contains an ISO-9660 filesystem and can be read by any standard CD-ROM drive. And it usually has nothing interesting. Track 3 also contains what appears to be an ISO-9660 filesystem. However, if you have a rip of the track and try to mount the image with standard tools, it will not work. In the second layout, the data follows no obvious format.

    Cracking The Filesystem Code
    I figured out quite a few years ago that in the case of the consolidated data track 3, that’s simply a standard ISO-9660 filesystem that would work fine with standard ISO-9660 reading software… if the data track were located beginning at sector 45000. The filesystem data structures contain references to absolute sector numbers. Thus, if it were possible to modify some ISO-9660 software to assume the first sector is 45000, it ought to have no trouble interpreting the data.


    ISO-9660 In A Single Track

    How about the split data track format ? Actually, it works the same way. If all the data were sitting on its original disc, track 3 would have data structures pointing to strings of contiguous sectors (extents) in the final track, and those are the files.

    To express more succinctly : track 3 contains the filesystem root structure and the directory structures, while the final track contains the actual file data. How is the filesystem always 100% full ? Track 3 gets padded out with 0-sectors until the beginning of any audio sectors.


    ISO-9660 Spread Across 2 Tracks

    Why Lay Things Out Like This ?
    Why push the data as far out on the disc as possible ? A reasonable explanation for this would be for read performance. Compact discs operate on Constant Linear Velocity (CLV), vs. Constant Angular Velocity (CAV). The implication of this is that data on the outside of the disc is read faster than data on the inside. I once profiled this characteristic in order to prove it to myself, using both PC CD drives as well as a Dreamcast. By pushing the data to the outer sectors, graphical data gets loaded into RAM faster, and full motion videos, which require a certain minimum bitrate for a good experience, have a better guarantee that playback will be smooth.

    Implications For Repacking
    Once people figured out how to boot burned CDs in the Dreamcast, they had a new problem : Squeeze as much as 1 gigabyte down to around 650 megabytes at the most. It looks like the most straightforward strategy was to simply rework the filesystem to remove the often enormous amount of empty space in track 3.

    My understanding is that another major strategy is to re-encode certain large assets. Full motion video (FMV) assets are a good target here since the prevailing FMV middleware format used on Sega Dreamcast games was Sofdec, which is basically just MPEG-1 video. There is ample opportunity to transcode these files to lower bitrate settings to squeeze some bits (and a lot of visual quality) out of them.

    Further, if you don’t really care about the audio tracks, you could just replace them with brief spurts of silence.

    Making A Tool
    So I could make a tool that would process these collections of files representing a disc. I could also adapt it for various forms that a Dreamcast rip might take (I have found at least 3 so far). I could eventually expand it to handle lots of other disc formats (you know, something like Aaru does these days). And that would have been my modus operandi perhaps 10 or more years ago. And of course, the ambitious tool would have never seen daylight as I got distracted by other ideas.

    I wanted to get a solution up and running as quickly as possible this time. Here was my initial brainstorm : assemble all the tracks into a single, large disc while pretending the audio tracks consist of 2048-byte sectors. In doing so, I ought to be able to use fuseiso to mount the giant image, with a modification to look for the starting sector at a somewhat nonstandard location.

    To achieve the first part I wrote a quick Python script that processed the contents of a GDI file, which was stored alongside the ISO (data) and RAW (audio) track track rips from when I extracted the disc. The GDI is a very matter-of-fact listing of the tracks and their properties, e.g. :

    5
    1 0 4 2048 track01.iso 0
    2 721 0 2352 track02.raw 0
    3 45000 4 2048 track03.iso 0
    4 338449 0 2352 track04.raw 0
    5 349096 4 2048 track05.iso 0
    

    track number / starting sector / track type (4=data, 0=audio) / bytes per sector / filename / ??

    The script skips the first 2 filenames, instead writing 45000 zero sectors in order to simulate the CD-compatible area. Then, for each file, if it’s an ISO, append the data to the final data file ; if it’s audio, compute the number of sectors occupied, and then append that number of 2048-byte zero sectors to the final data file.

    Finally, to interpret the filesystem, I used an old tool that I’ve relied upon for a long time– fuseiso. This is a program that leverages Filesystem in Userspace (FUSE) to mount ISO-9660 filesystems as part of the local filesystem, without needing root privileges. The original source hasn’t been updated for 15 years, but I found a repo that attempts to modernize it slightly. I forked a version which fixes a few build issues.

    Anyway, I just had to update a table to ask it to start looking for the root ISO-9660 filesystem at a different location than normal. Suddenly, after so many years, I was able to freely browse a GD-ROM filesystem directly under Linux !

    Conclusion And Next Steps
    I had to hack the fuseiso3 tool a bit in order to make this work. I don’t think it’s especially valuable to make sure anyone can run with the same modifications since the tool assumes that a GD-ROM rip has been processed through the exact pipeline I described above.

    I have uploaded all of the North American Dreamcast demo discs to archive.org. See this post for a more granular breakdown of what this entails. In the course of this exercise, I also found some European demo discs that could use the same extraction.

    What else ? Should I perform the same extraction experiment for all known Dreamcast games ? Would anyone care ? Maybe if there’s a demand for it.

    Here is a followup on the interesting and weird things I have found on these discs so far.

    The post Understanding The Dreamcast GD-ROM Layout first appeared on Breaking Eggs And Making Omelettes.