使用vlc来播放rtsp的结果
在我的其他文章中可以找到如何使用ffmpeg使用dshow采集usb摄像头,我们也可以直接使用dshow。也可以参考以下代码。
int CameraCapture::initialise()
{
fState = 0;
if (fCamDesc == NULL) {
wprintf("camera description pointer not set!");
return -1;
}
if (fCamDesc->name[0] == '\0') {
wprintf("camera name is empty!");
return -1;
}
int ret = 0;
char str_tmp[128];
str_tmp[127] = 0;
AVDictionary* opt = nullptr;
AVDictionaryEntry* dict_entry = nullptr;
AVInputFormat *inFrmt = nullptr;
// Initialize FFmpeg environment
avdevice_register_all();
av_log_set_level(AV_LOG_ERROR);
if (fDecCtx != nullptr) {
avcodec_free_context(&fDecCtx);
fDecCtx = nullptr;
}
if (fInputCtx != nullptr) {
avformat_close_input(&fInputCtx);
fInputCtx = nullptr;
}
if (fFrameOut != nullptr) {
if (fFrameOut->data[0] != nullptr) {
av_freep(fFrameOut->data[0]);
}
av_frame_free(&fFrameOut);
fFrameOut = nullptr;
}
fInputCtx = avformat_alloc_context();
inFrmt = av_find_input_format("dshow");
//video size
ret = snprintf(str_tmp, 127, "video_size=%dx%d;pixel_format=%s;framerate=%g;",
fCamDesc->width, fCamDesc->height, (fCamDesc->pixel_format).c_str(),
fCamDesc->frame_rate);
av_dict_parse_string(&opt, str_tmp, "=", ";", 0);
if (fCamDesc->device_num > 0) {
ret += av_dict_set(&opt, "video_device_number", int2str(fCamDesc->device_num).c_str(), 0);
}
if (!fCamDesc->pin_name.empty()) {
av_dict_set(&opt, "video_pin_name", fCamDesc->pin_name.c_str(), 0);
}
if (fCamDesc->rtbuffsize > 102400) { //ignore a small rtbuffsize
av_dict_set(&opt, "rtbufsize", byte2str(fCamDesc->rtbuffsize).c_str(), 0);
}
snprintf(str_tmp, 127, "video=%s", fCamDesc->name.c_str());
if (ret = avformat_open_input(&fInputCtx, str_tmp, inFrmt, &opt) != 0) {
//exception
av_dict_free(&opt);
av_strerror(ret, str_tmp, 127);
eprintf("open video input '%s' failed! err = %s", fCamDesc->name.c_str(), str_tmp);
return -1;
}
if (opt != nullptr) {
iprintf("the following options are not used:");
dict_entry = nullptr;
while (dict_entry = av_dict_get(opt, "", dict_entry, AV_DICT_IGNORE_SUFFIX)) {
fprintf(stdout, " '%s' = '%s'\n", dict_entry->key, dict_entry->value);
}
av_dict_free(&opt);
}
if (avformat_find_stream_info(fInputCtx, nullptr) name.c_str());
return -1;
}
//print out the video stream information
iprintf("video stream from '%s': ", fCamDesc->name.c_str());
av_dump_format(fInputCtx, 0, fInputCtx->url, 0);
fOutStreamNum = -1;
AVStream* stream = nullptr;
for (unsigned int i = 0; i nb_streams; i++) {
if (fInputCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
fOutStreamNum = i;
stream = fInputCtx->streams[i];
}
}
if (fOutStreamNum == -1 || stream == nullptr) {
//exception
eprintf("no video stream found in '%s'!\n", fCamDesc->name.c_str());
return -1;
}
AVCodecParameters *codec_param = stream->codecpar;
fBitrate = codec_param->bit_rate;
fDelayClock = (int)((double)(CLOCKS_PER_SEC) * (double)(stream->avg_frame_rate.den) / (double)(stream->avg_frame_rate.num));
AVCodec* decoder = avcodec_find_decoder(codec_param->codec_id);
if (decoder == nullptr) {
eprintf("cannot find decoder for '%s'!", avcodec_get_name(codec_param->codec_id));
return -1;
}
fDecCtx = avcodec_alloc_context3(decoder);
avcodec_parameters_to_context(fDecCtx, codec_param);
av_log_set_level(AV_LOG_FATAL);
if (avcodec_open2(fDecCtx, decoder, nullptr) width, fDecCtx->height, fDecCtx->pix_fmt,
fDecCtx->width, fDecCtx->height, AV_PIX_FMT_NV12, SWS_BICUBIC, nullptr, nullptr, nullptr);
fFrameOut = av_frame_alloc();
if (fFrameOut == nullptr) {
eprintf("allocating output frame failed!");
return -1;
}
fFrameOut->width = fDecCtx->width;
fFrameOut->height = fDecCtx->height;
fFrameOut->format = AV_PIX_FMT_NV12;
fDataOutSz = av_image_get_buffer_size(AV_PIX_FMT_NV12, fFrameOut->width,
fFrameOut->height, MEM_ALIGN);
ret = av_frame_get_buffer(fFrameOut, MEM_ALIGN);
if (ret set_PPS_NAL(fH264Encoder->PPS_NAL(), fH264Encoder->PPS_NAL_size());
sub->set_SPS_NAL(fH264Encoder->SPS_NAL(), fH264Encoder->SPS_NAL_size());
if (fH264Encoder->h264_bit_rate() > 102400) {
sub->set_bit_rate(fH264Encoder->h264_bit_rate());
}
else {
sub->set_bit_rate(static_cast(fH264Encoder->pict_width() * fH264Encoder->pict_height() * fH264Encoder->frame_rate() / 20));
}
sms->addSubsession(sub);
rtspServer->addServerMediaSession(sms);
char* url = rtspServer->rtspURL(sms);
*env taskScheduler().doEventLoop(&fQuit); // does not return
Medium::close(rtspServer);
Medium::close(inputDevice);
}
env->reclaim();
delete scheduler;
};
}