need help transcoding audio only files

Peter Quiring pquiring at gmail.com
Thu Jun 28 09:25:40 PDT 2012


I'm having some success with GStreamer but having some difficulties with
audio only files.

If I transcode WMV to OGG it works.
But if I try to transcode MP3 to WAV it fails.

ERROR : encodebin says : Couldn't create encoder for format audio/x-wav
In my encoding profile I don't use a container, only an audio profile that
is set to the encodebin "profile" property.

And if I try and just decode MP3 to RAW it never starts and my appsink
blocks forever.  I don't see any WARN or ERRORs in this case.  But my
decoder works with WMV files fine.

The gstreamer0.10-ffmpeg package is installed (ubuntu).

Here is my transcoder source (it's Java Native code).
I could post my decoder to RAW source if desired but it's basically half of
the transcoder but goes to an appsink instead of an encodebin/filesink.

The call I make to transcode MP3 to WAV is:

JNI.gst_transcoder(id, mp3filein, wavfileout, null, "audio/x-wav", null,
true);
//args = instance ID, fileinString,fileoutString, containerCodec,
audioCodec, videoCodec, startPlayingBoolean

//the instance ID is just an index into an array of structs holding info
related to GStreamer

struct insts {
  //instance vars
  GstElement *pipeline, *videosink, *appsink_audio, *appsink_video,
*filesrc, *filesink
    , *decoder, *encoder, *appsrc_audio, *appsrc_video, *alphacolor,
*imgenc, *imgdec
    , *alsasrc, *alsasink, *audioresample, *audioconvert;
  GstCaps *caps_audio, *caps_video;
  int wav_size;
  guint8 *wav_data;
  jmethodID method;
  jclass cls;
  jobject obj;
  int id;
  JavaVM *vm;
};

#define instcnt 32

struct insts inst[instcnt];

static void
cb_newpad_transcoder (GstElement *bin,
           GstPad     *pad,
           gpointer    data)
{
  GstCaps *caps;
  GstStructure *str;
  GstPad *audiopad, *videopad;
  struct insts *inst = (struct insts*)data;

  /* check media type */
  caps = gst_pad_get_caps(pad);
  str = gst_caps_get_structure(caps, 0);
  if (g_strrstr(gst_structure_get_name(str), "audio")) {
    /* only link once */
    audiopad = gst_element_get_request_pad(inst->encoder, "audio_%d");
    if (GST_PAD_IS_LINKED (audiopad)) {
      printf("pad already linked");
      g_object_unref(audiopad);
      return;
    }
    gst_caps_unref(caps);
    gst_pad_link(pad, audiopad);
    return;
  }
  if (g_strrstr(gst_structure_get_name(str), "video")) {
    /* only link once */
    videopad = gst_element_get_request_pad(inst->encoder, "video_%d");
    if (GST_PAD_IS_LINKED (videopad)) {
      printf("pad already linked");
      g_object_unref(videopad);
      return;
    }
    gst_caps_unref(caps);
    gst_pad_link(pad, videopad);
    return;
  }
  printf("unknown pad type:%s\n", gst_structure_get_name(str));
  gst_caps_unref(caps);
}

//gst transcoder
JNIEXPORT jboolean JNICALL Java_javaforce_jni_JNI_gst_1transcoder
  (JNIEnv *env, jclass cls, jint id, jstring _filein, jstring _fileout,
jstring _container, jstring _acodec, jstring _vcodec, jboolean start_coding)
{
  GstBus *bus;

  inst[id].pipeline = gst_pipeline_new("my-pipeline");
  inst[id].filesrc = gst_element_factory_make("filesrc", "my-filesrc");
  inst[id].filesink = gst_element_factory_make("filesink", "my-filesink");
  inst[id].decoder = gst_element_factory_make("decodebin2", "my-decoder");
  inst[id].encoder = gst_element_factory_make("encodebin", "my-encoder");

  g_signal_connect(inst[id].decoder, "pad-added",
G_CALLBACK(cb_newpad_transcoder), &inst[id]);

  gst_bin_add_many(GST_BIN(inst[id].pipeline), inst[id].filesrc,
inst[id].decoder
    , inst[id].filesink, inst[id].encoder
    , NULL);

  //create EncoderProfiles and assign to encoder
  GstEncodingContainerProfile *cprof = NULL;
  GstEncodingAudioProfile *aprof = NULL;
  GstEncodingVideoProfile *vprof = NULL;
  GstCaps *caps;

  if (_container != NULL) {
    const char *container = (*env)->GetStringUTFChars(env,_container,NULL);
    caps = gst_caps_from_string(container);
    cprof = gst_encoding_container_profile_new(NULL, NULL, caps, NULL);
    gst_caps_unref(caps);
    (*env)->ReleaseStringUTFChars(env, _container, container);
  }

  if (_acodec != NULL) {
    const char *acodec = (*env)->GetStringUTFChars(env,_acodec,NULL);
    caps = gst_caps_from_string(acodec);
    aprof = (GstEncodingAudioProfile*) gst_encoding_audio_profile_new(caps,
NULL, NULL, 0);
    if (cprof != NULL) gst_encoding_container_profile_add_profile(cprof,
(GstEncodingProfile*)aprof);
    gst_caps_unref(caps);
    (*env)->ReleaseStringUTFChars(env, _acodec, acodec);
  }

  if (_vcodec != NULL) {
    const char *vcodec = (*env)->GetStringUTFChars(env,_vcodec,NULL);
    caps = gst_caps_from_string(vcodec);
    vprof = (GstEncodingVideoProfile*) gst_encoding_video_profile_new(caps,
NULL, NULL, 0);
    if (cprof != NULL) gst_encoding_container_profile_add_profile(cprof,
(GstEncodingProfile*)vprof);
    gst_caps_unref(caps);
    (*env)->ReleaseStringUTFChars(env, _vcodec, vcodec);
  }

  if (cprof != NULL) {
    g_object_set (G_OBJECT (inst[id].encoder), "profile", cprof, NULL);
  } else if (aprof != NULL) {
    g_object_set (G_OBJECT (inst[id].encoder), "profile", aprof, NULL);
  } else if (vprof != NULL) {
    g_object_set (G_OBJECT (inst[id].encoder), "profile", vprof, NULL);
  }

//this crashes???
//  if (cprof != NULL) gst_encoding_profile_unref(cprof);
//  if (aprof != NULL) gst_encoding_profile_unref(aprof);
//  if (vprof != NULL) gst_encoding_profile_unref(vprof);

  gst_element_link(inst[id].filesrc, inst[id].decoder);
  gst_element_link(inst[id].encoder, inst[id].filesink);

  const char *filein = (*env)->GetStringUTFChars(env,_filein,NULL);
  if (filein) g_object_set(G_OBJECT(inst[id].filesrc), "location", filein,
NULL);
  (*env)->ReleaseStringUTFChars(env, _filein, filein);

  const char *fileout = (*env)->GetStringUTFChars(env,_fileout,NULL);
  if (fileout) g_object_set(G_OBJECT(inst[id].filesink), "location",
fileout, NULL);
  (*env)->ReleaseStringUTFChars(env, _fileout, fileout);

  bus = gst_pipeline_get_bus(GST_PIPELINE(inst[id].pipeline));
  gst_bus_add_watch(bus, bus_call, &inst[id]);
  gst_object_unref(bus);

  if (start_coding) gst_element_set_state(GST_ELEMENT(inst[id].pipeline),
GST_STATE_PLAYING);

  return TRUE;
}

Thanks.

--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/need-help-transcoding-audio-only-files-tp4655428.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list