static void open_audio (GeglProperties *o, AVFormatContext * oc, AVStream * st) { Priv *p = (Priv*)o->user_data; AVCodecContext *c; AVCodec *codec; int i; c = st->codec; /* find the audio encoder */ codec = avcodec_find_encoder (c->codec_id); if (!codec) { fprintf (stderr, "codec not found\n"); exit (1); } c->bit_rate = 64000; c->sample_fmt = codec->sample_fmts ? codec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP; if (p->audio_sample_rate == -1) { if (o->audio) { if (gegl_audio_fragment_get_sample_rate (o->audio) == 0) { gegl_audio_fragment_set_sample_rate (o->audio, 48000); // XXX: should skip adding audiostream instead } p->audio_sample_rate = gegl_audio_fragment_get_sample_rate (o->audio); } } c->sample_rate = p->audio_sample_rate; c->channel_layout = AV_CH_LAYOUT_STEREO; c->channels = 2; if (codec->supported_samplerates) { c->sample_rate = codec->supported_samplerates[0]; for (i = 0; codec->supported_samplerates[i]; i++) { if (codec->supported_samplerates[i] == p->audio_sample_rate) c->sample_rate = p->audio_sample_rate; } } //st->time_base = (AVRational){1, c->sample_rate}; st->time_base = (AVRational){1, p->audio_sample_rate}; c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; // ffmpeg AAC is not quite stable yet /* open it */ if (avcodec_open2 (c, codec, NULL) < 0) { fprintf (stderr, "could not open codec\n"); exit (1); } }
static gboolean process (GeglOperation *operation, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglProperties *o = GEGL_PROPERTIES (operation); Priv *p = (Priv*)o->user_data; { if (p->video_fcontext && !decode_frame (operation, o->frame)) { long sample_start = 0; if (p->audio_stream) { int sample_count; gegl_audio_fragment_set_sample_rate (o->audio, p->audio_stream->codec->sample_rate); gegl_audio_fragment_set_channels (o->audio, 2); gegl_audio_fragment_set_channel_layout (o->audio, GEGL_CH_LAYOUT_STEREO); sample_count = samples_per_frame (o->frame, o->frame_rate, p->audio_stream->codec->sample_rate, &sample_start); gegl_audio_fragment_set_sample_count (o->audio, sample_count); decode_audio (operation, p->prevpts, p->prevpts + 5.0); { int i; for (i = 0; i < sample_count; i++) { get_sample_data (p, sample_start + i, &o->audio->data[0][i], &o->audio->data[1][i]); } } } if (p->video_stream->codec->pix_fmt == AV_PIX_FMT_RGB24) { GeglRectangle extent = {0,0,p->width,p->height}; gegl_buffer_set (output, &extent, 0, babl_format("R'G'B' u8"), p->lavc_frame->data[0], GEGL_AUTO_ROWSTRIDE); } else { struct SwsContext *img_convert_ctx; GeglRectangle extent = {0,0,p->width,p->height}; img_convert_ctx = sws_getContext(p->width, p->height, p->video_stream->codec->pix_fmt, p->width, p->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); if (!p->rgb_frame) p->rgb_frame = alloc_picture (AV_PIX_FMT_RGB24, p->width, p->height); sws_scale (img_convert_ctx, (void*)p->lavc_frame->data, p->lavc_frame->linesize, 0, p->height, p->rgb_frame->data, p->rgb_frame->linesize); gegl_buffer_set (output, &extent, 0, babl_format("R'G'B' u8"), p->rgb_frame->data[0], GEGL_AUTO_ROWSTRIDE); sws_freeContext (img_convert_ctx); } } } return TRUE; }