### FFmpeg Initialization Example Source: https://ffmpeg.org/doxygen/8.0/avpacket_8c.html This C code snippet demonstrates basic initialization for FFmpeg, including necessary header includes and function definitions for setup and initialization. ```c #include #include #include #include #include "libavcodec/avcodec.h" #include "libavutil/error.h" #include "libavutil/mem.h" ``` -------------------------------- ### QSV Decode Example Source: https://ffmpeg.org/doxygen/8.0/qsv__decode_8c.html Demonstrates the necessary includes for QSV decoding operations in FFmpeg. This setup is required for using QSV hardware acceleration. ```c #include #include #include #include #include #include #include #include #include ``` -------------------------------- ### Audio Encoding Example Source: https://ffmpeg.org/doxygen/8.0/encode__audio_8c.html This C code demonstrates the process of encoding audio using FFmpeg. It includes setup for codec context, frame, and packet, along with utility functions for checking audio parameters and performing the encoding. ```c #include #include #include #include #include #include #include #include static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt) { // Implementation details for checking sample format return 0; // Placeholder } static int select_sample_rate(const AVCodec *codec) { // Implementation details for selecting sample rate return 0; // Placeholder } static int select_channel_layout(const AVCodec *codec, AVChannelLayout *dst) { // Implementation details for selecting channel layout return 0; // Placeholder } static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt, FILE *output) { // Implementation details for encoding } int main(int argc, char **argv) { // Main function implementation return 0; // Placeholder } ``` -------------------------------- ### Get GUID as String (Macro) Source: https://ffmpeg.org/doxygen/8.0/mf__utils_8c_source.html A macro to get the string representation of a GUID, likely using ff_guid_str_buf internally. It simplifies the process of converting a GUID to a string. ```c #define ff_guid_str(guid) ``` -------------------------------- ### Main Function for qt-faststart Utility Source: https://ffmpeg.org/doxygen/8.0/qt-faststart_8c_source.html The main entry point for the qt-faststart utility. It handles command-line arguments, opens input and output files, parses the QuickTime file structure, and rearranges the 'moov' atom. ```c int main(int argc, char *argv[]) { FILE *infile = NULL; FILE *outfile = NULL; unsigned char atom_bytes[ATOM_PREAMBLE_SIZE]; uint32_t atom_type = 0; uint64_t atom_size = 0; uint64_t atom_offset = 0; int64_t last_offset; unsigned char *moov_atom = NULL; unsigned char *ftyp_atom = NULL; uint64_t moov_atom_size; uint64_t ftyp_atom_size = 0; int64_t start_offset = 0; unsigned char *copy_buffer = NULL; int bytes_to_copy; uint64_t free_size = 0; uint64_t moov_size = 0; if (argc != 3) { printf("Usage: qt-faststart \n"); printf("Note: alternatively you can use -movflags +faststart in ffmpeg\n"); return 0; } if (!strcmp(argv[1], argv[2])) { fprintf(stderr, "input and output files need to be different\n"); return 1; } infile = fopen(argv[1], "rb"); if (!infile) { perror(argv[1]); goto error_out; } /* traverse through the atoms in the file to make sure that 'moov' is * at the end */ while (!feof(infile)) { if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) { break; } atom_size = BE_32(&atom_bytes[0]); atom_type = BE_32(&atom_bytes[4]); /* keep ftyp atom */ if (atom_type == FTYP_ATOM) { if (atom_size > MAX_FTYP_ATOM_SIZE) { fprintf(stderr, "ftyp atom size %"PRIu64" too big\n", atom_size); goto error_out; } ftyp_atom_size = atom_size; free(ftyp_atom); ftyp_atom = malloc(ftyp_atom_size); if (!ftyp_atom) { fprintf(stderr, "could not allocate %"PRIu64" bytes for ftyp atom\n", atom_size); goto error_out; } if (fseeko(infile, -ATOM_PREAMBLE_SIZE, SEEK_CUR) || fread(ftyp_atom, atom_size, 1, infile) != 1 || (start_offset = ftello(infile)) < 0) { perror(argv[1]); goto error_out; } } else { int ret; /* 64-bit special case */ if (atom_size == 1) { if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) { break; } atom_size = BE_64(&atom_bytes[0]); ret = fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE * 2, SEEK_CUR); } else { ret = fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE, SEEK_CUR); } if (ret) { perror(argv[1]); goto error_out; } } printf("%c%c%c%c %10"PRIu64" %"PRIu64"\n", (atom_type >> 24) & 255, (atom_type >> 16) & 255, (atom_type >> 8) & 255, (atom_type >> 0) & 255, atom_offset, atom_size); if ((atom_type != FREE_ATOM) && (atom_type != JUNK_ATOM) && (atom_type != MDAT_ATOM) && (atom_type != MOOV_ATOM) && (atom_type != PNOT_ATOM) && (atom_type != SKIP_ATOM) && (atom_type != WIDE_ATOM) && (atom_type != PICT_ATOM) && (atom_type != UUID_ATOM) && (atom_type != FTYP_ATOM)) { fprintf(stderr, "encountered non-QT top-level atom (is this a QuickTime file?)\n"); break; } atom_offset += atom_size; /* The atom header is 8 (or 16 bytes), if the atom size (which * includes these 8 or 16 bytes) is less than that, we won't be * able to continue scanning sensibly after this atom, so break. */ if (atom_size < 8) break; if (atom_type == MOOV_ATOM) moov_size = atom_size; if (moov_size && atom_type == FREE_ATOM) { free_size += atom_size; atom_type = MOOV_ATOM; atom_size = moov_size; } } if (atom_type != MOOV_ATOM) { printf("last atom in file was not a moov atom\n"); free(ftyp_atom); fclose(infile); return 0; } if (atom_size < 16) { fprintf(stderr, "bad moov atom size\n"); goto error_out; } /* moov atom was, in fact, the last atom in the chunk; load the whole * moov atom */ if (fseeko(infile, -(atom_size + free_size), SEEK_END)) { perror(argv[1]); goto error_out; } last_offset = ftello(infile); if (last_offset < 0) { perror(argv[1]); goto error_out; } moov_atom_size = atom_size; moov_atom = malloc(moov_atom_size); if (!moov_atom) { fprintf(stderr, "could not allocate %"PRIu64" bytes for moov atom\n", atom_size); goto error_out; } if (fread(moov_atom, atom_size, 1, infile) != 1) { perror(argv[1]); goto error_out; } /* this utility does not support compressed atoms yet, so disqualify ``` -------------------------------- ### Load DNN Torch Model Source: https://ffmpeg.org/doxygen/8.0/dnn__backend__torch_8cpp.html Loads a DNNModel using the Torch backend, specifying the function type and filter context. This function orchestrates model setup, including starting inference and getting outputs. ```c static DNNModel *dnn_load_model_th(DnnContext *ctx, DNNFunctionType func_type, AVFilterContext *filter_ctx) ``` -------------------------------- ### Example: Opening an H.264 Decoder Source: https://ffmpeg.org/doxygen/8.0/group__lavc__core.html Demonstrates finding an H.264 decoder, allocating a context, and opening it with specific options. Exits on failure. ```c AVDictionary *opts = NULL; AVCodec *codec; AVCodecContext *context; av_dict_set(&opts, "b", "2.5M", 0); codec = avcodec_find_decoder(AV_CODEC_ID_H264); if (!codec) exit(1); context = avcodec_alloc_context3(codec); if (avcodec_open2(context, codec, opts) < 0) exit(1); ``` -------------------------------- ### W64 Muxer: Start GUID Function Source: https://ffmpeg.org/doxygen/8.0/wavenc_8c_source.html Helper function to write a GUID and its associated size placeholder to the AVIOContext for W64 files. It records the starting position for later size updates. ```c static void start_guid(AVIOContext *pb, const uint8_t *guid, int64_t *pos) { *pos = avio_tell(pb); avio_write(pb, guid, 16); avio_wl64(pb, INT64_MAX); } ``` -------------------------------- ### Get GUID Function Source: https://ffmpeg.org/doxygen/8.0/wtvdec_8c_source.html Retrieves a GUID from an AVIOContext. This function is part of the ASF demuxer. ```c int ff_get_guid(AVIOContext *s, ff_asf_guid *g) { return get_guid(s, g); } ``` -------------------------------- ### QSV Transcoding Example Usage Source: https://ffmpeg.org/doxygen/8.0/qsv__transcode_8c_source.html Illustrates the command-line usage for the QSV transcoding example. It shows how to specify input/output files, codec, initial options, and dynamic option changes. ```bash qsv_transcode input_stream codec output_stream initial option { frame_number new_option } e.g: - qsv_transcode input.mp4 h264_qsv output_h264.mp4 "g 60" - qsv_transcode input.mp4 hevc_qsv output_hevc.mp4 "g 60 async_depth 1" 100 "g 120" (initialize codec with gop_size 60 and change it to 120 after 100 frames) ``` -------------------------------- ### FFprobe Initialization and Logging Setup Source: https://ffmpeg.org/doxygen/8.0/ffprobe_8c_source.html This C code snippet shows the initialization of dynamic loading and setting up FFmpeg's logging flags for skipping repeated messages. ```c init_dynload(); setvbuf(stderr, NULL, _IONBF, 0); /* win32 runtime needs this */ av_log_set_flags(AV_LOG_SKIP_REPEATED); ``` -------------------------------- ### Get Codec GUID from AVCodecID Source: https://ffmpeg.org/doxygen/8.0/riffenc_8c_source.html Retrieves the ASF GUID for a given AVCodecID from a provided array of AVCodecGuid structures. Returns NULL if no matching GUID is found. ```c const ff_asf_guid *ff_get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid) { int i; for (i = 0; av_guid[i].id != AV_CODEC_ID_NONE; i++) { if (id == av_guid[i].id) return &(av_guid[i].guid); } return NULL; } ``` -------------------------------- ### Main Function for HW Decoding Example Source: https://ffmpeg.org/doxygen/8.0/hw__decode_8c_source.html Sets up the FFmpeg environment, parses command-line arguments for device type, input, and output files, and initiates the decoding process. ```c int main(int argc, char *argv[]) { AVFormatContext *input_ctx = NULL; int video_stream, ret; AVStream *video = NULL; AVCodecContext *decoder_ctx = NULL; const AVCodec *decoder = NULL; AVPacket *packet = NULL; enum AVHWDeviceType type; int i; if (argc < 4) { fprintf(stderr, "Usage: %s \n", argv[0]); return -1; } type = av_hwdevice_find_type_by_name(argv[1]); if (type == AV_HWDEVICE_TYPE_NONE) { fprintf(stderr, "Device type %s is not supported.\n", argv[1]); fprintf(stderr, "Available device types:"); while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE) fprintf(stderr, " %s", av_hwdevice_get_type_name(type)); fprintf(stderr, "\n"); return -1; } packet = av_packet_alloc(); if (!packet) { fprintf(stderr, "Failed to allocate AVPacket\n"); return -1; } /* open the input file */ if (avformat_open_input(&input_ctx, argv[2], NULL, NULL) != 0) { fprintf(stderr, "Cannot open input file '%s'\n", argv[2]); return -1; } if (avformat_find_stream_info(input_ctx, NULL) < 0) { fprintf(stderr, "Cannot find input stream information.\n"); return -1; } /* find the video stream information */ ret = av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); if (ret < 0) { fprintf(stderr, "Cannot find a video stream in the input file\n"); return -1; } video_stream = ret; for (i = 0;; ``` -------------------------------- ### ff_codec_guid_get_id Source: https://ffmpeg.org/doxygen/8.0/riffdec_8c.html Gets the AVCodecID corresponding to a given GUID. ```APIDOC ## ff_codec_guid_get_id ### Description Maps a GUID to its corresponding AVCodecID using a provided lookup table. ### Method (Not specified, likely a C function call) ### Parameters #### Path Parameters (None specified) #### Query Parameters (None specified) #### Request Body (None specified) ### Request Example (None specified) ### Response #### Success Response - **Return Value** (enum AVCodecID) - The AVCodecID corresponding to the GUID. #### Response Example (None specified) ``` -------------------------------- ### RV34 Get Start Offset Source: https://ffmpeg.org/doxygen/8.0/rv30_8c_source.html Calculates the starting offset for decoding in RV34 streams. This function is used to determine the initial position for decoding. ```c int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size) { Decode starting slice position. ``` -------------------------------- ### Initialize Audio Stream Parameters Source: https://ffmpeg.org/doxygen/8.0/electronicarts_8c_source.html Sets up codec parameters and the audio stream index for the demuxer. ```c st->codecpar->block_align = ea->num_channels * st->codecpar->bits_per_coded_sample; ea->audio_stream_index = st->index; st->start_time = 0; return 0; } no_audio: ea->audio_codec = AV_CODEC_ID_NONE; if (!ea->video.codec) return AVERROR_INVALIDDATA; return 0; } ``` -------------------------------- ### Output Transformation Setup Source: https://ffmpeg.org/doxygen/8.0/vf__v360_8c_source.html Selects the output transformation function based on the specified output format. This example shows the setup for equirectangular output. ```c switch (s->out) { case EQUIRECTANGULAR: s->out_transform = equirect_to_xyz; ``` -------------------------------- ### Install FFmpeg Source: https://ffmpeg.org/doxygen/8.0/md_INSTALL.html Install the built binaries and libraries. ```bash make install ``` -------------------------------- ### Main function for AVIO Directory Listing Example Source: https://ffmpeg.org/doxygen/8.0/avio_list_dir_8c-example.html Sets up logging, parses command-line arguments for the directory path, initializes network components, calls the directory listing operation, and deinitializes network components. Handles basic argument validation and error reporting. ```c int main(int argc, char *argv[]) { int ret; av_log_set_level(AV_LOG_DEBUG); if (argc < 2) { usage(argv[0]); return 1; } avformat_network_init(); ret = list_op(argv[1]); avformat_network_deinit(); return ret < 0 ? 1 : 0; } ``` -------------------------------- ### Start VDPAU Common Frame Source: https://ffmpeg.org/doxygen/8.0/vdpau__vp9_8c_source.html Common function to start processing a frame with VDPAU hardware acceleration. It handles buffer management and context setup. ```c int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic_ctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { return ff_vdpau_common_start_frame(pic_ctx, buffer, size); } ``` -------------------------------- ### Show Bits Example Source: https://ffmpeg.org/doxygen/8.0/agm_8c_source.html Demonstrates how to show a specified number of bits from a GetBitContext. ```c static unsigned int show_bits(GetBitContext *s, int n) Show 1-25 bits. ``` -------------------------------- ### DXVA2 VC1 Start Frame Function Source: https://ffmpeg.org/doxygen/8.0/dxva2__vc1_8c_source.html Initializes the start of a frame for VC1 decoding using DXVA2. This function is part of the hardware acceleration setup. ```c static int dxva2_vc1_start_frame(AVCodecContext *avctx, av_unused const AVBufferRef *buffer_ref, av_unused const uint8_t *buffer, av_unused uint32_t size) ``` -------------------------------- ### Get Start Offset for Macroblock Source: https://ffmpeg.org/doxygen/8.0/rv34_8c_source.html Determines the starting offset for a macroblock based on its size. It selects the appropriate bit size for reading the offset from the bitstream. ```c int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size) { int i; for(i = 0; i < 5; i++) if(rv34_mb_max_sizes[i] >= mb_size - 1) break; return get_bits(gb, rv34_mb_bits_sizes[i]); } ``` -------------------------------- ### Initialize WPP Entry Point Source: https://ffmpeg.org/doxygen/8.0/thread_8c_source.html Copies CABAC state and PP data from an existing entry point to a new one, and initializes static coefficients. ```c static void ep_init_wpp(EntryPoint *next, const EntryPoint *ep, const VVCSPS *sps) { memcpy(next->cabac_state, ep->cabac_state, sizeof(next->cabac_state)); memcpy(next->pp, ep->pp, sizeof(next->pp)); ff_vvc_ep_init_stat_coeff(next, sps->bit_depth, sps->r->sps_persistent_rice_adaptation_enabled_flag); } ``` -------------------------------- ### Get MPEG-TS Payload Start Pointer Source: https://ffmpeg.org/doxygen/8.0/mpegtsenc_8c_source.html Returns a pointer to the start of the payload within an MPEG-TS packet, accounting for the presence and length of an adaptation field. ```c static uint8_t *get_ts_payload_start(uint8_t *pkt) { if (pkt[3] & 0x20) return pkt + 5 + pkt[4]; else return pkt + 4; } ``` -------------------------------- ### QSV Transcode Example Usage Source: https://ffmpeg.org/doxygen/8.0/qsv_transcode_8c-example.html Provides a concrete example of the qsv_transcode command, demonstrating the use of 'g' for gop_size and 'async_depth' as initial options. ```bash qsv_transcode input.mp4 h264_qsv output_h264.mp4 "g 60" ``` -------------------------------- ### Usage message for AVIO Directory Listing Example Source: https://ffmpeg.org/doxygen/8.0/avio_list_dir_8c-example.html Prints the usage instructions for the `avio_list_dir` example program to standard error. Explains the expected command-line argument. ```c static void usage(const char *program_name) { fprintf(stderr, "usage: %s input_dir\n" "API example program to show how to list files in directory " "accessed through AVIOContext.\n", program_name); } ``` -------------------------------- ### RIFF FourCC to AVCodecID Mapping Example Source: https://ffmpeg.org/doxygen/8.0/avformat_8h_source.html Demonstrates how to use RIFF FourCC tables to get the corresponding libavcodec AVCodecID. This example shows mapping for video codecs. ```c uint32_t tag = MKTAG('H', '2', '6', '4'); const struct AVCodecTag *table[] = { avformat_get_riff_video_tags(), 0 }; enum AVCodecID id = av_codec_get_id(table, tag); ``` -------------------------------- ### Main Function: Initialize and Output Media File Source: https://ffmpeg.org/doxygen/8.0/mux_8c-example.html The main function initializes the output media context, adds audio and video streams, and prepares for encoding. It handles command-line arguments for the output filename. ```c /* * media file output */ int main(int argc, char **argv) { OutputStream video_st = { 0 }, audio_st = { 0 }; const AVOutputFormat *fmt; const char *filename; AVFormatContext *oc; const AVCodec *audio_codec, *video_codec; int ret; int have_video = 0, have_audio = 0; int encode_video = 0, encode_audio = 0; AVDictionary *opt = NULL; int i; if (argc < 2) { printf("usage: %s output_file\n" "API example program to output a media file with libavformat.\n" "This program generates a synthetic audio and video stream, encodes and\n" "muxes them into a file named output_file.\n" "The output format is automatically guessed according to the file extension.\n" "Raw images can also be output by using '%%d' in the filename.\n" "\n", argv[0]); return 1; } filename = argv[1]; for (i = 2; i+1 < argc; i+=2) { if (!strcmp(argv[i], "-flags") || !strcmp(argv[i], "-fflags")) av_dict_set(&opt, argv[i]+1, argv[i+1], 0); } /* allocate the output media context */ avformat_alloc_output_context2(&oc, NULL, NULL, filename); if (!oc) { printf("Could not deduce output format from file extension: using MPEG.\n"); avformat_alloc_output_context2(&oc, NULL, "mpeg", filename); } if (!oc) return 1; fmt = oc->oformat; /* Add the audio and video streams using the default format codecs * and initialize the codecs. */ if (fmt->video_codec != AV_CODEC_ID_NONE) { add_stream(&video_st, oc, &video_codec, fmt->video_codec); have_video = 1; encode_video = 1; } if (fmt->audio_codec != AV_CODEC_ID_NONE) { add_stream(&audio_st, oc, &audio_codec, fmt->audio_codec); have_audio = 1; encode_audio = 1; } /* Now that all the parameters are set, we can open the audio and * video codecs and allocate the streams (buffers etc). */ if (have_video) open_video(oc, video_codec, &video_st, opt); if (have_audio) open_audio(oc, audio_codec, &audio_st, opt); av_dict_free(&opt); /* open the output file, if any */ if (avio_open(filename, AVIO_FLAG_WRITE) < 0) { fprintf(stderr, "Could not open '%s': %s\n", filename, av_err2str(ret)); return 1; } /* Write the stream header, if any. */ ret = avformat_write_header(oc, opt); if (ret < 0) { fprintf(stderr, "Error writing stream header: ", av_err2str(ret)); return 1; } /* ... rest of the main function ... */ /* close output file, dummy and remove this */ //avio_close(filename); avformat_free_context(oc); if (have_video) close_stream(oc, &video_st); if (have_audio) close_stream(oc, &audio_st); return 0; } ``` -------------------------------- ### Get DXVA2 Decoder GUID Source: https://ffmpeg.org/doxygen/8.0/dxva2_8c.html Determines and retrieves the appropriate DXVA2 decoder GUID for a given service and configuration. This function selects the best hardware decoder for the current context. ```c static int dxva_get_decoder_guid (AVCodecContext *avctx, void *service, void *surface_format, unsigned guid_count, const GUID *guid_list, GUID *decoder_guid) ``` -------------------------------- ### Main Function Example Source: https://ffmpeg.org/doxygen/8.0/tests_2drawutils_8c.html Entry point for the drawutils test program. Includes necessary headers for pixel description and drawing utilities. ```c #include #include "libavutil/pixdesc.h" #include "libavfilter/drawutils.h" int main (void) ``` -------------------------------- ### Setup Frame Dimensions and Tile Starts Source: https://ffmpeg.org/doxygen/8.0/vulkan__av1_8c_source.html Populates arrays for frame width, height, and tile start columns/rows in units of superblocks. This is essential for tiling and resolution handling in AV1 decoding. ```c for (int i = 0; i < 64; i++) { ap->width_in_sbs_minus1[i] = frame_header->width_in_sbs_minus1[i]; ap->height_in_sbs_minus1[i] = frame_header->height_in_sbs_minus1[i]; ap->mi_col_starts[i] = frame_header->tile_start_col_sb[i]; ap->mi_row_starts[i] = frame_header->tile_start_row_sb[i]; } ``` -------------------------------- ### Get Relative Time Function Source: https://ffmpeg.org/doxygen/8.0/fifo__muxer_8c_source.html Retrieves the current time in microseconds relative to an unspecified starting point. ```c int64_t av_gettime_relative(void) Get the current time in microseconds since some unspecified starting point. ``` -------------------------------- ### Main Function: Setting up AVIOContext and Reading Input Source: https://ffmpeg.org/doxygen/8.0/avio__read__callback_8c_source.html The main function demonstrates the complete process of setting up an AVIOContext with a custom read callback. It maps a file into memory, initializes the AVIOContext, and then uses libavformat functions to open the input and find stream information. Error handling and resource cleanup are included. ```c #include #include #include #include #include struct buffer_data { uint8_t *ptr; size_t size; ///< size left in the buffer }; int main(int argc, char *argv[]) { AVFormatContext *fmt_ctx = NULL; AVIOContext *avio_ctx = NULL; uint8_t *buffer = NULL, *avio_ctx_buffer = NULL; size_t buffer_size, avio_ctx_buffer_size = 4096; char *input_filename = NULL; int ret = 0; struct buffer_data bd = { 0 }; if (argc != 2) { fprintf(stderr, "usage: %s input_file\n" "API example program to show how to read from a custom buffer " "accessed through AVIOContext.\n", argv[0]); return 1; } input_filename = argv[1]; /* slurp file content into buffer */ ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL); if (ret < 0) goto end; /* fill opaque structure used by the AVIOContext read callback */ bd.ptr = buffer; bd.size = buffer_size; if (!(fmt_ctx = avformat_alloc_context())) { ret = AVERROR(ENOMEM); goto end; } avio_ctx_buffer = av_malloc(avio_ctx_buffer_size); if (!avio_ctx_buffer) { ret = AVERROR(ENOMEM); goto end; } avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, &bd, &read_packet, NULL, NULL); if (!avio_ctx) { av_freep(&avio_ctx_buffer); ret = AVERROR(ENOMEM); goto end; } fmt_ctx->pb = avio_ctx; ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL); if (ret < 0) { fprintf(stderr, "Could not open input\n"); goto end; } ret = avformat_find_stream_info(fmt_ctx, NULL); if (ret < 0) { fprintf(stderr, "Could not find stream information\n"); goto end; } av_dump_format(fmt_ctx, 0, input_filename, 0); end: avformat_close_input(&fmt_ctx); /* note: the internal buffer could have changed, and be != avio_ctx_buffer */ if (avio_ctx) av_freep(&avio_ctx->buffer); avio_context_free(&avio_ctx); av_file_unmap(buffer, buffer_size); if (ret < 0) { fprintf(stderr, "Error occurred: %s\n", av_err2str(ret)); return 1; } return 0; } ``` -------------------------------- ### Example: Opening Codec Context from AVCodecParameters Source: https://ffmpeg.org/doxygen/8.0/group__lavc__core.html Shows how to initialize a codec context using AVCodecParameters, typically obtained from demuxing a stream. The codec parameters are copied to the context before opening. ```c AVStream *stream = ...; AVCodecContext *context; AVCodec *codec; context = avcodec_alloc_context3(codec); if (avcodec_parameters_to_context(context, stream->codecpar) < 0) exit(1); if (avcodec_open2(context, codec, NULL) < 0) exit(1); ``` -------------------------------- ### Get Relative Time in Microseconds (Monotonic Clock) Source: https://ffmpeg.org/doxygen/8.0/time_8c_source.html Gets the current time in microseconds using a monotonic clock source if available. This time is relative to an unspecified starting point and is suitable for measuring time intervals. ```c int64_t av_gettime_relative(void) { #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) #ifdef __APPLE__ if (&clock_gettime) #endif { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (int64_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; } #endif return av_gettime() + 42 * 60 * 60 * INT64_C(1000000); } ``` -------------------------------- ### QSV Encoder Initialization and Parameter Setup Source: https://ffmpeg.org/doxygen/8.0/qsvenc_8c_source.html This C code snippet demonstrates the initialization of the QSV encoder, including copying external parameters, handling hardware acceleration contexts, and setting encoding parameters using MFX API calls. It prepares the encoder for operation based on codec and user-defined parameters. ```c memcpy(q->extparam, q->extparam_internal, q->nb_extparam * sizeof(*q->extparam)); if (avctx->hwaccel_context) { AVQSVContext *qsv = avctx->hwaccel_context; int i, j; for (i = 0; i < qsv->nb_ext_buffers; i++) { for (j = 0; j < q->nb_extparam_internal; j++) { if (qsv->ext_buffers[i]->BufferId == q->extparam_internal[j]->BufferId) { q->extparam[j] = qsv->ext_buffers[i]; break; } } if (j == q->nb_extparam_internal) { tmp = av_realloc_array(q->extparam, q->nb_extparam + 1, sizeof(*q->extparam)); if (!tmp) return AVERROR(ENOMEM); q->extparam = tmp; q->extparam[q->nb_extparam++] = qsv->ext_buffers[i]; } } } q->param.ExtParam = q->extparam; q->param.NumExtParam = q->nb_extparam; #if HAVE_STRUCT_MFXCONFIGINTERFACE ret = MFXVideoCORE_GetHandle(q->session, MFX_HANDLE_CONFIG_INTERFACE, (mfxHDL *)(&iface)); if (ret < 0) return ff_qsv_print_error(avctx, ret, "Error getting mfx config interface handle"); while ((param = av_dict_get(q->qsv_params, "", param, AV_DICT_IGNORE_SUFFIX))) { const char *param_key = param->key; const char *param_value = param->value; mfxExtBuffer *new_ext_buf; void *tmp; av_log(avctx, AV_LOG_VERBOSE, "Parameter key: %s, value: %s\n", param_key, param_value); // Set encoding parameters using MFXSetParameter for (int i = 0; i < 2; i++) { ret = iface->SetParameter(iface, (mfxU8*)param_key, (mfxU8*)param_value, MFX_STRUCTURE_TYPE_VIDEO_PARAM, &q->param, &ext_buf); if (ret == MFX_ERR_NONE) { break; } else if (i == 0 && ret == MFX_ERR_MORE_EXTBUFFER) { tmp = av_realloc_array(q->extparam_str, q->nb_extparam_str + 1, sizeof(*q->extparam_str)); if (!tmp) return AVERROR(ENOMEM); q->extparam_str = tmp; tmp = av_realloc_array(q->extparam, q->nb_extparam + 1, sizeof(*q->extparam)); if (!tmp) return AVERROR(ENOMEM); q->extparam = tmp; new_ext_buf = (mfxExtBuffer*)av_mallocz(ext_buf.BufferSz); if (!new_ext_buf) return AVERROR(ENOMEM); new_ext_buf->BufferId = ext_buf.BufferId; new_ext_buf->BufferSz = ext_buf.BufferSz; q->extparam_str[q->nb_extparam_str++] = new_ext_buf; q->extparam[q->nb_extparam++] = new_ext_buf; q->param.ExtParam = q->extparam; q->param.NumExtParam = q->nb_extparam; } else { av_log(avctx, AV_LOG_ERROR, "Failed to set parameter: %s\n", param_key); return AVERROR_UNKNOWN; } } } #else if (q->qsv_params) { av_log(avctx, AV_LOG_WARNING, "MFX string API is not supported, ignore qsv_params option\n"); } #endif ret = MFXVideoENCODE_Query(q->session, &q->param, &q->param); if (ret == MFX_WRN_PARTIAL_ACCELERATION) { av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n"); } else if (ret < 0) { return ff_qsv_print_error(avctx, ret, "Error querying encoder params"); } ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req); if (ret < 0) return ff_qsv_print_error(avctx, ret, "Error querying (IOSurf) the encoding parameters"); if (opaque_alloc) { #if QSV_HAVE_OPAQUE ret = qsv_init_opaque_alloc(avctx, q); if (ret < 0) return ret; #else av_log(avctx, AV_LOG_ERROR, "User is requesting to allocate OPAQUE surface, " "however libmfx %d.%d doesn't support OPAQUE memory.\n", q->ver.Major, q->ver.Minor); return AVERROR_UNKNOWN; #endif } ret = MFXVideoENCODE_Init(q->session, &q->param); if (ret < 0) return ff_qsv_print_error(avctx, ret, "Error initializing the encoder"); else if (ret > 0) ff_qsv_print_warning(avctx, ret, "Warning in encoder initialization"); switch (avctx->codec_id) { case AV_CODEC_ID_MJPEG: ret = qsv_retrieve_enc_jpeg_params(avctx, q); break; case AV_CODEC_ID_VP9: ret = qsv_retrieve_enc_vp9_params(avctx, q); break; case AV_CODEC_ID_AV1: ret = qsv_retrieve_enc_av1_params(avctx, q); break; default: ret = qsv_retrieve_enc_params(avctx, q); break; } if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n"); return ret; } q->avctx = avctx; return 0; ``` -------------------------------- ### vk_av1_start_frame Function Source: https://ffmpeg.org/doxygen/8.0/vulkan__av1_8c.html Static function to start decoding a frame for AV1 with Vulkan. It is part of the hardware acceleration setup. ```c static int vk_av1_start_frame(AVCodecContext *avctx, av_unused const AVBufferRef *buffer_ref, av_unused const uint8_t *buffer, av_unused uint32_t size) ``` -------------------------------- ### Configure FFmpeg Source: https://ffmpeg.org/doxygen/8.0/md_INSTALL.html Run the configure script to set up the build environment. Use 'configure --help' for a list of options. Building out of tree is supported by providing an absolute path. ```bash ./configure ``` ```bash /ffmpegdir/ffmpeg/configure ``` -------------------------------- ### Get Current Position in PutByteContext Source: https://ffmpeg.org/doxygen/8.0/bytestream_8h_source.html Returns the current write position within the PutByteContext relative to the start of the buffer. ```c static av_always_inline int bytestream2_tell_p(const PutByteContext *p) { return (int)(p->buffer - p->buffer_start); } ``` -------------------------------- ### Get Next NAL Unit Source: https://ffmpeg.org/doxygen/8.0/hls__sample__encryption_8c_source.html Parses the buffer to find the next Network Abstraction Layer (NAL) unit. It identifies the start code and extracts the NAL unit data and type. Handles both 3 and 4-byte start codes. ```c static int get_next_nal_unit(CodecParserContext *ctx, NALUnit *nalu) { const uint8_t *nalu_start = ctx->buf_ptr; if (ctx->buf_end - ctx->buf_ptr >= 4 && AV_RB32(ctx->buf_ptr) == 0x00000001) nalu->start_code_length = 4; else if (ctx->buf_end - ctx->buf_ptr >= 3 && AV_RB24(ctx->buf_ptr) == 0x000001) nalu->start_code_length = 3; else /* No start code at the beginning of the NAL unit */ return -1; ctx->buf_ptr += nalu->start_code_length; while (ctx->buf_ptr < ctx->buf_end) { if (ctx->buf_end - ctx->buf_ptr >= 4 && AV_RB32(ctx->buf_ptr) == 0x00000001) break; else if (ctx->buf_end - ctx->buf_ptr >= 3 && AV_RB24(ctx->buf_ptr) == 0x000001) break; cxtx->buf_ptr++; } nalu->data = (uint8_t *)nalu_start + nalu->start_code_length; nalu->length = ctx->buf_ptr - nalu->data; nalu->type = *nalu->data & 0x1F; return 0; } ``` -------------------------------- ### Main Function for Video Encoding Source: https://ffmpeg.org/doxygen/8.0/encode_video_8c-example.html This is the main entry point for the video encoding example. It initializes the codec, sets up encoding parameters, allocates necessary structures, and drives the encoding process for a specified duration. Ensure the correct codec name is provided as a command-line argument. ```c int main(int argc, char **argv) { const char *filename, *codec_name; const AVCodec *codec; AVCodecContext *c= NULL; int i, ret, x, y; FILE *f; AVFrame *frame; AVPacket *pkt; uint8_t endcode[] = { 0, 0, 1, 0xb7 }; if (argc <= 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(0); } filename = argv[1]; codec_name = argv[2]; /* find the mpeg1video encoder */ codec = avcodec_find_encoder_by_name(codec_name); if (!codec) { fprintf(stderr, "Codec '%s' not found\n", codec_name); exit(1); } c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate video codec context\n"); exit(1); } pkt = av_packet_alloc(); if (!pkt) exit(1); /* put sample parameters */ c->bit_rate = 400000; /* resolution must be a multiple of two */ c->width = 352; c->height = 288; /* frames per second */ c->time_base = (AVRational){1, 25}; c->framerate = (AVRational){25, 1}; /* emit one intra frame every ten frames * check frame pict_type before passing frame * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I * then gop_size is ignored and the output of encoder * will always be I frame irrespective to gop_size */ c->gop_size = 10; c->max_b_frames = 1; c->pix_fmt = AV_PIX_FMT_YUV420P; if (codec->id == AV_CODEC_ID_H264) av_opt_set(c->priv_data, "preset", "slow", 0); /* open it */ ret = avcodec_open2(c, codec, NULL); if (ret < 0) { fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret)); exit(1); } f = fopen(filename, "wb"); if (!f) { fprintf(stderr, "Could not open %s\n", filename); exit(1); } frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "Could not allocate video frame\n"); exit(1); } frame->format = c->pix_fmt; frame->width = c->width; frame->height = c->height; ret = av_frame_get_buffer(frame, 0); if (ret < 0) { fprintf(stderr, "Could not allocate the video frame data\n"); exit(1); } /* encode 1 second of video */ for (i = 0; i < 25; i++) { fflush(stdout); /* Make sure the frame data is writable. * On the first round, the frame is fresh from av_frame_get_buffer() * and therefore we know it is writable. * But on the next rounds, encode() will have called * avcodec_send_frame(), and the codec may have kept a reference to * the frame in its internal structures, that makes the frame * unwritable. * av_frame_make_writable() checks that and allocates a new buffer * for the frame only if necessary. */ ret = av_frame_make_writable(frame); if (ret < 0) exit(1); /* Prepare a dummy image. * In real code, this is where you would have your own logic for * filling the frame. FFmpeg does not care what you put in the * frame. */ /* Y */ for (y = 0; y < c->height; y++) { for (x = 0; x < c->width; x++) { frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3; } } /* Cb and Cr */ for (y = 0; y < c->height/2; y++) { for (x = 0; x < c->width/2; x++) { frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2; frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5; } } frame->pts = i; /* encode the image */ encode(c, frame, pkt, f); } /* flush the encoder */ encode(c, NULL, pkt, f); /* Add sequence end code to have a real MPEG file. * It makes only sense because this tiny examples writes packets * directly. This is called "elementary stream" and only works for some * codecs. To create a valid file, you usually need to write packets * into a proper file format or protocol; see mux.c. */ if (codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO) fwrite(endcode, 1, sizeof(endcode), f); fclose(f); avcodec_free_context(&c); av_frame_free(&frame); av_packet_free(&pkt); return 0; } ``` -------------------------------- ### WTV Probe Function Source: https://ffmpeg.org/doxygen/8.0/wtvdec_8c_source.html Implements the probe function for WTV files, returning AVPROBE_SCORE_MAX if the buffer starts with the WTV GUID. ```c static int read_probe(const AVProbeData *p) { return ff_guidcmp(p->buf, ff_wtv_guid) ? 0 : AVPROBE_SCORE_MAX; } ``` -------------------------------- ### Function setup_find_stream_info_opts Source: https://ffmpeg.org/doxygen/8.0/cmdutils_8c_source.html Sets up AVCodecContext options for avformat_find_stream_info. ```c int setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *local_codec_opts, AVDictionary ***dst) ``` -------------------------------- ### Get Hardware Device by Type Source: https://ffmpeg.org/doxygen/8.0/ffmpeg__hw_8c.html Retrieves a hardware device based on its type. This function is referenced by other device setup functions. ```c #include #include "libavutil/mem.h" #include "ffmpeg.h" HWDevice * hw_device_get_by_type (enum AVHWDeviceType type) ```