Ticket #1913 (closed defect: invalid)
Why file fails to open when saving frames from one file to other without any encoding/decoding?
| Reported by: | theateist | 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
Change History
comment:1 Changed 6 months ago by theateist
FlickAnimation?.avi is the file from which I take frames
out.avi is the file to which I write the frames
comment:2 Changed 6 months ago by cehoyos
- Analyzed by developer unset
- Priority changed from important to 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.
comment:3 follow-up: ↓ 4 Changed 6 months ago by cehoyos
- Status changed from new to closed
- Resolution set to invalid
- Component changed from avcodec to undetermined
You have to set bits_per_coded_sample:
outStream->codec->bits_per_coded_sample = inStream->codec->bits_per_coded_sample;
comment:4 in reply to: ↑ 3 ; follow-ups: ↓ 5 ↓ 7 Changed 6 months ago by theateist
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?
comment:5 in reply to: ↑ 4 ; follow-up: ↓ 6 Changed 6 months ago by 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?
comment:6 in reply to: ↑ 5 Changed 6 months ago by theateist
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 in reply to: ↑ 4 Changed 6 months ago by cehoyos
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



