jint Java_org_telegram_ui_Components_AnimatedFileDrawable_createDecoder(JNIEnv *env, jclass clazz, jstring src, jintArray data) { VideoInfo *info = new VideoInfo(); char const *srcString = env->GetStringUTFChars(src, 0); int len = strlen(srcString); info->src = new char[len + 1]; memcpy(info->src, srcString, len); info->src[len] = '\0'; if (srcString != 0) { env->ReleaseStringUTFChars(src, srcString); } int ret; if ((ret = avformat_open_input(&info->fmt_ctx, info->src, NULL, NULL)) < 0) { LOGE("can't open source file %s, %s", info->src, av_err2str(ret)); delete info; return 0; } if ((ret = avformat_find_stream_info(info->fmt_ctx, NULL)) < 0) { LOGE("can't find stream information %s, %s", info->src, av_err2str(ret)); delete info; return 0; } if (open_codec_context(&info->video_stream_idx, info->fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) { info->video_stream = info->fmt_ctx->streams[info->video_stream_idx]; info->video_dec_ctx = info->video_stream->codec; } if (info->video_stream <= 0) { LOGE("can't find video stream in the input, aborting %s", info->src); delete info; return 0; } info->frame = av_frame_alloc(); if (info->frame == nullptr) { LOGE("can't allocate frame %s", info->src); delete info; return 0; } av_init_packet(&info->pkt); info->pkt.data = NULL; info->pkt.size = 0; jint *dataArr = env->GetIntArrayElements(data, 0); if (dataArr != nullptr) { dataArr[0] = info->video_dec_ctx->width; dataArr[1] = info->video_dec_ctx->height; AVDictionaryEntry *rotate_tag = av_dict_get(info->video_stream->metadata, "rotate", NULL, 0); if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) { char *tail; dataArr[2] = (int) av_strtod(rotate_tag->value, &tail); if (*tail) { dataArr[2] = 0; } } else { dataArr[2] = 0; } env->ReleaseIntArrayElements(data, dataArr, 0); } //LOGD("successfully opened file %s", info->src); return (int) info; }
bool FFmpegInput::open (const std::string &name, ImageSpec &spec) { // Temporary workaround: refuse to open a file whose name does not // indicate that it's a movie file. This avoids the problem that ffmpeg // is willing to open tiff and other files better handled by other // plugins. The better long-term solution is to replace av_register_all // with our own function that registers only the formats that we want // this reader to handle. At some point, we will institute that superior // approach, but in the mean time, this is a quick solution that 90% // does the job. bool valid_extension = false; for (int i = 0; ffmpeg_input_extensions[i]; ++i) if (Strutil::ends_with (name, ffmpeg_input_extensions[i])) { valid_extension = true; break; } if (! valid_extension) { error ("\"%s\" could not open input", name); return false; } static boost::once_flag init_flag = BOOST_ONCE_INIT; boost::call_once (&av_register_all, init_flag); const char *file_name = name.c_str(); av_log_set_level (AV_LOG_FATAL); if (avformat_open_input (&m_format_context, file_name, NULL, NULL) != 0) // avformat_open_input allocs format_context { error ("\"%s\" could not open input", file_name); return false; } if (avformat_find_stream_info (m_format_context, NULL) < 0) { error ("\"%s\" could not find stream info", file_name); return false; } m_video_stream = -1; for (unsigned int i=0; i<m_format_context->nb_streams; i++) { if (m_format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { if (m_video_stream < 0) { m_video_stream=i; } m_video_indexes.push_back (i); // needed for later use break; } } if (m_video_stream == -1) { error ("\"%s\" could not find a valid videostream", file_name); return false; } m_codec_context = m_format_context->streams[m_video_stream]->codec; // codec context for videostream m_codec = avcodec_find_decoder (m_codec_context->codec_id); if (!m_codec) { error ("\"%s\" unsupported codec", file_name); return false; } if (avcodec_open2 (m_codec_context, m_codec, NULL) < 0) { error ("\"%s\" could not open codec", file_name); return false; } if (!strcmp (m_codec_context->codec->name, "mjpeg") || !strcmp (m_codec_context->codec->name, "dvvideo")) { m_offset_time = false; } m_codec_cap_delay = m_codec_context->codec->capabilities & CODEC_CAP_DELAY ; AVStream *stream = m_format_context->streams[m_video_stream]; if (stream->r_frame_rate.num != 0 && stream->r_frame_rate.den != 0) { m_frame_rate = stream->r_frame_rate; } m_frames = stream->nb_frames; m_start_time = stream->start_time; if (!m_frames) { seek (0); AVPacket pkt; av_init_packet (&pkt); av_read_frame (m_format_context, &pkt); int64_t first_pts = pkt.pts; int64_t max_pts = 0 ; av_free_packet (&pkt); //because seek(int) uses m_format_context seek (1 << 29); av_init_packet (&pkt); //Is this needed? while (stream && av_read_frame (m_format_context, &pkt) >= 0) { int64_t current_pts = static_cast<int64_t> (av_q2d(stream->time_base) * (pkt.pts - first_pts) * fps()); if (current_pts > max_pts) { max_pts = current_pts +1; } av_free_packet (&pkt); //Always free before format_context usage } m_frames = max_pts; } m_frame = av_frame_alloc(); m_rgb_frame = av_frame_alloc(); m_rgb_buffer.resize( avpicture_get_size (AV_PIX_FMT_RGB24, m_codec_context->width, m_codec_context->height), 0 ); AVPixelFormat pixFormat; switch (m_codec_context->pix_fmt) { // deprecation warning for YUV formats case AV_PIX_FMT_YUVJ420P: pixFormat = AV_PIX_FMT_YUV420P; break; case AV_PIX_FMT_YUVJ422P: pixFormat = AV_PIX_FMT_YUV422P; break; case AV_PIX_FMT_YUVJ444P: pixFormat = AV_PIX_FMT_YUV444P; break; case AV_PIX_FMT_YUVJ440P: pixFormat = AV_PIX_FMT_YUV440P; default: pixFormat = m_codec_context->pix_fmt; break; } m_sws_rgb_context = sws_getContext( m_codec_context->width, m_codec_context->height, pixFormat, m_codec_context->width, m_codec_context->height, AV_PIX_FMT_RGB24, SWS_AREA, NULL, NULL, NULL ); m_spec = ImageSpec (m_codec_context->width, m_codec_context->height, 3, TypeDesc::UINT8); AVDictionaryEntry *tag = NULL; while ((tag = av_dict_get (m_format_context->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { m_spec.attribute (tag->key, tag->value); } m_spec.attribute ("FramesPerSecond", m_frame_rate.num / static_cast<float> (m_frame_rate.den)); m_spec.attribute ("oiio:Movie", true); m_nsubimages = m_frames; spec = m_spec; return true; }
static int video_decode_example(const char *input_filename) { AVCodec *codec = NULL; AVCodecContext *ctx= NULL; AVCodecParameters *origin_par = NULL; AVFrame *fr = NULL; uint8_t *byte_buffer = NULL; AVPacket pkt; AVFormatContext *fmt_ctx = NULL; int number_of_written_bytes; int video_stream; int got_frame = 0; int byte_buffer_size; int i = 0; int result; int end_of_stream = 0; result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL); if (result < 0) { av_log(NULL, AV_LOG_ERROR, "Can't open file\n"); return result; } result = avformat_find_stream_info(fmt_ctx, NULL); if (result < 0) { av_log(NULL, AV_LOG_ERROR, "Can't get stream info\n"); return result; } video_stream = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if (video_stream < 0) { av_log(NULL, AV_LOG_ERROR, "Can't find video stream in input file\n"); return -1; } origin_par = fmt_ctx->streams[video_stream]->codecpar; codec = avcodec_find_decoder(origin_par->codec_id); if (!codec) { av_log(NULL, AV_LOG_ERROR, "Can't find decoder\n"); return -1; } ctx = avcodec_alloc_context3(codec); if (!ctx) { av_log(NULL, AV_LOG_ERROR, "Can't allocate decoder context\n"); return AVERROR(ENOMEM); } result = avcodec_parameters_to_context(ctx, origin_par); if (result) { av_log(NULL, AV_LOG_ERROR, "Can't copy decoder context\n"); return result; } result = avcodec_open2(ctx, codec, NULL); if (result < 0) { av_log(ctx, AV_LOG_ERROR, "Can't open decoder\n"); return result; } fr = av_frame_alloc(); if (!fr) { av_log(NULL, AV_LOG_ERROR, "Can't allocate frame\n"); return AVERROR(ENOMEM); } byte_buffer_size = av_image_get_buffer_size(ctx->pix_fmt, ctx->width, ctx->height, 16); byte_buffer = av_malloc(byte_buffer_size); if (!byte_buffer) { av_log(NULL, AV_LOG_ERROR, "Can't allocate buffer\n"); return AVERROR(ENOMEM); } printf("#tb %d: %d/%d\n", video_stream, fmt_ctx->streams[video_stream]->time_base.num, fmt_ctx->streams[video_stream]->time_base.den); i = 0; av_init_packet(&pkt); do { if (!end_of_stream) if (av_read_frame(fmt_ctx, &pkt) < 0) end_of_stream = 1; if (end_of_stream) { pkt.data = NULL; pkt.size = 0; } if (pkt.stream_index == video_stream || end_of_stream) { got_frame = 0; if (pkt.pts == AV_NOPTS_VALUE) pkt.pts = pkt.dts = i; result = avcodec_decode_video2(ctx, fr, &got_frame, &pkt); if (result < 0) { av_log(NULL, AV_LOG_ERROR, "Error decoding frame\n"); return result; } if (got_frame) { number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size, (const uint8_t* const *)fr->data, (const int*) fr->linesize, ctx->pix_fmt, ctx->width, ctx->height, 1); if (number_of_written_bytes < 0) { av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n"); return number_of_written_bytes; } printf("%d, %10"PRId64", %10"PRId64", %8"PRId64", %8d, 0x%08lx\n", video_stream, fr->pts, fr->pkt_dts, fr->pkt_duration, number_of_written_bytes, av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes)); } av_packet_unref(&pkt); av_init_packet(&pkt); } i++; } while (!end_of_stream || got_frame); av_packet_unref(&pkt); av_frame_free(&fr); avcodec_close(ctx); avformat_close_input(&fmt_ctx); avcodec_free_context(&ctx); av_freep(&byte_buffer); return 0; }
bool FFmpegEncoderOpen(struct FFmpegEncoder* encoder, const char* outfile) { AVCodec* acodec = avcodec_find_encoder_by_name(encoder->audioCodec); AVCodec* vcodec = avcodec_find_encoder_by_name(encoder->videoCodec); if ((encoder->audioCodec && !acodec) || !vcodec || !FFmpegEncoderVerifyContainer(encoder)) { return false; } encoder->currentAudioSample = 0; encoder->currentAudioFrame = 0; encoder->currentVideoFrame = 0; encoder->nextAudioPts = 0; AVOutputFormat* oformat = av_guess_format(encoder->containerFormat, 0, 0); #ifndef USE_LIBAV avformat_alloc_output_context2(&encoder->context, oformat, 0, outfile); #else encoder->context = avformat_alloc_context(); strncpy(encoder->context->filename, outfile, sizeof(encoder->context->filename) - 1); encoder->context->filename[sizeof(encoder->context->filename) - 1] = '\0'; encoder->context->oformat = oformat; #endif if (acodec) { #ifdef FFMPEG_USE_CODECPAR encoder->audioStream = avformat_new_stream(encoder->context, NULL); encoder->audio = avcodec_alloc_context3(acodec); #else encoder->audioStream = avformat_new_stream(encoder->context, acodec); encoder->audio = encoder->audioStream->codec; #endif encoder->audio->bit_rate = encoder->audioBitrate; encoder->audio->channels = 2; encoder->audio->channel_layout = AV_CH_LAYOUT_STEREO; encoder->audio->sample_rate = encoder->sampleRate; encoder->audio->sample_fmt = encoder->sampleFormat; AVDictionary* opts = 0; av_dict_set(&opts, "strict", "-2", 0); if (encoder->context->oformat->flags & AVFMT_GLOBALHEADER) { encoder->audio->flags |= CODEC_FLAG_GLOBAL_HEADER; } avcodec_open2(encoder->audio, acodec, &opts); av_dict_free(&opts); #if LIBAVCODEC_VERSION_MAJOR >= 55 encoder->audioFrame = av_frame_alloc(); #else encoder->audioFrame = avcodec_alloc_frame(); #endif if (!encoder->audio->frame_size) { encoder->audio->frame_size = 1; } encoder->audioFrame->nb_samples = encoder->audio->frame_size; encoder->audioFrame->format = encoder->audio->sample_fmt; encoder->audioFrame->pts = 0; encoder->resampleContext = avresample_alloc_context(); av_opt_set_int(encoder->resampleContext, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(encoder->resampleContext, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(encoder->resampleContext, "in_sample_rate", PREFERRED_SAMPLE_RATE, 0); av_opt_set_int(encoder->resampleContext, "out_sample_rate", encoder->sampleRate, 0); av_opt_set_int(encoder->resampleContext, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(encoder->resampleContext, "out_sample_fmt", encoder->sampleFormat, 0); avresample_open(encoder->resampleContext); encoder->audioBufferSize = (encoder->audioFrame->nb_samples * PREFERRED_SAMPLE_RATE / encoder->sampleRate) * 4; encoder->audioBuffer = av_malloc(encoder->audioBufferSize); encoder->postaudioBufferSize = av_samples_get_buffer_size(0, encoder->audio->channels, encoder->audio->frame_size, encoder->audio->sample_fmt, 0); encoder->postaudioBuffer = av_malloc(encoder->postaudioBufferSize); avcodec_fill_audio_frame(encoder->audioFrame, encoder->audio->channels, encoder->audio->sample_fmt, (const uint8_t*) encoder->postaudioBuffer, encoder->postaudioBufferSize, 0); if (encoder->audio->codec->id == AV_CODEC_ID_AAC && (strcasecmp(encoder->containerFormat, "mp4") || strcasecmp(encoder->containerFormat, "m4v") || strcasecmp(encoder->containerFormat, "mov"))) { // MP4 container doesn't support the raw ADTS AAC format that the encoder spits out #ifdef FFMPEG_USE_NEW_BSF av_bsf_alloc(av_bsf_get_by_name("aac_adtstoasc"), &encoder->absf); avcodec_parameters_from_context(encoder->absf->par_in, encoder->audio); av_bsf_init(encoder->absf); #else encoder->absf = av_bitstream_filter_init("aac_adtstoasc"); #endif } #ifdef FFMPEG_USE_CODECPAR avcodec_parameters_from_context(encoder->audioStream->codecpar, encoder->audio); #endif } #ifdef FFMPEG_USE_CODECPAR encoder->videoStream = avformat_new_stream(encoder->context, NULL); encoder->video = avcodec_alloc_context3(vcodec); #else encoder->videoStream = avformat_new_stream(encoder->context, vcodec); encoder->video = encoder->videoStream->codec; #endif encoder->video->bit_rate = encoder->videoBitrate; encoder->video->width = encoder->width; encoder->video->height = encoder->height; encoder->video->time_base = (AVRational) { VIDEO_TOTAL_LENGTH, GBA_ARM7TDMI_FREQUENCY }; encoder->video->pix_fmt = encoder->pixFormat; encoder->video->gop_size = 60; encoder->video->max_b_frames = 3; if (encoder->context->oformat->flags & AVFMT_GLOBALHEADER) { encoder->video->flags |= CODEC_FLAG_GLOBAL_HEADER; } if (strcmp(vcodec->name, "libx264") == 0) { // Try to adaptively figure out when you can use a slower encoder if (encoder->width * encoder->height > 1000000) { av_opt_set(encoder->video->priv_data, "preset", "superfast", 0); } else if (encoder->width * encoder->height > 500000) { av_opt_set(encoder->video->priv_data, "preset", "veryfast", 0); } else { av_opt_set(encoder->video->priv_data, "preset", "faster", 0); } av_opt_set(encoder->video->priv_data, "tune", "zerolatency", 0); } avcodec_open2(encoder->video, vcodec, 0); #if LIBAVCODEC_VERSION_MAJOR >= 55 encoder->videoFrame = av_frame_alloc(); #else encoder->videoFrame = avcodec_alloc_frame(); #endif encoder->videoFrame->format = encoder->video->pix_fmt; encoder->videoFrame->width = encoder->video->width; encoder->videoFrame->height = encoder->video->height; encoder->videoFrame->pts = 0; _ffmpegSetVideoDimensions(&encoder->d, encoder->iwidth, encoder->iheight); av_image_alloc(encoder->videoFrame->data, encoder->videoFrame->linesize, encoder->video->width, encoder->video->height, encoder->video->pix_fmt, 32); #ifdef FFMPEG_USE_CODECPAR avcodec_parameters_from_context(encoder->videoStream->codecpar, encoder->video); #endif avio_open(&encoder->context->pb, outfile, AVIO_FLAG_WRITE); return avformat_write_header(encoder->context, 0) >= 0; }
// -------------------------------------------------------------------------- //! @brief Initialize video. //! @return Result of initialization //! @retval 1 Success //! @retval 0 Failure // -------------------------------------------------------------------------- int ARDrone::initVideo(void) { // AR.Drone 2.0 if (version.major == ARDRONE_VERSION_2) { // Open the IP address and port char filename[256]; sprintf(filename, "tcp://%s:%d", ip, ARDRONE_VIDEO_PORT); if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) < 0) { CVDRONE_ERROR("avformat_open_input() was failed. (%s, %d)\n", __FILE__, __LINE__); return 0; } // Retrive and dump stream information avformat_find_stream_info(pFormatCtx, NULL); av_dump_format(pFormatCtx, 0, filename, 0); // Find the decoder for the video stream pCodecCtx = pFormatCtx->streams[0]->codec; AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if (pCodec == NULL) { CVDRONE_ERROR("avcodec_find_decoder() was failed. (%s, %d)\n", __FILE__, __LINE__); return 0; } // Open codec if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { CVDRONE_ERROR("avcodec_open2() was failed. (%s, %d)\n", __FILE__, __LINE__); return 0; } // Allocate video frames and a buffer #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) pFrame = av_frame_alloc(); pFrameBGR = av_frame_alloc(); #else pFrame = avcodec_alloc_frame(); pFrameBGR = avcodec_alloc_frame(); #endif bufferBGR = (uint8_t*)av_mallocz(avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height) * sizeof(uint8_t)); // Assign appropriate parts of buffer to image planes in pFrameBGR avpicture_fill((AVPicture*)pFrameBGR, bufferBGR, PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height); // Convert it to BGR pConvertCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_BGR24, SWS_SPLINE, NULL, NULL, NULL); } // AR.Drone 1.0 else { // Open the IP address and port if (!sockVideo.open(ip, ARDRONE_VIDEO_PORT)) { CVDRONE_ERROR("UDPSocket::open(port=%d) was failed. (%s, %d)\n", ARDRONE_VIDEO_PORT, __FILE__, __LINE__); return 0; } // Set codec pCodecCtx = avcodec_alloc_context3(NULL); pCodecCtx->width = 320; pCodecCtx->height = 240; // Allocate a buffer bufferBGR = (uint8_t*)av_mallocz(avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height)); } // Allocate an IplImage img = cvCreateImage(cvSize(pCodecCtx->width, (pCodecCtx->height == 368) ? 360 : pCodecCtx->height), IPL_DEPTH_8U, 3); if (!img) { CVDRONE_ERROR("cvCreateImage() was failed. (%s, %d)\n", __FILE__, __LINE__); return 0; } // Clear the image cvZero(img); // Create a mutex mutexVideo = new pthread_mutex_t; pthread_mutex_init(mutexVideo, NULL); // Create a thread threadVideo = new pthread_t; if (pthread_create(threadVideo, NULL, runVideo, this) != 0) { CVDRONE_ERROR("pthread_create() was failed. (%s, %d)\n", __FILE__, __LINE__); return 0; } return 1; }
static int filter(struct af_instance *af, struct mp_audio *data, int flags) { struct priv *p = af->priv; struct mp_audio *r = af->data; bool eof = data->samples == 0 && (flags & AF_FILTER_FLAG_EOF); AVFilterLink *l_in = p->in->outputs[0]; AVFrame *frame = av_frame_alloc(); frame->nb_samples = data->samples; frame->format = l_in->format; // Timebase is 1/sample_rate frame->pts = p->samples_in; frame->channel_layout = l_in->channel_layout; frame->sample_rate = l_in->sample_rate; #if LIBAVFILTER_VERSION_MICRO >= 100 // FFmpeg being a stupid POS frame->channels = l_in->channels; #endif frame->extended_data = frame->data; for (int n = 0; n < data->num_planes; n++) frame->data[n] = data->planes[n]; frame->linesize[0] = frame->nb_samples * data->sstride; if (av_buffersrc_add_frame(p->in, eof ? NULL : frame) < 0) { av_frame_free(&frame); return -1; } av_frame_free(&frame); int64_t out_pts = AV_NOPTS_VALUE; r->samples = 0; for (;;) { frame = av_frame_alloc(); if (av_buffersink_get_frame(p->out, frame) < 0) { // Not an error situation - no more output buffers in queue. av_frame_free(&frame); break; } mp_audio_realloc_min(r, r->samples + frame->nb_samples); for (int n = 0; n < r->num_planes; n++) { memcpy((char *)r->planes[n] + r->samples * r->sstride, frame->extended_data[n], frame->nb_samples * r->sstride); } r->samples += frame->nb_samples; if (out_pts == AV_NOPTS_VALUE) out_pts = frame->pts; av_frame_free(&frame); } p->samples_in += data->samples; if (out_pts != AV_NOPTS_VALUE) { double in_time = p->samples_in / (double)data->rate; double out_time = out_pts * av_q2d(p->timebase_out); // Need pts past the last output sample. out_time += r->samples / (double)r->rate; af->delay = in_time - out_time; } *data = *r; return 0; }
static bool ffemu_init_video(ffemu_t *handle) { struct ff_config_param *params = &handle->config; struct ff_video_info *video = &handle->video; struct ffemu_params *param = &handle->params; AVCodec *codec = NULL; if (*params->vcodec) codec = avcodec_find_encoder_by_name(params->vcodec); else { // By default, lossless video. av_dict_set(¶ms->video_opts, "qp", "0", 0); codec = avcodec_find_encoder_by_name("libx264rgb"); } if (!codec) { RARCH_ERR("[FFmpeg]: Cannot find vcodec %s.\n", *params->vcodec ? params->vcodec : "libx264rgb"); return false; } video->encoder = codec; // Don't use swscaler unless format is not something "in-house" scaler supports. // libswscale doesn't scale RGB -> RGB correctly (goes via YUV first), and it's non-trivial to fix // upstream as it's heavily geared towards YUV. // If we're dealing with strange formats or YUV, just use libswscale. if (params->out_pix_fmt != PIX_FMT_NONE) { video->pix_fmt = params->out_pix_fmt; if (video->pix_fmt != PIX_FMT_BGR24 && video->pix_fmt != PIX_FMT_RGB32) video->use_sws = true; switch (video->pix_fmt) { case PIX_FMT_BGR24: video->scaler.out_fmt = SCALER_FMT_BGR24; break; case PIX_FMT_RGB32: video->scaler.out_fmt = SCALER_FMT_ARGB8888; break; default: break; } } else // Use BGR24 as default out format. { video->pix_fmt = PIX_FMT_BGR24; video->scaler.out_fmt = SCALER_FMT_BGR24; } switch (param->pix_fmt) { case FFEMU_PIX_RGB565: video->scaler.in_fmt = SCALER_FMT_RGB565; video->in_pix_fmt = PIX_FMT_RGB565; video->pix_size = 2; break; case FFEMU_PIX_BGR24: video->scaler.in_fmt = SCALER_FMT_BGR24; video->in_pix_fmt = PIX_FMT_BGR24; video->pix_size = 3; break; case FFEMU_PIX_ARGB8888: video->scaler.in_fmt = SCALER_FMT_ARGB8888; video->in_pix_fmt = PIX_FMT_RGB32; video->pix_size = 4; break; default: return false; } video->codec = avcodec_alloc_context3(codec); // Useful to set scale_factor to 2 for chroma subsampled formats to maintain full chroma resolution. // (Or just use 4:4:4 or RGB ...) param->out_width *= params->scale_factor; param->out_height *= params->scale_factor; video->codec->codec_type = AVMEDIA_TYPE_VIDEO; video->codec->width = param->out_width; video->codec->height = param->out_height; video->codec->time_base = av_d2q((double)params->frame_drop_ratio / param->fps, 1000000); // Arbitrary big number. video->codec->sample_aspect_ratio = av_d2q(param->aspect_ratio * param->out_height / param->out_width, 255); video->codec->pix_fmt = video->pix_fmt; video->codec->thread_count = params->threads; if (params->video_qscale) { video->codec->flags |= CODEC_FLAG_QSCALE; video->codec->global_quality = params->video_global_quality; } else if (params->video_bit_rate) video->codec->bit_rate = params->video_bit_rate; if (handle->muxer.ctx->oformat->flags & AVFMT_GLOBALHEADER) video->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; if (avcodec_open2(video->codec, codec, params->video_opts ? ¶ms->video_opts : NULL) != 0) return false; // Allocate a big buffer :p ffmpeg API doesn't seem to give us some clues how big this buffer should be. video->outbuf_size = 1 << 23; video->outbuf = (uint8_t*)av_malloc(video->outbuf_size); video->frame_drop_ratio = params->frame_drop_ratio; size_t size = avpicture_get_size(video->pix_fmt, param->out_width, param->out_height); video->conv_frame_buf = (uint8_t*)av_malloc(size); video->conv_frame = av_frame_alloc(); avpicture_fill((AVPicture*)video->conv_frame, video->conv_frame_buf, video->pix_fmt, param->out_width, param->out_height); return true; }
/* * Audio encoding example */ static void audio_encode_example(const char *filename) { AVCodec *codec; AVCodecContext *c= NULL; AVFrame *frame; AVPacket pkt; int i, j, k, ret, got_output; int buffer_size; FILE *f; uint16_t *samples; float t, tincr; printf("Audio encoding\n"); /* find the MP2 encoder */ codec = avcodec_find_encoder(AV_CODEC_ID_MP2); if (!codec) { fprintf(stderr, "codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); /* put sample parameters */ c->bit_rate = 64000; /* check that the encoder supports s16 pcm input */ c->sample_fmt = AV_SAMPLE_FMT_S16; if (!check_sample_fmt(codec, c->sample_fmt)) { fprintf(stderr, "encoder does not support %s", av_get_sample_fmt_name(c->sample_fmt)); exit(1); } /* select other audio parameters supported by the encoder */ c->sample_rate = select_sample_rate(codec); c->channel_layout = select_channel_layout(codec); c->channels = av_get_channel_layout_nb_channels(c->channel_layout); /* open it */ if (avcodec_open2(c, codec, NULL) < 0) { fprintf(stderr, "could not open codec\n"); exit(1); } f = fopen(filename, "wb"); if (!f) { fprintf(stderr, "could not open %s\n", filename); exit(1); } /* frame containing input raw audio */ frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "could not allocate audio frame\n"); exit(1); } frame->nb_samples = c->frame_size; frame->format = c->sample_fmt; frame->channel_layout = c->channel_layout; /* the codec gives us the frame size, in samples, * we calculate the size of the samples buffer in bytes */ buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size, c->sample_fmt, 0); samples = av_malloc(buffer_size); if (!samples) { fprintf(stderr, "could not allocate %d bytes for samples buffer\n", buffer_size); exit(1); } /* setup the data pointers in the AVFrame */ ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, (const uint8_t*)samples, buffer_size, 0); if (ret < 0) { fprintf(stderr, "could not setup audio frame\n"); exit(1); } /* encode a single tone sound */ t = 0; tincr = 2 * M_PI * 440.0 / c->sample_rate; for(i=0;i<200;i++) { av_init_packet(&pkt); pkt.data = NULL; // packet data will be allocated by the encoder pkt.size = 0; for (j = 0; j < c->frame_size; j++) { samples[2*j] = (int)(sin(t) * 10000); for (k = 1; k < c->channels; k++) samples[2*j + k] = samples[2*j]; t += tincr; } /* encode the samples */ ret = avcodec_encode_audio2(c, &pkt, frame, &got_output); if (ret < 0) { fprintf(stderr, "error encoding audio frame\n"); exit(1); } if (got_output) { fwrite(pkt.data, 1, pkt.size, f); av_free_packet(&pkt); } } fclose(f); av_freep(&samples); av_frame_free(&frame); avcodec_close(c); av_free(c); }
/* * Audio decoding. */ static void audio_decode_example(const char *outfilename, const char *filename) { AVCodec *codec; AVCodecContext *c= NULL; int len; FILE *f, *outfile; uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; AVPacket avpkt; AVFrame *decoded_frame = NULL; av_init_packet(&avpkt); printf("Audio decoding\n"); /* find the mpeg audio decoder */ codec = avcodec_find_decoder(AV_CODEC_ID_MP2); if (!codec) { fprintf(stderr, "codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); /* open it */ if (avcodec_open2(c, codec, NULL) < 0) { fprintf(stderr, "could not open codec\n"); exit(1); } f = fopen(filename, "rb"); if (!f) { fprintf(stderr, "could not open %s\n", filename); exit(1); } outfile = fopen(outfilename, "wb"); if (!outfile) { av_free(c); exit(1); } /* decode until eof */ avpkt.data = inbuf; avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); while (avpkt.size > 0) { int got_frame = 0; if (!decoded_frame) { if (!(decoded_frame = av_frame_alloc())) { fprintf(stderr, "out of memory\n"); exit(1); } } len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt); if (len < 0) { fprintf(stderr, "Error while decoding\n"); exit(1); } if (got_frame) { /* if a frame has been decoded, output it */ int data_size = av_samples_get_buffer_size(NULL, c->channels, decoded_frame->nb_samples, c->sample_fmt, 1); fwrite(decoded_frame->data[0], 1, data_size, outfile); } avpkt.size -= len; avpkt.data += len; if (avpkt.size < AUDIO_REFILL_THRESH) { /* Refill the input buffer, to avoid trying to decode * incomplete frames. Instead of this, one could also use * a parser, or use a proper container format through * libavformat. */ memmove(inbuf, avpkt.data, avpkt.size); avpkt.data = inbuf; len = fread(avpkt.data + avpkt.size, 1, AUDIO_INBUF_SIZE - avpkt.size, f); if (len > 0) avpkt.size += len; } } fclose(outfile); fclose(f); avcodec_close(c); av_free(c); av_frame_free(&decoded_frame); }
extern "C" int UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API init(char* name, int textureId) { // Register all formats and codecs if(name == NULL) return -1; av_register_all(); avformat_network_init(); uint8_t *buffers[FRAME_SIZE]; int buffer_size; buffer_size = avpicture_get_size(AV_PIX_FMT_RGB24, VIEW_WIDTH, VIEW_HEIGHT); for(int i=0;i<FRAME_SIZE;i++) { buffers[i] = (uint8_t *) av_malloc(buffer_size*sizeof(uint8_t)); pFrameRGB[i]=av_frame_alloc(); avpicture_fill((AVPicture *) pFrameRGB[i], buffers[i], AV_PIX_FMT_RGB24, VIEW_WIDTH, VIEW_HEIGHT); } VideoState *is; is = (VideoState*)av_mallocz(sizeof(VideoState)); gs = is; strcpy(is->filename, name); is->textureId = textureId; for(int i=0;i<FRAME_SIZE;i++) { is->frames[i]=av_frame_alloc(); pFrameRGB_status[i]=false; } is->frames[FRAME_SIZE]=av_frame_alloc(); is->mutex=PTHREAD_MUTEX_INITIALIZER; is->cond=PTHREAD_COND_INITIALIZER; pthread_create(&is->parse_tid, NULL, decode_thread, is); if(!is->parse_tid) { av_free(is); return -1; } int ret = 0; // OpenGL ES init. glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_SRC_COLOR); // End init. fprintf(stdout, "[FFmpeg-main thread] wait for event\n"); for(;;) { pthread_mutex_lock(&event_mutex); pthread_cond_wait(&event_cond, &event_mutex); switch(event_type) { case FF_QUIT_EVENT: ret = pthread_join(is->parse_tid, NULL); if(ret) fprintf(stdout, "decode_thread exit with error.\n"); else fprintf(stdout, "decode_thread exit with no error.\n"); ret = pthread_join(is->video_tid, NULL); if(ret) fprintf(stdout, "video_thread exit error.\n"); else fprintf(stdout, "video_thread exit with no error.\n"); ret = pthread_join(is->trans_tid, NULL); if(ret) fprintf(stdout, "transcode thread exit error.\n"); else fprintf(stdout, "transcode_thread exit with no error.\n"); av_frame_free(&pFrameRGB[0]); av_frame_free(&pFrameRGB[1]); fprintf(stdout, "[FFmpeg-main thread] thread terminated\n"); return 0; break; default: break; } pthread_mutex_unlock(&event_mutex); } return 0; }
int main() { // init accessory Accessory acc; if (!acc.init(VID, PID)) { fprintf(stderr, "Can't init accessory\n"); return 1; } printf("AOA init succeed\n"); AVCodecContext *pCodecCtx = NULL; AVCodec *pCodec = NULL; AVFrame *pFrame = NULL; // init ffmpeg codec avcodec_register_all(); pCodec=avcodec_find_decoder(CODEC_ID_H264); if(pCodec==NULL) { fprintf(stderr, "Unsupported codec!\n"); return 1; } pCodecCtx = avcodec_alloc_context3(pCodec); pCodecCtx->width = WIDTH; pCodecCtx->height = HEIGHT; pCodecCtx->pix_fmt = PIX_FMT_YUV420P; if(avcodec_open2(pCodecCtx, pCodec, NULL)<0) { fprintf(stderr, "codec open failed\n"); return 1; } pFrame=av_frame_alloc(); // init SDL if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); exit(1); } SDL_Surface *screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0); if(!screen) { fprintf(stderr, "SDL: could not set video mode - exiting\n"); exit(1); } SDL_Overlay *bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height, SDL_YV12_OVERLAY, screen); // init swscaler struct SwsContext *sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL); SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = pCodecCtx->width; rect.h = pCodecCtx->height; AVPacket packet; int gotFrame; unsigned char buf[2]; int r; while(1) { r = acc.readUsb(buf, 2); if (r < 0) { fprintf(stderr, "EOF\n"); break; } int length = (((int)buf[0]) << 8) | buf[1]; //printf("length = %d\n", length); char *packet_buf = (char *)av_malloc(length); r = acc.readUsb((unsigned char *)packet_buf, length); memset(&packet, 0, sizeof(packet)); av_packet_from_data(&packet, (uint8_t *)packet_buf, length); avcodec_decode_video2(pCodecCtx, pFrame, &gotFrame, &packet); //av_free(packet_buf); if(gotFrame) { SDL_LockYUVOverlay(bmp); AVPicture pict; pict.data[0] = bmp->pixels[0]; pict.data[1] = bmp->pixels[2]; pict.data[2] = bmp->pixels[1]; pict.linesize[0] = bmp->pitches[0]; pict.linesize[1] = bmp->pitches[2]; pict.linesize[2] = bmp->pitches[1]; // Convert the image into YUV format that SDL uses sws_scale(sws_ctx, (uint8_t const *const *) pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pict.data, pict.linesize); SDL_UnlockYUVOverlay(bmp); SDL_DisplayYUVOverlay(bmp, &rect); } av_free_packet(&packet); } return 0; }
bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) { m_hints = hints; m_options = options; AVCodec* pCodec; m_iOrientation = hints.orientation; for(std::vector<ERenderFormat>::iterator it = options.m_formats.begin(); it != options.m_formats.end(); ++it) { m_formats.push_back((AVPixelFormat)CDVDCodecUtils::PixfmtFromEFormat(*it)); if(*it == RENDER_FMT_YUV420P) m_formats.push_back(AV_PIX_FMT_YUVJ420P); } m_formats.push_back(AV_PIX_FMT_NONE); /* always add none to get a terminated list in ffmpeg world */ pCodec = avcodec_find_decoder(hints.codec); if(pCodec == NULL) { CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to find codec %d", hints.codec); return false; } CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::Open() Using codec: %s",pCodec->long_name ? pCodec->long_name : pCodec->name); m_pCodecContext = avcodec_alloc_context3(pCodec); m_pCodecContext->opaque = (void*)this; m_pCodecContext->debug_mv = 0; m_pCodecContext->debug = 0; m_pCodecContext->workaround_bugs = FF_BUG_AUTODETECT; m_pCodecContext->get_format = GetFormat; m_pCodecContext->codec_tag = hints.codec_tag; // setup threading model if (!hints.software) { bool tryhw = false; #ifdef HAVE_LIBVDPAU if(CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVDPAU)) tryhw = true; #endif #ifdef HAVE_LIBVA if(CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVAAPI)) tryhw = true; #endif #ifdef HAS_DX if(CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDXVA2)) tryhw = true; #endif #ifdef TARGET_DARWIN_OSX if(CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVDA)) tryhw = true; #endif if (tryhw && m_decoderState == STATE_NONE) { m_decoderState = STATE_HW_SINGLE; } else { int num_threads = std::min(8 /*MAX_THREADS*/, g_cpuInfo.getCPUCount()); if( num_threads > 1) m_pCodecContext->thread_count = num_threads; m_pCodecContext->thread_safe_callbacks = 1; m_decoderState = STATE_SW_MULTI; CLog::Log(LOGDEBUG, "CDVDVideoCodecFFmpeg - open frame threaded with %d threads", num_threads); } } else m_decoderState = STATE_SW_SINGLE; #if defined(TARGET_DARWIN_IOS) // ffmpeg with enabled neon will crash and burn if this is enabled m_pCodecContext->flags &= CODEC_FLAG_EMU_EDGE; #else if (pCodec->id != AV_CODEC_ID_H264 && pCodec->capabilities & CODEC_CAP_DR1 && pCodec->id != AV_CODEC_ID_VP8 ) m_pCodecContext->flags |= CODEC_FLAG_EMU_EDGE; #endif // if we don't do this, then some codecs seem to fail. m_pCodecContext->coded_height = hints.height; m_pCodecContext->coded_width = hints.width; m_pCodecContext->bits_per_coded_sample = hints.bitsperpixel; if( hints.extradata && hints.extrasize > 0 ) { m_pCodecContext->extradata_size = hints.extrasize; m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize); } // advanced setting override for skip loop filter (see avcodec.h for valid options) // TODO: allow per video setting? if (g_advancedSettings.m_iSkipLoopFilter != 0) { m_pCodecContext->skip_loop_filter = (AVDiscard)g_advancedSettings.m_iSkipLoopFilter; } // set any special options for(std::vector<CDVDCodecOption>::iterator it = options.m_keys.begin(); it != options.m_keys.end(); ++it) { if (it->m_name == "surfaces") m_uSurfacesCount = atoi(it->m_value.c_str()); else av_opt_set(m_pCodecContext, it->m_name.c_str(), it->m_value.c_str(), 0); } if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) { CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to open codec"); return false; } m_pFrame = av_frame_alloc(); if (!m_pFrame) return false; m_pFilterFrame = av_frame_alloc(); if (!m_pFilterFrame) return false; UpdateName(); return true; }
static void video_decode_example(const char *outfilename, const char *filename) { AVCodec *codec; AVCodecContext *c= NULL; int frame_count; FILE *f; AVFrame *frame; uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; AVPacket avpkt; av_init_packet(&avpkt); /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); printf("Decode video file %s to %s\n", filename, outfilename); /* find the mpeg1 video decoder */ codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO); if (!codec) { fprintf(stderr, "Codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate video codec context\n"); exit(1); } if(codec->capabilities&CODEC_CAP_TRUNCATED) c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */ /* For some codecs, such as msmpeg4 and mpeg4, width and height MUST be initialized there because this information is not available in the bitstream. */ /* open it */ if (avcodec_open2(c, codec, NULL) < 0) { fprintf(stderr, "Could not open codec\n"); exit(1); } f = fopen(filename, "rb"); if (!f) { fprintf(stderr, "Could not open %s\n", filename); exit(1); } frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "Could not allocate video frame\n"); exit(1); } frame_count = 0; for(;;) { avpkt.size = fread(inbuf, 1, INBUF_SIZE, f); if (avpkt.size == 0) break; /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio) and this is the only method to use them because you cannot know the compressed data size before analysing it. BUT some other codecs (msmpeg4, mpeg4) are inherently frame based, so you must call them with all the data for one frame exactly. You must also initialize 'width' and 'height' before initializing them. */ /* NOTE2: some codecs allow the raw parameters (frame size, sample rate) to be changed at any frame. We handle this, so you should also take care of it */ /* here, we use a stream based decoder (mpeg1video), so we feed decoder and see if it could decode a frame */ avpkt.data = inbuf; while (avpkt.size > 0) if (decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 0) < 0) exit(1); } /* some codecs, such as MPEG, transmit the I and P frame with a latency of one frame. You must do the following to have a chance to get the last frame of the video */ avpkt.data = NULL; avpkt.size = 0; decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1); fclose(f); avcodec_close(c); av_free(c); av_frame_free(&frame); printf("\n"); }
int main(int argc, const char *argv[]) { int ret = 0, got_frame, got_output; int video_stream_idx = -1; int video_dst_bufsize; const char *src_filename; const char *dst_filename; FILE *dst_file = NULL; AVCodec *codec_enc = NULL; AVFormatContext *fmt_ctx = NULL; AVStream *video_stream = NULL; AVCodecContext *video_dec_ctx = NULL; AVCodecContext *video_enc_ctx = NULL; AVFrame *frame = NULL; AVPacket pkt_dec, pkt_enc; uint8_t *video_dst_data[4] = {NULL}; int video_dst_linesize[4]; if (argc != 3) { printf("Usage: %s <in_file> <out_file>\n", argv[0]); exit(1); } av_register_all(); av_log_set_level(AV_LOG_DEBUG); src_filename = argv[1]; dst_filename = argv[2]; codec_enc = avcodec_find_encoder(AV_CODEC_ID_JPEG2000); if (!codec_enc) { fprintf(stderr, "Codec not found\n"); exit(1); } video_enc_ctx = avcodec_alloc_context3(codec_enc); if (!video_enc_ctx) { fprintf(stderr, "Could not allocate video codec context\n"); exit(1); } // j2kenc_init(video_enc_ctx); /* open input file, and 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(1); } if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO, src_filename) >= 0) { video_stream = fmt_ctx->streams[video_stream_idx]; video_dec_ctx = video_stream->codec; video_enc_ctx->width = video_dec_ctx->width; video_enc_ctx->height = video_dec_ctx->height; video_enc_ctx->pix_fmt = video_dec_ctx->pix_fmt; // make ffmpeg not complain about j2k being experiemntal video_enc_ctx->strict_std_compliance = -2; // printf("About to open encoder\n"); if (avcodec_open2(video_enc_ctx, codec_enc, NULL) < 0) { fprintf(stderr, "Could not open codec\n"); exit(1); } dst_file = fopen(dst_filename, "wb"); if (!dst_file) { fprintf(stderr, "Could not open destination file %s\n", dst_filename); ret = 1; goto end; } /* allocate image where the decoded image will be put */ ret = av_image_alloc(video_dst_data, video_dst_linesize, video_dec_ctx->width, video_dec_ctx->height, video_dec_ctx->pix_fmt, 1); if (ret < 0) { fprintf(stderr, "Could not allocate raw video buffer\n"); goto end; } video_dst_bufsize = ret; } /* dump input information to stderr */ av_dump_format(fmt_ctx, 0, src_filename, 0); frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "Could not allocate frame\n"); ret = AVERROR(ENOMEM); goto end; } /* initialize packet, set data to NULL, let the demuxer fill it */ av_init_packet(&pkt_dec); pkt_dec.data = NULL; pkt_dec.size = 0; if (video_stream) printf("Demuxing video from file '%s' into '%s'\n", src_filename, dst_filename); /* read frames from the file */ while (av_read_frame(fmt_ctx, &pkt_dec) >= 0) { // AVPacket orig_pkt = pkt; do { ret = decode_packet(&got_frame, 0, &pkt_dec, video_dec_ctx, frame); if (ret < 0) break; pkt_dec.data += ret; pkt_dec.size -= ret; } while (pkt_dec.size > 0); // av_free_packet(&orig_pkt); } /* flush cached frames */ pkt_dec.data = NULL; pkt_dec.size = 0; do { decode_packet(&got_frame, 1, &pkt_dec, video_dec_ctx, frame); if (got_frame) { // DO SOME ENCODING HERE av_init_packet(&pkt_enc); pkt_enc.data = NULL; pkt_enc.size = 0; ret = avcodec_encode_video2(video_enc_ctx, &pkt_enc, frame, &got_output); if (ret < 0) { fprintf(stderr, "Error encoding frame\n"); goto end; } if (got_output) { printf("Write frame (size=%5d)\n", pkt_enc.size); fwrite(pkt_enc.data, 1, pkt_enc.size, dst_file); } } } while (got_frame); printf("Demuxing succeeded.\n"); end: av_free_packet(&pkt_enc); av_free_packet(&pkt_dec); if (video_dec_ctx) avcodec_close(video_dec_ctx); if (video_enc_ctx) avcodec_close(video_enc_ctx); // if (codec_enc) // av_free(codec_enc); avformat_close_input(&fmt_ctx); if (dst_file) fclose(dst_file); else av_frame_free(&frame); av_free(video_dst_data[0]); return ret < 0; }
static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, AVFrame *frame, int flags) { BufferSourceContext *s = ctx->priv; AVFrame *copy; int refcounted, ret; s->nb_failed_requests = 0; if (!frame) { s->eof = 1; return 0; } else if (s->eof) return AVERROR(EINVAL); refcounted = !!frame->buf[0]; if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) { switch (ctx->outputs[0]->type) { case AVMEDIA_TYPE_VIDEO: CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height, frame->format); break; case AVMEDIA_TYPE_AUDIO: /* For layouts unknown on input but known on link after negotiation. */ if (!frame->channel_layout) frame->channel_layout = s->channel_layout; CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout, av_frame_get_channels(frame), frame->format); break; default: return AVERROR(EINVAL); } } if (!av_fifo_space(s->fifo) && (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) + sizeof(copy))) < 0) return ret; if (!(copy = av_frame_alloc())) return AVERROR(ENOMEM); if (refcounted) { av_frame_move_ref(copy, frame); } else { ret = av_frame_ref(copy, frame); if (ret < 0) { av_frame_free(©); return ret; } } if ((ret = av_fifo_generic_write(s->fifo, ©, sizeof(copy), NULL)) < 0) { if (refcounted) av_frame_move_ref(frame, copy); av_frame_free(©); return ret; } if ((flags & AV_BUFFERSRC_FLAG_PUSH)) if ((ret = ctx->output_pads[0].request_frame(ctx->outputs[0])) < 0) return ret; return 0; }
/* * Video encoding example */ static void video_encode_example(const char *filename) { AVCodec *codec; AVCodecContext *c= NULL; int i, ret, x, y, got_output; FILE *f; AVFrame *picture; AVPacket pkt; uint8_t endcode[] = { 0, 0, 1, 0xb7 }; printf("Video encoding\n"); /* find the mpeg1 video encoder */ codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO); if (!codec) { fprintf(stderr, "codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); picture = av_frame_alloc(); /* put sample parameters */ c->bit_rate = 400000; /* resolution must be a multiple of two */ c->width = 352; c->height = 288; /* frames per second */ c->time_base= (AVRational){1,25}; c->gop_size = 10; /* emit one intra frame every ten frames */ c->max_b_frames=1; c->pix_fmt = AV_PIX_FMT_YUV420P; /* open it */ if (avcodec_open2(c, codec, NULL) < 0) { fprintf(stderr, "could not open codec\n"); exit(1); } f = fopen(filename, "wb"); if (!f) { fprintf(stderr, "could not open %s\n", filename); exit(1); } ret = av_image_alloc(picture->data, picture->linesize, c->width, c->height, c->pix_fmt, 32); if (ret < 0) { fprintf(stderr, "could not alloc raw picture buffer\n"); exit(1); } picture->format = c->pix_fmt; picture->width = c->width; picture->height = c->height; /* encode 1 second of video */ for(i=0;i<25;i++) { av_init_packet(&pkt); pkt.data = NULL; // packet data will be allocated by the encoder pkt.size = 0; fflush(stdout); /* prepare a dummy image */ /* Y */ for(y=0;y<c->height;y++) { for(x=0;x<c->width;x++) { picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; } } /* Cb and Cr */ for(y=0;y<c->height/2;y++) { for(x=0;x<c->width/2;x++) { picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; } } picture->pts = i; /* encode the image */ ret = avcodec_encode_video2(c, &pkt, picture, &got_output); if (ret < 0) { fprintf(stderr, "error encoding frame\n"); exit(1); } if (got_output) { printf("encoding frame %3d (size=%5d)\n", i, pkt.size); fwrite(pkt.data, 1, pkt.size, f); av_free_packet(&pkt); } } /* get the delayed frames */ for (got_output = 1; got_output; i++) { fflush(stdout); ret = avcodec_encode_video2(c, &pkt, NULL, &got_output); if (ret < 0) { fprintf(stderr, "error encoding frame\n"); exit(1); } if (got_output) { printf("encoding frame %3d (size=%5d)\n", i, pkt.size); fwrite(pkt.data, 1, pkt.size, f); av_free_packet(&pkt); } } /* add sequence end code to have a real mpeg file */ fwrite(endcode, 1, sizeof(endcode), f); fclose(f); avcodec_close(c); av_free(c); av_freep(&picture->data[0]); av_frame_free(&picture); printf("\n"); }
static int func_run_sync(IJKFF_Pipenode *node) { JNIEnv *env = NULL; IJKFF_Pipenode_Opaque *opaque = node->opaque; FFPlayer *ffp = opaque->ffp; VideoState *is = ffp->is; Decoder *d = &is->viddec; PacketQueue *q = d->queue; int ret = 0; int dequeue_count = 0; AVFrame *frame = NULL; int got_frame = 0; AVRational tb = is->video_st->time_base; AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL); double duration; double pts; if (!opaque->acodec) { return ffp_video_thread(ffp); } if (JNI_OK != SDL_JNI_SetupThreadEnv(&env)) { ALOGE("%s: SetupThreadEnv failed\n", __func__); return -1; } frame = av_frame_alloc(); if (!frame) goto fail; if (opaque->frame_rotate_degrees == 90 || opaque->frame_rotate_degrees == 270) { opaque->frame_width = opaque->avctx->height; opaque->frame_height = opaque->avctx->width; } else { opaque->frame_width = opaque->avctx->width; opaque->frame_height = opaque->avctx->height; } opaque->enqueue_thread = SDL_CreateThreadEx(&opaque->_enqueue_thread, enqueue_thread_func, node, "amediacodec_input_thread"); if (!opaque->enqueue_thread) { ALOGE("%s: SDL_CreateThreadEx failed\n", __func__); ret = -1; goto fail; } while (!q->abort_request) { int64_t timeUs = opaque->acodec_first_dequeue_output_request ? 0 : AMC_OUTPUT_TIMEOUT_US; got_frame = 0; ret = drain_output_buffer(env, node, timeUs, &dequeue_count, frame, &got_frame); if (opaque->acodec_first_dequeue_output_request) { SDL_LockMutex(opaque->acodec_first_dequeue_output_mutex); opaque->acodec_first_dequeue_output_request = false; SDL_CondSignal(opaque->acodec_first_dequeue_output_cond); SDL_UnlockMutex(opaque->acodec_first_dequeue_output_mutex); } if (ret != 0) { ret = -1; if (got_frame && frame->opaque) SDL_VoutAndroid_releaseBufferProxyP(opaque->weak_vout, (SDL_AMediaCodecBufferProxy **)&frame->opaque, false); goto fail; } if (got_frame) { duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0); pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb); ret = ffp_queue_picture(ffp, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial); if (ret) { if (frame->opaque) SDL_VoutAndroid_releaseBufferProxyP(opaque->weak_vout, (SDL_AMediaCodecBufferProxy **)&frame->opaque, false); } av_frame_unref(frame); } } fail: av_frame_free(&frame); SDL_AMediaCodecFake_abort(opaque->acodec); if (opaque->n_buf_out) { free(opaque->amc_buf_out); opaque->n_buf_out = 0; opaque->amc_buf_out = NULL; opaque->off_buf_out = 0; opaque->last_queued_pts = AV_NOPTS_VALUE; } if (opaque->acodec) { SDL_VoutAndroid_invalidateAllBuffers(opaque->weak_vout); SDL_LockMutex(opaque->acodec_mutex); SDL_AMediaCodec_stop(opaque->acodec); SDL_UnlockMutex(opaque->acodec_mutex); } SDL_WaitThread(opaque->enqueue_thread, NULL); SDL_AMediaCodec_decreaseReferenceP(&opaque->acodec); ALOGI("MediaCodec: %s: exit: %d", __func__, ret); return ret; #if 0 fallback_to_ffplay: ALOGW("fallback to ffplay decoder\n"); return ffp_video_thread(opaque->ffp); #endif }
static void video_decode_example(const char *outfilename, const char *filename) { AVCodec *codec; AVCodecContext *c= NULL; int frame, got_picture, len; FILE *f; AVFrame *picture; uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; char buf[1024]; AVPacket avpkt; av_init_packet(&avpkt); /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); printf("Video decoding\n"); /* find the mpeg1 video decoder */ codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO); if (!codec) { fprintf(stderr, "codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); picture = av_frame_alloc(); if(codec->capabilities&CODEC_CAP_TRUNCATED) c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */ /* For some codecs, such as msmpeg4 and mpeg4, width and height MUST be initialized there because this information is not available in the bitstream. */ /* open it */ if (avcodec_open2(c, codec, NULL) < 0) { fprintf(stderr, "could not open codec\n"); exit(1); } /* the codec gives us the frame size, in samples */ f = fopen(filename, "rb"); if (!f) { fprintf(stderr, "could not open %s\n", filename); exit(1); } frame = 0; for(;;) { avpkt.size = fread(inbuf, 1, INBUF_SIZE, f); if (avpkt.size == 0) break; /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio) and this is the only method to use them because you cannot know the compressed data size before analysing it. BUT some other codecs (msmpeg4, mpeg4) are inherently frame based, so you must call them with all the data for one frame exactly. You must also initialize 'width' and 'height' before initializing them. */ /* NOTE2: some codecs allow the raw parameters (frame size, sample rate) to be changed at any frame. We handle this, so you should also take care of it */ /* here, we use a stream based decoder (mpeg1video), so we feed decoder and see if it could decode a frame */ avpkt.data = inbuf; while (avpkt.size > 0) { len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); if (len < 0) { fprintf(stderr, "Error while decoding frame %d\n", frame); exit(1); } if (got_picture) { printf("saving frame %3d\n", frame); fflush(stdout); /* the picture is allocated by the decoder. no need to free it */ snprintf(buf, sizeof(buf), outfilename, frame); pgm_save(picture->data[0], picture->linesize[0], c->width, c->height, buf); frame++; } avpkt.size -= len; avpkt.data += len; } } /* some codecs, such as MPEG, transmit the I and P frame with a latency of one frame. You must do the following to have a chance to get the last frame of the video */ avpkt.data = NULL; avpkt.size = 0; len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); if (got_picture) { printf("saving last frame %3d\n", frame); fflush(stdout); /* the picture is allocated by the decoder. no need to free it */ snprintf(buf, sizeof(buf), outfilename, frame); pgm_save(picture->data[0], picture->linesize[0], c->width, c->height, buf); frame++; } fclose(f); avcodec_close(c); av_free(c); av_frame_free(&picture); printf("\n"); }
// http://blog.csdn.net/leixiaohua1020/article/details/25346147 int yuv_to_jpg (unsigned char * yuv, unsigned iw, unsigned ih, const char * jpg_file) { AVFormatContext * pFormatCtx; AVOutputFormat * fmt; AVStream * video_st; AVCodecContext * pCodecCtx; AVCodec * pCodec; AVFrame* picture; AVPacket pkt; unsigned y_size = 0; unsigned size = 0; int got_pic = 0; int ret = 0; av_register_all (); //Method 1 pFormatCtx = avformat_alloc_context (); //Guess format fmt = av_guess_format ("mjpeg", NULL, NULL); pFormatCtx->oformat = fmt; //Output URL if (avio_open (&pFormatCtx->pb,jpg_file, AVIO_FLAG_READ_WRITE) < 0){ printf("Couldn't open output file."); return -1; } video_st = avformat_new_stream (pFormatCtx, 0); if (video_st==NULL) return -1; pCodecCtx = video_st->codec; pCodecCtx->codec_id = fmt->video_codec; pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO; pCodecCtx->pix_fmt = AV_PIX_FMT_YUVJ420P; pCodecCtx->width = iw; pCodecCtx->height = ih; pCodecCtx->time_base.num = 1; pCodecCtx->time_base.den = 25; pCodec = avcodec_find_encoder (pCodecCtx->codec_id); if (!pCodec) { printf("Codec not found."); return -1; } if (avcodec_open2 (pCodecCtx, pCodec,NULL) < 0){ printf("Could not open codec."); return -1; } picture = av_frame_alloc (); // size = iw * ih * 3 / 2 size = avpicture_fill ((AVPicture *) picture, NULL, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height); //Read YUV y_size = pCodecCtx->width * pCodecCtx->height; picture->data[0] = yuv; // Y picture->data[1] = yuv + y_size; // U picture->data[2] = yuv + y_size * 5 / 4; // V //Write Header avformat_write_header (pFormatCtx,NULL); //Encode av_new_packet (&pkt, y_size * 3); ret = avcodec_encode_video2 (pCodecCtx, &pkt, picture, &got_pic); if(ret < 0){ printf("Encode Error.\n"); return -1; } if (got_pic==1) { pkt.stream_index = video_st->index; ret = av_write_frame (pFormatCtx, &pkt); } av_free_packet (&pkt); //Write Trailer av_write_trailer (pFormatCtx); printf ("Encode Successful.\n"); if (video_st) { avcodec_close (video_st->codec); av_free (picture); } avio_close (pFormatCtx->pb); avformat_free_context (pFormatCtx); return 0; }
static void prepare (GeglOperation *operation) { GeglProperties *o = GEGL_PROPERTIES (operation); Priv *p = (Priv*)o->user_data; if (p == NULL) init (o); p = (Priv*)o->user_data; g_assert (o->user_data != NULL); gegl_operation_set_format (operation, "output", babl_format ("R'G'B' u8")); if (!p->loadedfilename || strcmp (p->loadedfilename, o->path) || p->prevframe > o->frame /* a bit heavy handed, but improves consistency */ ) { gint i; gint err; ff_cleanup (o); err = avformat_open_input(&p->video_fcontext, o->path, NULL, 0); if (err < 0) { print_error (o->path, err); } err = avformat_find_stream_info (p->video_fcontext, NULL); if (err < 0) { g_warning ("ff-load: error finding stream info for %s", o->path); return; } err = avformat_open_input(&p->audio_fcontext, o->path, NULL, 0); if (err < 0) { print_error (o->path, err); } err = avformat_find_stream_info (p->audio_fcontext, NULL); if (err < 0) { g_warning ("ff-load: error finding stream info for %s", o->path); return; } for (i = 0; i< p->video_fcontext->nb_streams; i++) { AVCodecContext *c = p->video_fcontext->streams[i]->codec; if (c->codec_type == AVMEDIA_TYPE_VIDEO) { p->video_stream = p->video_fcontext->streams[i]; p->video_index = i; } if (c->codec_type == AVMEDIA_TYPE_AUDIO) { p->audio_stream = p->audio_fcontext->streams[i]; p->audio_index = i; } } p->video_codec = avcodec_find_decoder (p->video_stream->codec->codec_id); if (p->audio_stream) { p->audio_codec = avcodec_find_decoder (p->audio_stream->codec->codec_id); if (p->audio_codec == NULL) g_warning ("audio codec not found"); else if (avcodec_open2 (p->audio_stream->codec, p->audio_codec, NULL) < 0) { g_warning ("error opening codec %s", p->audio_stream->codec->codec->name); } else { o->audio_sample_rate = p->audio_stream->codec->sample_rate; o->audio_channels = MIN(p->audio_stream->codec->channels, GEGL_MAX_AUDIO_CHANNELS); } } p->video_stream->codec->err_recognition = AV_EF_IGNORE_ERR | AV_EF_BITSTREAM | AV_EF_BUFFER; p->video_stream->codec->workaround_bugs = FF_BUG_AUTODETECT; if (p->video_codec == NULL) g_warning ("video codec not found"); if (avcodec_open2 (p->video_stream->codec, p->video_codec, NULL) < 0) { g_warning ("error opening codec %s", p->video_stream->codec->codec->name); return; } p->width = p->video_stream->codec->width; p->height = p->video_stream->codec->height; p->lavc_frame = av_frame_alloc (); if (o->video_codec) g_free (o->video_codec); if (p->video_codec->name) o->video_codec = g_strdup (p->video_codec->name); else o->video_codec = g_strdup (""); if (o->audio_codec) g_free (o->audio_codec); if (p->audio_codec && p->audio_codec->name) o->audio_codec = g_strdup (p->audio_codec->name); else o->audio_codec = g_strdup (""); if (p->loadedfilename) g_free (p->loadedfilename); p->loadedfilename = g_strdup (o->path); p->prevframe = -1; p->a_prevframe = -1; o->frames = p->video_stream->nb_frames; o->frame_rate = av_q2d (av_guess_frame_rate (p->video_fcontext, p->video_stream, NULL)); if (!o->frames) { /* this is a guesstimate of frame-count */ o->frames = p->video_fcontext->duration * o->frame_rate / AV_TIME_BASE; /* make second guess for things like luxo */ if (o->frames < 1) o->frames = 23; } #if 0 { int m ,h; int s = o->frames / o->frame_rate; m = s / 60; s -= m * 60; h = m / 60; m -= h * 60; fprintf (stdout, "duration: %02i:%02i:%02i\n", h, m, s); } #endif p->codec_delay = p->video_stream->codec->delay; if (!strcmp (o->video_codec, "mpeg1video")) p->codec_delay = 1; else if (!strcmp (o->video_codec, "h264")) { if (strstr (p->video_fcontext->filename, ".mp4") || strstr (p->video_fcontext->filename, ".MP4")) /* XXX: too hacky, isn't there an avformat thing to use?, or perhaps we can measure this when decoding the first frame. */ p->codec_delay = 3; else p->codec_delay = 0; } clear_audio_track (o); } }
static bool encode_audio(ffemu_t *handle, AVPacket *pkt, bool dry) { av_init_packet(pkt); pkt->data = handle->audio.outbuf; pkt->size = handle->audio.outbuf_size; AVFrame *frame = av_frame_alloc(); if (!frame) return false; frame->nb_samples = handle->audio.frames_in_buffer; frame->format = handle->audio.codec->sample_fmt; frame->channel_layout = handle->audio.codec->channel_layout; frame->pts = handle->audio.frame_cnt; planarize_audio(handle); int samples_size = av_samples_get_buffer_size(NULL, handle->audio.codec->channels, handle->audio.frames_in_buffer, handle->audio.codec->sample_fmt, 0); avcodec_fill_audio_frame(frame, handle->audio.codec->channels, handle->audio.codec->sample_fmt, handle->audio.is_planar ? (uint8_t*)handle->audio.planar_buf : handle->audio.buffer, samples_size, 0); int got_packet = 0; if (avcodec_encode_audio2(handle->audio.codec, pkt, dry ? NULL : frame, &got_packet) < 0) { av_frame_free(&frame); return false; } if (!got_packet) { pkt->size = 0; pkt->pts = AV_NOPTS_VALUE; pkt->dts = AV_NOPTS_VALUE; av_frame_free(&frame); return true; } if (pkt->pts != (int64_t)AV_NOPTS_VALUE) { pkt->pts = av_rescale_q(pkt->pts, handle->audio.codec->time_base, handle->muxer.astream->time_base); } if (pkt->dts != (int64_t)AV_NOPTS_VALUE) { pkt->dts = av_rescale_q(pkt->dts, handle->audio.codec->time_base, handle->muxer.astream->time_base); } av_frame_free(&frame); pkt->stream_index = handle->muxer.astream->index; return true; }
.dstPitch = frame->linesize[i], .srcY = offset, .WidthInBytes = FFMIN(pitch, frame->linesize[i]), .Height = avctx->height >> (i ? 1 : 0), }; ret = CHECK_CU(ctx->cudl->cuMemcpy2D(&cpy)); if (ret < 0) goto error; offset += avctx->coded_height; } } else if (avctx->pix_fmt == AV_PIX_FMT_NV12 || avctx->pix_fmt == AV_PIX_FMT_P010 || avctx->pix_fmt == AV_PIX_FMT_P016) { AVFrame *tmp_frame = av_frame_alloc(); if (!tmp_frame) { av_log(avctx, AV_LOG_ERROR, "av_frame_alloc failed\n"); ret = AVERROR(ENOMEM); goto error; } tmp_frame->format = AV_PIX_FMT_CUDA; tmp_frame->hw_frames_ctx = av_buffer_ref(ctx->hwframe); tmp_frame->data[0] = (uint8_t*)mapped_frame; tmp_frame->linesize[0] = pitch; tmp_frame->data[1] = (uint8_t*)(mapped_frame + avctx->coded_height * pitch); tmp_frame->linesize[1] = pitch; tmp_frame->width = avctx->width; tmp_frame->height = avctx->height;
/** \fn initialize */ bool AUDMEncoder_Lavcodec::initialize(void) { int ret; if( _incoming->getInfo()->channels>ADM_LAV_MAX_CHANNEL) { ADM_error("[Lavcodec]Too many channels\n"); return 0; } AVCodec *codec; AVCodecID codecID; codecID=avMakeName; codec = avcodec_find_encoder(codecID); ADM_assert(codec); _context=( void *)avcodec_alloc_context3(codec); _frame=av_frame_alloc(); wavheader.byterate=(_config.bitrate*1000)>>3; _chunk = ADM_LAV_SAMPLE_PER_P*wavheader.channels; // AC3 planarBuffer=new float[_chunk]; planarBufferSize=_chunk; ADM_info("[Lavcodec]Incoming : fq : %" PRIu32", channel : %" PRIu32" bitrate: %" PRIu32" \n", wavheader.frequency,wavheader.channels,_config.bitrate); if(wavheader.channels>2) { ADM_warning("Channel remapping activated\n"); needChannelRemapping=true; } else needChannelRemapping=false; CONTEXT->channels = wavheader.channels; CONTEXT->sample_rate = wavheader.frequency; CONTEXT->bit_rate = (_config.bitrate*1000); // bits -> kbits CONTEXT->sample_fmt = AV_SAMPLE_FMT_FLT; CONTEXT->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; CONTEXT->frame_size=_chunk/wavheader.channels; CONTEXT->channel_layout=av_get_default_channel_layout(wavheader.channels); if(true==_globalHeader) { ADM_info("Configuring audio codec to use global headers\n"); CONTEXT->flags|=CODEC_FLAG_GLOBAL_HEADER; } computeChannelLayout(); CONTEXT->sample_fmt = AV_SAMPLE_FMT_FLTP; ret = avcodec_open2(CONTEXT, codec,NULL); if (ret<0) { CONTEXT->sample_fmt=AV_SAMPLE_FMT_S16; ret = avcodec_open2(CONTEXT, codec,NULL); if (ret<0) { printError("Init failed",ret); return 0; } } //ADM_info("Frame size : %d, %d\n",CONTEXT->frame_size,_chunk/wavheader.channels); _frame->format=CONTEXT->sample_fmt; outputFlavor=asFloatPlanar; ADM_info("[Lavcodec]Lavcodec successfully initialized,wavTag : 0x%x\n",makeName(WAV)); return 1; }
static void handle_packet(struct vidsrc_st *st, AVPacket *pkt) { AVPicture pict; AVFrame *frame = NULL; struct vidframe vf; struct vidsz sz; unsigned i; if (st->codec) { int got_pict, ret; #if LIBAVUTIL_VERSION_INT >= ((52<<16)+(20<<8)+100) frame = av_frame_alloc(); #else frame = avcodec_alloc_frame(); #endif #if LIBAVCODEC_VERSION_INT <= ((52<<16)+(23<<8)+0) ret = avcodec_decode_video(st->ctx, frame, &got_pict, pkt->data, pkt->size); #else ret = avcodec_decode_video2(st->ctx, frame, &got_pict, pkt); #endif if (ret < 0 || !got_pict) return; sz.w = st->ctx->width; sz.h = st->ctx->height; /* check if size changed */ if (!vidsz_cmp(&sz, &st->sz)) { info("size changed: %d x %d ---> %d x %d\n", st->sz.w, st->sz.h, sz.w, sz.h); st->sz = sz; if (st->sws) { sws_freeContext(st->sws); st->sws = NULL; } } if (!st->sws) { info("scaling: %d x %d ---> %d x %d\n", st->sz.w, st->sz.h, st->app_sz.w, st->app_sz.h); st->sws = sws_getContext(st->sz.w, st->sz.h, st->ctx->pix_fmt, st->app_sz.w, st->app_sz.h, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); if (!st->sws) return; } ret = avpicture_alloc(&pict, PIX_FMT_YUV420P, st->app_sz.w, st->app_sz.h); if (ret < 0) return; ret = sws_scale(st->sws, SRCSLICE_CAST frame->data, frame->linesize, 0, st->sz.h, pict.data, pict.linesize); if (ret <= 0) goto end; } else { avpicture_fill(&pict, pkt->data, PIX_FMT_YUV420P, st->sz.w, st->sz.h); } vf.size = st->app_sz; vf.fmt = VID_FMT_YUV420P; for (i=0; i<4; i++) { vf.data[i] = pict.data[i]; vf.linesize[i] = pict.linesize[i]; } st->frameh(&vf, st->arg); end: if (st->codec) avpicture_free(&pict); if (frame) { #if LIBAVUTIL_VERSION_INT >= ((52<<16)+(20<<8)+100) av_frame_free(&frame); #else av_free(frame); #endif } }
static av_cold int libx265_encode_init(AVCodecContext *avctx) { libx265Context *ctx = avctx->priv_data; x265_nal *nal; uint8_t *buf; int sar_num, sar_den; int nnal; int ret; int i; if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL && !av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_w && !av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_h) { av_log(avctx, AV_LOG_ERROR, "4:4:4 support is not fully defined for HEVC yet. " "Set -strict experimental to encode anyway.\n"); return AVERROR(ENOSYS); } avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) { av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); return AVERROR(ENOMEM); } ctx->params = x265_param_alloc(); if (!ctx->params) { av_log(avctx, AV_LOG_ERROR, "Could not allocate x265 param structure.\n"); return AVERROR(ENOMEM); } if (x265_param_default_preset(ctx->params, ctx->preset, ctx->tune) < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid preset or tune.\n"); return AVERROR(EINVAL); } ctx->params->frameNumThreads = avctx->thread_count; ctx->params->fpsNum = avctx->time_base.den; ctx->params->fpsDenom = avctx->time_base.num * avctx->ticks_per_frame; ctx->params->sourceWidth = avctx->width; ctx->params->sourceHeight = avctx->height; av_reduce(&sar_num, &sar_den, avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 4096); ctx->params->vui.bEnableVuiParametersPresentFlag = 1; ctx->params->vui.bEnableAspectRatioIdc = 1; ctx->params->vui.aspectRatioIdc = 255; ctx->params->vui.sarWidth = sar_num; ctx->params->vui.sarHeight = sar_den; if (x265_max_bit_depth == 8) ctx->params->internalBitDepth = 8; else if (x265_max_bit_depth == 12) ctx->params->internalBitDepth = 10; switch (avctx->pix_fmt) { case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUV420P10: ctx->params->internalCsp = X265_CSP_I420; break; case AV_PIX_FMT_YUV444P: case AV_PIX_FMT_YUV444P10: ctx->params->internalCsp = X265_CSP_I444; break; } if (avctx->bit_rate > 0) { ctx->params->rc.bitrate = avctx->bit_rate / 1000; ctx->params->rc.rateControlMode = X265_RC_ABR; } if (ctx->x265_opts) { AVDictionary *dict = NULL; AVDictionaryEntry *en = NULL; if (!av_dict_parse_string(&dict, ctx->x265_opts, "=", ":", 0)) { while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) { int parse_ret = x265_param_parse(ctx->params, en->key, en->value); switch (parse_ret) { case X265_PARAM_BAD_NAME: av_log(avctx, AV_LOG_WARNING, "Unknown option: %s.\n", en->key); break; case X265_PARAM_BAD_VALUE: av_log(avctx, AV_LOG_WARNING, "Invalid value for %s: %s.\n", en->key, en->value); break; default: break; } } av_dict_free(&dict); } } ctx->encoder = x265_encoder_open(ctx->params); if (!ctx->encoder) { av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n"); libx265_encode_close(avctx); return AVERROR_INVALIDDATA; } ret = x265_encoder_headers(ctx->encoder, &nal, &nnal); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot encode headers.\n"); libx265_encode_close(avctx); return AVERROR_INVALIDDATA; } for (i = 0; i < nnal; i++) ctx->header_size += nal[i].sizeBytes; ctx->header = av_malloc(ctx->header_size); if (!ctx->header) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate HEVC header of size %d.\n", ctx->header_size); libx265_encode_close(avctx); return AVERROR(ENOMEM); } buf = ctx->header; for (i = 0; i < nnal; i++) { memcpy(buf, nal[i].payload, nal[i].sizeBytes); buf += nal[i].sizeBytes; } return 0; }
int main(int argc, char *argv[]) { av_register_all(); AVFormatContext *pFormatCtx = NULL; //Open video file and allocate format context //读取文件的头部信息,并且保持这些信息到AVFormatContext中 //如果AVFormatContext是NULL,这个函数将会同时申请一个空间 if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) < 0) { av_log(pFormatCtx, AV_LOG_ERROR, "Could not open file.\n"); return 1; } //检查在文件的流的信息 //这个函数为 pFormatCtx-streams填充正确的信息 if (avformat_find_stream_info(pFormatCtx, NULL) < 0) { av_log(pFormatCtx, AV_LOG_ERROR, "Could not find stream info.\n"); return 1; } //输出信息 av_dump_format(pFormatCtx, 0, argv[1], 0); //找到视频流 int videoStream = 0; videoStream = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if (videoStream == -1) { av_log(pFormatCtx, AV_LOG_ERROR, "Could not find stream index.\n"); return 1; } AVCodecContext *pCodecCtx = NULL; pCodecCtx = pFormatCtx->streams[videoStream]->codec; AVCodec *pCodec = NULL; pCodec =avcodec_find_decoder(pCodecCtx->codec_id); if (pCodec == NULL) { av_log(pCodec, AV_LOG_ERROR, "Could not find decoder.\n"); return 1; } //open codec if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { av_log(pCodecCtx, AV_LOG_ERROR, "Could open decoder.\n"); return 1; } AVFrame *pFrameRGB = NULL; pFrameRGB = av_frame_alloc(); if (!pFrameRGB) { av_log(pFrameRGB , AV_LOG_ERROR, "Could allocate frame.\n"); return 1; } uint8_t *buffer; int numBytes = 0; /* 之前我们申请了一个 帧 对象,当转换的时候,我们仍然需要一个地方来放置原始的数据。 我们使用avpicture_get_size来获取大小,然后av_malloc申请大小 avpicture_fill将申请的帧和我们新申请的内存结合起来 */ // numBytes = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); // buffer = (uint8_t *)av_malloc(numBytes); // avpicture_fill((AVPicture*)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); //使用av_image_alloc代替上面注释的三行代码 av_image_alloc(pFrameRGB->data, pFrameRGB->linesize, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, 1); //接下来,读入整个视频流,然后把它解码成帧,最后转换格式并且保存 int frameFinished; AVPacket pkt; //用来存储解码后的原始数据 AVFrame *pFrame = av_frame_alloc(); int i = 0; auto img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BILINEAR, NULL, NULL, NULL); while (av_read_frame(pFormatCtx, &pkt) >= 0) { //Is this a packet from the video stream? if (pkt.stream_index == videoStream) { //Decode video frame //packet -----> frame avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &pkt); if (frameFinished) { sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, (uint8_t *const *)pFrameRGB->data, pFrameRGB->linesize); if( ++i <= 100 ) SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i); } av_free_packet(&pkt); } } sws_freeContext(img_convert_ctx); //free the rgb image //av_free(buffer); av_free(pFrameRGB); //free the yuv frame av_free(pFrame); //close the codec avcodec_close(pCodecCtx); //close the video file avformat_close_input(&pFormatCtx); return 0; }
static int encode_audio(AVCodecContext *avctx, AVPacket *pkt, int16_t *audio_samples, int nb_samples) { // Assume *pkt is already initialized. int i, ch, buffer_size, ret, got_output = 0; AVMallocHolder<uint8_t> samples; AVFrameHolder frame; if (audio_samples) { frame.reset(av_frame_alloc()); if (!frame) return AVERROR(ENOMEM); frame->nb_samples = nb_samples; frame->format = avctx->sample_fmt; #if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 13, 0)) frame->channel_layout = avctx->channel_layout; #endif buffer_size = av_samples_get_buffer_size(NULL, avctx->channels, frame->nb_samples, avctx->sample_fmt, 0); if (buffer_size < 0) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Could not get sample buffer size")), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return buffer_size; } samples.reset(static_cast<uint8_t*>(av_malloc(buffer_size))); if (!samples) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Could not allocate bytes for samples buffer")), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return AVERROR(ENOMEM); } /* setup the data pointers in the AVFrame */ ret = avcodec_fill_audio_frame(frame.get(), avctx->channels, avctx->sample_fmt, samples.get(), buffer_size, 0); if (ret < 0) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Could not setup audio frame")), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return ret; } for (ch = 0; ch < avctx->channels; ch++) { for (i = 0; i < frame->nb_samples; i++) { switch(avctx->sample_fmt) { case AV_SAMPLE_FMT_U8: ((uint8_t*)(frame->data[0]))[ch + i*avctx->channels] = audio_samples[ch + i*avctx->channels]/258 + 128; break; case AV_SAMPLE_FMT_U8P: ((uint8_t*)(frame->data[ch]))[i] = audio_samples[ch + i*avctx->channels]/258 + 128; break; case AV_SAMPLE_FMT_S16: ((int16_t*)(frame->data[0]))[ch + i*avctx->channels] = audio_samples[ch + i*avctx->channels]; break; case AV_SAMPLE_FMT_S16P: ((int16_t*)(frame->data[ch]))[i] = audio_samples[ch + i*avctx->channels]; break; case AV_SAMPLE_FMT_S32: ((int32_t*)(frame->data[0]))[ch + i*avctx->channels] = audio_samples[ch + i*avctx->channels]<<16; break; case AV_SAMPLE_FMT_S32P: ((int32_t*)(frame->data[ch]))[i] = audio_samples[ch + i*avctx->channels]<<16; break; case AV_SAMPLE_FMT_FLT: ((float*)(frame->data[0]))[ch + i*avctx->channels] = audio_samples[ch + i*avctx->channels] / 32767.0; break; case AV_SAMPLE_FMT_FLTP: ((float*)(frame->data[ch]))[i] = audio_samples[ch + i*avctx->channels] / 32767.; break; case AV_SAMPLE_FMT_NONE: case AV_SAMPLE_FMT_DBL: case AV_SAMPLE_FMT_DBLP: case AV_SAMPLE_FMT_NB: wxASSERT(false); break; } } } } pkt->data = NULL; // packet data will be allocated by the encoder pkt->size = 0; ret = avcodec_encode_audio2(avctx, pkt, frame.get(), &got_output); if (ret < 0) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - encoding frame failed")), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return ret; } pkt->dts = pkt->pts = AV_NOPTS_VALUE; // we dont set frame.pts thus dont trust the AVPacket ts return got_output; }
int main(int argc, char *argv[]) { AVFormatContext *pFormatCtx = NULL; int i, videoStream; AVCodecContext *pCodecCtx = NULL; AVCodec *pCodec = NULL; AVFrame *pFrame = NULL; AVFrame *pFrameRGB = NULL; AVPacket packet; int frameFinished; int numBytes; uint8_t *buffer = NULL; AVDictionary *optionsDict = NULL; struct SwsContext *sws_ctx = NULL; if(argc < 2) { printf("Please provide a movie file\n"); return -1; } char out_file[1024]={0}; sprintf(out_file,"%s.nalu",argv[1]); static FILE *fp = fopen(out_file,"wb"); if(!fp){ printf("can't open output file:%s\n",out_file); } // 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; i<pFormatCtx->nb_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 pCodecCtx=pFormatCtx->streams[videoStream]->codec; // Find the decoder for the video stream pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) { fprintf(stderr, "Unsupported codec!\n"); return -1; // Codec not found } // Open codec if(avcodec_open2(pCodecCtx, pCodec, &optionsDict)<0) return -1; // Could not open codec // Allocate video frame pFrame=av_frame_alloc(); unsigned char *dummy=NULL; //输入的指针 int dummy_len; AVBitStreamFilterContext* bsfc = av_bitstream_filter_init("h264_mp4toannexb"); av_bitstream_filter_filter(bsfc, pCodecCtx, NULL, &dummy, &dummy_len, NULL, 0, 0); fwrite(pCodecCtx->extradata,pCodecCtx->extradata_size,1,fp); av_bitstream_filter_close(bsfc); free(dummy); // 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) { static bool find_i = false; if(!find_i){ static unsigned char i_tag[] = {0x65}; if(memcmp(i_tag,(packet.data)+4,1) ==0) { find_i = true; printf("find i frame\n"); } else { continue; } } char nal_start[]={0,0,0,1}; fwrite(nal_start,4,1,fp); fwrite(packet.data+4,packet.size-4,1,fp); printf("write packet size:%d\n",packet.size-4); } } } // Free the packet that was allocated by av_read_frame av_free_packet(&packet); // Free the RGB image av_free(buffer); // Free the YUV frame av_free(pFrame); // Close the codec avcodec_close(pCodecCtx); // Close the video file avformat_close_input(&pFormatCtx); fclose(fp); return 0; }
void AudioLoader::openAudioFile(const string& filename) { E_DEBUG(EAlgorithm, "AudioLoader: opening file: " << filename); // Open file int errnum; if ((errnum = avformat_open_input(&_demuxCtx, filename.c_str(), NULL, NULL)) != 0) { char errorstr[128]; string error = "Unknown error"; if (av_strerror(errnum, errorstr, 128) == 0) error = errorstr; throw EssentiaException("AudioLoader: Could not open file \"", filename, "\", error = ", error); } // Retrieve stream information if ((errnum = avformat_find_stream_info(_demuxCtx, NULL)) < 0) { char errorstr[128]; string error = "Unknown error"; if (av_strerror(errnum, errorstr, 128) == 0) error = errorstr; avformat_close_input(&_demuxCtx); _demuxCtx = 0; throw EssentiaException("AudioLoader: Could not find stream information, error = ", error); } // Dump information about file onto standard error //dump_format(_demuxCtx, 0, filename.c_str(), 0); // Check that we have only 1 audio stream in the file int nAudioStreams = 0; for (int i=0; i<(int)_demuxCtx->nb_streams; i++) { if (_demuxCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { _streamIdx = i; nAudioStreams++; } } if (nAudioStreams != 1) { throw EssentiaException("AudioLoader ERROR: found ", nAudioStreams, " streams in the file, expecting only one audio stream"); } // Load corresponding audio codec _audioCtx = _demuxCtx->streams[_streamIdx]->codec; _audioCodec = avcodec_find_decoder(_audioCtx->codec_id); if (!_audioCodec) { throw EssentiaException("AudioLoader: Unsupported codec!"); } if (avcodec_open2(_audioCtx, _audioCodec, NULL) < 0) { throw EssentiaException("AudioLoader: Unable to instantiate codec..."); } // Configure format convertion (no samplerate conversion yet) int64_t layout = av_get_default_channel_layout(_audioCtx->channels); /* const char* fmt = 0; get_format_from_sample_fmt(&fmt, _audioCtx->sample_fmt); E_DEBUG(EAlgorithm, "AudioLoader: converting from " << (fmt ? fmt : "unknown") << " to FLT"); */ E_DEBUG(EAlgorithm, "AudioLoader: using sample format conversion from libavresample"); _convertCtxAv = avresample_alloc_context(); av_opt_set_int(_convertCtxAv, "in_channel_layout", layout, 0); av_opt_set_int(_convertCtxAv, "out_channel_layout", layout, 0); av_opt_set_int(_convertCtxAv, "in_sample_rate", _audioCtx->sample_rate, 0); av_opt_set_int(_convertCtxAv, "out_sample_rate", _audioCtx->sample_rate, 0); av_opt_set_int(_convertCtxAv, "in_sample_fmt", _audioCtx->sample_fmt, 0); av_opt_set_int(_convertCtxAv, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0); if (avresample_open(_convertCtxAv) < 0) { throw EssentiaException("AudioLoader: Could not initialize avresample context"); } av_init_packet(&_packet); _decodedFrame = av_frame_alloc(); if (!_decodedFrame) { throw EssentiaException("AudioLoader: Could not allocate audio frame"); } av_md5_init(_md5Encoded); }
int main(int argc, char* argv[]) { AVFormatContext *ifmt_ctx = NULL; AVFormatContext *ifmt_ctx_a = NULL; AVFormatContext *ofmt_ctx; AVInputFormat* ifmt; AVStream* video_st; AVStream* audio_st; AVCodecContext* pCodecCtx; AVCodecContext* pCodecCtx_a; AVCodec* pCodec; AVCodec* pCodec_a; AVPacket *dec_pkt, enc_pkt; AVPacket *dec_pkt_a, enc_pkt_a; AVFrame *pframe, *pFrameYUV; struct SwsContext *img_convert_ctx; struct SwrContext *aud_convert_ctx; char capture_name[80] = { 0 }; char device_name[80] = { 0 }; char device_name_a[80] = { 0 }; int framecnt = 0; int nb_samples = 0; int videoindex; int audioindex; int i; int ret; HANDLE hThread; const char* out_path = "rtmp://localhost/live/livestream"; int dec_got_frame, enc_got_frame; int dec_got_frame_a, enc_got_frame_a; int aud_next_pts = 0; int vid_next_pts = 0; int encode_video = 1, encode_audio = 1; AVRational time_base_q = { 1, AV_TIME_BASE }; av_register_all(); //Register Device avdevice_register_all(); avformat_network_init(); #if USEFILTER //Register Filter avfilter_register_all(); buffersrc = avfilter_get_by_name("buffer"); buffersink = avfilter_get_by_name("buffersink"); #endif //Show Dshow Device show_dshow_device(); printf("\nChoose video capture device: "); if (gets(capture_name) == 0) { printf("Error in gets()\n"); return -1; } sprintf(device_name, "video=%s", capture_name); printf("\nChoose audio capture device: "); if (gets(capture_name) == 0) { printf("Error in gets()\n"); return -1; } sprintf(device_name_a, "audio=%s", capture_name); //wchar_t *cam = L"video=Integrated Camera"; //wchar_t *cam = L"video=YY伴侣"; //char *device_name_utf8 = dup_wchar_to_utf8(cam); //wchar_t *cam_a = L"audio=麦克风阵列 (Realtek High Definition Audio)"; //char *device_name_utf8_a = dup_wchar_to_utf8(cam_a); ifmt = av_find_input_format("dshow"); // Set device params AVDictionary *device_param = 0; //if not setting rtbufsize, error messages will be shown in cmd, but you can still watch or record the stream correctly in most time //setting rtbufsize will erase those error messages, however, larger rtbufsize will bring latency //av_dict_set(&device_param, "rtbufsize", "10M", 0); //Set own video device's name if (avformat_open_input(&ifmt_ctx, device_name, ifmt, &device_param) != 0){ printf("Couldn't open input video stream.(无法打开输入流)\n"); return -1; } //Set own audio device's name if (avformat_open_input(&ifmt_ctx_a, device_name_a, ifmt, &device_param) != 0){ printf("Couldn't open input audio stream.(无法打开输入流)\n"); return -1; } //input video initialize if (avformat_find_stream_info(ifmt_ctx, NULL) < 0) { printf("Couldn't find video stream information.(无法获取流信息)\n"); return -1; } videoindex = -1; for (i = 0; i < ifmt_ctx->nb_streams; i++) if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoindex = i; break; } if (videoindex == -1) { printf("Couldn't find a video stream.(没有找到视频流)\n"); return -1; } if (avcodec_open2(ifmt_ctx->streams[videoindex]->codec, avcodec_find_decoder(ifmt_ctx->streams[videoindex]->codec->codec_id), NULL) < 0) { printf("Could not open video codec.(无法打开解码器)\n"); return -1; } //input audio initialize if (avformat_find_stream_info(ifmt_ctx_a, NULL) < 0) { printf("Couldn't find audio stream information.(无法获取流信息)\n"); return -1; } audioindex = -1; for (i = 0; i < ifmt_ctx_a->nb_streams; i++) if (ifmt_ctx_a->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { audioindex = i; break; } if (audioindex == -1) { printf("Couldn't find a audio stream.(没有找到视频流)\n"); return -1; } if (avcodec_open2(ifmt_ctx_a->streams[audioindex]->codec, avcodec_find_decoder(ifmt_ctx_a->streams[audioindex]->codec->codec_id), NULL) < 0) { printf("Could not open audio codec.(无法打开解码器)\n"); return -1; } //output initialize avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", out_path); //output video encoder initialize pCodec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!pCodec){ printf("Can not find output video encoder! (没有找到合适的编码器!)\n"); return -1; } pCodecCtx = avcodec_alloc_context3(pCodec); pCodecCtx->pix_fmt = PIX_FMT_YUV420P; pCodecCtx->width = ifmt_ctx->streams[videoindex]->codec->width; pCodecCtx->height = ifmt_ctx->streams[videoindex]->codec->height; pCodecCtx->time_base.num = 1; pCodecCtx->time_base.den = 25; pCodecCtx->bit_rate = 300000; pCodecCtx->gop_size = 250; /* Some formats want stream headers to be separate. */ if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER; //H264 codec param //pCodecCtx->me_range = 16; //pCodecCtx->max_qdiff = 4; //pCodecCtx->qcompress = 0.6; pCodecCtx->qmin = 10; pCodecCtx->qmax = 51; //Optional Param pCodecCtx->max_b_frames = 0; // Set H264 preset and tune AVDictionary *param = 0; av_dict_set(¶m, "preset", "fast", 0); av_dict_set(¶m, "tune", "zerolatency", 0); if (avcodec_open2(pCodecCtx, pCodec, ¶m) < 0){ printf("Failed to open output video encoder! (编码器打开失败!)\n"); return -1; } //Add a new stream to output,should be called by the user before avformat_write_header() for muxing video_st = avformat_new_stream(ofmt_ctx, pCodec); if (video_st == NULL){ return -1; } video_st->time_base.num = 1; video_st->time_base.den = 25; video_st->codec = pCodecCtx; //output audio encoder initialize pCodec_a = avcodec_find_encoder(AV_CODEC_ID_AAC); if (!pCodec_a){ printf("Can not find output audio encoder! (没有找到合适的编码器!)\n"); return -1; } pCodecCtx_a = avcodec_alloc_context3(pCodec_a); pCodecCtx_a->channels = 2; pCodecCtx_a->channel_layout = av_get_default_channel_layout(2); pCodecCtx_a->sample_rate = ifmt_ctx_a->streams[audioindex]->codec->sample_rate; pCodecCtx_a->sample_fmt = pCodec_a->sample_fmts[0]; pCodecCtx_a->bit_rate = 32000; pCodecCtx_a->time_base.num = 1; pCodecCtx_a->time_base.den = pCodecCtx_a->sample_rate; /** Allow the use of the experimental AAC encoder */ pCodecCtx_a->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; /* Some formats want stream headers to be separate. */ if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) pCodecCtx_a->flags |= CODEC_FLAG_GLOBAL_HEADER; if (avcodec_open2(pCodecCtx_a, pCodec_a, NULL) < 0){ printf("Failed to open ouput audio encoder! (编码器打开失败!)\n"); return -1; } //Add a new stream to output,should be called by the user before avformat_write_header() for muxing audio_st = avformat_new_stream(ofmt_ctx, pCodec_a); if (audio_st == NULL){ return -1; } audio_st->time_base.num = 1; audio_st->time_base.den = pCodecCtx_a->sample_rate; audio_st->codec = pCodecCtx_a; //Open output URL,set before avformat_write_header() for muxing if (avio_open(&ofmt_ctx->pb, out_path, AVIO_FLAG_READ_WRITE) < 0){ printf("Failed to open output file! (输出文件打开失败!)\n"); return -1; } //Show some Information av_dump_format(ofmt_ctx, 0, out_path, 1); //Write File Header avformat_write_header(ofmt_ctx, NULL); //prepare before decode and encode dec_pkt = (AVPacket *)av_malloc(sizeof(AVPacket)); #if USEFILTER #else //camera data may has a pix fmt of RGB or sth else,convert it to YUV420 img_convert_ctx = sws_getContext(ifmt_ctx->streams[videoindex]->codec->width, ifmt_ctx->streams[videoindex]->codec->height, ifmt_ctx->streams[videoindex]->codec->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); // Initialize the resampler to be able to convert audio sample formats aud_convert_ctx = swr_alloc_set_opts(NULL, av_get_default_channel_layout(pCodecCtx_a->channels), pCodecCtx_a->sample_fmt, pCodecCtx_a->sample_rate, av_get_default_channel_layout(ifmt_ctx_a->streams[audioindex]->codec->channels), ifmt_ctx_a->streams[audioindex]->codec->sample_fmt, ifmt_ctx_a->streams[audioindex]->codec->sample_rate, 0, NULL); /** * Perform a sanity check so that the number of converted samples is * not greater than the number of samples to be converted. * If the sample rates differ, this case has to be handled differently */ //av_assert0(pCodecCtx_a->sample_rate == ifmt_ctx_a->streams[audioindex]->codec->sample_rate); swr_init(aud_convert_ctx); #endif //Initialize the buffer to store YUV frames to be encoded. pFrameYUV = av_frame_alloc(); uint8_t *out_buffer = (uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height)); avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height); //Initialize the FIFO buffer to store audio samples to be encoded. AVAudioFifo *fifo = NULL; fifo = av_audio_fifo_alloc(pCodecCtx_a->sample_fmt, pCodecCtx_a->channels, 1); //Initialize the buffer to store converted samples to be encoded. uint8_t **converted_input_samples = NULL; /** * Allocate as many pointers as there are audio channels. * Each pointer will later point to the audio samples of the corresponding * channels (although it may be NULL for interleaved formats). */ if (!(converted_input_samples = (uint8_t**)calloc(pCodecCtx_a->channels, sizeof(**converted_input_samples)))) { printf("Could not allocate converted input sample pointers\n"); return AVERROR(ENOMEM); } printf("\n --------call started----------\n"); #if USEFILTER printf("\n Press differnet number for different filters:"); printf("\n 1->Mirror"); printf("\n 2->Add Watermark"); printf("\n 3->Negate"); printf("\n 4->Draw Edge"); printf("\n 5->Split Into 4"); printf("\n 6->Vintage"); printf("\n Press 0 to remove filter\n"); #endif printf("\nPress enter to stop...\n"); hThread = CreateThread( NULL, // default security attributes 0, // use default stack size MyThreadFunction, // thread function name NULL, // argument to thread function 0, // use default creation flags NULL); // returns the thread identifier //start decode and encode int64_t start_time = av_gettime(); while (encode_video || encode_audio) { if (encode_video && (!encode_audio || av_compare_ts(vid_next_pts, time_base_q, aud_next_pts, time_base_q) <= 0)) { if ((ret=av_read_frame(ifmt_ctx, dec_pkt)) >= 0){ if (exit_thread) break; av_log(NULL, AV_LOG_DEBUG, "Going to reencode the frame\n"); pframe = av_frame_alloc(); if (!pframe) { ret = AVERROR(ENOMEM); return ret; } ret = avcodec_decode_video2(ifmt_ctx->streams[dec_pkt->stream_index]->codec, pframe, &dec_got_frame, dec_pkt); if (ret < 0) { av_frame_free(&pframe); av_log(NULL, AV_LOG_ERROR, "Decoding failed\n"); break; } if (dec_got_frame){ #if USEFILTER pframe->pts = av_frame_get_best_effort_timestamp(pframe); if (filter_change) apply_filters(ifmt_ctx); filter_change = 0; /* push the decoded frame into the filtergraph */ if (av_buffersrc_add_frame(buffersrc_ctx, pframe) < 0) { printf("Error while feeding the filtergraph\n"); break; } picref = av_frame_alloc(); /* pull filtered pictures from the filtergraph */ while (1) { ret = av_buffersink_get_frame_flags(buffersink_ctx, picref, 0); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break; if (ret < 0) return ret; if (picref) { img_convert_ctx = sws_getContext(picref->width, picref->height, (AVPixelFormat)picref->format, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); sws_scale(img_convert_ctx, (const uint8_t* const*)picref->data, picref->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); sws_freeContext(img_convert_ctx); pFrameYUV->width = picref->width; pFrameYUV->height = picref->height; pFrameYUV->format = PIX_FMT_YUV420P; #else sws_scale(img_convert_ctx, (const uint8_t* const*)pframe->data, pframe->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); pFrameYUV->width = pframe->width; pFrameYUV->height = pframe->height; pFrameYUV->format = PIX_FMT_YUV420P; #endif enc_pkt.data = NULL; enc_pkt.size = 0; av_init_packet(&enc_pkt); ret = avcodec_encode_video2(pCodecCtx, &enc_pkt, pFrameYUV, &enc_got_frame); av_frame_free(&pframe); if (enc_got_frame == 1){ //printf("Succeed to encode frame: %5d\tsize:%5d\n", framecnt, enc_pkt.size); framecnt++; enc_pkt.stream_index = video_st->index; //Write PTS AVRational time_base = ofmt_ctx->streams[0]->time_base;//{ 1, 1000 }; AVRational r_framerate1 = ifmt_ctx->streams[videoindex]->r_frame_rate;//{ 50, 2 }; //Duration between 2 frames (us) int64_t calc_duration = (double)(AV_TIME_BASE)*(1 / av_q2d(r_framerate1)); //内部时间戳 //Parameters //enc_pkt.pts = (double)(framecnt*calc_duration)*(double)(av_q2d(time_base_q)) / (double)(av_q2d(time_base)); enc_pkt.pts = av_rescale_q(framecnt*calc_duration, time_base_q, time_base); enc_pkt.dts = enc_pkt.pts; enc_pkt.duration = av_rescale_q(calc_duration, time_base_q, time_base); //(double)(calc_duration)*(double)(av_q2d(time_base_q)) / (double)(av_q2d(time_base)); enc_pkt.pos = -1; //printf("video pts : %d\n", enc_pkt.pts); vid_next_pts=framecnt*calc_duration; //general timebase //Delay int64_t pts_time = av_rescale_q(enc_pkt.pts, time_base, time_base_q); int64_t now_time = av_gettime() - start_time; if ((pts_time > now_time) && ((vid_next_pts + pts_time - now_time)<aud_next_pts)) av_usleep(pts_time - now_time); ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt); av_free_packet(&enc_pkt); } #if USEFILTER av_frame_unref(picref); } } #endif } else { av_frame_free(&pframe); } av_free_packet(dec_pkt); } else if (ret == AVERROR_EOF) encode_video = 0; else { printf("Could not read video frame\n"); return ret; } } else { //audio trancoding here const int output_frame_size = pCodecCtx_a->frame_size; if (exit_thread) break; /** * Make sure that there is one frame worth of samples in the FIFO * buffer so that the encoder can do its work. * Since the decoder's and the encoder's frame size may differ, we * need to FIFO buffer to store as many frames worth of input samples * that they make up at least one frame worth of output samples. */ while (av_audio_fifo_size(fifo) < output_frame_size) { /** * Decode one frame worth of audio samples, convert it to the * output sample format and put it into the FIFO buffer. */ AVFrame *input_frame = av_frame_alloc(); if (!input_frame) { ret = AVERROR(ENOMEM); return ret; } /** Decode one frame worth of audio samples. */ /** Packet used for temporary storage. */ AVPacket input_packet; av_init_packet(&input_packet); input_packet.data = NULL; input_packet.size = 0; /** Read one audio frame from the input file into a temporary packet. */ if ((ret = av_read_frame(ifmt_ctx_a, &input_packet)) < 0) { /** If we are at the end of the file, flush the decoder below. */ if (ret == AVERROR_EOF) { encode_audio = 0; } else { printf("Could not read audio frame\n"); return ret; } } /** * Decode the audio frame stored in the temporary packet. * The input audio stream decoder is used to do this. * If we are at the end of the file, pass an empty packet to the decoder * to flush it. */ if ((ret = avcodec_decode_audio4(ifmt_ctx_a->streams[audioindex]->codec, input_frame, &dec_got_frame_a, &input_packet)) < 0) { printf("Could not decode audio frame\n"); return ret; } av_packet_unref(&input_packet); /** If there is decoded data, convert and store it */ if (dec_got_frame_a) { /** * Allocate memory for the samples of all channels in one consecutive * block for convenience. */ if ((ret = av_samples_alloc(converted_input_samples, NULL, pCodecCtx_a->channels, input_frame->nb_samples, pCodecCtx_a->sample_fmt, 0)) < 0) { printf("Could not allocate converted input samples\n"); av_freep(&(*converted_input_samples)[0]); free(*converted_input_samples); return ret; } /** * Convert the input samples to the desired output sample format. * This requires a temporary storage provided by converted_input_samples. */ /** Convert the samples using the resampler. */ if ((ret = swr_convert(aud_convert_ctx, converted_input_samples, input_frame->nb_samples, (const uint8_t**)input_frame->extended_data, input_frame->nb_samples)) < 0) { printf("Could not convert input samples\n"); return ret; } /** Add the converted input samples to the FIFO buffer for later processing. */ /** * Make the FIFO as large as it needs to be to hold both, * the old and the new samples. */ if ((ret = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + input_frame->nb_samples)) < 0) { printf("Could not reallocate FIFO\n"); return ret; } /** Store the new samples in the FIFO buffer. */ if (av_audio_fifo_write(fifo, (void **)converted_input_samples, input_frame->nb_samples) < input_frame->nb_samples) { printf("Could not write data to FIFO\n"); return AVERROR_EXIT; } } } /** * If we have enough samples for the encoder, we encode them. * At the end of the file, we pass the remaining samples to * the encoder. */ if (av_audio_fifo_size(fifo) >= output_frame_size) /** * Take one frame worth of audio samples from the FIFO buffer, * encode it and write it to the output file. */ { /** Temporary storage of the output samples of the frame written to the file. */ AVFrame *output_frame=av_frame_alloc(); if (!output_frame) { ret = AVERROR(ENOMEM); return ret; } /** * Use the maximum number of possible samples per frame. * If there is less than the maximum possible frame size in the FIFO * buffer use this number. Otherwise, use the maximum possible frame size */ const int frame_size = FFMIN(av_audio_fifo_size(fifo), pCodecCtx_a->frame_size); /** Initialize temporary storage for one output frame. */ /** * Set the frame's parameters, especially its size and format. * av_frame_get_buffer needs this to allocate memory for the * audio samples of the frame. * Default channel layouts based on the number of channels * are assumed for simplicity. */ output_frame->nb_samples = frame_size; output_frame->channel_layout = pCodecCtx_a->channel_layout; output_frame->format = pCodecCtx_a->sample_fmt; output_frame->sample_rate = pCodecCtx_a->sample_rate; /** * Allocate the samples of the created frame. This call will make * sure that the audio frame can hold as many samples as specified. */ if ((ret = av_frame_get_buffer(output_frame, 0)) < 0) { printf("Could not allocate output frame samples\n"); av_frame_free(&output_frame); return ret; } /** * Read as many samples from the FIFO buffer as required to fill the frame. * The samples are stored in the frame temporarily. */ if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) { printf("Could not read data from FIFO\n"); return AVERROR_EXIT; } /** Encode one frame worth of audio samples. */ /** Packet used for temporary storage. */ AVPacket output_packet; av_init_packet(&output_packet); output_packet.data = NULL; output_packet.size = 0; /** Set a timestamp based on the sample rate for the container. */ if (output_frame) { nb_samples += output_frame->nb_samples; } /** * Encode the audio frame and store it in the temporary packet. * The output audio stream encoder is used to do this. */ if ((ret = avcodec_encode_audio2(pCodecCtx_a, &output_packet, output_frame, &enc_got_frame_a)) < 0) { printf("Could not encode frame\n"); av_packet_unref(&output_packet); return ret; } /** Write one audio frame from the temporary packet to the output file. */ if (enc_got_frame_a) { output_packet.stream_index = 1; AVRational time_base = ofmt_ctx->streams[1]->time_base; AVRational r_framerate1 = { ifmt_ctx_a->streams[audioindex]->codec->sample_rate, 1 };// { 44100, 1}; int64_t calc_duration = (double)(AV_TIME_BASE)*(1 / av_q2d(r_framerate1)); //内部时间戳 output_packet.pts = av_rescale_q(nb_samples*calc_duration, time_base_q, time_base); output_packet.dts = output_packet.pts; output_packet.duration = output_frame->nb_samples; //printf("audio pts : %d\n", output_packet.pts); aud_next_pts = nb_samples*calc_duration; int64_t pts_time = av_rescale_q(output_packet.pts, time_base, time_base_q); int64_t now_time = av_gettime() - start_time; if ((pts_time > now_time) && ((aud_next_pts + pts_time - now_time)<vid_next_pts)) av_usleep(pts_time - now_time); if ((ret = av_interleaved_write_frame(ofmt_ctx, &output_packet)) < 0) { printf("Could not write frame\n"); av_packet_unref(&output_packet); return ret; } av_packet_unref(&output_packet); } av_frame_free(&output_frame); } } } //Flush Encoder ret = flush_encoder(ifmt_ctx, ofmt_ctx, 0, framecnt); if (ret < 0) { printf("Flushing encoder failed\n"); return -1; } ret = flush_encoder_a(ifmt_ctx_a, ofmt_ctx, 1, nb_samples); if (ret < 0) { printf("Flushing encoder failed\n"); return -1; } //Write file trailer av_write_trailer(ofmt_ctx); cleanup: //Clean #if USEFILTER if (filter_graph) avfilter_graph_free(&filter_graph); #endif if (video_st) avcodec_close(video_st->codec); if (audio_st) avcodec_close(audio_st->codec); av_free(out_buffer); if (converted_input_samples) { av_freep(&converted_input_samples[0]); //free(converted_input_samples); } if (fifo) av_audio_fifo_free(fifo); avio_close(ofmt_ctx->pb); avformat_free_context(ifmt_ctx); avformat_free_context(ifmt_ctx_a); avformat_free_context(ofmt_ctx); CloseHandle(hThread); return 0; }