I am grabbing a video frame from my webcam and trying to stream it live through RTMP (to YouTube specifically). I have been able to successfully grab a YUV420p frame from the camera, encode it in h.264, but when I try to send it to the muxer, it does not encode it to the stream correctly.
I suspect that I have failed to set a important parameter, or have done something in a incorrect order when initializing. I have also tried using both the av_write_frame function and the av_interleaved_write_frame.
To make it easier for testing, I have the output going to a flv file for now. I define FILE_TEST_PATH as the path I want the file saved to.
This is my initialization function:
void rtmp_stream::init(string url, int width, int height)
{
//if(avio_open2(&formatCtx->pb, url.c_str(), AVIO_FLAG_READ_WRITE , NULL, NULL))
if(avio_open2(&formatCtx->pb, FILE_TEST_PATH , AVIO_FLAG_WRITE, NULL, NULL))
{
printf("Error\n");
}
avformat_new_stream(formatCtx, codec);
formatCtx->streams[0]->codecpar->format=AV_PIX_FMT_YUV420P;
formatCtx->streams[0]->codecpar->bit_rate=4000000;
formatCtx->streams[0]->codecpar->width=width;
formatCtx->streams[0]->codecpar->height=height;
formatCtx->streams[0]->codecpar->codec_id = codec->id;
formatCtx->streams[0]->time_base=(AVRational){1,1000};
strcpy(formatCtx->filename, FILE_TEST_PATH);
/*
* It says using stream->codec is depricated but yet it does not populate codecpar
* without setting these up.
*/
formatCtx->streams[0]->codec->width=width;
formatCtx->streams[0]->codec->height=height;
formatCtx->streams[0]->codec->pix_fmt=AV_PIX_FMT_YUV420P;
formatCtx->streams[0]->codec->codec_id = codec->id;
formatCtx->streams[0]->codec->bit_rate=4000000;
formatCtx->streams[0]->codec->pix_fmt=AV_PIX_FMT_YUV420P;
formatCtx->streams[0]->codec->max_b_frames=3;
formatCtx->video_codec_id=formatCtx->streams[0]->codecpar->codec_id;
codecCtx->bit_rate=4000000;
codecCtx->bit_rate_tolerance=0;
codecCtx->framerate=(AVRational){1,1};
codecCtx->gop_size=12;
codecCtx->height=height;
codecCtx->width=width;
codecCtx->pix_fmt=AV_PIX_FMT_YUV420P;
codecCtx->time_base=(AVRational){1,25};
codecCtx->max_b_frames=3;
avcodec_open2(codecCtx, codec, NULL);
avformat_write_header(formatCtx, NULL);
}
This is the code that sends the encoded h.264 packet to the muxer
void rtmp_stream::send_packet()
{
av_packet_rescale_ts(packet, codecCtx->time_base, formatCtx->streams[0]->time_base);
if(av_write_frame(formatCtx, packet))
printf("ERROR\n");
}
Additional information: I know the frames from the camera are valid and working. I have dumped the h.264 packets from the encoder to a ".h264" file and played them in VLC and they played fine. I'm also only working with video for now.
I have the code in my git gub account should there be a need to see more code. https://github.com/chrismacias37/Heads-Up-Display