webrtc - Webm (VP8 / Opus) file read and write back -
i trying develop webrtc simulator in c/c++. media handling, plan use libav. thinking of below steps realize media exchange between 2 webrtc simulator. have 2 webrtc simulators a , b.
- read media @ input webm file using av_read_frame api.
- i assume encoded media (audio / video) data, am correct here?
- send encoded media data simulator b on udp socket.
- simulator b receives media data in udp socket rtp packets.
- simulator b extracts audio/video data received rtp packet.
- i assume extracted media data @ simulator b encoded data (am correct here). not want decode it. want write file. later play file check if have done right.
to simplify problem lets take out udp socket part. question reduces read data webm input file, encoded media, prepare packet , write output file using av_interleaved_write_frame or other appropriate api. these things want using libav.
is there example code can refer.
or can please guide me develop it.
i trying test program. first step, aim read file , write output file. have below code, not working properly.
//#define _audio_write_enabled_ #include "libavutil/imgutils.h" #include "libavutil/samplefmt.h" #include "libavformat/avformat.h" static avpacket pkt; static avformatcontext *fmt_ctx = null; static avformatcontext *av_format_context = null; static avoutputformat *av_output_format = null; static avcodec *video_codec = null; static avstream *video_stream = null; static avcodec *audio_codec = null; static avstream *audio_stream = null; static const char *src_filename = null; static const char *dst_filename = null; int main (int argc, char **argv) { int ret = 0; int index = 0; if (argc != 3) { printf("usage: ./webm input_video_file output_video_file \n"); exit(0); } src_filename = argv[1]; dst_filename = argv[2]; printf("source file = %s , destination file = %s\n", src_filename, dst_filename); av_register_all(); /* open input file, , allocate format context */ if (avformat_open_input(&fmt_ctx, src_filename, null, null) < 0) { fprintf(stderr, "could not open source file %s\n", src_filename); exit(1); } /* retrieve stream information */ if (avformat_find_stream_info(fmt_ctx, null) < 0) { fprintf(stderr, "could not find stream information\n"); exit(2); } av_output_format = av_guess_format(null, dst_filename, null); if(!av_output_format) { fprintf(stderr, "could not guess output file format\n"); exit(3); } av_output_format->audio_codec = av_codec_id_vorbis; av_output_format->video_codec = av_codec_id_vp8; av_format_context = avformat_alloc_context(); if(!av_format_context) { fprintf(stderr, "could not allocation av format context\n"); exit(4); } av_format_context->oformat = av_output_format; strcpy(av_format_context->filename, dst_filename); video_codec = avcodec_find_encoder(av_output_format->video_codec); if (!video_codec) { fprintf(stderr, "codec not found\n"); exit(5); } video_stream = avformat_new_stream(av_format_context, video_codec); if (!video_stream) { fprintf(stderr, "could not alloc stream\n"); exit(6); } avcodec_get_context_defaults3(video_stream->codec, video_codec); video_stream->codec->codec_id = av_codec_id_vp8; video_stream->codec->codec_type = avmedia_type_video; video_stream->time_base = (avrational) {1, 30}; video_stream->codec->width = 640; video_stream->codec->height = 480; video_stream->codec->pix_fmt = pix_fmt_yuv420p; video_stream->codec->flags |= codec_flag_global_header; video_stream->codec->bit_rate = 400000; video_stream->codec->gop_size = 10; video_stream->codec->max_b_frames=1; #ifdef _audio_write_enabled_ audio_codec = avcodec_find_encoder(av_output_format->audio_codec); if (!audio_codec) { fprintf(stderr, "codec not found audio codec\n"); exit(5); } audio_stream = avformat_new_stream(av_format_context, audio_codec); if (!audio_stream) { fprintf(stderr, "could not alloc stream audio\n"); exit(6); } avcodec_get_context_defaults3(audio_stream->codec, audio_codec); audio_stream->codec->codec_id = av_codec_id_vorbis; audio_stream->codec->codec_type = avmedia_type_audio; audio_stream->time_base = (avrational) {1, 30}; audio_stream->codec->sample_rate = 8000; audio_stream->codec->flags |= codec_flag_global_header; #endif if(!(av_output_format->flags & avfmt_nofile)) { if (avio_open(&av_format_context->pb, dst_filename, avio_flag_write) < 0) { fprintf(stderr, "could not open '%s'\n", dst_filename); } } /* before avformat_write_header set stream */ avformat_write_header(av_format_context, null); /* initialize packet, set data null, let demuxer fill */ av_init_packet(&pkt); pkt.data = null; pkt.size = 0; pkt.stream_index = video_stream->index; ret = av_read_frame(fmt_ctx, &pkt); while (ret >= 0) { index++; //pkt.stream_index = video_avstream->index; if(pkt.stream_index == video_stream->index) { printf("video: read cycle %d, bytes read = %d, pkt stream index=%d\n", index, pkt.size, pkt.stream_index); av_write_frame(av_format_context, &pkt); } #ifdef _audio_write_enabled_ else if(pkt.stream_index == audio_stream->index) { printf("audio: read cycle %d, bytes read = %d, pkt stream index=%d\n", index, pkt.size, pkt.stream_index); av_write_frame(av_format_context, &pkt); } #endif av_free_packet(&pkt); ret = av_read_frame(fmt_ctx, &pkt); } av_write_trailer(av_format_context); /** exit procedure starts */ avformat_close_input(&fmt_ctx); avformat_free_context(av_format_context); return 0; }
when execute program, outputs "codec not found". sure whats going wrong, can please.
codec not found issue resolved separately building libvpx1.4 version. still struggling read source file, , writing destination file.
edit 1: after code modification, video stuff able write file, though more errors still present.
edit 2: modified code (2nd round), see video frames written properly. audio frames added code under macro _audio_write_enabled_ , if enable macro program crashing. can guide whats wrong in audio write part (code under macro _audio_write_enabled_).
i not answering question, hope final solution eventually. when tried run code, got error "time base not set
".
time base , other header specs part of codec. is, how have thing specified writing file (vstream
of avstream
):
#if libavcodec_ver_at_least(53, 21) avcodec_get_context_defaults3(rc->vstream->codec, avmedia_type_video); #else avcodec_get_context_defaults2(rc->vstream->codec, avmedia_type_video); #endif #if libavcodec_ver_at_least(54, 25) vstream->codec->codec_id = av_codec_id_vp8; #else vstream->codec->codec_id = codec_id_vp8; #endif vstream->codec->codec_type = avmedia_type_video; vstream->codec->time_base = (avrational) {1, 30}; vstream->codec->width = 640; vstream->codec->height = 480; vstream->codec->pix_fmt = pix_fmt_yuv420p;
edit: ran program in valgrind , segfaults on av_write_frame. looks time_base , other specs output not set properly. add specs before avformat_write_header()
, before late.
Comments
Post a Comment