Recherche avancée

Médias (91)

Autres articles (36)

  • Keeping control of your media in your hands

    13 avril 2011, par

    The vocabulary used on this site and around MediaSPIP in general, aims to avoid reference to Web 2.0 and the companies that profit from media-sharing.
    While using MediaSPIP, you are invited to avoid using words like "Brand", "Cloud" and "Market".
    MediaSPIP is designed to facilitate the sharing of creative media online, while allowing authors to retain complete control of their work.
    MediaSPIP aims to be accessible to as many people as possible and development is based on expanding the (...)

  • 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" ;

  • Les images

    15 mai 2013

Sur d’autres sites (6187)

  • Decoding mp4/mkv using FFMPEG fails

    14 octobre 2016, par StarShine

    I’m using a project based on the latest FFmpeg git source tree, and linking to the shared DLL’s published by Zeranoe at https://ffmpeg.zeranoe.com/builds/

    The playback code works and loops. It plays back h265 files (raw), mpeg, avi, and mpg files. However as soon as an mp4 or mkv container is specified as input file, regardless of what’s inside,a lot of errors are dumped from the codec. It doesn’t matter if it’s HEVC or h264.

    [h264 @ 00000000xyz] No start code is found
    [h264 @ 00000000xyz] Error splitting the input into NAL units.

    To make everything really strange, ffplay.exe plays these files just fine.

    I realize that I can probably fix this by converting files into a raw format first, but I would like to be able to read and parse mp4 files a they are. Since I am using the pre-build libs of Zeraneo, my guess would be that something was not enabled during the build, but then I would expect ffplay to fail too. Do I need to set a flag in the format_context or codec_context, or provide some sort of filter identifier ?

    Movies that play fine came from http://bbb3d.renderfarming.net/download.html, http://www.w6rz.net/ and http://www.sample-videos.com/

    These work :

    big_buck_bunny_480p_surround-fix.avi
    bigbuckbunny_480x272.h265

    Being a total noob at ffmpeg, please help me understand what is wrong and how to fix it. If the pre-build libs are the culprit, then the second question is if someone has a convenient cmake setup to build this for windows X64 and x32 debug and release targets.

    Here’s the source for initializing ffmpeg for reading

    avdevice_register_all();
    avfilter_register_all();
    av_register_all();
    avformat_network_init();

    The format is parsed as follows :

    m_FormatContext = avformat_alloc_context();
    if (avformat_open_input(&m_FormatContext, file.GetPath().ToString().c_str(), NULL, NULL) != 0)
    {
       //std::cout << "failed to open input" << std::endl;
       success = false;
    }
    // find stream info
    if (success)
    {
       if (avformat_find_stream_info(m_FormatContext, NULL) < 0)
       {
           //std::cout << "failed to get stream info" << std::endl;
           success = false;
       }
    }

    The stream is opened as follows :

    m_VideoStream = avstream;
    m_FormatContext = formatContext;
    if (m_VideoStream)
    {
       m_StreamIndex = m_VideoStream->stream_identifier;
       AVCodecParameters *codecpar = m_VideoStream->codecpar;      
       if (codecpar)
       {
           AVCodecID codec_id = codecpar->codec_id;
           m_Decoder = avcodec_find_decoder(codec_id);
           if (m_Decoder)
           {
               m_CodecContext = avcodec_alloc_context3(m_Decoder);
               if (m_CodecContext)
               {
                   m_CodecContext->width = codecpar->width;                    
                   m_CodecContext->height = codecpar->height;
                   m_VideoSize = i3(codecpar->width, codecpar->height,1);
                   success = 0 == avcodec_open2(m_CodecContext, m_Decoder, NULL);
                   if (success)
                   {
                       if(m_CodecContext)
                       {
                           int size = av_image_get_buffer_size(format, m_CodecContext->width, m_CodecContext->height, 1);      
                           if (size > 0)
                           {
                               av_frame = av_frame_alloc();
                               gl_frame = av_frame_alloc();        
                               uint8_t *internal_buffer = (uint8_t *)av_malloc(size * sizeof(uint8_t));
                               av_image_fill_arrays((uint8_t**)((AVPicture *)gl_frame->data), (int*) ((AVPicture *)gl_frame->linesize), internal_buffer, format, m_CodecContext->width, m_CodecContext->height,1);
                               m_Packet = (AVPacket *)av_malloc(sizeof(AVPacket));
                           }
                       }
                   }
                   if (!success)
                   {
                       avcodec_close(m_CodecContext);
                       avcodec_free_context(&m_CodecContext);
                       m_CodecContext = NULL;
                       m_Decoder = NULL;
                       m_VideoStream = NULL;
                   }
               }
               else
               {
                   m_Decoder = NULL;
                   m_VideoStream = NULL;
               }
           }
       }
    }

    And dedoding on a single thread :

    do
    {
       if (av_read_frame(m_FormatContext, m_Packet) < 0)
       {
           av_packet_unref(m_Packet);
           m_AllPacketsSent = true;
       }
       else
       {
           if (m_Packet->stream_index == m_StreamIndex)
           {                  
               avcodec_send_packet(m_CodecContext, m_Packet);
           }
       }

       int frame_finished = avcodec_receive_frame(m_CodecContext, av_frame);
       if (frame_finished == 0)
       {
           if (!conv_ctx)
           {
               conv_ctx = sws_getContext(m_CodecContext->width,
                   m_CodecContext->height, m_CodecContext->pix_fmt,
                   m_CodecContext->width, m_CodecContext->height, format, SWS_BICUBIC, NULL, NULL, NULL);
           }

           sws_scale(conv_ctx, av_frame->data, av_frame->linesize, 0, m_CodecContext->height, gl_frame->data, gl_frame->linesize);

           switch(format)
           {
               case AV_PIX_FMT_BGR32_1:
               case AV_PIX_FMT_RGB32_1:
               case AV_PIX_FMT_0BGR32:
               case AV_PIX_FMT_0RGB32:
               case AV_PIX_FMT_BGR32:  
               case AV_PIX_FMT_RGB32:              
               {
                   m_CodecContext->bits_per_raw_sample = 32; break;                    
               }
               default:
               {
                   FWASSERT(format == AV_PIX_FMT_RGB32, "The format changed, update the bits per raw sample!"); break;
               }
           }


           size_t bufferSize = m_CodecContext->width * m_CodecContext->height * m_CodecContext->bits_per_raw_sample / 8;
           m_Buffer.Realloc(bufferSize, false,  gl_frame->data[0]);
           m_VideoSize = i3(m_CodecContext->width, m_CodecContext->height,1);
           result = true;
           // sends the image buffer straight to the locked texture here..
           // glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, codec_ctx->width, codec_ctx->height, GL_RGB, GL_UNSIGNED_BYTE, gl_frame->data[0]);
       }

       av_packet_unref(m_Packet);
    } while (m_Packet->stream_index != m_StreamIndex);

    m_FrameDecoded = result;

    Any insight is appreciated !

  • yet another screenshot encoding exercise with ffmpeg - stuck at getting AVFrame from ALT::CImage - VC++

    11 septembre 2013, par sith

    Total AV newbee here - trying to learn the ropes on using FFMpeg functions to encode movies. On searching for tutorials I found a few similar questions that I have linked here for reference :

    Encoding a screenshot into a video using FFMPEG

    [Libav-user] Encoding a screenshot into a video using FFMPEG

    Save bitmap to video (libavcodec ffmpeg)

    When converting from RGB to YUV using ffmpeg the video file the color is spread why ?

    How to convert RGB from YUV420p for ffmpeg encoder ?

    Encode bmp sequence with libavcodec...Help !

    Not able to encode image with ffmpeg

    For my setup FFMPEG is on VS12 - VC++ with MFC on win7.

    With the help of above samples, I am able to get "some" output from the encoder, but I am not sure in what format or state the output has been encoded. Neither VLC nor WMP can play this file. It does not even seem to recognize the metadata in the file to display the FPS or video length. What would normally cause that ? Also any pointers on what could be going wrong and how to approach fixing the problems would be great. [1]

    Here is the flow of my code :

    Step1 : capture desktop on to a CImg :

    int W=GetSystemMetrics(SM_CXSCREEN), H=GetSystemMetrics(SM_CYSCREEN), bpp=24;
    CImage cImg; cImg.Create(W,H,bpp)
    HDC hDC = cImg.GetDC();
    CWindowDC winDC(GetDesktopWindow());

    BitBlt(hDC, 0,0, rez.W(), rez.H(), winDC.m_hDC, 0, 0, SRCCOPY);

    At this point I am able to dump a screen shot into a bmp file -
    using cImg.Save( _T("test.bmp"), Gdiplus::ImageFormatBMP) ;

    Step2 : Extract the BMP bits from the CImg.

    HBITMAP hBitmap = (HBITMAP)cImg;
    HDC memDC = CreateCompatibleDC(NULL);
    SelectObject( memDC, hBitmap );

    BITMAPINFO bmi; // initialized bmi with {W,-H, plane=1, bitCount=24, comp=BI_RGB, size=W*H*3 }
    << removed bmi init code for conciseness. >>>

    BYTE *rgb24Data = new BYTE[W*H*3]; // 3 for 24bpp. 4 for 32...
    int ret = GetDIBits(memDC, hBitmap, 0, H, rgb24Data, &bmi, DIB_RGB_COLORS);

    At this point I faithfully believe rgb24Data points to pixel data :) - copied out of the cImg bitmap

    Step 3 : next I try to create an AV frame with the rgb24Data got from this CImg. Also this is where I have a massive knowledge gap. I am going to try and recover

    // setup the codecs and contexts here as per mohM's post

    AVCodec *currCodec = avcodec_find_encoder(CODEC_ID_MPEG4);

    AVCodecContext *codeCtxt = avcodec_alloc_context();  // init this with bate=400k, W, H,
    << removed codeCtxt init code for conciseness. >>>   //  time base 1/25, gop=10, max_b=1, fmt=YUV420

    avcodec_open(codeCtxt, currCodec);

    SwsContext *currSWSCtxt = sws_getContext( W, H, AV_PIX_FMT_RGB24, // FROM
                                             W, H, AV_PIX_FMT_YUV420P, // TO
                                             SWS_FAST_BILINEAR,
                                             NULL, NULL, NULL);

    // allocate and fill AVFrame
    int numBytes = avpicture_get_size(PIX_FMT_YUV420P, W, H);
    uint8_t *buffer=new uint8_t[numBytes];
    AVFrame *avFrame = avcodec_alloc_frame();
    avpicture_fill( (AVPicture*)avFrame, buffer, PIX_FMT_YUV420P, W, H );

    Step 4 : transform the data frame into YUV420P as we fill the frame.

    uint8_t * inData[1] = { rgb24Data };
    int inLinesize[1] = { 3*W }; // RGB stride
    sws_scale( currSWSCtxt, inData, inLinesize, 0, H,
              avFrame->data, avFrame->linesize);

    step 5 encode the frame and write out the output buffer into a file.

    int out_size = avcodec_encode_video( codeCtxt,
                                        outBuf,
                                        outBufSize,
                                        avFrame );

    fwrite(outBuf, 1, outBufSize, outFile );

    finally I close the file off with [0x00 0x00 0x01 0xb7]

    The first hint of things gone haywire is that for a 50 screens of 1920X1080 at 24bpp encoded at 25fps gives me a 507MB unplayable-mpeg file.

    As mentioned earlier, neither VLC nor WMP can play this file nor they even recognize the metadata in the file to display the FPS or video length. What would normally cause that ? Also any pointers on what could be going wrong and how to approach fixing the problems would be great. [2]

    Any guidance is much appreciated.

  • Trimmed a video with ffmpeg ; looks fine on a Mac, but audio/video are 3 seconds out of sync with Windows default player. Huh ?

    12 avril 2021, par kaltorak

    I've got a video which looks and sounds right when I play it in Windows or on a Mac.
    
