[FFmpeg-trac] #1187(avcodec:new): WMV video does not seek correctly in Windows Media Player on Windows 7

FFmpeg trac at avcodec.org
Tue Apr 10 23:38:10 CEST 2012


#1187: WMV video does not seek correctly in Windows Media Player on Windows 7
---------------------------------+---------------------------------------
             Reporter:  vpi      |                     Type:  defect
               Status:  new      |                 Priority:  normal
            Component:  avcodec  |                  Version:  unspecified
             Keywords:           |               Blocked By:
             Blocking:           |  Reproduced by developer:  0
Analyzed by developer:  0        |
---------------------------------+---------------------------------------
 When reading raw packets from a source WMV video file using the
 av_read_frame() function of the libavcodec library and writing them as-is
 to an output file using the av_write_frame() function, the output file
 plays but does not seek correctly in Windows Media Player 12 on Windows 7.
 There is a noticable delay before playback resumes (presumably Windows
 Media Player is waiting for the next key frame to arrive, which can take
 awhile).

 The output file plays and seeks fine in Windows Media Player 11 on Windows
 XP, and the source file plays and seeks fine in both Windows versions. So
 the issue is in playing libavcodec's output file in Windows Media Player
 12.

 What we want to do is make an exact copy of a video file with specific
 frames blacked out based on given timestamps and durations (is libavfilter
 capable of handling this better? How to hook it up in code?). For
 performance, we only decode/encode the video frames that need to be
 blacked out, the rest of the packets are read/written as-is.  For testing
 purposes though, the following stripped down code is what our current
 logic looks like just to make an unaltered copy of the video (error
 handling removed for brevity):

 {{{
 AVFormatContext *inputFormatCtx;
 AVCodecContext *inputCodecCtx;
 int videoStreamIndex;

 AVCodecContext *outputCodecCtx;
 AVFormatContext *outputFormatCtx;

 avformat_open_input(&inputFormatCtx, inputFileName, NULL, NULL);
 avformat_find_stream_info(inputFormatCtx, NULL);

 for(unsigned int i=0; i < inputFormatCtx->nb_streams; i++)
 {
         if ( inputFormatCtx->streams[i]->codec->codec_type ==
 AVMEDIA_TYPE_VIDEO)
         {
                 inputCodecCtx = inputFormatCtx->streams[i]->codec;
                 videoStreamIndex = i;
                 break;
         }
 }

 AVCodec *pDecoder = avcodec_find_decoder( inputFormatCtx->codec_id );
 avcodec_open2( inputFormatCtx, pDecoder, NULL );

 AVCodec *pEncoder = avcodec_find_encoder( inputCodecCtx->codec_id );

 avformat_alloc_output_context2(&outputFormatCtx, NULL, "asf",
 outputFileName);

 outputFormatCtx->oformat->audio_codec = CODEC_ID_NONE;
 outputFormatCtx->oformat->video_codec = inputCodecCtx->codec_id;
 outputFormatCtx->audio_codec_id = CODEC_ID_NONE;
 outputFormatCtx->video_codec_id = inputCodecCtx->codec_id;
 outputFormatCtx->duration = inputFormatCtx->duration;

 av_dict_copy( &(outputFormatCtx->metadata), inputFormatCtx->metadata, 0);
 av_dict_set( &(outputFormatCtx->metadata), "Author", "VPI", 0 );

 AVStream *stream = avformat_new_stream(outputFormatCtx, pEncoder);
 outputCodecCtx = stream->codec;
 //avcodec_copy_context( outputCodecCtx, inputCodecCtx );
 outputCodecCtx->pix_fmt = inputCodecCtx->pix_fmt;
 outputCodecCtx->time_base.num = 1;
 outputCodecCtx->time_base.den = 1;
 outputCodecCtx->width = inputCodecCtx->width;
 outputCodecCtx->height = inputCodecCtx->height;
 outputCodecCtx->bit_rate = inputCodecCtx->bit_rate;
 outputCodecCtx->bit_rate_tolerance = inputCodecCtx->bit_rate_tolerance;
 outputCodecCtx->qmax = inputCodecCtx->qmax;
 outputCodecCtx->qmin = inputCodecCtx->qmin;

 if ( outputformatCtx->oformat->flags & AVFMT_GLOBALHEADER )
         outputCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;

 avcodec_open2(outputCodecCtx, pEncoder, NULL);
 avio_open( &(outputFormatCtx->pb), outputFormatCtx->filename, URL_WRONLY);
 avformat_write_header( outputFormatCtx, NULL );

 AVPacket packet;
 av_init_packet( &packet );
 do
 {
         if (NULL != packet.data)
         {
                 av_free_packet(&packet);
                 packet.data = NULL;
         }

         if ( av_read_frame( inputFormatCtx, &packet ) < 0 )
                 break;

         if ( packet.stream_index == videoStreamIndex )
                 av_write_frame( outputFormatCtx, &packet );
 }
 while (true);

 av_write_trailer( outputFormatCtx );

 avcodec_close(outputCodecCtx);
 avio_close(outputFormatCtx->pb)
 outputFormatCtx->pb = NULL;
 avformat_free_context( outputFormatCtx );

 avcodec_close(inputCodecCtx);
 avio_close(inputFormatCtx->pb);
 inputFormatCtx->pb = NULL;
 avformat_close_input(&inputFormatCtx);

 if ( NULL != packet.data )
 {
         av_free_packet(&packet);
         packet.data = NULL;
 }
 }}}

 The same issue can be reproduced with the command-line ffmpeg.exe
 application using the following command-line:

 {{{
 ffmpeg -i seeks_fine.wmv -vcodec copy seeks_delayed.wmv
 }}}

 Here is the console output:

 {{{
 ffmpeg version N-36635-gceb0dd9 Copyright (c) 2000-2012 the FFmpeg
 developers
   built on Jan  9 2012 17:42:37 with gcc 4.6.2
   configuration: --disable-static --enable-shared --enable-gpl --enable-
 version3 --disable-w32threads --enable-runtime-cpudetect --enable-avisynth
 --enable-bzlib --enable-frei0r --enable-libopencore-amrnb --enable-
 libopencore-amrwb --enable-libfreetype --enable-libgsm --enable-libmp3lame
 --enable-libopenjpeg --enable-librtmp --enable-libschroedinger --enable-
 libspeex --enable-libtheora --enable-libvo-aacenc --enable-libvo-amrwbenc
 --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs
 --enable-libxvid --enable-zlib
   libavutil      51. 34.100 / 51. 34.100
   libavcodec     53. 54.100 / 53. 54.100
   libavformat    53. 29.100 / 53. 29.100
   libavdevice    53.  4.100 / 53.  4.100
   libavfilter     2. 58.100 /  2. 58.100
   libswscale      2.  1.100 /  2.  1.100
   libswresample   0.  6.100 /  0.  6.100
   libpostproc    51.  2.100 / 51.  2.100
 Input #0, asf, from 'C:\Documents and Settings\rp\Desktop\PCI
 Scrubbing\seeks_fine.wmv':
   Metadata:
     WMFSDKVersion   : 9.00.00.3250
     WMFSDKNeeded    : 0.0.0.0000
     IsVBR           : 1
     VBR Peak        : 1045
     Buffer Average  : 2090
   Duration: 00:00:56.00, start: 0.000000, bitrate: 31 kb/s
     Stream #0:0(eng): Video: wmv1 (WMV1 / 0x31564D57), yuv420p, 1024x768,
 29 kb/s, 1 tbr, 1k tbn, 1k tbc
 Output #0, asf, to 'C:\Documents and Settings\rp\Desktop\PCI
 Scrubbing\seeks_delayed.wmv':
   Metadata:
     WMFSDKVersion   : 9.00.00.3250
     WMFSDKNeeded    : 0.0.0.0000
     IsVBR           : 1
     VBR Peak        : 1045
     Buffer Average  : 2090
     WM/EncodingSettings: Lavf53.29.100
     Stream #0:0(eng): Video: wmv1 (WMV1 / 0x31564D57), yuv420p, 1024x768,
 q=2-31, 29 kb/s, 1k tbn, 1k tbc
 Stream mapping:
   Stream #0:0 -> #0:0 (copy)
 Press [q] to stop, [?] for help
 frame=   57 fps=  0 q=-1.0 Lsize=     214kB time=00:00:56.00 bitrate=
 31.2kbits/s
 video:208kB audio:0kB global headers:0kB muxing overhead 2.746522%
 }}}

 Attached are the two video files.

-- 
Ticket URL: <https://ffmpeg.org/trac/ffmpeg/ticket/1187>
FFmpeg <http://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list