none
[UWP]Video Codecs supported in UWP RRS feed

  • Question

  • The UWP framework includes a media namespace and other APIs to play, edit, and save audio and video.  I've designed and developed a nice media editing tool and was able to play, edit, and save some audio and video files during development.  However, now I'm going through and validating the default Codes installed with Windows 10 which are listed in the following web page: Supported Codecs and the Subtypes included in the Media Encoding Subtypes listed in the following web page: MediaEncodingSubtypes Class.

    I'm encountering problems that I hope someone can shed some light on.

    1. There is a Media Encoding Subtype of Nv12, but the Codec isn't listed and my internet search was vague about the Codec itself.  My best guess is that it's version 12 of the Native Video format developed through collaboration of many video camera manufacturers in order to standardize video output.  I was able to play, edit, and save NV12 video in an AVI Container, but since it's not listed on the Supported Codecs page I'm clueless as to which other Containers the default Codec supports.
    2. There's a Media Encoding Subtype HEVC and a CreateHevc method which is also not listed in the Supported Codecs page.  I get no errors when I save a video with that subtype; however, when I try to play it I get an Invalid Stream error.
    3. The Supported Codecs page indicates support for a AVCHD Container; however, when I select it I get an error indicating that it's an invalid subtype...I've tried several different variations such as "AVC HD", "AVC-HD", etc. but nothing has worked and there's no enum for Containers.
    4. Some of the Codecs only Decode, so in order to test them I need some video samples...specifically, H.265 in a fMP4 and MKV Container, H.263 in an AVI Container; plus VC-1, WMV9 Screen, DV, and Motion JPEG in any Container.


    Steven Edward Wood Computer Engineer

    Wednesday, June 19, 2019 2:36 PM

