
Recherche avancée
Autres articles (77)
-
List of compatible distributions
26 avril 2011, parThe table below is the list of Linux distributions compatible with the automated installation script of MediaSPIP. Distribution nameVersion nameVersion number Debian Squeeze 6.x.x Debian Weezy 7.x.x Debian Jessie 8.x.x Ubuntu The Precise Pangolin 12.04 LTS Ubuntu The Trusty Tahr 14.04
If you want to help us improve this list, you can provide us access to a machine whose distribution is not mentioned above or send the necessary fixes to add (...) -
Automated installation script of MediaSPIP
25 avril 2011, parTo overcome the difficulties mainly due to the installation of server side software dependencies, an "all-in-one" installation script written in bash was created to facilitate this step on a server with a compatible Linux distribution.
You must have access to your server via SSH and a root account to use it, which will install the dependencies. Contact your provider if you do not have that.
The documentation of the use of this installation script is available here.
The code of this (...) -
Contribute to translation
13 avril 2011You can help us to improve the language used in the software interface to make MediaSPIP more accessible and user-friendly. You can also translate the interface into any language that allows it to spread to new linguistic communities.
To do this, we use the translation interface of SPIP where the all the language modules of MediaSPIP are available. Just subscribe to the mailing list and request further informantion on translation.
MediaSPIP is currently available in French and English (...)
Sur d’autres sites (7315)
-
C++ ffmpeg - export to wav error : Invalid PCM packet, data has size 2 but at least a size of 4 was expected
9 septembre 2024, par Chris PC++ code :


AudioSegment AudioSegment::from_file(const std::string& file_path, const std::string& format, const std::string& codec,
 const std::map& parameters, int start_second, int duration) {

 avformat_network_init();
 av_log_set_level(AV_LOG_ERROR); // Adjust logging level as needed

 AVFormatContext* format_ctx = nullptr;
 if (avformat_open_input(&format_ctx, file_path.c_str(), nullptr, nullptr) != 0) {
 std::cerr << "Error: Could not open audio file." << std::endl;
 return AudioSegment(); // Return an empty AudioSegment on failure
 }

 if (avformat_find_stream_info(format_ctx, nullptr) < 0) {
 std::cerr << "Error: Could not find stream information." << std::endl;
 avformat_close_input(&format_ctx);
 return AudioSegment();
 }

 int audio_stream_index = -1;
 for (unsigned int i = 0; i < format_ctx->nb_streams; i++) {
 if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
 audio_stream_index = i;
 break;
 }
 }

 if (audio_stream_index == -1) {
 std::cerr << "Error: Could not find audio stream." << std::endl;
 avformat_close_input(&format_ctx);
 return AudioSegment();
 }

 AVCodecParameters* codec_par = format_ctx->streams[audio_stream_index]->codecpar;
 const AVCodec* my_codec = avcodec_find_decoder(codec_par->codec_id);
 AVCodecContext* codec_ctx = avcodec_alloc_context3(my_codec);

 if (!codec_ctx) {
 std::cerr << "Error: Could not allocate codec context." << std::endl;
 avformat_close_input(&format_ctx);
 return AudioSegment();
 }

 if (avcodec_parameters_to_context(codec_ctx, codec_par) < 0) {
 std::cerr << "Error: Could not initialize codec context." << std::endl;
 avcodec_free_context(&codec_ctx);
 avformat_close_input(&format_ctx);
 return AudioSegment();
 }

 if (avcodec_open2(codec_ctx, my_codec, nullptr) < 0) {
 std::cerr << "Error: Could not open codec." << std::endl;
 avcodec_free_context(&codec_ctx);
 avformat_close_input(&format_ctx);
 return AudioSegment();
 }

 SwrContext* swr_ctx = swr_alloc();
 if (!swr_ctx) {
 std::cerr << "Error: Could not allocate SwrContext." << std::endl;
 avcodec_free_context(&codec_ctx);
 avformat_close_input(&format_ctx);
 return AudioSegment();
 }
 codec_ctx->sample_rate = 44100;
 // Set up resampling context to convert to S16 format with 2 bytes per sample
 av_opt_set_chlayout(swr_ctx, "in_chlayout", &codec_ctx->ch_layout, 0);
 av_opt_set_int(swr_ctx, "in_sample_rate", codec_ctx->sample_rate, 0);
 av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", codec_ctx->sample_fmt, 0);

 AVChannelLayout dst_ch_layout;
 av_channel_layout_copy(&dst_ch_layout, &codec_ctx->ch_layout);
 av_channel_layout_uninit(&dst_ch_layout);
 av_channel_layout_default(&dst_ch_layout, 2);

 av_opt_set_chlayout(swr_ctx, "out_chlayout", &dst_ch_layout, 0);
 av_opt_set_int(swr_ctx, "out_sample_rate", codec_ctx->sample_rate, 0); // Match input sample rate
 av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); // Force S16 format

 if (swr_init(swr_ctx) < 0) {
 std::cerr << "Error: Failed to initialize the resampling context" << std::endl;
 swr_free(&swr_ctx);
 avcodec_free_context(&codec_ctx);
 avformat_close_input(&format_ctx);
 return AudioSegment();
 }

 AVPacket packet;
 AVFrame* frame = av_frame_alloc();
 if (!frame) {
 std::cerr << "Error: Could not allocate frame." << std::endl;
 swr_free(&swr_ctx);
 avcodec_free_context(&codec_ctx);
 avformat_close_input(&format_ctx);
 return AudioSegment();
 }

 std::vector<char> output;
 while (av_read_frame(format_ctx, &packet) >= 0) {
 if (packet.stream_index == audio_stream_index) {
 if (avcodec_send_packet(codec_ctx, &packet) == 0) {
 while (avcodec_receive_frame(codec_ctx, frame) == 0) {
 if (frame->pts != AV_NOPTS_VALUE) {
 frame->pts = av_rescale_q(frame->pts, codec_ctx->time_base, format_ctx->streams[audio_stream_index]->time_base);
 }

 uint8_t* output_buffer;
 int output_samples = av_rescale_rnd(
 swr_get_delay(swr_ctx, codec_ctx->sample_rate) + frame->nb_samples,
 codec_ctx->sample_rate, codec_ctx->sample_rate, AV_ROUND_UP);

 int output_buffer_size = av_samples_get_buffer_size(
 nullptr, 2, output_samples, AV_SAMPLE_FMT_S16, 1);

 output_buffer = (uint8_t*)av_malloc(output_buffer_size);

 if (output_buffer) {
 memset(output_buffer, 0, output_buffer_size); // Zero padding to avoid random noise
 int converted_samples = swr_convert(swr_ctx, &output_buffer, output_samples,
 (const uint8_t**)frame->extended_data, frame->nb_samples);

 if (converted_samples >= 0) {
 output.insert(output.end(), output_buffer, output_buffer + output_buffer_size);
 }
 else {
 std::cerr << "Error: Failed to convert audio samples." << std::endl;
 }
 // Make sure output_buffer is valid before freeing
 if (output_buffer != nullptr) {
 av_free(output_buffer);
 output_buffer = nullptr; // Prevent double-free
 }
 }
 else {
 std::cerr << "Error: Could not allocate output buffer." << std::endl;
 }
 }
 }
 else {
 std::cerr << "Error: Failed to send packet to codec context." << std::endl;
 }
 }
 av_packet_unref(&packet);
 }

 int frame_width = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * 2; // Use 2 bytes per sample and 2 channels

 std::map metadata = {
 {"sample_width", 2}, // S16 format has 2 bytes per sample
 {"frame_rate", codec_ctx->sample_rate}, // Use the input sample rate
 {"channels", 2}, // Assuming stereo output
 {"frame_width", frame_width}
 };

 av_frame_free(&frame);
 swr_free(&swr_ctx);
 avcodec_free_context(&codec_ctx);
 avformat_close_input(&format_ctx);

 return AudioSegment(static_cast<const>(output.data()), output.size(), metadata);
}

