Grabbing rtsp/rtp stream with libavformat - c

world.
I'm trying to grab rtsp mjpeg stream from IP-camera (realtime) as described in http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html, but ported to newer version.
It works well with mpeg file (loading it full as one AVPacket), but working with stream, avcodec_decode_video2 returns -1 (error). AVPacket in this case is a part of a frame.
How can I fix this?

Related

Changing playback speed using gstreamer

I am currently working on the gstreamer tutorials, in particular the one about playback speed adjustments. I pasted the example code into a file which I compiled with the flags pkg-config --cflags --libs gstreamer-1.0 (my gstreamer version is 1.20.5)
I tried to change the playback rates using the keys S / s, got the corresponding prints (Current rate: 0.5 etc.) but the playback speed stayed constant at 1. I thought that the failure to change the playback speed was due to the source being a remote file, so I changed the code to use local files (as command line arguments) instead:
gchar buffer[4096];
g_snprintf(buffer, 4096, "playbin uri=file://%s", argv[1]);
/* Build the pipeline */
data.pipeline = gst_parse_launch(buffer, &error);
I also switched from the video sink to an audio sink (audio is sufficient for my cases).
I then noticed that whether or not the rate changed works is (apparently) up to the type of the file I am opening: When I open a local ogg file, the playback speed changes, when I open an mp3 instead, nothing happens.
Is this a bug in gstreamer, or do I need a more sophisticated pipeline in order to get the approach to work with different media types (local files would be sufficient for my needs)?
Edit: Complete code, sample mp3

libsox: record from default microphone

I need to open the default audio capture device and start recording. libsox seems to be a nice cross-platform solution. Using the binary frontend, I can just rec test.wav and the default microphone is activated.
However, when browsing the documentation, no similar functionality exists. This thread discusses precisely the same topic as my question, but doesn't seem to have reached a solution.
Where could an example of using libsox for recording from the default audio device be located?
You can record using libsox. Just set the input file to "default" and set the filetype to the audio driver (e.g. coreaudio on mac, alsa or oss on linux)
const char* audio_driver = "alsa";
sox_format_t* input = sox_open_read("default", NULL, NULL, audio_driver);
Look at some examples for more info on how to structure the rest of the code.
You need to record with alsa first and use libsox for the right format. libsox is not for recording. see example: https://gist.github.com/albanpeignier/104902

Can ffmpeg decode G711 audio

I am receiving audio data in RTP stream. The audio can be either in G711 A-law or u-law depending on the source. How to decode the audio byte stream using ffmpeg api's? Can ALSA on Linux directly play the G711 audio format?
Libav for sure supports G.711. The associated codec ID are AV_CODEC_ID_PCM_MULAW and AV_CODEC_ID_PCM_ALAW. I suggest you start from the example program they provide and modify audio_decode_example() in order to use G.711.
avcodec.h: http://libav.org/doxygen/master/avcodec_8h.html
libav example: http://libav.org/doxygen/master/avcodec_8c-example.html

Extracting I-Frames from H264 in MPEG-TS in C

I am experimenting with video and would like to know how I can extract I-frames from H264 contained in MPEG-TS container.
What I want to do is generate preview images out of a video stream.
As the I-frame is supposed to be a complete picture fro which P- and B-Frames derive, is there a possibility to just extract the data of the picture without having to decode it using a codec?
I have already done some work with MPEG-TS container format but I am not that much specialized in codecs.
I am rather in search of information.
Thanks a lot.
I am no expert in this domain but I believe the answer to your question is NO.
If you want to save the I-frame as a JPEG image, you still need to "transcode" the video frame i.e. you first need to decode the I-frame using a H264 decoder and then encode it using a JPEG encoder. This is so because the JPEG encoder does not understand a H264 frame, it only accepts uncompressed video frames as input.
As an aside, since the input to the JPEG encoder is an uncompressed frame, you can generate a JPEG image from any type of frame (I/P/B) as it would already be decoded (using reference I frame, if needed) before feeding to the encoder.
As others have noted decoding h.264 is complicated. You could write your own decoder but it is a major effort. Why not use an existing decoder?
Intel's IPP library has the basic building blocks for a decoder and a sample decoer:
Code Samples for the IntelĀ® Integrated Performance Primitives
There's libavcodec:
Using libavformat and libavcodec
Revised avcodec_sample.0.4.9.cPP
I am not expert in this domain too. But I've played with decoding. Use this gstreamer pipeline to extract preview from video.mp4:
gst-launch -v filesrc location=./video.mp4 ! qtdemux name=demux demux.video_00 ! ffdec_h264 ! videorate ! 'video/x-raw-yuv,framerate=1/1' ! jpegenc ! multifilesink location=image-%05d.jpeg
If you want to write some code, replace videorate with appsrc/appsink elements. Write control program to the pipelines (see example):
filesrc location=./video.mp4 ! qtdemux name=demux demux.video_00 ! ffdec_h264 ! appsink
appsrc ! 'video/x-raw-yuv,framerate=1/1' ! jpegenc ! multifilesink location=image-%05d.jpeg
Buffers without GST_BUFFER_FLAG_DELTA_UNIT flag set is I-frames. You can safely skip many frames and start decoding stream at any I-frame.

Remux MPEG TS -> RTP MPEG ES

Please guide me to achieve the following result in my program (written in C):
I have a stream source as HTTP MPEG TS stream (codecs h264 & aac), It has 1 video and 1 audio substream.
I need to get MPEG ES frames (of same codecs), to send them via RTP to
RTSP clients. It'll be best if libavformat give frames with RTP
header.
MPEG ES is needed, because, as i know, media players on Blackberry
phones do not play TS (i tried it).
Although, i appreciate if anyone point me some another format, easier to get
in this situation, that can hold h264 & aac, and plays well on
blackberry and other phones.
I've already succeed with other task to open the stream and remux to
FLV container.
Tried to open two output format contexts with "rtp" formats, also got
frames. Sent to client. No success.
I've also tried writing frames to "m4v" AVFormatContext, have got
frames, have cut them by NAL, added RTP header before each frame, and sent to client. Client displays 1st frame and hangs, or plays a second of video+audio (faster than needed) each 10 seconds or more.
In VLC player log i have this: http://pastebin.com/NQ3htvFi
I've scaled timestamps to make them start with 0 for simplicity.
I compared it with what VLC (or Wowza, sorry i dont remember) incremented audio TS by 1024, not 1920, so i did additional linear scaling to be similar to other streamers.
Packet dump of playback of bigbuckbunny_450.mp4 is here:
ftp://rtb.org.ua/tmp/output_my_bbb_450.log
BTW in both cases i've hardly copied SDP from Wowza or VLC.
What is the right way to get what i need?
I'm also interested if there's some library similar to
libavformat? Maybe even in embryo state.

Resources