I trimmed it with ffmpeg.
    
The resulting file

    


      

    • plays fine on a Mac with QuickTime
    • 


    • throws an error on Windows QuickTime (Error -2041 : an invalid sample description was found in the movie (myfile.trimmed.mp4))
    • 


    • plays with Win10's default player (Movies and TV ?), but with the audio lagging nearly 3 seconds behind the video (as determined by me counting Mississippis, nothing more precise than that.)
    • 


    


    My original file :

    


    ffprobe -hide_banner myfile.mpg
[h264 @ 00000253d2d762c0] Increasing reorder buffer to 2
[mpegts @ 00000253d2d6fe00] PES packet size mismatch
[mpegts @ 00000253d2d6fe00] Packet corrupt (stream = 1, dts = 8467425232).
[mpegts @ 00000253d2d6fe00] Could not find codec parameters for stream 2 (Unknown: none ([151][0][0][0] / 0x0097)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mpegts, from 'myfile.mpg':
  Duration: 00:30:00.63, start: 92282.982578, bitrate: 6249 kb/s
  Program 1
    Stream #0:0[0x1aab]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, progressive), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc
    Stream #0:1[0x1abf]: Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, 5.1(side), fltp, 384 kb/s
    Stream #0:2[0x1ac1]: Unknown: none ([151][0][0][0] / 0x0097)
Unsupported codec with id 0 for input stream 2


    


    Stuff I notice :

    


      

    • The mpg container shouldn't hold h264 video. That messed me up, but remuxing to an mp4 container during the trimming step seemed to make it OK.
    • 


    • The start time isn't anywhere close to zero... but I don't think there's anything wrong with that.
    • 


    • The audio and video are in sync as I watch in a player, but the file contains audio starting nearly 1 second before the video. The first audio packet has pkt_pts_time=92282.982578 (matching the start reported by ffprobe, above), while the first video packet has pkt_pts_time=92283.926411
    • 


    


    So I trim it, like so...

    


    ffmpeg -hide_banner -ss 00:17:24 -i myfile.mpg -t 00:02:40 -c copy myfile.trimmed.mp4
[h264 @ 000002d5d73f4040] Increasing reorder buffer to 2
[mpegts @ 000002d5d73edbc0] PES packet size mismatch
[mpegts @ 000002d5d73edbc0] Packet corrupt (stream = 1, dts = 8467425232).
[mpegts @ 000002d5d73edbc0] Could not find codec parameters for stream 2 (Unknown: none ([151][0][0][0] / 0x0097)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 000002d5d73edbc0] PES packet size mismatch
[mpegts @ 000002d5d73edbc0] Packet corrupt (stream = 1, dts = 8467425232).
Input #0, mpegts, from 'myfile.mpg':
  Duration: 00:30:00.63, start: 92282.982578, bitrate: 6249 kb/s
  Program 1
    Stream #0:0[0x1aab]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, progressive), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc
    Stream #0:1[0x1abf]: Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, 5.1(side), fltp, 384 kb/s
    Stream #0:2[0x1ac1]: Unknown: none ([151][0][0][0] / 0x0097)
[mp4 @ 000002d5d7e90540] track 1: codec frame size is not set
Output #0, mp4, to 'myfile.trimmed.mp4':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, progressive), 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 59.94 fps, 59.94 tbr, 90k tbn, 90k tbc
    Stream #0:1: Audio: ac3 (ac-3 / 0x332D6361), 48000 Hz, 5.1(side), fltp, 384 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 9570 fps=0.0 q=-1.0 Lsize=  122587kB time=00:02:39.99 bitrate=6276.6kbits/s speed= 462x
video:114772kB audio:7545kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.220873%


    


    ffprobe -hide_banner myfile.trimmed.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'myfile.trimmed.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.45.100
  Duration: 00:02:40.96, start: 0.000000, bitrate: 6239 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 5890 kb/s, 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: ac3 (ac-3 / 0x332D6361), 48000 Hz, 5.1(side), fltp, 384 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
    Side data:
      audio service type: main


    


    ...and i get the file that plays fine on a Mac, but not on Windows's default player.
The start time as reported by ffprobe is 0 (above), so that must've been cleaned up by either the trimming or the remuxing. When I look at frames, the first audio packet has a pkt_pts_time=0.000000, and the first video packet has a pkt_pts_time=0.452000.

    


    Where do I go next ?