std::ofstream AudioSegment::export_segment_to_wav_file(const std::string& out_f) {
 std::cout << this->get_channels() << std::endl;
 av_log_set_level(AV_LOG_ERROR);
 AVCodecContext* codec_ctx = nullptr;
 AVFormatContext* format_ctx = nullptr;
 AVStream* stream = nullptr;
 AVFrame* frame = nullptr;
 AVPacket* pkt = nullptr;
 int ret;

 // Initialize format context for WAV
 if (avformat_alloc_output_context2(&format_ctx, nullptr, "wav", out_f.c_str()) < 0) {
 throw std::runtime_error("Could not allocate format context.");
 }

 // Find encoder for PCM
 const AVCodec* codec_ptr = avcodec_find_encoder(AV_CODEC_ID_PCM_S16LE);
 if (!codec_ptr) {
 throw std::runtime_error("PCM encoder not found.");
 }

 // Add stream
 stream = avformat_new_stream(format_ctx, codec_ptr);
 if (!stream) {
 throw std::runtime_error("Failed to create new stream.");
 }

 // Allocate codec context
 codec_ctx = avcodec_alloc_context3(codec_ptr);
 if (!codec_ctx) {
 throw std::runtime_error("Could not allocate audio codec context.");
 }

 // Set codec parameters for PCM
 codec_ctx->bit_rate = 128000; // Bitrate
 codec_ctx->sample_rate = this->get_frame_rate(); // Use correct sample rate
 codec_ctx->ch_layout.nb_channels = this->get_channels(); // Set the correct channel count

 // Set the channel layout: stereo or mono
 if (this->get_channels() == 2) {
 av_channel_layout_default(&codec_ctx->ch_layout, 2); // Stereo layout
 }
 else {
 av_channel_layout_default(&codec_ctx->ch_layout, 1); // Mono layout
 }

 codec_ctx->sample_fmt = AV_SAMPLE_FMT_S16; // PCM 16-bit format

 // Open codec
 if (avcodec_open2(codec_ctx, codec_ptr, nullptr) < 0) {
 throw std::runtime_error("Could not open codec.");
 }

 // Set codec parameters to the stream
 if (avcodec_parameters_from_context(stream->codecpar, codec_ctx) < 0) {
 throw std::runtime_error("Could not initialize stream codec parameters.");
 }

 // Open output file
 std::ofstream out_file(out_f, std::ios::binary);
 if (!out_file) {
 throw std::runtime_error("Failed to open output file.");
 }

 if (!(format_ctx->oformat->flags & AVFMT_NOFILE)) {
 if (avio_open(&format_ctx->pb, out_f.c_str(), AVIO_FLAG_WRITE) < 0) {
 throw std::runtime_error("Could not open output file.");
 }
 }

 // Write file header
 if (avformat_write_header(format_ctx, nullptr) < 0) {
 throw std::runtime_error("Error occurred when writing file header.");
 }

 // Initialize packet
 pkt = av_packet_alloc();
 if (!pkt) {
 throw std::runtime_error("Could not allocate AVPacket.");
 }

 // Initialize frame
 frame = av_frame_alloc();
 if (!frame) {
 throw std::runtime_error("Could not allocate AVFrame.");
 }

 // Set the frame properties
 frame->format = codec_ctx->sample_fmt;
 frame->ch_layout = codec_ctx->ch_layout;

 // Number of audio samples available in the data buffer
 int total_samples = data_.size() / (av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * codec_ctx->ch_layout.nb_channels);
 int samples_read = 0;

 // Set the number of samples per frame dynamically based on the input data
 while (samples_read < total_samples) {
 // Determine how many samples to read in this iteration (don't exceed the total sample count)
 int num_samples = std::min(codec_ctx->frame_size, total_samples - samples_read);
 if (num_samples == 0) {
 num_samples = 1024;
 codec_ctx->frame_size = 1024;
 }
 // Ensure num_samples is not zero
 if (num_samples <= 0) {
 throw std::runtime_error("Invalid number of samples in frame.");
 }

 // Set the number of samples in the frame
 frame->nb_samples = num_samples;

 // Allocate the frame buffer based on the number of samples
 ret = av_frame_get_buffer(frame, 0);
 if (ret < 0) {
 std::cerr << "Error allocating frame buffer: " << ret << std::endl;
 throw std::runtime_error("Could not allocate audio data buffers.");
 }

 // Copy the audio data into the frame's buffer (interleaving if necessary)
 /*if (codec_ctx->ch_layout.nb_channels == 2) {
 // If stereo, interleave planar data into packed format
 for (int i = 0; i < num_samples; ++i) {
 ((int16_t*)frame->data[0])[2 * i] = ((int16_t*)data_.data())[i]; // Left channel
 ((int16_t*)frame->data[0])[2 * i + 1] = ((int16_t*)data_.data())[total_samples + i]; // Right channel
 }
 }
 else {
 // For mono or packed data, directly copy the samples
 std::memcpy(frame->data[0], data_.data() + samples_read * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * codec_ctx->ch_layout.nb_channels,
 num_samples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * codec_ctx->ch_layout.nb_channels);
 }
 */
 std::memcpy(frame->data[0], data_.data() + samples_read * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * codec_ctx->ch_layout.nb_channels,
 num_samples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * codec_ctx->ch_layout.nb_channels);

 // Send the frame for encoding
 ret = avcodec_send_frame(codec_ctx, frame);
 if (ret < 0) {
 std::cerr << "Error sending frame for encoding: " << ret << std::endl;
 throw std::runtime_error("Error sending frame for encoding.");
 }

 // Receive and write encoded packets
 while (ret >= 0) {
 ret = avcodec_receive_packet(codec_ctx, pkt);
 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
 break;
 }
 else if (ret < 0) {
 throw std::runtime_error("Error during encoding.");
 }

 out_file.write(reinterpret_cast(pkt->data), pkt->size);
 av_packet_unref(pkt);
 }

 samples_read += num_samples;
 }

 // Flush the encoder
 if (avcodec_send_frame(codec_ctx, nullptr) < 0) {
 throw std::runtime_error("Error flushing the encoder.");
 }

 while (avcodec_receive_packet(codec_ctx, pkt) >= 0) {
 out_file.write(reinterpret_cast(pkt->data), pkt->size);
 av_packet_unref(pkt);
 }

 // Write file trailer
 av_write_trailer(format_ctx);

 // Cleanup
 av_frame_free(&frame);
 av_packet_free(&pkt);
 avcodec_free_context(&codec_ctx);

 if (!(format_ctx->oformat->flags & AVFMT_NOFILE)) {
 avio_closep(&format_ctx->pb);
 }
 avformat_free_context(format_ctx);

 out_file.close();
 return out_file;
}

