X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=futatabi%2Fvideo_stream.cpp;h=591ee7e219883e5f4eb9209cbb17e5100108ea83;hb=refs%2Fheads%2Fmaster;hp=a21832929957ea1d1ab84ade759dc524337666bf;hpb=bdc9f1ea04141e71906d486f9d254c3346835e72;p=nageru diff --git a/futatabi/video_stream.cpp b/futatabi/video_stream.cpp index a218329..c12acdf 100644 --- a/futatabi/video_stream.cpp +++ b/futatabi/video_stream.cpp @@ -15,6 +15,7 @@ extern "C" { #include "pbo_pool.h" #include "player.h" #include "shared/context.h" +#include "shared/ffmpeg_raii.h" #include "shared/httpd.h" #include "shared/metrics.h" #include "shared/shared_defs.h" @@ -353,8 +354,9 @@ void VideoStream::start() audio_codecpar->codec_type = AVMEDIA_TYPE_AUDIO; audio_codecpar->codec_id = AV_CODEC_ID_PCM_S32LE; - audio_codecpar->channel_layout = AV_CH_LAYOUT_STEREO; - audio_codecpar->channels = 2; + audio_codecpar->ch_layout.order = AV_CHANNEL_ORDER_NATIVE; + audio_codecpar->ch_layout.nb_channels = 2; + audio_codecpar->ch_layout.u.mask = AV_CH_LAYOUT_STEREO; audio_codecpar->sample_rate = OUTPUT_FREQUENCY; size_t width = global_flags.width, height = global_flags.height; // Doesn't matter for MJPEG. @@ -742,27 +744,25 @@ void VideoStream::encode_thread_func() // Hack: We mux the subtitle packet one time unit before the actual frame, // so that Nageru is sure to get it first. if (!qf.subtitle.empty() && with_subtitles == Mux::WITH_SUBTITLES) { - AVPacket pkt; - av_init_packet(&pkt); - pkt.stream_index = mux->get_subtitle_stream_idx(); - assert(pkt.stream_index != -1); - pkt.data = (uint8_t *)qf.subtitle.data(); - pkt.size = qf.subtitle.size(); - pkt.flags = 0; - pkt.duration = lrint(TIMEBASE / global_flags.output_framerate); // Doesn't really matter for Nageru. - mux->add_packet(pkt, qf.output_pts - 1, qf.output_pts - 1); + AVPacketWithDeleter pkt = av_packet_alloc_unique(); + pkt->stream_index = mux->get_subtitle_stream_idx(); + assert(pkt->stream_index != -1); + pkt->data = (uint8_t *)qf.subtitle.data(); + pkt->size = qf.subtitle.size(); + pkt->flags = 0; + pkt->duration = lrint(TIMEBASE / global_flags.output_framerate); // Doesn't really matter for Nageru. + mux->add_packet(*pkt, qf.output_pts - 1, qf.output_pts - 1); } if (qf.type == QueuedFrame::ORIGINAL) { // Send the JPEG frame on, unchanged. string jpeg = move(*qf.encoded_jpeg); - AVPacket pkt; - av_init_packet(&pkt); - pkt.stream_index = 0; - pkt.data = (uint8_t *)jpeg.data(); - pkt.size = jpeg.size(); - pkt.flags = AV_PKT_FLAG_KEY; - mux->add_packet(pkt, qf.output_pts, qf.output_pts); + AVPacketWithDeleter pkt = av_packet_alloc_unique(); + pkt->stream_index = 0; + pkt->data = (uint8_t *)jpeg.data(); + pkt->size = jpeg.size(); + pkt->flags = AV_PKT_FLAG_KEY; + mux->add_packet(*pkt, qf.output_pts, qf.output_pts); last_frame = move(jpeg); add_audio_or_silence(qf); @@ -776,13 +776,12 @@ void VideoStream::encode_thread_func() // Now JPEG encode it, and send it on to the stream. string jpeg = encode_jpeg_from_pbo(qf.resources->pbo_contents, global_flags.width, global_flags.height, /*exif_data=*/""); - AVPacket pkt; - av_init_packet(&pkt); - pkt.stream_index = 0; - pkt.data = (uint8_t *)jpeg.data(); - pkt.size = jpeg.size(); - pkt.flags = AV_PKT_FLAG_KEY; - mux->add_packet(pkt, qf.output_pts, qf.output_pts); + AVPacketWithDeleter pkt = av_packet_alloc_unique(); + pkt->stream_index = 0; + pkt->data = (uint8_t *)jpeg.data(); + pkt->size = jpeg.size(); + pkt->flags = AV_PKT_FLAG_KEY; + mux->add_packet(*pkt, qf.output_pts, qf.output_pts); last_frame = move(jpeg); add_audio_or_silence(qf); @@ -821,24 +820,22 @@ void VideoStream::encode_thread_func() interpolate->release_texture(qf.cbcr_tex); } - AVPacket pkt; - av_init_packet(&pkt); - pkt.stream_index = 0; - pkt.data = (uint8_t *)jpeg.data(); - pkt.size = jpeg.size(); - pkt.flags = AV_PKT_FLAG_KEY; - mux->add_packet(pkt, qf.output_pts, qf.output_pts); + AVPacketWithDeleter pkt = av_packet_alloc_unique(); + pkt->stream_index = 0; + pkt->data = (uint8_t *)jpeg.data(); + pkt->size = jpeg.size(); + pkt->flags = AV_PKT_FLAG_KEY; + mux->add_packet(*pkt, qf.output_pts, qf.output_pts); last_frame = move(jpeg); add_audio_or_silence(qf); } else if (qf.type == QueuedFrame::REFRESH) { - AVPacket pkt; - av_init_packet(&pkt); - pkt.stream_index = 0; - pkt.data = (uint8_t *)last_frame.data(); - pkt.size = last_frame.size(); - pkt.flags = AV_PKT_FLAG_KEY; - mux->add_packet(pkt, qf.output_pts, qf.output_pts); + AVPacketWithDeleter pkt = av_packet_alloc_unique(); + pkt->stream_index = 0; + pkt->data = (uint8_t *)last_frame.data(); + pkt->size = last_frame.size(); + pkt->flags = AV_PKT_FLAG_KEY; + mux->add_packet(*pkt, qf.output_pts, qf.output_pts); add_audio_or_silence(qf); // Definitely silence. } else if (qf.type == QueuedFrame::SILENCE) { @@ -886,13 +883,12 @@ void VideoStream::add_silence(int64_t pts, int64_t length_pts) long num_samples = lrint(length_pts * double(OUTPUT_FREQUENCY) / double(TIMEBASE)) * 2; uint8_t *zero = (uint8_t *)calloc(num_samples, sizeof(int32_t)); - AVPacket pkt; - av_init_packet(&pkt); - pkt.stream_index = 1; - pkt.data = zero; - pkt.size = num_samples * sizeof(int32_t); - pkt.flags = AV_PKT_FLAG_KEY; - mux->add_packet(pkt, pts, pts); + AVPacketWithDeleter pkt = av_packet_alloc_unique(); + pkt->stream_index = 1; + pkt->data = zero; + pkt->size = num_samples * sizeof(int32_t); + pkt->flags = AV_PKT_FLAG_KEY; + mux->add_packet(*pkt, pts, pts); free(zero); } @@ -903,12 +899,11 @@ void VideoStream::add_audio_or_silence(const QueuedFrame &qf) int64_t frame_length = lrint(double(TIMEBASE) / global_flags.output_framerate); add_silence(qf.output_pts, frame_length); } else { - AVPacket pkt; - av_init_packet(&pkt); - pkt.stream_index = 1; - pkt.data = (uint8_t *)qf.audio.data(); - pkt.size = qf.audio.size(); - pkt.flags = AV_PKT_FLAG_KEY; - mux->add_packet(pkt, qf.output_pts, qf.output_pts); + AVPacketWithDeleter pkt = av_packet_alloc_unique(); + pkt->stream_index = 1; + pkt->data = (uint8_t *)qf.audio.data(); + pkt->size = qf.audio.size(); + pkt->flags = AV_PKT_FLAG_KEY; + mux->add_packet(*pkt, qf.output_pts, qf.output_pts); } }