Skip to content

Instantly share code, notes, and snippets.

@irieger
Last active October 26, 2019 07:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save irieger/604125fba000f76095626696f34ae619 to your computer and use it in GitHub Desktop.
Save irieger/604125fba000f76095626696f34ae619 to your computer and use it in GitHub Desktop.
Excerpt of my try to use libavformat to pack (mov) movie containers with external CFHD frame encoding
std::string filename;
AVFormatContext* format_context = NULL;
int32_t out_height = 1080;
int32_t out_width = 1920;
int32_t out_framerate = 24;
AVOutputFormat* out_format = nullptr;
AVStream* out_avstream = nullptr;
int error;
error = avformat_alloc_output_context2(&format_context, NULL, NULL, filename.c_str());
if (error != 0)
{
std::cerr << "Unable to create output context" << std::endl;
std::exit(1);
}
out_format = clip->_format_context->oformat;
out_format->video_codec = AV_CODEC_ID_CFHD;
num_frames = 0;
out_avstream = avformat_new_stream(format_context, NULL);
if (clip->_out_avstream == NULL)
{
std::cerr << "Unable to create output video stream" << std::endl;
std::exit(1);
}
out_avstream->time_base = (AVRational){1, 24};
out_avstream->avg_frame_rate = (AVRational){24, 1};
// clip->_out_avstream->time_base.num = 1;
// clip->_out_avstream->time_base.den = 12288;
// clip->_out_avstream->avg_frame_rate.num = 24;
// clip->_out_avstream->avg_frame_rate.den = 1;
out_avstream->r_frame_rate = clip->_out_avstream->avg_frame_rate;
out_avstream->codec->time_base = clip->_out_avstream->time_base;
AVCodecParameters* codecpar = out_avstream->codecpar;
codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
codecpar->codec_id = AV_CODEC_ID_CFHD;
codecpar->codec_tag = 1145587267;
codecpar->extradata_size = 0;
switch (mode)
{
case CineformMode::YUV422:
codecpar->format = 66;
break;
default:
codecpar->format = 137; // RGB
}
codecpar->bit_rate = 61389834; //! @todo Correct bitrate information?!
codecpar->bits_per_coded_sample = 24;
codecpar->bits_per_raw_sample = 10;
codecpar->profile = -99;
codecpar->level = -99;
codecpar->width = width;
codecpar->height = height;
codecpar->sample_aspect_ratio.num = 0;
codecpar->sample_aspect_ratio.den = 1;
codecpar->field_order = AV_FIELD_PROGRESSIVE;
codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
codecpar->color_trc = AVCOL_TRC_UNSPECIFIED;
codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
codecpar->video_delay = 0;
codecpar->channel_layout = 0;
codecpar->channels = 0;
codecpar->sample_rate = 0;
codecpar->block_align = 0;
codecpar->frame_size = 0;
codecpar->initial_padding = 0;
codecpar->trailing_padding = 0;
codecpar->seek_preroll = 0;
av_dump_format(format_context, 0, filename.c_str(), 1);
error = avio_open(&format_context->pb, filename.c_str(), AVIO_FLAG_WRITE);
if (error < 0)
{
std::cerr << "Unable to create output file" << std::endl;
std::exit(1);
}
error = avformat_write_header(format_context, NULL);
if (error < 0)
{
std::cerr << "Unable to write header" << std::endl;
std::exit(1);
}
for all frames
{
int frame // number of the current frame
uint16_t* img_data // is filled with the data for the current frame
void* frame_data; // will contain the compressed data returned by cineformsdk
size_t frame_data_size; // size of frame_data
// cfhd_handler is a wrapper class that encapsulates the cineformSDK
if (cfhd_handler->encodeCfhdFrame(&frame_data, frame_data_size, img_data,
out_height, out_width, frame))
{
std::cout << "Frame compressed. Frame: " << frame << ", compressed_size: " << frame_data_size << std::endl;
}
else
{
std::cerr << "Failed to compress frame" << std::endl;
std::exit(1);
}
AVRational tc;
tc.num = frame;
tc.den = out_framerate;
AVPacket pkg;
pkg.buf = NULL;
pkg.pts = frame;
pkg.dts = frame;
pkg.data = reinterpret_cast<uint8_t*>(frame_data);
pkg.size = frame_data_size;
pkg.stream_index = out_avstream->index;
pkg.flags = 0;
pkg.side_data = NULL;
pkg.side_data_elems = 0;
pkg.duration = 0;
pkg.pos = -1;
error = av_interleaved_write_frame(format_context, &pkg);
if (error < 0)
{
std::cerr << "Unable to write frame to stream" << std::endl;
std::exit(1);
}
num_frames++;
}
av_write_trailer(format_context);
avio_closep(&format_context->pb);
avformat_free_context(format_context);
..$ ffmpeg -i testinput.mov
ffmpeg version 4.2.1-0york0~18.04.1 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
configuration: --prefix=/usr --extra-version='0york0~18.04.1' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-nonfree --enable-libfdk-aac --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'cineform_burnin.mov':
Metadata:
major_brand : qt
minor_version : 512
compatible_brands: qt
encoder : Lavf57.25.100
Duration: 00:01:07.33, start: 0.000000, bitrate: 287108 kb/s
Stream #0:0(eng): Video: cfhd (CFHD / 0x44484643), gbrp12le(10 bpc, bt709, progressive), 1920x1080, 287106 kb/s, SAR 1:1 DAR 16:9, 24 fps, 24 tbr, 12288 tbn, 12288 tbc (default)
Metadata:
handler_name : VideoHandler
encoder : GoPro CineForm RGB 16-bit
timecode : 01:00:00:00
Stream #0:1(eng): Data: none (tmcd / 0x64636D74)
Metadata:
handler_name : TimeCodeHandler
timecode : 01:00:00:00
At least one output file must be specified
================================================
..$ ffmpeg -i testoutput.mov
ffmpeg version 4.2.1-0york0~18.04.1 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
configuration: --prefix=/usr --extra-version='0york0~18.04.1' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-nonfree --enable-libfdk-aac --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'testout.mov':
Metadata:
major_brand : qt
minor_version : 512
compatible_brands: qt
encoder : Lavf58.29.100
Duration: 00:00:00.04, start: 0.000000, bitrate: 817533 kb/s
Stream #0:0: Video: cfhd (CFHD / 0x44484643), gbrp12le(10 bpc, progressive), 1920x1080, 817538 kb/s, 119.07 fps, 12288 tbr, 12288 tbn, 12288 tbc (default)
Metadata:
handler_name : VideoHandler
At least one output file must be specified
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment