Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#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 (2)

FlickAnimation.avi (1.5 MB) - added by theateist 5 years ago.
out.avi (1.5 MB) - added by theateist 5 years ago.

Change History (9)

Changed 5 years ago by theateist

Changed 5 years ago by theateist

comment:1 Changed 5 years 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 5 years 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: Changed 5 years ago by cehoyos

  • Component changed from avcodec to undetermined
  • Resolution set to invalid
  • Status changed from new to closed

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: Changed 5 years 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: Changed 5 years 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 5 years 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 5 years 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

Note: See TracTickets for help on using tickets.