</const></char>


Run code :


#include "audio_segment.h"
#include "effects.h"
#include "playback.h"
#include "cppaudioop.h"
#include "exceptions.h"
#include "generators.h"
#include "silence.h"
#include "utils.h"

#include <iostream>
#include <filesystem>

using namespace cppdub;

int main() {
 try {
 // Load the source audio file
 AudioSegment seg_1 = AudioSegment::from_file("../data/test10.mp3");
 std::string out_file_name = "ah-ah-ah.wav";

 // Export the audio segment to a new file with specified settings
 //seg_1.export_segment(out_file_name, "mp3");
 seg_1.export_segment_to_wav_file(out_file_name);


 // Optionally play the audio segment to verify
 // play(seg_1);

 // Load the exported audio file
 AudioSegment seg_2 = AudioSegment::from_file(out_file_name);

 // Play segments
 //play(seg_1);
 play(seg_2);
 }
 catch (const std::exception& e) {
 std::cerr << "An error occurred: " << e.what() << std::endl;
 }

 return 0;
}
</filesystem></iostream>


Error in second call of from_file function :


[pcm_s16le @ 000002d82ca5bfc0] Invalid PCM packet, data has size 2 but at least a size of 4 was expected


The process continue, i call hear the seg_2 with play(seg_2) call, but i can't directly play seg_2 export wav file (from windows explorer).


