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. |
On Thu, 2012-06-28 at 09:25 -0700, Peter Quiring wrote:
Hi Peter, > 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 Have you tried specifying audio/x-wav as container profile? Despite the name, wavenc is categorised as a muxer according to gst-inspect-0.10 wavenc: Factory Details: Long name: WAV audio muxer Class: Codec/Muxer/Audio ... Plugin Details: Name: wavenc Description: Encode raw audio into WAV Cheers -Tim _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
I got it now.
container = "audio/x-wav" audioCodec = "audio/x-raw-int" I had tried "audio/x-wav" for both container and audioCodec which didn't work either. Didn't think of "audio/x-raw-int" for the audioCodec. Thanks again. |
Free forum by Nabble | Edit this page |