Opened 11 years ago

Closed 11 years ago

Last modified 11 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: 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)

FlickAnimation.avi (1.5 MB ) - added by Igor 11 years ago.
out.avi (1.5 MB ) - added by Igor 11 years ago.

Change History (9)

by Igor, 11 years ago

Attachment: FlickAnimation.avi added

by Igor, 11 years ago

Attachment: out.avi added

comment:1 by Igor, 11 years ago

FlickAnimation.avi is the file from which I take frames
out.avi is the file to which I write the frames

comment:2 by Carl Eugen Hoyos, 11 years ago

Analyzed by developer: unset
Priority: importantnormal
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 by Carl Eugen Hoyos, 11 years ago

Component: avcodecundetermined
Resolution: invalid
Status: newclosed

You have to set bits_per_coded_sample:

outStream->codec->bits_per_coded_sample = inStream->codec->bits_per_coded_sample;

in reply to:  3 ; comment:4 by Igor, 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?

in reply to:  4 ; comment:5 by Carl Eugen Hoyos, 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?

in reply to:  5 comment:6 by Igor, 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?

in reply to:  4 comment:7 by Carl Eugen Hoyos, 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

Note: See TracTickets for help on using tickets.