Jump to content

  • Log In with Google      Sign In   
  • Create Account

FFMPEG and av_open_input_stream


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 arthur__   Members   -  Reputation: 102

Like
0Likes
Like

Posted 13 March 2012 - 12:06 PM

Hello,

I try to read a mpeg2 video from a stream with ffmpeg library. In my first tests, I tried to read from a byte buffer, but now I read directly from a file (in my ReadPacket function) in order to be sure it's right data.
I tried many way to do that, but av_open_input_stream function return always -1.
I post my code here and hope someone could help me ! If someone have a full code to do that, i''ll be happy to see it. Thanks.

av_log_set_level(AV_LOG_VERBOSE);
avcodec_init();
av_register_all();
avcodec_register_all();

pFormatCtx = avformat_alloc_context();
if (!pFormatCtx)
{
return -1;
}

FILE* f = fopen("D:\\projets\\test_data\\video\\video_ts.mpg", "rb");

int bioBufferSize = 8000;
unsigned char *bioBuffer = (unsigned char *)av_malloc(bioBufferSize +  FF_INPUT_BUFFER_PADDING_SIZE);
ByteIOContext *bioContext = new ByteIOContext();
int ret = init_put_byte(bioContext, bioBuffer, bioBufferSize, 0, (void *)f, readPackets, NULL, seekPackets);

AVFormatParameters params, *ap = &params;
memset(ap, 0, sizeof(*ap));
ap->prealloced_context = 1

//pFormatCtx->video_codec_id = findCodecOrDie("mpeg2video", AVMEDIA_TYPE_VIDEO, 0, avcodecOpts[AVMEDIA_TYPE_VIDEO]->strict_std_compliance);
//pFormatCtx->flags |= AVFMT_FLAG_NONBLOCK;
AVInputFormat *inputFormat = av_find_input_format("mpegts");
//pFormatCtx->iformat = inputFormat;

ret = av_open_input_stream(&pFormatCtx, bioContext, "stream", inputFormat, ap);

av_close_input_stream(pFormatCtx);
av_free(bioBuffer);
delete bioContext;
fclose(f);

[...]

And my readPacket func :

static int readPackets(void *opaque, uint8_t *buf, int buf_size)
{
	FILE* f = (FILE *)opaque;
	int read = fread(buf, 1, buf_size, f);
	return read;
}


Sponsor:

#2 Cornstalks   Crossbones+   -  Reputation: 6991

Like
0Likes
Like

Posted 13 March 2012 - 12:23 PM

Why not use FFmpeg to open the video file? I hate giving out code, but this is what I use to open and play video files. It accepts anything FFmpeg can read, not just mpeg2video. It's a copy 'n' paste of a small portion of my code, and for my personal purposes I just needed the frame to be an 8-bit gray frame so I convert all frames to 8-bit gray. If there's a particular part you have a question about, feel free to ask. Otherwise, I'm going to assume the code is self-explanatory.

Video::Video(const std::string& filename) : imageConvertContext(NULL),
	buffer(NULL),
	grayFrame(NULL),
	frame(NULL),
	codecContext(NULL),
	formatContext(NULL),
	videoStreamIndex(-1),
	endReached(true),
	scaledWidth(0),
	scaledHeight(0),
	currentFrameNumber(-1)
{
	int errorCode = 0;

	if ((errorCode = avformat_open_input(&formatContext, filename.c_str(), NULL, NULL)) != 0)
	{
		throw std::runtime_error("Unable to open the stream");
	}

	if ((errorCode = avformat_find_stream_info(formatContext, NULL)) < 0)
	{
		throw std::runtime_error("Unable to find the stream's info");
	}

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

	if (videoStreamIndex == -1)
	{
		throw std::runtime_error("Unable to find a video stream");
	}

	codecContext = formatContext->streams[videoStreamIndex]->codec;
	codec = avcodec_find_decoder(codecContext->codec_id);
	if (codec == NULL)
	{
		throw std::runtime_error("Unsupported codec");
	}

	if ((errorCode = avcodec_open2(codecContext, codec, NULL)) != 0)
	{
		throw std::runtime_error("Error opening the codec");
	}

	frameRate = formatContext->streams[videoStreamIndex]->avg_frame_rate;
	if (!frameRate.num || ! frameRate.den)
	{
		throw std::runtime_error("This video does not have a constant frame rate");
	}

	//TODO: if one of these fail, we should release what has succeeded
	frame = avcodec_alloc_frame();
	grayFrame = avcodec_alloc_frame();
	if (frame == NULL || grayFrame == NULL)
	{
		throw std::runtime_error("Unable to allocate frame memory");
	}

	int numBytes = avpicture_get_size(PIX_FMT_GRAY8, codecContext->width, codecContext->height);
	buffer = (uint8_t*)av_malloc(numBytes * sizeof(uint8_t));

	avpicture_fill((AVPicture*)grayFrame, buffer, PIX_FMT_GRAY8, codecContext->width, codecContext->height);

	imageConvertContext = sws_getContext(codecContext->width,
		codecContext->height,
		codecContext->pix_fmt,
		codecContext->width,
		codecContext->height,
		PIX_FMT_GRAY8,
		SWS_FAST_BILINEAR,
		NULL,
		NULL,
		NULL);

	scaledWidth = codecContext->width;
	scaledHeight = codecContext->height;

	endReached = false;
}

Video::~Video()
{
	sws_freeContext(imageConvertContext);
	av_free_packet(&packet);
	av_free(buffer);
	av_free(grayFrame);
	av_free(frame);
	avcodec_close(codecContext);
	av_close_input_file(formatContext);
}

const AVFrame* Video::getNextFrame()
{
	while (av_read_frame(formatContext, &packet) == 0)
	{
		int frameFinished = 0;
		if (packet.stream_index == videoStreamIndex)
		{
			avcodec_decode_video2(codecContext, frame, &frameFinished, &packet);
			if (frameFinished)
			{
				sws_scale(imageConvertContext,
					frame->data,
					frame->linesize,
					0,
					frame->height,
					grayFrame->data,
					grayFrame->linesize);

				++currentFrameNumber;
				return grayFrame;
			}
		}
	}

	endReached = true;
	return NULL;
}

[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#3 arthur__   Members   -  Reputation: 102

Like
0Likes
Like

Posted 14 March 2012 - 03:14 AM

Thanks for your reply;
I want to read from stream (in a char *buffer), but as it not work I changed my buffer by reading directly the file, that's why I use

av_open_input_stream.

I have already tried to open my file with av_open_input_file and it's work, but it's not my goal here.

#4 arthur__   Members   -  Reputation: 102

Like
0Likes
Like

Posted 15 March 2012 - 09:23 AM

Problem solved ! I compiled with ffmpeg static library and it works !




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS