#1913 closed defect (invalid)
Why file fails to open when saving frames from one file to other without any encoding/decoding?
Reported by: | Igor | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | undetermined |
Version: | unspecified | Keywords: | |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
I started learning ffmpeg and for practice I use the following code to just save all frames from inFileName to outFileName. At first sight it success but the file fails to open with WindowsMediaPlayer. VLC Player opens it but I see strange colorful stripes at the bottom. In addition, the pix_fmt of inFileName is pal8 and of the outFileName is changed to bgr24, although I construct outFormatCtx the same as inFormatCtx.
What is the problem and why I get different pix_fmt in out file?
Thanks
const char* inFileName = "C:\\FlickAnimation.avi"; const char* outFileName = "c:\\out.avi"; const char* outFileType = "avi"; av_register_all(); AVFormatContext* inFormatCtx = NULL; int err = avformat_open_input(&inFormatCtx, inFileName, NULL, NULL); if (err < 0) exit(1); err = av_find_stream_info(inFormatCtx); if (err < 0) exit(1); // Find video stream int videoStreamIndex = -1; for (unsigned int i = 0; i < inFormatCtx->nb_streams; ++i) { if (inFormatCtx->streams[i] && inFormatCtx->streams[i]->codec && inFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoStreamIndex = i; break; } } if (videoStreamIndex == -1) exit(1); AVOutputFormat* outFormat = av_guess_format(outFileType, NULL, NULL); if (!outFormat) exit(1); AVFormatContext* outFormatCtx = NULL; err = avformat_alloc_output_context2(&outFormatCtx, outFormat, NULL, NULL); if (err < 0 || !outFormatCtx) exit(1); err = avio_open(&outFormatCtx->pb, outFileName, AVIO_FLAG_WRITE); if (err < 0) exit(1); // Create and initiate output stream AVStream* outStream = av_new_stream(outFormatCtx, 0); AVStream const* const inStream = inFormatCtx->streams[videoStreamIndex]; AVCodec* codec = NULL; avcodec_get_context_defaults3(outStream->codec, inStream->codec->codec); outStream->codec->coder_type = AVMEDIA_TYPE_VIDEO; outStream->codec->sample_aspect_ratio = outStream->sample_aspect_ratio = inStream->sample_aspect_ratio; outStream->disposition = inStream->disposition; outStream->codec->bits_per_raw_sample = inStream->codec->bits_per_raw_sample; outStream->codec->chroma_sample_location = inStream->codec->chroma_sample_location; outStream->codec->codec_id = inStream->codec->codec_id; outStream->codec->codec_type = inStream->codec->codec_type; outStream->codec->bit_rate = inStream->codec->bit_rate; outStream->codec->rc_max_rate = inStream->codec->rc_max_rate; outStream->codec->rc_buffer_size = inStream->codec->rc_buffer_size; if (!outStream->codec->codec_tag) { if (! outFormatCtx->oformat->codec_tag || av_codec_get_id (outFormatCtx->oformat->codec_tag, inStream->codec->codec_tag) == outStream->codec->codec_id || av_codec_get_tag(outFormatCtx->oformat->codec_tag, inStream->codec->codec_id) <= 0) outStream->codec->codec_tag = inStream->codec->codec_tag; } size_t extra_size_alloc = (inStream->codec->extradata_size > 0) ? (inStream->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE) : 0; if (extra_size_alloc) { outStream->codec->extradata = (uint8_t*)av_malloc(extra_size_alloc); memcpy(outStream->codec->extradata, inStream->codec->extradata, inStream->codec->extradata_size); } outStream->codec->extradata_size = inStream->codec->extradata_size; AVRational input_time_base = inStream->time_base; AVRational frameRate; frameRate.num = inStream->r_frame_rate.num; frameRate.den = inStream->r_frame_rate.den; outStream->r_frame_rate = frameRate; outStream->codec->time_base = inStream->codec->time_base; outStream->codec->pix_fmt = inStream->codec->pix_fmt; outStream->codec->width = inStream->codec->width; outStream->codec->height = inStream->codec->height; outStream->codec->has_b_frames = inStream->codec->has_b_frames; if (!outStream->codec->sample_aspect_ratio.num) { AVRational r0 = {0, 1}; outStream->codec->sample_aspect_ratio = outStream->sample_aspect_ratio = inStream->sample_aspect_ratio.num ? inStream->sample_aspect_ratio : inStream->codec->sample_aspect_ratio.num ? inStream->codec->sample_aspect_ratio : r0; } avformat_write_header(outFormatCtx, NULL); AVPacket packet; while(av_read_frame(inFormatCtx, &packet)>=0) { if (packet.stream_index == videoStreamIndex) { err = av_interleaved_write_frame(outFormatCtx, &packet); if (err < 0) exit(1); } av_free_packet(&packet); } av_write_trailer(outFormatCtx); avio_close(outFormatCtx->pb); avformat_free_context(outFormatCtx); av_close_input_file(inFormatCtx);
d
Attachments (2)
Change History (9)
by , 11 years ago
Attachment: | FlickAnimation.avi added |
---|
by , 11 years ago
comment:1 by , 11 years ago
comment:2 by , 11 years ago
Analyzed by developer: | unset |
---|---|
Priority: | important → normal |
Reproduced by developer: | unset |
Your code does not compile.
Please consider that this is a bug tracker, not a support forum, see http://ffmpeg.org/contact.html for support mailing lists.
follow-up: 4 comment:3 by , 11 years ago
Component: | avcodec → undetermined |
---|---|
Resolution: | → invalid |
Status: | new → closed |
You have to set bits_per_coded_sample:
outStream->codec->bits_per_coded_sample = inStream->codec->bits_per_coded_sample;
follow-ups: 5 7 comment:4 by , 11 years ago
Replying to cehoyos:
You have to set bits_per_coded_sample:
outStream->codec->bits_per_coded_sample = inStream->codec->bits_per_coded_sample;
I'm sorry I didn't understood what kind of questions I can ask in bug-tracker?
Regarding my question I added
outStream->codec->bits_per_coded_sample = inStream->codec->bits_per_coded_sample;
and now both files(in and out) have pix_fmt=pal8, but WindowsMediaPlayer still fails to open the file and VLCPlayer now shows black screen without stripes as previously. Do you have any suggestion?
follow-up: 6 comment:5 by , 11 years ago
Replying to theateist:
Regarding my question I added
outStream->codec->bits_per_coded_sample = inStream->codec->bits_per_coded_sample;and now both files(in and out) have pix_fmt=pal8, but WindowsMediaPlayer still fails to open the file
Does it work if you do the remuxing with ffmpeg (the application)?
and VLCPlayer now shows black screen without stripes as previously.
Do you have any indication that vlc supports the original file?
comment:6 by , 11 years ago
Replying to cehoyos:
Replying to theateist:
Regarding my question I added
outStream->codec->bits_per_coded_sample = inStream->codec->bits_per_coded_sample;and now both files(in and out) have pix_fmt=pal8, but WindowsMediaPlayer still fails to open the file
Does it work if you do the remuxing with ffmpeg (the application)?
and VLCPlayer now shows black screen without stripes as previously.
Do you have any indication that vlc supports the original file?
My mistake, I didn't tried opening FlickAnimation.avi with vlc before, but only with WMediaPlayer. Vlc opens FlickAnimation.avi and plays it, but the screen is black. The same is for out.avi file(after adding bits_per_coded_sample). But why WindowsMediaPlayer doesn't even success to open the out.avi file?
Furthermore, I tried to use the same code for mp4 file. All success, but it plays only 90ms instead of 7 seconds. I checked the fps of the output file and it shows 533fps instead 25fps as in original mp4. Why?
comment:7 by , 11 years ago
Replying to theateist:
I'm sorry I didn't understood what kind of questions I can ask in bug-tracker?
As a very large simplification, do not ask questions on this bug tracker (use it only to report bugs).
To find out where to ask questions, please read https://ffmpeg.org/contact.html
FlickAnimation.avi is the file from which I take frames
out.avi is the file to which I write the frames