I had a guess that error may be because packed vs plannar formats missmatch but i am not quit sure. Maybe a swr_convert is necessary.


-
encoding with ffmpeg libx265 -pix_fmt gray gives unplayable vid
9 juin 2017, par netjiroWhat am I missing ?
I encode an old black and white film clip with ffmpeg libx265 passing -pix_fmt gray. The output is unplayable in both vlc and mplayer (linux), so I assume I’m missing something...encoding :
ffmpeg -i clip.mkv \
-c:v libx265 -preset slow -x265-params "crf=24" -pix_fmt gray \
-c:a libopus -b:a 64k \
-c:s copy \
out.mkvvlc errors :
[00007f8a3ddfe328] blend blend error: no matching alpha blending routine (chroma: RGBA -> GREY)
[00007f8a3ddfe328] core blend error: blending RGBA to GREY failed
... repeated ...mplayer errors :
Unexpected decoder output format Planar Y800
... repeated ...ffmpeg encoding output :
ffmpeg version 3.2.4 Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 4.9.4 (Gentoo 4.9.4 p1.0, pie-0.6.4)
configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64 --docdir=/usr/share/doc/ffmpeg-3.2.4/html --mandir=/usr/share/man --enable-shared --cc=x86_64-pc-linux-gnu-gcc --cxx=x86_64-pc-linux-gnu-g++ --ar=x86_64-pc-linux-gnu-ar --optflags='-march=native -O2 -pipe' --disable-static --enable-avfilter --enable-avresample --disable-stripping --enable-nonfree --enable-version3 --disable-indev=oss --disable-indev=jack --disable-outdev=oss --enable-version3 --enable-bzlib --disable-runtime-cpudetect --disable-debug --disable-gcrypt --disable-gnutls --disable-gmp --enable-gpl --enable-hardcoded-tables --enable-iconv --enable-lzma --enable-network --enable-openssl --enable-postproc --disable-libsmbclient --enable-ffplay --enable-sdl2 --enable-vaapi --enable-vdpau --enable-xlib --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-zlib --enable-libcdio --disable-libiec61883 --disable-libdc1394 --disable-libcaca --enable-openal --enable-opengl --enable-libv4l2 --disable-libpulse --enable-libopencore-amrwb --enable-libopencore-amrnb --disable-libfdk-aac --enable-libopenjpeg --enable-libbluray --enable-libcelt --disable-libgme --disable-libgsm --disable-mmal --enable-libmodplug --enable-libopus --disable-libilbc --disable-librtmp --enable-libssh --enable-libschroedinger --enable-libspeex --enable-libvorbis --enable-libvpx --disable-libzvbi --disable-libbs2b --disable-chromaprint --disable-libebur128 --disable-libflite --disable-frei0r --disable-libfribidi --enable-fontconfig --disable-ladspa --disable-libass --enable-libfreetype --disable-librubberband --disable-libzimg --enable-libsoxr --enable-pthreads --enable-libvo-amrwbenc --enable-libmp3lame --disable-libkvazaar --disable-nvenc --disable-libopenh264 --enable-libsnappy --enable-libtheora --enable-libtwolame --enable-libwavpack --disable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --disable-amd3dnow --disable-amd3dnowext --disable-fma4 --disable-xop --cpu=host --disable-doc --disable-htmlpages --enable-manpages
libavutil 55. 34.101 / 55. 34.101
libavcodec 57. 64.101 / 57. 64.101
libavformat 57. 56.101 / 57. 56.101
libavdevice 57. 1.100 / 57. 1.100
libavfilter 6. 65.100 / 6. 65.100
libavresample 3. 1. 0 / 3. 1. 0
libswscale 4. 2.100 / 4. 2.100
libswresample 2. 3.100 / 2. 3.100
libpostproc 54. 1.100 / 54. 1.100
x265 [info]: HEVC encoder version 2.2
x265 [info]: build info [Linux][GCC 4.9.4][64 bit] 8bit+10bit+12bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX AVX2 FMA3 LZCNT BMI2
x265 [info]: Unknown profile, Level-3.1 (Main tier)
x265 [warning]: No thread pool allocated, --wpp disabled
x265 [warning]: No thread pool allocated, --lookahead-slices disabled
x265 [info]: Slices : 1
x265 [info]: frame threads / pool features : 3 / none
x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
x265 [info]: ME / range / subpel / merge : star / 57 / 3 / 3
x265 [info]: Keyframe min / max / scenecut / bias: 23 / 250 / 40 / 5.00
x265 [info]: Lookahead / bframes / badapt : 25 / 4 / 2
x265 [info]: b-pyramid / weightp / weightb : 1 / 1 / 0
x265 [info]: References / ref-limit cu / depth : 4 / on / on
x265 [info]: AQ: mode / str / qg-size / cu-tree : 1 / 1.0 / 32 / 1
x265 [info]: Rate Control / qCompress : CRF-24.0 / 0.60
x265 [info]: tools: rect limit-modes rd=4 psy-rd=2.00 rdoq=2 psy-rdoq=1.00
x265 [info]: tools: rskip signhide tmvp strong-intra-smoothing deblock sao
Output #0, matroska, to 'out.mkv':
Metadata:
encoder : Lavf57.56.101
Metadata:
Stream #0:0(eng): Video: hevc (libx265), gray, 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 23.98 fps, 1k tbn, 23.98 tbc (default)
Metadata:
encoder : Lavc57.64.101 libx265
Stream #0:1(eng): Audio: opus (libopus) ([255][255][255][255] / 0xFFFFFFFF), 48000 Hz, stereo, flt, 64 kb/s (default)
Metadata:
encoder : Lavc57.64.101 libopus
Stream #0:2(eng): Subtitle: subrip (default)
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> hevc (libx265))
Stream #0:1 -> #0:1 (eac3 (native) -> opus (libopus))
Stream #0:3 -> #0:2 (copy)
Press [q] to stop, [?] for help
frame= 1439 fps=7.0 q=-0.0 Lsize= 5356kB time=00:01:00.01 bitrate= 731.1kbits/s speed=0.294x
video:4940kB audio:382kB subtitle:1kB other streams:0kB global headers:2kB muxing overhead: 0.629434%
x265 [info]: frame I: 9, Avg QP:22.27 kb/s: 6064.82
x265 [info]: frame P: 340, Avg QP:23.62 kb/s: 1950.21
x265 [info]: frame B: 1090, Avg QP:29.65 kb/s: 230.75
x265 [info]: Weighted P-Frames: Y:0.9% UV:0.0%
x265 [info]: consecutive B-frames: 2.9% 0.3% 1.4% 72.5% 22.9% -
Read existing MP4 File and write into a new MP4 file using libavcodec
4 octobre 2023, par TahfimulI am new to the libavcodec space.


