diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..206e887 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: go + +go: + - tip + +script: go test -v ./ \ No newline at end of file diff --git a/README.md b/README.md index 6c73d48..56e0568 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,47 @@ -# goav +# goav [![Build Status](https://travis-ci.org/giorgisio/goav.svg?branch=master)](https://travis-ci.org/giorgisio/goav) Golang bindings for FFmpeg + +## Notice +goav comes with ABSOLUTELY NO WARRANTY. + +## Installation +go get github.com/giorgisio/goav + +export FFMPEG_ROOT=$HOME/ffmpeg +export CGO_LDFLAGS="-L$FFMPEG_ROOT/lib/ -lavcodec -lavformat -lavutil -lswscale -lswresample -lavdevice -lavfilter" +export CGO_CFLAGS="-I$FFMPEG_ROOT/include" +export LD_LIBRARY_PATH=$HOME/ffmpeg/lib + +## Usage + +`````go + +import "github.com/giorgisio/gfg/avformat" + +func main() { + + filename := "/home/giorgis/media/sample2.mp4" + + // Register all formats and codecs + avformat.Av_register_all() + + if avformat.Avformat_open_input(&pFormatCtx, filename, nil, nil) != 0 { + return + } + + //... + +} +````` + +## TODO + +- [ ] Errors +- [ ] Tests +- [ ] Review library methods +- [ ] Possible restructuring packages +- [x] Tutorial01.c +- [ ] More Tutorial + +## License +This library is under the [MIT License](http://opensource.org/licenses/MIT) \ No newline at end of file diff --git a/avcodec/avcodec.go b/avcodec/avcodec.go new file mode 100644 index 0000000..5a87429 --- /dev/null +++ b/avcodec/avcodec.go @@ -0,0 +1,707 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) + + The codecs (decoders and encoders) provided by the libavcodec library + libavcodec provides some generic global options, which can be set on all the encoders and decoders. +*/ +package avcodec + +//#cgo pkg-config: libavformat libavcodec libavutil libswresample +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +import "C" +import ( + "unsafe" +) + +type ( + AVCodecDescriptor C.struct_AVCodecDescriptor + RcOverride C.struct_RcOverride + AVPanScan C.struct_AVPanScan + AVPacketSideData C.struct_AVPacketSideData + AVPacket C.struct_AVPacket + AVCodecContext C.struct_AVCodecContext + AVProfile C.struct_AVProfile + AVCodec C.struct_AVCodec + AVHWAccel C.struct_AVHWAccel + AVPicture C.struct_AVPicture + AVSubtitleRect C.struct_AVSubtitleRect + AVSubtitle C.struct_AVSubtitle + AVCodecParserContext C.struct_AVCodecParserContext + AVCodecParser C.struct_AVCodecParser + AVBitStreamFilterContext C.struct_AVBitStreamFilterContext + AVBitStreamFilter C.struct_AVBitStreamFilter + AVRational C.struct_AVRational + AVDictionary C.struct_AVDictionary + AVClass C.struct_AVClass + AVFrame C.struct_AVFrame +) + +type ( + AVPixelFormat C.enum_AVPixelFormat + AVChromaLocation C.enum_AVChromaLocation + AVPacketSideDataType C.enum_AVPacketSideDataType + AVSampleFormat C.enum_AVSampleFormat + AVMediaType C.enum_AVMediaType + AVCodecID C.enum_AVCodecID +) + +//AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx) +func Av_codec_get_pkt_timebase(ctxt *AVCodecContext) AVRational { + return (AVRational)(C.av_codec_get_pkt_timebase((*C.struct_AVCodecContext)(ctxt))) +} + +//void av_codec_set_pkt_timebase (AVCodecContext *avctx, AVRational val) +func Av_codec_set_pkt_timebase(ctxt *AVCodecContext, r AVRational) { + C.av_codec_set_pkt_timebase((*C.struct_AVCodecContext)(ctxt), (C.struct_AVRational)(r)) +} + +//const AVCodecDescriptor * av_codec_get_codec_descriptor (const AVCodecContext *avctx) +func Av_codec_get_codec_descriptor(ctxt *AVCodecContext) *AVCodecDescriptor { + return (*AVCodecDescriptor)(C.av_codec_get_codec_descriptor((*C.struct_AVCodecContext)(ctxt))) +} + +//void av_codec_set_codec_descriptor (AVCodecContext *avctx, const AVCodecDescriptor *desc) +func Av_codec_set_codec_descriptor(ctxt *AVCodecContext, d *AVCodecDescriptor) { + C.av_codec_set_codec_descriptor((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVCodecDescriptor)(d)) +} + +//int av_codec_get_lowres (const AVCodecContext *avctx) +func Av_codec_get_lowres(ctxt *AVCodecContext) int { + return int(C.av_codec_get_lowres((*C.struct_AVCodecContext)(ctxt))) +} + +//void av_codec_set_lowres (AVCodecContext *avctx, int val) +func Av_codec_set_lowres(ctxt *AVCodecContext, i int) { + C.av_codec_set_lowres((*C.struct_AVCodecContext)(ctxt), C.int(i)) +} + +//int av_codec_get_seek_preroll (const AVCodecContext *avctx) +func Av_codec_get_seek_preroll(ctxt *AVCodecContext) int { + return int(C.av_codec_get_seek_preroll((*C.struct_AVCodecContext)(ctxt))) +} + +//void av_codec_set_seek_preroll (AVCodecContext *avctx, int val) +func Av_codec_set_seek_preroll(ctxt *AVCodecContext, i int) { + C.av_codec_set_seek_preroll((*C.struct_AVCodecContext)(ctxt), C.int(i)) +} + +//uint16_t *av_codec_get_chroma_intra_matrix (const AVCodecContext *avctx) +func Av_codec_get_chroma_intra_matrix(ctxt *AVCodecContext) *uint16 { + return (*uint16)(C.av_codec_get_chroma_intra_matrix((*C.struct_AVCodecContext)(ctxt))) +} + +//void av_codec_set_chroma_intra_matrix (AVCodecContext *avctx, uint16_t *val) +func Av_codec_set_chroma_intra_matrix(ctxt *AVCodecContext, t *uint16) { + C.av_codec_set_chroma_intra_matrix((*C.struct_AVCodecContext)(ctxt), (*C.uint16_t)(t)) +} + +//int av_codec_get_max_lowres (const AVCodec *codec) +func Av_codec_get_max_lowres(c *AVCodec) int { + return int(C.av_codec_get_max_lowres((*C.struct_AVCodec)(c))) +} + +//If c is NULL, returns the first registered codec, if c is non-NULL, +//returns the next registered codec after c, or NULL if c is the last one. +//AVCodec *av_codec_next (const AVCodec *c) +func Av_codec_next(c *AVCodec) *AVCodec { + return (*AVCodec)(C.av_codec_next((*C.struct_AVCodec)(c))) +} + +//Return the LIBAVCODEC_VERSION_INT constant. +//unsigned avcodec_version (void) +func Avcodec_version() uint { + return uint(C.avcodec_version()) +} + +//Return the libavcodec build-time configuration. +//const char *avcodec_configuration (void) +func Avcodec_configuration() string { + return C.GoString(C.avcodec_configuration()) + +} + +//Return the libavcodec license. +//const char *avcodec_license (void) +func Avcodec_license() string { + return C.GoString(C.avcodec_license()) +} + +//Register the codec codec and initialize libavcodec. +//void avcodec_register (AVCodec *codec) +func Avcodec_register(c *AVCodec) { + C.avcodec_register((*C.struct_AVCodec)(c)) +} + +//Register all the codecs, parsers and bitstream filters which were enabled at configuration time. +//void avcodec_register_all (void) +func Avcodec_register_all() { + C.avcodec_register_all() +} + +//Allocate an AVCodecContext and set its fields to default values. +//AVCodecContext *avcodec_alloc_context3 (const AVCodec *codec) +func Avcodec_alloc_context3(c *AVCodec) *AVCodecContext { + return (*AVCodecContext)(C.avcodec_alloc_context3((*C.struct_AVCodec)(c))) +} + +//Free the codec context and everything associated with it and write NULL to the provided pointer. +//void avcodec_free_context (AVCodecContext **avctx) +func Avcodec_free_context(ctxt **AVCodecContext) { + C.avcodec_free_context((**C.struct_AVCodecContext)(unsafe.Pointer(ctxt))) +} + +//Set the fields of the given AVCodecContext to default values corresponding to the given codec (defaults may be codec-dependent). +//int avcodec_get_context_defaults3 (AVCodecContext *s, const AVCodec *codec) +func Avcodec_get_context_defaults3(ctxt *AVCodecContext, c *AVCodec) int { + return int(C.avcodec_get_context_defaults3((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVCodec)(c))) +} + +//Get the AVClass for AVCodecContext. +//const AVClass *avcodec_get_class (void) +func Avcodec_get_class() *AVClass { + return (*AVClass)(C.avcodec_get_class()) +} + +//Get the AVClass for AVFrame. +//const AVClass *avcodec_get_frame_class (void) +func Avcodec_get_frame_class() *AVClass { + return (*AVClass)(C.avcodec_get_frame_class()) +} + +//Get the AVClass for AVSubtitleRect. +//const AVClass *avcodec_get_subtitle_rect_class (void) +func Avcodec_get_subtitle_rect_class() *AVClass { + return (*AVClass)(C.avcodec_get_subtitle_rect_class()) +} + +//Copy the settings of the source AVCodecContext into the destination AVCodecContext. +//int avcodec_copy_context (AVCodecContext *dest, const AVCodecContext *src) +func Avcodec_copy_context(ctxt, ctxt2 *AVCodecContext) int { + return int(C.avcodec_copy_context((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVCodecContext)(ctxt2))) +} + +//Initialize the AVCodecContext to use the given AVCodec +//int avcodec_open2 (AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) +func Avcodec_open2(ctxt *AVCodecContext, c *AVCodec, d **AVDictionary) int { + return int(C.avcodec_open2((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVCodec)(c), (**C.struct_AVDictionary)(unsafe.Pointer(d)))) +} + +//Close a given AVCodecContext and free all the data associated with it (but not the AVCodecContext itself). +//int avcodec_close (AVCodecContext *avctx) +func Avcodec_close(ctxt *AVCodecContext) int { + return int(C.avcodec_close((*C.struct_AVCodecContext)(ctxt))) +} + +//Free all allocated data in the given subtitle struct. +//void avsubtitle_free (AVSubtitle *sub) +func Avsubtitle_free(s *AVSubtitle) { + C.avsubtitle_free((*C.struct_AVSubtitle)(s)) +} + +//Initialize optional fields of a packet with default values. +//void av_init_packet (AVPacket *pkt) +func Av_init_packet(p *AVPacket) { + C.av_init_packet((*C.struct_AVPacket)(p)) +} + +//Allocate the payload of a packet and initialize its fields with default values. +//int av_new_packet (AVPacket *pkt, int size) +func Av_new_packet(p *AVPacket, s int) int { + return int(C.av_new_packet((*C.struct_AVPacket)(p), C.int(s))) +} + +//Reduce packet size, correctly zeroing padding. +//void av_shrink_packet (AVPacket *pkt, int size) +func Av_shrink_packet(p *AVPacket, s int) { + C.av_shrink_packet((*C.struct_AVPacket)(p), C.int(s)) +} + +//Increase packet size, correctly zeroing padding. +//int av_grow_packet (AVPacket *pkt, int grow_by) +func Av_grow_packet(p *AVPacket, s int) int { + return int(C.av_grow_packet((*C.struct_AVPacket)(p), C.int(s))) +} + +//Initialize a reference-counted packet from av_malloc()ed data. +//int av_packet_from_data (AVPacket *pkt, uint8_t *data, int size) +func Av_packet_from_data(p *AVPacket, d *uint8, s int) int { + return int(C.av_packet_from_data((*C.struct_AVPacket)(p), (*C.uint8_t)(d), C.int(s))) + +} + +//int av_dup_packet (AVPacket *pkt) +func Av_dup_packet(p *AVPacket) int { + return int(C.av_dup_packet((*C.struct_AVPacket)(p))) + +} + +//Copy packet, including contents. +//int av_copy_packet (AVPacket *dst, const AVPacket *src) +func Av_copy_packet(p, r *AVPacket) int { + return int(C.av_copy_packet((*C.struct_AVPacket)(p), (*C.struct_AVPacket)(r))) + +} + +//Copy packet side data. +//int av_copy_packet_side_data (AVPacket *dst, const AVPacket *src) +func Av_copy_packet_side_data(p, r *AVPacket) int { + return int(C.av_copy_packet_side_data((*C.struct_AVPacket)(p), (*C.struct_AVPacket)(r))) + +} + +//Free a packet. +//void av_free_packet (AVPacket *pkt) +func Av_free_packet(p *AVPacket) { + C.av_free_packet((*C.struct_AVPacket)(p)) + +} + +//Allocate new information of a packet. +//uint8_t *av_packet_new_side_data (AVPacket *pkt, enum AVPacketSideDataType type, int size) +func Av_packet_new_side_data(p *AVPacket, t AVPacketSideDataType, s int) *uint8 { + return (*uint8)(C.av_packet_new_side_data((*C.struct_AVPacket)(p), (C.enum_AVPacketSideDataType)(t), C.int(s))) +} + +//Shrink the already allocated side data buffer. +//int av_packet_shrink_side_data (AVPacket *pkt, enum AVPacketSideDataType type, int size) +func Av_packet_shrink_side_data(p *AVPacket, t AVPacketSideDataType, s int) int { + return int(C.av_packet_shrink_side_data((*C.struct_AVPacket)(p), (C.enum_AVPacketSideDataType)(t), C.int(s))) +} + +//Get side information from packet. +//uint8_t *av_packet_get_side_data (AVPacket *pkt, enum AVPacketSideDataType type, int *size) +func Av_packet_get_side_data(p *AVPacket, t AVPacketSideDataType, s *int) *uint8 { + return (*uint8)(C.av_packet_get_side_data((*C.struct_AVPacket)(p), (C.enum_AVPacketSideDataType)(t), (*C.int)(unsafe.Pointer(s)))) +} + +//int av_packet_merge_side_data (AVPacket *pkt) +func Av_packet_merge_side_data(p *AVPacket) int { + return int(C.av_packet_merge_side_data((*C.struct_AVPacket)(p))) +} + +//int av_packet_split_side_data (AVPacket *pkt) +func Av_packet_split_side_data(p *AVPacket) int { + return int(C.av_packet_split_side_data((*C.struct_AVPacket)(p))) +} + +//const char *av_packet_side_data_name (enum AVPacketSideDataType type) +func Av_packet_side_data_name(t AVPacketSideDataType) string { + return C.GoString(C.av_packet_side_data_name((C.enum_AVPacketSideDataType)(t))) +} + +//Pack a dictionary for use in side_data. +//uint8_t *av_packet_pack_dictionary (AVDictionary *dict, int *size) +func Av_packet_pack_dictionary(d *AVDictionary, s *int) *uint8 { + return (*uint8)(C.av_packet_pack_dictionary((*C.struct_AVDictionary)(d), (*C.int)(unsafe.Pointer(s)))) +} + +//Unpack a dictionary from side_data. +//int av_packet_unpack_dictionary (const uint8_t *data, int size, AVDictionary **dict) +func Av_packet_unpack_dictionary(d *uint8, s int, dt **AVDictionary) int { + return int(C.av_packet_unpack_dictionary((*C.uint8_t)(d), C.int(s), (**C.struct_AVDictionary)(unsafe.Pointer(dt)))) +} + +//Convenience function to free all the side data stored. +//void av_packet_free_side_data (AVPacket *pkt) +func Av_packet_free_side_data(p *AVPacket) { + C.av_packet_free_side_data((*C.struct_AVPacket)(p)) +} + +//Setup a new reference to the data described by a given packet. +//int av_packet_ref (AVPacket *dst, const AVPacket *src) +func Av_packet_ref(p, s *AVPacket) int { + return int(C.av_packet_ref((*C.struct_AVPacket)(p), (*C.struct_AVPacket)(s))) +} + +//Wipe the packet. +//void av_packet_unref (AVPacket *pkt) +func Av_packet_unref(p *AVPacket) { + C.av_packet_unref((*C.struct_AVPacket)(p)) +} + +//Move every field in src to dst and reset src. +//void av_packet_move_ref (AVPacket *dst, AVPacket *src) +func Av_packet_move_ref(p, s *AVPacket) { + C.av_packet_move_ref((*C.struct_AVPacket)(p), (*C.struct_AVPacket)(s)) +} + +//Copy only "properties" fields from src to dst. +//int av_packet_copy_props (AVPacket *dst, const AVPacket *src) +func Av_packet_copy_props(p, s *AVPacket) int { + return int(C.av_packet_copy_props((*C.struct_AVPacket)(p), (*C.struct_AVPacket)(s))) +} + +//Convert valid timing fields (timestamps / durations) in a packet from one timebase to another. +//void av_packet_rescale_ts (AVPacket *pkt, AVRational tb_src, AVRational tb_dst) +func Av_packet_rescale_ts(p *AVPacket, r, r2 AVRational) { + C.av_packet_rescale_ts((*C.struct_AVPacket)(p), (C.struct_AVRational)(r), (C.struct_AVRational)(r2)) +} + +//Find a registered decoder with a matching codec ID. +//AVCodec *avcodec_find_decoder (enum AVCodecID id) +func Avcodec_find_decoder(id AVCodecID) *AVCodec { + return (*AVCodec)(C.avcodec_find_decoder((C.enum_AVCodecID)(id))) +} + +//Find a registered decoder with the specified name. +//AVCodec *avcodec_find_decoder_by_name (const char *name) +func Avcodec_find_decoder_by_name(n string) *AVCodec { + return (*AVCodec)(C.avcodec_find_decoder_by_name(C.CString(n))) +} + +//The default callback for AVCodecContext.get_buffer2(). +//int avcodec_default_get_buffer2 (AVCodecContext *s, AVFrame *frame, int flags) +func Avcodec_default_get_buffer2(s *AVCodecContext, f *AVFrame, l int) int { + return int(C.avcodec_default_get_buffer2((*C.struct_AVCodecContext)(s), (*C.struct_AVFrame)(f), C.int(l))) +} + +//Modify width and height values so that they will result in a memory buffer that is acceptable for the codec if you do not use any horizontal padding. +//void avcodec_align_dimensions (AVCodecContext *s, int *width, int *height) +func Avcodec_align_dimensions(ctxt *AVCodecContext, w, h *int) { + C.avcodec_align_dimensions((*C.struct_AVCodecContext)(ctxt), (*C.int)(unsafe.Pointer(w)), (*C.int)(unsafe.Pointer(h))) +} + +//Modify width and height values so that they will result in a memory buffer that is acceptable for the codec if you also ensure that all line sizes are a multiple of the respective linesize_align[i]. +//void avcodec_align_dimensions2 (AVCodecContext *s, int *width, int *height, int linesize_align[AV_NUM_DATA_POINTERS]) +func Avcodec_align_dimensions2(ctxt *AVCodecContext, w, h *int, l int) { + C.avcodec_align_dimensions2((*C.struct_AVCodecContext)(ctxt), (*C.int)(unsafe.Pointer(w)), (*C.int)(unsafe.Pointer(h)), (*C.int)(unsafe.Pointer(&l))) +} + +//Converts AVChromaLocation to swscale x/y chroma position. +//int avcodec_enum_to_chroma_pos (int *xpos, int *ypos, enum AVChromaLocation pos) +func Avcodec_enum_to_chroma_pos(x, y *int, l AVChromaLocation) int { + return int(C.avcodec_enum_to_chroma_pos((*C.int)(unsafe.Pointer(x)), (*C.int)(unsafe.Pointer(y)), (C.enum_AVChromaLocation)(l))) +} + +//Converts swscale x/y chroma position to AVChromaLocation. +//enum AVChromaLocation avcodec_chroma_pos_to_enum (int xpos, int ypos) +func Avcodec_chroma_pos_to_enum(x, y int) AVChromaLocation { + return (AVChromaLocation)(C.avcodec_chroma_pos_to_enum(C.int(x), C.int(y))) +} + +//Decode the audio frame of size avpkt->size from avpkt->data into frame. +//int avcodec_decode_audio4 (AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, const AVPacket *avpkt) +func Avcodec_decode_audio4(ctxt *AVCodecContext, f *AVFrame, g *int, a *AVPacket) int { + return int(C.avcodec_decode_audio4((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVFrame)(f), (*C.int)(unsafe.Pointer(g)), (*C.struct_AVPacket)(a))) +} + +//Decode the video frame of size avpkt->size from avpkt->data into picture. +//int avcodec_decode_video2 (AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt) +func Avcodec_decode_video2(ctxt *AVCodecContext, p *AVFrame, g *int, a *AVPacket) int { + return int(C.avcodec_decode_video2((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVFrame)(p), (*C.int)(unsafe.Pointer(g)), (*C.struct_AVPacket)(a))) +} + +//Decode a subtitle message. +//int avcodec_decode_subtitle2 (AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt) +func Avcodec_decode_subtitle2(ctxt *AVCodecContext, s *AVSubtitle, g *int, a *AVPacket) int { + return int(C.avcodec_decode_subtitle2((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVSubtitle)(s), (*C.int)(unsafe.Pointer(g)), (*C.struct_AVPacket)(a))) +} + +//AVCodecParser *av_parser_next (const AVCodecParser *c) +func Av_parser_next(p *AVCodecParser) *AVCodecParser { + return (*AVCodecParser)(C.av_parser_next((*C.struct_AVCodecParser)(p))) +} + +//void av_register_codec_parser (AVCodecParser *parser) +func Av_register_codec_parser(p *AVCodecParser) { + C.av_register_codec_parser((*C.struct_AVCodecParser)(p)) +} + +//AVCodecParserContext *av_parser_init (int codec_id) +func Av_parser_init(c int) *AVCodecParserContext { + return (*AVCodecParserContext)(C.av_parser_init(C.int(c))) +} + +//Parse a packet. +//int av_parser_parse2 (AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int64_t pts, int64_t dts, int64_t pos) +func Av_parser_parse2(ctxtp *AVCodecParserContext, ctxt *AVCodecContext, p **uint8, ps *int, b *uint8, bs int, pt, dt, po int64) int { + return int(C.av_parser_parse2((*C.struct_AVCodecParserContext)(ctxtp), (*C.struct_AVCodecContext)(ctxt), (**C.uint8_t)(unsafe.Pointer(p)), (*C.int)(unsafe.Pointer(ps)), (*C.uint8_t)(b), C.int(bs), (C.int64_t)(pt), (C.int64_t)(dt), (C.int64_t)(po))) +} + +//int av_parser_change (AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe) +func Av_parser_change(ctxtp *AVCodecParserContext, ctxt *AVCodecContext, pb **uint8, pbs *int, b *uint8, bs, k int) int { + return int(C.av_parser_change((*C.struct_AVCodecParserContext)(ctxtp), (*C.struct_AVCodecContext)(ctxt), (**C.uint8_t)(unsafe.Pointer(pb)), (*C.int)(unsafe.Pointer(pbs)), (*C.uint8_t)(b), C.int(bs), C.int(k))) +} + +//void av_parser_close (AVCodecParserContext *s) +func Av_parser_close(ctxtp *AVCodecParserContext) { + C.av_parser_close((*C.struct_AVCodecParserContext)(ctxtp)) +} + +//Find a registered encoder with a matching codec ID. +//AVCodec *avcodec_find_encoder (enum AVCodecID id) +func Avcodec_find_encoder(id AVCodecID) *AVCodec { + return (*AVCodec)(C.avcodec_find_encoder((C.enum_AVCodecID)(id))) +} + +//Find a registered encoder with the specified name. +//AVCodec *avcodec_find_encoder_by_name (const char *name) +func Avcodec_find_encoder_by_name(c string) *AVCodec { + return (*AVCodec)(C.avcodec_find_encoder_by_name(C.CString(c))) +} + +//Encode a frame of audio. +//int avcodec_encode_audio2 (AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) +func Avcodec_encode_audio2(ctxt *AVCodecContext, p *AVPacket, f *AVFrame, gp *int) int { + return int(C.avcodec_encode_audio2((*C.struct_AVCodecContext)(ctxt), (*C.struct_AVPacket)(p), (*C.struct_AVFrame)(f), (*C.int)(unsafe.Pointer(gp)))) +} + +//int avcodec_encode_subtitle (AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub) +func Avcodec_encode_subtitle(ctxt *AVCodecContext, b *uint8, bs int, s *AVSubtitle) int { + return int(C.avcodec_encode_subtitle((*C.struct_AVCodecContext)(ctxt), (*C.uint8_t)(b), C.int(bs), (*C.struct_AVSubtitle)(s))) +} + +//Free a picture previously allocated by avpicture_alloc(). +//Allocate memory for the pixels of a picture and setup the AVPicture fields for it. +func Avpicture_alloc(p *AVPicture, t AVPixelFormat, w, h int) int { + return int(C.avpicture_alloc((*C.struct_AVPicture)(p), (C.enum_AVPixelFormat)(t), C.int(w), C.int(h))) +} + +//void avpicture_free (AVPicture *picture) +func Avpicture_free(p *AVPicture) { + C.avpicture_free((*C.struct_AVPicture)(p)) +} + +//Setup the picture fields based on the specified image parameters and the provided image data buffer. +//int avpicture_fill (AVPicture *picture, const uint8_t *ptr, enum AVPixelFormat pix_fmt, int width, int height) +func Avpicture_fill(p *AVPicture, pt *uint8, pf AVPixelFormat, w, h int) int { + return int(C.avpicture_fill((*C.struct_AVPicture)(p), (*C.uint8_t)(pt), (C.enum_AVPixelFormat)(pf), C.int(w), C.int(h))) +} + +//Copy pixel data from an AVPicture into a buffer. +//int avpicture_layout (const AVPicture *src, enum AVPixelFormat pix_fmt, int width, int height, unsigned char *dest, int dest_size) +func Avpicture_layout(s *AVPicture, pf AVPixelFormat, w, h int, d *string, ds int) int { + return int(C.avpicture_layout((*C.struct_AVPicture)(s), (C.enum_AVPixelFormat)(pf), C.int(w), C.int(h), (*C.uchar)(unsafe.Pointer(d)), C.int(ds))) +} + +//Calculate the size in bytes that a picture of the given width and height would occupy if stored in the given picture format. +//int avpicture_get_size (enum AVPixelFormat pix_fmt, int width, int height) +func Avpicture_get_size(pf AVPixelFormat, w, h int) int { + return int(C.avpicture_get_size((C.enum_AVPixelFormat)(pf), C.int(w), C.int(h))) +} + +//Copy image src to dst. +//void av_picture_copy (AVPicture *dst, const AVPicture *src, enum AVPixelFormat pix_fmt, int width, int height) +func Av_picture_copy(d, s *AVPicture, pf AVPixelFormat, w, h int) { + C.av_picture_copy((*C.struct_AVPicture)(d), (*C.struct_AVPicture)(s), (C.enum_AVPixelFormat)(pf), C.int(w), C.int(h)) +} + +//Crop image top and left side. +//int av_picture_crop (AVPicture *dst, const AVPicture *src, enum AVPixelFormat pix_fmt, int top_band, int left_band) +func Av_picture_crop(d, s *AVPicture, pf AVPixelFormat, t, l int) int { + return int(C.av_picture_crop((*C.struct_AVPicture)(d), (*C.struct_AVPicture)(s), (C.enum_AVPixelFormat)(pf), C.int(t), C.int(l))) +} + +//Pad image. +//int av_picture_pad (AVPicture *dst, const AVPicture *src, int height, int width, enum AVPixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright, int *color) +func Av_picture_pad(p, s *AVPicture, h, w int, pf AVPixelFormat, t, b, l, r int, c *int) int { + return int(C.av_picture_pad((*C.struct_AVPicture)(p), (*C.struct_AVPicture)(s), (C.int)(h), (C.int)(w), (C.enum_AVPixelFormat)(pf), (C.int)(t), (C.int)(b), (C.int)(l), (C.int)(r), (*C.int)(unsafe.Pointer(c)))) +} + +//Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor. +//void avcodec_get_chroma_sub_sample (enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift) +func Avcodec_get_chroma_sub_sample(pf AVPixelFormat, h, v *int) { + C.avcodec_get_chroma_sub_sample((C.enum_AVPixelFormat)(pf), (*C.int)(unsafe.Pointer(h)), (*C.int)(unsafe.Pointer(v))) +} + +//Return a value representing the fourCC code associated to the pixel format pix_fmt, or 0 if no associated fourCC code can be found. +//unsigned int avcodec_pix_fmt_to_codec_tag (enum AVPixelFormat pix_fmt) +func Avcodec_pix_fmt_to_codec_tag(pf AVPixelFormat) uint { + return uint(C.avcodec_pix_fmt_to_codec_tag((C.enum_AVPixelFormat)(pf))) +} + +//int avcodec_get_pix_fmt_loss (enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, int has_alpha) +func Avcodec_get_pix_fmt_loss(p, f AVPixelFormat, a int) int { + return int(C.avcodec_get_pix_fmt_loss((C.enum_AVPixelFormat)(p), (C.enum_AVPixelFormat)(f), C.int(a))) +} + +//Find the best pixel format to convert to given a certain source pixel format. +//enum AVPixelFormat avcodec_find_best_pix_fmt_of_list (const enum AVPixelFormat *pix_fmt_list, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) +func Avcodec_find_best_pix_fmt_of_list(f *AVPixelFormat, s AVPixelFormat, a int, p *int) AVPixelFormat { + return (AVPixelFormat)(C.avcodec_find_best_pix_fmt_of_list((*C.enum_AVPixelFormat)(f), (C.enum_AVPixelFormat)(s), C.int(a), (*C.int)(unsafe.Pointer(p)))) +} + +//enum AVPixelFormat avcodec_find_best_pix_fmt_of_2 (enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) +func Avcodec_find_best_pix_fmt_of_2(f1, f2, s AVPixelFormat, a int, l *int) AVPixelFormat { + return (AVPixelFormat)(C.avcodec_find_best_pix_fmt_of_2((C.enum_AVPixelFormat)(f1), (C.enum_AVPixelFormat)(f2), (C.enum_AVPixelFormat)(s), C.int(a), (*C.int)(unsafe.Pointer(l)))) +} + +//enum AVPixelFormat avcodec_default_get_format (struct AVCodecContext *s, const enum AVPixelFormat *fmt) +func Avcodec_default_get_format(ctxt *AVCodecContext, f *AVPixelFormat) AVPixelFormat { + return (AVPixelFormat)(C.avcodec_default_get_format((*C.struct_AVCodecContext)(ctxt), (*C.enum_AVPixelFormat)(f))) +} + +//size_t av_get_codec_tag_string (char *buf, size_t buf_size, unsigned int codec_tag) +//Put a string representing the codec tag codec_tag in buf. +func Av_get_codec_tag_string(b string, bf uintptr, c uint) uintptr { + return uintptr(C.av_get_codec_tag_string(C.CString(b), C.size_t(bf), C.uint(c))) +} + +//void avcodec_string (char *buf, int buf_size, AVCodecContext *enc, int encode) +func Avcodec_string(b string, bs int, ctxt *AVCodecContext, e int) { + C.avcodec_string(C.CString(b), C.int(bs), (*C.struct_AVCodecContext)(ctxt), C.int(e)) +} + +//Return a name for the specified profile, if available. +//const char *av_get_profile_name (const AVCodec *codec, int profile) +func Av_get_profile_name(c *AVCodec, p int) string { + return C.GoString(C.av_get_profile_name((*C.struct_AVCodec)(c), C.int(p))) +} + +// //int avcodec_default_execute (AVCodecContext *c, int(*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size) +// func Avcodec_default_execute(ctxt AVCodecContext, int(*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, s int){ +// _,err := C.avcodec_default_execute(AVCodecContext *c, int(*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, s int) +// } + +// //int avcodec_default_execute2 (AVCodecContext *c, int(*func)(AVCodecContext *c2, void *arg2, int, int), void *arg, int *ret, int count) +// func Avcodec_default_execute2(AVCodecContext *c, int(*func)(AVCodecContext *c2, void *arg2, int, int), void *arg, int *ret, int count){ +// _,err := C.avcodec_default_execute2(AVCodecContext *c, int(*func)(AVCodecContext *c2, void *arg2, int, int), void *arg, int *ret, int count) +// } + +//Fill AVFrame audio data and linesize pointers. +//int avcodec_fill_audio_frame (AVFrame *frame, int nb_channels, enum AVSampleFormat sample_fmt, const uint8_t *buf, int buf_size, int align) +func Avcodec_fill_audio_frame(f *AVFrame, c int, s AVSampleFormat, b *uint8, bs, a int) int { + return int(C.avcodec_fill_audio_frame((*C.struct_AVFrame)(f), C.int(c), (C.enum_AVSampleFormat)(s), (*C.uint8_t)(b), C.int(bs), C.int(a))) +} + +//Reset the internal decoder state / flush internal buffers. +//void avcodec_flush_buffers (AVCodecContext *avctx) +func Avcodec_flush_buffers(ctxt *AVCodecContext) { + C.avcodec_flush_buffers((*C.struct_AVCodecContext)(ctxt)) +} + +//Return codec bits per sample. +//int av_get_bits_per_sample (enum AVCodecID codec_id) +func Av_get_bits_per_sample(c AVCodecID) int { + return int(C.av_get_bits_per_sample((C.enum_AVCodecID)(c))) +} + +//Return the PCM codec associated with a sample format. +//enum AVCodecID av_get_pcm_codec (enum AVSampleFormat fmt, int be) +func Av_get_pcm_codec(f AVSampleFormat, b int) AVCodecID { + return (AVCodecID)(C.av_get_pcm_codec((C.enum_AVSampleFormat)(f), C.int(b))) +} + +//Return codec bits per sample. +//int av_get_exact_bits_per_sample (enum AVCodecID codec_id) +func Av_get_exact_bits_per_sample(c AVCodecID) int { + return int(C.av_get_exact_bits_per_sample((C.enum_AVCodecID)(c))) +} + +//Return audio frame duration. +//int av_get_audio_frame_duration (AVCodecContext *avctx, int frame_bytes) +func Av_get_audio_frame_duration(ctxt *AVCodecContext, f int) int { + return int(C.av_get_audio_frame_duration((*C.struct_AVCodecContext)(ctxt), C.int(f))) +} + +//Register a bitstream filter. +//void av_register_bitstream_filter (AVBitStreamFilter *bsf) +func Av_register_bitstream_filter(b *AVBitStreamFilter) { + C.av_register_bitstream_filter((*C.struct_AVBitStreamFilter)(b)) +} + +//Create and initialize a bitstream filter context given a bitstream filter name. +//AVBitStreamFilterContext *av_bitstream_filter_init (const char *name) +func Av_bitstream_filter_init(n string) *AVBitStreamFilterContext { + return (*AVBitStreamFilterContext)(C.av_bitstream_filter_init(C.CString(n))) +} + +//Filter bitstream. +//int av_bitstream_filter_filter (AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe) +func Av_bitstream_filter_filter(bsctxt *AVBitStreamFilterContext, ctxt *AVCodecContext, a string, p **uint8, ps *int, b *uint8, bs, k int) int { + return int(C.av_bitstream_filter_filter((*C.struct_AVBitStreamFilterContext)(bsctxt), (*C.struct_AVCodecContext)(ctxt), C.CString(a), (**C.uint8_t)(unsafe.Pointer(p)), (*C.int)(unsafe.Pointer(ps)), (*C.uint8_t)(b), C.int(bs), C.int(k))) +} + +//Release bitstream filter context. +//void av_bitstream_filter_close (AVBitStreamFilterContext *bsf) +func Av_bitstream_filter_close(bsctxt *AVBitStreamFilterContext) { + C.av_bitstream_filter_close((*C.struct_AVBitStreamFilterContext)(bsctxt)) +} + +//If f is NULL, return the first registered bitstream filter, if f is non-NULL, return the next registered bitstream filter after f, or NULL if f is the last one. +//AVBitStreamFilter *av_bitstream_filter_next (const AVBitStreamFilter *f) +func Av_bitstream_filter_next(f *AVBitStreamFilter) *AVBitStreamFilter { + return (*AVBitStreamFilter)(C.av_bitstream_filter_next((*C.struct_AVBitStreamFilter)(f))) +} + +//Same behaviour av_fast_malloc but the buffer has additional FF_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0. +//void av_fast_padded_malloc (void *ptr, unsigned int *size, size_t min_size) +func Av_fast_padded_malloc(p unsafe.Pointer, s *uint, t uintptr) { + C.av_fast_padded_malloc(p, (*C.uint)(unsafe.Pointer(s)), (C.size_t)(t)) +} + +//Same behaviour av_fast_padded_malloc except that buffer will always be 0-initialized after call. +//void av_fast_padded_mallocz (void *ptr, unsigned int *size, size_t min_size) +func Av_fast_padded_mallocz(p unsafe.Pointer, s *uint, t uintptr) { + C.av_fast_padded_mallocz(p, (*C.uint)(unsafe.Pointer(s)), (C.size_t)(t)) +} + +//Encode extradata length to a buffer. +//unsigned int av_xiphlacing (unsigned char *s, unsigned int v) +func Av_xiphlacing(s *string, v uint) uint { + return uint(C.av_xiphlacing((*C.uchar)(unsafe.Pointer(s)), (C.uint)(v))) +} + +//If hwaccel is NULL, returns the first registered hardware accelerator, if hwaccel is non-NULL, +//returns the next registered hardware accelerator after hwaccel, or NULL if hwaccel is the last one. +//AVHWAccel *av_hwaccel_next (const AVHWAccel *hwaccel) +func Av_hwaccel_next(a *AVHWAccel) *AVHWAccel { + return (*AVHWAccel)(C.av_hwaccel_next((*C.struct_AVHWAccel)(a))) +} + +// //Register a user provided lock manager supporting the operations specified by AVLockOp. +// //int av_lockmgr_register (int(*cb)(void **mutex, enum AVLockOp op)) +// func Av_lockmgr_register(int(*cb)(void **mutex, enum AVLockOp op)) int { +// return C.av_lockmgr_register(int(*cb)(void **mutex, enum AVLockOp op)) +// } + +//Get the type of the given codec. +//enum AVMediaType avcodec_get_type (enum AVCodecID codec_id) +func Avcodec_get_type(c AVCodecID) AVMediaType { + return (AVMediaType)(C.avcodec_get_type((C.enum_AVCodecID)(c))) +} + +//Get the name of a codec. +//const char *avcodec_get_name (enum AVCodecID id) +func Avcodec_get_name(d AVCodecID) string { + return C.GoString(C.avcodec_get_name((C.enum_AVCodecID)(d))) +} + +//int avcodec_is_open (AVCodecContext *s) +func Avcodec_is_open(ctxt *AVCodecContext) int { + return int(C.avcodec_is_open((*C.struct_AVCodecContext)(ctxt))) +} + +//int av_codec_is_encoder (const AVCodec *codec) +func Av_codec_is_encoder(c *AVCodec) int { + return int(C.av_codec_is_encoder((*C.struct_AVCodec)(c))) +} + +//int av_codec_is_decoder (const AVCodec *codec) +func Av_codec_is_decoder(c *AVCodec) int { + return int(C.av_codec_is_decoder((*C.struct_AVCodec)(c))) +} + +//const AVCodecDescriptor *avcodec_descriptor_get (enum AVCodecID id) +func Avcodec_descriptor_get(id AVCodecID) *AVCodecDescriptor { + return (*AVCodecDescriptor)(C.avcodec_descriptor_get((C.enum_AVCodecID)(id))) +} + +//Iterate over all codec descriptors known to libavcodec. +//const AVCodecDescriptor *avcodec_descriptor_next (const AVCodecDescriptor *prev) +func Avcodec_descriptor_next(d *AVCodecDescriptor) *AVCodecDescriptor { + return (*AVCodecDescriptor)(C.avcodec_descriptor_next((*C.struct_AVCodecDescriptor)(d))) +} + +//const AVCodecDescriptor *avcodec_descriptor_get_by_name (const char *name) +func Avcodec_descriptor_get_by_name(n string) *AVCodecDescriptor { + return (*AVCodecDescriptor)(C.avcodec_descriptor_get_by_name(C.CString(n))) +} diff --git a/avcodec/exported.go b/avcodec/exported.go new file mode 100644 index 0000000..80587e1 --- /dev/null +++ b/avcodec/exported.go @@ -0,0 +1,25 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) +*/ +package avcodec + +func Codec_id(c *AVCodecContext) AVCodecID { + return (AVCodecID)(c.codec_id) +} + +func Width(c *AVCodecContext) int { + return int(c.width) +} + +func Height(c *AVCodecContext) int { + return int(c.width) +} + +func Pix_fmt(c *AVCodecContext) AVPixelFormat { + return (AVPixelFormat)(c.pix_fmt) +} + +func Stream_index(p *AVPacket) int { + return int(p.stream_index) +} diff --git a/avdevice/avdevice.go b/avdevice/avdevice.go new file mode 100644 index 0000000..6cceca9 --- /dev/null +++ b/avdevice/avdevice.go @@ -0,0 +1,130 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) + + The input and output devices provided by the libavdevice library + The libavdevice library provides the same interface as libavformat. + Namely, an input device is considered like a demuxer, and an output device like a muxer, + and the interface and generic device options are the same provided by libavformat +*/ +package avdevice + +/* + #cgo pkg-config: libavdevice + #include +*/ +import "C" +import ( + "unsafe" +) + +type ( + AVDeviceRect C.struct_AVDeviceRect + AVDeviceCapabilitiesQuery C.struct_AVDeviceCapabilitiesQuery + AVDeviceInfo C.struct_AVDeviceInfo + AVDeviceInfoList C.struct_AVDeviceInfoList + AVInputFormat C.struct_AVInputFormat + AVOutputFormat C.struct_AVOutputFormat + AVFormatContext C.struct_AVFormatContext + AVDictionary C.struct_AVDictionary +) + +type ( + AVAppToDevMessageType C.enum_AVAppToDevMessageType + AVDevToAppMessageType C.enum_AVDevToAppMessageType +) + +//unsigned avdevice_version (void) +//Return the LIBAVDEVICE_VERSION_INT constant. +func Avdevice_version() uint { + return uint(C.avdevice_version()) +} + +//const char * avdevice_configuration (void) +//Return the libavdevice build-time configuration. +func Avdevice_configuration() string { + return C.GoString(C.avdevice_configuration()) +} + +//const char * avdevice_license (void) +//Return the libavdevice license. +func Avdevice_license() string { + return C.GoString(C.avdevice_license()) +} + +//void avdevice_register_all (void) +//Initialize libavdevice and register all the input and output devices. +func Avdevice_register_all() { + C.avdevice_register_all() +} + +//AVInputFormat * av_input_audio_device_next (AVInputFormat *d) +//Audio input devices iterator. +func Av_input_audio_device_next(d *AVInputFormat) *AVInputFormat { + return (*AVInputFormat)(C.av_input_audio_device_next((*C.struct_AVInputFormat)(d))) +} + +//AVInputFormat * av_input_video_device_next (AVInputFormat *d) +//Video input devices iterator. +func Av_input_video_device_next(d *AVInputFormat) *AVInputFormat { + return (*AVInputFormat)(C.av_input_video_device_next((*C.struct_AVInputFormat)(d))) +} + +//AVOutputFormat * av_output_audio_device_next (AVOutputFormat *d) +//Audio output devices iterator. +func Av_output_audio_device_next(d *AVOutputFormat) *AVOutputFormat { + return (*AVOutputFormat)(C.av_output_audio_device_next((*C.struct_AVOutputFormat)(d))) +} + +//AVOutputFormat * av_output_video_device_next (AVOutputFormat *d) +//Video output devices iterator. +func Av_output_video_device_next(d *AVOutputFormat) *AVOutputFormat { + return (*AVOutputFormat)(C.av_output_video_device_next((*C.struct_AVOutputFormat)(d))) +} + +//int avdevice_app_to_dev_control_message (struct AVFormatContext *s, enum AVAppToDevMessageType type, void *data, size_t data_size) +//Send control message from application to device. +func Avdevice_app_to_dev_control_message(s *AVFormatContext, m AVAppToDevMessageType, da int, d uintptr) int { + return int(C.avdevice_app_to_dev_control_message((*C.struct_AVFormatContext)(s), (C.enum_AVAppToDevMessageType)(m), unsafe.Pointer(&da), C.size_t(d))) +} + +//int avdevice_dev_to_app_control_message (struct AVFormatContext *s, enum AVDevToAppMessageType type, void *data, size_t data_size) +//Send control message from device to application. +func Avdevice_dev_to_app_control_message(fcxt *AVFormatContext, m AVDevToAppMessageType, da int, d uintptr) int { + return int(C.avdevice_dev_to_app_control_message((*C.struct_AVFormatContext)(fcxt), (C.enum_AVDevToAppMessageType)(m), unsafe.Pointer(&da), C.size_t(d))) +} + +//int avdevice_capabilities_create (AVDeviceCapabilitiesQuery **caps, AVFormatContext *s, AVDictionary **device_options) +//Initialize capabilities probing API based on AVOption API. +func Avdevice_capabilities_create(c **AVDeviceCapabilitiesQuery, s *AVFormatContext, d **AVDictionary) int { + return int(C.avdevice_capabilities_create((**C.struct_AVDeviceCapabilitiesQuery)(unsafe.Pointer(c)), (*C.struct_AVFormatContext)(s), (**C.struct_AVDictionary)(unsafe.Pointer(d)))) +} + +//void avdevice_capabilities_free (AVDeviceCapabilitiesQuery **caps, AVFormatContext *s) +//Free resources created by avdevice_capabilities_create() +func Avdevice_capabilities_free(c **AVDeviceCapabilitiesQuery, s *AVFormatContext) { + C.avdevice_capabilities_free((**C.struct_AVDeviceCapabilitiesQuery)(unsafe.Pointer(c)), (*C.struct_AVFormatContext)(s)) +} + +//int avdevice_list_devices (struct AVFormatContext *s, AVDeviceInfoList **device_list) +//List devices. +func Avdevice_list_devices(s *AVFormatContext, d **AVDeviceInfoList) int { + return int(C.avdevice_list_devices((*C.struct_AVFormatContext)(s), (**C.struct_AVDeviceInfoList)(unsafe.Pointer(d)))) +} + +//void avdevice_free_list_devices (AVDeviceInfoList **device_list) +//Convenient function to free result of avdevice_list_devices(). +func Avdevice_free_list_devices(d **AVDeviceInfoList) { + C.avdevice_free_list_devices((**C.struct_AVDeviceInfoList)(unsafe.Pointer(d))) +} + +//int avdevice_list_input_sources (struct AVInputFormat *device, const char *device_name, AVDictionary *device_options, AVDeviceInfoList **device_list) +//List devices. +func Avdevice_list_input_sources(d *AVInputFormat, dv string, do *AVDictionary, dl **AVDeviceInfoList) int { + return int(C.avdevice_list_input_sources((*C.struct_AVInputFormat)(d), C.CString(dv), (*C.struct_AVDictionary)(do), (**C.struct_AVDeviceInfoList)(unsafe.Pointer(dl)))) +} + +//int avdevice_list_output_sinks (struct AVOutputFormat *device, const char *device_name, AVDictionary *device_options, AVDeviceInfoList **device_list) +func Avdevice_list_output_sinks(d *AVOutputFormat, dn string, di *AVDictionary, dl **AVDeviceInfoList) int { + return int(C.avdevice_list_output_sinks((*C.struct_AVOutputFormat)(d), C.CString(dn), (*C.struct_AVDictionary)(di), (**C.struct_AVDeviceInfoList)(unsafe.Pointer(dl)))) +} diff --git a/avfilter/avfilter.go b/avfilter/avfilter.go new file mode 100644 index 0000000..e2dd323 --- /dev/null +++ b/avfilter/avfilter.go @@ -0,0 +1,254 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) + + Filters in the same linear chain are separated by commas, + and distinct linear chains of filters are separated by semicolons. + FFmpeg is enabled through the "C" libavfilter library +*/ +package avfilter + +/* + #cgo pkg-config: libavfilter + #include +*/ +import "C" +import ( + "unsafe" +) + +type ( + AVFilter C.struct_AVFilter + AVFilterContext C.struct_AVFilterContext + AVFilterLink C.struct_AVFilterLink + AVFilterGraph C.struct_AVFilterGraph + AVFilterInOut C.struct_AVFilterInOut + AVFilterPad C.struct_AVFilterPad + AVDictionary C.struct_AVDictionary + AVClass C.struct_AVClass +) +type ( + AVMediaType C.enum_AVMediaType +) + +//unsigned avfilter_version (void) +//Return the LIBAVFILTER_VERSION_INT constant. +func Avfilter_version() uint { + return uint(C.avfilter_version()) +} + +//const char * avfilter_configuration (void) +//Return the libavfilter build-time configuration. +func Avfilter_configuration() string { + return C.GoString(C.avfilter_configuration()) +} + +//const char * avfilter_license (void) +//Return the libavfilter license. +func Avfilter_license() string { + return C.GoString(C.avfilter_license()) +} + +//int avfilter_pad_count (const AVFilterPad *pads) +//Get the number of elements in a NULL-terminated array of AVFilterPads (e.g. +func Avfilter_pad_count(p *AVFilterPad) int { + return int(C.avfilter_pad_count((*C.struct_AVFilterPad)(p))) +} + +//const char * avfilter_pad_get_name (const AVFilterPad *pads, int pad_idx) +//Get the name of an AVFilterPad. +func Avfilter_pad_get_name(p *AVFilterPad, pi int) string { + return C.GoString(C.avfilter_pad_get_name((*C.struct_AVFilterPad)(p), C.int(pi))) +} + +//enum AVMediaType avfilter_pad_get_type (const AVFilterPad *pads, int pad_idx) +//Get the type of an AVFilterPad. +func Avfilter_pad_get_type(p *AVFilterPad, pi int) AVMediaType { + return (AVMediaType)(C.avfilter_pad_get_type((*C.struct_AVFilterPad)(p), C.int(pi))) +} + +//int avfilter_link (AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad) +//Link two filters together. +func Avfilter_link(s *AVFilterContext, sp uint, d *AVFilterContext, dp uint) int { + return int(C.avfilter_link((*C.struct_AVFilterContext)(s), C.uint(sp), (*C.struct_AVFilterContext)(d), C.uint(dp))) +} + +//void avfilter_link_free (AVFilterLink **link) +//Free the link in *link, and set its pointer to NULL. +func Avfilter_link_free(l **AVFilterLink) { + C.avfilter_link_free((**C.struct_AVFilterLink)(unsafe.Pointer(l))) +} + +//int avfilter_link_get_channels (AVFilterLink *link) +//Get the number of channels of a link. +func Avfilter_link_get_channels(l *AVFilterLink) int { + return int(C.avfilter_link_get_channels((*C.struct_AVFilterLink)(l))) +} + +//void avfilter_link_set_closed (AVFilterLink *link, int closed) +//Set the closed field of a link. +func Avfilter_link_set_closed(l *AVFilterLink, c int) { + C.avfilter_link_set_closed((*C.struct_AVFilterLink)(l), C.int(c)) +} + +//int avfilter_config_links (AVFilterContext *filter) +//Negotiate the media format, dimensions, etc of all inputs to a filter. +func Avfilter_config_links(f *AVFilterContext) int { + return int(C.avfilter_config_links((*C.struct_AVFilterContext)(f))) +} + +//int avfilter_process_command (AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags) +//Make the filter instance process a command. +func Avfilter_process_command(f *AVFilterContext, cmd, arg, res string, l, fl int) int { + return int(C.avfilter_process_command((*C.struct_AVFilterContext)(f), C.CString(cmd), C.CString(arg), C.CString(res), C.int(l), C.int(fl))) +} + +//void avfilter_register_all (void) +//Initialize the filter system. +func Avfilter_register_all() { + C.avfilter_register_all() +} + +//int avfilter_register (AVFilter *filter) +//Register a filter. +func Avfilter_register(f *AVFilter) int { + return int(C.avfilter_register((*C.struct_AVFilter)(f))) +} + +//const AVFilter * avfilter_get_by_name (const char *name) +//Get a filter definition matching the given name. +func Avfilter_get_by_name(n string) *AVFilter { + return (*AVFilter)(C.avfilter_get_by_name(C.CString(n))) +} + +//const AVFilter * avfilter_next (const AVFilter *prev) +//Iterate over all registered filters. +func Avfilter_next(f *AVFilter) *AVFilter { + return (*AVFilter)(C.avfilter_next((*C.struct_AVFilter)(f))) +} + +//int avfilter_init_str (AVFilterContext *ctx, const char *args) +//Initialize a filter with the supplied parameters. +func Avfilter_init_str(ctx *AVFilterContext, args string) int { + return int(C.avfilter_init_str((*C.struct_AVFilterContext)(ctx), C.CString(args))) +} + +//int avfilter_init_dict (AVFilterContext *ctx, AVDictionary **options) +//Initialize a filter with the supplied dictionary of options. +func Avfilter_init_dict(f *AVFilterContext, o **AVDictionary) int { + return int(C.avfilter_init_dict((*C.struct_AVFilterContext)(f), (**C.struct_AVDictionary)(unsafe.Pointer(o)))) +} + +//void avfilter_free (AVFilterContext *filter) +//Free a filter context. +func Avfilter_free(f *AVFilterContext) { + C.avfilter_free((*C.struct_AVFilterContext)(f)) +} + +//int avfilter_insert_filter (AVFilterLink *link, AVFilterContext *filt, unsigned filt_srcpad_idx, unsigned filt_dstpad_idx) +//Insert a filter in the middle of an existing link. +func Avfilter_insert_filter(l *AVFilterLink, f *AVFilterContext, fsi, fdi uint) int { + return int(C.avfilter_insert_filter((*C.struct_AVFilterLink)(l), (*C.struct_AVFilterContext)(f), C.uint(fsi), C.uint(fdi))) +} + +//const AVClass * avfilter_get_class (void) +//avfilter_get_class +func Avfilter_get_class() *AVClass { + return (*AVClass)(C.avfilter_get_class()) +} + +//Allocate a filter graph. +//AVFilterGraph * avfilter_graph_alloc (void) +func Avfilter_graph_alloc() *AVFilterGraph { + return (*AVFilterGraph)(C.avfilter_graph_alloc()) +} + +//AVFilterContext * avfilter_graph_alloc_filter (AVFilterGraph *graph, const AVFilter *filter, const char *name) +//Create a new filter instance in a filter graph. +func Avfilter_graph_alloc_filter(g *AVFilterGraph, f *AVFilter, n string) *AVFilterContext { + return (*AVFilterContext)(C.avfilter_graph_alloc_filter((*C.struct_AVFilterGraph)(g), (*C.struct_AVFilter)(f), C.CString(n))) +} + +//AVFilterContext * avfilter_graph_get_filter (AVFilterGraph *graph, const char *name) +//Get a filter instance identified by instance name from graph. +func Avfilter_graph_get_filter(g *AVFilterGraph, n string) *AVFilterContext { + return (*AVFilterContext)(C.avfilter_graph_get_filter((*C.struct_AVFilterGraph)(g), C.CString(n))) +} + +//int avfilter_graph_create_filter (AVFilterContext **filt_ctx, const AVFilter *filt, const char *name, const char *args, void *opaque, AVFilterGraph *graph_ctx) +//Create and add a filter instance into an existing graph. +func Avfilter_graph_create_filter(cx **AVFilterContext, f *AVFilter, n, a string, o int, g *AVFilterGraph) int { + return int(C.avfilter_graph_create_filter((**C.struct_AVFilterContext)(unsafe.Pointer(cx)), (*C.struct_AVFilter)(f), C.CString(n), C.CString(a), unsafe.Pointer(&o), (*C.struct_AVFilterGraph)(g))) +} + +//void avfilter_graph_set_auto_convert (AVFilterGraph *graph, unsigned flags) +//Enable or disable automatic format conversion inside the graph. +func Avfilter_graph_set_auto_convert(g *AVFilterGraph, f uint) { + C.avfilter_graph_set_auto_convert((*C.struct_AVFilterGraph)(g), C.uint(f)) +} + +//int avfilter_graph_config (AVFilterGraph *graphctx, void *log_ctx) +//Check validity and configure all the links and formats in the graph. +func Avfilter_graph_config(g *AVFilterGraph, l int) int { + return int(C.avfilter_graph_config((*C.struct_AVFilterGraph)(g), unsafe.Pointer(&l))) +} + +//void avfilter_graph_free (AVFilterGraph **graph) +//Free a graph, destroy its links, and set *graph to NULL. +func Avfilter_graph_free(g **AVFilterGraph) { + C.avfilter_graph_free((**C.struct_AVFilterGraph)(unsafe.Pointer(g))) +} + +//AVFilterInOut * avfilter_inout_alloc (void) +//Allocate a single AVFilterInOut entry. +func Avfilter_inout_alloc() *AVFilterInOut { + return (*AVFilterInOut)(C.avfilter_inout_alloc()) +} + +//void avfilter_inout_free (AVFilterInOut **inout) +//Free the supplied list of AVFilterInOut and set *inout to NULL. +func Avfilter_inout_free(i **AVFilterInOut) { + C.avfilter_inout_free((**C.struct_AVFilterInOut)(unsafe.Pointer(i))) +} + +//int avfilter_graph_parse (AVFilterGraph *graph, const char *filters, AVFilterInOut *inputs, AVFilterInOut *outputs, void *log_ctx) +//Add a graph described by a string to a graph. +func Avfilter_graph_parse(g *AVFilterGraph, f string, i, o *AVFilterInOut, l int) int { + return int(C.avfilter_graph_parse((*C.struct_AVFilterGraph)(g), C.CString(f), (*C.struct_AVFilterInOut)(i), (*C.struct_AVFilterInOut)(o), unsafe.Pointer(&l))) +} + +//int avfilter_graph_parse_ptr (AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs, void *log_ctx) +//Add a graph described by a string to a graph. +func Avfilter_graph_parse_ptr(g *AVFilterGraph, f string, i, o **AVFilterInOut, l int) int { + return int(C.avfilter_graph_parse_ptr((*C.struct_AVFilterGraph)(g), C.CString(f), (**C.struct_AVFilterInOut)(unsafe.Pointer(i)), (**C.struct_AVFilterInOut)(unsafe.Pointer(o)), unsafe.Pointer(&l))) +} + +//int avfilter_graph_parse2 (AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs) +//Add a graph described by a string to a graph. +func Avfilter_graph_parse2(g *AVFilterGraph, f string, i, o **AVFilterInOut) int { + return int(C.avfilter_graph_parse2((*C.struct_AVFilterGraph)(g), C.CString(f), (**C.struct_AVFilterInOut)(unsafe.Pointer(i)), (**C.struct_AVFilterInOut)(unsafe.Pointer(o)))) +} + +//int avfilter_graph_send_command (AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags) +//Send a command to one or more filter instances. +func Avfilter_graph_send_command(g *AVFilterGraph, t, cmd, arg, res string, resl, f int) int { + return int(C.avfilter_graph_send_command((*C.struct_AVFilterGraph)(g), C.CString(t), C.CString(cmd), C.CString(arg), C.CString(res), C.int(resl), C.int(f))) +} + +//int avfilter_graph_queue_command (AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, int flags, double ts) +//Queue a command for one or more filter instances. +func Avfilter_graph_queue_command(g *AVFilterGraph, t, cmd, arg string, f int, ts C.double) int { + return int(C.avfilter_graph_queue_command((*C.struct_AVFilterGraph)(g), C.CString(t), C.CString(cmd), C.CString(arg), C.int(f), ts)) +} + +//char * avfilter_graph_dump (AVFilterGraph *graph, const char *options) +//Dump a graph into a human-readable string representation. +func Avfilter_graph_dump(g *AVFilterGraph, o string) string { + return C.GoString(C.avfilter_graph_dump((*C.struct_AVFilterGraph)(g), C.CString(o))) +} + +//int avfilter_graph_request_oldest (AVFilterGraph *graph) +//Request a frame on the oldest sink +func Avfilter_graph_request_oldestlink(g *AVFilterGraph) int { + return int(C.avfilter_graph_request_oldest((*C.struct_AVFilterGraph)(g))) +} diff --git a/avformat/avformat.go b/avformat/avformat.go new file mode 100644 index 0000000..dfbe3c2 --- /dev/null +++ b/avformat/avformat.go @@ -0,0 +1,593 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) + + Supported formats (muxers and demuxers) provided by the libavformat library + The libavformat library provides some generic global options, + which can be set on all the muxers and demuxers. + In addition each muxer or demuxer may support so-called private options, + which are specific for that component. +*/ +package avformat + +//#cgo pkg-config: libavformat libavcodec libavutil libavdevice libavfilter libswresample libswscale +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +import "C" +import ( + "github.com/giorgisio/gfg/avcodec" + "unsafe" +) + +type ( + AVProbeData C.struct_AVProbeData + AVOutputFormat C.struct_AVOutputFormat + AVInputFormat C.struct_AVInputFormat + AVIndexEntry C.struct_AVIndexEntry + AVStream C.struct_AVStream + AVProgram C.struct_AVProgram + AVChapter C.struct_AVChapter + AVFormatContext C.struct_AVFormatContext + AVPacketList C.struct_AVPacketList + AVPacket C.struct_AVPacket + AVCodecParserContext C.struct_AVCodecParserContext + AVIOContext C.struct_AVIOContext + AVRational C.struct_AVRational + AVCodec C.struct_AVCodec + AVCodecTag C.struct_AVCodecTag + AVDictionary C.struct_AVDictionary + AVFrame C.struct_AVFrame + AVClass C.struct_AVClass + AVCodecContext C.struct_AVCodecContext +) +type ( + AVMediaType C.enum_AVMediaType + AVDurationEstimationMethod C.enum_AVDurationEstimationMethod + AVPacketSideDataType C.enum_AVPacketSideDataType + AVCodecID C.enum_AVCodecID +) + +type File C.FILE + +//int av_get_packet (AVIOContext *s, AVPacket *pkt, int size) +//Allocate and read the payload of a packet and initialize its fields with default values. +func Av_get_packet(ctxt *AVIOContext, pkt *AVPacket, s int) int { + return int(C.av_get_packet((*C.struct_AVIOContext)(ctxt), (*C.struct_AVPacket)(pkt), C.int(s))) +} + +//int av_append_packet (AVIOContext *s, AVPacket *pkt, int size) +//Read data and append it to the current content of the AVPacket. +func Av_append_packet(ctxt *AVIOContext, pkt *AVPacket, s int) int { + return int(C.av_append_packet((*C.struct_AVIOContext)(ctxt), (*C.struct_AVPacket)(pkt), C.int(s))) +} + +//AVRational av_stream_get_r_frame_rate (const AVStream *s) +func Av_stream_get_r_frame_rate(s *AVStream) AVRational { + return (AVRational)(C.av_stream_get_r_frame_rate((*C.struct_AVStream)(s))) +} + +//void av_stream_set_r_frame_rate (AVStream *s, AVRational r) +func Av_stream_set_r_frame_rate(s *AVStream, r AVRational) { + C.av_stream_set_r_frame_rate((*C.struct_AVStream)(s), (C.struct_AVRational)(r)) +} + +//struct AVCodecParserContext * av_stream_get_parser (const AVStream *s) +func Av_stream_get_parser(s *AVStream) *AVCodecParserContext { + return (*AVCodecParserContext)(C.av_stream_get_parser((*C.struct_AVStream)(s))) +} + +//char * av_stream_get_recommended_encoder_configuration (const AVStream *s) +func Av_stream_get_recommended_encoder_configuration(s *AVStream) string { + return C.GoString(C.av_stream_get_recommended_encoder_configuration((*C.struct_AVStream)(s))) +} + +//void av_stream_set_recommended_encoder_configuration (AVStream *s, char *configuration) +func Av_stream_set_recommended_encoder_configuration(s *AVStream, c string) { + C.av_stream_set_recommended_encoder_configuration((*C.struct_AVStream)(s), C.CString(c)) +} + +//int64_t av_stream_get_end_pts (const AVStream *st) +//Returns the pts of the last muxed packet + its duration. +func Av_stream_get_end_pts(s *AVStream) int64 { + return int64(C.av_stream_get_end_pts((*C.struct_AVStream)(s))) +} + +//int av_format_get_probe_score (const AVFormatContext *s) +func Av_format_get_probe_score(s *AVFormatContext) int { + return int(C.av_format_get_probe_score((*C.struct_AVFormatContext)(s))) +} + +//AVCodec * av_format_get_video_codec (const AVFormatContext *s) +func Av_format_get_video_codec(s *AVFormatContext) *AVCodec { + return (*AVCodec)(C.av_format_get_video_codec((*C.struct_AVFormatContext)(s))) +} + +//void av_format_set_video_codec (AVFormatContext *s, AVCodec *c) +func Av_format_set_video_codec(s *AVFormatContext, c *AVCodec) { + C.av_format_set_video_codec((*C.struct_AVFormatContext)(s), (*C.struct_AVCodec)(c)) +} + +//AVCodec * av_format_get_audio_codec (const AVFormatContext *s) +func Av_format_get_audio_codec(s *AVFormatContext) *AVCodec { + return (*AVCodec)(C.av_format_get_audio_codec((*C.struct_AVFormatContext)(s))) +} + +//void av_format_set_audio_codec (AVFormatContext *s, AVCodec *c) +func Av_format_set_audio_codec(s *AVFormatContext, c *AVCodec) { + C.av_format_set_audio_codec((*C.struct_AVFormatContext)(s), (*C.struct_AVCodec)(c)) +} + +//AVCodec * av_format_get_subtitle_codec (const AVFormatContext *s) +func Av_format_get_subtitle_codec(s *AVFormatContext) *AVCodec { + return (*AVCodec)(C.av_format_get_subtitle_codec((*C.struct_AVFormatContext)(s))) +} + +//void av_format_set_subtitle_codec (AVFormatContext *s, AVCodec *c) +func Av_format_set_subtitle_codec(s *AVFormatContext, c *AVCodec) { + C.av_format_set_subtitle_codec((*C.struct_AVFormatContext)(s), (*C.struct_AVCodec)(c)) +} + +//AVCodec * av_format_get_data_codec (const AVFormatContext *s) +func Av_format_get_data_codec(s *AVFormatContext) *AVCodec { + return (*AVCodec)(C.av_format_get_data_codec((*C.struct_AVFormatContext)(s))) +} + +//void av_format_set_data_codec (AVFormatContext *s, AVCodec *c) +func Av_format_set_data_codec(s *AVFormatContext, c *AVCodec) { + C.av_format_set_data_codec((*C.struct_AVFormatContext)(s), (*C.struct_AVCodec)(c)) +} + +//int av_format_get_metadata_header_padding (const AVFormatContext *s) +func Av_format_get_metadata_header_padding(s *AVFormatContext) int { + return int(C.av_format_get_metadata_header_padding((*C.struct_AVFormatContext)(s))) +} + +//void av_format_set_metadata_header_padding (AVFormatContext *s, int c) +func Av_format_set_metadata_header_padding(s *AVFormatContext, c int) { + C.av_format_set_metadata_header_padding((*C.struct_AVFormatContext)(s), C.int(c)) +} + +//void * av_format_get_opaque (const AVFormatContext *s) +func Av_format_get_opaque(s *AVFormatContext) { + C.av_format_get_opaque((*C.struct_AVFormatContext)(s)) +} + +//void av_format_set_opaque (AVFormatContext *s, void *opaque) +func Av_format_set_opaque(s *AVFormatContext, o int) { + C.av_format_set_opaque((*C.struct_AVFormatContext)(s), unsafe.Pointer(&o)) +} + +//av_format_control_message av_format_get_control_message_cb (const AVFormatContext *s) +func Av_format_control_message(s *AVFormatContext) C.av_format_control_message { + return C.av_format_get_control_message_cb((*C.struct_AVFormatContext)(s)) +} + +//void av_format_set_control_message_cb (AVFormatContext *s, av_format_control_message callback) +func Av_format_set_control_message_cb(s *AVFormatContext, c C.av_format_control_message) { + C.av_format_set_control_message_cb((*C.struct_AVFormatContext)(s), c) +} + +//void av_format_inject_global_side_data (AVFormatContext *s) +//This function will cause global side data to be injected in the next packet of each stream as well as after any subsequent seek. +func Av_format_inject_global_side_data(s *AVFormatContext) { + C.av_format_inject_global_side_data((*C.struct_AVFormatContext)(s)) +} + +//enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method (const AVFormatContext *ctx) +//Returns the method used to set ctx->duration. +func Av_fmt_ctx_get_duration_estimation_method(ctx *AVFormatContext) AVDurationEstimationMethod { + return (AVDurationEstimationMethod)(C.av_fmt_ctx_get_duration_estimation_method((*C.struct_AVFormatContext)(ctx))) +} + +//unsigned avformat_version (void) +//Return the LIBAVFORMAT_VERSION_INT constant. +func Avformat_version() uint { + return uint(C.avformat_version()) +} + +//const char * avformat_configuration (void) +//Return the libavformat build-time configuration. +func Avformat_configuration() string { + return C.GoString(C.avformat_configuration()) +} + +//const char * avformat_license (void) +//Return the libavformat license. +func Avformat_license() string { + return C.GoString(C.avformat_license()) +} + +//void av_register_all (void) +//Initialize libavformat and register all the muxers, demuxers and protocols. +func Av_register_all() { + C.av_register_all() +} + +//void av_register_input_format (AVInputFormat *format) +func Av_register_input_format(f *AVInputFormat) { + C.av_register_input_format((*C.struct_AVInputFormat)(f)) +} + +//void av_register_output_format (AVOutputFormat *format) +func Av_register_output_format(f *AVOutputFormat) { + C.av_register_output_format((*C.struct_AVOutputFormat)(f)) +} + +//int avformat_network_init (void) +//Do global initialization of network components. +func Avformat_network_init() int { + return int(C.avformat_network_init()) +} + +//int avformat_network_deinit (void) +//Undo the initialization done by avformat_network_init. +func Avformat_network_deinit() int { + return int(C.avformat_network_deinit()) +} + +//AVInputFormat * av_iformat_next (const AVInputFormat *f) +//If f is NULL, returns the first registered input format, if f is non-NULL, returns the next registered input format after f or NULL if f is the last one. +func Av_iformat_next(f *AVInputFormat) *AVInputFormat { + return (*AVInputFormat)(C.av_iformat_next((*C.struct_AVInputFormat)(f))) +} + +//AVOutputFormat * av_oformat_next (const AVOutputFormat *f) +//If f is NULL, returns the first registered output format, if f is non-NULL, returns the next registered output format after f or NULL if f is the last one. +func Av_oformat_next(f *AVOutputFormat) *AVOutputFormat { + return (*AVOutputFormat)(C.av_oformat_next((*C.struct_AVOutputFormat)(f))) +} + +//AVFormatContext * avformat_alloc_context (void) +//Allocate an AVFormatContext. +func Avformat_alloc_context() *AVFormatContext { + return (*AVFormatContext)(C.avformat_alloc_context()) +} + +//void avformat_free_context (AVFormatContext *s) +//Free an AVFormatContext and all its streams. +func Avformat_free_context(s *AVFormatContext) { + C.avformat_free_context((*C.struct_AVFormatContext)(s)) +} + +//const AVClass * avformat_get_class (void) +//Get the AVClass for AVFormatContext. +func Avformat_get_class() *AVClass { + return (*AVClass)(C.avformat_get_class()) +} + +//AVStream * avformat_new_stream (AVFormatContext *s, const AVCodec *c) +//Add a new stream to a media file. +func Avformat_new_stream(s *AVFormatContext, c *AVCodec) *AVStream { + return (*AVStream)(C.avformat_new_stream((*C.struct_AVFormatContext)(s), (*C.struct_AVCodec)(c))) +} + +//uint8_t * av_stream_get_side_data (AVStream *stream, enum AVPacketSideDataType type, int *size) +//Get side information from stream. +func Av_stream_get_side_data(s *AVStream, t AVPacketSideDataType, z int) *uint8 { + return (*uint8)(C.av_stream_get_side_data((*C.struct_AVStream)(s), (C.enum_AVPacketSideDataType)(t), (*C.int)(unsafe.Pointer(&z)))) +} + +//AVProgram * av_new_program (AVFormatContext *s, int id) +func Av_new_program(s *AVFormatContext, id int) *AVProgram { + return (*AVProgram)(C.av_new_program((*C.struct_AVFormatContext)(s), C.int(id))) +} + +//int avformat_alloc_output_context2 (AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename) +//Allocate an AVFormatContext for an output format. +func Avformat_alloc_output_context2(ctx **AVFormatContext, o *AVOutputFormat, fo, fi string) int { + return int(C.avformat_alloc_output_context2((**C.struct_AVFormatContext)(unsafe.Pointer(ctx)), (*C.struct_AVOutputFormat)(o), C.CString(fo), C.CString(fi))) +} + +//AVInputFormat * av_find_input_format (const char *short_name) +//Find AVInputFormat based on the short name of the input format. +func Av_find_input_format(s string) *AVInputFormat { + return (*AVInputFormat)(C.av_find_input_format(C.CString(s))) +} + +//AVInputFormat * av_probe_input_format (AVProbeData *pd, int is_opened) +//Guess the file format. +func Av_probe_input_format(pd *AVProbeData, i int) *AVInputFormat { + return (*AVInputFormat)(C.av_probe_input_format((*C.struct_AVProbeData)(pd), C.int(i))) +} + +//AVInputFormat * av_probe_input_format2 (AVProbeData *pd, int is_opened, int *score_max) +//Guess the file format. +func Av_probe_input_format2(pd *AVProbeData, o int, sm *int) *AVInputFormat { + return (*AVInputFormat)(C.av_probe_input_format2((*C.struct_AVProbeData)(pd), C.int(o), (*C.int)(unsafe.Pointer(sm)))) +} + +//AVInputFormat * av_probe_input_format3 (AVProbeData *pd, int is_opened, int *score_ret) +//Guess the file format. +func Av_probe_input_format3(pd *AVProbeData, o int, sl *int) *AVInputFormat { + return (*AVInputFormat)(C.av_probe_input_format3((*C.struct_AVProbeData)(pd), C.int(o), (*C.int)(unsafe.Pointer(sl)))) +} + +//int av_probe_input_buffer2 (AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size) +//Probe a bytestream to determine the input format. +func Av_probe_input_buffer2(pb *AVIOContext, f **AVInputFormat, fi string, l int, o, m uint) int { + return int(C.av_probe_input_buffer2((*C.struct_AVIOContext)(pb), (**C.struct_AVInputFormat)(unsafe.Pointer(f)), C.CString(fi), unsafe.Pointer(&l), C.uint(o), C.uint(m))) +} + +//int av_probe_input_buffer (AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size) +//Like av_probe_input_buffer2() but returns 0 on success. +func Av_probe_input_buffer(pb *AVIOContext, f **AVInputFormat, fi string, l int, o, m uint) int { + return int(C.av_probe_input_buffer((*C.struct_AVIOContext)(pb), (**C.struct_AVInputFormat)(unsafe.Pointer(f)), C.CString(fi), unsafe.Pointer(&l), C.uint(o), C.uint(m))) +} + +//int avformat_open_input (AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options) +//Open an input stream and read the header. +func Avformat_open_input(ps **AVFormatContext, fi string, fmt *AVInputFormat, d **AVDictionary) int { + return int(C.avformat_open_input((**C.struct_AVFormatContext)(unsafe.Pointer(ps)), C.CString(fi), (*C.struct_AVInputFormat)(fmt), (**C.struct_AVDictionary)(unsafe.Pointer(d)))) +} + +//int avformat_find_stream_info (AVFormatContext *ic, AVDictionary **options) +//Read packets of a media file to get stream information. +func Avformat_find_stream_info(ic *AVFormatContext, d **AVDictionary) int { + return int(C.avformat_find_stream_info((*C.struct_AVFormatContext)(ic), (**C.struct_AVDictionary)(unsafe.Pointer(d)))) +} + +//AVProgram * av_find_program_from_stream (AVFormatContext *ic, AVProgram *last, int s) +//Find the programs which belong to a given stream. +func Av_find_program_from_stream(ic *AVFormatContext, l *AVProgram, s int) *AVProgram { + return (*AVProgram)(C.av_find_program_from_stream((*C.struct_AVFormatContext)(ic), (*C.struct_AVProgram)(l), C.int(s))) +} + +//int av_find_best_stream (AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb, int related_stream, AVCodec **decoder_ret, int flags) +//Find the "best" stream in the file. +func Av_find_best_stream(ic *AVFormatContext, t AVMediaType, ws, rs int, c **AVCodec, f int) int { + return int(C.av_find_best_stream((*C.struct_AVFormatContext)(ic), (C.enum_AVMediaType)(t), C.int(ws), C.int(rs), (**C.struct_AVCodec)(unsafe.Pointer(c)), C.int(f))) +} + +//int av_read_frame (AVFormatContext *s, AVPacket *pkt) +//Return the next frame of a stream. +func Av_read_frame(s *AVFormatContext, pkt *avcodec.AVPacket) int { + return int(C.av_read_frame((*C.struct_AVFormatContext)(unsafe.Pointer(s)), (*C.struct_AVPacket)(unsafe.Pointer(pkt)))) +} + +//int av_seek_frame (AVFormatContext *s, int stream_index, int64_t timestamp, int flags) +//Seek to the keyframe at timestamp. +func Av_seek_frame(s *AVFormatContext, st int, t int64, f int) int { + return int(C.av_seek_frame((*C.struct_AVFormatContext)(s), C.int(st), C.int64_t(t), C.int(f))) +} + +//int avformat_seek_file (AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags) +//Seek to timestamp ts. +func Avformat_seek_file(s *AVFormatContext, si int, mit, ts, mat int64, f int) int { + return int(C.avformat_seek_file((*C.struct_AVFormatContext)(s), C.int(si), C.int64_t(mit), C.int64_t(ts), C.int64_t(mat), C.int(f))) +} + +//int avformat_flush (AVFormatContext *s) +//Discard all internally buffered data. +func Avformat_flush(s *AVFormatContext) int { + return int(C.avformat_flush((*C.struct_AVFormatContext)(s))) +} + +//int av_read_play (AVFormatContext *s) +//Start playing a network-based stream (e.g. +func Av_read_play(s *AVFormatContext) int { + return int(C.av_read_play((*C.struct_AVFormatContext)(s))) +} + +//int av_read_pause (AVFormatContext *s) +//Pause a network-based stream (e.g. +func Av_read_pause(s *AVFormatContext) int { + return int(C.av_read_pause((*C.struct_AVFormatContext)(s))) +} + +//void avformat_close_input (AVFormatContext **s) +//Close an opened input AVFormatContext. +func Avformat_close_input(s *AVFormatContext) { + C.avformat_close_input((**C.struct_AVFormatContext)(unsafe.Pointer(s))) +} + +//int avformat_write_header (AVFormatContext *s, AVDictionary **options) +//Allocate the stream private data and write the stream header to an output media file. +func Avformat_write_header(s *AVFormatContext, o **AVDictionary) int { + return int(C.avformat_write_header((*C.struct_AVFormatContext)(s), (**C.struct_AVDictionary)(unsafe.Pointer(o)))) +} + +//int av_write_frame (AVFormatContext *s, AVPacket *pkt) +//Write a packet to an output media file. +func Av_write_frame(s *AVFormatContext, pkt *AVPacket) int { + return int(C.av_write_frame((*C.struct_AVFormatContext)(s), (*C.struct_AVPacket)(pkt))) +} + +//int av_interleaved_write_frame (AVFormatContext *s, AVPacket *pkt) +//Write a packet to an output media file ensuring correct interleaving. +func Av_interleaved_write_frame(s *AVFormatContext, pkt *AVPacket) int { + return int(C.av_interleaved_write_frame((*C.struct_AVFormatContext)(s), (*C.struct_AVPacket)(pkt))) +} + +//int av_write_uncoded_frame (AVFormatContext *s, int stream_index, AVFrame *frame) +//Write a uncoded frame to an output media file. +func Av_write_uncoded_frame(s *AVFormatContext, si int, f *AVFrame) int { + return int(C.av_write_uncoded_frame((*C.struct_AVFormatContext)(s), C.int(si), (*C.struct_AVFrame)(f))) +} + +//int av_interleaved_write_uncoded_frame (AVFormatContext *s, int stream_index, AVFrame *frame) +//Write a uncoded frame to an output media file. +func Av_interleaved_write_uncoded_frame(s *AVFormatContext, si int, f *AVFrame) int { + return int(C.av_interleaved_write_uncoded_frame((*C.struct_AVFormatContext)(s), C.int(si), (*C.struct_AVFrame)(f))) +} + +//int av_write_uncoded_frame_query (AVFormatContext *s, int stream_index) +//Test whether a muxer supports uncoded frame. +func Av_write_uncoded_frame_query(s *AVFormatContext, si int) int { + return int(C.av_write_uncoded_frame_query((*C.struct_AVFormatContext)(s), C.int(si))) +} + +//int av_write_trailer (AVFormatContext *s) +//Write the stream trailer to an output media file and free the file private data. +func Av_write_trailer(s *AVFormatContext) int { + return int(C.av_write_trailer((*C.struct_AVFormatContext)(s))) +} + +//AVOutputFormat * av_guess_format (const char *short_name, const char *filename, const char *mime_type) +//Return the output format in the list of registered output formats which best matches the provided parameters, or return NULL if there is no match. +func Av_guess_format(sn, f, mt string) *AVOutputFormat { + return (*AVOutputFormat)(C.av_guess_format(C.CString(sn), C.CString(f), C.CString(mt))) +} + +//enum AVCodecID av_guess_codec (AVOutputFormat *fmt, const char *short_name, const char *filename, const char *mime_type, enum AVMediaType type) +//Guess the codec ID based upon muxer and filename. +func Av_guess_codec(fmt *AVOutputFormat, sn, f, mt string, t AVMediaType) AVCodecID { + return (AVCodecID)(C.av_guess_codec((*C.struct_AVOutputFormat)(fmt), C.CString(sn), C.CString(f), C.CString(mt), (C.enum_AVMediaType)(t))) +} + +//int av_get_output_timestamp (struct AVFormatContext *s, int stream, int64_t *dts, int64_t *wall) +//Get timing information for the data currently output. +func Av_get_output_timestamp(s *AVFormatContext, st int, dts, wall *C.int64_t) int { + return int(C.av_get_output_timestamp((*C.struct_AVFormatContext)(s), C.int(st), dts, wall)) +} + +//void av_hex_dump (FILE *f, const uint8_t *buf, int size) +//Send a nice hexadecimal dump of a buffer to the specified file stream. +func Av_hex_dump(f *File, b *uint8, s int) { + C.av_hex_dump((*C.FILE)(f), (*C.uint8_t)(b), C.int(s)) +} + +//void av_hex_dump_log (void *avcl, int level, const uint8_t *buf, int size) +//Send a nice hexadecimal dump of a buffer to the log. +func Av_hex_dump_log(a, l int, b *uint8, s int) { + C.av_hex_dump_log(unsafe.Pointer(&a), C.int(l), (*C.uint8_t)(b), C.int(s)) +} + +//void av_pkt_dump2 (FILE *f, const AVPacket *pkt, int dump_payload, const AVStream *st) +//Send a nice dump of a packet to the specified file stream. +func Av_pkt_dump2(f *File, pkt *AVPacket, dp int, st *AVStream) { + C.av_pkt_dump2((*C.FILE)(f), (*C.struct_AVPacket)(pkt), C.int(dp), (*C.struct_AVStream)(st)) +} + +//void av_pkt_dump_log2 (void *avcl, int level, const AVPacket *pkt, int dump_payload, const AVStream *st) +//Send a nice dump of a packet to the log. +func Av_pkt_dump_log2(a int, l int, pkt *AVPacket, dp int, st *AVStream) { + C.av_pkt_dump_log2(unsafe.Pointer(&a), C.int(l), (*C.struct_AVPacket)(pkt), C.int(dp), (*C.struct_AVStream)(st)) +} + +//enum AVCodecID av_codec_get_id (const struct AVCodecTag *const *tags, unsigned int tag) +//Get the AVCodecID for the given codec tag tag. +func Av_codec_get_id(t **AVCodecTag, tag uint) AVCodecID { + return (AVCodecID)(C.av_codec_get_id((**C.struct_AVCodecTag)(unsafe.Pointer(t)), C.uint(tag))) +} + +//unsigned int av_codec_get_tag (const struct AVCodecTag *const *tags, enum AVCodecID id) +//Get the codec tag for the given codec id id. +func Av_codec_get_tag(t **AVCodecTag, id AVCodecID) uint { + return uint(C.av_codec_get_tag((**C.struct_AVCodecTag)(unsafe.Pointer(t)), (C.enum_AVCodecID)(id))) +} + +//int av_codec_get_tag2 (const struct AVCodecTag *const *tags, enum AVCodecID id, unsigned int *tag) +//Get the codec tag for the given codec id. +func Av_codec_get_tag2(t **AVCodecTag, id AVCodecID, tag *uint) int { + return int(C.av_codec_get_tag2((**C.struct_AVCodecTag)(unsafe.Pointer(t)), (C.enum_AVCodecID)(id), (*C.uint)(unsafe.Pointer(tag)))) +} + +//int av_find_default_stream_index (AVFormatContext *s) +func Av_find_default_stream_index(s *AVFormatContext) int { + return int(C.av_find_default_stream_index((*C.struct_AVFormatContext)(s))) +} + +//int av_index_search_timestamp (AVStream *st, int64_t timestamp, int flags) +//Get the index for a specific timestamp. +func Av_index_search_timestamp(st *AVStream, t int64, f int) int { + return int(C.av_index_search_timestamp((*C.struct_AVStream)(st), C.int64_t(t), C.int(f))) +} + +//int av_add_index_entry (AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags) +//Add an index entry into a sorted list. +func Av_add_index_entry(st *AVStream, pos, t, int64, s, d, f int) int { + return int(C.av_add_index_entry((*C.struct_AVStream)(st), C.int64_t(pos), C.int64_t(t), C.int(s), C.int(d), C.int(f))) +} + +//void av_url_split (char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url) +//Split a URL string into components. +func Av_url_split(p string, ps int, a string, as int, h string, hs int, pp *int, path string, psize int, url string) { + C.av_url_split(C.CString(p), C.int(ps), C.CString(a), C.int(as), C.CString(h), C.int(hs), (*C.int)(unsafe.Pointer(pp)), C.CString(path), C.int(psize), C.CString(url)) +} + +//void av_dump_format (AVFormatContext *ic, int index, const char *url, int is_output) +//Print detailed information about the input or output format, such as duration, bitrate, streams, container, programs, metadata, side data, codec and time base. +func Av_dump_format(ic *AVFormatContext, i int, url string, io int) { + C.av_dump_format((*C.struct_AVFormatContext)(unsafe.Pointer(ic)), C.int(i), C.CString(url), C.int(io)) +} + +//int av_get_frame_filename (char *buf, int buf_size, const char *path, int number) +//Return in 'buf' the path with 'd' replaced by a number. +func Av_get_frame_filename(b string, bs int, pa string, n int) int { + return int(C.av_get_frame_filename(C.CString(b), C.int(bs), C.CString(pa), C.int(n))) +} + +//int av_filename_number_test (const char *filename) +//Check whether filename actually is a numbered sequence generator. +func Av_filename_number_test(f string) int { + return int(C.av_filename_number_test(C.CString(f))) +} + +//int av_sdp_create (AVFormatContext *ac[], int n_files, char *buf, int size) +//Generate an SDP for an RTP session. +func Av_sdp_create(ac **AVFormatContext, nf int, b string, s int) int { + return int(C.av_sdp_create((**C.struct_AVFormatContext)(unsafe.Pointer(ac)), C.int(nf), C.CString(b), C.int(s))) +} + +//int av_match_ext (const char *filename, const char *extensions) +//Return a positive value if the given filename has one of the given extensions, 0 otherwise. +func Av_match_ext(f, e string) int { + return int(C.av_match_ext(C.CString(f), C.CString(e))) +} + +//int avformat_query_codec (const AVOutputFormat *ofmt, enum AVCodecID codec_id, int std_compliance) +//Test if the given container can store a codec. +func Avformat_query_codec(o *AVOutputFormat, cd AVCodecID, sc int) int { + return int(C.avformat_query_codec((*C.struct_AVOutputFormat)(o), (C.enum_AVCodecID)(cd), C.int(sc))) +} + +//struct AVCodecTag * avformat_get_riff_video_tags (void) +func Avformat_get_riff_video_tags() *AVCodecTag { + return (*AVCodecTag)(C.avformat_get_riff_video_tags()) +} + +//struct AVCodecTag * avformat_get_riff_audio_tags (void) +func Avformat_get_riff_audio_tags() *AVCodecTag { + return (*AVCodecTag)(C.avformat_get_riff_audio_tags()) +} + +//struct AVCodecTag * avformat_get_mov_video_tags (void) +func Avformat_get_mov_video_tags() *AVCodecTag { + return (*AVCodecTag)(C.avformat_get_mov_video_tags()) +} + +//struct AVCodecTag * avformat_get_mov_audio_tags (void) +func Avformat_get_mov_audio_tags() *AVCodecTag { + return (*AVCodecTag)(C.avformat_get_mov_audio_tags()) +} + +//AVRational av_guess_sample_aspect_ratio (AVFormatContext *format, AVStream *stream, AVFrame *frame) +//Guess the sample aspect ratio of a frame, based on both the stream and the frame aspect ratio. +func Av_guess_sample_aspect_ratio(f *AVFormatContext, st *AVStream, fr *AVFrame) AVRational { + return (AVRational)(C.av_guess_sample_aspect_ratio((*C.struct_AVFormatContext)(f), (*C.struct_AVStream)(st), (*C.struct_AVFrame)(fr))) +} + +//AVRational av_guess_frame_rate (AVFormatContext *ctx, AVStream *stream, AVFrame *frame) +//Guess the frame rate, based on both the container and codec information. +func Av_guess_frame_rate(ctx *AVFormatContext, st *AVStream, fr *AVFrame) AVRational { + return (AVRational)(C.av_guess_frame_rate((*C.struct_AVFormatContext)(ctx), (*C.struct_AVStream)(st), (*C.struct_AVFrame)(fr))) +} + +//int avformat_match_stream_specifier (AVFormatContext *s, AVStream *st, const char *spec) +//Check if the stream st contained in s is matched by the stream specifier spec. +func Avformat_match_stream_specifier(s *AVFormatContext, st *AVStream, spec string) int { + return int(C.avformat_match_stream_specifier((*C.struct_AVFormatContext)(s), (*C.struct_AVStream)(st), C.CString(spec))) +} + +//int avformat_queue_attached_pictures (AVFormatContext *s) +func Avformat_queue_attached_pictures(s *AVFormatContext) int { + return int(C.avformat_queue_attached_pictures((*C.struct_AVFormatContext)(s))) +} diff --git a/avformat/exported.go b/avformat/exported.go new file mode 100644 index 0000000..391b210 --- /dev/null +++ b/avformat/exported.go @@ -0,0 +1,37 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) +*/ +package avformat + +//#cgo pkg-config: libavformat +//#include +import "C" +import ( + "fmt" + "unsafe" +) + +func Nb_streams(n *AVFormatContext) int { + cn := (*C.struct_AVFormatContext)(n) + return int(cn.nb_streams) +} + +func Streams(ctx *AVFormatContext) *AVStream { + cctx := (*C.struct_AVFormatContext)(ctx) + return (*AVStream)(unsafe.Pointer(cctx.streams)) +} + +func Codec_type(s *AVStream, n int) *AVMediaType { + c := Codec(s) + fmt.Println("Codec Type: Fix Method") + if c != nil { + return (*AVMediaType)(unsafe.Pointer(&c.codec_type)) + } else { + return nil + } +} + +func Codec(s *AVStream) *AVCodecContext { + return (*AVCodecContext)(s.codec) +} diff --git a/avutil/avutil.go b/avutil/avutil.go new file mode 100644 index 0000000..0c6c1a3 --- /dev/null +++ b/avutil/avutil.go @@ -0,0 +1,100 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) + + Some generic features and utilities provided by the libavutil library + The libavutil library is a utility library to aid portable multimedia programming. + It contains safe portable string functions, random number generators, data structures, + additional mathematics functions, cryptography and multimedia related functionality +*/ +package avutil + +//#cgo pkg-config: libavutil +//#include +//#include +import "C" +import ( + "unsafe" +) + +type ( + AVOptions C.struct_AVOptions + AVDictionary C.struct_AVDictionary + AVTree C.struct_AVTree + AVRational C.struct_AVRational +) + +type ( + AVMediaType C.enum_AVMediaType + AVPictureType C.enum_AVPictureType +) + +type ( + File C.FILE +) + +//unsigned avutil_version (void) +//Return the LIBAVUTIL_VERSION_INT constant. +func AvutilVersion() uint { + return uint(C.avutil_version()) +} + +//const char * avutil_configuration (void) +//Return the libavutil build-time configuration. +func Avutil_configuration() string { + return C.GoString(C.avutil_configuration()) +} + +//const char * avutil_license (void) +//Return the libavutil license. +func Avutil_license() string { + return C.GoString(C.avutil_license()) +} + +//const char * av_get_media_type_string (enum AVMediaType media_type) +//Return a string describing the media_type enum, NULL if media_type is unknown. +func Av_get_media_type_string(mt AVMediaType) string { + return C.GoString(C.av_get_media_type_string((C.enum_AVMediaType)(mt))) +} + +//char av_get_picture_type_char (enum AVPictureType pict_type) +//Return a single letter to describe the given picture type pict_type. +func Av_get_picture_type_char(pt AVPictureType) string { + return string(C.av_get_picture_type_char((C.enum_AVPictureType)(pt))) +} + +//static void * av_x_if_null (const void *p, const void *x) +//Return x default pointer in case p is NULL. +func Av_x_if_null(p, x int) { + C.av_x_if_null(unsafe.Pointer(&p), unsafe.Pointer(&x)) +} + +//unsigned av_int_list_length_for_size (unsigned elsize, const void *list, uint64_t term) av_pure +//Compute the length of an integer list. +func Av_int_list_length_for_size(e uint, l int, t uint64) uint { + return uint(C.av_int_list_length_for_size(C.uint(e), unsafe.Pointer(&l), (C.uint64_t)(t))) +} + +//FILE * av_fopen_utf8 (const char *path, const char *mode) +//Open a file using a UTF-8 filename. +func Av_fopen_utf8(p, m string) *File { + f := C.av_fopen_utf8(C.CString(p), C.CString(m)) + return (*File)(f) +} + +//AVRational av_get_time_base_q (void) +//Return the fractional representation of the internal time base. +func Av_get_time_base_q() AVRational { + return (AVRational)(C.av_get_time_base_q()) +} + +///////////////////////////////////////////////////////////////////////// +//Exported +///////////////////////////////////////////////////////////////////////// + +func Data(f *AVFrame) *uint8 { + return (*uint8)(unsafe.Pointer((*C.uint8_t)(unsafe.Pointer(&f.data)))) +} +func Linesize(f *AVFrame) int { + return int(*(*C.int)(unsafe.Pointer(&f.linesize))) +} diff --git a/avutil/exported.go b/avutil/exported.go new file mode 100644 index 0000000..d0ce7da --- /dev/null +++ b/avutil/exported.go @@ -0,0 +1,5 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) +*/ +package avutil diff --git a/avutil/frame.go b/avutil/frame.go new file mode 100644 index 0000000..01545e5 --- /dev/null +++ b/avutil/frame.go @@ -0,0 +1,140 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) +*/ +package avutil + +/* + #cgo pkg-config: libavutil + #include + #include +*/ +import "C" +import ( + "unsafe" +) + +type ( + AVBuffer C.struct_AVBuffer + AVBufferRef C.struct_AVBufferRef + AVBufferPool C.struct_AVBufferPool + AVFrame C.struct_AVFrame + AVFrameSideData C.struct_AVFrameSideData +) + +type ( + AVFrameSideDataType C.enum_AVFrameSideDataType +) + +//WHERE ?? +//'get_frame_defaults' undeclared (first use in this function) +//'get_audio_buffer' undeclared (first use in this function) +//'get_video_buffer' undeclared (first use in this function) + +//AVDictionary ** avpriv_frame_get_metadatap (AVFrame *frame) +func Avpriv_frame_get_metadatap(f *AVFrame) **AVDictionary { + return (**AVDictionary)(unsafe.Pointer(C.avpriv_frame_get_metadatap((*C.struct_AVFrame)(unsafe.Pointer(f))))) +} + +//int av_frame_set_qp_table (AVFrame *f, AVBufferRef *buf, int stride, int qp_type) +func Av_frame_set_qp_table(f *AVFrame, b *AVBufferRef, s, q int) int { + return int(C.av_frame_set_qp_table((*C.struct_AVFrame)(unsafe.Pointer(f)), (*C.struct_AVBufferRef)(unsafe.Pointer(b)), C.int(s), C.int(q))) +} + +//int8_t * av_frame_get_qp_table (AVFrame *f, int *stride, int *type) +func Av_frame_get_qp_table(f *AVFrame, s, t *int) int8 { + return int8(*C.av_frame_get_qp_table((*C.struct_AVFrame)(unsafe.Pointer(f)), (*C.int)(unsafe.Pointer(s)), (*C.int)(unsafe.Pointer(t)))) +} + +// //static void get_frame_defaults (AVFrame *frame) +// func Get_frame_defaults(f *AVFrame) { +// C.get_frame_defaults(*C.struct_AVFrame(f)) +// } + +//AVFrame * av_frame_alloc (void) +//Allocate an AVFrame and set its fields to default values. +func Av_frame_alloc() *AVFrame { + return (*AVFrame)(unsafe.Pointer(C.av_frame_alloc())) +} + +//void av_frame_free (AVFrame **frame) +//Free the frame and any dynamically allocated objects in it, e.g. +func Av_frame_free(f *AVFrame) { + C.av_frame_free((**C.struct_AVFrame)(unsafe.Pointer(f))) +} + +// //static int get_video_buffer (AVFrame *frame, int align) +// func Get_video_buffer(f *AVFrame, a int) int { +// return int(C.get_video_buffer(f, C.int(a))) +// } + +// //static int get_audio_buffer (AVFrame *frame, int align) +// func Get_audio_buffer(f *AVFrame, a int) int { +// return C.get_audio_buffer(f, C.int(a)) +// } + +//int av_frame_get_buffer (AVFrame *frame, int align) +//Allocate new buffer(s) for audio or video data. +func Av_frame_get_buffer(f *AVFrame, a int) int { + return int(C.av_frame_get_buffer((*C.struct_AVFrame)(unsafe.Pointer(f)), C.int(a))) +} + +//int av_frame_ref (AVFrame *dst, AVFrame *src) +//Setup a new reference to the data described by an given frame. +func Av_frame_ref(d, s *AVFrame) int { + return int(C.av_frame_ref((*C.struct_AVFrame)(unsafe.Pointer(d)), (*C.struct_AVFrame)(unsafe.Pointer(s)))) +} + +//AVFrame * av_frame_clone (AVFrame *src) +//Create a new frame that references the same data as src. +func Av_frame_clone(f *AVFrame) *AVFrame { + return (*AVFrame)(C.av_frame_clone((*C.struct_AVFrame)(unsafe.Pointer(f)))) +} + +//void av_frame_unref (AVFrame *frame) +//Unreference all the buffers referenced by frame and reset the frame fields. +func Av_frame_unref(f *AVFrame) { + cf := (*C.struct_AVFrame)(unsafe.Pointer(f)) + C.av_frame_unref(cf) +} + +//void av_frame_move_ref (AVFrame *dst, AVFrame *src) +//Move everythnig contained in src to dst and reset src. +func Av_frame_move_ref(d, s *AVFrame) { + C.av_frame_move_ref((*C.struct_AVFrame)(unsafe.Pointer(d)), (*C.struct_AVFrame)(unsafe.Pointer(s))) +} + +//int av_frame_is_writable (AVFrame *frame) +//Check if the frame data is writable. +func Av_frame_is_writable(f *AVFrame) int { + return int(C.av_frame_is_writable((*C.struct_AVFrame)(unsafe.Pointer(f)))) +} + +//int av_frame_make_writable (AVFrame *frame) +//Ensure that the frame data is writable, avoiding data copy if possible. +func Av_frame_make_writable(f *AVFrame) int { + return int(C.av_frame_make_writable((*C.struct_AVFrame)(unsafe.Pointer(f)))) +} + +//int av_frame_copy_props (AVFrame *dst, const AVFrame *src) +//Copy only "metadata" fields from src to dst. +func Av_frame_copy_props(d, s *AVFrame) int { + return int(C.av_frame_copy_props((*C.struct_AVFrame)(unsafe.Pointer(d)), (*C.struct_AVFrame)(unsafe.Pointer(s)))) +} + +//AVBufferRef * av_frame_get_plane_buffer (AVFrame *frame, int plane) +//Get the buffer reference a given data plane is stored in. +func Av_frame_get_plane_buffer(f *AVFrame, p int) *AVBufferRef { + return (*AVBufferRef)(C.av_frame_get_plane_buffer((*C.struct_AVFrame)(unsafe.Pointer(f)), C.int(p))) +} + +//AVFrameSideData * av_frame_new_side_data (AVFrame *frame, enum AVFrameSideDataType type, int size) +//Add a new side data to a frame. +func Av_frame_new_side_data(f *AVFrame, d AVFrameSideDataType, s int) *AVFrameSideData { + return (*AVFrameSideData)(C.av_frame_new_side_data((*C.struct_AVFrame)(unsafe.Pointer(f)), (C.enum_AVFrameSideDataType)(d), C.int(s))) +} + +//AVFrameSideData * av_frame_get_side_data (AVFrame *frame, enum AVFrameSideDataType type) +func Av_frame_get_side_data(f *AVFrame, t AVFrameSideDataType) *AVFrameSideData { + return (*AVFrameSideData)(C.av_frame_get_side_data((*C.struct_AVFrame)(unsafe.Pointer(f)), (C.enum_AVFrameSideDataType)(t))) +} diff --git a/avutil/memory.go b/avutil/memory.go new file mode 100644 index 0000000..5861dab --- /dev/null +++ b/avutil/memory.go @@ -0,0 +1,150 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) +*/ +package avutil + +/* + #cgo pkg-config: libavutil + #include + #include + #include +*/ +import "C" +import ( + "unsafe" +) + +//void * av_malloc (size_t size) av_malloc_attrib 1(1) +//Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if available on the CPU). +func Av_malloc(s uintptr) unsafe.Pointer { + return unsafe.Pointer(C.av_malloc(C.size_t(s))) +} + +//static void * av_malloc_array (size_t nmemb, size_t size) +func Av_malloc_array(n, s uintptr) unsafe.Pointer { + return C.av_malloc_array(C.size_t(n), C.size_t(s)) +} + +//void * av_realloc (void *ptr, size_t size) 1(2) +//Allocate or reallocate a block of memory. +func Av_realloc(p *int, s uintptr) unsafe.Pointer { + return C.av_realloc(unsafe.Pointer(&p), C.size_t(s)) +} + +//void * av_realloc_f (void *ptr, size_t nelem, size_t elsize) +//Allocate or reallocate a block of memory. +func Av_realloc_f(p int, n, e uintptr) unsafe.Pointer { + return C.av_realloc_f(unsafe.Pointer(&p), C.size_t(n), C.size_t(e)) +} + +//int av_reallocp (void *ptr, size_t size) +//Allocate or reallocate a block of memory. +func Av_reallocp(p int, s uintptr) int { + return int(C.av_reallocp(unsafe.Pointer(&p), C.size_t(s))) +} + +//void * av_realloc_array (void *ptr, size_t nmemb, size_t size) +func Av_realloc_array(p int, n, s uintptr) unsafe.Pointer { + return C.av_realloc_array(unsafe.Pointer(&p), C.size_t(n), C.size_t(s)) +} + +//int av_reallocp_array (void *ptr, size_t nmemb, size_t size) +func Av_reallocp_array(p int, n, s uintptr) int { + return int(C.av_reallocp_array(unsafe.Pointer(&p), C.size_t(n), C.size_t(s))) +} + +//void av_free (void *ptr) +//Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). +func Av_free(p unsafe.Pointer) { + C.av_free(p) +} + +//void * av_mallocz (size_t size) av_malloc_attrib 1(1) +//Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if available on the CPU) and zero all the bytes of the block. +func Av_mallocz(s uintptr) unsafe.Pointer { + return C.av_mallocz(C.size_t(s)) +} + +//void * av_calloc (size_t nmemb, size_t size) av_malloc_attrib +//Allocate a block of nmemb * size bytes with alignment suitable for all memory accesses (including vectors if available on the CPU) and zero all the bytes of the block. +func Av_calloc(n, s uintptr) unsafe.Pointer { + return C.av_calloc(C.size_t(n), C.size_t(s)) +} + +//static void * av_mallocz_array (size_t nmemb, size_t size) +func Av_mallocz_array(n, s uintptr) unsafe.Pointer { + return C.av_mallocz_array(C.size_t(n), C.size_t(s)) +} + +//char * av_strdup (const char *s) av_malloc_attrib +//Duplicate the string s. +func Av_strdup(s string) string { + return C.GoString(C.av_strdup(C.CString(s))) +} + +//char * av_strndup (const char *s, size_t len) av_malloc_attrib +//Duplicate a substring of the string s. +func Av_strndup(s string, l uintptr) string { + return C.GoString(C.av_strndup(C.CString(s), C.size_t(l))) +} + +//void * av_memdup (const void *p, size_t size) +//Duplicate the buffer p. +func Av_memdup(p *int, s uintptr) unsafe.Pointer { + return C.av_memdup(unsafe.Pointer(p), C.size_t(s)) +} + +//void av_freep (void *ptr) +//Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer pointing to it to NULL. +func Av_freep(p unsafe.Pointer) { + C.av_freep(p) +} + +//void av_dynarray_add (void *tab_ptr, int *nb_ptr, void *elem) +//Add an element to a dynamic array. +func Av_dynarray_add(t unsafe.Pointer, n *int, e unsafe.Pointer) { + C.av_dynarray_add(t, (*C.int)(unsafe.Pointer(n)), e) +} + +//int av_dynarray_add_nofree (void *tab_ptr, int *nb_ptr, void *elem) +//Add an element to a dynamic array. +func Av_dynarray_add_nofree(p unsafe.Pointer, n *int, e unsafe.Pointer) int { + return int(C.av_dynarray_add_nofree(p, (*C.int)(unsafe.Pointer(&n)), e)) +} + +//void * av_dynarray2_add (void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data) +//Add an element of size elem_size to a dynamic array. +func Av_dynarray2_add(t *unsafe.Pointer, n *int, e uintptr, d uint8) unsafe.Pointer { + return C.av_dynarray2_add(t, (*C.int)(unsafe.Pointer(&n)), (C.size_t)(e), (*C.uint8_t)(unsafe.Pointer(&d))) +} + +//static int av_size_mult (size_t a, size_t b, size_t *r) +//Multiply two size_t values checking for overflow. +func Av_size_mult(a, b uintptr, r *uintptr) int { + return int(C.av_size_mult((C.size_t)(a), (C.size_t)(b), (*C.size_t)(unsafe.Pointer(r)))) +} + +//void av_max_alloc (size_t max) +//Set the maximum size that may me allocated in one block. +func Av_max_alloc(m uintptr) { + C.av_max_alloc(C.size_t(m)) +} + +//void av_memcpy_backptr (uint8_t *dst, int back, int cnt) +//deliberately overlapping memcpy implementation +func Av_memcpy_backptr(d *uintptr, b, c int) { + C.av_memcpy_backptr((*C.uint8_t)(unsafe.Pointer(d)), C.int(b), C.int(c)) +} + +//void * av_fast_realloc (void *ptr, unsigned int *size, size_t min_size) +//Reallocate the given block if it is not large enough, otherwise do nothing. +func Av_fast_realloc(p unsafe.Pointer, s *uint, m uintptr) unsafe.Pointer { + return C.av_fast_realloc(p, (*C.uint)(unsafe.Pointer(s)), (C.size_t)(m)) +} + +//void av_fast_malloc (void *ptr, unsigned int *size, size_t min_size) +//Allocate a buffer, reusing the given one if large enough. +func Av_fast_malloc(p unsafe.Pointer, s *uint, m uintptr) { + C.av_fast_malloc(p, (*C.uint)(unsafe.Pointer(s)), (C.size_t)(m)) +} diff --git a/example/tutorial01.c.source b/example/tutorial01.c.source new file mode 100644 index 0000000..cc191c2 --- /dev/null +++ b/example/tutorial01.c.source @@ -0,0 +1,195 @@ +// tutorial01.c +// Code based on a tutorial by Martin Bohme (boehme@inb.uni-luebeckREMOVETHIS.de) +// Tested on Gentoo, CVS version 5/01/07 compiled with GCC 4.1.1 +// With updates from https://github.com/chelyaev/ffmpeg-tutorial +// Updates tested on: +// LAVC 54.59.100, LAVF 54.29.104, LSWS 2.1.101 +// on GCC 4.7.2 in Debian February 2015 + +// A small sample program that shows how to use libavformat and libavcodec to +// read video from a file. +// +// Use +// +// gcc -o tutorial01 tutorial01.c -lavformat -lavcodec -lswscale -lz +// +// to build (assuming libavformat and libavcodec are correctly installed +// your system). +// +// Run using +// +// tutorial01 myvideofile.mpg +// +// to write the first five frames from "myvideofile.mpg" to disk in PPM +// format. + +#include +#include +#include + +#include + +// compatibility with newer API +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1) +#define av_frame_alloc avcodec_alloc_frame +#define av_frame_free avcodec_free_frame +#endif + +void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) { + FILE *pFile; + char szFilename[32]; + int y; + + // Open file + sprintf(szFilename, "frame%d.ppm", iFrame); + pFile=fopen(szFilename, "wb"); + if(pFile==NULL) + return; + + // Write header + fprintf(pFile, "P6\n%d %d\n255\n", width, height); + + // Write pixel data + for(y=0; ydata[0]+y*pFrame->linesize[0], 1, width*3, pFile); + + // Close file + fclose(pFile); +} + +int main(int argc, char *argv[]) { + // Initalizing these to NULL prevents segfaults! + AVFormatContext *pFormatCtx = NULL; + int i, videoStream; + AVCodecContext *pCodecCtxOrig = NULL; + AVCodecContext *pCodecCtx = NULL; + AVCodec *pCodec = NULL; + AVFrame *pFrame = NULL; + AVFrame *pFrameRGB = NULL; + AVPacket packet; + int frameFinished; + int numBytes; + uint8_t *buffer = NULL; + struct SwsContext *sws_ctx = NULL; + + if(argc < 2) { + printf("Please provide a movie file\n"); + return -1; + } + // Register all formats and codecs + av_register_all(); + + // Open video file + if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0) + return -1; // Couldn't open file + + // Retrieve stream information + if(avformat_find_stream_info(pFormatCtx, NULL)<0) + return -1; // Couldn't find stream information + + // Dump information about file onto standard error + av_dump_format(pFormatCtx, 0, argv[1], 0); + + // Find the first video stream + videoStream=-1; + for(i=0; inb_streams; i++) + if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { + videoStream=i; + break; + } + if(videoStream==-1) + return -1; // Didn't find a video stream + + // Get a pointer to the codec context for the video stream + pCodecCtxOrig=pFormatCtx->streams[videoStream]->codec; + // Find the decoder for the video stream + pCodec=avcodec_find_decoder(pCodecCtxOrig->codec_id); + if(pCodec==NULL) { + fprintf(stderr, "Unsupported codec!\n"); + return -1; // Codec not found + } + // Copy context + pCodecCtx = avcodec_alloc_context3(pCodec); + if(avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) { + fprintf(stderr, "Couldn't copy codec context"); + return -1; // Error copying codec context + } + + // Open codec + if(avcodec_open2(pCodecCtx, pCodec, NULL)<0) + return -1; // Could not open codec + + // Allocate video frame + pFrame=av_frame_alloc(); + + // Allocate an AVFrame structure + pFrameRGB=av_frame_alloc(); + if(pFrameRGB==NULL) + return -1; + + // Determine required buffer size and allocate buffer + numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, + pCodecCtx->height); + buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); + + // Assign appropriate parts of buffer to image planes in pFrameRGB + // Note that pFrameRGB is an AVFrame, but AVFrame is a superset + // of AVPicture + avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, + pCodecCtx->width, pCodecCtx->height); + + // initialize SWS context for software scaling + sws_ctx = sws_getContext(pCodecCtx->width, + pCodecCtx->height, + pCodecCtx->pix_fmt, + pCodecCtx->width, + pCodecCtx->height, + PIX_FMT_RGB24, + SWS_BILINEAR, + NULL, + NULL, + NULL + ); + + // Read frames and save first five frames to disk + i=0; + while(av_read_frame(pFormatCtx, &packet)>=0) { + // Is this a packet from the video stream? + if(packet.stream_index==videoStream) { + // Decode video frame + avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); + + // Did we get a video frame? + if(frameFinished) { + // Convert the image from its native format to RGB + sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, + pFrame->linesize, 0, pCodecCtx->height, + pFrameRGB->data, pFrameRGB->linesize); + + // Save the frame to disk + if(++i<=5) + SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, + i); + } + } + + // Free the packet that was allocated by av_read_frame + av_free_packet(&packet); + } + + // Free the RGB image + av_free(buffer); + av_frame_free(&pFrameRGB); + + // Free the YUV frame + av_frame_free(&pFrame); + + // Close the codecs + avcodec_close(pCodecCtx); + avcodec_close(pCodecCtxOrig); + + // Close the video file + avformat_close_input(&pFormatCtx); + + return 0; +} \ No newline at end of file diff --git a/example/tutorial01.go b/example/tutorial01.go new file mode 100644 index 0000000..a60ae1e --- /dev/null +++ b/example/tutorial01.go @@ -0,0 +1,236 @@ +package main + +import ( + "fmt" + "github.com/giorgisio/gfg/avcodec" + "github.com/giorgisio/gfg/avformat" + "github.com/giorgisio/gfg/avutil" + "github.com/giorgisio/gfg/swscale" + "log" + "os" + "unsafe" +) + +func main() { + + filename := "/home/giorgis/media/sample2.mp4" + + var ( + pFormatCtx *avformat.AVFormatContext + pCodecCtxOrig *avcodec.AVCodecContext + pCodecCtx *avcodec.AVCodecContext + pCodec *avcodec.AVCodec + pFrame *avutil.AVFrame + pFrameRGB *avutil.AVFrame + packet *avcodec.AVPacket + media_type *avutil.AVMediaType + sws_ctx *swscale.SwsContext + videoStream int + frameFinished int + numBytes int + url string + ) + + // Register all formats and codecs + avformat.Av_register_all() + + // Open video file + if avformat.Avformat_open_input(&pFormatCtx, filename, nil, nil) != 0 { + return + } + + // Retrieve stream information + if avformat.Avformat_find_stream_info(pFormatCtx, nil) < 0 { + log.Println("Error: Couldn't find stream information.") + return + } + + // Dump information about file onto standard error + avformat.Av_dump_format(pFormatCtx, 0, url, 0) + + // Find the first video stream + videoStream = -1 + + //pFormatCtx->nb_streams + n := avformat.Nb_streams(pFormatCtx) + + //pFormatCtx->streams[] + s := avformat.Streams(pFormatCtx) + //s2 := avformat.StreamsOne(pFormatCtx, 1) + + log.Println("Number of Streams:", n) + + for i := 0; i < n; i++ { + // pFormatCtx->streams[i]->codec->codec_type + log.Println("Stream Number:", i) + + if (*avutil.AVMediaType)(avformat.Codec_type(s, i)) != media_type { + videoStream = i + break + } + } + + if videoStream == -1 { + return // Didn't find a video stream + } + + codec := avformat.Codec(s) + log.Println("Codec:", codec) + + // Get a pointer to the codec context for the video stream + //pCodecCtxOrig = pFormatCtx.streams[videoStream].codec + pCodecCtxOrig = (*avcodec.AVCodecContext)(unsafe.Pointer(codec)) + log.Println("Codec Context:", pCodecCtxOrig) + + //C.enum_AVCodecID + codec_id := avcodec.Codec_id(pCodecCtxOrig) + log.Println("Codec ID:", codec_id) + + // Find the decoder for the video stream + pCodec = avcodec.Avcodec_find_decoder(codec_id) + if pCodec == nil { + log.Println("Error: Unsupported codec!") + return // Codec not found + } + + // Copy context + pCodecCtx = avcodec.Avcodec_alloc_context3(pCodec) + + if avcodec.Avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0 { + log.Println("Error: Couldn't copy codec context") + return // Error copying codec context + } + + // Open codec + if avcodec.Avcodec_open2(pCodecCtx, pCodec, nil) < 0 { + return // Could not open codec + } + + // Allocate video frame + pFrame = avutil.Av_frame_alloc() + + // Allocate an AVFrame structure + if pFrameRGB = avutil.Av_frame_alloc(); pFrameRGB == nil { + return + } + + //##TODO + var a swscale.AVPixelFormat + var b int + //avcodec.AVPixelFormat + //avcodec.PIX_FMT_RGB24 + //avcodec.SWS_BILINEAR + + w := avcodec.Width(pCodecCtx) + h := avcodec.Height(pCodecCtx) + pix_fmt := avcodec.Pix_fmt(pCodecCtx) + + // Determine required buffer size and allocate buffer + numBytes = avcodec.Avpicture_get_size((avcodec.AVPixelFormat)(a), w, h) + + buffer := avutil.Av_malloc(uintptr(numBytes)) + + // Assign appropriate parts of buffer to image planes in pFrameRGB + // Note that pFrameRGB is an AVFrame, but AVFrame is a superset + // of AVPicture + avcodec.Avpicture_fill((*avcodec.AVPicture)(unsafe.Pointer(pFrameRGB)), (*uint8)(buffer), (avcodec.AVPixelFormat)(a), w, h) + + // initialize SWS context for software scaling + sws_ctx = swscale.Sws_getContext(w, + h, + (swscale.AVPixelFormat)(pix_fmt), + w, + h, + a, + b, + nil, + nil, + nil, + ) + + // Read frames and save first five frames to disk + i := 0 + + for avformat.Av_read_frame(pFormatCtx, packet) >= 0 { + // Is this a packet from the video stream? + s := avcodec.Stream_index(packet) + if s == videoStream { + // Decode video frame + avcodec.Avcodec_decode_video2(pCodecCtx, (*avcodec.AVFrame)(unsafe.Pointer(pFrame)), &frameFinished, packet) + + // Did we get a video frame? + if frameFinished > 0 { + // Convert the image from its native format to RGB + d := avutil.Data(pFrame) + l := avutil.Linesize(pFrame) + dr := avutil.Data(pFrameRGB) + lr := avutil.Linesize(pFrameRGB) + swscale.Sws_scale(sws_ctx, + d, + l, + 0, + h, + dr, + lr, + ) + + // Save the frame to disk + if i <= 5 { + saveFrame(pFrameRGB, w, h, i) + } + i++ + } + } + + // Free the packet that was allocated by av_read_frame + avcodec.Av_free_packet(packet) + } + + // Free the RGB image + avutil.Av_free(buffer) + avutil.Av_frame_free(pFrameRGB) + + // Free the YUV frame + avutil.Av_frame_free(pFrame) + + // Close the codecs + avcodec.Avcodec_close(pCodecCtx) + avcodec.Avcodec_close(pCodecCtxOrig) + + // Close the video file + avformat.Avformat_close_input(pFormatCtx) + +} + +func saveFrame(pFrame *avutil.AVFrame, width int, height int, iFrame int) { + + var szFilename string + var y int + var file *os.File + var err error + + szFilename = "" + + // Open file + szFilename = fmt.Sprintf("frame%d.ppm", iFrame) + + if file, err = os.Open(szFilename); err != nil { + log.Println("Error Reading") + } + + // Write header + fh := fmt.Sprintf("P6\n%d %d\n255\n", width, height) + log.Println(fh) + + // Write pixel data + for y = 0; y < height; y++ { + // d := avutil.Data(pFrame) + // l := avutil.Linesize(pFrame) + //##TODO + f := make([]byte, 100) + file.Write(f) + } + + file.Close() + +} diff --git a/example/versions.go b/example/versions.go new file mode 100644 index 0000000..142df28 --- /dev/null +++ b/example/versions.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + //"github.com/giorgisio/gfg/avcodec" + "github.com/giorgisio/gfg/avdevice" //Just for test + "github.com/giorgisio/gfg/avfilter" //Just for test + "github.com/giorgisio/gfg/avformat" + //"github.com/giorgisio/gfg/avutil" + "github.com/giorgisio/gfg/swresample" //Just for test + //"github.com/giorgisio/gfg/swscale" +) + +func main() { + fmt.Println("Testing:") + + // Register all formats and codecs + avformat.Av_register_all() + avfilter.Avfilter_version() + avdevice.Avdevice_version() + swresample.Swresample_license() +} diff --git a/gfg.go b/gfg.go new file mode 100644 index 0000000..173f6d3 --- /dev/null +++ b/gfg.go @@ -0,0 +1,18 @@ +package gfg + +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) + + Contains: + + libavcodec: encoding/decoding library + libavfilter: graph-based frame editing library + libavformat: I/O and muxing/demuxing library + libavdevice: special devices muxing/demuxing library + libavutil: common utility library + libswresample: audio resampling, format conversion and mixing + libpostproc: post processing library + libswscale: color conversion and scaling library + +*/ diff --git a/swresample/swresample.go b/swresample/swresample.go new file mode 100644 index 0000000..fecacc8 --- /dev/null +++ b/swresample/swresample.go @@ -0,0 +1,153 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) + + The process of changing the sampling rate of a discrete signal to obtain + a new discrete representation of the underlying continuous signal. + resampler provides a high-level interface to the libswresample library audio resampling utilities +*/ +package swresample + +/* + #cgo pkg-config: libswresample + #include +*/ +import "C" +import ( + "unsafe" +) + +type ( + SwrContext C.struct_SwrContext + AVFrame C.struct_AVFrame + AVClass C.struct_AVClass + AVSampleFormat C.enum_AVSampleFormat +) + +//const AVClass * swr_get_class (void) +//Get the AVClass for SwrContext. +func Swr_get_class() *AVClass { + return (*AVClass)(C.swr_get_class()) +} + +//SwrContext constructor functions +//struct SwrContext * swr_alloc (void) +//Allocate SwrContext. +func Swr_alloc() *SwrContext { + return (*SwrContext)(C.swr_alloc()) +} + +//int swr_init (struct SwrContext *s) +//Initialize context after user parameters have been set. +func Swr_init(s *SwrContext) int { + return int(C.swr_init((*C.struct_SwrContext)(s))) +} + +//int swr_is_initialized (struct SwrContext *s) +//Check whether an swr context has been initialized or not. +func Swr_is_initialized(s *SwrContext) int { + return int(C.swr_is_initialized((*C.struct_SwrContext)(s))) +} + +//struct SwrContext * swr_alloc_set_opts (struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx) +//Allocate SwrContext if needed and set/reset common parameters. +func Swr_alloc_set_opts(s *SwrContext, ocl int64, osf AVSampleFormat, osr int, icl int64, isf AVSampleFormat, isr, lo, lc int) *SwrContext { + return (*SwrContext)(C.swr_alloc_set_opts((*C.struct_SwrContext)(s), C.int64_t(ocl), (C.enum_AVSampleFormat)(osf), C.int(osr), C.int64_t(icl), (C.enum_AVSampleFormat)(isf), C.int(isr), C.int(lo), unsafe.Pointer(&lc))) +} + +//SwrContext destructor functions +//void swr_free (struct SwrContext **s) +//Free the given SwrContext and set the pointer to NULL. +func Swr_free(s **SwrContext) { + C.swr_free((**C.struct_SwrContext)(unsafe.Pointer(s))) +} + +//void swr_close (struct SwrContext *s) +//Closes the context so that swr_is_initialized() returns 0. +func Swr_close(s *SwrContext) { + C.swr_close((*C.struct_SwrContext)(s)) +} + +//Core conversion functions +//int swr_convert (struct SwrContext *s, uint8_t **out, int out_count, const uint8_t **in, int in_count) +//Convert audio. +func Swr_convert(s *SwrContext, out **uint8, oc int, in **uint8, ic int) int { + return int(C.swr_convert((*C.struct_SwrContext)(s), (**C.uint8_t)(unsafe.Pointer(out)), C.int(oc), (**C.uint8_t)(unsafe.Pointer(in)), C.int(ic))) +} + +//int64_t swr_next_pts (struct SwrContext *s, int64_t pts) +//Convert the next timestamp from input to output timestamps are in 1/(in_sample_rate * out_sample_rate) units. +func Swr_next_pts(s *SwrContext, pts int64) int64 { + return int64(C.swr_next_pts((*C.struct_SwrContext)(s), C.int64_t(pts))) +} + +//Low-level option setting functions +//These functons provide a means to set low-level options that is not possible with the AVOption API. +//int swr_set_compensation (struct SwrContext *s, int sample_delta, int compensation_distance) +//Activate resampling compensation ("soft" compensation). +func Swr_set_compensation(s *SwrContext, sd, cd int) int { + return int(C.swr_set_compensation((*C.struct_SwrContext)(s), C.int(sd), C.int(cd))) +} + +//int swr_set_channel_mapping (struct SwrContext *s, const int *channel_map) +//Set a customized input channel mapping. +func Swr_set_channel_mapping(s *SwrContext, cm *int) int { + return int(C.swr_set_channel_mapping((*C.struct_SwrContext)(s), (*C.int)(unsafe.Pointer(cm)))) +} + +//int swr_set_matrix (struct SwrContext *s, const double *matrix, int stride) +//Set a customized remix matrix. +func Swr_set_matrix(s *SwrContext, m *int, t int) int { + return int(C.swr_set_matrix((*C.struct_SwrContext)(s), (*C.double)(unsafe.Pointer(m)), C.int(t))) +} + +//Sample handling functions +//int swr_drop_output (struct SwrContext *s, int count) +//Drops the specified number of output samples. +func Swr_drop_output(s *SwrContext, c int) int { + return int(C.swr_drop_output((*C.struct_SwrContext)(s), C.int(c))) +} + +//int swr_inject_silence (struct SwrContext *s, int count) +//Injects the specified number of silence samples. +func Swr_inject_silence(s *SwrContext, c int) int { + return int(C.swr_inject_silence((*C.struct_SwrContext)(s), C.int(c))) +} + +//int64_t swr_get_delay (struct SwrContext *s, int64_t base) +//Gets the delay the next input sample will experience relative to the next output sample. +func Swr_get_delay(s *SwrContext, b int64) int64 { + return int64(C.swr_get_delay((*C.struct_SwrContext)(s), C.int64_t(b))) +} + +//Configuration accessors +//unsigned swresample_version (void) +//Return the LIBSWRESAMPLE_VERSION_INT constant. +func Swresample_version() uint { + return uint(C.swresample_version()) +} + +//const char * swresample_configuration (void) +//Return the swr build-time configuration. +func Swresample_configuration() string { + return C.GoString(C.swresample_configuration()) +} + +//const char * swresample_license (void) +//Return the swr license. +func Swresample_license() string { + return C.GoString(C.swresample_license()) +} + +//AVFrame based API +//int swr_convert_frame (SwrContext *swr, AVFrame *output, const AVFrame *input) +//Convert the samples in the input AVFrame and write them to the output AVFrame. +func Swr_convert_frame(s *SwrContext, o, i *AVFrame) int { + return int(C.swr_convert_frame((*C.struct_SwrContext)(s), (*C.struct_AVFrame)(o), (*C.struct_AVFrame)(i))) +} + +//int swr_config_frame (SwrContext *swr, const AVFrame *out, const AVFrame *in) +//Configure or reconfigure the SwrContext using the information provided by the AVFrames. +func Swr_config_frame(s *SwrContext, o, i *AVFrame) int { + return int(C.swr_config_frame((*C.struct_SwrContext)(s), (*C.struct_AVFrame)(o), (*C.struct_AVFrame)(i))) +} diff --git a/swscale/swscale.go b/swscale/swscale.go new file mode 100644 index 0000000..78e6e10 --- /dev/null +++ b/swscale/swscale.go @@ -0,0 +1,235 @@ +/* + Use of this source code is governed by a MIT license that can be found in the LICENSE file. + by Giorgis (habtom@giorgis.io) + + libswscale library performs highly optimized image scaling and colorspace and pixel format conversion operations. + Rescaling: is the process of changing the video size. Several rescaling options and algorithms are available. + Pixel format conversion: is the process of converting the image format and colorspace of the image. +*/ +package swscale + +//#cgo pkg-config: libswscale libavutil +//#include +//#include +//#include +//#include +//#include +//#include +import "C" +import ( + "unsafe" +) + +type ( + SwsContext C.struct_SwsContext + SwsFilter C.struct_SwsFilter + SwsVector C.struct_SwsVector + AVClass C.struct_AVClass +) + +type ( + AVPixelFormat C.enum_AVPixelFormat +) + +//unsigned swscale_version (void) +//Return the LIBSWSCALE_VERSION_INT constant. +func Swscale_version() uint { + return uint(C.swscale_version()) +} + +//const char * swscale_configuration (void) +//Return the libswscale build-time configuration. +func Swscale_configuration() string { + return C.GoString(C.swscale_configuration()) +} + +//const char * swscale_license (void) +//Return the libswscale license. +func Swscale_license() string { + return C.GoString(C.swscale_license()) +} + +//const int * sws_getCoefficients (int colorspace) +//Return a pointer to yuv<->rgb coefficients for the given colorspace suitable for sws_setColorspaceDetails(). +func Sws_getCoefficients(c int) *C.int { + return C.sws_getCoefficients(C.int(c)) +} + +//int sws_isSupportedInput (enum AVPixelFormat pix_fmt) +//Return a positive value if pix_fmt is a supported input format, 0 otherwise. +func Sws_isSupportedInput(p AVPixelFormat) int { + return int(C.sws_isSupportedInput((C.enum_AVPixelFormat)(p))) +} + +//int sws_isSupportedOutput (enum AVPixelFormat pix_fmt) +//Return a positive value if pix_fmt is a supported output format, 0 otherwise. +func Sws_isSupportedOutput(p AVPixelFormat) int { + return int(C.sws_isSupportedOutput((C.enum_AVPixelFormat)(p))) +} + +//int sws_isSupportedEndiannessConversion (enum AVPixelFormat pix_fmt) +func Sws_isSupportedEndiannessConversion(p AVPixelFormat) int { + return int(C.sws_isSupportedEndiannessConversion((C.enum_AVPixelFormat)(p))) +} + +//struct SwsContext * sws_alloc_context (void) +//Allocate an empty SwsContext. +func Sws_alloc_context() *SwsContext { + return (*SwsContext)(C.sws_alloc_context()) +} + +//int sws_init_context (struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter) +//Initialize the swscaler context sws_context. +func Sws_init_context(ctxt *SwsContext, sf, df *SwsFilter) int { + return int(C.sws_init_context((*C.struct_SwsContext)(ctxt), (*C.struct_SwsFilter)(sf), (*C.struct_SwsFilter)(df))) +} + +//void sws_freeContext (struct SwsContext *swsContext) +//Free the swscaler context swsContext. +func Sws_freeContext(ctxt *SwsContext) { + C.sws_freeContext((*C.struct_SwsContext)(ctxt)) +} + +//struct SwsContext * sws_getContext (int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param) +//Allocate and return an SwsContext. +func Sws_getContext(sw, sh int, sf AVPixelFormat, dw, dh int, df AVPixelFormat, f int, sfl, dfl *SwsFilter, p *int) *SwsContext { + return (*SwsContext)(C.sws_getContext(C.int(sw), C.int(sh), (C.enum_AVPixelFormat)(sf), C.int(dw), C.int(dh), (C.enum_AVPixelFormat)(df), C.int(f), (*C.struct_SwsFilter)(sfl), (*C.struct_SwsFilter)(dfl), (*C.double)(unsafe.Pointer(p)))) +} + +////int sws_scale (struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]) +////Scale the image slice in srcSlice and put the resulting scaled slice in the image in dst. +func Sws_scale(ctxt *SwsContext, src *uint8, str int, y, h int, d *uint8, ds int) int { + cctxt := (*C.struct_SwsContext)(unsafe.Pointer(ctxt)) + csrc := (*C.uint8_t)(unsafe.Pointer(src)) + cstr := (*C.int)(unsafe.Pointer(&str)) + cd := (*C.uint8_t)(unsafe.Pointer(d)) + cds := (*C.int)(unsafe.Pointer(&ds)) + return int(C.sws_scale(cctxt, &csrc, cstr, C.int(y), C.int(h), &cd, cds)) +} + +//int sws_setColorspaceDetails (struct SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation) +func Sws_setColorspaceDetails(ctxt *C.struct_SwsContext, it *int, sr int, t *int, dr, b, c, s int) int { + cit := (*C.int)(unsafe.Pointer(it)) + ct := (*C.int)(unsafe.Pointer(t)) + return int(C.sws_setColorspaceDetails(ctxt, cit, C.int(sr), ct, C.int(dr), C.int(b), C.int(c), C.int(s))) +} + +//int sws_getColorspaceDetails (struct SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation) +func Sws_getColorspaceDetails(ctxt *C.struct_SwsContext, it, sr, t, dr, b, c, s *int) int { + cit := (**C.int)(unsafe.Pointer(it)) + csr := (*C.int)(unsafe.Pointer(sr)) + ct := (**C.int)(unsafe.Pointer(t)) + cdr := (*C.int)(unsafe.Pointer(dr)) + cb := (*C.int)(unsafe.Pointer(b)) + cc := (*C.int)(unsafe.Pointer(c)) + cs := (*C.int)(unsafe.Pointer(s)) + return int(C.sws_getColorspaceDetails(ctxt, cit, csr, ct, cdr, cb, cc, cs)) +} + +//SwsVector * sws_allocVec (int length) +//Allocate and return an uninitialized vector with length coefficients. +func Sws_allocVec(l int) *C.struct_SwsVector { + return C.sws_allocVec(C.int(l)) +} + +//SwsVector * sws_getGaussianVec (double variance, double quality) +//Return a normalized Gaussian curve used to filter stuff quality = 3 is high quality, lower is lower quality. +func Sws_getGaussianVec(v, q float64) *C.struct_SwsVector { + return C.sws_getGaussianVec(C.double(v), C.double(q)) +} + +//SwsVector * sws_getConstVec (double c, int length) +//Allocate and return a vector with length coefficients, all with the same value c. +func Sws_getConstVec(c float64, l int) *C.struct_SwsVector { + return C.sws_getConstVec(C.double(c), C.int(l)) +} + +//SwsVector * sws_getIdentityVec (void) +//Allocate and return a vector with just one coefficient, with value 1.0. +func Sws_getIdentityVec() *C.struct_SwsVector { + return C.sws_getIdentityVec() +} + +//void sws_scaleVec (SwsVector *a, double scalar) +//Scale all the coefficients of a by the scalar value. +func Sws_scaleVec(a *SwsVector, s float64) { + ca := (*C.struct_SwsVector)(unsafe.Pointer(a)) + C.sws_scaleVec(ca, C.double(s)) +} + +//void sws_normalizeVec (SwsVector *a, double height) +//Scale all the coefficients of a so that their sum equals height. +func Sws_normalizeVec(a *C.struct_SwsVector, h float64) { + C.sws_normalizeVec(a, C.double(h)) +} + +//void sws_convVec (SwsVector *a, SwsVector *b) +func Sws_convVec(a, b *C.struct_SwsVector) { + C.sws_convVec(a, b) +} + +//void sws_addVec (SwsVector *a, SwsVector *b) +func Sws_addVec(a, b *C.struct_SwsVector) { + C.sws_addVec(a, b) +} + +//void sws_subVec (SwsVector *a, SwsVector *b) +func Sws_subVec(a, b *C.struct_SwsVector) { + C.sws_subVec(a, b) +} + +//void sws_shiftVec (SwsVector *a, int shift) +func Sws_shiftVec(a *C.struct_SwsVector, s int) { + C.sws_shiftVec(a, C.int(s)) +} + +//SwsVector * sws_cloneVec (SwsVector *a) +//Allocate and return a clone of the vector a, that is a vector with the same coefficients as a. +func Sws_cloneVec(a *C.struct_SwsVector) *C.struct_SwsVector { + return C.sws_cloneVec(a) +} + +//void sws_printVec2 (SwsVector *a, AVClass *log_ctx, int log_level) +//Print with av_log() a textual representation of the vector a if log_level <= av_log_level. +func Sws_printVec2(a *C.struct_SwsVector, lctx *C.struct_AVClass, l int) { + C.sws_printVec2(a, lctx, C.int(l)) +} + +//void sws_freeVec (SwsVector *a) +func Sws_freeVec(a *C.struct_SwsVector) { + C.sws_freeVec(a) +} + +//SwsFilter * sws_getDefaultFilter (float lumaGBlur, float chromaGBlur, float lumaSharpen, float chromaSharpen, float chromaHShift, float chromaVShift, int verbose) +func Sws_getDefaultFilter(lb, cb, ls, cs, chs, cvs float32, v int) *C.struct_SwsFilter { + return C.sws_getDefaultFilter(C.float(lb), C.float(cb), C.float(ls), C.float(cs), C.float(chs), C.float(cvs), C.int(v)) +} + +//void sws_freeFilter (SwsFilter *filter) +func Sws_freeFilter(f *C.struct_SwsFilter) { + C.sws_freeFilter(f) +} + +//struct SwsContext * sws_getCachedContext (struct SwsContext *context, int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param) +//Check if context can be reused, otherwise reallocate a new one. +func Sws_getCachedContext(ctxt *C.struct_SwsContext, sw, sh int, sf C.enum_AVPixelFormat, dw, dh int, df C.enum_AVPixelFormat, f int, sfl, dfl *C.struct_SwsFilter, p *C.double) *C.struct_SwsContext { + return C.sws_getCachedContext(ctxt, C.int(sw), C.int(sh), sf, C.int(dw), C.int(dh), df, C.int(f), sfl, dfl, p) +} + +//void sws_convertPalette8ToPacked32 (const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) +//Convert an 8-bit paletted frame into a frame with a color depth of 32 bits. +func Sws_convertPalette8ToPacked32(s, d *C.uint8_t, px int, p *C.uint8_t) { + C.sws_convertPalette8ToPacked32(s, d, C.int(px), p) +} + +//void sws_convertPalette8ToPacked24 (const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) +//Convert an 8-bit paletted frame into a frame with a color depth of 24 bits. +func Sws_convertPalette8ToPacked24(s, d *C.uint8_t, px int, p *C.uint8_t) { + C.sws_convertPalette8ToPacked24(s, d, C.int(px), p) +} + +//const AVClass * sws_get_class (void) +//Get the AVClass for swsContext. +func Sws_get_class() *C.struct_AVClass { + return C.sws_get_class() +}