All replies

  • Hi,

    For question 1,2 and 3, could you please share me a sample that you used to test with? We can't tell until we could get the same behavior like you. It would be better if you could offer us a sample about this so that we could confirm the behavior you said. Another thing is could you please provide us the reproduce steps and some environment information like OS version, target version?

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, June 20, 2019 6:31 AM
    Moderator
  • Hi Roy...sure...no problem.

    Step 1: Create a new UWP app using the default blank app template.

    Step 2: Remove the Grid control and add the following:

     <Canvas>
      <AppBarButton Content="H264OK" Click="H264OK_Click" Canvas.Top="0"/>
      <AppBarButton Content="Problem1" Click="Problem1_Click" Canvas.Top="50" />
      <AppBarButton Content="Problem2" Click="Problem2_Click" Canvas.Top="100" />
      <AppBarButton Content="Problem3" Click="Problem3_Click" Canvas.Top="150" />
     </Canvas>
    

    Step 3: Add the following to the Class:

      /// <summary>
      /// Based on examples in documentation at https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/transcode-media-files
      /// This method opens a Video file formatted using the H264 Codec with Container subtype MPEG4
      /// Then transcodes it to a Video file formatted using the H264 Codec with Container subtype 3GP
      /// by only changing the profile.Container.Subtype to 3GP (and file extension to .3gp)
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private async void H264OK_Click(object sender, RoutedEventArgs e)
      {
       var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
       openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
       openPicker.FileTypeFilter.Add(".mp4");
       Windows.Storage.StorageFile source = await openPicker.PickSingleFileAsync();
    
       var savePicker = new Windows.Storage.Pickers.FileSavePicker();
       savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
       savePicker.DefaultFileExtension = ".3gp";
       savePicker.SuggestedFileName = "New Video";
       savePicker.FileTypeChoices.Add("3rd Generation Partner Project", new string[] { ".3GP" });
       Windows.Storage.StorageFile destination = await savePicker.PickSaveFileAsync();
    
       Windows.Media.MediaProperties.MediaEncodingProfile profile = await Windows.Media.MediaProperties.MediaEncodingProfile.CreateFromFileAsync(source);
    
       //The only change in the profile is Container subtype 3GP:
       profile.Container.Subtype = "3GP";
    
       Windows.Media.Transcoding.MediaTranscoder transcoder = new Windows.Media.Transcoding.MediaTranscoder();
       Windows.Media.Transcoding.PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(source, destination, profile);
       if (prepareOp.CanTranscode)
       {
        var transcodeOp = prepareOp.TranscodeAsync();
    
        transcodeOp.Progress += new AsyncActionProgressHandler<double>(TranscodeProgress);
        transcodeOp.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
       }
       else
       {
        switch (prepareOp.FailureReason)
        {
         case Windows.Media.Transcoding.TranscodeFailureReason.CodecNotFound:
          System.Diagnostics.Debug.WriteLine("Codec not found.");
          break;
         case Windows.Media.Transcoding.TranscodeFailureReason.InvalidProfile:
          System.Diagnostics.Debug.WriteLine("Invalid profile.");
          break;
         default:
          System.Diagnostics.Debug.WriteLine("Unknown failure.");
          break;
        }
       }
      }
    
      /// <summary>
      /// Based on examples in documentation at https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/transcode-media-files
      /// This method opens a Video file formatted using the NV12 Codec with Container subtype AVI
      /// Then tries to transcode it to a Video file formatted using the NV12 Codec with Container subtype MPEG4
      /// by only changing the profile.Container.Subtype to MPEG4 (and file extension to .mp4)
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private async void Problem1_Click(object sender, RoutedEventArgs e)
      {
       var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
       openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
       openPicker.FileTypeFilter.Add(".avi");
       Windows.Storage.StorageFile source = await openPicker.PickSingleFileAsync();
    
       var savePicker = new Windows.Storage.Pickers.FileSavePicker();
       savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
       savePicker.DefaultFileExtension = ".mp4";
       savePicker.SuggestedFileName = "New Video";
       savePicker.FileTypeChoices.Add("MPEG4", new string[] { ".mp4" });
       Windows.Storage.StorageFile destination = await savePicker.PickSaveFileAsync();
    
       Windows.Media.MediaProperties.MediaEncodingProfile profile = await Windows.Media.MediaProperties.MediaEncodingProfile.CreateFromFileAsync(source);
    
       //The only change in the profile is Container subtype MPEG4:
       profile.Container.Subtype = "MPEG4";
       
       Windows.Media.Transcoding.MediaTranscoder transcoder = new Windows.Media.Transcoding.MediaTranscoder();
       Windows.Media.Transcoding.PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(source, destination, profile);
       if (prepareOp.CanTranscode)
       {
        var transcodeOp = prepareOp.TranscodeAsync();
        transcodeOp.Progress += new AsyncActionProgressHandler<double>(TranscodeProgress);
        transcodeOp.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
       }
       else
       {
        switch (prepareOp.FailureReason)
        {
         case Windows.Media.Transcoding.TranscodeFailureReason.CodecNotFound:
          System.Diagnostics.Debug.WriteLine("Codec not found.");
          break;
         case Windows.Media.Transcoding.TranscodeFailureReason.InvalidProfile:
          System.Diagnostics.Debug.WriteLine("Invalid profile.");
          break;
         default:
          System.Diagnostics.Debug.WriteLine("Unknown failure.");
          break;
        }
       }
      }
    
      /// <summary>
      /// Based on examples in documentation at https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/transcode-media-files
      /// This method opens a Video file formatted using the H264 Codec with Container subtype MPEG4
      /// Then transcodes it to a Video file formatted using the HEVC Codec with Container subtype MPEG4
      /// by creating the profile using the CreateHevc method.
      /// The transcode is successful; however, opening the file in Movies & TV app results in an error of "Missing Codec" This item was encoded in a format that's not supported
      /// but then it plays just the audio track.
      /// Inpecting the file contents indicates that it is a valid MPEG4 Container with a valid HEVC Codec, but trying to play it results in a
      /// Error: "Video could not be decoded exception" or "Invalid Stream State" depending on what you use to try to play it.
      /// However, playing it with Windows Media Player throws no error but indicates that there's no video then plays just the audio track.
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private async void Problem2_Click(object sender, RoutedEventArgs e)
      {
       var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
       openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
       openPicker.FileTypeFilter.Add(".mp4");
       Windows.Storage.StorageFile source = await openPicker.PickSingleFileAsync();
    
       var savePicker = new Windows.Storage.Pickers.FileSavePicker();
       savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
       savePicker.DefaultFileExtension = ".mp4";
       savePicker.SuggestedFileName = "New Video";
       savePicker.FileTypeChoices.Add("MPEG4", new string[] { ".mp4" });
       Windows.Storage.StorageFile destination = await savePicker.PickSaveFileAsync();
    
       Windows.Media.MediaProperties.MediaEncodingProfile profile = await Windows.Media.MediaProperties.MediaEncodingProfile.CreateFromFileAsync(source);
    
       //Use the CreateHevc method to create a H265 profile:
       profile = Windows.Media.MediaProperties.MediaEncodingProfile.CreateHevc(Windows.Media.MediaProperties.VideoEncodingQuality.HD1080p);
    
       Windows.Media.Transcoding.MediaTranscoder transcoder = new Windows.Media.Transcoding.MediaTranscoder();
       Windows.Media.Transcoding.PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(source, destination, profile);
       if (prepareOp.CanTranscode)
       {
        var transcodeOp = prepareOp.TranscodeAsync();
        transcodeOp.Progress += new AsyncActionProgressHandler<double>(TranscodeProgress);
        transcodeOp.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
       }
       else
       {
        switch (prepareOp.FailureReason)
        {
         case Windows.Media.Transcoding.TranscodeFailureReason.CodecNotFound:
          System.Diagnostics.Debug.WriteLine("Codec not found.");
          break;
         case Windows.Media.Transcoding.TranscodeFailureReason.InvalidProfile:
          System.Diagnostics.Debug.WriteLine("Invalid profile.");
          break;
         default:
          System.Diagnostics.Debug.WriteLine("Unknown failure.");
          break;
        }
       }
      }
    
      /// <summary>
      /// Based on examples in documentation at https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/transcode-media-files
      /// This method opens a Video file formatted using the H264 Codec with Container subtype MPEG4
      /// Then transcodes it to a Video file formatted using the H264 Codec with Container subtype AVCHD
      /// by only changing the profile.Container.Subtype to AVCHD (and file extension to .avc)
      /// Exception of "Value does not fall within the expected range" is thrown at profile.Container.Subtype = "AVCHD";
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private async void Problem3_Click(object sender, RoutedEventArgs e)
      {
       var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
       openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
       openPicker.FileTypeFilter.Add(".mp4");
       Windows.Storage.StorageFile source = await openPicker.PickSingleFileAsync();
    
       var savePicker = new Windows.Storage.Pickers.FileSavePicker();
       savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
       savePicker.DefaultFileExtension = ".avc";
       savePicker.SuggestedFileName = "New Video";
       savePicker.FileTypeChoices.Add("AVCHD", new string[] { ".avc" });
       Windows.Storage.StorageFile destination = await savePicker.PickSaveFileAsync();
    
       Windows.Media.MediaProperties.MediaEncodingProfile profile = await Windows.Media.MediaProperties.MediaEncodingProfile.CreateFromFileAsync(source);
    
       //The only change in the profile is Container subtype AVCHD:
       profile.Container.Subtype = "AVCHD";
    
       Windows.Media.Transcoding.MediaTranscoder transcoder = new Windows.Media.Transcoding.MediaTranscoder();
       Windows.Media.Transcoding.PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(source, destination, profile);
       if (prepareOp.CanTranscode)
       {
        var transcodeOp = prepareOp.TranscodeAsync();
    
        transcodeOp.Progress += new AsyncActionProgressHandler<double>(TranscodeProgress);
        transcodeOp.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
       }
       else
       {
        switch (prepareOp.FailureReason)
        {
         case Windows.Media.Transcoding.TranscodeFailureReason.CodecNotFound:
          System.Diagnostics.Debug.WriteLine("Codec not found.");
          break;
         case Windows.Media.Transcoding.TranscodeFailureReason.InvalidProfile:
          System.Diagnostics.Debug.WriteLine("Invalid profile.");
          break;
         default:
          System.Diagnostics.Debug.WriteLine("Unknown failure.");
          break;
        }
       }
      }
    
      void TranscodeProgress(IAsyncActionWithProgress<double> asyncInfo, double percent)
      {
       // Display or handle progress info.
      }
    
      void TranscodeComplete(IAsyncActionWithProgress<double> asyncInfo, AsyncStatus status)
      {
       //asyncInfo.GetResults(); This causes an exception...the result was already added to the ErrorCode property.
       if (asyncInfo.Status == AsyncStatus.Completed)
       {
        System.Diagnostics.Debug.WriteLine("Transcode Completed.");
       }
       else if (asyncInfo.Status == AsyncStatus.Canceled)
       {
        System.Diagnostics.Debug.WriteLine("Transcode Canceled.");
       }
       else
       {
        System.Diagnostics.Debug.WriteLine("Transcode Failed.");
        System.Diagnostics.Debug.WriteLine(asyncInfo.ErrorCode);
        // The error code is an exception instance with message: System.Exception: Exception from HRESULT: 0xC00D4A45
        // I think this HRESULT translates to "Value does not fall within the expected range."
        // So...what are the expected ranges.
       }
      }
    
     

    Step 4: Verify that your project works by running it and clicking on the H264OK button. Watch the Output for the Debug messages.

    Step 5: Click the Problem1, Problem2, and Problem3 buttons for the samples you asked for questions 1, 2, and 3 respectively.

    Note: I did figure out that HEVC is documented as the H265 Codec, but the Problem2 sample does show that the UWP framework fails to properly encode a file using the HEVC Codec in a MEG4 Container when the documentation says that it should and the transcode process actually succeeds.  Strangely, the file actual does eventually play but only the audio track.


    Steven Edward Wood Computer Engineer

    Friday, June 21, 2019 4:23 AM
  • Hi,

    Thank you for the sample. I'm asking another engineer to take a look at this. There might be some time delay.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, June 21, 2019 8:48 AM
    Moderator
  • Hi Steven,

    I'm not sure that I see any questions here. All I can really do is comment on your bullets above and hope for the best. 

    1. NV12 is a video format / transport format and not really a "codec". It is an uncompressed format that is used as a universal video data exchange on the Windows platform. It is not intended to be saved directly to a container file, although it is theoretically possible to do so. 
    2. HEVC = h.265 and is listed on the supported codecs page. Microsoft does not supply an h.265 encoder or decoder by default. You will need to confirm that you have the necessary codecs installed before this format will work as expected. 
    3. Unfortunately, I'm not sure that I understand your problem. AVCHD is part of the h.264 specification. So if you have chosen h.264 as your codec you will be using the AVCHD file container. How are you attempting to select the AVCHD container?
    4. Unfortunately, I'm not sure what you are asking. If you want to support all of those file formats you will need to find sample content that supports the various formats to test your app. You should be able to find samples around the web. However, keep in mind that not all encoders are the same and some may not be compatible with the Windows decoders. This is particularly troublesome when trying to support MKV and MPEG-2 TS as these formats do not have good specifications.

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, June 24, 2019 11:17 PM
    Owner