I am trying to read video and audio streams from an existing mp4 file and take the data from the two streams and then mux the two streams and write the muxed data into a new mp4 file using libavcodec in C++. Essentially, I am aiming to split the original (existing) mp4 file into small chunks of 1 second clips that then can be played back using a video player. I would like to preserve the original mp4 video's video stream (i.e. preserve its color, resolution and etc.) and preserve the mp4 video's audio stream (i.e. preserve its bit rate and etc.). I am trying to achieve this using libavcodec in C++. But there does not seem to be any tutorial or documentation online that points me to that direction.


So far, I have looked at and tried to implement a solution using this tutorial (tutorial#1) : https://github.com/leandromoreira/ffmpeg-libav-tutorial/blob/master/0_hello_world.c


However, tutorial#1 aimed to save each video frame from the existing (original) mp4 video stream into individual .pgm files, which meant that the .pgm files would store a grayscale image of each video frame.


Since, I want to preserve the colors of the original (existing) mp4 file, I looked at this tutorial (tutorial#2) that aimed to convert the grayscale video frame into color using the swscale library : https://www.youtube.com/watch?v=Y7SUm7Xf1sc&ab_channel=Bartholomew
However, in tutorial#2, they exported the output from swscale library to a GUI library to be viewed in a GUI application and did not show hwo to write the output data into a new mp4 file that can be played back by a video player.


So then, I looked at this tutorial(tutorial#3) which showed how to create an MP4 file using libavcodec : C++ FFmpeg create mp4 file
However, the problem with that solution is that I was not able to take a video frame from the original mp4 video and store it into another mp4 file. I kept getting errors when attempting to do so and I did not succeed in taking the data from the original(existing) mp4 file and storing it into a new mp4 file.


Here is the code that I have written so far :


#include<fstream>
#include 
#include 
#include 
extern "C"
{
#include <libavcodec></libavcodec>avcodec.h>
#include <libavformat></libavformat>avformat.h>
#include <libavutil></libavutil>mathematics.h>
#include <libswscale></libswscale>swscale.h>
#include <libavfilter></libavfilter>buffersrc.h>
#include <libavfilter></libavfilter>buffersink.h>
#include <libavutil></libavutil>time.h>
#include <libavutil></libavutil>opt.h>
}
#pragma comment(lib, "avfilter.lib")
#ifdef av_err2str
#undef av_err2str
#include <string>
av_always_inline std::string av_err2string(int errnum) {
 char str[AV_ERROR_MAX_STRING_SIZE];
 return av_make_error_string(str, AV_ERROR_MAX_STRING_SIZE, errnum);
}
#define av_err2str(err) av_err2string(err).c_str()
#endif // av_err2str

#include <chrono>
#include <thread>


// decode packets into frames
static int decode_packet(AVPacket *pPacket, AVCodecContext *pCodecContext, AVFrame *pFrame);

static void pushFrame(AVFrame* frame, AVCodecContext* outputCodecContext, AVPacket * outputPacket, AVFormatContext* outputFormatContext, AVCodec *outputCodec) {
 
 std::cout<<"outputCodecContext: "<format = AV_PIX_FMT_YUV420P;
 frame->width = 800;
 frame->height = 800;
 if ((err = av_frame_get_buffer(frame, 32)) < 0) {
 std::cout << "Failed to allocate picture" << err << std::endl;
 return;
 }
 }
 SwsContext* swsCtx = nullptr;
 if (!swsCtx) {
 swsCtx = sws_getContext(800, 800, AV_PIX_FMT_RGB24, 800, 
 800, AV_PIX_FMT_YUV420P, SWS_BICUBIC, 0, 0, 0);
 }
 int inLinesize[1] = { 3 * 800 };
 // From RGB to YUV
 // sws_scale(swsCtx, (const uint8_t* const*)&data, inLinesize, 0, 800, 
 // frame->data, frame->linesize);
 std::cout<<"frame "<pts = (1.0 / 30.0) * 90000 * (1);
 // std::cout << videoFrame->pts << " " << cctx->time_base.num << " " << 
 // cctx->time_base.den << " " << 1 << std::endl;
 if ((err = avcodec_send_frame(outputCodecContext, frame)) < 0) {
 std::cout << "Failed to send frame" << err << std::endl;
 return;
 }
 AV_TIME_BASE;
 AVPacket pkt;
 av_init_packet(&pkt);
 pkt.data = NULL;
 pkt.size = 0;
 pkt.flags |= AV_PKT_FLAG_KEY;
 std::cout<<"here\n";
 if (avcodec_receive_packet(outputCodecContext, outputPacket) == 0) {
 static int counter = 0;
 if (counter == 0) {
 FILE* fp = fopen("dump_first_frame1.dat", "wb");
 fwrite(outputPacket->data, outputPacket->size, 1, fp);
 fclose(fp);
 }
 // std::cout << "pkt key: " << (pkt.flags & AV_PKT_FLAG_KEY) << " " << 
 // pkt.size << " " << (counter++) << std::endl;
 // uint8_t* size = ((uint8_t*)pkt.data);
 // std::cout << "first: " << (int)size[0] << " " << (int)size[1] << 
 // " " << (int)size[2] << " " << (int)size[3] << " " << (int)size[4] << 
 // " " << (int)size[5] << " " << (int)size[6] << " " << (int)size[7] << 
 // std::endl;
 av_interleaved_write_frame(outputFormatContext, outputPacket);
 av_packet_unref(outputPacket);
 }
}

int main()
{

 char* filename = "c++.mp4";

 AVFormatContext *pFormatContext = avformat_alloc_context();

 AVOutputFormat* outputFormat = NULL;

 AVFormatContext* outputFormatContext = nullptr;

 AVCodecContext* outputCodecContext = nullptr;

 if (!pFormatContext) {
 std::cerr<<"ERROR could not allocate memory for Format Context\n";
 return -1;
 }

 if (avformat_open_input(&pFormatContext, filename , NULL, NULL) != 0) {
 std::cerr<<"ERROR could not open the file\n";
 return -1;
 }

 std::cout<<"format: "<iformat->name<<" , duration:"<<(double)(pFormatContext->duration/AV_TIME_BASE)<<"seconds, bit_rate:"<bit_rate<video_codec);

 
 if (!outputCodec)
 {
 std::cout << "can't create output codec" << std::endl;
 return -1;
 } 
 

 AVStream* outputStream = avformat_new_stream(outputFormatContext, outputCodec);

 if (!outputStream)
 {
 std::cout << "can't find output format" << std::endl;
 return -1;
 }

 outputCodecContext = avcodec_alloc_context3(outputCodec);

 if (!outputCodecContext)
 {
 std::cout << "can't create output codec context" << std::endl;
 return -1;
 }

 AVCodec *pCodec = NULL;

 AVCodecParameters *pCodecParameters = NULL;

 int video_stream_index = -1;

 AVStream* stream = NULL;
 
 // loop though all the streams and print its main information
 for (int i = 0; i < pFormatContext->nb_streams; i++)
 {
 
 AVCodecParameters *pLocalCodecParameters = NULL;
 pLocalCodecParameters = pFormatContext->streams[i]->codecpar;

 AVCodec *pLocalCodec = NULL;
 pLocalCodec = avcodec_find_decoder(pLocalCodecParameters->codec_id);
 if (pLocalCodec==NULL) {
 std::cerr<<"ERROR unsupported codec!\n";
 // In this example if the codec is not found we just skip it
 continue;
 }


 if (pLocalCodecParameters->codec_type == AVMEDIA_TYPE_VIDEO) {
 if (video_stream_index == -1) {
 video_stream_index = i;
 pCodec = pLocalCodec;
 pCodecParameters = pLocalCodecParameters;
 stream = pFormatContext->streams[i];
 std::cout<<"codec id: "<codecpar->codec_id<codecpar->codec_type<codecpar->width<codecpar->height<codecpar->format<codecpar->bit_rate<codecpar->codec_id = outputFormat->video_codec;
 // outputStream->codecpar->codec_id = stream->codecpar->codec_id;
 outputStream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
 outputStream->codecpar->width = stream->codecpar->width;
 outputStream->codecpar->height = stream->codecpar->height;
 outputStream->codecpar->format = AV_PIX_FMT_YUV420P;
 outputStream->codecpar->bit_rate = stream->codecpar->bit_rate;
 
 avcodec_parameters_to_context(outputCodecContext, outputStream->codecpar);
 } 

 std::cout<<"Video Codec: resolution " << pLocalCodecParameters->width << " x "<height<codec_type == AVMEDIA_TYPE_AUDIO) {
 std::cout<<"Audio Codec: "<channels<<" channels, sample rate "<sample_rate<name << " ID: " <id<< " bit_rate: "<bit_rate</ outputStream->codecpar->codec_id = outputFormat->video_codec;
 // outputStream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
 // outputStream->codecpar->width = 300;
 // outputStream->codecpar->height = 300;
 // outputStream->codecpar->format = AV_PIX_FMT_YUV420P;
 // outputStream->codecpar->bit_rate = 200 * 1000;
 outputCodecContext->time_base = (AVRational){ 1, 1 };
 outputCodecContext->max_b_frames = 2;
 outputCodecContext->gop_size = 12;
 outputCodecContext->framerate = (AVRational){ 30, 1 };

 if (avcodec_parameters_to_context(pCodecContext, pCodecParameters) < 0)
 {
 std::cerr<<"failed to copy codec params to codec context\n";
 return -1;
 }

 // std::cout<<"pCodecContext->time_base: "<time_base)</ outputCodecContext->time_base = pCodecContext->time_base;
 // outputCodecContext->max_b_frames = pCodecContext->max_b_frames;
 // outputCodecContext->gop_size = pCodecContext->gop_size;
 // outputCodecContext->framerate = pCodecContext->framerate;

 if (outputStream->codecpar->codec_id == AV_CODEC_ID_H264) {
 // av_opt_set(pCodecContext, "preset", "ultrafast", 0);
 av_opt_set(outputCodecContext, "preset", "ultrafast", 0);
 }
 else if (outputStream->codecpar->codec_id == AV_CODEC_ID_H265)
 {
 // av_opt_set(pCodecContext, "preset", "ultrafast", 0);
 av_opt_set(outputCodecContext, "preset", "ultrafast", 0);
 }

 // avcodec_parameters_from_context(stream->codecpar, pCodecContext);
 avcodec_parameters_from_context(outputStream->codecpar, outputCodecContext);

 if (avcodec_open2(pCodecContext, pCodec, NULL) < 0)
 {
 std::cerr<<"failed to open codec through avcodec_open2\n";
 return -1;
 }

 if (avcodec_open2(outputCodecContext, outputCodec, NULL) < 0)
 {
 std::cerr<<"failed to open output codec through avcodec_open2\n";
 return -1;
 }


 if (!(outputFormat->flags & AVFMT_NOFILE)) {
 if (avio_open(&outputFormatContext->pb, "test.mp4", AVIO_FLAG_WRITE) < 0) {
 std::cout << "Failed to open file" << std::endl;
 return -1;
 }
 }

 if (avformat_write_header(outputFormatContext, NULL) < 0) {
 std::cout << "Failed to write header" << std::endl;
 return -1;
 }

 av_dump_format(outputFormatContext, 0, "test.mp4", 1);


 AVFrame *pFrame = av_frame_alloc();
 if (!pFrame)
 {
 std::cerr<<"failed to allocate memory for AVFrame\n";
 return -1;
 }
 
 // https://ffmpeg.org/doxygen/trunk/structAVPacket.html
 AVPacket *pPacket = av_packet_alloc();
 if (!pPacket)
 {
 std::cerr<<"failed to allocate memory for AVPacket\n";
 return -1;
 }

 int response = 0;
 int how_many_packets_to_process = 300;

 // fill the Packet with data from the Stream
 // https://ffmpeg.org/doxygen/trunk/group__lavf__decoding.html#ga4fdb3084415a82e3810de6ee60e46a61
 while (av_read_frame(pFormatContext, pPacket) >= 0)
 {
 // if it's the video stream
 if (pPacket->stream_index == video_stream_index) {
 std::cout<<"AVPacket->pts "<pts;
 // if(av_write_frame(outputFormatContext, pPacket)<0)
 // std::cout<<"error writing output frame\n";
 // pushFrame(pFrame, outputCodecContext, pPacket, outputFormatContext, outputCodec);
 response = decode_packet(pPacket, pCodecContext, pFrame);
 if (response < 0)
 break;
 // stop it, otherwise we'll be saving hundreds of frames
 if (--how_many_packets_to_process <= 0) break;
 }
 // https://ffmpeg.org/doxygen/trunk/group__lavc__packet.html#ga63d5a489b419bd5d45cfd09091cbcbc2
 av_packet_unref(pPacket);
 } 

 if(av_write_trailer(outputFormatContext)<0)
 std::cout <<"Error writing output trailer\n";


 return 0;
}

int save_frame_as_mpeg(AVCodecContext* pCodecCtx, AVFrame* pFrame, int FrameNo) {
 int ret = 0;

 const AVCodec* mpegCodec = avcodec_find_encoder(pCodecCtx->codec_id);
 if (!mpegCodec) {
 std::cout<<"failed to open mpegCodec\n";
 return -1;
 }
 AVCodecContext* mpegContext = avcodec_alloc_context3(mpegCodec);
 if (!mpegContext) {
 std::cout<<"failed to open mpegContext\n";
 return -1;
 }

 mpegContext->pix_fmt = pCodecCtx->pix_fmt;
 mpegContext->height = pFrame->height;
 mpegContext->width = pFrame->width;
 mpegContext->time_base = AVRational{ 1,10 };

 ret = avcodec_open2(mpegContext, mpegCodec, NULL);
 if (ret < 0) {
 return ret;
 }
 FILE* MPEGFile;
 char MPEGFName[256];

 AVPacket packet;
 packet.data = NULL;
 packet.size = 0;
 av_init_packet(&packet);

 int gotFrame;

 ret = avcodec_send_frame(mpegContext, pFrame);
 if (ret < 0) {
 std::cout<<"failed to send frame for mpegContext\n";
 return ret;
 }

 ret = avcodec_receive_packet(mpegContext, &packet);
 if (ret < 0) {
 std::cout<<"failed to receive packet for mpegContext\terrocode: "<pix_fmt = pCodecCtx->pix_fmt;
 jpegContext->height = pFrame->height;
 jpegContext->width = pFrame->width;
 jpegContext->time_base = AVRational{ 1,10 };

 ret = avcodec_open2(jpegContext, jpegCodec, NULL);
 if (ret < 0) {
 return ret;
 }
 FILE* JPEGFile;
 char JPEGFName[256];

 AVPacket packet;
 packet.data = NULL;
 packet.size = 0;
 av_init_packet(&packet);

 int gotFrame;

 ret = avcodec_send_frame(jpegContext, pFrame);
 if (ret < 0) {
 return ret;
 }

 ret = avcodec_receive_packet(jpegContext, &packet);
 if (ret < 0) {
 return ret;
 }

 sprintf(JPEGFName, "c:\\folder\\dvr-%06d.jpg", FrameNo);
 JPEGFile = fopen(JPEGFName, "wb");
 fwrite(packet.data, 1, packet.size, JPEGFile);
 fclose(JPEGFile);

 av_packet_unref(&packet);
 avcodec_close(jpegContext);
 return 0;
}

static int decode_packet(AVPacket *pPacket, AVCodecContext *pCodecContext, AVFrame *pFrame)
{
 // Supply raw packet data as input to a decoder
 // https://ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga58bc4bf1e0ac59e27362597e467efff3
 int response = avcodec_send_packet(pCodecContext, pPacket);
 if (response < 0) {
 std::cerr<<"Error while sending a packet to the decoder: "<= 0)
 {
 // Return decoded output data (into a frame) from a decoder
 // https://ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga11e6542c4e66d3028668788a1a74217c
 response = avcodec_receive_frame(pCodecContext, pFrame);
 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
 break;
 } else if (response < 0) {
 std::cerr<<"Error while receiving a frame from the decoder: "<= 0) {

 response = save_frame_as_jpeg(pCodecContext, pFrame, pCodecContext->frame_number);

 if(response<0)
 {
 std::cerr<<"Failed to save frame as jpeg\n";
 return -1;
 }

 response = save_frame_as_mpeg(pCodecContext, pFrame, pCodecContext->frame_number);

 if(response<0)
 {
 std::cerr<<"Failed to save frame as mpeg\n";
 return -1;
 }


 std::cout<<
 "Frame "<frame_number<< "type= "<pict_type)<<" size= "<pkt_size<<" bytes, format= "<format<<" "<pts<<"pts key_frame "<key_frame<< " [DTS"<coded_picture_number<<" ]\n";
 
 char frame_filename[1024];
 snprintf(frame_filename, sizeof(frame_filename), "%s-%d.pgm", "frame", pCodecContext->frame_number);
 // Check if the frame is a planar YUV 4:2:0, 12bpp
 // That is the format of the provided .mp4 file
 // RGB formats will definitely not give a gray image
 // Other YUV image may do so, but untested, so give a warning
 if (pFrame->format != AV_PIX_FMT_YUV420P)
 {
 std::cout<<"Warning: the generated file may not be a grayscale image, but could e.g. be just the R component if the video format is RGB\n";
 }
 
 }
 }
 return 0;
}
</thread></chrono></string></fstream>


The question that I am seeking an answer to is How can I use libavcodec to split an mp4 file into 1 second chunk clips (those clips will be in mp4 format) ?