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